@springbrand/agent-runtime 0.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/package.json +28 -0
- package/src/db/approval.repo.ts +291 -0
- package/src/db/ext-context.repo.ts +34 -0
- package/src/db/index.ts +83 -0
- package/src/db/message-ui.repo.ts +39 -0
- package/src/db/milestone.repo.ts +96 -0
- package/src/db/runtime-event-outbox.repo.ts +89 -0
- package/src/db/schema.ts +164 -0
- package/src/db/settlement.repo.ts +104 -0
- package/src/db/steer.repo.ts +73 -0
- package/src/db/submission.repo.ts +323 -0
- package/src/index.ts +133 -0
- package/src/kernel/approval-lifecycle.ts +552 -0
- package/src/kernel/bindings.ts +898 -0
- package/src/kernel/degradation.ts +15 -0
- package/src/kernel/extensions.ts +108 -0
- package/src/kernel/profile.ts +116 -0
- package/src/kernel/public-contracts.ts +17 -0
- package/src/kernel/receipts.ts +124 -0
- package/src/kernel/recoverable-chat-agent.ts +899 -0
- package/src/kernel/state.ts +76 -0
- package/src/kernel/submission-lifecycle.ts +600 -0
- package/src/layers/context/budget/gate.ts +88 -0
- package/src/layers/orchestration/subagents/agent-types/contract.ts +78 -0
- package/src/layers/orchestration/subagents/agent-types/extract/index.ts +47 -0
- package/src/layers/orchestration/subagents/agent-types/fanout/index.ts +53 -0
- package/src/layers/orchestration/subagents/agent-types/registry.ts +16 -0
- package/src/layers/orchestration/temporary-agent/core.ts +152 -0
- package/src/layers/orchestration/temporary-agent/runner.ts +133 -0
- package/src/layers/orchestration/temporary-agent/workspace.ts +154 -0
- package/src/lib/artifacts.ts +54 -0
- package/src/lib/egress.ts +44 -0
- package/src/lib/execution-level.ts +27 -0
- package/src/lib/extension-name.ts +18 -0
- package/src/lib/host-actions.ts +57 -0
- package/src/lib/mcp.ts +86 -0
- package/src/lib/model-catalog.ts +7 -0
- package/src/lib/prompt.ts +139 -0
- package/src/lib/telemetry-dev.ts +44 -0
- package/src/pi/assembly/context.ts +510 -0
- package/src/pi/assembly/extensions.ts +661 -0
- package/src/pi/assembly/index.ts +19 -0
- package/src/pi/assembly/snapshot.ts +200 -0
- package/src/pi/message/contract.ts +8 -0
- package/src/pi/message/conversion.ts +73 -0
- package/src/pi/message/index.ts +3 -0
- package/src/pi/message/projection.ts +604 -0
- package/src/pi/runtime-adapter/assembly.ts +552 -0
- package/src/pi/runtime-adapter/execution.ts +683 -0
- package/src/pi/runtime-adapter/index.ts +232 -0
- package/src/pi/runtime-adapter/models.ts +243 -0
- package/src/pi/runtime-adapter/recovery.ts +805 -0
- package/src/pi/runtime-adapter/transcript.ts +825 -0
- package/src/pi/session/index.ts +24 -0
- package/src/pi/session/storage.ts +353 -0
- package/src/pi/tool/ai-adapter.ts +100 -0
- package/src/pi/tool/base.ts +110 -0
- package/src/pi/tool/compiler.ts +444 -0
- package/src/pi/tool/core-host.ts +48 -0
- package/src/pi/tool/core.ts +251 -0
- package/src/pi/tool/index.ts +32 -0
- package/src/pi/tool/mcp.ts +319 -0
- package/src/pi/tool/schedule.ts +198 -0
- package/src/pi/tool/skill.ts +455 -0
- package/src/pi/tool/subagent.ts +148 -0
- package/src/pi/tool/web-search/api.ts +1292 -0
- package/src/pi/tool/web-search/index.ts +2 -0
- package/src/pi/tool/web-search/web-search.ts +127 -0
- package/src/pi/tool/workspace-sandbox.ts +664 -0
- package/src/pi/turn/approval.ts +181 -0
- package/src/pi/turn/index.ts +62 -0
- package/src/pi/turn/tool-recovery.ts +792 -0
- package/src/plugins.ts +1024 -0
- package/src/runtime-agent.ts +654 -0
- package/src/runtime.ts +2880 -0
|
@@ -0,0 +1,181 @@
|
|
|
1
|
+
import type { ToolResultMessage } from "@earendil-works/pi-ai";
|
|
2
|
+
import type {
|
|
3
|
+
ApprovalDecision,
|
|
4
|
+
ApprovalReceipt,
|
|
5
|
+
} from "../../kernel/receipts";
|
|
6
|
+
import { requiresExecutionApproval } from "../../lib/execution-level";
|
|
7
|
+
|
|
8
|
+
/**
|
|
9
|
+
* 表示一个 Pi Tool 在执行前等待用户处理的持久审批。
|
|
10
|
+
*
|
|
11
|
+
* Runtime 在 Tool handler 运行前保存它,恢复路径按 `executionId` 读取并应用一次决定。
|
|
12
|
+
*
|
|
13
|
+
* Tool 输入和执行身份随审批一起保存,才能在 Durable Object 重建后恢复原请求,而不是重新推断它。
|
|
14
|
+
*/
|
|
15
|
+
export interface PiToolApproval {
|
|
16
|
+
executionId: string;
|
|
17
|
+
requestId: string;
|
|
18
|
+
source: ApprovalReceipt["source"];
|
|
19
|
+
toolCallId: string;
|
|
20
|
+
toolName: string;
|
|
21
|
+
summary: string;
|
|
22
|
+
executionLevel: ApprovalReceipt["executionLevel"];
|
|
23
|
+
requiredExecutionLevel: ApprovalReceipt["requiredExecutionLevel"];
|
|
24
|
+
inputJson: string;
|
|
25
|
+
createdAt: number;
|
|
26
|
+
status: "pending" | "approved" | "rejected";
|
|
27
|
+
decidedAt?: number;
|
|
28
|
+
reason?: string;
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
/**
|
|
32
|
+
* 描述一次审批转换要求调用方采取的动作。
|
|
33
|
+
*
|
|
34
|
+
* Runtime 根据 `park`、`resume`、`denied` 或 `noop` 决定等待、续跑、写入拒绝结果或忽略重复决定。
|
|
35
|
+
*
|
|
36
|
+
* 状态转换与 I/O 分开,使同一套幂等规则同时服务在线执行和崩溃恢复。
|
|
37
|
+
*/
|
|
38
|
+
export type PiApprovalOutcome =
|
|
39
|
+
| {
|
|
40
|
+
kind: "park";
|
|
41
|
+
executionId: string;
|
|
42
|
+
requestId: string;
|
|
43
|
+
}
|
|
44
|
+
| {
|
|
45
|
+
kind: "resume";
|
|
46
|
+
executionId: string;
|
|
47
|
+
requestId: string;
|
|
48
|
+
toolCallId: string;
|
|
49
|
+
}
|
|
50
|
+
| {
|
|
51
|
+
kind: "denied";
|
|
52
|
+
executionId: string;
|
|
53
|
+
requestId: string;
|
|
54
|
+
toolResult: ToolResultMessage;
|
|
55
|
+
}
|
|
56
|
+
| {
|
|
57
|
+
kind: "noop";
|
|
58
|
+
executionId: string;
|
|
59
|
+
};
|
|
60
|
+
|
|
61
|
+
/**
|
|
62
|
+
* 把审批的新状态和对应动作绑定为一个不可拆分的决策结果。
|
|
63
|
+
*
|
|
64
|
+
* 在线执行与恢复调用方应同时消费 `approval` 和 `outcome`,不要只持久化其中一半。
|
|
65
|
+
*
|
|
66
|
+
* 两者由同一纯函数生成,可避免审批状态已经改变但续跑动作仍按旧状态计算。
|
|
67
|
+
*/
|
|
68
|
+
export interface PiApprovalTransition {
|
|
69
|
+
approval: PiToolApproval;
|
|
70
|
+
outcome: PiApprovalOutcome;
|
|
71
|
+
}
|
|
72
|
+
|
|
73
|
+
/**
|
|
74
|
+
* 判断当前 Pi Tool 是否必须先等待用户审批。
|
|
75
|
+
*
|
|
76
|
+
* 执行适配器会在调用 Tool handler 前传入 Agent 已授予档位和 Tool 所需档位。
|
|
77
|
+
*
|
|
78
|
+
* 最终矩阵委托给共享的 `requiresExecutionApproval`,避免 Pi 路径复制后偏离 Runtime 规则。
|
|
79
|
+
*/
|
|
80
|
+
export function requiresPiToolApproval(input: {
|
|
81
|
+
executionLevel: ApprovalReceipt["executionLevel"];
|
|
82
|
+
requiredExecutionLevel: ApprovalReceipt["requiredExecutionLevel"];
|
|
83
|
+
}): boolean {
|
|
84
|
+
return requiresExecutionApproval(
|
|
85
|
+
input.executionLevel,
|
|
86
|
+
input.requiredExecutionLevel,
|
|
87
|
+
);
|
|
88
|
+
}
|
|
89
|
+
|
|
90
|
+
/**
|
|
91
|
+
* 创建一个待处理审批,并告诉调用方暂停当前 Turn。
|
|
92
|
+
*
|
|
93
|
+
* 执行适配器确认需要审批后调用它,再把返回的 `approval` 持久化并等待用户决定。
|
|
94
|
+
*
|
|
95
|
+
* 此处不填写决定时间或理由,保证新记录只有一个明确的 `pending` 起点。
|
|
96
|
+
*/
|
|
97
|
+
export function parkPiToolApproval(
|
|
98
|
+
input: Omit<
|
|
99
|
+
PiToolApproval,
|
|
100
|
+
"status" | "decidedAt" | "reason"
|
|
101
|
+
>,
|
|
102
|
+
): PiApprovalTransition {
|
|
103
|
+
return {
|
|
104
|
+
approval: { ...input, status: "pending" },
|
|
105
|
+
outcome: {
|
|
106
|
+
kind: "park",
|
|
107
|
+
executionId: input.executionId,
|
|
108
|
+
requestId: input.requestId,
|
|
109
|
+
},
|
|
110
|
+
};
|
|
111
|
+
}
|
|
112
|
+
|
|
113
|
+
/**
|
|
114
|
+
* 把用户的首次审批决定应用到待处理记录。
|
|
115
|
+
*
|
|
116
|
+
* 在线审批和恢复路径在读到持久审批后调用它;已经决定过的记录会返回 `noop`,调用方不得再次执行 Tool。
|
|
117
|
+
*
|
|
118
|
+
* 拒绝仍生成 `isError: false` 的稳定 ToolResult,这是现有客户端识别 rejection envelope 的协议,不能改成普通异常。
|
|
119
|
+
*/
|
|
120
|
+
export function decidePiToolApproval(
|
|
121
|
+
approval: PiToolApproval,
|
|
122
|
+
input: ApprovalDecision & { decidedAt: number },
|
|
123
|
+
): PiApprovalTransition {
|
|
124
|
+
// 已结束的审批保持原状态,重复或并发决定只能得到 noop。
|
|
125
|
+
// 恢复路径依赖这一点避免重复续跑或产生相反终态。
|
|
126
|
+
if (approval.status !== "pending") {
|
|
127
|
+
return {
|
|
128
|
+
approval,
|
|
129
|
+
outcome: {
|
|
130
|
+
kind: "noop",
|
|
131
|
+
executionId: approval.executionId,
|
|
132
|
+
},
|
|
133
|
+
};
|
|
134
|
+
}
|
|
135
|
+
|
|
136
|
+
if (input.decision !== "deny") {
|
|
137
|
+
return {
|
|
138
|
+
approval: {
|
|
139
|
+
...approval,
|
|
140
|
+
status: "approved",
|
|
141
|
+
decidedAt: input.decidedAt,
|
|
142
|
+
},
|
|
143
|
+
outcome: {
|
|
144
|
+
kind: "resume",
|
|
145
|
+
executionId: approval.executionId,
|
|
146
|
+
requestId: approval.requestId,
|
|
147
|
+
toolCallId: approval.toolCallId,
|
|
148
|
+
},
|
|
149
|
+
};
|
|
150
|
+
}
|
|
151
|
+
|
|
152
|
+
const reason = input.reason?.trim() || "Tool execution denied by user";
|
|
153
|
+
// 拒绝是一个已处理的 Tool 结果,不是 Tool handler 失败。
|
|
154
|
+
// 保留 rejection details 和 isError:false,客户端才能继续显示既有拒绝语义。
|
|
155
|
+
return {
|
|
156
|
+
approval: {
|
|
157
|
+
...approval,
|
|
158
|
+
status: "rejected",
|
|
159
|
+
decidedAt: input.decidedAt,
|
|
160
|
+
reason,
|
|
161
|
+
},
|
|
162
|
+
outcome: {
|
|
163
|
+
kind: "denied",
|
|
164
|
+
executionId: approval.executionId,
|
|
165
|
+
requestId: approval.requestId,
|
|
166
|
+
toolResult: {
|
|
167
|
+
role: "toolResult",
|
|
168
|
+
toolCallId: approval.toolCallId,
|
|
169
|
+
toolName: approval.toolName,
|
|
170
|
+
content: [{ type: "text", text: reason }],
|
|
171
|
+
details: {
|
|
172
|
+
status: "rejected",
|
|
173
|
+
executionId: approval.executionId,
|
|
174
|
+
reason,
|
|
175
|
+
},
|
|
176
|
+
isError: false,
|
|
177
|
+
timestamp: input.decidedAt,
|
|
178
|
+
},
|
|
179
|
+
},
|
|
180
|
+
};
|
|
181
|
+
}
|
|
@@ -0,0 +1,62 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* 集中导出 Pi Turn 的审批和崩溃恢复规则。
|
|
3
|
+
*
|
|
4
|
+
* @remarks
|
|
5
|
+
* Runtime 适配器通过本入口判断审批、重放持久记录并选择恢复动作。
|
|
6
|
+
*
|
|
7
|
+
* 本目录统一使用以下术语:
|
|
8
|
+
*
|
|
9
|
+
* - **审批(approval)**:Tool handler 运行前持久化的用户许可;`pending` 状态会暂停 Turn。
|
|
10
|
+
* - **里程碑(milestone)**:属于同一个 `turnId` 和 `assemblyRevision` 的持久 JSON 记录。
|
|
11
|
+
* - **结算结果(settled ToolResult)**:已持久化且恢复时必须复用、不能再次执行副作用的 Tool 结果。
|
|
12
|
+
* - **续跑(continuation)**:审批或 Tool 结算后恢复原 Turn 的动作;先记 `pending`,再记 `committed`。
|
|
13
|
+
* - **权威结果(canonical ToolResult)**:同一 `toolCallId` 第一次成功重放出的结算结果。
|
|
14
|
+
*
|
|
15
|
+
* 这些定义对应 Runtime 的持久记录和恢复状态机;其他文件应引用本入口,不要另写一套含义。
|
|
16
|
+
*
|
|
17
|
+
* @packageDocumentation
|
|
18
|
+
*/
|
|
19
|
+
|
|
20
|
+
import {
|
|
21
|
+
parkPiToolApproval,
|
|
22
|
+
requiresPiToolApproval,
|
|
23
|
+
} from "./approval";
|
|
24
|
+
import {
|
|
25
|
+
applyRecoveredPiApprovalDecision,
|
|
26
|
+
commitPiRecoveryContinuation,
|
|
27
|
+
encodePiToolRecoveryMilestone,
|
|
28
|
+
planPiToolRecovery,
|
|
29
|
+
replayPiToolRecovery,
|
|
30
|
+
stagePiRecoveryContinuation,
|
|
31
|
+
} from "./tool-recovery";
|
|
32
|
+
|
|
33
|
+
/**
|
|
34
|
+
* 提供 Pi Tool 审批的两个入口操作。
|
|
35
|
+
*
|
|
36
|
+
* Runtime 执行适配器在调用 Tool handler 前先判断 `requires`,需要等待时再用 `park` 生成待审批状态。
|
|
37
|
+
*
|
|
38
|
+
* 冻结该门面可防止调用方在运行期间替换审批规则;完整类型和决策函数仍由本模块单独导出。
|
|
39
|
+
*/
|
|
40
|
+
export const piApproval = Object.freeze({
|
|
41
|
+
park: parkPiToolApproval,
|
|
42
|
+
requires: requiresPiToolApproval,
|
|
43
|
+
});
|
|
44
|
+
|
|
45
|
+
/**
|
|
46
|
+
* 提供 Pi Turn 恢复状态机的稳定入口。
|
|
47
|
+
*
|
|
48
|
+
* Runtime 恢复适配器先用 `replay` 还原状态,再用 `plan` 选择下一步,并按计划写入或提交续跑里程碑。
|
|
49
|
+
*
|
|
50
|
+
* 这些操作保持为无 I/O 的纯决策,持久化和调度仍由 Runtime 负责,避免恢复规则依赖具体存储实现。
|
|
51
|
+
*/
|
|
52
|
+
export const piRecovery = Object.freeze({
|
|
53
|
+
applyApprovalDecision: applyRecoveredPiApprovalDecision,
|
|
54
|
+
commitContinuation: commitPiRecoveryContinuation,
|
|
55
|
+
encodeMilestone: encodePiToolRecoveryMilestone,
|
|
56
|
+
plan: planPiToolRecovery,
|
|
57
|
+
replay: replayPiToolRecovery,
|
|
58
|
+
stageContinuation: stagePiRecoveryContinuation,
|
|
59
|
+
});
|
|
60
|
+
|
|
61
|
+
export * from "./approval";
|
|
62
|
+
export * from "./tool-recovery";
|