nexus-agents 2.77.12 → 2.78.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/{child-mcp-config-MJMUF7TL.js → child-mcp-config-CTO2MBRM.js} +3 -4
- package/dist/{child-mcp-config-MJMUF7TL.js.map → child-mcp-config-CTO2MBRM.js.map} +1 -1
- package/dist/{chunk-YJ2IGAD2.js → chunk-2UYTFLMO.js} +2 -2
- package/dist/{chunk-6AY5DK4E.js → chunk-2YPG6PDG.js} +3 -3
- package/dist/{chunk-3VWMM6UF.js → chunk-3NIPH6UP.js} +2 -2
- package/dist/{chunk-L3TPDTP3.js → chunk-4N33QZLH.js} +13 -15
- package/dist/{chunk-L3TPDTP3.js.map → chunk-4N33QZLH.js.map} +1 -1
- package/dist/{chunk-JN6UWGHH.js → chunk-5O6XLBPP.js} +2 -2
- package/dist/{chunk-ERWXGXV2.js → chunk-6TFTVW77.js} +3 -3
- package/dist/{chunk-2IAWMNNB.js → chunk-6WBTNZAY.js} +183 -87
- package/dist/chunk-6WBTNZAY.js.map +1 -0
- package/dist/{chunk-GOT7OAL5.js → chunk-7BMOZJYS.js} +29 -5
- package/dist/chunk-7BMOZJYS.js.map +1 -0
- package/dist/{chunk-C2LLQ6TW.js → chunk-7XCUZI4G.js} +4 -4
- package/dist/chunk-7XCUZI4G.js.map +1 -0
- package/dist/{chunk-TDV5ALHY.js → chunk-D6TM2VHX.js} +3 -3
- package/dist/{chunk-PWTJGGKB.js → chunk-DLXT23AC.js} +2 -2
- package/dist/chunk-DNO2INX5.js +276 -0
- package/dist/chunk-DNO2INX5.js.map +1 -0
- package/dist/{chunk-G2CSKBY5.js → chunk-FJWWSVWB.js} +29 -6
- package/dist/chunk-FJWWSVWB.js.map +1 -0
- package/dist/{chunk-DSQ5XM4O.js → chunk-FVPYP5DD.js} +4 -4
- package/dist/{chunk-MGLWPN2I.js → chunk-GONMG4NM.js} +2 -2
- package/dist/{chunk-XYA3DPWJ.js → chunk-GTGDVBLW.js} +5 -5
- package/dist/{chunk-YQMQSJQK.js → chunk-HYU4GZY6.js} +2 -2
- package/dist/{chunk-3DH5SLFH.js → chunk-K2QILJG4.js} +6 -6
- package/dist/{chunk-5WHWKY32.js → chunk-KT5FIBWS.js} +2 -2
- package/dist/{chunk-DIB6V67T.js → chunk-L6SCKLGO.js} +3 -3
- package/dist/{chunk-IPWCD22D.js → chunk-PLX6FCFC.js} +2 -2
- package/dist/chunk-PQHVC4BD.js +639 -0
- package/dist/chunk-PQHVC4BD.js.map +1 -0
- package/dist/chunk-Q5CFPIJ5.js +5581 -0
- package/dist/chunk-Q5CFPIJ5.js.map +1 -0
- package/dist/{chunk-G6ZPVADX.js → chunk-SD76JZBG.js} +2 -2
- package/dist/{chunk-Y2CP4Z5B.js → chunk-SWFJU3W2.js} +220 -4580
- package/dist/chunk-SWFJU3W2.js.map +1 -0
- package/dist/{chunk-3MRM53T4.js → chunk-WDYCIJWN.js} +640 -470
- package/dist/chunk-WDYCIJWN.js.map +1 -0
- package/dist/{chunk-CM3TORGV.js → chunk-YXWGEIQR.js} +2 -2
- package/dist/{chunk-7NK7BTWP.js → chunk-ZVCED4Z4.js} +2 -2
- package/dist/cli-circuit-breaker-I74ZQ44Q.js +13 -0
- package/dist/cli.js +109 -58
- package/dist/cli.js.map +1 -1
- package/dist/{composite-router-S6E26BCI.js → composite-router-V3OC57IE.js} +3 -4
- package/dist/consensus-vote-ESFPGEJE.js +30 -0
- package/dist/context-retriever-MB3D7KS6.js +18 -0
- package/dist/dist-NIXVXYIH.js +42 -0
- package/dist/doctor-deep-KQ765XZA.js +12 -0
- package/dist/expert-bridge-JKLC57IC.js +10 -0
- package/dist/factory-BUUXNGIB.js +14 -0
- package/dist/{factory-X3VKIGKP.js → factory-LHHYDVZX.js} +5 -6
- package/dist/index.d.ts +72 -8
- package/dist/index.js +208 -316
- package/dist/index.js.map +1 -1
- package/dist/{init-opencode-CFE7M6XA.js → init-opencode-GXZN2W5S.js} +6 -7
- package/dist/{init-opencode-CFE7M6XA.js.map → init-opencode-GXZN2W5S.js.map} +1 -1
- package/dist/issue-triage-RMXPDZ2K.js +15 -0
- package/dist/{learning-persistence-N6ILD2HX.js → learning-persistence-Q3HTOGTU.js} +2 -3
- package/dist/outcome-store-adapter-QRFJJIKB.js +57 -0
- package/dist/outcome-store-adapter-QRFJJIKB.js.map +1 -0
- package/dist/{registry-command-RPPC7N2K.js → registry-command-6E4YKAMT.js} +3 -4
- package/dist/{registry-command-RPPC7N2K.js.map → registry-command-6E4YKAMT.js.map} +1 -1
- package/dist/{repo-security-plan-7ZCDVH5O.js → repo-security-plan-AGRU72DL.js} +4 -5
- package/dist/research-helpers-synthesize-K2UCJQQG.js +13 -0
- package/dist/{routing-memory-5VTX7LQX.js → routing-memory-3B6DDZ76.js} +3 -4
- package/dist/{session-memory-7XBV6BMY.js → session-memory-L7EQIY2O.js} +4 -5
- package/dist/{setup-command-3ZTEPKDA.js → setup-command-VYV4RFWW.js} +11 -12
- package/dist/setup-config-EQT24DD4.js +10 -0
- package/dist/{setup-custom-api-WM5W5AY5.js → setup-custom-api-IBDV654K.js} +5 -6
- package/dist/{setup-custom-api-WM5W5AY5.js.map → setup-custom-api-IBDV654K.js.map} +1 -1
- package/dist/tool-memory-6HCHQLAN.js +19 -0
- package/dist/{weather-report-YJMVKJGA.js → weather-report-ER3WUZ7S.js} +3 -4
- package/package.json +3 -2
- package/dist/adaptive-memory-EI564K4C.js +0 -16
- package/dist/chunk-2IAWMNNB.js.map +0 -1
- package/dist/chunk-3MRM53T4.js.map +0 -1
- package/dist/chunk-BJ2OMC7P.js +0 -944
- package/dist/chunk-BJ2OMC7P.js.map +0 -1
- package/dist/chunk-C2LLQ6TW.js.map +0 -1
- package/dist/chunk-G2CSKBY5.js.map +0 -1
- package/dist/chunk-GOT7OAL5.js.map +0 -1
- package/dist/chunk-I7ORMAO7.js +0 -32
- package/dist/chunk-I7ORMAO7.js.map +0 -1
- package/dist/chunk-Y2CP4Z5B.js.map +0 -1
- package/dist/cli-circuit-breaker-YX4BWZD5.js +0 -14
- package/dist/consensus-vote-MUQ4HPIF.js +0 -30
- package/dist/doctor-deep-BRU5ZUJI.js +0 -13
- package/dist/expert-bridge-ZPNVLJVN.js +0 -11
- package/dist/factory-A7DTCCUY.js +0 -15
- package/dist/issue-triage-6XD6CVPB.js +0 -16
- package/dist/mobimem-CG2MNS7V.js +0 -14
- package/dist/nexus-data-dir-77UO7N6J.js +0 -12
- package/dist/research-helpers-synthesize-36TUTUUA.js +0 -14
- package/dist/setup-config-EI5KROA3.js +0 -11
- /package/dist/{chunk-YJ2IGAD2.js.map → chunk-2UYTFLMO.js.map} +0 -0
- /package/dist/{chunk-6AY5DK4E.js.map → chunk-2YPG6PDG.js.map} +0 -0
- /package/dist/{chunk-3VWMM6UF.js.map → chunk-3NIPH6UP.js.map} +0 -0
- /package/dist/{chunk-JN6UWGHH.js.map → chunk-5O6XLBPP.js.map} +0 -0
- /package/dist/{chunk-ERWXGXV2.js.map → chunk-6TFTVW77.js.map} +0 -0
- /package/dist/{chunk-TDV5ALHY.js.map → chunk-D6TM2VHX.js.map} +0 -0
- /package/dist/{chunk-PWTJGGKB.js.map → chunk-DLXT23AC.js.map} +0 -0
- /package/dist/{chunk-DSQ5XM4O.js.map → chunk-FVPYP5DD.js.map} +0 -0
- /package/dist/{chunk-MGLWPN2I.js.map → chunk-GONMG4NM.js.map} +0 -0
- /package/dist/{chunk-XYA3DPWJ.js.map → chunk-GTGDVBLW.js.map} +0 -0
- /package/dist/{chunk-YQMQSJQK.js.map → chunk-HYU4GZY6.js.map} +0 -0
- /package/dist/{chunk-3DH5SLFH.js.map → chunk-K2QILJG4.js.map} +0 -0
- /package/dist/{chunk-5WHWKY32.js.map → chunk-KT5FIBWS.js.map} +0 -0
- /package/dist/{chunk-DIB6V67T.js.map → chunk-L6SCKLGO.js.map} +0 -0
- /package/dist/{chunk-IPWCD22D.js.map → chunk-PLX6FCFC.js.map} +0 -0
- /package/dist/{chunk-G6ZPVADX.js.map → chunk-SD76JZBG.js.map} +0 -0
- /package/dist/{chunk-CM3TORGV.js.map → chunk-YXWGEIQR.js.map} +0 -0
- /package/dist/{chunk-7NK7BTWP.js.map → chunk-ZVCED4Z4.js.map} +0 -0
- /package/dist/{adaptive-memory-EI564K4C.js.map → cli-circuit-breaker-I74ZQ44Q.js.map} +0 -0
- /package/dist/{cli-circuit-breaker-YX4BWZD5.js.map → composite-router-V3OC57IE.js.map} +0 -0
- /package/dist/{composite-router-S6E26BCI.js.map → consensus-vote-ESFPGEJE.js.map} +0 -0
- /package/dist/{consensus-vote-MUQ4HPIF.js.map → context-retriever-MB3D7KS6.js.map} +0 -0
- /package/dist/{doctor-deep-BRU5ZUJI.js.map → dist-NIXVXYIH.js.map} +0 -0
- /package/dist/{expert-bridge-ZPNVLJVN.js.map → doctor-deep-KQ765XZA.js.map} +0 -0
- /package/dist/{factory-A7DTCCUY.js.map → expert-bridge-JKLC57IC.js.map} +0 -0
- /package/dist/{factory-X3VKIGKP.js.map → factory-BUUXNGIB.js.map} +0 -0
- /package/dist/{issue-triage-6XD6CVPB.js.map → factory-LHHYDVZX.js.map} +0 -0
- /package/dist/{learning-persistence-N6ILD2HX.js.map → issue-triage-RMXPDZ2K.js.map} +0 -0
- /package/dist/{mobimem-CG2MNS7V.js.map → learning-persistence-Q3HTOGTU.js.map} +0 -0
- /package/dist/{nexus-data-dir-77UO7N6J.js.map → repo-security-plan-AGRU72DL.js.map} +0 -0
- /package/dist/{repo-security-plan-7ZCDVH5O.js.map → research-helpers-synthesize-K2UCJQQG.js.map} +0 -0
- /package/dist/{research-helpers-synthesize-36TUTUUA.js.map → routing-memory-3B6DDZ76.js.map} +0 -0
- /package/dist/{routing-memory-5VTX7LQX.js.map → session-memory-L7EQIY2O.js.map} +0 -0
- /package/dist/{session-memory-7XBV6BMY.js.map → setup-command-VYV4RFWW.js.map} +0 -0
- /package/dist/{setup-command-3ZTEPKDA.js.map → setup-config-EQT24DD4.js.map} +0 -0
- /package/dist/{setup-config-EI5KROA3.js.map → tool-memory-6HCHQLAN.js.map} +0 -0
- /package/dist/{weather-report-YJMVKJGA.js.map → weather-report-ER3WUZ7S.js.map} +0 -0
|
@@ -1,9 +1,7 @@
|
|
|
1
1
|
import {
|
|
2
|
-
isPersistenceEnabled
|
|
3
|
-
} from "./chunk-I7ORMAO7.js";
|
|
4
|
-
import {
|
|
2
|
+
isPersistenceEnabled,
|
|
5
3
|
nexusDataPath
|
|
6
|
-
} from "./chunk-
|
|
4
|
+
} from "./chunk-7BMOZJYS.js";
|
|
7
5
|
import {
|
|
8
6
|
__require
|
|
9
7
|
} from "./chunk-UP2VWCW5.js";
|
|
@@ -280,33 +278,6 @@ function createLogger(baseContext) {
|
|
|
280
278
|
}
|
|
281
279
|
var logger = createLogger();
|
|
282
280
|
|
|
283
|
-
// src/context/mobimem-types.ts
|
|
284
|
-
import { z } from "zod";
|
|
285
|
-
var DEFAULT_MOBIMEM_CONFIG = {
|
|
286
|
-
dbPath: ":memory:",
|
|
287
|
-
maxProfileEntries: 100,
|
|
288
|
-
maxExperiencePatterns: 500,
|
|
289
|
-
maxActionCacheEntries: 1e3,
|
|
290
|
-
actionCacheTtlMs: 36e5,
|
|
291
|
-
// 1 hour
|
|
292
|
-
minProfileConfidence: 0.6,
|
|
293
|
-
minExperienceSuccessRate: 0.7,
|
|
294
|
-
autoEviction: true
|
|
295
|
-
};
|
|
296
|
-
var MobiMemConfigSchema = z.object({
|
|
297
|
-
dbPath: z.string(),
|
|
298
|
-
maxProfileEntries: z.number().int().positive().default(100),
|
|
299
|
-
maxExperiencePatterns: z.number().int().positive().default(500),
|
|
300
|
-
maxActionCacheEntries: z.number().int().positive().default(1e3),
|
|
301
|
-
actionCacheTtlMs: z.number().int().positive().default(36e5),
|
|
302
|
-
minProfileConfidence: z.number().min(0).max(1).default(0.6),
|
|
303
|
-
minExperienceSuccessRate: z.number().min(0).max(1).default(0.7),
|
|
304
|
-
autoEviction: z.boolean().default(true)
|
|
305
|
-
});
|
|
306
|
-
|
|
307
|
-
// src/context/mobimem-impl.ts
|
|
308
|
-
import { randomUUID as randomUUID4 } from "crypto";
|
|
309
|
-
|
|
310
281
|
// src/core/result.ts
|
|
311
282
|
function ok(value) {
|
|
312
283
|
return { ok: true, value };
|
|
@@ -1464,10 +1435,10 @@ function buildInTreeEntries() {
|
|
|
1464
1435
|
// src/config/manifest-overlay.ts
|
|
1465
1436
|
import { existsSync, readFileSync, statSync } from "fs";
|
|
1466
1437
|
import { parse as parseYaml } from "yaml";
|
|
1467
|
-
import { z as
|
|
1438
|
+
import { z as z2 } from "zod";
|
|
1468
1439
|
|
|
1469
1440
|
// src/config/model-capabilities-types.ts
|
|
1470
|
-
import { z
|
|
1441
|
+
import { z } from "zod";
|
|
1471
1442
|
var OUTPUT_MODALITIES = [
|
|
1472
1443
|
"text",
|
|
1473
1444
|
"image_png",
|
|
@@ -1504,7 +1475,7 @@ var SPECIAL_FEATURES = [
|
|
|
1504
1475
|
];
|
|
1505
1476
|
var PROVIDERS = ["anthropic", "google", "openai", "custom-openai", "openrouter"];
|
|
1506
1477
|
var CLI_NAMES = ["claude", "gemini", "codex", "opencode"];
|
|
1507
|
-
var CliNameSchema =
|
|
1478
|
+
var CliNameSchema = z.enum(CLI_NAMES);
|
|
1508
1479
|
var DEFAULT_CLI = "claude";
|
|
1509
1480
|
var MODEL_IDS = [
|
|
1510
1481
|
"claude-opus",
|
|
@@ -1523,49 +1494,49 @@ var MODEL_IDS = [
|
|
|
1523
1494
|
"openrouter-nemotron-super",
|
|
1524
1495
|
"openrouter-qwen-coder"
|
|
1525
1496
|
];
|
|
1526
|
-
var QualityScoresSchema =
|
|
1527
|
-
reasoning:
|
|
1528
|
-
codeGeneration:
|
|
1529
|
-
speed:
|
|
1530
|
-
cost:
|
|
1497
|
+
var QualityScoresSchema = z.object({
|
|
1498
|
+
reasoning: z.number().min(0).max(10),
|
|
1499
|
+
codeGeneration: z.number().min(0).max(10),
|
|
1500
|
+
speed: z.number().min(0).max(10),
|
|
1501
|
+
cost: z.number().min(0).max(10)
|
|
1531
1502
|
});
|
|
1532
|
-
var PricingSchema =
|
|
1533
|
-
inputPer1M:
|
|
1534
|
-
outputPer1M:
|
|
1503
|
+
var PricingSchema = z.object({
|
|
1504
|
+
inputPer1M: z.number().nonnegative(),
|
|
1505
|
+
outputPer1M: z.number().nonnegative()
|
|
1535
1506
|
});
|
|
1536
|
-
var ModelCapabilitySchema =
|
|
1507
|
+
var ModelCapabilitySchema = z.object({
|
|
1537
1508
|
/** Unique model identifier matching delegate_to_model model IDs */
|
|
1538
|
-
id:
|
|
1509
|
+
id: z.enum(MODEL_IDS),
|
|
1539
1510
|
/** Human-readable display name */
|
|
1540
|
-
displayName:
|
|
1511
|
+
displayName: z.string().min(1),
|
|
1541
1512
|
/** Provider/vendor */
|
|
1542
|
-
provider:
|
|
1513
|
+
provider: z.enum(PROVIDERS),
|
|
1543
1514
|
/** Maximum context window in tokens */
|
|
1544
|
-
contextWindow:
|
|
1515
|
+
contextWindow: z.number().int().positive(),
|
|
1545
1516
|
/** Output modalities this model can produce */
|
|
1546
|
-
outputModalities:
|
|
1517
|
+
outputModalities: z.array(z.enum(OUTPUT_MODALITIES)).min(1),
|
|
1547
1518
|
/** Input modalities this model can accept */
|
|
1548
|
-
inputModalities:
|
|
1519
|
+
inputModalities: z.array(z.enum(INPUT_MODALITIES)).min(1),
|
|
1549
1520
|
/** Tool/integration capabilities */
|
|
1550
|
-
toolCapabilities:
|
|
1521
|
+
toolCapabilities: z.array(z.enum(TOOL_CAPABILITIES)),
|
|
1551
1522
|
/** Special features beyond standard generation */
|
|
1552
|
-
specialFeatures:
|
|
1523
|
+
specialFeatures: z.array(z.enum(SPECIAL_FEATURES)),
|
|
1553
1524
|
/** Known constraints or limitations */
|
|
1554
|
-
constraints:
|
|
1525
|
+
constraints: z.array(z.string()).optional(),
|
|
1555
1526
|
/** Notes about the model (e.g., beta features, pricing tier) */
|
|
1556
|
-
notes:
|
|
1527
|
+
notes: z.string().optional(),
|
|
1557
1528
|
/** Pricing per 1M tokens (USD) */
|
|
1558
1529
|
pricing: PricingSchema.optional(),
|
|
1559
1530
|
/** Quality scores for routing (0-10 scale) */
|
|
1560
1531
|
qualityScores: QualityScoresSchema.optional(),
|
|
1561
1532
|
/** Maximum output tokens */
|
|
1562
|
-
maxOutputTokens:
|
|
1533
|
+
maxOutputTokens: z.number().int().positive().optional(),
|
|
1563
1534
|
/** Which CLI tool this model belongs to */
|
|
1564
|
-
cliName:
|
|
1535
|
+
cliName: z.enum(CLI_NAMES).optional(),
|
|
1565
1536
|
/** Short alias used by the CLI (e.g., 'opus' for Claude CLI) */
|
|
1566
|
-
cliAlias:
|
|
1537
|
+
cliAlias: z.string().optional(),
|
|
1567
1538
|
/** Model name the CLI binary expects (e.g., 'gemini-2.5-pro') */
|
|
1568
|
-
cliModelName:
|
|
1539
|
+
cliModelName: z.string().optional(),
|
|
1569
1540
|
/**
|
|
1570
1541
|
* Legacy / version-suffixed names that resolve to this model. Used by
|
|
1571
1542
|
* adapters and routing to map historical user-facing names (e.g.,
|
|
@@ -1576,21 +1547,21 @@ var ModelCapabilitySchema = z2.object({
|
|
|
1576
1547
|
* Added for issue #2199 Child 1; populated by the companion migration
|
|
1577
1548
|
* epic #2200.
|
|
1578
1549
|
*/
|
|
1579
|
-
aliases:
|
|
1550
|
+
aliases: z.array(z.string().min(1)).optional(),
|
|
1580
1551
|
/** Whether this model is deprecated and should receive a scoring penalty */
|
|
1581
|
-
deprecated:
|
|
1552
|
+
deprecated: z.boolean().optional(),
|
|
1582
1553
|
/** ISO date when the model was deprecated (informational) */
|
|
1583
|
-
deprecatedAt:
|
|
1554
|
+
deprecatedAt: z.string().optional(),
|
|
1584
1555
|
/** Model ID to migrate to (informational guidance) */
|
|
1585
|
-
replacedBy:
|
|
1556
|
+
replacedBy: z.enum(MODEL_IDS).optional()
|
|
1586
1557
|
});
|
|
1587
|
-
var ModelCapabilitiesMatrixSchema =
|
|
1558
|
+
var ModelCapabilitiesMatrixSchema = z.object({
|
|
1588
1559
|
/** Schema version for forward compatibility */
|
|
1589
|
-
version:
|
|
1560
|
+
version: z.number().int().positive(),
|
|
1590
1561
|
/** Last updated date (ISO 8601) */
|
|
1591
|
-
updatedAt:
|
|
1562
|
+
updatedAt: z.string(),
|
|
1592
1563
|
/** Model capability definitions */
|
|
1593
|
-
models:
|
|
1564
|
+
models: z.array(ModelCapabilitySchema).min(1)
|
|
1594
1565
|
});
|
|
1595
1566
|
|
|
1596
1567
|
// src/config/manifest-overlay.ts
|
|
@@ -1604,7 +1575,7 @@ function resolveManifestPath(env = process.env) {
|
|
|
1604
1575
|
if (override !== void 0 && override !== "") return override;
|
|
1605
1576
|
return defaultManifestPath();
|
|
1606
1577
|
}
|
|
1607
|
-
var ModelVendorSchema =
|
|
1578
|
+
var ModelVendorSchema = z2.enum([
|
|
1608
1579
|
"anthropic",
|
|
1609
1580
|
"openai",
|
|
1610
1581
|
"google",
|
|
@@ -1616,49 +1587,49 @@ var ModelVendorSchema = z3.enum([
|
|
|
1616
1587
|
"deepseek",
|
|
1617
1588
|
"unknown"
|
|
1618
1589
|
]);
|
|
1619
|
-
var ToolDefinitionFormatSchema =
|
|
1590
|
+
var ToolDefinitionFormatSchema = z2.enum([
|
|
1620
1591
|
"openai",
|
|
1621
1592
|
"anthropic",
|
|
1622
1593
|
"gemini"
|
|
1623
1594
|
]);
|
|
1624
|
-
var PromptCachingModeSchema =
|
|
1595
|
+
var PromptCachingModeSchema = z2.enum([
|
|
1625
1596
|
"none",
|
|
1626
1597
|
"ephemeral",
|
|
1627
1598
|
"aggressive"
|
|
1628
1599
|
]);
|
|
1629
|
-
var ManifestEntrySchema =
|
|
1600
|
+
var ManifestEntrySchema = z2.object({
|
|
1630
1601
|
// Identity (required)
|
|
1631
|
-
id:
|
|
1602
|
+
id: z2.string().min(1).max(200),
|
|
1632
1603
|
vendor: ModelVendorSchema,
|
|
1633
|
-
family:
|
|
1604
|
+
family: z2.string().min(1).max(80),
|
|
1634
1605
|
// Identity (optional)
|
|
1635
|
-
aliases:
|
|
1636
|
-
version:
|
|
1637
|
-
displayName:
|
|
1606
|
+
aliases: z2.array(z2.string().min(1).max(200)).max(20).optional(),
|
|
1607
|
+
version: z2.string().min(1).max(50).optional(),
|
|
1608
|
+
displayName: z2.string().min(1).max(200).optional(),
|
|
1638
1609
|
// Capabilities (all optional)
|
|
1639
|
-
contextWindow:
|
|
1640
|
-
maxOutputTokens:
|
|
1641
|
-
inputModalities:
|
|
1642
|
-
outputModalities:
|
|
1643
|
-
toolCapabilities:
|
|
1644
|
-
specialFeatures:
|
|
1610
|
+
contextWindow: z2.number().int().positive().max(2e7).optional(),
|
|
1611
|
+
maxOutputTokens: z2.number().int().positive().max(2e7).optional(),
|
|
1612
|
+
inputModalities: z2.array(z2.enum(INPUT_MODALITIES)).optional(),
|
|
1613
|
+
outputModalities: z2.array(z2.enum(OUTPUT_MODALITIES)).optional(),
|
|
1614
|
+
toolCapabilities: z2.array(z2.enum(TOOL_CAPABILITIES)).optional(),
|
|
1615
|
+
specialFeatures: z2.array(z2.enum(SPECIAL_FEATURES)).optional(),
|
|
1645
1616
|
pricing: PricingSchema.optional(),
|
|
1646
1617
|
qualityScores: QualityScoresSchema.optional(),
|
|
1647
|
-
notes:
|
|
1618
|
+
notes: z2.string().max(2e3).optional(),
|
|
1648
1619
|
// Behaviour (all optional — defaults fill in)
|
|
1649
|
-
parallelToolCalls:
|
|
1620
|
+
parallelToolCalls: z2.boolean().optional(),
|
|
1650
1621
|
promptCaching: PromptCachingModeSchema.optional(),
|
|
1651
1622
|
toolDefinitionFormat: ToolDefinitionFormatSchema.optional(),
|
|
1652
|
-
maxRecommendedTurnBudget:
|
|
1653
|
-
strictJson:
|
|
1654
|
-
quirks:
|
|
1655
|
-
profileId:
|
|
1623
|
+
maxRecommendedTurnBudget: z2.number().int().positive().max(100).optional(),
|
|
1624
|
+
strictJson: z2.boolean().optional(),
|
|
1625
|
+
quirks: z2.array(z2.string().max(80)).max(20).optional(),
|
|
1626
|
+
profileId: z2.string().min(1).max(80).optional(),
|
|
1656
1627
|
// Provenance (optional)
|
|
1657
|
-
verifiedAt:
|
|
1628
|
+
verifiedAt: z2.string().min(8).max(40).optional()
|
|
1658
1629
|
});
|
|
1659
|
-
var ManifestSchema =
|
|
1660
|
-
version:
|
|
1661
|
-
models:
|
|
1630
|
+
var ManifestSchema = z2.object({
|
|
1631
|
+
version: z2.literal(1),
|
|
1632
|
+
models: z2.array(z2.unknown())
|
|
1662
1633
|
});
|
|
1663
1634
|
function loadManifestOverlay(options) {
|
|
1664
1635
|
const logger11 = options?.logger ?? createLogger({ component: "manifest-overlay" });
|
|
@@ -2603,7 +2574,7 @@ function formatPercentage(value, decimals = 0) {
|
|
|
2603
2574
|
|
|
2604
2575
|
// src/core/artifact.ts
|
|
2605
2576
|
import { randomUUID as randomUUID2 } from "crypto";
|
|
2606
|
-
import { z as
|
|
2577
|
+
import { z as z3 } from "zod";
|
|
2607
2578
|
var ArtifactType = {
|
|
2608
2579
|
/** Planning documents and task breakdowns */
|
|
2609
2580
|
PLAN: "plan",
|
|
@@ -2616,30 +2587,30 @@ var ArtifactType = {
|
|
|
2616
2587
|
/** Intent declarations for policy authorization */
|
|
2617
2588
|
INTENT: "intent"
|
|
2618
2589
|
};
|
|
2619
|
-
var ArtifactTypeSchema =
|
|
2590
|
+
var ArtifactTypeSchema = z3.enum([
|
|
2620
2591
|
ArtifactType.PLAN,
|
|
2621
2592
|
ArtifactType.ANALYSIS,
|
|
2622
2593
|
ArtifactType.DECISION,
|
|
2623
2594
|
ArtifactType.RESULT,
|
|
2624
2595
|
ArtifactType.INTENT
|
|
2625
2596
|
]);
|
|
2626
|
-
var ArtifactMetadataSchema =
|
|
2627
|
-
createdAt:
|
|
2628
|
-
createdBy:
|
|
2629
|
-
parentId:
|
|
2630
|
-
taskId:
|
|
2631
|
-
traceId:
|
|
2597
|
+
var ArtifactMetadataSchema = z3.object({
|
|
2598
|
+
createdAt: z3.iso.datetime({ message: "createdAt must be ISO 8601 format" }),
|
|
2599
|
+
createdBy: z3.string().min(1, "createdBy is required"),
|
|
2600
|
+
parentId: z3.uuid().optional(),
|
|
2601
|
+
taskId: z3.string().min(1, "taskId is required"),
|
|
2602
|
+
traceId: z3.string().optional()
|
|
2632
2603
|
});
|
|
2633
2604
|
function createArtifactSchema(dataSchema) {
|
|
2634
|
-
return
|
|
2635
|
-
id:
|
|
2605
|
+
return z3.object({
|
|
2606
|
+
id: z3.uuid(),
|
|
2636
2607
|
type: ArtifactTypeSchema,
|
|
2637
|
-
schemaVersion:
|
|
2608
|
+
schemaVersion: z3.string().regex(/^\d+\.\d+\.\d+$/, "schemaVersion must be semver"),
|
|
2638
2609
|
data: dataSchema,
|
|
2639
2610
|
metadata: ArtifactMetadataSchema
|
|
2640
2611
|
});
|
|
2641
2612
|
}
|
|
2642
|
-
var BaseArtifactSchema = createArtifactSchema(
|
|
2613
|
+
var BaseArtifactSchema = createArtifactSchema(z3.unknown());
|
|
2643
2614
|
|
|
2644
2615
|
// src/core/metrics.ts
|
|
2645
2616
|
var MAX_RECENT_ERRORS = 1e3;
|
|
@@ -4585,19 +4556,19 @@ var TopsisRouter = class {
|
|
|
4585
4556
|
};
|
|
4586
4557
|
|
|
4587
4558
|
// src/cli-adapters/budget-router-types.ts
|
|
4588
|
-
import { z as
|
|
4589
|
-
var BudgetConstraintSchema =
|
|
4590
|
-
maxTokens:
|
|
4591
|
-
maxCostUSD:
|
|
4592
|
-
maxLatencyMs:
|
|
4559
|
+
import { z as z4 } from "zod";
|
|
4560
|
+
var BudgetConstraintSchema = z4.object({
|
|
4561
|
+
maxTokens: z4.number().int().positive().optional(),
|
|
4562
|
+
maxCostUSD: z4.number().positive().optional(),
|
|
4563
|
+
maxLatencyMs: z4.number().positive().optional()
|
|
4593
4564
|
});
|
|
4594
|
-
var SessionBudgetSchema =
|
|
4595
|
-
totalTokens:
|
|
4596
|
-
totalCostUSD:
|
|
4597
|
-
usedTokens:
|
|
4598
|
-
usedCostUSD:
|
|
4599
|
-
startTime:
|
|
4600
|
-
sessionId:
|
|
4565
|
+
var SessionBudgetSchema = z4.object({
|
|
4566
|
+
totalTokens: z4.number().int().positive(),
|
|
4567
|
+
totalCostUSD: z4.number().positive(),
|
|
4568
|
+
usedTokens: z4.number().int().min(0).default(0),
|
|
4569
|
+
usedCostUSD: z4.number().min(0).default(0),
|
|
4570
|
+
startTime: z4.number().int().positive(),
|
|
4571
|
+
sessionId: z4.string().min(1)
|
|
4601
4572
|
});
|
|
4602
4573
|
var DEFAULT_LINUCB_CONFIG = {
|
|
4603
4574
|
numArms: 4,
|
|
@@ -4605,11 +4576,11 @@ var DEFAULT_LINUCB_CONFIG = {
|
|
|
4605
4576
|
alpha: 1,
|
|
4606
4577
|
lambda: 1
|
|
4607
4578
|
};
|
|
4608
|
-
var LinUCBConfigSchema =
|
|
4609
|
-
numArms:
|
|
4610
|
-
featureDim:
|
|
4611
|
-
alpha:
|
|
4612
|
-
lambda:
|
|
4579
|
+
var LinUCBConfigSchema = z4.object({
|
|
4580
|
+
numArms: z4.number().int().positive().default(4),
|
|
4581
|
+
featureDim: z4.number().int().positive().default(6),
|
|
4582
|
+
alpha: z4.number().positive().default(1),
|
|
4583
|
+
lambda: z4.number().positive().default(1)
|
|
4613
4584
|
});
|
|
4614
4585
|
|
|
4615
4586
|
// src/cli-adapters/linucb-math.ts
|
|
@@ -4964,7 +4935,7 @@ var LinUCBBandit = class {
|
|
|
4964
4935
|
import { randomUUID as randomUUID3 } from "crypto";
|
|
4965
4936
|
|
|
4966
4937
|
// src/cli-adapters/preference-router-types.ts
|
|
4967
|
-
import { z as
|
|
4938
|
+
import { z as z5 } from "zod";
|
|
4968
4939
|
var DEFAULT_PREFERENCE_ROUTER_CONFIG = {
|
|
4969
4940
|
strongModel: {
|
|
4970
4941
|
tier: "strong",
|
|
@@ -4985,24 +4956,24 @@ var DEFAULT_PREFERENCE_ROUTER_CONFIG = {
|
|
|
4985
4956
|
maxDataPoints: 1e4,
|
|
4986
4957
|
enableOnlineLearning: true
|
|
4987
4958
|
};
|
|
4988
|
-
var PreferenceRouterConfigSchema =
|
|
4989
|
-
strongModel:
|
|
4990
|
-
tier:
|
|
4991
|
-
cli:
|
|
4992
|
-
costPerMillionTokens:
|
|
4993
|
-
qualityBaseline:
|
|
4959
|
+
var PreferenceRouterConfigSchema = z5.object({
|
|
4960
|
+
strongModel: z5.object({
|
|
4961
|
+
tier: z5.literal("strong"),
|
|
4962
|
+
cli: z5.enum(["claude", "gemini", "codex", "opencode"]),
|
|
4963
|
+
costPerMillionTokens: z5.number().positive(),
|
|
4964
|
+
qualityBaseline: z5.number().min(0).max(1)
|
|
4994
4965
|
}),
|
|
4995
|
-
weakModel:
|
|
4996
|
-
tier:
|
|
4997
|
-
cli:
|
|
4998
|
-
costPerMillionTokens:
|
|
4999
|
-
qualityBaseline:
|
|
4966
|
+
weakModel: z5.object({
|
|
4967
|
+
tier: z5.literal("weak"),
|
|
4968
|
+
cli: z5.enum(["claude", "gemini", "codex", "opencode"]),
|
|
4969
|
+
costPerMillionTokens: z5.number().positive(),
|
|
4970
|
+
qualityBaseline: z5.number().min(0).max(1)
|
|
5000
4971
|
}),
|
|
5001
|
-
routingThreshold:
|
|
5002
|
-
minDataPoints:
|
|
5003
|
-
maxDataPoints:
|
|
5004
|
-
enableOnlineLearning:
|
|
5005
|
-
domainThresholds:
|
|
4972
|
+
routingThreshold: z5.number().min(0).max(1).default(0.5),
|
|
4973
|
+
minDataPoints: z5.number().int().positive().default(10),
|
|
4974
|
+
maxDataPoints: z5.number().int().positive().default(1e4),
|
|
4975
|
+
enableOnlineLearning: z5.boolean().default(true),
|
|
4976
|
+
domainThresholds: z5.record(z5.string(), z5.number().min(0).max(1)).optional()
|
|
5006
4977
|
});
|
|
5007
4978
|
|
|
5008
4979
|
// src/cli-adapters/preference-router-store.ts
|
|
@@ -5344,8 +5315,8 @@ function createPreferenceRouter(config, dataStore) {
|
|
|
5344
5315
|
}
|
|
5345
5316
|
|
|
5346
5317
|
// src/cli-adapters/zero-router-types.ts
|
|
5347
|
-
import { z as
|
|
5348
|
-
var DifficultyDimensionSchema =
|
|
5318
|
+
import { z as z6 } from "zod";
|
|
5319
|
+
var DifficultyDimensionSchema = z6.enum([
|
|
5349
5320
|
"reasoning",
|
|
5350
5321
|
"knowledge",
|
|
5351
5322
|
"creativity",
|
|
@@ -5359,17 +5330,17 @@ var DIFFICULTY_DIMENSIONS = [
|
|
|
5359
5330
|
"precision",
|
|
5360
5331
|
"context_length"
|
|
5361
5332
|
];
|
|
5362
|
-
var DifficultySpaceSchema =
|
|
5333
|
+
var DifficultySpaceSchema = z6.object({
|
|
5363
5334
|
/** Reasoning difficulty: logical complexity, multi-step inference (0-1) */
|
|
5364
|
-
reasoning:
|
|
5335
|
+
reasoning: z6.number().min(0).max(1),
|
|
5365
5336
|
/** Knowledge difficulty: domain expertise required (0-1) */
|
|
5366
|
-
knowledge:
|
|
5337
|
+
knowledge: z6.number().min(0).max(1),
|
|
5367
5338
|
/** Creativity difficulty: novel generation, open-endedness (0-1) */
|
|
5368
|
-
creativity:
|
|
5339
|
+
creativity: z6.number().min(0).max(1),
|
|
5369
5340
|
/** Precision difficulty: accuracy requirements, error tolerance (0-1) */
|
|
5370
|
-
precision:
|
|
5341
|
+
precision: z6.number().min(0).max(1),
|
|
5371
5342
|
/** Context length difficulty: amount of context to process (0-1) */
|
|
5372
|
-
context_length:
|
|
5343
|
+
context_length: z6.number().min(0).max(1)
|
|
5373
5344
|
});
|
|
5374
5345
|
var DEFAULT_DIFFICULTY_THRESHOLDS = {
|
|
5375
5346
|
easyUpperBound: 0.3,
|
|
@@ -5385,12 +5356,12 @@ var DEFAULT_TIER_TO_CLIS = {
|
|
|
5385
5356
|
balanced: ["codex", "opencode", "gemini", "claude"],
|
|
5386
5357
|
powerful: ["claude", "codex", "opencode", "gemini"]
|
|
5387
5358
|
};
|
|
5388
|
-
var DifficultyWeightsSchema =
|
|
5389
|
-
reasoning:
|
|
5390
|
-
knowledge:
|
|
5391
|
-
creativity:
|
|
5392
|
-
precision:
|
|
5393
|
-
context_length:
|
|
5359
|
+
var DifficultyWeightsSchema = z6.object({
|
|
5360
|
+
reasoning: z6.number().min(0).max(1),
|
|
5361
|
+
knowledge: z6.number().min(0).max(1),
|
|
5362
|
+
creativity: z6.number().min(0).max(1),
|
|
5363
|
+
precision: z6.number().min(0).max(1),
|
|
5364
|
+
context_length: z6.number().min(0).max(1)
|
|
5394
5365
|
});
|
|
5395
5366
|
var DEFAULT_DIFFICULTY_WEIGHTS = {
|
|
5396
5367
|
reasoning: 0.3,
|
|
@@ -5399,29 +5370,29 @@ var DEFAULT_DIFFICULTY_WEIGHTS = {
|
|
|
5399
5370
|
precision: 0.25,
|
|
5400
5371
|
context_length: 0.15
|
|
5401
5372
|
};
|
|
5402
|
-
var ZeroRouterConfigSchema =
|
|
5373
|
+
var ZeroRouterConfigSchema = z6.object({
|
|
5403
5374
|
/** Difficulty thresholds for level classification */
|
|
5404
|
-
thresholds:
|
|
5405
|
-
easyUpperBound:
|
|
5406
|
-
hardLowerBound:
|
|
5375
|
+
thresholds: z6.object({
|
|
5376
|
+
easyUpperBound: z6.number().min(0).max(1),
|
|
5377
|
+
hardLowerBound: z6.number().min(0).max(1)
|
|
5407
5378
|
}).default(DEFAULT_DIFFICULTY_THRESHOLDS),
|
|
5408
5379
|
/** Weights for difficulty aggregation */
|
|
5409
5380
|
weights: DifficultyWeightsSchema.default(DEFAULT_DIFFICULTY_WEIGHTS),
|
|
5410
5381
|
/** Mapping from difficulty level to model tier */
|
|
5411
|
-
difficultyToTier:
|
|
5382
|
+
difficultyToTier: z6.record(z6.enum(["easy", "medium", "hard"]), z6.enum(["fast", "balanced", "powerful"])).default(DEFAULT_DIFFICULTY_TO_TIER),
|
|
5412
5383
|
/** Mapping from model tier to CLI preference order */
|
|
5413
|
-
tierToClis:
|
|
5414
|
-
|
|
5415
|
-
|
|
5384
|
+
tierToClis: z6.record(
|
|
5385
|
+
z6.enum(["fast", "balanced", "powerful"]),
|
|
5386
|
+
z6.array(z6.enum(["claude", "gemini", "codex", "opencode"]))
|
|
5416
5387
|
).default(DEFAULT_TIER_TO_CLIS),
|
|
5417
5388
|
/** Enable adaptive calibration from outcomes */
|
|
5418
|
-
enableCalibration:
|
|
5389
|
+
enableCalibration: z6.boolean().default(true),
|
|
5419
5390
|
/** Maximum outcomes to store for calibration */
|
|
5420
|
-
maxCalibrationOutcomes:
|
|
5391
|
+
maxCalibrationOutcomes: z6.number().int().positive().default(1e3),
|
|
5421
5392
|
/** Minimum outcomes before applying calibration adjustments */
|
|
5422
|
-
minCalibrationOutcomes:
|
|
5393
|
+
minCalibrationOutcomes: z6.number().int().positive().default(50),
|
|
5423
5394
|
/** Verbose logging */
|
|
5424
|
-
verbose:
|
|
5395
|
+
verbose: z6.boolean().default(false)
|
|
5425
5396
|
});
|
|
5426
5397
|
var DEFAULT_ZERO_ROUTER_CONFIG = {
|
|
5427
5398
|
thresholds: DEFAULT_DIFFICULTY_THRESHOLDS,
|
|
@@ -5945,16 +5916,16 @@ var ZeroRouter = class {
|
|
|
5945
5916
|
};
|
|
5946
5917
|
|
|
5947
5918
|
// src/cli-adapters/latency-tracker-types.ts
|
|
5948
|
-
import { z as
|
|
5949
|
-
var LatencyTrackerConfigSchema =
|
|
5919
|
+
import { z as z7 } from "zod";
|
|
5920
|
+
var LatencyTrackerConfigSchema = z7.object({
|
|
5950
5921
|
/** Maximum number of samples to keep per CLI (default: 100) */
|
|
5951
|
-
windowSize:
|
|
5922
|
+
windowSize: z7.number().int().positive().default(100),
|
|
5952
5923
|
/** Time-weighted decay factor (0-1, higher = more weight to recent) (default: 0.95) */
|
|
5953
|
-
decayFactor:
|
|
5924
|
+
decayFactor: z7.number().min(0).max(1).default(0.95),
|
|
5954
5925
|
/** Maximum age of samples in milliseconds before forced eviction (default: 3600000 = 1 hour) */
|
|
5955
|
-
maxSampleAgeMs:
|
|
5926
|
+
maxSampleAgeMs: z7.number().int().positive().default(36e5),
|
|
5956
5927
|
/** Percentiles to calculate (default: [50, 95, 99]) */
|
|
5957
|
-
percentiles:
|
|
5928
|
+
percentiles: z7.array(z7.number().min(0).max(100)).default([50, 95, 99])
|
|
5958
5929
|
});
|
|
5959
5930
|
var EMPTY_LATENCY_STATS = {
|
|
5960
5931
|
count: 0,
|
|
@@ -6188,192 +6159,20 @@ var LatencyTracker = class {
|
|
|
6188
6159
|
}
|
|
6189
6160
|
};
|
|
6190
6161
|
|
|
6191
|
-
// src/context/routing-memory.ts
|
|
6192
|
-
var DEFAULT_ROUTING_MEMORY_CONFIG = {
|
|
6193
|
-
minObservations: 5,
|
|
6194
|
-
confidenceThreshold: 0.6,
|
|
6195
|
-
successRateThreshold: 0.7,
|
|
6196
|
-
actionCacheMaxAgeMs: 36e5
|
|
6197
|
-
// 1 hour
|
|
6198
|
-
};
|
|
6199
|
-
var RoutingMemory = class {
|
|
6200
|
-
mobimem;
|
|
6201
|
-
config;
|
|
6202
|
-
logger;
|
|
6203
|
-
// Statistics
|
|
6204
|
-
cacheHits = 0;
|
|
6205
|
-
cacheMisses = 0;
|
|
6206
|
-
recommendationsMade = 0;
|
|
6207
|
-
constructor(config, mobimem) {
|
|
6208
|
-
this.config = { ...DEFAULT_ROUTING_MEMORY_CONFIG, ...config };
|
|
6209
|
-
this.logger = this.config.logger ?? createLogger({ component: "RoutingMemory" });
|
|
6210
|
-
this.mobimem = mobimem ?? new MobiMem();
|
|
6211
|
-
this.logger.info("RoutingMemory initialized", {
|
|
6212
|
-
minObservations: this.config.minObservations,
|
|
6213
|
-
confidenceThreshold: this.config.confidenceThreshold
|
|
6214
|
-
});
|
|
6215
|
-
}
|
|
6216
|
-
storePreference(model, taskType, performance2) {
|
|
6217
|
-
const preferenceKey = `model_preference:${taskType}`;
|
|
6218
|
-
const entityId = `routing:${model}`;
|
|
6219
|
-
const entry = this.mobimem.profile.observe(entityId, "agent", preferenceKey, {
|
|
6220
|
-
model,
|
|
6221
|
-
performance: performance2,
|
|
6222
|
-
updatedAt: getTimeProvider().nowIso()
|
|
6223
|
-
});
|
|
6224
|
-
this.logger.debug("Stored model preference", {
|
|
6225
|
-
model,
|
|
6226
|
-
taskType,
|
|
6227
|
-
confidence: entry.confidence,
|
|
6228
|
-
observations: entry.observationCount
|
|
6229
|
-
});
|
|
6230
|
-
}
|
|
6231
|
-
getPreferences(taskType) {
|
|
6232
|
-
const preferenceKey = `model_preference:${taskType}`;
|
|
6233
|
-
const preferences = [];
|
|
6234
|
-
for (const model of CLI_NAMES) {
|
|
6235
|
-
const entityId = `routing:${model}`;
|
|
6236
|
-
const entry = this.mobimem.profile.getPreference(entityId, preferenceKey);
|
|
6237
|
-
if (entry !== null && entry.observationCount >= this.config.minObservations) {
|
|
6238
|
-
const value = entry.preferenceValue;
|
|
6239
|
-
preferences.push({
|
|
6240
|
-
model: value.model,
|
|
6241
|
-
strength: this.calculateStrength(value.performance),
|
|
6242
|
-
performance: value.performance,
|
|
6243
|
-
confidence: entry.confidence
|
|
6244
|
-
});
|
|
6245
|
-
}
|
|
6246
|
-
}
|
|
6247
|
-
return preferences.sort((a, b) => b.strength - a.strength);
|
|
6248
|
-
}
|
|
6249
|
-
recordExperience(workflow, models, success, metrics2) {
|
|
6250
|
-
const contextSignature = models.join("->");
|
|
6251
|
-
const actionSequence = models.map((model, index) => ({
|
|
6252
|
-
index,
|
|
6253
|
-
actionType: "model_route",
|
|
6254
|
-
parameters: { model },
|
|
6255
|
-
durationMs: Math.floor(metrics2.durationMs / models.length),
|
|
6256
|
-
success
|
|
6257
|
-
}));
|
|
6258
|
-
const outcome = metrics2.qualityScore !== void 0 ? {
|
|
6259
|
-
success,
|
|
6260
|
-
qualityScore: metrics2.qualityScore,
|
|
6261
|
-
totalDurationMs: metrics2.durationMs,
|
|
6262
|
-
tokensUsed: metrics2.tokensUsed
|
|
6263
|
-
} : {
|
|
6264
|
-
success,
|
|
6265
|
-
totalDurationMs: metrics2.durationMs,
|
|
6266
|
-
tokensUsed: metrics2.tokensUsed
|
|
6267
|
-
};
|
|
6268
|
-
this.mobimem.experience.recordExecution(workflow, actionSequence, outcome, contextSignature);
|
|
6269
|
-
this.logger.debug("Recorded routing experience", {
|
|
6270
|
-
workflow,
|
|
6271
|
-
models: models.join("->"),
|
|
6272
|
-
success,
|
|
6273
|
-
durationMs: metrics2.durationMs
|
|
6274
|
-
});
|
|
6275
|
-
}
|
|
6276
|
-
getExperiencePatterns(workflow) {
|
|
6277
|
-
const experiences = this.mobimem.experience.findPatterns(workflow);
|
|
6278
|
-
return experiences.filter((exp) => exp.successRate >= this.config.successRateThreshold).map((exp) => this.mapExperienceToPattern(exp));
|
|
6279
|
-
}
|
|
6280
|
-
cacheAction(action, model, result, durationMs2) {
|
|
6281
|
-
const input = { actionSignature: action, model };
|
|
6282
|
-
this.mobimem.action.cache(input, result, durationMs2);
|
|
6283
|
-
this.logger.debug("Cached action result", { action: action.slice(0, 50), model, durationMs: durationMs2 });
|
|
6284
|
-
}
|
|
6285
|
-
getCachedAction(action) {
|
|
6286
|
-
for (const model of CLI_NAMES) {
|
|
6287
|
-
const input = { actionSignature: action, model };
|
|
6288
|
-
const entry = this.mobimem.action.get(input);
|
|
6289
|
-
if (entry !== null) {
|
|
6290
|
-
this.cacheHits++;
|
|
6291
|
-
const inputData = entry.input;
|
|
6292
|
-
return {
|
|
6293
|
-
action,
|
|
6294
|
-
result: entry.result,
|
|
6295
|
-
model: inputData.model,
|
|
6296
|
-
cachedAt: entry.cachedAt,
|
|
6297
|
-
timeSavedMs: entry.timeSavedMs
|
|
6298
|
-
};
|
|
6299
|
-
}
|
|
6300
|
-
}
|
|
6301
|
-
this.cacheMisses++;
|
|
6302
|
-
return void 0;
|
|
6303
|
-
}
|
|
6304
|
-
getRecommendation(taskType) {
|
|
6305
|
-
const preferences = this.getPreferences(taskType);
|
|
6306
|
-
const top = preferences[0];
|
|
6307
|
-
if (top !== void 0 && top.confidence >= this.config.confidenceThreshold) {
|
|
6308
|
-
this.recommendationsMade++;
|
|
6309
|
-
this.logger.debug("Generated routing recommendation", {
|
|
6310
|
-
taskType,
|
|
6311
|
-
recommended: top.model,
|
|
6312
|
-
confidence: top.confidence,
|
|
6313
|
-
strength: top.strength
|
|
6314
|
-
});
|
|
6315
|
-
return top.model;
|
|
6316
|
-
}
|
|
6317
|
-
return void 0;
|
|
6318
|
-
}
|
|
6319
|
-
getStats() {
|
|
6320
|
-
const mobiStats = this.mobimem.getStats();
|
|
6321
|
-
return {
|
|
6322
|
-
totalPreferences: mobiStats.profile.totalEntries,
|
|
6323
|
-
totalExperiences: mobiStats.experience.totalPatterns,
|
|
6324
|
-
cacheHits: this.cacheHits,
|
|
6325
|
-
cacheMisses: this.cacheMisses,
|
|
6326
|
-
recommendationsMade: this.recommendationsMade
|
|
6327
|
-
};
|
|
6328
|
-
}
|
|
6329
|
-
// ========================================================================
|
|
6330
|
-
// Private Helpers
|
|
6331
|
-
// ========================================================================
|
|
6332
|
-
/**
|
|
6333
|
-
* Calculate preference strength from performance metrics.
|
|
6334
|
-
*/
|
|
6335
|
-
calculateStrength(performance2) {
|
|
6336
|
-
const qualityWeight = 0.4;
|
|
6337
|
-
const successWeight = 0.3;
|
|
6338
|
-
const speedWeight = 0.2;
|
|
6339
|
-
const efficiencyWeight = 0.1;
|
|
6340
|
-
const normalizedLatency = 1 - Math.min(performance2.avgLatencyMs / 1e4, 1);
|
|
6341
|
-
const normalizedTokens = 1 - Math.min(performance2.avgTokens / 1e5, 1);
|
|
6342
|
-
return performance2.avgQuality * qualityWeight + performance2.successRate * successWeight + normalizedLatency * speedWeight + normalizedTokens * efficiencyWeight;
|
|
6343
|
-
}
|
|
6344
|
-
/**
|
|
6345
|
-
* Map MobiMem experience entry to routing pattern.
|
|
6346
|
-
*/
|
|
6347
|
-
mapExperienceToPattern(exp) {
|
|
6348
|
-
const models = exp.actionSequence.filter((step) => step.actionType === "model_route").map((step) => step.parameters.model);
|
|
6349
|
-
const avgDuration = exp.outcome.totalDurationMs;
|
|
6350
|
-
return {
|
|
6351
|
-
workflow: exp.taskType,
|
|
6352
|
-
modelSequence: models,
|
|
6353
|
-
successRate: exp.successRate,
|
|
6354
|
-
avgDurationMs: avgDuration,
|
|
6355
|
-
usageCount: exp.attemptCount
|
|
6356
|
-
};
|
|
6357
|
-
}
|
|
6358
|
-
};
|
|
6359
|
-
function createRoutingMemory(config, mobimem) {
|
|
6360
|
-
return new RoutingMemory(config, mobimem);
|
|
6361
|
-
}
|
|
6362
|
-
|
|
6363
6162
|
// src/cli-adapters/routing/router-stage.ts
|
|
6364
|
-
import { z as
|
|
6365
|
-
var StageConfigSchema =
|
|
6366
|
-
enabled:
|
|
6367
|
-
priority:
|
|
6368
|
-
options:
|
|
6163
|
+
import { z as z8 } from "zod";
|
|
6164
|
+
var StageConfigSchema = z8.object({
|
|
6165
|
+
enabled: z8.boolean().default(true),
|
|
6166
|
+
priority: z8.number().int().min(0).max(100).default(50),
|
|
6167
|
+
options: z8.record(z8.string(), z8.unknown()).optional()
|
|
6369
6168
|
});
|
|
6370
|
-
var RoutingOutcomeSchema =
|
|
6169
|
+
var RoutingOutcomeSchema = z8.object({
|
|
6371
6170
|
selectedCli: CliNameSchema,
|
|
6372
|
-
task:
|
|
6373
|
-
success:
|
|
6374
|
-
qualityScore:
|
|
6375
|
-
latencyMs:
|
|
6376
|
-
tokensUsed:
|
|
6171
|
+
task: z8.string(),
|
|
6172
|
+
success: z8.boolean(),
|
|
6173
|
+
qualityScore: z8.number().min(0).max(1).optional(),
|
|
6174
|
+
latencyMs: z8.number().int().positive().optional(),
|
|
6175
|
+
tokensUsed: z8.number().int().positive().optional()
|
|
6377
6176
|
});
|
|
6378
6177
|
function createRoutingContext(task, availableClis = ["claude", "gemini", "codex", "opencode"], metadata) {
|
|
6379
6178
|
return {
|
|
@@ -6570,7 +6369,7 @@ var ConfidenceCascadeStage = class {
|
|
|
6570
6369
|
};
|
|
6571
6370
|
|
|
6572
6371
|
// src/config/task-specialization-types.ts
|
|
6573
|
-
import { z as
|
|
6372
|
+
import { z as z9 } from "zod";
|
|
6574
6373
|
var TASK_CATEGORIES = [
|
|
6575
6374
|
"architecture",
|
|
6576
6375
|
"code_generation",
|
|
@@ -6583,8 +6382,8 @@ var TASK_CATEGORIES = [
|
|
|
6583
6382
|
"devops",
|
|
6584
6383
|
"exploration"
|
|
6585
6384
|
];
|
|
6586
|
-
var TaskCategorySchema =
|
|
6587
|
-
var TaskSpecializationSchema =
|
|
6385
|
+
var TaskCategorySchema = z9.enum(TASK_CATEGORIES);
|
|
6386
|
+
var TaskSpecializationSchema = z9.object({
|
|
6588
6387
|
/** Task category identifier */
|
|
6589
6388
|
category: TaskCategorySchema,
|
|
6590
6389
|
/** Primary CLI recommendation */
|
|
@@ -6592,11 +6391,11 @@ var TaskSpecializationSchema = z10.object({
|
|
|
6592
6391
|
/** Secondary CLI fallback */
|
|
6593
6392
|
secondaryCli: CliNameSchema,
|
|
6594
6393
|
/** Why this CLI is preferred for this task type */
|
|
6595
|
-
reasoning:
|
|
6394
|
+
reasoning: z9.string(),
|
|
6596
6395
|
/** Keywords that trigger this category detection */
|
|
6597
|
-
keywords:
|
|
6396
|
+
keywords: z9.array(z9.string()).min(1),
|
|
6598
6397
|
/** Bonus score applied when this category matches (0-20) */
|
|
6599
|
-
bonus:
|
|
6398
|
+
bonus: z9.number().min(0).max(20)
|
|
6600
6399
|
});
|
|
6601
6400
|
|
|
6602
6401
|
// src/config/task-specialization.ts
|
|
@@ -7819,10 +7618,10 @@ function createPersistentDistillerOrFallback(outcomeStore, logger11) {
|
|
|
7819
7618
|
}
|
|
7820
7619
|
|
|
7821
7620
|
// src/orchestration/outcomes/outcome-types.ts
|
|
7822
|
-
import { z as
|
|
7621
|
+
import { z as z10 } from "zod";
|
|
7823
7622
|
var logger6 = createLogger({ component: "outcome-error-taxonomy" });
|
|
7824
|
-
var OutcomeSourceSchema =
|
|
7825
|
-
var OutcomeFailureCategorySchema =
|
|
7623
|
+
var OutcomeSourceSchema = z10.enum(["delegate", "consensus", "manual"]);
|
|
7624
|
+
var OutcomeFailureCategorySchema = z10.enum([
|
|
7826
7625
|
"timeout",
|
|
7827
7626
|
"authentication",
|
|
7828
7627
|
"rate_limit",
|
|
@@ -7835,47 +7634,58 @@ var OutcomeFailureCategorySchema = z11.enum([
|
|
|
7835
7634
|
"generic",
|
|
7836
7635
|
"unknown"
|
|
7837
7636
|
]);
|
|
7838
|
-
var TaskOutcomeSchema =
|
|
7839
|
-
id:
|
|
7637
|
+
var TaskOutcomeSchema = z10.object({
|
|
7638
|
+
id: z10.string().min(1),
|
|
7840
7639
|
cli: CliNameSchema,
|
|
7841
7640
|
category: TaskCategorySchema,
|
|
7842
|
-
model:
|
|
7843
|
-
success:
|
|
7844
|
-
durationMs:
|
|
7845
|
-
timestamp:
|
|
7846
|
-
qualitySignals:
|
|
7641
|
+
model: z10.string().min(1),
|
|
7642
|
+
success: z10.boolean(),
|
|
7643
|
+
durationMs: z10.number().nonnegative(),
|
|
7644
|
+
timestamp: z10.string().min(1),
|
|
7645
|
+
qualitySignals: z10.array(z10.string()).optional(),
|
|
7847
7646
|
failureCategory: OutcomeFailureCategorySchema.optional(),
|
|
7848
|
-
errorMessage:
|
|
7647
|
+
errorMessage: z10.string().max(500).optional(),
|
|
7849
7648
|
source: OutcomeSourceSchema,
|
|
7850
7649
|
/** Whether this outcome came from a triage-initiated retry (#1506). */
|
|
7851
|
-
wasRetried:
|
|
7650
|
+
wasRetried: z10.boolean().optional(),
|
|
7852
7651
|
/** Triage action taken on the failure (#1506). */
|
|
7853
|
-
triageAction:
|
|
7652
|
+
triageAction: z10.string().max(30).optional(),
|
|
7854
7653
|
/** Routing stage that selected this CLI (#1785). */
|
|
7855
|
-
routingStage:
|
|
7654
|
+
routingStage: z10.string().max(50).optional(),
|
|
7856
7655
|
/** Number of retry attempts before this outcome (#1785). */
|
|
7857
|
-
retryCount:
|
|
7656
|
+
retryCount: z10.number().int().nonnegative().optional(),
|
|
7858
7657
|
/** Vendor resolved from `model` via ModelRegistry at write time (#2548). */
|
|
7859
|
-
vendor:
|
|
7658
|
+
vendor: z10.string().min(1).max(40).optional(),
|
|
7860
7659
|
/** Family resolved from `model` via ModelRegistry at write time (#2548). */
|
|
7861
|
-
family:
|
|
7660
|
+
family: z10.string().min(1).max(80).optional(),
|
|
7862
7661
|
/**
|
|
7863
7662
|
* Voter role for `source: 'consensus'` outcomes (#2662) — `architect`,
|
|
7864
7663
|
* `security`, etc. Absent on non-consensus outcomes. Lets the
|
|
7865
7664
|
* stratified outcome report break results down by voter role.
|
|
7866
7665
|
*/
|
|
7867
|
-
voterRole:
|
|
7666
|
+
voterRole: z10.string().min(1).max(40).optional(),
|
|
7667
|
+
/**
|
|
7668
|
+
* Baseline this outcome forked from (#2697 / Epic F follow-up to #2665).
|
|
7669
|
+
* Set on outcomes recorded inside a fork-then-merge graph branch so
|
|
7670
|
+
* `query({ baselineId: 'B' })` returns every branch outcome forked
|
|
7671
|
+
* from baseline B — letting later analysis compare branches as a
|
|
7672
|
+
* cohort. Free-form string (caller-assigned); typically the parent
|
|
7673
|
+
* node's `executionId` or `taskId`.
|
|
7674
|
+
*/
|
|
7675
|
+
baselineId: z10.string().min(1).max(64).optional()
|
|
7868
7676
|
});
|
|
7869
|
-
var OutcomeQuerySchema =
|
|
7677
|
+
var OutcomeQuerySchema = z10.object({
|
|
7870
7678
|
cli: CliNameSchema.optional(),
|
|
7871
7679
|
category: TaskCategorySchema.optional(),
|
|
7872
7680
|
source: OutcomeSourceSchema.optional(),
|
|
7873
|
-
success:
|
|
7681
|
+
success: z10.boolean().optional(),
|
|
7874
7682
|
failureCategory: OutcomeFailureCategorySchema.optional(),
|
|
7875
|
-
since:
|
|
7876
|
-
limit:
|
|
7683
|
+
since: z10.string().optional(),
|
|
7684
|
+
limit: z10.number().int().positive().optional(),
|
|
7877
7685
|
/** Exclude outcomes with any of these quality signals (#1680). */
|
|
7878
|
-
excludeQualitySignals:
|
|
7686
|
+
excludeQualitySignals: z10.array(z10.string()).optional(),
|
|
7687
|
+
/** Restrict to outcomes recorded against a specific baseline (#2697). */
|
|
7688
|
+
baselineId: z10.string().min(1).max(64).optional()
|
|
7879
7689
|
});
|
|
7880
7690
|
var TIMEOUT_PATTERNS = ["timeout", "timed out", "deadline exceeded", "socket hang up", "aborted"];
|
|
7881
7691
|
var AUTH_PATTERNS = [
|
|
@@ -8245,9 +8055,18 @@ function getOutcomeStore() {
|
|
|
8245
8055
|
} else {
|
|
8246
8056
|
singletonStore = new OutcomeStore();
|
|
8247
8057
|
}
|
|
8058
|
+
void attachOutcomeStoreToRegistry(singletonStore);
|
|
8248
8059
|
}
|
|
8249
8060
|
return singletonStore;
|
|
8250
8061
|
}
|
|
8062
|
+
async function attachOutcomeStoreToRegistry(store) {
|
|
8063
|
+
try {
|
|
8064
|
+
const { getMemoryRegistry } = await import("./dist-NIXVXYIH.js");
|
|
8065
|
+
const { OutcomeStoreAdapter } = await import("./outcome-store-adapter-QRFJJIKB.js");
|
|
8066
|
+
getMemoryRegistry().attach("outcomes", new OutcomeStoreAdapter(store));
|
|
8067
|
+
} catch {
|
|
8068
|
+
}
|
|
8069
|
+
}
|
|
8251
8070
|
function resetOutcomeStore() {
|
|
8252
8071
|
singletonStore = void 0;
|
|
8253
8072
|
}
|
|
@@ -8297,6 +8116,9 @@ function buildPredicates(filter) {
|
|
|
8297
8116
|
return !signals.some((s) => excluded.has(s));
|
|
8298
8117
|
});
|
|
8299
8118
|
}
|
|
8119
|
+
if (filter.baselineId !== void 0) {
|
|
8120
|
+
preds.push((o) => o.baselineId === filter.baselineId);
|
|
8121
|
+
}
|
|
8300
8122
|
return preds;
|
|
8301
8123
|
}
|
|
8302
8124
|
function applyFilters(entries, filter) {
|
|
@@ -8494,52 +8316,52 @@ function runWarmUp(logger11) {
|
|
|
8494
8316
|
}
|
|
8495
8317
|
|
|
8496
8318
|
// src/cli-adapters/composite-router-types.ts
|
|
8497
|
-
import { z as
|
|
8498
|
-
var CompositeRouterConfigSchema =
|
|
8319
|
+
import { z as z11 } from "zod";
|
|
8320
|
+
var CompositeRouterConfigSchema = z11.object({
|
|
8499
8321
|
/** Enable confidence cascade stage (default: false) (Issue #755, ADR-0005) */
|
|
8500
|
-
enableConfidenceCascade:
|
|
8322
|
+
enableConfidenceCascade: z11.boolean().default(false),
|
|
8501
8323
|
/** Enable budget filtering stage (default: true) */
|
|
8502
|
-
enableBudgetFilter:
|
|
8324
|
+
enableBudgetFilter: z11.boolean().default(true),
|
|
8503
8325
|
/** Enable capability match stage (default: false) (Issue #755, ADR-0005) */
|
|
8504
|
-
enableCapabilityMatch:
|
|
8326
|
+
enableCapabilityMatch: z11.boolean().default(false),
|
|
8505
8327
|
/** Enable ZeroRouter difficulty-based routing stage (default: true) (Issue #473) */
|
|
8506
|
-
enableZeroRouter:
|
|
8328
|
+
enableZeroRouter: z11.boolean().default(true),
|
|
8507
8329
|
/** Enable preference-trained routing stage (default: false) */
|
|
8508
|
-
enablePreferenceRouting:
|
|
8330
|
+
enablePreferenceRouting: z11.boolean().default(false),
|
|
8509
8331
|
/** Enable TOPSIS ranking stage (default: true) */
|
|
8510
|
-
enableTopsisRanking:
|
|
8332
|
+
enableTopsisRanking: z11.boolean().default(true),
|
|
8511
8333
|
/** Enable LinUCB selection stage (default: true) */
|
|
8512
|
-
enableLinUCBSelection:
|
|
8334
|
+
enableLinUCBSelection: z11.boolean().default(true),
|
|
8513
8335
|
/** Enable quality constraint stage (default: false) (Issue #755, ADR-0005) */
|
|
8514
|
-
enableQualityConstraint:
|
|
8336
|
+
enableQualityConstraint: z11.boolean().default(false),
|
|
8515
8337
|
/** Enable resource strategy stage for budget-aware oscillation (default: true) (Issue #998) */
|
|
8516
|
-
enableResourceStrategy:
|
|
8338
|
+
enableResourceStrategy: z11.boolean().default(true),
|
|
8517
8339
|
/** Enable strategy distillation for learned routing rules (default: false) (Issue #999) */
|
|
8518
|
-
enableStrategyDistillation:
|
|
8340
|
+
enableStrategyDistillation: z11.boolean().default(false),
|
|
8519
8341
|
/** Enable latency tracking for routing decisions (default: true) (Issue #361) */
|
|
8520
|
-
enableLatencyTracking:
|
|
8342
|
+
enableLatencyTracking: z11.boolean().default(true),
|
|
8521
8343
|
/** Enable routing memory for learned routing (default: false) (Issue #463, #461) */
|
|
8522
|
-
enableRoutingMemory:
|
|
8523
|
-
/** Enable KNN experience-based routing (default: false) (arXiv:
|
|
8524
|
-
enableKnnRouting:
|
|
8344
|
+
enableRoutingMemory: z11.boolean().default(false),
|
|
8345
|
+
/** Enable KNN experience-based routing (default: false) (arXiv:2505.12601) */
|
|
8346
|
+
enableKnnRouting: z11.boolean().default(false),
|
|
8525
8347
|
/** Weight for latency score in final routing (0-1, default: 0.2) */
|
|
8526
|
-
latencyScoreWeight:
|
|
8348
|
+
latencyScoreWeight: z11.number().min(0).max(1).default(0.2),
|
|
8527
8349
|
/** Budget constraints (optional) */
|
|
8528
|
-
budgetConstraints:
|
|
8529
|
-
maxTokens:
|
|
8530
|
-
maxCostUsd:
|
|
8531
|
-
maxLatencyMs:
|
|
8350
|
+
budgetConstraints: z11.object({
|
|
8351
|
+
maxTokens: z11.number().positive(),
|
|
8352
|
+
maxCostUsd: z11.number().positive(),
|
|
8353
|
+
maxLatencyMs: z11.number().positive()
|
|
8532
8354
|
}).partial().optional(),
|
|
8533
8355
|
/** LinUCB exploration parameter (default: 1.0) */
|
|
8534
|
-
linucbAlpha:
|
|
8356
|
+
linucbAlpha: z11.number().positive().default(1),
|
|
8535
8357
|
/** Billing mode: 'plan' zeroes cost weight, 'api' preserves current behavior (default: 'plan') */
|
|
8536
|
-
billingMode:
|
|
8358
|
+
billingMode: z11.enum(["plan", "api"]).default("plan"),
|
|
8537
8359
|
/** Enable capacity-aware load balancing (deprioritize exhausted CLIs) (default: true) (Issue #807) */
|
|
8538
|
-
enableCapacityBalancing:
|
|
8360
|
+
enableCapacityBalancing: z11.boolean().default(true),
|
|
8539
8361
|
/** Maximum routing decision time in ms (default: 50) */
|
|
8540
|
-
maxDecisionTimeMs:
|
|
8362
|
+
maxDecisionTimeMs: z11.number().positive().default(50),
|
|
8541
8363
|
/** Minimum preference data points before using learned routing (default: 10) */
|
|
8542
|
-
preferenceMinDataPoints:
|
|
8364
|
+
preferenceMinDataPoints: z11.number().int().positive().default(10)
|
|
8543
8365
|
});
|
|
8544
8366
|
var DEFAULT_COMPOSITE_CONFIG = {
|
|
8545
8367
|
enableConfidenceCascade: false,
|
|
@@ -8561,7 +8383,7 @@ var DEFAULT_COMPOSITE_CONFIG = {
|
|
|
8561
8383
|
enableLatencyTracking: true,
|
|
8562
8384
|
enableRoutingMemory: false,
|
|
8563
8385
|
enableKnnRouting: false,
|
|
8564
|
-
// arXiv:
|
|
8386
|
+
// arXiv:2505.12601 - KNN experience-based routing
|
|
8565
8387
|
enableCapacityBalancing: true,
|
|
8566
8388
|
// Issue #807 - Deprioritize exhausted CLIs
|
|
8567
8389
|
latencyScoreWeight: 0.2,
|
|
@@ -8823,12 +8645,12 @@ async function fetchCapacityData(adapters) {
|
|
|
8823
8645
|
}
|
|
8824
8646
|
|
|
8825
8647
|
// src/mcp/tools/weather-report-types.ts
|
|
8826
|
-
import { z as
|
|
8827
|
-
var WeatherReportInputSchema =
|
|
8648
|
+
import { z as z12 } from "zod";
|
|
8649
|
+
var WeatherReportInputSchema = z12.object({
|
|
8828
8650
|
/** Filter by CLI name. */
|
|
8829
|
-
cli:
|
|
8651
|
+
cli: z12.enum(CLI_NAMES).optional().describe("Filter by CLI"),
|
|
8830
8652
|
/** Filter by task category. */
|
|
8831
|
-
category:
|
|
8653
|
+
category: z12.enum([
|
|
8832
8654
|
"architecture",
|
|
8833
8655
|
"code_generation",
|
|
8834
8656
|
"code_review",
|
|
@@ -8841,22 +8663,22 @@ var WeatherReportInputSchema = z13.object({
|
|
|
8841
8663
|
"exploration"
|
|
8842
8664
|
]).optional().describe("Filter by task category"),
|
|
8843
8665
|
/** Include adaptive routing bonus data. */
|
|
8844
|
-
includeAdaptive:
|
|
8666
|
+
includeAdaptive: z12.boolean().optional().default(true).describe("Include adaptive routing bonuses (default: true)")
|
|
8845
8667
|
});
|
|
8846
8668
|
var DEFAULT_OUTCOME_LOOKBACK_MS = 7 * 24 * 60 * 60 * 1e3;
|
|
8847
|
-
var WeatherReportConfigSchema =
|
|
8669
|
+
var WeatherReportConfigSchema = z12.object({
|
|
8848
8670
|
/** Minimum observations before adjusting bonuses (lowered for faster activation). */
|
|
8849
|
-
coldStartThreshold:
|
|
8671
|
+
coldStartThreshold: z12.number().int().min(1).max(1e3).default(3),
|
|
8850
8672
|
/** Exploration rate: fraction of random routing (0.0-1.0). */
|
|
8851
|
-
explorationRate:
|
|
8673
|
+
explorationRate: z12.number().min(0).max(1).default(0.1),
|
|
8852
8674
|
/** Max adaptive bonus adjustment (+/-). */
|
|
8853
|
-
maxBonusAdjustment:
|
|
8675
|
+
maxBonusAdjustment: z12.number().min(0).max(20).default(10),
|
|
8854
8676
|
/**
|
|
8855
8677
|
* Lookback window for outcome queries (ms). Only outcomes within this
|
|
8856
8678
|
* window are used for adaptive bonuses. Falls back to all history if
|
|
8857
8679
|
* the window has fewer samples than coldStartThreshold. Default: 7 days.
|
|
8858
8680
|
*/
|
|
8859
|
-
outcomeLookbackMs:
|
|
8681
|
+
outcomeLookbackMs: z12.number().int().min(0).default(DEFAULT_OUTCOME_LOOKBACK_MS)
|
|
8860
8682
|
});
|
|
8861
8683
|
function createDefaultWeatherConfig() {
|
|
8862
8684
|
return WeatherReportConfigSchema.parse({});
|
|
@@ -9241,47 +9063,47 @@ function createMetricsMiddleware() {
|
|
|
9241
9063
|
import { randomBytes as randomBytes3 } from "crypto";
|
|
9242
9064
|
|
|
9243
9065
|
// src/config/defaults-types.ts
|
|
9244
|
-
import { z as
|
|
9066
|
+
import { z as z13 } from "zod";
|
|
9245
9067
|
function isKnownCliName(cli) {
|
|
9246
9068
|
return cli === "claude" || cli === "gemini" || cli === "codex" || cli === "opencode" || cli === "default";
|
|
9247
9069
|
}
|
|
9248
|
-
var positiveInt =
|
|
9249
|
-
var nonNegativeInt =
|
|
9250
|
-
var durationMs =
|
|
9251
|
-
var TimeoutProfileSchema =
|
|
9070
|
+
var positiveInt = z13.number().int().positive();
|
|
9071
|
+
var nonNegativeInt = z13.number().int().nonnegative();
|
|
9072
|
+
var durationMs = z13.number().int().positive().describe("Duration in milliseconds");
|
|
9073
|
+
var TimeoutProfileSchema = z13.object({
|
|
9252
9074
|
simple: durationMs.describe("Timeout for simple tasks"),
|
|
9253
9075
|
standard: durationMs.describe("Timeout for standard tasks"),
|
|
9254
9076
|
complex: durationMs.describe("Timeout for complex tasks")
|
|
9255
9077
|
});
|
|
9256
|
-
var RetryDefaultsSchema =
|
|
9078
|
+
var RetryDefaultsSchema = z13.object({
|
|
9257
9079
|
maxRetries: nonNegativeInt.max(10).describe("Maximum retry attempts"),
|
|
9258
9080
|
baseDelayMs: durationMs.describe("Base delay between retries"),
|
|
9259
9081
|
maxDelayMs: durationMs.describe("Maximum delay between retries"),
|
|
9260
|
-
jitterFactor:
|
|
9082
|
+
jitterFactor: z13.number().min(0).max(1).describe("Jitter factor (0-1)")
|
|
9261
9083
|
});
|
|
9262
|
-
var RateLimitDefaultsSchema =
|
|
9084
|
+
var RateLimitDefaultsSchema = z13.object({
|
|
9263
9085
|
requestsPerMinute: positiveInt.max(1e3).describe("Max requests per minute"),
|
|
9264
|
-
enabled:
|
|
9086
|
+
enabled: z13.boolean().describe("Whether rate limiting is enabled"),
|
|
9265
9087
|
maxConcurrent: positiveInt.max(100).describe("Max concurrent requests"),
|
|
9266
9088
|
capacity: positiveInt.describe("Token bucket capacity"),
|
|
9267
9089
|
refillRate: positiveInt.describe("Token refill rate"),
|
|
9268
9090
|
refillIntervalMs: durationMs.describe("Token refill interval")
|
|
9269
9091
|
});
|
|
9270
|
-
var CircuitBreakerDefaultsSchema =
|
|
9271
|
-
failureThreshold:
|
|
9092
|
+
var CircuitBreakerDefaultsSchema = z13.object({
|
|
9093
|
+
failureThreshold: z13.number().int().min(1).max(100).describe("Failures before opening"),
|
|
9272
9094
|
resetTimeoutMs: durationMs.describe("Time before attempting reset"),
|
|
9273
|
-
halfOpenSuccessThreshold:
|
|
9274
|
-
countTimeoutsAsFailures:
|
|
9275
|
-
countAuthFailuresAsFailures:
|
|
9276
|
-
countRateLimitsAsFailures:
|
|
9095
|
+
halfOpenSuccessThreshold: z13.number().int().min(1).max(10).describe("Successes to close"),
|
|
9096
|
+
countTimeoutsAsFailures: z13.boolean().describe("Count timeouts as failures"),
|
|
9097
|
+
countAuthFailuresAsFailures: z13.boolean().describe("Count auth failures as failures"),
|
|
9098
|
+
countRateLimitsAsFailures: z13.boolean().describe("Count rate limit errors as failures"),
|
|
9277
9099
|
halfOpenMaxRequests: positiveInt.describe("Max requests in half-open state")
|
|
9278
9100
|
});
|
|
9279
|
-
var ToolRateLimitConfigSchema =
|
|
9101
|
+
var ToolRateLimitConfigSchema = z13.object({
|
|
9280
9102
|
capacity: positiveInt.describe("Token bucket capacity"),
|
|
9281
9103
|
refillRate: positiveInt.describe("Token refill rate"),
|
|
9282
9104
|
refillIntervalMs: durationMs.describe("Token refill interval")
|
|
9283
9105
|
});
|
|
9284
|
-
var WorkerDefaultsSchema =
|
|
9106
|
+
var WorkerDefaultsSchema = z13.object({
|
|
9285
9107
|
maxWorkers: positiveInt.max(32).describe("Maximum worker threads"),
|
|
9286
9108
|
poolSize: positiveInt.max(32).describe("Worker pool size"),
|
|
9287
9109
|
idleTimeoutMs: durationMs.describe("Worker idle timeout"),
|
|
@@ -9291,7 +9113,7 @@ var WorkerDefaultsSchema = z14.object({
|
|
|
9291
9113
|
eventBusMaxHistory: nonNegativeInt.max(1e4).describe("Event bus history limit"),
|
|
9292
9114
|
swarmObserverMaxEvents: nonNegativeInt.max(1e4).describe("Swarm observer event limit")
|
|
9293
9115
|
});
|
|
9294
|
-
var TimeoutDefaultsSchema =
|
|
9116
|
+
var TimeoutDefaultsSchema = z13.object({
|
|
9295
9117
|
cliMs: durationMs.describe("Default CLI timeout"),
|
|
9296
9118
|
cliSimpleMs: durationMs.describe("Simple CLI task timeout"),
|
|
9297
9119
|
cliComplexMs: durationMs.describe("Complex CLI task timeout"),
|
|
@@ -10232,9 +10054,9 @@ function convertBonusesToScoreMap(bonuses, taskCategory) {
|
|
|
10232
10054
|
}
|
|
10233
10055
|
|
|
10234
10056
|
// src/cli-adapters/fallback-chains.ts
|
|
10235
|
-
import { z as
|
|
10236
|
-
var FallbackChainSchema =
|
|
10237
|
-
var FallbackChainRegistrySchema =
|
|
10057
|
+
import { z as z14 } from "zod";
|
|
10058
|
+
var FallbackChainSchema = z14.array(z14.enum(["claude", "gemini", "codex", "opencode"])).min(1).readonly();
|
|
10059
|
+
var FallbackChainRegistrySchema = z14.object({
|
|
10238
10060
|
code: FallbackChainSchema,
|
|
10239
10061
|
research: FallbackChainSchema,
|
|
10240
10062
|
documentation: FallbackChainSchema,
|
|
@@ -10933,6 +10755,15 @@ var CompositeRouter = class _CompositeRouter {
|
|
|
10933
10755
|
linucbBandit;
|
|
10934
10756
|
latencyTracker;
|
|
10935
10757
|
routingMemory;
|
|
10758
|
+
/**
|
|
10759
|
+
* Most recently consulted unified memory context (Phase 3 of #2792).
|
|
10760
|
+
* Set on every {@link route} call so tests + telemetry can inspect what
|
|
10761
|
+
* the router saw at decision time. Typed as `unknown` here to avoid
|
|
10762
|
+
* pulling the typed surface into this module's circular-dep zone — the
|
|
10763
|
+
* field is for observability; callers that need typed reads should call
|
|
10764
|
+
* `getContextForTask` directly.
|
|
10765
|
+
*/
|
|
10766
|
+
lastUnifiedContext;
|
|
10936
10767
|
/** Metrics collector for routing observability (Issue #559) */
|
|
10937
10768
|
metricsCollector;
|
|
10938
10769
|
/** Orchestration observer for routing decision tracking (Issue #587) */
|
|
@@ -10947,7 +10778,7 @@ var CompositeRouter = class _CompositeRouter {
|
|
|
10947
10778
|
resourceStrategyStage;
|
|
10948
10779
|
/** Distilled rule stage instance (Issue #999) */
|
|
10949
10780
|
distilledRuleStage;
|
|
10950
|
-
/** KNN routing stage instance (arXiv:
|
|
10781
|
+
/** KNN routing stage instance (arXiv:2505.12601) */
|
|
10951
10782
|
knnRoutingStage;
|
|
10952
10783
|
/** Strategy distiller instance (Issue #999) */
|
|
10953
10784
|
strategyDistiller;
|
|
@@ -11134,12 +10965,40 @@ var CompositeRouter = class _CompositeRouter {
|
|
|
11134
10965
|
});
|
|
11135
10966
|
}
|
|
11136
10967
|
async route(task) {
|
|
10968
|
+
void this.consultUnifiedContext(task);
|
|
11137
10969
|
const result = await this.executeRouting(task, getTimeProvider().now());
|
|
11138
10970
|
if (result.ok) {
|
|
11139
10971
|
this.emitRoutingDecision(result.value, task.content);
|
|
11140
10972
|
}
|
|
11141
10973
|
return result;
|
|
11142
10974
|
}
|
|
10975
|
+
/**
|
|
10976
|
+
* Read the unified memory context for this task. Best-effort, never
|
|
10977
|
+
* throws. Sets `this.lastUnifiedContext` so external observers (tests,
|
|
10978
|
+
* telemetry) can inspect what the router consulted at decision time.
|
|
10979
|
+
*/
|
|
10980
|
+
async consultUnifiedContext(task) {
|
|
10981
|
+
try {
|
|
10982
|
+
const { getContextForTask, inferTaskCategory } = await import("./context-retriever-MB3D7KS6.js");
|
|
10983
|
+
const ctx = await getContextForTask({
|
|
10984
|
+
task: task.content,
|
|
10985
|
+
category: inferTaskCategory(task.content),
|
|
10986
|
+
logger: this.logger
|
|
10987
|
+
});
|
|
10988
|
+
this.lastUnifiedContext = ctx;
|
|
10989
|
+
this.logger.debug("CompositeRouter: unified memory context", {
|
|
10990
|
+
beliefs: ctx.beliefs.length,
|
|
10991
|
+
similarMemories: ctx.similarMemories.length,
|
|
10992
|
+
recentLearnings: ctx.recentLearnings.length,
|
|
10993
|
+
experiencePatterns: ctx.experiencePatterns.length,
|
|
10994
|
+
outcomesTotal: ctx.outcomes?.totalTasks ?? 0
|
|
10995
|
+
});
|
|
10996
|
+
} catch (error) {
|
|
10997
|
+
this.logger.debug("CompositeRouter: context retrieval failed", {
|
|
10998
|
+
error: error instanceof Error ? error.message : String(error)
|
|
10999
|
+
});
|
|
11000
|
+
}
|
|
11001
|
+
}
|
|
11143
11002
|
/**
|
|
11144
11003
|
* Unified method that routes, executes, and auto-records feedback.
|
|
11145
11004
|
* Use this for most cases; use route() when you need decision details without execution.
|
|
@@ -11303,7 +11162,7 @@ var CompositeRouter = class _CompositeRouter {
|
|
|
11303
11162
|
resourceStrategyStage: this.resourceStrategyStage,
|
|
11304
11163
|
// Issue #999 distilled rule stage
|
|
11305
11164
|
distilledRuleStage: this.distilledRuleStage,
|
|
11306
|
-
// arXiv:
|
|
11165
|
+
// arXiv:2505.12601 KNN routing
|
|
11307
11166
|
knnRoutingStage: this.knnRoutingStage
|
|
11308
11167
|
};
|
|
11309
11168
|
}
|
|
@@ -11506,6 +11365,38 @@ var OrchestratorError = class extends Error {
|
|
|
11506
11365
|
}
|
|
11507
11366
|
};
|
|
11508
11367
|
|
|
11368
|
+
// src/context/mobimem.ts
|
|
11369
|
+
import Database from "better-sqlite3";
|
|
11370
|
+
import { dirname as dirname3 } from "path";
|
|
11371
|
+
import { mkdirSync as mkdirSync2 } from "fs";
|
|
11372
|
+
|
|
11373
|
+
// src/context/mobimem-types.ts
|
|
11374
|
+
import { z as z15 } from "zod";
|
|
11375
|
+
var DEFAULT_MOBIMEM_CONFIG = {
|
|
11376
|
+
dbPath: ":memory:",
|
|
11377
|
+
maxProfileEntries: 100,
|
|
11378
|
+
maxExperiencePatterns: 500,
|
|
11379
|
+
maxActionCacheEntries: 1e3,
|
|
11380
|
+
actionCacheTtlMs: 36e5,
|
|
11381
|
+
// 1 hour
|
|
11382
|
+
minProfileConfidence: 0.6,
|
|
11383
|
+
minExperienceSuccessRate: 0.7,
|
|
11384
|
+
autoEviction: true
|
|
11385
|
+
};
|
|
11386
|
+
var MobiMemConfigSchema = z15.object({
|
|
11387
|
+
dbPath: z15.string(),
|
|
11388
|
+
maxProfileEntries: z15.number().int().positive().default(100),
|
|
11389
|
+
maxExperiencePatterns: z15.number().int().positive().default(500),
|
|
11390
|
+
maxActionCacheEntries: z15.number().int().positive().default(1e3),
|
|
11391
|
+
actionCacheTtlMs: z15.number().int().positive().default(36e5),
|
|
11392
|
+
minProfileConfidence: z15.number().min(0).max(1).default(0.6),
|
|
11393
|
+
minExperienceSuccessRate: z15.number().min(0).max(1).default(0.7),
|
|
11394
|
+
autoEviction: z15.boolean().default(true)
|
|
11395
|
+
});
|
|
11396
|
+
|
|
11397
|
+
// src/context/mobimem-impl.ts
|
|
11398
|
+
import { randomUUID as randomUUID4 } from "crypto";
|
|
11399
|
+
|
|
11509
11400
|
// src/context/mobimem-impl-helpers.ts
|
|
11510
11401
|
import { createHash as createHash2 } from "crypto";
|
|
11511
11402
|
function calculateConfidence2(observationCount) {
|
|
@@ -11553,12 +11444,89 @@ function computeAverage(values, valueFn) {
|
|
|
11553
11444
|
return count > 0 ? total / count : 0;
|
|
11554
11445
|
}
|
|
11555
11446
|
|
|
11447
|
+
// src/context/mobimem-persistence.ts
|
|
11448
|
+
var MobiMemPersistence = class {
|
|
11449
|
+
active;
|
|
11450
|
+
db;
|
|
11451
|
+
domain;
|
|
11452
|
+
stmts;
|
|
11453
|
+
constructor(options) {
|
|
11454
|
+
this.db = options.db;
|
|
11455
|
+
this.domain = options.domain;
|
|
11456
|
+
this.active = options.db !== null;
|
|
11457
|
+
if (!/^[a-z][a-z0-9_]{0,63}$/i.test(options.domain)) {
|
|
11458
|
+
throw new Error(
|
|
11459
|
+
`mobimem-persistence: invalid domain "${options.domain}" \u2014 must match [a-zA-Z][a-zA-Z0-9_]{0,63}`
|
|
11460
|
+
);
|
|
11461
|
+
}
|
|
11462
|
+
if (this.active && this.db !== null) {
|
|
11463
|
+
this.db.exec(`
|
|
11464
|
+
CREATE TABLE IF NOT EXISTS ${options.domain} (
|
|
11465
|
+
key TEXT PRIMARY KEY,
|
|
11466
|
+
value TEXT NOT NULL,
|
|
11467
|
+
timestamp INTEGER NOT NULL
|
|
11468
|
+
);
|
|
11469
|
+
CREATE INDEX IF NOT EXISTS ${options.domain}_timestamp ON ${options.domain}(timestamp);
|
|
11470
|
+
`);
|
|
11471
|
+
this.stmts = {
|
|
11472
|
+
upsert: this.db.prepare(
|
|
11473
|
+
`INSERT INTO ${options.domain} (key, value, timestamp) VALUES (@key, @value, @timestamp)
|
|
11474
|
+
ON CONFLICT(key) DO UPDATE SET value = excluded.value, timestamp = excluded.timestamp`
|
|
11475
|
+
),
|
|
11476
|
+
delete: this.db.prepare(`DELETE FROM ${options.domain} WHERE key = ?`),
|
|
11477
|
+
clear: this.db.prepare(`DELETE FROM ${options.domain}`),
|
|
11478
|
+
selectAll: this.db.prepare(`SELECT key, value FROM ${options.domain}`)
|
|
11479
|
+
};
|
|
11480
|
+
} else {
|
|
11481
|
+
this.stmts = null;
|
|
11482
|
+
}
|
|
11483
|
+
}
|
|
11484
|
+
/** Hydrate the impl's Map cache from SQLite. No-op when inactive. */
|
|
11485
|
+
load() {
|
|
11486
|
+
if (this.stmts === null) return [];
|
|
11487
|
+
const rows = this.stmts.selectAll.all();
|
|
11488
|
+
return rows.map((r) => [r.key, JSON.parse(r.value)]);
|
|
11489
|
+
}
|
|
11490
|
+
/** Upsert a single row. No-op when inactive. */
|
|
11491
|
+
upsert(key, value) {
|
|
11492
|
+
if (this.stmts === null) return;
|
|
11493
|
+
this.stmts.upsert.run({
|
|
11494
|
+
key,
|
|
11495
|
+
value: JSON.stringify(value),
|
|
11496
|
+
timestamp: Date.now()
|
|
11497
|
+
});
|
|
11498
|
+
}
|
|
11499
|
+
/** Delete a single row. No-op when inactive. */
|
|
11500
|
+
delete(key) {
|
|
11501
|
+
if (this.stmts === null) return;
|
|
11502
|
+
this.stmts.delete.run(key);
|
|
11503
|
+
}
|
|
11504
|
+
/** Wipe the table. No-op when inactive. */
|
|
11505
|
+
clear() {
|
|
11506
|
+
if (this.stmts === null) return;
|
|
11507
|
+
this.stmts.clear.run();
|
|
11508
|
+
}
|
|
11509
|
+
};
|
|
11510
|
+
|
|
11556
11511
|
// src/context/mobimem-impl.ts
|
|
11512
|
+
function hydrateDates(value, dateKeys) {
|
|
11513
|
+
const out = value;
|
|
11514
|
+
for (const key of dateKeys) {
|
|
11515
|
+
const v = out[key];
|
|
11516
|
+
if (typeof v === "string") out[key] = new Date(v);
|
|
11517
|
+
}
|
|
11518
|
+
return value;
|
|
11519
|
+
}
|
|
11557
11520
|
var ProfileMemoryImpl = class {
|
|
11558
11521
|
entries = /* @__PURE__ */ new Map();
|
|
11559
11522
|
config;
|
|
11560
|
-
|
|
11523
|
+
persist;
|
|
11524
|
+
constructor(config, db = null) {
|
|
11561
11525
|
this.config = config;
|
|
11526
|
+
this.persist = new MobiMemPersistence({ db, domain: "mobimem_profile" });
|
|
11527
|
+
for (const [k, v] of this.persist.load()) {
|
|
11528
|
+
this.entries.set(k, hydrateDates(v, ["createdAt", "updatedAt"]));
|
|
11529
|
+
}
|
|
11562
11530
|
}
|
|
11563
11531
|
observe(entityId, entityType, preferenceKey, preferenceValue) {
|
|
11564
11532
|
const key = `${entityId}:${preferenceKey}`;
|
|
@@ -11574,6 +11542,7 @@ var ProfileMemoryImpl = class {
|
|
|
11574
11542
|
updatedAt: now
|
|
11575
11543
|
};
|
|
11576
11544
|
this.entries.set(key, updated);
|
|
11545
|
+
this.persist.upsert(key, updated);
|
|
11577
11546
|
return updated;
|
|
11578
11547
|
}
|
|
11579
11548
|
const entry = {
|
|
@@ -11589,6 +11558,7 @@ var ProfileMemoryImpl = class {
|
|
|
11589
11558
|
};
|
|
11590
11559
|
this.enforceLimit(entityId);
|
|
11591
11560
|
this.entries.set(key, entry);
|
|
11561
|
+
this.persist.upsert(key, entry);
|
|
11592
11562
|
return entry;
|
|
11593
11563
|
}
|
|
11594
11564
|
getPreferences(entityId) {
|
|
@@ -11614,6 +11584,7 @@ var ProfileMemoryImpl = class {
|
|
|
11614
11584
|
for (const [key, entry] of this.entries) {
|
|
11615
11585
|
if (entry.entityId === entityId) {
|
|
11616
11586
|
this.entries.delete(key);
|
|
11587
|
+
this.persist.delete(key);
|
|
11617
11588
|
count++;
|
|
11618
11589
|
}
|
|
11619
11590
|
}
|
|
@@ -11635,6 +11606,7 @@ var ProfileMemoryImpl = class {
|
|
|
11635
11606
|
if (toRemove !== void 0) {
|
|
11636
11607
|
const key = `${entityId}:${toRemove.preferenceKey}`;
|
|
11637
11608
|
this.entries.delete(key);
|
|
11609
|
+
this.persist.delete(key);
|
|
11638
11610
|
}
|
|
11639
11611
|
}
|
|
11640
11612
|
}
|
|
@@ -11642,8 +11614,13 @@ var ProfileMemoryImpl = class {
|
|
|
11642
11614
|
var ExperienceMemoryImpl = class {
|
|
11643
11615
|
patterns = /* @__PURE__ */ new Map();
|
|
11644
11616
|
config;
|
|
11645
|
-
|
|
11617
|
+
persist;
|
|
11618
|
+
constructor(config, db = null) {
|
|
11646
11619
|
this.config = config;
|
|
11620
|
+
this.persist = new MobiMemPersistence({ db, domain: "mobimem_experience" });
|
|
11621
|
+
for (const [k, v] of this.persist.load()) {
|
|
11622
|
+
this.patterns.set(k, hydrateDates(v, ["createdAt", "lastUsedAt"]));
|
|
11623
|
+
}
|
|
11647
11624
|
}
|
|
11648
11625
|
recordExecution(taskType, actionSequence, outcome, contextSignature) {
|
|
11649
11626
|
const patternKey = generatePatternKey(taskType, actionSequence, contextSignature);
|
|
@@ -11662,6 +11639,7 @@ var ExperienceMemoryImpl = class {
|
|
|
11662
11639
|
lastUsedAt: now
|
|
11663
11640
|
};
|
|
11664
11641
|
this.patterns.set(patternKey, updated);
|
|
11642
|
+
this.persist.upsert(patternKey, updated);
|
|
11665
11643
|
return updated;
|
|
11666
11644
|
}
|
|
11667
11645
|
const entry = {
|
|
@@ -11678,6 +11656,7 @@ var ExperienceMemoryImpl = class {
|
|
|
11678
11656
|
};
|
|
11679
11657
|
this.enforceLimit(taskType);
|
|
11680
11658
|
this.patterns.set(patternKey, entry);
|
|
11659
|
+
this.persist.upsert(patternKey, entry);
|
|
11681
11660
|
return entry;
|
|
11682
11661
|
}
|
|
11683
11662
|
findPatterns(taskType, limit = 10) {
|
|
@@ -11712,11 +11691,13 @@ var ExperienceMemoryImpl = class {
|
|
|
11712
11691
|
for (const [key, entry] of this.patterns) {
|
|
11713
11692
|
if (entry.id === patternId) {
|
|
11714
11693
|
const metrics2 = computeUpdatedMetrics(entry.successCount, entry.attemptCount, success);
|
|
11715
|
-
|
|
11694
|
+
const updated = {
|
|
11716
11695
|
...entry,
|
|
11717
11696
|
...metrics2,
|
|
11718
11697
|
lastUsedAt: new Date(getTimeProvider().now())
|
|
11719
|
-
}
|
|
11698
|
+
};
|
|
11699
|
+
this.patterns.set(key, updated);
|
|
11700
|
+
this.persist.upsert(key, updated);
|
|
11720
11701
|
return;
|
|
11721
11702
|
}
|
|
11722
11703
|
}
|
|
@@ -11738,6 +11719,7 @@ var ExperienceMemoryImpl = class {
|
|
|
11738
11719
|
for (const [key, entry] of this.patterns) {
|
|
11739
11720
|
if (entry.id === toRemove.id) {
|
|
11740
11721
|
this.patterns.delete(key);
|
|
11722
|
+
this.persist.delete(key);
|
|
11741
11723
|
break;
|
|
11742
11724
|
}
|
|
11743
11725
|
}
|
|
@@ -11748,10 +11730,18 @@ var ExperienceMemoryImpl = class {
|
|
|
11748
11730
|
var ActionCacheImpl = class {
|
|
11749
11731
|
entries = /* @__PURE__ */ new Map();
|
|
11750
11732
|
config;
|
|
11733
|
+
persist;
|
|
11751
11734
|
totalHits = 0;
|
|
11752
11735
|
totalRequests = 0;
|
|
11753
|
-
constructor(config) {
|
|
11736
|
+
constructor(config, db = null) {
|
|
11754
11737
|
this.config = config;
|
|
11738
|
+
this.persist = new MobiMemPersistence({ db, domain: "mobimem_action" });
|
|
11739
|
+
for (const [k, v] of this.persist.load()) {
|
|
11740
|
+
this.entries.set(
|
|
11741
|
+
k,
|
|
11742
|
+
hydrateDates(v, ["cachedAt", "lastAccessedAt", "expiresAt"])
|
|
11743
|
+
);
|
|
11744
|
+
}
|
|
11755
11745
|
}
|
|
11756
11746
|
cache(input, result, durationMs2) {
|
|
11757
11747
|
const inputHash = hashInput(input);
|
|
@@ -11770,6 +11760,7 @@ var ActionCacheImpl = class {
|
|
|
11770
11760
|
};
|
|
11771
11761
|
this.enforceLimit();
|
|
11772
11762
|
this.entries.set(inputHash, entry);
|
|
11763
|
+
this.persist.upsert(inputHash, entry);
|
|
11773
11764
|
return entry;
|
|
11774
11765
|
}
|
|
11775
11766
|
get(input) {
|
|
@@ -11779,6 +11770,7 @@ var ActionCacheImpl = class {
|
|
|
11779
11770
|
if (entry === void 0) return null;
|
|
11780
11771
|
if (entry.expiresAt < new Date(getTimeProvider().now())) {
|
|
11781
11772
|
this.entries.delete(inputHash);
|
|
11773
|
+
this.persist.delete(inputHash);
|
|
11782
11774
|
return null;
|
|
11783
11775
|
}
|
|
11784
11776
|
this.totalHits++;
|
|
@@ -11794,6 +11786,7 @@ var ActionCacheImpl = class {
|
|
|
11794
11786
|
lastAccessedAt: new Date(getTimeProvider().now())
|
|
11795
11787
|
};
|
|
11796
11788
|
this.entries.set(hash, updated);
|
|
11789
|
+
this.persist.upsert(hash, updated);
|
|
11797
11790
|
return;
|
|
11798
11791
|
}
|
|
11799
11792
|
}
|
|
@@ -11804,6 +11797,7 @@ var ActionCacheImpl = class {
|
|
|
11804
11797
|
for (const [hash, entry] of this.entries) {
|
|
11805
11798
|
if (entry.expiresAt < now) {
|
|
11806
11799
|
this.entries.delete(hash);
|
|
11800
|
+
this.persist.delete(hash);
|
|
11807
11801
|
evicted++;
|
|
11808
11802
|
}
|
|
11809
11803
|
}
|
|
@@ -11812,6 +11806,7 @@ var ActionCacheImpl = class {
|
|
|
11812
11806
|
clear() {
|
|
11813
11807
|
const count = this.entries.size;
|
|
11814
11808
|
this.entries.clear();
|
|
11809
|
+
this.persist.clear();
|
|
11815
11810
|
this.totalHits = 0;
|
|
11816
11811
|
this.totalRequests = 0;
|
|
11817
11812
|
return count;
|
|
@@ -11828,6 +11823,7 @@ var ActionCacheImpl = class {
|
|
|
11828
11823
|
timeSavedMs: totalTimeSaved
|
|
11829
11824
|
};
|
|
11830
11825
|
}
|
|
11826
|
+
/** Drop one entry to stay under the cache limit. SQLite mirror updated. */
|
|
11831
11827
|
enforceLimit() {
|
|
11832
11828
|
if (this.entries.size >= this.config.maxActionCacheEntries) {
|
|
11833
11829
|
this.evictExpired();
|
|
@@ -11838,6 +11834,7 @@ var ActionCacheImpl = class {
|
|
|
11838
11834
|
const toRemove = sorted[0];
|
|
11839
11835
|
if (toRemove !== void 0) {
|
|
11840
11836
|
this.entries.delete(toRemove[0]);
|
|
11837
|
+
this.persist.delete(toRemove[0]);
|
|
11841
11838
|
}
|
|
11842
11839
|
}
|
|
11843
11840
|
}
|
|
@@ -11851,13 +11848,24 @@ var MobiMem = class {
|
|
|
11851
11848
|
experience;
|
|
11852
11849
|
action;
|
|
11853
11850
|
config;
|
|
11851
|
+
db;
|
|
11854
11852
|
constructor(config = {}) {
|
|
11855
11853
|
const validated = MobiMemConfigSchema.parse({ ...DEFAULT_MOBIMEM_CONFIG, ...config });
|
|
11856
11854
|
this.config = validated;
|
|
11857
|
-
|
|
11858
|
-
|
|
11859
|
-
|
|
11855
|
+
if (validated.dbPath === ":memory:" || validated.dbPath === "") {
|
|
11856
|
+
this.db = null;
|
|
11857
|
+
} else {
|
|
11858
|
+
mkdirSync2(dirname3(validated.dbPath), { recursive: true });
|
|
11859
|
+
const db = new Database(validated.dbPath);
|
|
11860
|
+
db.pragma("journal_mode = WAL");
|
|
11861
|
+
this.db = db;
|
|
11862
|
+
}
|
|
11863
|
+
this.profile = new ProfileMemoryImpl(this.config, this.db);
|
|
11864
|
+
this.experience = new ExperienceMemoryImpl(this.config, this.db);
|
|
11865
|
+
this.action = new ActionCacheImpl(this.config, this.db);
|
|
11860
11866
|
logger10.info("MobiMem initialized", {
|
|
11867
|
+
dbPath: validated.dbPath,
|
|
11868
|
+
persisted: this.db !== null,
|
|
11861
11869
|
maxProfileEntries: this.config.maxProfileEntries,
|
|
11862
11870
|
maxExperiencePatterns: this.config.maxExperiencePatterns,
|
|
11863
11871
|
maxActionCacheEntries: this.config.maxActionCacheEntries
|
|
@@ -11893,31 +11901,194 @@ var MobiMem = class {
|
|
|
11893
11901
|
}
|
|
11894
11902
|
}
|
|
11895
11903
|
close() {
|
|
11904
|
+
if (this.db !== null) this.db.close();
|
|
11896
11905
|
logger10.info("MobiMem closed");
|
|
11897
11906
|
}
|
|
11898
|
-
|
|
11899
|
-
|
|
11900
|
-
|
|
11901
|
-
|
|
11902
|
-
|
|
11907
|
+
};
|
|
11908
|
+
var sharedInstance = null;
|
|
11909
|
+
var resolveSharedDbPath = defaultSharedDbPath;
|
|
11910
|
+
function getSharedMobiMem() {
|
|
11911
|
+
sharedInstance ??= new MobiMem({ dbPath: resolveSharedDbPath() });
|
|
11912
|
+
return sharedInstance;
|
|
11913
|
+
}
|
|
11914
|
+
function setSharedMobiMemDbPathResolver(resolver) {
|
|
11915
|
+
resolveSharedDbPath = resolver;
|
|
11916
|
+
}
|
|
11917
|
+
function defaultSharedDbPath() {
|
|
11918
|
+
const root = process.env["NEXUS_DATA_DIR"] ?? `${process.env["HOME"] ?? "/tmp"}/.nexus-agents`;
|
|
11919
|
+
return `${root}/memory/mobimem.db`;
|
|
11920
|
+
}
|
|
11921
|
+
|
|
11922
|
+
// src/context/routing-memory.ts
|
|
11923
|
+
var DEFAULT_ROUTING_MEMORY_CONFIG = {
|
|
11924
|
+
minObservations: 5,
|
|
11925
|
+
confidenceThreshold: 0.6,
|
|
11926
|
+
successRateThreshold: 0.7,
|
|
11927
|
+
actionCacheMaxAgeMs: 36e5
|
|
11928
|
+
// 1 hour
|
|
11929
|
+
};
|
|
11930
|
+
var RoutingMemory = class {
|
|
11931
|
+
mobimem;
|
|
11932
|
+
config;
|
|
11933
|
+
logger;
|
|
11934
|
+
// Statistics
|
|
11935
|
+
cacheHits = 0;
|
|
11936
|
+
cacheMisses = 0;
|
|
11937
|
+
recommendationsMade = 0;
|
|
11938
|
+
constructor(config, mobimem) {
|
|
11939
|
+
this.config = { ...DEFAULT_ROUTING_MEMORY_CONFIG, ...config };
|
|
11940
|
+
this.logger = this.config.logger ?? createLogger({ component: "RoutingMemory" });
|
|
11941
|
+
this.mobimem = mobimem ?? getSharedMobiMem();
|
|
11942
|
+
this.logger.info("RoutingMemory initialized", {
|
|
11943
|
+
minObservations: this.config.minObservations,
|
|
11944
|
+
confidenceThreshold: this.config.confidenceThreshold
|
|
11945
|
+
});
|
|
11946
|
+
}
|
|
11947
|
+
storePreference(model, taskType, performance2) {
|
|
11948
|
+
const preferenceKey = `model_preference:${taskType}`;
|
|
11949
|
+
const entityId = `routing:${model}`;
|
|
11950
|
+
const entry = this.mobimem.profile.observe(entityId, "agent", preferenceKey, {
|
|
11951
|
+
model,
|
|
11952
|
+
performance: performance2,
|
|
11953
|
+
updatedAt: getTimeProvider().nowIso()
|
|
11954
|
+
});
|
|
11955
|
+
this.logger.debug("Stored model preference", {
|
|
11956
|
+
model,
|
|
11957
|
+
taskType,
|
|
11958
|
+
confidence: entry.confidence,
|
|
11959
|
+
observations: entry.observationCount
|
|
11960
|
+
});
|
|
11961
|
+
}
|
|
11962
|
+
getPreferences(taskType) {
|
|
11963
|
+
const preferenceKey = `model_preference:${taskType}`;
|
|
11964
|
+
const preferences = [];
|
|
11965
|
+
for (const model of CLI_NAMES) {
|
|
11966
|
+
const entityId = `routing:${model}`;
|
|
11967
|
+
const entry = this.mobimem.profile.getPreference(entityId, preferenceKey);
|
|
11968
|
+
if (entry !== null && entry.observationCount >= this.config.minObservations) {
|
|
11969
|
+
const value = entry.preferenceValue;
|
|
11970
|
+
preferences.push({
|
|
11971
|
+
model: value.model,
|
|
11972
|
+
strength: this.calculateStrength(value.performance),
|
|
11973
|
+
performance: value.performance,
|
|
11974
|
+
confidence: entry.confidence
|
|
11975
|
+
});
|
|
11976
|
+
}
|
|
11977
|
+
}
|
|
11978
|
+
return preferences.sort((a, b) => b.strength - a.strength);
|
|
11979
|
+
}
|
|
11980
|
+
recordExperience(workflow, models, success, metrics2) {
|
|
11981
|
+
const contextSignature = models.join("->");
|
|
11982
|
+
const actionSequence = models.map((model, index) => ({
|
|
11983
|
+
index,
|
|
11984
|
+
actionType: "model_route",
|
|
11985
|
+
parameters: { model },
|
|
11986
|
+
durationMs: Math.floor(metrics2.durationMs / models.length),
|
|
11987
|
+
success
|
|
11988
|
+
}));
|
|
11989
|
+
const outcome = metrics2.qualityScore !== void 0 ? {
|
|
11990
|
+
success,
|
|
11991
|
+
qualityScore: metrics2.qualityScore,
|
|
11992
|
+
totalDurationMs: metrics2.durationMs,
|
|
11993
|
+
tokensUsed: metrics2.tokensUsed
|
|
11994
|
+
} : {
|
|
11995
|
+
success,
|
|
11996
|
+
totalDurationMs: metrics2.durationMs,
|
|
11997
|
+
tokensUsed: metrics2.tokensUsed
|
|
11903
11998
|
};
|
|
11999
|
+
this.mobimem.experience.recordExecution(workflow, actionSequence, outcome, contextSignature);
|
|
12000
|
+
this.logger.debug("Recorded routing experience", {
|
|
12001
|
+
workflow,
|
|
12002
|
+
models: models.join("->"),
|
|
12003
|
+
success,
|
|
12004
|
+
durationMs: metrics2.durationMs
|
|
12005
|
+
});
|
|
11904
12006
|
}
|
|
11905
|
-
|
|
11906
|
-
|
|
11907
|
-
|
|
11908
|
-
|
|
11909
|
-
|
|
11910
|
-
|
|
11911
|
-
|
|
11912
|
-
|
|
11913
|
-
|
|
11914
|
-
|
|
11915
|
-
|
|
12007
|
+
getExperiencePatterns(workflow) {
|
|
12008
|
+
const experiences = this.mobimem.experience.findPatterns(workflow);
|
|
12009
|
+
return experiences.filter((exp) => exp.successRate >= this.config.successRateThreshold).map((exp) => this.mapExperienceToPattern(exp));
|
|
12010
|
+
}
|
|
12011
|
+
cacheAction(action, model, result, durationMs2) {
|
|
12012
|
+
const input = { actionSignature: action, model };
|
|
12013
|
+
this.mobimem.action.cache(input, result, durationMs2);
|
|
12014
|
+
this.logger.debug("Cached action result", { action: action.slice(0, 50), model, durationMs: durationMs2 });
|
|
12015
|
+
}
|
|
12016
|
+
getCachedAction(action) {
|
|
12017
|
+
for (const model of CLI_NAMES) {
|
|
12018
|
+
const input = { actionSignature: action, model };
|
|
12019
|
+
const entry = this.mobimem.action.get(input);
|
|
12020
|
+
if (entry !== null) {
|
|
12021
|
+
this.cacheHits++;
|
|
12022
|
+
const inputData = entry.input;
|
|
12023
|
+
return {
|
|
12024
|
+
action,
|
|
12025
|
+
result: entry.result,
|
|
12026
|
+
model: inputData.model,
|
|
12027
|
+
cachedAt: entry.cachedAt,
|
|
12028
|
+
timeSavedMs: entry.timeSavedMs
|
|
12029
|
+
};
|
|
12030
|
+
}
|
|
11916
12031
|
}
|
|
12032
|
+
this.cacheMisses++;
|
|
12033
|
+
return void 0;
|
|
12034
|
+
}
|
|
12035
|
+
getRecommendation(taskType) {
|
|
12036
|
+
const preferences = this.getPreferences(taskType);
|
|
12037
|
+
const top = preferences[0];
|
|
12038
|
+
if (top !== void 0 && top.confidence >= this.config.confidenceThreshold) {
|
|
12039
|
+
this.recommendationsMade++;
|
|
12040
|
+
this.logger.debug("Generated routing recommendation", {
|
|
12041
|
+
taskType,
|
|
12042
|
+
recommended: top.model,
|
|
12043
|
+
confidence: top.confidence,
|
|
12044
|
+
strength: top.strength
|
|
12045
|
+
});
|
|
12046
|
+
return top.model;
|
|
12047
|
+
}
|
|
12048
|
+
return void 0;
|
|
12049
|
+
}
|
|
12050
|
+
getStats() {
|
|
12051
|
+
const mobiStats = this.mobimem.getStats();
|
|
12052
|
+
return {
|
|
12053
|
+
totalPreferences: mobiStats.profile.totalEntries,
|
|
12054
|
+
totalExperiences: mobiStats.experience.totalPatterns,
|
|
12055
|
+
cacheHits: this.cacheHits,
|
|
12056
|
+
cacheMisses: this.cacheMisses,
|
|
12057
|
+
recommendationsMade: this.recommendationsMade
|
|
12058
|
+
};
|
|
12059
|
+
}
|
|
12060
|
+
// ========================================================================
|
|
12061
|
+
// Private Helpers
|
|
12062
|
+
// ========================================================================
|
|
12063
|
+
/**
|
|
12064
|
+
* Calculate preference strength from performance metrics.
|
|
12065
|
+
*/
|
|
12066
|
+
calculateStrength(performance2) {
|
|
12067
|
+
const qualityWeight = 0.4;
|
|
12068
|
+
const successWeight = 0.3;
|
|
12069
|
+
const speedWeight = 0.2;
|
|
12070
|
+
const efficiencyWeight = 0.1;
|
|
12071
|
+
const normalizedLatency = 1 - Math.min(performance2.avgLatencyMs / 1e4, 1);
|
|
12072
|
+
const normalizedTokens = 1 - Math.min(performance2.avgTokens / 1e5, 1);
|
|
12073
|
+
return performance2.avgQuality * qualityWeight + performance2.successRate * successWeight + normalizedLatency * speedWeight + normalizedTokens * efficiencyWeight;
|
|
12074
|
+
}
|
|
12075
|
+
/**
|
|
12076
|
+
* Map MobiMem experience entry to routing pattern.
|
|
12077
|
+
*/
|
|
12078
|
+
mapExperienceToPattern(exp) {
|
|
12079
|
+
const models = exp.actionSequence.filter((step) => step.actionType === "model_route").map((step) => step.parameters.model);
|
|
12080
|
+
const avgDuration = exp.outcome.totalDurationMs;
|
|
12081
|
+
return {
|
|
12082
|
+
workflow: exp.taskType,
|
|
12083
|
+
modelSequence: models,
|
|
12084
|
+
successRate: exp.successRate,
|
|
12085
|
+
avgDurationMs: avgDuration,
|
|
12086
|
+
usageCount: exp.attemptCount
|
|
12087
|
+
};
|
|
11917
12088
|
}
|
|
11918
12089
|
};
|
|
11919
|
-
function
|
|
11920
|
-
return new
|
|
12090
|
+
function createRoutingMemory(config, mobimem) {
|
|
12091
|
+
return new RoutingMemory(config, mobimem);
|
|
11921
12092
|
}
|
|
11922
12093
|
|
|
11923
12094
|
export {
|
|
@@ -12022,9 +12193,8 @@ export {
|
|
|
12022
12193
|
PreferenceRouter,
|
|
12023
12194
|
createPreferenceRouter,
|
|
12024
12195
|
DEFAULT_ZERO_ROUTER_CONFIG,
|
|
12025
|
-
|
|
12026
|
-
|
|
12027
|
-
createMobiMem,
|
|
12196
|
+
getSharedMobiMem,
|
|
12197
|
+
setSharedMobiMemDbPathResolver,
|
|
12028
12198
|
DEFAULT_ROUTING_MEMORY_CONFIG,
|
|
12029
12199
|
RoutingMemory,
|
|
12030
12200
|
createRoutingMemory,
|
|
@@ -12106,4 +12276,4 @@ export {
|
|
|
12106
12276
|
ParseError,
|
|
12107
12277
|
OrchestratorError
|
|
12108
12278
|
};
|
|
12109
|
-
//# sourceMappingURL=chunk-
|
|
12279
|
+
//# sourceMappingURL=chunk-WDYCIJWN.js.map
|