Archived
Make stop abort active work
This commit is contained in:
@@ -108,6 +108,7 @@ export const api = {
|
|||||||
shell: (sessionId: string, text: string) => request(`/api/sessions/${sessionId}/shell`, parseAccepted, { method: "POST", body: JSON.stringify({ text }) }),
|
shell: (sessionId: string, text: string) => request(`/api/sessions/${sessionId}/shell`, parseAccepted, { method: "POST", body: JSON.stringify({ text }) }),
|
||||||
runCommand: (sessionId: string, text: string) => request(`/api/sessions/${sessionId}/commands/run`, parseCommandResult, { method: "POST", body: JSON.stringify({ text }) }),
|
runCommand: (sessionId: string, text: string) => request(`/api/sessions/${sessionId}/commands/run`, parseCommandResult, { method: "POST", body: JSON.stringify({ text }) }),
|
||||||
respondToCommand: (sessionId: string, requestId: string, value: string) => request(`/api/sessions/${sessionId}/commands/respond`, parseCommandResult, { method: "POST", body: JSON.stringify({ requestId, value }) }),
|
respondToCommand: (sessionId: string, requestId: string, value: string) => request(`/api/sessions/${sessionId}/commands/respond`, parseCommandResult, { method: "POST", body: JSON.stringify({ requestId, value }) }),
|
||||||
|
abort: (sessionId: string) => request(`/api/sessions/${sessionId}/abort`, parseAborted, { method: "POST" }),
|
||||||
stop: (sessionId: string) => request(`/api/sessions/${sessionId}/stop`, parseStopped, { method: "POST" }),
|
stop: (sessionId: string) => request(`/api/sessions/${sessionId}/stop`, parseStopped, { method: "POST" }),
|
||||||
archive: (sessionId: string) => request(`/api/sessions/${sessionId}/archive`, parseArchived, { method: "POST" }),
|
archive: (sessionId: string) => request(`/api/sessions/${sessionId}/archive`, parseArchived, { method: "POST" }),
|
||||||
restore: (sessionId: string) => request(`/api/sessions/${sessionId}/restore`, parseRestored, { method: "POST" }),
|
restore: (sessionId: string) => request(`/api/sessions/${sessionId}/restore`, parseRestored, { method: "POST" }),
|
||||||
@@ -300,6 +301,12 @@ function parseAccepted(value: unknown): { accepted: true } {
|
|||||||
return { accepted: true };
|
return { accepted: true };
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function parseAborted(value: unknown): { aborted: true } {
|
||||||
|
const record = requireRecord(value);
|
||||||
|
if (record["aborted"] !== true) throw new Error("Expected aborted response");
|
||||||
|
return { aborted: true };
|
||||||
|
}
|
||||||
|
|
||||||
function parseStopped(value: unknown): { stopped: true } {
|
function parseStopped(value: unknown): { stopped: true } {
|
||||||
const record = requireRecord(value);
|
const record = requireRecord(value);
|
||||||
if (record["stopped"] !== true) throw new Error("Expected stopped response");
|
if (record["stopped"] !== true) throw new Error("Expected stopped response");
|
||||||
|
|||||||
@@ -115,7 +115,7 @@ export class PiWebApp extends LitElement {
|
|||||||
${state.error ? html`<div class="error">${state.error}</div>` : null}
|
${state.error ? html`<div class="error">${state.error}</div>` : null}
|
||||||
${state.selectedSession ? html`
|
${state.selectedSession ? html`
|
||||||
<chat-view .sessionId=${state.selectedSession.id} .messages=${state.messages} .messageStart=${state.messagePageStart} .messageTotal=${state.messagePageTotal} .hasMore=${state.messagePageStart > 0} .loadingMore=${state.isLoadingEarlierMessages} .isCompacting=${state.status?.isCompacting === true} .pendingMessageCount=${state.status?.pendingMessageCount ?? 0} .onLoadMore=${() => this.withChatPrependTransition(() => this.sessions.loadEarlierMessages())}></chat-view>
|
<chat-view .sessionId=${state.selectedSession.id} .messages=${state.messages} .messageStart=${state.messagePageStart} .messageTotal=${state.messagePageTotal} .hasMore=${state.messagePageStart > 0} .loadingMore=${state.isLoadingEarlierMessages} .isCompacting=${state.status?.isCompacting === true} .pendingMessageCount=${state.status?.pendingMessageCount ?? 0} .onLoadMore=${() => this.withChatPrependTransition(() => this.sessions.loadEarlierMessages())}></chat-view>
|
||||||
<prompt-editor .sessionId=${state.selectedSession.id} .cwd=${state.selectedWorkspace?.path} .disabled=${state.selectedSession.archived === true} .canSteer=${state.status?.isStreaming === true} .isCompacting=${state.status?.isCompacting === true} .onSend=${(text: string, streamingBehavior?: "steer" | "followUp") => this.sessions.send(text, streamingBehavior)} .onStopSession=${() => this.sessions.stopSession()}></prompt-editor>
|
<prompt-editor .sessionId=${state.selectedSession.id} .cwd=${state.selectedWorkspace?.path} .disabled=${state.selectedSession.archived === true} .canSteer=${state.status?.isStreaming === true} .isCompacting=${state.status?.isCompacting === true} .canStop=${state.status?.isStreaming === true || state.status?.isBashRunning === true || state.status?.isCompacting === true} .onSend=${(text: string, streamingBehavior?: "steer" | "followUp") => this.sessions.send(text, streamingBehavior)} .onStop=${() => this.sessions.stopActiveWork()}></prompt-editor>
|
||||||
<status-bar .status=${state.status} .activity=${state.activity} .workspace=${state.selectedWorkspace}></status-bar>
|
<status-bar .status=${state.status} .activity=${state.activity} .workspace=${state.selectedWorkspace}></status-bar>
|
||||||
${state.commandDialog !== undefined ? html`<command-picker .title=${state.commandDialog.title} .options=${state.commandDialog.options} .onPick=${(value: string) => this.sessions.respondToCommand(state.commandDialog?.requestId ?? "", value)} .onCancel=${() => { this.sessions.cancelCommand(); }}></command-picker>` : null}
|
${state.commandDialog !== undefined ? html`<command-picker .title=${state.commandDialog.title} .options=${state.commandDialog.options} .onPick=${(value: string) => this.sessions.respondToCommand(state.commandDialog?.requestId ?? "", value)} .onCancel=${() => { this.sessions.cancelCommand(); }}></command-picker>` : null}
|
||||||
` : html`<div class="empty">Select or start a session.</div>`}
|
` : html`<div class="empty">Select or start a session.</div>`}
|
||||||
|
|||||||
@@ -12,8 +12,9 @@ export class PromptEditor extends LitElement {
|
|||||||
@property() cwd?: string;
|
@property() cwd?: string;
|
||||||
@property({ type: Boolean }) canSteer = false;
|
@property({ type: Boolean }) canSteer = false;
|
||||||
@property({ type: Boolean }) isCompacting = false;
|
@property({ type: Boolean }) isCompacting = false;
|
||||||
|
@property({ type: Boolean }) canStop = false;
|
||||||
@property({ attribute: false }) onSend?: (text: string, streamingBehavior?: "steer" | "followUp") => void;
|
@property({ attribute: false }) onSend?: (text: string, streamingBehavior?: "steer" | "followUp") => void;
|
||||||
@property({ attribute: false }) onStopSession?: () => void;
|
@property({ attribute: false }) onStop?: () => void;
|
||||||
@query("textarea") private textarea?: HTMLTextAreaElement;
|
@query("textarea") private textarea?: HTMLTextAreaElement;
|
||||||
@state() private draft = "";
|
@state() private draft = "";
|
||||||
@state() private completions: CompletionItem[] = [];
|
@state() private completions: CompletionItem[] = [];
|
||||||
@@ -56,7 +57,7 @@ export class PromptEditor extends LitElement {
|
|||||||
<div class="actions">
|
<div class="actions">
|
||||||
<button ?disabled=${this.disabled} title=${queuesInput ? "Queue until the current activity finishes" : "Send message"} @click=${() => { this.send("followUp"); }}>${queuesInput ? "Queue" : "Send"}</button>
|
<button ?disabled=${this.disabled} title=${queuesInput ? "Queue until the current activity finishes" : "Send message"} @click=${() => { this.send("followUp"); }}>${queuesInput ? "Queue" : "Send"}</button>
|
||||||
${this.canSteer && !this.isCompacting ? html`<button ?disabled=${this.disabled} title="Steer the current response before the next model call" @click=${() => { this.send("steer"); }}>Steer</button>` : null}
|
${this.canSteer && !this.isCompacting ? html`<button ?disabled=${this.disabled} title="Steer the current response before the next model call" @click=${() => { this.send("steer"); }}>Steer</button>` : null}
|
||||||
<button ?disabled=${this.disabled} title="Stop only this Pi session from continuing" @click=${() => this.onStopSession?.()}>Stop session</button>
|
<button ?disabled=${this.disabled || !this.canStop} title=${this.canStop ? "Stop current work" : "Nothing running"} @click=${() => this.onStop?.()}>Stop</button>
|
||||||
</div>
|
</div>
|
||||||
</footer>
|
</footer>
|
||||||
`;
|
`;
|
||||||
|
|||||||
@@ -167,16 +167,13 @@ export class SessionController {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
async stopSession() {
|
async stopActiveWork() {
|
||||||
const session = this.getState().selectedSession;
|
const session = this.getState().selectedSession;
|
||||||
if (!session) return;
|
if (!session) return;
|
||||||
try {
|
try {
|
||||||
await api.stop(session.id);
|
await api.abort(session.id);
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
this.setState({ error: String(error) });
|
this.setState({ error: String(error) });
|
||||||
} finally {
|
|
||||||
this.clearActiveSession();
|
|
||||||
this.updateUrl();
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -180,7 +180,10 @@ export class PiSessionService {
|
|||||||
|
|
||||||
async abort(sessionId: string): Promise<void> {
|
async abort(sessionId: string): Promise<void> {
|
||||||
const active = this.active.get(sessionId);
|
const active = this.active.get(sessionId);
|
||||||
if (active) await active.runtime.session.abort();
|
if (!active) return;
|
||||||
|
await active.runtime.session.abort();
|
||||||
|
this.publishActivity(active.runtime.session, "stopped", "idle");
|
||||||
|
this.publishStatus(active.runtime.session);
|
||||||
}
|
}
|
||||||
|
|
||||||
stop(sessionId: string): void {
|
stop(sessionId: string): void {
|
||||||
|
|||||||
Reference in New Issue
Block a user