Add status === 'deprecated' check for OpenCode Zen models, matching
the existing pattern used for GitHub Copilot models. This removes
deprecated models like glm-4.7-free and minimax-m2.1-free from the
generated model catalog.
Allows custom models to specify which upstream providers OpenRouter
should route requests to via the `openRouterRouting` field in model
definitions.
Supported fields:
- `only`: list of provider slugs to exclusively use
- `order`: list of provider slugs to try in order
When Google providers return tool calls without an args field (common for
no-argument tools), the arguments field was undefined. This breaks
subsequent API calls that require tool_use.input to be present.
Now defaults to {} when args is missing.
Related: clawdbot/clawdbot#1509
- anthropic.ts: use model.api instead of hardcoding 'anthropic-messages'
- openai-responses.ts: use model.api instead of hardcoding 'openai-responses'
- gitlab-duo: simplify to use actual model IDs, export MODELS array
- Add resetApiProviders() to clear and re-register built-in providers
- Add createAssistantMessageEventStream() factory for extensions
- Add streamSimple support in ProviderConfig for custom API implementations
- Call resetApiProviders() on /reload to clean up extension providers
- Add custom-provider.md documentation
- Add custom-provider.ts example with full Anthropic implementation
- Update extensions.md with streamSimple config option
fix bug encountered when running GLM-4.7-Flash hosted by LM Studio, in
which the provider sends tool call arguments via
`response.function_call_arguments.done` events instead of streaming them
via `response.function_call_arguments.delta` events. The final
`response.output_item.done` event then contains empty `{}` arguments.
The code only handled delta events, so tool calls failed with validation
errors like `"must have required property 'command'"`.
Full disclosure, Opus triaged the bug and provided the fix (by adding
logging statements to the req/resp to the upstream provider (LM
Studio)). I'm to provide prompts/transcripts, and acknowledge that I'm
not an expert in Pi internals at this time.
When switching between OpenAI models (e.g., gpt-5-mini to gpt-5.2-codex),
function_call IDs with fc_ prefix trigger pairing validation errors because
OpenAI tracks which fc_xxx IDs were paired with rs_xxx reasoning items.
The fix omits the id field for function_calls from different models, which
avoids the pairing validation while keeping call_id for matching with
function_call_output.
Fixes#886
- Added headers field to base StreamOptions interface
- Updated all providers to merge options.headers with defaults
- Forward headers and onPayload through streamSimple/completeSimple
- Bedrock not supported (uses AWS SDK auth)
Fixes OpenAI Responses 400 error 'reasoning without following item' by
skipping errored/aborted assistant messages entirely rather than filtering
at the provider level. This covers openai-responses, openai-codex-responses,
and future providers.
Removes strictResponsesPairing compat option (no longer needed).
Closes#838
Split OpenAICompat into OpenAICompletionsCompat and OpenAIResponsesCompat
for type-safe API-specific compat settings. Added strictResponsesPairing
option to suppress orphaned reasoning/tool calls on incomplete turns,
fixing 400 errors on Azure's Responses API which requires strict pairing.
Closes#768
- Replace hardcoded pi->CC tool mappings with single CC tool name list
- Case-insensitive lookup: if tool name matches CC tool, use CC casing
- Remove broken find->Glob mapping (round-trip failed)
- Add test coverage for tool name normalization
When an assistant message has stopReason 'error', its tool calls are now
excluded from pending tool tracking. This prevents synthetic tool results
from being generated for calls that will be dropped by provider-specific
converters (e.g., Codex drops tool calls from errored messages).
Previously, this mismatch caused OpenAI to reject requests with 'No tool
call found for function call output with call_id ...' errors.
fixes#812
Bedrock Claude models require max_tokens to exceed thinking.budget_tokens.
This constraint was handled for anthropic-messages API but missing for
bedrock-converse-stream, causing compaction failures.
Extracted adjustMaxTokensForThinking() helper that:
- Adds thinking budget on top of desired output tokens
- Reduces thinking budget if insufficient room (min 1024 output tokens)
- Applied to both anthropic-messages and bedrock-converse-stream APIs
Instead of skipping unsigned tool calls entirely (which lobotomizes context),
convert them to text with an explicit note telling the model this is historical
context from a different model and not a format to mimic.
This preserves tool call/result context when switching from providers without
thought signatures (e.g. Claude via Antigravity) to Gemini 3.
When 429/500 errors occur during tool execution, empty assistant messages
with stopReason='error' get persisted. These break the tool_use -> tool_result
chain for Claude/Gemini APIs.
Added centralized filtering in transformMessages to skip assistant messages
with empty content and no tool calls. Provider-level filters remain for
defense-in-depth.
Previously, OpenAI-compatible provider settings (like developer role support)
were detected only from the baseUrl. When using custom URLs (e.g., proxies),
detection failed. Now checks model.provider first, then falls back to URL.
Fixes#774