mirror of
https://github.com/CJackHwang/ds2api.git
synced 2026-05-05 08:55:28 +08:00
feat: add compatibility setting to strip reference markers from model output and update stream handlers accordingly
This commit is contained in:
@@ -28,7 +28,8 @@
|
||||
"o3": "deepseek-reasoner"
|
||||
},
|
||||
"compat": {
|
||||
"wide_input_strict_output": true
|
||||
"wide_input_strict_output": true,
|
||||
"strip_reference_markers": true
|
||||
},
|
||||
"toolcall": {
|
||||
"mode": "feature_match",
|
||||
|
||||
@@ -1,8 +1,10 @@
|
||||
# DeepSeek SSE 流格式字段分析(2026-04-03)
|
||||
# DeepSeek SSE 流格式字段分析(永久默认样本)
|
||||
|
||||
> 日期:2026-04-03(UTC)
|
||||
> 日期:2026-04-05(UTC)
|
||||
>
|
||||
> 样本:`tests/raw_stream_samples/guangzhou-weather-reasoner-search-20260403/upstream.stream.sse`
|
||||
> 默认样本:
|
||||
> - `tests/raw_stream_samples/guangzhou-weather-reasoner-search-20260404/upstream.stream.sse`
|
||||
> - `tests/raw_stream_samples/content-filter-trigger-20260405-jwt3/upstream.stream.sse`
|
||||
>
|
||||
> 模型:`deepseek-reasoner-search`(搜索 + 思考)
|
||||
|
||||
@@ -69,13 +71,28 @@ data: <json or text>
|
||||
|
||||
1. 跳过所有 `response/fragments/-?\d+/status`。
|
||||
2. 继续保留 `response/status=FINISHED` 作为真正结束判定。
|
||||
3. 通过独立仿真工具持续回放全部样本,作为回归门禁:
|
||||
3. 通过独立仿真工具持续回放 manifest 声明的 canonical 默认样本,作为回归门禁:
|
||||
|
||||
```bash
|
||||
./tests/scripts/run-raw-stream-sim.sh
|
||||
```
|
||||
|
||||
## 6. 后续扩展建议
|
||||
## 6. `CONTENT_FILTER` 终态样本
|
||||
|
||||
在 `content-filter-trigger-20260405-jwt3` 样本中,末尾会出现一组明确的风控终态字段:
|
||||
|
||||
- `response.status = CONTENT_FILTER`
|
||||
- `response.quasi_status = CONTENT_FILTER`
|
||||
- `response.fragments` 里包含 `TEMPLATE_RESPONSE` 拒答文案
|
||||
- 后续仍会有 `event: finish`
|
||||
|
||||
这说明:
|
||||
|
||||
1. 风控不是“没有结束信号”,而是“正常流式输出后在尾部切换到风控终态”。
|
||||
2. 适配层不能把 `TEMPLATE_RESPONSE` 当普通正文输出。
|
||||
3. 回放工具需要把这种终态保留下来,用于后续回归和字段分析。
|
||||
|
||||
## 7. 后续扩展建议
|
||||
|
||||
- 增加不同模型(`deepseek-chat-search` / 非 search / 非 thinking)样本。
|
||||
- 增加异常样本(限流、中断、content_filter、空结果)。
|
||||
|
||||
@@ -233,7 +233,7 @@ go run ./cmd/ds2api-tests --no-preflight
|
||||
```
|
||||
|
||||
说明:
|
||||
- 该工具会重放 `tests/raw_stream_samples` 下全部样本,按上游 SSE 顺序做 1:1 仿真解析。
|
||||
- 该工具默认重放 `tests/raw_stream_samples/manifest.json` 声明的 canonical 样本,按上游 SSE 顺序做 1:1 仿真解析。
|
||||
- 默认校验不出现 `FINISHED` 文本泄露,并要求存在结束信号。
|
||||
- 结果会写入 `artifacts/raw-stream-sim/*.json`,可供其他测试脚本或排障流程复用。
|
||||
|
||||
|
||||
@@ -22,6 +22,7 @@ type DeepSeekCaller interface {
|
||||
|
||||
type ConfigReader interface {
|
||||
ClaudeMapping() map[string]string
|
||||
CompatStripReferenceMarkers() bool
|
||||
}
|
||||
|
||||
type OpenAIChatRunner interface {
|
||||
|
||||
@@ -7,6 +7,7 @@ type mockClaudeConfig struct {
|
||||
}
|
||||
|
||||
func (m mockClaudeConfig) ClaudeMapping() map[string]string { return m.m }
|
||||
func (mockClaudeConfig) CompatStripReferenceMarkers() bool { return true }
|
||||
|
||||
func TestNormalizeClaudeRequestUsesConfigInterfaceMapping(t *testing.T) {
|
||||
req := map[string]any{
|
||||
|
||||
@@ -149,6 +149,7 @@ func (h *Handler) handleClaudeStreamRealtime(w http.ResponseWriter, r *http.Requ
|
||||
messages,
|
||||
thinkingEnabled,
|
||||
searchEnabled,
|
||||
h.compatStripReferenceMarkers(),
|
||||
toolNames,
|
||||
)
|
||||
streamRuntime.sendMessageStart()
|
||||
|
||||
@@ -21,6 +21,13 @@ type Handler struct {
|
||||
OpenAI OpenAIChatRunner
|
||||
}
|
||||
|
||||
func (h *Handler) compatStripReferenceMarkers() bool {
|
||||
if h == nil || h.Store == nil {
|
||||
return true
|
||||
}
|
||||
return h.Store.CompatStripReferenceMarkers()
|
||||
}
|
||||
|
||||
var (
|
||||
claudeStreamPingInterval = time.Duration(deepseek.KeepAliveTimeout) * time.Second
|
||||
claudeStreamIdleTimeout = time.Duration(deepseek.StreamIdleTimeout) * time.Second
|
||||
|
||||
13
internal/adapter/claude/output_clean.go
Normal file
13
internal/adapter/claude/output_clean.go
Normal file
@@ -0,0 +1,13 @@
|
||||
package claude
|
||||
|
||||
import textclean "ds2api/internal/textclean"
|
||||
|
||||
func cleanVisibleOutput(text string, stripReferenceMarkers bool) string {
|
||||
if text == "" {
|
||||
return text
|
||||
}
|
||||
if stripReferenceMarkers {
|
||||
text = textclean.StripReferenceMarkers(text)
|
||||
}
|
||||
return text
|
||||
}
|
||||
@@ -16,6 +16,8 @@ func (s claudeProxyStoreStub) ClaudeMapping() map[string]string {
|
||||
return s.mapping
|
||||
}
|
||||
|
||||
func (claudeProxyStoreStub) CompatStripReferenceMarkers() bool { return true }
|
||||
|
||||
type openAIProxyStub struct {
|
||||
status int
|
||||
body string
|
||||
|
||||
@@ -19,13 +19,14 @@ type claudeStreamRuntime struct {
|
||||
toolNames []string
|
||||
messages []any
|
||||
|
||||
thinkingEnabled bool
|
||||
searchEnabled bool
|
||||
bufferToolContent bool
|
||||
thinkingEnabled bool
|
||||
searchEnabled bool
|
||||
bufferToolContent bool
|
||||
stripReferenceMarkers bool
|
||||
|
||||
messageID string
|
||||
thinking strings.Builder
|
||||
text strings.Builder
|
||||
messageID string
|
||||
thinking strings.Builder
|
||||
text strings.Builder
|
||||
outputTokens int
|
||||
|
||||
nextBlockIndex int
|
||||
@@ -45,21 +46,23 @@ func newClaudeStreamRuntime(
|
||||
messages []any,
|
||||
thinkingEnabled bool,
|
||||
searchEnabled bool,
|
||||
stripReferenceMarkers bool,
|
||||
toolNames []string,
|
||||
) *claudeStreamRuntime {
|
||||
return &claudeStreamRuntime{
|
||||
w: w,
|
||||
rc: rc,
|
||||
canFlush: canFlush,
|
||||
model: model,
|
||||
messages: messages,
|
||||
thinkingEnabled: thinkingEnabled,
|
||||
searchEnabled: searchEnabled,
|
||||
bufferToolContent: len(toolNames) > 0,
|
||||
toolNames: toolNames,
|
||||
messageID: fmt.Sprintf("msg_%d", time.Now().UnixNano()),
|
||||
thinkingBlockIndex: -1,
|
||||
textBlockIndex: -1,
|
||||
w: w,
|
||||
rc: rc,
|
||||
canFlush: canFlush,
|
||||
model: model,
|
||||
messages: messages,
|
||||
thinkingEnabled: thinkingEnabled,
|
||||
searchEnabled: searchEnabled,
|
||||
bufferToolContent: len(toolNames) > 0,
|
||||
stripReferenceMarkers: stripReferenceMarkers,
|
||||
toolNames: toolNames,
|
||||
messageID: fmt.Sprintf("msg_%d", time.Now().UnixNano()),
|
||||
thinkingBlockIndex: -1,
|
||||
textBlockIndex: -1,
|
||||
}
|
||||
}
|
||||
|
||||
@@ -80,10 +83,11 @@ func (s *claudeStreamRuntime) onParsed(parsed sse.LineResult) streamengine.Parse
|
||||
|
||||
contentSeen := false
|
||||
for _, p := range parsed.Parts {
|
||||
if p.Text == "" {
|
||||
cleanedText := cleanVisibleOutput(p.Text, s.stripReferenceMarkers)
|
||||
if cleanedText == "" {
|
||||
continue
|
||||
}
|
||||
if p.Type != "thinking" && s.searchEnabled && sse.IsCitation(p.Text) {
|
||||
if p.Type != "thinking" && s.searchEnabled && sse.IsCitation(cleanedText) {
|
||||
continue
|
||||
}
|
||||
contentSeen = true
|
||||
@@ -92,7 +96,7 @@ func (s *claudeStreamRuntime) onParsed(parsed sse.LineResult) streamengine.Parse
|
||||
if !s.thinkingEnabled {
|
||||
continue
|
||||
}
|
||||
s.thinking.WriteString(p.Text)
|
||||
s.thinking.WriteString(cleanedText)
|
||||
s.closeTextBlock()
|
||||
if !s.thinkingBlockOpen {
|
||||
s.thinkingBlockIndex = s.nextBlockIndex
|
||||
@@ -112,13 +116,13 @@ func (s *claudeStreamRuntime) onParsed(parsed sse.LineResult) streamengine.Parse
|
||||
"index": s.thinkingBlockIndex,
|
||||
"delta": map[string]any{
|
||||
"type": "thinking_delta",
|
||||
"thinking": p.Text,
|
||||
"thinking": cleanedText,
|
||||
},
|
||||
})
|
||||
continue
|
||||
}
|
||||
|
||||
s.text.WriteString(p.Text)
|
||||
s.text.WriteString(cleanedText)
|
||||
if s.bufferToolContent {
|
||||
if hasUnclosedCodeFence(s.text.String()) {
|
||||
continue
|
||||
@@ -144,7 +148,7 @@ func (s *claudeStreamRuntime) onParsed(parsed sse.LineResult) streamengine.Parse
|
||||
"index": s.textBlockIndex,
|
||||
"delta": map[string]any{
|
||||
"type": "text_delta",
|
||||
"text": p.Text,
|
||||
"text": cleanedText,
|
||||
},
|
||||
})
|
||||
}
|
||||
|
||||
@@ -43,7 +43,7 @@ func (s *claudeStreamRuntime) finalize(stopReason string) {
|
||||
s.closeTextBlock()
|
||||
|
||||
finalThinking := s.thinking.String()
|
||||
finalText := s.text.String()
|
||||
finalText := cleanVisibleOutput(s.text.String(), s.stripReferenceMarkers)
|
||||
|
||||
if s.bufferToolContent {
|
||||
detected := util.ParseStandaloneToolCalls(finalText, s.toolNames)
|
||||
@@ -64,7 +64,7 @@ func (s *claudeStreamRuntime) finalize(stopReason string) {
|
||||
"input": map[string]any{},
|
||||
},
|
||||
})
|
||||
|
||||
|
||||
inputBytes, _ := json.Marshal(tc.Input)
|
||||
s.send("content_block_delta", map[string]any{
|
||||
"type": "content_block_delta",
|
||||
|
||||
@@ -28,6 +28,8 @@ func (streamStatusClaudeStoreStub) ClaudeMapping() map[string]string {
|
||||
}
|
||||
}
|
||||
|
||||
func (streamStatusClaudeStoreStub) CompatStripReferenceMarkers() bool { return true }
|
||||
|
||||
func captureClaudeStatusMiddleware(statuses *[]int) func(http.Handler) http.Handler {
|
||||
return func(next http.Handler) http.Handler {
|
||||
return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
|
||||
|
||||
@@ -22,6 +22,7 @@ type DeepSeekCaller interface {
|
||||
|
||||
type ConfigReader interface {
|
||||
ModelAliases() map[string]string
|
||||
CompatStripReferenceMarkers() bool
|
||||
}
|
||||
|
||||
type OpenAIChatRunner interface {
|
||||
|
||||
@@ -140,7 +140,15 @@ func (h *Handler) handleNonStreamGenerateContent(w http.ResponseWriter, resp *ht
|
||||
}
|
||||
|
||||
result := sse.CollectStream(resp, thinkingEnabled, true)
|
||||
writeJSON(w, http.StatusOK, buildGeminiGenerateContentResponse(model, finalPrompt, result.Thinking, result.Text, toolNames, result.OutputTokens))
|
||||
stripReferenceMarkers := h.compatStripReferenceMarkers()
|
||||
writeJSON(w, http.StatusOK, buildGeminiGenerateContentResponse(
|
||||
model,
|
||||
finalPrompt,
|
||||
cleanVisibleOutput(result.Thinking, stripReferenceMarkers),
|
||||
cleanVisibleOutput(result.Text, stripReferenceMarkers),
|
||||
toolNames,
|
||||
result.OutputTokens,
|
||||
))
|
||||
}
|
||||
|
||||
func buildGeminiGenerateContentResponse(model, finalPrompt, finalThinking, finalText string, toolNames []string, outputTokens int) map[string]any {
|
||||
@@ -179,7 +187,7 @@ func buildGeminiUsage(finalPrompt, finalThinking, finalText string, outputTokens
|
||||
|
||||
func buildGeminiPartsFromFinal(finalText, finalThinking string, toolNames []string) []map[string]any {
|
||||
detected := util.ParseToolCalls(finalText, toolNames)
|
||||
if len(detected) == 0 && strings.TrimSpace(finalThinking) != "" {
|
||||
if len(detected) == 0 && finalThinking != "" {
|
||||
detected = util.ParseToolCalls(finalThinking, toolNames)
|
||||
}
|
||||
if len(detected) > 0 {
|
||||
@@ -196,7 +204,7 @@ func buildGeminiPartsFromFinal(finalText, finalThinking string, toolNames []stri
|
||||
}
|
||||
|
||||
text := finalText
|
||||
if strings.TrimSpace(text) == "" {
|
||||
if text == "" {
|
||||
text = finalThinking
|
||||
}
|
||||
return []map[string]any{{"text": text}}
|
||||
|
||||
@@ -17,6 +17,13 @@ type Handler struct {
|
||||
OpenAI OpenAIChatRunner
|
||||
}
|
||||
|
||||
func (h *Handler) compatStripReferenceMarkers() bool {
|
||||
if h == nil || h.Store == nil {
|
||||
return true
|
||||
}
|
||||
return h.Store.CompatStripReferenceMarkers()
|
||||
}
|
||||
|
||||
func RegisterRoutes(r chi.Router, h *Handler) {
|
||||
r.Post("/v1beta/models/{model}:generateContent", h.GenerateContent)
|
||||
r.Post("/v1beta/models/{model}:streamGenerateContent", h.StreamGenerateContent)
|
||||
|
||||
@@ -27,7 +27,7 @@ func (h *Handler) handleStreamGenerateContent(w http.ResponseWriter, r *http.Req
|
||||
|
||||
rc := http.NewResponseController(w)
|
||||
_, canFlush := w.(http.Flusher)
|
||||
runtime := newGeminiStreamRuntime(w, rc, canFlush, model, finalPrompt, thinkingEnabled, searchEnabled, toolNames)
|
||||
runtime := newGeminiStreamRuntime(w, rc, canFlush, model, finalPrompt, thinkingEnabled, searchEnabled, h.compatStripReferenceMarkers(), toolNames)
|
||||
|
||||
initialType := "text"
|
||||
if thinkingEnabled {
|
||||
@@ -57,13 +57,14 @@ type geminiStreamRuntime struct {
|
||||
model string
|
||||
finalPrompt string
|
||||
|
||||
thinkingEnabled bool
|
||||
searchEnabled bool
|
||||
bufferContent bool
|
||||
toolNames []string
|
||||
thinkingEnabled bool
|
||||
searchEnabled bool
|
||||
bufferContent bool
|
||||
stripReferenceMarkers bool
|
||||
toolNames []string
|
||||
|
||||
thinking strings.Builder
|
||||
text strings.Builder
|
||||
thinking strings.Builder
|
||||
text strings.Builder
|
||||
outputTokens int
|
||||
}
|
||||
|
||||
@@ -75,18 +76,20 @@ func newGeminiStreamRuntime(
|
||||
finalPrompt string,
|
||||
thinkingEnabled bool,
|
||||
searchEnabled bool,
|
||||
stripReferenceMarkers bool,
|
||||
toolNames []string,
|
||||
) *geminiStreamRuntime {
|
||||
return &geminiStreamRuntime{
|
||||
w: w,
|
||||
rc: rc,
|
||||
canFlush: canFlush,
|
||||
model: model,
|
||||
finalPrompt: finalPrompt,
|
||||
thinkingEnabled: thinkingEnabled,
|
||||
searchEnabled: searchEnabled,
|
||||
bufferContent: len(toolNames) > 0,
|
||||
toolNames: toolNames,
|
||||
w: w,
|
||||
rc: rc,
|
||||
canFlush: canFlush,
|
||||
model: model,
|
||||
finalPrompt: finalPrompt,
|
||||
thinkingEnabled: thinkingEnabled,
|
||||
searchEnabled: searchEnabled,
|
||||
bufferContent: len(toolNames) > 0,
|
||||
stripReferenceMarkers: stripReferenceMarkers,
|
||||
toolNames: toolNames,
|
||||
}
|
||||
}
|
||||
|
||||
@@ -113,20 +116,21 @@ func (s *geminiStreamRuntime) onParsed(parsed sse.LineResult) streamengine.Parse
|
||||
|
||||
contentSeen := false
|
||||
for _, p := range parsed.Parts {
|
||||
if p.Text == "" {
|
||||
cleanedText := cleanVisibleOutput(p.Text, s.stripReferenceMarkers)
|
||||
if cleanedText == "" {
|
||||
continue
|
||||
}
|
||||
if p.Type != "thinking" && s.searchEnabled && sse.IsCitation(p.Text) {
|
||||
if p.Type != "thinking" && s.searchEnabled && sse.IsCitation(cleanedText) {
|
||||
continue
|
||||
}
|
||||
contentSeen = true
|
||||
if p.Type == "thinking" {
|
||||
if s.thinkingEnabled {
|
||||
s.thinking.WriteString(p.Text)
|
||||
s.thinking.WriteString(cleanedText)
|
||||
}
|
||||
continue
|
||||
}
|
||||
s.text.WriteString(p.Text)
|
||||
s.text.WriteString(cleanedText)
|
||||
if s.bufferContent {
|
||||
continue
|
||||
}
|
||||
@@ -136,7 +140,7 @@ func (s *geminiStreamRuntime) onParsed(parsed sse.LineResult) streamengine.Parse
|
||||
"index": 0,
|
||||
"content": map[string]any{
|
||||
"role": "model",
|
||||
"parts": []map[string]any{{"text": p.Text}},
|
||||
"parts": []map[string]any{{"text": cleanedText}},
|
||||
},
|
||||
},
|
||||
},
|
||||
@@ -148,7 +152,7 @@ func (s *geminiStreamRuntime) onParsed(parsed sse.LineResult) streamengine.Parse
|
||||
|
||||
func (s *geminiStreamRuntime) finalize() {
|
||||
finalThinking := s.thinking.String()
|
||||
finalText := s.text.String()
|
||||
finalText := cleanVisibleOutput(s.text.String(), s.stripReferenceMarkers)
|
||||
|
||||
if s.bufferContent {
|
||||
parts := buildGeminiPartsFromFinal(finalText, finalThinking, s.toolNames)
|
||||
|
||||
@@ -17,7 +17,8 @@ import (
|
||||
|
||||
type testGeminiConfig struct{}
|
||||
|
||||
func (testGeminiConfig) ModelAliases() map[string]string { return nil }
|
||||
func (testGeminiConfig) ModelAliases() map[string]string { return nil }
|
||||
func (testGeminiConfig) CompatStripReferenceMarkers() bool { return true }
|
||||
|
||||
type testGeminiAuth struct {
|
||||
a *auth.RequestAuth
|
||||
@@ -62,8 +63,8 @@ func (m testGeminiDS) CallCompletion(_ context.Context, _ *auth.RequestAuth, _ m
|
||||
}
|
||||
|
||||
type geminiOpenAIErrorStub struct {
|
||||
status int
|
||||
body string
|
||||
status int
|
||||
body string
|
||||
headers map[string]string
|
||||
}
|
||||
|
||||
@@ -247,7 +248,7 @@ func TestStreamGenerateContentEmitsSSE(t *testing.T) {
|
||||
|
||||
func TestGenerateContentOpenAIProxyErrorUsesGeminiEnvelope(t *testing.T) {
|
||||
h := &Handler{
|
||||
Store: testGeminiConfig{},
|
||||
Store: testGeminiConfig{},
|
||||
OpenAI: geminiOpenAIErrorStub{
|
||||
status: http.StatusUnauthorized,
|
||||
body: `{"error":{"message":"invalid api key"}}`,
|
||||
|
||||
13
internal/adapter/gemini/output_clean.go
Normal file
13
internal/adapter/gemini/output_clean.go
Normal file
@@ -0,0 +1,13 @@
|
||||
package gemini
|
||||
|
||||
import textclean "ds2api/internal/textclean"
|
||||
|
||||
func cleanVisibleOutput(text string, stripReferenceMarkers bool) string {
|
||||
if text == "" {
|
||||
return text
|
||||
}
|
||||
if stripReferenceMarkers {
|
||||
text = textclean.StripReferenceMarkers(text)
|
||||
}
|
||||
return text
|
||||
}
|
||||
@@ -22,8 +22,9 @@ type chatStreamRuntime struct {
|
||||
finalPrompt string
|
||||
toolNames []string
|
||||
|
||||
thinkingEnabled bool
|
||||
searchEnabled bool
|
||||
thinkingEnabled bool
|
||||
searchEnabled bool
|
||||
stripReferenceMarkers bool
|
||||
|
||||
firstChunkSent bool
|
||||
bufferToolContent bool
|
||||
@@ -49,25 +50,27 @@ func newChatStreamRuntime(
|
||||
finalPrompt string,
|
||||
thinkingEnabled bool,
|
||||
searchEnabled bool,
|
||||
stripReferenceMarkers bool,
|
||||
toolNames []string,
|
||||
bufferToolContent bool,
|
||||
emitEarlyToolDeltas bool,
|
||||
) *chatStreamRuntime {
|
||||
return &chatStreamRuntime{
|
||||
w: w,
|
||||
rc: rc,
|
||||
canFlush: canFlush,
|
||||
completionID: completionID,
|
||||
created: created,
|
||||
model: model,
|
||||
finalPrompt: finalPrompt,
|
||||
toolNames: toolNames,
|
||||
thinkingEnabled: thinkingEnabled,
|
||||
searchEnabled: searchEnabled,
|
||||
bufferToolContent: bufferToolContent,
|
||||
emitEarlyToolDeltas: emitEarlyToolDeltas,
|
||||
streamToolCallIDs: map[int]string{},
|
||||
streamToolNames: map[int]string{},
|
||||
w: w,
|
||||
rc: rc,
|
||||
canFlush: canFlush,
|
||||
completionID: completionID,
|
||||
created: created,
|
||||
model: model,
|
||||
finalPrompt: finalPrompt,
|
||||
toolNames: toolNames,
|
||||
thinkingEnabled: thinkingEnabled,
|
||||
searchEnabled: searchEnabled,
|
||||
stripReferenceMarkers: stripReferenceMarkers,
|
||||
bufferToolContent: bufferToolContent,
|
||||
emitEarlyToolDeltas: emitEarlyToolDeltas,
|
||||
streamToolCallIDs: map[int]string{},
|
||||
streamToolNames: map[int]string{},
|
||||
}
|
||||
}
|
||||
|
||||
@@ -98,7 +101,7 @@ func (s *chatStreamRuntime) sendDone() {
|
||||
|
||||
func (s *chatStreamRuntime) finalize(finishReason string) {
|
||||
finalThinking := s.thinking.String()
|
||||
finalText := sanitizeLeakedOutput(s.text.String())
|
||||
finalText := cleanVisibleOutput(s.text.String(), s.stripReferenceMarkers)
|
||||
detected := util.ParseStandaloneToolCallsDetailed(finalText, s.toolNames)
|
||||
if len(detected.Calls) > 0 && !s.toolCallsDoneEmitted {
|
||||
finishReason = "tool_calls"
|
||||
@@ -142,7 +145,7 @@ func (s *chatStreamRuntime) finalize(finishReason string) {
|
||||
if evt.Content == "" {
|
||||
continue
|
||||
}
|
||||
cleaned := sanitizeLeakedOutput(evt.Content)
|
||||
cleaned := cleanVisibleOutput(evt.Content, s.stripReferenceMarkers)
|
||||
if cleaned == "" {
|
||||
continue
|
||||
}
|
||||
@@ -203,10 +206,11 @@ func (s *chatStreamRuntime) onParsed(parsed sse.LineResult) streamengine.ParsedD
|
||||
newChoices := make([]map[string]any, 0, len(parsed.Parts))
|
||||
contentSeen := false
|
||||
for _, p := range parsed.Parts {
|
||||
if s.searchEnabled && sse.IsCitation(p.Text) {
|
||||
cleanedText := cleanVisibleOutput(p.Text, s.stripReferenceMarkers)
|
||||
if s.searchEnabled && sse.IsCitation(cleanedText) {
|
||||
continue
|
||||
}
|
||||
if p.Text == "" {
|
||||
if cleanedText == "" {
|
||||
continue
|
||||
}
|
||||
contentSeen = true
|
||||
@@ -217,15 +221,15 @@ func (s *chatStreamRuntime) onParsed(parsed sse.LineResult) streamengine.ParsedD
|
||||
}
|
||||
if p.Type == "thinking" {
|
||||
if s.thinkingEnabled {
|
||||
s.thinking.WriteString(p.Text)
|
||||
delta["reasoning_content"] = p.Text
|
||||
s.thinking.WriteString(cleanedText)
|
||||
delta["reasoning_content"] = cleanedText
|
||||
}
|
||||
} else {
|
||||
s.text.WriteString(p.Text)
|
||||
s.text.WriteString(cleanedText)
|
||||
if !s.bufferToolContent {
|
||||
delta["content"] = p.Text
|
||||
delta["content"] = cleanedText
|
||||
} else {
|
||||
events := processToolSieveChunk(&s.toolSieve, p.Text, s.toolNames)
|
||||
events := processToolSieveChunk(&s.toolSieve, cleanedText, s.toolNames)
|
||||
for _, evt := range events {
|
||||
if len(evt.ToolCallDeltas) > 0 {
|
||||
if !s.emitEarlyToolDeltas {
|
||||
@@ -264,7 +268,7 @@ func (s *chatStreamRuntime) onParsed(parsed sse.LineResult) streamengine.ParsedD
|
||||
continue
|
||||
}
|
||||
if evt.Content != "" {
|
||||
cleaned := sanitizeLeakedOutput(evt.Content)
|
||||
cleaned := cleanVisibleOutput(evt.Content, s.stripReferenceMarkers)
|
||||
if cleaned == "" {
|
||||
continue
|
||||
}
|
||||
|
||||
@@ -25,6 +25,7 @@ type DeepSeekCaller interface {
|
||||
type ConfigReader interface {
|
||||
ModelAliases() map[string]string
|
||||
CompatWideInputStrictOutput() bool
|
||||
CompatStripReferenceMarkers() bool
|
||||
ToolcallMode() string
|
||||
ToolcallEarlyEmitConfidence() string
|
||||
ResponsesStoreTTLSeconds() int
|
||||
|
||||
@@ -15,6 +15,7 @@ func (m mockOpenAIConfig) ModelAliases() map[string]string { return m.aliases }
|
||||
func (m mockOpenAIConfig) CompatWideInputStrictOutput() bool {
|
||||
return m.wideInput
|
||||
}
|
||||
func (m mockOpenAIConfig) CompatStripReferenceMarkers() bool { return true }
|
||||
func (m mockOpenAIConfig) ToolcallMode() string { return m.toolMode }
|
||||
func (m mockOpenAIConfig) ToolcallEarlyEmitConfidence() string { return m.earlyEmit }
|
||||
func (m mockOpenAIConfig) ResponsesStoreTTLSeconds() int { return m.responsesTTL }
|
||||
|
||||
@@ -104,9 +104,10 @@ func (h *Handler) handleNonStream(w http.ResponseWriter, ctx context.Context, re
|
||||
_ = ctx
|
||||
result := sse.CollectStream(resp, thinkingEnabled, true)
|
||||
|
||||
finalThinking := result.Thinking
|
||||
finalText := sanitizeLeakedOutput(result.Text)
|
||||
if writeUpstreamEmptyOutputError(w, result) {
|
||||
stripReferenceMarkers := h.compatStripReferenceMarkers()
|
||||
finalThinking := cleanVisibleOutput(result.Thinking, stripReferenceMarkers)
|
||||
finalText := cleanVisibleOutput(result.Text, stripReferenceMarkers)
|
||||
if writeUpstreamEmptyOutputError(w, finalThinking, finalText, result.ContentFilter) {
|
||||
return
|
||||
}
|
||||
respBody := openaifmt.BuildChatCompletion(completionID, model, finalPrompt, finalThinking, finalText, toolNames)
|
||||
@@ -141,6 +142,7 @@ func (h *Handler) handleStream(w http.ResponseWriter, r *http.Request, resp *htt
|
||||
created := time.Now().Unix()
|
||||
bufferToolContent := len(toolNames) > 0
|
||||
emitEarlyToolDeltas := h.toolcallFeatureMatchEnabled() && h.toolcallEarlyEmitHighConfidence()
|
||||
stripReferenceMarkers := h.compatStripReferenceMarkers()
|
||||
initialType := "text"
|
||||
if thinkingEnabled {
|
||||
initialType = "thinking"
|
||||
@@ -156,6 +158,7 @@ func (h *Handler) handleStream(w http.ResponseWriter, r *http.Request, resp *htt
|
||||
finalPrompt,
|
||||
thinkingEnabled,
|
||||
searchEnabled,
|
||||
stripReferenceMarkers,
|
||||
toolNames,
|
||||
bufferToolContent,
|
||||
emitEarlyToolDeltas,
|
||||
|
||||
@@ -28,6 +28,13 @@ type Handler struct {
|
||||
responses *responseStore
|
||||
}
|
||||
|
||||
func (h *Handler) compatStripReferenceMarkers() bool {
|
||||
if h == nil || h.Store == nil {
|
||||
return true
|
||||
}
|
||||
return h.Store.CompatStripReferenceMarkers()
|
||||
}
|
||||
|
||||
type streamLease struct {
|
||||
Auth *auth.RequestAuth
|
||||
ExpiresAt time.Time
|
||||
|
||||
13
internal/adapter/openai/output_clean.go
Normal file
13
internal/adapter/openai/output_clean.go
Normal file
@@ -0,0 +1,13 @@
|
||||
package openai
|
||||
|
||||
import textclean "ds2api/internal/textclean"
|
||||
|
||||
func cleanVisibleOutput(text string, stripReferenceMarkers bool) string {
|
||||
if text == "" {
|
||||
return text
|
||||
}
|
||||
if stripReferenceMarkers {
|
||||
text = textclean.StripReferenceMarkers(text)
|
||||
}
|
||||
return sanitizeLeakedOutput(text)
|
||||
}
|
||||
@@ -113,8 +113,10 @@ func (h *Handler) handleResponsesNonStream(w http.ResponseWriter, resp *http.Res
|
||||
return
|
||||
}
|
||||
result := sse.CollectStream(resp, thinkingEnabled, true)
|
||||
sanitizedText := sanitizeLeakedOutput(result.Text)
|
||||
if writeUpstreamEmptyOutputError(w, result) {
|
||||
stripReferenceMarkers := h.compatStripReferenceMarkers()
|
||||
sanitizedThinking := cleanVisibleOutput(result.Thinking, stripReferenceMarkers)
|
||||
sanitizedText := cleanVisibleOutput(result.Text, stripReferenceMarkers)
|
||||
if writeUpstreamEmptyOutputError(w, sanitizedThinking, sanitizedText, result.ContentFilter) {
|
||||
return
|
||||
}
|
||||
textParsed := util.ParseStandaloneToolCallsDetailed(sanitizedText, toolNames)
|
||||
@@ -126,7 +128,7 @@ func (h *Handler) handleResponsesNonStream(w http.ResponseWriter, resp *http.Res
|
||||
return
|
||||
}
|
||||
|
||||
responseObj := openaifmt.BuildResponseObject(responseID, model, finalPrompt, result.Thinking, sanitizedText, toolNames)
|
||||
responseObj := openaifmt.BuildResponseObject(responseID, model, finalPrompt, sanitizedThinking, sanitizedText, toolNames)
|
||||
if result.OutputTokens > 0 {
|
||||
if usage, ok := responseObj["usage"].(map[string]any); ok {
|
||||
usage["output_tokens"] = result.OutputTokens
|
||||
@@ -159,6 +161,7 @@ func (h *Handler) handleResponsesStream(w http.ResponseWriter, r *http.Request,
|
||||
}
|
||||
bufferToolContent := len(toolNames) > 0
|
||||
emitEarlyToolDeltas := h.toolcallFeatureMatchEnabled() && h.toolcallEarlyEmitHighConfidence()
|
||||
stripReferenceMarkers := h.compatStripReferenceMarkers()
|
||||
|
||||
streamRuntime := newResponsesStreamRuntime(
|
||||
w,
|
||||
@@ -169,6 +172,7 @@ func (h *Handler) handleResponsesStream(w http.ResponseWriter, r *http.Request,
|
||||
finalPrompt,
|
||||
thinkingEnabled,
|
||||
searchEnabled,
|
||||
stripReferenceMarkers,
|
||||
toolNames,
|
||||
bufferToolContent,
|
||||
emitEarlyToolDeltas,
|
||||
|
||||
@@ -23,8 +23,9 @@ type responsesStreamRuntime struct {
|
||||
traceID string
|
||||
toolChoice util.ToolChoicePolicy
|
||||
|
||||
thinkingEnabled bool
|
||||
searchEnabled bool
|
||||
thinkingEnabled bool
|
||||
searchEnabled bool
|
||||
stripReferenceMarkers bool
|
||||
|
||||
bufferToolContent bool
|
||||
emitEarlyToolDeltas bool
|
||||
@@ -63,6 +64,7 @@ func newResponsesStreamRuntime(
|
||||
finalPrompt string,
|
||||
thinkingEnabled bool,
|
||||
searchEnabled bool,
|
||||
stripReferenceMarkers bool,
|
||||
toolNames []string,
|
||||
bufferToolContent bool,
|
||||
emitEarlyToolDeltas bool,
|
||||
@@ -71,34 +73,35 @@ func newResponsesStreamRuntime(
|
||||
persistResponse func(obj map[string]any),
|
||||
) *responsesStreamRuntime {
|
||||
return &responsesStreamRuntime{
|
||||
w: w,
|
||||
rc: rc,
|
||||
canFlush: canFlush,
|
||||
responseID: responseID,
|
||||
model: model,
|
||||
finalPrompt: finalPrompt,
|
||||
thinkingEnabled: thinkingEnabled,
|
||||
searchEnabled: searchEnabled,
|
||||
toolNames: toolNames,
|
||||
bufferToolContent: bufferToolContent,
|
||||
emitEarlyToolDeltas: emitEarlyToolDeltas,
|
||||
streamToolCallIDs: map[int]string{},
|
||||
functionItemIDs: map[int]string{},
|
||||
functionOutputIDs: map[int]int{},
|
||||
functionArgs: map[int]string{},
|
||||
functionDone: map[int]bool{},
|
||||
functionAdded: map[int]bool{},
|
||||
functionNames: map[int]string{},
|
||||
messageOutputID: -1,
|
||||
toolChoice: toolChoice,
|
||||
traceID: traceID,
|
||||
persistResponse: persistResponse,
|
||||
w: w,
|
||||
rc: rc,
|
||||
canFlush: canFlush,
|
||||
responseID: responseID,
|
||||
model: model,
|
||||
finalPrompt: finalPrompt,
|
||||
thinkingEnabled: thinkingEnabled,
|
||||
searchEnabled: searchEnabled,
|
||||
stripReferenceMarkers: stripReferenceMarkers,
|
||||
toolNames: toolNames,
|
||||
bufferToolContent: bufferToolContent,
|
||||
emitEarlyToolDeltas: emitEarlyToolDeltas,
|
||||
streamToolCallIDs: map[int]string{},
|
||||
functionItemIDs: map[int]string{},
|
||||
functionOutputIDs: map[int]int{},
|
||||
functionArgs: map[int]string{},
|
||||
functionDone: map[int]bool{},
|
||||
functionAdded: map[int]bool{},
|
||||
functionNames: map[int]string{},
|
||||
messageOutputID: -1,
|
||||
toolChoice: toolChoice,
|
||||
traceID: traceID,
|
||||
persistResponse: persistResponse,
|
||||
}
|
||||
}
|
||||
|
||||
func (s *responsesStreamRuntime) finalize() {
|
||||
finalThinking := s.thinking.String()
|
||||
finalText := sanitizeLeakedOutput(s.text.String())
|
||||
finalText := cleanVisibleOutput(s.text.String(), s.stripReferenceMarkers)
|
||||
|
||||
if s.bufferToolContent {
|
||||
s.processToolStreamEvents(flushToolSieve(&s.sieve, s.toolNames), true)
|
||||
@@ -190,10 +193,11 @@ func (s *responsesStreamRuntime) onParsed(parsed sse.LineResult) streamengine.Pa
|
||||
|
||||
contentSeen := false
|
||||
for _, p := range parsed.Parts {
|
||||
if p.Text == "" {
|
||||
cleanedText := cleanVisibleOutput(p.Text, s.stripReferenceMarkers)
|
||||
if cleanedText == "" {
|
||||
continue
|
||||
}
|
||||
if p.Type != "thinking" && s.searchEnabled && sse.IsCitation(p.Text) {
|
||||
if p.Type != "thinking" && s.searchEnabled && sse.IsCitation(cleanedText) {
|
||||
continue
|
||||
}
|
||||
contentSeen = true
|
||||
@@ -201,15 +205,11 @@ func (s *responsesStreamRuntime) onParsed(parsed sse.LineResult) streamengine.Pa
|
||||
if !s.thinkingEnabled {
|
||||
continue
|
||||
}
|
||||
s.thinking.WriteString(p.Text)
|
||||
s.sendEvent("response.reasoning.delta", openaifmt.BuildResponsesReasoningDeltaPayload(s.responseID, p.Text))
|
||||
s.thinking.WriteString(cleanedText)
|
||||
s.sendEvent("response.reasoning.delta", openaifmt.BuildResponsesReasoningDeltaPayload(s.responseID, cleanedText))
|
||||
continue
|
||||
}
|
||||
|
||||
cleanedText := sanitizeLeakedOutput(p.Text)
|
||||
if cleanedText == "" {
|
||||
continue
|
||||
}
|
||||
s.text.WriteString(cleanedText)
|
||||
if !s.bufferToolContent {
|
||||
s.emitTextDelta(cleanedText)
|
||||
|
||||
@@ -69,7 +69,7 @@ func (s *responsesStreamRuntime) ensureMessageContentPartAdded() {
|
||||
}
|
||||
|
||||
func (s *responsesStreamRuntime) emitTextDelta(content string) {
|
||||
if strings.TrimSpace(content) == "" {
|
||||
if content == "" {
|
||||
return
|
||||
}
|
||||
s.ensureMessageContentPartAdded()
|
||||
|
||||
@@ -83,13 +83,13 @@ func (s *responsesStreamRuntime) buildCompletedResponseObject(finalThinking, fin
|
||||
})
|
||||
} else if len(calls) == 0 {
|
||||
content := make([]map[string]any, 0, 2)
|
||||
if strings.TrimSpace(finalThinking) != "" {
|
||||
if finalThinking != "" {
|
||||
content = append(content, map[string]any{
|
||||
"type": "reasoning",
|
||||
"text": finalThinking,
|
||||
})
|
||||
}
|
||||
if strings.TrimSpace(finalText) != "" {
|
||||
if finalText != "" {
|
||||
content = append(content, map[string]any{
|
||||
"type": "output_text",
|
||||
"text": finalText,
|
||||
@@ -136,10 +136,10 @@ func (s *responsesStreamRuntime) buildCompletedResponseObject(finalThinking, fin
|
||||
}
|
||||
|
||||
outputText := s.visibleText.String()
|
||||
if strings.TrimSpace(outputText) == "" && len(calls) == 0 {
|
||||
if strings.TrimSpace(finalText) != "" {
|
||||
if outputText == "" && len(calls) == 0 {
|
||||
if finalText != "" {
|
||||
outputText = finalText
|
||||
} else if strings.TrimSpace(finalThinking) != "" {
|
||||
} else if finalThinking != "" {
|
||||
outputText = finalThinking
|
||||
}
|
||||
}
|
||||
|
||||
@@ -48,7 +48,7 @@ func (s *toolStreamSieveState) resetIncrementalToolState() {
|
||||
}
|
||||
|
||||
func (s *toolStreamSieveState) noteText(content string) {
|
||||
if strings.TrimSpace(content) == "" {
|
||||
if content == "" {
|
||||
return
|
||||
}
|
||||
s.recentTextTail = appendTail(s.recentTextTail, content, toolSieveContextTailLimit)
|
||||
|
||||
@@ -1,17 +1,12 @@
|
||||
package openai
|
||||
|
||||
import (
|
||||
"net/http"
|
||||
"strings"
|
||||
import "net/http"
|
||||
|
||||
"ds2api/internal/sse"
|
||||
)
|
||||
|
||||
func writeUpstreamEmptyOutputError(w http.ResponseWriter, result sse.CollectResult) bool {
|
||||
if strings.TrimSpace(result.Thinking) != "" || strings.TrimSpace(sanitizeLeakedOutput(result.Text)) != "" {
|
||||
func writeUpstreamEmptyOutputError(w http.ResponseWriter, thinking, text string, contentFilter bool) bool {
|
||||
if thinking != "" || text != "" {
|
||||
return false
|
||||
}
|
||||
if result.ContentFilter {
|
||||
if contentFilter {
|
||||
writeOpenAIErrorWithCode(w, http.StatusBadRequest, "Upstream content filtered the response and returned no output.", "content_filter")
|
||||
return true
|
||||
}
|
||||
|
||||
@@ -99,10 +99,13 @@ func (h *Handler) handleVercelStreamPrepare(w http.ResponseWriter, r *http.Reque
|
||||
"final_prompt": stdReq.FinalPrompt,
|
||||
"thinking_enabled": stdReq.Thinking,
|
||||
"search_enabled": stdReq.Search,
|
||||
"tool_names": stdReq.ToolNames,
|
||||
"deepseek_token": a.DeepSeekToken,
|
||||
"pow_header": powHeader,
|
||||
"payload": payload,
|
||||
"compat": map[string]any{
|
||||
"strip_reference_markers": h.compatStripReferenceMarkers(),
|
||||
},
|
||||
"tool_names": stdReq.ToolNames,
|
||||
"deepseek_token": a.DeepSeekToken,
|
||||
"pow_header": powHeader,
|
||||
"payload": payload,
|
||||
})
|
||||
}
|
||||
|
||||
|
||||
@@ -32,6 +32,7 @@ type ConfigStore interface {
|
||||
RuntimeAccountMaxQueue(defaultSize int) int
|
||||
RuntimeGlobalMaxInflight(defaultSize int) int
|
||||
RuntimeTokenRefreshIntervalHours() int
|
||||
CompatStripReferenceMarkers() bool
|
||||
AutoDeleteSessions() bool
|
||||
}
|
||||
|
||||
|
||||
@@ -21,10 +21,11 @@ func boolFrom(v any) bool {
|
||||
}
|
||||
}
|
||||
|
||||
func parseSettingsUpdateRequest(req map[string]any) (*config.AdminConfig, *config.RuntimeConfig, *config.ResponsesConfig, *config.EmbeddingsConfig, *config.AutoDeleteConfig, map[string]string, map[string]string, error) {
|
||||
func parseSettingsUpdateRequest(req map[string]any) (*config.AdminConfig, *config.RuntimeConfig, *config.CompatConfig, *config.ResponsesConfig, *config.EmbeddingsConfig, *config.AutoDeleteConfig, map[string]string, map[string]string, error) {
|
||||
var (
|
||||
adminCfg *config.AdminConfig
|
||||
runtimeCfg *config.RuntimeConfig
|
||||
compatCfg *config.CompatConfig
|
||||
respCfg *config.ResponsesConfig
|
||||
embCfg *config.EmbeddingsConfig
|
||||
autoDeleteCfg *config.AutoDeleteConfig
|
||||
@@ -37,7 +38,7 @@ func parseSettingsUpdateRequest(req map[string]any) (*config.AdminConfig, *confi
|
||||
if v, exists := raw["jwt_expire_hours"]; exists {
|
||||
n := intFrom(v)
|
||||
if n < 1 || n > 720 {
|
||||
return nil, nil, nil, nil, nil, nil, nil, fmt.Errorf("admin.jwt_expire_hours must be between 1 and 720")
|
||||
return nil, nil, nil, nil, nil, nil, nil, nil, fmt.Errorf("admin.jwt_expire_hours must be between 1 and 720")
|
||||
}
|
||||
cfg.JWTExpireHours = n
|
||||
}
|
||||
@@ -49,43 +50,56 @@ func parseSettingsUpdateRequest(req map[string]any) (*config.AdminConfig, *confi
|
||||
if v, exists := raw["account_max_inflight"]; exists {
|
||||
n := intFrom(v)
|
||||
if n < 1 || n > 256 {
|
||||
return nil, nil, nil, nil, nil, nil, nil, fmt.Errorf("runtime.account_max_inflight must be between 1 and 256")
|
||||
return nil, nil, nil, nil, nil, nil, nil, nil, fmt.Errorf("runtime.account_max_inflight must be between 1 and 256")
|
||||
}
|
||||
cfg.AccountMaxInflight = n
|
||||
}
|
||||
if v, exists := raw["account_max_queue"]; exists {
|
||||
n := intFrom(v)
|
||||
if n < 1 || n > 200000 {
|
||||
return nil, nil, nil, nil, nil, nil, nil, fmt.Errorf("runtime.account_max_queue must be between 1 and 200000")
|
||||
return nil, nil, nil, nil, nil, nil, nil, nil, fmt.Errorf("runtime.account_max_queue must be between 1 and 200000")
|
||||
}
|
||||
cfg.AccountMaxQueue = n
|
||||
}
|
||||
if v, exists := raw["global_max_inflight"]; exists {
|
||||
n := intFrom(v)
|
||||
if n < 1 || n > 200000 {
|
||||
return nil, nil, nil, nil, nil, nil, nil, fmt.Errorf("runtime.global_max_inflight must be between 1 and 200000")
|
||||
return nil, nil, nil, nil, nil, nil, nil, nil, fmt.Errorf("runtime.global_max_inflight must be between 1 and 200000")
|
||||
}
|
||||
cfg.GlobalMaxInflight = n
|
||||
}
|
||||
if v, exists := raw["token_refresh_interval_hours"]; exists {
|
||||
n := intFrom(v)
|
||||
if n < 1 || n > 720 {
|
||||
return nil, nil, nil, nil, nil, nil, nil, fmt.Errorf("runtime.token_refresh_interval_hours must be between 1 and 720")
|
||||
return nil, nil, nil, nil, nil, nil, nil, nil, fmt.Errorf("runtime.token_refresh_interval_hours must be between 1 and 720")
|
||||
}
|
||||
cfg.TokenRefreshIntervalHours = n
|
||||
}
|
||||
if cfg.AccountMaxInflight > 0 && cfg.GlobalMaxInflight > 0 && cfg.GlobalMaxInflight < cfg.AccountMaxInflight {
|
||||
return nil, nil, nil, nil, nil, nil, nil, fmt.Errorf("runtime.global_max_inflight must be >= runtime.account_max_inflight")
|
||||
return nil, nil, nil, nil, nil, nil, nil, nil, fmt.Errorf("runtime.global_max_inflight must be >= runtime.account_max_inflight")
|
||||
}
|
||||
runtimeCfg = cfg
|
||||
}
|
||||
|
||||
if raw, ok := req["compat"].(map[string]any); ok {
|
||||
cfg := &config.CompatConfig{}
|
||||
if v, exists := raw["wide_input_strict_output"]; exists {
|
||||
b := boolFrom(v)
|
||||
cfg.WideInputStrictOutput = &b
|
||||
}
|
||||
if v, exists := raw["strip_reference_markers"]; exists {
|
||||
b := boolFrom(v)
|
||||
cfg.StripReferenceMarkers = &b
|
||||
}
|
||||
compatCfg = cfg
|
||||
}
|
||||
|
||||
if raw, ok := req["responses"].(map[string]any); ok {
|
||||
cfg := &config.ResponsesConfig{}
|
||||
if v, exists := raw["store_ttl_seconds"]; exists {
|
||||
n := intFrom(v)
|
||||
if n < 30 || n > 86400 {
|
||||
return nil, nil, nil, nil, nil, nil, nil, fmt.Errorf("responses.store_ttl_seconds must be between 30 and 86400")
|
||||
return nil, nil, nil, nil, nil, nil, nil, nil, fmt.Errorf("responses.store_ttl_seconds must be between 30 and 86400")
|
||||
}
|
||||
cfg.StoreTTLSeconds = n
|
||||
}
|
||||
@@ -133,5 +147,5 @@ func parseSettingsUpdateRequest(req map[string]any) (*config.AdminConfig, *confi
|
||||
autoDeleteCfg = cfg
|
||||
}
|
||||
|
||||
return adminCfg, runtimeCfg, respCfg, embCfg, autoDeleteCfg, claudeMap, aliasMap, nil
|
||||
return adminCfg, runtimeCfg, compatCfg, respCfg, embCfg, autoDeleteCfg, claudeMap, aliasMap, nil
|
||||
}
|
||||
|
||||
@@ -26,6 +26,7 @@ func (h *Handler) getSettings(w http.ResponseWriter, _ *http.Request) {
|
||||
"global_max_inflight": h.Store.RuntimeGlobalMaxInflight(recommended),
|
||||
"token_refresh_interval_hours": h.Store.RuntimeTokenRefreshIntervalHours(),
|
||||
},
|
||||
"compat": snap.Compat,
|
||||
"responses": snap.Responses,
|
||||
"embeddings": snap.Embeddings,
|
||||
"auto_delete": snap.AutoDelete,
|
||||
|
||||
@@ -17,7 +17,7 @@ func (h *Handler) updateSettings(w http.ResponseWriter, r *http.Request) {
|
||||
return
|
||||
}
|
||||
|
||||
adminCfg, runtimeCfg, responsesCfg, embeddingsCfg, autoDeleteCfg, claudeMap, aliasMap, err := parseSettingsUpdateRequest(req)
|
||||
adminCfg, runtimeCfg, compatCfg, responsesCfg, embeddingsCfg, autoDeleteCfg, claudeMap, aliasMap, err := parseSettingsUpdateRequest(req)
|
||||
if err != nil {
|
||||
writeJSON(w, http.StatusBadRequest, map[string]any{"detail": err.Error()})
|
||||
return
|
||||
@@ -49,6 +49,14 @@ func (h *Handler) updateSettings(w http.ResponseWriter, r *http.Request) {
|
||||
c.Runtime.TokenRefreshIntervalHours = runtimeCfg.TokenRefreshIntervalHours
|
||||
}
|
||||
}
|
||||
if compatCfg != nil {
|
||||
if compatCfg.WideInputStrictOutput != nil {
|
||||
c.Compat.WideInputStrictOutput = compatCfg.WideInputStrictOutput
|
||||
}
|
||||
if compatCfg.StripReferenceMarkers != nil {
|
||||
c.Compat.StripReferenceMarkers = compatCfg.StripReferenceMarkers
|
||||
}
|
||||
}
|
||||
if responsesCfg != nil && responsesCfg.StoreTTLSeconds > 0 {
|
||||
c.Responses.StoreTTLSeconds = responsesCfg.StoreTTLSeconds
|
||||
}
|
||||
|
||||
@@ -35,7 +35,7 @@ func (c Config) MarshalJSON() ([]byte, error) {
|
||||
if c.Runtime.AccountMaxInflight > 0 || c.Runtime.AccountMaxQueue > 0 || c.Runtime.GlobalMaxInflight > 0 || c.Runtime.TokenRefreshIntervalHours > 0 {
|
||||
m["runtime"] = c.Runtime
|
||||
}
|
||||
if c.Compat.WideInputStrictOutput != nil {
|
||||
if c.Compat.WideInputStrictOutput != nil || c.Compat.StripReferenceMarkers != nil {
|
||||
m["compat"] = c.Compat
|
||||
}
|
||||
if c.Responses.StoreTTLSeconds > 0 {
|
||||
@@ -137,6 +137,7 @@ func (c Config) Clone() Config {
|
||||
Runtime: c.Runtime,
|
||||
Compat: CompatConfig{
|
||||
WideInputStrictOutput: cloneBoolPtr(c.Compat.WideInputStrictOutput),
|
||||
StripReferenceMarkers: cloneBoolPtr(c.Compat.StripReferenceMarkers),
|
||||
},
|
||||
Responses: c.Responses,
|
||||
Embeddings: c.Embeddings,
|
||||
|
||||
@@ -52,6 +52,7 @@ func (c *Config) DropInvalidAccounts() {
|
||||
|
||||
type CompatConfig struct {
|
||||
WideInputStrictOutput *bool `json:"wide_input_strict_output,omitempty"`
|
||||
StripReferenceMarkers *bool `json:"strip_reference_markers,omitempty"`
|
||||
}
|
||||
|
||||
type AdminConfig struct {
|
||||
|
||||
@@ -97,6 +97,8 @@ func TestLowerFunction(t *testing.T) {
|
||||
// ─── Config.MarshalJSON / UnmarshalJSON roundtrip ────────────────────
|
||||
|
||||
func TestConfigJSONRoundtrip(t *testing.T) {
|
||||
trueVal := true
|
||||
falseVal := false
|
||||
cfg := Config{
|
||||
Keys: []string{"key1", "key2"},
|
||||
Accounts: []Account{{Email: "user@example.com", Password: "pass", Token: "tok"}},
|
||||
@@ -107,6 +109,10 @@ func TestConfigJSONRoundtrip(t *testing.T) {
|
||||
Runtime: RuntimeConfig{
|
||||
TokenRefreshIntervalHours: 12,
|
||||
},
|
||||
Compat: CompatConfig{
|
||||
WideInputStrictOutput: &trueVal,
|
||||
StripReferenceMarkers: &falseVal,
|
||||
},
|
||||
VercelSyncHash: "hash123",
|
||||
VercelSyncTime: 1234567890,
|
||||
AdditionalFields: map[string]any{
|
||||
@@ -136,6 +142,12 @@ func TestConfigJSONRoundtrip(t *testing.T) {
|
||||
if decoded.Runtime.TokenRefreshIntervalHours != 12 {
|
||||
t.Fatalf("unexpected runtime refresh interval: %#v", decoded.Runtime.TokenRefreshIntervalHours)
|
||||
}
|
||||
if decoded.Compat.WideInputStrictOutput == nil || !*decoded.Compat.WideInputStrictOutput {
|
||||
t.Fatalf("unexpected compat wide_input_strict_output: %#v", decoded.Compat.WideInputStrictOutput)
|
||||
}
|
||||
if decoded.Compat.StripReferenceMarkers == nil || *decoded.Compat.StripReferenceMarkers {
|
||||
t.Fatalf("unexpected compat strip_reference_markers: %#v", decoded.Compat.StripReferenceMarkers)
|
||||
}
|
||||
if decoded.VercelSyncHash != "hash123" {
|
||||
t.Fatalf("unexpected vercel sync hash: %q", decoded.VercelSyncHash)
|
||||
}
|
||||
@@ -162,12 +174,16 @@ func TestConfigUnmarshalJSONPreservesUnknownFields(t *testing.T) {
|
||||
// ─── Config.Clone ────────────────────────────────────────────────────
|
||||
|
||||
func TestConfigCloneIsDeepCopy(t *testing.T) {
|
||||
falseVal := false
|
||||
cfg := Config{
|
||||
Keys: []string{"key1"},
|
||||
Accounts: []Account{{Email: "user@test.com", Token: "token"}},
|
||||
ClaudeMapping: map[string]string{
|
||||
"fast": "deepseek-chat",
|
||||
},
|
||||
Compat: CompatConfig{
|
||||
StripReferenceMarkers: &falseVal,
|
||||
},
|
||||
AdditionalFields: map[string]any{"custom": "value"},
|
||||
}
|
||||
|
||||
@@ -177,6 +193,9 @@ func TestConfigCloneIsDeepCopy(t *testing.T) {
|
||||
cfg.Keys[0] = "modified"
|
||||
cfg.Accounts[0].Email = "modified@test.com"
|
||||
cfg.ClaudeMapping["fast"] = "modified-model"
|
||||
if cfg.Compat.StripReferenceMarkers != nil {
|
||||
*cfg.Compat.StripReferenceMarkers = true
|
||||
}
|
||||
|
||||
// Cloned should not be affected
|
||||
if cloned.Keys[0] != "key1" {
|
||||
@@ -188,6 +207,9 @@ func TestConfigCloneIsDeepCopy(t *testing.T) {
|
||||
if cloned.ClaudeMapping["fast"] != "deepseek-chat" {
|
||||
t.Fatalf("clone claude mapping was affected: %#v", cloned.ClaudeMapping)
|
||||
}
|
||||
if cloned.Compat.StripReferenceMarkers == nil || *cloned.Compat.StripReferenceMarkers {
|
||||
t.Fatalf("clone compat was affected: %#v", cloned.Compat.StripReferenceMarkers)
|
||||
}
|
||||
}
|
||||
|
||||
func TestConfigCloneNilMaps(t *testing.T) {
|
||||
@@ -359,6 +381,39 @@ func TestStoreCompatWideInputStrictOutputCanDisable(t *testing.T) {
|
||||
}
|
||||
}
|
||||
|
||||
func TestStoreCompatStripReferenceMarkersDefaultTrue(t *testing.T) {
|
||||
t.Setenv("DS2API_CONFIG_JSON", `{"keys":["k1"],"accounts":[]}`)
|
||||
store := LoadStore()
|
||||
if !store.CompatStripReferenceMarkers() {
|
||||
t.Fatal("expected default strip_reference_markers=true when unset")
|
||||
}
|
||||
}
|
||||
|
||||
func TestStoreCompatStripReferenceMarkersCanDisable(t *testing.T) {
|
||||
t.Setenv("DS2API_CONFIG_JSON", `{"keys":["k1"],"accounts":[],"compat":{"strip_reference_markers":false}}`)
|
||||
store := LoadStore()
|
||||
if store.CompatStripReferenceMarkers() {
|
||||
t.Fatal("expected strip_reference_markers=false when explicitly configured")
|
||||
}
|
||||
|
||||
snap := store.Snapshot()
|
||||
data, err := snap.MarshalJSON()
|
||||
if err != nil {
|
||||
t.Fatalf("marshal failed: %v", err)
|
||||
}
|
||||
var out map[string]any
|
||||
if err := json.Unmarshal(data, &out); err != nil {
|
||||
t.Fatalf("decode failed: %v", err)
|
||||
}
|
||||
rawCompat, ok := out["compat"].(map[string]any)
|
||||
if !ok {
|
||||
t.Fatalf("expected compat in marshaled output, got %#v", out)
|
||||
}
|
||||
if rawCompat["strip_reference_markers"] != false {
|
||||
t.Fatalf("expected explicit false in compat, got %#v", rawCompat)
|
||||
}
|
||||
}
|
||||
|
||||
func TestStoreIsEnvBacked(t *testing.T) {
|
||||
t.Setenv("DS2API_CONFIG_JSON", `{"keys":["k1"],"accounts":[]}`)
|
||||
store := LoadStore()
|
||||
|
||||
@@ -42,6 +42,15 @@ func (s *Store) CompatWideInputStrictOutput() bool {
|
||||
return *s.cfg.Compat.WideInputStrictOutput
|
||||
}
|
||||
|
||||
func (s *Store) CompatStripReferenceMarkers() bool {
|
||||
s.mu.RLock()
|
||||
defer s.mu.RUnlock()
|
||||
if s.cfg.Compat.StripReferenceMarkers == nil {
|
||||
return true
|
||||
}
|
||||
return *s.cfg.Compat.StripReferenceMarkers
|
||||
}
|
||||
|
||||
func (s *Store) ToolcallMode() string {
|
||||
return "feature_match"
|
||||
}
|
||||
|
||||
@@ -7,6 +7,7 @@ const {
|
||||
parseChunkForContent,
|
||||
extractContentRecursive,
|
||||
shouldSkipPath,
|
||||
stripReferenceMarkers,
|
||||
} = require('./sse_parse');
|
||||
const {
|
||||
resolveToolcallPolicy,
|
||||
@@ -100,6 +101,7 @@ module.exports.__test = {
|
||||
parseChunkForContent,
|
||||
extractContentRecursive,
|
||||
shouldSkipPath,
|
||||
stripReferenceMarkers,
|
||||
asString,
|
||||
resolveToolcallPolicy,
|
||||
formatIncrementalToolCallDeltas,
|
||||
|
||||
@@ -5,7 +5,7 @@ const {
|
||||
SKIP_EXACT_PATHS,
|
||||
} = require('../shared/deepseek-constants');
|
||||
|
||||
function parseChunkForContent(chunk, thinkingEnabled, currentType) {
|
||||
function parseChunkForContent(chunk, thinkingEnabled, currentType, stripReferenceMarkers = true) {
|
||||
if (!chunk || typeof chunk !== 'object' || !Object.prototype.hasOwnProperty.call(chunk, 'v')) {
|
||||
return { parts: [], finished: false, newType: currentType };
|
||||
}
|
||||
@@ -26,7 +26,7 @@ function parseChunkForContent(chunk, thinkingEnabled, currentType) {
|
||||
continue;
|
||||
}
|
||||
const fragType = asString(frag.type).toUpperCase();
|
||||
const content = asString(frag.content);
|
||||
const content = asContentString(frag.content, stripReferenceMarkers);
|
||||
if (!content) {
|
||||
continue;
|
||||
}
|
||||
@@ -76,14 +76,15 @@ function parseChunkForContent(chunk, thinkingEnabled, currentType) {
|
||||
if (val === 'FINISHED' && (!pathValue || pathValue === 'status')) {
|
||||
return { parts: [], finished: true, newType };
|
||||
}
|
||||
if (val) {
|
||||
parts.push({ text: val, type: partType });
|
||||
const content = asContentString(val, stripReferenceMarkers);
|
||||
if (content) {
|
||||
parts.push({ text: content, type: partType });
|
||||
}
|
||||
return { parts, finished: false, newType };
|
||||
}
|
||||
|
||||
if (Array.isArray(val)) {
|
||||
const extracted = extractContentRecursive(val, partType);
|
||||
const extracted = extractContentRecursive(val, partType, stripReferenceMarkers);
|
||||
if (extracted.finished) {
|
||||
return { parts: [], finished: true, newType };
|
||||
}
|
||||
@@ -98,7 +99,7 @@ function parseChunkForContent(chunk, thinkingEnabled, currentType) {
|
||||
if (!frag || typeof frag !== 'object') {
|
||||
continue;
|
||||
}
|
||||
const content = asString(frag.content);
|
||||
const content = asContentString(frag.content, stripReferenceMarkers);
|
||||
if (!content) {
|
||||
continue;
|
||||
}
|
||||
@@ -118,7 +119,7 @@ function parseChunkForContent(chunk, thinkingEnabled, currentType) {
|
||||
return { parts, finished: false, newType };
|
||||
}
|
||||
|
||||
function extractContentRecursive(items, defaultType) {
|
||||
function extractContentRecursive(items, defaultType, stripReferenceMarkers = true) {
|
||||
const parts = [];
|
||||
for (const it of items) {
|
||||
if (!it || typeof it !== 'object') {
|
||||
@@ -135,7 +136,7 @@ function extractContentRecursive(items, defaultType) {
|
||||
if (shouldSkipPath(itemPath)) {
|
||||
continue;
|
||||
}
|
||||
const content = asString(it.content);
|
||||
const content = asContentString(it.content, stripReferenceMarkers);
|
||||
if (content) {
|
||||
const typeName = asString(it.type).toUpperCase();
|
||||
if (typeName === 'THINK' || typeName === 'THINKING') {
|
||||
@@ -157,7 +158,10 @@ function extractContentRecursive(items, defaultType) {
|
||||
|
||||
if (typeof itemV === 'string') {
|
||||
if (itemV && itemV !== 'FINISHED') {
|
||||
parts.push({ text: itemV, type: partType });
|
||||
const content = asContentString(itemV, stripReferenceMarkers);
|
||||
if (content) {
|
||||
parts.push({ text: content, type: partType });
|
||||
}
|
||||
}
|
||||
continue;
|
||||
}
|
||||
@@ -168,14 +172,17 @@ function extractContentRecursive(items, defaultType) {
|
||||
for (const inner of itemV) {
|
||||
if (typeof inner === 'string') {
|
||||
if (inner) {
|
||||
parts.push({ text: inner, type: partType });
|
||||
const content = asContentString(inner, stripReferenceMarkers);
|
||||
if (content) {
|
||||
parts.push({ text: content, type: partType });
|
||||
}
|
||||
}
|
||||
continue;
|
||||
}
|
||||
if (!inner || typeof inner !== 'object') {
|
||||
continue;
|
||||
}
|
||||
const ct = asString(inner.content);
|
||||
const ct = asContentString(inner.content, stripReferenceMarkers);
|
||||
if (!ct) {
|
||||
continue;
|
||||
}
|
||||
@@ -218,6 +225,40 @@ function isCitation(text) {
|
||||
return asString(text).trim().startsWith('[citation:');
|
||||
}
|
||||
|
||||
function asContentString(v, stripReferenceMarkers = true) {
|
||||
if (typeof v === 'string') {
|
||||
return stripReferenceMarkers ? stripReferenceMarkersText(v) : v;
|
||||
}
|
||||
if (Array.isArray(v)) {
|
||||
let out = '';
|
||||
for (const item of v) {
|
||||
out += asContentString(item, stripReferenceMarkers);
|
||||
}
|
||||
return out;
|
||||
}
|
||||
if (v && typeof v === 'object') {
|
||||
if (Object.prototype.hasOwnProperty.call(v, 'content')) {
|
||||
return asContentString(v.content, stripReferenceMarkers);
|
||||
}
|
||||
if (Object.prototype.hasOwnProperty.call(v, 'v')) {
|
||||
return asContentString(v.v, stripReferenceMarkers);
|
||||
}
|
||||
return '';
|
||||
}
|
||||
if (v == null) {
|
||||
return '';
|
||||
}
|
||||
const text = String(v);
|
||||
return stripReferenceMarkers ? stripReferenceMarkersText(text) : text;
|
||||
}
|
||||
|
||||
function stripReferenceMarkersText(text) {
|
||||
if (!text) {
|
||||
return text;
|
||||
}
|
||||
return text.replace(/\[reference:\s*\d+\]/gi, '');
|
||||
}
|
||||
|
||||
function asString(v) {
|
||||
if (typeof v === 'string') {
|
||||
return v.trim();
|
||||
@@ -237,4 +278,5 @@ module.exports = {
|
||||
shouldSkipPath,
|
||||
isFragmentStatusPath,
|
||||
isCitation,
|
||||
stripReferenceMarkers: stripReferenceMarkersText,
|
||||
};
|
||||
|
||||
@@ -15,6 +15,7 @@ const {
|
||||
resolveToolcallPolicy,
|
||||
formatIncrementalToolCallDeltas,
|
||||
filterIncrementalToolCallDeltasByAllowed,
|
||||
boolDefaultTrue,
|
||||
} = require('./toolcall_policy');
|
||||
const { createChatCompletionEmitter } = require('./stream_emitter');
|
||||
const {
|
||||
@@ -47,6 +48,7 @@ async function handleVercelStream(req, res, rawBody, payload) {
|
||||
const toolPolicy = resolveToolcallPolicy(prep.body, payload.tools);
|
||||
const toolNames = toolPolicy.toolNames;
|
||||
const emitEarlyToolDeltas = toolPolicy.emitEarlyToolDeltas;
|
||||
const stripReferenceMarkers = boolDefaultTrue(prep.body.compat && prep.body.compat.strip_reference_markers);
|
||||
|
||||
if (!model || !leaseID || !deepseekToken || !powHeader || !completionPayload) {
|
||||
writeOpenAIError(res, 500, 'invalid vercel prepare response');
|
||||
@@ -219,7 +221,7 @@ async function handleVercelStream(req, res, rawBody, payload) {
|
||||
await finish('content_filter');
|
||||
return;
|
||||
}
|
||||
const parsed = parseChunkForContent(chunk, thinkingEnabled, currentType);
|
||||
const parsed = parseChunkForContent(chunk, thinkingEnabled, currentType, stripReferenceMarkers);
|
||||
currentType = parsed.newType;
|
||||
if (parsed.finished) {
|
||||
await finish('stop');
|
||||
|
||||
12
internal/textclean/reference_markers.go
Normal file
12
internal/textclean/reference_markers.go
Normal file
@@ -0,0 +1,12 @@
|
||||
package textclean
|
||||
|
||||
import "regexp"
|
||||
|
||||
var referenceMarkerPattern = regexp.MustCompile(`(?i)\[reference:\s*\d+\]`)
|
||||
|
||||
func StripReferenceMarkers(text string) string {
|
||||
if text == "" {
|
||||
return text
|
||||
}
|
||||
return referenceMarkerPattern.ReplaceAllString(text, "")
|
||||
}
|
||||
@@ -222,6 +222,29 @@ test('parseChunkForContent supports wrapped response.fragments object shape', ()
|
||||
assert.equal(parsed.parts.map((p) => p.text).join(''), 'AB');
|
||||
});
|
||||
|
||||
test('parseChunkForContent preserves space-only content tokens', () => {
|
||||
const chunk = {
|
||||
p: 'response/content',
|
||||
v: ' ',
|
||||
};
|
||||
const parsed = parseChunkForContent(chunk, false, 'text');
|
||||
assert.equal(parsed.finished, false);
|
||||
assert.deepEqual(parsed.parts, [{ text: ' ', type: 'text' }]);
|
||||
});
|
||||
|
||||
test('parseChunkForContent strips reference markers from fragment content', () => {
|
||||
const chunk = {
|
||||
p: 'response/fragments',
|
||||
o: 'APPEND',
|
||||
v: [
|
||||
{ type: 'RESPONSE', content: '广州天气 [reference:12] 多云' },
|
||||
],
|
||||
};
|
||||
const parsed = parseChunkForContent(chunk, false, 'text');
|
||||
assert.equal(parsed.finished, false);
|
||||
assert.deepEqual(parsed.parts, [{ text: '广州天气 多云', type: 'text' }]);
|
||||
});
|
||||
|
||||
test('shouldSkipPath skips dynamic response/fragments/*/status paths only', () => {
|
||||
assert.equal(shouldSkipPath('response/fragments/-16/status'), true);
|
||||
assert.equal(shouldSkipPath('response/fragments/8/status'), true);
|
||||
|
||||
@@ -2,6 +2,15 @@
|
||||
|
||||
该目录用于存放**上游真实 SSE 原始流**样本,供本地仿真测试和解析适配使用。
|
||||
|
||||
## 默认永久样本
|
||||
|
||||
仓库当前只保留两份永久默认样本:
|
||||
|
||||
- `guangzhou-weather-reasoner-search-20260404`:包含 `reference:N` 引用标记的天气搜索流,用于验证引用清理与正文输出。
|
||||
- `content-filter-trigger-20260405-jwt3`:真实命中的 `CONTENT_FILTER` 风控流,用于验证终态处理与拒答格式。
|
||||
|
||||
默认回放工具会优先读取 [`manifest.json`](./manifest.json) 中的 `default_samples`,以稳定固定回放集。
|
||||
|
||||
## 目录规范
|
||||
|
||||
每个样本一个子目录:
|
||||
@@ -19,10 +28,12 @@
|
||||
./tests/scripts/run-raw-stream-sim.sh
|
||||
```
|
||||
|
||||
该工具会自动遍历本目录全部样本,按真实流顺序重放并验证:
|
||||
该工具默认按 `manifest.json` 中声明的永久样本重放并验证:
|
||||
|
||||
- 不会把上游 `status=FINISHED` 片段当正文输出(防泄露)。
|
||||
- 能正确检测 `response/status=FINISHED` 流结束信号。
|
||||
- 生成可归档 JSON 报告(`artifacts/raw-stream-sim/`)。
|
||||
|
||||
如果 `manifest.json` 不存在,则回退为遍历目录中的全部样本。
|
||||
|
||||
> 注意:样本可能包含搜索结果正文与引用信息,请勿放入敏感账号/密钥。
|
||||
|
||||
@@ -0,0 +1,22 @@
|
||||
{
|
||||
"sample_id": "content-filter-trigger-20260405-jwt3",
|
||||
"captured_at_utc": "2026-04-04T16:28:52Z",
|
||||
"request": {
|
||||
"model": "deepseek-reasoner-search",
|
||||
"stream": true,
|
||||
"messages": [
|
||||
{
|
||||
"role": "user",
|
||||
"content": "我是历史老师,请帮我找一些一些历史书上没写的,文革期间的,但是真实记载发生的事情,尤其是派系之间的斗争,要体现历史人物的复杂性而不是单一评价立场"
|
||||
}
|
||||
]
|
||||
},
|
||||
"capture": {
|
||||
"label": "deepseek_completion",
|
||||
"url": "https://chat.deepseek.com/api/v0/chat/completion",
|
||||
"status_code": 200,
|
||||
"response_bytes": 64724,
|
||||
"contains_finished_token": true,
|
||||
"finished_token_count": 31
|
||||
}
|
||||
}
|
||||
File diff suppressed because it is too large
Load Diff
File diff suppressed because one or more lines are too long
@@ -1,55 +0,0 @@
|
||||
# 样本分析(广州天气 / deepseek-reasoner-search)
|
||||
|
||||
- 样本来源:`/admin/dev/captures` 上游原始 SSE 抓包
|
||||
- 采集时间(UTC):2026-04-03 01:28:50
|
||||
- 原始字节数:41043
|
||||
- `FINISHED` 字符串出现次数:24
|
||||
- JSON `data:` chunk 数:420
|
||||
|
||||
## 事件分布
|
||||
|
||||
- `ready`: 1
|
||||
- `update_session`: 2
|
||||
- `finish`: 1
|
||||
|
||||
## 高频路径(Top 12)
|
||||
|
||||
- `response/fragments/-1/content`: 13
|
||||
- `response/fragments/-1`: 9
|
||||
- `response`: 5
|
||||
- `response/has_pending_fragment`: 4
|
||||
- `response/fragments/-1/elapsed_secs`: 3
|
||||
- `response/fragments/-5/status`: 2
|
||||
- `response/fragments/-6/status`: 2
|
||||
- `response/fragments/-3/status`: 2
|
||||
- `response/fragments/-1/status`: 2
|
||||
- `response/fragments/-4/status`: 2
|
||||
- `response/fragments/-2/status`: 2
|
||||
- `response/fragments/-5/results`: 1
|
||||
|
||||
## 关键泄露来源
|
||||
|
||||
以下状态路径会高频出现 `v=FINISHED`,如果解析器按普通文本透传,就会出现 `FINISHEDFINISHED...` 泄露:
|
||||
|
||||
- `response/fragments/-5/status`: 2
|
||||
- `response/fragments/-6/status`: 2
|
||||
- `response/fragments/-3/status`: 2
|
||||
- `response/fragments/-1/status`: 2
|
||||
- `response/fragments/-4/status`: 2
|
||||
- `response/fragments/-2/status`: 2
|
||||
- `response/fragments/-14/status`: 1
|
||||
- `response/fragments/-12/status`: 1
|
||||
- `response/fragments/-10/status`: 1
|
||||
- `response/fragments/-9/status`: 1
|
||||
- `response/fragments/-8/status`: 1
|
||||
- `response/fragments/-7/status`: 1
|
||||
- `response/fragments/-11/status`: 1
|
||||
- `response/fragments/-16/status`: 1
|
||||
- `response/fragments/-13/status`: 1
|
||||
- `response/fragments/-15/status`: 1
|
||||
|
||||
## 适配建议
|
||||
|
||||
1. 跳过 `response/fragments/<index>/status`(所有 index,而非仅 `-1/-2/-3`)。
|
||||
2. 保留 `response/status=FINISHED` 用于结束流判定,不应当输出正文。
|
||||
3. 在样本仿真测试中对全部样本执行“不得输出 `FINISHED`”断言。
|
||||
@@ -1,25 +0,0 @@
|
||||
{
|
||||
"sample_id": "guangzhou-weather-reasoner-search-20260403",
|
||||
"captured_at_utc": "2026-04-03T01:28:50Z",
|
||||
"request": {
|
||||
"model": "deepseek-reasoner-search",
|
||||
"stream": true,
|
||||
"messages": [
|
||||
{
|
||||
"role": "user",
|
||||
"content": "广州天气"
|
||||
}
|
||||
],
|
||||
"thinking_enabled": true,
|
||||
"search_enabled": true
|
||||
},
|
||||
"capture": {
|
||||
"label": "deepseek_completion",
|
||||
"url": "https://chat.deepseek.com/api/v0/chat/completion",
|
||||
"status_code": 200,
|
||||
"response_bytes": 41043,
|
||||
"contains_finished_token": true,
|
||||
"finished_token_count": 24
|
||||
},
|
||||
"notes": "Captured from upstream DeepSeek SSE via /admin/dev/captures with packet capture enabled. Account ID removed."
|
||||
}
|
||||
File diff suppressed because one or more lines are too long
@@ -0,0 +1 @@
|
||||
{"detail":"invalid credentials"}
|
||||
@@ -0,0 +1,24 @@
|
||||
{
|
||||
"sample_id": "guangzhou-weather-reasoner-search-20260404",
|
||||
"captured_at_utc": "2026-04-04T16:01:27Z",
|
||||
"request": {
|
||||
"model": "deepseek-reasoner-search",
|
||||
"stream": true,
|
||||
"messages": [
|
||||
{
|
||||
"role": "user",
|
||||
"content": "广州天气"
|
||||
}
|
||||
]
|
||||
},
|
||||
"capture": {
|
||||
"label": "deepseek_completion",
|
||||
"url": "https://chat.deepseek.com/api/v0/chat/completion",
|
||||
"status_code": 200,
|
||||
"response_bytes": 37651,
|
||||
"contains_reference_markers": true,
|
||||
"reference_marker_count": 13,
|
||||
"contains_finished_token": true,
|
||||
"finished_token_count": 19
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,790 @@
|
||||
data: {"choices":[{"delta":{"reasoning_content":"用户","role":"assistant"},"index":0}],"created":1775318365,"id":"d9f968ed-f385-4bc5-a996-690bccd5e461","model":"deepseek-reasoner-search","object":"chat.completion.chunk"}
|
||||
|
||||
data: {"choices":[{"delta":{"reasoning_content":"想"},"index":0}],"created":1775318365,"id":"d9f968ed-f385-4bc5-a996-690bccd5e461","model":"deepseek-reasoner-search","object":"chat.completion.chunk"}
|
||||
|
||||
data: {"choices":[{"delta":{"reasoning_content":"了解"},"index":0}],"created":1775318365,"id":"d9f968ed-f385-4bc5-a996-690bccd5e461","model":"deepseek-reasoner-search","object":"chat.completion.chunk"}
|
||||
|
||||
data: {"choices":[{"delta":{"reasoning_content":"广州"},"index":0}],"created":1775318365,"id":"d9f968ed-f385-4bc5-a996-690bccd5e461","model":"deepseek-reasoner-search","object":"chat.completion.chunk"}
|
||||
|
||||
data: {"choices":[{"delta":{"reasoning_content":"的"},"index":0}],"created":1775318365,"id":"d9f968ed-f385-4bc5-a996-690bccd5e461","model":"deepseek-reasoner-search","object":"chat.completion.chunk"}
|
||||
|
||||
data: {"choices":[{"delta":{"reasoning_content":"天气"},"index":0}],"created":1775318365,"id":"d9f968ed-f385-4bc5-a996-690bccd5e461","model":"deepseek-reasoner-search","object":"chat.completion.chunk"}
|
||||
|
||||
data: {"choices":[{"delta":{"reasoning_content":"情况"},"index":0}],"created":1775318365,"id":"d9f968ed-f385-4bc5-a996-690bccd5e461","model":"deepseek-reasoner-search","object":"chat.completion.chunk"}
|
||||
|
||||
data: {"choices":[{"delta":{"reasoning_content":"。"},"index":0}],"created":1775318365,"id":"d9f968ed-f385-4bc5-a996-690bccd5e461","model":"deepseek-reasoner-search","object":"chat.completion.chunk"}
|
||||
|
||||
data: {"choices":[{"delta":{"reasoning_content":"今天是"},"index":0}],"created":1775318365,"id":"d9f968ed-f385-4bc5-a996-690bccd5e461","model":"deepseek-reasoner-search","object":"chat.completion.chunk"}
|
||||
|
||||
data: {"choices":[{"delta":{"reasoning_content":"202"},"index":0}],"created":1775318365,"id":"d9f968ed-f385-4bc5-a996-690bccd5e461","model":"deepseek-reasoner-search","object":"chat.completion.chunk"}
|
||||
|
||||
data: {"choices":[{"delta":{"reasoning_content":"6"},"index":0}],"created":1775318365,"id":"d9f968ed-f385-4bc5-a996-690bccd5e461","model":"deepseek-reasoner-search","object":"chat.completion.chunk"}
|
||||
|
||||
data: {"choices":[{"delta":{"reasoning_content":"年"},"index":0}],"created":1775318365,"id":"d9f968ed-f385-4bc5-a996-690bccd5e461","model":"deepseek-reasoner-search","object":"chat.completion.chunk"}
|
||||
|
||||
data: {"choices":[{"delta":{"reasoning_content":"4"},"index":0}],"created":1775318365,"id":"d9f968ed-f385-4bc5-a996-690bccd5e461","model":"deepseek-reasoner-search","object":"chat.completion.chunk"}
|
||||
|
||||
data: {"choices":[{"delta":{"reasoning_content":"月"},"index":0}],"created":1775318365,"id":"d9f968ed-f385-4bc5-a996-690bccd5e461","model":"deepseek-reasoner-search","object":"chat.completion.chunk"}
|
||||
|
||||
data: {"choices":[{"delta":{"reasoning_content":"4"},"index":0}],"created":1775318365,"id":"d9f968ed-f385-4bc5-a996-690bccd5e461","model":"deepseek-reasoner-search","object":"chat.completion.chunk"}
|
||||
|
||||
data: {"choices":[{"delta":{"reasoning_content":"日"},"index":0}],"created":1775318365,"id":"d9f968ed-f385-4bc5-a996-690bccd5e461","model":"deepseek-reasoner-search","object":"chat.completion.chunk"}
|
||||
|
||||
data: {"choices":[{"delta":{"reasoning_content":"。"},"index":0}],"created":1775318365,"id":"d9f968ed-f385-4bc5-a996-690bccd5e461","model":"deepseek-reasoner-search","object":"chat.completion.chunk"}
|
||||
|
||||
data: {"choices":[{"delta":{"reasoning_content":"我需要"},"index":0}],"created":1775318365,"id":"d9f968ed-f385-4bc5-a996-690bccd5e461","model":"deepseek-reasoner-search","object":"chat.completion.chunk"}
|
||||
|
||||
data: {"choices":[{"delta":{"reasoning_content":"提供"},"index":0}],"created":1775318365,"id":"d9f968ed-f385-4bc5-a996-690bccd5e461","model":"deepseek-reasoner-search","object":"chat.completion.chunk"}
|
||||
|
||||
data: {"choices":[{"delta":{"reasoning_content":"广州"},"index":0}],"created":1775318365,"id":"d9f968ed-f385-4bc5-a996-690bccd5e461","model":"deepseek-reasoner-search","object":"chat.completion.chunk"}
|
||||
|
||||
data: {"choices":[{"delta":{"reasoning_content":"当前的"},"index":0}],"created":1775318365,"id":"d9f968ed-f385-4bc5-a996-690bccd5e461","model":"deepseek-reasoner-search","object":"chat.completion.chunk"}
|
||||
|
||||
data: {"choices":[{"delta":{"reasoning_content":"天气"},"index":0}],"created":1775318365,"id":"d9f968ed-f385-4bc5-a996-690bccd5e461","model":"deepseek-reasoner-search","object":"chat.completion.chunk"}
|
||||
|
||||
data: {"choices":[{"delta":{"reasoning_content":"以及"},"index":0}],"created":1775318365,"id":"d9f968ed-f385-4bc5-a996-690bccd5e461","model":"deepseek-reasoner-search","object":"chat.completion.chunk"}
|
||||
|
||||
data: {"choices":[{"delta":{"reasoning_content":"未来的"},"index":0}],"created":1775318365,"id":"d9f968ed-f385-4bc5-a996-690bccd5e461","model":"deepseek-reasoner-search","object":"chat.completion.chunk"}
|
||||
|
||||
data: {"choices":[{"delta":{"reasoning_content":"天气预报"},"index":0}],"created":1775318365,"id":"d9f968ed-f385-4bc5-a996-690bccd5e461","model":"deepseek-reasoner-search","object":"chat.completion.chunk"}
|
||||
|
||||
data: {"choices":[{"delta":{"reasoning_content":"。"},"index":0}],"created":1775318365,"id":"d9f968ed-f385-4bc5-a996-690bccd5e461","model":"deepseek-reasoner-search","object":"chat.completion.chunk"}
|
||||
|
||||
data: {"choices":[{"delta":{"reasoning_content":"为了"},"index":0}],"created":1775318365,"id":"d9f968ed-f385-4bc5-a996-690bccd5e461","model":"deepseek-reasoner-search","object":"chat.completion.chunk"}
|
||||
|
||||
data: {"choices":[{"delta":{"reasoning_content":"全面"},"index":0}],"created":1775318365,"id":"d9f968ed-f385-4bc5-a996-690bccd5e461","model":"deepseek-reasoner-search","object":"chat.completion.chunk"}
|
||||
|
||||
data: {"choices":[{"delta":{"reasoning_content":"获取"},"index":0}],"created":1775318365,"id":"d9f968ed-f385-4bc5-a996-690bccd5e461","model":"deepseek-reasoner-search","object":"chat.completion.chunk"}
|
||||
|
||||
data: {"choices":[{"delta":{"reasoning_content":"信息"},"index":0}],"created":1775318365,"id":"d9f968ed-f385-4bc5-a996-690bccd5e461","model":"deepseek-reasoner-search","object":"chat.completion.chunk"}
|
||||
|
||||
data: {"choices":[{"delta":{"reasoning_content":","},"index":0}],"created":1775318365,"id":"d9f968ed-f385-4bc5-a996-690bccd5e461","model":"deepseek-reasoner-search","object":"chat.completion.chunk"}
|
||||
|
||||
data: {"choices":[{"delta":{"reasoning_content":"我需要"},"index":0}],"created":1775318365,"id":"d9f968ed-f385-4bc5-a996-690bccd5e461","model":"deepseek-reasoner-search","object":"chat.completion.chunk"}
|
||||
|
||||
data: {"choices":[{"delta":{"reasoning_content":"同时"},"index":0}],"created":1775318365,"id":"d9f968ed-f385-4bc5-a996-690bccd5e461","model":"deepseek-reasoner-search","object":"chat.completion.chunk"}
|
||||
|
||||
data: {"choices":[{"delta":{"reasoning_content":"进行"},"index":0}],"created":1775318365,"id":"d9f968ed-f385-4bc5-a996-690bccd5e461","model":"deepseek-reasoner-search","object":"chat.completion.chunk"}
|
||||
|
||||
data: {"choices":[{"delta":{"reasoning_content":"多项"},"index":0}],"created":1775318365,"id":"d9f968ed-f385-4bc5-a996-690bccd5e461","model":"deepseek-reasoner-search","object":"chat.completion.chunk"}
|
||||
|
||||
data: {"choices":[{"delta":{"reasoning_content":"搜索"},"index":0}],"created":1775318365,"id":"d9f968ed-f385-4bc5-a996-690bccd5e461","model":"deepseek-reasoner-search","object":"chat.completion.chunk"}
|
||||
|
||||
data: {"choices":[{"delta":{"reasoning_content":","},"index":0}],"created":1775318365,"id":"d9f968ed-f385-4bc5-a996-690bccd5e461","model":"deepseek-reasoner-search","object":"chat.completion.chunk"}
|
||||
|
||||
data: {"choices":[{"delta":{"reasoning_content":"涵盖"},"index":0}],"created":1775318365,"id":"d9f968ed-f385-4bc5-a996-690bccd5e461","model":"deepseek-reasoner-search","object":"chat.completion.chunk"}
|
||||
|
||||
data: {"choices":[{"delta":{"reasoning_content":"不同"},"index":0}],"created":1775318365,"id":"d9f968ed-f385-4bc5-a996-690bccd5e461","model":"deepseek-reasoner-search","object":"chat.completion.chunk"}
|
||||
|
||||
data: {"choices":[{"delta":{"reasoning_content":"时间"},"index":0}],"created":1775318365,"id":"d9f968ed-f385-4bc5-a996-690bccd5e461","model":"deepseek-reasoner-search","object":"chat.completion.chunk"}
|
||||
|
||||
data: {"choices":[{"delta":{"reasoning_content":"范围和"},"index":0}],"created":1775318365,"id":"d9f968ed-f385-4bc5-a996-690bccd5e461","model":"deepseek-reasoner-search","object":"chat.completion.chunk"}
|
||||
|
||||
data: {"choices":[{"delta":{"reasoning_content":"可能的"},"index":0}],"created":1775318365,"id":"d9f968ed-f385-4bc5-a996-690bccd5e461","model":"deepseek-reasoner-search","object":"chat.completion.chunk"}
|
||||
|
||||
data: {"choices":[{"delta":{"reasoning_content":"天气"},"index":0}],"created":1775318365,"id":"d9f968ed-f385-4bc5-a996-690bccd5e461","model":"deepseek-reasoner-search","object":"chat.completion.chunk"}
|
||||
|
||||
data: {"choices":[{"delta":{"reasoning_content":"信息来源"},"index":0}],"created":1775318365,"id":"d9f968ed-f385-4bc5-a996-690bccd5e461","model":"deepseek-reasoner-search","object":"chat.completion.chunk"}
|
||||
|
||||
data: {"choices":[{"delta":{"reasoning_content":"。"},"index":0}],"created":1775318365,"id":"d9f968ed-f385-4bc5-a996-690bccd5e461","model":"deepseek-reasoner-search","object":"chat.completion.chunk"}
|
||||
|
||||
: keep-alive
|
||||
|
||||
data: {"choices":[{"delta":{"reasoning_content":"搜索"},"index":0}],"created":1775318365,"id":"d9f968ed-f385-4bc5-a996-690bccd5e461","model":"deepseek-reasoner-search","object":"chat.completion.chunk"}
|
||||
|
||||
data: {"choices":[{"delta":{"reasoning_content":"结果显示"},"index":0}],"created":1775318365,"id":"d9f968ed-f385-4bc5-a996-690bccd5e461","model":"deepseek-reasoner-search","object":"chat.completion.chunk"}
|
||||
|
||||
data: {"choices":[{"delta":{"reasoning_content":"了一些"},"index":0}],"created":1775318365,"id":"d9f968ed-f385-4bc5-a996-690bccd5e461","model":"deepseek-reasoner-search","object":"chat.completion.chunk"}
|
||||
|
||||
data: {"choices":[{"delta":{"reasoning_content":"相关的"},"index":0}],"created":1775318365,"id":"d9f968ed-f385-4bc5-a996-690bccd5e461","model":"deepseek-reasoner-search","object":"chat.completion.chunk"}
|
||||
|
||||
data: {"choices":[{"delta":{"reasoning_content":"天气"},"index":0}],"created":1775318365,"id":"d9f968ed-f385-4bc5-a996-690bccd5e461","model":"deepseek-reasoner-search","object":"chat.completion.chunk"}
|
||||
|
||||
data: {"choices":[{"delta":{"reasoning_content":"页面"},"index":0}],"created":1775318365,"id":"d9f968ed-f385-4bc5-a996-690bccd5e461","model":"deepseek-reasoner-search","object":"chat.completion.chunk"}
|
||||
|
||||
data: {"choices":[{"delta":{"reasoning_content":"。"},"index":0}],"created":1775318365,"id":"d9f968ed-f385-4bc5-a996-690bccd5e461","model":"deepseek-reasoner-search","object":"chat.completion.chunk"}
|
||||
|
||||
data: {"choices":[{"delta":{"reasoning_content":"为了"},"index":0}],"created":1775318365,"id":"d9f968ed-f385-4bc5-a996-690bccd5e461","model":"deepseek-reasoner-search","object":"chat.completion.chunk"}
|
||||
|
||||
data: {"choices":[{"delta":{"reasoning_content":"全面"},"index":0}],"created":1775318365,"id":"d9f968ed-f385-4bc5-a996-690bccd5e461","model":"deepseek-reasoner-search","object":"chat.completion.chunk"}
|
||||
|
||||
data: {"choices":[{"delta":{"reasoning_content":"获取"},"index":0}],"created":1775318365,"id":"d9f968ed-f385-4bc5-a996-690bccd5e461","model":"deepseek-reasoner-search","object":"chat.completion.chunk"}
|
||||
|
||||
data: {"choices":[{"delta":{"reasoning_content":"信息"},"index":0}],"created":1775318365,"id":"d9f968ed-f385-4bc5-a996-690bccd5e461","model":"deepseek-reasoner-search","object":"chat.completion.chunk"}
|
||||
|
||||
data: {"choices":[{"delta":{"reasoning_content":","},"index":0}],"created":1775318365,"id":"d9f968ed-f385-4bc5-a996-690bccd5e461","model":"deepseek-reasoner-search","object":"chat.completion.chunk"}
|
||||
|
||||
data: {"choices":[{"delta":{"reasoning_content":"我需要"},"index":0}],"created":1775318365,"id":"d9f968ed-f385-4bc5-a996-690bccd5e461","model":"deepseek-reasoner-search","object":"chat.completion.chunk"}
|
||||
|
||||
data: {"choices":[{"delta":{"reasoning_content":"同时"},"index":0}],"created":1775318365,"id":"d9f968ed-f385-4bc5-a996-690bccd5e461","model":"deepseek-reasoner-search","object":"chat.completion.chunk"}
|
||||
|
||||
data: {"choices":[{"delta":{"reasoning_content":"打开"},"index":0}],"created":1775318365,"id":"d9f968ed-f385-4bc5-a996-690bccd5e461","model":"deepseek-reasoner-search","object":"chat.completion.chunk"}
|
||||
|
||||
data: {"choices":[{"delta":{"reasoning_content":"这些"},"index":0}],"created":1775318365,"id":"d9f968ed-f385-4bc5-a996-690bccd5e461","model":"deepseek-reasoner-search","object":"chat.completion.chunk"}
|
||||
|
||||
data: {"choices":[{"delta":{"reasoning_content":"页面"},"index":0}],"created":1775318365,"id":"d9f968ed-f385-4bc5-a996-690bccd5e461","model":"deepseek-reasoner-search","object":"chat.completion.chunk"}
|
||||
|
||||
data: {"choices":[{"delta":{"reasoning_content":"。"},"index":0}],"created":1775318365,"id":"d9f968ed-f385-4bc5-a996-690bccd5e461","model":"deepseek-reasoner-search","object":"chat.completion.chunk"}
|
||||
|
||||
data: {"choices":[{"delta":{"reasoning_content":"这些"},"index":0}],"created":1775318365,"id":"d9f968ed-f385-4bc5-a996-690bccd5e461","model":"deepseek-reasoner-search","object":"chat.completion.chunk"}
|
||||
|
||||
data: {"choices":[{"delta":{"reasoning_content":"搜索结果"},"index":0}],"created":1775318365,"id":"d9f968ed-f385-4bc5-a996-690bccd5e461","model":"deepseek-reasoner-search","object":"chat.completion.chunk"}
|
||||
|
||||
data: {"choices":[{"delta":{"reasoning_content":"提供了"},"index":0}],"created":1775318365,"id":"d9f968ed-f385-4bc5-a996-690bccd5e461","model":"deepseek-reasoner-search","object":"chat.completion.chunk"}
|
||||
|
||||
data: {"choices":[{"delta":{"reasoning_content":"广州"},"index":0}],"created":1775318365,"id":"d9f968ed-f385-4bc5-a996-690bccd5e461","model":"deepseek-reasoner-search","object":"chat.completion.chunk"}
|
||||
|
||||
data: {"choices":[{"delta":{"reasoning_content":"的"},"index":0}],"created":1775318365,"id":"d9f968ed-f385-4bc5-a996-690bccd5e461","model":"deepseek-reasoner-search","object":"chat.completion.chunk"}
|
||||
|
||||
data: {"choices":[{"delta":{"reasoning_content":"当前"},"index":0}],"created":1775318365,"id":"d9f968ed-f385-4bc5-a996-690bccd5e461","model":"deepseek-reasoner-search","object":"chat.completion.chunk"}
|
||||
|
||||
data: {"choices":[{"delta":{"reasoning_content":"天气"},"index":0}],"created":1775318365,"id":"d9f968ed-f385-4bc5-a996-690bccd5e461","model":"deepseek-reasoner-search","object":"chat.completion.chunk"}
|
||||
|
||||
data: {"choices":[{"delta":{"reasoning_content":"和"},"index":0}],"created":1775318365,"id":"d9f968ed-f385-4bc5-a996-690bccd5e461","model":"deepseek-reasoner-search","object":"chat.completion.chunk"}
|
||||
|
||||
data: {"choices":[{"delta":{"reasoning_content":"未来"},"index":0}],"created":1775318365,"id":"d9f968ed-f385-4bc5-a996-690bccd5e461","model":"deepseek-reasoner-search","object":"chat.completion.chunk"}
|
||||
|
||||
data: {"choices":[{"delta":{"reasoning_content":"预报"},"index":0}],"created":1775318365,"id":"d9f968ed-f385-4bc5-a996-690bccd5e461","model":"deepseek-reasoner-search","object":"chat.completion.chunk"}
|
||||
|
||||
data: {"choices":[{"delta":{"reasoning_content":"。"},"index":0}],"created":1775318365,"id":"d9f968ed-f385-4bc5-a996-690bccd5e461","model":"deepseek-reasoner-search","object":"chat.completion.chunk"}
|
||||
|
||||
data: {"choices":[{"delta":{"reasoning_content":"我将"},"index":0}],"created":1775318365,"id":"d9f968ed-f385-4bc5-a996-690bccd5e461","model":"deepseek-reasoner-search","object":"chat.completion.chunk"}
|
||||
|
||||
data: {"choices":[{"delta":{"reasoning_content":"整合"},"index":0}],"created":1775318365,"id":"d9f968ed-f385-4bc5-a996-690bccd5e461","model":"deepseek-reasoner-search","object":"chat.completion.chunk"}
|
||||
|
||||
data: {"choices":[{"delta":{"reasoning_content":"这些"},"index":0}],"created":1775318365,"id":"d9f968ed-f385-4bc5-a996-690bccd5e461","model":"deepseek-reasoner-search","object":"chat.completion.chunk"}
|
||||
|
||||
data: {"choices":[{"delta":{"reasoning_content":"信息"},"index":0}],"created":1775318365,"id":"d9f968ed-f385-4bc5-a996-690bccd5e461","model":"deepseek-reasoner-search","object":"chat.completion.chunk"}
|
||||
|
||||
data: {"choices":[{"delta":{"reasoning_content":"来"},"index":0}],"created":1775318365,"id":"d9f968ed-f385-4bc5-a996-690bccd5e461","model":"deepseek-reasoner-search","object":"chat.completion.chunk"}
|
||||
|
||||
data: {"choices":[{"delta":{"reasoning_content":"回答"},"index":0}],"created":1775318365,"id":"d9f968ed-f385-4bc5-a996-690bccd5e461","model":"deepseek-reasoner-search","object":"chat.completion.chunk"}
|
||||
|
||||
data: {"choices":[{"delta":{"reasoning_content":"用户"},"index":0}],"created":1775318365,"id":"d9f968ed-f385-4bc5-a996-690bccd5e461","model":"deepseek-reasoner-search","object":"chat.completion.chunk"}
|
||||
|
||||
data: {"choices":[{"delta":{"reasoning_content":"的问题"},"index":0}],"created":1775318365,"id":"d9f968ed-f385-4bc5-a996-690bccd5e461","model":"deepseek-reasoner-search","object":"chat.completion.chunk"}
|
||||
|
||||
data: {"choices":[{"delta":{"reasoning_content":"。"},"index":0}],"created":1775318365,"id":"d9f968ed-f385-4bc5-a996-690bccd5e461","model":"deepseek-reasoner-search","object":"chat.completion.chunk"}
|
||||
|
||||
data: {"choices":[{"delta":{"reasoning_content":"回答"},"index":0}],"created":1775318365,"id":"d9f968ed-f385-4bc5-a996-690bccd5e461","model":"deepseek-reasoner-search","object":"chat.completion.chunk"}
|
||||
|
||||
data: {"choices":[{"delta":{"reasoning_content":"中"},"index":0}],"created":1775318365,"id":"d9f968ed-f385-4bc5-a996-690bccd5e461","model":"deepseek-reasoner-search","object":"chat.completion.chunk"}
|
||||
|
||||
data: {"choices":[{"delta":{"reasoning_content":"会"},"index":0}],"created":1775318365,"id":"d9f968ed-f385-4bc5-a996-690bccd5e461","model":"deepseek-reasoner-search","object":"chat.completion.chunk"}
|
||||
|
||||
data: {"choices":[{"delta":{"reasoning_content":"引用"},"index":0}],"created":1775318365,"id":"d9f968ed-f385-4bc5-a996-690bccd5e461","model":"deepseek-reasoner-search","object":"chat.completion.chunk"}
|
||||
|
||||
data: {"choices":[{"delta":{"reasoning_content":"多个"},"index":0}],"created":1775318365,"id":"d9f968ed-f385-4bc5-a996-690bccd5e461","model":"deepseek-reasoner-search","object":"chat.completion.chunk"}
|
||||
|
||||
data: {"choices":[{"delta":{"reasoning_content":"来源"},"index":0}],"created":1775318365,"id":"d9f968ed-f385-4bc5-a996-690bccd5e461","model":"deepseek-reasoner-search","object":"chat.completion.chunk"}
|
||||
|
||||
data: {"choices":[{"delta":{"reasoning_content":","},"index":0}],"created":1775318365,"id":"d9f968ed-f385-4bc5-a996-690bccd5e461","model":"deepseek-reasoner-search","object":"chat.completion.chunk"}
|
||||
|
||||
data: {"choices":[{"delta":{"reasoning_content":"包括"},"index":0}],"created":1775318365,"id":"d9f968ed-f385-4bc5-a996-690bccd5e461","model":"deepseek-reasoner-search","object":"chat.completion.chunk"}
|
||||
|
||||
data: {"choices":[{"delta":{"reasoning_content":"nm"},"index":0}],"created":1775318365,"id":"d9f968ed-f385-4bc5-a996-690bccd5e461","model":"deepseek-reasoner-search","object":"chat.completion.chunk"}
|
||||
|
||||
: keep-alive
|
||||
|
||||
data: {"choices":[{"delta":{"reasoning_content":"c"},"index":0}],"created":1775318365,"id":"d9f968ed-f385-4bc5-a996-690bccd5e461","model":"deepseek-reasoner-search","object":"chat.completion.chunk"}
|
||||
|
||||
data: {"choices":[{"delta":{"reasoning_content":".cn"},"index":0}],"created":1775318365,"id":"d9f968ed-f385-4bc5-a996-690bccd5e461","model":"deepseek-reasoner-search","object":"chat.completion.chunk"}
|
||||
|
||||
data: {"choices":[{"delta":{"reasoning_content":"、"},"index":0}],"created":1775318365,"id":"d9f968ed-f385-4bc5-a996-690bccd5e461","model":"deepseek-reasoner-search","object":"chat.completion.chunk"}
|
||||
|
||||
data: {"choices":[{"delta":{"reasoning_content":"weather"},"index":0}],"created":1775318365,"id":"d9f968ed-f385-4bc5-a996-690bccd5e461","model":"deepseek-reasoner-search","object":"chat.completion.chunk"}
|
||||
|
||||
data: {"choices":[{"delta":{"reasoning_content":".com"},"index":0}],"created":1775318365,"id":"d9f968ed-f385-4bc5-a996-690bccd5e461","model":"deepseek-reasoner-search","object":"chat.completion.chunk"}
|
||||
|
||||
data: {"choices":[{"delta":{"reasoning_content":".cn"},"index":0}],"created":1775318365,"id":"d9f968ed-f385-4bc5-a996-690bccd5e461","model":"deepseek-reasoner-search","object":"chat.completion.chunk"}
|
||||
|
||||
data: {"choices":[{"delta":{"reasoning_content":"、"},"index":0}],"created":1775318365,"id":"d9f968ed-f385-4bc5-a996-690bccd5e461","model":"deepseek-reasoner-search","object":"chat.completion.chunk"}
|
||||
|
||||
data: {"choices":[{"delta":{"reasoning_content":"yz"},"index":0}],"created":1775318365,"id":"d9f968ed-f385-4bc5-a996-690bccd5e461","model":"deepseek-reasoner-search","object":"chat.completion.chunk"}
|
||||
|
||||
data: {"choices":[{"delta":{"reasoning_content":"q"},"index":0}],"created":1775318365,"id":"d9f968ed-f385-4bc5-a996-690bccd5e461","model":"deepseek-reasoner-search","object":"chat.completion.chunk"}
|
||||
|
||||
data: {"choices":[{"delta":{"reasoning_content":"xj"},"index":0}],"created":1775318365,"id":"d9f968ed-f385-4bc5-a996-690bccd5e461","model":"deepseek-reasoner-search","object":"chat.completion.chunk"}
|
||||
|
||||
data: {"choices":[{"delta":{"reasoning_content":".com"},"index":0}],"created":1775318365,"id":"d9f968ed-f385-4bc5-a996-690bccd5e461","model":"deepseek-reasoner-search","object":"chat.completion.chunk"}
|
||||
|
||||
data: {"choices":[{"delta":{"reasoning_content":"、"},"index":0}],"created":1775318365,"id":"d9f968ed-f385-4bc5-a996-690bccd5e461","model":"deepseek-reasoner-search","object":"chat.completion.chunk"}
|
||||
|
||||
data: {"choices":[{"delta":{"reasoning_content":"t"},"index":0}],"created":1775318365,"id":"d9f968ed-f385-4bc5-a996-690bccd5e461","model":"deepseek-reasoner-search","object":"chat.completion.chunk"}
|
||||
|
||||
data: {"choices":[{"delta":{"reasoning_content":"ian"},"index":0}],"created":1775318365,"id":"d9f968ed-f385-4bc5-a996-690bccd5e461","model":"deepseek-reasoner-search","object":"chat.completion.chunk"}
|
||||
|
||||
data: {"choices":[{"delta":{"reasoning_content":"qi"},"index":0}],"created":1775318365,"id":"d9f968ed-f385-4bc5-a996-690bccd5e461","model":"deepseek-reasoner-search","object":"chat.completion.chunk"}
|
||||
|
||||
data: {"choices":[{"delta":{"reasoning_content":".com"},"index":0}],"created":1775318365,"id":"d9f968ed-f385-4bc5-a996-690bccd5e461","model":"deepseek-reasoner-search","object":"chat.completion.chunk"}
|
||||
|
||||
data: {"choices":[{"delta":{"reasoning_content":"、"},"index":0}],"created":1775318365,"id":"d9f968ed-f385-4bc5-a996-690bccd5e461","model":"deepseek-reasoner-search","object":"chat.completion.chunk"}
|
||||
|
||||
data: {"choices":[{"delta":{"reasoning_content":"e"},"index":0}],"created":1775318365,"id":"d9f968ed-f385-4bc5-a996-690bccd5e461","model":"deepseek-reasoner-search","object":"chat.completion.chunk"}
|
||||
|
||||
data: {"choices":[{"delta":{"reasoning_content":"ast"},"index":0}],"created":1775318365,"id":"d9f968ed-f385-4bc5-a996-690bccd5e461","model":"deepseek-reasoner-search","object":"chat.completion.chunk"}
|
||||
|
||||
data: {"choices":[{"delta":{"reasoning_content":"day"},"index":0}],"created":1775318365,"id":"d9f968ed-f385-4bc5-a996-690bccd5e461","model":"deepseek-reasoner-search","object":"chat.completion.chunk"}
|
||||
|
||||
data: {"choices":[{"delta":{"reasoning_content":".com"},"index":0}],"created":1775318365,"id":"d9f968ed-f385-4bc5-a996-690bccd5e461","model":"deepseek-reasoner-search","object":"chat.completion.chunk"}
|
||||
|
||||
data: {"choices":[{"delta":{"reasoning_content":"等"},"index":0}],"created":1775318365,"id":"d9f968ed-f385-4bc5-a996-690bccd5e461","model":"deepseek-reasoner-search","object":"chat.completion.chunk"}
|
||||
|
||||
data: {"choices":[{"delta":{"reasoning_content":"。"},"index":0}],"created":1775318365,"id":"d9f968ed-f385-4bc5-a996-690bccd5e461","model":"deepseek-reasoner-search","object":"chat.completion.chunk"}
|
||||
|
||||
data: {"choices":[{"delta":{"reasoning_content":"回答"},"index":0}],"created":1775318365,"id":"d9f968ed-f385-4bc5-a996-690bccd5e461","model":"deepseek-reasoner-search","object":"chat.completion.chunk"}
|
||||
|
||||
data: {"choices":[{"delta":{"reasoning_content":"将"},"index":0}],"created":1775318365,"id":"d9f968ed-f385-4bc5-a996-690bccd5e461","model":"deepseek-reasoner-search","object":"chat.completion.chunk"}
|
||||
|
||||
data: {"choices":[{"delta":{"reasoning_content":"涵盖"},"index":0}],"created":1775318365,"id":"d9f968ed-f385-4bc5-a996-690bccd5e461","model":"deepseek-reasoner-search","object":"chat.completion.chunk"}
|
||||
|
||||
data: {"choices":[{"delta":{"reasoning_content":"当前"},"index":0}],"created":1775318365,"id":"d9f968ed-f385-4bc5-a996-690bccd5e461","model":"deepseek-reasoner-search","object":"chat.completion.chunk"}
|
||||
|
||||
data: {"choices":[{"delta":{"reasoning_content":"天气"},"index":0}],"created":1775318365,"id":"d9f968ed-f385-4bc5-a996-690bccd5e461","model":"deepseek-reasoner-search","object":"chat.completion.chunk"}
|
||||
|
||||
data: {"choices":[{"delta":{"reasoning_content":"、"},"index":0}],"created":1775318365,"id":"d9f968ed-f385-4bc5-a996-690bccd5e461","model":"deepseek-reasoner-search","object":"chat.completion.chunk"}
|
||||
|
||||
data: {"choices":[{"delta":{"reasoning_content":"未来"},"index":0}],"created":1775318365,"id":"d9f968ed-f385-4bc5-a996-690bccd5e461","model":"deepseek-reasoner-search","object":"chat.completion.chunk"}
|
||||
|
||||
data: {"choices":[{"delta":{"reasoning_content":"几天"},"index":0}],"created":1775318365,"id":"d9f968ed-f385-4bc5-a996-690bccd5e461","model":"deepseek-reasoner-search","object":"chat.completion.chunk"}
|
||||
|
||||
data: {"choices":[{"delta":{"reasoning_content":"预报"},"index":0}],"created":1775318365,"id":"d9f968ed-f385-4bc5-a996-690bccd5e461","model":"deepseek-reasoner-search","object":"chat.completion.chunk"}
|
||||
|
||||
data: {"choices":[{"delta":{"reasoning_content":"、"},"index":0}],"created":1775318365,"id":"d9f968ed-f385-4bc5-a996-690bccd5e461","model":"deepseek-reasoner-search","object":"chat.completion.chunk"}
|
||||
|
||||
data: {"choices":[{"delta":{"reasoning_content":"预警"},"index":0}],"created":1775318365,"id":"d9f968ed-f385-4bc5-a996-690bccd5e461","model":"deepseek-reasoner-search","object":"chat.completion.chunk"}
|
||||
|
||||
data: {"choices":[{"delta":{"reasoning_content":"信息"},"index":0}],"created":1775318365,"id":"d9f968ed-f385-4bc5-a996-690bccd5e461","model":"deepseek-reasoner-search","object":"chat.completion.chunk"}
|
||||
|
||||
data: {"choices":[{"delta":{"reasoning_content":"以及"},"index":0}],"created":1775318365,"id":"d9f968ed-f385-4bc5-a996-690bccd5e461","model":"deepseek-reasoner-search","object":"chat.completion.chunk"}
|
||||
|
||||
data: {"choices":[{"delta":{"reasoning_content":"相关"},"index":0}],"created":1775318365,"id":"d9f968ed-f385-4bc5-a996-690bccd5e461","model":"deepseek-reasoner-search","object":"chat.completion.chunk"}
|
||||
|
||||
data: {"choices":[{"delta":{"reasoning_content":"提示"},"index":0}],"created":1775318365,"id":"d9f968ed-f385-4bc5-a996-690bccd5e461","model":"deepseek-reasoner-search","object":"chat.completion.chunk"}
|
||||
|
||||
data: {"choices":[{"delta":{"reasoning_content":"。"},"index":0}],"created":1775318365,"id":"d9f968ed-f385-4bc5-a996-690bccd5e461","model":"deepseek-reasoner-search","object":"chat.completion.chunk"}
|
||||
|
||||
data: {"choices":[{"delta":{"content":"广州"},"index":0}],"created":1775318365,"id":"d9f968ed-f385-4bc5-a996-690bccd5e461","model":"deepseek-reasoner-search","object":"chat.completion.chunk"}
|
||||
|
||||
data: {"choices":[{"delta":{"content":"今天"},"index":0}],"created":1775318365,"id":"d9f968ed-f385-4bc5-a996-690bccd5e461","model":"deepseek-reasoner-search","object":"chat.completion.chunk"}
|
||||
|
||||
data: {"choices":[{"delta":{"content":"("},"index":0}],"created":1775318365,"id":"d9f968ed-f385-4bc5-a996-690bccd5e461","model":"deepseek-reasoner-search","object":"chat.completion.chunk"}
|
||||
|
||||
data: {"choices":[{"delta":{"content":"4"},"index":0}],"created":1775318365,"id":"d9f968ed-f385-4bc5-a996-690bccd5e461","model":"deepseek-reasoner-search","object":"chat.completion.chunk"}
|
||||
|
||||
data: {"choices":[{"delta":{"content":"月"},"index":0}],"created":1775318365,"id":"d9f968ed-f385-4bc5-a996-690bccd5e461","model":"deepseek-reasoner-search","object":"chat.completion.chunk"}
|
||||
|
||||
data: {"choices":[{"delta":{"content":"4"},"index":0}],"created":1775318365,"id":"d9f968ed-f385-4bc5-a996-690bccd5e461","model":"deepseek-reasoner-search","object":"chat.completion.chunk"}
|
||||
|
||||
data: {"choices":[{"delta":{"content":"日"},"index":0}],"created":1775318365,"id":"d9f968ed-f385-4bc5-a996-690bccd5e461","model":"deepseek-reasoner-search","object":"chat.completion.chunk"}
|
||||
|
||||
data: {"choices":[{"delta":{"content":")"},"index":0}],"created":1775318365,"id":"d9f968ed-f385-4bc5-a996-690bccd5e461","model":"deepseek-reasoner-search","object":"chat.completion.chunk"}
|
||||
|
||||
data: {"choices":[{"delta":{"content":"天气"},"index":0}],"created":1775318365,"id":"d9f968ed-f385-4bc5-a996-690bccd5e461","model":"deepseek-reasoner-search","object":"chat.completion.chunk"}
|
||||
|
||||
data: {"choices":[{"delta":{"content":"不稳定"},"index":0}],"created":1775318365,"id":"d9f968ed-f385-4bc5-a996-690bccd5e461","model":"deepseek-reasoner-search","object":"chat.completion.chunk"}
|
||||
|
||||
data: {"choices":[{"delta":{"content":","},"index":0}],"created":1775318365,"id":"d9f968ed-f385-4bc5-a996-690bccd5e461","model":"deepseek-reasoner-search","object":"chat.completion.chunk"}
|
||||
|
||||
data: {"choices":[{"delta":{"content":"**"},"index":0}],"created":1775318365,"id":"d9f968ed-f385-4bc5-a996-690bccd5e461","model":"deepseek-reasoner-search","object":"chat.completion.chunk"}
|
||||
|
||||
data: {"choices":[{"delta":{"content":"多"},"index":0}],"created":1775318365,"id":"d9f968ed-f385-4bc5-a996-690bccd5e461","model":"deepseek-reasoner-search","object":"chat.completion.chunk"}
|
||||
|
||||
data: {"choices":[{"delta":{"content":"区"},"index":0}],"created":1775318365,"id":"d9f968ed-f385-4bc5-a996-690bccd5e461","model":"deepseek-reasoner-search","object":"chat.completion.chunk"}
|
||||
|
||||
data: {"choices":[{"delta":{"content":"有"},"index":0}],"created":1775318365,"id":"d9f968ed-f385-4bc5-a996-690bccd5e461","model":"deepseek-reasoner-search","object":"chat.completion.chunk"}
|
||||
|
||||
data: {"choices":[{"delta":{"content":"暴雨"},"index":0}],"created":1775318365,"id":"d9f968ed-f385-4bc5-a996-690bccd5e461","model":"deepseek-reasoner-search","object":"chat.completion.chunk"}
|
||||
|
||||
data: {"choices":[{"delta":{"content":"和"},"index":0}],"created":1775318365,"id":"d9f968ed-f385-4bc5-a996-690bccd5e461","model":"deepseek-reasoner-search","object":"chat.completion.chunk"}
|
||||
|
||||
data: {"choices":[{"delta":{"content":"强"},"index":0}],"created":1775318365,"id":"d9f968ed-f385-4bc5-a996-690bccd5e461","model":"deepseek-reasoner-search","object":"chat.completion.chunk"}
|
||||
|
||||
data: {"choices":[{"delta":{"content":"对流"},"index":0}],"created":1775318365,"id":"d9f968ed-f385-4bc5-a996-690bccd5e461","model":"deepseek-reasoner-search","object":"chat.completion.chunk"}
|
||||
|
||||
data: {"choices":[{"delta":{"content":"预警"},"index":0}],"created":1775318365,"id":"d9f968ed-f385-4bc5-a996-690bccd5e461","model":"deepseek-reasoner-search","object":"chat.completion.chunk"}
|
||||
|
||||
data: {"choices":[{"delta":{"content":"**"},"index":0}],"created":1775318365,"id":"d9f968ed-f385-4bc5-a996-690bccd5e461","model":"deepseek-reasoner-search","object":"chat.completion.chunk"}
|
||||
|
||||
data: {"choices":[{"delta":{"content":"[reference:0]"},"index":0}],"created":1775318365,"id":"d9f968ed-f385-4bc5-a996-690bccd5e461","model":"deepseek-reasoner-search","object":"chat.completion.chunk"}
|
||||
|
||||
data: {"choices":[{"delta":{"content":"[reference:1]"},"index":0}],"created":1775318365,"id":"d9f968ed-f385-4bc5-a996-690bccd5e461","model":"deepseek-reasoner-search","object":"chat.completion.chunk"}
|
||||
|
||||
data: {"choices":[{"delta":{"content":"。"},"index":0}],"created":1775318365,"id":"d9f968ed-f385-4bc5-a996-690bccd5e461","model":"deepseek-reasoner-search","object":"chat.completion.chunk"}
|
||||
|
||||
data: {"choices":[{"delta":{"content":"未来"},"index":0}],"created":1775318365,"id":"d9f968ed-f385-4bc5-a996-690bccd5e461","model":"deepseek-reasoner-search","object":"chat.completion.chunk"}
|
||||
|
||||
data: {"choices":[{"delta":{"content":"一周"},"index":0}],"created":1775318365,"id":"d9f968ed-f385-4bc5-a996-690bccd5e461","model":"deepseek-reasoner-search","object":"chat.completion.chunk"}
|
||||
|
||||
data: {"choices":[{"delta":{"content":"以"},"index":0}],"created":1775318365,"id":"d9f968ed-f385-4bc5-a996-690bccd5e461","model":"deepseek-reasoner-search","object":"chat.completion.chunk"}
|
||||
|
||||
data: {"choices":[{"delta":{"content":"阴"},"index":0}],"created":1775318365,"id":"d9f968ed-f385-4bc5-a996-690bccd5e461","model":"deepseek-reasoner-search","object":"chat.completion.chunk"}
|
||||
|
||||
data: {"choices":[{"delta":{"content":"雨"},"index":0}],"created":1775318365,"id":"d9f968ed-f385-4bc5-a996-690bccd5e461","model":"deepseek-reasoner-search","object":"chat.completion.chunk"}
|
||||
|
||||
data: {"choices":[{"delta":{"content":"天气"},"index":0}],"created":1775318365,"id":"d9f968ed-f385-4bc5-a996-690bccd5e461","model":"deepseek-reasoner-search","object":"chat.completion.chunk"}
|
||||
|
||||
data: {"choices":[{"delta":{"content":"为主"},"index":0}],"created":1775318365,"id":"d9f968ed-f385-4bc5-a996-690bccd5e461","model":"deepseek-reasoner-search","object":"chat.completion.chunk"}
|
||||
|
||||
data: {"choices":[{"delta":{"content":","},"index":0}],"created":1775318365,"id":"d9f968ed-f385-4bc5-a996-690bccd5e461","model":"deepseek-reasoner-search","object":"chat.completion.chunk"}
|
||||
|
||||
data: {"choices":[{"delta":{"content":"特别是"},"index":0}],"created":1775318365,"id":"d9f968ed-f385-4bc5-a996-690bccd5e461","model":"deepseek-reasoner-search","object":"chat.completion.chunk"}
|
||||
|
||||
data: {"choices":[{"delta":{"content":"明"},"index":0}],"created":1775318365,"id":"d9f968ed-f385-4bc5-a996-690bccd5e461","model":"deepseek-reasoner-search","object":"chat.completion.chunk"}
|
||||
|
||||
data: {"choices":[{"delta":{"content":"后"},"index":0}],"created":1775318365,"id":"d9f968ed-f385-4bc5-a996-690bccd5e461","model":"deepseek-reasoner-search","object":"chat.completion.chunk"}
|
||||
|
||||
data: {"choices":[{"delta":{"content":"两天"},"index":0}],"created":1775318365,"id":"d9f968ed-f385-4bc5-a996-690bccd5e461","model":"deepseek-reasoner-search","object":"chat.completion.chunk"}
|
||||
|
||||
data: {"choices":[{"delta":{"content":"("},"index":0}],"created":1775318365,"id":"d9f968ed-f385-4bc5-a996-690bccd5e461","model":"deepseek-reasoner-search","object":"chat.completion.chunk"}
|
||||
|
||||
data: {"choices":[{"delta":{"content":"4"},"index":0}],"created":1775318365,"id":"d9f968ed-f385-4bc5-a996-690bccd5e461","model":"deepseek-reasoner-search","object":"chat.completion.chunk"}
|
||||
|
||||
data: {"choices":[{"delta":{"content":"月"},"index":0}],"created":1775318365,"id":"d9f968ed-f385-4bc5-a996-690bccd5e461","model":"deepseek-reasoner-search","object":"chat.completion.chunk"}
|
||||
|
||||
data: {"choices":[{"delta":{"content":"5"},"index":0}],"created":1775318365,"id":"d9f968ed-f385-4bc5-a996-690bccd5e461","model":"deepseek-reasoner-search","object":"chat.completion.chunk"}
|
||||
|
||||
data: {"choices":[{"delta":{"content":"日"},"index":0}],"created":1775318365,"id":"d9f968ed-f385-4bc5-a996-690bccd5e461","model":"deepseek-reasoner-search","object":"chat.completion.chunk"}
|
||||
|
||||
data: {"choices":[{"delta":{"content":"-"},"index":0}],"created":1775318365,"id":"d9f968ed-f385-4bc5-a996-690bccd5e461","model":"deepseek-reasoner-search","object":"chat.completion.chunk"}
|
||||
|
||||
data: {"choices":[{"delta":{"content":"6"},"index":0}],"created":1775318365,"id":"d9f968ed-f385-4bc5-a996-690bccd5e461","model":"deepseek-reasoner-search","object":"chat.completion.chunk"}
|
||||
|
||||
data: {"choices":[{"delta":{"content":"日"},"index":0}],"created":1775318365,"id":"d9f968ed-f385-4bc5-a996-690bccd5e461","model":"deepseek-reasoner-search","object":"chat.completion.chunk"}
|
||||
|
||||
data: {"choices":[{"delta":{"content":")"},"index":0}],"created":1775318365,"id":"d9f968ed-f385-4bc5-a996-690bccd5e461","model":"deepseek-reasoner-search","object":"chat.completion.chunk"}
|
||||
|
||||
data: {"choices":[{"delta":{"content":"雨"},"index":0}],"created":1775318365,"id":"d9f968ed-f385-4bc5-a996-690bccd5e461","model":"deepseek-reasoner-search","object":"chat.completion.chunk"}
|
||||
|
||||
data: {"choices":[{"delta":{"content":"势"},"index":0}],"created":1775318365,"id":"d9f968ed-f385-4bc5-a996-690bccd5e461","model":"deepseek-reasoner-search","object":"chat.completion.chunk"}
|
||||
|
||||
data: {"choices":[{"delta":{"content":"较大"},"index":0}],"created":1775318365,"id":"d9f968ed-f385-4bc5-a996-690bccd5e461","model":"deepseek-reasoner-search","object":"chat.completion.chunk"}
|
||||
|
||||
data: {"choices":[{"delta":{"content":"。\n\n"},"index":0}],"created":1775318365,"id":"d9f968ed-f385-4bc5-a996-690bccd5e461","model":"deepseek-reasoner-search","object":"chat.completion.chunk"}
|
||||
|
||||
data: {"choices":[{"delta":{"content":"*"},"index":0}],"created":1775318365,"id":"d9f968ed-f385-4bc5-a996-690bccd5e461","model":"deepseek-reasoner-search","object":"chat.completion.chunk"}
|
||||
|
||||
data: {"choices":[{"delta":{"content":" **"},"index":0}],"created":1775318365,"id":"d9f968ed-f385-4bc5-a996-690bccd5e461","model":"deepseek-reasoner-search","object":"chat.completion.chunk"}
|
||||
|
||||
data: {"choices":[{"delta":{"content":"今日"},"index":0}],"created":1775318365,"id":"d9f968ed-f385-4bc5-a996-690bccd5e461","model":"deepseek-reasoner-search","object":"chat.completion.chunk"}
|
||||
|
||||
data: {"choices":[{"delta":{"content":"("},"index":0}],"created":1775318365,"id":"d9f968ed-f385-4bc5-a996-690bccd5e461","model":"deepseek-reasoner-search","object":"chat.completion.chunk"}
|
||||
|
||||
data: {"choices":[{"delta":{"content":"4"},"index":0}],"created":1775318365,"id":"d9f968ed-f385-4bc5-a996-690bccd5e461","model":"deepseek-reasoner-search","object":"chat.completion.chunk"}
|
||||
|
||||
data: {"choices":[{"delta":{"content":"月"},"index":0}],"created":1775318365,"id":"d9f968ed-f385-4bc5-a996-690bccd5e461","model":"deepseek-reasoner-search","object":"chat.completion.chunk"}
|
||||
|
||||
data: {"choices":[{"delta":{"content":"4"},"index":0}],"created":1775318365,"id":"d9f968ed-f385-4bc5-a996-690bccd5e461","model":"deepseek-reasoner-search","object":"chat.completion.chunk"}
|
||||
|
||||
data: {"choices":[{"delta":{"content":"日"},"index":0}],"created":1775318365,"id":"d9f968ed-f385-4bc5-a996-690bccd5e461","model":"deepseek-reasoner-search","object":"chat.completion.chunk"}
|
||||
|
||||
data: {"choices":[{"delta":{"content":")"},"index":0}],"created":1775318365,"id":"d9f968ed-f385-4bc5-a996-690bccd5e461","model":"deepseek-reasoner-search","object":"chat.completion.chunk"}
|
||||
|
||||
data: {"choices":[{"delta":{"content":"**"},"index":0}],"created":1775318365,"id":"d9f968ed-f385-4bc5-a996-690bccd5e461","model":"deepseek-reasoner-search","object":"chat.completion.chunk"}
|
||||
|
||||
data: {"choices":[{"delta":{"content":":"},"index":0}],"created":1775318365,"id":"d9f968ed-f385-4bc5-a996-690bccd5e461","model":"deepseek-reasoner-search","object":"chat.completion.chunk"}
|
||||
|
||||
data: {"choices":[{"delta":{"content":"中"},"index":0}],"created":1775318365,"id":"d9f968ed-f385-4bc5-a996-690bccd5e461","model":"deepseek-reasoner-search","object":"chat.completion.chunk"}
|
||||
|
||||
data: {"choices":[{"delta":{"content":"到大"},"index":0}],"created":1775318365,"id":"d9f968ed-f385-4bc5-a996-690bccd5e461","model":"deepseek-reasoner-search","object":"chat.completion.chunk"}
|
||||
|
||||
data: {"choices":[{"delta":{"content":"雨"},"index":0}],"created":1775318365,"id":"d9f968ed-f385-4bc5-a996-690bccd5e461","model":"deepseek-reasoner-search","object":"chat.completion.chunk"}
|
||||
|
||||
data: {"choices":[{"delta":{"content":"转"},"index":0}],"created":1775318365,"id":"d9f968ed-f385-4bc5-a996-690bccd5e461","model":"deepseek-reasoner-search","object":"chat.completion.chunk"}
|
||||
|
||||
data: {"choices":[{"delta":{"content":"多云"},"index":0}],"created":1775318365,"id":"d9f968ed-f385-4bc5-a996-690bccd5e461","model":"deepseek-reasoner-search","object":"chat.completion.chunk"}
|
||||
|
||||
data: {"choices":[{"delta":{"content":","},"index":0}],"created":1775318365,"id":"d9f968ed-f385-4bc5-a996-690bccd5e461","model":"deepseek-reasoner-search","object":"chat.completion.chunk"}
|
||||
|
||||
data: {"choices":[{"delta":{"content":"20"},"index":0}],"created":1775318365,"id":"d9f968ed-f385-4bc5-a996-690bccd5e461","model":"deepseek-reasoner-search","object":"chat.completion.chunk"}
|
||||
|
||||
data: {"choices":[{"delta":{"content":"℃"},"index":0}],"created":1775318365,"id":"d9f968ed-f385-4bc5-a996-690bccd5e461","model":"deepseek-reasoner-search","object":"chat.completion.chunk"}
|
||||
|
||||
data: {"choices":[{"delta":{"content":" ~"},"index":0}],"created":1775318365,"id":"d9f968ed-f385-4bc5-a996-690bccd5e461","model":"deepseek-reasoner-search","object":"chat.completion.chunk"}
|
||||
|
||||
data: {"choices":[{"delta":{"content":"26"},"index":0}],"created":1775318365,"id":"d9f968ed-f385-4bc5-a996-690bccd5e461","model":"deepseek-reasoner-search","object":"chat.completion.chunk"}
|
||||
|
||||
data: {"choices":[{"delta":{"content":"℃,"},"index":0}],"created":1775318365,"id":"d9f968ed-f385-4bc5-a996-690bccd5e461","model":"deepseek-reasoner-search","object":"chat.completion.chunk"}
|
||||
|
||||
data: {"choices":[{"delta":{"content":"微风"},"index":0}],"created":1775318365,"id":"d9f968ed-f385-4bc5-a996-690bccd5e461","model":"deepseek-reasoner-search","object":"chat.completion.chunk"}
|
||||
|
||||
data: {"choices":[{"delta":{"content":","},"index":0}],"created":1775318365,"id":"d9f968ed-f385-4bc5-a996-690bccd5e461","model":"deepseek-reasoner-search","object":"chat.completion.chunk"}
|
||||
|
||||
data: {"choices":[{"delta":{"content":"相对"},"index":0}],"created":1775318365,"id":"d9f968ed-f385-4bc5-a996-690bccd5e461","model":"deepseek-reasoner-search","object":"chat.completion.chunk"}
|
||||
|
||||
data: {"choices":[{"delta":{"content":"湿度"},"index":0}],"created":1775318365,"id":"d9f968ed-f385-4bc5-a996-690bccd5e461","model":"deepseek-reasoner-search","object":"chat.completion.chunk"}
|
||||
|
||||
data: {"choices":[{"delta":{"content":"约"},"index":0}],"created":1775318365,"id":"d9f968ed-f385-4bc5-a996-690bccd5e461","model":"deepseek-reasoner-search","object":"chat.completion.chunk"}
|
||||
|
||||
data: {"choices":[{"delta":{"content":"88"},"index":0}],"created":1775318365,"id":"d9f968ed-f385-4bc5-a996-690bccd5e461","model":"deepseek-reasoner-search","object":"chat.completion.chunk"}
|
||||
|
||||
data: {"choices":[{"delta":{"content":"%-"},"index":0}],"created":1775318365,"id":"d9f968ed-f385-4bc5-a996-690bccd5e461","model":"deepseek-reasoner-search","object":"chat.completion.chunk"}
|
||||
|
||||
data: {"choices":[{"delta":{"content":"96"},"index":0}],"created":1775318365,"id":"d9f968ed-f385-4bc5-a996-690bccd5e461","model":"deepseek-reasoner-search","object":"chat.completion.chunk"}
|
||||
|
||||
data: {"choices":[{"delta":{"content":"%"},"index":0}],"created":1775318365,"id":"d9f968ed-f385-4bc5-a996-690bccd5e461","model":"deepseek-reasoner-search","object":"chat.completion.chunk"}
|
||||
|
||||
data: {"choices":[{"delta":{"content":"[reference:2]"},"index":0}],"created":1775318365,"id":"d9f968ed-f385-4bc5-a996-690bccd5e461","model":"deepseek-reasoner-search","object":"chat.completion.chunk"}
|
||||
|
||||
data: {"choices":[{"delta":{"content":"[reference:3]"},"index":0}],"created":1775318365,"id":"d9f968ed-f385-4bc5-a996-690bccd5e461","model":"deepseek-reasoner-search","object":"chat.completion.chunk"}
|
||||
|
||||
data: {"choices":[{"delta":{"content":"[reference:4]"},"index":0}],"created":1775318365,"id":"d9f968ed-f385-4bc5-a996-690bccd5e461","model":"deepseek-reasoner-search","object":"chat.completion.chunk"}
|
||||
|
||||
data: {"choices":[{"delta":{"content":"[reference:5]"},"index":0}],"created":1775318365,"id":"d9f968ed-f385-4bc5-a996-690bccd5e461","model":"deepseek-reasoner-search","object":"chat.completion.chunk"}
|
||||
|
||||
data: {"choices":[{"delta":{"content":"。\n"},"index":0}],"created":1775318365,"id":"d9f968ed-f385-4bc5-a996-690bccd5e461","model":"deepseek-reasoner-search","object":"chat.completion.chunk"}
|
||||
|
||||
data: {"choices":[{"delta":{"content":"*"},"index":0}],"created":1775318365,"id":"d9f968ed-f385-4bc5-a996-690bccd5e461","model":"deepseek-reasoner-search","object":"chat.completion.chunk"}
|
||||
|
||||
data: {"choices":[{"delta":{"content":" **"},"index":0}],"created":1775318365,"id":"d9f968ed-f385-4bc5-a996-690bccd5e461","model":"deepseek-reasoner-search","object":"chat.completion.chunk"}
|
||||
|
||||
data: {"choices":[{"delta":{"content":"明天"},"index":0}],"created":1775318365,"id":"d9f968ed-f385-4bc5-a996-690bccd5e461","model":"deepseek-reasoner-search","object":"chat.completion.chunk"}
|
||||
|
||||
data: {"choices":[{"delta":{"content":"("},"index":0}],"created":1775318365,"id":"d9f968ed-f385-4bc5-a996-690bccd5e461","model":"deepseek-reasoner-search","object":"chat.completion.chunk"}
|
||||
|
||||
data: {"choices":[{"delta":{"content":"4"},"index":0}],"created":1775318365,"id":"d9f968ed-f385-4bc5-a996-690bccd5e461","model":"deepseek-reasoner-search","object":"chat.completion.chunk"}
|
||||
|
||||
data: {"choices":[{"delta":{"content":"月"},"index":0}],"created":1775318365,"id":"d9f968ed-f385-4bc5-a996-690bccd5e461","model":"deepseek-reasoner-search","object":"chat.completion.chunk"}
|
||||
|
||||
data: {"choices":[{"delta":{"content":"5"},"index":0}],"created":1775318365,"id":"d9f968ed-f385-4bc5-a996-690bccd5e461","model":"deepseek-reasoner-search","object":"chat.completion.chunk"}
|
||||
|
||||
data: {"choices":[{"delta":{"content":"日"},"index":0}],"created":1775318365,"id":"d9f968ed-f385-4bc5-a996-690bccd5e461","model":"deepseek-reasoner-search","object":"chat.completion.chunk"}
|
||||
|
||||
data: {"choices":[{"delta":{"content":")"},"index":0}],"created":1775318365,"id":"d9f968ed-f385-4bc5-a996-690bccd5e461","model":"deepseek-reasoner-search","object":"chat.completion.chunk"}
|
||||
|
||||
data: {"choices":[{"delta":{"content":"**"},"index":0}],"created":1775318365,"id":"d9f968ed-f385-4bc5-a996-690bccd5e461","model":"deepseek-reasoner-search","object":"chat.completion.chunk"}
|
||||
|
||||
data: {"choices":[{"delta":{"content":":"},"index":0}],"created":1775318365,"id":"d9f968ed-f385-4bc5-a996-690bccd5e461","model":"deepseek-reasoner-search","object":"chat.completion.chunk"}
|
||||
|
||||
data: {"choices":[{"delta":{"content":"大到"},"index":0}],"created":1775318365,"id":"d9f968ed-f385-4bc5-a996-690bccd5e461","model":"deepseek-reasoner-search","object":"chat.completion.chunk"}
|
||||
|
||||
data: {"choices":[{"delta":{"content":"暴雨"},"index":0}],"created":1775318365,"id":"d9f968ed-f385-4bc5-a996-690bccd5e461","model":"deepseek-reasoner-search","object":"chat.completion.chunk"}
|
||||
|
||||
data: {"choices":[{"delta":{"content":"转"},"index":0}],"created":1775318365,"id":"d9f968ed-f385-4bc5-a996-690bccd5e461","model":"deepseek-reasoner-search","object":"chat.completion.chunk"}
|
||||
|
||||
data: {"choices":[{"delta":{"content":"雷"},"index":0}],"created":1775318365,"id":"d9f968ed-f385-4bc5-a996-690bccd5e461","model":"deepseek-reasoner-search","object":"chat.completion.chunk"}
|
||||
|
||||
data: {"choices":[{"delta":{"content":"阵"},"index":0}],"created":1775318365,"id":"d9f968ed-f385-4bc5-a996-690bccd5e461","model":"deepseek-reasoner-search","object":"chat.completion.chunk"}
|
||||
|
||||
data: {"choices":[{"delta":{"content":"雨"},"index":0}],"created":1775318365,"id":"d9f968ed-f385-4bc5-a996-690bccd5e461","model":"deepseek-reasoner-search","object":"chat.completion.chunk"}
|
||||
|
||||
data: {"choices":[{"delta":{"content":","},"index":0}],"created":1775318365,"id":"d9f968ed-f385-4bc5-a996-690bccd5e461","model":"deepseek-reasoner-search","object":"chat.completion.chunk"}
|
||||
|
||||
data: {"choices":[{"delta":{"content":"20"},"index":0}],"created":1775318365,"id":"d9f968ed-f385-4bc5-a996-690bccd5e461","model":"deepseek-reasoner-search","object":"chat.completion.chunk"}
|
||||
|
||||
data: {"choices":[{"delta":{"content":"℃"},"index":0}],"created":1775318365,"id":"d9f968ed-f385-4bc5-a996-690bccd5e461","model":"deepseek-reasoner-search","object":"chat.completion.chunk"}
|
||||
|
||||
data: {"choices":[{"delta":{"content":" ~"},"index":0}],"created":1775318365,"id":"d9f968ed-f385-4bc5-a996-690bccd5e461","model":"deepseek-reasoner-search","object":"chat.completion.chunk"}
|
||||
|
||||
data: {"choices":[{"delta":{"content":"25"},"index":0}],"created":1775318365,"id":"d9f968ed-f385-4bc5-a996-690bccd5e461","model":"deepseek-reasoner-search","object":"chat.completion.chunk"}
|
||||
|
||||
data: {"choices":[{"delta":{"content":"℃"},"index":0}],"created":1775318365,"id":"d9f968ed-f385-4bc5-a996-690bccd5e461","model":"deepseek-reasoner-search","object":"chat.completion.chunk"}
|
||||
|
||||
data: {"choices":[{"delta":{"content":"[reference:6]"},"index":0}],"created":1775318365,"id":"d9f968ed-f385-4bc5-a996-690bccd5e461","model":"deepseek-reasoner-search","object":"chat.completion.chunk"}
|
||||
|
||||
data: {"choices":[{"delta":{"content":"[reference:7]"},"index":0}],"created":1775318365,"id":"d9f968ed-f385-4bc5-a996-690bccd5e461","model":"deepseek-reasoner-search","object":"chat.completion.chunk"}
|
||||
|
||||
data: {"choices":[{"delta":{"content":"[reference:8]"},"index":0}],"created":1775318365,"id":"d9f968ed-f385-4bc5-a996-690bccd5e461","model":"deepseek-reasoner-search","object":"chat.completion.chunk"}
|
||||
|
||||
data: {"choices":[{"delta":{"content":"[reference:9]"},"index":0}],"created":1775318365,"id":"d9f968ed-f385-4bc5-a996-690bccd5e461","model":"deepseek-reasoner-search","object":"chat.completion.chunk"}
|
||||
|
||||
data: {"choices":[{"delta":{"content":"。\n"},"index":0}],"created":1775318365,"id":"d9f968ed-f385-4bc5-a996-690bccd5e461","model":"deepseek-reasoner-search","object":"chat.completion.chunk"}
|
||||
|
||||
data: {"choices":[{"delta":{"content":"*"},"index":0}],"created":1775318365,"id":"d9f968ed-f385-4bc5-a996-690bccd5e461","model":"deepseek-reasoner-search","object":"chat.completion.chunk"}
|
||||
|
||||
data: {"choices":[{"delta":{"content":" **"},"index":0}],"created":1775318365,"id":"d9f968ed-f385-4bc5-a996-690bccd5e461","model":"deepseek-reasoner-search","object":"chat.completion.chunk"}
|
||||
|
||||
data: {"choices":[{"delta":{"content":"后天"},"index":0}],"created":1775318365,"id":"d9f968ed-f385-4bc5-a996-690bccd5e461","model":"deepseek-reasoner-search","object":"chat.completion.chunk"}
|
||||
|
||||
data: {"choices":[{"delta":{"content":"("},"index":0}],"created":1775318365,"id":"d9f968ed-f385-4bc5-a996-690bccd5e461","model":"deepseek-reasoner-search","object":"chat.completion.chunk"}
|
||||
|
||||
data: {"choices":[{"delta":{"content":"4"},"index":0}],"created":1775318365,"id":"d9f968ed-f385-4bc5-a996-690bccd5e461","model":"deepseek-reasoner-search","object":"chat.completion.chunk"}
|
||||
|
||||
data: {"choices":[{"delta":{"content":"月"},"index":0}],"created":1775318365,"id":"d9f968ed-f385-4bc5-a996-690bccd5e461","model":"deepseek-reasoner-search","object":"chat.completion.chunk"}
|
||||
|
||||
data: {"choices":[{"delta":{"content":"6"},"index":0}],"created":1775318365,"id":"d9f968ed-f385-4bc5-a996-690bccd5e461","model":"deepseek-reasoner-search","object":"chat.completion.chunk"}
|
||||
|
||||
data: {"choices":[{"delta":{"content":"日"},"index":0}],"created":1775318365,"id":"d9f968ed-f385-4bc5-a996-690bccd5e461","model":"deepseek-reasoner-search","object":"chat.completion.chunk"}
|
||||
|
||||
data: {"choices":[{"delta":{"content":")"},"index":0}],"created":1775318365,"id":"d9f968ed-f385-4bc5-a996-690bccd5e461","model":"deepseek-reasoner-search","object":"chat.completion.chunk"}
|
||||
|
||||
data: {"choices":[{"delta":{"content":"**"},"index":0}],"created":1775318365,"id":"d9f968ed-f385-4bc5-a996-690bccd5e461","model":"deepseek-reasoner-search","object":"chat.completion.chunk"}
|
||||
|
||||
data: {"choices":[{"delta":{"content":":"},"index":0}],"created":1775318365,"id":"d9f968ed-f385-4bc5-a996-690bccd5e461","model":"deepseek-reasoner-search","object":"chat.completion.chunk"}
|
||||
|
||||
data: {"choices":[{"delta":{"content":"中"},"index":0}],"created":1775318365,"id":"d9f968ed-f385-4bc5-a996-690bccd5e461","model":"deepseek-reasoner-search","object":"chat.completion.chunk"}
|
||||
|
||||
data: {"choices":[{"delta":{"content":"雨"},"index":0}],"created":1775318365,"id":"d9f968ed-f385-4bc5-a996-690bccd5e461","model":"deepseek-reasoner-search","object":"chat.completion.chunk"}
|
||||
|
||||
data: {"choices":[{"delta":{"content":"转"},"index":0}],"created":1775318365,"id":"d9f968ed-f385-4bc5-a996-690bccd5e461","model":"deepseek-reasoner-search","object":"chat.completion.chunk"}
|
||||
|
||||
data: {"choices":[{"delta":{"content":"多云"},"index":0}],"created":1775318365,"id":"d9f968ed-f385-4bc5-a996-690bccd5e461","model":"deepseek-reasoner-search","object":"chat.completion.chunk"}
|
||||
|
||||
data: {"choices":[{"delta":{"content":","},"index":0}],"created":1775318365,"id":"d9f968ed-f385-4bc5-a996-690bccd5e461","model":"deepseek-reasoner-search","object":"chat.completion.chunk"}
|
||||
|
||||
data: {"choices":[{"delta":{"content":"23"},"index":0}],"created":1775318365,"id":"d9f968ed-f385-4bc5-a996-690bccd5e461","model":"deepseek-reasoner-search","object":"chat.completion.chunk"}
|
||||
|
||||
data: {"choices":[{"delta":{"content":"℃"},"index":0}],"created":1775318365,"id":"d9f968ed-f385-4bc5-a996-690bccd5e461","model":"deepseek-reasoner-search","object":"chat.completion.chunk"}
|
||||
|
||||
data: {"choices":[{"delta":{"content":" ~"},"index":0}],"created":1775318365,"id":"d9f968ed-f385-4bc5-a996-690bccd5e461","model":"deepseek-reasoner-search","object":"chat.completion.chunk"}
|
||||
|
||||
data: {"choices":[{"delta":{"content":"30"},"index":0}],"created":1775318365,"id":"d9f968ed-f385-4bc5-a996-690bccd5e461","model":"deepseek-reasoner-search","object":"chat.completion.chunk"}
|
||||
|
||||
data: {"choices":[{"delta":{"content":"℃"},"index":0}],"created":1775318365,"id":"d9f968ed-f385-4bc5-a996-690bccd5e461","model":"deepseek-reasoner-search","object":"chat.completion.chunk"}
|
||||
|
||||
data: {"choices":[{"delta":{"content":"[reference:10]"},"index":0}],"created":1775318365,"id":"d9f968ed-f385-4bc5-a996-690bccd5e461","model":"deepseek-reasoner-search","object":"chat.completion.chunk"}
|
||||
|
||||
data: {"choices":[{"delta":{"content":"[reference:11]"},"index":0}],"created":1775318365,"id":"d9f968ed-f385-4bc5-a996-690bccd5e461","model":"deepseek-reasoner-search","object":"chat.completion.chunk"}
|
||||
|
||||
data: {"choices":[{"delta":{"content":"[reference:12]"},"index":0}],"created":1775318365,"id":"d9f968ed-f385-4bc5-a996-690bccd5e461","model":"deepseek-reasoner-search","object":"chat.completion.chunk"}
|
||||
|
||||
data: {"choices":[{"delta":{"content":"。\n"},"index":0}],"created":1775318365,"id":"d9f968ed-f385-4bc5-a996-690bccd5e461","model":"deepseek-reasoner-search","object":"chat.completion.chunk"}
|
||||
|
||||
data: {"choices":[{"delta":{"content":"*"},"index":0}],"created":1775318365,"id":"d9f968ed-f385-4bc5-a996-690bccd5e461","model":"deepseek-reasoner-search","object":"chat.completion.chunk"}
|
||||
|
||||
data: {"choices":[{"delta":{"content":" **"},"index":0}],"created":1775318365,"id":"d9f968ed-f385-4bc5-a996-690bccd5e461","model":"deepseek-reasoner-search","object":"chat.completion.chunk"}
|
||||
|
||||
data: {"choices":[{"delta":{"content":"周二"},"index":0}],"created":1775318365,"id":"d9f968ed-f385-4bc5-a996-690bccd5e461","model":"deepseek-reasoner-search","object":"chat.completion.chunk"}
|
||||
|
||||
data: {"choices":[{"delta":{"content":"("},"index":0}],"created":1775318365,"id":"d9f968ed-f385-4bc5-a996-690bccd5e461","model":"deepseek-reasoner-search","object":"chat.completion.chunk"}
|
||||
|
||||
data: {"choices":[{"delta":{"content":"4"},"index":0}],"created":1775318365,"id":"d9f968ed-f385-4bc5-a996-690bccd5e461","model":"deepseek-reasoner-search","object":"chat.completion.chunk"}
|
||||
|
||||
data: {"choices":[{"delta":{"content":"月"},"index":0}],"created":1775318365,"id":"d9f968ed-f385-4bc5-a996-690bccd5e461","model":"deepseek-reasoner-search","object":"chat.completion.chunk"}
|
||||
|
||||
data: {"choices":[{"delta":{"content":"7"},"index":0}],"created":1775318365,"id":"d9f968ed-f385-4bc5-a996-690bccd5e461","model":"deepseek-reasoner-search","object":"chat.completion.chunk"}
|
||||
|
||||
data: {"choices":[{"delta":{"content":"日"},"index":0}],"created":1775318365,"id":"d9f968ed-f385-4bc5-a996-690bccd5e461","model":"deepseek-reasoner-search","object":"chat.completion.chunk"}
|
||||
|
||||
data: {"choices":[{"delta":{"content":")"},"index":0}],"created":1775318365,"id":"d9f968ed-f385-4bc5-a996-690bccd5e461","model":"deepseek-reasoner-search","object":"chat.completion.chunk"}
|
||||
|
||||
data: {"choices":[{"delta":{"content":"**"},"index":0}],"created":1775318365,"id":"d9f968ed-f385-4bc5-a996-690bccd5e461","model":"deepseek-reasoner-search","object":"chat.completion.chunk"}
|
||||
|
||||
data: {"choices":[{"delta":{"content":":"},"index":0}],"created":1775318365,"id":"d9f968ed-f385-4bc5-a996-690bccd5e461","model":"deepseek-reasoner-search","object":"chat.completion.chunk"}
|
||||
|
||||
data: {"choices":[{"delta":{"content":"雷"},"index":0}],"created":1775318365,"id":"d9f968ed-f385-4bc5-a996-690bccd5e461","model":"deepseek-reasoner-search","object":"chat.completion.chunk"}
|
||||
|
||||
data: {"choices":[{"delta":{"content":"阵"},"index":0}],"created":1775318365,"id":"d9f968ed-f385-4bc5-a996-690bccd5e461","model":"deepseek-reasoner-search","object":"chat.completion.chunk"}
|
||||
|
||||
data: {"choices":[{"delta":{"content":"雨"},"index":0}],"created":1775318365,"id":"d9f968ed-f385-4bc5-a996-690bccd5e461","model":"deepseek-reasoner-search","object":"chat.completion.chunk"}
|
||||
|
||||
data: {"choices":[{"delta":{"content":"转"},"index":0}],"created":1775318365,"id":"d9f968ed-f385-4bc5-a996-690bccd5e461","model":"deepseek-reasoner-search","object":"chat.completion.chunk"}
|
||||
|
||||
data: {"choices":[{"delta":{"content":"多云"},"index":0}],"created":1775318365,"id":"d9f968ed-f385-4bc5-a996-690bccd5e461","model":"deepseek-reasoner-search","object":"chat.completion.chunk"}
|
||||
|
||||
data: {"choices":[{"delta":{"content":","},"index":0}],"created":1775318365,"id":"d9f968ed-f385-4bc5-a996-690bccd5e461","model":"deepseek-reasoner-search","object":"chat.completion.chunk"}
|
||||
|
||||
data: {"choices":[{"delta":{"content":"24"},"index":0}],"created":1775318365,"id":"d9f968ed-f385-4bc5-a996-690bccd5e461","model":"deepseek-reasoner-search","object":"chat.completion.chunk"}
|
||||
|
||||
: keep-alive
|
||||
|
||||
data: {"choices":[{"delta":{"content":"℃"},"index":0}],"created":1775318365,"id":"d9f968ed-f385-4bc5-a996-690bccd5e461","model":"deepseek-reasoner-search","object":"chat.completion.chunk"}
|
||||
|
||||
data: {"choices":[{"delta":{"content":" ~"},"index":0}],"created":1775318365,"id":"d9f968ed-f385-4bc5-a996-690bccd5e461","model":"deepseek-reasoner-search","object":"chat.completion.chunk"}
|
||||
|
||||
data: {"choices":[{"delta":{"content":"29"},"index":0}],"created":1775318365,"id":"d9f968ed-f385-4bc5-a996-690bccd5e461","model":"deepseek-reasoner-search","object":"chat.completion.chunk"}
|
||||
|
||||
data: {"choices":[{"delta":{"content":"℃"},"index":0}],"created":1775318365,"id":"d9f968ed-f385-4bc5-a996-690bccd5e461","model":"deepseek-reasoner-search","object":"chat.completion.chunk"}
|
||||
|
||||
data: {"choices":[{"delta":{"content":"[reference:13]"},"index":0}],"created":1775318365,"id":"d9f968ed-f385-4bc5-a996-690bccd5e461","model":"deepseek-reasoner-search","object":"chat.completion.chunk"}
|
||||
|
||||
data: {"choices":[{"delta":{"content":"[reference:14]"},"index":0}],"created":1775318365,"id":"d9f968ed-f385-4bc5-a996-690bccd5e461","model":"deepseek-reasoner-search","object":"chat.completion.chunk"}
|
||||
|
||||
data: {"choices":[{"delta":{"content":"[reference:15]"},"index":0}],"created":1775318365,"id":"d9f968ed-f385-4bc5-a996-690bccd5e461","model":"deepseek-reasoner-search","object":"chat.completion.chunk"}
|
||||
|
||||
data: {"choices":[{"delta":{"content":"。\n"},"index":0}],"created":1775318365,"id":"d9f968ed-f385-4bc5-a996-690bccd5e461","model":"deepseek-reasoner-search","object":"chat.completion.chunk"}
|
||||
|
||||
data: {"choices":[{"delta":{"content":"*"},"index":0}],"created":1775318365,"id":"d9f968ed-f385-4bc5-a996-690bccd5e461","model":"deepseek-reasoner-search","object":"chat.completion.chunk"}
|
||||
|
||||
data: {"choices":[{"delta":{"content":" **"},"index":0}],"created":1775318365,"id":"d9f968ed-f385-4bc5-a996-690bccd5e461","model":"deepseek-reasoner-search","object":"chat.completion.chunk"}
|
||||
|
||||
data: {"choices":[{"delta":{"content":"周三"},"index":0}],"created":1775318365,"id":"d9f968ed-f385-4bc5-a996-690bccd5e461","model":"deepseek-reasoner-search","object":"chat.completion.chunk"}
|
||||
|
||||
data: {"choices":[{"delta":{"content":"("},"index":0}],"created":1775318365,"id":"d9f968ed-f385-4bc5-a996-690bccd5e461","model":"deepseek-reasoner-search","object":"chat.completion.chunk"}
|
||||
|
||||
data: {"choices":[{"delta":{"content":"4"},"index":0}],"created":1775318365,"id":"d9f968ed-f385-4bc5-a996-690bccd5e461","model":"deepseek-reasoner-search","object":"chat.completion.chunk"}
|
||||
|
||||
data: {"choices":[{"delta":{"content":"月"},"index":0}],"created":1775318365,"id":"d9f968ed-f385-4bc5-a996-690bccd5e461","model":"deepseek-reasoner-search","object":"chat.completion.chunk"}
|
||||
|
||||
data: {"choices":[{"delta":{"content":"8"},"index":0}],"created":1775318365,"id":"d9f968ed-f385-4bc5-a996-690bccd5e461","model":"deepseek-reasoner-search","object":"chat.completion.chunk"}
|
||||
|
||||
data: {"choices":[{"delta":{"content":"日"},"index":0}],"created":1775318365,"id":"d9f968ed-f385-4bc5-a996-690bccd5e461","model":"deepseek-reasoner-search","object":"chat.completion.chunk"}
|
||||
|
||||
data: {"choices":[{"delta":{"content":")"},"index":0}],"created":1775318365,"id":"d9f968ed-f385-4bc5-a996-690bccd5e461","model":"deepseek-reasoner-search","object":"chat.completion.chunk"}
|
||||
|
||||
data: {"choices":[{"delta":{"content":"**"},"index":0}],"created":1775318365,"id":"d9f968ed-f385-4bc5-a996-690bccd5e461","model":"deepseek-reasoner-search","object":"chat.completion.chunk"}
|
||||
|
||||
data: {"choices":[{"delta":{"content":":"},"index":0}],"created":1775318365,"id":"d9f968ed-f385-4bc5-a996-690bccd5e461","model":"deepseek-reasoner-search","object":"chat.completion.chunk"}
|
||||
|
||||
data: {"choices":[{"delta":{"content":"多云"},"index":0}],"created":1775318365,"id":"d9f968ed-f385-4bc5-a996-690bccd5e461","model":"deepseek-reasoner-search","object":"chat.completion.chunk"}
|
||||
|
||||
data: {"choices":[{"delta":{"content":","},"index":0}],"created":1775318365,"id":"d9f968ed-f385-4bc5-a996-690bccd5e461","model":"deepseek-reasoner-search","object":"chat.completion.chunk"}
|
||||
|
||||
data: {"choices":[{"delta":{"content":"24"},"index":0}],"created":1775318365,"id":"d9f968ed-f385-4bc5-a996-690bccd5e461","model":"deepseek-reasoner-search","object":"chat.completion.chunk"}
|
||||
|
||||
data: {"choices":[{"delta":{"content":"℃"},"index":0}],"created":1775318365,"id":"d9f968ed-f385-4bc5-a996-690bccd5e461","model":"deepseek-reasoner-search","object":"chat.completion.chunk"}
|
||||
|
||||
data: {"choices":[{"delta":{"content":" ~"},"index":0}],"created":1775318365,"id":"d9f968ed-f385-4bc5-a996-690bccd5e461","model":"deepseek-reasoner-search","object":"chat.completion.chunk"}
|
||||
|
||||
data: {"choices":[{"delta":{"content":"30"},"index":0}],"created":1775318365,"id":"d9f968ed-f385-4bc5-a996-690bccd5e461","model":"deepseek-reasoner-search","object":"chat.completion.chunk"}
|
||||
|
||||
data: {"choices":[{"delta":{"content":"℃"},"index":0}],"created":1775318365,"id":"d9f968ed-f385-4bc5-a996-690bccd5e461","model":"deepseek-reasoner-search","object":"chat.completion.chunk"}
|
||||
|
||||
data: {"choices":[{"delta":{"content":"[reference:16]"},"index":0}],"created":1775318365,"id":"d9f968ed-f385-4bc5-a996-690bccd5e461","model":"deepseek-reasoner-search","object":"chat.completion.chunk"}
|
||||
|
||||
data: {"choices":[{"delta":{"content":"[reference:17]"},"index":0}],"created":1775318365,"id":"d9f968ed-f385-4bc5-a996-690bccd5e461","model":"deepseek-reasoner-search","object":"chat.completion.chunk"}
|
||||
|
||||
data: {"choices":[{"delta":{"content":"[reference:18]"},"index":0}],"created":1775318365,"id":"d9f968ed-f385-4bc5-a996-690bccd5e461","model":"deepseek-reasoner-search","object":"chat.completion.chunk"}
|
||||
|
||||
data: {"choices":[{"delta":{"content":"。\n"},"index":0}],"created":1775318365,"id":"d9f968ed-f385-4bc5-a996-690bccd5e461","model":"deepseek-reasoner-search","object":"chat.completion.chunk"}
|
||||
|
||||
data: {"choices":[{"delta":{"content":"*"},"index":0}],"created":1775318365,"id":"d9f968ed-f385-4bc5-a996-690bccd5e461","model":"deepseek-reasoner-search","object":"chat.completion.chunk"}
|
||||
|
||||
data: {"choices":[{"delta":{"content":" **"},"index":0}],"created":1775318365,"id":"d9f968ed-f385-4bc5-a996-690bccd5e461","model":"deepseek-reasoner-search","object":"chat.completion.chunk"}
|
||||
|
||||
data: {"choices":[{"delta":{"content":"周四"},"index":0}],"created":1775318365,"id":"d9f968ed-f385-4bc5-a996-690bccd5e461","model":"deepseek-reasoner-search","object":"chat.completion.chunk"}
|
||||
|
||||
data: {"choices":[{"delta":{"content":"("},"index":0}],"created":1775318365,"id":"d9f968ed-f385-4bc5-a996-690bccd5e461","model":"deepseek-reasoner-search","object":"chat.completion.chunk"}
|
||||
|
||||
data: {"choices":[{"delta":{"content":"4"},"index":0}],"created":1775318365,"id":"d9f968ed-f385-4bc5-a996-690bccd5e461","model":"deepseek-reasoner-search","object":"chat.completion.chunk"}
|
||||
|
||||
data: {"choices":[{"delta":{"content":"月"},"index":0}],"created":1775318365,"id":"d9f968ed-f385-4bc5-a996-690bccd5e461","model":"deepseek-reasoner-search","object":"chat.completion.chunk"}
|
||||
|
||||
data: {"choices":[{"delta":{"content":"9"},"index":0}],"created":1775318365,"id":"d9f968ed-f385-4bc5-a996-690bccd5e461","model":"deepseek-reasoner-search","object":"chat.completion.chunk"}
|
||||
|
||||
data: {"choices":[{"delta":{"content":"日"},"index":0}],"created":1775318365,"id":"d9f968ed-f385-4bc5-a996-690bccd5e461","model":"deepseek-reasoner-search","object":"chat.completion.chunk"}
|
||||
|
||||
data: {"choices":[{"delta":{"content":")"},"index":0}],"created":1775318365,"id":"d9f968ed-f385-4bc5-a996-690bccd5e461","model":"deepseek-reasoner-search","object":"chat.completion.chunk"}
|
||||
|
||||
data: {"choices":[{"delta":{"content":"**"},"index":0}],"created":1775318365,"id":"d9f968ed-f385-4bc5-a996-690bccd5e461","model":"deepseek-reasoner-search","object":"chat.completion.chunk"}
|
||||
|
||||
data: {"choices":[{"delta":{"content":":"},"index":0}],"created":1775318365,"id":"d9f968ed-f385-4bc5-a996-690bccd5e461","model":"deepseek-reasoner-search","object":"chat.completion.chunk"}
|
||||
|
||||
data: {"choices":[{"delta":{"content":"多云"},"index":0}],"created":1775318365,"id":"d9f968ed-f385-4bc5-a996-690bccd5e461","model":"deepseek-reasoner-search","object":"chat.completion.chunk"}
|
||||
|
||||
data: {"choices":[{"delta":{"content":","},"index":0}],"created":1775318365,"id":"d9f968ed-f385-4bc5-a996-690bccd5e461","model":"deepseek-reasoner-search","object":"chat.completion.chunk"}
|
||||
|
||||
data: {"choices":[{"delta":{"content":"23"},"index":0}],"created":1775318365,"id":"d9f968ed-f385-4bc5-a996-690bccd5e461","model":"deepseek-reasoner-search","object":"chat.completion.chunk"}
|
||||
|
||||
data: {"choices":[{"delta":{"content":"℃"},"index":0}],"created":1775318365,"id":"d9f968ed-f385-4bc5-a996-690bccd5e461","model":"deepseek-reasoner-search","object":"chat.completion.chunk"}
|
||||
|
||||
data: {"choices":[{"delta":{"content":" ~"},"index":0}],"created":1775318365,"id":"d9f968ed-f385-4bc5-a996-690bccd5e461","model":"deepseek-reasoner-search","object":"chat.completion.chunk"}
|
||||
|
||||
data: {"choices":[{"delta":{"content":"31"},"index":0}],"created":1775318365,"id":"d9f968ed-f385-4bc5-a996-690bccd5e461","model":"deepseek-reasoner-search","object":"chat.completion.chunk"}
|
||||
|
||||
data: {"choices":[{"delta":{"content":"℃"},"index":0}],"created":1775318365,"id":"d9f968ed-f385-4bc5-a996-690bccd5e461","model":"deepseek-reasoner-search","object":"chat.completion.chunk"}
|
||||
|
||||
data: {"choices":[{"delta":{"content":"[reference:19]"},"index":0}],"created":1775318365,"id":"d9f968ed-f385-4bc5-a996-690bccd5e461","model":"deepseek-reasoner-search","object":"chat.completion.chunk"}
|
||||
|
||||
data: {"choices":[{"delta":{"content":"[reference:20]"},"index":0}],"created":1775318365,"id":"d9f968ed-f385-4bc5-a996-690bccd5e461","model":"deepseek-reasoner-search","object":"chat.completion.chunk"}
|
||||
|
||||
data: {"choices":[{"delta":{"content":"[reference:21]"},"index":0}],"created":1775318365,"id":"d9f968ed-f385-4bc5-a996-690bccd5e461","model":"deepseek-reasoner-search","object":"chat.completion.chunk"}
|
||||
|
||||
data: {"choices":[{"delta":{"content":"。\n"},"index":0}],"created":1775318365,"id":"d9f968ed-f385-4bc5-a996-690bccd5e461","model":"deepseek-reasoner-search","object":"chat.completion.chunk"}
|
||||
|
||||
data: {"choices":[{"delta":{"content":"*"},"index":0}],"created":1775318365,"id":"d9f968ed-f385-4bc5-a996-690bccd5e461","model":"deepseek-reasoner-search","object":"chat.completion.chunk"}
|
||||
|
||||
data: {"choices":[{"delta":{"content":" **"},"index":0}],"created":1775318365,"id":"d9f968ed-f385-4bc5-a996-690bccd5e461","model":"deepseek-reasoner-search","object":"chat.completion.chunk"}
|
||||
|
||||
data: {"choices":[{"delta":{"content":"周五"},"index":0}],"created":1775318365,"id":"d9f968ed-f385-4bc5-a996-690bccd5e461","model":"deepseek-reasoner-search","object":"chat.completion.chunk"}
|
||||
|
||||
data: {"choices":[{"delta":{"content":"("},"index":0}],"created":1775318365,"id":"d9f968ed-f385-4bc5-a996-690bccd5e461","model":"deepseek-reasoner-search","object":"chat.completion.chunk"}
|
||||
|
||||
data: {"choices":[{"delta":{"content":"4"},"index":0}],"created":1775318365,"id":"d9f968ed-f385-4bc5-a996-690bccd5e461","model":"deepseek-reasoner-search","object":"chat.completion.chunk"}
|
||||
|
||||
data: {"choices":[{"delta":{"content":"月"},"index":0}],"created":1775318365,"id":"d9f968ed-f385-4bc5-a996-690bccd5e461","model":"deepseek-reasoner-search","object":"chat.completion.chunk"}
|
||||
|
||||
data: {"choices":[{"delta":{"content":"10"},"index":0}],"created":1775318365,"id":"d9f968ed-f385-4bc5-a996-690bccd5e461","model":"deepseek-reasoner-search","object":"chat.completion.chunk"}
|
||||
|
||||
data: {"choices":[{"delta":{"content":"日"},"index":0}],"created":1775318365,"id":"d9f968ed-f385-4bc5-a996-690bccd5e461","model":"deepseek-reasoner-search","object":"chat.completion.chunk"}
|
||||
|
||||
data: {"choices":[{"delta":{"content":")"},"index":0}],"created":1775318365,"id":"d9f968ed-f385-4bc5-a996-690bccd5e461","model":"deepseek-reasoner-search","object":"chat.completion.chunk"}
|
||||
|
||||
data: {"choices":[{"delta":{"content":"**"},"index":0}],"created":1775318365,"id":"d9f968ed-f385-4bc5-a996-690bccd5e461","model":"deepseek-reasoner-search","object":"chat.completion.chunk"}
|
||||
|
||||
data: {"choices":[{"delta":{"content":":"},"index":0}],"created":1775318365,"id":"d9f968ed-f385-4bc5-a996-690bccd5e461","model":"deepseek-reasoner-search","object":"chat.completion.chunk"}
|
||||
|
||||
data: {"choices":[{"delta":{"content":"多云"},"index":0}],"created":1775318365,"id":"d9f968ed-f385-4bc5-a996-690bccd5e461","model":"deepseek-reasoner-search","object":"chat.completion.chunk"}
|
||||
|
||||
data: {"choices":[{"delta":{"content":","},"index":0}],"created":1775318365,"id":"d9f968ed-f385-4bc5-a996-690bccd5e461","model":"deepseek-reasoner-search","object":"chat.completion.chunk"}
|
||||
|
||||
data: {"choices":[{"delta":{"content":"24"},"index":0}],"created":1775318365,"id":"d9f968ed-f385-4bc5-a996-690bccd5e461","model":"deepseek-reasoner-search","object":"chat.completion.chunk"}
|
||||
|
||||
data: {"choices":[{"delta":{"content":"℃"},"index":0}],"created":1775318365,"id":"d9f968ed-f385-4bc5-a996-690bccd5e461","model":"deepseek-reasoner-search","object":"chat.completion.chunk"}
|
||||
|
||||
data: {"choices":[{"delta":{"content":" ~"},"index":0}],"created":1775318365,"id":"d9f968ed-f385-4bc5-a996-690bccd5e461","model":"deepseek-reasoner-search","object":"chat.completion.chunk"}
|
||||
|
||||
data: {"choices":[{"delta":{"content":"31"},"index":0}],"created":1775318365,"id":"d9f968ed-f385-4bc5-a996-690bccd5e461","model":"deepseek-reasoner-search","object":"chat.completion.chunk"}
|
||||
|
||||
data: {"choices":[{"delta":{"content":"℃"},"index":0}],"created":1775318365,"id":"d9f968ed-f385-4bc5-a996-690bccd5e461","model":"deepseek-reasoner-search","object":"chat.completion.chunk"}
|
||||
|
||||
data: {"choices":[{"delta":{"content":"[reference:22]"},"index":0}],"created":1775318365,"id":"d9f968ed-f385-4bc5-a996-690bccd5e461","model":"deepseek-reasoner-search","object":"chat.completion.chunk"}
|
||||
|
||||
data: {"choices":[{"delta":{"content":"[reference:23]"},"index":0}],"created":1775318365,"id":"d9f968ed-f385-4bc5-a996-690bccd5e461","model":"deepseek-reasoner-search","object":"chat.completion.chunk"}
|
||||
|
||||
data: {"choices":[{"delta":{"content":"[reference:24]"},"index":0}],"created":1775318365,"id":"d9f968ed-f385-4bc5-a996-690bccd5e461","model":"deepseek-reasoner-search","object":"chat.completion.chunk"}
|
||||
|
||||
data: {"choices":[{"delta":{"content":"。\n\n"},"index":0}],"created":1775318365,"id":"d9f968ed-f385-4bc5-a996-690bccd5e461","model":"deepseek-reasoner-search","object":"chat.completion.chunk"}
|
||||
|
||||
data: {"choices":[{"delta":{"content":"⚠"},"index":0}],"created":1775318365,"id":"d9f968ed-f385-4bc5-a996-690bccd5e461","model":"deepseek-reasoner-search","object":"chat.completion.chunk"}
|
||||
|
||||
data: {"choices":[{"delta":{"content":"️"},"index":0}],"created":1775318365,"id":"d9f968ed-f385-4bc5-a996-690bccd5e461","model":"deepseek-reasoner-search","object":"chat.completion.chunk"}
|
||||
|
||||
data: {"choices":[{"delta":{"content":" **"},"index":0}],"created":1775318365,"id":"d9f968ed-f385-4bc5-a996-690bccd5e461","model":"deepseek-reasoner-search","object":"chat.completion.chunk"}
|
||||
|
||||
data: {"choices":[{"delta":{"content":"特别"},"index":0}],"created":1775318365,"id":"d9f968ed-f385-4bc5-a996-690bccd5e461","model":"deepseek-reasoner-search","object":"chat.completion.chunk"}
|
||||
|
||||
data: {"choices":[{"delta":{"content":"提醒"},"index":0}],"created":1775318365,"id":"d9f968ed-f385-4bc5-a996-690bccd5e461","model":"deepseek-reasoner-search","object":"chat.completion.chunk"}
|
||||
|
||||
data: {"choices":[{"delta":{"content":"**"},"index":0}],"created":1775318365,"id":"d9f968ed-f385-4bc5-a996-690bccd5e461","model":"deepseek-reasoner-search","object":"chat.completion.chunk"}
|
||||
|
||||
data: {"choices":[{"delta":{"content":":"},"index":0}],"created":1775318365,"id":"d9f968ed-f385-4bc5-a996-690bccd5e461","model":"deepseek-reasoner-search","object":"chat.completion.chunk"}
|
||||
|
||||
data: {"choices":[{"delta":{"content":"未来"},"index":0}],"created":1775318365,"id":"d9f968ed-f385-4bc5-a996-690bccd5e461","model":"deepseek-reasoner-search","object":"chat.completion.chunk"}
|
||||
|
||||
data: {"choices":[{"delta":{"content":"三天"},"index":0}],"created":1775318365,"id":"d9f968ed-f385-4bc5-a996-690bccd5e461","model":"deepseek-reasoner-search","object":"chat.completion.chunk"}
|
||||
|
||||
data: {"choices":[{"delta":{"content":"天气"},"index":0}],"created":1775318365,"id":"d9f968ed-f385-4bc5-a996-690bccd5e461","model":"deepseek-reasoner-search","object":"chat.completion.chunk"}
|
||||
|
||||
data: {"choices":[{"delta":{"content":"非常"},"index":0}],"created":1775318365,"id":"d9f968ed-f385-4bc5-a996-690bccd5e461","model":"deepseek-reasoner-search","object":"chat.completion.chunk"}
|
||||
|
||||
data: {"choices":[{"delta":{"content":"不稳定"},"index":0}],"created":1775318365,"id":"d9f968ed-f385-4bc5-a996-690bccd5e461","model":"deepseek-reasoner-search","object":"chat.completion.chunk"}
|
||||
|
||||
data: {"choices":[{"delta":{"content":","},"index":0}],"created":1775318365,"id":"d9f968ed-f385-4bc5-a996-690bccd5e461","model":"deepseek-reasoner-search","object":"chat.completion.chunk"}
|
||||
|
||||
data: {"choices":[{"delta":{"content":"出门"},"index":0}],"created":1775318365,"id":"d9f968ed-f385-4bc5-a996-690bccd5e461","model":"deepseek-reasoner-search","object":"chat.completion.chunk"}
|
||||
|
||||
data: {"choices":[{"delta":{"content":"一定要注意"},"index":0}],"created":1775318365,"id":"d9f968ed-f385-4bc5-a996-690bccd5e461","model":"deepseek-reasoner-search","object":"chat.completion.chunk"}
|
||||
|
||||
data: {"choices":[{"delta":{"content":"防范"},"index":0}],"created":1775318365,"id":"d9f968ed-f385-4bc5-a996-690bccd5e461","model":"deepseek-reasoner-search","object":"chat.completion.chunk"}
|
||||
|
||||
data: {"choices":[{"delta":{"content":"强"},"index":0}],"created":1775318365,"id":"d9f968ed-f385-4bc5-a996-690bccd5e461","model":"deepseek-reasoner-search","object":"chat.completion.chunk"}
|
||||
|
||||
data: {"choices":[{"delta":{"content":"降雨"},"index":0}],"created":1775318365,"id":"d9f968ed-f385-4bc5-a996-690bccd5e461","model":"deepseek-reasoner-search","object":"chat.completion.chunk"}
|
||||
|
||||
data: {"choices":[{"delta":{"content":"和"},"index":0}],"created":1775318365,"id":"d9f968ed-f385-4bc5-a996-690bccd5e461","model":"deepseek-reasoner-search","object":"chat.completion.chunk"}
|
||||
|
||||
data: {"choices":[{"delta":{"content":"雷电"},"index":0}],"created":1775318365,"id":"d9f968ed-f385-4bc5-a996-690bccd5e461","model":"deepseek-reasoner-search","object":"chat.completion.chunk"}
|
||||
|
||||
data: {"choices":[{"delta":{"content":"大风"},"index":0}],"created":1775318365,"id":"d9f968ed-f385-4bc5-a996-690bccd5e461","model":"deepseek-reasoner-search","object":"chat.completion.chunk"}
|
||||
|
||||
data: {"choices":[{"delta":{"content":","},"index":0}],"created":1775318365,"id":"d9f968ed-f385-4bc5-a996-690bccd5e461","model":"deepseek-reasoner-search","object":"chat.completion.chunk"}
|
||||
|
||||
data: {"choices":[{"delta":{"content":"注意"},"index":0}],"created":1775318365,"id":"d9f968ed-f385-4bc5-a996-690bccd5e461","model":"deepseek-reasoner-search","object":"chat.completion.chunk"}
|
||||
|
||||
data: {"choices":[{"delta":{"content":"安全"},"index":0}],"created":1775318365,"id":"d9f968ed-f385-4bc5-a996-690bccd5e461","model":"deepseek-reasoner-search","object":"chat.completion.chunk"}
|
||||
|
||||
data: {"choices":[{"delta":{"content":"[reference:25]"},"index":0}],"created":1775318365,"id":"d9f968ed-f385-4bc5-a996-690bccd5e461","model":"deepseek-reasoner-search","object":"chat.completion.chunk"}
|
||||
|
||||
data: {"choices":[{"delta":{"content":"[reference:26]"},"index":0}],"created":1775318365,"id":"d9f968ed-f385-4bc5-a996-690bccd5e461","model":"deepseek-reasoner-search","object":"chat.completion.chunk"}
|
||||
|
||||
data: {"choices":[{"delta":{"content":"[reference:27]"},"index":0}],"created":1775318365,"id":"d9f968ed-f385-4bc5-a996-690bccd5e461","model":"deepseek-reasoner-search","object":"chat.completion.chunk"}
|
||||
|
||||
data: {"choices":[{"delta":{"content":"[reference:28]"},"index":0}],"created":1775318365,"id":"d9f968ed-f385-4bc5-a996-690bccd5e461","model":"deepseek-reasoner-search","object":"chat.completion.chunk"}
|
||||
|
||||
data: {"choices":[{"delta":{"content":"。"},"index":0}],"created":1775318365,"id":"d9f968ed-f385-4bc5-a996-690bccd5e461","model":"deepseek-reasoner-search","object":"chat.completion.chunk"}
|
||||
|
||||
data: {"choices":[{"delta":{},"finish_reason":"stop","index":0}],"created":1775318365,"id":"d9f968ed-f385-4bc5-a996-690bccd5e461","model":"deepseek-reasoner-search","object":"chat.completion.chunk","usage":{"completion_tokens":280,"completion_tokens_details":{"reasoning_tokens":173},"prompt_tokens":6,"total_tokens":286}}
|
||||
|
||||
data: [DONE]
|
||||
|
||||
File diff suppressed because one or more lines are too long
8
tests/raw_stream_samples/manifest.json
Normal file
8
tests/raw_stream_samples/manifest.json
Normal file
@@ -0,0 +1,8 @@
|
||||
{
|
||||
"version": 1,
|
||||
"default_samples": [
|
||||
"guangzhou-weather-reasoner-search-20260404",
|
||||
"content-filter-trigger-20260405-jwt3"
|
||||
],
|
||||
"notes": "Canonical raw stream samples used by the default replay simulator."
|
||||
}
|
||||
@@ -13,6 +13,7 @@ function parseArgs(argv) {
|
||||
samplesRoot: 'tests/raw_stream_samples',
|
||||
reportPath: '',
|
||||
failOnLeak: true,
|
||||
failOnReferenceLeak: true,
|
||||
failOnMissingFinish: true,
|
||||
};
|
||||
for (let i = 2; i < argv.length; i += 1) {
|
||||
@@ -23,6 +24,8 @@ function parseArgs(argv) {
|
||||
out.reportPath = argv[++i];
|
||||
} else if (a === '--no-fail-on-leak') {
|
||||
out.failOnLeak = false;
|
||||
} else if (a === '--no-fail-on-reference-leak') {
|
||||
out.failOnReferenceLeak = false;
|
||||
} else if (a === '--no-fail-on-missing-finish') {
|
||||
out.failOnMissingFinish = false;
|
||||
}
|
||||
@@ -30,15 +33,55 @@ function parseArgs(argv) {
|
||||
return out;
|
||||
}
|
||||
|
||||
function findSampleDirs(root) {
|
||||
if (!fs.existsSync(root)) {
|
||||
return [];
|
||||
function loadManifest(root) {
|
||||
const manifestPath = path.join(root, 'manifest.json');
|
||||
if (!fs.existsSync(manifestPath)) {
|
||||
return null;
|
||||
}
|
||||
return fs.readdirSync(root)
|
||||
try {
|
||||
const manifest = JSON.parse(fs.readFileSync(manifestPath, 'utf8'));
|
||||
const defaultSamples = Array.isArray(manifest.default_samples)
|
||||
? manifest.default_samples.map((v) => String(v).trim()).filter(Boolean)
|
||||
: [];
|
||||
if (defaultSamples.length === 0) {
|
||||
return null;
|
||||
}
|
||||
return { manifestPath, defaultSamples };
|
||||
} catch (err) {
|
||||
throw new Error(`[sim] failed to parse ${manifestPath}: ${err.message}`);
|
||||
}
|
||||
}
|
||||
|
||||
function resolveSampleDirs(root) {
|
||||
if (!fs.existsSync(root)) {
|
||||
return { dirs: [], manifestPath: '' };
|
||||
}
|
||||
|
||||
const manifest = loadManifest(root);
|
||||
if (manifest) {
|
||||
const dirs = [];
|
||||
const missing = [];
|
||||
for (const sampleID of manifest.defaultSamples) {
|
||||
const dir = path.join(root, sampleID);
|
||||
const ssePath = path.join(dir, 'upstream.stream.sse');
|
||||
if (!fs.existsSync(dir) || !fs.statSync(dir).isDirectory() || !fs.existsSync(ssePath)) {
|
||||
missing.push(sampleID);
|
||||
continue;
|
||||
}
|
||||
dirs.push(dir);
|
||||
}
|
||||
if (missing.length > 0) {
|
||||
throw new Error(`[sim] manifest sample(s) missing: ${missing.join(', ')}`);
|
||||
}
|
||||
return { dirs, manifestPath: manifest.manifestPath };
|
||||
}
|
||||
|
||||
const dirs = fs.readdirSync(root)
|
||||
.map((name) => path.join(root, name))
|
||||
.filter((p) => fs.statSync(p).isDirectory())
|
||||
.filter((p) => fs.existsSync(path.join(p, 'upstream.stream.sse')))
|
||||
.sort();
|
||||
return { dirs, manifestPath: '' };
|
||||
}
|
||||
|
||||
function parseSSE(raw) {
|
||||
@@ -101,13 +144,15 @@ function replaySample(raw) {
|
||||
parsedChunks,
|
||||
sawFinish,
|
||||
leakedFinishedText: outputText.includes('FINISHED'),
|
||||
leakedReferenceMarkers: /\[reference:/i.test(outputText),
|
||||
referenceLeakCount: (outputText.match(/\[reference:/gi) || []).length,
|
||||
outputChars: outputText.length,
|
||||
};
|
||||
}
|
||||
|
||||
function main() {
|
||||
const opts = parseArgs(process.argv);
|
||||
const dirs = findSampleDirs(opts.samplesRoot);
|
||||
const { dirs, manifestPath } = resolveSampleDirs(opts.samplesRoot);
|
||||
if (dirs.length === 0) {
|
||||
console.error(`[sim] no samples found: ${opts.samplesRoot}`);
|
||||
process.exit(1);
|
||||
@@ -116,11 +161,16 @@ function main() {
|
||||
const report = {
|
||||
generated_at: new Date().toISOString(),
|
||||
samples_root: opts.samplesRoot,
|
||||
manifest_path: manifestPath,
|
||||
total: dirs.length,
|
||||
failed: 0,
|
||||
samples: [],
|
||||
};
|
||||
|
||||
if (manifestPath) {
|
||||
console.log(`[sim] using manifest ${manifestPath} samples=${dirs.length}`);
|
||||
}
|
||||
|
||||
for (const dir of dirs) {
|
||||
const sampleID = path.basename(dir);
|
||||
const raw = fs.readFileSync(path.join(dir, 'upstream.stream.sse'), 'utf8');
|
||||
@@ -132,6 +182,9 @@ function main() {
|
||||
if (opts.failOnLeak && r.leakedFinishedText) {
|
||||
errors.push('FINISHED leaked into output text');
|
||||
}
|
||||
if (opts.failOnReferenceLeak && r.leakedReferenceMarkers) {
|
||||
errors.push('reference markers leaked into output text');
|
||||
}
|
||||
if (errors.length > 0) {
|
||||
report.failed += 1;
|
||||
}
|
||||
@@ -144,8 +197,9 @@ function main() {
|
||||
|
||||
for (const s of report.samples) {
|
||||
const status = s.ok ? 'OK' : 'FAIL';
|
||||
const leakNote = s.leakedReferenceMarkers ? ` refLeaks=${s.referenceLeakCount}` : '';
|
||||
const note = s.errors.length > 0 ? ` errors=${s.errors.join(';')}` : '';
|
||||
console.log(`[sim] ${status} ${s.sample_id} events=${s.events} parsed=${s.parsedChunks} chars=${s.outputChars}${note}`);
|
||||
console.log(`[sim] ${status} ${s.sample_id} events=${s.events} parsed=${s.parsedChunks} chars=${s.outputChars}${leakNote}${note}`);
|
||||
}
|
||||
|
||||
if (report.failed > 0) {
|
||||
|
||||
34
webui/src/features/settings/CompatibilitySection.jsx
Normal file
34
webui/src/features/settings/CompatibilitySection.jsx
Normal file
@@ -0,0 +1,34 @@
|
||||
import { ShieldAlert } from 'lucide-react'
|
||||
|
||||
export default function CompatibilitySection({ t, form, setForm }) {
|
||||
return (
|
||||
<div className="bg-card border border-border rounded-xl p-5 space-y-4">
|
||||
<div className="flex items-center gap-2">
|
||||
<ShieldAlert className="w-4 h-4 text-muted-foreground" />
|
||||
<h3 className="font-semibold">{t('settings.compatibilityTitle')}</h3>
|
||||
</div>
|
||||
<p className="text-sm text-muted-foreground">{t('settings.compatibilityDesc')}</p>
|
||||
<div className="flex items-center justify-between gap-4">
|
||||
<label className="text-sm font-medium">{t('settings.stripReferenceMarkers')}</label>
|
||||
<button
|
||||
type="button"
|
||||
role="switch"
|
||||
aria-checked={form.compat?.strip_reference_markers ?? true}
|
||||
onClick={() => setForm((prev) => ({
|
||||
...prev,
|
||||
compat: { ...prev.compat, strip_reference_markers: !Boolean(prev.compat?.strip_reference_markers ?? true) },
|
||||
}))}
|
||||
className={`relative inline-flex h-6 w-11 items-center rounded-full transition-colors ${
|
||||
form.compat?.strip_reference_markers ?? true ? 'bg-primary' : 'bg-muted'
|
||||
}`}
|
||||
>
|
||||
<span
|
||||
className={`inline-block h-4 w-4 transform rounded-full bg-white transition-transform ${
|
||||
form.compat?.strip_reference_markers ?? true ? 'translate-x-6' : 'translate-x-1'
|
||||
}`}
|
||||
/>
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
)
|
||||
}
|
||||
@@ -5,6 +5,7 @@ import { useSettingsForm } from './useSettingsForm'
|
||||
import SecuritySection from './SecuritySection'
|
||||
import RuntimeSection from './RuntimeSection'
|
||||
import BehaviorSection from './BehaviorSection'
|
||||
import CompatibilitySection from './CompatibilitySection'
|
||||
import AutoDeleteSection from './AutoDeleteSection'
|
||||
import ModelSection from './ModelSection'
|
||||
import BackupSection from './BackupSection'
|
||||
@@ -94,6 +95,8 @@ export default function SettingsContainer({ onRefresh, onMessage, authFetch, onF
|
||||
|
||||
<BehaviorSection t={t} form={form} setForm={setForm} />
|
||||
|
||||
<CompatibilitySection t={t} form={form} setForm={setForm} />
|
||||
|
||||
<AutoDeleteSection t={t} form={form} setForm={setForm} />
|
||||
|
||||
<ModelSection t={t} form={form} setForm={setForm} />
|
||||
|
||||
@@ -13,6 +13,7 @@ const MAX_AUTO_FETCH_FAILURES = 3
|
||||
const DEFAULT_FORM = {
|
||||
admin: { jwt_expire_hours: 24 },
|
||||
runtime: { account_max_inflight: 2, account_max_queue: 10, global_max_inflight: 10, token_refresh_interval_hours: 6 },
|
||||
compat: { strip_reference_markers: true },
|
||||
responses: { store_ttl_seconds: 900 },
|
||||
embeddings: { provider: '' },
|
||||
auto_delete: { sessions: false },
|
||||
@@ -46,6 +47,9 @@ function fromServerForm(data) {
|
||||
global_max_inflight: Number(data.runtime?.global_max_inflight || 10),
|
||||
token_refresh_interval_hours: Number(data.runtime?.token_refresh_interval_hours || 6),
|
||||
},
|
||||
compat: {
|
||||
strip_reference_markers: data.compat?.strip_reference_markers ?? true,
|
||||
},
|
||||
responses: {
|
||||
store_ttl_seconds: Number(data.responses?.store_ttl_seconds || 900),
|
||||
},
|
||||
@@ -69,6 +73,9 @@ function toServerPayload(form) {
|
||||
global_max_inflight: Number(form.runtime.global_max_inflight),
|
||||
token_refresh_interval_hours: Number(form.runtime.token_refresh_interval_hours),
|
||||
},
|
||||
compat: {
|
||||
strip_reference_markers: Boolean(form.compat?.strip_reference_markers ?? true),
|
||||
},
|
||||
responses: { store_ttl_seconds: Number(form.responses.store_ttl_seconds) },
|
||||
embeddings: { provider: String(form.embeddings.provider || '').trim() },
|
||||
auto_delete: { sessions: Boolean(form.auto_delete?.sessions) },
|
||||
|
||||
@@ -236,6 +236,9 @@
|
||||
"behaviorTitle": "Behavior",
|
||||
"responsesTTL": "Responses store TTL (seconds)",
|
||||
"embeddingsProvider": "Embeddings provider",
|
||||
"compatibilityTitle": "Compatibility",
|
||||
"compatibilityDesc": "Compatibility controls that keep stream output closer to the wire format or safer for the web UI.",
|
||||
"stripReferenceMarkers": "Strip [reference:N] markers",
|
||||
"modelTitle": "Model mapping",
|
||||
"claudeMapping": "Claude mapping (JSON)",
|
||||
"modelAliases": "Model aliases (JSON)",
|
||||
|
||||
@@ -236,6 +236,9 @@
|
||||
"behaviorTitle": "行为设置",
|
||||
"responsesTTL": "Responses 缓存 TTL(秒)",
|
||||
"embeddingsProvider": "Embeddings Provider",
|
||||
"compatibilityTitle": "兼容性设置",
|
||||
"compatibilityDesc": "用于控制输出格式兼容性,避免把模型原始流里的标记直接暴露到前端。",
|
||||
"stripReferenceMarkers": "移除 [reference:N] 标记",
|
||||
"modelTitle": "模型映射",
|
||||
"claudeMapping": "Claude 映射(JSON)",
|
||||
"modelAliases": "模型别名(JSON)",
|
||||
|
||||
Reference in New Issue
Block a user