@springbrand/agent-runtime 0.1.3-alpha.4 → 0.1.3-alpha.6

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (45) hide show
  1. package/package.json +11 -3
  2. package/src/adapter/cloudflare/index.ts +55 -0
  3. package/src/adapter/cloudflare/resources/runtime-resources.ts +89 -0
  4. package/src/adapter/cloudflare/sandbox/adapter.ts +1509 -0
  5. package/src/adapter/cloudflare/sandbox/id.ts +23 -0
  6. package/src/adapter/cloudflare/sandbox/policy.ts +15 -0
  7. package/src/adapter/cloudflare/subagent/definition.ts +574 -0
  8. package/src/adapter/cloudflare/subagent/runner.ts +175 -0
  9. package/src/adapter/cloudflare/subagent/tools.ts +254 -0
  10. package/src/adapter/cloudflare/universal-agent/hooks.ts +35 -0
  11. package/src/adapter/cloudflare/universal-agent/preparation.ts +273 -0
  12. package/src/adapter/cloudflare/universal-agent/tools.ts +74 -0
  13. package/src/adapter/cloudflare/workspace/publisher.ts +31 -0
  14. package/src/adapter/cloudflare/workspace/scoped-workspace.ts +376 -0
  15. package/src/agent-tool-runtime.ts +152 -0
  16. package/src/index.ts +49 -7
  17. package/src/kernel/bindings.ts +6 -6
  18. package/src/kernel/recoverable-chat-agent.ts +12 -0
  19. package/src/kernel/runtime-load.ts +89 -0
  20. package/src/layers/orchestration/temporary-agent/core.ts +12 -1
  21. package/src/layers/orchestration/temporary-agent/runner.ts +1 -2
  22. package/src/lib/mcp.ts +7 -3
  23. package/src/pi/assembly/context.ts +3 -3
  24. package/src/pi/assembly/extensions.ts +11 -22
  25. package/src/pi/assembly/snapshot.ts +1 -1
  26. package/src/pi/message/contract.ts +7 -0
  27. package/src/pi/message/conversion.ts +9 -1
  28. package/src/pi/runtime-adapter/assembly.ts +4 -10
  29. package/src/pi/runtime-adapter/index.ts +6 -2
  30. package/src/pi/tool/base.ts +17 -2
  31. package/src/pi/tool/compiler.ts +0 -1
  32. package/src/pi/tool/core.ts +13 -3
  33. package/src/pi/tool/mcp.ts +3 -4
  34. package/src/pi/tool/schedule.ts +11 -1
  35. package/src/pi/tool/skill.ts +55 -41
  36. package/src/pi/tool/subagent.ts +14 -2
  37. package/src/pi/tool/web-fetch.ts +0 -1
  38. package/src/pi/tool/web-search/web-search.ts +0 -1
  39. package/src/pi/tool/workspace-sandbox.ts +15 -7
  40. package/src/runtime-agent-context.ts +112 -0
  41. package/src/runtime-agent.ts +442 -328
  42. package/src/runtime-assembler.ts +255 -103
  43. package/src/runtime-definition.ts +173 -0
  44. package/src/runtime.ts +185 -25
  45. package/src/tool-registry.ts +143 -0
@@ -33,75 +33,41 @@ import {
33
33
  type PiToolSurface,
34
34
  type PiRuntimeAssembly,
35
35
  } from "./pi/assembly/snapshot";
36
+ import type { AgentTool } from "@earendil-works/pi-agent-core";
36
37
  import type { PiToolCandidate } from "./pi/tool/compiler";
38
+ import type {
39
+ AssembleRuntimeSnapshotInput,
40
+ RuntimeAgentHooks,
41
+ RuntimeSettings,
42
+ RuntimeExtensionContribution,
43
+ RuntimeProfileContribution,
44
+ RuntimeSkillContribution,
45
+ RuntimeToolSurfacePolicy,
46
+ } from "./runtime-definition";
47
+ import type { ToolRegistry } from "./tool-registry";
48
+ import { withRuntimeLoadTimeout } from "./kernel/runtime-load";
37
49
  import {
38
50
  basePiToolCandidates,
39
51
  memoryPiToolCandidate,
40
52
  } from "./pi/tool/base";
