diff --git a/internal/llm/client_completions.go b/internal/llm/client_completions.go index 74f6c00..0a12b3e 100644 --- a/internal/llm/client_completions.go +++ b/internal/llm/client_completions.go @@ -444,6 +444,13 @@ func (c *Client) completionsStream(ctx context.Context, messages []Message, mode ReasoningDelta: delta.ReasoningContent, } } + if delta.Reasoning != "" { + acc.reasoning.WriteString(delta.Reasoning) + events <- StreamEvent{ + Type: streamEventReasoningDelta, + ReasoningDelta: delta.Reasoning, + } + } // Accumulate tool call deltas by index. for _, tc := range delta.ToolCalls { idx := 0 diff --git a/internal/llm/llm.go b/internal/llm/llm.go index 156f97f..9893005 100644 --- a/internal/llm/llm.go +++ b/internal/llm/llm.go @@ -138,6 +138,7 @@ type Delta struct { Content string `json:"content,omitempty"` Refusal string `json:"refusal,omitempty"` ReasoningContent string `json:"reasoning_content,omitempty"` + Reasoning string `json:"reasoning,omitempty"` ToolCalls []ToolCall `json:"tool_calls,omitempty"` } @@ -199,6 +200,7 @@ type Message struct { ContentParts []ContentPart `json:"content,omitempty"` Refusal string `json:"refusal,omitempty"` ReasoningContent string `json:"reasoning_content,omitempty"` + Reasoning string `json:"reasoning,omitempty"` Name string `json:"name,omitempty"` ToolCalls []ToolCall `json:"tool_calls,omitempty"` ToolCallID string `json:"tool_call_id,omitempty"` @@ -244,16 +246,21 @@ func (m *Message) UnmarshalJSON(data []byte) error { m.ContentParts = append(m.ContentParts, part) } } + // Normalize: if ReasoningContent is empty but Reasoning is set, use Reasoning + if m.ReasoningContent == "" && m.Reasoning != "" { + m.ReasoningContent = m.Reasoning + } return nil } // Model represents an available model from the API. type Model struct { - ID string `json:"id"` - Created int64 `json:"created"` - Object string `json:"object"` - OwnedBy string `json:"owned_by"` - Meta *ModelMeta `json:"meta,omitempty"` + ID string `json:"id"` + Created int64 `json:"created"` + Object string `json:"object"` + OwnedBy string `json:"owned_by"` + Meta *ModelMeta `json:"meta,omitempty"` + ContextLength int `json:"context_length,omitempty"` } // ModelMeta contains optional model metadata from the provider. diff --git a/internal/service/service.go b/internal/service/service.go index 25055be..d199066 100644 --- a/internal/service/service.go +++ b/internal/service/service.go @@ -833,8 +833,12 @@ func (svc *Service) models(w http.ResponseWriter, r *http.Request) { for _, m := range models { baseID, _, _ := strings.Cut(m.ID, ":") available[baseID] = struct{}{} - if m.Meta != nil && m.Meta.NCtx > 0 { - contextSizes[baseID] = m.Meta.NCtx + cs := m.ContextLength + if cs == 0 && m.Meta != nil { + cs = m.Meta.NCtx + } + if cs > 0 { + contextSizes[baseID] = cs } }