npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2026 – Pkg Stats / Ryan Hefner

opencode-qwencode-oauth

v1.0.5

Published

Qwen OAuth authentication plugin for OpenCode with multi-account rotation and API translation

Downloads

1,511

Readme

OpenCode Qwen Auth Plugin

npm version npm downloads CI License: MIT Built with Bun

Qwen OAuth authentication plugin for OpenCode with multi-account rotation, proactive token refresh, and automatic API translation.

Features

  • Device Flow OAuth - PKCE-secured authentication, works in headless/CI environments
  • Multi-Account Support - Store and rotate between multiple Qwen accounts
  • Hybrid Account Rotation - Smart selection using health scores, token bucket, and LRU
  • Proactive Token Refresh - Automatically refresh tokens before expiry
  • Rate Limit Handling - Detects 429 responses, rotates accounts, respects retry-after
  • API Translation - Bridges OpenAI Responses API ↔ Chat Completions API
  • Streaming Support - Full SSE transformation for real-time responses
  • Cross-Platform - Works on macOS, Linux, and Windows

Installation

Let an LLM Do It

Paste this into any LLM agent (Claude Code, OpenCode, Cursor, etc.):

Install the opencode-qwencode-oauth plugin by following: https://raw.githubusercontent.com/mseptiaan/opencode-qwencode-oauth/main/README.md

Quick Install (Recommended)

Add to your opencode.json:

{
  "$schema": "https://opencode.ai/config.json",
  "plugin": ["opencode-qwencode-oauth"],
  "provider": {
    "qwen": {
      "npm": "@ai-sdk/openai",
      "options": {
        "baseURL": "https://portal.qwen.ai/v1",
        "compatibility": "strict"
      },
      "models": {
        "coder-model": {
          "id": "coder-model",
          "name": "Qwen Coder",
          "limit": {
            "context": 1048576,
            "output": 65536
          },
          "modalities": {
            "input": [
              "text",
              "image"
            ],
            "output": [
              "text"
            ]
          },
          "attachment": true
        }
      }
    }
  }
}

Quick Start

  1. Start OpenCode in your project directory:

    opencode
  2. Authenticate with Qwen:

    /connect

    Select Qwen OAuth and follow the device flow instructions.

  3. Start coding with Qwen models:

    /model qwen/coder-model

Configuration

No configuration required. The plugin works out of the box with sensible defaults.

Configuration is loaded in layers with later sources taking precedence:

  1. Built-in defaults
  2. User config (~/.config/opencode/qwen.json)
  3. Project config (.opencode/qwen.json)
  4. Environment variables

Available Options

| Option | Default | Description | | ------ | ------- | ----------- | | rotation_strategy | "hybrid" | Account rotation strategy (hybrid, round-robin, sequential) | | proactive_refresh | true | Refresh tokens before they expire | | refresh_window_seconds | 300 | Seconds before expiry to trigger a proactive refresh | | max_rate_limit_wait_seconds | 300 | Max time to wait when all accounts are rate-limited (0 = unlimited) | | quiet_mode | false | Suppress informational log output | | pid_offset_enabled | false | Distribute load by process PID when running parallel sessions | | health_score | (see below) | Fine-tune health score parameters | | token_bucket | (see below) | Fine-tune token bucket parameters |

Environment Variables

| Variable | Config Key | | -------- | ---------- | | QWEN_OAUTH_CLIENT_ID | client_id | | QWEN_OAUTH_BASE_URL | oauth_base_url | | QWEN_API_BASE_URL | base_url | | QWEN_ROTATION_STRATEGY | rotation_strategy | | QWEN_PROACTIVE_REFRESH | proactive_refresh | | QWEN_REFRESH_WINDOW_SECONDS | refresh_window_seconds | | QWEN_MAX_RATE_LIMIT_WAIT_SECONDS | max_rate_limit_wait_seconds | | QWEN_QUIET_MODE | quiet_mode | | QWEN_PID_OFFSET_ENABLED | pid_offset_enabled |

Models

Available via OAuth

| Model | Context Window | Features | | ----- | -------------- | -------- | | coder-model | 1M tokens | Text + image input, streaming |

Multi-Account Rotation

Add multiple accounts for higher throughput:

  1. Run /connect and complete the first login
  2. Run /connect again to add additional accounts
  3. The plugin automatically rotates between accounts

Rotation Strategies

  • hybrid (default): Smart selection combining health scores, token bucket rate limiting, and LRU. Accounts recover health passively over time.
  • round-robin: Cycles through accounts on each request.
  • sequential: Uses one account until rate limited, then switches.

Hybrid Strategy Details

