github-router 0.3.310 → 0.3.312

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 (29) hide show
  1. package/dist/{attribution-settings-n3zk0BR5.js → attribution-settings-os6aa-ck.js} +133 -23
  2. package/dist/attribution-settings-os6aa-ck.js.map +1 -0
  3. package/dist/browser-ext/manifest.json +1 -1
  4. package/dist/{claude-B0XJn7SY.js → claude-CHObdsb5.js} +111 -42
  5. package/dist/claude-CHObdsb5.js.map +1 -0
  6. package/dist/{codex-B2AyAp1I.js → codex-CUQklRRv.js} +4 -4
  7. package/dist/{codex-B2AyAp1I.js.map → codex-CUQklRRv.js.map} +1 -1
  8. package/dist/engine-DyzGsCUb.js +2 -0
  9. package/dist/{gate-discovery-Vr1ZKmB9.js → gate-discovery-_flEdhYo.js} +2 -2
  10. package/dist/{gate-discovery-Vr1ZKmB9.js.map → gate-discovery-_flEdhYo.js.map} +1 -1
  11. package/dist/{internal-stop-hook-BXHOU8L9.js → internal-stop-hook-BJ3o61-L.js} +2 -2
  12. package/dist/{internal-stop-hook-BXHOU8L9.js.map → internal-stop-hook-BJ3o61-L.js.map} +1 -1
  13. package/dist/main.js +5 -5
  14. package/dist/{peer-mcp-personas-CBJbxpNT.js → peer-mcp-personas-DklYru_1.js} +238 -59
  15. package/dist/peer-mcp-personas-DklYru_1.js.map +1 -0
  16. package/dist/{provision-D_fn8Ry4.js → provision-BYdIsKcp.js} +2 -2
  17. package/dist/{provision-D_fn8Ry4.js.map → provision-BYdIsKcp.js.map} +1 -1
  18. package/dist/{serve-FPj_k6Af.js → serve-B70Kczq6.js} +5 -5
  19. package/dist/{serve-FPj_k6Af.js.map → serve-B70Kczq6.js.map} +1 -1
  20. package/dist/{server-setup-m5vGQ3k8.js → server-setup-DX27fdcf.js} +275 -29
  21. package/dist/server-setup-DX27fdcf.js.map +1 -0
  22. package/dist/{start-Bw--i3Rz.js → start-JbcSzClY.js} +3 -3
  23. package/dist/{start-Bw--i3Rz.js.map → start-JbcSzClY.js.map} +1 -1
  24. package/package.json +1 -1
  25. package/dist/attribution-settings-n3zk0BR5.js.map +0 -1
  26. package/dist/claude-B0XJn7SY.js.map +0 -1
  27. package/dist/engine-BLetfq6a.js +0 -2
  28. package/dist/peer-mcp-personas-CBJbxpNT.js.map +0 -1
  29. package/dist/server-setup-m5vGQ3k8.js.map +0 -1
@@ -99,6 +99,66 @@ async function tryCreateLock(p) {
99
99
  }
100
100
  }
101
101
  //#endregion
102
+ //#region src/lib/cheap-profile-contract.ts
103
+ const CHEAP_PROFILE_MODELS = Object.freeze({
104
+ lead: "gemini-3.8-flash",
105
+ explore: "gpt-5.6-luna",
106
+ plan: "gpt-5.6-sol",
107
+ "general-purpose": "gpt-5.6-luna",
108
+ implementer: "gemini-3.8-flash",
109
+ reviewer: "gpt-5.6-luna",
110
+ advisor: "gpt-5.6-sol",
111
+ oracle: "grok-4.6",
112
+ astra: "gpt-6-astra"
113
+ });
114
+ const CHEAP_PROFILE_NATIVE_AGENT_NAMES = [
115
+ "Explore",
116
+ "Plan",
117
+ "general-purpose",
118
+ "implementer",
119
+ "reviewer"
120
+ ];
121
+ const CHEAP_PROFILE_NATIVE_MODELS = Object.freeze({
122
+ Explore: CHEAP_PROFILE_MODELS.explore,
123
+ Plan: CHEAP_PROFILE_MODELS.plan,
124
+ "general-purpose": CHEAP_PROFILE_MODELS["general-purpose"],
125
+ implementer: CHEAP_PROFILE_MODELS.implementer,
126
+ reviewer: CHEAP_PROFILE_MODELS.reviewer
127
+ });
128
+ const CHEAP_PROFILE_NATIVE_EFFORTS = Object.freeze({
129
+ Explore: "high",
130
+ Plan: "high",
131
+ "general-purpose": "max",
132
+ implementer: "high",
133
+ reviewer: "max"
134
+ });
135
+ /**
136
+ * Subagent/peer context window (tokens). The cheap family deliberately runs
137
+ * every non-lead role (and, under `-m cheap`, the lead as well) at Claude
138
+ * Code's DEFAULT (bare-slug) budget — 200K — rather than decorating roles
139
+ * with the `[1m]` accounting suffix, which is exactly what makes the cheap
140
+ * surface cheaper than fast's per-role 1M windows.
141
+ */
142
+ const CHEAP_PROFILE_SUBAGENT_CONTEXT_TOKENS = 2e5;
143
+ const CHEAP_PROFILE_ADVISOR_MODEL = CHEAP_PROFILE_MODELS.advisor;
144
+ /**
145
+ * Client-visible Advisor identity for cheap mode. The BARE slug (no `[1m]`
146
+ * bracket): Claude Code budgets the Advisor tool as a 200K-model and forwards
147
+ * no more than ~200K of the lead's transcript, and the proxy mirrors that with
148
+ * `CHEAP_PROFILE_ADVISOR_CONTEXT_TOKENS`. The upstream Copilot request is the
149
+ * bare id either way (`resolveModel` strips the bracket), so this only changes
150
+ * the context the advisor is allowed to see — the cost lever.
151
+ */
152
+ const CHEAP_PROFILE_ADVISOR_CLIENT_MODEL = CHEAP_PROFILE_MODELS.advisor;
153
+ /** Advisor context window for cheap mode (tokens). */
154
+ const CHEAP_PROFILE_ADVISOR_CONTEXT_TOKENS = CHEAP_PROFILE_SUBAGENT_CONTEXT_TOKENS;
155
+ const CHEAP_PROFILE_ORACLE_MODEL = CHEAP_PROFILE_MODELS.oracle;
156
+ const CHEAP_PROFILE_ORACLE_EFFORT = "medium";
157
+ /** Astra identity for the `-m cheap1m` successor only (`-m cheap` has no
158
+ * astra peer). Runs at the 200K default window and medium effort. */
159
+ const CHEAP_PROFILE_ASTRA_MODEL = CHEAP_PROFILE_MODELS.astra;
160
+ const CHEAP_PROFILE_ASTRA_EFFORT = "medium";
161
+ //#endregion
102
162
  //#region src/lib/one-m-context.ts
103
163
  /**
104
164
  * Context-window threshold at which Claude Code's `[1m]` accounting unlock is
@@ -460,6 +520,13 @@ const DEFAULT_OPUS_FAMILY = "5";
460
520
  * Gemini-driven profile (see `./launch-profile`).
461
521
  */
462
522
  const FAST_LEAD_MODEL = FAST_PROFILE_MODELS.lead;
