fix: 修复 Queue 已读投影和取消传播
This commit is contained in:
+26
-6
@@ -1,4 +1,4 @@
|
||||
import type { BackendProfile, BackendTurnResult, CommandRecord, CreateCommandInput, CreateQueueTaskInput, CreateRunInput, FailureKind, JsonRecord, ListGcExpiredSessionsInput, QueueAttemptRef, QueueCommanderSnapshot, QueueReadCursorRecord, QueueStats, QueueTaskListResult, QueueTaskRecord, QueueTaskState, RunEvent, RunnerJobRecord, RunnerRecord, RunRecord, SessionEventPage, SessionListResult, SessionListState, SessionReadCursorRecord, SessionRecord, SessionRef, SessionStoragePatch, SessionSummary, TerminalStatus, UpsertSessionInput } from "../common/types.js";
|
||||
import type { BackendProfile, BackendTurnResult, CommandRecord, CreateCommandInput, CreateQueueTaskInput, CreateRunInput, FailureKind, JsonRecord, ListGcExpiredSessionsInput, QueueAttemptRef, QueueCommanderSnapshot, QueueReadCursorRecord, QueueStats, QueueTaskListResult, QueueTaskRecord, QueueTaskState, QueueTaskSummary, RunEvent, RunnerJobRecord, RunnerRecord, RunRecord, SessionEventPage, SessionListResult, SessionListState, SessionReadCursorRecord, SessionRecord, SessionRef, SessionStoragePatch, SessionSummary, TerminalStatus, UpsertSessionInput } from "../common/types.js";
|
||||
import { AgentRunError } from "../common/errors.js";
|
||||
import { newId, nowIso, stableHash } from "../common/validation.js";
|
||||
import { redactJson } from "../common/redaction.js";
|
||||
@@ -55,7 +55,7 @@ export interface AgentRunStore {
|
||||
cancelQueueTask(taskId: string, reason?: string): MaybePromise<QueueTaskRecord>;
|
||||
markQueueTaskRead(taskId: string, readerId: string): MaybePromise<QueueReadCursorRecord>;
|
||||
queueStats(queue?: string): MaybePromise<QueueStats>;
|
||||
queueCommander(queue?: string): MaybePromise<QueueCommanderSnapshot>;
|
||||
queueCommander(queue?: string, readerId?: string | null): MaybePromise<QueueCommanderSnapshot>;
|
||||
backends(): MaybePromise<JsonRecord[]>;
|
||||
close?(): MaybePromise<void>;
|
||||
}
|
||||
@@ -495,8 +495,11 @@ export class MemoryAgentRunStore implements AgentRunStore {
|
||||
cancelQueueTask(taskId: string, reason = "cancel requested"): QueueTaskRecord {
|
||||
const task = this.getQueueTask(taskId);
|
||||
if (isTerminalQueueTaskState(task.state)) return task;
|
||||
if (task.latestAttempt?.commandId) this.cancelCommand(task.latestAttempt.commandId, reason);
|
||||
else if (task.latestAttempt?.runId) this.cancelRun(task.latestAttempt.runId, reason);
|
||||
const at = nowIso();
|
||||
const next: QueueTaskRecord = { ...task, state: "cancelled", version: this.nextQueueVersion(), updatedAt: at, cancelledAt: at, cancelReason: reason };
|
||||
const latestAttempt = task.latestAttempt ? { ...task.latestAttempt, state: "cancelled" as const } : null;
|
||||
const next: QueueTaskRecord = { ...task, state: "cancelled", latestAttempt, version: this.nextQueueVersion(), updatedAt: at, cancelledAt: at, cancelReason: reason };
|
||||
this.queueTasks.set(taskId, next);
|
||||
return next;
|
||||
}
|
||||
@@ -512,10 +515,15 @@ export class MemoryAgentRunStore implements AgentRunStore {
|
||||
return buildQueueStats(Array.from(this.queueTasks.values()).filter((task) => !queue || task.queue === queue), queue ?? null);
|
||||
}
|
||||
|
||||
queueCommander(queue?: string): QueueCommanderSnapshot {
|
||||
const items = Array.from(this.queueTasks.values()).filter((task) => !queue || task.queue === queue).sort(queueTaskSort).slice(0, 20);
|
||||
queueCommander(queue?: string, readerId: string | null = null): QueueCommanderSnapshot {
|
||||
const tasks = Array.from(this.queueTasks.values()).filter((task) => !queue || task.queue === queue);
|
||||
const generatedAt = nowIso();
|
||||
return { queue: queue ?? null, stats: buildQueueStats(Array.from(this.queueTasks.values()).filter((task) => !queue || task.queue === queue), queue ?? null, generatedAt), items, generatedAt };
|
||||
const items = tasks
|
||||
.map((task) => buildQueueTaskSummary(task, readerId, readerId ? this.queueReadCursors.get(queueReadKey(task.id, readerId)) ?? null : null))
|
||||
.filter((task) => queueTaskMatchesCommander(task, readerId))
|
||||
.sort(queueTaskSort)
|
||||
.slice(0, 20);
|
||||
return { queue: queue ?? null, readerId, stats: buildQueueStats(tasks, queue ?? null, generatedAt), items, generatedAt };
|
||||
}
|
||||
|
||||
backends(): JsonRecord[] {
|
||||
@@ -686,6 +694,18 @@ export function buildSessionSummary(record: SessionRecord, readerId: string | nu
|
||||
return { ...record, sessionPath: `${record.tenantId}/${record.projectId}/${record.sessionId}`, readerId, readCursor, attentionState, unread, active };
|
||||
}
|
||||
|
||||
export function buildQueueTaskSummary(record: QueueTaskRecord, readerId: string | null, readCursor: QueueReadCursorRecord | null): QueueTaskSummary {
|
||||
const active = !isTerminalQueueTaskState(record.state);
|
||||
const unread = !active && (!readCursor || readCursor.taskVersion < record.version);
|
||||
const attentionState = active ? "active" : unread ? "unread" : "read";
|
||||
return { ...record, readerId, readCursor, attentionState, unread, active };
|
||||
}
|
||||
|
||||
export function queueTaskMatchesCommander(task: QueueTaskSummary, readerId: string | null): boolean {
|
||||
if (!readerId) return true;
|
||||
return task.active || task.unread;
|
||||
}
|
||||
|
||||
export function sessionMatchesListState(session: SessionSummary, state: SessionListState): boolean {
|
||||
if (state === "all") return true;
|
||||
if (state === "default") return session.active || session.unread;
|
||||
|
||||
Reference in New Issue
Block a user