{"version":3,"file":"runtime.d.ts","sourceRoot":"","sources":["../../src/bundle/runtime.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,SAAS,EAAiB,MAAM,yBAAyB,CAAC;AACxE,OAAO,EAUN,KAAK,gBAAgB,EACrB,KAAK,iBAAiB,EAGtB,MAAM,2BAA2B,CAAC;AAOnC,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,wCAAwC,CAAC;AAChF,OAAO,KAAK,EAAkC,oBAAoB,EAAE,MAAM,uCAAuC,CAAC;AAgDlH,OAAO,KAAK,EAAE,cAAc,EAAiE,MAAM,aAAa,CAAC;AAIjH,OAAO,EACN,KAAK,uBAAuB,EAI5B,MAAM,sBAAsB,CAAC;AAG9B,OAAO,EAAE,uBAAuB,EAAE,eAAe,EAAE,mBAAmB,EAAE,MAAM,mBAAmB,CAAC;AAelG;;;;;;GAMG;AACH,eAAO,MAAM,8BAA8B,EAAE,SAAS,MAAM,EAU3D,CAAC;AA8BF,MAAM,MAAM,6BAA6B,GAAG,QAAQ,GAAG,SAAS,GAAG,QAAQ,GAAG,SAAS,CAAC;AAExF,MAAM,WAAW,oBAAoB;IACpC,IAAI,EAAE,MAAM,CAAC;IACb,OAAO,EAAE,MAAM,CAAC;IAChB,SAAS,EAAE,6BAA6B,CAAC;CACzC;AAED,MAAM,WAAW,aAAa;IAC7B,MAAM,EAAE,cAAc,CAAC;IACvB,kBAAkB,EAAE,MAAM,CAAC;IAC3B,QAAQ,EAAE,SAAS,oBAAoB,EAAE,CAAC;IAC1C,gBAAgB,EAAE,uBAAuB,CAAC;IAC1C,cAAc,CAAC,EAAE,MAAM,CAAC;IACxB,YAAY,CAAC,EAAE,MAAM,EAAE,CAAC;CACxB;AAsBD,wBAAgB,yBAAyB,CACxC,OAAO,EAAE,aAAa,EACtB,aAAa,GAAE,WAAW,CAAC,MAAM,CAAa,GAC5C,MAAM,CAER;AAkBD,wBAAgB,0BAA0B,CACzC,OAAO,EAAE,SAAS,OAAO,EAAE,EAC3B,SAAS,EAAE,MAAM,EACjB,MAAM,EAAE,iBAAiB,CAAC,QAAQ,CAAC,GACjC,MAAM,GAAG,SAAS,CASpB;AAcD,wBAAsB,mBAAmB,CAAC,MAAM,EAAE,cAAc,GAAG,OAAO,CAAC,aAAa,CAAC,CA+CxF;AAED,wBAAgB,0BAA0B,CAAC,YAAY,EAAE,MAAM,EAAE,WAAW,EAAE,MAAM,GAAG,MAAM,CAK5F;AA2BD,MAAM,WAAW,uBAAuB;IACvC,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,gBAAgB,CAAC,EAAE,OAAO,CAAC;IAC3B,2EAA2E;IAC3E,eAAe,CAAC,EAAE,SAAS,SAAS,EAAE,CAAC;IACvC,gDAAgD;IAChD,sBAAsB,CAAC,EAAE,MAAM,CAAC;IAChC,mEAAmE;IACnE,kBAAkB,CAAC,EAAE,MAAM,CAAC;IAC5B;;;;OAIG;IACH,kBAAkB,CAAC,EAAE,OAAO,CAAC,MAAM,CAAC,iBAAiB,EAAE,oBAAoB,CAAC,CAAC,CAAC;CAC9E;AAgKD,wBAAgB,4BAA4B,CAAC,OAAO,GAAE,uBAA4B,GAAG,gBAAgB,CAo1BpG","sourcesContent":["import { readdir, readFile } from \"node:fs/promises\";\nimport { join } from \"node:path\";\nimport type { AgentTool, ThinkingLevel } from \"@ch1nyzzz/pi-agent-core\";\nimport {\n\tconvertToLlm,\n\tcreateBashToolDefinition,\n\tcreateEditToolDefinition,\n\tcreateFindToolDefinition,\n\tcreateGrepToolDefinition,\n\tcreateLsToolDefinition,\n\tcreateReadToolDefinition,\n\tcreateWriteToolDefinition,\n\ttype ExtensionContext,\n\ttype ExtensionFactory,\n\ttype SessionStartEvent,\n\tserializeConversation,\n\ttype ToolDefinition,\n} from \"@ch1nyzzz/pi-coding-agent\";\nimport { Type } from \"typebox\";\nimport { type LoadedEvoComponentArtifact, validateEvoComponentSelection } from \"../components/artifact.ts\";\nimport { EvoCapabilityBroker } from \"../components/capabilities/broker.ts\";\nimport { createFileCapabilityServices } from \"../components/capabilities/host-services.ts\";\nimport { createInferCapabilityService, createModelRegistryInferHost } from \"../components/capabilities/infer.ts\";\nimport { createMemoryCapabilityServices } from \"../components/capabilities/memory.ts\";\nimport type { EvoCapabilityName } from \"../components/capabilities/protocol.ts\";\nimport type { EvoCapabilityComponentIdentity, EvoCapabilityService } from \"../components/capabilities/service.ts\";\nimport { createSpawnAgentCapabilityService } from \"../components/capabilities/spawn-agent.ts\";\nimport { createModelRegistrySpawnAgentHost } from \"../components/capabilities/spawn-agent-host.ts\";\nimport { type EvoMemoryNamespace, EvoMemoryStore, parseEvoMemoryFragmentInput } from \"../components/memory/store.ts\";\nimport {\n\tcanUseEvoComponentSandbox,\n\ttype EvoComponentCapabilityBroker,\n\tEvoComponentProcess,\n\ttype EvoComponentProcessOptions,\n} from \"../components/process-runtime.ts\";\nimport {\n\tCOMPACTION_V1_ABI,\n\tCONTEXT_V1_ABI,\n\tCONTROL_V1_ABI,\n\ttype CompactionV1Config,\n\ttype CompactionV1Input,\n\ttype CompactionV1Output,\n\ttype ContextV1Config,\n\ttype ContextV1Input,\n\ttype ContextV1Output,\n\ttype ControlV1Input,\n\ttype ControlV1Output,\n\tcreateDefaultEvoAbiRegistry,\n\ttype EvoAbiDefinition,\n\tGENERATION_V1_ABI,\n\ttype GenerationV1Input,\n\ttype GenerationV1Output,\n\tGUARD_V1_ABI,\n\ttype GuardV1Input,\n\ttype GuardV1Output,\n\tINSTRUCTIONS_V1_ABI,\n\ttype InstructionsV1Input,\n\ttype InstructionsV1Output,\n\tMEMORY_V1_ABI,\n\ttype MemoryV1Input,\n\ttype MemoryV1Output,\n\tTOOL_V1_ABI,\n\ttype ToolV1Input,\n\ttype ToolV1Output,\n\tWORKFLOW_V1_ABI,\n\ttype WorkflowV1Input,\n\ttype WorkflowV1Output,\n} from \"../components/registry.ts\";\nimport { createEvolutionResearchTools } from \"../evolve/research-tools.ts\";\nimport { renderBundlePreferenceInstructions } from \"../memory/preferences.ts\";\nimport { getEvoPaths } from \"../paths.ts\";\nimport { BundleRegistry } from \"../registry/registry.ts\";\nimport { canonicalJson } from \"../storage.ts\";\nimport type { CompiledBundle, EvoComponentSelection, EvoToolSelection, EvoWorkflowSelection } from \"../types.ts\";\nimport { filterEvoCodeFeatureTools } from \"./code-feature.ts\";\nimport { loadCompiledBundle } from \"./compile.ts\";\nimport { activateEvoFeatureSession } from \"./feature-gate.ts\";\nimport {\n\ttype ManagedRuntimeResources,\n\tprepareManagedRuntimeResources,\n\treplaceManagedHostResources,\n\tverifyManagedSourceSnapshots,\n} from \"./managed-sources.ts\";\nimport { isDigest } from \"./schema.ts\";\n\nexport { createEvoFeatureHandler, guardEvoFeature, isEvoFeatureEnabled } from \"./feature-gate.ts\";\n\nconst BUNDLE_BEGIN = \"<!-- evo-pi bundle begin -->\";\nconst BUNDLE_END = \"<!-- evo-pi bundle end -->\";\nconst EVO_TOOL_PARAMETERS = Type.Record(Type.String(), Type.Unknown());\nconst DEFAULT_SPAWN_AGENT_SYSTEM_PROMPT =\n\t\"You are an isolated child agent. Complete the requested task using only explicitly provided tools.\";\nconst DEFAULT_SPAWN_AGENT_MAX_TURNS = 64;\n/**\n * A workflow invoke spans an entire orchestration (potentially dozens of\n * sequential child-agent rounds), so it gets a far larger request timeout\n * than the single-transform invokes of the other ABIs.\n */\nconst WORKFLOW_INVOKE_TIMEOUT_MS = 60 * 60_000;\n\n/**\n * Tool names offered to spawned child agents when the embedder does not supply\n * its own trusted tool set. Grant previews default their spawn-agent allowlist\n * to this same list so imported packs work against the default host. The two\n * research tools give retrieval-heavy workflows (deep-research) allowlisted\n * public search/fetch without credentials.\n */\nexport const DEFAULT_SPAWN_AGENT_TOOL_NAMES: readonly string[] = [\n\t\"bash\",\n\t\"edit\",\n\t\"evo_research_fetch\",\n\t\"evo_research_search\",\n\t\"find\",\n\t\"grep\",\n\t\"ls\",\n\t\"read\",\n\t\"write\",\n];\n\n/**\n * The host's standard coding tools plus the public research tools, rebuilt\n * against the session cwd. The `agent` tool is deliberately excluded: spawned\n * children must not recurse.\n */\nfunction createDefaultSpawnAgentTools(cwd: string): AgentTool[] {\n\tconst definitions: ToolDefinition<any, any>[] = [\n\t\tcreateBashToolDefinition(cwd),\n\t\tcreateEditToolDefinition(cwd),\n\t\tcreateFindToolDefinition(cwd),\n\t\tcreateGrepToolDefinition(cwd),\n\t\tcreateLsToolDefinition(cwd),\n\t\tcreateReadToolDefinition(cwd),\n\t\tcreateWriteToolDefinition(cwd),\n\t\t...createEvolutionResearchTools(),\n\t];\n\treturn definitions.map((definition) => ({\n\t\tname: definition.name,\n\t\tlabel: definition.label,\n\t\tdescription: definition.description,\n\t\tparameters: definition.parameters,\n\t\tprepareArguments: definition.prepareArguments,\n\t\texecutionMode: definition.executionMode,\n\t\texecute: (toolCallId, params, signal, onUpdate) =>\n\t\t\tdefinition.execute(toolCallId, params, signal, onUpdate, undefined as unknown as ExtensionContext),\n\t}));\n}\n\nexport type RuntimeBundleSectionPlacement = \"stable\" | \"regular\" | \"memory\" | \"dynamic\";\n\nexport interface RuntimeBundleSection {\n\tpath: string;\n\tcontent: string;\n\tplacement: RuntimeBundleSectionPlacement;\n}\n\nexport interface RuntimeBundle {\n\tbundle: CompiledBundle;\n\tsystemPromptAppend: string;\n\tsections: readonly RuntimeBundleSection[];\n\tmanagedResources: ManagedRuntimeResources;\n\tskillDirectory?: string;\n\tenabledTools?: string[];\n}\n\nfunction renderRuntimeBundleSections(\n\tbundle: CompiledBundle,\n\tsections: readonly RuntimeBundleSection[],\n\texcludedPaths: ReadonlySet<string>,\n): string {\n\tconst content = (placement: RuntimeBundleSectionPlacement): string[] =>\n\t\tsections\n\t\t\t.filter((section) => section.placement === placement && !excludedPaths.has(section.path))\n\t\t\t.map((section) => section.content);\n\treturn [\n\t\tBUNDLE_BEGIN,\n\t\t...content(\"stable\"),\n\t\t`Bundle: ${bundle.digest}`,\n\t\t...content(\"regular\"),\n\t\t...content(\"memory\"),\n\t\t...content(\"dynamic\"),\n\t\tBUNDLE_END,\n\t].join(\"\\n\\n\");\n}\n\nexport function renderRuntimeBundlePrompt(\n\truntime: RuntimeBundle,\n\texcludedPaths: ReadonlySet<string> = new Set(),\n): string {\n\treturn renderRuntimeBundleSections(runtime.bundle, runtime.sections, excludedPaths);\n}\n\nfunction isRecord(value: unknown): value is Record<string, unknown> {\n\treturn typeof value === \"object\" && value !== null;\n}\n\nfunction parseBundleEntry(entry: unknown): { digest: string; sessionId?: string } | undefined {\n\tif (!isRecord(entry) || entry.type !== \"custom\" || entry.customType !== \"evo.bundle\" || !isRecord(entry.data)) {\n\t\treturn undefined;\n\t}\n\tif (typeof entry.data.digest !== \"string\" || !isDigest(entry.data.digest)) return undefined;\n\tif (\"sessionId\" in entry.data && typeof entry.data.sessionId !== \"string\") return undefined;\n\treturn {\n\t\tdigest: entry.data.digest,\n\t\tsessionId: typeof entry.data.sessionId === \"string\" ? entry.data.sessionId : undefined,\n\t};\n}\n\nexport function resolveSessionBundleDigest(\n\tentries: readonly unknown[],\n\tsessionId: string,\n\treason: SessionStartEvent[\"reason\"],\n): string | undefined {\n\tlet legacyDigest: string | undefined;\n\tfor (let index = entries.length - 1; index >= 0; index--) {\n\t\tconst bundleEntry = parseBundleEntry(entries[index]);\n\t\tif (!bundleEntry) continue;\n\t\tif (bundleEntry.sessionId === sessionId) return bundleEntry.digest;\n\t\tif (bundleEntry.sessionId === undefined && legacyDigest === undefined) legacyDigest = bundleEntry.digest;\n\t}\n\treturn reason === \"startup\" || reason === \"resume\" || reason === \"reload\" ? legacyDigest : undefined;\n}\n\nasync function listMarkdown(directory: string): Promise<string[]> {\n\ttry {\n\t\treturn (await readdir(directory, { withFileTypes: true }))\n\t\t\t.filter((entry) => entry.isFile() && entry.name.endsWith(\".md\"))\n\t\t\t.map((entry) => entry.name)\n\t\t\t.sort();\n\t} catch (error) {\n\t\tif (typeof error === \"object\" && error !== null && \"code\" in error && error.code === \"ENOENT\") return [];\n\t\tthrow error;\n\t}\n}\n\nexport async function renderRuntimeBundle(bundle: CompiledBundle): Promise<RuntimeBundle> {\n\tconst promptFiles = await listMarkdown(join(bundle.directory, \"prompts\"));\n\tconst orderedPaths = [\n\t\t...(bundle.policy.promptOrder ?? []),\n\t\t...promptFiles.map((file) => `prompts/${file}`).filter((path) => !bundle.policy.promptOrder?.includes(path)),\n\t];\n\tconst stablePaths = new Set(bundle.policy.stablePromptPaths ?? []);\n\tconst dynamicPaths = new Set(bundle.policy.dynamicPromptPaths ?? []);\n\tconst sections: RuntimeBundleSection[] = [];\n\tfor (const path of orderedPaths) {\n\t\tconst content = (await readFile(join(bundle.directory, path), \"utf8\")).trim();\n\t\tif (!content) continue;\n\t\tconst placement: RuntimeBundleSectionPlacement = stablePaths.has(path)\n\t\t\t? \"stable\"\n\t\t\t: dynamicPaths.has(path)\n\t\t\t\t? \"dynamic\"\n\t\t\t\t: \"regular\";\n\t\tsections.push({ path, content, placement });\n\t}\n\tconst preferenceInstructions = await renderBundlePreferenceInstructions(bundle);\n\tif (preferenceInstructions) {\n\t\tsections.push({\n\t\t\tpath: \"memory/preferences.json\",\n\t\t\tcontent: preferenceInstructions,\n\t\t\tplacement: \"memory\",\n\t\t});\n\t}\n\tfor (const file of await listMarkdown(join(bundle.directory, \"memory\"))) {\n\t\tconst content = (await readFile(join(bundle.directory, \"memory\", file), \"utf8\")).trim();\n\t\tif (!content) continue;\n\t\tsections.push({\n\t\t\tpath: `memory/${file}`,\n\t\t\tcontent: `## Remembered user context\\n\\n${content}`,\n\t\t\tplacement: \"memory\",\n\t\t});\n\t}\n\tconst skillDirectory = bundle.manifest.files.some((file) => file.path.startsWith(\"skills/\"))\n\t\t? join(bundle.directory, \"skills\")\n\t\t: undefined;\n\treturn {\n\t\tbundle,\n\t\tsystemPromptAppend: renderRuntimeBundleSections(bundle, sections, new Set()),\n\t\tsections,\n\t\tmanagedResources: await prepareManagedRuntimeResources(bundle),\n\t\tskillDirectory,\n\t\tenabledTools: bundle.policy.enabledTools,\n\t};\n}\n\nexport function replaceRuntimeBundlePrompt(systemPrompt: string, replacement: string): string {\n\tconst start = systemPrompt.indexOf(BUNDLE_BEGIN);\n\tconst end = systemPrompt.indexOf(BUNDLE_END);\n\tif (start === -1 || end === -1 || end < start) return `${systemPrompt}\\n\\n${replacement}`;\n\treturn `${systemPrompt.slice(0, start)}${replacement}${systemPrompt.slice(end + BUNDLE_END.length)}`;\n}\n\nfunction resolveWorkerModel(ctx: ExtensionContext, route: string): NonNullable<ExtensionContext[\"model\"]> {\n\tconst separator = route.indexOf(\"/\");\n\tif (separator !== -1) {\n\t\tconst provider = route.slice(0, separator);\n\t\tconst modelId = route.slice(separator + 1);\n\t\tconst model = ctx.modelRegistry.find(provider, modelId);\n\t\tif (!model) throw new Error(`Evo-Pi worker model does not exist: ${route}`);\n\t\treturn model;\n\t}\n\tconst matches = ctx.modelRegistry.getAll().filter((model) => model.id === route);\n\tif (matches.length === 0) throw new Error(`Evo-Pi worker model does not exist: ${route}`);\n\tif (matches.length > 1) {\n\t\tthrow new Error(`Evo-Pi worker model id is ambiguous: ${route}`);\n\t}\n\treturn matches[0];\n}\n\ninterface PreparedRuntimeComponent<TInput, TOutput, TConfig> {\n\tartifact: LoadedEvoComponentArtifact;\n\tabi: EvoAbiDefinition<TInput, TOutput, TConfig>;\n\tconfig: TConfig;\n\tprocessOptions: EvoComponentProcessOptions;\n\tmemoryNamespace?: EvoMemoryNamespace;\n}\n\nexport interface EvoPolicyRuntimeOptions {\n\troot?: string;\n\tcomponentSandbox?: boolean;\n\t/** Trusted, pre-constructed tools available to isolated spawned agents. */\n\tspawnAgentTools?: readonly AgentTool[];\n\t/** Fixed prompt for isolated spawned agents. */\n\tspawnAgentSystemPrompt?: string;\n\t/** Hard provider-turn limit for one isolated spawned-agent run. */\n\tspawnAgentMaxTurns?: number;\n\t/**\n\t * Trusted host adapters supplied by the embedding extension. Built-in\n\t * workspace file, infer, spawn-agent, and component-memory services are\n\t * merged around these adapters; memory adapters cannot be replaced.\n\t */\n\tcapabilityServices?: Partial<Record<EvoCapabilityName, EvoCapabilityService>>;\n}\n\nfunction isSupportedAgentMessage(value: unknown): boolean {\n\tif (!isRecord(value) || typeof value.role !== \"string\") return false;\n\treturn [\"user\", \"assistant\", \"toolResult\", \"bashExecution\", \"custom\", \"branchSummary\", \"compactionSummary\"].includes(\n\t\tvalue.role,\n\t);\n}\n\nfunction resolveThinkingLevel(value: string): ThinkingLevel {\n\tswitch (value) {\n\t\tcase \"off\":\n\t\tcase \"minimal\":\n\t\tcase \"low\":\n\t\tcase \"medium\":\n\t\tcase \"high\":\n\t\tcase \"xhigh\":\n\t\tcase \"max\":\n\t\t\treturn value;\n\t\tdefault:\n\t\t\tthrow new Error(`Unsupported reasoning level: ${value}`);\n\t}\n}\n\nfunction componentIdentity(\n\tartifact: LoadedEvoComponentArtifact,\n\tabi: { capabilityCeiling: readonly string[] },\n): EvoCapabilityComponentIdentity {\n\treturn {\n\t\tid: artifact.manifest.id,\n\t\tabi: artifact.manifest.abi,\n\t\tartifactDigest: artifact.manifest.artifactDigest,\n\t\tdeclaredCapabilities: artifact.manifest.capabilities,\n\t\tabiCapabilityCeiling: abi.capabilityCeiling,\n\t};\n}\n\nconst MEMORY_NAMESPACE_CAPABILITIES = new Set<EvoCapabilityName>([\"memory-read\", \"memory-write\", \"retrieve\"]);\n\nfunction persistedGrantCapabilities(selection: EvoComponentSelection): Set<EvoCapabilityName> {\n\treturn new Set((selection.grants ?? []).map((grant) => grant.capability));\n}\n\nfunction usesGrantedComponentMemory(surface: string, selection: EvoComponentSelection): boolean {\n\tconst granted = persistedGrantCapabilities(selection);\n\tif (surface === \"memory\" && (!granted.has(\"memory-read\") || !granted.has(\"memory-write\"))) {\n\t\tthrow new Error(\"memory/v1 requires persisted memory-read and memory-write grants for its full lifecycle\");\n\t}\n\treturn [...granted].some((capability) => MEMORY_NAMESPACE_CAPABILITIES.has(capability));\n}\n\nasync function prepareMemoryNamespace(\n\tpaths: ReturnType<typeof getEvoPaths>,\n\tregistry: BundleRegistry,\n\tbundle: CompiledBundle,\n\tartifact: LoadedEvoComponentArtifact,\n): Promise<EvoMemoryNamespace> {\n\tconst store = new EvoMemoryStore({\n\t\tpaths,\n\t\tcomponentId: artifact.manifest.id,\n\t\tartifactDigest: artifact.manifest.artifactDigest,\n\t});\n\treturn registry.withMemoryLifecycle(async ({ stableDigest, trial, verifiedBundleLineage }) => {\n\t\tif (stableDigest !== bundle.digest) {\n\t\t\tthrow new Error(`Bundle ${bundle.digest} is no longer active while preparing component memory`);\n\t\t}\n\t\tif (verifiedBundleLineage[0] !== bundle.digest) {\n\t\t\tthrow new Error(`Bundle ${bundle.digest} does not match the registry-verified active lineage`);\n\t\t}\n\t\tif (trial?.digest === bundle.digest) {\n\t\t\tif (verifiedBundleLineage[1] !== trial.parent) {\n\t\t\t\tthrow new Error(`Trial parent ${trial.parent} does not match the registry-verified active lineage`);\n\t\t\t}\n\t\t\tawait store.materializeStableForBundle({\n\t\t\t\ttargetBundleDigest: trial.parent,\n\t\t\t\ttargetAncestorBundleDigests: verifiedBundleLineage.slice(2),\n\t\t\t});\n\t\t\treturn store.beginTrial({ parentBundleDigest: trial.parent, trialBundleDigest: bundle.digest });\n\t\t}\n\t\treturn store.materializeStableForBundle({\n\t\t\ttargetBundleDigest: bundle.digest,\n\t\t\ttargetAncestorBundleDigests: verifiedBundleLineage.slice(1),\n\t\t});\n\t});\n}\n\nasync function applyMemoryFragment(\n\tnamespace: EvoMemoryNamespace,\n\toperation: \"append\" | \"update\",\n\tvalue: unknown,\n\texpectedStateDigest?: string,\n): Promise<void> {\n\tconst fragment = parseEvoMemoryFragmentInput(value);\n\tif (operation === \"append\") await namespace.append(fragment, expectedStateDigest);\n\telse await namespace.update(fragment, expectedStateDigest);\n}\n\nasync function upsertMemoryFragments(\n\tnamespace: EvoMemoryNamespace,\n\tvalues: readonly Record<string, unknown>[],\n): Promise<void> {\n\tconst state = await namespace.read();\n\tconst known = new Set(state.fragments.map((fragment) => fragment.id));\n\tfor (const value of values) {\n\t\tconst fragment = parseEvoMemoryFragmentInput(value);\n\t\tif (known.has(fragment.id)) await namespace.update(fragment);\n\t\telse {\n\t\t\tawait namespace.append(fragment);\n\t\t\tknown.add(fragment.id);\n\t\t}\n\t}\n}\n\nasync function applyMemoryComponentOutput(namespace: EvoMemoryNamespace, output: MemoryV1Output): Promise<void> {\n\tif (output.mode === \"recall\") return;\n\tif (output.mode === \"encode\") {\n\t\tfor (const fragment of output.writes) await applyMemoryFragment(namespace, \"append\", fragment);\n\t\tfor (const fragment of output.updates) await applyMemoryFragment(namespace, \"update\", fragment);\n\t\tfor (const id of output.forgets) await namespace.forget(id);\n\t\treturn;\n\t}\n\tawait upsertMemoryFragments(namespace, [...output.merged, ...output.insights]);\n\tfor (const id of output.forget) await namespace.forget(id);\n}\n\nfunction requireExpectedStateDigest(value: unknown): string | undefined {\n\tif (value === undefined) return undefined;\n\tif (typeof value !== \"string\" || !isDigest(value)) {\n\t\tthrow new Error(\"control/v1 memory delta expectedStateDigest must be a sha256 digest\");\n\t}\n\treturn value;\n}\n\nasync function applyControlMemoryDeltas(\n\tnamespace: EvoMemoryNamespace,\n\tdeltas: readonly Record<string, unknown>[],\n): Promise<void> {\n\tfor (const [index, delta] of deltas.entries()) {\n\t\tconst label = `control/v1 memoryDeltas[${index}]`;\n\t\tconst operation = delta.operation;\n\t\tconst allowed =\n\t\t\toperation === \"forget\"\n\t\t\t\t? new Set([\"operation\", \"id\", \"expectedStateDigest\"])\n\t\t\t\t: new Set([\"operation\", \"fragment\", \"expectedStateDigest\"]);\n\t\tfor (const key of Object.keys(delta)) {\n\t\t\tif (!allowed.has(key)) throw new Error(`${label} has unknown key: ${key}`);\n\t\t}\n\t\tconst expectedStateDigest = requireExpectedStateDigest(delta.expectedStateDigest);\n\t\tif (operation === \"append\" || operation === \"update\") {\n\t\t\tawait applyMemoryFragment(namespace, operation, delta.fragment, expectedStateDigest);\n\t\t\tcontinue;\n\t\t}\n\t\tif (operation !== \"forget\") {\n\t\t\tthrow new Error(`${label}.operation must be 'append', 'update', or 'forget'`);\n\t\t}\n\t\tif (typeof delta.id !== \"string\") throw new Error(`${label}.id must be a string`);\n\t\tawait namespace.forget(delta.id, expectedStateDigest);\n\t}\n}\n\nexport function createPolicyRuntimeExtension(options: EvoPolicyRuntimeOptions = {}): ExtensionFactory {\n\tconst paths = getEvoPaths(options.root);\n\tconst registry = new BundleRegistry(paths);\n\treturn (pi) => {\n\t\tlet pinned: RuntimeBundle | undefined;\n\t\tlet activeToolsBeforeBundle: string[] | undefined;\n\t\tlet activeModelBeforeBundle: ExtensionContext[\"model\"];\n\t\tlet clearFeatureSession: (() => void) | undefined;\n\t\tlet compactionProcess: EvoComponentProcess<CompactionV1Input, CompactionV1Output, CompactionV1Config> | undefined;\n\t\tlet contextProcess: EvoComponentProcess<ContextV1Input, ContextV1Output, ContextV1Config> | undefined;\n\t\tlet guardProcess: EvoComponentProcess<GuardV1Input, GuardV1Output, Record<string, never>> | undefined;\n\t\tlet controlProcess: EvoComponentProcess<ControlV1Input, ControlV1Output, Record<string, never>> | undefined;\n\t\tlet controlMemoryNamespace: EvoMemoryNamespace | undefined;\n\t\tlet memoryProcess: EvoComponentProcess<MemoryV1Input, MemoryV1Output, Record<string, never>> | undefined;\n\t\tlet memoryNamespace: EvoMemoryNamespace | undefined;\n\t\tconst toolProcesses = new Map<string, EvoComponentProcess<ToolV1Input, ToolV1Output, Record<string, never>>>();\n\t\tconst workflowComponents = new Map<\n\t\t\tstring,\n\t\t\tPreparedRuntimeComponent<WorkflowV1Input, WorkflowV1Output, Record<string, never>>\n\t\t>();\n\t\tconst registeredEvoToolNames = new Set<string>();\n\t\tconst registeredEvoWorkflowCommands = new Set<string>();\n\t\tlet instructionsComponent:\n\t\t\t| PreparedRuntimeComponent<InstructionsV1Input, InstructionsV1Output, Record<string, never>>\n\t\t\t| undefined;\n\t\tlet generationComponent:\n\t\t\t| PreparedRuntimeComponent<GenerationV1Input, GenerationV1Output, Record<string, never>>\n\t\t\t| undefined;\n\t\tconst activeTurnProcesses = new Set<{ shutdown(): Promise<void> }>();\n\t\tlet guardInvocationTail = Promise.resolve();\n\t\tlet memoryInvocationTail = Promise.resolve();\n\n\t\tasync function stopComponentProcesses(): Promise<void> {\n\t\t\tconst processes = [\n\t\t\t\tcompactionProcess,\n\t\t\t\tcontextProcess,\n\t\t\t\tguardProcess,\n\t\t\t\tcontrolProcess,\n\t\t\t\tmemoryProcess,\n\t\t\t\t...toolProcesses.values(),\n\t\t\t\t...activeTurnProcesses,\n\t\t\t].filter((process): process is { shutdown(): Promise<void> } => process !== undefined);\n\t\t\tcompactionProcess = undefined;\n\t\t\tcontextProcess = undefined;\n\t\t\tguardProcess = undefined;\n\t\t\tcontrolProcess = undefined;\n\t\t\tcontrolMemoryNamespace = undefined;\n\t\t\tmemoryProcess = undefined;\n\t\t\tmemoryNamespace = undefined;\n\t\t\ttoolProcesses.clear();\n\t\t\tworkflowComponents.clear();\n\t\t\tinstructionsComponent = undefined;\n\t\t\tgenerationComponent = undefined;\n\t\t\tactiveTurnProcesses.clear();\n\t\t\tguardInvocationTail = Promise.resolve();\n\t\t\tmemoryInvocationTail = Promise.resolve();\n\t\t\tawait Promise.all(processes.map(async (process) => process.shutdown()));\n\t\t}\n\n\t\tasync function prepareComponent<TInput, TOutput, TConfig>(\n\t\t\tsurface: string,\n\t\t\tselection: EvoComponentSelection,\n\t\t\tabi: EvoAbiDefinition<TInput, TOutput, TConfig>,\n\t\t\tbundle: CompiledBundle,\n\t\t\tctx: ExtensionContext,\n\t\t): Promise<PreparedRuntimeComponent<TInput, TOutput, TConfig>> {\n\t\t\tconst abiRegistry = createDefaultEvoAbiRegistry();\n\t\t\tconst artifact = await validateEvoComponentSelection(paths, surface, selection, abiRegistry);\n\t\t\tconst config = abi.validateConfig(selection.config ?? {});\n\t\t\tlet sandboxOptions: Pick<EvoComponentProcessOptions, \"sandbox\"> = {};\n\t\t\tif (options.componentSandbox === false) {\n\t\t\t\tsandboxOptions = { sandbox: false };\n\t\t\t} else if (!(await canUseEvoComponentSandbox())) {\n\t\t\t\tif (!ctx.hasUI) {\n\t\t\t\t\tthrow new Error(\n\t\t\t\t\t\t\"Component sandbox is unavailable and direct execution requires one-time user permission\",\n\t\t\t\t\t);\n\t\t\t\t}\n\t\t\t\tconst allowDirect = await ctx.ui.confirm(\n\t\t\t\t\t\"One-time component permission\",\n\t\t\t\t\t`The OS sandbox is unavailable. Allow ${selection.id} (${selection.artifactDigest.slice(0, 12)}) to run directly with your user permissions for this session only?`,\n\t\t\t\t);\n\t\t\t\tif (!allowDirect) throw new Error(\"User declined one-time direct component execution\");\n\t\t\t\tsandboxOptions = { sandbox: false };\n\t\t\t}\n\t\t\tconst usesMemory = usesGrantedComponentMemory(surface, selection);\n\t\t\tconst componentMemory = usesMemory\n\t\t\t\t? await prepareMemoryNamespace(paths, registry, bundle, artifact)\n\t\t\t\t: undefined;\n\t\t\tconst services: Partial<Record<EvoCapabilityName, EvoCapabilityService>> = {\n\t\t\t\t...createFileCapabilityServices({\n\t\t\t\t\treadRoots: { workspace: ctx.cwd, bundle: bundle.directory },\n\t\t\t\t\twriteRoots: { workspace: ctx.cwd },\n\t\t\t\t}),\n\t\t\t\tinfer: createInferCapabilityService(createModelRegistryInferHost(ctx.modelRegistry)),\n\t\t\t\t\"spawn-agent\": createSpawnAgentCapabilityService(\n\t\t\t\t\tcreateModelRegistrySpawnAgentHost({\n\t\t\t\t\t\tmodelRegistry: ctx.modelRegistry,\n\t\t\t\t\t\ttools: options.spawnAgentTools ?? createDefaultSpawnAgentTools(ctx.cwd),\n\t\t\t\t\t\tsystemPrompt: options.spawnAgentSystemPrompt ?? DEFAULT_SPAWN_AGENT_SYSTEM_PROMPT,\n\t\t\t\t\t\tmaxTurns: options.spawnAgentMaxTurns ?? DEFAULT_SPAWN_AGENT_MAX_TURNS,\n\t\t\t\t\t}),\n\t\t\t\t),\n\t\t\t\t...options.capabilityServices,\n\t\t\t\t...(componentMemory ? createMemoryCapabilityServices(componentMemory) : {}),\n\t\t\t};\n\t\t\tconst capabilityBroker = new EvoCapabilityBroker({ paths, services });\n\t\t\tconst identity = componentIdentity(artifact, abi);\n\t\t\tconst authorityId = await capabilityBroker.replaceComponentGrants(identity, selection.grants ?? []);\n\t\t\tconst scopedCapabilityBroker: EvoComponentCapabilityBroker = {\n\t\t\t\trequest(component, frame, signal) {\n\t\t\t\t\treturn capabilityBroker.request(authorityId, component, frame, signal);\n\t\t\t\t},\n\t\t\t};\n\t\t\treturn {\n\t\t\t\tartifact,\n\t\t\t\tabi,\n\t\t\t\tconfig,\n\t\t\t\tprocessOptions: {\n\t\t\t\t\t...sandboxOptions,\n\t\t\t\t\tcapabilityBroker: scopedCapabilityBroker,\n\t\t\t\t\t...(surface === \"workflow\" ? { requestTimeoutMs: WORKFLOW_INVOKE_TIMEOUT_MS } : {}),\n\t\t\t\t},\n\t\t\t\t...(componentMemory ? { memoryNamespace: componentMemory } : {}),\n\t\t\t};\n\t\t}\n\n\t\tasync function startSessionComponent<TInput, TOutput, TConfig>(\n\t\t\tcomponent: PreparedRuntimeComponent<TInput, TOutput, TConfig>,\n\t\t): Promise<EvoComponentProcess<TInput, TOutput, TConfig>> {\n\t\t\tconst process = new EvoComponentProcess(\n\t\t\t\tcomponent.artifact,\n\t\t\t\tcomponent.abi,\n\t\t\t\tcomponent.config,\n\t\t\t\tcomponent.processOptions,\n\t\t\t);\n\t\t\tawait process.start();\n\t\t\treturn process;\n\t\t}\n\n\t\tasync function invokeTurnComponent<TInput, TOutput, TConfig>(\n\t\t\tcomponent: PreparedRuntimeComponent<TInput, TOutput, TConfig>,\n\t\t\tinput: TInput,\n\t\t): Promise<TOutput> {\n\t\t\tconst process = new EvoComponentProcess(\n\t\t\t\tcomponent.artifact,\n\t\t\t\tcomponent.abi,\n\t\t\t\tcomponent.config,\n\t\t\t\tcomponent.processOptions,\n\t\t\t);\n\t\t\tactiveTurnProcesses.add(process);\n\t\t\ttry {\n\t\t\t\treturn await process.invoke(input);\n\t\t\t} finally {\n\t\t\t\tactiveTurnProcesses.delete(process);\n\t\t\t\tawait process.shutdown();\n\t\t\t}\n\t\t}\n\n\t\tfunction registerToolComponent(\n\t\t\tselection: EvoToolSelection,\n\t\t\tprocess: EvoComponentProcess<ToolV1Input, ToolV1Output, Record<string, never>>,\n\t\t): void {\n\t\t\ttoolProcesses.set(selection.id, process);\n\t\t\tif (!registeredEvoToolNames.has(selection.id) && pi.getAllTools().some((tool) => tool.name === selection.id)) {\n\t\t\t\tthrow new Error(`Evo tool name conflicts with an existing host tool: ${selection.id}`);\n\t\t\t}\n\t\t\tregisteredEvoToolNames.add(selection.id);\n\t\t\tpi.registerTool({\n\t\t\t\tname: selection.id,\n\t\t\t\tlabel: selection.id,\n\t\t\t\tdescription: `Sandboxed Evo tool component ${selection.id}. Parameters are passed as a JSON object.`,\n\t\t\t\tparameters: EVO_TOOL_PARAMETERS,\n\t\t\t\texecutionMode: \"sequential\",\n\t\t\t\tasync execute(_toolCallId, params, signal) {\n\t\t\t\t\tconst active = toolProcesses.get(selection.id);\n\t\t\t\t\tif (!active || active !== process) {\n\t\t\t\t\t\tthrow new Error(`Evo tool component is not active: ${selection.id}`);\n\t\t\t\t\t}\n\t\t\t\t\tlet abortError: Error | undefined;\n\t\t\t\t\tlet abortTermination: Promise<void> | undefined;\n\t\t\t\t\tconst abort = (): void => {\n\t\t\t\t\t\ttoolProcesses.delete(selection.id);\n\t\t\t\t\t\tabortError =\n\t\t\t\t\t\t\tsignal?.reason instanceof Error ? signal.reason : new Error(\"Evo tool execution aborted\");\n\t\t\t\t\t\tabortTermination ??= active.terminate(abortError);\n\t\t\t\t\t\tvoid abortTermination.catch(() => undefined);\n\t\t\t\t\t};\n\t\t\t\t\tsignal?.addEventListener(\"abort\", abort, { once: true });\n\t\t\t\t\tif (signal?.aborted) abort();\n\t\t\t\t\ttry {\n\t\t\t\t\t\tif (abortTermination) {\n\t\t\t\t\t\t\tawait abortTermination;\n\t\t\t\t\t\t\tthrow abortError ?? new Error(\"Evo tool execution aborted\");\n\t\t\t\t\t\t}\n\t\t\t\t\t\treturn await active.invoke({ params });\n\t\t\t\t\t} catch (error) {\n\t\t\t\t\t\ttoolProcesses.delete(selection.id);\n\t\t\t\t\t\tif (abortTermination) await abortTermination;\n\t\t\t\t\t\telse await active.shutdown();\n\t\t\t\t\t\tthrow error;\n\t\t\t\t\t} finally {\n\t\t\t\t\t\tsignal?.removeEventListener(\"abort\", abort);\n\t\t\t\t\t}\n\t\t\t\t},\n\t\t\t});\n\t\t}\n\n\t\tfunction registerWorkflowComponent(\n\t\t\tselection: EvoWorkflowSelection,\n\t\t\tcomponent: PreparedRuntimeComponent<WorkflowV1Input, WorkflowV1Output, Record<string, never>>,\n\t\t): void {\n\t\t\tconst command = selection.trigger.slice(1);\n\t\t\tif (\n\t\t\t\t!registeredEvoWorkflowCommands.has(command) &&\n\t\t\t\tpi.getCommands().some((candidate) => candidate.name === command)\n\t\t\t) {\n\t\t\t\tthrow new Error(`Evo workflow trigger conflicts with an existing command: ${selection.trigger}`);\n\t\t\t}\n\t\t\tregisteredEvoWorkflowCommands.add(command);\n\t\t\tworkflowComponents.set(selection.trigger, component);\n\t\t\tconst spawnGrant = (selection.grants ?? []).find((grant) => grant.capability === \"spawn-agent\");\n\t\t\tconst host =\n\t\t\t\tspawnGrant && \"models\" in spawnGrant\n\t\t\t\t\t? {\n\t\t\t\t\t\t\t...(spawnGrant.models[0] ? { model: spawnGrant.models[0] } : {}),\n\t\t\t\t\t\t\ttools: [...(spawnGrant.tools ?? [])],\n\t\t\t\t\t\t\tmaxOutputTokensPerCall: spawnGrant.maxOutputTokensPerCall,\n\t\t\t\t\t\t}\n\t\t\t\t\t: undefined;\n\t\t\tpi.registerCommand(command, {\n\t\t\t\tdescription: `Run sandboxed Evo workflow ${selection.id}`,\n\t\t\t\tasync handler(args) {\n\t\t\t\t\tconst active = workflowComponents.get(selection.trigger);\n\t\t\t\t\tif (!active || active !== component) {\n\t\t\t\t\t\tthrow new Error(`Evo workflow is not active: ${selection.trigger}`);\n\t\t\t\t\t}\n\t\t\t\t\tconst output = await invokeTurnComponent(active, {\n\t\t\t\t\t\ttrigger: selection.trigger,\n\t\t\t\t\t\targs: { text: args },\n\t\t\t\t\t\t...(host ? { host } : {}),\n\t\t\t\t\t});\n\t\t\t\t\tpi.sendMessage(\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\tcustomType: \"evo.workflow-result\",\n\t\t\t\t\t\t\tcontent: canonicalJson(output.result),\n\t\t\t\t\t\t\tdisplay: true,\n\t\t\t\t\t\t\tdetails: {\n\t\t\t\t\t\t\t\tid: selection.id,\n\t\t\t\t\t\t\t\ttrigger: selection.trigger,\n\t\t\t\t\t\t\t\tresult: output.result,\n\t\t\t\t\t\t\t},\n\t\t\t\t\t\t},\n\t\t\t\t\t\t{ triggerTurn: false },\n\t\t\t\t\t);\n\t\t\t\t},\n\t\t\t});\n\t\t}\n\n\t\tasync function invokeGuard(input: GuardV1Input): Promise<GuardV1Output | undefined> {\n\t\t\tconst process = guardProcess;\n\t\t\tif (!process) return undefined;\n\t\t\tconst invocation = guardInvocationTail.then(async () => process.invoke(input));\n\t\t\tguardInvocationTail = invocation.then(\n\t\t\t\t() => undefined,\n\t\t\t\t() => undefined,\n\t\t\t);\n\t\t\treturn invocation;\n\t\t}\n\n\t\tasync function invokeMemory(input: MemoryV1Input): Promise<MemoryV1Output | undefined> {\n\t\t\tconst process = memoryProcess;\n\t\t\tif (!process) return undefined;\n\t\t\tconst invocation = memoryInvocationTail.then(async () => process.invoke(input));\n\t\t\tmemoryInvocationTail = invocation.then(\n\t\t\t\t() => undefined,\n\t\t\t\t() => undefined,\n\t\t\t);\n\t\t\treturn invocation;\n\t\t}\n\n\t\tfunction clearActiveFeatures(): void {\n\t\t\tclearFeatureSession?.();\n\t\t\tclearFeatureSession = undefined;\n\t\t}\n\n\t\tfunction restoreActiveTools(): void {\n\t\t\tif (activeToolsBeforeBundle === undefined) return;\n\t\t\ttry {\n\t\t\t\tpi.setActiveTools(activeToolsBeforeBundle);\n\t\t\t} finally {\n\t\t\t\tactiveToolsBeforeBundle = undefined;\n\t\t\t}\n\t\t}\n\n\t\tasync function restoreActiveModel(): Promise<void> {\n\t\t\tif (activeModelBeforeBundle === undefined) return;\n\t\t\tconst restored = await pi.setModel(activeModelBeforeBundle);\n\t\t\tif (!restored) throw new Error(\"Evo-Pi could not restore the model active before bundle routing\");\n\t\t\tactiveModelBeforeBundle = undefined;\n\t\t}\n\n\t\tpi.on(\"session_start\", async (event, ctx) => {\n\t\t\tpinned = undefined;\n\t\t\tclearActiveFeatures();\n\t\t\tawait stopComponentProcesses();\n\t\t\ttry {\n\t\t\t\trestoreActiveTools();\n\t\t\t\tawait restoreActiveModel();\n\t\t\t\tactiveToolsBeforeBundle = [...pi.getActiveTools()];\n\t\t\t\tconst sessionId = ctx.sessionManager.getSessionId();\n\t\t\t\tconst recordedDigest = resolveSessionBundleDigest(ctx.sessionManager.getEntries(), sessionId, event.reason);\n\t\t\t\tconst digest = recordedDigest ?? (await registry.readStableDigest());\n\t\t\t\tif (!digest) {\n\t\t\t\t\tpi.setActiveTools(filterEvoCodeFeatureTools(activeToolsBeforeBundle, [], { root: paths.root }));\n\t\t\t\t\treturn;\n\t\t\t\t}\n\t\t\t\tconst compiledBundle = await loadCompiledBundle(paths, digest);\n\t\t\t\tawait verifyManagedSourceSnapshots(compiledBundle.policy.managedSources ?? []);\n\t\t\t\tconst runtimeBundle = await renderRuntimeBundle(compiledBundle);\n\t\t\t\tconst components = compiledBundle.policy.components ?? {};\n\t\t\t\tconst compactionSelection = components.compaction;\n\t\t\t\tif (compactionSelection) {\n\t\t\t\t\tcompactionProcess = await startSessionComponent(\n\t\t\t\t\t\tawait prepareComponent(\"compaction\", compactionSelection, COMPACTION_V1_ABI, compiledBundle, ctx),\n\t\t\t\t\t);\n\t\t\t\t}\n\t\t\t\tconst contextSelection = components.context;\n\t\t\t\tif (contextSelection) {\n\t\t\t\t\tcontextProcess = await startSessionComponent(\n\t\t\t\t\t\tawait prepareComponent(\"context\", contextSelection, CONTEXT_V1_ABI, compiledBundle, ctx),\n\t\t\t\t\t);\n\t\t\t\t}\n\t\t\t\tconst guardSelection = components.guard;\n\t\t\t\tif (guardSelection) {\n\t\t\t\t\tguardProcess = await startSessionComponent(\n\t\t\t\t\t\tawait prepareComponent(\"guard\", guardSelection, GUARD_V1_ABI, compiledBundle, ctx),\n\t\t\t\t\t);\n\t\t\t\t}\n\t\t\t\tconst instructionsSelection = components.instructions;\n\t\t\t\tif (instructionsSelection) {\n\t\t\t\t\tinstructionsComponent = await prepareComponent(\n\t\t\t\t\t\t\"instructions\",\n\t\t\t\t\t\tinstructionsSelection,\n\t\t\t\t\t\tINSTRUCTIONS_V1_ABI,\n\t\t\t\t\t\tcompiledBundle,\n\t\t\t\t\t\tctx,\n\t\t\t\t\t);\n\t\t\t\t}\n\t\t\t\tconst generationSelection = components.generation;\n\t\t\t\tif (generationSelection) {\n\t\t\t\t\tgenerationComponent = await prepareComponent(\n\t\t\t\t\t\t\"generation\",\n\t\t\t\t\t\tgenerationSelection,\n\t\t\t\t\t\tGENERATION_V1_ABI,\n\t\t\t\t\t\tcompiledBundle,\n\t\t\t\t\t\tctx,\n\t\t\t\t\t);\n\t\t\t\t}\n\t\t\t\tconst controlSelection = components.control;\n\t\t\t\tif (controlSelection) {\n\t\t\t\t\tconst prepared = await prepareComponent(\n\t\t\t\t\t\t\"control\",\n\t\t\t\t\t\tcontrolSelection,\n\t\t\t\t\t\tCONTROL_V1_ABI,\n\t\t\t\t\t\tcompiledBundle,\n\t\t\t\t\t\tctx,\n\t\t\t\t\t);\n\t\t\t\t\tcontrolMemoryNamespace = persistedGrantCapabilities(controlSelection).has(\"memory-write\")\n\t\t\t\t\t\t? prepared.memoryNamespace\n\t\t\t\t\t\t: undefined;\n\t\t\t\t\tcontrolProcess = await startSessionComponent(prepared);\n\t\t\t\t}\n\t\t\t\tconst memorySelection = components.memory;\n\t\t\t\tif (memorySelection) {\n\t\t\t\t\tconst prepared = await prepareComponent(\"memory\", memorySelection, MEMORY_V1_ABI, compiledBundle, ctx);\n\t\t\t\t\tif (!prepared.memoryNamespace) {\n\t\t\t\t\t\tthrow new Error(\"memory/v1 component did not receive a host-owned memory namespace\");\n\t\t\t\t\t}\n\t\t\t\t\tmemoryNamespace = prepared.memoryNamespace;\n\t\t\t\t\tmemoryProcess = await startSessionComponent(prepared);\n\t\t\t\t}\n\t\t\t\tfor (const selection of compiledBundle.policy.tools ?? []) {\n\t\t\t\t\tconst process = await startSessionComponent(\n\t\t\t\t\t\tawait prepareComponent(\"tool\", selection, TOOL_V1_ABI, compiledBundle, ctx),\n\t\t\t\t\t);\n\t\t\t\t\tregisterToolComponent(selection, process);\n\t\t\t\t}\n\t\t\t\tfor (const selection of compiledBundle.policy.workflows ?? []) {\n\t\t\t\t\tregisterWorkflowComponent(\n\t\t\t\t\t\tselection,\n\t\t\t\t\t\tawait prepareComponent(\"workflow\", selection, WORKFLOW_V1_ABI, compiledBundle, ctx),\n\t\t\t\t\t);\n\t\t\t\t}\n\t\t\t\tif (recordedDigest === undefined) pi.appendEntry(\"evo.bundle\", { digest, sessionId });\n\t\t\t\tconst workerRoute = runtimeBundle.bundle.policy.modelRouting?.worker;\n\t\t\t\tif (workerRoute) {\n\t\t\t\t\tconst originalModel = ctx.model;\n\t\t\t\t\tif (!originalModel)\n\t\t\t\t\t\tthrow new Error(\"Evo-Pi cannot route a worker model without a current model to restore\");\n\t\t\t\t\tconst workerModel = resolveWorkerModel(ctx, workerRoute);\n\t\t\t\t\tactiveModelBeforeBundle = originalModel;\n\t\t\t\t\tif (!(await pi.setModel(workerModel))) {\n\t\t\t\t\t\tthrow new Error(`Evo-Pi worker model is unavailable: ${workerRoute}`);\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t\tclearFeatureSession = activateEvoFeatureSession(runtimeBundle.bundle.policy.enabledFeatures ?? [], {\n\t\t\t\t\troot: paths.root,\n\t\t\t\t\tsessionId,\n\t\t\t\t});\n\t\t\t\tpi.setActiveTools(\n\t\t\t\t\tfilterEvoCodeFeatureTools(\n\t\t\t\t\t\truntimeBundle.enabledTools ?? [\n\t\t\t\t\t\t\t...new Set([\n\t\t\t\t\t\t\t\t...activeToolsBeforeBundle,\n\t\t\t\t\t\t\t\t...(compiledBundle.policy.tools ?? []).map((tool) => tool.id),\n\t\t\t\t\t\t\t]),\n\t\t\t\t\t\t],\n\t\t\t\t\t\truntimeBundle.bundle.policy.enabledFeatures ?? [],\n\t\t\t\t\t\t{ root: paths.root },\n\t\t\t\t\t),\n\t\t\t\t);\n\t\t\t\tpinned = runtimeBundle;\n\t\t\t} catch (error) {\n\t\t\t\tpinned = undefined;\n\t\t\t\tclearActiveFeatures();\n\t\t\t\tconst detail = error instanceof Error ? error.message : String(error);\n\t\t\t\tlet recoveryError: unknown;\n\t\t\t\ttry {\n\t\t\t\t\tawait stopComponentProcesses();\n\t\t\t\t} catch (shutdownError) {\n\t\t\t\t\trecoveryError = shutdownError;\n\t\t\t\t}\n\t\t\t\ttry {\n\t\t\t\t\tpi.setActiveTools([]);\n\t\t\t\t} catch (disableError) {\n\t\t\t\t\trecoveryError ??= disableError;\n\t\t\t\t}\n\t\t\t\ttry {\n\t\t\t\t\tawait restoreActiveModel();\n\t\t\t\t} catch (modelError) {\n\t\t\t\t\trecoveryError ??= modelError;\n\t\t\t\t}\n\t\t\t\tif (recoveryError !== undefined) {\n\t\t\t\t\tconst recoveryDetail = recoveryError instanceof Error ? recoveryError.message : String(recoveryError);\n\t\t\t\t\tctx.ui.notify(`Evo-Pi bundle failed and recovery was incomplete: ${detail}; ${recoveryDetail}`, \"error\");\n\t\t\t\t\tthrow new Error(\"Evo-Pi could not fail closed after bundle activation failed\", { cause: recoveryError });\n\t\t\t\t}\n\t\t\t\tctx.ui.notify(`Evo-Pi bundle disabled with all tools blocked: ${detail}`, \"error\");\n\t\t\t}\n\t\t});\n\n\t\tpi.on(\"session_shutdown\", async () => {\n\t\t\ttry {\n\t\t\t\ttry {\n\t\t\t\t\trestoreActiveTools();\n\t\t\t\t} finally {\n\t\t\t\t\ttry {\n\t\t\t\t\t\tawait restoreActiveModel();\n\t\t\t\t\t} finally {\n\t\t\t\t\t\ttry {\n\t\t\t\t\t\t\tclearActiveFeatures();\n\t\t\t\t\t\t} finally {\n\t\t\t\t\t\t\tawait stopComponentProcesses();\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t} finally {\n\t\t\t\tpinned = undefined;\n\t\t\t}\n\t\t});\n\n\t\tpi.on(\"session_before_compact\", async (event, ctx) => {\n\t\t\tconst activeContextProcess = contextProcess;\n\t\t\tif (activeContextProcess && !compactionProcess && pinned) {\n\t\t\t\ttry {\n\t\t\t\t\tconst { preparation } = event;\n\t\t\t\t\tconst conversation = serializeConversation(\n\t\t\t\t\t\tconvertToLlm([...preparation.messagesToSummarize, ...preparation.turnPrefixMessages]),\n\t\t\t\t\t);\n\t\t\t\t\tconst result = await activeContextProcess.invoke({\n\t\t\t\t\t\tmode: \"checkpoint\",\n\t\t\t\t\t\tconversation,\n\t\t\t\t\t\t...(preparation.previousSummary ? { previousSummary: preparation.previousSummary } : {}),\n\t\t\t\t\t\tfirstKeptEntryId: preparation.firstKeptEntryId,\n\t\t\t\t\t\ttokensBefore: preparation.tokensBefore,\n\t\t\t\t\t\treason: event.reason,\n\t\t\t\t\t\t...(event.customInstructions ? { customInstructions: event.customInstructions } : {}),\n\t\t\t\t\t});\n\t\t\t\t\tif (\"messages\" in result) {\n\t\t\t\t\t\tthrow new Error(\"context/v1 checkpoint returned a transform result\");\n\t\t\t\t\t}\n\t\t\t\t\tif (result.firstKeptEntryId !== preparation.firstKeptEntryId) {\n\t\t\t\t\t\tthrow new Error(\"context/v1 checkpoint changed the prepared kept-message boundary\");\n\t\t\t\t\t}\n\t\t\t\t\treturn {\n\t\t\t\t\t\tcompaction: {\n\t\t\t\t\t\t\tsummary: result.summary,\n\t\t\t\t\t\t\tfirstKeptEntryId: result.firstKeptEntryId,\n\t\t\t\t\t\t\ttokensBefore: preparation.tokensBefore,\n\t\t\t\t\t\t\tdetails: {\n\t\t\t\t\t\t\t\tabi: CONTEXT_V1_ABI.id,\n\t\t\t\t\t\t\t\tcomponentId: pinned.bundle.policy.components?.context?.id,\n\t\t\t\t\t\t\t\tartifactDigest: pinned.bundle.policy.components?.context?.artifactDigest,\n\t\t\t\t\t\t\t\t...(result.metrics ? { metrics: result.metrics } : {}),\n\t\t\t\t\t\t\t\t...(result.details === undefined ? {} : { componentDetails: result.details }),\n\t\t\t\t\t\t\t},\n\t\t\t\t\t\t},\n\t\t\t\t\t};\n\t\t\t\t} catch (error) {\n\t\t\t\t\tconst detail = error instanceof Error ? error.message : String(error);\n\t\t\t\t\tctx.ui.notify(`Evo-Pi context checkpoint failed; using default compaction: ${detail}`, \"warning\");\n\t\t\t\t\tcontextProcess = undefined;\n\t\t\t\t\tawait activeContextProcess.shutdown();\n\t\t\t\t\treturn undefined;\n\t\t\t\t}\n\t\t\t}\n\t\t\tconst process = compactionProcess;\n\t\t\tif (!process || !pinned) return undefined;\n\t\t\ttry {\n\t\t\t\tconst { preparation } = event;\n\t\t\t\tconst conversation = serializeConversation(\n\t\t\t\t\tconvertToLlm([...preparation.messagesToSummarize, ...preparation.turnPrefixMessages]),\n\t\t\t\t);\n\t\t\t\tconst result = await process.invoke({\n\t\t\t\t\tconversation,\n\t\t\t\t\t...(preparation.previousSummary ? { previousSummary: preparation.previousSummary } : {}),\n\t\t\t\t\tfirstKeptEntryId: preparation.firstKeptEntryId,\n\t\t\t\t\ttokensBefore: preparation.tokensBefore,\n\t\t\t\t\treason: event.reason,\n\t\t\t\t\t...(event.customInstructions ? { customInstructions: event.customInstructions } : {}),\n\t\t\t\t});\n\t\t\t\tif (result.firstKeptEntryId !== preparation.firstKeptEntryId) {\n\t\t\t\t\tthrow new Error(\"compaction/v1 component changed the prepared kept-message boundary\");\n\t\t\t\t}\n\t\t\t\treturn {\n\t\t\t\t\tcompaction: {\n\t\t\t\t\t\tsummary: result.summary,\n\t\t\t\t\t\tfirstKeptEntryId: result.firstKeptEntryId,\n\t\t\t\t\t\ttokensBefore: preparation.tokensBefore,\n\t\t\t\t\t\tdetails: {\n\t\t\t\t\t\t\tabi: COMPACTION_V1_ABI.id,\n\t\t\t\t\t\t\tcomponentId: pinned.bundle.policy.components?.compaction?.id,\n\t\t\t\t\t\t\tartifactDigest: pinned.bundle.policy.components?.compaction?.artifactDigest,\n\t\t\t\t\t\t\t...(result.metrics ? { metrics: result.metrics } : {}),\n\t\t\t\t\t\t\t...(result.details === undefined ? {} : { componentDetails: result.details }),\n\t\t\t\t\t\t},\n\t\t\t\t\t},\n\t\t\t\t};\n\t\t\t} catch (error) {\n\t\t\t\tconst detail = error instanceof Error ? error.message : String(error);\n\t\t\t\tctx.ui.notify(`Evo-Pi compaction component failed; using default compaction: ${detail}`, \"warning\");\n\t\t\t\tcompactionProcess = undefined;\n\t\t\t\tawait process.shutdown();\n\t\t\t\treturn undefined;\n\t\t\t}\n\t\t});\n\n\t\tpi.on(\"context\", async (event, ctx) => {\n\t\t\tconst process = contextProcess;\n\t\t\tif (!process || !pinned) return undefined;\n\t\t\ttry {\n\t\t\t\tconst usage = ctx.getContextUsage();\n\t\t\t\tconst result = await process.invoke({\n\t\t\t\t\tmode: \"transform\",\n\t\t\t\t\tmessages: event.messages,\n\t\t\t\t\t...(typeof usage?.tokens === \"number\" ? { tokenEstimate: usage.tokens } : {}),\n\t\t\t\t\t...(usage ? { contextWindow: usage.contextWindow } : {}),\n\t\t\t\t\t...(ctx.model ? { model: `${ctx.model.provider}/${ctx.model.id}` } : {}),\n\t\t\t\t\treason: \"turn\",\n\t\t\t\t});\n\t\t\t\tif (!(\"messages\" in result)) {\n\t\t\t\t\tthrow new Error(\"context/v1 transform returned a checkpoint result\");\n\t\t\t\t}\n\t\t\t\tif (result.messages.some((message) => !isSupportedAgentMessage(message))) {\n\t\t\t\t\tthrow new Error(\"context/v1 transform returned an unsupported AgentMessage\");\n\t\t\t\t}\n\t\t\t\treturn { messages: result.messages as typeof event.messages };\n\t\t\t} catch (error) {\n\t\t\t\tconst detail = error instanceof Error ? error.message : String(error);\n\t\t\t\tctx.ui.notify(`Evo-Pi context component failed; using the original messages: ${detail}`, \"warning\");\n\t\t\t\tcontextProcess = undefined;\n\t\t\t\tawait process.shutdown();\n\t\t\t\treturn undefined;\n\t\t\t}\n\t\t});\n\n\t\tpi.on(\"tool_call\", async (event, ctx) => {\n\t\t\tconst process = guardProcess;\n\t\t\tif (!process || !pinned) return undefined;\n\t\t\ttry {\n\t\t\t\tconst result = await invokeGuard({\n\t\t\t\t\tmode: \"before\",\n\t\t\t\t\ttoolCallId: event.toolCallId,\n\t\t\t\t\ttoolName: event.toolName,\n\t\t\t\t\targs: event.input,\n\t\t\t\t});\n\t\t\t\tif (!result || result.mode !== \"before\") {\n\t\t\t\t\tthrow new Error(\"guard/v1 before invocation returned an after result\");\n\t\t\t\t}\n\t\t\t\tif (result.args) {\n\t\t\t\t\tconst mutableInput = event.input as Record<string, unknown>;\n\t\t\t\t\tfor (const key of Object.keys(mutableInput)) delete mutableInput[key];\n\t\t\t\t\tObject.assign(mutableInput, result.args);\n\t\t\t\t}\n\t\t\t\treturn {\n\t\t\t\t\t...(result.block === undefined ? {} : { block: result.block }),\n\t\t\t\t\t...(result.reason === undefined ? {} : { reason: result.reason }),\n\t\t\t\t};\n\t\t\t} catch (error) {\n\t\t\t\tconst detail = error instanceof Error ? error.message : String(error);\n\t\t\t\tctx.ui.notify(`Evo-Pi guard component failed; blocking the tool call: ${detail}`, \"error\");\n\t\t\t\tguardProcess = undefined;\n\t\t\t\tawait process.shutdown();\n\t\t\t\treturn { block: true, reason: `Evo-Pi guard failed closed: ${detail}` };\n\t\t\t}\n\t\t});\n\n\t\tpi.on(\"tool_result\", async (event, ctx) => {\n\t\t\tconst process = guardProcess;\n\t\t\tif (!process || !pinned) return undefined;\n\t\t\ttry {\n\t\t\t\tconst result = await invokeGuard({\n\t\t\t\t\tmode: \"after\",\n\t\t\t\t\ttoolCallId: event.toolCallId,\n\t\t\t\t\ttoolName: event.toolName,\n\t\t\t\t\targs: event.input,\n\t\t\t\t\tcontent: event.content,\n\t\t\t\t\t...(event.details === undefined ? {} : { details: event.details }),\n\t\t\t\t\tisError: event.isError,\n\t\t\t\t});\n\t\t\t\tif (!result || result.mode !== \"after\") {\n\t\t\t\t\tthrow new Error(\"guard/v1 after invocation returned a before result\");\n\t\t\t\t}\n\t\t\t\treturn {\n\t\t\t\t\t...(result.content === undefined ? {} : { content: result.content as typeof event.content }),\n\t\t\t\t\t...(result.details === undefined ? {} : { details: result.details }),\n\t\t\t\t\t...(result.isError === undefined ? {} : { isError: result.isError }),\n\t\t\t\t\t...(result.terminate === undefined ? {} : { terminate: result.terminate }),\n\t\t\t\t};\n\t\t\t} catch (error) {\n\t\t\t\tconst detail = error instanceof Error ? error.message : String(error);\n\t\t\t\tctx.ui.notify(\n\t\t\t\t\t`Evo-Pi guard component failed after tool execution; terminating the batch: ${detail}`,\n\t\t\t\t\t\"error\",\n\t\t\t\t);\n\t\t\t\tguardProcess = undefined;\n\t\t\t\tawait process.shutdown();\n\t\t\t\treturn {\n\t\t\t\t\tcontent: [{ type: \"text\", text: `Evo-Pi guard failed closed after tool execution: ${detail}` }],\n\t\t\t\t\tisError: true,\n\t\t\t\t\tterminate: true,\n\t\t\t\t};\n\t\t\t}\n\t\t});\n\n\t\tpi.on(\"prepare_next_turn\", async (event, ctx) => {\n\t\t\tconst activeMemoryProcess = memoryProcess;\n\t\t\tconst activeMemoryNamespace = memoryNamespace;\n\t\t\tif (activeMemoryProcess && activeMemoryNamespace && pinned) {\n\t\t\t\ttry {\n\t\t\t\t\tconst usage = ctx.getContextUsage();\n\t\t\t\t\tconst result = await invokeMemory({\n\t\t\t\t\t\tmode: \"encode\",\n\t\t\t\t\t\tturnDigest: {\n\t\t\t\t\t\t\tturnIndex: event.turnIndex,\n\t\t\t\t\t\t\tmessage: event.message,\n\t\t\t\t\t\t\ttoolResults: event.toolResults,\n\t\t\t\t\t\t\t...(usage ? { usage } : {}),\n\t\t\t\t\t\t\t...(ctx.model ? { model: `${ctx.model.provider}/${ctx.model.id}` } : {}),\n\t\t\t\t\t\t\treasoning: pi.getThinkingLevel(),\n\t\t\t\t\t\t},\n\t\t\t\t\t});\n\t\t\t\t\tif (!result || result.mode !== \"encode\") {\n\t\t\t\t\t\tthrow new Error(\"memory/v1 encode invocation returned a non-encode result\");\n\t\t\t\t\t}\n\t\t\t\t\tawait applyMemoryComponentOutput(activeMemoryNamespace, result);\n\t\t\t\t} catch (error) {\n\t\t\t\t\tconst detail = error instanceof Error ? error.message : String(error);\n\t\t\t\t\tctx.ui.notify(`Evo-Pi memory encode failed; disabling memory for this session: ${detail}`, \"warning\");\n\t\t\t\t\tmemoryProcess = undefined;\n\t\t\t\t\tmemoryNamespace = undefined;\n\t\t\t\t\tawait activeMemoryProcess.shutdown();\n\t\t\t\t}\n\t\t\t}\n\t\t\tconst process = controlProcess;\n\t\t\tif (!process || !pinned) return undefined;\n\t\t\ttry {\n\t\t\t\tconst usage = ctx.getContextUsage();\n\t\t\t\tconst result = await process.invoke({\n\t\t\t\t\tturnIndex: event.turnIndex,\n\t\t\t\t\tmessage: event.message,\n\t\t\t\t\ttoolResults: event.toolResults,\n\t\t\t\t\t...(usage ? { usage } : {}),\n\t\t\t\t\t...(ctx.model ? { model: `${ctx.model.provider}/${ctx.model.id}` } : {}),\n\t\t\t\t\treasoning: pi.getThinkingLevel(),\n\t\t\t\t});\n\t\t\t\tif (result.model !== undefined) {\n\t\t\t\t\tconst model = resolveWorkerModel(ctx, result.model);\n\t\t\t\t\tif (!(await pi.setModel(model))) {\n\t\t\t\t\t\tthrow new Error(`control/v1 model is unavailable: ${result.model}`);\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t\tif (result.reasoning !== undefined) pi.setThinkingLevel(resolveThinkingLevel(result.reasoning));\n\t\t\t\tif (result.memoryDeltas !== undefined) {\n\t\t\t\t\tif (!controlMemoryNamespace) {\n\t\t\t\t\t\tthrow new Error(\"control/v1 returned memoryDeltas without a persisted memory-write grant\");\n\t\t\t\t\t}\n\t\t\t\t\tawait applyControlMemoryDeltas(controlMemoryNamespace, result.memoryDeltas);\n\t\t\t\t}\n\t\t\t\treturn result.stop === undefined ? undefined : { stop: result.stop };\n\t\t\t} catch (error) {\n\t\t\t\tconst detail = error instanceof Error ? error.message : String(error);\n\t\t\t\tctx.ui.notify(`Evo-Pi control component failed; stopping the current run: ${detail}`, \"error\");\n\t\t\t\tcontrolProcess = undefined;\n\t\t\t\tawait process.shutdown();\n\t\t\t\treturn { stop: true };\n\t\t\t}\n\t\t});\n\n\t\tpi.on(\"message_end\", async (event, ctx) => {\n\t\t\tconst component = generationComponent;\n\t\t\tif (!component || !pinned || event.message.role !== \"assistant\") return undefined;\n\t\t\tif (event.message.content.some((content) => content.type === \"toolCall\")) return undefined;\n\t\t\ttry {\n\t\t\t\tconst result = await invokeTurnComponent(component, {\n\t\t\t\t\tmessage: JSON.parse(canonicalJson(event.message)) as Record<string, unknown>,\n\t\t\t\t});\n\t\t\t\tif (!result.message && result.stopReason === undefined && !result.redo) return undefined;\n\t\t\t\tlet content = event.message.content;\n\t\t\t\tif (result.message) {\n\t\t\t\t\tif (result.message.role !== \"assistant\" || !Array.isArray(result.message.content)) {\n\t\t\t\t\t\tthrow new Error(\"generation/v1 replacement must be an assistant message with content\");\n\t\t\t\t\t}\n\t\t\t\t\tif (result.message.content.some((block) => !isRecord(block) || block.type === \"toolCall\")) {\n\t\t\t\t\t\tthrow new Error(\"generation/v1 cannot inject or replace tool calls\");\n\t\t\t\t\t}\n\t\t\t\t\tcontent = result.message.content as typeof content;\n\t\t\t\t}\n\t\t\t\tlet stopReason = event.message.stopReason;\n\t\t\t\tif (result.stopReason !== undefined) {\n\t\t\t\t\tswitch (result.stopReason) {\n\t\t\t\t\t\tcase \"stop\":\n\t\t\t\t\t\tcase \"length\":\n\t\t\t\t\t\tcase \"toolUse\":\n\t\t\t\t\t\tcase \"error\":\n\t\t\t\t\t\tcase \"aborted\":\n\t\t\t\t\t\t\tstopReason = result.stopReason;\n\t\t\t\t\t\t\tbreak;\n\t\t\t\t\t\tdefault:\n\t\t\t\t\t\t\tthrow new Error(\"generation/v1 returned an invalid stopReason\");\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t\treturn {\n\t\t\t\t\tmessage: { ...event.message, content, stopReason },\n\t\t\t\t\t...(result.redo ? { redo: true } : {}),\n\t\t\t\t};\n\t\t\t} catch (error) {\n\t\t\t\tconst detail = error instanceof Error ? error.message : String(error);\n\t\t\t\tctx.ui.notify(`Evo-Pi generation component failed; using the original message: ${detail}`, \"warning\");\n\t\t\t\tgenerationComponent = undefined;\n\t\t\t\treturn undefined;\n\t\t\t}\n\t\t});\n\n\t\tpi.on(\"resources_discover\", () => {\n\t\t\treturn pinned?.skillDirectory ? { skillPaths: [pinned.skillDirectory] } : undefined;\n\t\t});\n\n\t\tpi.on(\"agent_settled\", async (_event, ctx) => {\n\t\t\tconst activeMemoryProcess = memoryProcess;\n\t\t\tconst activeMemoryNamespace = memoryNamespace;\n\t\t\tif (!activeMemoryProcess || !activeMemoryNamespace || !pinned) return;\n\t\t\ttry {\n\t\t\t\tconst state = await activeMemoryNamespace.read();\n\t\t\t\tconst result = await invokeMemory({\n\t\t\t\t\tmode: \"consolidate\",\n\t\t\t\t\tcandidates: state.fragments.map(\n\t\t\t\t\t\t(fragment) => JSON.parse(canonicalJson(fragment)) as Record<string, unknown>,\n\t\t\t\t\t),\n\t\t\t\t});\n\t\t\t\tif (!result || result.mode !== \"consolidate\") {\n\t\t\t\t\tthrow new Error(\"memory/v1 consolidate invocation returned a non-consolidate result\");\n\t\t\t\t}\n\t\t\t\tawait applyMemoryComponentOutput(activeMemoryNamespace, result);\n\t\t\t} catch (error) {\n\t\t\t\tconst detail = error instanceof Error ? error.message : String(error);\n\t\t\t\tctx.ui.notify(\n\t\t\t\t\t`Evo-Pi memory consolidation failed; disabling memory for this session: ${detail}`,\n\t\t\t\t\t\"warning\",\n\t\t\t\t);\n\t\t\t\tmemoryProcess = undefined;\n\t\t\t\tmemoryNamespace = undefined;\n\t\t\t\tawait activeMemoryProcess.shutdown();\n\t\t\t}\n\t\t});\n\n\t\tpi.on(\"before_agent_start\", async (event, ctx) => {\n\t\t\tif (!pinned) return undefined;\n\t\t\tlet systemPrompt: string;\n\t\t\tif (!pinned.bundle.policy.managedSources?.length) {\n\t\t\t\tsystemPrompt = replaceRuntimeBundlePrompt(event.systemPrompt, pinned.systemPromptAppend);\n\t\t\t} else {\n\t\t\t\tconst managed = replaceManagedHostResources({\n\t\t\t\t\tevent,\n\t\t\t\t\tbundle: pinned.bundle,\n\t\t\t\t\tresources: pinned.managedResources,\n\t\t\t\t});\n\t\t\t\tsystemPrompt = replaceRuntimeBundlePrompt(\n\t\t\t\t\tmanaged.systemPrompt,\n\t\t\t\t\trenderRuntimeBundlePrompt(pinned, managed.excludedTargets),\n\t\t\t\t);\n\t\t\t}\n\t\t\tconst activeMemoryProcess = memoryProcess;\n\t\t\tif (activeMemoryProcess && memoryNamespace) {\n\t\t\t\ttry {\n\t\t\t\t\tconst result = await invokeMemory({ mode: \"recall\", query: event.prompt });\n\t\t\t\t\tif (!result || result.mode !== \"recall\") {\n\t\t\t\t\t\tthrow new Error(\"memory/v1 recall invocation returned a non-recall result\");\n\t\t\t\t\t}\n\t\t\t\t\tif (result.fragments.length > 0) {\n\t\t\t\t\t\tsystemPrompt += `\\n\\n## Recalled episodic memory\\n\\n${canonicalJson(result.fragments)}`;\n\t\t\t\t\t}\n\t\t\t\t} catch (error) {\n\t\t\t\t\tconst detail = error instanceof Error ? error.message : String(error);\n\t\t\t\t\tctx.ui.notify(`Evo-Pi memory recall failed; disabling memory for this session: ${detail}`, \"warning\");\n\t\t\t\t\tmemoryProcess = undefined;\n\t\t\t\t\tmemoryNamespace = undefined;\n\t\t\t\t\tawait activeMemoryProcess.shutdown();\n\t\t\t\t}\n\t\t\t}\n\t\t\tconst component = instructionsComponent;\n\t\t\tif (!component) return { systemPrompt };\n\t\t\ttry {\n\t\t\t\tconst result = await invokeTurnComponent(component, {\n\t\t\t\t\tsystemPrompt,\n\t\t\t\t\toptions: event.systemPromptOptions as unknown as Record<string, unknown>,\n\t\t\t\t});\n\t\t\t\treturn {\n\t\t\t\t\tsystemPrompt:\n\t\t\t\t\t\t\"systemPrompt\" in result\n\t\t\t\t\t\t\t? result.systemPrompt\n\t\t\t\t\t\t\t: result.sections.map((section) => section.content).join(\"\\n\\n\"),\n\t\t\t\t};\n\t\t\t} catch (error) {\n\t\t\t\tconst detail = error instanceof Error ? error.message : String(error);\n\t\t\t\tctx.ui.notify(`Evo-Pi instructions component failed; using the bundle prompt: ${detail}`, \"warning\");\n\t\t\t\tinstructionsComponent = undefined;\n\t\t\t\treturn { systemPrompt };\n\t\t\t}\n\t\t});\n\t};\n}\n"]}