77 "log/slog"
88 "strings"
99 "sync"
10+ "time"
1011
1112 acp "github.com/coder/acp-go-sdk"
1213 st "github.com/coder/agentapi/lib/screentracker"
@@ -15,6 +16,9 @@ import (
1516// Compile-time assertion that ACPAgentIO implements st.AgentIO
1617var _ st.AgentIO = (* ACPAgentIO )(nil )
1718
19+ // DefaultPromptTimeout is the maximum time to wait for an agent response.
20+ const DefaultPromptTimeout = 5 * time .Minute
21+
1822// ACPAgentIO implements screentracker.AgentIO using the ACP protocol
1923type ACPAgentIO struct {
2024 ctx context.Context
@@ -131,7 +135,7 @@ func (a *ACPAgentIO) SetOnChunk(fn func(chunk string)) {
131135}
132136
133137// NewWithPipes creates an ACPAgentIO connected via the provided pipes
134- func NewWithPipes (ctx context.Context , toAgent io.Writer , fromAgent io.Reader , logger * slog.Logger ) (* ACPAgentIO , error ) {
138+ func NewWithPipes (ctx context.Context , toAgent io.Writer , fromAgent io.Reader , logger * slog.Logger , getwd func () ( string , error ) ) (* ACPAgentIO , error ) {
135139 if logger == nil {
136140 logger = slog .Default ()
137141 }
@@ -155,8 +159,13 @@ func NewWithPipes(ctx context.Context, toAgent io.Writer, fromAgent io.Reader, l
155159 logger .Debug ("ACP initialized" , "protocolVersion" , initResp .ProtocolVersion )
156160
157161 // Create a session
162+ cwd , err := getwd ()
163+ if err != nil {
164+ logger .Error ("Failed to get working directory" , "error" , err )
165+ return nil , err
166+ }
158167 sessResp , err := conn .NewSession (ctx , acp.NewSessionRequest {
159- Cwd : "/tmp" ,
168+ Cwd : cwd ,
160169 McpServers : []acp.McpServer {},
161170 })
162171 if err != nil {
@@ -199,7 +208,11 @@ func (a *ACPAgentIO) Write(data []byte) (int, error) {
199208 "textLen" , len (text ),
200209 "rawDataLen" , len (data ))
201210
202- resp , err := a .conn .Prompt (a .ctx , acp.PromptRequest {
211+ // Use a timeout to prevent hanging indefinitely
212+ promptCtx , cancel := context .WithTimeout (a .ctx , DefaultPromptTimeout )
213+ defer cancel ()
214+
215+ resp , err := a .conn .Prompt (promptCtx , acp.PromptRequest {
203216 SessionId : a .sessionID ,
204217 Prompt : []acp.ContentBlock {acp .TextBlock (text )},
205218 })
0 commit comments