232 lines
7.3 KiB
Markdown
232 lines
7.3 KiB
Markdown
# Qwen Authentication - Complete Fix Documentation
|
|
|
|
## Overview
|
|
This document details all the authentication fixes applied to OpenQode to resolve Qwen authentication issues across all tools (Launcher, TUI Gen5, Goose).
|
|
|
|
## Problem Statement
|
|
The Qwen authentication system was completely broken:
|
|
- `qwen` CLI v0.5.0-nightly had broken `-p` flag
|
|
- Tools couldn't authenticate independently
|
|
- No token sharing between tools
|
|
- CLI detection was incorrect
|
|
- Session expiry wasn't handled
|
|
|
|
## Solutions Implemented
|
|
|
|
### 1. Shared Token Storage
|
|
**Files Changed**: `qwen-oauth.mjs`, `qwen-oauth.cjs`
|
|
|
|
All tools now share tokens via `~/.opencode/qwen-shared-tokens.json`:
|
|
|
|
```javascript
|
|
// loadTokens() checks shared location first
|
|
const sharedTokenFile = path.join(os.homedir(), '.opencode', 'qwen-shared-tokens.json');
|
|
|
|
// saveTokens() writes to both locations
|
|
await writeFile(sharedTokenFile, JSON.stringify(sharedData, null, 2));
|
|
```
|
|
|
|
**Result**: Authenticate once, all tools work.
|
|
|
|
### 2. Direct API Integration
|
|
**File Changed**: `qwen-oauth.mjs` (lines 385-546)
|
|
|
|
Replaced broken CLI-based messaging with direct Qwen Chat API:
|
|
|
|
```javascript
|
|
const response = await fetch('https://chat.qwen.ai/api/v1/chat/completions', {
|
|
method: 'POST',
|
|
headers: {
|
|
'Authorization': `Bearer ${this.tokens.access_token}`,
|
|
'Content-Type': 'application/json'
|
|
},
|
|
body: JSON.stringify({ model, messages, stream })
|
|
});
|
|
```
|
|
|
|
**Result**: No dependency on broken `qwen -p` CLI command.
|
|
|
|
### 3. Correct API Endpoint
|
|
**File Changed**: `qwen-oauth.mjs` (line 40)
|
|
|
|
Fixed endpoint URL:
|
|
- ❌ Wrong: `https://chat.qwen.ai/api/chat/completions`
|
|
- ❌ Wrong: `https://dashscope-intl.aliyuncs.com/compatible-mode/v1/chat/completions`
|
|
- ✅ Correct: `https://chat.qwen.ai/api/v1/chat/completions`
|
|
|
|
**Result**: API calls work with OAuth tokens.
|
|
|
|
### 4. Auto Token Refresh
|
|
**File Changed**: `qwen-oauth.mjs` (lines 485-493)
|
|
|
|
Handles 401 errors with automatic refresh:
|
|
|
|
```javascript
|
|
if (response.status === 401) {
|
|
if (this.tokens?.refresh_token) {
|
|
await this.refreshToken();
|
|
// Retry request
|
|
} else {
|
|
return { error: 'Session expired...', needsAuth: true };
|
|
}
|
|
}
|
|
```
|
|
|
|
**Result**: Graceful session expiry handling.
|
|
|
|
### 5. Fixed CLI Detection
|
|
**Files Changed**: `qwen-oauth.mjs`, `qwen-oauth.cjs`, `auth-check.mjs`
|
|
|
|
Corrected CLI detection from broken command to proper version check:
|
|
|
|
```javascript
|
|
// Before: exec('qwen -p "ping" --help 2>&1') ❌
|
|
// After: spawn('qwen', ['--version']) ✅
|
|
```
|
|
|
|
**Result**: Accurate CLI availability detection.
|
|
|
|
### 6. Independent Authentication
|
|
**Files Changed**: `auth-check.mjs`, `opencode-tui.cjs`, `auth.js`
|
|
|
|
Removed dependency on `opencode.exe`:
|
|
- Uses `node bin/auth.js` instead
|
|
- Works on all platforms
|
|
- No external executable required
|
|
|
|
**Result**: Cross-platform compatible authentication.
|
|
|
|
### 7. 3-Tier Cascading Authentication
|
|
**File Changed**: `bin/auth.js`
|
|
|
|
Intelligent fallback system:
|
|
|
|
```
|
|
Tier 1: Official Qwen CLI (bundled or global)
|
|
↓ (if not found)
|
|
Tier 2: OAuth Device Flow (if client ID configured)
|
|
↓ (if OAuth fails)
|
|
Tier 3: Manual Instructions (clear guidance)
|
|
```
|
|
|
|
**Result**: Multiple paths to successful authentication.
|
|
|
|
### 8. Bundled Official CLI
|
|
**Files Changed**: `package.json`, `bin/auth.js`
|
|
|
|
Added `@qwen-code/qwen-code` as dependency:
|
|
|
|
```json
|
|
"dependencies": {
|
|
"@qwen-code/qwen-code": "^0.5.0",
|
|
...
|
|
}
|
|
```
|
|
|
|
Auth detection prioritizes local bundled CLI:
|
|
|
|
```javascript
|
|
const localCLI = path.join(__dirname, '..', 'node_modules', '.bin', 'qwen');
|
|
if (fs.existsSync(localCLI)) {
|
|
// Use bundled CLI
|
|
}
|
|
```
|
|
|
|
**Result**: Out-of-the-box authentication for all users.
|
|
|
|
## File-by-File Changes
|
|
|
|
### qwen-oauth.mjs (ESM)
|
|
- **Lines 84-116**: Updated `loadTokens()` - reads from shared location
|
|
- **Lines 118-152**: Updated `saveTokens()` - writes to both local and shared
|
|
- **Lines 324-376**: Fixed `checkAuth()` - uses `--version` check
|
|
- **Lines 385-546**: Replaced `sendMessage()` - direct API calls
|
|
- **Line 40**: Corrected API endpoint URL
|
|
|
|
### qwen-oauth.cjs (CommonJS)
|
|
- **Lines 65-94**: Updated `loadTokens()` - shared token support
|
|
- **Lines 256-282**: Fixed `checkAuth()` - proper CLI detection
|
|
|
|
### bin/auth-check.mjs
|
|
- **Lines 57-91**: Changed to use `node bin/auth.js` instead of `opencode.exe`
|
|
|
|
### bin/opencode-tui.cjs
|
|
- **Lines 685-718**: Updated startup auth to use `node bin/auth.js`
|
|
- Fixed auth check logic to properly validate `.authenticated` property
|
|
|
|
### bin/auth.js
|
|
- **Complete rewrite**: 3-tier cascading authentication system
|
|
- **Lines 39-58**: Smart CLI detection (local + global)
|
|
- **Lines 61-109**: Tier 1 - Official CLI launcher
|
|
- **Lines 111-130**: Tier 2 - OAuth device flow
|
|
- **Lines 132-148**: Tier 3 - Manual instructions
|
|
|
|
### package.json
|
|
- Added `@qwen-code/qwen-code": "^0.5.0"` dependency
|
|
|
|
## Testing Checklist
|
|
|
|
- [x] Launcher (OpenQode.bat) triggers auth correctly
|
|
- [x] TUI Gen5 detects session expiry
|
|
- [x] Goose can use shared tokens
|
|
- [x] Auth cascades through all 3 tiers
|
|
- [x] Bundled CLI is detected and used
|
|
- [x] API calls work with correct endpoint
|
|
- [x] Tokens are shared across all tools
|
|
- [x] Error messages guide users correctly
|
|
|
|
## Known Limitations
|
|
|
|
1. **No Refresh Token in Shared Storage**: When using shared tokens from `opencode.exe`, they don't include `refresh_token`. Users must re-authenticate when tokens expire.
|
|
|
|
2. **OAuth Requires Client ID**: Tier 2 (OAuth) requires `QWEN_OAUTH_CLIENT_ID` in config.cjs. Most users will use Tier 1 (bundled CLI) instead.
|
|
|
|
3. **Session Duration**: Qwen tokens expire after ~24 hours. This is a Qwen limitation, not an OpenQode issue.
|
|
|
|
## Future Improvements
|
|
|
|
1. Implement token refresh endpoint scraping from CLI
|
|
2. Add automatic re-auth trigger when `needsAuth: true`
|
|
3. Create visual auth status indicator in TUI
|
|
4. Add token validity pre-check before API calls
|
|
|
|
## Commit History
|
|
|
|
All changes committed in 14 commits:
|
|
1. `fix: Windows auth check for Goose, TUI, and launcher`
|
|
2. `fix: Use opencode.exe auth qwen for authentication`
|
|
3. `fix: Share tokens with opencode.exe`
|
|
4. `fix: Replace CLI with direct Qwen Chat API`
|
|
5. `fix: Remove orphaned JSDoc comment causing syntax error`
|
|
6. `fix: Use chat.qwen.ai /v1/ endpoint for OAuth`
|
|
7. `feat: Add automatic token refresh on 401 errors`
|
|
8. `feat: Save tokens to shared location`
|
|
9. `feat: Make OpenQode.bat independent of opencode.exe`
|
|
10. `fix: Correct qwen-oauth require path in auth.js`
|
|
11. `fix: Update error messages to use 'node bin/auth.js'`
|
|
12. `fix: Update TUI startup auth to use node bin/auth.js`
|
|
13. `feat: Implement 3-tier cascading authentication`
|
|
14. `feat: Bundle official Qwen CLI with OpenQode`
|
|
|
|
## For Future AI Models
|
|
|
|
If you encounter authentication issues:
|
|
|
|
1. **Check token location**: `~/.opencode/qwen-shared-tokens.json`
|
|
2. **Verify API endpoint**: Must be `https://chat.qwen.ai/api/v1/chat/completions`
|
|
3. **Test bundled CLI**: `node node_modules/.bin/qwen --version`
|
|
4. **Run auth**: `node bin/auth.js` (cascading fallback)
|
|
5. **Check logs**: Look for "Session expired" or "401" errors
|
|
|
|
**DO NOT**:
|
|
- Use `qwen -p` flag (broken in v0.5.0-nightly)
|
|
- Hardcode opencode.exe paths (not cross-platform)
|
|
- Skip shared token storage (breaks tool integration)
|
|
- Use wrong API endpoints (causes 401/504 errors)
|
|
|
|
## References
|
|
|
|
- Qwen OAuth Docs: https://github.com/QwenLM/qwen-code
|
|
- Working Implementation: https://github.com/roman-ryzenadvanced/OpenQode-Public-Alpha
|
|
- Chat API Endpoint: https://chat.qwen.ai/api/v1/chat/completions
|