Skip to content

feat: add Fireworks AI plugin for usage tracking and billing metrics#359

Open
sayuru-akash wants to merge 1 commit intorobinebers:mainfrom
sayuru-akash:main
Open

feat: add Fireworks AI plugin for usage tracking and billing metrics#359
sayuru-akash wants to merge 1 commit intorobinebers:mainfrom
sayuru-akash:main

Conversation

@sayuru-akash
Copy link
Copy Markdown
Contributor

@sayuru-akash sayuru-akash commented Apr 7, 2026

Description

This pull request introduces a new provider plugin for Fireworks AI, enabling users to track their Fireworks AI usage directly within OpenUsage.

The integration is built on Fireworks AI's official non-browser surfaces and does not depend on browser login or session state. It fetches account details and quotas from the Fireworks API, and uses the official firectl billing export-metrics path to compute rolling token usage for serverless inference.

The provider currently calculates and displays the most truthful metrics available from the validated account shape:

  • Serverless usage
  • Prompt tokens
  • Generated tokens
  • Monthly spend
  • Budget insights
  • Status when the account is not healthy

Authentication is supported via both macOS Keychain and environment variables, ensuring secure and flexible API key management.

A complete plugin manifest, documentation, icon assets, shared host/runtime support, and comprehensive test coverage have also been included.

Fireworks AI Integration

  • Added a new Fireworks AI plugin to fetch:
    • Account details
    • Usage quotas
    • Billing and spend metrics
  • Computed and exposed:
    • Serverless usage
    • Prompt tokens
    • Generated tokens
    • Monthly spend
    • Budget tracking
  • Implemented authentication via:
    • macOS Keychain
    • Environment variables
  • Added plugin manifest defining:
    • Metadata
    • Metrics
    • UI display lines
  • Included SVG icon for provider representation
  • Added detailed documentation for setup and usage
  • Implemented comprehensive test coverage for:
    • API interactions
    • Data parsing
    • Error handling

What Else We Can Do In The Future

  • Add a Fireworks-specific usage chart line backed by the official billing export data
    • This might be the right way to represent the daily serverless token pattern shown in the Fireworks dashboard
    • It should be implemented as a small histogram/sparkbar over a rolling window, not as a fake percentage progress bar

Related Issue

Fixes #352

Type of Change

  • Bug fix
  • New feature
  • New provider plugin
  • Documentation
  • Performance improvement
  • Other (describe below)

Screenshot

Screenshot 2026-04-08 at 01 37 43

Testing

  • I ran bun run build and it succeeded
  • I ran bun run test and all tests pass
  • I tested the change locally with bun tauri dev

Checklist

  • I read CONTRIBUTING.md
  • My PR targets the main branch
  • I did not introduce new dependencies without justification

Summary by cubic

Adds a fireworks-ai provider plugin to track Fireworks usage and billing in OpenUsage. Shows serverless tokens, prompt/generated tokens, month spend, budget, and account health with API-key auth via macOS Keychain or FIREWORKS_API_KEY, using the official firectl billing export-metrics path when available.

  • New Features
    • New fireworks-ai plugin: lists accounts/quotas from https://api.fireworks.ai/v1 and picks a healthy account.
    • Rolling token totals via host fireworks.exportBillingMetrics wrapper around firectl; falls back to token quotas or spend-only.
    • Lines shown: Serverless usage, Prompt tokens, Generated tokens, Month spend, Budget, Status; plan tier inferred from budget cap.
    • Host runtime: added FIREWORKS_API_KEY allowlist, redacts /accounts/{id} in URLs, exposes fireworks.exportBillingMetrics to plugins.
    • Added docs, icon, manifest, tests; README lists Fireworks under providers.

Written for commit 59d328e. Summary will update on new commits.

- Implemented the Fireworks AI plugin to track serverless usage, prompt tokens, generated tokens, monthly spend, and budget.
- Added API calls to list accounts and quotas, and export billing metrics.
- Integrated macOS Keychain and environment variable support for API key management.
- Created a detailed documentation file for the Fireworks AI plugin.
- Added SVG icon for the Fireworks AI plugin.
- Developed comprehensive tests to ensure functionality and error handling.
Copilot AI review requested due to automatic review settings April 7, 2026 20:08
@github-actions github-actions bot added rust Pull requests that update rust code plugin docs labels Apr 7, 2026
@augmentcode
Copy link
Copy Markdown

