Skip to content

🤖 feat: count AI calls from bash commands in workspace costs (opt-in) - #5772

Merged
ThomasK33 merged 3 commits into
mainfrom
bash-ai-proxy/1-local
Oct 6, 2026
Merged

ThomasK33 merged 3 commits into
mainfrom
bash-ai-proxy/1-local

Conversation

@ThomasK33

@ThomasK33 ThomasK33 commented Oct 6, 2026 •

Copy link
Copy Markdown
Member

Summary

Bash tool commands can now send their Anthropic and OpenAI calls through Xum, so the spend shows up in the workspace's Cost tab and in Analytics. Turn on Settings → Providers → Bash commands (off by default). Each Local or Worktree bash command then gets ANTHROPIC_BASE_URL, OPENAI_BASE_URL and a per-workspace xum-proxy-… key that point at a loopback proxy. The proxy forwards with the provider keys from Xum's settings and records the reported usage.

This is PR 1 of 4 in a stack. PR 2 keeps the port and keys stable across restarts, PR 3 adds SSH and Coder hosts, and PR 4 adds a bug-bash scenario for the feature.

Background

Test harnesses (make bug-bash, e2e explorers, SDK scripts) that the agent runs in bash call providers directly. Today that spend never reaches Xum's ledger, so the Cost tab and Analytics undercount.

Implementation

  • src/node/services/bashAiProxy/bashAiProxyService.ts: a loopback HTTP proxy. Allowed paths: Messages, Responses, Chat Completions, token counting and model listing. It replaces the proxy key with the real key and provider headers, adds stream_options.include_usage to streamed Chat Completions, drops Expect, and does not follow redirects. It builds the upstream URL from the configured base URL (normalized like the chat path, query kept) and keeps headers configured in providers.jsonc, such as OpenAI-Project.
  • usageExtract.ts reads usage from JSON and SSE bodies (Anthropic and OpenAI). The proxy records usage through SessionUsageService.recordHeadlessUsage with analytics source bash_proxy, and emits a live session-usage-delta.
  • TurnRequestBuilder adds the variables to xumEnv on a best-effort basis. It adds none when:
    • the switch is off,
    • a project secret names any of that provider's variables,
    • Xum has no API key for that provider,
    • the workspace is not trusted for shared execution (untrusted project or XUM_DISABLE_PROJECT_AUTOMATION=1). The bash tool blanks provider keys there, so a proxy URL would pair with a blank key.
  • The proxy checks each request. If the switch is off, it returns 503. If the key's workspace was removed, it returns 401. If the project lost trust, it returns 403. So commands that already hold a key lose access at once.

Validation

  • Unit tests with a fake upstream: both Anthropic SDK path styles, OpenAI chat and responses, SSE usage, header handling, the refusals above, and the env rules. aiService.test.ts covers the trust gating for trusted, untrusted and kill-switch workspaces. I mutation-checked it and the 403 test.

  • Dogfood with a fake provider and no real spend: a bash curl through the proxy shows up in the Cost tab rows next to the chat turns.

    Cost tab with bash proxy usage

  • Four agent bug-bash rounds (Opus 5.5 and Sonnet 5.5 explorers, effort high, PR 4 scenario) against the top of the stack. The last round found no defect in branch code. Earlier rounds found unclear setting copy and two trust gaps. This stack fixes them.

Risks

  • With the switch on, agent CLIs such as claude -p bill the Xum API key instead of a subscription login. That is why the switch is opt-in. The docs and the setting text say so.
  • Usage comes from what the provider reports. If a client disconnects mid-stream, Xum records only the usage seen before the disconnect.

Related issues filed from the bug bashes (not fixed here): #5766, #5767, #5768, #5769, #5771.


Generated with xum • Model: anthropic:claude-opus-5-5 • Thinking: high • Cost: $32.63

@mintlify

mintlify Bot commented Oct 6, 2026 •

Copy link
Copy Markdown

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

Project Status Preview Updated
Mux 🟢 Ready View Preview Oct 6, 2026, 7:30 PM

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

@chatgpt-codex-connector

chatgpt-codex-connector Bot commented Oct 6, 2026 •

Copy link
Copy Markdown

Codex Review Summary

This comment shows the latest Codex review activity on this pull request.

Review Status Commit Review trigger
📝 Code Review ✅ Completed 2026-10-06T19:35:04.405507Z 30fae67 New commits
🔒 Security Review ✅ Completed 2026-10-06T19:37:54.728303Z 30fae67 New commits
ℹ️ 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" or "@codex security review".

Codex reacts with 👀 while any review is running, comments if it has suggestions, and reacts with 👍 once all reviews finish with no findings.

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown

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: ccb29071fb

ℹ️ 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 thread src/node/services/bashAiProxy/bashAiProxyService.ts Outdated
Comment thread src/node/services/bashAiProxy/bashAiProxyService.ts Outdated
Comment thread src/node/services/bashAiProxy/bashAiProxyService.ts Outdated

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown

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: b02260512b

ℹ️ 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 thread src/node/services/bashAiProxy/bashAiProxyService.ts Outdated
Comment thread src/browser/features/Settings/Sections/ProvidersSection.tsx
Comment thread src/node/services/turnRequestBuilder.ts
Comment thread src/browser/features/Settings/Sections/ProvidersSection.tsx
@ThomasK33

Copy link
Copy Markdown
Member Author

Heads-up from #5791: #5799 makes config-backed palette toggles show "Current: On" or "Current: Off". "Toggle Keep Screen Awake" reads keepScreenAwake from AppConfigStore through a getKeepScreenAwake param, and describeConfigToggle in src/browser/utils/commands/sources.ts builds the subtitle. The "Toggle Count AI Calls from Bash Commands" action in this PR has the same gap. After #5799 merges, give it a store field and the same helper, so it shows its state too.


Generated with xum • Model: anthropic:claude-opus-5-5 • Thinking: high

Merged via the queue into main with commit 056349e Oct 6, 2026
36 of 37 checks passed
@ThomasK33
ThomasK33 deleted the bash-ai-proxy/1-local branch October 6, 2026 21:35

This branch was successfully deployed

1 active deployment
staging - docs — 30fae674 Deployed Oct 6, 2026 by mintlify[bot]
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.

1 participant