@cortexkit/opencode-claustrum-auth 0.1.1 → 0.1.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.
package/dist/index.js CHANGED
@@ -94,6 +94,26 @@ function transitionActivation(previous, event) {
94
94
  }
95
95
  return result;
96
96
  }
97
+ // ../core/src/balance.ts
98
+ var balanceProbeMs = 5 * 60 * 1000;
99
+ function isBalanceFailure(service, body) {
100
+ if (service === "deepseek")
101
+ return true;
102
+ if (service !== "openrouter")
103
+ return false;
104
+ try {
105
+ const value = JSON.parse(body ?? "");
106
+ if (typeof value !== "object" || value === null || !("error" in value))
107
+ return false;
108
+ const error = value.error;
109
+ if (typeof error !== "object" || error === null || !("metadata" in error))
110
+ return false;
111
+ const metadata = error.metadata;
112
+ return typeof metadata === "object" && metadata !== null && "limit_source" in metadata && metadata.limit_source === "openrouter_credits" && (!("reason" in metadata) || metadata.reason !== "weight_exceeds_budget");
113
+ } catch {
114
+ return false;
115
+ }
116
+ }
97
117
  // ../../node_modules/.bun/@cortexkit+common-auth@0.29.1+e881539e648aba62/node_modules/@cortexkit/common-auth/dist/redaction/index.js
98
118
  import { types } from "node:util";
99
119
 
@@ -1076,7 +1096,7 @@ function retryExpiry(response, now) {
1076
1096
  if (Number.isFinite(date) && date > now)
1077
1097
  return date;
1078
1098
  }
1079
- return now + 60000;
1099
+ return now + (response.status === 402 ? balanceProbeMs : 60000);
1080
1100
  }
