@zmzai/agent-framework 0.9.0 → 0.14.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.
Files changed (126) hide show
  1. package/dist/adapters/openai-provider.d.ts +6 -3
  2. package/dist/adapters/openai-provider.d.ts.map +1 -1
  3. package/dist/adapters/openai-provider.js +1 -1
  4. package/dist/adapters/openai-provider.js.map +1 -1
  5. package/dist/core/events/manifest.d.ts +2 -2
  6. package/dist/core/runtime/active-run-registry.d.ts +34 -0
  7. package/dist/core/runtime/active-run-registry.d.ts.map +1 -0
  8. package/dist/core/runtime/active-run-registry.js +44 -0
  9. package/dist/core/runtime/active-run-registry.js.map +1 -0
  10. package/dist/core/runtime/attempt-executor.d.ts +67 -0
  11. package/dist/core/runtime/attempt-executor.d.ts.map +1 -0
  12. package/dist/core/runtime/attempt-executor.js +683 -0
  13. package/dist/core/runtime/attempt-executor.js.map +1 -0
  14. package/dist/core/runtime/command-service.d.ts +48 -0
  15. package/dist/core/runtime/command-service.d.ts.map +1 -0
  16. package/dist/core/runtime/command-service.js +148 -0
  17. package/dist/core/runtime/command-service.js.map +1 -0
  18. package/dist/core/runtime/compaction.d.ts +30 -6
  19. package/dist/core/runtime/compaction.d.ts.map +1 -1
  20. package/dist/core/runtime/compaction.js +5 -4
  21. package/dist/core/runtime/compaction.js.map +1 -1
  22. package/dist/core/runtime/context-builder.d.ts +66 -0
  23. package/dist/core/runtime/context-builder.d.ts.map +1 -0
  24. package/dist/core/runtime/context-builder.js +187 -0
  25. package/dist/core/runtime/context-builder.js.map +1 -0
  26. package/dist/core/runtime/run-scheduler.d.ts +44 -0
  27. package/dist/core/runtime/run-scheduler.d.ts.map +1 -0
  28. package/dist/core/runtime/run-scheduler.js +136 -0
  29. package/dist/core/runtime/run-scheduler.js.map +1 -0
  30. package/dist/core/runtime/runner.d.ts +29 -178
  31. package/dist/core/runtime/runner.d.ts.map +1 -1
  32. package/dist/core/runtime/runner.js +111 -1457
  33. package/dist/core/runtime/runner.js.map +1 -1
  34. package/dist/core/runtime/task-lifecycle.d.ts +165 -0
  35. package/dist/core/runtime/task-lifecycle.d.ts.map +1 -0
  36. package/dist/core/runtime/task-lifecycle.js +424 -0
  37. package/dist/core/runtime/task-lifecycle.js.map +1 -0
  38. package/dist/core/session/sqlite-store.d.ts.map +1 -1
  39. package/dist/core/session/sqlite-store.js +130 -1
  40. package/dist/core/session/sqlite-store.js.map +1 -1
  41. package/dist/core/session/store.d.ts +9 -1
  42. package/dist/core/session/store.d.ts.map +1 -1
  43. package/dist/core/session/types.d.ts +16 -0
  44. package/dist/core/session/types.d.ts.map +1 -1
  45. package/dist/core/session/workflow.d.ts +49 -2
  46. package/dist/core/session/workflow.d.ts.map +1 -1
  47. package/dist/core/session/workflow.js.map +1 -1
  48. package/dist/core/subagents/coordinator.d.ts +210 -0
  49. package/dist/core/subagents/coordinator.d.ts.map +1 -0
  50. package/dist/core/subagents/coordinator.js +534 -0
  51. package/dist/core/subagents/coordinator.js.map +1 -0
  52. package/dist/core/subagents/parked.d.ts +55 -0
  53. package/dist/core/subagents/parked.d.ts.map +1 -0
  54. package/dist/core/subagents/parked.js +84 -0
  55. package/dist/core/subagents/parked.js.map +1 -0
  56. package/dist/core/subagents/tools.d.ts +29 -0
  57. package/dist/core/subagents/tools.d.ts.map +1 -0
  58. package/dist/core/subagents/tools.js +164 -0
  59. package/dist/core/subagents/tools.js.map +1 -0
  60. package/dist/core/subagents/types.d.ts +114 -0
  61. package/dist/core/subagents/types.d.ts.map +1 -0
  62. package/dist/core/subagents/types.js +44 -0
  63. package/dist/core/subagents/types.js.map +1 -0
  64. package/dist/core/task/completion.d.ts +3 -0
  65. package/dist/core/task/completion.d.ts.map +1 -1
  66. package/dist/core/task/completion.js +4 -0
  67. package/dist/core/task/completion.js.map +1 -1
  68. package/dist/core/task/types.d.ts +5 -0
  69. package/dist/core/task/types.d.ts.map +1 -1
  70. package/dist/core/task/types.js.map +1 -1
  71. package/dist/core/tools/adapter.d.ts.map +1 -1
  72. package/dist/core/tools/adapter.js +87 -61
  73. package/dist/core/tools/adapter.js.map +1 -1
  74. package/dist/core/tools/builtins.d.ts.map +1 -1
  75. package/dist/core/tools/builtins.js +7 -0
  76. package/dist/core/tools/builtins.js.map +1 -1
  77. package/dist/core/tools/context.d.ts +1 -0
  78. package/dist/core/tools/context.d.ts.map +1 -1
  79. package/dist/core/tools/def.d.ts +25 -0
  80. package/dist/core/tools/def.d.ts.map +1 -1
  81. package/dist/core/tools/def.js.map +1 -1
  82. package/dist/core/tools/git.d.ts.map +1 -1
  83. package/dist/core/tools/git.js +4 -0
  84. package/dist/core/tools/git.js.map +1 -1
  85. package/dist/core/tools/patch.d.ts.map +1 -1
  86. package/dist/core/tools/patch.js +1 -0
  87. package/dist/core/tools/patch.js.map +1 -1
  88. package/dist/core/tools/qa-check.d.ts +2 -2
  89. package/dist/core/tools/qa-check.d.ts.map +1 -1
  90. package/dist/core/tools/qa-check.js +1 -0
  91. package/dist/core/tools/qa-check.js.map +1 -1
  92. package/dist/core/tools/repomap.d.ts.map +1 -1
  93. package/dist/core/tools/repomap.js +1 -0
  94. package/dist/core/tools/repomap.js.map +1 -1
  95. package/dist/core/tools/task-block.d.ts.map +1 -1
  96. package/dist/core/tools/task-block.js +1 -0
  97. package/dist/core/tools/task-block.js.map +1 -1
  98. package/dist/core/tools/task-deliver.d.ts +1 -1
  99. package/dist/core/tools/task-deliver.d.ts.map +1 -1
  100. package/dist/core/tools/task-deliver.js +1 -0
  101. package/dist/core/tools/task-deliver.js.map +1 -1
  102. package/dist/core/tools/task.d.ts.map +1 -1
  103. package/dist/core/tools/task.js +3 -0
  104. package/dist/core/tools/task.js.map +1 -1
  105. package/dist/core/tools/terminal.d.ts.map +1 -1
  106. package/dist/core/tools/terminal.js +5 -0
  107. package/dist/core/tools/terminal.js.map +1 -1
  108. package/dist/core/tools/webfetch.d.ts.map +1 -1
  109. package/dist/core/tools/webfetch.js +1 -0
  110. package/dist/core/tools/webfetch.js.map +1 -1
  111. package/dist/core/tools/websearch.d.ts.map +1 -1
  112. package/dist/core/tools/websearch.js +1 -0
  113. package/dist/core/tools/websearch.js.map +1 -1
  114. package/dist/index.d.ts +5 -0
  115. package/dist/index.d.ts.map +1 -1
  116. package/dist/index.js +3 -0
  117. package/dist/index.js.map +1 -1
  118. package/dist/server/create-agent-runtime.d.ts +3 -1
  119. package/dist/server/create-agent-runtime.d.ts.map +1 -1
  120. package/dist/server/create-agent-runtime.js +8 -1
  121. package/dist/server/create-agent-runtime.js.map +1 -1
  122. package/dist/server/create-server.d.ts +6 -0
  123. package/dist/server/create-server.d.ts.map +1 -1
  124. package/dist/server/create-server.js +9 -0
  125. package/dist/server/create-server.js.map +1 -1
  126. package/package.json +12 -11
@@ -0,0 +1,187 @@
1
+ import { createHash } from "node:crypto";
2
+ import { attachmentContent, attachmentRefContent } from "./attachments.js";
3
+ import { newPartId } from "../session/ids.js";
4
+ /** canonical 前缀指纹(W7-S8):播种复用的唯一安全判据。 */
5
+ function prefixHashOf(messages) {
6
+ return createHash("sha256").update(JSON.stringify(messages)).digest("hex");
7
+ }
8
+ /** 上下文组装(W7 S6 自 SessionRunner 搬移,spec §9.1 的先行子集):
9
+ * 历史重建(同拍快照修 TOCTOU)、压缩 transform、记忆召回——runLoop 里
10
+ * 唯一的上下文来源。§9.1 的 ContextManifest/预算计费属 M2,不在此。 */
11
+ export class ContextBuilder {
12
+ deps;
13
+ constructor(deps) {
14
+ this.deps = deps;
15
+ }
16
+ /** 「重建输入」的一致性快照:排除集与消息条目**同拍**读取。
17
+ *
18
+ * 【为什么必须同拍】此前 runLoop 先读 workflowRuns 算排除集、下一拍才
19
+ * getMessages——两拍之间 acceptPrompt 落库的新消息已进 messages 表但不在
20
+ * 排除集里,排队中的用户消息于是泄入正在运行 run 的模型上下文(W6 §8
21
+ * 用插桩证实的读偏斜竞态,FIFO 用例靠一拍微任务时序侥幸掩盖)。
22
+ * sqlite 实现走单 transaction;实现未提供 rebuildSnapshot 时回落两拍
23
+ * (JSONL/demo 模式可接受——无并发提交面)。 */
24
+ async historySnapshot(sessionId) {
25
+ const workflow = this.deps.store.workflow;
26
+ if (workflow?.rebuildSnapshot)
27
+ return await workflow.rebuildSnapshot(sessionId);
28
+ const workflowRuns = workflow ? await workflow.workflowRuns(sessionId) : [];
29
+ const excludedUserIds = new Set(workflowRuns.filter((run) => run.status !== "completed" && run.status !== "failed").map((run) => run.receipt.userMessageId));
30
+ const entries = await this.deps.store.getMessages(sessionId);
31
+ return { entries, excludedUserIds };
32
+ }
33
+ /** 从持久 parts 重建 PI 上下文(自 runner 原样搬移;entries 由
34
+ * historySnapshot 提供,保证排除判定与消息读取一致)。 */
35
+ async rebuildMessages(sessionId, entries, excludedUserIds) {
36
+ const messages = [];
37
+ for (const { info, parts } of entries) {
38
+ if (info.role === "user") {
39
+ if (excludedUserIds?.has(info.id))
40
+ continue;
41
+ const text = parts
42
+ .filter((part) => part.type === "text")
43
+ .map((part) => part.text)
44
+ .join("\n");
45
+ const fileParts = parts.filter((p) => p.type === "file");
46
+ // 旧链路历史:data URL 内联部分保持原样重建,否则升级后老会话会「丢附件」。
47
+ const legacy = fileParts.flatMap((p) => {
48
+ const url = p.url;
49
+ if (typeof url !== "string" || !url.startsWith("data:"))
50
+ return [];
51
+ return [{ name: p.filename, mediaType: p.mime, data: url, size: Buffer.from(url.slice(url.indexOf(",") + 1), "base64").length }];
52
+ });
53
+ // 新链路:按描述符重建,正文经 provider 读取(图片→视觉输入、小文本→内联、其余→清单)。
54
+ // 因此重放历史**不会**把所有附件正文反复塞进后续每个 turn(规格 2 §11)。
55
+ // 用 AttachmentContentRef 而不是 InputAttachmentRef:part 里没有 sha256,
56
+ // 硬编一个假摘要会违反该类型的不变量。
57
+ const refs = fileParts.flatMap((p) => p.attachmentId
58
+ ? [{
59
+ id: p.attachmentId,
60
+ name: p.filename,
61
+ mediaType: p.mime,
62
+ ...(typeof p.size === "number" ? { size: p.size } : {}),
63
+ kind: p.kind ?? "text",
64
+ }]
65
+ : []);
66
+ const refParts = await attachmentRefContent(this.deps.attachments, refs, { sessionId });
67
+ messages.push({ role: "user", content: [{ type: "text", text }, ...attachmentContent(legacy), ...refParts], timestamp: Date.parse(info.time.created) || Date.now() });
68
+ }
69
+ else {
70
+ const text = parts
71
+ .filter((part) => part.type === "text")
72
+ .map((part) => part.text)
73
+ .join("\n");
74
+ if (!text)
75
+ continue;
76
+ messages.push({
77
+ role: "assistant",
78
+ content: [{ type: "text", text }],
79
+ api: "openai-completions",
80
+ provider: info.model.providerId,
81
+ model: info.model.modelId,
82
+ usage: { input: info.tokens?.input ?? 0, output: info.tokens?.output ?? 0, cacheRead: info.tokens?.cacheRead ?? 0, cacheWrite: info.tokens?.cacheWrite ?? 0, totalTokens: (info.tokens?.input ?? 0) + (info.tokens?.output ?? 0) + (info.tokens?.cacheRead ?? 0) + (info.tokens?.cacheWrite ?? 0) },
83
+ stopReason: info.error ? "error" : "stop",
84
+ ...(info.error ? { errorMessage: info.error.message } : {}),
85
+ timestamp: Date.parse(info.time.created) || Date.now(),
86
+ });
87
+ }
88
+ }
89
+ return messages;
90
+ }
91
+ /** 当前会话的压缩阈值:优先取模型目录给的真实上下文窗口,回落 runtime 级
92
+ * 全局配置。旧行为恒取 deps.compaction.contextWindow;模型目录未覆盖该
93
+ * modelId 时 model.contextWindow 即等于该全局值,行为不变。
94
+ * modelFor 抛错(宿主 provider 不认识该 ref)时同样回落,绝不阻断压缩。 */
95
+ contextWindowFor(session) {
96
+ const fallback = this.deps.compaction?.contextWindow ?? 0;
97
+ try {
98
+ const model = this.deps.modelFor(session.model);
99
+ const win = model?.contextWindow;
100
+ return typeof win === "number" && win > 0 ? win : fallback;
101
+ }
102
+ catch {
103
+ return fallback;
104
+ }
105
+ }
106
+ /** Builds the compaction transformContext (spec §8.3) when the builder has a
107
+ * summary model configured. Emits a `compaction` part on the latest
108
+ * assistant message so the boundary shows in the transcript. force=true
109
+ * skips the threshold/滞回 early-outs (手动「压缩当前会话」)。 */
110
+ async buildCompaction(session, emit, force = false, initialState) {
111
+ if (!this.deps.compaction?.enabled || !this.deps.compaction.summaryModel)
112
+ return undefined;
113
+ const { buildCompactionTransform, streamOneText } = await import("./compaction.js");
114
+ return buildCompactionTransform({
115
+ enabled: true,
116
+ contextWindow: this.contextWindowFor(session),
117
+ summaryModel: this.deps.compaction.summaryModel,
118
+ ...(force ? { force: true } : {}),
119
+ ...(initialState ? { initialState } : {}),
120
+ streamOne: async (model, messages) => {
121
+ const streamFn = this.deps.streamFnFor(session);
122
+ return streamOneText(async (m, ctx) => {
123
+ const stream = await streamFn(m, ctx);
124
+ return stream;
125
+ }, model, "你是上下文压缩助手。只输出结构化摘要,不续写对话。", messages);
126
+ },
127
+ onCompacted: async (summary, _tokensBefore, state) => {
128
+ // CompactionStore(W7-S8):持久化前缀指纹,供下一 Attempt 校验播种。
129
+ // 写失败只损失复用(下次重新摘要),不影响本次压缩——静默降级。
130
+ const record = {
131
+ summary,
132
+ anchor: state.anchor,
133
+ tailTokensAtCompaction: state.tailTokensAtCompaction,
134
+ prefixHash: prefixHashOf(state.messages.slice(0, state.anchor)),
135
+ updatedAt: new Date().toISOString(),
136
+ };
137
+ await this.deps.store.compaction?.put(session.id, record).catch(() => undefined);
138
+ void (async () => {
139
+ const entries = await this.deps.store.getMessages(session.id);
140
+ const lastAssistant = [...entries].reverse().find((entry) => entry.info.role === "assistant");
141
+ if (!lastAssistant)
142
+ return;
143
+ const part = { id: newPartId(), sessionId: session.id, messageId: lastAssistant.info.id, type: "compaction", summary };
144
+ await this.deps.store.appendPart(part).catch(() => undefined);
145
+ emit({ type: "message.part.updated", data: { part } });
146
+ })();
147
+ },
148
+ });
149
+ }
150
+ /** Attempt 上下文的唯一组装入口:压缩 transform(经前缀指纹校验播种)、
151
+ * 同拍快照重建、记忆召回。baseline:本次 run 新增消息从这之后算(供
152
+ * onRunEnd 提取 retain)。 */
153
+ async buildAttemptContext(session, input, emit) {
154
+ // 记忆召回(spec §记忆):单点注入,天然覆盖正常 prompt/排队出队/
155
+ // automation/子代理触发四条路径。只进内存不落 store;抛错静默降级。
156
+ const { entries, excludedUserIds } = await this.historySnapshot(session.id);
157
+ const history = await this.rebuildMessages(session.id, entries, excludedUserIds);
158
+ if (this.deps.memoryContextFor) {
159
+ try {
160
+ const section = await this.deps.memoryContextFor(session, input.text);
161
+ if (section) {
162
+ history.unshift({ role: "user", content: [{ type: "text", text: section }], timestamp: Date.now() });
163
+ }
164
+ }
165
+ catch {
166
+ // 召回失败不阻塞 run
167
+ }
168
+ }
169
+ // 播种校验放在记忆召回之后:召回会改变 canonical 前缀,指纹对不上就
170
+ // 放弃复用(宁重复摘要,不脏上下文)。
171
+ const compactionTransform = await this.buildCompaction(session, emit, false, await this.seedStateFor(session.id, history));
172
+ return { compactionTransform, history, baseline: history.length };
173
+ }
174
+ /** 前缀指纹校验:record 覆盖的前缀与本次重建逐字节一致才允许播种。 */
175
+ async seedStateFor(sessionId, history) {
176
+ const store = this.deps.store.compaction;
177
+ if (!store)
178
+ return undefined;
179
+ const record = await store.get(sessionId).catch(() => null);
180
+ if (!record || record.anchor <= 0 || record.anchor > history.length)
181
+ return undefined;
182
+ if (prefixHashOf(history.slice(0, record.anchor)) !== record.prefixHash)
183
+ return undefined;
184
+ return { summary: record.summary, anchor: record.anchor, tailTokensAtCompaction: record.tailTokensAtCompaction };
185
+ }
186
+ }
187
+ //# sourceMappingURL=context-builder.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"context-builder.js","sourceRoot":"","sources":["../../../src/core/runtime/context-builder.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,44 @@
1
+ import type { SessionStore } from "../session/store.js";
2
+ import type { PromptInput, WorkflowState } from "../session/workflow.js";
3
+ import type { SessionInfo } from "../session/types.js";
4
+ /** RunScheduler 的执行回调(W6 §3.2):怎么跑一条被认领的 job、怎么推进被
5
+ * 放行的任务、停止时怎么收残余任务。W6 由 SessionRunner 实现;W7 换
6
+ * AttemptExecutor 时这里就是插槽。 */
7
+ export type SchedulerExecutor = {
8
+ runJob(session: SessionInfo, input: PromptInput, acceptedUserId?: string): Promise<WorkflowState>;
9
+ driveResumed(session: SessionInfo): Promise<void>;
10
+ cancelResidual(sessionId: string): Promise<void>;
11
+ };
12
+ export type SchedulerDeps = {
13
+ store: SessionStore;
14
+ executor: SchedulerExecutor;
15
+ /** 租约 owner。默认 `node:${pid}`(搬移前现行为);§6.2 的
16
+ * hostInstanceId+executionEpoch 落地时由宿主注入更强的身份。 */
17
+ leaseOwner?: string;
18
+ leaseStore?: {
19
+ stamp(sessionId: string, owner: string, expiresAt: Date): Promise<void>;
20
+ clear(sessionId: string): Promise<void>;
21
+ };
22
+ };
23
+ /** 会话级 FIFO 调度(W6 S3 自 SessionRunner 原样搬移):drain 驱动链、放行
24
+ * 通路登记、停止协调与租约打点。语义零变化;竞争窗口注释一并搬走。 */
25
+ export declare class RunScheduler {
26
+ private readonly deps;
27
+ private readonly draining;
28
+ private readonly stopRequested;
29
+ /** 已被用户放行、等待驱动链接手推进的会话(见 `drain` 的第三条分支)。 */
30
+ private readonly resumeRequests;
31
+ private readonly leaseOwner;
32
+ constructor(deps: SchedulerDeps);
33
+ isStopRequested(sessionId: string): boolean;
34
+ stampLease(sessionId: string): Promise<void>;
35
+ clearLease(sessionId: string): Promise<void>;
36
+ drain(sessionId: string): void;
37
+ /** 用户放行通路的调度侧登记(任务层的 CAS 与恢复闸放行留在
38
+ * SessionRunner.resumeTask——那是任务语义,不是调度语义)。 */
39
+ requestResume(sessionId: string): void;
40
+ abort(sessionId: string): Promise<void>;
41
+ /** 测试辅助:等待全部驱动链收尾(含收尾窗口内可能的重启)。 */
42
+ idle(): Promise<void>;
43
+ }
44
+ //# sourceMappingURL=run-scheduler.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"run-scheduler.d.ts","sourceRoot":"","sources":["../../../src/core/runtime/run-scheduler.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,qBAAqB,CAAC;AACxD,OAAO,KAAK,EAAE,WAAW,EAAE,aAAa,EAAE,MAAM,wBAAwB,CAAC;AACzE,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,qBAAqB,CAAC;AAGvD;;+BAE+B;AAC/B,MAAM,MAAM,iBAAiB,GAAG;IAC9B,MAAM,CAAC,OAAO,EAAE,WAAW,EAAE,KAAK,EAAE,WAAW,EAAE,cAAc,CAAC,EAAE,MAAM,GAAG,OAAO,CAAC,aAAa,CAAC,CAAC;IAClG,YAAY,CAAC,OAAO,EAAE,WAAW,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;IAClD,cAAc,CAAC,SAAS,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;CAClD,CAAC;AAEF,MAAM,MAAM,aAAa,GAAG;IAC1B,KAAK,EAAE,YAAY,CAAC;IACpB,QAAQ,EAAE,iBAAiB,CAAC;IAC5B;uDACmD;IACnD,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,UAAU,CAAC,EAAE;QAAE,KAAK,CAAC,SAAS,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,EAAE,SAAS,EAAE,IAAI,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;QAAC,KAAK,CAAC,SAAS,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,CAAA;KAAE,CAAC;CACnI,CAAC;AAEF;uCACuC;AACvC,qBAAa,YAAY;IAOX,OAAO,CAAC,QAAQ,CAAC,IAAI;IANjC,OAAO,CAAC,QAAQ,CAAC,QAAQ,CAAoC;IAC7D,OAAO,CAAC,QAAQ,CAAC,aAAa,CAAqB;IACnD,6CAA6C;IAC7C,OAAO,CAAC,QAAQ,CAAC,cAAc,CAAqB;IACpD,OAAO,CAAC,QAAQ,CAAC,UAAU,CAAS;gBAEP,IAAI,EAAE,aAAa;IAIhD,eAAe,CAAC,SAAS,EAAE,MAAM,GAAG,OAAO;IAIrC,UAAU,CAAC,SAAS,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC;IAK5C,UAAU,CAAC,SAAS,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC;IAKlD,KAAK,CAAC,SAAS,EAAE,MAAM,GAAG,IAAI;IAiE9B;oDACgD;IAChD,aAAa,CAAC,SAAS,EAAE,MAAM,GAAG,IAAI;IAKhC,KAAK,CAAC,SAAS,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC;IAoB7C,mCAAmC;IAC7B,IAAI,IAAI,OAAO,CAAC,IAAI,CAAC;CAG5B"}
@@ -0,0 +1,136 @@
1
+ import { leaseDurationMs } from "../../adapters/index.js";
2
+ import { defaultActiveRunRegistry } from "./active-run-registry.js";
3
+ /** 会话级 FIFO 调度(W6 S3 自 SessionRunner 原样搬移):drain 驱动链、放行
4
+ * 通路登记、停止协调与租约打点。语义零变化;竞争窗口注释一并搬走。 */
5
+ export class RunScheduler {
6
+ deps;
7
+ draining = new Map();
8
+ stopRequested = new Set();
9
+ /** 已被用户放行、等待驱动链接手推进的会话(见 `drain` 的第三条分支)。 */
10
+ resumeRequests = new Set();
11
+ leaseOwner;
12
+ constructor(deps) {
13
+ this.deps = deps;
14
+ this.leaseOwner = deps.leaseOwner ?? `node:${process.pid}`;
15
+ }
16
+ isStopRequested(sessionId) {
17
+ return this.stopRequested.has(sessionId);
18
+ }
19
+ async stampLease(sessionId) {
20
+ if (!this.deps.leaseStore)
21
+ return; // demo/JSONL mode: no lease
22
+ await this.deps.leaseStore.stamp(sessionId, this.leaseOwner, new Date(Date.now() + leaseDurationMs)).catch(() => undefined);
23
+ }
24
+ async clearLease(sessionId) {
25
+ if (!this.deps.leaseStore)
26
+ return;
27
+ await this.deps.leaseStore.clear(sessionId).catch(() => undefined);
28
+ }
29
+ drain(sessionId) {
30
+ if (this.draining.has(sessionId))
31
+ return;
32
+ const work = (async () => {
33
+ while (true) {
34
+ const job = await this.deps.store.workflow.claimPrompt(sessionId, `node:${process.pid}`);
35
+ if (job) {
36
+ let outcome = "recovery_required";
37
+ try {
38
+ if (this.stopRequested.has(sessionId)) {
39
+ outcome = "cancelled";
40
+ }
41
+ else {
42
+ const session = await this.deps.store.getSession(sessionId);
43
+ if (!session) {
44
+ outcome = "failed";
45
+ }
46
+ else {
47
+ // 走任务层:一次 claim 之后可能跑多轮 Attempt(规格 §8.2)
48
+ outcome = await this.deps.executor.runJob(session, job.input, job.receipt.userMessageId);
49
+ }
50
+ }
51
+ }
52
+ catch {
53
+ // Setup or settlement may have failed after a tool ran. Do not replay.
54
+ }
55
+ try {
56
+ await this.deps.store.workflow.finishPrompt(sessionId, job.receipt.runId, job.revision, outcome);
57
+ }
58
+ catch (error) {
59
+ // revision 是这次 run 的所有权凭据。冲突说明这次 run 的归属已经在
60
+ // 别处被改写过——最典型的就是进程崩溃后恢复扫描把它标成
61
+ // `recovery_required`,而这一轮结算才姗姗来迟。那时这条结论不该由
62
+ // 我们写(恢复扫描已经给出了它的判断),静默退出即可。把冲突往上抛
63
+ // 只会炸掉 `abort()`——它正 await 着这条驱动链。
64
+ if (!/RUN_REVISION_CONFLICT/.test(String(error?.message ?? "")))
65
+ throw error;
66
+ return;
67
+ }
68
+ if (outcome !== "completed")
69
+ return;
70
+ continue;
71
+ }
72
+ // 队列里没有 run 了。还有第三种可能要推进:**用户刚按了「继续」**。
73
+ // 这类任务停下的原因是预算/无进展/等待,而不是「排队等认领」——它那次
74
+ // 的 workflow run 早已 `completed`,`claimPrompt` 永远取不到它。没有这条
75
+ // 分支,`resumeTask` 把任务放回 queued 之后就再没有东西会碰它,
76
+ // 每个 blocker 里写的那句「确认后可以继续」就是一句系统接不住的承诺。
77
+ if (!this.resumeRequests.delete(sessionId))
78
+ return;
79
+ if (this.stopRequested.has(sessionId))
80
+ return;
81
+ const resumed = await this.deps.store.getSession(sessionId);
82
+ if (!resumed)
83
+ return;
84
+ await this.deps.executor.driveResumed(resumed);
85
+ }
86
+ })();
87
+ this.draining.set(sessionId, work);
88
+ void work.catch(() => undefined).finally(async () => {
89
+ this.draining.delete(sessionId);
90
+ if (this.stopRequested.has(sessionId))
91
+ return;
92
+ // 有放行请求就在原地接着驱动。必须在这里再查一次:`resumeTask` 是在
93
+ // `draining.delete` 之前判断「有没有人在跑」的,上面那个 while 也可能
94
+ // 刚刚判定退出——两件事都发生在微任务队列里,中间只差一次 await。
95
+ // 少了这一查,一次恰好落在收尾窗口里的「继续」会被静默丢掉。
96
+ if (this.resumeRequests.has(sessionId)) {
97
+ this.drain(sessionId);
98
+ return;
99
+ }
100
+ const queued = await this.deps.store.workflow.workflowRuns(sessionId).catch(() => []);
101
+ if (queued.some(run => run.status === "queued") && !queued.some(run => run.status === "running" || run.status === "recovery_required"))
102
+ this.drain(sessionId);
103
+ });
104
+ }
105
+ /** 用户放行通路的调度侧登记(任务层的 CAS 与恢复闸放行留在
106
+ * SessionRunner.resumeTask——那是任务语义,不是调度语义)。 */
107
+ requestResume(sessionId) {
108
+ this.resumeRequests.add(sessionId);
109
+ this.drain(sessionId);
110
+ }
111
+ async abort(sessionId) {
112
+ this.stopRequested.add(sessionId);
113
+ await this.deps.store.clearQueuedPrompts(sessionId);
114
+ const active = defaultActiveRunRegistry.get(sessionId);
115
+ // PI's abort signal does not cancel a PermissionEngine.ask() promise.
116
+ // Rejecting pending approvals first releases beforeToolCall so the run can
117
+ // publish its terminal state and a continuation cannot overlap it.
118
+ if (active) {
119
+ active.engine.dispose("任务已停止,未处理的授权请求已取消");
120
+ active.abort();
121
+ await active.done;
122
+ }
123
+ await this.draining.get(sessionId);
124
+ await this.deps.executor.cancelResidual(sessionId);
125
+ // 停止会作废还没被认领的放行请求:留着它,驱动链下一次启动就会去推进一个
126
+ // 用户已经改主意(点了停止)的任务。
127
+ this.resumeRequests.delete(sessionId);
128
+ this.stopRequested.delete(sessionId);
129
+ }
130
+ /** 测试辅助:等待全部驱动链收尾(含收尾窗口内可能的重启)。 */
131
+ async idle() {
132
+ while (this.draining.size > 0)
133
+ await Promise.allSettled([...this.draining.values()]);
134
+ }
135
+ }
136
+ //# sourceMappingURL=run-scheduler.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"run-scheduler.js","sourceRoot":"","sources":["../../../src/core/runtime/run-scheduler.ts"],"names":[],"mappings":"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"}