@p4code/cli 0.6.51 → 0.6.53
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/bin.mjs +812 -253
- package/dist/client/assets/{DiffPanel-BUCreuWY.js → DiffPanel-DIwMVc8O.js} +3 -3
- package/dist/client/assets/{FilePreviewPanel-cy1z7CZO.js → FilePreviewPanel-BKJazNKZ.js} +5 -5
- package/dist/client/assets/{PreviewPanel-eSWyX1_v.js → PreviewPanel-B6V5_zrn.js} +2 -2
- package/dist/client/assets/{PullRequestCodeTab-C-Daetzd.js → PullRequestCodeTab-Db-f5nCl.js} +2 -2
- package/dist/client/assets/{fileCommentAnnotations-84Z3ObDe.js → fileCommentAnnotations-DNTigixo.js} +2 -2
- package/dist/client/assets/{index-CQLaabQG.js → index-5L471ah2.js} +252 -240
- package/dist/client/assets/{index-B_0XzNmV.css → index-o7sBVQed.css} +1 -1
- package/dist/client/assets/previewAssetResource-CgRbTpIo.js +48 -0
- package/dist/client/assets/{renderFileChildren-Cd2hMjqK.js → renderFileChildren-COEZ-8XH.js} +2 -2
- package/dist/client/assets/{toggle-group-19UXopN-.js → toggle-group-DyK1qT7a.js} +2 -2
- package/dist/client/index.html +3 -3
- package/package.json +1 -1
- package/dist/client/assets/previewAssetResource-DYwBmJlU.js +0 -48
package/dist/bin.mjs
CHANGED
|
@@ -263,7 +263,7 @@ const make$123 = () => {
|
|
|
263
263
|
const layer$124 = Layer.sync(NetService, make$123);
|
|
264
264
|
//#endregion
|
|
265
265
|
//#region package.json
|
|
266
|
-
var version$1 = "0.6.
|
|
266
|
+
var version$1 = "0.6.53";
|
|
267
267
|
//#endregion
|
|
268
268
|
//#region ../../packages/shared/src/serverInstance.ts
|
|
269
269
|
/**
|
|
@@ -7950,9 +7950,18 @@ const RESET_CREDIT_IDEMPOTENCY_KEY_MAX_LENGTH = 128;
|
|
|
7950
7950
|
* the request never produced an answer - the provider may or may not have
|
|
7951
7951
|
* acted, so retrying with the same `idempotencyKey` is the safe next step.
|
|
7952
7952
|
*/
|
|
7953
|
+
/** A Codex account a usage source pools, named by the source and the source's account id. */
|
|
7954
|
+
const UsageLimitSourceAccountRef = Schema$1.Struct({
|
|
7955
|
+
sourceId: UsageLimitSourceId,
|
|
7956
|
+
accountId: TrimmedNonEmptyString
|
|
7957
|
+
});
|
|
7958
|
+
/** Whose reset credit: a native provider instance, or an account a usage source pools. */
|
|
7959
|
+
const ResetCreditTarget = Schema$1.Union([Schema$1.Struct({ instanceId: ProviderInstanceId }), Schema$1.Struct({ sourceAccount: UsageLimitSourceAccountRef })]);
|
|
7953
7960
|
const ProviderResetCreditAttempt = Schema$1.Struct({
|
|
7954
7961
|
idempotencyKey: TrimmedNonEmptyString,
|
|
7955
|
-
|
|
7962
|
+
/** Set for a native instance's attempt; `sourceAccount` is set instead for a pooled account. */
|
|
7963
|
+
instanceId: Schema$1.optional(ProviderInstanceId),
|
|
7964
|
+
sourceAccount: Schema$1.optional(UsageLimitSourceAccountRef),
|
|
7956
7965
|
/** The credit this attempt named, fixed at its first try so a retry cannot switch credits. */
|
|
7957
7966
|
creditId: Schema$1.optional(TrimmedNonEmptyString),
|
|
7958
7967
|
requestedAt: IsoDateTime,
|
|
@@ -7960,15 +7969,27 @@ const ProviderResetCreditAttempt = Schema$1.Struct({
|
|
|
7960
7969
|
detail: Schema$1.optional(TrimmedNonEmptyString),
|
|
7961
7970
|
completedAt: Schema$1.optional(IsoDateTime)
|
|
7962
7971
|
});
|
|
7963
|
-
const
|
|
7964
|
-
instanceId: ProviderInstanceId,
|
|
7972
|
+
const ConsumeProviderResetCreditFields = {
|
|
7965
7973
|
/** One logical attempt; resend the same key to retry it without spending twice. */
|
|
7966
7974
|
idempotencyKey: TrimmedNonEmptyString.check(Schema$1.isMaxLength(RESET_CREDIT_IDEMPOTENCY_KEY_MAX_LENGTH)),
|
|
7967
|
-
/**
|
|
7975
|
+
/**
|
|
7976
|
+
* The credit the client was shown; omitted lets the provider pick the next
|
|
7977
|
+
* one. Required for a pooled account, whose source may since hold another
|
|
7978
|
+
* login: naming the credit makes Codex refuse instead of spending its reset.
|
|
7979
|
+
*/
|
|
7968
7980
|
creditId: Schema$1.optional(TrimmedNonEmptyString)
|
|
7969
|
-
}
|
|
7970
|
-
|
|
7981
|
+
};
|
|
7982
|
+
const ConsumeProviderResetCreditInput = Schema$1.Union([Schema$1.Struct({
|
|
7971
7983
|
instanceId: ProviderInstanceId,
|
|
7984
|
+
...ConsumeProviderResetCreditFields
|
|
7985
|
+
}), Schema$1.Struct({
|
|
7986
|
+
sourceAccount: UsageLimitSourceAccountRef,
|
|
7987
|
+
...ConsumeProviderResetCreditFields,
|
|
7988
|
+
creditId: TrimmedNonEmptyString
|
|
7989
|
+
})]);
|
|
7990
|
+
var ProviderResetCreditError = class extends Schema$1.TaggedErrorClass()("ProviderResetCreditError", {
|
|
7991
|
+
instanceId: Schema$1.optionalKey(ProviderInstanceId),
|
|
7992
|
+
sourceAccount: Schema$1.optionalKey(UsageLimitSourceAccountRef),
|
|
7972
7993
|
detail: Schema$1.String,
|
|
7973
7994
|
/** True once the request reached Codex, so a reset may have been used. */
|
|
7974
7995
|
consumeSent: Schema$1.optionalKey(Schema$1.Boolean),
|
|
@@ -16276,17 +16297,18 @@ const WsServerGetProviderUsageRpc = Rpc.make(WS_METHODS.serverGetProviderUsage,
|
|
|
16276
16297
|
error: Schema$1.Union([TextGenerationError, EnvironmentAuthorizationError])
|
|
16277
16298
|
});
|
|
16278
16299
|
/**
|
|
16279
|
-
* Redeem one of the account's banked reset credits
|
|
16280
|
-
*
|
|
16300
|
+
* Redeem one of the account's banked reset credits: natively for a Codex
|
|
16301
|
+
* instance, or through the usage source for a pooled Codex account. Anything
|
|
16302
|
+
* else fails with `ProviderResetCreditError`.
|
|
16281
16303
|
*/
|
|
16282
16304
|
const WsServerConsumeProviderResetCreditRpc = Rpc.make(WS_METHODS.serverConsumeProviderResetCredit, {
|
|
16283
16305
|
payload: ConsumeProviderResetCreditInput,
|
|
16284
16306
|
success: Schema$1.Struct({ attempt: ProviderResetCreditAttempt }),
|
|
16285
16307
|
error: Schema$1.Union([ProviderResetCreditError, EnvironmentAuthorizationError])
|
|
16286
16308
|
});
|
|
16287
|
-
/** Redemptions started through P4 for one instance, newest first. */
|
|
16309
|
+
/** Redemptions started through P4 for one instance or pooled account, newest first. */
|
|
16288
16310
|
const WsServerListProviderResetCreditAttemptsRpc = Rpc.make(WS_METHODS.serverListProviderResetCreditAttempts, {
|
|
16289
|
-
payload:
|
|
16311
|
+
payload: ResetCreditTarget,
|
|
16290
16312
|
success: Schema$1.Struct({ attempts: Schema$1.Array(ProviderResetCreditAttempt) }),
|
|
16291
16313
|
error: Schema$1.Union([ProviderResetCreditError, EnvironmentAuthorizationError])
|
|
16292
16314
|
});
|
|
@@ -33511,7 +33533,7 @@ const ManifestFile = Schema$1.Struct({
|
|
|
33511
33533
|
directories: Schema$1.Record(Schema$1.String, Schema$1.Array(ManifestEntry))
|
|
33512
33534
|
});
|
|
33513
33535
|
const ManifestFileFromJson = Schema$1.fromJsonString(ManifestFile);
|
|
33514
|
-
const decodeManifest
|
|
33536
|
+
const decodeManifest = Schema$1.decodeUnknownEffect(ManifestFileFromJson);
|
|
33515
33537
|
const encodeManifest = Schema$1.encodeEffect(ManifestFileFromJson);
|
|
33516
33538
|
const EMPTY = {
|
|
33517
33539
|
version: 1,
|
|
@@ -33528,7 +33550,7 @@ const EMPTY = {
|
|
|
33528
33550
|
const readSkillManifest = Effect.fn("skillManifest.read")(function* (manifestPath) {
|
|
33529
33551
|
const raw = yield* (yield* FileSystem.FileSystem).readFileString(manifestPath).pipe(Effect.orElseSucceed(() => void 0));
|
|
33530
33552
|
if (raw === void 0) return EMPTY;
|
|
33531
|
-
return yield* decodeManifest
|
|
33553
|
+
return yield* decodeManifest(raw).pipe(Effect.orElseSucceed(() => EMPTY));
|
|
33532
33554
|
});
|
|
33533
33555
|
const entriesFor = (manifest, skillsRoot) => manifest.directories[skillsRoot] ?? [];
|
|
33534
33556
|
const withEntriesFor = (manifest, skillsRoot, entries) => ({
|
|
@@ -37146,7 +37168,7 @@ function collectForkedAttachmentCopies(threadId, rows) {
|
|
|
37146
37168
|
}
|
|
37147
37169
|
return copies;
|
|
37148
37170
|
}
|
|
37149
|
-
function isRecord$
|
|
37171
|
+
function isRecord$7(value) {
|
|
37150
37172
|
return value !== null && typeof value === "object" && !Array.isArray(value);
|
|
37151
37173
|
}
|
|
37152
37174
|
/**
|
|
@@ -37157,7 +37179,7 @@ function isRecord$6(value) {
|
|
|
37157
37179
|
function buildForkedProviderBinding(threadId, source) {
|
|
37158
37180
|
if (source === void 0) return { rejection: "no-binding" };
|
|
37159
37181
|
if (!FORKABLE_PROVIDERS.has(source.provider)) return { rejection: "provider-cannot-fork" };
|
|
37160
|
-
if (!isRecord$
|
|
37182
|
+
if (!isRecord$7(source.resumeCursor) || typeof source.resumeCursor.resume !== "string") return { rejection: "no-resume-cursor" };
|
|
37161
37183
|
return { binding: {
|
|
37162
37184
|
threadId,
|
|
37163
37185
|
provider: source.provider,
|
|
@@ -62754,18 +62776,18 @@ function deriveToolActivityPresentation(input) {
|
|
|
62754
62776
|
}
|
|
62755
62777
|
//#endregion
|
|
62756
62778
|
//#region src/provider/acp/AcpRuntimeModel.ts
|
|
62757
|
-
function isRecord$
|
|
62779
|
+
function isRecord$6(value) {
|
|
62758
62780
|
return typeof value === "object" && value !== null && !Array.isArray(value);
|
|
62759
62781
|
}
|
|
62760
62782
|
function isSessionModelState(value) {
|
|
62761
|
-
if (!isRecord$
|
|
62783
|
+
if (!isRecord$6(value) || typeof value.currentModelId !== "string") return false;
|
|
62762
62784
|
if (!Array.isArray(value.availableModels)) return false;
|
|
62763
|
-
return value.availableModels.every((model) => isRecord$
|
|
62785
|
+
return value.availableModels.every((model) => isRecord$6(model) && typeof model.modelId === "string" && typeof model.name === "string" && (model.description === void 0 || model.description === null || typeof model.description === "string"));
|
|
62764
62786
|
}
|
|
62765
62787
|
function isSessionModeState(value) {
|
|
62766
|
-
if (!isRecord$
|
|
62788
|
+
if (!isRecord$6(value) || typeof value.currentModeId !== "string") return false;
|
|
62767
62789
|
if (!Array.isArray(value.availableModes)) return false;
|
|
62768
|
-
return value.availableModes.every((mode) => isRecord$
|
|
62790
|
+
return value.availableModes.every((mode) => isRecord$6(mode) && typeof mode.id === "string" && typeof mode.name === "string" && (mode.description === void 0 || typeof mode.description === "string"));
|
|
62769
62791
|
}
|
|
62770
62792
|
function extractModelConfigId(sessionResponse) {
|
|
62771
62793
|
const configOptions = sessionResponse.configOptions;
|
|
@@ -62841,7 +62863,7 @@ function extractCommandFromTitle(title) {
|
|
|
62841
62863
|
return /`([^`]+)`/.exec(title)?.[1]?.trim() || void 0;
|
|
62842
62864
|
}
|
|
62843
62865
|
function extractToolCallCommand(rawInput, title) {
|
|
62844
|
-
if (isRecord$
|
|
62866
|
+
if (isRecord$6(rawInput)) {
|
|
62845
62867
|
const directCommand = normalizeCommandValue(rawInput.command);
|
|
62846
62868
|
if (directCommand) return directCommand;
|
|
62847
62869
|
const executable = typeof rawInput.executable === "string" ? rawInput.executable.trim() : "";
|
|
@@ -62963,7 +62985,7 @@ function parsePermissionRequest(params) {
|
|
|
62963
62985
|
}
|
|
62964
62986
|
function sessionUpdateIsReplay(params) {
|
|
62965
62987
|
const meta = params._meta;
|
|
62966
|
-
return isRecord$
|
|
62988
|
+
return isRecord$6(meta) && meta.isReplay === true;
|
|
62967
62989
|
}
|
|
62968
62990
|
const waitForSessionLoadReplayIdle = (input) => Effect.gen(function* () {
|
|
62969
62991
|
const pollInterval = Duration.millis(25);
|
|
@@ -62978,8 +63000,8 @@ const waitForSessionLoadReplayIdle = (input) => Effect.gen(function* () {
|
|
|
62978
63000
|
});
|
|
62979
63001
|
function syntheticLoadSessionResponseFromInitialize(initializeResult) {
|
|
62980
63002
|
const meta = initializeResult._meta;
|
|
62981
|
-
const modelState = isRecord$
|
|
62982
|
-
const modeState = isRecord$
|
|
63003
|
+
const modelState = isRecord$6(meta) ? meta.modelState : void 0;
|
|
63004
|
+
const modeState = isRecord$6(meta) ? meta.modeState : void 0;
|
|
62983
63005
|
const models = isSessionModelState(modelState) ? modelState : void 0;
|
|
62984
63006
|
const modes = isSessionModeState(modeState) ? modeState : void 0;
|
|
62985
63007
|
return {
|
|
@@ -67083,24 +67105,426 @@ function hasValidClaudeManifestAdapters(manifest) {
|
|
|
67083
67105
|
return Object.values(catalog.profiles).every((profile) => Option.isSome(decodeClaudeProfileAdapter(profile.adapter ?? {}))) && catalog.models.every((model) => Option.isSome(decodeClaudeModelAdapter(model.adapter ?? {})));
|
|
67084
67106
|
}
|
|
67085
67107
|
//#endregion
|
|
67108
|
+
//#region src/usage/usageSourceHttp.ts
|
|
67109
|
+
const MAX_RESPONSE_BYTES$1 = 1024 * 1024;
|
|
67110
|
+
const LOOPBACK_HOSTS$1 = /* @__PURE__ */ new Set([
|
|
67111
|
+
"localhost",
|
|
67112
|
+
"127.0.0.1",
|
|
67113
|
+
"[::1]"
|
|
67114
|
+
]);
|
|
67115
|
+
/** The management key stays on the configured origin, including redirects. */
|
|
67116
|
+
async function readManagementJson(config, path, body, signal) {
|
|
67117
|
+
const base = new URL(config.url);
|
|
67118
|
+
if (base.username || base.password || base.search || base.hash || base.protocol !== "https:" && !(base.protocol === "http:" && LOOPBACK_HOSTS$1.has(base.hostname))) throw new Error("Invalid usage source origin");
|
|
67119
|
+
if (path !== "auth-files" && path !== "api-call" && !/^model-definitions\/[a-z0-9-]+$/.test(path)) throw new Error("Unsupported management operation");
|
|
67120
|
+
const response = await fetch(new URL(`/v0/management/${path}`, base), {
|
|
67121
|
+
method: body === void 0 ? "GET" : "POST",
|
|
67122
|
+
redirect: "error",
|
|
67123
|
+
signal,
|
|
67124
|
+
headers: {
|
|
67125
|
+
authorization: `Bearer ${config.managementKey}`,
|
|
67126
|
+
"content-type": "application/json"
|
|
67127
|
+
},
|
|
67128
|
+
...body === void 0 ? {} : { body: JSON.stringify(body) }
|
|
67129
|
+
});
|
|
67130
|
+
if (!response.ok || !response.body) {
|
|
67131
|
+
await response.body?.cancel();
|
|
67132
|
+
throw new UsageLimitSourceError({ detail: response.status === 401 || response.status === 403 ? `The usage source rejected its management key (HTTP ${response.status}). Edit the source under Usage sources to update the management key; a provider API key cannot replace it.` : `The usage source management request failed (HTTP ${response.status}). Check the source URL and management API availability.` });
|
|
67133
|
+
}
|
|
67134
|
+
const reader = response.body.getReader();
|
|
67135
|
+
const chunks = [];
|
|
67136
|
+
let total = 0;
|
|
67137
|
+
try {
|
|
67138
|
+
for (;;) {
|
|
67139
|
+
const chunk = await reader.read();
|
|
67140
|
+
if (chunk.done) break;
|
|
67141
|
+
total += chunk.value.byteLength;
|
|
67142
|
+
if (total > MAX_RESPONSE_BYTES$1) throw new Error("Usage source response too large");
|
|
67143
|
+
chunks.push(chunk.value);
|
|
67144
|
+
}
|
|
67145
|
+
return JSON.parse(Buffer.concat(chunks).toString("utf8"));
|
|
67146
|
+
} finally {
|
|
67147
|
+
await reader.cancel().catch(() => void 0);
|
|
67148
|
+
reader.releaseLock();
|
|
67149
|
+
}
|
|
67150
|
+
}
|
|
67151
|
+
//#endregion
|
|
67152
|
+
//#region src/provider/externalModelCatalog.ts
|
|
67153
|
+
/**
|
|
67154
|
+
* External model list folded over the bundled manifest. Sources in order: the
|
|
67155
|
+
* user's CLIProxyAPI (CPA) usage source, models.dev, then OpenRouter. Each
|
|
67156
|
+
* provider comes from the first source that lists it.
|
|
67157
|
+
*
|
|
67158
|
+
* The external list decides which Anthropic, OpenAI and Google models exist,
|
|
67159
|
+
* their names, context sizes and which one is current in each family. The
|
|
67160
|
+
* bundled manifest keeps what only P4 Code knows: Claude Code option profiles
|
|
67161
|
+
* (ultracode, effort mapping), minimum CLI versions, aliases and Antigravity's
|
|
67162
|
+
* effort-suffixed slugs. A model the bundle does not know yet inherits the
|
|
67163
|
+
* newest bundled model of its family.
|
|
67164
|
+
*/
|
|
67165
|
+
const MODELS_DEV_URL = "https://models.dev/api.json";
|
|
67166
|
+
const OPENROUTER_MODELS_URL = "https://openrouter.ai/api/v1/models";
|
|
67167
|
+
const ExternalProvider = Schema$1.Literals([
|
|
67168
|
+
"anthropic",
|
|
67169
|
+
"openai",
|
|
67170
|
+
"google"
|
|
67171
|
+
]);
|
|
67172
|
+
const EXTERNAL_PROVIDERS = [
|
|
67173
|
+
"anthropic",
|
|
67174
|
+
"openai",
|
|
67175
|
+
"google"
|
|
67176
|
+
];
|
|
67177
|
+
/** CPA `model-definitions` channels per provider. Its Google channels trail models.dev. */
|
|
67178
|
+
const CPA_CHANNELS = [
|
|
67179
|
+
{
|
|
67180
|
+
provider: "anthropic",
|
|
67181
|
+
channel: "claude"
|
|
67182
|
+
},
|
|
67183
|
+
{
|
|
67184
|
+
provider: "openai",
|
|
67185
|
+
channel: "codex-pro"
|
|
67186
|
+
},
|
|
67187
|
+
{
|
|
67188
|
+
provider: "openai",
|
|
67189
|
+
channel: "codex-plus"
|
|
67190
|
+
},
|
|
67191
|
+
{
|
|
67192
|
+
provider: "openai",
|
|
67193
|
+
channel: "codex-team"
|
|
67194
|
+
},
|
|
67195
|
+
{
|
|
67196
|
+
provider: "openai",
|
|
67197
|
+
channel: "codex-free"
|
|
67198
|
+
}
|
|
67199
|
+
];
|
|
67200
|
+
const ExternalModel = Schema$1.Struct({
|
|
67201
|
+
provider: ExternalProvider,
|
|
67202
|
+
id: Schema$1.String,
|
|
67203
|
+
name: Schema$1.String,
|
|
67204
|
+
family: Schema$1.String,
|
|
67205
|
+
/** ISO date; the newest model of a family is its current one. */
|
|
67206
|
+
releaseDate: Schema$1.optional(Schema$1.String),
|
|
67207
|
+
contextTokens: Schema$1.optional(Schema$1.Number),
|
|
67208
|
+
/** Effort levels the model accepts, when the source lists them. */
|
|
67209
|
+
effort: Schema$1.optional(Schema$1.Array(Schema$1.String)),
|
|
67210
|
+
/** Whether a fast mode exists, when the source says. */
|
|
67211
|
+
fastMode: Schema$1.optional(Schema$1.Boolean)
|
|
67212
|
+
});
|
|
67213
|
+
const isRecord$5 = (value) => typeof value === "object" && value !== null && !Array.isArray(value);
|
|
67214
|
+
const stringOr = (value) => typeof value === "string" && value.trim() !== "" ? value.trim() : void 0;
|
|
67215
|
+
const numberOr = (value) => typeof value === "number" && Number.isFinite(value) && value > 0 ? value : void 0;
|
|
67216
|
+
/** Coding agents only run tool-calling models that answer in text; image, audio and TTS models share families with them. */
|
|
67217
|
+
const isTextOnly = (modalities) => Array.isArray(modalities) && modalities.length === 1 && modalities[0] === "text";
|
|
67218
|
+
/** Family of a model id with its version tokens removed: `claude-opus-5-5` is `claude-opus`. */
|
|
67219
|
+
function familyOf(id) {
|
|
67220
|
+
return id.split("-").filter((token) => !/^\d+(\.\d+)*$/.test(token)).join("-");
|
|
67221
|
+
}
|
|
67222
|
+
/** Parse one CPA `/v0/management/model-definitions/:channel` response. */
|
|
67223
|
+
function parseCpaModelDefinitions(json, provider) {
|
|
67224
|
+
if (!isRecord$5(json) || !Array.isArray(json.models)) return [];
|
|
67225
|
+
return json.models.flatMap((raw) => {
|
|
67226
|
+
if (!isRecord$5(raw)) return [];
|
|
67227
|
+
const id = stringOr(raw.id);
|
|
67228
|
+
const output = raw.supportedOutputModalities;
|
|
67229
|
+
if (!id || output !== void 0 && !isTextOnly(output)) return [];
|
|
67230
|
+
const created = numberOr(raw.created);
|
|
67231
|
+
const contextTokens = numberOr(raw.context_length) ?? numberOr(raw.inputTokenLimit);
|
|
67232
|
+
const levels = isRecord$5(raw.thinking) ? raw.thinking.levels : void 0;
|
|
67233
|
+
return [{
|
|
67234
|
+
provider,
|
|
67235
|
+
id,
|
|
67236
|
+
name: stringOr(raw.display_name) ?? id,
|
|
67237
|
+
family: familyOf(id),
|
|
67238
|
+
...created ? { releaseDate: (/* @__PURE__ */ new Date(created * 1e3)).toISOString() } : {},
|
|
67239
|
+
...contextTokens ? { contextTokens } : {},
|
|
67240
|
+
...Array.isArray(levels) ? { effort: levels.filter((level) => typeof level === "string") } : {}
|
|
67241
|
+
}];
|
|
67242
|
+
});
|
|
67243
|
+
}
|
|
67244
|
+
/** Parse `https://models.dev/api.json`; null when it lists none of our providers. */
|
|
67245
|
+
function parseModelsDev(json) {
|
|
67246
|
+
if (!isRecord$5(json)) return null;
|
|
67247
|
+
const models = [];
|
|
67248
|
+
for (const provider of EXTERNAL_PROVIDERS) {
|
|
67249
|
+
const entry = json[provider];
|
|
67250
|
+
if (!isRecord$5(entry) || !isRecord$5(entry.models)) continue;
|
|
67251
|
+
for (const raw of Object.values(entry.models)) {
|
|
67252
|
+
if (!isRecord$5(raw)) continue;
|
|
67253
|
+
const id = stringOr(raw.id);
|
|
67254
|
+
const output = isRecord$5(raw.modalities) ? raw.modalities.output : void 0;
|
|
67255
|
+
if (!id || raw.tool_call !== true || !isTextOnly(output)) continue;
|
|
67256
|
+
const effort = Array.isArray(raw.reasoning_options) ? raw.reasoning_options.find((option) => isRecord$5(option) && option.type === "effort") : void 0;
|
|
67257
|
+
const effortValues = isRecord$5(effort) && Array.isArray(effort.values) ? effort.values.filter((value) => typeof value === "string") : void 0;
|
|
67258
|
+
const modes = isRecord$5(raw.experimental) ? raw.experimental.modes : void 0;
|
|
67259
|
+
const releaseDate = stringOr(raw.release_date);
|
|
67260
|
+
const contextTokens = isRecord$5(raw.limit) ? numberOr(raw.limit.context) : void 0;
|
|
67261
|
+
models.push({
|
|
67262
|
+
provider,
|
|
67263
|
+
id,
|
|
67264
|
+
name: stringOr(raw.name) ?? id,
|
|
67265
|
+
family: stringOr(raw.family) ?? familyOf(id),
|
|
67266
|
+
...releaseDate ? { releaseDate } : {},
|
|
67267
|
+
...contextTokens ? { contextTokens } : {},
|
|
67268
|
+
...effortValues ? { effort: effortValues } : {},
|
|
67269
|
+
fastMode: isRecord$5(modes) && modes.fast !== void 0
|
|
67270
|
+
});
|
|
67271
|
+
}
|
|
67272
|
+
}
|
|
67273
|
+
return models.length > 0 ? models : null;
|
|
67274
|
+
}
|
|
67275
|
+
/** Parse `https://openrouter.ai/api/v1/models`; null when it lists none of our providers. */
|
|
67276
|
+
function parseOpenRouter(json) {
|
|
67277
|
+
if (!isRecord$5(json) || !Array.isArray(json.data)) return null;
|
|
67278
|
+
const models = [];
|
|
67279
|
+
for (const raw of json.data) {
|
|
67280
|
+
if (!isRecord$5(raw)) continue;
|
|
67281
|
+
const fullId = stringOr(raw.id);
|
|
67282
|
+
if (!fullId || fullId.includes(":")) continue;
|
|
67283
|
+
const output = isRecord$5(raw.architecture) ? raw.architecture.output_modalities : void 0;
|
|
67284
|
+
const parameters = Array.isArray(raw.supported_parameters) ? raw.supported_parameters : [];
|
|
67285
|
+
if (!isTextOnly(output) || !parameters.includes("tools")) continue;
|
|
67286
|
+
const [prefix, rawId] = fullId.split("/", 2);
|
|
67287
|
+
const provider = EXTERNAL_PROVIDERS.find((candidate) => candidate === prefix);
|
|
67288
|
+
if (!provider || !rawId) continue;
|
|
67289
|
+
const id = provider === "anthropic" ? rawId.replace(/(\d)\.(\d)/g, "$1-$2") : rawId;
|
|
67290
|
+
const created = numberOr(raw.created);
|
|
67291
|
+
const contextTokens = numberOr(raw.context_length);
|
|
67292
|
+
models.push({
|
|
67293
|
+
provider,
|
|
67294
|
+
id,
|
|
67295
|
+
name: (stringOr(raw.name) ?? id).replace(/^[^:]+:\s*/, ""),
|
|
67296
|
+
family: familyOf(id),
|
|
67297
|
+
...created ? { releaseDate: (/* @__PURE__ */ new Date(created * 1e3)).toISOString() } : {},
|
|
67298
|
+
...contextTokens ? { contextTokens } : {}
|
|
67299
|
+
});
|
|
67300
|
+
}
|
|
67301
|
+
return models.length > 0 ? models : null;
|
|
67302
|
+
}
|
|
67303
|
+
/** Providers the list has no models for. */
|
|
67304
|
+
function missingProviders(models) {
|
|
67305
|
+
return EXTERNAL_PROVIDERS.filter((provider) => !models.some((model) => model.provider === provider));
|
|
67306
|
+
}
|
|
67307
|
+
/** Add `next` for the providers `models` lacks; ids already present win. */
|
|
67308
|
+
function fillMissingProviders(models, next) {
|
|
67309
|
+
const missing = new Set(missingProviders(models));
|
|
67310
|
+
return [...models, ...next.filter((model) => missing.has(model.provider))];
|
|
67311
|
+
}
|
|
67312
|
+
const DATED_SNAPSHOT = /-\d{8}$/;
|
|
67313
|
+
const releaseMs = (model) => {
|
|
67314
|
+
const parsed = model?.releaseDate ? Date.parse(model.releaseDate) : NaN;
|
|
67315
|
+
return Number.isNaN(parsed) ? 0 : parsed;
|
|
67316
|
+
};
|
|
67317
|
+
/** A family the bundle never listed is retired once its newest release trails the provider's by this much. */
|
|
67318
|
+
const CURRENT_FAMILY_WINDOW_MS = 4320 * 60 * 60 * 1e3;
|
|
67319
|
+
/**
|
|
67320
|
+
* Ids that are current: the newest release of each family, and `-latest`
|
|
67321
|
+
* pointers. Families the bundle lists keep their newest model current however
|
|
67322
|
+
* long the next release takes; other families and `-latest` pointers must be
|
|
67323
|
+
* recent enough to still be shipping.
|
|
67324
|
+
*/
|
|
67325
|
+
function currentIds(models, bundledFamilies) {
|
|
67326
|
+
const newest = /* @__PURE__ */ new Map();
|
|
67327
|
+
let providerNewest = 0;
|
|
67328
|
+
for (const model of models) {
|
|
67329
|
+
const released = releaseMs(model);
|
|
67330
|
+
newest.set(model.family, Math.max(newest.get(model.family) ?? 0, released));
|
|
67331
|
+
providerNewest = Math.max(providerNewest, released);
|
|
67332
|
+
}
|
|
67333
|
+
return new Set(models.filter((model) => {
|
|
67334
|
+
const released = releaseMs(model);
|
|
67335
|
+
const recent = providerNewest - released <= CURRENT_FAMILY_WINDOW_MS;
|
|
67336
|
+
if (model.id.endsWith("-latest")) return recent;
|
|
67337
|
+
return released === newest.get(model.family) && (recent || bundledFamilies.has(model.family));
|
|
67338
|
+
}).map((model) => model.id));
|
|
67339
|
+
}
|
|
67340
|
+
/** Effort values only Claude Code offers, with the API effort each one needs. */
|
|
67341
|
+
const CLAUDE_CODE_EFFORTS = {
|
|
67342
|
+
ultracode: "xhigh",
|
|
67343
|
+
ultrathink: null
|
|
67344
|
+
};
|
|
67345
|
+
/** Template profile narrowed to what the external entry says the model supports. */
|
|
67346
|
+
function deriveClaudeProfile(template, model) {
|
|
67347
|
+
const descriptors = (template?.capabilities?.optionDescriptors ?? []).flatMap((descriptor) => {
|
|
67348
|
+
if (descriptor.id === "fastMode" && model.fastMode === false) return [];
|
|
67349
|
+
if (descriptor.id !== "effort" || descriptor.type !== "select" || !model.effort) return [descriptor];
|
|
67350
|
+
const supported = new Set(model.effort);
|
|
67351
|
+
const options = descriptor.options.filter((option) => {
|
|
67352
|
+
const needs = CLAUDE_CODE_EFFORTS[option.id];
|
|
67353
|
+
return supported.has(option.id) || needs === null || needs !== void 0 && supported.has(needs);
|
|
67354
|
+
});
|
|
67355
|
+
return options.length > 0 ? [{
|
|
67356
|
+
...descriptor,
|
|
67357
|
+
options
|
|
67358
|
+
}] : [];
|
|
67359
|
+
});
|
|
67360
|
+
const adapter = isRecord$5(template?.adapter) ? template.adapter : {};
|
|
67361
|
+
const claudeCode = isRecord$5(adapter.claudeCode) ? adapter.claudeCode : {};
|
|
67362
|
+
const hasContextPicker = descriptors.some((descriptor) => descriptor.id === "contextWindow");
|
|
67363
|
+
return {
|
|
67364
|
+
capabilities: { optionDescriptors: descriptors },
|
|
67365
|
+
adapter: {
|
|
67366
|
+
...adapter,
|
|
67367
|
+
claudeCode: {
|
|
67368
|
+
...claudeCode,
|
|
67369
|
+
...!hasContextPicker && model.contextTokens ? { fixedContextWindowTokens: model.contextTokens } : {}
|
|
67370
|
+
}
|
|
67371
|
+
}
|
|
67372
|
+
};
|
|
67373
|
+
}
|
|
67374
|
+
/** `claude-opus-6-1` reads `opus-6.1` and `claude-opus-6.1`; `claude-opus-6` reads `opus-6`. */
|
|
67375
|
+
function shortAliases(slug) {
|
|
67376
|
+
const dotted = slug.replace(/-(\d+)-(\d+)$/, "-$1.$2");
|
|
67377
|
+
return [.../* @__PURE__ */ new Set([dotted.replace(/^claude-/, ""), dotted])].filter((alias) => alias !== slug);
|
|
67378
|
+
}
|
|
67379
|
+
function deriveClaudeCatalog(catalog, external) {
|
|
67380
|
+
const models = external.filter((model) => !DATED_SNAPSHOT.test(model.id));
|
|
67381
|
+
const current = currentIds(models, new Set(catalog.models.map((entry) => familyOf(entry.slug))));
|
|
67382
|
+
const byId = new Map(models.map((model) => [model.id, model]));
|
|
67383
|
+
const profiles = { ...catalog.profiles };
|
|
67384
|
+
const entries = catalog.models.map((entry) => {
|
|
67385
|
+
if (!byId.get(entry.slug)) return { ...entry };
|
|
67386
|
+
return {
|
|
67387
|
+
...entry,
|
|
67388
|
+
status: current.has(entry.slug) ? "current" : "legacy"
|
|
67389
|
+
};
|
|
67390
|
+
});
|
|
67391
|
+
const bundledSlugs = new Set(catalog.models.map((entry) => entry.slug));
|
|
67392
|
+
for (const model of models) {
|
|
67393
|
+
if (bundledSlugs.has(model.id) || !current.has(model.id)) continue;
|
|
67394
|
+
const template = catalog.models.filter((entry) => familyOf(entry.slug) === model.family).toSorted((left, right) => releaseMs(byId.get(right.slug)) - releaseMs(byId.get(left.slug))).at(0);
|
|
67395
|
+
const profileKey = `models.dev:${model.id}`;
|
|
67396
|
+
profiles[profileKey] = deriveClaudeProfile(template?.profile ? catalog.profiles[template.profile] : void 0, model);
|
|
67397
|
+
const aliases = shortAliases(model.id);
|
|
67398
|
+
entries.push({
|
|
67399
|
+
slug: model.id,
|
|
67400
|
+
name: model.name,
|
|
67401
|
+
...aliases.length > 0 ? { aliases } : {},
|
|
67402
|
+
status: "current",
|
|
67403
|
+
profile: profileKey,
|
|
67404
|
+
...template?.adapter !== void 0 ? { adapter: template.adapter } : {}
|
|
67405
|
+
});
|
|
67406
|
+
}
|
|
67407
|
+
for (const entry of entries) {
|
|
67408
|
+
const familyAlias = familyOf(entry.slug).replace(/^claude-/, "");
|
|
67409
|
+
if (entry.status === "current" || !entry.aliases?.includes(familyAlias)) continue;
|
|
67410
|
+
const successor = entries.find((candidate) => candidate.status === "current" && familyOf(candidate.slug) === familyOf(entry.slug));
|
|
67411
|
+
if (!successor) continue;
|
|
67412
|
+
entry.aliases = entry.aliases.filter((alias) => alias !== familyAlias);
|
|
67413
|
+
successor.aliases = [familyAlias, ...successor.aliases ?? []];
|
|
67414
|
+
}
|
|
67415
|
+
return {
|
|
67416
|
+
catalog: {
|
|
67417
|
+
...catalog,
|
|
67418
|
+
...withCurrentDefault(catalog, entries),
|
|
67419
|
+
profiles,
|
|
67420
|
+
models: entries
|
|
67421
|
+
},
|
|
67422
|
+
current: entries.filter((entry) => entry.status === "current").map((entry) => entry.slug)
|
|
67423
|
+
};
|
|
67424
|
+
}
|
|
67425
|
+
/** Keep the chat default; when it went legacy, move it to its family's current model. */
|
|
67426
|
+
function withCurrentDefault(catalog, entries, matches = (candidate, previous) => familyOf(candidate.slug) === familyOf(previous.slug)) {
|
|
67427
|
+
const chat = catalog.defaults?.chat;
|
|
67428
|
+
const previous = entries.find((entry) => entry.slug === chat);
|
|
67429
|
+
if (!previous || previous.status === "current") return { defaults: catalog.defaults };
|
|
67430
|
+
const next = entries.find((entry) => entry.status === "current" && matches(entry, previous));
|
|
67431
|
+
return { defaults: {
|
|
67432
|
+
...catalog.defaults,
|
|
67433
|
+
chat: next?.slug ?? chat
|
|
67434
|
+
} };
|
|
67435
|
+
}
|
|
67436
|
+
const ANTIGRAVITY_EFFORT_SUFFIX = /-(high|medium|low|minimal)$/;
|
|
67437
|
+
const effortLabel = (effort) => effort.charAt(0).toUpperCase() + effort.slice(1);
|
|
67438
|
+
/**
|
|
67439
|
+
* Antigravity slugs carry their effort (`gemini-3.8-flash-high`). Every current
|
|
67440
|
+
* Google model in a family the bundle already offers gets the same variants.
|
|
67441
|
+
*/
|
|
67442
|
+
function deriveAntigravityCatalog(catalog, external) {
|
|
67443
|
+
const byId = new Map(external.map((model) => [model.id, model]));
|
|
67444
|
+
const baseOf = (slug) => slug.replace(ANTIGRAVITY_EFFORT_SUFFIX, "");
|
|
67445
|
+
const suffixes = [...new Set(catalog.models.flatMap((entry) => entry.slug.match(ANTIGRAVITY_EFFORT_SUFFIX)?.[1] ?? []))];
|
|
67446
|
+
const families = new Set(catalog.models.flatMap((entry) => byId.get(baseOf(entry.slug))?.family ?? []));
|
|
67447
|
+
const current = currentIds(external, families);
|
|
67448
|
+
const entries = catalog.models.map((entry) => {
|
|
67449
|
+
const known = byId.get(baseOf(entry.slug));
|
|
67450
|
+
if (!known) return entry;
|
|
67451
|
+
return {
|
|
67452
|
+
...entry,
|
|
67453
|
+
status: current.has(known.id) ? "current" : "legacy"
|
|
67454
|
+
};
|
|
67455
|
+
});
|
|
67456
|
+
const slugs = new Set(entries.map((entry) => entry.slug));
|
|
67457
|
+
for (const model of external) {
|
|
67458
|
+
if (!families.has(model.family) || !current.has(model.id) || model.id.endsWith("-latest")) continue;
|
|
67459
|
+
for (const suffix of suffixes) {
|
|
67460
|
+
const slug = `${model.id}-${suffix}`;
|
|
67461
|
+
if (slugs.has(slug) || model.effort && !model.effort.includes(suffix)) continue;
|
|
67462
|
+
slugs.add(slug);
|
|
67463
|
+
entries.push({
|
|
67464
|
+
slug,
|
|
67465
|
+
name: `${model.name} (${effortLabel(suffix)})`,
|
|
67466
|
+
status: "current"
|
|
67467
|
+
});
|
|
67468
|
+
}
|
|
67469
|
+
}
|
|
67470
|
+
return {
|
|
67471
|
+
catalog: {
|
|
67472
|
+
...catalog,
|
|
67473
|
+
...withCurrentDefault(catalog, entries, (candidate, previous) => candidate.slug.match(ANTIGRAVITY_EFFORT_SUFFIX)?.[1] === previous.slug.match(ANTIGRAVITY_EFFORT_SUFFIX)?.[1]),
|
|
67474
|
+
models: entries
|
|
67475
|
+
},
|
|
67476
|
+
current: entries.filter((entry) => entry.status === "current").map((entry) => entry.slug)
|
|
67477
|
+
};
|
|
67478
|
+
}
|
|
67479
|
+
/** Codex discovers its own models; the manifest only says which are current. */
|
|
67480
|
+
function deriveCodexCurrent(bundledCurrent, external) {
|
|
67481
|
+
const byId = new Map(external.map((model) => [model.id, model]));
|
|
67482
|
+
const current = currentIds(external, new Set(bundledCurrent.map((slug) => byId.get(slug)?.family ?? familyOf(slug))));
|
|
67483
|
+
const known = new Set(byId.keys());
|
|
67484
|
+
return [.../* @__PURE__ */ new Set([...current, ...bundledCurrent.filter((slug) => !known.has(slug))])];
|
|
67485
|
+
}
|
|
67486
|
+
/** Fold the external model list over the bundled manifest. */
|
|
67487
|
+
function deriveModelManifest(bundled, external) {
|
|
67488
|
+
const forProvider = (provider) => external.filter((model) => model.provider === provider);
|
|
67489
|
+
const providers = { ...bundled.providers };
|
|
67490
|
+
const currentModels = { ...bundled.currentModels };
|
|
67491
|
+
const claude = bundled.providers?.claudeAgent;
|
|
67492
|
+
if (claude) {
|
|
67493
|
+
const derived = deriveClaudeCatalog(claude, forProvider("anthropic"));
|
|
67494
|
+
providers.claudeAgent = derived.catalog;
|
|
67495
|
+
currentModels.claudeAgent = derived.current;
|
|
67496
|
+
}
|
|
67497
|
+
const antigravity = bundled.providers?.antigravity;
|
|
67498
|
+
if (antigravity) {
|
|
67499
|
+
const derived = deriveAntigravityCatalog(antigravity, forProvider("google"));
|
|
67500
|
+
providers.antigravity = derived.catalog;
|
|
67501
|
+
currentModels.antigravity = derived.current;
|
|
67502
|
+
}
|
|
67503
|
+
currentModels.codex = deriveCodexCurrent(bundled.currentModels.codex ?? [], forProvider("openai"));
|
|
67504
|
+
return {
|
|
67505
|
+
...bundled,
|
|
67506
|
+
currentModels,
|
|
67507
|
+
providers
|
|
67508
|
+
};
|
|
67509
|
+
}
|
|
67510
|
+
//#endregion
|
|
67086
67511
|
//#region src/provider/model-manifest.json
|
|
67087
67512
|
var model_manifest_default = {
|
|
67088
67513
|
version: 1,
|
|
67089
|
-
updatedAt: "2026-
|
|
67514
|
+
updatedAt: "2026-10-07T19:00:00Z",
|
|
67090
67515
|
currentModels: {
|
|
67091
67516
|
"codex": [
|
|
67092
67517
|
"gpt-6-astra",
|
|
67093
|
-
"gpt-
|
|
67094
|
-
"gpt-
|
|
67095
|
-
"gpt-5.6-sol",
|
|
67518
|
+
"gpt-6.1-sol",
|
|
67519
|
+
"gpt-6-luna",
|
|
67096
67520
|
"gpt-daybreak-blue-latest",
|
|
67097
67521
|
"gpt-daybreak-red-latest"
|
|
67098
67522
|
],
|
|
67099
67523
|
"claudeAgent": [
|
|
67100
67524
|
"claude-fable-5-1",
|
|
67101
|
-
"claude-opus-5",
|
|
67525
|
+
"claude-opus-5-5",
|
|
67102
67526
|
"claude-sonnet-5-5",
|
|
67103
|
-
"claude-
|
|
67527
|
+
"claude-haiku-5-5"
|
|
67104
67528
|
],
|
|
67105
67529
|
"antigravity": [
|
|
67106
67530
|
"gemini-3.8-flash-high",
|
|
@@ -67110,7 +67534,7 @@ var model_manifest_default = {
|
|
|
67110
67534
|
},
|
|
67111
67535
|
providers: {
|
|
67112
67536
|
"claudeAgent": {
|
|
67113
|
-
"defaults": { "chat": "claude-
|
|
67537
|
+
"defaults": { "chat": "claude-fable-5-1" },
|
|
67114
67538
|
"profiles": {
|
|
67115
67539
|
"fable-5": {
|
|
67116
67540
|
"capabilities": { "optionDescriptors": [{
|
|
@@ -67124,13 +67548,60 @@ var model_manifest_default = {
|
|
|
67124
67548
|
},
|
|
67125
67549
|
{
|
|
67126
67550
|
"id": "medium",
|
|
67127
|
-
"label": "Medium"
|
|
67551
|
+
"label": "Medium",
|
|
67552
|
+
"isDefault": true
|
|
67128
67553
|
},
|
|
67129
67554
|
{
|
|
67130
67555
|
"id": "high",
|
|
67131
|
-
"label": "High"
|
|
67556
|
+
"label": "High"
|
|
67557
|
+
},
|
|
67558
|
+
{
|
|
67559
|
+
"id": "xhigh",
|
|
67560
|
+
"label": "Extra High"
|
|
67561
|
+
},
|
|
67562
|
+
{
|
|
67563
|
+
"id": "max",
|
|
67564
|
+
"label": "Max"
|
|
67565
|
+
},
|
|
67566
|
+
{
|
|
67567
|
+
"id": "ultracode",
|
|
67568
|
+
"label": "Ultracode",
|
|
67569
|
+
"description": "xhigh effort plus multi-agent workflow orchestration"
|
|
67570
|
+
},
|
|
67571
|
+
{
|
|
67572
|
+
"id": "ultrathink",
|
|
67573
|
+
"label": "Ultrathink"
|
|
67574
|
+
}
|
|
67575
|
+
],
|
|
67576
|
+
"promptInjectedValues": ["ultrathink"]
|
|
67577
|
+
}] },
|
|
67578
|
+
"adapter": { "claudeCode": {
|
|
67579
|
+
"effortMap": {
|
|
67580
|
+
"ultracode": "xhigh",
|
|
67581
|
+
"ultrathink": null
|
|
67582
|
+
},
|
|
67583
|
+
"fixedContextWindowTokens": 1e6
|
|
67584
|
+
} }
|
|
67585
|
+
},
|
|
67586
|
+
"opus-5-5": {
|
|
67587
|
+
"capabilities": { "optionDescriptors": [{
|
|
67588
|
+
"id": "effort",
|
|
67589
|
+
"label": "Reasoning",
|
|
67590
|
+
"type": "select",
|
|
67591
|
+
"options": [
|
|
67592
|
+
{
|
|
67593
|
+
"id": "low",
|
|
67594
|
+
"label": "Low"
|
|
67595
|
+
},
|
|
67596
|
+
{
|
|
67597
|
+
"id": "medium",
|
|
67598
|
+
"label": "Medium",
|
|
67132
67599
|
"isDefault": true
|
|
67133
67600
|
},
|
|
67601
|
+
{
|
|
67602
|
+
"id": "high",
|
|
67603
|
+
"label": "High"
|
|
67604
|
+
},
|
|
67134
67605
|
{
|
|
67135
67606
|
"id": "xhigh",
|
|
67136
67607
|
"label": "Extra High"
|
|
@@ -67151,99 +67622,67 @@ var model_manifest_default = {
|
|
|
67151
67622
|
],
|
|
67152
67623
|
"promptInjectedValues": ["ultrathink"]
|
|
67153
67624
|
}, {
|
|
67154
|
-
"id": "
|
|
67155
|
-
"label": "
|
|
67156
|
-
"type": "
|
|
67157
|
-
"options": [{
|
|
67158
|
-
"id": "200k",
|
|
67159
|
-
"label": "200k"
|
|
67160
|
-
}, {
|
|
67161
|
-
"id": "1m",
|
|
67162
|
-
"label": "1M",
|
|
67163
|
-
"isDefault": true
|
|
67164
|
-
}]
|
|
67625
|
+
"id": "fastMode",
|
|
67626
|
+
"label": "Fast Mode",
|
|
67627
|
+
"type": "boolean"
|
|
67165
67628
|
}] },
|
|
67166
67629
|
"adapter": { "claudeCode": {
|
|
67167
67630
|
"effortMap": {
|
|
67168
67631
|
"ultracode": "xhigh",
|
|
67169
67632
|
"ultrathink": null
|
|
67170
67633
|
},
|
|
67171
|
-
"
|
|
67172
|
-
"contextWindowTokens": {
|
|
67173
|
-
"200k": 2e5,
|
|
67174
|
-
"1m": 1e6
|
|
67175
|
-
}
|
|
67634
|
+
"fixedContextWindowTokens": 1e6
|
|
67176
67635
|
} }
|
|
67177
67636
|
},
|
|
67178
67637
|
"opus-5": {
|
|
67179
|
-
"capabilities": { "optionDescriptors": [
|
|
67180
|
-
|
|
67181
|
-
|
|
67182
|
-
|
|
67183
|
-
|
|
67184
|
-
|
|
67185
|
-
|
|
67186
|
-
|
|
67187
|
-
|
|
67188
|
-
|
|
67189
|
-
|
|
67190
|
-
|
|
67191
|
-
|
|
67192
|
-
|
|
67193
|
-
|
|
67194
|
-
|
|
67195
|
-
"label": "High",
|
|
67196
|
-
"isDefault": true
|
|
67197
|
-
},
|
|
67198
|
-
{
|
|
67199
|
-
"id": "xhigh",
|
|
67200
|
-
"label": "Extra High"
|
|
67201
|
-
},
|
|
67202
|
-
{
|
|
67203
|
-
"id": "max",
|
|
67204
|
-
"label": "Max"
|
|
67205
|
-
},
|
|
67206
|
-
{
|
|
67207
|
-
"id": "ultracode",
|
|
67208
|
-
"label": "Ultracode",
|
|
67209
|
-
"description": "xhigh effort plus multi-agent workflow orchestration"
|
|
67210
|
-
},
|
|
67211
|
-
{
|
|
67212
|
-
"id": "ultrathink",
|
|
67213
|
-
"label": "Ultrathink"
|
|
67214
|
-
}
|
|
67215
|
-
],
|
|
67216
|
-
"promptInjectedValues": ["ultrathink"]
|
|
67217
|
-
},
|
|
67218
|
-
{
|
|
67219
|
-
"id": "fastMode",
|
|
67220
|
-
"label": "Fast Mode",
|
|
67221
|
-
"type": "boolean"
|
|
67222
|
-
},
|
|
67223
|
-
{
|
|
67224
|
-
"id": "contextWindow",
|
|
67225
|
-
"label": "Context Window",
|
|
67226
|
-
"type": "select",
|
|
67227
|
-
"options": [{
|
|
67228
|
-
"id": "200k",
|
|
67229
|
-
"label": "200k"
|
|
67230
|
-
}, {
|
|
67231
|
-
"id": "1m",
|
|
67232
|
-
"label": "1M",
|
|
67638
|
+
"capabilities": { "optionDescriptors": [{
|
|
67639
|
+
"id": "effort",
|
|
67640
|
+
"label": "Reasoning",
|
|
67641
|
+
"type": "select",
|
|
67642
|
+
"options": [
|
|
67643
|
+
{
|
|
67644
|
+
"id": "low",
|
|
67645
|
+
"label": "Low"
|
|
67646
|
+
},
|
|
67647
|
+
{
|
|
67648
|
+
"id": "medium",
|
|
67649
|
+
"label": "Medium"
|
|
67650
|
+
},
|
|
67651
|
+
{
|
|
67652
|
+
"id": "high",
|
|
67653
|
+
"label": "High",
|
|
67233
67654
|
"isDefault": true
|
|
67234
|
-
}
|
|
67235
|
-
|
|
67236
|
-
|
|
67655
|
+
},
|
|
67656
|
+
{
|
|
67657
|
+
"id": "xhigh",
|
|
67658
|
+
"label": "Extra High"
|
|
67659
|
+
},
|
|
67660
|
+
{
|
|
67661
|
+
"id": "max",
|
|
67662
|
+
"label": "Max"
|
|
67663
|
+
},
|
|
67664
|
+
{
|
|
67665
|
+
"id": "ultracode",
|
|
67666
|
+
"label": "Ultracode",
|
|
67667
|
+
"description": "xhigh effort plus multi-agent workflow orchestration"
|
|
67668
|
+
},
|
|
67669
|
+
{
|
|
67670
|
+
"id": "ultrathink",
|
|
67671
|
+
"label": "Ultrathink"
|
|
67672
|
+
}
|
|
67673
|
+
],
|
|
67674
|
+
"promptInjectedValues": ["ultrathink"]
|
|
67675
|
+
}, {
|
|
67676
|
+
"id": "fastMode",
|
|
67677
|
+
"label": "Fast Mode",
|
|
67678
|
+
"type": "boolean"
|
|
67679
|
+
}] },
|
|
67237
67680
|
"adapter": { "claudeCode": {
|
|
67238
67681
|
"effortMap": {
|
|
67239
67682
|
"ultracode": "xhigh",
|
|
67240
67683
|
"ultrathink": null
|
|
67241
67684
|
},
|
|
67242
|
-
"
|
|
67243
|
-
"contextWindowTokens": {
|
|
67244
|
-
"200k": 2e5,
|
|
67245
|
-
"1m": 1e6
|
|
67246
|
-
}
|
|
67685
|
+
"fixedContextWindowTokens": 1e6
|
|
67247
67686
|
} }
|
|
67248
67687
|
},
|
|
67249
67688
|
"opus-4-8": {
|
|
@@ -67431,7 +67870,7 @@ var model_manifest_default = {
|
|
|
67431
67870
|
"label": "Fast Mode",
|
|
67432
67871
|
"type": "boolean"
|
|
67433
67872
|
}] },
|
|
67434
|
-
"adapter": { "claudeCode": {} }
|
|
67873
|
+
"adapter": { "claudeCode": { "fixedContextWindowTokens": 2e5 } }
|
|
67435
67874
|
},
|
|
67436
67875
|
"sonnet-5": {
|
|
67437
67876
|
"capabilities": { "optionDescriptors": [{
|
|
@@ -67466,26 +67905,10 @@ var model_manifest_default = {
|
|
|
67466
67905
|
}
|
|
67467
67906
|
],
|
|
67468
67907
|
"promptInjectedValues": ["ultrathink"]
|
|
67469
|
-
}, {
|
|
67470
|
-
"id": "contextWindow",
|
|
67471
|
-
"label": "Context Window",
|
|
67472
|
-
"type": "select",
|
|
67473
|
-
"options": [{
|
|
67474
|
-
"id": "200k",
|
|
67475
|
-
"label": "200k",
|
|
67476
|
-
"isDefault": true
|
|
67477
|
-
}, {
|
|
67478
|
-
"id": "1m",
|
|
67479
|
-
"label": "1M"
|
|
67480
|
-
}]
|
|
67481
67908
|
}] },
|
|
67482
67909
|
"adapter": { "claudeCode": {
|
|
67483
67910
|
"effortMap": { "ultrathink": null },
|
|
67484
|
-
"
|
|
67485
|
-
"contextWindowTokens": {
|
|
67486
|
-
"200k": 2e5,
|
|
67487
|
-
"1m": 1e6
|
|
67488
|
-
}
|
|
67911
|
+
"fixedContextWindowTokens": 1e6
|
|
67489
67912
|
} }
|
|
67490
67913
|
},
|
|
67491
67914
|
"sonnet-4-6": {
|
|
@@ -67542,16 +67965,81 @@ var model_manifest_default = {
|
|
|
67542
67965
|
}
|
|
67543
67966
|
} }
|
|
67544
67967
|
},
|
|
67968
|
+
"haiku-5-5": {
|
|
67969
|
+
"capabilities": { "optionDescriptors": [{
|
|
67970
|
+
"id": "effort",
|
|
67971
|
+
"label": "Reasoning",
|
|
67972
|
+
"type": "select",
|
|
67973
|
+
"options": [
|
|
67974
|
+
{
|
|
67975
|
+
"id": "low",
|
|
67976
|
+
"label": "Low"
|
|
67977
|
+
},
|
|
67978
|
+
{
|
|
67979
|
+
"id": "medium",
|
|
67980
|
+
"label": "Medium",
|
|
67981
|
+
"isDefault": true
|
|
67982
|
+
},
|
|
67983
|
+
{
|
|
67984
|
+
"id": "high",
|
|
67985
|
+
"label": "High"
|
|
67986
|
+
},
|
|
67987
|
+
{
|
|
67988
|
+
"id": "xhigh",
|
|
67989
|
+
"label": "Extra High"
|
|
67990
|
+
},
|
|
67991
|
+
{
|
|
67992
|
+
"id": "max",
|
|
67993
|
+
"label": "Max"
|
|
67994
|
+
},
|
|
67995
|
+
{
|
|
67996
|
+
"id": "ultrathink",
|
|
67997
|
+
"label": "Ultrathink"
|
|
67998
|
+
}
|
|
67999
|
+
],
|
|
68000
|
+
"promptInjectedValues": ["ultrathink"]
|
|
68001
|
+
}] },
|
|
68002
|
+
"adapter": { "claudeCode": {
|
|
68003
|
+
"effortMap": { "ultrathink": null },
|
|
68004
|
+
"fixedContextWindowTokens": 1e6
|
|
68005
|
+
} }
|
|
68006
|
+
},
|
|
67545
68007
|
"haiku-4-5": {
|
|
67546
68008
|
"capabilities": { "optionDescriptors": [{
|
|
67547
68009
|
"id": "thinking",
|
|
67548
68010
|
"label": "Thinking",
|
|
67549
68011
|
"type": "boolean"
|
|
67550
68012
|
}] },
|
|
67551
|
-
"adapter": { "claudeCode": {} }
|
|
68013
|
+
"adapter": { "claudeCode": { "fixedContextWindowTokens": 2e5 } }
|
|
67552
68014
|
}
|
|
67553
68015
|
},
|
|
67554
68016
|
"models": [
|
|
68017
|
+
{
|
|
68018
|
+
"slug": "claude-opus-5-5",
|
|
68019
|
+
"name": "Claude Opus 5.5",
|
|
68020
|
+
"aliases": [
|
|
68021
|
+
"opus",
|
|
68022
|
+
"opus-5.5",
|
|
68023
|
+
"claude-opus-5.5"
|
|
68024
|
+
],
|
|
68025
|
+
"status": "current",
|
|
68026
|
+
"badge": "new",
|
|
68027
|
+
"profile": "opus-5-5",
|
|
68028
|
+
"adapter": { "claudeCode": { "minVersion": "2.1.280" } }
|
|
68029
|
+
},
|
|
68030
|
+
{
|
|
68031
|
+
"slug": "claude-sonnet-5-5",
|
|
68032
|
+
"name": "Claude Sonnet 5.5",
|
|
68033
|
+
"aliases": [
|
|
68034
|
+
"sonnet",
|
|
68035
|
+
"sonnet-5.5",
|
|
68036
|
+
"claude-sonnet-5.5"
|
|
68037
|
+
],
|
|
68038
|
+
"status": "current",
|
|
68039
|
+
"badge": "new",
|
|
68040
|
+
"profile": "sonnet-5",
|
|
68041
|
+
"adapter": { "claudeCode": { "minVersion": "2.1.284" } }
|
|
68042
|
+
},
|
|
67555
68043
|
{
|
|
67556
68044
|
"slug": "claude-fable-5-1",
|
|
67557
68045
|
"name": "Claude Fable 5.1",
|
|
@@ -67561,7 +68049,6 @@ var model_manifest_default = {
|
|
|
67561
68049
|
"claude-fable-5.1"
|
|
67562
68050
|
],
|
|
67563
68051
|
"status": "current",
|
|
67564
|
-
"badge": "new",
|
|
67565
68052
|
"profile": "fable-5",
|
|
67566
68053
|
"adapter": { "claudeCode": { "minVersion": "2.1.257" } }
|
|
67567
68054
|
},
|
|
@@ -67576,12 +68063,11 @@ var model_manifest_default = {
|
|
|
67576
68063
|
"slug": "claude-opus-5",
|
|
67577
68064
|
"name": "Claude Opus 5",
|
|
67578
68065
|
"aliases": [
|
|
67579
|
-
"opus",
|
|
67580
68066
|
"opus-5",
|
|
67581
68067
|
"claude-opus-5.0",
|
|
67582
68068
|
"claude-opus-5-0"
|
|
67583
68069
|
],
|
|
67584
|
-
"status": "
|
|
68070
|
+
"status": "legacy",
|
|
67585
68071
|
"profile": "opus-5",
|
|
67586
68072
|
"adapter": { "claudeCode": { "minVersion": "2.1.219" } }
|
|
67587
68073
|
},
|
|
@@ -67618,25 +68104,15 @@ var model_manifest_default = {
|
|
|
67618
68104
|
"status": "legacy",
|
|
67619
68105
|
"profile": "opus-4-5"
|
|
67620
68106
|
},
|
|
67621
|
-
{
|
|
67622
|
-
"slug": "claude-sonnet-5-5",
|
|
67623
|
-
"name": "Claude Sonnet 5.5",
|
|
67624
|
-
"aliases": ["sonnet-5.5", "claude-sonnet-5.5"],
|
|
67625
|
-
"status": "current",
|
|
67626
|
-
"badge": "new",
|
|
67627
|
-
"profile": "sonnet-5",
|
|
67628
|
-
"adapter": { "claudeCode": { "minVersion": "2.1.284" } }
|
|
67629
|
-
},
|
|
67630
68107
|
{
|
|
67631
68108
|
"slug": "claude-sonnet-5",
|
|
67632
68109
|
"name": "Claude Sonnet 5",
|
|
67633
68110
|
"aliases": [
|
|
67634
|
-
"sonnet",
|
|
67635
68111
|
"sonnet-5",
|
|
67636
68112
|
"claude-sonnet-5.0",
|
|
67637
68113
|
"claude-sonnet-5-0"
|
|
67638
68114
|
],
|
|
67639
|
-
"status": "
|
|
68115
|
+
"status": "legacy",
|
|
67640
68116
|
"profile": "sonnet-5"
|
|
67641
68117
|
},
|
|
67642
68118
|
{
|
|
@@ -67650,11 +68126,23 @@ var model_manifest_default = {
|
|
|
67650
68126
|
"status": "legacy",
|
|
67651
68127
|
"profile": "sonnet-4-6"
|
|
67652
68128
|
},
|
|
68129
|
+
{
|
|
68130
|
+
"slug": "claude-haiku-5-5",
|
|
68131
|
+
"name": "Claude Haiku 5.5",
|
|
68132
|
+
"aliases": [
|
|
68133
|
+
"haiku",
|
|
68134
|
+
"haiku-5.5",
|
|
68135
|
+
"claude-haiku-5.5"
|
|
68136
|
+
],
|
|
68137
|
+
"status": "current",
|
|
68138
|
+
"badge": "new",
|
|
68139
|
+
"profile": "haiku-5-5",
|
|
68140
|
+
"adapter": { "claudeCode": { "minVersion": "2.1.293" } }
|
|
68141
|
+
},
|
|
67653
68142
|
{
|
|
67654
68143
|
"slug": "claude-haiku-4-5",
|
|
67655
68144
|
"name": "Claude Haiku 4.5",
|
|
67656
68145
|
"aliases": [
|
|
67657
|
-
"haiku",
|
|
67658
68146
|
"haiku-4.5",
|
|
67659
68147
|
"claude-haiku-4.5",
|
|
67660
68148
|
"claude-haiku-4-5-20251001"
|
|
@@ -67690,27 +68178,27 @@ var model_manifest_default = {
|
|
|
67690
68178
|
//#endregion
|
|
67691
68179
|
//#region src/provider/ModelManifest.ts
|
|
67692
68180
|
/**
|
|
67693
|
-
* ModelManifest —
|
|
67694
|
-
* fallback.
|
|
68181
|
+
* ModelManifest — provider-model metadata: the bundled manifest folded with
|
|
68182
|
+
* the external model list from models.dev (OpenRouter as fallback).
|
|
67695
68183
|
*
|
|
67696
|
-
* Provider catalogs and legacy classification live in `model-manifest.json
|
|
67697
|
-
*
|
|
67698
|
-
*
|
|
67699
|
-
*
|
|
67700
|
-
* provider check.
|
|
68184
|
+
* Provider catalogs and legacy classification live in `model-manifest.json`,
|
|
68185
|
+
* which ships with every release. At runtime the service fetches the external
|
|
68186
|
+
* list and derives the manifest from both (`externalModelCatalog.ts`).
|
|
68187
|
+
* Preference order is a fresh fetch, then the last successful list on disk,
|
|
68188
|
+
* then the bundle alone. A failed fetch never fails a provider check.
|
|
67701
68189
|
*
|
|
67702
68190
|
* Providers with authoritative discovery can use only the classification
|
|
67703
68191
|
* overlay. Providers with static catalogs can resolve presentation and
|
|
67704
68192
|
* capabilities from `providers`, then decode their own allowlisted adapter
|
|
67705
68193
|
* payload separately.
|
|
67706
68194
|
*/
|
|
67707
|
-
const MODEL_MANIFEST_URL = "https://raw.githubusercontent.com/pingdotgg/t3code/main/apps/server/src/provider/model-manifest.json";
|
|
67708
68195
|
/** How long a fetched manifest stays fresh before the next probe re-fetches. */
|
|
67709
68196
|
const MANIFEST_TTL_MS = 3600 * 1e3;
|
|
67710
68197
|
/** Minimum gap between fetch attempts after a failure, so an offline server
|
|
67711
68198
|
* does not pay a network timeout on every provider check. */
|
|
67712
68199
|
const MANIFEST_RETRY_MS = 300 * 1e3;
|
|
67713
|
-
|
|
68200
|
+
/** models.dev serves about 0.5 MB compressed, so allow more than a small JSON. */
|
|
68201
|
+
const FETCH_TIMEOUT_MS = 2e4;
|
|
67714
68202
|
const ManifestModelStatus = Schema$1.Literals(["current", "legacy"]);
|
|
67715
68203
|
const ManifestModelProfile = Schema$1.Struct({
|
|
67716
68204
|
capabilities: Schema$1.optional(ModelCapabilities),
|
|
@@ -67738,11 +68226,7 @@ const ManifestProviderCatalog = Schema$1.Struct({
|
|
|
67738
68226
|
*/
|
|
67739
68227
|
const ModelManifestEnvelopeSchema = Schema$1.Struct({
|
|
67740
68228
|
version: Schema$1.Literal(1),
|
|
67741
|
-
/**
|
|
67742
|
-
* ISO date of the last edit. A release bundles its manifest, and a disk
|
|
67743
|
-
* cache of an older edit must not outrank it. Optional so older remote
|
|
67744
|
-
* files still decode; they count as older than any dated bundle.
|
|
67745
|
-
*/
|
|
68229
|
+
/** ISO date of the last edit. */
|
|
67746
68230
|
updatedAt: Schema$1.optional(Schema$1.String),
|
|
67747
68231
|
currentModels: Schema$1.Record(Schema$1.String, Schema$1.Array(Schema$1.String)),
|
|
67748
68232
|
providers: Schema$1.optional(Schema$1.Record(Schema$1.String, ManifestProviderCatalog))
|
|
@@ -67756,13 +68240,22 @@ const hasValidProviderCatalogReferences = (manifest) => Object.values(manifest.p
|
|
|
67756
68240
|
}) && (catalog.defaults?.chat === void 0 || slugs.has(catalog.defaults.chat));
|
|
67757
68241
|
});
|
|
67758
68242
|
const ModelManifestSchema = ModelManifestEnvelopeSchema.pipe(Schema$1.check(Schema$1.makeFilter(hasValidProviderCatalogReferences, { expected: "unique model slugs and existing model and profile references" }), Schema$1.makeFilter(hasValidClaudeManifestAdapters, { expected: "valid Claude adapter metadata" })));
|
|
67759
|
-
const
|
|
68243
|
+
const decodeManifestOption = Schema$1.decodeUnknownOption(ModelManifestSchema);
|
|
68244
|
+
/** Public sources after the user's CPA, in order. */
|
|
68245
|
+
const PUBLIC_SOURCES = [{
|
|
68246
|
+
url: MODELS_DEV_URL,
|
|
68247
|
+
parse: parseModelsDev
|
|
68248
|
+
}, {
|
|
68249
|
+
url: OPENROUTER_MODELS_URL,
|
|
68250
|
+
parse: parseOpenRouter
|
|
68251
|
+
}];
|
|
67760
68252
|
const BUNDLED_MODEL_MANIFEST = Schema$1.decodeUnknownSync(ModelManifestSchema)(model_manifest_default);
|
|
67761
|
-
/**
|
|
67762
|
-
|
|
67763
|
-
|
|
67764
|
-
|
|
67765
|
-
|
|
68253
|
+
/**
|
|
68254
|
+
* The bundle folded with an external list. A derived manifest that fails the
|
|
68255
|
+
* catalog checks is dropped in favour of the bundle alone.
|
|
68256
|
+
*/
|
|
68257
|
+
function manifestFromExternalModels(external) {
|
|
68258
|
+
return Option.getOrNull(decodeManifestOption(deriveModelManifest(BUNDLED_MODEL_MANIFEST, external)));
|
|
67766
68259
|
}
|
|
67767
68260
|
/** Resolve provider-neutral model presentation and capability data. */
|
|
67768
68261
|
function resolveProviderCatalog(manifest, driverKind) {
|
|
@@ -67798,13 +68291,12 @@ function resolveProviderCatalog(manifest, driverKind) {
|
|
|
67798
68291
|
defaults: { chat: catalog.defaults?.chat }
|
|
67799
68292
|
};
|
|
67800
68293
|
}
|
|
67801
|
-
/** On-disk shape of the last successfully fetched
|
|
68294
|
+
/** On-disk shape of the last successfully fetched external model list. */
|
|
67802
68295
|
const ManifestCacheFile = Schema$1.Struct({
|
|
67803
68296
|
fetchedAtMs: Schema$1.Number,
|
|
67804
|
-
|
|
68297
|
+
models: Schema$1.Array(ExternalModel)
|
|
67805
68298
|
});
|
|
67806
68299
|
const decodeManifestCache = Schema$1.decodeUnknownEffect(Schema$1.fromJsonString(ManifestCacheFile));
|
|
67807
|
-
/** Exported for tests that seed the disk cache. */
|
|
67808
68300
|
const encodeManifestCache = Schema$1.encodeEffect(Schema$1.fromJsonString(ManifestCacheFile));
|
|
67809
68301
|
/** True when the manifest classifies `slug` as legacy for `driverKind`. */
|
|
67810
68302
|
function isLegacyModel(manifest, driverKind, slug) {
|
|
@@ -67885,7 +68377,7 @@ const make$76 = Effect.gen(function* () {
|
|
|
67885
68377
|
const settingsService = yield* ServerSettingsService;
|
|
67886
68378
|
const httpClient = yield* HttpClient.HttpClient;
|
|
67887
68379
|
const serviceScope = yield* Effect.scope;
|
|
67888
|
-
const cachePath = path.join(config.stateDir, "
|
|
68380
|
+
const cachePath = path.join(config.stateDir, "external-models.json");
|
|
67889
68381
|
let manifest = BUNDLED_MODEL_MANIFEST;
|
|
67890
68382
|
let fetchedAtMs = null;
|
|
67891
68383
|
let lastAttemptMs = null;
|
|
@@ -67893,10 +68385,26 @@ const make$76 = Effect.gen(function* () {
|
|
|
67893
68385
|
const ensureDiskCacheLoaded = yield* Effect.cached(Effect.gen(function* () {
|
|
67894
68386
|
const fromDisk = yield* fileSystem.readFileString(cachePath).pipe(Effect.flatMap((raw) => decodeManifestCache(raw)), Effect.catchCause(() => Effect.succeed(null)));
|
|
67895
68387
|
if (fromDisk === null) return;
|
|
67896
|
-
|
|
67897
|
-
|
|
68388
|
+
const derived = manifestFromExternalModels(fromDisk.models);
|
|
68389
|
+
if (derived === null) return;
|
|
68390
|
+
manifest = derived;
|
|
67898
68391
|
fetchedAtMs = fromDisk.fetchedAtMs;
|
|
67899
68392
|
}));
|
|
68393
|
+
const fetchPublic = (source) => httpClient.get(source.url).pipe(Effect.flatMap(HttpClientResponse.filterStatusOk), Effect.flatMap((response) => response.json), Effect.map((json) => source.parse(json) ?? []), Effect.timeout(FETCH_TIMEOUT_MS), Effect.catchCause(() => Effect.succeed([])));
|
|
68394
|
+
/** Static model definitions from the first enabled CPA usage source; credentials do not matter. */
|
|
68395
|
+
const fetchCpa = (sources) => {
|
|
68396
|
+
const source = Object.values(sources).find((candidate) => candidate.enabled && candidate.managementKey !== "");
|
|
68397
|
+
if (!source) return Effect.succeed([]);
|
|
68398
|
+
return Effect.forEach(CPA_CHANNELS, ({ provider, channel }) => Effect.tryPromise((signal) => readManagementJson(source, `model-definitions/${channel}`, void 0, signal)).pipe(Effect.map((json) => parseCpaModelDefinitions(json, provider)), Effect.timeout(FETCH_TIMEOUT_MS), Effect.catchCause(() => Effect.succeed([]))), { concurrency: "unbounded" }).pipe(Effect.map((lists) => {
|
|
68399
|
+
const seen = /* @__PURE__ */ new Set();
|
|
68400
|
+
return lists.flat().filter((model) => {
|
|
68401
|
+
const key = `${model.provider}:${model.id}`;
|
|
68402
|
+
if (seen.has(key)) return false;
|
|
68403
|
+
seen.add(key);
|
|
68404
|
+
return true;
|
|
68405
|
+
});
|
|
68406
|
+
}));
|
|
68407
|
+
};
|
|
67900
68408
|
const refresh = Effect.fn("ModelManifest.refresh")(function* () {
|
|
67901
68409
|
yield* ensureDiskCacheLoaded;
|
|
67902
68410
|
const now = yield* Clock.currentTimeMillis;
|
|
@@ -67906,13 +68414,18 @@ const make$76 = Effect.gen(function* () {
|
|
|
67906
68414
|
const settings = yield* settingsService.getSettings.pipe(Effect.catchCause(() => Effect.succeed(null)));
|
|
67907
68415
|
if (settings !== null && !settings.enableProviderUpdateChecks) return manifest;
|
|
67908
68416
|
lastAttemptMs = now;
|
|
67909
|
-
|
|
68417
|
+
let models = settings === null ? [] : yield* fetchCpa(settings.usageLimitSources);
|
|
68418
|
+
for (const source of PUBLIC_SOURCES) {
|
|
68419
|
+
if (missingProviders(models).length === 0) break;
|
|
68420
|
+
models = fillMissingProviders(models, yield* fetchPublic(source));
|
|
68421
|
+
}
|
|
68422
|
+
const fetched = models.length === 0 ? null : manifestFromExternalModels(models);
|
|
67910
68423
|
if (fetched === null) return manifest;
|
|
67911
68424
|
manifest = fetched;
|
|
67912
68425
|
fetchedAtMs = now;
|
|
67913
68426
|
yield* encodeManifestCache({
|
|
67914
68427
|
fetchedAtMs: now,
|
|
67915
|
-
|
|
68428
|
+
models
|
|
67916
68429
|
}).pipe(Effect.flatMap((serialized) => fileSystem.writeFileString(cachePath, serialized)), Effect.catchCause(() => Effect.void));
|
|
67917
68430
|
return manifest;
|
|
67918
68431
|
});
|
|
@@ -69891,7 +70404,7 @@ const makeClaudeTextGeneration = Effect.fn("makeClaudeTextGeneration")(function*
|
|
|
69891
70404
|
const baseUrl = claudeEnvironment.ANTHROPIC_BASE_URL?.trim();
|
|
69892
70405
|
return yield* new TextGenerationError({
|
|
69893
70406
|
operation,
|
|
69894
|
-
detail: baseUrl && !/^https:\/\/api\.anthropic\.com\/?$/i.test(baseUrl) ? "This Claude instance uses a custom API endpoint. The CLI did not report subscription limits. For pooled accounts, open Subscription limits >
|
|
70407
|
+
detail: baseUrl && !/^https:\/\/api\.anthropic\.com\/?$/i.test(baseUrl) ? "This Claude instance uses a custom API endpoint. The CLI did not report subscription limits. For pooled accounts, open Subscription limits > Usage sources and configure the proxy's management URL and management key." : "Claude CLI did not return subscription limits. API-key accounts do not report subscription allowances here. If this instance should use a subscription, check its login and CLAUDE_CONFIG_DIR."
|
|
69895
70408
|
});
|
|
69896
70409
|
}
|
|
69897
70410
|
return { report };
|
|
@@ -71765,6 +72278,10 @@ const makeClaudeAdapter = Effect.fn("makeClaudeAdapter")(function* (claudeSettin
|
|
|
71765
72278
|
rawMethod: "claude/stream_event/message_delta",
|
|
71766
72279
|
rawPayload: message
|
|
71767
72280
|
});
|
|
72281
|
+
if (!context.contextBreakdownRequested) {
|
|
72282
|
+
context.contextBreakdownRequested = true;
|
|
72283
|
+
yield* queryCurrentContextUsage(context, context.lastKnownTotalProcessedTokens).pipe(Effect.flatMap((usage) => emitThreadTokenUsage(context, usage, { rawMethod: "claude/get_context_usage" })), Effect.forkChild);
|
|
72284
|
+
}
|
|
71768
72285
|
return;
|
|
71769
72286
|
}
|
|
71770
72287
|
if (event.type === "content_block_delta") {
|
|
@@ -73042,6 +73559,7 @@ const makeClaudeAdapter = Effect.fn("makeClaudeAdapter")(function* (claudeSettin
|
|
|
73042
73559
|
lastKnownContextWindow: initialContextWindow,
|
|
73043
73560
|
lastKnownTokenUsage: void 0,
|
|
73044
73561
|
lastKnownTotalProcessedTokens: void 0,
|
|
73562
|
+
contextBreakdownRequested: false,
|
|
73045
73563
|
lastAssistantUuid: resumeState?.resumeSessionAt,
|
|
73046
73564
|
lastThreadStartedId: void 0,
|
|
73047
73565
|
interruptRequested: false,
|
|
@@ -103153,50 +103671,6 @@ const makeProviderInstallation = Effect.fn("makeProviderInstallation")(function*
|
|
|
103153
103671
|
};
|
|
103154
103672
|
});
|
|
103155
103673
|
//#endregion
|
|
103156
|
-
//#region src/usage/usageSourceHttp.ts
|
|
103157
|
-
const MAX_RESPONSE_BYTES$1 = 1024 * 1024;
|
|
103158
|
-
const LOOPBACK_HOSTS$1 = /* @__PURE__ */ new Set([
|
|
103159
|
-
"localhost",
|
|
103160
|
-
"127.0.0.1",
|
|
103161
|
-
"[::1]"
|
|
103162
|
-
]);
|
|
103163
|
-
/** The management key stays on the configured origin, including redirects. */
|
|
103164
|
-
async function readManagementJson(config, path, body, signal) {
|
|
103165
|
-
const base = new URL(config.url);
|
|
103166
|
-
if (base.username || base.password || base.search || base.hash || base.protocol !== "https:" && !(base.protocol === "http:" && LOOPBACK_HOSTS$1.has(base.hostname))) throw new Error("Invalid usage source origin");
|
|
103167
|
-
if (path !== "auth-files" && path !== "api-call") throw new Error("Unsupported management operation");
|
|
103168
|
-
const response = await fetch(new URL(`/v0/management/${path}`, base), {
|
|
103169
|
-
method: body === void 0 ? "GET" : "POST",
|
|
103170
|
-
redirect: "error",
|
|
103171
|
-
signal,
|
|
103172
|
-
headers: {
|
|
103173
|
-
authorization: `Bearer ${config.managementKey}`,
|
|
103174
|
-
"content-type": "application/json"
|
|
103175
|
-
},
|
|
103176
|
-
...body === void 0 ? {} : { body: JSON.stringify(body) }
|
|
103177
|
-
});
|
|
103178
|
-
if (!response.ok || !response.body) {
|
|
103179
|
-
await response.body?.cancel();
|
|
103180
|
-
throw new UsageLimitSourceError({ detail: response.status === 401 || response.status === 403 ? `The usage source rejected its management key (HTTP ${response.status}). Update the management key in Manage usage sources; a provider API key cannot replace it.` : `The usage source management request failed (HTTP ${response.status}). Check the source URL and management API availability.` });
|
|
103181
|
-
}
|
|
103182
|
-
const reader = response.body.getReader();
|
|
103183
|
-
const chunks = [];
|
|
103184
|
-
let total = 0;
|
|
103185
|
-
try {
|
|
103186
|
-
for (;;) {
|
|
103187
|
-
const chunk = await reader.read();
|
|
103188
|
-
if (chunk.done) break;
|
|
103189
|
-
total += chunk.value.byteLength;
|
|
103190
|
-
if (total > MAX_RESPONSE_BYTES$1) throw new Error("Usage source response too large");
|
|
103191
|
-
chunks.push(chunk.value);
|
|
103192
|
-
}
|
|
103193
|
-
return JSON.parse(Buffer.concat(chunks).toString("utf8"));
|
|
103194
|
-
} finally {
|
|
103195
|
-
await reader.cancel().catch(() => void 0);
|
|
103196
|
-
reader.releaseLock();
|
|
103197
|
-
}
|
|
103198
|
-
}
|
|
103199
|
-
//#endregion
|
|
103200
103674
|
//#region src/usage/cliproxyApi.ts
|
|
103201
103675
|
const isUsageLimitSourceError$1 = Schema$1.is(UsageLimitSourceError);
|
|
103202
103676
|
const MAX_SOURCE_ACCOUNTS = 128;
|
|
@@ -103261,7 +103735,21 @@ const CreditList = Schema$1.Struct({ credits: Schema$1.Array(Schema$1.Struct({
|
|
|
103261
103735
|
reset_type: Schema$1.String,
|
|
103262
103736
|
expires_at: Schema$1.String
|
|
103263
103737
|
})) });
|
|
103738
|
+
/** Codex's answer to a consume request (openai/codex backend-client `ConsumeRateLimitResetCreditResponse`). */
|
|
103739
|
+
const ConsumeResponse = Schema$1.Struct({ code: Schema$1.Literals([
|
|
103740
|
+
"reset",
|
|
103741
|
+
"nothing_to_reset",
|
|
103742
|
+
"no_credit",
|
|
103743
|
+
"already_redeemed"
|
|
103744
|
+
]) });
|
|
103745
|
+
const CONSUME_OUTCOMES = {
|
|
103746
|
+
reset: "reset",
|
|
103747
|
+
nothing_to_reset: "nothingToReset",
|
|
103748
|
+
no_credit: "noCredit",
|
|
103749
|
+
already_redeemed: "alreadyRedeemed"
|
|
103750
|
+
};
|
|
103264
103751
|
const decodeAuthFiles = Schema$1.decodeUnknownEffect(AuthFiles);
|
|
103752
|
+
const decodeConsumeResponse = Schema$1.decodeUnknownEffect(Schema$1.fromJsonString(ConsumeResponse));
|
|
103265
103753
|
const encodeJson$5 = Schema$1.encodeEffect(Schema$1.fromJsonString(Schema$1.Unknown));
|
|
103266
103754
|
const decodeApiResponse = Schema$1.decodeUnknownEffect(ApiResponse);
|
|
103267
103755
|
const decodeCreditList = Schema$1.decodeUnknownEffect(Schema$1.fromJsonString(CreditList));
|
|
@@ -103269,6 +103757,7 @@ const decodeClaudeUsage = Schema$1.decodeUnknownEffect(Schema$1.fromJsonString(C
|
|
|
103269
103757
|
const decodeCodexUsage = Schema$1.decodeUnknownEffect(Schema$1.fromJsonString(CodexUsage));
|
|
103270
103758
|
const CODEX_BASE = "https://chatgpt.com/backend-api/wham";
|
|
103271
103759
|
const CREDIT_URL = `${CODEX_BASE}/rate-limit-reset-credits`;
|
|
103760
|
+
const CONSUME_URL = `${CREDIT_URL}/consume`;
|
|
103272
103761
|
const makeCliproxyApi = Effect.gen(function* () {
|
|
103273
103762
|
const management = (config, path, body) => Effect.tryPromise({
|
|
103274
103763
|
try: (signal) => readManagementJson(config, path, body, signal),
|
|
@@ -103389,10 +103878,32 @@ const makeCliproxyApi = Effect.gen(function* () {
|
|
|
103389
103878
|
})
|
|
103390
103879
|
})));
|
|
103391
103880
|
});
|
|
103392
|
-
return {
|
|
103393
|
-
|
|
103394
|
-
|
|
103395
|
-
|
|
103881
|
+
return {
|
|
103882
|
+
readAccounts: Effect.fn("CliproxyApi.readAccounts")(function* (config) {
|
|
103883
|
+
const accounts = yield* authFiles(config).pipe(Effect.mapError((cause) => isUsageLimitSourceError$1(cause) ? cause : new UsageLimitSourceError({ detail: "The usage source returned an unsupported account list." })));
|
|
103884
|
+
return yield* Effect.forEach(accounts.filter((account) => !account.disabled && (account.provider === "codex" || account.provider === "claude")), (account) => readAccount(config, account), { concurrency: ACCOUNT_READ_CONCURRENCY });
|
|
103885
|
+
}),
|
|
103886
|
+
consumeResetCredit: Effect.fn("CliproxyApi.consumeResetCredit")(function* (config, accountId, input) {
|
|
103887
|
+
const notSent = (detail) => ({
|
|
103888
|
+
detail,
|
|
103889
|
+
sent: false
|
|
103890
|
+
});
|
|
103891
|
+
const account = (yield* authFiles(config).pipe(Effect.mapError((cause) => notSent(isUsageLimitSourceError$1(cause) ? cause.detail : "The usage source returned an unsupported account list.")))).find((file) => file.id === accountId && file.provider === "codex" && !file.disabled);
|
|
103892
|
+
if (!account) return yield* Effect.fail(notSent("The usage source no longer has this Codex account. Refresh and try again."));
|
|
103893
|
+
const body = yield* apiCall(config, account, CONSUME_URL, {
|
|
103894
|
+
redeem_request_id: input.idempotencyKey,
|
|
103895
|
+
credit_id: input.creditId
|
|
103896
|
+
}).pipe(Effect.mapError((cause) => ({
|
|
103897
|
+
detail: isUsageLimitSourceError$1(cause) ? cause.detail : "The usage source could not send the reset request.",
|
|
103898
|
+
sent: true
|
|
103899
|
+
})));
|
|
103900
|
+
const response = yield* decodeConsumeResponse(body).pipe(Effect.mapError(() => ({
|
|
103901
|
+
detail: "Codex answered the reset request in a form P4 does not understand.",
|
|
103902
|
+
sent: true
|
|
103903
|
+
})));
|
|
103904
|
+
return CONSUME_OUTCOMES[response.code];
|
|
103905
|
+
})
|
|
103906
|
+
};
|
|
103396
103907
|
});
|
|
103397
103908
|
//#endregion
|
|
103398
103909
|
//#region src/usage/UsageLimitSources.ts
|
|
@@ -103441,9 +103952,21 @@ const makeWithReader = (api) => Effect.gen(function* () {
|
|
|
103441
103952
|
yield* settings.streamChanges.pipe(Stream.map((value) => value.usageLimitSources), Stream.changes, Stream.switchMap(() => Stream.fromEffect(publish([]).pipe(Effect.andThen(refresh)))), Stream.runDrain, Effect.forkScoped);
|
|
103442
103953
|
yield* Effect.forever(Effect.sleep(REFRESH_INTERVAL).pipe(Effect.andThen(refresh))).pipe(Effect.forkScoped);
|
|
103443
103954
|
yield* refresh.pipe(Effect.forkScoped);
|
|
103955
|
+
const consumeResetCredit = (account, input) => Effect.gen(function* () {
|
|
103956
|
+
const config = (yield* settings.getSettings.pipe(Effect.mapError(() => ({
|
|
103957
|
+
detail: "Could not read the usage source settings.",
|
|
103958
|
+
sent: false
|
|
103959
|
+
})))).usageLimitSources[account.sourceId];
|
|
103960
|
+
if (!config?.enabled || !config.managementKey) return yield* Effect.fail({
|
|
103961
|
+
detail: "This usage source is off or has no management key.",
|
|
103962
|
+
sent: false
|
|
103963
|
+
});
|
|
103964
|
+
return yield* api.consumeResetCredit(config, account.accountId, input);
|
|
103965
|
+
});
|
|
103444
103966
|
return {
|
|
103445
103967
|
current: Ref.get(state),
|
|
103446
103968
|
refresh,
|
|
103969
|
+
consumeResetCredit,
|
|
103447
103970
|
streamChanges: Stream.unwrap(Effect.gen(function* () {
|
|
103448
103971
|
const subscription = yield* PubSub.subscribe(changes);
|
|
103449
103972
|
return Stream.concat(Stream.make(yield* Ref.get(state)), Stream.fromSubscription(subscription)).pipe(Stream.changes);
|
|
@@ -130256,10 +130779,18 @@ const make$27 = Effect.gen(function* PreviewManagerMake() {
|
|
|
130256
130779
|
}).pipe(Effect.withSpan("PreviewManager.make"));
|
|
130257
130780
|
const layer$19 = Layer.effect(PreviewManager, make$27);
|
|
130258
130781
|
const isStoredOutcome = Schema$1.is(Schema$1.Union([ProviderResetCreditOutcome, Schema$1.Literal("failed")]));
|
|
130259
|
-
|
|
130782
|
+
/**
|
|
130783
|
+
* The `instance_id` column holds the target's owner key. Instance ids never
|
|
130784
|
+
* contain a colon, so a pooled account's `source:` key cannot collide with one,
|
|
130785
|
+
* and the JSON keeps any source id unambiguous.
|
|
130786
|
+
*/
|
|
130787
|
+
function resetCreditOwnerKey(target) {
|
|
130788
|
+
return "instanceId" in target ? target.instanceId : `source:${JSON.stringify([target.sourceAccount.sourceId, target.sourceAccount.accountId])}`;
|
|
130789
|
+
}
|
|
130790
|
+
function toAttempt(row, target) {
|
|
130260
130791
|
return {
|
|
130261
130792
|
idempotencyKey: row.idempotency_key,
|
|
130262
|
-
|
|
130793
|
+
...target,
|
|
130263
130794
|
...row.credit_id ? { creditId: row.credit_id } : {},
|
|
130264
130795
|
requestedAt: row.requested_at,
|
|
130265
130796
|
...row.outcome !== null && isStoredOutcome(row.outcome) ? { outcome: row.outcome } : {},
|
|
@@ -130272,28 +130803,39 @@ function toAttempt(row) {
|
|
|
130272
130803
|
* attempt already wrote. The stored row wins: its credit is the one a retry
|
|
130273
130804
|
* must ask about, whatever the retry itself sent.
|
|
130274
130805
|
*
|
|
130275
|
-
* A new attempt is refused while another attempt for the same
|
|
130806
|
+
* A new attempt is refused while another attempt for the same target has no
|
|
130276
130807
|
* answer; `blockedBy` is that attempt, which the caller must retry instead.
|
|
130277
130808
|
* The partial unique index makes the refusal hold across concurrent clients.
|
|
130809
|
+
* `foreign` marks a key already used for another target.
|
|
130278
130810
|
*/
|
|
130279
130811
|
const beginResetCreditAttempt = Effect.fn("ProviderResetCreditAttempts.begin")(function* (input) {
|
|
130280
130812
|
const sql = yield* SqlClient.SqlClient;
|
|
130813
|
+
const owner = resetCreditOwnerKey(input.target);
|
|
130281
130814
|
yield* sql`INSERT INTO provider_reset_credit_attempts
|
|
130282
130815
|
(idempotency_key, instance_id, credit_id, requested_at)
|
|
130283
|
-
VALUES (${input.idempotencyKey}, ${
|
|
130816
|
+
VALUES (${input.idempotencyKey}, ${owner}, ${input.creditId ?? null},
|
|
130284
130817
|
${input.requestedAt})
|
|
130285
130818
|
ON CONFLICT DO NOTHING`;
|
|
130286
130819
|
const own = yield* sql`SELECT * FROM provider_reset_credit_attempts
|
|
130287
130820
|
WHERE idempotency_key = ${input.idempotencyKey}`;
|
|
130288
|
-
if (own[0] !== void 0)
|
|
130289
|
-
|
|
130290
|
-
|
|
130291
|
-
|
|
130821
|
+
if (own[0] !== void 0) {
|
|
130822
|
+
if (own[0].instance_id !== owner) return {
|
|
130823
|
+
attempt: null,
|
|
130824
|
+
blockedBy: null,
|
|
130825
|
+
foreign: true
|
|
130826
|
+
};
|
|
130827
|
+
return {
|
|
130828
|
+
attempt: toAttempt(own[0], input.target),
|
|
130829
|
+
blockedBy: null,
|
|
130830
|
+
foreign: false
|
|
130831
|
+
};
|
|
130832
|
+
}
|
|
130292
130833
|
const unresolved = yield* sql`SELECT * FROM provider_reset_credit_attempts
|
|
130293
|
-
WHERE instance_id = ${
|
|
130834
|
+
WHERE instance_id = ${owner} AND (outcome IS NULL OR outcome = 'failed')`;
|
|
130294
130835
|
return {
|
|
130295
130836
|
attempt: null,
|
|
130296
|
-
blockedBy: unresolved[0] === void 0 ? null : toAttempt(unresolved[0])
|
|
130837
|
+
blockedBy: unresolved[0] === void 0 ? null : toAttempt(unresolved[0], input.target),
|
|
130838
|
+
foreign: false
|
|
130297
130839
|
};
|
|
130298
130840
|
});
|
|
130299
130841
|
/** Write what the provider answered, or `failed` when no answer came back. */
|
|
@@ -130305,15 +130847,15 @@ const completeResetCreditAttempt = Effect.fn("ProviderResetCreditAttempts.comple
|
|
|
130305
130847
|
WHERE idempotency_key = ${input.idempotencyKey}
|
|
130306
130848
|
AND (outcome IS NULL OR outcome = 'failed')
|
|
130307
130849
|
RETURNING *`;
|
|
130308
|
-
if (rows[0] !== void 0) return toAttempt(rows[0]);
|
|
130850
|
+
if (rows[0] !== void 0) return toAttempt(rows[0], input.target);
|
|
130309
130851
|
return toAttempt((yield* sql`SELECT * FROM provider_reset_credit_attempts
|
|
130310
|
-
WHERE idempotency_key = ${input.idempotencyKey}`)[0]);
|
|
130852
|
+
WHERE idempotency_key = ${input.idempotencyKey}`)[0], input.target);
|
|
130311
130853
|
});
|
|
130312
|
-
/** This
|
|
130313
|
-
const listResetCreditAttempts = Effect.fn("ProviderResetCreditAttempts.list")(function* (
|
|
130854
|
+
/** This target's attempts, newest first. */
|
|
130855
|
+
const listResetCreditAttempts = Effect.fn("ProviderResetCreditAttempts.list")(function* (target) {
|
|
130314
130856
|
return (yield* (yield* SqlClient.SqlClient)`SELECT * FROM provider_reset_credit_attempts
|
|
130315
|
-
WHERE instance_id = ${
|
|
130316
|
-
ORDER BY requested_at DESC LIMIT ${20}`).map(toAttempt);
|
|
130857
|
+
WHERE instance_id = ${resetCreditOwnerKey(target)}
|
|
130858
|
+
ORDER BY requested_at DESC LIMIT ${20}`).map((row) => toAttempt(row, target));
|
|
130317
130859
|
});
|
|
130318
130860
|
//#endregion
|
|
130319
130861
|
//#region src/workspace/WorkspaceSearchIndex.ts
|
|
@@ -133715,35 +134257,51 @@ const makeWsRpcLayer = (currentSession, previewAutomationBroker, computerUseBrok
|
|
|
133715
134257
|
detail: "This provider does not report account usage."
|
|
133716
134258
|
})), { "rpc.aggregate": "server" }),
|
|
133717
134259
|
[WS_METHODS.serverConsumeProviderResetCredit]: (input) => {
|
|
134260
|
+
const target = "instanceId" in input ? { instanceId: input.instanceId } : { sourceAccount: input.sourceAccount };
|
|
133718
134261
|
let consumeSent = false;
|
|
133719
134262
|
return observeRpcEffect$1(WS_METHODS.serverConsumeProviderResetCredit, Effect.gen(function* () {
|
|
133720
134263
|
const fail = (detail, cause) => new ProviderResetCreditError({
|
|
133721
|
-
|
|
134264
|
+
...target,
|
|
133722
134265
|
detail,
|
|
133723
134266
|
...consumeSent ? { consumeSent } : {},
|
|
133724
134267
|
...cause === void 0 ? {} : { cause }
|
|
133725
134268
|
});
|
|
133726
134269
|
const begun = yield* beginResetCreditAttempt({
|
|
133727
134270
|
idempotencyKey: input.idempotencyKey,
|
|
133728
|
-
|
|
134271
|
+
target,
|
|
133729
134272
|
creditId: input.creditId,
|
|
133730
134273
|
requestedAt: yield* nowIso$2
|
|
133731
134274
|
});
|
|
134275
|
+
if (begun.foreign) return yield* fail("This attempt belongs to another account.");
|
|
133732
134276
|
const started = begun.attempt;
|
|
133733
134277
|
if (started === null) return yield* fail(begun.blockedBy === null ? "Another reset request just finished. Check the count and try again." : "An earlier reset request has no answer from Codex yet. Retry it before starting another.");
|
|
133734
|
-
if (started.instanceId !== input.instanceId) return yield* fail("This attempt belongs to another provider.");
|
|
133735
134278
|
if (started.outcome !== void 0 && started.outcome !== "failed") return { attempt: started };
|
|
133736
|
-
const
|
|
133737
|
-
|
|
134279
|
+
const creditId = started.creditId;
|
|
134280
|
+
let send;
|
|
134281
|
+
let refresh;
|
|
134282
|
+
if ("instanceId" in target) {
|
|
134283
|
+
const consume = textGeneration.consumeResetCredit;
|
|
134284
|
+
if (!consume) return yield* fail("This provider cannot redeem resets from P4.");
|
|
134285
|
+
send = consume({
|
|
134286
|
+
instanceId: target.instanceId,
|
|
134287
|
+
idempotencyKey: input.idempotencyKey,
|
|
134288
|
+
creditId
|
|
134289
|
+
}).pipe(Effect.map((answer) => answer.outcome));
|
|
134290
|
+
refresh = providerRegistry.refreshInstance(target.instanceId).pipe(Effect.ignoreCause({ log: true }));
|
|
134291
|
+
} else {
|
|
134292
|
+
send = usageLimitSources.consumeResetCredit(target.sourceAccount, {
|
|
134293
|
+
idempotencyKey: input.idempotencyKey,
|
|
134294
|
+
creditId: creditId ?? ("sourceAccount" in input ? input.creditId : "")
|
|
134295
|
+
});
|
|
134296
|
+
refresh = usageLimitSources.refresh;
|
|
134297
|
+
}
|
|
133738
134298
|
consumeSent = true;
|
|
133739
|
-
const result = yield*
|
|
133740
|
-
instanceId: input.instanceId,
|
|
133741
|
-
idempotencyKey: input.idempotencyKey,
|
|
133742
|
-
creditId: started.creditId
|
|
133743
|
-
}).pipe(Effect.result);
|
|
134299
|
+
const result = yield* send.pipe(Effect.result);
|
|
133744
134300
|
if (Result$1.isFailure(result)) {
|
|
134301
|
+
if (result.failure.sent === false) consumeSent = false;
|
|
133745
134302
|
const recorded = yield* completeResetCreditAttempt({
|
|
133746
134303
|
idempotencyKey: input.idempotencyKey,
|
|
134304
|
+
target,
|
|
133747
134305
|
outcome: "failed",
|
|
133748
134306
|
detail: result.failure.detail,
|
|
133749
134307
|
completedAt: yield* nowIso$2
|
|
@@ -133753,20 +134311,21 @@ const makeWsRpcLayer = (currentSession, previewAutomationBroker, computerUseBrok
|
|
|
133753
134311
|
}
|
|
133754
134312
|
const attempt = yield* completeResetCreditAttempt({
|
|
133755
134313
|
idempotencyKey: input.idempotencyKey,
|
|
133756
|
-
|
|
134314
|
+
target,
|
|
134315
|
+
outcome: result.success,
|
|
133757
134316
|
completedAt: yield* nowIso$2
|
|
133758
134317
|
});
|
|
133759
|
-
yield*
|
|
134318
|
+
yield* refresh;
|
|
133760
134319
|
return { attempt };
|
|
133761
134320
|
}).pipe(Effect.catchTag("SqlError", (cause) => Effect.fail(new ProviderResetCreditError({
|
|
133762
|
-
|
|
134321
|
+
...target,
|
|
133763
134322
|
detail: "Could not record the reset attempt.",
|
|
133764
134323
|
...consumeSent ? { consumeSent } : {},
|
|
133765
134324
|
cause
|
|
133766
134325
|
}))), Effect.provideService(SqlClient.SqlClient, sql)), { "rpc.aggregate": "server" });
|
|
133767
134326
|
},
|
|
133768
|
-
[WS_METHODS.serverListProviderResetCreditAttempts]: (input) => observeRpcEffect$1(WS_METHODS.serverListProviderResetCreditAttempts, listResetCreditAttempts(input
|
|
133769
|
-
|
|
134327
|
+
[WS_METHODS.serverListProviderResetCreditAttempts]: (input) => observeRpcEffect$1(WS_METHODS.serverListProviderResetCreditAttempts, listResetCreditAttempts(input).pipe(Effect.map((attempts) => ({ attempts })), Effect.catchTag("SqlError", (cause) => Effect.fail(new ProviderResetCreditError({
|
|
134328
|
+
...input,
|
|
133770
134329
|
detail: "Could not read reset history.",
|
|
133771
134330
|
cause
|
|
133772
134331
|
}))), Effect.provideService(SqlClient.SqlClient, sql)), { "rpc.aggregate": "server" }),
|