fix(agent): address code review feedback

- Replace deprecated strings.Title with manual capitalize
- Fix race: set codexClient.onMessage before starting reader goroutine
- Remove unused msgCh parameter from codexClient.handleLine
- Route agent stderr through logger instead of dumping to os.Stderr
- Use deterministic agent order in ensurePaired (prefer codex)
- Increase message channel buffer from 64 to 256
- Rename test to match function rename (buildPrompt)

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
This commit is contained in:
yushen 2026-03-24 14:10:08 +08:00
parent bb45f17cf9
commit 0d9b687d92
4 changed files with 47 additions and 25 deletions

View file

@ -5,7 +5,6 @@ import (
"context"
"encoding/json"
"fmt"
"os"
"os/exec"
"strings"
"sync"
@ -49,7 +48,7 @@ func (b *codexBackend) Execute(ctx context.Context, prompt string, opts ExecOpti
cancel()
return nil, fmt.Errorf("codex stdin pipe: %w", err)
}
cmd.Stderr = os.Stderr
cmd.Stderr = newLogWriter(b.cfg.Logger, "[codex:stderr] ")
if err := cmd.Start(); err != nil {
cancel()
@ -58,15 +57,24 @@ func (b *codexBackend) Execute(ctx context.Context, prompt string, opts ExecOpti
b.cfg.Logger.Printf("[codex] started app-server pid=%d cwd=%s", cmd.Process.Pid, opts.Cwd)
msgCh := make(chan Message, 256)
resCh := make(chan Result, 1)
var output strings.Builder
c := &codexClient{
cfg: b.cfg,
stdin: stdin,
pending: make(map[int]*pendingRPC),
// Set onMessage before starting the reader goroutine to avoid a race.
onMessage: func(msg Message) {
if msg.Type == MessageText {
output.WriteString(msg.Content)
}
trySend(msgCh, msg)
},
}
msgCh := make(chan Message, 64)
resCh := make(chan Result, 1)
// Start reading stdout in background
go func() {
scanner := bufio.NewScanner(stdout)
@ -76,7 +84,7 @@ func (b *codexBackend) Execute(ctx context.Context, prompt string, opts ExecOpti
if line == "" {
continue
}
c.handleLine(line, msgCh)
c.handleLine(line)
}
c.closeAllPending(fmt.Errorf("codex process exited"))
}()
@ -94,15 +102,6 @@ func (b *codexBackend) Execute(ctx context.Context, prompt string, opts ExecOpti
startTime := time.Now()
finalStatus := "completed"
var finalError string
var output strings.Builder
// Drain messages to accumulate output
c.onMessage = func(msg Message) {
if msg.Type == MessageText {
output.WriteString(msg.Content)
}
trySend(msgCh, msg)
}
// 1. Initialize handshake
_, err := c.request(runCtx, "initialize", map[string]any{
@ -308,7 +307,7 @@ func (c *codexClient) closeAllPending(err error) {
}
}
func (c *codexClient) handleLine(line string, msgCh chan<- Message) {
func (c *codexClient) handleLine(line string) {
var raw map[string]json.RawMessage
if err := json.Unmarshal([]byte(line), &raw); err != nil {
return