feat: add capability-aware reasoning effort controls (#593)

* feat(reasoning): add capability-aware effort resolution

- resolve requested reasoning levels against exact model capabilities

- persist requested effort on agents and expose effective effort in traces

- add backend tests for provider models, agent store, and resolution logic

Refs #591

* feat(ui): gate reasoning controls by model capabilities

- only show supported reasoning levels when provider model metadata is available

- preserve expert reasoning selections during async model loading

- surface effective reasoning details in trace dialogs and localized copy

Refs #591

* docs(api): document capability-aware reasoning controls

- describe exact-match capability lookup and downgrade behavior

- update provider model metadata and trace response documentation

- refresh the generated OpenAPI spec for the new reasoning fields

Refs #591

* feat: add provider-first reasoning controls

* docs: refresh PR 593 UI evidence callouts

* refactor: deduplicate reasoning normalize functions and remove PR evidence

- Export NormalizeReasoningEffort/NormalizeReasoningFallback from providers
  package; store package now delegates instead of duplicating
- Store reasoning fallback constants alias providers canonical definitions
- Export deriveLegacyThinkingLevel from types/provider.ts; remove local
  copies from agent-advanced-dialog and provider-overview
- Remove unused _providerType param from useProviderModels hook
- Fix reasoning debug log to fire for all cases with a reason (not just
  non-off efforts)
- Remove docs/pr-593-evidence/ binary screenshots from repo

---------

Co-authored-by: viettranx <viettranx@gmail.com>
This commit is contained in:
Kai (Tam Nhu) Tranandviettranx authored and GitHub committed 2026-03-31 07:56:01 +07:00
1 parent 1dee22aeb7
commit 3ca3bb2062
41 files changed
+2354 -213

No files matched your search

+114 -10
View File
@@ -487,7 +487,56 @@
"tags": ["Providers"],
"summary": "List available models",
"parameters": [{ "name": "id", "in": "path", "required": true, "schema": { "type": "string", "format": "uuid" } }],
"responses": { "200": { "description": "Model list" } }
"responses": {
"200": {
"description": "Model list with optional reasoning capability metadata",
"content": {
"application/json": {
"schema": {
"type": "object",
"properties": {
"models": {
"type": "array",
"items": {
"type": "object",
"properties": {
"id": { "type": "string" },
"name": { "type": "string" },
"reasoning": {
"type": "object",
"properties": {
"levels": {
"type": "array",
"items": { "type": "string" }
},
"default_effort": { "type": "string" }
}
}
},
"required": ["id"]
}
},
"reasoning_defaults": {
"type": "object",
"description": "Provider-owned default reasoning policy returned when the provider has saved defaults and at least one discovered model exposes reasoning capability metadata.",
"properties": {
"effort": {
"type": "string",
"enum": ["off", "auto", "none", "minimal", "low", "medium", "high", "xhigh"]
},
"fallback": {
"type": "string",
"enum": ["downgrade", "off", "provider_default"]
}
}
}
},
"required": ["models"]
}
}
}
}
}
}
},
"/v1/providers/{id}/verify": {
@@ -837,14 +886,37 @@
"description": { "type": "string" },
"provider": { "type": "string", "description": "LLM provider name" },
"model": { "type": "string", "description": "Model ID" },
"system_prompt": { "type": "string" },
"other_config": {
"type": "object",
"description": "Optional per-agent JSON config.",
"properties": {
"chatgpt_oauth_routing": {
"type": "object",
"description": "Optional agent-side routing override for ChatGPT OAuth providers. The main provider field remains the preferred/default account, while provider settings may supply inherited defaults.",
"system_prompt": { "type": "string" },
"other_config": {
"type": "object",
"description": "Optional per-agent JSON config.",
"properties": {
"thinking_level": {
"type": "string",
"enum": ["off", "low", "medium", "high"],
"description": "Legacy coarse reasoning shim. Unset means off."
},
"reasoning": {
"type": "object",
"description": "Capability-aware reasoning policy for GPT-5/Codex models.",
"properties": {
"override_mode": {
"type": "string",
"enum": ["inherit", "custom"]
},
"effort": {
"type": "string",
"enum": ["off", "auto", "none", "minimal", "low", "medium", "high", "xhigh"]
},
"fallback": {
"type": "string",
"enum": ["downgrade", "off", "provider_default"]
}
}
},
"chatgpt_oauth_routing": {
"type": "object",
"description": "Optional agent-side routing override for ChatGPT OAuth providers. The main provider field remains the preferred/default account, while provider settings may supply inherited defaults.",
"properties": {
"override_mode": { "type": "string", "enum": ["inherit", "custom"] },
"strategy": { "type": "string", "enum": ["manual", "primary_first", "round_robin", "priority_order"] },
@@ -864,7 +936,39 @@
"provider_type": { "type": "string", "enum": ["anthropic_native", "openai_compat", "gemini_native", "openrouter", "groq", "deepseek", "mistral", "xai", "minimax_native", "cohere", "perplexity", "dashscope", "bailian", "chatgpt_oauth", "claude_cli", "suno", "yescale", "zai", "zai_coding", "ollama", "ollama_cloud", "acp"] },
"api_base": { "type": "string" },
"api_key": { "type": "string" },
"enabled": { "type": "boolean", "default": true }
"enabled": { "type": "boolean", "default": true },
"settings": {
"type": "object",
"description": "Provider-specific settings such as provider-owned Codex pool defaults and reasoning defaults.",
"properties": {
"reasoning_defaults": {
"type": "object",
"properties": {
"effort": {
"type": "string",
"enum": ["off", "auto", "none", "minimal", "low", "medium", "high", "xhigh"]
},
"fallback": {
"type": "string",
"enum": ["downgrade", "off", "provider_default"]
}
}
},
"codex_pool": {
"type": "object",
"properties": {
"strategy": {
"type": "string",
"enum": ["manual", "primary_first", "round_robin", "priority_order"]
},
"extra_provider_names": {
"type": "array",
"items": { "type": "string" }
}
}
}
}
}
}
},
"Error": {