fix: 暴露 session follow-up 可见性
This commit is contained in:
+111
-10
@@ -115,9 +115,10 @@ async function readBody(req: import("node:http").IncomingMessage): Promise<unkno
|
||||
return JSON.parse(text) as unknown;
|
||||
}
|
||||
|
||||
async function refreshQueueTaskForRead(store: AgentRunStore, taskId: string): Promise<QueueTaskRecord> {
|
||||
async function refreshQueueTaskForRead(store: AgentRunStore, taskId: string): Promise<JsonRecord> {
|
||||
const task = await store.getQueueTask(taskId);
|
||||
return await refreshQueueTaskRecordForRead(store, task);
|
||||
const refreshed = await refreshQueueTaskRecordForRead(store, task);
|
||||
return await enrichQueueTaskForRead(store, refreshed as unknown as JsonRecord);
|
||||
}
|
||||
|
||||
async function refreshQueuePageForRead(store: AgentRunStore, input: ListQueueTasksInput): Promise<void> {
|
||||
@@ -148,27 +149,69 @@ async function queueCommanderForRead(store: AgentRunStore, queue: string | undef
|
||||
const items = Array.isArray(snapshot.items) ? snapshot.items : [];
|
||||
const enrichedItems = await Promise.all(items.map(async (item) => {
|
||||
const task = asJsonRecord(item);
|
||||
if (!task) return item as JsonValue;
|
||||
const supervisor = await queueTaskSupervisor(store, task);
|
||||
return supervisor ? { ...task, supervisor, valuesPrinted: false } : task;
|
||||
return task ? await enrichQueueTaskForRead(store, task) as JsonValue : item as JsonValue;
|
||||
}));
|
||||
return { ...snapshot, items: enrichedItems, valuesPrinted: false } as JsonValue;
|
||||
const byId = new Map<string, JsonValue>();
|
||||
for (const item of enrichedItems) {
|
||||
const task = asJsonRecord(item);
|
||||
const id = stringJsonValue(task?.id);
|
||||
if (id) byId.set(id, item);
|
||||
}
|
||||
if (readerId) {
|
||||
const unfiltered = await store.queueCommander(queue, null) as unknown as JsonRecord;
|
||||
const unfilteredItems = Array.isArray(unfiltered.items) ? unfiltered.items : [];
|
||||
for (const item of unfilteredItems) {
|
||||
const task = asJsonRecord(item);
|
||||
const id = stringJsonValue(task?.id);
|
||||
if (!task || !id || byId.has(id)) continue;
|
||||
const enriched = await enrichQueueTaskForRead(store, task);
|
||||
if (queueTaskHasActiveSession(enriched)) byId.set(id, enriched as unknown as JsonValue);
|
||||
}
|
||||
}
|
||||
const visibleItems = Array.from(byId.values());
|
||||
const activeSessionCount = visibleItems.filter((item) => queueTaskHasActiveSession(asJsonRecord(item))).length;
|
||||
return { ...snapshot, items: visibleItems, activeSessionCount, valuesPrinted: false } as JsonValue;
|
||||
}
|
||||
|
||||
async function queueTaskSupervisor(store: AgentRunStore, task: JsonRecord): Promise<JsonRecord | null> {
|
||||
async function enrichQueueTaskForRead(store: AgentRunStore, task: JsonRecord): Promise<JsonRecord> {
|
||||
const activeSession = await queueTaskActiveSession(store, task);
|
||||
const supervisor = await queueTaskSupervisor(store, task, activeSession);
|
||||
const activeBySession = activeSession?.active === true || stringJsonValue(activeSession?.activeRunId) !== null || stringJsonValue(activeSession?.activeCommandId) !== null;
|
||||
return {
|
||||
...task,
|
||||
...(activeSession ? { activeSession } : {}),
|
||||
...(supervisor ? { supervisor } : {}),
|
||||
...(activeBySession ? { active: true, attentionState: "active-session" } : {}),
|
||||
valuesPrinted: false,
|
||||
};
|
||||
}
|
||||
|
||||
async function queueTaskSupervisor(store: AgentRunStore, task: JsonRecord, activeSession: JsonRecord | null = null): Promise<JsonRecord | null> {
|
||||
const attempt = asJsonRecord(task.latestAttempt);
|
||||
const runId = stringJsonValue(attempt?.runId);
|
||||
const attemptRunId = stringJsonValue(attempt?.runId);
|
||||
const attemptCommandId = stringJsonValue(attempt?.commandId);
|
||||
const activeRunId = stringJsonValue(activeSession?.activeRunId);
|
||||
const activeCommandId = stringJsonValue(activeSession?.activeCommandId);
|
||||
const runId = activeRunId ?? attemptRunId;
|
||||
if (!runId) return null;
|
||||
const commandId = activeCommandId ?? attemptCommandId ?? undefined;
|
||||
try {
|
||||
const result = await buildRunResult(store, runId, stringJsonValue(attempt?.commandId) ?? undefined);
|
||||
const result = await buildRunResult(store, runId, commandId);
|
||||
const liveness = asJsonRecord(result.liveness);
|
||||
const lastActivity = asJsonRecord(liveness?.lastActivity ?? liveness?.lastCommandActivity);
|
||||
const timeoutBudget = asJsonRecord(liveness?.timeoutBudget);
|
||||
const terminalClassification = asJsonRecord(result.terminalClassification ?? liveness?.terminalClassification);
|
||||
const lease = asJsonRecord(liveness?.lease);
|
||||
return {
|
||||
source: activeRunId ? "active-session" : "latest-attempt",
|
||||
attemptRunId,
|
||||
attemptCommandId,
|
||||
activeSession,
|
||||
runId: stringJsonValue(result.runId),
|
||||
commandId: stringJsonValue(result.commandId),
|
||||
executionState: stringJsonValue(activeSession?.executionState),
|
||||
activeRunId,
|
||||
activeCommandId,
|
||||
status: stringJsonValue(result.status),
|
||||
terminalStatus: stringJsonValue(result.terminalStatus),
|
||||
failureKind: stringJsonValue(result.failureKind),
|
||||
@@ -192,6 +235,46 @@ async function queueTaskSupervisor(store: AgentRunStore, task: JsonRecord): Prom
|
||||
}
|
||||
}
|
||||
|
||||
async function queueTaskActiveSession(store: AgentRunStore, task: JsonRecord): Promise<JsonRecord | null> {
|
||||
const sessionId = queueTaskSessionId(task);
|
||||
if (!sessionId) return null;
|
||||
try {
|
||||
const session = await store.getSessionSummary(sessionId, null) as unknown as JsonRecord;
|
||||
const activeRunId = stringJsonValue(session.activeRunId);
|
||||
const activeCommandId = stringJsonValue(session.activeCommandId);
|
||||
const active = session.active === true || activeRunId !== null || activeCommandId !== null || stringJsonValue(session.executionState) === "running";
|
||||
if (!active) return null;
|
||||
return {
|
||||
sessionId,
|
||||
sessionPath: stringJsonValue(session.sessionPath) ?? `/api/v1/sessions/${sessionId}`,
|
||||
executionState: stringJsonValue(session.executionState),
|
||||
attentionState: stringJsonValue(session.attentionState),
|
||||
active,
|
||||
activeRunId,
|
||||
activeCommandId,
|
||||
lastRunId: stringJsonValue(session.lastRunId),
|
||||
lastCommandId: stringJsonValue(session.lastCommandId),
|
||||
terminalStatus: stringJsonValue(session.terminalStatus),
|
||||
failureKind: stringJsonValue(session.failureKind),
|
||||
lastActivityAt: stringJsonValue(session.lastActivityAt),
|
||||
updatedAt: stringJsonValue(session.updatedAt),
|
||||
valuesPrinted: false,
|
||||
};
|
||||
} catch {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
function queueTaskSessionId(task: JsonRecord): string | null {
|
||||
return stringJsonValue(asJsonRecord(task.sessionRef)?.sessionId) ?? stringJsonValue(asJsonRecord(task.latestAttempt)?.sessionId) ?? null;
|
||||
}
|
||||
|
||||
function queueTaskHasActiveSession(task: JsonRecord | null): boolean {
|
||||
const activeSession = asJsonRecord(task?.activeSession);
|
||||
const supervisor = asJsonRecord(task?.supervisor);
|
||||
return activeSession?.active === true || supervisor?.source === "active-session" || supervisor?.active === true;
|
||||
}
|
||||
|
||||
function compactActivity(activity: JsonRecord): JsonRecord {
|
||||
return {
|
||||
sourceSeq: numberJsonValue(activity.sourceSeq ?? activity.seq),
|
||||
@@ -337,17 +420,35 @@ async function route({ method, url, body, store, sourceCommit, authSummary, runn
|
||||
const commandId = summary.activeCommandId ?? summary.lastCommandId ?? undefined;
|
||||
try {
|
||||
const result = await buildRunResult(store, runId, commandId);
|
||||
const liveness = asJsonRecord(result.liveness);
|
||||
const lastActivity = asJsonRecord(liveness?.lastActivity ?? liveness?.lastCommandActivity);
|
||||
const timeoutBudget = asJsonRecord(liveness?.timeoutBudget);
|
||||
const terminalClassification = asJsonRecord(result.terminalClassification ?? liveness?.terminalClassification);
|
||||
return {
|
||||
...summary,
|
||||
liveness: result.liveness ?? null,
|
||||
supervisor: {
|
||||
sessionId: summary.sessionId,
|
||||
executionState: summary.executionState,
|
||||
attentionState: summary.attentionState,
|
||||
active: summary.active,
|
||||
activeRunId: summary.activeRunId,
|
||||
activeCommandId: summary.activeCommandId,
|
||||
lastRunId: summary.lastRunId,
|
||||
lastCommandId: summary.lastCommandId,
|
||||
runId: result.runId,
|
||||
commandId: result.commandId,
|
||||
status: result.status,
|
||||
terminalStatus: result.terminalStatus,
|
||||
failureKind: result.failureKind,
|
||||
terminalClassification: terminalClassification ? compactTerminalClassification(terminalClassification) : null,
|
||||
phase: stringJsonValue(liveness?.phase),
|
||||
lastEventAgeMs: numberJsonValue(liveness?.lastEventAgeMs),
|
||||
lastActivity: lastActivity ? compactActivity(lastActivity) : null,
|
||||
timeoutBudget: timeoutBudget ? compactTimeoutBudget(timeoutBudget) : null,
|
||||
lastSeq: result.lastSeq,
|
||||
liveness: result.liveness ?? null,
|
||||
recoveryActions: typeof result.liveness === "object" && result.liveness !== null && !Array.isArray(result.liveness) ? (result.liveness as JsonRecord).recoveryActions ?? [] : [],
|
||||
recoveryActions: compactRecoveryActions(liveness?.recoveryActions),
|
||||
...(result.steerDelivery ? { steerDelivery: result.steerDelivery } : {}),
|
||||
valuesPrinted: false,
|
||||
},
|
||||
|
||||
Reference in New Issue
Block a user