feat(model): LLM 多供应商适配(Adapter/OpenAI 非流式+SSE 流式/per-role 路由/主备降级/多模态检测/调用记录)

This commit is contained in:
Aska committed 2026-09-06 04:37:27 +08:00
1 parent 51b2bdfba2
commit d09ccc7570
9 files changed
+1285

No files matched your search

+56
View File
@@ -0,0 +1,56 @@
package model
import "testing"
func TestTextMessage(t *testing.T) {
t.Parallel()
msg := TextMessage(RoleUser, "hi")
if msg.Role != RoleUser {
t.Fatalf("role = %q, want %q", msg.Role, RoleUser)
}
if len(msg.Content) != 1 || msg.Content[0].Type != ContentTypeText || msg.Content[0].Text != "hi" {
t.Fatalf("content = %+v, want a single text part", msg.Content)
}
}
func TestImageMessage(t *testing.T) {
t.Parallel()
msg := ImageMessage(RoleUser, "look", "data:image/png;base64,abc")
if len(msg.Content) != 2 {
t.Fatalf("content len = %d, want 2 (text + image)", len(msg.Content))
}
if msg.Content[1].Type != ContentTypeImage || msg.Content[1].ImageURL != "data:image/png;base64,abc" {
t.Fatalf("image part = %+v", msg.Content[1])
}
}
func TestImageMessage_NoText(t *testing.T) {
t.Parallel()
msg := ImageMessage(RoleUser, "", "data:image/png;base64,abc")
if len(msg.Content) != 1 || msg.Content[0].Type != ContentTypeImage {
t.Fatalf("content = %+v, want a single image part", msg.Content)
}
}
func TestHasImage(t *testing.T) {
t.Parallel()
cases := []struct {
name string
msgs []Message
want bool
}{
{"empty", nil, false},
{"text only", []Message{TextMessage(RoleUser, "hi")}, false},
{"image", []Message{ImageMessage(RoleUser, "", "data:image/png;base64,x")}, true},
{"text and image", []Message{ImageMessage(RoleUser, "desc", "data:image/png;base64,x")}, true},
}
for _, c := range cases {
c := c
t.Run(c.name, func(t *testing.T) {
t.Parallel()
if got := HasImage(c.msgs); got != c.want {
t.Fatalf("HasImage = %v, want %v", got, c.want)
}
})
}
}