Resume sessions whose background subagents a restart killed
This commit is contained in:
@@ -35,6 +35,8 @@ const agentActor = "agent"
|
||||
|
||||
const restartNotice = "byre restarted while you were mid-turn, so your last turn was cut off. Re-check the working tree (git status and the files you were editing) before continuing where you left off."
|
||||
|
||||
const subagentsLostNotice = "Your agent process ended while background subagents you started were still running, so they were stopped and will never report back. Anything they found is lost; redo that work (run them again or do it yourself) and carry on where you left off."
|
||||
|
||||
var progressSubtypes = map[string]bool{"status": true, "thinking_tokens": true}
|
||||
|
||||
type Manager struct {
|
||||
@@ -456,11 +458,15 @@ func (m *Manager) Recover(ctx context.Context) error {
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
orphaned := []string{}
|
||||
for _, sess := range stale {
|
||||
err = m.store.SetSubagents(ctx, sess.Id, 0, "byre")
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
if sess.State == api.AgentSessionStateIdle {
|
||||
orphaned = append(orphaned, sess.Id)
|
||||
}
|
||||
}
|
||||
|
||||
sessions, err := m.store.SessionsInState(ctx, api.AgentSessionStateRunning)
|
||||
@@ -488,6 +494,10 @@ func (m *Manager) Recover(ctx context.Context) error {
|
||||
}
|
||||
}
|
||||
|
||||
for _, id := range orphaned {
|
||||
m.wakeOrphaned(ctx, id)
|
||||
}
|
||||
|
||||
idle, err := m.store.SessionsInState(ctx, api.AgentSessionStateIdle)
|
||||
if err != nil {
|
||||
return err
|
||||
@@ -508,6 +518,15 @@ func (m *Manager) Recover(ctx context.Context) error {
|
||||
return nil
|
||||
}
|
||||
|
||||
func (m *Manager) wakeOrphaned(ctx context.Context, sessionID string) {
|
||||
_, _, err := m.Message(ctx, sessionID, "byre", Prompt{Text: subagentsLostNotice})
|
||||
if err != nil {
|
||||
slog.Error("wake session whose subagents were stopped", "session", sessionID, "err", err)
|
||||
return
|
||||
}
|
||||
slog.Info("woke session whose subagents were stopped", "session", sessionID)
|
||||
}
|
||||
|
||||
func (m *Manager) failResume(ctx context.Context, sess api.AgentSession, err error) error {
|
||||
slog.Error("resume session", "session", sess.Id, "err", err)
|
||||
if sess.Role == api.Reviewer {
|
||||
@@ -982,7 +1001,8 @@ func (m *Manager) pump(l *live) {
|
||||
quiet := closing || l.stopping
|
||||
m.mu.Unlock()
|
||||
|
||||
if len(l.subagents) > 0 && !closing {
|
||||
orphaned := len(l.subagents) > 0 && !closing
|
||||
if orphaned {
|
||||
err := m.store.SetSubagents(ctx, l.id, 0, "byre")
|
||||
if err != nil {
|
||||
slog.Error("clear exited session's subagents", "session", l.id, "err", err)
|
||||
@@ -1000,6 +1020,10 @@ func (m *Manager) pump(l *live) {
|
||||
return
|
||||
}
|
||||
|
||||
if sess.State == api.AgentSessionStateIdle && orphaned {
|
||||
m.wakeOrphaned(ctx, l.id)
|
||||
return
|
||||
}
|
||||
if sess.State != api.AgentSessionStateRunning {
|
||||
return
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user