Skip to content

Instantly share code, notes, and snippets.

@nitishfy
Created July 4, 2026 11:56
Show Gist options
  • Select an option

  • Save nitishfy/1e943e812013c6f6d12a43a46272bf2a to your computer and use it in GitHub Desktop.

Select an option

Save nitishfy/1e943e812013c6f6d12a43a46272bf2a to your computer and use it in GitHub Desktop.
Chatbot that works on the top of Ollama
package main
import (
"bufio"
"bytes"
"encoding/json"
"flag"
"fmt"
"net/http"
"os"
"strings"
)
type Message struct {
Role string `json:"role"`
Content string `json:"content"`
}
// RequestToModel is what we send to the model
type RequestToModel struct {
Model string `json:"model"`
Message []Message `json:"messages"`
}
type ReplyFromModel struct {
Choices []Choice `json:"choices"`
}
type Choice struct {
Message Message `json:"message"`
}
func main() {
model := flag.String("model", "qwen2.5:0.5b", "model name to chat with")
flag.Parse()
conversation := []Message{
{
Role: "system",
Content: "You are a concise, friendly assistant",
},
}
reader := bufio.NewReader(os.Stdin)
fmt.Printf("Chatting with %s. Type 'quit' to exit.\n", *model)
for {
fmt.Print("\nyou > ")
line, _ := reader.ReadString('\n')
line = strings.TrimSpace(line)
if line == "quit" || line == "" {
return
}
// add the message to the converation
conversation = append(conversation, Message{Role: "user", Content: line})
// send the conversation to the model
reply, err := ask(*model, conversation)
if err != nil {
fmt.Println("error:", err)
continue
}
conversation = append(conversation, reply)
fmt.Printf("bot > %s\n", reply.Content)
}
}
// ask sends the conversation to the model and returns the models' reply message
func ask(model string, conversation []Message) (Message, error) {
request := RequestToModel{
Model: model,
Message: conversation,
}
body, _ := json.Marshal(request)
resp, err := http.Post("http://localhost:11434/v1/chat/completions", "application/json", bytes.NewReader(body))
if err != nil {
return Message{}, err
}
defer resp.Body.Close()
// Decode the JSON that comes back into our ReplyFromModel shape.
var incoming ReplyFromModel
if err := json.NewDecoder(resp.Body).Decode(&incoming); err != nil {
return Message{}, err
}
if len(incoming.Choices) == 0 {
return Message{}, fmt.Errorf("no reply from model")
}
// Hand back the first (and usually only) answer.
return incoming.Choices[0].Message, nil
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment