Skip to content

Commit 53bcd57

Browse files
authored
refactor(tasks): unify the shared task run registry (#57324)
* refactor(tasks): simplify shared task run registry * refactor(tasks): remove legacy task registry aliases * fix(cron): normalize timeout task status and harden ledger writes * fix(cron): keep manual runs resilient to ledger failures
1 parent e4466c7 commit 53bcd57

19 files changed

Lines changed: 569 additions & 159 deletions

src/acp/control-plane/manager.core.ts

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -833,7 +833,7 @@ export class AcpSessionManager {
833833
if (taskContext) {
834834
const terminalResult = resolveBackgroundTaskTerminalResult(taskProgressSummary);
835835
this.updateBackgroundTaskState(taskContext.runId, {
836-
status: "done",
836+
status: "succeeded",
837837
endedAt: Date.now(),
838838
lastEventAt: Date.now(),
839839
error: undefined,
@@ -1880,13 +1880,12 @@ export class AcpSessionManager {
18801880
private createBackgroundTaskRecord(context: BackgroundTaskContext, startedAt: number): void {
18811881
try {
18821882
createTaskRecord({
1883-
source: "unknown",
18841883
runtime: "acp",
1884+
sourceId: context.runId,
18851885
requesterSessionKey: context.requesterSessionKey,
18861886
requesterOrigin: context.requesterOrigin,
18871887
childSessionKey: context.childSessionKey,
18881888
runId: context.runId,
1889-
bindingTargetKind: "session",
18901889
label: context.label,
18911890
task: context.task,
18921891
status: "running",

src/acp/control-plane/manager.test.ts

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -304,13 +304,12 @@ describe("AcpSessionManager", () => {
304304
});
305305

306306
expect(findTaskByRunId("direct-parented-run")).toMatchObject({
307-
source: "unknown",
308307
runtime: "acp",
309308
requesterSessionKey: "agent:quant:telegram:quant:direct:822430204",
310309
childSessionKey: "agent:codex:acp:child-1",
311310
label: "Quant patch",
312311
task: "Implement the feature and report back",
313-
status: "done",
312+
status: "succeeded",
314313
progressSummary: "Write failed: permission denied for /root/oc-acp-write-should-fail.txt.",
315314
terminalOutcome: "blocked",
316315
terminalSummary: "Permission denied for /root/oc-acp-write-should-fail.txt.",

src/agents/acp-spawn.ts

Lines changed: 2 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -954,19 +954,17 @@ export async function spawnAcpDirect(
954954
parentRelay?.notifyStarted();
955955
try {
956956
createTaskRecord({
957-
source: "sessions_spawn",
958957
runtime: "acp",
958+
sourceId: childRunId,
959959
requesterSessionKey: requesterInternalKey,
960960
requesterOrigin: requesterState.origin,
961961
childSessionKey: sessionKey,
962962
runId: childRunId,
963-
bindingTargetKind: "session",
964963
label: params.label,
965964
task: params.task,
966965
status: "running",
967966
deliveryStatus: requesterInternalKey.trim() ? "pending" : "parent_missing",
968967
startedAt: Date.now(),
969-
streamLogPath,
970968
});
971969
} catch (error) {
972970
log.warn("Failed to create background task for ACP spawn", {
@@ -987,13 +985,12 @@ export async function spawnAcpDirect(
987985

988986
try {
989987
createTaskRecord({
990-
source: "sessions_spawn",
991988
runtime: "acp",
989+
sourceId: childRunId,
992990
requesterSessionKey: requesterInternalKey,
993991
requesterOrigin: requesterState.origin,
994992
childSessionKey: sessionKey,
995993
runId: childRunId,
996-
bindingTargetKind: "session",
997994
label: params.label,
998995
task: params.task,
999996
status: "running",

src/agents/subagent-registry-lifecycle.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -460,7 +460,7 @@ export function createSubagentRegistryLifecycleController(params: {
460460
runId: entry.runId,
461461
status:
462462
completeParams.outcome.status === "ok"
463-
? "done"
463+
? "succeeded"
464464
: completeParams.outcome.status === "timeout"
465465
? "timed_out"
466466
: "failed",

src/agents/subagent-registry-run-manager.ts

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -318,13 +318,12 @@ export function createSubagentRunManager(params: {
318318
});
319319
try {
320320
createTaskRecord({
321-
source: "sessions_spawn",
322321
runtime: "subagent",
322+
sourceId: registerParams.runId,
323323
requesterSessionKey: registerParams.requesterSessionKey,
324324
requesterOrigin,
325325
childSessionKey: registerParams.childSessionKey,
326326
runId: registerParams.runId,
327-
bindingTargetKind: "subagent",
328327
label: registerParams.label,
329328
task: registerParams.task,
330329
status: "running",

src/cli/program/register.status-health-sessions.ts

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -224,10 +224,10 @@ export function registerStatusHealthSessionsCommands(program: Command) {
224224
.command("tasks")
225225
.description("Inspect durable background task state")
226226
.option("--json", "Output as JSON", false)
227-
.option("--runtime <name>", "Filter by runtime (subagent, acp, cli)")
227+
.option("--runtime <name>", "Filter by kind (subagent, acp, cron, cli)")
228228
.option(
229229
"--status <name>",
230-
"Filter by status (accepted, running, done, failed, timed_out, cancelled, lost)",
230+
"Filter by status (queued, running, succeeded, failed, timed_out, cancelled, lost)",
231231
)
232232
.action(async (opts) => {
233233
await runCommandWithRuntime(defaultRuntime, async () => {
@@ -247,10 +247,10 @@ export function registerStatusHealthSessionsCommands(program: Command) {
247247
.command("list")
248248
.description("List tracked background tasks")
249249
.option("--json", "Output as JSON", false)
250-
.option("--runtime <name>", "Filter by runtime (subagent, acp, cli)")
250+
.option("--runtime <name>", "Filter by kind (subagent, acp, cron, cli)")
251251
.option(
252252
"--status <name>",
253-
"Filter by status (accepted, running, done, failed, timed_out, cancelled, lost)",
253+
"Filter by status (queued, running, succeeded, failed, timed_out, cancelled, lost)",
254254
)
255255
.action(async (opts, command) => {
256256
const parentOpts = command.parent?.opts() as

src/commands/tasks.test.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -37,8 +37,8 @@ let tasksCancelCommand: typeof import("./tasks.js").tasksCancelCommand;
3737

3838
const taskFixture = {
3939
taskId: "task-12345678",
40-
source: "sessions_spawn",
4140
runtime: "acp",
41+
sourceId: "run-12345678",
4242
requesterSessionKey: "agent:main:main",
4343
childSessionKey: "agent:codex:acp:child",
4444
runId: "run-12345678",

src/commands/tasks.ts

Lines changed: 8 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -38,7 +38,7 @@ function formatTaskStatusCell(status: string, rich: boolean) {
3838
if (!rich) {
3939
return padded;
4040
}
41-
if (status === "done") {
41+
if (status === "succeeded") {
4242
return theme.success(padded);
4343
}
4444
if (status === "failed" || status === "lost" || status === "timed_out") {
@@ -53,7 +53,7 @@ function formatTaskStatusCell(status: string, rich: boolean) {
5353
function formatTaskRows(tasks: TaskRecord[], rich: boolean) {
5454
const header = [
5555
"Task".padEnd(ID_PAD),
56-
"Runtime".padEnd(RUNTIME_PAD),
56+
"Kind".padEnd(RUNTIME_PAD),
5757
"Status".padEnd(STATUS_PAD),
5858
"Delivery".padEnd(DELIVERY_PAD),
5959
"Run".padEnd(RUN_PAD),
@@ -151,21 +151,24 @@ export async function tasksShowCommand(
151151
const lines = [
152152
"Background task:",
153153
`taskId: ${task.taskId}`,
154-
`runtime: ${task.runtime}`,
154+
`kind: ${task.runtime}`,
155+
`sourceId: ${task.sourceId ?? "n/a"}`,
155156
`status: ${task.status}`,
157+
`result: ${task.terminalOutcome ?? "n/a"}`,
156158
`delivery: ${task.deliveryStatus}`,
157159
`notify: ${task.notifyPolicy}`,
158-
`source: ${task.source}`,
159160
`requesterSessionKey: ${task.requesterSessionKey}`,
160161
`childSessionKey: ${task.childSessionKey ?? "n/a"}`,
162+
`parentTaskId: ${task.parentTaskId ?? "n/a"}`,
163+
`agentId: ${task.agentId ?? "n/a"}`,
161164
`runId: ${task.runId ?? "n/a"}`,
162-
`bindingTargetKind: ${task.bindingTargetKind ?? "n/a"}`,
163165
`label: ${task.label ?? "n/a"}`,
164166
`task: ${task.task}`,
165167
`createdAt: ${new Date(task.createdAt).toISOString()}`,
166168
`startedAt: ${task.startedAt ? new Date(task.startedAt).toISOString() : "n/a"}`,
167169
`endedAt: ${task.endedAt ? new Date(task.endedAt).toISOString() : "n/a"}`,
168170
`lastEventAt: ${task.lastEventAt ? new Date(task.lastEventAt).toISOString() : "n/a"}`,
171+
`cleanupAfter: ${task.cleanupAfter ? new Date(task.cleanupAfter).toISOString() : "n/a"}`,
169172
...(task.error ? [`error: ${task.error}`] : []),
170173
...(task.progressSummary ? [`progressSummary: ${task.progressSummary}`] : []),
171174
...(task.terminalSummary ? [`terminalSummary: ${task.terminalSummary}`] : []),
@@ -177,10 +180,6 @@ export async function tasksShowCommand(
177180
}`,
178181
)
179182
: []),
180-
...(task.streamLogPath ? [`streamLogPath: ${task.streamLogPath}`] : []),
181-
...(task.transcriptPath ? [`transcriptPath: ${task.transcriptPath}`] : []),
182-
...(task.agentSessionId ? [`agentSessionId: ${task.agentSessionId}`] : []),
183-
...(task.backendSessionId ? [`backendSessionId: ${task.backendSessionId}`] : []),
184183
];
185184
for (const line of lines) {
186185
runtime.log(line);

0 commit comments

Comments
 (0)