Support configuring effort alongside model

This commit is contained in:
Ian Gulliver
2026-10-23 08:40:00 -07:00
parent 6bbae3fffe
commit d6d9dd86d9
40 changed files with 805 additions and 541 deletions
+21 -17
View File
@@ -60,7 +60,7 @@ type Manager struct {
paneMoved map[string]time.Time
moveHolds map[string]showHold
startHolds map[string]showHold
handoffModel map[string]string
handoffModel map[string]modelChoice
mergeTurns map[string]mergeTurn
paused map[string]chan struct{}
@@ -100,6 +100,7 @@ type live struct {
id string
dir string
model string
effort string
gitName string
gitEmail string
vendor api.AgentSessionVendor
@@ -164,7 +165,7 @@ func New(st *store.Store, worktreeRoot, leadRoot, handsRoot, codexHome, antigrav
paneMoved: map[string]time.Time{},
moveHolds: map[string]showHold{},
startHolds: map[string]showHold{},
handoffModel: map[string]string{},
handoffModel: map[string]modelChoice{},
mergeTurns: map[string]mergeTurn{},
paused: map[string]chan struct{}{},
signals: make(chan []api.Event, 1024),
@@ -189,7 +190,7 @@ func (m *Manager) taskFor(ctx context.Context, sess api.AgentSession) (api.Task,
return m.store.GetTask(ctx, sess.TaskId)
}
func (m *Manager) Create(ctx context.Context, task api.Task, creator api.User, prompt, model, sendID, client string, images ...string) (api.AgentSession, error) {
func (m *Manager) Create(ctx context.Context, task api.Task, creator api.User, prompt, model, effort, sendID, client string, images ...string) (api.AgentSession, error) {
unlock := m.lockDelivery("create:" + task.Id)
defer unlock()
@@ -204,12 +205,12 @@ func (m *Manager) Create(ctx context.Context, task api.Task, creator api.User, p
}
if found {
slog.Info("first message to an unused session", "session", unused, "task", task.Id)
return m.Send(ctx, unused, creator.Login, prompt, model, sendID, client, images...)
return m.Send(ctx, unused, creator.Login, prompt, model, effort, sendID, client, images...)
}
return m.create(ctx, task, creator, "", prompt, model, creator.Login, sendID, client, images)
return m.create(ctx, task, creator, "", prompt, model, effort, creator.Login, sendID, client, images)
}
func (m *Manager) create(ctx context.Context, task api.Task, creator api.User, member, prompt, model, actor, sendID, client string, images []string) (api.AgentSession, error) {
func (m *Manager) create(ctx context.Context, task api.Task, creator api.User, member, prompt, model, effort, actor, sendID, client string, images []string) (api.AgentSession, error) {
if creator.GitName == "" || creator.GitEmail == "" {
return api.AgentSession{}, ErrNoGitIdentity
}
@@ -218,14 +219,14 @@ func (m *Manager) create(ctx context.Context, task api.Task, creator api.User, m
return api.AgentSession{}, fmt.Errorf("%w: task %s is %s", ErrConflict, task.Id, task.Status)
}
sess, err := m.newSession(ctx, task, creator, member, model)
sess, err := m.newSession(ctx, task, creator, member, model, effort)
if err != nil {
return api.AgentSession{}, err
}
return m.turn(ctx, sess, task, actor, prompt, sendID, client, images)
}
func (m *Manager) newSession(ctx context.Context, task api.Task, creator api.User, member, model string) (api.AgentSession, error) {
func (m *Manager) newSession(ctx context.Context, task api.Task, creator api.User, member, model, effort string) (api.AgentSession, error) {
if task.Workflow != nil {
return api.AgentSession{}, fmt.Errorf("%w: task %s is a workflow run, which has no agent; its stage tasks have theirs", ErrInvalid, task.Id)
}
@@ -239,12 +240,12 @@ func (m *Manager) newSession(ctx context.Context, task api.Task, creator api.Use
}
}
sess := sessionFor(task, creator, member, model)
sess := sessionFor(task, creator, member, model, effort)
err = m.store.CreateSession(ctx, sess, task.ProjectId)
return sess, err
}
func sessionFor(task api.Task, creator api.User, member, model string) api.AgentSession {
func sessionFor(task api.Task, creator api.User, member, model, effort string) api.AgentSession {
id := ids.New(ids.Session)
vendor := vendorOf(model)
return api.AgentSession{
@@ -252,6 +253,7 @@ func sessionFor(task api.Task, creator api.User, member, model string) api.Agent
TaskId: task.Id,
Vendor: vendor,
Model: model,
Effort: effort,
VendorSessionId: initialVendorSessionID(vendor),
State: api.AgentSessionStateIdle,
Role: api.Implementer,
@@ -261,7 +263,7 @@ func sessionFor(task api.Task, creator api.User, member, model string) api.Agent
}
}
func (m *Manager) Send(ctx context.Context, sessionID, actor, text, model, sendID, client string, images ...string) (api.AgentSession, error) {
func (m *Manager) Send(ctx context.Context, sessionID, actor, text, model, effort, sendID, client string, images ...string) (api.AgentSession, error) {
sess, err := m.store.GetSession(ctx, sessionID)
if err != nil {
return api.AgentSession{}, err
@@ -271,7 +273,7 @@ func (m *Manager) Send(ctx context.Context, sessionID, actor, text, model, sendI
return api.AgentSession{}, fmt.Errorf("%w: session %s is %s", ErrConflict, sess.Id, sess.State)
}
sess, err = m.changeModel(ctx, sess, model, actor)
sess, err = m.changeModel(ctx, sess, model, effort, actor)
if err != nil {
return api.AgentSession{}, err
}
@@ -625,7 +627,7 @@ func (m *Manager) launch(ctx context.Context, sess api.AgentSession, task api.Ta
func (m *Manager) deliver(ctx context.Context, sess api.AgentSession, task api.Task, actor, client, text string, imgs []agentinput.Image, compacting bool) error {
l, err := m.ensureLive(ctx, sess, task)
if err == nil {
err = m.syncModel(ctx, l, sess.Model)
err = m.syncModel(ctx, l, sess.Model, sess.Effort)
}
if err != nil {
m.failStart(ctx, sess.Id, actor, err)
@@ -689,19 +691,20 @@ func (m *Manager) failStart(ctx context.Context, sessionID, actor string, err er
}
}
func (m *Manager) syncModel(ctx context.Context, l *live, model string) error {
if model == l.model {
func (m *Manager) syncModel(ctx context.Context, l *live, model, effort string) error {
if model == l.model && effort == l.effort {
return nil
}
cctx, cancel := context.WithTimeout(ctx, 10*time.Second)
defer cancel()
err := l.sess.setModel(cctx, model)
err := l.sess.setModel(cctx, model, effort)
if err != nil {
return fmt.Errorf("set model %s: %w", model, err)
return fmt.Errorf("set model %s, effort %q: %w", model, effort, err)
}
l.model = model
l.effort = effort
return nil
}
@@ -853,6 +856,7 @@ func (m *Manager) startLive(ctx context.Context, sess api.AgentSession, task api
id: sess.Id,
dir: task.WorktreePath,
model: sess.Model,
effort: sess.Effort,
gitName: creator.GitName,
gitEmail: creator.GitEmail,
vendor: sess.Vendor,