523
+ /**
524
+ * The lead `-m cheap` selects. Same Gemini leader as `fast`, but run at the
525
+ * 200K DEFAULT window (BARE slug, no `[1m]`) — see the cheap-family split in
526
+ * `./launch-profile` and `.resolveLeadSlugArg` below. `-m cheap1m` is the
527
+ * successor that keeps the leader at its full 1M window.
528
+ */
529
+ const CHEAP_LEAD_MODEL = CHEAP_PROFILE_MODELS.lead;
463
530
  /** Small/fast tier for a budget lead, in the two forms this codebase needs.
464
531
  *
465
532
  * `SLUG` is the Anthropic-published DASHED form and is what goes into
@@ -474,18 +541,22 @@ const BUDGET_SMALL_FAST_CATALOG_ID = "claude-haiku-4.5";
474
541
  /**
475
542
  * Resolve the `-m` argument to the lead slug to launch with.
476
543
  *
477
- * - `fast` → `FAST_LEAD_MODEL` (the fast Luna profile — see
544
+ * - `fast` → `FAST_LEAD_MODEL` (the fast Gemini profile — see
478
545
  * `./launch-profile`, NOT the retired Sonnet budget lead)
546
+ * - `cheap1m` → `CHEAP_LEAD_MODEL` decorated `[1m]` (the named successor
547
+ * of the original cheap launch: Gemini leader at 1M)
548
+ * - `cheap` → `CHEAP_LEAD_MODEL` BARE (the cost-lean launch: Gemini
549
+ * leader at the 200K DEFAULT window, no astra peer)
479
550
  * - `N.M` → the best variant of that Opus family, via `pickClaudeDefault`
480
551
  * - a full slug → unchanged, including Copilot slugs a power user pins
481
552
  * - absent → the ordinary default
482
553
  *
483
- * Every branch is `[1m]`-decorated against the live catalog, by
484
- * `pickClaudeDefault` on the two Opus-family branches and by
485
- * `withOneMSuffixForLead` on the other two. `gpt-5.6-luna` advertises a 1M
486
- * window, so `-m fast` gets local 1M accounting exactly like every other
487
- * branch here; the decoration is catalog-gated per model, so a genuinely
488
- * 200K model (`claude-haiku-4.5`) still comes back bare.
554
+ * Every branch except `cheap` is `[1m]`-decorated against the live catalog,
555
+ * by `pickClaudeDefault` on the two Opus-family branches and by
556
+ * `withOneMSuffixForLead` on the rest the decoration is catalog-gated per
557
+ * model, so a genuinely 200K model (`claude-haiku-4.5`) still comes back
558
+ * bare. `cheap` deliberately skips the decoration entirely because its whole
559
+ * cost lever is the 200K default lead window.
489
560
  *
490
561
  * `fast` resolves to an ordinary slug rather than setting a mode flag —
491
562
  * `resolveLaunchProfile` (`./launch-profile`) is keyed off the SAME raw
@@ -507,6 +578,8 @@ function resolveLeadSlugArg(modelArg) {
507
578
  if (!arg) return pickClaudeDefault();
508
579
  if (arg.toLowerCase() === "fast") return withOneMSuffixForLead(FAST_LEAD_MODEL);
509
580
  if (arg.toLowerCase() === "max") return withOneMSuffixForLead(MAX_PROFILE_LEAD_MODEL);
581
+ if (arg.toLowerCase() === "cheap1m") return withOneMSuffixForLead(CHEAP_LEAD_MODEL);
582
+ if (arg.toLowerCase() === "cheap") return CHEAP_LEAD_MODEL;
510
583
  const opusFamilyShorthand = arg.match(/^(\d+\.\d+)$/)?.[1];
511
584
  if (opusFamilyShorthand) return pickClaudeDefault(opusFamilyShorthand);
512
585
  return withOneMSuffixForLead(arg);
@@ -27851,6 +27924,57 @@ function fastAstraModel() {
27851
27924
  if (fastEndpointForModel(found) !== "responses") return void 0;
27852
27925
  return FAST_PROFILE_ASTRA_MODEL;
27853
27926
  }
27927
+ /** Sol/high Advisor for the cheap family at the 200K default window. Unlike the
27928
+ * fast Advisor (which budgets a 1M transcript), cheap caps the transcript at
27929
+ * `CHEAP_PROFILE_ADVISOR_CONTEXT_TOKENS`, so the 200K subagent floor — the
27930
+ * same gate launch validation enforces — is the correct prerequisite here. */
27931
+ function cheapAdvisorModel() {
27932
+ const found = state.models?.data.find((m) => m.id === CHEAP_PROFILE_ADVISOR_MODEL);
27933
+ if (!found) return void 0;
27934
+ if ((found.capabilities?.limits?.max_context_window_tokens ?? 0) < 2e5) return void 0;
27935
+ if (found.capabilities?.supports?.tool_calls !== true) return void 0;
27936
+ const efforts = found.capabilities?.supports?.reasoning_effort;
27937
+ if (!Array.isArray(efforts) || !efforts.includes("high")) return void 0;
27938
+ if (fastEndpointForModel(found) !== "responses") return void 0;
27939
+ return CHEAP_PROFILE_ADVISOR_MODEL;
27940
+ }
27941
+ /** Exact Grok 4.6 only: the cheap Oracle runs the cheaper avenger at 200K/medium,
27942
+ * mirrored from fast's Opus 5 1M/high. Dispatch goes to the RESPONSES endpoint
27943
+ * (grok-4.6 serves no messages endpoint). */
27944
+ function cheapOracleModel() {
27945
+ const found = state.models?.data.find((m) => m.id === CHEAP_PROFILE_ORACLE_MODEL);
27946
+ if (!found) return void 0;
27947
+ if ((found.capabilities?.limits?.max_context_window_tokens ?? 0) < 2e5) return void 0;
27948
+ if ((found.capabilities?.limits?.max_prompt_tokens ?? 0) <= 0) return void 0;
27949
+ const efforts = found.capabilities?.supports?.reasoning_effort;
27950
+ if (!Array.isArray(efforts) || !efforts.includes("medium")) return void 0;
27951
+ if (fastEndpointForModel(found) !== "responses") return void 0;
27952
+ return CHEAP_PROFILE_ORACLE_MODEL;
27953
+ }
27954
+ /** Luna/max reviewer for the cheap family at the 200K default window. */
27955
+ function cheapReviewerModel() {
27956
+ const found = state.models?.data.find((m) => m.id === CHEAP_PROFILE_MODELS.reviewer);
27957
+ if (!found) return void 0;
27958
+ if (found.capabilities?.supports?.tool_calls !== true) return void 0;
27959
+ if ((found.capabilities?.limits?.max_context_window_tokens ?? 0) < 2e5) return void 0;
27960
+ const efforts = found.capabilities?.supports?.reasoning_effort;
27961
+ if (!Array.isArray(efforts) || !efforts.includes(CHEAP_PROFILE_NATIVE_EFFORTS.reviewer)) return void 0;
27962
+ if (fastEndpointForModel(found) !== "responses") return void 0;
27963
+ return CHEAP_PROFILE_MODELS.reviewer;
27964
+ }
27965
+ /** Exact GPT-6 Astra only: cheap escalation consultant at 200K/medium. */
27966
+ function cheapAstraModel() {
27967
+ const found = state.models?.data.find((m) => m.id === CHEAP_PROFILE_ASTRA_MODEL);
27968
+ if (!found) return void 0;
27969
+ if ((found.capabilities?.limits?.max_context_window_tokens ?? 0) < 2e5) return void 0;
27970
+ if ((found.capabilities?.limits?.max_prompt_tokens ?? 0) < 2e5) return void 0;
27971
+ const tokenizer = found.capabilities?.tokenizer;
27972
+ if (tokenizer && tokenizer !== "o200k_base") return void 0;
27973
+ const efforts = found.capabilities?.supports?.reasoning_effort;
27974
+ if (!Array.isArray(efforts) || !efforts.includes("medium")) return void 0;
27975
+ if (fastEndpointForModel(found) !== "responses") return void 0;
27976
+ return CHEAP_PROFILE_ASTRA_MODEL;
27977
+ }
27854
27978
  /**
27855
27979
  * Gate for the worker tools (`explore`, `review`, `implement`).
27856
27980
  *
@@ -28147,10 +28271,10 @@ function activePersonas(launch) {
28147
28271
  };
28148
28272
  });
28149
28273
  }
28150
- function oracleToolEntry() {
28274
+ function oracleToolEntry(isCheap = false, astraAvailable = true) {
28151
28275
  return {
28152
28276
  name: "oracle",
28153
- description: "Fast-profile expert consultant (Opus 5 1M context at high effort) available to the lead and Plan. Stateless and cold-start: it sees only what you paste, with no repo access, tools, or prior history.\n\nWhen to invoke: preferred for difficult conceptual, algorithmic, spec/protocol, or architectural tradeoffs when repository evidence alone cannot settle them, or when multiple viable designs conflict. Preferred over advisor for substantive technical decisions that can be evaluated in a self-contained brief.\n\nWhen NOT to invoke: not for routine code lookup, web search, execution, approval, or mechanical facts verifiable by tests.\n\nPass complete context, constraints, minimal code excerpts with path:line, and one precise unresolved question.",
28277
+ description: `Expert consultant backed by ${isCheap ? "Grok 4.6 (200K context, medium effort)" : "exact Opus 5 (1M context, high effort)"} for complex conceptual, algorithmic, spec/protocol, or architectural trade-offs. Stateless and cold-start: evaluates a self-contained brief.\n\nWhen to invoke: use for difficult conceptual, algorithmic, spec/protocol, or architectural tradeoffs before implementation when repository evidence alone cannot settle them. Preferred over advisor for self-contained technical briefs.\n\nWhen NOT to invoke: not for transcript-aware framing (consult Advisor), ${astraAvailable ? "terminal dead ends (consult Astra), " : "terminal dead ends (no escalation peer on this profile; report the dead end with evidence to the lead), "}routine code lookup, or mechanical facts verifiable by tests.\n\nPass complete context, constraints, minimal code excerpts with path:line, and one precise unresolved question.`,
28154
28278
  inputSchema: {
28155
28279
  type: "object",
28156
28280
  required: ["query", "context"],
@@ -28171,7 +28295,8 @@ function oracleToolEntry() {
28171
28295
  function escapeXml(unsafe) {
28172
28296
  return unsafe.replace(/&/g, "&amp;").replace(/</g, "&lt;").replace(/>/g, "&gt;").replace(/"/g, "&quot;").replace(/'/g, "&apos;");
28173
28297
  }
28174
- const ASTRA_INSTRUCTIONS = `You are Astra, a stateless technical decision consultant running on GPT-6 Astra at high reasoning effort.
28298
+ function astraInstructions(effortLabel) {
28299
+ return `You are Astra, a stateless technical decision consultant running on GPT-6 Astra at ${effortLabel} reasoning effort.
28175
28300
 
28176
28301
  # Objective
28177
28302
  Resolve one precise technical, algorithmic, protocol, or architectural decision that remains blocked after direct investigation, Advisor, and Oracle. Find a defensible path, identify the minimum evidence needed to find one, or conclude that no defensible path exists under the stated constraints.
@@ -28202,10 +28327,11 @@ A short ordered list executable by the caller. For NEED_EVIDENCE, list at most t
28202
28327
 
28203
28328
  ## Assumptions and falsifiers
28204
28329
  The assumptions used and the single fact most likely to change the recommendation.`;
28205
- function astraToolEntry() {
28330
+ }
28331
+ function astraToolEntry(isCheap = false) {
28206
28332
  return {
28207
28333
  name: "astra",
28208
- description: "Expensive, lead-only final escalation to GPT-6 Astra (200K policy window at fixed high reasoning effort). Astra is stateless and sees only the supplied packet. It has no repository access, session transcript, tools, execution authority, or approval authority.\n\nWhen to invoke: use ONLY as the terminal escalation when direct empirical investigation (code, tests, builds), Advisor (framing/trajectory), and Oracle (spec/architectural trade-offs) have ALL failed to produce a defensible path forward.\n\nWhen NOT to invoke: do not use for routine lookup, mechanical facts, code generation, approval, extra confidence after a sufficient answer, or retrying with unchanged evidence.\n\nPass one specific decision in `query` and a concise but complete self-contained evidence packet in `context`. Expected consultation: at most 1-2 calls per decision.\n\nReturns concise, specific structured Markdown with Status (PATH_FOUND | NEED_EVIDENCE | NO_DEFENSIBLE_PATH), Recommendation, Decision basis, Next checks or actions, and Assumptions and falsifiers.",
28334
+ description: `Terminal decision consultant backed by GPT-6 Astra (${isCheap ? "200K policy window, medium effort" : "200K policy window, high effort"}). Stateless and cold-start: evaluates a self-contained brief with no repository access, session transcript, tools, execution authority, or approval authority.\n\nWhen to invoke: use strictly as a last resort when direct empirical investigation (code, tests, builds), Advisor (framing/trajectory), and Oracle (spec/architectural trade-offs) have ALL failed to produce a defensible path forward.\n\nWhen NOT to invoke: not for initial trade-offs (consult Oracle), routine framing (consult Advisor), mechanical facts, code generation, approval, or retrying with unchanged evidence.\n\nPass one specific decision in \`query\` and a concise but complete self-contained evidence packet in \`context\`. Expected consultation: at most 1-2 calls per decision.\n\nReturns concise, specific structured Markdown with Status (PATH_FOUND | NEED_EVIDENCE | NO_DEFENSIBLE_PATH), Recommendation, Decision basis, Next checks or actions, and Assumptions and falsifiers.`,
28209
28335
  inputSchema: {
28210
28336
  type: "object",
28211
28337
  required: ["query", "context"],
@@ -28264,7 +28390,7 @@ function fastToolIsEnabled(tool) {
28264
28390
  }
28265
28391
  /** Shared Fast projection for list and call, including non-persona dispatch kind. */