1081
1101
  function limited(marks, now) {
1082
1102
  const expiries = [...marks.values()].filter((expiry) => expiry > now);
@@ -1109,6 +1129,7 @@ function createFetch(options) {
1109
1129
  const tried = new Set;
1110
1130
  const secrets = [];
1111
1131
  let saw429 = false;
1132
+ let saw402 = false;
1112
1133
  try {
1113
1134
  for (;; ) {
1114
1135
  signal.throwIfAborted();
@@ -1119,6 +1140,7 @@ function createFetch(options) {
1119
1140
  throw new ClaustrumAuthError("no-vault-account");
1120
1141
  }
1121
1142
  tried.add(route);
1143
+ const previousMark = rateLimitMarks.get(route);
1122
1144
  let target = url;
1123
1145
  let method = template.method;
1124
1146
  let bytes = body;
@@ -1168,11 +1190,26 @@ function createFetch(options) {
1168
1190
  }
1169
1191
  target = next;
1170
1192
  }
1171
- if (response.status !== 429 && response.status !== 401)
1193
+ let balance402 = false;
1194
+ if (response.status === 402) {
1195
+ let text;
1196
+ if (options.entry.service === "openrouter") {
1197
+ try {
1198
+ text = await response.clone().text();
1199
+ } catch {}
1200
+ }
1201
+ balance402 = isBalanceFailure(options.entry.service, text);
1202
+ }
1203
+ if ((response.ok || response.status === 402 && !balance402) && previousMark !== undefined && previousMark <= now() && rateLimitMarks.get(route) === previousMark)
1204
+ rateLimitMarks.delete(route);
1205
+ if (response.status !== 401 && response.status !== 429 && !balance402)
1172
1206
  return await redactResponse(response, secrets);
1173
1207
  signal.throwIfAborted();
1174
- if (response.status === 429) {
1175
- saw429 = true;
1208
+ if (response.status === 429 || balance402) {
1209
+ if (response.status === 429)
1210
+ saw429 = true;
1211
+ else
1212
+ saw402 = true;
1176
1213
  rateLimitMarks.set(route, retryExpiry(response, now()));
1177
1214
  }
1178
1215
  const next = orderedRoutes(routing, tried)[0];
@@ -1180,7 +1217,7 @@ function createFetch(options) {
1180
1217
  await response.body?.cancel().catch(() => {});
1181
1218
  continue;
1182
1219
  }
1183
- if (response.status === 401 && saw429) {
1220
+ if (saw429 && (response.status === 401 || saw402)) {
1184
1221
  await response.body?.cancel().catch(() => {});
1185
1222
  return limited(rateLimitMarks, now());
1186
1223
  }
@@ -7185,6 +7222,20 @@ var supportedProviders = [
7185
7222
  class: "A",
7186
7223
  origins: ["https://api.kimi.com", "https://api.kimi.ai"]
7187
7224
  },
7225
+ {
7226
+ service: "minimax-coding-plan",
7227
+ ids: ["minimax-coding-plan"],
7228
+ hosts: { opencode2: "minimax-coding-plan" },
7229
+ class: "A",
7230
+ origins: ["https://api.minimax.io"]
7231
+ },
7232
+ {
7233
+ service: "ollama-cloud",
7234
+ ids: ["ollama-cloud"],
7235
+ hosts: { opencode1: "ollama-cloud", opencode2: "ollama-cloud" },
7236
+ class: "A",
7237
+ origins: ["https://ollama.com"]
7238
+ },
7188
7239
  {
7189
7240
  service: "openrouter",
7190
7241
  ids: ["openrouter"],
@@ -7196,6 +7247,13 @@ var supportedProviders = [
7196
7247
  class: "A",
7197
7248
  origins: ["https://openrouter.ai"]
7198
7249
  },
7250
+ {
7251
+ service: "synthetic",
7252
+ ids: ["synthetic"],
7253
+ hosts: { opencode1: "synthetic", opencode2: "synthetic" },
7254
+ class: "A",
7255
+ origins: ["https://api.synthetic.new"]
7256
+ },
7199
7257
  {
7200
7258
  service: "typesafe",
7201
7259
  ids: ["typesafe"],
package/dist/server.js CHANGED
@@ -94,6 +94,26 @@ function transitionActivation(previous, event) {
94
94
  }
95
95
  return result;
96
96
  }
97
+ // ../core/src/balance.ts
98
+ var balanceProbeMs = 5 * 60 * 1000;
99
+ function isBalanceFailure(service, body) {
100
+ if (service === "deepseek")
101
+ return true;
102
+ if (service !== "openrouter")
103
+ return false;
104
+ try {
105
+ const value = JSON.parse(body ?? "");
106
+ if (typeof value !== "object" || value === null || !("error" in value))
107
+ return false;
108
+ const error = value.error;
109
+ if (typeof error !== "object" || error === null || !("metadata" in error))
110
+ return false;
111
+ const metadata = error.metadata;
112
+ return typeof metadata === "object" && metadata !== null && "limit_source" in metadata && metadata.limit_source === "openrouter_credits" && (!("reason" in metadata) || metadata.reason !== "weight_exceeds_budget");
113
+ } catch {
114
+ return false;
115
+ }
116
+ }
97
117
  // ../../node_modules/.bun/@cortexkit+common-auth@0.29.1+e881539e648aba62/node_modules/@cortexkit/common-auth/dist/redaction/index.js
98
118
  import { types } from "node:util";
99
119
 
@@ -1110,7 +1130,7 @@ function retryExpiry(response, now) {
1110
1130
  if (Number.isFinite(date) && date > now)
1111
1131
  return date;
1112
1132
  }
1113
- return now + 60000;
1133
+ return now + (response.status === 402 ? balanceProbeMs : 60000);
1114
1134
  }
1115
1135
  function limited(marks, now) {
1116
1136
  const expiries = [...marks.values()].filter((expiry) => expiry > now);
@@ -1143,6 +1163,7 @@ function createFetch(options) {
1143
1163
  const tried = new Set;
1144
1164
  const secrets = [];
1145
1165
  let saw429 = false;
1166
+ let saw402 = false;
1146
1167
  try {
1147
1168
  for (;; ) {
1148
1169
  signal.throwIfAborted();
@@ -1153,6 +1174,7 @@ function createFetch(options) {
1153
1174
  throw new ClaustrumAuthError("no-vault-account");
1154
1175
  }
1155
1176
  tried.add(route);
1177
+ const previousMark = rateLimitMarks.get(route);
1156
1178
  let target = url;
1157
1179
  let method = template.method;
1158
1180
  let bytes = body;
@@ -1202,11 +1224,26 @@ function createFetch(options) {
1202
1224
  }
1203
1225
  target = next;
1204
1226
  }
1205
- if (response.status !== 429 && response.status !== 401)
1227
+ let balance402 = false;
1228
+ if (response.status === 402) {
1229
+ let text;
1230
+ if (options.entry.service === "openrouter") {
1231
+ try {
1232
+ text = await response.clone().text();
1233
+ } catch {}
1234
+ }
1235
+ balance402 = isBalanceFailure(options.entry.service, text);
1236
+ }
1237
+ if ((response.ok || response.status === 402 && !balance402) && previousMark !== undefined && previousMark <= now() && rateLimitMarks.get(route) === previousMark)
1238
+ rateLimitMarks.delete(route);
1239
+ if (response.status !== 401 && response.status !== 429 && !balance402)
1206
1240
  return await redactResponse(response, secrets);
1207
1241
  signal.throwIfAborted();
1208
- if (response.status === 429) {
1209
- saw429 = true;
1242
+ if (response.status === 429 || balance402) {
1243
+ if (response.status === 429)
1244
+ saw429 = true;
1245
+ else
1246
+ saw402 = true;
1210
1247
  rateLimitMarks.set(route, retryExpiry(response, now()));
1211
1248
  }
1212
1249
  const next = orderedRoutes(routing, tried)[0];
@@ -1214,7 +1251,7 @@ function createFetch(options) {
1214
1251
  await response.body?.cancel().catch(() => {});
1215
1252
  continue;
1216
1253
  }
1217
- if (response.status === 401 && saw429) {
1254
+ if (saw429 && (response.status === 401 || saw402)) {
1218
1255
  await response.body?.cancel().catch(() => {});
1219
1256
  return limited(rateLimitMarks, now());
1220
1257
  }
@@ -7219,6 +7256,20 @@ var supportedProviders = [
7219
7256
  class: "A",
7220
7257
  origins: ["https://api.kimi.com", "https://api.kimi.ai"]
7221
7258
  },
7259
+ {
7260
+ service: "minimax-coding-plan",
7261
+ ids: ["minimax-coding-plan"],
7262
+ hosts: { opencode2: "minimax-coding-plan" },
7263
+ class: "A",
7264
+ origins: ["https://api.minimax.io"]
7265
+ },
7266
+ {
7267
+ service: "ollama-cloud",
7268
+ ids: ["ollama-cloud"],
7269
+ hosts: { opencode1: "ollama-cloud", opencode2: "ollama-cloud" },
7270
+ class: "A",
7271
+ origins: ["https://ollama.com"]
7272
+ },
7222
7273
  {
7223
7274
  service: "openrouter",
7224
7275
  ids: ["openrouter"],
@@ -7230,6 +7281,13 @@ var supportedProviders = [
7230
7281
  class: "A",
7231
7282
  origins: ["https://openrouter.ai"]
7232
7283
  },
7284
+ {
7285
+ service: "synthetic",
7286
+ ids: ["synthetic"],
7287
+ hosts: { opencode1: "synthetic", opencode2: "synthetic" },
7288
+ class: "A",
7289
+ origins: ["https://api.synthetic.new"]
7290
+ },
7233
7291
  {
7234
7292
  service: "typesafe",
7235
7293
  ids: ["typesafe"],
@@ -9354,34 +9412,32 @@ function frameCode(event) {
9354
9412
  const code = event.code ?? nested?.code ?? nested?.type;
9355
9413
  return typeof code === "string" ? code : undefined;
9356
9414
  }
9357
- function inspectResponsesFrame(data, attempt) {
9415
+ function inspectResponsesFrame(data, attempt, service) {
9358
9416
  let event;
9359
9417
  try {
9360
9418
  event = JSON.parse(data);
9361
9419
  } catch {
9362
- return;
9420
+ return { outputStarted: true };
9363
9421
  }
9364
9422
  if (!isRecord6(event))
9365
- return;
9423
+ return { outputStarted: true };
9366
9424
  const type = typeof event.type === "string" ? event.type : event.error != null ? "error" : undefined;
9367
- if (type === undefined)
9425
+ if (type === "response.created" || type === "response.in_progress" || type?.startsWith("codex."))
9368
9426
  return;
9369
9427
  if (type === "response.completed" || type === "response.incomplete")
9370
- return { done: true };
9428
+ return { done: true, outputStarted: true };
9371
9429
  if (type === "error" || type === "response.failed") {
9372
9430
  const status = frameStatus(event);
9373
9431
  if (attempt && status !== undefined)
9374
9432
  attempt.frameStatus = status;
9375
9433
  const code = frameCode(event);
9376
- const limited = status === 429 || code !== undefined && /rate.?limit/iu.test(code);
9434
+ const limited = status !== 402 && (status === 429 || code !== undefined && /rate.?limit/iu.test(code));
9377
9435
  return {
9378
9436
  error: "the provider answered with an error frame",
9379
- ...limited ? { limit: { reason: "rate-limit", status: status ?? 429 } } : {}
9437
+ ...status === 402 && isBalanceFailure(service, data) ? { limit: { reason: "payment-required", status } } : limited ? { limit: { reason: "rate-limit", status: status ?? 429 } } : {}
9380
9438
  };
9381
9439
  }
9382
- if (type.startsWith("response.") && type.endsWith(".delta"))
9383
- return { outputStarted: true };
9384
- return;
9440
+ return { outputStarted: true };
9385
9441
  }
9386
9442
  var defaultMarkMs = 60000;
9387
9443
  function retryAfterMs(headers, now) {
@@ -9395,7 +9451,7 @@ function retryAfterMs(headers, now) {
9395
9451
  return Number.isFinite(date) && date > now ? date - now : undefined;
9396
9452
  }
9397
9453
  function markUntil(limit, now) {
9398
- return now + (limit.retryAfterMs ?? defaultMarkMs);
9454
+ return now + (limit.retryAfterMs ?? (limit.status === 402 ? balanceProbeMs : defaultMarkMs));
9399
9455
  }
9400
9456
  async function rebuild(request, url, headers) {
9401
9457
  const body = request.body === null ? undefined : await request.clone().arrayBuffer();
@@ -9422,7 +9478,7 @@ function createVaultAdapter(options) {
9422
9478
  now,
9423
9479
  rateLimitMarks: marks
9424
9480
  }, tried);
9425
- const inspectEvent = options.entry.handshakeOrigins?.length ? ({ transport, data, attempt }) => transport === "ws" ? inspectResponsesFrame(data, attempt.data) : undefined : undefined;
9481
+ const inspectEvent = options.entry.handshakeOrigins?.length ? ({ transport, data, attempt }) => transport === "ws" ? inspectResponsesFrame(data, attempt.data, options.entry.service) : undefined : undefined;
9426
9482
  const noAccount = async () => {
9427
9483
  let mode;
9428
9484
  try {
@@ -9538,12 +9594,22 @@ function createVaultAdapter(options) {
9538
9594
  return;
9539
9595
  return redactResponse(response, [secret]);
9540
9596
  },
9541
- limitFromResponse({ status, headers }) {
9542
- if (status !== 429)
9597
+ async limitFromResponse({ status, headers, body }) {
9598
+ if (status !== 429 && status !== 402)
9543
9599
  return;
9600
+ if (status === 402) {
9601
+ let text;
9602
+ if (options.entry.service === "openrouter") {
9603
+ try {
9604
+ text = await body();
9605
+ } catch {}
9606
+ }
9607
+ if (!isBalanceFailure(options.entry.service, text))
9608
+ return;
9609
+ }
9544
9610
  const wait = retryAfterMs(headers, now());
9545
9611
  return {
9546
- reason: "rate-limit",
9612
+ reason: status === 402 ? "payment-required" : "rate-limit",
9547
9613
  status,
9548
9614
  ...wait === undefined ? {} : { retryAfterMs: wait }
9549
9615
  };
package/dist/setup-bin.js CHANGED
@@ -7,6 +7,8 @@ import { pathToFileURL } from "node:url";
7
7
  // src/setup.ts
8
8
  import { homedir as homedir2 } from "node:os";
9
9
  import path2 from "node:path";
10
+ // ../core/src/balance.ts
11
+ var balanceProbeMs = 5 * 60 * 1000;
10
12
  // ../../node_modules/.bun/@cortexkit+common-auth@0.29.1+e881539e648aba62/node_modules/@cortexkit/common-auth/dist/logger/redact.js
11
13
  var SECRET_KEY_EXACT = /^(authorization|x-api-key|cookie|set-cookie|refresh|access|token)$/i;
12
14
  var TOKEN_VALUE = /\b(Bearer\s+[\w.-]+|sk-[\w-]+|eyJ[\w.-]+)\b|ckh_[A-Za-z0-9_-]{20,}/g;
@@ -5787,6 +5789,20 @@ var supportedProviders = [
5787
5789
  class: "A",
5788
5790
  origins: ["https://api.kimi.com", "https://api.kimi.ai"]
5789
5791
  },
5792
+ {
5793
+ service: "minimax-coding-plan",
5794
+ ids: ["minimax-coding-plan"],
5795
+ hosts: { opencode2: "minimax-coding-plan" },
5796
+ class: "A",
5797
+ origins: ["https://api.minimax.io"]
5798
+ },
5799
+ {
5800
+ service: "ollama-cloud",
5801
+ ids: ["ollama-cloud"],
5802
+ hosts: { opencode1: "ollama-cloud", opencode2: "ollama-cloud" },
5803
+ class: "A",
5804
+ origins: ["https://ollama.com"]
5805
+ },
5790
5806
  {
5791
5807
  service: "openrouter",
5792
5808
  ids: ["openrouter"],
@@ -5798,6 +5814,13 @@ var supportedProviders = [
5798
5814
  class: "A",
5799
5815
  origins: ["https://openrouter.ai"]
5800
5816
  },
5817
+ {
5818
+ service: "synthetic",
5819
+ ids: ["synthetic"],
5820
+ hosts: { opencode1: "synthetic", opencode2: "synthetic" },
5821
+ class: "A",
5822
+ origins: ["https://api.synthetic.new"]
5823
+ },
5801
5824
  {
5802
5825
  service: "typesafe",
5803
5826
  ids: ["typesafe"],
@@ -6014,7 +6037,7 @@ import {
6014
6037
  // ../pi/package.json
6015
6038
  var package_default = {
6016
6039
  name: "@cortexkit/pi-claustrum-auth",
6017
- version: "0.1.1",
6040
+ version: "0.1.3",
6018
6041
  description: "Claustrum vault credentials for Pi",
6019
6042
  type: "module",
6020
6043
  license: "MIT",
@@ -6063,7 +6086,7 @@ var package_default = {
6063
6086
  // package.json
6064
6087
  var package_default2 = {
6065
6088
  name: "@cortexkit/opencode-claustrum-auth",
6066
- version: "0.1.1",
6089
+ version: "0.1.3",
6067
6090
  description: "Claustrum vault credentials for OpenCode 1 and OpenCode 2",
6068
6091
  type: "module",
6069
6092
  license: "MIT",
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@cortexkit/opencode-claustrum-auth",
3
- "version": "0.1.1",
3
+ "version": "0.1.3",
4
4
  "description": "Claustrum vault credentials for OpenCode 1 and OpenCode 2",
5
5
  "type": "module",
6
6
  "license": "MIT",