From 99fece268be5b2f4870a15566554226bd676d906 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Arnaud=20He=CC=81ritier?= Date: Tue, 6 Oct 2026 15:26:33 +0200 Subject: [PATCH] fix(chatgpt): infer image input from OpenAI catalogue --- docs/configuration/models/index.md | 8 +- docs/providers/chatgpt/index.md | 27 +++++ examples/README.md | 1 + examples/chatgpt-images.png | Bin 0 -> 306 bytes examples/chatgpt-images.yaml | 20 ++++ .../provider/capability_override_test.go | 16 +++ pkg/model/provider/openai/chatgpt_test.go | 93 ++++++++++++++++++ pkg/modelinfo/catalog_caps.go | 27 +++++ pkg/modelinfo/modelinfo.go | 9 +- pkg/modelinfo/resolve_caps_test.go | 69 +++++++++++++ pkg/runtime/transforms.go | 6 +- pkg/runtime/transforms_test.go | 75 ++++++++++++++ 12 files changed, 344 insertions(+), 7 deletions(-) create mode 100644 examples/chatgpt-images.png create mode 100644 examples/chatgpt-images.yaml create mode 100644 pkg/modelinfo/catalog_caps.go diff --git a/docs/configuration/models/index.md b/docs/configuration/models/index.md index 2a82cdc0e..6a9ab65eb 100644 --- a/docs/configuration/models/index.md +++ b/docs/configuration/models/index.md @@ -90,7 +90,9 @@ For custom OpenAI-compatible providers, local models (Ollama, DMR), and any model the built-in catalogue does not describe, Docker Agent cannot auto-detect whether the endpoint accepts image, PDF, audio, or video attachments. When the model is absent from the catalogue, Docker Agent logs a -diagnostic and falls back to text-only, silently dropping attachments. +diagnostic and falls back to text-only, silently dropping attachments. For the +`chatgpt` provider, a missing entry first falls back to the matching `openai` +entry for **image input only**; PDF, audio, and video are not inferred. Declare `capabilities` to make the model's attachment support authoritative and skip the catalogue lookup entirely: @@ -130,8 +132,8 @@ models: The flags must match what the endpoint actually accepts. Claiming a modality that the endpoint does not support leads to a provider-side API error. When -`capabilities` is omitted the behaviour is unchanged (catalogue lookup then -conservative text-only fallback). +`capabilities` is omitted, input support comes from the catalogue, the scoped +ChatGPT image fallback above, or conservative text-only fallback. ### Unsupported media is stripped before the call diff --git a/docs/providers/chatgpt/index.md b/docs/providers/chatgpt/index.md index ed5025005..7394783fc 100644 --- a/docs/providers/chatgpt/index.md +++ b/docs/providers/chatgpt/index.md @@ -101,6 +101,33 @@ The effort picker exposes Low/Medium/High/XHigh/Max on the GPT-5.6 family there. Client-side sampling parameters (`temperature`, `top_p`, `max_tokens`) are not supported by the backend and are dropped. +## Image Input + +For image-capable models such as `gpt-6.1-sol`, you can attach an image: + +```bash +docker agent run examples/chatgpt-images.yaml --exec \ + --attach examples/chatgpt-images.png "Describe the shapes and colors." +``` + +The sample includes a red square centered on a blue background. Running it +requires ChatGPT sign-in and access to the selected model. Image input for +`gpt-6.1-sol` is inferred from the matching OpenAI catalogue entry; no +`capabilities` override is needed. + +When models.dev has no direct `chatgpt/` entry, Docker Agent uses the +matching `openai/` entry for **image input only**. This applies both to +`--attach` images and image content returned by MCP tools (for example, +screenshots). Tool images are sent in a follow-up user message alongside the +text function-call output. PDF, audio, and video support, prices, context limits, +tool support, output capabilities, and `max_tokens` are not inherited. +A direct ChatGPT catalogue entry takes precedence; unknown models remain +text-only. + +To intentionally override catalogue capabilities or declare support for an +unknown model, see [Attachment Capability Overrides](../../configuration/models/index.md#attachment-capability-overrides). +Image input support does not enable image generation or editing. + ## Setting the Token Explicitly `CHATGPT_OAUTH_TOKEN` can also be set like any other credential (shell diff --git a/examples/README.md b/examples/README.md index 1f6196985..de8491267 100644 --- a/examples/README.md +++ b/examples/README.md @@ -210,6 +210,7 @@ remote MCP endpoints. | [`cloudflare-workers-ai.yaml`](cloudflare-workers-ai.yaml) | Cloudflare Workers AI edge-hosted open models. | | [`cloudflare-ai-gateway.yaml`](cloudflare-ai-gateway.yaml) | Cloudflare AI Gateway multi-provider router. | | [`grok.yaml`](grok.yaml) | xAI Grok model. | +| [`chatgpt-images.yaml`](chatgpt-images.yaml) + [`chatgpt-images.png`](chatgpt-images.png) | ChatGPT image input with an attached sample image and automatic capability detection. | | [`github-copilot.yaml`](github-copilot.yaml) | GitHub Copilot models via OAuth device-flow. | | [`fallback_models.yaml`](fallback_models.yaml) | Automatic fallback to a secondary model when the primary fails. | | [`model_picker.yaml`](model_picker.yaml) | Lets the agent itself swap to a stronger model mid-conversation. | diff --git a/examples/chatgpt-images.png b/examples/chatgpt-images.png new file mode 100644 index 0000000000000000000000000000000000000000..21e47b4550b822d428d7a0a963355b66ab64c58c GIT binary patch literal 306 zcmeAS@N?(olHy`uVBq!ia0vp^2_VeD1SE5RJ;(=AKRsO>Ln`LHyY_zB9