claude-use 11.39.0 → 11.40.1
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/dist/cli.cjs +242 -91
- package/dist/index.cjs +4 -4
- package/dist/index.mjs +4 -4
- package/dist/types/index.d.ts +455 -455
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -132,6 +132,7 @@ agent-shim model remove <name> [--yes]
|
|
|
132
132
|
agent-shim model tier <tier> --ref <ref> | --clear
|
|
133
133
|
agent-shim model price <ref> --input <usd> --output <usd> | --clear
|
|
134
134
|
agent-shim model list [--json]
|
|
135
|
+
agent-shim model explain <name> # which member the virtual model's mode picks now, and why
|
|
135
136
|
agent-shim provider remove <name> [--yes] [--json]
|
|
136
137
|
|
|
137
138
|
agent-shim rule add <path> [--config-profile <profile>] [--identity <identity>] [--json]
|
package/dist/cli.cjs
CHANGED
|
@@ -34636,7 +34636,7 @@ var init_package = __esm({
|
|
|
34636
34636
|
"package.json"() {
|
|
34637
34637
|
package_default = {
|
|
34638
34638
|
name: "claude-use",
|
|
34639
|
-
version: "11.
|
|
34639
|
+
version: "11.40.1",
|
|
34640
34640
|
description: "A profile manager and launcher for Claude Code that lets one person run multiple logins from one machine while controlling what gets shared between them.",
|
|
34641
34641
|
license: "MIT",
|
|
34642
34642
|
author: "Joseph Mearman <joseph@mearman.co.uk>",
|
|
@@ -35948,6 +35948,7 @@ function createUsageStore(deps) {
|
|
|
35948
35948
|
}
|
|
35949
35949
|
fs26.appendFilePrivate(import_node_path26.default.join(paths.usageLogDir, segmentName(day, deps.pid)), `${JSON.stringify(record2)}
|
|
35950
35950
|
`);
|
|
35951
|
+
deps.onRecord?.(record2);
|
|
35951
35952
|
if (record2.identity !== void 0) {
|
|
35952
35953
|
rewriteSnapshot(record2.identity, (current) => ({ ...current?.providers, [record2.provider]: foldProviderState(current?.providers[record2.provider], record2) }));
|
|
35953
35954
|
}
|
|
@@ -65489,9 +65490,8 @@ function routedModelRows(models, providers) {
|
|
|
65489
65490
|
if (provider.kind !== void 0 && provider.kind !== "http") {
|
|
65490
65491
|
continue;
|
|
65491
65492
|
}
|
|
65492
|
-
const
|
|
65493
|
-
|
|
65494
|
-
if (match?.[0].endsWith("_MODEL") === true) {
|
|
65493
|
+
const match = Object.entries(provider.env ?? {}).find(([key, value2]) => value2 === model && key.startsWith("ANTHROPIC_DEFAULT_") && key.endsWith("_MODEL"));
|
|
65494
|
+
if (match !== void 0) {
|
|
65495
65495
|
const tier = match[0].replace("ANTHROPIC_DEFAULT_", "").replace("_MODEL", "").toLowerCase();
|
|
65496
65496
|
return tier === "fable" || tier === "opus" || tier === "sonnet" || tier === "haiku" ? tier : void 0;
|
|
65497
65497
|
}
|
|
@@ -115764,6 +115764,72 @@ function supervisedSessionOf(fs26, paths, sessionId, isRunning) {
|
|
|
115764
115764
|
return void 0;
|
|
115765
115765
|
}
|
|
115766
115766
|
|
|
115767
|
+
// src/selection/targetStore.ts
|
|
115768
|
+
init_read();
|
|
115769
|
+
|
|
115770
|
+
// src/selection/signals.ts
|
|
115771
|
+
function targetOf(record2) {
|
|
115772
|
+
return record2.model === void 0 ? void 0 : `${record2.provider}/${record2.model}`;
|
|
115773
|
+
}
|
|
115774
|
+
function median(values) {
|
|
115775
|
+
if (values.length === 0) {
|
|
115776
|
+
return void 0;
|
|
115777
|
+
}
|
|
115778
|
+
const sorted = [...values].sort((left, right) => left - right);
|
|
115779
|
+
const middle = Math.floor(sorted.length / 2);
|
|
115780
|
+
const above = sorted[middle];
|
|
115781
|
+
const below = sorted[middle - 1];
|
|
115782
|
+
return sorted.length % 2 === 0 && above !== void 0 && below !== void 0 ? (above + below) / 2 : sorted[middle];
|
|
115783
|
+
}
|
|
115784
|
+
var OBSERVATION_WINDOW = 20;
|
|
115785
|
+
function observeRecord(observations, record2) {
|
|
115786
|
+
const target = targetOf(record2);
|
|
115787
|
+
if (target === void 0) {
|
|
115788
|
+
return new Map(observations);
|
|
115789
|
+
}
|
|
115790
|
+
const kept = [...observations.get(target) ?? [], record2].slice(-OBSERVATION_WINDOW);
|
|
115791
|
+
return new Map(observations).set(target, kept);
|
|
115792
|
+
}
|
|
115793
|
+
function observationOf(records) {
|
|
115794
|
+
const completed = records.filter((record2) => record2.outcome === "completed");
|
|
115795
|
+
const latencies = completed.map((record2) => record2.latencyMs);
|
|
115796
|
+
const usage = records.flatMap((record2) => record2.usage === void 0 ? [] : [record2.usage]);
|
|
115797
|
+
const input2 = usage.reduce((sum, entry) => sum + (entry.inputTokens ?? 0), 0);
|
|
115798
|
+
const output2 = usage.reduce((sum, entry) => sum + (entry.outputTokens ?? 0), 0);
|
|
115799
|
+
const cacheRead = usage.reduce((sum, entry) => sum + (entry.cacheReadInputTokens ?? 0), 0);
|
|
115800
|
+
return {
|
|
115801
|
+
latencyMs: median(latencies),
|
|
115802
|
+
successRate: records.length === 0 ? void 0 : completed.length / records.length,
|
|
115803
|
+
tokenMix: input2 + output2 + cacheRead === 0 ? void 0 : { input: input2, output: output2, cacheRead }
|
|
115804
|
+
};
|
|
115805
|
+
}
|
|
115806
|
+
function blendedPricePerMTok(prices, mix) {
|
|
115807
|
+
const total = mix.input + mix.output + mix.cacheRead;
|
|
115808
|
+
if (total === 0) {
|
|
115809
|
+
return void 0;
|
|
115810
|
+
}
|
|
115811
|
+
return (prices.input * mix.input + prices.output * mix.output) / total;
|
|
115812
|
+
}
|
|
115813
|
+
|
|
115814
|
+
// src/selection/targetStore.ts
|
|
115815
|
+
var SEED_LOOKBACK_RECORDS = 500;
|
|
115816
|
+
function createTargetObservationStore(fs26, paths) {
|
|
115817
|
+
let observations = /* @__PURE__ */ new Map();
|
|
115818
|
+
const seeded = readUsageLog(fs26, paths.usageLogDir, {}).records.slice(-SEED_LOOKBACK_RECORDS);
|
|
115819
|
+
for (const record2 of seeded) {
|
|
115820
|
+
observations = observeRecord(observations, record2);
|
|
115821
|
+
}
|
|
115822
|
+
return {
|
|
115823
|
+
observe: (record2) => {
|
|
115824
|
+
observations = observeRecord(observations, record2);
|
|
115825
|
+
},
|
|
115826
|
+
observation: (target) => {
|
|
115827
|
+
const records = observations.get(target);
|
|
115828
|
+
return records === void 0 ? void 0 : observationOf(records);
|
|
115829
|
+
}
|
|
115830
|
+
};
|
|
115831
|
+
}
|
|
115832
|
+
|
|
115767
115833
|
// src/update/commands.ts
|
|
115768
115834
|
var import_node_fs14 = __toESM(require("node:fs"), 1);
|
|
115769
115835
|
var import_node_os7 = __toESM(require("node:os"), 1);
|
|
@@ -131323,6 +131389,39 @@ function createPassthroughRoute(name, target) {
|
|
|
131323
131389
|
// src/frontdoor/providerRoute.ts
|
|
131324
131390
|
init_conditions();
|
|
131325
131391
|
init_quotaFacts();
|
|
131392
|
+
init_modelsStore();
|
|
131393
|
+
|
|
131394
|
+
// src/selection/candidates.ts
|
|
131395
|
+
var WINDOW_PERIOD_HOURS = { fiveHour: 5, sevenDay: 168, extraUsage: 168 };
|
|
131396
|
+
function candidateOf(ref, order, facts, isCurrent) {
|
|
131397
|
+
const present = Object.entries(facts.quota ?? {}).map(([name, window]) => ({ name, ...window }));
|
|
131398
|
+
const available = present.every((window) => window.remaining > 0);
|
|
131399
|
+
const remainingAllowance = present.length === 0 ? void 0 : Math.min(...present.map((window) => window.remaining));
|
|
131400
|
+
const hoursToReset = present.length === 0 ? void 0 : Math.min(...present.map((window) => window.hoursUntilReset));
|
|
131401
|
+
const pressure = present.length === 0 ? void 0 : Math.max(
|
|
131402
|
+
...present.map((window) => {
|
|
131403
|
+
const period = WINDOW_PERIOD_HOURS[window.name] ?? Number.NaN;
|
|
131404
|
+
return period > 0 && window.hoursUntilReset > 0 ? window.remaining / (window.hoursUntilReset / period) : Number.NaN;
|
|
131405
|
+
})
|
|
131406
|
+
);
|
|
131407
|
+
return {
|
|
131408
|
+
ref,
|
|
131409
|
+
order,
|
|
131410
|
+
available,
|
|
131411
|
+
...remainingAllowance === void 0 ? {} : { remainingAllowance },
|
|
131412
|
+
...hoursToReset === void 0 ? {} : { hoursToReset },
|
|
131413
|
+
...pressure === void 0 || Number.isNaN(pressure) ? {} : { pressure },
|
|
131414
|
+
// Feasibility at the observed burn needs a burn rate no signal yet carries, so an available candidate counts as feasible and the run-dry projection waits on one.
|
|
131415
|
+
feasible: available,
|
|
131416
|
+
...facts.observation?.latencyMs === void 0 ? {} : { latencyMs: facts.observation.latencyMs },
|
|
131417
|
+
...facts.observation?.successRate === void 0 ? {} : { successRate: facts.observation.successRate },
|
|
131418
|
+
...facts.price === void 0 || facts.observation?.tokenMix === void 0 ? {} : { pricePerMTok: blendedPricePerMTok(facts.price, facts.observation.tokenMix) },
|
|
131419
|
+
isCurrent
|
|
131420
|
+
};
|
|
131421
|
+
}
|
|
131422
|
+
|
|
131423
|
+
// src/frontdoor/providerRoute.ts
|
|
131424
|
+
init_engine();
|
|
131326
131425
|
init_route();
|
|
131327
131426
|
var import_node_stream3 = require("node:stream");
|
|
131328
131427
|
|
|
@@ -131412,22 +131511,43 @@ function scopeSessionProviderPath(request7) {
|
|
|
131412
131511
|
}
|
|
131413
131512
|
return { ...request7, url: `${PROVIDER_PATH_PREFIX}${encodeURIComponent(request7.session.provider)}${request7.url}` };
|
|
131414
131513
|
}
|
|
131415
|
-
function
|
|
131416
|
-
|
|
131417
|
-
|
|
131514
|
+
function resolveRoutedModel(model, providerName, session, includeUnqualified, deps, memory, rotations) {
|
|
131515
|
+
const models = deps.models?.();
|
|
131516
|
+
const qualified = model.includes("/") && !model.startsWith("acct:") ? model : void 0;
|
|
131517
|
+
if (qualified !== void 0) {
|
|
131518
|
+
const [provider2, ...rest2] = qualified.split("/");
|
|
131519
|
+
const named = rest2.join("/");
|
|
131520
|
+
return provider2 === void 0 || named === "" ? void 0 : { provider: provider2, model: named, ref: qualified };
|
|
131418
131521
|
}
|
|
131419
|
-
|
|
131420
|
-
|
|
131522
|
+
const virtual = models?.virtual?.[model];
|
|
131523
|
+
if (virtual === void 0 || !includeUnqualified) {
|
|
131524
|
+
return void 0;
|
|
131421
131525
|
}
|
|
131422
|
-
|
|
131526
|
+
const members2 = expandMembers(model, models).filter((member) => !member.startsWith("acct:") && !member.startsWith("family:"));
|
|
131527
|
+
if (members2.length === 0) {
|
|
131423
131528
|
return void 0;
|
|
131424
131529
|
}
|
|
131425
|
-
const
|
|
131426
|
-
const
|
|
131427
|
-
|
|
131530
|
+
const snapshot = deps.usageSnapshotOf?.(session.identity);
|
|
131531
|
+
const current = memory.get(session.sessionId ?? "");
|
|
131532
|
+
const candidates = members2.map((ref, order) => {
|
|
131533
|
+
const [provider2] = ref.split("/");
|
|
131534
|
+
const facts = quotaFactsOf(snapshot?.providers[provider2 ?? ""]?.rateLimit?.unified, Date.now());
|
|
131535
|
+
return candidateOf(ref, order, {
|
|
131536
|
+
quota: facts,
|
|
131537
|
+
...deps.observations?.(ref) === void 0 ? {} : { observation: deps.observations(ref) },
|
|
131538
|
+
...models?.prices?.[ref] === void 0 ? {} : { price: models.prices[ref] }
|
|
131539
|
+
}, ref === current);
|
|
131540
|
+
});
|
|
131541
|
+
const evaluated = candidates.map((candidate) => ({ candidate, capabilities: { vision: true, tools: true, thinking: true } }));
|
|
131542
|
+
const rotation = rotations.get(model) ?? 0;
|
|
131543
|
+
rotations.set(model, rotation + 1);
|
|
131544
|
+
const selection = selectMember(virtual.mode, evaluated, { rotation });
|
|
131545
|
+
if (selection.ref === void 0) {
|
|
131428
131546
|
return void 0;
|
|
131429
131547
|
}
|
|
131430
|
-
|
|
131548
|
+
const [provider, ...rest] = selection.ref.split("/");
|
|
131549
|
+
const chosen = rest.join("/");
|
|
131550
|
+
return provider === void 0 || chosen === "" ? void 0 : { provider, model: chosen, ref: selection.ref };
|
|
131431
131551
|
}
|
|
131432
131552
|
function resolveAccountTarget(model, models) {
|
|
131433
131553
|
if (model.startsWith("acct:")) {
|
|
@@ -131444,6 +131564,8 @@ function createProviderRouteResolver(deps) {
|
|
|
131444
131564
|
const oauthRoute = createPassthroughRoute("anthropic", { baseUrl: `https://${CONNECT_INTERCEPT_HOST}:${String(HTTPS_PORT)}`, stripPrefix: void 0, headroomUpstream: void 0 });
|
|
131445
131565
|
const antigravityQuotaSources = /* @__PURE__ */ new Map();
|
|
131446
131566
|
const antigravityRoutingMemory = /* @__PURE__ */ new Map();
|
|
131567
|
+
const routingMemory = /* @__PURE__ */ new Map();
|
|
131568
|
+
const rotations = /* @__PURE__ */ new Map();
|
|
131447
131569
|
const memoryFor = (provider) => {
|
|
131448
131570
|
const existing = antigravityRoutingMemory.get(provider);
|
|
131449
131571
|
if (existing !== void 0) {
|
|
@@ -131605,10 +131727,12 @@ function createProviderRouteResolver(deps) {
|
|
|
131605
131727
|
}
|
|
131606
131728
|
const routesByName = (isRouter || current.session.routeByName) && !isRcSelfHostPath(path65);
|
|
131607
131729
|
if (routesByName) {
|
|
131608
|
-
const scan2 = await scanRequestHead(current,
|
|
131609
|
-
if (scan2.replayed
|
|
131610
|
-
|
|
131730
|
+
const scan2 = await scanRequestHead(current, true);
|
|
131731
|
+
if (scan2.replayed === void 0) {
|
|
131732
|
+
const resolution = resolve2(current);
|
|
131733
|
+
return resolution.ok && replay !== void 0 ? { ok: true, route: servingRewritten(resolution.route, { ...replay, url: current.url }), request: { ...replay, url: current.url } } : resolution.ok ? serveScoped(resolution) : resolution;
|
|
131611
131734
|
}
|
|
131735
|
+
replay = scan2.replayed;
|
|
131612
131736
|
const account = scan2.model === void 0 ? void 0 : resolveAccountTarget(scan2.model, deps.models?.());
|
|
131613
131737
|
if (account !== void 0) {
|
|
131614
131738
|
const sessionId = current.session.sessionId ?? "";
|
|
@@ -131619,18 +131743,29 @@ function createProviderRouteResolver(deps) {
|
|
|
131619
131743
|
message: moved ? `model "${account.model}" runs under identity "${account.identity}"; this session is being moved there and will resume with it` : `model "${account.model}" runs under identity "${account.identity}", which needs a relaunch this session cannot make; start it there with: claude @${account.identity} --resume`
|
|
131620
131744
|
};
|
|
131621
131745
|
}
|
|
131622
|
-
const
|
|
131623
|
-
|
|
131746
|
+
const routed = scan2.model === void 0 ? void 0 : resolveRoutedModel(scan2.model, providerName, current.session, isRouter || providerName !== void 0, deps, routingMemory, rotations);
|
|
131747
|
+
const requested = scan2.model;
|
|
131748
|
+
if (routed !== void 0) {
|
|
131749
|
+
routingMemory.set(current.session.sessionId ?? "", routed.ref);
|
|
131750
|
+
if (requested !== void 0 && routed.provider === providerName && routed.model === requested) {
|
|
131751
|
+
const resolution2 = resolve2(current);
|
|
131752
|
+
return resolution2.ok ? { ok: true, route: servingRewritten(resolution2.route, { ...replay, url: current.url }), request: { ...replay, url: current.url } } : resolution2;
|
|
131753
|
+
}
|
|
131754
|
+
if (requested !== void 0 && routed.model !== requested) {
|
|
131755
|
+
const rewritten = (scan2.text ?? "").replace(new RegExp('"model":\\s*"' + requested.replace(/[.*+?^${}()|[\]\\]/g, "\\$&") + '"'), '"model":"' + routed.model + '"');
|
|
131756
|
+
const headers = Object.fromEntries(Object.entries(replay.headers).filter(([name]) => name.toLowerCase() !== "content-length"));
|
|
131757
|
+
replay = { ...replay, headers, body: import_node_stream3.Readable.from([Buffer.from(rewritten, "utf8")]) };
|
|
131758
|
+
}
|
|
131759
|
+
if (routed.provider !== providerName) {
|
|
131760
|
+
const scopedPrefix = providerName === void 0 ? void 0 : `${PROVIDER_PATH_PREFIX}${encodeURIComponent(providerName)}`;
|
|
131761
|
+
const rest2 = scopedPrefix !== void 0 && path65.startsWith(scopedPrefix) ? path65.slice(scopedPrefix.length) : path65;
|
|
131762
|
+
const query2 = current.url.includes("?") ? current.url.slice(current.url.indexOf("?")) : "";
|
|
131763
|
+
const carried = replay;
|
|
131764
|
+
current = { ...current, url: `${PROVIDER_PATH_PREFIX}${encodeURIComponent(routed.provider)}${rest2}${query2}`, body: carried.body, headers: carried.headers };
|
|
131765
|
+
continue;
|
|
131766
|
+
}
|
|
131624
131767
|
const resolution = resolve2(current);
|
|
131625
|
-
return resolution.ok
|
|
131626
|
-
}
|
|
131627
|
-
if (target !== void 0) {
|
|
131628
|
-
const scopedPrefix = providerName === void 0 ? void 0 : `${PROVIDER_PATH_PREFIX}${encodeURIComponent(providerName)}`;
|
|
131629
|
-
const rest2 = scopedPrefix !== void 0 && path65.startsWith(scopedPrefix) ? path65.slice(scopedPrefix.length) : path65;
|
|
131630
|
-
const query2 = current.url.includes("?") ? current.url.slice(current.url.indexOf("?")) : "";
|
|
131631
|
-
const carried = scan2.replayed ?? current;
|
|
131632
|
-
current = { ...current, url: `${PROVIDER_PATH_PREFIX}${encodeURIComponent(target)}${rest2}${query2}`, body: carried.body, headers: carried.headers };
|
|
131633
|
-
continue;
|
|
131768
|
+
return resolution.ok ? { ok: true, route: servingRewritten(resolution.route, { ...replay, url: current.url }), request: { ...replay, url: current.url } } : resolution;
|
|
131634
131769
|
}
|
|
131635
131770
|
}
|
|
131636
131771
|
if (routes === void 0 || routes.length === 0) {
|
|
@@ -134701,67 +134836,6 @@ function createRealQuotaRefresher(params) {
|
|
|
134701
134836
|
|
|
134702
134837
|
// src/frontdoor/commands.ts
|
|
134703
134838
|
init_store2();
|
|
134704
|
-
|
|
134705
|
-
// src/selection/targetStore.ts
|
|
134706
|
-
init_read();
|
|
134707
|
-
|
|
134708
|
-
// src/selection/signals.ts
|
|
134709
|
-
function targetOf(record2) {
|
|
134710
|
-
return record2.model === void 0 ? void 0 : `${record2.provider}/${record2.model}`;
|
|
134711
|
-
}
|
|
134712
|
-
function median(values) {
|
|
134713
|
-
if (values.length === 0) {
|
|
134714
|
-
return void 0;
|
|
134715
|
-
}
|
|
134716
|
-
const sorted = [...values].sort((left, right) => left - right);
|
|
134717
|
-
const middle = Math.floor(sorted.length / 2);
|
|
134718
|
-
const above = sorted[middle];
|
|
134719
|
-
const below = sorted[middle - 1];
|
|
134720
|
-
return sorted.length % 2 === 0 && above !== void 0 && below !== void 0 ? (above + below) / 2 : sorted[middle];
|
|
134721
|
-
}
|
|
134722
|
-
var OBSERVATION_WINDOW = 20;
|
|
134723
|
-
function observeRecord(observations, record2) {
|
|
134724
|
-
const target = targetOf(record2);
|
|
134725
|
-
if (target === void 0) {
|
|
134726
|
-
return new Map(observations);
|
|
134727
|
-
}
|
|
134728
|
-
const kept = [...observations.get(target) ?? [], record2].slice(-OBSERVATION_WINDOW);
|
|
134729
|
-
return new Map(observations).set(target, kept);
|
|
134730
|
-
}
|
|
134731
|
-
function observationOf(records) {
|
|
134732
|
-
const completed = records.filter((record2) => record2.outcome === "completed");
|
|
134733
|
-
const latencies = completed.map((record2) => record2.latencyMs);
|
|
134734
|
-
const usage = records.flatMap((record2) => record2.usage === void 0 ? [] : [record2.usage]);
|
|
134735
|
-
const input2 = usage.reduce((sum, entry) => sum + (entry.inputTokens ?? 0), 0);
|
|
134736
|
-
const output2 = usage.reduce((sum, entry) => sum + (entry.outputTokens ?? 0), 0);
|
|
134737
|
-
const cacheRead = usage.reduce((sum, entry) => sum + (entry.cacheReadInputTokens ?? 0), 0);
|
|
134738
|
-
return {
|
|
134739
|
-
latencyMs: median(latencies),
|
|
134740
|
-
successRate: records.length === 0 ? void 0 : completed.length / records.length,
|
|
134741
|
-
tokenMix: input2 + output2 + cacheRead === 0 ? void 0 : { input: input2, output: output2, cacheRead }
|
|
134742
|
-
};
|
|
134743
|
-
}
|
|
134744
|
-
|
|
134745
|
-
// src/selection/targetStore.ts
|
|
134746
|
-
var SEED_LOOKBACK_RECORDS = 500;
|
|
134747
|
-
function createTargetObservationStore(fs26, paths) {
|
|
134748
|
-
let observations = /* @__PURE__ */ new Map();
|
|
134749
|
-
const seeded = readUsageLog(fs26, paths.usageLogDir, {}).records.slice(-SEED_LOOKBACK_RECORDS);
|
|
134750
|
-
for (const record2 of seeded) {
|
|
134751
|
-
observations = observeRecord(observations, record2);
|
|
134752
|
-
}
|
|
134753
|
-
return {
|
|
134754
|
-
observe: (record2) => {
|
|
134755
|
-
observations = observeRecord(observations, record2);
|
|
134756
|
-
},
|
|
134757
|
-
observation: (target) => {
|
|
134758
|
-
const records = observations.get(target);
|
|
134759
|
-
return records === void 0 ? void 0 : observationOf(records);
|
|
134760
|
-
}
|
|
134761
|
-
};
|
|
134762
|
-
}
|
|
134763
|
-
|
|
134764
|
-
// src/frontdoor/commands.ts
|
|
134765
134839
|
function respawnInvocation(paths) {
|
|
134766
134840
|
const env = {};
|
|
134767
134841
|
for (const [name, value2] of Object.entries({ ...process.env, AGENT_SHIM_HOME: paths.root })) {
|
|
@@ -134846,6 +134920,7 @@ function realFrontDoorSupervisorPorts(paths) {
|
|
|
134846
134920
|
appendLog(paths, `frontdoor ${String(process.pid)}: ${line}`);
|
|
134847
134921
|
}
|
|
134848
134922
|
});
|
|
134923
|
+
const observations = createTargetObservationStore(realFarmFs, paths);
|
|
134849
134924
|
const routingSnapshots = /* @__PURE__ */ new Map();
|
|
134850
134925
|
const rcControlToken = (0, import_node_crypto25.randomUUID)();
|
|
134851
134926
|
const resolveRoute = rcObservingResolver(
|
|
@@ -134861,6 +134936,7 @@ function realFrontDoorSupervisorPorts(paths) {
|
|
|
134861
134936
|
credentials: { ...realCredentialPort, cache: realCredentialCacheEnv(paths) },
|
|
134862
134937
|
usageSnapshotOf: (identity) => identity === void 0 ? void 0 : routingSnapshots.get(identity) ?? readUsageSnapshot(realFarmFs, paths.usageSnapshotsDir, identity),
|
|
134863
134938
|
// An `acct:` model member is served by relaunch: the door leaves a move request for the session's supervisor (found across every pool's registry, since the door does not know which pool launched the session) and answers the request with what is happening. A session nothing supervises gets the message naming the command to run instead.
|
|
134939
|
+
observations: (target) => observations.observation(target),
|
|
134864
134940
|
accountMoves: (sessionId, to2, model) => {
|
|
134865
134941
|
if (supervisedSessionOf(realFarmFs, paths, sessionId, realIsProcessRunning) === void 0) {
|
|
134866
134942
|
return false;
|
|
@@ -134884,6 +134960,9 @@ function realFrontDoorSupervisorPorts(paths) {
|
|
|
134884
134960
|
publish: (snapshot) => {
|
|
134885
134961
|
routingSnapshots.set(snapshot.identity, snapshot);
|
|
134886
134962
|
usagePublisher.publish(snapshot);
|
|
134963
|
+
},
|
|
134964
|
+
onRecord: (record2) => {
|
|
134965
|
+
observations.observe(record2);
|
|
134887
134966
|
}
|
|
134888
134967
|
});
|
|
134889
134968
|
const quotaRefresher = createRealQuotaRefresher({ paths, store: usageStore, log });
|
|
@@ -135501,7 +135580,8 @@ function enrichStatuslinePayload(params) {
|
|
|
135501
135580
|
sevenDayResetAt: void 0,
|
|
135502
135581
|
providerQuotaWindows: [],
|
|
135503
135582
|
quotaFamilies: [],
|
|
135504
|
-
headroom: params.headroom
|
|
135583
|
+
headroom: params.headroom,
|
|
135584
|
+
routedTarget: params.routedTarget
|
|
135505
135585
|
};
|
|
135506
135586
|
if (params.snapshot !== void 0) {
|
|
135507
135587
|
const scopedName = providerScopedState(params.snapshot, params.providerName, params.env.AGENT_SHIM_PROVIDER);
|
|
@@ -135575,6 +135655,9 @@ function providerScopedState(snapshot, providerName, providerDisplayName) {
|
|
|
135575
135655
|
return void 0;
|
|
135576
135656
|
}
|
|
135577
135657
|
|
|
135658
|
+
// src/statusline/commands.ts
|
|
135659
|
+
init_read();
|
|
135660
|
+
|
|
135578
135661
|
// src/statusline/ansi.ts
|
|
135579
135662
|
var ESCAPE_CHAR_CODE = 27;
|
|
135580
135663
|
var ESCAPE = String.fromCharCode(ESCAPE_CHAR_CODE);
|
|
@@ -135866,6 +135949,9 @@ function renderStatuslineBlock(summary, view, terminalWidth, nowMs) {
|
|
|
135866
135949
|
const account = [summary.providerAccountEmail, summary.providerPlan].filter((part) => part !== void 0);
|
|
135867
135950
|
header.push(account.length > 0 ? `${summary.provider} \xB7 ${account.join(" \xB7 ")}` : summary.provider);
|
|
135868
135951
|
}
|
|
135952
|
+
if (summary.routedTarget !== void 0) {
|
|
135953
|
+
header.push(`via ${summary.routedTarget}`);
|
|
135954
|
+
}
|
|
135869
135955
|
const loginPlan = summary.provider === void 0 ? summary.loginPlan ?? accountPlanLabel(summary) : void 0;
|
|
135870
135956
|
const loginOrgName = summary.loginOrganizationType === "claude_team" || summary.loginOrganizationType === "claude_enterprise" ? summary.loginOrganizationName : void 0;
|
|
135871
135957
|
const loginParts = [summary.loginAccountEmail, loginOrgName, loginPlan].filter((part) => part !== void 0);
|
|
@@ -135969,6 +136055,7 @@ async function readAllStdin() {
|
|
|
135969
136055
|
process.stdin.resume();
|
|
135970
136056
|
});
|
|
135971
136057
|
}
|
|
136058
|
+
var ROUTED_TARGET_LOOKBACK_MS = 36e5;
|
|
135972
136059
|
function registerStatuslineCommand(program2, deps) {
|
|
135973
136060
|
withExamples(
|
|
135974
136061
|
program2.command("statusline").description("Serve as a statusline entrypoint: read the client's stdin payload, add the identity's live provider, account and usage windows under an agent_shim key, then run the renderer named in AGENT_SHIM_STATUSLINE_CMD or print the built-in line.").action(async () => {
|
|
@@ -136015,7 +136102,19 @@ function registerStatuslineCommand(program2, deps) {
|
|
|
136015
136102
|
const target = headroomTargetOf(process.env, socketTarget === void 0 || socketTarget.refused !== void 0 ? void 0 : socketTarget.socketPath);
|
|
136016
136103
|
const sessionId = headroomSessionIdOf(payload, process.env);
|
|
136017
136104
|
const headroom = target === void 0 || sessionId === void 0 ? void 0 : await fetchHeadroomSessionStats(realHeadroomGet, target, sessionId);
|
|
136018
|
-
const
|
|
136105
|
+
const sessionHeader = /x-agent-shim-session:\s*([A-Za-z0-9@._-]+)/i.exec(process.env.ANTHROPIC_CUSTOM_HEADERS ?? "")?.[1];
|
|
136106
|
+
let routedTarget;
|
|
136107
|
+
if (sessionHeader !== void 0) {
|
|
136108
|
+
try {
|
|
136109
|
+
const last = readUsageLog(realFarmFs, deps.paths.usageLogDir, { sinceMs: nowMs - ROUTED_TARGET_LOOKBACK_MS }).records.filter((record2) => record2.sessionId === sessionHeader).at(-1);
|
|
136110
|
+
if (last?.model !== void 0 && last.provider !== providerName) {
|
|
136111
|
+
routedTarget = `${last.provider}/${last.model}`;
|
|
136112
|
+
}
|
|
136113
|
+
} catch {
|
|
136114
|
+
routedTarget = void 0;
|
|
136115
|
+
}
|
|
136116
|
+
}
|
|
136117
|
+
const { payload: enriched, summary } = enrichStatuslinePayload({ payload, env: process.env, snapshot, account, providerName, nowMs, headroom, routedTarget });
|
|
136019
136118
|
const renderer = process.env.AGENT_SHIM_STATUSLINE_CMD;
|
|
136020
136119
|
if (renderer !== void 0 && renderer !== "") {
|
|
136021
136120
|
const child = (0, import_node_child_process7.spawn)("/bin/sh", ["-c", renderer], { stdio: ["pipe", "inherit", "inherit"] });
|
|
@@ -147539,6 +147638,52 @@ function sameFamilyOtherVersion(a10, b) {
|
|
|
147539
147638
|
|
|
147540
147639
|
// src/models.ts
|
|
147541
147640
|
init_modelsStore();
|
|
147641
|
+
init_realPorts();
|
|
147642
|
+
init_read();
|
|
147643
|
+
init_quotaFacts();
|
|
147644
|
+
init_engine();
|
|
147645
|
+
function providerQuotaOf(paths) {
|
|
147646
|
+
const newest = /* @__PURE__ */ new Map();
|
|
147647
|
+
for (const name of realFarmFs.readdir(paths.usageSnapshotsDir)) {
|
|
147648
|
+
if (!name.endsWith(".json")) {
|
|
147649
|
+
continue;
|
|
147650
|
+
}
|
|
147651
|
+
const identity = name.slice(0, -".json".length);
|
|
147652
|
+
const snapshot = readUsageSnapshot(realFarmFs, paths.usageSnapshotsDir, identity);
|
|
147653
|
+
if (snapshot === void 0) {
|
|
147654
|
+
continue;
|
|
147655
|
+
}
|
|
147656
|
+
for (const provider of Object.keys(snapshot.providers)) {
|
|
147657
|
+
const known = newest.get(provider);
|
|
147658
|
+
if (known === void 0 || snapshot.updatedAt.localeCompare(known.updatedAt) > 0) {
|
|
147659
|
+
newest.set(provider, snapshot);
|
|
147660
|
+
}
|
|
147661
|
+
}
|
|
147662
|
+
}
|
|
147663
|
+
return (provider) => {
|
|
147664
|
+
const snapshot = newest.get(provider);
|
|
147665
|
+
return snapshot === void 0 ? {} : quotaFactsOf(snapshot.providers[provider]?.rateLimit?.unified, Date.now());
|
|
147666
|
+
};
|
|
147667
|
+
}
|
|
147668
|
+
function explainVirtualModel(paths, name) {
|
|
147669
|
+
const models = readModels(paths);
|
|
147670
|
+
const definition = models?.virtual?.[name];
|
|
147671
|
+
if (definition === void 0) {
|
|
147672
|
+
throw new UsageError(`No virtual model named "${name}".`);
|
|
147673
|
+
}
|
|
147674
|
+
const quotaOf = providerQuotaOf(paths);
|
|
147675
|
+
const observations = createTargetObservationStore(realFarmFs, paths);
|
|
147676
|
+
const candidates = expandMembers(name, models).filter((member) => !member.startsWith("acct:") && !member.startsWith("family:")).map((ref, order) => {
|
|
147677
|
+
const [provider] = ref.split("/");
|
|
147678
|
+
return candidateOf(ref, order, { quota: quotaOf(provider ?? ""), ...observations.observation(ref) === void 0 ? {} : { observation: observations.observation(ref) }, ...models?.prices?.[ref] === void 0 ? {} : { price: models.prices[ref] } }, false);
|
|
147679
|
+
});
|
|
147680
|
+
const evaluated = candidates.map((candidate) => ({ candidate, capabilities: { vision: true, tools: true, thinking: true } }));
|
|
147681
|
+
const selection = selectMember(definition.mode, evaluated, {});
|
|
147682
|
+
console.log(`${name} (${definition.mode}) chooses ${selection.ref ?? "nothing"}:`);
|
|
147683
|
+
for (const line of selection.reasons) {
|
|
147684
|
+
console.log(` ${line}`);
|
|
147685
|
+
}
|
|
147686
|
+
}
|
|
147542
147687
|
function providerModels(paths) {
|
|
147543
147688
|
return listProviders(paths).flatMap((entry) => {
|
|
147544
147689
|
const catalogue = parseCatalogueCache(realFsPort.readFileUtf8(catalogueCachePath(paths, entry.name)));
|
|
@@ -147573,6 +147718,12 @@ function matchModels(models) {
|
|
|
147573
147718
|
function registerModelsCommand(program2, deps) {
|
|
147574
147719
|
const { paths } = deps;
|
|
147575
147720
|
const modelsCommand = program2.command("model").description("Define and inspect the models the providers offer and the virtual models chosen among them.");
|
|
147721
|
+
withExamples(
|
|
147722
|
+
modelsCommand.command("explain <name>").description("Show which member a virtual model's mode picks over the live signals, and why each candidate stands where it does.").action((name) => {
|
|
147723
|
+
explainVirtualModel(paths, name);
|
|
147724
|
+
}),
|
|
147725
|
+
["agent-shim model explain fast"]
|
|
147726
|
+
);
|
|
147576
147727
|
withExamples(modelsCommand, ["agent-shim model match", "agent-shim model add fast --mode soonest-reset --member z/glm-5.3 --member m/MiniMax-M3"]);
|
|
147577
147728
|
withExamples(
|
|
147578
147729
|
modelsCommand.command("match").description("List every model every provider offers, grouped into the ones that are the same model across providers, with the pairs that are merely similar named beside them.").option("--json", "Print the match as JSON."),
|
package/dist/index.cjs
CHANGED
|
@@ -3106,7 +3106,7 @@ var init_package = __esm({
|
|
|
3106
3106
|
"package.json"() {
|
|
3107
3107
|
package_default = {
|
|
3108
3108
|
name: "claude-use",
|
|
3109
|
-
version: "11.
|
|
3109
|
+
version: "11.40.1",
|
|
3110
3110
|
description: "A profile manager and launcher for Claude Code that lets one person run multiple logins from one machine while controlling what gets shared between them.",
|
|
3111
3111
|
license: "MIT",
|
|
3112
3112
|
author: "Joseph Mearman <joseph@mearman.co.uk>",
|
|
@@ -6063,6 +6063,7 @@ function createUsageStore(deps) {
|
|
|
6063
6063
|
}
|
|
6064
6064
|
fs13.appendFilePrivate(import_node_path20.default.join(paths.usageLogDir, segmentName(day, deps.pid)), `${JSON.stringify(record)}
|
|
6065
6065
|
`);
|
|
6066
|
+
deps.onRecord?.(record);
|
|
6066
6067
|
if (record.identity !== void 0) {
|
|
6067
6068
|
rewriteSnapshot(record.identity, (current) => ({ ...current?.providers, [record.provider]: foldProviderState(current?.providers[record.provider], record) }));
|
|
6068
6069
|
}
|
|
@@ -8955,9 +8956,8 @@ function routedModelRows(models, providers) {
|
|
|
8955
8956
|
if (provider.kind !== void 0 && provider.kind !== "http") {
|
|
8956
8957
|
continue;
|
|
8957
8958
|
}
|
|
8958
|
-
const
|
|
8959
|
-
|
|
8960
|
-
if (match?.[0].endsWith("_MODEL") === true) {
|
|
8959
|
+
const match = Object.entries(provider.env ?? {}).find(([key, value]) => value === model && key.startsWith("ANTHROPIC_DEFAULT_") && key.endsWith("_MODEL"));
|
|
8960
|
+
if (match !== void 0) {
|
|
8961
8961
|
const tier = match[0].replace("ANTHROPIC_DEFAULT_", "").replace("_MODEL", "").toLowerCase();
|
|
8962
8962
|
return tier === "fable" || tier === "opus" || tier === "sonnet" || tier === "haiku" ? tier : void 0;
|
|
8963
8963
|
}
|
package/dist/index.mjs
CHANGED
|
@@ -3082,7 +3082,7 @@ var init_package = __esm({
|
|
|
3082
3082
|
"package.json"() {
|
|
3083
3083
|
package_default = {
|
|
3084
3084
|
name: "claude-use",
|
|
3085
|
-
version: "11.
|
|
3085
|
+
version: "11.40.1",
|
|
3086
3086
|
description: "A profile manager and launcher for Claude Code that lets one person run multiple logins from one machine while controlling what gets shared between them.",
|
|
3087
3087
|
license: "MIT",
|
|
3088
3088
|
author: "Joseph Mearman <joseph@mearman.co.uk>",
|
|
@@ -6038,6 +6038,7 @@ function createUsageStore(deps) {
|
|
|
6038
6038
|
}
|
|
6039
6039
|
fs13.appendFilePrivate(path20.join(paths.usageLogDir, segmentName(day, deps.pid)), `${JSON.stringify(record)}
|
|
6040
6040
|
`);
|
|
6041
|
+
deps.onRecord?.(record);
|
|
6041
6042
|
if (record.identity !== void 0) {
|
|
6042
6043
|
rewriteSnapshot(record.identity, (current) => ({ ...current?.providers, [record.provider]: foldProviderState(current?.providers[record.provider], record) }));
|
|
6043
6044
|
}
|
|
@@ -8927,9 +8928,8 @@ function routedModelRows(models, providers) {
|
|
|
8927
8928
|
if (provider.kind !== void 0 && provider.kind !== "http") {
|
|
8928
8929
|
continue;
|
|
8929
8930
|
}
|
|
8930
|
-
const
|
|
8931
|
-
|
|
8932
|
-
if (match?.[0].endsWith("_MODEL") === true) {
|
|
8931
|
+
const match = Object.entries(provider.env ?? {}).find(([key, value]) => value === model && key.startsWith("ANTHROPIC_DEFAULT_") && key.endsWith("_MODEL"));
|
|
8932
|
+
if (match !== void 0) {
|
|
8933
8933
|
const tier = match[0].replace("ANTHROPIC_DEFAULT_", "").replace("_MODEL", "").toLowerCase();
|
|
8934
8934
|
return tier === "fable" || tier === "opus" || tier === "sonnet" || tier === "haiku" ? tier : void 0;
|
|
8935
8935
|
}
|