github-router 0.3.292 → 0.3.295

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.
Files changed (93) hide show
  1. package/dist/{attribution-settings-CpLUCi8R.js → attribution-settings-pkIop1NU.js} +69 -30
  2. package/dist/attribution-settings-pkIop1NU.js.map +1 -0
  3. package/dist/{auth-BwUHopJz.js → auth-CluG5e-l.js} +3 -3
  4. package/dist/{auth-BwUHopJz.js.map → auth-CluG5e-l.js.map} +1 -1
  5. package/dist/browser-ext/manifest.json +1 -1
  6. package/dist/{check-usage-BTda5753.js → check-usage-iOzfnKJe.js} +4 -4
  7. package/dist/{check-usage-BTda5753.js.map → check-usage-iOzfnKJe.js.map} +1 -1
  8. package/dist/{claude-_DYGKCw8.js → claude-DNmxk-Rm.js} +162 -42
  9. package/dist/claude-DNmxk-Rm.js.map +1 -0
  10. package/dist/{codex-rTJ8jW5G.js → codex-Dl4gpHn-.js} +5 -5
  11. package/dist/{codex-rTJ8jW5G.js.map → codex-Dl4gpHn-.js.map} +1 -1
  12. package/dist/{debug-B3UrZTHQ.js → debug-DsEwleGg.js} +2 -2
  13. package/dist/{debug-B3UrZTHQ.js.map → debug-DsEwleGg.js.map} +1 -1
  14. package/dist/engine-XnluJUs6.js +2 -0
  15. package/dist/{gate-discovery-Bjar5dgv.js → gate-discovery-WcduofL4.js} +5 -5
  16. package/dist/{gate-discovery-Bjar5dgv.js.map → gate-discovery-WcduofL4.js.map} +1 -1
  17. package/dist/{get-copilot-usage-CRrf1ZSC.js → get-copilot-usage-B7Z4XVWj.js} +2 -2
  18. package/dist/{get-copilot-usage-CRrf1ZSC.js.map → get-copilot-usage-B7Z4XVWj.js.map} +1 -1
  19. package/dist/hooks.mjs +180 -3
  20. package/dist/hooks.sha256 +1 -1
  21. package/dist/{internal-artifact-open-BsEQRvDi.js → internal-artifact-open-D6tKMg8v.js} +2 -2
  22. package/dist/{internal-artifact-open-BsEQRvDi.js.map → internal-artifact-open-D6tKMg8v.js.map} +1 -1
  23. package/dist/internal-fast-dispatch-guard-CPlCrTlU.js +2 -0
  24. package/dist/internal-fast-dispatch-guard-Xyu17k9X.js +187 -0
  25. package/dist/internal-fast-dispatch-guard-Xyu17k9X.js.map +1 -0
  26. package/dist/{internal-first-mate-guard-CVFFJriA.js → internal-first-mate-guard-C9BV7J4U.js} +3 -3
  27. package/dist/{internal-first-mate-guard-CVFFJriA.js.map → internal-first-mate-guard-C9BV7J4U.js.map} +1 -1
  28. package/dist/{internal-first-mate-guard-DJdX6t48.js → internal-first-mate-guard-WJApyc8j.js} +1 -1
  29. package/dist/{internal-plan-review-8TKDLco6.js → internal-plan-review-t3PuNfuL.js} +3 -3
  30. package/dist/{internal-plan-review-8TKDLco6.js.map → internal-plan-review-t3PuNfuL.js.map} +1 -1
  31. package/dist/{internal-prompt-submit-Da7pxqua.js → internal-prompt-submit-C3KovHQG.js} +4 -4
  32. package/dist/{internal-prompt-submit-Da7pxqua.js.map → internal-prompt-submit-C3KovHQG.js.map} +1 -1
  33. package/dist/{internal-session-bind-BOFytA1f.js → internal-session-bind-d2uoja8I.js} +2 -2
  34. package/dist/{internal-session-bind-BOFytA1f.js.map → internal-session-bind-d2uoja8I.js.map} +1 -1
  35. package/dist/{internal-stop-hook-DrX2xlj0.js → internal-stop-hook-DJFtGCsE.js} +5 -5
  36. package/dist/{internal-stop-hook-DrX2xlj0.js.map → internal-stop-hook-DJFtGCsE.js.map} +1 -1
  37. package/dist/{internal-stop-review-CdouacHL.js → internal-stop-review-YtDUGXpX.js} +2 -2
  38. package/dist/{internal-stop-review-CdouacHL.js.map → internal-stop-review-YtDUGXpX.js.map} +1 -1
  39. package/dist/{internal-worker-guard-Bx-itoP8.js → internal-worker-guard-CdkeS9PN.js} +2 -2
  40. package/dist/{internal-worker-guard-Bx-itoP8.js.map → internal-worker-guard-CdkeS9PN.js.map} +1 -1
  41. package/dist/{internal-workspace-header-8WT0iB5K.js → internal-workspace-header-tuBXJV22.js} +2 -2
  42. package/dist/{internal-workspace-header-8WT0iB5K.js.map → internal-workspace-header-tuBXJV22.js.map} +1 -1
  43. package/dist/{lifecycle-nuOHfwgj.js → lifecycle-Bg6doY3-.js} +2 -2
  44. package/dist/{lifecycle-nuOHfwgj.js.map → lifecycle-Bg6doY3-.js.map} +1 -1
  45. package/dist/lifecycle-CGLt1cJQ.js +2 -0
  46. package/dist/{lifecycle-LeSfa7wH.js → lifecycle-CM9eTzvk.js} +2 -2
  47. package/dist/{lifecycle-LeSfa7wH.js.map → lifecycle-CM9eTzvk.js.map} +1 -1
  48. package/dist/lifecycle-DoUwpVDB.js +2 -0
  49. package/dist/main.js +19 -18
  50. package/dist/main.js.map +1 -1
  51. package/dist/{mcp-workspace-header-q34H_4wL.js → mcp-workspace-header-dERl2YTT.js} +2 -2
  52. package/dist/{mcp-workspace-header-q34H_4wL.js.map → mcp-workspace-header-dERl2YTT.js.map} +1 -1
  53. package/dist/{models-hhJcrZhr.js → models-DZ4hYsR7.js} +3 -3
  54. package/dist/{models-hhJcrZhr.js.map → models-DZ4hYsR7.js.map} +1 -1
  55. package/dist/{orchestration-pzbrKkgD.js → orchestration-BiGCEwbH.js} +2 -2
  56. package/dist/{orchestration-pzbrKkgD.js.map → orchestration-BiGCEwbH.js.map} +1 -1
  57. package/dist/{paths-BH4J7slC.js → paths-Ci485qSJ.js} +4 -4
  58. package/dist/{paths-BH4J7slC.js.map → paths-Ci485qSJ.js.map} +1 -1
  59. package/dist/paths-GD7bgGGy.js +2 -0
  60. package/dist/{peer-mcp-personas-CHbl6MwM.js → peer-mcp-personas-BwNtC8jt.js} +411 -84
  61. package/dist/peer-mcp-personas-BwNtC8jt.js.map +1 -0
  62. package/dist/{plan-review-hook-CfcanA7_.js → plan-review-hook-DuW0pSoM.js} +3 -3
  63. package/dist/{plan-review-hook-CfcanA7_.js.map → plan-review-hook-DuW0pSoM.js.map} +1 -1
  64. package/dist/{prompt-submit-hook-Bqf9ORgb.js → prompt-submit-hook-IMl7ssfr.js} +3 -3
  65. package/dist/{prompt-submit-hook-Bqf9ORgb.js.map → prompt-submit-hook-IMl7ssfr.js.map} +1 -1
  66. package/dist/{provision-BYFd9nPK.js → provision-DeNqzvSM.js} +4 -4
  67. package/dist/{provision-BYFd9nPK.js.map → provision-DeNqzvSM.js.map} +1 -1
  68. package/dist/{self-invocation-DhO1Z8iD.js → self-invocation-DAB_od0C.js} +2 -2
  69. package/dist/{self-invocation-DhO1Z8iD.js.map → self-invocation-DAB_od0C.js.map} +1 -1
  70. package/dist/{serve-BWMxDLnD.js → serve-BS5EmCpM.js} +12 -12
  71. package/dist/{serve-BWMxDLnD.js.map → serve-BS5EmCpM.js.map} +1 -1
  72. package/dist/{server-setup-CqlaZukJ.js → server-setup-DsGJnJ_O.js} +398 -283
  73. package/dist/server-setup-DsGJnJ_O.js.map +1 -0
  74. package/dist/{start-5MgGT4IF.js → start-vJdt2MiM.js} +3 -3
  75. package/dist/{start-5MgGT4IF.js.map → start-vJdt2MiM.js.map} +1 -1
  76. package/dist/{stop-gate-hook-BiBp5aGm.js → stop-gate-hook-DQnh_KfI.js} +3 -3
  77. package/dist/{stop-gate-hook-BiBp5aGm.js.map → stop-gate-hook-DQnh_KfI.js.map} +1 -1
  78. package/dist/{stop-gate-policy-BGd6b5hR.js → stop-gate-policy-DMr3KVmw.js} +2 -2
  79. package/dist/{stop-gate-policy-BGd6b5hR.js.map → stop-gate-policy-DMr3KVmw.js.map} +1 -1
  80. package/dist/{token-8drORhXg.js → token-BtJhjXXu.js} +54 -7
  81. package/dist/token-BtJhjXXu.js.map +1 -0
  82. package/dist/{worker-dispatch-D5fGroNr.js → worker-dispatch-BEHkTbnH.js} +2 -2
  83. package/dist/{worker-dispatch-D5fGroNr.js.map → worker-dispatch-BEHkTbnH.js.map} +1 -1
  84. package/package.json +1 -1
  85. package/dist/attribution-settings-CpLUCi8R.js.map +0 -1
  86. package/dist/claude-_DYGKCw8.js.map +0 -1
  87. package/dist/engine-C9axTIu7.js +0 -2
  88. package/dist/lifecycle-C8fOsQke.js +0 -2
  89. package/dist/lifecycle-D4Yc1aap.js +0 -2
  90. package/dist/paths-DJZoXfAS.js +0 -2
  91. package/dist/peer-mcp-personas-CHbl6MwM.js.map +0 -1
  92. package/dist/server-setup-CqlaZukJ.js.map +0 -1
  93. package/dist/token-8drORhXg.js.map +0 -1
