github-router 0.3.315 → 0.3.317
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/{aic-ledger-BS47yb_C.js → aic-ledger-DY03LbBM.js} +2 -2
- package/dist/{aic-ledger-BS47yb_C.js.map → aic-ledger-DY03LbBM.js.map} +1 -1
- package/dist/{attribution-settings-DXmmyuEE.js → attribution-settings-D6dAkP4e.js} +120 -21
- package/dist/attribution-settings-D6dAkP4e.js.map +1 -0
- package/dist/{auth-D8t41c5D.js → auth-Iun7ftd8.js} +4 -4
- package/dist/{auth-D8t41c5D.js.map → auth-Iun7ftd8.js.map} +1 -1
- package/dist/browser-ext/manifest.json +1 -1
- package/dist/{check-usage-BpBKOjGZ.js → check-usage-1c-0z3iy.js} +4 -4
- package/dist/{check-usage-BpBKOjGZ.js.map → check-usage-1c-0z3iy.js.map} +1 -1
- package/dist/{claude-Cmmu3-cL.js → claude-aZ6OaFP5.js} +178 -49
- package/dist/claude-aZ6OaFP5.js.map +1 -0
- package/dist/{codex-DqTKKoEx.js → codex-PTdWu7er.js} +6 -6
- package/dist/codex-PTdWu7er.js.map +1 -0
- package/dist/{copilot-discount-IbXR5A28.js → copilot-discount-C3jx9Q-o.js} +2 -2
- package/dist/{copilot-discount-IbXR5A28.js.map → copilot-discount-C3jx9Q-o.js.map} +1 -1
- package/dist/{debug-CA7pg8V9.js → debug-CDyXUPcC.js} +2 -2
- package/dist/{debug-CA7pg8V9.js.map → debug-CDyXUPcC.js.map} +1 -1
- package/dist/engine-D5GNXylB.js +2 -0
- package/dist/{gate-discovery-CPk6Z8yc.js → gate-discovery-B17pvgE0.js} +5 -5
- package/dist/{gate-discovery-CPk6Z8yc.js.map → gate-discovery-B17pvgE0.js.map} +1 -1
- package/dist/{get-copilot-usage-FSQE8szQ.js → get-copilot-usage-BWCAzmSc.js} +3 -3
- package/dist/{get-copilot-usage-FSQE8szQ.js.map → get-copilot-usage-BWCAzmSc.js.map} +1 -1
- package/dist/hooks.mjs +125 -117
- package/dist/hooks.sha256 +1 -1
- package/dist/{internal-aic-status-BN0xRLSF.js → internal-aic-status-BiblmImt.js} +13 -6
- package/dist/{internal-aic-status-BN0xRLSF.js.map → internal-aic-status-BiblmImt.js.map} +1 -1
- package/dist/{internal-artifact-open-B3stUu74.js → internal-artifact-open-CA1trJ15.js} +2 -2
- package/dist/{internal-artifact-open-B3stUu74.js.map → internal-artifact-open-CA1trJ15.js.map} +1 -1
- package/dist/{internal-fast-dispatch-guard-CAwYj_Yz.js → internal-fast-dispatch-guard-CZ4BZuAG.js} +2 -2
- package/dist/{internal-fast-dispatch-guard-CAwYj_Yz.js.map → internal-fast-dispatch-guard-CZ4BZuAG.js.map} +1 -1
- package/dist/{internal-fast-dispatch-guard-2QjUlhqO.js → internal-fast-dispatch-guard-D5kozMpo.js} +1 -1
- package/dist/{internal-first-mate-guard-VgnHBp0s.js → internal-first-mate-guard-B_or0eN3.js} +1 -1
- package/dist/{internal-first-mate-guard-B0rbLb0L.js → internal-first-mate-guard-CiFH6X1H.js} +3 -3
- package/dist/{internal-first-mate-guard-B0rbLb0L.js.map → internal-first-mate-guard-CiFH6X1H.js.map} +1 -1
- package/dist/{internal-max-dispatch-guard-BzKsY9ze.js → internal-max-dispatch-guard-BGOHRYRt.js} +1 -1
- package/dist/{internal-max-dispatch-guard-l1NGYHtF.js → internal-max-dispatch-guard-CnBZxo5l.js} +3 -3
- package/dist/{internal-max-dispatch-guard-l1NGYHtF.js.map → internal-max-dispatch-guard-CnBZxo5l.js.map} +1 -1
- package/dist/{internal-plan-review-QUvNZmMR.js → internal-plan-review-C73snnD8.js} +3 -3
- package/dist/{internal-plan-review-QUvNZmMR.js.map → internal-plan-review-C73snnD8.js.map} +1 -1
- package/dist/{internal-prompt-submit-fj5ccft_.js → internal-prompt-submit-dov4UvBo.js} +4 -4
- package/dist/{internal-prompt-submit-fj5ccft_.js.map → internal-prompt-submit-dov4UvBo.js.map} +1 -1
- package/dist/{internal-session-bind-0Hmak8PR.js → internal-session-bind-C3hrb9rP.js} +2 -2
- package/dist/{internal-session-bind-0Hmak8PR.js.map → internal-session-bind-C3hrb9rP.js.map} +1 -1
- package/dist/{internal-stop-hook-BKiKYeda.js → internal-stop-hook-DZ6CCP4C.js} +5 -5
- package/dist/{internal-stop-hook-BKiKYeda.js.map → internal-stop-hook-DZ6CCP4C.js.map} +1 -1
- package/dist/{internal-stop-review-8v2llYDB.js → internal-stop-review-MBVYtrYS.js} +2 -2
- package/dist/{internal-stop-review-8v2llYDB.js.map → internal-stop-review-MBVYtrYS.js.map} +1 -1
- package/dist/{internal-worker-guard-BI4Pl0Ew.js → internal-worker-guard-dxGawAY3.js} +2 -2
- package/dist/{internal-worker-guard-BI4Pl0Ew.js.map → internal-worker-guard-dxGawAY3.js.map} +1 -1
- package/dist/{internal-workspace-header-kg9FoNXK.js → internal-workspace-header-_aEXOz5q.js} +2 -2
- package/dist/{internal-workspace-header-kg9FoNXK.js.map → internal-workspace-header-_aEXOz5q.js.map} +1 -1
- package/dist/{lifecycle-IwotwedG.js → lifecycle-CJB2BwSJ.js} +2 -2
- package/dist/{lifecycle-IwotwedG.js.map → lifecycle-CJB2BwSJ.js.map} +1 -1
- package/dist/lifecycle-D0KsoSqz.js +2 -0
- package/dist/lifecycle-DimEguJO.js +2 -0
- package/dist/{lifecycle-Cx1wVrLb.js → lifecycle-_BE0SnNs.js} +2 -2
- package/dist/{lifecycle-Cx1wVrLb.js.map → lifecycle-_BE0SnNs.js.map} +1 -1
- package/dist/main.js +20 -20
- package/dist/{max-profile-contract-BcrMlrmo.js → max-profile-contract-Bl7I_EOC.js} +2 -2
- package/dist/{max-profile-contract-BcrMlrmo.js.map → max-profile-contract-Bl7I_EOC.js.map} +1 -1
- package/dist/{mcp-workspace-header-BYgWioLH.js → mcp-workspace-header-mXRLE8kg.js} +2 -2
- package/dist/{mcp-workspace-header-BYgWioLH.js.map → mcp-workspace-header-mXRLE8kg.js.map} +1 -1
- package/dist/{models-DgLeb-Dv.js → models-CSFIVxAH.js} +3 -3
- package/dist/{models-DgLeb-Dv.js.map → models-CSFIVxAH.js.map} +1 -1
- package/dist/{orchestration-Dc3mO0G3.js → orchestration-B8kypXcZ.js} +2 -2
- package/dist/{orchestration-Dc3mO0G3.js.map → orchestration-B8kypXcZ.js.map} +1 -1
- package/dist/{paths-CMxlQEfQ.js → paths-CHBAj_t9.js} +36 -4
- package/dist/{paths-CMxlQEfQ.js.map → paths-CHBAj_t9.js.map} +1 -1
- package/dist/paths-eHoOwFzZ.js +2 -0
- package/dist/{peer-mcp-personas-CYWJSxPK.js → peer-mcp-personas-CRMVuMVF.js} +201 -61
- package/dist/peer-mcp-personas-CRMVuMVF.js.map +1 -0
- package/dist/{plan-review-hook-BIMwWkh6.js → plan-review-hook-BMmw7wxR.js} +3 -3
- package/dist/{plan-review-hook-BIMwWkh6.js.map → plan-review-hook-BMmw7wxR.js.map} +1 -1
- package/dist/{prompt-submit-hook-BcFpjHXg.js → prompt-submit-hook-CGgT5m4Q.js} +3 -3
- package/dist/{prompt-submit-hook-BcFpjHXg.js.map → prompt-submit-hook-CGgT5m4Q.js.map} +1 -1
- package/dist/{provision-AwSjt-vR.js → provision-Bn8-NDp7.js} +4 -4
- package/dist/{provision-AwSjt-vR.js.map → provision-Bn8-NDp7.js.map} +1 -1
- package/dist/{self-invocation-cRl4RqfW.js → self-invocation-DahN1gw9.js} +2 -2
- package/dist/{self-invocation-cRl4RqfW.js.map → self-invocation-DahN1gw9.js.map} +1 -1
- package/dist/{serve-BG2O6Slz.js → serve-CX4Ifk5p.js} +13 -13
- package/dist/{serve-BG2O6Slz.js.map → serve-CX4Ifk5p.js.map} +1 -1
- package/dist/{server-setup-D7ABbEs1.js → server-setup-0PaS4m2B.js} +254 -66
- package/dist/server-setup-0PaS4m2B.js.map +1 -0
- package/dist/{start-Dpwpnq99.js → start-Bz_559ua.js} +3 -3
- package/dist/{start-Dpwpnq99.js.map → start-Bz_559ua.js.map} +1 -1
- package/dist/{state-B8adscCv.js → state-BlMpEFAt.js} +2 -1
- package/dist/{state-B8adscCv.js.map → state-BlMpEFAt.js.map} +1 -1
- package/dist/{stop-gate-hook-BUCxa5Kc.js → stop-gate-hook-D7N759TG.js} +72 -4
- package/dist/{stop-gate-hook-BUCxa5Kc.js.map → stop-gate-hook-D7N759TG.js.map} +1 -1
- package/dist/{stop-gate-policy--bpyxxXU.js → stop-gate-policy-C0gt04R0.js} +2 -2
- package/dist/{stop-gate-policy--bpyxxXU.js.map → stop-gate-policy-C0gt04R0.js.map} +1 -1
- package/dist/{token-ClzS23Y2.js → token-86uk6y4P.js} +3 -3
- package/dist/{token-ClzS23Y2.js.map → token-86uk6y4P.js.map} +1 -1
- package/dist/{worker-dispatch-DMIdrlsF.js → worker-dispatch-B-OA7tvU.js} +2 -2
- package/dist/{worker-dispatch-DMIdrlsF.js.map → worker-dispatch-B-OA7tvU.js.map} +1 -1
- package/package.json +1 -1
- package/dist/attribution-settings-DXmmyuEE.js.map +0 -1
- package/dist/claude-Cmmu3-cL.js.map +0 -1
- package/dist/codex-DqTKKoEx.js.map +0 -1
- package/dist/engine-b9XaKLp0.js +0 -2
- package/dist/lifecycle-BpqAyaAj.js +0 -2
- package/dist/lifecycle-CL2WiyeQ.js +0 -2
- package/dist/paths-BXXCVFvA.js +0 -2
- package/dist/peer-mcp-personas-CYWJSxPK.js.map +0 -1
- package/dist/server-setup-D7ABbEs1.js.map +0 -1
|
@@ -1,13 +1,13 @@
|
|
|
1
|
-
import { $ as
|
|
1
|
+
import { $ as EFFORT_ORDER, $t as parseJsonOrDiagnose, An as oneMContextDisabled, B as resolveAdvisorEffort, Bn as CHEAP_PROFILE_MODELS, Bt as getTextTokenCount, Cn as isBudgetClaudeLead, D as toolbeltEnabled, Dn as upstreamMaxConnections, En as upstreamAllowH2, F as ADVISOR_TOOL_INSTRUCTIONS, Fn as CHEAPEST_PROFILE_NATIVE_AGENT_NAMES, G as repairKnownThinkingHistory, Gn as withInstallLock, H as resolveCheapestAdvisorModel, Ht as getTokenizerFromModel, I as FAST_ADVISOR_TOOL_INSTRUCTIONS, J as buildOpenAIErrorEvent, Jt as resolveMcpToolTimeoutMs, K as repairRejectedThinkingHistory, Kt as assembleResponsesPayload, L as buildAdvisorStream, Lt as shimDefaultsToXhigh, Mn as withOneMSuffixForLead, N as searchWeb, Nn as CHEAPEST_PROFILE_ADVISOR_CLIENT_MODEL, On as classifyMessagesRoute, P as ADVISOR_INTERNAL_TOOL_NAME, Pn as CHEAPEST_PROFILE_MODELS, Q as relayAnthropicStream, Qt as readResponseBodyCapped, R as injectAdvisorTool, Rn as CHEAPEST_PROFILE_SUBAGENT_CONTEXT_TOKENS, Rt as countTokens, Sn as generateRandomPort, U as formatThinkingRepairDecline, Ut as findLaunchBySecret, V as resolveAdvisorModel, Vn as CHEAP_PROFILE_NATIVE_AGENT_NAMES, Vt as getTokenCount, W as rememberThinkingHistoryRepair, Wn as CHEAP_PROFILE_SUBAGENT_CONTEXT_TOKENS, X as logStreamError, Xt as createChatCompletions, Y as isControllerClosedError, Yt as createResponses, Z as readIteratorWithTimeout, Zt as MAX_RESPONSE_BODY_BYTES, at as agentToolsEnabled, bn as UPSTREAM_FETCH_TIMEOUT_MS, cn as provisionTreeSitterAssets, en as normalizeOpenAIUsage, et as UNKNOWN_EFFORT_ANCHOR, hn as BUDGET_SMALL_FAST_SLUG, i as assertMcpToolSurfaceConsistent, it as handleMcpPost, jn as withOneMSuffix, kn as catalogAdvertises1M, nt as clampEffort, pn as toolbeltPathOverride, q as buildAnthropicErrorEvent, qt as warnOnTokenPriceDrift, rt as handleMcpDelete, tt as bucketEffort, xn as UPSTREAM_INACTIVITY_TIMEOUT_MS, z as isAdvisorRequested, zn as CHEAP_PROFILE_ADVISOR_CLIENT_MODEL, zt as createMessages } from "./peer-mcp-personas-CRMVuMVF.js";
|
|
2
2
|
import { t as getPackageVersion } from "./version-C8x2hQrZ.js";
|
|
3
|
-
import { i as ensurePaths, t as PATHS } from "./paths-
|
|
4
|
-
import { t as state } from "./state-
|
|
5
|
-
import { T as copilotHeaders, _ as forwardError, a as cacheCopilotVersion, c as filterBetaHeader, d as resolveModel, f as sleep, g as HTTPError, i as tryRefreshAndRetry, l as isNullish, n as setupGitHubAgentToken, o as cacheModels, r as setupGitHubToken, s as cacheVSCodeVersion, t as setupCopilotToken, w as copilotBaseUrl, y as fetchWithTransientRetry } from "./token-
|
|
6
|
-
import { t as getCopilotUsage } from "./get-copilot-usage-
|
|
3
|
+
import { i as ensurePaths, t as PATHS } from "./paths-CHBAj_t9.js";
|
|
4
|
+
import { t as state } from "./state-BlMpEFAt.js";
|
|
5
|
+
import { T as copilotHeaders, _ as forwardError, a as cacheCopilotVersion, c as filterBetaHeader, d as resolveModel, f as sleep, g as HTTPError, i as tryRefreshAndRetry, l as isNullish, n as setupGitHubAgentToken, o as cacheModels, r as setupGitHubToken, s as cacheVSCodeVersion, t as setupCopilotToken, w as copilotBaseUrl, y as fetchWithTransientRetry } from "./token-86uk6y4P.js";
|
|
6
|
+
import { t as getCopilotUsage } from "./get-copilot-usage-BWCAzmSc.js";
|
|
7
7
|
import { c as runCommandVoid, i as parseBoolEnv, o as resolveExecutable, r as killManagedTree, s as runCommandCapture } from "./exec-COUT4QsS.js";
|
|
8
8
|
import { c as FAST_PROFILE_MODELS, l as FAST_PROFILE_NATIVE_AGENT_NAMES, r as FAST_PROFILE_ADVISOR_MODEL } from "./fast-profile-contract-_DhIWank.js";
|
|
9
|
-
import { A as normalizeTrailingOneMSuffix, a as MAX_PROFILE_NATIVE_AGENT_NAMES, d as maxAdvisorPinIsValid, h as maxOpusModel, i as MAX_PROFILE_MODELS, j as stripTrailingOneMSuffix, k as fastEndpointForModel, l as maxAdvisorEffortForModel, n as MAX_PROFILE_ALLOWED_LEAD_MODEL_IDS, t as MAX_PROFILE_ADVISOR_INSTRUCTIONS, u as maxAdvisorModelFromPin, y as validateMaxProfilePrerequisites } from "./max-profile-contract-
|
|
10
|
-
import { c as recordAic, d as extractCopilotUsage, f as formatAic, i as extractAndRecordAic, p as nanoAiuToCredits } from "./aic-ledger-
|
|
9
|
+
import { A as normalizeTrailingOneMSuffix, a as MAX_PROFILE_NATIVE_AGENT_NAMES, d as maxAdvisorPinIsValid, h as maxOpusModel, i as MAX_PROFILE_MODELS, j as stripTrailingOneMSuffix, k as fastEndpointForModel, l as maxAdvisorEffortForModel, n as MAX_PROFILE_ALLOWED_LEAD_MODEL_IDS, t as MAX_PROFILE_ADVISOR_INSTRUCTIONS, u as maxAdvisorModelFromPin, y as validateMaxProfilePrerequisites } from "./max-profile-contract-Bl7I_EOC.js";
|
|
10
|
+
import { c as recordAic, d as extractCopilotUsage, f as formatAic, i as extractAndRecordAic, p as nanoAiuToCredits } from "./aic-ledger-DY03LbBM.js";
|
|
11
11
|
import consola from "consola";
|
|
12
12
|
import fs, { existsSync } from "node:fs";
|
|
13
13
|
import path from "node:path";
|
|
@@ -421,6 +421,25 @@ const CHEAP_PROFILE = Object.freeze({
|
|
|
421
421
|
hasCoordinator: false
|
|
422
422
|
});
|
|
423
423
|
/**
|
|
424
|
+
* The `-m cheapest` roster: the exact cheap surface and groups, but Luna-led
|
|
425
|
+
* (`gpt-5.6-luna`/max at the 200K default window), a Gemini/high Advisor, a
|
|
426
|
+
* Sol/high Oracle, and a Gemini/high reviewer. Oracle-only peer set, no
|
|
427
|
+
* `astra`. Hard-denies match fast's: core workers, `orchestrate`, `decide`,
|
|
428
|
+
* `fleet`, and `first-mate`.
|
|
429
|
+
*/
|
|
430
|
+
const CHEAPEST_PROFILE = Object.freeze({
|
|
431
|
+
id: "cheapest",
|
|
432
|
+
nativeRoster: new Set(CHEAPEST_PROFILE_NATIVE_AGENT_NAMES),
|
|
433
|
+
personaAllowlist: /* @__PURE__ */ new Set(["oracle"]),
|
|
434
|
+
allowedGroups: /* @__PURE__ */ new Set([
|
|
435
|
+
"peers",
|
|
436
|
+
"search",
|
|
437
|
+
"workers",
|
|
438
|
+
"browser"
|
|
439
|
+
]),
|
|
440
|
+
hasCoordinator: false
|
|
441
|
+
});
|
|
442
|
+
/**
|
|
424
443
|
* The `-m max` profile: Sol/Luna-led, browse-only workers, and explicit
|
|
425
444
|
* cross-lab peer names. The descriptor is a hard projection for bound launch
|
|
426
445
|
* requests; unbound/BYO traffic remains standard because it has no registry
|
|
@@ -455,6 +474,7 @@ function profileDescriptor(id) {
|
|
|
455
474
|
if (id === "max") return MAX_PROFILE;
|
|
456
475
|
if (id === "cheap1m") return CHEAP1M_PROFILE;
|
|
457
476
|
if (id === "cheap") return CHEAP_PROFILE;
|
|
477
|
+
if (id === "cheapest") return CHEAPEST_PROFILE;
|
|
458
478
|
return STANDARD_PROFILE;
|
|
459
479
|
}
|
|
460
480
|
/**
|
|
@@ -474,6 +494,7 @@ function resolveLaunchProfile(modelArg) {
|
|
|
474
494
|
if (arg === "max") return "max";
|
|
475
495
|
if (arg === "cheap1m") return "cheap1m";
|
|
476
496
|
if (arg === "cheap") return "cheap";
|
|
497
|
+
if (arg === "cheapest") return "cheapest";
|
|
477
498
|
return "standard";
|
|
478
499
|
}
|
|
479
500
|
function validateMaxProfileLaunch(catalog) {
|
|
@@ -786,6 +807,53 @@ function formatCheap1mPrerequisiteFailure(missing) {
|
|
|
786
807
|
function formatCheapPrerequisiteFailure(missing) {
|
|
787
808
|
return "github-router claude -m cheap requires the following live-catalog capabilities, which this account's catalog does not fully provide:\n" + missing.map((m) => ` - ${m}`).join("\n") + "\n\nFalling back or silently dropping an agent is not supported for the cheap profile's exact roster. Run plain `github-router claude` instead.";
|
|
788
809
|
}
|
|
810
|
+
/** The subagent window floor: every cheapest role runs at the 200K default. */
|
|
811
|
+
const CHEAPEST_SUBAGENT_MIN_CONTEXT_TOKENS = CHEAPEST_PROFILE_SUBAGENT_CONTEXT_TOKENS;
|
|
812
|
+
/**
|
|
813
|
+
* Validate the live Copilot catalog for `-m cheapest`: Luna lead at the 200K
|
|
814
|
+
* default window, Luna Explore/Plan/GP/implementer roles, Gemini reviewer and
|
|
815
|
+
* Advisor, and a Sol Oracle — all at the 200K default with their fixed
|
|
816
|
+
* efforts and supported endpoints.
|
|
817
|
+
*/
|
|
818
|
+
function validateCheapestProfilePrerequisites(catalog) {
|
|
819
|
+
const missing = [];
|
|
820
|
+
const luna = findModel(catalog, CHEAPEST_PROFILE_MODELS.lead);
|
|
821
|
+
if (!luna) missing.push(`${CHEAPEST_PROFILE_MODELS.lead}: absent from the live catalog`);
|
|
822
|
+
else {
|
|
823
|
+
if (!hasToolCalls(luna)) missing.push(`${CHEAPEST_PROFILE_MODELS.lead}: does not advertise tool_calls`);
|
|
824
|
+
if (!hasContextAtLeast(luna, CHEAPEST_SUBAGENT_MIN_CONTEXT_TOKENS)) missing.push(`${CHEAPEST_PROFILE_MODELS.lead}: advertised context window is below the 200K subagent floor`);
|
|
825
|
+
if (!supportsEffort(luna, "high") || !supportsEffort(luna, "max") || !supportsEffort(luna, "xhigh")) missing.push(`${CHEAPEST_PROFILE_MODELS.lead}: does not advertise "high", "max", and "xhigh" reasoning effort`);
|
|
826
|
+
if (!supportsEndpoint(luna, "responses")) missing.push(`${CHEAPEST_PROFILE_MODELS.lead}: does not advertise a supported Responses endpoint`);
|
|
827
|
+
}
|
|
828
|
+
const sol = findModel(catalog, CHEAPEST_PROFILE_MODELS.plan);
|
|
829
|
+
if (!sol) missing.push(`${CHEAPEST_PROFILE_MODELS.plan}: absent from the live catalog`);
|
|
830
|
+
else {
|
|
831
|
+
if (!hasToolCalls(sol)) missing.push(`${CHEAPEST_PROFILE_MODELS.plan}: does not advertise tool_calls`);
|
|
832
|
+
if (!hasContextAtLeast(sol, CHEAPEST_SUBAGENT_MIN_CONTEXT_TOKENS)) missing.push(`${CHEAPEST_PROFILE_MODELS.plan}: advertised context window is below the 200K subagent floor`);
|
|
833
|
+
if (!supportsEffort(sol, "high")) missing.push(`${CHEAPEST_PROFILE_MODELS.plan}: does not advertise a "high" reasoning effort`);
|
|
834
|
+
if (!supportsEndpoint(sol, "responses")) missing.push(`${CHEAPEST_PROFILE_MODELS.plan}: does not advertise a supported Responses endpoint`);
|
|
835
|
+
if (!hasUsablePromptMetadata(sol)) missing.push(`${CHEAPEST_PROFILE_MODELS.plan}: no usable max_prompt_tokens metadata (Oracle brief)`);
|
|
836
|
+
}
|
|
837
|
+
const gemini = findModel(catalog, CHEAPEST_PROFILE_MODELS.reviewer);
|
|
838
|
+
if (!gemini) missing.push(`${CHEAPEST_PROFILE_MODELS.reviewer}: absent from the live catalog`);
|
|
839
|
+
else {
|
|
840
|
+
if (!hasToolCalls(gemini)) missing.push(`${CHEAPEST_PROFILE_MODELS.reviewer}: does not advertise tool_calls`);
|
|
841
|
+
if (!hasContextAtLeast(gemini, CHEAPEST_SUBAGENT_MIN_CONTEXT_TOKENS)) missing.push(`${CHEAPEST_PROFILE_MODELS.reviewer}: advertised context window is below the 200K subagent floor`);
|
|
842
|
+
if (!supportsEffort(gemini, "high")) missing.push(`${CHEAPEST_PROFILE_MODELS.reviewer}: does not advertise a "high" reasoning effort`);
|
|
843
|
+
if (!supportsEndpoint(gemini, "chat")) missing.push(`${CHEAPEST_PROFILE_MODELS.reviewer}: does not advertise a supported chat-completions endpoint`);
|
|
844
|
+
}
|
|
845
|
+
return {
|
|
846
|
+
ok: missing.length === 0,
|
|
847
|
+
missing
|
|
848
|
+
};
|
|
849
|
+
}
|
|
850
|
+
/**
|
|
851
|
+
* Format `validateCheapestProfilePrerequisites`'s failure list into the
|
|
852
|
+
* launch error message.
|
|
853
|
+
*/
|
|
854
|
+
function formatCheapestPrerequisiteFailure(missing) {
|
|
855
|
+
return "github-router claude -m cheapest requires the following live-catalog capabilities, which this account's catalog does not fully provide:\n" + missing.map((m) => ` - ${m}`).join("\n") + "\n\nFalling back or silently dropping an agent is not supported for the cheapest profile's exact roster. Run plain `github-router claude` instead.";
|
|
856
|
+
}
|
|
789
857
|
//#endregion
|
|
790
858
|
//#region src/lib/file-log-reporter.ts
|
|
791
859
|
const MAX_LOG_BYTES = 1048576;
|
|
@@ -1150,6 +1218,26 @@ const CHEAP_PICKER_MODELS = Object.freeze([
|
|
|
1150
1218
|
neverOneM: true
|
|
1151
1219
|
}
|
|
1152
1220
|
]);
|
|
1221
|
+
const CHEAPEST_PICKER_MODELS = Object.freeze([
|
|
1222
|
+
{
|
|
1223
|
+
id: "gpt-5.6-sol",
|
|
1224
|
+
label: "GPT-5.6 Sol",
|
|
1225
|
+
behavesAs: "claude-opus-5",
|
|
1226
|
+
neverOneM: true
|
|
1227
|
+
},
|
|
1228
|
+
{
|
|
1229
|
+
id: "gpt-5.6-luna",
|
|
1230
|
+
label: "GPT-5.6 Luna",
|
|
1231
|
+
behavesAs: "claude-opus-5",
|
|
1232
|
+
neverOneM: true
|
|
1233
|
+
},
|
|
1234
|
+
{
|
|
1235
|
+
id: "gemini-3.8-flash",
|
|
1236
|
+
label: "Gemini 3.8 Flash",
|
|
1237
|
+
behavesAs: "claude-sonnet-5",
|
|
1238
|
+
neverOneM: true
|
|
1239
|
+
}
|
|
1240
|
+
]);
|
|
1153
1241
|
/**
|
|
1154
1242
|
* Return the ordered, profile-specific `/model` rows supported by the live
|
|
1155
1243
|
* Copilot catalog. Fast intentionally shares Standard's four-row inventory;
|
|
@@ -1167,7 +1255,7 @@ function selectableModelsInCatalog(profile) {
|
|
|
1167
1255
|
const catalog = state.models?.data;
|
|
1168
1256
|
if (!catalog || catalog.length === 0) return [];
|
|
1169
1257
|
const present = new Set(catalog.map((entry) => entry.id));
|
|
1170
|
-
return (profile === "max" ? MAX_PICKER_MODELS : profile === "cheap" || profile === "cheap1m" ? CHEAP_PICKER_MODELS : STANDARD_PICKER_MODELS).filter((entry) => present.has(entry.id)).map((entry) => ({
|
|
1258
|
+
return (profile === "max" ? MAX_PICKER_MODELS : profile === "cheap" || profile === "cheap1m" ? CHEAP_PICKER_MODELS : profile === "cheapest" ? CHEAPEST_PICKER_MODELS : STANDARD_PICKER_MODELS).filter((entry) => present.has(entry.id)).map((entry) => ({
|
|
1171
1259
|
model: entry.neverOneM ? entry.id : withOneMSuffix(entry.id),
|
|
1172
1260
|
label: entry.label,
|
|
1173
1261
|
behavesAs: entry.behavesAs
|
|
@@ -1196,6 +1284,17 @@ async function renameSettingsWithRetry(temp, target) {
|
|
|
1196
1284
|
await fs$1.rm(temp, { force: true }).catch(() => {});
|
|
1197
1285
|
throw lastError;
|
|
1198
1286
|
}
|
|
1287
|
+
/**
|
|
1288
|
+
* Profiles whose sessions run router-provided surfaces only. On these
|
|
1289
|
+
* launches a user-curated `modelPicker` in the (per-launch, disposable)
|
|
1290
|
+
* mirror is overwritten with the router rows rather than preserved: the
|
|
1291
|
+
* mirror is a snapshot copy, so the operator's real settings are never
|
|
1292
|
+
* touched, but a stale standard `[1m]` picker must not survive into a
|
|
1293
|
+
* 200K session's `/model` UI.
|
|
1294
|
+
*/
|
|
1295
|
+
function routerWinsPicker(profile) {
|
|
1296
|
+
return profile === "fast" || profile === "cheap" || profile === "cheap1m" || profile === "cheapest";
|
|
1297
|
+
}
|
|
1199
1298
|
function modelIdsFromExistingPicker(value) {
|
|
1200
1299
|
if (!value || typeof value !== "object" || Array.isArray(value)) return [];
|
|
1201
1300
|
const options = value.options;
|
|
@@ -1220,11 +1319,16 @@ async function injectModelPickerSettingsFile(settingsPath, profile) {
|
|
|
1220
1319
|
if (!parsed || typeof parsed !== "object" || Array.isArray(parsed)) throw new Error(`settings.json at ${settingsPath} is not a JSON object; refusing to overwrite`);
|
|
1221
1320
|
existing = parsed;
|
|
1222
1321
|
}
|
|
1223
|
-
|
|
1224
|
-
|
|
1225
|
-
|
|
1226
|
-
|
|
1227
|
-
|
|
1322
|
+
let overwroteUserPicker = false;
|
|
1323
|
+
if ("modelPicker" in existing) {
|
|
1324
|
+
if (!routerWinsPicker(profile)) return {
|
|
1325
|
+
written: false,
|
|
1326
|
+
reason: "user-set",
|
|
1327
|
+
models: modelIdsFromExistingPicker(existing.modelPicker)
|
|
1328
|
+
};
|
|
1329
|
+
overwroteUserPicker = true;
|
|
1330
|
+
delete existing.modelPicker;
|
|
1331
|
+
}
|
|
1228
1332
|
if (options.length === 0) return {
|
|
1229
1333
|
written: false,
|
|
1230
1334
|
reason: "no-models",
|
|
@@ -1249,6 +1353,7 @@ async function injectModelPickerSettingsFile(settingsPath, profile) {
|
|
|
1249
1353
|
}
|
|
1250
1354
|
return {
|
|
1251
1355
|
written: true,
|
|
1356
|
+
...overwroteUserPicker ? { reason: "router-overwrite" } : {},
|
|
1252
1357
|
models: options.map((option) => option.model)
|
|
1253
1358
|
};
|
|
1254
1359
|
}
|
|
@@ -2108,7 +2213,7 @@ function collectToolFieldKeys(body) {
|
|
|
2108
2213
|
//#endregion
|
|
2109
2214
|
//#region package.json
|
|
2110
2215
|
var name = "github-router";
|
|
2111
|
-
var version = "0.3.
|
|
2216
|
+
var version = "0.3.317";
|
|
2112
2217
|
//#endregion
|
|
2113
2218
|
//#region src/lib/approval.ts
|
|
2114
2219
|
const awaitApproval = async () => {
|
|
@@ -4940,7 +5045,9 @@ async function handleNonClaudeResponses(c, opts) {
|
|
|
4940
5045
|
return stream;
|
|
4941
5046
|
}
|
|
4942
5047
|
const payload = parsedToResponsesPayload(parsed);
|
|
4943
|
-
const
|
|
5048
|
+
const result = await createResponses(payload, opts.model?.requestHeaders, void 0, true);
|
|
5049
|
+
extractAndRecordAic(opts.modelId, result);
|
|
5050
|
+
const anthropic = responsesResponseToAnthropicMessage(result, opts.modelId);
|
|
4944
5051
|
const usage = anthropic.usage;
|
|
4945
5052
|
logRequest({
|
|
4946
5053
|
method: "POST",
|
|
@@ -4996,7 +5103,9 @@ async function handleNonClaudeChat(c, opts) {
|
|
|
4996
5103
|
return stream;
|
|
4997
5104
|
}
|
|
4998
5105
|
const payload = parsedToChatPayload(parsed);
|
|
4999
|
-
const
|
|
5106
|
+
const result = await createChatCompletions(payload, opts.model?.requestHeaders, void 0, true);
|
|
5107
|
+
extractAndRecordAic(opts.modelId, result);
|
|
5108
|
+
const anthropic = chatResponseToAnthropicMessage(result, opts.modelId);
|
|
5000
5109
|
const usage = anthropic.usage;
|
|
5001
5110
|
logRequest({
|
|
5002
5111
|
method: "POST",
|
|
@@ -5159,16 +5268,38 @@ function preprocessMaxRequest(rawBody, launch, subagentRequest = false) {
|
|
|
5159
5268
|
Object.freeze([MAX_LUNA_HIGH_ALIAS_ID, MAX_LUNA_MAX_ALIAS_ID]);
|
|
5160
5269
|
//#endregion
|
|
5161
5270
|
//#region src/lib/fast-request-preprocess.ts
|
|
5162
|
-
const cheapFamily = (profileId) => profileId === "cheap" || profileId === "cheap1m";
|
|
5271
|
+
const cheapFamily = (profileId) => profileId === "cheap" || profileId === "cheap1m" || profileId === "cheapest";
|
|
5272
|
+
const pinnedProfile = (profileId) => profileId === "fast" || cheapFamily(profileId);
|
|
5273
|
+
/**
|
|
5274
|
+
* Profiles whose every selectable `/model` row must stay at Claude Code's
|
|
5275
|
+
* 200K DEFAULT context window (bare id, no `[1m]` accounting bracket).
|
|
5276
|
+
* `fast` keeps 1M on lead and subagents by design; `cheap1m` keeps 1M on
|
|
5277
|
+
* the lead only (its subagents are bare-by-construction).
|
|
5278
|
+
*/
|
|
5279
|
+
const bareEnforcedProfile = (profileId) => profileId === "cheap" || profileId === "cheapest";
|
|
5280
|
+
function explicitEffortOf(value) {
|
|
5281
|
+
return typeof value === "string" && value.trim() !== "" ? value : void 0;
|
|
5282
|
+
}
|
|
5163
5283
|
/**
|
|
5164
5284
|
* Apply authenticated fast/cheap-profile model and effort policy before
|
|
5165
5285
|
* ordinary model resolution. Synthetic aliases are refused outside an
|
|
5166
|
-
* authenticated
|
|
5167
|
-
*
|
|
5168
|
-
* mapping (same model-to-effort rows, just bare subagent
|
|
5169
|
-
* wiring layer), so this preprocess is shared.
|
|
5170
|
-
* fast reviews on Sonnet 5/xhigh while cheap
|
|
5171
|
-
*
|
|
5286
|
+
* authenticated pinned launch, so raw/BYO traffic cannot opt itself into
|
|
5287
|
+
* private profile semantics. The cheap family (including cheapest) shares
|
|
5288
|
+
* fast's effort mapping (same model-to-effort rows, just bare subagent
|
|
5289
|
+
* slugs at the wiring layer), so this preprocess is shared.
|
|
5290
|
+
* Note the reviewer differs: fast reviews on Sonnet 5/xhigh while cheap
|
|
5291
|
+
* reviews on Luna/max and cheapest reviews on Gemini/high — all rows exist
|
|
5292
|
+
* here, so each profile's reviewer resolves to its fixed effort.
|
|
5293
|
+
*
|
|
5294
|
+
* Pinned-profile isolation (fast/cheap/cheap1m/cheapest): only
|
|
5295
|
+
* router-provided models are accepted (anything else is `rejectedModel`).
|
|
5296
|
+
* Context: cheap/cheapest traffic is stripped to the bare 200K id;
|
|
5297
|
+
* cheap1m subagent traffic is stripped while its lead keeps 1M; fast
|
|
5298
|
+
* keeps 1M on both. Effort: picker changes apply to the lead session
|
|
5299
|
+
* only — lead requests keep an explicit `output_config.effort` when
|
|
5300
|
+
* present and fall back to the fixed mapping otherwise, while subagent
|
|
5301
|
+
* traffic (`x-claude-code-agent-id`) always receives its fixed
|
|
5302
|
+
* per-model effort.
|
|
5172
5303
|
*/
|
|
5173
5304
|
function preprocessFastRequest(rawBody, launch, subagentRequest = false) {
|
|
5174
5305
|
if (launch?.profileId === "max") return preprocessMaxRequest(rawBody, launch, subagentRequest);
|
|
@@ -5205,23 +5336,30 @@ function preprocessFastRequest(rawBody, launch, subagentRequest = false) {
|
|
|
5205
5336
|
modified: false
|
|
5206
5337
|
};
|
|
5207
5338
|
const { base: bare } = stripTrailingOneMSuffix(originalModel);
|
|
5208
|
-
|
|
5339
|
+
const profileId = launch?.profileId;
|
|
5340
|
+
const stripBracket = bareEnforcedProfile(profileId) || profileId === "cheap1m" && subagentRequest;
|
|
5341
|
+
const leadCallerControlled = pinnedProfile(profileId) && !subagentRequest;
|
|
5342
|
+
let fixedEffort;
|
|
5209
5343
|
if (alias) {
|
|
5210
|
-
|
|
5344
|
+
fixedEffort = alias.absentEffortDefault;
|
|
5211
5345
|
parsed.model = canonicalizeAliasModel(originalModel);
|
|
5212
|
-
} else if (bare === "gpt-5.6-luna")
|
|
5213
|
-
else if (bare === "gpt-5.6-sol")
|
|
5214
|
-
else if (bare === "grok-4.6")
|
|
5215
|
-
else if (bare === "gemini-3.8-flash")
|
|
5216
|
-
else if (bare === "claude-sonnet-5")
|
|
5217
|
-
else if (bare === "claude-opus-5")
|
|
5218
|
-
if (!
|
|
5346
|
+
} else if (bare === "gpt-5.6-luna") fixedEffort = "max";
|
|
5347
|
+
else if (bare === "gpt-5.6-sol") fixedEffort = "high";
|
|
5348
|
+
else if (bare === "grok-4.6") fixedEffort = "medium";
|
|
5349
|
+
else if (bare === "gemini-3.8-flash") fixedEffort = "high";
|
|
5350
|
+
else if (bare === "claude-sonnet-5") fixedEffort = "xhigh";
|
|
5351
|
+
else if (bare === "claude-opus-5") fixedEffort = "high";
|
|
5352
|
+
if (!fixedEffort && !alias) return {
|
|
5219
5353
|
body: rawBody,
|
|
5220
5354
|
originalModel,
|
|
5221
5355
|
modified: false,
|
|
5222
5356
|
rejectedModel: originalModel
|
|
5223
5357
|
};
|
|
5358
|
+
if (stripBracket && typeof parsed.model === "string") parsed.model = stripTrailingOneMSuffix(parsed.model).base;
|
|
5359
|
+
else if (stripBracket) parsed.model = bare;
|
|
5224
5360
|
const outputConfig = parsed.output_config && typeof parsed.output_config === "object" ? parsed.output_config : {};
|
|
5361
|
+
const explicitEffort = explicitEffortOf(outputConfig.effort);
|
|
5362
|
+
const effort = leadCallerControlled && explicitEffort ? explicitEffort : fixedEffort;
|
|
5225
5363
|
parsed.output_config = {
|
|
5226
5364
|
...outputConfig,
|
|
5227
5365
|
effort
|
|
@@ -5539,6 +5677,23 @@ function fastAdvisorMetadataMismatch(rawBody) {
|
|
|
5539
5677
|
if (stripTrailingOneMSuffix(model).base !== FAST_PROFILE_ADVISOR_MODEL) return `the native Advisor tool requested ${JSON.stringify(model)} instead of ${JSON.stringify(FAST_PROFILE_ADVISOR_MODEL)}`;
|
|
5540
5678
|
}
|
|
5541
5679
|
}
|
|
5680
|
+
function cheapestAdvisorMetadataMismatch(rawBody) {
|
|
5681
|
+
let body;
|
|
5682
|
+
try {
|
|
5683
|
+
body = JSON.parse(rawBody);
|
|
5684
|
+
} catch {
|
|
5685
|
+
return;
|
|
5686
|
+
}
|
|
5687
|
+
if (!Array.isArray(body.tools) || body.tools.length === 0) return void 0;
|
|
5688
|
+
for (const tool of body.tools) {
|
|
5689
|
+
if (!tool || typeof tool !== "object") continue;
|
|
5690
|
+
const type = tool.type;
|
|
5691
|
+
if (typeof type !== "string" || !type.startsWith("advisor_")) continue;
|
|
5692
|
+
const model = tool.model;
|
|
5693
|
+
if (typeof model !== "string") return "the native Advisor tool omitted its fixed model";
|
|
5694
|
+
if (stripTrailingOneMSuffix(model).base !== CHEAPEST_PROFILE_ADVISOR_CLIENT_MODEL) return `the native Advisor tool requested ${JSON.stringify(model)} instead of ${JSON.stringify(CHEAPEST_PROFILE_ADVISOR_CLIENT_MODEL)}`;
|
|
5695
|
+
}
|
|
5696
|
+
}
|
|
5542
5697
|
function stripAdvisorTool(rawBody) {
|
|
5543
5698
|
let body;
|
|
5544
5699
|
try {
|
|
@@ -5674,18 +5829,22 @@ async function handleCompletion(c) {
|
|
|
5674
5829
|
const fastProfileRequest = identity.launch?.profileId === "fast";
|
|
5675
5830
|
const maxProfileRequest = identity.launch?.profileId === "max";
|
|
5676
5831
|
const cheapProfileRequest = identity.launch?.profileId === "cheap" || identity.launch?.profileId === "cheap1m";
|
|
5832
|
+
const cheapestProfileRequest = identity.launch?.profileId === "cheapest";
|
|
5677
5833
|
const subagentRequest = Boolean(c.req.header("x-claude-code-agent-id"));
|
|
5678
5834
|
const fastSubagentRequest = fastProfileRequest && subagentRequest;
|
|
5679
5835
|
const maxSubagentRequest = maxProfileRequest && subagentRequest;
|
|
5680
5836
|
const cheapSubagentRequest = cheapProfileRequest && subagentRequest;
|
|
5837
|
+
const cheapestSubagentRequest = cheapestProfileRequest && subagentRequest;
|
|
5681
5838
|
const fastLeadAdvisor = fastProfileRequest && !fastSubagentRequest;
|
|
5682
5839
|
const maxLeadAdvisor = maxProfileRequest && !maxSubagentRequest;
|
|
5683
5840
|
const cheapLeadAdvisor = cheapProfileRequest && !cheapSubagentRequest;
|
|
5684
|
-
const
|
|
5841
|
+
const cheapestLeadAdvisor = cheapestProfileRequest && !cheapestSubagentRequest;
|
|
5842
|
+
const advisorEnabled = advisorRequested && !fastSubagentRequest && !maxSubagentRequest && !cheapSubagentRequest && !cheapestSubagentRequest;
|
|
5685
5843
|
const fastAdvisorEnabled = fastLeadAdvisor && advisorRequested && hasNonEmptyTools(rawBody);
|
|
5686
5844
|
const maxAdvisorEnabled = maxLeadAdvisor && advisorRequested && hasNonEmptyTools(rawBody);
|
|
5687
5845
|
const cheapAdvisorEnabled = cheapLeadAdvisor && advisorRequested && hasNonEmptyTools(rawBody);
|
|
5688
|
-
const
|
|
5846
|
+
const cheapestAdvisorEnabled = cheapestLeadAdvisor && advisorRequested && hasNonEmptyTools(rawBody);
|
|
5847
|
+
const advisorBehaviorEnabled = fastLeadAdvisor ? fastAdvisorEnabled : cheapLeadAdvisor ? cheapAdvisorEnabled : cheapestLeadAdvisor ? cheapestAdvisorEnabled : maxLeadAdvisor ? maxAdvisorEnabled : advisorEnabled;
|
|
5689
5848
|
let fastAdvisorChoice;
|
|
5690
5849
|
let maxAdvisorChoice;
|
|
5691
5850
|
if (maxAdvisorEnabled) {
|
|
@@ -5746,10 +5905,31 @@ async function handleCompletion(c) {
|
|
|
5746
5905
|
}, 503);
|
|
5747
5906
|
}
|
|
5748
5907
|
}
|
|
5908
|
+
if (cheapestAdvisorEnabled) {
|
|
5909
|
+
const mismatch = cheapestAdvisorMetadataMismatch(rawBody);
|
|
5910
|
+
if (mismatch) return c.json({
|
|
5911
|
+
type: "error",
|
|
5912
|
+
error: {
|
|
5913
|
+
type: "invalid_request_error",
|
|
5914
|
+
message: `Cheapest Advisor model mismatch: ${mismatch}. Run \`/advisor ${CHEAPEST_PROFILE_ADVISOR_CLIENT_MODEL}\` to restore the fixed cheapest profile, or relaunch with \`github-router claude -m cheapest\`.`
|
|
5915
|
+
}
|
|
5916
|
+
}, 400);
|
|
5917
|
+
try {
|
|
5918
|
+
fastAdvisorChoice = resolveCheapestAdvisorModel();
|
|
5919
|
+
} catch (error) {
|
|
5920
|
+
return c.json({
|
|
5921
|
+
type: "error",
|
|
5922
|
+
error: {
|
|
5923
|
+
type: "api_error",
|
|
5924
|
+
message: error instanceof Error ? error.message : String(error)
|
|
5925
|
+
}
|
|
5926
|
+
}, 503);
|
|
5927
|
+
}
|
|
5928
|
+
}
|
|
5749
5929
|
const fastPreprocess = preprocessFastRequest(rawBody, identity.launch, subagentRequest);
|
|
5750
5930
|
if (fastPreprocess.retiredAlias || fastPreprocess.rejectedAlias || fastPreprocess.rejectedModel) {
|
|
5751
5931
|
const profileId = identity.launch?.profileId;
|
|
5752
|
-
const profileLabel = profileId === "cheap" || profileId === "cheap1m" ? "cheap" : "fast";
|
|
5932
|
+
const profileLabel = profileId === "cheap" || profileId === "cheap1m" ? "cheap" : profileId === "cheapest" ? "cheapest" : "fast";
|
|
5753
5933
|
const message = fastPreprocess.retiredAlias ? `Router-owned model alias ${JSON.stringify(fastPreprocess.retiredAlias)} belongs to a retired Fast role and is no longer valid. Relaunch or select a current Fast role.` : profileId === "max" ? maxRequestError(fastPreprocess) ?? "Invalid max request" : fastPreprocess.rejectedAlias ? `Router-owned model alias ${JSON.stringify(fastPreprocess.rejectedAlias)} is valid only for an authenticated -m ${profileLabel} launch.` : `Model ${JSON.stringify(fastPreprocess.rejectedModel)} is outside the fixed -m ${profileLabel} model set.`;
|
|
5754
5934
|
return c.json({
|
|
5755
5935
|
type: "error",
|
|
@@ -5796,7 +5976,7 @@ async function handleCompletion(c) {
|
|
|
5796
5976
|
parsedBase = JSON.parse(promptWindowBody);
|
|
5797
5977
|
} catch {}
|
|
5798
5978
|
const wantsStream = parsedBase?.stream === true;
|
|
5799
|
-
if ((fastAdvisorEnabled || cheapAdvisorEnabled || maxAdvisorEnabled) && wantsStream) {
|
|
5979
|
+
if ((fastAdvisorEnabled || cheapAdvisorEnabled || cheapestAdvisorEnabled || maxAdvisorEnabled) && wantsStream) {
|
|
5800
5980
|
const initialConversation = Array.isArray(parsedBase.messages) ? parsedBase.messages : [];
|
|
5801
5981
|
const parsedInitial = parseAnthropicRequest(parsedBase, modelId, selectedModel);
|
|
5802
5982
|
const translatedAdvisorAborter = new AbortController();
|
|
@@ -5819,7 +5999,7 @@ async function handleCompletion(c) {
|
|
|
5819
5999
|
effort: maxAdvisorChoice.effort,
|
|
5820
6000
|
escalated: false,
|
|
5821
6001
|
fastProfile: false
|
|
5822
|
-
} : cheapAdvisorEnabled ? {
|
|
6002
|
+
} : cheapAdvisorEnabled || cheapestAdvisorEnabled ? {
|
|
5823
6003
|
model: fastAdvisorChoice.model,
|
|
5824
6004
|
effort: resolveAdvisorEffort(rawBody, fastAdvisorChoice.model, true),
|
|
5825
6005
|
escalated: fastAdvisorChoice.escalated,
|
|
@@ -5839,7 +6019,7 @@ async function handleCompletion(c) {
|
|
|
5839
6019
|
advisorEscalated: advisorChoice.escalated,
|
|
5840
6020
|
advisorFastProfile: advisorChoice.fastProfile,
|
|
5841
6021
|
advisorMaxProfile: maxAdvisorEnabled,
|
|
5842
|
-
advisorCheapProfile: cheapAdvisorEnabled,
|
|
6022
|
+
advisorCheapProfile: cheapAdvisorEnabled || cheapestAdvisorEnabled,
|
|
5843
6023
|
advisorEffort: advisorChoice.effort,
|
|
5844
6024
|
externalAborter: translatedAdvisorAborter,
|
|
5845
6025
|
continueTurn: makeShimContinueTurn(endpoint, {
|
|
@@ -5962,10 +6142,10 @@ async function handleCompletion(c) {
|
|
|
5962
6142
|
requestHeaders,
|
|
5963
6143
|
advisorModel: advisorChoice.model,
|
|
5964
6144
|
advisorEscalated: advisorChoice.escalated,
|
|
5965
|
-
advisorFastProfile: fastLeadAdvisor || cheapLeadAdvisor,
|
|
6145
|
+
advisorFastProfile: fastLeadAdvisor || cheapLeadAdvisor || cheapestLeadAdvisor,
|
|
5966
6146
|
advisorMaxProfile: maxAdvisorEnabled,
|
|
5967
|
-
advisorCheapProfile: cheapLeadAdvisor,
|
|
5968
|
-
advisorEffort: maxAdvisorChoice ? maxAdvisorChoice.effort : resolveAdvisorEffort(rawBody, advisorChoice.model, fastLeadAdvisor || cheapLeadAdvisor),
|
|
6147
|
+
advisorCheapProfile: cheapLeadAdvisor || cheapestLeadAdvisor,
|
|
6148
|
+
advisorEffort: maxAdvisorChoice ? maxAdvisorChoice.effort : resolveAdvisorEffort(rawBody, advisorChoice.model, fastLeadAdvisor || cheapLeadAdvisor || cheapestLeadAdvisor),
|
|
5969
6149
|
externalAborter: advisorAborter
|
|
5970
6150
|
}), {
|
|
5971
6151
|
status: response.status,
|
|
@@ -7113,6 +7293,7 @@ async function setupAndServe(options) {
|
|
|
7113
7293
|
state.showToken = options.showToken;
|
|
7114
7294
|
state.extendedBetas = options.extendedBetas;
|
|
7115
7295
|
state.browseEnabled = options.browseEnabled || process.env.GH_ROUTER_ENABLE_BROWSE === "1";
|
|
7296
|
+
state.searchEnabled = options.searchEnabled || process.env.GH_ROUTER_ENABLE_SEMANTIC_SEARCH === "1";
|
|
7116
7297
|
state.fleetEnabled = options.fleetEnabled || process.env.GH_ROUTER_ENABLE_FLEET === "1";
|
|
7117
7298
|
state.agentsEnabled = options.agentsEnabled || process.env.GH_ROUTER_ENABLE_AGENTS === "1";
|
|
7118
7299
|
state.powerBrowseEnabled = options.powerBrowseEnabled || process.env.GH_ROUTER_ENABLE_POWER_BROWSE === "1";
|
|
@@ -7261,6 +7442,11 @@ const sharedServerArgs = {
|
|
|
7261
7442
|
type: "boolean",
|
|
7262
7443
|
default: true,
|
|
7263
7444
|
description: "Update github-router itself to the latest npm version on launch (throttled once/hour). Best-effort and non-blocking: the proxy serves immediately and a detached updater applies the new version after this process exits (it takes effect on the NEXT launch; the running process keeps its current build). Disable with --no-self-update or GH_ROUTER_NO_SELF_UPDATE=1. Skipped silently if npm/network unavailable."
|
|
7445
|
+
},
|
|
7446
|
+
search: {
|
|
7447
|
+
type: "boolean",
|
|
7448
|
+
default: false,
|
|
7449
|
+
description: "Enable ColBERT/colgrep semantic code search (meaning-ranked `code` tool results over a per-workspace index, with transparent lexical fallback). Off by default; the `code` tool is lexical-only unless this is set. Can also be enabled with GH_ROUTER_ENABLE_SEMANTIC_SEARCH=1. GH_ROUTER_DISABLE_SEMANTIC_SEARCH=1 hard-disables (wins over --search, for tests)."
|
|
7264
7450
|
}
|
|
7265
7451
|
};
|
|
7266
7452
|
const allowedAccountTypes = /* @__PURE__ */ new Set([
|
|
@@ -7302,7 +7488,8 @@ function parseSharedArgs(args) {
|
|
|
7302
7488
|
fleetEnabled: args.fleet,
|
|
7303
7489
|
agentsEnabled: args.agents,
|
|
7304
7490
|
powerBrowseEnabled: args["power-browse"],
|
|
7305
|
-
humanlikeEnabled: args.humanlike
|
|
7491
|
+
humanlikeEnabled: args.humanlike,
|
|
7492
|
+
searchEnabled: args.search
|
|
7306
7493
|
};
|
|
7307
7494
|
}
|
|
7308
7495
|
/**
|
|
@@ -7374,23 +7561,24 @@ function getClaudeCodeEnvVars(serverUrl, model, launchProfileId = "standard", pi
|
|
|
7374
7561
|
if (process.env.MCP_TOOL_TIMEOUT === void 0) vars.MCP_TOOL_TIMEOUT = mcpToolTimeoutMs;
|
|
7375
7562
|
const isFastProfile = launchProfileId === "fast";
|
|
7376
7563
|
const isMaxProfile = launchProfileId === "max";
|
|
7377
|
-
const isCheapProfile = launchProfileId === "cheap" || launchProfileId === "cheap1m";
|
|
7564
|
+
const isCheapProfile = launchProfileId === "cheap" || launchProfileId === "cheap1m" || launchProfileId === "cheapest";
|
|
7565
|
+
const routerWinsTiers = isFastProfile || isCheapProfile;
|
|
7378
7566
|
const smallFastModel = isMaxProfile ? MAX_LUNA_HIGH_ALIAS_ID : isFastProfile ? LUNA_HAIKU_ALIAS_ID : isCheapProfile ? LUNA_HAIKU_ALIAS_ID : isBudgetClaudeLead(model) && (state.models?.data?.some((m) => m.id === "claude-haiku-4.5") ?? false) ? BUDGET_SMALL_FAST_SLUG : "claude-sonnet-5";
|
|
7379
|
-
if (process.env.ANTHROPIC_SMALL_FAST_MODEL === void 0) vars.ANTHROPIC_SMALL_FAST_MODEL = (isFastProfile || isMaxProfile) && !isCheapProfile ? oneMSuffixForAlias(smallFastModel) : smallFastModel;
|
|
7567
|
+
if (process.env.ANTHROPIC_SMALL_FAST_MODEL === void 0 || routerWinsTiers) vars.ANTHROPIC_SMALL_FAST_MODEL = (isFastProfile || isMaxProfile) && !isCheapProfile ? oneMSuffixForAlias(smallFastModel) : smallFastModel;
|
|
7380
7568
|
const seedTierRow = (modelKey, nameKey, bareSlug) => {
|
|
7381
7569
|
if (process.env[modelKey] !== void 0) return;
|
|
7382
7570
|
vars[modelKey] = withOneMSuffixForLead(bareSlug);
|
|
7383
7571
|
if (process.env[nameKey] === void 0) vars[nameKey] = bareSlug;
|
|
7384
7572
|
};
|
|
7385
|
-
const seedFastAliasTierRow = (modelKey, nameKey, aliasId, displayName) => {
|
|
7386
|
-
if (process.env[modelKey] !== void 0) return;
|
|
7573
|
+
const seedFastAliasTierRow = (modelKey, nameKey, aliasId, displayName, force = false) => {
|
|
7574
|
+
if (!force && process.env[modelKey] !== void 0) return;
|
|
7387
7575
|
vars[modelKey] = oneMSuffixForAlias(aliasId);
|
|
7388
|
-
if (process.env[nameKey] === void 0) vars[nameKey] = displayName;
|
|
7576
|
+
if (force || process.env[nameKey] === void 0) vars[nameKey] = displayName;
|
|
7389
7577
|
};
|
|
7390
|
-
const seedCheapAliasTierRow = (modelKey, nameKey, aliasId, displayName) => {
|
|
7391
|
-
if (process.env[modelKey] !== void 0) return;
|
|
7578
|
+
const seedCheapAliasTierRow = (modelKey, nameKey, aliasId, displayName, force = false) => {
|
|
7579
|
+
if (!force && process.env[modelKey] !== void 0) return;
|
|
7392
7580
|
vars[modelKey] = aliasId;
|
|
7393
|
-
if (process.env[nameKey] === void 0) vars[nameKey] = displayName;
|
|
7581
|
+
if (force || process.env[nameKey] === void 0) vars[nameKey] = displayName;
|
|
7394
7582
|
};
|
|
7395
7583
|
if (isMaxProfile) {
|
|
7396
7584
|
const seedMaxRow = (modelKey, nameKey, id) => {
|
|
@@ -7406,26 +7594,26 @@ function getClaudeCodeEnvVars(serverUrl, model, launchProfileId = "standard", pi
|
|
|
7406
7594
|
if (process.env.ANTHROPIC_CUSTOM_MODEL_OPTION_NAME === void 0) vars.ANTHROPIC_CUSTOM_MODEL_OPTION_NAME = "GPT-5.6 Sol";
|
|
7407
7595
|
}
|
|
7408
7596
|
} else if (isCheapProfile) {
|
|
7409
|
-
seedCheapAliasTierRow("ANTHROPIC_DEFAULT_SONNET_MODEL", "ANTHROPIC_DEFAULT_SONNET_MODEL_NAME", LUNA_SONNET_ALIAS_ID, "GPT-5.6 Luna (xhigh)");
|
|
7410
|
-
seedCheapAliasTierRow("ANTHROPIC_DEFAULT_HAIKU_MODEL", "ANTHROPIC_DEFAULT_HAIKU_MODEL_NAME", LUNA_HAIKU_ALIAS_ID, "GPT-5.6 Luna (high)");
|
|
7597
|
+
seedCheapAliasTierRow("ANTHROPIC_DEFAULT_SONNET_MODEL", "ANTHROPIC_DEFAULT_SONNET_MODEL_NAME", LUNA_SONNET_ALIAS_ID, "GPT-5.6 Luna (xhigh)", routerWinsTiers);
|
|
7598
|
+
seedCheapAliasTierRow("ANTHROPIC_DEFAULT_HAIKU_MODEL", "ANTHROPIC_DEFAULT_HAIKU_MODEL_NAME", LUNA_HAIKU_ALIAS_ID, "GPT-5.6 Luna (high)", routerWinsTiers);
|
|
7411
7599
|
const cheapAliasCapabilities = "effort,xhigh_effort,max_effort,thinking,adaptive_thinking,interleaved_thinking";
|
|
7412
|
-
if (process.env.ANTHROPIC_DEFAULT_SONNET_MODEL_SUPPORTED_CAPABILITIES === void 0) vars.ANTHROPIC_DEFAULT_SONNET_MODEL_SUPPORTED_CAPABILITIES = cheapAliasCapabilities;
|
|
7413
|
-
if (process.env.ANTHROPIC_DEFAULT_HAIKU_MODEL_SUPPORTED_CAPABILITIES === void 0) vars.ANTHROPIC_DEFAULT_HAIKU_MODEL_SUPPORTED_CAPABILITIES = cheapAliasCapabilities;
|
|
7414
|
-
if (process.env.ANTHROPIC_CUSTOM_MODEL_OPTION === void 0) {
|
|
7600
|
+
if (routerWinsTiers || process.env.ANTHROPIC_DEFAULT_SONNET_MODEL_SUPPORTED_CAPABILITIES === void 0) vars.ANTHROPIC_DEFAULT_SONNET_MODEL_SUPPORTED_CAPABILITIES = cheapAliasCapabilities;
|
|
7601
|
+
if (routerWinsTiers || process.env.ANTHROPIC_DEFAULT_HAIKU_MODEL_SUPPORTED_CAPABILITIES === void 0) vars.ANTHROPIC_DEFAULT_HAIKU_MODEL_SUPPORTED_CAPABILITIES = cheapAliasCapabilities;
|
|
7602
|
+
if (routerWinsTiers || process.env.ANTHROPIC_CUSTOM_MODEL_OPTION === void 0) {
|
|
7415
7603
|
vars.ANTHROPIC_CUSTOM_MODEL_OPTION = LUNA_DRIVER_ALIAS_ID;
|
|
7416
|
-
if (process.env.ANTHROPIC_CUSTOM_MODEL_OPTION_NAME === void 0) vars.ANTHROPIC_CUSTOM_MODEL_OPTION_NAME = "GPT-5.6 Luna (max)";
|
|
7417
|
-
if (process.env.ANTHROPIC_CUSTOM_MODEL_OPTION_SUPPORTED_CAPABILITIES === void 0) vars.ANTHROPIC_CUSTOM_MODEL_OPTION_SUPPORTED_CAPABILITIES = cheapAliasCapabilities;
|
|
7604
|
+
if (routerWinsTiers || process.env.ANTHROPIC_CUSTOM_MODEL_OPTION_NAME === void 0) vars.ANTHROPIC_CUSTOM_MODEL_OPTION_NAME = "GPT-5.6 Luna (max)";
|
|
7605
|
+
if (routerWinsTiers || process.env.ANTHROPIC_CUSTOM_MODEL_OPTION_SUPPORTED_CAPABILITIES === void 0) vars.ANTHROPIC_CUSTOM_MODEL_OPTION_SUPPORTED_CAPABILITIES = cheapAliasCapabilities;
|
|
7418
7606
|
}
|
|
7419
7607
|
} else if (isFastProfile) {
|
|
7420
|
-
seedFastAliasTierRow("ANTHROPIC_DEFAULT_SONNET_MODEL", "ANTHROPIC_DEFAULT_SONNET_MODEL_NAME", LUNA_SONNET_ALIAS_ID, "GPT-5.6 Luna (xhigh)");
|
|
7421
|
-
seedFastAliasTierRow("ANTHROPIC_DEFAULT_HAIKU_MODEL", "ANTHROPIC_DEFAULT_HAIKU_MODEL_NAME", LUNA_HAIKU_ALIAS_ID, "GPT-5.6 Luna (high)");
|
|
7608
|
+
seedFastAliasTierRow("ANTHROPIC_DEFAULT_SONNET_MODEL", "ANTHROPIC_DEFAULT_SONNET_MODEL_NAME", LUNA_SONNET_ALIAS_ID, "GPT-5.6 Luna (xhigh)", routerWinsTiers);
|
|
7609
|
+
seedFastAliasTierRow("ANTHROPIC_DEFAULT_HAIKU_MODEL", "ANTHROPIC_DEFAULT_HAIKU_MODEL_NAME", LUNA_HAIKU_ALIAS_ID, "GPT-5.6 Luna (high)", routerWinsTiers);
|
|
7422
7610
|
const fastAliasCapabilities = "effort,xhigh_effort,max_effort,thinking,adaptive_thinking,interleaved_thinking";
|
|
7423
|
-
if (process.env.ANTHROPIC_DEFAULT_SONNET_MODEL_SUPPORTED_CAPABILITIES === void 0) vars.ANTHROPIC_DEFAULT_SONNET_MODEL_SUPPORTED_CAPABILITIES = fastAliasCapabilities;
|
|
7424
|
-
if (process.env.ANTHROPIC_DEFAULT_HAIKU_MODEL_SUPPORTED_CAPABILITIES === void 0) vars.ANTHROPIC_DEFAULT_HAIKU_MODEL_SUPPORTED_CAPABILITIES = fastAliasCapabilities;
|
|
7425
|
-
if (process.env.ANTHROPIC_CUSTOM_MODEL_OPTION === void 0) {
|
|
7611
|
+
if (routerWinsTiers || process.env.ANTHROPIC_DEFAULT_SONNET_MODEL_SUPPORTED_CAPABILITIES === void 0) vars.ANTHROPIC_DEFAULT_SONNET_MODEL_SUPPORTED_CAPABILITIES = fastAliasCapabilities;
|
|
7612
|
+
if (routerWinsTiers || process.env.ANTHROPIC_DEFAULT_HAIKU_MODEL_SUPPORTED_CAPABILITIES === void 0) vars.ANTHROPIC_DEFAULT_HAIKU_MODEL_SUPPORTED_CAPABILITIES = fastAliasCapabilities;
|
|
7613
|
+
if (routerWinsTiers || process.env.ANTHROPIC_CUSTOM_MODEL_OPTION === void 0) {
|
|
7426
7614
|
vars.ANTHROPIC_CUSTOM_MODEL_OPTION = oneMSuffixForAlias(LUNA_DRIVER_ALIAS_ID);
|
|
7427
|
-
if (process.env.ANTHROPIC_CUSTOM_MODEL_OPTION_NAME === void 0) vars.ANTHROPIC_CUSTOM_MODEL_OPTION_NAME = "GPT-5.6 Luna (max)";
|
|
7428
|
-
if (process.env.ANTHROPIC_CUSTOM_MODEL_OPTION_SUPPORTED_CAPABILITIES === void 0) vars.ANTHROPIC_CUSTOM_MODEL_OPTION_SUPPORTED_CAPABILITIES = fastAliasCapabilities;
|
|
7615
|
+
if (routerWinsTiers || process.env.ANTHROPIC_CUSTOM_MODEL_OPTION_NAME === void 0) vars.ANTHROPIC_CUSTOM_MODEL_OPTION_NAME = "GPT-5.6 Luna (max)";
|
|
7616
|
+
if (routerWinsTiers || process.env.ANTHROPIC_CUSTOM_MODEL_OPTION_SUPPORTED_CAPABILITIES === void 0) vars.ANTHROPIC_CUSTOM_MODEL_OPTION_SUPPORTED_CAPABILITIES = fastAliasCapabilities;
|
|
7429
7617
|
}
|
|
7430
7618
|
} else {
|
|
7431
7619
|
seedTierRow("ANTHROPIC_DEFAULT_SONNET_MODEL", "ANTHROPIC_DEFAULT_SONNET_MODEL_NAME", "claude-sonnet-5");
|
|
@@ -7522,6 +7710,6 @@ function getCodexEnvVars(serverUrl) {
|
|
|
7522
7710
|
return vars;
|
|
7523
7711
|
}
|
|
7524
7712
|
//#endregion
|
|
7525
|
-
export {
|
|
7713
|
+
export { validateMaxProfileLaunch as C, updateClaude as E, validateFastProfilePrerequisites as S, checkClaudeVersion as T, profileDescriptor as _, sharedServerArgs as a, validateCheapProfilePrerequisites as b, stopKeepAwake as c, enableFileLogging as d, LUNA_SCOUT_ALIAS_ID as f, formatFastPrerequisiteFailure as g, formatCheapestPrerequisiteFailure as h, setupAndServe as i, injectModelPickerSettingsFile as l, formatCheapPrerequisiteFailure as m, getCodexEnvVars as n, LAUNCH_SECRET_HEADER as o, formatCheap1mPrerequisiteFailure as p, parseSharedArgs as r, startKeepAwake as s, getClaudeCodeEnvVars as t, listModelsForEndpoint as u, resolveLaunchProfile as v, runSelfUpdate as w, validateCheapestProfilePrerequisites as x, validateCheap1mProfilePrerequisites as y };
|
|
7526
7714
|
|
|
7527
|
-
//# sourceMappingURL=server-setup-
|
|
7715
|
+
//# sourceMappingURL=server-setup-0PaS4m2B.js.map
|