@introspection-ai/recipes 0.13.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.
Files changed (161) hide show
  1. package/LICENSE +191 -0
  2. package/README.md +184 -0
  3. package/dist/agent-tool.d.ts +42 -0
  4. package/dist/agent-tool.d.ts.map +1 -0
  5. package/dist/agent-tool.js +159 -0
  6. package/dist/agent-tool.js.map +1 -0
  7. package/dist/child-agent-completions.d.ts +61 -0
  8. package/dist/child-agent-completions.d.ts.map +1 -0
  9. package/dist/child-agent-completions.js +135 -0
  10. package/dist/child-agent-completions.js.map +1 -0
  11. package/dist/child-agent-store.d.ts +48 -0
  12. package/dist/child-agent-store.d.ts.map +1 -0
  13. package/dist/child-agent-store.js +98 -0
  14. package/dist/child-agent-store.js.map +1 -0
  15. package/dist/child-agent.d.ts +43 -0
  16. package/dist/child-agent.d.ts.map +1 -0
  17. package/dist/child-agent.js +268 -0
  18. package/dist/child-agent.js.map +1 -0
  19. package/dist/direct-cli.d.ts +9 -0
  20. package/dist/direct-cli.d.ts.map +1 -0
  21. package/dist/direct-cli.js +22 -0
  22. package/dist/direct-cli.js.map +1 -0
  23. package/dist/index.d.ts +14 -0
  24. package/dist/index.d.ts.map +1 -0
  25. package/dist/index.js +14 -0
  26. package/dist/index.js.map +1 -0
  27. package/dist/inspect.d.ts +26 -0
  28. package/dist/inspect.d.ts.map +1 -0
  29. package/dist/inspect.js +70 -0
  30. package/dist/inspect.js.map +1 -0
  31. package/dist/interactions.d.ts +204 -0
  32. package/dist/interactions.d.ts.map +1 -0
  33. package/dist/interactions.js +358 -0
  34. package/dist/interactions.js.map +1 -0
  35. package/dist/mcp-catalog.d.ts +8 -0
  36. package/dist/mcp-catalog.d.ts.map +1 -0
  37. package/dist/mcp-catalog.js +60 -0
  38. package/dist/mcp-catalog.js.map +1 -0
  39. package/dist/mcp-cli-core.d.ts +79 -0
  40. package/dist/mcp-cli-core.d.ts.map +1 -0
  41. package/dist/mcp-cli-core.js +1717 -0
  42. package/dist/mcp-cli-core.js.map +1 -0
  43. package/dist/mcp-cli-help.d.ts +2 -0
  44. package/dist/mcp-cli-help.d.ts.map +1 -0
  45. package/dist/mcp-cli-help.js +36 -0
  46. package/dist/mcp-cli-help.js.map +1 -0
  47. package/dist/mcp-cli-policy.d.ts +17 -0
  48. package/dist/mcp-cli-policy.d.ts.map +1 -0
  49. package/dist/mcp-cli-policy.js +230 -0
  50. package/dist/mcp-cli-policy.js.map +1 -0
  51. package/dist/mcp-cli.d.ts +3 -0
  52. package/dist/mcp-cli.d.ts.map +1 -0
  53. package/dist/mcp-cli.js +33 -0
  54. package/dist/mcp-cli.js.map +1 -0
  55. package/dist/mcp-client.d.ts +3 -0
  56. package/dist/mcp-client.d.ts.map +1 -0
  57. package/dist/mcp-client.js +86 -0
  58. package/dist/mcp-client.js.map +1 -0
  59. package/dist/mcp-command-context.d.ts +13 -0
  60. package/dist/mcp-command-context.d.ts.map +1 -0
  61. package/dist/mcp-command-context.js +29 -0
  62. package/dist/mcp-command-context.js.map +1 -0
  63. package/dist/mcp-contract.d.ts +16 -0
  64. package/dist/mcp-contract.d.ts.map +1 -0
  65. package/dist/mcp-contract.js +306 -0
  66. package/dist/mcp-contract.js.map +1 -0
  67. package/dist/mcp-daemon-client.d.ts +10 -0
  68. package/dist/mcp-daemon-client.d.ts.map +1 -0
  69. package/dist/mcp-daemon-client.js +119 -0
  70. package/dist/mcp-daemon-client.js.map +1 -0
  71. package/dist/mcp-daemon-protocol.d.ts +64 -0
  72. package/dist/mcp-daemon-protocol.d.ts.map +1 -0
  73. package/dist/mcp-daemon-protocol.js +6 -0
  74. package/dist/mcp-daemon-protocol.js.map +1 -0
  75. package/dist/mcp-daemon.d.ts +3 -0
  76. package/dist/mcp-daemon.d.ts.map +1 -0
  77. package/dist/mcp-daemon.js +76880 -0
  78. package/dist/mcp-daemon.js.map +1 -0
  79. package/dist/mcp-run-worker.d.ts +2 -0
  80. package/dist/mcp-run-worker.d.ts.map +1 -0
  81. package/dist/mcp-run-worker.js +76579 -0
  82. package/dist/mcp-run-worker.js.map +1 -0
  83. package/dist/mcp.d.ts +168 -0
  84. package/dist/mcp.d.ts.map +1 -0
  85. package/dist/mcp.js +558 -0
  86. package/dist/mcp.js.map +1 -0
  87. package/dist/pi-extension.d.ts +30 -0
  88. package/dist/pi-extension.d.ts.map +1 -0
  89. package/dist/pi-extension.js +880 -0
  90. package/dist/pi-extension.js.map +1 -0
  91. package/dist/provider-env.d.ts +2 -0
  92. package/dist/provider-env.d.ts.map +1 -0
  93. package/dist/provider-env.js +21 -0
  94. package/dist/provider-env.js.map +1 -0
  95. package/dist/recipe/resolve.d.ts +30 -0
  96. package/dist/recipe/resolve.d.ts.map +1 -0
  97. package/dist/recipe/resolve.js +131 -0
  98. package/dist/recipe/resolve.js.map +1 -0
  99. package/dist/recipe-agent.d.ts +71 -0
  100. package/dist/recipe-agent.d.ts.map +1 -0
  101. package/dist/recipe-agent.js +555 -0
  102. package/dist/recipe-agent.js.map +1 -0
  103. package/dist/recipe-extensions.d.ts +9 -0
  104. package/dist/recipe-extensions.d.ts.map +1 -0
  105. package/dist/recipe-extensions.js +81 -0
  106. package/dist/recipe-extensions.js.map +1 -0
  107. package/dist/recipe-mcp-config.d.ts +15 -0
  108. package/dist/recipe-mcp-config.d.ts.map +1 -0
  109. package/dist/recipe-mcp-config.js +82 -0
  110. package/dist/recipe-mcp-config.js.map +1 -0
  111. package/dist/recipe-model.d.ts +49 -0
  112. package/dist/recipe-model.d.ts.map +1 -0
  113. package/dist/recipe-model.js +299 -0
  114. package/dist/recipe-model.js.map +1 -0
  115. package/dist/recipe-package.d.ts +79 -0
  116. package/dist/recipe-package.d.ts.map +1 -0
  117. package/dist/recipe-package.js +479 -0
  118. package/dist/recipe-package.js.map +1 -0
  119. package/dist/recipe-skills.d.ts +7 -0
  120. package/dist/recipe-skills.d.ts.map +1 -0
  121. package/dist/recipe-skills.js +46 -0
  122. package/dist/recipe-skills.js.map +1 -0
  123. package/dist/run-controller.d.ts +32 -0
  124. package/dist/run-controller.d.ts.map +1 -0
  125. package/dist/run-controller.js +259 -0
  126. package/dist/run-controller.js.map +1 -0
  127. package/dist/run.d.ts +28 -0
  128. package/dist/run.d.ts.map +1 -0
  129. package/dist/run.js +84 -0
  130. package/dist/run.js.map +1 -0
  131. package/dist/session.d.ts +140 -0
  132. package/dist/session.d.ts.map +1 -0
  133. package/dist/session.js +363 -0
  134. package/dist/session.js.map +1 -0
  135. package/dist/test-utils.d.ts +32 -0
  136. package/dist/test-utils.d.ts.map +1 -0
  137. package/dist/test-utils.js +259 -0
  138. package/dist/test-utils.js.map +1 -0
  139. package/dist/testing.d.ts +25 -0
  140. package/dist/testing.d.ts.map +1 -0
  141. package/dist/testing.js +96 -0
  142. package/dist/testing.js.map +1 -0
  143. package/docs/agent-composition.md +196 -0
  144. package/docs/deployment-configuration.md +65 -0
  145. package/docs/index.md +49 -0
  146. package/docs/interactions.md +210 -0
  147. package/docs/mcp-auth.md +80 -0
  148. package/docs/mcp-configuration.md +126 -0
  149. package/docs/migration.md +70 -0
  150. package/docs/pi-extension.md +97 -0
  151. package/docs/python-bindings-release.md +47 -0
  152. package/docs/recipe-evals.md +70 -0
  153. package/docs/recipe-flow.md +41 -0
  154. package/docs/recipe-format.md +186 -0
  155. package/docs/recipe-judges.md +152 -0
  156. package/docs/runtime-library.md +171 -0
  157. package/package.json +106 -0
  158. package/vendor/mcp-client/darwin-arm64/mcp-client +0 -0
  159. package/vendor/mcp-client/darwin-x64/mcp-client +0 -0
  160. package/vendor/mcp-client/linux-arm64/mcp-client +0 -0
  161. package/vendor/mcp-client/linux-x64/mcp-client +0 -0
