Files
openclaw/src/tasks/task-registry.process-state.ts
T
Peter Steinberger b985d5a1ed feat: stream live subagent progress in task events (#121549)
* feat(tasks): stream live subagent activity

* fix(tasks): correlate edit activity from start events

* fix(gateway): sanitize live task activity

* test(reply): align custody harnesses with lifecycle

* fix(outbound): preserve post-send recovery evidence

* fix(types): align reply harnesses with current contracts

* fix(tasks): preserve activity liveness and SDK parity

* test(sdk): avoid unsafe task summary assertion

* chore(contracts): refresh Plugin SDK API baseline
2026-08-10 18:37:58 -07:00

53 lines
2.2 KiB
TypeScript

// Tracks task process state transitions used to reconcile running work.
import type { TaskDeliveryState, TaskRecord } from "./task-registry.types.js";
export type TaskActivityOverlayState = {
runId: string;
assistantText: string;
thinkingText: string;
hasAssistantActivity: boolean;
lastActivity?: string;
files: Set<string>;
added: number;
removed: number;
pendingDiffByToolCallId: Map<string, { files: string[]; added: number; removed: number }>;
dirty: boolean;
lastFlushedAt?: number;
flushTimer?: ReturnType<typeof setTimeout>;
};
/** Process-local indexes backing task lookup, owner access, and pending delivery scans. */
type TaskRegistryProcessState = {
tasks: Map<string, TaskRecord>;
taskDeliveryStates: Map<string, TaskDeliveryState>;
taskIdsByRunId: Map<string, Set<string>>;
taskIdsByOwnerKey: Map<string, Set<string>>;
taskIdsByParentFlowId: Map<string, Set<string>>;
taskIdsByRelatedSessionKey: Map<string, Set<string>>;
tasksWithPendingDelivery: Set<string>;
/** Ephemeral live activity is intentionally discarded on gateway restart. */
taskActivityByTaskId: Map<string, TaskActivityOverlayState>;
// Listener ownership must survive module reloads alongside the task indexes it updates.
listenerStop?: (() => void) | null;
};
const TASK_REGISTRY_PROCESS_STATE_KEY = Symbol.for("openclaw.taskRegistry.state");
/** Returns the singleton in-process task registry state. */
export function getTaskRegistryProcessState(): TaskRegistryProcessState {
const globalState = globalThis as typeof globalThis & {
[TASK_REGISTRY_PROCESS_STATE_KEY]?: TaskRegistryProcessState;
};
globalState[TASK_REGISTRY_PROCESS_STATE_KEY] ??= {
tasks: new Map<string, TaskRecord>(),
taskDeliveryStates: new Map<string, TaskDeliveryState>(),
taskIdsByRunId: new Map<string, Set<string>>(),
taskIdsByOwnerKey: new Map<string, Set<string>>(),
taskIdsByParentFlowId: new Map<string, Set<string>>(),
taskIdsByRelatedSessionKey: new Map<string, Set<string>>(),
tasksWithPendingDelivery: new Set<string>(),
taskActivityByTaskId: new Map<string, TaskActivityOverlayState>(),
};
return globalState[TASK_REGISTRY_PROCESS_STATE_KEY];
}