Skip to content

feat: add provider config for multi-backend subprocess routing#50

Merged
mcheemaa merged 2 commits intomainfrom
phase2/provider-config
Apr 12, 2026
Merged

feat: add provider config for multi-backend subprocess routing#50
mcheemaa merged 2 commits intomainfrom
phase2/provider-config

Conversation

@mcheemaa
Copy link
Copy Markdown
Member

Summary

  • Adds a provider block to phantom.yaml that lets operators point the Agent SDK subprocess at any Anthropic Messages API compatible endpoint without touching code
  • Seven providers supported out of the box with sensible defaults: anthropic (default, unchanged behavior), zai, openrouter, vllm, ollama, litellm, custom
  • buildProviderEnv() translates the YAML block into the environment variables the bundled cli.js already honors (ANTHROPIC_BASE_URL, ANTHROPIC_AUTH_TOKEN, ANTHROPIC_API_KEY, ANTHROPIC_DEFAULT_*_MODEL, CLAUDE_CODE_DISABLE_EXPERIMENTAL_BETAS, API_TIMEOUT_MS) and merges them into both the main agent query and the evolution judge query
  • PHANTOM_PROVIDER_TYPE and PHANTOM_PROVIDER_BASE_URL env overrides added next to the existing PHANTOM_MODEL / PHANTOM_DOMAIN knobs for operators who prefer env to YAML
  • resolveJudgeMode() in auto mode now honors four credential paths: non-anthropic provider selected, custom base_url set, ANTHROPIC_API_KEY present, or ~/.claude/.credentials.json exists. Previously it only checked ANTHROPIC_API_KEY, which meant non-Anthropic deployments silently fell back to heuristic judges.

Both the main agent AND every evolution judge flow through the chosen provider because #49 unified them onto a single Agent SDK subprocess path. Existing deployments with no provider: block continue to work unchanged thanks to a schema-level default ({ type: "anthropic" } is behaviorally identical to the block being absent).

Minimum config to route Phantom at Z.AI's GLM-5.1 Anthropic-compatible endpoint:

model: claude-sonnet-4-6
provider:
  type: zai
  api_key_env: ZAI_API_KEY
  model_mappings:
    opus: glm-5.1
    sonnet: glm-5.1
    haiku: glm-4.5-air

Set ZAI_API_KEY in .env, restart, done. The main agent and judges both route through Z.AI. Follow-up commit will update the README and docs.

Test plan

  • bun test: 875 pass, 0 fail (up from 838 with 37 new tests)
  • bun run typecheck clean
  • bun run lint clean
  • buildProviderEnv() covered for all 7 presets, user overrides, model mappings, timeout propagation, purity invariant, no-undefined-values invariant (22 tests)
  • resolveJudgeMode() covered for all four new auto-mode credential paths plus the legacy ANTHROPIC_API_KEY regression guard (5 new tests, 5 existing tests still pass)
  • loader.ts env-var overrides covered for valid, unknown, and malformed values (6 tests)
  • No raw @anthropic-ai/sdk import remains in src/ (only @anthropic-ai/claude-agent-sdk)

Copy link
Copy Markdown

@chatgpt-codex-connector chatgpt-codex-connector bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: 5c4b90d799

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

Comment on lines +114 to +118
if (apiKeyEnv) {
const resolved = process.env[apiKeyEnv];
if (resolved && resolved.length > 0) {
env.ANTHROPIC_AUTH_TOKEN = resolved;
env.ANTHROPIC_API_KEY = resolved;
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P1 Badge Override inherited Anthropic keys when provider auth is unset

buildProviderEnv() leaves both ANTHROPIC_API_KEY and ANTHROPIC_AUTH_TOKEN absent when api_key_env is missing/unset, but both runtime query paths merge this map on top of process.env (src/agent/runtime.ts:189 and src/agent/judge-query.ts:131). In a non-Anthropic provider config (e.g., ollama, custom, or a mis-set zai key), any preexisting Anthropic credentials from the parent shell are still forwarded to the new ANTHROPIC_BASE_URL, which can leak credentials to third-party endpoints and produce hard-to-debug auth failures instead of a clean missing-key failure.

Useful? React with 👍 / 👎.

Comment on lines +74 to +77
if (this.runtime) {
const provider = this.runtime.getPhantomConfig().provider;
if (provider.type !== "anthropic") return true;
if (provider.base_url) return true;
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P2 Badge Recompute auto judge mode after binding runtime provider

resolveJudgeMode() now enables auto judges based on this.runtime provider settings (provider.type/provider.base_url), but this logic only runs in the constructor. If the engine is created without a runtime and one is attached later (the class explicitly supports this via setRuntime), llmJudgesEnabled stays at its initial value, so non-Anthropic/provider-based auto activation never turns on and the engine remains stuck on heuristic judges.

Useful? React with 👍 / 👎.

@mcheemaa mcheemaa merged commit 258e072 into main Apr 12, 2026
1 check passed
@mcheemaa mcheemaa deleted the phase2/provider-config branch April 12, 2026 05:18
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant