Q55: the operator can stop in-flight runs; pause stops them too

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
ZacharyZhang-NYandClaude Opus 5.5 committed 2026-10-08 09:59:03 -04:00
1 parent e809cfefea
commit 9e1f8da11c
18 files changed
+259 -17

No files matched your search

+3
View File
@@ -32,6 +32,9 @@ export const zh: Record<string, string> = {
"superseded": "已被取代",
"stalled": "已停滞",
"Resume": "恢复",
"Stop": "停止",
"Stopped": "已停止",
"stopped": "已停止",
"Why it did not run": "未运行的原因",
"Done tasks do not run": "已完成的任务不能再运行",
"A session is already queued or running": "已有会话在排队或运行中",
+1
View File
@@ -360,5 +360,6 @@ function runStateLabel(state: string): string {
if (state === "completed") return t("Done");
if (state === "failed") return t("Failed");
if (state === "superseded") return t("Superseded");
if (state === "stopped") return t("Stopped");
return state;
}
+14 -4
View File
@@ -1,5 +1,5 @@
import { useMemo, useState } from "react";
import { Avatar, Pill, Segmented } from "../shared/ui";
import { Avatar, Button, Pill, Segmented } from "../shared/ui";
import type { AgentRecord, ProviderRecord, TaskRecord, TaskRunRecord } from "../../../shared/domain";
import type { PageProps } from "./types";
import { activeOrgId, formatRelative } from "./types";
@@ -14,7 +14,7 @@ const FILTERS: Array<{ id: StatusFilter; label: string }> = [
{ id: "failed", label: t("Failed") },
];
export function RunsPage({ snapshot }: PageProps) {
export function RunsPage({ snapshot, actions }: PageProps) {
const orgId = activeOrgId(snapshot);
const taskRuns = useMemo(() => snapshot.taskRuns.filter((r) => r.orgId === orgId), [snapshot.taskRuns, orgId]);
const tasks = useMemo(() => snapshot.tasks.filter((t) => t.orgId === orgId), [snapshot.tasks, orgId]);
@@ -89,7 +89,7 @@ export function RunsPage({ snapshot }: PageProps) {
</aside>
<div style={{ flex: 1, minWidth: 0, overflow: "auto", padding: 24 }}>
{selected ? (
<RunDetail run={selected} tasks={tasks} agents={agents} providers={providers} providerRequests={providerRequests} />
<RunDetail run={selected} tasks={tasks} agents={agents} providers={providers} providerRequests={providerRequests} actions={actions} />
) : (
<div style={{ display: "grid", placeItems: "center", height: "100%", color: "var(--text-3)", fontSize: 14 }}>
{t("Select a run")}
@@ -100,7 +100,8 @@ export function RunsPage({ snapshot }: PageProps) {
);
}
function RunDetail({ run, tasks, agents, providers, providerRequests }: {
function RunDetail({ run, tasks, agents, providers, providerRequests, actions }: {
actions: PageProps["actions"];
run: TaskRunRecord;
tasks: TaskRecord[];
agents: AgentRecord[];
@@ -115,6 +116,12 @@ function RunDetail({ run, tasks, agents, providers, providerRequests }: {
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)));
};
return (
<div>
@@ -125,7 +132,9 @@ function RunDetail({ run, tasks, agents, providers, providerRequests }: {
<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>}
</div>
{stopError && <div className="form-error" role="alert">{stopError}</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>
@@ -204,6 +213,7 @@ function runLabel(state: string): string {
if (state === "completed") return t("Done");
if (state === "failed") return t("Failed");
if (state === "superseded") return t("Superseded");
if (state === "stopped") return t("Stopped");
return state;
}
@@ -28,6 +28,7 @@ export function prettyRunState(state: string): string {
if (state === "completed") return t("completed");
if (state === "failed") return t("failed");
if (state === "superseded") return t("superseded");
if (state === "stopped") return t("stopped");
return state.replaceAll("_", " ");
}