@migor/agentia 0.9.5 → 0.10.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +740 -1
- package/README.en.md +61 -3
- package/README.md +66 -4
- package/dist/AGENTS.md +54 -13
- package/dist/container/container.js +17 -11
- package/dist/container/container.js.map +1 -1
- package/dist/core/limits.d.ts +12 -5
- package/dist/core/limits.js +4 -4
- package/dist/core/limits.js.map +1 -1
- package/dist/engine/budget.js +14 -0
- package/dist/engine/budget.js.map +1 -1
- package/dist/engine/errors.d.ts +23 -1
- package/dist/engine/errors.js +24 -0
- package/dist/engine/errors.js.map +1 -1
- package/dist/index.d.ts +1 -1
- package/dist/index.js +1 -1
- package/dist/index.js.map +1 -1
- package/dist/runtime/run.js +14 -2
- package/dist/runtime/run.js.map +1 -1
- package/dist/store/redisStore.d.ts +21 -0
- package/dist/store/redisStore.js +21 -0
- package/dist/store/redisStore.js.map +1 -1
- package/dist/store/store.d.ts +1 -1
- package/dist/transport/approval-supervisor.d.ts +73 -0
- package/dist/transport/approval-supervisor.js +252 -0
- package/dist/transport/approval-supervisor.js.map +1 -0
- package/dist/transport/async.d.ts +29 -105
- package/dist/transport/async.js +85 -513
- package/dist/transport/async.js.map +1 -1
- package/dist/transport/resume-scanner.d.ts +55 -0
- package/dist/transport/resume-scanner.js +219 -0
- package/dist/transport/resume-scanner.js.map +1 -0
- package/dist/transport/signal-supervisor.d.ts +80 -0
- package/dist/transport/signal-supervisor.js +129 -0
- package/dist/transport/signal-supervisor.js.map +1 -0
- package/dist/transport/task-events.js +8 -1
- package/dist/transport/task-events.js.map +1 -1
- package/package.json +11 -2
package/dist/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,MAAM,CAAC,MAAM,eAAe,GAAG,
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"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"}
|
package/dist/runtime/run.js
CHANGED
|
@@ -147,8 +147,10 @@ export async function executeRun(options) {
|
|
|
147
147
|
try {
|
|
148
148
|
memoryRev = await hydrateMemory(memory, ctx);
|
|
149
149
|
}
|
|
150
|
-
catch {
|
|
151
|
-
|
|
150
|
+
catch (e) {
|
|
151
|
+
// 水合失败此前是**完全无声**的:它的后果(CAS 回写被拒)发生在几十行之后、还被归因成
|
|
152
|
+
// 「并发抢写」(2026-09-29 外部深评 A1)—— 在这里留下**第一因**,别让它隔着整条 run。
|
|
153
|
+
console.warn('[agentia] 记忆水合(load)失败,本次 run 当作「无记忆」继续(辅助动作失败不击穿 run):', e instanceof Error ? e.message : e);
|
|
152
154
|
}
|
|
153
155
|
}
|
|
154
156
|
const result = await runAgent({
|
|
@@ -360,6 +362,16 @@ async function flushMemory(memory, ctx, rev) {
|
|
|
360
362
|
}
|
|
361
363
|
const { store } = memory;
|
|
362
364
|
if (typeof store.saveIfRev === 'function') {
|
|
365
|
+
// rev === undefined ⇒ 水合(load)失败被上面 catch 吞掉(能走到本分支的 store 必有
|
|
366
|
+
// loadWithRev —— `assertMemoryStoreShape` 在入口保证成对)⇒ 此时做 CAS 没有意义:**读都没
|
|
367
|
+
// 成功**,谈「读之后有没有人写」是伪命题;而 `saveIfRev(entries, undefined)` 会被 CAS store
|
|
368
|
+
// 判成冲突 ⇒ 报出「并发抢写」的**假归因**(2026-09-29 外部深评 A1)。跳过 + 说真话。
|
|
369
|
+
if (rev === undefined) {
|
|
370
|
+
console.warn('[agentia] 记忆回写被跳过:水合(load)失败 ⇒ 没有可用的版本号,不做 CAS 回写(写了也只会被拒)。' +
|
|
371
|
+
`keys=[${memory.keys.join(', ')}] —— 真因是「这一次读失败了」,**不是**并发抢写;` +
|
|
372
|
+
'要查的是 store 连通性(Redis 挂了 / 网络抖动),不是并发。');
|
|
373
|
+
return;
|
|
374
|
+
}
|
|
363
375
|
const outcome = await store.saveIfRev(entries, rev);
|
|
364
376
|
// 判据是 `!== true`(不是 `=== false`):`saveIfRev` 忘返回结果(`undefined`)时
|
|
365
377
|
// 按「没提交」处理 —— 宁可多报一次,也不把「不知道写没写」记成写成功。
|
package/dist/runtime/run.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"run.js","sourceRoot":"","sources":["../../src/runtime/run.ts"],"names":[],"mappings":"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
|
|
1
|
+
{"version":3,"file":"run.js","sourceRoot":"","sources":["../../src/runtime/run.ts"],"names":[],"mappings":"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"}
|
|
@@ -64,6 +64,16 @@ export interface RedisLike {
|
|
|
64
64
|
MATCH?: string;
|
|
65
65
|
COUNT?: number;
|
|
66
66
|
}): AsyncIterable<string | string[]>;
|
|
67
|
+
/**
|
|
68
|
+
* 关闭连接(可选)—— `RedisTaskStore.close()` 用它。对应 ioredis / node-redis 的 `quit()`。
|
|
69
|
+
*
|
|
70
|
+
* ⚠️ 取 `quit` 而不是 `close` / `destroy`:它是**三家共名**的成员(ioredis ✓、node-redis v4 ✓、
|
|
71
|
+
* v5 有但已 `@deprecated`)—— 与既有的 `expire` 同档判据(取公共面,不追任何一家的新写法)。
|
|
72
|
+
* 2026-09-29 查 node-redis master 源码:`quit()` 已标 `@deprecated`(后继 `close()`),但
|
|
73
|
+
* 本仓要同时兼容 ioredis,故暂留 `quit`;将来只支持 node-redis v5+ 时再换 `close`。
|
|
74
|
+
* 返回类型放宽为 `Promise<unknown>`:ioredis 返 `'OK'`、node-redis 返 `void` / 字符串。
|
|
75
|
+
*/
|
|
76
|
+
quit?(): Promise<unknown>;
|
|
67
77
|
}
|
|
68
78
|
export interface RedisTaskStoreOptions {
|
|
69
79
|
/** key 前缀,缺省 'agentia:' */
|
|
@@ -107,6 +117,17 @@ export declare class RedisTaskStore implements TaskStore {
|
|
|
107
117
|
byIdempotency(key: string): Promise<TaskRecord | undefined>;
|
|
108
118
|
list(): Promise<TaskRecord[]>;
|
|
109
119
|
clear(): Promise<void>;
|
|
120
|
+
/**
|
|
121
|
+
* 关闭底层连接(`TaskStore.close?()` 的实现 —— 外部深评 C1:唯一真正握着外部连接的 store 此前
|
|
122
|
+
* 没有关闭出口,因为 `RedisLike` 上没有 `quit`)。
|
|
123
|
+
*
|
|
124
|
+
* ⚠️ 框架**不主动调**它:`drain` 不关 store(store 可能在多条 run / 宿主之间共享,见 `store.ts`
|
|
125
|
+
* 对 `close?()` 的说明)。这是给宿主在「确认不再用这个 store」时的手动出口。
|
|
126
|
+
*
|
|
127
|
+
* **幂等**:客户端没有 `quit`(只读桩 / fake)⇒ 直接返回;已关过 / 连接已断时 ioredis 的
|
|
128
|
+
* `quit` 会 reject ⇒ 吞掉 —— 关闭是尽力而为,重复关闭不该打断宿主的 shutdown 路径。
|
|
129
|
+
*/
|
|
130
|
+
close(): Promise<void>;
|
|
110
131
|
/** `${prefix}task:*` —— prefix 里的 glob 元字符必须转义,否则会被当模式解释 */
|
|
111
132
|
private taskPattern;
|
|
112
133
|
/** 按键枚举:优先 scanIterator,缺则退回 keys(pattern) */
|
package/dist/store/redisStore.js
CHANGED
|
@@ -101,6 +101,27 @@ export class RedisTaskStore {
|
|
|
101
101
|
for (const k of keys)
|
|
102
102
|
await this.client.del(k);
|
|
103
103
|
}
|
|
104
|
+
/**
|
|
105
|
+
* 关闭底层连接(`TaskStore.close?()` 的实现 —— 外部深评 C1:唯一真正握着外部连接的 store 此前
|
|
106
|
+
* 没有关闭出口,因为 `RedisLike` 上没有 `quit`)。
|
|
107
|
+
*
|
|
108
|
+
* ⚠️ 框架**不主动调**它:`drain` 不关 store(store 可能在多条 run / 宿主之间共享,见 `store.ts`
|
|
109
|
+
* 对 `close?()` 的说明)。这是给宿主在「确认不再用这个 store」时的手动出口。
|
|
110
|
+
*
|
|
111
|
+
* **幂等**:客户端没有 `quit`(只读桩 / fake)⇒ 直接返回;已关过 / 连接已断时 ioredis 的
|
|
112
|
+
* `quit` 会 reject ⇒ 吞掉 —— 关闭是尽力而为,重复关闭不该打断宿主的 shutdown 路径。
|
|
113
|
+
*/
|
|
114
|
+
async close() {
|
|
115
|
+
const quit = this.client.quit;
|
|
116
|
+
if (typeof quit !== 'function')
|
|
117
|
+
return;
|
|
118
|
+
try {
|
|
119
|
+
await quit.call(this.client);
|
|
120
|
+
}
|
|
121
|
+
catch {
|
|
122
|
+
/* 幂等:已关闭 / 连接已断 —— 关闭语义是「尽力而为」,不抛 */
|
|
123
|
+
}
|
|
124
|
+
}
|
|
104
125
|
/** `${prefix}task:*` —— prefix 里的 glob 元字符必须转义,否则会被当模式解释 */
|
|
105
126
|
taskPattern() {
|
|
106
127
|
return `${escapeGlob(this.prefix)}task:*`;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"redisStore.js","sourceRoot":"","sources":["../../src/store/redisStore.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,gBAAgB,EAAE,MAAM,gBAAgB,CAAC;AAClD,OAAO,EAAE,eAAe,EAAE,MAAM,aAAa,CAAC;
|
|
1
|
+
{"version":3,"file":"redisStore.js","sourceRoot":"","sources":["../../src/store/redisStore.ts"],"names":[],"mappings":"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"}
|
package/dist/store/store.d.ts
CHANGED
|
@@ -79,7 +79,7 @@ export interface TaskRecord {
|
|
|
79
79
|
pendingEvents?: TaskEvent[] | undefined;
|
|
80
80
|
/**
|
|
81
81
|
* 已投递事件的 eventId 簿记(幂等去重依据;**随记录落库** ⇒ 跨进程/重启不丢)。
|
|
82
|
-
* 有界:最多保留 `MAX_DELIVERED_EVENT_IDS`(`transport/
|
|
82
|
+
* 有界:最多保留 `MAX_DELIVERED_EVENT_IDS`(`transport/signal-supervisor.ts`)条,超出 FIFO 裁
|
|
83
83
|
* 最旧 —— 它是去重簿记,不是审计日志;超出上限后同 id 重投会再进一次历史(如实:
|
|
84
84
|
* 簿记有界,恰好一次的承诺也就有界)。
|
|
85
85
|
*/
|
|
@@ -0,0 +1,73 @@
|
|
|
1
|
+
import type { SuspendedSummary } from './wake-policy.js';
|
|
2
|
+
import type { TaskRecord, TaskStore } from '../store/store.js';
|
|
3
|
+
/** `approve` 的入参:一批 tool_use_id → 批准/拒绝(理由可选) */
|
|
4
|
+
export type ApprovalDecisions = Record<string, {
|
|
5
|
+
approved: boolean;
|
|
6
|
+
reason?: string;
|
|
7
|
+
}>;
|
|
8
|
+
/**
|
|
9
|
+
* `approve` 的失败:带 HTTP 语义的状态码(404 = 任务不存在,409 = 任务当前不在
|
|
10
|
+
* `suspended` 状态),HTTP 宿主据此回对应响应。
|
|
11
|
+
* module 级 export —— 不进公共导出面(纯宿主内部实现细节)。
|
|
12
|
+
*/
|
|
13
|
+
export declare class TaskApproveError extends Error {
|
|
14
|
+
/** 400 = 入参语义不合法(decisions 里有本任务待决之外的 id,2026-09-28 深评 P1-2) */
|
|
15
|
+
readonly status: 400 | 404 | 409;
|
|
16
|
+
constructor(status: 400 | 404 | 409, message: string);
|
|
17
|
+
}
|
|
18
|
+
/** `ApprovalSupervisor` 的注入依赖(全部由 `AsyncRunner` 构造时提供) */
|
|
19
|
+
export interface ApprovalSupervisorDeps {
|
|
20
|
+
store: TaskStore;
|
|
21
|
+
/** 恢复执行时写进记录的宿主标识(`approve` / 超时恢复都要 `rec.ownerId = ownerId`) */
|
|
22
|
+
ownerId: string;
|
|
23
|
+
/** 审批超时的毫秒数(0 = 不限)。已由 `AsyncRunner` 构造期校验为「≥ 0 的有限数」 */
|
|
24
|
+
approvalTimeoutMs: number;
|
|
25
|
+
/** 派发入口(`AsyncRunner.#dispatch`:停机闸 + 唯一派发点 + 停机窗口里的一次告警) */
|
|
26
|
+
dispatch(rec: TaskRecord): void;
|
|
27
|
+
}
|
|
28
|
+
export declare class ApprovalSupervisor {
|
|
29
|
+
#private;
|
|
30
|
+
constructor(deps: ApprovalSupervisorDeps);
|
|
31
|
+
/** 挂起读数:按原因分组的条数 + 最早的目标时刻(无时间挂起时为 `null`) */
|
|
32
|
+
get summary(): SuspendedSummary;
|
|
33
|
+
/** 登记一条挂起(纪律①)。原因缺失的记录不进表 —— 分不了组,宁可少数也不猜一个原因出来 */
|
|
34
|
+
markSuspended(rec: TaskRecord): void;
|
|
35
|
+
/** 除名(纪律②):任务离开挂起态时调用(恢复、终态都算) */
|
|
36
|
+
unmarkSuspended(taskId: string): void;
|
|
37
|
+
/**
|
|
38
|
+
* 按 store 的**全表**重建挂起集(读数纪律③)—— `resumePending` 扫描时调用。
|
|
39
|
+
* 扫描本来就 `list()` 了全表,顺手把读数对齐一遍;顺带把**他进程**(或本进程上一世)
|
|
40
|
+
* 留下的挂起也算进本进程可见的那些(口径见 `summary` 的注释)。
|
|
41
|
+
*/
|
|
42
|
+
rebuild(recs: TaskRecord[]): void;
|
|
43
|
+
/**
|
|
44
|
+
* 惰性审批超时:`approvalExpired` 为真 ⇒ 进在飞闸 + 自动全拒 + 落库 + 派发。返回是否命中。
|
|
45
|
+
*
|
|
46
|
+
* 与原 `#lazyGates` / `#redispatch` 里那两句 `if (approvalExpired(...)) #expireAndResume(...)`
|
|
47
|
+
* **逐字等价** —— `approvalExpired` 内部已判 `status === 'suspended'` 与
|
|
48
|
+
* `reason === 'approval'`(见 approval-policy.ts),所以 `#redispatch` 原写法里那句额外的
|
|
49
|
+
* `rec.status !== 'suspended'` 短路是冗余的,合并到本方法不改变任何可观测行为。
|
|
50
|
+
*/
|
|
51
|
+
expireIfExpired(rec: TaskRecord, now: number): boolean;
|
|
52
|
+
/**
|
|
53
|
+
* 审批一个处于 `suspended` 的任务(HITL)。
|
|
54
|
+
*
|
|
55
|
+
* - **逐 tool_use_id 幂等**:已存在的决定不覆盖(第一次决定赢)—— 重复提交 /
|
|
56
|
+
* 并发点击不会推翻已有决定,也不会让恢复段重复执行;
|
|
57
|
+
* - **并发重入共享在飞那次**:同一任务的并发 approve(双击「批准」/两个审批人
|
|
58
|
+
* 同时批)返回同一个 Promise —— 否则两个调用都在对方落库前读到
|
|
59
|
+
* `suspended`、各自判「决定齐了」、**各派发一次**(同一任务重复执行,
|
|
60
|
+
* 与 resumePending 的闸门同一 bug 类)。被共享的那次覆盖不到的决定不丢:
|
|
61
|
+
* 调用方从返回的记录看到任务仍在等待,重试即并入;
|
|
62
|
+
* - 决定齐了就恢复:`status` 回 `running`、**先落库再派发**(与 `#redispatch`
|
|
63
|
+
* 同一条纪律 —— 没落库就恢复,进程崩在窗口里会丢决定);恢复段带着
|
|
64
|
+
* `rec.approvals` 与扩展后的消息历史(`rec.spec.messages`,末尾是含未决
|
|
65
|
+
* tool_use 的那条 assistant 消息)重进引擎循环;
|
|
66
|
+
* - 决定**没**齐:只把本批决定落库,任务继续等(可能多轮审批);
|
|
67
|
+
* - 返回当前 TaskRecord(快照)。任务不存在抛 404 语义、状态不对抛 409 语义
|
|
68
|
+
* 的 `TaskApproveError`。
|
|
69
|
+
*/
|
|
70
|
+
approve(taskId: string, decisions: ApprovalDecisions, opts?: {
|
|
71
|
+
decidedBy?: string;
|
|
72
|
+
}): Promise<TaskRecord>;
|
|
73
|
+
}
|
|
@@ -0,0 +1,252 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Agentia —— 审批监督:HITL 挂起登记簿(读数)+ 在飞闸 + `approve` + 审批超时恢复。
|
|
3
|
+
*
|
|
4
|
+
* 从 `async.ts` 的 `AsyncRunner` 抽出的**方向正交**的一块(外部深评结构体检的建议②)。
|
|
5
|
+
* 它管的是「谁挂着、谁在等审批、审批超时了没」,与「认领 / 槽位 / 派发 / 执行」不是
|
|
6
|
+
* 一个方向 —— 而抽之前它被私字段(`#suspended` / `#inflightApprovals`)与私有方法缝在
|
|
7
|
+
* 1554 行的 `AsyncRunner` 里,横跨 5 处外部调用点(`cancel` / `signalTask` / 到期唤醒 /
|
|
8
|
+
* `resumePending` 扫描 / `#executeInner` 的挂起与终态出口)+ 对外 getter。
|
|
9
|
+
*
|
|
10
|
+
* **零行为变化**:本文件是对原成员的**逐字搬迁** + 依赖改为构造注入。判据、分支顺序、
|
|
11
|
+
* 错误类型、副作用次序(先落库再派发)一字未改。
|
|
12
|
+
*
|
|
13
|
+
* 为什么 `dispatch` 用**回调注入**而不是 import `async.ts`:`#dispatch` 是 `AsyncRunner`
|
|
14
|
+
* 的私有方法(停机闸 + 唯一派发入口 + 一次性告警),审批簇只**消费**它,不该拥有它、
|
|
15
|
+
* 也不该复制一份。注入让依赖保持单向(审批 → 派发),同时避免模块循环。
|
|
16
|
+
*
|
|
17
|
+
* ⚠️ `TaskApproveError` / `ApprovalDecisions` 随本簇迁到这里;`async.ts` 仍 **re-export**
|
|
18
|
+
* 它们 ⇒ `http-endpoints.ts` / `http-shapes.ts` 的 import 路径不变。
|
|
19
|
+
*/
|
|
20
|
+
import { approvalExpired, approvalsComplete, fillTimeoutDenials } from './approval-policy.js';
|
|
21
|
+
import { summarizeSuspended } from './wake-policy.js';
|
|
22
|
+
import { isThenable } from '../store/store.js';
|
|
23
|
+
/**
|
|
24
|
+
* `approve` 的失败:带 HTTP 语义的状态码(404 = 任务不存在,409 = 任务当前不在
|
|
25
|
+
* `suspended` 状态),HTTP 宿主据此回对应响应。
|
|
26
|
+
* module 级 export —— 不进公共导出面(纯宿主内部实现细节)。
|
|
27
|
+
*/
|
|
28
|
+
export class TaskApproveError extends Error {
|
|
29
|
+
/** 400 = 入参语义不合法(decisions 里有本任务待决之外的 id,2026-09-28 深评 P1-2) */
|
|
30
|
+
status;
|
|
31
|
+
constructor(status, message) {
|
|
32
|
+
super(message);
|
|
33
|
+
this.name = 'TaskApproveError';
|
|
34
|
+
this.status = status;
|
|
35
|
+
}
|
|
36
|
+
}
|
|
37
|
+
export class ApprovalSupervisor {
|
|
38
|
+
/**
|
|
39
|
+
* **本进程可见的挂起读数**(`/healthz` 的 `suspended` 段,配套 6)。
|
|
40
|
+
*
|
|
41
|
+
* 口径与 `inFlight` 同一张表:只数**本进程**经手的挂起 —— 跨进程要合并看板请自己聚合,
|
|
42
|
+
* 不假装是全局面(别的进程挂起的记录这里看不见,重启后由首次扫描对齐,见下)。
|
|
43
|
+
*
|
|
44
|
+
* 三条维护纪律(这条读数的唯一风险是**漂移**,所以每条出口都要写清):
|
|
45
|
+
* ① 进挂起时登记(`#executeInner` 的挂起分支,与落库同一个分支);
|
|
46
|
+
* ② 离开挂起时除名(`approve` / 两条恢复路径 / 终态分支);
|
|
47
|
+
* ③ **每次 `resumePending` 扫描按 store 重建**(`rebuild`)—— 扫描本来就 `list()` 了全表,
|
|
48
|
+
* 顺手对齐即可,把「漏了某个出口」从永久漂移降级成「下一次扫描前的偏差」。
|
|
49
|
+
*
|
|
50
|
+
* 为什么不留成 store 查询(每次 /healthz 扫全表):`/healthz` 是探针端点(秒级频率),
|
|
51
|
+
* 而 `list()` 要把**每条记录的完整 trace**取出来(sqlite/redis 下是全部反序列化)——
|
|
52
|
+
* 拿它当健康检查的代价比它回答的问题大得多。
|
|
53
|
+
*/
|
|
54
|
+
#suspended = new Map();
|
|
55
|
+
/** 同一任务的在飞审批(`approve` 的重入闸)。**与惰性超时恢复共用同一把闸** ——
|
|
56
|
+
* `approve` 与超时恢复都会「填决定 + 落库 + 派发」,不互斥就是同一任务跑两遍。 */
|
|
57
|
+
#inflight = new Map();
|
|
58
|
+
#deps;
|
|
59
|
+
constructor(deps) {
|
|
60
|
+
this.#deps = deps;
|
|
61
|
+
}
|
|
62
|
+
/** 挂起读数:按原因分组的条数 + 最早的目标时刻(无时间挂起时为 `null`) */
|
|
63
|
+
get summary() {
|
|
64
|
+
return summarizeSuspended(this.#suspended.values());
|
|
65
|
+
}
|
|
66
|
+
/** 登记一条挂起(纪律①)。原因缺失的记录不进表 —— 分不了组,宁可少数也不猜一个原因出来 */
|
|
67
|
+
markSuspended(rec) {
|
|
68
|
+
if (rec.status !== 'suspended' || rec.suspendedReason === undefined)
|
|
69
|
+
return;
|
|
70
|
+
this.#suspended.set(rec.taskId, { reason: rec.suspendedReason, wakeAt: rec.wakeAt });
|
|
71
|
+
}
|
|
72
|
+
/** 除名(纪律②):任务离开挂起态时调用(恢复、终态都算) */
|
|
73
|
+
unmarkSuspended(taskId) {
|
|
74
|
+
this.#suspended.delete(taskId);
|
|
75
|
+
}
|
|
76
|
+
/**
|
|
77
|
+
* 按 store 的**全表**重建挂起集(读数纪律③)—— `resumePending` 扫描时调用。
|
|
78
|
+
* 扫描本来就 `list()` 了全表,顺手把读数对齐一遍;顺带把**他进程**(或本进程上一世)
|
|
79
|
+
* 留下的挂起也算进本进程可见的那些(口径见 `summary` 的注释)。
|
|
80
|
+
*/
|
|
81
|
+
rebuild(recs) {
|
|
82
|
+
this.#suspended.clear();
|
|
83
|
+
for (const rec of recs) {
|
|
84
|
+
if (rec.status !== 'suspended' || rec.suspendedReason === undefined)
|
|
85
|
+
continue;
|
|
86
|
+
this.#suspended.set(rec.taskId, { reason: rec.suspendedReason, wakeAt: rec.wakeAt });
|
|
87
|
+
}
|
|
88
|
+
}
|
|
89
|
+
/**
|
|
90
|
+
* 惰性审批超时:`approvalExpired` 为真 ⇒ 进在飞闸 + 自动全拒 + 落库 + 派发。返回是否命中。
|
|
91
|
+
*
|
|
92
|
+
* 与原 `#lazyGates` / `#redispatch` 里那两句 `if (approvalExpired(...)) #expireAndResume(...)`
|
|
93
|
+
* **逐字等价** —— `approvalExpired` 内部已判 `status === 'suspended'` 与
|
|
94
|
+
* `reason === 'approval'`(见 approval-policy.ts),所以 `#redispatch` 原写法里那句额外的
|
|
95
|
+
* `rec.status !== 'suspended'` 短路是冗余的,合并到本方法不改变任何可观测行为。
|
|
96
|
+
*/
|
|
97
|
+
expireIfExpired(rec, now) {
|
|
98
|
+
if (!approvalExpired(rec, now, this.#deps.approvalTimeoutMs))
|
|
99
|
+
return false;
|
|
100
|
+
this.#expireAndResume(rec, now);
|
|
101
|
+
return true;
|
|
102
|
+
}
|
|
103
|
+
/**
|
|
104
|
+
* 审批一个处于 `suspended` 的任务(HITL)。
|
|
105
|
+
*
|
|
106
|
+
* - **逐 tool_use_id 幂等**:已存在的决定不覆盖(第一次决定赢)—— 重复提交 /
|
|
107
|
+
* 并发点击不会推翻已有决定,也不会让恢复段重复执行;
|
|
108
|
+
* - **并发重入共享在飞那次**:同一任务的并发 approve(双击「批准」/两个审批人
|
|
109
|
+
* 同时批)返回同一个 Promise —— 否则两个调用都在对方落库前读到
|
|
110
|
+
* `suspended`、各自判「决定齐了」、**各派发一次**(同一任务重复执行,
|
|
111
|
+
* 与 resumePending 的闸门同一 bug 类)。被共享的那次覆盖不到的决定不丢:
|
|
112
|
+
* 调用方从返回的记录看到任务仍在等待,重试即并入;
|
|
113
|
+
* - 决定齐了就恢复:`status` 回 `running`、**先落库再派发**(与 `#redispatch`
|
|
114
|
+
* 同一条纪律 —— 没落库就恢复,进程崩在窗口里会丢决定);恢复段带着
|
|
115
|
+
* `rec.approvals` 与扩展后的消息历史(`rec.spec.messages`,末尾是含未决
|
|
116
|
+
* tool_use 的那条 assistant 消息)重进引擎循环;
|
|
117
|
+
* - 决定**没**齐:只把本批决定落库,任务继续等(可能多轮审批);
|
|
118
|
+
* - 返回当前 TaskRecord(快照)。任务不存在抛 404 语义、状态不对抛 409 语义
|
|
119
|
+
* 的 `TaskApproveError`。
|
|
120
|
+
*/
|
|
121
|
+
async approve(taskId, decisions, opts = {}) {
|
|
122
|
+
const inflight = this.#inflight.get(taskId);
|
|
123
|
+
if (inflight)
|
|
124
|
+
return inflight;
|
|
125
|
+
const run = this.#approveInner(taskId, decisions, opts).finally(() => {
|
|
126
|
+
this.#inflight.delete(taskId);
|
|
127
|
+
});
|
|
128
|
+
this.#inflight.set(taskId, run);
|
|
129
|
+
return run;
|
|
130
|
+
}
|
|
131
|
+
async #approveInner(taskId, decisions, opts) {
|
|
132
|
+
const rec = await this.#deps.store.get(taskId);
|
|
133
|
+
if (!rec)
|
|
134
|
+
throw new TaskApproveError(404, `task 不存在: ${taskId}`);
|
|
135
|
+
if (rec.status !== 'suspended' || rec.suspendedReason !== 'approval') {
|
|
136
|
+
throw new TaskApproveError(409, rec.status === 'suspended'
|
|
137
|
+
? `task ${taskId} 的挂起原因是 ${rec.suspendedReason ?? '未知'},只有等人工审批的挂起能审批`
|
|
138
|
+
: `task ${taskId} 当前状态为 ${rec.status},只有挂起在等审批的任务才能审批`);
|
|
139
|
+
}
|
|
140
|
+
const now = Date.now();
|
|
141
|
+
// 入参校验(2026-09-28 外部深评 P1-2):本批只许批**本任务待决的** id。
|
|
142
|
+
// 不校验会怎样(实证:一次 approve 塞 5000 个无关键 ⇒ 记录从 246 字节撑到 419 KB):
|
|
143
|
+
// 多出来的键照样写进 `rec.approvals`、随每次 save 全文重写落库、并随任务**永久保留**
|
|
144
|
+
// (终态也不清:审批记录是审计的一部分)⇒ 一个**认证调用方**单次请求就能把记录撑大,
|
|
145
|
+
// 反复调用可无限叠加。拒整批而不是挑着收:与 `parseApproveBody`(形状全有或全无)、
|
|
146
|
+
// `parseEventBody`(多一个字段即拒)同一条纪律 —— 调用方本来就该从记录的 `pendingApprovals`
|
|
147
|
+
// 里读要批哪些 id。
|
|
148
|
+
// ⚠️ 为什么**不需要**再给 `rec.approvals` 加常量上限:单次 approve 能新写的键 ⊆ 当前
|
|
149
|
+
// `pendingApprovals`(挂起那一刻固定)。跨多轮挂起它会累计**历次**待决的并集
|
|
150
|
+
// (决定是审计,终态也保留),但每一轮都对应真跑出来的模型回合与 tool_use ——
|
|
151
|
+
// 调用方的单次输入无法放大体积,增长只能随真实运行发生。再加常量上限是一段
|
|
152
|
+
// 永远触发不到的死代码(那不是护栏,是噪音)。
|
|
153
|
+
const pendingIds = new Set(rec.pendingApprovals ?? []);
|
|
154
|
+
const unknownIds = Object.keys(decisions).filter((id) => !pendingIds.has(id));
|
|
155
|
+
if (unknownIds.length > 0) {
|
|
156
|
+
throw new TaskApproveError(400, `decisions 里有 ${unknownIds.length} 个 id 不在本任务的待决列表里(如 ${unknownIds[0]})—— 整批拒掉,记录不动`);
|
|
157
|
+
}
|
|
158
|
+
rec.approvals ??= {};
|
|
159
|
+
for (const [id, d] of Object.entries(decisions)) {
|
|
160
|
+
if (rec.approvals[id])
|
|
161
|
+
continue; // 逐 id 幂等:第一次决定赢
|
|
162
|
+
rec.approvals[id] = {
|
|
163
|
+
approved: d.approved,
|
|
164
|
+
...(d.reason !== undefined ? { reason: d.reason } : {}),
|
|
165
|
+
...(opts.decidedBy !== undefined ? { decidedBy: opts.decidedBy } : {}),
|
|
166
|
+
decidedAt: now,
|
|
167
|
+
...(rec.suspendedSince !== undefined ? { requestedAt: rec.suspendedSince } : {}),
|
|
168
|
+
};
|
|
169
|
+
}
|
|
170
|
+
// 惰性审批超时:人的决定先并入(先到先赢),仍空着的待决项由超时兜底成 deny
|
|
171
|
+
if (approvalExpired(rec, now, this.#deps.approvalTimeoutMs))
|
|
172
|
+
fillTimeoutDenials(rec, now);
|
|
173
|
+
const complete = approvalsComplete(rec);
|
|
174
|
+
if (complete) {
|
|
175
|
+
rec.status = 'running'; // 由 #executeInner 接管(acquireSlot → 恢复执行)
|
|
176
|
+
rec.ownerId = this.#deps.ownerId;
|
|
177
|
+
}
|
|
178
|
+
// 先落库再派发 —— **真纪律,不是注释**:save 失败(同步抛 / 异步 reject)就
|
|
179
|
+
// 绝不恢复执行(落不了库的决定不算决定:进程崩在窗口里会丢决定,重启后把
|
|
180
|
+
// 同一件事再判一次、可能改判)。调用方拿到 reject,重试即可。
|
|
181
|
+
await this.#deps.store.save(rec);
|
|
182
|
+
if (complete) {
|
|
183
|
+
// 离开挂起态(读数纪律②):决定齐了这就是「醒来」那一刻
|
|
184
|
+
this.unmarkSuspended(taskId);
|
|
185
|
+
// 派发走**唯一入口**(闸在 #dispatch 里判一次 —— 2026-09-28 外部深评 P1-1 的结构性修法):
|
|
186
|
+
// 决定已经在记录里,停机窗口里放行的是「重新排期」(下次启动认领),不是「吞掉」。
|
|
187
|
+
this.#deps.dispatch(rec);
|
|
188
|
+
}
|
|
189
|
+
return { ...rec };
|
|
190
|
+
}
|
|
191
|
+
/**
|
|
192
|
+
* 惰性超时扫描(HITL):读到一个已超时的 awaiting 任务 ⇒ 自动全拒 + 落库 + 重派。
|
|
193
|
+
* 与 #redispatch 同一条纪律:**先落库再派发**(没落库就恢复,进程崩在窗口里会
|
|
194
|
+
* 丢掉超时决定、把同一件事再判一次)。
|
|
195
|
+
*
|
|
196
|
+
* 重入闸(2026-09-20,见 spec §10 当日条):与 `approve` **共用同一把** per-taskId
|
|
197
|
+
* 闸(`#inflight`)。异步 store 的 `get` 返回**新副本**且有网络往返 —— 两个
|
|
198
|
+
* 并发 poll(或 poll 与 approve)各自看到 awaiting 快照 ⇒ 双双填超时拒绝 + 双双
|
|
199
|
+
* `#execute`(同一任务跑两遍)。在飞即跳过:另一路径自己会兜底(`#approveInner`
|
|
200
|
+
* 里也有 approvalExpired 判定,见 approval-policy.ts),决定逐 id 幂等(第一次决定赢)。
|
|
201
|
+
* 反之 approve 撞上在飞的超时恢复时共享其结果 —— 与人的决定竞速,先到先得。
|
|
202
|
+
*/
|
|
203
|
+
#expireAndResume(rec, now) {
|
|
204
|
+
if (this.#inflight.has(rec.taskId))
|
|
205
|
+
return;
|
|
206
|
+
const run = this.#expireAndResumeInner(rec, now).finally(() => {
|
|
207
|
+
this.#inflight.delete(rec.taskId);
|
|
208
|
+
});
|
|
209
|
+
this.#inflight.set(rec.taskId, run);
|
|
210
|
+
// poll / resumePending 路径没有调用方接 reject —— 订阅掉,不得逃逸成 unhandled rejection
|
|
211
|
+
run.catch(() => undefined);
|
|
212
|
+
}
|
|
213
|
+
async #expireAndResumeInner(rec, now) {
|
|
214
|
+
// 进闸后**重读一遍**再判:闸只互斥「进入」,挡不住「进闸前已取到的旧副本」——
|
|
215
|
+
// 本记录的快照可能是在另一次恢复落库**之前**取的(异步 store 的 get 有往返),
|
|
216
|
+
// 凭陈旧快照放行会把同一任务再派发一次。
|
|
217
|
+
const fresh = await this.#deps.store.get(rec.taskId);
|
|
218
|
+
const target = fresh ?? rec;
|
|
219
|
+
if (target.status !== 'suspended' ||
|
|
220
|
+
!approvalExpired(target, now, this.#deps.approvalTimeoutMs)) {
|
|
221
|
+
return target;
|
|
222
|
+
}
|
|
223
|
+
fillTimeoutDenials(target, now);
|
|
224
|
+
target.status = 'running';
|
|
225
|
+
target.ownerId = this.#deps.ownerId;
|
|
226
|
+
let saved;
|
|
227
|
+
try {
|
|
228
|
+
saved = this.#deps.store.save(target);
|
|
229
|
+
}
|
|
230
|
+
catch {
|
|
231
|
+
return target; // 同步落库失败则不派发(与下一条异步分支同纪律:先落库再派发)
|
|
232
|
+
}
|
|
233
|
+
if (isThenable(saved)) {
|
|
234
|
+
// 落库失败则不派发(认领没落地就派发 = 重新打开重复执行窗口)
|
|
235
|
+
try {
|
|
236
|
+
await saved;
|
|
237
|
+
}
|
|
238
|
+
catch {
|
|
239
|
+
return target;
|
|
240
|
+
}
|
|
241
|
+
}
|
|
242
|
+
// 离开挂起态(读数纪律②)—— 落在**落库成功之后**:落不了库就不算恢复(没派发,读数也不动)
|
|
243
|
+
this.unmarkSuspended(target.taskId);
|
|
244
|
+
// 派发走唯一入口(闸在 #dispatch 里)。⚠️ **这一条正是外部深评抓到的第四条路径**:
|
|
245
|
+
// `#expireAndResume`(审批超时自动全拒并恢复)与 `approve` 不同触发源、同一形状,
|
|
246
|
+
// 由 `poll()` 的惰性闸驱动 —— 而「停机中照常可轮询」是 HTTP 宿主的明确承诺
|
|
247
|
+
// (LB / K8s preStop / 前端轮询)⇒ 停机后照样能起新 run。
|
|
248
|
+
this.#deps.dispatch(target);
|
|
249
|
+
return target;
|
|
250
|
+
}
|
|
251
|
+
}
|
|
252
|
+
//# sourceMappingURL=approval-supervisor.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"approval-supervisor.js","sourceRoot":"","sources":["../../src/transport/approval-supervisor.ts"],"names":[],"mappings":"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"}
|