@introspection-ai/recipes 0.13.0 → 0.14.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 +46 -57
- package/dist/{agent-tool.d.ts → agents.d.ts} +4 -1
- package/dist/agents.d.ts.map +1 -0
- package/dist/{agent-tool.js → agents.js} +1 -1
- package/dist/agents.js.map +1 -0
- package/dist/api/extensions.d.ts +3 -0
- package/dist/api/extensions.d.ts.map +1 -0
- package/dist/api/extensions.js +2 -0
- package/dist/api/extensions.js.map +1 -0
- package/dist/api/mcp.d.ts +4 -0
- package/dist/api/mcp.d.ts.map +1 -0
- package/dist/api/mcp.js +2 -0
- package/dist/api/mcp.js.map +1 -0
- package/dist/api/session.d.ts +3 -0
- package/dist/api/session.d.ts.map +1 -0
- package/dist/api/session.js +2 -0
- package/dist/api/session.js.map +1 -0
- package/dist/child-agent.d.ts +5 -4
- package/dist/child-agent.d.ts.map +1 -1
- package/dist/child-agent.js +26 -117
- package/dist/child-agent.js.map +1 -1
- package/dist/child-session.d.ts +23 -0
- package/dist/child-session.d.ts.map +1 -0
- package/dist/child-session.js +48 -0
- package/dist/child-session.js.map +1 -0
- package/dist/extensions.d.ts +29 -0
- package/dist/extensions.d.ts.map +1 -0
- package/dist/extensions.js +119 -0
- package/dist/extensions.js.map +1 -0
- package/dist/index.d.ts +4 -13
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +2 -13
- package/dist/index.js.map +1 -1
- package/dist/inspect.d.ts +38 -5
- package/dist/inspect.d.ts.map +1 -1
- package/dist/inspect.js +92 -41
- package/dist/inspect.js.map +1 -1
- package/dist/interactions.d.ts +18 -2
- package/dist/interactions.d.ts.map +1 -1
- package/dist/interactions.js +41 -10
- package/dist/interactions.js.map +1 -1
- package/dist/mcp-catalog.d.ts +1 -0
- package/dist/mcp-catalog.d.ts.map +1 -1
- package/dist/mcp-catalog.js +14 -6
- package/dist/mcp-catalog.js.map +1 -1
- package/dist/mcp-chunks/auth-command-ZLGYIEUY.js +273 -0
- package/dist/mcp-chunks/call-arguments-LU3W6D3K.js +13 -0
- package/dist/mcp-chunks/call-command-LKTKSYTH.js +612 -0
- package/dist/mcp-chunks/chunk-2U4BSDC4.js +3951 -0
- package/dist/mcp-chunks/chunk-2XL7MG7R.js +272 -0
- package/dist/mcp-chunks/chunk-3BJA27PY.js +2321 -0
- package/dist/mcp-chunks/chunk-4SQKWYFF.js +15 -0
- package/dist/mcp-chunks/chunk-5QOSCSQB.js +290 -0
- package/dist/mcp-chunks/chunk-6W5QFASN.js +77 -0
- package/dist/mcp-chunks/chunk-6XCZGU3G.js +1004 -0
- package/dist/mcp-chunks/chunk-7FHEBT5G.js +149 -0
- package/dist/mcp-chunks/chunk-7KA2VJVZ.js +114 -0
- package/dist/mcp-chunks/chunk-7UDVSOOF.js +138 -0
- package/dist/mcp-chunks/chunk-BNV3TPE4.js +66 -0
- package/dist/mcp-chunks/chunk-BTLAWHTA.js +129 -0
- package/dist/mcp-chunks/chunk-BV56DXPW.js +13 -0
- package/dist/mcp-chunks/chunk-BWHIA4PC.js +90 -0
- package/dist/mcp-chunks/chunk-BZIQOWE6.js +267 -0
- package/dist/mcp-chunks/chunk-D3MRAZ6H.js +16140 -0
- package/dist/mcp-chunks/chunk-DHBE7UBH.js +750 -0
- package/dist/mcp-chunks/chunk-E22DYOW5.js +251 -0
- package/dist/mcp-chunks/chunk-ECIVB7P4.js +139 -0
- package/dist/mcp-chunks/chunk-HKRJ6O36.js +1076 -0
- package/dist/mcp-chunks/chunk-IABRYROW.js +44 -0
- package/dist/mcp-chunks/chunk-J6LYIZXN.js +45 -0
- package/dist/mcp-chunks/chunk-L7NTQVYN.js +161 -0
- package/dist/mcp-chunks/chunk-LEZSACDE.js +141 -0
- package/dist/mcp-chunks/chunk-LKIBAYKU.js +208 -0
- package/dist/mcp-chunks/chunk-LNH5LAJD.js +152 -0
- package/dist/mcp-chunks/chunk-LQQEYD76.js +124 -0
- package/dist/mcp-chunks/chunk-LRKZP7DJ.js +47 -0
- package/dist/mcp-chunks/chunk-LS7PMWSR.js +109 -0
- package/dist/mcp-chunks/chunk-M3TPODXI.js +95 -0
- package/dist/mcp-chunks/chunk-MZ2NARG7.js +400 -0
- package/dist/mcp-chunks/chunk-N46NEFAF.js +45 -0
- package/dist/mcp-chunks/chunk-NNOEGEUZ.js +17273 -0
- package/dist/mcp-chunks/chunk-NRAJX5E4.js +69 -0
- package/dist/mcp-chunks/chunk-P3PSC54P.js +869 -0
- package/dist/mcp-chunks/chunk-PIIYJR44.js +6341 -0
- package/dist/mcp-chunks/chunk-PWYFKGKG.js +385 -0
- package/dist/mcp-chunks/chunk-SJCCBNZ4.js +45 -0
- package/dist/mcp-chunks/chunk-TATVT5IT.js +194 -0
- package/dist/mcp-chunks/chunk-TEUKFFQL.js +29 -0
- package/dist/mcp-chunks/chunk-UKYNQGNE.js +150 -0
- package/dist/mcp-chunks/chunk-UNKB4SBV.js +37 -0
- package/dist/mcp-chunks/chunk-WD6BOD24.js +138 -0
- package/dist/mcp-chunks/chunk-WQJZMCJN.js +73 -0
- package/dist/mcp-chunks/chunk-XANPGTLI.js +364 -0
- package/dist/mcp-chunks/chunk-XQK2JSW4.js +35 -0
- package/dist/mcp-chunks/chunk-YHQUTU6L.js +571 -0
- package/dist/mcp-chunks/chunk-YVZKMV5H.js +57 -0
- package/dist/mcp-chunks/cli-UV4QJZZM.js +929 -0
- package/dist/mcp-chunks/client-S7RQUG5U.js +13 -0
- package/dist/mcp-chunks/config-command-NLAGKID5.js +1101 -0
- package/dist/mcp-chunks/daemon-command-U242Z6VY.js +26 -0
- package/dist/mcp-chunks/dist-LK3SHAMX.js +6478 -0
- package/dist/mcp-chunks/emit-ts-command-VBXVXO6V.js +386 -0
- package/dist/mcp-chunks/generate-cli-runner-6CAZZA3P.js +1426 -0
- package/dist/mcp-chunks/inspect-cli-command-3ZORTOR7.js +111 -0
- package/dist/mcp-chunks/launch-YKRXHXJI.js +10 -0
- package/dist/mcp-chunks/lifecycle-XVKRHPH3.js +16 -0
- package/dist/mcp-chunks/list-command-2MEGGNFQ.js +4190 -0
- package/dist/mcp-chunks/output-utils-NKESLAJ6.js +12 -0
- package/dist/mcp-chunks/prompt-B1Yc1NPt-VGOTWJMN.js +918 -0
- package/dist/mcp-chunks/record-command-YXHTTTT5.js +17 -0
- package/dist/mcp-chunks/replay-command-25HJ6AQU.js +85 -0
- package/dist/mcp-chunks/resource-command-OO4NYF5C.js +97 -0
- package/dist/mcp-chunks/result-utils-MOHHLNM7.js +15 -0
- package/dist/mcp-chunks/runtime-5WJ3G25Y.js +33 -0
- package/dist/mcp-chunks/runtime-wrapper-RPWDIDBF.js +10 -0
- package/dist/mcp-chunks/serve-command-DHXJZMMN.js +3302 -0
- package/dist/mcp-chunks/timeouts-W2XWCCXR.js +18 -0
- package/dist/mcp-chunks/vault-command-PIYIUEZL.js +154 -0
- package/dist/mcp-daemon-client.d.ts +6 -1
- package/dist/mcp-daemon-client.d.ts.map +1 -1
- package/dist/mcp-daemon-client.js +119 -2
- package/dist/mcp-daemon-client.js.map +1 -1
- package/dist/mcp-daemon-protocol.d.ts +18 -1
- package/dist/mcp-daemon-protocol.d.ts.map +1 -1
- package/dist/mcp-daemon-protocol.js +31 -0
- package/dist/mcp-daemon-protocol.js.map +1 -1
- package/dist/mcp-daemon.js +169 -76602
- package/dist/mcp-daemon.js.map +1 -1
- package/dist/mcp-policy.d.ts +11 -0
- package/dist/mcp-policy.d.ts.map +1 -0
- package/dist/mcp-policy.js +27 -0
- package/dist/mcp-policy.js.map +1 -0
- package/dist/mcp-run-worker.js +38 -76540
- package/dist/mcp-tools.d.ts +39 -0
- package/dist/mcp-tools.d.ts.map +1 -0
- package/dist/mcp-tools.js +493 -0
- package/dist/mcp-tools.js.map +1 -0
- package/dist/mcp.d.ts +21 -9
- package/dist/mcp.d.ts.map +1 -1
- package/dist/mcp.js +101 -31
- package/dist/mcp.js.map +1 -1
- package/dist/model-binding.d.ts +39 -0
- package/dist/model-binding.d.ts.map +1 -0
- package/dist/model-binding.js +103 -0
- package/dist/model-binding.js.map +1 -0
- package/dist/pi-extension.d.ts +2 -22
- package/dist/pi-extension.d.ts.map +1 -1
- package/dist/pi-extension.js +296 -71
- package/dist/pi-extension.js.map +1 -1
- package/dist/recipe/resolve.d.ts +43 -20
- package/dist/recipe/resolve.d.ts.map +1 -1
- package/dist/recipe/resolve.js +215 -70
- package/dist/recipe/resolve.js.map +1 -1
- package/dist/recipe-agent.d.ts +24 -27
- package/dist/recipe-agent.d.ts.map +1 -1
- package/dist/recipe-agent.js +278 -230
- package/dist/recipe-agent.js.map +1 -1
- package/dist/recipe-check.d.ts +18 -0
- package/dist/recipe-check.d.ts.map +1 -0
- package/dist/recipe-check.js +261 -0
- package/dist/recipe-check.js.map +1 -0
- package/dist/recipe-extensions.d.ts.map +1 -1
- package/dist/recipe-extensions.js +0 -3
- package/dist/recipe-extensions.js.map +1 -1
- package/dist/recipe-model.d.ts +3 -1
- package/dist/recipe-model.d.ts.map +1 -1
- package/dist/recipe-model.js +15 -12
- package/dist/recipe-model.js.map +1 -1
- package/dist/recipe-package.d.ts +6 -28
- package/dist/recipe-package.d.ts.map +1 -1
- package/dist/recipe-package.js +248 -191
- package/dist/recipe-package.js.map +1 -1
- package/dist/recipe-skills.d.ts.map +1 -1
- package/dist/recipe-skills.js +42 -29
- package/dist/recipe-skills.js.map +1 -1
- package/dist/run-controller.d.ts +10 -9
- package/dist/run-controller.d.ts.map +1 -1
- package/dist/run-controller.js +28 -21
- package/dist/run-controller.js.map +1 -1
- package/dist/session.d.ts +40 -53
- package/dist/session.d.ts.map +1 -1
- package/dist/session.js +312 -173
- package/dist/session.js.map +1 -1
- package/dist/test-utils.d.ts +7 -7
- package/dist/test-utils.d.ts.map +1 -1
- package/dist/test-utils.js +32 -15
- package/dist/test-utils.js.map +1 -1
- package/docs/agent-composition.md +41 -35
- package/docs/host-api.md +201 -0
- package/docs/index.md +9 -14
- package/docs/interactions.md +12 -11
- package/docs/mcp-auth.md +6 -6
- package/docs/mcp-configuration.md +73 -25
- package/docs/pi-extension.md +39 -11
- package/docs/recipe-flow.md +9 -9
- package/docs/recipe-format.md +106 -41
- package/docs/recipe-judges.md +24 -36
- package/package.json +23 -17
- 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/recipe-check/darwin-arm64/recipe-check +0 -0
- package/vendor/recipe-check/darwin-x64/recipe-check +0 -0
- package/vendor/recipe-check/linux-arm64/recipe-check +0 -0
- package/vendor/recipe-check/linux-x64/recipe-check +0 -0
- package/vendor/recipe-check/linux-x64-musl/recipe-check +0 -0
- package/vendor/recipe-check/win32-x64/recipe-check.exe +0 -0
- package/dist/agent-tool.d.ts.map +0 -1
- package/dist/agent-tool.js.map +0 -1
- package/dist/run.d.ts +0 -28
- package/dist/run.d.ts.map +0 -1
- package/dist/run.js +0 -84
- package/dist/run.js.map +0 -1
- package/dist/testing.d.ts +0 -25
- package/dist/testing.d.ts.map +0 -1
- package/dist/testing.js +0 -96
- package/dist/testing.js.map +0 -1
- package/docs/deployment-configuration.md +0 -65
- package/docs/migration.md +0 -70
- package/docs/python-bindings-release.md +0 -47
- package/docs/recipe-evals.md +0 -70
- package/docs/runtime-library.md +0 -171
package/dist/session.js
CHANGED
|
@@ -1,137 +1,123 @@
|
|
|
1
1
|
import { randomUUID } from "node:crypto";
|
|
2
|
-
import {
|
|
3
|
-
import {
|
|
4
|
-
import { createAgentSessionFromServices, createAgentSessionServices, ModelRuntime, SessionManager, SettingsManager, } from "@earendil-works/pi-coding-agent";
|
|
2
|
+
import { rm } from "node:fs/promises";
|
|
3
|
+
import { getModel } from "@earendil-works/pi-ai/compat";
|
|
4
|
+
import { createBashToolDefinition, createAgentSessionFromServices, createAgentSessionServices, ModelRuntime, SessionManager, SettingsManager, } from "@earendil-works/pi-coding-agent";
|
|
5
5
|
import { instrumentSession, } from "@introspection-sdk/introspection-pi";
|
|
6
|
-
import { createAgentTool } from "./
|
|
6
|
+
import { createAgentTool } from "./agents.js";
|
|
7
7
|
import { clearMcpCatalogPreload, preloadMcpCatalogs, } from "./mcp-catalog.js";
|
|
8
|
-
import { configureMcpLocalConfigPath, isolateMcpEnvironment, materializeMcpSession, materializeSessionMcpCli, restoreMcpEnvironment, resolveAgentMcpSelections, snapshotMcpEnvironment, stopMcpDaemon, } from "./mcp.js";
|
|
9
|
-
import {
|
|
8
|
+
import { createIsolatedMcpEnvironment, configureMcpLocalConfigPath, isolateMcpEnvironment, materializeMcpSession, materializeSessionMcpCli, readMcpSessionConfig, restoreMcpEnvironment, resolveAgentMcpSelections, snapshotMcpEnvironment, stopMcpDaemon, } from "./mcp.js";
|
|
9
|
+
import { createMcpToolSet } from "./mcp-tools.js";
|
|
10
|
+
import { assertRecipeModelTransport, RecipeCredentialError, RecipeModelError, RecipeModelTransportError, resolveRecipeCredentials, } from "./model-binding.js";
|
|
10
11
|
import { loadRecipeExtensionFactory } from "./recipe-extensions.js";
|
|
11
|
-
import {
|
|
12
|
-
import {
|
|
12
|
+
import { bindRecipeExtensionFactory, createRecipeExtensionRegistrationRegistry, recipeExtensionToolAllowlist, } from "./extensions.js";
|
|
13
|
+
import { applyRecipeAgentModelConfigToModel, applyRecipeAgentModelConfigToSession, cloneModelForRecipe, } from "./recipe-model.js";
|
|
13
14
|
export { expectedProviderEnvVars } from "./provider-env.js";
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
15
|
+
export { RecipeCredentialError, RecipeModelError, RecipeModelTransportError, };
|
|
16
|
+
function schemaChildPosition(position, key) {
|
|
17
|
+
if (position === "schema-map")
|
|
18
|
+
return "schema";
|
|
19
|
+
if (position === "literal")
|
|
20
|
+
return "literal";
|
|
21
|
+
if (key === "properties" ||
|
|
22
|
+
key === "patternProperties" ||
|
|
23
|
+
key === "$defs" ||
|
|
24
|
+
key === "definitions" ||
|
|
25
|
+
key === "dependentSchemas") {
|
|
26
|
+
return "schema-map";
|
|
25
27
|
}
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
constructor(modelSpec) {
|
|
32
|
-
super(`Recipe model is not available: ${modelSpec}`);
|
|
33
|
-
this.modelSpec = modelSpec;
|
|
28
|
+
if (key === "default" ||
|
|
29
|
+
key === "const" ||
|
|
30
|
+
key === "examples" ||
|
|
31
|
+
key === "enum") {
|
|
32
|
+
return "literal";
|
|
34
33
|
}
|
|
34
|
+
return "schema";
|
|
35
35
|
}
|
|
36
|
-
function
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
36
|
+
function stripAdditionalProperties(value, position = "schema") {
|
|
37
|
+
if (value === null || typeof value !== "object")
|
|
38
|
+
return value;
|
|
39
|
+
const clone = Array.isArray(value)
|
|
40
|
+
? []
|
|
41
|
+
: Object.create(Object.getPrototypeOf(value));
|
|
42
|
+
for (const key of Reflect.ownKeys(value)) {
|
|
43
|
+
if (position === "schema" && key === "additionalProperties")
|
|
44
|
+
continue;
|
|
45
|
+
const descriptor = Object.getOwnPropertyDescriptor(value, key);
|
|
46
|
+
if (!descriptor)
|
|
47
|
+
continue;
|
|
48
|
+
if ("value" in descriptor) {
|
|
49
|
+
descriptor.value = stripAdditionalProperties(descriptor.value, schemaChildPosition(position, key));
|
|
50
|
+
}
|
|
51
|
+
Object.defineProperty(clone, key, descriptor);
|
|
40
52
|
}
|
|
41
|
-
|
|
42
|
-
const modelId = spec.slice(slash + 1);
|
|
43
|
-
const lookupProvider = provider === "gemini" ? "google" : provider;
|
|
44
|
-
return { provider, modelId, lookupProvider };
|
|
53
|
+
return clone;
|
|
45
54
|
}
|
|
46
55
|
/**
|
|
47
|
-
*
|
|
48
|
-
*
|
|
49
|
-
|
|
50
|
-
const AMBIENT_CREDENTIAL_SENTINEL = "<authenticated>";
|
|
51
|
-
/**
|
|
52
|
-
* Resolve credentials fail-closed against the session's own `env`, never the
|
|
53
|
-
* ambient process env: explicit store → per-provider env keys → error.
|
|
56
|
+
* Gemini rejects JSON Schema's `additionalProperties` keyword in tool
|
|
57
|
+
* declarations. Normalize the final Recipe toolset after host tools and the
|
|
58
|
+
* shared agent tool have been registered so every host gets the same behavior.
|
|
54
59
|
*/
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
}
|
|
63
|
-
const env = opts.env ?? process.env;
|
|
64
|
-
const store = new InMemoryCredentialStore();
|
|
65
|
-
const apiKey = getEnvApiKey(lookupProvider, env) ??
|
|
66
|
-
env[`${lookupProvider.toUpperCase().replace(/-/g, "_")}_API_KEY`];
|
|
67
|
-
if (!apiKey) {
|
|
68
|
-
throw new RecipeCredentialError(lookupProvider, expectedProviderEnvVars(lookupProvider));
|
|
69
|
-
}
|
|
70
|
-
if (apiKey !== AMBIENT_CREDENTIAL_SENTINEL) {
|
|
71
|
-
await store.modify(lookupProvider, async () => ({
|
|
72
|
-
type: "api_key",
|
|
73
|
-
key: apiKey,
|
|
74
|
-
}));
|
|
60
|
+
function normalizeSessionToolsForModel(session, model) {
|
|
61
|
+
const isGemini = [model.id, model.name].some((value) => value?.toLowerCase().includes("gemini"));
|
|
62
|
+
if (!isGemini)
|
|
63
|
+
return;
|
|
64
|
+
const mutableSession = session;
|
|
65
|
+
for (const tool of mutableSession.agent?.state?.tools ?? []) {
|
|
66
|
+
tool.parameters = stripAdditionalProperties(tool.parameters);
|
|
75
67
|
}
|
|
76
|
-
// Ambient-credential providers (Bedrock, Vertex ADC) keep an empty store;
|
|
77
|
-
// the pi-ai provider resolves its own credential chain at stream time.
|
|
78
|
-
return store;
|
|
79
68
|
}
|
|
80
69
|
function scopedMcpSelections(recipe) {
|
|
81
|
-
return
|
|
70
|
+
return resolveAgentMcpSelections(recipe.mcp);
|
|
82
71
|
}
|
|
83
72
|
const leasedMcpEnvironments = new WeakSet();
|
|
84
73
|
export class RecipeMcpEnvironmentInUseError extends Error {
|
|
85
74
|
name = "RecipeMcpEnvironmentInUseError";
|
|
86
75
|
constructor() {
|
|
87
|
-
super("This environment already belongs to a live materialized Recipe MCP session; use a separate env object per concurrent session or let the host materialize MCP once and pass
|
|
88
|
-
}
|
|
89
|
-
}
|
|
90
|
-
/**
|
|
91
|
-
* Everything `createRecipeSession` fail-closes on, without creating a
|
|
92
|
-
* session or starting MCP: recipe resolution, model lookup, credentials.
|
|
93
|
-
* Hosts with a boot phase (the serve layer) run this once to fail fast.
|
|
94
|
-
*/
|
|
95
|
-
export async function preflightRecipeSession(opts) {
|
|
96
|
-
const recipe = resolveRecipe({
|
|
97
|
-
recipeDir: opts.recipeDir,
|
|
98
|
-
...(opts.agentName ? { agentName: opts.agentName } : {}),
|
|
99
|
-
});
|
|
100
|
-
const modelSpec = opts.model ?? recipe.modelSpec;
|
|
101
|
-
const { lookupProvider, modelId } = parseModelSpec(modelSpec);
|
|
102
|
-
const credentialProvider = opts.modelOverride?.provider ?? lookupProvider;
|
|
103
|
-
const credentials = await resolveCredentialStore(credentialProvider, opts);
|
|
104
|
-
const modelRuntime = await ModelRuntime.create({
|
|
105
|
-
credentials,
|
|
106
|
-
modelsPath: null,
|
|
107
|
-
});
|
|
108
|
-
const model = opts.modelOverride ??
|
|
109
|
-
modelRuntime.getModel(lookupProvider, modelId) ??
|
|
110
|
-
getModel(lookupProvider, modelId);
|
|
111
|
-
if (!model) {
|
|
112
|
-
throw new RecipeModelError(modelSpec);
|
|
76
|
+
super("This environment already belongs to a live materialized Recipe MCP session; use a separate env object per concurrent session or let the host materialize MCP once and pass mcpProvisioning: \"host\"");
|
|
113
77
|
}
|
|
114
|
-
return recipe;
|
|
115
78
|
}
|
|
116
79
|
/**
|
|
117
80
|
* Materialize the session MCP runtime for a recipe scope into `env` at
|
|
118
|
-
* `cwd`. Exposed for hosts that materialize once per process
|
|
119
|
-
*
|
|
81
|
+
* `cwd`. Exposed for hosts that materialize once per process and create their
|
|
82
|
+
* sessions with `mcpProvisioning: "host"`.
|
|
120
83
|
*/
|
|
121
84
|
export async function materializeRecipeSessionMcp(recipe, cwd, env, opts = {}) {
|
|
122
|
-
return configureSessionMcp(recipe, cwd, env, {
|
|
123
|
-
recipeDir: recipe.recipeDir,
|
|
124
|
-
...opts,
|
|
125
|
-
}, false);
|
|
126
|
-
}
|
|
127
|
-
async function configureSessionMcp(recipe, cwd, env, opts, leaseEnvironment) {
|
|
128
85
|
const selections = scopedMcpSelections(recipe);
|
|
129
|
-
if (opts.mcpMode === "inherit")
|
|
130
|
-
return { materialized: false };
|
|
131
86
|
if (selections.length === 0)
|
|
132
87
|
return { materialized: false };
|
|
133
|
-
|
|
134
|
-
|
|
88
|
+
if (opts.mcpBindingsPath) {
|
|
89
|
+
env.PI_RECIPES_MCP_LOCAL_CONFIG = opts.mcpBindingsPath;
|
|
90
|
+
}
|
|
91
|
+
else if (!opts.mcpBindings) {
|
|
92
|
+
configureMcpLocalConfigPath({ cwd, recipeDir: recipe.recipeDir, env });
|
|
93
|
+
}
|
|
94
|
+
if (recipe.mcp?.mode === "cli") {
|
|
95
|
+
await materializeSessionMcpCli({ cwd, env });
|
|
96
|
+
}
|
|
97
|
+
await materializeMcpSession({
|
|
98
|
+
cwd,
|
|
99
|
+
manifest: recipe.manifest,
|
|
100
|
+
agentMcp: selections,
|
|
101
|
+
env,
|
|
102
|
+
...(opts.mcpBindings ? { localConfig: opts.mcpBindings } : {}),
|
|
103
|
+
});
|
|
104
|
+
return { materialized: true };
|
|
105
|
+
}
|
|
106
|
+
async function configureSessionMcp(recipe, cwd, env, opts, activation) {
|
|
107
|
+
const selections = scopedMcpSelections(recipe);
|
|
108
|
+
if (selections.length === 0) {
|
|
109
|
+
return { available: false, materialized: false };
|
|
110
|
+
}
|
|
111
|
+
const mode = recipe.mcp?.mode ?? "cli";
|
|
112
|
+
const hostProvisioned = opts.mcpProvisioning === "host";
|
|
113
|
+
const mcpCwd = opts.mcpRuntimeDir ?? cwd;
|
|
114
|
+
const snapshot = !hostProvisioned && mode === "cli"
|
|
115
|
+
? snapshotMcpEnvironment(env)
|
|
116
|
+
: undefined;
|
|
117
|
+
let runtimeEnv = env;
|
|
118
|
+
let privateDirectory;
|
|
119
|
+
let privateMcporterConfigPath;
|
|
120
|
+
if (snapshot) {
|
|
135
121
|
if (leasedMcpEnvironments.has(env)) {
|
|
136
122
|
throw new RecipeMcpEnvironmentInUseError();
|
|
137
123
|
}
|
|
@@ -139,46 +125,87 @@ async function configureSessionMcp(recipe, cwd, env, opts, leaseEnvironment) {
|
|
|
139
125
|
isolateMcpEnvironment(env);
|
|
140
126
|
}
|
|
141
127
|
const release = async () => {
|
|
142
|
-
if (
|
|
128
|
+
if (hostProvisioned)
|
|
143
129
|
return;
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
130
|
+
clearMcpCatalogPreload(runtimeEnv);
|
|
131
|
+
await stopMcpDaemon(runtimeEnv);
|
|
132
|
+
if (privateDirectory) {
|
|
133
|
+
await rm(privateDirectory, { recursive: true, force: true });
|
|
147
134
|
}
|
|
148
|
-
|
|
135
|
+
if (snapshot) {
|
|
149
136
|
restoreMcpEnvironment(env, snapshot);
|
|
150
137
|
leasedMcpEnvironments.delete(env);
|
|
151
138
|
}
|
|
152
139
|
};
|
|
153
140
|
try {
|
|
154
|
-
if (
|
|
155
|
-
|
|
141
|
+
if (!hostProvisioned && mode === "tools") {
|
|
142
|
+
const isolated = await createIsolatedMcpEnvironment(env);
|
|
143
|
+
runtimeEnv = isolated.env;
|
|
144
|
+
privateDirectory = isolated.directory;
|
|
145
|
+
privateMcporterConfigPath = isolated.mcporterConfigPath;
|
|
156
146
|
}
|
|
157
|
-
|
|
158
|
-
|
|
147
|
+
let session;
|
|
148
|
+
if (hostProvisioned) {
|
|
149
|
+
session = readMcpSessionConfig(cwd, runtimeEnv);
|
|
159
150
|
}
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
151
|
+
else {
|
|
152
|
+
if (opts.mcpBindingsPath) {
|
|
153
|
+
runtimeEnv.PI_RECIPES_MCP_LOCAL_CONFIG = opts.mcpBindingsPath;
|
|
154
|
+
}
|
|
155
|
+
else if (!opts.mcpBindings) {
|
|
156
|
+
configureMcpLocalConfigPath({
|
|
157
|
+
cwd,
|
|
158
|
+
recipeDir: recipe.recipeDir,
|
|
159
|
+
env: runtimeEnv,
|
|
160
|
+
});
|
|
161
|
+
}
|
|
162
|
+
if (mode === "cli") {
|
|
163
|
+
await materializeSessionMcpCli({ cwd: mcpCwd, env: runtimeEnv });
|
|
164
|
+
}
|
|
165
|
+
session = await materializeMcpSession({
|
|
166
|
+
cwd: mcpCwd,
|
|
164
167
|
manifest: recipe.manifest,
|
|
165
168
|
agentMcp: selections,
|
|
166
|
-
env,
|
|
169
|
+
env: runtimeEnv,
|
|
167
170
|
...(opts.mcpBindings ? { localConfig: opts.mcpBindings } : {}),
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
|
|
171
|
+
...(privateMcporterConfigPath
|
|
172
|
+
? { mcporterConfigPath: privateMcporterConfigPath }
|
|
173
|
+
: {}),
|
|
174
|
+
});
|
|
175
|
+
}
|
|
176
|
+
if (mode === "tools") {
|
|
177
|
+
const catalogs = session.servers.length > 0
|
|
178
|
+
? await preloadMcpCatalogs({
|
|
179
|
+
env: runtimeEnv,
|
|
180
|
+
allowPartial: true,
|
|
181
|
+
})
|
|
182
|
+
: [];
|
|
183
|
+
const materialized = createMcpToolSet({
|
|
184
|
+
session,
|
|
185
|
+
catalogs,
|
|
186
|
+
mcp: recipe.mcp,
|
|
187
|
+
env: runtimeEnv,
|
|
188
|
+
activation,
|
|
189
|
+
});
|
|
190
|
+
return {
|
|
191
|
+
available: true,
|
|
192
|
+
materialized: !hostProvisioned,
|
|
193
|
+
tools: materialized.tools,
|
|
194
|
+
initialActiveToolNames: materialized.initialActiveToolNames,
|
|
195
|
+
...(materialized.searchToolName
|
|
196
|
+
? { searchToolName: materialized.searchToolName }
|
|
197
|
+
: {}),
|
|
198
|
+
release,
|
|
199
|
+
};
|
|
200
|
+
}
|
|
175
201
|
if (session.servers.length > 0) {
|
|
176
202
|
// Warm tool catalogs in the background; sessions work without the warmup.
|
|
177
|
-
void preloadMcpCatalogs({ env }).catch(() => { });
|
|
203
|
+
void preloadMcpCatalogs({ env: runtimeEnv }).catch(() => { });
|
|
178
204
|
}
|
|
179
205
|
return {
|
|
180
|
-
|
|
181
|
-
|
|
206
|
+
available: true,
|
|
207
|
+
materialized: !hostProvisioned,
|
|
208
|
+
release,
|
|
182
209
|
};
|
|
183
210
|
}
|
|
184
211
|
catch (error) {
|
|
@@ -186,42 +213,49 @@ async function configureSessionMcp(recipe, cwd, env, opts, leaseEnvironment) {
|
|
|
186
213
|
throw error;
|
|
187
214
|
}
|
|
188
215
|
}
|
|
189
|
-
|
|
190
|
-
const recipe = resolveRecipe({
|
|
191
|
-
recipeDir: opts.recipeDir,
|
|
192
|
-
...(opts.agentName ? { agentName: opts.agentName } : {}),
|
|
193
|
-
});
|
|
216
|
+
async function createSessionForAgent(recipe, opts) {
|
|
194
217
|
const cwd = opts.cwd ?? process.cwd();
|
|
195
218
|
const env = opts.env ?? process.env;
|
|
219
|
+
const recipeExtensionContext = Object.freeze({
|
|
220
|
+
recipe: Object.freeze({ name: recipe.manifest.name }),
|
|
221
|
+
agent: Object.freeze({ name: recipe.name }),
|
|
222
|
+
session: Object.freeze({
|
|
223
|
+
role: opts.sessionRole,
|
|
224
|
+
}),
|
|
225
|
+
});
|
|
196
226
|
const otel = opts.otel
|
|
197
227
|
? {
|
|
198
228
|
...opts.otel,
|
|
199
229
|
meta: {
|
|
200
230
|
conversationId: opts.otel.meta?.conversationId ?? randomUUID(),
|
|
201
231
|
agentId: opts.otel.meta?.agentId ??
|
|
202
|
-
`${recipe.manifest.name}/${recipe.
|
|
203
|
-
agentName: opts.otel.meta?.agentName ?? recipe.
|
|
232
|
+
`${recipe.manifest.name}/${recipe.name}`,
|
|
233
|
+
agentName: opts.otel.meta?.agentName ?? recipe.name,
|
|
204
234
|
},
|
|
205
235
|
}
|
|
206
236
|
: undefined;
|
|
207
237
|
// Model + credentials, fail-closed before any MCP runtime starts.
|
|
208
|
-
const modelSpec =
|
|
209
|
-
const { lookupProvider, modelId } =
|
|
238
|
+
const modelSpec = recipe.modelSpec;
|
|
239
|
+
const { lookupProvider, modelId } = assertRecipeModelTransport(modelSpec, opts.modelOverride);
|
|
210
240
|
const credentialProvider = opts.modelOverride?.provider ?? lookupProvider;
|
|
211
|
-
const credentials =
|
|
241
|
+
const credentials = opts.credentialsResolved && opts.credentials
|
|
242
|
+
? opts.credentials
|
|
243
|
+
: await resolveRecipeCredentials({
|
|
244
|
+
provider: credentialProvider,
|
|
245
|
+
env,
|
|
246
|
+
...(opts.modelOverride ? { model: opts.modelOverride } : {}),
|
|
247
|
+
...(opts.credentials ? { credentials: opts.credentials } : {}),
|
|
248
|
+
});
|
|
212
249
|
const modelRuntime = await ModelRuntime.create({ credentials, modelsPath: null });
|
|
213
|
-
|
|
214
|
-
modelRuntime.getModel(lookupProvider, modelId) ??
|
|
215
|
-
getModel(lookupProvider, modelId);
|
|
216
|
-
if (!model) {
|
|
217
|
-
throw new RecipeModelError(modelSpec);
|
|
218
|
-
}
|
|
219
|
-
applyRecipeAgentModelConfigToModel(model, recipe.modelConfig);
|
|
220
|
-
const mcp = await configureSessionMcp(recipe, cwd, env, opts, true);
|
|
250
|
+
let model;
|
|
221
251
|
let session;
|
|
222
|
-
let
|
|
252
|
+
let agentRuns;
|
|
223
253
|
let unsubscribe;
|
|
224
254
|
let detachInstrumentation;
|
|
255
|
+
const mcp = await configureSessionMcp(recipe, cwd, env, opts, {
|
|
256
|
+
getActiveTools: () => session?.getActiveToolNames() ?? [],
|
|
257
|
+
setActiveTools: (names) => session?.setActiveToolsByName(names),
|
|
258
|
+
});
|
|
225
259
|
const cleanup = async () => {
|
|
226
260
|
try {
|
|
227
261
|
unsubscribe?.();
|
|
@@ -230,13 +264,9 @@ export async function createRecipeSession(opts) {
|
|
|
230
264
|
// Continue releasing the remaining session-owned resources.
|
|
231
265
|
}
|
|
232
266
|
unsubscribe = undefined;
|
|
233
|
-
if (
|
|
267
|
+
if (agentRuns) {
|
|
234
268
|
try {
|
|
235
|
-
|
|
236
|
-
if (run.status !== "closed") {
|
|
237
|
-
await runs.close(run.agent_run_id).catch(() => { });
|
|
238
|
-
}
|
|
239
|
-
}
|
|
269
|
+
await agentRuns.shutdown();
|
|
240
270
|
}
|
|
241
271
|
catch {
|
|
242
272
|
// Child teardown is best-effort; the session still disposes.
|
|
@@ -270,83 +300,182 @@ export async function createRecipeSession(opts) {
|
|
|
270
300
|
// Recipe extensions load through the shared jiti loader; host extensions
|
|
271
301
|
// append after them, matching the Pi extension host's ordering.
|
|
272
302
|
const inlineExtensions = [];
|
|
303
|
+
const recipeRegistrations = createRecipeExtensionRegistrationRegistry();
|
|
304
|
+
for (const toolName of [
|
|
305
|
+
"read",
|
|
306
|
+
"bash",
|
|
307
|
+
"edit",
|
|
308
|
+
"write",
|
|
309
|
+
"grep",
|
|
310
|
+
"find",
|
|
311
|
+
"ls",
|
|
312
|
+
...(opts.customTools ?? []).map((tool) => tool.name),
|
|
313
|
+
...(recipe.subagents.size > 0 && opts.runController !== null
|
|
314
|
+
? ["agent"]
|
|
315
|
+
: []),
|
|
316
|
+
]) {
|
|
317
|
+
recipeRegistrations.claim("tool", toolName, "<host>");
|
|
318
|
+
}
|
|
273
319
|
for (const extensionPath of recipe.extensionPaths) {
|
|
274
|
-
inlineExtensions.push(await loadRecipeExtensionFactory(recipe.recipeDir, extensionPath)
|
|
320
|
+
inlineExtensions.push(bindRecipeExtensionFactory(await loadRecipeExtensionFactory(recipe.recipeDir, extensionPath), recipeExtensionContext, recipeRegistrations, extensionPath, recipeExtensionToolAllowlist(recipe.tools, recipe.subagents.size > 0 && opts.runController !== null, [
|
|
321
|
+
...(mcp.tools?.map((tool) => tool.name) ?? []),
|
|
322
|
+
...(mcp.searchToolName ? [mcp.searchToolName] : []),
|
|
323
|
+
])));
|
|
275
324
|
}
|
|
276
325
|
inlineExtensions.push(...(opts.extensionFactories ?? []));
|
|
326
|
+
const settingsManager = opts.settingsManager ?? SettingsManager.create(cwd, recipe.recipeDir);
|
|
277
327
|
const services = await createAgentSessionServices({
|
|
278
328
|
cwd,
|
|
279
329
|
agentDir: recipe.recipeDir,
|
|
280
330
|
modelRuntime,
|
|
281
|
-
settingsManager
|
|
331
|
+
settingsManager,
|
|
282
332
|
resourceLoaderOptions: {
|
|
283
333
|
eventBus: opts.eventBus,
|
|
334
|
+
noExtensions: true,
|
|
284
335
|
noSkills: true,
|
|
336
|
+
noPromptTemplates: true,
|
|
337
|
+
noContextFiles: true,
|
|
285
338
|
additionalSkillPaths: [
|
|
286
|
-
...(opts.
|
|
339
|
+
...(opts.materializedSkillPaths ?? recipe.skillPaths),
|
|
287
340
|
...(opts.additionalSkillPaths ?? []),
|
|
288
341
|
],
|
|
289
|
-
additionalPromptTemplatePaths: recipe.promptPaths,
|
|
342
|
+
additionalPromptTemplatePaths: [...recipe.promptPaths],
|
|
290
343
|
extensionFactories: inlineExtensions,
|
|
291
344
|
systemPromptOverride: (base) => {
|
|
292
345
|
const resolved = recipe.systemPromptOverride(base);
|
|
293
|
-
return opts.
|
|
346
|
+
return opts.transformSystemPrompt
|
|
347
|
+
? opts.transformSystemPrompt(resolved ?? "")
|
|
348
|
+
: resolved;
|
|
294
349
|
},
|
|
295
350
|
},
|
|
296
351
|
});
|
|
297
352
|
opts.onDiagnostics?.(services.diagnostics);
|
|
353
|
+
const extensionLoadErrors = services.resourceLoader.getExtensions().errors;
|
|
354
|
+
const fatalDiagnostics = services.diagnostics.filter((diagnostic) => diagnostic.type === "error");
|
|
355
|
+
if (fatalDiagnostics.length > 0 || extensionLoadErrors.length > 0) {
|
|
356
|
+
throw new Error(`Recipe extension startup failed:\n${[
|
|
357
|
+
...extensionLoadErrors.map(({ path, error }) => `- ${path}: ${error}`),
|
|
358
|
+
...fatalDiagnostics.map((diagnostic) => `- ${diagnostic.message}`),
|
|
359
|
+
]
|
|
360
|
+
.join("\n")}`);
|
|
361
|
+
}
|
|
362
|
+
const selectedModel = opts.modelOverride ??
|
|
363
|
+
services.modelRuntime.getModel(lookupProvider, modelId) ??
|
|
364
|
+
modelRuntime.getModel(lookupProvider, modelId) ??
|
|
365
|
+
getModel(lookupProvider, modelId);
|
|
366
|
+
if (!selectedModel) {
|
|
367
|
+
throw new RecipeModelError(modelSpec);
|
|
368
|
+
}
|
|
369
|
+
model = cloneModelForRecipe(selectedModel);
|
|
370
|
+
applyRecipeAgentModelConfigToModel(model, recipe.modelConfig);
|
|
298
371
|
// Subagents: the shared `agent` tool against an injected or in-process
|
|
299
372
|
// controller. `runController: null` disables delegation outright.
|
|
300
373
|
const wantsSubagents = recipe.subagents.size > 0 && opts.runController !== null;
|
|
301
374
|
if (opts.runController) {
|
|
302
|
-
|
|
375
|
+
agentRuns = opts.runController;
|
|
303
376
|
}
|
|
304
377
|
else {
|
|
305
378
|
const { createInProcessRunController, inertRunController } = await import("./run-controller.js");
|
|
306
|
-
|
|
379
|
+
agentRuns = wantsSubagents
|
|
307
380
|
? createInProcessRunController({
|
|
308
|
-
|
|
381
|
+
recipe: opts.recipe,
|
|
309
382
|
cwd,
|
|
310
383
|
env,
|
|
311
384
|
...(opts.credentials ? { credentials: opts.credentials } : {}),
|
|
312
|
-
concurrency: opts.
|
|
385
|
+
concurrency: opts.inProcessRunController?.concurrency,
|
|
313
386
|
...(otel ? { otel } : {}),
|
|
314
387
|
})
|
|
315
388
|
: inertRunController();
|
|
316
389
|
}
|
|
317
|
-
const tools =
|
|
318
|
-
|
|
319
|
-
|
|
390
|
+
const tools = [
|
|
391
|
+
...recipe.tools,
|
|
392
|
+
...(wantsSubagents ? ["agent"] : []),
|
|
393
|
+
];
|
|
394
|
+
const mcpToolNames = mcp.tools?.map((tool) => tool.name) ?? [];
|
|
395
|
+
const recipeExtensionToolNames = new Set(services.resourceLoader
|
|
396
|
+
.getExtensions()
|
|
397
|
+
.extensions.flatMap((extension) => [...extension.tools.keys()]));
|
|
398
|
+
const occupiedToolNames = new Set([
|
|
399
|
+
...tools,
|
|
400
|
+
...(opts.customTools ?? []).map((tool) => tool.name),
|
|
401
|
+
...(wantsSubagents ? ["agent"] : []),
|
|
402
|
+
]);
|
|
403
|
+
const collisions = mcpToolNames.filter((name) => occupiedToolNames.has(name) || recipeExtensionToolNames.has(name));
|
|
404
|
+
if (collisions.length > 0) {
|
|
405
|
+
throw new Error(`Recipe MCP tool name collision: ${collisions.join(", ")}`);
|
|
406
|
+
}
|
|
407
|
+
const selectedToolNames = [...tools, ...mcpToolNames];
|
|
408
|
+
const environmentBash = (recipe.mcp?.mode ?? "cli") === "cli" &&
|
|
409
|
+
mcp.available &&
|
|
410
|
+
env !== process.env &&
|
|
411
|
+
tools.includes("bash") &&
|
|
412
|
+
!(opts.customTools ?? []).some((tool) => tool.name === "bash")
|
|
413
|
+
? createBashToolDefinition(cwd, {
|
|
414
|
+
commandPrefix: settingsManager.getShellCommandPrefix(),
|
|
415
|
+
shellPath: settingsManager.getShellPath(),
|
|
416
|
+
spawnHook: (context) => ({
|
|
417
|
+
...context,
|
|
418
|
+
env: { ...context.env, ...env },
|
|
419
|
+
}),
|
|
420
|
+
})
|
|
421
|
+
: undefined;
|
|
320
422
|
const customTools = [
|
|
423
|
+
...(environmentBash ? [environmentBash] : []),
|
|
321
424
|
...(opts.customTools ?? []),
|
|
322
425
|
...(wantsSubagents
|
|
323
|
-
? [
|
|
426
|
+
? [
|
|
427
|
+
createAgentTool(agentRuns, recipe.subagents, opts.agentToolOptions),
|
|
428
|
+
]
|
|
324
429
|
: []),
|
|
430
|
+
...(mcp.tools ?? []),
|
|
325
431
|
];
|
|
326
432
|
const created = await createAgentSessionFromServices({
|
|
327
433
|
services,
|
|
328
434
|
sessionManager: opts.sessionManager ?? SessionManager.inMemory(cwd),
|
|
329
435
|
model,
|
|
330
|
-
...(
|
|
331
|
-
? { thinkingLevel:
|
|
436
|
+
...(recipe.thinkingLevel
|
|
437
|
+
? { thinkingLevel: recipe.thinkingLevel }
|
|
332
438
|
: {}),
|
|
333
|
-
tools,
|
|
439
|
+
tools: selectedToolNames,
|
|
334
440
|
customTools,
|
|
335
441
|
});
|
|
336
442
|
session = created.session;
|
|
443
|
+
normalizeSessionToolsForModel(session, model);
|
|
337
444
|
applyRecipeAgentModelConfigToSession(session, recipe.modelConfig);
|
|
338
445
|
await session.bindExtensions({});
|
|
446
|
+
const registered = new Set(session.getAllTools().map((tool) => tool.name));
|
|
447
|
+
const missingDeclaredTools = selectedToolNames.filter((name) => !registered.has(name));
|
|
448
|
+
if (missingDeclaredTools.length > 0) {
|
|
449
|
+
throw new Error(`Recipe agent "${recipe.name}" declares unavailable tool(s): ${missingDeclaredTools.join(", ")}`);
|
|
450
|
+
}
|
|
451
|
+
if (mcp.tools) {
|
|
452
|
+
const missingRegistered = mcpToolNames.filter((name) => !registered.has(name));
|
|
453
|
+
if (missingRegistered.length > 0) {
|
|
454
|
+
throw new Error(`Pi did not register Recipe MCP tool(s): ${missingRegistered.join(", ")}`);
|
|
455
|
+
}
|
|
456
|
+
const activeTools = [
|
|
457
|
+
...tools,
|
|
458
|
+
...(mcp.initialActiveToolNames ?? []),
|
|
459
|
+
...(mcp.searchToolName ? [mcp.searchToolName] : []),
|
|
460
|
+
];
|
|
461
|
+
session.setActiveToolsByName(activeTools);
|
|
462
|
+
const applied = new Set(session.getActiveToolNames());
|
|
463
|
+
const missing = activeTools.filter((name) => !applied.has(name));
|
|
464
|
+
if (missing.length > 0) {
|
|
465
|
+
throw new Error(`Pi did not activate Recipe tool(s): ${missing.join(", ")}`);
|
|
466
|
+
}
|
|
467
|
+
}
|
|
339
468
|
unsubscribe = opts.onEvent ? session.subscribe(opts.onEvent) : undefined;
|
|
340
469
|
detachInstrumentation = otel
|
|
341
470
|
? instrumentSession(session, otel).detach
|
|
342
471
|
: undefined;
|
|
343
472
|
const liveSession = session;
|
|
344
|
-
const liveRuns =
|
|
473
|
+
const liveRuns = agentRuns;
|
|
345
474
|
let disposed = false;
|
|
346
475
|
return {
|
|
347
476
|
session: liveSession,
|
|
348
|
-
recipe,
|
|
349
|
-
|
|
477
|
+
agent: recipe,
|
|
478
|
+
agentRuns: liveRuns,
|
|
350
479
|
async dispose() {
|
|
351
480
|
if (disposed)
|
|
352
481
|
return;
|
|
@@ -360,4 +489,14 @@ export async function createRecipeSession(opts) {
|
|
|
360
489
|
throw error;
|
|
361
490
|
}
|
|
362
491
|
}
|
|
492
|
+
export async function createAgentSession(opts) {
|
|
493
|
+
return createSessionForAgent(opts.recipe.selectAgent(opts.agentName), {
|
|
494
|
+
...opts,
|
|
495
|
+
sessionRole: "root",
|
|
496
|
+
});
|
|
497
|
+
}
|
|
498
|
+
/** @internal Construct a child with Recipes-owned lifecycle state. */
|
|
499
|
+
export async function createAgentSessionInternal(opts) {
|
|
500
|
+
return createSessionForAgent(opts.recipe.selectAgent(opts.agentName), opts);
|
|
501
|
+
}
|
|
363
502
|
//# sourceMappingURL=session.js.map
|