@@ -2,6 +2,7 @@ package root
22
33import (
44 "bufio"
5+ "context"
56 "encoding/json"
67 "fmt"
78 "os"
@@ -117,13 +118,12 @@ func printToolCallResponse(toolCall tools.ToolCall, response string) {
117118 fmt .Printf ("\n %s\n " , white ("%s response%s" , bold (toolCall .Function .Name ), formatToolCallResponse (response )))
118119}
119120
120- func promptMaxIterationsContinue (maxIterations int ) ConfirmationResult {
121+ func promptMaxIterationsContinue (ctx context. Context , maxIterations int ) ConfirmationResult {
121122 fmt .Printf ("\n %s\n " , yellow ("⚠️ Maximum iterations (%d) reached. The agent may be stuck in a loop." , maxIterations ))
122123 fmt .Printf ("%s\n " , white ("This can happen with smaller or less capable models." ))
123124 fmt .Printf ("\n %s (y/n): " , blue ("Do you want to continue for 10 more iterations?" ))
124125
125- reader := bufio .NewReader (os .Stdin )
126- response , err := reader .ReadString ('\n' )
126+ response , err := readLine (ctx )
127127 if err != nil {
128128 fmt .Printf ("\n %s\n " , red ("Failed to read input, exiting..." ))
129129 return ConfirmationAbort
@@ -139,15 +139,14 @@ func promptMaxIterationsContinue(maxIterations int) ConfirmationResult {
139139 }
140140}
141141
142- func promptOAuthAuthorization (serverURL string ) ConfirmationResult {
142+ func promptOAuthAuthorization (ctx context. Context , serverURL string ) ConfirmationResult {
143143 fmt .Printf ("\n %s\n " , yellow ("🔐 OAuth Authorization Required" ))
144144 fmt .Printf ("%s %s (remote)\n " , white ("Server:" ), blue (serverURL ))
145145 fmt .Printf ("%s\n " , white ("This server requires OAuth authentication to access its tools." ))
146146 fmt .Printf ("%s\n " , white ("Your browser will open automatically to complete the authorization." ))
147147 fmt .Printf ("\n %s (y/n): " , blue ("Do you want to authorize access?" ))
148148
149- reader := bufio .NewReader (os .Stdin )
150- response , err := reader .ReadString ('\n' )
149+ response , err := readLine (ctx )
151150 if err != nil {
152151 fmt .Printf ("\n %s\n " , red ("Failed to read input, aborting authorization..." ))
153152 return ConfirmationAbort
@@ -290,3 +289,30 @@ func formatJSONValue(key string, value any) string {
290289 return fmt .Sprintf ("%s: %s" , bold (key ), string (jsonBytes ))
291290 }
292291}
292+
293+ func readLine (ctx context.Context ) (string , error ) {
294+ lines := make (chan string )
295+ errs := make (chan error )
296+
297+ go func () {
298+ defer close (lines )
299+ defer close (errs )
300+
301+ reader := bufio .NewReader (os .Stdin )
302+ line , err := reader .ReadString ('\n' )
303+ if err != nil {
304+ errs <- err
305+ } else {
306+ lines <- line
307+ }
308+ }()
309+
310+ select {
311+ case <- ctx .Done ():
312+ return "" , ctx .Err ()
313+ case err := <- errs :
314+ return "" , err
315+ case line := <- lines :
316+ return line , nil
317+ }
318+ }
0 commit comments