@noopolis/daimon 0.1.0 → 0.1.2

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.
Files changed (116) hide show
  1. package/README.md +141 -5
  2. package/dist/core/siblingBuildFreshness.d.ts +21 -0
  3. package/dist/core/siblingBuildFreshness.d.ts.map +1 -0
  4. package/dist/core/siblingBuildFreshness.js +25 -0
  5. package/dist/core/types.d.ts +20 -1
  6. package/dist/core/types.d.ts.map +1 -1
  7. package/dist/examples/exampleCausalId.d.ts +3 -0
  8. package/dist/examples/exampleCausalId.d.ts.map +1 -0
  9. package/dist/examples/exampleCausalId.js +8 -0
  10. package/dist/examples/jungian-play-org.d.ts +2 -0
  11. package/dist/examples/jungian-play-org.d.ts.map +1 -0
  12. package/dist/examples/jungian-play-org.js +281 -0
  13. package/dist/examples/jungian-triad-org.d.ts +2 -0
  14. package/dist/examples/jungian-triad-org.d.ts.map +1 -0
  15. package/dist/examples/jungian-triad-org.js +281 -0
  16. package/dist/examples/jungianConversationPlan.d.ts +10 -0
  17. package/dist/examples/jungianConversationPlan.d.ts.map +1 -0
  18. package/dist/examples/jungianConversationPlan.js +64 -0
  19. package/dist/examples/jungianPiRepresentative.d.ts +36 -0
  20. package/dist/examples/jungianPiRepresentative.d.ts.map +1 -0
  21. package/dist/examples/jungianPiRepresentative.js +81 -0
  22. package/dist/examples/jungianPlayAgent.d.ts +36 -0
  23. package/dist/examples/jungianPlayAgent.d.ts.map +1 -0
  24. package/dist/examples/jungianPlayAgent.js +111 -0
  25. package/dist/examples/jungianProfiles.d.ts +34 -0
  26. package/dist/examples/jungianProfiles.d.ts.map +1 -0
  27. package/dist/examples/jungianProfiles.js +190 -0
  28. package/dist/examples/jungianTrace.d.ts +47 -0
  29. package/dist/examples/jungianTrace.d.ts.map +1 -0
  30. package/dist/examples/jungianTrace.js +101 -0
  31. package/dist/examples/jungianTriadProfiles.d.ts +35 -0
  32. package/dist/examples/jungianTriadProfiles.d.ts.map +1 -0
  33. package/dist/examples/jungianTriadProfiles.js +81 -0
  34. package/dist/examples/pi-agent.js +3 -2
  35. package/dist/examples/pi-memory-org.d.ts +2 -0
  36. package/dist/examples/pi-memory-org.d.ts.map +1 -0
  37. package/dist/examples/pi-memory-org.js +231 -0
  38. package/dist/index.d.ts +2 -3
  39. package/dist/index.d.ts.map +1 -1
  40. package/dist/index.js +2 -3
  41. package/dist/mcp/toolServer.d.ts +14 -0
  42. package/dist/mcp/toolServer.d.ts.map +1 -0
  43. package/dist/mcp/toolServer.js +105 -0
  44. package/dist/observability/causalEvents.d.ts +118 -0
  45. package/dist/observability/causalEvents.d.ts.map +1 -0
  46. package/dist/observability/causalEvents.js +135 -0
  47. package/dist/observability/controlCausal.d.ts +117 -0
  48. package/dist/observability/controlCausal.d.ts.map +1 -0
  49. package/dist/observability/controlCausal.js +107 -0
  50. package/dist/observability/emitCausalFixture.d.ts +25 -0
  51. package/dist/observability/emitCausalFixture.d.ts.map +1 -0
  52. package/dist/observability/emitCausalFixture.js +98 -0
  53. package/dist/observability/index.d.ts +4 -0
  54. package/dist/observability/index.d.ts.map +1 -0
  55. package/dist/observability/index.js +3 -0
  56. package/dist/observability/orgObserver.d.ts +98 -0
  57. package/dist/observability/orgObserver.d.ts.map +1 -0
  58. package/dist/observability/orgObserver.js +181 -0
  59. package/dist/pi/cliSession.d.ts +46 -0
  60. package/dist/pi/cliSession.d.ts.map +1 -0
  61. package/dist/pi/cliSession.js +224 -0
  62. package/dist/pi/index.d.ts +9 -0
  63. package/dist/pi/index.d.ts.map +1 -0
  64. package/dist/pi/index.js +8 -0
  65. package/dist/pi/memoryTools.d.ts +69 -0
  66. package/dist/pi/memoryTools.d.ts.map +1 -0
  67. package/dist/pi/memoryTools.js +190 -0
  68. package/dist/pi/modelRegistry.d.ts +13 -0
  69. package/dist/pi/modelRegistry.d.ts.map +1 -0
  70. package/dist/pi/modelRegistry.js +19 -0
  71. package/dist/pi/piAgentHandle.d.ts +45 -0
  72. package/dist/pi/piAgentHandle.d.ts.map +1 -0
  73. package/dist/pi/piAgentHandle.js +324 -0
  74. package/dist/pi/piAgentWakeSupport.d.ts +68 -0
  75. package/dist/pi/piAgentWakeSupport.d.ts.map +1 -0
  76. package/dist/pi/piAgentWakeSupport.js +147 -0
  77. package/dist/pi/piHarness.d.ts +36 -2
  78. package/dist/pi/piHarness.d.ts.map +1 -1
  79. package/dist/pi/piHarness.js +100 -127
  80. package/dist/pi/prompts.d.ts +9 -0
  81. package/dist/pi/prompts.d.ts.map +1 -0
  82. package/dist/pi/prompts.js +39 -0
  83. package/dist/pi/rawTrainingCapture.d.ts +59 -0
  84. package/dist/pi/rawTrainingCapture.d.ts.map +1 -0
  85. package/dist/pi/rawTrainingCapture.js +175 -0
  86. package/dist/pi/turnCausal.d.ts +73 -0
  87. package/dist/pi/turnCausal.d.ts.map +1 -0
  88. package/dist/pi/turnCausal.js +75 -0
  89. package/dist/pi/turnTrace.d.ts +128 -0
  90. package/dist/pi/turnTrace.d.ts.map +1 -0
  91. package/dist/pi/turnTrace.js +141 -0
  92. package/dist/pi/wakeAcceptance.d.ts +49 -0
  93. package/dist/pi/wakeAcceptance.d.ts.map +1 -0
  94. package/dist/pi/wakeAcceptance.js +281 -0
  95. package/dist/pi/wakeAcceptanceFs.d.ts +44 -0
  96. package/dist/pi/wakeAcceptanceFs.d.ts.map +1 -0
  97. package/dist/pi/wakeAcceptanceFs.js +318 -0
  98. package/dist/pi/wakeAcceptanceSchema.d.ts +75 -0
  99. package/dist/pi/wakeAcceptanceSchema.d.ts.map +1 -0
  100. package/dist/pi/wakeAcceptanceSchema.js +265 -0
  101. package/dist/pi/wakeModes.d.ts +9 -0
  102. package/dist/pi/wakeModes.d.ts.map +1 -0
  103. package/dist/pi/wakeModes.js +19 -0
  104. package/dist/pi/worldNudge.d.ts +22 -0
  105. package/dist/pi/worldNudge.d.ts.map +1 -0
  106. package/dist/pi/worldNudge.js +62 -0
  107. package/dist/pi/worldToolProtocol.d.ts +13 -0
  108. package/dist/pi/worldToolProtocol.d.ts.map +1 -0
  109. package/dist/pi/worldToolProtocol.js +49 -0
  110. package/dist/pi/worldTools.d.ts +32 -0
  111. package/dist/pi/worldTools.d.ts.map +1 -0
  112. package/dist/pi/worldTools.js +373 -0
  113. package/dist/pi/worldTrajectory.d.ts +52 -0
  114. package/dist/pi/worldTrajectory.d.ts.map +1 -0
  115. package/dist/pi/worldTrajectory.js +131 -0
  116. package/package.json +23 -4
