@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.
- package/LICENSE +191 -0
- package/README.md +184 -0
- package/dist/agent-tool.d.ts +42 -0
- package/dist/agent-tool.d.ts.map +1 -0
- package/dist/agent-tool.js +159 -0
- package/dist/agent-tool.js.map +1 -0
- package/dist/child-agent-completions.d.ts +61 -0
- package/dist/child-agent-completions.d.ts.map +1 -0
- package/dist/child-agent-completions.js +135 -0
- package/dist/child-agent-completions.js.map +1 -0
- package/dist/child-agent-store.d.ts +48 -0
- package/dist/child-agent-store.d.ts.map +1 -0
- package/dist/child-agent-store.js +98 -0
- package/dist/child-agent-store.js.map +1 -0
- package/dist/child-agent.d.ts +43 -0
- package/dist/child-agent.d.ts.map +1 -0
- package/dist/child-agent.js +268 -0
- package/dist/child-agent.js.map +1 -0
- package/dist/direct-cli.d.ts +9 -0
- package/dist/direct-cli.d.ts.map +1 -0
- package/dist/direct-cli.js +22 -0
- package/dist/direct-cli.js.map +1 -0
- package/dist/index.d.ts +14 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +14 -0
- package/dist/index.js.map +1 -0
- package/dist/inspect.d.ts +26 -0
- package/dist/inspect.d.ts.map +1 -0
- package/dist/inspect.js +70 -0
- package/dist/inspect.js.map +1 -0
- package/dist/interactions.d.ts +204 -0
- package/dist/interactions.d.ts.map +1 -0
- package/dist/interactions.js +358 -0
- package/dist/interactions.js.map +1 -0
- package/dist/mcp-catalog.d.ts +8 -0
- package/dist/mcp-catalog.d.ts.map +1 -0
- package/dist/mcp-catalog.js +60 -0
- package/dist/mcp-catalog.js.map +1 -0
- package/dist/mcp-cli-core.d.ts +79 -0
- package/dist/mcp-cli-core.d.ts.map +1 -0
- package/dist/mcp-cli-core.js +1717 -0
- package/dist/mcp-cli-core.js.map +1 -0
- package/dist/mcp-cli-help.d.ts +2 -0
- package/dist/mcp-cli-help.d.ts.map +1 -0
- package/dist/mcp-cli-help.js +36 -0
- package/dist/mcp-cli-help.js.map +1 -0
- package/dist/mcp-cli-policy.d.ts +17 -0
- package/dist/mcp-cli-policy.d.ts.map +1 -0
- package/dist/mcp-cli-policy.js +230 -0
- package/dist/mcp-cli-policy.js.map +1 -0
- package/dist/mcp-cli.d.ts +3 -0
- package/dist/mcp-cli.d.ts.map +1 -0
- package/dist/mcp-cli.js +33 -0
- package/dist/mcp-cli.js.map +1 -0
- package/dist/mcp-client.d.ts +3 -0
- package/dist/mcp-client.d.ts.map +1 -0
- package/dist/mcp-client.js +86 -0
- package/dist/mcp-client.js.map +1 -0
- package/dist/mcp-command-context.d.ts +13 -0
- package/dist/mcp-command-context.d.ts.map +1 -0
- package/dist/mcp-command-context.js +29 -0
- package/dist/mcp-command-context.js.map +1 -0
- package/dist/mcp-contract.d.ts +16 -0
- package/dist/mcp-contract.d.ts.map +1 -0
- package/dist/mcp-contract.js +306 -0
- package/dist/mcp-contract.js.map +1 -0
- package/dist/mcp-daemon-client.d.ts +10 -0
- package/dist/mcp-daemon-client.d.ts.map +1 -0
- package/dist/mcp-daemon-client.js +119 -0
- package/dist/mcp-daemon-client.js.map +1 -0
- package/dist/mcp-daemon-protocol.d.ts +64 -0
- package/dist/mcp-daemon-protocol.d.ts.map +1 -0
- package/dist/mcp-daemon-protocol.js +6 -0
- package/dist/mcp-daemon-protocol.js.map +1 -0
- package/dist/mcp-daemon.d.ts +3 -0
- package/dist/mcp-daemon.d.ts.map +1 -0
- package/dist/mcp-daemon.js +76880 -0
- package/dist/mcp-daemon.js.map +1 -0
- package/dist/mcp-run-worker.d.ts +2 -0
- package/dist/mcp-run-worker.d.ts.map +1 -0
- package/dist/mcp-run-worker.js +76579 -0
- package/dist/mcp-run-worker.js.map +1 -0
- package/dist/mcp.d.ts +168 -0
- package/dist/mcp.d.ts.map +1 -0
- package/dist/mcp.js +558 -0
- package/dist/mcp.js.map +1 -0
- package/dist/pi-extension.d.ts +30 -0
- package/dist/pi-extension.d.ts.map +1 -0
- package/dist/pi-extension.js +880 -0
- package/dist/pi-extension.js.map +1 -0
- package/dist/provider-env.d.ts +2 -0
- package/dist/provider-env.d.ts.map +1 -0
- package/dist/provider-env.js +21 -0
- package/dist/provider-env.js.map +1 -0
- package/dist/recipe/resolve.d.ts +30 -0
- package/dist/recipe/resolve.d.ts.map +1 -0
- package/dist/recipe/resolve.js +131 -0
- package/dist/recipe/resolve.js.map +1 -0
- package/dist/recipe-agent.d.ts +71 -0
- package/dist/recipe-agent.d.ts.map +1 -0
- package/dist/recipe-agent.js +555 -0
- package/dist/recipe-agent.js.map +1 -0
- package/dist/recipe-extensions.d.ts +9 -0
- package/dist/recipe-extensions.d.ts.map +1 -0
- package/dist/recipe-extensions.js +81 -0
- package/dist/recipe-extensions.js.map +1 -0
- package/dist/recipe-mcp-config.d.ts +15 -0
- package/dist/recipe-mcp-config.d.ts.map +1 -0
- package/dist/recipe-mcp-config.js +82 -0
- package/dist/recipe-mcp-config.js.map +1 -0
- package/dist/recipe-model.d.ts +49 -0
- package/dist/recipe-model.d.ts.map +1 -0
- package/dist/recipe-model.js +299 -0
- package/dist/recipe-model.js.map +1 -0
- package/dist/recipe-package.d.ts +79 -0
- package/dist/recipe-package.d.ts.map +1 -0
- package/dist/recipe-package.js +479 -0
- package/dist/recipe-package.js.map +1 -0
- package/dist/recipe-skills.d.ts +7 -0
- package/dist/recipe-skills.d.ts.map +1 -0
- package/dist/recipe-skills.js +46 -0
- package/dist/recipe-skills.js.map +1 -0
- package/dist/run-controller.d.ts +32 -0
- package/dist/run-controller.d.ts.map +1 -0
- package/dist/run-controller.js +259 -0
- package/dist/run-controller.js.map +1 -0
- package/dist/run.d.ts +28 -0
- package/dist/run.d.ts.map +1 -0
- package/dist/run.js +84 -0
- package/dist/run.js.map +1 -0
- package/dist/session.d.ts +140 -0
- package/dist/session.d.ts.map +1 -0
- package/dist/session.js +363 -0
- package/dist/session.js.map +1 -0
- package/dist/test-utils.d.ts +32 -0
- package/dist/test-utils.d.ts.map +1 -0
- package/dist/test-utils.js +259 -0
- package/dist/test-utils.js.map +1 -0
- package/dist/testing.d.ts +25 -0
- package/dist/testing.d.ts.map +1 -0
- package/dist/testing.js +96 -0
- package/dist/testing.js.map +1 -0
- package/docs/agent-composition.md +196 -0
- package/docs/deployment-configuration.md +65 -0
- package/docs/index.md +49 -0
- package/docs/interactions.md +210 -0
- package/docs/mcp-auth.md +80 -0
- package/docs/mcp-configuration.md +126 -0
- package/docs/migration.md +70 -0
- package/docs/pi-extension.md +97 -0
- package/docs/python-bindings-release.md +47 -0
- package/docs/recipe-evals.md +70 -0
- package/docs/recipe-flow.md +41 -0
- package/docs/recipe-format.md +186 -0
- package/docs/recipe-judges.md +152 -0
- package/docs/runtime-library.md +171 -0
- package/package.json +106 -0
- package/vendor/mcp-client/darwin-arm64/mcp-client +0 -0
- package/vendor/mcp-client/darwin-x64/mcp-client +0 -0
- package/vendor/mcp-client/linux-arm64/mcp-client +0 -0
- package/vendor/mcp-client/linux-x64/mcp-client +0 -0
|
@@ -0,0 +1,186 @@
|
|
|
1
|
+
# Recipe Format
|
|
2
|
+
|
|
3
|
+
**Status:** Open format, version 1
|
|
4
|
+
**Reference implementation:** `@introspection-ai/recipes`
|
|
5
|
+
**Validator:** `pi-recipe-check`
|
|
6
|
+
|
|
7
|
+
The Recipe Format is a Git-native package contract for complete Pi agents. It
|
|
8
|
+
defines the agent-owned inputs that a compatible host must interpret the same
|
|
9
|
+
way. It does not define deployment infrastructure or a network protocol.
|
|
10
|
+
|
|
11
|
+
The key words **MUST**, **MUST NOT**, **SHOULD**, and **MAY** are normative.
|
|
12
|
+
|
|
13
|
+
## Compatibility scope
|
|
14
|
+
|
|
15
|
+
A conforming Recipe is **Pi-native and host-portable**:
|
|
16
|
+
|
|
17
|
+
- it MUST produce the same resolved agent configuration in compatible Pi hosts;
|
|
18
|
+
- it MUST NOT depend on an Introspection-managed runtime;
|
|
19
|
+
- it MAY declare host requirements that a particular host cannot satisfy;
|
|
20
|
+
- a host MUST fail closed when a required capability cannot be bound.
|
|
21
|
+
|
|
22
|
+
This format does not claim interoperability with non-Pi agent harnesses.
|
|
23
|
+
|
|
24
|
+
## Package root
|
|
25
|
+
|
|
26
|
+
A Recipe MUST be a directory containing `package.json`. The manifest MUST have:
|
|
27
|
+
|
|
28
|
+
```json
|
|
29
|
+
{
|
|
30
|
+
"name": "acme-research",
|
|
31
|
+
"version": "1.0.0",
|
|
32
|
+
"description": "Research an account and produce a sourced brief.",
|
|
33
|
+
"pi": {
|
|
34
|
+
"agents": ["agents/*.yaml"],
|
|
35
|
+
"skills": ["skills/**/SKILL.md"],
|
|
36
|
+
"extensions": ["extensions/*.ts"],
|
|
37
|
+
"prompts": ["prompts/*.md"]
|
|
38
|
+
}
|
|
39
|
+
}
|
|
40
|
+
```
|
|
41
|
+
|
|
42
|
+
`name` is the package identity. `version` is distribution metadata and defaults
|
|
43
|
+
to `0.0.0` when omitted for compatibility. `description` is human-facing.
|
|
44
|
+
|
|
45
|
+
Resource paths:
|
|
46
|
+
|
|
47
|
+
- MUST be relative to the package root;
|
|
48
|
+
- MUST NOT traverse outside the package;
|
|
49
|
+
- MAY be files, directories, or supported glob patterns;
|
|
50
|
+
- are resolved deterministically in lexical order.
|
|
51
|
+
|
|
52
|
+
Unknown top-level `package.json` fields retain normal npm semantics. Unknown
|
|
53
|
+
Recipe fields inside supported `pi` structures are validation errors unless a
|
|
54
|
+
later format version explicitly defines them.
|
|
55
|
+
|
|
56
|
+
## Agents
|
|
57
|
+
|
|
58
|
+
`pi.agents` declares YAML agent definitions. A resolved Recipe MUST contain at
|
|
59
|
+
least one agent.
|
|
60
|
+
|
|
61
|
+
```yaml
|
|
62
|
+
name: agent
|
|
63
|
+
description: Produce a sourced research brief.
|
|
64
|
+
model:
|
|
65
|
+
name: openrouter/anthropic/claude-sonnet-4.5
|
|
66
|
+
thinking_level: high
|
|
67
|
+
tools: [read, bash]
|
|
68
|
+
skills: [research]
|
|
69
|
+
subagents: [reviewer]
|
|
70
|
+
extensions:
|
|
71
|
+
include: [citations]
|
|
72
|
+
system_instructions:
|
|
73
|
+
mode: append
|
|
74
|
+
content: Verify every material claim.
|
|
75
|
+
```
|
|
76
|
+
|
|
77
|
+
An agent MAY inherit from another named agent with `from`. Inheritance MUST be
|
|
78
|
+
acyclic. Child fields override inherited scalar fields; documented collection
|
|
79
|
+
fields use the merge or replacement behavior in
|
|
80
|
+
[Agent composition](agent-composition.md).
|
|
81
|
+
|
|
82
|
+
Every fully resolved agent MUST define:
|
|
83
|
+
|
|
84
|
+
- `model.name` as `<provider>/<model_id>`;
|
|
85
|
+
- `model.thinking_level`;
|
|
86
|
+
- `tools`;
|
|
87
|
+
- `system_instructions`.
|
|
88
|
+
|
|
89
|
+
Omitted `skills` and `subagents` resolve to empty lists.
|
|
90
|
+
|
|
91
|
+
The default agent is named `agent`. If no `agent` exists, a host MAY select the
|
|
92
|
+
only declared agent. When multiple agents exist without `agent`, the caller
|
|
93
|
+
MUST select one explicitly.
|
|
94
|
+
|
|
95
|
+
## Instructions, skills, prompts, and extensions
|
|
96
|
+
|
|
97
|
+
`SYSTEM.md`, when present, is package-wide instruction source. Agent
|
|
98
|
+
`system_instructions.mode` determines whether agent instructions append to or
|
|
99
|
+
replace the current prompt.
|
|
100
|
+
|
|
101
|
+
Skills follow the [Agent Skills](https://agentskills.io) directory convention
|
|
102
|
+
and are selected from the resources declared by `pi.skills`.
|
|
103
|
+
|
|
104
|
+
Prompt templates are declared by `pi.prompts`.
|
|
105
|
+
|
|
106
|
+
Recipe-owned Pi extensions are declared by `pi.extensions`. An agent MAY select
|
|
107
|
+
declared extensions with `extensions.include` and `extensions.exclude`. A host
|
|
108
|
+
MUST NOT load undeclared Recipe extension source.
|
|
109
|
+
|
|
110
|
+
## Tools, subagents, and capabilities
|
|
111
|
+
|
|
112
|
+
`tools` is an allowlist. A host MUST expose no undeclared Pi or extension tool
|
|
113
|
+
through this field.
|
|
114
|
+
|
|
115
|
+
`subagents` names agents the selected agent may invoke. A host MUST expose only
|
|
116
|
+
those resolved definitions through the shared `agent` tool. How child work is
|
|
117
|
+
scheduled or isolated belongs to the host.
|
|
118
|
+
|
|
119
|
+
The `pi.mcp` package block declares capability servers and package-level tool
|
|
120
|
+
policy. Agent `mcp` blocks narrow those declarations. Credentials and concrete
|
|
121
|
+
endpoint bindings MUST NOT be required in distributable Recipe source. A host
|
|
122
|
+
MUST reject an unbound required server before the session begins.
|
|
123
|
+
|
|
124
|
+
See [MCP configuration](mcp-configuration.md) for the complete authored and
|
|
125
|
+
binding grammar.
|
|
126
|
+
|
|
127
|
+
## Quality and resource intent
|
|
128
|
+
|
|
129
|
+
Recipe-owned judge YAML expresses portable quality definitions. Hosts MAY use
|
|
130
|
+
those definitions online or offline, but MUST preserve their authored identity
|
|
131
|
+
and semantics.
|
|
132
|
+
|
|
133
|
+
`pi.evals` MAY pin external evaluation suites. The format records the pin; an
|
|
134
|
+
evaluation runner remains an external tool.
|
|
135
|
+
|
|
136
|
+
Portable resource intent is declared under the documented runtime resource
|
|
137
|
+
grammar. A host decides whether it can satisfy that intent and MUST report
|
|
138
|
+
unsupported required resources rather than silently weakening them.
|
|
139
|
+
|
|
140
|
+
## Host responsibilities
|
|
141
|
+
|
|
142
|
+
The Recipe Format owns:
|
|
143
|
+
|
|
144
|
+
- package and agent interpretation;
|
|
145
|
+
- instruction composition;
|
|
146
|
+
- model and tool selection;
|
|
147
|
+
- skill, prompt, and extension selection;
|
|
148
|
+
- subagent visibility;
|
|
149
|
+
- capability policy;
|
|
150
|
+
- quality definitions and resource intent.
|
|
151
|
+
|
|
152
|
+
The host owns:
|
|
153
|
+
|
|
154
|
+
- credentials and secret resolution;
|
|
155
|
+
- workspaces and filesystem isolation;
|
|
156
|
+
- task and process lifecycle;
|
|
157
|
+
- persistence and recovery;
|
|
158
|
+
- scheduling and concurrency enforcement;
|
|
159
|
+
- network protocols and user authentication;
|
|
160
|
+
- telemetry export policy;
|
|
161
|
+
- deployment.
|
|
162
|
+
|
|
163
|
+
Those host concerns MUST NOT become mandatory Recipe source fields.
|
|
164
|
+
|
|
165
|
+
## Conformance
|
|
166
|
+
|
|
167
|
+
There are two conformance layers:
|
|
168
|
+
|
|
169
|
+
1. `pi-recipe-check` validates authored package snapshots without executing
|
|
170
|
+
them.
|
|
171
|
+
2. `@introspection-ai/recipes/test-utils` verifies that a host constructs and
|
|
172
|
+
disposes Recipe sessions with the required semantics.
|
|
173
|
+
|
|
174
|
+
A host SHOULD run both layers in CI.
|
|
175
|
+
|
|
176
|
+
## Evolution
|
|
177
|
+
|
|
178
|
+
The format follows additive evolution while version 1 is active:
|
|
179
|
+
|
|
180
|
+
- new optional fields MAY be added;
|
|
181
|
+
- existing field meaning MUST NOT change incompatibly;
|
|
182
|
+
- required fields MUST NOT be added without a new major format version;
|
|
183
|
+
- hosts MUST ignore only extension points explicitly documented as open.
|
|
184
|
+
|
|
185
|
+
The implementation package follows SemVer independently. Package version and
|
|
186
|
+
format version are not the same thing.
|
|
@@ -0,0 +1,152 @@
|
|
|
1
|
+
# Recipe judge definitions
|
|
2
|
+
|
|
3
|
+
Recipe judges are optional, recipe-owned LLM grading definitions. Author them
|
|
4
|
+
as direct children of `judges/` using a lowercase `.yaml` or `.yml` extension:
|
|
5
|
+
|
|
6
|
+
```text
|
|
7
|
+
my-recipe/
|
|
8
|
+
judges/
|
|
9
|
+
helpful.yaml
|
|
10
|
+
```
|
|
11
|
+
|
|
12
|
+
Nested files such as `judges/calibration/helpful.yaml` are not judge sources.
|
|
13
|
+
The standalone `recipe-check` binary, `introspection check`, and in-memory
|
|
14
|
+
bindings discover the same direct-child set and return the same validation
|
|
15
|
+
result. Recipes without judge sources have no judge diagnostics or
|
|
16
|
+
`resources.judges` count.
|
|
17
|
+
|
|
18
|
+
## Ownership boundary
|
|
19
|
+
|
|
20
|
+
`pi-recipe-check` owns the portable authored YAML specification and its static,
|
|
21
|
+
file-oriented diagnostics. The I/O-free `check_recipe_files` core is the common
|
|
22
|
+
validation path used by the filesystem checker, npm CLI, serialized snapshot
|
|
23
|
+
API, and Python binding.
|
|
24
|
+
|
|
25
|
+
The Introspection judge engine owns runtime evaluation: applicability
|
|
26
|
+
execution, conversation assembly and transcript protection, model request
|
|
27
|
+
construction, retries, verdict normalization, and evaluation identity. Runtime
|
|
28
|
+
implementations should consume or remain explicitly compatible with the
|
|
29
|
+
authored specification defined here; new authored fields must land in this
|
|
30
|
+
checker and its contract tests rather than being introduced only in a runtime
|
|
31
|
+
parser.
|
|
32
|
+
|
|
33
|
+
The Rust checker and Python binding return a `Report` containing diagnostics
|
|
34
|
+
and, when judges exist, a `resources.judges` source count. The report does not
|
|
35
|
+
contain a normalized judge definition, `judge_id`, `definition_hash`, or
|
|
36
|
+
registry projection. Migrating project-scoped registry projection away from
|
|
37
|
+
the runtime parser is a separate platform change and must not add project or
|
|
38
|
+
tenant context to this portable API.
|
|
39
|
+
|
|
40
|
+
## Definition shape
|
|
41
|
+
|
|
42
|
+
The minimal definition is:
|
|
43
|
+
|
|
44
|
+
```yaml
|
|
45
|
+
judge: helpful
|
|
46
|
+
|
|
47
|
+
instructions: |
|
|
48
|
+
Determine whether the assistant answered the user correctly.
|
|
49
|
+
|
|
50
|
+
llm:
|
|
51
|
+
model: gpt-5
|
|
52
|
+
```
|
|
53
|
+
|
|
54
|
+
`judge`, `instructions`, and `llm.model` are required and non-empty. Judge names
|
|
55
|
+
must be unique across all judge files in one recipe. `llm.provider` defaults to
|
|
56
|
+
`openai` at runtime.
|
|
57
|
+
|
|
58
|
+
The canonical expanded definition is:
|
|
59
|
+
|
|
60
|
+
```yaml
|
|
61
|
+
judge: helpful
|
|
62
|
+
description: Did the assistant answer correctly?
|
|
63
|
+
|
|
64
|
+
on:
|
|
65
|
+
- event: message
|
|
66
|
+
match:
|
|
67
|
+
role: assistant
|
|
68
|
+
|
|
69
|
+
instructions: |
|
|
70
|
+
Determine whether the assistant answered the user correctly.
|
|
71
|
+
|
|
72
|
+
llm:
|
|
73
|
+
provider: openai
|
|
74
|
+
model: gpt-5
|
|
75
|
+
request:
|
|
76
|
+
temperature: 0
|
|
77
|
+
max_tokens: 1024
|
|
78
|
+
reasoning_effort: medium
|
|
79
|
+
transport:
|
|
80
|
+
timeout_ms: 60000
|
|
81
|
+
max_retries: 2
|
|
82
|
+
max_retry_delay_ms: 5000
|
|
83
|
+
local:
|
|
84
|
+
base_url: https://api.openai.com/v1
|
|
85
|
+
api_key_env: OPENAI_API_KEY
|
|
86
|
+
```
|
|
87
|
+
|
|
88
|
+
Unknown fields are errors at every level. The obsolete top-level `model:`
|
|
89
|
+
block is rejected.
|
|
90
|
+
|
|
91
|
+
### LLM settings
|
|
92
|
+
|
|
93
|
+
- `provider` is a 1-64 byte lowercase slug containing ASCII letters, digits,
|
|
94
|
+
and hyphens. The portable checker does not restrict it to managed platform
|
|
95
|
+
providers because custom slugs can be used with an explicit local endpoint.
|
|
96
|
+
- `model` is a trimmed, non-empty string of at most 255 bytes.
|
|
97
|
+
- `request.temperature` is a finite number from 0 through 2 and defaults to 0.
|
|
98
|
+
- `request.max_tokens` is an integer from 1 through 131072 when present;
|
|
99
|
+
explicit `null` is treated as omitted.
|
|
100
|
+
- `request.reasoning_effort` is a 1-64 byte lowercase slug containing ASCII
|
|
101
|
+
letters and hyphens; explicit `null` is treated as omitted.
|
|
102
|
+
- `transport.timeout_ms` is an integer from 1 through 600000 and defaults to
|
|
103
|
+
60000.
|
|
104
|
+
- `transport.max_retries` is an integer from 0 through 10 and defaults to 0.
|
|
105
|
+
- `transport.max_retry_delay_ms` is an integer from 0 through 60000 and
|
|
106
|
+
defaults to 5000.
|
|
107
|
+
- `local` requires both `base_url` and `api_key_env`. The URL must be HTTP(S),
|
|
108
|
+
have a host, contain no embedded credentials, query, or fragment, and use
|
|
109
|
+
HTTPS unless it targets `localhost`, `127.0.0.1`, or `::1`. `api_key_env` is
|
|
110
|
+
an environment-variable name, not a credential value.
|
|
111
|
+
|
|
112
|
+
Transport and local settings affect execution but not authored grading
|
|
113
|
+
identity. The platform judge engine remains responsible for applying defaults,
|
|
114
|
+
building requests, and enforcing runtime routing.
|
|
115
|
+
|
|
116
|
+
## Applicability
|
|
117
|
+
|
|
118
|
+
`on` is optional. Omission, an empty mapping, or an empty list makes the judge
|
|
119
|
+
applicable to every conversation selected for judging. Otherwise it is an
|
|
120
|
+
OR-list of matchers. Supported events are `message`, `tool`, and `feedback`;
|
|
121
|
+
fields within one `match` mapping are ANDed by the runtime engine.
|
|
122
|
+
|
|
123
|
+
```yaml
|
|
124
|
+
on:
|
|
125
|
+
- event: message
|
|
126
|
+
match:
|
|
127
|
+
role: user
|
|
128
|
+
text: /refund|invoice/i
|
|
129
|
+
- event: tool
|
|
130
|
+
match:
|
|
131
|
+
name: shell
|
|
132
|
+
args.command: /pytest/i
|
|
133
|
+
- event: feedback
|
|
134
|
+
match:
|
|
135
|
+
sentiment: negative
|
|
136
|
+
```
|
|
137
|
+
|
|
138
|
+
Match keys are non-empty field paths. Regex literals use Rust regex syntax and
|
|
139
|
+
support unique `i`, `m`, `s`, and `u` flags. `environment`, `runtime_group`, and
|
|
140
|
+
paths ending in `pattern_id` are platform-owned and cannot appear as authored
|
|
141
|
+
match fields. The runtime engine owns dotted-path traversal and actual gate
|
|
142
|
+
evaluation.
|
|
143
|
+
|
|
144
|
+
## Diagnostics
|
|
145
|
+
|
|
146
|
+
Invalid recipe content is reported through the normal `Report`/`Diagnostic`
|
|
147
|
+
model. Judge diagnostics use stable `judge.*` codes, recipe-relative source
|
|
148
|
+
paths, useful help text, and deterministic ordering. YAML syntax failures use
|
|
149
|
+
`judge.yaml_malformed` and include a 1-based source span when the parser
|
|
150
|
+
provides one. Invalid definitions do not raise a separate content exception in
|
|
151
|
+
the Python binding; they return `Report(valid=False, ...)` like other recipe
|
|
152
|
+
errors.
|
|
@@ -0,0 +1,171 @@
|
|
|
1
|
+
# Runtime library
|
|
2
|
+
|
|
3
|
+
The Recipes runtime library turns Recipe source into a live Pi agent. It is a
|
|
4
|
+
library boundary, not a hosting framework.
|
|
5
|
+
|
|
6
|
+
## The embedding ladder
|
|
7
|
+
|
|
8
|
+
```text
|
|
9
|
+
resolveRecipe() read and resolve the portable package
|
|
10
|
+
│
|
|
11
|
+
▼
|
|
12
|
+
createRecipeSession() construct the complete live Pi session
|
|
13
|
+
│
|
|
14
|
+
└── runRecipe() execute one turn and dispose
|
|
15
|
+
```
|
|
16
|
+
|
|
17
|
+
Hosts should use the lowest layer that preserves their control.
|
|
18
|
+
|
|
19
|
+
## `resolveRecipe`
|
|
20
|
+
|
|
21
|
+
```ts
|
|
22
|
+
import { resolveRecipe } from "@introspection-ai/recipes/recipe";
|
|
23
|
+
|
|
24
|
+
const recipe = resolveRecipe({
|
|
25
|
+
recipeDir,
|
|
26
|
+
agentName,
|
|
27
|
+
});
|
|
28
|
+
```
|
|
29
|
+
|
|
30
|
+
The result contains the selected agent, visible subagents, model settings,
|
|
31
|
+
tools, MCP policy, skills, prompts, extensions, and system-prompt composition.
|
|
32
|
+
It does not create a model client or start a session.
|
|
33
|
+
|
|
34
|
+
## `createRecipeSession`
|
|
35
|
+
|
|
36
|
+
```ts
|
|
37
|
+
import { createRecipeSession } from "@introspection-ai/recipes/session";
|
|
38
|
+
|
|
39
|
+
const handle = await createRecipeSession({
|
|
40
|
+
recipeDir,
|
|
41
|
+
agentName,
|
|
42
|
+
cwd: workspaceDir,
|
|
43
|
+
credentials,
|
|
44
|
+
modelOverride,
|
|
45
|
+
mcpBindings,
|
|
46
|
+
eventBus,
|
|
47
|
+
customTools,
|
|
48
|
+
extensionFactories,
|
|
49
|
+
runController,
|
|
50
|
+
agentToolOptions,
|
|
51
|
+
settingsManager,
|
|
52
|
+
sessionManager,
|
|
53
|
+
additionalSkillPaths,
|
|
54
|
+
skillPaths,
|
|
55
|
+
systemPrompt,
|
|
56
|
+
onDiagnostics,
|
|
57
|
+
onEvent,
|
|
58
|
+
otel: {
|
|
59
|
+
tracer,
|
|
60
|
+
meter,
|
|
61
|
+
meta: { conversationId },
|
|
62
|
+
runSpans: false,
|
|
63
|
+
getParentContext: () => currentTurnContext,
|
|
64
|
+
},
|
|
65
|
+
});
|
|
66
|
+
```
|
|
67
|
+
|
|
68
|
+
This is the primary host integration point. It:
|
|
69
|
+
|
|
70
|
+
- resolves the Recipe and selected agent;
|
|
71
|
+
- resolves model credentials fail-closed;
|
|
72
|
+
- materializes required MCP bindings fail-closed;
|
|
73
|
+
- loads Recipe skills, prompts, and extensions;
|
|
74
|
+
- registers the shared subagent tool;
|
|
75
|
+
- creates and binds the Pi `AgentSession`;
|
|
76
|
+
- returns one idempotent `dispose()` boundary.
|
|
77
|
+
|
|
78
|
+
The returned `RecipeSessionHandle` exposes:
|
|
79
|
+
|
|
80
|
+
- `session` — Pi prompt, steer, follow-up, abort, messages, and events;
|
|
81
|
+
- `recipe` — the resolved portable definition;
|
|
82
|
+
- `runs` — the subagent run controller;
|
|
83
|
+
- `dispose()` — child, session, instrumentation, and MCP cleanup.
|
|
84
|
+
|
|
85
|
+
Host injection is intentional. A managed host can supply durable session state,
|
|
86
|
+
cross-process subagent execution, inline endpoint bindings, platform
|
|
87
|
+
extensions, its own settings, an event bus, host tools, and a
|
|
88
|
+
gateway-decorated model without reimplementing Recipe semantics. The Recipe
|
|
89
|
+
continues to own model configuration and tool selection; host seams replace
|
|
90
|
+
transport and materialized resources, not the portable definition.
|
|
91
|
+
|
|
92
|
+
Default MCP materialization leases the supplied `env` object until the handle
|
|
93
|
+
is disposed and restores its prior MCP/PATH state afterward. Concurrent
|
|
94
|
+
materialized sessions must receive separate environment objects. A host that
|
|
95
|
+
materializes one process-wide MCP runtime instead passes `mcpMode: "inherit"`
|
|
96
|
+
to its sessions, as runtime-agent does.
|
|
97
|
+
|
|
98
|
+
## `runRecipe`
|
|
99
|
+
|
|
100
|
+
```ts
|
|
101
|
+
import { runRecipe } from "@introspection-ai/recipes/run";
|
|
102
|
+
|
|
103
|
+
const result = await runRecipe({
|
|
104
|
+
recipeDir,
|
|
105
|
+
cwd: workspaceDir,
|
|
106
|
+
prompt,
|
|
107
|
+
timeoutMs: 120_000,
|
|
108
|
+
});
|
|
109
|
+
```
|
|
110
|
+
|
|
111
|
+
`runRecipe` creates one session, executes one prompt, returns the transcript and
|
|
112
|
+
final text, and always disposes. It is suitable for tests, cron jobs, and queue
|
|
113
|
+
workers that do not need a durable conversational host.
|
|
114
|
+
|
|
115
|
+
## Inspection
|
|
116
|
+
|
|
117
|
+
```ts
|
|
118
|
+
import { inspectRecipe } from "@introspection-ai/recipes/inspect";
|
|
119
|
+
|
|
120
|
+
const requirements = inspectRecipe(recipeDir);
|
|
121
|
+
```
|
|
122
|
+
|
|
123
|
+
Inspection derives agents, providers, expected credential variables, required
|
|
124
|
+
and optional MCP servers, and resource counts without creating a session.
|
|
125
|
+
|
|
126
|
+
## OpenTelemetry
|
|
127
|
+
|
|
128
|
+
Pass a tracer through `otel` to attach the JS SDK's OpenTelemetry GenAI
|
|
129
|
+
semantic-convention instrumentation to the session. Recipes derives default
|
|
130
|
+
agent identity from the resolved package and generates a conversation id when
|
|
131
|
+
the host does not provide one. The default in-process subagent controller
|
|
132
|
+
inherits that conversation id while each child derives its own Recipe agent
|
|
133
|
+
identity. Injected run controllers own their child-session instrumentation.
|
|
134
|
+
|
|
135
|
+
Recipes does not create or register an OTel provider, processor, exporter, or
|
|
136
|
+
global context manager. The host owns that pipeline and its content policy. A
|
|
137
|
+
standalone host can therefore use the same standard OTLP exporter for
|
|
138
|
+
Braintrust, Langfuse, an OTel Collector, or another compatible backend. A host
|
|
139
|
+
that needs structure-only infrastructure traces can wrap that exporter with
|
|
140
|
+
`GenAiContentScrubbingExporter` from
|
|
141
|
+
`@introspection-sdk/introspection-pi`.
|
|
142
|
+
|
|
143
|
+
Short-lived hosts must flush their own provider after `runRecipe` completes;
|
|
144
|
+
long-lived hosts should flush and shut it down with the host lifecycle.
|
|
145
|
+
|
|
146
|
+
## Host conformance
|
|
147
|
+
|
|
148
|
+
```ts
|
|
149
|
+
import { hostConformanceCases } from "@introspection-ai/recipes/test-utils";
|
|
150
|
+
|
|
151
|
+
for (const testCase of hostConformanceCases(myHostAdapter)) {
|
|
152
|
+
it(testCase.name, testCase.run);
|
|
153
|
+
}
|
|
154
|
+
```
|
|
155
|
+
|
|
156
|
+
Passing the suite means the host is using the same session construction
|
|
157
|
+
contract as Pi and Introspection. Protocol behavior, persistence, tenancy, and
|
|
158
|
+
deployment remain host-specific and require their own tests.
|
|
159
|
+
|
|
160
|
+
## Deliberate non-features
|
|
161
|
+
|
|
162
|
+
The package does not provide:
|
|
163
|
+
|
|
164
|
+
- an HTTP server or wire protocol;
|
|
165
|
+
- a task database or task state machine;
|
|
166
|
+
- a scheduler or queue;
|
|
167
|
+
- sandbox or tenant isolation;
|
|
168
|
+
- a deployment CLI;
|
|
169
|
+
- provider-specific hosting adapters.
|
|
170
|
+
|
|
171
|
+
Those layers compose above `createRecipeSession`.
|
package/package.json
ADDED
|
@@ -0,0 +1,106 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "@introspection-ai/recipes",
|
|
3
|
+
"version": "0.13.0",
|
|
4
|
+
"description": "The open package format for complete, portable Pi agents.",
|
|
5
|
+
"license": "Apache-2.0",
|
|
6
|
+
"type": "module",
|
|
7
|
+
"engines": {
|
|
8
|
+
"node": ">=24"
|
|
9
|
+
},
|
|
10
|
+
"files": [
|
|
11
|
+
"dist",
|
|
12
|
+
"vendor/mcp-client",
|
|
13
|
+
"docs",
|
|
14
|
+
"README.md",
|
|
15
|
+
"package.json"
|
|
16
|
+
],
|
|
17
|
+
"repository": {
|
|
18
|
+
"type": "git",
|
|
19
|
+
"url": "git+ssh://git@github.com/introspection-org/pi-recipes.git"
|
|
20
|
+
},
|
|
21
|
+
"bugs": {
|
|
22
|
+
"url": "https://github.com/introspection-org/pi-recipes/issues"
|
|
23
|
+
},
|
|
24
|
+
"homepage": "https://github.com/introspection-org/pi-recipes#readme",
|
|
25
|
+
"publishConfig": {
|
|
26
|
+
"access": "public",
|
|
27
|
+
"tag": "latest"
|
|
28
|
+
},
|
|
29
|
+
"exports": {
|
|
30
|
+
".": {
|
|
31
|
+
"types": "./dist/index.d.ts",
|
|
32
|
+
"import": "./dist/index.js"
|
|
33
|
+
},
|
|
34
|
+
"./interactions": {
|
|
35
|
+
"types": "./dist/interactions.d.ts",
|
|
36
|
+
"import": "./dist/interactions.js"
|
|
37
|
+
},
|
|
38
|
+
"./pi-extension": {
|
|
39
|
+
"types": "./dist/pi-extension.d.ts",
|
|
40
|
+
"import": "./dist/pi-extension.js"
|
|
41
|
+
},
|
|
42
|
+
"./pi": {
|
|
43
|
+
"types": "./dist/agent-tool.d.ts",
|
|
44
|
+
"import": "./dist/agent-tool.js"
|
|
45
|
+
},
|
|
46
|
+
"./recipe": {
|
|
47
|
+
"types": "./dist/recipe/resolve.d.ts",
|
|
48
|
+
"import": "./dist/recipe/resolve.js"
|
|
49
|
+
},
|
|
50
|
+
"./session": {
|
|
51
|
+
"types": "./dist/session.d.ts",
|
|
52
|
+
"import": "./dist/session.js"
|
|
53
|
+
},
|
|
54
|
+
"./run": {
|
|
55
|
+
"types": "./dist/run.d.ts",
|
|
56
|
+
"import": "./dist/run.js"
|
|
57
|
+
},
|
|
58
|
+
"./test-utils": {
|
|
59
|
+
"types": "./dist/test-utils.d.ts",
|
|
60
|
+
"import": "./dist/test-utils.js"
|
|
61
|
+
},
|
|
62
|
+
"./inspect": {
|
|
63
|
+
"types": "./dist/inspect.d.ts",
|
|
64
|
+
"import": "./dist/inspect.js"
|
|
65
|
+
}
|
|
66
|
+
},
|
|
67
|
+
"pi": {
|
|
68
|
+
"extensions": [
|
|
69
|
+
"./dist/pi-extension.js"
|
|
70
|
+
]
|
|
71
|
+
},
|
|
72
|
+
"dependencies": {
|
|
73
|
+
"@introspection-sdk/introspection-pi": "^0.13.0",
|
|
74
|
+
"@opentelemetry/api": "^1.9.1",
|
|
75
|
+
"mcporter": "0.12.3",
|
|
76
|
+
"yaml": "^2.9.0"
|
|
77
|
+
},
|
|
78
|
+
"peerDependencies": {
|
|
79
|
+
"@earendil-works/pi-agent-core": "^0.82.0",
|
|
80
|
+
"@earendil-works/pi-ai": "^0.82.0",
|
|
81
|
+
"@earendil-works/pi-coding-agent": "^0.82.0",
|
|
82
|
+
"@earendil-works/pi-tui": "^0.82.0",
|
|
83
|
+
"typebox": "*"
|
|
84
|
+
},
|
|
85
|
+
"devDependencies": {
|
|
86
|
+
"@earendil-works/pi-agent-core": "0.82.0",
|
|
87
|
+
"@earendil-works/pi-ai": "0.82.0",
|
|
88
|
+
"@earendil-works/pi-coding-agent": "0.82.0",
|
|
89
|
+
"@earendil-works/pi-tui": "0.82.0",
|
|
90
|
+
"@types/node": "^22.10.0",
|
|
91
|
+
"esbuild": "^0.28.1",
|
|
92
|
+
"typebox": "^1.0.56",
|
|
93
|
+
"typescript": "^5.7.3",
|
|
94
|
+
"vitest": "^4.0.18"
|
|
95
|
+
},
|
|
96
|
+
"scripts": {
|
|
97
|
+
"build": "pnpm build:ts && pnpm build:native",
|
|
98
|
+
"build:ts": "rm -rf dist && tsc && node scripts/build-mcp-daemon.mjs",
|
|
99
|
+
"build:native": "cargo build --release -p pi-mcp-client && node scripts/package-mcp-client.mjs",
|
|
100
|
+
"bench:mcp-client": "pnpm build:ts && cargo build --release -p pi-mcp-client && node scripts/benchmark-mcp-client.mjs",
|
|
101
|
+
"typecheck": "node scripts/check-recipe-check-versions.mjs && tsc --noEmit && tsc --noEmit -p tsconfig.test.json",
|
|
102
|
+
"test": "pnpm build:ts && cargo test -p pi-mcp-client -p pi-recipe-check && cargo build -p pi-mcp-client && MCP_CLIENT_BIN=target/debug/mcp-client node scripts/package-mcp-client.mjs && vitest run",
|
|
103
|
+
"pack:check": "pnpm pack --dry-run --json | node scripts/check-npm-pack.mjs",
|
|
104
|
+
"clean": "rm -rf dist .turbo node_modules target vendor/mcp-client"
|
|
105
|
+
}
|
|
106
|
+
}
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|