nexus-agents 10.1.1 → 10.2.0
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/{ast-rule-runner-AAOBENF2.js → ast-rule-runner-RI7ZJ4ZI.js} +3 -3
- package/dist/{child-mcp-config-FRWGQIHP.js → child-mcp-config-73BX4OTR.js} +2 -2
- package/dist/{chunk-NUXSGWDS.js → chunk-23QA6GQD.js} +5 -5
- package/dist/{chunk-EGUISJBB.js → chunk-2DYCHHWW.js} +4 -4
- package/dist/{chunk-WVIHRMGD.js → chunk-2TA6KTRF.js} +15 -15
- package/dist/{chunk-YHY7GMAL.js → chunk-4JJI34RV.js} +2 -2
- package/dist/{chunk-KPGWNBDA.js → chunk-7EV3QAKO.js} +2 -2
- package/dist/{chunk-SCQ5YAYO.js → chunk-D6E3LJGP.js} +4 -4
- package/dist/{chunk-XYYXVJSO.js → chunk-EJ5EBTAV.js} +2 -2
- package/dist/{chunk-BJLP4E6Q.js → chunk-FNHVTDHZ.js} +3 -3
- package/dist/{chunk-VGCRYAEH.js → chunk-FWQSOPBA.js} +4 -4
- package/dist/{chunk-RBFHY2LF.js → chunk-GAX75XCV.js} +2 -2
- package/dist/{chunk-O46IOND3.js → chunk-GX5ZHZR2.js} +7 -7
- package/dist/{chunk-WNWLMQAV.js → chunk-J44RKRGQ.js} +3 -3
- package/dist/{chunk-L4P4A7Z2.js → chunk-JGY5HMWI.js} +2 -2
- package/dist/{chunk-WCHN7B2Q.js → chunk-JUUGLXSN.js} +8 -10
- package/dist/{chunk-WCHN7B2Q.js.map → chunk-JUUGLXSN.js.map} +1 -1
- package/dist/{chunk-BK6Q3VQK.js → chunk-KASBBKAQ.js} +2 -2
- package/dist/chunk-KASBBKAQ.js.map +1 -0
- package/dist/chunk-KLSNDPU6.js +2412 -0
- package/dist/chunk-KLSNDPU6.js.map +1 -0
- package/dist/{chunk-K2S6SHSK.js → chunk-LP5ISXKM.js} +4 -4
- package/dist/{chunk-QPU7QKPT.js → chunk-LXYT2P2Y.js} +3 -3
- package/dist/{chunk-UABTN3VX.js → chunk-OMSKBBL7.js} +15 -15
- package/dist/{chunk-M4IJ3H6M.js → chunk-PXYSAG5B.js} +2 -2
- package/dist/{chunk-52Q72CPP.js → chunk-QG3VDSWD.js} +3 -3
- package/dist/{chunk-IRFKJ2KR.js → chunk-QM5W3T3O.js} +2 -2
- package/dist/{chunk-O3VPGING.js → chunk-QRC3QLUQ.js} +92 -95
- package/dist/chunk-QRC3QLUQ.js.map +1 -0
- package/dist/{chunk-MCWIMVG2.js → chunk-QS5HGPCN.js} +2 -2
- package/dist/{chunk-O5OUJ3PX.js → chunk-SS53PZO6.js} +5 -5
- package/dist/{chunk-VHOOJ4FG.js → chunk-SX2XWCGA.js} +2 -2
- package/dist/{chunk-2VD5OQQR.js → chunk-TDUXUVUU.js} +2 -2
- package/dist/{chunk-XFTTKOHK.js → chunk-U37AITDA.js} +2 -2
- package/dist/{chunk-V5FGXVSX.js → chunk-UZJ6IPJR.js} +5 -5
- package/dist/{chunk-MYM2TPNL.js → chunk-V26YQQK4.js} +2 -2
- package/dist/{chunk-HVZVVDFN.js → chunk-VLOPXV47.js} +5 -5
- package/dist/{chunk-UBOJ2A3P.js → chunk-WD4DENPC.js} +3 -3
- package/dist/{chunk-WI73OZAU.js → chunk-WKFPKPEM.js} +13 -13
- package/dist/chunk-WKFPKPEM.js.map +1 -0
- package/dist/{chunk-G4JXD6UJ.js → chunk-XDUTAUK3.js} +40 -42
- package/dist/{chunk-G4JXD6UJ.js.map → chunk-XDUTAUK3.js.map} +1 -1
- package/dist/{cli-circuit-breaker-AM425BRL.js → cli-circuit-breaker-62YOQQT3.js} +3 -3
- package/dist/{cli-readiness-LWOMHZ34.js → cli-readiness-O6EOQV4L.js} +7 -7
- package/dist/cli.js +50 -51
- package/dist/cli.js.map +1 -1
- package/dist/{composite-router-VXQFXNET.js → composite-router-YPZ3D5Y6.js} +2 -2
- package/dist/{consensus-vote-KKS36YLZ.js → consensus-vote-RNQQUBXO.js} +16 -17
- package/dist/{context-retriever-GEQIPCVL.js → context-retriever-HVPLM6DH.js} +8 -8
- package/dist/{doctor-deep-DSOZGB5J.js → doctor-deep-UZQTD65D.js} +3 -3
- package/dist/{doctor-gateway-report-RJOSOHGA.js → doctor-gateway-report-LRBPPJD4.js} +6 -7
- package/dist/{doctor-live-7LVRGOS5.js → doctor-live-QFLT5SDB.js} +11 -11
- package/dist/{expert-bridge-5A4ADUBO.js → expert-bridge-O3UZXLGB.js} +4 -4
- package/dist/{factory-UBAUIA2M.js → factory-KCKQQAEH.js} +10 -10
- package/dist/{factory-4RZLP7QV.js → factory-LUKUIB6C.js} +5 -5
- package/dist/{improvement-review-VLFBN5US.js → improvement-review-7IABFAU3.js} +6 -6
- package/dist/index.d.ts +20 -22
- package/dist/index.js +35 -37
- package/dist/index.js.map +1 -1
- package/dist/{init-opencode-WUN3CTBM.js → init-opencode-RYPBCM4P.js} +5 -6
- package/dist/{init-opencode-WUN3CTBM.js.map → init-opencode-RYPBCM4P.js.map} +1 -1
- package/dist/{issue-triage-VKEHVHO4.js → issue-triage-YBVJVAUU.js} +6 -6
- package/dist/{model-config-helpers-GYPIIXOP.js → model-config-helpers-QNV3KD2W.js} +2 -2
- package/dist/{openai-compat-adapter-GSDOJ7TQ.js → openai-compat-adapter-GPZDIR3D.js} +11 -8
- package/dist/{outcome-store-adapter-PXT7AL6T.js → outcome-store-adapter-WRONSTUD.js} +2 -2
- package/dist/{pr-reviewer-helpers-GUUT7G43.js → pr-reviewer-helpers-7SMNNDFJ.js} +4 -4
- package/dist/{registry-command-4G3WGKS5.js → registry-command-U7K6HIBK.js} +2 -2
- package/dist/{repo-security-plan-QO6ACTPZ.js → repo-security-plan-LFWLVEL2.js} +3 -3
- package/dist/{research-helpers-synthesize-MPEJHPYR.js → research-helpers-synthesize-X6MVAAKT.js} +4 -4
- package/dist/{routing-memory-VHQDJ6XZ.js → routing-memory-OCIVXKOU.js} +2 -2
- package/dist/{session-memory-M3CQFFL6.js → session-memory-4LMEWO3X.js} +3 -3
- package/dist/{setup-config-VGEBCEKX.js → setup-config-YNNNR4AE.js} +3 -3
- package/dist/{setup-custom-api-DX7CNYKT.js → setup-custom-api-QEPUCHOX.js} +3 -3
- package/dist/setup-data-dir-XM5DWH7R.js +35 -0
- package/dist/{tool-memory-7QUPGCWV.js → tool-memory-EFGFXF65.js} +5 -5
- package/dist/{unified-registry-CLZK3H64.js → unified-registry-KLNC24HA.js} +11 -11
- package/dist/{weather-report-OKMXF73V.js → weather-report-PMYQ3WBW.js} +2 -2
- package/package.json +1 -1
- package/dist/chunk-BK6Q3VQK.js.map +0 -1
- package/dist/chunk-K6M2ZWX5.js +0 -1116
- package/dist/chunk-K6M2ZWX5.js.map +0 -1
- package/dist/chunk-O3VPGING.js.map +0 -1
- package/dist/chunk-WI73OZAU.js.map +0 -1
- package/dist/chunk-XQMQGUJT.js +0 -995
- package/dist/chunk-XQMQGUJT.js.map +0 -1
- package/dist/setup-data-dir-6MZ2HZDC.js +0 -36
- /package/dist/{ast-rule-runner-AAOBENF2.js.map → ast-rule-runner-RI7ZJ4ZI.js.map} +0 -0
- /package/dist/{child-mcp-config-FRWGQIHP.js.map → child-mcp-config-73BX4OTR.js.map} +0 -0
- /package/dist/{chunk-NUXSGWDS.js.map → chunk-23QA6GQD.js.map} +0 -0
- /package/dist/{chunk-EGUISJBB.js.map → chunk-2DYCHHWW.js.map} +0 -0
- /package/dist/{chunk-WVIHRMGD.js.map → chunk-2TA6KTRF.js.map} +0 -0
- /package/dist/{chunk-YHY7GMAL.js.map → chunk-4JJI34RV.js.map} +0 -0
- /package/dist/{chunk-KPGWNBDA.js.map → chunk-7EV3QAKO.js.map} +0 -0
- /package/dist/{chunk-SCQ5YAYO.js.map → chunk-D6E3LJGP.js.map} +0 -0
- /package/dist/{chunk-XYYXVJSO.js.map → chunk-EJ5EBTAV.js.map} +0 -0
- /package/dist/{chunk-BJLP4E6Q.js.map → chunk-FNHVTDHZ.js.map} +0 -0
- /package/dist/{chunk-VGCRYAEH.js.map → chunk-FWQSOPBA.js.map} +0 -0
- /package/dist/{chunk-RBFHY2LF.js.map → chunk-GAX75XCV.js.map} +0 -0
- /package/dist/{chunk-O46IOND3.js.map → chunk-GX5ZHZR2.js.map} +0 -0
- /package/dist/{chunk-WNWLMQAV.js.map → chunk-J44RKRGQ.js.map} +0 -0
- /package/dist/{chunk-L4P4A7Z2.js.map → chunk-JGY5HMWI.js.map} +0 -0
- /package/dist/{chunk-K2S6SHSK.js.map → chunk-LP5ISXKM.js.map} +0 -0
- /package/dist/{chunk-QPU7QKPT.js.map → chunk-LXYT2P2Y.js.map} +0 -0
- /package/dist/{chunk-UABTN3VX.js.map → chunk-OMSKBBL7.js.map} +0 -0
- /package/dist/{chunk-M4IJ3H6M.js.map → chunk-PXYSAG5B.js.map} +0 -0
- /package/dist/{chunk-52Q72CPP.js.map → chunk-QG3VDSWD.js.map} +0 -0
- /package/dist/{chunk-IRFKJ2KR.js.map → chunk-QM5W3T3O.js.map} +0 -0
- /package/dist/{chunk-MCWIMVG2.js.map → chunk-QS5HGPCN.js.map} +0 -0
- /package/dist/{chunk-O5OUJ3PX.js.map → chunk-SS53PZO6.js.map} +0 -0
- /package/dist/{chunk-VHOOJ4FG.js.map → chunk-SX2XWCGA.js.map} +0 -0
- /package/dist/{chunk-2VD5OQQR.js.map → chunk-TDUXUVUU.js.map} +0 -0
- /package/dist/{chunk-XFTTKOHK.js.map → chunk-U37AITDA.js.map} +0 -0
- /package/dist/{chunk-V5FGXVSX.js.map → chunk-UZJ6IPJR.js.map} +0 -0
- /package/dist/{chunk-MYM2TPNL.js.map → chunk-V26YQQK4.js.map} +0 -0
- /package/dist/{chunk-HVZVVDFN.js.map → chunk-VLOPXV47.js.map} +0 -0
- /package/dist/{chunk-UBOJ2A3P.js.map → chunk-WD4DENPC.js.map} +0 -0
- /package/dist/{cli-circuit-breaker-AM425BRL.js.map → cli-circuit-breaker-62YOQQT3.js.map} +0 -0
- /package/dist/{cli-readiness-LWOMHZ34.js.map → cli-readiness-O6EOQV4L.js.map} +0 -0
- /package/dist/{composite-router-VXQFXNET.js.map → composite-router-YPZ3D5Y6.js.map} +0 -0
- /package/dist/{consensus-vote-KKS36YLZ.js.map → consensus-vote-RNQQUBXO.js.map} +0 -0
- /package/dist/{context-retriever-GEQIPCVL.js.map → context-retriever-HVPLM6DH.js.map} +0 -0
- /package/dist/{doctor-deep-DSOZGB5J.js.map → doctor-deep-UZQTD65D.js.map} +0 -0
- /package/dist/{doctor-gateway-report-RJOSOHGA.js.map → doctor-gateway-report-LRBPPJD4.js.map} +0 -0
- /package/dist/{doctor-live-7LVRGOS5.js.map → doctor-live-QFLT5SDB.js.map} +0 -0
- /package/dist/{expert-bridge-5A4ADUBO.js.map → expert-bridge-O3UZXLGB.js.map} +0 -0
- /package/dist/{factory-4RZLP7QV.js.map → factory-KCKQQAEH.js.map} +0 -0
- /package/dist/{factory-UBAUIA2M.js.map → factory-LUKUIB6C.js.map} +0 -0
- /package/dist/{improvement-review-VLFBN5US.js.map → improvement-review-7IABFAU3.js.map} +0 -0
- /package/dist/{issue-triage-VKEHVHO4.js.map → issue-triage-YBVJVAUU.js.map} +0 -0
- /package/dist/{model-config-helpers-GYPIIXOP.js.map → model-config-helpers-QNV3KD2W.js.map} +0 -0
- /package/dist/{openai-compat-adapter-GSDOJ7TQ.js.map → openai-compat-adapter-GPZDIR3D.js.map} +0 -0
- /package/dist/{outcome-store-adapter-PXT7AL6T.js.map → outcome-store-adapter-WRONSTUD.js.map} +0 -0
- /package/dist/{pr-reviewer-helpers-GUUT7G43.js.map → pr-reviewer-helpers-7SMNNDFJ.js.map} +0 -0
- /package/dist/{registry-command-4G3WGKS5.js.map → registry-command-U7K6HIBK.js.map} +0 -0
- /package/dist/{repo-security-plan-QO6ACTPZ.js.map → repo-security-plan-LFWLVEL2.js.map} +0 -0
- /package/dist/{research-helpers-synthesize-MPEJHPYR.js.map → research-helpers-synthesize-X6MVAAKT.js.map} +0 -0
- /package/dist/{routing-memory-VHQDJ6XZ.js.map → routing-memory-OCIVXKOU.js.map} +0 -0
- /package/dist/{session-memory-M3CQFFL6.js.map → session-memory-4LMEWO3X.js.map} +0 -0
- /package/dist/{setup-config-VGEBCEKX.js.map → setup-config-YNNNR4AE.js.map} +0 -0
- /package/dist/{setup-custom-api-DX7CNYKT.js.map → setup-custom-api-QEPUCHOX.js.map} +0 -0
- /package/dist/{setup-data-dir-6MZ2HZDC.js.map → setup-data-dir-XM5DWH7R.js.map} +0 -0
- /package/dist/{tool-memory-7QUPGCWV.js.map → tool-memory-EFGFXF65.js.map} +0 -0
- /package/dist/{unified-registry-CLZK3H64.js.map → unified-registry-KLNC24HA.js.map} +0 -0
- /package/dist/{weather-report-OKMXF73V.js.map → weather-report-PMYQ3WBW.js.map} +0 -0
|
@@ -9,8 +9,8 @@ import {
|
|
|
9
9
|
getBuiltInAstRulesPath,
|
|
10
10
|
loadRules,
|
|
11
11
|
runAstQaRules
|
|
12
|
-
} from "./chunk-
|
|
13
|
-
import "./chunk-
|
|
12
|
+
} from "./chunk-EJ5EBTAV.js";
|
|
13
|
+
import "./chunk-WKFPKPEM.js";
|
|
14
14
|
import "./chunk-XBEKMUTO.js";
|
|
15
15
|
import "./chunk-UE7A2XHM.js";
|
|
16
16
|
import "./chunk-LWOX65CP.js";
|
|
@@ -28,4 +28,4 @@ export {
|
|
|
28
28
|
loadRules,
|
|
29
29
|
runAstQaRules
|
|
30
30
|
};
|
|
31
|
-
//# sourceMappingURL=ast-rule-runner-
|
|
31
|
+
//# sourceMappingURL=ast-rule-runner-RI7ZJ4ZI.js.map
|
|
@@ -3,7 +3,7 @@ import {
|
|
|
3
3
|
} from "./chunk-JPFRRNRR.js";
|
|
4
4
|
import {
|
|
5
5
|
createLogger
|
|
6
|
-
} from "./chunk-
|
|
6
|
+
} from "./chunk-WKFPKPEM.js";
|
|
7
7
|
import "./chunk-XBEKMUTO.js";
|
|
8
8
|
import "./chunk-UE7A2XHM.js";
|
|
9
9
|
import "./chunk-LWOX65CP.js";
|
|
@@ -75,4 +75,4 @@ async function generateMcpConfig(options) {
|
|
|
75
75
|
export {
|
|
76
76
|
generateMcpConfig
|
|
77
77
|
};
|
|
78
|
-
//# sourceMappingURL=child-mcp-config-
|
|
78
|
+
//# sourceMappingURL=child-mcp-config-73BX4OTR.js.map
|
|
@@ -1,12 +1,12 @@
|
|
|
1
1
|
import {
|
|
2
2
|
generateHyphenId
|
|
3
|
-
} from "./chunk-
|
|
3
|
+
} from "./chunk-GAX75XCV.js";
|
|
4
4
|
import {
|
|
5
5
|
getDefaultCliCircuitBreakerRegistry
|
|
6
|
-
} from "./chunk-
|
|
6
|
+
} from "./chunk-SX2XWCGA.js";
|
|
7
7
|
import {
|
|
8
8
|
sanitizeOutput
|
|
9
|
-
} from "./chunk-
|
|
9
|
+
} from "./chunk-QM5W3T3O.js";
|
|
10
10
|
import {
|
|
11
11
|
CLI_VERSION_REQUIREMENTS,
|
|
12
12
|
DEFAULT_CAPABILITIES,
|
|
@@ -47,7 +47,7 @@ import {
|
|
|
47
47
|
servesListedModel,
|
|
48
48
|
unenforcedAccessModeRefusal,
|
|
49
49
|
withEnforcedAccessMode
|
|
50
|
-
} from "./chunk-
|
|
50
|
+
} from "./chunk-WKFPKPEM.js";
|
|
51
51
|
import {
|
|
52
52
|
parseBoolValue
|
|
53
53
|
} from "./chunk-LWOX65CP.js";
|
|
@@ -1960,4 +1960,4 @@ export {
|
|
|
1960
1960
|
IN_FAMILY_FALLBACK_OPTION,
|
|
1961
1961
|
ClaudeCliAdapter
|
|
1962
1962
|
};
|
|
1963
|
-
//# sourceMappingURL=chunk-
|
|
1963
|
+
//# sourceMappingURL=chunk-23QA6GQD.js.map
|
|
@@ -1,14 +1,14 @@
|
|
|
1
1
|
import {
|
|
2
2
|
IN_FAMILY_FALLBACK_OPTION
|
|
3
|
-
} from "./chunk-
|
|
3
|
+
} from "./chunk-23QA6GQD.js";
|
|
4
4
|
import {
|
|
5
5
|
sanitizeErrorDetails
|
|
6
|
-
} from "./chunk-
|
|
6
|
+
} from "./chunk-QM5W3T3O.js";
|
|
7
7
|
import {
|
|
8
8
|
classifyExtractedError,
|
|
9
9
|
getTimeProvider,
|
|
10
10
|
isTimeoutText
|
|
11
|
-
} from "./chunk-
|
|
11
|
+
} from "./chunk-WKFPKPEM.js";
|
|
12
12
|
import {
|
|
13
13
|
resolveClassGuardMs
|
|
14
14
|
} from "./chunk-4PN3UVZV.js";
|
|
@@ -156,4 +156,4 @@ export {
|
|
|
156
156
|
SERVES_PROBE_PROMPT,
|
|
157
157
|
probeServes
|
|
158
158
|
};
|
|
159
|
-
//# sourceMappingURL=chunk-
|
|
159
|
+
//# sourceMappingURL=chunk-2DYCHHWW.js.map
|
|
@@ -21,24 +21,21 @@ import {
|
|
|
21
21
|
toolSuccess,
|
|
22
22
|
withProgressHeartbeat,
|
|
23
23
|
wrapToolWithTimeout
|
|
24
|
-
} from "./chunk-
|
|
24
|
+
} from "./chunk-LP5ISXKM.js";
|
|
25
25
|
import {
|
|
26
26
|
getToolMemory
|
|
27
|
-
} from "./chunk-
|
|
27
|
+
} from "./chunk-FWQSOPBA.js";
|
|
28
28
|
import {
|
|
29
29
|
allOf
|
|
30
30
|
} from "./chunk-EZNIYU5T.js";
|
|
31
31
|
import {
|
|
32
32
|
VERSION
|
|
33
|
-
} from "./chunk-
|
|
34
|
-
import {
|
|
35
|
-
isGatewayModelAdapter
|
|
36
|
-
} from "./chunk-XQMQGUJT.js";
|
|
33
|
+
} from "./chunk-WD4DENPC.js";
|
|
37
34
|
import {
|
|
38
35
|
ModelBoundAdapter,
|
|
39
36
|
createEvent,
|
|
40
37
|
getGlobalRegistry
|
|
41
|
-
} from "./chunk-
|
|
38
|
+
} from "./chunk-UZJ6IPJR.js";
|
|
42
39
|
import {
|
|
43
40
|
UNVERIFIABLE_STDERR_RE,
|
|
44
41
|
classifyUnverifiable,
|
|
@@ -46,25 +43,28 @@ import {
|
|
|
46
43
|
getAvailableClis,
|
|
47
44
|
isAbsentSeat,
|
|
48
45
|
markUnverifiable
|
|
49
|
-
} from "./chunk-
|
|
46
|
+
} from "./chunk-QRC3QLUQ.js";
|
|
50
47
|
import {
|
|
51
48
|
ensureGatewayDiscovered
|
|
52
|
-
} from "./chunk-
|
|
49
|
+
} from "./chunk-LXYT2P2Y.js";
|
|
50
|
+
import {
|
|
51
|
+
isGatewayModelAdapter
|
|
52
|
+
} from "./chunk-KLSNDPU6.js";
|
|
53
53
|
import {
|
|
54
54
|
CLI_TO_MODELSDEV_VENDOR,
|
|
55
55
|
delay,
|
|
56
56
|
getAbortObservation,
|
|
57
57
|
sleep,
|
|
58
58
|
withTimeout
|
|
59
|
-
} from "./chunk-
|
|
59
|
+
} from "./chunk-23QA6GQD.js";
|
|
60
60
|
import {
|
|
61
61
|
getDefaultCliCircuitBreakerRegistry
|
|
62
|
-
} from "./chunk-
|
|
62
|
+
} from "./chunk-SX2XWCGA.js";
|
|
63
63
|
import {
|
|
64
64
|
sanitizeErrorDetails,
|
|
65
65
|
sanitizeOutput,
|
|
66
66
|
sanitizeStringLeaves
|
|
67
|
-
} from "./chunk-
|
|
67
|
+
} from "./chunk-QM5W3T3O.js";
|
|
68
68
|
import {
|
|
69
69
|
AgentError,
|
|
70
70
|
DecisionCostStore,
|
|
@@ -123,7 +123,7 @@ import {
|
|
|
123
123
|
servedCostDetail,
|
|
124
124
|
stepBus,
|
|
125
125
|
voteRecordWriteFailedMessage
|
|
126
|
-
} from "./chunk-
|
|
126
|
+
} from "./chunk-WKFPKPEM.js";
|
|
127
127
|
import {
|
|
128
128
|
ensureLearningDir,
|
|
129
129
|
getOutcomesFile
|
|
@@ -6658,7 +6658,7 @@ function logPartialProposal(bounded, log) {
|
|
|
6658
6658
|
}
|
|
6659
6659
|
async function runContrarianCheck(proposal, options, log, opts) {
|
|
6660
6660
|
try {
|
|
6661
|
-
const { executeExpert } = await import("./expert-bridge-
|
|
6661
|
+
const { executeExpert } = await import("./expert-bridge-O3UZXLGB.js");
|
|
6662
6662
|
const bounded = boundArtifactForReview(proposal, CONTRARIAN_PROPOSAL_BUDGET, "proposal");
|
|
6663
6663
|
logPartialProposal(bounded, log);
|
|
6664
6664
|
const result = await executeExpert(
|
|
@@ -9870,4 +9870,4 @@ export {
|
|
|
9870
9870
|
CONSENSUS_VOTE_TOOL_SCHEMA,
|
|
9871
9871
|
registerConsensusVoteTool
|
|
9872
9872
|
};
|
|
9873
|
-
//# sourceMappingURL=chunk-
|
|
9873
|
+
//# sourceMappingURL=chunk-2TA6KTRF.js.map
|
|
@@ -6,7 +6,7 @@ import {
|
|
|
6
6
|
getErrorMessage,
|
|
7
7
|
ok,
|
|
8
8
|
resolveInsideRoot
|
|
9
|
-
} from "./chunk-
|
|
9
|
+
} from "./chunk-WKFPKPEM.js";
|
|
10
10
|
import {
|
|
11
11
|
findRepoRoot,
|
|
12
12
|
getActiveWorkspaceRoot,
|
|
@@ -211,4 +211,4 @@ export {
|
|
|
211
211
|
loadPapersRegistry,
|
|
212
212
|
savePapersRegistry
|
|
213
213
|
};
|
|
214
|
-
//# sourceMappingURL=chunk-
|
|
214
|
+
//# sourceMappingURL=chunk-4JJI34RV.js.map
|
|
@@ -2,7 +2,7 @@ import {
|
|
|
2
2
|
createLogger,
|
|
3
3
|
err,
|
|
4
4
|
ok
|
|
5
|
-
} from "./chunk-
|
|
5
|
+
} from "./chunk-WKFPKPEM.js";
|
|
6
6
|
|
|
7
7
|
// src/scm/token-resolver.ts
|
|
8
8
|
import { execFile } from "node:child_process";
|
|
@@ -87,4 +87,4 @@ export {
|
|
|
87
87
|
hasToken,
|
|
88
88
|
getTokenEnvVars
|
|
89
89
|
};
|
|
90
|
-
//# sourceMappingURL=chunk-
|
|
90
|
+
//# sourceMappingURL=chunk-7EV3QAKO.js.map
|
|
@@ -1,14 +1,14 @@
|
|
|
1
1
|
import {
|
|
2
2
|
GitHubProvider,
|
|
3
3
|
ScmError
|
|
4
|
-
} from "./chunk-
|
|
4
|
+
} from "./chunk-U37AITDA.js";
|
|
5
5
|
import {
|
|
6
6
|
resolveToken
|
|
7
|
-
} from "./chunk-
|
|
7
|
+
} from "./chunk-7EV3QAKO.js";
|
|
8
8
|
import {
|
|
9
9
|
err,
|
|
10
10
|
ok
|
|
11
|
-
} from "./chunk-
|
|
11
|
+
} from "./chunk-WKFPKPEM.js";
|
|
12
12
|
|
|
13
13
|
// src/scm/factory.ts
|
|
14
14
|
async function createScmProvider(config) {
|
|
@@ -41,4 +41,4 @@ export {
|
|
|
41
41
|
createScmProvider,
|
|
42
42
|
createGitHubProvider
|
|
43
43
|
};
|
|
44
|
-
//# sourceMappingURL=chunk-
|
|
44
|
+
//# sourceMappingURL=chunk-D6E3LJGP.js.map
|
|
@@ -4,7 +4,7 @@ import {
|
|
|
4
4
|
createLogger,
|
|
5
5
|
formatZodError,
|
|
6
6
|
resolveInsideRoot
|
|
7
|
-
} from "./chunk-
|
|
7
|
+
} from "./chunk-WKFPKPEM.js";
|
|
8
8
|
|
|
9
9
|
// src/security/ast-rule-runner.ts
|
|
10
10
|
import { existsSync } from "node:fs";
|
|
@@ -241,4 +241,4 @@ export {
|
|
|
241
241
|
collectAstQaFindings,
|
|
242
242
|
runAstQaRules
|
|
243
243
|
};
|
|
244
|
-
//# sourceMappingURL=chunk-
|
|
244
|
+
//# sourceMappingURL=chunk-EJ5EBTAV.js.map
|
|
@@ -1,9 +1,9 @@
|
|
|
1
1
|
import {
|
|
2
2
|
loadPapersRegistry
|
|
3
|
-
} from "./chunk-
|
|
3
|
+
} from "./chunk-4JJI34RV.js";
|
|
4
4
|
import {
|
|
5
5
|
getErrorMessage
|
|
6
|
-
} from "./chunk-
|
|
6
|
+
} from "./chunk-WKFPKPEM.js";
|
|
7
7
|
|
|
8
8
|
// src/cli/research-helpers-synthesize.ts
|
|
9
9
|
import { z } from "zod";
|
|
@@ -876,4 +876,4 @@ export {
|
|
|
876
876
|
AttributedInsightSchema,
|
|
877
877
|
synthesizeResearch
|
|
878
878
|
};
|
|
879
|
-
//# sourceMappingURL=chunk-
|
|
879
|
+
//# sourceMappingURL=chunk-FNHVTDHZ.js.map
|
|
@@ -3,7 +3,7 @@ import {
|
|
|
3
3
|
} from "./chunk-ZO6ZKR7L.js";
|
|
4
4
|
import {
|
|
5
5
|
SessionMemory
|
|
6
|
-
} from "./chunk-
|
|
6
|
+
} from "./chunk-QS5HGPCN.js";
|
|
7
7
|
import {
|
|
8
8
|
TRUST_TIER_NUMERIC,
|
|
9
9
|
TrustTierSchema
|
|
@@ -17,7 +17,7 @@ import {
|
|
|
17
17
|
} from "./chunk-ROYGBFVE.js";
|
|
18
18
|
import {
|
|
19
19
|
generateId
|
|
20
|
-
} from "./chunk-
|
|
20
|
+
} from "./chunk-GAX75XCV.js";
|
|
21
21
|
import {
|
|
22
22
|
ErrorCode,
|
|
23
23
|
NexusError,
|
|
@@ -34,7 +34,7 @@ import {
|
|
|
34
34
|
stringifyValue,
|
|
35
35
|
tokenize,
|
|
36
36
|
tokenizeFiltered
|
|
37
|
-
} from "./chunk-
|
|
37
|
+
} from "./chunk-WKFPKPEM.js";
|
|
38
38
|
import {
|
|
39
39
|
nexusDataPath
|
|
40
40
|
} from "./chunk-LWOX65CP.js";
|
|
@@ -5841,4 +5841,4 @@ export {
|
|
|
5841
5841
|
shutdownToolMemory,
|
|
5842
5842
|
ToolMemoryManager
|
|
5843
5843
|
};
|
|
5844
|
-
//# sourceMappingURL=chunk-
|
|
5844
|
+
//# sourceMappingURL=chunk-FWQSOPBA.js.map
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import {
|
|
2
2
|
getRandomProvider,
|
|
3
3
|
getTimeProvider
|
|
4
|
-
} from "./chunk-
|
|
4
|
+
} from "./chunk-WKFPKPEM.js";
|
|
5
5
|
|
|
6
6
|
// src/utils/id-utils.ts
|
|
7
7
|
import { randomUUID } from "node:crypto";
|
|
@@ -24,4 +24,4 @@ export {
|
|
|
24
24
|
generateHyphenId,
|
|
25
25
|
generateUUID
|
|
26
26
|
};
|
|
27
|
-
//# sourceMappingURL=chunk-
|
|
27
|
+
//# sourceMappingURL=chunk-GAX75XCV.js.map
|
|
@@ -1,13 +1,13 @@
|
|
|
1
1
|
import {
|
|
2
2
|
ensureGatewayDiscovered,
|
|
3
3
|
gatewayDiscoveryGeneration
|
|
4
|
-
} from "./chunk-
|
|
4
|
+
} from "./chunk-LXYT2P2Y.js";
|
|
5
5
|
import {
|
|
6
6
|
createLogger,
|
|
7
7
|
getTimeProvider,
|
|
8
8
|
isRateLimitText,
|
|
9
9
|
resolveCliSlot
|
|
10
|
-
} from "./chunk-
|
|
10
|
+
} from "./chunk-WKFPKPEM.js";
|
|
11
11
|
|
|
12
12
|
// src/pipeline/expert-access-mode.ts
|
|
13
13
|
var logger = createLogger({ component: "expert-bridge" });
|
|
@@ -78,7 +78,7 @@ async function dispatchWithMcpConfig(router, content, expertType, start, options
|
|
|
78
78
|
let config;
|
|
79
79
|
if (requestedAccessModeOf(options) === "default") {
|
|
80
80
|
try {
|
|
81
|
-
const { generateMcpConfig } = await import("./child-mcp-config-
|
|
81
|
+
const { generateMcpConfig } = await import("./child-mcp-config-73BX4OTR.js");
|
|
82
82
|
config = await generateMcpConfig();
|
|
83
83
|
activeMcpConfigs.add(config);
|
|
84
84
|
} catch (error) {
|
|
@@ -167,8 +167,8 @@ async function getRouter() {
|
|
|
167
167
|
}
|
|
168
168
|
if (cachedRouter !== null) return cachedRouter;
|
|
169
169
|
routerInitPromise ??= (async () => {
|
|
170
|
-
const { createAllAdapters } = await import("./factory-
|
|
171
|
-
const { createCompositeRouter } = await import("./composite-router-
|
|
170
|
+
const { createAllAdapters } = await import("./factory-KCKQQAEH.js");
|
|
171
|
+
const { createCompositeRouter } = await import("./composite-router-YPZ3D5Y6.js");
|
|
172
172
|
const adapters = createAllAdapters();
|
|
173
173
|
const superseded = generation !== routerGeneration;
|
|
174
174
|
if (adapters.size === 0) {
|
|
@@ -179,7 +179,7 @@ async function getRouter() {
|
|
|
179
179
|
if (superseded) return router;
|
|
180
180
|
cachedRouter = router;
|
|
181
181
|
try {
|
|
182
|
-
const { createCliCircuitBreakerIntegration } = await import("./cli-circuit-breaker-
|
|
182
|
+
const { createCliCircuitBreakerIntegration } = await import("./cli-circuit-breaker-62YOQQT3.js");
|
|
183
183
|
cachedCircuitBreaker = createCliCircuitBreakerIntegration([...adapters.values()]);
|
|
184
184
|
} catch (error) {
|
|
185
185
|
const msg = error instanceof Error ? error.message : String(error);
|
|
@@ -320,4 +320,4 @@ export {
|
|
|
320
320
|
tokenSplitFromUsage,
|
|
321
321
|
executeExpert
|
|
322
322
|
};
|
|
323
|
-
//# sourceMappingURL=chunk-
|
|
323
|
+
//# sourceMappingURL=chunk-GX5ZHZR2.js.map
|
|
@@ -7,7 +7,7 @@ import {
|
|
|
7
7
|
toSdkCallback,
|
|
8
8
|
toolStructuredError,
|
|
9
9
|
wrapToolWithTimeout
|
|
10
|
-
} from "./chunk-
|
|
10
|
+
} from "./chunk-LP5ISXKM.js";
|
|
11
11
|
import {
|
|
12
12
|
JsonlStore,
|
|
13
13
|
SECURITY_KEYWORDS,
|
|
@@ -21,7 +21,7 @@ import {
|
|
|
21
21
|
hasMeasuredCategory,
|
|
22
22
|
isDeclaredNeverDeprecate,
|
|
23
23
|
isRegisteredToolName
|
|
24
|
-
} from "./chunk-
|
|
24
|
+
} from "./chunk-WKFPKPEM.js";
|
|
25
25
|
import {
|
|
26
26
|
getNexusDataDir,
|
|
27
27
|
nexusDataPath
|
|
@@ -2431,4 +2431,4 @@ export {
|
|
|
2431
2431
|
runImprovementReview,
|
|
2432
2432
|
registerImprovementReviewTool
|
|
2433
2433
|
};
|
|
2434
|
-
//# sourceMappingURL=chunk-
|
|
2434
|
+
//# sourceMappingURL=chunk-J44RKRGQ.js.map
|
|
@@ -4,7 +4,7 @@ import {
|
|
|
4
4
|
import {
|
|
5
5
|
createLogger,
|
|
6
6
|
getTimeProvider
|
|
7
|
-
} from "./chunk-
|
|
7
|
+
} from "./chunk-WKFPKPEM.js";
|
|
8
8
|
|
|
9
9
|
// src/mcp/tools/scanner-registry-fetcher.ts
|
|
10
10
|
import { z } from "zod";
|
|
@@ -740,4 +740,4 @@ export {
|
|
|
740
740
|
generateSecurityPlan,
|
|
741
741
|
buildPlanFromAnalysis
|
|
742
742
|
};
|
|
743
|
-
//# sourceMappingURL=chunk-
|
|
743
|
+
//# sourceMappingURL=chunk-JGY5HMWI.js.map
|
|
@@ -1,19 +1,17 @@
|
|
|
1
|
+
import {
|
|
2
|
+
CUSTOM_API_DEFAULT_MODEL
|
|
3
|
+
} from "./chunk-XSAUVC6D.js";
|
|
1
4
|
import {
|
|
2
5
|
GATEWAY_HOST_LOOKUP_TIMED_OUT,
|
|
3
6
|
checkGatewayHost,
|
|
4
7
|
createOpenAICompatAdapter,
|
|
5
8
|
discoverGatewayCatalog,
|
|
9
|
+
gatewayProxyUrl,
|
|
6
10
|
readOpenAICompatEnv
|
|
7
|
-
} from "./chunk-
|
|
8
|
-
import {
|
|
9
|
-
CUSTOM_API_DEFAULT_MODEL
|
|
10
|
-
} from "./chunk-XSAUVC6D.js";
|
|
11
|
-
import {
|
|
12
|
-
gatewayProxyUrl
|
|
13
|
-
} from "./chunk-K6M2ZWX5.js";
|
|
11
|
+
} from "./chunk-KLSNDPU6.js";
|
|
14
12
|
import {
|
|
15
13
|
redactGatewaySecrets
|
|
16
|
-
} from "./chunk-
|
|
14
|
+
} from "./chunk-KASBBKAQ.js";
|
|
17
15
|
import {
|
|
18
16
|
DEFAULT_OPENAI_COMPAT_ENDPOINT,
|
|
19
17
|
GATEWAY_COST_ENV,
|
|
@@ -31,7 +29,7 @@ import {
|
|
|
31
29
|
isCliDisabled,
|
|
32
30
|
symbols,
|
|
33
31
|
writeLine
|
|
34
|
-
} from "./chunk-
|
|
32
|
+
} from "./chunk-WKFPKPEM.js";
|
|
35
33
|
|
|
36
34
|
// src/cli/doctor-gateway-slots.ts
|
|
37
35
|
var FAMILY_SLOTS = [
|
|
@@ -384,4 +382,4 @@ export {
|
|
|
384
382
|
formatGatewayReport,
|
|
385
383
|
formatGatewaySlotWarnings
|
|
386
384
|
};
|
|
387
|
-
//# sourceMappingURL=chunk-
|
|
385
|
+
//# sourceMappingURL=chunk-JUUGLXSN.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/cli/doctor-gateway-slots.ts","../src/cli/doctor-gateway.ts","../src/cli/doctor-voter-transport.ts","../src/cli/doctor-gateway-report.ts"],"sourcesContent":["/**\n * What serves each gateway family slot, as `doctor` reports it (#6720).\n *\n * The decision is the router's own: `decideSlotServing` from\n * `cli-adapters/gateway-slot-arm.ts`, the function `buildGatewaySlotRouterArm`\n * reads. Only its inputs come from doctor's measurement: the gateway's slot\n * mapping, `NEXUS_DISABLED_CLIS`, and the CLI checks. Where the router defers\n * to its availability probe (`cli-or-gateway`), doctor has already run that\n * probe, so it resolves the slot to whichever target the probe would pick.\n *\n * @module cli/doctor-gateway-slots\n */\n\nimport { isCliDisabled } from '../cli-adapters/disabled-clis.js';\nimport { decideSlotServing } from '../cli-adapters/gateway-slot-arm.js';\nimport type { GatewayFamily, GatewaySlotMapping } from '../adapters/gateway-family-slots.js';\nimport type { CliCheckResult } from './doctor.js';\nimport type { GatewayHealth } from './doctor-gateway.js';\n\n/** A family slot of the gateway mapping. */\nexport type GatewayFamilySlot = keyof GatewaySlotMapping;\n\n/** The family slots in report order, with the family each one is served by. */\nconst FAMILY_SLOTS: readonly (readonly [GatewayFamilySlot, GatewayFamily])[] = [\n ['claude', 'anthropic'],\n ['codex', 'openai'],\n ['gemini', 'google'],\n];\n\n/** One slot: the target that serves it, and why. */\nexport interface GatewaySlotServing {\n readonly slot: GatewayFamilySlot;\n readonly family: GatewayFamily;\n /** The gateway model for the slot, or `'unavailable'` when the gateway has none. */\n readonly model: string;\n readonly serving: 'cli' | 'gateway' | 'unavailable';\n /** Disabled by `NEXUS_DISABLED_CLIS`. */\n readonly disabled: boolean;\n}\n\n/**\n * Each family slot's serving target on a healthy gateway; empty for any other\n * state, which has no slot mapping. A CLI absent from `clis` counts as not\n * installed: doctor checks every CLI it does not skip as disabled.\n */\nexport function gatewaySlotServing(\n health: GatewayHealth,\n clis: readonly CliCheckResult[]\n): readonly GatewaySlotServing[] {\n if (health.state !== 'healthy') return [];\n return FAMILY_SLOTS.map(([slot, family]) => {\n const model = health.slots[slot];\n const check = clis.find((c) => c.name === slot);\n const disabled = isCliDisabled(slot);\n const decided = decideSlotServing({\n disabled,\n onPath: () => check?.installed === true,\n gateway: model === 'unavailable' ? 'unavailable' : 'resolved',\n });\n if (decided !== 'cli-or-gateway') return { slot, family, model, serving: decided, disabled };\n // `routerAdmits` is the router's own predicate (`isCliAdmitted`) over\n // doctor's health check and auth probe, so this is the target it picks.\n const serving = check?.routerAdmits === true ? 'cli' : 'gateway';\n return { slot, family, model, serving, disabled };\n });\n}\n\n/** An installed CLI that fails its own check: unauthenticated or on an unsupported version. */\nexport function installedCliIsBroken(cli: CliCheckResult): boolean {\n return cli.installed && (!cli.authenticated || cli.versionStatus === 'unsupported');\n}\n\n/** An installed, broken CLI whose slot the gateway serves (#6782). */\ninterface GatewayCoveredCli {\n readonly cli: CliCheckResult['name'];\n /** The gateway model serving the slot. */\n readonly model: string;\n /** The CLI's own failure, for the report line. */\n readonly reason: string;\n}\n\n/**\n * Installed CLIs that fail their own check while the gateway actually serves\n * their slot (#6782). Service is unaffected, so they do not fail the verdict;\n * they are reported with ⚠ and named in the summary instead. The CLI's health\n * is its binary's own — the gateway's is never credited to it.\n */\nexport function gatewayCoveredClis(\n health: GatewayHealth,\n clis: readonly CliCheckResult[]\n): readonly GatewayCoveredCli[] {\n const served = gatewaySlotServing(health, clis).filter((s) => s.serving === 'gateway');\n return clis.filter(installedCliIsBroken).flatMap((cli) => {\n const slot = served.find((s) => s.slot === cli.name);\n if (slot === undefined) return [];\n return [{ cli: cli.name, model: slot.model, reason: brokenCliReason(cli) }];\n });\n}\n\n/** The CLI's own failure: its reported error, else the failed check. */\nfunction brokenCliReason(cli: CliCheckResult): string {\n if (cli.error !== undefined && cli.error !== '') return cli.error;\n return cli.versionStatus === 'unsupported'\n ? `unsupported version ${cli.version}`\n : 'not authenticated';\n}\n\n/** The report line for a gateway-covered CLI, with its remedy (#6782). */\nexport function formatGatewayCoveredCli(c: GatewayCoveredCli): string {\n return (\n `${c.cli} CLI installed but unhealthy (${c.reason}); slot served by gateway model ${c.model}. ` +\n `Repair the CLI, or set NEXUS_DISABLED_CLIS=${c.cli} to stop using it`\n );\n}\n\n/** Why the CLI does not serve its slot, for a report line. */\nfunction cliAbsence(s: GatewaySlotServing): string {\n return s.disabled ? 'CLI disabled by NEXUS_DISABLED_CLIS' : 'CLI not available';\n}\n\n/** The `doctor --gateway` line for one slot. */\nexport function formatSlotServing(s: GatewaySlotServing): string {\n switch (s.serving) {\n case 'gateway':\n return `${s.slot} → ${s.model} (gateway; ${cliAbsence(s)})`;\n case 'unavailable':\n return `${s.slot} → unavailable (${cliAbsence(s)}; the gateway has no ${s.family} model)`;\n case 'cli':\n return s.model === 'unavailable'\n ? `${s.slot} → CLI (the gateway has no ${s.family} model)`\n : `${s.slot} → CLI (installed and authenticated; ${s.model} if it stops being available)`;\n }\n}\n","/**\n * The gateway half of `nexus-agents doctor` (#6609, epic #6612).\n *\n * Before this, doctor printed \"✓ Voter transport: In-process gateway\" from the\n * presence of two env vars, and its verdict counted only vendor API keys and\n * installed CLIs — so a host served entirely by a working gateway always\n * exited 1, and a host whose gateway was down could still print a check mark.\n *\n * {@link checkGatewayHealth} MEASURES the gateway with the calls the server\n * itself makes: the private-address guard (`checkGatewayHost`) and discovery\n * (`GET /models`, chat filter, allowlist). The completion probe is opt-in\n * because it spends tokens. {@link gatewayVerdict} turns the measurement into\n * the one term `isAllHealthy` and `failingVerdictTerms` read.\n *\n * Secrets: the key, the extra header values and the proxy URL's userinfo\n * never reach the result. Errors are redacted of the key and every header\n * value before they are stored.\n *\n * @module cli/doctor-gateway\n */\n\nimport type { IModelAdapter } from '../core/index.js';\nimport { getErrorMessage, getTimeProvider } from '../core/index.js';\nimport {\n createOpenAICompatAdapter,\n discoverGatewayCatalog,\n readOpenAICompatEnv,\n type OpenAICompatConfig,\n} from '../adapters/openai-compat-adapter.js';\nimport {\n checkGatewayHost,\n GATEWAY_HOST_LOOKUP_TIMED_OUT,\n type GatewayHostStatus,\n} from '../adapters/gateway-host-status.js';\nimport { gatewayProxyUrl } from '../adapters/gateway-http.js';\nimport { redactGatewaySecrets } from '../adapters/gateway-redaction.js';\nimport {\n gatewayModelFamily,\n gatewaySlotMapping,\n type GatewayFamily,\n type GatewaySlotMapping,\n} from '../adapters/gateway-family-slots.js';\nimport type { CliCheckResult } from './doctor.js';\nimport { gatewaySlotServing, installedCliIsBroken } from './doctor-gateway-slots.js';\n\n/** Census buckets: the three slot families, and every model outside them. */\nexport type GatewayCensusBucket = GatewayFamily | 'unknown';\n\n/**\n * Chat models per family. `unknown` counts every model not classified as one\n * of the three: an unrecognised vendor and a recognised fourth vendor alike.\n */\nexport type GatewayCensus = Readonly<Record<GatewayCensusBucket, number>>;\n\n/**\n * How gateway calls leave the host. Never carries the proxy URL: it can hold\n * `user:password@`. `proxyHost` is host and port only.\n */\nexport type GatewayProxyStatus =\n | { readonly kind: 'direct' }\n | { readonly kind: 'proxy'; readonly proxyHost: string }\n /** A proxy variable is set, but `NO_PROXY` exempts the gateway host. */\n | { readonly kind: 'exempt' }\n /** A proxy variable is set but unusable (not http/https): calls go direct. */\n | { readonly kind: 'ignored' };\n\n/** One family's completion probe. */\nexport type GatewayCompletionProbe =\n | { readonly family: GatewayFamily; readonly outcome: 'no_model' }\n | {\n readonly family: GatewayFamily;\n readonly outcome: 'ok' | 'failed';\n readonly model: string;\n readonly latencyMs: number;\n /** Redacted of the key and header values. Present when `failed`. */\n readonly error?: string;\n };\n\n/** The measured gateway. Every state but `not_configured` names the host. */\nexport type GatewayHealth =\n | { readonly state: 'not_configured' }\n | {\n readonly state: 'refused_private_host';\n readonly host: string;\n readonly reason: string;\n readonly remedy: string;\n readonly proxy: GatewayProxyStatus;\n }\n | {\n /** `/models` failed: unreachable, refused, timed out, rejected the key, or over the cap. */\n readonly state: 'discovery_failed';\n readonly host: string;\n readonly error: string;\n readonly proxy: GatewayProxyStatus;\n }\n | {\n /** `/models` answered, but no model survived the chat filter and allowlist. */\n readonly state: 'no_chat_models';\n readonly host: string;\n readonly listedCount: number;\n readonly proxy: GatewayProxyStatus;\n }\n | {\n readonly state: 'healthy';\n readonly host: string;\n /** Rows `/models` returned, before the chat filter. */\n readonly listedCount: number;\n /** Chat models kept after the chat filter (and the allowlist, when set). */\n readonly chatCount: number;\n readonly allowlistActive: boolean;\n readonly census: GatewayCensus;\n readonly slots: GatewaySlotMapping;\n readonly proxy: GatewayProxyStatus;\n /** `skipped` unless the operator passed `--probe`. */\n readonly probes: readonly GatewayCompletionProbe[] | 'skipped';\n };\n\n/** The verdict term: no gateway, a gateway that works, or one that does not. */\nexport type GatewayVerdict = 'absent' | 'pass' | 'fail';\n\nconst PROBE_FAMILIES: readonly GatewayFamily[] = ['anthropic', 'openai', 'google'];\nconst PROBE_SLOT: Readonly<Record<GatewayFamily, keyof GatewaySlotMapping>> = {\n anthropic: 'claude',\n openai: 'codex',\n google: 'gemini',\n};\n/** Room for a reasoning model to think and still answer one word. */\nconst PROBE_MAX_TOKENS = 256;\nconst PROBE_TIMEOUT_MS = 30_000;\n\nexport interface GatewayHealthOptions {\n /** Send one completion per family. Spends tokens; off unless `--probe`. */\n readonly probe?: boolean;\n /** Injectable for tests; defaults to the server's reader. */\n readonly config?: OpenAICompatConfig | null;\n readonly env?: NodeJS.ProcessEnv;\n}\n\n/**\n * The health a host-guard outcome ends the check with, or `undefined` when the\n * host is allowed. A lookup timeout fails closed, as discovery does (#6671).\n */\nfunction hostGuardHealth(\n guard: GatewayHostStatus,\n proxy: GatewayProxyStatus\n): GatewayHealth | undefined {\n if (guard.state === 'refused_private_host') {\n const { host, reason, remedy } = guard;\n return { state: 'refused_private_host', host, reason, remedy, proxy };\n }\n if (guard.state === 'lookup_timed_out') {\n return {\n state: 'discovery_failed',\n host: guard.host,\n error: GATEWAY_HOST_LOOKUP_TIMED_OUT,\n proxy,\n };\n }\n return undefined;\n}\n\n/** Measure the configured gateway. `not_configured` makes no network call. */\nexport async function checkGatewayHealth(\n options: GatewayHealthOptions = {}\n): Promise<GatewayHealth> {\n const config = options.config !== undefined ? options.config : readOpenAICompatEnv();\n if (config === null) return { state: 'not_configured' };\n const env = options.env ?? process.env;\n const proxy = proxyStatus(config, env);\n const guard = await checkGatewayHost(config.baseUrl);\n const blocked = hostGuardHealth(guard, proxy);\n if (blocked !== undefined) return blocked;\n const host = guard.host;\n const discovered = await discoverGatewayCatalog(config);\n if (!discovered.ok) {\n return {\n state: 'discovery_failed',\n host,\n error: redact(discovered.error.message, config),\n proxy,\n };\n }\n const { listedCount, models } = discovered.value;\n if (models.length === 0) return { state: 'no_chat_models', host, listedCount, proxy };\n const adapters = models.map((m) => createOpenAICompatAdapter(m.id, config, m.created));\n const slots = gatewaySlotMapping(adapters, env);\n return {\n state: 'healthy',\n host,\n listedCount,\n chatCount: models.length,\n allowlistActive: (config.modelAllowlist ?? []).length > 0,\n census: censusOf(models.map((m) => m.id)),\n slots,\n proxy,\n probes: options.probe === true ? await probeFamilies(adapters, slots, config) : 'skipped',\n };\n}\n\n/** Chat models per family. */\nfunction censusOf(ids: readonly string[]): GatewayCensus {\n const census: Record<GatewayCensusBucket, number> = {\n anthropic: 0,\n openai: 0,\n google: 0,\n unknown: 0,\n };\n for (const id of ids) {\n const family = gatewayModelFamily(id);\n const bucket = family === undefined || family === 'other' ? 'unknown' : family;\n census[bucket] += 1;\n }\n return census;\n}\n\n/** The proxy the gateway's calls use, told apart from its three look-alikes. */\nfunction proxyStatus(config: OpenAICompatConfig, env: NodeJS.ProcessEnv): GatewayProxyStatus {\n if (config.proxyUrl !== undefined) return { kind: 'proxy', proxyHost: proxyHostOf(config) };\n if (gatewayProxyUrl(config.baseUrl, env) !== undefined) return { kind: 'ignored' };\n const withoutNoProxy = { ...env, no_proxy: undefined, NO_PROXY: undefined };\n if (gatewayProxyUrl(config.baseUrl, withoutNoProxy) !== undefined) return { kind: 'exempt' };\n return { kind: 'direct' };\n}\n\nfunction proxyHostOf(config: OpenAICompatConfig): string {\n try {\n return new URL(config.proxyUrl ?? '').host;\n } catch {\n return '<unparseable proxy>';\n }\n}\n\n/** One completion per family, in family order; a family with no model is not called. */\nasync function probeFamilies(\n adapters: readonly IModelAdapter[],\n slots: GatewaySlotMapping,\n config: OpenAICompatConfig\n): Promise<readonly GatewayCompletionProbe[]> {\n const probes: GatewayCompletionProbe[] = [];\n for (const family of PROBE_FAMILIES) {\n const model = slots[PROBE_SLOT[family]];\n const adapter = adapters.find((a) => a.modelId === model);\n if (adapter === undefined) {\n probes.push({ family, outcome: 'no_model' });\n continue;\n }\n probes.push(await probeOne(family, adapter, config));\n }\n return probes;\n}\n\nasync function probeOne(\n family: GatewayFamily,\n adapter: IModelAdapter,\n config: OpenAICompatConfig\n): Promise<GatewayCompletionProbe> {\n const clock = getTimeProvider();\n const started = clock.now();\n const base = { family, model: adapter.modelId };\n try {\n const result = await adapter.complete({\n messages: [{ role: 'user', content: 'Reply with the single word OK.' }],\n maxTokens: PROBE_MAX_TOKENS,\n timeoutMs: PROBE_TIMEOUT_MS,\n });\n const latencyMs = clock.now() - started;\n if (result.ok) return { ...base, outcome: 'ok', latencyMs };\n return { ...base, outcome: 'failed', latencyMs, error: redact(result.error.message, config) };\n } catch (e: unknown) {\n const latencyMs = clock.now() - started;\n return { ...base, outcome: 'failed', latencyMs, error: redact(getErrorMessage(e), config) };\n }\n}\n\n/** `message` with the key and every extra header value replaced. */\nfunction redact(message: string, config: OpenAICompatConfig): string {\n return redactGatewaySecrets(message, { apiKey: config.apiKey, headers: config.extraHeaders });\n}\n\n/** A vendor slot the gateway can serve: one per family. */\ntype GatewaySlot = keyof GatewaySlotMapping;\n\n/**\n * The family slots a healthy gateway does NOT serve, in family order (#6658):\n * each slot that resolved to `unavailable`. This is also exactly the set of\n * `--probe` `no_model` results — `probeFamilies` reads the same mapping — so a\n * `no_model` family counts against the verdict the same way. Empty for any\n * other state: there is no slot mapping to read.\n */\nfunction unservedGatewaySlots(health: GatewayHealth): readonly GatewaySlot[] {\n if (health.state !== 'healthy') return [];\n const { slots } = health;\n return PROBE_FAMILIES.map((family) => PROBE_SLOT[family]).filter(\n (slot) => slots[slot] === 'unavailable'\n );\n}\n\n/**\n * The verdict term. A requested probe that failed fails the gateway: it was\n * asked whether the gateway serves, and it said no. A gateway that serves NO\n * family slot fails too (#6658): it answered `/models` but every pinned slot\n * would throw \"unavailable\" at use. One that serves SOME slots passes, and\n * {@link gatewaySlotWarnings} names each slot it does not serve.\n */\nexport function gatewayVerdict(health: GatewayHealth): GatewayVerdict {\n if (health.state === 'not_configured') return 'absent';\n if (health.state !== 'healthy') return 'fail';\n const failed = health.probes !== 'skipped' && health.probes.some((p) => p.outcome === 'failed');\n if (failed) return 'fail';\n return unservedGatewaySlots(health).length < PROBE_FAMILIES.length ? 'pass' : 'fail';\n}\n\n/**\n * One warning per family slot the passing gateway leaves with no arm (#6658):\n * its CLI is missing or disabled by `NEXUS_DISABLED_CLIS` (#6720), and the\n * gateway has no model of its family — the router's own decision, read via\n * {@link gatewaySlotServing}. Such a slot does not fail the verdict — other\n * slots work — but a task pinned to it throws \"unavailable\" at use, so it is\n * named rather than silently excused. opencode has no gateway slot, so a\n * missing opencode is always named. No warning when the gateway does not\n * pass: the missing CLIs then fail the verdict themselves\n * ({@link cliFailsVerdict}).\n */\nexport function gatewaySlotWarnings(\n health: GatewayHealth,\n clis: readonly CliCheckResult[]\n): string[] {\n if (gatewayVerdict(health) !== 'pass') return [];\n const missing = (name: CliCheckResult['name']): boolean =>\n clis.some((c) => c.name === name && !c.installed);\n const warnings = gatewaySlotServing(health, clis)\n .filter((s) => s.serving === 'unavailable')\n .map((s) => {\n const why = s.disabled ? 'disabled by NEXUS_DISABLED_CLIS' : 'not installed';\n return `${s.slot} slot unavailable: ${why}, and the gateway has no ${s.family} model`;\n });\n if (missing('opencode')) {\n warnings.push('opencode slot unavailable: not installed, and the gateway has no opencode slot');\n }\n return warnings;\n}\n\n/**\n * The `doctor --gateway` line for each family slot the gateway does not serve,\n * in family order — or one line saying no slot is served, the case\n * {@link gatewayVerdict} fails on.\n */\nexport function unservedSlotLines(health: GatewayHealth): string[] {\n const unserved = unservedGatewaySlots(health);\n if (health.state !== 'healthy' || unserved.length === 0) return [];\n if (unserved.length === PROBE_FAMILIES.length) {\n return [\n 'no slot has a gateway model: every pinned claude, codex or gemini slot is unavailable',\n ];\n }\n return PROBE_FAMILIES.filter((f) => unserved.includes(PROBE_SLOT[f])).map(\n (f) => `${PROBE_SLOT[f]} slot unavailable: the gateway has no ${f} model`\n );\n}\n\n/**\n * Whether one CLI counts against the verdict. With a passing gateway — one\n * that serves at least one family slot — a CLI that is not installed does\n * not. When its own slot has a gateway model it is excused outright; when it\n * has none (or it is opencode, which never has one) it is a named warning\n * from {@link gatewaySlotWarnings}, not a failure (#6658). A host with zero\n * served slots has a failing gateway, so every missing CLI counts. An\n * installed CLI still has to be authenticated and supported — unless the\n * gateway actually serves its slot (`gatewayCovered`, from\n * `gatewayCoveredClis` in `doctor-gateway-slots.ts`): service is unaffected, so it is a named ⚠, not\n * a failure (#6782). A broken CLI whose slot nothing serves still fails.\n */\nexport function cliFailsVerdict(\n cli: CliCheckResult,\n gateway: GatewayVerdict,\n gatewayCovered: boolean\n): boolean {\n if (!cli.installed) return gateway !== 'pass';\n return installedCliIsBroken(cli) && !gatewayCovered;\n}\n","/**\n * Doctor lines for the voter transport (#4255) and the gateway's cost\n * declaration (#4392 increment 2). A sibling of `doctor-formatting.ts` for\n * the file cap, in the same shape as `doctor-claude-model.ts`.\n *\n * @module cli/doctor-voter-transport\n */\n\nimport { describeGatewayCostDeclaration } from '../adapters/sdk/gateway-cost.js';\nimport {\n DEFAULT_OPENAI_COMPAT_ENDPOINT,\n GATEWAY_COST_ENV,\n OPENAI_COMPAT_ENDPOINT_ENV,\n OPENAI_COMPAT_KEY_ENV,\n OPENAI_COMPAT_URL_ENV,\n} from '../adapters/sdk/types.js';\nimport type { VoterTransportCheck } from './doctor.js';\nimport type { GatewayHealth } from './doctor-gateway.js';\nimport { colors, symbols, writeLine } from './ansi-output.js';\n\nconst CHECK = `${colors.green}${symbols.check}${colors.reset}`;\nconst WARN = `${colors.yellow}${symbols.warn}${colors.reset}`;\nconst CROSS = `${colors.red}${symbols.cross}${colors.reset}`;\n\n/**\n * Prints which transport voter/consensus calls will use (#4255): an\n * in-process OpenAI-compatible gateway when configured, else the CLI\n * subprocess round-robin fallback. A configured gateway is followed by its\n * cost line. The gateway line reports the MEASURED gateway (#6609), not the\n * presence of its env vars: a gateway whose discovery fails is not used, and\n * the server falls back to CLI subprocesses.\n */\nexport function printVoterTransportCheck(check: VoterTransportCheck, gateway: GatewayHealth): void {\n if (check.configured) {\n writeLine(gatewayTransportLine(gateway));\n printGatewayCostLine(check.cost);\n return;\n }\n writeLine(`${CHECK} Voter transport: ${colors.dim}CLI subprocess${colors.reset}`);\n writeLine(\n ` ${colors.dim}Set ${OPENAI_COMPAT_URL_ENV} and ${OPENAI_COMPAT_KEY_ENV} for faster in-process voting${colors.reset}`\n );\n}\n\nconst CEILING_CONSEQUENCE =\n 'the task-class cost ceiling and the per-task budget exclude this gateway until declared';\n\n/** One warning per gap, each naming its own fix (see `VoterTransportCheck.cost`). */\nconst GAP_LINES: Record<'unset' | 'invalid' | 'no-default', string> = {\n unset: `Gateway cost: UNSET — set ${GATEWAY_COST_ENV}=free|local|priced[:<in>,<out>]; ${CEILING_CONSEQUENCE}`,\n invalid: `Gateway cost: INVALID — ${GATEWAY_COST_ENV} does not parse (the startup env warning names the reason); ${CEILING_CONSEQUENCE}`,\n 'no-default': `Gateway cost: NOT DECLARED for the voter gateway — ${GATEWAY_COST_ENV} names neither a bare declaration nor this gateway's endpoint (${OPENAI_COMPAT_ENDPOINT_ENV}, default ${DEFAULT_OPENAI_COMPAT_ENDPOINT}); add a bare or <endpoint>= entry; ${CEILING_CONSEQUENCE}`,\n};\n\n/**\n * The gateway's cost declaration. Each gap is a warning that names its fix\n * and the consequence; none touches `allHealthy`. No line at all when no\n * gateway is configured (`cost` absent).\n */\nfunction printGatewayCostLine(cost: VoterTransportCheck['cost']): void {\n if (cost === undefined) return;\n if (typeof cost === 'string') {\n writeLine(`${WARN} ${GAP_LINES[cost]}`);\n return;\n }\n writeLine(`${CHECK} Gateway cost: ${describeGatewayCostDeclaration(cost)}`);\n}\n\n/** The voter-transport line for a configured gateway, from its measurement. */\nfunction gatewayTransportLine(gateway: GatewayHealth): string {\n switch (gateway.state) {\n case 'healthy':\n return (\n `${CHECK} Voter transport: In-process gateway (${gateway.host}: ` +\n `${String(gateway.chatCount)} chat models answered /models)`\n );\n case 'not_configured':\n // The env names a gateway but its config did not read: nothing was measured.\n return `${WARN} Voter transport: In-process gateway (not measured)`;\n default:\n return (\n `${CROSS} Voter transport: In-process gateway at ${gateway.host} FAILED ` +\n `(${gatewayFailureReason(gateway)}); voters fall back to CLI subprocesses`\n );\n }\n}\n\n/** Why a configured gateway is not in use, naming no secret. */\nexport function gatewayFailureReason(\n gateway: Exclude<GatewayHealth, { state: 'healthy' | 'not_configured' }>\n): string {\n switch (gateway.state) {\n case 'refused_private_host':\n return `private-address guard refused it: ${gateway.reason}`;\n case 'discovery_failed':\n return gateway.error;\n case 'no_chat_models':\n return `/models listed ${String(gateway.listedCount)} models, none of them chat models`;\n }\n}\n","/**\n * The `doctor --gateway` section (#6609): what the gateway measurement in\n * `doctor-gateway.ts` found, line by line. Rendering only; the verdict lives\n * in `gatewayVerdict`. Prints no key, header value or proxy credential — the\n * measurement never holds them.\n *\n * @module cli/doctor-gateway-report\n */\n\nimport {\n OPENAI_COMPAT_KEY_ENV,\n OPENAI_COMPAT_MODELS_ENV,\n OPENAI_COMPAT_URL_ENV,\n} from '../adapters/sdk/types.js';\nimport type { CliCheckResult } from './doctor.js';\nimport {\n gatewaySlotWarnings,\n gatewayVerdict,\n unservedSlotLines,\n type GatewayCompletionProbe,\n type GatewayHealth,\n type GatewayProxyStatus,\n} from './doctor-gateway.js';\nimport { gatewayFailureReason } from './doctor-voter-transport.js';\nimport { formatSlotServing, gatewaySlotServing } from './doctor-gateway-slots.js';\nimport { colors, symbols } from './ansi-output.js';\nimport { CUSTOM_API_DEFAULT_MODEL } from '../config/defaults.js';\n\nconst CHECK = `${colors.green}${symbols.check}${colors.reset}`;\nconst CROSS = `${colors.red}${symbols.cross}${colors.reset}`;\nconst WARN = `${colors.yellow}${symbols.warn}${colors.reset}`;\n\n/** Says what the probe costs whether or not it ran, so the flag is never a surprise. */\nconst PROBE_COST_NOTE = 'one tiny completion per family; this spends gateway tokens';\n\n/**\n * The `doctor --gateway` section as lines. `clis` are doctor's CLI checks;\n * each slot line says what serves the slot, decided as the router decides it\n * ({@link gatewaySlotServing}, #6720). Omitted, no CLI counts as installed.\n */\nexport function formatGatewayReport(\n health: GatewayHealth,\n clis: readonly CliCheckResult[] = []\n): string[] {\n const lines = [`${colors.cyan}Checking gateway (doctor --gateway)...${colors.reset}`, ''];\n if (health.state === 'not_configured') {\n lines.push(\n `${WARN} Gateway: not configured — set ${OPENAI_COMPAT_URL_ENV} and ${OPENAI_COMPAT_KEY_ENV}`\n );\n return lines;\n }\n if (health.state !== 'healthy') {\n lines.push(`${CROSS} Gateway ${health.host}: FAILED — ${gatewayFailureReason(health)}`);\n if (health.state === 'refused_private_host') lines.push(` ${health.remedy}`);\n lines.push(` Proxy: ${formatProxy(health.proxy)}`, unverifiedFallbackLine());\n return lines;\n }\n const filter = health.allowlistActive\n ? `after the chat filter and ${OPENAI_COMPAT_MODELS_ENV}`\n : 'after the chat filter';\n const { census } = health;\n lines.push(\n `${CHECK} Gateway ${health.host}: /models answered`,\n ` Private-address guard: allowed`,\n ` Proxy: ${formatProxy(health.proxy)}`,\n ` Models: ${String(health.listedCount)} listed, ${String(health.chatCount)} chat models ${filter}`,\n ` Families: anthropic ${String(census.anthropic)}, openai ${String(census.openai)}, ` +\n `google ${String(census.google)}, unknown ${String(census.unknown)}`,\n ` Slots (an available CLI serves its own slot first):`,\n ...gatewaySlotServing(health, clis).map((s) => ` ${formatSlotServing(s)}`),\n ...formatProbes(health.probes),\n ...formatUnservedSlots(health)\n );\n return lines;\n}\n\n/**\n * The missing CLIs a passing gateway cannot stand in for, one warning line\n * each (#6658). Printed with every `doctor` run, `--gateway` or not: they are\n * not failures — other slots work — but they are never silently excused.\n */\nexport function formatGatewaySlotWarnings(\n health: GatewayHealth,\n clis: readonly CliCheckResult[]\n): string[] {\n return gatewaySlotWarnings(health, clis).map((warning) => `${WARN} ${warning}`);\n}\n\n/**\n * Each family slot the gateway does not serve (#6658): a warning while some\n * slot works, a failure when none does — the same line `gatewayVerdict` fails on.\n */\nfunction formatUnservedSlots(health: GatewayHealth): string[] {\n const glyph = gatewayVerdict(health) === 'fail' ? CROSS : WARN;\n return unservedSlotLines(health).map((line) => ` ${glyph} ${line}`);\n}\n\nfunction formatProxy(proxy: GatewayProxyStatus): string {\n switch (proxy.kind) {\n case 'direct':\n return 'direct (no proxy variable applies)';\n case 'proxy':\n return `via ${proxy.proxyHost}`;\n case 'exempt':\n return 'direct (NO_PROXY exempts the gateway host)';\n case 'ignored':\n return 'direct (the proxy variable is not a usable http(s) URL; see the startup warning)';\n }\n}\n\nfunction formatProbes(probes: readonly GatewayCompletionProbe[] | 'skipped'): string[] {\n if (probes === 'skipped') {\n return [` Completion probe: skipped — pass --probe to send ${PROBE_COST_NOTE}`];\n }\n return [` Completion probe (${PROBE_COST_NOTE}):`, ...probes.map(formatProbe)];\n}\n\nfunction formatProbe(probe: GatewayCompletionProbe): string {\n if (probe.outcome === 'no_model') {\n return ` ${WARN} ${probe.family}: no gateway model of this family, not probed`;\n }\n const ms = `${String(probe.latencyMs)} ms`;\n if (probe.outcome === 'ok')\n return ` ${CHECK} ${probe.family}: ${probe.model} answered (${ms})`;\n return ` ${CROSS} ${probe.family}: ${probe.model} FAILED (${ms}) — ${probe.error ?? 'no error message'}`;\n}\n\n/**\n * #4392: with no catalogue, the single-model custom-openai adapter still sends\n * `NEXUS_CUSTOM_MODEL` (or the built-in default) — and nothing says the\n * gateway serves it. Named here so the operator sees it before a call fails.\n */\nfunction unverifiedFallbackLine(): string {\n const model = process.env['NEXUS_CUSTOM_MODEL'] ?? CUSTOM_API_DEFAULT_MODEL;\n return (\n ` ${WARN} No catalogue: the custom-openai fallback sends '${model}' unverified ` +\n 'and gateway family slots are unavailable'\n );\n}\n"],"mappings":"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","names":["CHECK","CROSS","WARN"]}
|
|
1
|
+
{"version":3,"sources":["../src/cli/doctor-gateway-slots.ts","../src/cli/doctor-gateway.ts","../src/cli/doctor-voter-transport.ts","../src/cli/doctor-gateway-report.ts"],"sourcesContent":["/**\n * What serves each gateway family slot, as `doctor` reports it (#6720).\n *\n * The decision is the router's own: `decideSlotServing` from\n * `cli-adapters/gateway-slot-arm.ts`, the function `buildGatewaySlotRouterArm`\n * reads. Only its inputs come from doctor's measurement: the gateway's slot\n * mapping, `NEXUS_DISABLED_CLIS`, and the CLI checks. Where the router defers\n * to its availability probe (`cli-or-gateway`), doctor has already run that\n * probe, so it resolves the slot to whichever target the probe would pick.\n *\n * @module cli/doctor-gateway-slots\n */\n\nimport { isCliDisabled } from '../cli-adapters/disabled-clis.js';\nimport { decideSlotServing } from '../cli-adapters/gateway-slot-arm.js';\nimport type { GatewayFamily, GatewaySlotMapping } from '../adapters/gateway-family-slots.js';\nimport type { CliCheckResult } from './doctor.js';\nimport type { GatewayHealth } from './doctor-gateway.js';\n\n/** A family slot of the gateway mapping. */\nexport type GatewayFamilySlot = keyof GatewaySlotMapping;\n\n/** The family slots in report order, with the family each one is served by. */\nconst FAMILY_SLOTS: readonly (readonly [GatewayFamilySlot, GatewayFamily])[] = [\n ['claude', 'anthropic'],\n ['codex', 'openai'],\n ['gemini', 'google'],\n];\n\n/** One slot: the target that serves it, and why. */\nexport interface GatewaySlotServing {\n readonly slot: GatewayFamilySlot;\n readonly family: GatewayFamily;\n /** The gateway model for the slot, or `'unavailable'` when the gateway has none. */\n readonly model: string;\n readonly serving: 'cli' | 'gateway' | 'unavailable';\n /** Disabled by `NEXUS_DISABLED_CLIS`. */\n readonly disabled: boolean;\n}\n\n/**\n * Each family slot's serving target on a healthy gateway; empty for any other\n * state, which has no slot mapping. A CLI absent from `clis` counts as not\n * installed: doctor checks every CLI it does not skip as disabled.\n */\nexport function gatewaySlotServing(\n health: GatewayHealth,\n clis: readonly CliCheckResult[]\n): readonly GatewaySlotServing[] {\n if (health.state !== 'healthy') return [];\n return FAMILY_SLOTS.map(([slot, family]) => {\n const model = health.slots[slot];\n const check = clis.find((c) => c.name === slot);\n const disabled = isCliDisabled(slot);\n const decided = decideSlotServing({\n disabled,\n onPath: () => check?.installed === true,\n gateway: model === 'unavailable' ? 'unavailable' : 'resolved',\n });\n if (decided !== 'cli-or-gateway') return { slot, family, model, serving: decided, disabled };\n // `routerAdmits` is the router's own predicate (`isCliAdmitted`) over\n // doctor's health check and auth probe, so this is the target it picks.\n const serving = check?.routerAdmits === true ? 'cli' : 'gateway';\n return { slot, family, model, serving, disabled };\n });\n}\n\n/** An installed CLI that fails its own check: unauthenticated or on an unsupported version. */\nexport function installedCliIsBroken(cli: CliCheckResult): boolean {\n return cli.installed && (!cli.authenticated || cli.versionStatus === 'unsupported');\n}\n\n/** An installed, broken CLI whose slot the gateway serves (#6782). */\ninterface GatewayCoveredCli {\n readonly cli: CliCheckResult['name'];\n /** The gateway model serving the slot. */\n readonly model: string;\n /** The CLI's own failure, for the report line. */\n readonly reason: string;\n}\n\n/**\n * Installed CLIs that fail their own check while the gateway actually serves\n * their slot (#6782). Service is unaffected, so they do not fail the verdict;\n * they are reported with ⚠ and named in the summary instead. The CLI's health\n * is its binary's own — the gateway's is never credited to it.\n */\nexport function gatewayCoveredClis(\n health: GatewayHealth,\n clis: readonly CliCheckResult[]\n): readonly GatewayCoveredCli[] {\n const served = gatewaySlotServing(health, clis).filter((s) => s.serving === 'gateway');\n return clis.filter(installedCliIsBroken).flatMap((cli) => {\n const slot = served.find((s) => s.slot === cli.name);\n if (slot === undefined) return [];\n return [{ cli: cli.name, model: slot.model, reason: brokenCliReason(cli) }];\n });\n}\n\n/** The CLI's own failure: its reported error, else the failed check. */\nfunction brokenCliReason(cli: CliCheckResult): string {\n if (cli.error !== undefined && cli.error !== '') return cli.error;\n return cli.versionStatus === 'unsupported'\n ? `unsupported version ${cli.version}`\n : 'not authenticated';\n}\n\n/** The report line for a gateway-covered CLI, with its remedy (#6782). */\nexport function formatGatewayCoveredCli(c: GatewayCoveredCli): string {\n return (\n `${c.cli} CLI installed but unhealthy (${c.reason}); slot served by gateway model ${c.model}. ` +\n `Repair the CLI, or set NEXUS_DISABLED_CLIS=${c.cli} to stop using it`\n );\n}\n\n/** Why the CLI does not serve its slot, for a report line. */\nfunction cliAbsence(s: GatewaySlotServing): string {\n return s.disabled ? 'CLI disabled by NEXUS_DISABLED_CLIS' : 'CLI not available';\n}\n\n/** The `doctor --gateway` line for one slot. */\nexport function formatSlotServing(s: GatewaySlotServing): string {\n switch (s.serving) {\n case 'gateway':\n return `${s.slot} → ${s.model} (gateway; ${cliAbsence(s)})`;\n case 'unavailable':\n return `${s.slot} → unavailable (${cliAbsence(s)}; the gateway has no ${s.family} model)`;\n case 'cli':\n return s.model === 'unavailable'\n ? `${s.slot} → CLI (the gateway has no ${s.family} model)`\n : `${s.slot} → CLI (installed and authenticated; ${s.model} if it stops being available)`;\n }\n}\n","/**\n * The gateway half of `nexus-agents doctor` (#6609, epic #6612).\n *\n * Before this, doctor printed \"✓ Voter transport: In-process gateway\" from the\n * presence of two env vars, and its verdict counted only vendor API keys and\n * installed CLIs — so a host served entirely by a working gateway always\n * exited 1, and a host whose gateway was down could still print a check mark.\n *\n * {@link checkGatewayHealth} MEASURES the gateway with the calls the server\n * itself makes: the private-address guard (`checkGatewayHost`) and discovery\n * (`GET /models`, chat filter, allowlist). The completion probe is opt-in\n * because it spends tokens. {@link gatewayVerdict} turns the measurement into\n * the one term `isAllHealthy` and `failingVerdictTerms` read.\n *\n * Secrets: the key, the extra header values and the proxy URL's userinfo\n * never reach the result. Errors are redacted of the key and every header\n * value before they are stored.\n *\n * @module cli/doctor-gateway\n */\n\nimport type { IModelAdapter } from '../core/index.js';\nimport { getErrorMessage, getTimeProvider } from '../core/index.js';\nimport {\n createOpenAICompatAdapter,\n discoverGatewayCatalog,\n readOpenAICompatEnv,\n type OpenAICompatConfig,\n} from '../adapters/openai-compat-adapter.js';\nimport {\n checkGatewayHost,\n GATEWAY_HOST_LOOKUP_TIMED_OUT,\n type GatewayHostStatus,\n} from '../adapters/gateway-host-status.js';\nimport { gatewayProxyUrl } from '../adapters/gateway-http.js';\nimport { redactGatewaySecrets } from '../adapters/gateway-redaction.js';\nimport {\n gatewayModelFamily,\n gatewaySlotMapping,\n type GatewayFamily,\n type GatewaySlotMapping,\n} from '../adapters/gateway-family-slots.js';\nimport type { CliCheckResult } from './doctor.js';\nimport { gatewaySlotServing, installedCliIsBroken } from './doctor-gateway-slots.js';\n\n/** Census buckets: the three slot families, and every model outside them. */\nexport type GatewayCensusBucket = GatewayFamily | 'unknown';\n\n/**\n * Chat models per family. `unknown` counts every model not classified as one\n * of the three: an unrecognised vendor and a recognised fourth vendor alike.\n */\nexport type GatewayCensus = Readonly<Record<GatewayCensusBucket, number>>;\n\n/**\n * How gateway calls leave the host. Never carries the proxy URL: it can hold\n * `user:password@`. `proxyHost` is host and port only.\n */\nexport type GatewayProxyStatus =\n | { readonly kind: 'direct' }\n | { readonly kind: 'proxy'; readonly proxyHost: string }\n /** A proxy variable is set, but `NO_PROXY` exempts the gateway host. */\n | { readonly kind: 'exempt' }\n /** A proxy variable is set but unusable (not http/https): calls go direct. */\n | { readonly kind: 'ignored' };\n\n/** One family's completion probe. */\nexport type GatewayCompletionProbe =\n | { readonly family: GatewayFamily; readonly outcome: 'no_model' }\n | {\n readonly family: GatewayFamily;\n readonly outcome: 'ok' | 'failed';\n readonly model: string;\n readonly latencyMs: number;\n /** Redacted of the key and header values. Present when `failed`. */\n readonly error?: string;\n };\n\n/** The measured gateway. Every state but `not_configured` names the host. */\nexport type GatewayHealth =\n | { readonly state: 'not_configured' }\n | {\n readonly state: 'refused_private_host';\n readonly host: string;\n readonly reason: string;\n readonly remedy: string;\n readonly proxy: GatewayProxyStatus;\n }\n | {\n /** `/models` failed: unreachable, refused, timed out, rejected the key, or over the cap. */\n readonly state: 'discovery_failed';\n readonly host: string;\n readonly error: string;\n readonly proxy: GatewayProxyStatus;\n }\n | {\n /** `/models` answered, but no model survived the chat filter and allowlist. */\n readonly state: 'no_chat_models';\n readonly host: string;\n readonly listedCount: number;\n readonly proxy: GatewayProxyStatus;\n }\n | {\n readonly state: 'healthy';\n readonly host: string;\n /** Rows `/models` returned, before the chat filter. */\n readonly listedCount: number;\n /** Chat models kept after the chat filter (and the allowlist, when set). */\n readonly chatCount: number;\n readonly allowlistActive: boolean;\n readonly census: GatewayCensus;\n readonly slots: GatewaySlotMapping;\n readonly proxy: GatewayProxyStatus;\n /** `skipped` unless the operator passed `--probe`. */\n readonly probes: readonly GatewayCompletionProbe[] | 'skipped';\n };\n\n/** The verdict term: no gateway, a gateway that works, or one that does not. */\nexport type GatewayVerdict = 'absent' | 'pass' | 'fail';\n\nconst PROBE_FAMILIES: readonly GatewayFamily[] = ['anthropic', 'openai', 'google'];\nconst PROBE_SLOT: Readonly<Record<GatewayFamily, keyof GatewaySlotMapping>> = {\n anthropic: 'claude',\n openai: 'codex',\n google: 'gemini',\n};\n/** Room for a reasoning model to think and still answer one word. */\nconst PROBE_MAX_TOKENS = 256;\nconst PROBE_TIMEOUT_MS = 30_000;\n\nexport interface GatewayHealthOptions {\n /** Send one completion per family. Spends tokens; off unless `--probe`. */\n readonly probe?: boolean;\n /** Injectable for tests; defaults to the server's reader. */\n readonly config?: OpenAICompatConfig | null;\n readonly env?: NodeJS.ProcessEnv;\n}\n\n/**\n * The health a host-guard outcome ends the check with, or `undefined` when the\n * host is allowed. A lookup timeout fails closed, as discovery does (#6671).\n */\nfunction hostGuardHealth(\n guard: GatewayHostStatus,\n proxy: GatewayProxyStatus\n): GatewayHealth | undefined {\n if (guard.state === 'refused_private_host') {\n const { host, reason, remedy } = guard;\n return { state: 'refused_private_host', host, reason, remedy, proxy };\n }\n if (guard.state === 'lookup_timed_out') {\n return {\n state: 'discovery_failed',\n host: guard.host,\n error: GATEWAY_HOST_LOOKUP_TIMED_OUT,\n proxy,\n };\n }\n return undefined;\n}\n\n/** Measure the configured gateway. `not_configured` makes no network call. */\nexport async function checkGatewayHealth(\n options: GatewayHealthOptions = {}\n): Promise<GatewayHealth> {\n const config = options.config !== undefined ? options.config : readOpenAICompatEnv();\n if (config === null) return { state: 'not_configured' };\n const env = options.env ?? process.env;\n const proxy = proxyStatus(config, env);\n const guard = await checkGatewayHost(config.baseUrl);\n const blocked = hostGuardHealth(guard, proxy);\n if (blocked !== undefined) return blocked;\n const host = guard.host;\n const discovered = await discoverGatewayCatalog(config);\n if (!discovered.ok) {\n return {\n state: 'discovery_failed',\n host,\n error: redact(discovered.error.message, config),\n proxy,\n };\n }\n const { listedCount, models } = discovered.value;\n if (models.length === 0) return { state: 'no_chat_models', host, listedCount, proxy };\n const adapters = models.map((m) => createOpenAICompatAdapter(m.id, config, m.created));\n const slots = gatewaySlotMapping(adapters, env);\n return {\n state: 'healthy',\n host,\n listedCount,\n chatCount: models.length,\n allowlistActive: (config.modelAllowlist ?? []).length > 0,\n census: censusOf(models.map((m) => m.id)),\n slots,\n proxy,\n probes: options.probe === true ? await probeFamilies(adapters, slots, config) : 'skipped',\n };\n}\n\n/** Chat models per family. */\nfunction censusOf(ids: readonly string[]): GatewayCensus {\n const census: Record<GatewayCensusBucket, number> = {\n anthropic: 0,\n openai: 0,\n google: 0,\n unknown: 0,\n };\n for (const id of ids) {\n const family = gatewayModelFamily(id);\n const bucket = family === undefined || family === 'other' ? 'unknown' : family;\n census[bucket] += 1;\n }\n return census;\n}\n\n/** The proxy the gateway's calls use, told apart from its three look-alikes. */\nfunction proxyStatus(config: OpenAICompatConfig, env: NodeJS.ProcessEnv): GatewayProxyStatus {\n if (config.proxyUrl !== undefined) return { kind: 'proxy', proxyHost: proxyHostOf(config) };\n if (gatewayProxyUrl(config.baseUrl, env) !== undefined) return { kind: 'ignored' };\n const withoutNoProxy = { ...env, no_proxy: undefined, NO_PROXY: undefined };\n if (gatewayProxyUrl(config.baseUrl, withoutNoProxy) !== undefined) return { kind: 'exempt' };\n return { kind: 'direct' };\n}\n\nfunction proxyHostOf(config: OpenAICompatConfig): string {\n try {\n return new URL(config.proxyUrl ?? '').host;\n } catch {\n return '<unparseable proxy>';\n }\n}\n\n/** One completion per family, in family order; a family with no model is not called. */\nasync function probeFamilies(\n adapters: readonly IModelAdapter[],\n slots: GatewaySlotMapping,\n config: OpenAICompatConfig\n): Promise<readonly GatewayCompletionProbe[]> {\n const probes: GatewayCompletionProbe[] = [];\n for (const family of PROBE_FAMILIES) {\n const model = slots[PROBE_SLOT[family]];\n const adapter = adapters.find((a) => a.modelId === model);\n if (adapter === undefined) {\n probes.push({ family, outcome: 'no_model' });\n continue;\n }\n probes.push(await probeOne(family, adapter, config));\n }\n return probes;\n}\n\nasync function probeOne(\n family: GatewayFamily,\n adapter: IModelAdapter,\n config: OpenAICompatConfig\n): Promise<GatewayCompletionProbe> {\n const clock = getTimeProvider();\n const started = clock.now();\n const base = { family, model: adapter.modelId };\n try {\n const result = await adapter.complete({\n messages: [{ role: 'user', content: 'Reply with the single word OK.' }],\n maxTokens: PROBE_MAX_TOKENS,\n timeoutMs: PROBE_TIMEOUT_MS,\n });\n const latencyMs = clock.now() - started;\n if (result.ok) return { ...base, outcome: 'ok', latencyMs };\n return { ...base, outcome: 'failed', latencyMs, error: redact(result.error.message, config) };\n } catch (e: unknown) {\n const latencyMs = clock.now() - started;\n return { ...base, outcome: 'failed', latencyMs, error: redact(getErrorMessage(e), config) };\n }\n}\n\n/** `message` with the key and every extra header value replaced. */\nfunction redact(message: string, config: OpenAICompatConfig): string {\n return redactGatewaySecrets(message, { apiKey: config.apiKey, headers: config.extraHeaders });\n}\n\n/** A vendor slot the gateway can serve: one per family. */\ntype GatewaySlot = keyof GatewaySlotMapping;\n\n/**\n * The family slots a healthy gateway does NOT serve, in family order (#6658):\n * each slot that resolved to `unavailable`. This is also exactly the set of\n * `--probe` `no_model` results — `probeFamilies` reads the same mapping — so a\n * `no_model` family counts against the verdict the same way. Empty for any\n * other state: there is no slot mapping to read.\n */\nfunction unservedGatewaySlots(health: GatewayHealth): readonly GatewaySlot[] {\n if (health.state !== 'healthy') return [];\n const { slots } = health;\n return PROBE_FAMILIES.map((family) => PROBE_SLOT[family]).filter(\n (slot) => slots[slot] === 'unavailable'\n );\n}\n\n/**\n * The verdict term. A requested probe that failed fails the gateway: it was\n * asked whether the gateway serves, and it said no. A gateway that serves NO\n * family slot fails too (#6658): it answered `/models` but every pinned slot\n * would throw \"unavailable\" at use. One that serves SOME slots passes, and\n * {@link gatewaySlotWarnings} names each slot it does not serve.\n */\nexport function gatewayVerdict(health: GatewayHealth): GatewayVerdict {\n if (health.state === 'not_configured') return 'absent';\n if (health.state !== 'healthy') return 'fail';\n const failed = health.probes !== 'skipped' && health.probes.some((p) => p.outcome === 'failed');\n if (failed) return 'fail';\n return unservedGatewaySlots(health).length < PROBE_FAMILIES.length ? 'pass' : 'fail';\n}\n\n/**\n * One warning per family slot the passing gateway leaves with no arm (#6658):\n * its CLI is missing or disabled by `NEXUS_DISABLED_CLIS` (#6720), and the\n * gateway has no model of its family — the router's own decision, read via\n * {@link gatewaySlotServing}. Such a slot does not fail the verdict — other\n * slots work — but a task pinned to it throws \"unavailable\" at use, so it is\n * named rather than silently excused. opencode has no gateway slot, so a\n * missing opencode is always named. No warning when the gateway does not\n * pass: the missing CLIs then fail the verdict themselves\n * ({@link cliFailsVerdict}).\n */\nexport function gatewaySlotWarnings(\n health: GatewayHealth,\n clis: readonly CliCheckResult[]\n): string[] {\n if (gatewayVerdict(health) !== 'pass') return [];\n const missing = (name: CliCheckResult['name']): boolean =>\n clis.some((c) => c.name === name && !c.installed);\n const warnings = gatewaySlotServing(health, clis)\n .filter((s) => s.serving === 'unavailable')\n .map((s) => {\n const why = s.disabled ? 'disabled by NEXUS_DISABLED_CLIS' : 'not installed';\n return `${s.slot} slot unavailable: ${why}, and the gateway has no ${s.family} model`;\n });\n if (missing('opencode')) {\n warnings.push('opencode slot unavailable: not installed, and the gateway has no opencode slot');\n }\n return warnings;\n}\n\n/**\n * The `doctor --gateway` line for each family slot the gateway does not serve,\n * in family order — or one line saying no slot is served, the case\n * {@link gatewayVerdict} fails on.\n */\nexport function unservedSlotLines(health: GatewayHealth): string[] {\n const unserved = unservedGatewaySlots(health);\n if (health.state !== 'healthy' || unserved.length === 0) return [];\n if (unserved.length === PROBE_FAMILIES.length) {\n return [\n 'no slot has a gateway model: every pinned claude, codex or gemini slot is unavailable',\n ];\n }\n return PROBE_FAMILIES.filter((f) => unserved.includes(PROBE_SLOT[f])).map(\n (f) => `${PROBE_SLOT[f]} slot unavailable: the gateway has no ${f} model`\n );\n}\n\n/**\n * Whether one CLI counts against the verdict. With a passing gateway — one\n * that serves at least one family slot — a CLI that is not installed does\n * not. When its own slot has a gateway model it is excused outright; when it\n * has none (or it is opencode, which never has one) it is a named warning\n * from {@link gatewaySlotWarnings}, not a failure (#6658). A host with zero\n * served slots has a failing gateway, so every missing CLI counts. An\n * installed CLI still has to be authenticated and supported — unless the\n * gateway actually serves its slot (`gatewayCovered`, from\n * `gatewayCoveredClis` in `doctor-gateway-slots.ts`): service is unaffected, so it is a named ⚠, not\n * a failure (#6782). A broken CLI whose slot nothing serves still fails.\n */\nexport function cliFailsVerdict(\n cli: CliCheckResult,\n gateway: GatewayVerdict,\n gatewayCovered: boolean\n): boolean {\n if (!cli.installed) return gateway !== 'pass';\n return installedCliIsBroken(cli) && !gatewayCovered;\n}\n","/**\n * Doctor lines for the voter transport (#4255) and the gateway's cost\n * declaration (#4392 increment 2). A sibling of `doctor-formatting.ts` for\n * the file cap, in the same shape as `doctor-claude-model.ts`.\n *\n * @module cli/doctor-voter-transport\n */\n\nimport { describeGatewayCostDeclaration } from '../adapters/sdk/gateway-cost.js';\nimport {\n DEFAULT_OPENAI_COMPAT_ENDPOINT,\n GATEWAY_COST_ENV,\n OPENAI_COMPAT_ENDPOINT_ENV,\n OPENAI_COMPAT_KEY_ENV,\n OPENAI_COMPAT_URL_ENV,\n} from '../adapters/sdk/types.js';\nimport type { VoterTransportCheck } from './doctor.js';\nimport type { GatewayHealth } from './doctor-gateway.js';\nimport { colors, symbols, writeLine } from './ansi-output.js';\n\nconst CHECK = `${colors.green}${symbols.check}${colors.reset}`;\nconst WARN = `${colors.yellow}${symbols.warn}${colors.reset}`;\nconst CROSS = `${colors.red}${symbols.cross}${colors.reset}`;\n\n/**\n * Prints which transport voter/consensus calls will use (#4255): an\n * in-process OpenAI-compatible gateway when configured, else the CLI\n * subprocess round-robin fallback. A configured gateway is followed by its\n * cost line. The gateway line reports the MEASURED gateway (#6609), not the\n * presence of its env vars: a gateway whose discovery fails is not used, and\n * the server falls back to CLI subprocesses.\n */\nexport function printVoterTransportCheck(check: VoterTransportCheck, gateway: GatewayHealth): void {\n if (check.configured) {\n writeLine(gatewayTransportLine(gateway));\n printGatewayCostLine(check.cost);\n return;\n }\n writeLine(`${CHECK} Voter transport: ${colors.dim}CLI subprocess${colors.reset}`);\n writeLine(\n ` ${colors.dim}Set ${OPENAI_COMPAT_URL_ENV} and ${OPENAI_COMPAT_KEY_ENV} for faster in-process voting${colors.reset}`\n );\n}\n\nconst CEILING_CONSEQUENCE =\n 'the task-class cost ceiling and the per-task budget exclude this gateway until declared';\n\n/** One warning per gap, each naming its own fix (see `VoterTransportCheck.cost`). */\nconst GAP_LINES: Record<'unset' | 'invalid' | 'no-default', string> = {\n unset: `Gateway cost: UNSET — set ${GATEWAY_COST_ENV}=free|local|priced[:<in>,<out>]; ${CEILING_CONSEQUENCE}`,\n invalid: `Gateway cost: INVALID — ${GATEWAY_COST_ENV} does not parse (the startup env warning names the reason); ${CEILING_CONSEQUENCE}`,\n 'no-default': `Gateway cost: NOT DECLARED for the voter gateway — ${GATEWAY_COST_ENV} names neither a bare declaration nor this gateway's endpoint (${OPENAI_COMPAT_ENDPOINT_ENV}, default ${DEFAULT_OPENAI_COMPAT_ENDPOINT}); add a bare or <endpoint>= entry; ${CEILING_CONSEQUENCE}`,\n};\n\n/**\n * The gateway's cost declaration. Each gap is a warning that names its fix\n * and the consequence; none touches `allHealthy`. No line at all when no\n * gateway is configured (`cost` absent).\n */\nfunction printGatewayCostLine(cost: VoterTransportCheck['cost']): void {\n if (cost === undefined) return;\n if (typeof cost === 'string') {\n writeLine(`${WARN} ${GAP_LINES[cost]}`);\n return;\n }\n writeLine(`${CHECK} Gateway cost: ${describeGatewayCostDeclaration(cost)}`);\n}\n\n/** The voter-transport line for a configured gateway, from its measurement. */\nfunction gatewayTransportLine(gateway: GatewayHealth): string {\n switch (gateway.state) {\n case 'healthy':\n return (\n `${CHECK} Voter transport: In-process gateway (${gateway.host}: ` +\n `${String(gateway.chatCount)} chat models answered /models)`\n );\n case 'not_configured':\n // The env names a gateway but its config did not read: nothing was measured.\n return `${WARN} Voter transport: In-process gateway (not measured)`;\n default:\n return (\n `${CROSS} Voter transport: In-process gateway at ${gateway.host} FAILED ` +\n `(${gatewayFailureReason(gateway)}); voters fall back to CLI subprocesses`\n );\n }\n}\n\n/** Why a configured gateway is not in use, naming no secret. */\nexport function gatewayFailureReason(\n gateway: Exclude<GatewayHealth, { state: 'healthy' | 'not_configured' }>\n): string {\n switch (gateway.state) {\n case 'refused_private_host':\n return `private-address guard refused it: ${gateway.reason}`;\n case 'discovery_failed':\n return gateway.error;\n case 'no_chat_models':\n return `/models listed ${String(gateway.listedCount)} models, none of them chat models`;\n }\n}\n","/**\n * The `doctor --gateway` section (#6609): what the gateway measurement in\n * `doctor-gateway.ts` found, line by line. Rendering only; the verdict lives\n * in `gatewayVerdict`. Prints no key, header value or proxy credential — the\n * measurement never holds them.\n *\n * @module cli/doctor-gateway-report\n */\n\nimport {\n OPENAI_COMPAT_KEY_ENV,\n OPENAI_COMPAT_MODELS_ENV,\n OPENAI_COMPAT_URL_ENV,\n} from '../adapters/sdk/types.js';\nimport type { CliCheckResult } from './doctor.js';\nimport {\n gatewaySlotWarnings,\n gatewayVerdict,\n unservedSlotLines,\n type GatewayCompletionProbe,\n type GatewayHealth,\n type GatewayProxyStatus,\n} from './doctor-gateway.js';\nimport { gatewayFailureReason } from './doctor-voter-transport.js';\nimport { formatSlotServing, gatewaySlotServing } from './doctor-gateway-slots.js';\nimport { colors, symbols } from './ansi-output.js';\nimport { CUSTOM_API_DEFAULT_MODEL } from '../config/defaults.js';\n\nconst CHECK = `${colors.green}${symbols.check}${colors.reset}`;\nconst CROSS = `${colors.red}${symbols.cross}${colors.reset}`;\nconst WARN = `${colors.yellow}${symbols.warn}${colors.reset}`;\n\n/** Says what the probe costs whether or not it ran, so the flag is never a surprise. */\nconst PROBE_COST_NOTE = 'one tiny completion per family; this spends gateway tokens';\n\n/**\n * The `doctor --gateway` section as lines. `clis` are doctor's CLI checks;\n * each slot line says what serves the slot, decided as the router decides it\n * ({@link gatewaySlotServing}, #6720). Omitted, no CLI counts as installed.\n */\nexport function formatGatewayReport(\n health: GatewayHealth,\n clis: readonly CliCheckResult[] = []\n): string[] {\n const lines = [`${colors.cyan}Checking gateway (doctor --gateway)...${colors.reset}`, ''];\n if (health.state === 'not_configured') {\n lines.push(\n `${WARN} Gateway: not configured — set ${OPENAI_COMPAT_URL_ENV} and ${OPENAI_COMPAT_KEY_ENV}`\n );\n return lines;\n }\n if (health.state !== 'healthy') {\n lines.push(`${CROSS} Gateway ${health.host}: FAILED — ${gatewayFailureReason(health)}`);\n if (health.state === 'refused_private_host') lines.push(` ${health.remedy}`);\n lines.push(` Proxy: ${formatProxy(health.proxy)}`, unverifiedFallbackLine());\n return lines;\n }\n const filter = health.allowlistActive\n ? `after the chat filter and ${OPENAI_COMPAT_MODELS_ENV}`\n : 'after the chat filter';\n const { census } = health;\n lines.push(\n `${CHECK} Gateway ${health.host}: /models answered`,\n ` Private-address guard: allowed`,\n ` Proxy: ${formatProxy(health.proxy)}`,\n ` Models: ${String(health.listedCount)} listed, ${String(health.chatCount)} chat models ${filter}`,\n ` Families: anthropic ${String(census.anthropic)}, openai ${String(census.openai)}, ` +\n `google ${String(census.google)}, unknown ${String(census.unknown)}`,\n ` Slots (an available CLI serves its own slot first):`,\n ...gatewaySlotServing(health, clis).map((s) => ` ${formatSlotServing(s)}`),\n ...formatProbes(health.probes),\n ...formatUnservedSlots(health)\n );\n return lines;\n}\n\n/**\n * The missing CLIs a passing gateway cannot stand in for, one warning line\n * each (#6658). Printed with every `doctor` run, `--gateway` or not: they are\n * not failures — other slots work — but they are never silently excused.\n */\nexport function formatGatewaySlotWarnings(\n health: GatewayHealth,\n clis: readonly CliCheckResult[]\n): string[] {\n return gatewaySlotWarnings(health, clis).map((warning) => `${WARN} ${warning}`);\n}\n\n/**\n * Each family slot the gateway does not serve (#6658): a warning while some\n * slot works, a failure when none does — the same line `gatewayVerdict` fails on.\n */\nfunction formatUnservedSlots(health: GatewayHealth): string[] {\n const glyph = gatewayVerdict(health) === 'fail' ? CROSS : WARN;\n return unservedSlotLines(health).map((line) => ` ${glyph} ${line}`);\n}\n\nfunction formatProxy(proxy: GatewayProxyStatus): string {\n switch (proxy.kind) {\n case 'direct':\n return 'direct (no proxy variable applies)';\n case 'proxy':\n return `via ${proxy.proxyHost}`;\n case 'exempt':\n return 'direct (NO_PROXY exempts the gateway host)';\n case 'ignored':\n return 'direct (the proxy variable is not a usable http(s) URL; see the startup warning)';\n }\n}\n\nfunction formatProbes(probes: readonly GatewayCompletionProbe[] | 'skipped'): string[] {\n if (probes === 'skipped') {\n return [` Completion probe: skipped — pass --probe to send ${PROBE_COST_NOTE}`];\n }\n return [` Completion probe (${PROBE_COST_NOTE}):`, ...probes.map(formatProbe)];\n}\n\nfunction formatProbe(probe: GatewayCompletionProbe): string {\n if (probe.outcome === 'no_model') {\n return ` ${WARN} ${probe.family}: no gateway model of this family, not probed`;\n }\n const ms = `${String(probe.latencyMs)} ms`;\n if (probe.outcome === 'ok')\n return ` ${CHECK} ${probe.family}: ${probe.model} answered (${ms})`;\n return ` ${CROSS} ${probe.family}: ${probe.model} FAILED (${ms}) — ${probe.error ?? 'no error message'}`;\n}\n\n/**\n * #4392: with no catalogue, the single-model custom-openai adapter still sends\n * `NEXUS_CUSTOM_MODEL` (or the built-in default) — and nothing says the\n * gateway serves it. Named here so the operator sees it before a call fails.\n */\nfunction unverifiedFallbackLine(): string {\n const model = process.env['NEXUS_CUSTOM_MODEL'] ?? CUSTOM_API_DEFAULT_MODEL;\n return (\n ` ${WARN} No catalogue: the custom-openai fallback sends '${model}' unverified ` +\n 'and gateway family slots are unavailable'\n );\n}\n"],"mappings":"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","names":["CHECK","CROSS","WARN"]}
|