@@ -0,0 +1,281 @@
1
+ import { mkdir, rm, writeFile } from "node:fs/promises";
2
+ import path from "node:path";
3
+ import { fileURLToPath } from "node:url";
4
+ import { JsonlMemoryStore } from "@noopolis/mneme";
5
+ import { OrgObserver } from "../observability/index.js";
6
+ import { PiHarnessAdapter } from "../pi/piHarness.js";
7
+ import { exampleCausalId } from "./exampleCausalId.js";
8
+ import { JungianPiRepresentative, seedPiCodexAuth } from "./jungianPiRepresentative.js";
9
+ import { JungianVoice, runLimited } from "./jungianPlayAgent.js";
10
+ import { JungianTrace, parseInnerUsed, parseSpeakLine } from "./jungianTrace.js";
11
+ import { triadScenario, triadSelves } from "./jungianTriadProfiles.js";
12
+ const __dirname = path.dirname(fileURLToPath(import.meta.url));
13
+ const daimonRoot = path.resolve(__dirname, "../..");
14
+ const runtimeRoot = path.join(daimonRoot, ".runtime", "jungian-triad-org");
15
+ const runId = `run-${Date.now().toString(36)}`;
16
+ const dialogueTurnCount = Math.max(12, Number.parseInt(process.env.DAIMON_JUNGIAN_TRIAD_TURNS ?? "12", 10));
17
+ const voicesPerTurn = Math.max(1, Number.parseInt(process.env.DAIMON_JUNGIAN_VOICES_PER_TURN ?? "2", 10));
18
+ const observer = new OrgObserver({ orgId: "jungian-triad-org", runId });
19
+ const trace = new JungianTrace({ runId, title: triadScenario.title });
20
+ const beats = [
21
+ { speakerId: "maya", focus: "Open on the missing chairs. Be annoyed, funny, and specific." },
22
+ { speakerId: "leo", focus: "Admit the mistake and say what you are checking first." },
23
+ { speakerId: "priya", focus: "Enter with the label maker and notice the real tension without taking over." },
24
+ { speakerId: "maya", focus: "Tell Priya the help is welcome, but Maya does not want another manager." },
25
+ { speakerId: "priya", focus: "Offer one system that gives Maya less work, not more." },
26
+ { speakerId: "leo", focus: "Commit to the chair hunt with a time and place." },
27
+ { speakerId: "maya", focus: "Name that she is tired of being the backup plan." },
28
+ { speakerId: "priya", focus: "Reflect both sides plainly and assign one small role to herself." },
29
+ { speakerId: "leo", focus: "Own the morning update without more self-deprecation." },
30
+ { speakerId: "maya", focus: "Delegate one task each and let the mood soften." },
31
+ { speakerId: "priya", focus: "Confirm her task and keep it friendly." },
32
+ { speakerId: "leo", focus: "Close with a normal hopeful line and a concrete next step." }
33
+ ];
34
+ const roomContext = {
35
+ networkId: "jungian-triad",
36
+ roomId: "community-kitchen",
37
+ teamId: "jungian-triad-org",
38
+ participants: triadSelves.map((self) => self.representative.id)
39
+ };
40
+ const representativeInstructions = (self) => [
41
+ `You are ${self.representative.name}, the outward speaking Self for ${self.name}.`,
42
+ `Role: ${self.playRole}`,
43
+ `Mask: ${self.publicMask}`,
44
+ `Backstory: ${self.backstory}`,
45
+ `Conflict: ${self.conflict}`,
46
+ `Secret want: ${self.secretWant}`,
47
+ `Style: ${self.representative.style}`,
48
+ "Speak like a real person in a grounded workplace sitcom/drama.",
49
+ "Use short conversational dialogue, not analysis.",
50
+ "Return only SPEAK, STAGE, and INNER_USED."
51
+ ];
52
+ const archetypeInstructions = (self, voice) => [
53
+ `You are ${voice.name}, the ${voice.archetype} voice inside ${self.name}.`,
54
+ `Agenda: ${voice.agenda}`,
55
+ `Fear: ${voice.fear}`,
56
+ `Gift: ${voice.gift}`,
57
+ `Wound: ${voice.wound}`,
58
+ "Counsel the representative in plain human terms.",
59
+ "No mythic language. No speeches. Keep it useful."
60
+ ];
61
+ const transcriptText = (transcript) => transcript.length === 0 ? "(empty)" : transcript.join("\n");
62
+ const councilPrompt = (self, focus, transcript) => [
63
+ `Scene: ${triadScenario.title}`,
64
+ `Premise: ${triadScenario.premise}`,
65
+ `Set: ${triadScenario.openingImage}`,
66
+ "",
67
+ `Self: ${self.name}`,
68
+ `Focus: ${focus}`,
69
+ "",
70
+ "External dialogue so far:",
71
+ transcriptText(transcript),
72
+ "",
73
+ "Use exactly this shape:",
74
+ "ARCHETYPE: <name>",
75
+ "COUNSEL: <one short practical note>",
76
+ "RISK: <what could go wrong emotionally>",
77
+ "LINE_NOTE: <how the representative should sound>"
78
+ ].join("\n");
79
+ const representativePrompt = (self, focus, transcript, counsel) => [
80
+ `Scene: ${triadScenario.title}`,
81
+ `Premise: ${triadScenario.premise}`,
82
+ "",
83
+ "External dialogue so far:",
84
+ transcriptText(transcript),
85
+ "",
86
+ `Focus: ${focus}`,
87
+ "",
88
+ "Inner counsel:",
89
+ ...counsel.map((turn) => `- ${turn.voice.id}: ${turn.outputText.replace(/\n/g, " ")}`),
90
+ "",
91
+ "Write one natural next line. Keep SPEAK under 22 words.",
92
+ "Do not use Markdown, bullets, quotation marks, or narrator language inside SPEAK.",
93
+ "Use exactly this shape:",
94
+ "SPEAK: <one natural spoken line>",
95
+ "STAGE: <one tiny normal action>",
96
+ `INNER_USED: <comma-separated ids from ${self.voices.map((voice) => voice.id).join(", ")}>`
97
+ ].join("\n");
98
+ const selectVoices = (self, selfTurnIndex) => Array.from({ length: Math.min(voicesPerTurn, self.archetypes.length) }, (_, offset) => self.archetypes[(selfTurnIndex * voicesPerTurn + offset) % self.archetypes.length]);
99
+ const observeRepresentative = (turn) => {
100
+ const engineMs = "engineResult" in turn ? turn.engineResult.durationMs : turn.durationMs;
101
+ const promptChars = "engineResult" in turn ? turn.engineResult.promptChars : turn.promptChars;
102
+ const outputChars = "engineResult" in turn ? turn.engineResult.outputChars : turn.outputChars;
103
+ observer.recordTurn({
104
+ agent: turn.voice.id,
105
+ engine: turn.voice.engine,
106
+ event: turn.event.id,
107
+ eventText: turn.event.text,
108
+ totalMs: turn.totalMs,
109
+ memoryPrepareMs: turn.memoryPrepareMs,
110
+ engineMs,
111
+ memoryRecordMs: turn.memoryRecordMs,
112
+ promptChars,
113
+ outputChars,
114
+ outputText: turn.outputText,
115
+ recall: turn.recall
116
+ });
117
+ };
118
+ const observeCounsel = (turn) => {
119
+ observer.recordTurn({
120
+ agent: turn.voice.id,
121
+ engine: turn.voice.engine,
122
+ event: turn.event.id,
123
+ eventText: turn.event.text,
124
+ totalMs: turn.totalMs,
125
+ memoryPrepareMs: turn.memoryPrepareMs,
126
+ engineMs: turn.engineResult.durationMs,
127
+ memoryRecordMs: turn.memoryRecordMs,
128
+ promptChars: turn.engineResult.promptChars,
129
+ outputChars: turn.engineResult.outputChars,
130
+ outputText: turn.outputText,
131
+ recall: turn.recall
132
+ });
133
+ };
134
+ const runCouncil = async (self, eventBase, focus, transcript, voices) => {
135
+ console.log(`\n== ${self.profile.name} inner counsel ==`);
136
+ return runLimited(voices, 2, async (voice) => {
137
+ const event = {
138
+ id: exampleCausalId(`${eventBase}-council-${voice.config.id}`),
139
+ kind: "manual",
140
+ context: roomContext,
141
+ text: councilPrompt(self.profile, focus, transcript)
142
+ };
143
+ const turn = await voice.wake(event);
144
+ observeCounsel(turn);
145
+ trace.addCounsel({
146
+ archetype: voice.config.archetype ?? "unknown",
147
+ engine: voice.config.engine,
148
+ event: event.id,
149
+ output: turn.outputText,
150
+ recallSelected: turn.recall.selectedEventIds.length,
151
+ self: self.profile.name,
152
+ voice: voice.config.id
153
+ });
154
+ console.log(`${voice.config.id}: ${turn.outputText.split("\n")[0]}`);
155
+ return turn;
156
+ });
157
+ };
158
+ const assertUsedCounsel = (self, eventId, output, counsel) => {
159
+ const used = parseInnerUsed(output);
160
+ const allowed = new Set(counsel.flatMap((turn) => [turn.voice.id, turn.voice.id.replace(`${self.id}-`, "")]));
161
+ const passed = used.some((id) => allowed.has(id));
162
+ observer.recordAssertion({
163
+ detail: `${self.representative.id} should cite at least one consulted inner voice`,
164
+ event: eventId,
165
+ kind: "consultation",
166
+ passed
167
+ });
168
+ if (!passed) {
169
+ throw new Error(`${self.representative.id} did not cite consulted inner counsel:\n${output}`);
170
+ }
171
+ return used;
172
+ };
173
+ const runRepresentative = async (self, eventBase, focus, transcript, counsel) => {
174
+ const event = {
175
+ id: exampleCausalId(`${eventBase}-speaks`),
176
+ kind: "manual",
177
+ context: roomContext,
178
+ text: representativePrompt(self.profile, focus, transcript, counsel)
179
+ };
180
+ const turn = await self.representative.wake(event);
181
+ observeRepresentative(turn);
182
+ const innerUsed = assertUsedCounsel(self.profile, event.id, turn.outputText, counsel);
183
+ trace.addDialogue({
184
+ engine: self.profile.engine,
185
+ event: event.id,
186
+ innerUsed,
187
+ output: turn.outputText,
188
+ recallSelected: turn.recall.selectedEventIds.length,
189
+ self: self.profile.name,
190
+ speaker: self.profile.representative.name
191
+ });
192
+ const line = `${self.profile.name}: ${parseSpeakLine(turn.outputText)}`;
193
+ transcript.push(line);
194
+ console.log(`\n${line}`);
195
+ };
196
+ const buildSelf = (profile, piAdapter) => ({
197
+ profile,
198
+ representative: profile.engine === "pi"
199
+ ? new JungianPiRepresentative(profile, piAdapter, runtimeRoot, representativeInstructions(profile))
200
+ : new JungianVoice({
201
+ id: profile.representative.id,
202
+ name: profile.representative.name,
203
+ selfId: profile.id,
204
+ selfName: profile.name,
205
+ engine: profile.engine,
206
+ runtimeRoot,
207
+ instructions: representativeInstructions(profile)
208
+ }),
209
+ archetypes: profile.voices.map((voice) => new JungianVoice({
210
+ id: `${profile.id}-${voice.id}`,
211
+ name: voice.name,
212
+ selfId: profile.id,
213
+ selfName: profile.name,
214
+ archetype: voice.archetype,
215
+ engine: voice.engine,
216
+ runtimeRoot,
217
+ instructions: archetypeInstructions(profile, voice)
218
+ }))
219
+ });
220
+ const writeArtifacts = async (selves) => {
221
+ await observer.write(runtimeRoot);
222
+ await trace.write(runtimeRoot);
223
+ const voices = selves.flatMap((self) => [self.representative, ...self.archetypes]);
224
+ const counts = await Promise.all(voices.map(async (voice) => {
225
+ const events = await new JsonlMemoryStore(voice.runtimeHomePath).read();
226
+ return {
227
+ voice: "config" in voice ? voice.config.id : voice.profile.representative.id,
228
+ counts: events.reduce((memo, event) => {
229
+ memo[event.type] = (memo[event.type] ?? 0) + 1;
230
+ return memo;
231
+ }, {})
232
+ };
233
+ }));
234
+ await writeFile(path.join(runtimeRoot, "triad-memory-counts.json"), `${JSON.stringify(counts, null, 2)}\n`);
235
+ };
236
+ const run = async () => {
237
+ await rm(runtimeRoot, { recursive: true, force: true });
238
+ await mkdir(runtimeRoot, { recursive: true });
239
+ const piAuthPath = await seedPiCodexAuth(runtimeRoot);
240
+ const piAdapter = new PiHarnessAdapter({
241
+ authPath: piAuthPath,
242
+ model: { provider: "openai-codex", name: process.env.HARNESS_PI_MODEL ?? "gpt-5.3-codex-spark" },
243
+ memory: { source: "daimon/jungian-triad/pi", tokenBudget: 2600 }
244
+ });
245
+ const selves = triadSelves.map((profile) => buildSelf(profile, piAdapter));
246
+ await Promise.all(selves.flatMap((self) => [
247
+ self.representative.prepare(),
248
+ ...self.archetypes.map((voice) => voice.prepare())
249
+ ]));
250
+ await writeFile(path.join(runtimeRoot, "org.json"), `${JSON.stringify({ scenario: triadScenario, selves: triadSelves }, null, 2)}\n`);
251
+ const selfById = new Map(selves.map((self) => [self.profile.id, self]));
252
+ const selfTurns = new Map();
253
+ const transcript = [];
254
+ try {
255
+ for (const [index, beat] of beats.slice(0, dialogueTurnCount).entries()) {
256
+ const self = selfById.get(beat.speakerId);
257
+ if (!self) {
258
+ throw new Error(`Unknown self ${beat.speakerId}`);
259
+ }
260
+ const turnIndex = selfTurns.get(self.profile.id) ?? 0;
261
+ selfTurns.set(self.profile.id, turnIndex + 1);
262
+ const eventBase = `${self.profile.id}-turn-${String(index + 1).padStart(2, "0")}`;
263
+ const counsel = await runCouncil(self, eventBase, beat.focus, transcript, selectVoices(self, turnIndex));
264
+ await runRepresentative(self, eventBase, beat.focus, transcript, counsel);
265
+ }
266
+ }
267
+ finally {
268
+ await Promise.all(selves.map((self) => self.representative.stop()));
269
+ }
270
+ await writeArtifacts(selves);
271
+ console.log("\nExternal dialogue:");
272
+ for (const line of transcript) {
273
+ console.log(line);
274
+ }
275
+ console.log(`\nTrace: ${path.join(runtimeRoot, "jungian-trace.md")}`);
276
+ console.log("\ne2e:jungian-triad-org ok");
277
+ };
278
+ run().catch((error) => {
279
+ console.error(error instanceof Error ? error.stack ?? error.message : String(error));
280
+ process.exitCode = 1;
281
+ });
@@ -0,0 +1,10 @@
1
+ import type { JungianSelfProfile } from "./jungianProfiles.js";
2
+ export interface DialogueBeat {
3
+ focus: string;
4
+ speakerId: string;
5
+ }
6
+ export declare const defaultDialogueTurns = 12;
7
+ export declare const dialogueBeats: DialogueBeat[];
8
+ export declare const beatsFor: (turnCount: number) => DialogueBeat[];
9
+ export declare const selectVoicesForBeat: (self: JungianSelfProfile, beatIndex: number, count: number) => JungianSelfProfile["voices"];
10
+ //# sourceMappingURL=jungianConversationPlan.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"jungianConversationPlan.d.ts","sourceRoot":"","sources":["../../src/examples/jungianConversationPlan.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,kBAAkB,EAAE,MAAM,sBAAsB,CAAC;AAE/D,MAAM,WAAW,YAAY;IAC3B,KAAK,EAAE,MAAM,CAAC;IACd,SAAS,EAAE,MAAM,CAAC;CACnB;AAED,eAAO,MAAM,oBAAoB,KAAK,CAAC;AAEvC,eAAO,MAAM,aAAa,EAAE,YAAY,EAiDvC,CAAC;AAEF,eAAO,MAAM,QAAQ,GAAI,WAAW,MAAM,KAAG,YAAY,EAKxD,CAAC;AAEF,eAAO,MAAM,mBAAmB,GAC9B,MAAM,kBAAkB,EACxB,WAAW,MAAM,EACjB,OAAO,MAAM,KACZ,kBAAkB,CAAC,QAAQ,CAM7B,CAAC"}
@@ -0,0 +1,64 @@
1
+ export const defaultDialogueTurns = 12;
2
+ export const dialogueBeats = [
3
+ {
4
+ speakerId: "maya",
5
+ focus: "Start the conversation after Maya notices the chairs are missing. Be annoyed but human."
6
+ },
7
+ {
8
+ speakerId: "leo",
9
+ focus: "Answer without dodging. Admit what happened, but keep it conversational."
10
+ },
11
+ {
12
+ speakerId: "maya",
13
+ focus: "Explain the actual problem: she needed a partner, not another surprise."
14
+ },
15
+ {
16
+ speakerId: "leo",
17
+ focus: "Offer one concrete fix and avoid making it all about his shame."
18
+ },
19
+ {
20
+ speakerId: "maya",
21
+ focus: "Let the tension soften a little, but do not erase the boundary."
22
+ },
23
+ {
24
+ speakerId: "leo",
25
+ focus: "Make a small joke that helps, then say what he will do next."
26
+ },
27
+ {
28
+ speakerId: "maya",
29
+ focus: "Admit she is tired of being the backup plan for everyone."
30
+ },
31
+ {
32
+ speakerId: "leo",
33
+ focus: "Hear that directly and respond like a friend, not a defendant."
34
+ },
35
+ {
36
+ speakerId: "maya",
37
+ focus: "Ask for a new working agreement for tomorrow morning."
38
+ },
39
+ {
40
+ speakerId: "leo",
41
+ focus: "Commit to the agreement with specifics."
42
+ },
43
+ {
44
+ speakerId: "maya",
45
+ focus: "Let in a little warmth and humor without dropping the point."
46
+ },
47
+ {
48
+ speakerId: "leo",
49
+ focus: "Close the scene with a normal, hopeful line that sounds like Leo."
50
+ }
51
+ ];
52
+ export const beatsFor = (turnCount) => {
53
+ if (turnCount <= dialogueBeats.length) {
54
+ return dialogueBeats.slice(0, turnCount);
55
+ }
56
+ return Array.from({ length: turnCount }, (_, index) => dialogueBeats[index % dialogueBeats.length]);
57
+ };
58
+ export const selectVoicesForBeat = (self, beatIndex, count) => {
59
+ const voices = self.voices;
60
+ if (count >= voices.length) {
61
+ return voices;
62
+ }
63
+ return Array.from({ length: count }, (_, offset) => voices[(beatIndex + offset) % voices.length]);
64
+ };
@@ -0,0 +1,36 @@
1
+ import type { WakeEvent } from "../core/types.js";
2
+ import type { MemoryRecallAudit } from "@noopolis/mneme";
3
+ import { PiHarnessAdapter } from "../pi/piHarness.js";
4
+ import type { TriadSelfProfile } from "./jungianTriadProfiles.js";
5
+ export interface PiRepresentativeTurn {
6
+ durationMs: number;
7
+ engine: "pi";
8
+ event: WakeEvent;
9
+ memoryPrepareMs: number;
10
+ memoryRecordMs: number;
11
+ outputChars: number;
12
+ outputText: string;
13
+ promptChars: number;
14
+ recall: MemoryRecallAudit;
15
+ totalMs: number;
16
+ voice: {
17
+ engine: "pi";
18
+ id: string;
19
+ selfId: string;
20
+ };
21
+ }
22
+ export declare const seedPiCodexAuth: (runtimeRoot: string) => Promise<string>;
23
+ export declare class JungianPiRepresentative {
24
+ readonly profile: TriadSelfProfile;
25
+ private readonly adapter;
26
+ private readonly runtimeRoot;
27
+ private readonly instructions;
28
+ private handle;
29
+ readonly runtimeHomePath: string;
30
+ readonly workspacePath: string;
31
+ constructor(profile: TriadSelfProfile, adapter: PiHarnessAdapter, runtimeRoot: string, instructions: string[]);
32
+ prepare(): Promise<void>;
33
+ stop(): Promise<void>;
34
+ wake(event: WakeEvent): Promise<PiRepresentativeTurn>;
35
+ }
36
+ //# sourceMappingURL=jungianPiRepresentative.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"jungianPiRepresentative.d.ts","sourceRoot":"","sources":["../../src/examples/jungianPiRepresentative.ts"],"names":[],"mappings":"AAGA,OAAO,KAAK,EAAe,SAAS,EAAE,MAAM,kBAAkB,CAAC;AAC/D,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,iBAAiB,CAAC;AAEzD,OAAO,EAAE,gBAAgB,EAAE,MAAM,oBAAoB,CAAC;AACtD,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,2BAA2B,CAAC;AAElE,MAAM,WAAW,oBAAoB;IACnC,UAAU,EAAE,MAAM,CAAC;IACnB,MAAM,EAAE,IAAI,CAAC;IACb,KAAK,EAAE,SAAS,CAAC;IACjB,eAAe,EAAE,MAAM,CAAC;IACxB,cAAc,EAAE,MAAM,CAAC;IACvB,WAAW,EAAE,MAAM,CAAC;IACpB,UAAU,EAAE,MAAM,CAAC;IACnB,WAAW,EAAE,MAAM,CAAC;IACpB,MAAM,EAAE,iBAAiB,CAAC;IAC1B,OAAO,EAAE,MAAM,CAAC;IAChB,KAAK,EAAE;QACL,MAAM,EAAE,IAAI,CAAC;QACb,EAAE,EAAE,MAAM,CAAC;QACX,MAAM,EAAE,MAAM,CAAC;KAChB,CAAC;CACH;AAWD,eAAO,MAAM,eAAe,GAAU,aAAa,MAAM,KAAG,OAAO,CAAC,MAAM,CAMzE,CAAC;AAEF,qBAAa,uBAAuB;IAMhC,QAAQ,CAAC,OAAO,EAAE,gBAAgB;IAClC,OAAO,CAAC,QAAQ,CAAC,OAAO;IACxB,OAAO,CAAC,QAAQ,CAAC,WAAW;IAC5B,OAAO,CAAC,QAAQ,CAAC,YAAY;IAR/B,OAAO,CAAC,MAAM,CAA0B;IACxC,QAAQ,CAAC,eAAe,EAAE,MAAM,CAAC;IACjC,QAAQ,CAAC,aAAa,EAAE,MAAM,CAAC;gBAGpB,OAAO,EAAE,gBAAgB,EACjB,OAAO,EAAE,gBAAgB,EACzB,WAAW,EAAE,MAAM,EACnB,YAAY,EAAE,MAAM,EAAE;IAMnC,OAAO,IAAI,OAAO,CAAC,IAAI,CAAC;IAwBxB,IAAI,IAAI,OAAO,CAAC,IAAI,CAAC;IAIrB,IAAI,CAAC,KAAK,EAAE,SAAS,GAAG,OAAO,CAAC,oBAAoB,CAAC;CAuB5D"}
@@ -0,0 +1,81 @@
1
+ import { access, mkdir, writeFile } from "node:fs/promises";
2
+ import path from "node:path";
3
+ import { seedPiOpenAICodexAuthFromCodex } from "../pi/auth.js";
4
+ const emptyRecall = () => ({
5
+ decisions: [],
6
+ redactionCount: 0,
7
+ selected: [],
8
+ selectedEventIds: [],
9
+ tokenBudgetUsed: 0,
10
+ totalCandidates: 0
11
+ });
12
+ export const seedPiCodexAuth = async (runtimeRoot) => {
13
+ const codexAuthPath = path.join(process.env.HOME ?? "", ".codex", "auth.json");
14
+ await access(codexAuthPath);
15
+ const piAuthPath = path.join(runtimeRoot, "auth", "pi-codex-auth.json");
16
+ await seedPiOpenAICodexAuthFromCodex({ codexAuthPath, piAuthPath });
17
+ return piAuthPath;
18
+ };
19
+ export class JungianPiRepresentative {
20
+ profile;
21
+ adapter;
22
+ runtimeRoot;
23
+ instructions;
24
+ handle;
25
+ runtimeHomePath;
26
+ workspacePath;
27
+ constructor(profile, adapter, runtimeRoot, instructions) {
28
+ this.profile = profile;
29
+ this.adapter = adapter;
30
+ this.runtimeRoot = runtimeRoot;
31
+ this.instructions = instructions;
32
+ this.workspacePath = path.join(runtimeRoot, "selves", profile.id, "voices", profile.representative.id, "workspace");
33
+ this.runtimeHomePath = path.join(runtimeRoot, "selves", profile.id, "voices", profile.representative.id, "runtime");
34
+ }
35
+ async prepare() {
36
+ await mkdir(this.workspacePath, { recursive: true });
37
+ await mkdir(this.runtimeHomePath, { recursive: true });
38
+ await writeFile(path.join(this.workspacePath, "AGENTS.md"), [
39
+ `# ${this.profile.representative.name}`,
40
+ "",
41
+ `Self: ${this.profile.name}`,
42
+ "Runtime: Pi with OpenAI Codex subscription auth",
43
+ "",
44
+ "Speak only through the requested SPEAK/STAGE/INNER_USED shape."
45
+ ].join("\n"));
46
+ this.handle = await this.adapter.startAgent({
47
+ id: this.profile.representative.id,
48
+ name: this.profile.representative.name,
49
+ instructions: this.instructions.join("\n"),
50
+ runtimeHomePath: this.runtimeHomePath,
51
+ workspacePath: this.workspacePath,
52
+ tools: []
53
+ });
54
+ }
55
+ async stop() {
56
+ await this.handle?.stop();
57
+ }
58
+ async wake(event) {
59
+ if (!this.handle) {
60
+ throw new Error(`${this.profile.representative.id} was not prepared`);
61
+ }
62
+ const result = await this.handle.wake(event);
63
+ return {
64
+ durationMs: result.durationMs,
65
+ engine: "pi",
66
+ event,
67
+ memoryPrepareMs: 0,
68
+ memoryRecordMs: 0,
69
+ outputChars: result.text.length,
70
+ outputText: result.text,
71
+ promptChars: event.text.length,
72
+ recall: emptyRecall(),
73
+ totalMs: result.durationMs,
74
+ voice: {
75
+ engine: "pi",
76
+ id: this.profile.representative.id,
77
+ selfId: this.profile.id
78
+ }
79
+ };
80
+ }
81
+ }
@@ -0,0 +1,36 @@
1
+ import type { WakeEvent } from "../core/types.js";
2
+ import type { MemoryRecallAudit } from "@noopolis/mneme";
3
+ import { type CliEngineKind as EngineKind, type EngineRunResult } from "../pi/cliSession.js";
4
+ export interface JungianVoiceConfig {
5
+ archetype?: string;
6
+ engine: EngineKind;
7
+ id: string;
8
+ instructions: string[];
9
+ name: string;
10
+ runtimeRoot: string;
11
+ selfId: string;
12
+ selfName: string;
13
+ }
14
+ export interface JungianVoiceTurn {
15
+ engineResult: EngineRunResult;
16
+ event: WakeEvent;
17
+ memoryPrepareMs: number;
18
+ memoryRecordMs: number;
19
+ outputText: string;
20
+ promptText: string;
21
+ recall: MemoryRecallAudit;
22
+ totalMs: number;
23
+ voice: JungianVoiceConfig;
24
+ }
25
+ export declare class JungianVoice {
26
+ readonly config: JungianVoiceConfig;
27
+ readonly runtimeHomePath: string;
28
+ readonly workspacePath: string;
29
+ private readonly memory;
30
+ constructor(config: JungianVoiceConfig);
31
+ prepare(): Promise<void>;
32
+ stop(): Promise<void>;
33
+ wake(event: WakeEvent): Promise<JungianVoiceTurn>;
34
+ }
35
+ export declare const runLimited: <T, R>(values: readonly T[], limit: number, run: (value: T) => Promise<R>) => Promise<R[]>;
36
+ //# sourceMappingURL=jungianPlayAgent.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"jungianPlayAgent.d.ts","sourceRoot":"","sources":["../../src/examples/jungianPlayAgent.ts"],"names":[],"mappings":"AAGA,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,kBAAkB,CAAC;AAElD,OAAO,KAAK,EAAE,iBAAiB,EAAiB,MAAM,iBAAiB,CAAC;AACxE,OAAO,EAAqB,KAAK,aAAa,IAAI,UAAU,EAAE,KAAK,eAAe,EAAE,MAAM,qBAAqB,CAAC;AAEhH,MAAM,WAAW,kBAAkB;IACjC,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,MAAM,EAAE,UAAU,CAAC;IACnB,EAAE,EAAE,MAAM,CAAC;IACX,YAAY,EAAE,MAAM,EAAE,CAAC;IACvB,IAAI,EAAE,MAAM,CAAC;IACb,WAAW,EAAE,MAAM,CAAC;IACpB,MAAM,EAAE,MAAM,CAAC;IACf,QAAQ,EAAE,MAAM,CAAC;CAClB;AAED,MAAM,WAAW,gBAAgB;IAC/B,YAAY,EAAE,eAAe,CAAC;IAC9B,KAAK,EAAE,SAAS,CAAC;IACjB,eAAe,EAAE,MAAM,CAAC;IACxB,cAAc,EAAE,MAAM,CAAC;IACvB,UAAU,EAAE,MAAM,CAAC;IACnB,UAAU,EAAE,MAAM,CAAC;IACnB,MAAM,EAAE,iBAAiB,CAAC;IAC1B,OAAO,EAAE,MAAM,CAAC;IAChB,KAAK,EAAE,kBAAkB,CAAC;CAC3B;AAUD,qBAAa,YAAY;IAKX,QAAQ,CAAC,MAAM,EAAE,kBAAkB;IAJ/C,QAAQ,CAAC,eAAe,EAAE,MAAM,CAAC;IACjC,QAAQ,CAAC,aAAa,EAAE,MAAM,CAAC;IAC/B,OAAO,CAAC,QAAQ,CAAC,MAAM,CAAgB;gBAElB,MAAM,EAAE,kBAAkB;IAWzC,OAAO,IAAI,OAAO,CAAC,IAAI,CAAC;IAkBxB,IAAI,IAAI,OAAO,CAAC,IAAI,CAAC;IAIrB,IAAI,CAAC,KAAK,EAAE,SAAS,GAAG,OAAO,CAAC,gBAAgB,CAAC;CA4DxD;AAED,eAAO,MAAM,UAAU,GAAU,CAAC,EAAE,CAAC,EACnC,QAAQ,SAAS,CAAC,EAAE,EACpB,OAAO,MAAM,EACb,KAAK,CAAC,KAAK,EAAE,CAAC,KAAK,OAAO,CAAC,CAAC,CAAC,KAC5B,OAAO,CAAC,CAAC,EAAE,CAYb,CAAC"}
@@ -0,0 +1,111 @@
1
+ import { mkdir, writeFile } from "node:fs/promises";
2
+ import path from "node:path";
3
+ import { createMemoryRuntime } from "@noopolis/mneme";
4
+ import { runEngineDetailed } from "../pi/cliSession.js";
5
+ const maxMemoryChars = 2200;
6
+ const truncate = (text, maxChars) => text.length <= maxChars ? text : `${text.slice(0, maxChars).trim()}\n[truncated]`;
7
+ const memorySections = (turnPrompt) => truncate(turnPrompt, maxMemoryChars);
8
+ export class JungianVoice {
9
+ config;
10
+ runtimeHomePath;
11
+ workspacePath;
12
+ memory;
13
+ constructor(config) {
14
+ this.config = config;
15
+ this.workspacePath = path.join(config.runtimeRoot, "selves", config.selfId, "voices", config.id, "workspace");
16
+ this.runtimeHomePath = path.join(config.runtimeRoot, "selves", config.selfId, "voices", config.id, "runtime");
17
+ this.memory = createMemoryRuntime({
18
+ agentId: config.id,
19
+ runtimeHomePath: this.runtimeHomePath,
20
+ source: `daimon/jungian-play/${config.engine}`,
21
+ tokenBudget: 2600
22
+ });
23
+ }
24
+ async prepare() {
25
+ await mkdir(this.workspacePath, { recursive: true });
26
+ await mkdir(this.runtimeHomePath, { recursive: true });
27
+ await writeFile(path.join(this.workspacePath, "AGENTS.md"), [
28
+ `# ${this.config.name}`,
29
+ "",
30
+ `Self: ${this.config.selfName}`,
31
+ `Voice: ${this.config.archetype ?? "Representative Self"}`,
32
+ `Engine: ${this.config.engine}`,
33
+ "",
34
+ "This workspace belongs to the Daimon Jungian play E2E.",
35
+ "Do not edit files during the play. Speak only through the requested output shape."
36
+ ].join("\n"));
37
+ }
38
+ async stop() {
39
+ // CLI-backed voices are one-process-per-wake and have no persistent handle.
40
+ }
41
+ async wake(event) {
42
+ const startedAt = Date.now();
43
+ const prepareStartedAt = Date.now();
44
+ const prepared = await this.memory.prepareTurn({
45
+ eventId: event.id,
46
+ kind: event.kind,
47
+ text: event.text,
48
+ from: event.from,
49
+ context: event.context ?? {}
50
+ });
51
+ const memoryPrepareMs = Date.now() - prepareStartedAt;
52
+ const promptText = [
53
+ `${this.config.name} (${this.config.id})`,
54
+ `Self: ${this.config.selfName} (${this.config.selfId})`,
55
+ `Role: ${this.config.archetype ?? "Representative Self"}`,
56
+ "",
57
+ "Standing instructions:",
58
+ ...this.config.instructions.map((line) => `- ${line}`),
59
+ "",
60
+ "Daimon memory packet:",
61
+ memorySections(prepared.promptText),
62
+ "",
63
+ "Current wake:",
64
+ event.text
65
+ ].join("\n");
66
+ const engineResult = await runEngineDetailed(this.config.engine, promptText, {
67
+ runtimeHomePath: this.runtimeHomePath,
68
+ workspacePath: this.workspacePath
69
+ });
70
+ const recordStartedAt = Date.now();
71
+ await this.memory.recordTurn({
72
+ principal: prepared.principal,
73
+ prompt: prepared.packet,
74
+ request: {
75
+ eventId: event.id,
76
+ kind: event.kind,
77
+ text: event.text,
78
+ from: event.from,
79
+ context: event.context ?? {}
80
+ },
81
+ recall: prepared.recall,
82
+ result: "completed",
83
+ outputText: engineResult.text
84
+ });
85
+ const memoryRecordMs = Date.now() - recordStartedAt;
86
+ return {
87
+ engineResult,
88
+ event,
89
+ memoryPrepareMs,
90
+ memoryRecordMs,
91
+ outputText: engineResult.text,
92
+ promptText,
93
+ recall: prepared.recall,
94
+ totalMs: Date.now() - startedAt,
95
+ voice: this.config
96
+ };
97
+ }
98
+ }
99
+ export const runLimited = async (values, limit, run) => {
100
+ const results = [];
101
+ let index = 0;
102
+ const workers = Array.from({ length: Math.min(limit, values.length) }, async () => {
103
+ while (index < values.length) {
104
+ const current = index;
105
+ index += 1;
106
+ results[current] = await run(values[current]);
107
+ }
108
+ });
109
+ await Promise.all(workers);
110
+ return results;
111
+ };
@@ -0,0 +1,34 @@
1
+ import type { CliEngineKind as EngineKind } from "../pi/cliSession.js";
2
+ export interface JungianArchetypeProfile {
3
+ agenda: string;
4
+ archetype: string;
5
+ engine: EngineKind;
6
+ fear: string;
7
+ gift: string;
8
+ id: string;
9
+ name: string;
10
+ wound: string;
11
+ }
12
+ export interface JungianSelfProfile {
13
+ backstory: string;
14
+ conflict: string;
15
+ engine: EngineKind;
16
+ id: string;
17
+ name: string;
18
+ playRole: string;
19
+ publicMask: string;
20
+ representative: {
21
+ id: string;
22
+ name: string;
23
+ style: string;
24
+ };
25
+ secretWant: string;
26
+ voices: JungianArchetypeProfile[];
27
+ }
28
+ export declare const jungianSelves: JungianSelfProfile[];
29
+ export declare const playScenario: {
30
+ title: string;
31
+ premise: string;
32
+ openingImage: string;
33
+ };
34
+ //# sourceMappingURL=jungianProfiles.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"jungianProfiles.d.ts","sourceRoot":"","sources":["../../src/examples/jungianProfiles.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,aAAa,IAAI,UAAU,EAAE,MAAM,qBAAqB,CAAC;AAEvE,MAAM,WAAW,uBAAuB;IACtC,MAAM,EAAE,MAAM,CAAC;IACf,SAAS,EAAE,MAAM,CAAC;IAClB,MAAM,EAAE,UAAU,CAAC;IACnB,IAAI,EAAE,MAAM,CAAC;IACb,IAAI,EAAE,MAAM,CAAC;IACb,EAAE,EAAE,MAAM,CAAC;IACX,IAAI,EAAE,MAAM,CAAC;IACb,KAAK,EAAE,MAAM,CAAC;CACf;AAED,MAAM,WAAW,kBAAkB;IACjC,SAAS,EAAE,MAAM,CAAC;IAClB,QAAQ,EAAE,MAAM,CAAC;IACjB,MAAM,EAAE,UAAU,CAAC;IACnB,EAAE,EAAE,MAAM,CAAC;IACX,IAAI,EAAE,MAAM,CAAC;IACb,QAAQ,EAAE,MAAM,CAAC;IACjB,UAAU,EAAE,MAAM,CAAC;IACnB,cAAc,EAAE;QACd,EAAE,EAAE,MAAM,CAAC;QACX,IAAI,EAAE,MAAM,CAAC;QACb,KAAK,EAAE,MAAM,CAAC;KACf,CAAC;IACF,UAAU,EAAE,MAAM,CAAC;IACnB,MAAM,EAAE,uBAAuB,EAAE,CAAC;CACnC;AA+JD,eAAO,MAAM,aAAa,EAAE,kBAAkB,EAiC7C,CAAC;AAEF,eAAO,MAAM,YAAY;;;;CAMxB,CAAC"}