@code-yeongyu/senpi-ai 2026.11.3-1 → 2026.11.3-3

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.
@@ -9,14 +9,16 @@
9
9
  * re-acquires the lock and compare-and-swaps on the slot's refresh token, so a
10
10
  * slot rotated meanwhile by another process is adopted instead of overwritten.
11
11
  *
12
- * Within a process, concurrent refreshes of the same slot join one exchange.
12
+ * Persistent stores inject a session-scoped lock around read/exchange/write so
13
+ * two processes cannot consume the same rotating token. Within a process,
14
+ * concurrent refreshes of the same slot join one exchange.
13
15
  * Waiters that own the exchange (per-request resolution) cancel it once none of
14
16
  * them is waiting; the catalog-refresh lane joins without owning it, so a
15
17
  * superseded catalog refresh stops waiting but never aborts the exchange.
16
18
  */
17
19
  import { raceWithAbortSignal } from "../utils/abort.js";
18
20
  import { oauthRefreshFailureCause } from "../utils/oauth-refresh-error.js";
19
- import { mergeRefreshed, mergeRefreshedSlot, projectSlot } from "./pool/slots.js";
21
+ import { DEFAULT_SLOT_NAME, listSlots, mergeRefreshed, mergeRefreshedSlot, projectSlot } from "./pool/slots.js";
20
22
  export const DEFAULT_OAUTH_REFRESH_TIMEOUT_MS = 15_000;
21
23
  /** The provider rejected or timed out the token exchange. */
