Skip to content

feat(agents): support custom providers and secret store values#12901

Open
mikeldking wants to merge 10 commits intomainfrom
mikeldking/12899-providers-and-secrets
Open

feat(agents): support custom providers and secret store values#12901
mikeldking wants to merge 10 commits intomainfrom
mikeldking/12899-providers-and-secrets

Conversation

@mikeldking
Copy link
Copy Markdown
Collaborator

@mikeldking mikeldking commented Apr 28, 2026

This PR updates the agents chat flow to support both secret-backed built-in providers and custom generative model providers.

It also refactors the chat implementation so the router is a thin HTTP layer and the chat-domain code lives under src/phoenix/server/agents/.

Closes #12899.

@mintlify
Copy link
Copy Markdown
Contributor

mintlify Bot commented Apr 28, 2026

Preview deployment for your docs. Learn more about Mintlify Previews.

Project Status Preview Updated (UTC)
arize-phoenix 🟢 Ready View Preview Apr 28, 2026, 7:34 PM

💡 Tip: Enable Workflows to automatically generate PRs for you.

@mikeldking mikeldking changed the title [codex] [agents] support custom providers and secret store values feat(agents): support custom providers and secret store values Apr 28, 2026
Comment thread src/phoenix/server/api/routers/chat.py Fixed
Comment thread src/phoenix/server/api/routers/data_stream_protocol.py Fixed
Comment thread src/phoenix/server/api/routers/data_stream_protocol.py Fixed
Comment thread src/phoenix/server/agents/model_factory.py Fixed
Comment thread src/phoenix/server/agents/model_factory.py Fixed
Comment thread src/phoenix/server/agents/mcp.py Fixed
Comment thread src/phoenix/server/api/routers/data_stream_protocol.py Fixed
CodeQL flagged the TYPE_CHECKING import as unused because the
annotation was a string literal. With `from __future__ import
annotations` in effect the quotes are unnecessary, and removing them
exposes the bare-name reference to static analysis.
ContextualTool is defined before the back-import in registry.py, so a
plain top-level import works without a circular-import workaround.
Restore the Args/Returns block dropped in the chat refactor and reword
the summary so it describes the behavior rather than the MCP transport.
Captures lessons from PR #12901 review: don't strip Args/Returns blocks
during refactors, and describe behavior abstractly on public APIs rather
than coupling docstrings to a specific transport (e.g. MCP).
- Map the agents/ package in the __init__ docstring so future consumers
  can find the right module without reading every file.
- Add module + class docstrings to chat_params, model_factory, and
  tools/registry, including a short "adding a new contextual tool"
  recipe.
- Document the secret-vs-env precedence in _resolve_secret_or_env and
  the params/raises contract for build_chat_model.
- Comment the assert_never + raise pattern so future readers don't
  strip one of the two as dead code (it satisfies CodeQL flow analysis).
- Re-export ContextualTool from agents.tools so callers don't need to
  reach into registry.
- Remove the unused instance-level MintlifyDocsClient.is_backend_tool
  duplicate; only the module-level helper is referenced.
Lift transport concerns out of the agents domain layer:

- New phoenix.server.agents.exceptions module with an AgentError
  hierarchy (Provider{NotFound,Config,Credentials,Unsupported,
  Dependency}Error). Each subclass carries a status_code so the REST
  router maps them to HTTP responses without inspecting types.
- model_factory no longer imports fastapi or strawberry.relay. It
  raises domain exceptions; the chat router translates them to
  HTTPException at the boundary.
- GlobalID decoding moves from build_chat_model into a Pydantic
  validator on CustomProviderChatSearchParams.provider_id, so the
  factory works on the decoded integer node ID.
- _resolve_secret_or_env now wraps the BadRequest raised by
  playground_clients._resolve_secrets into a ProviderConfigError. This
  closes a latent bug where a corrupt stored secret produced a 500
  instead of the intended 400.

Tests updated to assert on the new domain exceptions, plus a new
regression test that exercises the previously-broken decrypt-failure-
during-secret-lookup path through build_chat_model.
- Use the existing from_global_id_with_expected_type helper from
  phoenix.server.api.types.node in the chat_params validator instead of
  hand-rolling the relay-id-to-int decode. Adds free type validation
  that the GlobalID corresponds to a GenerativeModelCustomProvider.
- Add an explicit int annotation to ProviderNotFoundError.status_code
  so subclass overrides match the base class's signature.
- Extract the duplicated "Azure identity package not installed."
  string into a module-level constant.
- Batch the AWS Bedrock secret lookup into a single DB query via a new
  _resolve_secrets_or_env helper (previously three sequential queries
  for AWS_ACCESS_KEY_ID, AWS_SECRET_ACCESS_KEY, AWS_SESSION_TOKEN).
  _resolve_secret_or_env now delegates to the batched helper.
@mikeldking mikeldking marked this pull request as ready for review April 28, 2026 23:52
@mikeldking mikeldking requested a review from a team as a code owner April 28, 2026 23:52
@dosubot dosubot Bot added the size:XXL This PR changes 1000+ lines, ignoring generated files. label Apr 28, 2026
@claude
Copy link
Copy Markdown
Contributor

claude Bot commented Apr 28, 2026

Code review

No issues found. Checked for bugs and CLAUDE.md compliance.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

size:XXL This PR changes 1000+ lines, ignoring generated files.

Projects

Status: 📘 Todo

Development

Successfully merging this pull request may close these issues.

[agents] support custom providers and secret store values

1 participant