nexus-agents 2.72.1 → 2.74.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/{adaptive-memory-UPE76IP6.js → adaptive-memory-OJY3IVNM.js} +3 -3
- package/dist/{child-mcp-config-5HRJGLCR.js → child-mcp-config-KMCKKPNY.js} +2 -2
- package/dist/{chunk-TF3GROMO.js → chunk-2SVS5WRV.js} +2 -2
- package/dist/{chunk-QECRZ3YA.js → chunk-3ESCBV47.js} +2 -2
- package/dist/{chunk-QL4HCYRD.js → chunk-3SZBDLFX.js} +3 -3
- package/dist/{chunk-VTVKC4FS.js → chunk-44MVIL3F.js} +4 -4
- package/dist/{chunk-BVETPIOQ.js → chunk-4K6L7RKC.js} +3 -3
- package/dist/chunk-4K6L7RKC.js.map +1 -0
- package/dist/{chunk-C3JGKBL2.js → chunk-65R32U3M.js} +4 -4
- package/dist/{chunk-3FIDMWFC.js → chunk-BK54O5J5.js} +2 -2
- package/dist/chunk-BK54O5J5.js.map +1 -0
- package/dist/{chunk-J4VR2WNI.js → chunk-BYKS53GW.js} +1086 -1709
- package/dist/chunk-BYKS53GW.js.map +1 -0
- package/dist/{chunk-L6N2S3UB.js → chunk-CCODJRS6.js} +2 -2
- package/dist/{chunk-DA5UDQYW.js → chunk-DGELGUZF.js} +2 -2
- package/dist/{chunk-2KB63QGE.js → chunk-EQHYXT56.js} +2 -2
- package/dist/{chunk-VPC3YNFR.js → chunk-G5VE2DZS.js} +2 -2
- package/dist/{chunk-2MD5MWCK.js → chunk-GS3GW7C7.js} +2 -2
- package/dist/{chunk-ES6GFP35.js → chunk-NC2LECY6.js} +26 -9
- package/dist/chunk-NC2LECY6.js.map +1 -0
- package/dist/{chunk-5MHIWRKB.js → chunk-NQR7QAZX.js} +21 -2
- package/dist/chunk-NQR7QAZX.js.map +1 -0
- package/dist/{chunk-5WQ3SRSE.js → chunk-PAFH336F.js} +2 -2
- package/dist/{chunk-O4KUCF5S.js → chunk-Q3RFPJYK.js} +1325 -441
- package/dist/chunk-Q3RFPJYK.js.map +1 -0
- package/dist/{chunk-P5OFZWDW.js → chunk-Q6JDV36D.js} +13 -6
- package/dist/chunk-Q6JDV36D.js.map +1 -0
- package/dist/{chunk-A35XORXU.js → chunk-Q7FTNKPO.js} +2 -2
- package/dist/chunk-QON7LR7J.js +153 -0
- package/dist/chunk-QON7LR7J.js.map +1 -0
- package/dist/{chunk-53K3KEKT.js → chunk-T5VPZZYX.js} +1564 -848
- package/dist/chunk-T5VPZZYX.js.map +1 -0
- package/dist/{chunk-TQFRPFMG.js → chunk-TBRNRW2Q.js} +2 -2
- package/dist/{chunk-345KMHWH.js → chunk-UWJKMBPL.js} +6 -6
- package/dist/{chunk-V7ATY4BG.js → chunk-VJD5LANR.js} +14 -16
- package/dist/chunk-VJD5LANR.js.map +1 -0
- package/dist/{chunk-YOREAPF6.js → chunk-WCCTIRSB.js} +11 -10
- package/dist/chunk-WCCTIRSB.js.map +1 -0
- package/dist/{cli-circuit-breaker-GFF2RLBZ.js → cli-circuit-breaker-STXIH563.js} +4 -4
- package/dist/cli.d.ts +5 -2
- package/dist/cli.js +138 -106
- package/dist/cli.js.map +1 -1
- package/dist/{composite-router-33F3F74I.js → composite-router-7AHZN3VI.js} +2 -2
- package/dist/{consensus-vote-5V4KVHBE.js → consensus-vote-XY55C7WQ.js} +11 -10
- package/dist/consensus-vote-types-CoGbAEjf.d.ts +195 -0
- package/dist/{doctor-deep-AHDTNURD.js → doctor-deep-ONHJTGR4.js} +3 -3
- package/dist/{expert-bridge-DMDHHDEU.js → expert-bridge-3AWQHR65.js} +3 -3
- package/dist/{factory-FVD7PZ6S.js → factory-E5NMAMZC.js} +5 -5
- package/dist/{factory-VQS3HJ7V.js → factory-HWHQ44BB.js} +4 -4
- package/dist/index.d.ts +4089 -3693
- package/dist/index.js +85 -73
- package/dist/index.js.map +1 -1
- package/dist/{init-opencode-EIOIPVWL.js → init-opencode-Z7OQ5RCB.js} +5 -5
- package/dist/{issue-triage-HJUJWGAD.js → issue-triage-UWBHMQHC.js} +4 -4
- package/dist/{mobimem-BOJFXQ7B.js → mobimem-G4UXJTCV.js} +2 -2
- package/dist/{registry-command-NCWUJKAF.js → registry-command-HYWVRAHE.js} +5 -6
- package/dist/registry-command-HYWVRAHE.js.map +1 -0
- package/dist/{repo-security-plan-3J45VAD6.js → repo-security-plan-W35CXK3T.js} +3 -3
- package/dist/{research-helpers-synthesize-UGQHZZJN.js → research-helpers-synthesize-GUQORWL4.js} +3 -3
- package/dist/{routing-memory-NO7QEH7T.js → routing-memory-VOJBOX3X.js} +2 -2
- package/dist/{session-memory-DOXLEWEU.js → session-memory-B6LQMF4N.js} +3 -3
- package/dist/{setup-command-BWUFMZ7U.js → setup-command-CTC5YNA4.js} +9 -8
- package/dist/{setup-config-E3JZYSLR.js → setup-config-53MHJA7S.js} +3 -3
- package/dist/{setup-custom-api-DHJ5DRH2.js → setup-custom-api-VD5W754A.js} +4 -4
- package/dist/{weather-report-FNN4OX3N.js → weather-report-APASTJDQ.js} +2 -2
- package/package.json +1 -1
- package/dist/chunk-3FIDMWFC.js.map +0 -1
- package/dist/chunk-53K3KEKT.js.map +0 -1
- package/dist/chunk-5MHIWRKB.js.map +0 -1
- package/dist/chunk-BVETPIOQ.js.map +0 -1
- package/dist/chunk-ES6GFP35.js.map +0 -1
- package/dist/chunk-J4VR2WNI.js.map +0 -1
- package/dist/chunk-O4KUCF5S.js.map +0 -1
- package/dist/chunk-P5OFZWDW.js.map +0 -1
- package/dist/chunk-V7ATY4BG.js.map +0 -1
- package/dist/chunk-YOREAPF6.js.map +0 -1
- package/dist/model-capabilities-types-B57GZryc.d.ts +0 -18
- package/dist/registry-command-NCWUJKAF.js.map +0 -1
- /package/dist/{adaptive-memory-UPE76IP6.js.map → adaptive-memory-OJY3IVNM.js.map} +0 -0
- /package/dist/{child-mcp-config-5HRJGLCR.js.map → child-mcp-config-KMCKKPNY.js.map} +0 -0
- /package/dist/{chunk-TF3GROMO.js.map → chunk-2SVS5WRV.js.map} +0 -0
- /package/dist/{chunk-QECRZ3YA.js.map → chunk-3ESCBV47.js.map} +0 -0
- /package/dist/{chunk-QL4HCYRD.js.map → chunk-3SZBDLFX.js.map} +0 -0
- /package/dist/{chunk-VTVKC4FS.js.map → chunk-44MVIL3F.js.map} +0 -0
- /package/dist/{chunk-C3JGKBL2.js.map → chunk-65R32U3M.js.map} +0 -0
- /package/dist/{chunk-L6N2S3UB.js.map → chunk-CCODJRS6.js.map} +0 -0
- /package/dist/{chunk-DA5UDQYW.js.map → chunk-DGELGUZF.js.map} +0 -0
- /package/dist/{chunk-2KB63QGE.js.map → chunk-EQHYXT56.js.map} +0 -0
- /package/dist/{chunk-VPC3YNFR.js.map → chunk-G5VE2DZS.js.map} +0 -0
- /package/dist/{chunk-2MD5MWCK.js.map → chunk-GS3GW7C7.js.map} +0 -0
- /package/dist/{chunk-5WQ3SRSE.js.map → chunk-PAFH336F.js.map} +0 -0
- /package/dist/{chunk-A35XORXU.js.map → chunk-Q7FTNKPO.js.map} +0 -0
- /package/dist/{chunk-TQFRPFMG.js.map → chunk-TBRNRW2Q.js.map} +0 -0
- /package/dist/{chunk-345KMHWH.js.map → chunk-UWJKMBPL.js.map} +0 -0
- /package/dist/{cli-circuit-breaker-GFF2RLBZ.js.map → cli-circuit-breaker-STXIH563.js.map} +0 -0
- /package/dist/{composite-router-33F3F74I.js.map → composite-router-7AHZN3VI.js.map} +0 -0
- /package/dist/{consensus-vote-5V4KVHBE.js.map → consensus-vote-XY55C7WQ.js.map} +0 -0
- /package/dist/{doctor-deep-AHDTNURD.js.map → doctor-deep-ONHJTGR4.js.map} +0 -0
- /package/dist/{expert-bridge-DMDHHDEU.js.map → expert-bridge-3AWQHR65.js.map} +0 -0
- /package/dist/{factory-FVD7PZ6S.js.map → factory-E5NMAMZC.js.map} +0 -0
- /package/dist/{factory-VQS3HJ7V.js.map → factory-HWHQ44BB.js.map} +0 -0
- /package/dist/{init-opencode-EIOIPVWL.js.map → init-opencode-Z7OQ5RCB.js.map} +0 -0
- /package/dist/{issue-triage-HJUJWGAD.js.map → issue-triage-UWBHMQHC.js.map} +0 -0
- /package/dist/{mobimem-BOJFXQ7B.js.map → mobimem-G4UXJTCV.js.map} +0 -0
- /package/dist/{repo-security-plan-3J45VAD6.js.map → repo-security-plan-W35CXK3T.js.map} +0 -0
- /package/dist/{research-helpers-synthesize-UGQHZZJN.js.map → research-helpers-synthesize-GUQORWL4.js.map} +0 -0
- /package/dist/{routing-memory-NO7QEH7T.js.map → routing-memory-VOJBOX3X.js.map} +0 -0
- /package/dist/{session-memory-DOXLEWEU.js.map → session-memory-B6LQMF4N.js.map} +0 -0
- /package/dist/{setup-command-BWUFMZ7U.js.map → setup-command-CTC5YNA4.js.map} +0 -0
- /package/dist/{setup-config-E3JZYSLR.js.map → setup-config-53MHJA7S.js.map} +0 -0
- /package/dist/{setup-custom-api-DHJ5DRH2.js.map → setup-custom-api-VD5W754A.js.map} +0 -0
- /package/dist/{weather-report-FNN4OX3N.js.map → weather-report-APASTJDQ.js.map} +0 -0
|
@@ -1,6 +1,9 @@
|
|
|
1
1
|
import {
|
|
2
2
|
isPersistenceEnabled
|
|
3
3
|
} from "./chunk-I7ORMAO7.js";
|
|
4
|
+
import {
|
|
5
|
+
nexusDataPath
|
|
6
|
+
} from "./chunk-GOT7OAL5.js";
|
|
4
7
|
import {
|
|
5
8
|
__require
|
|
6
9
|
} from "./chunk-UP2VWCW5.js";
|
|
@@ -631,6 +634,15 @@ var ErrorCode = {
|
|
|
631
634
|
// Model errors
|
|
632
635
|
MODEL_ERROR: "MODEL_ERROR",
|
|
633
636
|
MODEL_UNAVAILABLE: "MODEL_UNAVAILABLE",
|
|
637
|
+
/**
|
|
638
|
+
* Model is reachable but the requested id no longer exists — typically a
|
|
639
|
+
* 404 from /v1/chat/completions, an Anthropic `model_not_found` error,
|
|
640
|
+
* or a vendor "this model has been deprecated" message. Distinct from
|
|
641
|
+
* MODEL_UNAVAILABLE (transient 502/503 service overload) — this one
|
|
642
|
+
* means the model is gone, retry won't help, route to a different id.
|
|
643
|
+
* See `withModelNotFoundFallback` for the retire-and-retry primitive.
|
|
644
|
+
*/
|
|
645
|
+
MODEL_NOT_FOUND: "MODEL_NOT_FOUND",
|
|
634
646
|
MODEL_RATE_LIMITED: "MODEL_RATE_LIMITED",
|
|
635
647
|
MODEL_TIMEOUT: "MODEL_TIMEOUT",
|
|
636
648
|
// Agent errors
|
|
@@ -776,134 +788,7 @@ function extractObjectMessage(error, fallback) {
|
|
|
776
788
|
}
|
|
777
789
|
}
|
|
778
790
|
|
|
779
|
-
// src/config/
|
|
780
|
-
import { z as z2 } from "zod";
|
|
781
|
-
var OUTPUT_MODALITIES = [
|
|
782
|
-
"text",
|
|
783
|
-
"image_png",
|
|
784
|
-
"image_jpeg",
|
|
785
|
-
"audio_pcm",
|
|
786
|
-
"audio_wav",
|
|
787
|
-
"audio_mp3",
|
|
788
|
-
"video_mp4",
|
|
789
|
-
"svg",
|
|
790
|
-
"structured_json",
|
|
791
|
-
"code"
|
|
792
|
-
];
|
|
793
|
-
var INPUT_MODALITIES = ["text", "image", "audio", "video", "pdf", "code"];
|
|
794
|
-
var TOOL_CAPABILITIES = [
|
|
795
|
-
"mcp",
|
|
796
|
-
"function_calling",
|
|
797
|
-
"computer_use",
|
|
798
|
-
"code_execution_sandbox",
|
|
799
|
-
"web_search",
|
|
800
|
-
"file_operations",
|
|
801
|
-
"structured_output",
|
|
802
|
-
"apply_patch"
|
|
803
|
-
];
|
|
804
|
-
var SPECIAL_FEATURES = [
|
|
805
|
-
"extended_thinking",
|
|
806
|
-
"deep_research",
|
|
807
|
-
"streaming",
|
|
808
|
-
"grounding",
|
|
809
|
-
"citations",
|
|
810
|
-
"image_editing",
|
|
811
|
-
"voice_cloning",
|
|
812
|
-
"live_api",
|
|
813
|
-
"context_caching"
|
|
814
|
-
];
|
|
815
|
-
var PROVIDERS = ["anthropic", "google", "openai", "custom-openai", "openrouter"];
|
|
816
|
-
var CLI_NAMES = ["claude", "gemini", "codex", "opencode"];
|
|
817
|
-
var CliNameSchema = z2.enum(CLI_NAMES);
|
|
818
|
-
var DEFAULT_CLI = "claude";
|
|
819
|
-
var MODEL_IDS = [
|
|
820
|
-
"claude-opus",
|
|
821
|
-
"claude-sonnet",
|
|
822
|
-
"claude-haiku",
|
|
823
|
-
"gemini-3-pro",
|
|
824
|
-
"gemini-pro",
|
|
825
|
-
"gemini-3-flash",
|
|
826
|
-
"gemini-flash",
|
|
827
|
-
"codex-5.3",
|
|
828
|
-
"codex-5.2",
|
|
829
|
-
"codex-5.1-mini",
|
|
830
|
-
"opencode-default",
|
|
831
|
-
"opencode-custom-opus",
|
|
832
|
-
"opencode-custom-sonnet",
|
|
833
|
-
"openrouter-nemotron-super",
|
|
834
|
-
"openrouter-qwen-coder"
|
|
835
|
-
];
|
|
836
|
-
var QualityScoresSchema = z2.object({
|
|
837
|
-
reasoning: z2.number().min(0).max(10),
|
|
838
|
-
codeGeneration: z2.number().min(0).max(10),
|
|
839
|
-
speed: z2.number().min(0).max(10),
|
|
840
|
-
cost: z2.number().min(0).max(10)
|
|
841
|
-
});
|
|
842
|
-
var PricingSchema = z2.object({
|
|
843
|
-
inputPer1M: z2.number().nonnegative(),
|
|
844
|
-
outputPer1M: z2.number().nonnegative()
|
|
845
|
-
});
|
|
846
|
-
var ModelCapabilitySchema = z2.object({
|
|
847
|
-
/** Unique model identifier matching delegate_to_model model IDs */
|
|
848
|
-
id: z2.enum(MODEL_IDS),
|
|
849
|
-
/** Human-readable display name */
|
|
850
|
-
displayName: z2.string().min(1),
|
|
851
|
-
/** Provider/vendor */
|
|
852
|
-
provider: z2.enum(PROVIDERS),
|
|
853
|
-
/** Maximum context window in tokens */
|
|
854
|
-
contextWindow: z2.number().int().positive(),
|
|
855
|
-
/** Output modalities this model can produce */
|
|
856
|
-
outputModalities: z2.array(z2.enum(OUTPUT_MODALITIES)).min(1),
|
|
857
|
-
/** Input modalities this model can accept */
|
|
858
|
-
inputModalities: z2.array(z2.enum(INPUT_MODALITIES)).min(1),
|
|
859
|
-
/** Tool/integration capabilities */
|
|
860
|
-
toolCapabilities: z2.array(z2.enum(TOOL_CAPABILITIES)),
|
|
861
|
-
/** Special features beyond standard generation */
|
|
862
|
-
specialFeatures: z2.array(z2.enum(SPECIAL_FEATURES)),
|
|
863
|
-
/** Known constraints or limitations */
|
|
864
|
-
constraints: z2.array(z2.string()).optional(),
|
|
865
|
-
/** Notes about the model (e.g., beta features, pricing tier) */
|
|
866
|
-
notes: z2.string().optional(),
|
|
867
|
-
/** Pricing per 1M tokens (USD) */
|
|
868
|
-
pricing: PricingSchema.optional(),
|
|
869
|
-
/** Quality scores for routing (0-10 scale) */
|
|
870
|
-
qualityScores: QualityScoresSchema.optional(),
|
|
871
|
-
/** Maximum output tokens */
|
|
872
|
-
maxOutputTokens: z2.number().int().positive().optional(),
|
|
873
|
-
/** Which CLI tool this model belongs to */
|
|
874
|
-
cliName: z2.enum(CLI_NAMES).optional(),
|
|
875
|
-
/** Short alias used by the CLI (e.g., 'opus' for Claude CLI) */
|
|
876
|
-
cliAlias: z2.string().optional(),
|
|
877
|
-
/** Model name the CLI binary expects (e.g., 'gemini-2.5-pro') */
|
|
878
|
-
cliModelName: z2.string().optional(),
|
|
879
|
-
/**
|
|
880
|
-
* Legacy / version-suffixed names that resolve to this model. Used by
|
|
881
|
-
* adapters and routing to map historical user-facing names (e.g.,
|
|
882
|
-
* `claude-opus-4-5-20251101`, `gemini-2.5-pro`) to the current registry
|
|
883
|
-
* entry. Empty strings are rejected; uniqueness within the array is not
|
|
884
|
-
* enforced at schema level (caller responsibility).
|
|
885
|
-
*
|
|
886
|
-
* Added for issue #2199 Child 1; populated by the companion migration
|
|
887
|
-
* epic #2200.
|
|
888
|
-
*/
|
|
889
|
-
aliases: z2.array(z2.string().min(1)).optional(),
|
|
890
|
-
/** Whether this model is deprecated and should receive a scoring penalty */
|
|
891
|
-
deprecated: z2.boolean().optional(),
|
|
892
|
-
/** ISO date when the model was deprecated (informational) */
|
|
893
|
-
deprecatedAt: z2.string().optional(),
|
|
894
|
-
/** Model ID to migrate to (informational guidance) */
|
|
895
|
-
replacedBy: z2.enum(MODEL_IDS).optional()
|
|
896
|
-
});
|
|
897
|
-
var ModelCapabilitiesMatrixSchema = z2.object({
|
|
898
|
-
/** Schema version for forward compatibility */
|
|
899
|
-
version: z2.number().int().positive(),
|
|
900
|
-
/** Last updated date (ISO 8601) */
|
|
901
|
-
updatedAt: z2.string(),
|
|
902
|
-
/** Model capability definitions */
|
|
903
|
-
models: z2.array(ModelCapabilitySchema).min(1)
|
|
904
|
-
});
|
|
905
|
-
|
|
906
|
-
// src/config/model-capabilities.ts
|
|
791
|
+
// src/config/in-tree-data.ts
|
|
907
792
|
var DEFAULT_MODEL_CAPABILITIES = {
|
|
908
793
|
version: 3,
|
|
909
794
|
updatedAt: "2026-03-14",
|
|
@@ -1225,38 +1110,994 @@ var DEFAULT_MODEL_CAPABILITIES = {
|
|
|
1225
1110
|
cliName: "opencode",
|
|
1226
1111
|
cliModelName: "qwen/qwen3-coder-480b-a35b:free"
|
|
1227
1112
|
}
|
|
1228
|
-
]
|
|
1229
|
-
};
|
|
1230
|
-
var DEFAULT_MODEL_PER_CLI = {
|
|
1231
|
-
claude: "claude-opus",
|
|
1232
|
-
gemini: "gemini-3-pro",
|
|
1233
|
-
codex: "codex-5.3",
|
|
1234
|
-
opencode: "opencode-default"
|
|
1113
|
+
]
|
|
1114
|
+
};
|
|
1115
|
+
var DEFAULT_MODEL_PER_CLI = {
|
|
1116
|
+
claude: "claude-opus",
|
|
1117
|
+
gemini: "gemini-3-pro",
|
|
1118
|
+
codex: "codex-5.3",
|
|
1119
|
+
opencode: "opencode-default"
|
|
1120
|
+
};
|
|
1121
|
+
|
|
1122
|
+
// src/config/model-derivation.ts
|
|
1123
|
+
var DEFAULT_ENTRY = {
|
|
1124
|
+
parallelToolCalls: false,
|
|
1125
|
+
promptCaching: "none",
|
|
1126
|
+
toolDefinitionFormat: "openai",
|
|
1127
|
+
maxRecommendedTurnBudget: 10,
|
|
1128
|
+
strictJson: true,
|
|
1129
|
+
quirks: []
|
|
1130
|
+
};
|
|
1131
|
+
var VENDOR_DEFAULTS = {
|
|
1132
|
+
anthropic: {
|
|
1133
|
+
profileId: "anthropic-default",
|
|
1134
|
+
parallelToolCalls: true,
|
|
1135
|
+
promptCaching: "ephemeral",
|
|
1136
|
+
toolDefinitionFormat: "anthropic",
|
|
1137
|
+
maxRecommendedTurnBudget: 15
|
|
1138
|
+
},
|
|
1139
|
+
openai: {
|
|
1140
|
+
profileId: "openai-default",
|
|
1141
|
+
parallelToolCalls: true,
|
|
1142
|
+
toolDefinitionFormat: "openai",
|
|
1143
|
+
maxRecommendedTurnBudget: 15
|
|
1144
|
+
},
|
|
1145
|
+
google: {
|
|
1146
|
+
profileId: "google-default",
|
|
1147
|
+
parallelToolCalls: true,
|
|
1148
|
+
toolDefinitionFormat: "gemini",
|
|
1149
|
+
maxRecommendedTurnBudget: 15
|
|
1150
|
+
},
|
|
1151
|
+
meta: {
|
|
1152
|
+
profileId: "meta-default",
|
|
1153
|
+
parallelToolCalls: false,
|
|
1154
|
+
toolDefinitionFormat: "openai",
|
|
1155
|
+
maxRecommendedTurnBudget: 8
|
|
1156
|
+
},
|
|
1157
|
+
qwen: {
|
|
1158
|
+
profileId: "qwen-default",
|
|
1159
|
+
parallelToolCalls: false,
|
|
1160
|
+
toolDefinitionFormat: "openai",
|
|
1161
|
+
maxRecommendedTurnBudget: 8
|
|
1162
|
+
},
|
|
1163
|
+
nvidia: {
|
|
1164
|
+
profileId: "nvidia-nemotron-default",
|
|
1165
|
+
parallelToolCalls: false,
|
|
1166
|
+
toolDefinitionFormat: "openai",
|
|
1167
|
+
maxRecommendedTurnBudget: 8
|
|
1168
|
+
},
|
|
1169
|
+
mistral: {
|
|
1170
|
+
profileId: "mistral-default",
|
|
1171
|
+
parallelToolCalls: false,
|
|
1172
|
+
toolDefinitionFormat: "openai",
|
|
1173
|
+
maxRecommendedTurnBudget: 8
|
|
1174
|
+
},
|
|
1175
|
+
cohere: {
|
|
1176
|
+
profileId: "cohere-default",
|
|
1177
|
+
parallelToolCalls: false,
|
|
1178
|
+
toolDefinitionFormat: "openai",
|
|
1179
|
+
maxRecommendedTurnBudget: 8
|
|
1180
|
+
},
|
|
1181
|
+
deepseek: {
|
|
1182
|
+
profileId: "deepseek-default",
|
|
1183
|
+
parallelToolCalls: false,
|
|
1184
|
+
toolDefinitionFormat: "openai",
|
|
1185
|
+
maxRecommendedTurnBudget: 10
|
|
1186
|
+
}
|
|
1187
|
+
};
|
|
1188
|
+
var FAMILY_DEFAULTS = [
|
|
1189
|
+
{
|
|
1190
|
+
vendor: "anthropic",
|
|
1191
|
+
family: "claude-opus",
|
|
1192
|
+
override: { profileId: "claude-opus", maxRecommendedTurnBudget: 20 }
|
|
1193
|
+
},
|
|
1194
|
+
{
|
|
1195
|
+
vendor: "anthropic",
|
|
1196
|
+
family: "claude-haiku",
|
|
1197
|
+
override: { profileId: "claude-haiku", maxRecommendedTurnBudget: 8 }
|
|
1198
|
+
},
|
|
1199
|
+
{
|
|
1200
|
+
vendor: "openai",
|
|
1201
|
+
family: "o-reasoning",
|
|
1202
|
+
override: { profileId: "openai-o-reasoning", maxRecommendedTurnBudget: 25 }
|
|
1203
|
+
},
|
|
1204
|
+
{
|
|
1205
|
+
vendor: "google",
|
|
1206
|
+
family: "gemini-flash",
|
|
1207
|
+
override: { profileId: "gemini-flash", maxRecommendedTurnBudget: 8 }
|
|
1208
|
+
}
|
|
1209
|
+
];
|
|
1210
|
+
function deriveEntry(modelId, identity) {
|
|
1211
|
+
const vendorOverride = VENDOR_DEFAULTS[identity.vendor] ?? {};
|
|
1212
|
+
const familyOverride = FAMILY_DEFAULTS.find((f) => f.vendor === identity.vendor && f.family === identity.family)?.override ?? {};
|
|
1213
|
+
const merged = {
|
|
1214
|
+
...DEFAULT_ENTRY,
|
|
1215
|
+
profileId: "default",
|
|
1216
|
+
...vendorOverride,
|
|
1217
|
+
...familyOverride
|
|
1218
|
+
};
|
|
1219
|
+
const quirks = [.../* @__PURE__ */ new Set([...merged.quirks, ...identity.quirks])];
|
|
1220
|
+
let budget = merged.maxRecommendedTurnBudget;
|
|
1221
|
+
if (identity.quirks.includes("thinking")) {
|
|
1222
|
+
budget = Math.ceil(budget * 1.5);
|
|
1223
|
+
}
|
|
1224
|
+
return {
|
|
1225
|
+
id: modelId,
|
|
1226
|
+
vendor: identity.vendor,
|
|
1227
|
+
family: identity.family,
|
|
1228
|
+
...identity.version !== void 0 && { version: identity.version },
|
|
1229
|
+
parallelToolCalls: merged.parallelToolCalls,
|
|
1230
|
+
promptCaching: merged.promptCaching,
|
|
1231
|
+
toolDefinitionFormat: merged.toolDefinitionFormat,
|
|
1232
|
+
maxRecommendedTurnBudget: budget,
|
|
1233
|
+
strictJson: merged.strictJson,
|
|
1234
|
+
quirks,
|
|
1235
|
+
profileId: merged.profileId,
|
|
1236
|
+
source: "derived"
|
|
1237
|
+
};
|
|
1238
|
+
}
|
|
1239
|
+
|
|
1240
|
+
// src/config/model-identity.ts
|
|
1241
|
+
var VENDOR_PATTERNS = [
|
|
1242
|
+
{ vendor: "anthropic", regex: /\b(claude|anthropic)\b/ },
|
|
1243
|
+
// OpenAI: gpt, o1-o9 reasoning, chatgpt, openai prefix
|
|
1244
|
+
{ vendor: "openai", regex: /\b(gpt|o[1-9]|chatgpt|openai)\b/ },
|
|
1245
|
+
{ vendor: "google", regex: /\b(gemini|bison|gecko|palm|google)\b/ },
|
|
1246
|
+
{ vendor: "meta", regex: /\b(llama|meta-llama|meta)\b/ },
|
|
1247
|
+
{ vendor: "qwen", regex: /\b(qwen)\b/ },
|
|
1248
|
+
{ vendor: "nvidia", regex: /\b(nemotron|nvidia)\b/ },
|
|
1249
|
+
{ vendor: "mistral", regex: /\b(mistral|mixtral|codestral)\b/ },
|
|
1250
|
+
{ vendor: "cohere", regex: /\b(command-r|command|cohere)\b/ },
|
|
1251
|
+
{ vendor: "deepseek", regex: /\b(deepseek)\b/ }
|
|
1252
|
+
];
|
|
1253
|
+
var FAMILY_PATTERNS = [
|
|
1254
|
+
// Anthropic
|
|
1255
|
+
{ vendor: "anthropic", family: "claude-opus", regex: /\b(opus)\b/ },
|
|
1256
|
+
{ vendor: "anthropic", family: "claude-sonnet", regex: /\b(sonnet)\b/ },
|
|
1257
|
+
{ vendor: "anthropic", family: "claude-haiku", regex: /\b(haiku)\b/ },
|
|
1258
|
+
// OpenAI
|
|
1259
|
+
{ vendor: "openai", family: "o-reasoning", regex: /\bo[1-9]\b/ },
|
|
1260
|
+
{ vendor: "openai", family: "gpt-4o", regex: /\b(gpt-4o|gpt4o|4o)\b/ },
|
|
1261
|
+
{ vendor: "openai", family: "gpt-4", regex: /\b(gpt-4)\b/ },
|
|
1262
|
+
{ vendor: "openai", family: "gpt-3.5", regex: /\b(gpt-3-5|gpt-3\.5|gpt35)\b/ },
|
|
1263
|
+
// Google
|
|
1264
|
+
{ vendor: "google", family: "gemini-pro", regex: /\bgemini.*\bpro\b/ },
|
|
1265
|
+
{ vendor: "google", family: "gemini-flash", regex: /\bgemini.*\bflash\b/ },
|
|
1266
|
+
{ vendor: "google", family: "gemini", regex: /\bgemini\b/ },
|
|
1267
|
+
// Meta
|
|
1268
|
+
{ vendor: "meta", family: "llama-3", regex: /\bllama-?3\b/ },
|
|
1269
|
+
{ vendor: "meta", family: "llama-2", regex: /\bllama-?2\b/ },
|
|
1270
|
+
// Qwen — version is in the family name
|
|
1271
|
+
{ vendor: "qwen", family: "qwen-3", regex: /\bqwen-?3\b/ },
|
|
1272
|
+
{ vendor: "qwen", family: "qwen-2.5", regex: /\bqwen-?2-?5\b/ },
|
|
1273
|
+
{ vendor: "qwen", family: "qwen-2", regex: /\bqwen-?2\b/ },
|
|
1274
|
+
// Mistral
|
|
1275
|
+
{ vendor: "mistral", family: "mixtral", regex: /\bmixtral\b/ },
|
|
1276
|
+
{ vendor: "mistral", family: "codestral", regex: /\bcodestral\b/ },
|
|
1277
|
+
{ vendor: "mistral", family: "mistral", regex: /\bmistral\b/ }
|
|
1278
|
+
];
|
|
1279
|
+
var QUIRK_PATTERNS = [
|
|
1280
|
+
{ regex: /\b(embedding|embed)\b/, quirk: "embedding" },
|
|
1281
|
+
{ regex: /\b(thinking|reasoning)\b/, quirk: "thinking" },
|
|
1282
|
+
{ regex: /\bvision\b/, quirk: "vision" },
|
|
1283
|
+
{ regex: /\b(coder|code)\b/, quirk: "coder" },
|
|
1284
|
+
{ regex: /\binstruct\b/, quirk: "instruct" },
|
|
1285
|
+
{ regex: /\b(mini|nano|tiny|small|lite)\b/, quirk: "small" },
|
|
1286
|
+
{ regex: /\b(large|xl|big|maxi)\b/, quirk: "large" },
|
|
1287
|
+
{ regex: /\bhigh\b/, quirk: "high-variant" },
|
|
1288
|
+
{ regex: /\b(\d+)b\b/, quirk: "sized-suffix" },
|
|
1289
|
+
// 7b, 70b, 405b
|
|
1290
|
+
{ regex: /\b(?:\d{8}|\d{4}-\d{2}-\d{2}|\d{4}-\d{2})\b/, quirk: "dated" }
|
|
1291
|
+
// 20240806 / 2024-08-06 / 2024-08
|
|
1292
|
+
];
|
|
1293
|
+
async function resolveModelIdentity(adapter, options = {}) {
|
|
1294
|
+
const rawModelId = adapter.modelId;
|
|
1295
|
+
const hints = options.hints ?? {};
|
|
1296
|
+
let probe;
|
|
1297
|
+
if (options.skipProbe !== true && typeof adapter.listModels === "function") {
|
|
1298
|
+
probe = await runProbe(adapter, rawModelId);
|
|
1299
|
+
}
|
|
1300
|
+
const parsed = parseModelId(rawModelId);
|
|
1301
|
+
return mergeIdentity({ rawModelId, hints, probe, parsed });
|
|
1302
|
+
}
|
|
1303
|
+
function resolveModelIdentitySync(modelId, hints) {
|
|
1304
|
+
return mergeIdentity({
|
|
1305
|
+
rawModelId: modelId,
|
|
1306
|
+
hints: hints ?? {},
|
|
1307
|
+
probe: void 0,
|
|
1308
|
+
parsed: parseModelId(modelId)
|
|
1309
|
+
});
|
|
1310
|
+
}
|
|
1311
|
+
function parseModelId(modelId) {
|
|
1312
|
+
const normalised = normaliseModelId(modelId);
|
|
1313
|
+
const vendor = detectVendor(normalised);
|
|
1314
|
+
const family = vendor !== void 0 ? detectFamily(normalised, vendor) : void 0;
|
|
1315
|
+
const version = vendor !== void 0 && family !== void 0 ? extractVersion(normalised, family) : void 0;
|
|
1316
|
+
const quirks = detectQuirks(normalised);
|
|
1317
|
+
return {
|
|
1318
|
+
...vendor !== void 0 && { vendor },
|
|
1319
|
+
...family !== void 0 && { family },
|
|
1320
|
+
...version !== void 0 && { version },
|
|
1321
|
+
quirks
|
|
1322
|
+
};
|
|
1323
|
+
}
|
|
1324
|
+
function normaliseModelId(modelId) {
|
|
1325
|
+
return modelId.toLowerCase().replace(/[_/]/g, "-").replace(/-+/g, "-").replace(/^-|-$/g, "");
|
|
1326
|
+
}
|
|
1327
|
+
function detectVendor(normalised) {
|
|
1328
|
+
for (const { vendor, regex } of VENDOR_PATTERNS) {
|
|
1329
|
+
if (regex.test(normalised)) return vendor;
|
|
1330
|
+
}
|
|
1331
|
+
return void 0;
|
|
1332
|
+
}
|
|
1333
|
+
function detectFamily(normalised, vendor) {
|
|
1334
|
+
for (const fp of FAMILY_PATTERNS) {
|
|
1335
|
+
if (fp.vendor !== vendor) continue;
|
|
1336
|
+
if (fp.regex.test(normalised)) return fp.family;
|
|
1337
|
+
}
|
|
1338
|
+
return void 0;
|
|
1339
|
+
}
|
|
1340
|
+
function extractVersion(normalised, family) {
|
|
1341
|
+
const familyRoot = family.replace(/^claude-|^gemini-|^llama-|^qwen-|^gpt-/, "");
|
|
1342
|
+
const idx = normalised.indexOf(familyRoot);
|
|
1343
|
+
if (idx === -1) return void 0;
|
|
1344
|
+
const tail = normalised.slice(idx + familyRoot.length);
|
|
1345
|
+
const m = /^[-]?(\d[\d.\-]*)/.exec(tail);
|
|
1346
|
+
if (m === null) return void 0;
|
|
1347
|
+
return m[1]?.replace(/-+$/, "") ?? void 0;
|
|
1348
|
+
}
|
|
1349
|
+
function detectQuirks(normalised) {
|
|
1350
|
+
const out = [];
|
|
1351
|
+
for (const { regex, quirk } of QUIRK_PATTERNS) {
|
|
1352
|
+
if (regex.test(normalised) && !out.includes(quirk)) out.push(quirk);
|
|
1353
|
+
}
|
|
1354
|
+
return out;
|
|
1355
|
+
}
|
|
1356
|
+
async function runProbe(adapter, modelId) {
|
|
1357
|
+
try {
|
|
1358
|
+
const capable = adapter;
|
|
1359
|
+
const models = await capable.listModels();
|
|
1360
|
+
const matched = models.find((m) => m.id === modelId);
|
|
1361
|
+
if (matched === void 0) return void 0;
|
|
1362
|
+
const result = { metadata: matched };
|
|
1363
|
+
if (matched.ownedBy !== void 0) {
|
|
1364
|
+
const vendor = vendorFromOwnedBy(matched.ownedBy);
|
|
1365
|
+
if (vendor !== void 0) {
|
|
1366
|
+
return { ...result, vendor };
|
|
1367
|
+
}
|
|
1368
|
+
}
|
|
1369
|
+
return result;
|
|
1370
|
+
} catch {
|
|
1371
|
+
return void 0;
|
|
1372
|
+
}
|
|
1373
|
+
}
|
|
1374
|
+
var OWNED_BY_PATTERNS = [
|
|
1375
|
+
{ substr: "anthropic", vendor: "anthropic" },
|
|
1376
|
+
{ substr: "openai", vendor: "openai" },
|
|
1377
|
+
{ substr: "google", vendor: "google" },
|
|
1378
|
+
{ substr: "meta", vendor: "meta" },
|
|
1379
|
+
{ substr: "alibaba", vendor: "qwen" },
|
|
1380
|
+
{ substr: "qwen", vendor: "qwen" },
|
|
1381
|
+
{ substr: "nvidia", vendor: "nvidia" },
|
|
1382
|
+
{ substr: "nemotron", vendor: "nvidia" },
|
|
1383
|
+
{ substr: "mistral", vendor: "mistral" },
|
|
1384
|
+
{ substr: "cohere", vendor: "cohere" },
|
|
1385
|
+
{ substr: "deepseek", vendor: "deepseek" }
|
|
1386
|
+
];
|
|
1387
|
+
function vendorFromOwnedBy(ownedBy) {
|
|
1388
|
+
const lc = ownedBy.toLowerCase();
|
|
1389
|
+
for (const { substr, vendor } of OWNED_BY_PATTERNS) {
|
|
1390
|
+
if (lc.includes(substr)) return vendor;
|
|
1391
|
+
}
|
|
1392
|
+
return void 0;
|
|
1393
|
+
}
|
|
1394
|
+
function mergeIdentity(args) {
|
|
1395
|
+
const { rawModelId, hints, probe, parsed } = args;
|
|
1396
|
+
const version = pickVersion(hints, parsed);
|
|
1397
|
+
return {
|
|
1398
|
+
vendor: hints.vendor ?? probe?.vendor ?? parsed.vendor ?? "unknown",
|
|
1399
|
+
family: hints.family ?? parsed.family ?? "unknown",
|
|
1400
|
+
...version !== void 0 && { version },
|
|
1401
|
+
quirks: [.../* @__PURE__ */ new Set([...hints.quirks ?? [], ...parsed.quirks])],
|
|
1402
|
+
source: pickSource(hints, probe, parsed),
|
|
1403
|
+
rawModelId
|
|
1404
|
+
};
|
|
1405
|
+
}
|
|
1406
|
+
function pickVersion(hints, parsed) {
|
|
1407
|
+
return hints.version ?? parsed.version;
|
|
1408
|
+
}
|
|
1409
|
+
function pickSource(hints, probe, parsed) {
|
|
1410
|
+
if (hints.vendor !== void 0) return "modelHints";
|
|
1411
|
+
if (probe?.vendor !== void 0) return "probe";
|
|
1412
|
+
if (parsed.vendor !== void 0) return "modelIdParse";
|
|
1413
|
+
return "default";
|
|
1414
|
+
}
|
|
1415
|
+
|
|
1416
|
+
// src/config/in-tree-entries.ts
|
|
1417
|
+
function providerToVendor(provider) {
|
|
1418
|
+
switch (provider) {
|
|
1419
|
+
case "anthropic":
|
|
1420
|
+
case "google":
|
|
1421
|
+
case "openai":
|
|
1422
|
+
return provider;
|
|
1423
|
+
default:
|
|
1424
|
+
return "unknown";
|
|
1425
|
+
}
|
|
1426
|
+
}
|
|
1427
|
+
function optionalFields(model) {
|
|
1428
|
+
const out = {};
|
|
1429
|
+
if (model.maxOutputTokens !== void 0) out.maxOutputTokens = model.maxOutputTokens;
|
|
1430
|
+
if (model.pricing !== void 0) out.pricing = model.pricing;
|
|
1431
|
+
if (model.qualityScores !== void 0) out.qualityScores = model.qualityScores;
|
|
1432
|
+
if (model.notes !== void 0) out.notes = model.notes;
|
|
1433
|
+
if (model.cliName !== void 0) out.cliName = model.cliName;
|
|
1434
|
+
if (model.cliAlias !== void 0) out.cliAlias = model.cliAlias;
|
|
1435
|
+
if (model.cliModelName !== void 0) out.cliModelName = model.cliModelName;
|
|
1436
|
+
return out;
|
|
1437
|
+
}
|
|
1438
|
+
function toEntry(model) {
|
|
1439
|
+
const vendorHint = providerToVendor(model.provider);
|
|
1440
|
+
const identity = resolveModelIdentitySync(model.id, { vendor: vendorHint });
|
|
1441
|
+
const derived = deriveEntry(model.id, identity);
|
|
1442
|
+
const allAliases = new Set(model.aliases ?? []);
|
|
1443
|
+
if (model.cliModelName !== void 0 && model.cliModelName !== model.id) {
|
|
1444
|
+
allAliases.add(model.cliModelName);
|
|
1445
|
+
}
|
|
1446
|
+
return {
|
|
1447
|
+
...derived,
|
|
1448
|
+
id: model.id,
|
|
1449
|
+
...allAliases.size > 0 && { aliases: [...allAliases] },
|
|
1450
|
+
displayName: model.displayName,
|
|
1451
|
+
contextWindow: model.contextWindow,
|
|
1452
|
+
inputModalities: model.inputModalities,
|
|
1453
|
+
outputModalities: model.outputModalities,
|
|
1454
|
+
toolCapabilities: model.toolCapabilities,
|
|
1455
|
+
specialFeatures: model.specialFeatures,
|
|
1456
|
+
...optionalFields(model),
|
|
1457
|
+
source: "in-tree"
|
|
1458
|
+
};
|
|
1459
|
+
}
|
|
1460
|
+
function buildInTreeEntries() {
|
|
1461
|
+
return DEFAULT_MODEL_CAPABILITIES.models.map(toEntry);
|
|
1462
|
+
}
|
|
1463
|
+
|
|
1464
|
+
// src/config/manifest-overlay.ts
|
|
1465
|
+
import { existsSync, readFileSync, statSync } from "fs";
|
|
1466
|
+
import { parse as parseYaml } from "yaml";
|
|
1467
|
+
import { z as z3 } from "zod";
|
|
1468
|
+
|
|
1469
|
+
// src/config/model-capabilities-types.ts
|
|
1470
|
+
import { z as z2 } from "zod";
|
|
1471
|
+
var OUTPUT_MODALITIES = [
|
|
1472
|
+
"text",
|
|
1473
|
+
"image_png",
|
|
1474
|
+
"image_jpeg",
|
|
1475
|
+
"audio_pcm",
|
|
1476
|
+
"audio_wav",
|
|
1477
|
+
"audio_mp3",
|
|
1478
|
+
"video_mp4",
|
|
1479
|
+
"svg",
|
|
1480
|
+
"structured_json",
|
|
1481
|
+
"code"
|
|
1482
|
+
];
|
|
1483
|
+
var INPUT_MODALITIES = ["text", "image", "audio", "video", "pdf", "code"];
|
|
1484
|
+
var TOOL_CAPABILITIES = [
|
|
1485
|
+
"mcp",
|
|
1486
|
+
"function_calling",
|
|
1487
|
+
"computer_use",
|
|
1488
|
+
"code_execution_sandbox",
|
|
1489
|
+
"web_search",
|
|
1490
|
+
"file_operations",
|
|
1491
|
+
"structured_output",
|
|
1492
|
+
"apply_patch"
|
|
1493
|
+
];
|
|
1494
|
+
var SPECIAL_FEATURES = [
|
|
1495
|
+
"extended_thinking",
|
|
1496
|
+
"deep_research",
|
|
1497
|
+
"streaming",
|
|
1498
|
+
"grounding",
|
|
1499
|
+
"citations",
|
|
1500
|
+
"image_editing",
|
|
1501
|
+
"voice_cloning",
|
|
1502
|
+
"live_api",
|
|
1503
|
+
"context_caching"
|
|
1504
|
+
];
|
|
1505
|
+
var PROVIDERS = ["anthropic", "google", "openai", "custom-openai", "openrouter"];
|
|
1506
|
+
var CLI_NAMES = ["claude", "gemini", "codex", "opencode"];
|
|
1507
|
+
var CliNameSchema = z2.enum(CLI_NAMES);
|
|
1508
|
+
var DEFAULT_CLI = "claude";
|
|
1509
|
+
var MODEL_IDS = [
|
|
1510
|
+
"claude-opus",
|
|
1511
|
+
"claude-sonnet",
|
|
1512
|
+
"claude-haiku",
|
|
1513
|
+
"gemini-3-pro",
|
|
1514
|
+
"gemini-pro",
|
|
1515
|
+
"gemini-3-flash",
|
|
1516
|
+
"gemini-flash",
|
|
1517
|
+
"codex-5.3",
|
|
1518
|
+
"codex-5.2",
|
|
1519
|
+
"codex-5.1-mini",
|
|
1520
|
+
"opencode-default",
|
|
1521
|
+
"opencode-custom-opus",
|
|
1522
|
+
"opencode-custom-sonnet",
|
|
1523
|
+
"openrouter-nemotron-super",
|
|
1524
|
+
"openrouter-qwen-coder"
|
|
1525
|
+
];
|
|
1526
|
+
var QualityScoresSchema = z2.object({
|
|
1527
|
+
reasoning: z2.number().min(0).max(10),
|
|
1528
|
+
codeGeneration: z2.number().min(0).max(10),
|
|
1529
|
+
speed: z2.number().min(0).max(10),
|
|
1530
|
+
cost: z2.number().min(0).max(10)
|
|
1531
|
+
});
|
|
1532
|
+
var PricingSchema = z2.object({
|
|
1533
|
+
inputPer1M: z2.number().nonnegative(),
|
|
1534
|
+
outputPer1M: z2.number().nonnegative()
|
|
1535
|
+
});
|
|
1536
|
+
var ModelCapabilitySchema = z2.object({
|
|
1537
|
+
/** Unique model identifier matching delegate_to_model model IDs */
|
|
1538
|
+
id: z2.enum(MODEL_IDS),
|
|
1539
|
+
/** Human-readable display name */
|
|
1540
|
+
displayName: z2.string().min(1),
|
|
1541
|
+
/** Provider/vendor */
|
|
1542
|
+
provider: z2.enum(PROVIDERS),
|
|
1543
|
+
/** Maximum context window in tokens */
|
|
1544
|
+
contextWindow: z2.number().int().positive(),
|
|
1545
|
+
/** Output modalities this model can produce */
|
|
1546
|
+
outputModalities: z2.array(z2.enum(OUTPUT_MODALITIES)).min(1),
|
|
1547
|
+
/** Input modalities this model can accept */
|
|
1548
|
+
inputModalities: z2.array(z2.enum(INPUT_MODALITIES)).min(1),
|
|
1549
|
+
/** Tool/integration capabilities */
|
|
1550
|
+
toolCapabilities: z2.array(z2.enum(TOOL_CAPABILITIES)),
|
|
1551
|
+
/** Special features beyond standard generation */
|
|
1552
|
+
specialFeatures: z2.array(z2.enum(SPECIAL_FEATURES)),
|
|
1553
|
+
/** Known constraints or limitations */
|
|
1554
|
+
constraints: z2.array(z2.string()).optional(),
|
|
1555
|
+
/** Notes about the model (e.g., beta features, pricing tier) */
|
|
1556
|
+
notes: z2.string().optional(),
|
|
1557
|
+
/** Pricing per 1M tokens (USD) */
|
|
1558
|
+
pricing: PricingSchema.optional(),
|
|
1559
|
+
/** Quality scores for routing (0-10 scale) */
|
|
1560
|
+
qualityScores: QualityScoresSchema.optional(),
|
|
1561
|
+
/** Maximum output tokens */
|
|
1562
|
+
maxOutputTokens: z2.number().int().positive().optional(),
|
|
1563
|
+
/** Which CLI tool this model belongs to */
|
|
1564
|
+
cliName: z2.enum(CLI_NAMES).optional(),
|
|
1565
|
+
/** Short alias used by the CLI (e.g., 'opus' for Claude CLI) */
|
|
1566
|
+
cliAlias: z2.string().optional(),
|
|
1567
|
+
/** Model name the CLI binary expects (e.g., 'gemini-2.5-pro') */
|
|
1568
|
+
cliModelName: z2.string().optional(),
|
|
1569
|
+
/**
|
|
1570
|
+
* Legacy / version-suffixed names that resolve to this model. Used by
|
|
1571
|
+
* adapters and routing to map historical user-facing names (e.g.,
|
|
1572
|
+
* `claude-opus-4-5-20251101`, `gemini-2.5-pro`) to the current registry
|
|
1573
|
+
* entry. Empty strings are rejected; uniqueness within the array is not
|
|
1574
|
+
* enforced at schema level (caller responsibility).
|
|
1575
|
+
*
|
|
1576
|
+
* Added for issue #2199 Child 1; populated by the companion migration
|
|
1577
|
+
* epic #2200.
|
|
1578
|
+
*/
|
|
1579
|
+
aliases: z2.array(z2.string().min(1)).optional(),
|
|
1580
|
+
/** Whether this model is deprecated and should receive a scoring penalty */
|
|
1581
|
+
deprecated: z2.boolean().optional(),
|
|
1582
|
+
/** ISO date when the model was deprecated (informational) */
|
|
1583
|
+
deprecatedAt: z2.string().optional(),
|
|
1584
|
+
/** Model ID to migrate to (informational guidance) */
|
|
1585
|
+
replacedBy: z2.enum(MODEL_IDS).optional()
|
|
1586
|
+
});
|
|
1587
|
+
var ModelCapabilitiesMatrixSchema = z2.object({
|
|
1588
|
+
/** Schema version for forward compatibility */
|
|
1589
|
+
version: z2.number().int().positive(),
|
|
1590
|
+
/** Last updated date (ISO 8601) */
|
|
1591
|
+
updatedAt: z2.string(),
|
|
1592
|
+
/** Model capability definitions */
|
|
1593
|
+
models: z2.array(ModelCapabilitySchema).min(1)
|
|
1594
|
+
});
|
|
1595
|
+
|
|
1596
|
+
// src/config/manifest-overlay.ts
|
|
1597
|
+
var MANIFEST_ENV_VAR = "NEXUS_MODELS_OVERLAY_PATH";
|
|
1598
|
+
var MANIFEST_MAX_BYTES = 1 * 1024 * 1024;
|
|
1599
|
+
function defaultManifestPath() {
|
|
1600
|
+
return nexusDataPath("models-manifest.yaml");
|
|
1601
|
+
}
|
|
1602
|
+
function resolveManifestPath(env = process.env) {
|
|
1603
|
+
const override = env[MANIFEST_ENV_VAR];
|
|
1604
|
+
if (override !== void 0 && override !== "") return override;
|
|
1605
|
+
return defaultManifestPath();
|
|
1606
|
+
}
|
|
1607
|
+
var ModelVendorSchema = z3.enum([
|
|
1608
|
+
"anthropic",
|
|
1609
|
+
"openai",
|
|
1610
|
+
"google",
|
|
1611
|
+
"meta",
|
|
1612
|
+
"qwen",
|
|
1613
|
+
"nvidia",
|
|
1614
|
+
"mistral",
|
|
1615
|
+
"cohere",
|
|
1616
|
+
"deepseek",
|
|
1617
|
+
"unknown"
|
|
1618
|
+
]);
|
|
1619
|
+
var ToolDefinitionFormatSchema = z3.enum([
|
|
1620
|
+
"openai",
|
|
1621
|
+
"anthropic",
|
|
1622
|
+
"gemini"
|
|
1623
|
+
]);
|
|
1624
|
+
var PromptCachingModeSchema = z3.enum([
|
|
1625
|
+
"none",
|
|
1626
|
+
"ephemeral",
|
|
1627
|
+
"aggressive"
|
|
1628
|
+
]);
|
|
1629
|
+
var ManifestEntrySchema = z3.object({
|
|
1630
|
+
// Identity (required)
|
|
1631
|
+
id: z3.string().min(1).max(200),
|
|
1632
|
+
vendor: ModelVendorSchema,
|
|
1633
|
+
family: z3.string().min(1).max(80),
|
|
1634
|
+
// Identity (optional)
|
|
1635
|
+
aliases: z3.array(z3.string().min(1).max(200)).max(20).optional(),
|
|
1636
|
+
version: z3.string().min(1).max(50).optional(),
|
|
1637
|
+
displayName: z3.string().min(1).max(200).optional(),
|
|
1638
|
+
// Capabilities (all optional)
|
|
1639
|
+
contextWindow: z3.number().int().positive().max(2e7).optional(),
|
|
1640
|
+
maxOutputTokens: z3.number().int().positive().max(2e7).optional(),
|
|
1641
|
+
inputModalities: z3.array(z3.enum(INPUT_MODALITIES)).optional(),
|
|
1642
|
+
outputModalities: z3.array(z3.enum(OUTPUT_MODALITIES)).optional(),
|
|
1643
|
+
toolCapabilities: z3.array(z3.enum(TOOL_CAPABILITIES)).optional(),
|
|
1644
|
+
specialFeatures: z3.array(z3.enum(SPECIAL_FEATURES)).optional(),
|
|
1645
|
+
pricing: PricingSchema.optional(),
|
|
1646
|
+
qualityScores: QualityScoresSchema.optional(),
|
|
1647
|
+
notes: z3.string().max(2e3).optional(),
|
|
1648
|
+
// Behaviour (all optional — defaults fill in)
|
|
1649
|
+
parallelToolCalls: z3.boolean().optional(),
|
|
1650
|
+
promptCaching: PromptCachingModeSchema.optional(),
|
|
1651
|
+
toolDefinitionFormat: ToolDefinitionFormatSchema.optional(),
|
|
1652
|
+
maxRecommendedTurnBudget: z3.number().int().positive().max(100).optional(),
|
|
1653
|
+
strictJson: z3.boolean().optional(),
|
|
1654
|
+
quirks: z3.array(z3.string().max(80)).max(20).optional(),
|
|
1655
|
+
profileId: z3.string().min(1).max(80).optional(),
|
|
1656
|
+
// Provenance (optional)
|
|
1657
|
+
verifiedAt: z3.string().min(8).max(40).optional()
|
|
1658
|
+
});
|
|
1659
|
+
var ManifestSchema = z3.object({
|
|
1660
|
+
version: z3.literal(1),
|
|
1661
|
+
models: z3.array(z3.unknown())
|
|
1662
|
+
});
|
|
1663
|
+
function loadManifestOverlay(options) {
|
|
1664
|
+
const logger11 = options?.logger ?? createLogger({ component: "manifest-overlay" });
|
|
1665
|
+
const path2 = options?.path ?? resolveManifestPath(options?.env);
|
|
1666
|
+
let exists = false;
|
|
1667
|
+
try {
|
|
1668
|
+
exists = existsSync(path2);
|
|
1669
|
+
} catch {
|
|
1670
|
+
return { entries: [], rejections: [], path: path2, status: "missing" };
|
|
1671
|
+
}
|
|
1672
|
+
if (!exists) {
|
|
1673
|
+
return { entries: [], rejections: [], path: path2, status: "missing" };
|
|
1674
|
+
}
|
|
1675
|
+
const stat = statSync(path2);
|
|
1676
|
+
if (stat.size === 0) {
|
|
1677
|
+
return { entries: [], rejections: [], path: path2, status: "empty" };
|
|
1678
|
+
}
|
|
1679
|
+
if (stat.size > MANIFEST_MAX_BYTES) {
|
|
1680
|
+
logger11.warn("Manifest overlay too large; skipping", {
|
|
1681
|
+
path: path2,
|
|
1682
|
+
size: stat.size,
|
|
1683
|
+
max: MANIFEST_MAX_BYTES
|
|
1684
|
+
});
|
|
1685
|
+
return { entries: [], rejections: [], path: path2, status: "too-large" };
|
|
1686
|
+
}
|
|
1687
|
+
const raw = readFileSync(path2, "utf-8");
|
|
1688
|
+
return parseManifest(raw, path2, logger11);
|
|
1689
|
+
}
|
|
1690
|
+
function parseManifest(raw, path2, logger11) {
|
|
1691
|
+
let parsed;
|
|
1692
|
+
try {
|
|
1693
|
+
if (path2.endsWith(".json")) {
|
|
1694
|
+
parsed = JSON.parse(raw);
|
|
1695
|
+
} else {
|
|
1696
|
+
parsed = parseYaml(raw);
|
|
1697
|
+
}
|
|
1698
|
+
} catch (e) {
|
|
1699
|
+
logger11.warn("Manifest overlay parse failure; skipping", {
|
|
1700
|
+
path: path2,
|
|
1701
|
+
error: e instanceof Error ? e.message : String(e)
|
|
1702
|
+
});
|
|
1703
|
+
return { entries: [], rejections: [], path: path2, status: "malformed" };
|
|
1704
|
+
}
|
|
1705
|
+
const shape = ManifestSchema.safeParse(parsed);
|
|
1706
|
+
if (!shape.success) {
|
|
1707
|
+
logger11.warn("Manifest overlay schema mismatch at root; skipping", {
|
|
1708
|
+
path: path2,
|
|
1709
|
+
issues: shape.error.issues.slice(0, 5).map((i) => i.message)
|
|
1710
|
+
});
|
|
1711
|
+
return { entries: [], rejections: [], path: path2, status: "malformed" };
|
|
1712
|
+
}
|
|
1713
|
+
const entries = [];
|
|
1714
|
+
const rejections = [];
|
|
1715
|
+
shape.data.models.forEach((rawEntry, index) => {
|
|
1716
|
+
const result = ManifestEntrySchema.safeParse(rawEntry);
|
|
1717
|
+
if (!result.success) {
|
|
1718
|
+
const candidateId = typeof rawEntry === "object" && rawEntry !== null && "id" in rawEntry && typeof rawEntry.id === "string" ? rawEntry.id : void 0;
|
|
1719
|
+
const baseRejection = {
|
|
1720
|
+
index,
|
|
1721
|
+
reason: result.error.issues.slice(0, 3).map((i) => `${i.path.join(".")}: ${i.message}`).join("; ")
|
|
1722
|
+
};
|
|
1723
|
+
if (candidateId !== void 0) baseRejection.id = candidateId;
|
|
1724
|
+
rejections.push(baseRejection);
|
|
1725
|
+
return;
|
|
1726
|
+
}
|
|
1727
|
+
entries.push(materializeEntry(result.data));
|
|
1728
|
+
});
|
|
1729
|
+
return { entries, rejections, path: path2, status: "loaded" };
|
|
1730
|
+
}
|
|
1731
|
+
function materializeEntry(input) {
|
|
1732
|
+
return {
|
|
1733
|
+
id: input.id,
|
|
1734
|
+
vendor: input.vendor,
|
|
1735
|
+
family: input.family,
|
|
1736
|
+
// Behaviour with sensible defaults
|
|
1737
|
+
parallelToolCalls: input.parallelToolCalls ?? false,
|
|
1738
|
+
promptCaching: input.promptCaching ?? "none",
|
|
1739
|
+
toolDefinitionFormat: input.toolDefinitionFormat ?? "openai",
|
|
1740
|
+
maxRecommendedTurnBudget: input.maxRecommendedTurnBudget ?? 10,
|
|
1741
|
+
strictJson: input.strictJson ?? true,
|
|
1742
|
+
quirks: input.quirks ?? [],
|
|
1743
|
+
profileId: input.profileId ?? `manifest-${input.vendor}`,
|
|
1744
|
+
source: "manifest",
|
|
1745
|
+
...pickOptionalFields(input)
|
|
1746
|
+
};
|
|
1747
|
+
}
|
|
1748
|
+
var OPTIONAL_PASSTHROUGH_KEYS = [
|
|
1749
|
+
"aliases",
|
|
1750
|
+
"version",
|
|
1751
|
+
"displayName",
|
|
1752
|
+
"contextWindow",
|
|
1753
|
+
"maxOutputTokens",
|
|
1754
|
+
"inputModalities",
|
|
1755
|
+
"outputModalities",
|
|
1756
|
+
"toolCapabilities",
|
|
1757
|
+
"specialFeatures",
|
|
1758
|
+
"pricing",
|
|
1759
|
+
"qualityScores",
|
|
1760
|
+
"notes",
|
|
1761
|
+
"verifiedAt"
|
|
1762
|
+
];
|
|
1763
|
+
function pickOptionalFields(input) {
|
|
1764
|
+
const out = {};
|
|
1765
|
+
const inputRecord = input;
|
|
1766
|
+
for (const key of OPTIONAL_PASSTHROUGH_KEYS) {
|
|
1767
|
+
const value = inputRecord[key];
|
|
1768
|
+
if (value !== void 0) out[key] = value;
|
|
1769
|
+
}
|
|
1770
|
+
return out;
|
|
1771
|
+
}
|
|
1772
|
+
|
|
1773
|
+
// src/config/models-dev-snapshot-loader.ts
|
|
1774
|
+
import { existsSync as existsSync2, readFileSync as readFileSync2 } from "fs";
|
|
1775
|
+
import { fileURLToPath } from "url";
|
|
1776
|
+
import { dirname, join } from "path";
|
|
1777
|
+
function defaultSnapshotPath() {
|
|
1778
|
+
const here = dirname(fileURLToPath(import.meta.url));
|
|
1779
|
+
return join(here, "models-dev-snapshot.json");
|
|
1780
|
+
}
|
|
1781
|
+
function loadModelsDevSnapshot(options) {
|
|
1782
|
+
const logger11 = createLogger({ component: "models-dev-snapshot" });
|
|
1783
|
+
const path2 = options?.path ?? defaultSnapshotPath();
|
|
1784
|
+
let exists = false;
|
|
1785
|
+
try {
|
|
1786
|
+
exists = existsSync2(path2);
|
|
1787
|
+
} catch {
|
|
1788
|
+
return { entries: [], path: path2, status: "missing" };
|
|
1789
|
+
}
|
|
1790
|
+
if (!exists) {
|
|
1791
|
+
return { entries: [], path: path2, status: "missing" };
|
|
1792
|
+
}
|
|
1793
|
+
let parsed;
|
|
1794
|
+
try {
|
|
1795
|
+
parsed = JSON.parse(readFileSync2(path2, "utf-8"));
|
|
1796
|
+
} catch (e) {
|
|
1797
|
+
logger11.warn("models.dev snapshot parse failure; skipping", {
|
|
1798
|
+
path: path2,
|
|
1799
|
+
error: e instanceof Error ? e.message : String(e)
|
|
1800
|
+
});
|
|
1801
|
+
return { entries: [], path: path2, status: "malformed" };
|
|
1802
|
+
}
|
|
1803
|
+
if (parsed.version !== 1) {
|
|
1804
|
+
logger11.warn("models.dev snapshot version unsupported; skipping", {
|
|
1805
|
+
path: path2,
|
|
1806
|
+
version: parsed.version
|
|
1807
|
+
});
|
|
1808
|
+
return { entries: [], path: path2, status: "malformed" };
|
|
1809
|
+
}
|
|
1810
|
+
if (!Array.isArray(parsed.entries)) {
|
|
1811
|
+
logger11.warn("models.dev snapshot missing entries array; skipping", { path: path2 });
|
|
1812
|
+
return { entries: [], path: path2, status: "malformed" };
|
|
1813
|
+
}
|
|
1814
|
+
const entries = parsed.entries;
|
|
1815
|
+
return {
|
|
1816
|
+
entries,
|
|
1817
|
+
path: path2,
|
|
1818
|
+
status: "loaded",
|
|
1819
|
+
...typeof parsed.fetchedAt === "string" ? { fetchedAt: parsed.fetchedAt } : {}
|
|
1820
|
+
};
|
|
1821
|
+
}
|
|
1822
|
+
|
|
1823
|
+
// src/config/model-registry.ts
|
|
1824
|
+
var ModelRegistry = class {
|
|
1825
|
+
byId = /* @__PURE__ */ new Map();
|
|
1826
|
+
byAlias = /* @__PURE__ */ new Map();
|
|
1827
|
+
// alias → canonical id
|
|
1828
|
+
constructor(options = {}) {
|
|
1829
|
+
if (options.modelsDevEntries !== void 0) {
|
|
1830
|
+
this.loadEntries(options.modelsDevEntries);
|
|
1831
|
+
}
|
|
1832
|
+
if (options.inTreeEntries !== void 0) {
|
|
1833
|
+
this.loadEntries(options.inTreeEntries);
|
|
1834
|
+
}
|
|
1835
|
+
if (options.manifestEntries !== void 0) {
|
|
1836
|
+
this.loadEntries(options.manifestEntries);
|
|
1837
|
+
}
|
|
1838
|
+
}
|
|
1839
|
+
/**
|
|
1840
|
+
* Resolve a model id to its full metadata entry. Always returns —
|
|
1841
|
+
* unknown models get a derived entry with sensible defaults.
|
|
1842
|
+
*/
|
|
1843
|
+
getEntry(modelId, hints) {
|
|
1844
|
+
const direct = this.lookupExact(modelId);
|
|
1845
|
+
if (direct !== void 0 && direct.source !== "models-dev") return direct;
|
|
1846
|
+
const identity = resolveModelIdentitySync(modelId, augmentHints(hints, direct));
|
|
1847
|
+
const derived = deriveEntry(modelId, identity);
|
|
1848
|
+
if (direct !== void 0 && identity.vendor !== "unknown") {
|
|
1849
|
+
return mergeSnapshotWithDerived(direct, derived);
|
|
1850
|
+
}
|
|
1851
|
+
return direct ?? derived;
|
|
1852
|
+
}
|
|
1853
|
+
/**
|
|
1854
|
+
* Has the registry got an authoritative entry for this id?
|
|
1855
|
+
* Consumers use this to distinguish "we know X" from "we guessed."
|
|
1856
|
+
*/
|
|
1857
|
+
hasAuthoritative(modelId) {
|
|
1858
|
+
return this.lookupExact(modelId) !== void 0;
|
|
1859
|
+
}
|
|
1860
|
+
/** All authoritative entries (in-tree + models.dev + manifest, deduped). */
|
|
1861
|
+
allEntries() {
|
|
1862
|
+
return [...this.byId.values()];
|
|
1863
|
+
}
|
|
1864
|
+
/** Snapshot of canonical id → entry mapping. */
|
|
1865
|
+
toMap() {
|
|
1866
|
+
return new Map(this.byId);
|
|
1867
|
+
}
|
|
1868
|
+
lookupExact(modelId) {
|
|
1869
|
+
const direct = this.byId.get(modelId);
|
|
1870
|
+
if (direct !== void 0) return direct;
|
|
1871
|
+
const canonical = this.byAlias.get(modelId);
|
|
1872
|
+
if (canonical !== void 0) return this.byId.get(canonical);
|
|
1873
|
+
return void 0;
|
|
1874
|
+
}
|
|
1875
|
+
loadEntries(entries) {
|
|
1876
|
+
for (const entry of entries) {
|
|
1877
|
+
this.byId.set(entry.id, entry);
|
|
1878
|
+
if (entry.aliases !== void 0) {
|
|
1879
|
+
for (const alias of entry.aliases) {
|
|
1880
|
+
this.byAlias.set(alias, entry.id);
|
|
1881
|
+
}
|
|
1882
|
+
}
|
|
1883
|
+
}
|
|
1884
|
+
}
|
|
1235
1885
|
};
|
|
1236
|
-
function
|
|
1237
|
-
|
|
1886
|
+
function augmentHints(hints, direct) {
|
|
1887
|
+
const h = hints ?? {};
|
|
1888
|
+
if (direct === void 0) return h;
|
|
1889
|
+
const out = {
|
|
1890
|
+
vendor: h.vendor ?? direct.vendor,
|
|
1891
|
+
family: h.family ?? direct.family
|
|
1892
|
+
};
|
|
1893
|
+
if (h.version !== void 0) out.version = h.version;
|
|
1894
|
+
if (h.quirks !== void 0) out.quirks = h.quirks;
|
|
1895
|
+
return out;
|
|
1896
|
+
}
|
|
1897
|
+
function mergeSnapshotWithDerived(snapshot, derived) {
|
|
1898
|
+
return {
|
|
1899
|
+
...snapshot,
|
|
1900
|
+
parallelToolCalls: derived.parallelToolCalls,
|
|
1901
|
+
promptCaching: derived.promptCaching,
|
|
1902
|
+
toolDefinitionFormat: derived.toolDefinitionFormat,
|
|
1903
|
+
maxRecommendedTurnBudget: derived.maxRecommendedTurnBudget,
|
|
1904
|
+
strictJson: derived.strictJson,
|
|
1905
|
+
quirks: derived.quirks,
|
|
1906
|
+
profileId: derived.profileId,
|
|
1907
|
+
source: "derived"
|
|
1908
|
+
};
|
|
1909
|
+
}
|
|
1910
|
+
var globalRegistry;
|
|
1911
|
+
function getDefaultRegistry() {
|
|
1912
|
+
globalRegistry ??= buildDefaultRegistry();
|
|
1913
|
+
return globalRegistry;
|
|
1914
|
+
}
|
|
1915
|
+
function buildDefaultRegistry() {
|
|
1916
|
+
const overlay = loadManifestOverlay();
|
|
1917
|
+
const snapshot = loadModelsDevSnapshot();
|
|
1918
|
+
const inTree = buildInTreeEntries();
|
|
1919
|
+
const options = { inTreeEntries: inTree };
|
|
1920
|
+
if (overlay.status === "loaded" && overlay.entries.length > 0) {
|
|
1921
|
+
options.manifestEntries = overlay.entries;
|
|
1922
|
+
}
|
|
1923
|
+
if (snapshot.status === "loaded" && snapshot.entries.length > 0) {
|
|
1924
|
+
options.modelsDevEntries = snapshot.entries;
|
|
1925
|
+
}
|
|
1926
|
+
return new ModelRegistry(options);
|
|
1927
|
+
}
|
|
1928
|
+
function setDefaultRegistry(registry) {
|
|
1929
|
+
globalRegistry = registry;
|
|
1930
|
+
}
|
|
1931
|
+
|
|
1932
|
+
// src/config/model-config-helpers.ts
|
|
1933
|
+
function cliAvgLatency() {
|
|
1934
|
+
return { claude: 800, gemini: 400, codex: 500, opencode: 600 };
|
|
1935
|
+
}
|
|
1936
|
+
function lookupInTree(modelId) {
|
|
1937
|
+
const entry = getDefaultRegistry().getEntry(modelId);
|
|
1938
|
+
return entry.source === "in-tree" ? entry : void 0;
|
|
1939
|
+
}
|
|
1940
|
+
function inTreeById() {
|
|
1941
|
+
return new Map(buildInTreeEntries().map((e) => [e.id, e]));
|
|
1942
|
+
}
|
|
1943
|
+
function getModelContextWindow(modelId) {
|
|
1944
|
+
return lookupInTree(modelId)?.contextWindow ?? 8192;
|
|
1945
|
+
}
|
|
1946
|
+
function getDefaultModelForCli(cli) {
|
|
1947
|
+
return DEFAULT_MODEL_PER_CLI[cli];
|
|
1948
|
+
}
|
|
1949
|
+
function getCliModelName(modelId) {
|
|
1950
|
+
const entry = lookupInTree(modelId);
|
|
1951
|
+
return entry?.cliModelName ?? entry?.cliAlias ?? modelId;
|
|
1952
|
+
}
|
|
1953
|
+
function resolveCliAlias(alias) {
|
|
1954
|
+
const match = getDefaultRegistry().allEntries().find(
|
|
1955
|
+
(e) => e.source === "in-tree" && (e.cliAlias === alias || e.id === alias || (e.aliases?.includes(alias) ?? false))
|
|
1956
|
+
);
|
|
1957
|
+
return match?.id;
|
|
1958
|
+
}
|
|
1959
|
+
function buildCapabilityProfiles() {
|
|
1960
|
+
const result = {};
|
|
1961
|
+
for (const entry of buildInTreeEntries()) {
|
|
1962
|
+
const q = entry.qualityScores;
|
|
1963
|
+
if (q !== void 0 && entry.contextWindow !== void 0) {
|
|
1964
|
+
result[entry.id] = {
|
|
1965
|
+
reasoning: q.reasoning,
|
|
1966
|
+
contextWindow: entry.contextWindow,
|
|
1967
|
+
codeGeneration: q.codeGeneration,
|
|
1968
|
+
speed: q.speed,
|
|
1969
|
+
cost: q.cost
|
|
1970
|
+
};
|
|
1971
|
+
}
|
|
1972
|
+
}
|
|
1973
|
+
return result;
|
|
1974
|
+
}
|
|
1975
|
+
function buildCliCapabilityProfiles() {
|
|
1976
|
+
const result = {};
|
|
1977
|
+
const byId = inTreeById();
|
|
1978
|
+
for (const [cli, modelId] of Object.entries(DEFAULT_MODEL_PER_CLI)) {
|
|
1979
|
+
const entry = byId.get(modelId);
|
|
1980
|
+
const q = entry?.qualityScores;
|
|
1981
|
+
if (entry !== void 0 && q !== void 0 && entry.contextWindow !== void 0) {
|
|
1982
|
+
result[cli] = {
|
|
1983
|
+
reasoning: q.reasoning,
|
|
1984
|
+
contextWindow: entry.contextWindow,
|
|
1985
|
+
codeGeneration: q.codeGeneration,
|
|
1986
|
+
speed: q.speed,
|
|
1987
|
+
cost: q.cost
|
|
1988
|
+
};
|
|
1989
|
+
}
|
|
1990
|
+
}
|
|
1991
|
+
return result;
|
|
1992
|
+
}
|
|
1993
|
+
function buildTopsisProfiles() {
|
|
1994
|
+
const profiles = [];
|
|
1995
|
+
const byId = inTreeById();
|
|
1996
|
+
for (const [cli, modelId] of Object.entries(DEFAULT_MODEL_PER_CLI)) {
|
|
1997
|
+
const entry = byId.get(modelId);
|
|
1998
|
+
const q = entry?.qualityScores;
|
|
1999
|
+
const p = entry?.pricing;
|
|
2000
|
+
if (entry === void 0 || q === void 0 || p === void 0) continue;
|
|
2001
|
+
if (entry.contextWindow === void 0) continue;
|
|
2002
|
+
profiles.push({
|
|
2003
|
+
cliName: cli,
|
|
2004
|
+
capabilities: {
|
|
2005
|
+
reasoning: q.reasoning,
|
|
2006
|
+
contextWindow: entry.contextWindow,
|
|
2007
|
+
codeGeneration: q.codeGeneration,
|
|
2008
|
+
speed: q.speed,
|
|
2009
|
+
cost: q.cost
|
|
2010
|
+
},
|
|
2011
|
+
costPerMillionInput: p.inputPer1M,
|
|
2012
|
+
costPerMillionOutput: p.outputPer1M,
|
|
2013
|
+
averageLatencyMs: cliAvgLatency()[cli],
|
|
2014
|
+
qualityScore: (q.reasoning + q.codeGeneration) / 2
|
|
2015
|
+
});
|
|
2016
|
+
}
|
|
2017
|
+
return profiles;
|
|
2018
|
+
}
|
|
2019
|
+
function findCanonicalModel(cli, cliModelName) {
|
|
2020
|
+
const entry = getDefaultRegistry().allEntries().find(
|
|
2021
|
+
(e) => e.source === "in-tree" && e.cliName === cli && (e.cliModelName === cliModelName || e.cliAlias === cliModelName || e.id === cliModelName || (e.aliases?.includes(cliModelName) ?? false))
|
|
2022
|
+
);
|
|
2023
|
+
return entry !== void 0 ? entryToCapability(entry) : void 0;
|
|
2024
|
+
}
|
|
2025
|
+
function applyOptionalCapabilityFields(entry, target) {
|
|
2026
|
+
if (entry.notes !== void 0) target.notes = entry.notes;
|
|
2027
|
+
if (entry.pricing !== void 0) target.pricing = entry.pricing;
|
|
2028
|
+
if (entry.qualityScores !== void 0) target.qualityScores = entry.qualityScores;
|
|
2029
|
+
if (entry.maxOutputTokens !== void 0) target.maxOutputTokens = entry.maxOutputTokens;
|
|
2030
|
+
if (entry.cliName !== void 0) target.cliName = entry.cliName;
|
|
2031
|
+
if (entry.cliAlias !== void 0) target.cliAlias = entry.cliAlias;
|
|
2032
|
+
if (entry.cliModelName !== void 0) target.cliModelName = entry.cliModelName;
|
|
2033
|
+
if (entry.aliases !== void 0) target.aliases = [...entry.aliases];
|
|
2034
|
+
}
|
|
2035
|
+
function entryToCapability(entry) {
|
|
2036
|
+
const cap = {
|
|
2037
|
+
id: entry.id,
|
|
2038
|
+
displayName: entry.displayName ?? entry.id,
|
|
2039
|
+
provider: entry.vendor === "unknown" ? "openai" : entry.vendor,
|
|
2040
|
+
contextWindow: entry.contextWindow ?? 0,
|
|
2041
|
+
outputModalities: [...entry.outputModalities ?? ["text"]],
|
|
2042
|
+
inputModalities: [...entry.inputModalities ?? ["text"]],
|
|
2043
|
+
toolCapabilities: [...entry.toolCapabilities ?? []],
|
|
2044
|
+
specialFeatures: [...entry.specialFeatures ?? []]
|
|
2045
|
+
};
|
|
2046
|
+
applyOptionalCapabilityFields(entry, cap);
|
|
2047
|
+
return cap;
|
|
2048
|
+
}
|
|
2049
|
+
function buildModelInfo(cli, cliModelName) {
|
|
2050
|
+
const cap = findCanonicalModel(cli, cliModelName);
|
|
2051
|
+
if (cap === void 0) return void 0;
|
|
2052
|
+
const info = {
|
|
2053
|
+
id: cliModelName,
|
|
2054
|
+
name: cap.displayName,
|
|
2055
|
+
contextWindow: cap.contextWindow
|
|
2056
|
+
};
|
|
2057
|
+
if (cap.maxOutputTokens !== void 0) {
|
|
2058
|
+
info.maxOutput = cap.maxOutputTokens;
|
|
2059
|
+
}
|
|
2060
|
+
if (cap.pricing !== void 0) {
|
|
2061
|
+
info.costPerMillionInput = cap.pricing.inputPer1M;
|
|
2062
|
+
info.costPerMillionOutput = cap.pricing.outputPer1M;
|
|
2063
|
+
}
|
|
2064
|
+
return info;
|
|
2065
|
+
}
|
|
2066
|
+
function getInTreeCapabilitiesMatrix() {
|
|
2067
|
+
return {
|
|
2068
|
+
version: DEFAULT_MODEL_CAPABILITIES.version,
|
|
2069
|
+
updatedAt: DEFAULT_MODEL_CAPABILITIES.updatedAt,
|
|
2070
|
+
models: buildInTreeEntries().map(entryToCapability)
|
|
2071
|
+
};
|
|
2072
|
+
}
|
|
2073
|
+
function lookupInTreeCapability(modelId) {
|
|
2074
|
+
const entry = lookupInTree(modelId);
|
|
2075
|
+
return entry !== void 0 ? entryToCapability(entry) : void 0;
|
|
1238
2076
|
}
|
|
1239
|
-
function
|
|
1240
|
-
return
|
|
2077
|
+
function findInTreeByCli(cliName) {
|
|
2078
|
+
return buildInTreeEntries().filter((e) => e.cliName === cliName).map(entryToCapability);
|
|
1241
2079
|
}
|
|
1242
|
-
function
|
|
1243
|
-
return
|
|
2080
|
+
function inTreeModels() {
|
|
2081
|
+
return buildInTreeEntries().map(entryToCapability);
|
|
1244
2082
|
}
|
|
1245
|
-
function
|
|
1246
|
-
return
|
|
2083
|
+
function findModelsByOutputModality(modality) {
|
|
2084
|
+
return inTreeModels().filter((m) => m.outputModalities.includes(modality));
|
|
1247
2085
|
}
|
|
1248
|
-
function
|
|
1249
|
-
return
|
|
2086
|
+
function findModelsByInputModality(modality) {
|
|
2087
|
+
return inTreeModels().filter((m) => m.inputModalities.includes(modality));
|
|
1250
2088
|
}
|
|
1251
|
-
function
|
|
1252
|
-
return
|
|
2089
|
+
function findModelsByToolCapability(capability) {
|
|
2090
|
+
return inTreeModels().filter((m) => m.toolCapabilities.includes(capability));
|
|
2091
|
+
}
|
|
2092
|
+
function findModelsByFeature(feature) {
|
|
2093
|
+
return inTreeModels().filter((m) => m.specialFeatures.includes(feature));
|
|
1253
2094
|
}
|
|
1254
2095
|
function includesAll(haystack, required) {
|
|
1255
2096
|
if (required === void 0) return true;
|
|
1256
2097
|
return required.every((item) => haystack.includes(item));
|
|
1257
2098
|
}
|
|
1258
|
-
function modelSupportsAll(modelId, requirements
|
|
1259
|
-
const model =
|
|
2099
|
+
function modelSupportsAll(modelId, requirements) {
|
|
2100
|
+
const model = lookupInTreeCapability(modelId);
|
|
1260
2101
|
if (model === void 0) return false;
|
|
1261
2102
|
const meetsContext = requirements.minContextWindow === void 0 || model.contextWindow >= requirements.minContextWindow;
|
|
1262
2103
|
return meetsContext && includesAll(model.outputModalities, requirements.outputModalities) && includesAll(model.inputModalities, requirements.inputModalities) && includesAll(model.toolCapabilities, requirements.toolCapabilities) && includesAll(model.specialFeatures, requirements.specialFeatures);
|
|
@@ -1276,10 +2117,11 @@ function isPrefixMatch(entry, query) {
|
|
|
1276
2117
|
return id.length > 0 && query.startsWith(id) || cliName.length > 0 && query.startsWith(cliName);
|
|
1277
2118
|
}
|
|
1278
2119
|
function lookupCanonicalPricing(model) {
|
|
1279
|
-
|
|
2120
|
+
const models = getInTreeCapabilitiesMatrix().models;
|
|
2121
|
+
for (const m of models) {
|
|
1280
2122
|
if (isExactMatch(m, model)) return toPricing(m.pricing);
|
|
1281
2123
|
}
|
|
1282
|
-
for (const m of
|
|
2124
|
+
for (const m of models) {
|
|
1283
2125
|
if (m.pricing !== void 0 && isPrefixMatch(m, model)) return toPricing(m.pricing);
|
|
1284
2126
|
}
|
|
1285
2127
|
return void 0;
|
|
@@ -1761,7 +2603,7 @@ function formatPercentage(value, decimals = 0) {
|
|
|
1761
2603
|
|
|
1762
2604
|
// src/core/artifact.ts
|
|
1763
2605
|
import { randomUUID as randomUUID2 } from "crypto";
|
|
1764
|
-
import { z as
|
|
2606
|
+
import { z as z4 } from "zod";
|
|
1765
2607
|
var ArtifactType = {
|
|
1766
2608
|
/** Planning documents and task breakdowns */
|
|
1767
2609
|
PLAN: "plan",
|
|
@@ -1774,30 +2616,30 @@ var ArtifactType = {
|
|
|
1774
2616
|
/** Intent declarations for policy authorization */
|
|
1775
2617
|
INTENT: "intent"
|
|
1776
2618
|
};
|
|
1777
|
-
var ArtifactTypeSchema =
|
|
2619
|
+
var ArtifactTypeSchema = z4.enum([
|
|
1778
2620
|
ArtifactType.PLAN,
|
|
1779
2621
|
ArtifactType.ANALYSIS,
|
|
1780
2622
|
ArtifactType.DECISION,
|
|
1781
2623
|
ArtifactType.RESULT,
|
|
1782
2624
|
ArtifactType.INTENT
|
|
1783
2625
|
]);
|
|
1784
|
-
var ArtifactMetadataSchema =
|
|
1785
|
-
createdAt:
|
|
1786
|
-
createdBy:
|
|
1787
|
-
parentId:
|
|
1788
|
-
taskId:
|
|
1789
|
-
traceId:
|
|
2626
|
+
var ArtifactMetadataSchema = z4.object({
|
|
2627
|
+
createdAt: z4.iso.datetime({ message: "createdAt must be ISO 8601 format" }),
|
|
2628
|
+
createdBy: z4.string().min(1, "createdBy is required"),
|
|
2629
|
+
parentId: z4.uuid().optional(),
|
|
2630
|
+
taskId: z4.string().min(1, "taskId is required"),
|
|
2631
|
+
traceId: z4.string().optional()
|
|
1790
2632
|
});
|
|
1791
2633
|
function createArtifactSchema(dataSchema) {
|
|
1792
|
-
return
|
|
1793
|
-
id:
|
|
2634
|
+
return z4.object({
|
|
2635
|
+
id: z4.uuid(),
|
|
1794
2636
|
type: ArtifactTypeSchema,
|
|
1795
|
-
schemaVersion:
|
|
2637
|
+
schemaVersion: z4.string().regex(/^\d+\.\d+\.\d+$/, "schemaVersion must be semver"),
|
|
1796
2638
|
data: dataSchema,
|
|
1797
2639
|
metadata: ArtifactMetadataSchema
|
|
1798
2640
|
});
|
|
1799
2641
|
}
|
|
1800
|
-
var BaseArtifactSchema = createArtifactSchema(
|
|
2642
|
+
var BaseArtifactSchema = createArtifactSchema(z4.unknown());
|
|
1801
2643
|
|
|
1802
2644
|
// src/core/metrics.ts
|
|
1803
2645
|
var MAX_RECENT_ERRORS = 1e3;
|
|
@@ -2974,108 +3816,6 @@ function estimateTokens(text) {
|
|
|
2974
3816
|
return getTokenEstimator().estimateText(text);
|
|
2975
3817
|
}
|
|
2976
3818
|
|
|
2977
|
-
// src/config/model-config-helpers.ts
|
|
2978
|
-
function getModelContextWindow(modelId) {
|
|
2979
|
-
return getModelCapabilities(modelId)?.contextWindow ?? 8192;
|
|
2980
|
-
}
|
|
2981
|
-
function getDefaultModelForCli(cli) {
|
|
2982
|
-
return DEFAULT_MODEL_PER_CLI[cli];
|
|
2983
|
-
}
|
|
2984
|
-
function getCliModelName(modelId) {
|
|
2985
|
-
const cap = getModelCapabilities(modelId);
|
|
2986
|
-
return cap?.cliModelName ?? cap?.cliAlias ?? modelId;
|
|
2987
|
-
}
|
|
2988
|
-
function resolveCliAlias(alias) {
|
|
2989
|
-
return DEFAULT_MODEL_CAPABILITIES.models.find(
|
|
2990
|
-
(m) => m.cliAlias === alias || m.id === alias || (m.aliases?.includes(alias) ?? false)
|
|
2991
|
-
)?.id;
|
|
2992
|
-
}
|
|
2993
|
-
function buildCapabilityProfiles() {
|
|
2994
|
-
const result = {};
|
|
2995
|
-
for (const model of DEFAULT_MODEL_CAPABILITIES.models) {
|
|
2996
|
-
const q = model.qualityScores;
|
|
2997
|
-
if (q !== void 0) {
|
|
2998
|
-
result[model.id] = {
|
|
2999
|
-
reasoning: q.reasoning,
|
|
3000
|
-
contextWindow: model.contextWindow,
|
|
3001
|
-
codeGeneration: q.codeGeneration,
|
|
3002
|
-
speed: q.speed,
|
|
3003
|
-
cost: q.cost
|
|
3004
|
-
};
|
|
3005
|
-
}
|
|
3006
|
-
}
|
|
3007
|
-
return result;
|
|
3008
|
-
}
|
|
3009
|
-
function buildCliCapabilityProfiles() {
|
|
3010
|
-
const result = {};
|
|
3011
|
-
for (const [cli, modelId] of Object.entries(DEFAULT_MODEL_PER_CLI)) {
|
|
3012
|
-
const model = getModelCapabilities(modelId);
|
|
3013
|
-
const q = model?.qualityScores;
|
|
3014
|
-
if (model !== void 0 && q !== void 0) {
|
|
3015
|
-
result[cli] = {
|
|
3016
|
-
reasoning: q.reasoning,
|
|
3017
|
-
contextWindow: model.contextWindow,
|
|
3018
|
-
codeGeneration: q.codeGeneration,
|
|
3019
|
-
speed: q.speed,
|
|
3020
|
-
cost: q.cost
|
|
3021
|
-
};
|
|
3022
|
-
}
|
|
3023
|
-
}
|
|
3024
|
-
return result;
|
|
3025
|
-
}
|
|
3026
|
-
var CLI_AVG_LATENCY = {
|
|
3027
|
-
claude: 800,
|
|
3028
|
-
gemini: 400,
|
|
3029
|
-
codex: 500,
|
|
3030
|
-
opencode: 600
|
|
3031
|
-
};
|
|
3032
|
-
function buildTopsisProfiles() {
|
|
3033
|
-
const profiles = [];
|
|
3034
|
-
for (const [cli, modelId] of Object.entries(DEFAULT_MODEL_PER_CLI)) {
|
|
3035
|
-
const model = getModelCapabilities(modelId);
|
|
3036
|
-
const q = model?.qualityScores;
|
|
3037
|
-
const p = model?.pricing;
|
|
3038
|
-
if (model === void 0 || q === void 0 || p === void 0) continue;
|
|
3039
|
-
profiles.push({
|
|
3040
|
-
cliName: cli,
|
|
3041
|
-
capabilities: {
|
|
3042
|
-
reasoning: q.reasoning,
|
|
3043
|
-
contextWindow: model.contextWindow,
|
|
3044
|
-
codeGeneration: q.codeGeneration,
|
|
3045
|
-
speed: q.speed,
|
|
3046
|
-
cost: q.cost
|
|
3047
|
-
},
|
|
3048
|
-
costPerMillionInput: p.inputPer1M,
|
|
3049
|
-
costPerMillionOutput: p.outputPer1M,
|
|
3050
|
-
averageLatencyMs: CLI_AVG_LATENCY[cli],
|
|
3051
|
-
qualityScore: (q.reasoning + q.codeGeneration) / 2
|
|
3052
|
-
});
|
|
3053
|
-
}
|
|
3054
|
-
return profiles;
|
|
3055
|
-
}
|
|
3056
|
-
function findCanonicalModel(cli, cliModelName) {
|
|
3057
|
-
return DEFAULT_MODEL_CAPABILITIES.models.find(
|
|
3058
|
-
(m) => m.cliName === cli && (m.cliModelName === cliModelName || m.cliAlias === cliModelName || m.id === cliModelName || (m.aliases?.includes(cliModelName) ?? false))
|
|
3059
|
-
);
|
|
3060
|
-
}
|
|
3061
|
-
function buildModelInfo(cli, cliModelName) {
|
|
3062
|
-
const cap = findCanonicalModel(cli, cliModelName);
|
|
3063
|
-
if (cap === void 0) return void 0;
|
|
3064
|
-
const info = {
|
|
3065
|
-
id: cliModelName,
|
|
3066
|
-
name: cap.displayName,
|
|
3067
|
-
contextWindow: cap.contextWindow
|
|
3068
|
-
};
|
|
3069
|
-
if (cap.maxOutputTokens !== void 0) {
|
|
3070
|
-
info.maxOutput = cap.maxOutputTokens;
|
|
3071
|
-
}
|
|
3072
|
-
if (cap.pricing !== void 0) {
|
|
3073
|
-
info.costPerMillionInput = cap.pricing.inputPer1M;
|
|
3074
|
-
info.costPerMillionOutput = cap.pricing.outputPer1M;
|
|
3075
|
-
}
|
|
3076
|
-
return info;
|
|
3077
|
-
}
|
|
3078
|
-
|
|
3079
3819
|
// src/cli-adapters/types-capability.ts
|
|
3080
3820
|
var CLI_VERSION_REQUIREMENTS = {
|
|
3081
3821
|
claude: {
|
|
@@ -3845,19 +4585,19 @@ var TopsisRouter = class {
|
|
|
3845
4585
|
};
|
|
3846
4586
|
|
|
3847
4587
|
// src/cli-adapters/budget-router-types.ts
|
|
3848
|
-
import { z as
|
|
3849
|
-
var BudgetConstraintSchema =
|
|
3850
|
-
maxTokens:
|
|
3851
|
-
maxCostUSD:
|
|
3852
|
-
maxLatencyMs:
|
|
4588
|
+
import { z as z5 } from "zod";
|
|
4589
|
+
var BudgetConstraintSchema = z5.object({
|
|
4590
|
+
maxTokens: z5.number().int().positive().optional(),
|
|
4591
|
+
maxCostUSD: z5.number().positive().optional(),
|
|
4592
|
+
maxLatencyMs: z5.number().positive().optional()
|
|
3853
4593
|
});
|
|
3854
|
-
var SessionBudgetSchema =
|
|
3855
|
-
totalTokens:
|
|
3856
|
-
totalCostUSD:
|
|
3857
|
-
usedTokens:
|
|
3858
|
-
usedCostUSD:
|
|
3859
|
-
startTime:
|
|
3860
|
-
sessionId:
|
|
4594
|
+
var SessionBudgetSchema = z5.object({
|
|
4595
|
+
totalTokens: z5.number().int().positive(),
|
|
4596
|
+
totalCostUSD: z5.number().positive(),
|
|
4597
|
+
usedTokens: z5.number().int().min(0).default(0),
|
|
4598
|
+
usedCostUSD: z5.number().min(0).default(0),
|
|
4599
|
+
startTime: z5.number().int().positive(),
|
|
4600
|
+
sessionId: z5.string().min(1)
|
|
3861
4601
|
});
|
|
3862
4602
|
var DEFAULT_LINUCB_CONFIG = {
|
|
3863
4603
|
numArms: 4,
|
|
@@ -3865,11 +4605,11 @@ var DEFAULT_LINUCB_CONFIG = {
|
|
|
3865
4605
|
alpha: 1,
|
|
3866
4606
|
lambda: 1
|
|
3867
4607
|
};
|
|
3868
|
-
var LinUCBConfigSchema =
|
|
3869
|
-
numArms:
|
|
3870
|
-
featureDim:
|
|
3871
|
-
alpha:
|
|
3872
|
-
lambda:
|
|
4608
|
+
var LinUCBConfigSchema = z5.object({
|
|
4609
|
+
numArms: z5.number().int().positive().default(4),
|
|
4610
|
+
featureDim: z5.number().int().positive().default(6),
|
|
4611
|
+
alpha: z5.number().positive().default(1),
|
|
4612
|
+
lambda: z5.number().positive().default(1)
|
|
3873
4613
|
});
|
|
3874
4614
|
|
|
3875
4615
|
// src/cli-adapters/linucb-math.ts
|
|
@@ -4224,7 +4964,7 @@ var LinUCBBandit = class {
|
|
|
4224
4964
|
import { randomUUID as randomUUID3 } from "crypto";
|
|
4225
4965
|
|
|
4226
4966
|
// src/cli-adapters/preference-router-types.ts
|
|
4227
|
-
import { z as
|
|
4967
|
+
import { z as z6 } from "zod";
|
|
4228
4968
|
var DEFAULT_PREFERENCE_ROUTER_CONFIG = {
|
|
4229
4969
|
strongModel: {
|
|
4230
4970
|
tier: "strong",
|
|
@@ -4245,24 +4985,24 @@ var DEFAULT_PREFERENCE_ROUTER_CONFIG = {
|
|
|
4245
4985
|
maxDataPoints: 1e4,
|
|
4246
4986
|
enableOnlineLearning: true
|
|
4247
4987
|
};
|
|
4248
|
-
var PreferenceRouterConfigSchema =
|
|
4249
|
-
strongModel:
|
|
4250
|
-
tier:
|
|
4251
|
-
cli:
|
|
4252
|
-
costPerMillionTokens:
|
|
4253
|
-
qualityBaseline:
|
|
4988
|
+
var PreferenceRouterConfigSchema = z6.object({
|
|
4989
|
+
strongModel: z6.object({
|
|
4990
|
+
tier: z6.literal("strong"),
|
|
4991
|
+
cli: z6.enum(["claude", "gemini", "codex", "opencode"]),
|
|
4992
|
+
costPerMillionTokens: z6.number().positive(),
|
|
4993
|
+
qualityBaseline: z6.number().min(0).max(1)
|
|
4254
4994
|
}),
|
|
4255
|
-
weakModel:
|
|
4256
|
-
tier:
|
|
4257
|
-
cli:
|
|
4258
|
-
costPerMillionTokens:
|
|
4259
|
-
qualityBaseline:
|
|
4995
|
+
weakModel: z6.object({
|
|
4996
|
+
tier: z6.literal("weak"),
|
|
4997
|
+
cli: z6.enum(["claude", "gemini", "codex", "opencode"]),
|
|
4998
|
+
costPerMillionTokens: z6.number().positive(),
|
|
4999
|
+
qualityBaseline: z6.number().min(0).max(1)
|
|
4260
5000
|
}),
|
|
4261
|
-
routingThreshold:
|
|
4262
|
-
minDataPoints:
|
|
4263
|
-
maxDataPoints:
|
|
4264
|
-
enableOnlineLearning:
|
|
4265
|
-
domainThresholds:
|
|
5001
|
+
routingThreshold: z6.number().min(0).max(1).default(0.5),
|
|
5002
|
+
minDataPoints: z6.number().int().positive().default(10),
|
|
5003
|
+
maxDataPoints: z6.number().int().positive().default(1e4),
|
|
5004
|
+
enableOnlineLearning: z6.boolean().default(true),
|
|
5005
|
+
domainThresholds: z6.record(z6.string(), z6.number().min(0).max(1)).optional()
|
|
4266
5006
|
});
|
|
4267
5007
|
|
|
4268
5008
|
// src/cli-adapters/preference-router-store.ts
|
|
@@ -4604,8 +5344,8 @@ function createPreferenceRouter(config, dataStore) {
|
|
|
4604
5344
|
}
|
|
4605
5345
|
|
|
4606
5346
|
// src/cli-adapters/zero-router-types.ts
|
|
4607
|
-
import { z as
|
|
4608
|
-
var DifficultyDimensionSchema =
|
|
5347
|
+
import { z as z7 } from "zod";
|
|
5348
|
+
var DifficultyDimensionSchema = z7.enum([
|
|
4609
5349
|
"reasoning",
|
|
4610
5350
|
"knowledge",
|
|
4611
5351
|
"creativity",
|
|
@@ -4619,17 +5359,17 @@ var DIFFICULTY_DIMENSIONS = [
|
|
|
4619
5359
|
"precision",
|
|
4620
5360
|
"context_length"
|
|
4621
5361
|
];
|
|
4622
|
-
var DifficultySpaceSchema =
|
|
5362
|
+
var DifficultySpaceSchema = z7.object({
|
|
4623
5363
|
/** Reasoning difficulty: logical complexity, multi-step inference (0-1) */
|
|
4624
|
-
reasoning:
|
|
5364
|
+
reasoning: z7.number().min(0).max(1),
|
|
4625
5365
|
/** Knowledge difficulty: domain expertise required (0-1) */
|
|
4626
|
-
knowledge:
|
|
5366
|
+
knowledge: z7.number().min(0).max(1),
|
|
4627
5367
|
/** Creativity difficulty: novel generation, open-endedness (0-1) */
|
|
4628
|
-
creativity:
|
|
5368
|
+
creativity: z7.number().min(0).max(1),
|
|
4629
5369
|
/** Precision difficulty: accuracy requirements, error tolerance (0-1) */
|
|
4630
|
-
precision:
|
|
5370
|
+
precision: z7.number().min(0).max(1),
|
|
4631
5371
|
/** Context length difficulty: amount of context to process (0-1) */
|
|
4632
|
-
context_length:
|
|
5372
|
+
context_length: z7.number().min(0).max(1)
|
|
4633
5373
|
});
|
|
4634
5374
|
var DEFAULT_DIFFICULTY_THRESHOLDS = {
|
|
4635
5375
|
easyUpperBound: 0.3,
|
|
@@ -4645,12 +5385,12 @@ var DEFAULT_TIER_TO_CLIS = {
|
|
|
4645
5385
|
balanced: ["codex", "opencode", "gemini", "claude"],
|
|
4646
5386
|
powerful: ["claude", "codex", "opencode", "gemini"]
|
|
4647
5387
|
};
|
|
4648
|
-
var DifficultyWeightsSchema =
|
|
4649
|
-
reasoning:
|
|
4650
|
-
knowledge:
|
|
4651
|
-
creativity:
|
|
4652
|
-
precision:
|
|
4653
|
-
context_length:
|
|
5388
|
+
var DifficultyWeightsSchema = z7.object({
|
|
5389
|
+
reasoning: z7.number().min(0).max(1),
|
|
5390
|
+
knowledge: z7.number().min(0).max(1),
|
|
5391
|
+
creativity: z7.number().min(0).max(1),
|
|
5392
|
+
precision: z7.number().min(0).max(1),
|
|
5393
|
+
context_length: z7.number().min(0).max(1)
|
|
4654
5394
|
});
|
|
4655
5395
|
var DEFAULT_DIFFICULTY_WEIGHTS = {
|
|
4656
5396
|
reasoning: 0.3,
|
|
@@ -4659,29 +5399,29 @@ var DEFAULT_DIFFICULTY_WEIGHTS = {
|
|
|
4659
5399
|
precision: 0.25,
|
|
4660
5400
|
context_length: 0.15
|
|
4661
5401
|
};
|
|
4662
|
-
var ZeroRouterConfigSchema =
|
|
5402
|
+
var ZeroRouterConfigSchema = z7.object({
|
|
4663
5403
|
/** Difficulty thresholds for level classification */
|
|
4664
|
-
thresholds:
|
|
4665
|
-
easyUpperBound:
|
|
4666
|
-
hardLowerBound:
|
|
5404
|
+
thresholds: z7.object({
|
|
5405
|
+
easyUpperBound: z7.number().min(0).max(1),
|
|
5406
|
+
hardLowerBound: z7.number().min(0).max(1)
|
|
4667
5407
|
}).default(DEFAULT_DIFFICULTY_THRESHOLDS),
|
|
4668
5408
|
/** Weights for difficulty aggregation */
|
|
4669
5409
|
weights: DifficultyWeightsSchema.default(DEFAULT_DIFFICULTY_WEIGHTS),
|
|
4670
5410
|
/** Mapping from difficulty level to model tier */
|
|
4671
|
-
difficultyToTier:
|
|
5411
|
+
difficultyToTier: z7.record(z7.enum(["easy", "medium", "hard"]), z7.enum(["fast", "balanced", "powerful"])).default(DEFAULT_DIFFICULTY_TO_TIER),
|
|
4672
5412
|
/** Mapping from model tier to CLI preference order */
|
|
4673
|
-
tierToClis:
|
|
4674
|
-
|
|
4675
|
-
|
|
5413
|
+
tierToClis: z7.record(
|
|
5414
|
+
z7.enum(["fast", "balanced", "powerful"]),
|
|
5415
|
+
z7.array(z7.enum(["claude", "gemini", "codex", "opencode"]))
|
|
4676
5416
|
).default(DEFAULT_TIER_TO_CLIS),
|
|
4677
5417
|
/** Enable adaptive calibration from outcomes */
|
|
4678
|
-
enableCalibration:
|
|
5418
|
+
enableCalibration: z7.boolean().default(true),
|
|
4679
5419
|
/** Maximum outcomes to store for calibration */
|
|
4680
|
-
maxCalibrationOutcomes:
|
|
5420
|
+
maxCalibrationOutcomes: z7.number().int().positive().default(1e3),
|
|
4681
5421
|
/** Minimum outcomes before applying calibration adjustments */
|
|
4682
|
-
minCalibrationOutcomes:
|
|
5422
|
+
minCalibrationOutcomes: z7.number().int().positive().default(50),
|
|
4683
5423
|
/** Verbose logging */
|
|
4684
|
-
verbose:
|
|
5424
|
+
verbose: z7.boolean().default(false)
|
|
4685
5425
|
});
|
|
4686
5426
|
var DEFAULT_ZERO_ROUTER_CONFIG = {
|
|
4687
5427
|
thresholds: DEFAULT_DIFFICULTY_THRESHOLDS,
|
|
@@ -5205,16 +5945,16 @@ var ZeroRouter = class {
|
|
|
5205
5945
|
};
|
|
5206
5946
|
|
|
5207
5947
|
// src/cli-adapters/latency-tracker-types.ts
|
|
5208
|
-
import { z as
|
|
5209
|
-
var LatencyTrackerConfigSchema =
|
|
5948
|
+
import { z as z8 } from "zod";
|
|
5949
|
+
var LatencyTrackerConfigSchema = z8.object({
|
|
5210
5950
|
/** Maximum number of samples to keep per CLI (default: 100) */
|
|
5211
|
-
windowSize:
|
|
5951
|
+
windowSize: z8.number().int().positive().default(100),
|
|
5212
5952
|
/** Time-weighted decay factor (0-1, higher = more weight to recent) (default: 0.95) */
|
|
5213
|
-
decayFactor:
|
|
5953
|
+
decayFactor: z8.number().min(0).max(1).default(0.95),
|
|
5214
5954
|
/** Maximum age of samples in milliseconds before forced eviction (default: 3600000 = 1 hour) */
|
|
5215
|
-
maxSampleAgeMs:
|
|
5955
|
+
maxSampleAgeMs: z8.number().int().positive().default(36e5),
|
|
5216
5956
|
/** Percentiles to calculate (default: [50, 95, 99]) */
|
|
5217
|
-
percentiles:
|
|
5957
|
+
percentiles: z8.array(z8.number().min(0).max(100)).default([50, 95, 99])
|
|
5218
5958
|
});
|
|
5219
5959
|
var EMPTY_LATENCY_STATS = {
|
|
5220
5960
|
count: 0,
|
|
@@ -5621,19 +6361,19 @@ function createRoutingMemory(config, mobimem) {
|
|
|
5621
6361
|
}
|
|
5622
6362
|
|
|
5623
6363
|
// src/cli-adapters/routing/router-stage.ts
|
|
5624
|
-
import { z as
|
|
5625
|
-
var StageConfigSchema =
|
|
5626
|
-
enabled:
|
|
5627
|
-
priority:
|
|
5628
|
-
options:
|
|
6364
|
+
import { z as z9 } from "zod";
|
|
6365
|
+
var StageConfigSchema = z9.object({
|
|
6366
|
+
enabled: z9.boolean().default(true),
|
|
6367
|
+
priority: z9.number().int().min(0).max(100).default(50),
|
|
6368
|
+
options: z9.record(z9.string(), z9.unknown()).optional()
|
|
5629
6369
|
});
|
|
5630
|
-
var RoutingOutcomeSchema =
|
|
6370
|
+
var RoutingOutcomeSchema = z9.object({
|
|
5631
6371
|
selectedCli: CliNameSchema,
|
|
5632
|
-
task:
|
|
5633
|
-
success:
|
|
5634
|
-
qualityScore:
|
|
5635
|
-
latencyMs:
|
|
5636
|
-
tokensUsed:
|
|
6372
|
+
task: z9.string(),
|
|
6373
|
+
success: z9.boolean(),
|
|
6374
|
+
qualityScore: z9.number().min(0).max(1).optional(),
|
|
6375
|
+
latencyMs: z9.number().int().positive().optional(),
|
|
6376
|
+
tokensUsed: z9.number().int().positive().optional()
|
|
5637
6377
|
});
|
|
5638
6378
|
function createRoutingContext(task, availableClis = ["claude", "gemini", "codex", "opencode"], metadata) {
|
|
5639
6379
|
return {
|
|
@@ -5830,7 +6570,7 @@ var ConfidenceCascadeStage = class {
|
|
|
5830
6570
|
};
|
|
5831
6571
|
|
|
5832
6572
|
// src/config/task-specialization-types.ts
|
|
5833
|
-
import { z as
|
|
6573
|
+
import { z as z10 } from "zod";
|
|
5834
6574
|
var TASK_CATEGORIES = [
|
|
5835
6575
|
"architecture",
|
|
5836
6576
|
"code_generation",
|
|
@@ -5843,8 +6583,8 @@ var TASK_CATEGORIES = [
|
|
|
5843
6583
|
"devops",
|
|
5844
6584
|
"exploration"
|
|
5845
6585
|
];
|
|
5846
|
-
var TaskCategorySchema =
|
|
5847
|
-
var TaskSpecializationSchema =
|
|
6586
|
+
var TaskCategorySchema = z10.enum(TASK_CATEGORIES);
|
|
6587
|
+
var TaskSpecializationSchema = z10.object({
|
|
5848
6588
|
/** Task category identifier */
|
|
5849
6589
|
category: TaskCategorySchema,
|
|
5850
6590
|
/** Primary CLI recommendation */
|
|
@@ -5852,11 +6592,11 @@ var TaskSpecializationSchema = z9.object({
|
|
|
5852
6592
|
/** Secondary CLI fallback */
|
|
5853
6593
|
secondaryCli: CliNameSchema,
|
|
5854
6594
|
/** Why this CLI is preferred for this task type */
|
|
5855
|
-
reasoning:
|
|
6595
|
+
reasoning: z10.string(),
|
|
5856
6596
|
/** Keywords that trigger this category detection */
|
|
5857
|
-
keywords:
|
|
6597
|
+
keywords: z10.array(z10.string()).min(1),
|
|
5858
6598
|
/** Bonus score applied when this category matches (0-20) */
|
|
5859
|
-
bonus:
|
|
6599
|
+
bonus: z10.number().min(0).max(20)
|
|
5860
6600
|
});
|
|
5861
6601
|
|
|
5862
6602
|
// src/config/task-specialization.ts
|
|
@@ -7079,10 +7819,10 @@ function createPersistentDistillerOrFallback(outcomeStore, logger11) {
|
|
|
7079
7819
|
}
|
|
7080
7820
|
|
|
7081
7821
|
// src/orchestration/outcomes/outcome-types.ts
|
|
7082
|
-
import { z as
|
|
7822
|
+
import { z as z11 } from "zod";
|
|
7083
7823
|
var logger6 = createLogger({ component: "outcome-error-taxonomy" });
|
|
7084
|
-
var OutcomeSourceSchema =
|
|
7085
|
-
var OutcomeFailureCategorySchema =
|
|
7824
|
+
var OutcomeSourceSchema = z11.enum(["delegate", "consensus", "manual"]);
|
|
7825
|
+
var OutcomeFailureCategorySchema = z11.enum([
|
|
7086
7826
|
"timeout",
|
|
7087
7827
|
"authentication",
|
|
7088
7828
|
"rate_limit",
|
|
@@ -7095,37 +7835,41 @@ var OutcomeFailureCategorySchema = z10.enum([
|
|
|
7095
7835
|
"generic",
|
|
7096
7836
|
"unknown"
|
|
7097
7837
|
]);
|
|
7098
|
-
var TaskOutcomeSchema =
|
|
7099
|
-
id:
|
|
7838
|
+
var TaskOutcomeSchema = z11.object({
|
|
7839
|
+
id: z11.string().min(1),
|
|
7100
7840
|
cli: CliNameSchema,
|
|
7101
7841
|
category: TaskCategorySchema,
|
|
7102
|
-
model:
|
|
7103
|
-
success:
|
|
7104
|
-
durationMs:
|
|
7105
|
-
timestamp:
|
|
7106
|
-
qualitySignals:
|
|
7842
|
+
model: z11.string().min(1),
|
|
7843
|
+
success: z11.boolean(),
|
|
7844
|
+
durationMs: z11.number().nonnegative(),
|
|
7845
|
+
timestamp: z11.string().min(1),
|
|
7846
|
+
qualitySignals: z11.array(z11.string()).optional(),
|
|
7107
7847
|
failureCategory: OutcomeFailureCategorySchema.optional(),
|
|
7108
|
-
errorMessage:
|
|
7848
|
+
errorMessage: z11.string().max(500).optional(),
|
|
7109
7849
|
source: OutcomeSourceSchema,
|
|
7110
7850
|
/** Whether this outcome came from a triage-initiated retry (#1506). */
|
|
7111
|
-
wasRetried:
|
|
7851
|
+
wasRetried: z11.boolean().optional(),
|
|
7112
7852
|
/** Triage action taken on the failure (#1506). */
|
|
7113
|
-
triageAction:
|
|
7853
|
+
triageAction: z11.string().max(30).optional(),
|
|
7114
7854
|
/** Routing stage that selected this CLI (#1785). */
|
|
7115
|
-
routingStage:
|
|
7855
|
+
routingStage: z11.string().max(50).optional(),
|
|
7116
7856
|
/** Number of retry attempts before this outcome (#1785). */
|
|
7117
|
-
retryCount:
|
|
7857
|
+
retryCount: z11.number().int().nonnegative().optional(),
|
|
7858
|
+
/** Vendor resolved from `model` via ModelRegistry at write time (#2548). */
|
|
7859
|
+
vendor: z11.string().min(1).max(40).optional(),
|
|
7860
|
+
/** Family resolved from `model` via ModelRegistry at write time (#2548). */
|
|
7861
|
+
family: z11.string().min(1).max(80).optional()
|
|
7118
7862
|
});
|
|
7119
|
-
var OutcomeQuerySchema =
|
|
7863
|
+
var OutcomeQuerySchema = z11.object({
|
|
7120
7864
|
cli: CliNameSchema.optional(),
|
|
7121
7865
|
category: TaskCategorySchema.optional(),
|
|
7122
7866
|
source: OutcomeSourceSchema.optional(),
|
|
7123
|
-
success:
|
|
7867
|
+
success: z11.boolean().optional(),
|
|
7124
7868
|
failureCategory: OutcomeFailureCategorySchema.optional(),
|
|
7125
|
-
since:
|
|
7126
|
-
limit:
|
|
7869
|
+
since: z11.string().optional(),
|
|
7870
|
+
limit: z11.number().int().positive().optional(),
|
|
7127
7871
|
/** Exclude outcomes with any of these quality signals (#1680). */
|
|
7128
|
-
excludeQualitySignals:
|
|
7872
|
+
excludeQualitySignals: z11.array(z11.string()).optional()
|
|
7129
7873
|
});
|
|
7130
7874
|
var TIMEOUT_PATTERNS = ["timeout", "timed out", "deadline exceeded", "socket hang up", "aborted"];
|
|
7131
7875
|
var AUTH_PATTERNS = [
|
|
@@ -7320,6 +8064,7 @@ function categorizeOutcomeErrorMessage(msg) {
|
|
|
7320
8064
|
|
|
7321
8065
|
// src/orchestration/outcomes/outcome-store.ts
|
|
7322
8066
|
var DEFAULT_MAX_ENTRIES = 1e4;
|
|
8067
|
+
var DEFAULT_FAMILY_FALLBACK_THRESHOLD = 5;
|
|
7323
8068
|
function autoClassify(outcome) {
|
|
7324
8069
|
if (outcome.success || outcome.failureCategory !== void 0) return outcome;
|
|
7325
8070
|
if (typeof outcome.errorMessage === "string" && outcome.errorMessage.length > 0) {
|
|
@@ -7333,20 +8078,73 @@ function hasErrorMessage(o) {
|
|
|
7333
8078
|
var OutcomeStore = class {
|
|
7334
8079
|
entries = [];
|
|
7335
8080
|
maxEntries;
|
|
8081
|
+
registry;
|
|
7336
8082
|
constructor(config) {
|
|
7337
8083
|
this.maxEntries = config?.maxEntries ?? DEFAULT_MAX_ENTRIES;
|
|
8084
|
+
this.registry = config?.registry ?? getDefaultRegistry();
|
|
7338
8085
|
}
|
|
7339
|
-
/**
|
|
8086
|
+
/**
|
|
8087
|
+
* Append a new outcome. Auto-classifies failures missing failureCategory
|
|
8088
|
+
* (#1441) and resolves the outcome's `vendor` / `family` via the
|
|
8089
|
+
* ModelRegistry (#2548) so family-level retrieval can warm-start
|
|
8090
|
+
* siblings after a model retirement.
|
|
8091
|
+
*/
|
|
7340
8092
|
append(outcome) {
|
|
7341
|
-
this.entries.push(autoClassify(outcome));
|
|
8093
|
+
this.entries.push(this.enrich(autoClassify(outcome)));
|
|
7342
8094
|
this.enforceLimit();
|
|
7343
8095
|
}
|
|
8096
|
+
/**
|
|
8097
|
+
* Attach `vendor` and `family` to the outcome if they're not already
|
|
8098
|
+
* set. Idempotent — pre-enriched outcomes pass through unchanged.
|
|
8099
|
+
*/
|
|
8100
|
+
enrich(outcome) {
|
|
8101
|
+
if (outcome.vendor !== void 0 && outcome.family !== void 0) return outcome;
|
|
8102
|
+
const entry = this.registry.getEntry(outcome.model);
|
|
8103
|
+
return {
|
|
8104
|
+
...outcome,
|
|
8105
|
+
vendor: outcome.vendor ?? entry.vendor,
|
|
8106
|
+
family: outcome.family ?? entry.family
|
|
8107
|
+
};
|
|
8108
|
+
}
|
|
7344
8109
|
/** Query outcomes with optional filters. */
|
|
7345
8110
|
query(filter) {
|
|
7346
8111
|
if (filter === void 0) return [...this.entries];
|
|
7347
8112
|
const filtered = applyFilters(this.entries, filter);
|
|
7348
8113
|
return filter.limit !== void 0 ? filtered.slice(-filter.limit) : filtered;
|
|
7349
8114
|
}
|
|
8115
|
+
/**
|
|
8116
|
+
* Query outcomes for a specific model with a family-level warm-start
|
|
8117
|
+
* fallback (#2548). When the literal `modelId` has fewer than
|
|
8118
|
+
* `threshold` samples in the store, broaden the result to the model's
|
|
8119
|
+
* `{vendor, family}` siblings — siblings within a family share enough
|
|
8120
|
+
* behavior profile that their outcomes are useful priors for cold
|
|
8121
|
+
* starts after a retirement.
|
|
8122
|
+
*
|
|
8123
|
+
* Returns the outcomes and a `scope` flag so callers know whether
|
|
8124
|
+
* they're consuming literal-id data or family-broadened data.
|
|
8125
|
+
*/
|
|
8126
|
+
queryByModelWithFamilyFallback(modelId, options) {
|
|
8127
|
+
const threshold = options?.threshold ?? DEFAULT_FAMILY_FALLBACK_THRESHOLD;
|
|
8128
|
+
const base = options?.extraFilter ?? {};
|
|
8129
|
+
const literal = applyFilters(this.entries, base).filter((o) => o.model === modelId);
|
|
8130
|
+
if (literal.length >= threshold) {
|
|
8131
|
+
const entry2 = this.registry.getEntry(modelId);
|
|
8132
|
+
return { outcomes: literal, scope: "literal", vendor: entry2.vendor, family: entry2.family };
|
|
8133
|
+
}
|
|
8134
|
+
const entry = this.registry.getEntry(modelId);
|
|
8135
|
+
const family = applyFilters(this.entries, base).filter(
|
|
8136
|
+
(o) => (
|
|
8137
|
+
// Cross-vendor transfer is out of scope (#2548) — vendor must match.
|
|
8138
|
+
// Family must match too: an Anthropic claude-opus outcome shouldn't
|
|
8139
|
+
// warm-start an Anthropic claude-haiku query.
|
|
8140
|
+
o.vendor === entry.vendor && o.family === entry.family
|
|
8141
|
+
)
|
|
8142
|
+
);
|
|
8143
|
+
if (family.length === 0) {
|
|
8144
|
+
return { outcomes: literal, scope: "empty", vendor: entry.vendor, family: entry.family };
|
|
8145
|
+
}
|
|
8146
|
+
return { outcomes: family, scope: "family", vendor: entry.vendor, family: entry.family };
|
|
8147
|
+
}
|
|
7350
8148
|
/** Aggregate outcomes into a performance summary. */
|
|
7351
8149
|
summarize(filter) {
|
|
7352
8150
|
const outcomes = this.query(filter);
|
|
@@ -7690,52 +8488,52 @@ function runWarmUp(logger11) {
|
|
|
7690
8488
|
}
|
|
7691
8489
|
|
|
7692
8490
|
// src/cli-adapters/composite-router-types.ts
|
|
7693
|
-
import { z as
|
|
7694
|
-
var CompositeRouterConfigSchema =
|
|
8491
|
+
import { z as z12 } from "zod";
|
|
8492
|
+
var CompositeRouterConfigSchema = z12.object({
|
|
7695
8493
|
/** Enable confidence cascade stage (default: false) (Issue #755, ADR-0005) */
|
|
7696
|
-
enableConfidenceCascade:
|
|
8494
|
+
enableConfidenceCascade: z12.boolean().default(false),
|
|
7697
8495
|
/** Enable budget filtering stage (default: true) */
|
|
7698
|
-
enableBudgetFilter:
|
|
8496
|
+
enableBudgetFilter: z12.boolean().default(true),
|
|
7699
8497
|
/** Enable capability match stage (default: false) (Issue #755, ADR-0005) */
|
|
7700
|
-
enableCapabilityMatch:
|
|
8498
|
+
enableCapabilityMatch: z12.boolean().default(false),
|
|
7701
8499
|
/** Enable ZeroRouter difficulty-based routing stage (default: true) (Issue #473) */
|
|
7702
|
-
enableZeroRouter:
|
|
8500
|
+
enableZeroRouter: z12.boolean().default(true),
|
|
7703
8501
|
/** Enable preference-trained routing stage (default: false) */
|
|
7704
|
-
enablePreferenceRouting:
|
|
8502
|
+
enablePreferenceRouting: z12.boolean().default(false),
|
|
7705
8503
|
/** Enable TOPSIS ranking stage (default: true) */
|
|
7706
|
-
enableTopsisRanking:
|
|
8504
|
+
enableTopsisRanking: z12.boolean().default(true),
|
|
7707
8505
|
/** Enable LinUCB selection stage (default: true) */
|
|
7708
|
-
enableLinUCBSelection:
|
|
8506
|
+
enableLinUCBSelection: z12.boolean().default(true),
|
|
7709
8507
|
/** Enable quality constraint stage (default: false) (Issue #755, ADR-0005) */
|
|
7710
|
-
enableQualityConstraint:
|
|
8508
|
+
enableQualityConstraint: z12.boolean().default(false),
|
|
7711
8509
|
/** Enable resource strategy stage for budget-aware oscillation (default: true) (Issue #998) */
|
|
7712
|
-
enableResourceStrategy:
|
|
8510
|
+
enableResourceStrategy: z12.boolean().default(true),
|
|
7713
8511
|
/** Enable strategy distillation for learned routing rules (default: false) (Issue #999) */
|
|
7714
|
-
enableStrategyDistillation:
|
|
8512
|
+
enableStrategyDistillation: z12.boolean().default(false),
|
|
7715
8513
|
/** Enable latency tracking for routing decisions (default: true) (Issue #361) */
|
|
7716
|
-
enableLatencyTracking:
|
|
8514
|
+
enableLatencyTracking: z12.boolean().default(true),
|
|
7717
8515
|
/** Enable routing memory for learned routing (default: false) (Issue #463, #461) */
|
|
7718
|
-
enableRoutingMemory:
|
|
8516
|
+
enableRoutingMemory: z12.boolean().default(false),
|
|
7719
8517
|
/** Enable KNN experience-based routing (default: false) (arXiv:2507.05370) */
|
|
7720
|
-
enableKnnRouting:
|
|
8518
|
+
enableKnnRouting: z12.boolean().default(false),
|
|
7721
8519
|
/** Weight for latency score in final routing (0-1, default: 0.2) */
|
|
7722
|
-
latencyScoreWeight:
|
|
8520
|
+
latencyScoreWeight: z12.number().min(0).max(1).default(0.2),
|
|
7723
8521
|
/** Budget constraints (optional) */
|
|
7724
|
-
budgetConstraints:
|
|
7725
|
-
maxTokens:
|
|
7726
|
-
maxCostUsd:
|
|
7727
|
-
maxLatencyMs:
|
|
8522
|
+
budgetConstraints: z12.object({
|
|
8523
|
+
maxTokens: z12.number().positive(),
|
|
8524
|
+
maxCostUsd: z12.number().positive(),
|
|
8525
|
+
maxLatencyMs: z12.number().positive()
|
|
7728
8526
|
}).partial().optional(),
|
|
7729
8527
|
/** LinUCB exploration parameter (default: 1.0) */
|
|
7730
|
-
linucbAlpha:
|
|
8528
|
+
linucbAlpha: z12.number().positive().default(1),
|
|
7731
8529
|
/** Billing mode: 'plan' zeroes cost weight, 'api' preserves current behavior (default: 'plan') */
|
|
7732
|
-
billingMode:
|
|
8530
|
+
billingMode: z12.enum(["plan", "api"]).default("plan"),
|
|
7733
8531
|
/** Enable capacity-aware load balancing (deprioritize exhausted CLIs) (default: true) (Issue #807) */
|
|
7734
|
-
enableCapacityBalancing:
|
|
8532
|
+
enableCapacityBalancing: z12.boolean().default(true),
|
|
7735
8533
|
/** Maximum routing decision time in ms (default: 50) */
|
|
7736
|
-
maxDecisionTimeMs:
|
|
8534
|
+
maxDecisionTimeMs: z12.number().positive().default(50),
|
|
7737
8535
|
/** Minimum preference data points before using learned routing (default: 10) */
|
|
7738
|
-
preferenceMinDataPoints:
|
|
8536
|
+
preferenceMinDataPoints: z12.number().int().positive().default(10)
|
|
7739
8537
|
});
|
|
7740
8538
|
var DEFAULT_COMPOSITE_CONFIG = {
|
|
7741
8539
|
enableConfidenceCascade: false,
|
|
@@ -8019,12 +8817,12 @@ async function fetchCapacityData(adapters) {
|
|
|
8019
8817
|
}
|
|
8020
8818
|
|
|
8021
8819
|
// src/mcp/tools/weather-report-types.ts
|
|
8022
|
-
import { z as
|
|
8023
|
-
var WeatherReportInputSchema =
|
|
8820
|
+
import { z as z13 } from "zod";
|
|
8821
|
+
var WeatherReportInputSchema = z13.object({
|
|
8024
8822
|
/** Filter by CLI name. */
|
|
8025
|
-
cli:
|
|
8823
|
+
cli: z13.enum(CLI_NAMES).optional().describe("Filter by CLI"),
|
|
8026
8824
|
/** Filter by task category. */
|
|
8027
|
-
category:
|
|
8825
|
+
category: z13.enum([
|
|
8028
8826
|
"architecture",
|
|
8029
8827
|
"code_generation",
|
|
8030
8828
|
"code_review",
|
|
@@ -8037,22 +8835,22 @@ var WeatherReportInputSchema = z12.object({
|
|
|
8037
8835
|
"exploration"
|
|
8038
8836
|
]).optional().describe("Filter by task category"),
|
|
8039
8837
|
/** Include adaptive routing bonus data. */
|
|
8040
|
-
includeAdaptive:
|
|
8838
|
+
includeAdaptive: z13.boolean().optional().default(true).describe("Include adaptive routing bonuses (default: true)")
|
|
8041
8839
|
});
|
|
8042
8840
|
var DEFAULT_OUTCOME_LOOKBACK_MS = 7 * 24 * 60 * 60 * 1e3;
|
|
8043
|
-
var WeatherReportConfigSchema =
|
|
8841
|
+
var WeatherReportConfigSchema = z13.object({
|
|
8044
8842
|
/** Minimum observations before adjusting bonuses (lowered for faster activation). */
|
|
8045
|
-
coldStartThreshold:
|
|
8843
|
+
coldStartThreshold: z13.number().int().min(1).max(1e3).default(3),
|
|
8046
8844
|
/** Exploration rate: fraction of random routing (0.0-1.0). */
|
|
8047
|
-
explorationRate:
|
|
8845
|
+
explorationRate: z13.number().min(0).max(1).default(0.1),
|
|
8048
8846
|
/** Max adaptive bonus adjustment (+/-). */
|
|
8049
|
-
maxBonusAdjustment:
|
|
8847
|
+
maxBonusAdjustment: z13.number().min(0).max(20).default(10),
|
|
8050
8848
|
/**
|
|
8051
8849
|
* Lookback window for outcome queries (ms). Only outcomes within this
|
|
8052
8850
|
* window are used for adaptive bonuses. Falls back to all history if
|
|
8053
8851
|
* the window has fewer samples than coldStartThreshold. Default: 7 days.
|
|
8054
8852
|
*/
|
|
8055
|
-
outcomeLookbackMs:
|
|
8853
|
+
outcomeLookbackMs: z13.number().int().min(0).default(DEFAULT_OUTCOME_LOOKBACK_MS)
|
|
8056
8854
|
});
|
|
8057
8855
|
function createDefaultWeatherConfig() {
|
|
8058
8856
|
return WeatherReportConfigSchema.parse({});
|
|
@@ -8437,47 +9235,47 @@ function createMetricsMiddleware() {
|
|
|
8437
9235
|
import { randomBytes as randomBytes3 } from "crypto";
|
|
8438
9236
|
|
|
8439
9237
|
// src/config/defaults-types.ts
|
|
8440
|
-
import { z as
|
|
9238
|
+
import { z as z14 } from "zod";
|
|
8441
9239
|
function isKnownCliName(cli) {
|
|
8442
9240
|
return cli === "claude" || cli === "gemini" || cli === "codex" || cli === "opencode" || cli === "default";
|
|
8443
9241
|
}
|
|
8444
|
-
var positiveInt =
|
|
8445
|
-
var nonNegativeInt =
|
|
8446
|
-
var durationMs =
|
|
8447
|
-
var TimeoutProfileSchema =
|
|
9242
|
+
var positiveInt = z14.number().int().positive();
|
|
9243
|
+
var nonNegativeInt = z14.number().int().nonnegative();
|
|
9244
|
+
var durationMs = z14.number().int().positive().describe("Duration in milliseconds");
|
|
9245
|
+
var TimeoutProfileSchema = z14.object({
|
|
8448
9246
|
simple: durationMs.describe("Timeout for simple tasks"),
|
|
8449
9247
|
standard: durationMs.describe("Timeout for standard tasks"),
|
|
8450
9248
|
complex: durationMs.describe("Timeout for complex tasks")
|
|
8451
9249
|
});
|
|
8452
|
-
var RetryDefaultsSchema =
|
|
9250
|
+
var RetryDefaultsSchema = z14.object({
|
|
8453
9251
|
maxRetries: nonNegativeInt.max(10).describe("Maximum retry attempts"),
|
|
8454
9252
|
baseDelayMs: durationMs.describe("Base delay between retries"),
|
|
8455
9253
|
maxDelayMs: durationMs.describe("Maximum delay between retries"),
|
|
8456
|
-
jitterFactor:
|
|
9254
|
+
jitterFactor: z14.number().min(0).max(1).describe("Jitter factor (0-1)")
|
|
8457
9255
|
});
|
|
8458
|
-
var RateLimitDefaultsSchema =
|
|
9256
|
+
var RateLimitDefaultsSchema = z14.object({
|
|
8459
9257
|
requestsPerMinute: positiveInt.max(1e3).describe("Max requests per minute"),
|
|
8460
|
-
enabled:
|
|
9258
|
+
enabled: z14.boolean().describe("Whether rate limiting is enabled"),
|
|
8461
9259
|
maxConcurrent: positiveInt.max(100).describe("Max concurrent requests"),
|
|
8462
9260
|
capacity: positiveInt.describe("Token bucket capacity"),
|
|
8463
9261
|
refillRate: positiveInt.describe("Token refill rate"),
|
|
8464
9262
|
refillIntervalMs: durationMs.describe("Token refill interval")
|
|
8465
9263
|
});
|
|
8466
|
-
var CircuitBreakerDefaultsSchema =
|
|
8467
|
-
failureThreshold:
|
|
9264
|
+
var CircuitBreakerDefaultsSchema = z14.object({
|
|
9265
|
+
failureThreshold: z14.number().int().min(1).max(100).describe("Failures before opening"),
|
|
8468
9266
|
resetTimeoutMs: durationMs.describe("Time before attempting reset"),
|
|
8469
|
-
halfOpenSuccessThreshold:
|
|
8470
|
-
countTimeoutsAsFailures:
|
|
8471
|
-
countAuthFailuresAsFailures:
|
|
8472
|
-
countRateLimitsAsFailures:
|
|
9267
|
+
halfOpenSuccessThreshold: z14.number().int().min(1).max(10).describe("Successes to close"),
|
|
9268
|
+
countTimeoutsAsFailures: z14.boolean().describe("Count timeouts as failures"),
|
|
9269
|
+
countAuthFailuresAsFailures: z14.boolean().describe("Count auth failures as failures"),
|
|
9270
|
+
countRateLimitsAsFailures: z14.boolean().describe("Count rate limit errors as failures"),
|
|
8473
9271
|
halfOpenMaxRequests: positiveInt.describe("Max requests in half-open state")
|
|
8474
9272
|
});
|
|
8475
|
-
var ToolRateLimitConfigSchema =
|
|
9273
|
+
var ToolRateLimitConfigSchema = z14.object({
|
|
8476
9274
|
capacity: positiveInt.describe("Token bucket capacity"),
|
|
8477
9275
|
refillRate: positiveInt.describe("Token refill rate"),
|
|
8478
9276
|
refillIntervalMs: durationMs.describe("Token refill interval")
|
|
8479
9277
|
});
|
|
8480
|
-
var WorkerDefaultsSchema =
|
|
9278
|
+
var WorkerDefaultsSchema = z14.object({
|
|
8481
9279
|
maxWorkers: positiveInt.max(32).describe("Maximum worker threads"),
|
|
8482
9280
|
poolSize: positiveInt.max(32).describe("Worker pool size"),
|
|
8483
9281
|
idleTimeoutMs: durationMs.describe("Worker idle timeout"),
|
|
@@ -8487,7 +9285,7 @@ var WorkerDefaultsSchema = z13.object({
|
|
|
8487
9285
|
eventBusMaxHistory: nonNegativeInt.max(1e4).describe("Event bus history limit"),
|
|
8488
9286
|
swarmObserverMaxEvents: nonNegativeInt.max(1e4).describe("Swarm observer event limit")
|
|
8489
9287
|
});
|
|
8490
|
-
var TimeoutDefaultsSchema =
|
|
9288
|
+
var TimeoutDefaultsSchema = z14.object({
|
|
8491
9289
|
cliMs: durationMs.describe("Default CLI timeout"),
|
|
8492
9290
|
cliSimpleMs: durationMs.describe("Simple CLI task timeout"),
|
|
8493
9291
|
cliComplexMs: durationMs.describe("Complex CLI task timeout"),
|
|
@@ -8522,7 +9320,15 @@ var VOTE_TIMEOUTS = {
|
|
|
8522
9320
|
/** Maximum allowed vote timeout (cap for env override). */
|
|
8523
9321
|
maxMs: 6e5,
|
|
8524
9322
|
/** Default max retries per agent. */
|
|
8525
|
-
maxRetries: 2
|
|
9323
|
+
maxRetries: 2,
|
|
9324
|
+
/**
|
|
9325
|
+
* Slack buffer added to the overall wall-clock deadline in
|
|
9326
|
+
* `computeOverallConsensusDeadlineMs` (#1871). Acts as a safety net
|
|
9327
|
+
* above per-vote × (retries+1) + stagger. Centralized so the formula
|
|
9328
|
+
* can be tuned in one place.
|
|
9329
|
+
* (Issue #2636 — was hardcoded `60_000` in voter-agents.ts:93)
|
|
9330
|
+
*/
|
|
9331
|
+
overallDeadlineBufferMs: 6e4
|
|
8526
9332
|
};
|
|
8527
9333
|
var MCP_TIMEOUTS = {
|
|
8528
9334
|
/** Default timeout for MCP tool handlers. */
|
|
@@ -8619,7 +9425,26 @@ var INTERNAL_TIMEOUTS = {
|
|
|
8619
9425
|
/** Wave scheduler per-task timeout. */
|
|
8620
9426
|
waveTaskMs: 6e4,
|
|
8621
9427
|
/** Puppeteer orchestration timeout. */
|
|
8622
|
-
puppeteerMs: 3e5
|
|
9428
|
+
puppeteerMs: 3e5,
|
|
9429
|
+
/**
|
|
9430
|
+
* Initial cooldown before a disabled worker role can attempt recovery
|
|
9431
|
+
* (Issue #1458). Used by `worker-dispatcher.ts` circuit-breaker logic.
|
|
9432
|
+
* (Issue #2636 — re-homed from worker-dispatcher.ts:57)
|
|
9433
|
+
*/
|
|
9434
|
+
workerRecoveryCooldownMs: 3e4,
|
|
9435
|
+
/**
|
|
9436
|
+
* Maximum cooldown after exponential backoff (Issue #1458). Caps the
|
|
9437
|
+
* worker-dispatcher circuit-breaker backoff so a permanently-broken
|
|
9438
|
+
* role doesn't hold the slot indefinitely.
|
|
9439
|
+
* (Issue #2636 — re-homed from worker-dispatcher.ts:60)
|
|
9440
|
+
*/
|
|
9441
|
+
workerMaxCooldownMs: 3e5,
|
|
9442
|
+
/**
|
|
9443
|
+
* Minimum spacing between requests to rate-limited worker roles
|
|
9444
|
+
* (Issue #1458).
|
|
9445
|
+
* (Issue #2636 — re-homed from worker-dispatcher.ts:63)
|
|
9446
|
+
*/
|
|
9447
|
+
workerRateLimitSpacingMs: 2e3
|
|
8623
9448
|
};
|
|
8624
9449
|
var EXPERT_TIMEOUTS = {
|
|
8625
9450
|
/** Complex reasoning tasks: architecture, security_review, planning. */
|
|
@@ -8630,6 +9455,14 @@ var EXPERT_TIMEOUTS = {
|
|
|
8630
9455
|
minMs: 3e4,
|
|
8631
9456
|
/** Maximum allowed expert timeout. */
|
|
8632
9457
|
maxMs: 9e5,
|
|
9458
|
+
/**
|
|
9459
|
+
* Stricter floor for `execute_expert` specifically — LLM inference takes
|
|
9460
|
+
* 20-90s minimum (#1163, #1330), so this caller-facing floor prevents
|
|
9461
|
+
* configuring a timeout that's guaranteed to fail. The global `minMs`
|
|
9462
|
+
* (30s) remains the absolute floor for non-execute paths.
|
|
9463
|
+
* (Issue #2636 — was hardcoded `EXPERT_TIMEOUT_FLOOR_MS = 120_000` in execute-expert.ts:68)
|
|
9464
|
+
*/
|
|
9465
|
+
executeFloorMs: 12e4,
|
|
8633
9466
|
/** Categories considered complex (longer timeout).
|
|
8634
9467
|
* Updated: Issue #1675 — devops (avg 54s) and documentation (avg 64s on gemini)
|
|
8635
9468
|
* regularly exceed the 120s standard CLI timeout. */
|
|
@@ -9393,9 +10226,9 @@ function convertBonusesToScoreMap(bonuses, taskCategory) {
|
|
|
9393
10226
|
}
|
|
9394
10227
|
|
|
9395
10228
|
// src/cli-adapters/fallback-chains.ts
|
|
9396
|
-
import { z as
|
|
9397
|
-
var FallbackChainSchema =
|
|
9398
|
-
var FallbackChainRegistrySchema =
|
|
10229
|
+
import { z as z15 } from "zod";
|
|
10230
|
+
var FallbackChainSchema = z15.array(z15.enum(["claude", "gemini", "codex", "opencode"])).min(1).readonly();
|
|
10231
|
+
var FallbackChainRegistrySchema = z15.object({
|
|
9399
10232
|
code: FallbackChainSchema,
|
|
9400
10233
|
research: FallbackChainSchema,
|
|
9401
10234
|
documentation: FallbackChainSchema,
|
|
@@ -10113,6 +10946,12 @@ var CompositeRouter = class _CompositeRouter {
|
|
|
10113
10946
|
/** Strategy distiller instance (Issue #999) */
|
|
10114
10947
|
strategyDistiller;
|
|
10115
10948
|
cliNames;
|
|
10949
|
+
/**
|
|
10950
|
+
* (#2540 PR 7) Optional harness-driven availability gate. When set,
|
|
10951
|
+
* `executeRouting` filters the candidate CLI list to only those with
|
|
10952
|
+
* ≥1 routable model per the cache. See `getCandidateCliNames`.
|
|
10953
|
+
*/
|
|
10954
|
+
availableModelsCache;
|
|
10116
10955
|
// Statistics tracking
|
|
10117
10956
|
totalDecisions = 0;
|
|
10118
10957
|
decisionsPerCli = {
|
|
@@ -10140,6 +10979,7 @@ var CompositeRouter = class _CompositeRouter {
|
|
|
10140
10979
|
distilledRuleStageConfig,
|
|
10141
10980
|
metricsCollector,
|
|
10142
10981
|
orchestrationObserver,
|
|
10982
|
+
availableModelsCache,
|
|
10143
10983
|
...baseConfig
|
|
10144
10984
|
} = config ?? {};
|
|
10145
10985
|
this.config = CompositeRouterConfigSchema.parse(baseConfig);
|
|
@@ -10153,6 +10993,10 @@ var CompositeRouter = class _CompositeRouter {
|
|
|
10153
10993
|
this.orchestrationObserver = orchestrationObserver;
|
|
10154
10994
|
this.logger.debug("OrchestrationObserver wired to CompositeRouter");
|
|
10155
10995
|
}
|
|
10996
|
+
if (availableModelsCache !== void 0) {
|
|
10997
|
+
this.availableModelsCache = availableModelsCache;
|
|
10998
|
+
this.logger.debug("AvailableModelsCache wired to CompositeRouter");
|
|
10999
|
+
}
|
|
10156
11000
|
this.initializeCoreRouters(
|
|
10157
11001
|
adapters,
|
|
10158
11002
|
preferenceRouterConfig,
|
|
@@ -10379,11 +11223,12 @@ var CompositeRouter = class _CompositeRouter {
|
|
|
10379
11223
|
try {
|
|
10380
11224
|
const taskProfile = analyzeTaskProfile(task, stagesExecuted);
|
|
10381
11225
|
const deps = this.getStageDependencies();
|
|
11226
|
+
const candidateCliNames = await this.getCandidateCliNames();
|
|
10382
11227
|
const pipelineResult = await runPipeline(
|
|
10383
11228
|
task,
|
|
10384
11229
|
taskProfile,
|
|
10385
11230
|
stagesExecuted,
|
|
10386
|
-
|
|
11231
|
+
candidateCliNames,
|
|
10387
11232
|
deps
|
|
10388
11233
|
);
|
|
10389
11234
|
if (!pipelineResult.ok) {
|
|
@@ -10401,6 +11246,37 @@ var CompositeRouter = class _CompositeRouter {
|
|
|
10401
11246
|
return this.handleRoutingError(error, stagesExecuted);
|
|
10402
11247
|
}
|
|
10403
11248
|
}
|
|
11249
|
+
/**
|
|
11250
|
+
* (#2540 PR 7) Returns the CLI candidate set for the routing pipeline,
|
|
11251
|
+
* filtered by harness-driven availability when the cache is wired.
|
|
11252
|
+
*
|
|
11253
|
+
* Filtering rules:
|
|
11254
|
+
* - No cache configured → return all registered CLI names (prior behaviour).
|
|
11255
|
+
* - Cache configured → query getAll(); a CLI is excluded only if the
|
|
11256
|
+
* cache reports zero models for it. If the cache returns an empty union
|
|
11257
|
+
* (cold start, all sources failing), fall back to all registered CLIs
|
|
11258
|
+
* so the router never wedges on a transient cache miss.
|
|
11259
|
+
* - Errors in the cache do not block routing — log and fall through.
|
|
11260
|
+
*/
|
|
11261
|
+
async getCandidateCliNames() {
|
|
11262
|
+
if (this.availableModelsCache === void 0) return this.cliNames;
|
|
11263
|
+
try {
|
|
11264
|
+
const all = await this.availableModelsCache.getAll();
|
|
11265
|
+
if (all.length === 0) return this.cliNames;
|
|
11266
|
+
const sourcesWithModels = new Set(all.map((m) => m.source));
|
|
11267
|
+
const filtered = this.cliNames.filter((name) => sourcesWithModels.has(name));
|
|
11268
|
+
return filtered.length > 0 ? filtered : this.cliNames;
|
|
11269
|
+
} catch (e) {
|
|
11270
|
+
this.logger.warn("AvailableModelsCache query failed; falling back to all CLIs", {
|
|
11271
|
+
error: e instanceof Error ? e.message : String(e)
|
|
11272
|
+
});
|
|
11273
|
+
return this.cliNames;
|
|
11274
|
+
}
|
|
11275
|
+
}
|
|
11276
|
+
/** (#2540 PR 7) Public accessor for the wired cache (or undefined). */
|
|
11277
|
+
getAvailableModelsCache() {
|
|
11278
|
+
return this.availableModelsCache;
|
|
11279
|
+
}
|
|
10404
11280
|
getStageDependencies() {
|
|
10405
11281
|
return {
|
|
10406
11282
|
config: this.config,
|
|
@@ -11068,6 +11944,11 @@ export {
|
|
|
11068
11944
|
RateLimitError,
|
|
11069
11945
|
toError,
|
|
11070
11946
|
getErrorMessage,
|
|
11947
|
+
DEFAULT_MODEL_PER_CLI,
|
|
11948
|
+
DEFAULT_ENTRY,
|
|
11949
|
+
deriveEntry,
|
|
11950
|
+
resolveModelIdentity,
|
|
11951
|
+
resolveModelIdentitySync,
|
|
11071
11952
|
OUTPUT_MODALITIES,
|
|
11072
11953
|
INPUT_MODALITIES,
|
|
11073
11954
|
TOOL_CAPABILITIES,
|
|
@@ -11076,14 +11957,23 @@ export {
|
|
|
11076
11957
|
CliNameSchema,
|
|
11077
11958
|
DEFAULT_CLI,
|
|
11078
11959
|
ModelCapabilitySchema,
|
|
11079
|
-
|
|
11080
|
-
|
|
11081
|
-
|
|
11960
|
+
ModelRegistry,
|
|
11961
|
+
getDefaultRegistry,
|
|
11962
|
+
setDefaultRegistry,
|
|
11963
|
+
getModelContextWindow,
|
|
11964
|
+
getDefaultModelForCli,
|
|
11965
|
+
getCliModelName,
|
|
11966
|
+
resolveCliAlias,
|
|
11967
|
+
buildCapabilityProfiles,
|
|
11968
|
+
findCanonicalModel,
|
|
11969
|
+
buildModelInfo,
|
|
11970
|
+
getInTreeCapabilitiesMatrix,
|
|
11971
|
+
lookupInTreeCapability,
|
|
11972
|
+
findInTreeByCli,
|
|
11082
11973
|
findModelsByOutputModality,
|
|
11083
11974
|
findModelsByInputModality,
|
|
11084
11975
|
findModelsByToolCapability,
|
|
11085
11976
|
findModelsByFeature,
|
|
11086
|
-
findModelsByCli,
|
|
11087
11977
|
modelSupportsAll,
|
|
11088
11978
|
calculateCost,
|
|
11089
11979
|
colors,
|
|
@@ -11113,13 +12003,6 @@ export {
|
|
|
11113
12003
|
getRandomProvider,
|
|
11114
12004
|
getTokenEstimator,
|
|
11115
12005
|
estimateTokens,
|
|
11116
|
-
getModelContextWindow,
|
|
11117
|
-
getDefaultModelForCli,
|
|
11118
|
-
getCliModelName,
|
|
11119
|
-
resolveCliAlias,
|
|
11120
|
-
buildCapabilityProfiles,
|
|
11121
|
-
findCanonicalModel,
|
|
11122
|
-
buildModelInfo,
|
|
11123
12006
|
CLI_VERSION_REQUIREMENTS,
|
|
11124
12007
|
DEFAULT_CAPABILITIES,
|
|
11125
12008
|
RoutingMemoryError,
|
|
@@ -11190,6 +12073,7 @@ export {
|
|
|
11190
12073
|
API_TIMEOUTS,
|
|
11191
12074
|
WORKER_TIMEOUTS,
|
|
11192
12075
|
INTERNAL_TIMEOUTS,
|
|
12076
|
+
EXPERT_TIMEOUTS,
|
|
11193
12077
|
HEARTBEAT_TIMEOUTS,
|
|
11194
12078
|
TIMEOUT_GUARD,
|
|
11195
12079
|
REFLECTIVE_TIMEOUTS,
|
|
@@ -11216,4 +12100,4 @@ export {
|
|
|
11216
12100
|
ParseError,
|
|
11217
12101
|
OrchestratorError
|
|
11218
12102
|
};
|
|
11219
|
-
//# sourceMappingURL=chunk-
|
|
12103
|
+
//# sourceMappingURL=chunk-Q3RFPJYK.js.map
|