Files
openclaw/src/gateway/server-methods/task-summary.ts

71 lines
2.6 KiB
TypeScript

// Public task summaries keep task-registry internals and unbounded status text
// out of gateway responses and events.
import type { TaskSummary } from "../../../packages/gateway-protocol/src/index.js";
import type { TaskRecord, TaskStatus } from "../../tasks/task-registry.types.js";
import {
TASK_STATUS_DETAIL_MAX_CHARS,
formatTaskStatusTitle,
sanitizeTaskStatusText,
} from "../../tasks/task-status.js";
type TaskLedgerStatus = TaskSummary["status"];
const TASK_STATUS_TO_LEDGER_STATUS: Record<TaskStatus, TaskLedgerStatus> = {
queued: "queued",
running: "running",
succeeded: "completed",
failed: "failed",
timed_out: "timed_out",
cancelled: "cancelled",
lost: "failed",
};
export type TaskEventPayload =
| { action: "upserted"; task: TaskSummary }
| { action: "deleted"; taskId: string }
| { action: "restored" };
export function taskUpdatedAt(task: TaskRecord): number {
return task.lastEventAt ?? task.endedAt ?? task.startedAt ?? task.createdAt;
}
function sanitizeOptionalTaskText(
value: unknown,
opts?: { errorContext?: boolean },
): string | undefined {
const sanitized = sanitizeTaskStatusText(value, {
errorContext: opts?.errorContext,
maxChars: TASK_STATUS_DETAIL_MAX_CHARS,
});
return sanitized || undefined;
}
export function mapTaskSummary(task: TaskRecord): TaskSummary {
const progressSummary = sanitizeOptionalTaskText(task.progressSummary);
const terminalSummary = sanitizeOptionalTaskText(task.terminalSummary, { errorContext: true });
const error = sanitizeOptionalTaskText(task.error, { errorContext: true });
return {
id: task.taskId,
taskId: task.taskId,
kind: task.taskKind ?? task.runtime,
runtime: task.runtime,
status: TASK_STATUS_TO_LEDGER_STATUS[task.status],
title: formatTaskStatusTitle(task),
...(task.agentId ? { agentId: task.agentId } : {}),
sessionKey: task.requesterSessionKey,
...(task.childSessionKey ? { childSessionKey: task.childSessionKey } : {}),
ownerKey: task.ownerKey,
...(task.runId ? { runId: task.runId } : {}),
...(task.parentFlowId ? { flowId: task.parentFlowId } : {}),
...(task.parentTaskId ? { parentTaskId: task.parentTaskId } : {}),
...(task.sourceId ? { sourceId: task.sourceId } : {}),
createdAt: task.createdAt,
updatedAt: taskUpdatedAt(task),
...(task.startedAt !== undefined ? { startedAt: task.startedAt } : {}),
...(task.endedAt !== undefined ? { endedAt: task.endedAt } : {}),
...(progressSummary ? { progressSummary } : {}),
...(terminalSummary ? { terminalSummary } : {}),
...(error ? { error } : {}),
};
}