fix(openai): reasoning alias를 처리한다
This commit is contained in:
parent
9ecf7f9fef
commit
8838e0aced
2 changed files with 57 additions and 11 deletions
|
|
@ -253,6 +253,7 @@ streamResponse:
|
|||
if len(choice.Delta.ToolCalls) > 0 {
|
||||
toolCalls.AddDelta(choice.Delta.ToolCalls)
|
||||
}
|
||||
reasoning := choice.Delta.ReasoningText()
|
||||
if traceStream {
|
||||
a.logger.Info("openai_compat provider stream parsed chunk",
|
||||
zap.String("run_id", spec.RunID),
|
||||
|
|
@ -263,13 +264,13 @@ streamResponse:
|
|||
zap.Bool("content_has_open_think", hasOpenThinkTag(choice.Delta.Content)),
|
||||
zap.Bool("content_has_close_think", hasCloseThinkTag(choice.Delta.Content)),
|
||||
zap.String("content_preview", tracePreview(choice.Delta.Content, 2000)),
|
||||
zap.Int("reasoning_len", len(choice.Delta.ReasoningContent)),
|
||||
zap.Bool("reasoning_has_open_think", hasOpenThinkTag(choice.Delta.ReasoningContent)),
|
||||
zap.Bool("reasoning_has_close_think", hasCloseThinkTag(choice.Delta.ReasoningContent)),
|
||||
zap.String("reasoning_preview", tracePreview(choice.Delta.ReasoningContent, 2000)),
|
||||
zap.Int("reasoning_len", len(reasoning)),
|
||||
zap.Bool("reasoning_has_open_think", hasOpenThinkTag(reasoning)),
|
||||
zap.Bool("reasoning_has_close_think", hasCloseThinkTag(reasoning)),
|
||||
zap.String("reasoning_preview", tracePreview(reasoning, 2000)),
|
||||
)
|
||||
}
|
||||
if reasoning := choice.Delta.ReasoningContent; reasoning != "" {
|
||||
if reasoning != "" {
|
||||
if err := sink.Emit(ctx, runtime.RuntimeEvent{
|
||||
RunID: spec.RunID,
|
||||
Type: runtime.EventTypeReasoningDelta,
|
||||
|
|
@ -754,12 +755,8 @@ type chatMessage struct {
|
|||
|
||||
type chatChunk struct {
|
||||
Choices []struct {
|
||||
Delta struct {
|
||||
Content string `json:"content"`
|
||||
ReasoningContent string `json:"reasoning_content"`
|
||||
ToolCalls []any `json:"tool_calls"`
|
||||
} `json:"delta"`
|
||||
FinishReason *string `json:"finish_reason"`
|
||||
Delta chatChunkDelta `json:"delta"`
|
||||
FinishReason *string `json:"finish_reason"`
|
||||
} `json:"choices"`
|
||||
Usage *struct {
|
||||
PromptTokens int `json:"prompt_tokens"`
|
||||
|
|
@ -767,6 +764,20 @@ type chatChunk struct {
|
|||
} `json:"usage"`
|
||||
}
|
||||
|
||||
type chatChunkDelta struct {
|
||||
Content string `json:"content"`
|
||||
ReasoningContent string `json:"reasoning_content"`
|
||||
Reasoning string `json:"reasoning"`
|
||||
ToolCalls []any `json:"tool_calls"`
|
||||
}
|
||||
|
||||
func (d chatChunkDelta) ReasoningText() string {
|
||||
if d.ReasoningContent != "" {
|
||||
return d.ReasoningContent
|
||||
}
|
||||
return d.Reasoning
|
||||
}
|
||||
|
||||
type openAIToolCallAccumulator struct {
|
||||
calls map[int]map[string]any
|
||||
order []int
|
||||
|
|
|
|||
|
|
@ -209,6 +209,41 @@ func TestOpenAICompatExecuteStreamsDeltasAndFinishReason(t *testing.T) {
|
|||
}
|
||||
}
|
||||
|
||||
func TestOpenAICompatExecuteStreamsReasoningAlias(t *testing.T) {
|
||||
server := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
|
||||
if r.URL.Path != "/v1/chat/completions" {
|
||||
t.Fatalf("unexpected path %s", r.URL.Path)
|
||||
}
|
||||
w.Header().Set("Content-Type", "text/event-stream")
|
||||
_, _ = fmt.Fprintf(w, "data: %s\n\n", `{"choices":[{"delta":{"reasoning":"think alias "}}]}`)
|
||||
_, _ = fmt.Fprintf(w, "data: %s\n\n", `{"choices":[{"delta":{"content":"answer"}}]}`)
|
||||
_, _ = fmt.Fprintf(w, "data: [DONE]\n\n")
|
||||
}))
|
||||
defer server.Close()
|
||||
|
||||
adapter := New(config.OpenAICompatConf{Endpoint: server.URL}, zap.NewNop())
|
||||
sink := &fakeSink{}
|
||||
err := adapter.Execute(context.Background(), runtime.ExecutionSpec{
|
||||
RunID: "run-1",
|
||||
Target: "qwen-model",
|
||||
Input: map[string]any{"prompt": "say hello"},
|
||||
}, sink)
|
||||
if err != nil {
|
||||
t.Fatalf("Execute failed: %v", err)
|
||||
}
|
||||
|
||||
events := sink.all()
|
||||
if len(events) != 4 {
|
||||
t.Fatalf("expected 4 events, got %d: %+v", len(events), events)
|
||||
}
|
||||
if events[1].Type != runtime.EventTypeReasoningDelta || events[1].Delta != "think alias " {
|
||||
t.Fatalf("expected reasoning alias delta, got %+v", events[1])
|
||||
}
|
||||
if events[2].Type != runtime.EventTypeDelta || events[2].Delta != "answer" {
|
||||
t.Fatalf("expected answer delta, got %+v", events[2])
|
||||
}
|
||||
}
|
||||
|
||||
func TestOpenAICompatExecuteSendsHeaders(t *testing.T) {
|
||||
var gotAuth, gotContentType string
|
||||
server := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
|
||||
|
|
|
|||
Loading…
Reference in a new issue