Skip to content

feat(fireworks): add Fireworks AI provider#475

Merged
SantiagoDePolonia merged 2 commits into
mainfrom
feat/fireworks-provider
Jul 4, 2026
Merged

feat(fireworks): add Fireworks AI provider#475
SantiagoDePolonia merged 2 commits into
mainfrom
feat/fireworks-provider

Conversation

@SantiagoDePolonia

Copy link
Copy Markdown
Contributor

Summary

Adds Fireworks AI (api.fireworks.ai/inference/v1) as a first-class provider. Setting FIREWORKS_API_KEY is the whole setup — the provider is auto-discovered, with optional FIREWORKS_BASE_URL and FIREWORKS_MODELS overrides following the standard convention.

User-visible impact

  • New provider type fireworks: chat completions, streaming, /v1/models discovery, embeddings, passthrough, and /v1/responses (translated via chat completions).
  • Model IDs are Fireworks' account-scoped paths (e.g. accounts/fireworks/models/gpt-oss-120b) and pass through verbatim, including in FIREWORKS_MODELS lists.
  • Model metadata, pricing enrichment, and cost tracking work out of the box: the fireworks type matches the ai-model-list registry key (76 models), and usage costing falls back to the shared OpenAI-compatible token mappings.

Provider-specific behavior

  • Implemented as a minimal openai.ChatCompatible embed (same shape as Z.ai/MiniMax/Xiaomi) — all transport is shared code; there is no Fireworks-specific request/response translation.
  • No native files/batches/audio surface is exposed (Fireworks' inference API doesn't offer OpenAI-compatible endpoints for them); tests pin this interface surface.
  • No dedicated docs page, per the overview's "set an API key and go" convention — documented via the provider matrix row + a note about account-scoped model IDs.

Testing

  • Unit tests: bearer auth + endpoint paths for chat/embeddings/models, interface-surface guards.
  • Full go test ./..., make lint (0 issues), and pre-commit make test-race all green.
  • E2E against a mock upstream: booted the gateway with only env vars — provider registered, /v1/models listed fireworks/accounts/fireworks/models/..., and chat/embeddings/responses round-tripped correctly with slash-containing model IDs.
  • Probed the live GET /inference/v1/models endpoint (401 without key) to confirm upstream discovery support.

🤖 Generated with Claude Code

Add Fireworks AI (api.fireworks.ai/inference/v1) as a provider, discovered
via FIREWORKS_API_KEY with optional FIREWORKS_BASE_URL/FIREWORKS_MODELS.

The provider embeds openai.ChatCompatible: chat completions, streaming,
/models discovery, embeddings, and passthrough come from the shared
OpenAI-compatible transport, with /v1/responses translated through chat.
The "fireworks" type matches the ai-model-list registry key, so model
metadata, pricing enrichment, and cost tracking work without extra
mapping; account-scoped model IDs (accounts/fireworks/models/...) pass
through verbatim.

Document the provider in the overview matrix (no dedicated page needed:
bearer key + optional base URL), .env.template, config.example.yaml, and
the swagger description.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
@mintlify

mintlify Bot commented Jul 4, 2026

Copy link
Copy Markdown

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

Project Status Preview Updated (UTC)
gomodel 🟢 Ready View Preview Jul 4, 2026, 4:29 PM

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

@coderabbitai

coderabbitai Bot commented Jul 4, 2026

Copy link
Copy Markdown
Contributor

Warning

Review limit reached

@SantiagoDePolonia, you've reached your PR review limit, so we couldn't start this review.

Next review available in: 16 minutes

Enable usage-based reviews in Billing to review now. Otherwise, wait until the next included review is available.
You're only billed for reviews past your plan's rate limits ($0.25/file).

How can I continue?

After more reviews become available, a review can be triggered using the @coderabbitai review command as a PR comment. Alternatively, push new commits to this PR.

