Merge pull request #12982 from Kilo-Org/investigate-kilocode-luna-openai-usage-leak

feat(vscode): sync model selector with slash command overrides
This commit is contained in:
Marius
2026-08-07 12:39:07 +02:00
committed by GitHub
7 changed files with 90 additions and 17 deletions
@@ -0,0 +1,5 @@
---
"kilo-code": patch
---
Update the active model, mode, and thinking selectors when executing a slash command with configured overrides.
@@ -13,12 +13,18 @@ export async function loadCommands(client: KiloClient, dir: string): Promise<unk
const promise = retry(() => client.command.list({ directory: dir }, { throwOnError: true })).then(({ data }) => ({
type: "commandsLoaded",
commands: data.map((cmd) => ({
name: cmd.name,
description: cmd.description,
source: cmd.source,
hints: cmd.hints,
})),
commands: data.map((cmd) => {
const item = cmd as typeof cmd & { variant?: string }
return {
name: item.name,
description: item.description,
agent: item.agent,
model: item.model,
variant: item.variant,
source: item.source,
hints: item.hints,
}
}),
}))
promises.set(dir, promise)
@@ -78,6 +78,15 @@ describe("sendCommand dismisses pending tool requests", () => {
it("rejects questions before sending", () => {
expect(body).toContain("dismissQuestion")
})
it("applies model, agent, and variant overrides when provided by a command", () => {
expect(body).toContain("if (overrides?.agent)")
expect(body).toContain("selectAgent(overrides.agent, scope)")
expect(body).toContain("if (overrides?.model)")
expect(body).toContain("selectModel(parsed.providerID, parsed.modelID, scope)")
expect(body).toContain("if (overrides?.variant)")
expect(body).toContain("selectVariant(overrides.variant, scope)")
})
})
describe("static command completion contract", () => {
@@ -188,4 +188,31 @@ describe("useSlashCommand sandbox action", () => {
expect(ctx.slash.results()[0]?.description).toBe("Toggle sandbox")
ctx.dispose()
})
it("preserves model, agent, and variant metadata on loaded server commands", () => {
const ctx = setup(() => {})
ctx.fire({
type: "commandsLoaded",
commands: [
{
name: "ship",
description: "Ship PR",
agent: "code",
model: "openai/gpt-5.6-luna-fast",
variant: "xhigh",
hints: ["deploy"],
},
],
})
ctx.slash.onInput("/ship", 5)
const matches = ctx.slash.results()
expect(matches).toHaveLength(1)
expect(matches[0]?.name).toBe("ship")
expect(matches[0]?.agent).toBe("code")
expect(matches[0]?.model).toBe("openai/gpt-5.6-luna-fast")
expect(matches[0]?.variant).toBe("xhigh")
ctx.dispose()
})
})
@@ -1239,6 +1239,11 @@ export const PromptInput: Component<PromptInputProps> = (props) => {
pendingId,
context,
origin ?? null,
{
agent: matched.agent,
model: matched.model,
variant: matched.variant,
},
)
} else {
session.sendMessage(message, sel?.providerID, sel?.modelID, attachments, pendingId, context, data, origin ?? null)
@@ -283,6 +283,7 @@ interface SessionContextValue {
draftID?: string,
context?: string,
origin?: string | null,
overrides?: { agent?: string; model?: string; variant?: string },
) => void
abort: () => void
compact: () => void
@@ -2352,31 +2353,51 @@ export const SessionProvider: ParentComponent = (props) => {
draftID?: string,
context?: string,
origin?: string | null,
overrides?: { agent?: string; model?: string; variant?: string },
) {
if (!server.isConnected()) {
console.warn("[Kilo New] Cannot send command: not connected")
return
}
// Cloud previews need import-then-command; post importAndSend with command metadata
const sid = origin === undefined ? currentSessionID() : (origin ?? undefined)
const selection = providerID && modelID ? { providerID, modelID } : selected(sid)
recordModelUsage(selection?.providerID, selection?.modelID)
const effectiveDraftID = !sid && !draftID ? crypto.randomUUID() : draftID
const scope = effectiveDraftID ?? sid
if (!sid && !draftID && effectiveDraftID) agentDrafts.seed(effectiveDraftID)
if (overrides?.agent) {
selectAgent(overrides.agent, scope)
}
if (overrides?.model) {
const parsed = parseModelString(overrides.model)
if (parsed) {
selectModel(parsed.providerID, parsed.modelID, scope)
}
}
if (overrides?.variant) {
selectVariant(overrides.variant, scope)
}
const effectiveSelection = selected(scope)
const effectiveProvider = effectiveSelection?.providerID ?? providerID
const effectiveModel = effectiveSelection?.modelID ?? modelID
recordModelUsage(effectiveProvider, effectiveModel)
// Cloud previews need import-then-command; post importAndSend with command metadata
const preview = sid?.startsWith("cloud:")
? sid.slice("cloud:".length)
: origin === undefined
? cloudPreviewId()
: null
if (preview) {
const scope = draftID ?? sid
const agent = promptAgent(scope)
vscode.postMessage({
type: "importAndSend",
cloudSessionId: preview,
text: `/${command} ${args}`.trim(),
messageID: Identifier.ascending("message"),
providerID,
modelID,
providerID: effectiveProvider,
modelID: effectiveModel,
agent,
variant: currentVariant(scope),
files,
@@ -2393,9 +2414,6 @@ export const SessionProvider: ParentComponent = (props) => {
dismissQuestion(q.id)
}
const effectiveDraftID = !sid && !draftID ? crypto.randomUUID() : draftID
const scope = effectiveDraftID ?? sid
if (!sid && !draftID && effectiveDraftID) agentDrafts.seed(effectiveDraftID)
if (scope) {
clearClose(scope)
addOptimistic(scope, messageID, `/${command} ${args}`.trim(), files)
@@ -2414,8 +2432,8 @@ export const SessionProvider: ParentComponent = (props) => {
messageID,
sessionID: sid,
draftID: effectiveDraftID,
providerID,
modelID,
providerID: effectiveProvider,
modelID: effectiveModel,
agent,
variant: currentVariant(scope),
files,
@@ -11,6 +11,9 @@ export interface SkillInfo {
export interface SlashCommandInfo {
name: string
description?: string
agent?: string
model?: string
variant?: string
source?: "command" | "mcp" | "skill"
hints: string[]
}