Skip to content

feat: add AI image generation tool#11826

Merged
marius-kilocode merged 40 commits into
Kilo-Org:mainfrom
vkeerthivikram:feat/ai-image-generation
Jul 8, 2026
Merged

feat: add AI image generation tool#11826
marius-kilocode merged 40 commits into
Kilo-Org:mainfrom
vkeerthivikram:feat/ai-image-generation

Conversation

@vkeerthivikram

@vkeerthivikram vkeerthivikram commented Jun 30, 2026

Copy link
Copy Markdown
Contributor

Linked issue: #11565 — Support AI image generation (generate_image tool)


Summary

Adds a new generate_image tool that lets the agent generate or edit images from text prompts, gated behind experimental.image_generation. Routes through the Kilo Gateway (zero-config) or a BYO OpenRouter API key, with a dynamic model picker in the VS Code Experimental settings tab.

Restores a feature the legacy Kilo extension had (kilocode-legacy/GenerateImageTool.ts); this port improves on it by fetching the model list dynamically from api.kilo.ai instead of using a hardcoded array.

What I changed

New files:

  • packages/opencode/src/kilocode/tool/generate-image.ts — the tool (Tool.define, image generation + editing, gateway-aware provider resolution)
  • packages/opencode/src/kilocode/tool/generate-image.txt — tool description
  • packages/opencode/test/kilocode/tool/generate-image.test.ts — 23 tests (parser, provider resolver, path extension, MIME normalization, model catalog)
  • packages/kilo-vscode/src/image-generation/models.ts — fetch helper for the settings dropdown
  • packages/kilo-vscode/webview-ui/src/context/image-models.tsx — SolidJS context provider
  • .changeset/image-generation.md — minor changeset

