Commit Graph
3245 Commits
Author SHA1 Message Date
Jason dcdcbcb473 fix(pi): resolve $NAME references in apiKey for usage queries
Pi lets a models.json provider's apiKey be "$NAME" / "${NAME}" (read from
the environment, with "$$" and "$!" as literal "$" and "!") or "!command".
CC Switch's own usage queries (Coding Plan, balance, usage-script
{{apiKey}}) read the Pi apiKey verbatim through resolve_usage_credentials,
so the provider received "Bearer $COMMAND_API_KEY" and answered 401.

Resolve the value with Pi's template rules before sending it. A referenced
variable that is unset or empty leaves the value unresolved, as in Pi, and
"!command" values are still never run by CC Switch; both now give an empty
key instead of sending the reference as the credential. The resolved key is
only used for the outgoing request and is never written back.

Refs #8822
2026-10-24 22:56:15 +08:00
Jason 442df1db70 fix(skills): send a User-Agent when downloading skill archives
The shared reqwest client has no default User-Agent (it also serves the
proxy forwarding path, where request headers must stay untouched), so
skill install and update downloaded GitHub repository archives without
one. GitHub throttles UA-less archive requests more aggressively; behind
a shared proxy exit the reporter got persistent HTTP 429 on update while
the same URL returned 200 once a User-Agent was present.

Set `CC-Switch/<version>` as the User-Agent on the archive download
request in `download_and_extract`, which covers both install and update,
matching the format already used by the deeplink icon fetcher.

Refs #8813
2026-10-24 22:56:15 +08:00
Jason b9f317af51 fix(usage): stop treating an empty DeepSeek balance as an expired plan
DeepSeek's /user/balance returns `is_available`, which only says whether
the balance is enough for API calls. It turns false as soon as the
balance reaches zero or goes negative, while the key itself still works.
The parser mapped it straight to `is_valid`, so the provider card and the
tray showed "plan expired" and dropped the balance entirely.

Always report the balance as valid and leave invalid keys to the
existing 401/403 auth-error path. A zero or negative balance now goes
through the normal balance line, which shows the amount in red on the
card and amber in the tray, the same as OpenRouter and Novita.

Refs #8812
2026-10-24 22:56:15 +08:00
Jason f395cd6be5 fix(kimi): import subagent usage from their own wire logs
Kimi Code writes every subagent to its own agents/agent-N/wire.jsonl,
but the usage importer only scanned agents/main/wire.jsonl and only read
assistant agent.message.appended records. Subagent replies never become
such records, so all subagent token usage was missing from the stats.

Scan every agents/<agent>/wire.jsonl. The main wire is imported exactly
as before. For a subagent wire, import each step.end that carries usage
(one per LLM call, matching usage.record 1:1 on real Kimi Code 2.3.1
data), keyed by its messageId in the dedup ledger, and resolve the
model and timing through a RequestIndex scoped to that agent instead of
discarding every request whose agentId is not "main". The parent's
subagent.completed summary is left alone so nothing is counted twice.

Refs #8792
2026-10-24 22:56:15 +08:00
Jason 6c2fc74e3b feat(pi): pick fetched models in a dialog for Pi and omp
The Pi form (also used by omp) only filled a per-row dropdown after
"Fetch models", so models had to be added one row at a time, unlike the
OpenCode, Codex and Kimi Code forms. Use the shared FetchedModelPicker:
a successful fetch opens the dialog, checked models are added as rows
and filled from presets or models.dev (thinking level maps only for Pi),
and unchecking a configured model removes its row. Fetched IDs are
de-duplicated and the success toast is dropped since the dialog opens.
The per-row dropdown stays.
2026-10-24 22:56:15 +08:00
Jason c6617bc235 fix(omp): move the discovery note from the apps page to the MCP and Skills columns
Oh My Pi also discovers MCP servers and skills from other agents'
directories, so what it loads can differ from what the matrix shows.
The note about this sat on the apps page, where it showed even before
Oh My Pi was installed and the "Docs: context-files" link did not say
what it was for.

Show the note in the Oh My Pi column popover of the MCP and Skills
matrices instead, and reword the link to say what it explains. The
apps page row now looks like every other app.
2026-10-24 22:56:15 +08:00
Jason ba6a8a5554 fix(apps): group Claude Desktop by whether it is installed
Claude Desktop was grouped by whether it was connected to CC Switch, so
an installed but unconnected Desktop showed up under "Not installed".

