@oh-my-pi/pi-ai 16.3.14 → 16.4.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.
Files changed (53) hide show
  1. package/CHANGELOG.md +45 -0
  2. package/README.md +5 -2
  3. package/dist/types/auth-broker/remote-store.d.ts +1 -0
  4. package/dist/types/auth-broker/wire-schemas.d.ts +8 -0
  5. package/dist/types/auth-storage.d.ts +5 -0
  6. package/dist/types/providers/azure-openai-responses.d.ts +1 -1
  7. package/dist/types/providers/ollama.d.ts +1 -1
  8. package/dist/types/providers/openai-chat-server-schema.d.ts +1 -1
  9. package/dist/types/providers/openai-chat-wire.d.ts +1 -1
  10. package/dist/types/providers/openai-codex/request-transformer.d.ts +43 -5
  11. package/dist/types/providers/openai-codex-responses.d.ts +51 -8
  12. package/dist/types/providers/openai-completions.d.ts +1 -1
  13. package/dist/types/providers/openai-responses-wire.d.ts +16 -7
  14. package/dist/types/providers/openai-responses.d.ts +1 -1
  15. package/dist/types/providers/openai-shared.d.ts +38 -8
  16. package/dist/types/registry/novita.d.ts +6 -0
  17. package/dist/types/registry/oauth/device-code.d.ts +25 -0
  18. package/dist/types/registry/oauth/index.d.ts +1 -25
  19. package/dist/types/registry/oauth/xai-oauth.d.ts +9 -25
  20. package/dist/types/registry/registry.d.ts +4 -1
  21. package/dist/types/registry/xai-oauth.d.ts +0 -1
  22. package/dist/types/types.d.ts +26 -3
  23. package/package.json +4 -4
  24. package/src/auth-broker/remote-store.ts +60 -5
  25. package/src/auth-broker/server.ts +1 -0
  26. package/src/auth-broker/wire-schemas.ts +1 -0
  27. package/src/auth-gateway/server.ts +2 -2
  28. package/src/auth-storage.ts +198 -60
  29. package/src/error/flags.ts +4 -1
  30. package/src/error/rate-limit.ts +7 -1
  31. package/src/providers/amazon-bedrock.ts +1 -0
  32. package/src/providers/anthropic-messages-server.ts +18 -0
  33. package/src/providers/azure-openai-responses.ts +3 -3
  34. package/src/providers/ollama.ts +1 -1
  35. package/src/providers/openai-chat-server-schema.ts +1 -1
  36. package/src/providers/openai-chat-server.ts +8 -1
  37. package/src/providers/openai-chat-wire.ts +1 -1
  38. package/src/providers/openai-codex/request-transformer.ts +94 -41
  39. package/src/providers/openai-codex-responses.ts +475 -39
  40. package/src/providers/openai-completions.ts +38 -12
  41. package/src/providers/openai-responses-server.ts +8 -1
  42. package/src/providers/openai-responses-wire.ts +16 -7
  43. package/src/providers/openai-responses.ts +18 -5
  44. package/src/providers/openai-shared.ts +125 -13
  45. package/src/registry/novita.ts +22 -0
  46. package/src/registry/oauth/__tests__/xai-oauth.test.ts +191 -80
  47. package/src/registry/oauth/device-code.ts +92 -0
  48. package/src/registry/oauth/index.ts +1 -91
  49. package/src/registry/oauth/xai-oauth.ts +231 -191
  50. package/src/registry/registry.ts +2 -0
  51. package/src/registry/xai-oauth.ts +0 -1
  52. package/src/stream.ts +7 -1
  53. package/src/types.ts +29 -3
package/CHANGELOG.md CHANGED
@@ -2,6 +2,51 @@
2
2
 
3
3
  ## [Unreleased]
4
4
 
5
+ ## [16.4.0] - 2026-07-10
6
+
7
+ ### Added
8
+
9
+ - Added "max" as a first-class reasoning effort option across providers (including Anthropic, Google, Bedrock, and OpenAI), supporting a maximum reasoning budget of 32,768 tokens.
10
+ - Added and standardized the "Responses Lite" wire contract and transport, enabling automatic activation via model-level catalog flags, moving tools and instructions into developer input items, disabling parallel tool calls, and stripping image detail instead of falling back to the full transport.
11
+ - Added support for concurrent reasoning summaries on Codex Responses using the sequential-cutoff streaming contract.
12
+ - Added Novita API-key login with authenticated key validation and automatic NOVITA_API_KEY environment variable discovery.
13
+
14
+ ### Changed
15
+
16
+ - Recognized Pro Lite as a paid plan tier for OpenAI Codex models.
17
+
18
+ ### Fixed
19
+
20
+ - Fixed xAI SuperGrok multi-account rotation to correctly treat HTTP 403 credit exhaustion and spending limit errors as usage limits, triggering a credential rotation to a sibling account.
21
+ - Fixed error classification for AWS credential-resolution failures (AwsCredentialsError) to correctly map them as authentication failures.
22
+ - Fixed OpenAI-compatible chat-completions streams to preserve vLLM-style trailing cached-token usage chunks, ensuring accurate cacheRead and billable input session statistics.
23
+ - Fixed xai-oauth/grok-4.5 Responses requests to omit the unsupported reasoning.summary field while preserving the reasoning.effort payload.
24
+ - Fixed Codex OAuth credential selection to re-check blocked accounts during ranking and clear stale usage-limit blocks once live usage indicates recovery.
25
+ - Fixed sequential-cutoff reasoning summaries duplicating section headers across Codex reasoning items by tracking the cumulative summary response-globally, so replayed sections and replay-only items no longer re-emit text earlier thinking blocks already streamed.
26
+
27
+ ## [16.3.15] - 2026-07-09
28
+
29
+ ### Breaking Changes
30
+
31
+ - Renamed `OpenAIResponsesCacheOptions`, `normalizeOpenAIResponsesPromptCacheKey`, and `getOpenAIResponsesPromptCacheKey` to the endpoint-neutral `OpenAICacheOptions`, `normalizeOpenAIPromptCacheKey`, and `getOpenAIPromptCacheKey`.
32
+
33
+ ### Added
34
+
35
+ - Added automatic prompt-cache affinity header injection for OpenAI-family chat completions
36
+ - Added support for explicit prompt-cache affinity headers in OpenAI-family chat completions
37
+ - Added OpenAI pro reasoning mode support: models carrying the catalog `reasoningMode: "pro"` marker (GPT-5.6 Pro aliases) send `reasoning: { mode: "pro" }` on OpenAI Responses and Codex Responses requests, alongside the configured effort. The Codex request body now honors `requestModelId` so catalog aliases request the base upstream model id.
38
+
39
+ ### Changed
40
+
41
+ - Updated xAI OAuth to use a dedicated device-code flow instead of redirect/loopback server
42
+
43
+ ### Fixed
44
+
45
+ - Improved account routing for GPT-5.6 models to better respect paid tier requirements
46
+ - Refined account selection logic to correctly identify plan types from account metadata
47
+ - Fixed OpenAI Codex multi-account routing for GPT-5.6: Sol and Luna requests now prefer Plus-or-higher accounts while Terra remains available to Free/Go accounts; local pro-mode aliases inherit their base model's Codex plan eligibility.
48
+ - Fixed xAI Grok OAuth login to use xAI's device authorization flow: `/login` now opens the verification URL, displays the device code, and polls for approval instead of asking for a pasted redirect or linking to Hermes Agent documentation.
49
+
5
50
  ## [16.3.14] - 2026-07-09