To avoid repeated limits, reduce automatic review volume by pausing incremental auto-reviews earlier, using label-based review opt-in, excluding WIP or generated PR titles, or requesting reviews manually when the PR is ready. If your team needs uninterrupted high-volume reviews, an organization admin can enable usage-based reviews.

How do review limits work?

CodeRabbit enforces per-developer PR review limits for each organization. Most developers receive the normal plan review availability.

For paid Pro and Pro+ PR reviews, CodeRabbit uses adaptive limits for sustained high-volume activity. When a developer's recent PR review activity reaches the 95th percentile or higher among CodeRabbit users, additional reviews become available more gradually as earlier reviews age out of the rolling window.

Please refer docs for additional details.

Review details
⚙️ Run configuration

Configuration used: Organization UI

Review profile: ASSERTIVE

Plan: Pro

Run ID: b85a46ae-2632-4373-988a-9626b65929c7

📥 Commits

Reviewing files that changed from the base of the PR and between 2417ed1 and 20ada98.

📒 Files selected for processing (10)
  • .env.template
  • CLAUDE.md
  • README.md
  • cmd/gomodel/docs/docs.go
  • cmd/gomodel/main.go
  • config/config.example.yaml
  • docs/openapi.json
  • docs/providers/overview.mdx
  • internal/providers/fireworks/fireworks.go
  • internal/providers/fireworks/fireworks_test.go
✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch feat/fireworks-provider

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands.

@codecov-commenter

Copy link
Copy Markdown

⚠️ Please install the 'codecov app svg image' to ensure uploads and comments are reliably processed by Codecov.

Codecov Report

❌ Patch coverage is 45.45455% with 6 lines in your changes missing coverage. Please review.

Files with missing lines Patch % Lines
internal/providers/fireworks/fireworks.go 50.00% 5 Missing ⚠️
cmd/gomodel/main.go 0.00% 1 Missing ⚠️

📢 Thoughts on this report? Let us know!

@greptile-apps

greptile-apps Bot commented Jul 4, 2026

Copy link
Copy Markdown

Confidence Score: 4/5

Safe to merge — the change is purely additive, isolated in its own package, and follows the established provider pattern exactly.

The implementation correctly embeds ChatCompatible and inherits all transport behavior. The only gap is a missing StreamChatCompletion test; every other observable behavior is covered. Doc updates are accurate: /responses works via the inherited chat-translation path, and passthrough is available when explicitly enabled.

internal/providers/fireworks/fireworks_test.go — could benefit from a streaming smoke test.

Sequence Diagram

%%{init: {'theme': 'neutral'}}%%
sequenceDiagram
    participant Client
    participant Gateway as GoModel Gateway
    participant Fireworks as Fireworks AI<br/>(api.fireworks.ai/inference/v1)

    Client->>Gateway: "POST /v1/chat/completions<br/>model: accounts/fireworks/models/gpt-oss-120b"
    Gateway->>Gateway: Route to fireworks.Provider
    Gateway->>Fireworks: "POST /chat/completions<br/>Authorization: Bearer fw_..."
    Fireworks-->>Gateway: ChatResponse
    Gateway-->>Client: OpenAI-compatible response

    Client->>Gateway: POST /v1/responses
    Gateway->>Gateway: providers.ResponsesViaChat()
    Gateway->>Fireworks: POST /chat/completions (translated)
    Fireworks-->>Gateway: ChatResponse
    Gateway-->>Client: ResponsesResponse (normalized)

    Client->>Gateway: POST /v1/embeddings
    Gateway->>Fireworks: "POST /embeddings<br/>Authorization: Bearer fw_..."
    Fireworks-->>Gateway: EmbeddingResponse
    Gateway-->>Client: OpenAI-compatible embedding response

    Client->>Gateway: GET /v1/models
    Gateway->>Fireworks: GET /models
    Fireworks-->>Gateway: Model list (account-scoped IDs)
    Gateway-->>Client: Normalized models list
