Q157: a run can be cancelled before it starts, and a failed or stopped one retried or resumed
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
1 parent
71ac5085cd
commit
a075f931d5
12 files changed
+114
-22
No files matched your search
@@ -51,6 +51,10 @@ export const zh: Record<string, string> = {
|
||||
"No notes": "无备注",
|
||||
"Showing {shown} of {total}": "显示 {total} 项中的 {shown} 项",
|
||||
"Show earlier decisions": "显示更早的决定",
|
||||
"Cancel run": "取消运行",
|
||||
"Running…": "运行中…",
|
||||
"A cancelled session can start again on the next heartbeat; block the task to keep it stopped.": "取消的会话可能在下一次心跳时再次开始;如需保持停止,请阻塞该任务。",
|
||||
"A new session on the task picks up from what earlier sessions did and where they stopped.": "任务的新会话会接着之前会话做过的工作和停下的位置继续。",
|
||||
"Edit the task": "编辑任务",
|
||||
"Changing the task replaces this request with a fresh one.": "修改任务会用新的申请替换这一项。",
|
||||
"Delete task": "删除任务",
|
||||
|
||||
@@ -90,7 +90,7 @@ export function RunsPage({ snapshot, actions, navigate, focus }: PageProps) {
|
||||
</aside>
|
||||
<div style={{ flex: 1, minWidth: 0, overflow: "auto", padding: 24 }}>
|
||||
{selected ? (
|
||||
<RunDetail run={selected} tasks={tasks} agents={agents} providers={providers} providerRequests={providerRequests} actions={actions} onOpenTask={(taskId) => navigate("work", { kind: "task", id: taskId })} />
|
||||
<RunDetail key={selected.id} run={selected} tasks={tasks} agents={agents} providers={providers} providerRequests={providerRequests} actions={actions} onOpenTask={(taskId) => navigate("work", { kind: "task", id: taskId })} />
|
||||
) : (
|
||||
<div style={{ display: "grid", placeItems: "center", height: "100%", color: "var(--text-3)", fontSize: 14 }}>
|
||||
{t("Select a run")}
|
||||
@@ -118,12 +118,19 @@ function RunDetail({ run, tasks, agents, providers, providerRequests, actions, o
|
||||
const started = run.startedAt ? new Date(run.startedAt) : null;
|
||||
const completed = run.completedAt ? new Date(run.completedAt) : null;
|
||||
const durationMs = started && completed ? completed.getTime() - started.getTime() : null;
|
||||
const [stopError, setStopError] = useState<string | null>(null);
|
||||
const stop = (runId: string) => {
|
||||
setStopError(null);
|
||||
actions.run(() => window.agentCompany.stopRun({ runId }))
|
||||
.catch((error: unknown) => setStopError(error instanceof Error ? error.message : String(error)));
|
||||
// Stop a running session, cancel one not yet started, or start a new session that picks up from the journal.
|
||||
const [controlError, setControlError] = useState<string | null>(null);
|
||||
const [busy, setBusy] = useState(false);
|
||||
const control = (operation: () => Promise<unknown>) => {
|
||||
setControlError(null);
|
||||
setBusy(true);
|
||||
operation()
|
||||
.catch((error: unknown) => setControlError(error instanceof Error ? error.message : String(error)))
|
||||
.finally(() => setBusy(false));
|
||||
};
|
||||
const stop = () => control(() => actions.run(() => window.agentCompany.stopRun({ runId: run.id })));
|
||||
const cancel = () => control(() => actions.run(() => window.agentCompany.cancelQueuedRun({ orgId: run.orgId, runId: run.id })));
|
||||
const again = () => control(() => actions.run(() => window.agentCompany.runTask({ orgId: run.orgId, taskId: run.taskId })));
|
||||
|
||||
return (
|
||||
<div>
|
||||
@@ -136,9 +143,16 @@ function RunDetail({ run, tasks, agents, providers, providerRequests, actions, o
|
||||
<div style={{ fontSize: 12, color: "var(--text-3)" }}>{run.id}</div>
|
||||
</div>
|
||||
<Pill tone={runTone(run.state)}>{runLabel(run.state)}</Pill>
|
||||
{run.state === "running" && <Button size="small" onClick={() => stop(run.id)}>{t("Stop")}</Button>}
|
||||
{run.state === "running" && <Button size="small" onClick={stop} disabled={busy}>{t("Stop")}</Button>}
|
||||
{run.state === "queued" && <Button size="small" onClick={cancel} disabled={busy}>{t("Cancel run")}</Button>}
|
||||
{run.state === "failed" && <Button size="small" onClick={again} disabled={busy}>{busy ? t("Running…") : t("Retry")}</Button>}
|
||||
{(run.state === "stopped" || run.state === "superseded") && <Button size="small" onClick={again} disabled={busy}>{busy ? t("Running…") : t("Resume")}</Button>}
|
||||
</div>
|
||||
{stopError && <div className="form-error" role="alert">{stopError}</div>}
|
||||
{run.state === "queued" && <div style={{ fontSize: 12, color: "var(--text-3)", marginBottom: 8 }}>{t("A cancelled session can start again on the next heartbeat; block the task to keep it stopped.")}</div>}
|
||||
{(run.state === "failed" || run.state === "stopped" || run.state === "superseded") && (
|
||||
<div style={{ fontSize: 12, color: "var(--text-3)", marginBottom: 8 }}>{t("A new session on the task picks up from what earlier sessions did and where they stopped.")}</div>
|
||||
)}
|
||||
{controlError && <div className="form-error" role="alert">{controlError}</div>}
|
||||
|
||||
<div style={{ display: "grid", gridTemplateColumns: "120px 1fr", gap: "8px 16px", fontSize: 14, marginBottom: 20 }}>
|
||||
<MetaLabel>{t("Agent")}</MetaLabel><div>{agent?.name ?? "—"} ({agent?.role ?? "—"})</div>
|
||||
|
||||
Reference in new issue
Block a user