The CommandCode CLI never sends image parts to a model that has no image input modality. In dist/cli.mjs the model client gates on the registry before building the wire body:
const r = !e.registry.supportsVision({ model: t.model }) && hasImage2({ messages: t.messages })
? stripImages({ messages: t.messages })
: t.messages;
stripImages removes every image part and substitutes placeholder text, keeping only the most recent user message's image slots as numbered placeholders.
The bridge cannot do this today: providerModelsFromCatalog in src/model-catalog.ts only keeps id, name, context_length, and owned_by, so there is no modality information to gate on. Once image parts are actually forwarded upstream (PR #3), a request carrying an image to a text-only model produces a body shape the CLI would never emit, besides likely being rejected upstream.
Work needed:
- Carry input modality (or an explicit vision flag) through the model catalog, either from the provider catalog payload if it exposes one, or as a maintained list.
- Strip image parts for non-vision models before building the generate body, mirroring the CLI's placeholder substitution.
- Cover it with a converter test asserting no
image part survives for a text-only model.
Blocked on PR #3 landing first, since image parts do not reach the upstream body before then.
The CommandCode CLI never sends image parts to a model that has no image input modality. In
dist/cli.mjsthe model client gates on the registry before building the wire body:stripImagesremoves every image part and substitutes placeholder text, keeping only the most recent user message's image slots as numbered placeholders.The bridge cannot do this today:
providerModelsFromCataloginsrc/model-catalog.tsonly keepsid,name,context_length, andowned_by, so there is no modality information to gate on. Once image parts are actually forwarded upstream (PR #3), a request carrying an image to a text-only model produces a body shape the CLI would never emit, besides likely being rejected upstream.Work needed:
imagepart survives for a text-only model.Blocked on PR #3 landing first, since image parts do not reach the upstream body before then.