Skip to content

Commit 0b9e687

Browse files
committed
refactor: use channel for initialPromptReady one-time signaling
Replace atomic.Bool with a channel that gets closed for one-time signaling, which is more idiomatic Go. Remove sync/atomic import since it's no longer needed.
1 parent f725683 commit 0b9e687

1 file changed

Lines changed: 11 additions & 5 deletions

File tree

lib/screentracker/pty_conversation.go

Lines changed: 11 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,6 @@ import (
66
"log/slog"
77
"strings"
88
"sync"
9-
"sync/atomic"
109
"time"
1110

1211
"github.com/coder/agentapi/lib/msgfmt"
@@ -102,9 +101,9 @@ type PTYConversation struct {
102101
stableSignal chan struct{}
103102
// toolCallMessageSet keeps track of the tool calls that have been detected & logged in the current agent message
104103
toolCallMessageSet map[string]bool
105-
// initialPromptReady is set to true when ReadyForInitialPrompt returns true.
104+
// initialPromptReady is closed when ReadyForInitialPrompt returns true.
106105
// This is checked by a separate goroutine to avoid calling ReadyForInitialPrompt on every tick.
107-
initialPromptReady atomic.Bool
106+
initialPromptReady chan struct{}
108107
}
109108

110109
var _ Conversation = &PTYConversation{}
@@ -128,6 +127,7 @@ func NewPTY(ctx context.Context, cfg PTYConversationConfig) *PTYConversation {
128127
outboundQueue: make(chan []MessagePart, 1),
129128
stableSignal: make(chan struct{}, 1),
130129
toolCallMessageSet: make(map[string]bool),
130+
initialPromptReady: make(chan struct{}),
131131
}
132132
// If we have an initial prompt, enqueue it
133133
if len(cfg.InitialPrompt) > 0 {
@@ -157,7 +157,7 @@ func (c *PTYConversation) Start(ctx context.Context) {
157157
case <-ticker.C:
158158
screen := c.cfg.AgentIO.ReadScreen()
159159
if c.cfg.ReadyForInitialPrompt(screen) {
160-
c.initialPromptReady.Store(true)
160+
close(c.initialPromptReady)
161161
return
162162
}
163163
}
@@ -183,7 +183,13 @@ func (c *PTYConversation) Start(ctx context.Context) {
183183
// Signal send loop if agent is ready and queue has items.
184184
// We check readiness independently of statusLocked() because
185185
// statusLocked() returns "changing" when queue has items.
186-
if len(c.outboundQueue) > 0 && c.isScreenStableLocked() && c.initialPromptReady.Load() {
186+
isReady := false
187+
select {
188+
case <-c.initialPromptReady:
189+
isReady = true
190+
default:
191+
}
192+
if len(c.outboundQueue) > 0 && c.isScreenStableLocked() && isReady {
187193
select {
188194
case c.stableSignal <- struct{}{}:
189195
default:

0 commit comments

Comments
 (0)