story-kit: merge 337_story_web_ui_button_to_stop_an_agent_on_a_story
This commit is contained in:
@@ -798,6 +798,12 @@ export function Chat({ projectPath, onCloseProject }: ChatProps) {
|
||||
setQueuedMessages([...queuedMessagesRef.current]);
|
||||
}, []);
|
||||
|
||||
const handleStopAgent = useCallback((storyId: string, agentName: string) => {
|
||||
agentsApi.stopAgent(storyId, agentName).catch((err: unknown) => {
|
||||
console.error("Failed to stop agent:", err);
|
||||
});
|
||||
}, []);
|
||||
|
||||
return (
|
||||
<div
|
||||
className="chat-container"
|
||||
@@ -1077,18 +1083,21 @@ export function Chat({ projectPath, onCloseProject }: ChatProps) {
|
||||
items={pipeline.done ?? []}
|
||||
costs={storyTokenCosts}
|
||||
onItemClick={(item) => setSelectedWorkItemId(item.story_id)}
|
||||
onStopAgent={handleStopAgent}
|
||||
/>
|
||||
<StagePanel
|
||||
title="To Merge"
|
||||
items={pipeline.merge}
|
||||
costs={storyTokenCosts}
|
||||
onItemClick={(item) => setSelectedWorkItemId(item.story_id)}
|
||||
onStopAgent={handleStopAgent}
|
||||
/>
|
||||
<StagePanel
|
||||
title="QA"
|
||||
items={pipeline.qa}
|
||||
costs={storyTokenCosts}
|
||||
onItemClick={(item) => setSelectedWorkItemId(item.story_id)}
|
||||
onStopAgent={handleStopAgent}
|
||||
/>
|
||||
<StagePanel
|
||||
title="Current"
|
||||
@@ -1098,6 +1107,7 @@ export function Chat({ projectPath, onCloseProject }: ChatProps) {
|
||||
agentRoster={agentRoster}
|
||||
busyAgentNames={busyAgentNames}
|
||||
onStartAgent={handleStartAgent}
|
||||
onStopAgent={handleStopAgent}
|
||||
/>
|
||||
<StagePanel
|
||||
title="Backlog"
|
||||
@@ -1107,6 +1117,7 @@ export function Chat({ projectPath, onCloseProject }: ChatProps) {
|
||||
agentRoster={agentRoster}
|
||||
busyAgentNames={busyAgentNames}
|
||||
onStartAgent={handleStartAgent}
|
||||
onStopAgent={handleStopAgent}
|
||||
/>
|
||||
<ServerLogsPanel logs={serverLogs} />
|
||||
</>
|
||||
|
||||
@@ -43,6 +43,7 @@ interface StagePanelProps {
|
||||
items: PipelineStageItem[];
|
||||
emptyMessage?: string;
|
||||
onItemClick?: (item: PipelineStageItem) => void;
|
||||
onStopAgent?: (storyId: string, agentName: string) => void;
|
||||
/** Map of story_id → total_cost_usd for displaying cost badges. */
|
||||
costs?: Map<string, number>;
|
||||
/** Agent roster to populate the start agent dropdown. */
|
||||
@@ -56,9 +57,11 @@ interface StagePanelProps {
|
||||
function AgentLozenge({
|
||||
agent,
|
||||
storyId,
|
||||
onStop,
|
||||
}: {
|
||||
agent: AgentAssignment;
|
||||
storyId: string;
|
||||
onStop?: () => void;
|
||||
}) {
|
||||
const { saveSlotRect, pendingFlyIns } = useLozengeFly();
|
||||
const lozengeRef = useRef<HTMLDivElement>(null);
|
||||
@@ -128,6 +131,31 @@ function AgentLozenge({
|
||||
/>
|
||||
)}
|
||||
{label}
|
||||
{isRunning && onStop && (
|
||||
<button
|
||||
type="button"
|
||||
data-testid={`stop-agent-${storyId}`}
|
||||
onClick={(e) => {
|
||||
e.stopPropagation();
|
||||
onStop();
|
||||
}}
|
||||
title="Stop agent"
|
||||
style={{
|
||||
marginLeft: "4px",
|
||||
padding: "0 3px",
|
||||
background: "transparent",
|
||||
border: "none",
|
||||
color,
|
||||
cursor: "pointer",
|
||||
fontSize: "0.9em",
|
||||
lineHeight: 1,
|
||||
opacity: 0.8,
|
||||
flexShrink: 0,
|
||||
}}
|
||||
>
|
||||
■
|
||||
</button>
|
||||
)}
|
||||
</div>
|
||||
);
|
||||
}
|
||||
@@ -224,6 +252,7 @@ export function StagePanel({
|
||||
items,
|
||||
emptyMessage = "Empty.",
|
||||
onItemClick,
|
||||
onStopAgent,
|
||||
costs,
|
||||
agentRoster,
|
||||
busyAgentNames,
|
||||
@@ -391,7 +420,19 @@ export function StagePanel({
|
||||
)}
|
||||
</div>
|
||||
{item.agent && (
|
||||
<AgentLozenge agent={item.agent} storyId={item.story_id} />
|
||||
<AgentLozenge
|
||||
agent={item.agent}
|
||||
storyId={item.story_id}
|
||||
onStop={
|
||||
onStopAgent && item.agent.status === "running"
|
||||
? () =>
|
||||
onStopAgent(
|
||||
item.story_id,
|
||||
item.agent?.agent_name ?? "",
|
||||
)
|
||||
: undefined
|
||||
}
|
||||
/>
|
||||
)}
|
||||
{canStart && onStartAgent && (
|
||||
<StartAgentControl
|
||||
|
||||
Reference in New Issue
Block a user