Commit Graph

348 Commits

Author SHA1 Message Date
Mario Zechner f7df474084 fix google vertex unsigned tool call replay closes #4032 2026-04-30 21:59:21 +02:00
Mario Zechner fe66edd943 remove gemini cli and antigravity support 2026-04-30 21:24:36 +02:00
Armin Ronacher 7dc1bed478 feat(ai): add Moonshot AI provider model support 2026-04-30 17:21:03 +02:00
Johannes Ebeling 779d0ef39d feat(ai): add Mistral Medium 3.5 model (#4009) 2026-04-30 12:18:17 +02:00
Alejandro e354c521f4 feat(ai): expose routed model on openai-completions (#3968)
Adds `AssistantMessage.responseModel` on the openai-completions path:
surfaces the concrete `chunk.model` when it differs from the requested
id (e.g. OpenRouter `auto` -> `anthropic/...`).
2026-04-30 00:16:12 +02:00
Mario Zechner 83592bb2df fix(ai): detect incomplete Anthropic streams
closes #3936
2026-04-29 23:30:29 +02:00
Mario Zechner d935a0f4f8 Closes #3900 2026-04-29 22:44:02 +02:00
Mario Zechner fc3cbedc6c fix(ai): track DeepSeek prompt cache hits
closes #3880
2026-04-29 16:37:39 +02:00
Armin Ronacher ed4bc73080 fix(ai): normalize Bedrock model names for profiles 2026-04-28 11:23:31 +02:00
MC d6e08b3da0 feat(ai): add Cloudflare Workers AI as a provider (#3851)
* feat(ai): add Cloudflare Workers AI as a provider

Cloudflare Workers AI hosts open-weight LLMs (Kimi K2.6, GPT-OSS,
GLM-4.7, Llama 4, Gemma 4, Nemotron 3) on Cloudflare's GPU network with
an OpenAI-compatible endpoint. Reuses the openai-completions API
protocol; the per-account URL contains a {CLOUDFLARE_ACCOUNT_ID}
placeholder resolved at request time by a small helper.

Pi automatically sets x-session-affinity for prefix caching:
https://developers.cloudflare.com/workers-ai/features/prompt-caching/

Auth: CLOUDFLARE_API_KEY (matches pi's *_API_KEY convention) +
CLOUDFLARE_ACCOUNT_ID. The User-Agent identifies traffic as
'pi-coding-agent' in Cloudflare analytics.

Verified end-to-end against a real Cloudflare account: 17 e2e tests
pass across stream/empty/tokens/unicode/tool-call-without-result/
total-tokens against @cf/moonshotai/kimi-k2.6.

Cloudflare AI Gateway is a separate, larger change (it requires routing
through provider-specific subpaths with the matching API protocol per
upstream) and will land in a follow-up PR.

* refactor(ai): move Cloudflare User-Agent and session-affinity flag to per-model metadata

Instead of conditionally setting them in openai-completions.ts based on
provider detection, declare them as model-level fields in the catalog
(headers + compat). This is consistent with how the github-copilot and
kimi-coding entries already declare their static headers.

  packages/ai/scripts/generate-models.ts: emit headers and compat fields
  on each cloudflare-workers-ai entry (CLOUDFLARE_STATIC_HEADERS).
  packages/ai/src/providers/openai-completions.ts: drop the
  isCloudflareProvider conditional that injected User-Agent and the
  isCloudflareWorkersAI override of sendSessionAffinityHeaders.
  packages/ai/src/models.generated.ts: re-spliced 8 cloudflare-workers-ai
  entries with headers + compat.

Behavior is unchanged - verified via fetch interceptor that User-Agent
and x-session-affinity / session_id / x-client-request-id are still sent
on outbound requests. 5/5 e2e tests pass.
2026-04-27 23:41:54 +02:00
marcbloech 9dcde1e3fa add cognitive services implementation (#3799) 2026-04-27 18:38:03 +02:00
anirudhmarc 5a07d946ef fix(bedrock): check model.name for prompt caching and adaptive thinking (#3527)
supportsPromptCaching, supportsAdaptiveThinking, supportsThinkingSignature,
and the Claude detection in streamSimpleBedrock/buildAdditionalModelRequestFields
all check model.id for Claude model name patterns. Application inference profile
ARNs are opaque and do not contain the model name, so these checks silently fail.

Fix by also checking model.name (user-controlled via models.json or
registerProvider) as a fallback in all affected functions. Added a shared
isAnthropicClaudeModel helper for the common Claude detection pattern.

Fixes #2925

Co-authored-by: Your Name <you@example.com>
2026-04-25 19:58:17 +02:00
Mario Zechner 3e7ffff184 fix(ai): ignore unknown anthropic sse events
closes #3708
2026-04-25 16:57:03 +02:00
Mario Zechner 953f89fbe9 chore(ai): lower codex default verbosity 2026-04-25 16:20:56 +02:00
HQidea 3e0ee69b5e fix(ai): omit tools field instead of sending empty array (#3650)
DashScope / Aliyun Qwen (OpenAI-compatible) rejects `tools: []`
with HTTP 400 `"[] is too short - 'tools'"`. Five providers used
a truthy check (`if (context.tools)`) that treated an empty array
as "send tools", so `pi --no-tools` produced `tools: []` in the
request body. Matching the Google provider's pattern, we now
guard on `context.tools.length > 0`:

- openai-completions.ts
- openai-responses.ts
- openai-codex-responses.ts
- azure-openai-responses.ts
- anthropic.ts

The openai-completions fallback that emits `tools: []` when the
conversation has tool history (required by LiteLLM / Anthropic
proxies) is preserved via the existing `else if (hasToolHistory)`
branch.

closes #3649

Co-authored-by: 槐聚 <huaiju@zbyte-inc.com>
Co-authored-by: Claude Opus 4.7 <noreply@anthropic.com>
Co-authored-by: Mario Zechner <badlogicgames@gmail.com>
2026-04-24 14:24:31 +02:00
Mario Zechner c1b62ae7fe fix(ai,coding-agent): omit undefined provider request options closes #3627 2026-04-24 14:18:35 +02:00
Mario Zechner c06750410a fix(ai,coding-agent): expose provider timeout/retry controls closes #3627 2026-04-24 13:33:00 +02:00
Mario Zechner 1e33492525 fix(coding-agent): harden clipboard copy
closes #3639
2026-04-24 12:55:58 +02:00
Mario Zechner 65a6472bdd fix(ai): forward google vertex base url
closes #3619
2026-04-24 00:05:43 +02:00
Markus Ylisiurunen ba8f1c228a Align GPT-5.5 Codex capability handling (#3618)
* fix(ai): align gpt-5.5 codex capabilities

* chore(ai): update generated models

* fix(ai): apply gpt-5.5 priority pricing to api

---------

Co-authored-by: Mario Zechner <badlogicgames@gmail.com>
2026-04-23 23:49:33 +02:00
Mario Zechner 4cd4cfd98e fix(ai): support long cache retention compat
closes #3543
2026-04-23 23:43:34 +02:00
Mario Zechner c681d35d76 fix(ai): avoid double-counting reasoning tokens
closes #3581
2026-04-23 23:28:16 +02:00
Mario Zechner ffa0f31239 fix(ai): support Anthropic eager tool streaming compat
closes #3575
2026-04-23 23:12:45 +02:00
Mario Zechner 6af10c9c7f fix(ai): make OpenAI Responses session_id header optional closes #3579 2026-04-23 23:12:24 +02:00
Mario Zechner 01509156b3 fix(ai): coalesce malformed streamed tool calls closes #3576 2026-04-23 16:05:21 +02:00
Armin Ronacher 35ff2689ee fix(typebox): migrate to v1 with extension compat (#3474)
* fix(typebox): migrate to v1 with extension compat

Replace AJV-based validation with TypeBox-native validation, keep legacy extension imports working (including @sinclair/typebox/compiler), and restore coercion for serialized/plain JSON schemas.

This change closes #3112.

* fix(typebox): use canonical imports and harden coercion

Switch first-party code to canonical typebox imports while retaining legacy extension aliases in the loader.

Remove obsolete runtime codegen guards, expand serialized JSON-schema coercion coverage, and update related tests and fixtures.

Fixes #3112.

---------

Co-authored-by: Mario Zechner <badlogicgames@gmail.com>
2026-04-22 19:59:33 +02:00
Mario Zechner a23fab4693 fix(ai): synthesize trailing orphaned tool results closes #3555 2026-04-22 19:41:55 +02:00
Mario Zechner b0217ca6f8 fix(ai): drop deprecated fine-grained-tool-streaming beta header, use eager_input_streaming per-tool
Replace the deprecated global anthropic-beta header with per-tool
eager_input_streaming: true. Fix empty anthropic-beta header causing
400 errors on models with no beta features.

fixes #3175
2026-04-21 23:53:23 +02:00
Mario Zechner e58d631c89 Reapply "fix(ai): own Anthropic SSE parsing to avoid SDK JSON.parse hard-failures"
This reverts commit fc9220d2de.
2026-04-21 23:42:19 +02:00
Mario Zechner fc9220d2de Revert "fix(ai): own Anthropic SSE parsing to avoid SDK JSON.parse hard-failures"
This reverts commit 4b926a30a2.
2026-04-21 23:19:52 +02:00
Mario Zechner 4b926a30a2 fix(ai): own Anthropic SSE parsing to avoid SDK JSON.parse hard-failures
Bypass the Anthropic SDK streaming parser entirely. Use
client.messages.create().asResponse() and decode the SSE stream
ourselves with defensive JSON parsing that repairs invalid escape
sequences and control characters inside string literals.

- Switch from SDK .stream() to .asResponse() + pi-owned SSE decoder
- Add repairJson() / parseJsonWithRepair() to json-parse.ts
- Add anthropic-sse-parsing.test.ts regression for malformed tool deltas
- Update github-copilot-anthropic.test.ts mock to match new call path
- Update deprecated claude-3-5-haiku-20241022 refs to claude-haiku-4-5
- Remove stale non-reasoning model test

fixes #3175
2026-04-21 23:00:56 +02:00
Mario Zechner a0a16c7762 fix(amazon-bedrock): restore regional endpoint resolution
closes #3481
closes #3485
closes #3486
closes #3487
closes #3488
2026-04-21 13:20:10 +02:00
Mario Zechner 1d488626d9 fix(ai): preserve requiresThinkingAsText replay semantics closes #3387 2026-04-20 19:44:38 +02:00
Mario Zechner 3054fd7a3b fix(ai,coding-agent): support anthropic-style cache control for openai compatibles closes #3392 2026-04-20 17:12:05 +02:00
Mario Zechner 2f4f283cc2 fix(ai,coding-agent): preserve non-vision image placeholders closes #3429 2026-04-20 16:52:27 +02:00
Mario Zechner aa1b587b10 fix(ai): add direct OpenAI completions prompt caching closes #3426 2026-04-20 15:37:29 +02:00
Vladyslav Tkachenko f732f5e858 fix(ai): strip JSON Schema meta keys for Cloud Code Assist (#3412) 2026-04-19 16:54:49 +02:00
wirjo a5fac1ef09 feat(amazon-bedrock): conditionally omit maxTokens from inferenceConfig (#3400)
When model.maxTokens is 0 (unset/unknown), omit maxTokens from the
Bedrock ConverseStream inferenceConfig instead of sending 0.

Bedrock's inferenceConfig.maxTokens is optional — when omitted, the
model uses its own internal default. This is optimal for Bedrock's
token quota management:

- At request start, Bedrock reserves input_tokens + max_tokens from
  your TPM quota
- For Claude 3.7+ models, output tokens have a 5x burndown rate
- Sending an unnecessarily high maxTokens wastes TPM capacity during
  the reservation window, reducing concurrent request throughput
- Omitting it lets Bedrock use the model default (~4096 for Claude),
  matching expected output sizes and maximizing quota utilization

Also applies the same conditional pattern to temperature — only
include it in inferenceConfig when explicitly set.

Changes:
- simple-options.ts: Use ?? instead of || so explicit 0 is preserved;
  return undefined when model.maxTokens is 0 (unset)
- amazon-bedrock.ts: Spread maxTokens and temperature into
  inferenceConfig only when defined

Fixes #3399
2026-04-19 08:48:43 +02:00
wirjo 5a889ef58b fix(amazon-bedrock): pass model.baseUrl as endpoint to BedrockRuntimeClient (#3402)
BedrockRuntimeClient was constructed without the endpoint option,
causing model.baseUrl to be silently ignored. This meant custom
Bedrock endpoints (VPC endpoints, proxy setups, custom routing)
were never used — requests always went to the default regional
endpoint.

Pass model.baseUrl as the endpoint config when set. When not set
(the default), the SDK falls back to the standard regional endpoint
constructed from the region config, preserving existing behavior.

Fixes openclaw/openclaw#47899
2026-04-19 08:47:10 +02:00
Mario Zechner 454b9619c7 fix(ai): use SDK token auth and omit Bedrock display in GovCloud closes #3359 2026-04-18 01:24:13 +02:00
Mario Zechner 2dddc5ba25 fix(ai): sanitize Mistral tool schemas closes #3361 2026-04-18 00:54:46 +02:00
Mario Zechner 62778a82d5 fix(ai): use reasoning_effort for Mistral Small 4 closes #3338 2026-04-17 22:44:27 +02:00
Mario Zechner e3f6912d49 fix(ai): preserve qwen chat-template thinking closes #3325 2026-04-17 16:59:00 +02:00
Markus Ylisiurunen 2cdac7382a fix(ai): trust requested Codex service tier (#3307) 2026-04-17 01:50:04 +02:00
Armin Ronacher b789900570 fix(ai): type bedrock bearer auth middleware 2026-04-16 23:50:29 +02:00
wirjo 22085a9a17 feat(bedrock): support Bearer token auth for Converse API (#3125)
Adds bearer token authentication for the Bedrock Converse API, enabling
users to authenticate with an API key instead of SigV4/IAM credentials.

When a bearer token is available (via `options.bearerToken` or the
`AWS_BEARER_TOKEN_BEDROCK` env var), the provider:
1. Sets dummy credentials to prevent SDK credential resolution errors
2. Injects middleware after SigV4 signing that replaces the Authorization
   header with `Bearer <token>` and removes SigV4-specific headers

This uses the official `bedrock:CallWithBearerToken` IAM action, which
is a documented AWS feature for API key auth on Bedrock endpoints.

Use case: users who receive a Bedrock API key (bearer token) from the
AWS console or their admin, without having IAM access keys or instance
roles. Similar to how ANTHROPIC_API_KEY works for direct Anthropic API.

Required IAM permission on the token's identity:
  bedrock:CallWithBearerToken

Tested: Bearer token successfully authenticates against Bedrock Converse
API (returns correct 403 for missing IAM permission, not auth format error).
SigV4 path is unchanged when no bearer token is set.
2026-04-16 23:34:18 +02:00
Vegard Stikbakke 45f1a2cd00 fix(ai): set session id headers for all OpenAI compatible responses (#3264) 2026-04-16 22:38:40 +02:00
Mario Zechner acbf8eca06 feat(ai): add thinkingDisplay option for Anthropic and Bedrock Claude
Exposes the new ThinkingConfig.display field on Anthropic and Bedrock
Claude providers. Defaults to 'summarized' so Claude Opus 4.7 and Mythos
Preview keep returning thinking text despite Anthropic's silent default
change to 'omitted'. Set to 'omitted' explicitly to skip thinking
streaming for faster time-to-first-text-token.
2026-04-16 22:12:06 +02:00
Mario Zechner a5f9f47d13 fix(ai): restore changelog and sdk type compatibility 2026-04-16 20:32:23 +02:00
Mario Zechner d131fcd4ba feat(coding-agent): add after_provider_response hook closes #3128 2026-04-16 20:28:08 +02:00