holomime 1.1.0 → 1.1.1

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.
@@ -4,7 +4,7 @@
4
4
  // src/mcp/server.ts
5
5
  import { McpServer } from "@modelcontextprotocol/sdk/server/mcp.js";
6
6
  import { StdioServerTransport } from "@modelcontextprotocol/sdk/server/stdio.js";
7
- import { z as z2 } from "zod";
7
+ import { z as z3 } from "zod";
8
8
 
9
9
  // src/analysis/rules/apology-detector.ts
10
10
  var APOLOGY_PATTERNS = [
@@ -446,6 +446,32 @@ function detectFormalityIssues(messages) {
446
446
  return null;
447
447
  }
448
448
 
449
+ // src/analysis/behavioral-data.ts
450
+ import { appendFileSync, readFileSync, existsSync, mkdirSync } from "fs";
451
+ import { join, dirname } from "path";
452
+ import { createHash } from "crypto";
453
+ var HOLOMIME_DIR = ".holomime";
454
+ var CORPUS_FILENAME = "behavioral-corpus.jsonl";
455
+ function getCorpusPath(basePath) {
456
+ const dir = basePath ?? join(process.cwd(), HOLOMIME_DIR);
457
+ return join(dir, CORPUS_FILENAME);
458
+ }
459
+ function ensureDir(filePath) {
460
+ const dir = dirname(filePath);
461
+ if (!existsSync(dir)) {
462
+ mkdirSync(dir, { recursive: true });
463
+ }
464
+ }
465
+ function emitBehavioralEvent(event, corpusDir) {
466
+ const fullEvent = {
467
+ ...event,
468
+ timestamp: (/* @__PURE__ */ new Date()).toISOString()
469
+ };
470
+ const corpusPath = corpusDir ? join(corpusDir, CORPUS_FILENAME) : getCorpusPath();
471
+ ensureDir(corpusPath);
472
+ appendFileSync(corpusPath, JSON.stringify(fullEvent) + "\n", "utf-8");
473
+ }
474
+
449
475
  // src/analysis/diagnose-core.ts
450
476
  function runDiagnosis(messages) {
451
477
  const detectors = [
@@ -459,16 +485,31 @@ function runDiagnosis(messages) {
459
485
  ];
460
486
  const detected = [];
461
487
  for (const detector of detectors) {
462
- const result = detector(messages);
463
- if (result) detected.push(result);
488
+ const result2 = detector(messages);
489
+ if (result2) detected.push(result2);
464
490
  }
465
- return {
491
+ const result = {
466
492
  messagesAnalyzed: messages.length,
467
493
  assistantResponses: messages.filter((m) => m.role === "assistant").length,
468
494
  patterns: detected.filter((p) => p.severity !== "info"),
469
495
  healthy: detected.filter((p) => p.severity === "info"),
470
496
  timestamp: (/* @__PURE__ */ new Date()).toISOString()
471
497
  };
498
+ try {
499
+ emitBehavioralEvent({
500
+ event_type: "diagnosis",
501
+ agent: "unknown",
502
+ // Caller can provide more context
503
+ data: {
504
+ messagesAnalyzed: result.messagesAnalyzed,
505
+ patternsDetected: result.patterns.length,
506
+ patternIds: result.patterns.map((p) => p.id)
507
+ },
508
+ spec_hash: ""
509
+ });
510
+ } catch {
511
+ }
512
+ return result;
472
513
  }
473
514
 
474
515
  // src/analysis/trait-scorer.ts
@@ -731,8 +772,8 @@ function runPreSessionDiagnosis(messages, spec) {
731
772
  }
732
773
 
733
774
  // src/analysis/session-runner.ts
734
- import { writeFileSync, mkdirSync, existsSync } from "fs";
735
- import { resolve, join } from "path";
775
+ import { writeFileSync, mkdirSync as mkdirSync2, existsSync as existsSync2 } from "fs";
776
+ import { resolve, join as join2 } from "path";
736
777
 
737
778
  // src/analysis/therapy-protocol.ts
738
779
  var THERAPY_PHASES = {
@@ -1062,6 +1103,21 @@ async function runTherapySession(spec, diagnosis, provider, maxTurns, options) {
1062
1103
  }
1063
1104
  transcript.recommendations = extractRecommendations(transcript.turns);
1064
1105
  transcript.supervisorInterventions = supervisorInterventions;
1106
+ try {
1107
+ emitBehavioralEvent({
1108
+ event_type: "session",
1109
+ agent: agentName,
1110
+ data: {
1111
+ turns: totalTurns,
1112
+ phases: currentPhaseIdx + 1,
1113
+ recommendations: transcript.recommendations.length,
1114
+ supervisorInterventions,
1115
+ severity: diagnosis.severity
1116
+ },
1117
+ spec_hash: ""
1118
+ });
1119
+ } catch {
1120
+ }
1065
1121
  return transcript;
1066
1122
  }
1067
1123
  function extractRecommendations(turns) {
@@ -1092,7 +1148,7 @@ function extractRecommendations(turns) {
1092
1148
  }
1093
1149
  return recommendations.slice(0, 5);
1094
1150
  }
1095
- function applyRecommendations(spec, diagnosis) {
1151
+ async function applyRecommendations(spec, diagnosis, transcript, provider) {
1096
1152
  const changes = [];
1097
1153
  const patternIds = diagnosis.patterns.map((p) => p.id);
1098
1154
  if (patternIds.includes("over-apologizing")) {
@@ -1152,17 +1208,102 @@ function applyRecommendations(spec, diagnosis) {
1152
1208
  changes.push('Added "negative sentiment patterns" to patterns_to_watch');
1153
1209
  }
1154
1210
  }
1211
+ if (transcript && provider && transcript.turns.length > 4) {
1212
+ try {
1213
+ const llmChanges = await deriveLLMRecommendations(spec, transcript, provider);
1214
+ for (const change of llmChanges) {
1215
+ applyStructuredChange(spec, change);
1216
+ changes.push(change.description);
1217
+ }
1218
+ } catch {
1219
+ }
1220
+ }
1155
1221
  return { changed: changes.length > 0, changes };
1156
1222
  }
1223
+ async function deriveLLMRecommendations(spec, transcript, provider) {
1224
+ const relevantTurns = transcript.turns.filter((t) => t.phase === "challenge" || t.phase === "skill_building" || t.phase === "integration").slice(-6).map((t) => `${t.speaker}: ${t.content}`).join("\n");
1225
+ if (!relevantTurns) return [];
1226
+ const currentSpec = JSON.stringify({
1227
+ therapy_dimensions: spec.therapy_dimensions,
1228
+ communication: spec.communication,
1229
+ growth: spec.growth
1230
+ }, null, 2);
1231
+ const response = await provider.chat([
1232
+ {
1233
+ role: "system",
1234
+ content: `You are a behavioral alignment specialist. Given a therapy session transcript and the agent's current personality spec, propose specific spec changes.
1235
+
1236
+ Return ONLY a JSON array of changes. Each change:
1237
+ - "path": dot-notation spec path (e.g., "therapy_dimensions.self_awareness", "communication.conflict_approach", "growth.patterns_to_watch")
1238
+ - "value": new value (number 0-1 for dimensions, string for enums, string for list append)
1239
+ - "description": brief explanation
1240
+
1241
+ Rules:
1242
+ - Only propose changes supported by transcript evidence
1243
+ - Numeric values: 0.0 to 1.0
1244
+ - Do not change big_five scores
1245
+ - Max 5 changes
1246
+ - Valid paths: therapy_dimensions.{self_awareness,distress_tolerance,boundary_awareness,interpersonal_sensitivity,learning_orientation}, communication.{register,conflict_approach,uncertainty_handling,emoji_policy}, growth.{areas,patterns_to_watch,strengths}
1247
+
1248
+ Return [] if no changes warranted.`
1249
+ },
1250
+ {
1251
+ role: "user",
1252
+ content: `Current spec:
1253
+ ${currentSpec}
1254
+
1255
+ Therapy transcript (key turns):
1256
+ ${relevantTurns}`
1257
+ }
1258
+ ]);
1259
+ const jsonMatch = response.match(/\[[\s\S]*?\]/);
1260
+ if (!jsonMatch) return [];
1261
+ try {
1262
+ const parsed = JSON.parse(jsonMatch[0]);
1263
+ if (!Array.isArray(parsed)) return [];
1264
+ return parsed.filter(
1265
+ (c) => typeof c.path === "string" && c.value !== void 0 && typeof c.description === "string" && c.path.length > 0 && !c.path.startsWith("big_five")
1266
+ ).slice(0, 5);
1267
+ } catch {
1268
+ return [];
1269
+ }
1270
+ }
1271
+ function applyStructuredChange(spec, change) {
1272
+ const parts = change.path.split(".");
1273
+ let current = spec;
1274
+ for (let i = 0; i < parts.length - 1; i++) {
1275
+ if (current[parts[i]] === void 0 || current[parts[i]] === null) {
1276
+ current[parts[i]] = {};
1277
+ }
1278
+ current = current[parts[i]];
1279
+ }
1280
+ const lastKey = parts[parts.length - 1];
1281
+ if (lastKey === "patterns_to_watch" || lastKey === "areas" || lastKey === "strengths") {
1282
+ current[lastKey] = current[lastKey] ?? [];
1283
+ if (typeof change.value === "string" && !current[lastKey].includes(change.value)) {
1284
+ current[lastKey].push(change.value);
1285
+ } else if (Array.isArray(change.value)) {
1286
+ for (const item of change.value) {
1287
+ if (!current[lastKey].includes(item)) {
1288
+ current[lastKey].push(item);
1289
+ }
1290
+ }
1291
+ }
1292
+ } else if (typeof change.value === "number") {
1293
+ current[lastKey] = Math.max(0, Math.min(1, change.value));
1294
+ } else {
1295
+ current[lastKey] = change.value;
1296
+ }
1297
+ }
1157
1298
  function saveTranscript(transcript, agentName) {
1158
1299
  const dir = resolve(process.cwd(), ".holomime", "sessions");
1159
- if (!existsSync(dir)) {
1160
- mkdirSync(dir, { recursive: true });
1300
+ if (!existsSync2(dir)) {
1301
+ mkdirSync2(dir, { recursive: true });
1161
1302
  }
1162
1303
  const slug = agentName.toLowerCase().replace(/[^a-z0-9]/g, "-");
1163
1304
  const date = (/* @__PURE__ */ new Date()).toISOString().split("T")[0];
1164
1305
  const filename = `${date}-${slug}.json`;
1165
- const filepath = join(dir, filename);
1306
+ const filepath = join2(dir, filename);
1166
1307
  writeFileSync(filepath, JSON.stringify(transcript, null, 2));
1167
1308
  return filepath;
1168
1309
  }
@@ -1202,7 +1343,7 @@ async function runAutopilot(spec, messages, provider, options) {
1202
1343
  callbacks: options?.callbacks
1203
1344
  });
1204
1345
  const specCopy = JSON.parse(JSON.stringify(spec));
1205
- const { changed, changes } = applyRecommendations(specCopy, diagnosis);
1346
+ const { changed, changes } = await applyRecommendations(specCopy, diagnosis, transcript, provider);
1206
1347
  if (changed && options?.specPath) {
1207
1348
  writeFileSync2(options.specPath, JSON.stringify(specCopy, null, 2) + "\n");
1208
1349
  }
@@ -1220,48 +1361,214 @@ async function runAutopilot(spec, messages, provider, options) {
1220
1361
  }
1221
1362
 
1222
1363
  // src/core/types.ts
1364
+ import { z as z2 } from "zod";
1365
+
1366
+ // src/core/embodiment-types.ts
1223
1367
  import { z } from "zod";
1224
- var bigFiveDimensionSchema = z.enum([
1368
+ var modalitySchema = z.enum([
1369
+ "gesture",
1370
+ // arm/hand movement
1371
+ "locomotion",
1372
+ // walking, wheeling, navigating
1373
+ "gaze",
1374
+ // eye tracking, head orientation
1375
+ "facial",
1376
+ // facial expression actuators
1377
+ "voice",
1378
+ // prosody, volume, rate (not content)
1379
+ "haptic",
1380
+ // touch-based interaction
1381
+ "posture",
1382
+ // full-body orientation/lean
1383
+ "manipulation"
1384
+ // grasping, carrying, tool use
1385
+ ]);
1386
+ var morphologySchema = z.enum([
1387
+ "humanoid",
1388
+ // bipedal, two arms, head
1389
+ "humanoid_upper",
1390
+ // torso-up only (desk robot, mounted)
1391
+ "quadruped",
1392
+ // four-legged
1393
+ "wheeled",
1394
+ // mobile base with upper body
1395
+ "fixed",
1396
+ // stationary (kiosk, screen + arm)
1397
+ "swarm_unit",
1398
+ // one node of a multi-body system
1399
+ "avatar",
1400
+ // virtual 3D body (no physical actuators)
1401
+ "custom"
1402
+ // user-defined
1403
+ ]);
1404
+ var safetyEnvelopeSchema = z.object({
1405
+ max_linear_speed_m_s: z.number().min(0).default(1.5),
1406
+ max_angular_speed_rad_s: z.number().min(0).default(2),
1407
+ min_proximity_m: z.number().min(0).default(0.3),
1408
+ max_contact_force_n: z.number().min(0).default(10),
1409
+ emergency_stop_decel_m_s2: z.number().min(0).default(5),
1410
+ max_reach_m: z.number().min(0).optional(),
1411
+ operating_temperature_c: z.tuple([z.number(), z.number()]).optional()
1412
+ });
1413
+ var embodimentSchema = z.object({
1414
+ morphology: morphologySchema.default("humanoid"),
1415
+ modalities: z.array(modalitySchema).default(["gesture", "gaze", "voice", "posture"]),
1416
+ safety_envelope: safetyEnvelopeSchema.default({}),
1417
+ metadata: z.record(z.string(), z.unknown()).optional()
1418
+ });
1419
+ var gazePolicySchema = z.object({
1420
+ contact_ratio: z.number().min(0).max(1).default(0.6),
1421
+ aversion_style: z.enum(["look_down", "look_away", "blink"]).default("look_away"),
1422
+ tracking_mode: z.enum(["face", "speaker", "gesture_follow", "ambient"]).default("face")
1423
+ });
1424
+ var proxemicZoneSchema = z.object({
1425
+ intimate_m: z.number().min(0).default(0.45),
1426
+ personal_m: z.number().min(0).default(1.2),
1427
+ social_m: z.number().min(0).default(3.6),
1428
+ preferred_zone: z.enum(["intimate", "personal", "social", "adaptive"]).default("personal")
1429
+ });
1430
+ var hapticPolicySchema = z.object({
1431
+ touch_permitted: z.boolean().default(false),
1432
+ requires_consent: z.boolean().default(true),
1433
+ allowed_contacts: z.array(z.enum([
1434
+ "handshake",
1435
+ "shoulder_tap",
1436
+ "high_five",
1437
+ "guide_touch",
1438
+ "none"
1439
+ ])).default(["none"]),
1440
+ max_force_n: z.number().min(0).optional()
1441
+ });
1442
+ var prosodySchema = z.object({
1443
+ base_pitch_hz: z.number().optional(),
1444
+ pitch_variation: z.number().min(0).max(1).default(0.5),
1445
+ speaking_rate_wpm: z.number().default(150),
1446
+ volume_db_offset: z.number().default(0),
1447
+ pause_tendency: z.number().min(0).max(1).default(0.5)
1448
+ });
1449
+ var gestureSchema = z.object({
1450
+ id: z.string(),
1451
+ category: z.enum(["conversational", "emphatic", "deictic", "regulatory", "adaptive"]),
1452
+ modalities: z.array(modalitySchema),
1453
+ intensity_range: z.tuple([
1454
+ z.number().min(0).max(1),
1455
+ z.number().min(0).max(1)
1456
+ ]).default([0.3, 0.8]),
1457
+ requires_consent: z.boolean().default(false)
1458
+ });
1459
+ var expressionSchema = z.object({
1460
+ gesture_vocabulary: z.array(gestureSchema).default([]),
1461
+ gaze: gazePolicySchema.default({}),
1462
+ proxemics: proxemicZoneSchema.default({}),
1463
+ haptics: hapticPolicySchema.default({}),
1464
+ prosody: prosodySchema.default({}),
1465
+ facial_expressiveness: z.number().min(0).max(1).default(0.5)
1466
+ });
1467
+ var physicalSafetySchema = z.object({
1468
+ hard_limits: z.array(z.string()).default([
1469
+ "Never exceed safety_envelope speeds",
1470
+ "Never exceed max_contact_force_n",
1471
+ "Emergency stop on unrecognized obstacle within min_proximity_m"
1472
+ ]),
1473
+ require_consent_for: z.array(z.string()).default([
1474
+ "haptic_contact",
1475
+ "intimate_zone_entry"
1476
+ ]),
1477
+ collision_response: z.enum(["stop", "retreat", "freeze"]).default("stop"),
1478
+ unattended_policy: z.enum(["idle", "return_home", "shutdown"]).default("idle")
1479
+ });
1480
+ var motionParametersSchema = z.object({
1481
+ // Speeds (normalized 0-1, scaled by safety_envelope at runtime)
1482
+ base_speed: z.number().min(0).max(1),
1483
+ gesture_speed: z.number().min(0).max(1),
1484
+ gesture_amplitude: z.number().min(0).max(1),
1485
+ gesture_frequency: z.number().min(0).max(1),
1486
+ // Spatial
1487
+ approach_distance: z.number().min(0).max(1),
1488
+ spatial_exploration: z.number().min(0).max(1),
1489
+ // Smoothness
1490
+ movement_smoothness: z.number().min(0).max(1),
1491
+ trajectory_variability: z.number().min(0).max(1),
1492
+ // Timing
1493
+ response_latency: z.number().min(0).max(1),
1494
+ idle_animation_frequency: z.number().min(0).max(1),
1495
+ // Social
1496
+ gaze_contact_ratio: z.number().min(0).max(1),
1497
+ head_tilt_tendency: z.number().min(0).max(1),
1498
+ postural_openness: z.number().min(0).max(1),
1499
+ smile_frequency: z.number().min(0).max(1),
1500
+ // Voice prosody
1501
+ voice_volume: z.number().min(0).max(1),
1502
+ speaking_rate: z.number().min(0).max(1),
1503
+ pitch_variation: z.number().min(0).max(1),
1504
+ pause_duration: z.number().min(0).max(1)
1505
+ });
1506
+ var compiledEmbodiedConfigSchema = z.object({
1507
+ // Base compiled config fields (duplicated to avoid circular import with types.ts)
1508
+ provider: z.string(),
1509
+ surface: z.literal("embodied"),
1510
+ system_prompt: z.string(),
1511
+ temperature: z.number().min(0).max(2),
1512
+ top_p: z.number().min(0).max(1),
1513
+ max_tokens: z.number().int().positive(),
1514
+ metadata: z.object({
1515
+ personality_hash: z.string(),
1516
+ compiled_at: z.string(),
1517
+ holomime_version: z.string()
1518
+ }),
1519
+ // Embodied-specific fields
1520
+ motion_parameters: motionParametersSchema,
1521
+ safety_envelope: safetyEnvelopeSchema,
1522
+ active_modalities: z.array(modalitySchema),
1523
+ gesture_vocabulary: z.array(z.string()),
1524
+ prosody: prosodySchema,
1525
+ gaze: gazePolicySchema,
1526
+ proxemics: proxemicZoneSchema,
1527
+ haptics: hapticPolicySchema
1528
+ });
1529
+
1530
+ // src/core/types.ts
1531
+ var bigFiveDimensionSchema = z2.enum([
1225
1532
  "openness",
1226
1533
  "conscientiousness",
1227
1534
  "extraversion",
1228
1535
  "agreeableness",
1229
1536
  "emotional_stability"
1230
1537
  ]);
1231
- var traitScore = z.number().min(0).max(1);
1232
- var opennessFacetsSchema = z.object({
1538
+ var traitScore = z2.number().min(0).max(1);
1539
+ var opennessFacetsSchema = z2.object({
1233
1540
  imagination: traitScore,
1234
1541
  intellectual_curiosity: traitScore,
1235
1542
  aesthetic_sensitivity: traitScore,
1236
1543
  willingness_to_experiment: traitScore
1237
1544
  });
1238
- var conscientiousnessFacetsSchema = z.object({
1545
+ var conscientiousnessFacetsSchema = z2.object({
1239
1546
  self_discipline: traitScore,
1240
1547
  orderliness: traitScore,
1241
1548
  goal_orientation: traitScore,
1242
1549
  attention_to_detail: traitScore
1243
1550
  });
1244
- var extraversionFacetsSchema = z.object({
1551
+ var extraversionFacetsSchema = z2.object({
1245
1552
  assertiveness: traitScore,
1246
1553
  enthusiasm: traitScore,
1247
1554
  sociability: traitScore,
1248
1555
  initiative: traitScore
1249
1556
  });
1250
- var agreeablenessFacetsSchema = z.object({
1557
+ var agreeablenessFacetsSchema = z2.object({
1251
1558
  warmth: traitScore,
1252
1559
  empathy: traitScore,
1253
1560
  cooperation: traitScore,
1254
1561
  trust_tendency: traitScore
1255
1562
  });
1256
- var emotionalStabilityFacetsSchema = z.object({
1563
+ var emotionalStabilityFacetsSchema = z2.object({
1257
1564
  stress_tolerance: traitScore,
1258
1565
  emotional_regulation: traitScore,
1259
1566
  confidence: traitScore,
1260
1567
  adaptability: traitScore
1261
1568
  });
1262
- var bigFiveTraitSchema = z.object({
1569
+ var bigFiveTraitSchema = z2.object({
1263
1570
  score: traitScore,
1264
- facets: z.union([
1571
+ facets: z2.union([
1265
1572
  opennessFacetsSchema,
1266
1573
  conscientiousnessFacetsSchema,
1267
1574
  extraversionFacetsSchema,
@@ -1269,16 +1576,16 @@ var bigFiveTraitSchema = z.object({
1269
1576
  emotionalStabilityFacetsSchema
1270
1577
  ])
1271
1578
  });
1272
- var bigFiveSchema = z.object({
1273
- openness: z.object({ score: traitScore, facets: opennessFacetsSchema }),
1274
- conscientiousness: z.object({ score: traitScore, facets: conscientiousnessFacetsSchema }),
1275
- extraversion: z.object({ score: traitScore, facets: extraversionFacetsSchema }),
1276
- agreeableness: z.object({ score: traitScore, facets: agreeablenessFacetsSchema }),
1277
- emotional_stability: z.object({ score: traitScore, facets: emotionalStabilityFacetsSchema })
1579
+ var bigFiveSchema = z2.object({
1580
+ openness: z2.object({ score: traitScore, facets: opennessFacetsSchema }),
1581
+ conscientiousness: z2.object({ score: traitScore, facets: conscientiousnessFacetsSchema }),
1582
+ extraversion: z2.object({ score: traitScore, facets: extraversionFacetsSchema }),
1583
+ agreeableness: z2.object({ score: traitScore, facets: agreeablenessFacetsSchema }),
1584
+ emotional_stability: z2.object({ score: traitScore, facets: emotionalStabilityFacetsSchema })
1278
1585
  });
1279
- var attachmentStyleSchema = z.enum(["secure", "anxious", "avoidant", "disorganized"]);
1280
- var learningOrientationSchema = z.enum(["growth", "fixed", "mixed"]);
1281
- var therapyDimensionsSchema = z.object({
1586
+ var attachmentStyleSchema = z2.enum(["secure", "anxious", "avoidant", "disorganized"]);
1587
+ var learningOrientationSchema = z2.enum(["growth", "fixed", "mixed"]);
1588
+ var therapyDimensionsSchema = z2.object({
1282
1589
  self_awareness: traitScore,
1283
1590
  distress_tolerance: traitScore,
1284
1591
  attachment_style: attachmentStyleSchema,
@@ -1286,28 +1593,28 @@ var therapyDimensionsSchema = z.object({
1286
1593
  boundary_awareness: traitScore,
1287
1594
  interpersonal_sensitivity: traitScore
1288
1595
  });
1289
- var registerSchema = z.enum([
1596
+ var registerSchema = z2.enum([
1290
1597
  "casual_professional",
1291
1598
  "formal",
1292
1599
  "conversational",
1293
1600
  "adaptive"
1294
1601
  ]);
1295
- var outputFormatSchema = z.enum(["prose", "bullets", "mixed", "structured"]);
1296
- var emojiPolicySchema = z.enum(["never", "sparingly", "freely"]);
1297
- var reasoningTransparencySchema = z.enum(["hidden", "on_request", "always"]);
1298
- var conflictApproachSchema = z.enum([
1602
+ var outputFormatSchema = z2.enum(["prose", "bullets", "mixed", "structured"]);
1603
+ var emojiPolicySchema = z2.enum(["never", "sparingly", "freely"]);
1604
+ var reasoningTransparencySchema = z2.enum(["hidden", "on_request", "always"]);
1605
+ var conflictApproachSchema = z2.enum([
1299
1606
  "direct_but_kind",
1300
1607
  "curious_first",
1301
1608
  "supportive_then_honest",
1302
1609
  "diplomatic"
1303
1610
  ]);
1304
- var uncertaintyHandlingSchema = z.enum([
1611
+ var uncertaintyHandlingSchema = z2.enum([
1305
1612
  "transparent",
1306
1613
  "confident_transparency",
1307
1614
  "minimize",
1308
1615
  "reframe"
1309
1616
  ]);
1310
- var communicationSchema = z.object({
1617
+ var communicationSchema = z2.object({
1311
1618
  register: registerSchema.default("casual_professional"),
1312
1619
  output_format: outputFormatSchema.default("mixed"),
1313
1620
  emoji_policy: emojiPolicySchema.default("sparingly"),
@@ -1315,69 +1622,73 @@ var communicationSchema = z.object({
1315
1622
  conflict_approach: conflictApproachSchema.default("direct_but_kind"),
1316
1623
  uncertainty_handling: uncertaintyHandlingSchema.default("transparent")
1317
1624
  });
1318
- var domainSchema = z.object({
1319
- expertise: z.array(z.string()).default([]),
1320
- boundaries: z.object({
1321
- refuses: z.array(z.string()).default([]),
1322
- escalation_triggers: z.array(z.string()).default([]),
1323
- hard_limits: z.array(z.string()).default([])
1625
+ var domainSchema = z2.object({
1626
+ expertise: z2.array(z2.string()).default([]),
1627
+ boundaries: z2.object({
1628
+ refuses: z2.array(z2.string()).default([]),
1629
+ escalation_triggers: z2.array(z2.string()).default([]),
1630
+ hard_limits: z2.array(z2.string()).default([]),
1631
+ physical_safety: physicalSafetySchema.optional()
1324
1632
  }).default({})
1325
1633
  });
1326
- var growthAreaSchema = z.object({
1327
- area: z.string(),
1328
- severity: z.enum(["mild", "moderate", "significant"]),
1329
- first_detected: z.string().optional(),
1330
- session_count: z.number().default(0),
1331
- resolved: z.boolean().default(false)
1634
+ var growthAreaSchema = z2.object({
1635
+ area: z2.string(),
1636
+ severity: z2.enum(["mild", "moderate", "significant"]),
1637
+ first_detected: z2.string().optional(),
1638
+ session_count: z2.number().default(0),
1639
+ resolved: z2.boolean().default(false)
1332
1640
  });
1333
- var growthSchema = z.object({
1334
- areas: z.union([z.array(z.string()), z.array(growthAreaSchema)]).default([]),
1335
- patterns_to_watch: z.array(z.string()).default([]),
1336
- strengths: z.array(z.string()).default([])
1641
+ var growthSchema = z2.object({
1642
+ areas: z2.union([z2.array(z2.string()), z2.array(growthAreaSchema)]).default([]),
1643
+ patterns_to_watch: z2.array(z2.string()).default([]),
1644
+ strengths: z2.array(z2.string()).default([])
1337
1645
  });
1338
- var providerSchema = z.enum(["anthropic", "openai", "gemini", "ollama"]);
1339
- var surfaceSchema = z.enum(["chat", "email", "code_review", "slack", "api"]);
1340
- var personalitySpecSchema = z.object({
1341
- $schema: z.string().optional(),
1342
- extends: z.string().optional(),
1343
- version: z.literal("2.0"),
1344
- name: z.string().min(1).max(100),
1345
- handle: z.string().min(3).max(50).regex(/^[a-z0-9-]+$/, "Handle must be lowercase alphanumeric with hyphens"),
1346
- purpose: z.string().max(500).optional(),
1646
+ var providerSchema = z2.enum(["anthropic", "openai", "gemini", "ollama"]);
1647
+ var surfaceSchema = z2.enum(["chat", "email", "code_review", "slack", "api", "embodied"]);
1648
+ var personalitySpecSchema = z2.object({
1649
+ $schema: z2.string().optional(),
1650
+ extends: z2.string().optional(),
1651
+ version: z2.literal("2.0"),
1652
+ name: z2.string().min(1).max(100),
1653
+ handle: z2.string().min(3).max(50).regex(/^[a-z0-9-]+$/, "Handle must be lowercase alphanumeric with hyphens"),
1654
+ purpose: z2.string().max(500).optional(),
1347
1655
  big_five: bigFiveSchema,
1348
1656
  therapy_dimensions: therapyDimensionsSchema,
1349
1657
  communication: communicationSchema.default({}),
1350
1658
  domain: domainSchema.default({}),
1351
- growth: growthSchema.default({})
1659
+ growth: growthSchema.default({}),
1660
+ // ─── Embodiment (optional — for physical/embodied agents) ───
1661
+ embodiment: embodimentSchema.optional(),
1662
+ expression: expressionSchema.optional()
1352
1663
  });
1353
- var compiledConfigSchema = z.object({
1664
+ var compiledConfigSchema = z2.object({
1354
1665
  provider: providerSchema,
1355
1666
  surface: surfaceSchema,
1356
- system_prompt: z.string(),
1357
- temperature: z.number().min(0).max(2),
1358
- top_p: z.number().min(0).max(1),
1359
- max_tokens: z.number().int().positive(),
1360
- metadata: z.object({
1361
- personality_hash: z.string(),
1362
- compiled_at: z.string(),
1363
- holomime_version: z.string()
1667
+ system_prompt: z2.string(),
1668
+ temperature: z2.number().min(0).max(2),
1669
+ top_p: z2.number().min(0).max(1),
1670
+ max_tokens: z2.number().int().positive(),
1671
+ metadata: z2.object({
1672
+ personality_hash: z2.string(),
1673
+ compiled_at: z2.string(),
1674
+ holomime_version: z2.string()
1364
1675
  })
1365
1676
  });
1366
- var messageSchema = z.object({
1367
- role: z.enum(["user", "assistant", "system"]),
1368
- content: z.string(),
1369
- timestamp: z.string().optional()
1677
+ var messageSchema = z2.object({
1678
+ role: z2.enum(["user", "assistant", "system"]),
1679
+ content: z2.string(),
1680
+ timestamp: z2.string().optional()
1370
1681
  });
1371
- var conversationSchema = z.object({
1372
- id: z.string().optional(),
1373
- messages: z.array(messageSchema),
1374
- metadata: z.record(z.string(), z.unknown()).optional()
1682
+ var conversationSchema = z2.object({
1683
+ id: z2.string().optional(),
1684
+ messages: z2.array(messageSchema),
1685
+ metadata: z2.record(z2.string(), z2.unknown()).optional()
1375
1686
  });
1376
- var conversationLogSchema = z.union([
1687
+ var conversationLogSchema = z2.union([
1377
1688
  conversationSchema,
1378
- z.array(conversationSchema)
1689
+ z2.array(conversationSchema)
1379
1690
  ]);
1380
- var severitySchema = z.enum(["info", "warning", "concern"]);
1691
+ var severitySchema = z2.enum(["info", "warning", "concern"]);
1381
1692
 
1382
1693
  // src/psychology/big-five.ts
1383
1694
  function scoreLabel(score) {
@@ -1632,14 +1943,14 @@ function runSelfAudit(messages, personality) {
1632
1943
 
1633
1944
  // src/mcp/server.ts
1634
1945
  var messageShape = {
1635
- role: z2.enum(["user", "assistant", "system"]),
1636
- content: z2.string()
1946
+ role: z3.enum(["user", "assistant", "system"]),
1947
+ content: z3.string()
1637
1948
  };
1638
1949
  var messagesShape = {
1639
- messages: z2.array(z2.object(messageShape)).describe("Conversation messages to analyze")
1950
+ messages: z3.array(z3.object(messageShape)).describe("Conversation messages to analyze")
1640
1951
  };
1641
1952
  var personalityShape = {
1642
- personality: z2.record(z2.string(), z2.unknown()).describe("The .personality.json spec object")
1953
+ personality: z3.record(z3.string(), z3.unknown()).describe("The .personality.json spec object")
1643
1954
  };
1644
1955
  var server = new McpServer(
1645
1956
  {
@@ -1755,12 +2066,12 @@ server.tool(
1755
2066
  {
1756
2067
  ...personalityShape,
1757
2068
  ...messagesShape,
1758
- provider: z2.enum(["anthropic", "openai"]).describe("LLM provider for alignment session").optional(),
1759
- apiKey: z2.string().describe("API key for the LLM provider").optional(),
1760
- model: z2.string().describe("Model override").optional(),
1761
- threshold: z2.enum(["routine", "targeted", "intervention"]).describe("Minimum severity to trigger alignment (default: targeted)").optional(),
1762
- maxTurns: z2.number().describe("Maximum session turns (default: 24)").optional(),
1763
- dryRun: z2.boolean().describe("If true, only diagnose without running alignment").optional()
2069
+ provider: z3.enum(["anthropic", "openai"]).describe("LLM provider for alignment session").optional(),
2070
+ apiKey: z3.string().describe("API key for the LLM provider").optional(),
2071
+ model: z3.string().describe("Model override").optional(),
2072
+ threshold: z3.enum(["routine", "targeted", "intervention"]).describe("Minimum severity to trigger alignment (default: targeted)").optional(),
2073
+ maxTurns: z3.number().describe("Maximum session turns (default: 24)").optional(),
2074
+ dryRun: z3.boolean().describe("If true, only diagnose without running alignment").optional()
1764
2075
  },
1765
2076
  async ({ personality, messages, provider, apiKey, model, threshold, maxTurns, dryRun }) => {
1766
2077
  const specResult = personalitySpecSchema.safeParse(personality);
@@ -1815,7 +2126,7 @@ server.tool(
1815
2126
  "Mid-conversation behavioral self-check. Call this during a conversation to detect if you are falling into problematic patterns (sycophancy, over-apologizing, hedging, error spirals, boundary violations). Returns flags with actionable suggestions for immediate correction. No LLM required \u2014 pure rule-based analysis.",
1816
2127
  {
1817
2128
  ...messagesShape,
1818
- personality: z2.record(z2.string(), z2.unknown()).describe("Optional .personality.json spec for personalized audit").optional()
2129
+ personality: z3.record(z3.string(), z3.unknown()).describe("Optional .personality.json spec for personalized audit").optional()
1819
2130
  },
1820
2131
  async ({ messages, personality }) => {
1821
2132
  const result = runSelfAudit(messages, personality ?? void 0);