summaryrefslogtreecommitdiffhomepage
path: root/.rules/plan/09-15-reject-image-document.md
blob: 6b9459fec4e742c3c062ad4d96b876c549f6008b (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
# Phase 09 — Reject image and document content blocks

**Estimated time:** ~15 minutes
**Touches:**
`lib/dispatch/adapter/minimax/request_builder/messages.rb` (most likely),
or wherever interface `Message` content blocks are converted to the wire
format.

## Goal

MiniMax's compatibility docs explicitly state:

- `type="image"` is NOT supported.
- `type="document"` is NOT supported.

Currently the `Messages` builder probably forwards image / document
blocks transparently, relying on Anthropic's behavior. We must reject
them at request-build time with a clear `ArgumentError`. Sending a
malformed request and getting a server-side 400 is worse UX than failing
locally with a useful message.

## Steps

### 1. Identify the message-conversion file

Read `lib/dispatch/adapter/minimax/request_builder/messages.rb`. It will
have a method (likely `Messages.build` or `convert_message`) that walks
the interface message's `content` array and converts each block to the
wire format. Look for the `case block.class` (or `case block.type`)
dispatch.

### 2. Add explicit rejection branches

For ImageBlock-type and DocumentBlock-type interface blocks (or
generically: any content block whose wire `type` would be `"image"` or
`"document"`), raise `ArgumentError` with a descriptive message.

Example (adjust to fit the actual class names in
`dispatch-adapter-interface`):

```ruby
case block
when Dispatch::Adapter::TextBlock
  { type: "text", text: block.text }
when Dispatch::Adapter::ImageBlock
  raise ArgumentError,
        "MiniMax does not support image content blocks " \
        "(see https://platform.minimax.io/docs/api-reference/text-anthropic-api)."
when Dispatch::Adapter::DocumentBlock
  raise ArgumentError,
        "MiniMax does not support document content blocks " \
        "(see https://platform.minimax.io/docs/api-reference/text-anthropic-api)."
when Dispatch::Adapter::ThinkingBlock
  # ... existing handling ...
when Dispatch::Adapter::ToolUseBlock
  # ... existing handling ...
when Dispatch::Adapter::ToolResultBlock
  # ... existing handling ...
else
  raise ArgumentError, "Unsupported content block: #{block.class}"
end
```

If `dispatch-adapter-interface` does not actually export
`ImageBlock` / `DocumentBlock` constants (verify by reading the gem
source under
`reference/dispatch-adapter-minimax/Gemfile.lock` → `dispatch-adapter-interface`,
or checking the gemspec dependency), use a different detection. For
example, if interface only exposes a generic `ContentBlock` with a
`type` accessor, branch on `block.type == "image"` /
`block.type == "document"` instead.

### 3. Mirror the rejection in tool-result content if needed

If a `ToolResultBlock` can carry image/document content as a sub-block
(some Anthropic shapes allow this), the inner-content walker also needs
the same rejection. Check
`lib/dispatch/adapter/minimax/request_builder/messages.rb` for any
nested content walking and apply the same guard.

If you find nothing nested, do not invent code — just leave it.

### 4. Confirm no upstream supplier of image blocks

Run `grep -rn 'ImageBlock\|DocumentBlock' lib/`. The only matches should
be the rejection branches you just added. If lib code elsewhere
constructs image/document blocks (it shouldn't — they are caller input),
that is a bug to investigate.

## Acceptance criteria

- Building a request with a message whose content includes an ImageBlock
  raises `ArgumentError` whose message contains the substring
  `"MiniMax does not support image"`.
- Same for DocumentBlock with `"MiniMax does not support document"`.
- Building a request with only TextBlock / ThinkingBlock / ToolUseBlock /
  ToolResultBlock content succeeds as before.
- `bundle exec rubocop --autocorrect-all` exits 0.

## Verification

Run `run_tests` with `project_path=reference/dispatch-adapter-minimax`.
Rubocop must be clean. RSpec failures referring to image/document
fixtures are unlikely (the original specs probably only used text and
tools), but if any exist they are addressed in phase 13. Any failure NOT
explainable that way must be fixed before calling `ask_for_next_plan`.

NOTE: Test coverage for the new rejection branches is added in phase 13
(retarget request_builder spec). Do NOT add specs here.