@oh-my-pi/pi-ai 18.2.6 → 18.2.7
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 +13 -1
- package/THIRD-PARTY-NOTICES.txt +0 -37
- package/dist/types/auth-retry.d.ts +2 -0
- package/dist/types/auth-storage.d.ts +2 -2
- package/dist/types/error/classes.d.ts +4 -1
- package/dist/types/error/flags.d.ts +12 -4
- package/dist/types/index.d.ts +14 -12
- package/dist/types/judgment/types.d.ts +5 -2
- package/dist/types/judgment/typesafe.d.ts +16 -22
- package/dist/types/providers/anthropic-compaction.d.ts +10 -0
- package/dist/types/providers/anthropic-identity.d.ts +18 -0
- package/dist/types/providers/anthropic-state.d.ts +13 -0
- package/dist/types/providers/anthropic.d.ts +6 -59
- package/dist/types/providers/gitlab-duo.d.ts +0 -1
- package/dist/types/providers/kimi.d.ts +1 -5
- package/dist/types/providers/openai-codex-attestation.d.ts +6 -0
- package/dist/types/providers/openai-codex-compaction.d.ts +6 -0
- package/dist/types/providers/openai-codex-responses.d.ts +3 -27
- package/dist/types/providers/openai-codex-transport.d.ts +7 -0
- package/dist/types/providers/openai-shared.d.ts +0 -9
- package/dist/types/providers/register-builtins.d.ts +20 -22
- package/dist/types/providers/synthetic.d.ts +1 -5
- package/package.json +6 -6
- package/src/auth-retry.ts +3 -0
- package/src/auth-storage.ts +28 -22
- package/src/error/auth-classify.ts +10 -2
- package/src/error/classes.ts +23 -3
- package/src/error/flags.ts +51 -16
- package/src/index.ts +15 -12
- package/src/judgment/types.ts +6 -3
- package/src/judgment/typesafe.ts +53 -48
- package/src/provider-session-state.ts +1 -1
- package/src/providers/anthropic-compaction.ts +54 -0
- package/src/providers/anthropic-identity.ts +136 -0
- package/src/providers/anthropic-state.ts +55 -0
- package/src/providers/anthropic.ts +39 -296
- package/src/providers/bedrock-mantle.ts +1 -1
- package/src/providers/gitlab-duo.ts +0 -4
- package/src/providers/kimi.ts +1 -8
- package/src/providers/openai-codex-attestation.ts +19 -0
- package/src/providers/openai-codex-compaction.ts +18 -0
- package/src/providers/openai-codex-responses.ts +9 -68
- package/src/providers/openai-codex-transport.ts +18 -0
- package/src/providers/openai-shared.ts +1 -10
- package/src/providers/register-builtins.ts +113 -320
- package/src/providers/synthetic.ts +1 -8
- package/src/registry/cloudflare-ai-gateway.ts +1 -1
- package/src/stream.ts +7 -15
- package/src/utils/anthropic-auth.ts +3 -6
|
@@ -82,6 +82,11 @@ import {
|
|
|
82
82
|
transformRequestBody,
|
|
83
83
|
} from "./openai-codex/request-transformer";
|
|
84
84
|
import { CodexApiError } from "./openai-codex/response-handler";
|
|
85
|
+
import { getCodexAttestationHeader } from "./openai-codex-attestation";
|
|
86
|
+
export { createOpenAICodexCompactionRequestContext } from "./openai-codex-compaction";
|
|
87
|
+
import { getOpenAICodexWebSocketEnvValue, isOpenAICodexWebSocketPreferred } from "./openai-codex-transport";
|
|
88
|
+
export { setCodexAttestationProvider } from "./openai-codex-attestation";
|
|
89
|
+
export type { CodexAttestationProvider } from "./openai-codex-attestation";
|
|
85
90
|
import {
|
|
86
91
|
getOpenAIEffortControlState,
|
|
87
92
|
type OpenAIEffortControlState,
|
|
@@ -212,23 +217,6 @@ export interface OpenAICodexCompactionResetOptions {
|
|
|
212
217
|
compaction: CodexCompactionContext;
|
|
213
218
|
}
|
|
214
219
|
|
|
215
|
-
/** Add the selected wire implementation to one logical compaction context. */
|
|
216
|
-
export function createOpenAICodexCompactionRequestContext(options: {
|
|
217
|
-
context: CodexCompactionContext | undefined;
|
|
218
|
-
implementation: "responses" | "responses_compaction_v2" | "responses_compact";
|
|
219
|
-
}): CodexCompactionRequestContext | undefined {
|
|
220
|
-
const context = options.context;
|
|
221
|
-
if (!context) return undefined;
|
|
222
|
-
return {
|
|
223
|
-
operationId: context.operationId,
|
|
224
|
-
trigger: context.trigger,
|
|
225
|
-
reason: context.reason,
|
|
226
|
-
implementation: options.implementation,
|
|
227
|
-
phase: context.phase,
|
|
228
|
-
strategy: context.strategy,
|
|
229
|
-
};
|
|
230
|
-
}
|
|
231
|
-
|
|
232
220
|
const CODEX_DEBUG = $flag("PI_CODEX_DEBUG");
|
|
233
221
|
const CODEX_MAX_RETRIES = 5;
|
|
234
222
|
const CODEX_RETRY_DELAY_MS = 500;
|
|
@@ -281,41 +269,6 @@ const CODEX_RETRYABLE_EVENT_MESSAGE =
|
|
|
281
269
|
/processing your request|retry your request|temporar(?:y|ily)|overloaded|service.?unavailable|internal error|server error/i;
|
|
282
270
|
const CODEX_PROVIDER_SESSION_STATE_KEY = "openai-codex-responses";
|
|
283
271
|
|
|
284
|
-
/**
|
|
285
|
-
* Host integration boundary for just-in-time `x-oai-attestation` header
|
|
286
|
-
* values (codex-rs `AttestationProvider`). Resolves to the full header value
|
|
287
|
-
* — an `{"v":1,"s":0,"t":"v1.…"}` envelope — or `undefined` when no
|
|
288
|
-
* attestation should be sent.
|
|
289
|
-
*/
|
|
290
|
-
export type CodexAttestationProvider = () => Promise<string | undefined>;
|
|
291
|
-
|
|
292
|
-
let codexAttestationProvider: CodexAttestationProvider | undefined;
|
|
293
|
-
|
|
294
|
-
/**
|
|
295
|
-
* Install the process-wide attestation hook consulted for upstream Codex
|
|
296
|
-
* requests (codex-rs stores its provider on `ModelClient` construction). The
|
|
297
|
-
* hook is only consulted for ChatGPT-OAuth credentials and runs just-in-time
|
|
298
|
-
* per request; WebSocket handshakes resolve once per connection because the
|
|
299
|
-
* header is connection-scoped there.
|
|
300
|
-
*/
|
|
301
|
-
export function setCodexAttestationProvider(provider: CodexAttestationProvider | undefined): void {
|
|
302
|
-
codexAttestationProvider = provider;
|
|
303
|
-
}
|
|
304
|
-
|
|
305
|
-
/**
|
|
306
|
-
* Resolve the `x-oai-attestation` header value for one upstream request.
|
|
307
|
-
* Gated on ChatGPT-OAuth credentials (a Codex JWT carries `chatgpt_account_id`;
|
|
308
|
-
* codex-rs gates on `auth.is_chatgpt_auth()`). A throwing hook degrades to no
|
|
309
|
-
* header rather than failing the request.
|
|
310
|
-
*/
|
|
311
|
-
export async function getCodexAttestationHeader(accountId: string | undefined): Promise<string | undefined> {
|
|
312
|
-
if (!accountId || !codexAttestationProvider) return undefined;
|
|
313
|
-
try {
|
|
314
|
-
return await codexAttestationProvider();
|
|
315
|
-
} catch {
|
|
316
|
-
return undefined;
|
|
317
|
-
}
|
|
318
|
-
}
|
|
319
272
|
const X_CODEX_TURN_STATE_HEADER = "x-codex-turn-state";
|
|
320
273
|
const X_MODELS_ETAG_HEADER = "x-models-etag";
|
|
321
274
|
/** WebSocket frames cannot carry per-request HTTP headers; codex-rs mirrors the lite marker into `client_metadata` under this key. */
|
|
@@ -3229,14 +3182,6 @@ function recordCodexWebSocketFailure(state: CodexWebSocketSessionState, activate
|
|
|
3229
3182
|
}
|
|
3230
3183
|
}
|
|
3231
3184
|
|
|
3232
|
-
function getCodexWebSocketEnvValue(): boolean | undefined {
|
|
3233
|
-
const envVal = $env.PI_CODEX_WEBSOCKET;
|
|
3234
|
-
if (envVal !== undefined) {
|
|
3235
|
-
return $flag("PI_CODEX_WEBSOCKET");
|
|
3236
|
-
}
|
|
3237
|
-
return undefined;
|
|
3238
|
-
}
|
|
3239
|
-
|
|
3240
3185
|
function shouldUseCodexWebSocket(
|
|
3241
3186
|
model: Model<"openai-codex-responses">,
|
|
3242
3187
|
state: CodexWebSocketSessionState | undefined,
|
|
@@ -3247,7 +3192,7 @@ function shouldUseCodexWebSocket(
|
|
|
3247
3192
|
// Explicitly disabled by the session state.
|
|
3248
3193
|
if (!state || state.disableWebsocket) return false;
|
|
3249
3194
|
// Env val > Preference
|
|
3250
|
-
const envVal =
|
|
3195
|
+
const envVal = getOpenAICodexWebSocketEnvValue();
|
|
3251
3196
|
if (envVal !== undefined) return envVal;
|
|
3252
3197
|
// Negative preference overrides model preference; otherwise use the model's preference.
|
|
3253
3198
|
if (preferWebsockets === false) return false;
|
|
@@ -3308,13 +3253,9 @@ export function getOpenAICodexTransportDetails(
|
|
|
3308
3253
|
providerSessionState?: Map<string, ProviderSessionState>;
|
|
3309
3254
|
},
|
|
3310
3255
|
): OpenAICodexTransportDetails {
|
|
3311
|
-
const
|
|
3312
|
-
|
|
3313
|
-
|
|
3314
|
-
? envVal
|
|
3315
|
-
: options?.preferWebsockets === false
|
|
3316
|
-
? false
|
|
3317
|
-
: options?.preferWebsockets === true || model.preferWebsockets === true;
|
|
3256
|
+
const websocketPreferred = isOpenAICodexWebSocketPreferred(model, {
|
|
3257
|
+
preferWebsockets: options?.preferWebsockets,
|
|
3258
|
+
});
|
|
3318
3259
|
const state = getCodexWebSocketStateForPublicSession(model, options);
|
|
3319
3260
|
const providerSessionState = getCodexProviderSessionState(options?.providerSessionState);
|
|
3320
3261
|
const sessionId = normalizeOpenAIPromptCacheKey(options?.sessionId);
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
import { $env, $flag } from "@oh-my-pi/pi-utils";
|
|
2
|
+
import type { Model } from "../types";
|
|
3
|
+
|
|
4
|
+
/** Read the optional process-wide Codex WebSocket override. */
|
|
5
|
+
export function getOpenAICodexWebSocketEnvValue(): boolean | undefined {
|
|
6
|
+
return $env.PI_CODEX_WEBSOCKET === undefined ? undefined : $flag("PI_CODEX_WEBSOCKET");
|
|
7
|
+
}
|
|
8
|
+
|
|
9
|
+
/** Resolve the public WebSocket preference using env, caller, then model precedence. */
|
|
10
|
+
export function isOpenAICodexWebSocketPreferred(
|
|
11
|
+
model: Model<"openai-codex-responses">,
|
|
12
|
+
options?: { preferWebsockets?: boolean },
|
|
13
|
+
): boolean {
|
|
14
|
+
const envValue = getOpenAICodexWebSocketEnvValue();
|
|
15
|
+
if (envValue !== undefined) return envValue;
|
|
16
|
+
if (options?.preferWebsockets === false) return false;
|
|
17
|
+
return options?.preferWebsockets === true || model.preferWebsockets === true;
|
|
18
|
+
}
|
|
@@ -34,6 +34,7 @@ import {
|
|
|
34
34
|
structuredCloneJSON,
|
|
35
35
|
USER_AGENT,
|
|
36
36
|
} from "@oh-my-pi/pi-utils";
|
|
37
|
+
import { NO_AUTH_SENTINEL } from "../auth-retry";
|
|
37
38
|
import * as AIError from "../error";
|
|
38
39
|
import {
|
|
39
40
|
type Api,
|
|
@@ -122,16 +123,6 @@ import { applyInferenceHeaders, setHeaderIfAbsent } from "./inference-headers";
|
|
|
122
123
|
import { transformMessages } from "./transform-messages";
|
|
123
124
|
import { joinTextWithImagePlaceholder, NON_VISION_IMAGE_PLACEHOLDER, partitionVisionContent } from "./vision-guard";
|
|
124
125
|
|
|
125
|
-
/**
|
|
126
|
-
* Keyless-provider sentinel. Custom providers configured with `auth: none`
|
|
127
|
-
* (models.yml) have no credential, so the coding-agent resolves their API key
|
|
128
|
-
* to this literal instead of a real secret. Providers must treat it as "no
|
|
129
|
-
* credential" and suppress any credential-bearing header (e.g. `Authorization:
|
|
130
|
-
* Bearer …`) rather than forwarding the sentinel on the wire. See #6188; the
|
|
131
|
-
* google-vertex and amazon-bedrock transports apply the same guard inline.
|
|
132
|
-
*/
|
|
133
|
-
export const NO_AUTH_SENTINEL = "N/A";
|
|
134
|
-
|
|
135
126
|
export interface OpenAIModelIdentity {
|
|
136
127
|
provider: string;
|
|
137
128
|
id: string;
|