feat(vscode): configure provider output effort

Co-authored-by: kiloconnect[bot] <240665456+kiloconnect[bot]@users.noreply.github.com>
This commit is contained in:
chrarnoldus
2026-06-15 11:19:01 +00:00
parent f97b6bc1bc
commit a65f780fdd
8 changed files with 64 additions and 1 deletions
+1 -1
View File
@@ -2,4 +2,4 @@
"kilo-code": minor
---
Support multiple provider APIs, adaptive thinking, and split reasoning variants for custom providers.
Support multiple provider APIs, adaptive thinking, split reasoning, and output effort variants for custom providers.
@@ -17,6 +17,7 @@ const VariantConfigSchema = z.object({
thinking: z.object({ type: z.enum(["enabled", "disabled", "adaptive"]) }).optional(),
reasoning_split: z.boolean().optional(),
reasoningEffort: z.enum(["none", "minimal", "low", "medium", "high", "xhigh"]).optional(),
effort: z.enum(["low", "medium", "high", "xhigh", "max"]).optional(),
chat_template_args: z.object({ enable_thinking: z.boolean() }).optional(),
})
@@ -65,6 +65,7 @@ describe("validateCustomProvider variant name validation", () => {
enableThinking: undefined,
thinking: undefined,
splitReasoning: undefined,
outputEffort: undefined,
reasoningEffort: undefined,
chatTemplateArgs: undefined,
},
@@ -83,6 +84,7 @@ describe("validateCustomProvider variant name validation", () => {
enableThinking: undefined,
thinking: undefined,
splitReasoning: undefined,
outputEffort: undefined,
reasoningEffort: undefined,
chatTemplateArgs: undefined,
},
@@ -101,6 +103,7 @@ describe("validateCustomProvider variant name validation", () => {
enableThinking: undefined,
thinking: undefined,
splitReasoning: undefined,
outputEffort: undefined,
reasoningEffort: undefined,
chatTemplateArgs: undefined,
},
@@ -119,6 +122,7 @@ describe("validateCustomProvider variant name validation", () => {
enableThinking: undefined,
thinking: undefined,
splitReasoning: undefined,
outputEffort: undefined,
reasoningEffort: undefined,
chatTemplateArgs: undefined,
},
@@ -127,6 +131,7 @@ describe("validateCustomProvider variant name validation", () => {
enableThinking: undefined,
thinking: undefined,
splitReasoning: undefined,
outputEffort: undefined,
reasoningEffort: undefined,
chatTemplateArgs: undefined,
},
@@ -145,6 +150,7 @@ describe("validateCustomProvider variant name validation", () => {
enableThinking: undefined,
thinking: undefined,
splitReasoning: undefined,
outputEffort: undefined,
reasoningEffort: undefined,
chatTemplateArgs: undefined,
},
@@ -167,6 +173,7 @@ describe("validateCustomProvider variant name validation", () => {
enableThinking: true,
thinking: "adaptive",
splitReasoning: false,
outputEffort: "max",
reasoningEffort: "low",
chatTemplateArgs: undefined,
},
@@ -179,6 +186,7 @@ describe("validateCustomProvider variant name validation", () => {
enable_thinking: true,
thinking: { type: "adaptive" },
reasoning_split: false,
effort: "max",
reasoningEffort: "low",
},
})
@@ -132,6 +132,7 @@ describe("sanitizeCustomProviderConfig", () => {
thinking: {
thinking: { type: "adaptive" },
reasoning_split: true,
effort: "max",
chat_template_args: { enable_thinking: true },
},
},
@@ -26,6 +26,7 @@ import type {
ChatTemplateArgsValue,
EnableThinkingValue,
ModelEntry,
OutputEffortValue,
ReasoningEffortValue,
ThinkingTypeValue,
VariantEntry,
@@ -92,6 +93,7 @@ const CustomProviderDialog = (props: CustomProviderDialogProps) => {
splitReasoning: typeof vcfg.reasoning_split === "boolean" ? vcfg.reasoning_split : undefined,
reasoningEffort:
typeof vcfg.reasoningEffort === "string" ? (vcfg.reasoningEffort as ReasoningEffortValue) : undefined,
outputEffort: typeof vcfg.effort === "string" ? (vcfg.effort as OutputEffortValue) : undefined,
chatTemplateArgs:
typeof vcfg.chat_template_args === "object" && vcfg.chat_template_args !== null
? ((vcfg.chat_template_args as { enable_thinking?: boolean }).enable_thinking as ChatTemplateArgsValue)
@@ -373,6 +375,7 @@ const CustomProviderDialog = (props: CustomProviderDialogProps) => {
thinking: undefined,
splitReasoning: undefined,
reasoningEffort: undefined,
outputEffort: undefined,
chatTemplateArgs: undefined,
}
setForm("models", mi, "variants", (v) => [...v, blank])
@@ -599,6 +602,9 @@ const CustomProviderDialog = (props: CustomProviderDialogProps) => {
onChangeVariantReasoningEffort={(vi, val) =>
setForm("models", i(), "variants", vi, "reasoningEffort", val)
}
onChangeVariantOutputEffort={(vi, val) =>
setForm("models", i(), "variants", vi, "outputEffort", val)
}
onChangeVariantChatTemplateArgs={(vi, val) =>
setForm("models", i(), "variants", vi, "chatTemplateArgs", val)
}
@@ -12,6 +12,7 @@ export type EnableThinkingValue = undefined | boolean
export type ThinkingTypeValue = undefined | "enabled" | "disabled" | "adaptive"
export type SplitReasoningValue = undefined | boolean
export type ReasoningEffortValue = undefined | "none" | "minimal" | "low" | "medium" | "high" | "xhigh"
export type OutputEffortValue = undefined | "low" | "medium" | "high" | "xhigh" | "max"
export type ChatTemplateArgsValue = undefined | boolean
export type VariantEntry = {
@@ -20,6 +21,7 @@ export type VariantEntry = {
thinking: ThinkingTypeValue
splitReasoning: SplitReasoningValue
reasoningEffort: ReasoningEffortValue
outputEffort: OutputEffortValue
chatTemplateArgs: ChatTemplateArgsValue
}
@@ -67,6 +69,15 @@ const REASONING_EFFORT_OPTIONS: SelectOption<ReasoningEffortValue>[] = [
{ value: "xhigh", labelKey: "provider.custom.models.variants.reasoningEffort.xhigh" },
]
const OUTPUT_EFFORT_OPTIONS: SelectOption<OutputEffortValue>[] = [
{ value: undefined, labelKey: "provider.custom.models.variants.option.unset" },
{ value: "low", labelKey: "provider.custom.models.variants.outputEffort.low" },
{ value: "medium", labelKey: "provider.custom.models.variants.outputEffort.medium" },
{ value: "high", labelKey: "provider.custom.models.variants.outputEffort.high" },
{ value: "xhigh", labelKey: "provider.custom.models.variants.outputEffort.xhigh" },
{ value: "max", labelKey: "provider.custom.models.variants.outputEffort.max" },
]
type VariantRowProps = {
v: VariantEntry
vi: () => number
@@ -78,6 +89,7 @@ type VariantRowProps = {
onChangeThinking: (val: ThinkingTypeValue) => void
onChangeSplitReasoning: (val: SplitReasoningValue) => void
onChangeReasoningEffort: (val: ReasoningEffortValue) => void
onChangeOutputEffort: (val: OutputEffortValue) => void
onChangeChatTemplateArgs: (val: ChatTemplateArgsValue) => void
onRemove: () => void
}
@@ -212,6 +224,31 @@ function VariantRow(props: VariantRowProps) {
triggerVariant="settings"
/>
</div>
<div
style={{
display: "flex",
"flex-direction": "column",
gap: "4px",
flex: "0 0 auto",
}}
>
<label
style={{ "font-size": "var(--kilo-font-size-12)", "font-weight": "500", color: "var(--text-weak-base)" }}
>
{props.t("provider.custom.models.variants.outputEffort.label")}
</label>
<Select
options={OUTPUT_EFFORT_OPTIONS}
current={OUTPUT_EFFORT_OPTIONS.find((o) => o.value === props.v.outputEffort)}
value={(o) => String(o.value)}
label={(o) => props.t(o.labelKey)}
onSelect={(o) => props.onChangeOutputEffort(o?.value)}
placeholder={props.t("provider.custom.models.variants.outputEffort.placeholder")}
variant="secondary"
size="small"
triggerVariant="settings"
/>
</div>
<div
style={{
display: "flex",
@@ -267,6 +304,7 @@ type ModelCardProps = {
onChangeVariantThinking: (vi: number, val: ThinkingTypeValue) => void
onChangeVariantSplitReasoning: (vi: number, val: SplitReasoningValue) => void
onChangeVariantReasoningEffort: (vi: number, val: ReasoningEffortValue) => void
onChangeVariantOutputEffort: (vi: number, val: OutputEffortValue) => void
onChangeVariantChatTemplateArgs: (vi: number, val: ChatTemplateArgsValue) => void
}
@@ -356,6 +394,7 @@ export function ModelCard(props: ModelCardProps) {
onChangeThinking={(val) => props.onChangeVariantThinking(vi(), val)}
onChangeSplitReasoning={(val) => props.onChangeVariantSplitReasoning(vi(), val)}
onChangeReasoningEffort={(val) => props.onChangeVariantReasoningEffort(vi(), val)}
onChangeOutputEffort={(val) => props.onChangeVariantOutputEffort(vi(), val)}
onChangeChatTemplateArgs={(val) => props.onChangeVariantChatTemplateArgs(vi(), val)}
onRemove={() => props.onRemoveVariant(vi())}
/>
@@ -109,6 +109,7 @@ function serializeVariant(v: VariantEntry): [string, Record<string, unknown>] {
if (v.thinking !== undefined) cfg.thinking = { type: v.thinking }
if (v.splitReasoning !== undefined) cfg.reasoning_split = v.splitReasoning
if (v.reasoningEffort !== undefined) cfg.reasoningEffort = v.reasoningEffort
if (v.outputEffort !== undefined) cfg.effort = v.outputEffort
if (v.chatTemplateArgs !== undefined) cfg.chat_template_args = { enable_thinking: v.chatTemplateArgs }
return [v.name.trim(), cfg]
}
@@ -856,6 +856,13 @@ export const dict = {
"provider.custom.models.variants.reasoningEffort.medium": "medium",
"provider.custom.models.variants.reasoningEffort.high": "high",
"provider.custom.models.variants.reasoningEffort.xhigh": "xhigh",
"provider.custom.models.variants.outputEffort.label": "Output effort (e.g. Anthropic)",
"provider.custom.models.variants.outputEffort.placeholder": "effort",
"provider.custom.models.variants.outputEffort.low": "low",
"provider.custom.models.variants.outputEffort.medium": "medium",
"provider.custom.models.variants.outputEffort.high": "high",
"provider.custom.models.variants.outputEffort.xhigh": "xhigh",
"provider.custom.models.variants.outputEffort.max": "max",
"provider.custom.models.remove": "Remove model",
"provider.custom.models.add": "Add model",
"provider.custom.models.fetch": "Fetch models",