No description
Find a file
2026-05-19 10:53:59 +02:00
crates clean up the SSE 2026-05-19 10:53:59 +02:00
Cargo.lock Round 4: close all subsystem gaps — tools, hooks, skills activation, sessions resume, followup 2026-05-18 13:00:56 +02:00
Cargo.toml Round 4: close all subsystem gaps — tools, hooks, skills activation, sessions resume, followup 2026-05-18 13:00:56 +02:00
CONVERSION_PLAN.md Round 4: close all subsystem gaps — tools, hooks, skills activation, sessions resume, followup 2026-05-18 13:00:56 +02:00
PARITY.md Round 4: close all subsystem gaps — tools, hooks, skills activation, sessions resume, followup 2026-05-18 13:00:56 +02:00
qwen_adversarial_test.txt Fix path traversal check: block only '..', not absolute paths 2026-05-16 09:33:23 +02:00
qwen_final_verify.txt Fix path traversal check: block only '..', not absolute paths 2026-05-16 09:33:23 +02:00
README.md Round 4: close all subsystem gaps — tools, hooks, skills activation, sessions resume, followup 2026-05-18 13:00:56 +02:00

Qwen-Code (Rust)

AI coding agent ported from Qwen-Code TypeScript to Rust.

Quick Start

# Build
cargo build --release

# Interactive TUI (needs real terminal)
./target/release/qwen

# One-shot prompt
./target/release/qwen -p "explain rust traits"

# JSON output
./target/release/qwen -p "list 3 cli tips" --json

# HTTP server (with auth)
QWEN_API_KEY=mykey ./target/release/qwen serve --port 8080
curl -H "Authorization: Bearer mykey" -X POST http://localhost:8080/chat \
  -H "Content-Type: application/json" \
  -d '{"message":"write hello.py"}'

# Telegram bot
TELEGRAM_BOT_TOKEN=xxx ./target/release/qwen telegram

Modes

Command Description
qwen TUI (terminal UI)
qwen -p "text" One-shot prompt
qwen -p "text" --output-format json|stream-json|text Non-interactive output
qwen -p "/help" Slash command (handled locally)
qwen auth login|status|logout Qwen OAuth device flow
qwen serve HTTP API server (rate-limited)
qwen telegram Telegram bot

Features

  • LLM Providers: OpenAI-compatible (DashScope, Ollama, OpenRouter), Anthropic, Gemini (OpenAI-compat), and Qwen OAuth (device flow) with faithful auth-type resolution
  • System prompt: faithful port of qwen-code's full prompt (env-conditional sandbox/git sections, model-specific tool-call styles, deferred tools)
  • 18 tools: read_file, write_file, edit, run_shell_command, grep_search (ripgrep), glob, web_fetch, list_directory, todo_write, exit_plan_mode, ask_user_question, save_memory, structured_output, tool_search, task_stop, send_message, monitor, cron_create/list/delete, lsp
  • Turn model: full GeminiEventType parity (thought, tool calls, compaction, loop-detected, citations, retry, …)
  • Auto-compaction + loop detection (tool-call & content chanting)
  • LSP: stdio JSON-RPC client + per-language server manager
  • MCP: stdio client + OAuth (PKCE) + file token storage
  • Channels: Telegram, WeChat-Work, DingTalk
  • Telemetry: structured events, metrics registry, secret sanitizer, token-bucket rate limiting
  • Permissions: yolo/auto-edit/default/plan; shell read-only checker
  • Sessions / Memory / Skills / Hooks / SubAgents / Arena / Cron scheduler
  • 170 tests (126 core unit + 42 integration + 2 channel) — see CONVERSION_PLAN.md for the full TS→Rust milestone map

Security

  • HTTP server requires --api-key for authentication
  • Shell commands checked against dangerous pattern denylist
  • API keys masked in logs (first 4 + last 4 chars)
  • Path traversal blocked (".." in file paths)

Configuration

Create ~/.qwen/settings.json (Qwen-Code compatible):

{
  "modelProviders": {
    "openai": [{
      "id": "qwen3.5-plus",
      "name": "Qwen 3.5 Plus",
      "baseUrl": "https://coding-intl.dashscope.aliyuncs.com/v1",
      "envKey": "MY_API_KEY"
    }]
  },
  "model": { "name": "qwen3.5-plus" },
  "security": { "auth": { "selectedType": "openai" } },
  "env": { "MY_API_KEY": "sk-..." }
}

Architecture

qwen-core/     Core engine (LLM, tools, config, agent, memory, etc.)
qwen-tui/      Terminal UI (ratatui + crossterm)
qwen-telegram/ Telegram bot (teloxide)
qwen-cli/      CLI binary (clap + axum)