- Add bubbletea/lipgloss/glamour dependencies for TUI - Create internal/tui package with EventWriter, styles, and bubbletea Model - Support streaming output display in conversation window - Add right panel with statistics and active agent status - Implement multi-agent collaboration with sub-agents - Add AgentCallTool for delegating tasks to sub-agents - Support parallel tool execution with goroutines - Auto-discover sub-agents from ~/.orca/prompts/ directory - Fix orchestrator routing based on msg.To field - Add non-blocking event writer with timeout to prevent blocking
52 lines
899 B
Go
52 lines
899 B
Go
package tui
|
|
|
|
import (
|
|
"strings"
|
|
"sync"
|
|
"time"
|
|
)
|
|
|
|
type Event struct {
|
|
Type string
|
|
Content string
|
|
Agent string
|
|
}
|
|
|
|
type EventWriter struct {
|
|
ch chan Event
|
|
mu sync.Mutex
|
|
buffer strings.Builder
|
|
}
|
|
|
|
func NewEventWriter(ch chan Event) *EventWriter {
|
|
return &EventWriter{ch: ch}
|
|
}
|
|
|
|
func (w *EventWriter) Write(p []byte) (n int, err error) {
|
|
w.mu.Lock()
|
|
defer w.mu.Unlock()
|
|
w.buffer.Write(p)
|
|
content := w.buffer.String()
|
|
if strings.Contains(content, "\n") || len(content) > 80 {
|
|
w.sendEvent(Event{Type: "stream", Content: content})
|
|
w.buffer.Reset()
|
|
}
|
|
return len(p), nil
|
|
}
|
|
|
|
func (w *EventWriter) Flush() {
|
|
w.mu.Lock()
|
|
defer w.mu.Unlock()
|
|
if w.buffer.Len() > 0 {
|
|
w.sendEvent(Event{Type: "stream", Content: w.buffer.String()})
|
|
w.buffer.Reset()
|
|
}
|
|
}
|
|
|
|
func (w *EventWriter) sendEvent(ev Event) {
|
|
select {
|
|
case w.ch <- ev:
|
|
case <-time.After(100 * time.Millisecond):
|
|
}
|
|
}
|