Repository navigation
Conversation
Step 1 lists the services in three groups (model vendors, platforms and relays, local and custom) with real marks and one-line descriptions, and adds OpenRouter, ThinkWatch, Sub2API and New API / One API. Picking a tile goes straight to step 2. Step 2 asks only what the tile did not decide: an authentication row appears only when the service really has more than one method, the protocol select only where there is a choice, Z.ai's URL comes from its site, Ollama has no key field. The balance source is never asked for: Sub2API, New API and ThinkWatch write it from the tile, everything else leaves it to detection. Signing in with a ChatGPT or Z.ai account now happens in the wizard's second step instead of separate dialogs, keeping their notes, checks and cancellation, and adding a copyable sign-in link, the ChatGPT device code locally, and a device-code-only flow when connected to a remote core. After sign-in the upstream exists, so Models and Billing edit it through the edit path. The standalone Z.ai dialog is removed; the ChatGPT dialog remains for signing in again from an existing upstream. The shell returns the authorize URL for display; copying and opening still go by login ID, so the webview never hands Rust a URL to open or text to put on the clipboard. ProviderInput.balance is added to the generated types by hand until core protocol 46 is pinned. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Core's protocol 46 reports what config says as ProviderView.balance_setting. The edit form now fills from it and sends it back, so saving or toggling an upstream no longer turns `off` or a named source into `auto`. New upstreams still take the source from the tile. BalanceSetting and ProviderView.balance_setting are added to the generated types by hand until core protocol 46 is pinned. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Editing used to show every upstream as Custom, so an Ollama upstream asked for a key, an Anthropic one offered OAuth and a Z.ai one showed a raw address. The dialog now recognises the service from the saved upstream (official hosts, Bedrock, Ollama's port, and the balance setting for relays and the enterprise gateway) and asks what creating it would ask, with its logo and name in the header. Changing the address to another host makes it Custom from then on. A value that is set is never hidden: whatever the config held when the dialog opened and falls outside the service's rules (OAuth on an official host, a key on Ollama, another protocol, a non-standard Z.ai path, client identity) is shown the Custom way. Editing never requires a key. A Z.ai / BigModel upstream gets "sign in to replace the key", through the re-login dialog now shared with ChatGPT; core replaces only the key of the same-named upstream on that site. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Contributor
Author
|
Merged as part of #318 (2026.10.14). |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
What
The new-upstream wizard, second version.
Step 1 — Service. Three groups: Model vendors (Anthropic, OpenAI, Google Gemini, DeepSeek, Z.ai / BigModel), Platforms and relays (Amazon Bedrock, OpenRouter, ThinkWatch, Sub2API, New API / One API) and Local and custom (Ollama, Custom), each tile with the one-line description from the design (ThinkWatch: "ThinkWatch 企业网关", Sub2API and New API: "API 中转平台"). Real marks from
@/ui/logos; ThinkWatch draws the app's own TW mark (src/ui/app-mark.tsx, strokes shared with the launch screen throughsrc/ui/tw-strokes.ts); Sub2API and New API have no mark we may use and keep the initial-letter tile. Search matches name, description and common names ("ChatGPT" finds OpenAI, "智谱" finds Z.ai). Picking a tile goes straight to step 2. The separate "sign in with an account" group is gone: signing in is an authentication method of OpenAI and Z.ai.New presets:
balancewrittenhttps://openrouter.ai/api(core appends/v1/chat/completions,/v1/models)openrouter.ai)thinkwatchsub2apinewapiapi.z.ai/api/anthropic,open.bigmodel.cn/api/anthropicStep 2 — Connection / Account. A full-width, equal-segment Authentication row, only when the service has more than one method: OpenAI → API key / ChatGPT account; Z.ai / BigModel → API key / account sign-in; Bedrock → API key / access keys / AWS profile; Custom, ThinkWatch, Sub2API, New API → API key / OAuth; everything else has no row. Name and outbound proxy share the next row in every method. What the tile decided is not asked again (
presets.ts): the protocol select appears only where there is a real choice (OpenAI: Chat Completions / Responses; relays and Custom: all plus auto-detect), Z.ai's URL comes from its site control, Ollama has no API key field, "Forward client identity" only shows for relays and Custom, and services that need a key cannot go on without one. There is no balance-source control anywhere;toInputwritesbalancefrom the tile.Account sign-in inside the wizard (ChatGPT, Z.ai). The step is labelled Account and the login panel replaces the connection fields. Everything the two login dialogs did is kept: the notes with the "已阅读上述说明" checkbox (minus the "requests say they come from ThinkWatch" line), Z.ai's site choice, the name checks (ChatGPT names must be free; a Z.ai name on the same site replaces that upstream's key), proxy, errors, expiry, reopen and cancellation. New:
The standalone Z.ai dialog is deleted.
ChatgptLoginDialogbecameReloginDialog, used only to sign an existing upstream in again (a ChatGPT upstream's Account section, or a new key for a Z.ai / BigModel upstream, see Editing), built from the same hook (accountLogin.ts) and panel (AccountPanel.tsx).Rust (
src-tauri).start_chatgpt_login/start_zai_logintakeopenand return the authorize URL for display. Copying and opening still go by login ID on the Rust side:copy_chatgpt_codebecamecopy_chatgpt_login(id, item: "url" | "code"),copy_zai_login(id)is new, andreopen_chatgpt_loginopens the verification address for a device-code sign-in.Types. Core's protocol 46 (ThinkWatch-Core#321) is being built in parallel. Added by hand to
src/generated/tw-api.ts, following that branch:BalanceSetting = "auto" | "off" | "openrouter" | "deepseek" | "moonshot" | "sub2api" | "newapi" | "thinkwatch",ProviderInput.balance?: BalanceSetting | nullandProviderView.balance_setting(optional here, required in core; the regenerated file from core replaces all of it, andscripts/shots/core/answers get regenerated withoracle.shthen).Balance round-trip. The edit form fills
balancefromProviderView.balance_settingand sends it back asProviderInput.balance, so saving (or toggling) an upstream never turns anoffor a named source intoauto. New upstreams write the tile's source (Sub2API, New API, ThinkWatch); OpenRouter, DeepSeek and everything else leave it toauto, which recognises their hosts and the enterprise gateway.The Bedrock draft path (create from a client takeover) still opens on step 2 with the type decided.
Editing
The edit dialog applies the same per-service rules as creating.
serviceOf(inpresets.ts) recognises the saved upstream: official hosts (api.anthropic.com,api.openai.com,generativelanguage.googleapis.com,api.deepseek.com,openrouter.ai,api.z.ai/open.bigmodel.cnwith the site), Bedrock by its standard address orprotocol: bedrock, Ollama by port 11434, and Sub2API / New API / ThinkWatch bybalance_setting(they live on arbitrary hosts). Everything else is Custom; ChatGPT accounts keep their own Account section and re-login.name · Anthropic, the TW mark for ThinkWatch, S / N for Sub2API / New API); Custom keepsname · protocol · address.retarget), with the full form.fieldRules, decided by what the config held when the dialog opened, so a field cannot vanish while it is being edited): an Anthropic-host upstream saved with OAuth gets Custom's authentication choices with OAuth selected and kept; an Ollama upstream with a key shows the key; a protocol other than the one the service fixes (or none on a host that does not auto-detect to it) shows the full protocol list; a Z.ai upstream on a non-standard path shows its address; "Forward client identity" shows wherever it is on; headers always show. Editing never requires a key (a saved upstream may authenticate with its own header).ReloginDialog, shared with ChatGPT) for that site; core replaces only the key of the same-named upstream on the same site. Z.ai's notes and checkbox are shown there, since the key may never have come from a sign-in.Tests: recognition for every host and setting, re-recognition on address change, and "a set value is never hidden" cases (OAuth on an official host, Ollama key, foreign protocol, non-standard Z.ai path, client identity, key not required when editing).
Checked in the preview harness: editing each mocked upstream (anthropic, openrouter, deepseek, gemini, ollama, zai, bigmodel, chatgpt) and Sub2API / ThinkWatch / New API upstreams created through the wizard, saving with
balancekept, moving Anthropic to another host, and the Z.ai sign-in from the edit dialog; light and dark, Chinese and English.Where this deviates from the design canvas, and why
Known gaps
ProviderView.balance, the test result's balance line on the Sub2API board) are not shown here.Verification
pnpm typecheck,pnpm test(105 files, 1117 tests; newpresets.test.tsand form tests for auth options, naming, site, key requirements,balancefrom the tile, and anoff/ named /autosetting round-tripping through the edit form).cargo fmt --checkandcargo clippy --all-targets -- -D warningsonsrc-tauri;cargo test --no-fail-fastpasses exceptts_bindings::the_committed_bindings_match_the_pinned_core, which fails on purpose until a core with protocol 46 is pinned:src/generated/tw-api.tscarries the hand-added balance types described above. Pinning the new core and regenerating (UPDATE_TS=1 cargo test --test ts_bindings) clears it.🤖 Generated with Claude Code