Repository navigation
feat(core): make image_generate opt-in with one experimental config field - #60096
Conversation
There was a problem hiding this comment.
Looks good. The gate follows the same ConfigEntryObserver + ctx.tool.reload() pattern as the todo tool's flag. It is read per field like image_model and checked inside the transform together with the existing image-model check. I checked it with the image-generate and config-normalisation tests (57 pass; the new test shows the tool appearing and disappearing as the flag flips) and typecheck:tsc in packages/core. I couldn't check it end to end because the simulated provider has no image model.
Public API: adds the optional config key experimental.image_generate (boolean, defaults to false) to the schema, the OpenAPI spec and the generated client types. Existing configs still validate, but this changes behaviour: anyone who relied on image_generate appearing on its own with an image-capable provider now needs to set experimental.image_generate: true. experimental.image_model alone no longer turns the tool on.
No blocking concerns.
There was a problem hiding this comment.
The new commits look good. image_generate accepts true, {} or { model }, and both the opt-in check and the default model are read from the newest config document that sets it. The removed image_model handling leaves nothing behind in the repo. I checked it with the image-generate and config-normalisation tests (57 pass, covering each form, invalid values, the tool appearing and disappearing as the config changes, and the model fallbacks) and typecheck:tsc in packages/core and packages/schema. I couldn't run it end to end because the simulated provider has no image model.
Public API (config schema, OpenAPI spec, generated client types):
experimental.image_generate:boolean→boolean | { model?: "providerID/modelID[#variant]" | { providerID, model, variant? } }, defaults to off.experimental.image_model: removed. It was added in #59939 and doesn't appear to be in a release yet. Any config that already uses it needs to move toimage_generate: { model }.- The tool is now off unless
image_generateis set.
No blocking concerns.
The built-in
image_generatetool is now off by default. One config field turns it on and can optionally pick its default model:{ "experimental": { + "image_generate": true } }{ "experimental": { - "image_model": "openai/gpt-image-2", + "image_generate": { "model": "openai/gpt-image-2#hd" } } }false: tool offtrueor{}: tool on, model picked automatically (newest image model from the session's provider, otherwise the newest one overall){ "model": "providerID/modelID" }(a#variantis allowed): tool on with that default. If it can't serve a call (unavailable, missing variant, or no image input for edits) it falls back to automatic selection and says so, same as before.This replaces
experimental.image_model. That field hasn't shipped in a release, so there's no alias. Either way the tool only shows up while a connected provider has an image model.Why I made it opt-in: the tool is new, and it costs a few hundred tokens of tool schema on every request whether or not anyone wants an image. That's my estimate of roughly 450 tokens from the description and parameter text. Agents have also overused it in benchmarks. Image generation also isn't something most coding sessions need, so it's common to leave it out of a coding toolset. I'd rather keep it opt-in while it settles.
The field is read from the newest config document that sets it, so a later config that sets other experimental options doesn't hide it, and the tool list reloads when the config changes.
Visual
Verification
bun test test/tool-image-generate.test.ts test/config/normalization.test.tsinpackages/core(57 pass, coveringtrue,false,{},{ model }, invalid values, and the tool only being offered when enabled)bun run typecheck:tscinpackages/corebun run generateinpackages/clientandpackages/protocol, thenbun run check:generatedinpackages/protocolbun run checkat the repo rootAdded by the opencode bot (AI-generated).
Public API: experimental.image_generate (boolean | { model? }, default off) replaces experimental.image_model; image_generate tool is now opt-in