A start failure after admission leaves a session running with no turn

This commit is contained in:
Ian Gulliver
2026-10-16 12:36:05 -07:00
parent 9e039712b1
commit acbbd8747e
2 changed files with 30 additions and 11 deletions
+30 -9
View File
@@ -450,14 +450,17 @@ func (m *Manager) launch(ctx context.Context, sess api.AgentSession, task api.Ta
err = m.syncModel(ctx, l, sess.Model)
}
if err != nil {
serr := m.store.SetSessionState(ctx, sess.Id, api.AgentSessionStateIdle, actor, map[string]any{"error": err.Error()})
if serr != nil {
slog.Error("record failed start", "session", sess.Id, "err", serr)
}
m.failStart(ctx, sess.Id, actor, err)
return api.AgentSession{}, err
}
err = m.message(ctx, l, actor, text, images)
imgs, err := m.prepareMessage(ctx, l, actor, text, images)
if err != nil {
m.failStart(ctx, sess.Id, actor, err)
return api.AgentSession{}, err
}
err = l.sess.send(ctx, text, imgs)
if err != nil {
return api.AgentSession{}, err
}
@@ -465,6 +468,16 @@ func (m *Manager) launch(ctx context.Context, sess api.AgentSession, task api.Ta
return m.store.GetSession(ctx, sess.Id)
}
func (m *Manager) failStart(ctx context.Context, sessionID, actor string, err error) {
cctx, cancel := context.WithTimeout(context.WithoutCancel(ctx), 10*time.Second)
defer cancel()
serr := m.store.SetSessionState(cctx, sessionID, api.AgentSessionStateIdle, actor, map[string]any{"error": err.Error()})
if serr != nil {
slog.Error("record failed start", "session", sessionID, "err", serr)
}
}
func (m *Manager) syncModel(ctx context.Context, l *live, model string) error {
if model == l.model {
return nil
@@ -490,11 +503,19 @@ func transition(ctx context.Context, st *store.Store, id string, from, to api.Ag
}
func (m *Manager) message(ctx context.Context, l *live, actor, text string, images []string) error {
imgs, err := m.prepareMessage(ctx, l, actor, text, images)
if err != nil {
return err
}
return l.sess.send(ctx, text, imgs)
}
func (m *Manager) prepareMessage(ctx context.Context, l *live, actor, text string, images []string) ([]image, error) {
imgs := []image{}
for _, id := range images {
b, data, err := m.store.ReadBlob(ctx, id)
if err != nil {
return err
return nil, err
}
imgs = append(imgs, image{mediaType: b.ContentType, data: data})
}
@@ -503,7 +524,7 @@ func (m *Manager) message(ctx context.Context, l *live, actor, text string, imag
if l.implementer() {
head, err := git.Head(l.dir)
if err != nil {
return err
return nil, err
}
payload["head"] = head
}
@@ -519,7 +540,7 @@ func (m *Manager) message(ctx context.Context, l *live, actor, text string, imag
}
err := m.emit(ctx, l, actor, "user.message", payload)
if err != nil {
return err
return nil, err
}
m.mu.Lock()
@@ -532,7 +553,7 @@ func (m *Manager) message(ctx context.Context, l *live, actor, text string, imag
l.lastText = ""
m.mu.Unlock()
return l.sess.send(ctx, text, imgs)
return imgs, nil
}
func (m *Manager) ensureLive(ctx context.Context, sess api.AgentSession, task api.Task) (*live, error) {