feat(agent): simplify durable operation graph

This commit is contained in:
Mario Zechner 2026-08-26 16:10:53 +02:00
parent 3a68f018c0
commit c60dd63fdf
49 changed files with 2460 additions and 2772 deletions

View file

@ -77,8 +77,6 @@ export async function runClient(command: ClientCommand, options: RunClientOption
await watch.start(async (event) => {
if (event.type === "message_end" && event.runId !== undefined && event.message.role === "assistant") {
completedText.set(event.runId, messageText(event.message));
} else if (event.type === "run_end" && "finalMessage" in event) {
completedText.set(event.runId, messageText(event.finalMessage));
}
await options.onEvent?.(event);
});

View file

@ -248,58 +248,30 @@ function toHarnessDeferred(deferred: DeferredHandle): DeferredHandle {
}
function toWireRunValue(value: Extract<HarnessRunResult, { ok: true }>["value"]): WireRunValue {
switch (value.kind) {
case "completed":
return value.finalEntryId === undefined
? { kind: "completed", runId: value.runId, tipId: value.tipId }
: {
kind: "completed",
runId: value.runId,
tipId: value.tipId,
finalEntryId: value.finalEntryId,
finalMessage: toWireAssistantMessage(value.finalMessage),
};
case "aborted":
return value.finalEntryId === undefined
? { kind: "aborted", runId: value.runId, tipId: value.tipId }
: {
kind: "aborted",
runId: value.runId,
tipId: value.tipId,
finalEntryId: value.finalEntryId,
finalMessage: toWireAssistantMessage(value.finalMessage),
};
case "failed": {
const error = {
code: value.error.code,
message: value.error.message,
...(value.error.details === undefined
? {}
: { details: toWireJsonValue(value.error.details, "operation error details") }),
};
return value.finalEntryId === undefined
? { kind: "failed", runId: value.runId, tipId: value.tipId, error }
: {
kind: "failed",
runId: value.runId,
tipId: value.tipId,
error,
finalEntryId: value.finalEntryId,
finalMessage: toWireAssistantMessage(value.finalMessage),
};
}
case "suspended":
return {
kind: "suspended",
reason: "deferred",
runId: value.runId,
tipId: value.tipId,
finalEntryId: value.finalEntryId,
deferred: toWireDeferred(value.deferred),
};
default:
return assertNever(value);
if (value.status === "suspended") {
return { operationId: value.operationId, status: "suspended", deferred: toWireDeferred(value.deferred) };
}
const base = {
operationId: value.operationId,
kind: value.kind,
fromTipId: value.fromTipId,
tipId: value.tipId,
startedAt: value.startedAt,
endedAt: value.endedAt,
};
if (value.status !== "failed") return { ...base, status: value.status };
if (value.error === undefined) throw new TypeError("Failed harness result is missing its error");
return {
...base,
status: "failed",
error: {
code: value.error.code,
message: value.error.message,
...(value.error.details === undefined
? {}
: { details: toWireJsonValue(value.error.details, "operation error details") }),
},
};
}
function toWireRunError(error: Extract<HarnessRunResult, { ok: false }>["error"]): WireRunError {
@ -631,6 +603,7 @@ export function toWireLaneSnapshot(snapshot: HarnessLaneSnapshot): LaneSnapshot
lane: snapshot.lane,
transcript: snapshot.transcript.map(toWireEntry),
tipId: snapshot.tipId,
lastOperationId: snapshot.lastOperationId,
operation:
snapshot.operation === null
? null
@ -721,15 +694,21 @@ export function toWireLaneEvent(event: HarnessEvent): LaneEvent | undefined {
...base,
lane: event.lane,
};
case "run_end": {
const final =
event.finalEntryId === undefined
? {}
: { finalEntryId: event.finalEntryId, finalMessage: toWireAssistantMessage(event.finalMessage) };
return event.outcome === "failed"
? { ...event, error: { ...event.error }, ...final, ...base, lane: event.lane }
: { ...event, ...final, ...base, lane: event.lane };
}
case "run_end":
return event.status === "failed"
? {
...event,
error: {
code: event.error.code,
message: event.error.message,
...(event.error.details === undefined
? {}
: { details: toWireJsonValue(event.error.details, "operation error details") }),
},
...base,
lane: event.lane,
}
: { ...event, ...base, lane: event.lane };
case "message_start":
case "message_end":
return { ...event, message: toWireMessage(event.message), ...base, lane: event.lane };

View file

@ -58,9 +58,9 @@ export function toChatPromptResponse(result: HarnessRunResult): ChatPromptRespon
if (result.ok) {
return {
accepted: true,
operationId: result.value.runId,
operationId: result.value.operationId,
error:
result.value.kind === "failed"
result.value.status === "failed" && result.value.error !== undefined
? {
code: result.value.error.code,
message: result.value.error.message,