Skip to content
Back to skills

Add Provider

ASecurity

Add a brand-new LLM provider to llmshim (a company/API not already supported, i.e. not openai, anthropic, gemini, or xai). Use when wiring up a new upstream API — implementing the Provider trait, registering it in the router, and hooking up env-var key discovery. For a new model on an existing provider, use /add-provider is wrong — use /add-model instead.

  • 2 stars
  • 0 votes
  • 0 copies
  • 0 views
  • Added September 23, 2026
ai-agentsrustgobashapi

Works with

  • cli
  • api

Security analysis

A100/100

Scanned September 23, 2026

npx -y skills add sanjay920/llmshim --skill add-provider --agent claude-code

Installs into .claude/skills of the current project.

Are you the author of Add Provider?

Add the live security badge to your README. It updates with every re-scan.

Security grade badge for Add Provider
[![Security: A — Skills Directory](https://www.skillsdirectory.com/api/skills/sanjay920-add-provider/badge)](https://www.skillsdirectory.com/skills/sanjay920-add-provider)

More formats (shields.io, HTML) on the badges page. Keep it an A: scan every change in CI with Pro.

Download with Pro
SKILL.md
---
name: add-provider
description: Add a brand-new LLM provider to llmshim (a company/API not already supported, i.e. not openai, anthropic, gemini, or xai). Use when wiring up a new upstream API — implementing the Provider trait, registering it in the router, and hooking up env-var key discovery. For a new model on an existing provider, use /add-provider is wrong — use /add-model instead.
disable-model-invocation: true
argument-hint: [provider-key] [ProviderName]
allowed-tools: Bash(cargo fmt*), Bash(cargo test*), Bash(cargo clippy*)
---

# Add a provider to llmshim

A provider is a translation adapter: OpenAI-format JSON in → provider-native JSON out → OpenAI-format back. Everything flows as `serde_json::Value`; there is no canonical request struct. Study an existing provider that resembles the new API before writing anything:

- **`src/providers/xai.rs`** — closest to OpenAI's shape; smallest file, best starting template.
- **`src/providers/openai.rs`** — Responses API (function_call items, streaming event translation).
- **`src/providers/anthropic.rs`** — different message/tool/thinking model; `x-anthropic` extension namespace.
- **`src/providers/gemini.rs`** — `functionDeclarations`, `inline_data` vision.

Provider to add: **$ARGUMENTS**

## Steps

1. **Create `src/providers/<key>.rs`** implementing the `Provider` trait from `src/provider.rs`:
   - `fn name(&self) -> &str`
   - `fn transform_request(&self, model, request) -> Result<ProviderRequest>` — build URL, auth headers, and native body. Strip fields other providers add (`reasoning_content` always; `annotations`/`refusal` if the API rejects unknown keys) so multi-model conversations don't leak foreign fields.
   - `fn transform_response(&self, model, response) -> Result<Value>` — map back to OpenAI Chat Completions shape; normalize tool calls to OpenAI format and usage to the shared shape.
   - `fn transform_stream_chunk(&self, model, chunk) -> Result<Option<String>>` — translate one SSE `data:` line; return `Ok(None)` to skip keepalives.
   - A `pub fn new(api_key: String) -> Self` constructor (and `with_base_url` if useful for tests).
   - Put provider-only features under an `x-<key>` extension namespace, mirroring `x-anthropic`.

2. **`src/providers/mod.rs`** — add `pub mod <key>;`.

3. **`src/router.rs`**:
   - `use crate::providers::<key>::<ProviderName>;`
   - In `parse_model`, add prefix inference (e.g. `else if lower.starts_with("<prefix>")`) so bare model names route correctly.
   - In `Router::from_env`, register from the API-key env var:
     ```rust
     if let Ok(key) = std::env::var("<KEY>_API_KEY") {
         router = router.register("<key>", Box::new(<ProviderName>::new(key)));
     }
     ```

4. **`src/config.rs`** — if config-file key storage / `llmshim configure` should support it, add the provider there (check how existing providers are wired).

5. **Models** — register the provider's current advertised models via `/add-model` in `src/models.rs`; the CLI imports that catalog directly.

6. **Tests** — add `tests/unit_<key>.rs` covering request/response/stream transforms in the style of `tests/unit_xai.rs`. Add `tests/integration_<key>.rs` with `#[ignore]` tests that need a real API key. Add a `parse_model` case in `tests/unit_router.rs`.

7. **Docs** — update `CLAUDE.md` (provider list, tool-format section, env-var precedence) and `README.md`.

## Verify

```bash
cargo fmt --check
cargo clippy --features proxy -- -D warnings
cargo test --features proxy --tests
```

Set `<KEY>_API_KEY` and run `cargo test -- --ignored` to exercise the live integration tests, and `cargo run -- chat` to smoke-test streaming and `/model` switching.

## Public-API note

`src/router.rs` and `src/provider.rs` are public API. New provider modules and registrations are additive. Do not change existing trait signatures without a semver bump — see `/release`.

Attribution

Is this your skill, or is something wrong with this listing? Request removal or report an issue. Author removals are honored within 72 hours.

Comments

Loading comments…