Loading
%%{init: {'theme': 'base', 'themeVariables': {"darkMode": true, "background": "#0d1117", "primaryColor": "#21262d", "primaryTextColor": "#e6edf3", "primaryBorderColor": "#8b949e", "lineColor": "#8b949e", "textColor": "#e6edf3", "edgeLabelBackground": "#161b22", "actorBkg": "#21262d", "actorBorder": "#8b949e", "actorTextColor": "#e6edf3", "actorLineColor": "#8b949e", "signalColor": "#8b949e", "signalTextColor": "#e6edf3", "noteBkgColor": "#373320", "noteBorderColor": "#d4a72c", "noteTextColor": "#f0e6c0", "labelBoxBkgColor": "#21262d", "labelBoxBorderColor": "#8b949e", "labelTextColor": "#e6edf3", "loopTextColor": "#e6edf3", "activationBkgColor": "#30363d", "activationBorderColor": "#8b949e"}}}%%
sequenceDiagram
    participant Client
    participant Gateway as GoModel Gateway
    participant Fireworks as Fireworks AI<br/>(api.fireworks.ai/inference/v1)

    Client->>Gateway: "POST /v1/chat/completions<br/>model: accounts/fireworks/models/gpt-oss-120b"
    Gateway->>Gateway: Route to fireworks.Provider
    Gateway->>Fireworks: "POST /chat/completions<br/>Authorization: Bearer fw_..."
    Fireworks-->>Gateway: ChatResponse
    Gateway-->>Client: OpenAI-compatible response

    Client->>Gateway: POST /v1/responses
    Gateway->>Gateway: providers.ResponsesViaChat()
    Gateway->>Fireworks: POST /chat/completions (translated)
    Fireworks-->>Gateway: ChatResponse
    Gateway-->>Client: ResponsesResponse (normalized)

    Client->>Gateway: POST /v1/embeddings
    Gateway->>Fireworks: "POST /embeddings<br/>Authorization: Bearer fw_..."
    Fireworks-->>Gateway: EmbeddingResponse
    Gateway-->>Client: OpenAI-compatible embedding response

    Client->>Gateway: GET /v1/models
    Gateway->>Fireworks: GET /models
    Fireworks-->>Gateway: Model list (account-scoped IDs)
    Gateway-->>Client: Normalized models list
Loading

Reviews (1): Last reviewed commit: "Merge branch 'main' into feat/fireworks-..." | Re-trigger Greptile

Comment on lines +120 to +132
func TestProvider_DoesNotExposeOptionalOpenAICompatibleInterfaces(t *testing.T) {
provider := NewWithHTTPClient("fw-key", "", nil, llmclient.Hooks{})

if _, ok := any(provider).(core.NativeBatchProvider); ok {
t.Fatal("fireworks provider should not implement native batch provider")
}
if _, ok := any(provider).(core.NativeFileProvider); ok {
t.Fatal("fireworks provider should not implement native file provider")
}
if _, ok := any(provider).(core.AudioProvider); ok {
t.Fatal("fireworks provider should not implement audio provider")
}
}

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 Missing streaming coverage

StreamChatCompletion is not exercised anywhere in the test suite. The chat test verifies the non-streaming path (/chat/completions), but the streaming path (/chat/completions with stream: true and an SSE response) is left untested. Other providers like MiniMax override streaming explicitly; fireworks inherits it but the test surface gap means a regression in ChatCompatible.StreamChatCompletion (or providers.EnsureChatCompletionSSE) would not be caught by this package's tests. A short TestStreamChatCompletion_UsesBearerAuthAndStreamEndpoint similar to the other two transport tests would close this gap.

Note: If this suggestion doesn't match your team's coding style, reply to this and let me know. I'll remember it for next time!

@SantiagoDePolonia SantiagoDePolonia merged commit 49f895e into main Jul 4, 2026
20 checks passed
@greptile-apps

greptile-apps Bot commented Jul 4, 2026

