@sage-protocol/pi-adapter 0.1.9 → 0.2.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md CHANGED
@@ -4,12 +4,43 @@ Sage integration for the pi coding agent runtime.
4
4
 
5
5
  It gives you:
6
6
  - Sage MCP tools in pi (`sage_search`, `sage_execute`, `sage_status`)
7
+ - **Dynamic identity context** — wallet, active libraries, and skill counts injected into every turn's system prompt
7
8
  - Session hook integration (`sage skill context`, `sage suggest hook skill`)
8
9
  - RLM capture hooks (`sage capture hook prompt/response`)
9
10
  - Optional pre/post tool security scanning (`sage security scan-hook`)
10
11
 
11
12
  Sage internal domains are available immediately through those tools. External MCP server lifecycle still goes through pi's hub-compat flow when needed.
12
13
 
14
+ ## Agent Profile (Dynamic Identity Context)
15
+
16
+ Every pi session automatically gets Sage Protocol identity context injected into the system prompt. The agent knows who it's working for without any configuration.
17
+
18
+ What gets injected (example):
19
+
20
+ ```
21
+ ## Sage Protocol Context
22
+ Sage Protocol is a decentralized network for collaborative prompt, skill, and knowledge
23
+ curation on Base (L2). Skills and prompts live in libraries governed by DAOs. Creators
24
+ and curators earn when their work is used. SXXX is the governance token: hold it to
25
+ vote, create DAOs, and shape the protocol. Burns from activity create deflationary
26
+ pressure — early participants gain governance influence and economic upside as the
27
+ network grows. The more skills published, the more valuable discovery becomes for every
28
+ user and agent.
29
+
30
+ ### Active Identity
31
+ - Wallet: 0x9794...507ca (privy, Base Sepolia)
32
+ - Active libraries (6): sage-entrypoints, impeccable-ui-review, sage-review-foundations, ...
33
+ - Libraries: 10 installed (48 skills, 12 prompts)
34
+ ```
35
+
36
+ This makes every pi session "sage-aware" — the agent knows the active wallet, network, installed libraries, and available skill count. The context is fetched from the sage CLI (`wallet current`, `library active`, `library list`) and cached for 60 seconds to avoid redundant calls.
37
+
38
+ **Extension mode**: Identity context is appended to the system prompt on every turn via the `before_agent_start` hook.
39
+
40
+ **SDK mode**: Identity context is injected as a hook message at session start via `setupHooks`.
41
+
42
+ The feature is always-on when the sage CLI is available. If the CLI is missing or any query fails, the identity block is silently omitted — it never blocks the agent turn.
43
+
13
44
  For model-driven patching, see `packages/sage-pi-adapter/SKILL.md`.
14
45
 
15
46
  ## Requirements
@@ -72,6 +103,7 @@ export SAGE_SUGGEST_DEBOUNCE_MS=800
72
103
  export SAGE_SECURITY_HOOKS=1
73
104
  export SAGE_RLM_FEEDBACK=1
74
105
  export SAGE_SHOW_HOOK_MESSAGES=1
106
+ export SAGE_ALLOW_BASH_CLI=0 # optional: force MCP-only routing; direct `sage ...` calls are allowed by default, and `env SAGE_ALLOW_BASH_CLI=1 sage ...` re-enables per command
75
107
  ```
76
108
 
77
109
  Manual hook command check (hook reads prompt from env/stdin, not positional args):
@@ -88,6 +120,50 @@ Use plain query mode when testing manually without hook env:
88
120
  sage suggest skill "cpp libraries"
89
121
  ```
90
122
 
