@caupulican/pi-adaptative 0.80.64 → 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.
- package/CHANGELOG.md +6 -0
- package/dist/core/agent-session.d.ts +5 -0
- package/dist/core/agent-session.d.ts.map +1 -1
- package/dist/core/agent-session.js +33 -0
- package/dist/core/agent-session.js.map +1 -1
- package/dist/core/learning/reflection-engine.d.ts +5 -0
- package/dist/core/learning/reflection-engine.d.ts.map +1 -1
- package/dist/core/learning/reflection-engine.js +9 -1
- package/dist/core/learning/reflection-engine.js.map +1 -1
- package/examples/extensions/custom-provider-anthropic/package-lock.json +2 -2
- package/examples/extensions/custom-provider-anthropic/package.json +1 -1
- package/examples/extensions/custom-provider-gitlab-duo/package.json +1 -1
- package/examples/extensions/sandbox/package-lock.json +2 -2
- package/examples/extensions/sandbox/package.json +1 -1
- package/examples/extensions/with-deps/package-lock.json +2 -2
- package/examples/extensions/with-deps/package.json +1 -1
- package/npm-shrinkwrap.json +12 -12
- package/package.json +4 -4
|
@@ -40,6 +40,11 @@ export type ReflectionWrite = {
|
|
|
40
40
|
} | {
|
|
41
41
|
kind: "memory_remove";
|
|
42
42
|
target: string;
|
|
43
|
+
} | {
|
|
44
|
+
kind: "promote_skill";
|
|
45
|
+
name: string;
|
|
46
|
+
description: string;
|
|
47
|
+
body: string;
|
|
43
48
|
};
|
|
44
49
|
export interface ReflectionResult {
|
|
45
50
|
writes: ReflectionWrite[];
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"reflection-engine.d.ts","sourceRoot":"","sources":["../../../src/core/learning/reflection-engine.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,KAAK,EAAE,MAAM,mBAAmB,CAAC;AAE/C,MAAM,MAAM,UAAU,GAAG,MAAM,GAAG,SAAS,GAAG,SAAS,GAAG,OAAO,GAAG,MAAM,CAAC;AAE3E,MAAM,WAAW,wBAAwB;IACxC,IAAI,EAAE,MAAM,CAAC;IACb,KAAK,EAAE,KAAK,CAAC;IACb,UAAU,EAAE,UAAU,CAAC;CACvB;AAED,MAAM,MAAM,iBAAiB,GAAG,SAAS,GAAG,YAAY,GAAG,aAAa,GAAG,MAAM,CAAC;AAElF,MAAM,WAAW,aAAa;IAC7B,OAAO,EAAE,iBAAiB,CAAC;IAC3B,aAAa,EAAE,MAAM,CAAC;IACtB,aAAa,EAAE,OAAO,CAAC;IACvB,kBAAkB,EAAE,MAAM,CAAC;IAC3B,YAAY,EAAE,MAAM,CAAC;CACrB;AAED,MAAM,WAAW,UAAU;IAC1B,GAAG,EAAE,MAAM,GAAG,SAAS,CAAC;IACxB,MAAM,EAAE,MAAM,CAAC;IACf,WAAW,EAAE,MAAM,CAAC;CACpB;AAED;;;GAGG;AACH,wBAAgB,YAAY,CAAC,OAAO,EAAE,aAAa,GAAG,UAAU,CAyB/D;AAED,MAAM,WAAW,eAAe;IAC/B,cAAc,EAAE,MAAM,CAAC;IACvB,cAAc,EAAE,MAAM,CAAC;IACvB,IAAI,EAAE,UAAU,CAAC;IAEjB,QAAQ,EAAE,CAAC,YAAY,EAAE,MAAM,EAAE,UAAU,EAAE,MAAM,KAAK,OAAO,CAAC,wBAAwB,CAAC,CAAC;CAC1F;AAED,MAAM,MAAM,eAAe,GACxB;IAAE,IAAI,EAAE,YAAY,CAAC;IAAC,OAAO,EAAE,QAAQ,GAAG,MAAM,CAAC;IAAC,IAAI,EAAE,MAAM,CAAA;CAAE,GAChE;IAAE,IAAI,EAAE,gBAAgB,CAAC;IAAC,MAAM,EAAE,MAAM,CAAC;IAAC,IAAI,EAAE,MAAM,CAAA;CAAE,GACxD;IAAE,IAAI,EAAE,eAAe,CAAC;IAAC,MAAM,EAAE,MAAM,CAAA;CAAE,CAAC;
|
|
1
|
+
{"version":3,"file":"reflection-engine.d.ts","sourceRoot":"","sources":["../../../src/core/learning/reflection-engine.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,KAAK,EAAE,MAAM,mBAAmB,CAAC;AAE/C,MAAM,MAAM,UAAU,GAAG,MAAM,GAAG,SAAS,GAAG,SAAS,GAAG,OAAO,GAAG,MAAM,CAAC;AAE3E,MAAM,WAAW,wBAAwB;IACxC,IAAI,EAAE,MAAM,CAAC;IACb,KAAK,EAAE,KAAK,CAAC;IACb,UAAU,EAAE,UAAU,CAAC;CACvB;AAED,MAAM,MAAM,iBAAiB,GAAG,SAAS,GAAG,YAAY,GAAG,aAAa,GAAG,MAAM,CAAC;AAElF,MAAM,WAAW,aAAa;IAC7B,OAAO,EAAE,iBAAiB,CAAC;IAC3B,aAAa,EAAE,MAAM,CAAC;IACtB,aAAa,EAAE,OAAO,CAAC;IACvB,kBAAkB,EAAE,MAAM,CAAC;IAC3B,YAAY,EAAE,MAAM,CAAC;CACrB;AAED,MAAM,WAAW,UAAU;IAC1B,GAAG,EAAE,MAAM,GAAG,SAAS,CAAC;IACxB,MAAM,EAAE,MAAM,CAAC;IACf,WAAW,EAAE,MAAM,CAAC;CACpB;AAED;;;GAGG;AACH,wBAAgB,YAAY,CAAC,OAAO,EAAE,aAAa,GAAG,UAAU,CAyB/D;AAED,MAAM,WAAW,eAAe;IAC/B,cAAc,EAAE,MAAM,CAAC;IACvB,cAAc,EAAE,MAAM,CAAC;IACvB,IAAI,EAAE,UAAU,CAAC;IAEjB,QAAQ,EAAE,CAAC,YAAY,EAAE,MAAM,EAAE,UAAU,EAAE,MAAM,KAAK,OAAO,CAAC,wBAAwB,CAAC,CAAC;CAC1F;AAED,MAAM,MAAM,eAAe,GACxB;IAAE,IAAI,EAAE,YAAY,CAAC;IAAC,OAAO,EAAE,QAAQ,GAAG,MAAM,CAAC;IAAC,IAAI,EAAE,MAAM,CAAA;CAAE,GAChE;IAAE,IAAI,EAAE,gBAAgB,CAAC;IAAC,MAAM,EAAE,MAAM,CAAC;IAAC,IAAI,EAAE,MAAM,CAAA;CAAE,GACxD;IAAE,IAAI,EAAE,eAAe,CAAC;IAAC,MAAM,EAAE,MAAM,CAAA;CAAE,GAEzC;IAAE,IAAI,EAAE,eAAe,CAAC;IAAC,IAAI,EAAE,MAAM,CAAC;IAAC,WAAW,EAAE,MAAM,CAAC;IAAC,IAAI,EAAE,MAAM,CAAA;CAAE,CAAC;AAE9E,MAAM,WAAW,gBAAgB;IAChC,MAAM,EAAE,eAAe,EAAE,CAAC;IAC1B,KAAK,EAAE,KAAK,CAAC;IACb,SAAS,EAAE,MAAM,CAAC;CAClB;AAED,qBAAa,gBAAgB;IAC5B;;;;OAIG;IACG,OAAO,CAAC,KAAK,EAAE,eAAe,GAAG,OAAO,CAAC,gBAAgB,CAAC,CAkG/D;CACD","sourcesContent":["import type { Usage } from \"@caupulican/pi-ai\";\n\nexport type StopReason = \"stop\" | \"toolUse\" | \"aborted\" | \"error\" | string;\n\nexport interface IsolatedCompletionResult {\n\ttext: string;\n\tusage: Usage;\n\tstopReason: StopReason;\n}\n\nexport type ReflectionTrigger = \"complex\" | \"corrective\" | \"session-end\" | \"none\";\n\nexport interface DemandSignals {\n\ttrigger: ReflectionTrigger;\n\ttoolCallCount: number;\n\thadCorrection: boolean;\n\tcontextHeadroomPct: number; // 0..100\n\tusefulLately: number; // 0..1 rolling score\n}\n\nexport interface DemandPlan {\n\tact: \"skip\" | \"reflect\";\n\treason: string;\n\ttokenBudget: number;\n}\n\n/**\n * Pure zero-I/O heuristic to decide whether the current turn justifies a reflection run\n * and determine the token budget under the cheap-tool net-negative doctrine.\n */\nexport function decideDemand(signals: DemandSignals): DemandPlan {\n\tif (signals.trigger === \"none\") {\n\t\treturn { act: \"skip\", reason: \"No trigger detected\", tokenBudget: 0 };\n\t}\n\tif (signals.contextHeadroomPct < 10) {\n\t\treturn { act: \"skip\", reason: \"Context headroom is critically low (< 10%)\", tokenBudget: 0 };\n\t}\n\n\t// Dynamic token budget based on headroom (keep reflection bounded between 500 and 1500 tokens)\n\tconst baseBudget = 1000;\n\tconst tokenBudget = Math.max(500, Math.min(1500, Math.round(baseBudget * (signals.contextHeadroomPct / 100))));\n\n\tif (signals.hadCorrection) {\n\t\treturn { act: \"reflect\", reason: \"Correction detected in the turn\", tokenBudget };\n\t}\n\tif (signals.trigger === \"session-end\") {\n\t\treturn { act: \"reflect\", reason: \"Session end reflection triggered\", tokenBudget };\n\t}\n\tif (signals.trigger === \"complex\") {\n\t\tif (signals.toolCallCount >= 3) {\n\t\t\treturn { act: \"reflect\", reason: `Complex turn with ${signals.toolCallCount} tool calls`, tokenBudget };\n\t\t}\n\t}\n\n\treturn { act: \"skip\", reason: \"Signals do not justify reflection overhead\", tokenBudget: 0 };\n}\n\nexport interface ReflectionInput {\n\trecentTurnText: string; // host serializes the just-finished turn\n\texistingMemory: string; // current MEMORY.md + USER.md snapshot\n\tplan: DemandPlan;\n\t// host-injected isolated completion function:\n\tcomplete: (systemPrompt: string, userPrompt: string) => Promise<IsolatedCompletionResult>;\n}\n\nexport type ReflectionWrite =\n\t| { kind: \"memory_add\"; section: \"MEMORY\" | \"USER\"; text: string }\n\t| { kind: \"memory_replace\"; target: string; text: string }\n\t| { kind: \"memory_remove\"; target: string }\n\t// R7 memory-to-behavior: promote a recurring procedural workflow into an executable skill.\n\t| { kind: \"promote_skill\"; name: string; description: string; body: string };\n\nexport interface ReflectionResult {\n\twrites: ReflectionWrite[];\n\tusage: Usage;\n\trationale: string;\n}\n\nexport class ReflectionEngine {\n\t/**\n\t * Build the reflection prompt, call the injected isolated complete(),\n\t * parse the response, confront existing memory, and return memory writes.\n\t * Zero direct I/O.\n\t */\n\tasync reflect(input: ReflectionInput): Promise<ReflectionResult> {\n\t\tconst systemPrompt = `You are a reflection engine. Your job is to analyze the recent conversation turn, compare it against the agent's existing memory, and decide if any memory updates are needed.\n\nExisting Memory snapshot:\n${input.existingMemory}\n\nMemory guidelines:\n- \"MEMORY\" is for project facts, configuration, repeatable workflows, and coding findings.\n- \"USER\" is for user preferences, patterns, and style specifications.\n- Avoid duplicate facts. If the fact is already represented, do not add it.\n- CONFRONT existing memory: if the new turn contradicts or updates an existing fact, use \"memory_replace\" or \"memory_remove\" to supersede the old fact rather than blindly appending.\n- Keep memories short, factual, and direct. No fluff.\n- PROMOTE to behavior: if the turn established a REPEATABLE, multi-step PROCEDURE/workflow (not a one-off fact) that should govern a future class of tasks, emit a \"promote_skill\" instead of (or in addition to) a memory fact. Only promote a genuinely reusable procedure — never a single fact, a one-off narrative, or environment-specific noise. Prefer a memory fact when unsure.\n\nYou must output your analysis and writes in the following JSON format inside a \\`\\`\\`json\\`\\`\\` code fence:\n{\n \"rationale\": \"Explanation of your reasoning\",\n \"writes\": [\n { \"kind\": \"memory_add\", \"section\": \"MEMORY\" | \"USER\", \"text\": \"New direct fact to append\" },\n { \"kind\": \"memory_replace\", \"target\": \"Exact text substring to replace\", \"text\": \"New replacement text\" },\n { \"kind\": \"memory_remove\", \"target\": \"Exact text substring to remove\" },\n { \"kind\": \"promote_skill\", \"name\": \"kebab-case-skill-name\", \"description\": \"one line of when to use it\", \"body\": \"Markdown: the step-by-step procedure\" }\n ]\n}\n`;\n\n\t\tconst userPrompt = `Recent turn transcript:\n${input.recentTurnText}\n\nAnalyze this turn and output your memory updates.`;\n\n\t\ttry {\n\t\t\tconst compResult = await input.complete(systemPrompt, userPrompt);\n\t\t\tconst text = compResult.text;\n\n\t\t\tconst jsonMatch = text.match(/```json\\s*([\\s\\S]*?)\\s*```/) || text.match(/{[\\s\\S]*}/);\n\t\t\tif (!jsonMatch) {\n\t\t\t\treturn {\n\t\t\t\t\twrites: [],\n\t\t\t\t\tusage: compResult.usage,\n\t\t\t\t\trationale: `Failed to locate JSON response. Raw text:\\n${text}`,\n\t\t\t\t};\n\t\t\t}\n\n\t\t\tconst parsed = JSON.parse(jsonMatch[1] || jsonMatch[0]);\n\t\t\tconst rationale = parsed.rationale || \"\";\n\t\t\tconst writes: ReflectionWrite[] = [];\n\n\t\t\tif (Array.isArray(parsed.writes)) {\n\t\t\t\tfor (const w of parsed.writes) {\n\t\t\t\t\tif (w && typeof w === \"object\") {\n\t\t\t\t\t\tif (\n\t\t\t\t\t\t\tw.kind === \"memory_add\" &&\n\t\t\t\t\t\t\t(w.section === \"MEMORY\" || w.section === \"USER\") &&\n\t\t\t\t\t\t\ttypeof w.text === \"string\"\n\t\t\t\t\t\t) {\n\t\t\t\t\t\t\twrites.push({ kind: \"memory_add\", section: w.section, text: w.text });\n\t\t\t\t\t\t} else if (\n\t\t\t\t\t\t\tw.kind === \"memory_replace\" &&\n\t\t\t\t\t\t\ttypeof w.target === \"string\" &&\n\t\t\t\t\t\t\ttypeof w.text === \"string\"\n\t\t\t\t\t\t) {\n\t\t\t\t\t\t\twrites.push({ kind: \"memory_replace\", target: w.target, text: w.text });\n\t\t\t\t\t\t} else if (w.kind === \"memory_remove\" && typeof w.target === \"string\") {\n\t\t\t\t\t\t\twrites.push({ kind: \"memory_remove\", target: w.target });\n\t\t\t\t\t\t} else if (\n\t\t\t\t\t\t\tw.kind === \"promote_skill\" &&\n\t\t\t\t\t\t\ttypeof w.name === \"string\" &&\n\t\t\t\t\t\t\ttypeof w.description === \"string\" &&\n\t\t\t\t\t\t\ttypeof w.body === \"string\"\n\t\t\t\t\t\t) {\n\t\t\t\t\t\t\twrites.push({ kind: \"promote_skill\", name: w.name, description: w.description, body: w.body });\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\n\t\t\treturn {\n\t\t\t\twrites,\n\t\t\t\tusage: compResult.usage,\n\t\t\t\trationale,\n\t\t\t};\n\t\t} catch (err) {\n\t\t\t// Zeroed/fallback usage representation\n\t\t\tconst emptyUsage: Usage = {\n\t\t\t\tinput: 0,\n\t\t\t\toutput: 0,\n\t\t\t\tcacheRead: 0,\n\t\t\t\tcacheWrite: 0,\n\t\t\t\ttotalTokens: 0,\n\t\t\t\tcost: { input: 0, output: 0, cacheRead: 0, cacheWrite: 0, total: 0 },\n\t\t\t};\n\t\t\treturn {\n\t\t\t\twrites: [],\n\t\t\t\tusage: emptyUsage,\n\t\t\t\trationale: `Error during reflection: ${String(err)}`,\n\t\t\t};\n\t\t}\n\t}\n}\n"]}
|
|
@@ -43,6 +43,7 @@ Memory guidelines:
|
|
|
43
43
|
- Avoid duplicate facts. If the fact is already represented, do not add it.
|
|
44
44
|
- CONFRONT existing memory: if the new turn contradicts or updates an existing fact, use "memory_replace" or "memory_remove" to supersede the old fact rather than blindly appending.
|
|
45
45
|
- Keep memories short, factual, and direct. No fluff.
|
|
46
|
+
- PROMOTE to behavior: if the turn established a REPEATABLE, multi-step PROCEDURE/workflow (not a one-off fact) that should govern a future class of tasks, emit a "promote_skill" instead of (or in addition to) a memory fact. Only promote a genuinely reusable procedure — never a single fact, a one-off narrative, or environment-specific noise. Prefer a memory fact when unsure.
|
|
46
47
|
|
|
47
48
|
You must output your analysis and writes in the following JSON format inside a \`\`\`json\`\`\` code fence:
|
|
48
49
|
{
|
|
@@ -50,7 +51,8 @@ You must output your analysis and writes in the following JSON format inside a \
|
|
|
50
51
|
"writes": [
|
|
51
52
|
{ "kind": "memory_add", "section": "MEMORY" | "USER", "text": "New direct fact to append" },
|
|
52
53
|
{ "kind": "memory_replace", "target": "Exact text substring to replace", "text": "New replacement text" },
|
|
53
|
-
{ "kind": "memory_remove", "target": "Exact text substring to remove" }
|
|
54
|
+
{ "kind": "memory_remove", "target": "Exact text substring to remove" },
|
|
55
|
+
{ "kind": "promote_skill", "name": "kebab-case-skill-name", "description": "one line of when to use it", "body": "Markdown: the step-by-step procedure" }
|
|
54
56
|
]
|
|
55
57
|
}
|
|
56
58
|
`;
|
|
@@ -88,6 +90,12 @@ Analyze this turn and output your memory updates.`;
|
|
|
88
90
|
else if (w.kind === "memory_remove" && typeof w.target === "string") {
|
|
89
91
|
writes.push({ kind: "memory_remove", target: w.target });
|
|
90
92
|
}
|
|
93
|
+
else if (w.kind === "promote_skill" &&
|
|
94
|
+
typeof w.name === "string" &&
|
|
95
|
+
typeof w.description === "string" &&
|
|
96
|
+
typeof w.body === "string") {
|
|
97
|
+
writes.push({ kind: "promote_skill", name: w.name, description: w.description, body: w.body });
|
|
98
|
+
}
|
|
91
99
|
}
|
|
92
100
|
}
|
|
93
101
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"reflection-engine.js","sourceRoot":"","sources":["../../../src/core/learning/reflection-engine.ts"],"names":[],"mappings":"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","sourcesContent":["import type { Usage } from \"@caupulican/pi-ai\";\n\nexport type StopReason = \"stop\" | \"toolUse\" | \"aborted\" | \"error\" | string;\n\nexport interface IsolatedCompletionResult {\n\ttext: string;\n\tusage: Usage;\n\tstopReason: StopReason;\n}\n\nexport type ReflectionTrigger = \"complex\" | \"corrective\" | \"session-end\" | \"none\";\n\nexport interface DemandSignals {\n\ttrigger: ReflectionTrigger;\n\ttoolCallCount: number;\n\thadCorrection: boolean;\n\tcontextHeadroomPct: number; // 0..100\n\tusefulLately: number; // 0..1 rolling score\n}\n\nexport interface DemandPlan {\n\tact: \"skip\" | \"reflect\";\n\treason: string;\n\ttokenBudget: number;\n}\n\n/**\n * Pure zero-I/O heuristic to decide whether the current turn justifies a reflection run\n * and determine the token budget under the cheap-tool net-negative doctrine.\n */\nexport function decideDemand(signals: DemandSignals): DemandPlan {\n\tif (signals.trigger === \"none\") {\n\t\treturn { act: \"skip\", reason: \"No trigger detected\", tokenBudget: 0 };\n\t}\n\tif (signals.contextHeadroomPct < 10) {\n\t\treturn { act: \"skip\", reason: \"Context headroom is critically low (< 10%)\", tokenBudget: 0 };\n\t}\n\n\t// Dynamic token budget based on headroom (keep reflection bounded between 500 and 1500 tokens)\n\tconst baseBudget = 1000;\n\tconst tokenBudget = Math.max(500, Math.min(1500, Math.round(baseBudget * (signals.contextHeadroomPct / 100))));\n\n\tif (signals.hadCorrection) {\n\t\treturn { act: \"reflect\", reason: \"Correction detected in the turn\", tokenBudget };\n\t}\n\tif (signals.trigger === \"session-end\") {\n\t\treturn { act: \"reflect\", reason: \"Session end reflection triggered\", tokenBudget };\n\t}\n\tif (signals.trigger === \"complex\") {\n\t\tif (signals.toolCallCount >= 3) {\n\t\t\treturn { act: \"reflect\", reason: `Complex turn with ${signals.toolCallCount} tool calls`, tokenBudget };\n\t\t}\n\t}\n\n\treturn { act: \"skip\", reason: \"Signals do not justify reflection overhead\", tokenBudget: 0 };\n}\n\nexport interface ReflectionInput {\n\trecentTurnText: string; // host serializes the just-finished turn\n\texistingMemory: string; // current MEMORY.md + USER.md snapshot\n\tplan: DemandPlan;\n\t// host-injected isolated completion function:\n\tcomplete: (systemPrompt: string, userPrompt: string) => Promise<IsolatedCompletionResult>;\n}\n\nexport type ReflectionWrite =\n\t| { kind: \"memory_add\"; section: \"MEMORY\" | \"USER\"; text: string }\n\t| { kind: \"memory_replace\"; target: string; text: string }\n\t| { kind: \"memory_remove\"; target: string };\n\nexport interface ReflectionResult {\n\twrites: ReflectionWrite[];\n\tusage: Usage;\n\trationale: string;\n}\n\nexport class ReflectionEngine {\n\t/**\n\t * Build the reflection prompt, call the injected isolated complete(),\n\t * parse the response, confront existing memory, and return memory writes.\n\t * Zero direct I/O.\n\t */\n\tasync reflect(input: ReflectionInput): Promise<ReflectionResult> {\n\t\tconst systemPrompt = `You are a reflection engine. Your job is to analyze the recent conversation turn, compare it against the agent's existing memory, and decide if any memory updates are needed.\n\nExisting Memory snapshot:\n${input.existingMemory}\n\nMemory guidelines:\n- \"MEMORY\" is for project facts, configuration, repeatable workflows, and coding findings.\n- \"USER\" is for user preferences, patterns, and style specifications.\n- Avoid duplicate facts. If the fact is already represented, do not add it.\n- CONFRONT existing memory: if the new turn contradicts or updates an existing fact, use \"memory_replace\" or \"memory_remove\" to supersede the old fact rather than blindly appending.\n- Keep memories short, factual, and direct. No fluff.\n\nYou must output your analysis and writes in the following JSON format inside a \\`\\`\\`json\\`\\`\\` code fence:\n{\n \"rationale\": \"Explanation of your reasoning\",\n \"writes\": [\n { \"kind\": \"memory_add\", \"section\": \"MEMORY\" | \"USER\", \"text\": \"New direct fact to append\" },\n { \"kind\": \"memory_replace\", \"target\": \"Exact text substring to replace\", \"text\": \"New replacement text\" },\n { \"kind\": \"memory_remove\", \"target\": \"Exact text substring to remove\" }\n ]\n}\n`;\n\n\t\tconst userPrompt = `Recent turn transcript:\n${input.recentTurnText}\n\nAnalyze this turn and output your memory updates.`;\n\n\t\ttry {\n\t\t\tconst compResult = await input.complete(systemPrompt, userPrompt);\n\t\t\tconst text = compResult.text;\n\n\t\t\tconst jsonMatch = text.match(/```json\\s*([\\s\\S]*?)\\s*```/) || text.match(/{[\\s\\S]*}/);\n\t\t\tif (!jsonMatch) {\n\t\t\t\treturn {\n\t\t\t\t\twrites: [],\n\t\t\t\t\tusage: compResult.usage,\n\t\t\t\t\trationale: `Failed to locate JSON response. Raw text:\\n${text}`,\n\t\t\t\t};\n\t\t\t}\n\n\t\t\tconst parsed = JSON.parse(jsonMatch[1] || jsonMatch[0]);\n\t\t\tconst rationale = parsed.rationale || \"\";\n\t\t\tconst writes: ReflectionWrite[] = [];\n\n\t\t\tif (Array.isArray(parsed.writes)) {\n\t\t\t\tfor (const w of parsed.writes) {\n\t\t\t\t\tif (w && typeof w === \"object\") {\n\t\t\t\t\t\tif (\n\t\t\t\t\t\t\tw.kind === \"memory_add\" &&\n\t\t\t\t\t\t\t(w.section === \"MEMORY\" || w.section === \"USER\") &&\n\t\t\t\t\t\t\ttypeof w.text === \"string\"\n\t\t\t\t\t\t) {\n\t\t\t\t\t\t\twrites.push({ kind: \"memory_add\", section: w.section, text: w.text });\n\t\t\t\t\t\t} else if (\n\t\t\t\t\t\t\tw.kind === \"memory_replace\" &&\n\t\t\t\t\t\t\ttypeof w.target === \"string\" &&\n\t\t\t\t\t\t\ttypeof w.text === \"string\"\n\t\t\t\t\t\t) {\n\t\t\t\t\t\t\twrites.push({ kind: \"memory_replace\", target: w.target, text: w.text });\n\t\t\t\t\t\t} else if (w.kind === \"memory_remove\" && typeof w.target === \"string\") {\n\t\t\t\t\t\t\twrites.push({ kind: \"memory_remove\", target: w.target });\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\n\t\t\treturn {\n\t\t\t\twrites,\n\t\t\t\tusage: compResult.usage,\n\t\t\t\trationale,\n\t\t\t};\n\t\t} catch (err) {\n\t\t\t// Zeroed/fallback usage representation\n\t\t\tconst emptyUsage: Usage = {\n\t\t\t\tinput: 0,\n\t\t\t\toutput: 0,\n\t\t\t\tcacheRead: 0,\n\t\t\t\tcacheWrite: 0,\n\t\t\t\ttotalTokens: 0,\n\t\t\t\tcost: { input: 0, output: 0, cacheRead: 0, cacheWrite: 0, total: 0 },\n\t\t\t};\n\t\t\treturn {\n\t\t\t\twrites: [],\n\t\t\t\tusage: emptyUsage,\n\t\t\t\trationale: `Error during reflection: ${String(err)}`,\n\t\t\t};\n\t\t}\n\t}\n}\n"]}
|
|
1
|
+
{"version":3,"file":"reflection-engine.js","sourceRoot":"","sources":["../../../src/core/learning/reflection-engine.ts"],"names":[],"mappings":"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","sourcesContent":["import type { Usage } from \"@caupulican/pi-ai\";\n\nexport type StopReason = \"stop\" | \"toolUse\" | \"aborted\" | \"error\" | string;\n\nexport interface IsolatedCompletionResult {\n\ttext: string;\n\tusage: Usage;\n\tstopReason: StopReason;\n}\n\nexport type ReflectionTrigger = \"complex\" | \"corrective\" | \"session-end\" | \"none\";\n\nexport interface DemandSignals {\n\ttrigger: ReflectionTrigger;\n\ttoolCallCount: number;\n\thadCorrection: boolean;\n\tcontextHeadroomPct: number; // 0..100\n\tusefulLately: number; // 0..1 rolling score\n}\n\nexport interface DemandPlan {\n\tact: \"skip\" | \"reflect\";\n\treason: string;\n\ttokenBudget: number;\n}\n\n/**\n * Pure zero-I/O heuristic to decide whether the current turn justifies a reflection run\n * and determine the token budget under the cheap-tool net-negative doctrine.\n */\nexport function decideDemand(signals: DemandSignals): DemandPlan {\n\tif (signals.trigger === \"none\") {\n\t\treturn { act: \"skip\", reason: \"No trigger detected\", tokenBudget: 0 };\n\t}\n\tif (signals.contextHeadroomPct < 10) {\n\t\treturn { act: \"skip\", reason: \"Context headroom is critically low (< 10%)\", tokenBudget: 0 };\n\t}\n\n\t// Dynamic token budget based on headroom (keep reflection bounded between 500 and 1500 tokens)\n\tconst baseBudget = 1000;\n\tconst tokenBudget = Math.max(500, Math.min(1500, Math.round(baseBudget * (signals.contextHeadroomPct / 100))));\n\n\tif (signals.hadCorrection) {\n\t\treturn { act: \"reflect\", reason: \"Correction detected in the turn\", tokenBudget };\n\t}\n\tif (signals.trigger === \"session-end\") {\n\t\treturn { act: \"reflect\", reason: \"Session end reflection triggered\", tokenBudget };\n\t}\n\tif (signals.trigger === \"complex\") {\n\t\tif (signals.toolCallCount >= 3) {\n\t\t\treturn { act: \"reflect\", reason: `Complex turn with ${signals.toolCallCount} tool calls`, tokenBudget };\n\t\t}\n\t}\n\n\treturn { act: \"skip\", reason: \"Signals do not justify reflection overhead\", tokenBudget: 0 };\n}\n\nexport interface ReflectionInput {\n\trecentTurnText: string; // host serializes the just-finished turn\n\texistingMemory: string; // current MEMORY.md + USER.md snapshot\n\tplan: DemandPlan;\n\t// host-injected isolated completion function:\n\tcomplete: (systemPrompt: string, userPrompt: string) => Promise<IsolatedCompletionResult>;\n}\n\nexport type ReflectionWrite =\n\t| { kind: \"memory_add\"; section: \"MEMORY\" | \"USER\"; text: string }\n\t| { kind: \"memory_replace\"; target: string; text: string }\n\t| { kind: \"memory_remove\"; target: string }\n\t// R7 memory-to-behavior: promote a recurring procedural workflow into an executable skill.\n\t| { kind: \"promote_skill\"; name: string; description: string; body: string };\n\nexport interface ReflectionResult {\n\twrites: ReflectionWrite[];\n\tusage: Usage;\n\trationale: string;\n}\n\nexport class ReflectionEngine {\n\t/**\n\t * Build the reflection prompt, call the injected isolated complete(),\n\t * parse the response, confront existing memory, and return memory writes.\n\t * Zero direct I/O.\n\t */\n\tasync reflect(input: ReflectionInput): Promise<ReflectionResult> {\n\t\tconst systemPrompt = `You are a reflection engine. Your job is to analyze the recent conversation turn, compare it against the agent's existing memory, and decide if any memory updates are needed.\n\nExisting Memory snapshot:\n${input.existingMemory}\n\nMemory guidelines:\n- \"MEMORY\" is for project facts, configuration, repeatable workflows, and coding findings.\n- \"USER\" is for user preferences, patterns, and style specifications.\n- Avoid duplicate facts. If the fact is already represented, do not add it.\n- CONFRONT existing memory: if the new turn contradicts or updates an existing fact, use \"memory_replace\" or \"memory_remove\" to supersede the old fact rather than blindly appending.\n- Keep memories short, factual, and direct. No fluff.\n- PROMOTE to behavior: if the turn established a REPEATABLE, multi-step PROCEDURE/workflow (not a one-off fact) that should govern a future class of tasks, emit a \"promote_skill\" instead of (or in addition to) a memory fact. Only promote a genuinely reusable procedure — never a single fact, a one-off narrative, or environment-specific noise. Prefer a memory fact when unsure.\n\nYou must output your analysis and writes in the following JSON format inside a \\`\\`\\`json\\`\\`\\` code fence:\n{\n \"rationale\": \"Explanation of your reasoning\",\n \"writes\": [\n { \"kind\": \"memory_add\", \"section\": \"MEMORY\" | \"USER\", \"text\": \"New direct fact to append\" },\n { \"kind\": \"memory_replace\", \"target\": \"Exact text substring to replace\", \"text\": \"New replacement text\" },\n { \"kind\": \"memory_remove\", \"target\": \"Exact text substring to remove\" },\n { \"kind\": \"promote_skill\", \"name\": \"kebab-case-skill-name\", \"description\": \"one line of when to use it\", \"body\": \"Markdown: the step-by-step procedure\" }\n ]\n}\n`;\n\n\t\tconst userPrompt = `Recent turn transcript:\n${input.recentTurnText}\n\nAnalyze this turn and output your memory updates.`;\n\n\t\ttry {\n\t\t\tconst compResult = await input.complete(systemPrompt, userPrompt);\n\t\t\tconst text = compResult.text;\n\n\t\t\tconst jsonMatch = text.match(/```json\\s*([\\s\\S]*?)\\s*```/) || text.match(/{[\\s\\S]*}/);\n\t\t\tif (!jsonMatch) {\n\t\t\t\treturn {\n\t\t\t\t\twrites: [],\n\t\t\t\t\tusage: compResult.usage,\n\t\t\t\t\trationale: `Failed to locate JSON response. Raw text:\\n${text}`,\n\t\t\t\t};\n\t\t\t}\n\n\t\t\tconst parsed = JSON.parse(jsonMatch[1] || jsonMatch[0]);\n\t\t\tconst rationale = parsed.rationale || \"\";\n\t\t\tconst writes: ReflectionWrite[] = [];\n\n\t\t\tif (Array.isArray(parsed.writes)) {\n\t\t\t\tfor (const w of parsed.writes) {\n\t\t\t\t\tif (w && typeof w === \"object\") {\n\t\t\t\t\t\tif (\n\t\t\t\t\t\t\tw.kind === \"memory_add\" &&\n\t\t\t\t\t\t\t(w.section === \"MEMORY\" || w.section === \"USER\") &&\n\t\t\t\t\t\t\ttypeof w.text === \"string\"\n\t\t\t\t\t\t) {\n\t\t\t\t\t\t\twrites.push({ kind: \"memory_add\", section: w.section, text: w.text });\n\t\t\t\t\t\t} else if (\n\t\t\t\t\t\t\tw.kind === \"memory_replace\" &&\n\t\t\t\t\t\t\ttypeof w.target === \"string\" &&\n\t\t\t\t\t\t\ttypeof w.text === \"string\"\n\t\t\t\t\t\t) {\n\t\t\t\t\t\t\twrites.push({ kind: \"memory_replace\", target: w.target, text: w.text });\n\t\t\t\t\t\t} else if (w.kind === \"memory_remove\" && typeof w.target === \"string\") {\n\t\t\t\t\t\t\twrites.push({ kind: \"memory_remove\", target: w.target });\n\t\t\t\t\t\t} else if (\n\t\t\t\t\t\t\tw.kind === \"promote_skill\" &&\n\t\t\t\t\t\t\ttypeof w.name === \"string\" &&\n\t\t\t\t\t\t\ttypeof w.description === \"string\" &&\n\t\t\t\t\t\t\ttypeof w.body === \"string\"\n\t\t\t\t\t\t) {\n\t\t\t\t\t\t\twrites.push({ kind: \"promote_skill\", name: w.name, description: w.description, body: w.body });\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\n\t\t\treturn {\n\t\t\t\twrites,\n\t\t\t\tusage: compResult.usage,\n\t\t\t\trationale,\n\t\t\t};\n\t\t} catch (err) {\n\t\t\t// Zeroed/fallback usage representation\n\t\t\tconst emptyUsage: Usage = {\n\t\t\t\tinput: 0,\n\t\t\t\toutput: 0,\n\t\t\t\tcacheRead: 0,\n\t\t\t\tcacheWrite: 0,\n\t\t\t\ttotalTokens: 0,\n\t\t\t\tcost: { input: 0, output: 0, cacheRead: 0, cacheWrite: 0, total: 0 },\n\t\t\t};\n\t\t\treturn {\n\t\t\t\twrites: [],\n\t\t\t\tusage: emptyUsage,\n\t\t\t\trationale: `Error during reflection: ${String(err)}`,\n\t\t\t};\n\t\t}\n\t}\n}\n"]}
|
|
@@ -1,12 +1,12 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "pi-extension-custom-provider",
|
|
3
|
-
"version": "0.80.
|
|
3
|
+
"version": "0.80.62",
|
|
4
4
|
"lockfileVersion": 3,
|
|
5
5
|
"requires": true,
|
|
6
6
|
"packages": {
|
|
7
7
|
"": {
|
|
8
8
|
"name": "pi-extension-custom-provider",
|
|
9
|
-
"version": "0.80.
|
|
9
|
+
"version": "0.80.62",
|
|
10
10
|
"dependencies": {
|
|
11
11
|
"@anthropic-ai/sdk": "^0.52.0"
|
|
12
12
|
}
|
|
@@ -1,12 +1,12 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "pi-extension-sandbox",
|
|
3
|
-
"version": "0.80.
|
|
3
|
+
"version": "0.80.62",
|
|
4
4
|
"lockfileVersion": 3,
|
|
5
5
|
"requires": true,
|
|
6
6
|
"packages": {
|
|
7
7
|
"": {
|
|
8
8
|
"name": "pi-extension-sandbox",
|
|
9
|
-
"version": "0.80.
|
|
9
|
+
"version": "0.80.62",
|
|
10
10
|
"dependencies": {
|
|
11
11
|
"@anthropic-ai/sandbox-runtime": "^0.0.26"
|
|
12
12
|
}
|
|
@@ -1,12 +1,12 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "pi-extension-with-deps",
|
|
3
|
-
"version": "0.80.
|
|
3
|
+
"version": "0.80.62",
|
|
4
4
|
"lockfileVersion": 3,
|
|
5
5
|
"requires": true,
|
|
6
6
|
"packages": {
|
|
7
7
|
"": {
|
|
8
8
|
"name": "pi-extension-with-deps",
|
|
9
|
-
"version": "0.80.
|
|
9
|
+
"version": "0.80.62",
|
|
10
10
|
"dependencies": {
|
|
11
11
|
"ms": "^2.1.3"
|
|
12
12
|
},
|
package/npm-shrinkwrap.json
CHANGED
|
@@ -1,17 +1,17 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@caupulican/pi-adaptative",
|
|
3
|
-
"version": "0.80.
|
|
3
|
+
"version": "0.80.65",
|
|
4
4
|
"lockfileVersion": 3,
|
|
5
5
|
"requires": true,
|
|
6
6
|
"packages": {
|
|
7
7
|
"": {
|
|
8
8
|
"name": "@caupulican/pi-adaptative",
|
|
9
|
-
"version": "0.80.
|
|
9
|
+
"version": "0.80.65",
|
|
10
10
|
"license": "MIT",
|
|
11
11
|
"dependencies": {
|
|
12
|
-
"@caupulican/pi-agent-core": "^0.80.
|
|
13
|
-
"@caupulican/pi-ai": "^0.80.
|
|
14
|
-
"@caupulican/pi-tui": "^0.80.
|
|
12
|
+
"@caupulican/pi-agent-core": "^0.80.65",
|
|
13
|
+
"@caupulican/pi-ai": "^0.80.65",
|
|
14
|
+
"@caupulican/pi-tui": "^0.80.65",
|
|
15
15
|
"@silvia-odwyer/photon-node": "0.3.4",
|
|
16
16
|
"chalk": "5.6.2",
|
|
17
17
|
"cross-spawn": "7.0.6",
|
|
@@ -474,11 +474,11 @@
|
|
|
474
474
|
}
|
|
475
475
|
},
|
|
476
476
|
"node_modules/@caupulican/pi-agent-core": {
|
|
477
|
-
"version": "0.80.
|
|
478
|
-
"resolved": "https://registry.npmjs.org/@caupulican/pi-agent-core/-/pi-agent-core-0.80.
|
|
477
|
+
"version": "0.80.65",
|
|
478
|
+
"resolved": "https://registry.npmjs.org/@caupulican/pi-agent-core/-/pi-agent-core-0.80.65.tgz",
|
|
479
479
|
"license": "MIT",
|
|
480
480
|
"dependencies": {
|
|
481
|
-
"@caupulican/pi-ai": "^0.80.
|
|
481
|
+
"@caupulican/pi-ai": "^0.80.65",
|
|
482
482
|
"ignore": "7.0.5",
|
|
483
483
|
"typebox": "1.1.38",
|
|
484
484
|
"yaml": "2.9.0"
|
|
@@ -488,8 +488,8 @@
|
|
|
488
488
|
}
|
|
489
489
|
},
|
|
490
490
|
"node_modules/@caupulican/pi-ai": {
|
|
491
|
-
"version": "0.80.
|
|
492
|
-
"resolved": "https://registry.npmjs.org/@caupulican/pi-ai/-/pi-ai-0.80.
|
|
491
|
+
"version": "0.80.65",
|
|
492
|
+
"resolved": "https://registry.npmjs.org/@caupulican/pi-ai/-/pi-ai-0.80.65.tgz",
|
|
493
493
|
"license": "MIT",
|
|
494
494
|
"dependencies": {
|
|
495
495
|
"@anthropic-ai/sdk": "0.91.1",
|
|
@@ -511,8 +511,8 @@
|
|
|
511
511
|
}
|
|
512
512
|
},
|
|
513
513
|
"node_modules/@caupulican/pi-tui": {
|
|
514
|
-
"version": "0.80.
|
|
515
|
-
"resolved": "https://registry.npmjs.org/@caupulican/pi-tui/-/pi-tui-0.80.
|
|
514
|
+
"version": "0.80.65",
|
|
515
|
+
"resolved": "https://registry.npmjs.org/@caupulican/pi-tui/-/pi-tui-0.80.65.tgz",
|
|
516
516
|
"license": "MIT",
|
|
517
517
|
"dependencies": {
|
|
518
518
|
"get-east-asian-width": "1.6.0",
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@caupulican/pi-adaptative",
|
|
3
|
-
"version": "0.80.
|
|
3
|
+
"version": "0.80.65",
|
|
4
4
|
"description": "Adaptive fork of Pi coding agent for self-evolving agent harness experiments",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"piConfig": {
|
|
@@ -41,9 +41,9 @@
|
|
|
41
41
|
"prepublishOnly": "npm run clean && npm run build && npm run shrinkwrap"
|
|
42
42
|
},
|
|
43
43
|
"dependencies": {
|
|
44
|
-
"@caupulican/pi-agent-core": "^0.80.
|
|
45
|
-
"@caupulican/pi-ai": "^0.80.
|
|
46
|
-
"@caupulican/pi-tui": "^0.80.
|
|
44
|
+
"@caupulican/pi-agent-core": "^0.80.65",
|
|
45
|
+
"@caupulican/pi-ai": "^0.80.65",
|
|
46
|
+
"@caupulican/pi-tui": "^0.80.65",
|
|
47
47
|
"@silvia-odwyer/photon-node": "0.3.4",
|
|
48
48
|
"chalk": "5.6.2",
|
|
49
49
|
"cross-spawn": "7.0.6",
|