@oh-my-pi/pi-ai 18.6.1 → 18.7.0
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 +38 -38
- package/README.md +15 -0
- package/dist/types/auth/types.d.ts +4 -0
- package/dist/types/auth-broker/refresher.d.ts +6 -1
- package/dist/types/error/flags.d.ts +15 -0
- package/dist/types/images/index.d.ts +2 -3
- package/dist/types/providers/anthropic.d.ts +15 -2
- package/dist/types/providers/google-auth.d.ts +4 -1
- package/dist/types/providers/mock.d.ts +3 -1
- package/dist/types/providers/openai-responses-wire.d.ts +0 -54
- package/dist/types/providers/openai-responses.d.ts +32 -3
- package/dist/types/providers/openai-shared.d.ts +4 -1
- package/dist/types/registry/oauth/cursor.d.ts +9 -1
- package/dist/types/registry/oauth/index.d.ts +2 -0
- package/dist/types/registry/oauth/snowflake.d.ts +3 -0
- package/dist/types/registry/snowflake.d.ts +4 -0
- package/dist/types/types.d.ts +72 -13
- package/dist/types/utils/idle-iterator.d.ts +11 -0
- package/dist/types/utils.d.ts +6 -0
- package/package.json +6 -6
- package/src/auth/cascade.ts +6 -2
- package/src/auth/health.ts +1 -0
- package/src/auth/select.ts +3 -1
- package/src/auth/types.ts +4 -0
- package/src/auth-broker/refresher.ts +8 -1
- package/src/error/flags.ts +22 -0
- package/src/images/index.ts +3 -17
- package/src/providers/anthropic.ts +111 -45
- package/src/providers/devin.ts +3 -1
- package/src/providers/factory-droid.ts +2 -0
- package/src/providers/gitlab-duo.ts +1 -0
- package/src/providers/google-auth.ts +10 -3
- package/src/providers/mock.ts +4 -0
- package/src/providers/openai-anthropic-shim.ts +1 -0
- package/src/providers/openai-codex-responses.ts +37 -38
- package/src/providers/openai-completions.ts +3 -0
- package/src/providers/openai-responses-wire.ts +0 -54
- package/src/providers/openai-responses.ts +349 -6
- package/src/providers/openai-shared.ts +20 -9
- package/src/providers/pi-native-server.ts +1 -0
- package/src/registry/hooks/custom.ts +2 -0
- package/src/registry/hooks/env.ts +2 -5
- package/src/registry/oauth/cursor.ts +57 -3
- package/src/registry/oauth/index.ts +5 -0
- package/src/registry/oauth/snowflake.ts +183 -0
- package/src/registry/registry.ts +2 -0
- package/src/registry/snowflake.ts +149 -0
- package/src/stream.ts +35 -33
- package/src/types.ts +93 -14
- package/src/usage/claude.ts +3 -0
- package/src/usage/cursor.ts +14 -25
- package/src/usage/minimax-code.ts +8 -1
- package/src/utils/idle-iterator.ts +80 -35
- package/src/utils/thinking-loop.ts +18 -10
- package/src/utils.ts +19 -4
package/CHANGELOG.md
CHANGED
|
@@ -2,6 +2,43 @@
|
|
|
2
2
|
|
|
3
3
|
## [Unreleased]
|
|
4
4
|
|
|
5
|
+
## [18.7.0] - 2026-10-06
|
|
6
|
+
|
|
7
|
+
### Added
|
|
8
|
+
|
|
9
|
+
- Added `getOAuthCredentialProvider()` to resolve login aliases, such as `openai-codex-device`, to the provider where their credentials are stored.
|
|
10
|
+
|
|
11
|
+
### Fixed
|
|
12
|
+
|
|
13
|
+
- Fixed Ultrafast service-tier billing and usage accounting: GPT-6 Astra now applies its published premium rates—6× on the OpenAI API and 8× included usage on Codex—and is counted toward the premium-request limit.
|
|
14
|
+
- Fixed Vertex AI authentication on Windows when credentials are created with `gcloud auth application-default login`.
|
|
15
|
+
- Fixed selecting Cursor accounts by email through `auth.accountPolicies` and `/session pin`; newly refreshed and existing accounts now retain the account email.
|
|
16
|
+
|
|
17
|
+
## [18.6.3] - 2026-10-06
|
|
18
|
+
|
|
19
|
+
### Added
|
|
20
|
+
|
|
21
|
+
- Added per-model `compat.statefulResponses` to enable or disable stored Responses chaining (`previous_response_id` with `store: true`) for one endpoint without the official-only request fields that `compat.officialEndpoint` implies ([#13686](https://github.com/can1357/oh-my-pi/pull/13686) by [@alphastorm](https://github.com/alphastorm)).
|
|
22
|
+
- Added Snowflake Cortex with browser OAuth, token refresh, PAT environment authentication, and streaming Claude/OpenAI models with local tool execution ([#14507](https://github.com/can1357/oh-my-pi/pull/14507) by [@jorgoose](https://github.com/jorgoose)).
|
|
23
|
+
- `AuthStorage.health.check()` accepts `excludeProviders` to skip credentials of providers the caller does not serve ([#14234](https://github.com/can1357/oh-my-pi/pull/14234) by [@will-bogusz](https://github.com/will-bogusz))
|
|
24
|
+
|
|
25
|
+
### Changed
|
|
26
|
+
|
|
27
|
+
- Reduced CPU spent on thinking-loop detection while streaming long reasoning ([#14284](https://github.com/can1357/oh-my-pi/pull/14284) by [@abilliontokens](https://github.com/abilliontokens)).
|
|
28
|
+
- Added `recordAffinity: false` to credential resolution options, selecting as the session would without pinning the choice to that session ([#14512](https://github.com/can1357/oh-my-pi/pull/14512) by [@will-bogusz](https://github.com/will-bogusz))
|
|
29
|
+
|
|
30
|
+
### Fixed
|
|
31
|
+
|
|
32
|
+
- Codex native-lane steering rejections (`unsupported_native_inflight_message`) now classify as retryable from their error text alone, matching the provider's own classification, and `AIError.isCodexSteerRejection()` identifies them so the agent retry can stay on the same model ([#14242](https://github.com/can1357/oh-my-pi/pull/14242) by [@alphastorm](https://github.com/alphastorm))
|
|
33
|
+
- Fixed replayed Responses and Codex history, including persisted Codex user/developer and assistant items, sending `detail: "original"` images to endpoints whose `supportsImageDetailOriginal` is off ([#13687](https://github.com/can1357/oh-my-pi/pull/13687) by [@alphastorm](https://github.com/alphastorm)).
|
|
34
|
+
- Fixed thinking in turns kept after Anthropic native compaction being rejected or dropped on the next request ([#14251](https://github.com/can1357/oh-my-pi/pull/14251) by [@will-bogusz](https://github.com/will-bogusz))
|
|
35
|
+
- Fixed Claude usage being re-polled every 10 seconds while Anthropic rate-limits the account; a failed refresh now waits a minute before trying again ([#14515](https://github.com/can1357/oh-my-pi/pull/14515) by [@will-bogusz](https://github.com/will-bogusz))
|
|
36
|
+
- Fixed Devin requests skipping the `onPayload` hook, so payload capture now sees each Devin chat request and a returned replacement is what gets sent ([#14506](https://github.com/can1357/oh-my-pi/pull/14506) by [@will-bogusz](https://github.com/will-bogusz))
|
|
37
|
+
- An OpenAI Responses turn whose connection drops mid-stream can now recover the finished answer from the provider (on hosts that store results, such as Muse Code) instead of re-running the whole turn and discarding the reasoning already done. Storage is opt-in: pass `storeResponses: true`, set `PI_MUSE_STORE_RESPONSES=1`, or set a process-wide default with `configureProviderStoreResponses` ([#14293](https://github.com/can1357/oh-my-pi/pull/14293) and [#14534](https://github.com/can1357/oh-my-pi/pull/14534) by [@abilliontokens](https://github.com/abilliontokens)).
|
|
38
|
+
- Fixed the auth broker exiting when a background OAuth refresh sweep cannot read the credential store; the failure is now logged and the next sweep retries ([#14538](https://github.com/can1357/oh-my-pi/issues/14538))
|
|
39
|
+
- Fixed Anthropic OAuth billing headers changing during developer-first sessions and side turns, preserving the prompt-cache prefix ([#14495](https://github.com/can1357/oh-my-pi/issues/14495)).
|
|
40
|
+
- Fixed OpenAI-compatible chat-completions gateways recording completed turns as client-cancelled because the connection closed before their `[DONE]` sentinel arrived ([#14481](https://github.com/can1357/oh-my-pi/issues/14481)).
|
|
41
|
+
|
|
5
42
|
## [18.6.1] - 2026-10-04
|
|
6
43
|
|
|
7
44
|
### Fixed
|
|
@@ -2290,41 +2327,4 @@
|
|
|
2290
2327
|
- Fixed truncated Gemini and Gemma tool blocks from being emitted as plain text during streaming
|
|
2291
2328
|
- Fixed Gemini/Gemma in-band tool-call parsing around Python comments, raw/unicode string literals, and Gemma close-token text inside string values.
|
|
2292
2329
|
|
|
2293
|
-
|
|
2294
|
-
|
|
2295
|
-
### Added
|
|
2296
|
-
|
|
2297
|
-
- Added `jsonSchemaToTypeScript` to `@oh-my-pi/pi-ai/utils/schema` to render JSON Schema argument shapes as compact, human-readable TypeScript-style signatures
|
|
2298
|
-
- Added the generic `ToolExample` type (`ToolCallExample`/`ToolCompareExample`/`ToolNoteExample`, parameterized over a tool's argument shape) and an `examples` property on the `Tool` interface for defining tool-call examples once as data.
|
|
2299
|
-
- Added `renderToolExamples` (via `@oh-my-pi/pi-ai/grammar`) to render a tool's examples into an `<examples>` block in the model's native tool-call syntax, with an optional `_i` intent-field placeholder injected when intent tracing is active.
|
|
2300
|
-
- Added per-grammar `renderToolCall` rendering of a single tool-call invocation (the inner element only, without the parallel-call block envelope), distinct from `renderAssistantToolCalls` which renders a complete block of one or more parallel calls.
|
|
2301
|
-
- Added a `GrammarRenderOptions.example` flag to `renderToolCall`: when set, the invocation renders as the bare payload — Harmony emits just the JSON arguments, dropping the verbose `<|start|>…<|message|>…<|call|>` envelope — so `renderToolExamples` keeps `<examples>` blocks legible.
|
|
2302
|
-
- Added an `abortOnFabrication` parameter to `wrapInbandToolStream` (default `true`): when `false`, a fabricated in-band tool-result continuation is discarded without aborting the provider request instead of cutting the turn short.
|
|
2303
|
-
- Added `@oh-my-pi/pi-ai/utils/harmony-leak` export with helpers to detect, audit, and recover GPT-5 Harmony tool-call header leaks
|
|
2304
|
-
- Added the `@oh-my-pi/pi-ai/grammar` public entrypoint for grammar factories, prompt/call rendering, in-band scanning, history encoding, and related typed utilities
|
|
2305
|
-
- Added a unified in-band tool-call grammar engine with syntax-owned scanners, prompts, history rendering, tool-result rendering, and stream adaptation for GLM, Hermes/Qwen, Kimi, XML/Anthropic, DeepSeek, Harmony, and pi-native formats.
|
|
2306
|
-
|
|
2307
|
-
### Changed
|
|
2308
|
-
|
|
2309
|
-
- Changed Harmony in-band tool-call rendering to omit the `<|constrain|>json` marker before the payload in `commentary` channel calls
|
|
2310
|
-
- Changed tool inventory rendering to present each tool’s `Parameters` section as a simplified TypeScript-style signature derived from its wire schema
|
|
2311
|
-
- Added raw in-band tool-call block capture to parsed owned tool calls so debugging can inspect the exact model-emitted call syntax.
|
|
2312
|
-
- Moved the canonical `ToolCallSyntax` union to `@oh-my-pi/pi-catalog/identity` and re-exported it from `@oh-my-pi/pi-ai/grammar` so the catalog can own the syntax vocabulary without an `@oh-my-pi/pi-ai` runtime import; all existing import paths are unchanged.
|
|
2313
|
-
- Made tool-call argument validation more lenient for schema-directed scalar coercions, including object/array stringification and 0/1 boolean coercion.
|
|
2314
|
-
- Changed `renderToolInventory` (the verbose system-prompt inventory and `/dump`) to render each tool as a `# Tool: <name>` markdown section instead of a `<tool name="…">…</tool>` wrapper.
|
|
2315
|
-
|
|
2316
|
-
### Fixed
|
|
2317
|
-
|
|
2318
|
-
- 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
|
|
2319
|
-
- 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
|
|
2320
|
-
- 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.
|
|
2321
|
-
- 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))
|
|
2322
|
-
- 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)).
|
|
2323
|
-
|
|
2324
|
-
## [15.13.1] - 2026-06-15
|
|
2325
|
-
|
|
2326
|
-
### Fixed
|
|
2327
|
-
|
|
2328
|
-
- Fixed the auth-broker (`OMP_AUTH_BROKER_URL`) rejecting OAuth credentials that carry provider-specific extension fields (e.g. an MCP server's `tokenUrl`/`clientId`/`clientSecret`/`resource` embedded for self-contained token refresh): the OAuth credential wire schema was `.strict()`, so `POST /v1/credential` failed with `400 unrecognized_keys` and a broker-backed MCP reauth reported success while the reloaded credential lacked its refresh material and could no longer refresh. The OAuth wire schema now uses `.loose()` to preserve unknown fields — matching the field-preserving local SQLite store — so extra OAuth fields round-trip through broker set->get (envelope and API-key schemas stay strict).
|
|
2329
|
-
|
|
2330
|
-
Older entries are archived in [packages/ai/CHANGELOG.md@bac7e83b5b0e](https://github.com/can1357/oh-my-pi/blob/bac7e83b5b0eb86c909c17830a6666efc359578b/packages/ai/CHANGELOG.md).
|
|
2330
|
+
Older entries are archived in [packages/ai/CHANGELOG.md@a20cc0d04b64](https://github.com/can1357/oh-my-pi/blob/a20cc0d04b64f4a68fcc559cbd258743d984c50e/packages/ai/CHANGELOG.md).
|
package/README.md
CHANGED
|
@@ -77,6 +77,7 @@ Unified LLM API with automatic model discovery, provider configuration, token an
|
|
|
77
77
|
- **QwenCloud Token Plan** (supports `/login alibaba-token-plan`, `ALIBABA_TOKEN_PLAN_API_KEY`, or `BAILIAN_TOKEN_PLAN_API_KEY`; interactive login first selects a region — International (Singapore, default), China (Beijing) for 百炼 Token Plan keys, or a custom base URL — since region keys are non-interchangeable, then optionally stores a `home.qwencloud.com` Cookie request header for best-effort 5-hour and 7-day quota reporting)
|
|
78
78
|
To enable quota reporting, sign in to the Token Plan dashboard, copy the `Cookie` request-header value from a `home.qwencloud.com` request in browser developer tools, and paste it at the second login prompt. Press Enter to skip; the Cookie is sensitive and session-lived, so rerun login when it expires.
|
|
79
79
|
- **Cloudflare AI Gateway** (supports `/login cloudflare-ai-gateway`, or `CLOUDFLARE_AI_GATEWAY_API_KEY` with `CLOUDFLARE_ACCOUNT_ID` and `CLOUDFLARE_GATEWAY_ID`)
|
|
80
|
+
- **Snowflake Cortex** (browser `/login snowflake`, or `SNOWFLAKE_ACCOUNT` + `SNOWFLAKE_PAT`; account-billed Cortex REST API)
|
|
80
81
|
- **Ollama** (local OpenAI-compatible runtime; optional `OLLAMA_API_KEY`)
|
|
81
82
|
- **Ollama Cloud** (hosted native Ollama API; requires `OLLAMA_CLOUD_API_KEY`)
|
|
82
83
|
- **llama.cpp** (local OpenAI and Anthropic compatible inference server)
|
|
@@ -961,6 +962,7 @@ In Node.js environments, you can set environment variables to avoid passing API
|
|
|
961
962
|
| ZenMux | `ZENMUX_API_KEY` |
|
|
962
963
|
| vLLM | `VLLM_API_KEY` |
|
|
963
964
|
| Cloudflare AI Gateway | `CLOUDFLARE_AI_GATEWAY_API_KEY` + `CLOUDFLARE_ACCOUNT_ID` + `CLOUDFLARE_GATEWAY_ID` |
|
|
965
|
+
| Snowflake Cortex | `SNOWFLAKE_PAT` + `SNOWFLAKE_ACCOUNT` |
|
|
964
966
|
| GitHub Copilot | `COPILOT_GITHUB_TOKEN` or `GH_TOKEN` or `GITHUB_TOKEN` |
|
|
965
967
|
|
|
966
968
|
`/login cloudflare-ai-gateway` collects and stores the gateway token, account ID, and gateway ID. For environment configuration, set all three Cloudflare values above. OMP derives provider endpoints from the account and gateway IDs.
|
|
@@ -1029,9 +1031,22 @@ Several providers support OAuth authentication (some also support static API key
|
|
|
1029
1031
|
- **Google Gemini CLI** (Gemini 2.0/2.5 via Google Cloud Code Assist; free tier or paid subscription)
|
|
1030
1032
|
- **Antigravity** (Free Gemini 3, Claude, GPT-OSS via Google Cloud)
|
|
1031
1033
|
- **Qwen Portal** (Qwen OAuth token or API key)
|
|
1034
|
+
- **Snowflake Cortex** (Snowflake account OAuth with PKCE and refresh, subject to the account's local-application integration)
|
|
1032
1035
|
|
|
1033
1036
|
For paid Cloud Code Assist subscriptions, set `GOOGLE_CLOUD_PROJECT` or `GOOGLE_CLOUD_PROJECT_ID` to your project ID.
|
|
1034
1037
|
|
|
1038
|
+
### Snowflake Cortex
|
|
1039
|
+
|
|
1040
|
+
`/login snowflake` prompts for an account identifier (for example, `myorg-myaccount`), an HTTPS Snowflake account URL, or a Snowsight account link. It opens Snowflake's built-in `SNOWFLAKE$LOCAL_APPLICATION` OAuth flow using PKCE and a `127.0.0.1` callback (port 54551, with an ephemeral-port fallback). The stored account selects the inference endpoint; OAuth credentials cannot be sent to a different account through a custom model endpoint.
|
|
1041
|
+
|
|
1042
|
+
The default inference role must hold either `SNOWFLAKE.CORTEX_USER` or the narrower, REST-only `SNOWFLAKE.CORTEX_REST_API_USER` (recommended for least privilege). `CORTEX_REST_API_USER` cannot be granted to a user directly; grant it to a custom role, and revoke `CORTEX_USER` from users who already hold it so the narrower control applies. The Cortex REST API is not available in China-region (`.snowflakecomputing.cn`) accounts. An administrator can check local-app availability with `SHOW SECURITY INTEGRATIONS LIKE 'SNOWFLAKE$LOCAL_APPLICATION'` and enable the integration or refresh issuance if necessary. When Snowflake issues a refresh token, omp refreshes the access token automatically. Without one, login remains valid until expiry; then sign in again or use the PAT environment alternative.
|
|
1043
|
+
|
|
1044
|
+
For PAT authentication, set both `SNOWFLAKE_ACCOUNT` and `SNOWFLAKE_PAT`. Prefer a short-lived PAT restricted to a dedicated inference role and the required user-scoped network allowlist; do not disable network-policy enforcement. See [Snowflake PAT setup](https://docs.snowflake.com/en/user-guide/programmatic-access-tokens) and [local-application OAuth](https://docs.snowflake.com/en/user-guide/oauth-local-applications).
|
|
1045
|
+
|
|
1046
|
+
Claude models use `/api/v2/cortex/v1/messages`; OpenAI models use `/api/v2/cortex/v1/chat/completions`. Both reuse omp's streaming transports and local tool execution. The 15 bundled models are a documented roster, not an account entitlement check: availability still depends on Cortex REST API enablement, role grants, model allowlists, and region. If authentication succeeds but Cortex returns `003001` ("This account is not allowed to access this endpoint"), Snowflake has not enabled Cortex REST for the account. [Self-service trial accounts disable AI features until a credit card is added](https://docs.snowflake.com/en/user-guide/admin-trial-account#label-trial-account-ai-features) (adding one does not end the trial); REST access can remain disabled even after AI SQL functions work, in which case Snowflake support must enable it. Cross-region inference requires an account administrator's explicit decision. `omp models snowflake --json` lists available models only after credentials are configured.
|
|
1047
|
+
|
|
1048
|
+
This provider uses the [public, account-billed Cortex REST API](https://docs.snowflake.com/en/user-guide/snowflake-cortex/cortex-rest-api). CoCo-subscription coverage is unverified. Catalog prices are per-million-token estimates from [Consumption Table 6(b)](https://www.snowflake.com/legal-files/CreditConsumptionTable.pdf) at [$2 per AI Credit](https://docs.snowflake.com/en/user-guide/snowflake-cortex/pricing) for on-demand global routing, not your contract price. Output is capped at the REST API's documented 16,384-token maximum; context windows are conservative AI_COMPLETE limits, not verified REST maxima. Cortex compatibility rules limit explicit cache retention to five minutes. Paste an account identifier or current Snowsight link; legacy `app.snowflake.com/<region>/<locator>` links are rejected because they don't map uniformly to an account host.
|
|
1049
|
+
|
|
1035
1050
|
### Vertex AI (ADC)
|
|
1036
1051
|
|
|
1037
1052
|
Vertex AI models use Application Default Credentials (ADC):
|
|
@@ -220,6 +220,8 @@ export interface CheckCredentialsOptions {
|
|
|
220
220
|
completionProbe?: CompletionProbe;
|
|
221
221
|
/** Per-credential completion probe timeout (ms). Defaults to `timeoutMs`. */
|
|
222
222
|
completionTimeoutMs?: number;
|
|
223
|
+
/** Providers whose credentials are skipped entirely (not probed, not reported). */
|
|
224
|
+
excludeProviders?: ReadonlySet<string>;
|
|
223
225
|
}
|
|
224
226
|
/**
|
|
225
227
|
* Sentinel value placed in OAuth `refresh` fields when a credential is shared
|
|
@@ -424,6 +426,8 @@ export type AuthApiKeyOptions = {
|
|
|
424
426
|
forceRefresh?: boolean;
|
|
425
427
|
/** Explicit provider-401 recovery; generic force refreshes leave this unset. */
|
|
426
428
|
refreshReason?: OAuthRefreshReason;
|
|
429
|
+
/** When false, select as `sessionId` would without recording the choice as that session's sticky credential. */
|
|
430
|
+
recordAffinity?: boolean;
|
|
427
431
|
};
|
|
428
432
|
/** Non-secret identity bound to the OAuth credential selected for one request attempt. */
|
|
429
433
|
export interface OAuthRequestIdentity {
|
|
@@ -20,6 +20,11 @@ export declare class AuthBrokerRefresher {
|
|
|
20
20
|
start(): void;
|
|
21
21
|
stop(): void;
|
|
22
22
|
getSchedule(): AuthBrokerRefresherSchedule;
|
|
23
|
-
/**
|
|
23
|
+
/**
|
|
24
|
+
* Run one sweep. Exposed for tests.
|
|
25
|
+
*
|
|
26
|
+
* Never rejects: callers fire it unawaited from a timer, so a failed sweep
|
|
27
|
+
* (e.g. an unreadable credential store) is logged and retried next interval.
|
|
28
|
+
*/
|
|
24
29
|
tick(): Promise<void>;
|
|
25
30
|
}
|
|
@@ -43,6 +43,21 @@ export declare function isResponsesRequestBodyReadTimeout(message: {
|
|
|
43
43
|
errorMessage?: string;
|
|
44
44
|
requestBodyReadTimeoutFullReplay?: boolean;
|
|
45
45
|
}): boolean;
|
|
46
|
+
/**
|
|
47
|
+
* Codex code for the experimental native turn lane refusing a mid-response
|
|
48
|
+
* `response.steer`; the server then drops the in-flight response and closes
|
|
49
|
+
* the socket.
|
|
50
|
+
*/
|
|
51
|
+
export declare const CODEX_NATIVE_LANE_STEER_REJECTED_CODE = "unsupported_native_inflight_message";
|
|
52
|
+
/**
|
|
53
|
+
* A Codex turn the native turn lane dropped because omp steered it. The
|
|
54
|
+
* rejection answers our own `response.steer`, not the model's health: the
|
|
55
|
+
* provider stops steering the session, so the same model replays cleanly.
|
|
56
|
+
*/
|
|
57
|
+
export declare function isCodexSteerRejection(message: {
|
|
58
|
+
api?: Api;
|
|
59
|
+
errorMessage?: string;
|
|
60
|
+
}): boolean;
|
|
46
61
|
export declare const TRANSIENT_TRANSPORT_PATTERN: RegExp;
|
|
47
62
|
export declare const ANTHROPIC_ACCOUNT_POLICY_PATTERN: RegExp;
|
|
48
63
|
/** Whether an error message represents an Anthropic account-scoped permission/policy denial. */
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import type
|
|
1
|
+
import { type Api, type ImageGenerationApi, type Model } from "@oh-my-pi/pi-catalog/types";
|
|
2
2
|
import type { ImageGenerationOptions, ImageGenerationRequest, ImageGenerationResult } from "./types.js";
|
|
3
3
|
export * from "./google-antigravity.js";
|
|
4
4
|
export * from "./google-generative-ai.js";
|
|
@@ -6,8 +6,7 @@ export * from "./openai-hosted.js";
|
|
|
6
6
|
export * from "./openai-images.js";
|
|
7
7
|
export * from "./openrouter-images.js";
|
|
8
8
|
export * from "./types.js";
|
|
9
|
-
|
|
10
|
-
export type ImageGenerationApi = "openai-images" | "openrouter-images" | "google-generative-ai" | "google-gemini-cli" | "openai-responses" | "openai-codex-responses";
|
|
9
|
+
export type { ImageGenerationApi } from "@oh-my-pi/pi-catalog/types";
|
|
11
10
|
/** Whether a catalog API generates images through one of the pi-ai image clients. */
|
|
12
11
|
export declare function isImageGenerationApi(api: Api): api is ImageGenerationApi;
|
|
13
12
|
/** Generate (or edit, when `request.inputImages` is set) images through the transport selected by the model's `api`. */
|
|
@@ -1,4 +1,5 @@
|
|
|
1
|
-
import type {
|
|
1
|
+
import type { Effort } from "@oh-my-pi/pi-catalog/effort";
|
|
2
|
+
import type { AnthropicCompactionRequest, AnthropicOutputEffort, FetchImpl, Message, Model, ServiceTier, SimpleStreamOptions, StreamFunction, StreamOptions, Usage } from "../types.js";
|
|
2
3
|
import { type AnthropicFetchOptions, type AnthropicMessagesClientLike } from "./anthropic-client.js";
|
|
3
4
|
import { type FallbackParam, type MessageParam, type TextBlockParam } from "./anthropic-wire.js";
|
|
4
5
|
import { resolvesToOfficialAnthropicEndpoint, supportsAnthropicCompaction, supportsAnthropicCompactionOnClient } from "./anthropic-compaction.js";
|
|
@@ -209,7 +210,7 @@ export type AnthropicSystemBlock = {
|
|
|
209
210
|
type SystemBlockOptions = {
|
|
210
211
|
includeClaudeCodeInstruction?: boolean;
|
|
211
212
|
extraInstructions?: string[];
|
|
212
|
-
/** Text of the first user
|
|
213
|
+
/** Text of the first conversational wire user turn, used as the billing fingerprint seed. */
|
|
213
214
|
firstUserMessageText?: string;
|
|
214
215
|
/** Cache lifetime shared by the OAuth system breakpoint and later message breakpoints. */
|
|
215
216
|
cacheControl?: AnthropicCacheControl;
|
|
@@ -234,6 +235,16 @@ export declare function budgetThinkingOutput(maxTokens: number | undefined, budg
|
|
|
234
235
|
maxTokens: number;
|
|
235
236
|
budgetTokens: number;
|
|
236
237
|
};
|
|
238
|
+
/**
|
|
239
|
+
* The effort whose thinking allowance an on-demand compaction request over
|
|
240
|
+
* `messages` gets. It sends no effort change of its own, so once an earlier
|
|
241
|
+
* request recorded an effort, the one it left in force applies, even when
|
|
242
|
+
* `requested` differs or is off. When that request named none, the API's
|
|
243
|
+
* per-model default applies, which is not known here: the request gets the
|
|
244
|
+
* largest effort's allowance (`max_tokens` is a cap, not spend). Without a
|
|
245
|
+
* recorded effort the request sets its own.
|
|
246
|
+
*/
|
|
247
|
+
export declare function resolveAnthropicCompactionEffort(model: Model<"anthropic-messages">, messages: readonly Message[], requested: Effort | undefined): Effort | undefined;
|
|
237
248
|
/**
|
|
238
249
|
* Whether the conversation has stopped being thinking-led, so routes with
|
|
239
250
|
* `compat.stripThinkingHistory` drop the budget `thinking` config and replay
|
|
@@ -269,5 +280,7 @@ export declare function convertAnthropicMessages(messages: Message[], model: Mod
|
|
|
269
280
|
dropAllThinking?: boolean;
|
|
270
281
|
droppedThinkingBlocks?: ReadonlySet<string>;
|
|
271
282
|
credentialId?: number;
|
|
283
|
+
/** On-demand compaction request: it ends inside the conversation, so it gets nothing live requests lack there. */
|
|
284
|
+
compactionRequest?: AnthropicCompactionRequest;
|
|
272
285
|
}): AnthropicMessageParam[];
|
|
273
286
|
export declare function normalizeAnthropicToolSchema(schema: unknown): unknown;
|
|
@@ -5,13 +5,16 @@
|
|
|
5
5
|
* Sources, in priority order:
|
|
6
6
|
* 1. `GOOGLE_APPLICATION_CREDENTIALS` env → file with `type: "service_account"` (RS256 JWT exchange)
|
|
7
7
|
* or `type: "authorized_user"` (refresh-token exchange).
|
|
8
|
-
* 2.
|
|
8
|
+
* 2. gcloud user ADC: `%APPDATA%\gcloud\application_default_credentials.json` on Windows,
|
|
9
|
+
* `~/.config/gcloud/application_default_credentials.json` elsewhere (authorized_user flow).
|
|
9
10
|
* 3. GCE / Cloud Run metadata server (`metadata.google.internal`).
|
|
10
11
|
*
|
|
11
12
|
* Tokens are cached per source key and refreshed `GOOGLE_VERTEX_REFRESH_SKEW_MS` before expiry
|
|
12
13
|
* (default 60s). Concurrent callers waiting on a refresh share the same in-flight promise.
|
|
13
14
|
*/
|
|
14
15
|
import type { FetchImpl } from "../types.js";
|
|
16
|
+
/** gcloud's user ADC file: `%APPDATA%\gcloud\…` on Windows, `~/.config/gcloud/…` elsewhere. */
|
|
17
|
+
export declare function userAdcPath(platform?: typeof process.platform, appData?: string | undefined): string;
|
|
15
18
|
/**
|
|
16
19
|
* Returns a Bearer access token suitable for the `Authorization` header on Vertex AI calls.
|
|
17
20
|
* The token is cached in module scope and refreshed `GOOGLE_VERTEX_REFRESH_SKEW_MS` ms before it expires.
|
|
@@ -41,7 +41,7 @@
|
|
|
41
41
|
* // Inspect calls afterwards.
|
|
42
42
|
* expect(mock.calls).toHaveLength(2);
|
|
43
43
|
*/
|
|
44
|
-
import type { AnthropicFallbackCreditHandle, Api, Context, Model, SimpleStreamOptions, StopDetails, StopReason, Usage } from "../types.js";
|
|
44
|
+
import type { AnthropicFallbackCreditHandle, Api, Context, Model, ServiceTier, SimpleStreamOptions, StopDetails, StopReason, Usage } from "../types.js";
|
|
45
45
|
import { AssistantMessageEventStream } from "../utils/event-stream.js";
|
|
46
46
|
/** The API string this provider serves. */
|
|
47
47
|
export declare const MOCK_API: "mock";
|
|
@@ -78,6 +78,8 @@ export interface MockResponse {
|
|
|
78
78
|
usage?: Partial<Omit<Usage, "cost">> & {
|
|
79
79
|
cost?: Partial<Usage["cost"]>;
|
|
80
80
|
};
|
|
81
|
+
/** Service tier the mock reports serving the turn, as a real provider's response echo would. */
|
|
82
|
+
serviceTier?: ServiceTier;
|
|
81
83
|
/** Pre-set responseId. */
|
|
82
84
|
responseId?: string;
|
|
83
85
|
/** If set, the stream emits a terminal error event instead of completing. */
|
|
@@ -906,60 +906,6 @@ export declare namespace Response {
|
|
|
906
906
|
*/
|
|
907
907
|
type: "error";
|
|
908
908
|
}
|
|
909
|
-
/**
|
|
910
|
-
* A moderation result produced for the response input or output.
|
|
911
|
-
*/
|
|
912
|
-
interface ModerationResult {
|
|
913
|
-
/**
|
|
914
|
-
* A dictionary of moderation categories to booleans, True if the input is flagged
|
|
915
|
-
* under this category.
|
|
916
|
-
*/
|
|
917
|
-
categories: {
|
|
918
|
-
[key: string]: boolean;
|
|
919
|
-
};
|
|
920
|
-
/**
|
|
921
|
-
* Which modalities of input are reflected by the score for each category.
|
|
922
|
-
*/
|
|
923
|
-
category_applied_input_types: {
|
|
924
|
-
[key: string]: Array<"text" | "image">;
|
|
925
|
-
};
|
|
926
|
-
/**
|
|
927
|
-
* A dictionary of moderation categories to scores.
|
|
928
|
-
*/
|
|
929
|
-
category_scores: {
|
|
930
|
-
[key: string]: number;
|
|
931
|
-
};
|
|
932
|
-
/**
|
|
933
|
-
* A boolean indicating whether the content was flagged by any category.
|
|
934
|
-
*/
|
|
935
|
-
flagged: boolean;
|
|
936
|
-
/**
|
|
937
|
-
* The moderation model that produced this result.
|
|
938
|
-
*/
|
|
939
|
-
model: string;
|
|
940
|
-
/**
|
|
941
|
-
* The object type, which was always `moderation_result` for successful moderation
|
|
942
|
-
* results.
|
|
943
|
-
*/
|
|
944
|
-
type: "moderation_result";
|
|
945
|
-
}
|
|
946
|
-
/**
|
|
947
|
-
* An error produced while attempting moderation for the response input or output.
|
|
948
|
-
*/
|
|
949
|
-
interface Error {
|
|
950
|
-
/**
|
|
951
|
-
* The error code.
|
|
952
|
-
*/
|
|
953
|
-
code: string;
|
|
954
|
-
/**
|
|
955
|
-
* The error message.
|
|
956
|
-
*/
|
|
957
|
-
message: string;
|
|
958
|
-
/**
|
|
959
|
-
* The object type, which was always `error` for moderation failures.
|
|
960
|
-
*/
|
|
961
|
-
type: "error";
|
|
962
|
-
}
|
|
963
909
|
}
|
|
964
910
|
}
|
|
965
911
|
/**
|
|
@@ -16,9 +16,9 @@ export interface OpenAIResponsesOptions extends StreamOptions {
|
|
|
16
16
|
/**
|
|
17
17
|
* Stateful turns: chain via `previous_response_id` + delta input instead of
|
|
18
18
|
* replaying the full transcript. Forces `store: true` (the platform only
|
|
19
|
-
* resolves stored responses).
|
|
20
|
-
*
|
|
21
|
-
*
|
|
19
|
+
* resolves stored responses). Precedence: this option, then
|
|
20
|
+
* `PI_OPENAI_STATEFUL`, then `compat.statefulResponses`, then ON against the
|
|
21
|
+
* official OpenAI API and OFF elsewhere. Requires `sessionId` +
|
|
22
22
|
* `providerSessionState`. Falls back to a full replay whenever history
|
|
23
23
|
* mutates or the server reports a stale id.
|
|
24
24
|
*/
|
|
@@ -60,6 +60,27 @@ export interface OpenAIResponsesOptions extends StreamOptions {
|
|
|
60
60
|
/** Opt-in GPT-5.6+ prompt-cache policy. Unsupported explicit mode fails locally. */
|
|
61
61
|
promptCache?: OpenAIPromptCacheOptions;
|
|
62
62
|
}
|
|
63
|
+
/**
|
|
64
|
+
* Poll a stored Responses result until it reaches an adoptable terminal state.
|
|
65
|
+
* 404s, 5xx, and transport failures mean "not yet" (an in-flight run only
|
|
66
|
+
* becomes retrievable once the server finishes it); any other status, a
|
|
67
|
+
* mismatched id, or a failed/cancelled run ends the poll immediately. The
|
|
68
|
+
* whole recovery is bounded by one wall-clock deadline: each request's timeout
|
|
69
|
+
* is clamped to the time left, and no sleep may cross the deadline, so a
|
|
70
|
+
* stalled host cannot hold an already-failed turn past it. Returns the
|
|
71
|
+
* terminal object, or undefined on give-up/abort.
|
|
72
|
+
*
|
|
73
|
+
* @internal Exported for tests.
|
|
74
|
+
*/
|
|
75
|
+
export declare function pollOpenAIResponsesResultForCompletion(args: {
|
|
76
|
+
fetchImpl: NonNullable<StreamOptions["fetch"]>;
|
|
77
|
+
url: string;
|
|
78
|
+
headers: Record<string, string>;
|
|
79
|
+
responseId: string;
|
|
80
|
+
signal?: AbortSignal;
|
|
81
|
+
/** Sleep between polls; defaults to a real wait honoring `signal`. */
|
|
82
|
+
wait?: (ms: number, signal?: AbortSignal) => Promise<void>;
|
|
83
|
+
}): Promise<Record<string, unknown> | undefined>;
|
|
63
84
|
interface OpenAIResponsesProviderSessionState extends ProviderSessionState, OpenAIStrictToolsState, OpenAIReasoningEffortFallbackState {
|
|
64
85
|
nativeHistoryReplayWarmed: boolean;
|
|
65
86
|
/** Stateful `previous_response_id` chain baselines, keyed by baseUrl/model/session. */
|
|
@@ -85,6 +106,14 @@ interface OpenAIResponsesChainState {
|
|
|
85
106
|
/** Set once chaining is judged unsupported for this session (circuit breaker). */
|
|
86
107
|
disabled: boolean;
|
|
87
108
|
}
|
|
109
|
+
/**
|
|
110
|
+
* Set the process-wide storage default per provider id, used when a request
|
|
111
|
+
* leaves `storeResponses` unset. Hosts call this from their settings so every
|
|
112
|
+
* request follows the setting, including direct `streamSimple`/`completeSimple`
|
|
113
|
+
* side calls that do not pass per-request options. `PI_MUSE_STORE_RESPONSES`
|
|
114
|
+
* still overrides it.
|
|
115
|
+
*/
|
|
116
|
+
export declare function configureProviderStoreResponses(byProvider: Readonly<Record<string, boolean>> | undefined): void;
|
|
88
117
|
/**
|
|
89
118
|
* Drop the account-bound half of every retained `openai-responses` record in
|
|
90
119
|
* `states`: the stateful `previous_response_id` chain baselines.
|
|
@@ -76,8 +76,11 @@ export declare function applyOpenAIServiceTier(params: {
|
|
|
76
76
|
* resolved request tier. Scoped to `provider: "openai"` (the only standard
|
|
77
77
|
* Responses biller) so an echoed `service_tier` from an Azure/OpenRouter/Copilot
|
|
78
78
|
* proxy can never skew those costs.
|
|
79
|
+
*
|
|
80
|
+
* Returns the tier the turn ran on for the caller to record on the message, and
|
|
81
|
+
* counts the premium request the tier bills.
|
|
79
82
|
*/
|
|
80
|
-
export declare function applyOpenAIResponsesServiceTierCost(model: Pick<Model, "provider" | "serviceTierCost">, usage: AssistantMessage["usage"], responseServiceTier: unknown, requestServiceTier: ServiceTier | null | undefined):
|
|
83
|
+
export declare function applyOpenAIResponsesServiceTierCost(model: Pick<Model, "provider" | "serviceTierCost" | "api" | "identity">, usage: AssistantMessage["usage"], responseServiceTier: unknown, requestServiceTier: ServiceTier | null | undefined): ServiceTier | undefined;
|
|
81
84
|
/**
|
|
82
85
|
* Reconcile token-price estimates with a gateway's authoritative account charge.
|
|
83
86
|
* BYOK turns (`is_byok: true`) price from the provider spend in
|
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import type { FetchImpl } from "../../types.js";
|
|
1
2
|
import type { OAuthController, OAuthCredentials } from "./types.js";
|
|
2
3
|
export interface CursorAuthParams {
|
|
3
4
|
verifier: string;
|
|
@@ -13,6 +14,13 @@ export declare function pollCursorAuth(uuid: string, verifier: string): Promise<
|
|
|
13
14
|
export declare function loginCursor(onAuthUrl: (url: string) => void, onPollStart?: () => void): Promise<OAuthCredentials>;
|
|
14
15
|
export declare function loginCursorHook(callbacks: OAuthController): Promise<OAuthCredentials>;
|
|
15
16
|
export declare function refreshCursorToken(apiKeyOrRefreshToken: string): Promise<OAuthCredentials>;
|
|
16
|
-
export declare function refreshCursorHook(credentials: OAuthCredentials): Promise<OAuthCredentials>;
|
|
17
|
+
export declare function refreshCursorHook(credentials: OAuthCredentials, signal?: AbortSignal): Promise<OAuthCredentials>;
|
|
18
|
+
/** Request headers that present `accessToken` to cursor.com as its user's web session. */
|
|
19
|
+
export declare function cursorSessionHeaders(userId: string, accessToken: string): Record<string, string>;
|
|
20
|
+
/**
|
|
21
|
+
* Email of the Cursor account that owns `accessToken`, read from its cursor.com
|
|
22
|
+
* profile. Undefined when the token names no user or the profile names another.
|
|
23
|
+
*/
|
|
24
|
+
export declare function fetchCursorAccountEmail(accessToken: string, fetchImpl?: FetchImpl, signal?: AbortSignal): Promise<string | undefined>;
|
|
17
25
|
export declare function extractCursorAccessTokenUserId(accessToken: string): string | undefined;
|
|
18
26
|
export declare function isCursorTokenExpiringSoon(token: string, thresholdSeconds?: number): boolean;
|
|
@@ -43,3 +43,5 @@ export declare function getOAuthApiKey(provider: OAuthProvider, credentials: Rec
|
|
|
43
43
|
* Get list of OAuth providers.
|
|
44
44
|
*/
|
|
45
45
|
export declare function getOAuthProviders(): OAuthProviderInfo[];
|
|
46
|
+
/** Provider id that stores `providerId`'s credentials: login aliases (`openai-codex-device`) map to their target (`openai-codex`). */
|
|
47
|
+
export declare function getOAuthCredentialProvider(providerId: string): string;
|
|
@@ -0,0 +1,3 @@
|
|
|
1
|
+
import type { OAuthController, OAuthCredentials } from "./types.js";
|
|
2
|
+
export declare function loginSnowflake(ctrl: OAuthController): Promise<OAuthCredentials>;
|
|
3
|
+
export declare function refreshSnowflakeToken(credentials: OAuthCredentials, signal?: AbortSignal): Promise<OAuthCredentials>;
|
|
@@ -0,0 +1,4 @@
|
|
|
1
|
+
import type { ProviderTransport } from "./build.js";
|
|
2
|
+
/** Normalize account identifiers and Snowsight links without accepting arbitrary credential-receiving hosts. */
|
|
3
|
+
export declare function normalizeSnowflakeAccountUrl(input: string): string;
|
|
4
|
+
export declare const snowflakeTransport: ProviderTransport;
|
package/dist/types/types.d.ts
CHANGED
|
@@ -157,18 +157,31 @@ export declare function shouldSendServiceTier(serviceTier: ServiceTier | null |
|
|
|
157
157
|
*/
|
|
158
158
|
export declare function realizesPriorityServiceTier(serviceTier: ServiceTier | null | undefined, model: ServiceTierModel): boolean;
|
|
159
159
|
/**
|
|
160
|
-
* Premium-request weight contributed by a
|
|
161
|
-
*
|
|
162
|
-
*
|
|
163
|
-
*
|
|
160
|
+
* Premium-request weight contributed by a request a provider bills above
|
|
161
|
+
* standard. Priority (Fast mode) counts 1 on every provider that realizes it;
|
|
162
|
+
* `ultrafast` counts 1 on the OpenAI family, where it is a premium serving tier
|
|
163
|
+
* (its cost premium is recorded separately in `usage.cost`). Mirrors GitHub
|
|
164
|
+
* Copilot's `premiumRequests` accounting so the "premium requests" stat
|
|
165
|
+
* aggregates premium traffic across the OpenAI family, direct Anthropic fast
|
|
166
|
+
* mode, and Google priority.
|
|
164
167
|
*
|
|
165
|
-
* Returns 1 only when
|
|
166
|
-
* (see {@link realizesPriorityServiceTier}
|
|
167
|
-
* premium request. OpenRouter is excluded — it
|
|
168
|
-
* Copilot-premium semantics — as are
|
|
169
|
-
* silently dropped.
|
|
168
|
+
* Returns 1 only when the tier is actually realized on the wire for `model`
|
|
169
|
+
* (see {@link realizesPriorityServiceTier} and {@link shouldSendServiceTier})
|
|
170
|
+
* and the provider bills it as a premium request. OpenRouter is excluded — it
|
|
171
|
+
* bills per its own pricing, not Copilot-premium semantics — as are
|
|
172
|
+
* Bedrock/Vertex Claude, where priority is silently dropped.
|
|
173
|
+
*
|
|
174
|
+
* Pass `served: true` when the tier is the one the provider reported serving
|
|
175
|
+
* (an assistant message's {@link AssistantMessage.serviceTier}) rather than a
|
|
176
|
+
* requested setting: realization is then already proven, so the wire gate is
|
|
177
|
+
* skipped and a model without discovery metadata (a stats-backfill row) still
|
|
178
|
+
* counts.
|
|
170
179
|
*/
|
|
171
|
-
export declare function
|
|
180
|
+
export declare function getPremiumServiceTierRequests(serviceTier: ServiceTier | null | undefined, model: ServiceTierModel, options?: {
|
|
181
|
+
served?: boolean;
|
|
182
|
+
}): number;
|
|
183
|
+
/** Parse a provider-reported `service_tier` echo into a known tier, or `undefined` for anything else. */
|
|
184
|
+
export declare function parseServiceTier(value: unknown): ServiceTier | undefined;
|
|
172
185
|
/**
|
|
173
186
|
* Coerce a persisted service-tier value to a {@link ServiceTierByFamily}. Newer
|
|
174
187
|
* sessions store the family map directly; legacy sessions stored a single
|
|
@@ -215,6 +228,11 @@ export interface CodexCompactionRequestContext extends CodexCompactionMetadata {
|
|
|
215
228
|
export interface AnthropicCompactionRequest {
|
|
216
229
|
/** Custom summarization prompt; replaces the API default entirely when set. */
|
|
217
230
|
instructions?: string;
|
|
231
|
+
/**
|
|
232
|
+
* Replayed summaries' file metadata due before this time (ms) ends the request;
|
|
233
|
+
* later metadata replays with the retained tail, which the new summary carries.
|
|
234
|
+
*/
|
|
235
|
+
filesDueBefore?: number;
|
|
218
236
|
}
|
|
219
237
|
/** OpenAI's GPT-5.6+ explicit prompt-cache controls. */
|
|
220
238
|
export interface OpenAIPromptCacheOptions {
|
|
@@ -333,6 +351,16 @@ export interface StreamOptions {
|
|
|
333
351
|
* `false` so `previous_response_id` cannot explain a result.
|
|
334
352
|
*/
|
|
335
353
|
statefulResponses?: boolean;
|
|
354
|
+
/**
|
|
355
|
+
* Store this request's result server-side on hosts that support it
|
|
356
|
+
* (`compat.storeResponses`, e.g. Muse Code), so a stream that drops
|
|
357
|
+
* mid-turn resumes from `GET /responses/{id}` instead of re-running the
|
|
358
|
+
* turn. Privacy: stored runs retain prompts and outputs on the provider.
|
|
359
|
+
* Unset falls back to `PI_MUSE_STORE_RESPONSES`, then the host's
|
|
360
|
+
* `configureProviderStoreResponses` default, else off. Ignored on hosts
|
|
361
|
+
* without the capability.
|
|
362
|
+
*/
|
|
363
|
+
storeResponses?: boolean;
|
|
336
364
|
/**
|
|
337
365
|
* Disable native reasoning when the caller supplies an external scratchpad.
|
|
338
366
|
* OpenAI Responses emits `reasoning: { effort: "none" }`; Anthropic and
|
|
@@ -363,6 +391,8 @@ export interface StreamOptions {
|
|
|
363
391
|
* are not covered.
|
|
364
392
|
*/
|
|
365
393
|
maxInFlightRequests?: Record<string, number>;
|
|
394
|
+
/** @internal Keep the in-flight permit until a provider's bounded terminal drain finishes. */
|
|
395
|
+
waitForTerminalDrain?: boolean;
|
|
366
396
|
/**
|
|
367
397
|
* Optional callback for inspecting or replacing provider payloads before sending.
|
|
368
398
|
* Return undefined to keep the payload unchanged.
|
|
@@ -820,11 +850,31 @@ export interface AnthropicCompactionPayload {
|
|
|
820
850
|
encryptedContent?: string;
|
|
821
851
|
/**
|
|
822
852
|
* Harness-appended file metadata (`<files>` section) kept out of the
|
|
823
|
-
* byte-identical block.
|
|
824
|
-
*
|
|
825
|
-
*
|
|
853
|
+
* byte-identical block. The converter replaces the summary message with the
|
|
854
|
+
* block and skips its text, so it replays this as a user message after the
|
|
855
|
+
* block's retained tail: before the first message created after the summary.
|
|
826
856
|
*/
|
|
827
857
|
filesText?: string;
|
|
858
|
+
/**
|
|
859
|
+
* File metadata of earlier summaries whose replay position lies inside this
|
|
860
|
+
* summary's retained tail. Retained messages must reach the API unchanged,
|
|
861
|
+
* so each keeps replaying where it did: before the first message created
|
|
862
|
+
* after `after` (the earlier summary's commit time).
|
|
863
|
+
*/
|
|
864
|
+
retainedFiles?: AnthropicCompactionFiles[];
|
|
865
|
+
/**
|
|
866
|
+
* Set on summaries whose retained tail replays unchanged: file metadata
|
|
867
|
+
* after the tail, earlier metadata at `retainedFiles`. Summaries persisted
|
|
868
|
+
* without it keep their original layout (metadata after the first retained
|
|
869
|
+
* turn), since later thinking was signed against those bytes.
|
|
870
|
+
*/
|
|
871
|
+
exactTail?: true;
|
|
872
|
+
}
|
|
873
|
+
/** File metadata replayed at a fixed point of a natively compacted conversation. */
|
|
874
|
+
export interface AnthropicCompactionFiles {
|
|
875
|
+
text: string;
|
|
876
|
+
/** Replays before the first message created after this time (ms). */
|
|
877
|
+
after: number;
|
|
828
878
|
}
|
|
829
879
|
export type ProviderPayload = OpenAIResponsesHistoryPayload | AnthropicMessagePayload | AnthropicCompactionPayload;
|
|
830
880
|
/** Provider-reported rewrite applied to request content before inference. */
|
|
@@ -928,6 +978,15 @@ export interface AssistantMessage {
|
|
|
928
978
|
* other than what was requested.
|
|
929
979
|
*/
|
|
930
980
|
upstreamModel?: string;
|
|
981
|
+
/**
|
|
982
|
+
* Service tier the provider reported serving this turn, when the API echoes
|
|
983
|
+
* one (`response.service_tier`), falling back to the tier the request carried
|
|
984
|
+
* when the response omits the echo. Absent when the provider reports no tier
|
|
985
|
+
* or the echo cannot be trusted (proxies). This is the tier the turn actually
|
|
986
|
+
* ran on, which is what cost, premium-request, and speed accounting key on —
|
|
987
|
+
* the session's live setting may already have changed.
|
|
988
|
+
*/
|
|
989
|
+
serviceTier?: ServiceTier;
|
|
931
990
|
usage: Usage;
|
|
932
991
|
stopReason: StopReason;
|
|
933
992
|
stopDetails?: StopDetails | null;
|
|
@@ -138,6 +138,12 @@ export interface TerminalGraceIteratorOptions {
|
|
|
138
138
|
* the transport until that pending read settles.
|
|
139
139
|
*/
|
|
140
140
|
onGraceEnd?: () => void;
|
|
141
|
+
/**
|
|
142
|
+
* Wait for the bounded drain when the consumer returns early. Capped
|
|
143
|
+
* requests must not release their in-flight permit while the transport
|
|
144
|
+
* still owns a live connection.
|
|
145
|
+
*/
|
|
146
|
+
awaitDrainOnReturn?: boolean;
|
|
141
147
|
}
|
|
142
148
|
/**
|
|
143
149
|
* Yields items from an async iterable until the consumer marks the stream
|
|
@@ -148,5 +154,10 @@ export interface TerminalGraceIteratorOptions {
|
|
|
148
154
|
* hangs on `iterator.next()` until the idle watchdog converts an
|
|
149
155
|
* already-successful turn into a timeout error. Grace expiry is a clean end
|
|
150
156
|
* of iteration, never an error.
|
|
157
|
+
*
|
|
158
|
+
* A consumer that stops early (`break`) after `finishedAtMs()` is set leaves
|
|
159
|
+
* the source draining until `[DONE]`/EOF or the same grace deadline. Without
|
|
160
|
+
* `awaitDrainOnReturn`, the consumer is not held up; capped requests await
|
|
161
|
+
* the drain before completing and releasing their in-flight permit.
|
|
151
162
|
*/
|
|
152
163
|
export declare function iterateWithTerminalGrace<T>(iterable: AsyncIterable<T>, options: TerminalGraceIteratorOptions): AsyncGenerator<T>;
|