Add provider usage integrations batch#2215
Conversation
Cookie-based web provider for LongCat (Meituan) that surfaces console
token quota (总额度) and fuel-pack balance (加油包) by reading the
longcat.chat platform session, mirroring the Kimi/MiniMax cookie pattern.
Field mapping is locked against captured live responses:
- GET /api/v1/user-current -> data.name
- GET /api/lc-platform/v1/tokenUsage -> data.usage.{total,used,available}Token
- GET /api/lc-platform/v1/pending-fuel-packages -> data.totalQuota + data.list[]
The public API key path exposes no usage endpoint, so usage is read from
the web console session (all longcat.chat cookies are forwarded since the
Meituan passport cookie name is undocumented). The user-current body is
never logged (it carries a session token + phone).
Wires .longcat into the provider/icon enums, descriptor registry, settings
snapshot/builder, implementation registry, logging, widget, cost-usage and
debug switches; adds brand icon, docs provider-id list, CHANGELOG entry and
unit tests covering the live response shapes.
Addresses Codex review on steipete#1697: - user-current now propagates envelope auth failures (HTTP 200 + code 401/403 -> .invalidSession) instead of swallowing them with try?, so expired cookies prompt re-auth rather than reporting an empty snapshot. - Remove the never-assigned todayTokens / freeQuota fields and the unreachable tertiary 'Today' window; LongCat's tokenUsage is a quota snapshot with no per-day figure. - Add envelope unit tests (invalid-session + success unwrap).
Addresses Codex re-review on steipete#1697: resolveCookieOverride read context.env["LONGCAT_MANUAL_COOKIE"] directly, bypassing LongCatSettingsReader.cookieHeader(), so the lower-case longcat_manual_cookie alias and quote-trimming never reached the env fetch path for CLI/daemon users. Route the env value through the reader first. (The P3 changelog 'today's token usage' wording was already dropped during the rebase onto main.)
Addresses Codex re-review on steipete#1697 (2 P2): - Off now fully disables web auth: resolveCookieOverride returns nil when cookieSource is .off, so a lingering LONGCAT_MANUAL_COOKIE env value can no longer keep the web strategy available. - Browser cookie/keychain import is gated to the Auto source only; Manual no longer silently falls back to a browser session when the pasted header is missing/invalid (it surfaces as unavailable instead). - Add regression tests for the Off/Auto env-override gating.
Address maintainer-bar nits before review: - Thread an injectable ProviderHTTPTransport through fetchUsage/get (mirrors the Doubao fetcher) and add scripted-transport tests: 401/403 and blocked 3xx login redirects surface as .invalidSession, and a full live-shaped response maps account + token quota + fuel pack. - Pin fuel-pack parsing to the fields verified against live longcat.chat responses (availableToken / expireTime) instead of probing a speculative list of candidate key names.
AnyRouter is an OpenAI-compatible model-routing gateway billed from a shared credit balance. Read the balance from its credits API and surface spend in the menu bar like the other API-key providers. Only /api/v1/credits is reachable with an sk-ar-v1- inference key: /api/v1/key requires dashboard session auth, so key-scoped rate limits are not available. Unlike OpenRouter, the credits payload is flat rather than wrapped in `data`. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01J7Ussus9GfDUGjdabsqyL5 Co-Authored-By: duyetbot <101855044+duyetbot@users.noreply.github.com>
Use the shared UsageFormatter.currencyString instead of a local NumberFormatter, drop the settings error case that could never be thrown, and stop decoding the three credits fields nothing displays (they were required keys, so dropping them also removes a way a payload change could break decoding). Use the black brand logo and a matching graphite accent; the orange mark is retired. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01J7Ussus9GfDUGjdabsqyL5 Co-Authored-By: duyetbot <101855044+duyetbot@users.noreply.github.com>
A key whose allowed_endpoints list omits /api/v1/credits is valid but scoped out; AnyRouter answers 403 insufficient_scope. Reporting that as "key rejected" pointed users at the wrong fix, so give it its own error and document it. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01J7Ussus9GfDUGjdabsqyL5 Co-Authored-By: duyetbot <101855044+duyetbot@users.noreply.github.com>
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: 1d66c62eb1
ℹ️ About Codex in GitHub
Codex has been enabled to automatically 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 👍.
When you sign up for Codex through ChatGPT, Codex can also answer questions or update the PR, like "@codex address that feedback".
| subtitle: "Store one labeled AnyRouter inference key per environment you want to monitor.", | ||
| placeholder: "Paste AnyRouter API key (sk-ar-v1-…)…", |
There was a problem hiding this comment.
Prompt for AnyRouter management keys
When users add AnyRouter through Settings, this prompt tells them to paste an sk-ar-v1 inference key, but the fetcher sends that same token to GET /api/v1/credits; the current AnyRouter Credits API docs require an ak_ management key with read:credits and reject LLM keys, so a valid key obtained from the advertised UI path will only produce invalid-credentials errors and the provider will not fetch usage. Please ask for/store the management key (or use an endpoint that accepts inference keys).
Useful? React with 👍 / 👎.
Summary
Verification