Files
easyai-ai-gateway/apps/api/internal/httpapi/responses_streaming_test.go
T
wangbo fe8dcb40ca feat(openai): 完善 Chat 与 Responses 参数转发
原生 Chat/Responses 改为透明转发,保留标准工具结构并保护调用方显式参数。补齐 Responses 到 Chat 的兼容转换、协议路由边界、完整响应和流式事件,并同步更新 Swagger、回归测试与真实验收脚本。

验证:
- cd apps/api && env -u AI_GATEWAY_TEST_DATABASE_URL go test ./... -count=1
- pnpm openapi
- pnpm lint
- pnpm test
- pnpm build
- gofmt -l 无输出
- git diff --check 通过

风险:
- Chat 回退无法等价表达的 Responses 原生能力现在会返回 unsupported_response_parameter
- 真实供应商 E2E 因本地没有已启用的平台模型候选而未完成
2026-08-04 19:26:48 +08:00

50 lines
2.3 KiB
Go

package httpapi
import (
"net/http/httptest"
"strings"
"testing"
"github.com/easyai/easyai-ai-gateway/apps/api/internal/clients"
)
func TestResponsesStreamWriterForwardsStandardEventsAndNeverWritesDoneMarker(t *testing.T) {
recorder := httptest.NewRecorder()
writer := newCompatibleStreamWriter("responses", "demo", true)
writer.writeDelta(recorder, clients.StreamDeltaEvent{Event: map[string]any{
"type": "response.created", "response": map[string]any{"id": "resp_123", "status": "in_progress"},
}})
writer.writeDelta(recorder, clients.StreamDeltaEvent{Event: map[string]any{
"type": "response.function_call_arguments.delta", "item_id": "fc_1", "delta": "{\"x\":",
}})
writer.writeDelta(recorder, clients.StreamDeltaEvent{Event: map[string]any{
"type": "response.completed", "sequence_number": 2, "response": map[string]any{"id": "resp_123", "status": "completed", "output": []any{}},
}})
writer.writeDone(recorder, map[string]any{"id": "resp_123", "object": "response", "status": "completed", "output": []any{}})
body := recorder.Body.String()
for _, expected := range []string{"event: response.created", "event: response.function_call_arguments.delta", "event: response.completed"} {
if !strings.Contains(body, expected) {
t.Fatalf("missing %q in stream: %s", expected, body)
}
}
if strings.Contains(body, "[DONE]") || strings.Contains(body, "chat.completion") {
t.Fatalf("Responses stream leaked Chat framing: %s", body)
}
if strings.Count(body, "event: response.completed") != 1 {
t.Fatalf("Responses stream duplicated response.completed: %s", body)
}
}
func TestResponsesStreamWriterUsesIncompleteTerminalWithoutAppendingCompleted(t *testing.T) {
recorder := httptest.NewRecorder()
writer := newCompatibleStreamWriter("responses", "demo", false)
writer.writeDelta(recorder, clients.StreamDeltaEvent{Event: map[string]any{
"type": "response.incomplete", "sequence_number": 3, "response": map[string]any{"id": "resp_123", "status": "incomplete"},
}})
writer.writeDone(recorder, map[string]any{"id": "resp_123", "status": "incomplete"})
body := recorder.Body.String()
if strings.Count(body, "event: response.incomplete") != 1 || strings.Contains(body, "event: response.completed") {
t.Fatalf("incomplete terminal event was duplicated or rewritten: %s", body)
}
}