Commit 54ac427
authored
feat: add kimi and minimax oauth login (#291)
## Related Issue
No tracking issue — maintainer-directed change in the repository owner's
branch.
## Problem
Two independent gaps:
1. The login flow only offered API-key platforms and OpenAI Codex OAuth.
Kimi For Coding and MiniMax (global and China) subscriptions could not
be connected from pythinker-code.
2. OpenCode Go requires the `x-opencode-session` header (one stable id
per conversation) on gateway requests; pythinker-code did not send it.
OpenCode billing rejections such as `401 Insufficient balance` were also
being mislabeled as authentication failures.
## What changed
- Added Kimi For Coding and MiniMax OAuth sign-in for global and China
regions.
- Kimi now uses the official device flow, stable device identity
headers, sanitized host OS release, persisted OAuth credentials,
refresh-token rotation, and restart-safe runtime refresh.
- MiniMax now follows the official MiniMax CLI PKCE/state device flow,
including `user_code`, millisecond `expired_in`, provider-specific
polling semantics, persisted OAuth credentials, refresh-token rotation,
and regional endpoints.
- OAuth bearer tokens and refresh tokens are no longer embedded in
`config.toml`; providers reference the existing credential store
instead.
- Runtime OAuth refresh uses a five-minute proactive refresh window,
forced refresh after authorization failure, single-flight refresh for
concurrent requests, and persistence of rotated credentials.
- Device authorization cancellation now aborts the initial request and
cannot open a browser after cancellation. Kimi/MiniMax cancellation
during model selection/config loading resolves the login flow as `false`
without committing config.
- `scripts/check-product-boundaries.mjs`: the hosted-inference-endpoint
guard exempts `packages/oauth/src/kimi-oauth.ts` via the existing allow
mechanism because the direct device-OAuth login legitimately targets
that upstream; every other surface stays banned.
- Model requests to HTTPS OpenCode gateway hosts (`opencode.ai` and
subdomains) send `x-opencode-session` with a stable conversation id.
HTTP and lookalike hosts receive no session header. The one-shot
connectivity probe generates a fresh UUID for every probe.
- OpenCode `401 Insufficient balance` responses are classified as
provider/billing failures rather than `provider.auth_error`; ordinary
invalid-credential 401 responses remain authentication errors.
- Added focused regression coverage for OAuth protocol behavior,
refresh/rotation, cancellation, credential references, OpenCode billing
classification, HTTPS-only session headers, and fresh ping session IDs.
- Changesets are included for the user-facing changes.
## Checklist
- [x] I have read the
[CONTRIBUTING](https://github.com/PyModel/pythinker-code/blob/main/CONTRIBUTING.md)
document.
- [x] No related issue is required for this maintainer-directed change.
- [x] I have added tests that prove the feature and fixes work.
- [x] Ran `gen-changesets` skill, or this PR needs no additional
changeset.
- [x] Ran `gen-docs` skill, or this PR needs no doc update.
<!-- This is an auto-generated comment: release notes by coderabbit.ai
-->
## Summary by CodeRabbit
* **New Features**
* Added OAuth sign-in for Kimi For Coding and MiniMax in global and
China regions.
* Added device-code authentication, model selection, cancellation, and
account configuration.
* Added per-conversation session support for OpenCode Go requests.
* Added custom request-header support across supported AI providers.
* Added a workspace endpoint for adding directories.
* **Bug Fixes**
* Improved OAuth refresh reliability, concurrency protection, timeouts,
and credential preservation.
* Improved browser sign-in fallback and Windows Codex login.
* Improved authentication, billing, and quota error handling.
* Updated permission-mode labels and trust-prompt defaults.
<!-- end of auto-generated comment: release notes by coderabbit.ai -->1 parent 7838e5e commit 54ac427
124 files changed
Lines changed: 4332 additions & 633 deletions
File tree
- .agents/skills
- agent-core-review/slop
- write-tui
- .changeset
- apps/pythinker-code
- dist-web
- src
- cli
- sub
- web
- constant
- tui
- commands
- components
- chrome
- dialogs
- messages
- controllers
- utils
- utils
- test
- tui
- commands
- components
- chrome
- dialogs
- messages
- reverse-rpc
- utils
- docs
- configuration
- customization
- guides
- reference
- packages
- agent-core-v2
- docs
- src
- agent
- agentsMdReminder
- permissionPolicy/policies
- profile
- app/auth
- kosong
- contract
- model
- provider/bases
- anthropic
- google-genai
- openai
- session/advisor
- test
- agent
- agentsMdReminder
- permissionPolicy
- profile
- app/auth
- kosong
- model
- provider
- session/advisor
- agent-core/src/services/auth
- agent-gateway
- src
- protocol
- routes
- test
- __snapshots__
- node-sdk
- src
- login
- test
- oauth
- src
- test
- pi-tui
- scripts
Some content is hidden
Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
24 | 24 | | |
25 | 25 | | |
26 | 26 | | |
27 | | - | |
| 27 | + | |
28 | 28 | | |
29 | 29 | | |
30 | 30 | | |
| |||
Large diffs are not rendered by default.
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
| 1 | + | |
| 2 | + | |
| 3 | + | |
| 4 | + | |
| 5 | + | |
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
| 1 | + | |
| 2 | + | |
| 3 | + | |
| 4 | + | |
| 5 | + | |
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
| 1 | + | |
| 2 | + | |
| 3 | + | |
| 4 | + | |
| 5 | + | |
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
| 1 | + | |
| 2 | + | |
| 3 | + | |
| 4 | + | |
| 5 | + | |
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
| 1 | + | |
| 2 | + | |
| 3 | + | |
| 4 | + | |
| 5 | + | |
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
| 1 | + | |
| 2 | + | |
| 3 | + | |
| 4 | + | |
| 5 | + | |
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
| 1 | + | |
| 2 | + | |
| 3 | + | |
| 4 | + | |
| 5 | + | |
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
| 1 | + | |
| 2 | + | |
| 3 | + | |
| 4 | + | |
| 5 | + | |
0 commit comments