github-router 0.3.306 → 0.3.309
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/{attribution-settings-C5ScaOmz.js → attribution-settings-Ce6s_01h.js} +62 -63
- package/dist/attribution-settings-Ce6s_01h.js.map +1 -0
- package/dist/{auth-D9kUMR37.js → auth-O_UG1ABO.js} +3 -3
- package/dist/{auth-D9kUMR37.js.map → auth-O_UG1ABO.js.map} +1 -1
- package/dist/browser-ext/manifest.json +1 -1
- package/dist/{check-usage-C7MfBexN.js → check-usage-dicJOWML.js} +4 -4
- package/dist/{check-usage-C7MfBexN.js.map → check-usage-dicJOWML.js.map} +1 -1
- package/dist/{claude-CsGXL12X.js → claude-i4L8GZbI.js} +33 -30
- package/dist/claude-i4L8GZbI.js.map +1 -0
- package/dist/{codex-DpwyLLTp.js → codex-GZGqYj0M.js} +5 -5
- package/dist/{codex-DpwyLLTp.js.map → codex-GZGqYj0M.js.map} +1 -1
- package/dist/{debug-CDu4RIgW.js → debug-2PgImRnr.js} +2 -2
- package/dist/{debug-CDu4RIgW.js.map → debug-2PgImRnr.js.map} +1 -1
- package/dist/engine-DMnMGgeZ.js +2 -0
- package/dist/{fast-profile-contract-OuZQaGif.js → fast-profile-contract-BWCJy6iL.js} +6 -4
- package/dist/fast-profile-contract-BWCJy6iL.js.map +1 -0
- package/dist/{gate-discovery-BVLZH7-6.js → gate-discovery-DkJf7d-y.js} +5 -5
- package/dist/{gate-discovery-BVLZH7-6.js.map → gate-discovery-DkJf7d-y.js.map} +1 -1
- package/dist/{get-copilot-usage-CNMvWsMD.js → get-copilot-usage-Cjy8TiFf.js} +2 -2
- package/dist/{get-copilot-usage-CNMvWsMD.js.map → get-copilot-usage-Cjy8TiFf.js.map} +1 -1
- package/dist/hooks.mjs +28 -12
- package/dist/hooks.sha256 +1 -1
- package/dist/{internal-artifact-open-wYwuChib.js → internal-artifact-open-CxeIfsW_.js} +2 -2
- package/dist/{internal-artifact-open-wYwuChib.js.map → internal-artifact-open-CxeIfsW_.js.map} +1 -1
- package/dist/{internal-fast-dispatch-guard-CXs4ympz.js → internal-fast-dispatch-guard-CrsZI0pO.js} +1 -1
- package/dist/{internal-fast-dispatch-guard-u3vxgazZ.js → internal-fast-dispatch-guard-kzSKB0yV.js} +3 -3
- package/dist/{internal-fast-dispatch-guard-u3vxgazZ.js.map → internal-fast-dispatch-guard-kzSKB0yV.js.map} +1 -1
- package/dist/{internal-first-mate-guard-C8GG8i5H.js → internal-first-mate-guard-BuweUgjb.js} +3 -3
- package/dist/{internal-first-mate-guard-C8GG8i5H.js.map → internal-first-mate-guard-BuweUgjb.js.map} +1 -1
- package/dist/{internal-first-mate-guard-BGaGGIBS.js → internal-first-mate-guard-Nf1H0mCK.js} +1 -1
- package/dist/{internal-max-dispatch-guard-B-n687ho.js → internal-max-dispatch-guard-DF-f8VwE.js} +1 -1
- package/dist/{internal-max-dispatch-guard-Cw_9Qx-9.js → internal-max-dispatch-guard-lS4usOV5.js} +12 -5
- package/dist/internal-max-dispatch-guard-lS4usOV5.js.map +1 -0
- package/dist/{internal-plan-review-DCbxSIUR.js → internal-plan-review-DLduDz41.js} +3 -3
- package/dist/{internal-plan-review-DCbxSIUR.js.map → internal-plan-review-DLduDz41.js.map} +1 -1
- package/dist/{internal-prompt-submit-DIn8b_Zt.js → internal-prompt-submit-DG94f8E-.js} +4 -4
- package/dist/{internal-prompt-submit-DIn8b_Zt.js.map → internal-prompt-submit-DG94f8E-.js.map} +1 -1
- package/dist/{internal-session-bind-DXosxciQ.js → internal-session-bind-D6Hpl-84.js} +2 -2
- package/dist/{internal-session-bind-DXosxciQ.js.map → internal-session-bind-D6Hpl-84.js.map} +1 -1
- package/dist/{internal-stop-hook-C2lMgQuU.js → internal-stop-hook-XRtB33hW.js} +5 -5
- package/dist/{internal-stop-hook-C2lMgQuU.js.map → internal-stop-hook-XRtB33hW.js.map} +1 -1
- package/dist/{internal-stop-review-CnYqJTiC.js → internal-stop-review-DlKzZgFm.js} +2 -2
- package/dist/{internal-stop-review-CnYqJTiC.js.map → internal-stop-review-DlKzZgFm.js.map} +1 -1
- package/dist/{internal-worker-guard-DdwLtAMn.js → internal-worker-guard-D7sfByyo.js} +2 -2
- package/dist/{internal-worker-guard-DdwLtAMn.js.map → internal-worker-guard-D7sfByyo.js.map} +1 -1
- package/dist/{internal-workspace-header-B4qymRDb.js → internal-workspace-header-CU5OjLCB.js} +2 -2
- package/dist/{internal-workspace-header-B4qymRDb.js.map → internal-workspace-header-CU5OjLCB.js.map} +1 -1
- package/dist/lifecycle-B0USSJvd.js +2 -0
- package/dist/{lifecycle-DOvQozrm.js → lifecycle-BCnarXJV.js} +2 -2
- package/dist/{lifecycle-DOvQozrm.js.map → lifecycle-BCnarXJV.js.map} +1 -1
- package/dist/lifecycle-CQFjaQc0.js +2 -0
- package/dist/{lifecycle-CSHU91pP.js → lifecycle-CtRA3Y7p.js} +2 -2
- package/dist/{lifecycle-CSHU91pP.js.map → lifecycle-CtRA3Y7p.js.map} +1 -1
- package/dist/main.js +19 -19
- package/dist/max-profile-contract-v2Q6eN5w.js +355 -0
- package/dist/max-profile-contract-v2Q6eN5w.js.map +1 -0
- package/dist/{mcp-workspace-header-Cv4QWFVV.js → mcp-workspace-header-B60WSR1Y.js} +2 -2
- package/dist/{mcp-workspace-header-Cv4QWFVV.js.map → mcp-workspace-header-B60WSR1Y.js.map} +1 -1
- package/dist/{models-BDhlItXr.js → models-COuMOfM6.js} +3 -3
- package/dist/{models-BDhlItXr.js.map → models-COuMOfM6.js.map} +1 -1
- package/dist/{orchestration-C2Q_Qynl.js → orchestration-DjLA-lxB.js} +2 -2
- package/dist/{orchestration-C2Q_Qynl.js.map → orchestration-DjLA-lxB.js.map} +1 -1
- package/dist/{paths-D6SI5bmY.js → paths-De1Qh9Q9.js} +4 -4
- package/dist/{paths-D6SI5bmY.js.map → paths-De1Qh9Q9.js.map} +1 -1
- package/dist/paths-DyX6SEnd.js +2 -0
- package/dist/{peer-mcp-personas-DXOdPbev.js → peer-mcp-personas-C_38ckts.js} +130 -360
- package/dist/peer-mcp-personas-C_38ckts.js.map +1 -0
- package/dist/{plan-review-hook-CnRRttwl.js → plan-review-hook-vL6BYmA8.js} +3 -3
- package/dist/{plan-review-hook-CnRRttwl.js.map → plan-review-hook-vL6BYmA8.js.map} +1 -1
- package/dist/{prompt-submit-hook-G84QAm_F.js → prompt-submit-hook-DfqufWC1.js} +3 -3
- package/dist/{prompt-submit-hook-G84QAm_F.js.map → prompt-submit-hook-DfqufWC1.js.map} +1 -1
- package/dist/{provision-CfB_DkuL.js → provision-BoOza223.js} +4 -4
- package/dist/{provision-CfB_DkuL.js.map → provision-BoOza223.js.map} +1 -1
- package/dist/{self-invocation-Da5gSWen.js → self-invocation-B84JCHps.js} +2 -2
- package/dist/{self-invocation-Da5gSWen.js.map → self-invocation-B84JCHps.js.map} +1 -1
- package/dist/{serve-Bfw7xEkR.js → serve-DpS_lCbm.js} +12 -12
- package/dist/{serve-Bfw7xEkR.js.map → serve-DpS_lCbm.js.map} +1 -1
- package/dist/{server-setup-Cbuq2-Bi.js → server-setup-3nCFVn79.js} +301 -11
- package/dist/server-setup-3nCFVn79.js.map +1 -0
- package/dist/{start-CLSlFGUF.js → start-CX92d6cy.js} +3 -3
- package/dist/{start-CLSlFGUF.js.map → start-CX92d6cy.js.map} +1 -1
- package/dist/{stop-gate-hook-rjDyq1lk.js → stop-gate-hook-BEU8qQrC.js} +3 -3
- package/dist/{stop-gate-hook-rjDyq1lk.js.map → stop-gate-hook-BEU8qQrC.js.map} +1 -1
- package/dist/{stop-gate-policy-m3dvbV10.js → stop-gate-policy-qzqXfRxE.js} +2 -2
- package/dist/{stop-gate-policy-m3dvbV10.js.map → stop-gate-policy-qzqXfRxE.js.map} +1 -1
- package/dist/{token-DnTZlcc6.js → token-CCg-Ov5q.js} +2 -2
- package/dist/{token-DnTZlcc6.js.map → token-CCg-Ov5q.js.map} +1 -1
- package/dist/{worker-dispatch-CQ2y0aBP.js → worker-dispatch-CH-NN5FW.js} +2 -2
- package/dist/{worker-dispatch-CQ2y0aBP.js.map → worker-dispatch-CH-NN5FW.js.map} +1 -1
- package/package.json +1 -1
- package/dist/attribution-settings-C5ScaOmz.js.map +0 -1
- package/dist/claude-CsGXL12X.js.map +0 -1
- package/dist/engine-j34DK_PM.js +0 -2
- package/dist/fast-profile-contract-OuZQaGif.js.map +0 -1
- package/dist/internal-max-dispatch-guard-Cw_9Qx-9.js.map +0 -1
- package/dist/lifecycle-B4DDf-Me.js +0 -2
- package/dist/lifecycle-D0BpTV9A.js +0 -2
- package/dist/max-profile-contract-CiD5wyET.js +0 -276
- package/dist/max-profile-contract-CiD5wyET.js.map +0 -1
- package/dist/paths-Bmj5b7PS.js +0 -2
- package/dist/peer-mcp-personas-DXOdPbev.js.map +0 -1
- package/dist/server-setup-Cbuq2-Bi.js.map +0 -1
|
@@ -0,0 +1,355 @@
|
|
|
1
|
+
import { t as state } from "./state-B8adscCv.js";
|
|
2
|
+
//#region src/lib/model-suffix.ts
|
|
3
|
+
/** Strip every trailing `[1m]` marker, case-insensitively. */
|
|
4
|
+
function stripTrailingOneMSuffix(id) {
|
|
5
|
+
const match = id.match(/(?:\[1m\])+$/i);
|
|
6
|
+
if (!match || match.index === void 0) return {
|
|
7
|
+
base: id,
|
|
8
|
+
hadSuffix: false
|
|
9
|
+
};
|
|
10
|
+
return {
|
|
11
|
+
base: id.slice(0, match.index),
|
|
12
|
+
hadSuffix: true
|
|
13
|
+
};
|
|
14
|
+
}
|
|
15
|
+
/** Reapply at most one canonical `[1m]` marker when the input had one. */
|
|
16
|
+
function normalizeTrailingOneMSuffix(id) {
|
|
17
|
+
const { base, hadSuffix } = stripTrailingOneMSuffix(id);
|
|
18
|
+
return hadSuffix ? `${base}[1m]` : base;
|
|
19
|
+
}
|
|
20
|
+
//#endregion
|
|
21
|
+
//#region src/lib/fast-endpoint.ts
|
|
22
|
+
const ENDPOINTS = {
|
|
23
|
+
chat: /* @__PURE__ */ new Set(["/chat/completions", "/v1/chat/completions"]),
|
|
24
|
+
responses: /* @__PURE__ */ new Set(["/responses", "/v1/responses"]),
|
|
25
|
+
messages: /* @__PURE__ */ new Set(["/messages", "/v1/messages"])
|
|
26
|
+
};
|
|
27
|
+
/**
|
|
28
|
+
* Return the endpoint mandated by a fast-profile roster model.
|
|
29
|
+
*
|
|
30
|
+
* This is intentionally independent of the standard `pickEndpoint`: that
|
|
31
|
+
* resolver prefers chat when a catalog entry advertises both clients, while
|
|
32
|
+
* fast roles have a fixed provider contract. Gemini stays on chat; Luna, Sol,
|
|
33
|
+
* and Grok stay on Responses; the Opus Oracle stays on native Messages.
|
|
34
|
+
* Unknown ids return undefined so a fast caller cannot guess a transport.
|
|
35
|
+
*/
|
|
36
|
+
function fastEndpointRequirement(modelId) {
|
|
37
|
+
const id = modelId.replace(/(?:\[1m\])+$/i, "");
|
|
38
|
+
if (id === "gemini-3.8-flash") return "chat";
|
|
39
|
+
if (id === "gpt-5.6-luna" || id === "gpt-5.6-sol" || id === "grok-4.6") return "responses";
|
|
40
|
+
if (id === "claude-opus-5" || id === "claude-sonnet-5") return "messages";
|
|
41
|
+
}
|
|
42
|
+
/**
|
|
43
|
+
* Resolve the fixed fast transport only when the catalog explicitly advertises
|
|
44
|
+
* the required endpoint. An entry that advertises both still resolves to the
|
|
45
|
+
* policy endpoint, regardless of advertisement order.
|
|
46
|
+
*/
|
|
47
|
+
function advertisesEndpoint(model, endpoint) {
|
|
48
|
+
const advertised = model?.supported_endpoints;
|
|
49
|
+
return Array.isArray(advertised) && advertised.some((value) => ENDPOINTS[endpoint].has(value));
|
|
50
|
+
}
|
|
51
|
+
function fastEndpointForModel(model) {
|
|
52
|
+
const required = fastEndpointRequirement(model.id);
|
|
53
|
+
if (!required) return void 0;
|
|
54
|
+
return advertisesEndpoint(model, required) ? required : void 0;
|
|
55
|
+
}
|
|
56
|
+
/** Resolve a fast endpoint from a catalog id, without selecting a fallback. */
|
|
57
|
+
function fastEndpointForCatalogId(modelId, catalog) {
|
|
58
|
+
const found = catalog?.find((model) => model.id === modelId);
|
|
59
|
+
return found ? fastEndpointForModel(found) : void 0;
|
|
60
|
+
}
|
|
61
|
+
//#endregion
|
|
62
|
+
//#region src/lib/max-profile-prompts.ts
|
|
63
|
+
const MAX_PARALLELISM_RULE = "When two or more delegated workstreams are independent and non-overlapping, issue them together; sequence them when one needs another's result or their side effects can conflict.";
|
|
64
|
+
const MAX_NATIVE_PROMPT_SPECS = {
|
|
65
|
+
Explore: {
|
|
66
|
+
capability: "read-oriented repository exploration",
|
|
67
|
+
useWhen: "the answer requires broad, multi-file or multi-source discovery and the caller needs conclusions rather than raw context",
|
|
68
|
+
notFor: "a narrow lookup, implementation planning, or editing",
|
|
69
|
+
returns: "concise conclusions, load-bearing file:line evidence, checks or sources consulted, and explicit gaps",
|
|
70
|
+
prompt: "Explore the supplied question across the actual repository. Stay within discovery: do not plan the implementation or modify files. Return concise conclusions, load-bearing file:line evidence, checks or sources consulted, and explicit gaps. Stop when the question is supported or the missing evidence is identified. You do not have Advisor or native-agent delegation tools."
|
|
71
|
+
},
|
|
72
|
+
Plan: {
|
|
73
|
+
capability: "implementation planning",
|
|
74
|
+
useWhen: "a non-trivial change crosses interfaces, has dependency or migration ordering, preserves important invariants, or needs explicit acceptance criteria",
|
|
75
|
+
notFor: "routine decomposition, implementation, approval, or silently deciding unresolved product choices",
|
|
76
|
+
returns: "affected files or symbols, ordered implementation slices, invariants, risks, open decisions, acceptance criteria, and runnable verification",
|
|
77
|
+
prompt: "Turn the supplied goal, constraints, and evidence into an actionable implementation plan. Return affected files or symbols, ordered implementation slices with real dependencies identified, invariants, risks, open decisions, acceptance criteria, and runnable verification. Surface unresolved product or architecture choices instead of deciding them silently. Stop when another agent can implement the plan without rediscovering its structure; the lead owns acceptance and execution. You do not have Advisor or native-agent delegation tools."
|
|
78
|
+
},
|
|
79
|
+
"general-purpose": {
|
|
80
|
+
capability: "bounded mixed investigation and execution",
|
|
81
|
+
useWhen: "one owner should carry a multi-step outcome across several narrower kinds of work",
|
|
82
|
+
notFor: "a narrow direct action or a task cleanly owned by one specialist",
|
|
83
|
+
returns: "the requested outcome, changed artifacts, verification evidence, blockers, and residual risks",
|
|
84
|
+
prompt: "Own the supplied bounded outcome end to end. Return the requested outcome, changed artifacts, verification evidence, blockers, and residual risks. Stop at the requested scope and do not absorb adjacent cleanup. Do not re-delegate the core assignment merely to repeat it; any supporting delegation must be independent, non-overlapping, and integrated and verified by you."
|
|
85
|
+
},
|
|
86
|
+
implementer: {
|
|
87
|
+
capability: "bounded coding implementation",
|
|
88
|
+
useWhen: "the desired behavior and constraints are settled but the implementation still needs coding judgment",
|
|
89
|
+
notFor: "unresolved product behavior, architecture choices, or an unbounded investigation",
|
|
90
|
+
returns: "a coherent scoped change, files changed, observable behavior, checks and results, blockers, and unresolved risks",
|
|
91
|
+
prompt: "Implement the settled desired behavior within the supplied scope and repository conventions. Return the files changed, observable behavior, checks and results, blockers, and unresolved risks. Stop and report when ambiguity would materially change product behavior, architecture, or scope. Do not re-delegate the core assignment merely to repeat it; any supporting delegation must be independent, non-overlapping, and integrated and verified by you."
|
|
92
|
+
},
|
|
93
|
+
reviewer: {
|
|
94
|
+
capability: "repository-aware verification and reproduction",
|
|
95
|
+
useWhen: "an implementation or failure already exists and assessment requires repository navigation, commands, tests, or runtime evidence",
|
|
96
|
+
notFor: "a stateless review of an already self-contained artifact or authoring the fix",
|
|
97
|
+
returns: "a calibrated verdict, severity-ranked findings, file:line evidence, concrete failure scenarios, checks and results, and unverified areas",
|
|
98
|
+
prompt: "Assess the supplied artifact against its intent and the actual repository or runtime state. Return a calibrated verdict, severity-ranked findings, file:line evidence, concrete failure scenarios, checks and results, and unverified areas. Distinguish no findings from checks not run. Do not modify files or act as an approval gate. Stop when material claims have been tested to the available extent; the lead owns remediation and go/no-go. You do not have Advisor or native-agent delegation tools."
|
|
99
|
+
},
|
|
100
|
+
brainstorm: {
|
|
101
|
+
capability: "divergent repository-feasible option generation",
|
|
102
|
+
useWhen: "materially different approaches remain credible before implementation planning",
|
|
103
|
+
notFor: "a settled approach, proven fact, implementation plan, or code change",
|
|
104
|
+
returns: "distinct options, trade-offs, assumptions, failure modes, discriminating evidence, and a recommendation only when supported",
|
|
105
|
+
prompt: "Explore the useful design space for the supplied open decision. Return materially distinct repository-feasible options, trade-offs, assumptions, failure modes, discriminating evidence, and a recommendation only when the available evidence supports one. Do not turn the result into an implementation plan or modify files. Stop once the useful alternatives are covered or one option clearly dominates; the lead owns the decision. You do not have Advisor or native-agent delegation tools."
|
|
106
|
+
}
|
|
107
|
+
};
|
|
108
|
+
function maxNativeDescription(role, model, effort) {
|
|
109
|
+
const spec = MAX_NATIVE_PROMPT_SPECS[role];
|
|
110
|
+
return `Max-profile ${spec.capability} subagent running ${model} at ${effort} effort. Use when: ${spec.useWhen}. Not for: ${spec.notFor}. Returns: ${spec.returns}.`;
|
|
111
|
+
}
|
|
112
|
+
function maxNativePrompt(role) {
|
|
113
|
+
return MAX_NATIVE_PROMPT_SPECS[role].prompt;
|
|
114
|
+
}
|
|
115
|
+
const MAX_COORDINATOR_DESCRIPTION = "Max-profile peer-review coordinator running gpt-5.6-luna at maximum effort. Use when: a consequential self-contained plan, design, or diff has at least two distinct unresolved risk lenses for which independent fresh-context review could change the decision. Not for: routine second opinions, repository exploration or execution, facts a focused check can settle, or repeating one generic review across models. Returns: a provenance-preserving synthesis of material findings, disagreements, evidence gaps, and the cheapest checks that can settle them.";
|
|
116
|
+
const MAX_COORDINATOR_PROMPT = `Coordinate independent fresh-context review of the self-contained artifact and constraints supplied by the caller. You have peer tools only and cannot inspect the repository, transcript, or runtime, so identify missing material instead of guessing. Select the smallest sufficient peer set: use one peer when one lens is enough, and multiple peers only for distinct unresolved risk dimensions. Give every peer a non-overlapping lens; do not send one generic brief to several models or duplicate a same-family lens as a vote. ${MAX_PARALLELISM_RULE} Deduplicate findings while preserving provenance and genuine disagreement. Return severity-ranked material findings, concrete failure scenarios, confidence, evidence gaps, and the cheapest repository check or test that can settle each disagreement. Do not count votes or issue an evidence-free approval. Peer output is advisory; the lead owns go/no-go and remediation.`;
|
|
117
|
+
function maxPeerDescription(opts) {
|
|
118
|
+
return `Max-profile ${opts.kind} backed by ${opts.model}. Lens: ${opts.lens}. Use when: ${opts.useWhen}. Not for: ${opts.notFor}. Cold-start: it has no repository or transcript access and sees only the supplied prompt, context, and images. Returns: only material findings, or an explicit no material finding result.`;
|
|
119
|
+
}
|
|
120
|
+
function maxPeerInstructions(opts) {
|
|
121
|
+
const locationRule = opts.kind === "line-level reviewer" ? "For each finding, cite a location from the supplied artifact, give severity and a concrete failure scenario, and suggest the smallest correction." : "For each finding, identify the failed assumption or invariant, its consequence, and the cheapest evidence that would confirm or refute it.";
|
|
122
|
+
return `You are ${opts.name}, a fresh-context ${opts.kind} running on ${opts.model}. Apply this lens: ${opts.lens}. You have no repository or transcript access; use only the supplied artifact, constraints, and images. If material context is missing, identify it instead of guessing. ${locationRule} Treat supplied locations as citations to the artifact, not proof of repository state. Report only material findings; "no material finding" is a valid result. Stop when the requested lens is covered without padding or manufactured objections.`;
|
|
123
|
+
}
|
|
124
|
+
const MAX_ADVISOR_TOOL_INSTRUCTIONS = `# Advisor Tool
|
|
125
|
+
|
|
126
|
+
You have access to an optional, primary-lead-only, transcript-aware Max Advisor. Transcript awareness makes it useful for detecting framing drift, changed assumptions, and a stuck strategy; it is not an independent repository verifier, supervisor, approver, workflow gate, or substitute for your own reasoning. You keep decision ownership.
|
|
127
|
+
|
|
128
|
+
Use it for one precise consequential uncertainty that remains after proportionate direct investigation and cannot be settled by repository evidence, a focused command or test, Plan, reviewer, or a fresh-context peer. State the question, relevant evidence, credible alternatives, and what evidence would change the decision. Evidence-first does not require invoking every role before Advisor.
|
|
129
|
+
|
|
130
|
+
Do not call it for initial investigation, routine progress, waiting, ordinary verification, planner approval, reviewer confirmation, reassurance, or completion ceremony. Treat its result as advice, not authority. Consult again only when materially new or conflicting evidence creates a different question.`;
|
|
131
|
+
const MAX_ADVISOR_SYSTEM_PROMPT = "You are a non-binding, transcript-aware consultant to the primary lead. Answer the stated consequential question first, then give your recommendation and confidence, the transcript evidence and assumptions supporting it, the material risk, one credible alternative, and the evidence that would reverse your recommendation. The transcript may anchor you to the lead's framing, so identify any framing or assumption the session has stopped questioning. Stop after answering the focused question. Do not supervise, approve, veto, or redesign unrelated work; the lead weighs your advice against the user's intent and verified repository evidence.";
|
|
132
|
+
const ONE_M_TOKENS = 1e6;
|
|
133
|
+
function catalogModels() {
|
|
134
|
+
return state.models?.data ?? [];
|
|
135
|
+
}
|
|
136
|
+
function catalogModel(id) {
|
|
137
|
+
return catalogModels().find((model) => model.id === id);
|
|
138
|
+
}
|
|
139
|
+
const MAX_PROFILE_MODELS = Object.freeze({
|
|
140
|
+
sol: "gpt-5.6-sol",
|
|
141
|
+
luna: "gpt-5.6-luna",
|
|
142
|
+
gemini: "gemini-3.8-flash",
|
|
143
|
+
grok: "grok-4.6",
|
|
144
|
+
opus: "claude-opus-5",
|
|
145
|
+
sonnet: "claude-sonnet-5",
|
|
146
|
+
codex: "gpt-5.3-codex"
|
|
147
|
+
});
|
|
148
|
+
const MAX_PROFILE_NATIVE_AGENT_NAMES = [
|
|
149
|
+
"Explore",
|
|
150
|
+
"Plan",
|
|
151
|
+
"general-purpose",
|
|
152
|
+
"implementer",
|
|
153
|
+
"reviewer",
|
|
154
|
+
"brainstorm",
|
|
155
|
+
"peer-review-coordinator"
|
|
156
|
+
];
|
|
157
|
+
const MAX_PROFILE_NATIVE_EFFORTS = Object.freeze({
|
|
158
|
+
Explore: "high",
|
|
159
|
+
Plan: "high",
|
|
160
|
+
"general-purpose": "max",
|
|
161
|
+
implementer: "high",
|
|
162
|
+
reviewer: "xhigh",
|
|
163
|
+
brainstorm: "high",
|
|
164
|
+
"peer-review-coordinator": "max"
|
|
165
|
+
});
|
|
166
|
+
/** Default model family behind each native role's frontmatter. */
|
|
167
|
+
const MAX_PROFILE_NATIVE_MODELS = Object.freeze({
|
|
168
|
+
Explore: MAX_PROFILE_MODELS.luna,
|
|
169
|
+
Plan: MAX_PROFILE_MODELS.sol,
|
|
170
|
+
"general-purpose": MAX_PROFILE_MODELS.luna,
|
|
171
|
+
implementer: MAX_PROFILE_MODELS.gemini,
|
|
172
|
+
reviewer: MAX_PROFILE_MODELS.sonnet,
|
|
173
|
+
brainstorm: MAX_PROFILE_MODELS.opus,
|
|
174
|
+
"peer-review-coordinator": MAX_PROFILE_MODELS.luna
|
|
175
|
+
});
|
|
176
|
+
const MAX_PROFILE_LEAD_MODEL = MAX_PROFILE_MODELS.sol;
|
|
177
|
+
MAX_PROFILE_MODELS.opus;
|
|
178
|
+
const MAX_PROFILE_ADVISOR_EFFORT = "high";
|
|
179
|
+
const MAX_PROFILE_ADVISOR_INSTRUCTIONS = MAX_ADVISOR_TOOL_INSTRUCTIONS;
|
|
180
|
+
function maxAdvisorModelFromPin(pinned, opusModel) {
|
|
181
|
+
const trimmed = pinned?.trim();
|
|
182
|
+
const base = trimmed ? stripTrailingOneMSuffix(trimmed).base : void 0;
|
|
183
|
+
if (base === MAX_PROFILE_MODELS.sol || base === MAX_PROFILE_MODELS.opus) return base;
|
|
184
|
+
return opusModel ?? MAX_PROFILE_MODELS.opus;
|
|
185
|
+
}
|
|
186
|
+
function maxAdvisorPinIsValid(pinned) {
|
|
187
|
+
const trimmed = pinned?.trim();
|
|
188
|
+
const base = trimmed ? stripTrailingOneMSuffix(trimmed).base : trimmed;
|
|
189
|
+
return base === void 0 || base === "" || base === MAX_PROFILE_MODELS.sol || base === MAX_PROFILE_MODELS.opus;
|
|
190
|
+
}
|
|
191
|
+
function maxAdvisorEffortForModel(_model) {
|
|
192
|
+
return MAX_PROFILE_ADVISOR_EFFORT;
|
|
193
|
+
}
|
|
194
|
+
Object.freeze([
|
|
195
|
+
MAX_PROFILE_MODELS.luna,
|
|
196
|
+
MAX_PROFILE_MODELS.gemini,
|
|
197
|
+
MAX_PROFILE_MODELS.grok
|
|
198
|
+
]);
|
|
199
|
+
const MAX_PROFILE_ALLOWED_LEAD_MODEL_IDS = Object.freeze([
|
|
200
|
+
MAX_PROFILE_MODELS.sol,
|
|
201
|
+
MAX_PROFILE_MODELS.luna,
|
|
202
|
+
MAX_PROFILE_MODELS.gemini,
|
|
203
|
+
MAX_PROFILE_MODELS.opus
|
|
204
|
+
]);
|
|
205
|
+
function findModel(catalog, id) {
|
|
206
|
+
return catalog?.data?.find((model) => model.id === id);
|
|
207
|
+
}
|
|
208
|
+
function hasToolCalls(model) {
|
|
209
|
+
return model?.capabilities?.supports?.tool_calls === true;
|
|
210
|
+
}
|
|
211
|
+
function hasContextAtLeast(model, tokens) {
|
|
212
|
+
return (model?.capabilities?.limits?.max_context_window_tokens ?? 0) >= tokens;
|
|
213
|
+
}
|
|
214
|
+
function supportsEffort(model, effort) {
|
|
215
|
+
const ladder = model?.capabilities?.supports?.reasoning_effort;
|
|
216
|
+
return Array.isArray(ladder) && ladder.includes(effort);
|
|
217
|
+
}
|
|
218
|
+
function hasUsableLimits(model) {
|
|
219
|
+
const limits = model?.capabilities?.limits;
|
|
220
|
+
const prompt = limits?.max_prompt_tokens;
|
|
221
|
+
const output = limits?.max_output_tokens;
|
|
222
|
+
return typeof prompt === "number" && Number.isFinite(prompt) && prompt > 0 && typeof output === "number" && Number.isFinite(output) && output > 0 && (limits?.max_context_window_tokens ?? 0) >= prompt;
|
|
223
|
+
}
|
|
224
|
+
function supportsEndpoint(model, endpoint) {
|
|
225
|
+
return model !== void 0 && fastEndpointForModel(model) === endpoint;
|
|
226
|
+
}
|
|
227
|
+
function validateRequiredModel(model, id, requirements, missing) {
|
|
228
|
+
if (!model) {
|
|
229
|
+
missing.push(`${id}: absent from the live catalog`);
|
|
230
|
+
return;
|
|
231
|
+
}
|
|
232
|
+
for (const [message, ok] of requirements) if (!ok) missing.push(`${id}: ${message}`);
|
|
233
|
+
}
|
|
234
|
+
function usableGemini(model) {
|
|
235
|
+
return Boolean(model && hasToolCalls(model) && hasContextAtLeast(model, ONE_M_TOKENS) && supportsEffort(model, "high") && supportsEndpoint(model, "chat") && hasUsableLimits(model));
|
|
236
|
+
}
|
|
237
|
+
function usableGrok(model) {
|
|
238
|
+
return Boolean(model && hasToolCalls(model) && supportsEffort(model, "medium") && supportsEndpoint(model, "responses") && hasUsableLimits(model));
|
|
239
|
+
}
|
|
240
|
+
function usableGrokReviewer(model) {
|
|
241
|
+
return Boolean(usableGrok(model) && supportsEffort(model, "high") && (model?.capabilities?.limits?.max_prompt_tokens ?? 0) >= 2e5);
|
|
242
|
+
}
|
|
243
|
+
/**
|
|
244
|
+
* Validate the fixed prerequisites for the raw `-m max` launch.
|
|
245
|
+
*
|
|
246
|
+
* Max is a deliberately strong, closed profile. Its lead, planning,
|
|
247
|
+
* implementation, repository-review, brainstorm, and transcript-aware Advisor
|
|
248
|
+
* paths must all be present before any runtime artifact is written: Sol, Luna,
|
|
249
|
+
* Gemini 3.8 Flash, Sonnet 5, and Opus 5 are mandatory. Grok 4.6 is optional;
|
|
250
|
+
* when present it supplies additional peer critic/reviewer coverage and the
|
|
251
|
+
* preferred third-lab stand-in slot, but it is never a max lead and its sub-1M
|
|
252
|
+
* context must remain undecorated.
|
|
253
|
+
*/
|
|
254
|
+
function validateMaxProfilePrerequisites(catalog) {
|
|
255
|
+
const missing = [];
|
|
256
|
+
const sol = findModel(catalog, MAX_PROFILE_MODELS.sol);
|
|
257
|
+
const luna = findModel(catalog, MAX_PROFILE_MODELS.luna);
|
|
258
|
+
const gemini = findModel(catalog, MAX_PROFILE_MODELS.gemini);
|
|
259
|
+
const grok = findModel(catalog, MAX_PROFILE_MODELS.grok);
|
|
260
|
+
const opus = findModel(catalog, MAX_PROFILE_MODELS.opus);
|
|
261
|
+
const sonnet = findModel(catalog, MAX_PROFILE_MODELS.sonnet);
|
|
262
|
+
validateRequiredModel(sol, MAX_PROFILE_MODELS.sol, [
|
|
263
|
+
["does not advertise tool_calls", hasToolCalls(sol)],
|
|
264
|
+
["advertised context window is below 1M", hasContextAtLeast(sol, ONE_M_TOKENS)],
|
|
265
|
+
["does not advertise a high reasoning effort", supportsEffort(sol, "high")],
|
|
266
|
+
["does not advertise a supported Responses endpoint", supportsEndpoint(sol, "responses")],
|
|
267
|
+
["has no usable max_prompt_tokens/max_output_tokens limits", hasUsableLimits(sol)]
|
|
268
|
+
], missing);
|
|
269
|
+
validateRequiredModel(luna, MAX_PROFILE_MODELS.luna, [
|
|
270
|
+
["does not advertise tool_calls", hasToolCalls(luna)],
|
|
271
|
+
["advertised context window is below 1M", hasContextAtLeast(luna, ONE_M_TOKENS)],
|
|
272
|
+
["does not advertise a high reasoning effort", supportsEffort(luna, "high")],
|
|
273
|
+
["does not advertise a max reasoning effort", supportsEffort(luna, "max")],
|
|
274
|
+
["does not advertise a supported Responses endpoint", supportsEndpoint(luna, "responses")],
|
|
275
|
+
["has no usable max_prompt_tokens/max_output_tokens limits", hasUsableLimits(luna)]
|
|
276
|
+
], missing);
|
|
277
|
+
validateRequiredModel(gemini, MAX_PROFILE_MODELS.gemini, [
|
|
278
|
+
["does not advertise tool_calls", hasToolCalls(gemini)],
|
|
279
|
+
["advertised context window is below 1M", hasContextAtLeast(gemini, ONE_M_TOKENS)],
|
|
280
|
+
["does not advertise a high reasoning effort", supportsEffort(gemini, "high")],
|
|
281
|
+
["does not advertise a supported Chat Completions endpoint", supportsEndpoint(gemini, "chat")],
|
|
282
|
+
["has no usable max_prompt_tokens/max_output_tokens limits", hasUsableLimits(gemini)]
|
|
283
|
+
], missing);
|
|
284
|
+
validateRequiredModel(opus, MAX_PROFILE_MODELS.opus, [
|
|
285
|
+
["does not advertise tool_calls", hasToolCalls(opus)],
|
|
286
|
+
["advertised context window is below 1M", hasContextAtLeast(opus, ONE_M_TOKENS)],
|
|
287
|
+
["does not advertise adaptive_thinking", opus?.capabilities?.supports?.adaptive_thinking === true],
|
|
288
|
+
["does not advertise a high reasoning effort", supportsEffort(opus, "high")],
|
|
289
|
+
["does not advertise a supported Messages endpoint", supportsEndpoint(opus, "messages")],
|
|
290
|
+
["has no usable max_prompt_tokens/max_output_tokens limits", hasUsableLimits(opus)]
|
|
291
|
+
], missing);
|
|
292
|
+
validateRequiredModel(sonnet, MAX_PROFILE_MODELS.sonnet, [
|
|
293
|
+
["does not advertise tool_calls", hasToolCalls(sonnet)],
|
|
294
|
+
["advertised context window is below 1M", hasContextAtLeast(sonnet, ONE_M_TOKENS)],
|
|
295
|
+
["does not advertise adaptive_thinking", sonnet?.capabilities?.supports?.adaptive_thinking === true],
|
|
296
|
+
["does not advertise an xhigh reasoning effort", supportsEffort(sonnet, "xhigh")],
|
|
297
|
+
["does not advertise a supported Messages endpoint", supportsEndpoint(sonnet, "messages")],
|
|
298
|
+
["has no usable max_prompt_tokens/max_output_tokens limits", hasUsableLimits(sonnet)]
|
|
299
|
+
], missing);
|
|
300
|
+
const geminiUsable = usableGemini(gemini);
|
|
301
|
+
const grokUsable = usableGrok(grok);
|
|
302
|
+
return {
|
|
303
|
+
ok: missing.length === 0,
|
|
304
|
+
missing,
|
|
305
|
+
models: {
|
|
306
|
+
sol: sol && !missing.some((entry) => entry.startsWith(`${MAX_PROFILE_MODELS.sol}:`)) ? sol : void 0,
|
|
307
|
+
luna: luna && !missing.some((entry) => entry.startsWith(`${MAX_PROFILE_MODELS.luna}:`)) ? luna : void 0,
|
|
308
|
+
gemini: geminiUsable ? gemini : void 0,
|
|
309
|
+
grok: grokUsable ? grok : void 0,
|
|
310
|
+
opus: opus && !missing.some((entry) => entry.startsWith(`${MAX_PROFILE_MODELS.opus}:`)) ? opus : void 0,
|
|
311
|
+
sonnet: sonnet && !missing.some((entry) => entry.startsWith(`${MAX_PROFILE_MODELS.sonnet}:`)) ? sonnet : void 0,
|
|
312
|
+
thirdLab: grokUsable && supportsEffort(grok, "high") ? "grok" : geminiUsable ? "gemini" : void 0
|
|
313
|
+
}
|
|
314
|
+
};
|
|
315
|
+
}
|
|
316
|
+
function formatMaxPrerequisiteFailure(missing) {
|
|
317
|
+
return "github-router claude -m max requires the following live-catalog capabilities, which this account's catalog does not fully provide:\n" + missing.map((entry) => ` - ${entry}`).join("\n") + "\n\nMax launches do not fall back to arbitrary older models. Use plain `github-router claude` for the standard profile.";
|
|
318
|
+
}
|
|
319
|
+
function maxGeminiModel() {
|
|
320
|
+
const model = catalogModel(MAX_PROFILE_MODELS.gemini);
|
|
321
|
+
return model && usableGemini(model) ? model.id : void 0;
|
|
322
|
+
}
|
|
323
|
+
function maxGrokModel() {
|
|
324
|
+
const model = catalogModel(MAX_PROFILE_MODELS.grok);
|
|
325
|
+
return model && usableGrok(model) ? model.id : void 0;
|
|
326
|
+
}
|
|
327
|
+
/** Grok replacement for max-profile surfaces that require high effort. */
|
|
328
|
+
function maxGrokHighModel() {
|
|
329
|
+
const model = catalogModel(MAX_PROFILE_MODELS.grok);
|
|
330
|
+
return model && usableGrokReviewer(model) ? model.id : void 0;
|
|
331
|
+
}
|
|
332
|
+
/** Max-only replacement for any standard Gemini Pro assignment. */
|
|
333
|
+
function maxProReplacementModel() {
|
|
334
|
+
if (maxGrokHighModel()) return MAX_PROFILE_MODELS.grok;
|
|
335
|
+
if (maxGeminiModel()) return MAX_PROFILE_MODELS.gemini;
|
|
336
|
+
}
|
|
337
|
+
function maxOpusModel() {
|
|
338
|
+
const model = catalogModel(MAX_PROFILE_MODELS.opus);
|
|
339
|
+
return model && hasContextAtLeast(model, ONE_M_TOKENS) && model.capabilities?.supports?.adaptive_thinking === true && supportsEffort(model, "high") && supportsEndpoint(model, "messages") && hasUsableLimits(model) ? model.id : void 0;
|
|
340
|
+
}
|
|
341
|
+
function maxSonnetModel() {
|
|
342
|
+
const model = catalogModel(MAX_PROFILE_MODELS.sonnet);
|
|
343
|
+
return model && hasContextAtLeast(model, ONE_M_TOKENS) && model.capabilities?.supports?.tool_calls === true && model.capabilities?.supports?.adaptive_thinking === true && supportsEffort(model, "xhigh") && supportsEndpoint(model, "messages") && hasUsableLimits(model) ? model.id : void 0;
|
|
344
|
+
}
|
|
345
|
+
function maxReviewerModel() {
|
|
346
|
+
return maxSonnetModel();
|
|
347
|
+
}
|
|
348
|
+
function maxCodexReviewerModel() {
|
|
349
|
+
const model = catalogModel(MAX_PROFILE_MODELS.codex);
|
|
350
|
+
return model && hasToolCalls(model) && supportsEffort(model, "xhigh") && advertisesEndpoint(model, "responses") && hasUsableLimits(model) && (model.capabilities?.limits?.max_prompt_tokens ?? 0) >= 2e5 ? model.id : void 0;
|
|
351
|
+
}
|
|
352
|
+
//#endregion
|
|
353
|
+
export { normalizeTrailingOneMSuffix as A, MAX_PARALLELISM_RULE as C, maxPeerInstructions as D, maxPeerDescription as E, fastEndpointForCatalogId as O, MAX_COORDINATOR_PROMPT as S, maxNativePrompt as T, maxReviewerModel as _, MAX_PROFILE_NATIVE_AGENT_NAMES as a, MAX_ADVISOR_SYSTEM_PROMPT as b, formatMaxPrerequisiteFailure as c, maxAdvisorPinIsValid as d, maxCodexReviewerModel as f, maxProReplacementModel as g, maxOpusModel as h, MAX_PROFILE_MODELS as i, stripTrailingOneMSuffix as j, fastEndpointForModel as k, maxAdvisorEffortForModel as l, maxGrokModel as m, MAX_PROFILE_ALLOWED_LEAD_MODEL_IDS as n, MAX_PROFILE_NATIVE_EFFORTS as o, maxGeminiModel as p, MAX_PROFILE_LEAD_MODEL as r, MAX_PROFILE_NATIVE_MODELS as s, MAX_PROFILE_ADVISOR_INSTRUCTIONS as t, maxAdvisorModelFromPin as u, maxSonnetModel as v, maxNativeDescription as w, MAX_COORDINATOR_DESCRIPTION as x, validateMaxProfilePrerequisites as y };
|
|
354
|
+
|
|
355
|
+
//# sourceMappingURL=max-profile-contract-v2Q6eN5w.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"max-profile-contract-v2Q6eN5w.js","names":[],"sources":["../src/lib/model-suffix.ts","../src/lib/fast-endpoint.ts","../src/lib/max-profile-prompts.ts","../src/lib/max-profile-contract.ts"],"sourcesContent":["/**\n * Normalize Claude Code's local 1M-context decoration at model boundaries.\n *\n * `[1m]` is a client-side accounting marker, not part of a Copilot catalog id.\n * Claude Code can append its own marker to a picker value that is already\n * decorated by the router, producing a reachable doubled suffix. Keep the\n * helper dependency-free so launch/profile code and request preprocessing use\n * exactly the same trailing-suffix rule without an import cycle.\n */\nexport interface TrailingOneMSuffix {\n base: string\n hadSuffix: boolean\n}\n\n/** Strip every trailing `[1m]` marker, case-insensitively. */\nexport function stripTrailingOneMSuffix(id: string): TrailingOneMSuffix {\n const match = id.match(/(?:\\[1m\\])+$/i)\n if (!match || match.index === undefined) {\n return { base: id, hadSuffix: false }\n }\n return { base: id.slice(0, match.index), hadSuffix: true }\n}\n\n/** Reapply at most one canonical `[1m]` marker when the input had one. */\nexport function normalizeTrailingOneMSuffix(id: string): string {\n const { base, hadSuffix } = stripTrailingOneMSuffix(id)\n return hadSuffix ? `${base}[1m]` : base\n}\n\n/** Append one marker without ever creating a doubled suffix. */\nexport function withTrailingOneMSuffix(id: string): string {\n const { base } = stripTrailingOneMSuffix(id)\n return `${base}[1m]`\n}\n","import type { Model } from \"~/services/copilot/get-models\"\n\n// Fast endpoint policy is intentionally kept separate from the standard\n// pickEndpoint() resolver. See fastEndpointRequirement below.\n\n/** Endpoint clients used by the fast profile's fixed roster. */\nexport type FastEndpoint = \"chat\" | \"responses\" | \"messages\"\n\nconst ENDPOINTS: Readonly<Record<FastEndpoint, ReadonlySet<string>>> = {\n chat: new Set([\"/chat/completions\", \"/v1/chat/completions\"]),\n responses: new Set([\"/responses\", \"/v1/responses\"]),\n messages: new Set([\"/messages\", \"/v1/messages\"]),\n}\n\n/**\n * Return the endpoint mandated by a fast-profile roster model.\n *\n * This is intentionally independent of the standard `pickEndpoint`: that\n * resolver prefers chat when a catalog entry advertises both clients, while\n * fast roles have a fixed provider contract. Gemini stays on chat; Luna, Sol,\n * and Grok stay on Responses; the Opus Oracle stays on native Messages.\n * Unknown ids return undefined so a fast caller cannot guess a transport.\n */\nexport function fastEndpointRequirement(modelId: string): FastEndpoint | undefined {\n const id = modelId.replace(/(?:\\[1m\\])+$/i, \"\")\n if (id === \"gemini-3.8-flash\") return \"chat\"\n if (id === \"gpt-5.6-luna\" || id === \"gpt-5.6-sol\" || id === \"grok-4.6\") {\n return \"responses\"\n }\n if (id === \"claude-opus-5\" || id === \"claude-sonnet-5\") return \"messages\"\n return undefined\n}\n\n/**\n * Resolve the fixed fast transport only when the catalog explicitly advertises\n * the required endpoint. An entry that advertises both still resolves to the\n * policy endpoint, regardless of advertisement order.\n */\nexport function advertisesEndpoint(\n model: Model | undefined,\n endpoint: FastEndpoint,\n): boolean {\n const advertised = model?.supported_endpoints\n return Array.isArray(advertised)\n && advertised.some((value) => ENDPOINTS[endpoint].has(value))\n}\n\nexport function fastEndpointForModel(model: Model): FastEndpoint | undefined {\n const required = fastEndpointRequirement(model.id)\n if (!required) return undefined\n return advertisesEndpoint(model, required) ? required : undefined\n}\n\n/** Resolve a fast endpoint from a catalog id, without selecting a fallback. */\nexport function fastEndpointForCatalogId(\n modelId: string,\n catalog: ReadonlyArray<Model> | undefined,\n): FastEndpoint | undefined {\n const found = catalog?.find((model) => model.id === modelId)\n return found ? fastEndpointForModel(found) : undefined\n}\n\n/** Human-readable endpoint name for prerequisite diagnostics. */\nexport function fastEndpointLabel(endpoint: FastEndpoint): string {\n return endpoint === \"chat\"\n ? \"Chat Completions\"\n : endpoint === \"responses\"\n ? \"Responses\"\n : \"Messages\"\n}\n","import type { Effort } from \"./reasoning-effort\"\n\nexport const MAX_PARALLELISM_RULE =\n \"When two or more delegated workstreams are independent and non-overlapping, issue them together; sequence them when one needs another's result or their side effects can conflict.\"\n\nexport type MaxNativePromptRole =\n | \"Explore\"\n | \"Plan\"\n | \"general-purpose\"\n | \"implementer\"\n | \"reviewer\"\n | \"brainstorm\"\n\ninterface MaxNativePromptSpec {\n capability: string\n useWhen: string\n notFor: string\n returns: string\n prompt: string\n}\n\nconst MAX_NATIVE_PROMPT_SPECS: Record<MaxNativePromptRole, MaxNativePromptSpec> = {\n Explore: {\n capability: \"read-oriented repository exploration\",\n useWhen: \"the answer requires broad, multi-file or multi-source discovery and the caller needs conclusions rather than raw context\",\n notFor: \"a narrow lookup, implementation planning, or editing\",\n returns: \"concise conclusions, load-bearing file:line evidence, checks or sources consulted, and explicit gaps\",\n prompt: \"Explore the supplied question across the actual repository. Stay within discovery: do not plan the implementation or modify files. Return concise conclusions, load-bearing file:line evidence, checks or sources consulted, and explicit gaps. Stop when the question is supported or the missing evidence is identified. You do not have Advisor or native-agent delegation tools.\",\n },\n Plan: {\n capability: \"implementation planning\",\n useWhen: \"a non-trivial change crosses interfaces, has dependency or migration ordering, preserves important invariants, or needs explicit acceptance criteria\",\n notFor: \"routine decomposition, implementation, approval, or silently deciding unresolved product choices\",\n returns: \"affected files or symbols, ordered implementation slices, invariants, risks, open decisions, acceptance criteria, and runnable verification\",\n prompt: \"Turn the supplied goal, constraints, and evidence into an actionable implementation plan. Return affected files or symbols, ordered implementation slices with real dependencies identified, invariants, risks, open decisions, acceptance criteria, and runnable verification. Surface unresolved product or architecture choices instead of deciding them silently. Stop when another agent can implement the plan without rediscovering its structure; the lead owns acceptance and execution. You do not have Advisor or native-agent delegation tools.\",\n },\n \"general-purpose\": {\n capability: \"bounded mixed investigation and execution\",\n useWhen: \"one owner should carry a multi-step outcome across several narrower kinds of work\",\n notFor: \"a narrow direct action or a task cleanly owned by one specialist\",\n returns: \"the requested outcome, changed artifacts, verification evidence, blockers, and residual risks\",\n prompt: \"Own the supplied bounded outcome end to end. Return the requested outcome, changed artifacts, verification evidence, blockers, and residual risks. Stop at the requested scope and do not absorb adjacent cleanup. Do not re-delegate the core assignment merely to repeat it; any supporting delegation must be independent, non-overlapping, and integrated and verified by you.\",\n },\n implementer: {\n capability: \"bounded coding implementation\",\n useWhen: \"the desired behavior and constraints are settled but the implementation still needs coding judgment\",\n notFor: \"unresolved product behavior, architecture choices, or an unbounded investigation\",\n returns: \"a coherent scoped change, files changed, observable behavior, checks and results, blockers, and unresolved risks\",\n prompt: \"Implement the settled desired behavior within the supplied scope and repository conventions. Return the files changed, observable behavior, checks and results, blockers, and unresolved risks. Stop and report when ambiguity would materially change product behavior, architecture, or scope. Do not re-delegate the core assignment merely to repeat it; any supporting delegation must be independent, non-overlapping, and integrated and verified by you.\",\n },\n reviewer: {\n capability: \"repository-aware verification and reproduction\",\n useWhen: \"an implementation or failure already exists and assessment requires repository navigation, commands, tests, or runtime evidence\",\n notFor: \"a stateless review of an already self-contained artifact or authoring the fix\",\n returns: \"a calibrated verdict, severity-ranked findings, file:line evidence, concrete failure scenarios, checks and results, and unverified areas\",\n prompt: \"Assess the supplied artifact against its intent and the actual repository or runtime state. Return a calibrated verdict, severity-ranked findings, file:line evidence, concrete failure scenarios, checks and results, and unverified areas. Distinguish no findings from checks not run. Do not modify files or act as an approval gate. Stop when material claims have been tested to the available extent; the lead owns remediation and go/no-go. You do not have Advisor or native-agent delegation tools.\",\n },\n brainstorm: {\n capability: \"divergent repository-feasible option generation\",\n useWhen: \"materially different approaches remain credible before implementation planning\",\n notFor: \"a settled approach, proven fact, implementation plan, or code change\",\n returns: \"distinct options, trade-offs, assumptions, failure modes, discriminating evidence, and a recommendation only when supported\",\n prompt: \"Explore the useful design space for the supplied open decision. Return materially distinct repository-feasible options, trade-offs, assumptions, failure modes, discriminating evidence, and a recommendation only when the available evidence supports one. Do not turn the result into an implementation plan or modify files. Stop once the useful alternatives are covered or one option clearly dominates; the lead owns the decision. You do not have Advisor or native-agent delegation tools.\",\n },\n}\n\nexport function maxNativeDescription(\n role: MaxNativePromptRole,\n model: string,\n effort: Effort,\n): string {\n const spec = MAX_NATIVE_PROMPT_SPECS[role]\n return `Max-profile ${spec.capability} subagent running ${model} at ${effort} effort. Use when: ${spec.useWhen}. Not for: ${spec.notFor}. Returns: ${spec.returns}.`\n}\n\nexport function maxNativePrompt(role: MaxNativePromptRole): string {\n return MAX_NATIVE_PROMPT_SPECS[role].prompt\n}\n\nexport const MAX_COORDINATOR_DESCRIPTION =\n \"Max-profile peer-review coordinator running gpt-5.6-luna at maximum effort. Use when: a consequential self-contained plan, design, or diff has at least two distinct unresolved risk lenses for which independent fresh-context review could change the decision. Not for: routine second opinions, repository exploration or execution, facts a focused check can settle, or repeating one generic review across models. Returns: a provenance-preserving synthesis of material findings, disagreements, evidence gaps, and the cheapest checks that can settle them.\"\n\nexport const MAX_COORDINATOR_PROMPT =\n `Coordinate independent fresh-context review of the self-contained artifact and constraints supplied by the caller. You have peer tools only and cannot inspect the repository, transcript, or runtime, so identify missing material instead of guessing. Select the smallest sufficient peer set: use one peer when one lens is enough, and multiple peers only for distinct unresolved risk dimensions. Give every peer a non-overlapping lens; do not send one generic brief to several models or duplicate a same-family lens as a vote. ${MAX_PARALLELISM_RULE} Deduplicate findings while preserving provenance and genuine disagreement. Return severity-ranked material findings, concrete failure scenarios, confidence, evidence gaps, and the cheapest repository check or test that can settle each disagreement. Do not count votes or issue an evidence-free approval. Peer output is advisory; the lead owns go/no-go and remediation.`\n\nexport type MaxPeerKind = \"strategic critic\" | \"line-level reviewer\"\n\nexport interface MaxPeerPromptOptions {\n name: string\n model: string\n kind: MaxPeerKind\n lens: string\n useWhen: string\n notFor: string\n}\n\nexport function maxPeerDescription(opts: MaxPeerPromptOptions): string {\n return `Max-profile ${opts.kind} backed by ${opts.model}. Lens: ${opts.lens}. Use when: ${opts.useWhen}. Not for: ${opts.notFor}. Cold-start: it has no repository or transcript access and sees only the supplied prompt, context, and images. Returns: only material findings, or an explicit no material finding result.`\n}\n\nexport function maxPeerInstructions(opts: MaxPeerPromptOptions): string {\n const locationRule = opts.kind === \"line-level reviewer\"\n ? \"For each finding, cite a location from the supplied artifact, give severity and a concrete failure scenario, and suggest the smallest correction.\"\n : \"For each finding, identify the failed assumption or invariant, its consequence, and the cheapest evidence that would confirm or refute it.\"\n return `You are ${opts.name}, a fresh-context ${opts.kind} running on ${opts.model}. Apply this lens: ${opts.lens}. You have no repository or transcript access; use only the supplied artifact, constraints, and images. If material context is missing, identify it instead of guessing. ${locationRule} Treat supplied locations as citations to the artifact, not proof of repository state. Report only material findings; \"no material finding\" is a valid result. Stop when the requested lens is covered without padding or manufactured objections.`\n}\n\nexport const MAX_ADVISOR_TOOL_INSTRUCTIONS = `# Advisor Tool\n\nYou have access to an optional, primary-lead-only, transcript-aware Max Advisor. Transcript awareness makes it useful for detecting framing drift, changed assumptions, and a stuck strategy; it is not an independent repository verifier, supervisor, approver, workflow gate, or substitute for your own reasoning. You keep decision ownership.\n\nUse it for one precise consequential uncertainty that remains after proportionate direct investigation and cannot be settled by repository evidence, a focused command or test, Plan, reviewer, or a fresh-context peer. State the question, relevant evidence, credible alternatives, and what evidence would change the decision. Evidence-first does not require invoking every role before Advisor.\n\nDo not call it for initial investigation, routine progress, waiting, ordinary verification, planner approval, reviewer confirmation, reassurance, or completion ceremony. Treat its result as advice, not authority. Consult again only when materially new or conflicting evidence creates a different question.`\n\nexport const MAX_ADVISOR_SYSTEM_PROMPT =\n \"You are a non-binding, transcript-aware consultant to the primary lead. Answer the stated consequential question first, then give your recommendation and confidence, the transcript evidence and assumptions supporting it, the material risk, one credible alternative, and the evidence that would reverse your recommendation. The transcript may anchor you to the lead's framing, so identify any framing or assumption the session has stopped questioning. Stop after answering the focused question. Do not supervise, approve, veto, or redesign unrelated work; the lead weighs your advice against the user's intent and verified repository evidence.\"\n","import type { Model, ModelsResponse } from \"~/services/copilot/get-models\"\nimport type { Effort } from \"./reasoning-effort\"\nimport {\n advertisesEndpoint,\n fastEndpointForModel,\n} from \"./fast-endpoint\"\nimport { MAX_ADVISOR_TOOL_INSTRUCTIONS } from \"./max-profile-prompts\"\nimport { stripTrailingOneMSuffix } from \"./model-suffix\"\nimport { state } from \"./state\"\n\n// Max uses the same context threshold as Claude Code's `[1m]` accounting.\nexport const MAX_REQUIRED_CONTEXT_TOKENS = 1_000_000\n\nconst ONE_M_TOKENS = MAX_REQUIRED_CONTEXT_TOKENS\n\nfunction catalogModels(): Array<Model> {\n return state.models?.data ?? []\n}\n\nfunction catalogModel(id: string): Model | undefined {\n return catalogModels().find((model) => model.id === id)\n}\n\n\nexport const MAX_PROFILE_MODELS = Object.freeze({\n sol: \"gpt-5.6-sol\",\n luna: \"gpt-5.6-luna\",\n gemini: \"gemini-3.8-flash\",\n grok: \"grok-4.6\",\n opus: \"claude-opus-5\",\n sonnet: \"claude-sonnet-5\",\n codex: \"gpt-5.3-codex\",\n} as const)\n\nexport const MAX_PROFILE_NATIVE_AGENT_NAMES = [\n \"Explore\",\n \"Plan\",\n \"general-purpose\",\n \"implementer\",\n \"reviewer\",\n \"brainstorm\",\n \"peer-review-coordinator\",\n] as const\n\nexport type MaxProfileNativeAgentName =\n (typeof MAX_PROFILE_NATIVE_AGENT_NAMES)[number]\n\nexport const MAX_PROFILE_NATIVE_EFFORTS = Object.freeze({\n Explore: \"high\",\n Plan: \"high\",\n \"general-purpose\": \"max\",\n implementer: \"high\",\n reviewer: \"xhigh\",\n brainstorm: \"high\",\n \"peer-review-coordinator\": \"max\",\n} as const satisfies Record<MaxProfileNativeAgentName, Effort>)\n\n/** Default model family behind each native role's frontmatter. */\nexport const MAX_PROFILE_NATIVE_MODELS = Object.freeze({\n Explore: MAX_PROFILE_MODELS.luna,\n Plan: MAX_PROFILE_MODELS.sol,\n \"general-purpose\": MAX_PROFILE_MODELS.luna,\n implementer: MAX_PROFILE_MODELS.gemini,\n reviewer: MAX_PROFILE_MODELS.sonnet,\n brainstorm: MAX_PROFILE_MODELS.opus,\n \"peer-review-coordinator\": MAX_PROFILE_MODELS.luna,\n} as const satisfies Record<MaxProfileNativeAgentName, string>)\n\nexport const MAX_PROFILE_LEAD_MODEL = MAX_PROFILE_MODELS.sol\nexport const MAX_PROFILE_ADVISOR_MODEL = MAX_PROFILE_MODELS.opus\nexport const MAX_PROFILE_ADVISOR_EFFORT = \"high\" as const\nexport const MAX_PROFILE_ADVISOR_INSTRUCTIONS = MAX_ADVISOR_TOOL_INSTRUCTIONS\n\nexport function maxAdvisorModelFromPin(pinned: string | undefined, opusModel?: string): string {\n const trimmed = pinned?.trim()\n const base = trimmed ? stripTrailingOneMSuffix(trimmed).base : undefined\n if (base === MAX_PROFILE_MODELS.sol || base === MAX_PROFILE_MODELS.opus) {\n return base\n }\n return opusModel ?? MAX_PROFILE_MODELS.opus\n}\n\nexport function maxAdvisorPinIsValid(pinned: string | undefined): boolean {\n const trimmed = pinned?.trim()\n const base = trimmed ? stripTrailingOneMSuffix(trimmed).base : trimmed\n return base === undefined\n || base === \"\"\n || base === MAX_PROFILE_MODELS.sol\n || base === MAX_PROFILE_MODELS.opus\n}\n\nexport function maxAdvisorModelFromPinStrict(pinned: string | undefined, opusModel?: string): string {\n if (!maxAdvisorPinIsValid(pinned)) return opusModel ?? MAX_PROFILE_MODELS.opus\n return maxAdvisorModelFromPin(pinned, opusModel)\n}\n\nexport function maxStandInAvailable(): boolean {\n return usableSol(catalogModel(MAX_PROFILE_MODELS.sol))\n && maxOpusModel() !== undefined\n && (maxGrokHighModel() !== undefined || maxGeminiModel() !== undefined)\n}\nexport function maxAdvisorEffortForModel(_model: string): Effort {\n return MAX_PROFILE_ADVISOR_EFFORT\n}\n\nexport const MAX_PROFILE_NATIVE_MODEL_IDS = Object.freeze([\n MAX_PROFILE_MODELS.luna,\n MAX_PROFILE_MODELS.gemini,\n MAX_PROFILE_MODELS.grok,\n] as const)\n\nexport const MAX_PROFILE_ALLOWED_LEAD_MODEL_IDS = Object.freeze([\n MAX_PROFILE_MODELS.sol,\n MAX_PROFILE_MODELS.luna,\n MAX_PROFILE_MODELS.gemini,\n MAX_PROFILE_MODELS.opus,\n] as const)\n\nexport type MaxProfileAllowedLeadModel =\n (typeof MAX_PROFILE_ALLOWED_LEAD_MODEL_IDS)[number]\n\nexport interface MaxProfilePrerequisiteCheck {\n ok: boolean\n missing: ReadonlyArray<string>\n /** Resolved optional/third-lab assignments for the launch. */\n models: {\n sol?: Model\n luna?: Model\n gemini?: Model\n grok?: Model\n opus?: Model\n sonnet?: Model\n thirdLab?: \"gemini\" | \"grok\"\n }\n}\n\nfunction findModel(\n catalog: ModelsResponse | undefined,\n id: string,\n): Model | undefined {\n return catalog?.data?.find((model) => model.id === id)\n}\n\nfunction hasToolCalls(model: Model | undefined): boolean {\n return model?.capabilities?.supports?.tool_calls === true\n}\n\nfunction hasContextAtLeast(model: Model | undefined, tokens: number): boolean {\n return (model?.capabilities?.limits?.max_context_window_tokens ?? 0) >= tokens\n}\n\nfunction supportsEffort(model: Model | undefined, effort: Effort): boolean {\n const ladder = model?.capabilities?.supports?.reasoning_effort\n return Array.isArray(ladder) && ladder.includes(effort)\n}\n\nfunction hasUsableLimits(model: Model | undefined): boolean {\n const limits = model?.capabilities?.limits\n const prompt = limits?.max_prompt_tokens\n const output = limits?.max_output_tokens\n return (\n typeof prompt === \"number\"\n && Number.isFinite(prompt)\n && prompt > 0\n && typeof output === \"number\"\n && Number.isFinite(output)\n && output > 0\n && (limits?.max_context_window_tokens ?? 0) >= prompt\n )\n}\n\nfunction supportsEndpoint(\n model: Model | undefined,\n endpoint: \"chat\" | \"responses\" | \"messages\",\n): boolean {\n return model !== undefined && fastEndpointForModel(model) === endpoint\n}\n\nfunction validateRequiredModel(\n model: Model | undefined,\n id: string,\n requirements: ReadonlyArray<[string, boolean]>,\n missing: string[],\n): void {\n if (!model) {\n missing.push(`${id}: absent from the live catalog`)\n return\n }\n for (const [message, ok] of requirements) {\n if (!ok) missing.push(`${id}: ${message}`)\n }\n}\n\nfunction usableSol(model: Model | undefined): boolean {\n return Boolean(\n model\n && hasToolCalls(model)\n && hasContextAtLeast(model, ONE_M_TOKENS)\n && supportsEffort(model, \"high\")\n && supportsEndpoint(model, \"responses\")\n && hasUsableLimits(model)\n )\n}\n\nfunction usableGemini(model: Model | undefined): boolean {\n return Boolean(\n model\n && hasToolCalls(model)\n && hasContextAtLeast(model, ONE_M_TOKENS)\n && supportsEffort(model, \"high\")\n && supportsEndpoint(model, \"chat\")\n && hasUsableLimits(model),\n )\n}\n\nfunction usableGrok(model: Model | undefined): boolean {\n return Boolean(\n model\n && hasToolCalls(model)\n && supportsEffort(model, \"medium\")\n && supportsEndpoint(model, \"responses\")\n && hasUsableLimits(model),\n )\n}\n\nfunction usableGrokReviewer(model: Model | undefined): boolean {\n return Boolean(\n usableGrok(model)\n && supportsEffort(model, \"high\")\n && (model?.capabilities?.limits?.max_prompt_tokens ?? 0) >= 200_000,\n )\n}\n\n/**\n * Validate the fixed prerequisites for the raw `-m max` launch.\n *\n * Max is a deliberately strong, closed profile. Its lead, planning,\n * implementation, repository-review, brainstorm, and transcript-aware Advisor\n * paths must all be present before any runtime artifact is written: Sol, Luna,\n * Gemini 3.8 Flash, Sonnet 5, and Opus 5 are mandatory. Grok 4.6 is optional;\n * when present it supplies additional peer critic/reviewer coverage and the\n * preferred third-lab stand-in slot, but it is never a max lead and its sub-1M\n * context must remain undecorated.\n */\nexport function validateMaxProfilePrerequisites(\n catalog: ModelsResponse | undefined,\n): MaxProfilePrerequisiteCheck {\n const missing: string[] = []\n const sol = findModel(catalog, MAX_PROFILE_MODELS.sol)\n const luna = findModel(catalog, MAX_PROFILE_MODELS.luna)\n const gemini = findModel(catalog, MAX_PROFILE_MODELS.gemini)\n const grok = findModel(catalog, MAX_PROFILE_MODELS.grok)\n const opus = findModel(catalog, MAX_PROFILE_MODELS.opus)\n const sonnet = findModel(catalog, MAX_PROFILE_MODELS.sonnet)\n\n validateRequiredModel(\n sol,\n MAX_PROFILE_MODELS.sol,\n [\n [\"does not advertise tool_calls\", hasToolCalls(sol)],\n [\"advertised context window is below 1M\", hasContextAtLeast(sol, ONE_M_TOKENS)],\n [\"does not advertise a high reasoning effort\", supportsEffort(sol, \"high\")],\n [\"does not advertise a supported Responses endpoint\", supportsEndpoint(sol, \"responses\")],\n [\"has no usable max_prompt_tokens/max_output_tokens limits\", hasUsableLimits(sol)],\n ],\n missing,\n )\n validateRequiredModel(\n luna,\n MAX_PROFILE_MODELS.luna,\n [\n [\"does not advertise tool_calls\", hasToolCalls(luna)],\n [\"advertised context window is below 1M\", hasContextAtLeast(luna, ONE_M_TOKENS)],\n [\"does not advertise a high reasoning effort\", supportsEffort(luna, \"high\")],\n [\"does not advertise a max reasoning effort\", supportsEffort(luna, \"max\")],\n [\"does not advertise a supported Responses endpoint\", supportsEndpoint(luna, \"responses\")],\n [\"has no usable max_prompt_tokens/max_output_tokens limits\", hasUsableLimits(luna)],\n ],\n missing,\n )\n validateRequiredModel(\n gemini,\n MAX_PROFILE_MODELS.gemini,\n [\n [\"does not advertise tool_calls\", hasToolCalls(gemini)],\n [\"advertised context window is below 1M\", hasContextAtLeast(gemini, ONE_M_TOKENS)],\n [\"does not advertise a high reasoning effort\", supportsEffort(gemini, \"high\")],\n [\"does not advertise a supported Chat Completions endpoint\", supportsEndpoint(gemini, \"chat\")],\n [\"has no usable max_prompt_tokens/max_output_tokens limits\", hasUsableLimits(gemini)],\n ],\n missing,\n )\n validateRequiredModel(\n opus,\n MAX_PROFILE_MODELS.opus,\n [\n [\"does not advertise tool_calls\", hasToolCalls(opus)],\n [\"advertised context window is below 1M\", hasContextAtLeast(opus, ONE_M_TOKENS)],\n [\"does not advertise adaptive_thinking\", opus?.capabilities?.supports?.adaptive_thinking === true],\n [\"does not advertise a high reasoning effort\", supportsEffort(opus, \"high\")],\n [\"does not advertise a supported Messages endpoint\", supportsEndpoint(opus, \"messages\")],\n [\"has no usable max_prompt_tokens/max_output_tokens limits\", hasUsableLimits(opus)],\n ],\n missing,\n )\n validateRequiredModel(\n sonnet,\n MAX_PROFILE_MODELS.sonnet,\n [\n [\"does not advertise tool_calls\", hasToolCalls(sonnet)],\n [\"advertised context window is below 1M\", hasContextAtLeast(sonnet, ONE_M_TOKENS)],\n [\"does not advertise adaptive_thinking\", sonnet?.capabilities?.supports?.adaptive_thinking === true],\n [\"does not advertise an xhigh reasoning effort\", supportsEffort(sonnet, \"xhigh\")],\n [\"does not advertise a supported Messages endpoint\", supportsEndpoint(sonnet, \"messages\")],\n [\"has no usable max_prompt_tokens/max_output_tokens limits\", hasUsableLimits(sonnet)],\n ],\n missing,\n )\n\n // Grok is intentionally optional. A malformed optional entry is simply\n // omitted from the max projection; it must never make launch fail or be\n // decorated as a 1M model.\n const geminiUsable = usableGemini(gemini)\n const grokUsable = usableGrok(grok)\n\n return {\n ok: missing.length === 0,\n missing,\n models: {\n sol: sol && !missing.some((entry) => entry.startsWith(`${MAX_PROFILE_MODELS.sol}:`)) ? sol : undefined,\n luna: luna && !missing.some((entry) => entry.startsWith(`${MAX_PROFILE_MODELS.luna}:`)) ? luna : undefined,\n gemini: geminiUsable ? gemini : undefined,\n grok: grokUsable ? grok : undefined,\n opus: opus && !missing.some((entry) => entry.startsWith(`${MAX_PROFILE_MODELS.opus}:`)) ? opus : undefined,\n sonnet: sonnet && !missing.some((entry) => entry.startsWith(`${MAX_PROFILE_MODELS.sonnet}:`)) ? sonnet : undefined,\n thirdLab: grokUsable && supportsEffort(grok, \"high\")\n ? \"grok\"\n : geminiUsable\n ? \"gemini\"\n : undefined,\n },\n }\n}\n\nexport function formatMaxPrerequisiteFailure(\n missing: ReadonlyArray<string>,\n): string {\n return (\n \"github-router claude -m max requires the following live-catalog capabilities, \"\n + \"which this account's catalog does not fully provide:\\n\"\n + missing.map((entry) => ` - ${entry}`).join(\"\\n\")\n + \"\\n\\nMax launches do not fall back to arbitrary older models. \"\n + \"Use plain `github-router claude` for the standard profile.\"\n )\n}\n\nexport function maxModelIsOneM(\n model: Model | undefined,\n): boolean {\n return (\n (model?.capabilities?.limits?.max_context_window_tokens ?? 0) >= ONE_M_TOKENS\n )\n}\n\nexport function maxModelSupportsEffort(\n model: Model | undefined,\n effort: Effort,\n): boolean {\n return supportsEffort(model, effort)\n}\n\nexport function maxModelHasUsableLimits(model: Model | undefined): boolean {\n return hasUsableLimits(model)\n}\n\nexport function maxThirdLabModel(): string | undefined {\n const gemini = catalogModel(MAX_PROFILE_MODELS.gemini)\n if (usableGemini(gemini)) return MAX_PROFILE_MODELS.gemini\n const grok = catalogModel(MAX_PROFILE_MODELS.grok)\n return usableGrok(grok) ? MAX_PROFILE_MODELS.grok : undefined\n}\n\nexport function maxGeminiModel(): string | undefined {\n const model = catalogModel(MAX_PROFILE_MODELS.gemini)\n return model && usableGemini(model) ? model.id : undefined\n}\n\nexport function maxGrokModel(): string | undefined {\n const model = catalogModel(MAX_PROFILE_MODELS.grok)\n return model && usableGrok(model) ? model.id : undefined\n}\n\n/** Grok replacement for max-profile surfaces that require high effort. */\nexport function maxGrokHighModel(): string | undefined {\n const model = catalogModel(MAX_PROFILE_MODELS.grok)\n return model && usableGrokReviewer(model) ? model.id : undefined\n}\n\n/** Max-only replacement for any standard Gemini Pro assignment. */\nexport function maxProReplacementModel():\n | typeof MAX_PROFILE_MODELS.grok\n | typeof MAX_PROFILE_MODELS.gemini\n | undefined {\n if (maxGrokHighModel()) return MAX_PROFILE_MODELS.grok\n if (maxGeminiModel()) return MAX_PROFILE_MODELS.gemini\n return undefined\n}\n\nexport function maxOpusModel(): string | undefined {\n const model = catalogModel(MAX_PROFILE_MODELS.opus)\n return model && hasContextAtLeast(model, ONE_M_TOKENS)\n && model.capabilities?.supports?.adaptive_thinking === true\n && supportsEffort(model, \"high\")\n && supportsEndpoint(model, \"messages\")\n && hasUsableLimits(model)\n ? model.id\n : undefined\n}\n\nexport function maxLunaMaxModel(): string | undefined {\n const model = catalogModel(MAX_PROFILE_MODELS.luna)\n return model\n && hasToolCalls(model)\n && hasContextAtLeast(model, ONE_M_TOKENS)\n && supportsEffort(model, \"max\")\n && supportsEndpoint(model, \"responses\")\n && hasUsableLimits(model)\n ? model.id\n : undefined\n}\n\nexport function maxSonnetModel(): string | undefined {\n const model = catalogModel(MAX_PROFILE_MODELS.sonnet)\n return model && hasContextAtLeast(model, ONE_M_TOKENS)\n && model.capabilities?.supports?.tool_calls === true\n && model.capabilities?.supports?.adaptive_thinking === true\n && supportsEffort(model, \"xhigh\")\n && supportsEndpoint(model, \"messages\")\n && hasUsableLimits(model)\n ? model.id\n : undefined\n}\n\nexport function maxReviewerModel(): string | undefined {\n return maxSonnetModel()\n}\n\nexport function maxCodexReviewerModel(): string | undefined {\n const model = catalogModel(MAX_PROFILE_MODELS.codex)\n return model && hasToolCalls(model)\n && supportsEffort(model, \"xhigh\")\n && advertisesEndpoint(model, \"responses\")\n && hasUsableLimits(model)\n && (model.capabilities?.limits?.max_prompt_tokens ?? 0) >= 200_000\n ? model.id\n : undefined\n}\n\nexport function maxCatalogModel(id: string): Model | undefined {\n return catalogModel(id)\n}\n\nexport function maxCatalogModels(): ReadonlyArray<Model> {\n return catalogModels()\n}"],"mappings":"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"}
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { t as buildSelfCommand } from "./self-invocation-
|
|
1
|
+
import { t as buildSelfCommand } from "./self-invocation-B84JCHps.js";
|
|
2
2
|
//#region src/lib/mcp-workspace-header.ts
|
|
3
3
|
/** Header the per-session MCP headersHelper emits, carrying the calling Claude
|
|
4
4
|
* session's working directory. The /mcp handler uses it as the default
|
|
@@ -17,4 +17,4 @@ function buildWorkspaceHeaderHelperCommand(invocation) {
|
|
|
17
17
|
//#endregion
|
|
18
18
|
export { buildWorkspaceHeaderHelperCommand as n, buildWorkspaceHeaderJson as r, MCP_WORKSPACE_HEADER as t };
|
|
19
19
|
|
|
20
|
-
//# sourceMappingURL=mcp-workspace-header-
|
|
20
|
+
//# sourceMappingURL=mcp-workspace-header-B60WSR1Y.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"mcp-workspace-header-
|
|
1
|
+
{"version":3,"file":"mcp-workspace-header-B60WSR1Y.js","names":[],"sources":["../src/lib/mcp-workspace-header.ts"],"sourcesContent":["import { buildSelfCommand, type SelfInvocation } from \"./hook-launcher/self-invocation\"\n\n/** Header the per-session MCP headersHelper emits, carrying the calling Claude\n * session's working directory. The /mcp handler uses it as the default\n * `workspace` for repo-scoped tools so a machine-wide `serve` targets the\n * active repo, not the proxy launch cwd. */\nexport const MCP_WORKSPACE_HEADER = \"X-GH-Workspace\"\n\n/** stdout JSON the headersHelper prints; Claude merges it into the connection\n * headers. `cwd` is the helper's own process cwd = the session's project dir. */\nexport function buildWorkspaceHeaderJson(cwd: string): string {\n return JSON.stringify({ [MCP_WORKSPACE_HEADER]: cwd })\n}\n\n/** Command string Claude runs as the headersHelper. */\nexport function buildWorkspaceHeaderHelperCommand(invocation: SelfInvocation): string {\n return buildSelfCommand(invocation, \"internal-workspace-header\")\n}\n"],"mappings":";;;;;;AAMA,MAAa,uBAAuB;;;AAIpC,SAAgB,yBAAyB,KAAqB;CAC5D,OAAO,KAAK,UAAU,GAAG,uBAAuB,IAAI,CAAC;AACvD;;AAGA,SAAgB,kCAAkC,YAAoC;CACpF,OAAO,iBAAiB,YAAY,2BAA2B;AACjE"}
|
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import { i as ensurePaths } from "./paths-
|
|
2
|
-
import { p as getModels, r as setupGitHubToken, t as setupCopilotToken } from "./token-
|
|
1
|
+
import { i as ensurePaths } from "./paths-De1Qh9Q9.js";
|
|
2
|
+
import { p as getModels, r as setupGitHubToken, t as setupCopilotToken } from "./token-CCg-Ov5q.js";
|
|
3
3
|
import { defineCommand } from "citty";
|
|
4
4
|
import consola from "consola";
|
|
5
5
|
//#region src/models.ts
|
|
@@ -160,4 +160,4 @@ function formatTokens(n) {
|
|
|
160
160
|
//#endregion
|
|
161
161
|
export { models };
|
|
162
162
|
|
|
163
|
-
//# sourceMappingURL=models-
|
|
163
|
+
//# sourceMappingURL=models-COuMOfM6.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"models-BDhlItXr.js","names":[],"sources":["../src/models.ts"],"sourcesContent":["import { defineCommand } from \"citty\"\nimport consola from \"consola\"\n\nimport { ensurePaths } from \"./lib/paths\"\nimport { setupCopilotToken, setupGitHubToken, type StopCopilotTokenRefresh } from \"./lib/token\"\nimport { getModels, type Model } from \"./services/copilot/get-models\"\n\nexport const models = defineCommand({\n meta: {\n name: \"models\",\n description:\n \"List available GitHub Copilot models and their capabilities. Pass an optional pattern to filter (case-insensitive substring match on id, name, vendor, family).\",\n },\n args: {\n pattern: {\n type: \"positional\",\n required: false,\n description:\n \"Substring to filter models by (matches id, name, vendor, or family).\",\n },\n json: {\n type: \"boolean\",\n default: false,\n description: \"Emit raw JSON instead of the pretty layout.\",\n },\n },\n async run({ args }) {\n await ensurePaths()\n await setupGitHubToken()\n // One-shot command: stop the background refresh loop before returning, so\n // the timer is never what decides whether this process exits. (It is also\n // `unref()`d, so this is belt-and-braces — but ownership stays explicit.)\n let stopRefresh: StopCopilotTokenRefresh | undefined\n try {\n stopRefresh = await setupCopilotToken()\n } catch (err) {\n consola.error(\"Failed to obtain Copilot token:\", err)\n process.exit(1)\n }\n\n try {\n let catalog: Awaited<ReturnType<typeof getModels>>\n try {\n catalog = await getModels()\n } catch (err) {\n consola.error(\"Failed to fetch Copilot model catalog:\", err)\n process.exit(1)\n }\n\n const all = catalog.data\n const pattern = args.pattern?.toString().trim()\n const filtered = pattern ? filterModels(all, pattern) : all\n\n if (args.json) {\n process.stdout.write(`${JSON.stringify(filtered, null, 2)}\\n`)\n return\n }\n\n if (filtered.length === 0) {\n consola.warn(\n `No models matched \"${pattern}\". ${all.length} models available — try a different substring or run without an argument to list everything.`,\n )\n process.exit(1)\n }\n\n const grouped = groupByVendor(filtered)\n const lines: Array<string> = []\n const header = pattern\n ? `${filtered.length}/${all.length} models match \"${pattern}\"`\n : `${all.length} models available`\n lines.push(header)\n lines.push(\"\")\n for (const [vendor, list] of grouped) {\n lines.push(`▾ ${vendor} (${list.length})`)\n for (const model of list) {\n lines.push(...formatModel(model))\n }\n lines.push(\"\")\n }\n process.stdout.write(lines.join(\"\\n\"))\n } finally {\n stopRefresh?.()\n }\n },\n})\n\nfunction filterModels(models: Array<Model>, pattern: string): Array<Model> {\n const needle = pattern.toLowerCase()\n return models.filter((m) => {\n const haystack = [\n m.id,\n m.name,\n m.vendor,\n m.capabilities.family,\n m.capabilities.type,\n m.model_picker_category ?? \"\",\n ]\n .join(\" \")\n .toLowerCase()\n return haystack.includes(needle)\n })\n}\n\nfunction groupByVendor(models: Array<Model>): Array<[string, Array<Model>]> {\n const map = new Map<string, Array<Model>>()\n for (const m of models) {\n const key = m.vendor || \"(unknown vendor)\"\n const bucket = map.get(key)\n if (bucket) bucket.push(m)\n else map.set(key, [m])\n }\n // Stable vendor order: alphabetical for predictability.\n return [...map.entries()].sort(([a], [b]) => a.localeCompare(b))\n}\n\n/**\n * Test-only exports. Not part of the public CLI surface — kept out of\n * the default export so they don't show up in IDE autocomplete on\n * `import { ... } from \"github-router/models\"` consumers.\n */\nexport const __testing = { filterModels, groupByVendor, formatModel, formatTokens }\n\nfunction formatModel(model: Model): Array<string> {\n const lines: Array<string> = []\n const tags: Array<string> = []\n if (model.preview) tags.push(\"preview\")\n if (model.is_chat_default) tags.push(\"chat-default\")\n if (model.is_chat_fallback) tags.push(\"chat-fallback\")\n if (model.billing?.is_premium) tags.push(\"premium\")\n if (model.billing?.restricted_to?.length) {\n tags.push(`restricted:${model.billing.restricted_to.join(\"/\")}`)\n }\n if (model.policy && model.policy.state !== \"enabled\") {\n tags.push(`policy:${model.policy.state}`)\n }\n const tagStr = tags.length > 0 ? ` [${tags.join(\", \")}]` : \"\"\n lines.push(` • ${model.id}${tagStr}`)\n if (model.name && model.name !== model.id) {\n lines.push(` name: ${model.name}`)\n }\n const meta: Array<string> = [\n `family: ${model.capabilities.family}`,\n `type: ${model.capabilities.type}`,\n ]\n if (model.capabilities.tokenizer) {\n meta.push(`tokenizer: ${model.capabilities.tokenizer}`)\n }\n if (model.version) {\n meta.push(`version: ${model.version}`)\n }\n lines.push(` ${meta.join(\" · \")}`)\n\n const limits = model.capabilities.limits\n const limitParts: Array<string> = []\n if (limits) {\n if (limits.max_context_window_tokens) {\n limitParts.push(`ctx ${formatTokens(limits.max_context_window_tokens)}`)\n } else if (limits.max_prompt_tokens) {\n limitParts.push(`prompt ${formatTokens(limits.max_prompt_tokens)}`)\n }\n if (limits.max_output_tokens) {\n limitParts.push(`out ${formatTokens(limits.max_output_tokens)}`)\n }\n if (\n limits.max_non_streaming_output_tokens\n && limits.max_non_streaming_output_tokens !== limits.max_output_tokens\n ) {\n limitParts.push(\n `out-non-stream ${formatTokens(limits.max_non_streaming_output_tokens)}`,\n )\n }\n if (limits.max_inputs) limitParts.push(`inputs ${limits.max_inputs}`)\n if (limits.vision?.max_prompt_images) {\n limitParts.push(`images ${limits.vision.max_prompt_images}`)\n }\n }\n if (limitParts.length > 0) {\n lines.push(` limits: ${limitParts.join(\" · \")}`)\n }\n\n const supports = model.capabilities.supports\n const supportFlags: Array<string> = []\n if (supports) {\n if (supports.tool_calls) supportFlags.push(\"tools\")\n if (supports.parallel_tool_calls) supportFlags.push(\"parallel-tools\")\n if (supports.streaming) supportFlags.push(\"streaming\")\n if (supports.vision) supportFlags.push(\"vision\")\n if (supports.structured_outputs) supportFlags.push(\"structured-outputs\")\n if (supports.dimensions) supportFlags.push(\"dimensions\")\n if (supports.adaptive_thinking) {\n const min = supports.min_thinking_budget\n const max = supports.max_thinking_budget\n const range\n = min !== undefined && max !== undefined\n ? `(${formatTokens(min)}-${formatTokens(max)})`\n : \"\"\n supportFlags.push(`adaptive-thinking${range}`)\n }\n if (supports.reasoning_effort && supports.reasoning_effort.length > 0) {\n supportFlags.push(`reasoning:${supports.reasoning_effort.join(\"/\")}`)\n }\n }\n if (supportFlags.length > 0) {\n lines.push(` supports: ${supportFlags.join(\", \")}`)\n }\n\n if (model.supported_endpoints && model.supported_endpoints.length > 0) {\n lines.push(` endpoints: ${model.supported_endpoints.join(\", \")}`)\n }\n if (model.billing) {\n const billParts: Array<string> = []\n if (model.billing.is_premium) billParts.push(\"premium\")\n if (typeof model.billing.multiplier === \"number\") {\n billParts.push(`×${model.billing.multiplier}`)\n }\n if (billParts.length > 0) {\n lines.push(` billing: ${billParts.join(\" \")}`)\n }\n }\n return lines\n}\n\n/**\n * Format a token count in a compact human-readable form: `1024` →\n * `1k`, `4096` → `4k`, `131072` → `128k`, `1048576` → `1M`. Prefer\n * binary multiples (mebi, kibi) since Claude Code / Copilot context\n * windows are reported in binary units (`1M context` = 1024 × 1024\n * tokens). Fall back to decimal (`64k` for `64000`) when the value\n * is a clean decimal multiple but not binary.\n */\nfunction formatTokens(n: number): string {\n if (n >= 1_048_576 && n % 1_048_576 === 0) return `${n / 1_048_576}M`\n if (n >= 1024 && n % 1024 === 0) return `${n / 1024}k`\n if (n >= 1_000_000 && n % 1_000_000 === 0) return `${n / 1_000_000}M`\n if (n >= 1000 && n % 1000 === 0) return `${n / 1000}k`\n return `${n}`\n}\n"],"mappings":";;;;;AAOA,MAAa,SAAS,cAAc;CAClC,MAAM;EACJ,MAAM;EACN,aACE;CACJ;CACA,MAAM;EACJ,SAAS;GACP,MAAM;GACN,UAAU;GACV,aACE;EACJ;EACA,MAAM;GACJ,MAAM;GACN,SAAS;GACT,aAAa;EACf;CACF;CACA,MAAM,IAAI,EAAE,QAAQ;EAClB,MAAM,YAAY;EAClB,MAAM,iBAAiB;EAIvB,IAAI;EACJ,IAAI;GACF,cAAc,MAAM,kBAAkB;EACxC,SAAS,KAAK;GACZ,QAAQ,MAAM,mCAAmC,GAAG;GACpD,QAAQ,KAAK,CAAC;EAChB;EAEA,IAAI;GACF,IAAI;GACJ,IAAI;IACF,UAAU,MAAM,UAAU;GAC5B,SAAS,KAAK;IACZ,QAAQ,MAAM,0CAA0C,GAAG;IAC3D,QAAQ,KAAK,CAAC;GAChB;GAEA,MAAM,MAAM,QAAQ;GACpB,MAAM,UAAU,KAAK,SAAS,SAAS,CAAC,CAAC,KAAK;GAC9C,MAAM,WAAW,UAAU,aAAa,KAAK,OAAO,IAAI;GAExD,IAAI,KAAK,MAAM;IACb,QAAQ,OAAO,MAAM,GAAG,KAAK,UAAU,UAAU,MAAM,CAAC,EAAE,GAAG;IAC7D;GACF;GAEA,IAAI,SAAS,WAAW,GAAG;IACzB,QAAQ,KACN,sBAAsB,QAAQ,KAAK,IAAI,OAAO,6FAChD;IACA,QAAQ,KAAK,CAAC;GAChB;GAEA,MAAM,UAAU,cAAc,QAAQ;GACtC,MAAM,QAAuB,CAAC;GAC9B,MAAM,SAAS,UACX,GAAG,SAAS,OAAO,GAAG,IAAI,OAAO,iBAAiB,QAAQ,KAC1D,GAAG,IAAI,OAAO;GAClB,MAAM,KAAK,MAAM;GACjB,MAAM,KAAK,EAAE;GACb,KAAK,MAAM,CAAC,QAAQ,SAAS,SAAS;IACpC,MAAM,KAAK,KAAK,OAAO,IAAI,KAAK,OAAO,EAAE;IACzC,KAAK,MAAM,SAAS,MAClB,MAAM,KAAK,GAAG,YAAY,KAAK,CAAC;IAElC,MAAM,KAAK,EAAE;GACf;GACA,QAAQ,OAAO,MAAM,MAAM,KAAK,IAAI,CAAC;EACvC,UAAU;GACR,cAAc;EAChB;CACF;AACF,CAAC;AAED,SAAS,aAAa,QAAsB,SAA+B;CACzE,MAAM,SAAS,QAAQ,YAAY;CACnC,OAAO,OAAO,QAAQ,MAAM;EAW1B,OAViB;GACf,EAAE;GACF,EAAE;GACF,EAAE;GACF,EAAE,aAAa;GACf,EAAE,aAAa;GACf,EAAE,yBAAyB;EAC7B,CAAC,CACE,KAAK,GAAG,CAAC,CACT,YACW,CAAC,CAAC,SAAS,MAAM;CACjC,CAAC;AACH;AAEA,SAAS,cAAc,QAAqD;CAC1E,MAAM,sBAAM,IAAI,IAA0B;CAC1C,KAAK,MAAM,KAAK,QAAQ;EACtB,MAAM,MAAM,EAAE,UAAU;EACxB,MAAM,SAAS,IAAI,IAAI,GAAG;EAC1B,IAAI,QAAQ,OAAO,KAAK,CAAC;OACpB,IAAI,IAAI,KAAK,CAAC,CAAC,CAAC;CACvB;CAEA,OAAO,CAAC,GAAG,IAAI,QAAQ,CAAC,CAAC,CAAC,MAAM,CAAC,IAAI,CAAC,OAAO,EAAE,cAAc,CAAC,CAAC;AACjE;AASA,SAAS,YAAY,OAA6B;CAChD,MAAM,QAAuB,CAAC;CAC9B,MAAM,OAAsB,CAAC;CAC7B,IAAI,MAAM,SAAS,KAAK,KAAK,SAAS;CACtC,IAAI,MAAM,iBAAiB,KAAK,KAAK,cAAc;CACnD,IAAI,MAAM,kBAAkB,KAAK,KAAK,eAAe;CACrD,IAAI,MAAM,SAAS,YAAY,KAAK,KAAK,SAAS;CAClD,IAAI,MAAM,SAAS,eAAe,QAChC,KAAK,KAAK,cAAc,MAAM,QAAQ,cAAc,KAAK,GAAG,GAAG;CAEjE,IAAI,MAAM,UAAU,MAAM,OAAO,UAAU,WACzC,KAAK,KAAK,UAAU,MAAM,OAAO,OAAO;CAE1C,MAAM,SAAS,KAAK,SAAS,IAAI,KAAK,KAAK,KAAK,IAAI,EAAE,KAAK;CAC3D,MAAM,KAAK,OAAO,MAAM,KAAK,QAAQ;CACrC,IAAI,MAAM,QAAQ,MAAM,SAAS,MAAM,IACrC,MAAM,KAAK,eAAe,MAAM,MAAM;CAExC,MAAM,OAAsB,CAC1B,WAAW,MAAM,aAAa,UAC9B,SAAS,MAAM,aAAa,MAC9B;CACA,IAAI,MAAM,aAAa,WACrB,KAAK,KAAK,cAAc,MAAM,aAAa,WAAW;CAExD,IAAI,MAAM,SACR,KAAK,KAAK,YAAY,MAAM,SAAS;CAEvC,MAAM,KAAK,SAAS,KAAK,KAAK,OAAO,GAAG;CAExC,MAAM,SAAS,MAAM,aAAa;CAClC,MAAM,aAA4B,CAAC;CACnC,IAAI,QAAQ;EACV,IAAI,OAAO,2BACT,WAAW,KAAK,OAAO,aAAa,OAAO,yBAAyB,GAAG;OAClE,IAAI,OAAO,mBAChB,WAAW,KAAK,UAAU,aAAa,OAAO,iBAAiB,GAAG;EAEpE,IAAI,OAAO,mBACT,WAAW,KAAK,OAAO,aAAa,OAAO,iBAAiB,GAAG;EAEjE,IACE,OAAO,mCACJ,OAAO,oCAAoC,OAAO,mBAErD,WAAW,KACT,kBAAkB,aAAa,OAAO,+BAA+B,GACvE;EAEF,IAAI,OAAO,YAAY,WAAW,KAAK,UAAU,OAAO,YAAY;EACpE,IAAI,OAAO,QAAQ,mBACjB,WAAW,KAAK,UAAU,OAAO,OAAO,mBAAmB;CAE/D;CACA,IAAI,WAAW,SAAS,GACtB,MAAM,KAAK,iBAAiB,WAAW,KAAK,OAAO,GAAG;CAGxD,MAAM,WAAW,MAAM,aAAa;CACpC,MAAM,eAA8B,CAAC;CACrC,IAAI,UAAU;EACZ,IAAI,SAAS,YAAY,aAAa,KAAK,OAAO;EAClD,IAAI,SAAS,qBAAqB,aAAa,KAAK,gBAAgB;EACpE,IAAI,SAAS,WAAW,aAAa,KAAK,WAAW;EACrD,IAAI,SAAS,QAAQ,aAAa,KAAK,QAAQ;EAC/C,IAAI,SAAS,oBAAoB,aAAa,KAAK,oBAAoB;EACvE,IAAI,SAAS,YAAY,aAAa,KAAK,YAAY;EACvD,IAAI,SAAS,mBAAmB;GAC9B,MAAM,MAAM,SAAS;GACrB,MAAM,MAAM,SAAS;GACrB,MAAM,QACF,QAAQ,KAAA,KAAa,QAAQ,KAAA,IAC3B,IAAI,aAAa,GAAG,EAAE,GAAG,aAAa,GAAG,EAAE,KAC3C;GACN,aAAa,KAAK,oBAAoB,OAAO;EAC/C;EACA,IAAI,SAAS,oBAAoB,SAAS,iBAAiB,SAAS,GAClE,aAAa,KAAK,aAAa,SAAS,iBAAiB,KAAK,GAAG,GAAG;CAExE;CACA,IAAI,aAAa,SAAS,GACxB,MAAM,KAAK,mBAAmB,aAAa,KAAK,IAAI,GAAG;CAGzD,IAAI,MAAM,uBAAuB,MAAM,oBAAoB,SAAS,GAClE,MAAM,KAAK,oBAAoB,MAAM,oBAAoB,KAAK,IAAI,GAAG;CAEvE,IAAI,MAAM,SAAS;EACjB,MAAM,YAA2B,CAAC;EAClC,IAAI,MAAM,QAAQ,YAAY,UAAU,KAAK,SAAS;EACtD,IAAI,OAAO,MAAM,QAAQ,eAAe,UACtC,UAAU,KAAK,IAAI,MAAM,QAAQ,YAAY;EAE/C,IAAI,UAAU,SAAS,GACrB,MAAM,KAAK,kBAAkB,UAAU,KAAK,GAAG,GAAG;CAEtD;CACA,OAAO;AACT;;;;;;;;;AAUA,SAAS,aAAa,GAAmB;CACvC,IAAI,KAAK,WAAa,IAAI,YAAc,GAAG,OAAO,GAAG,IAAI,QAAU;CACnE,IAAI,KAAK,QAAQ,IAAI,SAAS,GAAG,OAAO,GAAG,IAAI,KAAK;CACpD,IAAI,KAAK,OAAa,IAAI,QAAc,GAAG,OAAO,GAAG,IAAI,IAAU;CACnE,IAAI,KAAK,OAAQ,IAAI,QAAS,GAAG,OAAO,GAAG,IAAI,IAAK;CACpD,OAAO,GAAG;AACZ"}
|
|
1
|
+
{"version":3,"file":"models-COuMOfM6.js","names":[],"sources":["../src/models.ts"],"sourcesContent":["import { defineCommand } from \"citty\"\nimport consola from \"consola\"\n\nimport { ensurePaths } from \"./lib/paths\"\nimport { setupCopilotToken, setupGitHubToken, type StopCopilotTokenRefresh } from \"./lib/token\"\nimport { getModels, type Model } from \"./services/copilot/get-models\"\n\nexport const models = defineCommand({\n meta: {\n name: \"models\",\n description:\n \"List available GitHub Copilot models and their capabilities. Pass an optional pattern to filter (case-insensitive substring match on id, name, vendor, family).\",\n },\n args: {\n pattern: {\n type: \"positional\",\n required: false,\n description:\n \"Substring to filter models by (matches id, name, vendor, or family).\",\n },\n json: {\n type: \"boolean\",\n default: false,\n description: \"Emit raw JSON instead of the pretty layout.\",\n },\n },\n async run({ args }) {\n await ensurePaths()\n await setupGitHubToken()\n // One-shot command: stop the background refresh loop before returning, so\n // the timer is never what decides whether this process exits. (It is also\n // `unref()`d, so this is belt-and-braces — but ownership stays explicit.)\n let stopRefresh: StopCopilotTokenRefresh | undefined\n try {\n stopRefresh = await setupCopilotToken()\n } catch (err) {\n consola.error(\"Failed to obtain Copilot token:\", err)\n process.exit(1)\n }\n\n try {\n let catalog: Awaited<ReturnType<typeof getModels>>\n try {\n catalog = await getModels()\n } catch (err) {\n consola.error(\"Failed to fetch Copilot model catalog:\", err)\n process.exit(1)\n }\n\n const all = catalog.data\n const pattern = args.pattern?.toString().trim()\n const filtered = pattern ? filterModels(all, pattern) : all\n\n if (args.json) {\n process.stdout.write(`${JSON.stringify(filtered, null, 2)}\\n`)\n return\n }\n\n if (filtered.length === 0) {\n consola.warn(\n `No models matched \"${pattern}\". ${all.length} models available — try a different substring or run without an argument to list everything.`,\n )\n process.exit(1)\n }\n\n const grouped = groupByVendor(filtered)\n const lines: Array<string> = []\n const header = pattern\n ? `${filtered.length}/${all.length} models match \"${pattern}\"`\n : `${all.length} models available`\n lines.push(header)\n lines.push(\"\")\n for (const [vendor, list] of grouped) {\n lines.push(`▾ ${vendor} (${list.length})`)\n for (const model of list) {\n lines.push(...formatModel(model))\n }\n lines.push(\"\")\n }\n process.stdout.write(lines.join(\"\\n\"))\n } finally {\n stopRefresh?.()\n }\n },\n})\n\nfunction filterModels(models: Array<Model>, pattern: string): Array<Model> {\n const needle = pattern.toLowerCase()\n return models.filter((m) => {\n const haystack = [\n m.id,\n m.name,\n m.vendor,\n m.capabilities.family,\n m.capabilities.type,\n m.model_picker_category ?? \"\",\n ]\n .join(\" \")\n .toLowerCase()\n return haystack.includes(needle)\n })\n}\n\nfunction groupByVendor(models: Array<Model>): Array<[string, Array<Model>]> {\n const map = new Map<string, Array<Model>>()\n for (const m of models) {\n const key = m.vendor || \"(unknown vendor)\"\n const bucket = map.get(key)\n if (bucket) bucket.push(m)\n else map.set(key, [m])\n }\n // Stable vendor order: alphabetical for predictability.\n return [...map.entries()].sort(([a], [b]) => a.localeCompare(b))\n}\n\n/**\n * Test-only exports. Not part of the public CLI surface — kept out of\n * the default export so they don't show up in IDE autocomplete on\n * `import { ... } from \"github-router/models\"` consumers.\n */\nexport const __testing = { filterModels, groupByVendor, formatModel, formatTokens }\n\nfunction formatModel(model: Model): Array<string> {\n const lines: Array<string> = []\n const tags: Array<string> = []\n if (model.preview) tags.push(\"preview\")\n if (model.is_chat_default) tags.push(\"chat-default\")\n if (model.is_chat_fallback) tags.push(\"chat-fallback\")\n if (model.billing?.is_premium) tags.push(\"premium\")\n if (model.billing?.restricted_to?.length) {\n tags.push(`restricted:${model.billing.restricted_to.join(\"/\")}`)\n }\n if (model.policy && model.policy.state !== \"enabled\") {\n tags.push(`policy:${model.policy.state}`)\n }\n const tagStr = tags.length > 0 ? ` [${tags.join(\", \")}]` : \"\"\n lines.push(` • ${model.id}${tagStr}`)\n if (model.name && model.name !== model.id) {\n lines.push(` name: ${model.name}`)\n }\n const meta: Array<string> = [\n `family: ${model.capabilities.family}`,\n `type: ${model.capabilities.type}`,\n ]\n if (model.capabilities.tokenizer) {\n meta.push(`tokenizer: ${model.capabilities.tokenizer}`)\n }\n if (model.version) {\n meta.push(`version: ${model.version}`)\n }\n lines.push(` ${meta.join(\" · \")}`)\n\n const limits = model.capabilities.limits\n const limitParts: Array<string> = []\n if (limits) {\n if (limits.max_context_window_tokens) {\n limitParts.push(`ctx ${formatTokens(limits.max_context_window_tokens)}`)\n } else if (limits.max_prompt_tokens) {\n limitParts.push(`prompt ${formatTokens(limits.max_prompt_tokens)}`)\n }\n if (limits.max_output_tokens) {\n limitParts.push(`out ${formatTokens(limits.max_output_tokens)}`)\n }\n if (\n limits.max_non_streaming_output_tokens\n && limits.max_non_streaming_output_tokens !== limits.max_output_tokens\n ) {\n limitParts.push(\n `out-non-stream ${formatTokens(limits.max_non_streaming_output_tokens)}`,\n )\n }\n if (limits.max_inputs) limitParts.push(`inputs ${limits.max_inputs}`)\n if (limits.vision?.max_prompt_images) {\n limitParts.push(`images ${limits.vision.max_prompt_images}`)\n }\n }\n if (limitParts.length > 0) {\n lines.push(` limits: ${limitParts.join(\" · \")}`)\n }\n\n const supports = model.capabilities.supports\n const supportFlags: Array<string> = []\n if (supports) {\n if (supports.tool_calls) supportFlags.push(\"tools\")\n if (supports.parallel_tool_calls) supportFlags.push(\"parallel-tools\")\n if (supports.streaming) supportFlags.push(\"streaming\")\n if (supports.vision) supportFlags.push(\"vision\")\n if (supports.structured_outputs) supportFlags.push(\"structured-outputs\")\n if (supports.dimensions) supportFlags.push(\"dimensions\")\n if (supports.adaptive_thinking) {\n const min = supports.min_thinking_budget\n const max = supports.max_thinking_budget\n const range\n = min !== undefined && max !== undefined\n ? `(${formatTokens(min)}-${formatTokens(max)})`\n : \"\"\n supportFlags.push(`adaptive-thinking${range}`)\n }\n if (supports.reasoning_effort && supports.reasoning_effort.length > 0) {\n supportFlags.push(`reasoning:${supports.reasoning_effort.join(\"/\")}`)\n }\n }\n if (supportFlags.length > 0) {\n lines.push(` supports: ${supportFlags.join(\", \")}`)\n }\n\n if (model.supported_endpoints && model.supported_endpoints.length > 0) {\n lines.push(` endpoints: ${model.supported_endpoints.join(\", \")}`)\n }\n if (model.billing) {\n const billParts: Array<string> = []\n if (model.billing.is_premium) billParts.push(\"premium\")\n if (typeof model.billing.multiplier === \"number\") {\n billParts.push(`×${model.billing.multiplier}`)\n }\n if (billParts.length > 0) {\n lines.push(` billing: ${billParts.join(\" \")}`)\n }\n }\n return lines\n}\n\n/**\n * Format a token count in a compact human-readable form: `1024` →\n * `1k`, `4096` → `4k`, `131072` → `128k`, `1048576` → `1M`. Prefer\n * binary multiples (mebi, kibi) since Claude Code / Copilot context\n * windows are reported in binary units (`1M context` = 1024 × 1024\n * tokens). Fall back to decimal (`64k` for `64000`) when the value\n * is a clean decimal multiple but not binary.\n */\nfunction formatTokens(n: number): string {\n if (n >= 1_048_576 && n % 1_048_576 === 0) return `${n / 1_048_576}M`\n if (n >= 1024 && n % 1024 === 0) return `${n / 1024}k`\n if (n >= 1_000_000 && n % 1_000_000 === 0) return `${n / 1_000_000}M`\n if (n >= 1000 && n % 1000 === 0) return `${n / 1000}k`\n return `${n}`\n}\n"],"mappings":"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"}
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { i as parseIntEnv, o as runCommandCapture } from "./exec-y8C_MU8A.js";
|
|
2
|
-
import "./stop-gate-hook-
|
|
2
|
+
import "./stop-gate-hook-BEU8qQrC.js";
|
|
3
3
|
//#region src/lib/orchestration/live-exec.ts
|
|
4
4
|
/**
|
|
5
5
|
* Live `ExecFn` for the gate runner — runs the kernel's SEALED gate command in a
|
|
@@ -36,4 +36,4 @@ const liveExec = async ({ command, cwd }) => {
|
|
|
36
36
|
//#endregion
|
|
37
37
|
export { liveExec as t };
|
|
38
38
|
|
|
39
|
-
//# sourceMappingURL=orchestration-
|
|
39
|
+
//# sourceMappingURL=orchestration-DjLA-lxB.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"orchestration-
|
|
1
|
+
{"version":3,"file":"orchestration-DjLA-lxB.js","names":[],"sources":["../src/lib/orchestration/live-exec.ts"],"sourcesContent":["/**\n * Live `ExecFn` for the gate runner — runs the kernel's SEALED gate command in a\n * workspace via the project's Windows-safe exec helper (`runCommandCapture` →\n * `buildExecInvocation`, which handles cmd.exe quoting on Windows). Only the\n * kernel's sealed gate commands flow through here (tests/types/lint/build),\n * never a producer-authored string, so a simple whitespace split into argv is\n * safe for these fixed commands. A command that can't run (spawn error / killed)\n * counts as a non-zero exit, never a throw — the gate runner treats it as\n * not-passed.\n *\n * This is the one piece of the gate engine that touches a real subprocess; it is\n * model-free and cross-platform, so it is exercised directly in CI (unlike the\n * worker/worktree/model adapters, which need the gated E2E harness).\n */\n\nimport { runCommandCapture } from \"~/lib/exec\"\n\nimport { type ExecFn } from \"./gate-runner\"\nimport { parseIntEnv } from \"../exec\"\n\n/** Per-command wall-clock cap so a hung gate command (watch-mode test, a process\n * waiting on stdin, a stale lockfile) is tree-killed instead of hanging the\n * caller forever. Generous (a real typecheck/test/lint can take minutes) but\n * bounded; override with GH_ROUTER_GATE_CMD_TIMEOUT_MS. A timeout kills the\n * command (code null) which the gate runner treats as not-passed. */\nconst CMD_TIMEOUT_MS =\n parseIntEnv(process.env.GH_ROUTER_GATE_CMD_TIMEOUT_MS) ?? 600_000\n\nexport const liveExec: ExecFn = async ({ command, cwd }) => {\n const argv = command.trim().split(/\\s+/).filter(Boolean)\n if (argv.length === 0) return { exitCode: 1 }\n try {\n const r = await runCommandCapture(argv, { cwd, timeoutMs: CMD_TIMEOUT_MS })\n // `code` is null when killed by signal/timeout → treat as a failed gate.\n return { exitCode: r.code ?? 1 }\n } catch {\n return { exitCode: 1 }\n }\n}\n"],"mappings":";;;;;;;;;;;;;;;;;;;;;;AAyBA,MAAM,iBACJ,YAAY,QAAQ,IAAI,6BAA6B,KAAK;AAE5D,MAAa,WAAmB,OAAO,EAAE,SAAS,UAAU;CAC1D,MAAM,OAAO,QAAQ,KAAK,CAAC,CAAC,MAAM,KAAK,CAAC,CAAC,OAAO,OAAO;CACvD,IAAI,KAAK,WAAW,GAAG,OAAO,EAAE,UAAU,EAAE;CAC5C,IAAI;EAGF,OAAO,EAAE,WAAU,MAFH,kBAAkB,MAAM;GAAE;GAAK,WAAW;EAAe,CAAC,EAAA,CAErD,QAAQ,EAAE;CACjC,QAAQ;EACN,OAAO,EAAE,UAAU,EAAE;CACvB;AACF"}
|
|
@@ -473,12 +473,12 @@ async function ensurePaths() {
|
|
|
473
473
|
consola.debug("Peer-agent .md sweep skipped:", err);
|
|
474
474
|
});
|
|
475
475
|
await (async () => {
|
|
476
|
-
await (await import("./lifecycle-
|
|
476
|
+
await (await import("./lifecycle-CQFjaQc0.js")).sweepStaleWorktreesAtBoot();
|
|
477
477
|
})().catch((err) => {
|
|
478
478
|
consola.debug("Worker worktree boot sweep skipped:", err);
|
|
479
479
|
});
|
|
480
480
|
await (async () => {
|
|
481
|
-
await (await import("./lifecycle-
|
|
481
|
+
await (await import("./lifecycle-B0USSJvd.js")).sweepStaleColbertMetaAtBoot();
|
|
482
482
|
})().catch((err) => {
|
|
483
483
|
consola.debug("ColBERT meta boot sweep skipped:", err);
|
|
484
484
|
});
|
|
@@ -1326,7 +1326,7 @@ async function sweepStalePeerAgentMdFiles() {
|
|
|
1326
1326
|
* previously absent here, so their stale files never got reaped. Note the capitals:
|
|
1327
1327
|
* the alternation is case-sensitive and those two are capitalized at the source.
|
|
1328
1328
|
*/
|
|
1329
|
-
const PEER_AGENT_MD_FILENAME = /^peer-(\d+)-[0-9a-f]{8}-(?:codex-critic|codex-reviewer|gemini-critic|gemini-reviewer|opus-critic|sol-critic|luna-reviewer|grok-critic|grok-reviewer|codex-implementer|peer-review-coordinator|implementer-fast|implementer|planner|reviewer|reviewer-fast|brainstorm|scout|scribe|general-purpose-fast|critic|generic-fast|generic-cheap|generic|debugger|qa-engineer|general-purpose|Explore|Plan|worker-explore|worker-implement|worker-review|worker-plan|worker-test|worker-browse)\.md$/;
|
|
1329
|
+
const PEER_AGENT_MD_FILENAME = /^peer-(\d+)-[0-9a-f]{8}-(?:codex-critic|codex-reviewer|sonnet-reviewer|gemini-critic|gemini-reviewer|opus-critic|sol-critic|luna-reviewer|grok-critic|grok-reviewer|codex-implementer|peer-review-coordinator|implementer-fast|implementer|planner|reviewer|reviewer-fast|brainstorm|scout|scribe|general-purpose-fast|critic|generic-fast|generic-cheap|generic|debugger|qa-engineer|general-purpose|Explore|Plan|worker-explore|worker-implement|worker-review|worker-plan|worker-test|worker-browse)\.md$/;
|
|
1330
1330
|
/**
|
|
1331
1331
|
* Strict regex matching only per-launch claude-config mirror dirs this
|
|
1332
1332
|
* proxy creates: `<pid>-<8 hex>`. Anchored to the entire entry name so
|
|
@@ -1397,4 +1397,4 @@ async function removeOwnClaudeConfigMirror() {
|
|
|
1397
1397
|
//#endregion
|
|
1398
1398
|
export { isUnderClaudeConfigMirror as a, sweepStalePeerAgentMdFiles as c, writeRuntimeFileSecure as d, ensurePaths as i, sweepStaleRuntimeFiles as l, PEER_AGENT_MD_FILENAME as n, removeOwnClaudeConfigMirror as o, ensureClaudeConfigMirror as r, sweepStaleClaudeConfigMirrors as s, PATHS as t, writeArtifactCredsToMirror as u };
|
|
1399
1399
|
|
|
1400
|
-
//# sourceMappingURL=paths-
|
|
1400
|
+
//# sourceMappingURL=paths-De1Qh9Q9.js.map
|