@oh-my-pi/pi-ai 15.3.1 → 15.4.1
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 +89 -0
- package/dist/types/auth-broker/client.d.ts +21 -1
- package/dist/types/auth-broker/remote-store.d.ts +6 -1
- package/dist/types/auth-broker/server.d.ts +6 -0
- package/dist/types/auth-broker/types.d.ts +36 -0
- package/dist/types/auth-broker/wire-schemas.d.ts +148 -0
- package/dist/types/auth-gateway/types.d.ts +1 -1
- package/dist/types/auth-storage.d.ts +96 -0
- package/dist/types/index.d.ts +0 -1
- package/dist/types/providers/amazon-bedrock.d.ts +16 -0
- package/dist/types/providers/cursor.d.ts +7 -1
- package/dist/types/providers/mock.d.ts +0 -2
- package/dist/types/providers/openai-responses-shared.d.ts +26 -0
- package/dist/types/types.d.ts +31 -8
- package/dist/types/utils/abortable-iterator.d.ts +4 -0
- package/dist/types/utils/anthropic-auth.d.ts +11 -24
- package/dist/types/utils/idle-iterator.d.ts +11 -9
- package/dist/types/utils/oauth/index.d.ts +8 -5
- package/dist/types/utils/sdk-stream-timeout.d.ts +33 -0
- package/package.json +2 -2
- package/src/auth-broker/client.ts +97 -0
- package/src/auth-broker/remote-store.ts +145 -20
- package/src/auth-broker/server.ts +191 -1
- package/src/auth-broker/types.ts +43 -0
- package/src/auth-broker/wire-schemas.ts +38 -0
- package/src/auth-gateway/server.ts +27 -1
- package/src/auth-gateway/types.ts +1 -1
- package/src/auth-storage.ts +353 -32
- package/src/index.ts +0 -1
- package/src/providers/amazon-bedrock.ts +80 -24
- package/src/providers/anthropic.ts +55 -18
- package/src/providers/azure-openai-responses.ts +33 -10
- package/src/providers/cursor.ts +149 -28
- package/src/providers/google-gemini-cli.ts +17 -36
- package/src/providers/mock.ts +0 -4
- package/src/providers/openai-codex-responses.ts +173 -79
- package/src/providers/openai-completions-compat.ts +7 -1
- package/src/providers/openai-completions.ts +33 -37
- package/src/providers/openai-responses-shared.ts +95 -0
- package/src/providers/openai-responses.ts +51 -47
- package/src/providers/pi-native-server.ts +1 -0
- package/src/providers/register-builtins.ts +61 -8
- package/src/providers/transform-messages.ts +25 -0
- package/src/stream.ts +6 -2
- package/src/types.ts +31 -8
- package/src/usage/gemini.ts +15 -13
- package/src/usage/google-antigravity.ts +13 -12
- package/src/usage/kimi.ts +9 -14
- package/src/utils/abortable-iterator.ts +69 -0
- package/src/utils/anthropic-auth.ts +22 -143
- package/src/utils/idle-iterator.ts +26 -31
- package/src/utils/oauth/index.ts +23 -17
- package/src/utils/oauth/moonshot.ts +11 -4
- package/src/utils/sdk-stream-timeout.ts +43 -0
- package/dist/types/utils/h2-fetch.d.ts +0 -22
- package/src/utils/h2-fetch.ts +0 -60
package/CHANGELOG.md
CHANGED
|
@@ -2,12 +2,101 @@
|
|
|
2
2
|
|
|
3
3
|
## [Unreleased]
|
|
4
4
|
|
|
5
|
+
## [15.4.1] - 2026-05-26
|
|
6
|
+
### Added
|
|
7
|
+
|
|
8
|
+
- Added `isOpenAICompletionsProgressChunk` export to identify real progress chunks vs. keepalives in OpenAI completions streams
|
|
9
|
+
- Added per-provider stream watchdog overrides via `getStreamIdleTimeoutMs(fallbackMs)` and `getStreamFirstEventTimeoutMs(idleTimeoutMs, fallbackMs)` to allow providers like Google Gemini CLI to extend first-event timeouts without affecting global defaults
|
|
10
|
+
- Added `promptCacheKey` to `StreamOptions` and passed it through stream option mapping so callers can specify an explicit prompt-cache key separate from `sessionId`
|
|
11
|
+
- Added `promptCacheKey` support to the native server option whitelist so `promptCacheKey` is accepted by `pi-native-server` streams
|
|
12
|
+
- Restored the per-provider stream watchdog (`iterateWithIdleTimeout`) on top of the abortable iterator. The lazy stream forwarder in `register-builtins` now wraps every provider's event stream with the first-event + steady-state idle watchdog (`PI_STREAM_FIRST_EVENT_TIMEOUT_MS`, `PI_STREAM_IDLE_TIMEOUT_MS`; aliases honored), and Anthropic / OpenAI Completions / OpenAI Responses / Azure OpenAI Responses / Codex SSE re-emit their per-provider progress predicates so empty keepalive frames cannot keep a stalled stream alive. Reverts the partial regression from #1392 that left Codex WebSocket subagent runs hanging silently for hours when the broker dropped frames between deltas. The Codex WebSocket transport additionally now resets `lastProgressAt` only on progress events (not keepalives), giving the 300s WS-internal idle ceiling the same liveness semantics as the SSE path.
|
|
13
|
+
|
|
14
|
+
### Changed
|
|
15
|
+
|
|
16
|
+
- Enabled OpenAI Codex WebSocket streams to apply `streamIdleTimeoutMs` and `streamFirstEventTimeoutMs` from `StreamOptions` per request instead of fixed internal defaults
|
|
17
|
+
- Changed stream idle watchdog implementation from `iterateUntilAbort` to `iterateWithIdleTimeout`, which now enforces maximum idle gaps between streamed events and distinguishes between first-event and steady-state timeouts
|
|
18
|
+
- Changed Anthropic, OpenAI Responses, OpenAI Completions, Azure OpenAI Responses, and OpenAI Codex Responses providers to use the new idle-timeout iterator with per-provider progress predicates so empty keepalive frames cannot keep a stalled stream alive
|
|
19
|
+
- Changed Codex WebSocket transport to reset `lastProgressAt` only on progress events (not keepalives), giving the 300s WS-internal idle ceiling the same liveness semantics as the SSE path
|
|
20
|
+
- Changed Google Gemini CLI stream forwarding defaults to use a 5-minute first-event floor via per-provider lazy-stream limits to avoid premature first-event timeouts on slow startup
|
|
21
|
+
- Changed OpenAI Responses and OpenAI Codex request handling to keep `sessionId` for provider routing and conversation headers while `promptCacheKey` controls the `prompt_cache_key` payload independently
|
|
22
|
+
- Changed `StreamOptions.streamIdleTimeoutMs` documentation to clarify it is now wired into every built-in provider and the lazy stream forwarder, and that `streamFirstEventTimeoutMs` is honored at both the SDK-request layer and the iterator-watchdog layer
|
|
23
|
+
- Changed OpenAI Responses and OpenAI Codex request handling so `sessionId` continues to drive provider routing and state while `promptCacheKey` controls the `prompt_cache_key` payload
|
|
24
|
+
- Changed Google Gemini CLI stream forwarding defaults to use a 5-minute first-event floor to avoid premature first-event timeouts on slow startup
|
|
25
|
+
- Changed auth-gateway request mapping to preserve incoming `prompt_cache_key` as both `promptCacheKey` and `sessionId` when routing OpenAI-compatible sessions
|
|
26
|
+
- Un-deprecated `StreamOptions.streamIdleTimeoutMs`; the option is wired into every built-in provider and the lazy stream forwarder again. `streamFirstEventTimeoutMs` is now honored at both the SDK-request layer (via `createSdkStreamRequestOptions`) and the iterator-watchdog layer, in cooperation.
|
|
27
|
+
|
|
28
|
+
### Removed
|
|
29
|
+
|
|
30
|
+
- Removed `installH2Fetch` and the `fetch` patch that forced HTTP/2 on HTTPS requests; callers now use the default Bun `fetch` transport
|
|
31
|
+
|
|
32
|
+
### Fixed
|
|
33
|
+
|
|
34
|
+
- Fixed first-item timeout handling so `iterateWithIdleTimeout` no longer keeps first-event timers active after the source throws or the consumer stops before semantic progress
|
|
35
|
+
- Fixed silent multi-hour hangs on Codex WebSocket subagent runs when the broker dropped frames between deltas by restoring per-provider stream watchdogs with progress-event filtering
|
|
36
|
+
- Fixed z.ai/GLM-via-OpenRouter subagent stalls where no-op keepalive chunks reset the idle watchdog indefinitely by filtering non-progress items before resetting the deadline
|
|
37
|
+
|
|
38
|
+
## [15.4.0] - 2026-05-26
|
|
39
|
+
### Breaking Changes
|
|
40
|
+
|
|
41
|
+
- Removed `findAnthropicAuth` from `anthropic-auth` and replaced store-driven auth discovery with `buildAnthropicAuthConfig`, requiring callers to provide an already-resolved API key before building Anthropic auth config
|
|
42
|
+
|
|
43
|
+
### Added
|
|
44
|
+
|
|
45
|
+
- Added `PI_CODEX_WEBSOCKET_FIRST_EVENT_TIMEOUT_MS` and `PI_CODEX_WEBSOCKET_IDLE_TIMEOUT_MS` options to tune Codex WebSocket timeout behavior before fallback
|
|
46
|
+
- Added `AuthStorage.getOAuthAccess` to return a refreshed OAuth access token with identity metadata (`accountId`, `email`, `projectId`, `enterpriseUrl`) for callers that need bearer-token headers together
|
|
47
|
+
- Added Codex WebSocket forwarding to the `onSseEvent` observer so the raw provider-stream debug viewer captures the inbound JSON frames and the outbound request frame from the WS transport using the same synthesized SSE-wire shape (`event:` + `data:` lines, prefixed with a `: ws ← <type>` (inbound) or `: ws → <type>` (outbound) comment).
|
|
48
|
+
|
|
49
|
+
### Changed
|
|
50
|
+
|
|
51
|
+
- Changed OAuth selection in `AuthStorage` to treat credentials as stale when they are within 60 seconds of expiry and rotate them preemptively
|
|
52
|
+
- Changed Google Gemini CLI, Google Gemini usage, Antigravity usage, and Kimi usage flows to stop refreshing OAuth tokens directly and rely on `AuthStorage` for token rotation
|
|
53
|
+
|
|
54
|
+
### Deprecated
|
|
55
|
+
|
|
56
|
+
- Deprecated `streamIdleTimeoutMs` in `StreamOptions` as a compatibility-only field that is no longer used by providers
|
|
57
|
+
|
|
58
|
+
### Removed
|
|
59
|
+
|
|
60
|
+
- Removed provider-local OAuth refresh helpers from Google Gemini CLI and Google/Kimi/Antigravity usage probes, preventing direct refresh calls from those usage paths
|
|
61
|
+
|
|
62
|
+
### Fixed
|
|
63
|
+
|
|
64
|
+
- Dropped truncated, thinking-only assistant turns with only `thinking`/`redacted_thinking` blocks and no `text` or `tool` content during message transformation, preventing Anthropic requests from sending consecutive assistant messages after a `max_tokens`/`error`/`aborted` interruption
|
|
65
|
+
- Fixed Amazon Bedrock bearer-token authentication to honor `AWS_BEARER_TOKEN_BEDROCK` before resolving AWS profiles or running `credential_process`, matching Bedrock API-key precedence. ([#1399](https://github.com/can1357/oh-my-pi/issues/1399))
|
|
66
|
+
- Updated `isRetryableError` to treat Bun HTTP/2 transport errors (`HTTP2StreamReset`, `HTTP2RefusedStream`) as retryable so transient stream-reset failures can be retried
|
|
67
|
+
- Fixed Codex WebSocket streaming to recover from stalled sessions by falling back to SSE when the first event or subsequent progress is delayed beyond the configured websocket timeout
|
|
68
|
+
- Fixed expired OAuth handling so provider-level paths no longer attempt direct token refresh calls for expired credentials and instead rely on `AuthStorage` for rotation
|
|
69
|
+
- Fixed provider streams aborting slow-but-valid first tokens or silent inter-event gaps with OMP-owned first-event/idle watchdog errors. Built-in lazy streams, OpenAI/Anthropic/Azure/Codex SSE, and Codex WebSocket streams now wait for provider output, provider/socket errors, caller aborts, or explicit request-layer timeouts instead of treating provider silence as failure ([#1392](https://github.com/can1357/oh-my-pi/issues/1392)).
|
|
70
|
+
- Fixed Claude Opus 4.7 on Amazon Bedrock streaming no reasoning output (and appearing to hang on long reasoning runs) because Anthropic silently switched the adaptive-thinking display default to `"omitted"`. The Bedrock provider now sends `thinking.display = "summarized"` by default on Opus 4.7+ adaptive models and on budget-based Claude models, mirroring the existing direct-Anthropic behavior. `BedrockOptions.thinkingDisplay` (`"summarized" | "omitted"`) is exposed for callers that want to opt out, and `hideThinkingSummary` now wires through to the Bedrock case ([#1373](https://github.com/can1357/oh-my-pi/issues/1373)).
|
|
71
|
+
- Fixed Cursor Composer resume/tool-continuation turns failing with `Cannot send empty user message to Cursor API`. Empty current user turns now use Cursor's `resumeAction` instead of constructing an invalid `userMessageAction` ([#1376](https://github.com/can1357/oh-my-pi/issues/1376)).
|
|
72
|
+
- Fixed `pi-ai login moonshot` failing with `invalid temperature: only 1 is allowed for this model` (HTTP 400) because the API-key validator probed `kimi-k2.5` with `temperature: 0`. Moonshot login now validates against `GET /v1/models`, matching the DeepSeek/Fireworks/NanoGPT/ZenMux pattern and authenticating the key without invoking model-specific parameter restrictions.
|
|
73
|
+
|
|
74
|
+
## [15.3.2] - 2026-05-25
|
|
75
|
+
### Added
|
|
76
|
+
|
|
77
|
+
- Added `GET /v1/snapshot/stream` for live auth-broker snapshot updates via SSE with `snapshot`, `entry`, and `removed` event frames
|
|
78
|
+
- Added `AuthBrokerClient.openSnapshotStream()` for consuming SSE snapshot streams from `/v1/snapshot/stream`
|
|
79
|
+
- Added `streamSnapshots` option to `RemoteAuthCredentialStore` (default `true`) to enable or disable SSE-based snapshot synchronization
|
|
80
|
+
- Added `streamKeepaliveMs` to `startAuthBroker()` to tune heartbeat frequency for the SSE stream
|
|
81
|
+
- Added `AuthStorage.checkCredentials({ signal?, timeoutMs?, baseUrlResolver? })` that returns a per-credential `CredentialHealthResult` with tri-state `ok` (`true` / `false` / `null`-unverifiable), the credential's identity (provider, type, email/accountId, broker-refresh flag), and the upstream error string when the probe fails. Iterates sequentially over `listAuthCredentials()`, exercises OAuth refresh on expiry, then calls the per-provider `UsageProvider.fetchUsage` without swallowing errors — so callers can identify which row in a multi-account broker is producing 401s instead of getting a silently-deduplicated `fetchUsageReports` list.
|
|
82
|
+
- Added `GET /v1/credentials/check` to `startAuthGateway()` that forwards to `AuthStorage.checkCredentials` and returns `{ generatedAt, credentials }`. Gated by the same bearer as the rest of the gateway.
|
|
83
|
+
|
|
84
|
+
### Changed
|
|
85
|
+
|
|
86
|
+
- Changed `RemoteAuthCredentialStore` to prefer SSE snapshot streaming and automatically fall back to long-polling when a broker returns 404 for `/v1/snapshot/stream`
|
|
87
|
+
- Changed snapshot write-refresh flow so `RemoteAuthCredentialStore` skips immediate `/v1/snapshot` refreshes when SSE streaming is active
|
|
88
|
+
- Changed broker SSE stream behavior to keep connections open with periodic keepalives and an increased server idle timeout
|
|
89
|
+
|
|
5
90
|
## [15.3.0] - 2026-05-25
|
|
6
91
|
|
|
7
92
|
### Added
|
|
8
93
|
|
|
9
94
|
- Added DeepSeek to the built-in API-key login provider catalog so `omp login deepseek` stores a reusable `DEEPSEEK_API_KEY` credential for the bundled DeepSeek models.
|
|
10
95
|
|
|
96
|
+
### Fixed
|
|
97
|
+
|
|
98
|
+
- Fixed `openai-responses` requests intermittently 400ing with `No tool call found for function call output with call_id …` after an aborted turn or a locally-rejected tool call (e.g. argument-validation failure). `convertConversationMessages` now folds orphan `function_call_output` / `custom_tool_call_output` items — those whose matching `function_call` was wiped by an earlier `dt: false` snapshot splice or never landed in any persisted provider payload — into assistant text notes, preserving the payload while keeping the request grammatically valid ([#1351](https://github.com/can1357/oh-my-pi/issues/1351)).
|
|
99
|
+
|
|
11
100
|
## [15.2.4] - 2026-05-22
|
|
12
101
|
|
|
13
102
|
### Fixed
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import type { AuthCredential } from "../auth-storage";
|
|
2
|
-
import type { CredentialDisableResponse, CredentialRefreshResponse, CredentialUploadResponse, HealthzResponse, SnapshotResponse, UsageResponse } from "./types";
|
|
2
|
+
import type { CredentialDisableResponse, CredentialRefreshResponse, CredentialUploadResponse, HealthzResponse, SnapshotResponse, SnapshotStreamEvent, UsageResponse } from "./types";
|
|
3
3
|
export interface AuthBrokerClientOptions {
|
|
4
4
|
/** Base URL (e.g. `https://broker.tailnet:8765`). Trailing slashes are trimmed. */
|
|
5
5
|
url: string;
|
|
@@ -21,6 +21,14 @@ export declare class AuthBrokerError extends Error {
|
|
|
21
21
|
cause?: unknown;
|
|
22
22
|
});
|
|
23
23
|
}
|
|
24
|
+
/**
|
|
25
|
+
* Thrown when a broker responds 404 to `GET /v1/snapshot/stream` — old
|
|
26
|
+
* brokers that predate the SSE endpoint. Callers (`RemoteAuthCredentialStore`)
|
|
27
|
+
* detect this sentinel to fall back to long-polling permanently.
|
|
28
|
+
*/
|
|
29
|
+
export declare class AuthBrokerStreamUnsupportedError extends AuthBrokerError {
|
|
30
|
+
constructor(message?: string);
|
|
31
|
+
}
|
|
24
32
|
export interface FetchSnapshotOptions {
|
|
25
33
|
ifGenerationGt?: number;
|
|
26
34
|
waitMs?: number;
|
|
@@ -39,6 +47,18 @@ export declare class AuthBrokerClient {
|
|
|
39
47
|
constructor(opts: AuthBrokerClientOptions);
|
|
40
48
|
healthz(signal?: AbortSignal): Promise<HealthzResponse>;
|
|
41
49
|
fetchSnapshot(opts?: FetchSnapshotOptions): Promise<FetchSnapshotResult>;
|
|
50
|
+
/**
|
|
51
|
+
* Subscribe to the broker's SSE snapshot stream. The first frame is always
|
|
52
|
+
* a full `snapshot`; subsequent frames are `entry` upserts / refreshes or
|
|
53
|
+
* `removed` deletes. Caller controls lifecycle via `opts.signal`.
|
|
54
|
+
*
|
|
55
|
+
* Throws {@link AuthBrokerStreamUnsupportedError} when the broker responds
|
|
56
|
+
* 404 — older brokers predate this endpoint and the caller should fall back
|
|
57
|
+
* to long-polling for the remainder of its lifetime.
|
|
58
|
+
*/
|
|
59
|
+
openSnapshotStream(opts?: {
|
|
60
|
+
signal?: AbortSignal;
|
|
61
|
+
}): AsyncGenerator<SnapshotStreamEvent>;
|
|
42
62
|
fetchUsage(signal?: AbortSignal): Promise<UsageResponse>;
|
|
43
63
|
refreshCredential(id: number, signal?: AbortSignal): Promise<CredentialRefreshResponse>;
|
|
44
64
|
disableCredential(id: number, cause: string, signal?: AbortSignal): Promise<CredentialDisableResponse>;
|
|
@@ -2,7 +2,7 @@ import { type AuthCredential, type AuthCredentialStore, type OAuthCredential, ty
|
|
|
2
2
|
import type { Provider } from "../types";
|
|
3
3
|
import type { UsageReport } from "../usage";
|
|
4
4
|
import type { OAuthCredentials } from "../utils/oauth/types";
|
|
5
|
-
import type
|
|
5
|
+
import { type AuthBrokerClient } from "./client";
|
|
6
6
|
import type { SnapshotResponse } from "./types";
|
|
7
7
|
export interface RemoteAuthCredentialStoreOptions {
|
|
8
8
|
client: AuthBrokerClient;
|
|
@@ -11,6 +11,11 @@ export interface RemoteAuthCredentialStoreOptions {
|
|
|
11
11
|
* {@link RemoteAuthCredentialStore.refreshSnapshot} before the first read.
|
|
12
12
|
*/
|
|
13
13
|
initialSnapshot?: SnapshotResponse;
|
|
14
|
+
/**
|
|
15
|
+
* Subscribe to the broker's SSE snapshot stream when available. Falls back
|
|
16
|
+
* to long-poll permanently when the broker returns 404. Default `true`.
|
|
17
|
+
*/
|
|
18
|
+
streamSnapshots?: boolean;
|
|
14
19
|
}
|
|
15
20
|
export declare class RemoteAuthCredentialStore implements AuthCredentialStore {
|
|
16
21
|
#private;
|
|
@@ -14,6 +14,12 @@ export interface AuthBrokerServerOptions {
|
|
|
14
14
|
refreshIntervalMs?: number;
|
|
15
15
|
/** Disable the background refresher (e.g. for tests). */
|
|
16
16
|
disableRefresher?: boolean;
|
|
17
|
+
/**
|
|
18
|
+
* Override SSE keepalive cadence in milliseconds for `/v1/snapshot/stream`.
|
|
19
|
+
* Internal-only — tests use a short interval so they can assert heartbeats
|
|
20
|
+
* without long sleeps. Default {@link DEFAULT_STREAM_KEEPALIVE_MS}.
|
|
21
|
+
*/
|
|
22
|
+
streamKeepaliveMs?: number;
|
|
17
23
|
}
|
|
18
24
|
export interface AuthBrokerServerHandle {
|
|
19
25
|
/** Bound URL (`http://host:port`). */
|
|
@@ -56,6 +56,35 @@ export interface CredentialUploadRequest {
|
|
|
56
56
|
export interface CredentialUploadResponse {
|
|
57
57
|
entries: AuthCredentialSnapshotEntry[];
|
|
58
58
|
}
|
|
59
|
+
/**
|
|
60
|
+
* SSE event kinds emitted on `GET /v1/snapshot/stream`. The same value is set
|
|
61
|
+
* as the SSE `event:` name (load-bearing for clients) **and** embedded as a
|
|
62
|
+
* `kind` field inside the JSON body so a Zod discriminated union can validate
|
|
63
|
+
* the payload without consulting the line metadata.
|
|
64
|
+
*/
|
|
65
|
+
export type SnapshotStreamEventKind = "snapshot" | "entry" | "removed";
|
|
66
|
+
/** Initial frame emitted on connect — the full {@link SnapshotResponse}. */
|
|
67
|
+
export interface SnapshotStreamSnapshotEvent extends SnapshotResponse {
|
|
68
|
+
kind: "snapshot";
|
|
69
|
+
}
|
|
70
|
+
/** Single credential added/changed (upsert or refresh). */
|
|
71
|
+
export interface SnapshotStreamEntryEvent {
|
|
72
|
+
kind: "entry";
|
|
73
|
+
generation: number;
|
|
74
|
+
serverNowMs: number;
|
|
75
|
+
refresher: RefresherSchedule;
|
|
76
|
+
entry: SnapshotEntry;
|
|
77
|
+
}
|
|
78
|
+
/** Single credential disabled/deleted. */
|
|
79
|
+
export interface SnapshotStreamRemovedEvent {
|
|
80
|
+
kind: "removed";
|
|
81
|
+
generation: number;
|
|
82
|
+
serverNowMs: number;
|
|
83
|
+
refresher: RefresherSchedule;
|
|
84
|
+
id: number;
|
|
85
|
+
}
|
|
86
|
+
/** Discriminated union of every event the snapshot stream emits. */
|
|
87
|
+
export type SnapshotStreamEvent = SnapshotStreamSnapshotEvent | SnapshotStreamEntryEvent | SnapshotStreamRemovedEvent;
|
|
59
88
|
/**
|
|
60
89
|
* Default bearer-protected route prefix. The broker exposes `/v1/healthz`
|
|
61
90
|
* unauthenticated for liveness probes; everything else requires a bearer.
|
|
@@ -67,3 +96,10 @@ export declare const DEFAULT_AUTH_BROKER_BIND = "127.0.0.1:8765";
|
|
|
67
96
|
export declare const DEFAULT_REFRESH_SKEW_MS: number;
|
|
68
97
|
/** Default broker refresh-loop cadence. */
|
|
69
98
|
export declare const DEFAULT_REFRESH_INTERVAL_MS = 60000;
|
|
99
|
+
/** Keepalive cadence for `GET /v1/snapshot/stream` SSE comments. */
|
|
100
|
+
export declare const DEFAULT_STREAM_KEEPALIVE_MS = 20000;
|
|
101
|
+
/**
|
|
102
|
+
* Bun.serve `idleTimeout` (seconds) used by the broker. Default Bun idle
|
|
103
|
+
* timeout (10s) would close long-lived SSE connections between keepalives.
|
|
104
|
+
*/
|
|
105
|
+
export declare const DEFAULT_SERVER_IDLE_TIMEOUT_S = 255;
|
|
@@ -138,6 +138,154 @@ export declare const snapshotResponseSchema: z.ZodObject<{
|
|
|
138
138
|
rotatesInMs: z.ZodNullable<z.ZodNumber>;
|
|
139
139
|
}, z.core.$strict>>;
|
|
140
140
|
}, z.core.$strict>;
|
|
141
|
+
/** First frame on connect — full snapshot embedded inline with a `kind` tag. */
|
|
142
|
+
export declare const snapshotStreamSnapshotEventSchema: z.ZodObject<{
|
|
143
|
+
generation: z.ZodNumber;
|
|
144
|
+
generatedAt: z.ZodNumber;
|
|
145
|
+
serverNowMs: z.ZodNumber;
|
|
146
|
+
refresher: z.ZodObject<{
|
|
147
|
+
enabled: z.ZodBoolean;
|
|
148
|
+
intervalMs: z.ZodNumber;
|
|
149
|
+
skewMs: z.ZodNumber;
|
|
150
|
+
nextSweepInMs: z.ZodNumber;
|
|
151
|
+
}, z.core.$strict>;
|
|
152
|
+
credentials: z.ZodArray<z.ZodObject<{
|
|
153
|
+
id: z.ZodNumber;
|
|
154
|
+
provider: z.ZodString;
|
|
155
|
+
credential: z.ZodDiscriminatedUnion<[z.ZodObject<{
|
|
156
|
+
type: z.ZodLiteral<"oauth">;
|
|
157
|
+
access: z.ZodString;
|
|
158
|
+
expires: z.ZodNumber;
|
|
159
|
+
enterpriseUrl: z.ZodOptional<z.ZodString>;
|
|
160
|
+
projectId: z.ZodOptional<z.ZodString>;
|
|
161
|
+
email: z.ZodOptional<z.ZodString>;
|
|
162
|
+
accountId: z.ZodOptional<z.ZodString>;
|
|
163
|
+
refresh: z.ZodLiteral<"__remote__">;
|
|
164
|
+
}, z.core.$strict>, z.ZodObject<{
|
|
165
|
+
type: z.ZodLiteral<"api_key">;
|
|
166
|
+
key: z.ZodString;
|
|
167
|
+
}, z.core.$strict>], "type">;
|
|
168
|
+
identityKey: z.ZodNullable<z.ZodString>;
|
|
169
|
+
rotatesInMs: z.ZodNullable<z.ZodNumber>;
|
|
170
|
+
}, z.core.$strict>>;
|
|
171
|
+
kind: z.ZodLiteral<"snapshot">;
|
|
172
|
+
}, z.core.$strict>;
|
|
173
|
+
/** Per-credential upsert/refresh delta. */
|
|
174
|
+
export declare const snapshotStreamEntryEventSchema: z.ZodObject<{
|
|
175
|
+
kind: z.ZodLiteral<"entry">;
|
|
176
|
+
generation: z.ZodNumber;
|
|
177
|
+
serverNowMs: z.ZodNumber;
|
|
178
|
+
refresher: z.ZodObject<{
|
|
179
|
+
enabled: z.ZodBoolean;
|
|
180
|
+
intervalMs: z.ZodNumber;
|
|
181
|
+
skewMs: z.ZodNumber;
|
|
182
|
+
nextSweepInMs: z.ZodNumber;
|
|
183
|
+
}, z.core.$strict>;
|
|
184
|
+
entry: z.ZodObject<{
|
|
185
|
+
id: z.ZodNumber;
|
|
186
|
+
provider: z.ZodString;
|
|
187
|
+
credential: z.ZodDiscriminatedUnion<[z.ZodObject<{
|
|
188
|
+
type: z.ZodLiteral<"oauth">;
|
|
189
|
+
access: z.ZodString;
|
|
190
|
+
expires: z.ZodNumber;
|
|
191
|
+
enterpriseUrl: z.ZodOptional<z.ZodString>;
|
|
192
|
+
projectId: z.ZodOptional<z.ZodString>;
|
|
193
|
+
email: z.ZodOptional<z.ZodString>;
|
|
194
|
+
accountId: z.ZodOptional<z.ZodString>;
|
|
195
|
+
refresh: z.ZodLiteral<"__remote__">;
|
|
196
|
+
}, z.core.$strict>, z.ZodObject<{
|
|
197
|
+
type: z.ZodLiteral<"api_key">;
|
|
198
|
+
key: z.ZodString;
|
|
199
|
+
}, z.core.$strict>], "type">;
|
|
200
|
+
identityKey: z.ZodNullable<z.ZodString>;
|
|
201
|
+
rotatesInMs: z.ZodNullable<z.ZodNumber>;
|
|
202
|
+
}, z.core.$strict>;
|
|
203
|
+
}, z.core.$strict>;
|
|
204
|
+
/** Per-credential delete delta. */
|
|
205
|
+
export declare const snapshotStreamRemovedEventSchema: z.ZodObject<{
|
|
206
|
+
kind: z.ZodLiteral<"removed">;
|
|
207
|
+
generation: z.ZodNumber;
|
|
208
|
+
serverNowMs: z.ZodNumber;
|
|
209
|
+
refresher: z.ZodObject<{
|
|
210
|
+
enabled: z.ZodBoolean;
|
|
211
|
+
intervalMs: z.ZodNumber;
|
|
212
|
+
skewMs: z.ZodNumber;
|
|
213
|
+
nextSweepInMs: z.ZodNumber;
|
|
214
|
+
}, z.core.$strict>;
|
|
215
|
+
id: z.ZodNumber;
|
|
216
|
+
}, z.core.$strict>;
|
|
217
|
+
/** Discriminated union over every event frame the snapshot stream emits. */
|
|
218
|
+
export declare const snapshotStreamEventSchema: z.ZodDiscriminatedUnion<[z.ZodObject<{
|
|
219
|
+
generation: z.ZodNumber;
|
|
220
|
+
generatedAt: z.ZodNumber;
|
|
221
|
+
serverNowMs: z.ZodNumber;
|
|
222
|
+
refresher: z.ZodObject<{
|
|
223
|
+
enabled: z.ZodBoolean;
|
|
224
|
+
intervalMs: z.ZodNumber;
|
|
225
|
+
skewMs: z.ZodNumber;
|
|
226
|
+
nextSweepInMs: z.ZodNumber;
|
|
227
|
+
}, z.core.$strict>;
|
|
228
|
+
credentials: z.ZodArray<z.ZodObject<{
|
|
229
|
+
id: z.ZodNumber;
|
|
230
|
+
provider: z.ZodString;
|
|
231
|
+
credential: z.ZodDiscriminatedUnion<[z.ZodObject<{
|
|
232
|
+
type: z.ZodLiteral<"oauth">;
|
|
233
|
+
access: z.ZodString;
|
|
234
|
+
expires: z.ZodNumber;
|
|
235
|
+
enterpriseUrl: z.ZodOptional<z.ZodString>;
|
|
236
|
+
projectId: z.ZodOptional<z.ZodString>;
|
|
237
|
+
email: z.ZodOptional<z.ZodString>;
|
|
238
|
+
accountId: z.ZodOptional<z.ZodString>;
|
|
239
|
+
refresh: z.ZodLiteral<"__remote__">;
|
|
240
|
+
}, z.core.$strict>, z.ZodObject<{
|
|
241
|
+
type: z.ZodLiteral<"api_key">;
|
|
242
|
+
key: z.ZodString;
|
|
243
|
+
}, z.core.$strict>], "type">;
|
|
244
|
+
identityKey: z.ZodNullable<z.ZodString>;
|
|
245
|
+
rotatesInMs: z.ZodNullable<z.ZodNumber>;
|
|
246
|
+
}, z.core.$strict>>;
|
|
247
|
+
kind: z.ZodLiteral<"snapshot">;
|
|
248
|
+
}, z.core.$strict>, z.ZodObject<{
|
|
249
|
+
kind: z.ZodLiteral<"entry">;
|
|
250
|
+
generation: z.ZodNumber;
|
|
251
|
+
serverNowMs: z.ZodNumber;
|
|
252
|
+
refresher: z.ZodObject<{
|
|
253
|
+
enabled: z.ZodBoolean;
|
|
254
|
+
intervalMs: z.ZodNumber;
|
|
255
|
+
skewMs: z.ZodNumber;
|
|
256
|
+
nextSweepInMs: z.ZodNumber;
|
|
257
|
+
}, z.core.$strict>;
|
|
258
|
+
entry: z.ZodObject<{
|
|
259
|
+
id: z.ZodNumber;
|
|
260
|
+
provider: z.ZodString;
|
|
261
|
+
credential: z.ZodDiscriminatedUnion<[z.ZodObject<{
|
|
262
|
+
type: z.ZodLiteral<"oauth">;
|
|
263
|
+
access: z.ZodString;
|
|
264
|
+
expires: z.ZodNumber;
|
|
265
|
+
enterpriseUrl: z.ZodOptional<z.ZodString>;
|
|
266
|
+
projectId: z.ZodOptional<z.ZodString>;
|
|
267
|
+
email: z.ZodOptional<z.ZodString>;
|
|
268
|
+
accountId: z.ZodOptional<z.ZodString>;
|
|
269
|
+
refresh: z.ZodLiteral<"__remote__">;
|
|
270
|
+
}, z.core.$strict>, z.ZodObject<{
|
|
271
|
+
type: z.ZodLiteral<"api_key">;
|
|
272
|
+
key: z.ZodString;
|
|
273
|
+
}, z.core.$strict>], "type">;
|
|
274
|
+
identityKey: z.ZodNullable<z.ZodString>;
|
|
275
|
+
rotatesInMs: z.ZodNullable<z.ZodNumber>;
|
|
276
|
+
}, z.core.$strict>;
|
|
277
|
+
}, z.core.$strict>, z.ZodObject<{
|
|
278
|
+
kind: z.ZodLiteral<"removed">;
|
|
279
|
+
generation: z.ZodNumber;
|
|
280
|
+
serverNowMs: z.ZodNumber;
|
|
281
|
+
refresher: z.ZodObject<{
|
|
282
|
+
enabled: z.ZodBoolean;
|
|
283
|
+
intervalMs: z.ZodNumber;
|
|
284
|
+
skewMs: z.ZodNumber;
|
|
285
|
+
nextSweepInMs: z.ZodNumber;
|
|
286
|
+
}, z.core.$strict>;
|
|
287
|
+
id: z.ZodNumber;
|
|
288
|
+
}, z.core.$strict>], "kind">;
|
|
141
289
|
export declare const healthzResponseSchema: z.ZodObject<{
|
|
142
290
|
ok: z.ZodBoolean;
|
|
143
291
|
version: z.ZodOptional<z.ZodString>;
|
|
@@ -58,7 +58,7 @@ export interface AuthGatewayParsedRequestOptions {
|
|
|
58
58
|
serviceTier?: ServiceTier;
|
|
59
59
|
/** Cache retention hint derived from inbound `cache_control` markers. */
|
|
60
60
|
cacheRetention?: CacheRetention;
|
|
61
|
-
/** OpenAI Responses `prompt_cache_key`;
|
|
61
|
+
/** OpenAI Responses `prompt_cache_key`; also seeds provider routing when no separate session id exists. */
|
|
62
62
|
promptCacheKey?: string;
|
|
63
63
|
/** OpenAI Responses `previous_response_id` for response chaining. */
|
|
64
64
|
previousResponseId?: string;
|
|
@@ -44,6 +44,45 @@ export interface StoredAuthCredential {
|
|
|
44
44
|
credential: AuthCredential;
|
|
45
45
|
disabledCause: string | null;
|
|
46
46
|
}
|
|
47
|
+
/**
|
|
48
|
+
* Per-credential health record returned by {@link AuthStorage.checkCredentials}.
|
|
49
|
+
*
|
|
50
|
+
* Use this to identify which credential in a multi-account pool is causing
|
|
51
|
+
* auth errors. `ok` is tri-state:
|
|
52
|
+
*
|
|
53
|
+
* - `true` — credential authenticated against the provider's auth-verifying
|
|
54
|
+
* probe (today: the usage endpoint). For OAuth this also exercises refresh
|
|
55
|
+
* when the access token was expired.
|
|
56
|
+
* - `false` — the probe rejected the credential (401/403/refresh failure/etc).
|
|
57
|
+
* `reason` carries the upstream error string.
|
|
58
|
+
* - `null` — no probe is configured for this provider (or the configured
|
|
59
|
+
* probe doesn't support this credential type). The credential's auth
|
|
60
|
+
* status is unverifiable from here.
|
|
61
|
+
*/
|
|
62
|
+
export interface CredentialHealthResult {
|
|
63
|
+
/** Database row id (matches {@link StoredAuthCredential.id}). */
|
|
64
|
+
id: number;
|
|
65
|
+
provider: string;
|
|
66
|
+
type: AuthCredential["type"];
|
|
67
|
+
/** OAuth email if known on the stored credential or surfaced by the probe. */
|
|
68
|
+
email?: string;
|
|
69
|
+
/** OAuth account id / org id if known. */
|
|
70
|
+
accountId?: string;
|
|
71
|
+
/** `true` when the refresh token lives on a remote broker (sentinel was present). */
|
|
72
|
+
remoteRefresh?: true;
|
|
73
|
+
ok: boolean | null;
|
|
74
|
+
/** Failure / unverifiable reason; absent when `ok === true`. */
|
|
75
|
+
reason?: string;
|
|
76
|
+
/** Probe usage report (raw payload stripped) when `ok === true`. */
|
|
77
|
+
report?: Omit<UsageReport, "raw">;
|
|
78
|
+
}
|
|
79
|
+
export interface CheckCredentialsOptions {
|
|
80
|
+
signal?: AbortSignal;
|
|
81
|
+
/** Per-credential probe timeout (ms). Defaults to the configured usage request timeout. */
|
|
82
|
+
timeoutMs?: number;
|
|
83
|
+
/** Provider → base URL override, same shape as {@link AuthStorage.fetchUsageReports}. */
|
|
84
|
+
baseUrlResolver?: (provider: Provider) => string | undefined;
|
|
85
|
+
}
|
|
47
86
|
/**
|
|
48
87
|
* Sentinel value placed in OAuth `refresh` fields when a credential is shared
|
|
49
88
|
* via {@link AuthStorage.exportSnapshot}. Refresh tokens never leave the broker;
|
|
@@ -252,6 +291,25 @@ type AuthApiKeyOptions = {
|
|
|
252
291
|
*/
|
|
253
292
|
signal?: AbortSignal;
|
|
254
293
|
};
|
|
294
|
+
/**
|
|
295
|
+
* Refreshed OAuth access plus identity metadata returned by
|
|
296
|
+
* {@link AuthStorage.getOAuthAccess}. Callers that authenticate via a bearer
|
|
297
|
+
* AND need the credential's identity (Codex `chatgpt-account-id`, Google
|
|
298
|
+
* `projectId`, GitHub `enterpriseUrl`) consume this shape directly; the
|
|
299
|
+
* refresh slot is deliberately omitted because rotating refresh tokens never
|
|
300
|
+
* leave {@link AuthStorage}.
|
|
301
|
+
*/
|
|
302
|
+
export interface OAuthAccess {
|
|
303
|
+
accessToken: string;
|
|
304
|
+
accountId?: string;
|
|
305
|
+
email?: string;
|
|
306
|
+
projectId?: string;
|
|
307
|
+
enterpriseUrl?: string;
|
|
308
|
+
}
|
|
309
|
+
export interface InvalidateCredentialMatchingOptions {
|
|
310
|
+
signal?: AbortSignal;
|
|
311
|
+
sessionId?: string;
|
|
312
|
+
}
|
|
255
313
|
/**
|
|
256
314
|
* Credential storage backed by an AuthCredentialStore.
|
|
257
315
|
* Reads from storage on reload(), manages round-robin credential selection,
|
|
@@ -401,6 +459,27 @@ export declare class AuthStorage {
|
|
|
401
459
|
/** Caller's cancel signal; only rejects this caller, never the shared upstream fetch. */
|
|
402
460
|
signal?: AbortSignal;
|
|
403
461
|
}): Promise<UsageReport[] | null>;
|
|
462
|
+
/**
|
|
463
|
+
* Probe each stored credential against its provider's auth-verifying usage
|
|
464
|
+
* endpoint and report per-credential auth health.
|
|
465
|
+
*
|
|
466
|
+
* Surfaces the identity of failing credentials so callers running a
|
|
467
|
+
* multi-account pool (e.g. a broker-backed auth-gateway) can tell which
|
|
468
|
+
* row is producing 401s. The probe mirrors the per-credential fan-out
|
|
469
|
+
* inside {@link AuthStorage.fetchUsageReports} (OAuth refresh-on-expiry,
|
|
470
|
+
* then `UsageProvider.fetchUsage`) but does NOT swallow errors — every
|
|
471
|
+
* credential gets either `ok: true`, `ok: false` with `reason`, or
|
|
472
|
+
* `ok: null` when no probe is configured for the provider.
|
|
473
|
+
*
|
|
474
|
+
* Iterates sequentially to avoid synchronized N-account fan-out that
|
|
475
|
+
* upstream `/usage` rate limiters (per source IP) treat as a burst.
|
|
476
|
+
*
|
|
477
|
+
* Only inspects active rows from {@link AuthCredentialStore.listAuthCredentials};
|
|
478
|
+
* soft-disabled rows are already known-bad and don't need a network probe.
|
|
479
|
+
* Environment-variable API keys are not enumerated — the caller's intent
|
|
480
|
+
* here is "which of my stored credentials is broken".
|
|
481
|
+
*/
|
|
482
|
+
checkCredentials(options?: CheckCredentialsOptions): Promise<CredentialHealthResult[]>;
|
|
404
483
|
/**
|
|
405
484
|
* Marks the current session's credential as temporarily blocked due to usage limits.
|
|
406
485
|
* Uses usage reports to determine accurate reset time when available.
|
|
@@ -429,6 +508,23 @@ export declare class AuthStorage {
|
|
|
429
508
|
* 6. Fallback resolver (models.yml custom providers, last-resort)
|
|
430
509
|
*/
|
|
431
510
|
getApiKey(provider: string, sessionId?: string, options?: AuthApiKeyOptions): Promise<string | undefined>;
|
|
511
|
+
/**
|
|
512
|
+
* Resolve the OAuth credential for `provider`, refreshing through the same
|
|
513
|
+
* pipeline as {@link AuthStorage.getApiKey} but returning the refreshed
|
|
514
|
+
* {@link OAuthAccess} (raw access token + identity metadata) instead of
|
|
515
|
+
* the API-key bytes.
|
|
516
|
+
*
|
|
517
|
+
* Use this when the caller needs to inject identity headers alongside the
|
|
518
|
+
* bearer (Codex `chatgpt-account-id`, Google `project`, GitHub
|
|
519
|
+
* `enterpriseUrl`). For pure "give me the bytes for `Authorization`"
|
|
520
|
+
* scenarios, prefer {@link AuthStorage.getApiKey}.
|
|
521
|
+
*
|
|
522
|
+
* Returns `undefined` when no OAuth credential is available, the
|
|
523
|
+
* credential fails to refresh, or runtime/config overrides have replaced
|
|
524
|
+
* OAuth with an explicit API key.
|
|
525
|
+
*/
|
|
526
|
+
getOAuthAccess(provider: string, sessionId?: string, options?: AuthApiKeyOptions): Promise<OAuthAccess | undefined>;
|
|
527
|
+
invalidateCredentialMatching(provider: string, apiKey: string, options?: InvalidateCredentialMatchingOptions): Promise<boolean>;
|
|
432
528
|
invalidateCredentialMatching(provider: string, apiKey: string, signal?: AbortSignal): Promise<boolean>;
|
|
433
529
|
/**
|
|
434
530
|
* Build a redacted snapshot of all loaded credentials for the auth-broker
|
package/dist/types/index.d.ts
CHANGED
|
@@ -40,7 +40,6 @@ export * from "./usage/zai";
|
|
|
40
40
|
export * from "./utils/anthropic-auth";
|
|
41
41
|
export * from "./utils/discovery";
|
|
42
42
|
export * from "./utils/event-stream";
|
|
43
|
-
export * from "./utils/h2-fetch";
|
|
44
43
|
export * from "./utils/oauth";
|
|
45
44
|
export type { OAuthCredentials, OAuthProvider, OAuthProviderId, OAuthProviderInfo, } from "./utils/oauth/types";
|
|
46
45
|
export * from "./utils/overflow";
|
|
@@ -8,9 +8,12 @@
|
|
|
8
8
|
*/
|
|
9
9
|
import type { Effort } from "../model-thinking";
|
|
10
10
|
import type { StreamFunction, StreamOptions, ThinkingBudgets } from "../types";
|
|
11
|
+
export type BedrockThinkingDisplay = "summarized" | "omitted";
|
|
11
12
|
export interface BedrockOptions extends StreamOptions {
|
|
12
13
|
region?: string;
|
|
13
14
|
profile?: string;
|
|
15
|
+
/** Amazon Bedrock API key sent as `Authorization: Bearer`, ahead of SigV4 credential resolution. */
|
|
16
|
+
bearerToken?: string;
|
|
14
17
|
toolChoice?: "auto" | "any" | "none" | {
|
|
15
18
|
type: "tool";
|
|
16
19
|
name: string;
|
|
@@ -18,5 +21,18 @@ export interface BedrockOptions extends StreamOptions {
|
|
|
18
21
|
reasoning?: Effort;
|
|
19
22
|
thinkingBudgets?: ThinkingBudgets;
|
|
20
23
|
interleavedThinking?: boolean;
|
|
24
|
+
/**
|
|
25
|
+
* Controls how Claude returns thinking content in Bedrock responses.
|
|
26
|
+
* - `"summarized"`: thinking blocks include human-readable summaries (default here).
|
|
27
|
+
* - `"omitted"`: thinking content is suppressed; the encrypted signature still
|
|
28
|
+
* travels back for multi-turn continuity.
|
|
29
|
+
*
|
|
30
|
+
* Starting with Claude Opus 4.7 the Anthropic API default is `"omitted"`, which
|
|
31
|
+
* leaves callers waiting on a silent stream during long reasoning runs (issue
|
|
32
|
+
* #1373). We default to `"summarized"` so adaptive-thinking models that accept
|
|
33
|
+
* the field keep producing visible thinking deltas. Older adaptive-thinking
|
|
34
|
+
* models (Opus 4.6, Sonnet 4.6+) reject the field, so we omit it for them.
|
|
35
|
+
*/
|
|
36
|
+
thinkingDisplay?: BedrockThinkingDisplay;
|
|
21
37
|
}
|
|
22
38
|
export declare const streamBedrock: StreamFunction<"bedrock-converse-stream">;
|
|
@@ -1,4 +1,5 @@
|
|
|
1
|
-
import
|
|
1
|
+
import { type JsonValue } from "@bufbuild/protobuf";
|
|
2
|
+
import type { CursorExecHandlerResult, CursorExecHandlers, CursorToolResultHandler, Message, StreamFunction, StreamOptions, ToolResultMessage } from "../types";
|
|
2
3
|
export declare const CURSOR_API_URL = "https://api2.cursor.sh";
|
|
3
4
|
export declare const CURSOR_CLIENT_VERSION = "cli-2026.01.09-231024f";
|
|
4
5
|
export interface CursorOptions extends StreamOptions {
|
|
@@ -34,3 +35,8 @@ export declare function resolveExecHandler<TArgs, TResult>(args: TArgs, handler:
|
|
|
34
35
|
* an empty `rootPromptMessagesJson` head.
|
|
35
36
|
*/
|
|
36
37
|
export declare function buildCursorSystemPromptJsons(systemPrompt: readonly string[] | undefined): string[];
|
|
38
|
+
/** Exported for tests: decodes Cursor history blobs built from conversation messages. */
|
|
39
|
+
export declare function buildCursorHistoryForTest(messages: Message[]): {
|
|
40
|
+
rootPromptMessagesJson: unknown[];
|
|
41
|
+
turnUserMessagesJson: JsonValue[];
|
|
42
|
+
};
|
|
@@ -163,8 +163,6 @@ export declare class MockModel implements Model<MockApi> {
|
|
|
163
163
|
/** Reset recorded calls AND the extras queue. The constructor `responses` are NOT reset. */
|
|
164
164
|
reset(): void;
|
|
165
165
|
}
|
|
166
|
-
/** @deprecated Use {@link MockModel}; the class IS the handle. */
|
|
167
|
-
export type MockModelHandle = MockModel;
|
|
168
166
|
/** Check whether `model` was produced by `createMockModel`. */
|
|
169
167
|
export declare function isMockModel(model: Model<Api>): model is MockModel;
|
|
170
168
|
/** Construct a mock model. */
|
|
@@ -2,6 +2,8 @@ import type OpenAI from "openai";
|
|
|
2
2
|
import type { ResponseInput, ResponseInputContent, ResponseOutputItem } from "openai/resources/responses/responses";
|
|
3
3
|
import { type Api, type AssistantMessage, type ImageContent, type Model, type ServiceTier, type StopReason, type StreamOptions, type TextContent, type TextSignatureV1, type ToolResultMessage } from "../types";
|
|
4
4
|
import type { AssistantMessageEventStream } from "../utils/event-stream";
|
|
5
|
+
export declare const OPENAI_RESPONSES_PROGRESS_EVENT_TYPES: ReadonlySet<string>;
|
|
6
|
+
export declare function isOpenAIResponsesProgressEvent(event: unknown): boolean;
|
|
5
7
|
export declare function encodeTextSignatureV1(id: string, phase?: TextSignatureV1["phase"]): string;
|
|
6
8
|
export declare function parseTextSignature(signature: string | undefined): {
|
|
7
9
|
id: string;
|
|
@@ -12,6 +14,30 @@ export declare function normalizeResponsesToolCallIdForTransform(id: string, mod
|
|
|
12
14
|
export declare function collectKnownCallIds(messages: ResponseInput): Set<string>;
|
|
13
15
|
/** Scan replay items for call_ids that were originally custom tool calls. */
|
|
14
16
|
export declare function collectCustomCallIds(messages: ResponseInput): Set<string>;
|
|
17
|
+
/**
|
|
18
|
+
* Convert orphan `function_call_output` / `custom_tool_call_output` items —
|
|
19
|
+
* those whose `call_id` has no matching preceding `function_call` /
|
|
20
|
+
* `custom_tool_call` in the same input — into assistant text notes.
|
|
21
|
+
*
|
|
22
|
+
* The Responses API rejects unpaired outputs with
|
|
23
|
+
* `400 No tool call found for function call output with call_id …`. Orphans
|
|
24
|
+
* sneak in through two paths today:
|
|
25
|
+
*
|
|
26
|
+
* - A previous turn's `providerPayload` snapshot replaces the input array via
|
|
27
|
+
* the `dt: false` splice (see {@link convertConversationMessages}), wiping
|
|
28
|
+
* the matching `function_call` while leaving the matching
|
|
29
|
+
* `function_call_output` queued in a later `toolResult`.
|
|
30
|
+
* - A locally-rejected tool call (argument-validation failure, hook reject,
|
|
31
|
+
* aborted turn before the call streamed) produces a tool result without a
|
|
32
|
+
* `function_call` ever landing in any persisted provider payload.
|
|
33
|
+
*
|
|
34
|
+
* Dropping the result loses information the model needs to recover; sending
|
|
35
|
+
* it as-is 400s the request. Folding it into an assistant `message` preserves
|
|
36
|
+
* the payload (call_id + truncated output) while staying within the Responses
|
|
37
|
+
* input grammar. Matches the behavior of {@link transformRequestBody} in the
|
|
38
|
+
* codex provider — issue #1351 / regression of #472.
|
|
39
|
+
*/
|
|
40
|
+
export declare function repairOrphanResponsesToolOutputs(input: ResponseInput): ResponseInput;
|
|
15
41
|
export declare function convertResponsesInputContent(content: string | Array<TextContent | ImageContent>, supportsImages: boolean): ResponseInputContent[] | undefined;
|
|
16
42
|
export declare function convertResponsesAssistantMessage<TApi extends Api>(assistantMsg: AssistantMessage, model: Model<TApi>, msgIndex: number, knownCallIds: Set<string>, includeThinkingSignatures?: boolean, customCallIds?: Set<string>): ResponseInput;
|
|
17
43
|
export declare function appendResponsesToolResultMessages<TApi extends Api>(messages: ResponseInput, toolResult: ToolResultMessage, model: Model<TApi>, strictResponsesPairing: boolean, knownCallIds: ReadonlySet<string>, customCallIds?: ReadonlySet<string>): void;
|