修复代理与日志链路的可靠性问题
This commit is contained in:
@@ -643,6 +643,58 @@ func TestGeminiStreamPreservesFunctionCallParts(t *testing.T) {
|
||||
}
|
||||
}
|
||||
|
||||
func TestGeminiStreamPreservesMultiplePartsByIndex(t *testing.T) {
|
||||
upstream := newSSEUpstream([]string{
|
||||
`data: {"candidates":[{"content":{"parts":[{"text":"hello "},{"functionCall":{"name":"lookup","args":{"q":"weather"}}},{"text":"world"}],"role":"model"},"index":0}]}` + "\n\n",
|
||||
`data: {"candidates":[{"content":{"parts":[{"text":"again"},{"functionCall":{"name":"lookup","args":{"q":"weather"}}},{"text":"!"}],"role":"model"},"finishReason":"STOP","index":0}]}` + "\n\n",
|
||||
})
|
||||
e := requestStreamEntry(t, upstream, "/v1beta/models/gemini-1.5-pro:streamGenerateContent")
|
||||
|
||||
var captured struct {
|
||||
Candidates []struct {
|
||||
Content struct {
|
||||
Parts []map[string]any `json:"parts"`
|
||||
} `json:"content"`
|
||||
} `json:"candidates"`
|
||||
}
|
||||
if err := json.Unmarshal(e.ResponseBody, &captured); err != nil {
|
||||
t.Fatalf("unmarshal assembled Gemini response: %v; body=%s", err, e.ResponseBody)
|
||||
}
|
||||
parts := captured.Candidates[0].Content.Parts
|
||||
if len(parts) != 3 || parts[0]["text"] != "hello again" || parts[2]["text"] != "world!" {
|
||||
t.Fatalf("multiple Gemini parts not preserved: %+v", parts)
|
||||
}
|
||||
if _, ok := parts[1]["functionCall"]; !ok {
|
||||
t.Fatalf("middle functionCall part missing: %+v", parts)
|
||||
}
|
||||
}
|
||||
|
||||
func TestGeminiStreamAppendsDifferentPartKindsAcrossChunks(t *testing.T) {
|
||||
upstream := newSSEUpstream([]string{
|
||||
`data: {"candidates":[{"content":{"parts":[{"text":"answer"}],"role":"model"},"index":0}]}` + "\n\n",
|
||||
`data: {"candidates":[{"content":{"parts":[{"functionCall":{"name":"lookup","args":{"q":"weather"}}}],"role":"model"},"finishReason":"STOP","index":0}]}` + "\n\n",
|
||||
})
|
||||
e := requestStreamEntry(t, upstream, "/v1beta/models/gemini-1.5-pro:streamGenerateContent")
|
||||
|
||||
var captured struct {
|
||||
Candidates []struct {
|
||||
Content struct {
|
||||
Parts []map[string]any `json:"parts"`
|
||||
} `json:"content"`
|
||||
} `json:"candidates"`
|
||||
}
|
||||
if err := json.Unmarshal(e.ResponseBody, &captured); err != nil {
|
||||
t.Fatalf("unmarshal assembled Gemini response: %v; body=%s", err, e.ResponseBody)
|
||||
}
|
||||
parts := captured.Candidates[0].Content.Parts
|
||||
if len(parts) != 2 || parts[0]["text"] != "answer" {
|
||||
t.Fatalf("different Gemini part kinds were merged: %+v", parts)
|
||||
}
|
||||
if _, ok := parts[1]["functionCall"]; !ok {
|
||||
t.Fatalf("functionCall part missing: %+v", parts)
|
||||
}
|
||||
}
|
||||
|
||||
func TestUnknownSSEKeepsRawBody(t *testing.T) {
|
||||
e := requestStreamEntry(t, fakeUnknownStreamUpstream(), "/v1/chat/completions")
|
||||
|
||||
|
||||
Reference in New Issue
Block a user