-
-
Save rajivmehtaflex/17426d75d30653313573685289503758 to your computer and use it in GitHub Desktop.
Here's a simple way for Claude Code users to switch from the costly Claude models to the newly released SOTA open-source/weights coding model, Qwen3-Coder, via OpenRouter using LiteLLM on your local machine.
This process is quite universal and can be easily adapted to suit your needs. Feel free to explore other models (including local ones) as well as different providers and coding agents.
I'm sharing what works for me. This guide is set up so you can just copy and paste the commands into your terminal.
1. Clone the official LiteLLM repo:
git clone https://github.com/BerriAI/litellm.git
cd litellm2. Create an .env file with your OpenRouter API key (make sure to insert your own API key!):
cat <<\EOF >.env
LITELLM_MASTER_KEY = "sk-1234"
# OpenRouter
OPENROUTER_API_KEY = "sk-or-v1-…" # 🚩
EOF3. Create a config.yaml file that replaces Anthropic models with Qwen3-Coder (with all the recommended parameters):
cat <<\EOF >config.yaml
model_list:
- model_name: "anthropic/*"
litellm_params:
model: "openrouter/qwen/qwen3-coder" # Qwen/Qwen3-Coder-480B-A35B-Instruct
max_tokens: 65536
repetition_penalty: 1.05
temperature: 0.7
top_k: 20
top_p: 0.8
EOF4. Create a docker-compose.yml file that loads config.yaml (it's easier to just create a finished one with all the required changes than to edit the original file):
cat <<\EOF >docker-compose.yml
services:
litellm:
build:
context: .
args:
target: runtime
############################################################################
command:
- "--config=/app/config.yaml"
container_name: litellm
hostname: litellm
image: ghcr.io/berriai/litellm:main-stable
restart: unless-stopped
volumes:
- ./config.yaml:/app/config.yaml
############################################################################
ports:
- "4000:4000" # Map the container port to the host, change the host port if necessary
environment:
DATABASE_URL: "postgresql://llmproxy:dbpassword9090@db:5432/litellm"
STORE_MODEL_IN_DB: "True" # allows adding models to proxy via UI
env_file:
- .env # Load local .env file
depends_on:
- db # Indicates that this service depends on the 'db' service, ensuring 'db' starts first
healthcheck: # Defines the health check configuration for the container
test: [ "CMD-SHELL", "wget --no-verbose --tries=1 http://localhost:4000/health/liveliness || exit 1" ] # Command to execute for health check
interval: 30s # Perform health check every 30 seconds
timeout: 10s # Health check command times out after 10 seconds
retries: 3 # Retry up to 3 times if health check fails
start_period: 40s # Wait 40 seconds after container start before beginning health checks
db:
image: postgres:16
restart: always
container_name: litellm_db
environment:
POSTGRES_DB: litellm
POSTGRES_USER: llmproxy
POSTGRES_PASSWORD: dbpassword9090
ports:
- "5432:5432"
volumes:
- postgres_data:/var/lib/postgresql/data # Persists Postgres data across container restarts
healthcheck:
test: ["CMD-SHELL", "pg_isready -d litellm -U llmproxy"]
interval: 1s
timeout: 5s
retries: 10
volumes:
postgres_data:
name: litellm_postgres_data # Named volume for Postgres data persistence
EOF5. Build and run LiteLLM (this is important, as some required fixes are not yet in the published image as of 2025-07-23):
docker compose up -d --build6. Export environment variables that make Claude Code use Qwen3-Coder via LiteLLM (remember to execute this before starting Claude Code or include it in your shell profile (.zshrc, .bashrc, etc.) for persistence):
export ANTHROPIC_AUTH_TOKEN=sk-1234
export ANTHROPIC_BASE_URL=http://localhost:4000
export ANTHROPIC_MODEL=openrouter/qwen/qwen3-coder
export ANTHROPIC_SMALL_FAST_MODEL=openrouter/qwen/qwen3-coder
export CLAUDE_CODE_DISABLE_NONESSENTIAL_TRAFFIC=1 # Optional: Disables telemetry, error reporting, and auto-updates7. Start Claude Code and it'll use Qwen3-Coder via OpenRouter instead of the expensive Claude models (you can check with the /model command that it's using a custom model):
claude8. Optional: Add an alias to your shell profile (.zshrc, .bashrc, etc.) to make it easier to use (e.g. qlaude for "Claude with Qwen"):
alias qlaude='ANTHROPIC_AUTH_TOKEN=sk-1234 ANTHROPIC_BASE_URL=http://localhost:4000 ANTHROPIC_MODEL=openrouter/qwen/qwen3-coder ANTHROPIC_SMALL_FAST_MODEL=openrouter/qwen/qwen3-coder claude'Have fun and happy coding!
PS: There are other ways to do this using dedicated Claude Code proxies, of which there are quite a few on GitHub. Before implementing this with LiteLLM, I reviewed some of them, but they all had issues, such as not handling the recommended inference parameters. I prefer using established projects with a solid track record and a large user base, which is why I chose LiteLLM. Open Source offers many options, so feel free to explore other projects and find what works best for you.
Pyodide, PyScript, and Wasmtime all use WebAssembly, but they solve different problems:
- Pyodide is CPython compiled to WebAssembly for a browser or JavaScript host. It lets Python run in a browser, subject to browser/WebAssembly constraints.
- PyScript is a browser application framework that loads and manages Python runtimes such as Pyodide and MicroPython. It adds HTML integration, configuration, package loading, DOM helpers, JavaScript interoperability, and worker support.
- Wasmtime is a standalone and embeddable WebAssembly runtime for servers, desktop applications, edge systems, and other host environments. It runs
.wasmmodules/components with explicit host capabilities through WASI or application-defined imports.
A useful mental model is:
Browser application Server / edge / desktop application
------------------- -------------------------------
PyScript Wasmtime
| |
v v
Pyodide / MicroPython .wasm module or component
| |
v v
Browser APIs, DOM, fetch WASI or host-provided capabilities
They are complementary, not interchangeable. Pyodide does not become a server runtime merely because it is compiled to WebAssembly, and Wasmtime does not provide a browser DOM.
PyScript
├── HTML integration
├── Python script loading
├── Configuration
├── Package installation
├── Worker support
└── Python <-> JavaScript bridge
|
v
Pyodide
├── CPython compiled to WebAssembly
├── Python standard library (with constraints)
├── NumPy/pandas/scikit-learn and other compatible packages
└── micropip package installation
<script type="py"> selects a CPython/Pyodide-style runtime. <script type="mpy"> selects MicroPython. Use Pyodide when CPython compatibility and scientific packages matter; use MicroPython when a smaller runtime and faster startup are more important.
<!doctype html>
<html>
<head>
<meta charset="utf-8">
<link rel="stylesheet" href="https://pyscript.net/releases/2026.6.1/core.css">
<script type="module" src="https://pyscript.net/releases/2026.6.1/core.js"></script>
</head>
<body>
<h1>PyScript + Pyodide</h1>
<button id="run-button">Run Python</button>
<div id="output"></div>
<script type="py" src="./main.py" config="./pyscript.json"></script>
</body>
</html>{
"packages": ["numpy", "pandas"]
}import numpy as np
from pyscript import document, when
output = document.querySelector("#output")
@when("click", "#run-button")
def run_python(event):
values = np.array([1, 2, 3, 4, 5])
output.innerText = str((values * 2).tolist())The startup sequence is:
Browser loads PyScript core.js
|
v
PyScript reads configuration
|
v
PyScript loads Pyodide
|
v
Pyodide/micropip loads packages
|
v
PyScript runs the Python script
|
v
Python interacts with the DOM and browser APIs
PyScript delegates package installation to Pyodide and micropip. micropip can install pure-Python wheels and Pyodide/Emscripten-compatible WebAssembly wheels. A package being available on PyPI does not by itself mean that it can run in a browser.
In PyScript configuration:
{
"packages": [
"numpy",
"scikit-learn"
]
}The lower-level Pyodide operation is conceptually:
import micropip
await micropip.install(["numpy", "scikit-learn"])The PyPI package name and import name can differ:
Package name: scikit-learn
Import name: sklearn
The reliable test is to install and import the package inside the exact target Pyodide version, then exercise the features the application needs:
const pyodide = await loadPyodide();
await pyodide.loadPackage("micropip");
const micropip = pyodide.pyimport("micropip");
await micropip.install("PACKAGE_NAME");
await pyodide.runPythonAsync(`
import PACKAGE_IMPORT_NAME
print("Package imported successfully")
`);Also test model loading, prediction, serialization, file handling, repeated calls, failure behavior, and performance. Import success alone is not sufficient.
For local validation, use a Pyodide-aware environment such as pyodide venv and verify the interpreter:
python -m pip install pyodide-build
pyodide venv .venv-pyodide
source .venv-pyodide/bin/activate
python -m pip install PACKAGE_NAME
python -c "import sys; print(sys.platform)"
python -c "import PACKAGE_IMPORT_NAME; print('import succeeded')"
python -m pip install pytest
python -m pytest tests/The platform should identify an Emscripten/WebAssembly runtime rather than the host operating system.
| Package type | Typical action |
|---|---|
Pure Python (py3-none-any) |
Usually install directly, then test |
| C/C++ extension | Build a Pyodide/Emscripten wheel |
| Cython extension | Usually build with pyodide build |
| Rust/PyO3 extension | Cross-compile for the target WebAssembly ABI |
| Native system dependency | Port, replace, or move behind a service |
| Threads/processes/sockets | Patch, move to JavaScript/WASI, or redesign |
| CUDA/native GPU driver | Not directly usable in browser Pyodide |
A compatible WebAssembly wheel may use a tag similar to:
package-1.0.0-cp314-cp314-pyemscripten_2026_0_wasm32.whl
A wheel containing only macOS, Linux, or Windows native tags is not directly usable by Pyodide.
The browser is the operating system boundary. Common problem areas include:
multiprocessing,threading, and sockets- POSIX process APIs,
fork(), andsubprocess ctypesand native system libraries- unrestricted filesystem access
- CUDA or native GPU-driver APIs
- desktop UI libraries such as Tkinter
- long-running CPU work on the browser main thread
- OpenSSL-dependent functionality and some
ssluse - browser networking restrictions, including CORS and browser-controlled certificates, proxies, and timeouts
For browser networking, use browser fetch, PyScript helpers, or a controlled JavaScript bridge. For heavy work, use a Web Worker and consider cross-origin isolation where the required feature needs it.
| Feature | Pyodide alone | PyScript + Pyodide |
|---|---|---|
| CPython in WebAssembly | Yes | Yes |
| Package loading | Manual APIs | Declarative configuration plus APIs |
| HTML integration | Manual | Built in |
| DOM access | Pyodide FFI | PyScript helpers and FFI |
| Event handlers | Manual JavaScript | Python decorators such as @when |
| JavaScript modules | Manual registration | js_modules configuration |
| Workers | Manual setup | PyScript worker facilities |
| MicroPython support | No | Yes, through type="mpy" |
Use PyScript for a simpler Python-in-HTML application model. Use Pyodide directly for precise initialization, custom worker orchestration, custom JavaScript/Wasm integration, or fine-grained performance control.
Wasmtime is a different layer: it is the host runtime that loads and executes WebAssembly modules/components outside the browser. The Wasmtime project describes it as a fast, secure, standards-compliant, standalone runtime, and it can also be embedded as a library.
| Wasmtime capability | Plain-English meaning |
|---|---|
Runs .wasm modules/components |
Executes WebAssembly programs from the CLI or another application |
| Sandboxed execution | Guest code does not automatically receive arbitrary host access |
| Explicit capabilities | The host chooses which files, clocks, environment values, or network interfaces are exposed |
| WASI support | Provides standardized interfaces for selected host capabilities |
| Embedding | Rust, C/C++, Python, .NET, Go, Ruby, and other bindings can host Wasm |
| Resource controls | The embedder can configure limits such as memory and CPU-related behavior |
| Multiple execution strategies | Cranelift for optimized compilation, Winch for fast startup, and Pulley as a portable interpreter in supported configurations |
Sandboxing is not the same as “no access.” A Wasm program can only use capabilities that the host grants, but a production host must still grant the minimum required capabilities and configure limits deliberately.
Rust / C / C++ / componentized Python / other source
|
v
Compile or componentize to .wasm
|
v
Wasmtime loads it
|
v
Cranelift / Winch / Pulley executes it
|
v
Wasm code uses only granted host capabilities
Wasmtime is useful for plugin systems, multi-tenant or untrusted extensions, server-side execution, edge workloads, and running the same Wasm artifact across Linux, macOS, Windows, and other supported hosts.
The workload determines the command and interface:
| Workload | Typical Wasm interface | Wasmtime mode | Lifecycle |
|---|---|---|---|
| HTTP API/server | wasi:http/proxy component |
wasmtime serve app.wasm |
Long-running request loop |
| Batch job/CLI | WASI CLI interfaces | wasmtime run job.wasm |
Starts, does work, exits |
| Cronjob | WASI CLI interfaces | OS scheduler invokes wasmtime run job.wasm |
No scheduler built into Wasmtime |
| Background worker | CLI/sockets or an application-defined interface | wasmtime run worker.wasm under a service manager |
Long-running only because the supervisor restarts/manages it |
wasmtime serve is not a generic wrapper for every .wasm file. The artifact must be a component implementing the HTTP handler world expected by the CLI. A plain command-style Wasm module should use wasmtime run instead.
WASI capability examples include:
wasi:filesystemfor explicitly permitted directorieswasi:clifor arguments and environment values- clocks and timers
- sockets or HTTP interfaces where supported by the chosen WASI/component APIs
The exact APIs and flags depend on the Wasmtime release and whether the artifact is a core module or a component, so pin and test versions in deployment.
There are two different meanings of “Python with Wasmtime.”
This is useful when a Python application wants to load a Wasm plugin or execute a Wasm function:
python -m pip install wasmtimehello.wat:
(module
(func $hello (import "" "hello"))
(func (export "run") (call $hello))
)main.py:
from wasmtime import Engine, Store, Module, Func, FuncType, Instance
engine = Engine()
module = Module.from_file(engine, "hello.wat")
store = Store(engine)
def hello():
print("Hello from the Python host!")
hello_func = Func(store, FuncType([], []), hello)
instance = Instance(store, module, [hello_func])
run = instance.exports(store)["run"]
run(store)Run it:
python main.py
# Hello from the Python host!The host provides the imported hello function; Python calls the exported run function. This is embedding Wasmtime, not converting the Python file into a Wasm application.
A normal .py file cannot run directly in Wasmtime. It needs a Python interpreter compiled for WebAssembly.
componentize-py packages a Python application together with a CPython-based Wasm runtime and a WIT-defined component interface. A simplified flow is:
python -m pip install componentize-py
# Install the Wasmtime CLI separately using the official instructions.app.py:
def hello():
print("Hello from Python inside Wasmtime!")hello.wit:
package example:hello;
world hello {
export run: func();
}Componentize and run:
componentize-py --wit-path hello.wit --world hello componentize app -o app.wasm
wasmtime run app.wasmThis is the better direction when the deliverable should be a self-contained Wasm component with typed interfaces. componentize-py and the Wasmtime Python/component APIs are version-sensitive; pin compatible versions and use the current project examples rather than assuming every historical command remains unchanged.
For quick experiments, a CPython WASI build can be run with the script directory explicitly mounted:
wasmtime run \
--dir . \
python.wasm \
-- myscript.py--dir . is a capability grant: it makes the current directory visible to the sandboxed interpreter. Without a directory mapping, the guest should not be assumed to see the host filesystem. This approach keeps python.wasm and the script separate; it is less convenient than a self-contained component for production packaging.
| Approach | Artifact | Best fit |
|---|---|---|
componentize-py |
One Wasm component containing the Python runtime and app | Typed interfaces and deployable Wasm components |
| CPython WASI build | python.wasm plus a mounted .py file |
Experiments and quick scripting |
| Wasmtime Python binding | Native Python host loading a Wasm guest | Python application/plugin architecture |
Python-in-Wasm is substantially larger than a small native Wasm guest because the interpreter and parts of the standard library are included. Measure startup time, memory, package availability, and cold-start behavior before choosing it for high-scale services.
wasmtime run /opt/jobs/job.wasmGrant only the required capabilities, for example a narrowly scoped data directory. Use the operating system’s scheduler for cron-like execution:
OS cron / systemd timer / external scheduler
|
v
wasmtime run job.wasm
wasmtime serve --addr=0.0.0.0:8080 /opt/myapp/app.wasmUse a service manager or container supervisor for restart policy, logs, resource limits, health checks, and graceful shutdown. The component must implement the HTTP interface required by serve.
A systemd-style service is conceptually:
[Unit]
Description=Wasmtime HTTP application
After=network.target
[Service]
ExecStart=/usr/local/bin/wasmtime serve --addr=0.0.0.0:8080 /opt/myapp/app.wasm
Restart=always
RestartSec=5
User=www-data
WorkingDirectory=/opt/myapp
[Install]
WantedBy=multi-user.targetFor containers, copy a pinned Wasmtime binary and the Wasm artifact into a minimal image. Do not install an unpinned development build in production, and do not grant broad host directories or network access by default.
- Pin the Wasmtime and component/tool versions.
- Distinguish core Wasm modules from Wasm components.
- Use
wasmtime runfor command-style programs andwasmtime serveonly for compatible HTTP components. - Grant the minimum filesystem, environment, clock, and network capabilities.
- Configure memory/CPU/time limits at the Wasmtime and OS/container layers.
- Run as a non-root user.
- Add structured logs, metrics, health checks, and restart policy.
- Test cold start, concurrency, cancellation, malformed input, and failure recovery.
- Treat Wasm sandboxing as defense in depth; audit the host capabilities and all imported functions.
For a browser application, a clean architecture is:
PyScript/Pyodide
|
| Python preprocessing and application workflow
v
Controlled JavaScript bridge
|
v
LiteRT.js
|
+-- WebGPU
+-- WebAssembly/XNNPACK
Expose narrow bridge functions such as:
initialize_model()
run_model(input)
get_model_metadata()
Keep responsibilities separate:
PyScript/Pyodide:
Python workflow, preprocessing, and browser-side data handling
LiteRT.js:
JavaScript-side .tflite inference and browser backend selection
JavaScript bridge:
Controlled Python <-> LiteRT.js interface
Wasmtime (optional server/edge tier):
Server-side Wasm services, plugins, or preprocessing/inference components
Wasmtime is not a drop-in replacement for LiteRT.js. LiteRT.js is designed for JavaScript/browser integration and browser acceleration backends. If inference moves to a Wasmtime service, the model runtime and its native/Wasm compatibility must be evaluated separately; a .tflite file alone does not make an inference stack Wasmtime-compatible.
For heavier browser workloads, use workers:
Main browser thread
├── User interface
└── PyScript controller
|
v
Pyodide Worker
├── Python preprocessing
└── Python data workflow
|
v
LiteRT.js Worker
├── .tflite model
└── WebGPU/WASM inference
For a hybrid product, the browser can run lightweight preprocessing and local inference while a Wasmtime-backed service handles heavier or sensitive workloads. Use an explicit API boundary rather than trying to share browser-only modules or unrestricted Python capabilities with the server runtime.
| Requirement | Best starting point | Why |
|---|---|---|
| Python in HTML and DOM events | PyScript + Pyodide | Browser integration and declarative configuration |
| Direct browser Python control | Pyodide | Precise initialization and custom JS/worker orchestration |
| Small embedded Python-like runtime | PyScript + MicroPython | Smaller footprint, reduced CPython compatibility |
| Run a portable Wasm CLI/job on a server | Wasmtime | wasmtime run, WASI capabilities, host portability |
| Expose a Wasm HTTP component | Wasmtime | wasmtime serve plus wasi:http component interface |
| Python host loading sandboxed plugins | Wasmtime Python binding | Python remains the host; Wasm is the guest |
| Package a Python application as a Wasm component | componentize-py + Wasmtime |
CPython-in-Wasm with a WIT-defined interface |
Browser-side .tflite inference |
LiteRT.js | JavaScript/browser backend integration |
- It provides a standalone/embeddable host runtime for Wasm outside the browser.
- It makes server, edge, plugin, batch, and scheduled-job deployment practical.
- It provides explicit WASI/component interfaces instead of browser DOM APIs.
- It supports a
runstyle for one-shot programs and aservestyle for compatible HTTP components. - It can host Wasm guests from Python, Rust, C/C++, and other host languages.
- A PyPI package still needs a compatible target build and runtime behavior.
- A browser cannot gain arbitrary OS access merely because code is compiled to WebAssembly.
- Pyodide’s browser constraints do not disappear when Pyodide is embedded in another application.
- LiteRT.js browser APIs do not automatically become Wasmtime APIs.
- A Wasm sandbox is not a complete security policy; host-granted capabilities and resource limits still matter.
- PyScript documentation: https://docs.pyscript.net/2026.6.1/
- Pyodide usage: https://pyodide.org/en/stable/usage/index.html
- Pyodide package loading: https://pyodide.org/en/stable/usage/loading-packages.html
- Pyodide WebAssembly/Python constraints: https://pyodide.org/en/stable/usage/wasm-constraints.html
- Pyodide build documentation: https://pyodide-build.readthedocs.io/en/latest/
- Wasmtime repository and README: https://github.com/bytecodealliance/wasmtime
- Wasmtime CLI guide: https://docs.wasmtime.dev/cli.html
- Wasmtime embedding/API guide: https://docs.wasmtime.dev/lang.html
- Wasmtime security: https://docs.wasmtime.dev/security.html
- WASI: https://wasi.dev/
componentize-py: https://github.com/bytecodealliance/componentize-py- LiteRT.js: https://ai.google.dev/edge/litert
| { | |
| "env": { | |
| "QWEN_CUSTOM_API_KEY_GEMINI_HTTPS_GENERATIVELANGUAGE_GOOGLEAPIS_COM": "<KEY>", | |
| "QWEN_CUSTOM_API_KEY_ANTHROPIC_HTTPS_API_DEEPSEEK_COM_ANTHROPIC": "<KEY>", | |
| "QWEN_CUSTOM_API_KEY_OPENAI_HTTPS_OPENROUTER_AI_API_V1": "<KEY>" | |
| }, | |
| "modelProviders": { | |
| "gemini": [ | |
| { | |
| "id": "gemma-4-31b-it", | |
| "name": "gemma-4-31b-it", | |
| "baseUrl": "https://generativelanguage.googleapis.com", | |
| "envKey": "QWEN_CUSTOM_API_KEY_GEMINI_HTTPS_GENERATIVELANGUAGE_GOOGLEAPIS_COM", | |
| "generationConfig": { | |
| "modalities": { | |
| "image": true, | |
| "video": true, | |
| "audio": true | |
| }, | |
| "extra_body": { | |
| "enable_thinking": true | |
| } | |
| } | |
| }, | |
| { | |
| "id": "gemini-3-flash-preview", | |
| "name": "gemini-3-flash-preview", | |
| "baseUrl": "https://generativelanguage.googleapis.com", | |
| "envKey": "QWEN_CUSTOM_API_KEY_GEMINI_HTTPS_GENERATIVELANGUAGE_GOOGLEAPIS_COM", | |
| "generationConfig": { | |
| "modalities": { | |
| "image": true, | |
| "video": true, | |
| "audio": true | |
| }, | |
| "extra_body": { | |
| "enable_thinking": true | |
| } | |
| } | |
| }, | |
| { | |
| "id": "gemini-3.1-flash-lite-preview", | |
| "name": "gemini-3.1-flash-lite-preview", | |
| "baseUrl": "https://generativelanguage.googleapis.com", | |
| "envKey": "QWEN_CUSTOM_API_KEY_GEMINI_HTTPS_GENERATIVELANGUAGE_GOOGLEAPIS_COM", | |
| "generationConfig": { | |
| "modalities": { | |
| "image": true, | |
| "video": true, | |
| "audio": true | |
| }, | |
| "extra_body": { | |
| "enable_thinking": true | |
| } | |
| } | |
| } | |
| ], | |
| "anthropic": [ | |
| { | |
| "id": "deepseek-v4-flash", | |
| "name": "deepseek-v4-flash", | |
| "baseUrl": "https://api.deepseek.com/anthropic", | |
| "envKey": "QWEN_CUSTOM_API_KEY_ANTHROPIC_HTTPS_API_DEEPSEEK_COM_ANTHROPIC", | |
| "generationConfig": { | |
| "extra_body": { | |
| "enable_thinking": true | |
| } | |
| } | |
| } | |
| ], | |
| "openai": [ | |
| { | |
| "id": "nvidia/nemotron-3-super-120b-a12b", | |
| "name": "nvidia/nemotron-3-super-120b-a12b", | |
| "baseUrl": "https://openrouter.ai/api/v1", | |
| "envKey": "QWEN_CUSTOM_API_KEY_OPENAI_HTTPS_OPENROUTER_AI_API_V1" | |
| }, | |
| { | |
| "id": "ibm-granite/granite-4.1-8b", | |
| "name": "ibm-granite/granite-4.1-8b", | |
| "baseUrl": "https://openrouter.ai/api/v1", | |
| "envKey": "QWEN_CUSTOM_API_KEY_OPENAI_HTTPS_OPENROUTER_AI_API_V1" | |
| }, | |
| { | |
| "id": "openrouter/owl-alpha", | |
| "name": "openrouter/owl-alpha", | |
| "baseUrl": "https://openrouter.ai/api/v1", | |
| "envKey": "QWEN_CUSTOM_API_KEY_OPENAI_HTTPS_OPENROUTER_AI_API_V1" | |
| }, | |
| { | |
| "id": "qwen/qwen3.6-flash", | |
| "name": "qwen/qwen3.6-flash", | |
| "baseUrl": "https://openrouter.ai/api/v1", | |
| "envKey": "QWEN_CUSTOM_API_KEY_OPENAI_HTTPS_OPENROUTER_AI_API_V1" | |
| }, | |
| { | |
| "id": "qwen/qwen3.6-35b-a3b", | |
| "name": "qwen/qwen3.6-35b-a3b", | |
| "baseUrl": "https://openrouter.ai/api/v1", | |
| "envKey": "QWEN_CUSTOM_API_KEY_OPENAI_HTTPS_OPENROUTER_AI_API_V1" | |
| } | |
| ] | |
| }, | |
| "security": { | |
| "auth": { | |
| "selectedType": "gemini" | |
| } | |
| }, | |
| "model": { | |
| "name": "gemma-4-31b-it" | |
| } | |
| } |
-
npx skills add https://github.com/anthropics/skills --agent qwen-code --skill skill-creator
-
antigravity, claude-code, openclaw, cline, codex, gemini-cli, github-copilot, mistral-vibe, mux, opencode, pi,qwen-code