(scriptPath string)
| 45 | } |
| 46 | |
| 47 | func runEchoAgent(scriptPath string) { |
| 48 | script, err := loadScript(scriptPath) |
| 49 | if err != nil { |
| 50 | fmt.Printf("Error loading script: %v\n", err) |
| 51 | os.Exit(1) |
| 52 | } |
| 53 | |
| 54 | if len(script) == 0 { |
| 55 | fmt.Println("Script is empty") |
| 56 | os.Exit(1) |
| 57 | } |
| 58 | |
| 59 | ctx, cancel := context.WithCancel(context.Background()) |
| 60 | defer cancel() |
| 61 | sigCh := make(chan os.Signal, 1) |
| 62 | signal.Notify(sigCh, os.Interrupt) |
| 63 | go func() { |
| 64 | for { |
| 65 | select { |
| 66 | case <-sigCh: |
| 67 | cancel() |
| 68 | fmt.Println("Exiting...") |
| 69 | os.Exit(0) |
| 70 | case <-ctx.Done(): |
| 71 | return |
| 72 | } |
| 73 | } |
| 74 | }() |
| 75 | |
| 76 | var messages []st.ConversationMessage |
| 77 | redrawTerminal(messages, false) |
| 78 | |
| 79 | scriptIndex := 0 |
| 80 | scanner := bufio.NewScanner(os.Stdin) |
| 81 | |
| 82 | for scriptIndex < len(script) { |
| 83 | entry := script[scriptIndex] |
| 84 | expectedMsg := strings.TrimSpace(entry.ExpectMessage) |
| 85 | |
| 86 | // Handle initial/follow-up messages (empty ExpectMessage) |
| 87 | if expectedMsg == "" { |
| 88 | // Show thinking state if there's a delay |
| 89 | if entry.ThinkDurationMS > 0 { |
| 90 | redrawTerminal(messages, true) |
| 91 | spinnerCtx, spinnerCancel := context.WithCancel(ctx) |
| 92 | spinnerDone := runSpinner(spinnerCtx) |
| 93 | time.Sleep(time.Duration(entry.ThinkDurationMS) * time.Millisecond) |
| 94 | spinnerCancel() |
| 95 | <-spinnerDone |
| 96 | } |
| 97 | |
| 98 | messages = append(messages, st.ConversationMessage{ |
| 99 | Role: st.ConversationRoleAgent, |
| 100 | Message: entry.ResponseMessage, |
| 101 | Time: time.Now(), |
| 102 | }) |
| 103 | redrawTerminal(messages, false) |
| 104 | scriptIndex++ |
no test coverage detected