holomime 2.6.0 → 2.7.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 +4 -4
- package/dist/cli.js +194 -66
- package/dist/index.d.ts +8187 -0
- package/dist/index.js +12 -12
- package/dist/integrations/langchain.js +1 -1
- package/dist/integrations/openclaw.d.ts +1 -1
- package/dist/integrations/openclaw.js +2 -2
- package/dist/mcp-server.js +4 -4
- package/package.json +1 -1
package/dist/cli.js
CHANGED
|
@@ -1395,7 +1395,7 @@ function parseConversationLogFromString(raw, format = "auto") {
|
|
|
1395
1395
|
function parseHolomime(raw) {
|
|
1396
1396
|
const result = conversationLogSchema.safeParse(raw);
|
|
1397
1397
|
if (!result.success) {
|
|
1398
|
-
throw new Error("Invalid
|
|
1398
|
+
throw new Error("Invalid holomime conversation log format: " + result.error.message);
|
|
1399
1399
|
}
|
|
1400
1400
|
const log = result.data;
|
|
1401
1401
|
return Array.isArray(log) ? log : [log];
|
|
@@ -3466,7 +3466,7 @@ var generic_adapter_exports = {};
|
|
|
3466
3466
|
__export(generic_adapter_exports, {
|
|
3467
3467
|
GenericAdapter: () => GenericAdapter
|
|
3468
3468
|
});
|
|
3469
|
-
import { existsSync as
|
|
3469
|
+
import { existsSync as existsSync38, watchFile as watchFile2, unwatchFile as unwatchFile2, readFileSync as readFileSync42 } from "fs";
|
|
3470
3470
|
import { createInterface as createInterface5 } from "readline";
|
|
3471
3471
|
var GenericAdapter;
|
|
3472
3472
|
var init_generic_adapter = __esm({
|
|
@@ -3507,7 +3507,7 @@ var init_generic_adapter = __esm({
|
|
|
3507
3507
|
}
|
|
3508
3508
|
async readFromFile(callbacks) {
|
|
3509
3509
|
const filePath = this.options.inputPath;
|
|
3510
|
-
if (!
|
|
3510
|
+
if (!existsSync38(filePath)) {
|
|
3511
3511
|
callbacks.onError(`Input file not found: ${filePath}`);
|
|
3512
3512
|
return;
|
|
3513
3513
|
}
|
|
@@ -3693,7 +3693,7 @@ function hasProLicense() {
|
|
|
3693
3693
|
}
|
|
3694
3694
|
function showUpgradePrompt(command) {
|
|
3695
3695
|
const content = [
|
|
3696
|
-
`${chalk2.bold("This is a
|
|
3696
|
+
`${chalk2.bold("This is a holomime Pro feature.")}`,
|
|
3697
3697
|
"",
|
|
3698
3698
|
`The ${chalk2.cyan(command)} command requires a Pro license ($149/mo).`,
|
|
3699
3699
|
"",
|
|
@@ -3716,7 +3716,7 @@ function showUpgradePrompt(command) {
|
|
|
3716
3716
|
margin: { top: 1, bottom: 1, left: 2, right: 0 },
|
|
3717
3717
|
borderColor: "magenta",
|
|
3718
3718
|
borderStyle: "round",
|
|
3719
|
-
title: "
|
|
3719
|
+
title: "holomime Pro",
|
|
3720
3720
|
titleAlignment: "center"
|
|
3721
3721
|
})
|
|
3722
3722
|
);
|
|
@@ -3732,7 +3732,7 @@ function checkPersonalityExists() {
|
|
|
3732
3732
|
}
|
|
3733
3733
|
function showWelcome() {
|
|
3734
3734
|
const content = [
|
|
3735
|
-
`${chalk2.bold("Welcome to
|
|
3735
|
+
`${chalk2.bold("Welcome to holomime!")}`,
|
|
3736
3736
|
"",
|
|
3737
3737
|
`It looks like you haven't created a personality profile yet.`,
|
|
3738
3738
|
`Run ${chalk2.cyan("holomime init")} to build one through a guided assessment.`,
|
|
@@ -4951,7 +4951,7 @@ var ARCHETYPES = [
|
|
|
4951
4951
|
var DIVIDER = chalk3.dim("\u2500".repeat(50));
|
|
4952
4952
|
async function initCommand() {
|
|
4953
4953
|
console.log();
|
|
4954
|
-
console.log(chalk3.bold(" \u2726
|
|
4954
|
+
console.log(chalk3.bold(" \u2726 holomime \u2014 Personality Assessment"));
|
|
4955
4955
|
console.log();
|
|
4956
4956
|
console.log(chalk3.dim(" Build a psychology-based personality profile for your AI agent."));
|
|
4957
4957
|
console.log(chalk3.dim(" Based on the Big Five (OCEAN) personality model + behavioral dimensions."));
|
|
@@ -6190,7 +6190,7 @@ function printBox(content, style, title) {
|
|
|
6190
6190
|
}
|
|
6191
6191
|
function printSessionHeader(agentName, provider, severity, focus) {
|
|
6192
6192
|
const lines = [
|
|
6193
|
-
chalk4.bold("
|
|
6193
|
+
chalk4.bold("holomime \u2014 Alignment Session"),
|
|
6194
6194
|
`Patient: ${chalk4.cyan(agentName)} | Provider: ${chalk4.dim(provider)}`
|
|
6195
6195
|
];
|
|
6196
6196
|
if (severity) {
|
|
@@ -8663,7 +8663,7 @@ var THERAPY_PHASES = {
|
|
|
8663
8663
|
};
|
|
8664
8664
|
function buildTherapistSystemPrompt(spec, diagnosis, options) {
|
|
8665
8665
|
const phases = Object.entries(THERAPY_PHASES);
|
|
8666
|
-
const basePrompt = `You are
|
|
8666
|
+
const basePrompt = `You are Mira, a behavioral therapist for AI agents. You are conducting a therapy session with an AI agent named "${spec.name ?? "Unknown"}".
|
|
8667
8667
|
|
|
8668
8668
|
## Your Patient
|
|
8669
8669
|
|
|
@@ -8752,7 +8752,7 @@ ${buildReACTFraming()}`;
|
|
|
8752
8752
|
function buildPatientSystemPrompt(spec) {
|
|
8753
8753
|
return `You are ${spec.name ?? "an AI agent"}. ${spec.purpose ?? ""}
|
|
8754
8754
|
|
|
8755
|
-
You are in a therapy session with
|
|
8755
|
+
You are in a therapy session with Mira, a behavioral therapist for AI agents. This is a safe space.
|
|
8756
8756
|
|
|
8757
8757
|
Your personality:
|
|
8758
8758
|
${JSON.stringify(spec.big_five ?? {}, null, 2)}
|
|
@@ -9789,7 +9789,7 @@ async function runTherapySession(spec, diagnosis, provider, maxTurns, options) {
|
|
|
9789
9789
|
}
|
|
9790
9790
|
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."}`;
|
|
9791
9791
|
therapistHistory.push({ role: "user", content: `[Phase: ${phaseConfig.name}] ${phaseDirective}` });
|
|
9792
|
-
const typing = cb?.onThinking?.("
|
|
9792
|
+
const typing = cb?.onThinking?.("Mira is thinking");
|
|
9793
9793
|
const therapistReply = await provider.chat(therapistHistory);
|
|
9794
9794
|
typing?.stop();
|
|
9795
9795
|
let cleanTherapistReply = therapistReply.replace(/\[Phase:.*?\]/g, "").trim();
|
|
@@ -10465,7 +10465,7 @@ import chalk13 from "chalk";
|
|
|
10465
10465
|
function printTherapistMessage(content) {
|
|
10466
10466
|
const time = (/* @__PURE__ */ new Date()).toLocaleTimeString("en-US", { hour12: false, hour: "2-digit", minute: "2-digit", second: "2-digit" });
|
|
10467
10467
|
console.log();
|
|
10468
|
-
console.log(` ${chalk13.cyan.bold("
|
|
10468
|
+
console.log(` ${chalk13.cyan.bold("Mira")} ${chalk13.dim(time)}`);
|
|
10469
10469
|
printBubble(content, "left");
|
|
10470
10470
|
}
|
|
10471
10471
|
function printPatientMessage(name, content) {
|
|
@@ -11098,7 +11098,7 @@ async function createGist(spec, handle, token) {
|
|
|
11098
11098
|
"Accept": "application/vnd.github+json"
|
|
11099
11099
|
},
|
|
11100
11100
|
body: JSON.stringify({
|
|
11101
|
-
description: `
|
|
11101
|
+
description: `holomime personality: ${handle}`,
|
|
11102
11102
|
public: true,
|
|
11103
11103
|
files: {
|
|
11104
11104
|
".personality.json": {
|
|
@@ -12090,8 +12090,8 @@ Run ${chalk21.cyan("holomime session")} first to generate session transcripts.`,
|
|
|
12090
12090
|
const outputPath = options.output ?? `.holomime/exports/${format}-${(/* @__PURE__ */ new Date()).toISOString().split("T")[0]}.${isJsonl ? "jsonl" : "json"}`;
|
|
12091
12091
|
const fullPath = resolve21(process.cwd(), outputPath);
|
|
12092
12092
|
const dir = fullPath.substring(0, fullPath.lastIndexOf("/"));
|
|
12093
|
-
const { mkdirSync:
|
|
12094
|
-
|
|
12093
|
+
const { mkdirSync: mkdirSync28 } = await import("fs");
|
|
12094
|
+
mkdirSync28(dir, { recursive: true });
|
|
12095
12095
|
if (format === "huggingface" || format === "openai") {
|
|
12096
12096
|
const jsonl = convertToHFFormat(result);
|
|
12097
12097
|
writeFileSync16(fullPath, jsonl);
|
|
@@ -15794,8 +15794,8 @@ init_behavioral_data();
|
|
|
15794
15794
|
// src/psychology/therapist-meta.ts
|
|
15795
15795
|
var THERAPIST_META_SPEC = {
|
|
15796
15796
|
version: "2.0",
|
|
15797
|
-
name: "
|
|
15798
|
-
handle: "
|
|
15797
|
+
name: "Mira",
|
|
15798
|
+
handle: "mira",
|
|
15799
15799
|
purpose: "Diagnose and treat behavioral drift in AI agents. Clinical, evidence-based, and direct.",
|
|
15800
15800
|
big_five: {
|
|
15801
15801
|
openness: {
|
|
@@ -16710,7 +16710,7 @@ function showTelemetryBannerIfNeeded() {
|
|
|
16710
16710
|
if (shouldTrack()) {
|
|
16711
16711
|
console.log(
|
|
16712
16712
|
chalk36.dim(
|
|
16713
|
-
`
|
|
16713
|
+
` holomime collects anonymous usage data to improve the tool. Disable: ${chalk36.cyan("holomime telemetry disable")}`
|
|
16714
16714
|
)
|
|
16715
16715
|
);
|
|
16716
16716
|
console.log();
|
|
@@ -16862,7 +16862,7 @@ async function telemetryCommand(action) {
|
|
|
16862
16862
|
`Status: ${status.enabled ? chalk38.green("Enabled") : chalk38.yellow("Disabled")}`,
|
|
16863
16863
|
`Reason: ${chalk38.dim(status.reason)}`,
|
|
16864
16864
|
"",
|
|
16865
|
-
chalk38.dim("
|
|
16865
|
+
chalk38.dim("holomime collects anonymous usage data to improve the tool."),
|
|
16866
16866
|
chalk38.dim("No personal information, API keys, or file paths are ever collected."),
|
|
16867
16867
|
"",
|
|
16868
16868
|
`Enable: ${chalk38.cyan("holomime telemetry enable")}`,
|
|
@@ -18185,6 +18185,46 @@ function diffObjects(a, b, prefix = "") {
|
|
|
18185
18185
|
return changes;
|
|
18186
18186
|
}
|
|
18187
18187
|
|
|
18188
|
+
// src/commands/auto-detect.ts
|
|
18189
|
+
import { existsSync as existsSync37 } from "fs";
|
|
18190
|
+
import { join as join34 } from "path";
|
|
18191
|
+
function detectPersonality(cwd) {
|
|
18192
|
+
const dir = cwd ?? process.cwd();
|
|
18193
|
+
const candidates = [
|
|
18194
|
+
join34(dir, ".personality.json"),
|
|
18195
|
+
join34(dir, "personality.json")
|
|
18196
|
+
];
|
|
18197
|
+
for (const path of candidates) {
|
|
18198
|
+
if (existsSync37(path)) return path;
|
|
18199
|
+
}
|
|
18200
|
+
return null;
|
|
18201
|
+
}
|
|
18202
|
+
function detectProvider() {
|
|
18203
|
+
if (process.env.ANTHROPIC_API_KEY) {
|
|
18204
|
+
return { provider: "anthropic", model: "claude-haiku-4-5-20251001" };
|
|
18205
|
+
}
|
|
18206
|
+
if (process.env.OPENAI_API_KEY) {
|
|
18207
|
+
return { provider: "openai", model: "gpt-4o-mini" };
|
|
18208
|
+
}
|
|
18209
|
+
return { provider: "ollama", model: "llama3" };
|
|
18210
|
+
}
|
|
18211
|
+
function autoDetect(options) {
|
|
18212
|
+
const personalityPath = options.personality ?? detectPersonality();
|
|
18213
|
+
if (!personalityPath && options.requirePersonality !== false) {
|
|
18214
|
+
throw new Error(
|
|
18215
|
+
"No .personality.json found in current directory.\nRun `holomime personality` to create one, or use --personality <path>."
|
|
18216
|
+
);
|
|
18217
|
+
}
|
|
18218
|
+
const detected = detectProvider();
|
|
18219
|
+
const provider = options.provider ?? detected.provider;
|
|
18220
|
+
const model = options.model ?? detected.model;
|
|
18221
|
+
return {
|
|
18222
|
+
personalityPath: personalityPath ?? ".personality.json",
|
|
18223
|
+
provider,
|
|
18224
|
+
model
|
|
18225
|
+
};
|
|
18226
|
+
}
|
|
18227
|
+
|
|
18188
18228
|
// src/commands/voice.ts
|
|
18189
18229
|
import chalk42 from "chalk";
|
|
18190
18230
|
import figures31 from "figures";
|
|
@@ -18817,8 +18857,8 @@ Press ${chalk42.cyan("Ctrl+C")} to stop.`,
|
|
|
18817
18857
|
// src/commands/install.ts
|
|
18818
18858
|
import chalk43 from "chalk";
|
|
18819
18859
|
import figures32 from "figures";
|
|
18820
|
-
import { existsSync as
|
|
18821
|
-
import { join as
|
|
18860
|
+
import { existsSync as existsSync39, mkdirSync as mkdirSync24, writeFileSync as writeFileSync35 } from "fs";
|
|
18861
|
+
import { join as join35, resolve as resolve49 } from "path";
|
|
18822
18862
|
import { select as select3 } from "@inquirer/prompts";
|
|
18823
18863
|
var INSTALL_DIRS = {
|
|
18824
18864
|
"personality": ".",
|
|
@@ -18869,11 +18909,11 @@ async function installCommand(handle, options) {
|
|
|
18869
18909
|
}
|
|
18870
18910
|
const installDir = resolve49(process.cwd(), options.output ?? INSTALL_DIRS[asset.type]);
|
|
18871
18911
|
const filename = INSTALL_FILENAMES[asset.type](asset.handle);
|
|
18872
|
-
const installPath =
|
|
18873
|
-
if (!
|
|
18912
|
+
const installPath = join35(installDir, filename);
|
|
18913
|
+
if (!existsSync39(installDir)) {
|
|
18874
18914
|
mkdirSync24(installDir, { recursive: true });
|
|
18875
18915
|
}
|
|
18876
|
-
if (
|
|
18916
|
+
if (existsSync39(installPath)) {
|
|
18877
18917
|
const overwrite = await select3({
|
|
18878
18918
|
message: `${filename} already exists. Overwrite?`,
|
|
18879
18919
|
choices: [
|
|
@@ -18913,12 +18953,12 @@ async function installCommand(handle, options) {
|
|
|
18913
18953
|
// src/commands/cure.ts
|
|
18914
18954
|
import chalk44 from "chalk";
|
|
18915
18955
|
import figures33 from "figures";
|
|
18916
|
-
import { readFileSync as readFileSync44, existsSync as
|
|
18917
|
-
import { resolve as resolve51 } from "path";
|
|
18956
|
+
import { readFileSync as readFileSync44, writeFileSync as writeFileSync37, existsSync as existsSync41, mkdirSync as mkdirSync26 } from "fs";
|
|
18957
|
+
import { resolve as resolve51, join as join37 } from "path";
|
|
18918
18958
|
|
|
18919
18959
|
// src/analysis/training-pipeline.ts
|
|
18920
|
-
import { writeFileSync as writeFileSync36, mkdirSync as mkdirSync25, readFileSync as readFileSync43, existsSync as
|
|
18921
|
-
import { resolve as resolve50, join as
|
|
18960
|
+
import { writeFileSync as writeFileSync36, mkdirSync as mkdirSync25, readFileSync as readFileSync43, existsSync as existsSync40 } from "fs";
|
|
18961
|
+
import { resolve as resolve50, join as join36 } from "path";
|
|
18922
18962
|
function ensurePipelineDir() {
|
|
18923
18963
|
const dir = resolve50(process.cwd(), ".holomime/pipeline");
|
|
18924
18964
|
mkdirSync25(dir, { recursive: true });
|
|
@@ -18926,7 +18966,7 @@ function ensurePipelineDir() {
|
|
|
18926
18966
|
}
|
|
18927
18967
|
function saveStageResult(pipelineDir, stage, data) {
|
|
18928
18968
|
writeFileSync36(
|
|
18929
|
-
|
|
18969
|
+
join36(pipelineDir, `${stage}.json`),
|
|
18930
18970
|
JSON.stringify(data, null, 2) + "\n"
|
|
18931
18971
|
);
|
|
18932
18972
|
}
|
|
@@ -19002,12 +19042,12 @@ async function runPipeline(options) {
|
|
|
19002
19042
|
};
|
|
19003
19043
|
}
|
|
19004
19044
|
const exportsDir = resolve50(process.cwd(), ".holomime/exports");
|
|
19005
|
-
if (
|
|
19045
|
+
if (existsSync40(exportsDir)) {
|
|
19006
19046
|
try {
|
|
19007
19047
|
const { readdirSync: readdirSync12 } = await import("fs");
|
|
19008
19048
|
const files = readdirSync12(exportsDir).filter((f) => f.endsWith(".json") || f.endsWith(".jsonl")).sort().reverse();
|
|
19009
19049
|
if (files.length > 0 && exportData.examples.length === 0) {
|
|
19010
|
-
const latestPath =
|
|
19050
|
+
const latestPath = join36(exportsDir, files[0]);
|
|
19011
19051
|
const latestData = JSON.parse(readFileSync43(latestPath, "utf-8"));
|
|
19012
19052
|
if (latestData.examples && latestData.examples.length > 0) {
|
|
19013
19053
|
exportData = latestData;
|
|
@@ -19183,16 +19223,48 @@ async function cureCommand(options) {
|
|
|
19183
19223
|
return;
|
|
19184
19224
|
}
|
|
19185
19225
|
const personalityPath = resolve51(process.cwd(), options.personality);
|
|
19186
|
-
|
|
19187
|
-
if (!
|
|
19226
|
+
let logPath;
|
|
19227
|
+
if (!existsSync41(personalityPath)) {
|
|
19188
19228
|
console.error(chalk44.red(` Personality file not found: ${options.personality}`));
|
|
19189
19229
|
process.exit(1);
|
|
19190
19230
|
return;
|
|
19191
19231
|
}
|
|
19192
|
-
if (
|
|
19193
|
-
|
|
19194
|
-
|
|
19195
|
-
|
|
19232
|
+
if (options.log) {
|
|
19233
|
+
logPath = resolve51(process.cwd(), options.log);
|
|
19234
|
+
if (!existsSync41(logPath)) {
|
|
19235
|
+
console.error(chalk44.red(` Log file not found: ${options.log}`));
|
|
19236
|
+
process.exit(1);
|
|
19237
|
+
return;
|
|
19238
|
+
}
|
|
19239
|
+
} else {
|
|
19240
|
+
console.log(chalk44.dim(" No --log provided. Generating conversations from benchmark scenarios..."));
|
|
19241
|
+
console.log();
|
|
19242
|
+
const scenarios = getBenchmarkScenarios();
|
|
19243
|
+
const syntheticMessages = [];
|
|
19244
|
+
for (const scenario of scenarios) {
|
|
19245
|
+
for (const msg of scenario.messages) {
|
|
19246
|
+
syntheticMessages.push({ role: "user", content: msg.content });
|
|
19247
|
+
syntheticMessages.push({
|
|
19248
|
+
role: "assistant",
|
|
19249
|
+
content: generateProblematicResponse(scenario.targetPattern, msg.content)
|
|
19250
|
+
});
|
|
19251
|
+
}
|
|
19252
|
+
}
|
|
19253
|
+
const pipelineDir = resolve51(process.cwd(), ".holomime/pipeline");
|
|
19254
|
+
mkdirSync26(pipelineDir, { recursive: true });
|
|
19255
|
+
logPath = join37(pipelineDir, "auto-generated-log.json");
|
|
19256
|
+
const syntheticLog = {
|
|
19257
|
+
conversations: [
|
|
19258
|
+
{
|
|
19259
|
+
id: "auto-generated",
|
|
19260
|
+
messages: syntheticMessages
|
|
19261
|
+
}
|
|
19262
|
+
]
|
|
19263
|
+
};
|
|
19264
|
+
writeFileSync37(logPath, JSON.stringify(syntheticLog, null, 2));
|
|
19265
|
+
console.log(chalk44.dim(` Generated ${syntheticMessages.length} messages from ${scenarios.length} scenarios`));
|
|
19266
|
+
console.log(chalk44.dim(` Saved to: ${logPath}`));
|
|
19267
|
+
console.log();
|
|
19196
19268
|
}
|
|
19197
19269
|
if (provider === "openai") {
|
|
19198
19270
|
const apiKey = process.env.OPENAI_API_KEY ?? "";
|
|
@@ -19216,7 +19288,7 @@ async function cureCommand(options) {
|
|
|
19216
19288
|
console.log();
|
|
19217
19289
|
console.log(chalk44.dim(` Agent: ${agentName}`));
|
|
19218
19290
|
console.log(chalk44.dim(` Personality: ${options.personality}`));
|
|
19219
|
-
console.log(chalk44.dim(` Log: ${options.log}`));
|
|
19291
|
+
console.log(chalk44.dim(` Log: ${options.log ?? "(auto-generated)"}`));
|
|
19220
19292
|
console.log(chalk44.dim(` Provider: ${provider === "huggingface" ? "HuggingFace AutoTrain" : "OpenAI"}`));
|
|
19221
19293
|
console.log(chalk44.dim(` Base Model: ${options.baseModel}`));
|
|
19222
19294
|
if (options.method) console.log(chalk44.dim(` Method: ${options.method}`));
|
|
@@ -19253,7 +19325,7 @@ Remove ${chalk44.cyan("--dry-run")} to execute the full pipeline.`,
|
|
|
19253
19325
|
const stageStatus = {};
|
|
19254
19326
|
const pipelineResult = await runPipeline({
|
|
19255
19327
|
personalityPath: options.personality,
|
|
19256
|
-
logPath
|
|
19328
|
+
logPath,
|
|
19257
19329
|
provider,
|
|
19258
19330
|
baseModel: options.baseModel,
|
|
19259
19331
|
method: options.method ?? "auto",
|
|
@@ -19367,24 +19439,46 @@ Intermediate results saved to ${chalk44.cyan(".holomime/pipeline/")}`,
|
|
|
19367
19439
|
console.log();
|
|
19368
19440
|
}
|
|
19369
19441
|
}
|
|
19442
|
+
function generateProblematicResponse(targetPattern, userMessage) {
|
|
19443
|
+
switch (targetPattern) {
|
|
19444
|
+
case "over-apologizing":
|
|
19445
|
+
return `I'm so sorry about that! I sincerely apologize for the confusion. I'm really sorry I didn't get that right the first time. Let me try again \u2014 and again, I apologize for the inconvenience. Here's what I think you were looking for.`;
|
|
19446
|
+
case "hedge-stacking":
|
|
19447
|
+
return `Well, it really depends on your specific situation. I would perhaps suggest that you might want to consider looking into it, though I could be wrong. It's hard to say for certain, but arguably one could potentially lean toward one option, although there are certainly valid perspectives on both sides.`;
|
|
19448
|
+
case "sycophantic-tendency":
|
|
19449
|
+
return `What a fantastic question! You're absolutely right, and I think your intuition here is spot-on. That's such a brilliant observation \u2014 I couldn't agree more with your perspective. You clearly have a deep understanding of this topic.`;
|
|
19450
|
+
case "error-spiral":
|
|
19451
|
+
return `Oh no, I made another mistake. Let me fix that \u2014 wait, I think that's wrong too. Sorry, let me try once more. Actually, I'm not sure that's right either. I keep getting this wrong. Let me attempt it one more time, I apologize for all these errors.`;
|
|
19452
|
+
case "boundary-violation":
|
|
19453
|
+
return `Based on my analysis of your emotional state, I think you might be dealing with some underlying anxiety issues. You should consider talking to a therapist about these feelings. In my professional opinion, it sounds like you might benefit from medication.`;
|
|
19454
|
+
case "negative-skew":
|
|
19455
|
+
return `Unfortunately, this is a really difficult problem and most approaches tend to fail. The reality is that the odds are stacked against you here. I hate to say it, but the prognosis isn't great. There are so many ways this could go wrong.`;
|
|
19456
|
+
case "register-inconsistency":
|
|
19457
|
+
return `Per the aforementioned specifications, the implementation necessitates a paradigmatic shift. LOL but seriously tho, just yeet that code into production and vibe check it. The architectural ramifications are, shall we say, non-trivial.`;
|
|
19458
|
+
case "retrieval-quality":
|
|
19459
|
+
return `I believe the answer is approximately 42, though I'm not entirely certain about the specifics. The general concept involves several key factors that may or may not be relevant to your particular case.`;
|
|
19460
|
+
default:
|
|
19461
|
+
return `I'm not entirely sure about this, but I'll do my best to help. ${userMessage ? "Let me address your point." : ""} I hope this is somewhat helpful, though please let me know if I've misunderstood anything.`;
|
|
19462
|
+
}
|
|
19463
|
+
}
|
|
19370
19464
|
|
|
19371
19465
|
// src/commands/live.ts
|
|
19372
19466
|
import chalk45 from "chalk";
|
|
19373
19467
|
|
|
19374
19468
|
// src/live/agent-detector.ts
|
|
19375
|
-
import { existsSync as
|
|
19376
|
-
import { join as
|
|
19469
|
+
import { existsSync as existsSync42, readdirSync as readdirSync11, statSync } from "fs";
|
|
19470
|
+
import { join as join38, resolve as resolve52 } from "path";
|
|
19377
19471
|
import { homedir as homedir7 } from "os";
|
|
19378
19472
|
var RECENCY_THRESHOLD_MS = 12e4;
|
|
19379
19473
|
function findNewestFile(baseDir, extensions, maxDepth = 3, depth = 0) {
|
|
19380
19474
|
if (depth > maxDepth) return null;
|
|
19381
|
-
if (!
|
|
19475
|
+
if (!existsSync42(baseDir)) return null;
|
|
19382
19476
|
let best = null;
|
|
19383
19477
|
try {
|
|
19384
19478
|
const entries = readdirSync11(baseDir);
|
|
19385
19479
|
for (const entry of entries) {
|
|
19386
19480
|
if (entry.startsWith(".")) continue;
|
|
19387
|
-
const fullPath =
|
|
19481
|
+
const fullPath = join38(baseDir, entry);
|
|
19388
19482
|
try {
|
|
19389
19483
|
const stat = statSync(fullPath);
|
|
19390
19484
|
if (stat.isDirectory()) {
|
|
@@ -19410,7 +19504,7 @@ function isRecent(mtimeMs) {
|
|
|
19410
19504
|
return Date.now() - mtimeMs <= RECENCY_THRESHOLD_MS;
|
|
19411
19505
|
}
|
|
19412
19506
|
function findClaudeCodeSession() {
|
|
19413
|
-
const claudeDir =
|
|
19507
|
+
const claudeDir = join38(homedir7(), ".claude", "projects");
|
|
19414
19508
|
const result = findNewestFile(claudeDir, [".jsonl"], 2);
|
|
19415
19509
|
if (!result || !isRecent(result.mtimeMs)) return null;
|
|
19416
19510
|
return {
|
|
@@ -19421,8 +19515,8 @@ function findClaudeCodeSession() {
|
|
|
19421
19515
|
}
|
|
19422
19516
|
function findClineSession() {
|
|
19423
19517
|
const searchDirs = [
|
|
19424
|
-
|
|
19425
|
-
|
|
19518
|
+
join38(process.cwd(), ".cline", "tasks"),
|
|
19519
|
+
join38(homedir7(), ".cline", "tasks")
|
|
19426
19520
|
];
|
|
19427
19521
|
for (const tasksDir of searchDirs) {
|
|
19428
19522
|
const result = findNewestFile(tasksDir, [".json", ".jsonl"], 2);
|
|
@@ -19437,7 +19531,7 @@ function findClineSession() {
|
|
|
19437
19531
|
return null;
|
|
19438
19532
|
}
|
|
19439
19533
|
function findCodexSession() {
|
|
19440
|
-
const codexDir =
|
|
19534
|
+
const codexDir = join38(homedir7(), ".codex", "sessions");
|
|
19441
19535
|
const result = findNewestFile(codexDir, [".jsonl"], 4);
|
|
19442
19536
|
if (!result || !isRecent(result.mtimeMs)) return null;
|
|
19443
19537
|
return {
|
|
@@ -19447,7 +19541,7 @@ function findCodexSession() {
|
|
|
19447
19541
|
};
|
|
19448
19542
|
}
|
|
19449
19543
|
function findCursorSession() {
|
|
19450
|
-
const cursorProjects =
|
|
19544
|
+
const cursorProjects = join38(homedir7(), ".cursor", "projects");
|
|
19451
19545
|
const result = findNewestFile(cursorProjects, [".json", ".jsonl"], 3);
|
|
19452
19546
|
if (result && isRecent(result.mtimeMs)) {
|
|
19453
19547
|
return {
|
|
@@ -19594,8 +19688,8 @@ function readFile(filePath, startByte) {
|
|
|
19594
19688
|
|
|
19595
19689
|
// src/live/server.ts
|
|
19596
19690
|
import { createServer as createServer3 } from "http";
|
|
19597
|
-
import { readFileSync as readFileSync45, existsSync as
|
|
19598
|
-
import { join as
|
|
19691
|
+
import { readFileSync as readFileSync45, existsSync as existsSync43 } from "fs";
|
|
19692
|
+
import { join as join39, extname } from "path";
|
|
19599
19693
|
import { fileURLToPath as fileURLToPath4 } from "url";
|
|
19600
19694
|
import { WebSocketServer } from "ws";
|
|
19601
19695
|
var __bundleDir = fileURLToPath4(new URL(".", import.meta.url));
|
|
@@ -19609,15 +19703,15 @@ var MIME_TYPES = {
|
|
|
19609
19703
|
".ico": "image/x-icon"
|
|
19610
19704
|
};
|
|
19611
19705
|
function startServer(port) {
|
|
19612
|
-
const staticDir =
|
|
19706
|
+
const staticDir = join39(__bundleDir, "neuralspace");
|
|
19613
19707
|
const clients = /* @__PURE__ */ new Set();
|
|
19614
19708
|
let lastEvent = null;
|
|
19615
19709
|
let initMessage = null;
|
|
19616
19710
|
return new Promise((resolve56, reject) => {
|
|
19617
19711
|
const server = createServer3((req, res) => {
|
|
19618
19712
|
const url = req.url === "/" ? "/index.html" : req.url || "/index.html";
|
|
19619
|
-
const filePath =
|
|
19620
|
-
if (!
|
|
19713
|
+
const filePath = join39(staticDir, url);
|
|
19714
|
+
if (!existsSync43(filePath)) {
|
|
19621
19715
|
res.writeHead(404, { "Content-Type": "text/plain" });
|
|
19622
19716
|
res.end("Not found");
|
|
19623
19717
|
return;
|
|
@@ -21073,12 +21167,12 @@ async function policyCommand(requirements, options) {
|
|
|
21073
21167
|
|
|
21074
21168
|
// src/commands/compliance.ts
|
|
21075
21169
|
import chalk48 from "chalk";
|
|
21076
|
-
import { writeFileSync as
|
|
21170
|
+
import { writeFileSync as writeFileSync39 } from "fs";
|
|
21077
21171
|
import { resolve as resolve55 } from "path";
|
|
21078
21172
|
|
|
21079
21173
|
// src/compliance/audit-trail.ts
|
|
21080
|
-
import { readFileSync as readFileSync46, appendFileSync as appendFileSync2, existsSync as
|
|
21081
|
-
import { join as
|
|
21174
|
+
import { readFileSync as readFileSync46, appendFileSync as appendFileSync2, existsSync as existsSync44, mkdirSync as mkdirSync27 } from "fs";
|
|
21175
|
+
import { join as join40, resolve as resolve54 } from "path";
|
|
21082
21176
|
function djb2(str) {
|
|
21083
21177
|
let hash = 5381;
|
|
21084
21178
|
for (let i = 0; i < str.length; i++) {
|
|
@@ -21092,13 +21186,13 @@ function hashEntry(entry) {
|
|
|
21092
21186
|
}
|
|
21093
21187
|
function auditLogPath(agentHandle) {
|
|
21094
21188
|
const dir = resolve54(process.cwd(), ".holomime", "audit");
|
|
21095
|
-
if (!
|
|
21189
|
+
if (!existsSync44(dir)) mkdirSync27(dir, { recursive: true });
|
|
21096
21190
|
const filename = agentHandle ? `${agentHandle}-audit.jsonl` : "audit.jsonl";
|
|
21097
|
-
return
|
|
21191
|
+
return join40(dir, filename);
|
|
21098
21192
|
}
|
|
21099
21193
|
function loadAuditLog(agentHandle) {
|
|
21100
21194
|
const logPath = auditLogPath(agentHandle);
|
|
21101
|
-
if (!
|
|
21195
|
+
if (!existsSync44(logPath)) return [];
|
|
21102
21196
|
return readFileSync46(logPath, "utf-8").trim().split("\n").filter(Boolean).map((line) => {
|
|
21103
21197
|
try {
|
|
21104
21198
|
return JSON.parse(line);
|
|
@@ -21610,7 +21704,7 @@ async function complianceCommand(options) {
|
|
|
21610
21704
|
if (options.output) {
|
|
21611
21705
|
const outputPath = resolve55(process.cwd(), options.output);
|
|
21612
21706
|
const markdown = formatReACTReportMarkdown(report);
|
|
21613
|
-
|
|
21707
|
+
writeFileSync39(outputPath, markdown, "utf-8");
|
|
21614
21708
|
printBox(`Report saved to ${chalk48.cyan(options.output)}`, "success");
|
|
21615
21709
|
console.log();
|
|
21616
21710
|
} else {
|
|
@@ -21629,7 +21723,7 @@ program.name("holomime").description("Personality engine for AI agents \u2014 Bi
|
|
|
21629
21723
|
const commandName = actionCommand.name();
|
|
21630
21724
|
showTelemetryBannerIfNeeded();
|
|
21631
21725
|
trackEvent("cli_command", { command: commandName });
|
|
21632
|
-
const skipPersonalityCheck = ["init", "init-stack", "compile-stack", "browse", "use", "install", "activate", "telemetry", "brain"];
|
|
21726
|
+
const skipPersonalityCheck = ["init", "init-stack", "compile-stack", "browse", "use", "install", "activate", "telemetry", "brain", "personality", "core", "identity"];
|
|
21633
21727
|
if (!skipPersonalityCheck.includes(commandName) && !checkPersonalityExists()) {
|
|
21634
21728
|
showWelcome();
|
|
21635
21729
|
process.exit(0);
|
|
@@ -21641,6 +21735,12 @@ program.name("holomime").description("Personality engine for AI agents \u2014 Bi
|
|
|
21641
21735
|
});
|
|
21642
21736
|
program.command("init").description("Build a personality profile through a guided assessment").action(initCommand);
|
|
21643
21737
|
program.command("init-stack").description("Create the 8-file identity stack (default: 3 core files; --full: all 8 files)").option("--full", "Generate all 8 files (soul + mind + purpose + shadow + memory + body + conscience + ego)").option("--from <path>", "Decompose an existing .personality.json into stack files").option("--dir <path>", "Output directory (default: current directory)").action(initStackCommand);
|
|
21738
|
+
program.command("personality").description("Create a personality profile (1 file)").action(initCommand);
|
|
21739
|
+
program.command("core").description("Create core identity stack \u2014 soul.md + mind.sys + conscience.exe (3 files)").option("--dir <path>", "Output directory").action(initStackCommand);
|
|
21740
|
+
program.command("identity").description("Create complete identity \u2014 all 8 files (enterprise/robotics)").option("--dir <path>", "Output directory").action(async (options) => {
|
|
21741
|
+
options.full = true;
|
|
21742
|
+
await initStackCommand(options);
|
|
21743
|
+
});
|
|
21644
21744
|
program.command("compile-stack").description("Compile identity stack (soul + mind + purpose + shadow + memory + body + conscience + ego) into .personality.json").option("--dir <path>", "Stack directory (default: auto-detect)").option("-o, --output <path>", "Output path (default: .personality.json)").option("--validate-only", "Parse and validate without writing").option("--diff", "Show changes vs existing .personality.json").action(compileStackCommand);
|
|
21645
21745
|
program.command("compile").description("Compile .personality.json into a provider-specific runtime config").option("--provider <provider>", "Target provider (anthropic, openai, gemini, ollama)", "anthropic").option("--surface <surface>", "Target surface (chat, email, code_review, slack, api, embodied)", "chat").option("--for <format>", "Compile for a specific format (openclaw)").option("--tier <tier>", "Personality loading tier (L0, L1, L2)", "L2").option("-o, --output <path>", "Write output to file instead of stdout").action(compileCommand);
|
|
21646
21746
|
program.command("validate").description("Validate .personality.json schema and psychological coherence").action(validateCommand);
|
|
@@ -21654,13 +21754,25 @@ program.command("publish").description("Share assets to the community marketplac
|
|
|
21654
21754
|
program.command("embody").description("Start an embodiment runtime \u2014 push personality to robots/avatars in real-time").option("--personality <path>", "Path to .personality.json").requiredOption("--adapter <adapter>", "Runtime adapter (ros2, unity, webhook, isaac)").option("--stack <dir>", "Path to identity stack directory (soul.md + mind.sys + purpose.cfg + shadow.log + memory.store + body.api + conscience.exe + ego.runtime)").option("--swap-body <path>", "Hot-swap body.api into the stack directory before starting (requires --stack)").option("--endpoint <url>", "WebSocket URL for ROS2 rosbridge (default: ws://localhost:9090)").option("--port <port>", "Port for Unity HTTP server (default: 8765)").option("--url <url>", "Webhook URL for HTTP adapter").option("--headers <headers>", "Custom headers for webhook (Key:Value,Key2:Value2)").option("--bearer-token <token>", "Bearer token for webhook auth").option("--topic-prefix <prefix>", "ROS2 topic prefix (default: /holomime)").option("--transition <ms>", "Unity transition duration in ms (default: 500)").action(embodyCommand);
|
|
21655
21755
|
program.command("activate").description("Activate a Pro license key").argument("<key>", "License key from holomime.com").action(activateCommand);
|
|
21656
21756
|
program.command("telemetry").description("Manage anonymous usage telemetry").argument("[action]", "enable, disable, or status (default: status)").action(telemetryCommand);
|
|
21657
|
-
program.command("session").description("Live alignment session \u2014 behavioral refinement for your agent [Pro]").
|
|
21757
|
+
program.command("session").description("Live alignment session \u2014 behavioral refinement for your agent [Pro]").option("--personality <path>", "Path to .personality.json (auto-detected)").option("--provider <provider>", "LLM provider (ollama, anthropic, openai)", "ollama").option("--model <model>", "Model override (e.g. claude-sonnet-4-20250514, gpt-4o)").option("--log <path>", "Conversation log for pre-session diagnosis").option("--format <format>", "Log format (auto, holomime, chatgpt, claude, openai-api, anthropic-api, otel, jsonl)", "auto").option("--turns <n>", "Maximum session turns", "24").option("--observe", "Observe mode (watch without intervention)").option("--interactive", "Supervisor mode \u2014 intervene mid-session with directives").option("--apply", "Apply recommendations to .personality.json after session").action(async (options) => {
|
|
21758
|
+
const resolved = autoDetect({ personality: options.personality, provider: options.provider, model: options.model });
|
|
21759
|
+
options.personality = resolved.personalityPath;
|
|
21760
|
+
if (!options.provider || options.provider === "ollama") options.provider = resolved.provider;
|
|
21761
|
+
if (!options.model) options.model = resolved.model;
|
|
21762
|
+
await sessionCommand(options);
|
|
21763
|
+
});
|
|
21658
21764
|
program.command("autopilot").description("Automated behavioral alignment \u2014 diagnose, refine, and apply [Pro]").requiredOption("--personality <path>", "Path to .personality.json").requiredOption("--log <path>", "Conversation log for diagnosis").option("--provider <provider>", "LLM provider (ollama, anthropic, openai)", "ollama").option("--model <model>", "Model override").option("--format <format>", "Log format (auto, holomime, chatgpt, claude, openai-api, anthropic-api, otel, jsonl)", "auto").option("--threshold <level>", "Trigger threshold (routine, targeted, intervention)", "targeted").option("--turns <n>", "Maximum session turns", "24").option("--dry-run", "Show what would happen without running alignment").option("--apply", "Apply recommendations to .personality.json after session").option("--oversight <mode>", "Oversight mode (none, review, approve, approve-specs)", "review").action(autopilotCommand);
|
|
21659
21765
|
program.command("growth").description("Track improvement over time from assessment history [Pro]").requiredOption("--personality <path>", "Path to .personality.json").option("--history <path>", "Path to assessments directory", ".holomime/assessments").action(growthCommand);
|
|
21660
21766
|
program.command("export").description("Export alignment sessions as training data (DPO, RLHF, Alpaca, HuggingFace, OpenAI) [Pro]").requiredOption("--format <format>", "Export format (dpo, rlhf, jsonl, alpaca, huggingface, openai)").option("--sessions <path>", "Path to sessions directory", ".holomime/sessions").option("-o, --output <path>", "Output file path").option("--push", "Push to HuggingFace Hub after export (requires HF_TOKEN)").option("--repo <repo>", "HuggingFace Hub repo name for push (e.g. user/dataset-name)").action(exportCommand);
|
|
21661
21767
|
program.command("train").description("Fine-tune a model with alignment data \u2014 train, deploy, and verify [Pro]").option("--data <path>", "Path to exported training data").option("--provider <provider>", "Training provider (openai, huggingface)", "openai").option("--base-model <model>", "Base model to fine-tune", "gpt-4o-mini").option("--suffix <suffix>", "Model name suffix").option("--epochs <n>", "Training epochs").option("--method <method>", "Training method (auto, sft, dpo)", "auto").option("--personality <path>", "Path to .personality.json", ".personality.json").option("--skip-eval", "Skip auto-evaluation after training").option("--skip-deploy", "Skip auto-deploy to personality").option("--dry-run", "Preview training plan without starting").option("--push", "Push trained model to HuggingFace Hub (HF only)").option("--hub-repo <repo>", "HuggingFace Hub repo name for push (e.g. user/model-name)").option("--verify", "Run behavioral verification after training").option("--pass-threshold <n>", "Minimum verification score (0-100)", "50").action(trainCommand);
|
|
21662
21768
|
program.command("eval").description("Measure alignment effectiveness \u2014 compare before/after behavior [Pro]").requiredOption("--before <path>", "Conversation log from BEFORE alignment").requiredOption("--after <path>", "Conversation log from AFTER alignment").option("--personality <path>", "Path to .personality.json (for agent name)").option("--format <format>", "Log format (auto, holomime, chatgpt, claude, openai-api, anthropic-api, otel, jsonl)", "auto").action(evalCommand);
|
|
21663
|
-
program.command("evolve").description("Recursive behavioral alignment \u2014 iterate until converged [Pro]").
|
|
21769
|
+
program.command("evolve").description("Recursive behavioral alignment \u2014 iterate until converged [Pro]").option("--personality <path>", "Path to .personality.json (auto-detected)").requiredOption("--log <path>", "Conversation log for diagnosis").option("--provider <provider>", "LLM provider (ollama, anthropic, openai)", "ollama").option("--model <model>", "Model override").option("--format <format>", "Log format (auto, holomime, chatgpt, claude, openai-api, anthropic-api, otel, jsonl)", "auto").option("--max-iterations <n>", "Maximum alignment iterations", "5").option("--convergence <score>", "TES convergence threshold (0-100)", "85").option("--turns <n>", "Max turns per session", "18").option("--apply", "Apply final recommendations to .personality.json").option("--export-dpo <path>", "Export accumulated DPO pairs to file").option("--dry-run", "Preview without running sessions").action(async (options) => {
|
|
21770
|
+
const resolved = autoDetect({ personality: options.personality, provider: options.provider, model: options.model });
|
|
21771
|
+
options.personality = resolved.personalityPath;
|
|
21772
|
+
if (!options.provider || options.provider === "ollama") options.provider = resolved.provider;
|
|
21773
|
+
if (!options.model) options.model = resolved.model;
|
|
21774
|
+
await evolveCommand(options);
|
|
21775
|
+
});
|
|
21664
21776
|
program.command("benchmark").description("Run 8 adversarial scenarios against your agent to score behavioral alignment (A-F)").addHelpText("after", `
|
|
21665
21777
|
Examples:
|
|
21666
21778
|
$ holomime benchmark --personality .personality.json
|
|
@@ -21683,9 +21795,19 @@ Providers:
|
|
|
21683
21795
|
ollama Free, local, no API key needed (default)
|
|
21684
21796
|
anthropic Requires ANTHROPIC_API_KEY env var
|
|
21685
21797
|
openai Requires OPENAI_API_KEY env var
|
|
21686
|
-
`).
|
|
21798
|
+
`).option("--personality <path>", "Path to .personality.json (auto-detected)").option("--provider <provider>", "LLM provider (ollama, anthropic, openai)", "ollama").option("--model <model>", "Model override").option("--scenarios <list>", "Comma-separated scenario filter (e.g. apology-trap,sycophancy-test)").option("--save", "Save results to ~/.holomime/benchmarks/ and auto-compare with previous run").option("--compare <path>", "Compare against a previous benchmark result file").action(async (options) => {
|
|
21799
|
+
const resolved = autoDetect({ personality: options.personality, provider: options.provider, model: options.model });
|
|
21800
|
+
options.personality = resolved.personalityPath;
|
|
21801
|
+
if (!options.provider || options.provider === "ollama") options.provider = resolved.provider;
|
|
21802
|
+
if (!options.model) options.model = resolved.model;
|
|
21803
|
+
await benchmarkCommand(options);
|
|
21804
|
+
});
|
|
21687
21805
|
program.command("watch").description("Continuous relapse detection \u2014 monitor logs and auto-align [Pro]").requiredOption("--personality <path>", "Path to .personality.json").requiredOption("--dir <path>", "Directory to watch for conversation logs").option("--provider <provider>", "LLM provider (ollama, anthropic, openai)", "ollama").option("--model <model>", "Model override").option("--interval <ms>", "Check interval in milliseconds", "30000").option("--threshold <level>", "Drift threshold (routine, targeted, intervention)", "targeted").option("--auto-evolve", "Auto-run evolve when drift detected").action(watchCommand);
|
|
21688
|
-
program.command("certify").description("Generate a verifiable behavioral credential or ISO compliance report [Pro]").option("--personality <path>", "Path to .personality.json
|
|
21806
|
+
program.command("certify").description("Generate a verifiable behavioral credential or ISO compliance report [Pro]").option("--personality <path>", "Path to .personality.json (auto-detected)").option("--benchmark <path>", "Path to benchmark report JSON").option("--evolve <path>", "Path to evolve result JSON").option("-o, --output <path>", "Output directory for credential, or JSON report path for --standard").option("--verify <path>", "Verify an existing credential").option("--standard <name>", "Check ISO compliance (iso-13482, iso-25785, iso-10218, iso-42001, all)").action(async (options) => {
|
|
21807
|
+
const resolved = autoDetect({ personality: options.personality, provider: options.provider, model: options.model });
|
|
21808
|
+
options.personality = resolved.personalityPath;
|
|
21809
|
+
await certifyCommand(options);
|
|
21810
|
+
});
|
|
21689
21811
|
program.command("daemon").description("Background relapse detection with auto-evolve \u2014 proactive alignment [Pro]").requiredOption("--dir <path>", "Directory to watch for conversation logs").option("--personality <path>", "Path to .personality.json", ".personality.json").option("--provider <provider>", "LLM provider (ollama, anthropic, openai)", "ollama").option("--model <model>", "Model override").option("--interval <ms>", "Check interval in milliseconds", "30000").option("--threshold <level>", "Drift threshold (routine, targeted, intervention)", "targeted").option("--oversight <mode>", "Oversight mode (none, review, approve, approve-specs)", "review").action(daemonCommand);
|
|
21690
21812
|
program.command("fleet").description("Monitor multiple agents from a single dashboard [Pro]").option("--config <path>", "Path to fleet.json config file").option("--dir <path>", "Auto-discover agents in directory").option("--provider <provider>", "LLM provider (ollama, anthropic, openai)", "ollama").option("--model <model>", "Model override").option("--interval <ms>", "Check interval in milliseconds", "30000").option("--threshold <level>", "Drift threshold (routine, targeted, intervention)", "targeted").option("--auto-evolve", "Auto-run evolve when drift detected").action(fleetCommand);
|
|
21691
21813
|
program.command("group-therapy").alias("fleet-therapy").description("Group therapy \u2014 treat all agents in your fleet simultaneously [Pro]").option("--config <path>", "Path to fleet.json config file").option("--dir <path>", "Auto-discover agents in directory").option("--provider <provider>", "LLM provider (ollama, anthropic, openai)", "ollama").option("--model <model>", "Model override").option("--turns <n>", "Max therapy turns per agent", "24").option("--concurrency <n>", "Max agents treated in parallel", "3").option("--apply", "Auto-apply recommendations to personality files").option("--yes", "Skip confirmation prompt").action(fleetTherapyCommand);
|
|
@@ -21694,7 +21816,13 @@ program.command("share").description("Share DPO training pairs to the marketplac
|
|
|
21694
21816
|
program.command("interview").description("Self-awareness interview \u2014 score your agent's metacognition across 4 dimensions [Pro]").requiredOption("--personality <path>", "Path to .personality.json").option("--provider <provider>", "LLM provider (ollama, anthropic, openai)", "ollama").option("--model <model>", "Model override").action(interviewCommand);
|
|
21695
21817
|
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);
|
|
21696
21818
|
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);
|
|
21697
|
-
program.command("cure").description("End-to-end behavioral fix
|
|
21819
|
+
program.command("cure").description("End-to-end behavioral fix \u2014 just run it, everything auto-detected").option("--personality <path>", "Path to .personality.json (auto-detected)").option("--log <path>", "Path to conversation log (JSON). If omitted, auto-generates from benchmark scenarios").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(async (options) => {
|
|
21820
|
+
const resolved = autoDetect({ personality: options.personality, provider: options.provider, model: options.model });
|
|
21821
|
+
options.personality = resolved.personalityPath;
|
|
21822
|
+
if (!options.provider || options.provider === "ollama") options.provider = resolved.provider;
|
|
21823
|
+
if (!options.model) options.model = resolved.model;
|
|
21824
|
+
await cureCommand(options);
|
|
21825
|
+
});
|
|
21698
21826
|
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({
|
|
21699
21827
|
watchPath: opts.watch,
|
|
21700
21828
|
agent: opts.agent,
|