@oh-my-pi/pi-ai 18.1.4 → 18.1.6
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +52 -9
- package/README.md +8 -33
- package/dist/types/dialect/thinking.d.ts +9 -0
- package/dist/types/dialect/types.d.ts +10 -0
- package/dist/types/error/flags.d.ts +0 -7
- package/dist/types/error/retryable.d.ts +3 -10
- package/dist/types/index.d.ts +0 -1
- package/dist/types/providers/amazon-bedrock.d.ts +7 -0
- package/dist/types/providers/anthropic.d.ts +1 -8
- package/dist/types/providers/cursor.d.ts +3 -1
- package/dist/types/providers/inference-headers.d.ts +24 -0
- package/dist/types/providers/openai-codex/request-transformer.d.ts +7 -10
- package/dist/types/providers/openai-codex-responses.d.ts +3 -7
- package/dist/types/providers/openai-shared.d.ts +1 -1
- package/dist/types/registry/amazon-bedrock.d.ts +3 -10
- package/dist/types/registry/bedrock-mantle.d.ts +3 -22
- package/dist/types/registry/build.d.ts +11 -0
- package/dist/types/registry/cloudflare-ai-gateway.d.ts +3 -13
- package/dist/types/registry/engine/api-key.d.ts +8 -0
- package/dist/types/registry/engine/common.d.ts +55 -0
- package/dist/types/registry/engine/device-code.d.ts +9 -0
- package/dist/types/registry/engine/oauth-code.d.ts +27 -0
- package/dist/types/registry/engine/refresh.d.ts +11 -0
- package/dist/types/registry/hooks/api-key.d.ts +8 -0
- package/dist/types/registry/hooks/custom.d.ts +7 -0
- package/dist/types/registry/hooks/device-code.d.ts +8 -0
- package/dist/types/registry/hooks/env.d.ts +2 -0
- package/dist/types/registry/hooks/index.d.ts +3 -0
- package/dist/types/registry/hooks/oauth-code.d.ts +8 -0
- package/dist/types/registry/hooks/types.d.ts +44 -0
- package/dist/types/registry/oauth/alibaba-coding-plan.d.ts +2 -0
- package/dist/types/registry/{alibaba-token-plan.d.ts → oauth/alibaba-token-plan.d.ts} +1 -6
- package/dist/types/registry/oauth/anthropic.d.ts +24 -16
- package/dist/types/registry/oauth/cloudflare-ai-gateway.d.ts +3 -0
- package/dist/types/registry/oauth/coreweave.d.ts +1 -0
- package/dist/types/registry/oauth/cursor.d.ts +3 -1
- package/dist/types/registry/oauth/github-copilot.d.ts +5 -2
- package/dist/types/registry/oauth/gitlab-duo.d.ts +3 -3
- package/dist/types/registry/oauth/google-antigravity.d.ts +3 -7
- package/dist/types/registry/oauth/google-gemini-cli.d.ts +3 -6
- package/dist/types/registry/oauth/google-oauth-shared.d.ts +0 -24
- package/dist/types/registry/oauth/kilo.d.ts +2 -0
- package/dist/types/registry/oauth/kimi.d.ts +0 -9
- package/dist/types/registry/oauth/openai-codex.d.ts +6 -13
- package/dist/types/registry/oauth/xai-oauth.d.ts +5 -10
- package/dist/types/registry/oauth/xiaomi.d.ts +2 -10
- package/dist/types/registry/oauth/zai.d.ts +3 -15
- package/dist/types/registry/registry.d.ts +9 -386
- package/dist/types/registry/types.d.ts +12 -9
- package/dist/types/types.d.ts +9 -0
- package/dist/types/usage.d.ts +12 -0
- package/dist/types/utils/http-inspector.d.ts +3 -4
- package/dist/types/utils/leaked-thinking-stream.d.ts +6 -0
- package/dist/types/utils/thinking-loop.d.ts +1 -1
- package/dist/types/utils.d.ts +7 -0
- package/package.json +5 -5
- package/src/auth-gateway/server.ts +7 -2
- package/src/auth-storage.ts +315 -78
- package/src/dialect/owned-stream.ts +3 -0
- package/src/dialect/thinking.ts +44 -7
- package/src/dialect/types.ts +8 -0
- package/src/error/flags.ts +0 -45
- package/src/error/rate-limit.ts +9 -1
- package/src/error/retryable.ts +3 -12
- package/src/index.ts +0 -1
- package/src/providers/amazon-bedrock.ts +72 -5
- package/src/providers/anthropic.ts +96 -49
- package/src/providers/cursor-external-tool-handoff.md +1 -0
- package/src/providers/cursor.ts +32 -1
- package/src/providers/github-copilot-headers.ts +7 -2
- package/src/providers/google-shared.ts +11 -9
- package/src/providers/google.ts +6 -0
- package/src/providers/inference-headers.ts +79 -0
- package/src/providers/openai-codex/request-transformer.ts +9 -15
- package/src/providers/openai-codex-responses.ts +6 -12
- package/src/providers/openai-completions.ts +5 -6
- package/src/providers/openai-responses.ts +35 -42
- package/src/providers/openai-shared.ts +8 -13
- package/src/providers/pi-native-server.ts +1 -0
- package/src/registry/amazon-bedrock.ts +5 -8
- package/src/registry/bedrock-mantle.ts +5 -8
- package/src/registry/build.ts +73 -0
- package/src/registry/cloudflare-ai-gateway.ts +4 -44
- package/src/registry/engine/api-key.ts +109 -0
- package/src/registry/engine/common.ts +306 -0
- package/src/registry/engine/device-code.ts +131 -0
- package/src/registry/engine/oauth-code.ts +227 -0
- package/src/registry/engine/refresh.ts +105 -0
- package/src/registry/hooks/api-key.ts +19 -0
- package/src/registry/hooks/custom.ts +15 -0
- package/src/registry/hooks/device-code.ts +13 -0
- package/src/registry/hooks/env.ts +42 -0
- package/src/registry/hooks/index.ts +21 -0
- package/src/registry/hooks/oauth-code.ts +18 -0
- package/src/registry/hooks/types.ts +53 -0
- package/src/registry/{alibaba-coding-plan.ts → oauth/alibaba-coding-plan.ts} +3 -11
- package/src/registry/{alibaba-token-plan.ts → oauth/alibaba-token-plan.ts} +3 -10
- package/src/registry/oauth/anthropic.ts +39 -272
- package/src/registry/oauth/cloudflare-ai-gateway.ts +39 -0
- package/src/registry/oauth/coreweave.ts +16 -0
- package/src/registry/oauth/cursor.ts +12 -1
- package/src/registry/oauth/github-copilot.ts +37 -21
- package/src/registry/oauth/gitlab-duo.ts +6 -219
- package/src/registry/oauth/google-antigravity.ts +32 -66
- package/src/registry/oauth/google-gemini-cli.ts +31 -65
- package/src/registry/oauth/google-oauth-shared.ts +0 -143
- package/src/registry/oauth/index.ts +28 -39
- package/src/registry/{kilo.ts → oauth/kilo.ts} +2 -9
- package/src/registry/oauth/kimi.ts +1 -246
- package/src/registry/oauth/openai-codex.ts +28 -109
- package/src/registry/oauth/xai-oauth.ts +7 -327
- package/src/registry/oauth/xiaomi.ts +9 -60
- package/src/registry/oauth/zai.ts +6 -100
- package/src/registry/registry.ts +32 -173
- package/src/registry/types.ts +12 -9
- package/src/stream.ts +52 -8
- package/src/types.ts +9 -0
- package/src/usage/github-copilot.ts +2 -2
- package/src/usage/google-antigravity.ts +279 -44
- package/src/usage.ts +9 -0
- package/src/utils/empty-completion-retry.ts +0 -1
- package/src/utils/http-inspector.ts +3 -8
- package/src/utils/leaked-thinking-stream.ts +37 -7
- package/src/utils/stream-markup-healing.ts +1 -0
- package/src/utils/thinking-loop.ts +1 -1
- package/src/utils.ts +18 -0
- package/dist/types/registry/aiand.d.ts +0 -7
- package/dist/types/registry/aimlapi.d.ts +0 -4
- package/dist/types/registry/alibaba-coding-plan.d.ts +0 -8
- package/dist/types/registry/anthropic.d.ts +0 -10
- package/dist/types/registry/api-key-login.d.ts +0 -48
- package/dist/types/registry/azure.d.ts +0 -4
- package/dist/types/registry/baseten.d.ts +0 -7
- package/dist/types/registry/cerebras.d.ts +0 -7
- package/dist/types/registry/cline-pass.d.ts +0 -7
- package/dist/types/registry/coreweave.d.ts +0 -7
- package/dist/types/registry/cursor.d.ts +0 -7
- package/dist/types/registry/deepinfra.d.ts +0 -6
- package/dist/types/registry/deepseek.d.ts +0 -8
- package/dist/types/registry/devin.d.ts +0 -8
- package/dist/types/registry/exa.d.ts +0 -8
- package/dist/types/registry/firepass.d.ts +0 -16
- package/dist/types/registry/fireworks.d.ts +0 -7
- package/dist/types/registry/github-copilot.d.ts +0 -7
- package/dist/types/registry/gitlab-duo-workflow.d.ts +0 -10
- package/dist/types/registry/gitlab-duo.d.ts +0 -9
- package/dist/types/registry/gmi-cloud.d.ts +0 -7
- package/dist/types/registry/google-antigravity.d.ts +0 -9
- package/dist/types/registry/google-gemini-cli.d.ts +0 -9
- package/dist/types/registry/google-vertex.d.ts +0 -5
- package/dist/types/registry/google.d.ts +0 -4
- package/dist/types/registry/groq.d.ts +0 -4
- package/dist/types/registry/huggingface.d.ts +0 -7
- package/dist/types/registry/kagi.d.ts +0 -14
- package/dist/types/registry/kilo.d.ts +0 -7
- package/dist/types/registry/kimi-code.d.ts +0 -7
- package/dist/types/registry/litellm.d.ts +0 -13
- package/dist/types/registry/llama-cpp.d.ts +0 -8
- package/dist/types/registry/lm-studio.d.ts +0 -8
- package/dist/types/registry/meta.d.ts +0 -7
- package/dist/types/registry/minimax-code-cn.d.ts +0 -6
- package/dist/types/registry/minimax-code.d.ts +0 -6
- package/dist/types/registry/minimax.d.ts +0 -4
- package/dist/types/registry/mistral.d.ts +0 -4
- package/dist/types/registry/moonshot.d.ts +0 -7
- package/dist/types/registry/nanogpt.d.ts +0 -7
- package/dist/types/registry/novita.d.ts +0 -6
- package/dist/types/registry/nvidia.d.ts +0 -7
- package/dist/types/registry/oauth/devin.d.ts +0 -5
- package/dist/types/registry/oauth/gitlab-duo-workflow.d.ts +0 -6
- package/dist/types/registry/oauth/minimax-code.d.ts +0 -27
- package/dist/types/registry/oauth/opencode.d.ts +0 -25
- package/dist/types/registry/oauth/openrouter.d.ts +0 -36
- package/dist/types/registry/oauth/wafer.d.ts +0 -1
- package/dist/types/registry/ollama-cloud.d.ts +0 -7
- package/dist/types/registry/ollama.d.ts +0 -12
- package/dist/types/registry/openai-codex-device.d.ts +0 -8
- package/dist/types/registry/openai-codex.d.ts +0 -9
- package/dist/types/registry/openai.d.ts +0 -4
- package/dist/types/registry/opencode-go.d.ts +0 -6
- package/dist/types/registry/opencode-zen.d.ts +0 -6
- package/dist/types/registry/openrouter.d.ts +0 -14
- package/dist/types/registry/parallel.d.ts +0 -14
- package/dist/types/registry/perplexity.d.ts +0 -7
- package/dist/types/registry/qianfan.d.ts +0 -7
- package/dist/types/registry/qwen-portal.d.ts +0 -7
- package/dist/types/registry/sakana.d.ts +0 -7
- package/dist/types/registry/siliconflow-cn.d.ts +0 -7
- package/dist/types/registry/siliconflow.d.ts +0 -7
- package/dist/types/registry/synthetic.d.ts +0 -6
- package/dist/types/registry/tavily.d.ts +0 -14
- package/dist/types/registry/together.d.ts +0 -6
- package/dist/types/registry/umans.d.ts +0 -7
- package/dist/types/registry/venice.d.ts +0 -13
- package/dist/types/registry/vercel-ai-gateway.d.ts +0 -7
- package/dist/types/registry/vllm.d.ts +0 -7
- package/dist/types/registry/wafer-serverless.d.ts +0 -6
- package/dist/types/registry/xai-oauth.d.ts +0 -7
- package/dist/types/registry/xai.d.ts +0 -7
- package/dist/types/registry/xiaomi-token-plan-ams.d.ts +0 -6
- package/dist/types/registry/xiaomi-token-plan-cn.d.ts +0 -6
- package/dist/types/registry/xiaomi-token-plan-sgp.d.ts +0 -6
- package/dist/types/registry/xiaomi.d.ts +0 -6
- package/dist/types/registry/yolo-auto.d.ts +0 -15
- package/dist/types/registry/zai.d.ts +0 -15
- package/dist/types/registry/zenmux.d.ts +0 -7
- package/dist/types/registry/zhipu-coding-plan.d.ts +0 -7
- package/dist/types/utils/retry.d.ts +0 -14
- package/src/registry/aiand.ts +0 -22
- package/src/registry/aimlapi.ts +0 -6
- package/src/registry/anthropic.ts +0 -26
- package/src/registry/api-key-login.ts +0 -135
- package/src/registry/azure.ts +0 -6
- package/src/registry/baseten.ts +0 -22
- package/src/registry/cerebras.ts +0 -23
- package/src/registry/cline-pass.ts +0 -27
- package/src/registry/coreweave.ts +0 -40
- package/src/registry/cursor.ts +0 -20
- package/src/registry/deepinfra.ts +0 -24
- package/src/registry/deepseek.ts +0 -46
- package/src/registry/devin.ts +0 -15
- package/src/registry/exa.ts +0 -19
- package/src/registry/firepass.ts +0 -32
- package/src/registry/fireworks.ts +0 -28
- package/src/registry/github-copilot.ts +0 -22
- package/src/registry/gitlab-duo-workflow.ts +0 -20
- package/src/registry/gitlab-duo.ts +0 -19
- package/src/registry/gmi-cloud.ts +0 -22
- package/src/registry/google-antigravity.ts +0 -22
- package/src/registry/google-gemini-cli.ts +0 -22
- package/src/registry/google-vertex.ts +0 -38
- package/src/registry/google.ts +0 -6
- package/src/registry/groq.ts +0 -6
- package/src/registry/huggingface.ts +0 -29
- package/src/registry/kagi.ts +0 -28
- package/src/registry/kimi-code.ts +0 -17
- package/src/registry/litellm.ts +0 -27
- package/src/registry/llama-cpp.ts +0 -25
- package/src/registry/lm-studio.ts +0 -20
- package/src/registry/meta.ts +0 -22
- package/src/registry/minimax-code-cn.ts +0 -12
- package/src/registry/minimax-code.ts +0 -12
- package/src/registry/minimax.ts +0 -6
- package/src/registry/mistral.ts +0 -6
- package/src/registry/moonshot.ts +0 -28
- package/src/registry/nanogpt.ts +0 -22
- package/src/registry/novita.ts +0 -25
- package/src/registry/nvidia.ts +0 -61
- package/src/registry/oauth/devin.ts +0 -124
- package/src/registry/oauth/gitlab-duo-workflow.ts +0 -146
- package/src/registry/oauth/minimax-code.ts +0 -53
- package/src/registry/oauth/opencode.ts +0 -64
- package/src/registry/oauth/openrouter.ts +0 -120
- package/src/registry/oauth/wafer.ts +0 -24
- package/src/registry/ollama-cloud.ts +0 -36
- package/src/registry/ollama.ts +0 -43
- package/src/registry/openai-codex-device.ts +0 -18
- package/src/registry/openai-codex.ts +0 -19
- package/src/registry/openai.ts +0 -6
- package/src/registry/opencode-go.ts +0 -12
- package/src/registry/opencode-zen.ts +0 -12
- package/src/registry/openrouter.ts +0 -24
- package/src/registry/parallel.ts +0 -27
- package/src/registry/perplexity.ts +0 -13
- package/src/registry/qianfan.ts +0 -28
- package/src/registry/qwen-portal.ts +0 -50
- package/src/registry/sakana.ts +0 -22
- package/src/registry/siliconflow-cn.ts +0 -22
- package/src/registry/siliconflow.ts +0 -22
- package/src/registry/synthetic.ts +0 -21
- package/src/registry/tavily.ts +0 -27
- package/src/registry/together.ts +0 -26
- package/src/registry/umans.ts +0 -23
- package/src/registry/venice.ts +0 -33
- package/src/registry/vercel-ai-gateway.ts +0 -20
- package/src/registry/vllm.ts +0 -24
- package/src/registry/wafer-serverless.ts +0 -12
- package/src/registry/xai-oauth.ts +0 -17
- package/src/registry/xai.ts +0 -22
- package/src/registry/xiaomi-token-plan-ams.ts +0 -12
- package/src/registry/xiaomi-token-plan-cn.ts +0 -12
- package/src/registry/xiaomi-token-plan-sgp.ts +0 -12
- package/src/registry/xiaomi.ts +0 -12
- package/src/registry/yolo-auto.ts +0 -30
- package/src/registry/zai.ts +0 -41
- package/src/registry/zenmux.ts +0 -22
- package/src/registry/zhipu-coding-plan.ts +0 -27
- package/src/utils/retry.ts +0 -77
package/CHANGELOG.md
CHANGED
|
@@ -2,6 +2,49 @@
|
|
|
2
2
|
|
|
3
3
|
## [Unreleased]
|
|
4
4
|
|
|
5
|
+
## [18.1.6] - 2026-09-03
|
|
6
|
+
|
|
7
|
+
### Breaking Changes
|
|
8
|
+
|
|
9
|
+
- Renamed `claudeCodeSessionId` to `sessionId` in `AnthropicClientOptionsArgs`.
|
|
10
|
+
- Renamed `openAISessionId` to `sessionId` in `OpenAIRequestSetupOptions`.
|
|
11
|
+
|
|
12
|
+
### Added
|
|
13
|
+
|
|
14
|
+
- Added Amazon Bedrock `requestMetadata` support for cost and usage attribution in AWS invocation logs.
|
|
15
|
+
|
|
16
|
+
### Changed
|
|
17
|
+
|
|
18
|
+
- Codex GPT-5.6 requests now use full Responses by default, enabling independent tool calls to run in parallel; provider-native compaction continues to use catalog-selected Responses Lite.
|
|
19
|
+
- Inference requests now identify as omp by default while preserving explicit provider and OAuth User-Agent fingerprints. Amazon Bedrock requests use an `omp/<version>` User-Agent by default and honor configured `User-Agent` overrides.
|
|
20
|
+
|
|
21
|
+
### Fixed
|
|
22
|
+
|
|
23
|
+
- Fixed Antigravity usage reporting to match the official client's five-hour and weekly quota buckets.
|
|
24
|
+
- Anthropic and OpenRouter credit-exhaustion errors now automatically switch to a sibling account instead of stopping the turn with a retry hint.
|
|
25
|
+
- Fixed OpenCode Go and Zen requests by including the required stable per-conversation session identification.
|
|
26
|
+
- Improved Anthropic prompt caching so explicit cache breakpoints preserve reusable tools and system prompts when the message tail changes.
|
|
27
|
+
|
|
28
|
+
## [18.1.5] - 2026-09-03
|
|
29
|
+
|
|
30
|
+
### Added
|
|
31
|
+
|
|
32
|
+
- Added `/login abliteration` with API key validation against `/v1/models`, supporting the `ABLITERATION_API_KEY` and `ABLIT_KEY` environment variables.
|
|
33
|
+
|
|
34
|
+
### Changed
|
|
35
|
+
|
|
36
|
+
- Modernized provider authentication and token refresh across the catalog, with shared support for API-key, authorization-code, and device-code sign-in flows and clearer sign-in progress messages for OpenRouter, Kimi, and xAI.
|
|
37
|
+
|
|
38
|
+
### Fixed
|
|
39
|
+
|
|
40
|
+
- GitHub Copilot now uses the official Copilot CLI identity and OAuth application for requests and new sign-ins, restoring access to client-gated models while preserving existing credentials.
|
|
41
|
+
- GitHub Copilot now reports `model_not_supported` responses immediately instead of repeatedly retrying unsupported models.
|
|
42
|
+
- Improved account recovery after Google rate limits are lifted earlier than the reported reset time.
|
|
43
|
+
- Fixed unmetered autocomplete models being reported as exhausted when quota is limited.
|
|
44
|
+
- Fixed Gemini 3 cross-model sessions in Cloud Code Assist when replaying tool calls without a thought signature.
|
|
45
|
+
- Fixed Cursor models behind an authentication gateway incorrectly retrying valid client-declared tool calls.
|
|
46
|
+
- Fixed reasoning from models that prefill `<think>` (including DeepSeek-R1 and hosted Qwen3-Thinking) being shown in the response instead of as a separate thinking block.
|
|
47
|
+
|
|
5
48
|
## [18.1.3] - 2026-09-02
|
|
6
49
|
|
|
7
50
|
### Fixed
|
|
@@ -163,7 +206,7 @@
|
|
|
163
206
|
- Fixed Codex continuations, retries, and compaction replacing or dropping the turn-scoped sticky-routing token ([#9277](https://github.com/can1357/oh-my-pi/issues/9277)).
|
|
164
207
|
- Fixed Codex Responses append chains falling back to full-context replay when replay-sanitized assistant items differ only by output-only IDs or lifecycle status.
|
|
165
208
|
- Fixed Cursor usage reporting “no usage data” for plans without a numeric legacy request cap.
|
|
166
|
-
- Fixed DeepSeek models rejecting requests with HTTP 400 `unknown variant \`image_url\`, expected \`text\``
|
|
209
|
+
- Fixed DeepSeek models rejecting requests with HTTP 400 `unknown variant \`image_url\`, expected \`text\``when screenshots or image-producing tool results are present in conversation history or when`model.input`claims vision capability;`convertMessages`in`openai-completions`now strips`image_url` content parts and injects non-vision image placeholders for all DeepSeek endpoints.
|
|
167
210
|
- Fixed `PI_PROXY` covering only provider streams: OAuth token refresh and login, usage probes, and model discovery went out through the bare global `fetch` and ignored it, so a region-blocked token endpoint answered `403 Request not allowed` (Anthropic `/v1/oauth/token`) and disabled the credential while the proxied stream itself worked. `installGlobalProxyFetch()` now routes the process-wide `fetch` through `PI_PROXY`; a per-request proxy such as `PI_PROXY_<PROVIDER>` still wins, and loopback / private-range / `NO_PROXY` targets stay direct.
|
|
168
211
|
- Fixed Anthropic inference ignoring every proxy setting. `coworkFetch` runs on `node:https`, whose Bun shim discards both `agent.createConnection` and `options.createConnection`: the CONNECT tunnel to `PI_PROXY` was built, TLS-negotiated, then abandoned, and the request dialed `api.anthropic.com` on the default route (measured at the proxy: 581 bytes of handshake, zero request bytes). On a region-blocked egress that returned `403 {"type":"forbidden","message":"Request not allowed"}` with the proxy apparently configured. Proxied requests now go through Bun's own `fetch`, which honors `init.proxy`, trading the Cowork TLS/header profile for a proxy that actually carries the traffic; the dead tunnel plumbing is gone from the transport. `node:http2` (Cursor) does honor `createConnection` and is unaffected.
|
|
169
212
|
- Fixed `cowork-fetch` capturing `globalThis.fetch` at module load, so a proxy wrapper installed later in startup was ignored on its fallback path.
|
|
@@ -233,7 +276,7 @@
|
|
|
233
276
|
|
|
234
277
|
### Changed
|
|
235
278
|
|
|
236
|
-
- Fixed Gemini thought summaries occasionally leaking a raw
|
|
279
|
+
- Fixed Gemini thought summaries occasionally leaking a raw ` ```thinking ` / ` ``````thinking ` fence delimiter into the reasoning block, so it no longer shows up as fence spam in the thinking display or persisted transcripts ([#8719](https://github.com/can1357/oh-my-pi/issues/8719)).
|
|
237
280
|
- Fixed the OpenCode Go login prompting for an "OpenCode Zen API key": the shared login flow now names the provider you selected, so connecting OpenCode Go asks for an OpenCode Go key (the `opencode.ai/auth` console is still shared, as documented upstream) ([#8738](https://github.com/can1357/oh-my-pi/issues/8738)).
|
|
238
281
|
- Fixed Anthropic-compatible endpoints with strict prompt validation (e.g. Z.AI GLM `api.z.ai/api/anthropic`, which rejects the whole request with `400 code 1213 "The prompt parameter was not received normally"`) failing sessions once a tool returned empty output on a vision-capable model: empty successful `tool_result` blocks now encode as `content: ""` instead of `content: []`, which both the official API and strict compatible endpoints accept.
|
|
239
282
|
- Fixed `retry.usageReservePct` (Reserve Margin) ignoring Claude Fable/Mythos weekly tier usage until it hit 100%, so a Fable model kept serving turns past the configured reserve; reserve health now honors the mapped tier row while credential-wide hard blocks still require confirmed exhaustion ([#8773](https://github.com/can1357/oh-my-pi/issues/8773)).
|
|
@@ -1285,7 +1328,7 @@
|
|
|
1285
1328
|
|
|
1286
1329
|
- Added a third streaming thinking-loop detection heuristic to catch "progress-lexicon stalls" where models endlessly reshuffle motivational filler without introducing new vocabulary or concrete technical references
|
|
1287
1330
|
- Added branded wordmark and logo animation to authentication flow
|
|
1288
|
-
- Added a third streaming thinking-loop detection shape — a
|
|
1331
|
+
- Added a third streaming thinking-loop detection shape — a _progress-lexicon stall_ — alongside verbatim tail repetition and near-duplicate (trigram) segments. It catches reasoning-summarizer loops that reshuffle the same motivational filler ("just doing it, pushing ahead, maintaining momentum") into fresh word order every paragraph: word-trigrams never cluster, but a run of substantial segments that recycle the recent vocabulary and introduce no _new_ concrete reference (path / identifier / code-span) trips the guard. Summarizer title/heading lines (`**Bold Title**`, `## Heading`) are stripped before analysis so their ever-changing wording cannot mask the stall by inflating novelty. Calibrated against 537k real non-Gemini reasoning blocks (zero false positives at novelty floor 0.2 / run length 8; the real loop sustains runs of 10+).
|
|
1289
1332
|
- Added CoreWeave Serverless Inference provider login support via `COREWEAVE_API_KEY` and `WANDB_API_KEY` fallback.
|
|
1290
1333
|
|
|
1291
1334
|
### Changed
|
|
@@ -1429,7 +1472,7 @@
|
|
|
1429
1472
|
- Fixed tool call ID normalization for Anthropic-compatible models
|
|
1430
1473
|
- Fixed Anthropic Messages replay sanitizing malformed tool-call IDs, including aborted native tool calls with empty IDs, so retries no longer send invalid `tool_use.id` / `tool_result.tool_use_id` pairs.
|
|
1431
1474
|
- Fixed the Codex Responses WebSocket transport attributing a prior turn's output to the current one on a reused connection: a trailing/duplicate frame from a cleanly-completed previous response that slipped past the queue drain could be consumed as this request's terminal (ending the turn with empty output) or as a stale tool call. Frames are now keyed by `response.id` — a frame carrying the previous response's id is dropped, and one carrying a third id (or a regressed `sequence_number`) fails closed so the turn retries instead of mixing two responses' streams. Idless frames (deltas, the rate-limit/metadata preamble, `response.created`-less streams) still pass through, matching upstream codex-rs.
|
|
1432
|
-
- Fixed `transformMessages` pulling an earlier, orphaned tool result onto a later tool call that reused the same id (left behind when compaction folded the originating `tool_use` into a summary). The pending-call flush now pairs each call with a result positioned
|
|
1475
|
+
- Fixed `transformMessages` pulling an earlier, orphaned tool result onto a later tool call that reused the same id (left behind when compaction folded the originating `tool_use` into a summary). The pending-call flush now pairs each call with a result positioned _after_ its assistant turn, so a reused id surfaces its own output rather than a prior turn's.
|
|
1433
1476
|
- Fixed DashScope 429 rate-limit messages that mention authorization being classified as credential failures, preventing valid API keys from being invalidated after throttling. ([#3172](https://github.com/can1357/oh-my-pi/issues/3172))
|
|
1434
1477
|
- Fixed OpenCode Go `401 Insufficient balance` quota errors being treated as unknown failures instead of usage-limit errors, restoring credential rotation and fallback chains. ([#3169](https://github.com/can1357/oh-my-pi/issues/3169))
|
|
1435
1478
|
|
|
@@ -1705,7 +1748,7 @@
|
|
|
1705
1748
|
- Added `wrapInbandToolStream` function to process streaming responses with in-band tool call parsing
|
|
1706
1749
|
- Added `ThinkingInbandScanner` for parsing thinking/reasoning blocks across dialects
|
|
1707
1750
|
- Added `OwnedStream` class for managing dialect-aware streaming with tool call events
|
|
1708
|
-
- Added in-band thinking channels to every dialect that was missing one: `gemini` (a
|
|
1751
|
+
- Added in-band thinking channels to every dialect that was missing one: `gemini` (a ` ```thinking ` fence mirroring ` ```tool_code `), `gemma` (its native `<|channel>thought…<channel|>` reasoning channel), `kimi` (`<think>…</think>`), and `pi` (`<thinking>…</thinking>`). Each scanner now parses reasoning into thinking events instead of leaking chain-of-thought into the visible reply, and every dialect's `renderThinking` is a real channel that round-trips back through its scanner (no passthrough renderers).
|
|
1709
1752
|
|
|
1710
1753
|
### Changed
|
|
1711
1754
|
|
|
@@ -1729,7 +1772,7 @@
|
|
|
1729
1772
|
|
|
1730
1773
|
### Added
|
|
1731
1774
|
|
|
1732
|
-
- Added the `gemini` in-band tool-call syntax with Python-style
|
|
1775
|
+
- Added the `gemini` in-band tool-call syntax with Python-style `tool_code` blocks and `default_api` invocations
|
|
1733
1776
|
- Added the `gemma` token-delimited in-band tool-call syntax using `<|tool_call>` and `<|tool_response>` blocks
|
|
1734
1777
|
- Added `gemini` and `gemma` to owned stream tool-result token detection so their tool responses are recognized
|
|
1735
1778
|
- Fixed truncated Gemini and Gemma tool blocks from being emitted as plain text during streaming
|
|
@@ -1774,7 +1817,7 @@
|
|
|
1774
1817
|
- Fixed Harmony leak handling support by adding `recoverHarmonyToolCall` plus leak-detection workflows for contaminated assistant messages so recoverable tool-call arguments can be safely truncated and retried
|
|
1775
1818
|
- Fixed false-positive gating in Harmony leak heuristics using signal-based checks so unrelated text containing `to=functions...` is not treated as leaked tool-call markup
|
|
1776
1819
|
- Routed Kimi, DeepSeek DSML, and plain thinking markup healing through the shared in-band scanners so provider leak repair and owned tool calling parse the same wire formats.
|
|
1777
|
-
- Fixed Cursor provider (`cursor-agent` API) streaming dropping large MCP tool-call arguments — most visibly the built-in `task` tool's `tasks` array on multi-subagent dispatches, which failed downstream schema validation with `tasks: Invalid input: expected array, received undefined`. Two upstream behaviors were fighting the stream handler in `packages/ai/src/providers/cursor.ts`: (1) `args_text_delta` carries the
|
|
1820
|
+
- Fixed Cursor provider (`cursor-agent` API) streaming dropping large MCP tool-call arguments — most visibly the built-in `task` tool's `tasks` array on multi-subagent dispatches, which failed downstream schema validation with `tasks: Invalid input: expected array, received undefined`. Two upstream behaviors were fighting the stream handler in `packages/ai/src/providers/cursor.ts`: (1) `args_text_delta` carries the _cumulative_ args text so far per `agent.proto`, but the handler concatenated each snapshot onto the buffer, garbling the JSON; (2) `tool_call_completed` carries an `McpArgs` map that omits oversized parameters entirely and downgrades unparsable values to their raw string fallback, but the handler unconditionally overwrote the streamed args with that map. The handler now strips the already-buffered prefix from each `args_text_delta` snapshot (falling back to append when the snapshot doesn't extend the buffer) and merges the decoded `McpArgs` map into the streamed args — preserving streamed keys the completion frame omits and the structured value when the completion frame downgrades to a string. ([#2615](https://github.com/can1357/oh-my-pi/issues/2615))
|
|
1778
1821
|
- Fixed Codex Responses stream mis-routing interleaved `function_call_arguments.delta` events when more than one tool call was open concurrently. The runtime tracked a singleton `currentItem`/`currentBlock`, so every delta — regardless of `item_id` — was appended to whichever item was most recently added, and `output_item.done` for the earlier call then overwrote a sibling's stored arguments (visible as `tasks: Invalid input: expected array, received undefined` on the `task` tool). Open items are now keyed by `item_id` with `output_index` fallback; deltas/done events route to the matching block, late deltas whose item already closed are dropped instead of corrupting a sibling, and `toolcall_*` stream events emit the right `contentIndex` per call ([#2619](https://github.com/can1357/oh-my-pi/issues/2619)).
|
|
1779
1822
|
|
|
1780
1823
|
## [15.13.1] - 2026-06-15
|
|
@@ -1983,7 +2026,7 @@
|
|
|
1983
2026
|
|
|
1984
2027
|
### Breaking Changes
|
|
1985
2028
|
|
|
1986
|
-
- The model catalog moved to the new `@oh-my-pi/pi-catalog` package. Deep subpath exports `@oh-my-pi/pi-ai/models.json`, `/models`, `/model-cache`, `/model-manager`, `/model-thinking`, `/effort`, `/provider-models*`, `/utils/discovery*`, `/providers/openai-codex/constants`, `/providers/google-gemini-headers`, and `/providers/openai-completions-compat` are gone — import the `@oh-my-pi/pi-catalog` equivalents (`/models.json`, `/models`, `/model-cache`, `/model-manager`, `/model-thinking`, `/effort`, `/provider-models*`, `/discovery*`, `/wire/codex`, `/wire/gemini-headers`, `/compat/openai`). The pi-ai root barrel re-exports only the model/effort
|
|
2029
|
+
- The model catalog moved to the new `@oh-my-pi/pi-catalog` package. Deep subpath exports `@oh-my-pi/pi-ai/models.json`, `/models`, `/model-cache`, `/model-manager`, `/model-thinking`, `/effort`, `/provider-models*`, `/utils/discovery*`, `/providers/openai-codex/constants`, `/providers/google-gemini-headers`, and `/providers/openai-completions-compat` are gone — import the `@oh-my-pi/pi-catalog` equivalents (`/models.json`, `/models`, `/model-cache`, `/model-manager`, `/model-thinking`, `/effort`, `/provider-models*`, `/discovery*`, `/wire/codex`, `/wire/gemini-headers`, `/compat/openai`). The pi-ai root barrel re-exports only the model/effort _types_ its own signatures use (`Model`, `Api`, `ThinkingConfig`, `Effort`, `Usage`, compat interfaces) — catalog _values_ (`getBundledModel(s)`, `calculateCost`, `modelsAreEqual`, `clampThinkingLevelForModel`, `DEFAULT_MODEL_PER_PROVIDER`, …) must be imported from `@oh-my-pi/pi-catalog`.
|
|
1987
2030
|
- `ProviderDefinition` is now auth-only: `defaultModel`, `createModelManagerOptions`, `catalogDiscovery`, `dynamicModelsAuthoritative`, `allowUnauthenticated`, and `specialModelManager` moved to pi-catalog's `CATALOG_PROVIDERS` table, and `KnownProviderId` was replaced by pi-catalog's `KnownProvider` (registry completeness is enforced by a compile-time check against that union). The pure GitHub Copilot key/endpoint helpers moved from `registry/oauth/github-copilot` to `@oh-my-pi/pi-catalog/wire/github-copilot`.
|
|
1988
2031
|
|
|
1989
2032
|
### Added
|
|
@@ -2072,7 +2115,7 @@
|
|
|
2072
2115
|
- Fixed `AnthropicMessagesClient` spreading `fetchOptions` after the core request fields, letting a caller-supplied `signal`/`method`/`body` silently disconnect the timeout controller or corrupt the request. Transport extras (TLS) still pass through; core fields now always win.
|
|
2073
2116
|
- Fixed Foundry mTLS/CA material being cached for the process lifetime when the env vars point at files: the cache key now folds in the file mtime so on-disk certificate rotation takes effect.
|
|
2074
2117
|
- Fixed the Claude Code fingerprint version drifting across surfaces: the usage endpoint (`claude-cli/2.1.160`) and OAuth bootstrap (`claude-code/2.1.160`) pinned a stale version while `/v1/messages` reported 2.1.165; both now derive from `claudeCodeVersion`.
|
|
2075
|
-
- Fixed a system prompt that merely
|
|
2118
|
+
- Fixed a system prompt that merely _mentions_ `x-anthropic-billing-header:` mid-text suppressing the entire Claude Code system-block injection (billing header, instruction, and cch attestation); the resumed-session guard now anchors with `startsWith`.
|
|
2076
2119
|
- Fixed lone surrogates in cross-API tool-call arguments reaching Anthropic's strict UTF-8 validation: replayed OpenAI/Google-origin `tool_use.input` string leaves are now deep-sanitized with `toWellFormed()`, while same-API Anthropic arguments stay byte-identical to keep prompt-cache prefixes stable.
|
|
2077
2120
|
- Bounded the many-image resize fan-out to 4 concurrent decodes (it previously decoded every oversized image at once, two encode pipelines each — multi-GB transient memory at the 20+-image threshold that activates the feature).
|
|
2078
2121
|
- Fixed `mergeHeaders` merging case-sensitively on the Copilot/client-options path, where a miscased user-configured header (e.g. `authorization` next to the synthesized `Authorization`) survived as two keys that the `Headers` constructor joins comma-separated on the wire.
|
package/README.md
CHANGED
|
@@ -1090,56 +1090,31 @@ For the current API-key onboarding flows, the library covers Together, Moonshot,
|
|
|
1090
1090
|
|
|
1091
1091
|
### Programmatic OAuth
|
|
1092
1092
|
|
|
1093
|
-
|
|
1093
|
+
Provider login and refresh behavior is exposed through the registry. Credential storage is the caller's responsibility.
|
|
1094
1094
|
|
|
1095
1095
|
```typescript
|
|
1096
1096
|
import {
|
|
1097
|
-
|
|
1098
|
-
loginAnthropic,
|
|
1099
|
-
loginOpenAICodex,
|
|
1100
|
-
loginGitHubCopilot,
|
|
1101
|
-
loginGeminiCli,
|
|
1102
|
-
loginAntigravity,
|
|
1103
|
-
loginCloudflareAiGateway,
|
|
1104
|
-
loginHuggingface,
|
|
1105
|
-
loginLiteLLM,
|
|
1106
|
-
loginMoonshot,
|
|
1107
|
-
loginNvidia,
|
|
1108
|
-
loginNanoGPT,
|
|
1109
|
-
loginQianfan,
|
|
1110
|
-
loginQwenPortal,
|
|
1111
|
-
loginTogether,
|
|
1112
|
-
loginVenice,
|
|
1113
|
-
loginVllm,
|
|
1114
|
-
loginXiaomi,
|
|
1115
|
-
|
|
1116
|
-
// Token management
|
|
1097
|
+
getProviderDefinition,
|
|
1117
1098
|
refreshOAuthToken, // (provider, credentials) => new credentials
|
|
1118
1099
|
getOAuthApiKey, // (provider, credentialsMap) => { newCredentials, apiKey } | null
|
|
1119
|
-
|
|
1120
|
-
// Types
|
|
1121
|
-
type OAuthProvider, // includes 'anthropic', 'openai-codex', 'github-copilot', 'google-gemini-cli', 'google-antigravity', 'together', 'moonshot', 'qianfan', 'nvidia', 'nanogpt', 'novita', 'huggingface', 'venice', 'xiaomi', 'vllm', 'litellm', 'cloudflare-ai-gateway', 'qwen-portal', ...
|
|
1100
|
+
type OAuthProvider,
|
|
1122
1101
|
type OAuthCredentials,
|
|
1123
1102
|
} from "@oh-my-pi/pi-ai";
|
|
1124
|
-
```
|
|
1125
1103
|
|
|
1126
|
-
|
|
1127
|
-
|
|
1128
|
-
```typescript
|
|
1129
|
-
await loginOpenAICodex({
|
|
1104
|
+
const provider = getProviderDefinition("openai-codex");
|
|
1105
|
+
const credentials = await provider?.login?.({
|
|
1130
1106
|
onAuth: ({ url }) => console.log(url),
|
|
1131
|
-
originator: "my-cli",
|
|
1132
1107
|
});
|
|
1133
1108
|
```
|
|
1134
1109
|
|
|
1135
1110
|
### Login Flow Example
|
|
1136
1111
|
|
|
1137
1112
|
```typescript
|
|
1138
|
-
import {
|
|
1113
|
+
import { getProviderDefinition } from "@oh-my-pi/pi-ai";
|
|
1139
1114
|
import * as fs from "node:fs";
|
|
1140
1115
|
|
|
1141
|
-
const credentials = await
|
|
1142
|
-
onAuth: (url, instructions) => {
|
|
1116
|
+
const credentials = await getProviderDefinition("github-copilot")?.login?.({
|
|
1117
|
+
onAuth: ({ url, instructions }) => {
|
|
1143
1118
|
console.log(`Open: ${url}`);
|
|
1144
1119
|
if (instructions) console.log(instructions);
|
|
1145
1120
|
},
|
|
@@ -1,6 +1,15 @@
|
|
|
1
1
|
import type { InbandScanEvent, InbandScanner } from "./types.js";
|
|
2
|
+
export interface ThinkingInbandScannerOptions {
|
|
3
|
+
/**
|
|
4
|
+
* Report a bare reasoning close tag (no open seen) as an `impliedThinkingEnd`
|
|
5
|
+
* event instead of passing it through as text. Off by default: only a
|
|
6
|
+
* consumer that owns the whole message can reclassify the text before it.
|
|
7
|
+
*/
|
|
8
|
+
readonly impliedOpen?: boolean;
|
|
9
|
+
}
|
|
2
10
|
export declare class ThinkingInbandScanner implements InbandScanner {
|
|
3
11
|
#private;
|
|
12
|
+
constructor(options?: ThinkingInbandScannerOptions);
|
|
4
13
|
feed(text: string): InbandScanEvent[];
|
|
5
14
|
flush(): InbandScanEvent[];
|
|
6
15
|
}
|
|
@@ -12,6 +12,16 @@ export type InbandScanEvent = {
|
|
|
12
12
|
} | {
|
|
13
13
|
type: "thinkingEnd";
|
|
14
14
|
thinking: string;
|
|
15
|
+
}
|
|
16
|
+
/**
|
|
17
|
+
* A reasoning close tag with no open in this stream. Chat templates that
|
|
18
|
+
* prefill the opener into the prompt (DeepSeek-R1, Qwen3-Thinking) make the
|
|
19
|
+
* model stream only the close, so everything emitted as `text` before this
|
|
20
|
+
* event was reasoning. Only {@link ThinkingInbandScanner} with `impliedOpen`
|
|
21
|
+
* emits it.
|
|
22
|
+
*/
|
|
23
|
+
| {
|
|
24
|
+
type: "impliedThinkingEnd";
|
|
15
25
|
} | {
|
|
16
26
|
type: "toolStart";
|
|
17
27
|
id: string;
|
|
@@ -87,13 +87,6 @@ export declare function isFastModeUnsupported(error: unknown): boolean;
|
|
|
87
87
|
* fail identically) nor surface as an auth failure.
|
|
88
88
|
*/
|
|
89
89
|
export declare function isClinePassSurfaceGateMessage(errorMessage: string | undefined): boolean;
|
|
90
|
-
/**
|
|
91
|
-
* GitHub Copilot 400 `model_not_supported` response for a model advertised by
|
|
92
|
-
* `/models` — transient fleet skew, not a malformed request. Reads the
|
|
93
|
-
* structural `code` through the SDK/body envelopes, then falls back to the
|
|
94
|
-
* stringified body both SDK families put in `message`.
|
|
95
|
-
*/
|
|
96
|
-
export declare function isCopilotTransientModelError(error: unknown): boolean;
|
|
97
90
|
export declare function classifyMessage(message: {
|
|
98
91
|
api?: Api;
|
|
99
92
|
provider?: string;
|
|
@@ -7,13 +7,6 @@
|
|
|
7
7
|
* may match more. Use this when you only have a `status: number`.
|
|
8
8
|
*/
|
|
9
9
|
export declare function isTransientStatus(status: number | undefined): boolean;
|
|
10
|
-
/** Hook for provider-specific transient detection that the error module must not import directly. */
|
|
11
|
-
export interface ProviderRetryableHooks {
|
|
12
|
-
/** Provider id of the failing request, used to gate provider-specific checks. */
|
|
13
|
-
provider?: string;
|
|
14
|
-
/** Provider-specific transient predicate (e.g. Copilot model-availability 400s). */
|
|
15
|
-
isProviderTransient?: (error: Error) => boolean;
|
|
16
|
-
}
|
|
17
10
|
/**
|
|
18
11
|
* Whether a provider stream error should be retried against the same credential.
|
|
19
12
|
*
|
|
@@ -21,7 +14,7 @@ export interface ProviderRetryableHooks {
|
|
|
21
14
|
* here — they are owned by the credential-rotation layer (auth-gateway /
|
|
22
15
|
* `streamSimple` a/b/c policy), not this seconds-scale provider backoff.
|
|
23
16
|
*
|
|
24
|
-
*
|
|
25
|
-
*
|
|
17
|
+
* Every 4xx other than 408/429 is terminal: a request the provider rejected
|
|
18
|
+
* as malformed, unauthorized, or unentitled fails identically on replay.
|
|
26
19
|
*/
|
|
27
|
-
export declare function isProviderRetryableError(error: unknown
|
|
20
|
+
export declare function isProviderRetryableError(error: unknown): boolean;
|
package/dist/types/index.d.ts
CHANGED
|
@@ -46,7 +46,6 @@ export * from "./utils/anthropic-auth.js";
|
|
|
46
46
|
export * from "./utils/event-stream.js";
|
|
47
47
|
export * from "./utils/glyph-codec.js";
|
|
48
48
|
export * from "./utils/openrouter-headers.js";
|
|
49
|
-
export * from "./utils/retry.js";
|
|
50
49
|
export * from "./utils/schema/index.js";
|
|
51
50
|
export * from "./utils/thinking-loop.js";
|
|
52
51
|
export * from "./utils/tool-call-loop-guard.js";
|
|
@@ -47,5 +47,12 @@ export interface BedrockOptions extends StreamOptions {
|
|
|
47
47
|
* we omit it for them.
|
|
48
48
|
*/
|
|
49
49
|
thinkingDisplay?: BedrockThinkingDisplay;
|
|
50
|
+
/**
|
|
51
|
+
* Per-request Bedrock invocation-log tags. Merged over `model.requestMetadata`
|
|
52
|
+
* (per-call entries win on key collision). AWS caps the result at 16 entries;
|
|
53
|
+
* keys 1-256 chars, values 0-256 chars, both limited to
|
|
54
|
+
* `[a-zA-Z0-9\s:_@$#=/+,-.]`. Entries outside those limits are dropped.
|
|
55
|
+
*/
|
|
56
|
+
requestMetadata?: Record<string, string>;
|
|
50
57
|
}
|
|
51
58
|
export declare const streamBedrock: StreamFunction<"bedrock-converse-stream">;
|
|
@@ -164,7 +164,7 @@ export type AnthropicClientOptionsArgs = {
|
|
|
164
164
|
disableStrictTools?: boolean;
|
|
165
165
|
fetch?: FetchImpl;
|
|
166
166
|
maxRetryDelayMs?: number;
|
|
167
|
-
|
|
167
|
+
sessionId?: string;
|
|
168
168
|
};
|
|
169
169
|
export type AnthropicClientOptionsResult = {
|
|
170
170
|
isOAuthToken: boolean;
|
|
@@ -188,13 +188,6 @@ export type AnthropicClientOptionsResult = {
|
|
|
188
188
|
* omitted there.
|
|
189
189
|
*/
|
|
190
190
|
export declare function resolveAnthropicCustomHeadersForBaseUrl(baseUrl: string | undefined): Record<string, string> | undefined;
|
|
191
|
-
/**
|
|
192
|
-
* Whether an Anthropic (or Copilot-over-Anthropic) stream error should be
|
|
193
|
-
* retried. The classification lives in {@link AIError.isProviderRetryableError};
|
|
194
|
-
* this wrapper injects the Copilot-specific model-availability transient check,
|
|
195
|
-
* which the error module must not import directly.
|
|
196
|
-
*/
|
|
197
|
-
export declare function isProviderRetryableError(error: unknown, provider?: string): boolean;
|
|
198
191
|
export type AnthropicUsageLike = {
|
|
199
192
|
cache_creation?: {
|
|
200
193
|
ephemeral_5m_input_tokens?: number | null;
|
|
@@ -12,6 +12,8 @@ export interface CursorOptions extends StreamOptions {
|
|
|
12
12
|
conversationId?: string;
|
|
13
13
|
execHandlers?: CursorExecHandlers;
|
|
14
14
|
onToolResult?: CursorToolResultHandler;
|
|
15
|
+
/** Treat unhandled MCP calls as accepted handoffs to an external executor. */
|
|
16
|
+
externalToolExecutor?: boolean;
|
|
15
17
|
/** Wire model id selected after thinking-effort routing (`resolveWireModelId`). */
|
|
16
18
|
wireModelId?: string;
|
|
17
19
|
}
|
|
@@ -104,7 +106,7 @@ export interface UsageState {
|
|
|
104
106
|
sawTokenDelta: boolean;
|
|
105
107
|
}
|
|
106
108
|
/** Exported for tests: drives one Cursor server message through the stream (exec waits mark the stream busy). */
|
|
107
|
-
export declare function handleServerMessage(msg: AgentServerMessage, output: AssistantMessage, stream: AssistantMessageEventStream, state: BlockState, blobStore: Map<string, Uint8Array>, h2Request: http2.ClientHttp2Stream, execHandlers: CursorExecHandlers | undefined, onToolResult: CursorToolResultHandler | undefined, usageState: UsageState, requestContextTools: McpToolDefinition[], requestContextRules?: CursorRule[], onConversationCheckpoint?: (checkpoint: ConversationStateStructure) => void): Promise<void>;
|
|
109
|
+
export declare function handleServerMessage(msg: AgentServerMessage, output: AssistantMessage, stream: AssistantMessageEventStream, state: BlockState, blobStore: Map<string, Uint8Array>, h2Request: http2.ClientHttp2Stream, execHandlers: CursorExecHandlers | undefined, onToolResult: CursorToolResultHandler | undefined, usageState: UsageState, requestContextTools: McpToolDefinition[], requestContextRules?: CursorRule[], onConversationCheckpoint?: (checkpoint: ConversationStateStructure) => void, externalToolExecutor?: boolean): Promise<void>;
|
|
108
110
|
/**
|
|
109
111
|
* Exported for tests: verifies handler is invoked with correct `this` when passed as bound.
|
|
110
112
|
*
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
/** Shared inference request identity headers. */
|
|
2
|
+
import type { FetchImpl } from "../types.js";
|
|
3
|
+
/** Options controlling provider and protocol inference headers. */
|
|
4
|
+
export interface InferenceHeaderOptions {
|
|
5
|
+
provider: string;
|
|
6
|
+
protocol: "anthropic" | "google" | "openai";
|
|
7
|
+
sessionId?: string;
|
|
8
|
+
}
|
|
9
|
+
/** Set a header unless the map already contains that field under any casing. */
|
|
10
|
+
export declare function setHeaderIfAbsent(headers: Record<string, string>, name: string, value: string): void;
|
|
11
|
+
/**
|
|
12
|
+
* Project omp's identity and authoritative conversation id onto the headers
|
|
13
|
+
* understood by the active inference protocol and host.
|
|
14
|
+
*/
|
|
15
|
+
export declare function applyInferenceHeaders(headers: Record<string, string>, options: InferenceHeaderOptions): void;
|
|
16
|
+
/**
|
|
17
|
+
* Apply omp's process-wide inference User-Agent default. Any explicit header,
|
|
18
|
+
* including Anthropic and Codex OAuth fingerprints, remains authoritative.
|
|
19
|
+
*
|
|
20
|
+
* Plain-object headers stay plain objects: custom `fetch` implementations
|
|
21
|
+
* (proxies, tests) index `init.headers` by name and must not be handed a
|
|
22
|
+
* `Headers` instance instead.
|
|
23
|
+
*/
|
|
24
|
+
export declare function withInferenceUserAgent(fetchImpl: FetchImpl): FetchImpl;
|
|
@@ -21,10 +21,8 @@ export interface CodexRequestOptions {
|
|
|
21
21
|
textVerbosity?: "low" | "medium" | "high";
|
|
22
22
|
include?: string[];
|
|
23
23
|
/**
|
|
24
|
-
* Responses Lite transport
|
|
25
|
-
*
|
|
26
|
-
* strips image detail, and disables parallel tool calling (codex-rs
|
|
27
|
-
* `use_responses_lite`).
|
|
24
|
+
* Responses Lite transport opt-in. Normal inference defaults to full
|
|
25
|
+
* Responses so the model can emit independent tool calls in parallel.
|
|
28
26
|
*/
|
|
29
27
|
responsesLite?: boolean;
|
|
30
28
|
}
|
|
@@ -70,13 +68,12 @@ export interface RequestBody {
|
|
|
70
68
|
[key: string]: unknown;
|
|
71
69
|
}
|
|
72
70
|
/**
|
|
73
|
-
* Resolve whether a Codex request
|
|
74
|
-
*
|
|
75
|
-
*
|
|
76
|
-
*
|
|
77
|
-
* decides.
|
|
71
|
+
* Resolve whether a Codex request explicitly opts into Responses Lite.
|
|
72
|
+
*
|
|
73
|
+
* Provider-native compaction passes the model's `useResponsesLite` flag as an
|
|
74
|
+
* explicit option; normal inference defaults to the full Responses contract.
|
|
78
75
|
*/
|
|
79
|
-
export declare function resolveCodexResponsesLite(
|
|
76
|
+
export declare function resolveCodexResponsesLite(requested: boolean | undefined): boolean;
|
|
80
77
|
/**
|
|
81
78
|
* Structural view of a Responses-style body mutated by the Lite rewrite.
|
|
82
79
|
* Loose (`unknown`) property types let the turn transformer (`RequestBody`)
|
|
@@ -12,13 +12,9 @@ export interface OpenAICodexResponsesOptions extends StreamOptions {
|
|
|
12
12
|
preferWebsockets?: boolean;
|
|
13
13
|
serviceTier?: ServiceTier;
|
|
14
14
|
/**
|
|
15
|
-
* Responses Lite transport
|
|
16
|
-
*
|
|
17
|
-
* `
|
|
18
|
-
* WebSocket upgrade (the marker is connection-scoped there, so lite and
|
|
19
|
-
* non-lite turns never share a pooled socket), moves instructions/tools
|
|
20
|
-
* into input items, strips image detail, and disables parallel tool
|
|
21
|
-
* calling — mirroring codex-rs.
|
|
15
|
+
* Responses Lite transport opt-in. Normal inference defaults to full
|
|
16
|
+
* Responses; provider-native compaction explicitly follows the model's
|
|
17
|
+
* `useResponsesLite` flag.
|
|
22
18
|
*/
|
|
23
19
|
responsesLite?: boolean;
|
|
24
20
|
/**
|
|
@@ -1,10 +1,3 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
readonly envKeys: () => string | undefined;
|
|
5
|
-
readonly mapSimpleOptions: (options: import("../index.js").SimpleStreamOptions) => {
|
|
6
|
-
region: string | undefined;
|
|
7
|
-
profile: string | undefined;
|
|
8
|
-
bearerToken: string | undefined;
|
|
9
|
-
};
|
|
10
|
-
};
|
|
1
|
+
import type { ProviderTransport } from "./build.js";
|
|
2
|
+
/** Amazon Bedrock request shaping; auth policy lives in `rules/auth/amazon-bedrock.kdl`. */
|
|
3
|
+
export declare const amazonBedrockTransport: ProviderTransport;
|
|
@@ -1,22 +1,3 @@
|
|
|
1
|
-
import type {
|
|
2
|
-
|
|
3
|
-
export declare const
|
|
4
|
-
readonly id: "bedrock-mantle";
|
|
5
|
-
readonly name: "Amazon Bedrock Mantle";
|
|
6
|
-
readonly envKeys: typeof resolveAwsRegistryApiKey;
|
|
7
|
-
readonly allowsMissingApiKey: true;
|
|
8
|
-
readonly prepareRequest: (model: Model<import("@oh-my-pi/pi-catalog").Api>, options: import("../index.js").StreamOptions) => import("../providers/bedrock-mantle.js").PreparedBedrockMantleRequest;
|
|
9
|
-
readonly mapSimpleOptions: (options: import("../index.js").SimpleStreamOptions) => {
|
|
10
|
-
providerOptions: Readonly<Record<string, unknown>> | undefined;
|
|
11
|
-
};
|
|
12
|
-
readonly prepareModelDiscovery: (config: import("./types.js").ProviderModelDiscoveryConfig) => {
|
|
13
|
-
baseUrl?: string;
|
|
14
|
-
fetch?: import("@oh-my-pi/pi-utils").FetchImpl;
|
|
15
|
-
apiKey: undefined;
|
|
16
|
-
authenticated: false;
|
|
17
|
-
} | {
|
|
18
|
-
authenticated: true;
|
|
19
|
-
baseUrl: string;
|
|
20
|
-
fetch: import("@oh-my-pi/pi-utils").FetchImpl;
|
|
21
|
-
};
|
|
22
|
-
};
|
|
1
|
+
import type { ProviderTransport } from "./build.js";
|
|
2
|
+
/** Bedrock Mantle request/discovery shaping; auth policy lives in `rules/auth/bedrock-mantle.kdl`. */
|
|
3
|
+
export declare const bedrockMantleTransport: ProviderTransport;
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Projects one compiled auth policy (`rules/auth/<id>.kdl`) plus the
|
|
3
|
+
* provider's optional TypeScript transport hooks into the
|
|
4
|
+
* {@link ProviderDefinition} the rest of `@oh-my-pi/pi-ai` consumes.
|
|
5
|
+
*/
|
|
6
|
+
import type { CompiledAuthProvider } from "@oh-my-pi/pi-catalog/compat/types";
|
|
7
|
+
import type { ProviderDefinition } from "./types.js";
|
|
8
|
+
/** Request/model shaping a provider implements in TypeScript beside its KDL auth policy. */
|
|
9
|
+
export type ProviderTransport = Pick<ProviderDefinition, "prepareModel" | "prepareRequest" | "mapSimpleOptions" | "prepareModelDiscovery">;
|
|
10
|
+
/** Materializes the registry definition for one compiled policy. */
|
|
11
|
+
export declare function buildProviderDefinition(policy: CompiledAuthProvider, transport?: ProviderTransport): ProviderDefinition;
|
|
@@ -1,13 +1,3 @@
|
|
|
1
|
-
import type {
|
|
2
|
-
/**
|
|
3
|
-
export declare
|
|
4
|
-
export declare const cloudflareAiGatewayProvider: {
|
|
5
|
-
readonly id: "cloudflare-ai-gateway";
|
|
6
|
-
readonly name: "Cloudflare AI Gateway";
|
|
7
|
-
readonly prepareModel: (model: import("@oh-my-pi/pi-catalog").Model<import("@oh-my-pi/pi-catalog").Api>) => import("@oh-my-pi/pi-catalog").Model<import("@oh-my-pi/pi-catalog").Api>;
|
|
8
|
-
readonly prepareRequest: (model: import("@oh-my-pi/pi-catalog").Model<import("@oh-my-pi/pi-catalog").Api>, options: import("../index.js").StreamOptions) => {
|
|
9
|
-
model: import("@oh-my-pi/pi-catalog").Model<import("@oh-my-pi/pi-catalog").Api>;
|
|
10
|
-
options: import("../index.js").StreamOptions;
|
|
11
|
-
};
|
|
12
|
-
readonly login: (cb: OAuthLoginCallbacks) => Promise<string>;
|
|
13
|
-
};
|
|
1
|
+
import type { ProviderTransport } from "./build.js";
|
|
2
|
+
/** Cloudflare AI Gateway model/request shaping; login lives in `oauth/cloudflare-ai-gateway.ts` + its auth rule. */
|
|
3
|
+
export declare const cloudflareAiGatewayTransport: ProviderTransport;
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* `login "api-key"` engine: open the provider's key page, prompt for a paste,
|
|
3
|
+
* optionally validate the key against a declared probe, return the key.
|
|
4
|
+
*/
|
|
5
|
+
import type { CompiledApiKeyLogin } from "@oh-my-pi/pi-catalog/compat/types";
|
|
6
|
+
import type { OAuthController } from "../oauth/types.js";
|
|
7
|
+
/** Builds the login function for one `login "api-key"` rule; `label` is the provider display name. */
|
|
8
|
+
export declare function createApiKeyLogin(rule: CompiledApiKeyLogin, label: string): (options: OAuthController) => Promise<string>;
|
|
@@ -0,0 +1,55 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Shared machinery for the declarative login engines: resolving KDL values
|
|
3
|
+
* (env overrides, obfuscation, hooks), `{placeholder}` templating, token
|
|
4
|
+
* endpoint requests and token-response → `OAuthCredentials` projection.
|
|
5
|
+
*/
|
|
6
|
+
import type { CompiledAuthValue, CompiledCredentialMap, CompiledOAuthRequest, CompiledUserinfo } from "@oh-my-pi/pi-catalog/compat/types";
|
|
7
|
+
import type { FetchImpl } from "../../types.js";
|
|
8
|
+
import type { AfterExchangeHook, ExchangeContext, HeadersHook, LoginHook, RefreshHook } from "../hooks/types.js";
|
|
9
|
+
import type { OAuthCredentials } from "../oauth/types.js";
|
|
10
|
+
/** Far-future epoch ms: credentials that never expire (durable minted keys, session JWTs). */
|
|
11
|
+
export declare const NEVER_EXPIRES = 8640000000000000;
|
|
12
|
+
/** Substitution values available to `{placeholder}` templates in KDL params/URLs. */
|
|
13
|
+
export type TemplateVars = Record<string, string | undefined>;
|
|
14
|
+
export declare function loadLoginHook(name: string): Promise<LoginHook>;
|
|
15
|
+
export declare function loadRefreshHook(name: string): Promise<RefreshHook>;
|
|
16
|
+
export declare function loadAfterExchangeHook(name: string): Promise<AfterExchangeHook>;
|
|
17
|
+
export declare function loadHeadersHook(name: string): Promise<HeadersHook>;
|
|
18
|
+
/** Resolves a KDL value node: env overrides first, then the (possibly encoded) literal or hook. */
|
|
19
|
+
export declare function resolveValue(value: CompiledAuthValue, signal?: AbortSignal): Promise<string>;
|
|
20
|
+
/** Replaces `{name}` placeholders; unknown or undefined placeholders resolve to the empty string. */
|
|
21
|
+
export declare function template(text: string, vars: TemplateVars): string;
|
|
22
|
+
/** Reads a dot path (`data.user.email`) from a parsed JSON body. */
|
|
23
|
+
export declare function jsonPath(body: unknown, path: string): unknown;
|
|
24
|
+
/** Decodes a JWT payload without verification; `null` for malformed tokens. */
|
|
25
|
+
export declare function decodeJwtPayload(token: string): Record<string, unknown> | null;
|
|
26
|
+
/** Epoch ms of a JWT `exp` claim minus `skewMs`, or undefined when absent. */
|
|
27
|
+
export declare function jwtExpiryMs(token: string, skewMs: number): number | undefined;
|
|
28
|
+
/**
|
|
29
|
+
* Projects a token response onto `OAuthCredentials` per the rule's
|
|
30
|
+
* `credential` map. A missing refresh token keeps `previous.refresh` (refresh
|
|
31
|
+
* grants that do not rotate) or falls back to the empty string.
|
|
32
|
+
*/
|
|
33
|
+
export declare function mapCredentials(map: CompiledCredentialMap, body: unknown, provider: string, previous?: OAuthCredentials): OAuthCredentials;
|
|
34
|
+
export interface RequestContext {
|
|
35
|
+
provider: string;
|
|
36
|
+
fetch: FetchImpl;
|
|
37
|
+
signal?: AbortSignal;
|
|
38
|
+
/** Extra headers merged under the rule's declared headers. */
|
|
39
|
+
headers?: Record<string, string>;
|
|
40
|
+
}
|
|
41
|
+
/**
|
|
42
|
+
* Performs one declared token-style POST. `standardParams` are the grant's
|
|
43
|
+
* baseline (included when the rule keeps `standard=#true`), `params` the
|
|
44
|
+
* rule's declared extras; both are templated with `vars`.
|
|
45
|
+
*/
|
|
46
|
+
export declare function postTokenRequest(request: CompiledOAuthRequest, standardParams: Record<string, string | undefined>, vars: TemplateVars, context: RequestContext, errorKind: "token-exchange" | "token-refresh" | "device-auth"): Promise<{
|
|
47
|
+
body: unknown;
|
|
48
|
+
response: Response;
|
|
49
|
+
}>;
|
|
50
|
+
/** Bearer GET declared by `userinfo`; failures leave identity fields unset. */
|
|
51
|
+
export declare function applyUserinfo(userinfo: CompiledUserinfo | undefined, credentials: OAuthCredentials, context: RequestContext): Promise<OAuthCredentials>;
|
|
52
|
+
/** Runs the rule's after-exchange / after-refresh hook, if declared. */
|
|
53
|
+
export declare function applyAfterExchange(hook: string | undefined, credentials: OAuthCredentials, context: ExchangeContext): Promise<OAuthCredentials>;
|
|
54
|
+
export declare function describeError(error: unknown): string;
|
|
55
|
+
export declare function throwIfCancelled(signal: AbortSignal | undefined): void;
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* `login "device-code"` engine: RFC 8628 device authorization — request a
|
|
3
|
+
* user code, show the verification URL, poll the token endpoint until the
|
|
4
|
+
* grant completes, then project / enrich the credentials.
|
|
5
|
+
*/
|
|
6
|
+
import type { CompiledDeviceCodeLogin } from "@oh-my-pi/pi-catalog/compat/types";
|
|
7
|
+
import type { OAuthController, OAuthCredentials } from "../oauth/types.js";
|
|
8
|
+
/** Builds the login function for one `login "device-code"` rule. */
|
|
9
|
+
export declare function createDeviceCodeLogin(rule: CompiledDeviceCodeLogin, provider: string): (ctrl: OAuthController) => Promise<OAuthCredentials>;
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* `login "oauth-code"` engine: authorization-code grant (optionally PKCE)
|
|
3
|
+
* through the loopback callback server, followed by the declared token
|
|
4
|
+
* exchange, credential projection, userinfo enrichment and after-exchange hook.
|
|
5
|
+
*/
|
|
6
|
+
import type { CompiledAuthProvider, CompiledCallback, CompiledOAuthCodeLogin } from "@oh-my-pi/pi-catalog/compat/types";
|
|
7
|
+
import { OAuthCallbackFlow, type OAuthCallbackFlowOptions } from "../oauth/callback-server.js";
|
|
8
|
+
import type { OAuthController, OAuthCredentials } from "../oauth/types.js";
|
|
9
|
+
/**
|
|
10
|
+
* Callback-server options for a rule. A `redirect-uri-env` override is
|
|
11
|
+
* advertised verbatim with random-port fallback disabled; HTTP loopback
|
|
12
|
+
* overrides also bind the listener to the URI's host/port/path.
|
|
13
|
+
*/
|
|
14
|
+
export declare function resolveCallbackOptions(callback: CompiledCallback, provider: string, signal?: AbortSignal): Promise<OAuthCallbackFlowOptions>;
|
|
15
|
+
/** Generic authorization-code flow driven by one compiled rule. */
|
|
16
|
+
export declare class DeclarativeOAuthCodeFlow extends OAuthCallbackFlow {
|
|
17
|
+
#private;
|
|
18
|
+
constructor(ctrl: OAuthController, rule: CompiledOAuthCodeLogin, policy: CompiledAuthProvider, options: OAuthCallbackFlowOptions);
|
|
19
|
+
generateState(): string;
|
|
20
|
+
generateAuthUrl(state: string, redirectUri: string): Promise<{
|
|
21
|
+
url: string;
|
|
22
|
+
instructions?: string;
|
|
23
|
+
}>;
|
|
24
|
+
exchangeToken(code: string, state: string, redirectUri: string): Promise<OAuthCredentials>;
|
|
25
|
+
}
|
|
26
|
+
/** Builds the login function for one `login "oauth-code"` rule. */
|
|
27
|
+
export declare function createOAuthCodeLogin(rule: CompiledOAuthCodeLogin, policy: CompiledAuthProvider): (ctrl: OAuthController) => Promise<OAuthCredentials>;
|