项目文件夹

文件
wehub-resource-sync a06f331eb8
CI / benchmark (push) Has been skipped
install-script / posix-syntax (push) Successful in 6m1s
CI / build-onnx (push) Failing after 6m43s
init-smoke / dry-run (push) Failing after 15m57s
security / govulncheck (push) Has been cancelled
security / trivy-fs (push) Has been cancelled
CI / test (1.26, ubuntu-latest) (push) Has been cancelled
Scorecard supply-chain security / Scorecard analysis (push) Has been cancelled
CI / test (1.26, macos-latest) (push) Has been cancelled
CI / build-windows (push) Has been cancelled
CI / lint (push) Has been cancelled
install-script / powershell-syntax (push) Has been cancelled
install-script / install (macos-14) (push) Has been cancelled
install-script / install (ubuntu-latest) (push) Has been cancelled
chore: import upstream snapshot with attribution
2026-07-13 12:33:42 +08:00

100 行
3.0 KiB
Go

package anthropic
import (
"strings"
"github.com/zzet/gortex/internal/llm"
)
// Option configures optional Anthropic behaviours on a Provider at
// construction. Provider.New takes a variadic list of these, so the
// base signature (a RemoteConfig) stays unchanged.
type Option func(*Provider)
// WithPromptCaching enables Anthropic prompt caching with the given TTL
// ("5m" or "1h"; "5m" is assumed when empty). When enabled, the system
// prompt and the structured-output tool are marked as cache
// breakpoints. A false `enabled` is a no-op.
func WithPromptCaching(enabled bool, ttl string) Option {
return func(p *Provider) {
if !enabled {
return
}
p.caching = true
p.cacheTTL = strings.TrimSpace(ttl)
}
}
// WithThinking configures extended thinking. mode is off / auto / manual
// / adaptive; budget is the manual-mode token budget; display is the
// adaptive-mode visibility ("summarized" / "omitted"). An empty or "off"
// mode is a no-op.
func WithThinking(mode string, budget int, display string) Option {
return func(p *Provider) {
p.thinkingMode = strings.ToLower(strings.TrimSpace(mode))
p.thinkingBudget = budget
p.thinkingDisplay = strings.TrimSpace(display)
}
}
// defaultThinkingBudget is the manual-mode budget used when thinking is
// enabled without an explicit one. The Anthropic minimum is 1024.
const defaultThinkingBudget = 4096
// cacheControl builds the ephemeral cache_control marker honouring the
// configured TTL.
func (p *Provider) cacheControl() map[string]any {
cc := map[string]any{"type": "ephemeral"}
if p.cacheTTL != "" {
cc["ttl"] = p.cacheTTL
}
return cc
}
// thinkingConfig returns the `thinking` request object and the minimum
// max_tokens the request must carry for it, or (nil, 0) when thinking
// is off or not applicable.
//
// Extended thinking is incompatible with a forced tool_choice, so it is
// only ever applied to freeform requests — the structured-output passes
// (which pin tool_choice to the respond tool) run without it. The
// resolved mode is gated by model capability: "auto" picks adaptive on a
// capable model, else manual; an explicit "adaptive" on an incapable
// model degrades to manual rather than erroring.
func (p *Provider) thinkingConfig(shape llm.JSONShape) (map[string]any, int) {
if shape != llm.ShapeFreeform {
return nil, 0
}
mode := p.thinkingMode
switch mode {
case "", "off":
return nil, 0
case "auto":
if supportsAdaptiveThinking(p.model) {
mode = "adaptive"
} else {
mode = "manual"
}
}
if mode == "adaptive" && supportsAdaptiveThinking(p.model) {
cfg := map[string]any{"type": "adaptive"}
if p.thinkingDisplay != "" {
cfg["display"] = p.thinkingDisplay
}
// Adaptive thinking still needs headroom in max_tokens.
return cfg, 4096
}
// manual (also the fallback for adaptive on an incapable model)
budget := p.thinkingBudget
if budget <= 0 {
budget = defaultThinkingBudget
}
if budget < 1024 {
budget = 1024
}
// max_tokens must exceed the thinking budget.
return map[string]any{"type": "enabled", "budget_tokens": budget}, budget + 1024
}