fix(kiro): map GPT-5.6 reasoning effort fields

Route GPT-5.6 reasoning effort through Kiro's native reasoning.effort field instead of the legacy Claude output_config.effort path. GPT-5.6 models now emit reasoning.effort for low/medium/high/xhigh, with max mapped to the xhigh wire value.

Preserve the Responses API reasoning.effort through the OpenAI intermediate by copying it to reasoning_effort before the field is dropped. Skip legacy thinking_mode prompt tags when a supported native GPT effort is emitted, while keeping the legacy fallback for unsupported values (auto/minimal/ultra) and explicit disable semantics (none/off/disabled). Claude adaptive effort continues to use thinking plus output_config.effort.
This commit is contained in:
Edison42
2026-07-20 11:08:23 +07:00
parent d587b2a487
commit cef5dd4d61
7 changed files with 193 additions and 35 deletions

View File

@@ -8,8 +8,8 @@
* - `-agentic` model suffix detection + chunked-write system prompt
* - reasoning / thinking trigger detection (Anthropic-Beta header,
* Claude `thinking`, OpenAI `reasoning_effort`, AMP/Cursor magic tag)
* - the `<thinking_mode>enabled</thinking_mode>` system-prompt injection
* that turns Kiro reasoning on
* - schema-specific native effort fields for supported GPT and Claude models
* - legacy `<thinking_mode>` system-prompt injection for other models
*
* Kiro upstream does not advertise `-agentic` model IDs; they are a 9router
* fiction. The suffix is stripped before the request leaves this process.
@@ -109,6 +109,7 @@ export function resolveKiroThinkingBudget(body, headers, model) {
const cfg = extractThinking(body);
if (cfg) {
if (cfg.mode === "none") return null;
if (cfg.mode === "level" && cfg.level === "disabled") return null;
if (cfg.mode === "budget") return cfg.budget;
if (cfg.mode === "level") return effortToBudget(cfg.level) ?? KIRO_THINKING_BUDGET_DEFAULT;
return KIRO_THINKING_BUDGET_DEFAULT;
@@ -144,8 +145,25 @@ export function extractKiroEffortLevel(body) {
return null;
}
function extractKiroGptEffortLevel(body) {
const effort =
body?.output_config?.effort ??
body?.reasoning_effort ??
(typeof body?.reasoning === "object" ? body.reasoning?.effort : null);
if (typeof effort !== "string") return null;
const normalized = effort.toLowerCase();
if (normalized === "max") return "xhigh";
// Kiro CLI does not advertise an explicit GPT "none" wire value; omit it.
if (["low", "medium", "high", "xhigh"].includes(normalized)) {
return normalized;
}
return null;
}
export function buildKiroAdditionalModelRequestFields(body, effortPath = "output_config") {
const effort = extractKiroEffortLevel(body);
const effort = effortPath === "reasoning"
? extractKiroGptEffortLevel(body)
: extractKiroEffortLevel(body);
if (!effort) return undefined;
if (effortPath === "reasoning") {
// Mirrors Kiro CLI/KAS buildEffortRequestFields("reasoning") for GPT.
@@ -183,6 +201,11 @@ export function supportsKiroAdditionalModelRequestFields(model) {
return resolveKiroEffortPath(model) !== null;
}
export function usesKiroNativeGptEffort(body, model) {
return resolveKiroEffortPath(model) === "reasoning"
&& extractKiroGptEffortLevel(body) !== null;
}
export function buildKiroAdditionalModelRequestFieldsForModel(body, model) {
const effortPath = resolveKiroEffortPath(model);
if (!effortPath) return undefined;