@code-yeongyu/senpi-ai 2026.10.11 → 2026.10.12

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.
@@ -27,8 +27,10 @@ import { normalizeToolCallId } from "../utils/tool-call-id.js";
27
27
  import { sendWithForcedToolChoiceFallback } from "../utils/tool-choice-fallback.js";
28
28
  import { resolveRootObjectSchema } from "../utils/tool-schema-compat.js";
29
29
  import { getCurrentTools, getDeclaredTools, getInitialSystemMessage, hasToolRedefinitions, normalizeContext, resolveTranscript, } from "../utils/transcript.js";
30
+ import { isAnthropicWebSearchReplayBlock, isReplayableAnthropicProviderNativeBlock, } from "./anthropic-native-replay-blocks.js";
30
31
  import { sanitizeAnthropicToolPairs } from "./anthropic-tool-pairs.js";
31
32
  import { demoteToolReferenceReplay, demoteUnavailableToolReferences } from "./anthropic-tool-references.js";
33
+ import { demoteExpiredWebSearchReplay, expiredWebSearchReplayIds, isExpiredWebSearchContentError, } from "./anthropic-web-search-expiry.js";
32
34
  import { resolveCloudflareBaseUrl } from "./cloudflare.js";
33
35
  import { getJsonSchemaToolParameters, resolveJsonSchemaStrictSampling, } from "./constrained-sampling.js";
34
36
  import { withGitHubCopilotFailureNote } from "./github-copilot-errors.js";
