Support configuring effort alongside model

This commit is contained in:
Ian Gulliver committed 2026-10-23 08:40:00 -07:00
1 parent 6bbae3fffe
commit d6d9dd86d9
40 files changed
+805 -541

No files matched your search

+15 -11
View File
@@ -25,7 +25,7 @@ const leadHandoffPrompt = `Write a handoff for a fresh lead agent that will take
`questions you have surfaced or answered and why; what you last pointed the human's attention at; and anything you promised to do or check. ` +
`Be complete: the next agent sees nothing else. Your final message is the handoff, and nothing else.`
func (m *Manager) Compact(ctx context.Context, sessionID, model string) (api.AgentSession, error) {
func (m *Manager) Compact(ctx context.Context, sessionID, model, effort string) (api.AgentSession, error) {
sess, err := m.store.GetSession(ctx, sessionID)
if err != nil {
return api.AgentSession{}, err
@@ -44,29 +44,33 @@ func (m *Manager) Compact(ctx context.Context, sessionID, model string) (api.Age
if err != nil {
return api.AgentSession{}, err
}
return m.launchCompaction(ctx, sess, task, model)
return m.launchCompaction(ctx, sess, task, model, effort)
}
func (m *Manager) launchCompaction(ctx context.Context, sess api.AgentSession, task api.Task, model string) (api.AgentSession, error) {
type modelChoice struct {
model, effort string
}
func (m *Manager) launchCompaction(ctx context.Context, sess api.AgentSession, task api.Task, model, effort string) (api.AgentSession, error) {
prompt := handoffPrompt
if sess.Owner != "" {
prompt = leadHandoffPrompt
}
m.mu.Lock()
m.handoffModel[sess.Id] = model
m.handoffModel[sess.Id] = modelChoice{model, effort}
m.mu.Unlock()
return m.launch(ctx, sess, task, "byre", prompt, "", "", nil)
}
func (m *Manager) continuationModel(sess api.AgentSession) string {
func (m *Manager) continuationModel(sess api.AgentSession) modelChoice {
m.mu.Lock()
model := m.handoffModel[sess.Id]
c := m.handoffModel[sess.Id]
delete(m.handoffModel, sess.Id)
m.mu.Unlock()
if model == "" {
return sess.Model
if c.model == "" {
return modelChoice{sess.Model, sess.Effort}
}
return model
return c
}
func isHandoffPrompt(actor, text string) bool {
@@ -107,7 +111,7 @@ func (m *Manager) handoff(ctx context.Context, sessionID, handoff string) error
if err != nil {
return err
}
_, err = m.createLead(ctx, creator, leadHandoffPreamble+handoff, model, "byre", "", "", nil)
_, err = m.createLead(ctx, creator, leadHandoffPreamble+handoff, model.model, model.effort, "byre", "", "", nil)
return err
}
@@ -118,7 +122,7 @@ func (m *Manager) handoff(ctx context.Context, sessionID, handoff string) error
if err != nil {
return err
}
next := sessionFor(task, creator, sess.Member, model)
next := sessionFor(task, creator, sess.Member, model.model, model.effort)
next.State = api.AgentSessionStateRunning
err = m.store.ReplaceSession(ctx, sess.Id, next, task.ProjectId, "byre")
if errors.Is(err, store.ErrStateChanged) {
+4 -4
View File
@@ -81,7 +81,7 @@ func (m *Manager) forkTool(l *live) mcp.Tool {
if err != nil {
return "", err
}
_, _, err = m.Message(ctx, sessionID, agentActor, args.Prompt, "", "", "")
_, _, err = m.Message(ctx, sessionID, agentActor, args.Prompt, "", "", "", "")
if err != nil {
return "", fmt.Errorf("task %s forked, but its agent did not start: %w", t.Id, err)
}
@@ -192,7 +192,7 @@ func (m *Manager) fork(ctx context.Context, src api.Task, project api.Project, n
}, snap.CommitSha, creator, srcSess, at)
}
func (m *Manager) Continue(ctx context.Context, srcSess api.AgentSession, src api.Task, project api.Project, creator api.User, text, model, sendID, client string, images ...string) (api.Task, error) {
func (m *Manager) Continue(ctx context.Context, srcSess api.AgentSession, src api.Task, project api.Project, creator api.User, text, model, effort, sendID, client string, images ...string) (api.Task, error) {
if creator.GitName == "" || creator.GitEmail == "" {
return api.Task{}, ErrNoGitIdentity
}
@@ -235,7 +235,7 @@ func (m *Manager) Continue(ctx context.Context, srcSess api.AgentSession, src ap
if err != nil {
return api.Task{}, err
}
_, _, err = m.Message(ctx, sessionID, creator.Login, text, model, sendID, client, images...)
_, _, err = m.Message(ctx, sessionID, creator.Login, text, model, effort, sendID, client, images...)
if err != nil {
return api.Task{}, fmt.Errorf("task %s created, but its agent did not start: %w", t.Id, err)
}
@@ -248,7 +248,7 @@ func (m *Manager) forkSession(ctx context.Context, project api.Project, task api
return api.Task{}, "", err
}
sess := sessionFor(t, creator, "", srcSess.Model)
sess := sessionFor(t, creator, "", srcSess.Model, srcSess.Effort)
sess.ForkedFrom = &srcSess.VendorSessionId
sess.ForkedAt = &at
err = m.store.CreateSession(ctx, sess, t.ProjectId)
+4 -3
View File
@@ -2,7 +2,7 @@
A workflow's definition is an object: an optional `description`, optional `auto_merge` and `auto_discard` booleans, then `steps`, which run in order. With `auto_merge`, when a stage task of a run calls `ready_for_merge`, byre merges it right away as the creator of the run, pressing the button the agent picked (`complete` or `continue`); with `auto_discard`, byre discards a stage task that calls `suggest_discard`. Without them the human decides, as for any task. The workflow's name is not in it. `save_workflow` takes it as its `definition` argument and `read_workflow` returns it, both as JSON. Unknown fields are refused.
Any workflow can run on a brief, each stage as its own task, and any workflow whose stages are single agents can be a project's review workflow (set with `set_review_workflow`), which reviews its tasks' snapshots: each stage is then one reviewer agent on its `model`, given the task's change and its stage's `prompt` (what to look for), and a stage after others also gets their reviews. A project can't review with a workflow that has a team stage (`agents`).
Any workflow can run on a brief, each stage as its own task, and any workflow whose stages are single agents can be a project's review workflow (set with `set_review_workflow`), which reviews its tasks' snapshots: each stage is then one reviewer agent on its `model` and `effort`, given the task's change and its stage's `prompt` (what to look for), and a stage after others also gets their reviews. A project can't review with a workflow that has a team stage (`agents`).
Each step is exactly one of:
@@ -18,8 +18,9 @@ A stage gets the outputs of the stages that end the step before it: the last sta
| Stage field | Meaning |
|---|---|
| `model` | Also picks the vendor: `gpt-*` models run on Codex, `gemini-*` models on Antigravity, every other model on Claude Code. |
| `effort` | Optional: `low`, `medium`, `high`, `xhigh` or `max` (Codex models take `low` to `xhigh`). Without it the agent runs at the vendor's default. |
| `prompt` | The stage agent's instructions. |
| `agents` | In place of `model`: a list of at least two, each with `name`, `model` and `prompt`, that runs the stage as a team. They work in the stage's one task and worktree and talk through a shared board; each gets the stage's `prompt` and then its own, and the first agent finishes the stage. |
| `agents` | In place of `model` and `effort`: a list of at least two, each with `name`, `model`, an optional `effort` and `prompt`, that runs the stage as a team. They work in the stage's one task and worktree and talk through a shared board; each gets the stage's `prompt` and then its own, and the first agent finishes the stage. |
Where a stage's task branches from follows from the shape. A stage after exactly one stage starts from the commit that stage finished at. A stage after a `parallel` starts from the default branch and is told the branches it can merge. A stage with nothing before it starts where the workflow was started. A run on a brief has a task of its own, with no agent, worktree or branch, and its stage tasks are that task's subtasks; it closes once they all have. A workflow is finished once every stage has finished; when it ends with a `parallel`, each branch's last stage keeps its task to merge, and the run's other stage tasks are discarded. A review is delivered to the task's agent, every stage's findings in one message, once every stage has reviewed. An `order`, `parallel` or `random` can't be empty.
@@ -27,7 +28,7 @@ Where a stage's task branches from follows from the shape. A stage after exactly
{
"description": "Build a change, review and test it in parallel, now and then auditing security in depth, then fix what they found.",
"steps": [
{"stage": "Build", "model": "claude-opus-5-5", "prompt": "Implement the brief."},
{"stage": "Build", "model": "claude-opus-5-5", "effort": "high", "prompt": "Implement the brief."},
{"parallel": [
{"stage": "Review", "model": "gpt-6.1-sol", "prompt": "Review the Build stage's work and list the problems."},
{"stage": "Test", "model": "gemini-4-argon-high", "prompt": "Exercise the change and report what fails."},
+8 -7
View File
@@ -100,7 +100,7 @@ func (m *Manager) activeLead(ctx context.Context, owner string) (api.AgentSessio
return api.AgentSession{}, false, nil
}
func (m *Manager) createLead(ctx context.Context, owner api.User, prompt, model, actor, sendID, client string, images []string) (api.AgentSession, error) {
func (m *Manager) createLead(ctx context.Context, owner api.User, prompt, model, effort, actor, sendID, client string, images []string) (api.AgentSession, error) {
_, found, err := m.activeLead(ctx, owner.Login)
if err != nil {
return api.AgentSession{}, err
@@ -116,6 +116,7 @@ func (m *Manager) createLead(ctx context.Context, owner api.User, prompt, model,
Owner: owner.Login,
Vendor: vendor,
Model: model,
Effort: effort,
VendorSessionId: initialVendorSessionID(vendor),
State: api.AgentSessionStateIdle,
Role: api.Lead,
@@ -129,7 +130,7 @@ func (m *Manager) createLead(ctx context.Context, owner api.User, prompt, model,
return m.turn(ctx, sess, api.Task{}, actor, prompt, sendID, client, images)
}
func (m *Manager) MessageLead(ctx context.Context, user api.User, text, model, sendID, client string, images []string) (api.AgentSession, error) {
func (m *Manager) MessageLead(ctx context.Context, user api.User, text, model, effort, sendID, client string, images []string) (api.AgentSession, error) {
m.setStartedTodo(user.Login, false)
m.leadMu.Lock()
@@ -150,17 +151,17 @@ func (m *Manager) MessageLead(ctx context.Context, user api.User, text, model, s
return prior, nil
}
if !found {
return m.createLead(ctx, user, text, model, user.Login, sendID, client, images)
return m.createLead(ctx, user, text, model, effort, user.Login, sendID, client, images)
}
if sess.State == api.AgentSessionStateIdle {
s, err := m.Send(ctx, sess.Id, user.Login, text, model, sendID, client, images...)
s, err := m.Send(ctx, sess.Id, user.Login, text, model, effort, sendID, client, images...)
if !errors.Is(err, ErrConflict) {
return s, err
}
}
sess, err = m.changeModel(ctx, sess, model, user.Login)
sess, err = m.changeModel(ctx, sess, model, effort, user.Login)
if err != nil {
return api.AgentSession{}, err
}
@@ -217,7 +218,7 @@ func (m *Manager) tryDeliverLead(ctx context.Context, owner string) error {
}
text += "\n\n" + state
}
_, err = m.Send(ctx, sess.Id, actor, text, "", sendID, client, images...)
_, err = m.Send(ctx, sess.Id, actor, text, "", "", sendID, client, images...)
if errors.Is(err, ErrConflict) {
return nil
}
@@ -346,7 +347,7 @@ func (m *Manager) compactLead(sessionID string) {
ctx := context.Background()
sess, err := m.store.GetSession(ctx, sessionID)
if err == nil {
_, err = m.launchCompaction(ctx, sess, api.Task{}, "")
_, err = m.launchCompaction(ctx, sess, api.Task{}, "", "")
}
if err == nil {
return
+26 -13
View File
@@ -158,13 +158,15 @@ func (m *Manager) leadTools(l *live) []mcp.Tool {
`{"type": "object", "properties": {
"task_id": {"type": "string"},
"text": {"type": "string"},
"model": {"type": "string", "description": "Switch the agent to this model from this turn on."}
"model": {"type": "string", "description": "Switch the agent to this model from this turn on."},
`+effortProperty+`
}, "required": ["task_id", "text"]}`,
func(ctx context.Context, user api.User, raw json.RawMessage) (string, error) {
args := struct {
TaskID string `json:"task_id"`
Text string `json:"text"`
Model string `json:"model"`
Effort string `json:"effort"`
}{}
err := json.Unmarshal(raw, &args)
if err != nil {
@@ -196,13 +198,13 @@ func (m *Manager) leadTools(l *live) []mcp.Tool {
return fmt.Sprintf("Posted to %s's board; every agent of its team gets it.", task.Id), nil
}
if !found {
_, err = m.create(ctx, task, user, "", args.Text, args.Model, leadActor(user.Login), "", "", nil)
_, err = m.create(ctx, task, user, "", args.Text, args.Model, args.Effort, leadActor(user.Login), "", "", nil)
if err != nil {
return "", err
}
return fmt.Sprintf("Started an agent on %s with your message.", task.Id), nil
}
_, queued, err := m.Message(ctx, sess.Id, leadActor(user.Login), args.Text, args.Model, "", "")
_, queued, err := m.Message(ctx, sess.Id, leadActor(user.Login), args.Text, args.Model, args.Effort, "", "")
if err != nil {
return "", err
}
@@ -226,10 +228,12 @@ func (m *Manager) leadTools(l *live) []mcp.Tool {
"prompt": {"type": "string"},
"from_task_id": {"type": "string"},
"model": {"type": "string"},
`+effortProperty+`,
"workflow": {"type": "string", "description": "The name of a workflow for the task to freeze a copy of and run."},
"agents": {"type": "array", "description": "A team of at least two agents; the first is the team's first agent, which byre's own requests (merges, discards, review findings) go to.", "items": {"type": "object", "properties": {
"name": {"type": "string", "description": "One line, unique in the team, such as a role: architect, skeptic."},
"model": {"type": "string"},
"effort": {"type": "string", "description": "low, medium, high, xhigh or max (Codex models take low to xhigh); empty or absent means the vendor's default."},
"prompt": {"type": "string", "description": "This agent's own instructions: its role in the team."}
}, "required": ["name", "model", "prompt"]}}
}, "required": ["project_id", "title"]}`,
@@ -240,6 +244,7 @@ func (m *Manager) leadTools(l *live) []mcp.Tool {
Prompt string `json:"prompt"`
FromTaskID string `json:"from_task_id"`
Model string `json:"model"`
Effort string `json:"effort"`
Workflow string `json:"workflow"`
Agents []api.TeamMember `json:"agents"`
}{}
@@ -301,7 +306,8 @@ func (m *Manager) leadTools(l *live) []mcp.Tool {
}
return fmt.Sprintf("Task %s %q created from %s and its team of %d agents started.", task.Id, task.Title, task.BaseRef, len(args.Agents)), nil
}
_, err = m.create(ctx, task, user, "", args.Prompt, m.modelOr(args.Model, l), leadActor(user.Login), "", "", nil)
model, effort := m.modelOr(args.Model, args.Effort, l)
_, err = m.create(ctx, task, user, "", args.Prompt, model, effort, leadActor(user.Login), "", "", nil)
if err != nil {
return "", fmt.Errorf("task %s created, but its agent did not start: %w", task.Id, err)
}
@@ -336,6 +342,7 @@ func (m *Manager) leadTools(l *live) []mcp.Tool {
"project_id": {"type": "string"},
"title": {"type": "string"},
"model": {"type": "string"},
`+effortProperty+`,
"workflow": {"type": "string", "description": "The name of a workflow for the task to freeze a copy of and run."}
}, "required": ["project_id", "title"]}`,
func(ctx context.Context, user api.User, raw json.RawMessage) (string, error) {
@@ -343,6 +350,7 @@ func (m *Manager) leadTools(l *live) []mcp.Tool {
ProjectID string `json:"project_id"`
Title string `json:"title"`
Model string `json:"model"`
Effort string `json:"effort"`
Workflow string `json:"workflow"`
}{}
err := json.Unmarshal(raw, &args)
@@ -356,7 +364,8 @@ func (m *Manager) leadTools(l *live) []mcp.Tool {
if err != nil {
return "", err
}
tasks, err := m.StartTodo(ctx, project, user, args.Title, m.modelOr(args.Model, l), leadActor(user.Login), args.Workflow, false)
model, effort := m.modelOr(args.Model, args.Effort, l)
tasks, err := m.StartTodo(ctx, project, user, args.Title, model, effort, leadActor(user.Login), args.Workflow, false)
if err != nil {
return "", err
}
@@ -379,11 +388,13 @@ func (m *Manager) leadTools(l *live) []mcp.Tool {
tool("compact_task", "Have a task's idle agent write a handoff and continue in a fresh session."+stoppedRefusal,
`{"type": "object", "properties": {
"task_id": {"type": "string"},
"model": {"type": "string", "description": "Start the fresh session on this model, on either vendor; the current agent still writes the handoff. Defaults to the current model."}
"model": {"type": "string", "description": "Start the fresh session on this model, on either vendor; the current agent still writes the handoff. Defaults to the current model and effort."},
`+effortProperty+`
}, "required": ["task_id"]}`,
func(ctx context.Context, user api.User, raw json.RawMessage) (string, error) {
args := struct {
Model string `json:"model"`
Model string `json:"model"`
Effort string `json:"effort"`
}{}
err := json.Unmarshal(raw, &args)
if err != nil {
@@ -397,7 +408,7 @@ func (m *Manager) leadTools(l *live) []mcp.Tool {
if err != nil {
return "", err
}
_, err = m.Compact(ctx, sess.Id, args.Model)
_, err = m.Compact(ctx, sess.Id, args.Model, args.Effort)
if err != nil {
return "", err
}
@@ -778,11 +789,13 @@ func (m *Manager) setStartedTodo(login string, started bool) {
})
}
func (m *Manager) modelOr(model string, l *live) string {
const effortProperty = `"effort": {"type": "string", "description": "The agent's effort, set together with model: low, medium, high, xhigh or max (Codex models take low to xhigh); empty means the vendor's default. Ignored without model."}`
func (m *Manager) modelOr(model, effort string, l *live) (string, string) {
if model != "" {
return model
return model, effort
}
return l.model
return l.model, l.effort
}
func (m *Manager) activeTask(ctx context.Context, taskID string) (api.Task, api.Project, error) {
@@ -906,11 +919,11 @@ func (m *Manager) listTasksText(ctx context.Context) (string, error) {
case len(team) > 0:
members := []string{}
for _, s := range team {
members = append(members, fmt.Sprintf("%q %s on %s", s.Member, s.State, s.Model))
members = append(members, fmt.Sprintf("%q %s on %s", s.Member, s.State, modelLabel(s)))
}
agent += "; team: " + strings.Join(members, ", ")
case found && sess.Model != "":
agent += "; agent on " + sess.Model
agent += "; agent on " + modelLabel(sess)
}
open := 0
for _, i := range items {
+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,
+4 -4
View File
@@ -62,9 +62,9 @@ func (m *Manager) sendMergeIn(ctx context.Context, task api.Task, user api.User,
return api.AgentSession{}, err
}
if found {
return m.Send(ctx, sess.Id, "byre", prompt, "", "", "")
return m.Send(ctx, sess.Id, "byre", prompt, "", "", "", "")
}
return m.create(ctx, task, user, sess.Member, prompt, "", "byre", "", "", nil)
return m.create(ctx, task, user, sess.Member, prompt, "", "", "byre", "", "", nil)
}
func (m *Manager) Merge(ctx context.Context, task api.Task, project api.Project, user api.User, title string) (api.Task, error) {
@@ -161,7 +161,7 @@ func (m *Manager) leadSession(ctx context.Context, task api.Task, user api.User)
if err != nil || found {
return sess, err
}
return m.newSession(ctx, task, user, sess.Member, "")
return m.newSession(ctx, task, user, sess.Member, "", "")
}
func (m *Manager) mergeSession(ctx context.Context, task api.Task, user api.User) (api.AgentSession, error) {
@@ -192,7 +192,7 @@ func (m *Manager) deliverMerge(ctx context.Context, sess api.AgentSession, task
if err != nil {
return err
}
err = m.syncModel(ctx, l, sess.Model)
err = m.syncModel(ctx, l, sess.Model, sess.Effort)
if err != nil {
return err
}
+28 -9
View File
@@ -22,7 +22,7 @@ import (
type agentProcess interface {
send(ctx context.Context, text string, images []agentinput.Image) error
interrupt(ctx context.Context) error
setModel(ctx context.Context, model string) error
setModel(ctx context.Context, model, effort string) error
kill()
pid() int
lastLine() time.Time
@@ -41,6 +41,13 @@ func vendorOf(model string) api.AgentSessionVendor {
return api.Claude
}
func modelLabel(sess api.AgentSession) string {
if sess.Effort == "" {
return sess.Model
}
return sess.Model + " at " + sess.Effort + " effort"
}
func initialVendorSessionID(vendor api.AgentSessionVendor) string {
if vendor != api.Claude {
return ""
@@ -52,18 +59,19 @@ func initialVendorSessionID(vendor api.AgentSessionVendor) string {
return fmt.Sprintf("%x-%x-%x-%x-%x", b[0:4], b[4:6], b[6:8], b[8:10], b[10:])
}
func (m *Manager) changeModel(ctx context.Context, sess api.AgentSession, model, actor string) (api.AgentSession, error) {
if model == "" || model == sess.Model {
func (m *Manager) changeModel(ctx context.Context, sess api.AgentSession, model, effort, actor string) (api.AgentSession, error) {
if model == "" || (model == sess.Model && effort == sess.Effort) {
return sess, nil
}
if vendorOf(model) != sess.Vendor {
return api.AgentSession{}, fmt.Errorf("%w: session %s is %s; %s is a %s model", ErrInvalid, sess.Id, sess.Vendor, model, vendorOf(model))
}
err := m.store.SetSessionModel(ctx, sess.Id, model, actor)
err := m.store.SetSessionModel(ctx, sess.Id, model, effort, actor)
if err != nil {
return api.AgentSession{}, err
}
sess.Model = model
sess.Effort = effort
return sess, nil
}
@@ -89,6 +97,7 @@ func (m *Manager) startClaude(ctx context.Context, sess api.AgentSession, l *liv
opts := claude.Options{
Cwd: l.dir,
Model: sess.Model,
Effort: sess.Effort,
Env: env,
Guidance: g + l.notes,
MCPServers: servers,
@@ -127,8 +136,16 @@ func (p claudeProcess) interrupt(ctx context.Context) error {
return p.s.Interrupt(ctx)
}
func (p claudeProcess) setModel(ctx context.Context, model string) error {
func (p claudeProcess) setModel(ctx context.Context, model, effort string) error {
_, err := p.s.Control(ctx, map[string]any{"subtype": "set_model", "model": model})
if err != nil {
return err
}
level := any(effort)
if effort == "" {
level = nil
}
_, err = p.s.Control(ctx, map[string]any{"subtype": "apply_flag_settings", "settings": map[string]any{"effortLevel": level}})
return err
}
@@ -164,6 +181,7 @@ func (m *Manager) startCodex(ctx context.Context, sess api.AgentSession, l *live
opts := codex.Options{
Cwd: l.dir,
Model: sess.Model,
Effort: sess.Effort,
Env: append(env, "CODEX_HOME="+m.codexHome),
Guidance: g + l.notes,
Reminder: g,
@@ -205,8 +223,8 @@ func (p codexProcess) interrupt(ctx context.Context) error {
return p.s.Interrupt(ctx)
}
func (p codexProcess) setModel(ctx context.Context, model string) error {
p.s.SetModel(model)
func (p codexProcess) setModel(ctx context.Context, model, effort string) error {
p.s.SetModel(model, effort)
return nil
}
@@ -238,6 +256,7 @@ func (m *Manager) startAntigravity(ctx context.Context, sess api.AgentSession, l
Dir: filepath.Join(m.antigravityRoot, sess.Id),
Cwd: l.dir,
Model: sess.Model,
Effort: sess.Effort,
Resume: sess.VendorSessionId,
Env: env,
Guidance: g,
@@ -271,8 +290,8 @@ func (p antigravityProcess) interrupt(ctx context.Context) error {
return p.s.Interrupt()
}
func (p antigravityProcess) setModel(ctx context.Context, model string) error {
return p.s.SetModel(model)
func (p antigravityProcess) setModel(ctx context.Context, model, effort string) error {
return p.s.SetModel(model, effort)
}
func (p antigravityProcess) kill() { p.s.Kill() }
+4 -4
View File
@@ -39,7 +39,7 @@ func (m *Manager) lockDelivery(sessionID string) func() {
}
}
func (m *Manager) Message(ctx context.Context, sessionID, actor, text, model, sendID, client string, images ...string) (api.AgentSession, bool, error) {
func (m *Manager) Message(ctx context.Context, sessionID, actor, text, model, effort, sendID, client string, images ...string) (api.AgentSession, bool, error) {
unlock := m.lockDelivery(sessionID)
defer unlock()
@@ -64,11 +64,11 @@ func (m *Manager) Message(ctx context.Context, sessionID, actor, text, model, se
}
held := sess.State == api.AgentSessionStateIdle && sess.Role == api.Implementer && (automatedActor(actor) && m.interrupted(sess.Id) || landing || m.isPaused(sess.Id))
if !held && (sess.State != api.AgentSessionStateRunning || sess.Role != api.Implementer) {
sess, err = m.Send(ctx, sessionID, actor, text, model, sendID, client, images...)
sess, err = m.Send(ctx, sessionID, actor, text, model, effort, sendID, client, images...)
return sess, false, err
}
sess, err = m.changeModel(ctx, sess, model, actor)
sess, err = m.changeModel(ctx, sess, model, effort, actor)
if err != nil {
return api.AgentSession{}, false, err
}
@@ -157,7 +157,7 @@ func (m *Manager) deliverQueued(ctx context.Context, sess api.AgentSession) (boo
}
in := inputs[0]
_, err = m.Send(ctx, sess.Id, in.Actor, in.Text, "", in.SendID, in.Client, in.Images...)
_, err = m.Send(ctx, sess.Id, in.Actor, in.Text, "", "", in.SendID, in.Client, in.Images...)
if errors.Is(err, ErrConflict) {
slog.Info("queued message held: session changed state", "session", sess.Id, "task", task.Id, "err", err)
return true, nil
+1 -1
View File
@@ -212,7 +212,7 @@ func (m *Manager) sendReadyPrompt(ctx context.Context, p store.ReadyPrompt) erro
unlock := m.lockDelivery(p.SessionID)
defer unlock()
_, err := m.Send(ctx, p.SessionID, "byre", prompt, "", "", "")
_, err := m.Send(ctx, p.SessionID, "byre", prompt, "", "", "", "")
if err != nil {
return err
}
+4 -2
View File
@@ -174,7 +174,8 @@ func (m *Manager) startReviewers(ctx context.Context, task api.Task, project api
failed := []api.Review{}
prompts := map[string]string{}
for _, s := range stages {
model := workflow.Get(s.Definition, s.Stage).Model
stage := workflow.Get(s.Definition, s.Stage)
model := stage.Model
vendor := vendorOf(model)
r := api.Review{Id: ids.New(ids.Review), TaskId: task.Id, SnapshotN: snap.N, Stage: s.Stage, Vendor: string(vendor), Model: model, CreatedAt: now}
prompt, err := m.reviewPrompt(ctx, task, project, snap, s.Definition, s.Stage, s.Inputs)
@@ -192,6 +193,7 @@ func (m *Manager) startReviewers(ctx context.Context, task api.Task, project api
TaskId: task.Id,
Vendor: vendor,
Model: model,
Effort: stage.Effort,
VendorSessionId: initialVendorSessionID(vendor),
State: api.AgentSessionStateRunning,
Role: api.Reviewer,
@@ -381,7 +383,7 @@ func (m *Manager) deliverFindings(ctx context.Context, ref store.SnapshotRef, re
slog.Info("review findings not delivered, task has no live agent", "task", ref.TaskID, "snapshot", ref.N)
return
}
_, _, err = m.Message(ctx, s.Id, "byre", text, "", "", "")
_, _, err = m.Message(ctx, s.Id, "byre", text, "", "", "", "")
if err != nil {
slog.Error("deliver review findings", "task", ref.TaskID, "snapshot", ref.N, "session", s.Id, "err", err)
return
+8 -5
View File
@@ -46,13 +46,15 @@ func (m *Manager) subtaskTools(l *live) []mcp.Tool {
`{"type": "object", "properties": {
"title": {"type": "string", "description": "Short task title, shown in the task list."},
"prompt": {"type": "string", "description": "The new agent's first message: a complete, self-contained brief."},
"model": {"type": "string", "description": "Model for the new agent: gpt-* models run on Codex, gemini-* models on Antigravity, every other model on Claude Code. Defaults to this session's model."}
"model": {"type": "string", "description": "Model for the new agent: gpt-* models run on Codex, gemini-* models on Antigravity, every other model on Claude Code. Defaults to this session's model and effort."},
`+effortProperty+`
}, "required": ["title", "prompt"]}`,
func(ctx context.Context, creator api.User, raw json.RawMessage) (string, error) {
args := struct {
Title string `json:"title"`
Prompt string `json:"prompt"`
Model string `json:"model"`
Effort string `json:"effort"`
}{}
err := json.Unmarshal(raw, &args)
if err != nil {
@@ -73,7 +75,8 @@ func (m *Manager) subtaskTools(l *live) []mcp.Tool {
if err != nil {
return "", err
}
_, err = m.create(ctx, task, creator, "", args.Prompt, m.modelOr(args.Model, l), agentActor, "", "", nil)
model, effort := m.modelOr(args.Model, args.Effort, l)
_, err = m.create(ctx, task, creator, "", args.Prompt, model, effort, agentActor, "", "", nil)
if err != nil {
return "", fmt.Errorf("subtask %s created, but its agent did not start: %w", task.Id, err)
}
@@ -99,7 +102,7 @@ func (m *Manager) subtaskTools(l *live) []mcp.Tool {
return "", err
}
if found {
agent = fmt.Sprintf("agent %s on %s", sess.State, sess.Model)
agent = fmt.Sprintf("agent %s on %s", sess.State, modelLabel(sess))
}
fmt.Fprintf(b, "- %s %q: %s; branch %s; worktree %s", t.Id, t.Title, agent, t.Branch, t.WorktreePath)
if t.MergingIntoParent {
@@ -294,10 +297,10 @@ func (m *Manager) messageTask(ctx context.Context, task api.Task, user api.User,
return err
}
if !found {
_, err = m.create(ctx, task, user, sess.Member, text, "", actor, "", "", nil)
_, err = m.create(ctx, task, user, sess.Member, text, "", "", actor, "", "", nil)
return err
}
_, _, err = m.Message(ctx, sess.Id, actor, text, "", "", "")
_, _, err = m.Message(ctx, sess.Id, actor, text, "", "", "", "")
return err
}
+1 -1
View File
@@ -183,7 +183,7 @@ func (m *Manager) beginDiscard(ctx context.Context, taskID string) error {
if err != nil {
return err
}
sess, err = m.newSession(ctx, task, creator, sess.Member, "")
sess, err = m.newSession(ctx, task, creator, sess.Member, "", "")
if err != nil {
return err
}
+4 -4
View File
@@ -19,7 +19,7 @@ func (m *Manager) CreateTask(ctx context.Context, project api.Project, title, cr
return m.createTask(ctx, project, api.Task{Title: title, CreatedBy: createdBy}, base, actor)
}
func (m *Manager) StartTask(ctx context.Context, project api.Project, creator api.User, title, prompt, model, client string, images []string) (api.Task, error) {
func (m *Manager) StartTask(ctx context.Context, project api.Project, creator api.User, title, prompt, model, effort, client string, images []string) (api.Task, error) {
if creator.GitName == "" || creator.GitEmail == "" {
return api.Task{}, ErrNoGitIdentity
}
@@ -27,7 +27,7 @@ func (m *Manager) StartTask(ctx context.Context, project api.Project, creator ap
if err != nil {
return api.Task{}, err
}
sess, err := m.newSession(ctx, task, creator, "", model)
sess, err := m.newSession(ctx, task, creator, "", model, effort)
if err == nil {
err = m.startRunning(ctx, sess, creator.Login)
}
@@ -48,7 +48,7 @@ func (m *Manager) StartTask(ctx context.Context, project api.Project, creator ap
return task, nil
}
func (m *Manager) StartTodo(ctx context.Context, project api.Project, creator api.User, title, model, actor, workflowName string, discuss bool) ([]api.Task, error) {
func (m *Manager) StartTodo(ctx context.Context, project api.Project, creator api.User, title, model, effort, actor, workflowName string, discuss bool) ([]api.Task, error) {
if creator.GitName == "" || creator.GitEmail == "" {
return nil, ErrNoGitIdentity
}
@@ -85,7 +85,7 @@ func (m *Manager) StartTodo(ctx context.Context, project api.Project, creator ap
if err != nil {
return nil, err
}
_, err = m.create(ctx, task, creator, "", todoPrompt(item, discuss), model, actor, "", "", nil)
_, err = m.create(ctx, task, creator, "", todoPrompt(item, discuss), model, effort, actor, "", "", nil)
if err != nil {
return nil, fmt.Errorf("task %s created, but its agent did not start: %w", task.Id, err)
}
+3 -3
View File
@@ -87,7 +87,7 @@ func (m *Manager) startTeam(ctx context.Context, task api.Task, creator api.User
}
sessions := []api.AgentSession{}
for _, mem := range members {
sess, err := m.newSession(ctx, task, creator, mem.Name, mem.Model)
sess, err := m.newSession(ctx, task, creator, mem.Name, mem.Model, mem.Effort)
if err != nil {
return err
}
@@ -114,7 +114,7 @@ func teamGuidance(sessions []api.AgentSession, member string, stage bool) string
team := teamSessions(sessions)
names := []string{}
for _, s := range team {
names = append(names, fmt.Sprintf("%q (%s)", s.Member, s.Model))
names = append(names, fmt.Sprintf("%q (%s)", s.Member, modelLabel(s)))
}
lead := teamLead(sessions)
g := fmt.Sprintf("\n- This task is worked by a team of agents in this one worktree: %s. You are %q. "+
@@ -189,7 +189,7 @@ func (m *Manager) post(ctx context.Context, task api.Task, from poster, text str
func (m *Manager) deliverPost(ctx context.Context, task api.Task, s api.AgentSession, msg string) {
started, err := m.store.SessionStarted(ctx, s.Id)
if err == nil && started {
_, _, err = m.Message(ctx, s.Id, boardActor, msg, "", "", "")
_, _, err = m.Message(ctx, s.Id, boardActor, msg, "", "", "", "")
}
if err == nil && started {
return
+1 -1
View File
@@ -199,7 +199,7 @@ func (m *Manager) terminalTypeTool(l *live) mcp.Tool {
func (m *Manager) wakeOnPrompt(l *live) func(string, []byte) {
return func(exit string, out []byte) {
text := fmt.Sprintf("The terminal you last typed into is back at its prompt: the command there finished with exit status %s (130 means it was canceled with Ctrl-C). The terminal's output since your last terminal_type reply:\n\n%s", exit, terminal.Text(out))
_, _, err := m.Message(context.Background(), l.id, "byre", text, "", "", "")
_, _, err := m.Message(context.Background(), l.id, "byre", text, "", "", "", "")
if err != nil {
slog.Error("wake agent on terminal prompt", "session", l.id, "task", l.taskID, "err", err)
return
+3 -1
View File
@@ -338,7 +338,7 @@ func (m *Manager) beginStage(ctx context.Context, task api.Task, project api.Pro
s := workflow.Get(frozen.Definition, stage)
message := stageMessage(frozen, stage, parents, project.DefaultBranch)
if s.Agents == nil {
return m.create(ctx, task, creator, "", message, s.Model, "byre", "", "", nil)
return m.create(ctx, task, creator, "", message, s.Model, s.Effort, "byre", "", "", nil)
}
err = m.startTeam(ctx, task, creator, message, *s.Agents, "byre")
if err != nil {
@@ -777,6 +777,7 @@ const workflowSchemaDefs = `"$defs": {
"properties": {
"stage": {"type": "string"},
"model": {"type": "string"},
"effort": {"type": "string", "description": "low, medium, high, xhigh or max (Codex models take low to xhigh); absent means the vendor's default."},
"prompt": {"type": "string"},
"agents": {"type": "array", "items": {"$ref": "#/$defs/agent"}},
"order": {"type": "array", "items": {"$ref": "#/$defs/step"}},
@@ -791,6 +792,7 @@ const workflowSchemaDefs = `"$defs": {
"properties": {
"name": {"type": "string"},
"model": {"type": "string"},
"effort": {"type": "string"},
"prompt": {"type": "string"}
},
"required": ["name", "model", "prompt"],
+9 -2
View File
@@ -32,6 +32,7 @@ type Options struct {
Dir string
Cwd string
Model string
Effort string
Resume string
Env []string
Guidance string
@@ -120,6 +121,7 @@ type Session struct {
mu sync.Mutex
p *proc
model string
effort string
killed bool
images int
@@ -152,6 +154,7 @@ func Start(ctx context.Context, opts Options) (*Session, error) {
s := &Session{
opts: opts,
model: opts.Model,
effort: opts.Effort,
convID: opts.Resume,
events: make(chan Event, 256),
dead: make(chan struct{}),
@@ -296,6 +299,9 @@ func (s *Session) spawnLocked() error {
if s.model != "" {
args = append(args, "--model", s.model)
}
if s.effort != "" {
args = append(args, "--effort", s.effort)
}
if id := s.ID(); id != "" {
args = append(args, "--conversation", id)
}
@@ -514,14 +520,15 @@ func (s *Session) Interrupt() error {
return nil
}
func (s *Session) SetModel(model string) error {
func (s *Session) SetModel(model, effort string) error {
s.mu.Lock()
defer s.mu.Unlock()
if model == s.model {
if model == s.model && effort == s.effort {
return nil
}
s.model = model
s.effort = effort
s.p.expected = true
s.p.stdin.Close()
err := s.restartLocked()
+394 -365
View File
@@ -678,6 +678,9 @@ type AgentSession struct {
CreatedAt time.Time `json:"created_at"`
CreatedBy string `json:"created_by"`
// Effort Requested effort (low, medium, high, xhigh, max; Codex models take low to xhigh); empty means the vendor's default.
Effort string `json:"effort"`
// ForkedAt With forked_from: the vendor's id of the last thing the fork keeps, a message for Claude Code, a turn for Codex.
ForkedAt *string `json:"forked_at,omitempty"`
@@ -879,6 +882,9 @@ type ClientSync struct {
// CompactCreate defines model for CompactCreate.
type CompactCreate struct {
// Effort Effort for the new session, set together with model; empty means the vendor's default. Without model, the new session keeps the old one's model and effort.
Effort *string `json:"effort,omitempty"`
// Model Model for the new session, on either vendor. The old session still writes the handoff. Defaults to the old session's model.
Model *string `json:"model,omitempty"`
}
@@ -913,7 +919,8 @@ type ConnectedClient struct {
// DefaultModel defines model for DefaultModel.
type DefaultModel struct {
Model string `json:"model"`
Effort string `json:"effort"`
Model string `json:"model"`
}
// DirEntry defines model for DirEntry.
@@ -1138,6 +1145,9 @@ type MergeFacts struct {
// MessageCreate defines model for MessageCreate.
type MessageCreate struct {
// Effort Effort for this turn and later ones, set together with model; empty means the vendor's default. Ignored without model, which keeps the session's model and effort.
Effort *string `json:"effort,omitempty"`
// Images Blob ids from uploadBlob, sent to the agent as images alongside the text.
Images *[]string `json:"images,omitempty"`
@@ -1385,6 +1395,8 @@ type ScheduleSave struct {
// SessionCreate defines model for SessionCreate.
type SessionCreate struct {
Effort *string `json:"effort,omitempty"`
// Images Blob ids from uploadBlob, sent to the agent as images alongside the prompt.
Images *[]string `json:"images,omitempty"`
Model *string `json:"model,omitempty"`
@@ -1604,6 +1616,9 @@ type TaskChanges struct {
// TaskCreate defines model for TaskCreate.
type TaskCreate struct {
// Effort The agent's effort when prompt or images are given; empty or absent means the vendor's default.
Effort *string `json:"effort,omitempty"`
// Images Blob ids of images attached to the first message; they start the agent like prompt does. Not with workflow.
Images *[]string `json:"images,omitempty"`
@@ -1639,6 +1654,9 @@ type TaskWorkflow struct {
// TeamMember defines model for TeamMember.
type TeamMember struct {
// Effort The agent's effort; empty means the vendor's default.
Effort string `json:"effort,omitempty"`
// Model The agent's model, which also picks its vendor.
Model string `json:"model"`
@@ -1689,6 +1707,7 @@ type TodoItem struct {
type TodoStart struct {
// Discuss Tell the agent the human wants to discuss the item in chat before anything is built.
Discuss *bool `json:"discuss,omitempty"`
Effort *string `json:"effort,omitempty"`
Model *string `json:"model,omitempty"`
// Title The title of the item to start.
@@ -1747,6 +1766,9 @@ type User struct {
// Away While true, byre answers the questions agents ask in this user's tasks at once.
Away bool `json:"away"`
// DefaultEffort The effort the app starts new tasks on; empty means the vendor's default.
DefaultEffort string `json:"default_effort"`
// DefaultModel The model the app starts new tasks on.
DefaultModel string `json:"default_model"`
DisplayName string `json:"display_name"`
@@ -1821,6 +1843,9 @@ type WorkflowStep struct {
// Agents Runs the stage as a team: several agents in the stage's one task and worktree, each on its own model, sharing a board. The first agent finishes the stage.
Agents *[]TeamMember `json:"agents,omitempty"`
// Effort The stage agent's effort (low, medium, high, xhigh, max; Codex models take low to xhigh); empty means the vendor's default. Refused with agents.
Effort string `json:"effort,omitempty"`
// Model The stage agent's model, which also picks its vendor: gpt-* models run on Codex, gemini-* models on Antigravity, every other model on Claude Code. Required without agents, refused with them.
Model string `json:"model,omitempty"`
@@ -5080,370 +5105,374 @@ func HandlerWithOptions(si ServerInterface, options StdHTTPServerOptions) http.H
// const string: with thousands of chunks the chained `+` fold is several
// times slower for the Go compiler than parsing a slice literal.
var swaggerSpec = []string{
"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",
}
// decodeSpec returns the embedded OpenAPI spec as raw JSON bytes,
+5
View File
@@ -31,6 +31,7 @@ type HookMatcher struct {
type Options struct {
Cwd string
Model string
Effort string
SessionID string
Resume string
ResumeAt string
@@ -330,6 +331,10 @@ func (s *Session) buildArgs(opts Options) ([]string, error) {
args = append(args, "--model", opts.Model)
}
if opts.Effort != "" {
args = append(args, "--effort", opts.Effort)
}
if opts.Guidance != "" {
args = append(args, "--append-system-prompt", opts.Guidance)
}
+54 -6
View File
@@ -28,6 +28,7 @@ import (
type Options struct {
Cwd string
Model string
Effort string
Resume string
ForkFrom string
ForkAt string
@@ -81,10 +82,12 @@ type Session struct {
pendingMu sync.Mutex
pending map[int64]chan rpcResult
stateMu sync.Mutex
threadID string
turnID string
model string
stateMu sync.Mutex
threadID string
turnID string
model string
effort string
effortSet bool
servers map[string]*mcp.Server
reminder string
@@ -113,6 +116,9 @@ func Start(ctx context.Context, opts Options) (*Session, error) {
func (s *Session) serveHooks(opts Options) (map[string]any, error) {
config := map[string]any{}
if opts.Effort != "" {
config["model_reasoning_effort"] = opts.Effort
}
if len(opts.StdioMCP) > 0 {
config["mcp_servers"] = stdioConfig(opts.StdioMCP)
}
@@ -354,12 +360,44 @@ func (s *Session) ID() string {
return s.threadID
}
func (s *Session) SetModel(model string) {
func (s *Session) SetModel(model, effort string) {
s.stateMu.Lock()
s.model = model
s.effort = effort
s.effortSet = true
s.stateMu.Unlock()
}
func (s *Session) defaultEffort(ctx context.Context, model string) (string, error) {
cursor := ""
for {
resp := struct {
Data []struct {
Model string `json:"model"`
DefaultReasoningEffort string `json:"defaultReasoningEffort"`
} `json:"data"`
NextCursor string `json:"nextCursor"`
}{}
params := map[string]any{"includeHidden": true}
if cursor != "" {
params["cursor"] = cursor
}
err := s.Call(ctx, "model/list", params, &resp)
if err != nil {
return "", fmt.Errorf("list models: %w", err)
}
for _, m := range resp.Data {
if m.Model == model {
return m.DefaultReasoningEffort, nil
}
}
if resp.NextCursor == "" {
return "", fmt.Errorf("codex lists no model %s to read its default effort from", model)
}
cursor = resp.NextCursor
}
}
func (s *Session) Send(ctx context.Context, text string, images ...agentinput.Image) (Turn, error) {
input := []UserInput{}
for _, img := range images {
@@ -373,9 +411,19 @@ func (s *Session) Send(ctx context.Context, text string, images ...agentinput.Im
}
s.stateMu.Lock()
params := TurnStartParams{ThreadID: s.threadID, Input: input, Model: s.model}
params := TurnStartParams{ThreadID: s.threadID, Input: input, Model: s.model, Effort: ReasoningEffort(s.effort)}
reset := s.effortSet && s.effort == ""
s.model = ""
s.effort = ""
s.effortSet = false
s.stateMu.Unlock()
if reset {
effort, err := s.defaultEffort(ctx, params.Model)
if err != nil {
return Turn{}, err
}
params.Effort = ReasoningEffort(effort)
}
if s.reminder != "" {
params.AdditionalContext = map[string]AdditionalContextEntry{
"byre": {Kind: AdditionalContextKindApplication, Value: s.reminder},
+5 -1
View File
@@ -62,12 +62,16 @@ func (s *Server) MessageLead(w http.ResponseWriter, r *http.Request) {
if req.Model != nil {
model = *req.Model
}
effort := ""
if req.Effort != nil {
effort = *req.Effort
}
sendID := ""
if req.SendId != nil {
sendID = *req.SendId
}
sess, err := s.agents.MessageLead(r.Context(), u, req.Text, model, sendID, r.Header.Get("Byre-Client"), images)
sess, err := s.agents.MessageLead(r.Context(), u, req.Text, model, effort, sendID, r.Header.Get("Byre-Client"), images)
if err != nil {
writeAgentError(w, err)
return
+1 -1
View File
@@ -33,7 +33,7 @@ func (s *Server) UpdateDefaultModel(w http.ResponseWriter, r *http.Request) {
return
}
u, err := s.store.UpdateDefaultModel(r.Context(), actor(r), req.Model)
u, err := s.store.UpdateDefaultModel(r.Context(), actor(r), req.Model, req.Effort)
if err != nil {
writeStoreError(w, err)
return
+30 -6
View File
@@ -435,7 +435,11 @@ func (s *Server) CreateTask(w http.ResponseWriter, r *http.Request, projectID st
if req.Model != nil {
model = *req.Model
}
t, err := s.agents.StartTask(r.Context(), p, u, title, prompt, model, r.Header.Get("Byre-Client"), images)
effort := ""
if req.Effort != nil {
effort = *req.Effort
}
t, err := s.agents.StartTask(r.Context(), p, u, title, prompt, model, effort, r.Header.Get("Byre-Client"), images)
if err != nil {
writeAgentError(w, err)
return
@@ -485,8 +489,12 @@ func (s *Server) StartTodoItem(w http.ResponseWriter, r *http.Request, projectID
if req.Model != nil {
model = *req.Model
}
effort := ""
if req.Effort != nil {
effort = *req.Effort
}
tasks, err := s.agents.StartTodo(r.Context(), p, u, req.Title, model, u.Login, "", req.Discuss != nil && *req.Discuss)
tasks, err := s.agents.StartTodo(r.Context(), p, u, req.Title, model, effort, u.Login, "", req.Discuss != nil && *req.Discuss)
if err != nil {
writeAgentError(w, err)
return
@@ -863,6 +871,10 @@ func (s *Server) ContinueSession(w http.ResponseWriter, r *http.Request, session
if req.Model != nil {
model = *req.Model
}
effort := ""
if req.Effort != nil {
effort = *req.Effort
}
sendID := ""
if req.SendId != nil {
sendID = *req.SendId
@@ -889,7 +901,7 @@ func (s *Server) ContinueSession(w http.ResponseWriter, r *http.Request, session
return
}
task, err := s.agents.Continue(r.Context(), src, t, p, u, req.Text, model, sendID, r.Header.Get("Byre-Client"), images...)
task, err := s.agents.Continue(r.Context(), src, t, p, u, req.Text, model, effort, sendID, r.Header.Get("Byre-Client"), images...)
if err != nil {
writeAgentError(w, err)
return
@@ -944,12 +956,16 @@ func (s *Server) CreateSession(w http.ResponseWriter, r *http.Request, taskID st
if req.Model != nil {
model = *req.Model
}
effort := ""
if req.Effort != nil {
effort = *req.Effort
}
sendID := ""
if req.SendId != nil {
sendID = *req.SendId
}
sess, err := s.agents.Create(r.Context(), t, u, req.Prompt, model, sendID, r.Header.Get("Byre-Client"), images...)
sess, err := s.agents.Create(r.Context(), t, u, req.Prompt, model, effort, sendID, r.Header.Get("Byre-Client"), images...)
if err != nil {
writeAgentError(w, err)
return
@@ -986,12 +1002,16 @@ func (s *Server) SendMessage(w http.ResponseWriter, r *http.Request, sessionID s
if req.Model != nil {
model = *req.Model
}
effort := ""
if req.Effort != nil {
effort = *req.Effort
}
sendID := ""
if req.SendId != nil {
sendID = *req.SendId
}
sess, _, err := s.agents.Message(r.Context(), sessionID, actor(r), req.Text, model, sendID, r.Header.Get("Byre-Client"), images...)
sess, _, err := s.agents.Message(r.Context(), sessionID, actor(r), req.Text, model, effort, sendID, r.Header.Get("Byre-Client"), images...)
if err != nil {
writeAgentError(w, err)
return
@@ -1017,7 +1037,11 @@ func (s *Server) CompactSession(w http.ResponseWriter, r *http.Request, sessionI
if req.Model != nil {
model = *req.Model
}
sess, err := s.agents.Compact(r.Context(), sessionID, model)
effort := ""
if req.Effort != nil {
effort = *req.Effort
}
sess, err := s.agents.Compact(r.Context(), sessionID, model, effort)
if err != nil {
writeAgentError(w, err)
return
+8 -8
View File
@@ -31,15 +31,15 @@ func insertDefinition(ctx context.Context, tx *sql.Tx, def api.WorkflowDefinitio
case s.Random != nil:
kind, children = "random", s.Random
}
_, err := tx.ExecContext(ctx, `INSERT INTO workflow_steps (definition_id, id, parent, position, kind, stage, model, prompt, weight) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?)`,
id, stepID, parent, pos, kind, s.Stage, s.Model, s.Prompt, s.Weight)
_, err := tx.ExecContext(ctx, `INSERT INTO workflow_steps (definition_id, id, parent, position, kind, stage, model, effort, prompt, weight) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?)`,
id, stepID, parent, pos, kind, s.Stage, s.Model, s.Effort, s.Prompt, s.Weight)
if err != nil {
return err
}
if s.Agents != nil {
for i, a := range *s.Agents {
_, err = tx.ExecContext(ctx, `INSERT INTO workflow_agents (definition_id, step_id, position, name, model, prompt) VALUES (?, ?, ?, ?, ?, ?)`,
id, stepID, i, a.Name, a.Model, a.Prompt)
_, err = tx.ExecContext(ctx, `INSERT INTO workflow_agents (definition_id, step_id, position, name, model, effort, prompt) VALUES (?, ?, ?, ?, ?, ?, ?)`,
id, stepID, i, a.Name, a.Model, a.Effort, a.Prompt)
if err != nil {
return err
}
@@ -74,14 +74,14 @@ func loadDefinition(ctx context.Context, q querier, id string) (api.WorkflowDefi
}
agents := map[int][]api.TeamMember{}
rows, err := q.QueryContext(ctx, `SELECT step_id, name, model, prompt FROM workflow_agents WHERE definition_id = ? ORDER BY step_id, position`, id)
rows, err := q.QueryContext(ctx, `SELECT step_id, name, model, effort, prompt FROM workflow_agents WHERE definition_id = ? ORDER BY step_id, position`, id)
if err != nil {
return def, err
}
for rows.Next() {
step := 0
a := api.TeamMember{}
err = rows.Scan(&step, &a.Name, &a.Model, &a.Prompt)
err = rows.Scan(&step, &a.Name, &a.Model, &a.Effort, &a.Prompt)
if err != nil {
rows.Close()
return def, err
@@ -94,14 +94,14 @@ func loadDefinition(ctx context.Context, q querier, id string) (api.WorkflowDefi
}
children := map[int][]stepRow{}
rows, err = q.QueryContext(ctx, `SELECT id, coalesce(parent, -1), kind, stage, model, prompt, weight FROM workflow_steps WHERE definition_id = ? ORDER BY coalesce(parent, -1), position`, id)
rows, err = q.QueryContext(ctx, `SELECT id, coalesce(parent, -1), kind, stage, model, effort, prompt, weight FROM workflow_steps WHERE definition_id = ? ORDER BY coalesce(parent, -1), position`, id)
if err != nil {
return def, err
}
for rows.Next() {
r := stepRow{}
parent := 0
err = rows.Scan(&r.id, &parent, &r.kind, &r.step.Stage, &r.step.Model, &r.step.Prompt, &r.step.Weight)
err = rows.Scan(&r.id, &parent, &r.kind, &r.step.Stage, &r.step.Model, &r.step.Effort, &r.step.Prompt, &r.step.Weight)
if err != nil {
rows.Close()
return def, err
@@ -0,0 +1,4 @@
ALTER TABLE users ADD COLUMN default_effort TEXT NOT NULL DEFAULT '';
ALTER TABLE agent_sessions ADD COLUMN effort TEXT NOT NULL DEFAULT '';
ALTER TABLE workflow_steps ADD COLUMN effort TEXT NOT NULL DEFAULT '';
ALTER TABLE workflow_agents ADD COLUMN effort TEXT NOT NULL DEFAULT '';
+2 -2
View File
@@ -11,8 +11,8 @@ func (s *Store) UpdateNotificationPrefs(ctx context.Context, login string, prefs
prefs.Questions, prefs.Reports, prefs.Errors, prefs.RateLimits, prefs.Ready, prefs.Discard, prefs.MergeProblems, prefs.Workflows)
}
func (s *Store) UpdateDefaultModel(ctx context.Context, login, model string) (api.User, error) {
return s.updateUser(ctx, login, `default_model = ?`, model)
func (s *Store) UpdateDefaultModel(ctx context.Context, login, model, effort string) (api.User, error) {
return s.updateUser(ctx, login, `default_model = ?, default_effort = ?`, model, effort)
}
func (s *Store) UpdateQuickRun(ctx context.Context, login string, q api.QuickRun) (api.User, error) {
+10 -10
View File
@@ -229,8 +229,8 @@ func (s *Store) EnsureUser(ctx context.Context, login, displayName string) (api.
func (s *Store) GetUser(ctx context.Context, login string) (api.User, error) {
u := api.User{}
p := &u.NotificationPrefs
err := s.db.QueryRowContext(ctx, `SELECT login, display_name, git_name, git_email, notify_questions, notify_reports, notify_errors, notify_rate_limits, notify_ready, notify_discard, notify_merge_problems, notify_workflows, default_model, away, coalesce(quick_run_project, ''), quick_run_workflow FROM users WHERE login = ?`, login).
Scan(&u.Login, &u.DisplayName, &u.GitName, &u.GitEmail, &p.Questions, &p.Reports, &p.Errors, &p.RateLimits, &p.Ready, &p.Discard, &p.MergeProblems, &p.Workflows, &u.DefaultModel, &u.Away, &u.QuickRun.ProjectId, &u.QuickRun.Workflow)
err := s.db.QueryRowContext(ctx, `SELECT login, display_name, git_name, git_email, notify_questions, notify_reports, notify_errors, notify_rate_limits, notify_ready, notify_discard, notify_merge_problems, notify_workflows, default_model, default_effort, away, coalesce(quick_run_project, ''), quick_run_workflow FROM users WHERE login = ?`, login).
Scan(&u.Login, &u.DisplayName, &u.GitName, &u.GitEmail, &p.Questions, &p.Reports, &p.Errors, &p.RateLimits, &p.Ready, &p.Discard, &p.MergeProblems, &p.Workflows, &u.DefaultModel, &u.DefaultEffort, &u.Away, &u.QuickRun.ProjectId, &u.QuickRun.Workflow)
if errors.Is(err, sql.ErrNoRows) {
return u, ErrNotFound
}
@@ -1213,9 +1213,9 @@ func insertSession(ctx context.Context, tx *sql.Tx, emit emitFunc, sess api.Agen
forkedAt = *sess.ForkedAt
}
_, err := tx.ExecContext(ctx, `
INSERT INTO agent_sessions (id, task_id, owner, vendor, model, vendor_session_id, state, role, member, created_by, created_at, forked_from, forked_at)
VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)
`, sess.Id, nullable(sess.TaskId), sess.Owner, string(sess.Vendor), sess.Model, sess.VendorSessionId, string(sess.State), string(sess.Role), sess.Member, sess.CreatedBy, formatTime(sess.CreatedAt), forkedFrom, forkedAt)
INSERT INTO agent_sessions (id, task_id, owner, vendor, model, effort, vendor_session_id, state, role, member, created_by, created_at, forked_from, forked_at)
VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)
`, sess.Id, nullable(sess.TaskId), sess.Owner, string(sess.Vendor), sess.Model, sess.Effort, sess.VendorSessionId, string(sess.State), string(sess.Role), sess.Member, sess.CreatedBy, formatTime(sess.CreatedAt), forkedFrom, forkedAt)
if err != nil {
return err
}
@@ -1519,7 +1519,7 @@ func (s *Store) SetVendorSessionID(ctx context.Context, id, vendorSessionID stri
})
}
func (s *Store) SetSessionModel(ctx context.Context, id, model, actor string) error {
func (s *Store) SetSessionModel(ctx context.Context, id, model, effort, actor string) error {
return s.write(ctx, func(tx *sql.Tx, emit emitFunc) error {
taskID := ""
projectID := ""
@@ -1534,12 +1534,12 @@ func (s *Store) SetSessionModel(ctx context.Context, id, model, actor string) er
return err
}
_, err = tx.ExecContext(ctx, `UPDATE agent_sessions SET model = ? WHERE id = ?`, model, id)
_, err = tx.ExecContext(ctx, `UPDATE agent_sessions SET model = ?, effort = ? WHERE id = ?`, model, effort, id)
if err != nil {
return err
}
return emit(sessionEvent("session.model", projectID, taskID, owner, id, actor, map[string]any{"model": model}))
return emit(sessionEvent("session.model", projectID, taskID, owner, id, actor, map[string]any{"model": model, "effort": effort}))
})
}
@@ -1739,7 +1739,7 @@ const backgroundExpr = `(audit != '' OR EXISTS (SELECT 1 FROM tasks r WHERE r.id
AND (kind != 'task.discard_suggested'
OR (kind = 'task.discard_suggested' AND NOT EXISTS (SELECT 1 FROM tasks r JOIN workflow_definitions d ON d.id = r.workflow_definition_id WHERE r.id IN (tasks.id, tasks.parent_task_id) AND d.auto_discard))))`
const sessionColumns = `id, coalesce(task_id, ''), owner, vendor, model, vendor_session_id, state, role, member, created_by, created_at, forked_from, forked_at, subagents, paused`
const sessionColumns = `id, coalesce(task_id, ''), owner, vendor, model, effort, vendor_session_id, state, role, member, created_by, created_at, forked_from, forked_at, subagents, paused`
type scanner interface {
Scan(dest ...any) error
@@ -1847,7 +1847,7 @@ func scanSession(row scanner) (api.AgentSession, error) {
createdAt := ""
forkedFrom := ""
forkedAt := ""
err := row.Scan(&sess.Id, &sess.TaskId, &sess.Owner, &vendor, &sess.Model, &sess.VendorSessionId, &state, &role, &sess.Member, &sess.CreatedBy, &createdAt, &forkedFrom, &forkedAt, &sess.Subagents, &sess.Paused)
err := row.Scan(&sess.Id, &sess.TaskId, &sess.Owner, &vendor, &sess.Model, &sess.Effort, &sess.VendorSessionId, &state, &role, &sess.Member, &sess.CreatedBy, &createdAt, &forkedFrom, &forkedAt, &sess.Subagents, &sess.Paused)
if err != nil {
return sess, err
}
+4 -4
View File
@@ -72,8 +72,8 @@ func stepProblems(s api.WorkflowStep, where string, seen map[string]bool, inRand
}
if s.Stage == "" {
if s.Model != "" || s.Prompt != "" || s.Agents != nil {
return append(problems, fmt.Sprintf("%s: model, prompt and agents belong on a stage, not on an order, parallel or random", where))
if s.Model != "" || s.Effort != "" || s.Prompt != "" || s.Agents != nil {
return append(problems, fmt.Sprintf("%s: model, effort, prompt and agents belong on a stage, not on an order, parallel or random", where))
}
list, kind := s.Order, "order"
switch {
@@ -112,8 +112,8 @@ func stepProblems(s api.WorkflowStep, where string, seen map[string]bool, inRand
seen[s.Stage] = true
switch {
case s.Agents != nil && strings.TrimSpace(s.Model) != "":
problems = append(problems, fmt.Sprintf("%s: model can't be given with agents, which name their own", where))
case s.Agents != nil && (strings.TrimSpace(s.Model) != "" || s.Effort != ""):
problems = append(problems, fmt.Sprintf("%s: model and effort can't be given with agents, which name their own", where))
case s.Agents != nil:
for _, p := range TeamProblems(*s.Agents) {
problems = append(problems, fmt.Sprintf("%s: %s", where, p))