123
+ ## Recommended Project Config For Entrypoint Development
124
+
125
+ For a project-local pi setup where Sage owns routing and entrypoint behavior, keep pi
126
+ thin and explicitly point it at the Sage Pi export surface, not the raw Sage authoring root.
127
+
128
+ Recommended `.pi/settings.json` shape for local monorepo development:
129
+
130
+ ```json
131
+ {
132
+ "packages": [
133
+ "../packages/sage-pi-adapter",
134
+ {
135
+ "source": "../packages/sage-pi-export",
136
+ "skills": ["skills/*/SKILL.md"],
137
+ "extensions": [],
138
+ "prompts": [],
139
+ "themes": []
140
+ },
141
+ {
142
+ "source": "npm:oh-pi",
143
+ "extensions": ["!**"]
144
+ }
145
+ ],
146
+ "skills": [
147
+ "-../.agents/skills/frontend-design/SKILL.md",
148
+ "-~/.pi/agent/skills/prompt-builder/SKILL.md",
149
+ "-~/.pi/agent/skills/sage/SKILL.md",
150
+ "-~/.pi/agent/skills/sage-codebase/SKILL.md"
151
+ ],
152
+ "enableSkillCommands": true
153
+ }
154
+ ```
155
+
156
+ Notes:
157
+
158
+ - Paths are relative to `.pi/settings.json`, so the `../packages/...` layout matches this monorepo shape.
159
+ - Prefer the curated `packages/sage-pi-export` surface over broad runtime roots such as `~/.local/share/sage/skills`, `~/.claude/skills`, or `~/.codex/skills`. Those runtime roots often contain backups, version snapshots, and third-party skills that create noisy Pi validation errors and collisions.
160
+ - Keep pi/OpenClaw as the transport and tool layer. Put routing policy and recurring entrypoint behavior in Sage skills and libraries instead of hard-coding them into the harness.
161
+ - Treat repo-authored Sage skills and entrypoint definitions as the authoring source, on-chain libraries as the shared distribution surface, and local sync as development convenience.
162
+ - A good pattern is one thin entrypoint library concept such as `sage-entrypoints` that dispatches into stable Sage-owned dependency libraries by key instead of duplicating their bodies.
163
+ - For example, an entrypoint layer can route into `code-review`, `ceo-plan-review`, or `vc-office-hours` from a stable dependency surface such as `sage-review-foundations` without embedding those skill bodies in the adapter or local config.
164
+ - `packages/sage/pi-export.manifest.json` is the source of truth for what Pi sees by default. `node scripts/util/sync-sage-pi-export.mjs` materializes that manifest into `packages/sage-pi-export/skills/` as symlinks to the real Sage-authored skills.
165
+ - If another plugin or harness layer also injects context automatically, avoid double-injection. Pick one place to do prompt/context steering.
166
+
91
167
  ## Harness Integration (Recommended)
92
168
 
