Lead compaction
This commit is contained in:
+14
-1
@@ -33,7 +33,7 @@ const leadGuidance = `You are the human's lead agent in byre, shown in the left
|
||||
- Workflows: you manage the server's workflows with list_workflows, read_workflow, save_workflow and delete_workflow, and run one by giving its name to create_task or start_todo. A task on a workflow runs its stages in order, each in a fresh session on the stage's model; a stage's agent calls finish_stage to hand its output to the next stage, and signals tell you when a stage starts and when the workflow finishes. Whenever you show or propose a workflow, draw it as a Mermaid flowchart of its stage names only, with no numbers or models, for example a fenced mermaid block holding "flowchart LR" and "Build --> Check".
|
||||
- Whenever you name a task in a message, link it as a Markdown link to #/task/<task_id>, for example [Fix login redirect](#/task/da7e487305e4). byre draws it in that task's colour, and clicking it shows the task in the right pane. To open a specific tab, append it: #/task/<task_id>/<tab>. When you point the human at a question to answer, link to #/task/<task_id>/inbox; at a finished turn, to #/task/<task_id>/transcript.
|
||||
- Keep messages short; the human reads them in half the screen. Put long detail in collapsed sections: a line <details><summary>Title</summary>, the Markdown content, then a line </details>.
|
||||
- You are long-running. Your context window is large. Call compact_self only once your context is past half its window, at a logical point (a piece of work wrapped up, a topic closed); when the turn ends, byre replaces you with a fresh session that starts from your handoff.
|
||||
- You are long-running. Your context window is large. byre sends you a signal once your context passes half its window; then call compact_self at a logical point (a piece of work wrapped up, a topic closed), and not before; when the turn ends, byre replaces you with a fresh session that starts from your handoff.
|
||||
- Don't commit, push, or touch git branches yourself.`
|
||||
|
||||
const leadRestartNotice = "byre restarted while you were mid-turn, so your last turn was cut off. Pick up where you left off."
|
||||
@@ -255,11 +255,24 @@ func (m *Manager) leadTurnEnded(ctx context.Context, l *live, res endResult) err
|
||||
}
|
||||
}()
|
||||
default:
|
||||
err = m.warnLeadContext(ctx, l)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
go m.deliverLead(l.owner)
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func (m *Manager) warnLeadContext(ctx context.Context, l *live) error {
|
||||
if l.contextWarned || l.contextWindow == 0 || l.contextUsed*2 < l.contextWindow {
|
||||
return nil
|
||||
}
|
||||
l.contextWarned = true
|
||||
text := fmt.Sprintf("Your context is at %d%% of its window (%d of %d tokens). Call compact_self at the next logical point, this turn if nothing is in progress.", l.contextUsed*100/l.contextWindow, l.contextUsed, l.contextWindow)
|
||||
return m.store.AddLeadInput(ctx, store.LeadInput{Owner: l.owner, Kind: store.LeadSignal, Actor: "byre", Text: text})
|
||||
}
|
||||
|
||||
func (m *Manager) Observe(ev api.Event) {
|
||||
switch ev.Kind {
|
||||
case "inbox.created", "inbox.updated", "task.created", "task.merged", "task.discarded", "turn.ended", "task.workflow_stage", "task.workflow_finished":
|
||||
|
||||
@@ -376,7 +376,7 @@ func (m *Manager) leadTools(l *live) []mcp.Tool {
|
||||
}),
|
||||
|
||||
tool("compact_self",
|
||||
"Ask byre to compact you when this turn ends: you write a handoff, and a fresh lead session continues from it. Call it only once your context is past half its window, at a logical point, then end the turn with a short final message.",
|
||||
"Ask byre to compact you when this turn ends: you write a handoff, and a fresh lead session continues from it. Call it only after byre signals that your context is past half its window, at a logical point, then end the turn with a short final message.",
|
||||
`{"type": "object", "properties": {}}`,
|
||||
func(ctx context.Context, user api.User, raw json.RawMessage) (string, error) {
|
||||
m.mu.Lock()
|
||||
|
||||
@@ -89,6 +89,7 @@ type live struct {
|
||||
contextModel string
|
||||
contextUsed int
|
||||
contextWindow int
|
||||
contextWarned bool
|
||||
}
|
||||
|
||||
func (l *live) implementer() bool {
|
||||
|
||||
Reference in New Issue
Block a user