@chances-ai/engine 27.0.0 → 28.0.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/dist/agents/bundled.d.ts +5 -0
- package/dist/agents/bundled.d.ts.map +1 -0
- package/dist/agents/bundled.js +66 -0
- package/dist/agents/bundled.js.map +1 -0
- package/dist/agents/index.d.ts +1 -0
- package/dist/agents/index.d.ts.map +1 -1
- package/dist/agents/index.js +1 -0
- package/dist/agents/index.js.map +1 -1
- package/dist/agents/parse.d.ts +3 -0
- package/dist/agents/parse.d.ts.map +1 -1
- package/dist/agents/parse.js +17 -0
- package/dist/agents/parse.js.map +1 -1
- package/dist/agents/types.d.ts +8 -0
- package/dist/agents/types.d.ts.map +1 -1
- package/dist/core/coordinator-mode.d.ts +32 -0
- package/dist/core/coordinator-mode.d.ts.map +1 -0
- package/dist/core/coordinator-mode.js +98 -0
- package/dist/core/coordinator-mode.js.map +1 -0
- package/dist/core/coordinator-tools.d.ts +22 -0
- package/dist/core/coordinator-tools.d.ts.map +1 -0
- package/dist/core/coordinator-tools.js +262 -0
- package/dist/core/coordinator-tools.js.map +1 -0
- package/dist/core/engine.d.ts +36 -6
- package/dist/core/engine.d.ts.map +1 -1
- package/dist/core/engine.js +59 -15
- package/dist/core/engine.js.map +1 -1
- package/dist/core/index.d.ts +3 -1
- package/dist/core/index.d.ts.map +1 -1
- package/dist/core/index.js +3 -1
- package/dist/core/index.js.map +1 -1
- package/dist/core/task-tool.d.ts +85 -1
- package/dist/core/task-tool.d.ts.map +1 -1
- package/dist/core/task-tool.js +456 -500
- package/dist/core/task-tool.js.map +1 -1
- package/package.json +3 -3
|
@@ -0,0 +1,262 @@
|
|
|
1
|
+
import { AppError, ErrorCode } from "@chances-ai/runtime";
|
|
2
|
+
import { DEFAULT_MAX_TURNS } from "./engine.js";
|
|
3
|
+
import { CREATE_TEAM_TOOL_NAME, DISMISS_WORKER_TOOL_NAME, LIST_WORKERS_TOOL_NAME, SEND_MESSAGE_TOOL_NAME, SPAWN_WORKER_TOOL_NAME, STOP_WORKER_TOOL_NAME, createChildAgentRuntime, } from "./task-tool.js";
|
|
4
|
+
/** Upper bound on a worker child's `maxTurns` — matches the one-shot `task`
|
|
5
|
+
* tool's `CHILD_MAX_TURNS_CEILING` so a worker can't wedge for hours. */
|
|
6
|
+
const WORKER_MAX_TURNS_CEILING = 50;
|
|
7
|
+
function strArg(args, key, required) {
|
|
8
|
+
const v = args[key];
|
|
9
|
+
if (v === undefined || v === null) {
|
|
10
|
+
if (required)
|
|
11
|
+
throw new AppError(ErrorCode.Tool, `Expected string arg "${key}"`);
|
|
12
|
+
return undefined;
|
|
13
|
+
}
|
|
14
|
+
if (typeof v !== "string") {
|
|
15
|
+
throw new AppError(ErrorCode.Tool, `Expected string arg "${key}"`);
|
|
16
|
+
}
|
|
17
|
+
return v;
|
|
18
|
+
}
|
|
19
|
+
/** A `to` target of the form `team:<id>` → the team id, else null. */
|
|
20
|
+
function teamTarget(to) {
|
|
21
|
+
return to.startsWith("team:") ? to.slice("team:".length) : null;
|
|
22
|
+
}
|
|
23
|
+
/**
|
|
24
|
+
* (7.8 §3.2) Build the coordinator's orchestration tool set:
|
|
25
|
+
* `spawn_worker` / `send_message` / `stop_worker` / `create_team` /
|
|
26
|
+
* `list_workers`. Registered on the COORDINATOR's main engine ONLY (coordinator
|
|
27
|
+
* mode) — a normal session never sees them, and the one-shot `task` stays the
|
|
28
|
+
* simple-delegation default. All orchestration ops are `isConcurrencySafe:false`
|
|
29
|
+
* (stateful side effects); only `list_workers` is read-only/parallel-safe.
|
|
30
|
+
*/
|
|
31
|
+
export function createCoordinatorTools(deps) {
|
|
32
|
+
const reg = deps.workerRegistry;
|
|
33
|
+
const childMaxTurns = Math.min(Math.max(1, deps.maxTurns ?? DEFAULT_MAX_TURNS), WORKER_MAX_TURNS_CEILING);
|
|
34
|
+
const spawnWorker = {
|
|
35
|
+
name: SPAWN_WORKER_TOOL_NAME,
|
|
36
|
+
description: "Spawn a PERSISTENT worker (a child agent that stays alive so you can continue it with send_message, reusing its context). Unlike the one-shot `task` tool, the worker does not die after one reply — direct it to research/implement/verify, then `send_message` it follow-up work or `stop_worker` it if it goes the wrong way. Returns an agent_id you address it by. The worker has full tool access (it does the editing); YOU only direct.",
|
|
37
|
+
category: "integration",
|
|
38
|
+
parameters: {
|
|
39
|
+
type: "object",
|
|
40
|
+
properties: {
|
|
41
|
+
description: {
|
|
42
|
+
type: "string",
|
|
43
|
+
description: "Short label (1–3 words) for this worker. Shown in the permission prompt and the worker panel.",
|
|
44
|
+
},
|
|
45
|
+
prompt: {
|
|
46
|
+
type: "string",
|
|
47
|
+
description: "The worker's first instruction. Make it self-contained — include specific file paths, line numbers, and exactly what to do (you must understand the work before delegating it).",
|
|
48
|
+
},
|
|
49
|
+
subagent_type: {
|
|
50
|
+
type: "string",
|
|
51
|
+
description: "Optional persona from the agent catalog. Omit for a full-inheritance worker.",
|
|
52
|
+
},
|
|
53
|
+
team: {
|
|
54
|
+
type: "string",
|
|
55
|
+
description: "Optional team id (from create_team) to group this worker under, for broadcast / batch-stop.",
|
|
56
|
+
},
|
|
57
|
+
isolation: {
|
|
58
|
+
type: "string",
|
|
59
|
+
enum: ["worktree", "none"],
|
|
60
|
+
description: "'worktree' runs the worker in an isolated git worktree; 'none' (default) shares the working tree.",
|
|
61
|
+
},
|
|
62
|
+
context: {
|
|
63
|
+
type: "string",
|
|
64
|
+
enum: ["fork", "fresh"],
|
|
65
|
+
description: "'fresh' (default) = empty context. 'fork' = inherit a copy of THIS conversation's completed turns as background.",
|
|
66
|
+
},
|
|
67
|
+
},
|
|
68
|
+
required: ["prompt"],
|
|
69
|
+
},
|
|
70
|
+
isConcurrencySafe: () => false,
|
|
71
|
+
summarize: (args) => {
|
|
72
|
+
const prompt = strArg(args, "prompt", true);
|
|
73
|
+
const desc = strArg(args, "description", false);
|
|
74
|
+
const head = prompt.length > 80 ? prompt.slice(0, 80) + "…" : prompt;
|
|
75
|
+
return `spawn_worker${desc ? `[${desc}]` : ""}: ${head}`;
|
|
76
|
+
},
|
|
77
|
+
async execute(args, ctx) {
|
|
78
|
+
const prompt = strArg(args, "prompt", true);
|
|
79
|
+
const team = strArg(args, "team", false);
|
|
80
|
+
if (team !== undefined && !reg.hasTeam(team)) {
|
|
81
|
+
return { ok: false, output: `Unknown team '${team}'. Create it first with create_team.` };
|
|
82
|
+
}
|
|
83
|
+
const built = await createChildAgentRuntime(deps, {
|
|
84
|
+
prompt,
|
|
85
|
+
subagentType: strArg(args, "subagent_type", false),
|
|
86
|
+
isolation: strArg(args, "isolation", false),
|
|
87
|
+
context: strArg(args, "context", false),
|
|
88
|
+
}, childMaxTurns, ctx.signal);
|
|
89
|
+
if (!built.ok)
|
|
90
|
+
return { ok: false, output: built.output };
|
|
91
|
+
try {
|
|
92
|
+
const { agentId } = reg.spawn({
|
|
93
|
+
teamId: team,
|
|
94
|
+
firstPrompt: built.firstPrompt,
|
|
95
|
+
runtime: built.runtime,
|
|
96
|
+
});
|
|
97
|
+
return {
|
|
98
|
+
ok: true,
|
|
99
|
+
output: [
|
|
100
|
+
`(worker spawned) agent_id=${agentId} name=${built.runtime.agentName}${team ? ` team=${team}` : ""}`,
|
|
101
|
+
"Continue it with send_message(to: \"" + agentId + "\", message: …); stop it with stop_worker. You will get its result as a <task-notification> on a future turn.",
|
|
102
|
+
].join("\n"),
|
|
103
|
+
};
|
|
104
|
+
}
|
|
105
|
+
catch (e) {
|
|
106
|
+
// Capacity refusal etc. → AppError(Tool) folded to ok:false.
|
|
107
|
+
if (e instanceof AppError) {
|
|
108
|
+
// worktree was created inside createChildAgentRuntime; close-on-failure
|
|
109
|
+
// happens via finalize() at the registry's next teardown — but since
|
|
110
|
+
// spawn never registered the worker, finalize the runtime now.
|
|
111
|
+
await built.runtime.finalize().catch(() => { });
|
|
112
|
+
await built.runtime.drainPty().catch(() => { });
|
|
113
|
+
return { ok: false, output: e.message };
|
|
114
|
+
}
|
|
115
|
+
throw e;
|
|
116
|
+
}
|
|
117
|
+
},
|
|
118
|
+
};
|
|
119
|
+
const sendMessage = {
|
|
120
|
+
name: SEND_MESSAGE_TOOL_NAME,
|
|
121
|
+
description: "Send a follow-up instruction to a live worker, CONTINUING it on its existing context (it remembers what it already read/did). `to` is an agent_id, a worker name, or `team:<id>` to broadcast to every worker in a team. If the worker is busy the message queues (FIFO); if it's idle/stopped it resumes. Synthesize the worker's prior findings into a concrete spec before sending — never delegate understanding back to it.",
|
|
122
|
+
category: "integration",
|
|
123
|
+
parameters: {
|
|
124
|
+
type: "object",
|
|
125
|
+
properties: {
|
|
126
|
+
to: { type: "string", description: "agent_id, worker name, or 'team:<id>' to broadcast." },
|
|
127
|
+
message: { type: "string", description: "The follow-up instruction (self-contained, with specifics)." },
|
|
128
|
+
},
|
|
129
|
+
required: ["to", "message"],
|
|
130
|
+
},
|
|
131
|
+
isConcurrencySafe: () => false,
|
|
132
|
+
summarize: (args) => {
|
|
133
|
+
const to = strArg(args, "to", true);
|
|
134
|
+
const msg = strArg(args, "message", true);
|
|
135
|
+
const head = msg.length > 60 ? msg.slice(0, 60) + "…" : msg;
|
|
136
|
+
return `send_message → ${to}: ${head}`;
|
|
137
|
+
},
|
|
138
|
+
async execute(args) {
|
|
139
|
+
const to = strArg(args, "to", true);
|
|
140
|
+
const message = strArg(args, "message", true);
|
|
141
|
+
const team = teamTarget(to);
|
|
142
|
+
if (team !== null) {
|
|
143
|
+
if (!reg.hasTeam(team))
|
|
144
|
+
return { ok: false, output: `Unknown team '${team}'.` };
|
|
145
|
+
const n = reg.broadcast(team, message);
|
|
146
|
+
return { ok: true, output: `Broadcast to ${n} worker(s) in team ${team}.` };
|
|
147
|
+
}
|
|
148
|
+
const delivered = reg.send(to, message);
|
|
149
|
+
if (!delivered) {
|
|
150
|
+
return {
|
|
151
|
+
ok: false,
|
|
152
|
+
output: `No live worker matches '${to}' (it may have been stopped-and-evicted or never existed). Use list_workers, or spawn_worker a fresh one.`,
|
|
153
|
+
};
|
|
154
|
+
}
|
|
155
|
+
return { ok: true, output: `Message queued for worker ${to}.` };
|
|
156
|
+
},
|
|
157
|
+
};
|
|
158
|
+
const stopWorker = {
|
|
159
|
+
name: STOP_WORKER_TOOL_NAME,
|
|
160
|
+
description: "Stop a worker that's going the wrong way: cancels its in-flight work but KEEPS it resumable (a later send_message continues it on the same context). `to` is an agent_id, a worker name, or `team:<id>` to stop every worker in a team.",
|
|
161
|
+
category: "integration",
|
|
162
|
+
parameters: {
|
|
163
|
+
type: "object",
|
|
164
|
+
properties: {
|
|
165
|
+
to: { type: "string", description: "agent_id, worker name, or 'team:<id>'." },
|
|
166
|
+
},
|
|
167
|
+
required: ["to"],
|
|
168
|
+
},
|
|
169
|
+
isConcurrencySafe: () => false,
|
|
170
|
+
summarize: (args) => `stop_worker → ${strArg(args, "to", true)}`,
|
|
171
|
+
async execute(args) {
|
|
172
|
+
const to = strArg(args, "to", true);
|
|
173
|
+
const team = teamTarget(to);
|
|
174
|
+
if (team !== null) {
|
|
175
|
+
if (!reg.hasTeam(team))
|
|
176
|
+
return { ok: false, output: `Unknown team '${team}'.` };
|
|
177
|
+
const n = reg.stopTeam(team);
|
|
178
|
+
return { ok: true, output: `Stopped ${n} worker(s) in team ${team}.` };
|
|
179
|
+
}
|
|
180
|
+
const stopped = reg.stop(to);
|
|
181
|
+
if (!stopped)
|
|
182
|
+
return { ok: false, output: `No live worker matches '${to}'.` };
|
|
183
|
+
return { ok: true, output: `Stopped worker ${to} (resumable with send_message).` };
|
|
184
|
+
},
|
|
185
|
+
};
|
|
186
|
+
const dismissWorker = {
|
|
187
|
+
name: DISMISS_WORKER_TOOL_NAME,
|
|
188
|
+
description: "Permanently dismiss a worker you are DONE with — it is closed (its worktree/PTY finalized) and its capacity slot is freed immediately. Unlike stop_worker (which keeps the worker resumable), a dismissed worker cannot be continued. Use this to reclaim a slot when you hit the worker capacity limit and no longer need a finished worker. `to` is an agent_id, a worker name, or `team:<id>` to dismiss every worker in a team.",
|
|
189
|
+
category: "integration",
|
|
190
|
+
parameters: {
|
|
191
|
+
type: "object",
|
|
192
|
+
properties: {
|
|
193
|
+
to: { type: "string", description: "agent_id, worker name, or 'team:<id>'." },
|
|
194
|
+
},
|
|
195
|
+
required: ["to"],
|
|
196
|
+
},
|
|
197
|
+
isConcurrencySafe: () => false,
|
|
198
|
+
summarize: (args) => `dismiss_worker → ${strArg(args, "to", true)}`,
|
|
199
|
+
async execute(args) {
|
|
200
|
+
const to = strArg(args, "to", true);
|
|
201
|
+
const team = teamTarget(to);
|
|
202
|
+
if (team !== null) {
|
|
203
|
+
if (!reg.hasTeam(team))
|
|
204
|
+
return { ok: false, output: `Unknown team '${team}'.` };
|
|
205
|
+
const n = await reg.dismissTeam(team);
|
|
206
|
+
return { ok: true, output: `Dismissed ${n} worker(s) in team ${team} (slots freed).` };
|
|
207
|
+
}
|
|
208
|
+
// Resolve a name → agentId so a name target works (close() is by agentId).
|
|
209
|
+
const match = reg.listWorkers().find((w) => w.agentId === to || w.name === to);
|
|
210
|
+
const dismissed = match ? await reg.close(match.agentId) : false;
|
|
211
|
+
if (!dismissed)
|
|
212
|
+
return { ok: false, output: `No live worker matches '${to}'.` };
|
|
213
|
+
return { ok: true, output: `Dismissed worker ${to} (slot freed; not resumable).` };
|
|
214
|
+
},
|
|
215
|
+
};
|
|
216
|
+
const createTeam = {
|
|
217
|
+
name: CREATE_TEAM_TOOL_NAME,
|
|
218
|
+
description: "Create a team to group related workers. Returns a team_id; pass it as spawn_worker's `team`, then send_message/stop_worker with `to: \"team:<id>\"` to broadcast / batch-stop.",
|
|
219
|
+
category: "integration",
|
|
220
|
+
parameters: {
|
|
221
|
+
type: "object",
|
|
222
|
+
properties: {
|
|
223
|
+
name: { type: "string", description: "Human-readable team label." },
|
|
224
|
+
},
|
|
225
|
+
required: ["name"],
|
|
226
|
+
},
|
|
227
|
+
isConcurrencySafe: () => false,
|
|
228
|
+
summarize: (args) => `create_team: ${strArg(args, "name", true)}`,
|
|
229
|
+
async execute(args) {
|
|
230
|
+
const name = strArg(args, "name", true);
|
|
231
|
+
const { teamId } = reg.createTeam(name);
|
|
232
|
+
return { ok: true, output: `(team created) team_id=${teamId} name=${name}` };
|
|
233
|
+
},
|
|
234
|
+
};
|
|
235
|
+
const listWorkers = {
|
|
236
|
+
name: LIST_WORKERS_TOOL_NAME,
|
|
237
|
+
description: "List your live workers and their status (running / idle / stopped / failed), optionally filtered by team. Use it to see what's in flight before directing more work.",
|
|
238
|
+
category: "file-read",
|
|
239
|
+
parameters: {
|
|
240
|
+
type: "object",
|
|
241
|
+
properties: {
|
|
242
|
+
team: { type: "string", description: "Optional team id to filter by." },
|
|
243
|
+
},
|
|
244
|
+
},
|
|
245
|
+
isConcurrencySafe: () => true,
|
|
246
|
+
summarize: (args) => {
|
|
247
|
+
const team = strArg(args, "team", false);
|
|
248
|
+
return team ? `list_workers (team ${team})` : "list_workers";
|
|
249
|
+
},
|
|
250
|
+
async execute(args) {
|
|
251
|
+
const team = strArg(args, "team", false);
|
|
252
|
+
const workers = reg.listWorkers(team);
|
|
253
|
+
if (workers.length === 0) {
|
|
254
|
+
return { ok: true, output: team ? `No workers in team ${team}.` : "No live workers." };
|
|
255
|
+
}
|
|
256
|
+
const lines = workers.map((w) => `- ${w.agentId} "${w.name}" [${w.status}]${w.teamId ? ` team=${w.teamId}` : ""} turns=${w.turnsRun} queued=${w.queued} — ${w.lastMessageHead}`);
|
|
257
|
+
return { ok: true, output: lines.join("\n") };
|
|
258
|
+
},
|
|
259
|
+
};
|
|
260
|
+
return [spawnWorker, sendMessage, stopWorker, dismissWorker, createTeam, listWorkers];
|
|
261
|
+
}
|
|
262
|
+
//# sourceMappingURL=coordinator-tools.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"coordinator-tools.js","sourceRoot":"","sources":["../../src/core/coordinator-tools.ts"],"names":[],"mappings":"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"}
|
package/dist/core/engine.d.ts
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { type ApprovalMode, type AsyncTaskRegistry, type BoundaryInjectionQueue, type CancellationToken, type EventBus, type TaskNotification, ModelSelection } from "@chances-ai/runtime";
|
|
1
|
+
import { type ApprovalMode, type AsyncTaskRegistry, type BoundaryInjectionQueue, type NotificationSource, type CancellationToken, type EventBus, type TaskNotification, ModelSelection } from "@chances-ai/runtime";
|
|
2
2
|
import { type Message, type ModelRouter, type Route, type RetryConfig, type ToolCallRequest, type ToolDefinition } from "../ai/index.js";
|
|
3
3
|
import type { SessionManager } from "../session/index.js";
|
|
4
4
|
import type { MemoryStore } from "../memory/index.js";
|
|
@@ -126,6 +126,15 @@ export interface AgentEngineOptions {
|
|
|
126
126
|
* backgrounds never accidentally orphan into a process exit.
|
|
127
127
|
*/
|
|
128
128
|
backgroundTasks?: AsyncTaskRegistry;
|
|
129
|
+
/**
|
|
130
|
+
* (7.8 §3.4) Persistent coordinator worker registry. A SECOND
|
|
131
|
+
* {@link NotificationSource} the engine drains alongside `backgroundTasks` at
|
|
132
|
+
* every turn boundary — a worker's per-message result reaches the coordinator
|
|
133
|
+
* as a `<task-notification>` exactly like a background subagent's. Undefined on
|
|
134
|
+
* a normal (non-coordinator) session (drain is a no-op). Per-session in the
|
|
135
|
+
* isolated serve path, same as `backgroundTasks`.
|
|
136
|
+
*/
|
|
137
|
+
workerRegistry?: NotificationSource;
|
|
129
138
|
/**
|
|
130
139
|
* (7.7 §4) Per-session steering queue. When provided, the engine drains it at
|
|
131
140
|
* every turn boundary (turn-top + after each tool batch) and injects the
|
|
@@ -273,14 +282,19 @@ interface TurnState {
|
|
|
273
282
|
* `injected*Ids` collections are mutated in place (append-only) by the loop and
|
|
274
283
|
* its hooks; the engine reads them back after the loop to persist + acknowledge.
|
|
275
284
|
*/
|
|
285
|
+
/** (7.8 §3.4 — codex R2 M1) Per-source injected-notification tracking. Keyed by
|
|
286
|
+
* the `NotificationSource` object so each source's ack set is independent — a
|
|
287
|
+
* cross-source id collision can't shadow or mis-ack a note. Turn-local. */
|
|
288
|
+
export type InjectedNotifs = Map<NotificationSource, Set<string>>;
|
|
276
289
|
export interface LoopRun {
|
|
277
290
|
turnId: string;
|
|
278
291
|
system: string;
|
|
279
292
|
toolDefs: ToolDefinition[];
|
|
280
293
|
/** Accumulator: assistant/tool/steering messages appended as the loop runs. */
|
|
281
294
|
turnMessages: Message[];
|
|
282
|
-
/** Notification ids already injected
|
|
283
|
-
|
|
295
|
+
/** (codex R2 M1) Notification ids already injected this turn, keyed PER source
|
|
296
|
+
* (turn-top + mid-turn) — ack the right source's own ids after persist. */
|
|
297
|
+
injectedNotifIds: InjectedNotifs;
|
|
284
298
|
/** Steering ids already injected — ack after persist. */
|
|
285
299
|
injectedSteerIds: string[];
|
|
286
300
|
/** Soft turn ceiling for THIS run (already clamped to the hard cap). */
|
|
@@ -315,7 +329,7 @@ export interface AgentLoopHooks {
|
|
|
315
329
|
/** Iteration-boundary injections: steering the user queued mid-turn + bg-task
|
|
316
330
|
* notifications that completed mid-turn (peek-not-drain; ids recorded for the
|
|
317
331
|
* post-persist ack). pi `getSteeringMessages`. */
|
|
318
|
-
getBoundaryMessages(injectedNotifIds:
|
|
332
|
+
getBoundaryMessages(injectedNotifIds: InjectedNotifs, injectedSteerIds: string[]): Message[];
|
|
319
333
|
/** When the model returned NO tool calls: a `user`-role reminder to finish
|
|
320
334
|
* open todos (loop continues) or `null` to let the turn resolve. The inverse
|
|
321
335
|
* of pi's `shouldStopAfterTurn`. */
|
|
@@ -347,8 +361,24 @@ export declare class AgentEngine {
|
|
|
347
361
|
* render each as a user message, and append its id to `injectedSteerIds` for
|
|
348
362
|
* post-persist ack. Peek-not-drain: a cancelled turn re-delivers. */
|
|
349
363
|
private drainSteering;
|
|
350
|
-
/** (7.
|
|
351
|
-
*
|
|
364
|
+
/** (7.8 §3.4) The notification sources the engine drains at turn boundaries:
|
|
365
|
+
* background subagent tasks AND persistent coordinator workers. Both
|
|
366
|
+
* implement {@link NotificationSource}; the engine renders their pending
|
|
367
|
+
* `<task-notification>`s together (FIFO within each) and acks EACH source's
|
|
368
|
+
* own ids after persist — never broadcasting a global id list (codex R1-§5). */
|
|
369
|
+
private notificationSources;
|
|
370
|
+
/** (7.7 §4 / 7.8 §3.4 — codex R2 M1) Collect notifications not yet injected this
|
|
371
|
+
* turn, across ALL sources, recording each into its OWN per-source injected set
|
|
372
|
+
* as it's taken. The injected tracking is keyed by `NotificationSource` (NOT a
|
|
373
|
+
* flat id set) so a hypothetical cross-source id collision can never make one
|
|
374
|
+
* source's note shadow another's, nor ack a note that was never injected. */
|
|
375
|
+
private collectFreshNotifications;
|
|
376
|
+
/** (7.7 §4 / 7.8 — codex R2 M1) Ack AFTER persist: each source acks EXACTLY the
|
|
377
|
+
* ids injected FROM it this turn (per-source set), never a merged global list.
|
|
378
|
+
* A cancelled turn (no ack) re-delivers; injected ids are turn-local. */
|
|
379
|
+
private ackNotifications;
|
|
380
|
+
/** (7.7 §4) Iteration-boundary drain: notifications that arrived mid-turn
|
|
381
|
+
* (combined render across all sources, same as turn-top) PLUS steering. Both
|
|
352
382
|
* peek-not-drain; ids recorded for post-persist ack. */
|
|
353
383
|
private drainBoundaryInjections;
|
|
354
384
|
/** (7.7 §5.3) Build an incomplete-todos reminder when the model stopped with
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"engine.d.ts","sourceRoot":"","sources":["../../src/core/engine.ts"],"names":[],"mappings":"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
|
|
1
|
+
{"version":3,"file":"engine.d.ts","sourceRoot":"","sources":["../../src/core/engine.ts"],"names":[],"mappings":"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"}
|
package/dist/core/engine.js
CHANGED
|
@@ -112,19 +112,62 @@ export class AgentEngine {
|
|
|
112
112
|
}
|
|
113
113
|
return out;
|
|
114
114
|
}
|
|
115
|
-
/** (7.
|
|
116
|
-
*
|
|
115
|
+
/** (7.8 §3.4) The notification sources the engine drains at turn boundaries:
|
|
116
|
+
* background subagent tasks AND persistent coordinator workers. Both
|
|
117
|
+
* implement {@link NotificationSource}; the engine renders their pending
|
|
118
|
+
* `<task-notification>`s together (FIFO within each) and acks EACH source's
|
|
119
|
+
* own ids after persist — never broadcasting a global id list (codex R1-§5). */
|
|
120
|
+
notificationSources() {
|
|
121
|
+
const out = [];
|
|
122
|
+
if (this.opts.backgroundTasks)
|
|
123
|
+
out.push(this.opts.backgroundTasks);
|
|
124
|
+
if (this.opts.workerRegistry)
|
|
125
|
+
out.push(this.opts.workerRegistry);
|
|
126
|
+
return out;
|
|
127
|
+
}
|
|
128
|
+
/** (7.7 §4 / 7.8 §3.4 — codex R2 M1) Collect notifications not yet injected this
|
|
129
|
+
* turn, across ALL sources, recording each into its OWN per-source injected set
|
|
130
|
+
* as it's taken. The injected tracking is keyed by `NotificationSource` (NOT a
|
|
131
|
+
* flat id set) so a hypothetical cross-source id collision can never make one
|
|
132
|
+
* source's note shadow another's, nor ack a note that was never injected. */
|
|
133
|
+
collectFreshNotifications(injected) {
|
|
134
|
+
const out = [];
|
|
135
|
+
for (const src of this.notificationSources()) {
|
|
136
|
+
let set = injected.get(src);
|
|
137
|
+
if (!set) {
|
|
138
|
+
set = new Set();
|
|
139
|
+
injected.set(src, set);
|
|
140
|
+
}
|
|
141
|
+
for (const n of src.peekPendingNotifications()) {
|
|
142
|
+
if (set.has(n.taskId))
|
|
143
|
+
continue;
|
|
144
|
+
out.push(n);
|
|
145
|
+
set.add(n.taskId); // record immediately so the boundary drain won't re-inject
|
|
146
|
+
}
|
|
147
|
+
}
|
|
148
|
+
return out;
|
|
149
|
+
}
|
|
150
|
+
/** (7.7 §4 / 7.8 — codex R2 M1) Ack AFTER persist: each source acks EXACTLY the
|
|
151
|
+
* ids injected FROM it this turn (per-source set), never a merged global list.
|
|
152
|
+
* A cancelled turn (no ack) re-delivers; injected ids are turn-local. */
|
|
153
|
+
ackNotifications(injected) {
|
|
154
|
+
for (const src of this.notificationSources()) {
|
|
155
|
+
const set = injected.get(src);
|
|
156
|
+
if (set && set.size > 0)
|
|
157
|
+
src.acknowledgeNotifications([...set]);
|
|
158
|
+
}
|
|
159
|
+
}
|
|
160
|
+
/** (7.7 §4) Iteration-boundary drain: notifications that arrived mid-turn
|
|
161
|
+
* (combined render across all sources, same as turn-top) PLUS steering. Both
|
|
117
162
|
* peek-not-drain; ids recorded for post-persist ack. */
|
|
118
163
|
drainBoundaryInjections(injectedNotifIds, injectedSteerIds) {
|
|
119
164
|
const out = [];
|
|
120
|
-
const fresh =
|
|
165
|
+
const fresh = this.collectFreshNotifications(injectedNotifIds);
|
|
121
166
|
if (fresh.length > 0) {
|
|
122
167
|
out.push({
|
|
123
168
|
role: "user",
|
|
124
169
|
content: [{ type: "text", text: fresh.map(renderTaskNotificationXml).join("\n") }],
|
|
125
170
|
});
|
|
126
|
-
for (const n of fresh)
|
|
127
|
-
injectedNotifIds.add(n.taskId);
|
|
128
171
|
}
|
|
129
172
|
out.push(...this.drainSteering(injectedSteerIds));
|
|
130
173
|
return out;
|
|
@@ -211,7 +254,7 @@ export class AgentEngine {
|
|
|
211
254
|
return this.runTurnImpl(prompt, token, opts.expandMentions !== false, opts.trustedContext);
|
|
212
255
|
}
|
|
213
256
|
async runTurnImpl(prompt, token, expandMentions, trustedContext) {
|
|
214
|
-
const { tools, session, plugins
|
|
257
|
+
const { tools, session, plugins } = this.opts;
|
|
215
258
|
const turnId = createId("turn");
|
|
216
259
|
// (3.6) Carry the active session id on `turn:start` so the OTel
|
|
217
260
|
// exporter can stamp `chances.gen_ai.session.id` correctly across
|
|
@@ -240,8 +283,10 @@ export class AgentEngine {
|
|
|
240
283
|
// persisted to `session.messages()`. Acknowledgement (queue removal)
|
|
241
284
|
// happens immediately after `session.appendTurn(turnMessages)`
|
|
242
285
|
// succeeds.
|
|
243
|
-
|
|
244
|
-
|
|
286
|
+
// (7.8 §3.4 — codex R2 M1) Collect across ALL notification sources (background
|
|
287
|
+
// tasks + persistent workers), recording each into its per-source injected set.
|
|
288
|
+
const injectedNotifIds = new Map();
|
|
289
|
+
const notifications = this.collectFreshNotifications(injectedNotifIds);
|
|
245
290
|
const turnMessages = [];
|
|
246
291
|
if (notifications.length > 0) {
|
|
247
292
|
const xml = notifications.map(renderTaskNotificationXml).join("\n");
|
|
@@ -270,10 +315,9 @@ export class AgentEngine {
|
|
|
270
315
|
turnMessages.push({ role: "user", content: [{ type: "text", text: trustedContext }] });
|
|
271
316
|
}
|
|
272
317
|
turnMessages.push({ role: "user", content: [{ type: "text", text: prompt }] });
|
|
273
|
-
// (7.7 §4) Drain any steering queued before this turn started
|
|
274
|
-
//
|
|
275
|
-
// boundary drain
|
|
276
|
-
const injectedNotifIds = new Set(notificationIds);
|
|
318
|
+
// (7.7 §4) Drain any steering queued before this turn started. `injectedNotifIds`
|
|
319
|
+
// (above) tracks per-source notification ids; `injectedSteerIds` tracks steering
|
|
320
|
+
// — both so the iteration-boundary drain + post-persist ack don't double-count.
|
|
277
321
|
const injectedSteerIds = [];
|
|
278
322
|
turnMessages.push(...this.drainSteering(injectedSteerIds));
|
|
279
323
|
const result = { text: "", inputTokens: 0, outputTokens: 0, costUsd: 0 };
|
|
@@ -300,9 +344,9 @@ export class AgentEngine {
|
|
|
300
344
|
// a cancellation between peek and persist leaves both queues intact (the
|
|
301
345
|
// next turn re-delivers). `injectedNotifIds` covers turn-top AND mid-turn
|
|
302
346
|
// notifications; `injectedSteerIds` covers all injected steering.
|
|
303
|
-
|
|
304
|
-
|
|
305
|
-
|
|
347
|
+
// (7.8 §3.4) Ack per source, each only its own injected ids (no global
|
|
348
|
+
// broadcast) — drains across backgroundTasks + workerRegistry uniformly.
|
|
349
|
+
this.ackNotifications(injectedNotifIds);
|
|
306
350
|
if (injectedSteerIds.length > 0) {
|
|
307
351
|
this.opts.steering?.acknowledge(injectedSteerIds);
|
|
308
352
|
}
|