@triflux/core 10.51.0 → 10.52.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/hub/bridge.mjs +65 -1172
- package/hub/index.mjs +2 -18
- package/hub/lib/process-utils.mjs +1 -33
- package/hub/team/claude-daemon-control.mjs +1 -2
- package/hub/team/claude-session-projection.mjs +5 -73
- package/hub/team/nativeProxy.mjs +759 -0
- package/hub/team/session-context.mjs +1 -1
- package/hud/constants.mjs +2 -0
- package/hud/hud-qos-status.mjs +21 -5
- package/hud/providers/gemini.mjs +20 -0
- package/hud/renderers.mjs +79 -46
- package/hud/utils.mjs +9 -5
- package/package.json +2 -4
- package/scripts/lib/agent-route-policy.mjs +0 -67
- package/scripts/lib/cli-claude.mjs +0 -12
- package/scripts/lib/env-probe.mjs +0 -70
- package/scripts/lib/legacy-mcp-cleanup.mjs +283 -0
- package/scripts/lib/mcp-guard-engine.mjs +40 -98
- package/scripts/lib/session-presence.mjs +1 -99
- package/hub/adaptive-diagnostic.mjs +0 -350
- package/hub/adaptive-inject.mjs +0 -224
- package/hub/adaptive-memory.mjs +0 -277
- package/hub/adaptive.mjs +0 -172
- package/hub/assign-callbacks.mjs +0 -170
- package/hub/delegator/contracts.mjs +0 -38
- package/hub/delegator/index.mjs +0 -14
- package/hub/delegator/schema/delegator-tools.schema.json +0 -250
- package/hub/delegator/service.mjs +0 -336
- package/hub/delegator/tool-definitions.mjs +0 -35
- package/hub/hitl.mjs +0 -202
- package/hub/lib/known-errors.json +0 -72
- package/hub/lib/memory-store.mjs +0 -1001
- package/hub/lib/phase-manager.mjs +0 -493
- package/hub/lib/state-snapshot.mjs +0 -293
- package/hub/lib/trace-recorder.mjs +0 -153
- package/hub/lib/uuidv7.mjs +0 -45
- package/hub/memory-doctor.mjs +0 -640
- package/hub/middleware/quota-middleware.mjs +0 -70
- package/hub/middleware/request-logger.mjs +0 -191
- package/hub/paths.mjs +0 -24
- package/hub/pipeline/index.mjs +0 -163
- package/hub/pipeline/state.mjs +0 -191
- package/hub/pipeline/transitions.mjs +0 -131
- package/hub/reflexion.mjs +0 -290
- package/hub/role-contract.mjs +0 -312
- package/hub/router.mjs +0 -2026
- package/hub/session-fingerprint.mjs +0 -418
- package/hub/state.mjs +0 -300
- package/hub/team/synapse-http.mjs +0 -311
- package/hub/team-bridge.mjs +0 -27
- package/scripts/lib/claudemd-scanner.mjs +0 -26
- package/scripts/lib/context.mjs +0 -51
- package/scripts/lib/handoff.mjs +0 -187
- package/scripts/lib/logger.mjs +0 -122
- package/scripts/lib/stealth-fetch.mjs +0 -176
package/hub/adaptive-memory.mjs
DELETED
|
@@ -1,277 +0,0 @@
|
|
|
1
|
-
import {
|
|
2
|
-
existsSync,
|
|
3
|
-
mkdirSync,
|
|
4
|
-
readFileSync,
|
|
5
|
-
rmSync,
|
|
6
|
-
writeFileSync,
|
|
7
|
-
} from "node:fs";
|
|
8
|
-
import { homedir } from "node:os";
|
|
9
|
-
import { join } from "node:path";
|
|
10
|
-
|
|
11
|
-
const SESSION_FILE = "adaptive-session.json";
|
|
12
|
-
const DEFAULT_CONFIDENCE = 0.5;
|
|
13
|
-
const TIER2_DECAY_STEP = 0.2;
|
|
14
|
-
const TIER2_DECAY_INTERVAL = 5;
|
|
15
|
-
const TIER2_REMOVE_THRESHOLD = 0.3;
|
|
16
|
-
const TIER3_WARN_THRESHOLD = 10;
|
|
17
|
-
const TIER3_REMOVE_THRESHOLD = 20;
|
|
18
|
-
|
|
19
|
-
const clone = (v) => (v == null ? v : JSON.parse(JSON.stringify(v)));
|
|
20
|
-
const clamp01 = (v) => {
|
|
21
|
-
const n = Number(v);
|
|
22
|
-
return Number.isFinite(n)
|
|
23
|
-
? Number(Math.max(0, Math.min(1, n)).toFixed(4))
|
|
24
|
-
: DEFAULT_CONFIDENCE;
|
|
25
|
-
};
|
|
26
|
-
const toDate = (v = Date.now()) => {
|
|
27
|
-
const d = new Date(v);
|
|
28
|
-
return Number.isNaN(d.getTime())
|
|
29
|
-
? new Date().toISOString().slice(0, 10)
|
|
30
|
-
: d.toISOString().slice(0, 10);
|
|
31
|
-
};
|
|
32
|
-
const uniq = (arr) => [
|
|
33
|
-
...new Set(arr.filter((s) => typeof s === "string" && s.trim())),
|
|
34
|
-
];
|
|
35
|
-
const slugify = (v) =>
|
|
36
|
-
String(v || "")
|
|
37
|
-
.trim()
|
|
38
|
-
.toLowerCase()
|
|
39
|
-
.replace(/[^a-z0-9]+/g, "-")
|
|
40
|
-
.replace(/^-+|-+$/g, "")
|
|
41
|
-
.slice(0, 80);
|
|
42
|
-
const buildId = (r) => {
|
|
43
|
-
const e = slugify(r.id);
|
|
44
|
-
if (e) return e;
|
|
45
|
-
const p = slugify(r.pattern);
|
|
46
|
-
return p || `adaptive-${Date.now()}`;
|
|
47
|
-
};
|
|
48
|
-
const readJson = (f, fb) => {
|
|
49
|
-
if (!existsSync(f)) return clone(fb);
|
|
50
|
-
try {
|
|
51
|
-
return { ...clone(fb), ...JSON.parse(readFileSync(f, "utf8")) };
|
|
52
|
-
} catch {
|
|
53
|
-
return clone(fb);
|
|
54
|
-
}
|
|
55
|
-
};
|
|
56
|
-
const writeJson = (f, v) =>
|
|
57
|
-
writeFileSync(f, `${JSON.stringify(v, null, 2)}\n`, "utf8");
|
|
58
|
-
const strip = (r) => {
|
|
59
|
-
if (!r) return null;
|
|
60
|
-
const { sessionIds, ...pub } = r;
|
|
61
|
-
return clone(pub);
|
|
62
|
-
};
|
|
63
|
-
const sortRules = (list) =>
|
|
64
|
-
[...list].sort(
|
|
65
|
-
(a, b) =>
|
|
66
|
-
a.tier - b.tier ||
|
|
67
|
-
b.confidence - a.confidence ||
|
|
68
|
-
a.id.localeCompare(b.id),
|
|
69
|
-
);
|
|
70
|
-
const upsert = (list, r) => [...list.filter((x) => x.id !== r.id), r];
|
|
71
|
-
const without = (list, id) => list.filter((x) => x.id !== id);
|
|
72
|
-
|
|
73
|
-
function toRule(rule, tier, sessionId, existing = null) {
|
|
74
|
-
return {
|
|
75
|
-
id: existing?.id || buildId(rule),
|
|
76
|
-
pattern: String(rule.pattern || existing?.pattern || ""),
|
|
77
|
-
rootCause: String(
|
|
78
|
-
rule.rootCause || rule.root_cause || existing?.rootCause || "",
|
|
79
|
-
),
|
|
80
|
-
rule: String(rule.rule || existing?.rule || ""),
|
|
81
|
-
confidence: clamp01(rule.confidence ?? existing?.confidence),
|
|
82
|
-
occurrences: Math.max(1, Number(existing?.occurrences || 0) + 1),
|
|
83
|
-
firstSeen: existing?.firstSeen || toDate(rule.timestamp),
|
|
84
|
-
lastSeen: toDate(rule.timestamp),
|
|
85
|
-
sessionsWithout: 0,
|
|
86
|
-
tier,
|
|
87
|
-
dnaFactor: rule.dnaFactor ?? rule.dna_factor ?? existing?.dnaFactor ?? null,
|
|
88
|
-
sessionIds: uniq([...(existing?.sessionIds || []), sessionId]),
|
|
89
|
-
};
|
|
90
|
-
}
|
|
91
|
-
|
|
92
|
-
export function createAdaptiveMemory(opts = {}) {
|
|
93
|
-
const projectSlug = slugify(opts.projectSlug);
|
|
94
|
-
if (!projectSlug) throw new Error("projectSlug is required");
|
|
95
|
-
|
|
96
|
-
const sessionDir = opts.sessionDir || join(process.cwd(), ".omc", "state");
|
|
97
|
-
const globalDir = opts.globalDir || join(homedir(), ".triflux", "adaptive");
|
|
98
|
-
const sessionFile = join(sessionDir, SESSION_FILE);
|
|
99
|
-
const projectFile = join(globalDir, `${projectSlug}.json`);
|
|
100
|
-
|
|
101
|
-
mkdirSync(sessionDir, { recursive: true });
|
|
102
|
-
mkdirSync(globalDir, { recursive: true });
|
|
103
|
-
|
|
104
|
-
let ss = readJson(sessionFile, { projectSlug, sessionId: null, rules: [] });
|
|
105
|
-
let ps = readJson(projectFile, {
|
|
106
|
-
projectSlug,
|
|
107
|
-
history: {},
|
|
108
|
-
tier2: [],
|
|
109
|
-
tier3: [],
|
|
110
|
-
});
|
|
111
|
-
|
|
112
|
-
function saveSession() {
|
|
113
|
-
if (ss.rules.length === 0) {
|
|
114
|
-
rmSync(sessionFile, { force: true });
|
|
115
|
-
return;
|
|
116
|
-
}
|
|
117
|
-
writeJson(sessionFile, ss);
|
|
118
|
-
}
|
|
119
|
-
|
|
120
|
-
function saveProject() {
|
|
121
|
-
const has =
|
|
122
|
-
Object.keys(ps.history).length > 0 ||
|
|
123
|
-
ps.tier2.length > 0 ||
|
|
124
|
-
ps.tier3.length > 0;
|
|
125
|
-
if (!has) {
|
|
126
|
-
rmSync(projectFile, { force: true });
|
|
127
|
-
return;
|
|
128
|
-
}
|
|
129
|
-
writeJson(projectFile, ps);
|
|
130
|
-
}
|
|
131
|
-
|
|
132
|
-
const saveAll = () => {
|
|
133
|
-
saveSession();
|
|
134
|
-
saveProject();
|
|
135
|
-
};
|
|
136
|
-
|
|
137
|
-
function getSessionId(id) {
|
|
138
|
-
const next = String(id || ss.sessionId || "session-current");
|
|
139
|
-
ss = { ...ss, sessionId: next };
|
|
140
|
-
return next;
|
|
141
|
-
}
|
|
142
|
-
|
|
143
|
-
const getDurable = (id) =>
|
|
144
|
-
ps.tier3.find((r) => r.id === id) ||
|
|
145
|
-
ps.tier2.find((r) => r.id === id) ||
|
|
146
|
-
null;
|
|
147
|
-
|
|
148
|
-
function promote(ruleId) {
|
|
149
|
-
const t2 = ps.tier2.find((r) => r.id === ruleId);
|
|
150
|
-
if (t2 && t2.occurrences >= 3 && t2.confidence >= 0.8) {
|
|
151
|
-
const next = { ...t2, tier: 3, sessionsWithout: 0 };
|
|
152
|
-
ps = {
|
|
153
|
-
...ps,
|
|
154
|
-
tier2: without(ps.tier2, ruleId),
|
|
155
|
-
tier3: upsert(ps.tier3, next),
|
|
156
|
-
};
|
|
157
|
-
saveProject();
|
|
158
|
-
return { rule: strip(next), promoted: true, fromTier: 2, toTier: 3 };
|
|
159
|
-
}
|
|
160
|
-
const cand = ps.history[ruleId];
|
|
161
|
-
if (cand && cand.occurrences >= 2 && cand.sessionIds.length >= 2) {
|
|
162
|
-
const next = { ...cand, tier: 2, sessionsWithout: 0 };
|
|
163
|
-
const { [ruleId]: _, ...history } = ps.history;
|
|
164
|
-
ps = { ...ps, history, tier2: upsert(ps.tier2, next) };
|
|
165
|
-
ss = { ...ss, rules: without(ss.rules, ruleId) };
|
|
166
|
-
saveAll();
|
|
167
|
-
return { rule: strip(next), promoted: true, fromTier: 1, toTier: 2 };
|
|
168
|
-
}
|
|
169
|
-
const cur = getDurable(ruleId) || ps.history[ruleId] || null;
|
|
170
|
-
return {
|
|
171
|
-
rule: strip(cur),
|
|
172
|
-
promoted: false,
|
|
173
|
-
fromTier: cur?.tier ?? null,
|
|
174
|
-
toTier: cur?.tier ?? null,
|
|
175
|
-
};
|
|
176
|
-
}
|
|
177
|
-
|
|
178
|
-
function record(rule = {}) {
|
|
179
|
-
if (!rule.pattern)
|
|
180
|
-
return { rule: null, promoted: false, fromTier: null, toTier: null };
|
|
181
|
-
const sessionId = getSessionId(rule.sessionId);
|
|
182
|
-
const ruleId = buildId(rule);
|
|
183
|
-
const durable = getDurable(ruleId);
|
|
184
|
-
if (durable) {
|
|
185
|
-
const next = toRule(rule, durable.tier, sessionId, durable);
|
|
186
|
-
ps =
|
|
187
|
-
durable.tier === 3
|
|
188
|
-
? { ...ps, tier3: upsert(ps.tier3, next) }
|
|
189
|
-
: { ...ps, tier2: upsert(ps.tier2, next) };
|
|
190
|
-
saveProject();
|
|
191
|
-
const res = promote(ruleId);
|
|
192
|
-
return res.promoted
|
|
193
|
-
? res
|
|
194
|
-
: {
|
|
195
|
-
rule: strip(next),
|
|
196
|
-
promoted: false,
|
|
197
|
-
fromTier: durable.tier,
|
|
198
|
-
toTier: durable.tier,
|
|
199
|
-
};
|
|
200
|
-
}
|
|
201
|
-
const cand = toRule(rule, 1, sessionId, ps.history[ruleId]);
|
|
202
|
-
ps = { ...ps, history: { ...ps.history, [ruleId]: cand } };
|
|
203
|
-
ss = { ...ss, rules: upsert(ss.rules, { ...cand, tier: 1 }) };
|
|
204
|
-
saveAll();
|
|
205
|
-
const res = promote(ruleId);
|
|
206
|
-
return res.promoted
|
|
207
|
-
? res
|
|
208
|
-
: { rule: strip(cand), promoted: false, fromTier: 1, toTier: 1 };
|
|
209
|
-
}
|
|
210
|
-
|
|
211
|
-
function decay(sessionId) {
|
|
212
|
-
const nextId = String(sessionId || `session-${Date.now()}`);
|
|
213
|
-
if (ss.sessionId === nextId)
|
|
214
|
-
return {
|
|
215
|
-
sessionId: nextId,
|
|
216
|
-
tier1Cleared: 0,
|
|
217
|
-
updated: [],
|
|
218
|
-
warned: [],
|
|
219
|
-
removed: [],
|
|
220
|
-
};
|
|
221
|
-
const warned = [],
|
|
222
|
-
removed = [],
|
|
223
|
-
updated = [];
|
|
224
|
-
const tier1Cleared = ss.rules.length;
|
|
225
|
-
const tier2 = ps.tier2.flatMap((r) => {
|
|
226
|
-
const sw = Number(r.sessionsWithout || 0) + 1;
|
|
227
|
-
const conf =
|
|
228
|
-
sw % TIER2_DECAY_INTERVAL === 0
|
|
229
|
-
? clamp01(r.confidence - TIER2_DECAY_STEP)
|
|
230
|
-
: r.confidence;
|
|
231
|
-
if (conf < TIER2_REMOVE_THRESHOLD) {
|
|
232
|
-
removed.push(r.id);
|
|
233
|
-
return [];
|
|
234
|
-
}
|
|
235
|
-
updated.push(r.id);
|
|
236
|
-
return [{ ...r, sessionsWithout: sw, confidence: conf }];
|
|
237
|
-
});
|
|
238
|
-
const tier3 = ps.tier3.flatMap((r) => {
|
|
239
|
-
const sw = Number(r.sessionsWithout || 0) + 1;
|
|
240
|
-
if (sw >= TIER3_REMOVE_THRESHOLD) {
|
|
241
|
-
removed.push(r.id);
|
|
242
|
-
return [];
|
|
243
|
-
}
|
|
244
|
-
if (sw === TIER3_WARN_THRESHOLD) warned.push(r.id);
|
|
245
|
-
updated.push(r.id);
|
|
246
|
-
return [{ ...r, sessionsWithout: sw }];
|
|
247
|
-
});
|
|
248
|
-
ss = { ...ss, sessionId: nextId, rules: [] };
|
|
249
|
-
ps = { ...ps, tier2, tier3 };
|
|
250
|
-
saveAll();
|
|
251
|
-
return { sessionId: nextId, tier1Cleared, updated, warned, removed };
|
|
252
|
-
}
|
|
253
|
-
|
|
254
|
-
function getRule(id) {
|
|
255
|
-
return strip(ss.rules.find((r) => r.id === id) || getDurable(id));
|
|
256
|
-
}
|
|
257
|
-
function getTier(tier) {
|
|
258
|
-
if (tier === 1) return sortRules(ss.rules).map(strip);
|
|
259
|
-
if (tier === 2) return sortRules(ps.tier2).map(strip);
|
|
260
|
-
if (tier === 3) return sortRules(ps.tier3).map(strip);
|
|
261
|
-
return [];
|
|
262
|
-
}
|
|
263
|
-
function getAllRules() {
|
|
264
|
-
return sortRules([...ss.rules, ...ps.tier2, ...ps.tier3]).map(strip);
|
|
265
|
-
}
|
|
266
|
-
function reset(target = "all") {
|
|
267
|
-
const rs = target === "all" || target === 1 || target === "session";
|
|
268
|
-
const rp =
|
|
269
|
-
target === "all" || target === 2 || target === 3 || target === "project";
|
|
270
|
-
if (rs) ss = { ...ss, rules: [] };
|
|
271
|
-
if (rp) ps = { ...ps, history: {}, tier2: [], tier3: [] };
|
|
272
|
-
saveAll();
|
|
273
|
-
return { sessionCleared: rs, projectCleared: rp };
|
|
274
|
-
}
|
|
275
|
-
|
|
276
|
-
return { record, promote, decay, getRule, getAllRules, getTier, reset };
|
|
277
|
-
}
|
package/hub/adaptive.mjs
DELETED
|
@@ -1,172 +0,0 @@
|
|
|
1
|
-
import { randomUUID } from "node:crypto";
|
|
2
|
-
import { join } from "node:path";
|
|
3
|
-
import { createDiagnosticPipeline } from "./adaptive-diagnostic.mjs";
|
|
4
|
-
import { createAdaptiveInjector } from "./adaptive-inject.mjs";
|
|
5
|
-
import { createAdaptiveMemory } from "./adaptive-memory.mjs";
|
|
6
|
-
import { createAdaptiveFingerprintService } from "./session-fingerprint.mjs";
|
|
7
|
-
|
|
8
|
-
let singletonEngine = null;
|
|
9
|
-
|
|
10
|
-
function clone(value) {
|
|
11
|
-
return value == null ? value : JSON.parse(JSON.stringify(value));
|
|
12
|
-
}
|
|
13
|
-
|
|
14
|
-
function toRuleList(value) {
|
|
15
|
-
return Array.isArray(value) ? value : [];
|
|
16
|
-
}
|
|
17
|
-
|
|
18
|
-
function resolveTierCount(memory, tier) {
|
|
19
|
-
if (typeof memory.getTier === "function") {
|
|
20
|
-
const rules = memory.getTier(tier);
|
|
21
|
-
return Array.isArray(rules) ? rules.length : 0;
|
|
22
|
-
}
|
|
23
|
-
return toRuleList(memory.getAllRules?.()).filter(
|
|
24
|
-
(rule) => Number(rule?.tier) === tier,
|
|
25
|
-
).length;
|
|
26
|
-
}
|
|
27
|
-
|
|
28
|
-
function resolveActiveRuleIds(memory, decayResult) {
|
|
29
|
-
if (Array.isArray(decayResult?.activeRuleIds))
|
|
30
|
-
return [...decayResult.activeRuleIds];
|
|
31
|
-
return toRuleList(memory.getAllRules?.())
|
|
32
|
-
.map((rule) => rule.id)
|
|
33
|
-
.filter(Boolean);
|
|
34
|
-
}
|
|
35
|
-
|
|
36
|
-
function resolveRecordedRule(recordResult) {
|
|
37
|
-
if (recordResult?.rule)
|
|
38
|
-
return {
|
|
39
|
-
rule: recordResult.rule,
|
|
40
|
-
promoted: Boolean(recordResult.promoted),
|
|
41
|
-
};
|
|
42
|
-
return { rule: recordResult || null, promoted: false };
|
|
43
|
-
}
|
|
44
|
-
|
|
45
|
-
function createEngineInstance(opts = {}) {
|
|
46
|
-
const repoRoot = opts.repoRoot || process.cwd();
|
|
47
|
-
const claudeMdPath = opts.claudeMdPath || join(repoRoot, "CLAUDE.md");
|
|
48
|
-
const projectSlug = String(opts.projectSlug || "default").trim() || "default";
|
|
49
|
-
const now = opts.now || (() => Date.now());
|
|
50
|
-
const sessionIdFactory = opts.sessionIdFactory || (() => randomUUID());
|
|
51
|
-
|
|
52
|
-
const memory =
|
|
53
|
-
opts.memory ||
|
|
54
|
-
opts.memoryFactory?.(opts) ||
|
|
55
|
-
createAdaptiveMemory({ projectSlug, ...opts.memoryOptions });
|
|
56
|
-
const diagnostic =
|
|
57
|
-
opts.diagnostic ||
|
|
58
|
-
opts.diagnosticFactory?.(opts) ||
|
|
59
|
-
createDiagnosticPipeline(opts.diagnosticOptions);
|
|
60
|
-
const injector =
|
|
61
|
-
opts.injector ||
|
|
62
|
-
opts.injectorFactory?.(opts) ||
|
|
63
|
-
createAdaptiveInjector({ claudeMdPath, ...opts.injectorOptions });
|
|
64
|
-
const fingerprintService =
|
|
65
|
-
opts.fingerprintService ||
|
|
66
|
-
opts.fingerprintFactory?.(opts) ||
|
|
67
|
-
createAdaptiveFingerprintService(opts.fingerprintOptions);
|
|
68
|
-
|
|
69
|
-
let started = false;
|
|
70
|
-
let currentSessionId = null;
|
|
71
|
-
let lastFingerprintId = null;
|
|
72
|
-
const counters = {
|
|
73
|
-
totalErrors: 0,
|
|
74
|
-
diagnosedErrors: 0,
|
|
75
|
-
};
|
|
76
|
-
|
|
77
|
-
function refreshFingerprint() {
|
|
78
|
-
if (typeof fingerprintService.computeFingerprint !== "function") return;
|
|
79
|
-
const fingerprint = fingerprintService.computeFingerprint({
|
|
80
|
-
scope: projectSlug,
|
|
81
|
-
cwd: repoRoot,
|
|
82
|
-
filePath: claudeMdPath,
|
|
83
|
-
workType: "adaptive",
|
|
84
|
-
timestamp: now(),
|
|
85
|
-
});
|
|
86
|
-
lastFingerprintId = fingerprint?.fingerprint_id || lastFingerprintId;
|
|
87
|
-
}
|
|
88
|
-
|
|
89
|
-
function startSession() {
|
|
90
|
-
if (started) return;
|
|
91
|
-
currentSessionId = sessionIdFactory();
|
|
92
|
-
const decayResult =
|
|
93
|
-
typeof memory.decay === "function"
|
|
94
|
-
? memory.decay(currentSessionId)
|
|
95
|
-
: null;
|
|
96
|
-
injector.cleanup?.(resolveActiveRuleIds(memory, decayResult));
|
|
97
|
-
refreshFingerprint();
|
|
98
|
-
started = true;
|
|
99
|
-
}
|
|
100
|
-
|
|
101
|
-
function handleError(errorContext = {}) {
|
|
102
|
-
if (!started) startSession();
|
|
103
|
-
counters.totalErrors += 1;
|
|
104
|
-
|
|
105
|
-
const diagnosis = diagnostic.diagnose({
|
|
106
|
-
...errorContext,
|
|
107
|
-
projectSlug,
|
|
108
|
-
sessionId: currentSessionId,
|
|
109
|
-
});
|
|
110
|
-
if (!diagnosis?.matched || !diagnosis.rule) {
|
|
111
|
-
return Object.freeze({ diagnosed: false, rule: null, promoted: false });
|
|
112
|
-
}
|
|
113
|
-
|
|
114
|
-
counters.diagnosedErrors += 1;
|
|
115
|
-
const { rule: recordedRule, promoted } = resolveRecordedRule(
|
|
116
|
-
memory.record({
|
|
117
|
-
...diagnosis.rule,
|
|
118
|
-
confidence: diagnosis.confidence,
|
|
119
|
-
dnaFactor: diagnosis.dnaFactor,
|
|
120
|
-
sessionId: currentSessionId,
|
|
121
|
-
lastSeen: new Date(now()).toISOString().slice(0, 10),
|
|
122
|
-
}),
|
|
123
|
-
);
|
|
124
|
-
|
|
125
|
-
const nextRule = clone(recordedRule || diagnosis.rule);
|
|
126
|
-
if (nextRule?.tier >= 3 && promoted) {
|
|
127
|
-
injector.inject?.(nextRule);
|
|
128
|
-
}
|
|
129
|
-
|
|
130
|
-
return Object.freeze({
|
|
131
|
-
diagnosed: true,
|
|
132
|
-
rule: nextRule,
|
|
133
|
-
promoted: Boolean(promoted),
|
|
134
|
-
});
|
|
135
|
-
}
|
|
136
|
-
|
|
137
|
-
function endSession() {
|
|
138
|
-
if (!started) return;
|
|
139
|
-
memory.reset?.({ tier: 1, sessionId: currentSessionId });
|
|
140
|
-
started = false;
|
|
141
|
-
currentSessionId = null;
|
|
142
|
-
}
|
|
143
|
-
|
|
144
|
-
function getStats() {
|
|
145
|
-
return Object.freeze({
|
|
146
|
-
tier1Count: resolveTierCount(memory, 1),
|
|
147
|
-
tier2Count: resolveTierCount(memory, 2),
|
|
148
|
-
tier3Count: resolveTierCount(memory, 3),
|
|
149
|
-
totalErrors: counters.totalErrors,
|
|
150
|
-
});
|
|
151
|
-
}
|
|
152
|
-
|
|
153
|
-
return Object.freeze({
|
|
154
|
-
handleError,
|
|
155
|
-
startSession,
|
|
156
|
-
endSession,
|
|
157
|
-
getStats,
|
|
158
|
-
__lastFingerprintId: () => lastFingerprintId,
|
|
159
|
-
});
|
|
160
|
-
}
|
|
161
|
-
|
|
162
|
-
export function createAdaptiveEngine(opts = {}) {
|
|
163
|
-
if (singletonEngine) return singletonEngine;
|
|
164
|
-
singletonEngine = createEngineInstance(opts);
|
|
165
|
-
return singletonEngine;
|
|
166
|
-
}
|
|
167
|
-
|
|
168
|
-
export function __resetAdaptiveEngineForTests() {
|
|
169
|
-
singletonEngine = null;
|
|
170
|
-
}
|
|
171
|
-
|
|
172
|
-
export default createAdaptiveEngine;
|
package/hub/assign-callbacks.mjs
DELETED
|
@@ -1,170 +0,0 @@
|
|
|
1
|
-
// hub/assign-callbacks.mjs — assign job 상태 변경용 Named Pipe/Unix socket 브로드캐스터
|
|
2
|
-
|
|
3
|
-
import { existsSync, unlinkSync } from "node:fs";
|
|
4
|
-
import net from "node:net";
|
|
5
|
-
import { IS_WINDOWS, pipePath } from "./platform.mjs";
|
|
6
|
-
|
|
7
|
-
export function getAssignCallbackPipePath(sessionId = process.pid) {
|
|
8
|
-
return pipePath("triflux-assign-callback", sessionId);
|
|
9
|
-
}
|
|
10
|
-
|
|
11
|
-
function buildAssignCallbackEvent(event = {}, row = null) {
|
|
12
|
-
const source = row || event || {};
|
|
13
|
-
const updatedAtMs = Number(source.updated_at_ms);
|
|
14
|
-
const createdAtMs = Number(source.created_at_ms);
|
|
15
|
-
const timestampMs = Number.isFinite(updatedAtMs)
|
|
16
|
-
? updatedAtMs
|
|
17
|
-
: Number.isFinite(createdAtMs)
|
|
18
|
-
? createdAtMs
|
|
19
|
-
: Date.now();
|
|
20
|
-
|
|
21
|
-
return {
|
|
22
|
-
event: "assign_job_status",
|
|
23
|
-
job_id: source.job_id || event.job_id || null,
|
|
24
|
-
supervisor_agent: source.supervisor_agent || null,
|
|
25
|
-
worker_agent: source.worker_agent || null,
|
|
26
|
-
topic: source.topic || null,
|
|
27
|
-
task: source.task || null,
|
|
28
|
-
status: source.status || event.status || null,
|
|
29
|
-
attempt: Number.isFinite(Number(source.attempt))
|
|
30
|
-
? Number(source.attempt)
|
|
31
|
-
: null,
|
|
32
|
-
retry_count: Number.isFinite(Number(source.retry_count))
|
|
33
|
-
? Number(source.retry_count)
|
|
34
|
-
: null,
|
|
35
|
-
max_retries: Number.isFinite(Number(source.max_retries))
|
|
36
|
-
? Number(source.max_retries)
|
|
37
|
-
: null,
|
|
38
|
-
priority: Number.isFinite(Number(source.priority))
|
|
39
|
-
? Number(source.priority)
|
|
40
|
-
: null,
|
|
41
|
-
ttl_ms: Number.isFinite(Number(source.ttl_ms))
|
|
42
|
-
? Number(source.ttl_ms)
|
|
43
|
-
: null,
|
|
44
|
-
timeout_ms: Number.isFinite(Number(source.timeout_ms))
|
|
45
|
-
? Number(source.timeout_ms)
|
|
46
|
-
: null,
|
|
47
|
-
deadline_ms: Number.isFinite(Number(source.deadline_ms))
|
|
48
|
-
? Number(source.deadline_ms)
|
|
49
|
-
: null,
|
|
50
|
-
trace_id: source.trace_id || null,
|
|
51
|
-
correlation_id: source.correlation_id || null,
|
|
52
|
-
last_message_id: source.last_message_id || null,
|
|
53
|
-
result: Object.hasOwn(source, "result")
|
|
54
|
-
? source.result
|
|
55
|
-
: Object.hasOwn(event, "result")
|
|
56
|
-
? event.result
|
|
57
|
-
: null,
|
|
58
|
-
error: Object.hasOwn(source, "error")
|
|
59
|
-
? source.error
|
|
60
|
-
: Object.hasOwn(event, "error")
|
|
61
|
-
? event.error
|
|
62
|
-
: null,
|
|
63
|
-
created_at_ms: Number.isFinite(createdAtMs) ? createdAtMs : null,
|
|
64
|
-
updated_at_ms: Number.isFinite(updatedAtMs) ? updatedAtMs : null,
|
|
65
|
-
started_at_ms: Number.isFinite(Number(source.started_at_ms))
|
|
66
|
-
? Number(source.started_at_ms)
|
|
67
|
-
: null,
|
|
68
|
-
completed_at_ms: Number.isFinite(Number(source.completed_at_ms))
|
|
69
|
-
? Number(source.completed_at_ms)
|
|
70
|
-
: null,
|
|
71
|
-
last_retry_at_ms: Number.isFinite(Number(source.last_retry_at_ms))
|
|
72
|
-
? Number(source.last_retry_at_ms)
|
|
73
|
-
: null,
|
|
74
|
-
timestamp: new Date(timestampMs).toISOString(),
|
|
75
|
-
};
|
|
76
|
-
}
|
|
77
|
-
|
|
78
|
-
export function createAssignCallbackServer({
|
|
79
|
-
store = null,
|
|
80
|
-
sessionId = process.pid,
|
|
81
|
-
} = {}) {
|
|
82
|
-
const pipePath = getAssignCallbackPipePath(sessionId);
|
|
83
|
-
const clients = new Set();
|
|
84
|
-
let server = null;
|
|
85
|
-
let detachStoreListener = null;
|
|
86
|
-
|
|
87
|
-
function removeSocket(socket) {
|
|
88
|
-
if (!socket) return;
|
|
89
|
-
clients.delete(socket);
|
|
90
|
-
try {
|
|
91
|
-
socket.destroy();
|
|
92
|
-
} catch {}
|
|
93
|
-
}
|
|
94
|
-
|
|
95
|
-
function broadcast(event) {
|
|
96
|
-
const frame = `${JSON.stringify(event)}\n`;
|
|
97
|
-
for (const socket of Array.from(clients)) {
|
|
98
|
-
if (!socket.writable || socket.destroyed) {
|
|
99
|
-
removeSocket(socket);
|
|
100
|
-
continue;
|
|
101
|
-
}
|
|
102
|
-
try {
|
|
103
|
-
socket.write(frame);
|
|
104
|
-
} catch {
|
|
105
|
-
removeSocket(socket);
|
|
106
|
-
}
|
|
107
|
-
}
|
|
108
|
-
}
|
|
109
|
-
|
|
110
|
-
return {
|
|
111
|
-
path: pipePath,
|
|
112
|
-
getStatus() {
|
|
113
|
-
return {
|
|
114
|
-
path: pipePath,
|
|
115
|
-
clients: clients.size,
|
|
116
|
-
};
|
|
117
|
-
},
|
|
118
|
-
async start() {
|
|
119
|
-
if (server) return { path: pipePath };
|
|
120
|
-
if (!IS_WINDOWS && existsSync(pipePath)) {
|
|
121
|
-
try {
|
|
122
|
-
unlinkSync(pipePath);
|
|
123
|
-
} catch {}
|
|
124
|
-
}
|
|
125
|
-
|
|
126
|
-
server = net.createServer((socket) => {
|
|
127
|
-
clients.add(socket);
|
|
128
|
-
socket.setEncoding("utf8");
|
|
129
|
-
socket.on("error", () => removeSocket(socket));
|
|
130
|
-
socket.on("close", () => removeSocket(socket));
|
|
131
|
-
});
|
|
132
|
-
|
|
133
|
-
await new Promise((resolve, reject) => {
|
|
134
|
-
server.once("error", reject);
|
|
135
|
-
server.listen(pipePath, () => {
|
|
136
|
-
server?.off("error", reject);
|
|
137
|
-
resolve();
|
|
138
|
-
});
|
|
139
|
-
});
|
|
140
|
-
|
|
141
|
-
if (store?.onAssignStatusChange && !detachStoreListener) {
|
|
142
|
-
detachStoreListener = store.onAssignStatusChange((event, row) => {
|
|
143
|
-
broadcast(buildAssignCallbackEvent(event, row));
|
|
144
|
-
});
|
|
145
|
-
}
|
|
146
|
-
|
|
147
|
-
return { path: pipePath };
|
|
148
|
-
},
|
|
149
|
-
async stop() {
|
|
150
|
-
if (detachStoreListener) {
|
|
151
|
-
try {
|
|
152
|
-
detachStoreListener();
|
|
153
|
-
} catch {}
|
|
154
|
-
detachStoreListener = null;
|
|
155
|
-
}
|
|
156
|
-
if (!server) return;
|
|
157
|
-
for (const socket of Array.from(clients)) {
|
|
158
|
-
removeSocket(socket);
|
|
159
|
-
}
|
|
160
|
-
await new Promise((resolve) => server.close(resolve));
|
|
161
|
-
server = null;
|
|
162
|
-
if (!IS_WINDOWS && existsSync(pipePath)) {
|
|
163
|
-
try {
|
|
164
|
-
unlinkSync(pipePath);
|
|
165
|
-
} catch {}
|
|
166
|
-
}
|
|
167
|
-
},
|
|
168
|
-
broadcast,
|
|
169
|
-
};
|
|
170
|
-
}
|
|
@@ -1,38 +0,0 @@
|
|
|
1
|
-
export const DELEGATOR_MCP_SERVER_INFO = Object.freeze({
|
|
2
|
-
name: "triflux-delegator",
|
|
3
|
-
version: "0.1.0",
|
|
4
|
-
});
|
|
5
|
-
|
|
6
|
-
export const DELEGATOR_TOOL_NAMES = Object.freeze({
|
|
7
|
-
delegate: "delegate",
|
|
8
|
-
delegateReply: "delegate-reply",
|
|
9
|
-
status: "status",
|
|
10
|
-
});
|
|
11
|
-
|
|
12
|
-
export const DELEGATOR_PIPE_ACTIONS = Object.freeze({
|
|
13
|
-
delegate: "delegator_delegate",
|
|
14
|
-
delegateReply: "delegator_reply",
|
|
15
|
-
status: "delegator_status",
|
|
16
|
-
});
|
|
17
|
-
|
|
18
|
-
export const DELEGATOR_JOB_STATUSES = Object.freeze([
|
|
19
|
-
"queued",
|
|
20
|
-
"running",
|
|
21
|
-
"waiting_reply",
|
|
22
|
-
"completed",
|
|
23
|
-
"failed",
|
|
24
|
-
]);
|
|
25
|
-
|
|
26
|
-
export const DELEGATOR_MODES = Object.freeze(["sync", "async"]);
|
|
27
|
-
|
|
28
|
-
export const DELEGATOR_PROVIDERS = Object.freeze([
|
|
29
|
-
"auto",
|
|
30
|
-
"codex",
|
|
31
|
-
"antigravity",
|
|
32
|
-
"gemini",
|
|
33
|
-
]);
|
|
34
|
-
|
|
35
|
-
export const DELEGATOR_SCHEMA_URL = new URL(
|
|
36
|
-
"./schema/delegator-tools.schema.json",
|
|
37
|
-
import.meta.url,
|
|
38
|
-
);
|
package/hub/delegator/index.mjs
DELETED
|
@@ -1,14 +0,0 @@
|
|
|
1
|
-
export {
|
|
2
|
-
DELEGATOR_JOB_STATUSES,
|
|
3
|
-
DELEGATOR_MCP_SERVER_INFO,
|
|
4
|
-
DELEGATOR_MODES,
|
|
5
|
-
DELEGATOR_PIPE_ACTIONS,
|
|
6
|
-
DELEGATOR_PROVIDERS,
|
|
7
|
-
DELEGATOR_SCHEMA_URL,
|
|
8
|
-
DELEGATOR_TOOL_NAMES,
|
|
9
|
-
} from "./contracts.mjs";
|
|
10
|
-
export { DelegatorService } from "./service.mjs";
|
|
11
|
-
export {
|
|
12
|
-
getDelegatorMcpToolDefinitions,
|
|
13
|
-
loadDelegatorSchemaBundle,
|
|
14
|
-
} from "./tool-definitions.mjs";
|