feat: add AI image generation tool#11566
Conversation
Port the legacy generate_image tool to the opencode-based CLI as a Kilo-owned tool gated by experimental.image_generation config flag. - New generate_image tool with prompt/path/image/model params - Routes through Kilo Gateway (zero-config) or BYO OpenRouter key - Supports text-to-image generation and image editing - Dynamic model discovery via GET /kilo/models/images endpoint - VS Code settings toggle + live model dropdown in Experimental tab - Writes image to disk and returns inline FilePart attachment - Fallback model catalog for offline resilience
Code Review SummaryStatus: 4 Issues Found | Recommendation: Address before merge Overview
Issue Details (click to expand)WARNING
SUGGESTION
Files Reviewed (5 files)
Fix these issues in Kilo Cloud Previous Review Summaries (3 snapshots, latest commit 632d2aa)Current summary above is authoritative. Previous snapshots are kept for context only. Previous review (commit 632d2aa)Status: 4 Issues Found | Recommendation: Address before merge Overview
Issue Details (click to expand)WARNING
SUGGESTION
Files Reviewed (5 files)
Fix these issues in Kilo Cloud Previous review (commit 4d50881)Status: 5 Issues Found | Recommendation: Address before merge Overview
Issue Details (click to expand)WARNING
SUGGESTION
Files Reviewed (22 files)
Fix these issues in Kilo Cloud Previous review (commit baf12c7)Status: 4 Issues Found | Recommendation: Address before merge Overview
Issue Details (click to expand)WARNING
SUGGESTION
Files Reviewed (54 files)
Reviewed by gpt-5.4-20260305 · Input: 21.7K · Output: 1.1K · Cached: 7.2K Review guidance: REVIEW.md from base branch |
| batch_tool: Schema.optional(Schema.Boolean).annotate({ description: "Enable the batch tool" }), | ||
| // kilocode_change start | ||
| codebase_search: Schema.optional(Schema.Boolean).annotate({ description: "Enable AI-powered codebase search" }), | ||
| image_generation: Schema.optional(Schema.Boolean).annotate({ description: "Enable AI image generation" }), |
There was a problem hiding this comment.
SUGGESTION: Mirror these new config keys in the cloud schema
This PR adds new kilocode_change fields under Config.Info.experimental, and the repo guidance requires matching entries in the cloud repo at apps/web/src/app/config.json/extras.ts. If that companion schema update is missing, users validating against https://app.kilo.ai/config.json will get false unknown property errors for experimental.image_generation and experimental.image_generation_model.
Reply with @kilocode-bot fix it to have Kilo Code address this issue.
There was a problem hiding this comment.
Pull request overview
Ports the legacy generate_image capability into the opencode-based CLI/serve surface, adding a gated image-generation tool plus a /kilo/models/images model-catalog endpoint and VS Code settings UI to toggle/select image models.
Changes:
- Added
generate_imageKilo tool (text-to-image + optional image-edit) with disk output and inlineFilePartattachment. - Added dynamic image-model discovery via Kilo Gateway (
fetchKiloImageModels()+GET /kilo/models/images) and regenerated SDK/OpenAPI artifacts. - Integrated VS Code settings toggle + model dropdown (webview message plumbing + context provider + locale string additions).
Reviewed changes
Copilot reviewed 54 out of 54 changed files in this pull request and generated 11 comments.
Show a summary per file
| File | Description |
|---|---|
| packages/sdk/openapi.json | Regenerated OpenAPI spec including /kilo/models/images and new config keys. |
| packages/sdk/js/src/v2/gen/types.gen.ts | Regenerated SDK types for new config keys and /kilo/models/images. |
| packages/sdk/js/src/v2/gen/sdk.gen.ts | Regenerated SDK client with kilo.models.images() helper. |
| packages/opencode/test/tool/registry.test.ts | Provides Auth.defaultLayer for tool registry tests. |
| packages/opencode/test/session/snapshot-tool-race.test.ts | Adds Auth.defaultLayer for session/http test wiring. |
| packages/opencode/test/session/prompt.test.ts | Adds Auth.defaultLayer for session prompt test wiring. |
| packages/opencode/test/kilocode/tool/generate-image.test.ts | New unit tests for parser/provider/extension/model catalog. |
| packages/opencode/test/kilocode/tool-registry-semantic-import-failure.test.ts | Extends registry test coverage for generate_image tool presence. |
| packages/opencode/test/kilocode/tool-registry-indexing.test.ts | Ensures generate_image is gated by experimental.image_generation. |
| packages/opencode/test/kilocode/tool-registry-indexing-import-failure.test.ts | Extends registry import-failure test for generate_image. |
| packages/opencode/test/kilocode/session-prompt-permission-refresh.test.ts | Adds Auth.defaultLayer for permission refresh tests. |
| packages/opencode/test/kilocode/session-prompt-compaction-safety.test.ts | Adds Auth.defaultLayer for compaction safety tests. |
| packages/opencode/test/kilocode/session-compaction-cap.test.ts | Adds Auth.defaultLayer for compaction cap tests. |
| packages/opencode/src/tool/registry.ts | Adds Auth.Service dependency/layer to support generate_image. |
| packages/opencode/src/kilocode/tool/registry.ts | Registers GenerateImageTool and gates it behind experimental.image_generation. |
| packages/opencode/src/kilocode/tool/generate-image.txt | Adds tool description text. |
| packages/opencode/src/kilocode/tool/generate-image.ts | Implements generate_image tool logic (provider routing, request, parse, write, attach). |
| packages/opencode/src/kilocode/server/httpapi/handlers/kilo-gateway.ts | Adds handler for listing image-capable models via gateway proxy. |
| packages/opencode/src/kilocode/server/httpapi/groups/kilo-gateway.ts | Defines GET /kilo/models/images Effect HttpApi endpoint + schemas. |
| packages/opencode/src/config/config.ts | Adds experimental.image_generation + experimental.image_generation_model config keys. |
| packages/kilo-vscode/webview-ui/src/types/messages/webview-messages.ts | Adds requestImageModels webview → extension message type. |
| packages/kilo-vscode/webview-ui/src/types/messages/extension-messages.ts | Adds imageModelsLoaded extension → webview message type. |
| packages/kilo-vscode/webview-ui/src/types/messages/config.ts | Adds image-generation fields to ExperimentalConfig. |
| packages/kilo-vscode/webview-ui/src/i18n/ar.ts | Adds settings strings for image-generation toggle/model UI. |
| packages/kilo-vscode/webview-ui/src/i18n/br.ts | Adds settings strings for image-generation toggle/model UI. |
| packages/kilo-vscode/webview-ui/src/i18n/bs.ts | Adds settings strings for image-generation toggle/model UI. |
| packages/kilo-vscode/webview-ui/src/i18n/da.ts | Adds settings strings for image-generation toggle/model UI. |
| packages/kilo-vscode/webview-ui/src/i18n/de.ts | Adds settings strings for image-generation toggle/model UI. |
| packages/kilo-vscode/webview-ui/src/i18n/en.ts | Adds settings strings for image-generation toggle/model UI. |
| packages/kilo-vscode/webview-ui/src/i18n/es.ts | Adds settings strings for image-generation toggle/model UI. |
| packages/kilo-vscode/webview-ui/src/i18n/fr.ts | Adds settings strings for image-generation toggle/model UI. |
| packages/kilo-vscode/webview-ui/src/i18n/it.ts | Adds settings strings for image-generation toggle/model UI. |
| packages/kilo-vscode/webview-ui/src/i18n/ja.ts | Adds settings strings for image-generation toggle/model UI. |
| packages/kilo-vscode/webview-ui/src/i18n/ko.ts | Adds settings strings for image-generation toggle/model UI. |
| packages/kilo-vscode/webview-ui/src/i18n/nl.ts | Adds settings strings for image-generation toggle/model UI. |
| packages/kilo-vscode/webview-ui/src/i18n/no.ts | Adds settings strings for image-generation toggle/model UI. |
| packages/kilo-vscode/webview-ui/src/i18n/pl.ts | Adds settings strings for image-generation toggle/model UI. |
| packages/kilo-vscode/webview-ui/src/i18n/ru.ts | Adds settings strings for image-generation toggle/model UI. |
| packages/kilo-vscode/webview-ui/src/i18n/th.ts | Adds settings strings for image-generation toggle/model UI. |
| packages/kilo-vscode/webview-ui/src/i18n/tr.ts | Adds settings strings for image-generation toggle/model UI. |
| packages/kilo-vscode/webview-ui/src/i18n/uk.ts | Adds settings strings for image-generation toggle/model UI. |
| packages/kilo-vscode/webview-ui/src/i18n/zh.ts | Adds settings strings for image-generation toggle/model UI. |
| packages/kilo-vscode/webview-ui/src/i18n/zht.ts | Adds settings strings for image-generation toggle/model UI. |
| packages/kilo-vscode/webview-ui/src/context/image-models.tsx | Adds webview context/provider to request + store image model list. |
| packages/kilo-vscode/webview-ui/src/components/settings/ExperimentalTab.tsx | Adds image-generation toggle and conditional model dropdown UI. |
| packages/kilo-vscode/webview-ui/src/App.tsx | Wires ImageModelsProvider into the app provider tree. |
| packages/kilo-vscode/src/KiloProvider.ts | Handles requestImageModels and posts imageModelsLoaded to webview. |
| packages/kilo-vscode/src/image-generation/models.ts | Implements extension-side fetch to /kilo/models/images via local backend. |
| packages/kilo-gateway/src/server/routes.ts | Adds gateway Hono routes for image model listing (and image generation proxy). |
| packages/kilo-gateway/src/index.ts | Exports new fetchKiloImageModels types/helpers. |
| packages/kilo-gateway/src/api/models.ts | Adds fetchKiloImageModels() and refactors shared raw model fetch. |
| packages/kilo-docs/source-links.md | Updates extracted source links for new URLs/references. |
| .kilo/plans/1782130204245-image-generation-tool.md | Adds implementation plan/status doc for the feature. |
| .changeset/image-generation.md | Adds changeset entry for experimental image generation feature. |
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
| "settings.experimental.imageGeneration.title": "Image Generation", | ||
| "settings.experimental.imageGeneration.description": "Enable AI image generation", | ||
| "settings.experimental.imageGenerationModel.title": "Image Model", | ||
| "settings.experimental.imageGenerationModel.description": "Model to use for image generation (fetched from Kilo Gateway)", | ||
| "settings.experimental.imageGenerationModel.placeholder": "Default (Gemini 2.5 Flash Image)", |
7e87d79 to
4d50881
Compare
| "settings.experimental.imageGeneration.title": "Image Generation", | ||
| "settings.experimental.imageGeneration.description": "Enable AI image generation", | ||
| "settings.experimental.imageGenerationModel.title": "Image Model", | ||
| "settings.experimental.imageGenerationModel.description": "Image Generation Model", |
There was a problem hiding this comment.
WARNING: The updated image-model setting copy is still hard-coded in English across this locale batch
ExperimentalTab renders both settings.experimental.imageGenerationModel.description and the adjacent placeholder directly in the settings row. Because this same replacement was applied across the other non-English locale files touched in this commit, users will still see untranslated image-generation settings text even after the follow-up i18n sweep.
Reply with @kilocode-bot fix it to have Kilo Code address this issue.
- Remove unused fetchKiloImageModels import in tool - Normalize jpg→jpeg MIME in parser, input image, and attachment - Replace mismatched extensions in ensureExtension (not just append) - Add assertExternalDirectoryEffect for output path traversal guard - Map unauthorized errors to 401 (not 400) in image models handler - Keep last known model list on fetch failure (don't overwrite with empty) - Fix tool description (remove false web search claim, fix grammar) - Remove duplicated provider resolver tests
|
|
||
| if (result.error) { | ||
| const err = | ||
| result.error.kind === "unauthorized" ? new HttpApiError.Unauthorized({}) : new HttpApiError.BadRequest({}) |
There was a problem hiding this comment.
WARNING: Upstream and network failures still collapse into 400
fetchKiloImageModels() already distinguishes network, schema, and http failures, but this branch still maps every non-unauthorized error to HttpApiError.BadRequest. That means a transient gateway outage or a 5xx response is surfaced to the SDK as a client-input problem, so callers cannot distinguish a bad request from a backend/service failure.
Reply with @kilocode-bot fix it to have Kilo Code address this issue.
# Conflicts: # packages/opencode/test/tool/registry.test.ts
…kram/kilocode into feat/image-generation
# Conflicts: # packages/kilo-vscode/webview-ui/src/components/settings/ExperimentalTab.tsx # packages/kilo-vscode/webview-ui/src/i18n/it.ts # packages/kilo-vscode/webview-ui/src/types/messages/config.ts # packages/opencode/src/config/config.ts # packages/opencode/src/kilocode/tool/registry.ts # packages/opencode/test/kilocode/tool-registry-indexing-import-failure.test.ts # packages/opencode/test/kilocode/tool-registry-indexing.test.ts # packages/opencode/test/kilocode/tool-registry-semantic-import-failure.test.ts # packages/sdk/js/src/v2/gen/types.gen.ts # packages/sdk/openapi.json
…/image-generation
…h-notification feat(vscode): notify on matching marketplace items
# Conflicts: # packages/kilo-gateway/src/index.ts
…rktree-sandbox feat(agent-manager): add sandbox toggle to new worktree modal
…ation docs: document the experimental sandbox feature
# Conflicts: # packages/kilo-vscode/tests/unit/prompt-input-connection-guard.test.ts # packages/kilo-vscode/webview-ui/src/components/chat/PromptInput.tsx
…e-docs docs(kilo-docs): remove legacy IDE documentation
chore(ci): reduce test log noise
feat(cli): add background process lifetimes
# Conflicts: # bun.lock # packages/opencode/src/cli/cmd/run/footer.ts # packages/opencode/src/cli/cmd/run/footer.view.tsx # packages/opencode/src/cli/cmd/tui/context/sync.tsx # packages/opencode/src/kilocode/tool/registry.ts # packages/opencode/src/session/session.ts # packages/opencode/src/tool/shell.ts # packages/opencode/test/kilocode/task-nesting.test.ts # packages/opencode/test/kilocode/tool-registry-indexing.test.ts # packages/opencode/test/session/prompt.test.ts
…Kilo-Org#11788) The branch icon read as a git merge glyph for the auto model entry. Swap to the models sparkle icon, which conveys automatic/AI selection.
* feat(jetbrains): show profile balance details * fix(jetbrains): address profile balance review feedback
feat(cli): interactive terminal tool
# Conflicts: # packages/kilo-vscode/webview-ui/src/App.tsx # packages/kilo-vscode/webview-ui/src/types/messages/config.ts # packages/opencode/src/config/config.ts # packages/opencode/src/kilocode/tool/registry.ts # packages/opencode/test/kilocode/tool-registry-indexing.test.ts # packages/sdk/js/src/v2/gen/types.gen.ts # packages/sdk/openapi.json
…/image-generation
…able-error-output feat(cli): surface resumable task_id when a subagent stops on error
The release publish smoke test demanded a live bubblewrap user-namespace bootstrap on the runner, which GitHub-hosted Ubuntu 24.04 blocks via kernel.apparmor_restrict_unprivileged_userns=1 (uid map permission denied). Make that host invocation non-fatal so the gate validates the artifact, not the runner's userns policy; the runtime probe already degrades gracefully when unprivileged user namespaces are unavailable. The Alpine smoke block also had an unescaped single-quoted grep pattern inside an outer sh -c '...' string, which prematurely terminated the script so the NOTICE license grep ran with no file (empty stdin -> exit 1) and the rest of the script never ran. Escape the inner quotes as '\''...'\'' so the license check runs against the real file.
…n-locales feat(vscode): localize autocomplete strings
…-test fix(ci): stabilize Linux sandbox CLI release smoke test
feat(agent-manager): send inline review draft comments directly from diff
8c15d26 to
6541714
Compare
|
Closing in favor of a fresh PR — rebasing the feature onto the latest main from a clean branch to drop merge-history noise. New PR will be linked shortly. |
|
Reopened as a clean PR rebased onto the latest main: #11826 (branch |
…rmatting (Kilo-Org#11566) Co-authored-by: Claude <noreply@anthropic.com>
Fixes #11565
What changed
Ports the legacy
generate_imagetool to the opencode-based CLI. The AI agent can now generate images from text prompts and edit existing images, saving results to disk with inline rendering in the chat.Core tool (
generate_image)packages/opencode/src/kilocode/tool/generate-image.tswith paramsprompt,path,image(optional, for editing),model(optional override).OPENROUTER_API_KEY).modalities: ["image", "text"]via the Kilo cloud OpenRouter passthrough.FilePartattachment for inline rendering.assertExternalDirectoryEffectpath guard.Dynamic model discovery
fetchKiloImageModels()in the gateway package — queriesapi.kilo.aiand filters foroutput_modalities.includes("image").GET /kilo/models/imagesendpoint in the opencode HttpApiGroup + handler.experimental.image_generation_modelfor the default model.FALLBACK_IMAGE_MODELSlist is kept for offline/error resilience.VS Code extension
kilo serveprocess via/kilo/models/images.Gating
experimental.image_generationconfig flag (off by default) — available on all clients (CLI, VS Code, desktop).Why
The legacy Kilo extension had image generation. It was lost during the opencode migration. This restores feature parity with a key improvement: dynamic model discovery from the Kilo Gateway instead of a static hardcoded list.
Implementation choices
IMAGE_GENERATION_MODELSarray. We fetch live fromapi.kilo.aiso new image models appear automatically, with a fallback list for offline use.modalities: ["image", "text"]for these models; the legacyimages_apipath was Roo-specific and dropped.kilo serveprocess, which uses the opencode Effect HttpApiGroup for/kilo/*routes. The endpoint is registered there.openrouter/auto: Uses OpenRouter's Auto Router to automatically select the best image model, rather than hardcoding a single provider.Testing evidence
cd packages/opencode && bun run typecheck— passcd packages/kilo-vscode && bun run typecheck— passcd packages/opencode && bun test ./test/kilocode/tool/generate-image.test.ts— 25 tests passcd packages/opencode && bun test ./test/kilocode/tool-registry-indexing.test.ts— passcd packages/opencode && bun test ./test/tool/registry.test.ts— passbun run script/check-opencode-annotations.ts --base origin/main— all shared upstream changes annotatedbun run script/extract-source-links.ts— source links updated./script/generate.ts— SDK regenerated with new endpointManual verification
OPENROUTER_API_KEY