Skip to content

feat: support subagent reasoning overrides - #11184

Merged
marius-kilocode merged 1 commit into
mainfrom
snow-recorder
Jun 12, 2026
Merged

feat: support subagent reasoning overrides#11184
marius-kilocode merged 1 commit into
mainfrom
snow-recorder

Conversation

@marius-kilocode

@marius-kilocode marius-kilocode commented Jun 12, 2026

Copy link
Copy Markdown
Collaborator

The global subagent model setting previously coupled reasoning effort to a single legacy variant value, which could become invalid when models changed and could not safely account for custom subagents using different models.

This adds model-specific subagent variant overrides while keeping the settings UI focused on one model and one matching reasoning selector. The general subagent receives the selected model and reasoning effort, while custom subagents retain their own model and only receive an override when one exists and is valid for that exact model. Stale or incompatible variants fall back to the agent's resolved variant instead of crossing model boundaries.

The settings controls also constrain long model labels to their input column so names truncate rather than overlap adjacent content.

file-eb2b53c39bea42f5aa9a9ded4dbd8ebf file-fc9aa0b11c00a659e64fbbd608d49bf7 file-47f834151cfba43986842a2fb9bb9491

if (choice.direct) {
const value = override(choice.model)
if (!value) return { model: choice.model, variant: choice.variant }
const full = yield* input.provider.getModel(choice.model.providerID, choice.model.modelID)

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: getModel is called here without a ProviderModelNotFoundError handler, unlike the adjacent non-direct path (lines 153–164) and the parent fallback path (lines 177–179).

If an agent has model hard-coded in its config and the provider later removes or renames that model, and the user has set a subagent_variant_override for it, this call will propagate an unhandled ProviderModelNotFoundError rather than gracefully falling back to choice.variant.

The fix mirrors the parent fallback:

const full = yield* input.provider
  .getModel(choice.model.providerID, choice.model.modelID)
  .pipe(Effect.catchTag("ProviderModelNotFoundError", () => Effect.succeed(undefined)))
const variant = full?.variants?.[value] ? value : choice.variant
return { model: choice.model, variant }

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

@kilo-code-bot

kilo-code-bot Bot commented Jun 12, 2026

Copy link
Copy Markdown
Contributor

Code Review Summary

Status: 2 Issues Found | Recommendation: Address before merge

Overview

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

WARNING

File Line Issue
packages/opencode/src/kilocode/tool/task.ts 149 getModel called without ProviderModelNotFoundError handler in the direct branch when an override is present — unhandled error if model is missing

SUGGESTION

File Line Issue
packages/sdk/js/src/v2/gen/types.gen.ts 1335 SDK type { [key: string]: string } omits null values allowed by Config.Info and the webview Config type — no delete-sentinel support in the SDK contract
Other Observations (not in diff)

SDK type narrower than runtime: packages/sdk/js/src/v2/gen/types.gen.ts:1335-1337 declares subagent_variant_overrides as { [key: string]: string }. The authoritative schema in packages/opencode/src/config/config.ts and the webview type in packages/kilo-vscode/webview-ui/src/types/messages/config.ts both allow string | null values (nulls act as delete sentinels for individual model entries). The generated SDK type is derived from packages/sdk/openapi.json which only has "type": "string" for the additional-properties value — it has no null there either. This is a generated artifact drift: the openapi.json and SDK type don't represent the null-sentinel protocol the backend actually accepts. As a result, any SDK consumer that inspects the type contract would not know to send null to clear a single model entry. Consider either adding nullable: true to the additionalProperties in openapi.json/config schema, or documenting this as intentional (that nulls are an internal merge protocol not surfaced via the public API).

No test for direct-path model missing + override: The test suite covers stale variants on the direct path ("stale model-specific override preserves the resolved variant"), but not the case where the agent's hard-coded model is missing from the provider and an override is set — the unhandled error path flagged inline would not be caught by existing tests.

Files Reviewed (8 files)
  • packages/opencode/src/kilocode/tool/task.ts — 1 issue
  • packages/opencode/src/config/config.ts
  • packages/opencode/test/kilocode/tool-task-model.test.ts
  • packages/opencode/test/kilocode/config/config.test.ts
  • packages/kilo-vscode/webview-ui/src/components/settings/ModelsTab.tsx
  • packages/kilo-vscode/webview-ui/src/types/messages/config.ts
  • packages/sdk/js/src/v2/gen/types.gen.ts — 1 observation
  • packages/kilo-vscode/tests/unit/settings-io.test.ts
  • .changeset/bright-subagents-reason.md

Fix these issues in Kilo Cloud


Reviewed by claude-4.6-sonnet-20260217 · 1,568,548 tokens

Review guidance: REVIEW.md from base branch main

@marius-kilocode
marius-kilocode merged commit 37a7618 into main Jun 12, 2026
22 checks passed
@marius-kilocode
marius-kilocode deleted the snow-recorder branch June 12, 2026 18:57
LigiaZ added a commit that referenced this pull request Jun 12, 2026
NJ-2020 pushed a commit to NJ-2020/kilocode that referenced this pull request Jul 4, 2026
t7tran pushed a commit to t7tran/kilocode that referenced this pull request Aug 14, 2026
t7tran pushed a commit to t7tran/kilocode that referenced this pull request Aug 14, 2026
feat: support subagent reasoning overrides
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.

2 participants