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

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.
@@ -1,6 +1,7 @@
1
1
  import type { SkillSource } from "agents/skills";
2
2
  import type {
3
3
  RuntimeCodeExecutionPort,
4
+ RuntimeGatewayPort,
4
5
  RuntimeMemoryPort,
5
6
  RuntimePlatformPort,
6
7
  RuntimeProviderPort,
@@ -51,38 +52,7 @@ import { subagentPiToolCandidates } from "./pi/tool/subagent";
51
52
  import { createWebSearch } from "./pi/tool/web-search";
52
53
  import { resolvePiModel } from "./pi/runtime-adapter/models";
53
54
 
54
- /**
55
- * 本文件实现 Plugin 的准备、声明合并、校验和原子候选装配。
56
- *
57
- * @remarks
58
- * 核心术语见包入口 `index.ts`,这里不重复定义。
59
- */
60
-
61
- // #region Plugin 公开契约
62
-
63
- /**
64
- * 标明一个 Plugin 负责哪一类能力。
65
- *
66
- * @remarks
67
- * 应用创建 Plugin 时必须选择其中一个值。
68
- *
69
- * Runtime 用它拒绝重复能力并确定贡献顺序,所以不要把它当作自由文本。
70
- */
71
- export type PluginKind =
72
- | "scope"
73
- | "profile"
74
- | "provider"
75
- | "platform"
76
- | "workspace"
77
- | "sandbox"
78
- | "memory"
79
- | "tool"
80
- | "skill"
81
- | "connector"
82
- | "extension"
83
- | "schedule"
84
- | "subagent"
85
- | "turn-events";
55
+ /** Runtime Assembler:校验一份扁平输入并生成可原子提交的 Snapshot。 */
86
56
 
87
57
  export type { RuntimeDegradation } from "./kernel/degradation";
88
58
 
@@ -90,7 +60,7 @@ export type { RuntimeDegradation } from "./kernel/degradation";
90
60
  * 提供 Runtime 核心运行参数。
91
61
  *
92
62
  * @remarks
93
- * `profile` Plugin 在准备结果中返回它。
63
+ * Host Planner 在装配输入中提供它。
94
64
  *
95
65
  * 这里只放业务可配置字段,冻结和最终结构由 Runtime 负责。
96
66
  */
@@ -131,113 +101,31 @@ export interface RuntimeToolSurfacePolicy {
131
101
  readonly allowsExtension?: (extension: RuntimeExtensionConfig) => boolean;
132
102
  }
133
103
 
134
- interface PluginResultByKind {
135
- readonly scope: {
136
- readonly commitGuards: readonly (() => Promise<void>)[];
137
- };
138
- readonly profile: { readonly profile: RuntimeProfileContribution };
139
- readonly provider: { readonly provider: RuntimeProviderPort };
140
- readonly platform: {
141
- readonly platform: RuntimePlatformPort;
142
- };
143
- readonly workspace: {
144
- readonly workspace?: WorkspacePort;
145
- readonly codeExecution?: RuntimeCodeExecutionPort;
146
- };
147
- readonly sandbox: {
148
- readonly sandbox?: RuntimeSandboxPort;
149
- };
150
- readonly memory: {
151
- readonly memoryProfile: RuntimeMemoryProfile;
152
- readonly memoryPort?: RuntimeMemoryPort;
153
- };
154
- readonly tool: {
155
- readonly hostTools: readonly PiToolCandidate[];
156
- readonly policy?: RuntimeToolSurfacePolicy;
157
- };
158
- readonly skill: {
159
- readonly skills: readonly RuntimeSkillContribution[];
160
- };
161
- readonly connector: {
162
- readonly connectors: readonly RuntimeMcpServer[];
163
- };
164
- readonly extension: {
165
- readonly extensions: readonly RuntimeExtensionContribution[];
166
- };
167
- readonly schedule: {
168
- readonly schedule: RuntimeSchedulePort;
169
- };
170
- readonly subagent: {
171
- readonly enabledSubagents: readonly string[];
172
- readonly subagents?: RuntimeSubagentPort;
173
- };
174
- readonly "turn-events": {
175
- readonly turnEvents: RuntimeTurnEventsPort;
176
- };
177
- }
178
-
179
- export type PluginPreparation<K extends PluginKind> = Readonly<
180
- PluginResultByKind[K] & {
181
- readonly degradations: readonly RuntimeDegradation[];
182
- }
183
- >;
184
-
185
- export type PreparedPlugin<K extends PluginKind = PluginKind> =
186
- K extends PluginKind
187
- ? Readonly<PluginPreparation<K> & { readonly kind: K }>
188
- : never;
189
-
190
- interface AgentPluginContract<K extends PluginKind> {
191
- readonly kind: K;
192
- prepare(): Promise<PreparedPlugin<K>>;
193
- }
194
-
195
- export type AgentPlugin<K extends PluginKind = PluginKind> =
196
- K extends PluginKind ? AgentPluginContract<K> : never;
197
-
198
- export interface AgentPluginSpec<K extends PluginKind> {
199
- readonly kind: K;
200
- prepare(): Promise<PluginPreparation<K>>;
201
- }
202
-
203
- /**
204
- * 汇总一次 Runtime 装配要使用的全部 Plugin。
205
- */
206
- export interface AgentConfig {
207
- readonly plugins: readonly AgentPlugin[];
208
- }
209
-
210
- /**
211
- * 定义一个只准备声明式结果的 Runtime Plugin。
212
- *
213
- * Runtime 内部负责排序、合并、冲突检查和提交。
214
- */
215
- export function definePlugin<K extends PluginKind>(
216
- spec: AgentPluginSpec<K>,
217
- ): AgentPlugin<K> {
218
- return Object.freeze({
219
- kind: spec.kind,
220
-
221
- async prepare(): Promise<PreparedPlugin<K>> {
222
- const prepared = await spec.prepare();
223
- const degradations = Object.freeze(
224
- prepared.degradations.map((degradation) =>
225
- Object.freeze({ ...degradation }),
226
- ),
227
- );
228
-
229
- return Object.freeze({
230
- ...prepared,
231
- kind: spec.kind,
232
- degradations,
233
- }) as PreparedPlugin<K>;
234
- },
235
- }) as AgentPlugin<K>;
104
+ /** Host Planner 与 Runtime Assembler 之间唯一的一次性 seam。 */
105
+ export interface RuntimeAssemblyInput {
106
+ readonly profile: RuntimeProfileContribution;
107
+ readonly memoryProfile: RuntimeMemoryProfile;
108
+ readonly toolPolicy?: RuntimeToolSurfacePolicy;
109
+ readonly enabledSubagents: readonly string[];
110
+ readonly provider: RuntimeProviderPort;
111
+ readonly platform: RuntimePlatformPort;
112
+ readonly workspace?: WorkspacePort;
113
+ readonly codeExecution?: RuntimeCodeExecutionPort;
114
+ readonly sandbox?: RuntimeSandboxPort;
115
+ readonly memory?: RuntimeMemoryPort;
116
+ readonly hostTools: readonly PiToolCandidate[];
117
+ readonly skills: readonly RuntimeSkillContribution[];
118
+ readonly connectors: readonly RuntimeMcpServer[];
119
+ readonly gateway?: RuntimeGatewayPort;
120
+ readonly extensions: readonly RuntimeExtensionContribution[];
121
+ readonly subagents?: RuntimeSubagentPort;
122
+ readonly schedule?: RuntimeSchedulePort;
123
+ readonly turnEvents?: RuntimeTurnEventsPort;
124
+ readonly commitGuards: readonly (() => Promise<void>)[];
125
+ readonly degradations: readonly RuntimeDegradation[];
236
126
  }
237
127
 
238
- // #endregion
239
-
240
- // #region 内部候选契约与装配顺序
128
+ // #region 内部候选契约
241
129
 
242
130
  /**
243
131
  * 保存一次已经完成校验、可供 Kernel 使用的 Runtime 结果。
@@ -261,29 +149,6 @@ export interface RuntimeCandidate {
261
149
  readonly commitGuards: readonly (() => Promise<void>)[];
262
150
  }
263
151
 
264
- const PLUGIN_ORDER: readonly PluginKind[] = Object.freeze([
265
- "scope",
266
- "profile",
267
- "provider",
268
- "platform",
269
- "workspace",
270
- "sandbox",
271
- "memory",
272
- "tool",
273
- "skill",
274
- "connector",
275
- "extension",
276
- "schedule",
277
- "subagent",
278
- "turn-events",
279
- ]);
280
-
281
- const REQUIRED_PLUGIN_KINDS: readonly PluginKind[] = Object.freeze([
282
- "profile",
283
- "provider",
284
- "platform",
285
- ]);
286
-
287
152
  const DISABLED_MEMORY: RuntimeMemoryProfile = Object.freeze({
288
153
  enabled: false,
289
154
  memoryTokens: 2_000,
@@ -441,6 +306,7 @@ class RuntimeBuilder {
441
306
  private profile?: RuntimeProfileContribution;
442
307
  private provider?: RuntimeProviderPort;
443
308
  private platform?: RuntimePlatformPort;
309
+ private gateway?: RuntimeGatewayPort;
444
310
  private workspace?: WorkspacePort;
445
311
  private codeExecution?: RuntimeCodeExecutionPort;
446
312
  private sandbox?: RuntimeSandboxPort;
@@ -466,68 +332,36 @@ class RuntimeBuilder {
466
332
  private readonly commitGuards: Array<() => Promise<void>> = [];
467
333
  private readonly degradations: RuntimeDegradation[] = [];
468
334
 
469
- merge(prepared: PreparedPlugin): void {
470
- for (const degradation of prepared.degradations) {
335
+ merge(input: RuntimeAssemblyInput): void {
336
+ for (const degradation of input.degradations) {
471
337
  this.reportDegradation(degradation);
472
338
  }
473
-
474
- switch (prepared.kind) {
475
- case "scope":
476
- this.commitGuards.push(...prepared.commitGuards);
477
- break;
478
- case "profile":
479
- if (!EXECUTION_LEVELS.includes(prepared.profile.executionLevel)) {
480
- throw new Error("Runtime execution level is invalid");
481
- }
482
- this.profile = prepared.profile;
483
- break;
484
- case "provider":
485
- this.provider = prepared.provider;
486
- break;
487
- case "platform":
488
- this.platform = prepared.platform;
489
- break;
490
- case "workspace":
491
- this.workspace = prepared.workspace;
492
- this.codeExecution = prepared.codeExecution;
493
- break;
494
- case "sandbox":
495
- this.sandbox = prepared.sandbox;
496
- break;
497
- case "memory":
498
- this.memoryProfile = prepared.memoryProfile;
499
- this.memory = prepared.memoryPort;
500
- break;
501
- case "tool":
502
- this.hostTools.push(...prepared.hostTools);
503
- this.toolPolicy = prepared.policy;
504
- break;
505
- case "skill":
506
- for (const skill of prepared.skills) this.addSkill(skill);
507
- break;
508
- case "connector":
509
- for (const connector of prepared.connectors) {
510
- this.addConnector(connector);
511
- }
512
- break;
513
- case "extension":
514
- for (const { name, extension } of prepared.extensions) {
515
- this.addExtension(name, extension);
516
- }
517
- break;
518
- case "schedule":
519
- this.schedule = prepared.schedule;
520
- break;
521
- case "subagent":
522
- for (const name of prepared.enabledSubagents) {
523
- this.enabledSubagents.add(requiredName(name, "Subagent"));
524
- }
525
- this.subagents = prepared.subagents;
526
- break;
527
- case "turn-events":
528
- this.turnEvents = prepared.turnEvents;
529
- break;
339
+ if (!EXECUTION_LEVELS.includes(input.profile.executionLevel)) {
340
+ throw new Error("Runtime execution level is invalid");
530
341
  }
342
+ this.profile = input.profile;
343
+ this.provider = input.provider;
344
+ this.platform = input.platform;
345
+ this.workspace = input.workspace;
346
+ this.codeExecution = input.codeExecution;
347
+ this.sandbox = input.sandbox;
348
+ this.memoryProfile = input.memoryProfile;
349
+ this.memory = input.memory;
350
+ this.hostTools.push(...input.hostTools);
351
+ this.toolPolicy = input.toolPolicy;
352
+ for (const skill of input.skills) this.addSkill(skill);
353
+ for (const connector of input.connectors) this.addConnector(connector);
354
+ this.gateway = input.gateway;
355
+ for (const { name, extension } of input.extensions) {
356
+ this.addExtension(name, extension);
357
+ }
358
+ this.schedule = input.schedule;
359
+ for (const name of input.enabledSubagents) {
360
+ this.enabledSubagents.add(requiredName(name, "Subagent"));
361
+ }
362
+ this.subagents = input.subagents;
363
+ this.turnEvents = input.turnEvents;
364
+ this.commitGuards.push(...input.commitGuards);
531
365
  }
532
366
 
533
367
  private addSkill(skill: RuntimeSkillContribution): void {
@@ -614,17 +448,17 @@ class RuntimeBuilder {
614
448
  // #region RuntimeBuilder 校验与候选生成
615
449
 
616
450
  // 作用:校验全部声明,并生成一个不可变候选 Runtime。
617
- // 调用:所有 Plugin 按固定顺序完成合并后调用一次。
451
+ // 调用:扁平 Assembly Input 合并完成后调用一次。
618
452
  // 原因:所有交叉约束都在这里通过后才返回候选,旧 Snapshot 不会半更新。
619
453
  async build(): Promise<RuntimeCandidate> {
620
454
  if (!this.profile) {
621
- throw new Error("Runtime profile Plugin did not configure a profile");
455
+ throw new Error("Runtime assembly did not configure a profile");
622
456
  }
623
457
  if (!this.platform) {
624
- throw new Error("Runtime platform Plugin did not bind a platform");
458
+ throw new Error("Runtime assembly did not bind a platform");
625
459
  }
626
460
  if (!this.provider) {
627
- throw new Error("Runtime provider Plugin did not bind a provider");
461
+ throw new Error("Runtime assembly did not bind a provider");
628
462
  }
629
463
  if (!this.profile.model.trim()) {
630
464
  throw new Error("Runtime model must not be empty");
@@ -730,6 +564,7 @@ class RuntimeBuilder {
730
564
  const bindings: RuntimeBindings = Object.freeze({
731
565
  provider,
732
566
  platform: Object.freeze({ ...this.platform }),
567
+ ...(this.gateway ? { gateway: this.gateway } : {}),
733
568
  ...(this.workspace ? { workspace: this.workspace } : {}),
734
569
  ...(this.memoryProfile.enabled && this.memory
735
570
  ? { memory: this.memory }
@@ -764,75 +599,23 @@ class RuntimeBuilder {
764
599
 
765
600
  }
766
601
 
767
- // 作用:检查 Plugin kind 合法、唯一,并包含所有必需能力。
768
- // 调用:任何 prepare 启动前由 `prepareRuntimeCandidate` 调用。
769
- // 原因:先校验结构可避免为注定失败的配置执行外部读取。
770
- function validatePluginKinds(
771
- plugins: readonly AgentPlugin[],
772
- ): void {
773
- const kinds = new Set<PluginKind>();
774
- const knownKinds = new Set(PLUGIN_ORDER);
775
-
776
- for (const plugin of plugins) {
777
- if (!knownKinds.has(plugin.kind)) {
778
- throw new Error(`Unknown Agent Plugin kind: ${plugin.kind}`);
779
- }
780
- if (kinds.has(plugin.kind)) {
781
- throw new Error(
782
- `Duplicate Agent Plugin kind: ${plugin.kind}`,
783
- );
784
- }
785
- kinds.add(plugin.kind);
786
- }
787
-
788
- for (const required of REQUIRED_PLUGIN_KINDS) {
789
- if (!kinds.has(required)) {
790
- throw new Error(
791
- `Missing required Agent Plugin: ${required}`,
792
- );
793
- }
794
- }
795
- }
796
-
797
602
  /**
798
603
  * 在不改动当前 Runtime 的前提下生成一个隔离候选。
799
604
  *
800
605
  * @remarks
801
606
  * `AgentRuntimeKernel` 在初始化或重载时调用它。
802
607
  *
803
- * prepare 并行执行,声明按固定 kind 顺序合并,任何失败都不会产生 commit。
608
+ * 任何合并、校验或 Tool Surface 构建失败都不会产生 commit。
804
609
  *
805
610
  * 该函数有意不从包入口导出,提交生命周期只能由 Kernel 控制。
806
611
  *
807
612
  * @internal
808
613
  */
809
614
  export async function prepareRuntimeCandidate(
810
- config: AgentConfig,
615
+ input: RuntimeAssemblyInput,
811
616
  ): Promise<RuntimeCandidate> {
812
- validatePluginKinds(config.plugins);
813
-
814
- const prepared = await Promise.all(
815
- config.plugins.map(async (plugin) => {
816
- const result = await plugin.prepare();
817
- if (result.kind !== plugin.kind) {
818
- throw new Error(
819
- `Prepared Agent Plugin kind mismatch: expected ${plugin.kind}, got ${result.kind}`,
820
- );
821
- }
822
- return result;
823
- }),
824
- );
825
- const byKind = new Map(
826
- prepared.map((plugin) => [plugin.kind, plugin]),
827
- );
828
617
  const builder = new RuntimeBuilder();
829
-
830
- for (const kind of PLUGIN_ORDER) {
831
- const plugin = byKind.get(kind);
832
- if (!plugin) continue;
833
- builder.merge(plugin);
834
- }
835
-
618
+ builder.merge(input);
836
619
  return builder.build();
837
620
  }
838
621
 
@@ -846,11 +629,11 @@ export async function prepareRuntimeCandidate(
846
629
  *
847
630
  * @internal
848
631
  */
849
- export async function initializeRuntimeConfig(
850
- config: AgentConfig,
632
+ export async function assembleRuntime(
633
+ input: RuntimeAssemblyInput,
851
634
  commit: (snapshot: RuntimeSnapshot) => void,
852
635
  ): Promise<void> {
853
- const candidate = await prepareRuntimeCandidate(config);
636
+ const candidate = await prepareRuntimeCandidate(input);
854
637
  for (const guard of candidate.commitGuards) {
855
638
  await guard();
856
639
  }