22
24
  export class OAuthRefreshExchangeError extends Error {
@@ -78,7 +80,7 @@ export function refreshOAuthCredential(request) {
78
80
  if (!inflight) {
79
81
  const controller = new AbortController();
80
82
  const created = { controller, waiters: 0, owned: false, promise: Promise.resolve(undefined) };
81
- created.promise = exchangeAndStore(request, controller.signal).finally(() => {
83
+ created.promise = serializeExchange(request, controller.signal).finally(() => {
82
84
  if (registry.get(key) === created)
83
85
  registry.delete(key);
84
86
  });
@@ -105,7 +107,50 @@ function join(inflight, signal, owning) {
105
107
  else
106
108
  signal.addEventListener("abort", leave, { once: true });
107
109
  }
108
- async function exchangeAndStore(request, signal) {
110
+ function refreshSlotName(credential, slotName) {
111
+ // Flat/catalog resolution and named resolution of its mirrored slot must
112
+ // acquire the same lock. Token equality locates the stable ID; it is not the key.
113
+ return (slotName ??
114
+ listSlots(credential).find((slot) => slot.refresh === credential.refresh || slot.access === credential.access)
115
+ ?.name ??
116
+ DEFAULT_SLOT_NAME);
117
+ }
118
+ async function serializeExchange(request, signal) {
119
+ const { credentials, providerId, slotName } = request;
120
+ let identity = refreshSlotName(request.stale, slotName);
121
+ let retry;
122
+ do {
123
+ retry = false;
124
+ const run = async (lockSignal) => {
125
+ const latest = await credentials.read(providerId, { signal: lockSignal });
126
+ if (credentials.withRefreshLock && latest?.type === "oauth") {
127
+ const currentIdentity = refreshSlotName(latest, slotName);
128
+ if (currentIdentity !== identity) {
129
+ // A login/removal changed the flat projection while we waited.
130
+ // Release before acquiring that account's lock; never nest locks.
131
+ identity = currentIdentity;
132
+ retry = true;
133
+ return undefined;
134
+ }
135
+ }
136
+ return exchangeAndStore(request, lockSignal, latest);
137
+ };
138
+ try {
139
+ const result = credentials.withRefreshLock
140
+ ? await credentials.withRefreshLock(providerId, identity, run, { signal })
141
+ : await run(signal);
142
+ if (!retry)
143
+ return result;
144
+ }
145
+ catch (error) {
146
+ if (error instanceof OAuthRefreshExchangeError || error instanceof OAuthRefreshStoreError)
147
+ throw error;
148
+ throw new OAuthRefreshStoreError(error);
149
+ }
150
+ } while (retry);
151
+ return undefined;
152
+ }
153
+ async function exchangeAndStore(request, signal, latest) {
109
154
  const { credentials, providerId, oauth, slotName } = request;
110
155
  const view = (credential) => {
111
156
  if (credential?.type !== "oauth")
@@ -115,13 +160,6 @@ async function exchangeAndStore(request, signal) {
115
160
  return undefined;
116
161
  return projected;
117
162
  };
118
- let latest;
119
- try {
120
- latest = await credentials.read(providerId, { signal });
121
- }
122
- catch (error) {
123
- throw new OAuthRefreshStoreError(error);
124
- }
125
163
  const current = view(latest);
126
164
  if (!current)
127
165
  return undefined; // logged out or slot removed meanwhile
@@ -0,0 +1,9 @@
1
+ import type { Credential } from "../types.ts";
2
+ /**
3
+ * Marks a credential a sign-in is about to store with a fresh `loginId`. Only sign-in paths call
4
+ * this (logins and account imports); a token refresh rewrites the material and keeps or drops the
5
+ * id but never mints one, so a new non-empty id means a person signed in again, never that a token
6
+ * rotated (senpi#4099). The id is random, not key material.
7
+ */
8
+ export declare function stampLogin(credential: Credential): Credential;
9
+ //# sourceMappingURL=login-id.d.ts.map
@@ -0,0 +1,10 @@
1
+ /**
2
+ * Marks a credential a sign-in is about to store with a fresh `loginId`. Only sign-in paths call
3
+ * this (logins and account imports); a token refresh rewrites the material and keeps or drops the
4
+ * id but never mints one, so a new non-empty id means a person signed in again, never that a token
5
+ * rotated (senpi#4099). The id is random, not key material.
6
+ */
7
+ export function stampLogin(credential) {
8
+ return { ...credential, loginId: globalThis.crypto.randomUUID() };
9
+ }
10
+ //# sourceMappingURL=login-id.js.map
@@ -3,6 +3,7 @@ import { ModelsError } from "../utils/models-error.js";
3
3
  import { classifyOAuthRefreshFailure, OAuthRefreshUnavailableError } from "../utils/oauth-refresh-error.js";
4
4
  import { readCredential, readSlotCredential } from "./credential-read.js";
5
5
  import { OAuthRefreshExchangeError, OAuthRefreshStoreError, projectOAuthSlot, refreshOAuthCredential, } from "./oauth-refresh.js";
6
+ import { managedSentinelMaterials } from "./pool/slots.js";
6
7
  export { ModelsError } from "../utils/models-error.js";
7
8
  /**
8
9
  * Prefix of the auth-miss every resolution site raises when a provider has no
@@ -104,6 +105,12 @@ async function resolveStoredOAuth(credentials, providerId, oauth, stored, authCo
104
105
  const expiresSoon = (credential) => Date.now() + minimumValidityMs >= credential.expires;
105
106
  const isStale = (credential) => expiresSoon(credential) || (rejectedAccess !== undefined && credential.access === rejectedAccess);
106
107
  let credential = stored;
108
+ // The sentinel marks a pool whose tokens live in its accounts; it is not a token, so a
109
+ // token endpoint can only reject it. Only a slot of the pool can authenticate.
110
+ const isManagedSentinel = credential.refresh === credential.access && managedSentinelMaterials(providerId).includes(credential.access);
111
+ if (isManagedSentinel && isStale(credential)) {
112
+ throw new ModelsError("auth", `The stored ${providerId} credential is a managed account-pool placeholder; resolve one of its accounts instead`);
113
+ }
107
114
  if (isStale(credential)) {
108
115
  let post;
109
116
  try {
@@ -16,6 +16,8 @@ export interface ApiKeyCredential {
16
16
  type: "api_key";
17
17
  key?: string;
18
18
  env?: ProviderEnv;
19
+ /** Random id the last sign-in wrote (`stampLogin`); a refresh keeps or drops it, never mints one. Not key material. */
20
+ loginId?: string;
19
21
  }
20
22
  /** OAuth token data returned by extension compatibility flows. */
21
23
  export interface OAuthCredentials {
@@ -27,6 +29,8 @@ export interface OAuthCredentials {
27
29
  /** Stored canonical OAuth credential. */
28
30
  export interface OAuthCredential extends OAuthCredentials {
29
31
  type: "oauth";
32
+ /** Random id the last sign-in wrote (`stampLogin`); a refresh keeps or drops it, never mints one. Not key material. */
33
+ loginId?: string;
30
34
  }
31
35
  /** One type-tagged credential per provider — the shape of today's auth.json. */
32
36
  export type Credential = ApiKeyCredential | OAuthCredential;
@@ -52,8 +56,8 @@ export interface LogoutOptions extends AuthOperationOptions {
52
56
  * App-owned credential storage, keyed by `Provider.id`, one entry per
53
57
  * provider; an entry may pool sibling slots under `accounts` while its flat
54
58
  * fields remain a valid credential. `modify` is the only write path, so every mutation is a
55
- * serialized read-modify-write; `Models.getAuth()` runs OAuth refresh inside
56
- * `modify` so concurrent requests cannot double-refresh a rotated token. The
59
+ * serialized read-modify-write. Persistent stores inject `withRefreshLock` to
60
+ * serialize a session's exchange without holding the global write lock. The
57
61
  * app persists a credential after login via
58
62
  * `modify(provider.id, async () => credential)`. Login/logout orchestration
59
63
  * is app-owned.
@@ -77,6 +81,14 @@ export interface CredentialStore {
77
81
  * resolves only the selected slot, never the flat key or a sibling.
78
82
  */
79
83
  readSlot?(providerId: string, slotName: string, options?: AuthOperationOptions): Promise<Credential | undefined>;
84
+ /**
85
+ * Optional session-scoped exclusion around read-latest -> exchange -> persist.
86
+ * Persistent stores serialize across processes, separately from `modify`, so
87
+ * unrelated accounts stay concurrent. The key is the provider and stable slot
88
+ * name, never token material. The callback's signal also aborts on lock loss;
89
+ * the lock stays held until the callback settles, including its final write.
90
+ */
91
+ withRefreshLock?<T>(providerId: string, slotName: string, fn: (signal: AbortSignal) => Promise<T>, options?: AuthOperationOptions): Promise<T>;
80
92
  /**
81
93
  * List stored credential metadata without resolving or exposing secrets.
82
94
  * Implementations must not execute configured API-key commands while listing.
@@ -275,7 +287,8 @@ export interface OAuthAuth {
275
287
  accountIdentity?(credential: Pick<OAuthCredential, "access">): string | undefined;
276
288
  /**
277
289
  * Exchange the refresh token. Network call; throws on failure
278
- * (invalid_grant etc.). `Models` runs this under the store lock.
290
+ * (invalid_grant etc.). `Models` uses the injected session refresh lock,
291
+ * never the store's global write lock.
279
292
  */
280
293
  refresh(credential: OAuthCredential, signal: AbortSignal): Promise<OAuthCredential>;
281
294
  /** End the renewable session before the caller clears local tokens. */
package/dist/models.js CHANGED
@@ -1,6 +1,7 @@
1
1
  import { lazyStream } from "./api/lazy.js";
2
2
  import { defaultProviderAuthContext as defaultAuthContext } from "./auth/context.js";
3
3
  import { InMemoryCredentialStore, revokeStoredOAuth } from "./auth/credential-store.js";
4
+ import { stampLogin } from "./auth/pool/login-id.js";
4
5
  import { appendLoginSlot, assertLoginKeyPresent, removeSlot, withoutBlankKey } from "./auth/pool/slots.js";
5
6
  import { resolveRefreshCredential } from "./auth/refresh-credential.js";
6
7
  import { ModelsError, providerNotConfiguredMessage, resolveProviderAuth, } from "./auth/resolve.js";
@@ -381,10 +382,10 @@ class ModelsImpl {
381
382
  const mutation = this.credentials.modify(providerId, async (current) => {
382
383
  mutationStarted = true;
383
384
  markMutationStarted?.();
384
- return appendLoginSlot(current, credential, (name, origin) => {
385
+ return stampLogin(appendLoginSlot(current, credential, (name, origin) => {
385
386
  committedName = name;
386
387
  committedOrigin = origin;
387
- }, { accountIdentity: provider.auth.oauth?.accountIdentity });
388
+ }, { accountIdentity: provider.auth.oauth?.accountIdentity }));
388
389
  }, { signal });
389
390
  void mutation.catch(() => { });
390
391
  try {
@@ -1 +1 @@
1
- {"schemaVersion":6,"generatedAt":"2026-11-03T03:22:20.574Z","structureHash":"a76348c932e71ac8d0fe82ef0ef0cb1ea2b0b5ddb4a373650b7dc9b4db97cdeb","files":{"alibaba-token-plan.json":"9f4d42cc765b2a875bcdcaa392bfdc1323c88968309baf9db9f611a26c595c73","amazon-bedrock.json":"a7e20838b095788cb9d5acbde49664b7f2868fad9b10fb4bbbd66635085bca2d","ant-ling.json":"628feab3ef6c7d80ce96f75999804e1d9f05fec3851e5302e30fff3b69db90f6","anthropic.json":"111384e9f5845e0247bd34edf2400ef7720fcbdac140b944cf8878192d8bd6ab","azure-openai-responses.json":"fd64c6a2a99fa87d768ed2f75f5c7813876df1dbe2f0d1776f7d9bd7ce2e61e4","bai.json":"7e6861aaf27d8af34e1771c6092602194fcec0a0046e6adfab9c3ee54d32b99f","baseten.json":"5bd3c98c61769388b3724368ef964d16b7a58e41a6edcf4ebceb9d4ac0a21d3b","cerebras.json":"2eb969b2956844f9a641d3de52c19f1791293c58f607282fb3b0ebfe85ff66f8","chatgpt-subscription.json":"98320f1d51709d26ca047b3d6e3191cfe2f192f1b27897cbb492f47b0e5a5030","cloudflare-ai-gateway.json":"ac281b8cc18eb84ba61f215eff3234d14732cd66239617fb59d6812b13d6473f","cloudflare-workers-ai.json":"1b9ad4360bde817f0ea358431020308f1052840e2278a57a93629f1790072d2e","deepseek.json":"10a296fb3e898f7715c80890c8af0af4f5fd58f22dbcd6612fdc5d762157ccdc","fireworks.json":"56c557eb97573028e871c211cb17e1d60665eb12d67a712615db4bb255bc9253","github-copilot.json":"474fa92eb88ef242208ca93709ebe6d7f21754917d0cad6210bd1edf2b99a87e","google-vertex.json":"8f986b4aca8c685b0f3481bd252bda21e4858bf9015ad37fc5bcc44b7f01d076","google.json":"d25613a7377e81d785d571be514d67b35436511ce6946247dc66f8674e2a5035","groq.json":"087df37206e9eed8b10f1e558e4c496289bef60074b7e8afba4f20fb102b4ec2","huggingface.json":"209cdcf205961ef2ff203486da614232a86a069ebe0e98266189a14a235fac8f","meta.json":"563f5ec07973f52ab8c3eb26ef91a36ad8a79e950b37174935666cdcb624bf35","minimax-cn.json":"70df757e95e9ea2275bf451956b58a746020835f6cbcbd1a644d7fad5b9941d3","minimax.json":"747038b05f4fc24e41405e8bc810f893d7d5121e214e35e6f812f775769a3806","mistral.json":"aafecc66686645b1baa8c90e81c02856115f09999ff507f9bee004d2e1c77a28","moonshotai-cn.json":"a953eace729ef96c91195d477c63c776a1c40aa36085b61236ca1be0fe5b9337","moonshotai.json":"0435f9dc4e532c0764b6d33d8dfa83ce5fccdbcab54224c5ae74ec2d965290f5","nvidia.json":"0e45bcd4d5a897f6f6785c0e257a9fb03691cef3ff87d9254da5daa5075468da","openai.json":"d61200cdd22d931dfff8181a5ed8d636c89fb34637dcec80f07ec24f8c2ef5c6","opencode-go.json":"2a5e0424854edfc0ef9a49033e80a8eb32c01a98c56ba2879b36a9502baa4027","opencode.json":"52786b917e5207c7b720e3c466b6c517e0cc57c58632c7f1ebf5e68b8fefeece","opengateway.json":"e83e1bc4205c8f906b5f5c9ccea472bc43110fa7c36bdfed27bb818353fb25c1","openrouter.json":"a5966ab090abb6d7ca2ac31b660aa902b09114649b85a167208f7589767b1a46","qwen-token-plan-cn.json":"751b18bd443fceb16659ea33013fed90fbf3bbdb4e0ffd7607c93cee2b4cf40d","qwen-token-plan-individual.json":"35ffb0ba1a1ce3f68fc73262dd5e07fbcb5bf5911ad1e6e17bc0621e2894676a","qwen-token-plan.json":"e59b0a45e238578f80d0eea937a093b9cec7cb93751ae20a9e88b16c09eb5cdd","radius.json":"d05cbfcc585c2b49019c5264e522b7c56565369f80d1f98569211b5bef92145c","together.json":"a68b8386a2f28f9e1570d296223fdbdc0ebcca8a322ade5b999212c0e60b772c","typesafe.json":"83409437dbf4c353ac413c0db4e7cf29902fc35e0e0197bdb4eeda2d7f3b07cd","venice.json":"6614b0b42eaeae73be35239c630414df1268aef624de540781d0fd45a4962c72","vercel-ai-gateway.json":"f1a5c5721321a18b034b150253922547ba142213037253140c91ae457a109de4","xai.json":"cf3f475fe5a13625f858171900ba3456c4d95ebb0bac5060cc25e29bb31d3457","xiaomi-token-plan-ams.json":"7fa339ba5675460b1ff4e5bca9e8ad0aa60b0277d75a989b1c196aa6ca2af34d","xiaomi-token-plan-cn.json":"ef7917c6ea0d3edc655c8a52082ee5f1330658aa6f10199d8f164eb4605ef0a0","xiaomi-token-plan-sgp.json":"addda93f6b70ba879db97e3cfd2e4f2efc7cda47d7daa78c23c5b0e51162de5c","xiaomi.json":"5a42caf49d3e4d7946d60386e9899c2146bf8e3cbaff4c576ee4f49b398cc11c","zai-coding-cn.json":"2b6f85e04b5c568e320b1bde25b1c1614af9342e4c1ba0e1d5bb248aaf50cfe9","zai.json":"e9cc408e1756de8abc70148d63d89d11a63c65b7ef06ad0661cd1328e4209ba3"}}
1
+ {"schemaVersion":6,"generatedAt":"2026-11-03T19:25:26.151Z","structureHash":"f02e0f2116db88980085dffcee84b272042fef2eaff3e6648bf05b485f18502d","files":{"alibaba-token-plan.json":"9f4d42cc765b2a875bcdcaa392bfdc1323c88968309baf9db9f611a26c595c73","amazon-bedrock.json":"a7e20838b095788cb9d5acbde49664b7f2868fad9b10fb4bbbd66635085bca2d","ant-ling.json":"628feab3ef6c7d80ce96f75999804e1d9f05fec3851e5302e30fff3b69db90f6","anthropic.json":"111384e9f5845e0247bd34edf2400ef7720fcbdac140b944cf8878192d8bd6ab","azure-openai-responses.json":"fd64c6a2a99fa87d768ed2f75f5c7813876df1dbe2f0d1776f7d9bd7ce2e61e4","bai.json":"7e6861aaf27d8af34e1771c6092602194fcec0a0046e6adfab9c3ee54d32b99f","baseten.json":"5bd3c98c61769388b3724368ef964d16b7a58e41a6edcf4ebceb9d4ac0a21d3b","cerebras.json":"2eb969b2956844f9a641d3de52c19f1791293c58f607282fb3b0ebfe85ff66f8","chatgpt-subscription.json":"98320f1d51709d26ca047b3d6e3191cfe2f192f1b27897cbb492f47b0e5a5030","cloudflare-ai-gateway.json":"ac281b8cc18eb84ba61f215eff3234d14732cd66239617fb59d6812b13d6473f","cloudflare-workers-ai.json":"1b9ad4360bde817f0ea358431020308f1052840e2278a57a93629f1790072d2e","deepseek.json":"10a296fb3e898f7715c80890c8af0af4f5fd58f22dbcd6612fdc5d762157ccdc","fireworks.json":"56c557eb97573028e871c211cb17e1d60665eb12d67a712615db4bb255bc9253","github-copilot.json":"474fa92eb88ef242208ca93709ebe6d7f21754917d0cad6210bd1edf2b99a87e","google-vertex.json":"8f986b4aca8c685b0f3481bd252bda21e4858bf9015ad37fc5bcc44b7f01d076","google.json":"d25613a7377e81d785d571be514d67b35436511ce6946247dc66f8674e2a5035","groq.json":"087df37206e9eed8b10f1e558e4c496289bef60074b7e8afba4f20fb102b4ec2","huggingface.json":"209cdcf205961ef2ff203486da614232a86a069ebe0e98266189a14a235fac8f","meta.json":"563f5ec07973f52ab8c3eb26ef91a36ad8a79e950b37174935666cdcb624bf35","minimax-cn.json":"70df757e95e9ea2275bf451956b58a746020835f6cbcbd1a644d7fad5b9941d3","minimax.json":"747038b05f4fc24e41405e8bc810f893d7d5121e214e35e6f812f775769a3806","mistral.json":"aafecc66686645b1baa8c90e81c02856115f09999ff507f9bee004d2e1c77a28","moonshotai-cn.json":"a953eace729ef96c91195d477c63c776a1c40aa36085b61236ca1be0fe5b9337","moonshotai.json":"0435f9dc4e532c0764b6d33d8dfa83ce5fccdbcab54224c5ae74ec2d965290f5","nvidia.json":"0e45bcd4d5a897f6f6785c0e257a9fb03691cef3ff87d9254da5daa5075468da","openai.json":"d61200cdd22d931dfff8181a5ed8d636c89fb34637dcec80f07ec24f8c2ef5c6","opencode-go.json":"de809e50975183fc8da3afb29a74bcf9164b6893271484588166a38b9930513f","opencode.json":"52786b917e5207c7b720e3c466b6c517e0cc57c58632c7f1ebf5e68b8fefeece","opengateway.json":"c39301d5db2d88aee71705143a6039ebfce2513ef4648979125def43ef409d49","openrouter.json":"455d8785b312d22cc0e789a6ecce18315bf30399b102b17b8297a38a60d716c8","qwen-token-plan-cn.json":"751b18bd443fceb16659ea33013fed90fbf3bbdb4e0ffd7607c93cee2b4cf40d","qwen-token-plan-individual.json":"35ffb0ba1a1ce3f68fc73262dd5e07fbcb5bf5911ad1e6e17bc0621e2894676a","qwen-token-plan.json":"e59b0a45e238578f80d0eea937a093b9cec7cb93751ae20a9e88b16c09eb5cdd","radius.json":"1e4868b8cef7b63d822584e7b8634111891fd6746983a758660ee8f44fad3400","together.json":"a68b8386a2f28f9e1570d296223fdbdc0ebcca8a322ade5b999212c0e60b772c","typesafe.json":"83409437dbf4c353ac413c0db4e7cf29902fc35e0e0197bdb4eeda2d7f3b07cd","venice.json":"cf6b67c0e15d62a126317e92897634c394f7aeefb5f6c5f99f7c885dbe963aab","vercel-ai-gateway.json":"1b6e25a28fa6b6d229c2c340edb5a850a6f944fa8db272efec7997b6b0fe6dc9","xai.json":"cf3f475fe5a13625f858171900ba3456c4d95ebb0bac5060cc25e29bb31d3457","xiaomi-token-plan-ams.json":"7fa339ba5675460b1ff4e5bca9e8ad0aa60b0277d75a989b1c196aa6ca2af34d","xiaomi-token-plan-cn.json":"ef7917c6ea0d3edc655c8a52082ee5f1330658aa6f10199d8f164eb4605ef0a0","xiaomi-token-plan-sgp.json":"addda93f6b70ba879db97e3cfd2e4f2efc7cda47d7daa78c23c5b0e51162de5c","xiaomi.json":"5a42caf49d3e4d7946d60386e9899c2146bf8e3cbaff4c576ee4f49b398cc11c","zai-coding-cn.json":"2b6f85e04b5c568e320b1bde25b1c1614af9342e4c1ba0e1d5bb248aaf50cfe9","zai.json":"e9cc408e1756de8abc70148d63d89d11a63c65b7ef06ad0661cd1328e4209ba3"}}
@@ -1 +1 @@
1
- {"anthropic-messages":{"chat:claude-haiku-5-5":{"id":"claude-haiku-5-5","name":"Claude Haiku 5.5","api":"anthropic-messages","provider":"opencode-go","baseUrl":"https://opencode.ai/inference/go","reasoning":true,"input":["text","image"],"cost":{"input":0.1,"output":0.5,"cacheRead":0.01,"cacheWrite":0.125,"tiers":[{"inputTokensAbove":100000,"input":0.5,"output":2.5,"cacheRead":0.05,"cacheWrite":0.625}]},"contextWindow":100000,"maxTokens":32000,"thinkingLevelMap":{"xhigh":"xhigh","max":"max"},"compat":{"supportsDisabledThinking":false,"forceAdaptiveThinking":true,"supportsTemperature":false},"inputLimits":{"images":{"resize":{"maxWidth":2000,"maxHeight":2000,"maxBytes":4718592,"jpegQuality":80}}},"type":"chat"},"chat:minimax-m3":{"id":"minimax-m3","name":"MiniMax-M3","api":"anthropic-messages","provider":"opencode-go","baseUrl":"https://opencode.ai/inference/go","reasoning":true,"input":["text","image"],"cost":{"input":0.3,"output":1.2,"cacheRead":0.06,"cacheWrite":0},"contextWindow":1000000,"maxTokens":131072,"inputLimits":{"images":{"resize":{"maxWidth":2000,"maxHeight":2000,"maxBytes":4718592,"jpegQuality":80}}},"type":"chat"},"chat:qwen3.7-plus":{"id":"qwen3.7-plus","name":"Qwen3.7 Plus","api":"anthropic-messages","provider":"opencode-go","baseUrl":"https://opencode.ai/inference/go","reasoning":true,"input":["text","image"],"cost":{"input":0.4,"output":1.6,"cacheRead":0.04,"cacheWrite":0.5},"contextWindow":1000000,"maxTokens":65536,"inputLimits":{"images":{"resize":{"maxWidth":2000,"maxHeight":2000,"maxBytes":4718592,"jpegQuality":80}}},"type":"chat"},"chat:qwen3.8-flash":{"id":"qwen3.8-flash","name":"Qwen3.8 Flash","api":"anthropic-messages","provider":"opencode-go","baseUrl":"https://opencode.ai/inference/go","reasoning":true,"input":["text","image"],"cost":{"input":0.15,"output":0.47,"cacheRead":0.016,"cacheWrite":0.2},"contextWindow":1000000,"maxTokens":131072,"compat":{"allowEmptySignature":true},"inputLimits":{"images":{"resize":{"maxWidth":2000,"maxHeight":2000,"maxBytes":4718592,"jpegQuality":80}}},"type":"chat"},"chat:qwen3.8-max":{"id":"qwen3.8-max","name":"Qwen3.8 Max","api":"anthropic-messages","provider":"opencode-go","baseUrl":"https://opencode.ai/inference/go","reasoning":true,"input":["text","image"],"cost":{"input":2,"output":6,"cacheRead":0.25,"cacheWrite":2.5},"contextWindow":1000000,"maxTokens":131072,"inputLimits":{"images":{"resize":{"maxWidth":2000,"maxHeight":2000,"maxBytes":4718592,"jpegQuality":80}}},"type":"chat"}},"google-generative-ai":{"chat:gemini-4-argon":{"id":"gemini-4-argon","name":"Gemini 4 Argon","api":"google-generative-ai","provider":"opencode-go","baseUrl":"https://opencode.ai/inference/go/v1","reasoning":true,"thinkingLevelMap":{"off":null,"minimal":null,"low":"low","medium":"medium","high":"high","xhigh":null,"max":null},"input":["text","image"],"cost":{"input":2,"output":10,"cacheRead":0.1,"cacheWrite":0},"contextWindow":1048576,"maxTokens":65536,"inputLimits":{"images":{"resize":{"maxWidth":2000,"maxHeight":2000,"maxBytes":4718592,"jpegQuality":80}}},"type":"chat"},"chat:gemini-4-argon-contributor":{"id":"gemini-4-argon-contributor","name":"Gemini 4 Argon Contributor","api":"google-generative-ai","provider":"opencode-go","baseUrl":"https://opencode.ai/inference/go/v1","reasoning":true,"thinkingLevelMap":{"off":null,"minimal":null,"low":"low","medium":"medium","high":"high","xhigh":null,"max":null},"input":["text","image"],"cost":{"input":4,"output":20,"cacheRead":0.2,"cacheWrite":0},"contextWindow":1048576,"maxTokens":65536,"deprecated":true,"inputLimits":{"images":{"resize":{"maxWidth":2000,"maxHeight":2000,"maxBytes":4718592,"jpegQuality":80}}},"type":"chat"}},"openai-completions":{"chat:beam-free":{"id":"beam-free","name":"Beam Free","api":"openai-completions","provider":"opencode-go","baseUrl":"https://opencode.ai/inference/go/v1","reasoning":true,"input":["text"],"cost":{"input":0,"output":0,"cacheRead":0,"cacheWrite":0},"compat":{"supportsStore":false,"supportsDeveloperRole":false,"supportsStrictMode":true,"maxTokensField":"max_tokens"},"contextWindow":1048576,"maxTokens":131072,"thinkingLevelMap":{"off":null,"minimal":null,"low":"low","medium":"medium","high":"high","xhigh":"xhigh","max":"max"},"type":"chat"},"chat:deepseek-v4-pro":{"id":"deepseek-v4-pro","name":"DeepSeek V4 Pro (New)","api":"openai-completions","provider":"opencode-go","baseUrl":"https://opencode.ai/inference/go/v1","reasoning":true,"input":["text"],"cost":{"input":0.66,"output":1.98,"cacheRead":0.022,"cacheWrite":0},"compat":{"supportsStore":false,"supportsDeveloperRole":false,"supportsStrictMode":true,"maxTokensField":"max_tokens","requiresReasoningContentOnAssistantMessages":true,"thinkingFormat":"deepseek"},"contextWindow":1000000,"maxTokens":384000,"thinkingLevelMap":{"minimal":null,"low":null,"medium":null,"high":"high","max":"max"},"type":"chat"},"chat:deepseek-v4.1-flash":{"id":"deepseek-v4.1-flash","name":"DeepSeek V4.1 Flash","api":"openai-completions","provider":"opencode-go","baseUrl":"https://opencode.ai/inference/go/v1","reasoning":true,"thinkingLevelMap":{"off":null,"minimal":null,"low":"low","medium":null,"high":"high","xhigh":null,"max":"max"},"input":["text","image"],"cost":{"input":0.15,"output":0.6,"cacheRead":0.003,"cacheWrite":0},"compat":{"supportsStore":false,"supportsDeveloperRole":false,"supportsStrictMode":true,"maxTokensField":"max_tokens","requiresReasoningContentOnAssistantMessages":true,"thinkingFormat":"deepseek"},"contextWindow":1000000,"maxTokens":384000,"inputLimits":{"images":{"resize":{"maxWidth":2000,"maxHeight":2000,"maxBytes":4718592,"jpegQuality":80}}},"type":"chat"},"chat:glm-5.2":{"id":"glm-5.2","name":"GLM-5.2","api":"openai-completions","provider":"opencode-go","baseUrl":"https://opencode.ai/inference/go/v1","reasoning":true,"input":["text"],"cost":{"input":1.4,"output":4.4,"cacheRead":0.26,"cacheWrite":0},"compat":{"supportsStore":false,"supportsDeveloperRole":false,"supportsStrictMode":true,"maxTokensField":"max_tokens"},"contextWindow":1000000,"maxTokens":131072,"thinkingLevelMap":{"off":null,"minimal":null,"low":null,"medium":null,"high":"high","xhigh":null,"max":"max"},"type":"chat"},"chat:glm-5.3":{"id":"glm-5.3","name":"GLM-5.3","api":"openai-completions","provider":"opencode-go","baseUrl":"https://opencode.ai/inference/go/v1","reasoning":true,"input":["text"],"cost":{"input":1.4,"output":4.4,"cacheRead":0.26,"cacheWrite":0},"compat":{"supportsStore":false,"supportsDeveloperRole":false,"supportsStrictMode":true,"maxTokensField":"max_tokens"},"contextWindow":1000000,"maxTokens":131072,"thinkingLevelMap":{"off":null,"minimal":null,"low":null,"medium":null,"high":"high","xhigh":null,"max":"max"},"type":"chat"},"chat:glm-5.3-flash":{"id":"glm-5.3-flash","name":"GLM-5.3-Flash","api":"openai-completions","provider":"opencode-go","baseUrl":"https://opencode.ai/inference/go/v1","reasoning":true,"input":["text","image"],"cost":{"input":0.15,"output":0.5,"cacheRead":0.03,"cacheWrite":0},"compat":{"supportsStore":false,"supportsDeveloperRole":false,"supportsStrictMode":true,"maxTokensField":"max_tokens"},"contextWindow":1000000,"maxTokens":131072,"thinkingLevelMap":{"off":null,"minimal":null,"low":"low","medium":null,"high":"high","xhigh":null,"max":"max"},"inputLimits":{"images":{"resize":{"maxWidth":2000,"maxHeight":2000,"maxBytes":4718592,"jpegQuality":80}}},"type":"chat"},"chat:hy3":{"id":"hy3","name":"Hy3","api":"openai-completions","provider":"opencode-go","baseUrl":"https://opencode.ai/inference/go/v1","reasoning":true,"input":["text"],"cost":{"input":0.14,"output":0.58,"cacheRead":0.035,"cacheWrite":0},"compat":{"supportsStore":false,"supportsDeveloperRole":false,"supportsStrictMode":true,"maxTokensField":"max_tokens"},"contextWindow":256000,"maxTokens":128000,"thinkingLevelMap":{"off":"none","minimal":null,"low":"low","medium":null,"high":"high","xhigh":null,"max":null},"type":"chat"},"chat:hy4-preview":{"id":"hy4-preview","name":"Hy4 preview","api":"openai-completions","provider":"opencode-go","baseUrl":"https://opencode.ai/inference/go/v1","reasoning":true,"input":["text"],"cost":{"input":0.834,"output":2.501,"cacheRead":0.042,"cacheWrite":0},"compat":{"supportsStore":false,"supportsDeveloperRole":false,"supportsStrictMode":true,"maxTokensField":"max_tokens"},"contextWindow":1024000,"maxTokens":64000,"thinkingLevelMap":{"off":"none","minimal":null,"low":null,"medium":null,"high":"high","xhigh":null,"max":null},"type":"chat"},"chat:iceman-contributor-free":{"id":"iceman-contributor-free","name":"Iceman Contributor Free","api":"openai-completions","provider":"opencode-go","baseUrl":"https://opencode.ai/inference/go/v1","reasoning":true,"input":["text"],"cost":{"input":0,"output":0,"cacheRead":0,"cacheWrite":0},"compat":{"supportsStore":false,"supportsDeveloperRole":false,"supportsStrictMode":true,"maxTokensField":"max_tokens"},"contextWindow":262144,"maxTokens":131072,"type":"chat"},"chat:kimi-k2.7-code":{"id":"kimi-k2.7-code","name":"Kimi K2.7 Code","api":"openai-completions","provider":"opencode-go","baseUrl":"https://opencode.ai/inference/go/v1","reasoning":true,"input":["text","image"],"cost":{"input":0.95,"output":4,"cacheRead":0.19,"cacheWrite":0},"compat":{"supportsStore":false,"supportsDeveloperRole":false,"supportsStrictMode":true,"maxTokensField":"max_tokens"},"contextWindow":262144,"maxTokens":262144,"inputLimits":{"images":{"resize":{"maxWidth":2000,"maxHeight":2000,"maxBytes":4718592,"jpegQuality":80}}},"type":"chat"},"chat:kimi-k3":{"id":"kimi-k3","name":"Kimi K3","api":"openai-completions","provider":"opencode-go","baseUrl":"https://opencode.ai/inference/go/v1","reasoning":true,"input":["text","image"],"cost":{"input":3,"output":15,"cacheRead":0.3,"cacheWrite":3},"compat":{"supportsStore":false,"supportsDeveloperRole":false,"supportsStrictMode":true,"maxTokensField":"max_tokens","supportsMidConvoSystemMessages":true,"supportsMidConvoToolAdditions":true},"contextWindow":1048576,"maxTokens":131072,"thinkingLevelMap":{"off":null,"minimal":null,"low":null,"medium":null,"high":null,"xhigh":null,"max":"max"},"inputLimits":{"images":{"resize":{"maxWidth":2000,"maxHeight":2000,"maxBytes":4718592,"jpegQuality":80}}},"type":"chat"},"chat:kimi-k3.1-pro":{"id":"kimi-k3.1-pro","name":"Kimi K3.1 Pro","api":"openai-completions","provider":"opencode-go","baseUrl":"https://opencode.ai/inference/go/v1","reasoning":true,"input":["text","image"],"cost":{"input":2,"output":10,"cacheRead":0.2,"cacheWrite":2},"compat":{"supportsStore":false,"supportsDeveloperRole":false,"supportsStrictMode":true,"maxTokensField":"max_tokens"},"contextWindow":1048576,"maxTokens":131072,"thinkingLevelMap":{"off":null,"minimal":null,"low":"low","medium":null,"high":"high","xhigh":null,"max":"max"},"inputLimits":{"images":{"resize":{"maxWidth":2000,"maxHeight":2000,"maxBytes":4718592,"jpegQuality":80}}},"type":"chat"},"chat:longcat-2.0":{"id":"longcat-2.0","name":"LongCat-2.0","api":"openai-completions","provider":"opencode-go","baseUrl":"https://opencode.ai/inference/go/v1","reasoning":true,"input":["text"],"cost":{"input":0.3,"output":1.2,"cacheRead":0.006,"cacheWrite":0},"compat":{"supportsStore":false,"supportsDeveloperRole":false,"supportsStrictMode":true,"maxTokensField":"max_tokens"},"contextWindow":1000000,"maxTokens":131072,"type":"chat"},"chat:longcat-2.5-preview-free":{"id":"longcat-2.5-preview-free","name":"LongCat 2.5 Preview Free","api":"openai-completions","provider":"opencode-go","baseUrl":"https://opencode.ai/inference/go/v1","reasoning":true,"input":["text","image"],"cost":{"input":0,"output":0,"cacheRead":0,"cacheWrite":0},"compat":{"supportsStore":false,"supportsDeveloperRole":false,"supportsStrictMode":true,"maxTokensField":"max_tokens"},"contextWindow":1000000,"maxTokens":131072,"deprecated":true,"inputLimits":{"images":{"resize":{"maxWidth":2000,"maxHeight":2000,"maxBytes":4718592,"jpegQuality":80}}},"type":"chat"},"chat:mimo-v2.5":{"id":"mimo-v2.5","name":"MiMo V2.5","api":"openai-completions","provider":"opencode-go","baseUrl":"https://opencode.ai/inference/go/v1","reasoning":true,"input":["text","image"],"cost":{"input":0.14,"output":0.28,"cacheRead":0.0028,"cacheWrite":0},"compat":{"supportsStore":false,"supportsDeveloperRole":false,"supportsStrictMode":true,"maxTokensField":"max_tokens"},"contextWindow":1000000,"maxTokens":128000,"inputLimits":{"images":{"resize":{"maxWidth":2000,"maxHeight":2000,"maxBytes":4718592,"jpegQuality":80}}},"type":"chat"},"chat:mimo-v2.5-pro":{"id":"mimo-v2.5-pro","name":"MiMo V2.5 Pro","api":"openai-completions","provider":"opencode-go","baseUrl":"https://opencode.ai/inference/go/v1","reasoning":true,"input":["text"],"cost":{"input":0.435,"output":0.87,"cacheRead":0.003625,"cacheWrite":0},"compat":{"supportsStore":false,"supportsDeveloperRole":false,"supportsStrictMode":true,"maxTokensField":"max_tokens"},"contextWindow":1048576,"maxTokens":128000,"type":"chat"},"chat:mimo-v2.6-flash":{"id":"mimo-v2.6-flash","name":"MiMo-V2.6-Flash","api":"openai-completions","provider":"opencode-go","baseUrl":"https://opencode.ai/inference/go/v1","reasoning":true,"input":["text","image"],"cost":{"input":0.14,"output":0.28,"cacheRead":0.0028,"cacheWrite":0},"compat":{"supportsStore":false,"supportsDeveloperRole":false,"supportsStrictMode":true,"maxTokensField":"max_tokens"},"contextWindow":1048576,"maxTokens":131072,"inputLimits":{"images":{"resize":{"maxWidth":2000,"maxHeight":2000,"maxBytes":4718592,"jpegQuality":80}}},"type":"chat"},"chat:mimo-v2.6-pro":{"id":"mimo-v2.6-pro","name":"MiMo-V2.6-Pro","api":"openai-completions","provider":"opencode-go","baseUrl":"https://opencode.ai/inference/go/v1","reasoning":true,"input":["text","image"],"cost":{"input":0.435,"output":0.87,"cacheRead":0.003625,"cacheWrite":0},"compat":{"supportsStore":false,"supportsDeveloperRole":false,"supportsStrictMode":true,"maxTokensField":"max_tokens"},"contextWindow":1048576,"maxTokens":131072,"inputLimits":{"images":{"resize":{"maxWidth":2000,"maxHeight":2000,"maxBytes":4718592,"jpegQuality":80}}},"type":"chat"},"chat:minimax-m3.1-flash":{"id":"minimax-m3.1-flash","name":"MiniMax M3.1 Flash","api":"openai-completions","provider":"opencode-go","baseUrl":"https://opencode.ai/inference/go/v1","reasoning":true,"input":["text","image"],"cost":{"input":0.15,"output":0.6,"cacheRead":0.015,"cacheWrite":0},"compat":{"supportsStore":false,"supportsDeveloperRole":false,"supportsStrictMode":true,"maxTokensField":"max_tokens"},"contextWindow":1000000,"maxTokens":512000,"thinkingLevelMap":{"off":null,"minimal":null,"low":"low","medium":"medium","high":"high","xhigh":"xhigh","max":"max"},"inputLimits":{"images":{"resize":{"maxWidth":2000,"maxHeight":2000,"maxBytes":4718592,"jpegQuality":80}}},"type":"chat"},"chat:minimax-m3.1-flash-free":{"id":"minimax-m3.1-flash-free","name":"MiniMax M3.1 Flash Free","api":"openai-completions","provider":"opencode-go","baseUrl":"https://opencode.ai/inference/go/v1","reasoning":true,"input":["text","image"],"cost":{"input":0,"output":0,"cacheRead":0,"cacheWrite":0},"compat":{"supportsStore":false,"supportsDeveloperRole":false,"supportsStrictMode":true,"maxTokensField":"max_tokens"},"contextWindow":1000000,"maxTokens":512000,"deprecated":true,"thinkingLevelMap":{"off":null,"minimal":null,"low":"low","medium":"medium","high":"high","xhigh":"xhigh","max":"max"},"inputLimits":{"images":{"resize":{"maxWidth":2000,"maxHeight":2000,"maxBytes":4718592,"jpegQuality":80}}},"type":"chat"},"chat:step-5-preview":{"id":"step-5-preview","name":"Step 5 Preview","api":"openai-completions","provider":"opencode-go","baseUrl":"https://opencode.ai/inference/go/v1","reasoning":true,"input":["text","image"],"cost":{"input":1,"output":2.7,"cacheRead":0.1,"cacheWrite":0},"compat":{"supportsStore":false,"supportsDeveloperRole":false,"supportsStrictMode":true,"maxTokensField":"max_tokens"},"contextWindow":1000000,"maxTokens":65536,"thinkingLevelMap":{"off":null,"minimal":null,"low":"low","medium":"medium","high":"high","xhigh":null,"max":null},"inputLimits":{"images":{"resize":{"maxWidth":2000,"maxHeight":2000,"maxBytes":4718592,"jpegQuality":80}}},"type":"chat"}},"openai-responses":{"chat:gpt-5.6-luna":{"id":"gpt-5.6-luna","name":"GPT-5.6 Luna","api":"openai-responses","provider":"opencode-go","baseUrl":"https://opencode.ai/inference/go/v1","reasoning":true,"input":["text","image"],"cost":{"input":0.2,"output":1.2,"cacheRead":0.02,"cacheWrite":0.25},"compat":{"sessionAffinityFormat":"openai-nosession","supportsMidConvoSystemMessages":true,"supportsAdditionalTools":true},"contextWindow":922000,"maxTokens":128000,"thinkingLevelMap":{"off":null,"minimal":null,"low":"low","medium":"medium","high":"high","xhigh":"xhigh","max":"max"},"inputLimits":{"images":{"resize":{"maxWidth":2000,"maxHeight":2000,"maxBytes":4718592,"jpegQuality":80}}},"type":"chat"},"chat:gpt-6-luna":{"id":"gpt-6-luna","name":"GPT-6 Luna","api":"openai-responses","provider":"opencode-go","baseUrl":"https://opencode.ai/inference/go/v1","reasoning":true,"input":["text","image"],"cost":{"input":0.1,"output":0.5,"cacheRead":0.01,"cacheWrite":0.125},"compat":{"sessionAffinityFormat":"openai-nosession","supportsMidConvoSystemMessages":true,"supportsAdditionalTools":true},"contextWindow":922000,"maxTokens":128000,"thinkingLevelMap":{"off":"none","minimal":null,"low":"low","medium":"medium","high":"high","xhigh":"xhigh","max":"max"},"inputLimits":{"images":{"resize":{"maxWidth":2000,"maxHeight":2000,"maxBytes":4718592,"jpegQuality":80}}},"type":"chat"},"chat:grok-4.7":{"id":"grok-4.7","name":"Grok 4.7","api":"openai-responses","provider":"opencode-go","baseUrl":"https://opencode.ai/inference/go/v1","reasoning":true,"input":["text","image"],"cost":{"input":2,"output":6,"cacheRead":0.5,"cacheWrite":0},"compat":{"sessionAffinityFormat":"openai-nosession"},"contextWindow":500000,"maxTokens":500000,"thinkingLevelMap":{"off":null,"minimal":null,"low":"low","medium":"medium","high":"high","xhigh":"xhigh","max":null},"inputLimits":{"images":{"resize":{"maxWidth":2000,"maxHeight":2000,"maxBytes":4718592,"jpegQuality":80}}},"type":"chat"},"chat:muse-spark-1.2-contributor":{"id":"muse-spark-1.2-contributor","name":"Muse Spark 1.2 Contributor","api":"openai-responses","provider":"opencode-go","baseUrl":"https://opencode.ai/inference/go/v1","reasoning":true,"input":["text","image"],"cost":{"input":0.1,"output":0.2,"cacheRead":0.002,"cacheWrite":0},"compat":{"sessionAffinityFormat":"openai-nosession"},"contextWindow":1048576,"maxTokens":131072,"thinkingLevelMap":{"off":null,"minimal":"minimal","low":"low","medium":"medium","high":"high","xhigh":"xhigh","max":null},"inputLimits":{"images":{"resize":{"maxWidth":2000,"maxHeight":2000,"maxBytes":4718592,"jpegQuality":80}}},"type":"chat"},"chat:muse-spark-1.3-contributor":{"id":"muse-spark-1.3-contributor","name":"Muse Spark 1.3 Contributor","api":"openai-responses","provider":"opencode-go","baseUrl":"https://opencode.ai/inference/go/v1","reasoning":true,"input":["text","image"],"cost":{"input":0.1,"output":0.2,"cacheRead":0.002,"cacheWrite":0},"compat":{"sessionAffinityFormat":"openai-nosession"},"contextWindow":1048576,"maxTokens":131072,"thinkingLevelMap":{"off":null,"minimal":"minimal","low":"low","medium":"medium","high":"high","xhigh":"xhigh","max":null},"inputLimits":{"images":{"resize":{"maxWidth":2000,"maxHeight":2000,"maxBytes":4718592,"jpegQuality":80}}},"type":"chat"}}}
1
+ {"anthropic-messages":{"chat:claude-haiku-5-5":{"id":"claude-haiku-5-5","name":"Claude Haiku 5.5","api":"anthropic-messages","provider":"opencode-go","baseUrl":"https://opencode.ai/inference/go","reasoning":true,"input":["text","image"],"cost":{"input":0.1,"output":0.5,"cacheRead":0.01,"cacheWrite":0.125,"tiers":[{"inputTokensAbove":100000,"input":0.5,"output":2.5,"cacheRead":0.05,"cacheWrite":0.625}]},"contextWindow":100000,"maxTokens":32000,"thinkingLevelMap":{"xhigh":"xhigh","max":"max"},"compat":{"supportsDisabledThinking":false,"forceAdaptiveThinking":true,"supportsTemperature":false},"inputLimits":{"images":{"resize":{"maxWidth":2000,"maxHeight":2000,"maxBytes":4718592,"jpegQuality":80}}},"type":"chat"},"chat:minimax-m3":{"id":"minimax-m3","name":"MiniMax-M3","api":"anthropic-messages","provider":"opencode-go","baseUrl":"https://opencode.ai/inference/go","reasoning":true,"input":["text","image"],"cost":{"input":0.3,"output":1.2,"cacheRead":0.06,"cacheWrite":0},"contextWindow":1000000,"maxTokens":131072,"inputLimits":{"images":{"resize":{"maxWidth":2000,"maxHeight":2000,"maxBytes":4718592,"jpegQuality":80}}},"type":"chat"},"chat:qwen3.7-plus":{"id":"qwen3.7-plus","name":"Qwen3.7 Plus","api":"anthropic-messages","provider":"opencode-go","baseUrl":"https://opencode.ai/inference/go","reasoning":true,"input":["text","image"],"cost":{"input":0.4,"output":1.6,"cacheRead":0.04,"cacheWrite":0.5},"contextWindow":1000000,"maxTokens":65536,"inputLimits":{"images":{"resize":{"maxWidth":2000,"maxHeight":2000,"maxBytes":4718592,"jpegQuality":80}}},"type":"chat"},"chat:qwen3.8-flash":{"id":"qwen3.8-flash","name":"Qwen3.8 Flash","api":"anthropic-messages","provider":"opencode-go","baseUrl":"https://opencode.ai/inference/go","reasoning":true,"input":["text","image"],"cost":{"input":0.15,"output":0.47,"cacheRead":0.016,"cacheWrite":0.2},"contextWindow":1000000,"maxTokens":131072,"compat":{"allowEmptySignature":true},"inputLimits":{"images":{"resize":{"maxWidth":2000,"maxHeight":2000,"maxBytes":4718592,"jpegQuality":80}}},"type":"chat"},"chat:qwen3.8-max":{"id":"qwen3.8-max","name":"Qwen3.8 Max","api":"anthropic-messages","provider":"opencode-go","baseUrl":"https://opencode.ai/inference/go","reasoning":true,"input":["text","image"],"cost":{"input":2,"output":6,"cacheRead":0.25,"cacheWrite":2.5},"contextWindow":1000000,"maxTokens":131072,"inputLimits":{"images":{"resize":{"maxWidth":2000,"maxHeight":2000,"maxBytes":4718592,"jpegQuality":80}}},"type":"chat"}},"google-generative-ai":{"chat:gemini-4-argon":{"id":"gemini-4-argon","name":"Gemini 4 Argon","api":"google-generative-ai","provider":"opencode-go","baseUrl":"https://opencode.ai/inference/go/v1","reasoning":true,"thinkingLevelMap":{"off":null,"minimal":null,"low":"low","medium":"medium","high":"high","xhigh":null,"max":null},"input":["text","image"],"cost":{"input":2,"output":10,"cacheRead":0.1,"cacheWrite":0},"contextWindow":1048576,"maxTokens":65536,"inputLimits":{"images":{"resize":{"maxWidth":2000,"maxHeight":2000,"maxBytes":4718592,"jpegQuality":80}}},"type":"chat"},"chat:gemini-4-argon-contributor":{"id":"gemini-4-argon-contributor","name":"Gemini 4 Argon Contributor","api":"google-generative-ai","provider":"opencode-go","baseUrl":"https://opencode.ai/inference/go/v1","reasoning":true,"thinkingLevelMap":{"off":null,"minimal":null,"low":"low","medium":"medium","high":"high","xhigh":null,"max":null},"input":["text","image"],"cost":{"input":4,"output":20,"cacheRead":0.2,"cacheWrite":0},"contextWindow":1048576,"maxTokens":65536,"deprecated":true,"inputLimits":{"images":{"resize":{"maxWidth":2000,"maxHeight":2000,"maxBytes":4718592,"jpegQuality":80}}},"type":"chat"}},"openai-completions":{"chat:beam-free":{"id":"beam-free","name":"Beam Free","api":"openai-completions","provider":"opencode-go","baseUrl":"https://opencode.ai/inference/go/v1","reasoning":true,"input":["text"],"cost":{"input":0,"output":0,"cacheRead":0,"cacheWrite":0},"compat":{"supportsStore":false,"supportsDeveloperRole":false,"supportsStrictMode":true,"maxTokensField":"max_tokens"},"contextWindow":1048576,"maxTokens":131072,"thinkingLevelMap":{"off":null,"minimal":null,"low":"low","medium":"medium","high":"high","xhigh":"xhigh","max":"max"},"type":"chat"},"chat:deepseek-v4-pro":{"id":"deepseek-v4-pro","name":"DeepSeek V4 Pro","api":"openai-completions","provider":"opencode-go","baseUrl":"https://opencode.ai/inference/go/v1","reasoning":true,"input":["text"],"cost":{"input":0.66,"output":1.98,"cacheRead":0.022,"cacheWrite":0},"compat":{"supportsStore":false,"supportsDeveloperRole":false,"supportsStrictMode":true,"maxTokensField":"max_tokens","requiresReasoningContentOnAssistantMessages":true,"thinkingFormat":"deepseek"},"contextWindow":1000000,"maxTokens":384000,"thinkingLevelMap":{"minimal":null,"low":null,"medium":null,"high":"high","max":"max"},"type":"chat"},"chat:deepseek-v4.1-flash":{"id":"deepseek-v4.1-flash","name":"DeepSeek V4.1 Flash","api":"openai-completions","provider":"opencode-go","baseUrl":"https://opencode.ai/inference/go/v1","reasoning":true,"thinkingLevelMap":{"off":null,"minimal":null,"low":"low","medium":null,"high":"high","xhigh":null,"max":"max"},"input":["text","image"],"cost":{"input":0.15,"output":0.6,"cacheRead":0.003,"cacheWrite":0},"compat":{"supportsStore":false,"supportsDeveloperRole":false,"supportsStrictMode":true,"maxTokensField":"max_tokens","requiresReasoningContentOnAssistantMessages":true,"thinkingFormat":"deepseek"},"contextWindow":1000000,"maxTokens":384000,"inputLimits":{"images":{"resize":{"maxWidth":2000,"maxHeight":2000,"maxBytes":4718592,"jpegQuality":80}}},"type":"chat"},"chat:glm-5.2":{"id":"glm-5.2","name":"GLM-5.2","api":"openai-completions","provider":"opencode-go","baseUrl":"https://opencode.ai/inference/go/v1","reasoning":true,"input":["text"],"cost":{"input":1.4,"output":4.4,"cacheRead":0.26,"cacheWrite":0},"compat":{"supportsStore":false,"supportsDeveloperRole":false,"supportsStrictMode":true,"maxTokensField":"max_tokens"},"contextWindow":1000000,"maxTokens":131072,"thinkingLevelMap":{"off":null,"minimal":null,"low":null,"medium":null,"high":"high","xhigh":null,"max":"max"},"type":"chat"},"chat:glm-5.3":{"id":"glm-5.3","name":"GLM-5.3","api":"openai-completions","provider":"opencode-go","baseUrl":"https://opencode.ai/inference/go/v1","reasoning":true,"input":["text"],"cost":{"input":1.4,"output":4.4,"cacheRead":0.26,"cacheWrite":0},"compat":{"supportsStore":false,"supportsDeveloperRole":false,"supportsStrictMode":true,"maxTokensField":"max_tokens"},"contextWindow":1000000,"maxTokens":131072,"thinkingLevelMap":{"off":null,"minimal":null,"low":null,"medium":null,"high":"high","xhigh":null,"max":"max"},"type":"chat"},"chat:glm-5.3-flash":{"id":"glm-5.3-flash","name":"GLM-5.3-Flash","api":"openai-completions","provider":"opencode-go","baseUrl":"https://opencode.ai/inference/go/v1","reasoning":true,"input":["text","image"],"cost":{"input":0.15,"output":0.5,"cacheRead":0.03,"cacheWrite":0},"compat":{"supportsStore":false,"supportsDeveloperRole":false,"supportsStrictMode":true,"maxTokensField":"max_tokens"},"contextWindow":1000000,"maxTokens":131072,"thinkingLevelMap":{"off":null,"minimal":null,"low":"low","medium":null,"high":"high","xhigh":null,"max":"max"},"inputLimits":{"images":{"resize":{"maxWidth":2000,"maxHeight":2000,"maxBytes":4718592,"jpegQuality":80}}},"type":"chat"},"chat:hy3":{"id":"hy3","name":"Hy3","api":"openai-completions","provider":"opencode-go","baseUrl":"https://opencode.ai/inference/go/v1","reasoning":true,"input":["text"],"cost":{"input":0.14,"output":0.58,"cacheRead":0.035,"cacheWrite":0},"compat":{"supportsStore":false,"supportsDeveloperRole":false,"supportsStrictMode":true,"maxTokensField":"max_tokens"},"contextWindow":256000,"maxTokens":128000,"thinkingLevelMap":{"off":"none","minimal":null,"low":"low","medium":null,"high":"high","xhigh":null,"max":null},"type":"chat"},"chat:hy4-preview":{"id":"hy4-preview","name":"Hy4 preview","api":"openai-completions","provider":"opencode-go","baseUrl":"https://opencode.ai/inference/go/v1","reasoning":true,"input":["text"],"cost":{"input":0.834,"output":2.501,"cacheRead":0.042,"cacheWrite":0},"compat":{"supportsStore":false,"supportsDeveloperRole":false,"supportsStrictMode":true,"maxTokensField":"max_tokens"},"contextWindow":1024000,"maxTokens":64000,"thinkingLevelMap":{"off":"none","minimal":null,"low":null,"medium":null,"high":"high","xhigh":null,"max":null},"type":"chat"},"chat:iceman-contributor-free":{"id":"iceman-contributor-free","name":"Iceman Contributor Free","api":"openai-completions","provider":"opencode-go","baseUrl":"https://opencode.ai/inference/go/v1","reasoning":true,"input":["text"],"cost":{"input":0,"output":0,"cacheRead":0,"cacheWrite":0},"compat":{"supportsStore":false,"supportsDeveloperRole":false,"supportsStrictMode":true,"maxTokensField":"max_tokens"},"contextWindow":262144,"maxTokens":131072,"type":"chat"},"chat:kimi-k2.7-code":{"id":"kimi-k2.7-code","name":"Kimi K2.7 Code","api":"openai-completions","provider":"opencode-go","baseUrl":"https://opencode.ai/inference/go/v1","reasoning":true,"input":["text","image"],"cost":{"input":0.95,"output":4,"cacheRead":0.19,"cacheWrite":0},"compat":{"supportsStore":false,"supportsDeveloperRole":false,"supportsStrictMode":true,"maxTokensField":"max_tokens"},"contextWindow":262144,"maxTokens":262144,"inputLimits":{"images":{"resize":{"maxWidth":2000,"maxHeight":2000,"maxBytes":4718592,"jpegQuality":80}}},"type":"chat"},"chat:kimi-k3":{"id":"kimi-k3","name":"Kimi K3","api":"openai-completions","provider":"opencode-go","baseUrl":"https://opencode.ai/inference/go/v1","reasoning":true,"input":["text","image"],"cost":{"input":3,"output":15,"cacheRead":0.3,"cacheWrite":3},"compat":{"supportsStore":false,"supportsDeveloperRole":false,"supportsStrictMode":true,"maxTokensField":"max_tokens","supportsMidConvoSystemMessages":true,"supportsMidConvoToolAdditions":true},"contextWindow":1048576,"maxTokens":131072,"thinkingLevelMap":{"off":null,"minimal":null,"low":null,"medium":null,"high":null,"xhigh":null,"max":"max"},"inputLimits":{"images":{"resize":{"maxWidth":2000,"maxHeight":2000,"maxBytes":4718592,"jpegQuality":80}}},"type":"chat"},"chat:kimi-k3.1-pro":{"id":"kimi-k3.1-pro","name":"Kimi K3.1 Pro","api":"openai-completions","provider":"opencode-go","baseUrl":"https://opencode.ai/inference/go/v1","reasoning":true,"input":["text","image"],"cost":{"input":2,"output":10,"cacheRead":0.2,"cacheWrite":2},"compat":{"supportsStore":false,"supportsDeveloperRole":false,"supportsStrictMode":true,"maxTokensField":"max_tokens"},"contextWindow":1048576,"maxTokens":131072,"thinkingLevelMap":{"off":null,"minimal":null,"low":"low","medium":null,"high":"high","xhigh":null,"max":"max"},"inputLimits":{"images":{"resize":{"maxWidth":2000,"maxHeight":2000,"maxBytes":4718592,"jpegQuality":80}}},"type":"chat"},"chat:longcat-2.0":{"id":"longcat-2.0","name":"LongCat-2.0","api":"openai-completions","provider":"opencode-go","baseUrl":"https://opencode.ai/inference/go/v1","reasoning":true,"input":["text"],"cost":{"input":0.3,"output":1.2,"cacheRead":0.006,"cacheWrite":0},"compat":{"supportsStore":false,"supportsDeveloperRole":false,"supportsStrictMode":true,"maxTokensField":"max_tokens"},"contextWindow":1000000,"maxTokens":131072,"type":"chat"},"chat:longcat-2.5-preview-free":{"id":"longcat-2.5-preview-free","name":"LongCat 2.5 Preview Free","api":"openai-completions","provider":"opencode-go","baseUrl":"https://opencode.ai/inference/go/v1","reasoning":true,"input":["text","image"],"cost":{"input":0,"output":0,"cacheRead":0,"cacheWrite":0},"compat":{"supportsStore":false,"supportsDeveloperRole":false,"supportsStrictMode":true,"maxTokensField":"max_tokens"},"contextWindow":1000000,"maxTokens":131072,"deprecated":true,"inputLimits":{"images":{"resize":{"maxWidth":2000,"maxHeight":2000,"maxBytes":4718592,"jpegQuality":80}}},"type":"chat"},"chat:mimo-v2.5":{"id":"mimo-v2.5","name":"MiMo V2.5","api":"openai-completions","provider":"opencode-go","baseUrl":"https://opencode.ai/inference/go/v1","reasoning":true,"input":["text","image"],"cost":{"input":0.14,"output":0.28,"cacheRead":0.0028,"cacheWrite":0},"compat":{"supportsStore":false,"supportsDeveloperRole":false,"supportsStrictMode":true,"maxTokensField":"max_tokens"},"contextWindow":1000000,"maxTokens":128000,"inputLimits":{"images":{"resize":{"maxWidth":2000,"maxHeight":2000,"maxBytes":4718592,"jpegQuality":80}}},"type":"chat"},"chat:mimo-v2.5-pro":{"id":"mimo-v2.5-pro","name":"MiMo V2.5 Pro","api":"openai-completions","provider":"opencode-go","baseUrl":"https://opencode.ai/inference/go/v1","reasoning":true,"input":["text"],"cost":{"input":0.435,"output":0.87,"cacheRead":0.003625,"cacheWrite":0},"compat":{"supportsStore":false,"supportsDeveloperRole":false,"supportsStrictMode":true,"maxTokensField":"max_tokens"},"contextWindow":1048576,"maxTokens":128000,"type":"chat"},"chat:mimo-v2.6-flash":{"id":"mimo-v2.6-flash","name":"MiMo-V2.6-Flash","api":"openai-completions","provider":"opencode-go","baseUrl":"https://opencode.ai/inference/go/v1","reasoning":true,"input":["text","image"],"cost":{"input":0.14,"output":0.28,"cacheRead":0.0028,"cacheWrite":0},"compat":{"supportsStore":false,"supportsDeveloperRole":false,"supportsStrictMode":true,"maxTokensField":"max_tokens"},"contextWindow":1048576,"maxTokens":131072,"inputLimits":{"images":{"resize":{"maxWidth":2000,"maxHeight":2000,"maxBytes":4718592,"jpegQuality":80}}},"type":"chat"},"chat:mimo-v2.6-pro":{"id":"mimo-v2.6-pro","name":"MiMo-V2.6-Pro","api":"openai-completions","provider":"opencode-go","baseUrl":"https://opencode.ai/inference/go/v1","reasoning":true,"input":["text","image"],"cost":{"input":0.435,"output":0.87,"cacheRead":0.003625,"cacheWrite":0},"compat":{"supportsStore":false,"supportsDeveloperRole":false,"supportsStrictMode":true,"maxTokensField":"max_tokens"},"contextWindow":1048576,"maxTokens":131072,"inputLimits":{"images":{"resize":{"maxWidth":2000,"maxHeight":2000,"maxBytes":4718592,"jpegQuality":80}}},"type":"chat"},"chat:minimax-m3.1-flash":{"id":"minimax-m3.1-flash","name":"MiniMax M3.1 Flash","api":"openai-completions","provider":"opencode-go","baseUrl":"https://opencode.ai/inference/go/v1","reasoning":true,"input":["text","image"],"cost":{"input":0.15,"output":0.6,"cacheRead":0.015,"cacheWrite":0},"compat":{"supportsStore":false,"supportsDeveloperRole":false,"supportsStrictMode":true,"maxTokensField":"max_tokens"},"contextWindow":1000000,"maxTokens":512000,"thinkingLevelMap":{"off":null,"minimal":null,"low":"low","medium":"medium","high":"high","xhigh":"xhigh","max":"max"},"inputLimits":{"images":{"resize":{"maxWidth":2000,"maxHeight":2000,"maxBytes":4718592,"jpegQuality":80}}},"type":"chat"},"chat:minimax-m3.1-flash-free":{"id":"minimax-m3.1-flash-free","name":"MiniMax M3.1 Flash Free","api":"openai-completions","provider":"opencode-go","baseUrl":"https://opencode.ai/inference/go/v1","reasoning":true,"input":["text","image"],"cost":{"input":0,"output":0,"cacheRead":0,"cacheWrite":0},"compat":{"supportsStore":false,"supportsDeveloperRole":false,"supportsStrictMode":true,"maxTokensField":"max_tokens"},"contextWindow":1000000,"maxTokens":512000,"deprecated":true,"thinkingLevelMap":{"off":null,"minimal":null,"low":"low","medium":"medium","high":"high","xhigh":"xhigh","max":"max"},"inputLimits":{"images":{"resize":{"maxWidth":2000,"maxHeight":2000,"maxBytes":4718592,"jpegQuality":80}}},"type":"chat"},"chat:step-5-preview":{"id":"step-5-preview","name":"Step 5 Preview","api":"openai-completions","provider":"opencode-go","baseUrl":"https://opencode.ai/inference/go/v1","reasoning":true,"input":["text","image"],"cost":{"input":1,"output":2.7,"cacheRead":0.1,"cacheWrite":0},"compat":{"supportsStore":false,"supportsDeveloperRole":false,"supportsStrictMode":true,"maxTokensField":"max_tokens"},"contextWindow":1000000,"maxTokens":65536,"thinkingLevelMap":{"off":null,"minimal":null,"low":"low","medium":"medium","high":"high","xhigh":null,"max":null},"inputLimits":{"images":{"resize":{"maxWidth":2000,"maxHeight":2000,"maxBytes":4718592,"jpegQuality":80}}},"type":"chat"}},"openai-responses":{"chat:gpt-5.6-luna":{"id":"gpt-5.6-luna","name":"GPT-5.6 Luna","api":"openai-responses","provider":"opencode-go","baseUrl":"https://opencode.ai/inference/go/v1","reasoning":true,"input":["text","image"],"cost":{"input":0.2,"output":1.2,"cacheRead":0.02,"cacheWrite":0.25},"compat":{"sessionAffinityFormat":"openai-nosession","supportsMidConvoSystemMessages":true,"supportsAdditionalTools":true},"contextWindow":922000,"maxTokens":128000,"thinkingLevelMap":{"off":null,"minimal":null,"low":"low","medium":"medium","high":"high","xhigh":"xhigh","max":"max"},"inputLimits":{"images":{"resize":{"maxWidth":2000,"maxHeight":2000,"maxBytes":4718592,"jpegQuality":80}}},"type":"chat"},"chat:gpt-6-luna":{"id":"gpt-6-luna","name":"GPT-6 Luna","api":"openai-responses","provider":"opencode-go","baseUrl":"https://opencode.ai/inference/go/v1","reasoning":true,"input":["text","image"],"cost":{"input":0.1,"output":0.5,"cacheRead":0.01,"cacheWrite":0.125},"compat":{"sessionAffinityFormat":"openai-nosession","supportsMidConvoSystemMessages":true,"supportsAdditionalTools":true},"contextWindow":922000,"maxTokens":128000,"thinkingLevelMap":{"off":"none","minimal":null,"low":"low","medium":"medium","high":"high","xhigh":"xhigh","max":"max"},"inputLimits":{"images":{"resize":{"maxWidth":2000,"maxHeight":2000,"maxBytes":4718592,"jpegQuality":80}}},"type":"chat"},"chat:grok-4.7":{"id":"grok-4.7","name":"Grok 4.7","api":"openai-responses","provider":"opencode-go","baseUrl":"https://opencode.ai/inference/go/v1","reasoning":true,"input":["text","image"],"cost":{"input":2,"output":6,"cacheRead":0.5,"cacheWrite":0},"compat":{"sessionAffinityFormat":"openai-nosession"},"contextWindow":500000,"maxTokens":500000,"thinkingLevelMap":{"off":null,"minimal":null,"low":"low","medium":"medium","high":"high","xhigh":"xhigh","max":null},"inputLimits":{"images":{"resize":{"maxWidth":2000,"maxHeight":2000,"maxBytes":4718592,"jpegQuality":80}}},"type":"chat"},"chat:muse-spark-1.2-contributor":{"id":"muse-spark-1.2-contributor","name":"Muse Spark 1.2 Contributor","api":"openai-responses","provider":"opencode-go","baseUrl":"https://opencode.ai/inference/go/v1","reasoning":true,"input":["text","image"],"cost":{"input":0.1,"output":0.2,"cacheRead":0.002,"cacheWrite":0},"compat":{"sessionAffinityFormat":"openai-nosession"},"contextWindow":1048576,"maxTokens":131072,"thinkingLevelMap":{"off":null,"minimal":"minimal","low":"low","medium":"medium","high":"high","xhigh":"xhigh","max":null},"inputLimits":{"images":{"resize":{"maxWidth":2000,"maxHeight":2000,"maxBytes":4718592,"jpegQuality":80}}},"type":"chat"},"chat:muse-spark-1.3-contributor":{"id":"muse-spark-1.3-contributor","name":"Muse Spark 1.3 Contributor","api":"openai-responses","provider":"opencode-go","baseUrl":"https://opencode.ai/inference/go/v1","reasoning":true,"input":["text","image"],"cost":{"input":0.1,"output":0.2,"cacheRead":0.002,"cacheWrite":0},"compat":{"sessionAffinityFormat":"openai-nosession"},"contextWindow":1048576,"maxTokens":131072,"thinkingLevelMap":{"off":null,"minimal":"minimal","low":"low","medium":"medium","high":"high","xhigh":"xhigh","max":null},"inputLimits":{"images":{"resize":{"maxWidth":2000,"maxHeight":2000,"maxBytes":4718592,"jpegQuality":80}}},"type":"chat"}}}