feat(agent): add task status and client-scoped operations

This commit is contained in:
yu
2026-07-17 18:30:10 +08:00
parent bdca6b0a5c
commit 062e4569aa
13 changed files with 407 additions and 39 deletions
+36 -4
View File
@@ -6,15 +6,30 @@ import { create } from "zustand";
export type WorkbenchCommand = {
nonce: number;
taskId?: string;
prompt?: string;
run: boolean;
};
export type WorkbenchGenerationTask = {
id: string;
kind: "image" | "video";
status: "queued" | "running" | "succeeded" | "failed";
prompt?: string;
createdAt: string;
updatedAt: string;
successCount?: number;
failCount?: number;
error?: string;
};
type WorkbenchAgentStore = {
imageCommand: WorkbenchCommand | null;
videoCommand: WorkbenchCommand | null;
dispatchImage: (command: Omit<WorkbenchCommand, "nonce">) => void;
dispatchVideo: (command: Omit<WorkbenchCommand, "nonce">) => void;
tasks: WorkbenchGenerationTask[];
dispatchImage: (command: Omit<WorkbenchCommand, "nonce" | "taskId">) => string | undefined;
dispatchVideo: (command: Omit<WorkbenchCommand, "nonce" | "taskId">) => string | undefined;
updateTask: (id: string, patch: Partial<Pick<WorkbenchGenerationTask, "status" | "successCount" | "failCount" | "error">>) => void;
clearImageCommand: () => void;
clearVideoCommand: () => void;
};
@@ -25,8 +40,25 @@ const nextNonce = () => (nonce += 1);
export const useWorkbenchAgentStore = create<WorkbenchAgentStore>((set) => ({
imageCommand: null,
videoCommand: null,
dispatchImage: (command) => set({ imageCommand: { ...command, nonce: nextNonce() } }),
dispatchVideo: (command) => set({ videoCommand: { ...command, nonce: nextNonce() } }),
tasks: [],
dispatchImage: (command) => {
const commandNonce = nextNonce();
const task = command.run ? createTask("image", commandNonce, command.prompt) : undefined;
set((state) => ({ imageCommand: { ...command, nonce: commandNonce, taskId: task?.id }, tasks: task ? [task, ...state.tasks].slice(0, 30) : state.tasks }));
return task?.id;
},
dispatchVideo: (command) => {
const commandNonce = nextNonce();
const task = command.run ? createTask("video", commandNonce, command.prompt) : undefined;
set((state) => ({ videoCommand: { ...command, nonce: commandNonce, taskId: task?.id }, tasks: task ? [task, ...state.tasks].slice(0, 30) : state.tasks }));
return task?.id;
},
updateTask: (id, patch) => set((state) => ({ tasks: state.tasks.map((task) => (task.id === id ? { ...task, ...patch, updatedAt: new Date().toISOString() } : task)) })),
clearImageCommand: () => set({ imageCommand: null }),
clearVideoCommand: () => set({ videoCommand: null }),
}));
function createTask(kind: "image" | "video", commandNonce: number, prompt?: string): WorkbenchGenerationTask {
const now = new Date().toISOString();
return { id: `${kind}-${commandNonce}`, kind, status: "queued", prompt, createdAt: now, updatedAt: now };
}