@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.
Files changed (49) hide show
  1. package/CHANGELOG.md +13 -1
  2. package/THIRD-PARTY-NOTICES.txt +0 -37
  3. package/dist/types/auth-retry.d.ts +2 -0
  4. package/dist/types/auth-storage.d.ts +2 -2
  5. package/dist/types/error/classes.d.ts +4 -1
  6. package/dist/types/error/flags.d.ts +12 -4
  7. package/dist/types/index.d.ts +14 -12
  8. package/dist/types/judgment/types.d.ts +5 -2
  9. package/dist/types/judgment/typesafe.d.ts +16 -22
  10. package/dist/types/providers/anthropic-compaction.d.ts +10 -0
  11. package/dist/types/providers/anthropic-identity.d.ts +18 -0
  12. package/dist/types/providers/anthropic-state.d.ts +13 -0
  13. package/dist/types/providers/anthropic.d.ts +6 -59
  14. package/dist/types/providers/gitlab-duo.d.ts +0 -1
  15. package/dist/types/providers/kimi.d.ts +1 -5
  16. package/dist/types/providers/openai-codex-attestation.d.ts +6 -0
  17. package/dist/types/providers/openai-codex-compaction.d.ts +6 -0
  18. package/dist/types/providers/openai-codex-responses.d.ts +3 -27
  19. package/dist/types/providers/openai-codex-transport.d.ts +7 -0
  20. package/dist/types/providers/openai-shared.d.ts +0 -9
  21. package/dist/types/providers/register-builtins.d.ts +20 -22
  22. package/dist/types/providers/synthetic.d.ts +1 -5
  23. package/package.json +6 -6
  24. package/src/auth-retry.ts +3 -0
  25. package/src/auth-storage.ts +28 -22
  26. package/src/error/auth-classify.ts +10 -2
  27. package/src/error/classes.ts +23 -3
  28. package/src/error/flags.ts +51 -16
  29. package/src/index.ts +15 -12
  30. package/src/judgment/types.ts +6 -3
  31. package/src/judgment/typesafe.ts +53 -48
  32. package/src/provider-session-state.ts +1 -1
  33. package/src/providers/anthropic-compaction.ts +54 -0
  34. package/src/providers/anthropic-identity.ts +136 -0
  35. package/src/providers/anthropic-state.ts +55 -0
  36. package/src/providers/anthropic.ts +39 -296
  37. package/src/providers/bedrock-mantle.ts +1 -1
  38. package/src/providers/gitlab-duo.ts +0 -4
  39. package/src/providers/kimi.ts +1 -8
  40. package/src/providers/openai-codex-attestation.ts +19 -0
  41. package/src/providers/openai-codex-compaction.ts +18 -0
  42. package/src/providers/openai-codex-responses.ts +9 -68
  43. package/src/providers/openai-codex-transport.ts +18 -0
  44. package/src/providers/openai-shared.ts +1 -10
  45. package/src/providers/register-builtins.ts +113 -320
  46. package/src/providers/synthetic.ts +1 -8
  47. package/src/registry/cloudflare-ai-gateway.ts +1 -1
  48. package/src/stream.ts +7 -15
  49. 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 = getCodexWebSocketEnvValue();
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 envVal = getCodexWebSocketEnvValue();
3312
- const websocketPreferred =
3313
- envVal !== undefined
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;