Add Modal as an LLM provider - #673
Conversation
There was a problem hiding this comment.
Pull request overview
Adds an opt-in Modal LLM provider to Fabro’s model catalog, routing Kimi K3 via the existing OpenAI-compatible adapter while authenticating with Modal proxy-token headers. This fits into the broader provider/catalog + credential-resolution architecture by extending the built-in catalog, auth resolution, test coverage, and end-user documentation.
Changes:
- Introduces a disabled-by-default
modalprovider with Kimi K3 metadata andModal-Key/Modal-Secretheader wiring. - Extends catalog + auth resolution test coverage to ensure Modal is opt-in and that both proxy-token values are required/resolved correctly.
- Adds live and hermetic request-routing coverage plus end-user docs (server vault setup, SDK env overrides, troubleshooting) and the provider icon.
Reviewed changes
Copilot reviewed 12 out of 13 changed files in this pull request and generated no comments.
Show a summary per file
| File | Description |
|---|---|
| lib/foundation/fabro-model/src/catalog/providers/modal.toml | Adds the built-in (disabled) Modal provider definition, headers, and Kimi K3 model metadata/costing. |
| lib/foundation/fabro-model/src/catalog.rs | Adds catalog tests validating Modal is opt-in and that Kimi K3 is exposed when enabled. |
| lib/foundation/fabro-auth/src/resolve.rs | Adds vault credential-resolution tests ensuring both proxy-token secrets are required and resolved into headers (no Authorization). |
| lib/foundation/fabro-auth/src/env_source.rs | Adds env-source tests showing Modal can be resolved via env only when extra headers are explicitly configured to env.*. |
| lib/components/fabro-llm/tests/integration.rs | Adds a live Modal deep tool round-trip E2E test gated on Modal env vars. |
| lib/components/fabro-llm/src/client.rs | Adds a hermetic routing test verifying proxy headers are forwarded and Authorization is omitted. |
| docs/public/reference/sdk.mdx | Documents Modal env variables and how to override header sources for direct EnvCredentialSource usage. |
| docs/public/integrations/modal.mdx | Adds a dedicated Modal integration guide (endpoint setup, vault secrets, costs, troubleshooting). |
| docs/public/docs.json | Adds the Modal integration page to docs navigation. |
| docs/public/core-concepts/models.mdx | Adds Modal to the provider enablement documentation and vault secret requirements. |
| docs/public/administration/server-configuration.mdx | Documents Modal vault variables and header resolution behavior. |
| apps/fabro-web/public/images/providers/modal.svg | Adds the Modal provider icon asset. |
| .env.example | Adds env var placeholders used by the Modal live integration test. |
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
Reduce duplication and over-specification introduced with the Modal provider, without changing shipped behavior. - Extract enabled_provider_catalog and assert_deep_tool_round_trip in the fabro-llm integration tests. The Poolside, Fireworks, OpenRouter, and Modal deep round trips were four near-identical copies. - Add ApiCredential::with_extra_headers for providers that authenticate with request headers instead of an API key. - Replace the unreachable require_env guards in the Modal e2e test with the std::env::var form used by every sibling test, and register MODAL_TOKEN_ID and MODAL_TOKEN_SECRET in EnvVars. - Collapse modal_requires_both_vault_proxy_tokens to a single case. The loop rebuilt the whole built-in catalog per iteration. - Drop tautological and over-specified assertions: the api_key_url doc URL, the forced default/probe lookups on a single-model provider, and the get_on_provider loop that could not fail. - Inline the single-use modal_env_catalog fixture and note why it overrides the shipped secrets templates. - Sort the MODAL_* keys in .env.example, and record in modal.toml why api_id keeps the Hugging Face capitalization. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
|
Ran a simplification pass over the branch (reuse, quality, and efficiency review). Pushed 8e4251b — tests and fixtures only, no change to shipped behavior. Net −65 lines. Removed duplication
Fixed dead and duplicated test code
Small things
Verified: Left alone — flagging for your call, not defects I want to fix silently:
|
There was a problem hiding this comment.
Pull request overview
Copilot reviewed 13 out of 14 changed files in this pull request and generated no new comments.
Comments suppressed due to low confidence (1)
lib/foundation/fabro-static/src/env_vars.rs:60
- MODAL_TOKEN_ID / MODAL_TOKEN_SECRET were added to EnvVars, but they are not registered as optional vault secrets in
fabro-static/src/secret_registry.rs(OPTIONAL_VAULT_SECRETS). That means the server.env→vault migration (2026052501_optional_server_env_secrets_to_vault.rs) will never migrate these secrets if an operator has configured them inserver.env, and the registry helpers will classify them as unknown.
pub const MODAL_TOKEN_ID: &'static str = "MODAL_TOKEN_ID";
pub const MODAL_TOKEN_SECRET: &'static str = "MODAL_TOKEN_SECRET";
Summary
Validation
cargo nextest run -p fabro-model -p fabro-auth -p fabro-llm(888 passed, 24 skipped)cargo build --workspacecargo +nightly-2026-04-14 fmt --check --allcargo +nightly-2026-04-14 clippy --workspace --all-targets -- -D warningscd apps/fabro-web && bun run typecheckcd apps/fabro-web && bun run buildcargo nextest run -p fabro-llm --profile e2e --run-ignored only modal_kimi_k3_deep_tool_round_tripagainst the live Modal endpoint (1 passed)Notes
fabro provider login --provider modalremains out of scope because the current login flow accepts one credential value. Modal setup uses twofabro secret setcommands instead.