@@ -0,0 +1 @@
1
+ {"version":3,"file":"test-utils.js","sourceRoot":"","sources":["../src/test-utils.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,25 @@
1
+ import type { ExtensionEvent, ExtensionAPI, RegisteredCommand, ToolDefinition } from "@earendil-works/pi-coding-agent";
2
+ export interface MockExtensionAPI extends ExtensionAPI {
3
+ commands: Map<string, Omit<RegisteredCommand, "name" | "sourceInfo">>;
4
+ tools: Map<string, ToolDefinition<any, any, any>>;
5
+ flags: Map<string, {
6
+ description?: string;
7
+ type: "boolean" | "string";
8
+ default?: boolean | string;
9
+ }>;
10
+ flagValues: Map<string, boolean | string>;
11
+ handlers: Map<string, Array<(event: any, ctx: any) => unknown>>;
12
+ messages: unknown[];
13
+ sentMessages: Array<{
14
+ message: any;
15
+ options?: any;
16
+ }>;
17
+ messageRenderers: Map<string, (message: any, options: any, theme: any) => unknown>;
18
+ sessionName?: string;
19
+ activeTools: string[];
20
+ thinkingLevel?: string;
21
+ model?: unknown;
22
+ emitExtensionEvent(event: ExtensionEvent, ctx: any): Promise<unknown[]>;
23
+ }
24
+ export declare function createMockExtensionAPI(): MockExtensionAPI;
25
+ //# sourceMappingURL=testing.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"testing.d.ts","sourceRoot":"","sources":["../src/testing.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EACV,cAAc,EACd,YAAY,EACZ,iBAAiB,EACjB,cAAc,EACf,MAAM,iCAAiC,CAAC;AAEzC,MAAM,WAAW,gBAAiB,SAAQ,YAAY;IACpD,QAAQ,EAAE,GAAG,CAAC,MAAM,EAAE,IAAI,CAAC,iBAAiB,EAAE,MAAM,GAAG,YAAY,CAAC,CAAC,CAAC;IACtE,KAAK,EAAE,GAAG,CAAC,MAAM,EAAE,cAAc,CAAC,GAAG,EAAE,GAAG,EAAE,GAAG,CAAC,CAAC,CAAC;IAClD,KAAK,EAAE,GAAG,CAAC,MAAM,EAAE;QAAE,WAAW,CAAC,EAAE,MAAM,CAAC;QAAC,IAAI,EAAE,SAAS,GAAG,QAAQ,CAAC;QAAC,OAAO,CAAC,EAAE,OAAO,GAAG,MAAM,CAAA;KAAE,CAAC,CAAC;IACrG,UAAU,EAAE,GAAG,CAAC,MAAM,EAAE,OAAO,GAAG,MAAM,CAAC,CAAC;IAC1C,QAAQ,EAAE,GAAG,CAAC,MAAM,EAAE,KAAK,CAAC,CAAC,KAAK,EAAE,GAAG,EAAE,GAAG,EAAE,GAAG,KAAK,OAAO,CAAC,CAAC,CAAC;IAChE,QAAQ,EAAE,OAAO,EAAE,CAAC;IACpB,YAAY,EAAE,KAAK,CAAC;QAAE,OAAO,EAAE,GAAG,CAAC;QAAC,OAAO,CAAC,EAAE,GAAG,CAAA;KAAE,CAAC,CAAC;IACrD,gBAAgB,EAAE,GAAG,CAAC,MAAM,EAAE,CAAC,OAAO,EAAE,GAAG,EAAE,OAAO,EAAE,GAAG,EAAE,KAAK,EAAE,GAAG,KAAK,OAAO,CAAC,CAAC;IACnF,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,WAAW,EAAE,MAAM,EAAE,CAAC;IACtB,aAAa,CAAC,EAAE,MAAM,CAAC;IACvB,KAAK,CAAC,EAAE,OAAO,CAAC;IAChB,kBAAkB,CAAC,KAAK,EAAE,cAAc,EAAE,GAAG,EAAE,GAAG,GAAG,OAAO,CAAC,OAAO,EAAE,CAAC,CAAC;CACzE;AAED,wBAAgB,sBAAsB,IAAI,gBAAgB,CA8FzD"}
@@ -0,0 +1,96 @@
1
+ export function createMockExtensionAPI() {
2
+ const commands = new Map();
3
+ const tools = new Map();
4
+ const flags = new Map();
5
+ const flagValues = new Map();
6
+ const handlers = new Map();
7
+ const messages = [];
8
+ const sentMessages = [];
9
+ const messageRenderers = new Map();
10
+ const api = {
11
+ commands,
12
+ tools,
13
+ flags,
14
+ flagValues,
15
+ handlers,
16
+ messages,
17
+ sentMessages,
18
+ messageRenderers,
19
+ activeTools: [],
20
+ on(event, handler) {
21
+ const list = handlers.get(event) ?? [];
22
+ list.push(handler);
23
+ handlers.set(event, list);
24
+ },
25
+ registerTool(tool) {
26
+ tools.set(tool.name, tool);
27
+ },
28
+ registerCommand(name, options) {
29
+ commands.set(name, options);
30
+ },
31
+ registerShortcut() { },
32
+ registerFlag(name, options) {
33
+ flags.set(name, options);
34
+ if (options.default !== undefined && !flagValues.has(name)) {
35
+ flagValues.set(name, options.default);
36
+ }
37
+ },
38
+ getFlag(name) {
39
+ return flagValues.get(name);
40
+ },
41
+ registerMessageRenderer(customType, renderer) {
42
+ messageRenderers.set(customType, renderer);
43
+ },
44
+ sendMessage(message, options) {
45
+ messages.push(message);
46
+ sentMessages.push({ message, options });
47
+ },
48
+ sendUserMessage() { },
49
+ setSessionName(name) {
50
+ api.sessionName = name;
51
+ },
52
+ getSessionName() {
53
+ return api.sessionName;
54
+ },
55
+ setActiveTools(toolNames) {
56
+ api.activeTools = toolNames;
57
+ },
58
+ getActiveTools() {
59
+ return api.activeTools;
60
+ },
61
+ getAllTools() {
62
+ return [...tools.values()].map((tool) => ({
63
+ name: tool.name,
64
+ description: tool.description,
65
+ parameters: tool.parameters,
66
+ sourceInfo: { path: "<test>", source: "test", scope: "temporary", origin: "top-level" },
67
+ }));
68
+ },
69
+ setThinkingLevel(level) {
70
+ api.thinkingLevel = level;
71
+ },
72
+ getThinkingLevel() {
73
+ return api.thinkingLevel ?? "off";
74
+ },
75
+ async setModel(model) {
76
+ api.model = model;
77
+ return true;
78
+ },
79
+ async emitExtensionEvent(event, ctx) {
80
+ const results = [];
81
+ for (const handler of handlers.get(event.type) ?? []) {
82
+ results.push(await handler(event, ctx));
83
+ }
84
+ return results;
85
+ },
86
+ events: {
87
+ emit() { },
88
+ on() {
89
+ return () => { };
90
+ },
91
+ off() { },
92
+ },
93
+ };
94
+ return api;
95
+ }
96
+ //# sourceMappingURL=testing.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"testing.js","sourceRoot":"","sources":["../src/testing.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,196 @@
1
+ # Agent Composition
2
+
3
+ A recipe separates behavior into package-wide context and agent-specific
4
+ configuration. Use that separation to share one operating model across a team
5
+ of agents without making every agent identical.
6
+
7
+ ## The Three Layers
8
+
9
+ | Layer | Scope | Use it for |
10
+ | --- | --- | --- |
11
+ | `package.json#pi` | Entire recipe package | Declaring available agents, extensions, skills, prompts, MCP servers, and evals |
12
+ | `SYSTEM.md` | Every root and delegated agent in the recipe | Shared mission, terminology, policies, and workflow rules |
13
+ | `agents/*.yaml` | One selected agent | Model, tools, selected skills, visible subagents, extension/MCP selection, and role-specific instructions |
14
+
15
+ `SYSTEM.md` is the shared recipe instruction layer. A root agent and every
16
+ delegated subagent start from the same recipe-level content. Put instructions
17
+ there when they should remain true regardless of which agent is selected.
18
+
19
+ Each agent's `system_instructions` specializes that shared layer:
20
+
21
+ ```yaml
22
+ system_instructions:
23
+ mode: append
24
+ content: |
25
+ Review the evidence and return a release recommendation.
26
+ ```
27
+
28
+ - `append` adds the agent-specific content after the shared recipe prompt.
29
+ - `replace` intentionally replaces the current prompt, including `SYSTEM.md`.
30
+
31
+ When a recipe has no `SYSTEM.md`, Pi's normal base prompt is the starting
32
+ prompt. When `SYSTEM.md` exists, it becomes the recipe-wide starting prompt.
33
+ Recipes then applies the selected agent's `system_instructions` mode.
34
+
35
+ ## Derive Agents With `from:`
36
+
37
+ Use `from:` to derive a named agent from another agent in the same recipe. This
38
+ is useful for model variants, constrained roles, and subagents that share most
39
+ of a base configuration.
40
+
41
+ ```yaml
42
+ # agents/agent.yaml
43
+ name: agent
44
+ description: Main release coordinator
45
+ model:
46
+ name: anthropic/claude-sonnet-4-6
47
+ thinking_level: medium
48
+ tools: [read, bash]
49
+ skills: [release-policy]
50
+ subagents: [reviewer]
51
+ extensions:
52
+ include: [release-tools]
53
+ system_instructions:
54
+ mode: append
55
+ content: Coordinate the complete release decision.
56
+ ```
57
+
58
+ ```yaml
59
+ # agents/reviewer.yaml
60
+ name: reviewer
61
+ from: agent
62
+ model:
63
+ thinking_level: high
64
+ tools: [read]
65
+ subagents: []
66
+ system_instructions:
67
+ mode: append
68
+ content: Independently review the evidence. Do not make changes.
69
+ ```
70
+
71
+ The derived agent inherits the base model name and selected skill, overrides
72
+ the thinking level and tool allowlist, clears its visible subagents, and uses
73
+ its own specialized instructions. Both agents still receive `SYSTEM.md`.
74
+
75
+ `from:` chains may contain multiple levels. The referenced name must resolve to
76
+ another agent in the same recipe. Missing bases and cycles are validation
77
+ errors. A filename stem can resolve as an alias for an explicitly named agent,
78
+ but explicit stable `name` values are recommended and required for portable
79
+ child-agent definitions.
80
+
81
+ Inheritance and delegation are separate. `from: reviewer-base` inherits a
82
+ definition; it does not expose the derived agent for delegation. A root agent
83
+ must still name that agent in its `subagents` list.
84
+
85
+ ## Inheritance Rules
86
+
87
+ Omission means "inherit" for a derived agent. Declaring a field means
88
+ "override or merge" according to its type.
89
+
90
+ | Field | Derived-agent behavior |
91
+ | --- | --- |
92
+ | `description` | Child value replaces the base; omission inherits it |
93
+ | `model` | Merges by key; nested stream/provider sections also merge by key |
94
+ | `tools` | Child array replaces the inherited allowlist; `[]` clears it |
95
+ | `skills` | Child array replaces the inherited selection; `[]` clears it |
96
+ | `subagents` | Child array replaces inherited visibility; `[]` clears it |
97
+ | `extensions` | `include` and `exclude` inherit independently; a declared child list replaces that list |
98
+ | `mcp` | Servers merge by id; each server's `include` and `exclude` inherit independently and a declared child list replaces that list |
99
+ | `system_instructions` | The whole child block replaces the inherited block; omission inherits it |
100
+
101
+ Agent instruction blocks are not concatenated along a `from:` chain. If a
102
+ child declares `system_instructions`, its block replaces the base agent's block.
103
+ The child's `mode: append` applies to the recipe-wide `SYSTEM.md` (or Pi base
104
+ prompt), not to the base agent's instructions. Put truly shared instructions in
105
+ `SYSTEM.md` or a shared skill.
106
+
107
+ Arrays never merge item by item. This makes capability boundaries reviewable:
108
+ a derived agent that declares `tools: [read]` receives only `read`, not the
109
+ base agent's other tools.
110
+
111
+ ## Model Configuration
112
+
113
+ Beyond `name` and `thinking_level`, the `model` block accepts request and
114
+ transport tuning and provider routing. Set only what a case needs.
115
+
116
+ ```yaml
117
+ model:
118
+ name: anthropic/claude-sonnet-4-6
119
+ thinking_level: medium # or reasoning_effort (an alias; a conflicting value errors)
120
+ temperature: 0.2
121
+ max_tokens: 4096
122
+ cache_retention: short # none | short | long
123
+ timeout_ms: 60000
124
+ max_retries: 2
125
+ max_retry_delay_ms: 8000
126
+ providers:
127
+ anthropic:
128
+ betas: [context-1m]
129
+ context_management: {}
130
+ openrouter:
131
+ routing: # allow_fallbacks, require_parameters, data_collection,
132
+ order: [anthropic] # zdr, order, only, ignore, quantizations, sort, max_price,
133
+ sort: throughput # preferred_min_throughput, preferred_max_latency, …
134
+ ```
135
+
136
+ All keys are optional and merge by key along a `from:` chain. Use `reasoning_effort`
137
+ or `thinking_level`, not both with different values.
138
+
139
+ ## Instruction Shorthand
140
+
141
+ A top-level `prompt:` string on an agent is shorthand for append-mode
142
+ `system_instructions` — the text is appended to `SYSTEM.md` for that agent. Use
143
+ the explicit `system_instructions` block when you need `mode: replace`.
144
+
145
+ ## Resources and Capabilities
146
+
147
+ The manifest declares what the package can provide; the selected agent narrows
148
+ what is active:
149
+
150
+ - `package.json#pi.skills` declares physical skill resources. `agent.skills`
151
+ selects the skill names Pi discovers for that agent.
152
+ - `package.json#pi.extensions` declares recipe-owned extensions.
153
+ `agent.extensions` filters which declared extensions load.
154
+ - `package.json#pi.mcp` defines the package's upper-bound MCP policy.
155
+ `agent.mcp` narrows tool access per server.
156
+ - `agent.tools` is the exact allowlist for Pi built-ins and tools registered by
157
+ loaded recipe extensions.
158
+ - `agent.subagents` controls which other recipe agents are visible through the
159
+ `agent` tool.
160
+ - Prompt templates declared by the package are recipe resources; they are not
161
+ specialized through `from:`.
162
+
163
+ Skill and subagent selection controls prompt exposure and runtime capability,
164
+ not filesystem isolation. All agents run in the same recipe package and current
165
+ workspace. Use sandboxing and external authorization for security boundaries.
166
+
167
+ ## Root Agents and Subagents
168
+
169
+ An agent selected with `--agent` is a root agent. If its effective `subagents`
170
+ list is non-empty, Recipes enables the `agent` tool and exposes only those
171
+ named agents.
172
+
173
+ A delegated subagent resolves its own complete effective definition:
174
+
175
+ 1. follow its `from:` chain;
176
+ 2. apply its model, tools, skills, extensions, MCP, and instruction overrides;
177
+ 3. start from the same recipe `SYSTEM.md` as the root agent; and
178
+ 4. append or replace with its effective `system_instructions`.
179
+
180
+ Delegation is one level deep. A definition may expose subagents when selected
181
+ directly as a root agent, but the same definition does not receive the `agent`
182
+ tool while running as a delegated child.
183
+
184
+ ## Recommended Structure
185
+
186
+ - Put shared identity, policies, terminology, and workflow invariants in
187
+ `SYSTEM.md`.
188
+ - Put role-specific duties and response contracts in the relevant agent's
189
+ `system_instructions`.
190
+ - Put reusable detailed judgment in skills and select only the skills each
191
+ agent needs.
192
+ - Use `from:` for real variants, not merely to avoid a few repeated lines.
193
+ - Declare narrow tool, extension, MCP, and subagent lists at the point where a
194
+ role's capability boundary changes.
195
+ - Run `introspection check` after changing inheritance, then prove each important
196
+ root agent and delegated path in a fresh Pi session.
@@ -0,0 +1,65 @@
1
+ # Deployment configuration
2
+
3
+ How a recipe declares what its tasks need from the platform that runs them —
4
+ compute resources and scratch disk — and what an implementing platform does
5
+ with those declarations.
6
+
7
+ This spec is defined here, in Recipes, because it describes *Recipe
8
+ intent*: portable, platform-neutral declarations that any host can honor.
9
+ The validation grammar lives in `pi_recipe_check::resources`
10
+ (`validate_resources`) so every host — the Introspection CLI, a
11
+ platform's manifest validator, wasm/Python bindings — applies identical
12
+ rules with stable diagnostic codes. Platform-specific enforcement (floors,
13
+ caps, billing) is the implementer's job, not part of the grammar.
14
+
15
+ ## Where the declarations live
16
+
17
+ Recipe *package* contents (`package.json#pi`, `agents/*.yaml`) are
18
+ materialized inside a running sandbox, after the machine that runs them
19
+ already exists — so deployment configuration cannot live there. It lives in
20
+ the host's deployment manifest, the file the platform reads *before*
21
+ provisioning. On Introspection that is the repo-root
22
+ `.introspection/<slug>.yaml` manifest's `runtime:` block:
23
+
24
+ ```yaml
25
+ runtime:
26
+ resources:
27
+ requests: { cpu: 500m, memory: 1.5Gi, storage: 10Gi }
28
+ limits: { cpu: 1500m, memory: 1.5Gi }
29
+ ```
30
+
31
+ ## `resources`
32
+
33
+ Kubernetes-style `requests`/`limits` (`validate_resources`). Grammar:
34
+ `500m` millicores or decimal cores for CPU; bytes with binary
35
+ (`Ki`/`Mi`/`Gi`/`Ti`) or decimal (`k`/`M`/`G`/`T`) suffixes for memory and
36
+ storage (`0.1T` works). Quantities may also be JSON numbers — `cpu: 1.5`
37
+ (cores) or an integer byte count for memory. A request must not exceed its limit.
38
+
39
+ `storage` is the sandbox scratch-volume size and follows the PVC
40
+ convention (`spec.resources.requests.storage`): request-only — declaring
41
+ it under `limits` is rejected. Whether the scratch volume is persistent
42
+ (survives sandbox teardown for warm restore) or ephemeral stays a
43
+ *deployment* setting on the implementing platform — the recipe only sizes
44
+ it. Future io characteristics (e.g. a storage class) would be siblings in
45
+ the manifest, mirroring how Kubernetes expresses them outside the
46
+ quantity.
47
+
48
+ ## How Introspection implements this
49
+
50
+ The reference implementation treats every declaration as an **upward
51
+ request** merged onto deployment-configured floors:
52
+
53
+ - cpu/memory requests: `max(recipe, deployment floor)`, capped by a
54
+ schedulability guard; limits raise to the resolved request.
55
+ - `requests.storage`: taken as declared — rounded up to whole GiB
56
+ (smaller scratch bills less; 1Gi is the validated minimum) and capped
57
+ at 300 GiB; undeclared uses the deployment default (10 GiB). Applied to
58
+ the sandbox's scratch volume (a persistent PVC when the deployment
59
+ enables warm storage, ephemeral emptyDir at the same mount path
60
+ otherwise).
61
+
62
+ Invalid declarations fail manifest validation at push — a recipe never
63
+ silently spawns with defaults because of a typo. Other platforms may
64
+ choose different enforcement; the declarations and their grammar are the
65
+ portable part.
package/docs/index.md ADDED
@@ -0,0 +1,49 @@
1
+ # Recipes documentation
2
+
3
+ **Recipes is the open package format for complete, portable Pi agents.**
4
+
5
+ A Recipe keeps the agent-owned layer together as inspectable source. Pi runs
6
+ the agent; a compatible host supplies credentials, isolation, persistence,
7
+ task lifecycle, protocols, and deployment.
8
+
9
+ ## Start here
10
+
11
+ | Goal | Document |
12
+ | --- | --- |
13
+ | Understand the portable artifact contract | [Recipe Format](recipe-format.md) |
14
+ | Embed a Recipe in a host | [Runtime library](runtime-library.md) |
15
+ | Run a Recipe in Pi | [Pi extension](pi-extension.md) |
16
+ | Compose agents and subagents | [Agent composition](agent-composition.md) |
17
+ | Ask for user input across hosts | [Interactions](interactions.md) |
18
+ | Declare capability policy and bindings | [MCP configuration](mcp-configuration.md) |
19
+ | Declare portable resource intent | [Deployment configuration](deployment-configuration.md) |
20
+ | Package quality definitions | [Recipe judges](recipe-judges.md) |
21
+ | Declare offline evaluation suites | [Recipe evals](recipe-evals.md) |
22
+ | Move from the previous package | [Migration](migration.md) |
23
+
24
+ ## Boundary
25
+
26
+ ```text
27
+ Recipe source
28
+
29
+
30
+ resolveRecipe() format interpretation
31
+
32
+
33
+ createRecipeSession() complete live Pi agent
34
+
35
+ ├── runRecipe() one-turn convenience
36
+
37
+ └── host tasks, persistence, auth, protocols, deployment
38
+ ```
39
+
40
+ Recipes stops at the live session boundary. It does not ship a generic server,
41
+ task store, scheduler, sandbox, or provider-specific deployment adapter.
42
+
43
+ The first-party hosts are:
44
+
45
+ - the Pi terminal harness through the Recipes extension;
46
+ - Introspection's managed `runtime-agent`.
47
+
48
+ Other hosts implement the same session contract and can run the host
49
+ conformance suite.
@@ -0,0 +1,210 @@
1
+ # Recipe Interactions
2
+
3
+ `@introspection-ai/recipes/interactions` gives recipe tools one contract for
4
+ asking the user a question or requesting approval that works on every pi host:
5
+ the local TUI, RPC-driven UIs, headless runs, and hosts that stream tool
6
+ results to a remote frontend and can pause/resume a run.
7
+
8
+ The module registers no tools. Recipes own their interaction tools — their
9
+ names, schemas, and prompts — and call `askUserQuestion()` or
10
+ `askUserApproval()` from the tool's `execute()`. Those helpers build the
11
+ `details.interrupt` request, local Pi dialog copy, and host metadata. Use raw
12
+ `askUser()` only when a tool needs a lower-level interaction shape.
13
+
14
+ ## Quick start
15
+
16
+ ```ts
17
+ import { Type } from "typebox";
18
+ import type { ExtensionAPI } from "@earendil-works/pi-coding-agent";
19
+ import { askUserQuestion } from "@introspection-ai/recipes/interactions";
20
+
21
+ export default function (pi: ExtensionAPI) {
22
+ pi.registerTool({
23
+ name: "ask_user_question",
24
+ label: "Ask user",
25
+ description: "Ask the user a clarifying question and wait for the answer.",
26
+ parameters: Type.Object({
27
+ question: Type.String(),
28
+ options: Type.Optional(Type.Array(Type.String())),
29
+ }),
30
+ // Required: interaction tools must not run concurrently with other tools,
31
+ // otherwise a host pause can strand half-finished parallel tool calls.
32
+ executionMode: "sequential",
33
+ async execute(toolCallId, params, signal, _onUpdate, ctx) {
34
+ return await askUserQuestion(
35
+ {
36
+ question: params.question,
37
+ options: params.options,
38
+ },
39
+ { toolCallId, ctx, signal }
40
+ );
41
+ },
42
+ });
43
+ }
44
+ ```
45
+
46
+ The helpers always return a finished tool result (`content` + `details`), so
47
+ the tool can return them directly. Pass the tool's own `signal` parameter —
48
+ not `ctx.signal` — so an aborted turn dismisses any open dialog.
49
+
50
+ ## Channel resolution
51
+
52
+ The interaction helpers pick the best available channel, in order:
53
+
54
+ 1. **`PI_ASK_USER_AUTO_APPROVE`** (env) — headless/CI runs: confirmations
55
+ resolve `approved`, everything else resolves `declined`. Deterministic and
56
+ never blocks.
57
+ 2. **Interactive UI** (`ctx.hasUI`, TUI and RPC modes) — the built-in dialog
58
+ walk: a select for fixed options and approvals, a text input otherwise.
59
+ A caller-provided `interactive` walk replaces the dialogs (return
60
+ `undefined` to fall through). In RPC mode dialogs get a default timeout
61
+ (`DEFAULT_RPC_DIALOG_TIMEOUT_MS`, 120s) so a client that never renders
62
+ them cannot wedge the session; a timed-out or dismissed dialog declines.
63
+ 3. **Pause/resume host** (`PI_INTERRUPT_RESUME` env, set by the host) —
64
+ the tool returns `Awaiting user response.` with a Recipes
65
+ `details.interrupt` request whose outcome is `awaiting_user`. The host
66
+ pauses the run, adapts the request to its own UI protocol, and later resumes
67
+ the run by rewriting this tool result with the response envelope (below).
68
+ Root sessions only. In-process child agents resolve interactions internally
69
+ and never emit a pause request.
70
+ 4. **Fallback** — the result states that nothing was shown to the user and
71
+ directs the model to ask in its normal assistant reply. An unrendered
72
+ question is never treated as declined.
73
+
74
+ ## The interrupt request
75
+
76
+ Pi's native tool-result shape is `content` plus arbitrary structured
77
+ `details`. Recipes stores its interaction state at `details.interrupt`.
78
+ A host that supports pause/resume treats
79
+ `details.interrupt.outcome.type === "awaiting_user"` as a pause request.
80
+ Runtime adapters generate their own pause state from this record.
81
+
82
+ | Field | Meaning |
83
+ | --- | --- |
84
+ | `reason` | Open string; well-known: `input_required`, `confirmation`, `tool_call` |
85
+ | `message` | Concise human-readable prompt |
86
+ | `options` | Optional structured answer suggestions: `{ label, value?, description? }[]` |
87
+ | `metadata` | Renderer or tool hints (`kind`, `header`, source tool parameters, …) |
88
+ | `display` | Optional structured display copy for richer local or remote UI |
89
+ | `expiresAt` | Optional ISO-8601 instant after which the host may auto-decline |
90
+ | `outcome` | Local result, or `{ type: "awaiting_user" }` when the host must pause |
91
+
92
+ Question options are suggestions, not a closed enum. Local Pi shows them in a
93
+ selector plus an `Other` input path, and runtime adapters should preserve that
94
+ same custom-answer path unless a specific tool explicitly does something else.
95
+
96
+ Resume payloads are single-question: `{ answer }` for questions,
97
+ `{ approved, feedback? }` for confirmations. A decline is a resume with
98
+ status `cancelled` and **no payload**. Any host-specific pause/resume state
99
+ should be generated by the host adapter from this request, not authored inside
100
+ recipes.
101
+
102
+ ## AG-UI compatibility
103
+
104
+ `details.interrupt` is intentionally close to the shape needed by AG-UI-style
105
+ frontends, while remaining Pi-native recipe metadata. A host that deploys
106
+ recipes behind the Agent User Interaction Protocol can map an awaiting
107
+ `details.interrupt` request into `RUN_FINISHED` with
108
+ `outcome: { type: "interrupt", interrupts: [...] }`, then resume with the
109
+ same `{ answer }`, `{ approved, feedback? }`, or cancelled payloads described
110
+ above.
111
+
112
+ Recipes should still emit only `details.interrupt`. The host adapter owns ids,
113
+ tool-call binding, response schemas, transport events, persistence, and any
114
+ frontend-specific rendering.
115
+
116
+ ## Display data
117
+
118
+ `message` is the concise prompt every host can show without understanding
119
+ recipe-specific metadata. Keep it meaningful, for example
120
+ `Approve search proposal: Senior product leaders in Sydney?`.
121
+
122
+ When a tool needs richer approval UI copy, pass card fields to
123
+ `askUserApproval()`:
124
+
125
+ ```ts
126
+ await askUserApproval(
127
+ {
128
+ kind: "plan_search",
129
+ message: "Approve search proposal: Senior product leaders in Sydney?",
130
+ title: "Senior product leaders in Sydney",
131
+ body: "Target senior product leaders in Sydney with B2B SaaS or marketplace experience.",
132
+ sections: [
133
+ {
134
+ title: "Starting angles",
135
+ items: [
136
+ "Product leadership titles in Sydney",
137
+ "Growth product leaders in Sydney",
138
+ "Marketplace product operators",
139
+ ],
140
+ },
141
+ ],
142
+ metadata: {
143
+ proposal: "Target senior product leaders in Sydney with B2B SaaS or marketplace experience.",
144
+ },
145
+ },
146
+ { toolCallId, ctx, signal }
147
+ );
148
+ ```
149
+
150
+ Local pi dialogs format the generated display into readable prompt text.
151
+ Remote hosts can adapt the same object into their own UI. Hosts that do not
152
+ understand the structured display can still render `message` and basic
153
+ options.
154
+
155
+ ## Response envelopes (frozen)
156
+
157
+ The envelope is the tool-result text the model sees after the user responds.
158
+ It is a byte-exact wire contract: the local dialog walk and every pause/resume
159
+ host must synthesize identical text for the same outcome,
160
+ so recipes cannot tell where the answer came from. Do not reword these
161
+ without a coordinated protocol change across all hosts.
162
+
163
+ | Outcome | Envelope |
164
+ | --- | --- |
165
+ | Answered | `Answer: <answer>` |
166
+ | Approved | `Approved.` |
167
+ | Approved with feedback | `Approved. Feedback: <feedback>` |
168
+ | Revision requested | `Revision requested.` |
169
+ | Revision requested with feedback | `Revision requested. Feedback: <feedback>` |
170
+ | Declined | `User declined to answer. Proceed with your best judgment.` |
171
+ | Pending host resume | `Awaiting user response.` |
172
+
173
+ Declines are **not** tool errors — the model is expected to proceed with its
174
+ best judgment.
175
+
176
+ ## Rules for interaction tools
177
+
178
+ - **`executionMode: "sequential"` is mandatory.** A host pause must never
179
+ race concurrently executing tools.
180
+ - **Prefer the wrappers.** Use `askUserQuestion()` and `askUserApproval()` so
181
+ recipes do not hand-author interrupt details, reasons, or display metadata.
182
+ - **Never format envelopes yourself.** Return the helper result as-is; envelope
183
+ authorship must not split across layers.
184
+ - **Thread the tool's `signal`** into the helper and check for aborts after any
185
+ custom dialog (`undefined` from a dialog means dismissal *or* abort — only
186
+ the signal distinguishes them).
187
+ - **Custom UIs are enhancements.** A richer TUI walk goes through the
188
+ `interactive` option; remote hosts can adapt `metadata` and `display`.
189
+ Hosts that recognize neither must still work off `reason`, `message`, and
190
+ `options`.
191
+ - **Child agents cannot ask the user directly.** Inside an in-process child
192
+ agent run, approvals resolve as approved and questions resolve as declined.
193
+ Child tools never open UI or interrupt the root session.
194
+
195
+ ## Host checklist (implementing `PI_INTERRUPT_RESUME`)
196
+
197
+ 1. Wrap every in-process child session prompt with
198
+ `autoResolveInteractions()`. The guard is shared across separately resolved
199
+ copies of Recipes, so Recipe-owned interaction tools observe the child
200
+ boundary too.
201
+ 2. Watch root-session `tool_execution_end` events for
202
+ `details.interrupt.outcome.type === "awaiting_user"`.
203
+ 3. Convert the Recipes interrupt request into the host UI protocol, pause the run, and
204
+ persist the host descriptor(s); the pause frame itself is not replayable,
205
+ so persisted descriptors are the source of truth.
206
+ 4. On resume, rewrite the paused tool result's text with the frozen envelope
207
+ for the user's response and continue the run. Declines (`cancelled`,
208
+ no payload) use the declined envelope and are not errors.
209
+ 5. Set `PI_INTERRUPT_RESUME=1` in the session environment only when all of
210
+ the above is wired.