6
51
 
7
52
  ### Changed
package/README.md CHANGED
@@ -59,6 +59,7 @@ Unified LLM API with automatic model discovery, provider configuration, token an
59
59
  - **Qianfan** (requires `QIANFAN_API_KEY`)
60
60
  - **NVIDIA** (requires `NVIDIA_API_KEY`)
61
61
  - **NanoGPT** (requires `NANO_GPT_API_KEY`)
62
+ - **Novita** (requires `NOVITA_API_KEY`)
62
63
  - **Hugging Face Inference**
63
64
  - **xAI**
64
65
  - **Venice** (requires `VENICE_API_KEY`)
@@ -943,6 +944,7 @@ In Node.js environments, you can set environment variables to avoid passing API
943
944
  | Synthetic | `SYNTHETIC_API_KEY` |
944
945
  | NVIDIA | `NVIDIA_API_KEY` |
945
946
  | NanoGPT | `NANO_GPT_API_KEY` |
947
+ | Novita | `NOVITA_API_KEY` |
946
948
  | Venice | `VENICE_API_KEY` |
947
949
  | Moonshot | `MOONSHOT_API_KEY` |
948
950
  | xAI | `XAI_API_KEY` |
@@ -981,6 +983,7 @@ Provider endpoint defaults for the current OpenAI-compatible integrations:
981
983
  - Qianfan: `https://qianfan.baidubce.com/v2`
982
984
  - NVIDIA: `https://integrate.api.nvidia.com/v1`
983
985
  - NanoGPT: `https://nano-gpt.com/api/v1`
986
+ - Novita: `https://api.novita.ai/openai/v1`
984
987
  - Hugging Face Inference: `https://router.huggingface.co/v1`
985
988
  - Venice: `https://api.venice.ai/api/v1`
986
989
  - Xiaomi MiMo: `https://api.xiaomimimo.com/anthropic`
@@ -1082,7 +1085,7 @@ Credentials are saved to `agent.db` in the agent directory. `/login qianfan` ope
1082
1085
 
1083
1086
  `login` supports OAuth providers (Anthropic, OpenAI Codex, GitHub Copilot, Gemini CLI, Antigravity) and API-key onboarding flows.
1084
1087
 
1085
- For the current API-key onboarding flows, the library covers Together, Moonshot, Qianfan, NVIDIA, NanoGPT, Hugging Face, Venice, Xiaomi, vLLM, LiteLLM, Cloudflare AI Gateway, Qwen Portal, and Ollama Cloud. Ollama remains the local runtime integration; set `OLLAMA_API_KEY` only when your local or self-hosted deployment enforces bearer auth.
1088
+ For the current API-key onboarding flows, the library covers Together, Moonshot, Qianfan, NVIDIA, NanoGPT, Novita, Hugging Face, Venice, Xiaomi, vLLM, LiteLLM, Cloudflare AI Gateway, Qwen Portal, and Ollama Cloud. Ollama remains the local runtime integration; set `OLLAMA_API_KEY` only when your local or self-hosted deployment enforces bearer auth.
1086
1089
 
1087
1090
  ### Programmatic OAuth
1088
1091
 
@@ -1114,7 +1117,7 @@ import {
1114
1117
  getOAuthApiKey, // (provider, credentialsMap) => { newCredentials, apiKey } | null
1115
1118
 
1116
1119
  // Types
1117
- type OAuthProvider, // includes 'anthropic', 'openai-codex', 'github-copilot', 'google-gemini-cli', 'google-antigravity', 'together', 'moonshot', 'qianfan', 'nvidia', 'nanogpt', 'huggingface', 'venice', 'xiaomi', 'vllm', 'litellm', 'cloudflare-ai-gateway', 'qwen-portal', ...
1120
+ type OAuthProvider, // includes 'anthropic', 'openai-codex', 'github-copilot', 'google-gemini-cli', 'google-antigravity', 'together', 'moonshot', 'qianfan', 'nvidia', 'nanogpt', 'novita', 'huggingface', 'venice', 'xiaomi', 'vllm', 'litellm', 'cloudflare-ai-gateway', 'qwen-portal', ...
1118
1121
  type OAuthCredentials,
1119
1122
  } from "@oh-my-pi/pi-ai";