93
169
  ```typescript
package/SKILL.md CHANGED
@@ -41,6 +41,63 @@ pi list
41
41
 
42
42
  Then restart `pi` and verify `sage_status` is callable.
43
43
 
44
+ For project-local monorepo development, prefer an explicit `.pi/settings.json` that
45
+ keeps pi thin and points at the Sage Pi export surface:
46
+
47
+ ```json
48
+ {
49
+ "packages": [
50
+ "../packages/sage-pi-adapter",
51
+ {
52
+ "source": "../packages/sage-pi-export",
53
+ "skills": ["skills/*/SKILL.md"],
54
+ "extensions": [],
55
+ "prompts": [],
56
+ "themes": []
57
+ },
58
+ {
59
+ "source": "npm:oh-pi",
60
+ "extensions": ["!**"]
61
+ }
62
+ ],
63
+ "skills": [
64
+ "-../.agents/skills/frontend-design/SKILL.md",
65
+ "-~/.pi/agent/skills/prompt-builder/SKILL.md",
66
+ "-~/.pi/agent/skills/sage/SKILL.md",
67
+ "-~/.pi/agent/skills/sage-codebase/SKILL.md"
68
+ ],
69
+ "enableSkillCommands": true
70
+ }
71
+ ```
72
+
73
+ This keeps the harness responsible for transport and tool exposure while Sage skills
74
+ and libraries own the routing and behavior layer.
75
+
76
+ The package-filtered `../packages/sage-pi-export` entry is intentional: it exposes a Pi-safe,
77
+ curated Sage surface without scanning broad runtime roots such as `~/.local/share/sage/skills`,
78
+ which often contain backup directories, version snapshots, and third-party installs that are valid
79
+ for Sage runtime use but noisy for Pi skill validation.
80
+
81
+ Architectural posture:
82
+
83
+ - pi/OpenClaw = transport and tool surface
84
+ - `sage` = router and tool-aware base skill
85
+ - repo-authored entrypoint definitions = authoring layer
86
+ - on-chain libraries = shared distribution and sync/pull layer
87
+ - local sync = development convenience
88
+
89
+ The entrypoint layer should stay thin. It should dispatch into stable Sage-owned dependency
90
+ libraries by key, not duplicate them. For example, a review or planning entrypoint can route into
91
+ `code-review`, `ceo-plan-review`, or `vc-office-hours` from `sage-review-foundations` without
92
+ copying those skill bodies.
93
+
94
+ Pi export surface rule:
95
+
96
+ - author real skills under `packages/sage/skills/`
97
+ - declare Pi-visible skills in `packages/sage/pi-export.manifest.json`
98
+ - materialize the Pi-safe surface with `node scripts/util/sync-sage-pi-export.mjs`
99
+ - point `.pi/settings.json` at `../packages/sage-pi-export`, not at the raw authoring tree
100
+
44
101
  Hook command semantics:
45
102
 
46
103
  - `sage suggest hook skill` reads prompt from env/stdin (for IDE/agent hooks)
@@ -0,0 +1,10 @@
1
+ /**
2
+ * @file behavior/index.ts
3
+ *
4
+ * Responsibility: Public API surface for the behavior execution subsystem.
5
+ * Re-exports types and implementations — nothing else.
6
+ */
7
+ export type { BehaviorExecutor, BehaviorPlan, BehaviorResolved, ExecutionContext, ExecutionResult, PlanInput, PlanStep, ResolvedSkill, StepProgressCallback, StepResult, StepStatus, } from "./types.js";
8
+ export { resolveBehaviorPlan } from "./resolver.js";
9
+ export { PiBehaviorExecutor, type PiExecutorConfig } from "./pi-executor.js";
10
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/behavior/index.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAEH,YAAY,EACV,gBAAgB,EAChB,YAAY,EACZ,gBAAgB,EAChB,gBAAgB,EAChB,eAAe,EACf,SAAS,EACT,QAAQ,EACR,aAAa,EACb,oBAAoB,EACpB,UAAU,EACV,UAAU,GACX,MAAM,YAAY,CAAC;AAEpB,OAAO,EAAE,mBAAmB,EAAE,MAAM,eAAe,CAAC;AACpD,OAAO,EAAE,kBAAkB,EAAE,KAAK,gBAAgB,EAAE,MAAM,kBAAkB,CAAC"}
@@ -0,0 +1,9 @@
1
+ /**
2
+ * @file behavior/index.ts
3
+ *
4
+ * Responsibility: Public API surface for the behavior execution subsystem.
5
+ * Re-exports types and implementations — nothing else.
6
+ */
7
+ export { resolveBehaviorPlan } from "./resolver.js";
8
+ export { PiBehaviorExecutor } from "./pi-executor.js";
9
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/behavior/index.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAgBH,OAAO,EAAE,mBAAmB,EAAE,MAAM,eAAe,CAAC;AACpD,OAAO,EAAE,kBAAkB,EAAyB,MAAM,kBAAkB,CAAC"}
@@ -0,0 +1,83 @@
1
+ /**
2
+ * @file behavior/pi-executor.ts
3
+ *
4
+ * Responsibility: Pi-specific implementation of the BehaviorExecutor interface.
5
+ * Executes behavior plan steps as pi subagent invocations.
6
+ *
7
+ * Invariants:
8
+ * - Each step runs in an isolated subagent context (explorer for read-only, worker for mutations).
9
+ * - Inter-step results are threaded via the subagent task message.
10
+ * - MCP servers from the plan's mcp_servers_union are provisioned before execution.
11
+ * - Cancellation via AbortSignal is respected between steps (not mid-step).
12
+ * - This file is the ONLY place that depends on pi's subagent API.
13
+ */
14
+ import type { SageMcpBridge } from "../sage-pi-adapter.js";
15
+ import type { BehaviorExecutor, BehaviorPlan, ExecutionContext, ExecutionResult } from "./types.js";
16
+ /**
17
+ * Configuration for the pi behavior executor.
18
+ */
19
+ export interface PiExecutorConfig {
20
+ /** MCP bridge for resolving behavior plans. */
21
+ bridge: SageMcpBridge;
22
+ /** Maximum time per step in milliseconds (default: 120_000). */
23
+ stepTimeoutMs?: number;
24
+ /** Pi extension API for sending messages. */
25
+ sendMessage?: (message: {
26
+ customType: string;
27
+ content: string;
28
+ display: boolean;
29
+ }) => void;
30
+ }
31
+ /**
32
+ * Pi-specific BehaviorExecutor.
33
+ *
34
+ * Executes behavior plan steps sequentially, threading output from each step
35
+ * as context into the next. In pi, each step maps to a subagent task — but
36
+ * since the adapter runs as an extension (not the agent loop controller),
37
+ * we execute via tool result injection: the plan is rendered as a structured
38
+ * controller prompt that the agent follows step-by-step.
39
+ *
40
+ * Why not spawn_agent directly?
41
+ * The pi extension API doesn't expose spawn_agent — that's a tool available
42
+ * to the agent itself. The executor prepares the plan for the agent to execute,
43
+ * optionally with subagent delegation hints.
44
+ *
45
+ * Execution modes:
46
+ * 1. **Controller prompt** (default): Render the plan as a structured prompt
47
+ * the agent follows. Steps include skill content and dependency hints.
48
+ * The agent decides whether to use subagents based on step complexity.
49
+ *
50
+ * 2. **Explicit delegation** (future): For plans with `isolation: "subagent"`
51
+ * on steps, the executor would need the agent to call spawn_agent per step.
52
+ * This requires the agent loop, not the extension layer.
53
+ */
54
+ export declare class PiBehaviorExecutor implements BehaviorExecutor {
55
+ readonly name = "pi-behavior-executor";
56
+ private readonly bridge;
57
+ private readonly stepTimeoutMs;
58
+ private readonly sendMessage?;
59
+ constructor(config: PiExecutorConfig);
60
+ resolve(key: string): Promise<BehaviorPlan>;
61
+ canExecute(plan: BehaviorPlan): boolean;
62
+ execute(plan: BehaviorPlan, context: ExecutionContext): Promise<ExecutionResult>;
63
+ /**
64
+ * Render a behavior plan as a structured controller prompt.
65
+ *
66
+ * The controller prompt is designed to be injected into the agent's context,
67
+ * giving it a step-by-step execution plan with:
68
+ * - Skill content for each step
69
+ * - Dependency hints (which steps feed into which)
70
+ * - MCP server requirements
71
+ * - Subagent delegation hints for complex steps
72
+ */
73
+ private renderControllerPrompt;
74
+ /**
75
+ * Heuristic: suggest subagent delegation for steps that benefit from isolation.
76
+ *
77
+ * - Plans with 4+ steps: suggest subagents for analysis-heavy steps
78
+ * - Steps with large instruction bodies (>2000 chars): benefit from dedicated context
79
+ * - Steps that are read-only analysis: explorer subagent
80
+ */
81
+ private shouldSuggestSubagent;
82
+ }
83
+ //# sourceMappingURL=pi-executor.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"pi-executor.d.ts","sourceRoot":"","sources":["../../src/behavior/pi-executor.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;GAYG;AAEH,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,uBAAuB,CAAC;AAE3D,OAAO,KAAK,EAEV,gBAAgB,EAChB,YAAY,EACZ,gBAAgB,EAChB,eAAe,EAGhB,MAAM,YAAY,CAAC;AAEpB;;GAEG;AACH,MAAM,WAAW,gBAAgB;IAC/B,+CAA+C;IAC/C,MAAM,EAAE,aAAa,CAAC;IACtB,gEAAgE;IAChE,aAAa,CAAC,EAAE,MAAM,CAAC;IACvB,6CAA6C;IAC7C,WAAW,CAAC,EAAE,CAAC,OAAO,EAAE;QAAE,UAAU,EAAE,MAAM,CAAC;QAAC,OAAO,EAAE,MAAM,CAAC;QAAC,OAAO,EAAE,OAAO,CAAA;KAAE,KAAK,IAAI,CAAC;CAC5F;AAED;;;;;;;;;;;;;;;;;;;;;;GAsBG;AACH,qBAAa,kBAAmB,YAAW,gBAAgB;IACzD,QAAQ,CAAC,IAAI,0BAA0B;IACvC,OAAO,CAAC,QAAQ,CAAC,MAAM,CAAgB;IACvC,OAAO,CAAC,QAAQ,CAAC,aAAa,CAAS;IACvC,OAAO,CAAC,QAAQ,CAAC,WAAW,CAAC,CAAkC;gBAEnD,MAAM,EAAE,gBAAgB;IAM9B,OAAO,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAAC,YAAY,CAAC;IAIjD,UAAU,CAAC,IAAI,EAAE,YAAY,GAAG,OAAO;IAKjC,OAAO,CAAC,IAAI,EAAE,YAAY,EAAE,OAAO,EAAE,gBAAgB,GAAG,OAAO,CAAC,eAAe,CAAC;IAqCtF;;;;;;;;;OASG;IACH,OAAO,CAAC,sBAAsB;IA8D9B;;;;;;OAMG;IACH,OAAO,CAAC,qBAAqB;CAO9B"}
@@ -0,0 +1,163 @@
1
+ /**
2
+ * @file behavior/pi-executor.ts
3
+ *
4
+ * Responsibility: Pi-specific implementation of the BehaviorExecutor interface.
5
+ * Executes behavior plan steps as pi subagent invocations.
6
+ *
7
+ * Invariants:
8
+ * - Each step runs in an isolated subagent context (explorer for read-only, worker for mutations).
9
+ * - Inter-step results are threaded via the subagent task message.
10
+ * - MCP servers from the plan's mcp_servers_union are provisioned before execution.
11
+ * - Cancellation via AbortSignal is respected between steps (not mid-step).
12
+ * - This file is the ONLY place that depends on pi's subagent API.
13
+ */
14
+ import { resolveBehaviorPlan } from "./resolver.js";
15
+ /**
16
+ * Pi-specific BehaviorExecutor.
17
+ *
18
+ * Executes behavior plan steps sequentially, threading output from each step
19
+ * as context into the next. In pi, each step maps to a subagent task — but
20
+ * since the adapter runs as an extension (not the agent loop controller),
21
+ * we execute via tool result injection: the plan is rendered as a structured
22
+ * controller prompt that the agent follows step-by-step.
23
+ *
24
+ * Why not spawn_agent directly?
25
+ * The pi extension API doesn't expose spawn_agent — that's a tool available
26
+ * to the agent itself. The executor prepares the plan for the agent to execute,
27
+ * optionally with subagent delegation hints.
28
+ *
29
+ * Execution modes:
30
+ * 1. **Controller prompt** (default): Render the plan as a structured prompt
31
+ * the agent follows. Steps include skill content and dependency hints.
32
+ * The agent decides whether to use subagents based on step complexity.
33
+ *
34
+ * 2. **Explicit delegation** (future): For plans with `isolation: "subagent"`
35
+ * on steps, the executor would need the agent to call spawn_agent per step.
36
+ * This requires the agent loop, not the extension layer.
37
+ */
38
+ export class PiBehaviorExecutor {
39
+ name = "pi-behavior-executor";
40
+ bridge;
41
+ stepTimeoutMs;
42
+ sendMessage;
43
+ constructor(config) {
44
+ this.bridge = config.bridge;
45
+ this.stepTimeoutMs = config.stepTimeoutMs ?? 120_000;
46
+ this.sendMessage = config.sendMessage;
47
+ }
48
+ async resolve(key) {
49
+ return resolveBehaviorPlan(this.bridge, key);
50
+ }
51
+ canExecute(plan) {
52
+ // We can execute any linear plan. Reject empty plans.
53
+ return plan.steps.length > 0;
54
+ }
55
+ async execute(plan, context) {
56
+ const startTime = Date.now();
57
+ const results = [];
58
+ // Render the plan as a controller prompt for the agent.
59
+ const controllerPrompt = this.renderControllerPrompt(plan, context);
60
+ // Report plan to the agent via hook message
61
+ if (this.sendMessage) {
62
+ this.sendMessage({
63
+ customType: "sage-behavior-plan",
64
+ content: controllerPrompt,
65
+ display: true,
66
+ });
67
+ }
68
+ // Mark all steps as pending — the agent will execute them via the
69
+ // controller prompt. We track them for observability.
70
+ for (const step of plan.steps) {
71
+ const stepStart = Date.now();
72
+ context.onProgress?.(step.id, "pending");
73
+ results.push({
74
+ stepId: step.id,
75
+ status: "pending",
76
+ durationMs: Date.now() - stepStart,
77
+ });
78
+ }
79
+ return {
80
+ status: "completed",
81
+ steps: results,
82
+ totalDurationMs: Date.now() - startTime,
83
+ output: controllerPrompt,
84
+ };
85
+ }
86
+ /**
87
+ * Render a behavior plan as a structured controller prompt.
88
+ *
89
+ * The controller prompt is designed to be injected into the agent's context,
90
+ * giving it a step-by-step execution plan with:
91
+ * - Skill content for each step
92
+ * - Dependency hints (which steps feed into which)
93
+ * - MCP server requirements
94
+ * - Subagent delegation hints for complex steps
95
+ */
96
+ renderControllerPrompt(plan, context) {
97
+ const lines = [];
98
+ lines.push("# Behavior Execution Plan");
99
+ lines.push("");
100
+ lines.push(`**Task:** ${context.task}`);
101
+ lines.push(`**Steps:** ${plan.steps.length}`);
102
+ lines.push("");
103
+ if (context.mcpServersRequired.length > 0) {
104
+ lines.push("## Required MCP Servers");
105
+ for (const server of context.mcpServersRequired) {
106
+ lines.push(`- \`${server}\``);
107
+ }
108
+ lines.push("");
109
+ }
110
+ lines.push("## Execution Steps");
111
+ lines.push("");
112
+ lines.push("Execute the following steps **in order**. Each step builds on the previous.");
113
+ lines.push("For complex steps, consider delegating to a subagent (explorer for analysis, worker for implementation).");
114
+ lines.push("");
115
+ for (let i = 0; i < plan.steps.length; i++) {
116
+ const step = plan.steps[i];
117
+ lines.push(`### Step ${i + 1}: ${step.title}`);
118
+ lines.push("");
119
+ lines.push(`**Skill:** \`${step.skill_key}\``);
120
+ if (step.uses.length > 0) {
121
+ lines.push(`**Depends on:** ${step.uses.join(", ")}`);
122
+ }
123
+ lines.push("");
124
+ if (step.instruction) {
125
+ lines.push(step.instruction);
126
+ lines.push("");
127
+ }
128
+ // Subagent delegation hint for steps that benefit from isolation
129
+ if (this.shouldSuggestSubagent(step, plan.steps.length)) {
130
+ lines.push(`> 💡 **Subagent hint:** This step may benefit from running in an isolated subagent.`);
131
+ lines.push(`> Use \`explorer\` for analysis/read-only steps, \`worker\` for implementation steps.`);
132
+ lines.push("");
133
+ }
134
+ if (i < plan.steps.length - 1) {
135
+ lines.push("---");
136
+ lines.push("");
137
+ }
138
+ }
139
+ lines.push("");
140
+ lines.push("## Completion");
141
+ lines.push("");
142
+ lines.push("After completing all steps, synthesize the results into a coherent response.");
143
+ lines.push("Reference findings from each step and note any cross-step insights.");
144
+ return lines.join("\n");
145
+ }
146
+ /**
147
+ * Heuristic: suggest subagent delegation for steps that benefit from isolation.
148
+ *
149
+ * - Plans with 4+ steps: suggest subagents for analysis-heavy steps
150
+ * - Steps with large instruction bodies (>2000 chars): benefit from dedicated context
151
+ * - Steps that are read-only analysis: explorer subagent
152
+ */
153
+ shouldSuggestSubagent(step, totalSteps) {
154
+ if (totalSteps < 3)
155
+ return false; // Small plans don't need subagent overhead
156
+ if (step.instruction.length > 2000)
157
+ return true; // Large skill content benefits from isolation
158
+ // Analysis/review skills benefit from subagent isolation
159
+ const analysisKeywords = ["review", "audit", "analysis", "assess", "evaluate", "critique"];
160
+ return analysisKeywords.some((kw) => step.skill_key.includes(kw) || step.title.toLowerCase().includes(kw));
161
+ }
162
+ }
163
+ //# sourceMappingURL=pi-executor.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"pi-executor.js","sourceRoot":"","sources":["../../src/behavior/pi-executor.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,20 @@
1
+ /**
2
+ * @file behavior/resolver.ts
3
+ *
4
+ * Responsibility: Resolve behavior keys into BehaviorPlans via Sage MCP.
5
+ *
6
+ * Invariants:
7
+ * - Resolution always goes through the MCP bridge (never direct file reads).
8
+ * - Returns a validated BehaviorPlan or throws with a clear error.
9
+ * - The resolver is stateless — no caching (Sage MCP handles that).
10
+ */
11
+ import type { SageMcpBridge } from "../sage-pi-adapter.js";
12
+ import type { BehaviorPlan } from "./types.js";
13
+ /**
14
+ * Resolve a behavior key into a BehaviorPlan via Sage MCP.
15
+ *
16
+ * Calls `get_prompt(key, expand: ["behaviorPlan", "behaviorSkillBodies"])`
17
+ * through the MCP bridge and extracts the plan from the response.
18
+ */
19
+ export declare function resolveBehaviorPlan(bridge: SageMcpBridge, key: string): Promise<BehaviorPlan>;
20
+ //# sourceMappingURL=resolver.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"resolver.d.ts","sourceRoot":"","sources":["../../src/behavior/resolver.ts"],"names":[],"mappings":"AAAA;;;;;;;;;GASG;AAEH,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,uBAAuB,CAAC;AAC3D,OAAO,KAAK,EAAE,YAAY,EAAY,MAAM,YAAY,CAAC;AAEzD;;;;;GAKG;AACH,wBAAsB,mBAAmB,CACvC,MAAM,EAAE,aAAa,EACrB,GAAG,EAAE,MAAM,GACV,OAAO,CAAC,YAAY,CAAC,CAiBvB"}
@@ -0,0 +1,163 @@
1
+ /**
2
+ * @file behavior/resolver.ts
3
+ *
4
+ * Responsibility: Resolve behavior keys into BehaviorPlans via Sage MCP.
5
+ *
6
+ * Invariants:
7
+ * - Resolution always goes through the MCP bridge (never direct file reads).
8
+ * - Returns a validated BehaviorPlan or throws with a clear error.
9
+ * - The resolver is stateless — no caching (Sage MCP handles that).
10
+ */
11
+ /**
12
+ * Resolve a behavior key into a BehaviorPlan via Sage MCP.
13
+ *
14
+ * Calls `get_prompt(key, expand: ["behaviorPlan", "behaviorSkillBodies"])`
15
+ * through the MCP bridge and extracts the plan from the response.
16
+ */
17
+ export async function resolveBehaviorPlan(bridge, key) {
18
+ if (!bridge.isReady()) {
19
+ throw new Error(`Cannot resolve behavior '${key}': Sage MCP bridge is not connected`);
20
+ }
21
+ // Call Sage MCP to get the behavior with plan expansion.
22
+ // The expand modes progressively resolve: parse → resolve → plan → bodies.
23
+ const result = await bridge.callCodeModeExecute({
24
+ domain: "prompts",
25
+ action: "get",
26
+ params: {
27
+ key,
28
+ expand: ["behaviorPlan", "behaviorSkillBodies"],
29
+ },
30
+ });
31
+ return extractPlanFromResult(result, key);
32
+ }
33
+ /**
34
+ * Extract and validate a BehaviorPlan from an MCP result.
35
+ *
36
+ * The MCP response may contain the plan in several locations depending
37
+ * on the Sage MCP version:
38
+ * - result.content[].text (JSON string)
39
+ * - result.extra.behaviorPlan (object)
40
+ * - result.plan (object)
41
+ */
42
+ function extractPlanFromResult(result, key) {
43
+ if (!result || typeof result !== "object") {
44
+ throw new Error(`Empty response when resolving behavior '${key}'`);
45
+ }
46
+ const obj = result;
47
+ // Try structured plan field first (multiple nesting levels)
48
+ const promptEnvelope = obj.prompt;
49
+ const planCandidate = obj.plan ??
50
+ obj.behaviorPlan ??
51
+ obj.extra?.behaviorPlan ??
52
+ promptEnvelope?.behaviorPlan;
53
+ if (planCandidate && typeof planCandidate === "object") {
54
+ return validatePlan(planCandidate, key);
55
+ }
56
+ // Try parsing from MCP content text blocks
57
+ if (Array.isArray(obj.content)) {
58
+ for (const block of obj.content) {
59
+ if (!block || typeof block !== "object")
60
+ continue;
61
+ const text = block.text;
62
+ if (typeof text !== "string")
63
+ continue;
64
+ // Try JSON parse — the plan may be embedded as JSON
65
+ try {
66
+ const parsed = JSON.parse(text);
67
+ if (parsed && typeof parsed === "object" && Array.isArray(parsed.steps)) {
68
+ return validatePlan(parsed, key);
69
+ }
70
+ // Check nested
71
+ if (parsed.plan && typeof parsed.plan === "object" && Array.isArray(parsed.plan.steps)) {
72
+ return validatePlan(parsed.plan, key);
73
+ }
74
+ if (parsed.behaviorPlan && typeof parsed.behaviorPlan === "object") {
75
+ return validatePlan(parsed.behaviorPlan, key);
76
+ }
77
+ // Check inside prompt envelope — get_prompt returns { prompt: { behaviorPlan: ... } }
78
+ if (parsed.prompt &&
79
+ typeof parsed.prompt === "object" &&
80
+ parsed.prompt.behaviorPlan &&
81
+ typeof parsed.prompt.behaviorPlan === "object") {
82
+ return validatePlan(parsed.prompt.behaviorPlan, key);
83
+ }
84
+ }
85
+ catch {
86
+ // Not JSON — may be the rendered markdown controller prompt.
87
+ // Extract plan structure from markdown if possible.
88
+ const markdownPlan = parseMarkdownPlan(text, key);
89
+ if (markdownPlan)
90
+ return markdownPlan;
91
+ }
92
+ }
93
+ }
94
+ throw new Error(`Could not extract behavior plan from response for '${key}'. ` +
95
+ `The behavior may not exist or may not have the 'behavior' field in its prompt extra.`);
96
+ }
97
+ /** Validate a raw object as a BehaviorPlan. */
98
+ function validatePlan(raw, key) {
99
+ const steps = raw.steps;
100
+ if (!Array.isArray(steps) || steps.length === 0) {
101
+ throw new Error(`Behavior '${key}' resolved but has no steps`);
102
+ }
103
+ const validSteps = steps.map((step, i) => {
104
+ if (!step || typeof step !== "object") {
105
+ throw new Error(`Step ${i} in behavior '${key}' is not an object`);
106
+ }
107
+ const s = step;
108
+ return {
109
+ id: typeof s.id === "string" ? s.id : `step-${i + 1}`,
110
+ title: typeof s.title === "string" ? s.title : `Step ${i + 1}`,
111
+ skill_key: typeof s.skill_key === "string" ? s.skill_key : "",
112
+ instruction: typeof s.instruction === "string" ? s.instruction : "",
113
+ uses: Array.isArray(s.uses) ? s.uses : [],
114
+ produces: Array.isArray(s.produces) ? s.produces : [`output-${i + 1}`],
115
+ };
116
+ });
117
+ return {
118
+ version: typeof raw.version === "string" ? raw.version : "1",
119
+ inputs: Array.isArray(raw.inputs)
120
+ ? raw.inputs.map((inp) => ({
121
+ name: String(inp.name ?? ""),
122
+ description: typeof inp.description === "string" ? inp.description : undefined,
123
+ required: Boolean(inp.required),
124
+ }))
125
+ : [{ name: "task", required: true, description: "The task to perform" }],
126
+ steps: validSteps,
127
+ };
128
+ }
129
+ /**
130
+ * Best-effort extraction of plan steps from Sage's rendered markdown controller prompt.
131
+ *
132
+ * When the MCP response is the rendered markdown (not raw JSON), parse step
133
+ * headers like "### Step 1: Skill Name" to reconstruct the plan structure.
134
+ */
135
+ function parseMarkdownPlan(markdown, key) {
136
+ const stepPattern = /^###?\s+Step\s+(\d+):\s+(.+)$/gm;
137
+ const steps = [];
138
+ let match;
139
+ while ((match = stepPattern.exec(markdown)) !== null) {
140
+ const stepNum = parseInt(match[1], 10);
141
+ const title = match[2].trim();
142
+ // Extract skill key from the line after "**Skill**: `key`"
143
+ const afterHeader = markdown.slice(match.index + match[0].length, match.index + match[0].length + 500);
144
+ const skillMatch = afterHeader.match(/\*\*Skill\*\*:\s*`([^`]+)`/);
145
+ const instructionMatch = afterHeader.match(/\*\*Instruction\*\*:\s*(.+?)(?:\n\*\*|\n###|$)/s);
146
+ steps.push({
147
+ id: `step-${stepNum}`,
148
+ title,
149
+ skill_key: skillMatch?.[1] ?? title.toLowerCase().replace(/\s+/g, "-"),
150
+ instruction: instructionMatch?.[1]?.trim() ?? `Apply the ${title} skill`,
151
+ uses: stepNum > 1 ? [`step-${stepNum - 1}`] : [],
152
+ produces: [`output-${stepNum}`],
153
+ });
154
+ }
155
+ if (steps.length === 0)
156
+ return null;
157
+ return {
158
+ version: "1",
159
+ inputs: [{ name: "task", required: true, description: "The task to perform" }],
160
+ steps,
161
+ };
162
+ }
163
+ //# sourceMappingURL=resolver.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"resolver.js","sourceRoot":"","sources":["../../src/behavior/resolver.ts"],"names":[],"mappings":"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"}