omnigateway 0.12.11 → 0.12.13
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/README.md +1 -0
- package/bin/omni.js +488 -119
- package/gateway.js +488 -111
- package/package.json +1 -1
- package/public/assets/{Chip-D4qvhu1D.js → Chip-D0XSbQUr.js} +1 -1
- package/public/assets/{CopyValue-SnsT2LML.js → CopyValue-DAlmkISB.js} +3 -3
- package/public/assets/{Field-BYBri2NV.js → Field-DG1317zr.js} +1 -1
- package/public/assets/Lamp-Dk9XrTCg.js +26 -0
- package/public/assets/{Panel-CWmOTDAP.js → Panel-CsovmtxF.js} +23 -4
- package/public/assets/Rack-CDUOJkS2.js +483 -0
- package/public/assets/{Readout-BTh732hP.js → Readout-DlT5oxGO.js} +1 -1
- package/public/assets/RequestTable-i3TtCB9m.js +93 -0
- package/public/assets/{SummaryDeck-7ivuca39.js → SummaryDeck-DrzTQQo5.js} +2 -2
- package/public/assets/{Toggle-t82IhqEt.js → Toggle-CdMD58sy.js} +1 -1
- package/public/assets/{TokenBreakdown-D1Wtza1y.js → TokenBreakdown-BC6nqo1v.js} +1 -1
- package/public/assets/{WindowChart-BeGPsccS.js → WindowChart-Bqbl-KFO.js} +2 -2
- package/public/assets/_app-CSru2YTE.js +1 -0
- package/public/assets/_app.accounts-B2lQkMb0.js +70 -0
- package/public/assets/_app.console-a2TJDoBC.js +24 -0
- package/public/assets/_app.database-CqSoTi2l.js +24 -0
- package/public/assets/_app.index-BV1kJJjA.js +67 -0
- package/public/assets/_app.keys-Dq5O0AG9.js +92 -0
- package/public/assets/_app.logs-PjRK5wqy.js +46 -0
- package/public/assets/_app.models-BfmeeB5e.js +148 -0
- package/public/assets/_app.plugins._pluginId-Owb05aFv.js +20 -0
- package/public/assets/{_app.settings-C3GzeJ4q.js → _app.settings-5i-vvT-H.js} +7 -7
- package/public/assets/_app.usage--5qFtU1W.js +76 -0
- package/public/assets/chevron-down-Bb5ZGvwk.js +1 -0
- package/public/assets/chevron-right-hwF5mD6-.js +1 -0
- package/public/assets/{client-k1tkFSNH.js → client-BcXc3lek.js} +4 -4
- package/public/assets/{dist-D03q-60i.js → dist-BBGxva0Y.js} +1 -1
- package/public/assets/index-D1RDaq3l.js +14 -0
- package/public/assets/{login-DW2Ipp21.js → login-GB0ZGUvA.js} +4 -4
- package/public/assets/plus-BgcHxxIr.js +1 -0
- package/public/assets/{preload-helper-BPaHpbO_.js → preload-helper-B7KDmXJ9.js} +1 -1
- package/public/assets/rotate-ccw-Do43Argv.js +1 -0
- package/public/assets/{shared-Dtkw6SE0.js → shared-DDpLUhCp.js} +2 -2
- package/public/assets/{trash-D4QWzEK_.js → trash-00950_yY.js} +1 -1
- package/public/index.html +5 -5
- package/public/assets/Lamp-DkvXKB-B.js +0 -26
- package/public/assets/Rack-CEuCdVXc.js +0 -483
- package/public/assets/RequestTable-D8L6iVJV.js +0 -93
- package/public/assets/_app-Drf03PWk.js +0 -1
- package/public/assets/_app.accounts-W1USUo2Q.js +0 -70
- package/public/assets/_app.console-Co9d2ZiD.js +0 -44
- package/public/assets/_app.database-CtFJLcfE.js +0 -24
- package/public/assets/_app.index-DigYfob3.js +0 -67
- package/public/assets/_app.keys-B1fRMyU-.js +0 -92
- package/public/assets/_app.logs-CFixPsUw.js +0 -60
- package/public/assets/_app.models-Dpl1O2RE.js +0 -148
- package/public/assets/_app.plugins._pluginId-BK0ADugW.js +0 -20
- package/public/assets/_app.usage-D2qlcEp4.js +0 -76
- package/public/assets/chevron-down-Bs0tSOyA.js +0 -1
- package/public/assets/chevron-right-DSaI1kFo.js +0 -1
- package/public/assets/index-Bk9sabex.js +0 -14
- package/public/assets/plus-BCfjC6nk.js +0 -1
package/bin/omni.js
CHANGED
|
@@ -24739,12 +24739,18 @@ var ANTHROPIC_MODELS = {
|
|
|
24739
24739
|
};
|
|
24740
24740
|
var ONE_M_SUFFIX = "[1m]";
|
|
24741
24741
|
var DATED_SUFFIX = /-\d{8}$/;
|
|
24742
|
-
function
|
|
24742
|
+
function anthropicChoice(model) {
|
|
24743
24743
|
let id = model.trim();
|
|
24744
24744
|
if (id.toLowerCase().endsWith(ONE_M_SUFFIX))
|
|
24745
24745
|
id = id.slice(0, -ONE_M_SUFFIX.length).trim();
|
|
24746
24746
|
id = id.replace(DATED_SUFFIX, "");
|
|
24747
|
-
return ANTHROPIC_MODELS.models.find((m) => m.id === id)
|
|
24747
|
+
return ANTHROPIC_MODELS.models.find((m) => m.id === id);
|
|
24748
|
+
}
|
|
24749
|
+
function anthropicReasoningForm(model) {
|
|
24750
|
+
return anthropicChoice(model)?.reasoningForm ?? "adaptive";
|
|
24751
|
+
}
|
|
24752
|
+
function anthropicMaxOutputTokens(model) {
|
|
24753
|
+
return anthropicChoice(model)?.limits.maxOutputTokens;
|
|
24748
24754
|
}
|
|
24749
24755
|
|
|
24750
24756
|
// packages/providers/src/anthropic/descriptor.ts
|
|
@@ -25635,7 +25641,8 @@ function codecAdapter(id, capabilities2, codec2, origins) {
|
|
|
25635
25641
|
credentials: req.credentials,
|
|
25636
25642
|
fail,
|
|
25637
25643
|
...req.requestId === undefined ? {} : { requestId: req.requestId },
|
|
25638
|
-
...req.autoCache === undefined ? {} : { autoCacheEnabled: req.autoCache }
|
|
25644
|
+
...req.autoCache === undefined ? {} : { autoCacheEnabled: req.autoCache },
|
|
25645
|
+
...req.maxOutputTokens === undefined ? {} : { maxOutputTokens: req.maxOutputTokens }
|
|
25639
25646
|
}));
|
|
25640
25647
|
const described = built?.request ?? {};
|
|
25641
25648
|
const request2 = {
|
|
@@ -27073,6 +27080,69 @@ function systemText(system, provider, note2) {
|
|
|
27073
27080
|
`);
|
|
27074
27081
|
}
|
|
27075
27082
|
|
|
27083
|
+
// packages/providers/src/toolResultFiles.ts
|
|
27084
|
+
function isTextual(mediaType) {
|
|
27085
|
+
const type = mediaType.split(";")[0]?.trim().toLowerCase() ?? "";
|
|
27086
|
+
return type.startsWith("text/") || type.endsWith("+json") || type.endsWith("+xml") || TEXTUAL.has(type);
|
|
27087
|
+
}
|
|
27088
|
+
var TEXTUAL = new Set([
|
|
27089
|
+
"application/json",
|
|
27090
|
+
"application/x-ndjson",
|
|
27091
|
+
"application/xml",
|
|
27092
|
+
"application/yaml",
|
|
27093
|
+
"application/x-yaml",
|
|
27094
|
+
"application/toml",
|
|
27095
|
+
"application/javascript",
|
|
27096
|
+
"application/typescript",
|
|
27097
|
+
"application/sql",
|
|
27098
|
+
"application/x-sh",
|
|
27099
|
+
"message/rfc822"
|
|
27100
|
+
]);
|
|
27101
|
+
function fileText(file2) {
|
|
27102
|
+
return Buffer.from(file2.data, "base64").toString("utf8");
|
|
27103
|
+
}
|
|
27104
|
+
function splitFiles(files, carries) {
|
|
27105
|
+
const text = [];
|
|
27106
|
+
const carried = [];
|
|
27107
|
+
let dropped = false;
|
|
27108
|
+
for (const file2 of files) {
|
|
27109
|
+
if (isTextual(file2.mediaType))
|
|
27110
|
+
text.push(fileText(file2));
|
|
27111
|
+
else if (carries(file2.mediaType))
|
|
27112
|
+
carried.push(file2);
|
|
27113
|
+
else
|
|
27114
|
+
dropped = true;
|
|
27115
|
+
}
|
|
27116
|
+
return { text, carried, dropped };
|
|
27117
|
+
}
|
|
27118
|
+
function withFileText(content, text) {
|
|
27119
|
+
return [content, ...text].filter((t) => t.length > 0).join(`
|
|
27120
|
+
|
|
27121
|
+
`);
|
|
27122
|
+
}
|
|
27123
|
+
var RESPONSES_FILE_TYPES = Object.assign(Object.create(null), {
|
|
27124
|
+
"application/pdf": "pdf",
|
|
27125
|
+
"application/rtf": "rtf",
|
|
27126
|
+
"application/msword": "doc",
|
|
27127
|
+
"application/vnd.ms-excel": "xls",
|
|
27128
|
+
"application/vnd.ms-powerpoint": "ppt",
|
|
27129
|
+
"application/vnd.openxmlformats-officedocument.wordprocessingml.document": "docx",
|
|
27130
|
+
"application/vnd.openxmlformats-officedocument.spreadsheetml.sheet": "xlsx",
|
|
27131
|
+
"application/vnd.openxmlformats-officedocument.presentationml.presentation": "pptx"
|
|
27132
|
+
});
|
|
27133
|
+
function fileName(file2) {
|
|
27134
|
+
return file2.filename ?? `file.${RESPONSES_FILE_TYPES[file2.mediaType] ?? "bin"}`;
|
|
27135
|
+
}
|
|
27136
|
+
function responsesFiles(files) {
|
|
27137
|
+
const { text, carried, dropped } = splitFiles(files, (t) => (t in RESPONSES_FILE_TYPES));
|
|
27138
|
+
const parts = carried.map((file2) => ({
|
|
27139
|
+
type: "input_file",
|
|
27140
|
+
filename: fileName(file2),
|
|
27141
|
+
file_data: `data:${file2.mediaType};base64,${file2.data}`
|
|
27142
|
+
}));
|
|
27143
|
+
return { parts, text, dropped };
|
|
27144
|
+
}
|
|
27145
|
+
|
|
27076
27146
|
// packages/providers/src/anthropic/wire.ts
|
|
27077
27147
|
var OAUTH_IDENTITY = "You are Claude Code, Anthropic's official CLI for Claude.";
|
|
27078
27148
|
function wireCacheControl(c) {
|
|
@@ -27110,22 +27180,13 @@ function encodeBlock(b, cloak) {
|
|
|
27110
27180
|
...cache
|
|
27111
27181
|
};
|
|
27112
27182
|
case "toolResult": {
|
|
27113
|
-
const
|
|
27114
|
-
|
|
27115
|
-
|
|
27116
|
-
|
|
27117
|
-
|
|
27118
|
-
|
|
27119
|
-
|
|
27120
|
-
return [];
|
|
27121
|
-
return [
|
|
27122
|
-
{
|
|
27123
|
-
type: "document",
|
|
27124
|
-
source,
|
|
27125
|
-
...file2.filename !== undefined && { title: file2.filename }
|
|
27126
|
-
}
|
|
27127
|
-
];
|
|
27128
|
-
});
|
|
27183
|
+
const files = splitFiles(b.files ?? [], (t) => t === "application/pdf");
|
|
27184
|
+
const text = withFileText(b.content, files.text);
|
|
27185
|
+
const documents = files.carried.map((file2) => ({
|
|
27186
|
+
type: "document",
|
|
27187
|
+
source: { type: "base64", media_type: file2.mediaType, data: file2.data },
|
|
27188
|
+
...file2.filename !== undefined && { title: file2.filename }
|
|
27189
|
+
}));
|
|
27129
27190
|
const parts = [
|
|
27130
27191
|
...(b.images ?? []).map((image) => encodeBlock(image, cloak)),
|
|
27131
27192
|
...documents,
|
|
@@ -27134,7 +27195,7 @@ function encodeBlock(b, cloak) {
|
|
|
27134
27195
|
return {
|
|
27135
27196
|
type: "tool_result",
|
|
27136
27197
|
tool_use_id: b.toolUseId,
|
|
27137
|
-
content: parts.length === 0 ?
|
|
27198
|
+
content: parts.length === 0 ? text : [...text.length > 0 ? [{ type: "text", text }] : [], ...parts],
|
|
27138
27199
|
is_error: b.isError,
|
|
27139
27200
|
...cache
|
|
27140
27201
|
};
|
|
@@ -27286,6 +27347,12 @@ function addAutoCacheBreakpoints(body, req, note2) {
|
|
|
27286
27347
|
lastHistory.cache_control = { type: "ephemeral" };
|
|
27287
27348
|
note2("anthropic:history-cache-breakpoint-added");
|
|
27288
27349
|
}
|
|
27350
|
+
function defaultMaxTokens(model, saved) {
|
|
27351
|
+
const ceiling = anthropicMaxOutputTokens(model);
|
|
27352
|
+
if (saved === undefined)
|
|
27353
|
+
return ceiling ?? 4096;
|
|
27354
|
+
return ceiling === undefined ? saved : Math.min(saved, ceiling);
|
|
27355
|
+
}
|
|
27289
27356
|
function toWire(req, model, opts) {
|
|
27290
27357
|
const cloak = opts.cloak ?? null;
|
|
27291
27358
|
const degradations = [];
|
|
@@ -27310,8 +27377,12 @@ function toWire(req, model, opts) {
|
|
|
27310
27377
|
note2("anthropic:system-turn-cache-control-dropped");
|
|
27311
27378
|
for (const m of req.messages) {
|
|
27312
27379
|
for (const b of m.content) {
|
|
27313
|
-
if (b.type === "toolResult" && b.files
|
|
27314
|
-
|
|
27380
|
+
if (b.type === "toolResult" && b.files !== undefined) {
|
|
27381
|
+
const files = splitFiles(b.files, (t) => t === "application/pdf");
|
|
27382
|
+
if (files.text.length > 0)
|
|
27383
|
+
note2("anthropic:tool-result-files-inlined");
|
|
27384
|
+
if (files.dropped)
|
|
27385
|
+
note2("anthropic:files-dropped");
|
|
27315
27386
|
}
|
|
27316
27387
|
}
|
|
27317
27388
|
}
|
|
@@ -27328,7 +27399,7 @@ function toWire(req, model, opts) {
|
|
|
27328
27399
|
}
|
|
27329
27400
|
return [{ role: m.role, content: encodeSystemTurn(m.content, cloak) }];
|
|
27330
27401
|
}),
|
|
27331
|
-
max_tokens: req.maxTokens ??
|
|
27402
|
+
max_tokens: req.maxTokens ?? defaultMaxTokens(model, opts.maxOutputTokens),
|
|
27332
27403
|
stream: req.stream
|
|
27333
27404
|
};
|
|
27334
27405
|
if (systemCache.retarget !== undefined) {
|
|
@@ -27467,7 +27538,8 @@ var anthropicCodec = {
|
|
|
27467
27538
|
const { body, degradations } = toWire(input2.request, input2.model, {
|
|
27468
27539
|
oauth,
|
|
27469
27540
|
cloak,
|
|
27470
|
-
autoCache: input2.autoCacheEnabled === true
|
|
27541
|
+
autoCache: input2.autoCacheEnabled === true,
|
|
27542
|
+
...input2.maxOutputTokens === undefined ? {} : { maxOutputTokens: input2.maxOutputTokens }
|
|
27471
27543
|
});
|
|
27472
27544
|
const firstUser = input2.request.messages.find((m) => m.role === "user");
|
|
27473
27545
|
const firstText = firstUser?.content.find((b) => b.type === "text");
|
|
@@ -27800,8 +27872,125 @@ var anthropicOAuthFlow = {
|
|
|
27800
27872
|
if (!usageReadable(res.status, "anthropic"))
|
|
27801
27873
|
return null;
|
|
27802
27874
|
return parseAnthropicUsage(parsed(res.body), now());
|
|
27875
|
+
},
|
|
27876
|
+
async* resetCredits({ secrets }) {
|
|
27877
|
+
if (secrets.accessToken === null)
|
|
27878
|
+
return null;
|
|
27879
|
+
const res = yield getJsonRequest(RESET_STATUS_URL, anthropicProfile, {
|
|
27880
|
+
accessToken: secrets.accessToken,
|
|
27881
|
+
extraHeaders: SIDE_HEADERS
|
|
27882
|
+
});
|
|
27883
|
+
if (!usageReadable(res.status, "anthropic"))
|
|
27884
|
+
return null;
|
|
27885
|
+
const root = recordOf(parsed(res.body));
|
|
27886
|
+
return root === null ? null : parseResetGrants(root.cedar_ember ?? null);
|
|
27887
|
+
},
|
|
27888
|
+
async* redeemReset({ secrets, creditId, requestId, fail }) {
|
|
27889
|
+
if (secrets.accessToken === null)
|
|
27890
|
+
throw fail("AUTH", "credential holds no access token");
|
|
27891
|
+
const grantId = grantOf(creditId);
|
|
27892
|
+
if (grantId === null)
|
|
27893
|
+
throw fail("CONFLICT", "that reset credit is not available");
|
|
27894
|
+
const profile = yield getJsonRequest(PROFILE_URL, anthropicProfile, {
|
|
27895
|
+
accessToken: secrets.accessToken,
|
|
27896
|
+
extraHeaders: SIDE_HEADERS
|
|
27897
|
+
});
|
|
27898
|
+
if (profile.status < 200 || profile.status >= 300) {
|
|
27899
|
+
throw fail(redeemErrorCode(profile.status), `profile read refused: http_${profile.status}`, {
|
|
27900
|
+
status: profile.status
|
|
27901
|
+
});
|
|
27902
|
+
}
|
|
27903
|
+
const orgId = orgIdOf(parsed(profile.body));
|
|
27904
|
+
if (orgId === null)
|
|
27905
|
+
throw fail("UPSTREAM", "profile names no organization");
|
|
27906
|
+
const res = yield postJsonRequest(`https://api.anthropic.com/api/organizations/${orgId}/reset_rate_limits`, anthropicProfile, {
|
|
27907
|
+
contentType: "application/json",
|
|
27908
|
+
body: JSON.stringify({ program: RESET_PROGRAM, grant_id: grantId, request_id: requestId }),
|
|
27909
|
+
extraHeaders: [["Authorization", `Bearer ${secrets.accessToken}`], ...SIDE_HEADERS]
|
|
27910
|
+
});
|
|
27911
|
+
if (res.status < 200 || res.status >= 300) {
|
|
27912
|
+
throw fail(redeemErrorCode(res.status), `reset claim refused: http_${res.status}`, {
|
|
27913
|
+
status: res.status
|
|
27914
|
+
});
|
|
27915
|
+
}
|
|
27916
|
+
return claimOutcome(parsed(res.body), fail);
|
|
27803
27917
|
}
|
|
27804
27918
|
};
|
|
27919
|
+
var RESET_PROGRAM = "cedar_ember";
|
|
27920
|
+
var RESET_STATUS_URL = `${USAGE_URL}?cedar_ember=1&skip_spend=1`;
|
|
27921
|
+
var PROFILE_URL = "https://api.anthropic.com/api/oauth/profile";
|
|
27922
|
+
var ORG_ID = /^[A-Za-z0-9-]{1,64}$/;
|
|
27923
|
+
var SIDE_HEADERS = [["anthropic-beta", "oauth-2025-04-20"]];
|
|
27924
|
+
var USE_SUFFIX = /-u(\d+)$/;
|
|
27925
|
+
function creditIdOf(grantId, left) {
|
|
27926
|
+
return `${grantId}-u${left}`;
|
|
27927
|
+
}
|
|
27928
|
+
function grantOf(creditId) {
|
|
27929
|
+
const grant = creditId.replace(USE_SUFFIX, "");
|
|
27930
|
+
return grant === creditId || grant === "" ? null : grant;
|
|
27931
|
+
}
|
|
27932
|
+
function orgIdOf(value) {
|
|
27933
|
+
const org = recordOf(recordOf(value)?.organization);
|
|
27934
|
+
const uuid3 = org?.uuid;
|
|
27935
|
+
return typeof uuid3 === "string" && ORG_ID.test(uuid3) ? uuid3 : null;
|
|
27936
|
+
}
|
|
27937
|
+
function parseResetGrants(value) {
|
|
27938
|
+
if (value === null)
|
|
27939
|
+
return { available: 0, credits: [] };
|
|
27940
|
+
const block = recordOf(value);
|
|
27941
|
+
if (block === null || !Array.isArray(block.grants))
|
|
27942
|
+
return null;
|
|
27943
|
+
const next = typeof block.next_grant_id === "string" ? block.next_grant_id : null;
|
|
27944
|
+
const atLimit = block.at_limit === true;
|
|
27945
|
+
let available = 0;
|
|
27946
|
+
const credits = block.grants.flatMap((raw) => {
|
|
27947
|
+
const g = recordOf(raw);
|
|
27948
|
+
if (g === null || typeof g.id !== "string")
|
|
27949
|
+
return [];
|
|
27950
|
+
const left = typeof g.resets_left === "number" ? g.resets_left : 0;
|
|
27951
|
+
const claimable = left > 0 && g.usable_now === true && g.paused !== true && (g.use_requires_limit !== true || atLimit) && (next === null || next === g.id);
|
|
27952
|
+
if (claimable)
|
|
27953
|
+
available += left;
|
|
27954
|
+
return [
|
|
27955
|
+
{
|
|
27956
|
+
id: creditIdOf(g.id, left),
|
|
27957
|
+
status: claimable ? "available" : left > 0 ? "unavailable" : "used",
|
|
27958
|
+
title: typeof g.label === "string" && g.label !== "" ? g.label : null,
|
|
27959
|
+
grantedAt: isoOrNull(g.starts_at),
|
|
27960
|
+
expiresAt: isoOrNull(g.ends_at)
|
|
27961
|
+
}
|
|
27962
|
+
];
|
|
27963
|
+
});
|
|
27964
|
+
return { available, credits };
|
|
27965
|
+
}
|
|
27966
|
+
function claimOutcome(value, fail) {
|
|
27967
|
+
const body = recordOf(value);
|
|
27968
|
+
const result = typeof body?.result === "string" ? body.result : null;
|
|
27969
|
+
if (result === "reset") {
|
|
27970
|
+
return { windowsReset: Array.isArray(body?.cleared) ? body.cleared.length : null };
|
|
27971
|
+
}
|
|
27972
|
+
if (result === "cooldown")
|
|
27973
|
+
throw fail("RATE_LIMIT", "reset claim refused: cooldown");
|
|
27974
|
+
if (result === "already_used" || result === "not_limited" || result === "ineligible") {
|
|
27975
|
+
throw fail("CONFLICT", `reset claim refused: ${result}`);
|
|
27976
|
+
}
|
|
27977
|
+
throw fail("UPSTREAM", "reset claim answered without a reset");
|
|
27978
|
+
}
|
|
27979
|
+
function redeemErrorCode(status) {
|
|
27980
|
+
if (status === 429)
|
|
27981
|
+
return "RATE_LIMIT";
|
|
27982
|
+
if (status === 401 || status === 403)
|
|
27983
|
+
return "AUTH";
|
|
27984
|
+
if (status >= 400 && status < 500)
|
|
27985
|
+
return "CONFLICT";
|
|
27986
|
+
return "UPSTREAM";
|
|
27987
|
+
}
|
|
27988
|
+
function isoOrNull(value) {
|
|
27989
|
+
if (typeof value !== "string")
|
|
27990
|
+
return null;
|
|
27991
|
+
const at = Date.parse(value);
|
|
27992
|
+
return Number.isNaN(at) ? null : at;
|
|
27993
|
+
}
|
|
27805
27994
|
// packages/providers/src/antigravity/codec.ts
|
|
27806
27995
|
import { createHash as createHash2 } from "crypto";
|
|
27807
27996
|
|
|
@@ -28406,16 +28595,19 @@ function toAntigravityWire(req, model, identity) {
|
|
|
28406
28595
|
note2("antigravity:tool-result-unmatched");
|
|
28407
28596
|
if (block.isError === true)
|
|
28408
28597
|
note2("antigravity:tool-result-error-flag-dropped");
|
|
28598
|
+
const files = splitFiles(block.files ?? [], () => true);
|
|
28599
|
+
if (files.text.length > 0)
|
|
28600
|
+
note2("antigravity:tool-result-files-inlined");
|
|
28409
28601
|
parts.push({
|
|
28410
28602
|
functionResponse: {
|
|
28411
28603
|
name: cloakName2(cloak, name ?? block.toolUseId),
|
|
28412
|
-
response: { output: block.content }
|
|
28604
|
+
response: { output: withFileText(block.content, files.text) }
|
|
28413
28605
|
}
|
|
28414
28606
|
});
|
|
28415
28607
|
for (const image of block.images ?? []) {
|
|
28416
28608
|
parts.push({ inlineData: { mimeType: image.mediaType, data: image.data } });
|
|
28417
28609
|
}
|
|
28418
|
-
for (const file2 of
|
|
28610
|
+
for (const file2 of files.carried) {
|
|
28419
28611
|
parts.push({ inlineData: { mimeType: file2.mediaType, data: file2.data } });
|
|
28420
28612
|
}
|
|
28421
28613
|
role = "user";
|
|
@@ -29120,7 +29312,7 @@ var grokOAuthFlow = {
|
|
|
29120
29312
|
|
|
29121
29313
|
// packages/providers/src/kilo/oauth.ts
|
|
29122
29314
|
var CODES_URL = "https://api.kilo.ai/api/device-auth/codes";
|
|
29123
|
-
var
|
|
29315
|
+
var PROFILE_URL2 = "https://api.kilo.ai/api/profile";
|
|
29124
29316
|
var FALLBACK_VERIFICATION_URL = "https://kilo.ai";
|
|
29125
29317
|
var DEFAULT_EXPIRES_SECONDS = 300;
|
|
29126
29318
|
var POLL_INTERVAL_SECONDS = 3;
|
|
@@ -29152,7 +29344,7 @@ function deviceCodeFrom(value, fail) {
|
|
|
29152
29344
|
}
|
|
29153
29345
|
async function* orgIdFor(accessToken) {
|
|
29154
29346
|
try {
|
|
29155
|
-
const res = yield getJsonRequest(
|
|
29347
|
+
const res = yield getJsonRequest(PROFILE_URL2, kiloProfile, { accessToken });
|
|
29156
29348
|
if (res.status < 200 || res.status >= 300)
|
|
29157
29349
|
return null;
|
|
29158
29350
|
const record2 = recordFrom(parsed(res.body));
|
|
@@ -29660,6 +29852,7 @@ var AUTHORIZE_URL3 = "https://auth.openai.com/oauth/authorize";
|
|
|
29660
29852
|
var TOKEN_URL5 = "https://auth.openai.com/oauth/token";
|
|
29661
29853
|
var SCOPES4 = "openid profile email offline_access";
|
|
29662
29854
|
var USAGE_URL3 = "https://chatgpt.com/backend-api/wham/usage";
|
|
29855
|
+
var RESET_CREDITS_URL = "https://chatgpt.com/backend-api/wham/rate-limit-reset-credits";
|
|
29663
29856
|
function isRecord7(value) {
|
|
29664
29857
|
return typeof value === "object" && value !== null;
|
|
29665
29858
|
}
|
|
@@ -29813,8 +30006,78 @@ var openaiOAuthFlow = {
|
|
|
29813
30006
|
if (!usageReadable(res.status, "openai"))
|
|
29814
30007
|
return null;
|
|
29815
30008
|
return parseOpenAIUsage(parsed(res.body), now());
|
|
30009
|
+
},
|
|
30010
|
+
async* resetCredits({ secrets, providerData }) {
|
|
30011
|
+
if (secrets.accessToken === null)
|
|
30012
|
+
return null;
|
|
30013
|
+
const res = yield getJsonRequest(RESET_CREDITS_URL, openaiProfile, {
|
|
30014
|
+
accessToken: secrets.accessToken,
|
|
30015
|
+
extraHeaders: accountHeader(providerData)
|
|
30016
|
+
});
|
|
30017
|
+
if (!usageReadable(res.status, "openai"))
|
|
30018
|
+
return null;
|
|
30019
|
+
return parseResetCredits(parsed(res.body));
|
|
30020
|
+
},
|
|
30021
|
+
async* redeemReset({ secrets, providerData, creditId, requestId, fail }) {
|
|
30022
|
+
if (secrets.accessToken === null)
|
|
30023
|
+
throw fail("AUTH", "credential holds no access token");
|
|
30024
|
+
const res = yield postJsonRequest(`${RESET_CREDITS_URL}/consume`, openaiProfile, {
|
|
30025
|
+
contentType: "application/json",
|
|
30026
|
+
body: JSON.stringify({ credit_id: creditId, redeem_request_id: requestId }),
|
|
30027
|
+
extraHeaders: [
|
|
30028
|
+
["Authorization", `Bearer ${secrets.accessToken}`],
|
|
30029
|
+
...accountHeader(providerData)
|
|
30030
|
+
]
|
|
30031
|
+
});
|
|
30032
|
+
if (res.status < 200 || res.status >= 300) {
|
|
30033
|
+
throw fail(redeemErrorCode2(res.status), `reset credit redeem refused: http_${res.status}`, {
|
|
30034
|
+
status: res.status
|
|
30035
|
+
});
|
|
30036
|
+
}
|
|
30037
|
+
const body = recordOf(parsed(res.body));
|
|
30038
|
+
const windowsReset = body === null ? null : numberOf(body, ["windows_reset"]);
|
|
30039
|
+
return { windowsReset };
|
|
29816
30040
|
}
|
|
29817
30041
|
};
|
|
30042
|
+
function accountHeader(providerData) {
|
|
30043
|
+
const accountId = accountIdFromProviderData(providerData);
|
|
30044
|
+
return accountId === null ? [] : [["chatgpt-account-id", accountId]];
|
|
30045
|
+
}
|
|
30046
|
+
function redeemErrorCode2(status) {
|
|
30047
|
+
if (status === 429)
|
|
30048
|
+
return "RATE_LIMIT";
|
|
30049
|
+
if (status === 401 || status === 403)
|
|
30050
|
+
return "AUTH";
|
|
30051
|
+
if (status >= 400 && status < 500)
|
|
30052
|
+
return "CONFLICT";
|
|
30053
|
+
return "UPSTREAM";
|
|
30054
|
+
}
|
|
30055
|
+
function isoOrNull2(value) {
|
|
30056
|
+
if (typeof value !== "string")
|
|
30057
|
+
return null;
|
|
30058
|
+
const at = Date.parse(value);
|
|
30059
|
+
return Number.isFinite(at) ? at : null;
|
|
30060
|
+
}
|
|
30061
|
+
function parseResetCredits(value) {
|
|
30062
|
+
const root = recordOf(value);
|
|
30063
|
+
if (root === null || !Array.isArray(root.credits))
|
|
30064
|
+
return null;
|
|
30065
|
+
const credits = root.credits.flatMap((raw) => {
|
|
30066
|
+
const c = recordOf(raw);
|
|
30067
|
+
if (c === null || typeof c.id !== "string" || typeof c.status !== "string")
|
|
30068
|
+
return [];
|
|
30069
|
+
return [
|
|
30070
|
+
{
|
|
30071
|
+
id: c.id,
|
|
30072
|
+
status: c.status,
|
|
30073
|
+
title: typeof c.title === "string" ? c.title : null,
|
|
30074
|
+
grantedAt: isoOrNull2(c.granted_at),
|
|
30075
|
+
expiresAt: isoOrNull2(c.expires_at)
|
|
30076
|
+
}
|
|
30077
|
+
];
|
|
30078
|
+
});
|
|
30079
|
+
return { available: credits.filter((c) => c.status === "available").length, credits };
|
|
30080
|
+
}
|
|
29818
30081
|
|
|
29819
30082
|
// packages/providers/src/builtinOAuth.ts
|
|
29820
30083
|
function builtinOAuthFlows() {
|
|
@@ -30158,61 +30421,6 @@ async function* decodeCustomResponses(messages) {
|
|
|
30158
30421
|
}
|
|
30159
30422
|
}
|
|
30160
30423
|
|
|
30161
|
-
// packages/providers/src/responsesFile.ts
|
|
30162
|
-
var ACCEPTED = new Set([
|
|
30163
|
-
"application/pdf",
|
|
30164
|
-
"text/plain",
|
|
30165
|
-
"text/csv",
|
|
30166
|
-
"text/markdown",
|
|
30167
|
-
"text/html",
|
|
30168
|
-
"text/css",
|
|
30169
|
-
"text/xml",
|
|
30170
|
-
"text/calendar",
|
|
30171
|
-
"text/tab-separated-values",
|
|
30172
|
-
"text/javascript",
|
|
30173
|
-
"text/x-python",
|
|
30174
|
-
"text/x-c",
|
|
30175
|
-
"text/x-java",
|
|
30176
|
-
"text/x-sh",
|
|
30177
|
-
"text/x-sql",
|
|
30178
|
-
"text/x-typescript",
|
|
30179
|
-
"text/x-yaml",
|
|
30180
|
-
"application/json",
|
|
30181
|
-
"application/javascript",
|
|
30182
|
-
"application/typescript",
|
|
30183
|
-
"application/toml",
|
|
30184
|
-
"application/yaml",
|
|
30185
|
-
"application/x-yaml",
|
|
30186
|
-
"message/rfc822",
|
|
30187
|
-
"application/rtf",
|
|
30188
|
-
"application/msword",
|
|
30189
|
-
"application/vnd.ms-excel",
|
|
30190
|
-
"application/vnd.ms-powerpoint",
|
|
30191
|
-
"application/vnd.openxmlformats-officedocument.wordprocessingml.document",
|
|
30192
|
-
"application/vnd.openxmlformats-officedocument.spreadsheetml.sheet",
|
|
30193
|
-
"application/vnd.openxmlformats-officedocument.presentationml.presentation"
|
|
30194
|
-
]);
|
|
30195
|
-
var TEXTUAL = new Set(["application/xml", "application/sql", "application/x-sh"]);
|
|
30196
|
-
function responsesFiles(files) {
|
|
30197
|
-
const parts = [];
|
|
30198
|
-
const text = [];
|
|
30199
|
-
let dropped = false;
|
|
30200
|
-
for (const file2 of files) {
|
|
30201
|
-
if (ACCEPTED.has(file2.mediaType)) {
|
|
30202
|
-
parts.push({
|
|
30203
|
-
type: "input_file",
|
|
30204
|
-
...file2.filename !== undefined && { filename: file2.filename },
|
|
30205
|
-
file_data: `data:${file2.mediaType};base64,${file2.data}`
|
|
30206
|
-
});
|
|
30207
|
-
} else if (file2.mediaType.startsWith("text/") || TEXTUAL.has(file2.mediaType)) {
|
|
30208
|
-
text.push(Buffer.from(file2.data, "base64").toString("utf8"));
|
|
30209
|
-
} else {
|
|
30210
|
-
dropped = true;
|
|
30211
|
-
}
|
|
30212
|
-
}
|
|
30213
|
-
return { parts, text, dropped };
|
|
30214
|
-
}
|
|
30215
|
-
|
|
30216
30424
|
// packages/providers/src/custom/wire.ts
|
|
30217
30425
|
function encodeChatToolChoice(c) {
|
|
30218
30426
|
switch (c.type) {
|
|
@@ -30276,19 +30484,23 @@ function toCustomChatWire(req, model) {
|
|
|
30276
30484
|
function: { name: block.name, arguments: JSON.stringify(block.input) }
|
|
30277
30485
|
});
|
|
30278
30486
|
break;
|
|
30279
|
-
case "toolResult":
|
|
30487
|
+
case "toolResult": {
|
|
30280
30488
|
if (block.native !== undefined)
|
|
30281
30489
|
note2("custom:anthropic-native-block-dropped");
|
|
30490
|
+
const files = splitFiles(block.files ?? [], () => false);
|
|
30282
30491
|
messages.push({
|
|
30283
30492
|
role: "tool",
|
|
30284
30493
|
tool_call_id: block.toolUseId,
|
|
30285
|
-
content: block.content
|
|
30494
|
+
content: withFileText(block.content, files.text)
|
|
30286
30495
|
});
|
|
30287
30496
|
if (block.images !== undefined)
|
|
30288
30497
|
note2("custom:images-dropped");
|
|
30289
|
-
if (
|
|
30498
|
+
if (files.text.length > 0)
|
|
30499
|
+
note2("custom:tool-result-files-inlined");
|
|
30500
|
+
if (files.dropped)
|
|
30290
30501
|
note2("custom:files-dropped");
|
|
30291
30502
|
break;
|
|
30503
|
+
}
|
|
30292
30504
|
case "providerNative":
|
|
30293
30505
|
note2("custom:anthropic-native-block-dropped");
|
|
30294
30506
|
break;
|
|
@@ -30410,9 +30622,7 @@ function toCustomResponsesWire(req, model) {
|
|
|
30410
30622
|
input2.push({
|
|
30411
30623
|
type: "function_call_output",
|
|
30412
30624
|
call_id: block.toolUseId,
|
|
30413
|
-
output:
|
|
30414
|
-
|
|
30415
|
-
`)
|
|
30625
|
+
output: withFileText(block.content, files.text)
|
|
30416
30626
|
});
|
|
30417
30627
|
if (block.images !== undefined) {
|
|
30418
30628
|
note2("custom:tool-result-images-moved");
|
|
@@ -30798,9 +31008,7 @@ function toGrokWire(req, model) {
|
|
|
30798
31008
|
input2.push({
|
|
30799
31009
|
type: "function_call_output",
|
|
30800
31010
|
call_id: block.toolUseId,
|
|
30801
|
-
output:
|
|
30802
|
-
|
|
30803
|
-
`)
|
|
31011
|
+
output: withFileText(block.content, files.text)
|
|
30804
31012
|
});
|
|
30805
31013
|
if (block.images !== undefined) {
|
|
30806
31014
|
note2("grok:tool-result-images-moved");
|
|
@@ -31258,15 +31466,20 @@ function toKiloWire(req, model) {
|
|
|
31258
31466
|
function: { name: block.name, arguments: JSON.stringify(block.input) }
|
|
31259
31467
|
});
|
|
31260
31468
|
break;
|
|
31261
|
-
case "toolResult":
|
|
31469
|
+
case "toolResult": {
|
|
31262
31470
|
if (block.native !== undefined)
|
|
31263
31471
|
note2("kilo:anthropic-native-block-dropped");
|
|
31264
31472
|
flush();
|
|
31473
|
+
const files = splitFiles(block.files ?? [], (t) => t === "application/pdf");
|
|
31265
31474
|
messages.push({
|
|
31266
31475
|
role: "tool",
|
|
31267
31476
|
tool_call_id: block.toolUseId,
|
|
31268
|
-
content: block.content
|
|
31477
|
+
content: withFileText(block.content, files.text)
|
|
31269
31478
|
});
|
|
31479
|
+
if (files.text.length > 0)
|
|
31480
|
+
note2("kilo:tool-result-files-inlined");
|
|
31481
|
+
if (files.dropped)
|
|
31482
|
+
note2("kilo:files-dropped");
|
|
31270
31483
|
for (const image of block.images ?? []) {
|
|
31271
31484
|
note2("kilo:tool-result-images-moved");
|
|
31272
31485
|
toolImages.push({
|
|
@@ -31274,17 +31487,18 @@ function toKiloWire(req, model) {
|
|
|
31274
31487
|
image_url: { url: `data:${image.mediaType};base64,${image.data}` }
|
|
31275
31488
|
});
|
|
31276
31489
|
}
|
|
31277
|
-
for (const file2 of
|
|
31490
|
+
for (const file2 of files.carried) {
|
|
31278
31491
|
note2("kilo:tool-result-files-moved");
|
|
31279
31492
|
toolImages.push({
|
|
31280
31493
|
type: "file",
|
|
31281
31494
|
file: {
|
|
31282
|
-
|
|
31495
|
+
filename: fileName(file2),
|
|
31283
31496
|
file_data: `data:${file2.mediaType};base64,${file2.data}`
|
|
31284
31497
|
}
|
|
31285
31498
|
});
|
|
31286
31499
|
}
|
|
31287
31500
|
break;
|
|
31501
|
+
}
|
|
31288
31502
|
case "providerNative":
|
|
31289
31503
|
note2("kilo:anthropic-native-block-dropped");
|
|
31290
31504
|
break;
|
|
@@ -31538,19 +31752,23 @@ function toChatWire(req, model, vendor = "kimi") {
|
|
|
31538
31752
|
function: { name: block.name, arguments: JSON.stringify(block.input) }
|
|
31539
31753
|
});
|
|
31540
31754
|
break;
|
|
31541
|
-
case "toolResult":
|
|
31755
|
+
case "toolResult": {
|
|
31542
31756
|
if (block.native !== undefined)
|
|
31543
31757
|
note2("kimi:anthropic-native-block-dropped");
|
|
31758
|
+
const files = splitFiles(block.files ?? [], () => false);
|
|
31544
31759
|
messages.push({
|
|
31545
31760
|
role: "tool",
|
|
31546
31761
|
tool_call_id: block.toolUseId,
|
|
31547
|
-
content: block.content
|
|
31762
|
+
content: withFileText(block.content, files.text)
|
|
31548
31763
|
});
|
|
31549
31764
|
if (block.images !== undefined)
|
|
31550
31765
|
note2("kimi:images-dropped");
|
|
31551
|
-
if (
|
|
31766
|
+
if (files.text.length > 0)
|
|
31767
|
+
note2("kimi:tool-result-files-inlined");
|
|
31768
|
+
if (files.dropped)
|
|
31552
31769
|
note2("kimi:files-dropped");
|
|
31553
31770
|
break;
|
|
31771
|
+
}
|
|
31554
31772
|
case "providerNative":
|
|
31555
31773
|
note2("kimi:anthropic-native-block-dropped");
|
|
31556
31774
|
break;
|
|
@@ -31957,9 +32175,7 @@ function toMuseWire(req, model) {
|
|
|
31957
32175
|
input2.push({
|
|
31958
32176
|
type: "function_call_output",
|
|
31959
32177
|
call_id: block.toolUseId,
|
|
31960
|
-
output:
|
|
31961
|
-
|
|
31962
|
-
`)
|
|
32178
|
+
output: withFileText(block.content, files.text)
|
|
31963
32179
|
});
|
|
31964
32180
|
if (block.images !== undefined) {
|
|
31965
32181
|
note2("muse:tool-result-images-moved");
|
|
@@ -32385,9 +32601,7 @@ function toResponsesWire(req, model, opts = { oauth: false }) {
|
|
|
32385
32601
|
input2.push({
|
|
32386
32602
|
type: "function_call_output",
|
|
32387
32603
|
call_id: block.toolUseId,
|
|
32388
|
-
output:
|
|
32389
|
-
|
|
32390
|
-
`)
|
|
32604
|
+
output: withFileText(block.content, files.text)
|
|
32391
32605
|
});
|
|
32392
32606
|
if (block.images !== undefined) {
|
|
32393
32607
|
note2("openai:tool-result-images-moved");
|
|
@@ -32794,6 +33008,11 @@ var quotaRefreshSchema = exports_external.discriminatedUnion("kind", [
|
|
|
32794
33008
|
}).strict(),
|
|
32795
33009
|
exports_external.object({ kind: exports_external.literal("all") }).strict()
|
|
32796
33010
|
]);
|
|
33011
|
+
var accountIdSchema = exports_external.string().trim().min(1).max(64).regex(/^[A-Za-z0-9_-]+$/, "credentialId must be an account id");
|
|
33012
|
+
var redeemResetSchema = exports_external.object({
|
|
33013
|
+
credentialId: accountIdSchema,
|
|
33014
|
+
creditId: exports_external.string().min(1).max(128).regex(/^[A-Za-z0-9_-]+$/).optional()
|
|
33015
|
+
}).strict();
|
|
32797
33016
|
var dimensionSchema = exports_external.enum([
|
|
32798
33017
|
"credential",
|
|
32799
33018
|
"model",
|
|
@@ -35203,6 +35422,29 @@ function oauthAdapter(id, flow, opts = {}) {
|
|
|
35203
35422
|
return Promise.resolve(null);
|
|
35204
35423
|
return runStep(id, "usage", step, deps, origins);
|
|
35205
35424
|
}
|
|
35425
|
+
},
|
|
35426
|
+
...flow.resetCredits === undefined ? {} : {
|
|
35427
|
+
resetCredits: (secrets, deps, providerData) => {
|
|
35428
|
+
const step = flow.resetCredits?.({ secrets, providerData, ...helpers(deps) });
|
|
35429
|
+
if (step === undefined)
|
|
35430
|
+
return Promise.resolve(null);
|
|
35431
|
+
return runStep(id, "resetCredits", step, deps, origins);
|
|
35432
|
+
}
|
|
35433
|
+
},
|
|
35434
|
+
...flow.redeemReset === undefined ? {} : {
|
|
35435
|
+
redeemReset: (secrets, deps, providerData, creditId, requestId) => {
|
|
35436
|
+
const step = flow.redeemReset?.({
|
|
35437
|
+
secrets,
|
|
35438
|
+
providerData,
|
|
35439
|
+
creditId,
|
|
35440
|
+
requestId,
|
|
35441
|
+
...helpers(deps)
|
|
35442
|
+
});
|
|
35443
|
+
if (step === undefined) {
|
|
35444
|
+
return Promise.reject(flowFailure(id, "redeemReset", "has no redeem step"));
|
|
35445
|
+
}
|
|
35446
|
+
return runStep(id, "redeemReset", step, deps, origins);
|
|
35447
|
+
}
|
|
35206
35448
|
}
|
|
35207
35449
|
};
|
|
35208
35450
|
if (flow.kind === "pkce")
|
|
@@ -35238,11 +35480,32 @@ function isAuthorizeStart(value) {
|
|
|
35238
35480
|
const candidate = value;
|
|
35239
35481
|
return typeof candidate.authorizeUrl === "string" && typeof candidate.pending === "object" && candidate.pending !== null;
|
|
35240
35482
|
}
|
|
35483
|
+
function isResetCreditsOrNull(value) {
|
|
35484
|
+
if (value === null)
|
|
35485
|
+
return true;
|
|
35486
|
+
if (typeof value !== "object")
|
|
35487
|
+
return false;
|
|
35488
|
+
const candidate = value;
|
|
35489
|
+
return typeof candidate.available === "number" && Array.isArray(candidate.credits) && candidate.credits.every((c) => {
|
|
35490
|
+
if (typeof c !== "object" || c === null)
|
|
35491
|
+
return false;
|
|
35492
|
+
const row = c;
|
|
35493
|
+
return typeof row.id === "string" && typeof row.status === "string" && (row.title === null || typeof row.title === "string") && (row.grantedAt === null || typeof row.grantedAt === "number") && (row.expiresAt === null || typeof row.expiresAt === "number");
|
|
35494
|
+
});
|
|
35495
|
+
}
|
|
35496
|
+
function isResetRedeemed(value) {
|
|
35497
|
+
if (typeof value !== "object" || value === null)
|
|
35498
|
+
return false;
|
|
35499
|
+
const held = value.windowsReset;
|
|
35500
|
+
return held === null || typeof held === "number";
|
|
35501
|
+
}
|
|
35241
35502
|
var RETURN_SHAPE = {
|
|
35242
35503
|
start: isAuthorizeStart,
|
|
35243
35504
|
begin: isAuthorizeStart,
|
|
35244
35505
|
exchange: isFlowResult,
|
|
35245
|
-
refresh: isFlowResult
|
|
35506
|
+
refresh: isFlowResult,
|
|
35507
|
+
resetCredits: isResetCreditsOrNull,
|
|
35508
|
+
redeemReset: isResetRedeemed
|
|
35246
35509
|
};
|
|
35247
35510
|
|
|
35248
35511
|
// packages/control/src/oauth/index.ts
|
|
@@ -35462,6 +35725,11 @@ function validateOAuthFlow(id, value) {
|
|
|
35462
35725
|
if (value.usage !== undefined) {
|
|
35463
35726
|
checkAt(typeof value.usage === "function", id, "oauth.usage", "a function");
|
|
35464
35727
|
}
|
|
35728
|
+
for (const fn of ["resetCredits", "redeemReset"]) {
|
|
35729
|
+
if (value[fn] !== undefined) {
|
|
35730
|
+
checkAt(typeof value[fn] === "function", id, `oauth.${fn}`, "a function");
|
|
35731
|
+
}
|
|
35732
|
+
}
|
|
35465
35733
|
if (kind === "device") {
|
|
35466
35734
|
checkAt(typeof value.begin === "function", id, "oauth.begin", "a function");
|
|
35467
35735
|
checkAt(typeof value.needsDeviceId === "boolean", id, "oauth.needsDeviceId", "a boolean");
|
|
@@ -35657,6 +35925,52 @@ async function quotaHistory(deps, input2) {
|
|
|
35657
35925
|
|
|
35658
35926
|
// packages/control/src/quota/clientHistory.ts
|
|
35659
35927
|
var MAX_SPAN_MS = 16 * 24 * 60 * 60 * 1000;
|
|
35928
|
+
// packages/control/src/quota/resets.ts
|
|
35929
|
+
async function resettable(deps, credentialId) {
|
|
35930
|
+
const credential = await deps.store.credentials.get(credentialId.trim());
|
|
35931
|
+
if (credential === null)
|
|
35932
|
+
throw new GatewayError("BAD_REQUEST", "no such credential");
|
|
35933
|
+
const provider = deps.providers[credential.provider];
|
|
35934
|
+
const list = provider?.resetCredits;
|
|
35935
|
+
const redeem = provider?.redeemReset;
|
|
35936
|
+
if (credential.authType !== "oauth" || list === undefined || redeem === undefined) {
|
|
35937
|
+
throw new GatewayError("BAD_REQUEST", "this account's provider has no quota resets");
|
|
35938
|
+
}
|
|
35939
|
+
return { credential, list, redeem };
|
|
35940
|
+
}
|
|
35941
|
+
async function listFor(deps, r) {
|
|
35942
|
+
const secrets = await usageSecretsFor(deps, r.credential);
|
|
35943
|
+
const read = await r.list(secrets, { http: deps.http, now: deps.now }, r.credential.providerData);
|
|
35944
|
+
if (read === null) {
|
|
35945
|
+
throw new GatewayError("UPSTREAM", "provider answered the reset list with nothing usable", {
|
|
35946
|
+
gatewayAuthored: true
|
|
35947
|
+
});
|
|
35948
|
+
}
|
|
35949
|
+
return read;
|
|
35950
|
+
}
|
|
35951
|
+
async function listResetCredits(deps, credentialId) {
|
|
35952
|
+
const r = await resettable(deps, credentialId);
|
|
35953
|
+
return { credentialId: r.credential.id, ...await listFor(deps, r) };
|
|
35954
|
+
}
|
|
35955
|
+
async function redeemResetCredit(deps, request2) {
|
|
35956
|
+
const r = await resettable(deps, request2.credentialId);
|
|
35957
|
+
return deps.coord.mutex.withLock(PROBE_LOCK_PREFIX + r.credential.id, PROBE_LOCK_TTL_MS, PROBE_LOCK_WAIT_MS, () => redeemLocked(deps, r, request2));
|
|
35958
|
+
}
|
|
35959
|
+
async function redeemLocked(deps, r, request2) {
|
|
35960
|
+
const available = (await listFor(deps, r)).credits.filter((c) => c.status === "available").sort((a, b) => (a.expiresAt ?? Number.POSITIVE_INFINITY) - (b.expiresAt ?? Number.POSITIVE_INFINITY));
|
|
35961
|
+
const credit = request2.creditId === undefined ? available[0] : available.find((c) => c.id === request2.creditId);
|
|
35962
|
+
if (credit === undefined) {
|
|
35963
|
+
throw new GatewayError("CONFLICT", request2.creditId === undefined ? "no reset credit is available for this account" : "that reset credit is not available");
|
|
35964
|
+
}
|
|
35965
|
+
const secrets = await usageSecretsFor(deps, r.credential);
|
|
35966
|
+
const { windowsReset } = await r.redeem(secrets, { http: deps.http, now: deps.now }, r.credential.providerData, credit.id, crypto.randomUUID());
|
|
35967
|
+
let quotaRefreshed = false;
|
|
35968
|
+
try {
|
|
35969
|
+
quotaRefreshed = await probe(deps, r.credential) !== null;
|
|
35970
|
+
} catch {}
|
|
35971
|
+
return { credentialId: r.credential.id, creditId: credit.id, windowsReset, quotaRefreshed };
|
|
35972
|
+
}
|
|
35973
|
+
|
|
35660
35974
|
// packages/control/src/quota/poll.ts
|
|
35661
35975
|
var CONCURRENCY = 4;
|
|
35662
35976
|
var RATE_LIMIT_COOLDOWN_MS = 180000;
|
|
@@ -35664,14 +35978,17 @@ var COOLDOWN_PREFIX = "quota:cooldown:";
|
|
|
35664
35978
|
var PROBE_LOCK_PREFIX = "quota:probe:";
|
|
35665
35979
|
var PROBE_LOCK_TTL_MS = 60000;
|
|
35666
35980
|
var PROBE_LOCK_WAIT_MS = 30000;
|
|
35981
|
+
async function usageSecretsFor(deps, credential) {
|
|
35982
|
+
const refreshed = credential.hasRefreshToken && credential.expiresAt !== null && credential.expiresAt - SCHEDULER_REFRESH_LEAD_MS <= deps.now() ? await deps.refresh(credential) : null;
|
|
35983
|
+
return refreshed === null ? await credential.openForUsage() : { accessToken: refreshed.accessToken };
|
|
35984
|
+
}
|
|
35667
35985
|
async function probe(deps, credential) {
|
|
35668
35986
|
if (credential.authType !== "oauth")
|
|
35669
35987
|
return null;
|
|
35670
35988
|
const provider = deps.providers[credential.provider];
|
|
35671
35989
|
if (provider?.usage === undefined)
|
|
35672
35990
|
return null;
|
|
35673
|
-
const
|
|
35674
|
-
const secrets = refreshed === null ? await credential.openForUsage() : { accessToken: refreshed.accessToken };
|
|
35991
|
+
const secrets = await usageSecretsFor(deps, credential);
|
|
35675
35992
|
const report = await provider.usage(secrets, { http: deps.http, now: deps.now }, credential.providerData);
|
|
35676
35993
|
if (report === null || report.windows.length === 0)
|
|
35677
35994
|
return null;
|
|
@@ -35834,6 +36151,12 @@ function quotaOps(deps) {
|
|
|
35834
36151
|
outcomes.push(result?.outcome ?? { kind: "failed", credentialId: credential.id, code: "INTERNAL" });
|
|
35835
36152
|
}
|
|
35836
36153
|
return { outcomes };
|
|
36154
|
+
},
|
|
36155
|
+
resetCredits: (credentialId) => listResetCredits(deps, credentialId),
|
|
36156
|
+
redeemReset: (request2) => redeemResetCredit(deps, request2),
|
|
36157
|
+
hasResets: (provider) => {
|
|
36158
|
+
const flow = deps.providers[provider];
|
|
36159
|
+
return flow?.resetCredits !== undefined && flow.redeemReset !== undefined;
|
|
35837
36160
|
}
|
|
35838
36161
|
};
|
|
35839
36162
|
}
|
|
@@ -38018,16 +38341,7 @@ var quotaRefresh = {
|
|
|
38018
38341
|
const store = await ctx.store();
|
|
38019
38342
|
const credentials = await listCredentials(store);
|
|
38020
38343
|
const wanted = id === undefined ? credentials : credentials.filter((c) => c.id === id);
|
|
38021
|
-
const
|
|
38022
|
-
const http = nodeHttpClient();
|
|
38023
|
-
const ops = quotaOps({
|
|
38024
|
-
store,
|
|
38025
|
-
coord: memoryCoord({ now: ctx.now }),
|
|
38026
|
-
providers,
|
|
38027
|
-
http,
|
|
38028
|
-
refresh: createRefresher({ store, providers, http, now: ctx.now }),
|
|
38029
|
-
now: ctx.now
|
|
38030
|
-
});
|
|
38344
|
+
const ops = await opsFor(ctx, wanted);
|
|
38031
38345
|
note(ctx, writer, id === undefined ? "refreshing every account\u2026" : `refreshing ${id}\u2026`);
|
|
38032
38346
|
const result = await ops.refresh(id === undefined ? { kind: "all" } : { kind: "one", credentialId: id });
|
|
38033
38347
|
const labels = new Map(credentials.map((c) => [c.id, c.label]));
|
|
@@ -38053,6 +38367,59 @@ var quotaRefresh = {
|
|
|
38053
38367
|
}
|
|
38054
38368
|
}
|
|
38055
38369
|
};
|
|
38370
|
+
async function opsFor(ctx, wanted) {
|
|
38371
|
+
const store = await ctx.store();
|
|
38372
|
+
const providers = wanted.every((c) => Object.hasOwn(PROVIDER_DESCRIPTORS, c.provider)) ? OAUTH_PROVIDERS : (await connectRegistryFor(ctx.root.root)).providers;
|
|
38373
|
+
const http = nodeHttpClient();
|
|
38374
|
+
return quotaOps({
|
|
38375
|
+
store,
|
|
38376
|
+
coord: memoryCoord({ now: ctx.now }),
|
|
38377
|
+
providers,
|
|
38378
|
+
http,
|
|
38379
|
+
refresh: createRefresher({ store, providers, http, now: ctx.now }),
|
|
38380
|
+
now: ctx.now
|
|
38381
|
+
});
|
|
38382
|
+
}
|
|
38383
|
+
var quotaResets = {
|
|
38384
|
+
usage: "quota resets <id>",
|
|
38385
|
+
summary: "List an account's banked quota resets (Codex, Claude)",
|
|
38386
|
+
async run(args, { ctx, writer }) {
|
|
38387
|
+
const id = requirePositional(args, 0, "credential id");
|
|
38388
|
+
const credentials = (await listCredentials(await ctx.store())).filter((c) => c.id === id);
|
|
38389
|
+
const listed = await (await opsFor(ctx, credentials)).resetCredits(id);
|
|
38390
|
+
emit(ctx, writer, listed, () => [
|
|
38391
|
+
table([{ header: "CREDIT" }, { header: "STATUS" }, { header: "TITLE" }, { header: "EXPIRES" }], listed.credits.map((c) => [c.id, c.status, c.title ?? dash, formatTime(c.expiresAt)])),
|
|
38392
|
+
"",
|
|
38393
|
+
`${listed.available} available`
|
|
38394
|
+
].join(`
|
|
38395
|
+
`));
|
|
38396
|
+
}
|
|
38397
|
+
};
|
|
38398
|
+
var quotaReset = {
|
|
38399
|
+
usage: "quota reset <id> [--credit CREDIT_ID]",
|
|
38400
|
+
summary: "Spend one banked quota reset on an account (irreversible)",
|
|
38401
|
+
options: { credit: { type: "string" } },
|
|
38402
|
+
async run(args, { ctx, writer, prompt }) {
|
|
38403
|
+
const id = requirePositional(args, 0, "credential id");
|
|
38404
|
+
const creditId = stringFlag(args.values, "credit");
|
|
38405
|
+
const credentials = (await listCredentials(await ctx.store())).filter((c) => c.id === id);
|
|
38406
|
+
const label3 = credentials[0]?.label ?? id;
|
|
38407
|
+
const ops = await opsFor(ctx, credentials);
|
|
38408
|
+
const provider2 = credentials[0]?.provider;
|
|
38409
|
+
if (provider2 === undefined)
|
|
38410
|
+
throw new CliError("no such credential");
|
|
38411
|
+
if (!ops.hasResets(provider2))
|
|
38412
|
+
throw new CliError("this account's provider has no quota resets");
|
|
38413
|
+
if (!await prompt.confirm(`spend one banked quota reset on "${label3}" (${id})?`)) {
|
|
38414
|
+
throw new CliError("cancelled");
|
|
38415
|
+
}
|
|
38416
|
+
const result = await ops.redeemReset({
|
|
38417
|
+
credentialId: id,
|
|
38418
|
+
...creditId === undefined ? {} : { creditId }
|
|
38419
|
+
});
|
|
38420
|
+
emit(ctx, writer, result, () => `${label3}: reset ${result.creditId} redeemed` + (result.windowsReset === null ? "" : `, ${result.windowsReset} window(s) reset`) + (result.quotaRefreshed ? "; quota re-read" : "; quota re-read failed, next poll will update it"));
|
|
38421
|
+
}
|
|
38422
|
+
};
|
|
38056
38423
|
|
|
38057
38424
|
// apps/cli/src/commands/service.ts
|
|
38058
38425
|
import { existsSync as existsSync5 } from "fs";
|
|
@@ -38143,7 +38510,7 @@ function createServiceDeps(input2) {
|
|
|
38143
38510
|
}
|
|
38144
38511
|
|
|
38145
38512
|
// apps/cli/src/version.ts
|
|
38146
|
-
var VERSION = "0.12.
|
|
38513
|
+
var VERSION = "0.12.13";
|
|
38147
38514
|
|
|
38148
38515
|
// apps/cli/src/commands/service.ts
|
|
38149
38516
|
function gatewayArgv(root) {
|
|
@@ -38860,6 +39227,8 @@ var COMMANDS = {
|
|
|
38860
39227
|
"credentials add-key": credentialsAddKey,
|
|
38861
39228
|
"credentials health": credentialsHealth,
|
|
38862
39229
|
"quota refresh": quotaRefresh,
|
|
39230
|
+
"quota resets": quotaResets,
|
|
39231
|
+
"quota reset": quotaReset,
|
|
38863
39232
|
"models list": modelsList,
|
|
38864
39233
|
"models show": modelsShow,
|
|
38865
39234
|
"models put": modelsPut,
|