`get_claude_desktop_status` now reports `installed`. Desktop has no
command to probe, so it is inferred: connected, or Desktop's own data
directory (`Claude`, created on its first launch; `Claude-3p` is not
counted because CC Switch writes it too) exists, or on macOS a
Claude.app bundle is in /Applications or ~/Applications. The apps page
groups the Desktop row by it; the row still says whether it is connected.
2026-10-24 22:56:15 +08:00
Jason b71141a868 feat(apps): drag to reorder installed apps, sidebar follows the order
Installed apps on the apps page can be reordered by dragging the handle
that appears at the start of a row on hover, the same way provider cards
are sorted. Only the installed section is sortable: where a missing app
sits does not matter, and while the first probe has not finished it is
not yet known which section a row belongs to.

There is a single order for all apps, saved as `appOrder` in the
device-level settings.json next to `visibleApps` (not cloud-synced). The
sidebar and the app opened by default follow it. Each section shows the
order filtered by install state, so an app keeps its relative position
when it moves between sections. Apps missing from a saved order, such as
ones added in a later version, are inserted after their default
predecessor; unknown ids are ignored.

The dragged row is kept inside its section's list box, which clips
overflow for the rounded corners, so it cannot disappear mid-drag.
2026-10-24 22:56:15 +08:00
Jason e68e694374 fix(i18n): reword the failed quota line in Chinese as "query failed"
The Simplified and Traditional Chinese copy for a failed quota query,
"额度没查到" / "額度沒查到", read as a casual remark rather than a status.
Use "额度查询失败" / "額度查詢失敗" on the provider card, in the auth
center's account quota column (including its defaultValue fallback) and
in the tray, where the two variants with a reason now read
"额度查询失败:登录已过期" and "额度查询失败:令牌待刷新".

English, Japanese and Turkish are unchanged. Tests and comments that
quoted the old wording are updated.
2026-10-24 22:56:15 +08:00
Jason 72b056f6e6 fix(usage): show the balance amount even when it is used up
A balance at or below zero used to be replaced with "Balance used up" on
the provider card and in the tray. That hid how far an account was in
debt (DeepSeek reports -24.96 the same way as 0.00), and the red
sentence read like the red "quota unavailable" line, so a spent balance
and a failed query were hard to tell apart.

Always write "Balance <amount> <unit>"; at or below zero the whole line
turns red on the card and amber in the tray, as before. A negative zero
or a tiny negative amount that rounds to zero is written as 0.00 rather
than -0.00. The balanceUsedUp copy and the tray's balance_used_up text
are removed. Currency units stay as they are.

Refs #8812
2026-10-24 22:56:15 +08:00
Jason 5bc562ce04 feat(apps): group the apps page into installed and not installed sections
The apps page listed every client in one table, so the few that are not
installed were mixed in with the ones in daily use. It now splits the
rows into "Installed · N" and "Not installed · N", like the added /
available sections of additive providers. The first section's title
takes the column header row; later sections get their own title row,
and empty sections are hidden.

A CLI counts as installed when a version was detected, it is installed
but not runnable, or the install report found a location -- the same
check that decides whether Uninstall is offered, now shared as
isToolPresent. Claude Desktop cannot be detected, so it is grouped by
whether it is connected to CC Switch.