augmentcode bot commented Apr 7, 2026

🤖 Augment PR Summary

Summary: Adds a new Fireworks AI provider plugin so OpenUsage can show Fireworks account health, spend/budget, and serverless token usage.

Changes:

  • New plugins/fireworks-ai plugin (manifest + JS probe) that fetches accounts/quotas from Fireworks’ control-plane API
  • Optional rolling token totals computed by parsing CSV from the official firectl billing export-metrics path
  • New provider documentation page and README provider list entry
  • Host runtime support: expose host.fireworks.exportBillingMetrics to plugins and allow FIREWORKS_API_KEY via env allowlist
  • Improve request logging redaction by masking /accounts/{id} path segments
  • Add comprehensive unit tests for plugin behavior, env exposure, wrapper injection, and redaction

Technical Notes: Billing exports use UTC date-only windows ("Last 30 days") and the UI falls back to spend/budget when token exports are unavailable.

🤖 Was this summary useful? React with 👍 or 👎

Copy link
Copy Markdown

@augmentcode augmentcode bot left a comment

Choose a reason for hiding this comment

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

Review completed. 4 suggestions posted.

Fix All in Augment

Comment augment review to trigger a new review at any time.

- [**Copilot**](docs/providers/copilot.md) / premium, chat, completions
- [**Cursor**](docs/providers/cursor.md) / credits, total usage, auto usage, API usage, on-demand, CLI auth
- [**Factory / Droid**](docs/providers/factory.md) / standard, premium tokens
- [**Fireworks AI**](docs/providers/fireworks-ai.md) / serverless usage, prompt/generated TPS, monthly spend
Copy link
Copy Markdown

Choose a reason for hiding this comment

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

README.md:34 — The provider blurb says prompt/generated TPS, but the plugin surfaces prompt/generated token totals (and doesn’t expose per-second throughput), so this looks user-facing inaccurate.

Severity: low

Fix This in Augment

🤖 Was this useful? React with 👍 or 👎, or 🚀 if it prevented an incident/outage.

| Metric | Source | Scope | Format | Notes |
| --- | --- | --- | --- | --- |
| Serverless usage | billing export or aggregate token counter | overview | text | Main cumulative usage line, shown as a compact token total like `104.85M tokens` |
| Prompt tokens | billing export or token counter | overview | text | Prompt/input token total for the selected rolling window |
Copy link
Copy Markdown

Choose a reason for hiding this comment

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

docs/providers/fireworks-ai.md:19 — The docs say Prompt/Generated tokens come from “billing export or token counter”, but the implementation only fills these from billing export (quota fallback is only used for an aggregate total). This may mislead users when firectl isn’t available.

Severity: medium

Fix This in Augment

🤖 Was this useful? React with 👍 or 👎, or 🚀 if it prevented an incident/outage.

generatedTokens += num(row.completion_tokens || row.completionTokens) || 0
}
const totalTokens = promptTokens + generatedTokens
return totalTokens > 0
Copy link
Copy Markdown

Choose a reason for hiding this comment

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

plugins/fireworks-ai/plugin.js:300 — loadBillingUsage treats a valid 0-token window as empty, which later renders usage as unavailable/no-data instead of showing 0 tokens. That can misrepresent legitimate zero-usage accounts.

Severity: medium

Fix This in Augment

🤖 Was this useful? React with 👍 or 👎, or 🚀 if it prevented an incident/outage.

"billing",
"export-metrics",
"--api-key",
opts.api_key.trim(),
Copy link
Copy Markdown

Choose a reason for hiding this comment

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

src-tauri/src/plugin_engine/host_api.rs:2062 — Passing the Fireworks API key via firectl --api-key ... exposes the secret in local process listings and potentially crash/diagnostic reports. This is a sensitive-secret handling risk for a desktop app.

Severity: high

Fix This in Augment

🤖 Was this useful? React with 👍 or 👎, or 🚀 if it prevented an incident/outage.

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: 59d328eacb

ℹ️ 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".

"--filename",
file_name.as_str(),
])
.output();
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 Add timeout around firectl billing export subprocess

