Cut transcript noise: fold grey boxes, drop duplicate review rows

This commit is contained in:
Ian Gulliver
2026-10-20 13:04:17 -07:00
parent 0f33ad4524
commit a7b2333535
14 changed files with 312 additions and 290 deletions
+1 -1
View File
@@ -24,7 +24,7 @@ const guidance = `You are running inside byre. The human reads your work in byre
- TODO.md at the repo root is the project's list of work for byre; its format is the read_knowledge article todo-file.`
const proseQuestionNudge = "Your final message asks the human something in prose. Ask it with byre's ask_human tool " +
"(context with the choices inline as `- ( ) choice` / `- (*) recommended` or `- [ ] choice` / `- [x] recommended` list items, question, why_blocked), " +
"(context with the choices inline as `- ( ) choice` / `- (*) recommended` or `- [ ] choice` / `- [x] recommended` list items, and question)," +
"then end your turn with a short summary."
var (
+1 -7
View File
@@ -24,7 +24,6 @@ var attachmentKinds = []api.AttachmentKind{
type askArgs struct {
Context string `json:"context"`
Question string `json:"question"`
WhyBlocked string `json:"why_blocked"`
Attachments []api.Attachment `json:"attachments"`
ThreadID string `json:"thread_id"`
}
@@ -58,7 +57,6 @@ func (m *Manager) askTool(l *live) mcp.Tool {
"properties": {
"context": {"type": "string", "description": "Everything the human needs to answer well without reading your transcript: what you are working on, what you found, the relevant facts and data shared by all the choices, and then the choices. Markdown is rendered. Each choice is a list item, at least two, all of one kind: '- ( ) Merge now' / '- (*) Wait for review' (pick one; exactly one (*) marks your recommendation), or '- [ ] Fix the tests' / '- [x] Update the docs' (pick any; [x] marks the ones you recommend). The choice's first line, after the marker, is a short name that comes back verbatim as the answer. Everything about that one choice goes in lines indented two spaces beneath it, not in a paragraph above the list: what it would concretely do, its worked example, any code block, command or sub-list, and its trade-offs. For example:\n\n- ( ) Retry in the client\n Wraps ` + "`fetch` in `retry(3)`" + `; a 500 shows the spinner up to 6s longer.\n ` + "```" + `ts\n await retry(3, () => api.get(path));\n ` + "```" + `\n- (*) Queue on the server\n The request returns at once; the write lands within 1s.\n\nPut long supporting detail (logs, full data, per-option analysis) in collapsed sections the human expands on demand: a line '<details><summary>Title</summary>', the Markdown content, then a line '</details>'."},
"question": {"type": "string", "description": "The question itself, in one or two sentences. Markdown is rendered."},
"why_blocked": {"type": "string", "description": "What you can't do until this is answered, and why you can't decide it yourself."},
"attachments": {"type": "array", "items": {
"type": "object",
"properties": {
@@ -77,7 +75,7 @@ func (m *Manager) askTool(l *live) mcp.Tool {
}},
"thread_id": {"type": "string"}
},
"required": ["context", "question", "why_blocked"]
"required": ["context", "question"]
}`),
Handler: func(ctx context.Context, raw json.RawMessage) (string, error) {
return m.ask(ctx, l, raw)
@@ -121,7 +119,6 @@ func (m *Manager) ask(ctx context.Context, l *live, raw json.RawMessage) (string
payload := map[string]any{
"context": args.Context,
"question": args.Question,
"why_blocked": args.WhyBlocked,
"options": options,
"multiple": choices[0].checkbox,
"recommended": recommended,
@@ -259,9 +256,6 @@ func (m *Manager) validateAsk(ctx context.Context, l *live, args askArgs) error
if strings.TrimSpace(args.Question) == "" {
problems = append(problems, "question is empty")
}
if strings.TrimSpace(args.WhyBlocked) == "" {
problems = append(problems, "why_blocked is empty: say what you can't do until this is answered and why you can't decide it yourself")
}
choices := parseChoices(args.Context)
if len(choices) < 2 {
problems = append(problems, "context needs at least two choices, each a list item on its own line: `- ( ) choice` (pick one) or `- [ ] choice` (pick any)")
+1 -1
View File
@@ -641,7 +641,7 @@ func (m *Manager) itemText(ctx context.Context, item api.InboxItem) string {
}
fmt.Fprintf(b, "- %s%s\n", clip(o, 300), mark)
}
fmt.Fprintf(b, "Blocked on: %v\nThe full context is in read_inbox.", p["why_blocked"])
b.WriteString("The full context is in read_inbox.")
return b.String()
}
+3
View File
@@ -723,6 +723,9 @@ func (m *Manager) recordMessage(ctx context.Context, sess api.AgentSession, task
if isContinuation(actor, text) {
payload["continuation"] = true
}
if isFindingsMessage(actor, text) {
payload["findings"] = true
}
err = m.store.RecordTurnMessage(ctx, sess.Id, newEvent(sess.Id, sess.Owner, task.ProjectId, task.Id, actor, "user.message", payload))
if err != nil {
return nil, false, err
+5 -1
View File
@@ -256,7 +256,11 @@ func (m *Manager) recordQueued(ctx context.Context, l *live, msgs []queued) stri
if l.implementer() && isMergeInPrompt(q.actor, q.text) {
m.takeMergeTurn(l)
}
err := m.emit(ctx, l, q.actor, "user.message", map[string]any{"text": q.text, "mid_turn": true})
payload := map[string]any{"text": q.text, "mid_turn": true}
if isFindingsMessage(q.actor, q.text) {
payload["findings"] = true
}
err := m.emit(ctx, l, q.actor, "user.message", payload)
if err != nil {
slog.Error("record mid-turn message", "session", l.id, "err", err)
}
+7 -1
View File
@@ -358,13 +358,19 @@ func (m *Manager) forwardFindings(taskID, reviewID string) {
slog.Info("review findings forwarded", "review", reviewID, "session", s.Id)
}
const findingsPreamble = "A reviewer looked at snapshot #"
func isFindingsMessage(actor, text string) bool {
return actor == "byre" && strings.HasPrefix(text, findingsPreamble)
}
func findingsMessage(r api.Review) string {
res := map[string]any{}
if r.Result != nil {
res = *r.Result
}
b := &strings.Builder{}
fmt.Fprintf(b, "A reviewer looked at snapshot #%d of your work and raised the findings below. Reviewers can be wrong or miss context: check each one against the code and your brief. "+
fmt.Fprintf(b, findingsPreamble+"%d of your work and raised the findings below. Reviewers can be wrong or miss context: check each one against the code and your brief. "+
"Before you change anything, answer each finding with respond_to_finding (snapshot %d and the finding's number): fixing if it holds up and you'll act on it, ignoring with your reason if you're leaving it. "+
"The human sees your answers on the findings and can overrule an ignore.", r.SnapshotN, r.SnapshotN)
findings, _ := res["findings"].([]any)