1120
1123
  ```
@@ -31,6 +31,7 @@ export declare class RemoteAuthCredentialStore implements AuthCredentialStore {
31
31
  refreshSnapshot(): Promise<SnapshotResponse>;
32
32
  listAuthCredentials(provider?: string): StoredAuthCredential[];
33
33
  getCredentialBlock(credentialId: number, providerKey: string, blockScope: string): number | undefined;
34
+ getCredentialBlockReconcileAfter(credentialId: number, providerKey: string, blockScope: string): number | undefined;
34
35
  listCredentialBlocks(credentialIds: readonly number[]): StoredCredentialBlock[];
35
36
  upsertCredentialBlock(block: StoredCredentialBlock): void;
36
37
  deleteCredentialBlocks(credentialId: number): void;
@@ -79,6 +79,7 @@ export declare const credentialBlockSnapshotSchema: import("arktype/internal/var
79
79
  providerKey: string;
80
80
  blockScope: string;
81
81
  blockedUntilMs: number;
82
+ updatedAtMs?: number | undefined;
82
83
  }, {}>;
83
84
  export declare const snapshotEntrySchema: import("arktype/internal/variants/object.ts").ObjectType<{
84
85
  id: number;
@@ -103,6 +104,7 @@ export declare const snapshotEntrySchema: import("arktype/internal/variants/obje
103
104
  providerKey: string;
104
105
  blockScope: string;
105
106
  blockedUntilMs: number;
107
+ updatedAtMs?: number | undefined;
106
108
  }[] | undefined;
107
109
  }, {}>;
108
110
  export declare const refresherScheduleSchema: import("arktype/internal/variants/object.ts").ObjectType<{
@@ -144,6 +146,7 @@ export declare const snapshotResponseSchema: import("arktype/internal/variants/o
144
146
  providerKey: string;
145
147
  blockScope: string;
146
148
  blockedUntilMs: number;
149
+ updatedAtMs?: number | undefined;
147
150
  }[] | undefined;
148
151
  }[];
149
152
  }, {}>;
@@ -181,6 +184,7 @@ export declare const snapshotStreamSnapshotEventSchema: import("arktype/internal
181
184
  providerKey: string;
182
185
  blockScope: string;
183
186
  blockedUntilMs: number;
187
+ updatedAtMs?: number | undefined;
184
188
  }[] | undefined;
185
189
  }[];
186
190
  kind: "snapshot";
@@ -219,6 +223,7 @@ export declare const snapshotStreamEntryEventSchema: import("arktype/internal/va
219
223
  providerKey: string;
220
224
  blockScope: string;
221
225
  blockedUntilMs: number;
226
+ updatedAtMs?: number | undefined;
222
227
  }[] | undefined;
223
228
  };
224
229
  }, {}>;
@@ -269,6 +274,7 @@ export declare const snapshotStreamEventSchema: import("arktype/internal/variant
269
274
  providerKey: string;
270
275
  blockScope: string;
271
276
  blockedUntilMs: number;
277
+ updatedAtMs?: number | undefined;
272
278
  }[] | undefined;
273
279
  }[];
274
280
  kind: "snapshot";
@@ -305,6 +311,7 @@ export declare const snapshotStreamEventSchema: import("arktype/internal/variant
305
311
  providerKey: string;
306
312
  blockScope: string;
307
313
  blockedUntilMs: number;
314
+ updatedAtMs?: number | undefined;
308
315
  }[] | undefined;
309
316
  };
310
317
  } | {
@@ -410,6 +417,7 @@ export declare const credentialBlockRequestSchema: import("arktype/internal/vari
410
417
  providerKey: string;
411
418
  blockScope: string;
412
419
  blockedUntilMs: number;
420
+ updatedAtMs?: number | undefined;
413
421
  }, {}>;
414
422
  export declare const credentialBlockResponseSchema: import("arktype/internal/variants/object.ts").ObjectType<{
415
423
  ok: boolean;
@@ -72,6 +72,8 @@ export interface StoredCredentialBlock {
72
72
  blockScope: string;
73
73
  /** Epoch milliseconds. */
74
74
  blockedUntilMs: number;
75
+ /** Last row update timestamp in epoch milliseconds, when provided by the backing store. */
76
+ updatedAtMs?: number;
75
77
  }
76
78
  /**
77
79
  * Per-credential health record returned by {@link AuthStorage.checkCredentials}.
@@ -241,6 +243,8 @@ export interface AuthCredentialStore {
241
243
  cleanExpiredCache(): void;
242
244
  /** Non-expired block for one (credential, providerKey, scope) key, or undefined. */
243
245
  getCredentialBlock?(credentialId: number, providerKey: string, blockScope: string): number | undefined;
246
+ /** Earliest time a shared-store block should be eligible for live-usage reconciliation. */
247
+ getCredentialBlockReconcileAfter?(credentialId: number, providerKey: string, blockScope: string): number | undefined;
244
248
  /** Upsert with MAX semantics: keep the later blockedUntilMs on conflict. */
245
249
  upsertCredentialBlock?(block: StoredCredentialBlock): void;
246
250
  /** Drop every block row for a credential (all providerKeys/scopes). */
@@ -1036,6 +1040,7 @@ export declare class SqliteAuthCredentialStore implements AuthCredentialStore {
1036
1040
  setCache(key: string, value: string, expiresAtSec: number): void;
1037
1041
  cleanExpiredCache(): void;
1038
1042
  getCredentialBlock(credentialId: number, providerKey: string, blockScope: string): number | undefined;
1043
+ getCredentialBlockReconcileAfter(credentialId: number, providerKey: string, blockScope: string): number | undefined;
1039
1044
  upsertCredentialBlock(block: StoredCredentialBlock): void;
1040
1045
  deleteCredentialBlocks(credentialId: number): void;
1041
1046
  cleanExpiredCredentialBlocks(nowMs: number): void;
@@ -1,7 +1,7 @@
1
1
  import type { ServiceTier, StreamFunction, StreamOptions, ToolChoice } from "../types.js";
2
2
  export { parseAzureDeploymentNameMap } from "./openai-shared.js";
3
3
  export interface AzureOpenAIResponsesOptions extends StreamOptions {
4
- reasoning?: "minimal" | "low" | "medium" | "high" | "xhigh";
4
+ reasoning?: "minimal" | "low" | "medium" | "high" | "xhigh" | "max";
5
5
  reasoningSummary?: "auto" | "detailed" | "concise" | null;
6
6
  azureApiVersion?: string;
7
7
  azureResourceName?: string;
@@ -1,6 +1,6 @@
1
1
  import type { StreamFunction, StreamOptions, ToolChoice } from "../types.js";
2
2
  export interface OllamaChatOptions extends StreamOptions {
3
- reasoning?: "minimal" | "low" | "medium" | "high" | "xhigh";
3
+ reasoning?: "minimal" | "low" | "medium" | "high" | "xhigh" | "max";
4
4
  disableReasoning?: boolean;
5
5
  toolChoice?: ToolChoice;
6
6
  }
@@ -665,7 +665,7 @@ export declare const openaiChatRequestSchema: import("arktype/internal/variants/
665
665
  [x: string]: number;
666
666
  } | undefined;
667
667
  user?: string | undefined;
668
- reasoning_effort?: "high" | "low" | "medium" | "minimal" | "xhigh" | undefined;
668
+ reasoning_effort?: "high" | "low" | "max" | "medium" | "minimal" | "xhigh" | undefined;
669
669
  parallel_tool_calls?: boolean | undefined;
670
670
  service_tier?: "auto" | "default" | "flex" | "priority" | "scale" | undefined;
671
671
  metadata?: {
@@ -31,7 +31,7 @@ export type Metadata = {
31
31
  [key: string]: string;
32
32
  };
33
33
  /** Constrains effort on reasoning for reasoning models. */
34
- export type ReasoningEffort = "none" | "minimal" | "low" | "medium" | "high" | "xhigh" | null;
34
+ export type ReasoningEffort = "none" | "minimal" | "low" | "medium" | "high" | "xhigh" | "max" | null;
35
35
  /** JSON object response format (older JSON mode). */
36
36
  export interface ResponseFormatJSONObject {
37
37
  /** Always `json_object`. */
@@ -2,21 +2,28 @@ import type { Model } from "../../types.js";
2
2
  /** Reasoning replay scope for the Codex Responses API (`reasoning.context`). */
3
3
  export type CodexReasoningContext = "auto" | "current_turn" | "all_turns";
4
4
  /** User-facing effort levels accepted by Codex request options. */
5
- type CodexCallerEffort = "minimal" | "low" | "medium" | "high" | "xhigh";
5
+ type CodexCallerEffort = "minimal" | "low" | "medium" | "high" | "xhigh" | "max";
6
6
  export interface ReasoningConfig {
7
7
  effort: "none" | "minimal" | "low" | "medium" | "high" | "xhigh" | "max";
8
8
  summary?: "auto" | "concise" | "detailed";
9
9
  context?: CodexReasoningContext;
10
+ /** Pro reasoning serving mode (gpt-5.6+ catalog pro aliases). */
11
+ mode?: "pro";
10
12
  }
11
13
  export interface CodexRequestOptions {
12
- /** User-facing effort; the wire-only `max` tier is reached via the model's effort map. */
14
+ /** User-facing effort; maps 1:1 onto the wire tier of the same name. */
13
15
  reasoningEffort?: CodexCallerEffort | "none";
14
16
  reasoningSummary?: ReasoningConfig["summary"] | null;
15
17
  /** Explicit `reasoning.context` override; defaults to `all_turns` when unset. The `all_turns` value is gated to gpt-5.4+ Codex models — older ids reject it, so it is suppressed and `context` omitted. */
16
18
  reasoningContext?: CodexReasoningContext;
17
19
  textVerbosity?: "low" | "medium" | "high";
18
20
  include?: string[];
19
- /** Responses Lite transport contract: strips image detail and disables parallel tool calling, mirroring codex-rs. */
21
+ /**
22
+ * Responses Lite transport override; defaults to the model's
23
+ * `useResponsesLite`. Lite moves instructions/tools into input items,
24
+ * strips image detail, and disables parallel tool calling (codex-rs
25
+ * `use_responses_lite`).
26
+ */
20
27
  responsesLite?: boolean;
21
28
  }
22
29
  export interface InputItem {
@@ -28,6 +35,8 @@ export interface InputItem {
28
35
  name?: string;
29
36
  output?: unknown;
30
37
  arguments?: unknown;
38
+ /** `additional_tools` developer item payload (Responses Lite). */
39
+ tools?: unknown;
31
40
  }
32
41
  export interface RequestBody {
33
42
  model: string;
@@ -37,6 +46,10 @@ export interface RequestBody {
37
46
  input?: InputItem[];
38
47
  tools?: unknown;
39
48
  tool_choice?: unknown;
49
+ /** Concurrent reasoning-summary delivery (codex-rs `StreamOptions`). */
50
+ stream_options?: {
51
+ reasoning_summary_delivery: "sequential_cutoff";
52
+ };
40
53
  reasoning?: Partial<ReasoningConfig>;
41
54
  text?: {
42
55
  verbosity?: "low" | "medium" | "high";
@@ -50,8 +63,33 @@ export interface RequestBody {
50
63
  service_tier?: "auto" | "default" | "flex" | "scale" | "priority" | null;
51
64
  [key: string]: unknown;
52
65
  }
53
- /** Returns whether a Codex request can use the text-only Responses Lite transport. */
54
- export declare function shouldUseCodexResponsesLite(body: RequestBody, requested: boolean | undefined): boolean;
66
+ /**
67
+ * Resolve whether a Codex request uses the Responses Lite transport: an
68
+ * explicit option wins, otherwise the model's catalog flag (codex-rs
69
+ * `model_info.use_responses_lite`) decides.
70
+ */
71
+ export declare function resolveCodexResponsesLite(model: Model<"openai-codex-responses">, requested: boolean | undefined): boolean;
72
+ /**
73
+ * Structural view of a Responses-style body mutated by the Lite rewrite.
74
+ * Loose (`unknown`) property types let the turn transformer (`RequestBody`)
75
+ * and the agent's remote-compaction payloads reuse one shaper.
76
+ */
77
+ export interface CodexLiteShapedBody {
78
+ instructions?: unknown;
79
+ tools?: unknown;
80
+ input?: unknown;
81
+ parallel_tool_calls?: unknown;
82
+ }
83
+ /**
84
+ * Applies the Responses Lite body contract in place (codex-rs
85
+ * `build_responses_request` with `use_responses_lite`): strips pinned image
86
+ * detail, forces parallel tool calling off, moves tools into a leading
87
+ * `additional_tools` developer item and the base instructions into a
88
+ * developer message, then omits top-level `instructions`/`tools`. Shared by
89
+ * normal turns and both remote-compaction paths — codex-rs routes
90
+ * `/responses/compact` through the same builder.
91
+ */
92
+ export declare function applyCodexResponsesLiteShape(body: CodexLiteShapedBody): void;
55
93
  export declare function transformRequestBody(body: RequestBody, model: Model<"openai-codex-responses">, options?: CodexRequestOptions, prompt?: {
56
94
  developerMessages: string[];
57
95
  }): Promise<RequestBody>;
@@ -1,8 +1,8 @@
1
- import type { Context, Model, ProviderSessionState, ServiceTier, StreamFunction, StreamOptions, Tool, ToolChoice } from "../types.js";
1
+ import type { CodexCompactionContext, CodexCompactionRequestContext, Context, Model, ProviderSessionState, ServiceTier, StreamFunction, StreamOptions, Tool, ToolChoice } from "../types.js";
2
2
  import { type CodexReasoningContext, type RequestBody } from "./openai-codex/request-transformer.js";
3
3
  import type { ResponseInput } from "./openai-responses-wire.js";
4
4
  export interface OpenAICodexResponsesOptions extends StreamOptions {
5
- reasoning?: "none" | "minimal" | "low" | "medium" | "high" | "xhigh";
5
+ reasoning?: "none" | "minimal" | "low" | "medium" | "high" | "xhigh" | "max";
6
6
  reasoningSummary?: "auto" | "concise" | "detailed" | null;
7
7
  /** `reasoning.context` replay scope; defaults to `all_turns` when unset. The `all_turns` value is gated to gpt-5.4+ Codex models — older ids reject it, so it is suppressed and `context` omitted. */
8
8
  reasoningContext?: CodexReasoningContext;
@@ -13,17 +13,19 @@ export interface OpenAICodexResponsesOptions extends StreamOptions {
13
13
  preferWebsockets?: boolean;
14
14
  serviceTier?: ServiceTier;
15
15
  /**
16
- * Opt into the Responses Lite transport contract. Sends
16
+ * Responses Lite transport override; defaults to the model's catalog
17
+ * `useResponsesLite` flag (codex-rs `use_responses_lite`). Sends
17
18
  * `x-openai-internal-codex-responses-lite: true` on HTTP requests and on the
18
19
  * WebSocket upgrade (the marker is connection-scoped there, so lite and
19
- * non-lite turns never share a pooled socket), strips image detail from
20
- * input, and disables parallel tool calling — mirroring codex-rs.
20
+ * non-lite turns never share a pooled socket), moves instructions/tools
21
+ * into input items, strips image detail, and disables parallel tool
22
+ * calling — mirroring codex-rs.
21
23
  */
22
24
  responsesLite?: boolean;
23
25
  /**
24
- * Extra `client_metadata` to include in the request body on both transports.
25
- * The canonical Codex envelope is `client_metadata["x-codex-turn-metadata"]`
26
- * (JSON string of thread/turn identifiers); flat keys are also accepted.
26
+ * Additional fields embedded in the canonical
27
+ * `client_metadata["x-codex-turn-metadata"]` JSON blob. Reserved identity
28
+ * keys are ignored; extras are never emitted as top-level metadata fields.
27
29
  */
28
30
  clientMetadata?: Record<string, string>;
29
31
  /**
@@ -34,6 +36,34 @@ export interface OpenAICodexResponsesOptions extends StreamOptions {
34
36
  */
35
37
  onModerationMetadata?: (metadata: unknown) => void;
36
38
  }
39
+ /** Inputs for synthesizing Codex request identity outside the normal stream path. */
40
+ export interface OpenAICodexCompatibilityMetadataOptions {
41
+ sessionId?: string;
42
+ providerSessionState?: Map<string, ProviderSessionState>;
43
+ requestKind: OpenAICodexRequestKind;
44
+ compaction?: CodexCompactionRequestContext;
45
+ startNewTurn?: boolean;
46
+ turnStartedAtUnixMs?: number;
47
+ clientMetadata?: Readonly<Record<string, string>>;
48
+ /** Add the direct installation header required by `/responses/compact`. */
49
+ includeInstallationHeader?: boolean;
50
+ }
51
+ /** Canonical Codex body metadata and compatibility headers for one request. */
52
+ export interface OpenAICodexCompatibilityMetadata {
53
+ clientMetadata: Record<string, string>;
54
+ headers: Record<string, string>;
55
+ }
56
+ /** Live Codex session state to preserve after a successful history rewrite. */
57
+ export interface OpenAICodexCompactionResetOptions {
58
+ providerSessionState?: Map<string, ProviderSessionState>;
59
+ sessionId?: string;
60
+ compaction: CodexCompactionContext;
61
+ }
62
+ /** Add the selected wire implementation to one logical compaction context. */
63
+ export declare function createOpenAICodexCompactionRequestContext(options: {
64
+ context: CodexCompactionContext | undefined;
65
+ implementation: "responses" | "responses_compaction_v2" | "responses_compact";
66
+ }): CodexCompactionRequestContext | undefined;
37
67
  type CodexTransport = "sse" | "websocket";
38
68
  /** Shape of the Codex request sent on the latest provider turn. */
39
69
  export interface OpenAICodexTurnRequestDiagnostics {
@@ -84,6 +114,18 @@ export interface OpenAICodexWebSocketDebugStats {
84
114
  lastPreviousResponseId?: string;
85
115
  lastTurn?: OpenAICodexTurnDiagnostics;
86
116
  }
117
+ /** Request classification encoded in Codex turn metadata. */
118
+ export type OpenAICodexRequestKind = "turn" | "prewarm" | "compaction";
119
+ /**
120
+ * Synthesize Codex request identity for raw provider routes such as remote
121
+ * compaction while reusing the live session's thread, window, and turn.
122
+ */
123
+ export declare function createOpenAICodexCompatibilityMetadata(options: OpenAICodexCompatibilityMetadataOptions): OpenAICodexCompatibilityMetadata;
124
+ /**
125
+ * Invalidate Codex history-dependent transport state after compaction while
126
+ * retaining the session identity and live connection.
127
+ */
128
+ export declare function resetOpenAICodexHistoryAfterCompaction(options: OpenAICodexCompactionResetOptions): void;
87
129
  /** @internal Exported for tests. */
88
130
  export declare function normalizeCodexToolChoice(choice: ToolChoice | undefined, tools?: Tool[], model?: Model<"openai-codex-responses">): string | Record<string, unknown> | undefined;
89
131
  /** @internal Exported for tests. */
@@ -99,6 +141,7 @@ export interface OpenAICodexTransportDetails {
99
141
  canAppend: boolean;
100
142
  prewarmed: boolean;
101
143
  hasSessionState: boolean;
144
+ hasTurnState: boolean;
102
145
  lastFallbackAt?: number;
103
146
  }
104
147
  export declare function getOpenAICodexWebSocketDebugStats(model: Model<"openai-codex-responses">, options?: {
@@ -18,7 +18,7 @@ export { applyOpenRouterRoutingVariant } from "./openai-shared.js";
18
18
  export declare function isOpenAICompletionsProgressChunk(chunk: unknown): boolean;
19
19
  export interface OpenAICompletionsOptions extends StreamOptions {
20
20
  toolChoice?: ToolChoice;
21
- reasoning?: "minimal" | "low" | "medium" | "high" | "xhigh";
21
+ reasoning?: "minimal" | "low" | "medium" | "high" | "xhigh" | "max";
22
22
  /** Force-disable reasoning where supported, or request the lowest effort on generic effort endpoints. */
23
23
  disableReasoning?: boolean;
24
24
  serviceTier?: ServiceTier;
@@ -5995,9 +5995,9 @@ export interface Reasoning {
5995
5995
  /**
5996
5996
  * Constrains effort on reasoning for
5997
5997
  * [reasoning models](https://platform.openai.com/docs/guides/reasoning). Currently
5998
- * supported values are `none`, `minimal`, `low`, `medium`, `high`, and `xhigh`.
5999
- * Reducing reasoning effort can result in faster responses and fewer tokens used
6000
- * on reasoning in a response.
5998
+ * supported values are `none`, `minimal`, `low`, `medium`, `high`, `xhigh`, and
5999
+ * `max`. Reducing reasoning effort can result in faster responses and fewer
6000
+ * tokens used on reasoning in a response.
6001
6001
  *
6002
6002
  * - `gpt-5.1` defaults to `none`, which does not perform reasoning. The supported
6003
6003
  * reasoning values for `gpt-5.1` are `none`, `low`, `medium`, and `high`. Tool
@@ -6006,8 +6006,16 @@ export interface Reasoning {
6006
6006
  * support `none`.
6007
6007
  * - The `gpt-5-pro` model defaults to (and only supports) `high` reasoning effort.
6008
6008
  * - `xhigh` is supported for all models after `gpt-5.1-codex-max`.
6009
+ * - `max` is supported for `gpt-5.6` and later models.
6009
6010
  */
6010
6011
  effort?: ReasoningEffort | null;
6012
+ /**
6013
+ * **gpt-5.6 and later models only**
6014
+ *
6015
+ * Reasoning serving mode. `pro` routes the request to the pro reasoning
6016
+ * path (more compute per response); omit for the standard path.
6017
+ */
6018
+ mode?: "pro" | null;
6011
6019
  /**
6012
6020
  * @deprecated **Deprecated:** use `summary` instead.
6013
6021
  *
@@ -6029,9 +6037,9 @@ export interface Reasoning {
6029
6037
  /**
6030
6038
  * Constrains effort on reasoning for
6031
6039
  * [reasoning models](https://platform.openai.com/docs/guides/reasoning). Currently
6032
- * supported values are `none`, `minimal`, `low`, `medium`, `high`, and `xhigh`.
6033
- * Reducing reasoning effort can result in faster responses and fewer tokens used
6034
- * on reasoning in a response.
6040
+ * supported values are `none`, `minimal`, `low`, `medium`, `high`, `xhigh`, and
6041
+ * `max`. Reducing reasoning effort can result in faster responses and fewer tokens
6042
+ * used on reasoning in a response.
6035
6043
  *
6036
6044
  * - `gpt-5.1` defaults to `none`, which does not perform reasoning. The supported
6037
6045
  * reasoning values for `gpt-5.1` are `none`, `low`, `medium`, and `high`. Tool
@@ -6040,8 +6048,9 @@ export interface Reasoning {
6040
6048
  * support `none`.
6041
6049
  * - The `gpt-5-pro` model defaults to (and only supports) `high` reasoning effort.
6042
6050
  * - `xhigh` is supported for all models after `gpt-5.1-codex-max`.
6051
+ * - `max` is supported for `gpt-5.6` and later models.
6043
6052
  */
6044
- export type ReasoningEffort = "none" | "minimal" | "low" | "medium" | "high" | "xhigh" | null;
6053
+ export type ReasoningEffort = "none" | "minimal" | "low" | "medium" | "high" | "xhigh" | "max" | null;
6045
6054
  /**
6046
6055
  * JSON object response format. An older method of generating JSON responses. Using
6047
6056
  * `json_schema` is recommended for models that support it. Note that the model
@@ -4,7 +4,7 @@ import { type OpenAIReasoningEffortFallbackState } from "./openai-reasoning-fall
4
4
  import type { Tool as OpenAITool, ResponseCreateParamsStreaming, ResponseInput } from "./openai-responses-wire.js";
5
5
  import { type OpenAIStrictToolsScope, type OpenAIStrictToolsState } from "./openai-shared.js";
6
6
  export interface OpenAIResponsesOptions extends StreamOptions {
7
- reasoning?: "minimal" | "low" | "medium" | "high" | "xhigh";
7
+ reasoning?: "minimal" | "low" | "medium" | "high" | "xhigh" | "max";
8
8
  reasoningSummary?: "auto" | "detailed" | "concise" | null;
9
9
  serviceTier?: ServiceTier;
10
10
  textVerbosity?: "low" | "medium" | "high";
@@ -27,7 +27,8 @@ export interface OpenAIRequestSetupModel extends OpenAIModelIdentity {
27
27
  premiumMultiplier?: number;
28
28
  compat?: Pick<ResolvedOpenAISharedCompat, "promptCacheSessionHeader">;
29
29
  }
30
- export interface OpenAIResponsesCacheOptions {
30
+ /** Cache identity controls shared by OpenAI-family transports. */
31
+ export interface OpenAICacheOptions {
31
32
  cacheRetention?: CacheRetention;
32
33
  sessionId?: string;
33
34
  promptCacheKey?: string;
@@ -86,11 +87,13 @@ export interface OpenAIUsageAccounting {
86
87
  orchestration?: Usage["orchestration"];
87
88
  }
88
89
  export declare function calculateOpenAIUsageAccounting(accounting: OpenAIUsageAccountingInput): OpenAIUsageAccounting;
89
- export declare function normalizeOpenAIResponsesPromptCacheKey(sessionId: string | undefined): string | undefined;
90
+ /** Normalize a cache identity to the wire limit accepted by OpenAI-family providers. */
91
+ export declare function normalizeOpenAIPromptCacheKey(sessionId: string | undefined): string | undefined;
90
92
  export declare function normalizeOpenRouterResponsesSessionId(sessionId: string | undefined): string | undefined;
91
- export declare function getOpenAIResponsesPromptCacheKey(options: OpenAIResponsesCacheOptions | undefined): string | undefined;
92
- export declare function getOpenAIResponsesRoutingSessionId(options: Pick<OpenAIResponsesCacheOptions, "cacheRetention" | "sessionId"> | undefined): string | undefined;
93
- export declare function getOpenRouterResponsesSessionId(options: Pick<OpenAIResponsesCacheOptions, "cacheRetention" | "sessionId"> | undefined): string | undefined;
93
+ /** Resolve a prompt-cache identity, falling back to the provider session unless caching is disabled. */
94
+ export declare function getOpenAIPromptCacheKey(options: OpenAICacheOptions | undefined): string | undefined;
95
+ export declare function getOpenAIResponsesRoutingSessionId(options: Pick<OpenAICacheOptions, "cacheRetention" | "sessionId"> | undefined): string | undefined;
96
+ export declare function getOpenRouterResponsesSessionId(options: Pick<OpenAICacheOptions, "cacheRetention" | "sessionId"> | undefined): string | undefined;
94
97
  export declare function parseAzureDeploymentNameMap(value: string | undefined): Map<string, string>;
95
98
  export declare function createOpenAIStrictToolsState(): OpenAIStrictToolsState;
96
99
  export declare function clearOpenAIStrictToolsState(state: OpenAIStrictToolsState): void;
@@ -221,7 +224,7 @@ export type OpenAICompletionsParams = Omit<ChatCompletionCreateParamsStreaming,
221
224
  };
222
225
  /** Reasoning-relevant slice of caller options the Chat Completions dialect dispatch reads. */
223
226
  export interface ChatCompletionsReasoningOptions {
224
- reasoning?: "minimal" | "low" | "medium" | "high" | "xhigh";
227
+ reasoning?: "minimal" | "low" | "medium" | "high" | "xhigh" | "max";
225
228
  disableReasoning?: boolean;
226
229
  }
227
230
  export type OpenAICompatEndpoint = "chat-completions" | "responses";
@@ -392,10 +395,37 @@ type ResponsesToolCallBlock = ToolCall & {
392
395
  [kStreamingLastParseLen]?: number;
393
396
  };
394
397
  export declare function appendReasoningSummaryPart(item: ResponseReasoningItem, part: ResponseReasoningItem["summary"][number]): void;
395
- /** Chooses the final reasoning text without discarding content already streamed into the block. */
396
- export declare function finalizeReasoningThinking(item: ResponseReasoningItem, streamedThinking: string): string;
398
+ /**
399
+ * Response-global accumulator for the sequential-cutoff summary contract.
400
+ *
401
+ * Summary indices are cumulative across ALL reasoning items in a response:
402
+ * each new reasoning item replays the previous item's last completed section
403
+ * (`.done` at index N-1) before streaming its own, and replay-only items may
404
+ * add nothing new. Folding per item would re-emit every replayed section, so
405
+ * the canonical summary and the emitted text span items and live here.
406
+ */
407
+ export interface SequentialCutoffSummaryState {
408
+ /** Latest full text per response-global summary index. */
409
+ summary: ResponseReasoningItem["summary"];
410
+ /** Canonical summary text already emitted as thinking deltas across all blocks. */
411
+ emitted: string;
412
+ }
413
+ export declare function createSequentialCutoffSummaryState(): SequentialCutoffSummaryState;
414
+ /** Chooses final reasoning text without making sequential-cutoff results disagree with emitted deltas. */
415
+ export declare function finalizeReasoningThinking(item: ResponseReasoningItem, streamedThinking: string, cutoff?: SequentialCutoffSummaryState): string;
397
416
  export declare function appendReasoningSummaryTextDelta(item: ResponseReasoningItem, block: ThinkingContent, delta: string, stream: AssistantMessageEventStream, output: AssistantMessage, contentIndex: number): void;
398
417
  export declare function appendReasoningSummaryPartDone(item: ResponseReasoningItem, block: ThinkingContent, stream: AssistantMessageEventStream, output: AssistantMessage, contentIndex: number): void;
418
+ /**
419
+ * Applies an atomic `response.reasoning_summary_text.done` snapshot.
420
+ *
421
+ * Sequential-cutoff summary indices are response-global: later reasoning items
422
+ * replay earlier sections, resend the accumulated summary as one part, or
423
+ * complete without new sections. The canonical summary is rebuilt in `state`
424
+ * (spanning items) and only its append-only suffix is emitted into the current
425
+ * block. Divergent corrections stay buffered until finalization so delta
426
+ * consumers never receive suffixes based on unseen replacement text.
427
+ */
428
+ export declare function applyReasoningSummaryDone(state: SequentialCutoffSummaryState, block: ThinkingContent, text: string, summaryIndex: number, stream: AssistantMessageEventStream, output: AssistantMessage, contentIndex: number): void;
399
429
  export declare function appendMessageContentPart(item: ResponseOutputMessage, part: ResponseContentPartAddedEvent["part"] | undefined): void;
400
430
  export declare function appendMessageTextDelta(item: ResponseOutputMessage, block: TextContent, delta: string, stream: AssistantMessageEventStream, output: AssistantMessage, contentIndex: number, partType: "output_text" | "refusal"): void;
401
431
  export declare function accumulateToolCallArgumentsDelta(block: ResponsesToolCallBlock, delta: string, stream: AssistantMessageEventStream, output: AssistantMessage, contentIndex: number): void;
@@ -0,0 +1,6 @@
1
+ export declare const loginNovita: (options: import("./oauth/index.js").OAuthController) => Promise<string>;
2
+ export declare const novitaProvider: {
3
+ id: "novita";
4
+ name: string;
5
+ login: (options: import("./oauth/index.js").OAuthController) => Promise<string>;
6
+ };
@@ -0,0 +1,25 @@
1
+ /** Result returned by one OAuth device-code polling attempt. */
2
+ export type OAuthDeviceCodePollResult<T> = {
3
+ status: "complete";
4
+ value: T;
5
+ } | {
6
+ status: "pending";
7
+ } | {
8
+ status: "slow_down";
9
+ } | {
10
+ status: "failed";
11
+ message: string;
12
+ };
13
+ /** Options for polling an RFC 8628-style OAuth device-code flow. */
14
+ export interface OAuthDeviceCodeFlowOptions<T> {
15
+ /** Poll the provider once and classify the response. */
16
+ poll(): OAuthDeviceCodePollResult<T> | Promise<OAuthDeviceCodePollResult<T>>;
17
+ /** Provider-requested polling cadence; defaults to RFC 8628's five seconds. */
18
+ intervalSeconds?: number;
19
+ /** Provider-issued expiry window for the device code. */
20
+ expiresInSeconds?: number;
21
+ /** Cancels the flow with the legacy "Login cancelled" error. */
22
+ signal?: AbortSignal;
23
+ }
24
+ /** Poll an OAuth device-code flow until completion, provider failure, timeout, or cancellation. */
25
+ export declare function pollOAuthDeviceCodeFlow<T>(options: OAuthDeviceCodeFlowOptions<T>): Promise<T>;
@@ -1,30 +1,6 @@
1
1
  import type { OAuthCredentials, OAuthProvider, OAuthProviderId, OAuthProviderInfo, OAuthProviderInterface } from "./types.js";
2
+ export * from "./device-code.js";
2
3
  export type * from "./types.js";
3
- /** Result returned by one OAuth device-code polling attempt. */
4
- export type OAuthDeviceCodePollResult<T> = {
5
- status: "complete";
6
- value: T;
7
- } | {
8
- status: "pending";
9
- } | {
10
- status: "slow_down";
11
- } | {
12
- status: "failed";
13
- message: string;
14
- };
15
- /** Options for polling an RFC 8628-style OAuth device-code flow. */
16
- export interface OAuthDeviceCodeFlowOptions<T> {
17
- /** Poll the provider once and classify the response. */
18
- poll(): OAuthDeviceCodePollResult<T> | Promise<OAuthDeviceCodePollResult<T>>;
19
- /** Provider-requested polling cadence; defaults to RFC 8628's five seconds. */
20
- intervalSeconds?: number;
21
- /** Provider-issued expiry window for the device code. */
22
- expiresInSeconds?: number;
23
- /** Cancels the flow with the legacy "Login cancelled" error. */
24
- signal?: AbortSignal;
25
- }
26
- /** Poll an OAuth device-code flow until completion, provider failure, timeout, or cancellation. */
27
- export declare function pollOAuthDeviceCodeFlow<T>(options: OAuthDeviceCodeFlowOptions<T>): Promise<T>;
28
4
  /**
29
5
  * Register a custom OAuth provider.
30
6
  */