@caupulican/pi-adaptative 0.80.63 → 0.80.65

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.
@@ -805,6 +805,16 @@ export class AgentSession {
805
805
  }
806
806
  return Array.from(unique);
807
807
  }
808
+ /**
809
+ * R6: the active profile's situational soul, wrapped so the model reads it as its identity for this
810
+ * situation. Empty when no active profile defines a soul.
811
+ */
812
+ _buildSituationSoulPrompt() {
813
+ const soul = this.settingsManager.getActiveProfileSoul();
814
+ if (!soul)
815
+ return undefined;
816
+ return `<situation_soul>\n${soul}\n</situation_soul>`;
817
+ }
808
818
  _buildSelfModificationPrompt() {
809
819
  const settings = this.settingsManager.getSelfModificationSettings();
810
820
  if (!settings.enabled) {
@@ -883,6 +893,9 @@ export class AgentSession {
883
893
  const loaderSystemPrompt = this._resourceLoader.getSystemPrompt();
884
894
  const loaderAppendSystemPrompt = this._resourceLoader.getAppendSystemPrompt();
885
895
  const appendSystemPromptParts = [
896
+ // R6: situational soul — the active profile's identity prefix, switched atomically with the
897
+ // profile's capabilities/model. Most prominent, so it comes first.
898
+ this._buildSituationSoulPrompt(),
886
899
  this._buildSelfModificationPrompt(),
887
900
  this._buildAutonomyPrompt(),
888
901
  // Memory subsystem: static, frozen-per-session block (e.g. file-store MEMORY.md/USER.md).
@@ -3376,6 +3389,12 @@ export class AgentSession {
3376
3389
  * isn't found there. Best-effort: failures are swallowed (reflection must never break a turn).
3377
3390
  */
3378
3391
  async _applyReflectionWrite(write, signal) {
3392
+ // R7 memory-to-behavior: a recurring procedure is compiled into an executable skill file rather
3393
+ // than stored as a flat fact. Written under the agent skills dir so it loads like any user skill.
3394
+ if (write.kind === "promote_skill") {
3395
+ this._promoteReflectionSkill(write.name, write.description, write.body);
3396
+ return;
3397
+ }
3379
3398
  const memTool = this._memoryManager.getToolDefinitions().find((t) => t.name === "memory");
3380
3399
  const exec = memTool?.execute;
3381
3400
  if (!exec)
@@ -3411,6 +3430,33 @@ export class AgentSession {
3411
3430
  }
3412
3431
  }
3413
3432
  }
3433
+ /**
3434
+ * R7: write a reflection-promoted skill as `<agentDir>/skills/<name>/SKILL.md` so it loads like any
3435
+ * user skill. Best-effort; never clobbers an existing (hand-authored) skill of the same name.
3436
+ */
3437
+ _promoteReflectionSkill(rawName, description, body) {
3438
+ const name = rawName
3439
+ .trim()
3440
+ .toLowerCase()
3441
+ .replace(/[^a-z0-9-]+/g, "-")
3442
+ .replace(/^-+|-+$/g, "")
3443
+ .slice(0, 64);
3444
+ if (!name || !body.trim())
3445
+ return;
3446
+ try {
3447
+ const dir = join(this._agentDir, "skills", name);
3448
+ const file = join(dir, "SKILL.md");
3449
+ if (existsSync(file))
3450
+ return; // do not overwrite an existing skill
3451
+ mkdirSync(dir, { recursive: true });
3452
+ const safeDescription = description.replace(/[\r\n]+/g, " ").trim();
3453
+ const content = `---\nname: ${name}\ndescription: ${safeDescription}\n---\n\n<!-- Auto-generated by the reflection engine (R7 memory-to-behavior). Review and refine. -->\n\n${body.trim()}\n`;
3454
+ writeFileSync(file, content, "utf-8");
3455
+ }
3456
+ catch {
3457
+ // promotion must never break a turn
3458
+ }
3459
+ }
3414
3460
  getContextUsage() {
3415
3461
  const model = this.model;
3416
3462
  if (!model)