package main import ( "bytes" "encoding/json" "fmt" "io" "net/http" "strings" "time" "github.com/chzyer/readline" ) const ( apiURL = "https://router.ivastudio.verint.live/ProxyScript/run/67bca862210071627d32ef12/current/basic_messenger" colorReset = "\033[0m" colorBlue = "\033[34m" colorGreen = "\033[32m" ) type Metadata struct { Channel string `json:"channel"` } type Message struct { Input string `json:"input"` Model string `json:"model"` PreviousResponseID string `json:"previous_response_id,omitempty"` Metadata Metadata `json:"metadata"` } type ContentItem struct { Type string `json:"type"` Text string `json:"text"` Annotations []string `json:"annotations"` } type OutputMessage struct { Type string `json:"type"` ID string `json:"id"` Role string `json:"role"` Content []ContentItem `json:"content"` } type Response struct { ID string `json:"id"` Object string `json:"object"` CreatedAt int64 `json:"created_at"` Status string `json:"status"` Model string `json:"model"` Output []OutputMessage `json:"output"` } type Messenger struct { client *http.Client model string previousResponseID string } func NewMessenger(model string) *Messenger { return &Messenger{ client: &http.Client{ Timeout: 10 * time.Second, }, model: model, } } func (m *Messenger) sendRequest(input string) (*Response, error) { msg := Message{ Input: input, Model: m.model, PreviousResponseID: m.previousResponseID, Metadata: Metadata{ Channel: "text", }, } jsonData, err := json.Marshal(msg) if err != nil { return nil, fmt.Errorf("failed to marshal JSON: %w", err) } req, err := http.NewRequest("POST", apiURL, bytes.NewBuffer(jsonData)) if err != nil { return nil, fmt.Errorf("failed to create request: %w", err) } req.Header.Set("Content-Type", "application/json") resp, err := m.client.Do(req) if err != nil { return nil, fmt.Errorf("failed to send request: %w", err) } defer resp.Body.Close() body, err := io.ReadAll(resp.Body) if err != nil { return nil, fmt.Errorf("failed to read response: %w", err) } var response Response if err := json.Unmarshal(body, &response); err != nil { return nil, fmt.Errorf("failed to unmarshal response: %w", err) } // Update previous response ID for conversation continuity if response.ID != "" { m.previousResponseID = response.ID } return &response, nil } func (m *Messenger) SendMessage(text string) (string, error) { resp, err := m.sendRequest(text) if err != nil { return "", err } if resp.Status != "completed" { return "", fmt.Errorf("response status: %s", resp.Status) } // Extract text from the response output if len(resp.Output) > 0 && len(resp.Output[0].Content) > 0 { return resp.Output[0].Content[0].Text, nil } return "", fmt.Errorf("no output received") } func printHeader() { fmt.Println("=== Terminal Messenger ===") fmt.Println("Type your message (or 'quit' to exit)") fmt.Println("Use ↑/↓ arrows to navigate history") fmt.Println("==========================") fmt.Println() } func main() { // Get model fmt.Print("Enter model name (default: 'default'): ") var model string fmt.Scanln(&model) if model == "" { model = "default" } messenger := NewMessenger(model) printHeader() // Setup readline for input history and line editing rl, err := readline.NewEx(&readline.Config{ Prompt: colorBlue + "You: " + colorReset, HistoryFile: "/tmp/messenger_history.tmp", InterruptPrompt: "^C", EOFPrompt: "exit", }) if err != nil { fmt.Printf("Error setting up readline: %v\n", err) return } defer rl.Close() // Main message loop for { input, err := rl.Readline() if err != nil { // io.EOF or readline.ErrInterrupt break } input = strings.TrimSpace(input) if input == "quit" || input == "exit" { break } if input == "" { continue } response, err := messenger.SendMessage(input) if err != nil { fmt.Printf("Error: %v\n", err) continue } fmt.Printf(colorGreen+"Assistant: %s"+colorReset+"\n\n", response) } fmt.Println("\nGoodbye!") }