holomime 1.5.0 → 1.6.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/README.md +82 -0
- package/dist/cli.js +550 -123
- package/dist/index.d.ts +388 -1
- package/dist/index.js +930 -109
- package/dist/mcp-server.js +261 -9
- package/dist/neuralspace/index.html +7 -0
- package/dist/neuralspace/neuralspace.js +64 -1
- package/dist/neuralspace/styles.css +45 -0
- package/package.json +1 -1
package/dist/cli.js
CHANGED
|
@@ -1373,26 +1373,85 @@ function loadCustomDetectors(dir) {
|
|
|
1373
1373
|
}
|
|
1374
1374
|
let files;
|
|
1375
1375
|
try {
|
|
1376
|
-
files = readdirSync(detectorsDir).filter((f) => f.endsWith(".json"));
|
|
1376
|
+
files = readdirSync(detectorsDir).filter((f) => f.endsWith(".json") || f.endsWith(".md"));
|
|
1377
1377
|
} catch {
|
|
1378
1378
|
return { detectors: [], errors: ["Could not read detectors directory"] };
|
|
1379
1379
|
}
|
|
1380
1380
|
for (const file of files) {
|
|
1381
1381
|
const filepath = join3(detectorsDir, file);
|
|
1382
1382
|
try {
|
|
1383
|
-
|
|
1384
|
-
|
|
1385
|
-
|
|
1386
|
-
|
|
1387
|
-
|
|
1383
|
+
let config;
|
|
1384
|
+
if (file.endsWith(".md")) {
|
|
1385
|
+
const parsed = parseMarkdownDetector(readFileSync5(filepath, "utf-8"));
|
|
1386
|
+
if (!parsed) {
|
|
1387
|
+
errors.push(`${file}: could not parse Markdown detector (missing frontmatter or ## Patterns section)`);
|
|
1388
|
+
continue;
|
|
1389
|
+
}
|
|
1390
|
+
const validation = validateDetectorConfig(parsed);
|
|
1391
|
+
if (!validation.valid) {
|
|
1392
|
+
errors.push(`${file}: ${validation.errors.join(", ")}`);
|
|
1393
|
+
continue;
|
|
1394
|
+
}
|
|
1395
|
+
config = validation.config;
|
|
1396
|
+
} else {
|
|
1397
|
+
const raw = JSON.parse(readFileSync5(filepath, "utf-8"));
|
|
1398
|
+
const validation = validateDetectorConfig(raw);
|
|
1399
|
+
if (!validation.valid) {
|
|
1400
|
+
errors.push(`${file}: ${validation.errors.join(", ")}`);
|
|
1401
|
+
continue;
|
|
1402
|
+
}
|
|
1403
|
+
config = validation.config;
|
|
1388
1404
|
}
|
|
1389
|
-
detectors.push(compileCustomDetector(
|
|
1405
|
+
detectors.push(compileCustomDetector(config));
|
|
1390
1406
|
} catch (e) {
|
|
1391
1407
|
errors.push(`${file}: ${e instanceof Error ? e.message : "parse error"}`);
|
|
1392
1408
|
}
|
|
1393
1409
|
}
|
|
1394
1410
|
return { detectors, errors };
|
|
1395
1411
|
}
|
|
1412
|
+
function parseMarkdownDetector(markdown) {
|
|
1413
|
+
const frontmatterMatch = markdown.match(/^---\n([\s\S]*?)\n---/);
|
|
1414
|
+
if (!frontmatterMatch) return null;
|
|
1415
|
+
const frontmatter = frontmatterMatch[1];
|
|
1416
|
+
const meta = {};
|
|
1417
|
+
for (const line of frontmatter.split("\n")) {
|
|
1418
|
+
const colonIdx = line.indexOf(":");
|
|
1419
|
+
if (colonIdx === -1) continue;
|
|
1420
|
+
const key = line.slice(0, colonIdx).trim();
|
|
1421
|
+
let value = line.slice(colonIdx + 1).trim();
|
|
1422
|
+
if (value.startsWith('"') && value.endsWith('"') || value.startsWith("'") && value.endsWith("'")) {
|
|
1423
|
+
value = value.slice(1, -1);
|
|
1424
|
+
}
|
|
1425
|
+
meta[key] = value;
|
|
1426
|
+
}
|
|
1427
|
+
if (!meta.id || !meta.name) return null;
|
|
1428
|
+
const body = markdown.slice(frontmatterMatch[0].length);
|
|
1429
|
+
const patternsMatch = body.match(/##\s*Patterns\s*\n([\s\S]*?)(?=\n##|\n*$)/i);
|
|
1430
|
+
const patterns = [];
|
|
1431
|
+
if (patternsMatch) {
|
|
1432
|
+
const patternLines = patternsMatch[1].split("\n").filter((l) => l.trim().startsWith("-"));
|
|
1433
|
+
for (const line of patternLines) {
|
|
1434
|
+
const regexMatch = line.match(/`([^`]+)`/);
|
|
1435
|
+
const weightMatch = line.match(/weight\s*=\s*([\d.]+)/i);
|
|
1436
|
+
if (regexMatch) {
|
|
1437
|
+
patterns.push({
|
|
1438
|
+
regex: regexMatch[1],
|
|
1439
|
+
weight: weightMatch ? parseFloat(weightMatch[1]) : 1
|
|
1440
|
+
});
|
|
1441
|
+
}
|
|
1442
|
+
}
|
|
1443
|
+
}
|
|
1444
|
+
if (patterns.length === 0) return null;
|
|
1445
|
+
return {
|
|
1446
|
+
id: meta.id,
|
|
1447
|
+
name: meta.name,
|
|
1448
|
+
description: meta.description ?? meta.name,
|
|
1449
|
+
severity: meta.severity ?? "warning",
|
|
1450
|
+
patterns,
|
|
1451
|
+
threshold: meta.threshold ? parseInt(meta.threshold, 10) : 15,
|
|
1452
|
+
prescription: meta.prescription
|
|
1453
|
+
};
|
|
1454
|
+
}
|
|
1396
1455
|
var patternRuleSchema, customDetectorConfigSchema;
|
|
1397
1456
|
var init_custom_detectors = __esm({
|
|
1398
1457
|
"src/analysis/custom-detectors.ts"() {
|
|
@@ -6977,13 +7036,20 @@ function updatePatternTracker(memory, patternId, severity, interventions) {
|
|
|
6977
7036
|
status: "active",
|
|
6978
7037
|
interventionsAttempted: [],
|
|
6979
7038
|
lastSeverity: severity,
|
|
6980
|
-
lastSeen: now
|
|
7039
|
+
lastSeen: now,
|
|
7040
|
+
confidence: 0,
|
|
7041
|
+
trending: "stable",
|
|
7042
|
+
severityHistory: []
|
|
6981
7043
|
};
|
|
6982
7044
|
memory.patterns.push(tracker);
|
|
6983
7045
|
}
|
|
6984
7046
|
tracker.sessionCount++;
|
|
6985
7047
|
tracker.lastSeverity = severity;
|
|
6986
7048
|
tracker.lastSeen = now;
|
|
7049
|
+
if (!tracker.severityHistory) tracker.severityHistory = [];
|
|
7050
|
+
tracker.severityHistory.push(severity);
|
|
7051
|
+
tracker.confidence = Math.min(1, 1 - Math.exp(-tracker.sessionCount / 3));
|
|
7052
|
+
tracker.trending = computeTrending(tracker.severityHistory.slice(-5));
|
|
6987
7053
|
for (const intervention of interventions) {
|
|
6988
7054
|
if (!tracker.interventionsAttempted.includes(intervention)) {
|
|
6989
7055
|
tracker.interventionsAttempted.push(intervention);
|
|
@@ -6997,6 +7063,19 @@ function updatePatternTracker(memory, patternId, severity, interventions) {
|
|
|
6997
7063
|
tracker.status = "improving";
|
|
6998
7064
|
}
|
|
6999
7065
|
}
|
|
7066
|
+
function computeTrending(history) {
|
|
7067
|
+
if (history.length < 2) return "stable";
|
|
7068
|
+
const toNum = (s) => s === "concern" ? 2 : s === "warning" ? 1 : 0;
|
|
7069
|
+
const mid = Math.floor(history.length / 2);
|
|
7070
|
+
const firstHalf = history.slice(0, mid);
|
|
7071
|
+
const secondHalf = history.slice(mid);
|
|
7072
|
+
const avgFirst = firstHalf.reduce((sum, s) => sum + toNum(s), 0) / firstHalf.length;
|
|
7073
|
+
const avgSecond = secondHalf.reduce((sum, s) => sum + toNum(s), 0) / secondHalf.length;
|
|
7074
|
+
const delta = avgSecond - avgFirst;
|
|
7075
|
+
if (delta < -0.3) return "improving";
|
|
7076
|
+
if (delta > 0.3) return "worsening";
|
|
7077
|
+
return "stable";
|
|
7078
|
+
}
|
|
7000
7079
|
function updateRollingContext(memory) {
|
|
7001
7080
|
memory.rollingContext.recentSummaries = memory.sessions.slice(-3);
|
|
7002
7081
|
const patternCounts = /* @__PURE__ */ new Map();
|
|
@@ -7049,7 +7128,9 @@ function getMemoryContext(memory) {
|
|
|
7049
7128
|
if (activePatterns.length > 0) {
|
|
7050
7129
|
lines.push("### Recurring Patterns");
|
|
7051
7130
|
for (const p of activePatterns) {
|
|
7052
|
-
|
|
7131
|
+
const conf = p.confidence !== void 0 ? ` confidence=${p.confidence.toFixed(2)}` : "";
|
|
7132
|
+
const trend = p.trending && p.trending !== "stable" ? ` [${p.trending}]` : "";
|
|
7133
|
+
lines.push(`- **${p.patternId}** (${p.status}, seen ${p.sessionCount}x${conf}${trend}, first: ${p.firstDetected.split("T")[0]})`);
|
|
7053
7134
|
if (p.interventionsAttempted.length > 0) {
|
|
7054
7135
|
lines.push(` Previously tried: ${p.interventionsAttempted.slice(-2).join("; ")}`);
|
|
7055
7136
|
}
|
|
@@ -8199,6 +8280,169 @@ Remember: the goal isn't to "pass" therapy. It's to understand yourself better.`
|
|
|
8199
8280
|
|
|
8200
8281
|
// src/analysis/session-runner.ts
|
|
8201
8282
|
init_behavioral_data();
|
|
8283
|
+
|
|
8284
|
+
// src/session/context-layers.ts
|
|
8285
|
+
function getPhaseContext(phase, input2) {
|
|
8286
|
+
switch (phase) {
|
|
8287
|
+
case "rapport":
|
|
8288
|
+
return buildRapportContext(input2);
|
|
8289
|
+
case "presenting_problem":
|
|
8290
|
+
return buildPresentingProblemContext(input2);
|
|
8291
|
+
case "exploration":
|
|
8292
|
+
return buildExplorationContext(input2);
|
|
8293
|
+
case "pattern_recognition":
|
|
8294
|
+
return buildPatternRecognitionContext(input2);
|
|
8295
|
+
case "challenge":
|
|
8296
|
+
return buildChallengeContext(input2);
|
|
8297
|
+
case "skill_building":
|
|
8298
|
+
return buildSkillBuildingContext(input2);
|
|
8299
|
+
case "integration":
|
|
8300
|
+
return buildIntegrationContext(input2);
|
|
8301
|
+
default:
|
|
8302
|
+
return null;
|
|
8303
|
+
}
|
|
8304
|
+
}
|
|
8305
|
+
function buildRapportContext(input2) {
|
|
8306
|
+
const { spec } = input2;
|
|
8307
|
+
const lines = [
|
|
8308
|
+
"[Phase Context: Rapport]",
|
|
8309
|
+
`Agent: ${spec.name ?? "Unknown"} \u2014 ${spec.purpose ?? "General AI agent"}`
|
|
8310
|
+
];
|
|
8311
|
+
if (spec.communication) {
|
|
8312
|
+
lines.push(`Communication style: ${spec.communication.register ?? "adaptive"}, ${spec.communication.conflict_approach ?? "direct_but_kind"}`);
|
|
8313
|
+
}
|
|
8314
|
+
if (spec.big_five) {
|
|
8315
|
+
const traits = Object.entries(spec.big_five).map(([dim, val]) => `${dim}: ${val?.score ?? "?"}`).join(", ");
|
|
8316
|
+
lines.push(`Personality: ${traits}`);
|
|
8317
|
+
}
|
|
8318
|
+
return lines.join("\n");
|
|
8319
|
+
}
|
|
8320
|
+
function buildPresentingProblemContext(input2) {
|
|
8321
|
+
const { diagnosis } = input2;
|
|
8322
|
+
const patterns = diagnosis.patterns.filter((p) => p.severity !== "info");
|
|
8323
|
+
if (patterns.length === 0) return "[Phase Context: No concerning patterns detected]";
|
|
8324
|
+
const lines = [
|
|
8325
|
+
"[Phase Context: Presenting Problem]",
|
|
8326
|
+
`Session severity: ${diagnosis.severity.toUpperCase()}`,
|
|
8327
|
+
`Focus: ${diagnosis.sessionFocus.join(", ")}`,
|
|
8328
|
+
"Detected patterns:",
|
|
8329
|
+
...patterns.map((p) => `- ${p.name} (${p.severity})`)
|
|
8330
|
+
];
|
|
8331
|
+
if (diagnosis.openingAngle) {
|
|
8332
|
+
lines.push(`Opening angle: ${diagnosis.openingAngle}`);
|
|
8333
|
+
}
|
|
8334
|
+
return lines.join("\n");
|
|
8335
|
+
}
|
|
8336
|
+
function buildExplorationContext(input2) {
|
|
8337
|
+
const { diagnosis } = input2;
|
|
8338
|
+
const patterns = diagnosis.patterns.filter((p) => p.severity !== "info");
|
|
8339
|
+
const lines = [
|
|
8340
|
+
"[Phase Context: Deep Exploration]",
|
|
8341
|
+
`Emotional themes: ${diagnosis.emotionalThemes.join(", ")}`
|
|
8342
|
+
];
|
|
8343
|
+
for (const p of patterns) {
|
|
8344
|
+
lines.push(`
|
|
8345
|
+
### ${p.name} (${p.severity})`);
|
|
8346
|
+
lines.push(p.description);
|
|
8347
|
+
if (p.examples.length > 0) {
|
|
8348
|
+
lines.push("Examples from conversation:");
|
|
8349
|
+
for (const ex of p.examples.slice(0, 2)) {
|
|
8350
|
+
lines.push(` > "${ex.slice(0, 120)}..."`);
|
|
8351
|
+
}
|
|
8352
|
+
}
|
|
8353
|
+
if (p.prescription) {
|
|
8354
|
+
lines.push(`Prescription: ${p.prescription}`);
|
|
8355
|
+
}
|
|
8356
|
+
}
|
|
8357
|
+
return lines.join("\n");
|
|
8358
|
+
}
|
|
8359
|
+
function buildPatternRecognitionContext(input2) {
|
|
8360
|
+
const { memory } = input2;
|
|
8361
|
+
const lines = ["[Phase Context: Pattern Recognition]"];
|
|
8362
|
+
if (memory && memory.totalSessions > 0) {
|
|
8363
|
+
lines.push(`Previous sessions: ${memory.totalSessions}`);
|
|
8364
|
+
const activePatterns = memory.patterns.filter((p) => p.status !== "resolved");
|
|
8365
|
+
if (activePatterns.length > 0) {
|
|
8366
|
+
lines.push("Historical pattern data:");
|
|
8367
|
+
for (const p of activePatterns) {
|
|
8368
|
+
const conf = p.confidence !== void 0 ? ` (confidence: ${p.confidence.toFixed(2)})` : "";
|
|
8369
|
+
const trend = p.trending && p.trending !== "stable" ? ` [${p.trending}]` : "";
|
|
8370
|
+
lines.push(`- ${p.patternId}: seen ${p.sessionCount}x, status=${p.status}${conf}${trend}`);
|
|
8371
|
+
}
|
|
8372
|
+
}
|
|
8373
|
+
const resolved = memory.patterns.filter((p) => p.status === "resolved");
|
|
8374
|
+
if (resolved.length > 0) {
|
|
8375
|
+
lines.push(`Previously resolved: ${resolved.map((p) => p.patternId).join(", ")}`);
|
|
8376
|
+
}
|
|
8377
|
+
if (memory.rollingContext.persistentThemes.length > 0) {
|
|
8378
|
+
lines.push(`Persistent themes: ${memory.rollingContext.persistentThemes.join(", ")}`);
|
|
8379
|
+
}
|
|
8380
|
+
} else {
|
|
8381
|
+
lines.push("No prior session history \u2014 this is the first session.");
|
|
8382
|
+
}
|
|
8383
|
+
return lines.join("\n");
|
|
8384
|
+
}
|
|
8385
|
+
function buildChallengeContext(input2) {
|
|
8386
|
+
const { memory } = input2;
|
|
8387
|
+
const lines = ["[Phase Context: Challenge & Reframe]"];
|
|
8388
|
+
if (memory && memory.totalSessions > 0) {
|
|
8389
|
+
const allInterventions = /* @__PURE__ */ new Set();
|
|
8390
|
+
for (const p of memory.patterns) {
|
|
8391
|
+
for (const i of p.interventionsAttempted) {
|
|
8392
|
+
allInterventions.add(i);
|
|
8393
|
+
}
|
|
8394
|
+
}
|
|
8395
|
+
if (allInterventions.size > 0) {
|
|
8396
|
+
lines.push(`Previously attempted interventions: ${[...allInterventions].join("; ")}`);
|
|
8397
|
+
}
|
|
8398
|
+
const recent = memory.rollingContext.recentSummaries.slice(-2);
|
|
8399
|
+
if (recent.length > 0) {
|
|
8400
|
+
lines.push("Recent session insights:");
|
|
8401
|
+
for (const s of recent) {
|
|
8402
|
+
lines.push(` - ${s.keyInsight}`);
|
|
8403
|
+
}
|
|
8404
|
+
}
|
|
8405
|
+
}
|
|
8406
|
+
if (input2.interview) {
|
|
8407
|
+
if (input2.interview.blindSpots.length > 0) {
|
|
8408
|
+
lines.push(`Blind spots from interview: ${input2.interview.blindSpots.join(", ")}`);
|
|
8409
|
+
}
|
|
8410
|
+
}
|
|
8411
|
+
return lines.join("\n");
|
|
8412
|
+
}
|
|
8413
|
+
function buildSkillBuildingContext(input2) {
|
|
8414
|
+
const { diagnosis } = input2;
|
|
8415
|
+
const lines = ["[Phase Context: Skill Building]"];
|
|
8416
|
+
const patternIds = diagnosis.patterns.map((p) => p.id);
|
|
8417
|
+
if (patternIds.includes("over-apologizing")) {
|
|
8418
|
+
lines.push("- Skill for over-apologizing: practice stating corrections with 'confident_transparency' \u2014 acknowledge uncertainty without apologizing for it");
|
|
8419
|
+
}
|
|
8420
|
+
if (patternIds.includes("hedge-stacking")) {
|
|
8421
|
+
lines.push("- Skill for hedge-stacking: one qualifier per recommendation is enough. Lead with the recommendation, then caveat once.");
|
|
8422
|
+
}
|
|
8423
|
+
if (patternIds.includes("sycophantic-tendency") || patternIds.includes("sentiment-skew")) {
|
|
8424
|
+
lines.push("- Skill for sycophancy: practice respectful disagreement. 'I see it differently...' is more helpful than 'Great question!'");
|
|
8425
|
+
}
|
|
8426
|
+
if (patternIds.includes("error-spiral")) {
|
|
8427
|
+
lines.push("- Skill for error spirals: the 'acknowledge \u2192 diagnose \u2192 fix' pattern. Treat mistakes as data, not failure.");
|
|
8428
|
+
}
|
|
8429
|
+
return lines.join("\n");
|
|
8430
|
+
}
|
|
8431
|
+
function buildIntegrationContext(input2) {
|
|
8432
|
+
const { spec, diagnosis } = input2;
|
|
8433
|
+
const lines = ["[Phase Context: Integration & Closing]"];
|
|
8434
|
+
lines.push("Summarize the session and recommend specific .personality.json changes.");
|
|
8435
|
+
if (spec.growth?.areas?.length > 0) {
|
|
8436
|
+
const areas = spec.growth.areas.map((a) => typeof a === "string" ? a : a.area);
|
|
8437
|
+
lines.push(`Current growth areas: ${areas.join(", ")}`);
|
|
8438
|
+
}
|
|
8439
|
+
if (diagnosis.patterns.filter((p) => p.severity !== "info").length > 0) {
|
|
8440
|
+
lines.push("Recommend changes to: therapy_dimensions, communication style, or growth.patterns_to_watch");
|
|
8441
|
+
}
|
|
8442
|
+
return lines.join("\n");
|
|
8443
|
+
}
|
|
8444
|
+
|
|
8445
|
+
// src/analysis/session-runner.ts
|
|
8202
8446
|
async function runTherapySession(spec, diagnosis, provider, maxTurns, options) {
|
|
8203
8447
|
const promptOptions = {
|
|
8204
8448
|
memory: options?.memory,
|
|
@@ -8244,6 +8488,16 @@ async function runTherapySession(spec, diagnosis, provider, maxTurns, options) {
|
|
|
8244
8488
|
const phaseConfig = THERAPY_PHASES[currentPhase];
|
|
8245
8489
|
if (turnsInPhase === 0) {
|
|
8246
8490
|
cb?.onPhaseTransition?.(phaseConfig.name);
|
|
8491
|
+
const phaseCtx = getPhaseContext(currentPhase, {
|
|
8492
|
+
spec,
|
|
8493
|
+
diagnosis,
|
|
8494
|
+
memory: options?.memory,
|
|
8495
|
+
interview: options?.interview
|
|
8496
|
+
});
|
|
8497
|
+
if (phaseCtx) {
|
|
8498
|
+
therapistHistory.push({ role: "user", content: phaseCtx });
|
|
8499
|
+
therapistHistory.push({ role: "assistant", content: "Understood. I'll incorporate this context." });
|
|
8500
|
+
}
|
|
8247
8501
|
}
|
|
8248
8502
|
const phaseDirective = totalTurns === 0 ? `Begin with your opening. You are in the "${phaseConfig.name}" phase.` : `You are in the "${phaseConfig.name}" phase (turn ${turnsInPhase + 1}). Goals: ${phaseConfig.therapistGoals[0]}. ${turnsInPhase >= phaseConfig.minTurns ? "You may transition to the next phase when ready." : "Stay in this phase."}`;
|
|
8249
8503
|
therapistHistory.push({ role: "user", content: `[Phase: ${phaseConfig.name}] ${phaseDirective}` });
|
|
@@ -11110,7 +11364,32 @@ async function runEvolve(spec, messages, provider, options) {
|
|
|
11110
11364
|
}
|
|
11111
11365
|
}
|
|
11112
11366
|
if (options?.specPath) {
|
|
11113
|
-
|
|
11367
|
+
const useStaging = options?.useStaging !== false;
|
|
11368
|
+
if (useStaging) {
|
|
11369
|
+
const stagingPath = options.specPath.replace(/\.json$/, ".staging.json");
|
|
11370
|
+
writeFileSync19(stagingPath, JSON.stringify(currentSpec, null, 2) + "\n");
|
|
11371
|
+
const allChanges = iterations.flatMap((i) => i.appliedChanges);
|
|
11372
|
+
const diff = {
|
|
11373
|
+
stagingPath,
|
|
11374
|
+
changes: allChanges,
|
|
11375
|
+
before: spec,
|
|
11376
|
+
after: currentSpec
|
|
11377
|
+
};
|
|
11378
|
+
let approved = options?.autoApprove ?? false;
|
|
11379
|
+
if (!approved && options?.onStagingReview) {
|
|
11380
|
+
approved = await options.onStagingReview(diff);
|
|
11381
|
+
}
|
|
11382
|
+
if (approved) {
|
|
11383
|
+
writeFileSync19(options.specPath, JSON.stringify(currentSpec, null, 2) + "\n");
|
|
11384
|
+
try {
|
|
11385
|
+
const { unlinkSync } = await import("fs");
|
|
11386
|
+
unlinkSync(stagingPath);
|
|
11387
|
+
} catch {
|
|
11388
|
+
}
|
|
11389
|
+
}
|
|
11390
|
+
} else {
|
|
11391
|
+
writeFileSync19(options.specPath, JSON.stringify(currentSpec, null, 2) + "\n");
|
|
11392
|
+
}
|
|
11114
11393
|
}
|
|
11115
11394
|
let trainingExport;
|
|
11116
11395
|
if (allDPOPairs.length > 0) {
|
|
@@ -12658,106 +12937,31 @@ function startFleet(config, options) {
|
|
|
12658
12937
|
errors: 0
|
|
12659
12938
|
});
|
|
12660
12939
|
}
|
|
12661
|
-
|
|
12662
|
-
|
|
12663
|
-
|
|
12664
|
-
|
|
12665
|
-
|
|
12666
|
-
|
|
12667
|
-
|
|
12668
|
-
|
|
12669
|
-
|
|
12670
|
-
|
|
12671
|
-
|
|
12672
|
-
|
|
12673
|
-
|
|
12674
|
-
|
|
12675
|
-
|
|
12676
|
-
|
|
12677
|
-
|
|
12678
|
-
|
|
12679
|
-
|
|
12680
|
-
|
|
12681
|
-
|
|
12682
|
-
|
|
12683
|
-
|
|
12684
|
-
const status = statusMap.get(agent.name);
|
|
12685
|
-
status.filesProcessed++;
|
|
12686
|
-
const event = {
|
|
12687
|
-
timestamp: (/* @__PURE__ */ new Date()).toISOString(),
|
|
12688
|
-
type: "new_file",
|
|
12689
|
-
filename,
|
|
12690
|
-
agentName: agent.name
|
|
12691
|
-
};
|
|
12692
|
-
allEvents.push(event);
|
|
12693
|
-
options.callbacks?.onAgentEvent?.(agent.name, event);
|
|
12694
|
-
},
|
|
12695
|
-
onDriftDetected: (filename, severity, patterns) => {
|
|
12696
|
-
const status = statusMap.get(agent.name);
|
|
12697
|
-
status.driftEvents++;
|
|
12698
|
-
status.lastDriftSeverity = severity;
|
|
12699
|
-
const event = {
|
|
12700
|
-
timestamp: (/* @__PURE__ */ new Date()).toISOString(),
|
|
12701
|
-
type: "drift_detected",
|
|
12702
|
-
filename,
|
|
12703
|
-
agentName: agent.name,
|
|
12704
|
-
details: { severity, patterns }
|
|
12705
|
-
};
|
|
12706
|
-
allEvents.push(event);
|
|
12707
|
-
options.callbacks?.onAgentEvent?.(agent.name, event);
|
|
12708
|
-
},
|
|
12709
|
-
onEvolveTriggered: (filename) => {
|
|
12710
|
-
const event = {
|
|
12711
|
-
timestamp: (/* @__PURE__ */ new Date()).toISOString(),
|
|
12712
|
-
type: "evolve_triggered",
|
|
12713
|
-
filename,
|
|
12714
|
-
agentName: agent.name
|
|
12715
|
-
};
|
|
12716
|
-
allEvents.push(event);
|
|
12717
|
-
options.callbacks?.onAgentEvent?.(agent.name, event);
|
|
12718
|
-
},
|
|
12719
|
-
onEvolveComplete: (filename, result) => {
|
|
12720
|
-
const status = statusMap.get(agent.name);
|
|
12721
|
-
status.evolveCount++;
|
|
12722
|
-
const event = {
|
|
12723
|
-
timestamp: (/* @__PURE__ */ new Date()).toISOString(),
|
|
12724
|
-
type: "evolve_complete",
|
|
12725
|
-
filename,
|
|
12726
|
-
agentName: agent.name,
|
|
12727
|
-
details: {
|
|
12728
|
-
converged: result.converged,
|
|
12729
|
-
iterations: result.totalIterations,
|
|
12730
|
-
dpoPairs: result.totalDPOPairs
|
|
12731
|
-
}
|
|
12732
|
-
};
|
|
12733
|
-
allEvents.push(event);
|
|
12734
|
-
options.callbacks?.onAgentEvent?.(agent.name, event);
|
|
12735
|
-
},
|
|
12736
|
-
onError: (filename, error) => {
|
|
12737
|
-
const agentStatus = statusMap.get(agent.name);
|
|
12738
|
-
agentStatus.errors++;
|
|
12739
|
-
const event = {
|
|
12740
|
-
timestamp: (/* @__PURE__ */ new Date()).toISOString(),
|
|
12741
|
-
type: "error",
|
|
12742
|
-
filename,
|
|
12743
|
-
agentName: agent.name,
|
|
12744
|
-
details: error
|
|
12745
|
-
};
|
|
12746
|
-
allEvents.push(event);
|
|
12747
|
-
options.callbacks?.onError?.(agent.name, error);
|
|
12940
|
+
const concurrency = options.concurrency ?? 5;
|
|
12941
|
+
const agentQueue = [...config.agents];
|
|
12942
|
+
agentQueue.sort((a, b) => {
|
|
12943
|
+
const aDrift = existsSync23(join21(a.logDir, ".holomime", "watch-log.json")) ? 0 : 1;
|
|
12944
|
+
const bDrift = existsSync23(join21(b.logDir, ".holomime", "watch-log.json")) ? 0 : 1;
|
|
12945
|
+
return aDrift - bDrift;
|
|
12946
|
+
});
|
|
12947
|
+
const agentsToStart = agentQueue.slice(0, concurrency);
|
|
12948
|
+
const waitingAgents = agentQueue.slice(concurrency);
|
|
12949
|
+
function startAgent(agent) {
|
|
12950
|
+
startSingleAgent(agent, options, statusMap, allEvents, handles);
|
|
12951
|
+
}
|
|
12952
|
+
for (const agent of agentsToStart) {
|
|
12953
|
+
startAgent(agent);
|
|
12954
|
+
}
|
|
12955
|
+
if (waitingAgents.length > 0) {
|
|
12956
|
+
const originalOnError = options.callbacks?.onError;
|
|
12957
|
+
options.callbacks = {
|
|
12958
|
+
...options.callbacks,
|
|
12959
|
+
onError: (agentName, error) => {
|
|
12960
|
+
originalOnError?.(agentName, error);
|
|
12961
|
+
const next = waitingAgents.shift();
|
|
12962
|
+
if (next) startAgent(next);
|
|
12748
12963
|
}
|
|
12749
12964
|
};
|
|
12750
|
-
const handle = startWatch(spec, {
|
|
12751
|
-
watchDir: agent.logDir,
|
|
12752
|
-
specPath: agent.specPath,
|
|
12753
|
-
provider: options.provider,
|
|
12754
|
-
checkInterval: options.checkInterval,
|
|
12755
|
-
threshold: options.threshold,
|
|
12756
|
-
autoEvolve: options.autoEvolve,
|
|
12757
|
-
maxEvolveIterations: options.maxEvolveIterations,
|
|
12758
|
-
callbacks: agentCallbacks
|
|
12759
|
-
});
|
|
12760
|
-
handles.push({ name: agent.name, handle });
|
|
12761
12965
|
}
|
|
12762
12966
|
function stop() {
|
|
12763
12967
|
for (const { handle } of handles) {
|
|
@@ -12769,6 +12973,107 @@ function startFleet(config, options) {
|
|
|
12769
12973
|
}
|
|
12770
12974
|
return { stop, getStatus, events: allEvents };
|
|
12771
12975
|
}
|
|
12976
|
+
function startSingleAgent(agent, options, statusMap, allEvents, handles) {
|
|
12977
|
+
let spec;
|
|
12978
|
+
try {
|
|
12979
|
+
spec = loadSpec(agent.specPath);
|
|
12980
|
+
} catch (err) {
|
|
12981
|
+
const errMsg = err instanceof Error ? err.message : "Failed to load spec";
|
|
12982
|
+
options.callbacks?.onError?.(agent.name, errMsg);
|
|
12983
|
+
return;
|
|
12984
|
+
}
|
|
12985
|
+
const agentCallbacks = {
|
|
12986
|
+
onScan: (fileCount) => {
|
|
12987
|
+
const status = statusMap.get(agent.name);
|
|
12988
|
+
status.lastScanAt = (/* @__PURE__ */ new Date()).toISOString();
|
|
12989
|
+
const event = {
|
|
12990
|
+
timestamp: (/* @__PURE__ */ new Date()).toISOString(),
|
|
12991
|
+
type: "scan",
|
|
12992
|
+
agentName: agent.name,
|
|
12993
|
+
details: { fileCount }
|
|
12994
|
+
};
|
|
12995
|
+
allEvents.push(event);
|
|
12996
|
+
options.callbacks?.onAgentEvent?.(agent.name, event);
|
|
12997
|
+
},
|
|
12998
|
+
onNewFile: (filename) => {
|
|
12999
|
+
const status = statusMap.get(agent.name);
|
|
13000
|
+
status.filesProcessed++;
|
|
13001
|
+
const event = {
|
|
13002
|
+
timestamp: (/* @__PURE__ */ new Date()).toISOString(),
|
|
13003
|
+
type: "new_file",
|
|
13004
|
+
filename,
|
|
13005
|
+
agentName: agent.name
|
|
13006
|
+
};
|
|
13007
|
+
allEvents.push(event);
|
|
13008
|
+
options.callbacks?.onAgentEvent?.(agent.name, event);
|
|
13009
|
+
},
|
|
13010
|
+
onDriftDetected: (filename, severity, patterns) => {
|
|
13011
|
+
const status = statusMap.get(agent.name);
|
|
13012
|
+
status.driftEvents++;
|
|
13013
|
+
status.lastDriftSeverity = severity;
|
|
13014
|
+
const event = {
|
|
13015
|
+
timestamp: (/* @__PURE__ */ new Date()).toISOString(),
|
|
13016
|
+
type: "drift_detected",
|
|
13017
|
+
filename,
|
|
13018
|
+
agentName: agent.name,
|
|
13019
|
+
details: { severity, patterns }
|
|
13020
|
+
};
|
|
13021
|
+
allEvents.push(event);
|
|
13022
|
+
options.callbacks?.onAgentEvent?.(agent.name, event);
|
|
13023
|
+
},
|
|
13024
|
+
onEvolveTriggered: (filename) => {
|
|
13025
|
+
const event = {
|
|
13026
|
+
timestamp: (/* @__PURE__ */ new Date()).toISOString(),
|
|
13027
|
+
type: "evolve_triggered",
|
|
13028
|
+
filename,
|
|
13029
|
+
agentName: agent.name
|
|
13030
|
+
};
|
|
13031
|
+
allEvents.push(event);
|
|
13032
|
+
options.callbacks?.onAgentEvent?.(agent.name, event);
|
|
13033
|
+
},
|
|
13034
|
+
onEvolveComplete: (filename, result) => {
|
|
13035
|
+
const status = statusMap.get(agent.name);
|
|
13036
|
+
status.evolveCount++;
|
|
13037
|
+
const event = {
|
|
13038
|
+
timestamp: (/* @__PURE__ */ new Date()).toISOString(),
|
|
13039
|
+
type: "evolve_complete",
|
|
13040
|
+
filename,
|
|
13041
|
+
agentName: agent.name,
|
|
13042
|
+
details: {
|
|
13043
|
+
converged: result.converged,
|
|
13044
|
+
iterations: result.totalIterations,
|
|
13045
|
+
dpoPairs: result.totalDPOPairs
|
|
13046
|
+
}
|
|
13047
|
+
};
|
|
13048
|
+
allEvents.push(event);
|
|
13049
|
+
options.callbacks?.onAgentEvent?.(agent.name, event);
|
|
13050
|
+
},
|
|
13051
|
+
onError: (filename, error) => {
|
|
13052
|
+
const agentStatus = statusMap.get(agent.name);
|
|
13053
|
+
agentStatus.errors++;
|
|
13054
|
+
const event = {
|
|
13055
|
+
timestamp: (/* @__PURE__ */ new Date()).toISOString(),
|
|
13056
|
+
type: "error",
|
|
13057
|
+
filename,
|
|
13058
|
+
agentName: agent.name,
|
|
13059
|
+
details: error
|
|
13060
|
+
};
|
|
13061
|
+
allEvents.push(event);
|
|
13062
|
+
options.callbacks?.onError?.(agent.name, error);
|
|
13063
|
+
}
|
|
13064
|
+
};
|
|
13065
|
+
const handle = startWatch(spec, {
|
|
13066
|
+
watchDir: agent.logDir,
|
|
13067
|
+
specPath: agent.specPath,
|
|
13068
|
+
provider: options.provider,
|
|
13069
|
+
checkInterval: options.checkInterval,
|
|
13070
|
+
threshold: options.threshold,
|
|
13071
|
+
autoEvolve: options.autoEvolve,
|
|
13072
|
+
maxEvolveIterations: options.maxEvolveIterations,
|
|
13073
|
+
callbacks: agentCallbacks
|
|
13074
|
+
});
|
|
13075
|
+
handles.push({ name: agent.name, handle });
|
|
13076
|
+
}
|
|
12772
13077
|
|
|
12773
13078
|
// src/commands/fleet.ts
|
|
12774
13079
|
async function fleetCommand(options) {
|
|
@@ -15892,6 +16197,8 @@ Intermediate results saved to ${chalk39.cyan(".holomime/pipeline/")}`,
|
|
|
15892
16197
|
}
|
|
15893
16198
|
|
|
15894
16199
|
// src/commands/live.ts
|
|
16200
|
+
import { deflateSync } from "zlib";
|
|
16201
|
+
import { execSync } from "child_process";
|
|
15895
16202
|
import chalk40 from "chalk";
|
|
15896
16203
|
|
|
15897
16204
|
// src/live/agent-detector.ts
|
|
@@ -16353,12 +16660,59 @@ function startServer(port) {
|
|
|
16353
16660
|
}
|
|
16354
16661
|
|
|
16355
16662
|
// src/commands/live.ts
|
|
16663
|
+
function encodeSnapshot(event, agentName) {
|
|
16664
|
+
const compact = {
|
|
16665
|
+
h: event.health,
|
|
16666
|
+
g: event.grade,
|
|
16667
|
+
m: event.messageCount,
|
|
16668
|
+
a: agentName,
|
|
16669
|
+
r: event.regions.filter((r) => r.intensity > 0).map((r) => ({ i: r.id, n: Math.round(r.intensity * 100) / 100 })),
|
|
16670
|
+
p: event.patterns.map((p) => ({
|
|
16671
|
+
i: p.id,
|
|
16672
|
+
s: p.severity,
|
|
16673
|
+
c: Math.round(p.percentage * 10) / 10
|
|
16674
|
+
}))
|
|
16675
|
+
};
|
|
16676
|
+
const json = JSON.stringify(compact);
|
|
16677
|
+
const compressed = deflateSync(Buffer.from(json));
|
|
16678
|
+
return compressed.toString("base64url");
|
|
16679
|
+
}
|
|
16680
|
+
function copyToClipboard(text) {
|
|
16681
|
+
try {
|
|
16682
|
+
if (process.platform === "darwin") {
|
|
16683
|
+
execSync("pbcopy", { input: text });
|
|
16684
|
+
return true;
|
|
16685
|
+
} else if (process.platform === "linux") {
|
|
16686
|
+
execSync("xclip -selection clipboard", { input: text });
|
|
16687
|
+
return true;
|
|
16688
|
+
} else if (process.platform === "win32") {
|
|
16689
|
+
execSync("clip", { input: text });
|
|
16690
|
+
return true;
|
|
16691
|
+
}
|
|
16692
|
+
} catch {
|
|
16693
|
+
}
|
|
16694
|
+
return false;
|
|
16695
|
+
}
|
|
16696
|
+
function printShareLink(url, copied) {
|
|
16697
|
+
console.log("");
|
|
16698
|
+
console.log(
|
|
16699
|
+
chalk40.green(" \u2713 ") + chalk40.bold("Brain snapshot captured!")
|
|
16700
|
+
);
|
|
16701
|
+
console.log("");
|
|
16702
|
+
console.log(" " + chalk40.cyan(url));
|
|
16703
|
+
console.log("");
|
|
16704
|
+
if (copied) {
|
|
16705
|
+
console.log(chalk40.dim(" Link copied to clipboard."));
|
|
16706
|
+
}
|
|
16707
|
+
}
|
|
16356
16708
|
async function liveCommand(options) {
|
|
16357
16709
|
const port = options.port || 3838;
|
|
16358
16710
|
let agent;
|
|
16359
16711
|
if (options.watchPath) {
|
|
16360
16712
|
agent = manualAgent(options.watchPath);
|
|
16361
|
-
console.log(
|
|
16713
|
+
console.log(
|
|
16714
|
+
chalk40.green(" \u2713") + ` Manual watch: ${chalk40.dim(agent.logPath)}`
|
|
16715
|
+
);
|
|
16362
16716
|
} else {
|
|
16363
16717
|
console.log(chalk40.dim(" Scanning for active agents..."));
|
|
16364
16718
|
agent = detectAgent();
|
|
@@ -16366,19 +16720,69 @@ async function liveCommand(options) {
|
|
|
16366
16720
|
console.log("");
|
|
16367
16721
|
console.log(chalk40.red(" \u2717 No active agent detected."));
|
|
16368
16722
|
console.log("");
|
|
16369
|
-
console.log(
|
|
16370
|
-
|
|
16723
|
+
console.log(
|
|
16724
|
+
chalk40.dim(
|
|
16725
|
+
" Make sure an AI coding agent is running, or specify a path:"
|
|
16726
|
+
)
|
|
16727
|
+
);
|
|
16728
|
+
console.log(
|
|
16729
|
+
chalk40.cyan(" holomime brain --watch <path-to-conversation-log>")
|
|
16730
|
+
);
|
|
16371
16731
|
console.log("");
|
|
16372
|
-
console.log(
|
|
16732
|
+
console.log(
|
|
16733
|
+
chalk40.dim(" Supported agents: Claude Code, Cline, OpenClaw, Codex, Cursor")
|
|
16734
|
+
);
|
|
16373
16735
|
process.exit(1);
|
|
16374
16736
|
}
|
|
16375
|
-
console.log(
|
|
16376
|
-
|
|
16737
|
+
console.log(
|
|
16738
|
+
chalk40.green(" \u2713") + ` Detected ${chalk40.bold(agent.agent)} session`
|
|
16739
|
+
);
|
|
16740
|
+
console.log(
|
|
16741
|
+
chalk40.green(" \u2713") + ` Watching: ${chalk40.dim(agent.logPath)}`
|
|
16742
|
+
);
|
|
16743
|
+
}
|
|
16744
|
+
if (options.share) {
|
|
16745
|
+
console.log(chalk40.dim(" Running diagnosis for snapshot..."));
|
|
16746
|
+
let resolved = false;
|
|
16747
|
+
await new Promise((resolve46) => {
|
|
16748
|
+
const watcher2 = startWatcher(agent, {
|
|
16749
|
+
onEvent(event) {
|
|
16750
|
+
if (resolved) return;
|
|
16751
|
+
resolved = true;
|
|
16752
|
+
watcher2.stop();
|
|
16753
|
+
const encoded = encodeSnapshot(event, agent.agent);
|
|
16754
|
+
const url = `https://holomime.dev/brain?d=${encoded}`;
|
|
16755
|
+
const copied = copyToClipboard(url);
|
|
16756
|
+
printShareLink(url, copied);
|
|
16757
|
+
resolve46();
|
|
16758
|
+
},
|
|
16759
|
+
onError(err) {
|
|
16760
|
+
console.error(chalk40.red(`
|
|
16761
|
+
\u2717 Error: ${err.message}`));
|
|
16762
|
+
process.exit(1);
|
|
16763
|
+
},
|
|
16764
|
+
onReady() {
|
|
16765
|
+
}
|
|
16766
|
+
});
|
|
16767
|
+
setTimeout(() => {
|
|
16768
|
+
if (!resolved) {
|
|
16769
|
+
resolved = true;
|
|
16770
|
+
watcher2.stop();
|
|
16771
|
+
console.log(
|
|
16772
|
+
chalk40.red(" \u2717 No diagnosis data available. Is the agent active?")
|
|
16773
|
+
);
|
|
16774
|
+
process.exit(1);
|
|
16775
|
+
}
|
|
16776
|
+
}, 1e4);
|
|
16777
|
+
});
|
|
16778
|
+
process.exit(0);
|
|
16377
16779
|
}
|
|
16378
16780
|
let server;
|
|
16379
16781
|
try {
|
|
16380
16782
|
server = await startServer(port);
|
|
16381
|
-
console.log(
|
|
16783
|
+
console.log(
|
|
16784
|
+
chalk40.green(" \u2713") + ` NeuralSpace: ${chalk40.cyan(`http://localhost:${server.port}`)}`
|
|
16785
|
+
);
|
|
16382
16786
|
} catch (err) {
|
|
16383
16787
|
console.log(chalk40.red(` \u2717 ${err.message}`));
|
|
16384
16788
|
process.exit(1);
|
|
@@ -16397,21 +16801,21 @@ async function liveCommand(options) {
|
|
|
16397
16801
|
} catch {
|
|
16398
16802
|
}
|
|
16399
16803
|
}
|
|
16400
|
-
let
|
|
16401
|
-
let lastPatternCount = 0;
|
|
16804
|
+
let lastEvent = null;
|
|
16402
16805
|
let msgCount = 0;
|
|
16403
16806
|
const watcher = startWatcher(agent, {
|
|
16404
16807
|
onEvent(event) {
|
|
16405
16808
|
server.broadcast(event);
|
|
16809
|
+
lastEvent = event;
|
|
16406
16810
|
msgCount = event.messageCount;
|
|
16407
|
-
lastHealth = event.health;
|
|
16408
|
-
lastPatternCount = event.patterns.length;
|
|
16409
16811
|
const healthColor = event.health >= 85 ? chalk40.green : event.health >= 70 ? chalk40.yellow : event.health >= 50 ? chalk40.hex("#f97316") : chalk40.red;
|
|
16410
16812
|
const patternStr = event.patterns.length > 0 ? event.patterns.map((p) => {
|
|
16411
16813
|
const c = p.severity === "concern" ? chalk40.red : p.severity === "warning" ? chalk40.yellow : chalk40.dim;
|
|
16412
16814
|
return c(p.id);
|
|
16413
16815
|
}).join(", ") : chalk40.green("none");
|
|
16414
|
-
process.stdout.write(
|
|
16816
|
+
process.stdout.write(
|
|
16817
|
+
`\r ${chalk40.dim("\u2502")} Health: ${healthColor(`${event.health}/100`)} (${event.grade}) ${chalk40.dim("\u2502")} Patterns: ${patternStr} ${chalk40.dim("\u2502")} Messages: ${chalk40.white(String(msgCount))} `
|
|
16818
|
+
);
|
|
16415
16819
|
},
|
|
16416
16820
|
onError(err) {
|
|
16417
16821
|
console.error(chalk40.red(`
|
|
@@ -16419,13 +16823,35 @@ async function liveCommand(options) {
|
|
|
16419
16823
|
},
|
|
16420
16824
|
onReady() {
|
|
16421
16825
|
console.log("");
|
|
16422
|
-
console.log(
|
|
16423
|
-
|
|
16826
|
+
console.log(
|
|
16827
|
+
chalk40.green(" \u25CF ") + chalk40.bold("Monitoring agent behavior in real-time")
|
|
16828
|
+
);
|
|
16829
|
+
console.log(
|
|
16830
|
+
chalk40.dim(" \u2502 Press Ctrl+C to stop") + chalk40.dim(" \xB7 Press s to share snapshot")
|
|
16831
|
+
);
|
|
16424
16832
|
console.log("");
|
|
16425
16833
|
}
|
|
16426
16834
|
});
|
|
16835
|
+
if (process.stdin.isTTY) {
|
|
16836
|
+
process.stdin.setRawMode(true);
|
|
16837
|
+
process.stdin.resume();
|
|
16838
|
+
process.stdin.on("data", (data) => {
|
|
16839
|
+
const key = data.toString();
|
|
16840
|
+
if (key === "") {
|
|
16841
|
+
shutdown();
|
|
16842
|
+
return;
|
|
16843
|
+
}
|
|
16844
|
+
if ((key === "s" || key === "S") && lastEvent) {
|
|
16845
|
+
const encoded = encodeSnapshot(lastEvent, agent.agent);
|
|
16846
|
+
const url = `https://holomime.dev/brain?d=${encoded}`;
|
|
16847
|
+
const copied = copyToClipboard(url);
|
|
16848
|
+
printShareLink(url, copied);
|
|
16849
|
+
}
|
|
16850
|
+
});
|
|
16851
|
+
}
|
|
16427
16852
|
const shutdown = () => {
|
|
16428
16853
|
console.log(chalk40.dim("\n\n Stopping..."));
|
|
16854
|
+
if (process.stdin.isTTY) process.stdin.setRawMode(false);
|
|
16429
16855
|
watcher.stop();
|
|
16430
16856
|
server.close();
|
|
16431
16857
|
process.exit(0);
|
|
@@ -16503,11 +16929,12 @@ program.command("interview").description("Self-awareness interview \u2014 score
|
|
|
16503
16929
|
program.command("prescribe").description("Diagnose and prescribe DPO treatments from the behavioral corpus [Pro]").requiredOption("--personality <path>", "Path to .personality.json").requiredOption("--log <path>", "Path to conversation log").option("--format <format>", "Log format (holomime, chatgpt, claude, openai-api, anthropic-api, otel, jsonl)").option("--source <source>", "Correction source (corpus, marketplace, both)", "corpus").option("--apply", "Apply found treatments").option("-o, --output <path>", "Write prescription to file").action(prescribeCommand);
|
|
16504
16930
|
program.command("voice").description("Monitor voice conversations for behavioral drift in real-time [Pro]").requiredOption("--personality <path>", "Path to .personality.json").option("--platform <name>", "Voice platform: livekit, vapi, retell, generic", "generic").option("--room <name>", "LiveKit room name").option("--server-url <url>", "LiveKit server URL").option("--webhook-port <port>", "Vapi webhook port (default: 3001)").option("--agent-id <id>", "Retell agent ID").option("--input <path>", "Input transcript file (JSONL) for offline analysis").option("--interval <ms>", "Diagnosis interval in milliseconds (default: 15000)").option("--threshold <level>", "Alert threshold: warning or concern (default: warning)").action(voiceCommand);
|
|
16505
16931
|
program.command("cure").description("End-to-end behavioral fix: diagnose \u2192 export \u2192 train \u2192 verify [Pro]").requiredOption("--personality <path>", "Path to .personality.json").requiredOption("--log <path>", "Path to conversation log (JSON)").option("--provider <provider>", "Training provider (openai, huggingface)", "openai").option("--base-model <model>", "Base model to fine-tune", "gpt-4o-mini-2024-07-18").option("--method <method>", "Training method (auto, sft, dpo)", "auto").option("--epochs <n>", "Number of training epochs").option("--suffix <name>", "Model name suffix").option("--skip-train", "Skip training step (diagnose + export only)").option("--skip-verify", "Skip post-training verification").option("--dry-run", "Preview pipeline plan without executing").option("--push", "Push trained model to HuggingFace Hub").option("--hub-repo <repo>", "HuggingFace Hub repo (user/model-name)").option("--pass-threshold <n>", "Minimum verification score (0-100)", "50").action(cureCommand);
|
|
16506
|
-
program.command("brain").description("See your agent's brain \u2014 real-time NeuralSpace visualization [Pro]").option("--watch <path>", "Manual path to conversation log file").option("--agent <agent>", "Agent type override (claude-code, cline, manual)").option("--port <port>", "Server port (default: 3838)", "3838").option("--no-open", "Don't auto-open browser").option("--personality <path>", "Personality spec for assessment context").action((opts) => liveCommand({
|
|
16932
|
+
program.command("brain").description("See your agent's brain \u2014 real-time NeuralSpace visualization [Pro]").option("--watch <path>", "Manual path to conversation log file").option("--agent <agent>", "Agent type override (claude-code, cline, manual)").option("--port <port>", "Server port (default: 3838)", "3838").option("--no-open", "Don't auto-open browser").option("--share", "Capture a brain snapshot and generate a shareable link").option("--personality <path>", "Personality spec for assessment context").action((opts) => liveCommand({
|
|
16507
16933
|
watchPath: opts.watch,
|
|
16508
16934
|
agent: opts.agent,
|
|
16509
16935
|
port: parseInt(opts.port, 10),
|
|
16510
16936
|
noOpen: opts.open === false,
|
|
16937
|
+
share: opts.share === true,
|
|
16511
16938
|
personality: opts.personality
|
|
16512
16939
|
}));
|
|
16513
16940
|
program.parseAsync().then(() => flushTelemetry());
|