fix: ia streaming usa json.Decoder en vez de Scanner + loggeo + manejo error interno Ollama
This commit is contained in:
@@ -5,6 +5,8 @@ import (
|
|||||||
"bytes"
|
"bytes"
|
||||||
"encoding/json"
|
"encoding/json"
|
||||||
"fmt"
|
"fmt"
|
||||||
|
"io"
|
||||||
|
"log"
|
||||||
"net/http"
|
"net/http"
|
||||||
"strings"
|
"strings"
|
||||||
"time"
|
"time"
|
||||||
@@ -22,6 +24,7 @@ type DataIa struct {
|
|||||||
type respuestaOllama struct {
|
type respuestaOllama struct {
|
||||||
Response string `json:"response"`
|
Response string `json:"response"`
|
||||||
Done bool `json:"done"`
|
Done bool `json:"done"`
|
||||||
|
Error string `json:"error"`
|
||||||
}
|
}
|
||||||
|
|
||||||
func GeneraTextoStream(c *fiber.Ctx) error {
|
func GeneraTextoStream(c *fiber.Ctx) error {
|
||||||
@@ -31,8 +34,10 @@ func GeneraTextoStream(c *fiber.Ctx) error {
|
|||||||
}
|
}
|
||||||
data.Stream = true
|
data.Stream = true
|
||||||
|
|
||||||
|
hasDBConfig := true
|
||||||
config, err := models.GetAiConfigForService("ia")
|
config, err := models.GetAiConfigForService("ia")
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
hasDBConfig = false
|
||||||
config = &models.AiConfig{
|
config = &models.AiConfig{
|
||||||
BaseURL: "http://72.60.24.97:8080/ollama",
|
BaseURL: "http://72.60.24.97:8080/ollama",
|
||||||
ApiKey: "",
|
ApiKey: "",
|
||||||
@@ -49,6 +54,12 @@ func GeneraTextoStream(c *fiber.Ctx) error {
|
|||||||
baseURL := strings.TrimSuffix(strings.TrimRight(config.BaseURL, "/"), "/v1")
|
baseURL := strings.TrimSuffix(strings.TrimRight(config.BaseURL, "/"), "/v1")
|
||||||
endpoint := baseURL + "/api/generate"
|
endpoint := baseURL + "/api/generate"
|
||||||
|
|
||||||
|
if !hasDBConfig {
|
||||||
|
log.Printf("[IA] Usando config default: endpoint=%s model=%s", endpoint, data.Model)
|
||||||
|
} else {
|
||||||
|
log.Printf("[IA] Usando config BD: endpoint=%s model=%s", endpoint, data.Model)
|
||||||
|
}
|
||||||
|
|
||||||
jsonData, _ := json.Marshal(data)
|
jsonData, _ := json.Marshal(data)
|
||||||
req, err := http.NewRequest("POST", endpoint, bytes.NewBuffer(jsonData))
|
req, err := http.NewRequest("POST", endpoint, bytes.NewBuffer(jsonData))
|
||||||
if err != nil {
|
if err != nil {
|
||||||
@@ -62,31 +73,39 @@ func GeneraTextoStream(c *fiber.Ctx) error {
|
|||||||
client := &http.Client{Timeout: 120 * time.Second}
|
client := &http.Client{Timeout: 120 * time.Second}
|
||||||
resp, err := client.Do(req)
|
resp, err := client.Do(req)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
log.Printf("[IA] Error conectando a Ollama: %v", err)
|
||||||
return c.Status(fiber.StatusBadGateway).JSON(fiber.Map{"error": err.Error()})
|
return c.Status(fiber.StatusBadGateway).JSON(fiber.Map{"error": err.Error()})
|
||||||
}
|
}
|
||||||
if resp.StatusCode != http.StatusOK {
|
if resp.StatusCode != http.StatusOK {
|
||||||
|
bodyBytes, _ := io.ReadAll(resp.Body)
|
||||||
resp.Body.Close()
|
resp.Body.Close()
|
||||||
|
log.Printf("[IA] Ollama status %d: %s", resp.StatusCode, string(bodyBytes))
|
||||||
return c.Status(fiber.StatusBadGateway).JSON(fiber.Map{
|
return c.Status(fiber.StatusBadGateway).JSON(fiber.Map{
|
||||||
"error": fmt.Sprintf("Ollama respondió con status %d", resp.StatusCode),
|
"error": fmt.Sprintf("Ollama respondió con status %d", resp.StatusCode),
|
||||||
|
"details": string(bodyBytes),
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
c.Set("Content-Type", "text/plain; charset=utf-8")
|
c.Set("Content-Type", "text/plain; charset=utf-8")
|
||||||
c.Set("Cache-Control", "no-cache")
|
c.Set("Cache-Control", "no-cache")
|
||||||
c.Set("Connection", "keep-alive")
|
c.Set("X-Accel-Buffering", "no")
|
||||||
|
|
||||||
c.Context().SetBodyStreamWriter(func(w *bufio.Writer) {
|
c.Context().SetBodyStreamWriter(func(w *bufio.Writer) {
|
||||||
defer resp.Body.Close()
|
defer resp.Body.Close()
|
||||||
scanner := bufio.NewScanner(resp.Body)
|
dec := json.NewDecoder(resp.Body)
|
||||||
scanner.Buffer(make([]byte, 0, 64*1024), 1024*1024)
|
for {
|
||||||
for scanner.Scan() {
|
|
||||||
line := scanner.Bytes()
|
|
||||||
if len(line) == 0 {
|
|
||||||
continue
|
|
||||||
}
|
|
||||||
var msg respuestaOllama
|
var msg respuestaOllama
|
||||||
if err := json.Unmarshal(line, &msg); err != nil {
|
if err := dec.Decode(&msg); err != nil {
|
||||||
continue
|
if err != io.EOF {
|
||||||
|
log.Printf("[IA] Error decodificando: %v", err)
|
||||||
|
}
|
||||||
|
break
|
||||||
|
}
|
||||||
|
if msg.Error != "" {
|
||||||
|
log.Printf("[IA] Ollama error: %s", msg.Error)
|
||||||
|
fmt.Fprintf(w, "[Error: %s]", msg.Error)
|
||||||
|
w.Flush()
|
||||||
|
break
|
||||||
}
|
}
|
||||||
if msg.Response != "" {
|
if msg.Response != "" {
|
||||||
fmt.Fprint(w, msg.Response)
|
fmt.Fprint(w, msg.Response)
|
||||||
|
|||||||
Reference in New Issue
Block a user