@@ -1,14 +1,14 @@
1
1
  import { n as explicitPackageRoot } from "./package-root-B-osctCk.js";
2
2
  import { t as getPackageVersion } from "./version-C8x2hQrZ.js";
3
- import { t as PATHS } from "./paths-BH4J7slC.js";
4
- import { A as state, C as GITHUB_GRAPHQL_URL, D as githubAgentGraphQLHeaders, E as copilotVersion, O as githubAgentHeaders, S as GITHUB_API_BASE_URL, T as copilotHeaders, b as sanitizeTransportText, d as resolveModel, f as sleep$2, g as HTTPError, h as isAllowedCopilotHost, i as tryRefreshAndRetry, v as classifyTransportError, w as copilotBaseUrl, x as withTransientRetry, y as fetchWithTransientRetry } from "./token-8drORhXg.js";
3
+ import { t as PATHS } from "./paths-Ci485qSJ.js";
4
+ import { A as state, C as GITHUB_GRAPHQL_URL, D as githubAgentGraphQLHeaders, E as copilotVersion, O as githubAgentHeaders, S as GITHUB_API_BASE_URL, T as copilotHeaders, b as sanitizeTransportText, d as resolveModel, f as sleep$2, g as HTTPError, h as isAllowedCopilotHost, i as tryRefreshAndRetry, v as classifyTransportError, w as copilotBaseUrl, x as withTransientRetry, y as fetchWithTransientRetry } from "./token-BtJhjXXu.js";
5
5
  import { a as resolveExecutable, c as runManagedExeCapture, i as parseIntEnv, l as spawnTaskkillBestEffort, r as parseBoolEnv } from "./exec-y8C_MU8A.js";
6
- import { i as registerExitHandlers$1, n as getInstanceUuid, r as recordWorkerRepo, t as WorktreeRegistry } from "./lifecycle-nuOHfwgj.js";
7
- import { t as MCP_WORKSPACE_HEADER } from "./mcp-workspace-header-q34H_4wL.js";
6
+ import { i as registerExitHandlers$1, n as getInstanceUuid, r as recordWorkerRepo, t as WorktreeRegistry } from "./lifecycle-Bg6doY3-.js";
7
+ import { t as MCP_WORKSPACE_HEADER } from "./mcp-workspace-header-dERl2YTT.js";
8
8
  import { n as ArtifactError, r as applyInsecureTls, t as ArtifactClient } from "./client-CQMfroGV.js";
9
- import { n as isPidAlive$1, r as registerColbertExitHandlers, s as trackChild, t as getColbertInstanceUuid } from "./lifecycle-LeSfa7wH.js";
10
- import { f as resolveSealedGate, m as runGateChecks, p as sealedGateIds } from "./stop-gate-hook-BiBp5aGm.js";
11
- import { t as liveExec } from "./orchestration-pzbrKkgD.js";
9
+ import { n as isPidAlive$1, r as registerColbertExitHandlers, s as trackChild, t as getColbertInstanceUuid } from "./lifecycle-CM9eTzvk.js";
10
+ import { f as resolveSealedGate, m as runGateChecks, p as sealedGateIds } from "./stop-gate-hook-DQnh_KfI.js";
11
+ import { t as liveExec } from "./orchestration-BiGCEwbH.js";
12
12
  import { createRequire } from "node:module";
13
13
  import consola from "consola";
14
14
  import { chmodSync, closeSync, constants, cpSync, existsSync, mkdirSync, openSync, readFileSync, readdirSync, realpathSync, renameSync, rmSync, statSync, unlinkSync, writeFileSync, writeSync } from "node:fs";
@@ -96,6 +96,25 @@ async function tryCreateLock(p) {
96
96
  }
97
97
  }
98
98
  //#endregion
99
+ //#region src/lib/model-suffix.ts
100
+ /** Strip every trailing `[1m]` marker, case-insensitively. */
101
+ function stripTrailingOneMSuffix(id) {
102
+ const match = id.match(/(?:\[1m\])+$/i);
103
+ if (!match || match.index === void 0) return {
104
+ base: id,
105
+ hadSuffix: false
106
+ };
107
+ return {
108
+ base: id.slice(0, match.index),
109
+ hadSuffix: true
110
+ };
111
+ }
112
+ /** Reapply at most one canonical `[1m]` marker when the input had one. */
113
+ function normalizeTrailingOneMSuffix(id) {
114
+ const { base, hadSuffix } = stripTrailingOneMSuffix(id);
115
+ return hadSuffix ? `${base}[1m]` : base;
116
+ }
117
+ //#endregion
99
118
  //#region src/lib/one-m-context.ts
100
119
  /**
101
120
  * Context-window threshold at which Claude Code's `[1m]` accounting unlock is
@@ -160,8 +179,9 @@ function oneMContextDisabled() {
160
179
  * conservative 200K accounting rather than being over-budgeted into an overflow.
161
180
  */
162
181
  function withOneMSuffix(id) {
163
- if (oneMContextDisabled()) return id;
164
- return catalogAdvertises1M(id) ? `${id}[1m]` : id;
182
+ const base = normalizeTrailingOneMSuffix(id).replace(/\[1m\]$/i, "");
183
+ if (oneMContextDisabled()) return base;
184
+ return catalogAdvertises1M(base) ? `${base}[1m]` : base;
165
185
  }
166
186
  /**
167
187
  * Decorate a slug the USER named — a `-m` argument or a launcher default — with
@@ -208,9 +228,48 @@ function withOneMSuffix(id) {
208
228
  * default — under-accounting, never overflow.
209
229
  */
210
230
  function withOneMSuffixForLead(slug) {
211
- if (oneMContextDisabled()) return slug;
212
- if (/\[1m\]$/i.test(slug)) return slug;
213
- return catalogAdvertises1M(resolveModel(slug)) ? `${slug}[1m]` : slug;
231
+ const base = normalizeTrailingOneMSuffix(slug).replace(/\[1m\]$/i, "");
232
+ if (oneMContextDisabled()) return base;
233
+ return catalogAdvertises1M(resolveModel(base)) ? `${base}[1m]` : base;
234
+ }
235
+ //#endregion
236
+ //#region src/lib/fast-endpoint.ts
237
+ const ENDPOINTS = {
238
+ chat: /* @__PURE__ */ new Set(["/chat/completions", "/v1/chat/completions"]),
239
+ responses: /* @__PURE__ */ new Set(["/responses", "/v1/responses"]),
240
+ messages: /* @__PURE__ */ new Set(["/messages", "/v1/messages"])
241
+ };
242
+ /**
243
+ * Return the endpoint mandated by a fast-profile roster model.
244
+ *
245
+ * This is intentionally independent of the standard `pickEndpoint`: that
246
+ * resolver prefers chat when a catalog entry advertises both clients, while
247
+ * fast roles have a fixed provider contract. Gemini stays on chat; Luna, Sol,
248
+ * and Grok stay on Responses; the Opus Oracle stays on native Messages.
249
+ * Unknown ids return undefined so a fast caller cannot guess a transport.
250
+ */
251
+ function fastEndpointRequirement(modelId) {
252
+ const id = modelId.replace(/(?:\[1m\])+$/i, "");
253
+ if (id === "gemini-3.7-flash") return "chat";
254
+ if (id === "gpt-5.6-luna" || id === "gpt-5.6-sol" || id === "grok-4.6") return "responses";
255
+ if (id === "claude-opus-5") return "messages";
256
+ }
257
+ /**
258
+ * Resolve the fixed fast transport only when the catalog explicitly advertises
259
+ * the required endpoint. An entry that advertises both still resolves to the
260
+ * policy endpoint, regardless of advertisement order.
261
+ */
262
+ function fastEndpointForModel(model) {
263
+ const required = fastEndpointRequirement(model.id);
264
+ if (!required) return void 0;
265
+ const advertised = model.supported_endpoints;
266
+ if (!Array.isArray(advertised) || advertised.length === 0) return void 0;
267
+ return advertised.some((endpoint) => ENDPOINTS[required].has(endpoint)) ? required : void 0;
268
+ }
269
+ /** Resolve a fast endpoint from a catalog id, without selecting a fallback. */
270
+ function fastEndpointForCatalogId(modelId, catalog) {
271
+ const found = catalog?.find((model) => model.id === modelId);
272
+ return found ? fastEndpointForModel(found) : void 0;
214
273
  }
215
274
  //#endregion
216
275
  //#region src/services/copilot/endpoint.ts