Avoid calling Command::output() without a timeout here: if firectl billing export-metrics stalls (for example due to DNS/proxy/network hangs), this probe thread can block indefinitely and the batch countdown in src-tauri/src/lib.rs never reaches completion, so users can get a probe batch that never finishes. Please run this command with bounded wait/kill logic (like the existing ccusage runner path) so one stuck export cannot wedge refreshes.

Useful? React with 👍 / 👎.

Copy link
Copy Markdown
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

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

Pull request overview

Adds a new Fireworks AI provider plugin to OpenUsage, including host/runtime support for pulling usage/billing metrics and documentation so users can configure authentication and understand reported metrics.

Changes:

  • Added a Fireworks AI plugin (manifest, implementation, icon) that queries Fireworks account/quota APIs and optionally computes rolling serverless token usage via firectl billing export-metrics.
  • Extended the Tauri plugin host API to expose host.fireworks.exportBillingMetrics() to plugins, whitelist FIREWORKS_API_KEY, and redact Fireworks account IDs from logged URLs.
  • Added provider docs, README provider list entry, and Vitest coverage for the new plugin + host changes.

Reviewed changes

Copilot reviewed 8 out of 9 changed files in this pull request and generated 7 comments.

Show a summary per file
File Description
src-tauri/src/plugin_engine/runtime.rs Calls the new Fireworks wrapper patch during plugin probe setup.
src-tauri/src/plugin_engine/host_api.rs Adds env allowlist entry, URL redaction for /accounts/{id}, Fireworks host API injection, and firectl runner integration + tests.
README.md Adds Fireworks AI to the provider list.
plugins/test-helpers.js Extends the mock host context with host.fireworks.exportBillingMetrics.
plugins/fireworks-ai/plugin.test.js Comprehensive tests for auth resolution, quota parsing, billing export integration, and error paths.
plugins/fireworks-ai/plugin.json New plugin manifest defining Fireworks AI lines/labels/scopes and metadata.
plugins/fireworks-ai/plugin.js Fireworks AI plugin implementation (accounts, quotas, billing CSV parsing, output formatting).
plugins/fireworks-ai/icon.svg Provider icon asset.
docs/providers/fireworks-ai.md Setup + behavior documentation for the Fireworks AI provider.

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment on lines 219 to +249
@@ -239,6 +242,12 @@ fn redact_url(url: &str) -> String {
"login",
];

let url = account_path_pattern
.replace_all(url, |caps: &regex_lite::Captures| {
format!("{}{}", &caps["prefix"], redact_value(&caps["value"]))
})
.to_string();
Copy link

Copilot AI Apr 7, 2026

Choose a reason for hiding this comment

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

redact_url now compiles a new regex_lite::Regex on every call. Since redact_url is invoked for every plugin HTTP request log line, this adds avoidable per-request overhead. Consider moving the regex into a static (e.g., OnceLock<Regex>) and reusing it, similar to other cached values in this module.

