修复 AI 网关流式断流:错误透传、自动降级,max_tokens 可缺省
CI / test (push) Successful in 33s
Release / release (push) Successful in 56s

This commit is contained in:
2026-07-13 15:06:01 +08:00
parent 81d4650f3d
commit 9309ad1ffc
11 changed files with 420 additions and 28 deletions
+29
View File
@@ -358,3 +358,32 @@ func (b *ChatRespBridge) Finish() []aiwire.ChatChunk {
// Usage 返回聚合到的用量(供调用日志),上游未报告时为 nil。
func (b *ChatRespBridge) Usage() *aiwire.Usage { return b.usage }
// ChatResponseChunks 把完整 Chat 响应展开为 chunk 序列(内容与工具调用 →
// 终块 → 可选 usage 块),供流式上游断流后的非流式降级结果推送。
func ChatResponseChunks(resp *aiwire.ChatResponse, includeUsage bool) []aiwire.ChatChunk {
if len(resp.Choices) == 0 {
return nil
}
choice := resp.Choices[0]
mk := func(delta aiwire.Delta, finish *string) aiwire.ChatChunk {
return aiwire.ChatChunk{ID: resp.ID, Object: "chat.completion.chunk", Created: resp.Created,
Model: resp.Model, Choices: []aiwire.ChunkChoice{{Index: 0, Delta: delta, FinishReason: finish}}}
}
delta := aiwire.Delta{Role: "assistant", Content: choice.Message.Content.Text}
for i, tc := range choice.Message.ToolCalls {
delta.ToolCalls = append(delta.ToolCalls, aiwire.ToolCallDelta{Index: i, ID: tc.ID,
Type: "function", Function: aiwire.FunctionCallDelta{Name: tc.Function.Name, Arguments: tc.Function.Arguments}})
}
finish := choice.FinishReason
chunks := []aiwire.ChatChunk{mk(delta, nil), mk(aiwire.Delta{}, &finish)}
if includeUsage {
usage := resp.Usage
if usage == nil {
usage = &aiwire.Usage{}
}
chunks = append(chunks, aiwire.ChatChunk{ID: resp.ID, Object: "chat.completion.chunk",
Created: resp.Created, Model: resp.Model, Choices: []aiwire.ChunkChoice{}, Usage: usage})
}
return chunks
}