package proxy import ( "encoding/json" "testing" ) // 复现线上火山方舟 qwen 流:data:{...} 无空格(省略 data: 后的空格)。 func TestSSEDataPayloadNoSpace(t *testing.T) { lines := []string{ `data:{"message":{"model":"qwen3.8-flash","id":"msg_1","role":"assistant","type":"message","content":[],"usage":{"input_tokens":31626,"output_tokens":0}},"type":"message_start"}`, `data:{"delta":{"type":"text_delta","text":"你好"},"type":"content_block_delta","index":0}`, `data:{"delta":{"type":"text_delta","text":"!"},"type":"content_block_delta","index":0}`, `data:{"delta":{"stop_reason":"end_turn"},"type":"message_delta","usage":{"cache_creation":{"ephemeral_5m_input_tokens":33065},"output_tokens":8,"cache_creation_input_tokens":33065,"input_tokens":8,"cache_read_input_tokens":0}}`, } var out string for _, l := range lines { out += sseContentText([]byte(l)) } if out != "你好!" { t.Fatalf("outputText=%q, want %q", out, "你好!") } // message_delta 的 delta.usage 应能提取(output_tokens=8) u := scanUsage([]byte(lines[3])) if u == nil { t.Fatal("scanUsage returned nil for message_delta with usage") } var sh usageShape if err := json.Unmarshal(u, &sh); err != nil { t.Fatalf("unmarshal usage: %v", err) } if sh.OutputTokens != 8 { t.Fatalf("output_tokens=%d, want 8", sh.OutputTokens) } } // 兼容带空格的单 data: 行(标准 SSE)与 event:+data: 多行块。 func TestSSEDataPayloadSpacedAndMultiLine(t *testing.T) { // 标准:data: {...} if got := sseContentText([]byte(`data: {"delta":{"type":"text_delta","text":"hi"},"type":"content_block_delta","index":0}`)); got != "hi" { t.Fatalf("spaced single line: got %q, want hi", got) } // 多行块:event: message_delta\ndata: {...} block := []byte("event: message_delta\ndata: {\"delta\":{\"type\":\"text_delta\",\"text\":\"yo\"},\"type\":\"content_block_delta\",\"index\":0}\n") if got := sseContentText(block); got != "yo" { t.Fatalf("multiline block: got %q, want yo", got) } }