7fbb5454ee
Add EffortLevel (auto/low/medium/high) as a provider-agnostic reasoning control, replacing the Capabilities.Thinking bool. Each provider maps the level to its native parameter: Anthropic budget tokens (1K/8K/16K), OpenAI reasoning_effort (low/medium/high), Google thinking budget (1K/8K/16K). Task classification auto-infers effort from TaskType and complexity; filterFeasible excludes arms that lack the required level.
149 lines
4.2 KiB
Go
149 lines
4.2 KiB
Go
package provider
|
|
|
|
import (
|
|
"context"
|
|
"encoding/json"
|
|
|
|
"somegit.dev/Owlibou/gnoma/internal/message"
|
|
"somegit.dev/Owlibou/gnoma/internal/stream"
|
|
)
|
|
|
|
// ToolChoiceMode controls how the model selects tools.
|
|
type ToolChoiceMode string
|
|
|
|
const (
|
|
ToolChoiceAuto ToolChoiceMode = "auto"
|
|
ToolChoiceRequired ToolChoiceMode = "required"
|
|
ToolChoiceNone ToolChoiceMode = "none"
|
|
)
|
|
|
|
// Request encapsulates everything needed for a single LLM API call.
|
|
type Request struct {
|
|
Model string
|
|
SystemPrompt string
|
|
Messages []message.Message
|
|
Tools []ToolDefinition
|
|
MaxTokens int64
|
|
Temperature *float64
|
|
TopP *float64
|
|
TopK *int64
|
|
StopSequences []string
|
|
Thinking *ThinkingConfig
|
|
ResponseFormat *ResponseFormat
|
|
ToolChoice ToolChoiceMode // "" = provider default (auto)
|
|
}
|
|
|
|
// ToolDefinition is the provider-agnostic tool schema.
|
|
type ToolDefinition struct {
|
|
Name string `json:"name"`
|
|
Description string `json:"description"`
|
|
Parameters json.RawMessage `json:"parameters"` // JSON Schema passthrough
|
|
}
|
|
|
|
// EffortLevel is the normalized effort/thinking level across providers.
|
|
type EffortLevel int
|
|
|
|
const (
|
|
EffortAuto EffortLevel = iota // no preference; provider decides
|
|
EffortLow // fast / minimal reasoning
|
|
EffortMedium // balanced
|
|
EffortHigh // maximum reasoning
|
|
)
|
|
|
|
func (e EffortLevel) String() string {
|
|
switch e {
|
|
case EffortLow:
|
|
return "low"
|
|
case EffortMedium:
|
|
return "medium"
|
|
case EffortHigh:
|
|
return "high"
|
|
default:
|
|
return "auto"
|
|
}
|
|
}
|
|
|
|
// ThinkingConfig controls extended thinking / reasoning.
|
|
type ThinkingConfig struct {
|
|
BudgetTokens int64 // explicit token budget (0 = derive from Level)
|
|
Level EffortLevel // normalized effort; used when BudgetTokens == 0
|
|
}
|
|
|
|
// ResponseFormat controls the output format.
|
|
type ResponseFormat struct {
|
|
Type ResponseFormatType
|
|
JSONSchema *JSONSchema // only used when Type == ResponseJSON
|
|
}
|
|
|
|
type ResponseFormatType string
|
|
|
|
const (
|
|
ResponseText ResponseFormatType = "text"
|
|
ResponseJSON ResponseFormatType = "json_object"
|
|
)
|
|
|
|
// JSONSchema defines a schema for structured JSON output.
|
|
type JSONSchema struct {
|
|
Name string `json:"name"`
|
|
Description string `json:"description,omitempty"`
|
|
Schema json.RawMessage `json:"schema"`
|
|
Strict bool `json:"strict,omitempty"`
|
|
}
|
|
|
|
// Capabilities describes what a model can do.
|
|
type Capabilities struct {
|
|
ToolUse bool `json:"tool_use"`
|
|
JSONOutput bool `json:"json_output"`
|
|
ThinkingModes []EffortLevel `json:"thinking_modes,omitempty"` // nil = no thinking support
|
|
Vision bool `json:"vision"`
|
|
ContextWindow int `json:"context_window"`
|
|
MaxOutput int `json:"max_output"`
|
|
}
|
|
|
|
// SupportsThinking returns true if the model supports any extended reasoning mode.
|
|
func (c Capabilities) SupportsThinking() bool {
|
|
return len(c.ThinkingModes) > 0
|
|
}
|
|
|
|
// SupportsEffort returns true if the model supports the given effort level.
|
|
// EffortAuto always returns true (it means "no constraint").
|
|
func (c Capabilities) SupportsEffort(level EffortLevel) bool {
|
|
if level == EffortAuto {
|
|
return true
|
|
}
|
|
for _, m := range c.ThinkingModes {
|
|
if m == level {
|
|
return true
|
|
}
|
|
}
|
|
return false
|
|
}
|
|
|
|
// ModelInfo describes a model available from a provider.
|
|
type ModelInfo struct {
|
|
ID string `json:"id"`
|
|
Name string `json:"name"`
|
|
Provider string `json:"provider"`
|
|
Capabilities Capabilities `json:"capabilities"`
|
|
}
|
|
|
|
// SupportsTools returns true if the model supports tool/function calling.
|
|
func (m ModelInfo) SupportsTools() bool {
|
|
return m.Capabilities.ToolUse
|
|
}
|
|
|
|
// Provider is the core abstraction over all LLM backends.
|
|
type Provider interface {
|
|
// Stream initiates a streaming request and returns an event stream.
|
|
Stream(ctx context.Context, req Request) (stream.Stream, error)
|
|
|
|
// Name returns the provider identifier (e.g., "mistral", "anthropic").
|
|
Name() string
|
|
|
|
// Models returns available models with their capabilities.
|
|
Models(ctx context.Context) ([]ModelInfo, error)
|
|
|
|
// DefaultModel returns the default model ID for this provider.
|
|
DefaultModel() string
|
|
}
|