The hybrid strategy uses a weighted scoring algorithm:

  • Health Score (0-100): Tracks account wellness. Success rewards (+1), rate limits penalize (-10), failures penalize more (-20). Accounts passively recover +2 points/hour when rested.
  • Token Bucket: Client-side rate limiting (50 tokens max, regenerates 6/minute) to prevent hitting server 429s.
  • LRU Freshness: Prefers accounts that haven't been used recently.

Score formula:

Score = (healthScore × 2) + ((tokens / maxTokens) × 100 × 5) + (min(secondsSinceUsed, 3600) × 0.1)

Maximum possible component values (total max ≈ 1060 points):

| Component | Max Points | Influence | | --------- | ---------- | --------- | | Health score | 200 pts | ~19% | | Token balance | 500 pts | ~47% | | Freshness (LRU) | 360 pts | ~34% |

Accounts with a health score below min_usable (default: 50) or with an exhausted token bucket are excluded from selection.

Enable pid_offset_enabled: true when running multiple parallel sessions (e.g., oh-my-opencode) to distribute load across accounts.

Customising Health Score

{
  "health_score": {
    "initial": 70,
    "success_reward": 1,
    "rate_limit_penalty": -10,
    "failure_penalty": -20,
    "recovery_rate_per_hour": 2,
    "min_usable": 50
  }
}

Customising Token Bucket

{
  "token_bucket": {
    "max_tokens": 50,
    "regeneration_rate_per_minute": 6
  }
}

How It Works

This plugin bridges OpenCode's Responses API format with Qwen's Chat Completions API:

OpenCode → [Responses API] → Plugin → [Chat Completions] → Qwen
                                ↓
OpenCode ← [Responses API] ← Plugin ← [Chat Completions] ← Qwen

Request Transformation

| Responses API | Chat Completions API | | ------------- | -------------------- | | input | messages | | input_text | text content type | | input_image | image_url content type | | instructions | System message | | max_output_tokens | max_tokens | | text.format | response_format |

Response Transformation (Streaming)

Converts SSE events from Chat Completions to Responses API format:

  • response.created
  • response.output_item.added
  • response.content_part.added
  • response.output_text.delta
  • response.completed

Storage Locations

| Data | Linux / macOS | Windows | | ---- | ------------- | ------- | | User config | ~/.config/opencode/qwen.json | %APPDATA%\opencode\qwen.json | | Project config | .opencode/qwen.json | .opencode/qwen.json | | Account tokens | ~/.config/opencode/qwen-auth-accounts.json | %APPDATA%\opencode\qwen-auth-accounts.json | | Tracker state | ~/.config/opencode/qwen-auth-tracker-state.json | %APPDATA%\opencode\qwen-auth-tracker-state.json |

XDG_CONFIG_HOME is respected on Linux/macOS.

Security Note: All token and state files are stored with restricted permissions (0600). Ensure appropriate filesystem security.

Troubleshooting

Authentication Issues

"invalid_grant" error

  • Your refresh token has expired or been revoked. The account is automatically excluded from rotation. Run /connect to re-authenticate.

Device code expired

  • Complete the browser login within 5 minutes of starting /connect.

Rate Limiting

Frequent 429 errors

  • Add more accounts with /connect.
  • Increase max_rate_limit_wait_seconds in config.
  • The hybrid strategy's token bucket provides client-side protection before hitting server limits.

Debug Logging

Set QWEN_DEBUG=1 to enable verbose debug output to stderr (and optionally a log file).

Reset Plugin State

To start fresh, delete the accounts and tracker state files:

rm ~/.config/opencode/qwen-auth-accounts.json
rm ~/.config/opencode/qwen-auth-tracker-state.json

Development

This project uses Bun for development.

Prerequisites

  • Bun 1.0+
  • Node.js 20+ (for npm compatibility)

Getting Started

# Install dependencies
bun install

# Build
bun run build

# Run tests (135 tests)
bun test

# Run tests in watch mode
bun test --watch

# Run with coverage
bun test --coverage

# Lint
bun run lint

# Auto-fix lint issues
bun run lint:fix

# Type-check
bun run typecheck

# Run e2e test (requires authenticated Qwen account)
bun run test:e2e

# Link for local testing
bun link

Using npm

npm install
npm run build
npm test

Known Limitations

  • Audio input (input_audio) is not supported by Qwen and is converted to placeholder text.

License

MIT License. See LICENSE for details.

Intended Use

  • Personal / internal development only
  • Respect internal quotas and data handling policies
  • Not for production services or bypassing intended limits

Warning

By using this plugin, you acknowledge:

  • Terms of Service risk — This approach may violate ToS of AI model providers
  • Account risk — Providers may suspend or ban accounts
  • No guarantees — APIs may change without notice
  • Assumption of risk — You assume all legal, financial, and technical risks

Disclaimer

  • Not affiliated with QWEN and Alibaba. This is an independent open-source project.
  • "QWEN" and "Alibaba" are trademarks of Alibaba company.