Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -152,6 +152,7 @@ For Claude, browser cookies (the `sessionKey`) are preferred, because they match
| Munito | Admin API Key | Today's and this month's organization spend against spend limits |
| Soniox | Organization API key | Prepaid USD balance, this month's spend against the monthly budget, billing method |
| Claude Platform | Browser cookies / manual Cookie header | Console API credit and purchased credit, other grants, month-to-date spend |
| Trae CN | Browser cookies / manual Cookie header | Credit allowance used against total, remaining credits, plan name |

</details>

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -328,6 +328,7 @@ fn cookie_source_provider(provider_id: &str) -> Option<codexbar::core::ProviderI
"xapi" => ProviderId::Xapi,
"parallel" => ProviderId::Parallel,
"claudeplatform" => ProviderId::ClaudePlatform,
"traecn" => ProviderId::TraeCn,
_ => return None,
})
}
Expand Down Expand Up @@ -1028,6 +1029,13 @@ pub fn cookie_source_options_for(provider_id: &str, lang: Language) -> Vec<Cooki
cookie_option(lang, "manual", None),
cookie_option(lang, "off", None),
],
// Upstream's Trae CN picker: automatic browser import, a pasted
// api.trae.cn Cookie header, or off.
"traecn" => vec![
cookie_option(lang, "auto", None),
cookie_option(lang, "manual", None),
cookie_option(lang, "off", None),
],
_ => Vec::new(),
}
}
Expand Down
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
3 changes: 3 additions & 0 deletions apps/desktop-tauri/src/components/providers/providerIcons.ts
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@ import augment from "./icons/ProviderIcon-augment.svg?raw";
import bedrock from "./icons/ProviderIcon-bedrock.svg?raw";
import claude from "./icons/ProviderIcon-claude.svg?raw";
import claudeplatform from "./icons/ProviderIcon-claudeplatform.svg?raw";
import traecn from "./icons/ProviderIcon-traecn.svg?raw";
import codebuff from "./icons/ProviderIcon-codebuff.svg?raw";
import coderabbit from "./icons/ProviderIcon-coderabbit.svg?raw";
import codex from "./icons/ProviderIcon-codex.svg?raw";
Expand Down Expand Up @@ -131,6 +132,7 @@ const RAW: Record<string, string> = {
bedrock: tint(bedrock),
claude: tint(claude),
claudeplatform: tint(claudeplatform),
traecn: tint(traecn),
codebuff: tint(codebuff),
coderabbit: tint(coderabbit),
codex: tint(codex),
Expand Down Expand Up @@ -229,6 +231,7 @@ export const PROVIDER_ICON_REGISTRY: Record<string, ProviderIcon> = {
augment: { id: "augment", brandColor: "#1aa049", fallbackLetter: "A", svgPath: RAW.augment },
claude: { id: "claude", brandColor: "#cc7c5e", fallbackLetter: "◈", svgPath: RAW.claude },
claudeplatform: { id: "claudeplatform", brandColor: "#cc7c5e", fallbackLetter: "◈", svgPath: RAW.claudeplatform },
traecn: { id: "traecn", brandColor: "#4D7CFE", fallbackLetter: "T", svgPath: RAW.traecn },
pi: { id: "pi", brandColor: "#4d9abf", fallbackLetter: "P" },
codebuff: { id: "codebuff", brandColor: "#00ff95", fallbackLetter: "B", svgPath: RAW.codebuff },
coderabbit: { id: "coderabbit", brandColor: "#ff5c35", fallbackLetter: "C", svgPath: RAW.coderabbit },
Expand Down
1 change: 1 addition & 0 deletions apps/desktop-tauri/src/test/providerCatalog.ts
Original file line number Diff line number Diff line change
Expand Up @@ -109,4 +109,5 @@ export const TEST_PROVIDER_CATALOG: Array<[string, string]> = [
["munito", "Munito"],
["soniox", "Soniox"],
["claudeplatform", "Claude Platform"],
["traecn", "Trae CN"],
];
37 changes: 37 additions & 0 deletions docs/PROVIDERS.md
Original file line number Diff line number Diff line change
Expand Up @@ -810,6 +810,43 @@ GET https://platform.claude.com/api/organizations/<uuid>/current_spend
showing $0. 429 reports rate limiting and 5xx reports the Console as
unavailable. Response bodies are never echoed in errors.

### Trae CN

Trae CN is disabled by default and shows the credit allowance of a Trae CN
(trae.cn) account. Sign in to trae.cn in your browser, and CodexBar uses the
`api.trae.cn` session cookies.

- **Automatic:** CodexBar tries each detected browser holding an api.trae.cn
session. If Trae rejects a session (401, 403 or a redirect), it moves to the
next browser. No session means sign in to trae.cn.
- **Manual:** Paste the Cookie header from an api.trae.cn request. Manual mode
does not fall back to browser sessions.
- **Off:** Cookies are disabled.

The provider makes two read-only POST requests per session and never makes a
billable call:

```text
POST https://api.trae.cn/cloudide/api/v3/common/GetUserToken
POST https://api.trae.cn/trae/api/v2/pay/user_current_entitlement_list
```

- The token from `GetUserToken` lives only for one refresh and is sent only to
api.trae.cn as a `Cloud-IDE-JWT` authorization header.
- The gauge is consumed over total credits. A zero allowance shows the details
without a gauge. Used, Total and Remaining appear in the **Credits** section.
- The plan name comes from the active plan entitlement and is shown as the
login method. Pack expiry dates do not set a reset: the provider infers no
renewal or reset date.
- Malformed responses (no `is_credits_billing`, non-numeric or negative amounts,
or no token) fail parsing instead of showing zero usage. 429 reports rate
limiting, 408 and 5xx report the service as unavailable, and response bodies
are never echoed in errors.
- For proof runs and fake servers, `TRAE_CN_BASE_URL` replaces the API origin
(default `https://api.trae.cn`). It accepts `https://`, or `http://` only for a
loopback host (`127.0.0.1`, `localhost`, `[::1]`), with no credentials, query,
or fragment. Any other value is ignored with a warning.

### Aerostack

Aerostack is disabled by default. In Settings → Providers → Aerostack, enter an
Expand Down
3 changes: 2 additions & 1 deletion rust/src/core/provider/id.rs
Original file line number Diff line number Diff line change
Expand Up @@ -135,6 +135,7 @@ pub enum ProviderId {
Munito,
ClaudePlatform,
Soniox,
TraeCn,
}

impl ProviderId {
Expand Down Expand Up @@ -309,7 +310,7 @@ mod tests {
#[test]
fn test_provider_id_all() {
let all = ProviderId::all();
assert_eq!(all.len(), 112);
assert_eq!(all.len(), 113);
assert!(all.contains(&ProviderId::Claude));
assert!(all.contains(&ProviderId::Codex));
assert!(all.contains(&ProviderId::Pi));
Expand Down
10 changes: 8 additions & 2 deletions rust/src/core/provider/spec.rs
Original file line number Diff line number Diff line change
Expand Up @@ -148,11 +148,11 @@ const fn spec(
}
}

const COUNT: usize = 112;
const COUNT: usize = 113;

pub(crate) static ALL: [ProviderId; COUNT] = {
// Indexing SPECS by discriminant relies on rows following declaration order.
assert!(P::Soniox as usize + 1 == COUNT);
assert!(P::TraeCn as usize + 1 == COUNT);
let mut ids = [P::Codex; COUNT];
let mut i = 0;
while i < COUNT {
Expand Down Expand Up @@ -782,4 +782,10 @@ pub(crate) static SPECS: [ProviderSpec; COUNT] = [
.labels("Monthly budget", "Usage")
.dashboard("https://console.soniox.com")
.status("https://status.soniox.com"),
spec(P::TraeCn, "traecn", "Trae CN", "#4D7CFE")
.labels("Credits", "Window")
.cookie("api.trae.cn")
.dashboard("https://www.trae.cn/dashboard#usage")
.aliases(&["trae-cn"])
.parse_aliases(&["trae cn"]),
];
11 changes: 8 additions & 3 deletions rust/src/core/provider_factory.rs
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,7 @@ use crate::providers::MuseAIProvider;
use crate::providers::ParallelProvider;
use crate::providers::SyntheticProvider;
use crate::providers::TavilyProvider;
use crate::providers::TraeCnProvider;
use crate::providers::WorkBuddyProvider;
use crate::providers::{
AbacusProvider, AiAndProvider, AixyProvider, AlibabaProvider, AlibabaTokenPlanProvider,
Expand Down Expand Up @@ -166,6 +167,7 @@ pub fn instantiate(id: ProviderId) -> Box<dyn Provider> {
ProviderId::Munito => Box::new(MunitoProvider::new()),
ProviderId::Soniox => Box::new(SonioxProvider::new()),
ProviderId::ClaudePlatform => Box::new(ClaudePlatformProvider::new()),
ProviderId::TraeCn => Box::new(TraeCnProvider::new()),
}
}

Expand Down Expand Up @@ -287,7 +289,8 @@ pub fn pace_capability(id: ProviderId) -> ProviderPaceCapability {
| ProviderId::FutureAgi
| ProviderId::Munito
| ProviderId::Soniox
| ProviderId::ClaudePlatform => ProviderPaceCapability::UNSUPPORTED,
| ProviderId::ClaudePlatform
| ProviderId::TraeCn => ProviderPaceCapability::UNSUPPORTED,
}
}

Expand Down Expand Up @@ -409,7 +412,8 @@ pub fn limit_reset_policy(id: ProviderId) -> ProviderLimitResetPolicy {
| ProviderId::FutureAgi
| ProviderId::Munito
| ProviderId::Soniox
| ProviderId::ClaudePlatform => ProviderLimitResetPolicy::DEFAULT,
| ProviderId::ClaudePlatform
| ProviderId::TraeCn => ProviderLimitResetPolicy::DEFAULT,
}
}

Expand Down Expand Up @@ -531,7 +535,8 @@ pub(crate) fn cost_cli_extension_for(id: ProviderId) -> Option<&'static dyn Cost
| ProviderId::FutureAgi
| ProviderId::Munito
| ProviderId::Soniox
| ProviderId::ClaudePlatform => None,
| ProviderId::ClaudePlatform
| ProviderId::TraeCn => None,
}
}

Expand Down
4 changes: 4 additions & 0 deletions rust/src/core/provider_registry_snapshot.txt
Original file line number Diff line number Diff line change
Expand Up @@ -446,3 +446,7 @@ Soniox cli=soniox display="Soniox" cookie=None color=#253772 deprecated=false bl
map=["soniox"]
metadata=ProviderMetadata { id: Soniox, display_name: "Soniox", session_label: "Monthly budget", weekly_label: "Usage", supports_opus: false, supports_credits: false, default_enabled: false, is_primary: false, dashboard_url: Some("https://console.soniox.com"), status_page_url: Some("https://status.soniox.com"), tertiary_label_key: None }
sources=[Auto, OAuth] oauth=false web=false cli=false
TraeCn cli=traecn display="Trae CN" cookie=Some("api.trae.cn") color=#4D7CFE deprecated=false blocking=None
map=["trae-cn", "traecn"]
metadata=ProviderMetadata { id: TraeCn, display_name: "Trae CN", session_label: "Credits", weekly_label: "Window", supports_opus: false, supports_credits: false, default_enabled: false, is_primary: false, dashboard_url: Some("https://www.trae.cn/dashboard#usage"), status_page_url: None, tertiary_label_key: None }
sources=[Auto, Web] oauth=false web=true cli=false
3 changes: 2 additions & 1 deletion rust/src/core/token_accounts.rs
Original file line number Diff line number Diff line change
Expand Up @@ -387,7 +387,8 @@ impl TokenAccountSupport {
| ProviderId::FutureAgi
| ProviderId::Munito
| ProviderId::Soniox
| ProviderId::ClaudePlatform => None,
| ProviderId::ClaudePlatform
| ProviderId::TraeCn => None,
}
}

Expand Down
2 changes: 2 additions & 0 deletions rust/src/providers/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -110,6 +110,7 @@ pub mod tavily;
#[cfg(test)]
pub(crate) mod test_support;
pub mod tinyapi;
pub mod traecn;
pub mod typesafe;
pub mod v0;
pub mod venice;
Expand Down Expand Up @@ -224,6 +225,7 @@ pub use synthetic::SyntheticProvider;
pub use t3chat::T3ChatProvider;
pub use tavily::TavilyProvider;
pub use tinyapi::TinyApiProvider;
pub use traecn::TraeCnProvider;
pub use typesafe::TypeSafeProvider;
pub use v0::V0Provider;
pub use venice::VeniceProvider;
Expand Down
Loading