Skip to content
skyl

provider/anthropicown module

Claude, native. A separate module, because it wraps the official SDK.

The Anthropic adapter reaches Claude at full fidelity — extended thinking, prompt caching, native tool calling. It is the only adapter that lives in its own Go module.

Installing#

Terminal
go get github.com/BAGOMBEKA-JOB-DEV/skyl/provider/anthropic
import "github.com/BAGOMBEKA-JOB-DEV/skyl/provider/anthropic"
import "github.com/BAGOMBEKA-JOB-DEV/skyl/provider/anthropic"

Requires Go 1.24+, inherited from anthropic-sdk-go.

Reference#

func New(apiKey string, opts ...Option) *Provider

Parameters

  • apiKey — your Anthropic credential. Sent as the x-api-key header.
  • opts — functional options, applied in order.
OptionSignatureDefaultDescription
WithBaseURLfunc WithBaseURL(url string) OptionAnthropic's own hostOverrides the API host. Point it at the sandbox to develop without a credential.
WithHTTPClientfunc WithHTTPClient(hc *http.Client) Optionhttp.DefaultClientSupplies the *http.Client used for every request. This is where you set transport timeouts, proxies, or OpenTelemetry trace propagation.
WithHeaderfunc WithHeader(key, value string) OptionAdds a fixed header to every request — beta feature flags, for instance. Headers are set at construction; ProviderOptions never sets headers on any adapter.

Caveats

  • This is a separate module. go get on the core library does not bring it, and it raises your Go floor to 1.24. That split is deliberate — see ADR-0006.
  • MaxTokens defaults to 4096 when you leave it zero. Anthropic's API requires the field, so skyl supplies a value rather than failing a request every other provider would accept. It is the only substituted default in the library.
  • ProviderOptions uses JSON paths here, not a shallow merge — so "thinking.budget_tokens": 4096 sets one nested field without disturbing its siblings. A top-level key containing a . is therefore interpreted as a path.
  • Thinking.Effort is ignored. The SDK's adaptive thinking config has no budget or effort field.
  • Tool schemas are reconstructed, not forwarded. $defs, $ref and oneOf survive; the top-level type is forced to "object" and non-string entries in required are dropped.

What only this adapter does#

CapabilityElsewhere
Emits EventThinkingDeltaNever emitted by the other three
Reports Usage.CacheWriteTokensAlways zero — no wire field
Delivers ToolResult.IsError as a real booleanLossy on OpenAI, dropped on Gemini
ProviderOptions by JSON pathShallow top-level merge
Reports StopStopSequenceReported as plain stop/STOP

Usage#

Constructing

goCompiles
p := anthropic.New(os.Getenv("ANTHROPIC_API_KEY"))
client := skyl.New(p)
p := anthropic.New(os.Getenv("ANTHROPIC_API_KEY"))
client := skyl.New(p)

Against the sandbox, with no credential

goCompiles
p := anthropic.New("sandbox-key",
	anthropic.WithBaseURL("http://127.0.0.1:8099/anthropic"))
p := anthropic.New("sandbox-key",
	anthropic.WithBaseURL("http://127.0.0.1:8099/anthropic"))

Prompt caching

goCompiles
// JSON-path options work only here, which is what makes this reachable
// without restating the whole system field.
req.ProviderOptions = map[string]any{
	"system.0.cache_control": map[string]any{"type": "ephemeral"},
}
// JSON-path options work only here, which is what makes this reachable
// without restating the whole system field.
req.ProviderOptions = map[string]any{
	"system.0.cache_control": map[string]any{"type": "ephemeral"},
}

Then Usage.CacheReadTokens tells you how much of InputTokens was discounted.

A precise thinking budget

goCompiles
// Effort is ignored on this adapter; the budget is reachable by path.
req.Thinking = &skyl.Thinking{Enabled: true}
req.ProviderOptions = map[string]any{"thinking.budget_tokens": 4096}
// Effort is ignored on this adapter; the budget is reachable by path.
req.Thinking = &skyl.Thinking{Enabled: true}
req.ProviderOptions = map[string]any{"thinking.budget_tokens": 4096}

A beta feature header

goCompiles
// Headers are fixed at construction. ProviderOptions never sets headers.
p := anthropic.New(key, anthropic.WithHeader("anthropic-beta", "some-feature-2026-01-01"))
// Headers are fixed at construction. ProviderOptions never sets headers.
p := anthropic.New(key, anthropic.WithHeader("anthropic-beta", "some-feature-2026-01-01"))

Troubleshooting#

The build fails mentioning the go directive

You are on Go 1.22 or 1.23. This module requires 1.24, inherited from the SDK. Upgrade Go — the core library still works on 1.22 if you drop this adapter.

My tool's required list is not enforced

Non-string entries in required are dropped by this adapter. A schema loaded from JSON decodes them as []any. Convert to []string.

Setting a ProviderOptions key with a dot did something unexpected

Keys are JSON paths on this adapter. "a.b" sets b inside a, not a top-level key literally named a.b. This is the only adapter where a key's spelling changes its meaning.

Effort had no effect

It is dropped here. Use thinking.budget_tokens through ProviderOptions.

Edit this page on GitHub