feat(provider): Anthropic Messages provider - #536
Open
espetro wants to merge 7 commits into
Open
Conversation
…ial source Extend ProviderId with .anthropic and CredentialSource with .anthropic_api_key, mirroring the openai/openai_api_key pair from the OpenAI-compatible transport. Credentials resolve from the ANTHROPIC_API_KEY environment variable or a profile-owned anthropic_api_key setting, never from repository config. Settings store gains the anthropic_model preference and config_runtime validates it alongside the existing per-provider model fields.
Implement the Anthropic Messages wire as a stream_provider.Provider:
POST {base}/v1/messages with x-api-key and anthropic-version headers,
top-level system hoisting, tool_use/tool_result blocks, and SSE
parsing for message_start, content_block_start/delta/stop (text,
thinking, and input_json deltas), message_delta, message_stop, and
error events. Stop reasons map to the shared failure taxonomy
(end_turn to stop, max_tokens to length, refusal to content_filter).
Assistant messages carrying both text and tool calls serialize the
tool_use blocks inside the still-open content array; closing it
before the blocks produced invalid JSON on every agentic replay.
Base URL defaults to https://api.anthropic.com and is overridable
via FX_ANTHROPIC_BASE_URL, with FX_E2E_ANTHROPIC_URL reserved for
loopback e2e fixtures. Boundaries match the existing transports
(1MB SSE line, 64MB aggregate, 128 tool calls, 4MB tool arguments).
anthropic_models.zig fetches /v1/models with the same caps as the
grok catalog and exports the standard model_catalog_provider pair.
Both files keep credential acceptance keyed by name so they compile
independently of the enum-case commit.
…faces Register the anthropic bundle in builtins/providers.zig and thread it through every surface the openai bundle reaches: the auth provider picker (choiceAt now yields the fifth provider entry), acp server and subagent prompt routing, cli_ask and cli_surface config structs, doctor diagnostics, output contracts, credential resolution call sites (profile anthropic key propagated alongside the openai key), and main.zig dependency injection for both the entry config and the ask/acp runner paths. Anthropic carries no permission reviewer yet, matching the optional reviewer slots; openai_compatible.zig rejects the anthropic_api_key source symmetrically. The model menu lists the anthropic credential label. Agent streams flow through the same ProviderRoutes dispatch as the other wire protocols.
… unset configuredProviderSelection returned ModelNotSelected whenever the saved settings lacked a model for the active provider, even when FX_MODEL carried a process override, making 'FX_PROVIDER=openai FX_MODEL=...' fail before the stream provider was ever consulted. Fall back to the trimmed FX_MODEL value before erroring for the non-gateway providers (anthropic included) and scope each TestEnv install in the override test to its own block so the FX_PROVIDER assertions no longer inherit a stale environment. Verified live against an OpenAI-compatible gateway on both the openai and anthropic wires, including a tool-calling round trip.
Gateway already resolves a compiled default model, so consulting FX_MODEL before the default changed the reported configured_model and broke the startup env-override test.
Requests on the anthropic wire returned ProviderAdmissionMissing at the gateway_step boundary because the codec never called admission.admit() after serialization, unlike the other transports.
|
Security review: https://reviewer.vercel-security.com/vercel-labs/fx/pull/536 |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Adds Anthropic as a first-class provider on top of the current provider_set architecture (supersedes the transport portion of #168, addresses #150 and #112).
What
ProviderId.anthropic,CredentialSource.anthropic_api_key, credential loading fromANTHROPIC_API_KEYenv or profile key, provider catalog entrysrc/gateway/anthropic.zigAnthropic Messages wire transport (POST /v1/messages, SSE, x-api-key + anthropic-version headers, system hoisting, tool_use/tool_result blocks, thinking budget) andanthropic_models.zigmodel catalogprovider_set.Setbundles, CLI surfaces, ACP, subagents, doctor, auth runtime, footer model menuFX_MODELenv fallback when a provider-scoped model is unset (non-gateway providers only), withAnthropicModelNotSelectederror surfaceVerification
zig build test: 8640 pass; the 6 remaining failures are pre-existing on currentmain(verified in a pristine worktree)Notes for reviewers
input_schemaformat directly from typed tool schemas (no intermediate serialized-tools JSON)