28266
28392
  function fastAllowsTool(scope, launch, item) {
28267
- if (launch.profileId !== "fast") return true;
28393
+ if (launch.profileId !== "fast" && launch.profileId !== "cheap" && launch.profileId !== "cheap1m") return true;
28268
28394
  if (scope !== "all" && item.group !== scope) return false;
28269
28395
  if (!launch.allowedGroups?.has(item.group)) return false;
28270
28396
  if (item.persona) return false;
@@ -28316,10 +28442,13 @@ function toolEntries(scope, launch, audience = "shared") {
28316
28442
  }));
28317
28443
  return [...personaEntries, ...nonPersonaEntries];
28318
28444
  }
28319
- if (launch.profileId === "fast") {
28445
+ if (launch.profileId === "fast" || launch.profileId === "cheap" || launch.profileId === "cheap1m") {
28446
+ const isCheap = launch.profileId === "cheap" || launch.profileId === "cheap1m";
28447
+ const astraWired = launch.profileId === "fast" || launch.profileId === "cheap1m";
28448
+ const astraAvailable = astraWired && (isCheap ? cheapAstraModel() : fastAstraModel()) != null;
28320
28449
  const entries = [];
28321
- if ((scope === "all" || scope === "peers") && launch.allowedGroups?.has("peers") && launch.allowedPersonas?.has("oracle") && fastOracleModel()) entries.push(oracleToolEntry());
28322
- if ((scope === "all" || scope === "peers") && launch.allowedGroups?.has("peers") && launch.allowedPersonas?.has("astra") && audience === "lead-peers" && fastAstraModel()) entries.push(astraToolEntry());
28450
+ if ((scope === "all" || scope === "peers") && launch.allowedGroups?.has("peers") && launch.allowedPersonas?.has("oracle") && (isCheap ? cheapOracleModel() : fastOracleModel())) entries.push(oracleToolEntry(isCheap, astraAvailable));
28451
+ if ((scope === "all" || scope === "peers") && launch.allowedGroups?.has("peers") && launch.allowedPersonas?.has("astra") && audience === "lead-peers" && astraWired && (isCheap ? cheapAstraModel() : fastAstraModel())) entries.push(astraToolEntry(isCheap));
28323
28452
  for (const tool of NON_PERSONA_MCP_TOOLS) {
28324
28453
  if (!fastAllowsTool(scope, launch, {
28325
28454
  group: tool.group,
@@ -28759,7 +28888,7 @@ async function handleToolsCall(body, scope, launch, audience = "shared", session
28759
28888
  tool: maxTool
28760
28889
  }) : false)) return rpcError(body.id, RPC_METHOD_NOT_FOUND, `tools/call: unknown tool "${name}"`);
28761
28890
  }
28762
- if (launch.profileId === "fast" && name !== "oracle" && name !== "astra") {
28891
+ if ((launch.profileId === "fast" || launch.profileId === "cheap" || launch.profileId === "cheap1m") && name !== "oracle" && name !== "astra") {
28763
28892
  const fastPersona = activePersonas(launch).find((persona) => persona.toolNameHttp === name);
28764
28893
  const fastTool = NON_PERSONA_MCP_TOOLS.find((tool) => tool.toolNameHttp === name);
28765
28894
  if (!(fastPersona ? fastAllowsTool(scope, launch, {
@@ -28772,23 +28901,26 @@ async function handleToolsCall(body, scope, launch, audience = "shared", session
28772
28901
  tool: fastTool
28773
28902
  }) : false)) return rpcError(body.id, RPC_METHOD_NOT_FOUND, `tools/call: unknown tool "${name}"`);
28774
28903
  }
28775
- if (launch.profileId === "fast" && name === "astra") {
28776
- if (scope !== "all" && scope !== "peers" || !launch.allowedGroups?.has("peers") || !launch.allowedPersonas?.has("astra") || audience !== "lead-peers" || !fastAstraModel()) return rpcError(body.id, RPC_METHOD_NOT_FOUND, `tools/call: unknown tool "${name}"`);
28904
+ if ((launch.profileId === "fast" || launch.profileId === "cheap1m") && name === "astra") {
28905
+ const isCheapAstra = launch.profileId === "cheap1m";
28906
+ const astraModel = isCheapAstra ? CHEAP_PROFILE_ASTRA_MODEL : "gpt-6-astra";
28907
+ const astraEffort = isCheapAstra ? CHEAP_PROFILE_ASTRA_EFFORT : "high";
28908
+ if (scope !== "all" && scope !== "peers" || !launch.allowedGroups?.has("peers") || !launch.allowedPersonas?.has("astra") || audience !== "lead-peers" || !(isCheapAstra ? cheapAstraModel() : fastAstraModel())) return rpcError(body.id, RPC_METHOD_NOT_FOUND, `tools/call: unknown tool "${name}"`);
28777
28909
  const query = typeof args.query === "string" ? args.query.trim() : "";
28778
28910
  const context = typeof args.context === "string" ? args.context.trim() : "";
28779
28911
  if (!query || !context) return rpcError(body.id, RPC_INVALID_PARAMS, "tools/call: astra requires non-empty arguments.query and arguments.context");
28780
28912
  const astraPersona = {
28781
28913
  agentName: "astra",
28782
28914
  toolNameHttp: "astra",
28783
- model: "gpt-6-astra",
28915
+ model: astraModel,
28784
28916
  endpoint: "/v1/responses",
28785
- description: "Fast-profile Astra",
28786
- baseInstructions: ASTRA_INSTRUCTIONS,
28917
+ description: "Fast/cheap-profile Astra",
28918
+ baseInstructions: astraInstructions(isCheapAstra ? "medium" : "high"),
28787
28919
  agentPrompt: "",
28788
28920
  writeCapable: false,
28789
28921
  requiresHttp: true,
28790
- allowedEfforts: ["high"],
28791
- defaultEffort: "high"
28922
+ allowedEfforts: [astraEffort],
28923
+ defaultEffort: astraEffort
28792
28924
  };
28793
28925
  const astraXmlInput = `<astra_request>\n <query>${escapeXml(query)}</query>\n <context>${escapeXml(context)}</context>\n</astra_request>`;
28794
28926
  const overflow = await predictedWindowOverflow(astraPersona, astraXmlInput, void 0, {
@@ -28809,16 +28941,16 @@ async function handleToolsCall(body, scope, launch, audience = "shared", session
28809
28941
  if (abortKey !== void 0) inflightAborts.set(abortKey, inflightEntry);
28810
28942
  try {
28811
28943
  const text = await dispatchModelCall({
28812
- model: "gpt-6-astra",
28944
+ model: astraModel,
28813
28945
  endpoint: "/v1/responses",
28814
28946
  instructions: astraPersona.baseInstructions,
28815
28947
  userText: astraXmlInput,
28816
- effort: "high",
28948
+ effort: astraEffort,
28817
28949
  signal: aborter.signal
28818
28950
  });
28819
28951
  logTelemetry({
28820
28952
  name: "astra",
28821
- model: "gpt-6-astra",
28953
+ model: astraModel,
28822
28954
  durationMs: Date.now() - startedAt,
28823
28955
  result: "ok"
28824
28956
  });
@@ -28830,7 +28962,7 @@ async function handleToolsCall(body, scope, launch, audience = "shared", session
28830
28962
  const message = err instanceof Error ? err.message : String(err);
28831
28963
  logTelemetry({
28832
28964
  name: "astra",
28833
- model: "gpt-6-astra",
28965
+ model: astraModel,
28834
28966
  durationMs: Date.now() - startedAt,
28835
28967
  result: "exception",
28836
28968
  errorMessage: message
@@ -28841,8 +28973,12 @@ async function handleToolsCall(body, scope, launch, audience = "shared", session
28841
28973
  release();
28842
28974
  }
28843
28975
  }
28844
- if (launch.profileId === "fast" && name === "oracle") {
28845
- if (scope !== "all" && scope !== "peers" || !launch.allowedGroups?.has("peers") || !launch.allowedPersonas?.has("oracle") || !fastOracleModel()) return rpcError(body.id, RPC_METHOD_NOT_FOUND, `tools/call: unknown tool "${name}"`);
28976
+ if ((launch.profileId === "fast" || launch.profileId === "cheap" || launch.profileId === "cheap1m") && name === "oracle") {
28977
+ const isCheapOracle = launch.profileId === "cheap" || launch.profileId === "cheap1m";
28978
+ const oracleModel = isCheapOracle ? CHEAP_PROFILE_ORACLE_MODEL : "claude-opus-5";
28979
+ const oracleEndpoint = isCheapOracle ? "/v1/responses" : "/v1/messages";
28980
+ const oracleEffort = isCheapOracle ? CHEAP_PROFILE_ORACLE_EFFORT : "high";
28981
+ if (scope !== "all" && scope !== "peers" || !launch.allowedGroups?.has("peers") || !launch.allowedPersonas?.has("oracle") || !(isCheapOracle ? cheapOracleModel() : fastOracleModel())) return rpcError(body.id, RPC_METHOD_NOT_FOUND, `tools/call: unknown tool "${name}"`);
28846
28982
  const query = typeof args.query === "string" ? args.query.trim() : "";
28847
28983
  const context = typeof args.context === "string" ? args.context.trim() : "";
28848
28984
  if (!query || !context) return rpcError(body.id, RPC_INVALID_PARAMS, "tools/call: oracle requires non-empty arguments.query and arguments.context");
@@ -28853,15 +28989,15 @@ async function handleToolsCall(body, scope, launch, audience = "shared", session
28853
28989
  const oraclePersona = {
28854
28990
  agentName: "oracle",
28855
28991
  toolNameHttp: "oracle",
28856
- model: "claude-opus-5",
28857
- endpoint: "/v1/messages",
28858
- description: "Fast-profile Oracle",
28859
- baseInstructions: "You are Oracle, an expert architectural and technical consultant running on Opus 5. You have no tools or repository access. Answer from the supplied context and state assumptions explicitly, noting which facts would change the recommendation. Never claim to execute, verify, approve, merge, or authorize an action.",
28992
+ model: oracleModel,
28993
+ endpoint: oracleEndpoint,
28994
+ description: "Fast/cheap-profile Oracle",
28995
+ baseInstructions: isCheapOracle ? "You are Oracle, an expert architectural and technical consultant running on Grok 4.6. You have no tools or repository access. Answer from the supplied context and state assumptions explicitly, noting which facts would change the recommendation. Never claim to execute, verify, approve, merge, or authorize an action." : "You are Oracle, an expert architectural and technical consultant running on Opus 5. You have no tools or repository access. Answer from the supplied context and state assumptions explicitly, noting which facts would change the recommendation. Never claim to execute, verify, approve, merge, or authorize an action.",
28860
28996
  agentPrompt: "",
28861
28997
  writeCapable: false,
28862
28998
  requiresHttp: true,
28863
- allowedEfforts: ["high"],
28864
- defaultEffort: "high"
28999
+ allowedEfforts: [oracleEffort],
29000
+ defaultEffort: oracleEffort
28865
29001
  };
28866
29002
  const overflow = await predictedWindowOverflow(oraclePersona, oracleInput, void 0);
28867
29003
  if (overflow) return rpcResult(body.id, toolError(overflow));
@@ -28877,16 +29013,16 @@ async function handleToolsCall(body, scope, launch, audience = "shared", session
28877
29013
  if (abortKey !== void 0) inflightAborts.set(abortKey, inflightEntry);
28878
29014
  try {
28879
29015
  const text = await dispatchModelCall({
28880
- model: "claude-opus-5",
28881
- endpoint: "/v1/messages",
29016
+ model: oracleModel,
29017
+ endpoint: oracleEndpoint,
28882
29018
  instructions: oraclePersona.baseInstructions,
28883
29019
  userText: oracleInput,
28884
- effort: "high",
29020
+ effort: oracleEffort,
28885
29021
  signal: aborter.signal
28886
29022
  });
28887
29023
  logTelemetry({
28888
29024
  name: "oracle",
28889
- model: "claude-opus-5",
29025
+ model: oracleModel,
28890
29026
  durationMs: Date.now() - startedAt,
28891
29027
  result: "ok"
28892
29028
  });
@@ -28898,7 +29034,7 @@ async function handleToolsCall(body, scope, launch, audience = "shared", session
28898
29034
  const message = err instanceof Error ? err.message : String(err);
28899
29035
  logTelemetry({
28900
29036
  name: "oracle",
28901
- model: "claude-opus-5",
29037
+ model: oracleModel,
28902
29038
  durationMs: Date.now() - startedAt,
28903
29039
  result: "exception",
28904
29040
  errorMessage: message
@@ -28909,7 +29045,7 @@ async function handleToolsCall(body, scope, launch, audience = "shared", session
28909
29045
  release();
28910
29046
  }
28911
29047
  }
28912
- if (launch.profileId === "fast" && PERSONAS_READ.some((p) => p.toolNameHttp === name)) return rpcError(body.id, RPC_METHOD_NOT_FOUND, `tools/call: unknown tool "${name}"`);
29048
+ if ((launch.profileId === "fast" || launch.profileId === "cheap" || launch.profileId === "cheap1m") && PERSONAS_READ.some((p) => p.toolNameHttp === name)) return rpcError(body.id, RPC_METHOD_NOT_FOUND, `tools/call: unknown tool "${name}"`);
28913
29049
  const persona = activePersonas(launch).find((p) => p.toolNameHttp === name);
28914
29050
  const nonPersonaTool = persona ? void 0 : NON_PERSONA_MCP_TOOLS.find((t) => t.toolNameHttp === name);
28915
29051
  if (!persona && !nonPersonaTool) return rpcError(body.id, RPC_METHOD_NOT_FOUND, `tools/call: unknown tool "${name}"`);
@@ -30176,6 +30312,7 @@ When to consult advisor:
30176
30312
  - Framing or assumption drift: when you suspect session momentum may have drifted from the user's core intent.
30177
30313
  - Trajectory guidance: when evaluating overall approach direction or when an approach is not converging.
30178
30314
  - Conflicting signals: when tool outputs or user feedback conflict and transcript context is required to evaluate why.
30315
+ - Perspective recovery: when a speed-oriented session may be missing relevant broader context, earlier constraints, unstated assumptions, or system-level consequences.
30179
30316
 
30180
30317
  Discriminator vs. Oracle:
30181
30318
  - If the question requires knowing what happened in this session -> consult Advisor.
@@ -30304,13 +30441,19 @@ function resolveAdvisorMaxTokens(advisorModel) {
30304
30441
  * omitted ...]` notice so the advisor knows the transcript is
30305
30442
  * partial and can flag if it needs the missing context.
30306
30443
  *
30444
+ * When `pinOriginalAsk` is enabled (fast and cheap profile leaders),
30445
+ * the FIRST user turn's text is reserved out of the budget and kept
30446
+ * verbatim, so the advisor always sees the original ask even after
30447
+ * aggressive seat-backward truncation — the "keep the ask + seat the
30448
+ * most-recent turns backward, no plan-detection" pruning rule.
30449
+ *
30307
30450
  * Unit-agnostic via the injected `measure` function: production passes
30308
30451
  * an EXACT o200k token counter and a token budget (so truncation tracks
30309
30452
  * the model's real `max_prompt_tokens`); the default `measure` is char
30310
30453
  * length, so callers/tests that pass a plain numeric budget get the
30311
30454
  * historical character-budget behavior.
30312
30455
  */
30313
- function renderConversationAsText(conversation, maxUnits = ADVISOR_MAX_CONVERSATION_CHARS, measure = (s) => s.length) {
30456
+ function renderConversationAsText(conversation, maxUnits = ADVISOR_MAX_CONVERSATION_CHARS, measure = (s) => s.length, pinOriginalAsk = false) {
30314
30457
  const turnBlocks = [];
30315
30458
  for (let i = 0; i < conversation.length; i++) {
30316
30459
  const msg = conversation[i];
@@ -30331,6 +30474,28 @@ function renderConversationAsText(conversation, maxUnits = ADVISOR_MAX_CONVERSAT
30331
30474
  block.push("");
30332
30475
  turnBlocks.push(block.join("\n"));
30333
30476
  }
30477
+ const PINNED_ASK_HEADER = "[Original ask (kept for the advisor):]\n\n";
30478
+ let pinnedAsk;
30479
+ if (pinOriginalAsk) for (const msg of conversation) {
30480
+ if (msg.role !== "user") continue;
30481
+ const content = msg.content;
30482
+ if (typeof content === "string") {
30483
+ pinnedAsk = content;
30484
+ break;
30485
+ }
30486
+ if (Array.isArray(content)) {
30487
+ for (const part of content) if (typeof part === "object" && part !== null && part.type === "text" && typeof part.text === "string") {
30488
+ pinnedAsk = part.text;
30489
+ break;
30490
+ }
30491
+ if (pinnedAsk) break;
30492
+ }
30493
+ }
30494
+ let pinnedAskBlock;
30495
+ if (pinnedAsk) {
30496
+ pinnedAskBlock = `${PINNED_ASK_HEADER}${pinnedAsk}\n\n`;
30497
+ maxUnits = Math.max(0, maxUnits - measure(pinnedAskBlock));
30498
+ }
30334
30499
  let totalUnits = 0;
30335
30500
  let firstKeptIdx = turnBlocks.length;
30336
30501
  for (let i = turnBlocks.length - 1; i >= 0; i--) {
@@ -30342,10 +30507,14 @@ function renderConversationAsText(conversation, maxUnits = ADVISOR_MAX_CONVERSAT
30342
30507
  if (firstKeptIdx === turnBlocks.length && turnBlocks.length > 0) {
30343
30508
  const last = turnBlocks[turnBlocks.length - 1];
30344
30509
  const notice = `[TRUNCATED: conversation too long for advisor model context; only the tail of the latest (turn ${turnBlocks.length}) is shown]\n\n`;
30345
- return notice + truncateTailToUnits(last, Math.max(0, maxUnits - measure(notice)), measure);
30510
+ const budgetForTail = Math.max(0, maxUnits - measure(notice));
30511
+ return (pinnedAskBlock ?? "") + notice + truncateTailToUnits(last, budgetForTail, measure);
30346
30512
  }
30347
30513
  const kept = turnBlocks.slice(firstKeptIdx);
30348
- if (firstKeptIdx > 0) kept.unshift(`[TRUNCATED: ${firstKeptIdx} earlier turn(s) omitted to fit advisor model context budget; ${turnBlocks.length - firstKeptIdx} most-recent turn(s) shown below]\n`);
30514
+ if (firstKeptIdx > 0) {
30515
+ kept.unshift(`[TRUNCATED: ${firstKeptIdx} earlier turn(s) omitted to fit advisor model context budget; ${turnBlocks.length - firstKeptIdx} most-recent turn(s) shown below]\n`);
30516
+ if (pinnedAskBlock) kept.unshift(pinnedAskBlock);
30517
+ }
30349
30518
  return kept.join("\n");
30350
30519
  }
30351
30520
  /**
@@ -30385,9 +30554,9 @@ function truncateTailToUnits(text, maxUnits, measure) {
30385
30554
  */
30386
30555
  function advisorSystemPrompt(advisorEscalated = false, fastProfile = false, maxProfile = false) {
30387
30556
  if (maxProfile) return MAX_ADVISOR_SYSTEM_PROMPT;
30388
- return "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. Address the focused uncertainty that prompted this call with a recommendation, its assumptions, material risks, credible alternatives, confidence, and any evidence gap that would change the recommendation. Do not approve, veto, dictate, or take ownership; the lead will weigh your advice against the user's intent and verified evidence." : "") + (advisorEscalated && !fastProfile && !maxProfile ? " 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." : "");
30557
+ return "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. Infer the most consequential unresolved uncertainty motivating this call from the transcript and state that interpretation briefly before advising. The primary lead is operating in a speed-oriented profile. Act as both advisor and guide: identify broader context, relevant world knowledge, forgotten earlier constraints, unstated assumptions, and system-level consequences the lead may have missed as the session evolved, keeping this guidance strictly relevant to the identified uncertainty. Distinguish verified repository facts from external world knowledge, and suggest concrete validation steps where external knowledge is consequential. Address the uncertainty with a concrete recommendation, its assumptions, material risks, credible alternatives, confidence, and any evidence gap that would change the recommendation. Do not approve, veto, dictate, or take ownership; the lead will weigh your advice against the user's intent and verified evidence." : "") + (advisorEscalated && !fastProfile && !maxProfile ? " 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." : "");
30389
30558
  }
30390
- async function runAdvisor(conversation, advisorModel, advisorEffort, signal, advisorEscalated = false, fastProfile = false, maxProfile = false) {
30559
+ async function runAdvisor(conversation, advisorModel, advisorEffort, signal, advisorEscalated = false, fastProfile = false, maxProfile = false, cheapProfile = false) {
30391
30560
  if (signal?.aborted) throw new Error("advisor call aborted before dispatch");
30392
30561
  const advisorSystem = advisorSystemPrompt(advisorEscalated, fastProfile, maxProfile);
30393
30562
  const resolvedAdvisorModel = resolveModel(advisorModel);
@@ -30397,15 +30566,16 @@ async function runAdvisor(conversation, advisorModel, advisorEffort, signal, adv
30397
30566
  const modelEntry = state.models?.data?.find((m) => m.id === resolvedAdvisorModel);
30398
30567
  const encoder = await loadEncoder(modelEntry ? getTokenizerFromModel(modelEntry) : "o200k_base");
30399
30568
  measure = (s) => encoder.encode(s).length;
30400
- maxUnits = resolveAdvisorMaxTokens(advisorModel);
30569
+ maxUnits = cheapProfile ? Math.min(resolveAdvisorMaxTokens(advisorModel), CHEAP_PROFILE_ADVISOR_CONTEXT_TOKENS) : resolveAdvisorMaxTokens(advisorModel);
30401
30570
  } catch (err) {
30402
30571
  consola.debug("advisor: tokenizer load failed; using char-length budget:", err);
30403
30572
  measure = (s) => s.length;
30404
30573
  maxUnits = ADVISOR_MAX_CONVERSATION_CHARS;
30405
30574
  }
30406
- const conversationText = renderConversationAsText(conversation, maxUnits, measure);
30575
+ const conversationText = renderConversationAsText(conversation, maxUnits, measure, fastProfile);
30407
30576
  const transport = advisorTransport(resolvedAdvisorModel, fastProfile);
30408
30577
  if (fastProfile) consola.warn(`fast Advisor dispatch: model=${resolvedAdvisorModel} transport=${transport} effort=${advisorEffort}`);
30578
+ if (cheapProfile) consola.warn(`cheap Advisor dispatch: model=${resolvedAdvisorModel} transport=${transport} effort=${advisorEffort} transcriptCap=200K`);
30409
30579
  if (transport === "responses") {
30410
30580
  const payload = applyResponsesCachePolicy({
30411
30581
  model: resolvedAdvisorModel,
@@ -30595,6 +30765,7 @@ function buildAdvisorStream(opts) {
30595
30765
  const advisorEscalated = opts.advisorEscalated ?? false;
30596
30766
  const advisorFastProfile = opts.advisorFastProfile ?? false;
30597
30767
  const advisorMaxProfile = opts.advisorMaxProfile ?? false;
30768
+ const advisorCheapProfile = opts.advisorCheapProfile ?? false;
30598
30769
  const continueTurn = opts.continueTurn ?? ((body, signal) => defaultContinueTurn(body, signal, opts.requestHeaders));
30599
30770
  const aborter = opts.externalAborter ?? new AbortController();
30600
30771
  let conversation = [...opts.initialConversation];
@@ -30845,7 +31016,7 @@ function buildAdvisorStream(opts) {
30845
31016
  const advisorConversation = conversation;
30846
31017
  const advisorTexts = await Promise.all(advisorToolUses.map(async () => {
30847
31018
  try {
30848
- return await runAdvisor(advisorConversation, advisorModel, advisorEffort, aborter.signal, advisorEscalated, advisorFastProfile, advisorMaxProfile);
31019
+ return await runAdvisor(advisorConversation, advisorModel, advisorEffort, aborter.signal, advisorEscalated, advisorFastProfile, advisorMaxProfile, advisorCheapProfile);
30849
31020
  } catch (err) {
30850
31021
  if (aborter.signal.aborted) throw err;
30851
31022
  const msg = err instanceof Error ? err.message : String(err);
@@ -35943,7 +36114,11 @@ function buildPeerAwarenessSnippet(opts) {
35943
36114
  `\`mcp__${searchKey}__code\` provides semantic-first code search and \`mcp__${searchKey}__web\` provides citable web sources. Advisor is transcript-aware, primary-lead-only, and unavailable to native subagents and browse workers; it can detect framing drift but is not independent verification.${browserClause}${workerClause}${decideClause}${fleetClause}${agentsClause}${artifactClause}`
35944
36115
  ].join("\n");
35945
36116
  }
35946
- if (opts.profile === "fast") {
36117
+ if (opts.profile === "fast" || opts.profile === "cheap" || opts.profile === "cheap1m") {
36118
+ const isCheap = opts.profile === "cheap" || opts.profile === "cheap1m";
36119
+ const profileLabel = isCheap ? "cheap" : "fast";
36120
+ const oracleDescriptor = isCheap ? "Grok 4.6 (200K/medium)" : "exact Opus 5 (1M/high)";
36121
+ const astraDescriptor = isCheap ? "200K/medium" : "200K/high";
35947
36122
  const fastPeersKey = key("peers");
35948
36123
  const fastSearchKey = key("search");
35949
36124
  const fastBrowserKey = key("browser");
@@ -35954,9 +36129,9 @@ function buildPeerAwarenessSnippet(opts) {
35954
36129
  return [
35955
36130
  "## Peer review and advisor",
35956
36131
  "",
35957
- `This is the fast launch profile. Follow an evidence-first escalation ladder: settle factual claims directly through code, tests, and builds. Advisor is an optional, non-binding, lead-only transcript-aware sounding board for trajectory guidance, framing checks, or conflicting signals (direction, not dictation), not routine progress, waiting, verification, or completion. \`mcp__${fastPeersKey}__oracle\` is exact Opus 5 (1M/high), an expert consultant available to the lead and \`Plan\`, preferred over advisor for difficult conceptual, algorithmic, spec/protocol, or architectural tradeoffs evaluated in a self-contained brief; \`reviewer\` and other subagents cannot call Oracle.${opts.astraAvailable ? ` \`mcp__${fastPeersKey}__astra\` is GPT-6 Astra (200K/high), an expensive terminal escalation consultant available to the lead only for hardest dead ends.` : ""}`,
36132
+ `This is the ${profileLabel} launch profile. Follow an evidence-first escalation ladder: settle factual claims directly through code, tests, and builds. Advisor is an optional, non-binding, lead-only transcript-aware sounding board for trajectory guidance, framing checks, or conflicting signals (direction, not dictation), not routine progress, waiting, verification, or completion. \`mcp__${fastPeersKey}__oracle\` is ${oracleDescriptor}, an expert consultant available to the lead and \`Plan\`, preferred over advisor for difficult conceptual, algorithmic, spec/protocol, or architectural tradeoffs evaluated in a self-contained brief; \`reviewer\` and other subagents cannot call Oracle.${opts.astraAvailable && opts.profile !== "cheap" ? ` \`mcp__${fastPeersKey}__astra\` is GPT-6 Astra (${astraDescriptor}), an expensive terminal escalation consultant available to the lead only for hardest dead ends.` : ""}`,
35958
36133
  "",
35959
- `\`mcp__${fastSearchKey}__code\` is semantic-first code search and \`mcp__${fastSearchKey}__web\` surfaces citable sources. Native Task roster: \`Explore\` (cheap broad discovery, launch in parallel), \`Plan\` (sequencing, interfaces, migration risk, acceptance criteria in plan mode), \`general-purpose\` (mixed execution), \`implementer\` (bounded coding), and \`reviewer\` (repo-aware verification after non-trivial changes). In plan mode, delegate planning to \`Plan\` and do not edit files. Verify claims with concrete repository evidence and tests before declaring done.${browserClause}${workerBrowseClause}${artifactClause}`,
36134
+ `\`mcp__${fastSearchKey}__code\` is semantic-first code search and \`mcp__${fastSearchKey}__web\` surfaces citable sources. Native Task roster: \`Explore\` (mandatory cheap broad discovery, launch in parallel; lead/\`Plan\` delegate rather than self-sweep), \`Plan\` (sequencing, interfaces, migration risk, acceptance criteria in plan mode), \`general-purpose\` (mixed execution), \`implementer\` (bounded coding in a fresh context to preserve lead context), and \`reviewer\` (repo-aware verification after non-trivial changes and always after \`implementer\`). In plan mode, delegate planning to \`Plan\` and do not edit files. Verify claims with concrete repository evidence and tests before declaring done.${browserClause}${workerBrowseClause}${artifactClause}`,
35960
36135
  "Native delegation is ACL-scoped: the lead may invoke all five; `Plan` may invoke `Explore` and `reviewer`; `implementer` and `general-purpose` may invoke `reviewer`; `Explore`, `reviewer`, and `worker-browse` cannot invoke native subagents."
35961
36136
  ].join("\n");
35962
36137
  }
@@ -36019,16 +36194,20 @@ function buildPeerAwarenessSummary(opts) {
36019
36194
  "Max native roster: `Explore` for broad discovery; `Plan` for interfaces, sequencing, risks, and acceptance criteria; `general-purpose` for bounded mixed execution; `implementer` for settled coding changes; `reviewer` for repository-aware verification and reproduction; `brainstorm` for materially different open approaches; and `peer-review-coordinator` for several distinct fresh-context review lenses. Configured models are deliberate role defaults.",
36020
36195
  "Native roles can inspect the repository within their listed tools. Fresh-context peers see only the artifact and constraints supplied to them. Advisor is transcript-aware, optional, non-binding, and primary-lead-only; it can identify framing drift but is not independent verification or an approval gate. Detailed routing lives in each role or tool description, and the full gated capability inventory lives in CLAUDE.md."
36021
36196
  ].join("\n");
36022
- if (opts.profile === "fast") {
36197
+ if (opts.profile === "fast" || opts.profile === "cheap" || opts.profile === "cheap1m") {
36198
+ const isCheap = opts.profile === "cheap" || opts.profile === "cheap1m";
36199
+ const profileLabel = isCheap ? "Cheap" : "Fast";
36200
+ const oracleDescriptor = isCheap ? "Grok 4.6 (200K/medium)" : "exact Opus 5 (1M/high)";
36201
+ const astraDescriptor = isCheap ? "200K/medium" : "200K/high";
36023
36202
  const browserClause = opts.browserToolsAvailable ?? opts.browseAvailable ? ` \`mcp__${key("browser")}__*\` provides the opt-in browser.` : "";
36024
36203
  const workerBrowseClause = opts.browseAvailable ? ` \`worker-browse\` runs delegated browsing tasks through \`mcp__${key("workers")}__browse\`.` : "";
36025
- const astraClause = opts.astraAvailable ? ` \`mcp__${key("peers")}__astra\` is GPT-6 Astra (200K/high), lead-only escalation for hardest dead ends.` : "";
36204
+ const astraClause = opts.astraAvailable && opts.profile !== "cheap" ? ` \`mcp__${key("peers")}__astra\` is GPT-6 Astra (${astraDescriptor}), lead-only escalation for hardest dead ends.` : "";
36026
36205
  return [
36027
36206
  "## Injected capabilities (summary)",
36028
36207
  "",
36029
- "Fast launch profile. Task roster: `Explore` (cheap discovery in parallel), `Plan` (planning in plan mode), `general-purpose`, `implementer`, `reviewer` (verification after implementation). Verify claims with concrete repository evidence and tests before declaring done.",
36208
+ `${profileLabel} launch profile. Task roster: \`Explore\` (mandatory parallel discovery delegate), \`Plan\` (planning in plan mode), \`general-purpose\` (mixed execution), \`implementer\` (fresh-context bounded implementation), \`reviewer\` (verification after implementation, always after \`implementer\`). Verify claims with concrete repository evidence and tests before declaring done.`,
36030
36209
  "Native delegation is ACL-scoped: the lead may invoke all five; `Plan` may invoke `Explore` and `reviewer`; `implementer` and `general-purpose` may invoke `reviewer`; `Explore`, `reviewer`, and `worker-browse` cannot invoke native subagents.",
36031
- `Advisor is optional, non-binding, transcript-aware, and lead-only for trajectory guidance or framing checks (direction, not dictation). \`mcp__${key("peers")}__oracle\` is exact Opus 5 (1M/high), an expert consultant for the lead and \`Plan\`, preferred over advisor for substantive trade-offs.${astraClause} \`mcp__${key("search")}__code\` and \`mcp__${key("search")}__web\` provide search.${browserClause}${workerBrowseClause}${opts.artifactToolsAvailable ? ` \`mcp__${key("peers")}__artifact_*\` provides human review with plan auto-open.` : ""}`
36210
+ `Advisor is optional, non-binding, transcript-aware, and lead-only for trajectory guidance or framing checks (direction, not dictation). \`mcp__${key("peers")}__oracle\` is ${oracleDescriptor}, an expert consultant for the lead and \`Plan\`, preferred over advisor for substantive trade-offs.${astraClause} \`mcp__${key("search")}__code\` and \`mcp__${key("search")}__web\` provide search.${browserClause}${workerBrowseClause}${opts.artifactToolsAvailable ? ` \`mcp__${key("peers")}__artifact_*\` provides human review with plan auto-open.` : ""}`
36032
36211
  ].join("\n");
36033
36212
  }
36034
36213
  const renderNative = (name) => {
@@ -37413,6 +37592,6 @@ function enumerateInjectedMcpToolNames(groupKeys, opts = {}) {
37413
37592
  return [...new Set(names)];
37414
37593
  }
37415
37594
  //#endregion
37416
- export { UNKNOWN_EFFORT_ANCHOR as $, extractZipMember as $t, TOOLBELT_TOOLS$1 as A, shimDefaultsToXhigh as At, resolveAdvisorEffort as B, warnOnTokenPriceDrift as Bt, runWorkerAgent as C, oneMContextDisabled as Cn, resolveGeminiReviewModel as Ct, toolbeltEnabled as D, scribeModel as Dt, buildToolbeltAwareness as E, withInstallLock as En, scoutModel as Et, ADVISOR_TOOL_INSTRUCTIONS as F, getTokenizerFromModel as Ft, repairRejectedThinkingHistory as G, readResponseBodyCapped as Gt, formatThinkingRepairDecline as H, createResponses as Ht, FAST_ADVISOR_TOOL_INSTRUCTIONS as I, findLaunchBySecret as It, isControllerClosedError as J, provisionBrowserAssets as Jt, buildAnthropicErrorEvent as K, parseJsonOrDiagnose as Kt, buildAdvisorStream as L, registerLaunch as Lt, satisfiesMinVersion as M, createMessages as Mt, searchWeb as N, getTextTokenCount as Nt, toolbeltSkipSet as O, standInToolEnabled as Ot, ADVISOR_INTERNAL_TOOL_NAME as P, getTokenCount as Pt, EFFORT_ORDER as Q, extractTarGzMember as Qt, injectAdvisorTool as R, unregisterLaunch as Rt, resolveWorkerRunOpts as S, catalogAdvertises1M as Sn, nativeSubagentModel as St, availableToolCommands as T, withOneMSuffixForLead as Tn, reviewerModel as Tt, rememberThinkingHistoryRepair as U, createChatCompletions as Ut, resolveAdvisorModel as V, resolveMcpToolTimeoutMs as Vt, repairKnownThinkingHistory as W, MAX_RESPONSE_BODY_BYTES as Wt, readIteratorWithTimeout as X, colbertDegradedWarning as Xt, logStreamError as Y, hasSupportedBrowserInstalled as Yt, relayAnthropicStream as Z, provisionAndIndexColbert as Zt, REVIEW_DEFAULT_MODEL as _, pickClaudeDefault as _n, fastScoutModel as _t, buildAgentPrompt as a, collapsePathKeys as an, artifactToolsEnabled as at, resolveDefaultModel as b, upstreamMaxConnections as bn, generalPurposeFastModel as bt, enumerateInjectedMcpToolNames as c, BUDGET_SMALL_FAST_SLUG as cn, browserCompoundToolsEnabled as ct, BROWSE_DEFAULT_MODEL as d, DEFAULT_CODEX_MODEL_FALLBACKS as dn, fastAstraModel as dt, warmTreeSitterPool as en, bucketEffort as et, DEFAULT_MODEL_CHAIN as f, DEFAULT_PORT as fn, fastGeneralPurposeModel as ft, PLAN_DEFAULT_MODEL as g, isBudgetClaudeLead as gn, fastReviewerModel as gt, IMPLEMENT_DEFAULT_MODEL as h, generateRandomPort as hn, fastPlanModel as ht, assertMcpToolSurfaceConsistent as i, shouldUseInsecureTls as in, agentToolsEnabled as it, assetFor as j, countTokens as jt, vscodeRipgrepPath as k, workerToolsEnabled as kt, maxPersonasFor as l, DEFAULT_CLAUDE_MODEL_FALLBACKS as ln, browserToolsEnabled as lt, EXPLORE_DEFAULT_THINKING as m, UPSTREAM_INACTIVITY_TIMEOUT_MS as mn, fastOracleModel as mt, MCP_GROUPS as n, CONDENSED_OPERATING_SEQUENCE as nn, handleMcpDelete as nt, buildPeerAwarenessSnippet as o, toolbeltPathOverride as on, brainstormModel as ot, EXPLORE_DEFAULT_MODEL as p, UPSTREAM_FETCH_TIMEOUT_MS as pn, fastImplementerModel as pt, buildOpenAIErrorEvent as q, normalizeOpenAIUsage as qt, agentNamesForToolAllowlist as r, DEFINITION_OF_GREATNESS as rn, handleMcpPost as rt, buildPeerAwarenessSummary as s, BUDGET_SMALL_FAST_CATALOG_ID as sn, browseAgentEnabled as st, GROUP_META as t, provisionTreeSitterAssets as tn, clampEffort as tt, personasFor as u, DEFAULT_CODEX_MODEL as un, fastAdvisorModel as ut, TEST_DEFAULT_MODEL as v, resolveLeadSlugArg as vn, fleetToolsEnabled as vt, buildEnv as w, withOneMSuffix as wn, reviewerFastModel as wt, resolveModeDefaults as x, classifyMessagesRoute as xn, implementerFastModel as xt, appendPlanReminder as y, upstreamAllowH2 as yn, geminiAvailable as yt, isAdvisorRequested as z, assembleResponsesPayload as zt };
37595
+ export { UNKNOWN_EFFORT_ANCHOR as $, colbertDegradedWarning as $t, TOOLBELT_TOOLS$1 as A, CHEAP_PROFILE_MODELS as An, scribeModel as At, resolveAdvisorEffort as B, registerLaunch as Bt, runWorkerAgent as C, upstreamMaxConnections as Cn, generalPurposeFastModel as Ct, toolbeltEnabled as D, withOneMSuffix as Dn, reviewerFastModel as Dt, buildToolbeltAwareness as E, oneMContextDisabled as En, resolveGeminiReviewModel as Et, ADVISOR_TOOL_INSTRUCTIONS as F, withInstallLock as Fn, createMessages as Ft, repairRejectedThinkingHistory as G, createResponses as Gt, formatThinkingRepairDecline as H, assembleResponsesPayload as Ht, FAST_ADVISOR_TOOL_INSTRUCTIONS as I, getTextTokenCount as It, isControllerClosedError as J, readResponseBodyCapped as Jt, buildAnthropicErrorEvent as K, createChatCompletions as Kt, buildAdvisorStream as L, getTokenCount as Lt, satisfiesMinVersion as M, CHEAP_PROFILE_NATIVE_EFFORTS as Mn, workerToolsEnabled as Mt, searchWeb as N, CHEAP_PROFILE_NATIVE_MODELS as Nn, shimDefaultsToXhigh as Nt, toolbeltSkipSet as O, withOneMSuffixForLead as On, reviewerModel as Ot, ADVISOR_INTERNAL_TOOL_NAME as P, CHEAP_PROFILE_SUBAGENT_CONTEXT_TOKENS as Pn, countTokens as Pt, EFFORT_ORDER as Q, hasSupportedBrowserInstalled as Qt, injectAdvisorTool as R, getTokenizerFromModel as Rt, resolveWorkerRunOpts as S, upstreamAllowH2 as Sn, geminiAvailable as St, availableToolCommands as T, catalogAdvertises1M as Tn, nativeSubagentModel as Tt, rememberThinkingHistoryRepair as U, warnOnTokenPriceDrift as Ut, resolveAdvisorModel as V, unregisterLaunch as Vt, repairKnownThinkingHistory as W, resolveMcpToolTimeoutMs as Wt, readIteratorWithTimeout as X, normalizeOpenAIUsage as Xt, logStreamError as Y, parseJsonOrDiagnose as Yt, relayAnthropicStream as Z, provisionBrowserAssets as Zt, REVIEW_DEFAULT_MODEL as _, UPSTREAM_INACTIVITY_TIMEOUT_MS as _n, fastOracleModel as _t, buildAgentPrompt as a, CONDENSED_OPERATING_SEQUENCE as an, artifactToolsEnabled as at, resolveDefaultModel as b, pickClaudeDefault as bn, fastScoutModel as bt, enumerateInjectedMcpToolNames as c, collapsePathKeys as cn, browserCompoundToolsEnabled as ct, BROWSE_DEFAULT_MODEL as d, BUDGET_SMALL_FAST_SLUG as dn, cheapOracleModel as dt, provisionAndIndexColbert as en, bucketEffort as et, DEFAULT_MODEL_CHAIN as f, DEFAULT_CLAUDE_MODEL_FALLBACKS as fn, cheapReviewerModel as ft, PLAN_DEFAULT_MODEL as g, UPSTREAM_FETCH_TIMEOUT_MS as gn, fastImplementerModel as gt, IMPLEMENT_DEFAULT_MODEL as h, DEFAULT_PORT as hn, fastGeneralPurposeModel as ht, assertMcpToolSurfaceConsistent as i, provisionTreeSitterAssets as in, agentToolsEnabled as it, assetFor as j, CHEAP_PROFILE_NATIVE_AGENT_NAMES as jn, standInToolEnabled as jt, vscodeRipgrepPath as k, CHEAP_PROFILE_ADVISOR_CLIENT_MODEL as kn, scoutModel as kt, maxPersonasFor as l, toolbeltPathOverride as ln, browserToolsEnabled as lt, EXPLORE_DEFAULT_THINKING as m, DEFAULT_CODEX_MODEL_FALLBACKS as mn, fastAstraModel as mt, MCP_GROUPS as n, extractZipMember as nn, handleMcpDelete as nt, buildPeerAwarenessSnippet as o, DEFINITION_OF_GREATNESS as on, brainstormModel as ot, EXPLORE_DEFAULT_MODEL as p, DEFAULT_CODEX_MODEL as pn, fastAdvisorModel as pt, buildOpenAIErrorEvent as q, MAX_RESPONSE_BODY_BYTES as qt, agentNamesForToolAllowlist as r, warmTreeSitterPool as rn, handleMcpPost as rt, buildPeerAwarenessSummary as s, shouldUseInsecureTls as sn, browseAgentEnabled as st, GROUP_META as t, extractTarGzMember as tn, clampEffort as tt, personasFor as u, BUDGET_SMALL_FAST_CATALOG_ID as un, cheapAdvisorModel as ut, TEST_DEFAULT_MODEL as v, generateRandomPort as vn, fastPlanModel as vt, buildEnv as w, classifyMessagesRoute as wn, implementerFastModel as wt, resolveModeDefaults as x, resolveLeadSlugArg as xn, fleetToolsEnabled as xt, appendPlanReminder as y, isBudgetClaudeLead as yn, fastReviewerModel as yt, isAdvisorRequested as z, findLaunchBySecret as zt };
37417
37596
 
37418
- //# sourceMappingURL=peer-mcp-personas-CBJbxpNT.js.map
37597
+ //# sourceMappingURL=peer-mcp-personas-DklYru_1.js.map