Copilot uses AI. Check for mistakes.
Comment on lines +2018 to +2029
fn resolve_firectl_runner() -> Option<String> {
for candidate in firectl_runner_candidates() {
if Command::new(candidate)
.arg("--help")
.status()
.map(|status| status.success())
.unwrap_or(false)
{
return Some(candidate.to_string());
}
}
None
Copy link

Copilot AI Apr 7, 2026

Choose a reason for hiding this comment

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

resolve_firectl_runner() runs firectl --help for each probe call. This can become expensive and also adds repeated process spawning even when the runner location never changes during the app session. Consider caching the resolved runner path (including negative results) in a OnceLock<Option<String>> and reusing it across calls.

Suggested change
fn resolve_firectl_runner() -> Option<String> {
for candidate in firectl_runner_candidates() {
if Command::new(candidate)
.arg("--help")
.status()
.map(|status| status.success())
.unwrap_or(false)
{
return Some(candidate.to_string());
}
}
None
static FIRECTL_RUNNER: OnceLock<Option<String>> = OnceLock::new();
fn resolve_firectl_runner() -> Option<String> {
FIRECTL_RUNNER
.get_or_init(|| {
for candidate in firectl_runner_candidates() {
if Command::new(candidate)
.arg("--help")
.status()
.map(|status| status.success())
.unwrap_or(false)
{
return Some(candidate.to_string());
}
}
None
})
.clone()

Copilot uses AI. Check for mistakes.
Comment on lines +2056 to +2072
let result = Command::new(&program)
.current_dir(&temp_dir)
.args([
"billing",
"export-metrics",
"--api-key",
opts.api_key.trim(),
"--account-id",
opts.account_id.trim(),
"--start-time",
opts.start_time.trim(),
"--end-time",
opts.end_time.trim(),
"--filename",
file_name.as_str(),
])
.output();
Copy link

Copilot AI Apr 7, 2026

Choose a reason for hiding this comment

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

The Fireworks API key is passed to firectl via the --api-key command-line argument. On many OSes this can be observed by other local processes via process listings, which is a credential-leak risk. If firectl supports reading the key from an environment variable or stdin, prefer that; otherwise consider documenting this limitation and/or using a more isolated execution strategy.

Suggested change
let result = Command::new(&program)
.current_dir(&temp_dir)
.args([
"billing",
"export-metrics",
"--api-key",
opts.api_key.trim(),
"--account-id",
opts.account_id.trim(),
"--start-time",
opts.start_time.trim(),
"--end-time",
opts.end_time.trim(),
"--filename",
file_name.as_str(),
])
.output();
let mut command = Command::new(&program);
command.current_dir(&temp_dir);
command.env("FIREWORKS_API_KEY", opts.api_key.trim());
command.args([
"billing",
"export-metrics",
"--account-id",
opts.account_id.trim(),
"--start-time",
opts.start_time.trim(),
"--end-time",
opts.end_time.trim(),
"--filename",
file_name.as_str(),
]);
let result = command.output();

Copilot uses AI. Check for mistakes.
- [**Copilot**](docs/providers/copilot.md) / premium, chat, completions
- [**Cursor**](docs/providers/cursor.md) / credits, total usage, auto usage, API usage, on-demand, CLI auth
- [**Factory / Droid**](docs/providers/factory.md) / standard, premium tokens
- [**Fireworks AI**](docs/providers/fireworks-ai.md) / serverless usage, prompt/generated TPS, monthly spend
Copy link

Copilot AI Apr 7, 2026

Choose a reason for hiding this comment

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

README entry says “prompt/generated TPS”, but the plugin surfaces prompt/generated token totals (and the docs explicitly note it does not ship token-per-second bars). Please update this line to avoid implying throughput metrics.

Suggested change
- [**Fireworks AI**](docs/providers/fireworks-ai.md) / serverless usage, prompt/generated TPS, monthly spend
- [**Fireworks AI**](docs/providers/fireworks-ai.md) / serverless usage, prompt/generated tokens, monthly spend

Copilot uses AI. Check for mistakes.
Comment on lines +16 to +23
| Metric | Source | Scope | Format | Notes |
| --- | --- | --- | --- | --- |
| Serverless usage | billing export or aggregate token counter | overview | text | Main cumulative usage line, shown as a compact token total like `104.85M tokens` |
| Prompt tokens | billing export or token counter | overview | text | Prompt/input token total for the selected rolling window |
| Generated tokens | billing export or token counter | overview | text | Generated/output token total for the selected rolling window |
| Month spend | `monthly-spend-usd.usage` | overview | text | Current calendar-month billable spend |
| Budget | `monthly-spend-usd.value` / `maxValue` | detail | text | Configured monthly budget plus the tier cap |
| Status | account `state` / `suspendState` | detail | badge | Only shown when the account is not in a healthy state |
Copy link

Copilot AI Apr 7, 2026

Choose a reason for hiding this comment

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

The markdown table under “Plugin Metrics” uses || at the start of each row, which renders as an extra empty column in most markdown parsers. Use a standard table format with single | separators so the table renders correctly.

Copilot uses AI. Check for mistakes.
Comment on lines +18 to +23
| Serverless usage | billing export or aggregate token counter | overview | text | Main cumulative usage line, shown as a compact token total like `104.85M tokens` |
| Prompt tokens | billing export or token counter | overview | text | Prompt/input token total for the selected rolling window |
| Generated tokens | billing export or token counter | overview | text | Generated/output token total for the selected rolling window |
| Month spend | `monthly-spend-usd.usage` | overview | text | Current calendar-month billable spend |
| Budget | `monthly-spend-usd.value` / `maxValue` | detail | text | Configured monthly budget plus the tier cap |
| Status | account `state` / `suspendState` | detail | badge | Only shown when the account is not in a healthy state |
Copy link

Copilot AI Apr 7, 2026

Choose a reason for hiding this comment

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

Docs claim Prompt/Generated tokens can come from “billing export or token counter”, but the current implementation only populates these lines from the billing-export CSV (aggregate quota fallback is only used for total tokens). Either update the docs to match the implementation or extend the plugin to populate prompt/generated from quota fields when available.

Copilot uses AI. Check for mistakes.
Comment on lines +36 to +41
function lastFinite(values) {
for (let i = 0; i < values.length; i += 1) {
if (Number.isFinite(values[i])) return values[i]
}
return null
}
Copy link

Copilot AI Apr 7, 2026

Choose a reason for hiding this comment

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

lastFinite() returns the first finite number it encounters, not the last. This is a naming mismatch that can cause confusion when maintaining the quota normalization logic. Consider renaming it to something like firstFinite/pickFirstFinite or adjusting the implementation to match the current name.

Copilot uses AI. Check for mistakes.
Copy link
Copy Markdown
Contributor

@cubic-dev-ai cubic-dev-ai bot left a comment

Choose a reason for hiding this comment

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

6 issues found across 9 files

Prompt for AI agents (unresolved issues)

Check if these issues are valid — if so, understand the root cause of each and fix them. If appropriate, use sub-agents to investigate and fix each issue separately.


<file name="src-tauri/src/plugin_engine/host_api.rs">

<violation number="1" location="src-tauri/src/plugin_engine/host_api.rs:31">
P1: Global allowlisting of `FIREWORKS_API_KEY` exposes a sensitive credential to all plugins because env access is not scoped per plugin.</violation>

<violation number="2" location="src-tauri/src/plugin_engine/host_api.rs:2062">
P1: Fireworks API key is passed in child-process argv (`--api-key <secret>`), creating credential exposure risk via process inspection/log surfaces.</violation>

<violation number="3" location="src-tauri/src/plugin_engine/host_api.rs:2072">
P1: `Command::output()` has no timeout — if `firectl billing export-metrics` hangs (DNS/network issues), the probe thread blocks indefinitely and the batch never finishes. Add bounded wait/kill logic similar to how other external command runners in this codebase handle subprocess timeouts.</violation>
</file>

<file name="README.md">

<violation number="1" location="README.md:34">
P2: README documents Fireworks metrics as TPS, but the plugin and provider docs expose prompt/generated token totals, creating a user-facing contract mismatch.</violation>
</file>

<file name="plugins/fireworks-ai/plugin.js">

<violation number="1" location="plugins/fireworks-ai/plugin.js:36">
P3: `lastFinite()` iterates forward and returns the **first** finite number, not the last. The name is misleading and will confuse future maintainers. Rename to `firstFinite` or change the loop to iterate backwards.</violation>

<violation number="2" location="plugins/fireworks-ai/plugin.js:302">
P2: Zero-token billing exports are incorrectly marked as non-ok, causing valid zero usage to be shown as unavailable/error state.</violation>
</file>

Reply with feedback, questions, or to request a fix. Tag @cubic-dev-ai to re-run a review, or fix all with cubic.

"billing",
"export-metrics",
"--api-key",
opts.api_key.trim(),
Copy link
Copy Markdown
Contributor

@cubic-dev-ai cubic-dev-ai bot Apr 7, 2026

Choose a reason for hiding this comment

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

P1: Fireworks API key is passed in child-process argv (--api-key <secret>), creating credential exposure risk via process inspection/log surfaces.

Prompt for AI agents
Check if this issue is valid — if so, understand the root cause and fix it. At src-tauri/src/plugin_engine/host_api.rs, line 2062:

<comment>Fireworks API key is passed in child-process argv (`--api-key <secret>`), creating credential exposure risk via process inspection/log surfaces.</comment>

<file context>
@@ -1992,6 +2002,164 @@ pub fn patch_ccusage_wrapper(ctx: &rquickjs::Ctx<'_>) -> rquickjs::Result<()> {
+            "billing",
+            "export-metrics",
+            "--api-key",
+            opts.api_key.trim(),
+            "--account-id",
+            opts.account_id.trim(),
</file context>
Fix with Cubic

"MINIMAX_CN_API_KEY",
"SYNTHETIC_API_KEY",
"PI_CODING_AGENT_DIR",
"FIREWORKS_API_KEY",
Copy link
Copy Markdown
Contributor

@cubic-dev-ai cubic-dev-ai bot Apr 7, 2026

Choose a reason for hiding this comment

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

P1: Global allowlisting of FIREWORKS_API_KEY exposes a sensitive credential to all plugins because env access is not scoped per plugin.

Prompt for AI agents
Check if this issue is valid — if so, understand the root cause and fix it. At src-tauri/src/plugin_engine/host_api.rs, line 31:

<comment>Global allowlisting of `FIREWORKS_API_KEY` exposes a sensitive credential to all plugins because env access is not scoped per plugin.</comment>

<file context>
@@ -28,6 +28,7 @@ const WHITELISTED_ENV_VARS: [&str; 16] = [
     "MINIMAX_CN_API_KEY",
     "SYNTHETIC_API_KEY",
     "PI_CODING_AGENT_DIR",
+    "FIREWORKS_API_KEY",
 ];
 
</file context>
Fix with Cubic

"--filename",
file_name.as_str(),
])
.output();
Copy link
Copy Markdown
Contributor

@cubic-dev-ai cubic-dev-ai bot Apr 7, 2026

Choose a reason for hiding this comment

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

P1: Command::output() has no timeout — if firectl billing export-metrics hangs (DNS/network issues), the probe thread blocks indefinitely and the batch never finishes. Add bounded wait/kill logic similar to how other external command runners in this codebase handle subprocess timeouts.

Prompt for AI agents
Check if this issue is valid — if so, understand the root cause and fix it. At src-tauri/src/plugin_engine/host_api.rs, line 2072:

<comment>`Command::output()` has no timeout — if `firectl billing export-metrics` hangs (DNS/network issues), the probe thread blocks indefinitely and the batch never finishes. Add bounded wait/kill logic similar to how other external command runners in this codebase handle subprocess timeouts.</comment>

<file context>
@@ -1992,6 +2002,164 @@ pub fn patch_ccusage_wrapper(ctx: &rquickjs::Ctx<'_>) -> rquickjs::Result<()> {
+            "--filename",
+            file_name.as_str(),
+        ])
+        .output();
+
+    let read_csv = || std::fs::read_to_string(&output_path).ok();
</file context>
Fix with Cubic

- [**Copilot**](docs/providers/copilot.md) / premium, chat, completions
- [**Cursor**](docs/providers/cursor.md) / credits, total usage, auto usage, API usage, on-demand, CLI auth
- [**Factory / Droid**](docs/providers/factory.md) / standard, premium tokens
- [**Fireworks AI**](docs/providers/fireworks-ai.md) / serverless usage, prompt/generated TPS, monthly spend
Copy link
Copy Markdown
Contributor

@cubic-dev-ai cubic-dev-ai bot Apr 7, 2026

Choose a reason for hiding this comment

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

P2: README documents Fireworks metrics as TPS, but the plugin and provider docs expose prompt/generated token totals, creating a user-facing contract mismatch.

Prompt for AI agents
Check if this issue is valid — if so, understand the root cause and fix it. At README.md, line 34:

<comment>README documents Fireworks metrics as TPS, but the plugin and provider docs expose prompt/generated token totals, creating a user-facing contract mismatch.</comment>

<file context>
@@ -31,6 +31,7 @@ OpenUsage lives in your menu bar and shows you how much of your AI coding subscr
 - [**Copilot**](docs/providers/copilot.md) / premium, chat, completions
 - [**Cursor**](docs/providers/cursor.md) / credits, total usage, auto usage, API usage, on-demand, CLI auth
 - [**Factory / Droid**](docs/providers/factory.md) / standard, premium tokens
+- [**Fireworks AI**](docs/providers/fireworks-ai.md) / serverless usage, prompt/generated TPS, monthly spend
 - [**Gemini**](docs/providers/gemini.md) / pro, flash, workspace/free/paid tier
 - [**JetBrains AI Assistant**](docs/providers/jetbrains-ai-assistant.md) / quota, remaining
</file context>
Suggested change
- [**Fireworks AI**](docs/providers/fireworks-ai.md) / serverless usage, prompt/generated TPS, monthly spend
- [**Fireworks AI**](docs/providers/fireworks-ai.md) / serverless usage, prompt/generated tokens, monthly spend
Fix with Cubic

const totalTokens = promptTokens + generatedTokens
return totalTokens > 0
? { status: "ok", label: window.label, promptTokens, generatedTokens, totalTokens }
: { status: "empty" }
Copy link
Copy Markdown
Contributor

@cubic-dev-ai cubic-dev-ai bot Apr 7, 2026

Choose a reason for hiding this comment

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

P2: Zero-token billing exports are incorrectly marked as non-ok, causing valid zero usage to be shown as unavailable/error state.

Prompt for AI agents
Check if this issue is valid — if so, understand the root cause and fix it. At plugins/fireworks-ai/plugin.js, line 302:

<comment>Zero-token billing exports are incorrectly marked as non-ok, causing valid zero usage to be shown as unavailable/error state.</comment>

<file context>
@@ -0,0 +1,369 @@
+    const totalTokens = promptTokens + generatedTokens
+    return totalTokens > 0
+      ? { status: "ok", label: window.label, promptTokens, generatedTokens, totalTokens }
+      : { status: "empty" }
+  }
+
</file context>
Fix with Cubic

