feat: add end session button to chat header

This commit is contained in:
Nathan Flurry 2026-01-27 21:03:33 -08:00
parent 53a06becb1
commit 962512a0db
3 changed files with 29 additions and 1 deletions

View file

@ -548,6 +548,16 @@ export default function App() {
} }
}; };
const endSession = async () => {
if (!sessionId) return;
try {
await getClient().terminateSession(sessionId);
await fetchSessions();
} catch (error) {
setSessionError(getErrorMessage(error, "Unable to end session"));
}
};
const questionRequests = useMemo(() => { const questionRequests = useMemo(() => {
const latestById = new Map<string, QuestionEventData>(); const latestById = new Map<string, QuestionEventData>();
for (const event of events) { for (const event of events) {
@ -859,6 +869,7 @@ export default function App() {
onVariantChange={setVariant} onVariantChange={setVariant}
onStreamModeChange={setStreamMode} onStreamModeChange={setStreamMode}
onToggleStream={toggleStream} onToggleStream={toggleStream}
onEndSession={endSession}
hasSession={Boolean(sessionId)} hasSession={Boolean(sessionId)}
eventError={eventError} eventError={eventError}
questionRequests={questionRequests} questionRequests={questionRequests}

View file

@ -1,4 +1,4 @@
import { MessageSquare, PauseCircle, PlayCircle, Plus, Terminal } from "lucide-react"; import { MessageSquare, PauseCircle, PlayCircle, Plus, Square, Terminal } from "lucide-react";
import { useEffect, useRef, useState } from "react"; import { useEffect, useRef, useState } from "react";
import type { AgentInfo, AgentModeInfo, PermissionEventData, QuestionEventData } from "sandbox-agent"; import type { AgentInfo, AgentModeInfo, PermissionEventData, QuestionEventData } from "sandbox-agent";
import ApprovalsTab from "../debug/ApprovalsTab"; import ApprovalsTab from "../debug/ApprovalsTab";
@ -39,6 +39,7 @@ const ChatPanel = ({
onVariantChange, onVariantChange,
onStreamModeChange, onStreamModeChange,
onToggleStream, onToggleStream,
onEndSession,
eventError, eventError,
questionRequests, questionRequests,
permissionRequests, permissionRequests,
@ -79,6 +80,7 @@ const ChatPanel = ({
onVariantChange: (value: string) => void; onVariantChange: (value: string) => void;
onStreamModeChange: (value: "poll" | "sse" | "turn") => void; onStreamModeChange: (value: "poll" | "sse" | "turn") => void;
onToggleStream: () => void; onToggleStream: () => void;
onEndSession: () => void;
eventError: string | null; eventError: string | null;
questionRequests: QuestionEventData[]; questionRequests: QuestionEventData[];
permissionRequests: PermissionEventData[]; permissionRequests: PermissionEventData[];
@ -131,6 +133,17 @@ const ChatPanel = ({
)} )}
</div> </div>
<div className="panel-header-right"> <div className="panel-header-right">
{sessionId && (
<button
type="button"
className="button ghost small"
onClick={onEndSession}
title="End session"
>
<Square size={12} />
End
</button>
)}
<div className="setup-stream"> <div className="setup-stream">
<select <select
className="setup-select-small" className="setup-select-small"

View file

@ -207,6 +207,10 @@ export class SandboxAgent {
); );
} }
async terminateSession(sessionId: string): Promise<void> {
await this.requestJson("POST", `${API_PREFIX}/sessions/${encodeURIComponent(sessionId)}/terminate`);
}
async dispose(): Promise<void> { async dispose(): Promise<void> {
if (this.spawnHandle) { if (this.spawnHandle) {
await this.spawnHandle.dispose(); await this.spawnHandle.dispose();