package main import ( "bytes" "encoding/json" "fmt" "io" "log" "net/http" "strings" ) const ollamaURL = "http://localhost:11434/api/chat" const model = "ento-label-parser" type ollamaRequest struct { Model string `json:"model"` Stream bool `json:"stream"` Messages []ollamaMessage `json:"messages"` } type ollamaMessage struct { Role string `json:"role"` Content string `json:"content"` } type ollamaResponse struct { Message struct { Content string `json:"content"` } `json:"message"` } type labelResult struct { Verbatim string `json:"verbatim"` Parsed json.RawMessage `json:"parsed,omitempty"` Error string `json:"error,omitempty"` } func parseLabel(label string) labelResult { result := labelResult{Verbatim: label} reqBody, _ := json.Marshal(ollamaRequest{ Model: model, Stream: false, Messages: []ollamaMessage{ {Role: "user", Content: label}, }, }) resp, err := http.Post(ollamaURL, "application/json", bytes.NewReader(reqBody)) if err != nil { result.Error = fmt.Sprintf("failed to call ollama: %v", err) return result } defer resp.Body.Close() body, err := io.ReadAll(resp.Body) if err != nil { result.Error = fmt.Sprintf("failed to read response: %v", err) return result } var ollamaResp ollamaResponse if err := json.Unmarshal(body, &ollamaResp); err != nil { result.Error = fmt.Sprintf("failed to parse ollama response: %v", err) return result } content := strings.TrimSpace(ollamaResp.Message.Content) var parsed json.RawMessage if err := json.Unmarshal([]byte(content), &parsed); err != nil { result.Error = fmt.Sprintf("model returned invalid JSON: %v\nraw content: %s", err, content) return result } result.Parsed = parsed return result } func handleParse(w http.ResponseWriter, r *http.Request) { if r.Method != http.MethodPost { http.Error(w, "method not allowed", http.StatusMethodNotAllowed) return } if err := r.ParseForm(); err != nil { http.Error(w, "bad request", http.StatusBadRequest) return } raw := r.FormValue("labels") lines := strings.Split(raw, "\n") var results []labelResult for _, line := range lines { line = strings.TrimSpace(line) if line == "" { continue } results = append(results, parseLabel(line)) } w.Header().Set("Content-Type", "application/json") enc := json.NewEncoder(w) enc.SetIndent("", " ") enc.Encode(results) } const indexHTML = `