claude-use 11.41.0 → 11.43.0

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/cli.cjs CHANGED
@@ -27528,6 +27528,9 @@ function pruneDeadFrontDoorDirectRecords(fs26, recordsDir, records, liveness) {
27528
27528
  }
27529
27529
  }
27530
27530
  }
27531
+ function recordOf(details) {
27532
+ return details === void 0 ? {} : { sessionId: details.sessionId, ...details.models === void 0 ? {} : { models: details.models } };
27533
+ }
27531
27534
  function writeFrontDoorSession(fs26, sessionsDir, session) {
27532
27535
  fs26.mkdirPrivate(sessionsDir);
27533
27536
  fs26.writeFilePrivate(import_node_path5.default.join(sessionsDir, `${String(session.pid)}.json`), `${JSON.stringify(session, null, 2)}
@@ -27580,14 +27583,31 @@ function liveSessionTokens(fs26, sessionsDir) {
27580
27583
  }
27581
27584
  return tokens;
27582
27585
  }
27586
+ function readFrontDoorSessionModels(fs26, sessionsDir, sessionId) {
27587
+ for (const name of fs26.readdir(sessionsDir)) {
27588
+ if (!name.endsWith(".json")) {
27589
+ continue;
27590
+ }
27591
+ try {
27592
+ const parsed = FrontDoorSessionSchema.safeParse(JSON.parse(fs26.readFileUtf8(import_node_path5.default.join(sessionsDir, name)) ?? ""));
27593
+ if (parsed.success && parsed.data.sessionId === sessionId) {
27594
+ return parsed.data.models;
27595
+ }
27596
+ } catch {
27597
+ continue;
27598
+ }
27599
+ }
27600
+ return void 0;
27601
+ }
27583
27602
  var import_node_path5, FRONT_DOOR_PROTOCOL, FrontDoorSessionSchema, FrontDoorStateSchema, MAX_TCP_PORT, FrontDoorDirectRecordSchema, RECORD_TEMPORARY_FILE;
27584
27603
  var init_state = __esm({
27585
27604
  "src/frontdoor/state.ts"() {
27586
27605
  "use strict";
27587
27606
  import_node_path5 = __toESM(require("node:path"), 1);
27588
27607
  init_zod();
27608
+ init_schema();
27589
27609
  FRONT_DOOR_PROTOCOL = 4;
27590
- FrontDoorSessionSchema = external_exports.strictObject({ pid: external_exports.number().int().positive(), startedAt: external_exports.number(), token: external_exports.string().min(1), supervisorPid: external_exports.number().int().positive().optional() });
27610
+ FrontDoorSessionSchema = external_exports.strictObject({ pid: external_exports.number().int().positive(), startedAt: external_exports.number(), token: external_exports.string().min(1), supervisorPid: external_exports.number().int().positive().optional(), sessionId: external_exports.string().min(1).optional(), models: ModelsConfigSchema.optional() });
27591
27611
  FrontDoorStateSchema = external_exports.strictObject({
27592
27612
  /**
27593
27613
  * The launcher-to-door wire protocol this supervisor speaks, written once it is serving; absent in state written by a release that predates the field, which `ensureFrontDoor` reads as protocol 0. A launcher replaces a door whose protocol is lower than its own (see `FRONT_DOOR_PROTOCOL`).
@@ -32142,7 +32162,8 @@ function assembleCascade(input2) {
32142
32162
  ...config2.categories === void 0 ? {} : { categories: config2.categories },
32143
32163
  ...config2.entries === void 0 ? {} : { entries: config2.entries },
32144
32164
  ...entryOrder === void 0 ? {} : { entryOrder },
32145
- ...config2.launch === void 0 ? {} : { launch: config2.launch }
32165
+ ...config2.launch === void 0 ? {} : { launch: config2.launch },
32166
+ ...config2.models === void 0 ? {} : { models: config2.models }
32146
32167
  });
32147
32168
  nextId += 1;
32148
32169
  }
@@ -34676,7 +34697,7 @@ var init_package = __esm({
34676
34697
  "package.json"() {
34677
34698
  package_default = {
34678
34699
  name: "claude-use",
34679
- version: "11.41.0",
34700
+ version: "11.43.0",
34680
34701
  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.",
34681
34702
  license: "MIT",
34682
34703
  author: "Joseph Mearman <joseph@mearman.co.uk>",
@@ -36251,6 +36272,219 @@ var init_realCredentialCache = __esm({
36251
36272
  }
36252
36273
  });
36253
36274
 
36275
+ // src/models/identity.ts
36276
+ function withoutContextMarker(model) {
36277
+ return model.toLowerCase().endsWith(CONTEXT_MARKER_1M) ? model.slice(0, -CONTEXT_MARKER_1M.length) : model;
36278
+ }
36279
+ function canonicalText(name) {
36280
+ return name.trim().toLowerCase().replace(NON_IDENTITY_BRACKET_RE, "").replace(/[\s_]+/g, "-").replace(/([a-z])(\d+(?:\.\d+)+)/g, "$1-$2").replace(/-+/g, "-").replace(/^-|-$/g, "");
36281
+ }
36282
+ function splitVariants(tokens) {
36283
+ const variants = [];
36284
+ let end = tokens.length;
36285
+ for (; ; ) {
36286
+ const token = tokens[end - 1];
36287
+ if (token === void 0 || !KNOWN_VARIANTS.has(token)) {
36288
+ return { familyTokens: tokens.slice(0, end), variants };
36289
+ }
36290
+ variants.unshift(token);
36291
+ end -= 1;
36292
+ }
36293
+ }
36294
+ function versionOf(tokens) {
36295
+ for (let index = 0; index < tokens.length; index += 1) {
36296
+ const token = tokens[index];
36297
+ const next = tokens[index + 1];
36298
+ if (token === void 0) {
36299
+ return "";
36300
+ }
36301
+ if (/^\d+$/.test(token) && next !== void 0 && /^\d+$/.test(next)) {
36302
+ return `${token}.${next}`;
36303
+ }
36304
+ const dotted = /^\d+(?:\.\d+)+$/.exec(token);
36305
+ if (dotted !== null) {
36306
+ return dotted[0];
36307
+ }
36308
+ }
36309
+ return "";
36310
+ }
36311
+ function modelIdentity(rawName) {
36312
+ const segments = rawName.trim().toLowerCase().split("/");
36313
+ const stripped = canonicalText(segments[segments.length - 1] ?? "").split(":")[0] ?? "";
36314
+ const withoutDate = stripped.replace(DATE_STAMP_RE, "");
36315
+ const tokens = withoutDate.split("-").filter((token) => token !== "");
36316
+ const { familyTokens, variants } = splitVariants(tokens);
36317
+ const version2 = versionOf(familyTokens);
36318
+ const versionless = familyTokens.filter((token, index) => {
36319
+ if (version2 === "") {
36320
+ return true;
36321
+ }
36322
+ const dotted = /^\d+(?:\.\d+)+$/.test(token);
36323
+ const previous = familyTokens[index - 1];
36324
+ const next = familyTokens[index + 1];
36325
+ const insideVersionRun = dotted || /^\d+$/.test(token) && (previous !== void 0 && /^\d+$/.test(previous) || next !== void 0 && /^\d+$/.test(next));
36326
+ return !insideVersionRun;
36327
+ });
36328
+ const family = versionless.join("-");
36329
+ const tokenVendor = familyTokens.find((token) => Object.keys(VENDOR_BY_TOKEN).some((key) => token === key || token.startsWith(key)));
36330
+ const namespace = segments.length >= 2 ? (segments[0] ?? "").split(":").pop() ?? "" : "";
36331
+ const namespaceVendor = VENDOR_BY_NAMESPACE[namespace] ?? "";
36332
+ const tokenVendorName = tokenVendor === void 0 ? "" : VENDOR_BY_TOKEN[Object.keys(VENDOR_BY_TOKEN).find((key) => tokenVendor === key || tokenVendor.startsWith(key)) ?? ""] ?? "";
36333
+ return {
36334
+ vendor: tokenVendorName === "" ? namespaceVendor : tokenVendorName,
36335
+ vendorConflict: tokenVendorName !== "" && namespaceVendor !== "" && tokenVendorName !== namespaceVendor,
36336
+ family,
36337
+ version: version2,
36338
+ variant: variants.join("-"),
36339
+ familyAndVersion: version2 === "" ? family : `${family}-${version2.replace(/\./g, "-")}`
36340
+ };
36341
+ }
36342
+ function relateModels(left, right) {
36343
+ const a10 = modelIdentity(left);
36344
+ const b = modelIdentity(right);
36345
+ if (a10.familyAndVersion !== b.familyAndVersion) {
36346
+ return sameFamilyOtherVersion(a10, b) ? "similar" : "distinct";
36347
+ }
36348
+ if (a10.variant !== b.variant || a10.vendorConflict || b.vendorConflict || a10.vendor !== "" && b.vendor !== "" && a10.vendor !== b.vendor) {
36349
+ return "similar";
36350
+ }
36351
+ return "same";
36352
+ }
36353
+ function sameFamilyOtherVersion(a10, b) {
36354
+ if (a10.family !== b.family) {
36355
+ return false;
36356
+ }
36357
+ if (a10.vendor !== "" && b.vendor !== "" && a10.vendor !== b.vendor) {
36358
+ return false;
36359
+ }
36360
+ return true;
36361
+ }
36362
+ var NON_IDENTITY_BRACKET_RE, CONTEXT_MARKER_1M, DATE_STAMP_RE, KNOWN_VARIANTS, VENDOR_BY_NAMESPACE, VENDOR_BY_TOKEN;
36363
+ var init_identity2 = __esm({
36364
+ "src/models/identity.ts"() {
36365
+ "use strict";
36366
+ NON_IDENTITY_BRACKET_RE = /\[[^\]]*\]/g;
36367
+ CONTEXT_MARKER_1M = "[1m]";
36368
+ DATE_STAMP_RE = /-(?:19|20)\d{2}(?:0[1-9]|1[0-2])(?:0[1-9]|[12]\d|3[01])$/;
36369
+ KNOWN_VARIANTS = /* @__PURE__ */ new Set(["high", "medium", "low", "thinking", "xhigh", "max", "highspeed", "sol", "terra", "luna", "mini", "flash-lite", "turbo"]);
36370
+ VENDOR_BY_NAMESPACE = Object.freeze({
36371
+ anthropic: "anthropic",
36372
+ google: "google",
36373
+ openai: "openai",
36374
+ zai: "zai",
36375
+ "z-ai": "zai",
36376
+ minimax: "minimax",
36377
+ qwen: "qwen",
36378
+ deepseek: "deepseek",
36379
+ moonshot: "moonshot",
36380
+ meta: "meta",
36381
+ mistral: "mistral"
36382
+ });
36383
+ VENDOR_BY_TOKEN = Object.freeze({
36384
+ claude: "anthropic",
36385
+ gemini: "google",
36386
+ antigravity: "google",
36387
+ gpt: "openai",
36388
+ glm: "zai",
36389
+ minimax: "minimax",
36390
+ qwen: "qwen",
36391
+ deepseek: "deepseek",
36392
+ kimi: "moonshot",
36393
+ llama: "meta",
36394
+ mistral: "mistral",
36395
+ mixtral: "mistral"
36396
+ });
36397
+ }
36398
+ });
36399
+
36400
+ // src/models/families.ts
36401
+ function modelOf(ref) {
36402
+ const slash = ref.indexOf("/");
36403
+ return slash === -1 ? ref : ref.slice(slash + 1);
36404
+ }
36405
+ function familyKeyOf(rawModel) {
36406
+ const identity = modelIdentity(rawModel);
36407
+ return identity.variant === "" ? identity.familyAndVersion : `${identity.familyAndVersion}${VARIANT_SEPARATOR}${identity.variant}`;
36408
+ }
36409
+ function assertionsOf(models) {
36410
+ return { same: models?.same ?? [], distinct: models?.distinct ?? [] };
36411
+ }
36412
+ function sameModel(left, right, assertions) {
36413
+ if (assertions.distinct.some(([a10, b]) => a10 === left && b === right || a10 === right && b === left)) {
36414
+ return false;
36415
+ }
36416
+ const leftGroup = assertions.same.find((group) => group.includes(left));
36417
+ const rightGroup = assertions.same.find((group) => group.includes(right));
36418
+ if (leftGroup !== void 0 && leftGroup === rightGroup) {
36419
+ return true;
36420
+ }
36421
+ if (leftGroup !== void 0 && !leftGroup.includes(right) || rightGroup !== void 0 && !rightGroup.includes(left)) {
36422
+ return false;
36423
+ }
36424
+ return relateModels(modelOf(left), modelOf(right)) === "same";
36425
+ }
36426
+ function pinnedTo(settings2, ref) {
36427
+ return settings2?.names?.some((name) => name === ref || name === modelOf(ref)) === true;
36428
+ }
36429
+ function buildFamilies(refs, models) {
36430
+ const assertions = assertionsOf(models);
36431
+ const settingsByKey = models?.families ?? {};
36432
+ const groups = [];
36433
+ for (const ref of refs) {
36434
+ const pinnedKey = Object.entries(settingsByKey).find(([, settings2]) => pinnedTo(settings2, ref))?.[0];
36435
+ const joined2 = groups.find((group) => pinnedKey === void 0 ? group.refs.some((first) => sameModel(first, ref, assertions)) : group.key === pinnedKey);
36436
+ if (joined2 !== void 0) {
36437
+ joined2.refs.push(ref);
36438
+ } else {
36439
+ groups.push({ key: pinnedKey ?? familyKeyOf(modelOf(ref)), refs: [ref] });
36440
+ }
36441
+ }
36442
+ return groups.map((group) => ({ key: group.key, refs: group.refs, settings: settingsByKey[group.key] ?? {} }));
36443
+ }
36444
+ function familyNamed(families, member) {
36445
+ if (!member.startsWith(FAMILY_PREFIX)) {
36446
+ return void 0;
36447
+ }
36448
+ const key = member.slice(FAMILY_PREFIX.length);
36449
+ return families.find((family) => family.key === key);
36450
+ }
36451
+ function familyCapabilities(settings2) {
36452
+ return { vision: settings2.vision ?? true, tools: settings2.tools ?? true, thinking: settings2.thinking ?? true };
36453
+ }
36454
+ function familyMode(settings2) {
36455
+ return settings2.mode ?? "ordered";
36456
+ }
36457
+ function sharedFamilies(families) {
36458
+ return families.filter((family) => family.refs.length > 1);
36459
+ }
36460
+ function expandFamilyMembers(members2, families) {
36461
+ const expanded = [];
36462
+ for (const member of members2) {
36463
+ for (const ref of member.startsWith(FAMILY_PREFIX) ? familyNamed(families, member)?.refs ?? [] : [member]) {
36464
+ if (!expanded.includes(ref)) {
36465
+ expanded.push(ref);
36466
+ }
36467
+ }
36468
+ }
36469
+ return expanded;
36470
+ }
36471
+ function familyOfRef(families, ref) {
36472
+ return families.find((family) => family.refs.includes(ref));
36473
+ }
36474
+ function accountRefsOf(models) {
36475
+ const named = [...(models?.same ?? []).flat(), ...Object.values(models?.families ?? {}).flatMap((settings2) => settings2.names ?? [])];
36476
+ return [...new Set(named.filter((ref) => ref.startsWith("acct:")))];
36477
+ }
36478
+ var FAMILY_PREFIX, VARIANT_SEPARATOR;
36479
+ var init_families = __esm({
36480
+ "src/models/families.ts"() {
36481
+ "use strict";
36482
+ init_identity2();
36483
+ FAMILY_PREFIX = "family:";
36484
+ VARIANT_SEPARATOR = "+";
36485
+ }
36486
+ });
36487
+
36254
36488
  // src/providersStore.ts
36255
36489
  function providerJsonPath(paths, name) {
36256
36490
  return import_node_path29.default.join(paths.providersDir, `${name}.json`);
@@ -36545,8 +36779,15 @@ function resolveRoutedProviderCredentials(params) {
36545
36779
  }
36546
36780
  const virtualNames = new Set(Object.keys(models.virtual ?? {}));
36547
36781
  const providerNames = /* @__PURE__ */ new Set();
36782
+ const families = () => buildFamilies(params.targets?.() ?? [], models);
36548
36783
  const collect = (ref) => {
36549
- if (ref.startsWith("acct:") || ref.startsWith("family:") || virtualNames.has(ref)) {
36784
+ if (ref.startsWith(FAMILY_PREFIX)) {
36785
+ for (const target of expandFamilyMembers([ref], families())) {
36786
+ collect(target);
36787
+ }
36788
+ return;
36789
+ }
36790
+ if (ref.startsWith("acct:") || virtualNames.has(ref)) {
36550
36791
  return;
36551
36792
  }
36552
36793
  const [provider] = ref.split("/", 1);
@@ -36603,6 +36844,7 @@ var init_providersStore = __esm({
36603
36844
  init_cliError();
36604
36845
  init_credential();
36605
36846
  init_walk();
36847
+ init_families();
36606
36848
  ProviderNotFoundError = class extends CliError {
36607
36849
  constructor(name) {
36608
36850
  super(`No provider named "${name}". Run \`agent-shim provider add ${name}\` first.`);
@@ -62713,7 +62955,7 @@ function ensureFrontDoor(params) {
62713
62955
  if (state?.port !== void 0 && state.connectPort !== void 0) {
62714
62956
  if (supervisorPid === params.launcherPid && params.replace !== true && ports.isFrontDoorSupervisor(supervisorPid)) {
62715
62957
  const token = (0, import_node_crypto11.randomUUID)();
62716
- writeFrontDoorSession(ports.fs, paths.frontdoorSessionsDir, { pid: params.launcherPid, startedAt: ports.now(), token, supervisorPid });
62958
+ writeFrontDoorSession(ports.fs, paths.frontdoorSessionsDir, { pid: params.launcherPid, startedAt: ports.now(), token, supervisorPid, ...recordOf(params.session) });
62717
62959
  return { port: state.port, connectPort: state.connectPort, token };
62718
62960
  }
62719
62961
  const verdict = verifyWithRetry(state.port);
@@ -62727,7 +62969,7 @@ function ensureFrontDoor(params) {
62727
62969
  }
62728
62970
  if (verdict.ok) {
62729
62971
  const token = (0, import_node_crypto11.randomUUID)();
62730
- writeFrontDoorSession(ports.fs, paths.frontdoorSessionsDir, { pid: params.launcherPid, startedAt: ports.now(), token, supervisorPid });
62972
+ writeFrontDoorSession(ports.fs, paths.frontdoorSessionsDir, { pid: params.launcherPid, startedAt: ports.now(), token, supervisorPid, ...recordOf(params.session) });
62731
62973
  return { port: state.port, connectPort: state.connectPort, token };
62732
62974
  }
62733
62975
  lastRejection = `the listener on 127.0.0.1:${String(state.port)} (recorded for pid ${String(supervisorPid)}) failed authentication: ${verdict.reason}`;
@@ -62993,8 +63235,8 @@ function realRestartFrontDoor(paths, spawnDaemon) {
62993
63235
  }
62994
63236
  function realFrontDoorPort(paths, spawnDaemon) {
62995
63237
  return {
62996
- ensure: (inheritedExtraCaCerts) => {
62997
- const up2 = ensureFrontDoor({ paths, launcherPid: process.pid, ports: realEnsurePorts(paths, spawnDaemon) });
63238
+ ensure: (inheritedExtraCaCerts, session) => {
63239
+ const up2 = ensureFrontDoor({ paths, launcherPid: process.pid, ports: realEnsurePorts(paths, spawnDaemon), ...session === void 0 ? {} : { session } });
62998
63240
  const trust = resolveTrustBundle({ caCertFile: paths.frontdoorCaCertFile, bundlesDir: paths.frontdoorCaBundlesDir, variable: "NODE_EXTRA_CA_CERTS", inherited: inheritedExtraCaCerts, fs: realTrustBundleFs });
62999
63241
  return {
63000
63242
  port: up2.port,
@@ -63796,6 +64038,14 @@ function buildEnv(params) {
63796
64038
  env[key] = value2;
63797
64039
  }
63798
64040
  }
64041
+ if (params.routeByName) {
64042
+ for (const tier of CLAUDE_TIERS) {
64043
+ const ref = params.tierModels?.[tier];
64044
+ if (ref !== void 0) {
64045
+ env[`ANTHROPIC_DEFAULT_${tier.toUpperCase()}_MODEL`] = ref;
64046
+ }
64047
+ }
64048
+ }
63799
64049
  if (params.provider !== void 0) {
63800
64050
  env.ANTHROPIC_AUTH_TOKEN = params.remoteControl ? void 0 : PROVIDER_SESSION_PLACEHOLDER;
63801
64051
  env.ANTHROPIC_API_KEY = void 0;
@@ -63838,6 +64088,7 @@ var init_flags = __esm({
63838
64088
  init_envBool();
63839
64089
  init_cliError();
63840
64090
  init_conditions();
64091
+ init_schema();
63841
64092
  init_credential();
63842
64093
  init_headers();
63843
64094
  init_capability();
@@ -64216,131 +64467,6 @@ var init_launchReport = __esm({
64216
64467
  }
64217
64468
  });
64218
64469
 
64219
- // src/models/identity.ts
64220
- function withoutContextMarker(model) {
64221
- return model.toLowerCase().endsWith(CONTEXT_MARKER_1M) ? model.slice(0, -CONTEXT_MARKER_1M.length) : model;
64222
- }
64223
- function canonicalText(name) {
64224
- return name.trim().toLowerCase().replace(NON_IDENTITY_BRACKET_RE, "").replace(/[\s_]+/g, "-").replace(/([a-z])(\d+(?:\.\d+)+)/g, "$1-$2").replace(/-+/g, "-").replace(/^-|-$/g, "");
64225
- }
64226
- function splitVariants(tokens) {
64227
- const variants = [];
64228
- let end = tokens.length;
64229
- for (; ; ) {
64230
- const token = tokens[end - 1];
64231
- if (token === void 0 || !KNOWN_VARIANTS.has(token)) {
64232
- return { familyTokens: tokens.slice(0, end), variants };
64233
- }
64234
- variants.unshift(token);
64235
- end -= 1;
64236
- }
64237
- }
64238
- function versionOf(tokens) {
64239
- for (let index = 0; index < tokens.length; index += 1) {
64240
- const token = tokens[index];
64241
- const next = tokens[index + 1];
64242
- if (token === void 0) {
64243
- return "";
64244
- }
64245
- if (/^\d+$/.test(token) && next !== void 0 && /^\d+$/.test(next)) {
64246
- return `${token}.${next}`;
64247
- }
64248
- const dotted = /^\d+(?:\.\d+)+$/.exec(token);
64249
- if (dotted !== null) {
64250
- return dotted[0];
64251
- }
64252
- }
64253
- return "";
64254
- }
64255
- function modelIdentity(rawName) {
64256
- const segments = rawName.trim().toLowerCase().split("/");
64257
- const stripped = canonicalText(segments[segments.length - 1] ?? "").split(":")[0] ?? "";
64258
- const withoutDate = stripped.replace(DATE_STAMP_RE, "");
64259
- const tokens = withoutDate.split("-").filter((token) => token !== "");
64260
- const { familyTokens, variants } = splitVariants(tokens);
64261
- const version2 = versionOf(familyTokens);
64262
- const versionless = familyTokens.filter((token, index) => {
64263
- if (version2 === "") {
64264
- return true;
64265
- }
64266
- const dotted = /^\d+(?:\.\d+)+$/.test(token);
64267
- const previous = familyTokens[index - 1];
64268
- const next = familyTokens[index + 1];
64269
- const insideVersionRun = dotted || /^\d+$/.test(token) && (previous !== void 0 && /^\d+$/.test(previous) || next !== void 0 && /^\d+$/.test(next));
64270
- return !insideVersionRun;
64271
- });
64272
- const family = versionless.join("-");
64273
- const tokenVendor = familyTokens.find((token) => Object.keys(VENDOR_BY_TOKEN).some((key) => token === key || token.startsWith(key)));
64274
- const namespace = segments.length >= 2 ? (segments[0] ?? "").split(":").pop() ?? "" : "";
64275
- const namespaceVendor = VENDOR_BY_NAMESPACE[namespace] ?? "";
64276
- const tokenVendorName = tokenVendor === void 0 ? "" : VENDOR_BY_TOKEN[Object.keys(VENDOR_BY_TOKEN).find((key) => tokenVendor === key || tokenVendor.startsWith(key)) ?? ""] ?? "";
64277
- return {
64278
- vendor: tokenVendorName === "" ? namespaceVendor : tokenVendorName,
64279
- vendorConflict: tokenVendorName !== "" && namespaceVendor !== "" && tokenVendorName !== namespaceVendor,
64280
- family,
64281
- version: version2,
64282
- variant: variants.join("-"),
64283
- familyAndVersion: version2 === "" ? family : `${family}-${version2.replace(/\./g, "-")}`
64284
- };
64285
- }
64286
- function relateModels(left, right) {
64287
- const a10 = modelIdentity(left);
64288
- const b = modelIdentity(right);
64289
- if (a10.familyAndVersion !== b.familyAndVersion) {
64290
- return sameFamilyOtherVersion(a10, b) ? "similar" : "distinct";
64291
- }
64292
- if (a10.variant !== b.variant || a10.vendorConflict || b.vendorConflict || a10.vendor !== "" && b.vendor !== "" && a10.vendor !== b.vendor) {
64293
- return "similar";
64294
- }
64295
- return "same";
64296
- }
64297
- function sameFamilyOtherVersion(a10, b) {
64298
- if (a10.family !== b.family) {
64299
- return false;
64300
- }
64301
- if (a10.vendor !== "" && b.vendor !== "" && a10.vendor !== b.vendor) {
64302
- return false;
64303
- }
64304
- return true;
64305
- }
64306
- var NON_IDENTITY_BRACKET_RE, CONTEXT_MARKER_1M, DATE_STAMP_RE, KNOWN_VARIANTS, VENDOR_BY_NAMESPACE, VENDOR_BY_TOKEN;
64307
- var init_identity2 = __esm({
64308
- "src/models/identity.ts"() {
64309
- "use strict";
64310
- NON_IDENTITY_BRACKET_RE = /\[[^\]]*\]/g;
64311
- CONTEXT_MARKER_1M = "[1m]";
64312
- DATE_STAMP_RE = /-(?:19|20)\d{2}(?:0[1-9]|1[0-2])(?:0[1-9]|[12]\d|3[01])$/;
64313
- KNOWN_VARIANTS = /* @__PURE__ */ new Set(["high", "medium", "low", "thinking", "xhigh", "max", "highspeed", "sol", "terra", "luna", "mini", "flash-lite", "turbo"]);
64314
- VENDOR_BY_NAMESPACE = Object.freeze({
64315
- anthropic: "anthropic",
64316
- google: "google",
64317
- openai: "openai",
64318
- zai: "zai",
64319
- "z-ai": "zai",
64320
- minimax: "minimax",
64321
- qwen: "qwen",
64322
- deepseek: "deepseek",
64323
- moonshot: "moonshot",
64324
- meta: "meta",
64325
- mistral: "mistral"
64326
- });
64327
- VENDOR_BY_TOKEN = Object.freeze({
64328
- claude: "anthropic",
64329
- gemini: "google",
64330
- antigravity: "google",
64331
- gpt: "openai",
64332
- glm: "zai",
64333
- minimax: "minimax",
64334
- qwen: "qwen",
64335
- deepseek: "deepseek",
64336
- kimi: "moonshot",
64337
- llama: "meta",
64338
- mistral: "mistral",
64339
- mixtral: "mistral"
64340
- });
64341
- }
64342
- });
64343
-
64344
64470
  // src/selection/engine.ts
64345
64471
  function compareMaybe(left, right, preferHigh) {
64346
64472
  if (left === void 0 && right === void 0) {
@@ -64471,24 +64597,40 @@ function selectAdaptive(candidates, needs) {
64471
64597
  return { ref: fallback.ref, reasons: [...reasons, "nothing stands: serving by order"] };
64472
64598
  }
64473
64599
  const current = standing.find((entry) => entry.candidate.isCurrent);
64474
- if (current !== void 0) {
64475
- return { ref: current.candidate.ref, reasons: [...reasons, `${current.candidate.ref} stands and is the model this session is already on, so the conversation is not re-sent`] };
64476
- }
64477
64600
  const ranked = by(
64478
64601
  (left, right) => compareMaybe(left.pressure, right.pressure, true) || compareMaybe(left.hoursToReset, right.hoursToReset, false) || compareMaybe(left.successRate, right.successRate, true),
64479
64602
  standing.map((entry) => entry.candidate)
64480
64603
  );
64481
64604
  const best = ranked[0];
64605
+ if (current !== void 0) {
64606
+ return stayOrSwitch(current.candidate, best, needs, reasons);
64607
+ }
64482
64608
  if (best === void 0) {
64483
64609
  return { ref: void 0, reasons };
64484
64610
  }
64485
64611
  return { ref: best.ref, reasons: [...reasons, `${best.ref} stands and carries the most allowance its reset would waste`] };
64486
64612
  }
64487
- var ADAPTIVE_HEALTH_FLOOR, availability;
64613
+ function stayOrSwitch(current, best, needs, reasons) {
64614
+ const stay = (why) => ({ ref: current.ref, reasons: [...reasons, `${current.ref} stands and is the model this session is already on${why}`] });
64615
+ if (best === void 0 || best.ref === current.ref) {
64616
+ return stay(", so the conversation is not re-sent");
64617
+ }
64618
+ if (needs === void 0 || best.pressure === void 0 || current.pressure === void 0 || current.pressure <= 0) {
64619
+ return stay(", and nothing says a move would pay for re-sending the conversation");
64620
+ }
64621
+ const gain = best.pressure / current.pressure - 1;
64622
+ const cost = needs.contextTokens / FULL_CONTEXT_TOKENS;
64623
+ if (gain > cost) {
64624
+ return { ref: best.ref, reasons: [...reasons, `${best.ref} carries ${gain.toFixed(2)} more of the allowance its reset would waste, more than the ${cost.toFixed(2)} of a full context that re-sending the conversation costs`] };
64625
+ }
64626
+ return stay(`, and ${best.ref}'s gain of ${gain.toFixed(2)} does not beat the ${cost.toFixed(2)} of a full context that re-sending the conversation costs`);
64627
+ }
64628
+ var ADAPTIVE_HEALTH_FLOOR, FULL_CONTEXT_TOKENS, availability;
64488
64629
  var init_engine = __esm({
64489
64630
  "src/selection/engine.ts"() {
64490
64631
  "use strict";
64491
64632
  ADAPTIVE_HEALTH_FLOOR = 0.5;
64633
+ FULL_CONTEXT_TOKENS = 1e6;
64492
64634
  availability = (candidate) => candidate.available ? "" : "quota spent";
64493
64635
  }
64494
64636
  });
@@ -65483,7 +65625,7 @@ function catalogueUrls(provider, catalogue) {
65483
65625
  function isRecord9(value2) {
65484
65626
  return typeof value2 === "object" && value2 !== null && !Array.isArray(value2);
65485
65627
  }
65486
- function modelOf(entry) {
65628
+ function modelOf2(entry) {
65487
65629
  if (typeof entry === "string") {
65488
65630
  return entry.trim() === "" ? void 0 : { id: entry.trim() };
65489
65631
  }
@@ -65499,7 +65641,7 @@ function parseCatalogueBody(body) {
65499
65641
  const seen = /* @__PURE__ */ new Set();
65500
65642
  const models = [];
65501
65643
  for (const entry of list) {
65502
- const model = modelOf(entry);
65644
+ const model = modelOf2(entry);
65503
65645
  if (model !== void 0 && !seen.has(model.id)) {
65504
65646
  seen.add(model.id);
65505
65647
  models.push(model);
@@ -65564,147 +65706,6 @@ var init_providerCatalogue = __esm({
65564
65706
  }
65565
65707
  });
65566
65708
 
65567
- // src/launcher/modelPicker.ts
65568
- function labelOf(model) {
65569
- return withoutContextMarker(model);
65570
- }
65571
- function describedAs(model, description) {
65572
- return model.toLowerCase().endsWith(CONTEXT_MARKER_1M) ? `${description}; 1M context` : description;
65573
- }
65574
- function joined(parts) {
65575
- const last = parts[parts.length - 1];
65576
- return last === void 0 || parts.length === 1 ? last ?? "" : `${parts.slice(0, -1).join(", ")} and ${last}`;
65577
- }
65578
- function rowOf(model, reaches) {
65579
- const lead = reaches.find((reach) => reach.standing === "first") ?? reaches[0];
65580
- if (lead === void 0) {
65581
- throw new Error(`model ${model} is reached by no tier`);
65582
- }
65583
- const firsts = reaches.filter((reach) => reach.standing === "first").map((reach) => reach.tier);
65584
- const fallbacks = reaches.filter((reach) => reach.standing === "fallback").map((reach) => reach.tier);
65585
- const serves = firsts.length === 0 ? [] : [`Serves the ${joined(firsts)} tier${firsts.length === 1 ? "" : "s"}`];
65586
- const falls = fallbacks.length === 0 ? [] : [`${serves.length === 0 ? "Fallback" : "fallback"} for ${joined(fallbacks)}`];
65587
- return { model, label: labelOf(model), description: describedAs(model, [...serves, ...falls].join("; ")), behavesAs: TIER_BEHAVES_AS[lead.tier] };
65588
- }
65589
- function rowsOfTable(table) {
65590
- const reachesByModel = /* @__PURE__ */ new Map();
65591
- for (const [tier, candidates] of table) {
65592
- candidates.forEach((model, index) => {
65593
- const reaches = reachesByModel.get(model) ?? [];
65594
- if (!reaches.some((reach) => reach.tier === tier)) {
65595
- reaches.push({ tier, standing: index === 0 ? "first" : "fallback" });
65596
- }
65597
- reachesByModel.set(model, reaches);
65598
- });
65599
- }
65600
- return [...reachesByModel].map(([model, reaches]) => rowOf(model, reaches));
65601
- }
65602
- function antigravityRows(provider) {
65603
- const config2 = resolveAntigravityConfig(provider.antigravity);
65604
- const tiers = rowsOfTable(CLAUDE_TIERS.map((tier) => [tier, config2.models[tier]]));
65605
- const behavesAsOf = new Map(tiers.map((row) => [row.model, row.behavesAs]));
65606
- const aliases = [...config2.aliases].flatMap(([alias, candidates]) => {
65607
- const [first] = candidates;
65608
- const behavesAs = first === void 0 ? void 0 : behavesAsOf.get(first);
65609
- const description = alias === AUTO_ALIAS ? `Routes each request to a backend model with quota left, best first (${String(candidates.length)} models)` : `Alias for ${candidates.join(", then ")}`;
65610
- return behavesAs === void 0 ? [] : [{ model: alias, label: labelOf(alias), description, behavesAs }];
65611
- });
65612
- return [...aliases.filter((row) => row.model === AUTO_ALIAS), ...tiers, ...aliases.filter((row) => row.model !== AUTO_ALIAS)];
65613
- }
65614
- function codexRows(provider) {
65615
- const config2 = resolveCodexConfig(provider.codex);
65616
- return rowsOfTable(CLAUDE_TIERS.map((tier) => [tier, [config2.models[tier]]]));
65617
- }
65618
- function httpRows(provider) {
65619
- const env = provider.env ?? {};
65620
- const table = CLAUDE_TIERS.flatMap((tier) => {
65621
- const model = env[TIER_ENV_VARIABLES[tier]];
65622
- return model === void 0 || model === "" ? [] : [[tier, [model]]];
65623
- });
65624
- return rowsOfTable(table);
65625
- }
65626
- function declaredRow(entry) {
65627
- return {
65628
- model: entry.model,
65629
- label: entry.label ?? labelOf(entry.model),
65630
- description: entry.description ?? describedAs(entry.model, `Declared by the provider for the ${entry.tier} tier`),
65631
- behavesAs: TIER_BEHAVES_AS[entry.tier]
65632
- };
65633
- }
65634
- function catalogueRows(provider, models) {
65635
- if (provider.kind !== void 0 && provider.kind !== "http" || provider.catalogue === void 0) {
65636
- return [];
65637
- }
65638
- const { tier } = provider.catalogue;
65639
- return filterCatalogue(models, provider.catalogue).map((model) => ({ model: model.id, label: labelOf(model.id), description: describedAs(model.id, model.name === void 0 ? "Listed by the provider" : `Listed by the provider as ${model.name}`), behavesAs: TIER_BEHAVES_AS[tier] })).sort((left, right) => left.model.localeCompare(right.model));
65640
- }
65641
- function providerModelRows(provider, catalogue = []) {
65642
- const derived2 = provider.kind === "codex" ? codexRows(provider) : provider.kind === "antigravity" ? antigravityRows(provider) : provider.kind === "router" ? [] : httpRows(provider);
65643
- const declared = provider.kind === "router" ? [] : (provider.pickerModels ?? []).map(declaredRow);
65644
- const declaredModels = new Set(declared.map((row) => row.model));
65645
- const named = [...derived2.filter((row) => !declaredModels.has(row.model)), ...declared];
65646
- const taken = new Set(named.map((row) => labelOf(row.model)));
65647
- return [...named, ...catalogueRows(provider, catalogue).filter((row) => !taken.has(labelOf(row.model)))];
65648
- }
65649
- function routedModelRows(models, providers) {
65650
- const hidden = new Set(models.hide ?? []);
65651
- const shown = models.show === void 0 ? void 0 : new Set(models.show);
65652
- const visible = (model) => shown === void 0 ? !hidden.has(model) : shown.has(model);
65653
- const tierOf = (model) => {
65654
- for (const [, provider] of providers) {
65655
- if (provider.kind !== void 0 && provider.kind !== "http") {
65656
- continue;
65657
- }
65658
- const match = Object.entries(provider.env ?? {}).find(([key, value2]) => value2 === model && key.startsWith("ANTHROPIC_DEFAULT_") && key.endsWith("_MODEL"));
65659
- if (match !== void 0) {
65660
- const tier = match[0].replace("ANTHROPIC_DEFAULT_", "").replace("_MODEL", "").toLowerCase();
65661
- return tier === "fable" || tier === "opus" || tier === "sonnet" || tier === "haiku" ? tier : void 0;
65662
- }
65663
- }
65664
- return void 0;
65665
- };
65666
- const virtual = Object.entries(models.virtual ?? {}).flatMap(([name, definition]) => {
65667
- if (!visible(name)) {
65668
- return [];
65669
- }
65670
- const first = definition.members.find((member) => member.includes("/"));
65671
- const tier = first === void 0 ? void 0 : tierOf(first.split("/").slice(1).join("/"));
65672
- const behavesAs = tier === void 0 ? void 0 : TIER_BEHAVES_AS[tier];
65673
- return behavesAs === void 0 ? [] : [{ model: name, label: name, description: `Virtual (${definition.mode})`, behavesAs }];
65674
- });
65675
- const concrete = providers.flatMap(([name, provider]) => providerModelRows(provider).map((row) => ({ ...row, model: `${name}/${row.model}`, label: `${name} / ${row.label}`, description: `${name}: ${row.description}` })));
65676
- return [...virtual, ...concrete.filter((row) => visible(row.model))];
65677
- }
65678
- function modelPickerSettings(provider, catalogue = []) {
65679
- return modelPickerSettingsFromRows(providerModelRows(provider, catalogue), true);
65680
- }
65681
- function modelPickerSettingsFromRows(options, replaceBuiltInOptions) {
65682
- return options.length === 0 ? void 0 : JSON.stringify({ modelPicker: { options, replaceBuiltInOptions } });
65683
- }
65684
- var TIER_BEHAVES_AS, TIER_ENV_VARIABLES;
65685
- var init_modelPicker = __esm({
65686
- "src/launcher/modelPicker.ts"() {
65687
- "use strict";
65688
- init_translate();
65689
- init_translate2();
65690
- init_providerCatalogue();
65691
- init_schema();
65692
- init_identity2();
65693
- TIER_BEHAVES_AS = Object.freeze({
65694
- fable: "claude-fable-5-1",
65695
- opus: "claude-opus-5-5",
65696
- sonnet: "claude-sonnet-5-5",
65697
- haiku: "claude-haiku-5-5"
65698
- });
65699
- TIER_ENV_VARIABLES = Object.freeze({
65700
- fable: "ANTHROPIC_DEFAULT_FABLE_MODEL",
65701
- opus: "ANTHROPIC_DEFAULT_OPUS_MODEL",
65702
- sonnet: "ANTHROPIC_DEFAULT_SONNET_MODEL",
65703
- haiku: "ANTHROPIC_DEFAULT_HAIKU_MODEL"
65704
- });
65705
- }
65706
- });
65707
-
65708
65709
  // src/modelsStore.ts
65709
65710
  function readModels(paths) {
65710
65711
  return readGlobalConfig(paths)?.models;
@@ -65855,6 +65856,148 @@ var init_modelsStore = __esm({
65855
65856
  }
65856
65857
  });
65857
65858
 
65859
+ // src/launcher/modelPicker.ts
65860
+ function labelOf(model) {
65861
+ return withoutContextMarker(model);
65862
+ }
65863
+ function describedAs(model, description) {
65864
+ return model.toLowerCase().endsWith(CONTEXT_MARKER_1M) ? `${description}; 1M context` : description;
65865
+ }
65866
+ function joined(parts) {
65867
+ const last = parts[parts.length - 1];
65868
+ return last === void 0 || parts.length === 1 ? last ?? "" : `${parts.slice(0, -1).join(", ")} and ${last}`;
65869
+ }
65870
+ function rowOf(model, reaches) {
65871
+ const lead = reaches.find((reach) => reach.standing === "first") ?? reaches[0];
65872
+ if (lead === void 0) {
65873
+ throw new Error(`model ${model} is reached by no tier`);
65874
+ }
65875
+ const firsts = reaches.filter((reach) => reach.standing === "first").map((reach) => reach.tier);
65876
+ const fallbacks = reaches.filter((reach) => reach.standing === "fallback").map((reach) => reach.tier);
65877
+ const serves = firsts.length === 0 ? [] : [`Serves the ${joined(firsts)} tier${firsts.length === 1 ? "" : "s"}`];
65878
+ const falls = fallbacks.length === 0 ? [] : [`${serves.length === 0 ? "Fallback" : "fallback"} for ${joined(fallbacks)}`];
65879
+ return { model, label: labelOf(model), description: describedAs(model, [...serves, ...falls].join("; ")), behavesAs: TIER_BEHAVES_AS[lead.tier] };
65880
+ }
65881
+ function rowsOfTable(table) {
65882
+ const reachesByModel = /* @__PURE__ */ new Map();
65883
+ for (const [tier, candidates] of table) {
65884
+ candidates.forEach((model, index) => {
65885
+ const reaches = reachesByModel.get(model) ?? [];
65886
+ if (!reaches.some((reach) => reach.tier === tier)) {
65887
+ reaches.push({ tier, standing: index === 0 ? "first" : "fallback" });
65888
+ }
65889
+ reachesByModel.set(model, reaches);
65890
+ });
65891
+ }
65892
+ return [...reachesByModel].map(([model, reaches]) => rowOf(model, reaches));
65893
+ }
65894
+ function antigravityRows(provider) {
65895
+ const config2 = resolveAntigravityConfig(provider.antigravity);
65896
+ const tiers = rowsOfTable(CLAUDE_TIERS.map((tier) => [tier, config2.models[tier]]));
65897
+ const behavesAsOf = new Map(tiers.map((row) => [row.model, row.behavesAs]));
65898
+ const aliases = [...config2.aliases].flatMap(([alias, candidates]) => {
65899
+ const [first] = candidates;
65900
+ const behavesAs = first === void 0 ? void 0 : behavesAsOf.get(first);
65901
+ const description = alias === AUTO_ALIAS ? `Routes each request to a backend model with quota left, best first (${String(candidates.length)} models)` : `Alias for ${candidates.join(", then ")}`;
65902
+ return behavesAs === void 0 ? [] : [{ model: alias, label: labelOf(alias), description, behavesAs }];
65903
+ });
65904
+ return [...aliases.filter((row) => row.model === AUTO_ALIAS), ...tiers, ...aliases.filter((row) => row.model !== AUTO_ALIAS)];
65905
+ }
65906
+ function codexRows(provider) {
65907
+ const config2 = resolveCodexConfig(provider.codex);
65908
+ return rowsOfTable(CLAUDE_TIERS.map((tier) => [tier, [config2.models[tier]]]));
65909
+ }
65910
+ function httpRows(provider) {
65911
+ const env = provider.env ?? {};
65912
+ const table = CLAUDE_TIERS.flatMap((tier) => {
65913
+ const model = env[TIER_ENV_VARIABLES[tier]];
65914
+ return model === void 0 || model === "" ? [] : [[tier, [model]]];
65915
+ });
65916
+ return rowsOfTable(table);
65917
+ }
65918
+ function declaredRow(entry) {
65919
+ return {
65920
+ model: entry.model,
65921
+ label: entry.label ?? labelOf(entry.model),
65922
+ description: entry.description ?? describedAs(entry.model, `Declared by the provider for the ${entry.tier} tier`),
65923
+ behavesAs: TIER_BEHAVES_AS[entry.tier]
65924
+ };
65925
+ }
65926
+ function catalogueRows(provider, models) {
65927
+ if (provider.kind !== void 0 && provider.kind !== "http" || provider.catalogue === void 0) {
65928
+ return [];
65929
+ }
65930
+ const { tier } = provider.catalogue;
65931
+ return filterCatalogue(models, provider.catalogue).map((model) => ({ model: model.id, label: labelOf(model.id), description: describedAs(model.id, model.name === void 0 ? "Listed by the provider" : `Listed by the provider as ${model.name}`), behavesAs: TIER_BEHAVES_AS[tier] })).sort((left, right) => left.model.localeCompare(right.model));
65932
+ }
65933
+ function providerModelRows(provider, catalogue = []) {
65934
+ const derived2 = provider.kind === "codex" ? codexRows(provider) : provider.kind === "antigravity" ? antigravityRows(provider) : provider.kind === "router" ? [] : httpRows(provider);
65935
+ const declared = provider.kind === "router" ? [] : (provider.pickerModels ?? []).map(declaredRow);
65936
+ const declaredModels = new Set(declared.map((row) => row.model));
65937
+ const named = [...derived2.filter((row) => !declaredModels.has(row.model)), ...declared];
65938
+ const taken = new Set(named.map((row) => labelOf(row.model)));
65939
+ return [...named, ...catalogueRows(provider, catalogue).filter((row) => !taken.has(labelOf(row.model)))];
65940
+ }
65941
+ function routedModelRows(models, providers) {
65942
+ const hidden = new Set(models.hide ?? []);
65943
+ const shown = models.show === void 0 ? void 0 : new Set(models.show);
65944
+ const visible = (model) => shown === void 0 ? !hidden.has(model) : shown.has(model);
65945
+ const concrete = providers.flatMap(([name, provider]) => providerModelRows(provider).map((row) => ({ ...row, model: `${name}/${row.model}`, label: `${name} / ${row.label}`, description: `${name}: ${row.description}` })));
65946
+ const concreteByRef = new Map(concrete.map((row) => [row.model, row]));
65947
+ const families = buildFamilies([...concrete.map((row) => row.model), ...accountRefsOf(models)], models);
65948
+ const handlingOf = (refs) => refs.map((ref) => concreteByRef.get(ref)?.behavesAs).find((behavesAs) => behavesAs !== void 0) ?? TIER_BEHAVES_AS.sonnet;
65949
+ const virtual = Object.entries(models.virtual ?? {}).flatMap(([name, definition]) => {
65950
+ if (!visible(name)) {
65951
+ return [];
65952
+ }
65953
+ const targets = expandFamilyMembers(safeExpand(name, models), families);
65954
+ return [{ model: name, label: name, description: `Virtual (${definition.mode})`, behavesAs: handlingOf(targets) }];
65955
+ });
65956
+ const familyRows = sharedFamilies(families).flatMap((family) => {
65957
+ const member = `${FAMILY_PREFIX}${family.key}`;
65958
+ return visible(member) ? [{ model: member, label: family.key, description: `Family (${familyMode(family.settings)}): ${family.refs.join(", ")}`, behavesAs: handlingOf(family.refs) }] : [];
65959
+ });
65960
+ return [...virtual, ...familyRows, ...concrete.filter((row) => visible(row.model))];
65961
+ }
65962
+ function safeExpand(name, models) {
65963
+ try {
65964
+ return expandMembers(name, models);
65965
+ } catch {
65966
+ return models.virtual?.[name]?.members ?? [];
65967
+ }
65968
+ }
65969
+ function modelPickerSettings(provider, catalogue = []) {
65970
+ return modelPickerSettingsFromRows(providerModelRows(provider, catalogue), true);
65971
+ }
65972
+ function modelPickerSettingsFromRows(options, replaceBuiltInOptions) {
65973
+ return options.length === 0 ? void 0 : JSON.stringify({ modelPicker: { options, replaceBuiltInOptions } });
65974
+ }
65975
+ var TIER_BEHAVES_AS, TIER_ENV_VARIABLES;
65976
+ var init_modelPicker = __esm({
65977
+ "src/launcher/modelPicker.ts"() {
65978
+ "use strict";
65979
+ init_translate();
65980
+ init_translate2();
65981
+ init_providerCatalogue();
65982
+ init_schema();
65983
+ init_identity2();
65984
+ init_families();
65985
+ init_modelsStore();
65986
+ TIER_BEHAVES_AS = Object.freeze({
65987
+ fable: "claude-fable-5-1",
65988
+ opus: "claude-opus-5-5",
65989
+ sonnet: "claude-sonnet-5-5",
65990
+ haiku: "claude-haiku-5-5"
65991
+ });
65992
+ TIER_ENV_VARIABLES = Object.freeze({
65993
+ fable: "ANTHROPIC_DEFAULT_FABLE_MODEL",
65994
+ opus: "ANTHROPIC_DEFAULT_OPUS_MODEL",
65995
+ sonnet: "ANTHROPIC_DEFAULT_SONNET_MODEL",
65996
+ haiku: "ANTHROPIC_DEFAULT_HAIKU_MODEL"
65997
+ });
65998
+ }
65999
+ });
66000
+
65858
66001
  // src/launcher/pool.ts
65859
66002
  function isResuming(passthrough) {
65860
66003
  const end = passthrough.indexOf(TERMINATOR3);
@@ -66054,6 +66197,26 @@ var init_launchHook = __esm({
66054
66197
  }
66055
66198
  });
66056
66199
 
66200
+ // src/models/targets.ts
66201
+ function providerModels(paths) {
66202
+ return listProviders(paths).flatMap((entry) => {
66203
+ const catalogue = parseCatalogueCache(realFsPort.readFileUtf8(catalogueCachePath(paths, entry.name)));
66204
+ return providerModelRows(entry.provider, catalogue?.models).map((row) => ({ provider: entry.name, model: row.model }));
66205
+ });
66206
+ }
66207
+ function targetRefs(paths) {
66208
+ return providerModels(paths).map((entry) => `${entry.provider}/${entry.model}`);
66209
+ }
66210
+ var init_targets = __esm({
66211
+ "src/models/targets.ts"() {
66212
+ "use strict";
66213
+ init_modelPicker();
66214
+ init_providerCatalogue();
66215
+ init_providersStore();
66216
+ init_realPorts();
66217
+ }
66218
+ });
66219
+
66057
66220
  // src/launcher.ts
66058
66221
  function resolveIdentityCredential(identity, credential, env, port) {
66059
66222
  if (port === void 0) {
@@ -66245,10 +66408,12 @@ function decideLaunch(params, readOnly) {
66245
66408
  }
66246
66409
  const launchCascade = farmContext?.cascade ?? (params.farm === void 0 ? void 0 : params.farm.loadCascade(configProfileDecision.name, cliOverride));
66247
66410
  let cascadeLaunch;
66411
+ let cascadeModels;
66248
66412
  if (launchCascade !== void 0 && params.farm !== void 0) {
66249
66413
  const assembled = assembleCascade(launchCascade);
66250
66414
  const flattened = flattenLayers(assembled.layers, { home: params.farm.home });
66251
66415
  cascadeLaunch = flattened.launch;
66416
+ cascadeModels = flattened.models;
66252
66417
  if (readOnly || farmContext === void 0) {
66253
66418
  reportDiagnostics(log, [...assembled.diagnostics, ...flattened.diagnostics], { errorsAsWarnings: readOnly });
66254
66419
  }
@@ -66277,7 +66442,9 @@ function decideLaunch(params, readOnly) {
66277
66442
  const flags = loginlessProvider === void 0 ? requestedFlags : { ...requestedFlags, remoteControl: false };
66278
66443
  const catalogue = selectedProvider === void 0 ? void 0 : parseCatalogueCache(params.fs.readFileUtf8(catalogueCachePath(paths, selectedProvider.name)));
66279
66444
  const routesByName = flags.routeByName || selectedProvider !== void 0 && isRouterProvider(selectedProvider.definition);
66280
- const pickerSettings = routesByName ? modelPickerSettingsFromRows(routedModelRows(readModels(paths) ?? {}, listProviders(paths).map((entry) => [entry.name, entry.provider])), selectedProvider !== void 0) : selectedProvider === void 0 ? void 0 : modelPickerSettings(selectedProvider.definition, catalogue?.models);
66445
+ const globalModels = loadConfigFile(paths.globalConfigFile, GlobalConfigSchema, params.fs.readConfigFile)?.config.models;
66446
+ const models = launchCascade !== void 0 && params.farm !== void 0 ? cascadeModels : globalModels;
66447
+ const pickerSettings = routesByName ? modelPickerSettingsFromRows(routedModelRows(models ?? {}, listProviders(paths).map((entry) => [entry.name, entry.provider])), selectedProvider !== void 0) : selectedProvider === void 0 ? void 0 : modelPickerSettings(selectedProvider.definition, catalogue?.models);
66281
66448
  const callerSettings = hasSettingsArgument(parsedArgv.rest);
66282
66449
  if (pickerSettings !== void 0 && callerSettings) {
66283
66450
  notes.push("--settings was passed, so /model keeps Claude Code's own model names");
@@ -66315,6 +66482,8 @@ function decideLaunch(params, readOnly) {
66315
66482
  identityCredential,
66316
66483
  pinnedVersion,
66317
66484
  flags,
66485
+ models,
66486
+ globalModels,
66318
66487
  bin: discovered.path,
66319
66488
  args,
66320
66489
  decision
@@ -66381,7 +66550,7 @@ function prepareLaunch(params) {
66381
66550
  }
66382
66551
  const routesByName = resolvedFlags.routeByName || resolvedProvider !== void 0 && isRouterProvider(resolvedProvider.definition);
66383
66552
  if (routesByName) {
66384
- const check2 = resolveRoutedProviderCredentials({ paths, port: params.fs, env, ...params.credentials === void 0 ? {} : { credentials: params.credentials }, models: loadConfigFile(paths.globalConfigFile, GlobalConfigSchema, params.fs.readConfigFile)?.config.models });
66553
+ const check2 = resolveRoutedProviderCredentials({ paths, port: params.fs, env, ...params.credentials === void 0 ? {} : { credentials: params.credentials }, models: decided.models, targets: () => targetRefs(paths) });
66385
66554
  if (!check2.ok) {
66386
66555
  log.error(check2.message);
66387
66556
  proc.exit(check2.status);
@@ -66393,7 +66562,10 @@ function prepareLaunch(params) {
66393
66562
  log.error("agent-shim: this launch routes through the front-door daemon, but this launcher has no front-door port wired; refusing to launch without it.");
66394
66563
  proc.exit(1);
66395
66564
  }
66396
- const frontDoor = frontDoorEngaged && frontDoorPort !== void 0 ? frontDoorPort.ensure(env.NODE_EXTRA_CA_CERTS) : void 0;
66565
+ const sessionId = params.supervised?.sessionId ?? (0, import_node_crypto18.randomUUID)();
66566
+ const resolvedModels = decided.models ?? (decided.globalModels === void 0 ? void 0 : {});
66567
+ const sessionModels = (0, import_node_util6.isDeepStrictEqual)(resolvedModels, decided.globalModels) ? void 0 : resolvedModels;
66568
+ const frontDoor = frontDoorEngaged && frontDoorPort !== void 0 ? frontDoorPort.ensure(env.NODE_EXTRA_CA_CERTS, { sessionId, ...sessionModels === void 0 ? {} : { models: sessionModels } }) : void 0;
66397
66569
  if (frontDoor?.trustWarning !== void 0) {
66398
66570
  log.warn(frontDoor.trustWarning);
66399
66571
  }
@@ -66407,7 +66579,6 @@ function prepareLaunch(params) {
66407
66579
  }
66408
66580
  rows.push(...routingRows({ frontDoor, headroom, provider: resolvedProvider !== void 0 }));
66409
66581
  const frontDoorRelease = frontDoor === void 0 ? void 0 : frontDoorPort?.release;
66410
- const sessionId = params.supervised?.sessionId ?? (0, import_node_crypto18.randomUUID)();
66411
66582
  const finalEnv = buildEnv({
66412
66583
  baseEnv: env,
66413
66584
  configDirEscapeHatch: configDirEscapeHatchApplies,
@@ -66419,7 +66590,8 @@ function prepareLaunch(params) {
66419
66590
  ...headroom === void 0 ? {} : { headroom },
66420
66591
  sessionId,
66421
66592
  remoteControl: resolvedFlags.remoteControl,
66422
- routeByName: routesByName
66593
+ routeByName: routesByName,
66594
+ ...decided.models?.tiers === void 0 ? {} : { tierModels: decided.models.tiers }
66423
66595
  });
66424
66596
  const releases = [...headroom === void 0 || headroomPort === void 0 ? [] : [headroomPort.release], ...frontDoorRelease === void 0 ? [] : [frontDoorRelease]];
66425
66597
  const release = () => {
@@ -66481,11 +66653,12 @@ function runLaunchPlan(plan, spawn8) {
66481
66653
  function runLauncher(params) {
66482
66654
  params.proc.exit(runLaunchPlan(prepareLaunch(params), params.spawn));
66483
66655
  }
66484
- var import_node_crypto18, import_node_path44;
66656
+ var import_node_crypto18, import_node_util6, import_node_path44;
66485
66657
  var init_launcher = __esm({
66486
66658
  "src/launcher.ts"() {
66487
66659
  "use strict";
66488
66660
  import_node_crypto18 = require("node:crypto");
66661
+ import_node_util6 = require("node:util");
66489
66662
  import_node_path44 = __toESM(require("node:path"), 1);
66490
66663
  init_package();
66491
66664
  init_envBool();
@@ -66502,7 +66675,6 @@ var init_launcher = __esm({
66502
66675
  init_launchReport();
66503
66676
  init_modelPicker();
66504
66677
  init_providerCatalogue();
66505
- init_modelsStore();
66506
66678
  init_providersStore();
66507
66679
  init_pool();
66508
66680
  init_resumeContext();
@@ -66520,6 +66692,7 @@ var init_launcher = __esm({
66520
66692
  init_read();
66521
66693
  init_claudeVersion();
66522
66694
  init_launchHook();
66695
+ init_targets();
66523
66696
  }
66524
66697
  });
66525
66698
 
@@ -119819,56 +119992,7 @@ init_source();
119819
119992
 
119820
119993
  // src/models/doctor.ts
119821
119994
  init_modelsStore();
119822
-
119823
- // src/models/families.ts
119824
- init_identity2();
119825
- var FAMILY_PREFIX = "family:";
119826
- var VARIANT_SEPARATOR = "+";
119827
- function modelOf2(ref) {
119828
- const slash = ref.indexOf("/");
119829
- return slash === -1 ? ref : ref.slice(slash + 1);
119830
- }
119831
- function familyKeyOf(rawModel) {
119832
- const identity = modelIdentity(rawModel);
119833
- return identity.variant === "" ? identity.familyAndVersion : `${identity.familyAndVersion}${VARIANT_SEPARATOR}${identity.variant}`;
119834
- }
119835
- function assertionsOf(models) {
119836
- return { same: models?.same ?? [], distinct: models?.distinct ?? [] };
119837
- }
119838
- function sameModel(left, right, assertions) {
119839
- if (assertions.distinct.some(([a10, b]) => a10 === left && b === right || a10 === right && b === left)) {
119840
- return false;
119841
- }
119842
- const leftGroup = assertions.same.find((group) => group.includes(left));
119843
- const rightGroup = assertions.same.find((group) => group.includes(right));
119844
- if (leftGroup !== void 0 && leftGroup === rightGroup) {
119845
- return true;
119846
- }
119847
- if (leftGroup !== void 0 && !leftGroup.includes(right) || rightGroup !== void 0 && !rightGroup.includes(left)) {
119848
- return false;
119849
- }
119850
- return relateModels(modelOf2(left), modelOf2(right)) === "same";
119851
- }
119852
- function pinnedTo(settings2, ref) {
119853
- return settings2?.names?.some((name) => name === ref || name === modelOf2(ref)) === true;
119854
- }
119855
- function buildFamilies(refs, models) {
119856
- const assertions = assertionsOf(models);
119857
- const settingsByKey = models?.families ?? {};
119858
- const groups = [];
119859
- for (const ref of refs) {
119860
- const pinnedKey = Object.entries(settingsByKey).find(([, settings2]) => pinnedTo(settings2, ref))?.[0];
119861
- const joined2 = groups.find((group) => pinnedKey === void 0 ? group.refs.some((first) => sameModel(first, ref, assertions)) : group.key === pinnedKey);
119862
- if (joined2 !== void 0) {
119863
- joined2.refs.push(ref);
119864
- } else {
119865
- groups.push({ key: pinnedKey ?? familyKeyOf(modelOf2(ref)), refs: [ref] });
119866
- }
119867
- }
119868
- return groups.map((group) => ({ key: group.key, refs: group.refs, settings: settingsByKey[group.key] ?? {} }));
119869
- }
119870
-
119871
- // src/models/doctor.ts
119995
+ init_families();
119872
119996
  init_identity2();
119873
119997
  function modelsFindings(input2) {
119874
119998
  const findings = [];
@@ -119956,22 +120080,8 @@ function modelsFindings(input2) {
119956
120080
  return findings;
119957
120081
  }
119958
120082
 
119959
- // src/models/targets.ts
119960
- init_modelPicker();
119961
- init_providerCatalogue();
119962
- init_providersStore();
119963
- init_realPorts();
119964
- function providerModels(paths) {
119965
- return listProviders(paths).flatMap((entry) => {
119966
- const catalogue = parseCatalogueCache(realFsPort.readFileUtf8(catalogueCachePath(paths, entry.name)));
119967
- return providerModelRows(entry.provider, catalogue?.models).map((row) => ({ provider: entry.name, model: row.model }));
119968
- });
119969
- }
119970
- function targetRefs(paths) {
119971
- return providerModels(paths).map((entry) => `${entry.provider}/${entry.model}`);
119972
- }
119973
-
119974
120083
  // src/doctorReport.ts
120084
+ init_targets();
119975
120085
  init_configProfilesStore();
119976
120086
 
119977
120087
  // src/headroom/allowlistDrift.ts
@@ -131698,6 +131808,7 @@ init_quotaFacts();
131698
131808
  init_modelsStore();
131699
131809
 
131700
131810
  // src/selection/candidates.ts
131811
+ var MIN_PROJECTION_ELAPSED_SHARE = 0.1;
131701
131812
  var WINDOW_PERIOD_HOURS = { fiveHour: 5, sevenDay: 168, extraUsage: 168 };
131702
131813
  function candidateOf(ref, order, facts, isCurrent) {
131703
131814
  const present = Object.entries(facts.quota ?? {}).map(([name, window]) => ({ name, ...window }));
@@ -131710,6 +131821,15 @@ function candidateOf(ref, order, facts, isCurrent) {
131710
131821
  return period > 0 && window.hoursUntilReset > 0 ? window.remaining / (window.hoursUntilReset / period) : Number.NaN;
131711
131822
  })
131712
131823
  );
131824
+ const runsDry = present.some((window) => {
131825
+ const period = WINDOW_PERIOD_HOURS[window.name] ?? Number.NaN;
131826
+ const elapsed = period - window.hoursUntilReset;
131827
+ if (!(elapsed >= period * MIN_PROJECTION_ELAPSED_SHARE) || window.hoursUntilReset <= 0) {
131828
+ return false;
131829
+ }
131830
+ const pace = (1 - window.remaining) / elapsed;
131831
+ return pace > 0 && window.remaining / pace < window.hoursUntilReset;
131832
+ });
131713
131833
  return {
131714
131834
  ref,
131715
131835
  order,
@@ -131717,8 +131837,7 @@ function candidateOf(ref, order, facts, isCurrent) {
131717
131837
  ...remainingAllowance === void 0 ? {} : { remainingAllowance },
131718
131838
  ...hoursToReset === void 0 ? {} : { hoursToReset },
131719
131839
  ...pressure === void 0 || Number.isNaN(pressure) ? {} : { pressure },
131720
- // 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.
131721
- feasible: available,
131840
+ feasible: available && !runsDry,
131722
131841
  ...facts.observation?.latencyMs === void 0 ? {} : { latencyMs: facts.observation.latencyMs },
131723
131842
  ...facts.observation?.successRate === void 0 ? {} : { successRate: facts.observation.successRate },
131724
131843
  ...facts.price === void 0 || facts.observation?.tokenMix === void 0 ? {} : { pricePerMTok: blendedPricePerMTok(facts.price, facts.observation.tokenMix) },
@@ -131728,6 +131847,7 @@ function candidateOf(ref, order, facts, isCurrent) {
131728
131847
 
131729
131848
  // src/frontdoor/providerRoute.ts
131730
131849
  init_engine();
131850
+ init_families();
131731
131851
  init_identity2();
131732
131852
  init_route();
131733
131853
  var import_node_stream3 = require("node:stream");
@@ -131818,37 +131938,45 @@ function scopeSessionProviderPath(request7) {
131818
131938
  }
131819
131939
  return { ...request7, url: `${PROVIDER_PATH_PREFIX}${encodeURIComponent(request7.session.provider)}${request7.url}` };
131820
131940
  }
131821
- function resolveRoutedModel(model, providerName, session, includeUnqualified, deps, memory, rotations) {
131822
- const models = deps.models?.();
131941
+ var CHARS_PER_TOKEN2 = 4;
131942
+ function needsOf(scan) {
131943
+ return { hasImage: scan.hasImage === true, hasTools: scan.toolsPresent === true, thinking: scan.thinking === true, contextTokens: Math.ceil((scan.text?.length ?? 0) / CHARS_PER_TOKEN2) };
131944
+ }
131945
+ function resolveRoutedModel(model, providerName, session, includeUnqualified, deps, memory, rotations, needs) {
131946
+ const models = deps.models?.(session);
131823
131947
  const qualified = model.includes("/") && !model.startsWith("acct:") ? model : void 0;
131824
131948
  if (qualified !== void 0) {
131825
131949
  const [provider2, ...rest2] = qualified.split("/");
131826
131950
  const named = rest2.join("/");
131827
131951
  return provider2 === void 0 || named === "" ? void 0 : { provider: provider2, model: withoutContextMarker(named), ref: qualified };
131828
131952
  }
131829
- const virtual = models?.virtual?.[model];
131830
- if (virtual === void 0 || !includeUnqualified) {
131953
+ const isFamily = model.startsWith(FAMILY_PREFIX);
131954
+ const virtual = isFamily ? void 0 : models?.virtual?.[model];
131955
+ if (virtual === void 0 && !isFamily || !includeUnqualified) {
131831
131956
  return void 0;
131832
131957
  }
131833
- const members2 = expandMembers(model, models).filter((member) => !member.startsWith("acct:") && !member.startsWith("family:"));
131958
+ const declared = isFamily ? [model] : expandMembers(model, models);
131959
+ const families = isFamily || declared.some((member) => member.startsWith(FAMILY_PREFIX)) || models?.families !== void 0 ? buildFamilies(deps.targets?.() ?? [], models) : [];
131960
+ const mode = virtual?.mode ?? familyMode(familyNamed(families, model)?.settings ?? {});
131961
+ const members2 = expandFamilyMembers(declared, families).filter((member) => !member.startsWith("acct:"));
131834
131962
  if (members2.length === 0) {
131835
131963
  return void 0;
131836
131964
  }
131837
131965
  const snapshot = deps.usageSnapshotOf?.(session.identity);
131838
131966
  const current = memory.get(session.sessionId ?? "");
131839
- const candidates = members2.map((ref, order) => {
131967
+ const evaluated = members2.map((ref, order) => {
131840
131968
  const [provider2] = ref.split("/");
131841
131969
  const facts = quotaFactsOf(snapshot?.providers[provider2 ?? ""]?.rateLimit?.unified, Date.now());
131842
- return candidateOf(ref, order, {
131970
+ const candidate = candidateOf(ref, order, {
131843
131971
  quota: facts,
131844
131972
  ...deps.observations?.(ref) === void 0 ? {} : { observation: deps.observations(ref) },
131845
131973
  ...models?.prices?.[ref] === void 0 ? {} : { price: models.prices[ref] }
131846
131974
  }, ref === current);
131975
+ return { candidate, capabilities: familyCapabilities(familyOfRef(families, ref)?.settings ?? {}) };
131847
131976
  });
131848
- const evaluated = candidates.map((candidate) => ({ candidate, capabilities: { vision: true, tools: true, thinking: true } }));
131849
131977
  const rotation = rotations.get(model) ?? 0;
131850
131978
  rotations.set(model, rotation + 1);
131851
- const selection = selectMember(virtual.mode, evaluated, { rotation });
131979
+ const selection = selectMember(mode, evaluated, { rotation, ...needs === void 0 ? {} : { needs } });
131852
131980
  if (selection.ref === void 0) {
131853
131981
  return void 0;
131854
131982
  }
@@ -132011,6 +132139,7 @@ function createProviderRouteResolver(deps) {
132011
132139
  const serveScoped = (resolution) => scopedRequest === request7 ? resolution : { ok: true, route: servingRewritten(resolution.route, scopedRequest) };
132012
132140
  let current = scopedRequest;
132013
132141
  let replay;
132142
+ let nameResolved = false;
132014
132143
  const visited = /* @__PURE__ */ new Set();
132015
132144
  for (; ; ) {
132016
132145
  const path65 = new URL(current.url, "http://127.0.0.1").pathname;
@@ -132032,7 +132161,7 @@ function createProviderRouteResolver(deps) {
132032
132161
  routes = void 0;
132033
132162
  isRouter = false;
132034
132163
  }
132035
- const routesByName = (isRouter || current.session.routeByName) && !isRcSelfHostPath(path65);
132164
+ const routesByName = !nameResolved && (isRouter || current.session.routeByName) && !isRcSelfHostPath(path65);
132036
132165
  if (routesByName) {
132037
132166
  const scan2 = await scanRequestHead(current, true);
132038
132167
  if (scan2.replayed === void 0) {
@@ -132040,7 +132169,7 @@ function createProviderRouteResolver(deps) {
132040
132169
  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;
132041
132170
  }
132042
132171
  replay = scan2.replayed;
132043
- const account = scan2.model === void 0 ? void 0 : resolveAccountTarget(scan2.model, deps.models?.());
132172
+ const account = scan2.model === void 0 ? void 0 : resolveAccountTarget(scan2.model, deps.models?.(current.session));
132044
132173
  if (account !== void 0) {
132045
132174
  const sessionId = current.session.sessionId ?? "";
132046
132175
  const moved = sessionId !== "" && (deps.accountMoves?.(sessionId, account.identity, account.model) ?? false);
@@ -132050,7 +132179,7 @@ function createProviderRouteResolver(deps) {
132050
132179
  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`
132051
132180
  };
132052
132181
  }
132053
- const routed = scan2.model === void 0 ? void 0 : resolveRoutedModel(scan2.model, providerName, current.session, isRouter || providerName !== void 0, deps, routingMemory, rotations);
132182
+ const routed = scan2.model === void 0 ? void 0 : resolveRoutedModel(scan2.model, providerName, current.session, isRouter || providerName !== void 0, deps, routingMemory, rotations, needsOf(scan2));
132054
132183
  const requested = scan2.model;
132055
132184
  if (routed !== void 0) {
132056
132185
  routingMemory.set(current.session.sessionId ?? "", routed.ref);
@@ -132069,6 +132198,7 @@ function createProviderRouteResolver(deps) {
132069
132198
  const query2 = current.url.includes("?") ? current.url.slice(current.url.indexOf("?")) : "";
132070
132199
  const carried = replay;
132071
132200
  current = { ...current, url: `${PROVIDER_PATH_PREFIX}${encodeURIComponent(routed.provider)}${rest2}${query2}`, body: carried.body, headers: carried.headers };
132201
+ nameResolved = true;
132072
132202
  continue;
132073
132203
  }
132074
132204
  const resolution = resolve2(current);
@@ -134555,6 +134685,9 @@ data: ${JSON.stringify(envelope)}
134555
134685
  };
134556
134686
  }
134557
134687
 
134688
+ // src/frontdoor/commands.ts
134689
+ init_targets();
134690
+
134558
134691
  // src/frontdoor/rcStream.ts
134559
134692
  var RC_STREAM_EVENT_NAME2 = "client_event";
134560
134693
  var SSE_BYTE_ORDER_MARK = 65279;
@@ -135233,7 +135366,9 @@ function realFrontDoorSupervisorPorts(paths) {
135233
135366
  const resolveRoute = rcObservingResolver(
135234
135367
  createProviderRouteResolver({
135235
135368
  // Read live so a models-block edit reaches the next request without a door restart.
135236
- models: () => readModels(paths),
135369
+ // The block this session launched with when its directory, profile or committed file added definitions of its own; otherwise the global block, read live so an edit applies to the next request with no relaunch.
135370
+ models: (session) => (session.sessionId === void 0 ? void 0 : readFrontDoorSessionModels(realFarmFs, paths.frontdoorSessionsDir, session.sessionId)) ?? readModels(paths),
135371
+ targets: () => targetRefs(paths),
135237
135372
  fs: realFsPort,
135238
135373
  providersDir: paths.providersDir,
135239
135374
  codexPorts,
@@ -147821,8 +147956,10 @@ function registerProviderCommand(program2, deps) {
147821
147956
 
147822
147957
  // src/models.ts
147823
147958
  init_commandDeps();
147959
+ init_targets();
147824
147960
  init_schema();
147825
147961
  init_cliError();
147962
+ init_families();
147826
147963
  init_identity2();
147827
147964
  init_modelsStore();
147828
147965
  init_realPorts();
@@ -147852,32 +147989,35 @@ function providerQuotaOf(paths) {
147852
147989
  return snapshot === void 0 ? {} : quotaFactsOf(snapshot.providers[provider]?.rateLimit?.unified, Date.now());
147853
147990
  };
147854
147991
  }
147855
- function describeUnroutedMembers(members2) {
147992
+ function describeUnroutedMembers(members2, families) {
147856
147993
  return members2.flatMap((member) => {
147857
147994
  if (member.startsWith("acct:")) {
147858
147995
  const [identity] = member.slice("acct:".length).split("/");
147859
147996
  return [`${member} is served by relaunching the session under identity "${identity ?? ""}", so no quota signal ranks it`];
147860
147997
  }
147861
- return member.startsWith("family:") ? [`${member} is resolved from the live catalogues, which the door does not read yet, so it is not a candidate`] : [];
147998
+ return member.startsWith(FAMILY_PREFIX) && familyNamed(families, member) === void 0 ? [`no target the providers offer belongs to ${member}, so it has nothing to choose among`] : [];
147862
147999
  });
147863
148000
  }
147864
148001
  function explainVirtualModel(paths, name) {
147865
148002
  const models = readModels(paths);
147866
- const definition = models?.virtual?.[name];
147867
- if (definition === void 0) {
148003
+ const virtual = models?.virtual?.[name];
148004
+ const families = buildFamilies(targetRefs(paths), models);
148005
+ const isFamily = name.startsWith(FAMILY_PREFIX);
148006
+ if (virtual === void 0 && !isFamily) {
147868
148007
  throw new UsageError(`No virtual model named "${name}".`);
147869
148008
  }
148009
+ const mode = virtual?.mode ?? familyMode(familyNamed(families, name)?.settings ?? {});
147870
148010
  const quotaOf = providerQuotaOf(paths);
147871
148011
  const observations = createTargetObservationStore(realFarmFs, paths);
147872
- const members2 = expandMembers(name, models);
147873
- const candidates = members2.filter((member) => !member.startsWith("acct:") && !member.startsWith("family:")).map((ref, order) => {
148012
+ const members2 = isFamily ? [name] : expandMembers(name, models);
148013
+ const candidates = expandFamilyMembers(members2, families).filter((member) => !member.startsWith("acct:")).map((ref, order) => {
147874
148014
  const [provider] = ref.split("/");
147875
148015
  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);
147876
148016
  });
147877
- const evaluated = candidates.map((candidate) => ({ candidate, capabilities: { vision: true, tools: true, thinking: true } }));
147878
- const selection = selectMember(definition.mode, evaluated, {});
147879
- const unrouted = describeUnroutedMembers(members2);
147880
- console.log(`${name} (${definition.mode}) chooses ${selection.ref ?? (candidates.length === 0 ? "nothing by quota" : "nothing")}:`);
148017
+ const evaluated = candidates.map((candidate) => ({ candidate, capabilities: familyCapabilities(familyOfRef(families, candidate.ref)?.settings ?? {}) }));
148018
+ const selection = selectMember(mode, evaluated, {});
148019
+ const unrouted = describeUnroutedMembers(members2, families);
148020
+ console.log(`${name} (${mode}) chooses ${selection.ref ?? (candidates.length === 0 ? "nothing by quota" : "nothing")}:`);
147881
148021
  for (const line of candidates.length === 0 ? unrouted : [...selection.reasons, ...unrouted]) {
147882
148022
  console.log(` ${line}`);
147883
148023
  }
@@ -147909,7 +148049,7 @@ function registerModelsCommand(program2, deps) {
147909
148049
  const { paths } = deps;
147910
148050
  const modelsCommand = program2.command("model").description("Define and inspect the models the providers offer and the virtual models chosen among them.");
147911
148051
  withExamples(
147912
- 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) => {
148052
+ modelsCommand.command("explain <name>").description("Show which member a virtual model's (or a family row's) mode picks over the live signals, and why each candidate stands where it does.").action((name) => {
147913
148053
  explainVirtualModel(paths, name);
147914
148054
  }),
147915
148055
  ["agent-shim model explain fast"]