claude-use 11.16.0 → 11.17.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
@@ -26906,7 +26906,7 @@ function isTimeZone(name) {
26906
26906
  return false;
26907
26907
  }
26908
26908
  }
26909
- var import_node_path4, CATEGORY_NAMES, OVERRIDABLE_CATEGORIES, CategoryMapSchema, DURATION_RE, DurationSchema, WhenConditionObjectSchema, WhenSchema, EntryValueSchema, ENTRY_KEY_RE, EntriesSchema, LaunchSchema, CREDENTIAL_TARGETS, PROVIDER_CREDENTIAL_TARGETS, CREDENTIAL_TARGET_VARS, ArgvSchema, CommandSourceOptions, EnvCredentialSourceSchema, FileCredentialSourceSchema, CommandCredentialSourceSchema, OpCredentialSourceSchema, KeychainCredentialSourceSchema, LiteralCredentialSourceSchema, CredentialSourceSchema, RemoteCredentialSourceSchema, CREDENTIAL_CACHE_STORES, CredentialCacheSchema, CredentialSchema, ProviderCredentialSchema, RESERVED_PROVIDER_ENV_KEYS, ProviderEnvSchema, PROVIDER_KINDS, ANTIGRAVITY_MODES, ANTIGRAVITY_TIERS, ANTIGRAVITY_EFFORTS, ANTIGRAVITY_DEFAULT_MODE, ANTIGRAVITY_DEFAULT_MODEL, ANTIGRAVITY_DEFAULT_TIER_MODELS, ANTIGRAVITY_DEFAULT_EFFORT, AntigravityProviderConfigSchema, CODEX_TIERS, CODEX_EFFORTS, CODEX_LOGINS, CODEX_DEFAULT_LOGIN, CODEX_DEFAULT_MODEL, CODEX_DEFAULT_TIER_MODELS, CODEX_DEFAULT_EFFORT, CodexProviderConfigSchema, ProviderRouteSchema, HttpProviderSchema, CodexProviderSchema, AntigravityProviderSchema, ProviderSchema, ConfigProfileSchema, POOL_SELECTOR_PREFIX, POOL_NAME_PATTERN, IDENTITY_NAME_PATTERN, PoolNameSchema, SELECTOR_RE, IdentitySelectorSchema, PoolMemberSchema, POOL_PREFERENCES, PoolPreferenceSchema, PoolSchema, WEEKDAYS, AnchorSchema, JOB_WINDOWS, JobTriggerSchema, JobTargetSchema, JobSchema, DirectoryRuleSchema, DirectoryRulesSchema, PortableConfigSchema, HEADROOM_MODES, HEADROOM_CCR_MODES, HEADROOM_ROLLOUT_CHANNELS, INTERCEPT_CHANNELS, READ_MATURATION_CHANNELS, HeadroomGlobalConfigObjectSchema, HeadroomGlobalConfigSchema, HEADROOM_DEFAULT_SOURCE, HEADROOM_DEFAULT_IDLE_SHUTDOWN_MINUTES, FRONTDOOR_DEFAULT_IDLE_SHUTDOWN_MINUTES, FrontDoorGlobalConfigSchema, UPDATE_MODES, UpdateGlobalConfigSchema, GlobalConfigSchema, IdentitySchema, CategoryClassificationSchema, CategoryClassificationOverlaySchema, SHIPPED_CATEGORY_DEFAULTS;
26909
+ var import_node_path4, CATEGORY_NAMES, OVERRIDABLE_CATEGORIES, CategoryMapSchema, DURATION_RE, DurationSchema, WhenConditionObjectSchema, WhenSchema, EntryValueSchema, ENTRY_KEY_RE, EntriesSchema, LaunchSchema, CREDENTIAL_TARGETS, PROVIDER_CREDENTIAL_TARGETS, CREDENTIAL_TARGET_VARS, ArgvSchema, CommandSourceOptions, EnvCredentialSourceSchema, FileCredentialSourceSchema, CommandCredentialSourceSchema, OpCredentialSourceSchema, KeychainCredentialSourceSchema, LiteralCredentialSourceSchema, CredentialSourceSchema, RemoteCredentialSourceSchema, CREDENTIAL_CACHE_STORES, CredentialCacheSchema, CredentialSchema, ProviderCredentialSchema, RESERVED_PROVIDER_ENV_KEYS, ProviderEnvSchema, PROVIDER_KINDS, ANTIGRAVITY_MODES, ANTIGRAVITY_TIERS, ANTIGRAVITY_EFFORTS, ANTIGRAVITY_DEFAULT_MODE, ANTIGRAVITY_DEFAULT_MODEL, ANTIGRAVITY_DEFAULT_TIER_MODELS, ANTIGRAVITY_DEFAULT_EFFORT, AntigravityModelTargetSchema, AntigravityProviderConfigSchema, CODEX_TIERS, CODEX_EFFORTS, CODEX_LOGINS, CODEX_DEFAULT_LOGIN, CODEX_DEFAULT_MODEL, CODEX_DEFAULT_TIER_MODELS, CODEX_DEFAULT_EFFORT, CodexProviderConfigSchema, ProviderRouteSchema, HttpProviderSchema, CodexProviderSchema, AntigravityProviderSchema, ProviderSchema, ConfigProfileSchema, POOL_SELECTOR_PREFIX, POOL_NAME_PATTERN, IDENTITY_NAME_PATTERN, PoolNameSchema, SELECTOR_RE, IdentitySelectorSchema, PoolMemberSchema, POOL_PREFERENCES, PoolPreferenceSchema, PoolSchema, WEEKDAYS, AnchorSchema, JOB_WINDOWS, JobTriggerSchema, JobTargetSchema, JobSchema, DirectoryRuleSchema, DirectoryRulesSchema, PortableConfigSchema, HEADROOM_MODES, HEADROOM_CCR_MODES, HEADROOM_ROLLOUT_CHANNELS, INTERCEPT_CHANNELS, READ_MATURATION_CHANNELS, HeadroomGlobalConfigObjectSchema, HeadroomGlobalConfigSchema, HEADROOM_DEFAULT_SOURCE, HEADROOM_DEFAULT_IDLE_SHUTDOWN_MINUTES, FRONTDOOR_DEFAULT_IDLE_SHUTDOWN_MINUTES, FrontDoorGlobalConfigSchema, UPDATE_MODES, UpdateGlobalConfigSchema, GlobalConfigSchema, IdentitySchema, CategoryClassificationSchema, CategoryClassificationOverlaySchema, SHIPPED_CATEGORY_DEFAULTS;
26910
26910
  var init_schema = __esm({
26911
26911
  "src/config/schema.ts"() {
26912
26912
  "use strict";
@@ -27012,19 +27012,20 @@ var init_schema = __esm({
27012
27012
  ANTIGRAVITY_DEFAULT_MODE = "cloud";
27013
27013
  ANTIGRAVITY_DEFAULT_MODEL = "gemini-3.8-flash-high";
27014
27014
  ANTIGRAVITY_DEFAULT_TIER_MODELS = Object.freeze({
27015
- fable: "gemini-3.8-flash-high",
27016
- opus: "gemini-3.8-flash-high",
27017
- sonnet: "gemini-3.8-flash-medium",
27018
- haiku: "gemini-3.8-flash-low"
27015
+ fable: ["claude-opus-5-5-high", "gemini-4-argon-high", "gemini-3.8-flash-high"],
27016
+ opus: ["claude-opus-5-5-high", "gemini-4-argon-high", "gemini-3.8-flash-high"],
27017
+ sonnet: ["claude-sonnet-5-5-medium", "gemini-4-argon-medium", "gemini-3.8-flash-medium"],
27018
+ haiku: ["gemini-3.8-flash-low", "gemini-4-argon-low", "gpt-oss-120b-medium"]
27019
27019
  });
27020
27020
  ANTIGRAVITY_DEFAULT_EFFORT = "low";
27021
+ AntigravityModelTargetSchema = external_exports.union([external_exports.string().min(1), external_exports.array(external_exports.string().min(1)).min(1)]);
27021
27022
  AntigravityProviderConfigSchema = external_exports.strictObject({
27022
27023
  /** Operational mode: direct cloud endpoint or local ACP daemon. Defaults to `cloud`. */
27023
27024
  mode: external_exports.enum(ANTIGRAVITY_MODES).optional(),
27024
27025
  /** The model a request maps to when no tier matches its model name. */
27025
27026
  defaultModel: external_exports.string().min(1).optional(),
27026
- /** Model name mapping. A key naming a tier (`fable`, `opus`, `sonnet`, `haiku`) overrides that tier's shipped model and is matched by substring of the requested name in `ANTIGRAVITY_TIERS` order; any other key is an alias, matched against the whole requested name case-insensitively, so `/model <alias>` selects its backend model. An alias outranks every other rule, including the pass-through of backend names. */
27027
- models: external_exports.record(external_exports.string().min(1), external_exports.string().min(1)).optional(),
27027
+ /** Model name mapping. A key naming a tier (`fable`, `opus`, `sonnet`, `haiku`) overrides that tier's shipped model and is matched by substring of the requested name in `ANTIGRAVITY_TIERS` order; any other key is an alias, matched against the whole requested name case-insensitively, so `/model <alias>` selects its backend model. An alias outranks every other rule, including the pass-through of backend names. A value is one model or an ordered list of candidates: the request goes to the first whose quota windows are not spent, and when every candidate is spent, to the one whose binding window lifts soonest. */
27028
+ models: external_exports.record(external_exports.string().min(1), AntigravityModelTargetSchema).optional(),
27028
27029
  /** The reasoning effort used when the request's own effort is not one the backend accepts. */
27029
27030
  effort: external_exports.enum(ANTIGRAVITY_EFFORTS).optional(),
27030
27031
  /** Cloud-specific settings (for `mode: "cloud"`). */
@@ -34088,7 +34089,7 @@ var init_package = __esm({
34088
34089
  "package.json"() {
34089
34090
  package_default = {
34090
34091
  name: "claude-use",
34091
- version: "11.16.0",
34092
+ version: "11.17.0",
34092
34093
  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.",
34093
34094
  license: "MIT",
34094
34095
  author: "Joseph Mearman <joseph@mearman.co.uk>",
@@ -127766,6 +127767,256 @@ function translateRequest(body, config2) {
127766
127767
  // src/antigravity/translate.ts
127767
127768
  var import_node_crypto21 = require("node:crypto");
127768
127769
 
127770
+ // src/antigravity/quota.ts
127771
+ init_cloudUpstream();
127772
+ var MS_PER_SECOND8 = 1e3;
127773
+ var DEFAULT_RETRY_AFTER_SECONDS = 60;
127774
+ var FRACTION_DIGITS = 3;
127775
+ var GEMINI_5H_KEYS = ["gemini-5h", "gemini_5h", "gemini"];
127776
+ var GEMINI_WEEKLY_KEYS = ["gemini-weekly", "gemini_weekly"];
127777
+ var ARGON_WEEKLY_KEYS = ["gemini-argon-wtu-weekly"];
127778
+ var THIRD_PARTY_5H_KEYS = ["3p-5h", "claude-5h", "3p_5h", "claude_5h", "claude"];
127779
+ var THIRD_PARTY_WEEKLY_KEYS = ["3p-weekly", "claude-weekly", "3p_weekly", "claude_weekly"];
127780
+ function findBucket(quota, keys) {
127781
+ for (const key of keys) {
127782
+ const bucket = quota[key];
127783
+ if (bucket !== void 0) {
127784
+ return bucket;
127785
+ }
127786
+ }
127787
+ return void 0;
127788
+ }
127789
+ var QUOTA_FAMILY_WINDOWS = [
127790
+ { label: "Gem 5h", keys: GEMINI_5H_KEYS },
127791
+ { label: "Gem Wk", keys: GEMINI_WEEKLY_KEYS },
127792
+ { label: "3P 5h", keys: THIRD_PARTY_5H_KEYS },
127793
+ { label: "3P Wk", keys: THIRD_PARTY_WEEKLY_KEYS },
127794
+ { label: "Argon Wk", keys: ARGON_WEEKLY_KEYS }
127795
+ ];
127796
+ function antigravityFamilyBuckets(quota) {
127797
+ return QUOTA_FAMILY_WINDOWS.flatMap(({ label, keys }) => {
127798
+ const bucket = findBucket(quota, keys);
127799
+ return bucket === void 0 ? [] : [{ label, bucket }];
127800
+ });
127801
+ }
127802
+ function selectAntigravityBuckets(quota, model) {
127803
+ const lower = (model ?? "").toLowerCase();
127804
+ if (lower.includes("argon")) {
127805
+ return { fiveHour: void 0, weekly: findBucket(quota, ARGON_WEEKLY_KEYS) };
127806
+ }
127807
+ const isGemini = lower.includes("gemini");
127808
+ return {
127809
+ fiveHour: findBucket(quota, isGemini ? GEMINI_5H_KEYS : THIRD_PARTY_5H_KEYS),
127810
+ weekly: findBucket(quota, isGemini ? GEMINI_WEEKLY_KEYS : THIRD_PARTY_WEEKLY_KEYS)
127811
+ };
127812
+ }
127813
+ var SECONDS_PER_HOUR2 = 3600;
127814
+ var HOURS_PER_FIVE_HOUR_WINDOW = 5;
127815
+ var DAYS_PER_WEEK2 = 7;
127816
+ var HOURS_PER_DAY5 = 24;
127817
+ var FIVE_HOUR_PERIOD_SECONDS = HOURS_PER_FIVE_HOUR_WINDOW * SECONDS_PER_HOUR2;
127818
+ var WEEK_PERIOD_SECONDS = DAYS_PER_WEEK2 * HOURS_PER_DAY5 * SECONDS_PER_HOUR2;
127819
+ function windowPressure(bucket, periodSeconds) {
127820
+ const remaining = bucket?.remaining_fraction;
127821
+ const resetIn = bucket?.reset_in_seconds;
127822
+ if (remaining === void 0 || resetIn === void 0 || !Number.isFinite(remaining) || !Number.isFinite(resetIn)) {
127823
+ return void 0;
127824
+ }
127825
+ const periodLeft = Math.min(1, Math.max(resetIn, 1) / periodSeconds);
127826
+ return Math.max(0, remaining) / periodLeft;
127827
+ }
127828
+ function antigravityQuotaPressure(quota, model) {
127829
+ const { fiveHour, weekly } = selectAntigravityBuckets(quota ?? {}, model);
127830
+ const pressures = [windowPressure(fiveHour, FIVE_HOUR_PERIOD_SECONDS), windowPressure(weekly, WEEK_PERIOD_SECONDS)].filter((pressure) => pressure !== void 0);
127831
+ return pressures.length === 0 ? void 0 : Math.min(...pressures);
127832
+ }
127833
+ function calculateUtilization(remainingFraction) {
127834
+ if (remainingFraction === void 0 || !Number.isFinite(remainingFraction)) {
127835
+ return void 0;
127836
+ }
127837
+ const clampedRem = Math.max(0, Math.min(1, remainingFraction));
127838
+ const used = Math.max(0, 1 - clampedRem);
127839
+ return used.toFixed(FRACTION_DIGITS);
127840
+ }
127841
+ function calculateResetTimestamp(nowSec, resetInSeconds) {
127842
+ if (resetInSeconds === void 0 || !Number.isFinite(resetInSeconds) || resetInSeconds < 0) {
127843
+ return void 0;
127844
+ }
127845
+ return String(nowSec + Math.ceil(resetInSeconds));
127846
+ }
127847
+ function parseRetryAfterSeconds(raw, defaultSeconds = DEFAULT_RETRY_AFTER_SECONDS) {
127848
+ if (raw === null || raw === void 0 || raw.trim() === "") {
127849
+ return defaultSeconds;
127850
+ }
127851
+ const numeric = Number(raw);
127852
+ if (Number.isFinite(numeric) && numeric > 0) {
127853
+ return Math.ceil(numeric);
127854
+ }
127855
+ const parsedDate = Date.parse(raw);
127856
+ if (!Number.isNaN(parsedDate)) {
127857
+ const diffSec = Math.ceil((parsedDate - Date.now()) / MS_PER_SECOND8);
127858
+ return Math.max(1, diffSec);
127859
+ }
127860
+ return defaultSeconds;
127861
+ }
127862
+ function unifiedAntigravityQuotaHeaders(params) {
127863
+ const rejected = params.rejected === true;
127864
+ const nowSec = Math.floor(params.nowMs / MS_PER_SECOND8);
127865
+ const { fiveHour: b5h, weekly: bWk } = selectAntigravityBuckets(params.quota ?? {}, params.model);
127866
+ const used5h = calculateUtilization(b5h?.remaining_fraction);
127867
+ const reset5h = calculateResetTimestamp(nowSec, b5h?.reset_in_seconds);
127868
+ const used7d = calculateUtilization(bWk?.remaining_fraction);
127869
+ const reset7d = calculateResetTimestamp(nowSec, bWk?.reset_in_seconds);
127870
+ const exhaustion = rejected ? antigravityQuotaExhaustion(params.quota, params.model, params.nowMs) : void 0;
127871
+ if (rejected && exhaustion === void 0) {
127872
+ return {};
127873
+ }
127874
+ if (!rejected && used5h === void 0 && reset5h === void 0 && used7d === void 0 && reset7d === void 0) {
127875
+ return {};
127876
+ }
127877
+ const headers = {
127878
+ "anthropic-ratelimit-unified-status": rejected ? "rejected" : "allowed"
127879
+ };
127880
+ let earliestResetSec;
127881
+ if (used5h !== void 0 && reset5h !== void 0) {
127882
+ headers["anthropic-ratelimit-unified-5h-utilization"] = used5h;
127883
+ headers["anthropic-ratelimit-unified-5h-reset"] = reset5h;
127884
+ earliestResetSec = Number(reset5h);
127885
+ if (rejected) {
127886
+ headers["anthropic-ratelimit-unified-5h-status"] = exhaustion?.exhaustedWindows.includes("five_hour") === true ? "rejected" : "allowed";
127887
+ }
127888
+ }
127889
+ if (used7d !== void 0 && reset7d !== void 0) {
127890
+ headers["anthropic-ratelimit-unified-7d-utilization"] = used7d;
127891
+ headers["anthropic-ratelimit-unified-7d-reset"] = reset7d;
127892
+ const reset7dSec = Number(reset7d);
127893
+ earliestResetSec = earliestResetSec === void 0 ? reset7dSec : Math.min(earliestResetSec, reset7dSec);
127894
+ if (rejected) {
127895
+ headers["anthropic-ratelimit-unified-7d-status"] = exhaustion?.exhaustedWindows.includes("seven_day") === true ? "rejected" : "allowed";
127896
+ }
127897
+ }
127898
+ if (exhaustion !== void 0) {
127899
+ headers["anthropic-ratelimit-unified-representative-claim"] = exhaustion.window;
127900
+ headers["anthropic-ratelimit-unified-reset"] = String(exhaustion.resetSec);
127901
+ headers["retry-after"] = String(Math.max(1, exhaustion.resetSec - nowSec));
127902
+ headers["x-should-retry"] = "false";
127903
+ return headers;
127904
+ }
127905
+ if (earliestResetSec !== void 0) {
127906
+ headers["anthropic-ratelimit-unified-reset"] = String(earliestResetSec);
127907
+ }
127908
+ return headers;
127909
+ }
127910
+ function antigravityQuotaExhaustion(quota, model, nowMs) {
127911
+ const { fiveHour, weekly } = selectAntigravityBuckets(quota ?? {}, model);
127912
+ const nowSec = Math.floor(nowMs / MS_PER_SECOND8);
127913
+ const spent = [];
127914
+ for (const [window, bucket] of [["five_hour", fiveHour], ["seven_day", weekly]]) {
127915
+ const remaining = bucket?.remaining_fraction;
127916
+ const resetIn = bucket?.reset_in_seconds;
127917
+ if (remaining !== void 0 && Number.isFinite(remaining) && remaining <= 0 && resetIn !== void 0 && Number.isFinite(resetIn) && resetIn >= 0) {
127918
+ spent.push({ window, resetSec: nowSec + Math.ceil(resetIn) });
127919
+ }
127920
+ }
127921
+ const binding = spent.reduce((latest, next) => latest === void 0 || next.resetSec > latest.resetSec ? next : latest, void 0);
127922
+ return binding === void 0 ? void 0 : { window: binding.window, resetSec: binding.resetSec, exhaustedWindows: spent.map((entry) => entry.window) };
127923
+ }
127924
+ function isRecord8(value2) {
127925
+ return typeof value2 === "object" && value2 !== null && !Array.isArray(value2);
127926
+ }
127927
+ function bucketToEntry(bucket, nowMs) {
127928
+ if (!isRecord8(bucket) || typeof bucket.bucketId !== "string") {
127929
+ return void 0;
127930
+ }
127931
+ const remainingFraction = typeof bucket.remainingFraction === "number" && Number.isFinite(bucket.remainingFraction) ? bucket.remainingFraction : void 0;
127932
+ const resetMs = typeof bucket.resetTime === "string" ? Date.parse(bucket.resetTime) : Number.NaN;
127933
+ const resetInSeconds = Number.isNaN(resetMs) ? void 0 : Math.max(0, Math.ceil((resetMs - nowMs) / MS_PER_SECOND8));
127934
+ if (remainingFraction === void 0 && resetInSeconds === void 0) {
127935
+ return void 0;
127936
+ }
127937
+ return {
127938
+ key: bucket.bucketId,
127939
+ entry: {
127940
+ ...remainingFraction === void 0 ? {} : { remaining_fraction: remainingFraction },
127941
+ ...resetInSeconds === void 0 ? {} : { reset_in_seconds: resetInSeconds }
127942
+ }
127943
+ };
127944
+ }
127945
+ async function fetchAntigravityQuotaSummary(params) {
127946
+ const fetchFn = params.fetchFn ?? fetch;
127947
+ let response;
127948
+ try {
127949
+ response = await fetchFn(`${params.endpoint ?? CCPA_ENDPOINT}/v1internal:retrieveUserQuotaSummary`, {
127950
+ method: "POST",
127951
+ headers: {
127952
+ "Content-Type": "application/json",
127953
+ Authorization: `Bearer ${params.token}`,
127954
+ "User-Agent": CCPA_USER_AGENT
127955
+ },
127956
+ body: JSON.stringify({ project: params.projectId ?? CCPA_DEFAULT_PROJECT_ID })
127957
+ });
127958
+ } catch {
127959
+ return void 0;
127960
+ }
127961
+ if (!response.ok) {
127962
+ return void 0;
127963
+ }
127964
+ let parsed;
127965
+ try {
127966
+ parsed = await response.json();
127967
+ } catch {
127968
+ return void 0;
127969
+ }
127970
+ if (!isRecord8(parsed) || !Array.isArray(parsed.groups)) {
127971
+ return void 0;
127972
+ }
127973
+ const map2 = {};
127974
+ for (const group of parsed.groups) {
127975
+ if (!isRecord8(group) || !Array.isArray(group.buckets)) {
127976
+ continue;
127977
+ }
127978
+ for (const bucket of group.buckets) {
127979
+ const read = bucketToEntry(bucket, params.nowMs);
127980
+ if (read !== void 0) {
127981
+ map2[read.key] = read.entry;
127982
+ }
127983
+ }
127984
+ }
127985
+ return Object.keys(map2).length > 0 ? map2 : void 0;
127986
+ }
127987
+ var ANTIGRAVITY_QUOTA_REFRESH_MS = 6e4;
127988
+ function createCachedAntigravityQuotaSource(params) {
127989
+ let cachedAt = Number.NEGATIVE_INFINITY;
127990
+ let cached2;
127991
+ let readAtMs = Number.NEGATIVE_INFINITY;
127992
+ let refresh;
127993
+ const refreshMs = params.refreshMs ?? ANTIGRAVITY_QUOTA_REFRESH_MS;
127994
+ const run = async () => {
127995
+ const nowMs = params.now();
127996
+ const read = await params.fetchSummary(nowMs);
127997
+ if (read !== void 0) {
127998
+ cached2 = read;
127999
+ readAtMs = nowMs;
128000
+ }
128001
+ cachedAt = params.now();
128002
+ };
128003
+ return () => {
128004
+ const nowMs = params.now();
128005
+ if (nowMs - cachedAt >= refreshMs) {
128006
+ refresh ??= run().finally(() => {
128007
+ refresh = void 0;
128008
+ });
128009
+ }
128010
+ return cached2 === void 0 ? void 0 : ageQuotaMap(cached2, nowMs - readAtMs);
128011
+ };
128012
+ }
128013
+ function ageQuotaMap(quota, elapsedMs) {
128014
+ const elapsedSec = elapsedMs / MS_PER_SECOND8;
128015
+ return Object.fromEntries(
128016
+ Object.entries(quota).map(([key, bucket]) => [key, bucket?.reset_in_seconds === void 0 ? bucket : { ...bucket, reset_in_seconds: Math.max(0, bucket.reset_in_seconds - elapsedSec) }])
128017
+ );
128018
+ }
128019
+
127769
128020
  // src/antigravity/signatures.ts
127770
128021
  var UNVERIFIED_THOUGHT_SIGNATURE = "skip_thought_signature_validator";
127771
128022
  var MAX_REMEMBERED = 1024;
@@ -127785,26 +128036,28 @@ function toolCallSignatureOf(toolUseId) {
127785
128036
 
127786
128037
  // src/antigravity/translate.ts
127787
128038
  init_schema();
128039
+ function candidatesOf(target) {
128040
+ return typeof target === "string" ? [target] : target;
128041
+ }
127788
128042
  function isAntigravityTier(key) {
127789
128043
  return ANTIGRAVITY_TIERS.some((tier) => tier === key);
127790
128044
  }
127791
128045
  function resolveAntigravityConfig(config2) {
127792
128046
  const overrides = config2?.models ?? {};
127793
128047
  const aliases = /* @__PURE__ */ new Map();
127794
- for (const [key, model] of Object.entries(overrides)) {
128048
+ for (const [key, target] of Object.entries(overrides)) {
127795
128049
  if (!isAntigravityTier(key)) {
127796
- aliases.set(key.toLowerCase(), model);
128050
+ aliases.set(key.toLowerCase(), candidatesOf(target));
127797
128051
  }
127798
128052
  }
128053
+ const tierModel = (tier) => {
128054
+ const target = overrides[tier];
128055
+ return target === void 0 ? ANTIGRAVITY_DEFAULT_TIER_MODELS[tier] : candidatesOf(target);
128056
+ };
127799
128057
  return {
127800
128058
  mode: config2?.mode ?? ANTIGRAVITY_DEFAULT_MODE,
127801
128059
  defaultModel: config2?.defaultModel ?? ANTIGRAVITY_DEFAULT_MODEL,
127802
- models: {
127803
- fable: overrides.fable ?? ANTIGRAVITY_DEFAULT_TIER_MODELS.fable,
127804
- opus: overrides.opus ?? ANTIGRAVITY_DEFAULT_TIER_MODELS.opus,
127805
- sonnet: overrides.sonnet ?? ANTIGRAVITY_DEFAULT_TIER_MODELS.sonnet,
127806
- haiku: overrides.haiku ?? ANTIGRAVITY_DEFAULT_TIER_MODELS.haiku
127807
- },
128060
+ models: { fable: tierModel("fable"), opus: tierModel("opus"), sonnet: tierModel("sonnet"), haiku: tierModel("haiku") },
127808
128061
  aliases,
127809
128062
  effort: config2?.effort ?? ANTIGRAVITY_DEFAULT_EFFORT,
127810
128063
  cloud: {
@@ -127832,10 +128085,45 @@ function mapModel2(requested, config2) {
127832
128085
  return alias;
127833
128086
  }
127834
128087
  if (isBackendModelName(stripped)) {
127835
- return stripped;
128088
+ return [stripped];
127836
128089
  }
127837
128090
  const tier = ANTIGRAVITY_TIERS.find((candidate) => lower.includes(candidate));
127838
- return tier === void 0 ? config2.defaultModel : config2.models[tier];
128091
+ return tier === void 0 ? [config2.defaultModel] : config2.models[tier];
128092
+ }
128093
+ function chooseCandidate(candidates, routing) {
128094
+ const first = candidates[0];
128095
+ if (first === void 0) {
128096
+ throw new Error("A model target holds at least one candidate");
128097
+ }
128098
+ if (routing === void 0 || candidates.length === 1) {
128099
+ return first;
128100
+ }
128101
+ if (routing.previous !== void 0 && candidates.includes(routing.previous) && antigravityQuotaExhaustion(routing.quota, routing.previous, routing.nowMs) === void 0) {
128102
+ return routing.previous;
128103
+ }
128104
+ const unspent = candidates.filter((model) => antigravityQuotaExhaustion(routing.quota, model, routing.nowMs) === void 0);
128105
+ if (unspent[0] === first) {
128106
+ return first;
128107
+ }
128108
+ const neutral = 1;
128109
+ let best;
128110
+ for (const model of unspent) {
128111
+ const pressure = antigravityQuotaPressure(routing.quota, model) ?? neutral;
128112
+ if (best === void 0 || pressure > best.pressure) {
128113
+ best = { model, pressure };
128114
+ }
128115
+ }
128116
+ if (best !== void 0) {
128117
+ return best.model;
128118
+ }
128119
+ let soonest;
128120
+ for (const model of candidates) {
128121
+ const exhaustion = antigravityQuotaExhaustion(routing.quota, model, routing.nowMs);
128122
+ if (exhaustion !== void 0 && (soonest === void 0 || exhaustion.resetSec < soonest.resetSec)) {
128123
+ soonest = { model, resetSec: exhaustion.resetSec };
128124
+ }
128125
+ }
128126
+ return soonest?.model ?? first;
127839
128127
  }
127840
128128
  var EFFORT_TO_BUDGET = {
127841
128129
  none: 0,
@@ -127900,7 +128188,7 @@ function turnBlocks2(message) {
127900
128188
  }
127901
128189
  return blocks.map((block2) => isTextBlock(block2) ? { ...block2, text: systemReminder2(block2.text) } : block2);
127902
128190
  }
127903
- function isRecord8(value2) {
128191
+ function isRecord9(value2) {
127904
128192
  return typeof value2 === "object" && value2 !== null && !Array.isArray(value2);
127905
128193
  }
127906
128194
  function messagesToGeminiContents(messages, names, toolIdToName) {
@@ -127946,7 +128234,7 @@ function messagesToGeminiContents(messages, names, toolIdToName) {
127946
128234
  ensureRole("model").push({
127947
128235
  functionCall: {
127948
128236
  name: sanitizedName,
127949
- args: isRecord8(block2.input) ? block2.input : {}
128237
+ args: isRecord9(block2.input) ? block2.input : {}
127950
128238
  },
127951
128239
  // The relay remembered the signature the backend attached to this exact call; echoing it back is what the backend requires of a repeated function call. A call with none remembered (made before a door restart, evicted from the bounded store, or produced by another model in a resumed session) gets the backend's documented bypass, since history is resent whole on every request and a single unsigned call would otherwise fail the whole conversation for good.
127952
128240
  thoughtSignature: signature ?? UNVERIFIED_THOUGHT_SIGNATURE
@@ -127968,7 +128256,7 @@ function messagesToGeminiContents(messages, names, toolIdToName) {
127968
128256
  var EMPTY_SCHEMA = { type: "object", properties: {} };
127969
128257
  var GEMINI_SCHEMA_KEYS = /* @__PURE__ */ new Set(["type", "format", "description", "nullable", "enum", "anyOf", "items", "properties", "required", "minimum", "maximum", "minItems", "maxItems"]);
127970
128258
  function describeSchemaValue(node2) {
127971
- if (!isRecord8(node2)) {
128259
+ if (!isRecord9(node2)) {
127972
128260
  return "any value";
127973
128261
  }
127974
128262
  const type2 = node2.type;
@@ -127979,7 +128267,7 @@ function describeSchemaValue(node2) {
127979
128267
  return name === "object" ? "an object" : `a ${name}`;
127980
128268
  }
127981
128269
  function toGeminiSchema(node2) {
127982
- if (!isRecord8(node2)) {
128270
+ if (!isRecord9(node2)) {
127983
128271
  return node2;
127984
128272
  }
127985
128273
  const out = {};
@@ -127997,7 +128285,7 @@ function toGeminiSchema(node2) {
127997
128285
  if (!GEMINI_SCHEMA_KEYS.has(key)) {
127998
128286
  if (key === "additionalProperties" && value2 !== false) {
127999
128287
  notes.push(`Each value is ${describeSchemaValue(value2)}.`);
128000
- } else if (key === "propertyNames" && isRecord8(value2) && typeof value2.pattern === "string") {
128288
+ } else if (key === "propertyNames" && isRecord9(value2) && typeof value2.pattern === "string") {
128001
128289
  notes.push(`Keys match ${value2.pattern}.`);
128002
128290
  }
128003
128291
  continue;
@@ -128014,7 +128302,7 @@ function toGeminiSchema(node2) {
128014
128302
  const description = typeof out.description === "string" ? out.description : "";
128015
128303
  out.description = `${description}${description === "" ? "" : " "}${notes.join(" ")}`;
128016
128304
  }
128017
- if ("properties" in out && isRecord8(out.properties)) {
128305
+ if ("properties" in out && isRecord9(out.properties)) {
128018
128306
  out.properties = Object.fromEntries(Object.entries(out.properties).map(([name, child]) => [name, toGeminiSchema(child)]));
128019
128307
  }
128020
128308
  if ("items" in out) {
@@ -128036,7 +128324,7 @@ function mapTools2(tools, names) {
128036
128324
  return {
128037
128325
  name: shortToolName2(tool.name, names),
128038
128326
  description: tool.description,
128039
- parameters: isRecord8(converted) ? converted : EMPTY_SCHEMA
128327
+ parameters: isRecord9(converted) ? converted : EMPTY_SCHEMA
128040
128328
  };
128041
128329
  });
128042
128330
  return [{ functionDeclarations: declarations }];
@@ -128060,16 +128348,16 @@ function completeEffortSuffix(model, request7, config2) {
128060
128348
  if (splitEffortSuffix(model) !== void 0) {
128061
128349
  return model;
128062
128350
  }
128063
- const configured = [config2.defaultModel, ...Object.values(config2.models), ...config2.aliases.values()];
128351
+ const configured = [config2.defaultModel, ...Object.values(config2.models).flat(), ...[...config2.aliases.values()].flat()];
128064
128352
  const effort = request7.output_config?.effort;
128065
128353
  const level = ANTIGRAVITY_EFFORTS.find((candidate) => candidate === effort) ?? config2.effort;
128066
128354
  const suffixed = `${model}-${effortSuffixOf(level)}`;
128067
128355
  return configured.some((entry) => entry === suffixed || splitEffortSuffix(entry)?.base === model) ? suffixed : model;
128068
128356
  }
128069
- function translateRequest2(request7, config2) {
128357
+ function translateRequest2(request7, config2, routing) {
128070
128358
  const toolNames = /* @__PURE__ */ new Map();
128071
128359
  const toolIdToName = /* @__PURE__ */ new Map();
128072
- const model = completeEffortSuffix(mapModel2(request7.model ?? "", config2), request7, config2);
128360
+ const model = chooseCandidate(mapModel2(request7.model ?? "", config2).map((candidate) => completeEffortSuffix(candidate, request7, config2)), routing);
128073
128361
  const thinkingBudget = mapEffort2(request7, config2);
128074
128362
  const systemInstruction = systemToInstruction(request7.system);
128075
128363
  const contents = messagesToGeminiContents(request7.messages, toolNames, toolIdToName);
@@ -128087,236 +128375,6 @@ function translateRequest2(request7, config2) {
128087
128375
  };
128088
128376
  }
128089
128377
 
128090
- // src/antigravity/quota.ts
128091
- init_cloudUpstream();
128092
- var MS_PER_SECOND8 = 1e3;
128093
- var DEFAULT_RETRY_AFTER_SECONDS = 60;
128094
- var FRACTION_DIGITS = 3;
128095
- var GEMINI_5H_KEYS = ["gemini-5h", "gemini_5h", "gemini"];
128096
- var GEMINI_WEEKLY_KEYS = ["gemini-weekly", "gemini_weekly"];
128097
- var ARGON_WEEKLY_KEYS = ["gemini-argon-wtu-weekly"];
128098
- var THIRD_PARTY_5H_KEYS = ["3p-5h", "claude-5h", "3p_5h", "claude_5h", "claude"];
128099
- var THIRD_PARTY_WEEKLY_KEYS = ["3p-weekly", "claude-weekly", "3p_weekly", "claude_weekly"];
128100
- function findBucket(quota, keys) {
128101
- for (const key of keys) {
128102
- const bucket = quota[key];
128103
- if (bucket !== void 0) {
128104
- return bucket;
128105
- }
128106
- }
128107
- return void 0;
128108
- }
128109
- var QUOTA_FAMILY_WINDOWS = [
128110
- { label: "Gem 5h", keys: GEMINI_5H_KEYS },
128111
- { label: "Gem Wk", keys: GEMINI_WEEKLY_KEYS },
128112
- { label: "3P 5h", keys: THIRD_PARTY_5H_KEYS },
128113
- { label: "3P Wk", keys: THIRD_PARTY_WEEKLY_KEYS },
128114
- { label: "Argon Wk", keys: ARGON_WEEKLY_KEYS }
128115
- ];
128116
- function antigravityFamilyBuckets(quota) {
128117
- return QUOTA_FAMILY_WINDOWS.flatMap(({ label, keys }) => {
128118
- const bucket = findBucket(quota, keys);
128119
- return bucket === void 0 ? [] : [{ label, bucket }];
128120
- });
128121
- }
128122
- function selectAntigravityBuckets(quota, model) {
128123
- const lower = (model ?? "").toLowerCase();
128124
- if (lower.includes("argon")) {
128125
- return { fiveHour: void 0, weekly: findBucket(quota, ARGON_WEEKLY_KEYS) };
128126
- }
128127
- const isGemini = lower.includes("gemini");
128128
- return {
128129
- fiveHour: findBucket(quota, isGemini ? GEMINI_5H_KEYS : THIRD_PARTY_5H_KEYS),
128130
- weekly: findBucket(quota, isGemini ? GEMINI_WEEKLY_KEYS : THIRD_PARTY_WEEKLY_KEYS)
128131
- };
128132
- }
128133
- function calculateUtilization(remainingFraction) {
128134
- if (remainingFraction === void 0 || !Number.isFinite(remainingFraction)) {
128135
- return void 0;
128136
- }
128137
- const clampedRem = Math.max(0, Math.min(1, remainingFraction));
128138
- const used = Math.max(0, 1 - clampedRem);
128139
- return used.toFixed(FRACTION_DIGITS);
128140
- }
128141
- function calculateResetTimestamp(nowSec, resetInSeconds) {
128142
- if (resetInSeconds === void 0 || !Number.isFinite(resetInSeconds) || resetInSeconds < 0) {
128143
- return void 0;
128144
- }
128145
- return String(nowSec + Math.ceil(resetInSeconds));
128146
- }
128147
- function parseRetryAfterSeconds(raw, defaultSeconds = DEFAULT_RETRY_AFTER_SECONDS) {
128148
- if (raw === null || raw === void 0 || raw.trim() === "") {
128149
- return defaultSeconds;
128150
- }
128151
- const numeric = Number(raw);
128152
- if (Number.isFinite(numeric) && numeric > 0) {
128153
- return Math.ceil(numeric);
128154
- }
128155
- const parsedDate = Date.parse(raw);
128156
- if (!Number.isNaN(parsedDate)) {
128157
- const diffSec = Math.ceil((parsedDate - Date.now()) / MS_PER_SECOND8);
128158
- return Math.max(1, diffSec);
128159
- }
128160
- return defaultSeconds;
128161
- }
128162
- function unifiedAntigravityQuotaHeaders(params) {
128163
- const rejected = params.rejected === true;
128164
- const nowSec = Math.floor(params.nowMs / MS_PER_SECOND8);
128165
- const { fiveHour: b5h, weekly: bWk } = selectAntigravityBuckets(params.quota ?? {}, params.model);
128166
- const used5h = calculateUtilization(b5h?.remaining_fraction);
128167
- const reset5h = calculateResetTimestamp(nowSec, b5h?.reset_in_seconds);
128168
- const used7d = calculateUtilization(bWk?.remaining_fraction);
128169
- const reset7d = calculateResetTimestamp(nowSec, bWk?.reset_in_seconds);
128170
- const exhaustion = rejected ? antigravityQuotaExhaustion(params.quota, params.model, params.nowMs) : void 0;
128171
- if (rejected && exhaustion === void 0) {
128172
- return {};
128173
- }
128174
- if (!rejected && used5h === void 0 && reset5h === void 0 && used7d === void 0 && reset7d === void 0) {
128175
- return {};
128176
- }
128177
- const headers = {
128178
- "anthropic-ratelimit-unified-status": rejected ? "rejected" : "allowed"
128179
- };
128180
- let earliestResetSec;
128181
- if (used5h !== void 0 && reset5h !== void 0) {
128182
- headers["anthropic-ratelimit-unified-5h-utilization"] = used5h;
128183
- headers["anthropic-ratelimit-unified-5h-reset"] = reset5h;
128184
- earliestResetSec = Number(reset5h);
128185
- if (rejected) {
128186
- headers["anthropic-ratelimit-unified-5h-status"] = exhaustion?.exhaustedWindows.includes("five_hour") === true ? "rejected" : "allowed";
128187
- }
128188
- }
128189
- if (used7d !== void 0 && reset7d !== void 0) {
128190
- headers["anthropic-ratelimit-unified-7d-utilization"] = used7d;
128191
- headers["anthropic-ratelimit-unified-7d-reset"] = reset7d;
128192
- const reset7dSec = Number(reset7d);
128193
- earliestResetSec = earliestResetSec === void 0 ? reset7dSec : Math.min(earliestResetSec, reset7dSec);
128194
- if (rejected) {
128195
- headers["anthropic-ratelimit-unified-7d-status"] = exhaustion?.exhaustedWindows.includes("seven_day") === true ? "rejected" : "allowed";
128196
- }
128197
- }
128198
- if (exhaustion !== void 0) {
128199
- headers["anthropic-ratelimit-unified-representative-claim"] = exhaustion.window;
128200
- headers["anthropic-ratelimit-unified-reset"] = String(exhaustion.resetSec);
128201
- headers["retry-after"] = String(Math.max(1, exhaustion.resetSec - nowSec));
128202
- headers["x-should-retry"] = "false";
128203
- return headers;
128204
- }
128205
- if (earliestResetSec !== void 0) {
128206
- headers["anthropic-ratelimit-unified-reset"] = String(earliestResetSec);
128207
- }
128208
- return headers;
128209
- }
128210
- function antigravityQuotaExhaustion(quota, model, nowMs) {
128211
- const { fiveHour, weekly } = selectAntigravityBuckets(quota ?? {}, model);
128212
- const nowSec = Math.floor(nowMs / MS_PER_SECOND8);
128213
- const spent = [];
128214
- for (const [window, bucket] of [["five_hour", fiveHour], ["seven_day", weekly]]) {
128215
- const remaining = bucket?.remaining_fraction;
128216
- const resetIn = bucket?.reset_in_seconds;
128217
- if (remaining !== void 0 && Number.isFinite(remaining) && remaining <= 0 && resetIn !== void 0 && Number.isFinite(resetIn) && resetIn >= 0) {
128218
- spent.push({ window, resetSec: nowSec + Math.ceil(resetIn) });
128219
- }
128220
- }
128221
- const binding = spent.reduce((latest, next) => latest === void 0 || next.resetSec > latest.resetSec ? next : latest, void 0);
128222
- return binding === void 0 ? void 0 : { window: binding.window, resetSec: binding.resetSec, exhaustedWindows: spent.map((entry) => entry.window) };
128223
- }
128224
- function isRecord9(value2) {
128225
- return typeof value2 === "object" && value2 !== null && !Array.isArray(value2);
128226
- }
128227
- function bucketToEntry(bucket, nowMs) {
128228
- if (!isRecord9(bucket) || typeof bucket.bucketId !== "string") {
128229
- return void 0;
128230
- }
128231
- const remainingFraction = typeof bucket.remainingFraction === "number" && Number.isFinite(bucket.remainingFraction) ? bucket.remainingFraction : void 0;
128232
- const resetMs = typeof bucket.resetTime === "string" ? Date.parse(bucket.resetTime) : Number.NaN;
128233
- const resetInSeconds = Number.isNaN(resetMs) ? void 0 : Math.max(0, Math.ceil((resetMs - nowMs) / MS_PER_SECOND8));
128234
- if (remainingFraction === void 0 && resetInSeconds === void 0) {
128235
- return void 0;
128236
- }
128237
- return {
128238
- key: bucket.bucketId,
128239
- entry: {
128240
- ...remainingFraction === void 0 ? {} : { remaining_fraction: remainingFraction },
128241
- ...resetInSeconds === void 0 ? {} : { reset_in_seconds: resetInSeconds }
128242
- }
128243
- };
128244
- }
128245
- async function fetchAntigravityQuotaSummary(params) {
128246
- const fetchFn = params.fetchFn ?? fetch;
128247
- let response;
128248
- try {
128249
- response = await fetchFn(`${params.endpoint ?? CCPA_ENDPOINT}/v1internal:retrieveUserQuotaSummary`, {
128250
- method: "POST",
128251
- headers: {
128252
- "Content-Type": "application/json",
128253
- Authorization: `Bearer ${params.token}`,
128254
- "User-Agent": CCPA_USER_AGENT
128255
- },
128256
- body: JSON.stringify({ project: params.projectId ?? CCPA_DEFAULT_PROJECT_ID })
128257
- });
128258
- } catch {
128259
- return void 0;
128260
- }
128261
- if (!response.ok) {
128262
- return void 0;
128263
- }
128264
- let parsed;
128265
- try {
128266
- parsed = await response.json();
128267
- } catch {
128268
- return void 0;
128269
- }
128270
- if (!isRecord9(parsed) || !Array.isArray(parsed.groups)) {
128271
- return void 0;
128272
- }
128273
- const map2 = {};
128274
- for (const group of parsed.groups) {
128275
- if (!isRecord9(group) || !Array.isArray(group.buckets)) {
128276
- continue;
128277
- }
128278
- for (const bucket of group.buckets) {
128279
- const read = bucketToEntry(bucket, params.nowMs);
128280
- if (read !== void 0) {
128281
- map2[read.key] = read.entry;
128282
- }
128283
- }
128284
- }
128285
- return Object.keys(map2).length > 0 ? map2 : void 0;
128286
- }
128287
- var ANTIGRAVITY_QUOTA_REFRESH_MS = 6e4;
128288
- function createCachedAntigravityQuotaSource(params) {
128289
- let cachedAt = Number.NEGATIVE_INFINITY;
128290
- let cached2;
128291
- let readAtMs = Number.NEGATIVE_INFINITY;
128292
- let refresh;
128293
- const refreshMs = params.refreshMs ?? ANTIGRAVITY_QUOTA_REFRESH_MS;
128294
- const run = async () => {
128295
- const nowMs = params.now();
128296
- const read = await params.fetchSummary(nowMs);
128297
- if (read !== void 0) {
128298
- cached2 = read;
128299
- readAtMs = nowMs;
128300
- }
128301
- cachedAt = params.now();
128302
- };
128303
- return () => {
128304
- const nowMs = params.now();
128305
- if (nowMs - cachedAt >= refreshMs) {
128306
- refresh ??= run().finally(() => {
128307
- refresh = void 0;
128308
- });
128309
- }
128310
- return cached2 === void 0 ? void 0 : ageQuotaMap(cached2, nowMs - readAtMs);
128311
- };
128312
- }
128313
- function ageQuotaMap(quota, elapsedMs) {
128314
- const elapsedSec = elapsedMs / MS_PER_SECOND8;
128315
- return Object.fromEntries(
128316
- Object.entries(quota).map(([key, bucket]) => [key, bucket?.reset_in_seconds === void 0 ? bucket : { ...bucket, reset_in_seconds: Math.max(0, bucket.reset_in_seconds - elapsedSec) }])
128317
- );
128318
- }
128319
-
128320
128378
  // src/frontdoor/providerRoute.ts
128321
128379
  init_credential();
128322
128380
  init_providersStore();
@@ -129273,12 +129331,14 @@ async function* callLocalAntigravity(params) {
129273
129331
 
129274
129332
  // src/antigravity/route.ts
129275
129333
  var MS_PER_SECOND10 = 1e3;
129334
+ var ROUTING_MEMORY_SESSIONS = 256;
129276
129335
  function exhaustedMessage(exhaustion) {
129277
129336
  const window = exhaustion.window === "five_hour" ? "5-hour" : "weekly";
129278
129337
  return `Antigravity ${window} limit reached; it resets at ${new Date(exhaustion.resetSec * MS_PER_SECOND10).toISOString()}.`;
129279
129338
  }
129280
129339
  function createAntigravityRoute(ports) {
129281
129340
  const fallbackId = ports.fallbackId ?? (() => (0, import_node_crypto22.randomUUID)());
129341
+ const lastRouted = /* @__PURE__ */ new Map();
129282
129342
  return async (request7) => {
129283
129343
  await Promise.resolve();
129284
129344
  if (request7.method !== "POST") {
@@ -129330,13 +129390,24 @@ function createAntigravityRoute(ports) {
129330
129390
  }
129331
129391
  const { config: config2, token, credentialTarget } = lookup;
129332
129392
  const requestedModel = parsed.data.model ?? config2.defaultModel;
129333
- const translated = translateRequest2(parsed.data, config2);
129393
+ const nowMs = ports.now?.() ?? Date.now();
129394
+ const sessionKey = parsed.data.metadata?.user_id === void 0 ? void 0 : `${parsed.data.metadata.user_id}\0${parsed.data.model ?? ""}`;
129395
+ const translated = translateRequest2(parsed.data, config2, { quota: ports.quotaSource?.(), nowMs, previous: sessionKey === void 0 ? void 0 : lastRouted.get(sessionKey) });
129396
+ if (sessionKey !== void 0) {
129397
+ lastRouted.delete(sessionKey);
129398
+ lastRouted.set(sessionKey, translated.model);
129399
+ if (lastRouted.size > ROUTING_MEMORY_SESSIONS) {
129400
+ const oldest = lastRouted.keys().next();
129401
+ if (oldest.done !== true) {
129402
+ lastRouted.delete(oldest.value);
129403
+ }
129404
+ }
129405
+ }
129334
129406
  const relay = createAntigravityRelay({
129335
129407
  requestedModel,
129336
129408
  toolNames: translated.toolNames,
129337
129409
  fallbackId
129338
129410
  });
129339
- const nowMs = ports.now?.() ?? Date.now();
129340
129411
  const upstreamChunks2 = config2.mode === "local" ? callLocalAntigravity({
129341
129412
  config: config2,
129342
129413
  model: translated.model,
@@ -145072,7 +145143,7 @@ function antigravityConfigFromOptions(options) {
145072
145143
  const candidate = {
145073
145144
  ...options.antigravityMode === void 0 ? {} : { mode: options.antigravityMode },
145074
145145
  ...options.antigravityDefaultModel === void 0 ? {} : { defaultModel: options.antigravityDefaultModel },
145075
- ...options.antigravityModel === void 0 ? {} : { models: options.antigravityModel },
145146
+ ...options.antigravityModel === void 0 ? {} : { models: Object.fromEntries(Object.entries(options.antigravityModel).map(([name, target]) => [name, target.includes(",") ? target.split(",") : target])) },
145076
145147
  ...options.antigravityEffort === void 0 ? {} : { effort: options.antigravityEffort },
145077
145148
  ...cloud === void 0 ? {} : { cloud },
145078
145149
  ...local === void 0 ? {} : { local }
@@ -145114,7 +145185,7 @@ function registerProviderCommand(program2, deps) {
145114
145185
  new Option("--credential-target <target>", "Where the token goes: bearer sets ANTHROPIC_AUTH_TOKEN (default), apiKey sets ANTHROPIC_API_KEY.").choices(
145115
145186
  PROVIDER_CREDENTIAL_TARGETS
145116
145187
  )
145117
- ).option("--env <KEY=VALUE>", "Extra environment entry for the child (repeatable).", collectStringPair).option("--codex-default-model <model>", "Codex providers: the codex model a request maps to when no tier matches.").option("--codex-model <tier=model>", "Codex providers: the codex model one tier (fable, opus, sonnet or haiku) maps to (repeatable).", collectStringPair).addOption(new Option("--codex-effort <effort>", "Codex providers: the reasoning effort when a request asks for none the backend accepts.").choices(CODEX_EFFORTS)).addOption(new Option("--codex-login <login>", "Codex providers: which login the upstream call uses, the Codex CLI's own login or a Sign in with ChatGPT grant from `agent-shim codex login`.").choices(CODEX_LOGINS)).addOption(new Option("--antigravity-mode <mode>", "Antigravity providers: cloud (direct Gemini/Vertex) or local (ACP daemon).").choices(ANTIGRAVITY_MODES)).option("--antigravity-default-model <model>", "Antigravity providers: the model a request maps to when no tier matches.").option("--antigravity-model <tier=model>", "Antigravity providers: the model a tier (fable, opus, sonnet or haiku, matched by substring) or an alias (any other name, matched whole, selectable with /model) maps to (repeatable).", collectStringPair).addOption(new Option("--antigravity-effort <effort>", "Antigravity providers: reasoning effort.").choices(ANTIGRAVITY_EFFORTS)).option("--antigravity-endpoint <url>", "Antigravity cloud providers: custom API endpoint URL.").option("--antigravity-project-id <id>", "Antigravity cloud providers: Google Cloud project ID (for Vertex AI).").option("--antigravity-location <loc>", "Antigravity cloud providers: Google Cloud location (for Vertex AI).").option("--antigravity-command <cmd...>", "Antigravity local providers: command to spawn ACP server.", collectRepeated).option("--antigravity-socket <path>", "Antigravity local providers: path to existing Unix domain socket.").option("--json", "Print the result as JSON.").action((name, options) => {
145188
+ ).option("--env <KEY=VALUE>", "Extra environment entry for the child (repeatable).", collectStringPair).option("--codex-default-model <model>", "Codex providers: the codex model a request maps to when no tier matches.").option("--codex-model <tier=model>", "Codex providers: the codex model one tier (fable, opus, sonnet or haiku) maps to (repeatable).", collectStringPair).addOption(new Option("--codex-effort <effort>", "Codex providers: the reasoning effort when a request asks for none the backend accepts.").choices(CODEX_EFFORTS)).addOption(new Option("--codex-login <login>", "Codex providers: which login the upstream call uses, the Codex CLI's own login or a Sign in with ChatGPT grant from `agent-shim codex login`.").choices(CODEX_LOGINS)).addOption(new Option("--antigravity-mode <mode>", "Antigravity providers: cloud (direct Gemini/Vertex) or local (ACP daemon).").choices(ANTIGRAVITY_MODES)).option("--antigravity-default-model <model>", "Antigravity providers: the model a request maps to when no tier matches.").option("--antigravity-model <tier=model>", "Antigravity providers: the model a tier (fable, opus, sonnet or haiku, matched by substring) or an alias (any other name, matched whole, selectable with /model) maps to; a comma-separated list routes by available quota, first unspent first (repeatable).", collectStringPair).addOption(new Option("--antigravity-effort <effort>", "Antigravity providers: reasoning effort.").choices(ANTIGRAVITY_EFFORTS)).option("--antigravity-endpoint <url>", "Antigravity cloud providers: custom API endpoint URL.").option("--antigravity-project-id <id>", "Antigravity cloud providers: Google Cloud project ID (for Vertex AI).").option("--antigravity-location <loc>", "Antigravity cloud providers: Google Cloud location (for Vertex AI).").option("--antigravity-command <cmd...>", "Antigravity local providers: command to spawn ACP server.", collectRepeated).option("--antigravity-socket <path>", "Antigravity local providers: path to existing Unix domain socket.").option("--json", "Print the result as JSON.").action((name, options) => {
145118
145189
  const codex = codexConfigFromOptions(options);
145119
145190
  const antigravity = antigravityConfigFromOptions(options);
145120
145191
  const created = addProvider(paths, name, {
@@ -145225,9 +145296,9 @@ function registerProviderCommand(program2, deps) {
145225
145296
  } else if (isAntigravityProvider(found)) {
145226
145297
  const config2 = resolveAntigravityConfig(found.antigravity);
145227
145298
  console.log(`Antigravity mode: ${config2.mode}`);
145228
- console.log(`Antigravity models: ${ANTIGRAVITY_TIERS.map((tier) => `${tier}=${config2.models[tier]}`).join(", ")}, otherwise ${config2.defaultModel}`);
145299
+ console.log(`Antigravity models: ${ANTIGRAVITY_TIERS.map((tier) => `${tier}=${config2.models[tier].join(" > ")}`).join(", ")}, otherwise ${config2.defaultModel}`);
145229
145300
  if (config2.aliases.size > 0) {
145230
- console.log(`Antigravity aliases: ${[...config2.aliases].map(([alias, model]) => `${alias}=${model}`).join(", ")}`);
145301
+ console.log(`Antigravity aliases: ${[...config2.aliases].map(([alias, model]) => `${alias}=${model.join(" > ")}`).join(", ")}`);
145231
145302
  }
145232
145303
  console.log(`Antigravity effort: ${config2.effort}`);
145233
145304
  console.log(`Endpoint: ${describeProviderEndpoint(found)}`);
package/dist/index.cjs CHANGED
@@ -242,7 +242,7 @@ function isTimeZone(name) {
242
242
  return false;
243
243
  }
244
244
  }
245
- var import_node_path2, import_zod, import_trilean, CATEGORY_NAMES, OVERRIDABLE_CATEGORIES, CategoryMapSchema, DURATION_RE, DurationSchema, WhenConditionObjectSchema, WhenSchema, EntryValueSchema, ENTRY_KEY_RE, EntriesSchema, LaunchSchema, CREDENTIAL_TARGETS, PROVIDER_CREDENTIAL_TARGETS, CREDENTIAL_TARGET_VARS, ArgvSchema, CommandSourceOptions, EnvCredentialSourceSchema, FileCredentialSourceSchema, CommandCredentialSourceSchema, OpCredentialSourceSchema, KeychainCredentialSourceSchema, LiteralCredentialSourceSchema, CredentialSourceSchema, RemoteCredentialSourceSchema, CREDENTIAL_CACHE_STORES, CredentialCacheSchema, CredentialSchema, ProviderCredentialSchema, RESERVED_PROVIDER_ENV_KEYS, ProviderEnvSchema, PROVIDER_KINDS, ANTIGRAVITY_MODES, ANTIGRAVITY_EFFORTS, ANTIGRAVITY_DEFAULT_MODE, ANTIGRAVITY_DEFAULT_TIER_MODELS, AntigravityProviderConfigSchema, CODEX_EFFORTS, CODEX_LOGINS, CODEX_DEFAULT_TIER_MODELS, CodexProviderConfigSchema, ProviderRouteSchema, HttpProviderSchema, CodexProviderSchema, AntigravityProviderSchema, ProviderSchema, ConfigProfileSchema, POOL_SELECTOR_PREFIX, POOL_NAME_PATTERN, IDENTITY_NAME_PATTERN, PoolNameSchema, SELECTOR_RE, IdentitySelectorSchema, PoolMemberSchema, POOL_PREFERENCES, PoolPreferenceSchema, PoolSchema, WEEKDAYS, AnchorSchema, JOB_WINDOWS, JobTriggerSchema, JobTargetSchema, JobSchema, DirectoryRuleSchema, DirectoryRulesSchema, PortableConfigSchema, HEADROOM_MODES, HEADROOM_CCR_MODES, HEADROOM_ROLLOUT_CHANNELS, INTERCEPT_CHANNELS, READ_MATURATION_CHANNELS, HeadroomGlobalConfigObjectSchema, HeadroomGlobalConfigSchema, HEADROOM_DEFAULT_SOURCE, HEADROOM_DEFAULT_IDLE_SHUTDOWN_MINUTES, FrontDoorGlobalConfigSchema, UPDATE_MODES, UpdateGlobalConfigSchema, GlobalConfigSchema, IdentitySchema, CategoryClassificationSchema, CategoryClassificationOverlaySchema, SHIPPED_CATEGORY_DEFAULTS;
245
+ var import_node_path2, import_zod, import_trilean, CATEGORY_NAMES, OVERRIDABLE_CATEGORIES, CategoryMapSchema, DURATION_RE, DurationSchema, WhenConditionObjectSchema, WhenSchema, EntryValueSchema, ENTRY_KEY_RE, EntriesSchema, LaunchSchema, CREDENTIAL_TARGETS, PROVIDER_CREDENTIAL_TARGETS, CREDENTIAL_TARGET_VARS, ArgvSchema, CommandSourceOptions, EnvCredentialSourceSchema, FileCredentialSourceSchema, CommandCredentialSourceSchema, OpCredentialSourceSchema, KeychainCredentialSourceSchema, LiteralCredentialSourceSchema, CredentialSourceSchema, RemoteCredentialSourceSchema, CREDENTIAL_CACHE_STORES, CredentialCacheSchema, CredentialSchema, ProviderCredentialSchema, RESERVED_PROVIDER_ENV_KEYS, ProviderEnvSchema, PROVIDER_KINDS, ANTIGRAVITY_MODES, ANTIGRAVITY_EFFORTS, ANTIGRAVITY_DEFAULT_MODE, ANTIGRAVITY_DEFAULT_TIER_MODELS, AntigravityModelTargetSchema, AntigravityProviderConfigSchema, CODEX_EFFORTS, CODEX_LOGINS, CODEX_DEFAULT_TIER_MODELS, CodexProviderConfigSchema, ProviderRouteSchema, HttpProviderSchema, CodexProviderSchema, AntigravityProviderSchema, ProviderSchema, ConfigProfileSchema, POOL_SELECTOR_PREFIX, POOL_NAME_PATTERN, IDENTITY_NAME_PATTERN, PoolNameSchema, SELECTOR_RE, IdentitySelectorSchema, PoolMemberSchema, POOL_PREFERENCES, PoolPreferenceSchema, PoolSchema, WEEKDAYS, AnchorSchema, JOB_WINDOWS, JobTriggerSchema, JobTargetSchema, JobSchema, DirectoryRuleSchema, DirectoryRulesSchema, PortableConfigSchema, HEADROOM_MODES, HEADROOM_CCR_MODES, HEADROOM_ROLLOUT_CHANNELS, INTERCEPT_CHANNELS, READ_MATURATION_CHANNELS, HeadroomGlobalConfigObjectSchema, HeadroomGlobalConfigSchema, HEADROOM_DEFAULT_SOURCE, HEADROOM_DEFAULT_IDLE_SHUTDOWN_MINUTES, FrontDoorGlobalConfigSchema, UPDATE_MODES, UpdateGlobalConfigSchema, GlobalConfigSchema, IdentitySchema, CategoryClassificationSchema, CategoryClassificationOverlaySchema, SHIPPED_CATEGORY_DEFAULTS;
246
246
  var init_schema = __esm({
247
247
  "src/config/schema.ts"() {
248
248
  "use strict";
@@ -346,18 +346,19 @@ var init_schema = __esm({
346
346
  ANTIGRAVITY_EFFORTS = ["none", "low", "medium", "high", "xhigh", "max"];
347
347
  ANTIGRAVITY_DEFAULT_MODE = "cloud";
348
348
  ANTIGRAVITY_DEFAULT_TIER_MODELS = Object.freeze({
349
- fable: "gemini-3.8-flash-high",
350
- opus: "gemini-3.8-flash-high",
351
- sonnet: "gemini-3.8-flash-medium",
352
- haiku: "gemini-3.8-flash-low"
349
+ fable: ["claude-opus-5-5-high", "gemini-4-argon-high", "gemini-3.8-flash-high"],
350
+ opus: ["claude-opus-5-5-high", "gemini-4-argon-high", "gemini-3.8-flash-high"],
351
+ sonnet: ["claude-sonnet-5-5-medium", "gemini-4-argon-medium", "gemini-3.8-flash-medium"],
352
+ haiku: ["gemini-3.8-flash-low", "gemini-4-argon-low", "gpt-oss-120b-medium"]
353
353
  });
354
+ AntigravityModelTargetSchema = import_zod.z.union([import_zod.z.string().min(1), import_zod.z.array(import_zod.z.string().min(1)).min(1)]);
354
355
  AntigravityProviderConfigSchema = import_zod.z.strictObject({
355
356
  /** Operational mode: direct cloud endpoint or local ACP daemon. Defaults to `cloud`. */
356
357
  mode: import_zod.z.enum(ANTIGRAVITY_MODES).optional(),
357
358
  /** The model a request maps to when no tier matches its model name. */
358
359
  defaultModel: import_zod.z.string().min(1).optional(),
359
- /** Model name mapping. A key naming a tier (`fable`, `opus`, `sonnet`, `haiku`) overrides that tier's shipped model and is matched by substring of the requested name in `ANTIGRAVITY_TIERS` order; any other key is an alias, matched against the whole requested name case-insensitively, so `/model <alias>` selects its backend model. An alias outranks every other rule, including the pass-through of backend names. */
360
- models: import_zod.z.record(import_zod.z.string().min(1), import_zod.z.string().min(1)).optional(),
360
+ /** Model name mapping. A key naming a tier (`fable`, `opus`, `sonnet`, `haiku`) overrides that tier's shipped model and is matched by substring of the requested name in `ANTIGRAVITY_TIERS` order; any other key is an alias, matched against the whole requested name case-insensitively, so `/model <alias>` selects its backend model. An alias outranks every other rule, including the pass-through of backend names. A value is one model or an ordered list of candidates: the request goes to the first whose quota windows are not spent, and when every candidate is spent, to the one whose binding window lifts soonest. */
361
+ models: import_zod.z.record(import_zod.z.string().min(1), AntigravityModelTargetSchema).optional(),
361
362
  /** The reasoning effort used when the request's own effort is not one the backend accepts. */
362
363
  effort: import_zod.z.enum(ANTIGRAVITY_EFFORTS).optional(),
363
364
  /** Cloud-specific settings (for `mode: "cloud"`). */
@@ -2836,7 +2837,7 @@ var init_package = __esm({
2836
2837
  "package.json"() {
2837
2838
  package_default = {
2838
2839
  name: "claude-use",
2839
- version: "11.16.0",
2840
+ version: "11.17.0",
2840
2841
  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.",
2841
2842
  license: "MIT",
2842
2843
  author: "Joseph Mearman <joseph@mearman.co.uk>",
package/dist/index.mjs CHANGED
@@ -223,7 +223,7 @@ function isTimeZone(name) {
223
223
  return false;
224
224
  }
225
225
  }
226
- var CATEGORY_NAMES, OVERRIDABLE_CATEGORIES, CategoryMapSchema, DURATION_RE, DurationSchema, WhenConditionObjectSchema, WhenSchema, EntryValueSchema, ENTRY_KEY_RE, EntriesSchema, LaunchSchema, CREDENTIAL_TARGETS, PROVIDER_CREDENTIAL_TARGETS, CREDENTIAL_TARGET_VARS, ArgvSchema, CommandSourceOptions, EnvCredentialSourceSchema, FileCredentialSourceSchema, CommandCredentialSourceSchema, OpCredentialSourceSchema, KeychainCredentialSourceSchema, LiteralCredentialSourceSchema, CredentialSourceSchema, RemoteCredentialSourceSchema, CREDENTIAL_CACHE_STORES, CredentialCacheSchema, CredentialSchema, ProviderCredentialSchema, RESERVED_PROVIDER_ENV_KEYS, ProviderEnvSchema, PROVIDER_KINDS, ANTIGRAVITY_MODES, ANTIGRAVITY_EFFORTS, ANTIGRAVITY_DEFAULT_MODE, ANTIGRAVITY_DEFAULT_TIER_MODELS, AntigravityProviderConfigSchema, CODEX_EFFORTS, CODEX_LOGINS, CODEX_DEFAULT_TIER_MODELS, CodexProviderConfigSchema, ProviderRouteSchema, HttpProviderSchema, CodexProviderSchema, AntigravityProviderSchema, ProviderSchema, ConfigProfileSchema, POOL_SELECTOR_PREFIX, POOL_NAME_PATTERN, IDENTITY_NAME_PATTERN, PoolNameSchema, SELECTOR_RE, IdentitySelectorSchema, PoolMemberSchema, POOL_PREFERENCES, PoolPreferenceSchema, PoolSchema, WEEKDAYS, AnchorSchema, JOB_WINDOWS, JobTriggerSchema, JobTargetSchema, JobSchema, DirectoryRuleSchema, DirectoryRulesSchema, PortableConfigSchema, HEADROOM_MODES, HEADROOM_CCR_MODES, HEADROOM_ROLLOUT_CHANNELS, INTERCEPT_CHANNELS, READ_MATURATION_CHANNELS, HeadroomGlobalConfigObjectSchema, HeadroomGlobalConfigSchema, HEADROOM_DEFAULT_SOURCE, HEADROOM_DEFAULT_IDLE_SHUTDOWN_MINUTES, FrontDoorGlobalConfigSchema, UPDATE_MODES, UpdateGlobalConfigSchema, GlobalConfigSchema, IdentitySchema, CategoryClassificationSchema, CategoryClassificationOverlaySchema, SHIPPED_CATEGORY_DEFAULTS;
226
+ var CATEGORY_NAMES, OVERRIDABLE_CATEGORIES, CategoryMapSchema, DURATION_RE, DurationSchema, WhenConditionObjectSchema, WhenSchema, EntryValueSchema, ENTRY_KEY_RE, EntriesSchema, LaunchSchema, CREDENTIAL_TARGETS, PROVIDER_CREDENTIAL_TARGETS, CREDENTIAL_TARGET_VARS, ArgvSchema, CommandSourceOptions, EnvCredentialSourceSchema, FileCredentialSourceSchema, CommandCredentialSourceSchema, OpCredentialSourceSchema, KeychainCredentialSourceSchema, LiteralCredentialSourceSchema, CredentialSourceSchema, RemoteCredentialSourceSchema, CREDENTIAL_CACHE_STORES, CredentialCacheSchema, CredentialSchema, ProviderCredentialSchema, RESERVED_PROVIDER_ENV_KEYS, ProviderEnvSchema, PROVIDER_KINDS, ANTIGRAVITY_MODES, ANTIGRAVITY_EFFORTS, ANTIGRAVITY_DEFAULT_MODE, ANTIGRAVITY_DEFAULT_TIER_MODELS, AntigravityModelTargetSchema, AntigravityProviderConfigSchema, CODEX_EFFORTS, CODEX_LOGINS, CODEX_DEFAULT_TIER_MODELS, CodexProviderConfigSchema, ProviderRouteSchema, HttpProviderSchema, CodexProviderSchema, AntigravityProviderSchema, ProviderSchema, ConfigProfileSchema, POOL_SELECTOR_PREFIX, POOL_NAME_PATTERN, IDENTITY_NAME_PATTERN, PoolNameSchema, SELECTOR_RE, IdentitySelectorSchema, PoolMemberSchema, POOL_PREFERENCES, PoolPreferenceSchema, PoolSchema, WEEKDAYS, AnchorSchema, JOB_WINDOWS, JobTriggerSchema, JobTargetSchema, JobSchema, DirectoryRuleSchema, DirectoryRulesSchema, PortableConfigSchema, HEADROOM_MODES, HEADROOM_CCR_MODES, HEADROOM_ROLLOUT_CHANNELS, INTERCEPT_CHANNELS, READ_MATURATION_CHANNELS, HeadroomGlobalConfigObjectSchema, HeadroomGlobalConfigSchema, HEADROOM_DEFAULT_SOURCE, HEADROOM_DEFAULT_IDLE_SHUTDOWN_MINUTES, FrontDoorGlobalConfigSchema, UPDATE_MODES, UpdateGlobalConfigSchema, GlobalConfigSchema, IdentitySchema, CategoryClassificationSchema, CategoryClassificationOverlaySchema, SHIPPED_CATEGORY_DEFAULTS;
227
227
  var init_schema = __esm({
228
228
  "src/config/schema.ts"() {
229
229
  "use strict";
@@ -324,18 +324,19 @@ var init_schema = __esm({
324
324
  ANTIGRAVITY_EFFORTS = ["none", "low", "medium", "high", "xhigh", "max"];
325
325
  ANTIGRAVITY_DEFAULT_MODE = "cloud";
326
326
  ANTIGRAVITY_DEFAULT_TIER_MODELS = Object.freeze({
327
- fable: "gemini-3.8-flash-high",
328
- opus: "gemini-3.8-flash-high",
329
- sonnet: "gemini-3.8-flash-medium",
330
- haiku: "gemini-3.8-flash-low"
327
+ fable: ["claude-opus-5-5-high", "gemini-4-argon-high", "gemini-3.8-flash-high"],
328
+ opus: ["claude-opus-5-5-high", "gemini-4-argon-high", "gemini-3.8-flash-high"],
329
+ sonnet: ["claude-sonnet-5-5-medium", "gemini-4-argon-medium", "gemini-3.8-flash-medium"],
330
+ haiku: ["gemini-3.8-flash-low", "gemini-4-argon-low", "gpt-oss-120b-medium"]
331
331
  });
332
+ AntigravityModelTargetSchema = z.union([z.string().min(1), z.array(z.string().min(1)).min(1)]);
332
333
  AntigravityProviderConfigSchema = z.strictObject({
333
334
  /** Operational mode: direct cloud endpoint or local ACP daemon. Defaults to `cloud`. */
334
335
  mode: z.enum(ANTIGRAVITY_MODES).optional(),
335
336
  /** The model a request maps to when no tier matches its model name. */
336
337
  defaultModel: z.string().min(1).optional(),
337
- /** Model name mapping. A key naming a tier (`fable`, `opus`, `sonnet`, `haiku`) overrides that tier's shipped model and is matched by substring of the requested name in `ANTIGRAVITY_TIERS` order; any other key is an alias, matched against the whole requested name case-insensitively, so `/model <alias>` selects its backend model. An alias outranks every other rule, including the pass-through of backend names. */
338
- models: z.record(z.string().min(1), z.string().min(1)).optional(),
338
+ /** Model name mapping. A key naming a tier (`fable`, `opus`, `sonnet`, `haiku`) overrides that tier's shipped model and is matched by substring of the requested name in `ANTIGRAVITY_TIERS` order; any other key is an alias, matched against the whole requested name case-insensitively, so `/model <alias>` selects its backend model. An alias outranks every other rule, including the pass-through of backend names. A value is one model or an ordered list of candidates: the request goes to the first whose quota windows are not spent, and when every candidate is spent, to the one whose binding window lifts soonest. */
339
+ models: z.record(z.string().min(1), AntigravityModelTargetSchema).optional(),
339
340
  /** The reasoning effort used when the request's own effort is not one the backend accepts. */
340
341
  effort: z.enum(ANTIGRAVITY_EFFORTS).optional(),
341
342
  /** Cloud-specific settings (for `mode: "cloud"`). */
@@ -2812,7 +2813,7 @@ var init_package = __esm({
2812
2813
  "package.json"() {
2813
2814
  package_default = {
2814
2815
  name: "claude-use",
2815
- version: "11.16.0",
2816
+ version: "11.17.0",
2816
2817
  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.",
2817
2818
  license: "MIT",
2818
2819
  author: "Joseph Mearman <joseph@mearman.co.uk>",
@@ -390,7 +390,7 @@ declare const AntigravityProviderConfigSchema: z.ZodObject<{
390
390
  local: "local";
391
391
  }>>;
392
392
  defaultModel: z.ZodOptional<z.ZodString>;
393
- models: z.ZodOptional<z.ZodRecord<z.ZodString, z.ZodString>>;
393
+ models: z.ZodOptional<z.ZodRecord<z.ZodString, z.ZodUnion<readonly [z.ZodString, z.ZodArray<z.ZodString>]>>>;
394
394
  effort: z.ZodOptional<z.ZodEnum<{
395
395
  none: "none";
396
396
  max: "max";
@@ -656,7 +656,7 @@ declare const ProviderSchema: z.ZodDiscriminatedUnion<[z.ZodObject<{
656
656
  local: "local";
657
657
  }>>;
658
658
  defaultModel: z.ZodOptional<z.ZodString>;
659
- models: z.ZodOptional<z.ZodRecord<z.ZodString, z.ZodString>>;
659
+ models: z.ZodOptional<z.ZodRecord<z.ZodString, z.ZodUnion<readonly [z.ZodString, z.ZodArray<z.ZodString>]>>>;
660
660
  effort: z.ZodOptional<z.ZodEnum<{
661
661
  none: "none";
662
662
  max: "max";
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "claude-use",
3
- "version": "11.16.0",
3
+ "version": "11.17.0",
4
4
  "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.",
5
5
  "license": "MIT",
6
6
  "author": "Joseph Mearman <joseph@mearman.co.uk>",