@@ -243,6 +245,8 @@ function supportsMidConvoToolChanges(model) {
243
245
  const unsignedThinkingTextReplayFallbacks = new Set();
244
246
  // Endpoints that rejected a replayed tool_reference for one conversation (senpi #2568).
245
247
  const toolReferenceReplayFallbacks = new Set();
248
+ // `${fallbackKey}\u0000${tool_use_id}` of web search results whose encrypted payload expired (senpi #3201).
249
+ const expiredWebSearchReplays = new Set();
246
250
  registerSessionResourceCleanup((sessionId) => {
247
251
  // One small entry per (session, base URL, model) that ever hit the fallback;
248
252
  // drop the session's entries at teardown so long-lived hosts do not collect
@@ -250,10 +254,15 @@ registerSessionResourceCleanup((sessionId) => {
250
254
  if (sessionId === undefined) {
251
255
  unsignedThinkingTextReplayFallbacks.clear();
252
256
  toolReferenceReplayFallbacks.clear();
257
+ expiredWebSearchReplays.clear();
253
258
  return;
254
259
  }
255
260
  const prefix = `${sessionId}\u0000`;
256
- for (const fallbacks of [unsignedThinkingTextReplayFallbacks, toolReferenceReplayFallbacks]) {
261
+ for (const fallbacks of [
262
+ unsignedThinkingTextReplayFallbacks,
263
+ toolReferenceReplayFallbacks,
264
+ expiredWebSearchReplays,
265
+ ]) {
257
266
  for (const key of fallbacks) {
258
267
  if (key.startsWith(prefix))
259
268
  fallbacks.delete(key);
@@ -355,26 +364,6 @@ let federationClient;
355
364
  function isRecord(value) {
356
365
  return typeof value === "object" && value !== null;
357
366
  }
358
- const REPLAYABLE_ANTHROPIC_PROVIDER_NATIVE_TYPES = new Set([
359
- "server_tool_use",
360
- "web_search_tool_result",
361
- "web_fetch_tool_result",
362
- "code_execution_tool_result",
363
- "bash_code_execution_tool_result",
364
- "text_editor_code_execution_tool_result",
365
- "tool_search_tool_result",
366
- "container_upload",
367
- // The server-side fallback marker (`fallback`, server-side-fallback-2026-06-01
368
- // beta) is deliberately absent: the Messages API rejects it as an *input* tag
369
- // ("Input tag 'fallback' found using 'type' does not match any of the expected
370
- // tags"), so replaying it 400s every subsequent same-model request. The stored
371
- // marker is audit metadata and still drives declined-attempt pruning in
372
- // convertMessages (see lastAnthropicFallbackBoundary and
373
- // collectDiscardedFallbackToolCallIds); blocks after it replay verbatim.
374
- ]);
375
- function isReplayableAnthropicProviderNativeBlock(raw) {
376
- return isRecord(raw) && typeof raw.type === "string" && REPLAYABLE_ANTHROPIC_PROVIDER_NATIVE_TYPES.has(raw.type);
377
- }
378
367
  function isSameAnthropicModel(message, model) {
379
368
  return message.provider === model.provider && message.api === model.api && message.model === model.id;
380
369
  }
@@ -408,17 +397,6 @@ function isAnthropicServerToolUseBlock(raw) {
408
397
  function isProviderNativeToolUseBlock(raw) {
409
398
  return isRecord(raw) && (raw.type === "server_tool_use" || raw.type === "mcp_tool_use");
410
399
  }
411
- // Endpoints without `supportsWebSearch` reject replayed web-search server-tool
412
- // blocks (kimi-coding 400s with `tool_call_id is not found`), wedging every
413
- // subsequent request of the session. Dropping the pair loses the searched
414
- // context but keeps the conversation usable.
415
- function isAnthropicWebSearchReplayBlock(raw) {
416
- if (!isRecord(raw))
417
- return false;
418
- if (raw.type === "web_search_tool_result")
419
- return true;
420
- return raw.type === "server_tool_use" && raw.name === "web_search";
421
- }
422
400
  // The user turn a pending server tool can survive is one that carries only
423
401
  // tool results. Anything else the wire would emit — real text, an image —
424
402
  // closes the assistant turn (the API then 400s the still-open use). A blank
@@ -448,7 +426,7 @@ function collectProviderNativeToolPairing(messages, model, deferredToolNames, no
448
426
  if (block.type !== "providerNative" || !isRecord(block.raw))
449
427
  continue;
450
428
  const raw = block.raw;
451
- if (typeof raw.type !== "string" || !REPLAYABLE_ANTHROPIC_PROVIDER_NATIVE_TYPES.has(raw.type))
429
+ if (!isReplayableAnthropicProviderNativeBlock(raw))
452
430
  continue;
453
431
  if (isProviderNativeToolUseBlock(raw) && typeof raw.id === "string")
454
432
  pendingUseIds.add(raw.id);
@@ -457,7 +435,7 @@ function collectProviderNativeToolPairing(messages, model, deferredToolNames, no
457
435
  if (block.type !== "providerNative" || !isRecord(block.raw))
458
436
  continue;
459
437
  const raw = block.raw;
460
- if (typeof raw.type !== "string" || !REPLAYABLE_ANTHROPIC_PROVIDER_NATIVE_TYPES.has(raw.type))
438
+ if (!isReplayableAnthropicProviderNativeBlock(raw))
461
439
  continue;
462
440
  const toolUseId = raw.tool_use_id;
463
441
  if (typeof toolUseId !== "string")
@@ -1016,6 +994,15 @@ export const stream = (model, context, options) => {
1016
994
  : getAnthropicCompat(model).unsignedThinkingReplay;
1017
995
  let demoteReferenceReplay = fallbackKey !== undefined && toolReferenceReplayFallbacks.has(fallbackKey);
1018
996
  let requestReplaysReferences = false;
997
+ const expiredSearchPrefix = fallbackKey === undefined ? undefined : `${fallbackKey}\u0000`;
998
+ const expiredSearchIds = new Set();
999
+ if (expiredSearchPrefix !== undefined) {
1000
+ for (const key of expiredWebSearchReplays) {
1001
+ if (key.startsWith(expiredSearchPrefix))
1002
+ expiredSearchIds.add(key.slice(expiredSearchPrefix.length));
1003
+ }
1004
+ }
1005
+ let lastSentParams;
1019
1006
  const createRequest = async () => {
1020
1007
  let params = buildParams(model, normalizedContext, isOAuth, options, unsignedThinkingReplay);
1021
1008
  const nextParams = await options?.onPayload?.(params, model);
@@ -1029,6 +1016,8 @@ export const stream = (model, context, options) => {
1029
1016
  requestReplaysReferences = withoutReferenceReplay !== params;
1030
1017
  if (demoteReferenceReplay)
1031
1018
  params = withoutReferenceReplay;
1019
+ params = demoteExpiredWebSearchReplay(params, expiredSearchIds);
1020
+ lastSentParams = params;
1032
1021
  params = sanitizeAnthropicToolPairs(params);
1033
1022
  const payloadRequestMetadata = extractPayloadRequestMetadata(params);
1034
1023
  params = payloadRequestMetadata.params;
@@ -1053,6 +1042,28 @@ export const stream = (model, context, options) => {
1053
1042
  });
1054
1043
  return { params: sent.params, response: sent.result };
1055
1044
  };
1045
+ // True when the error names web search payloads this request had not demoted yet.
1046
+ const markNewlyExpiredSearches = (error) => {
1047
+ if (!isExpiredWebSearchContentError(error) || lastSentParams === undefined)
1048
+ return false;
1049
+ const newlyExpired = expiredWebSearchReplayIds(lastSentParams, error).filter((id) => !expiredSearchIds.has(id));
1050
+ for (const id of newlyExpired) {
1051
+ expiredSearchIds.add(id);
1052
+ if (expiredSearchPrefix !== undefined)
1053
+ expiredWebSearchReplays.add(expiredSearchPrefix + id);
1054
+ }
1055
+ return newlyExpired.length > 0;
1056
+ };
1057
+ const createRequestDemotingExpiredSearches = async () => {
1058
+ try {
1059
+ return await createRequest();
1060
+ }
1061
+ catch (error) {
1062
+ if (markNewlyExpiredSearches(error))
1063
+ return createRequestDemotingExpiredSearches();
1064
+ throw error;
1065
+ }
1066
+ };
1056
1067
  let requestOutcome;
1057
1068
  try {
1058
1069
  requestOutcome = await retryProviderRequest(async () => {
@@ -1072,6 +1083,8 @@ export const stream = (model, context, options) => {
1072
1083
  toolReferenceReplayFallbacks.add(fallbackKey);
1073
1084
  return createRequest();
1074
1085
  }
1086
+ if (markNewlyExpiredSearches(error))
1087
+ return createRequestDemotingExpiredSearches();
1075
1088
  if (await retryWithNewerClaudeCode(error)) {
1076
1089
  try {
1077
1090
  return await createRequest();
@@ -0,0 +1,4 @@
1
+ import type { BetaContentBlockParam } from "@anthropic-ai/sdk/resources/beta/messages/messages.js";
2
+ export declare function isReplayableAnthropicProviderNativeBlock(raw: unknown): raw is BetaContentBlockParam;
3
+ export declare function isAnthropicWebSearchReplayBlock(raw: unknown): boolean;
4
+ //# sourceMappingURL=anthropic-native-replay-blocks.d.ts.map
@@ -0,0 +1,28 @@
1
+ const replayableTypes = new Set([
2
+ "server_tool_use",
3
+ "web_search_tool_result",
4
+ // GLM's Anthropic-compatible coding endpoint returns this server-result shape.
5
+ // Pairing still requires a preceding same-model server_tool_use.
6
+ "tool_result",
7
+ "web_fetch_tool_result",
8
+ "code_execution_tool_result",
9
+ "bash_code_execution_tool_result",
10
+ "text_editor_code_execution_tool_result",
11
+ "tool_search_tool_result",
12
+ "container_upload",
13
+ // Stored fallback markers are audit metadata, not valid Messages input tags.
14
+ ]);
15
+ function isRecord(value) {
16
+ return value !== null && typeof value === "object";
17
+ }
18
+ export function isReplayableAnthropicProviderNativeBlock(raw) {
19
+ return isRecord(raw) && typeof raw.type === "string" && replayableTypes.has(raw.type);
20
+ }
21
+ export function isAnthropicWebSearchReplayBlock(raw) {
22
+ if (!isRecord(raw))
23
+ return false;
24
+ if (raw.type === "web_search_tool_result" || raw.type === "tool_result")
25
+ return true;
26
+ return raw.type === "server_tool_use" && raw.name === "web_search";
27
+ }
28
+ //# sourceMappingURL=anthropic-native-replay-blocks.js.map
@@ -0,0 +1,10 @@
1
+ import type { MessageCreateParamsStreaming } from "@anthropic-ai/sdk/resources/beta/messages/messages.js";
2
+ export declare function isExpiredWebSearchContentError(error: unknown): error is Error;
3
+ /**
4
+ * The `tool_use_id`s of the web search results the rejected request replayed
5
+ * at or before the message the API named. Without a parsable index every
6
+ * replayed result counts as expired.
7
+ */
8
+ export declare function expiredWebSearchReplayIds(params: MessageCreateParamsStreaming, error: Error): string[];
9
+ export declare function demoteExpiredWebSearchReplay(params: MessageCreateParamsStreaming, expired: ReadonlySet<string>): MessageCreateParamsStreaming;
10
+ //# sourceMappingURL=anthropic-web-search-expiry.d.ts.map
@@ -0,0 +1,104 @@
1
+ /**
2
+ * The opaque `encrypted_content` of a native web search result is only valid
3
+ * for the account that ran the search (senpi #3201). Same-model replay keeps
4
+ * the payload byte-for-byte (#208), so once a request is served by another
5
+ * account (credential rotation, a multi-account gateway) every later request
6
+ * on that model fails with "messages.N.content.0: Invalid `encrypted_content` in
7
+ * `search_result` block" and the session only moves on through a model
8
+ * fallback. Stripping the field is not an option: the API requires it (#150).
9
+ *
10
+ * Recovery demotes expired search pairs to plain text: the `server_tool_use`
11
+ * becomes a note naming its query and the `web_search_tool_result` a list of
12
+ * the result titles and URLs. Only pairs whose result sits at or before the
13
+ * rejected message are demoted, because a search is never fresher than a
14
+ * later one; newer results keep replaying verbatim.
15
+ */
16
+ const EXPIRED_SEARCH_CONTENT = /Invalid `encrypted_content` in `search_result` block/i;
17
+ const REJECTED_MESSAGE_INDEX = /messages\.(\d+)\.content\.\d+: Invalid `encrypted_content`/i;
18
+ function isRecord(value) {
19
+ return typeof value === "object" && value !== null;
20
+ }
21
+ export function isExpiredWebSearchContentError(error) {
22
+ return (error instanceof Error &&
23
+ "status" in error &&
24
+ error.status === 400 &&
25
+ EXPIRED_SEARCH_CONTENT.test(error.message));
26
+ }
27
+ function webSearchResultIds(message) {
28
+ if (message.role !== "assistant" || !Array.isArray(message.content))
29
+ return [];
30
+ const ids = [];
31
+ for (const block of message.content) {
32
+ if (isRecord(block) && block.type === "web_search_tool_result" && typeof block.tool_use_id === "string") {
33
+ ids.push(block.tool_use_id);
34
+ }
35
+ }
36
+ return ids;
37
+ }
38
+ /**
39
+ * The `tool_use_id`s of the web search results the rejected request replayed
40
+ * at or before the message the API named. Without a parsable index every
41
+ * replayed result counts as expired.
42
+ */
43
+ export function expiredWebSearchReplayIds(params, error) {
44
+ const match = REJECTED_MESSAGE_INDEX.exec(error.message);
45
+ const lastIndex = match?.[1] === undefined ? params.messages.length - 1 : Number(match[1]);
46
+ return params.messages.slice(0, lastIndex + 1).flatMap(webSearchResultIds);
47
+ }
48
+ function searchQuery(block) {
49
+ const input = block.input;
50
+ return isRecord(input) && typeof input.query === "string" ? input.query : undefined;
51
+ }
52
+ function demotedResultText(block) {
53
+ const results = Array.isArray(block.content) ? block.content : [];
54
+ const lines = [];
55
+ for (const result of results) {
56
+ if (!isRecord(result) || result.type !== "web_search_result")
57
+ continue;
58
+ const title = typeof result.title === "string" ? result.title : "";
59
+ const url = typeof result.url === "string" ? result.url : "";
60
+ lines.push(`- ${title} (${url})`);
61
+ }
62
+ if (lines.length === 0)
63
+ return "Web search returned no results.";
64
+ return ["Web search results (page contents no longer available):", ...lines].join("\n");
65
+ }
66
+ function demoteBlock(block, expired) {
67
+ if (!isRecord(block))
68
+ return undefined;
69
+ if (block.type === "server_tool_use" && block.name === "web_search" && typeof block.id === "string") {
70
+ if (!expired.has(block.id))
71
+ return undefined;
72
+ const query = searchQuery(block);
73
+ return { type: "text", text: query === undefined ? "Searched the web." : `Searched the web for: ${query}` };
74
+ }
75
+ if (block.type === "web_search_tool_result" && typeof block.tool_use_id === "string") {
76
+ if (!expired.has(block.tool_use_id))
77
+ return undefined;
78
+ return { type: "text", text: demotedResultText(block) };
79
+ }
80
+ return undefined;
81
+ }
82
+ export function demoteExpiredWebSearchReplay(params, expired) {
83
+ if (expired.size === 0)
84
+ return params;
85
+ let changed = false;
86
+ const messages = params.messages.map((message) => {
87
+ if (message.role !== "assistant" || !Array.isArray(message.content))
88
+ return message;
89
+ let messageChanged = false;
90
+ const content = message.content.map((block) => {
91
+ const demoted = demoteBlock(block, expired);
92
+ if (demoted === undefined)
93
+ return block;
94
+ messageChanged = true;
95
+ return demoted;
96
+ });
97
+ if (!messageChanged)
98
+ return message;
99
+ changed = true;
100
+ return { ...message, content };
101
+ });
102
+ return changed ? { ...params, messages } : params;
103
+ }
104
+ //# sourceMappingURL=anthropic-web-search-expiry.js.map
@@ -322,6 +322,25 @@ export function convertResponsesMessages(model, context, allowedToolCallProvider
322
322
  // Signed foreign blocks with no text are intentionally dropped.
323
323
  }
324
324
  else if (block.type === "providerNative") {
325
+ // Responses accepts its completed web_search_call output items
326
+ // in the next input. Keep them only on the originating route/model;
327
+ // encrypted/native state must never cross provider boundaries.
328
+ // https://developers.openai.com/api/docs/guides/conversation-state
329
+ // Verified against the ChatGPT subscription endpoint for senpi#3122.
330
+ const raw = block.raw;
331
+ if (isSameModel &&
332
+ block.subtype === "web_search_call" &&
333
+ raw !== null &&
334
+ typeof raw === "object" &&
335
+ "type" in raw &&
336
+ raw.type === "web_search_call" &&
337
+ "id" in raw &&
338
+ typeof raw.id === "string" &&
339
+ "action" in raw &&
340
+ "status" in raw &&
341
+ (raw.status === "completed" || raw.status === "failed")) {
342
+ output.push(raw);
343
+ }
325
344
  }
326
345
  else if (block.type === "text") {
327
346
  const textBlock = block;
@@ -63,6 +63,7 @@ function getCompat(model, env) {
63
63
  supportsWebSocket: model.compat?.supportsWebSocket ?? isNativeEndpoint,
64
64
  supportsRemoteCompactionV2: model.compat?.supportsRemoteCompactionV2 ?? isNativeEndpoint,
65
65
  supportsWebSearchPreview: model.compat?.supportsWebSearchPreview ?? isNativeEndpoint,
66
+ webSearchToolType: model.compat?.webSearchToolType ?? "web_search_preview",
66
67
  supportsImageGeneration: model.compat?.supportsImageGeneration ?? isNativeEndpoint,
67
68
  supportsStrictMode: model.compat?.supportsStrictMode ?? false,
68
69
  supportsOpenAIGrammarTools: model.compat?.supportsOpenAIGrammarTools ?? false,
@@ -102,7 +103,10 @@ function isRecord(value) {
102
103
  return typeof value === "object" && value !== null;
103
104
  }
104
105
  function isOpenAiWebSearchPreviewTool(value) {
105
- return isRecord(value) && (value.type === "web_search_preview" || value.type === "web_search_preview_2025_03_11");
106
+ return (isRecord(value) &&
107
+ (value.type === "web_search" ||
108
+ value.type === "web_search_preview" ||
109
+ value.type === "web_search_preview_2025_03_11"));
106
110
  }
107
111
  function sanitizeUnsupportedNativeTools(params, compat) {
108
112
  if (compat.supportsWebSearchPreview) {
package/dist/model.d.ts CHANGED
@@ -44,8 +44,12 @@ export interface Model<TApi extends Api> extends BaseModel<TApi> {
44
44
  * probe; `modelSupportsAssistantPrefill` also applies the request settings.
45
45
  */
46
46
  supportsAssistantPrefill?: boolean;
47
- /** Compatibility overrides for OpenAI-compatible APIs. If not set, auto-detected from baseUrl. */
48
- compat?: TApi extends "openai-completions" ? OpenAICompletionsCompat : TApi extends "openai-responses" | "openai-codex-responses" | "azure-openai-responses" ? OpenAIResponsesCompat : TApi extends "anthropic-messages" ? AnthropicMessagesCompat : TApi extends "bedrock-converse-stream" ? BedrockCompat : TApi extends "mistral-conversations" ? MistralConversationsCompat : TApi extends "cursor-agent" ? CursorAgentCompat : TApi extends "devin-agent" ? DevinAgentCompat : never;
47
+ /** API compatibility overrides. Hosted search on unverified routes requires explicit opt-in. */
48
+ compat?: TApi extends "openai-completions" ? OpenAICompletionsCompat : TApi extends "openai-responses" | "openai-codex-responses" | "azure-openai-responses" ? OpenAIResponsesCompat : TApi extends "anthropic-messages" ? AnthropicMessagesCompat : TApi extends "bedrock-converse-stream" ? BedrockCompat : TApi extends "mistral-conversations" ? MistralConversationsCompat : TApi extends "cursor-agent" ? CursorAgentCompat : TApi extends "devin-agent" ? DevinAgentCompat : TApi extends "google-generative-ai" | "google-vertex" ? GoogleCompat : never;
49
+ }
50
+ export interface GoogleCompat {
51
+ /** Opt in to Google Search grounding, including mixed function-tool requests. */
52
+ supportsWebSearch?: boolean;
49
53
  }
50
54
  /** Devin (Cascade) model metadata the transport branches on. */
51
55
  export interface DevinAgentCompat {
@@ -1 +1 @@
1
- {"schemaVersion":6,"generatedAt":"2026-10-11T10:01:11.497Z","structureHash":"0989a1c88b40439cecf9d8a82fe466628aa29d2c7cc597ed79540d082d7890d6","files":{"alibaba-token-plan.json":"16b3c6c78d72c73ca34a1e79ce71c0cf36ba409d02e83a17396ce0949a1d5363","amazon-bedrock.json":"4a95e6bf974e5ca967d5c050df580262e13573e42b3186edb448fa11a302f09f","ant-ling.json":"628feab3ef6c7d80ce96f75999804e1d9f05fec3851e5302e30fff3b69db90f6","anthropic.json":"111384e9f5845e0247bd34edf2400ef7720fcbdac140b944cf8878192d8bd6ab","azure-openai-responses.json":"a3e52bd78f0220aa32bce519e13955b8e6e567860416343844cbe19902f4a682","bai.json":"7e6861aaf27d8af34e1771c6092602194fcec0a0046e6adfab9c3ee54d32b99f","baseten.json":"1fcdab8daf2881bd099eb08f9416f7df5bf39975937d2a63b841542bd032f2e6","cerebras.json":"3eccb58c5de3d0dc7ba49dc6e477ba29f00cb3150ce0a35cc90d59e6b5ab368e","chatgpt-subscription.json":"2fbeb0141b29c340542798bce53422b93bef026a13420986e87fca89353e0aa2","cloudflare-ai-gateway.json":"5c8782fdbf2477f620b238da4344b0bcc0948b8c177461e63e7e5ba256f769c7","cloudflare-workers-ai.json":"f351e80493dea7b7a2c31dceb086ee804a88d67c5f8a3c823ea907991fe5d659","deepseek.json":"10a296fb3e898f7715c80890c8af0af4f5fd58f22dbcd6612fdc5d762157ccdc","fireworks.json":"c3dc21dc2e95428fc9a38e3840c05bbf90f94e4c25dee0eedf0b385b49ff65a4","github-copilot.json":"2c5a84983477a7c4f6c001088a1e043ee959ce58c99fea6eb843e0286228664b","google-vertex.json":"96ecc19bf20a706f99ae658b021a0ee5438146119e1e99de5fd824a01fcfd81b","google.json":"c0f5a633e5e5a5044432db3e537f4bc674d4de18df09325c6349547fcc13cabe","groq.json":"910952ad9dad07856983459d63fce0148dba1203edd7b10d801a77c5824f3405","huggingface.json":"6399e958790a9d90c21fb55d1cbef8569427a1ceb28de86dadeb3b4454ecfade","meta.json":"0c7e9a370a7005c5a89dc94f0f93bc67b8935c3f802de324f11af6ff56fff429","minimax-cn.json":"f962c20ee6a6a342820f778e9dc363a18a524bf11998f6e2c57f2989915d62e5","minimax.json":"17a432f80d0ea6dd26eade80a4314250d3a855678601728a5f70dd8fa0d21dd2","mistral.json":"27aa66c71a0504b53dc87ec194286fa7e70b99747fc8df9b709b23b3548afe50","moonshotai-cn.json":"18954b55dc5edecc174d8a07a2c5993416dd9d3ce52e411438035c16ee982e8e","moonshotai.json":"62d08fd5beead025a56d5f2e4227d8516b9c5034275b1b36d761a8625918f2b9","nvidia.json":"a75e963dc81779e3eec01c051b12277c15ec37c5b94ab51ece9e9ccb3b16407c","openai.json":"9104538118053eed57f90852332b6ad274a4e4792389bdbc9cfca1ae400c705a","opencode-go.json":"48ff011f3e171f977cfed2928272667e9361f13a508e5994f00f2241f6a23419","opencode.json":"882b039f64ef266da7b02d30aee9255c191e16f0600ef5494022bc1ef746f749","opengateway.json":"dd4259885ea6045d723b3abaae06657dfcce07b9ce3c2b0300220ac661432859","openrouter.json":"9484c1583eb1d419e89ffe258cd4efb7bb793666ae09c94db545f400fe0d628e","qwen-token-plan-cn.json":"bd36a6d9cc2048deafacc85f7f0f2e51868c8b7aa09502e3e4e60e3e8b76f690","qwen-token-plan-individual.json":"35ffb0ba1a1ce3f68fc73262dd5e07fbcb5bf5911ad1e6e17bc0621e2894676a","qwen-token-plan.json":"ca27e49e62965221badead8e867b2007035c6b6a15a97c47219bd23d2c83c2b1","radius.json":"8214122385e8e4c4bc2e1d2a7d032f9e4c654da3bfd3ac8c5d4396e1b522e53a","together.json":"bbd7fad86cacfefe3d3d61f6638f22e9b6f5d575722fd1112a16aafe0485c46d","typesafe.json":"a4429a2f696d5cc5273969af61a7310bda07d6bdcd27bf9ac9c76c534cc43716","venice.json":"3604c88c46dd3e4151b833927c6f87bcc165d0999a4339b32db2ad74a9ff173f","vercel-ai-gateway.json":"9859481f690a9a9a8131af3abfadf5378b2d1ef51990041da4465de3f1e4ab78","xai.json":"d7771a1450b21c1f6aee887ca6fea61b6e7b3fc13b4dee5cf72a71134fe623bc","xiaomi-token-plan-ams.json":"4dd8f838e21d7aa7caf3122d0b0b1e5a02a33bc012b96e6a75bd119334152d7a","xiaomi-token-plan-cn.json":"46414ff49973b95a0c14bd33e8992cc1938a50ce2c7cea9e2e5cc02de8f1df31","xiaomi-token-plan-sgp.json":"f5b3f66bf7bb7238592d4a9667cad983a008d7539a66e9896b02422622800935","xiaomi.json":"8b62c158d55d5a165f35cd72c1fc82ab89ff8e73f08960105fc41b822f236f69","zai-coding-cn.json":"2a7f59d15f588a97d218997883f2506dfc52d3ee320697d39f14213a050fc912","zai.json":"e9cc408e1756de8abc70148d63d89d11a63c65b7ef06ad0661cd1328e4209ba3"}}
1
+ {"schemaVersion":6,"generatedAt":"2026-10-12T15:26:30.855Z","structureHash":"f696be8fbb6471faefafe7b9ae99f4c0db4391398bf4108f56024ed2712ebf88","files":{"alibaba-token-plan.json":"16b3c6c78d72c73ca34a1e79ce71c0cf36ba409d02e83a17396ce0949a1d5363","amazon-bedrock.json":"4a95e6bf974e5ca967d5c050df580262e13573e42b3186edb448fa11a302f09f","ant-ling.json":"628feab3ef6c7d80ce96f75999804e1d9f05fec3851e5302e30fff3b69db90f6","anthropic.json":"111384e9f5845e0247bd34edf2400ef7720fcbdac140b944cf8878192d8bd6ab","azure-openai-responses.json":"a3e52bd78f0220aa32bce519e13955b8e6e567860416343844cbe19902f4a682","bai.json":"7e6861aaf27d8af34e1771c6092602194fcec0a0046e6adfab9c3ee54d32b99f","baseten.json":"1fcdab8daf2881bd099eb08f9416f7df5bf39975937d2a63b841542bd032f2e6","cerebras.json":"3eccb58c5de3d0dc7ba49dc6e477ba29f00cb3150ce0a35cc90d59e6b5ab368e","chatgpt-subscription.json":"42b88c93d717b2a7469b71da7da5adf87347d0d9cc0f264b39117f0f940b51c0","cloudflare-ai-gateway.json":"5c8782fdbf2477f620b238da4344b0bcc0948b8c177461e63e7e5ba256f769c7","cloudflare-workers-ai.json":"f351e80493dea7b7a2c31dceb086ee804a88d67c5f8a3c823ea907991fe5d659","deepseek.json":"10a296fb3e898f7715c80890c8af0af4f5fd58f22dbcd6612fdc5d762157ccdc","fireworks.json":"c3dc21dc2e95428fc9a38e3840c05bbf90f94e4c25dee0eedf0b385b49ff65a4","github-copilot.json":"2c5a84983477a7c4f6c001088a1e043ee959ce58c99fea6eb843e0286228664b","google-vertex.json":"96ecc19bf20a706f99ae658b021a0ee5438146119e1e99de5fd824a01fcfd81b","google.json":"c0f5a633e5e5a5044432db3e537f4bc674d4de18df09325c6349547fcc13cabe","groq.json":"910952ad9dad07856983459d63fce0148dba1203edd7b10d801a77c5824f3405","huggingface.json":"6399e958790a9d90c21fb55d1cbef8569427a1ceb28de86dadeb3b4454ecfade","meta.json":"0c7e9a370a7005c5a89dc94f0f93bc67b8935c3f802de324f11af6ff56fff429","minimax-cn.json":"f962c20ee6a6a342820f778e9dc363a18a524bf11998f6e2c57f2989915d62e5","minimax.json":"17a432f80d0ea6dd26eade80a4314250d3a855678601728a5f70dd8fa0d21dd2","mistral.json":"27aa66c71a0504b53dc87ec194286fa7e70b99747fc8df9b709b23b3548afe50","moonshotai-cn.json":"18954b55dc5edecc174d8a07a2c5993416dd9d3ce52e411438035c16ee982e8e","moonshotai.json":"62d08fd5beead025a56d5f2e4227d8516b9c5034275b1b36d761a8625918f2b9","nvidia.json":"a75e963dc81779e3eec01c051b12277c15ec37c5b94ab51ece9e9ccb3b16407c","openai.json":"9104538118053eed57f90852332b6ad274a4e4792389bdbc9cfca1ae400c705a","opencode-go.json":"48ff011f3e171f977cfed2928272667e9361f13a508e5994f00f2241f6a23419","opencode.json":"882b039f64ef266da7b02d30aee9255c191e16f0600ef5494022bc1ef746f749","opengateway.json":"008c69b83d5fc98382e5463d77f701cdd87bb231c59830eabbbd453038d5a59f","openrouter.json":"4287f52f3e42a1873c09b72a9e6870c90718e0c71ed0b58c2f15da9e7271a529","qwen-token-plan-cn.json":"bd36a6d9cc2048deafacc85f7f0f2e51868c8b7aa09502e3e4e60e3e8b76f690","qwen-token-plan-individual.json":"35ffb0ba1a1ce3f68fc73262dd5e07fbcb5bf5911ad1e6e17bc0621e2894676a","qwen-token-plan.json":"ca27e49e62965221badead8e867b2007035c6b6a15a97c47219bd23d2c83c2b1","radius.json":"8214122385e8e4c4bc2e1d2a7d032f9e4c654da3bfd3ac8c5d4396e1b522e53a","together.json":"bbd7fad86cacfefe3d3d61f6638f22e9b6f5d575722fd1112a16aafe0485c46d","typesafe.json":"a4429a2f696d5cc5273969af61a7310bda07d6bdcd27bf9ac9c76c534cc43716","venice.json":"3604c88c46dd3e4151b833927c6f87bcc165d0999a4339b32db2ad74a9ff173f","vercel-ai-gateway.json":"b63765fc532a52b85b98d6b5afe8be3a3838b1907ae116cb25cf3d029bd70f0c","xai.json":"d7771a1450b21c1f6aee887ca6fea61b6e7b3fc13b4dee5cf72a71134fe623bc","xiaomi-token-plan-ams.json":"4dd8f838e21d7aa7caf3122d0b0b1e5a02a33bc012b96e6a75bd119334152d7a","xiaomi-token-plan-cn.json":"46414ff49973b95a0c14bd33e8992cc1938a50ce2c7cea9e2e5cc02de8f1df31","xiaomi-token-plan-sgp.json":"f5b3f66bf7bb7238592d4a9667cad983a008d7539a66e9896b02422622800935","xiaomi.json":"8b62c158d55d5a165f35cd72c1fc82ab89ff8e73f08960105fc41b822f236f69","zai-coding-cn.json":"2a7f59d15f588a97d218997883f2506dfc52d3ee320697d39f14213a050fc912","zai.json":"e9cc408e1756de8abc70148d63d89d11a63c65b7ef06ad0661cd1328e4209ba3"}}
@@ -1 +1 @@
1
- {"openai-codex-responses":{"chat:gpt-5.3-codex-spark":{"id":"gpt-5.3-codex-spark","name":"GPT-5.3 Codex Spark","api":"openai-codex-responses","provider":"chatgpt-subscription","baseUrl":"https://chatgpt.com/backend-api","reasoning":true,"input":["text"],"cost":{"input":1.75,"output":14,"cacheRead":0.175,"cacheWrite":0},"contextWindow":128000,"maxTokens":128000,"thinkingLevelMap":{"xhigh":"xhigh","minimal":"low"},"compat":{"supportsOpenAIGrammarTools":true},"type":"chat"},"chat:gpt-5.5":{"id":"gpt-5.5","name":"GPT-5.5","api":"openai-codex-responses","provider":"chatgpt-subscription","baseUrl":"https://chatgpt.com/backend-api","reasoning":true,"input":["text","image"],"cost":{"input":5,"output":30,"cacheRead":0.5,"cacheWrite":0,"tiers":[{"inputTokensAbove":272000,"input":10,"output":45,"cacheRead":1,"cacheWrite":0}]},"contextWindow":272000,"maxTokens":128000,"thinkingLevelMap":{"xhigh":"xhigh","minimal":"low"},"compat":{"supportsOpenAIGrammarTools":true,"supportsToolSearch":true,"supportsMidConvoSystemMessages":true},"inputLimits":{"images":{"resize":{"maxWidth":2000,"maxHeight":2000,"maxBytes":4718592,"jpegQuality":80}}},"type":"chat"},"chat:gpt-5.6-luna":{"id":"gpt-5.6-luna","name":"GPT-5.6 Luna","api":"openai-codex-responses","provider":"chatgpt-subscription","baseUrl":"https://chatgpt.com/backend-api","reasoning":true,"input":["text","image"],"cost":{"input":0.2,"output":1.2,"cacheRead":0.02,"cacheWrite":0.25,"tiers":[{"inputTokensAbove":272000,"input":0.4,"output":1.8,"cacheRead":0.04,"cacheWrite":0.5}]},"contextWindow":272000,"maxTokens":128000,"thinkingLevelMap":{"xhigh":"xhigh","max":"max","minimal":"low"},"compat":{"supportsOpenAIGrammarTools":true,"supportsAdditionalTools":true,"supportsToolSearch":true,"supportsMidConvoSystemMessages":true},"inputLimits":{"images":{"resize":{"maxWidth":2000,"maxHeight":2000,"maxBytes":4718592,"jpegQuality":80}}},"type":"chat"},"chat:gpt-5.6-luna-fast":{"id":"gpt-5.6-luna-fast","name":"GPT-5.6 Luna Fast","api":"openai-codex-responses","provider":"chatgpt-subscription","baseUrl":"https://chatgpt.com/backend-api","reasoning":true,"input":["text","image"],"cost":{"input":0.2,"output":1.2,"cacheRead":0.02,"cacheWrite":0.25,"tiers":[{"inputTokensAbove":272000,"input":0.4,"output":1.8,"cacheRead":0.04,"cacheWrite":0.5}]},"contextWindow":272000,"maxTokens":128000,"thinkingLevelMap":{"xhigh":"xhigh","max":"max","minimal":"low"},"compat":{"supportsOpenAIGrammarTools":true,"supportsAdditionalTools":true,"supportsToolSearch":true,"supportsMidConvoSystemMessages":true},"inputLimits":{"images":{"resize":{"maxWidth":2000,"maxHeight":2000,"maxBytes":4718592,"jpegQuality":80}}},"upstreamModelId":"gpt-5.6-luna","serviceTier":"priority","type":"chat"},"chat:gpt-5.6-sol":{"id":"gpt-5.6-sol","name":"GPT-5.6 Sol","api":"openai-codex-responses","provider":"chatgpt-subscription","baseUrl":"https://chatgpt.com/backend-api","reasoning":true,"input":["text","image"],"cost":{"input":4,"output":20,"cacheRead":0.4,"cacheWrite":5,"tiers":[{"inputTokensAbove":272000,"input":8,"output":30,"cacheRead":0.8,"cacheWrite":10}]},"contextWindow":650000,"maxTokens":128000,"thinkingLevelMap":{"xhigh":"xhigh","max":"max","minimal":"low"},"compat":{"supportsOpenAIGrammarTools":true,"supportsAdditionalTools":true,"supportsToolSearch":true,"supportsMidConvoSystemMessages":true},"inputLimits":{"images":{"resize":{"maxWidth":2000,"maxHeight":2000,"maxBytes":4718592,"jpegQuality":80}}},"type":"chat"},"chat:gpt-5.6-sol-fast":{"id":"gpt-5.6-sol-fast","name":"GPT-5.6 Sol Fast","api":"openai-codex-responses","provider":"chatgpt-subscription","baseUrl":"https://chatgpt.com/backend-api","reasoning":true,"input":["text","image"],"cost":{"input":4,"output":20,"cacheRead":0.4,"cacheWrite":5,"tiers":[{"inputTokensAbove":272000,"input":8,"output":30,"cacheRead":0.8,"cacheWrite":10}]},"contextWindow":650000,"maxTokens":128000,"thinkingLevelMap":{"xhigh":"xhigh","max":"max","minimal":"low"},"compat":{"supportsOpenAIGrammarTools":true,"supportsAdditionalTools":true,"supportsToolSearch":true,"supportsMidConvoSystemMessages":true},"inputLimits":{"images":{"resize":{"maxWidth":2000,"maxHeight":2000,"maxBytes":4718592,"jpegQuality":80}}},"upstreamModelId":"gpt-5.6-sol","serviceTier":"priority","type":"chat"},"chat:gpt-5.6-terra":{"id":"gpt-5.6-terra","name":"GPT-5.6 Terra","api":"openai-codex-responses","provider":"chatgpt-subscription","baseUrl":"https://chatgpt.com/backend-api","reasoning":true,"input":["text","image"],"cost":{"input":2,"output":12,"cacheRead":0.2,"cacheWrite":2.5,"tiers":[{"inputTokensAbove":272000,"input":4,"output":18,"cacheRead":0.4,"cacheWrite":5}]},"contextWindow":272000,"maxTokens":128000,"thinkingLevelMap":{"xhigh":"xhigh","max":"max","minimal":"low"},"compat":{"supportsOpenAIGrammarTools":true,"supportsAdditionalTools":true,"supportsToolSearch":true,"supportsMidConvoSystemMessages":true},"inputLimits":{"images":{"resize":{"maxWidth":2000,"maxHeight":2000,"maxBytes":4718592,"jpegQuality":80}}},"type":"chat"},"chat:gpt-5.6-terra-fast":{"id":"gpt-5.6-terra-fast","name":"GPT-5.6 Terra Fast","api":"openai-codex-responses","provider":"chatgpt-subscription","baseUrl":"https://chatgpt.com/backend-api","reasoning":true,"input":["text","image"],"cost":{"input":2,"output":12,"cacheRead":0.2,"cacheWrite":2.5,"tiers":[{"inputTokensAbove":272000,"input":4,"output":18,"cacheRead":0.4,"cacheWrite":5}]},"contextWindow":272000,"maxTokens":128000,"thinkingLevelMap":{"xhigh":"xhigh","max":"max","minimal":"low"},"compat":{"supportsOpenAIGrammarTools":true,"supportsAdditionalTools":true,"supportsToolSearch":true,"supportsMidConvoSystemMessages":true},"inputLimits":{"images":{"resize":{"maxWidth":2000,"maxHeight":2000,"maxBytes":4718592,"jpegQuality":80}}},"upstreamModelId":"gpt-5.6-terra","serviceTier":"priority","type":"chat"},"chat:gpt-6-astra":{"id":"gpt-6-astra","name":"GPT-6 Astra","api":"openai-codex-responses","provider":"chatgpt-subscription","baseUrl":"https://chatgpt.com/backend-api","reasoning":true,"input":["text","image"],"cost":{"input":10,"output":50,"cacheRead":1,"cacheWrite":12.5,"tiers":[{"inputTokensAbove":272000,"input":20,"output":75,"cacheRead":2,"cacheWrite":25}]},"contextWindow":600000,"maxTokens":128000,"thinkingLevelMap":{"off":null,"minimal":null,"low":"low","medium":"medium","high":"high","xhigh":"xhigh","max":"max"},"compat":{"supportsOpenAIGrammarTools":true,"supportsAdditionalTools":true,"supportsToolSearch":true,"supportsMidConvoSystemMessages":true,"supportsConfigurationUpdate":true},"inputLimits":{"images":{"resize":{"maxWidth":2000,"maxHeight":2000,"maxBytes":4718592,"jpegQuality":80}}},"type":"chat"},"chat:gpt-6-astra-fast":{"id":"gpt-6-astra-fast","name":"GPT-6 Astra Fast","api":"openai-codex-responses","provider":"chatgpt-subscription","baseUrl":"https://chatgpt.com/backend-api","reasoning":true,"input":["text","image"],"cost":{"input":10,"output":50,"cacheRead":1,"cacheWrite":12.5,"tiers":[{"inputTokensAbove":272000,"input":20,"output":75,"cacheRead":2,"cacheWrite":25}]},"contextWindow":600000,"maxTokens":128000,"thinkingLevelMap":{"off":null,"minimal":null,"low":"low","medium":"medium","high":"high","xhigh":"xhigh","max":"max"},"compat":{"supportsOpenAIGrammarTools":true,"supportsAdditionalTools":true,"supportsToolSearch":true,"supportsMidConvoSystemMessages":true,"supportsConfigurationUpdate":true},"inputLimits":{"images":{"resize":{"maxWidth":2000,"maxHeight":2000,"maxBytes":4718592,"jpegQuality":80}}},"upstreamModelId":"gpt-6-astra","serviceTier":"priority","type":"chat"},"chat:gpt-6-luna":{"id":"gpt-6-luna","name":"GPT-6 Luna","api":"openai-codex-responses","provider":"chatgpt-subscription","baseUrl":"https://chatgpt.com/backend-api","reasoning":true,"input":["text","image"],"cost":{"input":0.1,"output":0.5,"cacheRead":0.01,"cacheWrite":0.125,"tiers":[{"inputTokensAbove":272000,"input":0.2,"output":0.75,"cacheRead":0.02,"cacheWrite":0.25}]},"contextWindow":922000,"maxTokens":128000,"thinkingLevelMap":{"off":"none","minimal":null,"low":"low","medium":"medium","high":"high","xhigh":"xhigh","max":"max"},"compat":{"supportsOpenAIGrammarTools":true,"supportsAdditionalTools":true,"supportsToolSearch":true,"supportsMidConvoSystemMessages":true},"inputLimits":{"images":{"resize":{"maxWidth":2000,"maxHeight":2000,"maxBytes":4718592,"jpegQuality":80}}},"type":"chat"},"chat:gpt-6-luna-fast":{"id":"gpt-6-luna-fast","name":"GPT-6 Luna Fast","api":"openai-codex-responses","provider":"chatgpt-subscription","baseUrl":"https://chatgpt.com/backend-api","reasoning":true,"input":["text","image"],"cost":{"input":0.1,"output":0.5,"cacheRead":0.01,"cacheWrite":0.125,"tiers":[{"inputTokensAbove":272000,"input":0.2,"output":0.75,"cacheRead":0.02,"cacheWrite":0.25}]},"contextWindow":922000,"maxTokens":128000,"thinkingLevelMap":{"off":"none","minimal":null,"low":"low","medium":"medium","high":"high","xhigh":"xhigh","max":"max"},"compat":{"supportsOpenAIGrammarTools":true,"supportsAdditionalTools":true,"supportsToolSearch":true,"supportsMidConvoSystemMessages":true},"inputLimits":{"images":{"resize":{"maxWidth":2000,"maxHeight":2000,"maxBytes":4718592,"jpegQuality":80}}},"upstreamModelId":"gpt-6-luna","serviceTier":"priority","type":"chat"},"chat:gpt-6-sol":{"id":"gpt-6-sol","name":"GPT-6 Sol","api":"openai-codex-responses","provider":"chatgpt-subscription","baseUrl":"https://chatgpt.com/backend-api","reasoning":true,"input":["text","image"],"cost":{"input":2,"output":10,"cacheRead":0.2,"cacheWrite":2.5,"tiers":[{"inputTokensAbove":272000,"input":4,"output":15,"cacheRead":0.4,"cacheWrite":5}]},"contextWindow":400000,"maxTokens":128000,"thinkingLevelMap":{"off":"none","minimal":null,"low":"low","medium":"medium","high":"high","xhigh":"xhigh","max":"max"},"compat":{"supportsOpenAIGrammarTools":true,"supportsAdditionalTools":true,"supportsToolSearch":true,"supportsMidConvoSystemMessages":true},"inputLimits":{"images":{"resize":{"maxWidth":2000,"maxHeight":2000,"maxBytes":4718592,"jpegQuality":80}}},"type":"chat"},"chat:gpt-6-sol-fast":{"id":"gpt-6-sol-fast","name":"GPT-6 Sol Fast","api":"openai-codex-responses","provider":"chatgpt-subscription","baseUrl":"https://chatgpt.com/backend-api","reasoning":true,"input":["text","image"],"cost":{"input":2,"output":10,"cacheRead":0.2,"cacheWrite":2.5,"tiers":[{"inputTokensAbove":272000,"input":4,"output":15,"cacheRead":0.4,"cacheWrite":5}]},"contextWindow":400000,"maxTokens":128000,"thinkingLevelMap":{"off":"none","minimal":null,"low":"low","medium":"medium","high":"high","xhigh":"xhigh","max":"max"},"compat":{"supportsOpenAIGrammarTools":true,"supportsAdditionalTools":true,"supportsToolSearch":true,"supportsMidConvoSystemMessages":true},"inputLimits":{"images":{"resize":{"maxWidth":2000,"maxHeight":2000,"maxBytes":4718592,"jpegQuality":80}}},"upstreamModelId":"gpt-6-sol","serviceTier":"priority","type":"chat"},"chat:gpt-6.1-sol":{"id":"gpt-6.1-sol","name":"GPT-6.1 Sol","api":"openai-codex-responses","provider":"chatgpt-subscription","baseUrl":"https://chatgpt.com/backend-api","reasoning":true,"input":["text","image"],"cost":{"input":2,"output":10,"cacheRead":0.1,"cacheWrite":2.5,"tiers":[{"inputTokensAbove":272000,"input":4,"output":15,"cacheRead":0.2,"cacheWrite":5}]},"contextWindow":400000,"maxTokens":128000,"thinkingLevelMap":{"off":null,"minimal":null,"low":"low","medium":"medium","high":"high","xhigh":"xhigh","max":"max"},"compat":{"supportsOpenAIGrammarTools":true,"supportsAdditionalTools":true,"supportsToolSearch":true,"supportsMidConvoSystemMessages":true,"supportsConfigurationUpdate":true},"inputLimits":{"images":{"resize":{"maxWidth":2000,"maxHeight":2000,"maxBytes":4718592,"jpegQuality":80}}},"type":"chat"},"chat:gpt-6.1-sol-fast":{"id":"gpt-6.1-sol-fast","name":"GPT-6.1 Sol Fast","api":"openai-codex-responses","provider":"chatgpt-subscription","baseUrl":"https://chatgpt.com/backend-api","reasoning":true,"input":["text","image"],"cost":{"input":2,"output":10,"cacheRead":0.1,"cacheWrite":2.5,"tiers":[{"inputTokensAbove":272000,"input":4,"output":15,"cacheRead":0.2,"cacheWrite":5}]},"contextWindow":400000,"maxTokens":128000,"thinkingLevelMap":{"off":null,"minimal":null,"low":"low","medium":"medium","high":"high","xhigh":"xhigh","max":"max"},"compat":{"supportsOpenAIGrammarTools":true,"supportsAdditionalTools":true,"supportsToolSearch":true,"supportsMidConvoSystemMessages":true,"supportsConfigurationUpdate":true},"inputLimits":{"images":{"resize":{"maxWidth":2000,"maxHeight":2000,"maxBytes":4718592,"jpegQuality":80}}},"upstreamModelId":"gpt-6.1-sol","serviceTier":"priority","type":"chat"},"chat:gpt-6.1-sol-ultrafast":{"id":"gpt-6.1-sol-ultrafast","name":"GPT-6.1 Sol Ultrafast","api":"openai-codex-responses","provider":"chatgpt-subscription","baseUrl":"https://chatgpt.com/backend-api","reasoning":true,"input":["text","image"],"cost":{"input":2,"output":10,"cacheRead":0.1,"cacheWrite":2.5,"tiers":[{"inputTokensAbove":272000,"input":4,"output":15,"cacheRead":0.2,"cacheWrite":5}]},"contextWindow":400000,"maxTokens":128000,"thinkingLevelMap":{"off":null,"minimal":null,"low":"low","medium":"medium","high":"high","xhigh":"xhigh","max":"max"},"compat":{"supportsOpenAIGrammarTools":true,"supportsAdditionalTools":true,"supportsToolSearch":true,"supportsMidConvoSystemMessages":true,"supportsConfigurationUpdate":true},"inputLimits":{"images":{"resize":{"maxWidth":2000,"maxHeight":2000,"maxBytes":4718592,"jpegQuality":80}}},"upstreamModelId":"gpt-6.1-sol","serviceTier":"ultrafast","defaultThinkingLevel":"xhigh","type":"chat"}}}
1
+ {"openai-codex-responses":{"chat:gpt-5.3-codex-spark":{"id":"gpt-5.3-codex-spark","name":"GPT-5.3 Codex Spark","api":"openai-codex-responses","provider":"chatgpt-subscription","baseUrl":"https://chatgpt.com/backend-api","reasoning":true,"input":["text"],"cost":{"input":1.75,"output":14,"cacheRead":0.175,"cacheWrite":0},"contextWindow":128000,"maxTokens":128000,"thinkingLevelMap":{"xhigh":"xhigh","minimal":"low"},"compat":{"supportsOpenAIGrammarTools":true},"type":"chat"},"chat:gpt-5.5":{"id":"gpt-5.5","name":"GPT-5.5","api":"openai-codex-responses","provider":"chatgpt-subscription","baseUrl":"https://chatgpt.com/backend-api","reasoning":true,"input":["text","image"],"cost":{"input":5,"output":30,"cacheRead":0.5,"cacheWrite":0,"tiers":[{"inputTokensAbove":272000,"input":10,"output":45,"cacheRead":1,"cacheWrite":0}]},"contextWindow":272000,"maxTokens":128000,"thinkingLevelMap":{"xhigh":"xhigh","minimal":"low"},"compat":{"supportsOpenAIGrammarTools":true,"supportsToolSearch":true,"supportsMidConvoSystemMessages":true},"inputLimits":{"images":{"resize":{"maxWidth":2000,"maxHeight":2000,"maxBytes":4718592,"jpegQuality":80}}},"type":"chat"},"chat:gpt-5.6-luna":{"id":"gpt-5.6-luna","name":"GPT-5.6 Luna","api":"openai-codex-responses","provider":"chatgpt-subscription","baseUrl":"https://chatgpt.com/backend-api","reasoning":true,"input":["text","image"],"cost":{"input":0.2,"output":1.2,"cacheRead":0.02,"cacheWrite":0.25,"tiers":[{"inputTokensAbove":272000,"input":0.4,"output":1.8,"cacheRead":0.04,"cacheWrite":0.5}]},"contextWindow":272000,"maxTokens":128000,"thinkingLevelMap":{"xhigh":"xhigh","max":"max","minimal":"low"},"compat":{"supportsOpenAIGrammarTools":true,"supportsAdditionalTools":true,"supportsToolSearch":true,"supportsMidConvoSystemMessages":true},"inputLimits":{"images":{"resize":{"maxWidth":2000,"maxHeight":2000,"maxBytes":4718592,"jpegQuality":80}}},"type":"chat"},"chat:gpt-5.6-luna-fast":{"id":"gpt-5.6-luna-fast","name":"GPT-5.6 Luna Fast","api":"openai-codex-responses","provider":"chatgpt-subscription","baseUrl":"https://chatgpt.com/backend-api","reasoning":true,"input":["text","image"],"cost":{"input":0.2,"output":1.2,"cacheRead":0.02,"cacheWrite":0.25,"tiers":[{"inputTokensAbove":272000,"input":0.4,"output":1.8,"cacheRead":0.04,"cacheWrite":0.5}]},"contextWindow":272000,"maxTokens":128000,"thinkingLevelMap":{"xhigh":"xhigh","max":"max","minimal":"low"},"compat":{"supportsOpenAIGrammarTools":true,"supportsAdditionalTools":true,"supportsToolSearch":true,"supportsMidConvoSystemMessages":true},"inputLimits":{"images":{"resize":{"maxWidth":2000,"maxHeight":2000,"maxBytes":4718592,"jpegQuality":80}}},"upstreamModelId":"gpt-5.6-luna","serviceTier":"priority","type":"chat"},"chat:gpt-5.6-sol":{"id":"gpt-5.6-sol","name":"GPT-5.6 Sol","api":"openai-codex-responses","provider":"chatgpt-subscription","baseUrl":"https://chatgpt.com/backend-api","reasoning":true,"input":["text","image"],"cost":{"input":4,"output":20,"cacheRead":0.4,"cacheWrite":5,"tiers":[{"inputTokensAbove":272000,"input":8,"output":30,"cacheRead":0.8,"cacheWrite":10}]},"contextWindow":650000,"maxTokens":128000,"thinkingLevelMap":{"xhigh":"xhigh","max":"max","minimal":"low"},"compat":{"supportsOpenAIGrammarTools":true,"supportsAdditionalTools":true,"supportsToolSearch":true,"supportsMidConvoSystemMessages":true},"inputLimits":{"images":{"resize":{"maxWidth":2000,"maxHeight":2000,"maxBytes":4718592,"jpegQuality":80}}},"type":"chat"},"chat:gpt-5.6-sol-fast":{"id":"gpt-5.6-sol-fast","name":"GPT-5.6 Sol Fast","api":"openai-codex-responses","provider":"chatgpt-subscription","baseUrl":"https://chatgpt.com/backend-api","reasoning":true,"input":["text","image"],"cost":{"input":4,"output":20,"cacheRead":0.4,"cacheWrite":5,"tiers":[{"inputTokensAbove":272000,"input":8,"output":30,"cacheRead":0.8,"cacheWrite":10}]},"contextWindow":650000,"maxTokens":128000,"thinkingLevelMap":{"xhigh":"xhigh","max":"max","minimal":"low"},"compat":{"supportsOpenAIGrammarTools":true,"supportsAdditionalTools":true,"supportsToolSearch":true,"supportsMidConvoSystemMessages":true},"inputLimits":{"images":{"resize":{"maxWidth":2000,"maxHeight":2000,"maxBytes":4718592,"jpegQuality":80}}},"upstreamModelId":"gpt-5.6-sol","serviceTier":"priority","type":"chat"},"chat:gpt-5.6-terra":{"id":"gpt-5.6-terra","name":"GPT-5.6 Terra","api":"openai-codex-responses","provider":"chatgpt-subscription","baseUrl":"https://chatgpt.com/backend-api","reasoning":true,"input":["text","image"],"cost":{"input":2,"output":12,"cacheRead":0.2,"cacheWrite":2.5,"tiers":[{"inputTokensAbove":272000,"input":4,"output":18,"cacheRead":0.4,"cacheWrite":5}]},"contextWindow":272000,"maxTokens":128000,"thinkingLevelMap":{"xhigh":"xhigh","max":"max","minimal":"low"},"compat":{"supportsOpenAIGrammarTools":true,"supportsAdditionalTools":true,"supportsToolSearch":true,"supportsMidConvoSystemMessages":true},"inputLimits":{"images":{"resize":{"maxWidth":2000,"maxHeight":2000,"maxBytes":4718592,"jpegQuality":80}}},"type":"chat"},"chat:gpt-5.6-terra-fast":{"id":"gpt-5.6-terra-fast","name":"GPT-5.6 Terra Fast","api":"openai-codex-responses","provider":"chatgpt-subscription","baseUrl":"https://chatgpt.com/backend-api","reasoning":true,"input":["text","image"],"cost":{"input":2,"output":12,"cacheRead":0.2,"cacheWrite":2.5,"tiers":[{"inputTokensAbove":272000,"input":4,"output":18,"cacheRead":0.4,"cacheWrite":5}]},"contextWindow":272000,"maxTokens":128000,"thinkingLevelMap":{"xhigh":"xhigh","max":"max","minimal":"low"},"compat":{"supportsOpenAIGrammarTools":true,"supportsAdditionalTools":true,"supportsToolSearch":true,"supportsMidConvoSystemMessages":true},"inputLimits":{"images":{"resize":{"maxWidth":2000,"maxHeight":2000,"maxBytes":4718592,"jpegQuality":80}}},"upstreamModelId":"gpt-5.6-terra","serviceTier":"priority","type":"chat"},"chat:gpt-6-astra":{"id":"gpt-6-astra","name":"GPT-6 Astra","api":"openai-codex-responses","provider":"chatgpt-subscription","baseUrl":"https://chatgpt.com/backend-api","reasoning":true,"input":["text","image"],"cost":{"input":10,"output":50,"cacheRead":1,"cacheWrite":12.5,"tiers":[{"inputTokensAbove":272000,"input":20,"output":75,"cacheRead":2,"cacheWrite":25}]},"contextWindow":600000,"maxTokens":128000,"thinkingLevelMap":{"off":null,"minimal":null,"low":"low","medium":"medium","high":"high","xhigh":"xhigh","max":"max"},"compat":{"supportsOpenAIGrammarTools":true,"supportsAdditionalTools":true,"supportsToolSearch":true,"supportsMidConvoSystemMessages":true,"supportsConfigurationUpdate":true},"inputLimits":{"images":{"resize":{"maxWidth":2000,"maxHeight":2000,"maxBytes":4718592,"jpegQuality":80}}},"type":"chat"},"chat:gpt-6-astra-fast":{"id":"gpt-6-astra-fast","name":"GPT-6 Astra Fast","api":"openai-codex-responses","provider":"chatgpt-subscription","baseUrl":"https://chatgpt.com/backend-api","reasoning":true,"input":["text","image"],"cost":{"input":10,"output":50,"cacheRead":1,"cacheWrite":12.5,"tiers":[{"inputTokensAbove":272000,"input":20,"output":75,"cacheRead":2,"cacheWrite":25}]},"contextWindow":600000,"maxTokens":128000,"thinkingLevelMap":{"off":null,"minimal":null,"low":"low","medium":"medium","high":"high","xhigh":"xhigh","max":"max"},"compat":{"supportsOpenAIGrammarTools":true,"supportsAdditionalTools":true,"supportsToolSearch":true,"supportsMidConvoSystemMessages":true,"supportsConfigurationUpdate":true},"inputLimits":{"images":{"resize":{"maxWidth":2000,"maxHeight":2000,"maxBytes":4718592,"jpegQuality":80}}},"upstreamModelId":"gpt-6-astra","serviceTier":"priority","type":"chat"},"chat:gpt-6-luna":{"id":"gpt-6-luna","name":"GPT-6 Luna","api":"openai-codex-responses","provider":"chatgpt-subscription","baseUrl":"https://chatgpt.com/backend-api","reasoning":true,"input":["text","image"],"cost":{"input":0.1,"output":0.5,"cacheRead":0.01,"cacheWrite":0.125,"tiers":[{"inputTokensAbove":272000,"input":0.2,"output":0.75,"cacheRead":0.02,"cacheWrite":0.25}]},"contextWindow":922000,"maxTokens":128000,"thinkingLevelMap":{"off":"none","minimal":null,"low":"low","medium":"medium","high":"high","xhigh":"xhigh","max":"max"},"compat":{"supportsOpenAIGrammarTools":true,"supportsAdditionalTools":true,"supportsToolSearch":true,"supportsMidConvoSystemMessages":true},"inputLimits":{"images":{"resize":{"maxWidth":2000,"maxHeight":2000,"maxBytes":4718592,"jpegQuality":80}}},"type":"chat"},"chat:gpt-6-luna-fast":{"id":"gpt-6-luna-fast","name":"GPT-6 Luna Fast","api":"openai-codex-responses","provider":"chatgpt-subscription","baseUrl":"https://chatgpt.com/backend-api","reasoning":true,"input":["text","image"],"cost":{"input":0.1,"output":0.5,"cacheRead":0.01,"cacheWrite":0.125,"tiers":[{"inputTokensAbove":272000,"input":0.2,"output":0.75,"cacheRead":0.02,"cacheWrite":0.25}]},"contextWindow":922000,"maxTokens":128000,"thinkingLevelMap":{"off":"none","minimal":null,"low":"low","medium":"medium","high":"high","xhigh":"xhigh","max":"max"},"compat":{"supportsOpenAIGrammarTools":true,"supportsAdditionalTools":true,"supportsToolSearch":true,"supportsMidConvoSystemMessages":true},"inputLimits":{"images":{"resize":{"maxWidth":2000,"maxHeight":2000,"maxBytes":4718592,"jpegQuality":80}}},"upstreamModelId":"gpt-6-luna","serviceTier":"priority","type":"chat"},"chat:gpt-6-sol":{"id":"gpt-6-sol","name":"GPT-6 Sol","api":"openai-codex-responses","provider":"chatgpt-subscription","baseUrl":"https://chatgpt.com/backend-api","reasoning":true,"input":["text","image"],"cost":{"input":2,"output":10,"cacheRead":0.2,"cacheWrite":2.5,"tiers":[{"inputTokensAbove":272000,"input":4,"output":15,"cacheRead":0.4,"cacheWrite":5}]},"contextWindow":400000,"maxTokens":128000,"thinkingLevelMap":{"off":"none","minimal":null,"low":"low","medium":"medium","high":"high","xhigh":"xhigh","max":"max"},"compat":{"supportsOpenAIGrammarTools":true,"supportsAdditionalTools":true,"supportsToolSearch":true,"supportsMidConvoSystemMessages":true},"inputLimits":{"images":{"resize":{"maxWidth":2000,"maxHeight":2000,"maxBytes":4718592,"jpegQuality":80}}},"type":"chat"},"chat:gpt-6-sol-fast":{"id":"gpt-6-sol-fast","name":"GPT-6 Sol Fast","api":"openai-codex-responses","provider":"chatgpt-subscription","baseUrl":"https://chatgpt.com/backend-api","reasoning":true,"input":["text","image"],"cost":{"input":2,"output":10,"cacheRead":0.2,"cacheWrite":2.5,"tiers":[{"inputTokensAbove":272000,"input":4,"output":15,"cacheRead":0.4,"cacheWrite":5}]},"contextWindow":400000,"maxTokens":128000,"thinkingLevelMap":{"off":"none","minimal":null,"low":"low","medium":"medium","high":"high","xhigh":"xhigh","max":"max"},"compat":{"supportsOpenAIGrammarTools":true,"supportsAdditionalTools":true,"supportsToolSearch":true,"supportsMidConvoSystemMessages":true},"inputLimits":{"images":{"resize":{"maxWidth":2000,"maxHeight":2000,"maxBytes":4718592,"jpegQuality":80}}},"upstreamModelId":"gpt-6-sol","serviceTier":"priority","type":"chat"},"chat:gpt-6.1-sol":{"id":"gpt-6.1-sol","name":"GPT-6.1 Sol","api":"openai-codex-responses","provider":"chatgpt-subscription","baseUrl":"https://chatgpt.com/backend-api","reasoning":true,"input":["text","image"],"cost":{"input":2,"output":10,"cacheRead":0.1,"cacheWrite":2.5,"tiers":[{"inputTokensAbove":272000,"input":4,"output":15,"cacheRead":0.2,"cacheWrite":5}]},"contextWindow":500000,"maxTokens":128000,"thinkingLevelMap":{"off":null,"minimal":null,"low":"low","medium":"medium","high":"high","xhigh":"xhigh","max":"max"},"compat":{"supportsOpenAIGrammarTools":true,"supportsAdditionalTools":true,"supportsToolSearch":true,"supportsMidConvoSystemMessages":true,"supportsConfigurationUpdate":true},"inputLimits":{"images":{"resize":{"maxWidth":2000,"maxHeight":2000,"maxBytes":4718592,"jpegQuality":80}}},"type":"chat"},"chat:gpt-6.1-sol-fast":{"id":"gpt-6.1-sol-fast","name":"GPT-6.1 Sol Fast","api":"openai-codex-responses","provider":"chatgpt-subscription","baseUrl":"https://chatgpt.com/backend-api","reasoning":true,"input":["text","image"],"cost":{"input":2,"output":10,"cacheRead":0.1,"cacheWrite":2.5,"tiers":[{"inputTokensAbove":272000,"input":4,"output":15,"cacheRead":0.2,"cacheWrite":5}]},"contextWindow":500000,"maxTokens":128000,"thinkingLevelMap":{"off":null,"minimal":null,"low":"low","medium":"medium","high":"high","xhigh":"xhigh","max":"max"},"compat":{"supportsOpenAIGrammarTools":true,"supportsAdditionalTools":true,"supportsToolSearch":true,"supportsMidConvoSystemMessages":true,"supportsConfigurationUpdate":true},"inputLimits":{"images":{"resize":{"maxWidth":2000,"maxHeight":2000,"maxBytes":4718592,"jpegQuality":80}}},"upstreamModelId":"gpt-6.1-sol","serviceTier":"priority","type":"chat"},"chat:gpt-6.1-sol-ultrafast":{"id":"gpt-6.1-sol-ultrafast","name":"GPT-6.1 Sol Ultrafast","api":"openai-codex-responses","provider":"chatgpt-subscription","baseUrl":"https://chatgpt.com/backend-api","reasoning":true,"input":["text","image"],"cost":{"input":2,"output":10,"cacheRead":0.1,"cacheWrite":2.5,"tiers":[{"inputTokensAbove":272000,"input":4,"output":15,"cacheRead":0.2,"cacheWrite":5}]},"contextWindow":500000,"maxTokens":128000,"thinkingLevelMap":{"off":null,"minimal":null,"low":"low","medium":"medium","high":"high","xhigh":"xhigh","max":"max"},"compat":{"supportsOpenAIGrammarTools":true,"supportsAdditionalTools":true,"supportsToolSearch":true,"supportsMidConvoSystemMessages":true,"supportsConfigurationUpdate":true},"inputLimits":{"images":{"resize":{"maxWidth":2000,"maxHeight":2000,"maxBytes":4718592,"jpegQuality":80}}},"upstreamModelId":"gpt-6.1-sol","serviceTier":"ultrafast","defaultThinkingLevel":"xhigh","type":"chat"}}}