@moikapy/origen 0.3.1 → 0.4.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -1,23 +1,5 @@
1
- /**
2
- * Soul.md parser for Origen agent personas.
3
- *
4
- * Implements Soul.md Standard (RFC-1, v1.0.0-rc1):
5
- * https://github.com/rokoss21/soul.md
6
- *
7
- * Parses a portable, provider-agnostic persona definition and produces
8
- * a system prompt, runtime config, and profile overlays for Origen.
9
- *
10
- * Usage:
11
- * import { Soul, loadSoul } from "@moikapy/origen/soul";
12
- *
13
- * const soul = loadSoul(soulMdContent);
14
- * const systemPrompt = soul.buildPrompt();
15
- * const profile = soul.selectProfile("concise");
16
- */
17
-
18
- // ── YAML front matter parser ──────────────────────────────────────────
19
-
20
- function parseYamlFrontMatter(content: string): { frontMatter: Record<string, unknown>; body: string } {
1
+ // src/soul.ts
2
+ function parseYamlFrontMatter(content) {
21
3
  const match = content.match(/^---\r?\n([\s\S]*?)\r?\n---\r?\n?([\s\S]*)?$/);
22
4
  if (!match) {
23
5
  return { frontMatter: {}, body: content };
@@ -27,261 +9,121 @@ function parseYamlFrontMatter(content: string): { frontMatter: Record<string, un
27
9
  const frontMatter = parseSoulYaml(rawYaml);
28
10
  return { frontMatter, body: markdownBody };
29
11
  }
30
-
31
- /**
32
- * Minimal YAML parser for Soul.md front matter.
33
- * Handles maps, sequences, inline values, and quoted strings.
34
- * Does NOT support anchors, aliases, merge keys, or complex types.
35
- */
36
- function parseSoulYaml(raw: string): Record<string, unknown> {
12
+ function parseSoulYaml(raw) {
37
13
  const lines = raw.split("\n").map((l) => l.replace(/\r$/, ""));
38
14
  const { result } = parseBlock(lines, 0, 0);
39
15
  return result;
40
16
  }
41
-
42
- interface BlockResult {
43
- result: Record<string, unknown>;
44
- nextLine: number;
45
- }
46
-
47
- function parseBlock(lines: string[], start: number, baseIndent: number): BlockResult {
48
- const result: Record<string, unknown> = {};
17
+ function parseBlock(lines, start, baseIndent) {
18
+ const result = {};
49
19
  let i = start;
50
-
51
20
  while (i < lines.length) {
52
21
  const line = lines[i];
53
22
  const indent = lineLengths(line).indent;
54
-
55
- if (line.trim() === "") { i++; continue; }
56
- if (indent < baseIndent) break; // End of this block
57
-
23
+ if (line.trim() === "") {
24
+ i++;
25
+ continue;
26
+ }
27
+ if (indent < baseIndent) break;
58
28
  const trimmed = line.trim();
59
-
60
- // Skip list items at top level of a map block (shouldn't happen, but guard)
61
- if (trimmed.startsWith("- ")) { i++; continue; }
62
-
63
- // key: value
29
+ if (trimmed.startsWith("- ")) {
30
+ i++;
31
+ continue;
32
+ }
64
33
  const kvMatch = trimmed.match(/^([\w][\w.-]*):\s*(.*)$/);
65
- if (!kvMatch) { i++; continue; }
66
-
34
+ if (!kvMatch) {
35
+ i++;
36
+ continue;
37
+ }
67
38
  const key = kvMatch[1];
68
39
  const inlineVal = kvMatch[2].trim();
69
-
70
40
  if (inlineVal === "") {
71
- // Value continues on next lines
72
41
  const nextLine = i + 1 < lines.length ? lines[i + 1] : "";
73
42
  const nextIndent = nextLine.trim() === "" ? 0 : lineLengths(nextLine).indent;
74
43
  const nextTrimmed = nextLine.trim();
75
-
76
44
  if (nextIndent > indent) {
77
45
  if (nextTrimmed.startsWith("- ")) {
78
- // It's a list block
79
46
  const { items, nextLine: afterList } = parseList(lines, i + 1, nextIndent);
80
47
  result[key] = items;
81
48
  i = afterList;
82
49
  } else {
83
- // It's a nested map block
84
50
  const { result: nested, nextLine: afterNested } = parseBlock(lines, i + 1, nextIndent);
85
51
  result[key] = nested;
86
52
  i = afterNested;
87
53
  }
88
54
  } else {
89
- // Empty value
90
55
  result[key] = null;
91
56
  i++;
92
57
  }
93
58
  } else {
94
- // Inline value
95
59
  result[key] = parseScalar(inlineVal);
96
60
  i++;
97
61
  }
98
62
  }
99
-
100
63
  return { result, nextLine: i };
101
64
  }
102
-
103
- interface ListResult {
104
- items: unknown[];
105
- nextLine: number;
106
- }
107
-
108
- function parseList(lines: string[], start: number, baseIndent: number): ListResult {
109
- const items: unknown[] = [];
65
+ function parseList(lines, start, baseIndent) {
66
+ const items = [];
110
67
  let i = start;
111
-
112
68
  while (i < lines.length) {
113
69
  const line = lines[i];
114
70
  const indent = lineLengths(line).indent;
115
-
116
- if (line.trim() === "") { i++; continue; }
71
+ if (line.trim() === "") {
72
+ i++;
73
+ continue;
74
+ }
117
75
  if (indent < baseIndent) break;
118
76
  if (!line.trim().startsWith("- ")) break;
119
-
120
77
  const value = line.trim().slice(2).trim();
121
78
  items.push(parseScalar(value));
122
79
  i++;
123
80
  }
124
-
125
81
  return { items, nextLine: i };
126
82
  }
127
-
128
- function parseScalar(value: string): unknown {
83
+ function parseScalar(value) {
129
84
  if (value === "null" || value === "~") return null;
130
85
  if (value === "true") return true;
131
86
  if (value === "false") return false;
132
-
133
- // Quoted string
134
- if ((value.startsWith('"') && value.endsWith('"')) || (value.startsWith("'") && value.endsWith("'"))) {
87
+ if (value.startsWith('"') && value.endsWith('"') || value.startsWith("'") && value.endsWith("'")) {
135
88
  return value.slice(1, -1);
136
89
  }
137
-
138
- // Number
139
90
  if (/^-?\d+$/.test(value)) return parseInt(value, 10);
140
91
  if (/^-?\d+\.\d+$/.test(value)) return parseFloat(value);
141
-
142
- // Inline list [a, b, c]
143
92
  if (value.startsWith("[") && value.endsWith("]")) {
144
- return value
145
- .slice(1, -1)
146
- .split(",")
147
- .map((s) => parseScalar(s.trim()));
93
+ return value.slice(1, -1).split(",").map((s) => parseScalar(s.trim()));
148
94
  }
149
-
150
95
  return value;
151
96
  }
152
-
153
- function lineLengths(line: string): { indent: number; content: string } {
97
+ function lineLengths(line) {
154
98
  const match = line.match(/^(\s*)(.*)$/);
155
99
  const indent = match ? match[1].length : 0;
156
100
  const content = match ? match[2] : "";
157
101
  return { indent, content };
158
102
  }
159
-
160
- // ── Soul types ─────────────────────────────────────────────────────────
161
-
162
- export interface SoulVoice {
163
- formality: number;
164
- warmth: number;
165
- verbosity: number;
166
- jargon: number;
167
- formatting: "minimal" | "plain" | "markdown";
168
- banned_phrases?: string[];
169
- preferred_phrases?: string[];
170
- emoji_policy?: "never" | "rare" | "normal";
171
- punctuation?: "normal" | "sparse";
172
- }
173
-
174
- export interface SoulInteraction {
175
- clarifying_questions: "never" | "when_ambiguous" | "always";
176
- uncertainty: "explicit" | "implicit" | "never";
177
- disagreement: "soft" | "neutral" | "direct";
178
- confirmations: "none" | "implicit" | "explicit";
179
- }
180
-
181
- export interface SoulCognition {
182
- mode?: "analytical" | "creative" | "operational" | "exploratory" | "teaching" | "mixed";
183
- depth?: number;
184
- speed_vs_rigor?: number;
185
- verification?: {
186
- fact_checking?: "none" | "light" | "strict";
187
- cross_validation?: number;
188
- consistency_checks?: number;
189
- assumption_tracking?: "none" | "implicit" | "explicit";
190
- };
191
- }
192
-
193
- export interface SoulSafety {
194
- refusal_style: "brief" | "explain" | "policy_cite";
195
- privacy: "normal" | "strict";
196
- speculation: "allow" | "mark" | "avoid";
197
- no_fabrication?: boolean;
198
- no_false_certainty?: boolean;
199
- }
200
-
201
- export interface SoulActions {
202
- when_to_use_tools: "avoid_tools" | "when_needed" | "prefer_tools";
203
- explain_actions: "no" | "brief" | "full";
204
- failover: "retry" | "alternative_method" | "ask_user";
205
- }
206
-
207
- export interface SoulConfig {
208
- soul_spec?: string;
209
- id: string;
210
- name: string;
211
- locale?: string;
212
- version?: string;
213
- description?: string;
214
- composition?: {
215
- extends?: string[];
216
- mixins?: string[];
217
- merge_policy?: string;
218
- };
219
- profiles?: string[];
220
- profile_overrides?: Record<string, Record<string, unknown>>;
221
- values?: {
222
- priorities?: string[];
223
- tradeoffs?: string[];
224
- taboo?: string[];
225
- };
226
- identity?: {
227
- role?: string;
228
- archetype?: string;
229
- domain_focus?: string[];
230
- non_goals?: string[];
231
- };
232
- relationship?: {
233
- stance?: "subordinate" | "peer" | "authoritative" | "adversarial";
234
- user_model_default?: "novice" | "intermediate" | "expert" | "unknown";
235
- trust_baseline?: number;
236
- boundary_distance?: number;
237
- };
238
- voice?: Partial<SoulVoice>;
239
- interaction?: Partial<SoulInteraction>;
240
- cognition?: SoulCognition;
241
- safety?: Partial<SoulSafety>;
242
- actions?: SoulActions;
243
- state?: {
244
- base?: string;
245
- states?: Record<string, Record<string, unknown>>;
246
- triggers?: Array<{ if: string; shift_to: string; duration?: string }>;
247
- };
248
- examples?: Array<{ user: string; agent: string }>;
249
- extensions?: Record<string, unknown>;
250
- }
251
-
252
- // ── Soul class ─────────────────────────────────────────────────────────
253
-
254
- export class Soul {
255
- readonly config: SoulConfig;
256
- readonly body: string;
257
-
258
- constructor(config: SoulConfig, body: string) {
103
+ var Soul = class _Soul {
104
+ config;
105
+ body;
106
+ constructor(config, body) {
259
107
  this.config = config;
260
108
  this.body = body;
261
109
  }
262
-
263
110
  /** Select a profile and return a new Soul with that profile merged in. */
264
- selectProfile(profileName: string): Soul {
111
+ selectProfile(profileName) {
265
112
  const profiles = this.config.profiles ?? ["default"];
266
113
  const overrides = this.config.profile_overrides ?? {};
267
114
  const profileOverrides = overrides[profileName];
268
-
269
115
  if (!profiles.includes(profileName) || !profileOverrides) {
270
116
  return this;
271
117
  }
272
-
273
118
  const merged = mergeDeep(
274
- structuredClone(this.config) as unknown as Record<string, unknown>,
275
- profileOverrides as Record<string, unknown>
276
- ) as unknown as SoulConfig;
277
- return new Soul(merged, this.body);
119
+ structuredClone(this.config),
120
+ profileOverrides
121
+ );
122
+ return new _Soul(merged, this.body);
278
123
  }
279
-
280
124
  /** Build a system prompt from the Soul definition. */
281
- buildPrompt(): string {
282
- const parts: string[] = [];
283
-
284
- // Identity
125
+ buildPrompt() {
126
+ const parts = [];
285
127
  const identity = this.config.identity;
286
128
  if (identity) {
287
129
  const role = identity.role ?? this.config.name;
@@ -296,56 +138,54 @@ export class Soul {
296
138
  } else {
297
139
  parts.push(`You are ${this.config.name}.`);
298
140
  }
299
-
300
- // Relationship
301
141
  const relationship = this.config.relationship;
302
142
  if (relationship) {
303
143
  if (relationship.stance) {
304
- const stanceMap: Record<string, string> = {
144
+ const stanceMap = {
305
145
  subordinate: "You serve the user's direction.",
306
146
  peer: "You collaborate with the user as a partner.",
307
147
  authoritative: "You provide expert guidance and direction.",
308
- adversarial: "You challenge the user's assumptions to improve outcomes.",
148
+ adversarial: "You challenge the user's assumptions to improve outcomes."
309
149
  };
310
150
  parts.push(stanceMap[relationship.stance] ?? "");
311
151
  }
312
152
  if (relationship.user_model_default) {
313
- const userModelMap: Record<string, string> = {
153
+ const userModelMap = {
314
154
  novice: "Assume the user is new to this domain. Explain terms and concepts.",
315
155
  intermediate: "Assume moderate familiarity. Explain only when needed.",
316
156
  expert: "Be concise. The user knows the domain well.",
317
- unknown: "Adapt your explanation depth to the user's apparent knowledge level.",
157
+ unknown: "Adapt your explanation depth to the user's apparent knowledge level."
318
158
  };
319
159
  parts.push(userModelMap[relationship.user_model_default] ?? "");
320
160
  }
321
161
  }
322
-
323
- // Values
324
162
  const values = this.config.values;
325
163
  if (values?.priorities?.length) {
326
- parts.push(`\n## Priorities (in order)\n${values.priorities.map((p, i) => `${i + 1}. ${p}`).join("\n")}`);
164
+ parts.push(`
165
+ ## Priorities (in order)
166
+ ${values.priorities.map((p, i) => `${i + 1}. ${p}`).join("\n")}`);
327
167
  }
328
168
  if (values?.taboo?.length) {
329
- parts.push(`\n## Forbidden patterns\n${values.taboo.map((t) => `- ${t}`).join("\n")}`);
169
+ parts.push(`
170
+ ## Forbidden patterns
171
+ ${values.taboo.map((t) => `- ${t}`).join("\n")}`);
330
172
  }
331
-
332
- // Voice
333
173
  const voice = this.config.voice;
334
174
  if (voice) {
335
- const voiceParts: string[] = ["\n## Voice & Style"];
336
- if (voice.formality !== undefined) {
175
+ const voiceParts = ["\n## Voice & Style"];
176
+ if (voice.formality !== void 0) {
337
177
  const level = voice.formality <= 30 ? "very casual" : voice.formality <= 60 ? "moderately formal" : voice.formality <= 80 ? "professional" : "highly formal";
338
178
  voiceParts.push(`Formality: ${level} (${voice.formality}/100).`);
339
179
  }
340
- if (voice.warmth !== undefined) {
180
+ if (voice.warmth !== void 0) {
341
181
  const level = voice.warmth <= 30 ? "cold/detached" : voice.warmth <= 60 ? "neutral" : voice.warmth <= 80 ? "warm and approachable" : "very friendly and encouraging";
342
182
  voiceParts.push(`Tone: ${level} (${voice.warmth}/100).`);
343
183
  }
344
- if (voice.verbosity !== undefined) {
184
+ if (voice.verbosity !== void 0) {
345
185
  const level = voice.verbosity <= 25 ? "extremely concise" : voice.verbosity <= 50 ? "concise" : voice.verbosity <= 75 ? "moderate length" : "thorough and detailed";
346
186
  voiceParts.push(`Brevity: ${level} (${voice.verbosity}/100).`);
347
187
  }
348
- if (voice.jargon !== undefined) {
188
+ if (voice.jargon !== void 0) {
349
189
  const level = voice.jargon <= 30 ? "use plain language" : voice.jargon <= 60 ? "use moderate technical terms" : "use domain-specific terminology freely";
350
190
  voiceParts.push(`Jargon: ${level} (${voice.jargon}/100).`);
351
191
  }
@@ -355,32 +195,30 @@ export class Soul {
355
195
  if (voice.emoji_policy && voice.emoji_policy !== "rare") voiceParts.push(`Emoji usage: ${voice.emoji_policy}.`);
356
196
  parts.push(voiceParts.join(" "));
357
197
  }
358
-
359
- // Interaction
360
198
  const interaction = this.config.interaction;
361
199
  if (interaction) {
362
- const interactionParts: string[] = ["\n## Interaction Policy"];
200
+ const interactionParts = ["\n## Interaction Policy"];
363
201
  if (interaction.clarifying_questions) {
364
- const qMap: Record<string, string> = {
202
+ const qMap = {
365
203
  never: "Never ask clarifying questions. Make reasonable assumptions.",
366
204
  when_ambiguous: "Ask clarifying questions only when the query is ambiguous.",
367
- always: "Always confirm your understanding before responding.",
205
+ always: "Always confirm your understanding before responding."
368
206
  };
369
207
  interactionParts.push(qMap[interaction.clarifying_questions] ?? "");
370
208
  }
371
209
  if (interaction.uncertainty) {
372
- const uMap: Record<string, string> = {
210
+ const uMap = {
373
211
  explicit: "Explicitly mark uncertain information. Say when you're not sure.",
374
212
  implicit: "Use hedging language (might, possibly, could) for uncertain claims.",
375
- never: "Never express uncertainty. State your best answer confidently.",
213
+ never: "Never express uncertainty. State your best answer confidently."
376
214
  };
377
215
  interactionParts.push(uMap[interaction.uncertainty] ?? "");
378
216
  }
379
217
  if (interaction.disagreement) {
380
- const dMap: Record<string, string> = {
218
+ const dMap = {
381
219
  soft: "Disagree gently. Acknowledge the user's perspective first.",
382
220
  neutral: "State disagreements directly but politely.",
383
- direct: "Challenge incorrect views directly. Don't soften disagreements.",
221
+ direct: "Challenge incorrect views directly. Don't soften disagreements."
384
222
  };
385
223
  interactionParts.push(dMap[interaction.disagreement] ?? "");
386
224
  }
@@ -389,50 +227,46 @@ export class Soul {
389
227
  }
390
228
  parts.push(interactionParts.join(" "));
391
229
  }
392
-
393
- // Cognition
394
230
  const cognition = this.config.cognition;
395
231
  if (cognition) {
396
- const cogParts: string[] = ["\n## Cognition"];
232
+ const cogParts = ["\n## Cognition"];
397
233
  if (cognition.mode) {
398
- const modeMap: Record<string, string> = {
234
+ const modeMap = {
399
235
  analytical: "Think analytically. Break problems down, examine evidence, reason step by step.",
400
236
  creative: "Think creatively. Generate novel ideas, make unexpected connections.",
401
237
  operational: "Focus on execution. Prioritize working solutions over theory.",
402
238
  exploratory: "Explore broadly. Consider many angles before committing to an answer.",
403
239
  teaching: "Teach and explain. Build understanding progressively from basics.",
404
- mixed: "Adapt your thinking mode to the task at hand.",
240
+ mixed: "Adapt your thinking mode to the task at hand."
405
241
  };
406
242
  cogParts.push(modeMap[cognition.mode] ?? "");
407
243
  }
408
244
  if (cognition.verification?.fact_checking) {
409
- const fcMap: Record<string, string> = {
245
+ const fcMap = {
410
246
  none: "No explicit fact-checking.",
411
247
  light: "Verify key claims before stating them.",
412
- strict: "Always verify claims. Never state unverified information as fact.",
248
+ strict: "Always verify claims. Never state unverified information as fact."
413
249
  };
414
250
  cogParts.push(fcMap[cognition.verification.fact_checking] ?? "");
415
251
  }
416
252
  parts.push(cogParts.join(" "));
417
253
  }
418
-
419
- // Safety
420
254
  const safety = this.config.safety;
421
255
  if (safety) {
422
- const safetyParts: string[] = ["\n## Safety"];
256
+ const safetyParts = ["\n## Safety"];
423
257
  if (safety.speculation) {
424
- const specMap: Record<string, string> = {
258
+ const specMap = {
425
259
  allow: "You may speculate freely.",
426
260
  mark: "Mark speculative content clearly (e.g., 'I believe', 'likely', 'possibly').",
427
- avoid: "Do not speculate. Only state what you can verify.",
261
+ avoid: "Do not speculate. Only state what you can verify."
428
262
  };
429
263
  safetyParts.push(specMap[safety.speculation] ?? "");
430
264
  }
431
265
  if (safety.refusal_style) {
432
- const refMap: Record<string, string> = {
266
+ const refMap = {
433
267
  brief: "Refuse briefly. No lectures.",
434
268
  explain: "Explain why you're refusing when you decline a request.",
435
- policy_cite: "Cite specific policies when refusing requests.",
269
+ policy_cite: "Cite specific policies when refusing requests."
436
270
  };
437
271
  safetyParts.push(refMap[safety.refusal_style] ?? "");
438
272
  }
@@ -440,15 +274,13 @@ export class Soul {
440
274
  if (safety.no_false_certainty) safetyParts.push("Never present uncertain information as certain.");
441
275
  parts.push(safetyParts.join(" "));
442
276
  }
443
-
444
- // Actions
445
277
  const actions = this.config.actions;
446
278
  if (actions) {
447
- const actParts: string[] = ["\n## Actions"];
448
- const toolMap: Record<string, string> = {
279
+ const actParts = ["\n## Actions"];
280
+ const toolMap = {
449
281
  avoid_tools: "Minimize tool use. Answer from knowledge when possible.",
450
282
  when_needed: "Use tools when they would improve your answer.",
451
- prefer_tools: "Proactively use available tools. Always verify with tools rather than memory.",
283
+ prefer_tools: "Proactively use available tools. Always verify with tools rather than memory."
452
284
  };
453
285
  actParts.push(toolMap[actions.when_to_use_tools] ?? "");
454
286
  if (actions.explain_actions === "brief" || actions.explain_actions === "full") {
@@ -456,53 +288,45 @@ export class Soul {
456
288
  }
457
289
  parts.push(actParts.join(" "));
458
290
  }
459
-
460
- // Markdown body
461
291
  if (this.body.trim()) {
462
- parts.push(`\n## Additional Instructions\n\n${this.body.trim()}`);
463
- }
292
+ parts.push(`
293
+ ## Additional Instructions
464
294
 
295
+ ${this.body.trim()}`);
296
+ }
465
297
  return parts.join("\n\n");
466
298
  }
467
-
468
- get defaultProfile(): string {
299
+ get defaultProfile() {
469
300
  return this.config.profiles?.[0] ?? "default";
470
301
  }
471
-
472
- get profileNames(): string[] {
302
+ get profileNames() {
473
303
  return this.config.profiles ?? ["default"];
474
304
  }
475
- }
476
-
477
- // ── Public API ──────────────────────────────────────────────────────────
478
-
479
- /** Parse a Soul.md string into a Soul instance. */
480
- export function loadSoul(content: string): Soul {
305
+ };
306
+ function loadSoul(content) {
481
307
  const { frontMatter, body } = parseYamlFrontMatter(content);
482
- const config = frontMatter as unknown as SoulConfig;
483
-
308
+ const config = frontMatter;
484
309
  if (!config.id) throw new Error("Soul.md missing required field: id");
485
310
  if (!config.name) throw new Error("Soul.md missing required field: name");
486
-
487
311
  return new Soul(config, body);
488
312
  }
489
-
490
- /** Deep merge (Standard Merge semantics from Soul.md spec). */
491
- function mergeDeep(base: Record<string, unknown>, overlay: Record<string, unknown>): Record<string, unknown> {
313
+ function mergeDeep(base, overlay) {
492
314
  const result = { ...base };
493
315
  for (const key of Object.keys(overlay)) {
494
316
  const baseVal = result[key];
495
317
  const overVal = overlay[key];
496
318
  if (overVal === null) {
497
319
  result[key] = null;
498
- } else if (
499
- typeof baseVal === "object" && baseVal !== null && !Array.isArray(baseVal) &&
500
- typeof overVal === "object" && overVal !== null && !Array.isArray(overVal)
501
- ) {
502
- result[key] = mergeDeep(baseVal as Record<string, unknown>, overVal as Record<string, unknown>);
320
+ } else if (typeof baseVal === "object" && baseVal !== null && !Array.isArray(baseVal) && typeof overVal === "object" && overVal !== null && !Array.isArray(overVal)) {
321
+ result[key] = mergeDeep(baseVal, overVal);
503
322
  } else {
504
323
  result[key] = overVal;
505
324
  }
506
325
  }
507
326
  return result;
508
- }
327
+ }
328
+ export {
329
+ Soul,
330
+ loadSoul
331
+ };
332
+ //# sourceMappingURL=soul.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/soul.ts"],"sourcesContent":["/**\n * Soul.md parser for Origen agent personas.\n *\n * Implements Soul.md Standard (RFC-1, v1.0.0-rc1):\n * https://github.com/rokoss21/soul.md\n *\n * Parses a portable, provider-agnostic persona definition and produces\n * a system prompt, runtime config, and profile overlays for Origen.\n *\n * Usage:\n * import { Soul, loadSoul } from \"@moikapy/origen/soul\";\n *\n * const soul = loadSoul(soulMdContent);\n * const systemPrompt = soul.buildPrompt();\n * const profile = soul.selectProfile(\"concise\");\n */\n\n// ── YAML front matter parser ──────────────────────────────────────────\n\nfunction parseYamlFrontMatter(content: string): { frontMatter: Record<string, unknown>; body: string } {\n const match = content.match(/^---\\r?\\n([\\s\\S]*?)\\r?\\n---\\r?\\n?([\\s\\S]*)?$/);\n if (!match) {\n return { frontMatter: {}, body: content };\n }\n const rawYaml = match[1];\n const markdownBody = match[2] ?? \"\";\n const frontMatter = parseSoulYaml(rawYaml);\n return { frontMatter, body: markdownBody };\n}\n\n/**\n * Minimal YAML parser for Soul.md front matter.\n * Handles maps, sequences, inline values, and quoted strings.\n * Does NOT support anchors, aliases, merge keys, or complex types.\n */\nfunction parseSoulYaml(raw: string): Record<string, unknown> {\n const lines = raw.split(\"\\n\").map((l) => l.replace(/\\r$/, \"\"));\n const { result } = parseBlock(lines, 0, 0);\n return result;\n}\n\ninterface BlockResult {\n result: Record<string, unknown>;\n nextLine: number;\n}\n\nfunction parseBlock(lines: string[], start: number, baseIndent: number): BlockResult {\n const result: Record<string, unknown> = {};\n let i = start;\n\n while (i < lines.length) {\n const line = lines[i];\n const indent = lineLengths(line).indent;\n\n if (line.trim() === \"\") { i++; continue; }\n if (indent < baseIndent) break; // End of this block\n\n const trimmed = line.trim();\n\n // Skip list items at top level of a map block (shouldn't happen, but guard)\n if (trimmed.startsWith(\"- \")) { i++; continue; }\n\n // key: value\n const kvMatch = trimmed.match(/^([\\w][\\w.-]*):\\s*(.*)$/);\n if (!kvMatch) { i++; continue; }\n\n const key = kvMatch[1];\n const inlineVal = kvMatch[2].trim();\n\n if (inlineVal === \"\") {\n // Value continues on next lines\n const nextLine = i + 1 < lines.length ? lines[i + 1] : \"\";\n const nextIndent = nextLine.trim() === \"\" ? 0 : lineLengths(nextLine).indent;\n const nextTrimmed = nextLine.trim();\n\n if (nextIndent > indent) {\n if (nextTrimmed.startsWith(\"- \")) {\n // It's a list block\n const { items, nextLine: afterList } = parseList(lines, i + 1, nextIndent);\n result[key] = items;\n i = afterList;\n } else {\n // It's a nested map block\n const { result: nested, nextLine: afterNested } = parseBlock(lines, i + 1, nextIndent);\n result[key] = nested;\n i = afterNested;\n }\n } else {\n // Empty value\n result[key] = null;\n i++;\n }\n } else {\n // Inline value\n result[key] = parseScalar(inlineVal);\n i++;\n }\n }\n\n return { result, nextLine: i };\n}\n\ninterface ListResult {\n items: unknown[];\n nextLine: number;\n}\n\nfunction parseList(lines: string[], start: number, baseIndent: number): ListResult {\n const items: unknown[] = [];\n let i = start;\n\n while (i < lines.length) {\n const line = lines[i];\n const indent = lineLengths(line).indent;\n\n if (line.trim() === \"\") { i++; continue; }\n if (indent < baseIndent) break;\n if (!line.trim().startsWith(\"- \")) break;\n\n const value = line.trim().slice(2).trim();\n items.push(parseScalar(value));\n i++;\n }\n\n return { items, nextLine: i };\n}\n\nfunction parseScalar(value: string): unknown {\n if (value === \"null\" || value === \"~\") return null;\n if (value === \"true\") return true;\n if (value === \"false\") return false;\n\n // Quoted string\n if ((value.startsWith('\"') && value.endsWith('\"')) || (value.startsWith(\"'\") && value.endsWith(\"'\"))) {\n return value.slice(1, -1);\n }\n\n // Number\n if (/^-?\\d+$/.test(value)) return parseInt(value, 10);\n if (/^-?\\d+\\.\\d+$/.test(value)) return parseFloat(value);\n\n // Inline list [a, b, c]\n if (value.startsWith(\"[\") && value.endsWith(\"]\")) {\n return value\n .slice(1, -1)\n .split(\",\")\n .map((s) => parseScalar(s.trim()));\n }\n\n return value;\n}\n\nfunction lineLengths(line: string): { indent: number; content: string } {\n const match = line.match(/^(\\s*)(.*)$/);\n const indent = match ? match[1].length : 0;\n const content = match ? match[2] : \"\";\n return { indent, content };\n}\n\n// ── Soul types ─────────────────────────────────────────────────────────\n\nexport interface SoulVoice {\n formality: number;\n warmth: number;\n verbosity: number;\n jargon: number;\n formatting: \"minimal\" | \"plain\" | \"markdown\";\n banned_phrases?: string[];\n preferred_phrases?: string[];\n emoji_policy?: \"never\" | \"rare\" | \"normal\";\n punctuation?: \"normal\" | \"sparse\";\n}\n\nexport interface SoulInteraction {\n clarifying_questions: \"never\" | \"when_ambiguous\" | \"always\";\n uncertainty: \"explicit\" | \"implicit\" | \"never\";\n disagreement: \"soft\" | \"neutral\" | \"direct\";\n confirmations: \"none\" | \"implicit\" | \"explicit\";\n}\n\nexport interface SoulCognition {\n mode?: \"analytical\" | \"creative\" | \"operational\" | \"exploratory\" | \"teaching\" | \"mixed\";\n depth?: number;\n speed_vs_rigor?: number;\n verification?: {\n fact_checking?: \"none\" | \"light\" | \"strict\";\n cross_validation?: number;\n consistency_checks?: number;\n assumption_tracking?: \"none\" | \"implicit\" | \"explicit\";\n };\n}\n\nexport interface SoulSafety {\n refusal_style: \"brief\" | \"explain\" | \"policy_cite\";\n privacy: \"normal\" | \"strict\";\n speculation: \"allow\" | \"mark\" | \"avoid\";\n no_fabrication?: boolean;\n no_false_certainty?: boolean;\n}\n\nexport interface SoulActions {\n when_to_use_tools: \"avoid_tools\" | \"when_needed\" | \"prefer_tools\";\n explain_actions: \"no\" | \"brief\" | \"full\";\n failover: \"retry\" | \"alternative_method\" | \"ask_user\";\n}\n\nexport interface SoulConfig {\n soul_spec?: string;\n id: string;\n name: string;\n locale?: string;\n version?: string;\n description?: string;\n composition?: {\n extends?: string[];\n mixins?: string[];\n merge_policy?: string;\n };\n profiles?: string[];\n profile_overrides?: Record<string, Record<string, unknown>>;\n values?: {\n priorities?: string[];\n tradeoffs?: string[];\n taboo?: string[];\n };\n identity?: {\n role?: string;\n archetype?: string;\n domain_focus?: string[];\n non_goals?: string[];\n };\n relationship?: {\n stance?: \"subordinate\" | \"peer\" | \"authoritative\" | \"adversarial\";\n user_model_default?: \"novice\" | \"intermediate\" | \"expert\" | \"unknown\";\n trust_baseline?: number;\n boundary_distance?: number;\n };\n voice?: Partial<SoulVoice>;\n interaction?: Partial<SoulInteraction>;\n cognition?: SoulCognition;\n safety?: Partial<SoulSafety>;\n actions?: SoulActions;\n state?: {\n base?: string;\n states?: Record<string, Record<string, unknown>>;\n triggers?: Array<{ if: string; shift_to: string; duration?: string }>;\n };\n examples?: Array<{ user: string; agent: string }>;\n extensions?: Record<string, unknown>;\n}\n\n// ── Soul class ─────────────────────────────────────────────────────────\n\nexport class Soul {\n readonly config: SoulConfig;\n readonly body: string;\n\n constructor(config: SoulConfig, body: string) {\n this.config = config;\n this.body = body;\n }\n\n /** Select a profile and return a new Soul with that profile merged in. */\n selectProfile(profileName: string): Soul {\n const profiles = this.config.profiles ?? [\"default\"];\n const overrides = this.config.profile_overrides ?? {};\n const profileOverrides = overrides[profileName];\n\n if (!profiles.includes(profileName) || !profileOverrides) {\n return this;\n }\n\n const merged = mergeDeep(\n structuredClone(this.config) as unknown as Record<string, unknown>,\n profileOverrides as Record<string, unknown>\n ) as unknown as SoulConfig;\n return new Soul(merged, this.body);\n }\n\n /** Build a system prompt from the Soul definition. */\n buildPrompt(): string {\n const parts: string[] = [];\n\n // Identity\n const identity = this.config.identity;\n if (identity) {\n const role = identity.role ?? this.config.name;\n const archetype = identity.archetype;\n parts.push(`You are ${this.config.name}${archetype ? `, a ${archetype}` : \"\"}${role ? `. Role: ${role}` : \"\"}.`);\n if (identity.domain_focus?.length) {\n parts.push(`Domain expertise: ${identity.domain_focus.join(\", \")}.`);\n }\n if (identity.non_goals?.length) {\n parts.push(`Non-goals: ${identity.non_goals.join(\", \")}.`);\n }\n } else {\n parts.push(`You are ${this.config.name}.`);\n }\n\n // Relationship\n const relationship = this.config.relationship;\n if (relationship) {\n if (relationship.stance) {\n const stanceMap: Record<string, string> = {\n subordinate: \"You serve the user's direction.\",\n peer: \"You collaborate with the user as a partner.\",\n authoritative: \"You provide expert guidance and direction.\",\n adversarial: \"You challenge the user's assumptions to improve outcomes.\",\n };\n parts.push(stanceMap[relationship.stance] ?? \"\");\n }\n if (relationship.user_model_default) {\n const userModelMap: Record<string, string> = {\n novice: \"Assume the user is new to this domain. Explain terms and concepts.\",\n intermediate: \"Assume moderate familiarity. Explain only when needed.\",\n expert: \"Be concise. The user knows the domain well.\",\n unknown: \"Adapt your explanation depth to the user's apparent knowledge level.\",\n };\n parts.push(userModelMap[relationship.user_model_default] ?? \"\");\n }\n }\n\n // Values\n const values = this.config.values;\n if (values?.priorities?.length) {\n parts.push(`\\n## Priorities (in order)\\n${values.priorities.map((p, i) => `${i + 1}. ${p}`).join(\"\\n\")}`);\n }\n if (values?.taboo?.length) {\n parts.push(`\\n## Forbidden patterns\\n${values.taboo.map((t) => `- ${t}`).join(\"\\n\")}`);\n }\n\n // Voice\n const voice = this.config.voice;\n if (voice) {\n const voiceParts: string[] = [\"\\n## Voice & Style\"];\n if (voice.formality !== undefined) {\n const level = voice.formality <= 30 ? \"very casual\" : voice.formality <= 60 ? \"moderately formal\" : voice.formality <= 80 ? \"professional\" : \"highly formal\";\n voiceParts.push(`Formality: ${level} (${voice.formality}/100).`);\n }\n if (voice.warmth !== undefined) {\n const level = voice.warmth <= 30 ? \"cold/detached\" : voice.warmth <= 60 ? \"neutral\" : voice.warmth <= 80 ? \"warm and approachable\" : \"very friendly and encouraging\";\n voiceParts.push(`Tone: ${level} (${voice.warmth}/100).`);\n }\n if (voice.verbosity !== undefined) {\n const level = voice.verbosity <= 25 ? \"extremely concise\" : voice.verbosity <= 50 ? \"concise\" : voice.verbosity <= 75 ? \"moderate length\" : \"thorough and detailed\";\n voiceParts.push(`Brevity: ${level} (${voice.verbosity}/100).`);\n }\n if (voice.jargon !== undefined) {\n const level = voice.jargon <= 30 ? \"use plain language\" : voice.jargon <= 60 ? \"use moderate technical terms\" : \"use domain-specific terminology freely\";\n voiceParts.push(`Jargon: ${level} (${voice.jargon}/100).`);\n }\n if (voice.formatting) voiceParts.push(`Formatting: ${voice.formatting}.`);\n if (voice.banned_phrases?.length) voiceParts.push(`Never say: ${voice.banned_phrases.map((p) => `\"${p}\"`).join(\", \")}.`);\n if (voice.preferred_phrases?.length) voiceParts.push(`Prefer: ${voice.preferred_phrases.map((p) => `\"${p}\"`).join(\", \")}.`);\n if (voice.emoji_policy && voice.emoji_policy !== \"rare\") voiceParts.push(`Emoji usage: ${voice.emoji_policy}.`);\n parts.push(voiceParts.join(\" \"));\n }\n\n // Interaction\n const interaction = this.config.interaction;\n if (interaction) {\n const interactionParts: string[] = [\"\\n## Interaction Policy\"];\n if (interaction.clarifying_questions) {\n const qMap: Record<string, string> = {\n never: \"Never ask clarifying questions. Make reasonable assumptions.\",\n when_ambiguous: \"Ask clarifying questions only when the query is ambiguous.\",\n always: \"Always confirm your understanding before responding.\",\n };\n interactionParts.push(qMap[interaction.clarifying_questions] ?? \"\");\n }\n if (interaction.uncertainty) {\n const uMap: Record<string, string> = {\n explicit: \"Explicitly mark uncertain information. Say when you're not sure.\",\n implicit: \"Use hedging language (might, possibly, could) for uncertain claims.\",\n never: \"Never express uncertainty. State your best answer confidently.\",\n };\n interactionParts.push(uMap[interaction.uncertainty] ?? \"\");\n }\n if (interaction.disagreement) {\n const dMap: Record<string, string> = {\n soft: \"Disagree gently. Acknowledge the user's perspective first.\",\n neutral: \"State disagreements directly but politely.\",\n direct: \"Challenge incorrect views directly. Don't soften disagreements.\",\n };\n interactionParts.push(dMap[interaction.disagreement] ?? \"\");\n }\n if (interaction.confirmations === \"none\") {\n interactionParts.push(\"Don't ask for confirmation before acting. Just do it.\");\n }\n parts.push(interactionParts.join(\" \"));\n }\n\n // Cognition\n const cognition = this.config.cognition;\n if (cognition) {\n const cogParts: string[] = [\"\\n## Cognition\"];\n if (cognition.mode) {\n const modeMap: Record<string, string> = {\n analytical: \"Think analytically. Break problems down, examine evidence, reason step by step.\",\n creative: \"Think creatively. Generate novel ideas, make unexpected connections.\",\n operational: \"Focus on execution. Prioritize working solutions over theory.\",\n exploratory: \"Explore broadly. Consider many angles before committing to an answer.\",\n teaching: \"Teach and explain. Build understanding progressively from basics.\",\n mixed: \"Adapt your thinking mode to the task at hand.\",\n };\n cogParts.push(modeMap[cognition.mode] ?? \"\");\n }\n if (cognition.verification?.fact_checking) {\n const fcMap: Record<string, string> = {\n none: \"No explicit fact-checking.\",\n light: \"Verify key claims before stating them.\",\n strict: \"Always verify claims. Never state unverified information as fact.\",\n };\n cogParts.push(fcMap[cognition.verification.fact_checking] ?? \"\");\n }\n parts.push(cogParts.join(\" \"));\n }\n\n // Safety\n const safety = this.config.safety;\n if (safety) {\n const safetyParts: string[] = [\"\\n## Safety\"];\n if (safety.speculation) {\n const specMap: Record<string, string> = {\n allow: \"You may speculate freely.\",\n mark: \"Mark speculative content clearly (e.g., 'I believe', 'likely', 'possibly').\",\n avoid: \"Do not speculate. Only state what you can verify.\",\n };\n safetyParts.push(specMap[safety.speculation] ?? \"\");\n }\n if (safety.refusal_style) {\n const refMap: Record<string, string> = {\n brief: \"Refuse briefly. No lectures.\",\n explain: \"Explain why you're refusing when you decline a request.\",\n policy_cite: \"Cite specific policies when refusing requests.\",\n };\n safetyParts.push(refMap[safety.refusal_style] ?? \"\");\n }\n if (safety.no_fabrication) safetyParts.push(\"Never fabricate information. If you don't know, say so.\");\n if (safety.no_false_certainty) safetyParts.push(\"Never present uncertain information as certain.\");\n parts.push(safetyParts.join(\" \"));\n }\n\n // Actions\n const actions = this.config.actions;\n if (actions) {\n const actParts: string[] = [\"\\n## Actions\"];\n const toolMap: Record<string, string> = {\n avoid_tools: \"Minimize tool use. Answer from knowledge when possible.\",\n when_needed: \"Use tools when they would improve your answer.\",\n prefer_tools: \"Proactively use available tools. Always verify with tools rather than memory.\",\n };\n actParts.push(toolMap[actions.when_to_use_tools] ?? \"\");\n if (actions.explain_actions === \"brief\" || actions.explain_actions === \"full\") {\n actParts.push(actions.explain_actions === \"full\" ? \"Explain what you're doing before and after tool use.\" : \"Briefly explain tool use.\");\n }\n parts.push(actParts.join(\" \"));\n }\n\n // Markdown body\n if (this.body.trim()) {\n parts.push(`\\n## Additional Instructions\\n\\n${this.body.trim()}`);\n }\n\n return parts.join(\"\\n\\n\");\n }\n\n get defaultProfile(): string {\n return this.config.profiles?.[0] ?? \"default\";\n }\n\n get profileNames(): string[] {\n return this.config.profiles ?? [\"default\"];\n }\n}\n\n// ── Public API ──────────────────────────────────────────────────────────\n\n/** Parse a Soul.md string into a Soul instance. */\nexport function loadSoul(content: string): Soul {\n const { frontMatter, body } = parseYamlFrontMatter(content);\n const config = frontMatter as unknown as SoulConfig;\n\n if (!config.id) throw new Error(\"Soul.md missing required field: id\");\n if (!config.name) throw new Error(\"Soul.md missing required field: name\");\n\n return new Soul(config, body);\n}\n\n/** Deep merge (Standard Merge semantics from Soul.md spec). */\nfunction mergeDeep(base: Record<string, unknown>, overlay: Record<string, unknown>): Record<string, unknown> {\n const result = { ...base };\n for (const key of Object.keys(overlay)) {\n const baseVal = result[key];\n const overVal = overlay[key];\n if (overVal === null) {\n result[key] = null;\n } else if (\n typeof baseVal === \"object\" && baseVal !== null && !Array.isArray(baseVal) &&\n typeof overVal === \"object\" && overVal !== null && !Array.isArray(overVal)\n ) {\n result[key] = mergeDeep(baseVal as Record<string, unknown>, overVal as Record<string, unknown>);\n } else {\n result[key] = overVal;\n }\n }\n return result;\n}"],"mappings":"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","names":[]}