41
53
  import {
42
54
  browserQuickActionPiToolCandidates,
43
- codeExecutionPiToolCandidate,
44
55
  } from "./pi/tool/core";
45
- import {
46
- sandboxPiToolCandidates,
47
- workspacePiToolCandidates,
48
- } from "./pi/tool/workspace-sandbox";
49
- import { schedulePiToolCandidates } from "./pi/tool/schedule";
50
56
  import { skillPiToolCandidates } from "./pi/tool/skill";
51
- import { subagentPiToolCandidates } from "./pi/tool/subagent";
52
57
  import { createWebSearch } from "./pi/tool/web-search";
53
58
  import { resolvePiModel } from "./pi/runtime-adapter/models";
54
59
 
55
60
  /** Runtime Assembler:校验一份扁平输入并生成可原子提交的 Snapshot。 */
56
61
 
57
62
  export type { RuntimeDegradation } from "./kernel/degradation";
58
-
59
- /**
60
- * 提供 Runtime 核心运行参数。
61
- *
62
- * @remarks
63
- * Host Planner 在装配输入中提供它。
64
- *
65
- * 这里只放业务可配置字段,冻结和最终结构由 Runtime 负责。
66
- */
67
- export interface RuntimeProfileContribution {
68
- readonly model: string;
69
- readonly thinking: ThinkingEffort;
70
- readonly systemPrompt?: string;
71
- readonly executionLevel: ExecutionLevel;
72
- }
73
-
74
- /**
75
- * 描述一个已准备 Skill。
76
- */
77
- export interface RuntimeSkillContribution {
78
- readonly name: string;
79
- readonly description: string;
80
- readonly source: SkillSource;
81
- readonly script?: Partial<RuntimeSkillScriptPolicy>;
82
- }
83
-
84
- /**
85
- * 描述一个已准备 Extension。
86
- */
87
- export interface RuntimeExtensionContribution {
88
- readonly name: string;
89
- readonly extension: RuntimeExtensionConfig;
90
- }
91
-
92
- /**
93
- * 描述 Agent 对最终 Tool Surface 的可见性约束。
94
- *
95
- * Host 只提供策略;Runtime 在唯一 Tool Surface seam 中对所有
96
- * Port 和 Resource 生成的候选项统一应用。
97
- */
98
- export interface RuntimeToolSurfacePolicy {
99
- readonly denyPolicy?: RuntimeDenyPolicy;
100
- readonly allowsTool?: (name: string) => boolean;
101
- readonly allowsExtension?: (extension: RuntimeExtensionConfig) => boolean;
102
- }
103
-
104
- /** Host Planner 与 Runtime Assembler 之间唯一的一次性 seam。 */
63
+ export type {
64
+ RuntimeExtensionContribution,
65
+ RuntimeProfileContribution,
66
+ RuntimeSkillContribution,
67
+ RuntimeToolSurfacePolicy,
68
+ } from "./runtime-definition";
69
+
70
+ /** Host Planner Runtime Assembler 之间的一次性内部 seam。 */
105
71
  export interface RuntimeAssemblyInput {
106
72
  readonly profile: RuntimeProfileContribution;
107
73
  readonly memoryProfile: RuntimeMemoryProfile;
@@ -147,6 +113,8 @@ export interface RuntimeSnapshot {
147
113
  export interface RuntimeCandidate {
148
114
  readonly snapshot: RuntimeSnapshot;
149
115
  readonly commitGuards: readonly (() => Promise<void>)[];
116
+ readonly hooks?: RuntimeAgentHooks<Cloudflare.Env, unknown, never, never>;
117
+ readonly turnEvents?: RuntimeTurnEventsPort;
150
118
  }
151
119
 
152
120
  const DISABLED_MEMORY: RuntimeMemoryProfile = Object.freeze({
@@ -187,12 +155,8 @@ interface ToolSurfaceInput {
187
155
  readonly port: RuntimeMemoryPort;
188
156
  readonly profile: RuntimeMemoryProfile;
189
157
  };
190
- readonly codeExecution?: RuntimeCodeExecutionPort;
191
- readonly sandbox?: RuntimeSandboxPort;
192
158
  readonly hostTools: readonly PiToolCandidate[];
193
159
  readonly skills: readonly RuntimeSkillSourceBinding[];
194
- readonly schedule?: RuntimeSchedulePort;
195
- readonly subagents?: RuntimeSubagentPort;
196
160
  readonly enabledSubagents: readonly string[];
197
161
  readonly webSearch: Parameters<typeof basePiToolCandidates>[0];
198
162
  readonly extensions: readonly RuntimeExtensionConfig[];
@@ -205,7 +169,7 @@ interface ToolSurface {
205
169
  readonly degradations: readonly RuntimeDegradation[];
206
170
  }
207
171
 
208
- // 唯一 Tool Surface seam:只读取已授权 Port、Resource 和 Agent policy,
172
+ // 唯一 Tool Surface seam:只读取已配置 Port、Resource 和 Agent policy,
209
173
  // 统一生成可见 Tool,并在一处做名称、执行档位与冲突校验。
210
174
  async function createToolSurface(
211
175
  input: ToolSurfaceInput,
@@ -214,68 +178,41 @@ async function createToolSurface(
214
178
  const allowsTool = input.policy?.allowsTool;
215
179
  const allowsExtension = input.policy?.allowsExtension;
216
180
  const visible = (candidate: PiToolCandidate) =>
217
- candidate.authorized &&
218
181
  !deny.has(candidate.tool.name) &&
219
182
  allowsTool?.(candidate.tool.name) !== false;
220
183
  const browserCandidates = input.platform.browser
221
184
  ? browserQuickActionPiToolCandidates(input.platform.browser)
222
185
  : [];
223
- const workspaceCandidates = input.workspace
224
- ? workspacePiToolCandidates(input.workspace)
225
- : [];
226
- const executionCandidates = input.workspace && input.codeExecution
227
- ? [codeExecutionPiToolCandidate(input.codeExecution)]
228
- : [];
229
- const sandboxCandidates = input.sandbox
230
- ? sandboxPiToolCandidates(input.sandbox)
231
- : [];
232
- const subagentCandidates = subagentPiToolCandidates(
233
- input.subagents,
234
- input.enabledSubagents,
235
- );
236
- const scheduleCandidates = input.schedule
237
- ? schedulePiToolCandidates(input.schedule)
238
- : [];
239
186
  const baseCandidates = basePiToolCandidates(input.webSearch);
240
187
  const memoryCandidates = input.memory
241
188
  ? [memoryPiToolCandidate(input.memory.port, input.memory.profile)]
242
189
  : [];
243
190
  const scriptCandidates = [
244
191
  ...browserCandidates,
245
- ...workspaceCandidates,
246
- ...executionCandidates,
247
- ...sandboxCandidates,
248
192
  ...input.hostTools,
249
- ...scheduleCandidates,
250
- ...subagentCandidates,
251
193
  ...baseCandidates,
252
194
  ...memoryCandidates,
253
195
  ].filter(visible);
254
196
  const staticCandidates = [
255
197
  ...browserCandidates,
256
- ...workspaceCandidates,
257
- ...executionCandidates,
258
- ...sandboxCandidates,
259
198
  ...input.hostTools,
260
199
  ...(await skillPiToolCandidates(input.skills, {
261
200
  loader: input.platform.loader,
262
201
  ...(input.workspace ? { workspace: input.workspace } : {}),
263
202
  tools: scriptCandidates,
264
203
  })),
265
- ...scheduleCandidates,
266
- ...subagentCandidates,
267
204
  ...baseCandidates,
268
205
  ...memoryCandidates,
269
206
  ];
270
207
 
271
208
  return {
272
209
  surface: Object.freeze({
273
- finalize(authorizedCandidates: readonly PiToolCandidate[]) {
210
+ finalize(candidates: readonly PiToolCandidate[]) {
274
211
  const tools = new Map<string, PiToolCandidate>();
275
212
 
276
213
  for (const candidate of [
277
214
  ...staticCandidates,
278
- ...authorizedCandidates,
215
+ ...candidates,
279
216
  ]) {
280
217
  const name = requiredName(candidate.tool.name, "Pi Tool");
281
218
  if (!visible(candidate)) continue;
@@ -487,17 +424,7 @@ class RuntimeBuilder {
487
424
  assertMemoryProfile(this.memoryProfile);
488
425
  if (this.memoryProfile.enabled && (!this.workspace || !this.memory)) {
489
426
  throw new Error(
490
- "Enabled Runtime memory requires Workspace and Memory ports",
491
- );
492
- }
493
- if (this.sandbox && !this.workspace) {
494
- throw new Error(
495
- "Runtime Sandbox requires a persistent Workspace port",
496
- );
497
- }
498
- if (this.enabledSubagents.size > 0 && !this.subagents) {
499
- throw new Error(
500
- "Enabled Runtime Subagents require a Subagent port",
427
+ "Enabled Runtime memory requires Workspace and Memory bindings",
501
428
  );
502
429
  }
503
430
  const profile = freezeRuntimeProfile({
@@ -547,12 +474,8 @@ class RuntimeBuilder {
547
474
  ...(this.memoryProfile.enabled && this.memory
548
475
  ? { memory: { port: this.memory, profile: this.memoryProfile } }
549
476
  : {}),
550
- ...(this.codeExecution ? { codeExecution: this.codeExecution } : {}),
551
- ...(this.sandbox ? { sandbox: this.sandbox } : {}),
552
477
  hostTools: this.hostTools,
553
478
  skills: skillSources,
554
- ...(this.schedule ? { schedule: this.schedule } : {}),
555
- ...(this.subagents ? { subagents: this.subagents } : {}),
556
479
  enabledSubagents: [...this.enabledSubagents],
557
480
  webSearch,
558
481
  extensions: [...this.extensions.values()],
@@ -640,4 +563,233 @@ export async function assembleRuntime(
640
563
  commit(candidate.snapshot);
641
564
  }
642
565
 
566
+ export function toolRegistryPiToolCandidates(
567
+ registry: ToolRegistry,
568
+ settings?: Pick<RuntimeSettings, "toolPolicy">,
569
+ ): PiToolCandidate[] {
570
+ const deny = new Set(settings?.toolPolicy?.denyPolicy?.deny ?? []);
571
+ const allowsTool = settings?.toolPolicy?.allowsTool;
572
+ const candidates: PiToolCandidate[] = [];
573
+ for (const [name, spec] of Object.entries(registry)) {
574
+ if (deny.has(name)) continue;
575
+ if (allowsTool?.(name) === false) continue;
576
+ const normalized = requiredName(name, "Platform Tool");
577
+ candidates.push(Object.freeze({
578
+ owner: "platform",
579
+ requiredExecutionLevel: spec.requiredExecutionLevel,
580
+ ...(spec.alwaysRequiresApproval
581
+ ? { alwaysRequiresApproval: true }
582
+ : {}),
583
+ tool: Object.freeze({
584
+ name: normalized,
585
+ label: spec.label,
586
+ description: spec.description,
587
+ parameters: spec.parameters,
588
+ async execute(
589
+ toolCallId: string,
590
+ input: unknown,
591
+ signal?: AbortSignal,
592
+ ) {
593
+ const result = await spec.execute(input, {
594
+ toolCallId,
595
+ signal: signal ?? new AbortController().signal,
596
+ });
597
+ if (
598
+ result != null &&
599
+ typeof result === "object" &&
600
+ "content" in result &&
601
+ Array.isArray((result as { content?: unknown }).content)
602
+ ) {
603
+ return result as import("@earendil-works/pi-agent-core").AgentToolResult<unknown>;
604
+ }
605
+ let text: string;
606
+ try {
607
+ text = JSON.stringify(result) ?? String(result);
608
+ } catch {
609
+ text = String(result);
610
+ }
611
+ return {
612
+ content: [{ type: "text" as const, text }],
613
+ details: result,
614
+ };
615
+ },
616
+ } as AgentTool<any, any>),
617
+ }));
618
+ }
619
+ return candidates;
620
+ }
621
+
622
+ function hooksToTurnEventsPort<
623
+ Env extends Cloudflare.Env,
624
+ Config,
625
+ Command,
626
+ Change,
627
+ >(
628
+ ctx: AssembleRuntimeSnapshotInput<Env, Config, Command, Change>["ctx"],
629
+ hooks?: RuntimeAgentHooks<Env, Config, Command, Change>,
630
+ ): RuntimeTurnEventsPort | undefined {
631
+ if (!hooks) return undefined;
632
+ if (
633
+ !hooks.onTurnEnd &&
634
+ !hooks.onModelUsage &&
635
+ !hooks.onToolSettled &&
636
+ !hooks.onApproval &&
637
+ !hooks.onActivityChanged &&
638
+ !hooks.onSubmissionTerminal
639
+ ) {
640
+ return undefined;
641
+ }
642
+ return {
643
+ onResponse: hooks.onTurnEnd
644
+ ? (messages) => hooks.onTurnEnd!(ctx, messages)
645
+ : async () => undefined,
646
+ ...(hooks.onModelUsage ? { onModelUsage: hooks.onModelUsage } : {}),
647
+ ...(hooks.onToolSettled ? { onToolSettled: hooks.onToolSettled } : {}),
648
+ ...(hooks.onApproval ? { onApproval: hooks.onApproval } : {}),
649
+ ...(hooks.onActivityChanged
650
+ ? { onActivityChanged: hooks.onActivityChanged }
651
+ : {}),
652
+ ...(hooks.onSubmissionTerminal
653
+ ? { onSubmissionTerminal: hooks.onSubmissionTerminal }
654
+ : {}),
655
+ };
656
+ }
657
+
658
+ /**
659
+ * 从 Config、Tool 和已加载 Resource 装配 Runtime 候选 Snapshot。
660
+ *
661
+ * @internal
662
+ */
663
+ export async function assembleRuntimeSnapshot<
664
+ Env extends Cloudflare.Env,
665
+ Config,
666
+ Command = never,
667
+ Change = never,
668
+ >(
669
+ input: AssembleRuntimeSnapshotInput<Env, Config, Command, Change>,
670
+ ): Promise<RuntimeCandidate> {
671
+ const resources = input.resources;
672
+ const toolAssembly = input.tools;
673
+ const settings = resources.settings;
674
+ const provider = resources.provider;
675
+ let profile = settings.profile;
676
+ if (input.hooks?.profileOverrides) {
677
+ const overrides = await withRuntimeLoadTimeout(
678
+ "profile-overrides",
679
+ () => input.hooks!.profileOverrides!(
680
+ input.ctx,
681
+ input.config,
682
+ ),
683
+ );
684
+ if (overrides.systemPrompt !== undefined) {
685
+ profile = { ...profile, systemPrompt: overrides.systemPrompt };
686
+ }
687
+ if (overrides.executionLevel !== undefined) {
688
+ profile = { ...profile, executionLevel: overrides.executionLevel };
689
+ }
690
+ }
691
+
692
+ const hostTools = toolRegistryPiToolCandidates(
693
+ toolAssembly.tools,
694
+ settings,
695
+ );
696
+
697
+ const commitGuards: Array<() => Promise<void>> = [];
698
+ if (toolAssembly.commitGuard) commitGuards.push(toolAssembly.commitGuard);
699
+ if (input.hooks?.beforeCommit) {
700
+ for (const guard of input.hooks.beforeCommit) {
701
+ commitGuards.push(() => guard(input.ctx, input.config));
702
+ }
703
+ }
704
+
705
+ const platform: RuntimePlatformPort = input.hooks?.gateTool
706
+ ? Object.freeze({
707
+ ...resources.platform,
708
+ gateTool: (request: {
709
+ toolCallId: string;
710
+ toolName: string;
711
+ input: unknown;
712
+ requiredExecutionLevel: import("./lib/execution-level").ExecutionLevel;
713
+ signal: AbortSignal;
714
+ }) => input.hooks!.gateTool!(request),
715
+ })
716
+ : resources.platform;
717
+
718
+ const memoryProfile =
719
+ toolAssembly.memoryProfile ?? settings.memoryProfile;
720
+ const enabledSubagents =
721
+ toolAssembly.enabledSubagents ?? settings.enabledSubagents;
722
+ const turnEvents = hooksToTurnEventsPort(input.ctx, input.hooks);
723
+
724
+ const toolPolicy: RuntimeToolSurfacePolicy | undefined =
725
+ settings.toolPolicy || toolAssembly.surfacePolicy
726
+ ? {
727
+ ...(settings.toolPolicy?.denyPolicy
728
+ ? { denyPolicy: settings.toolPolicy.denyPolicy }
729
+ : {}),
730
+ ...(settings.toolPolicy?.allowsTool
731
+ ? { allowsTool: settings.toolPolicy.allowsTool }
732
+ : {}),
733
+ ...(settings.toolPolicy?.allowsExtension
734
+ ? { allowsExtension: settings.toolPolicy.allowsExtension }
735
+ : {}),
736
+ ...(toolAssembly.surfacePolicy?.allowsTool
737
+ ? { allowsTool: toolAssembly.surfacePolicy.allowsTool }
738
+ : {}),
739
+ ...(toolAssembly.surfacePolicy?.allowsExtension
740
+ ? { allowsExtension: toolAssembly.surfacePolicy.allowsExtension }
741
+ : {}),
742
+ }
743
+ : undefined;
744
+
745
+ const assemblyInput: RuntimeAssemblyInput = {
746
+ profile,
747
+ memoryProfile,
748
+ ...(toolPolicy ? { toolPolicy } : {}),
749
+ enabledSubagents: [...enabledSubagents],
750
+ provider,
751
+ platform,
752
+ ...(toolAssembly.bindings?.workspace
753
+ ? { workspace: toolAssembly.bindings.workspace }
754
+ : {}),
755
+ ...(memoryProfile.enabled && toolAssembly.bindings?.memory
756
+ ? { memory: toolAssembly.bindings.memory }
757
+ : {}),
758
+ hostTools,
759
+ skills: resources.skills,
760
+ connectors: resources.connectors.servers,
761
+ ...(resources.connectors.gateway
762
+ ? { gateway: resources.connectors.gateway }
763
+ : {}),
764
+ extensions: resources.extensions,
765
+ ...(turnEvents ? { turnEvents } : {}),
766
+ commitGuards: [],
767
+ degradations: [
768
+ ...(toolAssembly.degradations ?? []),
769
+ ...(resources.degradations ?? []),
770
+ ...resources.connectors.degradations,
771
+ ],
772
+ };
773
+
774
+ const candidate = await prepareRuntimeCandidate(assemblyInput);
775
+ return Object.freeze({
776
+ snapshot: candidate.snapshot,
777
+ commitGuards: Object.freeze([
778
+ ...candidate.commitGuards,
779
+ ...commitGuards,
780
+ ]),
781
+ ...(input.hooks
782
+ ? {
783
+ hooks: input.hooks as unknown as RuntimeAgentHooks<
784
+ Cloudflare.Env,
785
+ unknown,
786
+ never,
787
+ never
788
+ >,
789
+ }
790
+ : {}),
791
+ ...(turnEvents ? { turnEvents } : {}),
792
+ });
793
+ }
794
+
643
795
  // #endregion
@@ -0,0 +1,173 @@
1
+ import type { SkillSource } from "agents/skills";
2
+ import type { ExecutionLevel } from "./lib/execution-level";
3
+ import type {
4
+ RuntimeGatewayPort,
5
+ RuntimeModelUsageEvent,
6
+ RuntimePlatformPort,
7
+ RuntimeProviderPort,
8
+ RuntimeSkillScriptPolicy,
9
+ RuntimeTurnMessage,
10
+ } from "./kernel/bindings";
11
+ import type {
12
+ RuntimeDenyPolicy,
13
+ RuntimeMcpServer,
14
+ RuntimeMemoryProfile,
15
+ ThinkingEffort,
16
+ } from "./kernel/profile";
17
+ import type { RuntimeExtensionConfig } from "./kernel/extensions";
18
+ import type { RuntimeActivityProjection } from "./kernel/state";
19
+ import type { RuntimeDegradation } from "./kernel/degradation";
20
+ import type {
21
+ RuntimeAgentContext,
22
+ RuntimeAssemblyContext,
23
+ RuntimeAgentPlanningContext,
24
+ } from "./runtime-agent-context";
25
+
26
+ export interface RuntimeProfileContribution {
27
+ readonly model: string;
28
+ readonly thinking: ThinkingEffort;
29
+ readonly systemPrompt?: string;
30
+ readonly executionLevel: ExecutionLevel;
31
+ }
32
+
33
+ export interface RuntimeSkillContribution {
34
+ readonly name: string;
35
+ readonly description: string;
36
+ readonly source: SkillSource;
37
+ readonly script?: Partial<RuntimeSkillScriptPolicy>;
38
+ }
39
+
40
+ export interface RuntimeExtensionContribution {
41
+ readonly name: string;
42
+ readonly extension: RuntimeExtensionConfig;
43
+ }
44
+
45
+ export interface RuntimeToolSurfacePolicy {
46
+ readonly denyPolicy?: RuntimeDenyPolicy;
47
+ readonly allowsTool?: (name: string) => boolean;
48
+ readonly allowsExtension?: (extension: RuntimeExtensionConfig) => boolean;
49
+ }
50
+
51
+ export type { RuntimeAgentContext, RuntimeAssemblyContext } from "./runtime-agent-context";
52
+
53
+ export interface GateToolRequest {
54
+ readonly toolCallId: string;
55
+ readonly toolName: string;
56
+ readonly input: unknown;
57
+ readonly requiredExecutionLevel: ExecutionLevel;
58
+ readonly signal: AbortSignal;
59
+ }
60
+
61
+ export type {
62
+ PlatformToolContext,
63
+ PlatformToolRegistry,
64
+ PlatformToolSpec,
65
+ RuntimeToolBindings,
66
+ ToolAssemblyResult,
67
+ ToolContext,
68
+ ToolRegistry,
69
+ ToolSpec,
70
+ } from "./tool-registry";
71
+ export {
72
+ emptyPlatformToolRegistry,
73
+ emptyToolRegistry,
74
+ mergeToolRegistries,
75
+ normalizeToolAssembly,
76
+ toolRegistryFromPiCandidates,
77
+ } from "./tool-registry";
78
+
79
+ export interface ResolvedConnectors {
80
+ readonly servers: readonly RuntimeMcpServer[];
81
+ readonly gateway?: RuntimeGatewayPort;
82
+ readonly degradations: readonly RuntimeDegradation[];
83
+ }
84
+
85
+ export interface ResolvedResources {
86
+ readonly settings: RuntimeSettings;
87
+ readonly provider: RuntimeProviderPort;
88
+ readonly platform: RuntimePlatformPort;
89
+ readonly skills: readonly RuntimeSkillContribution[];
90
+ readonly extensions: readonly RuntimeExtensionContribution[];
91
+ readonly connectors: ResolvedConnectors;
92
+ readonly degradations?: readonly RuntimeDegradation[];
93
+ }
94
+
95
+ export interface ProfileOverrides {
96
+ readonly systemPrompt?: string;
97
+ readonly executionLevel?: ExecutionLevel;
98
+ }
99
+
100
+ export interface ApprovalHookInput {
101
+ readonly submissionId: string;
102
+ readonly approvalExecutionId: string;
103
+ }
104
+
105
+ export interface SubmissionTerminalHookInput {
106
+ readonly submissionId: string;
107
+ readonly status: "completed" | "aborted" | "skipped" | "error";
108
+ readonly error?: string;
109
+ readonly resultMessageId?: string;
110
+ }
111
+
112
+ export interface RuntimeToolSettlementEvent {
113
+ readonly eventId: string;
114
+ readonly submissionId: string;
115
+ readonly toolCallId: string;
116
+ readonly toolName: string;
117
+ readonly status: "success" | "error";
118
+ }
119
+
120
+ export interface RuntimeAgentHooks<
121
+ Env extends Cloudflare.Env = Cloudflare.Env,
122
+ Config = unknown,
123
+ Command = never,
124
+ Change = never,
125
+ > {
126
+ readonly beforeCommit?: ReadonlyArray<
127
+ (
128
+ ctx: RuntimeAssemblyContext<Env, Command, Change>,
129
+ config: Config,
130
+ ) => Promise<void>
131
+ >;
132
+
133
+ readonly onTurnEnd?: (
134
+ ctx: RuntimeAssemblyContext<Env, Command, Change>,
135
+ messages: readonly RuntimeTurnMessage[],
136
+ ) => Promise<void>;
137
+ readonly onModelUsage?: (event: RuntimeModelUsageEvent) => Promise<void>;
138
+ readonly onToolSettled?: (event: RuntimeToolSettlementEvent) => Promise<void>;
139
+ readonly onApproval?: (input: ApprovalHookInput) => Promise<void>;
140
+ readonly onActivityChanged?: (
141
+ projection: RuntimeActivityProjection,
142
+ ) => Promise<void>;
143
+ readonly onSubmissionTerminal?: (
144
+ input: SubmissionTerminalHookInput,
145
+ ) => Promise<void>;
146
+
147
+ readonly gateTool?: (request: GateToolRequest) => Promise<void>;
148
+
149
+ readonly profileOverrides?: (
150
+ ctx: RuntimeAssemblyContext<Env, Command, Change>,
151
+ config: Config,
152
+ ) => ProfileOverrides | Promise<ProfileOverrides>;
153
+ }
154
+
155
+ export interface RuntimeSettings {
156
+ readonly profile: RuntimeProfileContribution;
157
+ readonly memoryProfile: RuntimeMemoryProfile;
158
+ readonly toolPolicy?: RuntimeToolSurfacePolicy;
159
+ readonly enabledSubagents: readonly string[];
160
+ }
161
+
162
+ export interface AssembleRuntimeSnapshotInput<
163
+ Env extends Cloudflare.Env,
164
+ Config,
165
+ Command = never,
166
+ Change = never,
167
+ > {
168
+ readonly ctx: RuntimeAgentPlanningContext<Env, Command, Change>;
169
+ readonly config: Config;
170
+ readonly tools: import("./tool-registry").ToolAssemblyResult;
171
+ readonly resources: ResolvedResources;
172
+ readonly hooks?: RuntimeAgentHooks<Env, Config, Command, Change>;
173
+ }