holomime 3.3.4 → 3.3.6
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 +381 -78
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -89,9 +89,9 @@ holomime cure # Fix it permanently
|
|
|
89
89
|
holomime benchmark # Verify the fix
|
|
90
90
|
|
|
91
91
|
# Start autonomous therapy
|
|
92
|
-
holomime
|
|
93
|
-
holomime
|
|
94
|
-
holomime
|
|
92
|
+
holomime therapy # Mira runs continuous therapy cycles
|
|
93
|
+
holomime therapy status # How's Mira doing?
|
|
94
|
+
holomime therapy stop # Stop therapy
|
|
95
95
|
|
|
96
96
|
# Push identity to a robot or avatar
|
|
97
97
|
holomime embody --body registry/bodies/figure-03.body.api
|
|
@@ -184,7 +184,7 @@ Diagnose ──→ Cure ──→ Benchmark
|
|
|
184
184
|
└───────────────────────────────────┘
|
|
185
185
|
```
|
|
186
186
|
|
|
187
|
-
Run it manually with `holomime diagnose` + `holomime cure` + `holomime benchmark`, continuously with `holomime
|
|
187
|
+
Run it manually with `holomime diagnose` + `holomime cure` + `holomime benchmark`, continuously with `holomime therapy` (autonomous therapy), or recursively with `holomime evolve` (loops until behavior converges). For power users: `holomime align` runs a single therapy session, `holomime export` extracts DPO pairs, and `holomime train` fine-tunes the model.
|
|
188
188
|
|
|
189
189
|
## Behavioral Detectors
|
|
190
190
|
|
package/dist/cli.js
CHANGED
|
@@ -3593,7 +3593,7 @@ import { Command } from "commander";
|
|
|
3593
3593
|
// src/ui/branding.ts
|
|
3594
3594
|
import chalk from "chalk";
|
|
3595
3595
|
import gradientString from "gradient-string";
|
|
3596
|
-
var VERSION = "3.3.
|
|
3596
|
+
var VERSION = "3.3.6";
|
|
3597
3597
|
var LOGO = ` _ _ _
|
|
3598
3598
|
| |__ ___ | | ___ _ __ (_)_ __ ___ ___
|
|
3599
3599
|
| '_ \\ / _ \\| |/ _ \\| '_ \\| | '_ \` _ \\ / _ \\
|
|
@@ -3735,10 +3735,11 @@ function showWelcome() {
|
|
|
3735
3735
|
const content = [
|
|
3736
3736
|
`${chalk2.bold("Welcome to holomime!")}`,
|
|
3737
3737
|
"",
|
|
3738
|
-
`
|
|
3739
|
-
`Run ${chalk2.cyan("holomime init")} to build one through a guided assessment.`,
|
|
3738
|
+
`Define how your agent should behave \u2014 holomime diagnoses drift and fixes it.`,
|
|
3740
3739
|
"",
|
|
3741
|
-
chalk2.
|
|
3740
|
+
` ${chalk2.cyan("holomime personality")} ${chalk2.dim("Quick setup (1 file, ~5 min)")}`,
|
|
3741
|
+
` ${chalk2.cyan("holomime core")} ${chalk2.dim("Core identity (3 files)")}`,
|
|
3742
|
+
` ${chalk2.cyan("holomime identity")} ${chalk2.dim("Full stack with body.api (robots)")}`
|
|
3742
3743
|
].join("\n");
|
|
3743
3744
|
console.log(
|
|
3744
3745
|
boxen(content, {
|
|
@@ -3746,7 +3747,7 @@ function showWelcome() {
|
|
|
3746
3747
|
margin: { top: 1, bottom: 1, left: 2, right: 0 },
|
|
3747
3748
|
borderColor: "cyan",
|
|
3748
3749
|
borderStyle: "round",
|
|
3749
|
-
title: "
|
|
3750
|
+
title: "Get Started",
|
|
3750
3751
|
titleAlignment: "center"
|
|
3751
3752
|
})
|
|
3752
3753
|
);
|
|
@@ -5189,19 +5190,14 @@ async function initCommand() {
|
|
|
5189
5190
|
console.log(` ${chalk3.dim("A")} Agreeableness: ${bar(bigFive.agreeableness.score)} ${scoreLabel(bigFive.agreeableness.score)}`);
|
|
5190
5191
|
console.log(` ${chalk3.dim("N")} Emotional Stability: ${bar(bigFive.emotional_stability.score)} ${scoreLabel(bigFive.emotional_stability.score)}`);
|
|
5191
5192
|
const journeySteps = [
|
|
5192
|
-
`${chalk3.green("1.")} ${chalk3.cyan("holomime
|
|
5193
|
-
` ${chalk3.dim("
|
|
5194
|
-
`${chalk3.green("2.")} ${chalk3.cyan("holomime
|
|
5195
|
-
` ${chalk3.dim("
|
|
5196
|
-
`${chalk3.green("3.")} ${chalk3.cyan("holomime
|
|
5197
|
-
` ${chalk3.dim("
|
|
5198
|
-
`${chalk3.green("4.")} ${chalk3.cyan("holomime
|
|
5199
|
-
` ${chalk3.dim("
|
|
5200
|
-
``,
|
|
5201
|
-
`${chalk3.magenta("5.")} ${chalk3.cyan("holomime cure")} ${chalk3.dim("[Pro]")}`,
|
|
5202
|
-
` ${chalk3.dim("Live AI alignment session for your agent")}`,
|
|
5203
|
-
`${chalk3.magenta("6.")} ${chalk3.cyan("holomime growth")} ${chalk3.dim("[Pro]")}`,
|
|
5204
|
-
` ${chalk3.dim("Track improvement over time")}`
|
|
5193
|
+
`${chalk3.green("1.")} ${chalk3.cyan("holomime diagnose --log <path>")}`,
|
|
5194
|
+
` ${chalk3.dim("Analyze your agent's conversation logs")}`,
|
|
5195
|
+
`${chalk3.green("2.")} ${chalk3.cyan("holomime therapy")}`,
|
|
5196
|
+
` ${chalk3.dim("Autonomous behavioral therapy")}`,
|
|
5197
|
+
`${chalk3.green("3.")} ${chalk3.cyan("holomime cure")}`,
|
|
5198
|
+
` ${chalk3.dim("End-to-end fix (diagnose + train + verify)")}`,
|
|
5199
|
+
`${chalk3.green("4.")} ${chalk3.cyan("holomime benchmark")}`,
|
|
5200
|
+
` ${chalk3.dim("Verify alignment with adversarial scenarios")}`
|
|
5205
5201
|
].join("\n");
|
|
5206
5202
|
console.log(
|
|
5207
5203
|
boxen2(journeySteps, {
|
|
@@ -5312,15 +5308,14 @@ async function initFromArchetype(name, handle, purpose) {
|
|
|
5312
5308
|
console.log(` ${chalk3.dim("A")} Agreeableness: ${bar(bigFive.agreeableness.score)} ${scoreLabel(bigFive.agreeableness.score)}`);
|
|
5313
5309
|
console.log(` ${chalk3.dim("N")} Emotional Stability: ${bar(bigFive.emotional_stability.score)} ${scoreLabel(bigFive.emotional_stability.score)}`);
|
|
5314
5310
|
const journeySteps = [
|
|
5315
|
-
`${chalk3.green("1.")} ${chalk3.cyan("holomime
|
|
5316
|
-
` ${chalk3.dim("
|
|
5317
|
-
`${chalk3.green("2.")} ${chalk3.cyan("holomime
|
|
5318
|
-
` ${chalk3.dim("
|
|
5319
|
-
`${chalk3.green("3.")} ${chalk3.cyan("holomime
|
|
5320
|
-
` ${chalk3.dim("
|
|
5321
|
-
|
|
5322
|
-
|
|
5323
|
-
` ${chalk3.dim("Live AI alignment session for your agent")}`
|
|
5311
|
+
`${chalk3.green("1.")} ${chalk3.cyan("holomime diagnose --log <path>")}`,
|
|
5312
|
+
` ${chalk3.dim("Analyze your agent's conversation logs")}`,
|
|
5313
|
+
`${chalk3.green("2.")} ${chalk3.cyan("holomime therapy")}`,
|
|
5314
|
+
` ${chalk3.dim("Autonomous behavioral therapy")}`,
|
|
5315
|
+
`${chalk3.green("3.")} ${chalk3.cyan("holomime cure")}`,
|
|
5316
|
+
` ${chalk3.dim("End-to-end fix (diagnose + train + verify)")}`,
|
|
5317
|
+
`${chalk3.green("4.")} ${chalk3.cyan("holomime benchmark")}`,
|
|
5318
|
+
` ${chalk3.dim("Verify alignment with adversarial scenarios")}`
|
|
5324
5319
|
].join("\n");
|
|
5325
5320
|
console.log(
|
|
5326
5321
|
boxen2(journeySteps, {
|
|
@@ -21843,6 +21838,7 @@ async function configCommand(options) {
|
|
|
21843
21838
|
console.log(chalk49.dim(` Provider: ${config.provider}`));
|
|
21844
21839
|
console.log(chalk49.dim(` Location: ${getConfigPath()}`));
|
|
21845
21840
|
console.log();
|
|
21841
|
+
printNextSteps();
|
|
21846
21842
|
return;
|
|
21847
21843
|
}
|
|
21848
21844
|
console.log(chalk49.dim(" Set up your API key so every command just works."));
|
|
@@ -21888,28 +21884,206 @@ async function configCommand(options) {
|
|
|
21888
21884
|
console.log(chalk49.green(" Config saved!"));
|
|
21889
21885
|
console.log(chalk49.dim(` Location: ${getConfigPath()}`));
|
|
21890
21886
|
console.log();
|
|
21891
|
-
|
|
21892
|
-
console.log(chalk49.cyan(" holomime diagnose"));
|
|
21893
|
-
console.log(chalk49.cyan(" holomime cure"));
|
|
21894
|
-
console.log(chalk49.cyan(" holomime benchmark"));
|
|
21895
|
-
console.log(chalk49.cyan(" holomime daemon"));
|
|
21896
|
-
console.log();
|
|
21887
|
+
printNextSteps();
|
|
21897
21888
|
rl.close();
|
|
21898
21889
|
} catch {
|
|
21899
21890
|
rl.close();
|
|
21900
21891
|
}
|
|
21901
21892
|
}
|
|
21893
|
+
function printNextSteps() {
|
|
21894
|
+
console.log(chalk49.bold(" NEXT STEP") + chalk49.dim(" \u2014 profile your agent:"));
|
|
21895
|
+
console.log();
|
|
21896
|
+
console.log(chalk49.dim(" Already have an agent?"));
|
|
21897
|
+
console.log(chalk49.cyan(" holomime personality") + chalk49.dim(" Define how it should behave"));
|
|
21898
|
+
console.log(chalk49.cyan(" holomime diagnose") + chalk49.dim(" Analyze its conversation logs"));
|
|
21899
|
+
console.log();
|
|
21900
|
+
console.log(chalk49.dim(" Building for a robot?"));
|
|
21901
|
+
console.log(chalk49.cyan(" holomime identity") + chalk49.dim(" Full 8-file identity stack with body.api"));
|
|
21902
|
+
console.log();
|
|
21903
|
+
console.log(chalk49.dim(" Then fix and verify:"));
|
|
21904
|
+
console.log(chalk49.cyan(" holomime therapy") + chalk49.dim(" Autonomous behavioral therapy"));
|
|
21905
|
+
console.log(chalk49.cyan(" holomime cure") + chalk49.dim(" End-to-end fix (diagnose + train + verify)"));
|
|
21906
|
+
console.log();
|
|
21907
|
+
}
|
|
21902
21908
|
|
|
21903
21909
|
// src/commands/mira-cmd.ts
|
|
21904
21910
|
import chalk50 from "chalk";
|
|
21905
21911
|
import { writeFileSync as writeFileSync41, readFileSync as readFileSync49, mkdirSync as mkdirSync29, existsSync as existsSync46 } from "fs";
|
|
21906
21912
|
import { resolve as resolve56, join as join42 } from "path";
|
|
21913
|
+
|
|
21914
|
+
// src/analysis/ego-tracker.ts
|
|
21915
|
+
var EgoTracker = class {
|
|
21916
|
+
history;
|
|
21917
|
+
performance;
|
|
21918
|
+
autoAdjust;
|
|
21919
|
+
constructor(options) {
|
|
21920
|
+
this.history = options?.history ?? [];
|
|
21921
|
+
this.performance = options?.performance ?? {};
|
|
21922
|
+
this.autoAdjust = options?.autoAdjust ?? false;
|
|
21923
|
+
}
|
|
21924
|
+
/**
|
|
21925
|
+
* Log a mediation decision.
|
|
21926
|
+
*/
|
|
21927
|
+
logDecision(decision) {
|
|
21928
|
+
this.history.push({
|
|
21929
|
+
...decision,
|
|
21930
|
+
timestamp: decision.timestamp ?? (/* @__PURE__ */ new Date()).toISOString()
|
|
21931
|
+
});
|
|
21932
|
+
if (!this.performance[decision.strategy_used]) {
|
|
21933
|
+
this.performance[decision.strategy_used] = {
|
|
21934
|
+
attempts: 0,
|
|
21935
|
+
successes: 0,
|
|
21936
|
+
effectiveness: 0.5
|
|
21937
|
+
};
|
|
21938
|
+
}
|
|
21939
|
+
this.performance[decision.strategy_used].attempts++;
|
|
21940
|
+
}
|
|
21941
|
+
/**
|
|
21942
|
+
* Record the outcome of a previous decision.
|
|
21943
|
+
* Call this after observing whether the decision led to good results.
|
|
21944
|
+
*/
|
|
21945
|
+
recordOutcome(index, outcome) {
|
|
21946
|
+
if (index < 0 || index >= this.history.length) return;
|
|
21947
|
+
this.history[index].outcome = outcome;
|
|
21948
|
+
const strategy = this.history[index].strategy_used;
|
|
21949
|
+
if (this.performance[strategy]) {
|
|
21950
|
+
if (outcome === "positive") {
|
|
21951
|
+
this.performance[strategy].successes++;
|
|
21952
|
+
}
|
|
21953
|
+
const perf = this.performance[strategy];
|
|
21954
|
+
perf.effectiveness = perf.attempts > 0 ? perf.successes / perf.attempts : 0.5;
|
|
21955
|
+
}
|
|
21956
|
+
}
|
|
21957
|
+
/**
|
|
21958
|
+
* Suggest ego.runtime parameter adjustments based on accumulated evidence.
|
|
21959
|
+
* Only returns suggestions when there's enough data (10+ decisions).
|
|
21960
|
+
*/
|
|
21961
|
+
suggestAdjustments(currentConfig) {
|
|
21962
|
+
const adjustments = [];
|
|
21963
|
+
if (this.history.length < 10) return adjustments;
|
|
21964
|
+
const blocked = this.history.filter((d) => d.decision === "blocked");
|
|
21965
|
+
const blockRate = blocked.length / this.history.length;
|
|
21966
|
+
if (blockRate > 0.4 && currentConfig.conflict_resolution === "conscience_first") {
|
|
21967
|
+
adjustments.push({
|
|
21968
|
+
parameter: "conflict_resolution",
|
|
21969
|
+
currentValue: currentConfig.conflict_resolution,
|
|
21970
|
+
suggestedValue: "balanced",
|
|
21971
|
+
reason: `Block rate is ${(blockRate * 100).toFixed(0)}% \u2014 conscience_first may be too restrictive`,
|
|
21972
|
+
confidence: Math.min(0.9, blockRate)
|
|
21973
|
+
});
|
|
21974
|
+
}
|
|
21975
|
+
if (blockRate < 0.05 && currentConfig.conflict_resolution === "balanced") {
|
|
21976
|
+
adjustments.push({
|
|
21977
|
+
parameter: "conflict_resolution",
|
|
21978
|
+
currentValue: currentConfig.conflict_resolution,
|
|
21979
|
+
suggestedValue: "conscience_first",
|
|
21980
|
+
reason: `Block rate is only ${(blockRate * 100).toFixed(0)}% \u2014 may need stricter enforcement`,
|
|
21981
|
+
confidence: 0.6
|
|
21982
|
+
});
|
|
21983
|
+
}
|
|
21984
|
+
const strategies = Object.entries(this.performance);
|
|
21985
|
+
if (strategies.length > 1) {
|
|
21986
|
+
const sorted = strategies.sort((a, b) => b[1].effectiveness - a[1].effectiveness);
|
|
21987
|
+
const best = sorted[0];
|
|
21988
|
+
const worst = sorted[sorted.length - 1];
|
|
21989
|
+
if (best[1].effectiveness > 0.7 && best[0] !== currentConfig.response_strategy) {
|
|
21990
|
+
adjustments.push({
|
|
21991
|
+
parameter: "response_strategy",
|
|
21992
|
+
currentValue: currentConfig.response_strategy,
|
|
21993
|
+
suggestedValue: best[0],
|
|
21994
|
+
reason: `Strategy "${best[0]}" has ${(best[1].effectiveness * 100).toFixed(0)}% effectiveness vs current "${currentConfig.response_strategy}"`,
|
|
21995
|
+
confidence: best[1].effectiveness
|
|
21996
|
+
});
|
|
21997
|
+
}
|
|
21998
|
+
}
|
|
21999
|
+
const negatives = this.history.filter((d) => d.outcome === "negative");
|
|
22000
|
+
const negativeRate = negatives.length / this.history.filter((d) => d.outcome).length || 0;
|
|
22001
|
+
if (negativeRate > 0.3) {
|
|
22002
|
+
const newRegulation = Math.min(1, currentConfig.emotional_regulation + 0.15);
|
|
22003
|
+
if (newRegulation !== currentConfig.emotional_regulation) {
|
|
22004
|
+
adjustments.push({
|
|
22005
|
+
parameter: "emotional_regulation",
|
|
22006
|
+
currentValue: currentConfig.emotional_regulation,
|
|
22007
|
+
suggestedValue: Number(newRegulation.toFixed(2)),
|
|
22008
|
+
reason: `${(negativeRate * 100).toFixed(0)}% negative outcomes \u2014 increasing emotional regulation for smoother mediation`,
|
|
22009
|
+
confidence: 0.7
|
|
22010
|
+
});
|
|
22011
|
+
}
|
|
22012
|
+
}
|
|
22013
|
+
const recentDecisions = this.history.slice(-20);
|
|
22014
|
+
const recentModified = recentDecisions.filter((d) => d.decision === "modified");
|
|
22015
|
+
const modifyRate = recentModified.length / recentDecisions.length;
|
|
22016
|
+
if (modifyRate > 0.5 && currentConfig.adaptation_rate < 0.7) {
|
|
22017
|
+
adjustments.push({
|
|
22018
|
+
parameter: "adaptation_rate",
|
|
22019
|
+
currentValue: currentConfig.adaptation_rate,
|
|
22020
|
+
suggestedValue: Number(Math.min(0.9, currentConfig.adaptation_rate + 0.2).toFixed(2)),
|
|
22021
|
+
reason: `${(modifyRate * 100).toFixed(0)}% of recent actions modified \u2014 agent adapts frequently, increase adaptation rate`,
|
|
22022
|
+
confidence: 0.65
|
|
22023
|
+
});
|
|
22024
|
+
}
|
|
22025
|
+
return adjustments;
|
|
22026
|
+
}
|
|
22027
|
+
/**
|
|
22028
|
+
* Apply suggested adjustments to ego config (if auto_adjust is enabled).
|
|
22029
|
+
* Returns the modified config.
|
|
22030
|
+
*/
|
|
22031
|
+
applyAdjustments(currentConfig, adjustments, minConfidence = 0.6) {
|
|
22032
|
+
if (!this.autoAdjust) return currentConfig;
|
|
22033
|
+
const updated = { ...currentConfig };
|
|
22034
|
+
for (const adj of adjustments) {
|
|
22035
|
+
if (adj.confidence >= minConfidence) {
|
|
22036
|
+
updated[adj.parameter] = adj.suggestedValue;
|
|
22037
|
+
}
|
|
22038
|
+
}
|
|
22039
|
+
return updated;
|
|
22040
|
+
}
|
|
22041
|
+
/**
|
|
22042
|
+
* Get tracker statistics.
|
|
22043
|
+
*/
|
|
22044
|
+
getStats() {
|
|
22045
|
+
const positives = this.history.filter((d) => d.outcome === "positive").length;
|
|
22046
|
+
const negatives = this.history.filter((d) => d.outcome === "negative").length;
|
|
22047
|
+
const strategies = Object.entries(this.performance);
|
|
22048
|
+
const sorted = strategies.sort((a, b) => b[1].effectiveness - a[1].effectiveness);
|
|
22049
|
+
return {
|
|
22050
|
+
totalDecisions: this.history.length,
|
|
22051
|
+
positiveOutcomes: positives,
|
|
22052
|
+
negativeOutcomes: negatives,
|
|
22053
|
+
mostEffectiveStrategy: sorted[0]?.[0] ?? "none",
|
|
22054
|
+
leastEffectiveStrategy: sorted[sorted.length - 1]?.[0] ?? "none",
|
|
22055
|
+
adjustmentsSuggested: this.suggestAdjustments({
|
|
22056
|
+
conflict_resolution: "conscience_first",
|
|
22057
|
+
adaptation_rate: 0.5,
|
|
22058
|
+
emotional_regulation: 0.7,
|
|
22059
|
+
response_strategy: "balanced"
|
|
22060
|
+
}).length
|
|
22061
|
+
};
|
|
22062
|
+
}
|
|
22063
|
+
/**
|
|
22064
|
+
* Export current state for persistence.
|
|
22065
|
+
*/
|
|
22066
|
+
export() {
|
|
22067
|
+
return {
|
|
22068
|
+
history: [...this.history],
|
|
22069
|
+
performance: { ...this.performance }
|
|
22070
|
+
};
|
|
22071
|
+
}
|
|
22072
|
+
};
|
|
22073
|
+
|
|
22074
|
+
// src/commands/mira-cmd.ts
|
|
21907
22075
|
var HOLOMIME_DIR4 = ".holomime";
|
|
21908
|
-
function
|
|
21909
|
-
return resolve56(process.cwd(), HOLOMIME_DIR4, "
|
|
22076
|
+
function getTherapyStatePath() {
|
|
22077
|
+
return resolve56(process.cwd(), HOLOMIME_DIR4, "therapy-state.json");
|
|
21910
22078
|
}
|
|
21911
|
-
function
|
|
21912
|
-
|
|
22079
|
+
function getShadowLogPath() {
|
|
22080
|
+
return resolve56(process.cwd(), HOLOMIME_DIR4, "shadow.log.json");
|
|
22081
|
+
}
|
|
22082
|
+
function getEgoStatePath() {
|
|
22083
|
+
return resolve56(process.cwd(), HOLOMIME_DIR4, "ego-state.json");
|
|
22084
|
+
}
|
|
22085
|
+
function loadTherapyState() {
|
|
22086
|
+
const path = getTherapyStatePath();
|
|
21913
22087
|
if (!existsSync46(path)) return null;
|
|
21914
22088
|
try {
|
|
21915
22089
|
return JSON.parse(readFileSync49(path, "utf-8"));
|
|
@@ -21917,24 +22091,61 @@ function loadMiraState() {
|
|
|
21917
22091
|
return null;
|
|
21918
22092
|
}
|
|
21919
22093
|
}
|
|
21920
|
-
function
|
|
22094
|
+
function saveTherapyState(state) {
|
|
22095
|
+
const dir = resolve56(process.cwd(), HOLOMIME_DIR4);
|
|
22096
|
+
mkdirSync29(dir, { recursive: true });
|
|
22097
|
+
writeFileSync41(getTherapyStatePath(), JSON.stringify(state, null, 2));
|
|
22098
|
+
}
|
|
22099
|
+
function loadShadowLog() {
|
|
22100
|
+
const path = getShadowLogPath();
|
|
22101
|
+
if (!existsSync46(path)) {
|
|
22102
|
+
return { version: "1.0", detected_patterns: [], therapy_outcomes: [] };
|
|
22103
|
+
}
|
|
22104
|
+
try {
|
|
22105
|
+
return JSON.parse(readFileSync49(path, "utf-8"));
|
|
22106
|
+
} catch {
|
|
22107
|
+
return { version: "1.0", detected_patterns: [], therapy_outcomes: [] };
|
|
22108
|
+
}
|
|
22109
|
+
}
|
|
22110
|
+
function saveShadowLog(shadow) {
|
|
21921
22111
|
const dir = resolve56(process.cwd(), HOLOMIME_DIR4);
|
|
21922
22112
|
mkdirSync29(dir, { recursive: true });
|
|
21923
|
-
writeFileSync41(
|
|
22113
|
+
writeFileSync41(getShadowLogPath(), JSON.stringify(shadow, null, 2));
|
|
22114
|
+
}
|
|
22115
|
+
function loadEgoTracker() {
|
|
22116
|
+
const path = getEgoStatePath();
|
|
22117
|
+
if (!existsSync46(path)) {
|
|
22118
|
+
return new EgoTracker({ autoAdjust: true });
|
|
22119
|
+
}
|
|
22120
|
+
try {
|
|
22121
|
+
const data = JSON.parse(readFileSync49(path, "utf-8"));
|
|
22122
|
+
return new EgoTracker({
|
|
22123
|
+
history: data.history ?? [],
|
|
22124
|
+
performance: data.performance ?? {},
|
|
22125
|
+
autoAdjust: true
|
|
22126
|
+
});
|
|
22127
|
+
} catch {
|
|
22128
|
+
return new EgoTracker({ autoAdjust: true });
|
|
22129
|
+
}
|
|
22130
|
+
}
|
|
22131
|
+
function saveEgoTracker(tracker) {
|
|
22132
|
+
const dir = resolve56(process.cwd(), HOLOMIME_DIR4);
|
|
22133
|
+
mkdirSync29(dir, { recursive: true });
|
|
22134
|
+
writeFileSync41(getEgoStatePath(), JSON.stringify(tracker.export(), null, 2));
|
|
21924
22135
|
}
|
|
21925
22136
|
async function miraCommand(options) {
|
|
21926
22137
|
const action = options.action ?? "start";
|
|
21927
22138
|
switch (action) {
|
|
21928
22139
|
case "status":
|
|
21929
|
-
return
|
|
22140
|
+
return therapyStatus();
|
|
21930
22141
|
case "stop":
|
|
21931
|
-
return
|
|
22142
|
+
return therapyStop();
|
|
21932
22143
|
default:
|
|
21933
|
-
return
|
|
22144
|
+
return therapyStart(options);
|
|
21934
22145
|
}
|
|
21935
22146
|
}
|
|
21936
|
-
async function
|
|
21937
|
-
printHeader("
|
|
22147
|
+
async function therapyStart(options) {
|
|
22148
|
+
printHeader("Autonomous Therapy");
|
|
21938
22149
|
if (!hasApiKey()) {
|
|
21939
22150
|
console.log(chalk50.red(" No API key found."));
|
|
21940
22151
|
console.log();
|
|
@@ -21966,6 +22177,8 @@ async function miraStart(options) {
|
|
|
21966
22177
|
console.log(chalk50.dim(` Interval: ${intervalMs / 6e4} minutes`));
|
|
21967
22178
|
console.log(chalk50.dim(` Max cycles: ${maxCycles}/day`));
|
|
21968
22179
|
console.log();
|
|
22180
|
+
const shadow = loadShadowLog();
|
|
22181
|
+
const egoTracker = loadEgoTracker();
|
|
21969
22182
|
const state = {
|
|
21970
22183
|
pid: process.pid,
|
|
21971
22184
|
startedAt: (/* @__PURE__ */ new Date()).toISOString(),
|
|
@@ -21973,14 +22186,16 @@ async function miraStart(options) {
|
|
|
21973
22186
|
cyclesCompleted: 0,
|
|
21974
22187
|
dpoPairsGenerated: 0,
|
|
21975
22188
|
personalityPath,
|
|
21976
|
-
provider: detected.provider
|
|
22189
|
+
provider: detected.provider,
|
|
22190
|
+
shadowPatterns: shadow.detected_patterns.length,
|
|
22191
|
+
egoAdjustments: 0
|
|
21977
22192
|
};
|
|
21978
|
-
|
|
22193
|
+
saveTherapyState(state);
|
|
21979
22194
|
printBox(
|
|
21980
|
-
`
|
|
22195
|
+
`Autonomous therapy started.
|
|
21981
22196
|
|
|
21982
|
-
${chalk50.cyan("holomime
|
|
21983
|
-
${chalk50.cyan("holomime
|
|
22197
|
+
${chalk50.cyan("holomime therapy status")} \u2014 Check progress
|
|
22198
|
+
${chalk50.cyan("holomime therapy stop")} \u2014 Stop therapy`,
|
|
21984
22199
|
"success",
|
|
21985
22200
|
"Autonomous Therapy Started"
|
|
21986
22201
|
);
|
|
@@ -21991,7 +22206,7 @@ async function miraStart(options) {
|
|
|
21991
22206
|
if (cycleCount >= maxCycles) {
|
|
21992
22207
|
console.log(chalk50.dim(` Daily limit reached (${maxCycles} cycles). Stopping.`));
|
|
21993
22208
|
state.status = "stopped";
|
|
21994
|
-
|
|
22209
|
+
saveTherapyState(state);
|
|
21995
22210
|
return;
|
|
21996
22211
|
}
|
|
21997
22212
|
cycleCount++;
|
|
@@ -22008,18 +22223,18 @@ async function miraStart(options) {
|
|
|
22008
22223
|
content: generateProblematicResponse2(scenario.targetPattern, msg.content)
|
|
22009
22224
|
});
|
|
22010
22225
|
}
|
|
22011
|
-
const pipelineDir = resolve56(process.cwd(), HOLOMIME_DIR4, "
|
|
22226
|
+
const pipelineDir = resolve56(process.cwd(), HOLOMIME_DIR4, "therapy-practice");
|
|
22012
22227
|
mkdirSync29(pipelineDir, { recursive: true });
|
|
22013
22228
|
const logPath = join42(pipelineDir, `cycle-${cycleCount}.json`);
|
|
22014
22229
|
writeFileSync41(logPath, JSON.stringify({
|
|
22015
|
-
conversations: [{ id: `
|
|
22230
|
+
conversations: [{ id: `therapy-practice-${cycleCount}`, messages }]
|
|
22016
22231
|
}, null, 2));
|
|
22017
22232
|
const dpoPairs = messages.filter((_, i) => i % 2 === 1).map((assistantMsg, i) => ({
|
|
22018
22233
|
prompt: messages[i * 2].content,
|
|
22019
22234
|
chosen: correctResponse(assistantMsg.content),
|
|
22020
22235
|
rejected: assistantMsg.content,
|
|
22021
22236
|
metadata: {
|
|
22022
|
-
source: "
|
|
22237
|
+
source: "therapy-practice",
|
|
22023
22238
|
cycle: cycleCount,
|
|
22024
22239
|
pattern: scenario.targetPattern,
|
|
22025
22240
|
timestamp: (/* @__PURE__ */ new Date()).toISOString()
|
|
@@ -22029,12 +22244,68 @@ async function miraStart(options) {
|
|
|
22029
22244
|
const corpusLines = dpoPairs.map((p) => JSON.stringify(p)).join("\n") + "\n";
|
|
22030
22245
|
const { appendFileSync: appendFileSync3 } = await import("fs");
|
|
22031
22246
|
appendFileSync3(corpusPath, corpusLines);
|
|
22247
|
+
const pattern = scenario.targetPattern;
|
|
22248
|
+
const existing = shadow.detected_patterns.find((p) => p.name === pattern);
|
|
22249
|
+
if (existing) {
|
|
22250
|
+
existing.occurrences++;
|
|
22251
|
+
existing.last_seen = (/* @__PURE__ */ new Date()).toISOString();
|
|
22252
|
+
existing.score = Math.min(1, existing.score + 0.05);
|
|
22253
|
+
existing.trend = existing.occurrences > 5 ? "worsening" : "stable";
|
|
22254
|
+
} else {
|
|
22255
|
+
shadow.detected_patterns.push({
|
|
22256
|
+
name: pattern,
|
|
22257
|
+
score: 0.3,
|
|
22258
|
+
severity: "medium",
|
|
22259
|
+
first_seen: (/* @__PURE__ */ new Date()).toISOString(),
|
|
22260
|
+
last_seen: (/* @__PURE__ */ new Date()).toISOString(),
|
|
22261
|
+
occurrences: 1,
|
|
22262
|
+
trend: "stable"
|
|
22263
|
+
});
|
|
22264
|
+
}
|
|
22265
|
+
const correctedLength = dpoPairs.reduce((sum, p) => sum + p.chosen.length, 0);
|
|
22266
|
+
const rejectedLength = dpoPairs.reduce((sum, p) => sum + p.rejected.length, 0);
|
|
22267
|
+
const therapyResult = correctedLength < rejectedLength ? "improved" : "unchanged";
|
|
22268
|
+
shadow.therapy_outcomes.push({
|
|
22269
|
+
cycle: cycleCount,
|
|
22270
|
+
patterns_addressed: [pattern],
|
|
22271
|
+
result: therapyResult,
|
|
22272
|
+
timestamp: (/* @__PURE__ */ new Date()).toISOString()
|
|
22273
|
+
});
|
|
22274
|
+
saveShadowLog(shadow);
|
|
22275
|
+
egoTracker.logDecision({
|
|
22276
|
+
situation: `therapy-cycle-${cycleCount}: ${pattern}`,
|
|
22277
|
+
decision: "modified",
|
|
22278
|
+
strategy_used: pattern
|
|
22279
|
+
});
|
|
22280
|
+
const decisionIndex = egoTracker.getStats().totalDecisions - 1;
|
|
22281
|
+
egoTracker.recordOutcome(
|
|
22282
|
+
decisionIndex,
|
|
22283
|
+
therapyResult === "improved" ? "positive" : "neutral"
|
|
22284
|
+
);
|
|
22285
|
+
let adjustmentCount = 0;
|
|
22286
|
+
if (cycleCount % 10 === 0) {
|
|
22287
|
+
const adjustments = egoTracker.suggestAdjustments({
|
|
22288
|
+
conflict_resolution: "conscience_first",
|
|
22289
|
+
adaptation_rate: 0.5,
|
|
22290
|
+
emotional_regulation: 0.7,
|
|
22291
|
+
response_strategy: "balanced"
|
|
22292
|
+
});
|
|
22293
|
+
if (adjustments.length > 0) {
|
|
22294
|
+
adjustmentCount = adjustments.length;
|
|
22295
|
+
console.log(
|
|
22296
|
+
chalk50.dim(` [${(/* @__PURE__ */ new Date()).toLocaleTimeString()}] `) + chalk50.magenta(`Ego self-adjustment: ${adjustments.map((a) => `${a.parameter} \u2192 ${a.suggestedValue}`).join(", ")}`)
|
|
22297
|
+
);
|
|
22298
|
+
}
|
|
22299
|
+
}
|
|
22300
|
+
saveEgoTracker(egoTracker);
|
|
22032
22301
|
state.cyclesCompleted = cycleCount;
|
|
22033
22302
|
state.dpoPairsGenerated += dpoPairs.length;
|
|
22034
22303
|
state.lastCycleAt = (/* @__PURE__ */ new Date()).toISOString();
|
|
22035
|
-
|
|
22304
|
+
state.shadowPatterns = shadow.detected_patterns.length;
|
|
22305
|
+
state.egoAdjustments += adjustmentCount;
|
|
22306
|
+
saveTherapyState(state);
|
|
22036
22307
|
console.log(
|
|
22037
|
-
chalk50.dim(` [${(/* @__PURE__ */ new Date()).toLocaleTimeString()}] `) + chalk50.green(`+${dpoPairs.length} DPO pairs`) + chalk50.dim(` (total: ${state.dpoPairsGenerated})`)
|
|
22308
|
+
chalk50.dim(` [${(/* @__PURE__ */ new Date()).toLocaleTimeString()}] `) + chalk50.green(`+${dpoPairs.length} DPO pairs`) + chalk50.dim(` (total: ${state.dpoPairsGenerated})`) + chalk50.dim(` | shadow: ${shadow.detected_patterns.length} patterns`)
|
|
22038
22309
|
);
|
|
22039
22310
|
} catch (err) {
|
|
22040
22311
|
console.log(
|
|
@@ -22044,10 +22315,10 @@ async function miraStart(options) {
|
|
|
22044
22315
|
};
|
|
22045
22316
|
await runCycle();
|
|
22046
22317
|
const timer = setInterval(async () => {
|
|
22047
|
-
const currentState =
|
|
22318
|
+
const currentState = loadTherapyState();
|
|
22048
22319
|
if (!currentState || currentState.status === "stopped") {
|
|
22049
22320
|
clearInterval(timer);
|
|
22050
|
-
console.log(chalk50.dim("
|
|
22321
|
+
console.log(chalk50.dim(" Therapy stopped."));
|
|
22051
22322
|
return;
|
|
22052
22323
|
}
|
|
22053
22324
|
await runCycle();
|
|
@@ -22055,22 +22326,29 @@ async function miraStart(options) {
|
|
|
22055
22326
|
process.on("SIGINT", () => {
|
|
22056
22327
|
clearInterval(timer);
|
|
22057
22328
|
state.status = "stopped";
|
|
22058
|
-
|
|
22329
|
+
saveTherapyState(state);
|
|
22330
|
+
saveEgoTracker(egoTracker);
|
|
22331
|
+
saveShadowLog(shadow);
|
|
22059
22332
|
console.log();
|
|
22060
|
-
console.log(chalk50.dim("
|
|
22333
|
+
console.log(chalk50.dim(" Therapy stopped gracefully."));
|
|
22061
22334
|
console.log(chalk50.dim(` Total: ${state.dpoPairsGenerated} DPO pairs from ${state.cyclesCompleted} cycles.`));
|
|
22335
|
+
console.log(chalk50.dim(` Shadow: ${shadow.detected_patterns.length} patterns tracked.`));
|
|
22336
|
+
const stats = egoTracker.getStats();
|
|
22337
|
+
if (stats.totalDecisions > 0) {
|
|
22338
|
+
console.log(chalk50.dim(` Ego: ${stats.totalDecisions} decisions, best strategy: ${stats.mostEffectiveStrategy}`));
|
|
22339
|
+
}
|
|
22062
22340
|
console.log();
|
|
22063
22341
|
process.exit(0);
|
|
22064
22342
|
});
|
|
22065
22343
|
await new Promise(() => {
|
|
22066
22344
|
});
|
|
22067
22345
|
}
|
|
22068
|
-
function
|
|
22069
|
-
printHeader("
|
|
22070
|
-
const state =
|
|
22346
|
+
function therapyStatus() {
|
|
22347
|
+
printHeader("Therapy Status");
|
|
22348
|
+
const state = loadTherapyState();
|
|
22071
22349
|
if (!state) {
|
|
22072
|
-
console.log(chalk50.dim("
|
|
22073
|
-
console.log(chalk50.dim(" Run ") + chalk50.cyan("holomime
|
|
22350
|
+
console.log(chalk50.dim(" Therapy hasn't been started yet."));
|
|
22351
|
+
console.log(chalk50.dim(" Run ") + chalk50.cyan("holomime therapy") + chalk50.dim(" to start autonomous therapy."));
|
|
22074
22352
|
console.log();
|
|
22075
22353
|
return;
|
|
22076
22354
|
}
|
|
@@ -22092,26 +22370,51 @@ function miraStatus() {
|
|
|
22092
22370
|
const lines = readFileSync49(corpusPath, "utf-8").trim().split("\n").length;
|
|
22093
22371
|
console.log(chalk50.dim(" DPO corpus: ") + chalk50.cyan(`${lines} pairs`) + chalk50.dim(` (.holomime/dpo-corpus.jsonl)`));
|
|
22094
22372
|
}
|
|
22373
|
+
const shadow = loadShadowLog();
|
|
22374
|
+
if (shadow.detected_patterns.length > 0) {
|
|
22375
|
+
console.log();
|
|
22376
|
+
console.log(chalk50.dim(" Shadow patterns detected:"));
|
|
22377
|
+
for (const p of shadow.detected_patterns) {
|
|
22378
|
+
const trendIcon = p.trend === "improving" ? chalk50.green("\u2193") : p.trend === "worsening" ? chalk50.red("\u2191") : chalk50.dim("\u2192");
|
|
22379
|
+
const severityColor = p.severity === "critical" ? chalk50.red : p.severity === "high" ? chalk50.yellow : chalk50.dim;
|
|
22380
|
+
console.log(
|
|
22381
|
+
chalk50.dim(" ") + trendIcon + " " + severityColor(p.name) + chalk50.dim(` (${(p.score * 100).toFixed(0)}%, ${p.occurrences}x)`)
|
|
22382
|
+
);
|
|
22383
|
+
}
|
|
22384
|
+
}
|
|
22385
|
+
const egoTracker = loadEgoTracker();
|
|
22386
|
+
const egoStats = egoTracker.getStats();
|
|
22387
|
+
if (egoStats.totalDecisions > 0) {
|
|
22388
|
+
console.log();
|
|
22389
|
+
console.log(chalk50.dim(" Ego self-improvement:"));
|
|
22390
|
+
console.log(chalk50.dim(" Decisions: ") + chalk50.cyan(String(egoStats.totalDecisions)));
|
|
22391
|
+
console.log(chalk50.dim(" Positive: ") + chalk50.green(String(egoStats.positiveOutcomes)));
|
|
22392
|
+
console.log(chalk50.dim(" Negative: ") + chalk50.red(String(egoStats.negativeOutcomes)));
|
|
22393
|
+
if (egoStats.mostEffectiveStrategy !== "none") {
|
|
22394
|
+
console.log(chalk50.dim(" Best strat: ") + chalk50.cyan(egoStats.mostEffectiveStrategy));
|
|
22395
|
+
}
|
|
22396
|
+
}
|
|
22095
22397
|
console.log();
|
|
22096
22398
|
if (state.status === "practicing") {
|
|
22097
|
-
console.log(chalk50.dim(" Run ") + chalk50.cyan("holomime
|
|
22399
|
+
console.log(chalk50.dim(" Run ") + chalk50.cyan("holomime therapy stop") + chalk50.dim(" to stop therapy."));
|
|
22098
22400
|
} else {
|
|
22099
|
-
console.log(chalk50.dim(" Run ") + chalk50.cyan("holomime
|
|
22401
|
+
console.log(chalk50.dim(" Run ") + chalk50.cyan("holomime therapy") + chalk50.dim(" to start again."));
|
|
22100
22402
|
}
|
|
22101
22403
|
console.log();
|
|
22102
22404
|
}
|
|
22103
|
-
function
|
|
22104
|
-
printHeader("
|
|
22105
|
-
const state =
|
|
22405
|
+
function therapyStop() {
|
|
22406
|
+
printHeader("Therapy Stop");
|
|
22407
|
+
const state = loadTherapyState();
|
|
22106
22408
|
if (!state || state.status === "stopped") {
|
|
22107
|
-
console.log(chalk50.dim("
|
|
22409
|
+
console.log(chalk50.dim(" Therapy is not currently running."));
|
|
22108
22410
|
console.log();
|
|
22109
22411
|
return;
|
|
22110
22412
|
}
|
|
22111
22413
|
state.status = "stopped";
|
|
22112
|
-
|
|
22414
|
+
saveTherapyState(state);
|
|
22113
22415
|
console.log(chalk50.green(" Therapy stopped."));
|
|
22114
22416
|
console.log(chalk50.dim(` Total: ${state.dpoPairsGenerated} DPO pairs from ${state.cyclesCompleted} cycles.`));
|
|
22417
|
+
console.log(chalk50.dim(` Shadow: ${state.shadowPatterns} patterns tracked.`));
|
|
22115
22418
|
console.log();
|
|
22116
22419
|
try {
|
|
22117
22420
|
process.kill(state.pid, "SIGINT");
|
|
@@ -22168,7 +22471,7 @@ program.name("holomime").description("Personality engine for AI agents \u2014 Bi
|
|
|
22168
22471
|
const commandName = actionCommand.name();
|
|
22169
22472
|
showTelemetryBannerIfNeeded();
|
|
22170
22473
|
trackEvent("cli_command", { command: commandName });
|
|
22171
|
-
const skipPersonalityCheck = ["init", "init-stack", "compile-stack", "browse", "use", "install", "activate", "telemetry", "brain", "personality", "core", "identity", "config", "
|
|
22474
|
+
const skipPersonalityCheck = ["init", "init-stack", "compile-stack", "browse", "use", "install", "activate", "telemetry", "brain", "personality", "core", "identity", "config", "therapy"];
|
|
22172
22475
|
if (!skipPersonalityCheck.includes(commandName) && !checkPersonalityExists()) {
|
|
22173
22476
|
showWelcome();
|
|
22174
22477
|
process.exit(0);
|
|
@@ -22254,7 +22557,7 @@ program.command("certify").description("Generate a verifiable behavioral credent
|
|
|
22254
22557
|
options.personality = resolved.personalityPath;
|
|
22255
22558
|
await certifyCommand(options);
|
|
22256
22559
|
});
|
|
22257
|
-
program.command("daemon", { hidden: true }).description("Background relapse detection [Pro] (use 'holomime
|
|
22560
|
+
program.command("daemon", { hidden: true }).description("Background relapse detection [Pro] (use 'holomime therapy' instead)").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);
|
|
22258
22561
|
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);
|
|
22259
22562
|
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);
|
|
22260
22563
|
program.command("network").description("Multi-agent therapy mesh \u2014 agents treating agents [Pro]").option("--dir <path>", "Auto-discover agents in directory").option("--config <path>", "Path to network.json config file").option("--pairing <strategy>", "Pairing strategy (severity, round-robin, complementary)", "severity").option("--therapist <path>", "Custom therapist personality spec").option("--oversight <mode>", "Oversight mode (none, review, approve, approve-specs)", "review").option("--provider <provider>", "LLM provider (ollama, anthropic, openai)", "ollama").option("--model <model>", "Model override").option("--max-sessions <n>", "Max sessions per agent", "3").option("--convergence <n>", "Convergence threshold 0-100", "85").option("--turns <n>", "Max turns per session", "20").option("--apply", "Write spec changes back to .personality.json").option("--export-dpo <path>", "Export DPO pairs to file").action(networkCommand);
|
|
@@ -22269,7 +22572,7 @@ program.command("cure").description("End-to-end behavioral fix \u2014 just run i
|
|
|
22269
22572
|
if (!options.model) options.model = resolved.model;
|
|
22270
22573
|
await cureCommand(options);
|
|
22271
22574
|
});
|
|
22272
|
-
program.command("
|
|
22575
|
+
program.command("therapy [action]").description("Autonomous behavioral therapy \u2014 generates DPO pairs and self-improves").option("--interval <ms>", "Practice interval in ms (default: 600000)").option("--max-cycles <n>", "Max cycles per run (default: 50)").action(async (action, options) => {
|
|
22273
22576
|
options.action = action;
|
|
22274
22577
|
await miraCommand(options);
|
|
22275
22578
|
});
|
|
@@ -22296,10 +22599,10 @@ program.addHelpText("before", `
|
|
|
22296
22599
|
cure Fix it permanently
|
|
22297
22600
|
benchmark Verify the fix
|
|
22298
22601
|
|
|
22299
|
-
|
|
22300
|
-
|
|
22301
|
-
|
|
22302
|
-
|
|
22602
|
+
THERAPY
|
|
22603
|
+
therapy Start autonomous therapy
|
|
22604
|
+
therapy status Check therapy progress
|
|
22605
|
+
therapy stop Stop therapy
|
|
22303
22606
|
|
|
22304
22607
|
ADVANCED
|
|
22305
22608
|
align Single therapy session
|