* feat(usage): surface plan windows and account email in the chat context popover
The context-window popover now shows which account a session runs on:
provider usage snapshots carry an accountEmail resolved from the auth
profile when stored, the ChatGPT access-token JWT claims (openai/codex),
or the Claude CLI config file (~/.claude.json oauthAccount) for
keychain-synced logins. models.authStatus embeds it, quota groups keep
distinct accounts separate, and the popover renders the email under the
plan header for local CLI sessions and OpenClaw-configured subscriptions
alike.
* test(openai): assemble the fake usage JWT from parts
* test(usage): keep fixture tokens and identity plumbing scanner-safe
* fix(usage): verify the Claude CLI login before labeling usage with its email
Review findings: the CLI-config email fallback now requires the usage token
to match the cached CLI credential (and honors CLAUDE_CONFIG_DIR), so an
ambient login for another account never labels a snapshot; token-type
credentials propagate their stored email alongside oauth ones.
* style(anthropic): scanner-safe local for the CLI login read
* fix(usage): capture the Claude CLI account email on the credential
Review findings: reading ambient CLI config at usage-fetch time could not
verify keychain-only logins and could go stale across account switches.
The credential reader now captures oauthAccount.emailAddress next to the
credential it belongs to, the synced claude-cli profile carries it, and
the anthropic fetcher uses only the credential-borne identity.
* style(usage): scanner-safe credential fixtures and helper naming
* fix(auth): backfill the CLI account email onto existing synced profiles
Profiles synced before identity capture stay usable and skip CLI reads,
so upgraded installs would never gain the email until token rotation.
While the stored token material matches the CLI login, merge the
non-secret email onto the stored profile.
* style(test): scanner-safe email assertion
* test(auth): pin the no-reread invariant to identity-complete profiles
Fail closed when managed OpenAI OAuth refresh fails instead of silently falling back to stale external Codex CLI credentials.
Make managed provider OAuth authoritative after bootstrap, preserve API-key and non-OpenAI external CLI behavior, and surface targeted re-auth guidance without exposing profile IDs in group/channel replies.
Fixes#99120.
Co-authored-by: Eva <239388517+100yenadmin@users.noreply.github.com>
Refactor OpenAI provider identity so OpenAI remains the canonical provider for API-key and OAuth-backed flows while legacy openai-codex state is doctor/migration-only.
Keeps OpenAI Codex Responses as an API/transport class rather than a provider identity, moves auth aliases through providerAuthAliases, updates doctor repair sequencing for old auth/profile state, and refreshes tests/docs around the canonical OpenAI behavior.
* fix(auth): bootstrap codex cli credential without clobbering local
readCodexCliCredentialsCached was imported but never registered in
EXTERNAL_CLI_SYNC_PROVIDERS, so overlayExternalAuthProfiles could not
seed openai-codex:default on fresh agents and runtime surfaced
"No API key found for provider openai-codex" even after a successful
codex login.
Register the provider with a new bootstrapOnly flag. Providers flagged
bootstrapOnly are adopted only to fill an empty slot: the overlay skips
them when a local OAuth credential already exists for the profile, and
readExternalCliBootstrapCredential returns null so the refresh path
never replaces the locally stored canonical refresh token with stale
CLI state. Minimax keeps its existing replace-on-expiry behavior.
* test(auth): cover codex cli bootstrap
---------
Co-authored-by: sudol <sudol@A8Max.localdomain>
Co-authored-by: Peter Steinberger <steipete@gmail.com>
* Remove Qwen OAuth integration (qwen-portal-auth)
Qwen OAuth via portal.qwen.ai is being deprecated by the Qwen team due
to traffic impact on their primary Qwen Code user base. Users should
migrate to the officially supported Model Studio (Alibaba Cloud Coding
Plan) provider instead.
Ref: https://github.com/openclaw/openclaw/issues/49557
- Delete extensions/qwen-portal-auth/ plugin entirely
- Remove qwen-portal from onboarding auth choices, provider aliases,
auto-enable list, bundled plugin defaults, and pricing cache
- Remove Qwen CLI credential sync (external-cli-sync, cli-credentials)
- Remove QWEN_OAUTH_MARKER from model auth markers
- Update docs/providers/qwen.md to redirect to Model Studio
- Update model-providers docs (EN + zh-CN) to remove Qwen OAuth section
- Regenerate config and plugin-sdk baselines
- Update all affected tests
Co-authored-by: Qwen-Coder <qwen-coder@alibabacloud.com>
* Clean up residual qwen-portal references after OAuth removal
* Add migration hint for deprecated qwen-portal OAuth provider
* fix: finish qwen oauth removal follow-up
---------
Co-authored-by: Qwen-Coder <qwen-coder@alibabacloud.com>
Co-authored-by: Frank Yang <frank.ekn@gmail.com>
- invalidate cached Codex CLI credentials when auth.json changes within the TTL window
- skip external CLI sync when the stored Codex OAuth credential is newer
- cover both behaviors with focused regression tests
Refs #53466
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>