MCPcopy Create free account
hub / github.com/coder/agentapi / Start

Method Start

lib/screentracker/pty_conversation.go:212–310  ·  view source on GitHub ↗
(ctx context.Context)

Source from the content-addressed store, hash-verified

210}
211
212func (c *PTYConversation) Start(ctx context.Context) {
213 // Snapshot loop
214 c.cfg.Clock.TickerFunc(ctx, c.cfg.SnapshotInterval, func() error {
215 c.lock.Lock()
216 screen := c.cfg.AgentIO.ReadScreen()
217 c.snapshotLocked(screen)
218 status := c.statusLocked()
219 messages := c.messagesLocked()
220
221 // Signal send loop if agent is ready and queue has items.
222 // We check readiness independently of statusLocked() because
223 // statusLocked() returns "changing" when queue has items.
224 if !c.initialPromptReady && c.cfg.ReadyForInitialPrompt(screen) {
225 c.initialPromptReady = true
226 }
227
228 var loadErr string
229 if c.initialPromptReady && c.loadStateStatus == LoadStatePending && c.cfg.StatePersistenceConfig.LoadState {
230 if err, shouldEmit := c.loadStateLocked(); err != nil {
231 c.loadStateStatus = LoadStateFailed
232 if shouldEmit {
233 c.cfg.Logger.Error("Failed to load state", "error", err)
234 loadErr = fmt.Sprintf("Failed to restore previous session: %v", err)
235 }
236 } else {
237 c.loadStateStatus = LoadStateSucceeded
238 }
239 }
240
241 if c.initialPromptReady && len(c.cfg.InitialPrompt) > 0 && !c.initialPromptSent {
242 // Safe to send under lock: the queue is guaranteed empty here because
243 // statusLocked blocks Send until the snapshot buffer fills, which
244 // cannot happen before this first enqueue completes.
245 c.outboundQueue <- outboundMessage{parts: c.cfg.InitialPrompt, errCh: nil}
246 c.initialPromptSent = true
247 c.dirty = true
248 }
249
250 if c.initialPromptReady && len(c.outboundQueue) > 0 && c.isScreenStableLocked() {
251 select {
252 case c.stableSignal <- struct{}{}:
253 c.sendingMessage = true
254 default:
255 // Signal already pending
256 }
257 }
258 c.lock.Unlock()
259
260 if loadErr != "" {
261 c.emitter.EmitError(loadErr, ErrorLevelWarning)
262 }
263 c.emitter.EmitStatus(status)
264 c.emitter.EmitMessages(messages)
265 c.emitter.EmitScreen(screen)
266 return nil
267 }, "snapshot")
268
269 // Send loop - primary call site for sendLocked() in production

Callers

nothing calls this directly

Calls 11

snapshotLockedMethod · 0.95
statusLockedMethod · 0.95
messagesLockedMethod · 0.95
loadStateLockedMethod · 0.95
isScreenStableLockedMethod · 0.95
sendMessageMethod · 0.95
ReadScreenMethod · 0.65
EmitErrorMethod · 0.65
EmitStatusMethod · 0.65
EmitMessagesMethod · 0.65
EmitScreenMethod · 0.65

Tested by

no test coverage detected