return raw ? raw.split("/").filter(Boolean).pop() || null : null
}

function lastFinite(values) {
Copy link
Copy Markdown
Contributor

@cubic-dev-ai cubic-dev-ai bot Apr 7, 2026

Choose a reason for hiding this comment

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

P3: lastFinite() iterates forward and returns the first finite number, not the last. The name is misleading and will confuse future maintainers. Rename to firstFinite or change the loop to iterate backwards.

Prompt for AI agents
Check if this issue is valid — if so, understand the root cause and fix it. At plugins/fireworks-ai/plugin.js, line 36:

<comment>`lastFinite()` iterates forward and returns the **first** finite number, not the last. The name is misleading and will confuse future maintainers. Rename to `firstFinite` or change the loop to iterate backwards.</comment>

<file context>
@@ -0,0 +1,369 @@
+    return raw ? raw.split("/").filter(Boolean).pop() || null : null
+  }
+
+  function lastFinite(values) {
+    for (let i = 0; i < values.length; i += 1) {
+      if (Number.isFinite(values[i])) return values[i]
</file context>
Fix with Cubic

@validatedev
Copy link
Copy Markdown
Collaborator

@codex review

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: 59d328eacb

ℹ️ 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 +222 to +226
maxValue: num(raw.maxValue || raw.max_value),
usage: lastFinite([
num(raw.usage),
num(raw.currentUsage || raw.current_usage),
num(raw.consumedValue || raw.consumed_value),
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 Preserve zero-valued quotas when reading Fireworks fields

normalizeQuota uses raw.maxValue || raw.max_value and similar || fallbacks for usage fields, which treats legitimate 0 values as missing. When Fireworks returns currentUsage: 0 or maxValue: 0 (common at reset boundaries or new accounts), those values are converted to null, so downstream logic can hide spend/usage lines or show fallback states even though the API returned valid data. Use nullish checks (??) or explicit undefined handling so zero remains zero.

Useful? React with 👍 / 👎.

Comment on lines +313 to +316
const totalTokens = (billingUsage && billingUsage.status === "ok" && billingUsage.totalTokens) || tokenAmount(totalTokensQuota) || null
if (totalTokens !== null && totalTokens > 0) {
lines.push(ctx.line.text({ label: "Serverless usage", value: formatCompactCount(totalTokens) + " tokens", subtitle: billingUsage && billingUsage.status === "ok" ? billingUsage.label : "Tokens reported by Fireworks" }))
} else if (billingUsage && billingUsage.status !== "ok") {
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 Show zero token totals instead of fallback messaging

The serverless total uses ... || tokenAmount(totalTokensQuota) || null and then only renders when totalTokens > 0, so a real 0 token total is treated as absent and falls into the “Unavailable” fallback path whenever billing export is not ok. This misreports a valid zero-usage state (e.g., fresh account/window) as missing data. Treat 0 as a valid total and render 0 tokens rather than fallback text.

Useful? React with 👍 / 👎.

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

Labels

docs plugin rust Pull requests that update rust code

Projects

None yet

Development

Successfully merging this pull request may close these issues.

New provider request - Fireworks.ai

3 participants