@linxiraos/pi-ai 1.2.0 → 1.3.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 +83 -0
- package/README.md +4 -2
- package/THIRD-PARTY-NOTICES.txt +55 -5
- package/dist/types/auth/cascade.d.ts +5 -3
- package/dist/types/auth/pool.d.ts +3 -3
- package/dist/types/auth/select.d.ts +5 -1
- package/dist/types/auth/types.d.ts +15 -5
- package/dist/types/auth/usage-cache.d.ts +3 -1
- package/dist/types/auth-gateway/clients.d.ts +67 -0
- package/dist/types/auth-gateway/dispatch.d.ts +28 -10
- package/dist/types/auth-gateway/http.d.ts +2 -0
- package/dist/types/auth-gateway/index.d.ts +1 -0
- package/dist/types/auth-gateway/server.d.ts +9 -4
- package/dist/types/auth-gateway/session-state.d.ts +6 -0
- package/dist/types/auth-gateway/types.d.ts +16 -2
- package/dist/types/dialect/coercion.d.ts +6 -0
- package/dist/types/error/classes.d.ts +1 -1
- package/dist/types/error/flags.d.ts +15 -0
- package/dist/types/error/index.d.ts +1 -0
- package/dist/types/error/network-cause.d.ts +40 -0
- package/dist/types/images/shared.d.ts +26 -2
- package/dist/types/index.d.ts +1 -0
- package/dist/types/judgment/native.d.ts +51 -3
- package/dist/types/judgment/systemone.d.ts +9 -2
- package/dist/types/judgment/text.d.ts +11 -5
- package/dist/types/judgment/types.d.ts +5 -1
- package/dist/types/judgment/wire.d.ts +16 -3
- package/dist/types/provider-session-state.d.ts +2 -2
- package/dist/types/providers/anthropic-images.d.ts +7 -0
- package/dist/types/providers/anthropic-signature.d.ts +12 -2
- package/dist/types/providers/anthropic-state.d.ts +7 -0
- package/dist/types/providers/anthropic.d.ts +21 -6
- package/dist/types/providers/connection-prewarm.d.ts +15 -0
- package/dist/types/providers/cursor/exec-modern.d.ts +1 -1
- package/dist/types/providers/cursor-pi-args.d.ts +13 -0
- package/dist/types/providers/cursor.d.ts +7 -0
- package/dist/types/providers/openai-codex-responses.d.ts +6 -0
- package/dist/types/providers/openai-responses.d.ts +9 -0
- package/dist/types/providers/openai-shared.d.ts +30 -0
- package/dist/types/providers/systemone-server.d.ts +7 -3
- package/dist/types/providers/transform-messages.d.ts +26 -5
- package/dist/types/registry/oauth/google-antigravity.d.ts +1 -1
- package/dist/types/stream.d.ts +0 -2
- package/dist/types/types.d.ts +33 -9
- package/dist/types/utils/dsml-leak.d.ts +4 -2
- package/dist/types/utils/narration.d.ts +9 -0
- package/dist/types/utils/openai-http.d.ts +2 -0
- package/dist/types/utils/request-body.d.ts +11 -0
- package/dist/types/utils/request-compression.d.ts +21 -0
- package/dist/types/utils/tool-call-arguments.d.ts +2 -1
- package/dist/types/utils/transport-fetch.d.ts +8 -0
- package/dist/types/utils.d.ts +1 -1
- package/package.json +8 -8
- package/src/auth/cascade.ts +23 -13
- package/src/auth/pool.ts +3 -3
- package/src/auth/refresh.ts +39 -12
- package/src/auth/select.ts +8 -2
- package/src/auth/types.ts +16 -5
- package/src/auth/usage-cache.ts +23 -7
- package/src/auth/usage.ts +2 -4
- package/src/auth-broker/remote-store.ts +31 -6
- package/src/auth-gateway/clients.ts +318 -0
- package/src/auth-gateway/dispatch.ts +66 -35
- package/src/auth-gateway/http.ts +11 -5
- package/src/auth-gateway/index.ts +1 -0
- package/src/auth-gateway/routes/embeddings.ts +4 -10
- package/src/auth-gateway/routes/images.ts +6 -10
- package/src/auth-gateway/routes/rerank.ts +4 -10
- package/src/auth-gateway/routes/speech.ts +10 -10
- package/src/auth-gateway/routes/systemone.ts +22 -12
- package/src/auth-gateway/routes/transcriptions.ts +4 -2
- package/src/auth-gateway/routes/video.ts +12 -15
- package/src/auth-gateway/server.ts +136 -53
- package/src/auth-gateway/session-state.ts +14 -0
- package/src/auth-gateway/types.ts +16 -2
- package/src/dialect/coercion.ts +16 -0
- package/src/dialect/hermes.ts +7 -11
- package/src/dialect/qwen3.ts +3 -11
- package/src/error/classes.ts +3 -2
- package/src/error/flags.ts +24 -3
- package/src/error/index.ts +1 -0
- package/src/error/network-cause.ts +179 -0
- package/src/images/codex-format-directive.md +3 -0
- package/src/images/google-antigravity.ts +2 -1
- package/src/images/google-generative-ai.ts +4 -2
- package/src/images/openai-hosted.ts +25 -2
- package/src/images/openai-images.ts +11 -6
- package/src/images/shared.ts +77 -3
- package/src/index.ts +1 -0
- package/src/judgment/chat.ts +17 -1
- package/src/judgment/native.ts +182 -12
- package/src/judgment/openai-decisions.ts +27 -6
- package/src/judgment/systemone.ts +131 -10
- package/src/judgment/text.ts +20 -7
- package/src/judgment/types.ts +5 -1
- package/src/judgment/wire.ts +17 -3
- package/src/provider-session-state.ts +2 -2
- package/src/providers/amazon-bedrock.ts +4 -1
- package/src/providers/anthropic-client.ts +1 -1
- package/src/providers/anthropic-images.ts +263 -0
- package/src/providers/anthropic-messages-server.ts +84 -1
- package/src/providers/anthropic-signature.ts +35 -8
- package/src/providers/anthropic-state.ts +13 -0
- package/src/providers/anthropic.ts +479 -397
- package/src/providers/connection-prewarm.ts +78 -0
- package/src/providers/cowork-fetch.ts +5 -1
- package/src/providers/cursor/exec-modern.ts +1 -0
- package/src/providers/cursor-pi-args.ts +19 -0
- package/src/providers/cursor.ts +53 -13
- package/src/providers/devin.ts +10 -4
- package/src/providers/factory-droid/gemini.ts +9 -3
- package/src/providers/google-gemini-cli.ts +11 -1
- package/src/providers/google-shared.ts +2 -6
- package/src/providers/images-server.ts +6 -1
- package/src/providers/ollama.ts +15 -5
- package/src/providers/openai-anthropic-shim.ts +1 -0
- package/src/providers/openai-chat-server.ts +29 -0
- package/src/providers/openai-codex/access-programs.ts +2 -1
- package/src/providers/openai-codex-responses.ts +49 -82
- package/src/providers/openai-completions.ts +117 -19
- package/src/providers/openai-responses.ts +25 -2
- package/src/providers/openai-shared.ts +36 -5
- package/src/providers/pi-native-server.ts +1 -0
- package/src/providers/systemone-server.ts +72 -12
- package/src/providers/transform-messages.ts +95 -51
- package/src/registry/oauth/google-antigravity.ts +1 -1
- package/src/stream.ts +13 -73
- package/src/types.ts +33 -9
- package/src/usage/claude.ts +2 -9
- package/src/usage/github-copilot.ts +26 -4
- package/src/usage/openai-codex.ts +13 -7
- package/src/usage/opencode-go.ts +7 -8
- package/src/usage/xai-oauth.ts +2 -9
- package/src/utils/dsml-leak.ts +30 -14
- package/src/utils/leaked-thinking-stream.ts +10 -0
- package/src/utils/narration.ts +18 -0
- package/src/utils/openai-http.ts +27 -18
- package/src/utils/request-body.ts +27 -0
- package/src/utils/request-compression.ts +202 -0
- package/src/utils/request-debug.ts +23 -9
- package/src/utils/schema/dereference.ts +51 -18
- package/src/utils/schema/draft.ts +10 -2
- package/src/utils/schema/json-schema-validator.ts +4 -10
- package/src/utils/schema/normalize.ts +6 -9
- package/src/utils/tool-call-arguments.ts +2 -1
- package/src/utils/transport-fetch.ts +37 -0
- package/src/utils/validation.ts +26 -16
- package/src/utils.ts +38 -23
|
@@ -47,7 +47,7 @@ export declare class AnthropicApiError extends ProviderHttpError {
|
|
|
47
47
|
}
|
|
48
48
|
/** Network-level failure (DNS, TLS, socket reset) after retries were exhausted. */
|
|
49
49
|
export declare class AnthropicConnectionError extends Error {
|
|
50
|
-
constructor(cause: unknown);
|
|
50
|
+
constructor(cause: unknown, requestUrl?: string);
|
|
51
51
|
}
|
|
52
52
|
/** No response headers arrived within the configured request timeout. */
|
|
53
53
|
export declare class AnthropicConnectionTimeoutError extends Error {
|
|
@@ -68,10 +68,25 @@ export declare function isCodexSteerRejection(message: {
|
|
|
68
68
|
api?: Api;
|
|
69
69
|
errorMessage?: string;
|
|
70
70
|
}): boolean;
|
|
71
|
+
/**
|
|
72
|
+
* Transport-failure wording that marks an error transient. Covers
|
|
73
|
+
* diagnostics forwarded verbatim by gateways/proxies in other runtimes, e.g.
|
|
74
|
+
* undici's "other side closed" and Go's `net.ErrClosed` ("use of closed
|
|
75
|
+
* network connection", #15385). Also covers OMP's own network-failure
|
|
76
|
+
* sentences from `networkFailureMessage` (offline / unreachable / refused /
|
|
77
|
+
* TLS), which must stay at least as retryable as the bare `Connection error.`
|
|
78
|
+
* text they replaced.
|
|
79
|
+
*/
|
|
71
80
|
export declare const TRANSIENT_TRANSPORT_PATTERN: RegExp;
|
|
72
81
|
export declare const ANTHROPIC_ACCOUNT_POLICY_PATTERN: RegExp;
|
|
73
82
|
/** Whether an error message represents an Anthropic account-scoped permission/policy denial. */
|
|
74
83
|
export declare function isAnthropicAccountPolicyText(text: string, provider?: string, statusArg?: number): boolean;
|
|
84
|
+
/**
|
|
85
|
+
* Anthropic's rejection of a replayed latest assistant turn whose `thinking` or
|
|
86
|
+
* `redacted_thinking` blocks no longer verify. Resending the same turn fails the
|
|
87
|
+
* same way; only a request that changes that turn's reasoning can succeed.
|
|
88
|
+
*/
|
|
89
|
+
export declare function isImmutableLatestThinkingText(text: string): boolean;
|
|
75
90
|
/**
|
|
76
91
|
* Local llama.cpp / Ollama deterministic tool-call argument JSON parse failure.
|
|
77
92
|
* The model emitted invalid JSON in a tool call and the server returned HTTP 500
|
|
@@ -0,0 +1,40 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Local transport diagnosis for a rejected `fetch`.
|
|
3
|
+
*
|
|
4
|
+
* Bun and Node describe the same outage with different shapes — Bun throws a
|
|
5
|
+
* `TypeError` carrying `code: "ETIMEOUT" | "FailedToOpenSocket" |
|
|
6
|
+
* "ConnectionRefused"`, undici nests an `ENOTFOUND`/`ECONNREFUSED` errno under
|
|
7
|
+
* `TypeError: fetch failed` (sometimes through an `AggregateError`), and
|
|
8
|
+
* `fetchWithRetry` may already have flattened the chain into a message-only
|
|
9
|
+
* `Error`. Both the code and the text are inspected so every one of those
|
|
10
|
+
* shapes lands in the right bucket.
|
|
11
|
+
*/
|
|
12
|
+
/** Transport-level failure families that get their own user-visible wording. */
|
|
13
|
+
export type NetworkFailureKind = "offline" | "unreachable" | "refused" | "tls";
|
|
14
|
+
/** What {@link classifyNetworkCause} reports about a rejected `fetch`: the failure family plus the bits its sentence needs. */
|
|
15
|
+
export interface NetworkFailure {
|
|
16
|
+
kind: NetworkFailureKind;
|
|
17
|
+
/** Runtime error code when the chain exposed one (`ETIMEOUT`, `FailedToOpenSocket`, …). */
|
|
18
|
+
code: string | undefined;
|
|
19
|
+
/** Short parenthetical detail for the user-visible message. */
|
|
20
|
+
detail: string | undefined;
|
|
21
|
+
/** Host named by the error text, when it named one. */
|
|
22
|
+
host: string | undefined;
|
|
23
|
+
}
|
|
24
|
+
/**
|
|
25
|
+
* Walk an error's `cause`/`errors` graph (bounded depth, cycle-safe) and report
|
|
26
|
+
* the outermost link that describes a local transport failure. Returns
|
|
27
|
+
* `undefined` for anything else, including HTTP-level provider errors.
|
|
28
|
+
*/
|
|
29
|
+
export declare function classifyNetworkCause(err: unknown): NetworkFailure | undefined;
|
|
30
|
+
/**
|
|
31
|
+
* User-visible sentence for a network failure, or `undefined` when the error is
|
|
32
|
+
* not one. `requestUrl` wins over any host parsed out of the error text.
|
|
33
|
+
*/
|
|
34
|
+
export declare function networkFailureMessage(err: unknown, requestUrl?: string): string | undefined;
|
|
35
|
+
/**
|
|
36
|
+
* Re-describe a rejected `fetch` with {@link networkFailureMessage}, keeping the
|
|
37
|
+
* original error as `cause`. Anything that is not a local transport failure is
|
|
38
|
+
* returned untouched, so provider/HTTP errors keep their identity.
|
|
39
|
+
*/
|
|
40
|
+
export declare function networkFailureError(err: unknown, requestUrl?: string): unknown;
|
|
@@ -1,7 +1,8 @@
|
|
|
1
1
|
import type { FetchImpl, Model, Usage } from "@linxiraos/pi-catalog/types";
|
|
2
2
|
import type { ApiKey } from "../auth-retry.js";
|
|
3
3
|
import * as AIError from "../error/index.js";
|
|
4
|
-
import type {
|
|
4
|
+
import type { ImageContent } from "../types.js";
|
|
5
|
+
import type { GeneratedImage, ImageInput } from "./types.js";
|
|
5
6
|
export declare class ImageApiError extends AIError.ProviderHttpError {
|
|
6
7
|
readonly name = "ImageApiError";
|
|
7
8
|
}
|
|
@@ -38,6 +39,29 @@ export declare function decodeImageResponse(value: unknown, fetch: FetchImpl, si
|
|
|
38
39
|
* multi-MB payloads are never fully decoded just to be labelled.
|
|
39
40
|
*/
|
|
40
41
|
export declare function sniffBase64ImageMimeType(base64: string): string | undefined;
|
|
41
|
-
|
|
42
|
+
/**
|
|
43
|
+
* Validate provider-bound image input without changing it. Accepts non-empty standard base64
|
|
44
|
+
* with canonical trailing bits and optional padding, and case-insensitive image MIME syntax
|
|
45
|
+
* (RFC 6838 restricted names). Does not sniff the MIME type, decode image pixels, or enforce
|
|
46
|
+
* provider-specific format support; data-URL transports additionally go through `toDataUrl`.
|
|
47
|
+
*
|
|
48
|
+
* @throws {AIError.ValidationError} If the base64 data or image MIME type is invalid.
|
|
49
|
+
*/
|
|
50
|
+
export declare function validateImageInput(image: ImageInput): void;
|
|
51
|
+
/**
|
|
52
|
+
* Encode validated image input as a base64 data URL.
|
|
53
|
+
*
|
|
54
|
+
* @throws {AIError.ValidationError} If the input is invalid or its MIME type cannot survive a data URL.
|
|
55
|
+
*/
|
|
56
|
+
export declare function toDataUrl(image: ImageInput): string;
|
|
57
|
+
/**
|
|
58
|
+
* Whether a MIME type survives a data URL intact: a raw `#` starts a URL fragment and
|
|
59
|
+
* data-URL consumers leave a `%23` escape undecoded, so no data-URL transport preserves it.
|
|
60
|
+
*/
|
|
61
|
+
export declare function isDataUrlMimeType(mimeType: string): boolean;
|
|
62
|
+
/** Whether a value is an embedded image with valid base64 data, MIME type, and detail. */
|
|
63
|
+
export declare function isEmbeddedImageContent(image: unknown): image is ImageContent;
|
|
64
|
+
/** Convert one validated embedded image to a lowercase-MIME inline data URL. */
|
|
65
|
+
export declare function embeddedImageDataUrl(image: unknown): string;
|
|
42
66
|
export declare function resolveOpenAIImageSize(aspectRatio?: string, imageSize?: string): string | undefined;
|
|
43
67
|
export {};
|
package/dist/types/index.d.ts
CHANGED
|
@@ -64,6 +64,7 @@ export * from "./utils/anthropic-auth.js";
|
|
|
64
64
|
export * from "./utils/event-stream.js";
|
|
65
65
|
export * from "./utils/glyph-codec.js";
|
|
66
66
|
export * from "./utils/openrouter-headers.js";
|
|
67
|
+
export * from "./utils/narration.js";
|
|
67
68
|
export * from "./utils/schema/index.js";
|
|
68
69
|
export * from "./utils/thinking-loop.js";
|
|
69
70
|
export * from "./utils/tool-call-loop-guard.js";
|
|
@@ -1,9 +1,32 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Native judgment client: the {@link Judge} backend for catalog models whose
|
|
3
|
+
* API answers typed questions directly ({@link isJudgmentApi}).
|
|
4
|
+
*
|
|
5
|
+
* Each judgment API is one wire dialect: TypeSafe's System One route
|
|
6
|
+
* (`POST /v1/systemone`), OpenRouter Decisions (`POST /api/alpha/decisions`,
|
|
7
|
+
* same body), Cloudflare Workers AI (`POST /ai/run/{model}`, same body plus
|
|
8
|
+
* top-level data URL images; `systemone.ts`), and OpenAI Decisions
|
|
9
|
+
* (`POST /v1/decisions`, translated both ways; `openai-decisions.ts`).
|
|
10
|
+
* Credentials flow through {@link withAuth}, so a stored key rotates on
|
|
11
|
+
* 401/403 exactly like chat providers; transient 429/5xx responses retry with
|
|
12
|
+
* bounded, `retry-after`-aware backoff. Endpoints that cap the questions per
|
|
13
|
+
* request (the catalog's `judgment-questions-max`, e.g. OpenJEV at 16) get
|
|
14
|
+
* oversized requests split into chunks under `maxQuestions`, at most
|
|
15
|
+
* {@link CHUNK_PARALLEL} in flight at once.
|
|
16
|
+
*
|
|
17
|
+
* Environment (mirrors the official TypeSafe SDK, for judges built without an
|
|
18
|
+
* explicit model): `TYPESAFE_API_KEY` is resolved by the auth registry
|
|
19
|
+
* (`rules/auth/typesafe.kdl`), `TYPESAFE_BASE_URL` overrides the API root,
|
|
20
|
+
* `TYPESAFE_DEFAULT_MODEL` the model.
|
|
21
|
+
*/
|
|
22
|
+
import { type JudgmentImageInput } from "@linxiraos/pi-catalog/compat/judgment-images";
|
|
1
23
|
import type { Api, FetchImpl } from "@linxiraos/pi-catalog/types";
|
|
2
24
|
import { type ApiKey } from "../auth-retry.js";
|
|
3
25
|
import * as AIError from "../error/index.js";
|
|
4
|
-
import type { Model, Usage } from "../types.js";
|
|
26
|
+
import type { ImageContent, Model, Usage } from "../types.js";
|
|
5
27
|
import { type Judge, type JudgeOptions, type JudgmentRequest, type JudgmentResult, type Questions } from "./types.js";
|
|
6
|
-
import type { JudgmentWire } from "./wire.js";
|
|
28
|
+
import type { JudgmentImageAssets, JudgmentWire } from "./wire.js";
|
|
29
|
+
export type { JudgmentImageAssets } from "./wire.js";
|
|
7
30
|
export declare const TYPESAFE_PROVIDER = "typesafe";
|
|
8
31
|
export declare const TYPESAFE_DEFAULT_MODEL = "jev-latest";
|
|
9
32
|
declare const JUDGMENT_WIRES: {
|
|
@@ -16,6 +39,19 @@ declare const JUDGMENT_WIRES: {
|
|
|
16
39
|
export type JudgmentApi = keyof typeof JUDGMENT_WIRES;
|
|
17
40
|
/** Whether a catalog API answers judgments natively. */
|
|
18
41
|
export declare function isJudgmentApi(api: Api): api is JudgmentApi;
|
|
42
|
+
/** Whether both the native protocol and catalog model support image input. */
|
|
43
|
+
export declare function nativeJudgmentSupportsImages(model: Model): boolean;
|
|
44
|
+
/**
|
|
45
|
+
* Whether `model`'s native judgment API takes these exact images: image support plus every documented
|
|
46
|
+
* transport and catalog bound. A judge chain skips a candidate that would refuse them instead of failing on it.
|
|
47
|
+
*/
|
|
48
|
+
export declare function nativeJudgmentAcceptsImages(model: Model, images: readonly ImageContent[]): boolean;
|
|
49
|
+
/**
|
|
50
|
+
* Reject images that `model`'s native judgment API cannot take — no image support, an unsupported or
|
|
51
|
+
* unreferenced asset, or a transport or catalog bound exceeded — before any credential or upstream work.
|
|
52
|
+
* @throws {AIError.ValidationError} naming the reason.
|
|
53
|
+
*/
|
|
54
|
+
export declare function checkNativeJudgmentImages(model: Model, request: JudgmentRequest, imageAssets?: JudgmentImageAssets): void;
|
|
19
55
|
/** `TYPESAFE_BASE_URL` when set, else the public API root; trailing slashes stripped. */
|
|
20
56
|
export declare function typesafeBaseUrl(): string;
|
|
21
57
|
/** `TYPESAFE_DEFAULT_MODEL` when set, else {@link TYPESAFE_DEFAULT_MODEL}. */
|
|
@@ -43,9 +79,18 @@ export interface NativeJudgeOptions extends NativeJudgeConnection {
|
|
|
43
79
|
* requests are split. Unset: no cap.
|
|
44
80
|
*/
|
|
45
81
|
maxQuestions?: number;
|
|
82
|
+
/**
|
|
83
|
+
* Whether images are enabled for this judge. `false` disables image input; `true` enables
|
|
84
|
+
* dialects that require explicit opt-in but cannot enable a wire without image support.
|
|
85
|
+
*/
|
|
86
|
+
supportsImages?: boolean;
|
|
87
|
+
/** Catalog-selected image bounds, applied in addition to the wire's transport constraints. */
|
|
88
|
+
imageInput?: JudgmentImageInput;
|
|
46
89
|
}
|
|
47
90
|
/** Per-call options for {@link NativeJudge.judge}. */
|
|
48
91
|
export interface NativeJudgeCallOptions extends JudgeOptions {
|
|
92
|
+
/** Assets keyed by their existing references; wires without asset transport reject them. */
|
|
93
|
+
imageAssets?: JudgmentImageAssets;
|
|
49
94
|
/**
|
|
50
95
|
* Called before a split judgment rejects, with the summed usage of the chunks that had already
|
|
51
96
|
* succeeded: billed upstream, but their answers are discarded with the failure. Not called when
|
|
@@ -60,6 +105,8 @@ export declare class JudgmentApiError extends AIError.ProviderHttpError {
|
|
|
60
105
|
export declare class NativeJudge implements Judge {
|
|
61
106
|
#private;
|
|
62
107
|
readonly label: string;
|
|
108
|
+
/** True when the selected native wire and model or direct-call option permit image input. */
|
|
109
|
+
readonly supportsImages?: boolean;
|
|
63
110
|
readonly api: JudgmentApi;
|
|
64
111
|
readonly provider: string;
|
|
65
112
|
/** Wire model id sent with every request. */
|
|
@@ -67,6 +114,8 @@ export declare class NativeJudge implements Judge {
|
|
|
67
114
|
readonly baseUrl: string;
|
|
68
115
|
constructor(options: NativeJudgeOptions);
|
|
69
116
|
judge<Q extends Questions>(request: JudgmentRequest<Q>, options?: NativeJudgeCallOptions): Promise<JudgmentResult<Q>>;
|
|
117
|
+
/** Effective image detail for cache identity after applying this wire's forwarding behavior. */
|
|
118
|
+
effectiveImageDetail(detail: ImageContent["detail"]): ImageContent["detail"];
|
|
70
119
|
}
|
|
71
120
|
/**
|
|
72
121
|
* The {@link NativeJudge} for a catalog judge model: its API's dialect, wire id
|
|
@@ -77,4 +126,3 @@ export declare class NativeJudge implements Judge {
|
|
|
77
126
|
* @throws ConfigurationError when the model's API is not a judgment API.
|
|
78
127
|
*/
|
|
79
128
|
export declare function createNativeJudge(model: Model, connection: NativeJudgeConnection): NativeJudge;
|
|
80
|
-
export {};
|
|
@@ -1,7 +1,14 @@
|
|
|
1
|
-
import { type
|
|
1
|
+
import { type JudgmentRequest } from "./types.js";
|
|
2
|
+
import { type JudgmentImageAssets, type JudgmentWire } from "./wire.js";
|
|
3
|
+
/**
|
|
4
|
+
* The subset of `assets` that `request` references. TypeSafe substitutes a reference wherever it
|
|
5
|
+
* occurs as text in a string of `state`, a question's `instructions`, or its `criteria` (never in
|
|
6
|
+
* object keys) and rejects a request carrying an unreferenced asset.
|
|
7
|
+
*/
|
|
8
|
+
export declare function referencedImageAssets(request: JudgmentRequest, assets: JudgmentImageAssets): JudgmentImageAssets;
|
|
2
9
|
/** TypeSafe's own route, shared by every System One server. */
|
|
3
10
|
export declare const typesafeWire: JudgmentWire;
|
|
4
|
-
/** OpenRouter Decisions:
|
|
11
|
+
/** OpenRouter Decisions: System One body under `/api/alpha`, with image parts preserved in state. */
|
|
5
12
|
export declare const openrouterDecisionsWire: JudgmentWire;
|
|
6
13
|
/** Cloudflare Workers AI decision models (Clef) through the account-scoped `ai/run` route. */
|
|
7
14
|
export declare const workersAiWire: JudgmentWire;
|
|
@@ -1,8 +1,10 @@
|
|
|
1
|
-
import type { Usage } from "../types.js";
|
|
1
|
+
import type { ImageContent, Usage } from "../types.js";
|
|
2
2
|
import { type Answer, type Judge, type JudgeOptions, type JudgmentRequest, type JudgmentResult, type JudgmentState, type Question, type Questions } from "./types.js";
|
|
3
3
|
export interface TextPrompt {
|
|
4
4
|
system: string;
|
|
5
5
|
user: string;
|
|
6
|
+
/** Images are kept as distinct content blocks, never rendered into JSON text. */
|
|
7
|
+
images?: readonly ImageContent[];
|
|
6
8
|
/** Format-correction attempt; chat backends may enforce tool suppression on the wire. */
|
|
7
9
|
retry?: boolean;
|
|
8
10
|
}
|
|
@@ -16,6 +18,8 @@ export interface TextBackend {
|
|
|
16
18
|
readonly api: string;
|
|
17
19
|
readonly provider: string;
|
|
18
20
|
readonly model: string;
|
|
21
|
+
/** Whether this backend can send image content on the wire. */
|
|
22
|
+
readonly supportsImages?: boolean;
|
|
19
23
|
/** State guard for agent-tuned chat models; on-device classifier workers may disable it. */
|
|
20
24
|
readonly guardState?: boolean;
|
|
21
25
|
/** Format-correction retries after a completion cannot be parsed. */
|
|
@@ -26,10 +30,11 @@ export interface TextBackend {
|
|
|
26
30
|
export declare function renderJudgmentState(state: JudgmentState): string;
|
|
27
31
|
/**
|
|
28
32
|
* Render a request: the system prompt carries the preamble and question
|
|
29
|
-
* definitions (constant across states, so prompt caches hit); the user
|
|
30
|
-
* carries XML-field state followed by the answer-format cue.
|
|
31
|
-
* on a bare request (answer it,
|
|
32
|
-
* explicit tags and the trailing
|
|
33
|
+
* definitions (constant across states, so prompt caches hit); the user text
|
|
34
|
+
* carries XML-field state followed by the answer-format cue. Images remain
|
|
35
|
+
* separate content blocks. Small models act on a bare request (answer it,
|
|
36
|
+
* emit tool calls) instead of classifying it — explicit tags and the trailing
|
|
37
|
+
* cue keep them on task.
|
|
33
38
|
*/
|
|
34
39
|
export declare function renderJudgmentPrompt(request: JudgmentRequest, options?: {
|
|
35
40
|
guardState?: boolean;
|
|
@@ -53,6 +58,7 @@ export declare function splitAnswerLines(text: string, ids: readonly string[]):
|
|
|
53
58
|
export declare function parseAnswer(id: string, question: Question, reply: string): Answer;
|
|
54
59
|
export declare class TextJudge implements Judge {
|
|
55
60
|
#private;
|
|
61
|
+
readonly supportsImages?: boolean;
|
|
56
62
|
readonly label: string;
|
|
57
63
|
constructor(backend: TextBackend);
|
|
58
64
|
judge<Q extends Questions>(request: JudgmentRequest<Q>, options?: JudgeOptions): Promise<JudgmentResult<Q>>;
|
|
@@ -11,7 +11,7 @@
|
|
|
11
11
|
* bridge ({@link TextJudge}) renders the same questions into keyword prompts
|
|
12
12
|
* for an ordinary chat model.
|
|
13
13
|
*/
|
|
14
|
-
import type { Usage } from "../types.js";
|
|
14
|
+
import type { ImageContent, Usage } from "../types.js";
|
|
15
15
|
/** JSON-compatible value; readonly containers are accepted so `as const` state passes through. */
|
|
16
16
|
export type JsonValue = string | number | boolean | null | readonly JsonValue[] | {
|
|
17
17
|
readonly [key: string]: JsonValue;
|
|
@@ -73,6 +73,8 @@ export type AnswerFor<Q extends Question> = Q extends ChoiceQuestion<infer L> ?
|
|
|
73
73
|
export interface JudgmentRequest<Q extends Questions = Questions> {
|
|
74
74
|
state: JudgmentState;
|
|
75
75
|
questions: Q;
|
|
76
|
+
/** Images evaluated alongside the state; never part of the JSON state itself. */
|
|
77
|
+
images?: readonly ImageContent[];
|
|
76
78
|
}
|
|
77
79
|
export interface JudgmentResult<Q extends Questions = Questions> {
|
|
78
80
|
/** Transport that produced the answers (a judgment api such as `typesafe`, or the chat model's api). */
|
|
@@ -89,6 +91,8 @@ export interface JudgeOptions {
|
|
|
89
91
|
}
|
|
90
92
|
/** Answers typed questions about a state. Implementations are stateless and safe to share. */
|
|
91
93
|
export interface Judge {
|
|
94
|
+
/** Whether this backend can consume separate image content blocks. */
|
|
95
|
+
readonly supportsImages?: boolean;
|
|
92
96
|
/** Backend description for logs, e.g. `typesafe/jev-latest`. */
|
|
93
97
|
readonly label: string;
|
|
94
98
|
judge<Q extends Questions>(request: JudgmentRequest<Q>, options?: JudgeOptions): Promise<JudgmentResult<Q>>;
|
|
@@ -3,7 +3,8 @@
|
|
|
3
3
|
* encodes, and decodes one request for each API it serves. Internal to the
|
|
4
4
|
* judgment module; `native.ts` maps every judgment API to its dialect.
|
|
5
5
|
*/
|
|
6
|
-
import type { Usage } from "../types.js";
|
|
6
|
+
import type { ImageContent, Usage } from "../types.js";
|
|
7
|
+
import type { JudgmentImageInput } from "@linxiraos/pi-catalog/compat/judgment-images";
|
|
7
8
|
import type { JudgmentRequest } from "./types.js";
|
|
8
9
|
/** Where one attempt posts and which bearer token it sends. */
|
|
9
10
|
export interface JudgmentTarget {
|
|
@@ -20,6 +21,8 @@ export interface DecodedJudgment {
|
|
|
20
21
|
refused: readonly string[];
|
|
21
22
|
usage: Usage;
|
|
22
23
|
}
|
|
24
|
+
/** Image assets kept separately from judgment state for asset-aware native wires. */
|
|
25
|
+
export type JudgmentImageAssets = Readonly<Record<string, ImageContent>>;
|
|
23
26
|
/** How one judgment API addresses, encodes, and decodes a request. */
|
|
24
27
|
export interface JudgmentWire {
|
|
25
28
|
/**
|
|
@@ -27,8 +30,18 @@ export interface JudgmentWire {
|
|
|
27
30
|
* Throws when the credential cannot address the endpoint (e.g. no account id).
|
|
28
31
|
*/
|
|
29
32
|
target(baseUrl: string, model: string, key: string): JudgmentTarget;
|
|
30
|
-
/** Request body for `model
|
|
31
|
-
encode(request: JudgmentRequest, model: string): unknown;
|
|
33
|
+
/** Request body for `model`, with optional asset context for dialects that preserve references. */
|
|
34
|
+
encode(request: JudgmentRequest, model: string, imageAssets?: JudgmentImageAssets): unknown;
|
|
35
|
+
/** Headers this dialect adds to requests that carry images. */
|
|
36
|
+
imageHeaders?: Readonly<Record<string, string>>;
|
|
37
|
+
/** Image input this dialect accepts; absent means text-only. */
|
|
38
|
+
images?: JudgmentImageInput;
|
|
39
|
+
/** Whether raw asset maps can be transported without loss by this dialect. */
|
|
40
|
+
supportsImageAssets?: boolean;
|
|
41
|
+
/** Whether image support must be enabled explicitly for direct NativeJudge construction. */
|
|
42
|
+
imagesRequireOptIn?: boolean;
|
|
43
|
+
/** Whether this wire drops per-image detail metadata. */
|
|
44
|
+
ignoresImageDetail?: boolean;
|
|
32
45
|
/** The response's answers and usage; `undefined` when the payload is not this API's response shape. */
|
|
33
46
|
decode(payload: unknown): DecodedJudgment | undefined;
|
|
34
47
|
}
|
|
@@ -18,8 +18,8 @@
|
|
|
18
18
|
* siblings are endpoint-scoped and stay: `strictToolsDisabled`
|
|
19
19
|
* (grammar-too-large 400 for the model's tool schema),
|
|
20
20
|
* `replayUnsignedThinkingDisabled` / `thinkingReplayDisabled` (the endpoint
|
|
21
|
-
* is a signing proxy), `prefixDroppedThinkingBlocks` (blocks a
|
|
22
|
-
*
|
|
21
|
+
* is a signing proxy), `prefixDroppedThinkingBlocks` (blocks a rejected
|
|
22
|
+
* replay made the client strip).
|
|
23
23
|
* - **OpenAI Responses** — the `previous_response_id` chain baselines are
|
|
24
24
|
* account-scoped: a stored response belongs to the account that created it.
|
|
25
25
|
* Strict-tools / reasoning-effort fallbacks, replay warmup and the chaining
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
import type { Context, Model } from "../types.js";
|
|
2
|
+
/**
|
|
3
|
+
* Clamp every image a Claude reader would receive to the host's contract.
|
|
4
|
+
* Limits the model's policy leaves unset fall back to the canonical Anthropic
|
|
5
|
+
* API. Returns `context` itself when nothing needed resizing.
|
|
6
|
+
*/
|
|
7
|
+
export declare function prepareAnthropicImageContext(context: Context, model: Model<"anthropic-messages"> | Model<"google-gemini-cli">): Promise<Context>;
|
|
@@ -1,14 +1,17 @@
|
|
|
1
1
|
/**
|
|
2
|
-
*
|
|
2
|
+
* Reads the cleartext header Anthropic embeds in thinking-block signatures.
|
|
3
3
|
*
|
|
4
4
|
* A signature is a base64 protobuf: outer `{1: version, 2: envelope}`, envelope
|
|
5
5
|
* `{1: header, 2..5: nonce/ciphertext/tag}`, header
|
|
6
|
-
* `{1: schema, 5: hash, 6: model, 8:
|
|
6
|
+
* `{1: schema, 5: hash, 6: model, 8: kind, 11: org uuid, 15: profile, 21: unix ts}`.
|
|
7
7
|
* Field 6 names the model that actually produced the block — a concrete
|
|
8
8
|
* snapshot (`claude-haiku-4-5-20251001`) or an internal codename
|
|
9
9
|
* (`numbat-v6-…`) — which lets a caller notice a gateway serving something other
|
|
10
10
|
* than the requested model. The v4 outer format (`CAQS…`) ships a header
|
|
11
11
|
* without field 6; the decoder then yields nothing.
|
|
12
|
+
* Field 8 names the block kind: `thinking` for reasoning, `narration` for the
|
|
13
|
+
* user-facing prose the API converts into a thinking block when the model
|
|
14
|
+
* writes it between tool calls (connector-text summarization).
|
|
12
15
|
*/
|
|
13
16
|
/**
|
|
14
17
|
* Model id embedded in an Anthropic thinking signature, or undefined when the
|
|
@@ -16,6 +19,13 @@
|
|
|
16
19
|
* nothing resembling a model id.
|
|
17
20
|
*/
|
|
18
21
|
export declare function servedModelFromAnthropicSignature(signature: string): string | undefined;
|
|
22
|
+
/**
|
|
23
|
+
* Whether an Anthropic thinking signature marks its block as narration: prose
|
|
24
|
+
* the model addressed to the user between tool calls, which the API returns as
|
|
25
|
+
* a thinking block. Only an exact `narration` kind matches; any other or
|
|
26
|
+
* unreadable header stays reasoning.
|
|
27
|
+
*/
|
|
28
|
+
export declare function isAnthropicNarrationSignature(signature: string): boolean;
|
|
19
29
|
/**
|
|
20
30
|
* Model id from an OpenRouter reasoning item — a `reasoning_details` entry on
|
|
21
31
|
* chat completions or a Responses `reasoning` output item — which forwards the
|
|
@@ -7,6 +7,13 @@ export declare const ANTHROPIC_OPAQUE_CLIENT_ANCHOR_KEY = "anthropic-opaque-clie
|
|
|
7
7
|
export declare function normalizeAnthropicBaseUrl(baseUrl?: string): string | undefined;
|
|
8
8
|
/** Resolve the endpoint for a first-party Anthropic model without loading its provider implementation. */
|
|
9
9
|
export declare function resolveDirectAnthropicBaseUrl(model: Model<Api>): string;
|
|
10
|
+
/**
|
|
11
|
+
* Whether a request to `model` reaches the official endpoint its compat was built for. `compat.officialEndpoint`
|
|
12
|
+
* classifies the configured `baseUrl`, but a first-party Anthropic model is rerouted at request time by
|
|
13
|
+
* `ANTHROPIC_BASE_URL` or Foundry's `FOUNDRY_BASE_URL` without rebuilding compat. Gates official-only host
|
|
14
|
+
* limits such as the catalog's inline image byte and image count budgets.
|
|
15
|
+
*/
|
|
16
|
+
export declare function reachesOfficialEndpoint(model: Model<Api>): boolean;
|
|
10
17
|
/** Build the endpoint-and-model-scoped Anthropic session-state key. */
|
|
11
18
|
export declare function anthropicProviderSessionStateKey(baseUrl: string, modelId: string): string;
|
|
12
19
|
/** Re-arm fast mode across materialized Anthropic session-state entries. */
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import type { Effort } from "@linxiraos/pi-catalog/effort";
|
|
2
|
-
import type { AnthropicCompactionRequest, AnthropicOutputEffort, FetchImpl, Message, Model, ServiceTier, SimpleStreamOptions, StreamFunction, StreamOptions, Usage } from "../types.js";
|
|
2
|
+
import type { AnthropicCompactionRequest, AnthropicOutputEffort, Api, FetchImpl, Message, Model, ServiceTier, SimpleStreamOptions, StreamFunction, StreamOptions, Usage } from "../types.js";
|
|
3
3
|
import { type AnthropicFetchOptions, type AnthropicMessagesClientLike } from "./anthropic-client.js";
|
|
4
4
|
import { type FallbackParam, type MessageParam, type TextBlockParam } from "./anthropic-wire.js";
|
|
5
5
|
import { resolvesToOfficialAnthropicEndpoint, supportsAnthropicCompaction, supportsAnthropicCompactionOnClient } from "./anthropic-compaction.js";
|
|
@@ -118,7 +118,8 @@ export interface AnthropicOptions extends StreamOptions {
|
|
|
118
118
|
* header is auto-attached; the response parser then honors mid-stream
|
|
119
119
|
* `fallback` content blocks and `usage.iterations` for served-model
|
|
120
120
|
* promotion and per-attempt pricing. Opt-in ONLY — leaving this
|
|
121
|
-
* undefined
|
|
121
|
+
* undefined sends neither and keeps both off; a `fallback` block in the
|
|
122
|
+
* response (a gateway opted in) is still persisted as a replay boundary.
|
|
122
123
|
*/
|
|
123
124
|
fallbacks?: FallbackParam[];
|
|
124
125
|
}
|
|
@@ -132,6 +133,8 @@ export type AnthropicClientOptionsArgs = {
|
|
|
132
133
|
dynamicHeaders?: Record<string, string>;
|
|
133
134
|
isOAuth?: boolean;
|
|
134
135
|
hasTools?: boolean;
|
|
136
|
+
/** Whether a tool in ANTHROPIC_BUFFERED_INPUT_TOOLS is present; suppresses the request-wide fine-grained streaming beta. */
|
|
137
|
+
hasBufferedInputTools?: boolean;
|
|
135
138
|
thinkingEnabled?: boolean;
|
|
136
139
|
thinkingDisplay?: AnthropicThinkingDisplay;
|
|
137
140
|
disableStrictTools?: boolean;
|
|
@@ -240,6 +243,17 @@ type SystemBlockOptions = {
|
|
|
240
243
|
export declare function buildAnthropicSystemBlocks(systemPrompt: readonly string[] | undefined, options?: SystemBlockOptions): AnthropicSystemBlock[] | undefined;
|
|
241
244
|
export declare function normalizeExtraBetas(betas?: string[] | string): string[];
|
|
242
245
|
export declare function buildAnthropicClientOptions(args: AnthropicClientOptionsArgs): AnthropicClientOptionsResult;
|
|
246
|
+
/**
|
|
247
|
+
* Warm-up target for a first-party `anthropic` model: the effective official
|
|
248
|
+
* API URL plus the TLS options real requests use (sockets pool per TLS
|
|
249
|
+
* configuration, so a warm-up made with other options is never reused).
|
|
250
|
+
* `undefined` when requests resolve elsewhere — `ANTHROPIC_BASE_URL` or
|
|
251
|
+
* Foundry gateways never receive unsolicited probes.
|
|
252
|
+
*/
|
|
253
|
+
export declare function resolveAnthropicPrewarmTarget(model: Model<Api>): {
|
|
254
|
+
url: string;
|
|
255
|
+
init: RequestInit;
|
|
256
|
+
} | undefined;
|
|
243
257
|
/**
|
|
244
258
|
* True when enabled thinking on `model` is budget thinking
|
|
245
259
|
* (`thinking.type: "enabled"` with `budget_tokens`) rather than adaptive.
|
|
@@ -283,10 +297,11 @@ export type AnthropicMessageParam = MessageParam;
|
|
|
283
297
|
* Serialize zeta {@link Message}s to Anthropic wire messages.
|
|
284
298
|
*
|
|
285
299
|
* `opts.serverSideFallbackEnabled` — when the CURRENT request itself
|
|
286
|
-
* opts into the server-side-fallback beta chain. Only then
|
|
287
|
-
* `fallback` content block from a prior
|
|
288
|
-
* otherwise the block is dropped to avoid a 400
|
|
289
|
-
* that don't send the beta
|
|
300
|
+
* opts into the server-side-fallback beta chain. Only then, and only on the
|
|
301
|
+
* official endpoint, may a persisted `fallback` content block from a prior
|
|
302
|
+
* turn be replayed on the wire; otherwise the block is dropped to avoid a 400
|
|
303
|
+
* on requests that don't send the beta, and its turn keeps one model's
|
|
304
|
+
* reasoning (see {@link collapseFallbackSegments}).
|
|
290
305
|
*
|
|
291
306
|
* `opts.replayCompaction` — replay a user-role compaction summary that
|
|
292
307
|
* carries an {@link AnthropicCompactionPayload} from this provider as a
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
import type { Api, FetchImpl, Model } from "../types.js";
|
|
2
|
+
/**
|
|
3
|
+
* Opens, or keeps alive, a pooled connection to {@link model}'s API host so
|
|
4
|
+
* the next turn skips DNS + TCP + TLS. Sends a credential-less `HEAD` (nothing
|
|
5
|
+
* is billed; hosts answer 401/404/405) through the same transport — proxy,
|
|
6
|
+
* extra CA, Cowork profile, TLS options — as real requests, because sockets
|
|
7
|
+
* pool per transport configuration and a warm-up made any other way (e.g.
|
|
8
|
+
* `fetch.preconnect`, which also throws on Windows) is never reused.
|
|
9
|
+
* Throttled per origin; best effort, never throws.
|
|
10
|
+
*/
|
|
11
|
+
export declare function prewarmModelConnection(model: Model<Api>, options?: {
|
|
12
|
+
fetch?: FetchImpl;
|
|
13
|
+
}): Promise<void>;
|
|
14
|
+
/** Test hook: forgets every warm-up so the next call is not throttled. */
|
|
15
|
+
export declare function resetConnectionPrewarmForTesting(): void;
|
|
@@ -17,7 +17,7 @@ import type { ToolResultMessage } from "../../types.js";
|
|
|
17
17
|
* virtual registry. Re-exported here because this is where the frame builders
|
|
18
18
|
* and their translation are consumed together.
|
|
19
19
|
*/
|
|
20
|
-
export { cursorExecReadPath, cursorRawReadPath, omitUndefinedArgs, piEscapeRegexLiteral, piGrepSkip, piJoinPath, piLimit, piLsPath, piReadDisplayPath, piReadPath, piReadPathHasRange, piTimeout, shellTimeoutSeconds, } from "../cursor-pi-args.js";
|
|
20
|
+
export { cursorExecReadPath, cursorRawReadPath, omitUndefinedArgs, piEscapeRegexLiteral, piGrepSkip, piJoinPath, piLimit, piLsPath, piReadDisplayPath, piReadPath, piReadPathHasRange, piTimeout, shellDeadlineSeconds, shellTimeoutSeconds, } from "../cursor-pi-args.js";
|
|
21
21
|
/** Flatten a tool result's content into the single `output` string the Pi frames carry. */
|
|
22
22
|
export declare function piOutputText(toolResult: ToolResultMessage): string;
|
|
23
23
|
/**
|
|
@@ -129,6 +129,19 @@ export declare function piTimeout(timeout: number | undefined): number | undefin
|
|
|
129
129
|
* budgets round up: 0 seconds means "no deadline" to the bash tool.
|
|
130
130
|
*/
|
|
131
131
|
export declare function shellTimeoutSeconds(timeoutMs: number | undefined): number | undefined;
|
|
132
|
+
/**
|
|
133
|
+
* The bash-tool kill deadline, in seconds, for a Cursor `ShellArgs`/`ShellStreamArgs` frame.
|
|
134
|
+
*
|
|
135
|
+
* Cursor's `timeout` carries the model's `block_until_ms`, which Cursor's Shell tool documents as
|
|
136
|
+
* how long to block before moving the command to the background, not as a kill deadline; the kill
|
|
137
|
+
* deadline is `hard_timeout`. Without one, a short wait (`block_until_ms: 5000` on a build) must not
|
|
138
|
+
* kill the command: the deadline stays the bash default (`undefined`), raised to the wait only when
|
|
139
|
+
* the wait is longer.
|
|
140
|
+
*/
|
|
141
|
+
export declare function shellDeadlineSeconds(args: {
|
|
142
|
+
timeout: number;
|
|
143
|
+
hardTimeout?: number;
|
|
144
|
+
}): number | undefined;
|
|
132
145
|
/**
|
|
133
146
|
* Drop keys whose value is `undefined` so optional local-tool kwargs stay
|
|
134
147
|
* absent rather than present-as-undefined.
|
|
@@ -218,6 +218,13 @@ export declare function mergeCursorMcpToolCallArgs(streamed: Record<string, unkn
|
|
|
218
218
|
* call handed to an external executor is only a handoff while the marker is
|
|
219
219
|
* absent, and the consumer that runs it needs a runnable block.
|
|
220
220
|
*
|
|
221
|
+
* A frame whose `toolCallId` already has a block in `output` is the server
|
|
222
|
+
* re-dispatching that call (a new `execId`, e.g. a `read` re-sent once a
|
|
223
|
+
* parallel shell created the file). It adds no block: a second block with the
|
|
224
|
+
* same id makes every rebuilt history replay the call twice, which Cursor
|
|
225
|
+
* rejects (issue #15749). The re-run's result supersedes the first one in the
|
|
226
|
+
* host's result buffer.
|
|
227
|
+
*
|
|
221
228
|
* Exported for tests to exercise ordering with adjacent text/thinking blocks.
|
|
222
229
|
*/
|
|
223
230
|
export declare function synthesizeCursorExecToolCall(output: AssistantMessage, stream: AssistantMessageEventStream, state: BlockState, toolCallId: string, toolName: string, args: Record<string, unknown>, { executed }?: {
|
|
@@ -6,6 +6,12 @@ export type { CodexAttestationProvider } from "./openai-codex-attestation.js";
|
|
|
6
6
|
import type { ResponseInput } from "./openai-responses-wire.js";
|
|
7
7
|
export interface OpenAICodexResponsesOptions extends StreamOptions {
|
|
8
8
|
reasoning?: "none" | "minimal" | "low" | "medium" | "high" | "xhigh" | "max";
|
|
9
|
+
/**
|
|
10
|
+
* Run with the least reasoning the model allows; takes precedence over
|
|
11
|
+
* `reasoning`. Sends the `none` tier where the catalog's disable mode is
|
|
12
|
+
* `none-effort`, else the model's lowest supported effort.
|
|
13
|
+
*/
|
|
14
|
+
disableReasoning?: boolean;
|
|
9
15
|
reasoningSummary?: "auto" | "concise" | "detailed" | null;
|
|
10
16
|
/** Explicit `reasoning.context` replay scope. Omitted by default so Codex applies its native request policy. */
|
|
11
17
|
reasoningContext?: CodexReasoningContext;
|
|
@@ -114,6 +114,15 @@ interface OpenAIResponsesChainState {
|
|
|
114
114
|
/** Set once chaining is judged unsupported for this session (circuit breaker). */
|
|
115
115
|
disabled: boolean;
|
|
116
116
|
}
|
|
117
|
+
/**
|
|
118
|
+
* Whether the next request for `model` replays native Responses history items
|
|
119
|
+
* (encrypted reasoning, item ids), as {@link buildParams} decides it. A session
|
|
120
|
+
* is cold, rebuilding turns from message content, from the first request on a
|
|
121
|
+
* connection-bound host (`compat.connectionBoundNativeHistory`, GitHub Copilot)
|
|
122
|
+
* and after `close()` on any host, until a response succeeds. Without session
|
|
123
|
+
* state every request replays.
|
|
124
|
+
*/
|
|
125
|
+
export declare function openAIResponsesReplaysNativeHistory(model: Pick<Model, "api" | "provider" | "compat"> | null | undefined, providerSessionState: Map<string, ProviderSessionState> | undefined): boolean;
|
|
117
126
|
/**
|
|
118
127
|
* Set the process-wide storage default per provider id, used when a request
|
|
119
128
|
* leaves `storeResponses` unset. Hosts call this from their settings so every
|
|
@@ -399,6 +399,22 @@ interface StrictToolsRetryContext {
|
|
|
399
399
|
strictToolsApplied: boolean;
|
|
400
400
|
tools: Tool[] | undefined;
|
|
401
401
|
}
|
|
402
|
+
/**
|
|
403
|
+
* Read OpenRouter's `error.metadata.raw` from a captured non-2xx body.
|
|
404
|
+
*
|
|
405
|
+
* OpenRouter routes to a different upstream per request, so its top-level
|
|
406
|
+
* `error.message` is a generic policy sentence ("Access denied by security
|
|
407
|
+
* policy") and the only place the routed provider's own words appear is
|
|
408
|
+
* `error.metadata.raw`. Providers that proxy through OpenRouter also hang the
|
|
409
|
+
* upstream provider name there.
|
|
410
|
+
*
|
|
411
|
+
* The detail lives in the decoded body captured on the thrown
|
|
412
|
+
* {@link AIError.OpenAIHttpError}, not on the error object itself: no error
|
|
413
|
+
* class in this package carries an `error` property, so reading
|
|
414
|
+
* `error.error.metadata.raw` unconditionally yielded `undefined` and the
|
|
415
|
+
* upstream detail was dropped from every surfaced message.
|
|
416
|
+
*/
|
|
417
|
+
export declare function readOpenRouterRawMetadata(capturedErrorResponse: CapturedHttpErrorResponse | undefined): string | undefined;
|
|
402
418
|
/** Decide whether an OpenAI-family request should retry once with non-strict tools. */
|
|
403
419
|
export declare function shouldRetryWithoutStrictTools(error: unknown, capturedErrorResponse: CapturedHttpErrorResponse | undefined, context: StrictToolsRetryContext): boolean;
|
|
404
420
|
export declare const OPENAI_RESPONSES_PROGRESS_EVENT_TYPES: ReadonlySet<string>;
|
|
@@ -525,6 +541,20 @@ export interface BuildResponsesInputOptions<TApi extends Api> {
|
|
|
525
541
|
* Callers gate on {@link isHarmonyDialectModel}. Items are copied, not mutated.
|
|
526
542
|
*/
|
|
527
543
|
export declare function escapeReplayedControlTokens(items: ResponseInput): ResponseInput;
|
|
544
|
+
/**
|
|
545
|
+
* Whether a same-provider assistant turn may replay its native items while the
|
|
546
|
+
* provider session is still cold (#489). A cold session rebuilds turns from
|
|
547
|
+
* message content because some backends bind native items to one connection
|
|
548
|
+
* (GitHub Copilot: `401 input item does not belong to this connection`, #488).
|
|
549
|
+
* Binding needs server-issued state that survives replay sanitization: an
|
|
550
|
+
* `encrypted_content` blob or an item id. A turn with neither, whose every
|
|
551
|
+
* reasoning item carries plaintext `reasoning_text`, has nothing to bind and is
|
|
552
|
+
* exactly what the server receives once the session warms; rebuilding it would
|
|
553
|
+
* drop that reasoning and change the prompt prefix the server cached.
|
|
554
|
+
* Summary-only reasoning keeps the rebuild: it is no evidence of a server that
|
|
555
|
+
* returns plaintext reasoning.
|
|
556
|
+
*/
|
|
557
|
+
export declare function isColdReplayableResponsesTurn(items: ResponseInput): boolean;
|
|
528
558
|
export declare function buildResponsesInput<TApi extends Api>(options: BuildResponsesInputOptions<TApi>): ResponseInput;
|
|
529
559
|
/**
|
|
530
560
|
* Non-empty `reasoning_text` shipped for a synthesized reasoning item when no
|