feat(goal-run): add multi-checkpoint goal orchestration with H5 and admin surfaces.
Persist goal runs in MySQL, bind agent runs to checkpoints, expose awaiting-approval UX in chat, and add admin inspection routes with local verify scripts. Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
@@ -893,3 +893,126 @@ export async function patchMemoryV2Config(patch: Record<string, unknown>) {
|
||||
export async function fetchMemoryV2Runtime() {
|
||||
return adminFetch<MemoryV2RuntimeState>('/admin-api/memory-v2/runtime');
|
||||
}
|
||||
export type GoalRunRuntimeState = {
|
||||
enabled: boolean;
|
||||
canaryUserIds: string[];
|
||||
canaryMode: boolean;
|
||||
};
|
||||
|
||||
export type GoalRunSummaryResponse = {
|
||||
counts: Record<string, number>;
|
||||
runtime: GoalRunRuntimeState;
|
||||
};
|
||||
|
||||
export type GoalRunListItem = {
|
||||
id: string;
|
||||
userId: string;
|
||||
username: string | null;
|
||||
title: string;
|
||||
intentSummary: string;
|
||||
status: string;
|
||||
priority: number;
|
||||
sourceChannel: string;
|
||||
sourceSessionId: string | null;
|
||||
currentCheckpointId: string | null;
|
||||
checkpointCount: number;
|
||||
activeAgentRunCount: number;
|
||||
createdAt: number;
|
||||
updatedAt: number;
|
||||
completedAt: number | null;
|
||||
};
|
||||
|
||||
export type GoalRunCheckpointRow = {
|
||||
id: string;
|
||||
goalRunId: string;
|
||||
sequence: number;
|
||||
title: string;
|
||||
description: string | null;
|
||||
status: string;
|
||||
agentRunId: string | null;
|
||||
outputSummary: string | null;
|
||||
userFeedback: string | null;
|
||||
approvedAt: number | null;
|
||||
createdAt: number;
|
||||
updatedAt: number;
|
||||
startedAt: number | null;
|
||||
completedAt: number | null;
|
||||
};
|
||||
|
||||
export type GoalRunAgentRunRow = {
|
||||
id: string;
|
||||
status: string;
|
||||
requestId: string;
|
||||
goalCheckpointId: string | null;
|
||||
createdAt: number;
|
||||
updatedAt: number;
|
||||
completedAt: number | null;
|
||||
};
|
||||
|
||||
export type GoalRunDetail = {
|
||||
id: string;
|
||||
userId: string;
|
||||
username: string | null;
|
||||
title: string;
|
||||
intentSummary: string;
|
||||
status: string;
|
||||
priority: number;
|
||||
sourceChannel: string;
|
||||
sourceSessionId: string | null;
|
||||
sourceMessageId: string | null;
|
||||
currentCheckpointId: string | null;
|
||||
context: unknown;
|
||||
memorySnapshot: unknown;
|
||||
createdAt: number;
|
||||
updatedAt: number;
|
||||
completedAt: number | null;
|
||||
checkpoints: GoalRunCheckpointRow[];
|
||||
agentRuns: GoalRunAgentRunRow[];
|
||||
canaryEnabled: boolean;
|
||||
};
|
||||
|
||||
export async function fetchGoalRunSummary() {
|
||||
return adminFetch<GoalRunSummaryResponse>('/admin-api/goal-runs/summary');
|
||||
}
|
||||
|
||||
export async function fetchGoalRuns(params?: {
|
||||
status?: string;
|
||||
userId?: string;
|
||||
limit?: number;
|
||||
offset?: number;
|
||||
}) {
|
||||
const query = new URLSearchParams();
|
||||
if (params?.status) query.set('status', params.status);
|
||||
if (params?.userId) query.set('userId', params.userId);
|
||||
if (params?.limit != null) query.set('limit', String(params.limit));
|
||||
if (params?.offset != null) query.set('offset', String(params.offset));
|
||||
const suffix = query.toString() ? `?${query.toString()}` : '';
|
||||
return adminFetch<{ items: GoalRunListItem[]; status: string | null; limit: number; offset: number }>(
|
||||
`/admin-api/goal-runs${suffix}`,
|
||||
);
|
||||
}
|
||||
|
||||
export async function fetchGoalRunDetail(goalRunId: string) {
|
||||
return adminFetch<{ goal: GoalRunDetail }>(`/admin-api/goal-runs/${encodeURIComponent(goalRunId)}`);
|
||||
}
|
||||
|
||||
export async function approveGoalRunCheckpoint(
|
||||
goalRunId: string,
|
||||
checkpointId: string,
|
||||
feedback?: string | null,
|
||||
) {
|
||||
return adminFetch<{ ok: true; goal: GoalRunDetail }>(
|
||||
`/admin-api/goal-runs/${encodeURIComponent(goalRunId)}/checkpoints/${encodeURIComponent(checkpointId)}/approve`,
|
||||
{
|
||||
method: 'POST',
|
||||
body: JSON.stringify({ feedback: feedback ?? null }),
|
||||
},
|
||||
);
|
||||
}
|
||||
|
||||
export async function cancelGoalRun(goalRunId: string) {
|
||||
return adminFetch<{ ok: true; goal: GoalRunDetail }>(
|
||||
`/admin-api/goal-runs/${encodeURIComponent(goalRunId)}/cancel`,
|
||||
{ method: 'POST', body: JSON.stringify({}) },
|
||||
);
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user