@claude-flow/cli 3.10.41 → 3.10.42
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/src/commands/hooks.d.ts.map +1 -1
- package/dist/src/commands/hooks.js +12 -1
- package/dist/src/commands/hooks.js.map +1 -1
- package/dist/src/commands/init.d.ts.map +1 -1
- package/dist/src/commands/init.js +7 -1
- package/dist/src/commands/init.js.map +1 -1
- package/dist/src/mcp-tools/hooks-tools.d.ts.map +1 -1
- package/dist/src/mcp-tools/hooks-tools.js +79 -1
- package/dist/src/mcp-tools/hooks-tools.js.map +1 -1
- package/dist/src/ruvector/neural-router.d.ts +49 -0
- package/dist/src/ruvector/neural-router.d.ts.map +1 -0
- package/dist/src/ruvector/neural-router.js +132 -0
- package/dist/src/ruvector/neural-router.js.map +1 -0
- package/dist/src/ruvector/router-trajectory.d.ts +69 -0
- package/dist/src/ruvector/router-trajectory.d.ts.map +1 -0
- package/dist/src/ruvector/router-trajectory.js +87 -0
- package/dist/src/ruvector/router-trajectory.js.map +1 -0
- package/dist/tsconfig.tsbuildinfo +1 -1
- package/package.json +1 -1
|
@@ -0,0 +1,49 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Neural routing scaffold — `@ruvector/tiny-dancer` FastGRNN seam (#2334 Phase 1)
|
|
3
|
+
*
|
|
4
|
+
* Wires the optional neural path that ADR-026 originally described, behind a
|
|
5
|
+
* double gate that is OFF by default:
|
|
6
|
+
*
|
|
7
|
+
* CLAUDE_FLOW_ROUTER_NEURAL=1 — opt in to the neural path
|
|
8
|
+
* CLAUDE_FLOW_ROUTER_MODEL_PATH=<x.safetensors> — trained FastGRNN artifact
|
|
9
|
+
*
|
|
10
|
+
* Both must be set; otherwise `tryNeuralRoute` returns `null` immediately and
|
|
11
|
+
* the caller stays on the shipped heuristic + Thompson-bandit path. When the
|
|
12
|
+
* gate is open but anything fails (package not installed — it is an
|
|
13
|
+
* optionalDependency per ADR-124 — artifact missing/incompatible, runtime
|
|
14
|
+
* error), this module degrades gracefully: it returns `null`, never throws,
|
|
15
|
+
* and the caller reports `routedBy: 'bandit-fallback'` so the active path is
|
|
16
|
+
* observable rather than inferred from import success (ADR-086/074).
|
|
17
|
+
*
|
|
18
|
+
* Candidate modeling (#2334 Q3, provisional): the 3 model tiers are encoded as
|
|
19
|
+
* fixed candidates with deterministic placeholder embeddings (orthogonal-ish
|
|
20
|
+
* one-hot-block vectors). This is explicitly provisional — the trained Phase 2
|
|
21
|
+
* artifact defines what candidate embeddings mean, and this encoding is the
|
|
22
|
+
* scaffolding default until the maintainers answer #2334's candidate-modeling
|
|
23
|
+
* question. Until a real artifact exists the gate stays closed in practice, so
|
|
24
|
+
* the placeholder never influences routing.
|
|
25
|
+
*
|
|
26
|
+
* @module neural-router
|
|
27
|
+
*/
|
|
28
|
+
/** The three routable tiers — 'inherit' is never a neural candidate. */
|
|
29
|
+
export type NeuralRoutableModel = 'haiku' | 'sonnet' | 'opus';
|
|
30
|
+
export interface NeuralRouteDecision {
|
|
31
|
+
model: NeuralRoutableModel;
|
|
32
|
+
confidence: number;
|
|
33
|
+
uncertainty: number;
|
|
34
|
+
inferenceTimeUs: number;
|
|
35
|
+
}
|
|
36
|
+
/** True when the user has opted in AND pointed at a model artifact. */
|
|
37
|
+
export declare function neuralRoutingEnabled(): boolean;
|
|
38
|
+
/** Reset cached state — for tests. */
|
|
39
|
+
export declare function resetNeuralRouter(): void;
|
|
40
|
+
/**
|
|
41
|
+
* Attempt a neural routing decision for the given task embedding.
|
|
42
|
+
*
|
|
43
|
+
* Returns `null` (never throws) when the gate is closed, the package or
|
|
44
|
+
* artifact is unavailable, or inference fails — callers fall back to the
|
|
45
|
+
* bandit and report `routedBy: 'bandit-fallback'` (when the gate was open)
|
|
46
|
+
* or `'heuristic'` (when it never was).
|
|
47
|
+
*/
|
|
48
|
+
export declare function tryNeuralRoute(embedding: number[]): Promise<NeuralRouteDecision | null>;
|
|
49
|
+
//# sourceMappingURL=neural-router.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"neural-router.d.ts","sourceRoot":"","sources":["../../../src/ruvector/neural-router.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;GA0BG;AAQH,wEAAwE;AACxE,MAAM,MAAM,mBAAmB,GAAG,OAAO,GAAG,QAAQ,GAAG,MAAM,CAAC;AAE9D,MAAM,WAAW,mBAAmB;IAClC,KAAK,EAAE,mBAAmB,CAAC;IAC3B,UAAU,EAAE,MAAM,CAAC;IACnB,WAAW,EAAE,MAAM,CAAC;IACpB,eAAe,EAAE,MAAM,CAAC;CACzB;AAyBD,uEAAuE;AACvE,wBAAgB,oBAAoB,IAAI,OAAO,CAG9C;AAOD,sCAAsC;AACtC,wBAAgB,iBAAiB,IAAI,IAAI,CAGxC;AAoDD;;;;;;;GAOG;AACH,wBAAsB,cAAc,CAAC,SAAS,EAAE,MAAM,EAAE,GAAG,OAAO,CAAC,mBAAmB,GAAG,IAAI,CAAC,CA6B7F"}
|
|
@@ -0,0 +1,132 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Neural routing scaffold — `@ruvector/tiny-dancer` FastGRNN seam (#2334 Phase 1)
|
|
3
|
+
*
|
|
4
|
+
* Wires the optional neural path that ADR-026 originally described, behind a
|
|
5
|
+
* double gate that is OFF by default:
|
|
6
|
+
*
|
|
7
|
+
* CLAUDE_FLOW_ROUTER_NEURAL=1 — opt in to the neural path
|
|
8
|
+
* CLAUDE_FLOW_ROUTER_MODEL_PATH=<x.safetensors> — trained FastGRNN artifact
|
|
9
|
+
*
|
|
10
|
+
* Both must be set; otherwise `tryNeuralRoute` returns `null` immediately and
|
|
11
|
+
* the caller stays on the shipped heuristic + Thompson-bandit path. When the
|
|
12
|
+
* gate is open but anything fails (package not installed — it is an
|
|
13
|
+
* optionalDependency per ADR-124 — artifact missing/incompatible, runtime
|
|
14
|
+
* error), this module degrades gracefully: it returns `null`, never throws,
|
|
15
|
+
* and the caller reports `routedBy: 'bandit-fallback'` so the active path is
|
|
16
|
+
* observable rather than inferred from import success (ADR-086/074).
|
|
17
|
+
*
|
|
18
|
+
* Candidate modeling (#2334 Q3, provisional): the 3 model tiers are encoded as
|
|
19
|
+
* fixed candidates with deterministic placeholder embeddings (orthogonal-ish
|
|
20
|
+
* one-hot-block vectors). This is explicitly provisional — the trained Phase 2
|
|
21
|
+
* artifact defines what candidate embeddings mean, and this encoding is the
|
|
22
|
+
* scaffolding default until the maintainers answer #2334's candidate-modeling
|
|
23
|
+
* question. Until a real artifact exists the gate stays closed in practice, so
|
|
24
|
+
* the placeholder never influences routing.
|
|
25
|
+
*
|
|
26
|
+
* @module neural-router
|
|
27
|
+
*/
|
|
28
|
+
import { existsSync } from 'fs';
|
|
29
|
+
// ============================================================================
|
|
30
|
+
// Gate & lifecycle
|
|
31
|
+
// ============================================================================
|
|
32
|
+
/** True when the user has opted in AND pointed at a model artifact. */
|
|
33
|
+
export function neuralRoutingEnabled() {
|
|
34
|
+
return process.env.CLAUDE_FLOW_ROUTER_NEURAL === '1'
|
|
35
|
+
&& !!process.env.CLAUDE_FLOW_ROUTER_MODEL_PATH;
|
|
36
|
+
}
|
|
37
|
+
// Cached router instance + a sticky failure latch so a broken install/artifact
|
|
38
|
+
// costs one failed load, not one per routing call.
|
|
39
|
+
let routerInstance = null;
|
|
40
|
+
let loadFailed = false;
|
|
41
|
+
/** Reset cached state — for tests. */
|
|
42
|
+
export function resetNeuralRouter() {
|
|
43
|
+
routerInstance = null;
|
|
44
|
+
loadFailed = false;
|
|
45
|
+
}
|
|
46
|
+
async function loadRouter() {
|
|
47
|
+
if (routerInstance)
|
|
48
|
+
return routerInstance;
|
|
49
|
+
if (loadFailed)
|
|
50
|
+
return null;
|
|
51
|
+
const modelPath = process.env.CLAUDE_FLOW_ROUTER_MODEL_PATH;
|
|
52
|
+
if (!modelPath || !existsSync(modelPath)) {
|
|
53
|
+
loadFailed = true;
|
|
54
|
+
return null;
|
|
55
|
+
}
|
|
56
|
+
try {
|
|
57
|
+
// Dynamic import of an optionalDependency (ADR-124): absent on installs
|
|
58
|
+
// where the native binding failed or was skipped — degrade, don't throw.
|
|
59
|
+
const mod = await import('@ruvector/tiny-dancer');
|
|
60
|
+
const RouterCtor = mod.Router;
|
|
61
|
+
if (!RouterCtor) {
|
|
62
|
+
loadFailed = true;
|
|
63
|
+
return null;
|
|
64
|
+
}
|
|
65
|
+
routerInstance = new RouterCtor({ modelPath });
|
|
66
|
+
return routerInstance;
|
|
67
|
+
}
|
|
68
|
+
catch {
|
|
69
|
+
loadFailed = true;
|
|
70
|
+
return null;
|
|
71
|
+
}
|
|
72
|
+
}
|
|
73
|
+
// ============================================================================
|
|
74
|
+
// Candidate encoding (provisional — see header + #2334 Q3)
|
|
75
|
+
// ============================================================================
|
|
76
|
+
const TIER_ORDER = ['haiku', 'sonnet', 'opus'];
|
|
77
|
+
/**
|
|
78
|
+
* Deterministic placeholder embedding for a tier candidate: a block one-hot
|
|
79
|
+
* over the embedding dimensionality. Replaced by whatever the Phase 2 trained
|
|
80
|
+
* artifact defines as candidate space.
|
|
81
|
+
*/
|
|
82
|
+
function tierCandidateEmbedding(tierIndex, dim) {
|
|
83
|
+
const v = new Array(dim).fill(0);
|
|
84
|
+
const block = Math.max(1, Math.floor(dim / TIER_ORDER.length));
|
|
85
|
+
const start = tierIndex * block;
|
|
86
|
+
for (let i = start; i < Math.min(start + block, dim); i++)
|
|
87
|
+
v[i] = 1 / Math.sqrt(block);
|
|
88
|
+
return v;
|
|
89
|
+
}
|
|
90
|
+
// ============================================================================
|
|
91
|
+
// Routing
|
|
92
|
+
// ============================================================================
|
|
93
|
+
/**
|
|
94
|
+
* Attempt a neural routing decision for the given task embedding.
|
|
95
|
+
*
|
|
96
|
+
* Returns `null` (never throws) when the gate is closed, the package or
|
|
97
|
+
* artifact is unavailable, or inference fails — callers fall back to the
|
|
98
|
+
* bandit and report `routedBy: 'bandit-fallback'` (when the gate was open)
|
|
99
|
+
* or `'heuristic'` (when it never was).
|
|
100
|
+
*/
|
|
101
|
+
export async function tryNeuralRoute(embedding) {
|
|
102
|
+
if (!neuralRoutingEnabled())
|
|
103
|
+
return null;
|
|
104
|
+
if (!embedding || embedding.length === 0)
|
|
105
|
+
return null;
|
|
106
|
+
const router = await loadRouter();
|
|
107
|
+
if (!router)
|
|
108
|
+
return null;
|
|
109
|
+
try {
|
|
110
|
+
const response = await router.route({
|
|
111
|
+
queryEmbedding: embedding,
|
|
112
|
+
candidates: TIER_ORDER.map((tier, i) => ({
|
|
113
|
+
id: tier,
|
|
114
|
+
embedding: tierCandidateEmbedding(i, embedding.length),
|
|
115
|
+
metadata: JSON.stringify({ tier }),
|
|
116
|
+
})),
|
|
117
|
+
});
|
|
118
|
+
const best = response.decisions?.[0];
|
|
119
|
+
if (!best || !TIER_ORDER.includes(best.candidateId))
|
|
120
|
+
return null;
|
|
121
|
+
return {
|
|
122
|
+
model: best.candidateId,
|
|
123
|
+
confidence: best.confidence,
|
|
124
|
+
uncertainty: best.uncertainty,
|
|
125
|
+
inferenceTimeUs: response.inferenceTimeUs,
|
|
126
|
+
};
|
|
127
|
+
}
|
|
128
|
+
catch {
|
|
129
|
+
return null;
|
|
130
|
+
}
|
|
131
|
+
}
|
|
132
|
+
//# sourceMappingURL=neural-router.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"neural-router.js","sourceRoot":"","sources":["../../../src/ruvector/neural-router.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,69 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Router trajectory collection (#2334 Phase 1)
|
|
3
|
+
*
|
|
4
|
+
* Opt-in per-decision dataset collection for the model router. The persisted
|
|
5
|
+
* bandit state (`.swarm/model-router-state.json`) keeps only aggregates —
|
|
6
|
+
* 9 Beta(α,β) cells and a capped/truncated history — which is not trainable
|
|
7
|
+
* material for the Phase 2 FastGRNN tier-classifier. This sidecar captures
|
|
8
|
+
* the per-example rows that training needs:
|
|
9
|
+
*
|
|
10
|
+
* decision rows: { taskHash, task, embedding?, complexity, features,
|
|
11
|
+
* model, confidence, uncertainty, routedBy, ts }
|
|
12
|
+
* outcome rows: { taskHash, model, outcome, ts }
|
|
13
|
+
*
|
|
14
|
+
* joined offline on `taskHash` (sha256-16 of the task text).
|
|
15
|
+
*
|
|
16
|
+
* OFF by default. Enable with CLAUDE_FLOW_ROUTER_TRAJECTORY=1. Rows append to
|
|
17
|
+
* `.swarm/model-router-trajectories.jsonl` — local-only, same trust domain as
|
|
18
|
+
* the existing state file, but unlike it the rows contain full task text (up
|
|
19
|
+
* to 500 chars) and raw embeddings, which is why this is opt-in rather than
|
|
20
|
+
* always-on.
|
|
21
|
+
*
|
|
22
|
+
* Writes are best-effort: any fs error is swallowed (collection must never
|
|
23
|
+
* break routing), matching the state-file behavior in model-router.ts.
|
|
24
|
+
*
|
|
25
|
+
* @module router-trajectory
|
|
26
|
+
*/
|
|
27
|
+
export declare const TRAJECTORY_FILE = ".swarm/model-router-trajectories.jsonl";
|
|
28
|
+
export declare function trajectoryCollectionEnabled(): boolean;
|
|
29
|
+
/** Join key: first 16 hex chars of sha256(task). */
|
|
30
|
+
export declare function taskHash(task: string): string;
|
|
31
|
+
export interface TrajectoryDecisionRow {
|
|
32
|
+
v: number;
|
|
33
|
+
type: 'decision';
|
|
34
|
+
ts: string;
|
|
35
|
+
taskHash: string;
|
|
36
|
+
/** Task text, capped at 500 chars (cf. learningHistory's 100). */
|
|
37
|
+
task: string;
|
|
38
|
+
/** Raw embedding when one was threaded through route(); else omitted. */
|
|
39
|
+
embedding?: number[];
|
|
40
|
+
complexity: number;
|
|
41
|
+
features: {
|
|
42
|
+
lexicalComplexity: number;
|
|
43
|
+
semanticDepth: number;
|
|
44
|
+
taskScope: number;
|
|
45
|
+
uncertaintyLevel: number;
|
|
46
|
+
};
|
|
47
|
+
model: string;
|
|
48
|
+
confidence: number;
|
|
49
|
+
uncertainty: number;
|
|
50
|
+
routedBy: string;
|
|
51
|
+
}
|
|
52
|
+
export interface TrajectoryOutcomeRow {
|
|
53
|
+
v: number;
|
|
54
|
+
type: 'outcome';
|
|
55
|
+
ts: string;
|
|
56
|
+
taskHash: string;
|
|
57
|
+
model: string;
|
|
58
|
+
outcome: 'success' | 'failure' | 'escalated';
|
|
59
|
+
}
|
|
60
|
+
export declare function recordTrajectoryDecision(task: string, embedding: number[] | undefined, complexity: TrajectoryDecisionRow['features'] & {
|
|
61
|
+
score: number;
|
|
62
|
+
}, decision: {
|
|
63
|
+
model: string;
|
|
64
|
+
confidence: number;
|
|
65
|
+
uncertainty: number;
|
|
66
|
+
routedBy: string;
|
|
67
|
+
}): void;
|
|
68
|
+
export declare function recordTrajectoryOutcome(task: string, model: string, outcome: 'success' | 'failure' | 'escalated'): void;
|
|
69
|
+
//# sourceMappingURL=router-trajectory.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"router-trajectory.d.ts","sourceRoot":"","sources":["../../../src/ruvector/router-trajectory.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;GAyBG;AAMH,eAAO,MAAM,eAAe,2CAA2C,CAAC;AAKxE,wBAAgB,2BAA2B,IAAI,OAAO,CAErD;AAED,oDAAoD;AACpD,wBAAgB,QAAQ,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,CAE7C;AAED,MAAM,WAAW,qBAAqB;IACpC,CAAC,EAAE,MAAM,CAAC;IACV,IAAI,EAAE,UAAU,CAAC;IACjB,EAAE,EAAE,MAAM,CAAC;IACX,QAAQ,EAAE,MAAM,CAAC;IACjB,kEAAkE;IAClE,IAAI,EAAE,MAAM,CAAC;IACb,yEAAyE;IACzE,SAAS,CAAC,EAAE,MAAM,EAAE,CAAC;IACrB,UAAU,EAAE,MAAM,CAAC;IACnB,QAAQ,EAAE;QACR,iBAAiB,EAAE,MAAM,CAAC;QAC1B,aAAa,EAAE,MAAM,CAAC;QACtB,SAAS,EAAE,MAAM,CAAC;QAClB,gBAAgB,EAAE,MAAM,CAAC;KAC1B,CAAC;IACF,KAAK,EAAE,MAAM,CAAC;IACd,UAAU,EAAE,MAAM,CAAC;IACnB,WAAW,EAAE,MAAM,CAAC;IACpB,QAAQ,EAAE,MAAM,CAAC;CAClB;AAED,MAAM,WAAW,oBAAoB;IACnC,CAAC,EAAE,MAAM,CAAC;IACV,IAAI,EAAE,SAAS,CAAC;IAChB,EAAE,EAAE,MAAM,CAAC;IACX,QAAQ,EAAE,MAAM,CAAC;IACjB,KAAK,EAAE,MAAM,CAAC;IACd,OAAO,EAAE,SAAS,GAAG,SAAS,GAAG,WAAW,CAAC;CAC9C;AAaD,wBAAgB,wBAAwB,CACtC,IAAI,EAAE,MAAM,EACZ,SAAS,EAAE,MAAM,EAAE,GAAG,SAAS,EAC/B,UAAU,EAAE,qBAAqB,CAAC,UAAU,CAAC,GAAG;IAAE,KAAK,EAAE,MAAM,CAAA;CAAE,EACjE,QAAQ,EAAE;IAAE,KAAK,EAAE,MAAM,CAAC;IAAC,UAAU,EAAE,MAAM,CAAC;IAAC,WAAW,EAAE,MAAM,CAAC;IAAC,QAAQ,EAAE,MAAM,CAAA;CAAE,GACrF,IAAI,CAqBN;AAED,wBAAgB,uBAAuB,CACrC,IAAI,EAAE,MAAM,EACZ,KAAK,EAAE,MAAM,EACb,OAAO,EAAE,SAAS,GAAG,SAAS,GAAG,WAAW,GAC3C,IAAI,CAUN"}
|
|
@@ -0,0 +1,87 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Router trajectory collection (#2334 Phase 1)
|
|
3
|
+
*
|
|
4
|
+
* Opt-in per-decision dataset collection for the model router. The persisted
|
|
5
|
+
* bandit state (`.swarm/model-router-state.json`) keeps only aggregates —
|
|
6
|
+
* 9 Beta(α,β) cells and a capped/truncated history — which is not trainable
|
|
7
|
+
* material for the Phase 2 FastGRNN tier-classifier. This sidecar captures
|
|
8
|
+
* the per-example rows that training needs:
|
|
9
|
+
*
|
|
10
|
+
* decision rows: { taskHash, task, embedding?, complexity, features,
|
|
11
|
+
* model, confidence, uncertainty, routedBy, ts }
|
|
12
|
+
* outcome rows: { taskHash, model, outcome, ts }
|
|
13
|
+
*
|
|
14
|
+
* joined offline on `taskHash` (sha256-16 of the task text).
|
|
15
|
+
*
|
|
16
|
+
* OFF by default. Enable with CLAUDE_FLOW_ROUTER_TRAJECTORY=1. Rows append to
|
|
17
|
+
* `.swarm/model-router-trajectories.jsonl` — local-only, same trust domain as
|
|
18
|
+
* the existing state file, but unlike it the rows contain full task text (up
|
|
19
|
+
* to 500 chars) and raw embeddings, which is why this is opt-in rather than
|
|
20
|
+
* always-on.
|
|
21
|
+
*
|
|
22
|
+
* Writes are best-effort: any fs error is swallowed (collection must never
|
|
23
|
+
* break routing), matching the state-file behavior in model-router.ts.
|
|
24
|
+
*
|
|
25
|
+
* @module router-trajectory
|
|
26
|
+
*/
|
|
27
|
+
import { createHash } from 'crypto';
|
|
28
|
+
import { appendFileSync, existsSync, mkdirSync } from 'fs';
|
|
29
|
+
import { dirname, join } from 'path';
|
|
30
|
+
export const TRAJECTORY_FILE = '.swarm/model-router-trajectories.jsonl';
|
|
31
|
+
/** Schema version stamped on every row so offline training can dispatch. */
|
|
32
|
+
const ROW_VERSION = 1;
|
|
33
|
+
export function trajectoryCollectionEnabled() {
|
|
34
|
+
return process.env.CLAUDE_FLOW_ROUTER_TRAJECTORY === '1';
|
|
35
|
+
}
|
|
36
|
+
/** Join key: first 16 hex chars of sha256(task). */
|
|
37
|
+
export function taskHash(task) {
|
|
38
|
+
return createHash('sha256').update(task).digest('hex').slice(0, 16);
|
|
39
|
+
}
|
|
40
|
+
function appendRow(row) {
|
|
41
|
+
try {
|
|
42
|
+
const fullPath = join(process.cwd(), TRAJECTORY_FILE);
|
|
43
|
+
const dir = dirname(fullPath);
|
|
44
|
+
if (!existsSync(dir))
|
|
45
|
+
mkdirSync(dir, { recursive: true });
|
|
46
|
+
appendFileSync(fullPath, JSON.stringify(row) + '\n');
|
|
47
|
+
}
|
|
48
|
+
catch {
|
|
49
|
+
// Best-effort: collection must never break routing.
|
|
50
|
+
}
|
|
51
|
+
}
|
|
52
|
+
export function recordTrajectoryDecision(task, embedding, complexity, decision) {
|
|
53
|
+
if (!trajectoryCollectionEnabled())
|
|
54
|
+
return;
|
|
55
|
+
appendRow({
|
|
56
|
+
v: ROW_VERSION,
|
|
57
|
+
type: 'decision',
|
|
58
|
+
ts: new Date().toISOString(),
|
|
59
|
+
taskHash: taskHash(task),
|
|
60
|
+
task: task.slice(0, 500),
|
|
61
|
+
...(embedding && embedding.length > 0 ? { embedding } : {}),
|
|
62
|
+
complexity: complexity.score,
|
|
63
|
+
features: {
|
|
64
|
+
lexicalComplexity: complexity.lexicalComplexity,
|
|
65
|
+
semanticDepth: complexity.semanticDepth,
|
|
66
|
+
taskScope: complexity.taskScope,
|
|
67
|
+
uncertaintyLevel: complexity.uncertaintyLevel,
|
|
68
|
+
},
|
|
69
|
+
model: decision.model,
|
|
70
|
+
confidence: decision.confidence,
|
|
71
|
+
uncertainty: decision.uncertainty,
|
|
72
|
+
routedBy: decision.routedBy,
|
|
73
|
+
});
|
|
74
|
+
}
|
|
75
|
+
export function recordTrajectoryOutcome(task, model, outcome) {
|
|
76
|
+
if (!trajectoryCollectionEnabled())
|
|
77
|
+
return;
|
|
78
|
+
appendRow({
|
|
79
|
+
v: ROW_VERSION,
|
|
80
|
+
type: 'outcome',
|
|
81
|
+
ts: new Date().toISOString(),
|
|
82
|
+
taskHash: taskHash(task),
|
|
83
|
+
model,
|
|
84
|
+
outcome,
|
|
85
|
+
});
|
|
86
|
+
}
|
|
87
|
+
//# sourceMappingURL=router-trajectory.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"router-trajectory.js","sourceRoot":"","sources":["../../../src/ruvector/router-trajectory.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;GAyBG;AAEH,OAAO,EAAE,UAAU,EAAE,MAAM,QAAQ,CAAC;AACpC,OAAO,EAAE,cAAc,EAAE,UAAU,EAAE,SAAS,EAAE,MAAM,IAAI,CAAC;AAC3D,OAAO,EAAE,OAAO,EAAE,IAAI,EAAE,MAAM,MAAM,CAAC;AAErC,MAAM,CAAC,MAAM,eAAe,GAAG,wCAAwC,CAAC;AAExE,4EAA4E;AAC5E,MAAM,WAAW,GAAG,CAAC,CAAC;AAEtB,MAAM,UAAU,2BAA2B;IACzC,OAAO,OAAO,CAAC,GAAG,CAAC,6BAA6B,KAAK,GAAG,CAAC;AAC3D,CAAC;AAED,oDAAoD;AACpD,MAAM,UAAU,QAAQ,CAAC,IAAY;IACnC,OAAO,UAAU,CAAC,QAAQ,CAAC,CAAC,MAAM,CAAC,IAAI,CAAC,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC,KAAK,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC;AACtE,CAAC;AAiCD,SAAS,SAAS,CAAC,GAAiD;IAClE,IAAI,CAAC;QACH,MAAM,QAAQ,GAAG,IAAI,CAAC,OAAO,CAAC,GAAG,EAAE,EAAE,eAAe,CAAC,CAAC;QACtD,MAAM,GAAG,GAAG,OAAO,CAAC,QAAQ,CAAC,CAAC;QAC9B,IAAI,CAAC,UAAU,CAAC,GAAG,CAAC;YAAE,SAAS,CAAC,GAAG,EAAE,EAAE,SAAS,EAAE,IAAI,EAAE,CAAC,CAAC;QAC1D,cAAc,CAAC,QAAQ,EAAE,IAAI,CAAC,SAAS,CAAC,GAAG,CAAC,GAAG,IAAI,CAAC,CAAC;IACvD,CAAC;IAAC,MAAM,CAAC;QACP,oDAAoD;IACtD,CAAC;AACH,CAAC;AAED,MAAM,UAAU,wBAAwB,CACtC,IAAY,EACZ,SAA+B,EAC/B,UAAiE,EACjE,QAAsF;IAEtF,IAAI,CAAC,2BAA2B,EAAE;QAAE,OAAO;IAC3C,SAAS,CAAC;QACR,CAAC,EAAE,WAAW;QACd,IAAI,EAAE,UAAU;QAChB,EAAE,EAAE,IAAI,IAAI,EAAE,CAAC,WAAW,EAAE;QAC5B,QAAQ,EAAE,QAAQ,CAAC,IAAI,CAAC;QACxB,IAAI,EAAE,IAAI,CAAC,KAAK,CAAC,CAAC,EAAE,GAAG,CAAC;QACxB,GAAG,CAAC,SAAS,IAAI,SAAS,CAAC,MAAM,GAAG,CAAC,CAAC,CAAC,CAAC,EAAE,SAAS,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;QAC3D,UAAU,EAAE,UAAU,CAAC,KAAK;QAC5B,QAAQ,EAAE;YACR,iBAAiB,EAAE,UAAU,CAAC,iBAAiB;YAC/C,aAAa,EAAE,UAAU,CAAC,aAAa;YACvC,SAAS,EAAE,UAAU,CAAC,SAAS;YAC/B,gBAAgB,EAAE,UAAU,CAAC,gBAAgB;SAC9C;QACD,KAAK,EAAE,QAAQ,CAAC,KAAK;QACrB,UAAU,EAAE,QAAQ,CAAC,UAAU;QAC/B,WAAW,EAAE,QAAQ,CAAC,WAAW;QACjC,QAAQ,EAAE,QAAQ,CAAC,QAAQ;KAC5B,CAAC,CAAC;AACL,CAAC;AAED,MAAM,UAAU,uBAAuB,CACrC,IAAY,EACZ,KAAa,EACb,OAA4C;IAE5C,IAAI,CAAC,2BAA2B,EAAE;QAAE,OAAO;IAC3C,SAAS,CAAC;QACR,CAAC,EAAE,WAAW;QACd,IAAI,EAAE,SAAS;QACf,EAAE,EAAE,IAAI,IAAI,EAAE,CAAC,WAAW,EAAE;QAC5B,QAAQ,EAAE,QAAQ,CAAC,IAAI,CAAC;QACxB,KAAK;QACL,OAAO;KACR,CAAC,CAAC;AACL,CAAC"}
|