yao/agent/llm/adapters/reasoning.go
Max 3d149057fd Refactor LLM provider architecture to utilize capability adapters
- Removed legacy and audio providers, consolidating functionality into a new architecture that separates API format handling from capability management.
- Updated the OpenAI provider to support capability adapters for tool calls, vision, audio, and reasoning, enhancing modularity and extensibility.
- Introduced a new method for detecting API formats and streamlined the provider selection process.
- Enhanced documentation to reflect the new architecture and clarify provider capabilities and usage.
2025-11-17 06:44:20 +08:00

59 lines
1.9 KiB
Go

package adapters
import (
"github.com/yaoapp/yao/agent/context"
)
// ReasoningFormat represents the reasoning content format
type ReasoningFormat string
const (
ReasoningFormatNone ReasoningFormat = "none" // No reasoning support
ReasoningFormatOpenAI ReasoningFormat = "openai-o1" // OpenAI o1 format
ReasoningFormatDeepSeek ReasoningFormat = "deepseek-r1" // DeepSeek R1 format
ReasoningFormatGPTThink ReasoningFormat = "gpt-think" // Future GPT with thinking
)
// ReasoningAdapter handles reasoning content capability
// Parses reasoning_content from different model formats
type ReasoningAdapter struct {
*BaseAdapter
format ReasoningFormat
}
// NewReasoningAdapter creates a new reasoning adapter
func NewReasoningAdapter(format ReasoningFormat) *ReasoningAdapter {
return &ReasoningAdapter{
BaseAdapter: NewBaseAdapter("ReasoningAdapter"),
format: format,
}
}
// ProcessStreamChunk processes streaming chunks with reasoning content
func (a *ReasoningAdapter) ProcessStreamChunk(chunkType context.StreamChunkType, data []byte) (context.StreamChunkType, []byte, error) {
if a.format == ReasoningFormatNone {
// No reasoning support, pass through
return chunkType, data, nil
}
// TODO: Parse reasoning_content based on format
// - OpenAI o1: reasoning_content field in delta
// - DeepSeek R1: may have different format
// - Extract and emit as ChunkThinking
return chunkType, data, nil
}
// PostprocessResponse extracts reasoning content from the final response
func (a *ReasoningAdapter) PostprocessResponse(response *context.CompletionResponse) (*context.CompletionResponse, error) {
if a.format == ReasoningFormatNone {
// No reasoning support
return response, nil
}
// TODO: Extract reasoning content from response
// - Set response.ReasoningContent if present
// - Separate thinking from final answer
return response, nil
}