Until the first detection has a result for every row, the page keeps a
single ungrouped table so rows do not jump one by one; later re-checks
reuse the cached results and rows stay put. The action column width is
re-measured when rows move between sections, since they remount.
2026-10-24 22:56:14 +08:00
dsdbb520andJason 309c9c5154 fix(agy): recover subagent usage models from native generations (#8693)
Antigravity responses without a model field or a Model Selection event (subagents, ACP sessions) were imported as unknown. Recover the model from the native conversations/<id>.db: prefer the tiered model ID (field 21, matching Model Selection and pricing) and fall back to the base model name (field 19). The database is opened read-only, never waits on a writer, and keeps already recovered names when it cannot be read.

Co-authored-by: Jason <farion1231@gmail.com>
2026-10-24 22:42:59 +08:00
Xiangji c72c82cfbe feat(auth): support browser login for managed ChatGPT accounts (#8288)
Some managed ChatGPT workspaces disable device-code authentication, so those accounts could not be added to CC Switch. Add browser login (authorization code + PKCE with a loopback callback on port 1455) to the Auth Center and the Codex provider form, including reauthentication; device-code login stays available in a method selector.

Fixes #8284
2026-10-24 21:23:10 +08:00
Railgun bd50984e05 fix(forms): reflect automatic Copilot protocol routing (#8196) 2026-10-24 21:00:19 +08:00
alkank 9decd60e80 feat(i18n): complete Turkish catalog (#8616) 2026-10-24 20:56:55 +08:00
NeeYoonc 7f9cd9e967 fix(proxy): use the attached marker for orphan tool result media (#8157) 2026-10-24 20:54:40 +08:00
Vianrina e8ae28b659 fix(linux): restore window dragging and resize feedback (#8092) 2026-10-24 20:54:34 +08:00
Lukas 1a3057dc1f fix(sessions): skip local command output when titling Claude sessions (#8799) 2026-10-24 20:54:29 +08:00
Jason cae7c37540 chore(presets): remove EveryAPI sponsor and presets
Drop EveryAPI from the four README sponsor tables along with its banner,
remove its presets from the seven apps that carried them and its partner
promotion copy. The everyapi icon stays in the icon index because
providers users already added still reference it.
2026-10-24 15:44:09 +08:00
Jason c91aa77402 feat(kimi): show "No subscription" for accounts without a Kimi Code plan
Kimi's /usages endpoint answers HTTP 200 with an empty object for an
account that has no Kimi Code subscription. The quota query succeeds
with no tiers, so both the account row in the auth center and the
official card's quota footer used to stay blank, which looked like a
failed lookup.

When the query succeeds but yields no tiers, the account row now writes
"No subscription" in the value column and the card footer writes it in
the quota column, keeping the refresh control. SubscriptionQuotaView
takes an optional emptyText for this; other callers are unchanged.
2026-10-24 15:44:09 +08:00
Jason 626529451b feat(kimi): edit official account models and remove them from Kimi
Official Kimi accounts added in the Authorization Center were written
straight into config.toml with the model list discovered at sign-in.
Kimi Code only refreshes its own managed:kimi-code node, so separate
accounts kept that snapshot forever, and their cards could neither be
edited nor removed.

Official cards can now be edited. The editor hides the connection and
fetches the account's own catalog through a new kimi_oauth_models
command (token refreshed under Kimi's lock, aliases keyed by the
credential slot), so picked models carry the official context window,
capabilities and efforts. apply_provider pins an official node's
connection to the signed-in one, and ProviderService::update rejects
edits that would turn another card into an official account.

Official cards can also be removed from config.toml like other Kimi
providers: the card and credential stay, services pointing at a
separate account move to Kimi's own login, and "Add" restores it.
Deleting one still requires removing it first or using the
Authorization Center.
2026-10-24 15:44:09 +08:00
Jason c3e54a4e87 feat(pricing): seed Kimi K3.1 Pro and HighSpeed prices
Add Kimi K3.1 Pro (released 2026-10-23) to the built-in pricing table
at the official list price: 2/10 per MTok, cache read 0.20, 5-minute
cache write 2.00. HighSpeed doubles input, output and cache write but
keeps cache read at 0.20, unlike K2.7 Code HighSpeed where every column
is doubled.

Also seed the bare k3.1-pro / k3.1-pro-highspeed ids used by the Kimi
Code plan, mirroring the existing k3 row; the pricing prefix fallback
only matches longer ids, so they would otherwise bill at 0.
2026-10-24 15:44:00 +08:00
Jason d01daa0d65 fix(omp): hide the Oh My Pi choice when importing skills
Like Pi, Oh My Pi's skill state is whether the directory exists in its
native skills folder, and the import overwrites the submitted choice with
that fact. Showing the checkbox let users tick an option with no effect.
2026-10-24 15:30:32 +08:00
Jason d9422e7d6a fix(omp): install and update Oh My Pi without assuming Bun
omp also ships as a prebuilt binary (official installer, Homebrew), and
its npm package only runs under Bun. Install now runs the official
installer, which uses Bun when present and the verified binary otherwise.
Updates go through `omp update`, which routes every install source
itself: Homebrew keeps `brew upgrade`, Bun keeps `bun add -g` as the
fallback, Nix is left to the user, and npm is never offered. The
installer's binary is now recognized for uninstall.
2026-10-24 15:30:32 +08:00
Jason 9bacd1d172 fix(omp): allow project images in Oh My Pi session previews 2026-10-24 15:30:32 +08:00
Jason f1d43ebaab docs(readme): list Oh My Pi among the managed tools 2026-10-24 15:30:32 +08:00
Jason b34753b832 feat(omp): manage Oh My Pi global prompts
Oh My Pi reads its user-level instructions from AGENTS.md in the
profile-scoped agent directory, so prompts now project there like Kimi
Code's. Drop the prompt-sync skip and the stale deep-link notes that
assumed there was no prompt panel.
2026-10-24 15:30:32 +08:00
Jason e88a9fa417 refactor(omp): read Oh My Pi sessions through the Pi session reader
Oh My Pi keeps Pi's session tree format, so the Pi reader now takes a
small dialect (provider id, root resolution, resume command, the leading
title slot and the combined provider/model selector). The omp provider
keeps only its root resolution, resume command and artifact cleanup on
delete, and listing no longer renders every transcript to find a title.
2026-10-24 15:30:32 +08:00
Jasonandallenxu09 a03c6c7a3c refactor(omp): reuse the Pi provider form and plumbing for Oh My Pi
Drop the copied OmpProviderForm and the YAML editor; Oh My Pi now uses
PiProviderForm with an omp mode (no provider-level name, no
thinkingLevelMap, plus a discovery type selector). Presets are derived
from the Pi catalog. Pi-family helpers (isPiFamilyApp, parametrized
current-state queries and usage-script command) replace the scattered
pi/omp branches, and omp error keys reuse the Pi error translator.

Co-authored-by: allenxu09 <s23372.xu@stu.scie.com.cn>
2026-10-24 15:30:32 +08:00
Jasonandallenxu09 3d7cf6aa32 refactor(omp): port #8308's text-level models.yml editor and share Pi plumbing
Replace the passthrough/splice YAML layer with a single omp_config.rs:
#6747's verified agent-dir resolution (profiles, PI_CONFIG_DIR, XDG data
dir) plus #8308's block-level editor that rewrites only the one provider
entry, refuses anchors/tags/flow style instead of re-emitting them, and
rolls the file back byte for byte when the database commit fails.

- Validate only the node being written; model-level `api` also accepts
  omp's runner APIs.
- Drop ProviderMeta.ompPassthroughYaml, validation.rs and omp_state; the
  current-state command lives in commands/omp.rs and reuses PiCurrentState.
- Usage scripts go through the Pi command with an `app` argument.
- MCP reuses Pi's transport helpers; mcp.json writes are revision checked.
- Skills follow Pi: no DB column, state derived from <agent>/skills, and
  uninstall keeps an unverifiable same-name directory in either app.
- Move enabled_omp to a new v22 -> v23 migration (v22 shipped in 4.0.19)
  and add it to mcp_servers only; revert the .gitignore additions.

Co-authored-by: allenxu09 <s23372.xu@stu.scie.com.cn>
2026-10-24 15:30:32 +08:00
Jason 2afe8cdbef refactor(omp): rename the internal app id from ohmypi to omp
Match the binary name, the Apps page tool id and the i18n keys that
already used omp. The app is unreleased, so nothing persisted needs a
migration; ohmypi stays accepted as an alias when parsing app ids.
Show the app by default like Pi and Kimi Code.
2026-10-24 15:30:32 +08:00
JackieJKandallenxu09 c8945d2d91 feat(omp): add Oh My Pi support
Squashed from #6747 (head 50c3cec1d) onto current main: providers in
models.yml, MCP in mcp.json, Skills, sessions, app visibility and
directory override for Oh My Pi. Conflicts with the Kimi Code refresh
refactor in App.tsx and the locale files were resolved by keeping both
sides and routing Oh My Pi through refreshAdditiveLiveState.

Co-authored-by: allenxu09 <s23372.xu@stu.scie.com.cn>
2026-10-24 15:30:32 +08:00
Jason d8983bb10b docs(release): add v4.0.19 release notes v4.0.19 2026-10-23 20:13:26 +08:00
Jason a043b1f863 chore(release): v4.0.19 2026-10-23 20:13:26 +08:00
Jason bada9a4bb9 fix(models): don't borrow a vendor-hosted entry that points at another vendor
When a relay's model is not recognized by address, the metadata lookup
falls back to the vendor's entry: first the entry that same-name entries
point at via canonical_model_id, and only if none resolves, an entry
listed under a provider that some canonical id points at.

That last step only checked whether the provider counts as a vendor, not
whether the entry claims to be its own. models.dev has no
deepseek/deepseek-v4.1-flash-1017, so the ~40 entries pointing there all
miss, and thinkingmachines (counted as a vendor for its own models) won
with its LoRA fine-tuning entry DeepSeek-V4.1-Flash-1017:peft:262144,
whose canonical id points back at deepseek. It is text-only with a 262144
window, so picking the model filled every app with text-only input and a
quarter of the real window; Codex additionally turned image input off.

Skip entries whose canonical id names another vendor in that fallback.
Against the current models.dev data, 27 ids stop borrowing from hosts of
other vendors' models (thinkingmachines, NVIDIA, vivgrid, alibaba) and
leave the fields empty instead, and laguna-xs-2.1 now resolves to
poolside's own entry rather than being ambiguous. Skipping ':' variants
instead was rejected: it fixes this id but newly resolves nine
thinkingmachines entries carrying 65K training windows (gpt-oss-120b and
others).

Refs #8765, #8682
2026-10-23 20:11:53 +08:00
Jason e53ca7e820 fix(usage): tighten request log column spacing
The request log has more columns than the other usage tables, so at the
default window size the last column (first token) was cut off and the
table had to scroll sideways. Its columns are already sized to their
content, so the model column had no slack to give back.

Narrow the gaps for this table only: 16px between columns (was 24px) and
32px between column groups (was 40px), keeping the 16px outer edges. The
table shrinks by 72px with the same rows; model names are not truncated.
The provider, model and pricing tables keep their spacing.
2026-10-23 17:37:41 +08:00
Jason 50e091b055 fix(usage): step 7/14/30-day presets back by calendar days across DST
getPresetLookbackStart subtracted (N-1) * 24h from the current instant
and then rounded to local midnight. Across a DST offset change that
subtraction can land on the adjacent date, so the 7d/14d/30d presets
included one extra local day after spring-forward and dropped one after
fall-back (e.g. America/New_York, Europe/Berlin). The shifted range fed
the usage summary, model/provider stats and request-log queries.

Build the start date from today's local year/month/day minus (N-1) days
instead, which yields the first instant of that calendar day, including
zones where midnight itself is skipped by DST. The 1d rolling window,
today, all-time and custom ranges are unchanged.

Refs #8719
2026-10-23 17:37:41 +08:00
Jason 9cb6b6d7fa fix(agy): run background agy commands without a console window on Windows
Refreshing the Antigravity official quota on Windows popped up a black
console window. Outside macOS the quota falls back to spawning
`agy --print /usage`, and the model list in the provider form spawns
`agy models`. The release build is a GUI-subsystem app, so a console
child spawned without CREATE_NO_WINDOW gets its own console window.

Both spawn sites now go through agy_config::background_command, which
sets CREATE_NO_WINDOW on Windows like the other background tool probes.
Behaviour on macOS and Linux is unchanged.

Refs #8700
2026-10-23 17:37:41 +08:00
Jason 10e0aa2380 fix(deeplink): don't let a finished import close a newer link's confirmation
While provider link A was still importing (awaiting the backend import or
the follow-up cache refresh), a second link B could arrive, replace the
displayed request and be acknowledged in the backend. When A's import
completed, handleImport unconditionally called setIsOpen(false), closing
B's confirmation even though B was never imported and could no longer be
fetched again.

Track the request currently shown in a ref (set together with setRequest
in showPending) and close the dialog after an import only if it still
shows the request that import started with. Add a regression test that
holds A's import, delivers B, then checks B stays open and still imports
and closes on its own.

Refs #8696
2026-10-23 17:37:41 +08:00
Jason 7ecce7c79e fix(proxy): carry encrypted-only reasoning as empty thinking for Claude clients
Claude Code routed to an OpenAI Responses upstream showed "Unsupported
content type: redacted_thinking" before tool calls in the VS Code
extension. Reasoning items that only carry encrypted_content (summary is
empty) were converted into redacted_thinking blocks, which the extension
cannot render.

Emit them as an empty thinking block whose signature holds the reasoning
envelope instead, the same shape Anthropic returns for omitted thinking.
Replay already decodes thinking.signature and redacted_thinking.data the
same way, so replayed upstream requests are byte-identical and histories
written by older versions keep working.

Also recover summary text that never arrived as deltas: when
output_item.done carries a summary that strictly extends what was
streamed (e.g. a later summary part had no deltas), emit only the
missing tail before the signature. Snapshots that do not extend the
streamed text are ignored, so nothing is re-emitted.

The upstream request is unchanged; reasoning.summary is not injected.

Refs #8691
2026-10-23 17:37:41 +08:00
Jason 2fbd9c70f4 fix(hermes): launch the dashboard inside WSL when Hermes lives there
On Windows, pointing the Hermes config directory at a WSL path
(\\wsl$\<distro>\... or \\wsl.localhost\<distro>\...) only redirected
config, sessions and the version probe. When the Web UI was offline, the
"launch dashboard" action still opened a Windows terminal running
`hermes dashboard` natively, so it started the Windows hermes (or failed
with command not found) instead of the instance inside the distribution.

Build the dashboard command line from the existing per-tool WSL distro
detection: for a WSL override run it as
`wsl.exe -d <distro> -- sh -c "\"${SHELL:-sh}\" -lic 'hermes dashboard'"`
so the user's login shell PATH (e.g. ~/.local/bin) applies. Only one
shell flag is used, since a Ctrl+C exit is non-zero and a fallback retry
would relaunch the dashboard. The Web UI probe on 127.0.0.1 is unchanged;
WSL2 forwards localhost to the distribution. Other platforms keep the
plain `hermes dashboard`.

Refs #8689
2026-10-23 17:37:41 +08:00
Jason b5aa7fbbcb fix(agy): show Gemini quota when querying Google directly
Official Antigravity cards on macOS often showed only the Claude and GPT
quota. Google's retrieveUserQuotaSummary decides what to return from the
User-Agent: "cc-switch/<version> (antigravity)" passes the license check
but gets only the Claude and GPT group, and the Gemini group is returned
only to "antigravity/cli/<version>" from 1.2.0 on. agy's own /usage sends
that, which is why the fallback path always showed all four tiers.

The User-Agent is now "cc-switch/<version> (antigravity/cli/<agy
version>)". The version comes from the local "agy --version", probed once
per process, and falls back to 1.4.6 when agy cannot be found or read.
2026-10-23 17:37:41 +08:00
Jason 3494d0d100 chore(presets): add V-API backup endpoints
List V-API's mirror lines (api.vveai.com, run.v3.cm, api1.v3.cm,
api2.v3.cm, us.gpt.ge) as endpoint candidates after the main
api.gpt.ge in the Claude Code, Claude Desktop, Gemini CLI, Codex and
Grok Build presets, with /v1 on the OpenAI-format apps.
2026-10-23 17:37:41 +08:00
Allen Xu e5b04221ff fix(subscription): select Claude Keychain credentials by account (#8764) 2026-10-23 17:35:05 +08:00
ClarkChenandClaude Code c3ad9bb0bd fix(model-fetch): try compatible-mode models endpoint for /apps/anthropic base URLs (#8755)
Qianwen / Bailian Token Plan Anthropic endpoints (e.g.
https://token-plan.cn-beijing.maas.aliyuncs.com/apps/anthropic) return 404 for
/v1/models and /models; the model list is only served under the
OpenAI-compatible path {root}/compatible-mode/v1/models. Append it as the last
candidate when the base URL ends with /apps/anthropic.

Co-authored-by: Claude Code <noreply@anthropic.com>
2026-10-23 17:34:54 +08:00
streng during 2e1e29795a fix(proxy): recognize Codex session header aliases (#8718) 2026-10-23 17:34:44 +08:00
微尘 52652a02da fix(sessions): make the project group header clickable across the row (#8709) 2026-10-23 17:34:34 +08:00
秋澪Akimio c8f85674f4 fix(mcp): render server display name in unified MCP panel (#8692) 2026-10-23 17:34:24 +08:00
Jason e85ade714a chore(presets): swap the FluxA TokenPlan and Shengsuanyun sponsor positions
Move FluxA TokenPlan up to Shengsuanyun's former slot after V-API and
Shengsuanyun down to FluxA's former slot after SubRouter, in the four
README sponsor tables and the seven preset files that carry both.
2026-10-23 17:05:55 +08:00
Jason 91d3ed101d feat(presets): add V-API sponsor presets across nine apps
Add V-API (gpt.ge) as a full sponsor placed after BuyToken: README rows
and banner in all four languages, the partner promotion copy, an inline
tile icon, and presets for Claude Code, Claude Desktop, Codex, Gemini
CLI, Grok Build, OpenCode, OpenClaw, Hermes and Pi. The gateway prices
and gates models per token group, so each preset notes which group it
needs. It has no undated claude-haiku-4-5, so the Desktop Haiku tier is
mapped to claude-haiku-5-5.
2026-10-23 16:57:28 +08:00