Modified files:

  • packages/opencode/src/kilocode/tool/registry.ts — registered the new tool (gated by flag)
  • packages/opencode/src/kilocode/server/httpapi/groups/kilo-gateway.ts — added GET /kilo/models/images endpoint
  • packages/opencode/src/kilocode/server/httpapi/handlers/kilo-gateway.ts — added the handler calling fetchKiloImageModels
  • packages/kilo-gateway/src/api/models.ts — added fetchKiloImageModels() (queries api.kilo.ai, filters output_modalities.includes("image"))
  • packages/kilo-gateway/src/index.ts — exported the new function
  • packages/kilo-vscode/src/KiloProvider.ts — handler for requestImageModels message, cached fallback on fetch failure
  • packages/kilo-vscode/webview-ui/src/App.tsx — registered ImageModelsProvider
  • packages/kilo-vscode/webview-ui/src/components/settings/ExperimentalTab.tsx — Image Generation toggle + model dropdown
  • packages/kilo-vscode/webview-ui/src/types/messages/*.tsRequestImageModelsMessage + ImageModelsLoadedMessage
  • packages/kilo-vscode/webview-ui/src/i18n/*.ts — 20 locales
  • packages/sdk/js/src/v2/gen/sdk.gen.ts, types.gen.ts, openapi.json — regenerated SDK

Shared files (with kilocode_change markers):

  • packages/opencode/src/config/config.ts — added experimental.image_generation + experimental.image_generation_model config keys
  • packages/opencode/src/tool/registry.ts — added Auth.Service dependency (required by the tool)

Test updates: 9 test files updated to wire Auth.defaultLayer into the tool registry layer + add the new image tool field.

Testing

  • cd packages/opencode && bun test ./test/kilocode/tool/generate-image.test.ts — 23 pass
  • cd packages/opencode && bun run typecheck — pass
  • cd packages/kilo-vscode && bun run typecheck — pass
  • cd packages/kilo-gateway && bun run typecheck — pass
  • bun run script/check-opencode-annotations.ts --base origin/main — pass

📎 References · Issue #11565 · Legacy tool

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
- 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
…ation

# Conflicts:
#	packages/kilo-gateway/src/index.ts
#	packages/kilo-vscode/webview-ui/src/App.tsx
#	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/opencode/test/tool/registry.test.ts
#	packages/sdk/js/src/v2/gen/types.gen.ts
#	packages/sdk/openapi.json
Copilot AI review requested due to automatic review settings June 30, 2026 09:45

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

This PR adds an experimental generate_image tool to the agent runtime and wires it through the Kilo Gateway and local kilo serve HTTP API so clients (notably the VS Code extension) can both use image generation and discover image-capable models dynamically.

Changes:

  • Added a Kilo-owned generate_image tool (prompt + optional input image + output path) gated behind experimental.image_generation and configurable via experimental.image_generation_model.
  • Added /kilo/models/images endpoint + gateway plumbing for image-capable model discovery, and regenerated the JS SDK/OpenAPI outputs.
  • Updated the VS Code extension/webview to expose an experimental toggle + model dropdown backed by a new Image Models provider/context.

Reviewed changes

Copilot reviewed 54 out of 54 changed files in this pull request and generated 5 comments.

Show a summary per file
File Description
packages/sdk/openapi.json Adds /kilo/models/images path + experimental config keys in the OpenAPI spec.
packages/sdk/js/src/v2/gen/types.gen.ts Regenerates SDK types for the new endpoint and config flags.
packages/sdk/js/src/v2/gen/sdk.gen.ts Regenerates the SDK client to expose client.kilo.models.images().
packages/opencode/test/tool/registry.test.ts Updates test layers to provide Auth.defaultLayer needed by the new tool dependency graph.
packages/opencode/test/session/snapshot-tool-race.test.ts Provides Auth.defaultLayer in session test wiring.
packages/opencode/test/session/prompt.test.ts Provides Auth.defaultLayer in session prompt tests.
packages/opencode/test/kilocode/tool/generate-image.test.ts Adds unit tests for response parsing, provider resolution, and path extension behavior.
packages/opencode/test/kilocode/tool-registry-semantic-import-failure.test.ts Extends tool registry test expectations to include generate_image.
packages/opencode/test/kilocode/tool-registry-indexing.test.ts Extends tool registry indexing + gating tests for image_generation.
packages/opencode/test/kilocode/tool-registry-indexing-import-failure.test.ts Extends tool registry test expectations to include generate_image.
packages/opencode/test/kilocode/session-prompt-permission-refresh.test.ts Provides Auth.defaultLayer in session tests.
packages/opencode/test/kilocode/session-prompt-compaction-safety.test.ts Provides Auth.defaultLayer in session tests.
packages/opencode/test/kilocode/session-compaction-cap.test.ts Provides Auth.defaultLayer in session tests.
packages/opencode/src/tool/registry.ts Adds Auth.Service to the tool registry 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 end-user tool description text for generate_image.
packages/opencode/src/kilocode/tool/generate-image.ts Implements generate_image tool (provider resolution, request build, response parse, file write + attachment).
packages/opencode/src/kilocode/server/httpapi/handlers/kilo-gateway.ts Adds handler for /kilo/models/images via fetchKiloImageModels.
packages/opencode/src/kilocode/server/httpapi/groups/kilo-gateway.ts Adds the /kilo/models/images endpoint schema + OpenAPI annotations.
packages/opencode/src/config/config.ts Adds experimental config keys image_generation and image_generation_model.
packages/kilo-vscode/webview-ui/src/types/messages/webview-messages.ts Adds webview→extension message type for requesting image models.
packages/kilo-vscode/webview-ui/src/types/messages/extension-messages.ts Adds extension→webview message type for delivering image models.
packages/kilo-vscode/webview-ui/src/types/messages/config.ts Extends experimental config typing with image generation flags.
packages/kilo-vscode/webview-ui/src/i18n/zht.ts Adds new experimental settings strings for image generation (locale: zht).
packages/kilo-vscode/webview-ui/src/i18n/zh.ts Adds new experimental settings strings for image generation (locale: zh).
packages/kilo-vscode/webview-ui/src/i18n/uk.ts Adds new experimental settings strings for image generation (locale: uk).
packages/kilo-vscode/webview-ui/src/i18n/tr.ts Adds new experimental settings strings for image generation (locale: tr).
packages/kilo-vscode/webview-ui/src/i18n/th.ts Adds new experimental settings strings for image generation (locale: th).
packages/kilo-vscode/webview-ui/src/i18n/ru.ts Adds new experimental settings strings for image generation (locale: ru).
packages/kilo-vscode/webview-ui/src/i18n/pl.ts Adds new experimental settings strings for image generation (locale: pl).
packages/kilo-vscode/webview-ui/src/i18n/no.ts Adds new experimental settings strings for image generation (locale: no).
packages/kilo-vscode/webview-ui/src/i18n/nl.ts Adds new experimental settings strings for image generation (locale: nl).
packages/kilo-vscode/webview-ui/src/i18n/ko.ts Adds new experimental settings strings for image generation (locale: ko).
packages/kilo-vscode/webview-ui/src/i18n/ja.ts Adds new experimental settings strings for image generation (locale: ja).
packages/kilo-vscode/webview-ui/src/i18n/it.ts Adds new experimental settings strings for image generation (locale: it).
packages/kilo-vscode/webview-ui/src/i18n/fr.ts Adds new experimental settings strings for image generation (locale: fr).
packages/kilo-vscode/webview-ui/src/i18n/es.ts Adds new experimental settings strings for image generation (locale: es).
packages/kilo-vscode/webview-ui/src/i18n/en.ts Adds new experimental settings strings for image generation (locale: en).
packages/kilo-vscode/webview-ui/src/i18n/de.ts Adds new experimental settings strings for image generation (locale: de).
packages/kilo-vscode/webview-ui/src/i18n/da.ts Adds new experimental settings strings for image generation (locale: da).
packages/kilo-vscode/webview-ui/src/i18n/bs.ts Adds new experimental settings strings for image generation (locale: bs).
packages/kilo-vscode/webview-ui/src/i18n/br.ts Adds new experimental settings strings for image generation (locale: br).
packages/kilo-vscode/webview-ui/src/i18n/ar.ts Adds new experimental settings strings for image generation (locale: ar).
packages/kilo-vscode/webview-ui/src/context/image-models.tsx Adds webview context/provider that requests + stores the image model list (with retry).
packages/kilo-vscode/webview-ui/src/components/settings/ExperimentalTab.tsx Adds toggle + dropdown UI for experimental image generation and model selection.
packages/kilo-vscode/webview-ui/src/App.tsx Wires ImageModelsProvider into the webview provider tree.
packages/kilo-vscode/src/KiloProvider.ts Handles requestImageModels and posts imageModelsLoaded (with caching).
packages/kilo-vscode/src/image-generation/models.ts Adds extension-side fetch helper for /kilo/models/images.
packages/kilo-gateway/src/server/routes.ts Adds gateway route for /models/images (and related image proxy routing additions).
packages/kilo-gateway/src/index.ts Exports new fetchKiloImageModels API and associated types.
packages/kilo-gateway/src/api/models.ts Implements fetchKiloImageModels() and refactors shared raw model fetch.
packages/kilo-docs/source-links.md Updates extracted source links to include new URLs/endpoints referenced by new code.
.kilo/plans/1782130204245-image-generation-tool.md Adds/updates implementation plan doc for the feature.
.changeset/image-generation.md Adds a minor changeset for the VS Code extension package.

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment on lines +231 to +235
permission: "write",
patterns: [path.relative(instance.worktree, absPath)],
always: ["*"],
metadata: { filepath: absPath },
})
Comment thread packages/sdk/openapi.json
"x-codeSamples": [
{
"lang": "js",
"source": "import { createKiloClient } from \"@kilocode/sdk\n\nconst client = createKiloClient()\nawait client.kilo.models.images({\n ...\n})"
Comment on lines +17 to +37
export const ImageModelsProvider: ParentComponent = (props) => {
const vscode = useVSCode()
const [models, setModels] = createSignal<ImageModel[]>([])

const request = () => vscode.postMessage({ type: "requestImageModels" })

const unsubscribe = vscode.onMessage((message: ExtensionMessage) => {
if (message.type !== "imageModelsLoaded") return
setModels(message.models)
})

request()

// Retry once after a delay in case the backend wasn't ready for the initial request.
const retry = setTimeout(request, 3000)
onCleanup(() => clearTimeout(retry))

onCleanup(unsubscribe)

return <ImageModelsContext.Provider value={{ models }}>{props.children}</ImageModelsContext.Provider>
}
Comment on lines +1375 to +1379
"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",
"settings.experimental.imageGenerationModel.placeholder": "Default (Auto Router)",
Comment on lines +127 to +129
test("replaces mismatched extension when format differs", () => {
expect(ensureExtension("output/photo.jpg", "png")).toBe("output/photo.jpg.png")
})
const jpg = ["jpg", "jpeg"]
if (ext === "jpg" && jpg.includes(existing)) return relPath
if (ext === "png" && png.includes(existing)) return relPath
return `${relPath}.${ext}`

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

WARNING: Mismatched extensions are still appended instead of replaced

This branch preserves matching png/jpg suffixes, but any other image suffix still falls through to return ${relPath}.${ext}``. Saving PNG output to photo.jpg therefore produces `photo.jpg.png`, which leaves a misleading filename on disk and contradicts the intended behavior of this follow-up fix.


Reply with @kilocode-bot fix it to have Kilo Code address this issue.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@kilocode-bot fix it

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

To use Kilo from GitHub you first need to link your GitHub account to Kilo. Link your Kilo account to continue. After linking, mention me again in this issue or pull request.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Fixed in add1ddc. ensureExtension now replaces mismatched image extensions instead of appending: photo.jpg + PNG → photo.png. Non-image extensions (e.g. .final) are still preserved with appending. Updated tests cover jpg→png, jpeg→png, and png→jpg.

})

if (result.error) {
const status = result.error.kind === "unauthorized" ? 401 : (result.error.status ?? 500)

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

WARNING: The documented response codes no longer match the handler

fetchKiloImageModels() can surface upstream 429/5xx statuses here, but describeRoute() above only advertises 200 and 401. Any client generated from this route will treat those non-auth failures as impossible, so this should either normalize them to a documented status or add the extra responses to the schema.


Reply with @kilocode-bot fix it to have Kilo Code address this issue.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@kilocode-bot fix it

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

To use Kilo from GitHub you first need to link your GitHub account to Kilo. Link your Kilo account to continue. After linking, mention me again in this issue or pull request.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Fixed in add1ddc. Now uses ...errors(400, 401) — the same pattern as every other gateway route (/profile, /organization, /fim, etc.). Non-auth errors map to 400 instead of leaking arbitrary upstream statuses (429, 503, …).

Comment thread packages/sdk/openapi.json
}
}
},
"400": {

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

WARNING: The regenerated schema dropped the 401 branch for this endpoint

The new imageModels handler in packages/opencode/src/kilocode/server/httpapi/handlers/kilo-gateway.ts returns HttpApiError.Unauthorized, but this spec only exposes a 400 error response. That leaves the generated SDK unable to represent auth failures for /kilo/models/images, so callers cannot distinguish re-authentication from generic bad requests.


Reply with @kilocode-bot fix it to have Kilo Code address this issue.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@kilocode-bot fix it

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

To use Kilo from GitHub you first need to link your GitHub account to Kilo. Link your Kilo account to continue. After linking, mention me again in this issue or pull request.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Fixed in add1ddc. Added the 401 response to both openapi.json and types.gen.ts, matching the gateway route's errors(400, 401) declaration. The Effect OpenAPI generator suppresses 401 for all /kilo/* endpoints because the group's Authorization middleware declares HttpApiError.UnauthorizedNoContent (a no-content error the generator skips). Manual addition is consistent with what the gateway declares.

@kilo-code-bot

kilo-code-bot Bot commented Jun 30, 2026

Copy link
Copy Markdown
Contributor

Code Review Summary

Status: No Issues Found | Recommendation: Merge

Incremental review of commits since the previous pass (4b241f49c..84dd790455). This range's first-parent chain is almost entirely a merge of main (project-memory feature, sandboxing UI rework, JetBrains CLI downloader, prompt/session fixes, etc.) — none of that is owned by this PR. After reconciling the raw diff against the PR's actual base (bc15ee9b4, i.e. git diff bc15ee9b4..84dd790455, which matches gh pr diff --name-only exactly) and normalizing away line-number/context shifts caused by the main merge, the only PR-owned content change in this range is:

  • packages/kilo-docs/source-links.md — the final commit (84dd790455, "chore: refresh source-links.md after URL refactor") removes one stale line. This is a generated artifact checked by script/extract-source-links.ts in CI and is out of scope per this repo's review guidance.

Every other file that appears to differ between the two commit ranges (i18n files, AgentManagerApp.tsx, App.tsx, openapi.json, types.gen.ts, lychee.toml) does so only because unrelated main commits shifted surrounding context/line numbers or added adjacent entries — the actual PR-owned lines (e.g. ImageModelsProvider wiring, imageGeneration/imageGenerationModel i18n strings, the 401 OpenAPI response) are byte-for-byte unchanged from the previously reviewed commit.

Re-verified against current HEAD (84dd790455):

  • The OpenAPI 401 response fix for /kilo/models/images (flagged in an earlier round) remains in place in both openapi.json and types.gen.ts.
  • The remaining open Copilot inline comments (generate-image.ts:238 permission type, openapi.json:14394 code-sample typo, image-models.tsx:37 redundant retry timer) are all on files untouched by this increment, so they are left as-is per the incremental-review scope rules — no new duplicate comments were posted.
Files Reviewed (2 files)
  • packages/kilo-docs/source-links.md
  • packages/kilo-docs/lychee.toml (context-only shift, no PR-owned change)
Previous Review Summaries (7 snapshots, latest commit 4b241f4)

Current summary above is authoritative. Previous snapshots are kept for context only.

Previous review (commit 4b241f4)

Status: No Issues Found | Recommendation: Merge

Incremental review of commits since the previous pass (666560c..4b241f4). The only PR-owned commit in this range (4b241f49c) addresses prior review feedback:

  • Translates the imageGeneration/imageGenerationModel settings strings across all 19 non-English locales (previously left in English).
  • Replaces the hardcoded process.env["KILO_API_URL"] ?? "https://api.kilo.ai" fallback in generate-image.ts with the central KILO_OPENROUTER_BASE constant from @kilocode/kilo-gateway — verified KILO_OPENROUTER_BASE already expands to .../api/openrouter, so the resulting request URL (${KILO_OPENROUTER_BASE}/chat/completions) is unchanged.
  • Removes the now-completed implementation plan file.

The accompanying @openrouter/ai-sdk-provider version bump/revert in bun.lock and the core/kilo-gateway/opencode package.json files nets to no change versus main (2.9.0 → 2.9.0), so it does not appear in the PR's actual diff and was not evaluated as a code change.

Files Reviewed (20 files)
  • packages/opencode/src/kilocode/tool/generate-image.ts
  • packages/kilo-vscode/webview-ui/src/i18n/ar.ts
  • packages/kilo-vscode/webview-ui/src/i18n/br.ts
  • packages/kilo-vscode/webview-ui/src/i18n/bs.ts
  • packages/kilo-vscode/webview-ui/src/i18n/da.ts
  • packages/kilo-vscode/webview-ui/src/i18n/de.ts
  • packages/kilo-vscode/webview-ui/src/i18n/es.ts
  • packages/kilo-vscode/webview-ui/src/i18n/fr.ts
  • packages/kilo-vscode/webview-ui/src/i18n/it.ts
  • packages/kilo-vscode/webview-ui/src/i18n/ja.ts
  • packages/kilo-vscode/webview-ui/src/i18n/ko.ts
  • packages/kilo-vscode/webview-ui/src/i18n/nl.ts
  • packages/kilo-vscode/webview-ui/src/i18n/no.ts
  • packages/kilo-vscode/webview-ui/src/i18n/pl.ts
  • packages/kilo-vscode/webview-ui/src/i18n/ru.ts
  • packages/kilo-vscode/webview-ui/src/i18n/th.ts
  • packages/kilo-vscode/webview-ui/src/i18n/tr.ts
  • packages/kilo-vscode/webview-ui/src/i18n/uk.ts
  • packages/kilo-vscode/webview-ui/src/i18n/zh.ts
  • packages/kilo-vscode/webview-ui/src/i18n/zht.ts

Previous review (commit 666560c)

Status: No Issues Found | Recommendation: Merge

Incremental review of commits since the previous pass (9a37270..666560c). The only PR-owned commit in this range is a dependency bump (ffc510b1); the subsequent head move (666560c8) is a no-op merge of main that introduces no new PR diff. The bump only touches lockfile/manifest version strings — no application code changed.

Files Reviewed (4 files)
  • bun.lock
  • packages/core/package.json
  • packages/kilo-gateway/package.json
  • packages/opencode/package.json

Previous review (commit 9a37270)

Status: No Issues Found | Recommendation: Merge

Incremental review of commits since the previous pass (d322b6b..9a37270). Only two files changed in this range; both are clean.

Files Reviewed (2 files)
  • packages/kilo-docs/lychee.toml
  • packages/kilo-vscode/webview-ui/agent-manager/AgentManagerApp.tsx

Previous review (commit d322b6b)

Status: 1 Issue Found | Recommendation: Address before merge

Overview

Severity Count
CRITICAL 0
WARNING 1
SUGGESTION 0
Issue Details (click to expand)

WARNING

File Line Issue
packages/kilo-gateway/src/server/routes.ts 479 The new 400 path is still documented as `BadRequest

Fix these issues in Kilo Cloud

Files Reviewed (5 files)
  • packages/kilo-gateway/src/server/routes.ts - 1 issue
  • packages/opencode/src/kilocode/tool/generate-image.ts - no issues found
  • packages/opencode/test/kilocode/tool/generate-image.test.ts - no issues found
  • packages/sdk/js/src/v2/gen/types.gen.ts - no issues found
  • packages/sdk/openapi.json - no issues found

Previous review (commit a29e3a2)

Status: 1 Issue Found | Recommendation: Address before merge

Overview

Severity Count
CRITICAL 0
WARNING 1
SUGGESTION 0
Issue Details (click to expand)

WARNING

File Line Issue
packages/kilo-gateway/src/server/routes.ts 479 The new 400 path is still documented as `BadRequest

Fix these issues in Kilo Cloud

Files Reviewed (5 files)
  • packages/kilo-gateway/src/server/routes.ts - 1 issue
  • packages/opencode/src/kilocode/tool/generate-image.ts - no issues found
  • packages/opencode/test/kilocode/tool/generate-image.test.ts - no issues found
  • packages/sdk/js/src/v2/gen/types.gen.ts - no issues found
  • packages/sdk/openapi.json - no issues found

Previous review (commit aa81d0a)

Status: 1 Issue Found | Recommendation: Address before merge

Overview

Severity Count
CRITICAL 0
WARNING 1
SUGGESTION 0
Issue Details (click to expand)

WARNING

File Line Issue
packages/kilo-gateway/src/server/routes.ts 479 The new 400 path is still documented as `BadRequest

Fix these issues in Kilo Cloud

Files Reviewed (5 files)
  • packages/kilo-gateway/src/server/routes.ts - 1 issue
  • packages/opencode/src/kilocode/tool/generate-image.ts - no issues found
  • packages/opencode/test/kilocode/tool/generate-image.test.ts - no issues found
  • packages/sdk/js/src/v2/gen/types.gen.ts - no issues found
  • packages/sdk/openapi.json - no issues found

Previous review (commit 0cf21de)

Status: 3 Issues Found | Recommendation: Address before merge

Overview

Severity Count
CRITICAL 0
WARNING 3
SUGGESTION 0
Issue Details (click to expand)

WARNING

File Line Issue
packages/opencode/src/kilocode/tool/generate-image.ts 96 ensureExtension() still appends mismatched suffixes, so photo.jpg + PNG output becomes photo.jpg.png.
packages/kilo-gateway/src/server/routes.ts 478 /models/images can emit undeclared upstream statuses even though the route schema only documents 200 and 401.
packages/sdk/openapi.json 14140 /kilo/models/images omits the 401 response that the new handler can return, so generated clients cannot model auth failures.

Fix these issues in Kilo Cloud

Files Reviewed (54 files)
  • packages/opencode/src/kilocode/tool/generate-image.ts - 1 issue
  • packages/kilo-gateway/src/server/routes.ts - 1 issue
  • packages/sdk/openapi.json - 1 issue
  • 51 other changed files - no issues found

Reviewed by claude-sonnet-5 · Input: 114 · Output: 37.7K · Cached: 4.6M

Review guidance: REVIEW.md from base branch main

- ensureExtension replaces mismatched image extensions instead of
  appending (photo.jpg + PNG -> photo.png, not photo.jpg.png)
- Gateway /models/images normalizes errors to 400/401 matching every
  other gateway route (was leaking undeclared upstream statuses)
- Add 401 response to openapi.json + SDK types for /kilo/models/images
  to match the gateway's errors(400, 401) declaration

if (result.error) {
if (result.error.kind === "unauthorized") return c.json({ error: "unauthorized" }, 401)
return c.json({ error: result.error.kind }, 400)

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

WARNING: The new 400 branch still does not match the documented schema

errors(400, 401) now advertises a BadRequest | InvalidRequestError payload for this endpoint, but this line still returns { error: result.error.kind } for network / schema / http failures. The regenerated SDK therefore claims clients can decode structured 400 errors here even though the gateway sends a different shape, so this should either emit the documented error body or declare the actual response schema.


Reply with @kilocode-bot fix it to have Kilo Code address this issue.

@vkeerthivikram vkeerthivikram force-pushed the feat/ai-image-generation branch 2 times, most recently from 80c5c0e to add1ddc Compare June 30, 2026 11:59
…ation

# Conflicts:
#	packages/opencode/src/kilocode/tool/registry.ts
#	packages/opencode/test/kilocode/tool-registry-indexing.test.ts
#	packages/opencode/test/tool/registry.test.ts
@Robinnnnn

Copy link
Copy Markdown

This looks great. One note: @openrouter/ai-sdk-provider 2.10.0 switched imageModel() to OpenRouter's dedicated POST /api/v1/images endpoint (proper image usage/billing, image-specific params) — worth bumping from 2.9.0 to pick that up.

Switches imageModel() to OpenRouter's POST /api/v1/images endpoint for
proper image usage/billing and image-specific params.
@vkeerthivikram

vkeerthivikram commented Jul 7, 2026

Copy link
Copy Markdown
Contributor Author

This looks great. One note: @openrouter/ai-sdk-provider 2.10.0 switched imageModel() to OpenRouter's dedicated POST /api/v1/images endpoint (proper image usage/billing, image-specific params) — worth bumping from 2.9.0 to pick that up.

Done

@vkeerthivikram

Copy link
Copy Markdown
Contributor Author

tui-image-gen.webm
vscode-image-gen.webm
Please see attached screen recordings for sample user flows

Comment thread packages/kilo-gateway/package.json Outdated
Comment thread packages/kilo-vscode/webview-ui/src/i18n/zh.ts Outdated
Comment thread packages/opencode/src/kilocode/tool/generate-image.ts Outdated
Comment thread .kilo/plans/1782130204245-image-generation-tool.md Outdated
<!-- packages/opencode/src/kilocode/server/httpapi/public.ts -->
- <https://opencode.ai/zen>
<!-- packages/kilo-vscode/webview-ui/src/i18n/en.ts -->
- <https://openrouter.ai/api/v1/chat/completions>

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think we probably don't want to add support for this first in kilo gateway in the backend. Then this PR could use openrouter's image generation models accordingly. This would also allow moving some of the model specific logic into our backend. I can take a look into this.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks for offering to look into this! Happy to leave image generation to land in the kilo-gateway backend first and consume it from there. Let me know if you need anything from my end on the client side to support it.

- revert @openrouter/ai-sdk-provider 2.9.0->2.10.0 bump (image tool uses raw HTTP, not the SDK)
- translate image generation settings strings across all locales
- use central KILO_OPENROUTER_BASE instead of hardcoded URL fallback
- remove completed plan file
@vkeerthivikram

Copy link
Copy Markdown
Contributor Author

Pairs nicely with #12010 (inline image rendering in the chat view) — once a generated image is read back into context, it will render inline.

@marius-kilocode

Copy link
Copy Markdown
Collaborator
image image

Tested one more time with kilo gateway. This works already

@marius-kilocode marius-kilocode merged commit dfa712d into Kilo-Org:main Jul 8, 2026
25 checks passed
@marius-kilocode

Copy link
Copy Markdown
Collaborator

@vkeerthivikram Merged the feature! Thanks a lot for the contribution, hope it brings value!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants