superagent请求问题修复

This commit is contained in:
andy committed 2026-09-06 01:40:15 +08:00
1 parent ee9d2d7cf1
commit 7243319bbb
19 files changed
+388 -74

No files matched your search

+98 -5
View File
@@ -7,7 +7,7 @@ import (
)
func TestStreamStateConsumesCurrentTraceProtocol(t *testing.T) {
state := newStreamState("session-1")
state := newStreamState("session-1", true)
var traces []TraceEvent
stream := strings.Join([]string{
"event: metadata\nid: 1\ndata: {\"run_id\":\"run-1\",\"resolved_profile_id\":\"profile-1\",\"resolved_profile_version_id\":\"version-1\"}\n",
@@ -39,7 +39,7 @@ func TestStreamStateConsumesCurrentTraceProtocol(t *testing.T) {
}
func TestStreamStateConsumesLegacyValuesAndStructuredContent(t *testing.T) {
state := newStreamState("session-legacy")
state := newStreamState("session-legacy", true)
stream := "event: values\n" +
"data: {\"messages\":[{\"type\":\"human\",\"content\":\"ignored\"},{\"type\":\"ai\",\"content\":[{\"text\":\"first\"},{\"content\":\"second\"}],\"response_metadata\":{\"finish_reason\":\"stop\",\"model_name\":\"model-1\"},\"usage_metadata\":{\"input_tokens\":2,\"output_tokens\":3,\"total_tokens\":5}}]}\n\n" +
"event: trace\ndata: {\"event\":\"run.completed\",\"status\":\"success\"}\n\n" +
@@ -60,8 +60,101 @@ func TestStreamStateConsumesLegacyValuesAndStructuredContent(t *testing.T) {
}
}
func TestStreamStateConsumesNoTraceFinalMessage(t *testing.T) {
state := newStreamState("session-no-trace", false)
stream := "event: messages\n" +
"data: [{\"type\":\"AIMessageChunk\",\"content\":\"\",\"response_metadata\":{\"finish_reason\":\"stop\",\"model_name\":\"model-1\"},\"usage_metadata\":{\"input_tokens\":2,\"output_tokens\":3,\"total_tokens\":5}}]\n\n" +
"event: message.final\n" +
"data: {\"run_id\":\"run-no-trace\",\"text\":\"No trace answer\"}\n\n" +
"event: end\n\n"
if err := state.consume(strings.NewReader(stream), nil); err != nil {
t.Fatalf("consume() error = %v", err)
}
result, err := state.result()
if err != nil {
t.Fatalf("result() error = %v", err)
}
if result.Answer != "No trace answer" || result.ModelName != "model-1" || result.RunID != "run-no-trace" {
t.Fatalf("unexpected result: %#v", result)
}
if result.Usage != (TokenUsage{Input: 2, Output: 3, Total: 5}) {
t.Fatalf("Usage = %#v", result.Usage)
}
}
func TestStreamStateNoTraceRequiresStopAndEnd(t *testing.T) {
tests := []struct {
name string
stream string
wantErr error
result bool
}{
{
name: "missing stop",
stream: "event: messages\n" +
"data: [{\"type\":\"AIMessageChunk\",\"content\":\"partial\",\"response_metadata\":{\"finish_reason\":null}}]\n\n" +
"event: message.final\ndata: {\"run_id\":\"run-1\",\"text\":\"complete\"}\n\n" +
"event: end\n\n",
wantErr: ErrProtocol,
result: true,
},
{
name: "missing message final",
stream: "event: messages\n" +
"data: [{\"type\":\"AIMessageChunk\",\"content\":\"\",\"response_metadata\":{\"finish_reason\":\"stop\"}}]\n\n" +
"event: end\n\n",
wantErr: ErrProtocol,
result: true,
},
{
name: "missing end",
stream: "event: messages\n" +
"data: [{\"type\":\"AIMessageChunk\",\"content\":\"\",\"response_metadata\":{\"finish_reason\":\"stop\"}}]\n\n" +
"event: message.final\ndata: {\"run_id\":\"run-1\",\"text\":\"complete\"}\n\n",
wantErr: ErrStreamIncomplete,
},
{
name: "top-level error",
stream: "event: error\ndata: {\"code\":\"provider_error\",\"message\":\"do not expose me\"}\n\n",
wantErr: ErrRunFailed,
},
}
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
state := newStreamState("session-no-trace", false)
err := state.consume(strings.NewReader(tt.stream), nil)
if tt.result && err == nil {
_, err = state.result()
}
if !errors.Is(err, tt.wantErr) {
t.Fatalf("error = %v, want errors.Is(..., %v)", err, tt.wantErr)
}
if err != nil && strings.Contains(strings.ToLower(err.Error()), "do not expose") {
t.Fatalf("error leaked provider message: %v", err)
}
})
}
}
func TestStreamStateTraceStillRequiresRunCompleted(t *testing.T) {
state := newStreamState("session-trace", true)
stream := "event: values\n" +
"data: {\"messages\":[{\"type\":\"ai\",\"content\":\"complete\",\"response_metadata\":{\"finish_reason\":\"stop\"}}]}\n\n" +
"event: end\n\n"
if err := state.consume(strings.NewReader(stream), nil); err != nil {
t.Fatalf("consume() error = %v", err)
}
_, err := state.result()
if !errors.Is(err, ErrProtocol) || !strings.Contains(err.Error(), "run.completed") {
t.Fatalf("result() error = %v, want missing run.completed protocol error", err)
}
}
func TestStreamStateSupportsMultilineDataAndDeduplicatesIDs(t *testing.T) {
state := newStreamState("session-1")
state := newStreamState("session-1", true)
stream := ": heartbeat\n\n" +
"event: trace\nid: delta-1\ndata: {\"event\":\"message.delta\",\ndata: \"text\":\"A\"}\n\n" +
"event: trace\nid: delta-1\ndata: {\"event\":\"message.delta\",\"text\":\"duplicate\"}\n\n" +
@@ -128,7 +221,7 @@ func TestStreamStateRejectsIncompleteOrFailedStreams(t *testing.T) {
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
state := newStreamState("session-1")
state := newStreamState("session-1", true)
err := state.consume(strings.NewReader(tt.stream), nil)
if tt.result && err == nil {
_, err = state.result()
@@ -144,7 +237,7 @@ func TestStreamStateRejectsIncompleteOrFailedStreams(t *testing.T) {
}
func TestTraceProjectionRedactsAndBoundsText(t *testing.T) {
state := newStreamState("session-1")
state := newStreamState("session-1", true)
secretText := "token=highly-secret " + strings.Repeat("x", maxTraceText+100)
stream := "event: trace\ndata: {\"event\":\"message.final\",\"text\":" + quotedJSON(secretText) + "}\n\n" +
"event: trace\ndata: {\"event\":\"run.completed\",\"status\":\"success\"}\n\n" +