@@ -368,12 +427,16 @@ function isClaudeModel(modelId, model, originalModelId) {
368
427
  * `originalModelId` is the optional pre-resolution request id; when supplied it
369
428
  * is checked for Claude-likeness alongside the resolved id so an alias that
370
429
  * resolves to a non-Claude-looking id can't slip past.
430
+ *
431
+ * `fastProfile` is an authenticated launch-policy signal. It replaces only the
432
+ * endpoint selection step with the fixed fast roster policy; Claude identity
433
+ * still wins first, and standard/BYO callers retain `pickEndpoint` unchanged.
371
434
  */
372
- function classifyMessagesRoute(modelId, model, originalModelId) {
435
+ function classifyMessagesRoute(modelId, model, originalModelId, fastProfile = false) {
373
436
  if (!modelId) return "claude-passthrough";
374
437
  if (isClaudeModel(modelId, model, originalModelId)) return "claude-passthrough";
375
438
  if (!model) return "claude-passthrough";
376
- const endpoint = pickEndpoint(model);
439
+ const endpoint = fastProfile ? fastEndpointForModel(model) : pickEndpoint(model);
377
440
  if (endpoint === "responses") return "responses-shim";
378
441
  if (endpoint === "chat") return "chat-shim";
379
442
  return "claude-passthrough";
@@ -451,7 +514,7 @@ const DEFAULT_OPUS_FAMILY = "5";
451
514
  * The lead `-m fast` selects. `gpt-5.6-luna` — a distinct Luna-driven
452
515
  * profile (see `./launch-profile`), NOT a Claude Sonnet budget lead. This
453
516
  * REPLACES the earlier `-m fast` → `claude-sonnet-5` mapping: `fast` now
454
- * names a deliberately lean Luna surface (three native agents, one peer
517
+ * names a deliberately lean Luna surface (five native agents, one peer
455
518
  * persona, `peers`/`search` MCP groups only), not "budget Sonnet with the
456
519
  * full standard surface". `resolveLaunchProfile` in `./launch-profile`
457
520
  * keys off the same raw `-m` argument this constant is selected by, so the
@@ -18926,7 +18989,7 @@ function logAudit$1(record) {
18926
18989
  try {
18927
18990
  const fs = await import("node:fs/promises");
18928
18991
  const path = await import("node:path");
18929
- const { PATHS } = await import("./paths-DJZoXfAS.js");
18992
+ const { PATHS } = await import("./paths-GD7bgGGy.js");
18930
18993
  const dir = path.join(PATHS.APP_DIR, "browser-mcp");
18931
18994
  await fs.mkdir(dir, { recursive: true });
18932
18995
  const line = JSON.stringify({
@@ -27454,6 +27517,247 @@ function shimDefaultsToXhigh(id) {
27454
27517
  return XHIGH_DEFAULT_SHIM_MODELS.includes(normalizeModelId(id));
27455
27518
  }
27456
27519
  //#endregion
27520
+ //#region src/lib/launch-profile.ts
27521
+ const STANDARD_PROFILE = Object.freeze({
27522
+ id: "standard",
27523
+ hasCoordinator: true
27524
+ });
27525
+ /**
27526
+ * The `-m fast` roster: exactly five native agents (`scout`, `implementer`,
27527
+ * `reviewer`, `planner`, `critic`), the fast-only `oracle` peer tool, no coordinator,
27528
+ * and only `peers`/`search` plus the ordinary opt-in `browser` group.
27529
+ * `workers`/`orchestrate`/`decide`/`fleet`/`first-mate` are hard denies even
27530
+ * when their independent standard-profile gates pass.
27531
+ */
27532
+ const FAST_PROFILE = Object.freeze({
27533
+ id: "fast",
27534
+ nativeRoster: /* @__PURE__ */ new Set([
27535
+ "scout",
27536
+ "implementer",
27537
+ "reviewer",
27538
+ "planner",
27539
+ "critic"
27540
+ ]),
27541
+ personaAllowlist: /* @__PURE__ */ new Set(["oracle"]),
27542
+ allowedGroups: /* @__PURE__ */ new Set([
27543
+ "peers",
27544
+ "search",
27545
+ "browser"
27546
+ ]),
27547
+ hasCoordinator: false
27548
+ });
27549
+ function profileDescriptor(id) {
27550
+ return id === "fast" ? FAST_PROFILE : STANDARD_PROFILE;
27551
+ }
27552
+ /**
27553
+ * Resolve the parsed `-m` argument to a launch profile.
27554
+ *
27555
+ * Deliberately keyed on the RAW alias string (trimmed, case-insensitive
27556
+ * `"fast"`), never on a resolved model id: `resolveLeadSlugArg` maps `fast`
27557
+ * to `FAST_LEAD_MODEL` (`./port`) before this is of any use to a caller who
27558
+ * only has the resolved id, so callers that already resolved the lead must
27559
+ * pass the ORIGINAL `-m` value here, not the resolved one. This is what
27560
+ * keeps `-m gpt-5.6-luna` (a direct pin of the same underlying model) a
27561
+ * standard-surface launch — only the literal alias narrows the surface.
27562
+ */
27563
+ function resolveLaunchProfile(modelArg) {
27564
+ return modelArg?.trim().toLowerCase() === "fast" ? "fast" : "standard";
27565
+ }
27566
+ /**
27567
+ * Router-owned alias id for the fast profile's Sonnet-tier row
27568
+ * (`ANTHROPIC_DEFAULT_SONNET_MODEL`). Never sent upstream — canonicalized to
27569
+ * `LUNA_REAL_MODEL_ID` by `canonicalizeAliasModel` before the request
27570
+ * reaches Copilot.
27571
+ */
27572
+ const LUNA_DRIVER_ALIAS_ID = "gh-router-luna-driver-max";
27573
+ /** Fast native-agent alias ids preserve role-specific effort provenance until
27574
+ * the authenticated request boundary. They both canonicalize to Luna, but the
27575
+ * scout is fixed high while the implementer is fixed max. */
27576
+ const LUNA_SCOUT_ALIAS_ID = "gh-router-luna-scout-high";
27577
+ const LUNA_IMPLEMENTER_ALIAS_ID = "gh-router-luna-implementer-max";
27578
+ /** Fast-profile critic alias. It preserves Gemini's fixed medium effort until
27579
+ * the authenticated request boundary; bare Gemini remains high for the lead
27580
+ * and Advisor traffic. */
27581
+ const FAST_CRITIC_ALIAS_ID = "gh-router-fast-critic-medium";
27582
+ const LUNA_SONNET_ALIAS_ID = "gh-router-luna-sonnet-xhigh";
27583
+ /**
27584
+ * Router-owned alias id for the fast profile's Haiku-tier row
27585
+ * (`ANTHROPIC_DEFAULT_HAIKU_MODEL` / `ANTHROPIC_SMALL_FAST_MODEL`).
27586
+ */
27587
+ const LUNA_HAIKU_ALIAS_ID = "gh-router-luna-haiku-high";
27588
+ /** The real Copilot catalog id every Luna alias (including the driver
27589
+ * itself) canonicalizes to. */
27590
+ const LUNA_REAL_MODEL_ID = "gpt-5.6-luna";
27591
+ /**
27592
+ * The full alias table, keyed by `aliasId`. A simpler model-id-only table is
27593
+ * rejected by design: the driver, the Sonnet tier, and the Haiku tier all
27594
+ * resolve to the SAME Luna catalog id, while the fast critic alias resolves
27595
+ * to Gemini. After early canonicalization a table keyed on the real id could
27596
+ * no longer tell which absent-effort default applies. Alias provenance is the
27597
+ * minimum discriminator that survives from tier selection through to request
27598
+ * preprocessing, which is why canonicalization must happen LAST (in the
27599
+ * `/v1/messages` identity preflight), after the effort default has already
27600
+ * been read off the alias.
27601
+ */
27602
+ const MODEL_ALIAS_TABLE = /* @__PURE__ */ new Map([
27603
+ [LUNA_DRIVER_ALIAS_ID, {
27604
+ aliasId: LUNA_DRIVER_ALIAS_ID,
27605
+ realModel: LUNA_REAL_MODEL_ID,
27606
+ absentEffortDefault: "max"
27607
+ }],
27608
+ [LUNA_SCOUT_ALIAS_ID, {
27609
+ aliasId: LUNA_SCOUT_ALIAS_ID,
27610
+ realModel: LUNA_REAL_MODEL_ID,
27611
+ absentEffortDefault: "high"
27612
+ }],
27613
+ [LUNA_IMPLEMENTER_ALIAS_ID, {
27614
+ aliasId: LUNA_IMPLEMENTER_ALIAS_ID,
27615
+ realModel: LUNA_REAL_MODEL_ID,
27616
+ absentEffortDefault: "max"
27617
+ }],
27618
+ [FAST_CRITIC_ALIAS_ID, {
27619
+ aliasId: FAST_CRITIC_ALIAS_ID,
27620
+ realModel: "gemini-3.7-flash",
27621
+ absentEffortDefault: "medium"
27622
+ }],
27623
+ [LUNA_SONNET_ALIAS_ID, {
27624
+ aliasId: LUNA_SONNET_ALIAS_ID,
27625
+ realModel: LUNA_REAL_MODEL_ID,
27626
+ absentEffortDefault: "xhigh"
27627
+ }],
27628
+ [LUNA_HAIKU_ALIAS_ID, {
27629
+ aliasId: LUNA_HAIKU_ALIAS_ID,
27630
+ realModel: LUNA_REAL_MODEL_ID,
27631
+ absentEffortDefault: "high"
27632
+ }]
27633
+ ]);
27634
+ /**
27635
+ * Look up the alias descriptor for a wire-facing model id (with or without
27636
+ * a trailing `[1m]` bracket — the bracket is stripped before the table
27637
+ * lookup and is orthogonal to alias identity). Returns undefined for any
27638
+ * id that isn't one of the registered aliases (including bare `claude-*`
27639
+ * ids and every other real Copilot catalog id).
27640
+ */
27641
+ function resolveModelAlias(id) {
27642
+ const { base } = stripTrailingOneMSuffix(id);
27643
+ return MODEL_ALIAS_TABLE.get(base);
27644
+ }
27645
+ /**
27646
+ * Strip alias provenance and return the real catalog id to send upstream.
27647
+ * Idempotent passthrough for any id that isn't a registered alias (a bare
27648
+ * `claude-*` slug, an already-real Copilot id, or anything else) — this is
27649
+ * safe to call unconditionally on every `body.model` at the outbound
27650
+ * boundary. Preserves a trailing `[1m]` bracket: canonicalization only
27651
+ * erases ALIAS identity, not the 1M-context accounting decoration.
27652
+ */
27653
+ function canonicalizeAliasModel(id) {
27654
+ const { base, hadSuffix } = stripTrailingOneMSuffix(id);
27655
+ const alias = MODEL_ALIAS_TABLE.get(base);
27656
+ if (!alias) return normalizeTrailingOneMSuffix(id);
27657
+ return hadSuffix ? `${alias.realModel}[1m]` : alias.realModel;
27658
+ }
27659
+ const FAST_REQUIRED_CONTEXT_TOKENS = 1e6;
27660
+ function findModel(catalog, id) {
27661
+ return catalog?.data?.find((m) => m.id === id);
27662
+ }
27663
+ function hasToolCalls(model) {
27664
+ return model?.capabilities?.supports?.tool_calls === true;
27665
+ }
27666
+ function hasContextAtLeast(model, tokens) {
27667
+ return (model?.capabilities?.limits?.max_context_window_tokens ?? 0) >= tokens;
27668
+ }
27669
+ function supportsEffort(model, effort) {
27670
+ const list = model?.capabilities?.supports?.reasoning_effort;
27671
+ return Array.isArray(list) && list.includes(effort);
27672
+ }
27673
+ const FAST_REVIEWER_MIN_PROMPT_TOKENS = 2e5;
27674
+ function supportsEndpoint(model, endpoint) {
27675
+ return model !== void 0 && fastEndpointForModel(model) === endpoint;
27676
+ }
27677
+ function hasUsablePromptMetadata(model) {
27678
+ const prompt = model?.capabilities?.limits?.max_prompt_tokens;
27679
+ return typeof prompt === "number" && Number.isFinite(prompt) && prompt > 0;
27680
+ }
27681
+ function hasPromptAtLeast(model, tokens) {
27682
+ const prompt = model?.capabilities?.limits?.max_prompt_tokens;
27683
+ return typeof prompt === "number" && Number.isFinite(prompt) && prompt >= tokens;
27684
+ }
27685
+ /**
27686
+ * Validate the live Copilot catalog carries every model the fast profile's
27687
+ * EXACT roster depends on, with the specific capabilities each assignment
27688
+ * needs. These are capability-availability PREREQUISITES for constructing
27689
+ * the roster — not an allowlist of models the user may select later in the
27690
+ * session — so a partial catalog fails the whole `-m fast` launch rather
27691
+ * than silently substituting or dropping an agent.
27692
+ *
27693
+ * Checks, per the fast-launch-profile design:
27694
+ * - Luna lead/scout/implementer: tool calls, >=1M, high+max, Responses.
27695
+ * - Sol planner: tool calls, >=1M, high, Responses.
27696
+ * - Grok reviewer: tool calls, medium, Responses, usable prompt metadata.
27697
+ * - Gemini Advisor: >=1M, high, chat-completions.
27698
+ * - Gemini critic: tool calls, >=1M, medium, chat-completions.
27699
+ * - Opus Oracle: exact Opus 5, >=1M, adaptive/high, Messages, prompt metadata.
27700
+ *
27701
+ * Pure over the passed-in catalog snapshot so it's unit-testable without
27702
+ * `state` — callers pass `state.models` at call time.
27703
+ */
27704
+ function validateFastProfilePrerequisites(catalog) {
27705
+ const missing = [];
27706
+ const luna = findModel(catalog, LUNA_REAL_MODEL_ID);
27707
+ if (!luna) missing.push(`${LUNA_REAL_MODEL_ID}: absent from the live catalog`);
27708
+ else {
27709
+ if (!hasToolCalls(luna)) missing.push(`${LUNA_REAL_MODEL_ID}: does not advertise tool_calls`);
27710
+ if (!hasContextAtLeast(luna, FAST_REQUIRED_CONTEXT_TOKENS)) missing.push(`${LUNA_REAL_MODEL_ID}: advertised context window is below 1M`);
27711
+ if (!supportsEffort(luna, "high") || !supportsEffort(luna, "max")) missing.push(`${LUNA_REAL_MODEL_ID}: does not advertise both "high" and "max" reasoning effort`);
27712
+ if (!supportsEndpoint(luna, "responses")) missing.push(`${LUNA_REAL_MODEL_ID}: does not advertise a supported Responses endpoint`);
27713
+ }
27714
+ const sol = findModel(catalog, "gpt-5.6-sol");
27715
+ if (!sol) missing.push("gpt-5.6-sol: absent from the live catalog");
27716
+ else {
27717
+ if (!hasToolCalls(sol)) missing.push("gpt-5.6-sol: does not advertise tool_calls");
27718
+ if (!hasContextAtLeast(sol, FAST_REQUIRED_CONTEXT_TOKENS)) missing.push("gpt-5.6-sol: advertised context window is below 1M");
27719
+ if (!supportsEffort(sol, "high")) missing.push("gpt-5.6-sol: does not advertise a \"high\" reasoning effort");
27720
+ if (!supportsEndpoint(sol, "responses")) missing.push("gpt-5.6-sol: does not advertise a supported Responses endpoint");
27721
+ }
27722
+ const grok = findModel(catalog, "grok-4.6");
27723
+ if (!grok) missing.push("grok-4.6: absent from the live catalog");
27724
+ else {
27725
+ if (!hasToolCalls(grok)) missing.push("grok-4.6: does not advertise tool_calls");
27726
+ if (!supportsEffort(grok, "medium")) missing.push("grok-4.6: does not advertise a \"medium\" reasoning effort");
27727
+ if (!hasPromptAtLeast(grok, 2e5)) missing.push(`grok-4.6: advertised max_prompt_tokens is below ${FAST_REVIEWER_MIN_PROMPT_TOKENS}`);
27728
+ if (!supportsEndpoint(grok, "responses")) missing.push("grok-4.6: does not advertise a supported Responses endpoint");
27729
+ }
27730
+ const gemini = findModel(catalog, "gemini-3.7-flash");
27731
+ if (!gemini) missing.push("gemini-3.7-flash: absent from the live catalog");
27732
+ else {
27733
+ if (!hasToolCalls(gemini)) missing.push("gemini-3.7-flash: does not advertise tool_calls for the native critic");
27734
+ if (!hasContextAtLeast(gemini, FAST_REQUIRED_CONTEXT_TOKENS)) missing.push("gemini-3.7-flash: advertised context window is below 1M");
27735
+ if (!supportsEffort(gemini, "high")) missing.push("gemini-3.7-flash: does not advertise a \"high\" reasoning effort for Advisor");
27736
+ if (!supportsEffort(gemini, "medium")) missing.push("gemini-3.7-flash: does not advertise a \"medium\" reasoning effort for the native critic");
27737
+ if (!supportsEndpoint(gemini, "chat")) missing.push("gemini-3.7-flash: does not advertise a supported chat-completions endpoint");
27738
+ }
27739
+ const opus = findModel(catalog, "claude-opus-5");
27740
+ if (!opus) missing.push("claude-opus-5: absent from the live catalog");
27741
+ else {
27742
+ if (!hasContextAtLeast(opus, FAST_REQUIRED_CONTEXT_TOKENS)) missing.push("claude-opus-5: advertised context window is below 1M");
27743
+ if (!supportsEffort(opus, "high")) missing.push("claude-opus-5: does not advertise a \"high\" reasoning effort");
27744
+ if (opus.capabilities?.supports?.adaptive_thinking !== true) missing.push("claude-opus-5: does not advertise adaptive_thinking");
27745
+ if (!hasUsablePromptMetadata(opus)) missing.push("claude-opus-5: no usable max_prompt_tokens metadata");
27746
+ if (!supportsEndpoint(opus, "messages")) missing.push("claude-opus-5: does not advertise a supported Messages endpoint");
27747
+ }
27748
+ return {
27749
+ ok: missing.length === 0,
27750
+ missing
27751
+ };
27752
+ }
27753
+ /**
27754
+ * Format `validateFastProfilePrerequisites`'s failure list into the launch
27755
+ * error message: every missing/invalid model, plus the rollback command.
27756
+ */
27757
+ function formatFastPrerequisiteFailure(missing) {
27758
+ return "github-router claude -m fast requires the following live-catalog capabilities, which this account's catalog does not fully provide:\n" + missing.map((m) => ` - ${m}`).join("\n") + "\n\nFalling back or silently dropping an agent is not supported for the fast profile's exact roster. Run plain `github-router claude` instead.";
27759
+ }
27760
+ //#endregion
27457
27761
  //#region src/lib/mcp-capabilities.ts
27458
27762
  /**
27459
27763
  * Capability-gate predicates for the proxy's MCP tool surface.
@@ -27707,22 +28011,30 @@ const FAST_IMPLEMENTER_MODEL = "gpt-5.6-luna";
27707
28011
  * and is gated by max_prompt_tokens rather than the 1M floor. */
27708
28012
  const FAST_REVIEWER_MODEL = "grok-4.6";
27709
28013
  const FAST_PLANNER_MODEL = "gpt-5.6-sol";
28014
+ const FAST_CRITIC_MODEL = "gemini-3.7-flash";
27710
28015
  const FAST_ORACLE_MODEL = "claude-opus-5";
27711
28016
  /** Fixed effort pins for the fast profile. */
27712
28017
  const FAST_SCOUT_EFFORT = "high";
27713
28018
  const FAST_REVIEWER_EFFORT = "medium";
27714
28019
  const FAST_PLANNER_EFFORT = "high";
28020
+ const FAST_CRITIC_EFFORT = "medium";
27715
28021
  function fastScoutModel() {
27716
- return firstPresentInCatalog([FAST_SCOUT_MODEL], {
28022
+ const id = firstPresentInCatalog([FAST_SCOUT_MODEL], {
27717
28023
  requireToolCalls: true,
27718
28024
  minContextTokens: ONE_M_TOKENS
27719
28025
  });
28026
+ if (!id) return void 0;
28027
+ const found = state.models?.data.find((m) => m.id === id);
28028
+ return found && fastEndpointForModel(found) === "responses" ? id : void 0;
27720
28029
  }
27721
28030
  function fastImplementerModel() {
27722
- return firstPresentInCatalog([FAST_IMPLEMENTER_MODEL], {
28031
+ const id = firstPresentInCatalog([FAST_IMPLEMENTER_MODEL], {
27723
28032
  requireToolCalls: true,
27724
28033
  minContextTokens: ONE_M_TOKENS
27725
28034
  });
28035
+ if (!id) return void 0;
28036
+ const found = state.models?.data.find((m) => m.id === id);
28037
+ return found && fastEndpointForModel(found) === "responses" ? id : void 0;
27726
28038
  }
27727
28039
  function fastPlannerModel() {
27728
28040
  const id = firstPresentInCatalog([FAST_PLANNER_MODEL], {
@@ -27733,7 +28045,7 @@ function fastPlannerModel() {
27733
28045
  const found = state.models?.data.find((m) => m.id === id);
27734
28046
  const efforts = found?.capabilities?.supports?.reasoning_effort;
27735
28047
  if (!Array.isArray(efforts) || !efforts.includes("high")) return void 0;
27736
- if (pickEndpoint(found) !== "responses") return void 0;
28048
+ if (!found || fastEndpointForModel(found) !== "responses") return void 0;
27737
28049
  return id;
27738
28050
  }
27739
28051
  /** Gate Grok on the prompt limit that actually constrains pasted review input. */
@@ -27746,9 +28058,21 @@ function fastReviewerModel() {
27746
28058
  const efforts = found.capabilities?.supports?.reasoning_effort;
27747
28059
  if (!Array.isArray(efforts) || !efforts.includes("medium")) return void 0;
27748
28060
  if ((found.capabilities?.limits?.max_prompt_tokens ?? 0) < 2e5) return void 0;
27749
- if (pickEndpoint(found) !== "responses") return void 0;
28061
+ if (fastEndpointForModel(found) !== "responses") return void 0;
27750
28062
  return FAST_REVIEWER_MODEL;
27751
28063
  }
28064
+ /** Exact Gemini 3.7 Flash only: the fast native critic has no fallback.
28065
+ * Unlike the fast Advisor, it needs tool calls and a medium effort choice. */
28066
+ function fastCriticModel() {
28067
+ const found = state.models?.data.find((m) => m.id === FAST_CRITIC_MODEL);
28068
+ if (!found) return void 0;
28069
+ if (found.capabilities?.supports?.tool_calls !== true) return void 0;
28070
+ if ((found.capabilities?.limits?.max_context_window_tokens ?? 0) < 1e6) return void 0;
28071
+ const efforts = found.capabilities?.supports?.reasoning_effort;
28072
+ if (!Array.isArray(efforts) || !efforts.includes("medium")) return void 0;
28073
+ if (fastEndpointForModel(found) !== "chat") return void 0;
28074
+ return FAST_CRITIC_MODEL;
28075
+ }
27752
28076
  /** Exact Opus 5 only: the fast Oracle never inherits standard opus_critic's
27753
28077
  * older-family fallback. */
27754
28078
  function fastOracleModel() {
@@ -27759,7 +28083,7 @@ function fastOracleModel() {
27759
28083
  const efforts = found.capabilities?.supports?.reasoning_effort;
27760
28084
  if (!Array.isArray(efforts) || !efforts.includes("high")) return void 0;
27761
28085
  if (found.capabilities?.supports?.adaptive_thinking !== true) return void 0;
27762
- if (!(found.supported_endpoints ?? []).some((endpoint) => endpoint === "/messages" || endpoint === "/v1/messages")) return void 0;
28086
+ if (fastEndpointForModel(found) !== "messages") return void 0;
27763
28087
  return FAST_ORACLE_MODEL;
27764
28088
  }
27765
28089
  /**
@@ -29602,31 +29926,16 @@ const ADVISOR_MIN_EFFORT = "high";
29602
29926
  * the decorrelation instrument and are untouched. `GH_ROUTER_ADVISOR_MODEL`
29603
29927
  * keeps a cross-lab advisor one env var away for anyone who wants it back. */
29604
29928
  const ADVISOR_ESCALATION_MODEL = "claude-opus-5";
29605
- /** The Advisor model for the fast Luna profile. Gemini 3.7 Flash is a
29606
- * different lab from BOTH the Luna lead (OpenAI) and the fast profile's
29607
- * `gemini-critic` persona shares this same model see
29608
- * `docs/default-models.md` "Fast launch profile" for the roster this
29609
- * belongs to. Kept distinct from `ADVISOR_DEFAULT_MODEL` so the two never
29610
- * have to agree; `resolveAdvisorModel` picks between them purely on lead
29611
- * identity, never model availability heuristics beyond a live-catalog
29612
- * presence check (mirrors `shouldEscalateAdvisor`'s pattern). */
29929
+ /** The Advisor model for an authenticated fast primary lead. Gemini 3.7 Flash
29930
+ * is cross-lab from the OpenAI-backed Luna/Sol leads and is selected only when
29931
+ * its live catalog entry advertises the required Chat endpoint. Kept distinct
29932
+ * from `ADVISOR_DEFAULT_MODEL` so standard launches remain unchanged. */
29613
29933
  const ADVISOR_FAST_PROFILE_MODEL = "gemini-3.7-flash";
29614
- /**
29615
- * True when `leadModel` names the fast-profile Luna lead (bare, or with the
29616
- * `[1m]` context decoration `withOneMSuffixForLead` applies to it).
29617
- */
29618
- function isFastProfileLead(leadModel) {
29619
- if (!leadModel) return false;
29620
- const bare = leadModel.replace(/\[1m\]$/, "").trim();
29621
- const lastSegment = bare.slice(bare.lastIndexOf("/") + 1);
29622
- return bare === "gpt-5.6-luna" || lastSegment === "gpt-5.6-luna";
29623
- }
29624
- /** True when the live catalog actually carries `ADVISOR_FAST_PROFILE_MODEL`.
29625
- * Mirrors `shouldEscalateAdvisor`'s catalog probe: never advertise a model
29626
- * the account cannot reach, and fall back to the cross-lab default instead
29627
- * of a hard failure when it's absent. */
29934
+ /** True only when the live Gemini entry satisfies the fixed fast transport.
29935
+ * An ID-only presence check is insufficient: selecting a model whose catalog
29936
+ * row lost Chat support would silently degrade every fast Advisor call. */
29628
29937
  function fastProfileAdvisorAvailable() {
29629
- return state.models?.data?.some((m) => m.id === "gemini-3.7-flash") ?? false;
29938
+ return fastEndpointForCatalogId(ADVISOR_FAST_PROFILE_MODEL, state.models?.data) === "chat";
29630
29939
  }
29631
29940
  /** Output cap for the Anthropic-branch advisor call when the catalog carries no
29632
29941
  * limits for the resolved model. The value the branch used unconditionally
@@ -29673,10 +29982,18 @@ function advisorUsesResponses(resolvedAdvisorModel) {
29673
29982
  * chat, mirroring `pickEndpoint`'s "omits supported_endpoints => chat-eligible"
29674
29983
  * convention — the same convention `classifyMessagesRoute` relies on for a
29675
29984
  * lead model, applied here to the advisor's OWN model instead.
29985
+ *
29986
+ * The authenticated fast Advisor passes `fastProfile:true`, which uses the same
29987
+ * fixed endpoint policy as its lead/agent roster. Standard calls leave this
29988
+ * false and retain the historical catalog/name behavior.
29676
29989
  */
29677
- function advisorTransport(resolvedAdvisorModel) {
29990
+ function advisorTransport(resolvedAdvisorModel, fastProfile = false) {
29678
29991
  const bare = resolvedAdvisorModel.slice(resolvedAdvisorModel.lastIndexOf("/") + 1);
29679
29992
  const entry = state.models?.data?.find((m) => m.id === resolvedAdvisorModel || m.id === bare);
29993
+ if (fastProfile && entry) {
29994
+ const fixed = fastEndpointForModel(entry);
29995
+ if (fixed === "messages" || fixed === "responses" || fixed === "chat") return fixed;
29996
+ }
29680
29997
  if (isClaudeModel(resolvedAdvisorModel, entry)) return "messages";
29681
29998
  if (advisorUsesResponses(resolvedAdvisorModel)) return "responses";
29682
29999
  return "chat";
@@ -29707,29 +30024,20 @@ function shouldEscalateAdvisor(leadModel) {
29707
30024
  return state.models?.data?.some((m) => m.id === "claude-opus-5") ?? false;
29708
30025
  }
29709
30026
  /**
29710
- * Pick the advisor model for one request from the LEAD model that request is
29711
- * running on.
29712
- *
29713
- * Resolved per request rather than at launch because the lead changes
29714
- * mid-session via the `/model` picker; launch-time env plumbing would pin the
29715
- * advisor to whatever was selected at spawn.
30027
+ * Pick the Advisor model for one request. Standard selection follows the
30028
+ * current lead so a `/model` switch can change budget escalation; authenticated
30029
+ * fast selection follows launch identity instead, so changing among the fixed
30030
+ * fast lead models never removes Gemini Advisor.
29716
30031
  *
29717
30032
  * Precedence:
29718
- * 1. `GH_ROUTER_ADVISOR_MODEL` (trimmed) the operator pin, checked first so
29719
- * it works on every lead.
29720
- * 2. An authenticated fast launch whose current lead is Luna, with
29721
- * `ADVISOR_FAST_PROFILE_MODEL` present in the live catalog.
29722
- * 3. A lighter Claude lead with the escalation model in the catalog.
29723
- * 4. `ADVISOR_DEFAULT_MODEL`.
30033
+ * 1. `GH_ROUTER_ADVISOR_MODEL` (trimmed), on every launch and lead.
30034
+ * 2. Authenticated fast primary lead, when Gemini advertises the required
30035
+ * Chat endpoint.
30036
+ * 3. Standard lighter Claude lead with Opus escalation available.
30037
+ * 4. The literal `ADVISOR_DEFAULT_MODEL`.
29724
30038
  *
29725
- * Steps 2 and 3 are mutually exclusive lead families (non-Claude Luna vs. a
29726
- * lighter Claude tier) so their relative order does not matter functionally;
29727
- * fast-profile is checked first only because it is the more specific match.
29728
- *
29729
- * Step 4 returns the LITERAL constant rather than walking the OpenAI frontier
29730
- * chain. An Opus lead must resolve to exactly what it resolves to today, and a
29731
- * frontier walk could yield `gpt-5.5` on a catalog missing `gpt-5.6-sol` —
29732
- * a silent change to the one path that is required not to move.
30039
+ * Step 4 deliberately does not walk the OpenAI frontier chain. That would
30040
+ * silently change the standard Opus-lead path when Sol is absent.
29733
30041
  */
29734
30042
  /**
29735
30043
  * Map an operator pin onto the id the catalog actually carries.
@@ -29762,7 +30070,7 @@ function resolveAdvisorModel(leadModel, fastProfile = false) {
29762
30070
  escalated: false,
29763
30071
  fastProfile: false
29764
30072
  };
29765
- if (fastProfile && leadModel && isFastProfileLead(leadModel) && fastProfileAdvisorAvailable()) return {
30073
+ if (fastProfile && fastProfileAdvisorAvailable()) return {
29766
30074
  model: ADVISOR_FAST_PROFILE_MODEL,
29767
30075
  escalated: false,
29768
30076
  fastProfile: true
@@ -29840,6 +30148,18 @@ On tasks longer than a few steps, call advisor at least once before committing t
29840
30148
  Give the advice serious weight. If you follow a step and it fails empirically, or you have primary-source evidence that contradicts a specific claim (the file says X, the code does Y), adapt. A passing self-test is not evidence the advice is wrong -- it's evidence your test doesn't check what the advice is checking.
29841
30149
 
29842
30150
  If you've already retrieved data pointing one way and the advisor points another: don't silently switch. Surface the conflict in one more advisor call -- "I found X, you suggest Y, which constraint breaks the tie?" The advisor saw your evidence but may have underweighted it; a reconcile call is cheaper than committing to the wrong branch.`;
30151
+ /** Fast-profile lead-only policy. Unlike the standard Claude Code instructions
30152
+ * above, this makes consultation optional and leaves decision ownership with
30153
+ * the authenticated fast primary lead. Fast Task subagents never receive an advisor tool at all. */
30154
+ const FAST_ADVISOR_TOOL_INSTRUCTIONS = `# Advisor Tool
30155
+
30156
+ You have access to an optional, transcript-aware \`advisor\` tool. It takes no parameters and returns non-binding consultation. You remain responsible for every decision.
30157
+
30158
+ Use advisor only when a focused, consequential uncertainty remains after direct investigation: conflicting evidence, a materially changed assumption, a genuinely non-converging approach, a hard-to-reverse trade-off, or an explicit request for a fresh perspective. State the precise uncertainty in your response immediately before calling it.
30159
+
30160
+ Do not call advisor for routine progress, while waiting on a subagent, after ordinary tool output, for a fact that code or a command can verify, to obtain planner approval or reviewer verification, or as a ritual before implementation or completion.
30161
+
30162
+ Treat the result as advice, not authority. Weigh it against the user's intent, verified repository evidence, planner output, and reviewer findings. You may consult again when materially new evidence creates a different question or directly conflicts with earlier advice.`;
29843
30163
  const ADVISOR_OPT_OUT_ENV = "CLAUDE_CODE_DISABLE_ADVISOR_TOOL";
29844
30164
  /**
29845
30165
  * Detect whether the request asked for ADVISOR (incoming
@@ -29872,8 +30192,8 @@ function isAdvisorRequested(rawBetaHeader) {
29872
30192
  * client-shape `server_tool_use{name:"advisor"}` + `advisor_tool_result`
29873
30193
  * blocks the client expects.
29874
30194
  */
29875
- function injectAdvisorTool(rawBody) {
29876
- if (rawBody.includes(`"name":"__anthropic_advisor"`) && !rawBody.includes("\"advisor_")) return rawBody;
30195
+ function injectAdvisorTool(rawBody, instructions = ADVISOR_TOOL_INSTRUCTIONS) {
30196
+ if (instructions === ADVISOR_TOOL_INSTRUCTIONS && rawBody.includes(`"name":"__anthropic_advisor"`) && !rawBody.includes("\"advisor_")) return rawBody;
29877
30197
  let parsed;
29878
30198
  try {
29879
30199
  parsed = JSON.parse(rawBody);
@@ -29888,10 +30208,14 @@ function injectAdvisorTool(rawBody) {
29888
30208
  });
29889
30209
  const stripped = tools.length !== rawTools.length;
29890
30210
  const alreadyInjected = tools.some((t) => t?.name === ADVISOR_INTERNAL_TOOL_NAME);
29891
- if (alreadyInjected && !stripped) return rawBody;
29892
- parsed.tools = alreadyInjected ? tools : [...tools, {
30211
+ const needsDescriptionUpdate = alreadyInjected && tools.some((t) => t?.name === "__anthropic_advisor" && t.description !== instructions);
30212
+ if (alreadyInjected && !stripped && !needsDescriptionUpdate) return rawBody;
30213
+ parsed.tools = alreadyInjected ? tools.map((tool) => tool?.name === "__anthropic_advisor" ? {
30214
+ ...tool,
30215
+ description: instructions
30216
+ } : tool) : [...tools, {
29893
30217
  name: ADVISOR_INTERNAL_TOOL_NAME,
29894
- description: ADVISOR_TOOL_INSTRUCTIONS,
30218
+ description: instructions,
29895
30219
  input_schema: {
29896
30220
  type: "object",
29897
30221
  properties: {},
@@ -30032,9 +30356,9 @@ function truncateTailToUnits(text, maxUnits, measure) {
30032
30356
  * Anthropic's own ADVISOR ("see the whole task + every tool call +
30033
30357
  * every result").
30034
30358
  */
30035
- async function runAdvisor(conversation, advisorModel, advisorEffort, signal, advisorEscalated = false) {
30359
+ async function runAdvisor(conversation, advisorModel, advisorEffort, signal, advisorEscalated = false, fastProfile = false) {
30036
30360
  if (signal?.aborted) throw new Error("advisor call aborted before dispatch");
30037
- const advisorSystem = "You are an expert advisor reviewing an in-progress Claude Code session. The transcript below is the work-in-progress (turns numbered, with tool calls and results inlined). Read carefully and provide concrete, actionable advice on the next step or course-correction. Be specific — cite the parts of the transcript you're responding to. If the assistant is on the right track, say so explicitly. If they're stuck or off-track, name the specific assumption or step to revisit. Aim for 2-5 paragraphs of substantive guidance." + (advisorEscalated ? " The requesting agent is running a lighter, faster model than you. Give a directive recommendation and commit to the decision rather than laying out options for it to weigh." : "");
30361
+ const advisorSystem = "You are an expert advisor reviewing an in-progress Claude Code session. The transcript below is the work-in-progress (turns numbered, with tool calls and results inlined). Read carefully and provide concrete, actionable advice on the next step or course-correction. Be specific — cite the parts of the transcript you're responding to. If the assistant is on the right track, say so explicitly. If they're stuck or off-track, name the specific assumption or step to revisit. Aim for 2-5 paragraphs of substantive guidance." + (fastProfile ? " You are a non-binding consultant to the primary lead. Analyze the focused uncertainty that prompted this call and provide a recommendation, its assumptions, material risks, credible alternatives, confidence, and any evidence gap that should be resolved. Do not approve, veto, dictate, or take ownership of the workflow; the lead will weigh your advice against the user's intent and verified evidence." : "") + (advisorEscalated && !fastProfile ? " The requesting agent is running a lighter, faster model than you. Give a directive recommendation and commit to the decision rather than laying out options for it to weigh." : "");
30038
30362
  const resolvedAdvisorModel = resolveModel(advisorModel);
30039
30363
  let measure;
30040
30364
  let maxUnits;
@@ -30049,7 +30373,7 @@ async function runAdvisor(conversation, advisorModel, advisorEffort, signal, adv
30049
30373
  maxUnits = ADVISOR_MAX_CONVERSATION_CHARS;
30050
30374
  }
30051
30375
  const conversationText = renderConversationAsText(conversation, maxUnits, measure);
30052
- const transport = advisorTransport(resolvedAdvisorModel);
30376
+ const transport = advisorTransport(resolvedAdvisorModel, fastProfile);
30053
30377
  if (transport === "responses") {
30054
30378
  const payload = applyResponsesCachePolicy({
30055
30379
  model: resolvedAdvisorModel,
@@ -30141,7 +30465,7 @@ async function runAdvisor(conversation, advisorModel, advisorEffort, signal, adv
30141
30465
  * 1. A real Anthropic `toolu_*` id whose suffix is already in the
30142
30466
  * `^[a-zA-Z0-9_]+$` charset: `srvtoolu_<suffix>`, byte-for-byte
30143
30467
  * identical to the historical (Claude-lead) behavior.
30144
- * 2. Anything else — a Responses `call_*` id (the fast Luna profile's
30468
+ * 2. Anything else — a Responses `call_*` id (an authenticated fast lead's
30145
30469
  * lead, once its `tool_use{__anthropic_advisor}` block is synthesized
30146
30470
  * by the anthropic-translate shim from a Copilot `/responses` tool
30147
30471
  * call), a hyphenated or otherwise non-conforming id, an empty string,
@@ -30164,7 +30488,7 @@ async function runAdvisor(conversation, advisorModel, advisorEffort, signal, adv
30164
30488
  * Historically this threw "advisor tool_use id is not round-trippable" for
30165
30489
  * any non-`toolu_` shape. That was correct for a Claude-only advisor lead —
30166
30490
  * Copilot's native `/v1/messages` never emits anything else — but became a
30167
- * live defect once the advisor loop could run on a non-Claude (Luna) lead
30491
+ * live defect once the advisor loop could run on a non-Claude fast lead
30168
30492
  * shimmed through `/responses`: `responses-egress.ts` forwards a Responses
30169
30493
  * `call_*` id VERBATIM as the synthesized `tool_use.id` (see
30170
30494
  * `makeToolUseId` — it only synthesizes a `toolu_*` id when the upstream id
@@ -30194,7 +30518,7 @@ function sseEvent(type, data) {
30194
30518
  * passthrough (`createMessages`) plus signed-thinking-history repair-and-retry.
30195
30519
  * Extracted verbatim from the loop body so the behavior is byte-identical to
30196
30520
  * before `continueTurn` became injectable, and so a non-Claude
30197
- * `continueTurn` (the fast Luna profile's shim-backed one) can omit this
30521
+ * `continueTurn` (the fast profile's shim-backed one) can omit this
30198
30522
  * Claude-only repair path entirely rather than inherit dead code that would
30199
30523
  * never fire for it.
30200
30524
  */
@@ -30237,6 +30561,7 @@ function buildAdvisorStream(opts) {
30237
30561
  const advisorModel = opts.advisorModel ?? "gpt-5.6-sol";
30238
30562
  const advisorEffort = opts.advisorEffort ?? "xhigh";
30239
30563
  const advisorEscalated = opts.advisorEscalated ?? false;
30564
+ const advisorFastProfile = opts.advisorFastProfile ?? false;
30240
30565
  const continueTurn = opts.continueTurn ?? ((body, signal) => defaultContinueTurn(body, signal, opts.requestHeaders));
30241
30566
  const aborter = opts.externalAborter ?? new AbortController();
30242
30567
  let conversation = [...opts.initialConversation];
@@ -30487,7 +30812,7 @@ function buildAdvisorStream(opts) {
30487
30812
  const advisorConversation = conversation;
30488
30813
  const advisorTexts = await Promise.all(advisorToolUses.map(async () => {
30489
30814
  try {
30490
- return await runAdvisor(advisorConversation, advisorModel, advisorEffort, aborter.signal, advisorEscalated);
30815
+ return await runAdvisor(advisorConversation, advisorModel, advisorEffort, aborter.signal, advisorEscalated, advisorFastProfile);
30491
30816
  } catch (err) {
30492
30817
  if (aborter.signal.aborted) throw err;
30493
30818
  const msg = err instanceof Error ? err.message : String(err);
@@ -35556,9 +35881,10 @@ function buildPeerAwarenessSnippet(opts) {
35556
35881
  return [
35557
35882
  "## Peer review and advisor",
35558
35883
  "",
35559
- `This is the fast launch profile. \`mcp__${fastPeersKey}__oracle\` is exact Opus 5 (1M/high), a stateless last-resort consultant after the primary Luna path, Advisor, and reviewer/planner remain stuck. Advisor is the transcript-aware brainstorming, sounding-board, fresh-look, uncertainty, and stuck path.`,
35884
+ `This is the fast launch profile. Advisor is an optional, non-binding, lead-only transcript-aware sounding board for consequential unresolved uncertainty or a genuinely stuck path, not routine progress, waiting, verification, approval, or completion. \`mcp__${fastPeersKey}__oracle\` is exact Opus 5 (1M/high), a stateless last-resort consultant available to the lead, reviewer, and planner.`,
35560
35885
  "",
35561
- `\`mcp__${fastSearchKey}__code\` is semantic-first code search and \`mcp__${fastSearchKey}__web\` surfaces citable sources. Native Task roster: \`scout\` (broad discovery), \`implementer\` (mechanical implementation), \`reviewer\` (repo-aware verification/reproduction), and \`planner\` (Sol plan consultant/approver after Luna's draft). Before implementation obtain planner approval; before declaring done run relevant tests and ask reviewer to verify.${opts.browseAvailable ? ` \`mcp__${key("browser")}__*\` is the opt-in browser surface.` : ""}`
35886
+ `\`mcp__${fastSearchKey}__code\` is semantic-first code search and \`mcp__${fastSearchKey}__web\` surfaces citable sources. Native Task roster: \`scout\` (broad discovery), \`implementer\` (mechanical implementation), \`reviewer\` (repo-aware verification/reproduction), \`planner\` (Sol plan consultant/approver after Luna's draft), and \`critic\` (fresh-context cross-lab review). Before implementation obtain planner approval; before declaring done run relevant tests and ask reviewer to verify.${opts.browseAvailable ? ` \`mcp__${key("browser")}__*\` is the opt-in browser surface.` : ""}`,
35887
+ "Native delegation is ACL-scoped: the lead may invoke all five; planner may invoke reviewer, scout, and critic; implementer may invoke reviewer and critic; reviewer, scout, and critic cannot invoke native subagents."
35562
35888
  ].join("\n");
35563
35889
  }
35564
35890
  const peersKey = key("peers");
@@ -35617,8 +35943,9 @@ function buildPeerAwarenessSummary(opts) {
35617
35943
  if (opts.profile === "fast") return [
35618
35944
  "## Injected capabilities (summary)",
35619
35945
  "",
35620
- "Fast launch profile. Task roster: `scout`, `implementer`, `reviewer`, `planner`. Luna investigates and drafts; `planner` must approve before implementation. Before declaring done, run relevant tests and ask `reviewer` to verify.",
35621
- `Advisor is the transcript-aware brainstorming/sounding-board/fresh-look path. \`mcp__${key("peers")}__oracle\` is exact Opus 5 (1M/high), stateless and last resort. \`mcp__${key("search")}__code\` and \`mcp__${key("search")}__web\` provide search.${opts.browseAvailable ? ` \`mcp__${key("browser")}__*\` provides the opt-in browser.` : ""}`
35946
+ "Fast launch profile. Task roster: `scout`, `implementer`, `reviewer`, `planner`, `critic`. Luna investigates and drafts; `planner` must approve before implementation. Before declaring done, run relevant tests and ask `reviewer` to verify.",
35947
+ "Native delegation is ACL-scoped: the lead may invoke all five; `planner` may invoke `reviewer`, `scout`, and `critic`; `implementer` may invoke `reviewer` and `critic`; `reviewer`, `scout`, and `critic` cannot invoke native subagents.",
35948
+ `Advisor is optional, non-binding, transcript-aware, and lead-only; use it for consequential unresolved uncertainty, not routine progress or workflow gates. \`mcp__${key("peers")}__oracle\` is exact Opus 5 (1M/high), stateless and last resort for the lead, reviewer, and planner. \`mcp__${key("search")}__code\` and \`mcp__${key("search")}__web\` provide search.${opts.browseAvailable ? ` \`mcp__${key("browser")}__*\` provides the opt-in browser.` : ""}`
35622
35949
  ].join("\n");
35623
35950
  const renderNative = (name) => {
35624
35951
  const modelId = opts.nativeAgentModels?.[name];
@@ -36891,6 +37218,6 @@ function enumerateInjectedMcpToolNames(groupKeys, opts = {}) {
36891
37218
  return [...new Set(names)];
36892
37219
  }
36893
37220
  //#endregion
36894
- export { bucketEffort as $, CONDENSED_OPERATING_SEQUENCE as $t, assetFor as A, countTokens as At, resolveAdvisorModel as B, createChatCompletions as Bt, buildEnv as C, withOneMSuffixForLead as Cn, reviewerFastModel as Ct, toolbeltSkipSet as D, standInToolEnabled as Dt, toolbeltEnabled as E, scribeModel as Et, buildAdvisorStream as F, unregisterLaunch as Ft, buildAnthropicErrorEvent as G, provisionBrowserAssets as Gt, rememberThinkingHistoryRepair as H, readResponseBodyCapped as Ht, injectAdvisorTool as I, assembleResponsesPayload as It, logStreamError as J, provisionAndIndexColbert as Jt, buildOpenAIErrorEvent as K, hasSupportedBrowserInstalled as Kt, isAdvisorRequested as L, warnOnTokenPriceDrift as Lt, searchWeb as M, getTokenCount as Mt, ADVISOR_INTERNAL_TOOL_NAME as N, findLaunchBySecret as Nt, vscodeRipgrepPath as O, workerToolsEnabled as Ot, ADVISOR_TOOL_INSTRUCTIONS as P, registerLaunch as Pt, UNKNOWN_EFFORT_ANCHOR as Q, provisionTreeSitterAssets as Qt, isFastProfileLead as R, resolveMcpToolTimeoutMs as Rt, runWorkerAgent as S, withOneMSuffix as Sn, resolveGeminiReviewModel as St, buildToolbeltAwareness as T, scoutModel as Tt, repairKnownThinkingHistory as U, parseJsonOrDiagnose as Ut, formatThinkingRepairDecline as V, MAX_RESPONSE_BODY_BYTES as Vt, repairRejectedThinkingHistory as W, normalizeOpenAIUsage as Wt, relayAnthropicStream as X, extractZipMember as Xt, readIteratorWithTimeout as Y, extractTarGzMember as Yt, EFFORT_ORDER as Z, warmTreeSitterPool as Zt, TEST_DEFAULT_MODEL as _, upstreamMaxConnections as _n, fleetToolsEnabled as _t, buildAgentPrompt as a, BUDGET_SMALL_FAST_SLUG as an, FAST_SCOUT_EFFORT as at, resolveModeDefaults as b, catalogAdvertises1M as bn, implementerFastModel as bt, enumerateInjectedMcpToolNames as c, DEFAULT_CODEX_MODEL_FALLBACKS as cn, brainstormModel as ct, DEFAULT_MODEL_CHAIN as d, UPSTREAM_INACTIVITY_TIMEOUT_MS as dn, browserToolsEnabled as dt, DEFINITION_OF_GREATNESS as en, clampEffort as et, EXPLORE_DEFAULT_MODEL as f, generateRandomPort as fn, fastImplementerModel as ft, REVIEW_DEFAULT_MODEL as g, upstreamAllowH2 as gn, fastScoutModel as gt, PLAN_DEFAULT_MODEL as h, resolveLeadSlugArg as hn, fastReviewerModel as ht, assertMcpToolSurfaceConsistent as i, BUDGET_SMALL_FAST_CATALOG_ID as in, FAST_REVIEWER_EFFORT as it, satisfiesMinVersion as j, createMessages as jt, TOOLBELT_TOOLS$1 as k, shimDefaultsToXhigh as kt, personasFor as l, DEFAULT_PORT as ln, browseAgentEnabled as lt, IMPLEMENT_DEFAULT_MODEL as m, pickClaudeDefault as mn, fastPlannerModel as mt, MCP_GROUPS as n, collapsePathKeys as nn, handleMcpPost as nt, buildPeerAwarenessSnippet as o, DEFAULT_CLAUDE_MODEL_FALLBACKS as on, agentToolsEnabled as ot, EXPLORE_DEFAULT_THINKING as p, isBudgetClaudeLead as pn, fastOracleModel as pt, isControllerClosedError as q, colbertDegradedWarning as qt, agentNamesForToolAllowlist as r, toolbeltPathOverride as rn, FAST_PLANNER_EFFORT as rt, buildPeerAwarenessSummary as s, DEFAULT_CODEX_MODEL as sn, artifactToolsEnabled as st, GROUP_META as t, shouldUseInsecureTls as tn, handleMcpDelete as tt, BROWSE_DEFAULT_MODEL as u, UPSTREAM_FETCH_TIMEOUT_MS as un, browserCompoundToolsEnabled as ut, appendPlanReminder as v, classifyMessagesRoute as vn, geminiAvailable as vt, availableToolCommands as w, withInstallLock as wn, reviewerModel as wt, resolveWorkerRunOpts as x, oneMContextDisabled as xn, nativeSubagentModel as xt, resolveDefaultModel as y, pickEndpoint as yn, generalPurposeFastModel as yt, resolveAdvisorEffort as z, createResponses as zt };
37221
+ export { bucketEffort as $, assembleResponsesPayload as $t, assetFor as A, isBudgetClaudeLead as An, workerToolsEnabled as At, resolveAdvisorModel as B, stripTrailingOneMSuffix as Bn, profileDescriptor as Bt, buildEnv as C, DEFAULT_CLAUDE_MODEL_FALLBACKS as Cn, nativeSubagentModel as Ct, toolbeltSkipSet as D, UPSTREAM_FETCH_TIMEOUT_MS as Dn, scoutModel as Dt, toolbeltEnabled as E, DEFAULT_PORT as En, reviewerModel as Et, FAST_ADVISOR_TOOL_INSTRUCTIONS as F, classifyMessagesRoute as Fn, LUNA_REAL_MODEL_ID as Ft, buildAnthropicErrorEvent as G, countTokens as Gt, rememberThinkingHistoryRepair as H, resolveModelAlias as Ht, buildAdvisorStream as I, catalogAdvertises1M as In, LUNA_SCOUT_ALIAS_ID as It, logStreamError as J, getTokenCount as Jt, buildOpenAIErrorEvent as K, createMessages as Kt, injectAdvisorTool as L, oneMContextDisabled as Ln, LUNA_SONNET_ALIAS_ID as Lt, searchWeb as M, resolveLeadSlugArg as Mn, LUNA_DRIVER_ALIAS_ID as Mt, ADVISOR_INTERNAL_TOOL_NAME as N, upstreamAllowH2 as Nn, LUNA_HAIKU_ALIAS_ID as Nt, vscodeRipgrepPath as O, UPSTREAM_INACTIVITY_TIMEOUT_MS as On, scribeModel as Ot, ADVISOR_TOOL_INSTRUCTIONS as P, upstreamMaxConnections as Pn, LUNA_IMPLEMENTER_ALIAS_ID as Pt, UNKNOWN_EFFORT_ANCHOR as Q, unregisterLaunch as Qt, isAdvisorRequested as R, withOneMSuffix as Rn, canonicalizeAliasModel as Rt, runWorkerAgent as S, BUDGET_SMALL_FAST_SLUG as Sn, implementerFastModel as St, buildToolbeltAwareness as T, DEFAULT_CODEX_MODEL_FALLBACKS as Tn, reviewerFastModel as Tt, repairKnownThinkingHistory as U, validateFastProfilePrerequisites as Ut, formatThinkingRepairDecline as V, withInstallLock as Vn, resolveLaunchProfile as Vt, repairRejectedThinkingHistory as W, shimDefaultsToXhigh as Wt, relayAnthropicStream as X, findLaunchBySecret as Xt, readIteratorWithTimeout as Y, getTokenizerFromModel as Yt, EFFORT_ORDER as Z, registerLaunch as Zt, TEST_DEFAULT_MODEL as _, DEFINITION_OF_GREATNESS as _n, fastReviewerModel as _t, buildAgentPrompt as a, readResponseBodyCapped as an, FAST_REVIEWER_EFFORT as at, resolveModeDefaults as b, toolbeltPathOverride as bn, geminiAvailable as bt, enumerateInjectedMcpToolNames as c, provisionBrowserAssets as cn, artifactToolsEnabled as ct, DEFAULT_MODEL_CHAIN as d, provisionAndIndexColbert as dn, browserCompoundToolsEnabled as dt, warnOnTokenPriceDrift as en, clampEffort as et, EXPLORE_DEFAULT_MODEL as f, extractTarGzMember as fn, browserToolsEnabled as ft, REVIEW_DEFAULT_MODEL as g, CONDENSED_OPERATING_SEQUENCE as gn, fastPlannerModel as gt, PLAN_DEFAULT_MODEL as h, provisionTreeSitterAssets as hn, fastOracleModel as ht, assertMcpToolSurfaceConsistent as i, MAX_RESPONSE_BODY_BYTES as in, FAST_PLANNER_EFFORT as it, satisfiesMinVersion as j, pickClaudeDefault as jn, FAST_CRITIC_ALIAS_ID as jt, TOOLBELT_TOOLS$1 as k, generateRandomPort as kn, standInToolEnabled as kt, personasFor as l, hasSupportedBrowserInstalled as ln, brainstormModel as lt, IMPLEMENT_DEFAULT_MODEL as m, warmTreeSitterPool as mn, fastImplementerModel as mt, MCP_GROUPS as n, createResponses as nn, handleMcpPost as nt, buildPeerAwarenessSnippet as o, parseJsonOrDiagnose as on, FAST_SCOUT_EFFORT as ot, EXPLORE_DEFAULT_THINKING as p, extractZipMember as pn, fastCriticModel as pt, isControllerClosedError as q, getTextTokenCount as qt, agentNamesForToolAllowlist as r, createChatCompletions as rn, FAST_CRITIC_EFFORT as rt, buildPeerAwarenessSummary as s, normalizeOpenAIUsage as sn, agentToolsEnabled as st, GROUP_META as t, resolveMcpToolTimeoutMs as tn, handleMcpDelete as tt, BROWSE_DEFAULT_MODEL as u, colbertDegradedWarning as un, browseAgentEnabled as ut, appendPlanReminder as v, shouldUseInsecureTls as vn, fastScoutModel as vt, availableToolCommands as w, DEFAULT_CODEX_MODEL as wn, resolveGeminiReviewModel as wt, resolveWorkerRunOpts as x, BUDGET_SMALL_FAST_CATALOG_ID as xn, generalPurposeFastModel as xt, resolveDefaultModel as y, collapsePathKeys as yn, fleetToolsEnabled as yt, resolveAdvisorEffort as z, withOneMSuffixForLead as zn, formatFastPrerequisiteFailure as zt };
36895
37222
 
36896
- //# sourceMappingURL=peer-mcp-personas-CHbl6MwM.js.map
37223
+ //# sourceMappingURL=peer-mcp-personas-BwNtC8jt.js.map