Add a pause that holds an agent after its current step
This commit is contained in:
@@ -174,6 +174,10 @@ final class ChatModel {
|
||||
builder.open && session?.state == .running
|
||||
}
|
||||
|
||||
var paused: Bool {
|
||||
liveSession?.paused ?? false
|
||||
}
|
||||
|
||||
var reviewing: Bool {
|
||||
let state = taskId.flatMap { store.findTask($0) }?.state
|
||||
return state == .reviewing || state == .reviewPending || state == .mergeAfterReview
|
||||
@@ -559,6 +563,20 @@ final class ChatModel {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func setPaused(_ sessionId: String, _ paused: Bool, _ overlays: Overlays) {
|
||||
Task {
|
||||
do {
|
||||
if paused {
|
||||
_ = try await store.api.client.pauseSession(path: .init(sessionId: sessionId)).ok
|
||||
} else {
|
||||
_ = try await store.api.client.resumeSession(path: .init(sessionId: sessionId)).ok
|
||||
}
|
||||
} catch {
|
||||
overlays.showAlert(errorText(error))
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
struct ChatView: View {
|
||||
@@ -825,6 +843,24 @@ private struct ScrollMetrics: Equatable {
|
||||
let offset: CGFloat
|
||||
}
|
||||
|
||||
private struct PausedLine: View {
|
||||
let running: Bool
|
||||
|
||||
var body: some View {
|
||||
HStack(spacing: 6) {
|
||||
Image(systemName: "pause.fill")
|
||||
.font(.system(size: 10))
|
||||
Text(running ? "Paused: finishes its current step, then holds until you resume" : "Paused: no turn starts until you resume")
|
||||
.font(Fonts.font(13))
|
||||
}
|
||||
.foregroundStyle(Palette.muted)
|
||||
.padding(.horizontal, 8)
|
||||
.padding(.vertical, 4)
|
||||
.background(Palette.surface, in: RoundedRectangle(cornerRadius: 6))
|
||||
.overlay(RoundedRectangle(cornerRadius: 6).stroke(Palette.border))
|
||||
}
|
||||
}
|
||||
|
||||
private struct TranscriptScroll: View {
|
||||
let model: ChatModel
|
||||
@Environment(Store.self) private var store
|
||||
@@ -855,6 +891,10 @@ private struct TranscriptScroll: View {
|
||||
RowView(row: row, model: model, nested: false)
|
||||
.padding(.top, 12)
|
||||
}
|
||||
if model.paused {
|
||||
PausedLine(running: running)
|
||||
.padding(.top, 12)
|
||||
}
|
||||
ForEach(model.builder.pending) { p in
|
||||
PendingView(pending: p, model: model)
|
||||
.padding(.top, 12)
|
||||
|
||||
@@ -527,7 +527,7 @@ struct ComposerView: View {
|
||||
controls(m)
|
||||
.frame(maxWidth: .infinity, alignment: .leading)
|
||||
status
|
||||
actions(live?.id, running: sessionState == .running)
|
||||
actions(live?.id, running: sessionState == .running, paused: live?.paused ?? false)
|
||||
.frame(maxWidth: .infinity, alignment: .trailing)
|
||||
}
|
||||
}
|
||||
@@ -622,7 +622,7 @@ struct ComposerView: View {
|
||||
}
|
||||
}
|
||||
|
||||
private func actions(_ sessionId: String?, running: Bool) -> some View {
|
||||
private func actions(_ sessionId: String?, running: Bool, paused: Bool) -> some View {
|
||||
HStack(spacing: 8) {
|
||||
Button("Interrupt") {
|
||||
if let sessionId {
|
||||
@@ -632,6 +632,19 @@ struct ComposerView: View {
|
||||
.buttonStyle(WebButtonStyle(danger: true))
|
||||
.disabled(!running)
|
||||
.fixedSize()
|
||||
if case .task = chat.kind, !chat.team, !chat.closed {
|
||||
Button {
|
||||
if let sessionId {
|
||||
chat.setPaused(sessionId, !paused, overlays)
|
||||
}
|
||||
} label: {
|
||||
Image(systemName: paused ? "play.fill" : "pause.fill")
|
||||
.frame(width: 14, height: 14)
|
||||
}
|
||||
.buttonStyle(WebButtonStyle())
|
||||
.disabled(sessionId == nil)
|
||||
.help(paused ? "Resume the agent" : "Pause the agent after its current step")
|
||||
}
|
||||
Button(chat.closed ? "Continue" : "Send") {
|
||||
submit(modelState())
|
||||
}
|
||||
|
||||
@@ -858,7 +858,7 @@ final class Store {
|
||||
}
|
||||
notifyTask(self, ev)
|
||||
reloadTask(ev)
|
||||
case "session.created", "session.state", "session.subagents", "session.model":
|
||||
case "session.created", "session.state", "session.subagents", "session.model", "session.paused":
|
||||
if ev.owner != nil {
|
||||
reloadSessions(nil)
|
||||
} else if let taskId = ev.taskId {
|
||||
|
||||
Reference in New Issue
Block a user