Copy link
Copy Markdown

Confidence Score: 4/5

Mostly safe to merge after fixing the passthrough allowlist mismatch.

Core chat, embeddings, model discovery, and registration follow the existing ChatCompatible provider pattern. One contained bug remains: Fireworks passthrough is documented and implemented on the provider, but disabled by the default server allowlist.

internal/providers/fireworks/fireworks.go, config/config.go, internal/server/passthrough_support.go

T-Rex T-Rex Logs

What T-Rex did

  • The verifier confirmed that passthrough remains disabled, with only static code context inspected and no runtime artifacts captured because the step limit was reached.
  • A unit-test run for the fireworks provider produced a log showing the exact command and working directory used, but the run timed out before any test output or exit code could be captured, making validation inconclusive.

View all artifacts

T-Rex Ran code and verified through T-Rex

Sequence Diagram

%%{init: {'theme': 'neutral'}}%%
sequenceDiagram
participant User
participant GoModel as GoModel Gateway
participant Factory as Provider Factory
participant Fireworks as Fireworks Provider
participant Upstream as api.fireworks.ai/inference/v1

GoModel->>Factory: Register fireworks.Registration
User->>GoModel: /v1/chat/completions or /v1/embeddings
GoModel->>Fireworks: Route model selector to provider
Fireworks->>Upstream: OpenAI-compatible request with Bearer FIREWORKS_API_KEY
Upstream-->>Fireworks: OpenAI-compatible response
Fireworks-->>GoModel: Normalized core response
GoModel-->>User: OpenAI-compatible response
Loading
%%{init: {'theme': 'base', 'themeVariables': {"darkMode": true, "background": "#0d1117", "primaryColor": "#21262d", "primaryTextColor": "#e6edf3", "primaryBorderColor": "#8b949e", "lineColor": "#8b949e", "textColor": "#e6edf3", "edgeLabelBackground": "#161b22", "actorBkg": "#21262d", "actorBorder": "#8b949e", "actorTextColor": "#e6edf3", "actorLineColor": "#8b949e", "signalColor": "#8b949e", "signalTextColor": "#e6edf3", "noteBkgColor": "#373320", "noteBorderColor": "#d4a72c", "noteTextColor": "#f0e6c0", "labelBoxBkgColor": "#21262d", "labelBoxBorderColor": "#8b949e", "labelTextColor": "#e6edf3", "loopTextColor": "#e6edf3", "activationBkgColor": "#30363d", "activationBorderColor": "#8b949e"}}}%%
sequenceDiagram
participant User
participant GoModel as GoModel Gateway
participant Factory as Provider Factory
participant Fireworks as Fireworks Provider
participant Upstream as api.fireworks.ai/inference/v1

GoModel->>Factory: Register fireworks.Registration
User->>GoModel: /v1/chat/completions or /v1/embeddings
GoModel->>Fireworks: Route model selector to provider
Fireworks->>Upstream: OpenAI-compatible request with Bearer FIREWORKS_API_KEY
Upstream-->>Fireworks: OpenAI-compatible response
Fireworks-->>GoModel: Normalized core response
GoModel-->>User: OpenAI-compatible response
Loading

Reviews (2): Last reviewed commit: "Merge branch 'main' into feat/fireworks-..." | Re-trigger Greptile

Comment on lines +27 to +29
// "accounts/fireworks/models/llama-v3p1-8b-instruct" and pass through
// unchanged.
type Provider struct {

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 Passthrough stays disabled
Embedding ChatCompatible makes Fireworks implement Passthrough, but the server only exposes /p/{provider}/... for the allowlist in config/config.go and internal/server/passthrough_support.go, which currently omits fireworks. With the documented default setup of only FIREWORKS_API_KEY, /p/fireworks/... returns provider passthrough for "fireworks" is not enabled, so the advertised passthrough surface is not reachable unless users override ENABLED_PASSTHROUGH_PROVIDERS.

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.

2 participants