github-router 0.3.282 → 0.3.288
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/README.md +8 -5
- package/dist/{attribution-settings-srL3gBR9.js → attribution-settings-CofaqSzw.js} +54 -15
- package/dist/attribution-settings-CofaqSzw.js.map +1 -0
- package/dist/{auth-VUL2Zxvw.js → auth-DG4vh8-F.js} +3 -3
- package/dist/{auth-VUL2Zxvw.js.map → auth-DG4vh8-F.js.map} +1 -1
- package/dist/browser-ext/manifest.json +1 -1
- package/dist/{check-usage-CcLdFPGr.js → check-usage-BqN7mBYv.js} +4 -4
- package/dist/{check-usage-CcLdFPGr.js.map → check-usage-BqN7mBYv.js.map} +1 -1
- package/dist/{claude-DJQjA5oQ.js → claude-CoZKRNB8.js} +25 -20
- package/dist/claude-CoZKRNB8.js.map +1 -0
- package/dist/{codex-BAXemWpJ.js → codex-y2OyLIdv.js} +5 -5
- package/dist/{codex-BAXemWpJ.js.map → codex-y2OyLIdv.js.map} +1 -1
- package/dist/{debug-CtzYWxpJ.js → debug-B5TjPTTH.js} +2 -2
- package/dist/{debug-CtzYWxpJ.js.map → debug-B5TjPTTH.js.map} +1 -1
- package/dist/engine-B5nVGH4b.js +2 -0
- package/dist/{gate-discovery-BwtiYKvW.js → gate-discovery-LQZ-enJa.js} +5 -5
- package/dist/{gate-discovery-BwtiYKvW.js.map → gate-discovery-LQZ-enJa.js.map} +1 -1
- package/dist/{get-copilot-usage-B-EDAqQb.js → get-copilot-usage-BjA0nyGR.js} +2 -2
- package/dist/{get-copilot-usage-B-EDAqQb.js.map → get-copilot-usage-BjA0nyGR.js.map} +1 -1
- package/dist/{internal-artifact-open-Dj5Nlq0L.js → internal-artifact-open-BskmUpnb.js} +2 -2
- package/dist/{internal-artifact-open-Dj5Nlq0L.js.map → internal-artifact-open-BskmUpnb.js.map} +1 -1
- package/dist/{internal-first-mate-guard-DMgHg2s6.js → internal-first-mate-guard-5XEHMaqy.js} +3 -3
- package/dist/{internal-first-mate-guard-DMgHg2s6.js.map → internal-first-mate-guard-5XEHMaqy.js.map} +1 -1
- package/dist/{internal-first-mate-guard-CQdXWjNz.js → internal-first-mate-guard-DHDQ6hFz.js} +1 -1
- package/dist/{internal-plan-review-DRFHET_B.js → internal-plan-review-BUuMx4ku.js} +3 -3
- package/dist/{internal-plan-review-DRFHET_B.js.map → internal-plan-review-BUuMx4ku.js.map} +1 -1
- package/dist/{internal-prompt-submit-f1LR2P2G.js → internal-prompt-submit-CQQ15xdO.js} +4 -4
- package/dist/{internal-prompt-submit-f1LR2P2G.js.map → internal-prompt-submit-CQQ15xdO.js.map} +1 -1
- package/dist/{internal-session-bind-DhZhxJ3T.js → internal-session-bind-D04W2yWI.js} +2 -2
- package/dist/{internal-session-bind-DhZhxJ3T.js.map → internal-session-bind-D04W2yWI.js.map} +1 -1
- package/dist/{internal-stop-hook-514RJeHO.js → internal-stop-hook-DSbaDb_m.js} +5 -5
- package/dist/{internal-stop-hook-514RJeHO.js.map → internal-stop-hook-DSbaDb_m.js.map} +1 -1
- package/dist/{internal-stop-review-BBsLcbPG.js → internal-stop-review-CdByyJLc.js} +2 -2
- package/dist/{internal-stop-review-BBsLcbPG.js.map → internal-stop-review-CdByyJLc.js.map} +1 -1
- package/dist/{internal-worker-guard-VucpClSi.js → internal-worker-guard-BIPN6Rv9.js} +2 -2
- package/dist/{internal-worker-guard-VucpClSi.js.map → internal-worker-guard-BIPN6Rv9.js.map} +1 -1
- package/dist/{internal-workspace-header-OYgHEnFt.js → internal-workspace-header-BKqejstG.js} +2 -2
- package/dist/{internal-workspace-header-OYgHEnFt.js.map → internal-workspace-header-BKqejstG.js.map} +1 -1
- package/dist/lifecycle-BTodQvn4.js +2 -0
- package/dist/lifecycle-C7JYNz-F.js +2 -0
- package/dist/{lifecycle-B7CHqKlF.js → lifecycle-DbM29FLK.js} +2 -2
- package/dist/{lifecycle-B7CHqKlF.js.map → lifecycle-DbM29FLK.js.map} +1 -1
- package/dist/{lifecycle-D-rL81tT.js → lifecycle-SXaWssN9.js} +2 -2
- package/dist/{lifecycle-D-rL81tT.js.map → lifecycle-SXaWssN9.js.map} +1 -1
- package/dist/main.js +17 -17
- package/dist/{mcp-workspace-header-ucs2SDST.js → mcp-workspace-header-DRCCWlOi.js} +2 -2
- package/dist/{mcp-workspace-header-ucs2SDST.js.map → mcp-workspace-header-DRCCWlOi.js.map} +1 -1
- package/dist/{models-C16mBK2M.js → models-Dz8d_SnI.js} +3 -3
- package/dist/{models-C16mBK2M.js.map → models-Dz8d_SnI.js.map} +1 -1
- package/dist/{orchestration-CtM6FYNx.js → orchestration-BrJwZxMN.js} +2 -2
- package/dist/{orchestration-CtM6FYNx.js.map → orchestration-BrJwZxMN.js.map} +1 -1
- package/dist/paths-CTr59UC6.js +2 -0
- package/dist/{paths-wLC0InjX.js → paths-D7_SAaIQ.js} +4 -4
- package/dist/{paths-wLC0InjX.js.map → paths-D7_SAaIQ.js.map} +1 -1
- package/dist/{peer-mcp-personas-l4P4s1fK.js → peer-mcp-personas-B5Wp6wIn.js} +837 -147
- package/dist/peer-mcp-personas-B5Wp6wIn.js.map +1 -0
- package/dist/{plan-review-hook-Lf9ISdF6.js → plan-review-hook-CVZsG9MZ.js} +3 -3
- package/dist/{plan-review-hook-Lf9ISdF6.js.map → plan-review-hook-CVZsG9MZ.js.map} +1 -1
- package/dist/{prompt-submit-hook-BlijaOn7.js → prompt-submit-hook-BW92FX2D.js} +3 -3
- package/dist/{prompt-submit-hook-BlijaOn7.js.map → prompt-submit-hook-BW92FX2D.js.map} +1 -1
- package/dist/{provision-DlT34zcf.js → provision-CUqPki1z.js} +4 -4
- package/dist/{provision-DlT34zcf.js.map → provision-CUqPki1z.js.map} +1 -1
- package/dist/{self-invocation-CKMjcA5F.js → self-invocation-CP_SOkrr.js} +2 -2
- package/dist/{self-invocation-CKMjcA5F.js.map → self-invocation-CP_SOkrr.js.map} +1 -1
- package/dist/{serve-orGUartp.js → serve-BASqoXb3.js} +42 -29
- package/dist/serve-BASqoXb3.js.map +1 -0
- package/dist/{server-setup-BRBe8gW4.js → server-setup-D5hilphf.js} +33 -213
- package/dist/server-setup-D5hilphf.js.map +1 -0
- package/dist/{start-sutbbkwc.js → start-Rfim4TeF.js} +3 -3
- package/dist/{start-sutbbkwc.js.map → start-Rfim4TeF.js.map} +1 -1
- package/dist/{stop-gate-hook-DgJ6sW8N.js → stop-gate-hook-DriRc9xN.js} +3 -3
- package/dist/{stop-gate-hook-DgJ6sW8N.js.map → stop-gate-hook-DriRc9xN.js.map} +1 -1
- package/dist/{stop-gate-policy-DG5yYWGn.js → stop-gate-policy-DMPanpoR.js} +2 -2
- package/dist/{stop-gate-policy-DG5yYWGn.js.map → stop-gate-policy-DMPanpoR.js.map} +1 -1
- package/dist/{token-CnlB0884.js → token-BGCjZwtj.js} +2 -2
- package/dist/{token-CnlB0884.js.map → token-BGCjZwtj.js.map} +1 -1
- package/dist/{worker-dispatch-4O3IWtP0.js → worker-dispatch-BCTMyNE-.js} +9 -5
- package/dist/{worker-dispatch-4O3IWtP0.js.map → worker-dispatch-BCTMyNE-.js.map} +1 -1
- package/package.json +1 -1
- package/dist/attribution-settings-srL3gBR9.js.map +0 -1
- package/dist/claude-DJQjA5oQ.js.map +0 -1
- package/dist/engine-BvLgh1QI.js +0 -2
- package/dist/lifecycle-CbmHMMSD.js +0 -2
- package/dist/lifecycle-DTcZwa7U.js +0 -2
- package/dist/paths-CV9K7Xqm.js +0 -2
- package/dist/peer-mcp-personas-l4P4s1fK.js.map +0 -1
- package/dist/serve-orGUartp.js.map +0 -1
- package/dist/server-setup-BRBe8gW4.js.map +0 -1
|
@@ -1,8 +1,8 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { $ as handleMcpDelete, $t as generateRandomPort, At as readResponseBodyCapped, B as rememberThinkingHistoryRepair, Ct as getTokenCount, Dt as createResponses, Et as resolveMcpToolTimeoutMs, F as injectAdvisorTool, G as isControllerClosedError, H as repairRejectedThinkingHistory, I as isAdvisorRequested, J as relayAnthropicStream, K as logStreamError, Kt as BUDGET_SMALL_FAST_SLUG, L as resolveAdvisorEffort, M as ADVISOR_INTERNAL_TOOL_NAME, N as ADVISOR_TOOL_INSTRUCTIONS, Ot as createChatCompletions, P as buildAdvisorStream, Q as clampEffort, Qt as UPSTREAM_INACTIVITY_TIMEOUT_MS, R as resolveAdvisorModel, St as createMessages, T as toolbeltEnabled, Tt as warnOnTokenPriceDrift, U as buildAnthropicErrorEvent, V as repairKnownThinkingHistory, W as buildOpenAIErrorEvent, Wt as toolbeltPathOverride, X as UNKNOWN_EFFORT_ANCHOR, Y as EFFORT_ORDER, Z as bucketEffort, Zt as UPSTREAM_FETCH_TIMEOUT_MS, an as classifyMessagesRoute, bt as shimDefaultsToXhigh, cn as withInstallLock, en as isBudgetClaudeLead, et as handleMcpPost, in as upstreamMaxConnections, j as searchWeb, jt as parseJsonOrDiagnose, kt as MAX_RESPONSE_BODY_BYTES, nt as agentToolsEnabled, on as withOneMSuffix, pt as resolveGeminiReviewModel, q as readIteratorWithTimeout, r as assertMcpToolSurfaceConsistent, rn as upstreamAllowH2, sn as withOneMSuffixForLead, wt as assembleResponsesPayload, xt as countTokens, z as formatThinkingRepairDecline, zt as provisionTreeSitterAssets } from "./peer-mcp-personas-B5Wp6wIn.js";
|
|
2
2
|
import { t as getPackageVersion } from "./version-C8x2hQrZ.js";
|
|
3
|
-
import { i as ensurePaths, t as PATHS } from "./paths-
|
|
4
|
-
import { A as state, 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-
|
|
5
|
-
import { t as getCopilotUsage } from "./get-copilot-usage-
|
|
3
|
+
import { i as ensurePaths, t as PATHS } from "./paths-D7_SAaIQ.js";
|
|
4
|
+
import { A as state, 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-BGCjZwtj.js";
|
|
5
|
+
import { t as getCopilotUsage } from "./get-copilot-usage-BjA0nyGR.js";
|
|
6
6
|
import { a as resolveExecutable, n as killManagedTree, o as runCommandCapture, r as parseBoolEnv, s as runCommandVoid } from "./exec-y8C_MU8A.js";
|
|
7
7
|
import consola from "consola";
|
|
8
8
|
import * as fs$2 from "node:fs";
|
|
@@ -1429,7 +1429,7 @@ function collectToolFieldKeys(body) {
|
|
|
1429
1429
|
//#endregion
|
|
1430
1430
|
//#region package.json
|
|
1431
1431
|
var name = "github-router";
|
|
1432
|
-
var version = "0.3.
|
|
1432
|
+
var version = "0.3.288";
|
|
1433
1433
|
//#endregion
|
|
1434
1434
|
//#region src/lib/approval.ts
|
|
1435
1435
|
const awaitApproval = async () => {
|
|
@@ -2775,98 +2775,6 @@ function anthropicSseStreamFromEvents(events, opts) {
|
|
|
2775
2775
|
});
|
|
2776
2776
|
}
|
|
2777
2777
|
//#endregion
|
|
2778
|
-
//#region src/lib/reasoning-effort.ts
|
|
2779
|
-
/**
|
|
2780
|
-
* Reasoning-effort bucketing + clamping shared by the `/v1/messages` handler
|
|
2781
|
-
* (adaptive-thinking translation) and the Anthropic-translation shim
|
|
2782
|
-
* (thinking-budget → Responses `reasoning.effort`).
|
|
2783
|
-
*
|
|
2784
|
-
* Extracted from `src/routes/messages/handler.ts` so a `~/lib/*` module can
|
|
2785
|
-
* depend on it without importing route code (and without forming a
|
|
2786
|
-
* handler → shim → handler import cycle). `handler.ts` re-exports these for
|
|
2787
|
-
* backward compatibility with existing imports/tests.
|
|
2788
|
-
*/
|
|
2789
|
-
/**
|
|
2790
|
-
* Copilot's reasoning-effort tiers, lowest to highest.
|
|
2791
|
-
*
|
|
2792
|
-
* Both ends were added after the fact and both are load-bearing:
|
|
2793
|
-
*
|
|
2794
|
-
* `none` is advertised by every gpt-5.x entry in the live catalog. While it was
|
|
2795
|
-
* missing here it was treated as an UNRECOGNIZED value, so a client asking for
|
|
2796
|
-
* the MINIMUM on a model that does not offer it (gemini advertises only
|
|
2797
|
-
* low/medium/high) was anchored at the unknown-value tier and clamped to
|
|
2798
|
-
* `high` — the maximum. Listing it makes the clamp resolve to `low` instead,
|
|
2799
|
-
* which is what "nearest supported tier" should always have meant.
|
|
2800
|
-
*
|
|
2801
|
-
* `max` is advertised by `gpt-5.6-sol`, `gpt-5.6-terra`, `gpt-5.6-luna`,
|
|
2802
|
-
* `claude-opus-5` and the 4.7/4.8 Opus lines, and Claude Code's effort picker
|
|
2803
|
-
* offers it for any model whose entry allows it. Listing it lets an explicit
|
|
2804
|
-
* selection pass through, and lets `clampEffort` land on it for a model that
|
|
2805
|
-
* advertises nothing lower.
|
|
2806
|
-
*
|
|
2807
|
-
* `bucketEffort` deliberately reaches neither end — see below.
|
|
2808
|
-
*/
|
|
2809
|
-
const EFFORT_ORDER = [
|
|
2810
|
-
"none",
|
|
2811
|
-
"low",
|
|
2812
|
-
"medium",
|
|
2813
|
-
"high",
|
|
2814
|
-
"xhigh",
|
|
2815
|
-
"max"
|
|
2816
|
-
];
|
|
2817
|
-
/** Anchor for an effort value that is not a recognized tier at all.
|
|
2818
|
-
*
|
|
2819
|
-
* Deliberately NOT the top of `EFFORT_ORDER`. Callers reach this only when the
|
|
2820
|
-
* incoming value is unrecognized, which is a guess — and resolving a guess to
|
|
2821
|
-
* the most expensive tier a model advertises would silently spend more than the
|
|
2822
|
-
* caller could have meant. Anchoring here and clamping DOWN keeps the behavior
|
|
2823
|
-
* identical to before `max` joined the ladder, while `max` stays reachable by
|
|
2824
|
-
* explicit, valid selection. */
|
|
2825
|
-
const UNKNOWN_EFFORT_ANCHOR = "xhigh";
|
|
2826
|
-
/**
|
|
2827
|
-
* Bucket a thinking budget into a Copilot reasoning-effort string.
|
|
2828
|
-
* `<2000`→low, `<8000`→medium, `<24000`→high, else→xhigh.
|
|
2829
|
-
* Defaults missing/non-numeric budgets to 8000 ("high").
|
|
2830
|
-
*
|
|
2831
|
-
* The ceiling stays at `xhigh` even though `max` exists: Anthropic's
|
|
2832
|
-
* `budget_tokens` is unbounded above, so any threshold chosen for a `max`
|
|
2833
|
-
* bucket would silently re-tier existing callers whose budgets already map to
|
|
2834
|
-
* `xhigh`. `max` is reachable only by explicit selection
|
|
2835
|
-
* (`output_config.effort`), which is an unambiguous request rather than an
|
|
2836
|
-
* inference from a token count.
|
|
2837
|
-
*/
|
|
2838
|
-
function bucketEffort(budget) {
|
|
2839
|
-
const n = typeof budget === "number" && Number.isFinite(budget) ? budget : 8e3;
|
|
2840
|
-
if (n < 2e3) return "low";
|
|
2841
|
-
if (n < 8e3) return "medium";
|
|
2842
|
-
if (n < 24e3) return "high";
|
|
2843
|
-
return "xhigh";
|
|
2844
|
-
}
|
|
2845
|
-
/**
|
|
2846
|
-
* Clamp a bucketed effort to the closest value in `supported`. Ties resolve to
|
|
2847
|
-
* the lower-tier option (per EFFORT_ORDER).
|
|
2848
|
-
*
|
|
2849
|
-
* Iterates EFFORT_ORDER (canonical low→xhigh) so the first match on a given
|
|
2850
|
-
* distance is always the lower-tier value, regardless of input order in
|
|
2851
|
-
* `supported`.
|
|
2852
|
-
*/
|
|
2853
|
-
function clampEffort(bucketed, supported) {
|
|
2854
|
-
if (supported.includes(bucketed)) return bucketed;
|
|
2855
|
-
const targetIdx = EFFORT_ORDER.indexOf(bucketed);
|
|
2856
|
-
let best;
|
|
2857
|
-
let bestDist = Infinity;
|
|
2858
|
-
for (let i = 0; i < EFFORT_ORDER.length; i++) {
|
|
2859
|
-
const value = EFFORT_ORDER[i];
|
|
2860
|
-
if (!supported.includes(value)) continue;
|
|
2861
|
-
const dist = Math.abs(i - targetIdx);
|
|
2862
|
-
if (dist < bestDist) {
|
|
2863
|
-
bestDist = dist;
|
|
2864
|
-
best = value;
|
|
2865
|
-
}
|
|
2866
|
-
}
|
|
2867
|
-
return best ?? bucketed;
|
|
2868
|
-
}
|
|
2869
|
-
//#endregion
|
|
2870
2778
|
//#region src/lib/anthropic-translate/anthropic-request.ts
|
|
2871
2779
|
/**
|
|
2872
2780
|
* Steering appended to `instructions` for shim-routed (non-Claude) models when
|
|
@@ -3151,7 +3059,8 @@ function parseDisableParallelToolUse(toolChoice) {
|
|
|
3151
3059
|
function defaultReasoningEffort(model) {
|
|
3152
3060
|
const supported = model?.capabilities?.supports?.reasoning_effort;
|
|
3153
3061
|
if (!(Array.isArray(supported) && supported.length > 0)) return void 0;
|
|
3154
|
-
|
|
3062
|
+
const wantXhigh = parseBoolEnv(process.env.GH_ROUTER_FRONTIER_XHIGH_DEFAULT) === true && model?.id != null && shimDefaultsToXhigh(model.id) && supported.includes("xhigh");
|
|
3063
|
+
return clampEffort(wantXhigh ? "xhigh" : "high", supported);
|
|
3155
3064
|
}
|
|
3156
3065
|
/**
|
|
3157
3066
|
* Map Anthropic `thinking` to a Responses reasoning effort, clamped to the
|
|
@@ -3969,108 +3878,6 @@ async function* synthAnthropicFromResponses(upstream, opts) {
|
|
|
3969
3878
|
q.length = 0;
|
|
3970
3879
|
}
|
|
3971
3880
|
//#endregion
|
|
3972
|
-
//#region src/lib/anthropic-translate/classifier.ts
|
|
3973
|
-
/**
|
|
3974
|
-
* Routing classifier for `POST /v1/messages`.
|
|
3975
|
-
*
|
|
3976
|
-
* Claude Code speaks the Anthropic Messages wire format. Copilot only serves
|
|
3977
|
-
* Claude models on its native `/v1/messages` endpoint; a gpt/gemini request
|
|
3978
|
-
* sent there 400s. This classifier decides, from the RESOLVED model id and its
|
|
3979
|
-
* catalog metadata, whether a request stays on the native passthrough
|
|
3980
|
-
* (`createMessages`) or is diverted to the translation shim.
|
|
3981
|
-
*
|
|
3982
|
-
* Non-regression is the whole point — every Claude model (opus / sonnet / haiku /
|
|
3983
|
-
* any `claude-*` or Anthropic-vendored id) MUST return "claude-passthrough" so
|
|
3984
|
-
* its bytes reach `createMessages` unchanged — even if future catalog metadata
|
|
3985
|
-
* were to (wrongly) advertise a `/responses` endpoint for it. The Claude check
|
|
3986
|
-
* is therefore keyed off identity (id / vendor / family), NOT the endpoint.
|
|
3987
|
-
*
|
|
3988
|
-
* Non-Claude models are diverted to the translation shim by the endpoint the
|
|
3989
|
-
* catalog says they serve: `/responses` models (gpt-5.5, gpt-5.3-codex, …) take
|
|
3990
|
-
* the Responses path (`responses-shim`), `/chat/completions` models (gemini,
|
|
3991
|
-
* and any chat-default model) take the chat path (`chat-shim`). The decision is
|
|
3992
|
-
* derived from `pickEndpoint` (catalog `supported_endpoints`), never a
|
|
3993
|
-
* hardcoded slug list, so it generalizes. Copilot only serves Claude models on
|
|
3994
|
-
* its native `/v1/messages`, so diverting every non-Claude model to a shim is
|
|
3995
|
-
* correct — a non-Claude request sent to `/v1/messages` would 400.
|
|
3996
|
-
*/
|
|
3997
|
-
/**
|
|
3998
|
-
* Match "claude"/"anthropic" as a delimiter-bounded segment anywhere in a model
|
|
3999
|
-
* id: at the start, or after a `/ _ . : -` path/version delimiter, and followed
|
|
4000
|
-
* by end-of-string, another such delimiter, or a digit. This catches catalog
|
|
4001
|
-
* aliases like `github/claude-3-7-sonnet` or `anthropic/…` whose vendor is
|
|
4002
|
-
* "github" and whose family is empty — where the token only surfaces mid-id —
|
|
4003
|
-
* while NOT firing on incidental substrings like `notclaude`. Deliberately
|
|
4004
|
-
* over-inclusive at the boundaries: we fail CLOSED toward Claude (→ passthrough)
|
|
4005
|
-
* so a real Claude model can never be diverted to the non-Claude shim.
|
|
4006
|
-
*/
|
|
4007
|
-
const CLAUDE_ID_RE = /(^|[/_.:-])(claude|anthropic)(?=$|[/_.:-]|\d)/i;
|
|
4008
|
-
/**
|
|
4009
|
-
* True when the target is a Claude / Anthropic model. Matches on any of:
|
|
4010
|
-
* catalog vendor containing "anthropic", capability family containing "claude",
|
|
4011
|
-
* or a Claude/anthropic path-segment (see `CLAUDE_ID_RE`) in ANY id we hold —
|
|
4012
|
-
* the resolved id (`modelId`), the pre-resolution request id (`originalModelId`),
|
|
4013
|
-
* or the catalog entry's own id (`model.id`). Conservative by design: when in
|
|
4014
|
-
* doubt it returns true so a Claude request can never be diverted to the shim.
|
|
4015
|
-
*/
|
|
4016
|
-
function isClaudeModel(modelId, model, originalModelId) {
|
|
4017
|
-
if (model) {
|
|
4018
|
-
if ((model.vendor?.toLowerCase() ?? "").includes("anthropic")) return true;
|
|
4019
|
-
if ((model.capabilities?.family?.toLowerCase() ?? "").includes("claude")) return true;
|
|
4020
|
-
}
|
|
4021
|
-
return [
|
|
4022
|
-
modelId,
|
|
4023
|
-
originalModelId,
|
|
4024
|
-
model?.id
|
|
4025
|
-
].some((id) => typeof id === "string" && CLAUDE_ID_RE.test(id));
|
|
4026
|
-
}
|
|
4027
|
-
/**
|
|
4028
|
-
* Decide the route for a resolved model id + its catalog entry.
|
|
4029
|
-
*
|
|
4030
|
-
* - No model id, or a Claude model → "claude-passthrough" (existing behaviour).
|
|
4031
|
-
* - A non-Claude model whose catalog endpoint is `/responses` → "responses-shim".
|
|
4032
|
-
* - A non-Claude model whose catalog endpoint is `/chat/completions` (gemini and
|
|
4033
|
-
* any chat-default model) → "chat-shim".
|
|
4034
|
-
* - A non-Claude model absent from the catalog (so we can't confirm an endpoint)
|
|
4035
|
-
* → "claude-passthrough" (unchanged; we don't divert what we can't classify).
|
|
4036
|
-
* - A non-Claude model that IS in the catalog and serves NEITHER of the two shim
|
|
4037
|
-
* endpoints (`pickEndpoint` → undefined) → "claude-passthrough" as well.
|
|
4038
|
-
*
|
|
4039
|
-
* Those last two land on the same route but are NOT the same answer, and the
|
|
4040
|
-
* coincidence is deliberate rather than a collapsed default (contrast
|
|
4041
|
-
* `resolveEndpointForModelId`, whose callers must tell them apart because
|
|
4042
|
-
* guessing there produces an opaque upstream 400). Here neither shim is even a
|
|
4043
|
-
* candidate: a shim can only speak `/responses` or `/chat/completions`, so
|
|
4044
|
-
* diverting a model that serves neither would 400 just as surely. Passthrough
|
|
4045
|
-
* is the better default because it is sometimes RIGHT — a non-Claude catalog
|
|
4046
|
-
* model advertising `/v1/messages` is served by exactly the endpoint
|
|
4047
|
-
* passthrough uses. It also preserves this module's fail-CLOSED-toward-Claude
|
|
4048
|
-
* invariant: an unclassifiable model is never diverted.
|
|
4049
|
-
*
|
|
4050
|
-
* KNOWN GAP (audited, deliberately not fixed here): a non-Claude model serving
|
|
4051
|
-
* only something we cannot speak at all (say `/embeddings`) also lands on
|
|
4052
|
-
* passthrough and will still 400 upstream — `logEndpointMismatch(modelId,
|
|
4053
|
-
* "/v1/messages")` logs it at the passthrough seam, but no local error is
|
|
4054
|
-
* raised. Closing that needs a change in `src/routes/messages/handler.ts`,
|
|
4055
|
-
* which this seam does not own. It is strictly narrower than the defect fixed
|
|
4056
|
-
* in `resolveEndpointForModelId`: no such model is reachable as a Claude Code
|
|
4057
|
-
* `/v1/messages` target today, whereas the plan worker's `claude-opus-5`
|
|
4058
|
-
* default is.
|
|
4059
|
-
*
|
|
4060
|
-
* `originalModelId` is the optional pre-resolution request id; when supplied it
|
|
4061
|
-
* is checked for Claude-likeness alongside the resolved id so an alias that
|
|
4062
|
-
* resolves to a non-Claude-looking id can't slip past.
|
|
4063
|
-
*/
|
|
4064
|
-
function classifyMessagesRoute(modelId, model, originalModelId) {
|
|
4065
|
-
if (!modelId) return "claude-passthrough";
|
|
4066
|
-
if (isClaudeModel(modelId, model, originalModelId)) return "claude-passthrough";
|
|
4067
|
-
if (!model) return "claude-passthrough";
|
|
4068
|
-
const endpoint = pickEndpoint(model);
|
|
4069
|
-
if (endpoint === "responses") return "responses-shim";
|
|
4070
|
-
if (endpoint === "chat") return "chat-shim";
|
|
4071
|
-
return "claude-passthrough";
|
|
4072
|
-
}
|
|
4073
|
-
//#endregion
|
|
4074
3881
|
//#region src/lib/anthropic-translate/index.ts
|
|
4075
3882
|
const STREAM_HEADERS = {
|
|
4076
3883
|
"content-type": "text/event-stream",
|
|
@@ -4536,11 +4343,15 @@ async function handleCompletion(c) {
|
|
|
4536
4343
|
parsedBase = JSON.parse(nativeBody);
|
|
4537
4344
|
} catch {}
|
|
4538
4345
|
const initialConversation = Array.isArray(parsedBase.messages) ? parsedBase.messages : [];
|
|
4346
|
+
const advisorChoice = resolveAdvisorModel(originalModel);
|
|
4539
4347
|
return new Response(buildAdvisorStream({
|
|
4540
4348
|
firstResponse: response,
|
|
4541
4349
|
initialConversation,
|
|
4542
4350
|
baseBody: parsedBase,
|
|
4543
4351
|
requestHeaders,
|
|
4352
|
+
advisorModel: advisorChoice.model,
|
|
4353
|
+
advisorEscalated: advisorChoice.escalated,
|
|
4354
|
+
advisorEffort: resolveAdvisorEffort(rawBody, advisorChoice.model),
|
|
4544
4355
|
externalAborter: advisorAborter
|
|
4545
4356
|
}), {
|
|
4546
4357
|
status: response.status,
|
|
@@ -4649,7 +4460,8 @@ function clampOutputConfigEffortInPlace(body, model) {
|
|
|
4649
4460
|
const current = oc.effort;
|
|
4650
4461
|
if (typeof current !== "string") return false;
|
|
4651
4462
|
if (supported.includes(current)) return false;
|
|
4652
|
-
const
|
|
4463
|
+
const bucketed = EFFORT_ORDER.includes(current) ? current : UNKNOWN_EFFORT_ANCHOR;
|
|
4464
|
+
const clamped = clampEffort(bucketed, supported);
|
|
4653
4465
|
if (clamped === current) return false;
|
|
4654
4466
|
oc.effort = clamped;
|
|
4655
4467
|
return true;
|
|
@@ -5833,8 +5645,8 @@ function parseSharedArgs(args) {
|
|
|
5833
5645
|
* agent loop runs on them through the `/v1/messages` translation shim
|
|
5834
5646
|
* (`src/lib/anthropic-translate/*`, branched in `routes/messages/handler.ts`)
|
|
5835
5647
|
* that forwards non-Claude targets to Copilot `/responses` (gpt) or
|
|
5836
|
-
* `/chat/completions` (gemini). The
|
|
5837
|
-
* `gemini-3.1-pro-preview`
|
|
5648
|
+
* `/chat/completions` (gemini). The Gemini review row prefers
|
|
5649
|
+
* `gemini-3.1-pro-preview` and degrades to `gemini-3.7-flash`.
|
|
5838
5650
|
*
|
|
5839
5651
|
* Display labels only: the gateway-model cache schema Claude Code reads is
|
|
5840
5652
|
* `{id, display_name?}` per model — there is NO per-model context-window
|
|
@@ -5858,10 +5670,6 @@ const NATIVE_NON_CLAUDE_MODELS = [
|
|
|
5858
5670
|
{
|
|
5859
5671
|
id: "gemini-3.5-flash",
|
|
5860
5672
|
displayName: "Gemini 3.5 Flash"
|
|
5861
|
-
},
|
|
5862
|
-
{
|
|
5863
|
-
id: "gemini-3.1-pro-preview",
|
|
5864
|
-
displayName: "Gemini 3.1 Pro (preview)"
|
|
5865
5673
|
}
|
|
5866
5674
|
];
|
|
5867
5675
|
/**
|
|
@@ -5886,7 +5694,13 @@ function nativeSelectableModelsInCatalog() {
|
|
|
5886
5694
|
const catalog = state.models?.data;
|
|
5887
5695
|
if (!catalog || catalog.length === 0) return [];
|
|
5888
5696
|
const present = new Set(catalog.map((m) => m.id));
|
|
5889
|
-
|
|
5697
|
+
const models = NATIVE_NON_CLAUDE_MODELS.filter((m) => present.has(m.id));
|
|
5698
|
+
const geminiReviewModel = resolveGeminiReviewModel();
|
|
5699
|
+
if (geminiReviewModel) models.push({
|
|
5700
|
+
id: geminiReviewModel,
|
|
5701
|
+
displayName: geminiReviewModel === "gemini-3.7-flash" ? "Gemini 3.7 Flash" : "Gemini 3.1 Pro (preview)"
|
|
5702
|
+
});
|
|
5703
|
+
return models.map((m) => ({
|
|
5890
5704
|
id: withOneMSuffix(m.id),
|
|
5891
5705
|
display_name: m.displayName
|
|
5892
5706
|
}));
|
|
@@ -6020,10 +5834,16 @@ function getClaudeCodeEnvVars(serverUrl, model) {
|
|
|
6020
5834
|
const mcpToolTimeoutMs = String(resolveMcpToolTimeoutMs());
|
|
6021
5835
|
if (process.env.MCP_TIMEOUT === void 0) vars.MCP_TIMEOUT = mcpToolTimeoutMs;
|
|
6022
5836
|
if (process.env.MCP_TOOL_TIMEOUT === void 0) vars.MCP_TOOL_TIMEOUT = mcpToolTimeoutMs;
|
|
6023
|
-
|
|
6024
|
-
if (process.env.
|
|
6025
|
-
|
|
6026
|
-
|
|
5837
|
+
const smallFastModel = isBudgetClaudeLead(model) && (state.models?.data?.some((m) => m.id === "claude-haiku-4.5") ?? false) ? BUDGET_SMALL_FAST_SLUG : "claude-sonnet-5";
|
|
5838
|
+
if (process.env.ANTHROPIC_SMALL_FAST_MODEL === void 0) vars.ANTHROPIC_SMALL_FAST_MODEL = smallFastModel;
|
|
5839
|
+
const seedTierRow = (modelKey, nameKey, bareSlug) => {
|
|
5840
|
+
if (process.env[modelKey] !== void 0) return;
|
|
5841
|
+
vars[modelKey] = withOneMSuffixForLead(bareSlug);
|
|
5842
|
+
if (process.env[nameKey] === void 0) vars[nameKey] = bareSlug;
|
|
5843
|
+
};
|
|
5844
|
+
seedTierRow("ANTHROPIC_DEFAULT_SONNET_MODEL", "ANTHROPIC_DEFAULT_SONNET_MODEL_NAME", "claude-sonnet-5");
|
|
5845
|
+
seedTierRow("ANTHROPIC_DEFAULT_HAIKU_MODEL", "ANTHROPIC_DEFAULT_HAIKU_MODEL_NAME", smallFastModel);
|
|
5846
|
+
seedTierRow("ANTHROPIC_DEFAULT_OPUS_MODEL", "ANTHROPIC_DEFAULT_OPUS_MODEL_NAME", "claude-opus-5");
|
|
6027
5847
|
if (process.env.CLAUDE_CODE_PLAN_V2_AGENT_COUNT === void 0) vars.CLAUDE_CODE_PLAN_V2_AGENT_COUNT = "7";
|
|
6028
5848
|
for (const key of [
|
|
6029
5849
|
"CLAUDE_CODE_ENABLE_EXPERIMENTAL_ADVISOR_TOOL",
|
|
@@ -6063,4 +5883,4 @@ function getCodexEnvVars(serverUrl) {
|
|
|
6063
5883
|
//#endregion
|
|
6064
5884
|
export { sharedServerArgs as a, listModelsForEndpoint as c, checkClaudeVersion as d, updateClaude as f, setupAndServe as i, enableFileLogging as l, getCodexEnvVars as n, startKeepAwake as o, parseSharedArgs as r, stopKeepAwake as s, getClaudeCodeEnvVars as t, runSelfUpdate as u };
|
|
6065
5885
|
|
|
6066
|
-
//# sourceMappingURL=server-setup-
|
|
5886
|
+
//# sourceMappingURL=server-setup-D5hilphf.js.map
|