Files
36Wisdom/cmd/genasset/omlx.go
T

98 lines
2.4 KiB
Go
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
package main
import (
"bytes"
"context"
"encoding/json"
"fmt"
"io"
"net/http"
"time"
)
// omlx 调本机 oMLXOpenAI 兼容 /v1/chat/completions)。
// 注意:Qwen3.5 思考链默认开启且思考文本混入 content,必须传 chat_template_kwargs.enable_thinking=false。
type omlx struct {
endpoint string
apiKey string
model string
timeout int // 秒
maxTokens int
retries int
}
type chatRequest struct {
Model string `json:"model"`
Messages []chatMessage `json:"messages"`
Stream bool `json:"stream"`
MaxTokens int `json:"max_tokens"`
ChatTemplateKwargs map[string]any `json:"chat_template_kwargs"`
}
type chatMessage struct {
Role string `json:"role"`
Content string `json:"content"`
}
type chatResponse struct {
Choices []struct {
Message struct {
Content string `json:"content"`
} `json:"message"`
} `json:"choices"`
}
func (m *omlx) chat(ctx context.Context, system, user string) (string, error) {
payload := chatRequest{
Model: m.model,
Messages: []chatMessage{
{Role: "system", Content: system},
{Role: "user", Content: user},
},
Stream: false,
MaxTokens: m.maxTokens,
ChatTemplateKwargs: map[string]any{"enable_thinking": false},
}
buf, err := json.Marshal(payload)
if err != nil {
return "", err
}
var lastErr error
for i := 0; i <= m.retries; i++ {
req, err := http.NewRequestWithContext(ctx, http.MethodPost, m.endpoint+"/v1/chat/completions", bytes.NewReader(buf))
if err != nil {
return "", err
}
req.Header.Set("Content-Type", "application/json")
req.Header.Set("Authorization", "Bearer "+m.apiKey)
resp, err := (&http.Client{Timeout: time.Duration(m.timeout) * time.Second}).Do(req)
if err != nil {
lastErr = fmt.Errorf("oMLX 请求失败: %w", err)
time.Sleep(2 * time.Second)
continue
}
body, err := io.ReadAll(resp.Body)
resp.Body.Close()
if err != nil {
lastErr = err
continue
}
if resp.StatusCode >= 400 {
lastErr = fmt.Errorf("oMLX %d: %s", resp.StatusCode, string(body))
time.Sleep(2 * time.Second)
continue
}
var cr chatResponse
if err := json.Unmarshal(body, &cr); err != nil {
lastErr = fmt.Errorf("oMLX 响应解析失败: %w", err)
continue
}
if len(cr.Choices) == 0 {
lastErr = fmt.Errorf("oMLX 空响应")
continue
}
return cr.Choices[0].Message.Content, nil
}
return "", lastErr
}