Doramagic Project Pack Β· Human Manual
qwen-code
Related topics: System Architecture, Authentication and Model Providers
Project Overview
Related topics: System Architecture, Authentication and Model Providers
Continue reading this section for the full explanation and source context.
Continue reading this section for the full explanation and source context.
Continue reading this section for the full explanation and source context.
Continue reading this section for the full explanation and source context.
Related Pages
Related topics: System Architecture, Authentication and Model Providers
Project Overview
Qwen Code is an AI-powered coding assistant developed by the Qwen team. It provides an intelligent CLI (Command-Line Interface) tool that leverages large language models to assist developers with coding tasks, code review, refactoring, and automated programming workflows.
What is Qwen Code
Qwen Code is a multi-agent coding system that combines AI language model capabilities with traditional development tools. It enables developers to:
- Execute coding tasks through natural language commands
- Manage complex development workflows with multiple sub-agents
- Access external tools via MCP (Model Context Protocol) servers
- Compare AI models using an Arena feature for side-by-side evaluation
Sources: README.md:1-50
Architecture Overview
The project follows a monorepo structure with three main packages:
graph TD
subgraph "Qwen Code Repository"
CLI["packages/cli<br/>CLI Application"]
CORE["packages/core<br/>Core Engine"]
WEBUI["packages/webui<br/>Web UI Components"]
end
CLI --> CORE
CLI --> WEBUIPackage Breakdown
| Package | Purpose | Technology |
|---|---|---|
packages/cli | Command-line interface and terminal UI | TypeScript, React-like rendering (blessed) |
packages/core | Core AI logic, memory management, agent planning | TypeScript |
packages/webui | Reusable web components for React applications | React, Tailwind CSS |
Sources: README.md:30-45 Sources: packages/cli/package.json Sources: packages/core/package.json
Core Components
CLI Application (`packages/cli`)
The CLI package provides the terminal-based user interface for interacting with Qwen Code. It includes:
- Interactive terminal UI built with
blessedandreact-blessed - Arena functionality for comparing multiple AI agents side-by-side
- Background task management for long-running operations
- Sub-agent creation and management system
- MCP server integration for external tool access
graph TD
UI["UI Layer<br/>React-Blessed Components"]
CB["Context & State<br/>Management"]
CORE["Core Engine<br/>packages/core"]
IO["Non-Interactive<br/>CLI Mode"]
UI --> CB
CB --> CORE
IO --> CORESources: packages/cli/src/ui/components/arena/ArenaSelectDialog.tsx:1-50 Sources: packages/cli/src/ui/components/background-view/BackgroundTasksDialog.tsx:1-30
Core Engine (`packages/core`)
The core package contains the fundamental AI capabilities:
- Memory Management - Handles persistent memory with topic-based organization
- Agent Planning - Extraction and planning agents for task decomposition
- Managed Memory System - Durable storage for project-specific information
#### Memory System Architecture
graph TD
Input["User Input / Conversation"]
TopicScan["Topic Scanner"]
MemoryBlock["Memory Block<br/>Builder"]
PromptGen["Task Prompt<br/>Generator"]
Output["AI Context"]
Input --> TopicScan
TopicScan --> MemoryBlock
MemoryBlock --> PromptGen
PromptGen --> Output
subgraph "Managed Memory"
TopicDocs["Topic Documents<br/>scanAutoMemoryTopicDocuments"]
end
TopicScan --> TopicDocsSources: packages/core/src/memory/extractionAgentPlanner.ts:1-60 Sources: packages/core/src/memory/prompt.ts:1-50
Web UI Components (`packages/webui`)
The webui package provides a React component library for building web-based interfaces:
#### Available Component Categories
| Category | Components |
|---|---|
| Icons | FileIcon, FolderIcon, CheckIcon, ErrorIcon, WarningIcon, SendIcon, etc. |
| Layout | Container, Header, Footer, Sidebar, Main |
| Messages | Message, MessageList, MessageInput, WaitingMessage, InterruptedMessage |
| UI Primitives | Button, Input, Tooltip, Select, etc. |
#### ToolCall Components
Specialized components for displaying tool interactions:
// ToolCallCard with status indicators
<ToolCallCard icon="π">
<ToolCallRow label="SaveMemory">
<div>The user wants to refactor...</div>
</ToolCallRow>
</ToolCallCard>
Sources: packages/webui/README.md:1-80 Sources: packages/webui/src/components/toolcalls/shared/ToolCallCard.stories.tsx:1-50
Key Features
Arena Mode
The Arena feature enables side-by-side comparison of different AI agents:
- Multiple agent selection with status indicators
- Token and file count tracking
- Diff visualization with additions/deletions
- Duration and performance metrics
graph LR
Agent1["Agent A<br/>qwen3.6-plus"]
Agent2["Agent B<br///>glm-4.7"]
Arena["Arena Dialog"]
Results["Side-by-side<br/>Results"]
Agent1 --> Arena
Agent2 --> Arena
Arena --> ResultsSources: packages/cli/src/ui/components/arena/ArenaSelectDialog.tsx:20-40 Sources: packages/cli/src/ui/components/arena/ArenaStopDialog.tsx:1-30
Sub-agents System
Developers can create custom sub-agents with:
- Custom system prompts
- Tool configurations
- Model selection
- Color coding for visual distinction
- Project-level or user-level scope
Sources: packages/cli/src/ui/components/subagents/create/CreationSummary.tsx:1-50 Sources: packages/cli/src/ui/components/subagents/manage/AgentViewerStep.tsx:1-40
Extension System
Qwen Code supports extensions through:
- MCP server integration
- Version tracking
- Status monitoring
- Command registration
Sources: packages/cli/src/ui/components/extensions/steps/ExtensionDetailStep.tsx:1-40
Configuration
Model Provider Configuration
Qwen Code supports multiple AI model providers configured via JSON:
{
"modelProviders": {
"openai": [
{
"id": "qwen3.6-plus",
"name": "qwen3.6-plus (Coding Plan)",
"baseUrl": "https://coding.dashscope.aliyuncs.com/v1",
"envKey": "BAILIAN_CODING_PLAN_API_KEY"
}
]
}
}
Environment Variables
| Variable | Purpose |
|---|---|
BAILIAN_CODING_PLAN_API_KEY | API key for ModelStudio Coding Plan |
QWEN_MODEL | Default model selection |
Sources: README.md:50-80
Project Structure
qwen-code/
βββ packages/
β βββ cli/
β β βββ src/
β β β βββ ui/ # Terminal UI components
β β β β βββ components/
β β β β βββ contexts/
β β β βββ nonInteractiveCli.ts
β β βββ package.json
β βββ core/
β β βββ src/
β β β βββ memory/ # Memory management
β β βββ package.json
β βββ webui/
β βββ src/
β β βββ components/
β β βββ context/
β β βββ hooks/
β βββ package.json
βββ docs-site/ # Documentation website
βββ README.md
Technology Stack
| Layer | Technology |
|---|---|
| Runtime | Node.js |
| Language | TypeScript |
| CLI UI | blessed, react-blessed |
| Web UI | React, Tailwind CSS, Vite |
| Docs | Next.js, Nextra |
| Testing | Vitest, React Testing Library |
Installation & Usage
Quick Start
# Install globally
npm install -g qwen-code
# Configure (optional, can use defaults)
qwen config set openai.apiKey your-key
# Start Qwen Code
qwen
Development Setup
# Clone repository
git clone https://github.com/QwenLM/qwen-code.git
cd qwen-code
# Install dependencies
npm install
# Start development
npm run dev
Sources: README.md:1-60
Statistics & Performance
The CLI provides detailed performance metrics including:
- Wall Time - Total execution duration
- Agent Active Time - Time spent actively processing
- API Time - Time waiting for model responses
- Tool Time - Time executing tools
- Cache Efficiency - Token cache utilization
Sources: packages/cli/src/ui/components/StatsDisplay.tsx:1-50
Summary
Qwen Code is a comprehensive AI coding assistant that combines:
- CLI-first design for terminal-based workflows
- Modular architecture with separate core, CLI, and UI packages
- Multi-agent support via Arena and sub-agent systems
- Extensible tooling through MCP integration
- Web component library for building custom interfaces
The project is well-suited for developers who prefer command-line workflows while wanting access to powerful AI-assisted coding capabilities.
Sources: [README.md:1-50]()
System Architecture
Related topics: Core Agent Runtime, Tools System, Memory System
Continue reading this section for the full explanation and source context.
Continue reading this section for the full explanation and source context.
Continue reading this section for the full explanation and source context.
Continue reading this section for the full explanation and source context.
Related Pages
Related topics: Core Agent Runtime, Tools System, Memory System
System Architecture
Overview
Qwen Code is a multi-package monorepo designed as an AI-powered coding assistant. The system architecture follows a modular design pattern with clear separation between core logic, CLI interface, UI components, and channel integrations.
Package Structure
The repository is organized as a monorepo under the packages/ directory:
| Package | Purpose |
|---|---|
cli | Command-line interface with terminal-based UI |
core | Core functionality and business logic |
webui | Web-based user interface components |
channels | Abstraction layer for platform-specific capabilities |
Sources: packages/webui/README.md
Core Architectural Patterns
Agent Session Model
The system operates on an agent-based session model where agents perform coding tasks within isolated sessions.
graph TD
A[User Query] --> B[Session Manager]
B --> C[Agent Executor]
C --> D[Tool Registry]
D --> E[File System]
D --> F[MCP Servers]
C --> G[Token Tracker]
G --> H[Stats Aggregator]The BackgroundTasksDialog.tsx component manages agent sessions with support for:
- Session counting and tracking
- Progress reporting
- Topic metadata
- Lock-release mechanisms for session management
- Metadata write operations
Sources: packages/cli/src/ui/components/background-view/BackgroundTasksDialog.tsx
Task and Monitor System
Tasks flow through the system with monitoring capabilities:
graph LR
A[Task Created] --> B[Monitor Registry]
B --> C[Task Notification XML]
C --> D[Status: running|completed|failed|cancelled]The monitor system emits notifications via XML format:
Monitor emitted event #1.
<task-notification>
<task-id>mon_1</task-id>
<kind>monitor</kind>
<status>running</status>
<result>ready</result>
</task-notification>
Sources: packages/cli/src/nonInteractiveCli.test.ts
CLI Architecture
UI Component Hierarchy
The CLI package (packages/cli/src/ui/components/) organizes UI components by functional domain:
| Directory | Function |
|---|---|
arena/ | Arena comparison sessions and dialogs |
background-view/ | Background task management |
extensions/ | Extension management steps |
mcp/steps/ | MCP server and tool listing |
views/ | General view components |
Sources: packages/cli/src/ui/components/arena/ArenaSelectDialog.tsx
Arena System
The Arena system enables comparative evaluation of multiple agents:
graph TD
A[Arena Session] --> B[Agent Selection]
A --> C[Result Comparison]
A --> D[Diff Analysis]
B --> E{Stop Action}
E --> F[Cleanup]
E --> G[Preserve Artifacts]Arena Components:
- ArenaSelectDialog - Agent selection interface with status indicators
- ArenaStopDialog - Session termination with cleanup/preserve options
- ArenaCards - Visual comparison of agent outputs
The ArenaSelectDialog.tsx displays agent status with the following metadata:
- Status (success/error/running)
- Duration
- Token count
- File count
- Diff statistics (additions/deletions)
Sources: packages/cli/src/ui/components/arena/ArenaSelectDialog.tsx
Stop Actions:
| Action | Behavior |
|---|---|
cleanup | Remove all worktrees and session files |
preserve | Keep worktrees and session files for later inspection |
Sources: packages/cli/src/ui/components/arena/ArenaStopDialog.tsx
Stats and Performance Tracking
The StatsDisplay.tsx component aggregates performance metrics:
| Metric Category | Tracked Data |
|---|---|
| Performance | Wall time, agent active time, API time, tool time |
| Tokens | Total cached tokens, cache efficiency |
| Models | Per-model usage statistics |
The system calculates percentages for API and tool time relative to total execution time.
Sources: packages/cli/src/ui/components/StatsDisplay.tsx
MCP (Model Context Protocol) Integration
Architecture
graph TD
A[CLI] --> B[MCP Registry]
B --> C[Server List]
B --> D[Tool List]
C --> E[ServerListStep]
D --> F[ToolListStep]
E --> G[Status: connected/disconnected]
F --> H[Validation]Server Management
The ServerListStep.tsx component displays MCP server status:
interface MCPServer {
status: 'connected' | 'disconnected';
isDisabled?: boolean;
}
Disconnected servers display a debug hint:
"Run qwen --debug to see error logs"
Sources: packages/cli/src/ui/components/mcp/steps/ServerListStep.tsx
Tool Listing
The ToolListStep.tsx provides:
- Scrollable tool list with fixed-width name column
- Validation status indicators
- Tool annotations display
- Pagination for large tool sets (VISIBLE_TOOLS_COUNT)
Tool validation feedback:
interface Tool {
name: string;
isValid: boolean;
invalidReason?: string;
}
Sources: packages/cli/src/ui/components/mcp/steps/ToolListStep.tsx
Extension System
Extension Metadata
The ExtensionDetailStep.tsx displays extension information:
| Field | Description |
|---|---|
name | Extension name |
version | Semantic version |
status | Active/inactive state |
path | Installation path |
source | Install metadata source |
mcpServers | Associated MCP server list |
commands | Available CLI commands |
Sources: packages/cli/src/ui/components/extensions/steps/ExtensionDetailStep.tsx
Platform Abstraction
The webui package provides a PlatformProvider context for platform-specific capabilities:
import { PlatformProvider, usePlatform } from '@qwen-code/webui/context';
This abstraction allows the same codebase to run in different environments while exposing platform-specific APIs through a unified interface.
Sources: packages/webui/README.md
WebUI Components
Layout Components
Container- Main layout wrapperHeader- Application headerFooter- Application footerSidebar- Side navigationMain- Main content area
Message Components
Message- Chat message displayMessageList- List of messagesMessageInput- Message input fieldWaitingMessage- Loading/waiting stateInterruptedMessage- Interrupted state display
UI Primitives
- Buttons:
size,error,errorMessage,label,helperText,leftElement,rightElement - Tooltip: Content wrapper for hover hints
- Icons: File, Folder, Check, Error, Warning, Loading, Navigation, Edit, and Special icons
Sources: packages/webui/README.md
Key Command Processing
The atCommandProcessor handles special commands prefixed with @:
graph TD
A[User Query] --> B{Contains @?}
B -->|No| C[Pass Through]
B -->|Yes| D[At Command Parser]
D --> E[Command Registry]
E --> F[Processed Query]Configuration options:
getTruncateToolOutputThreshold(default: 2500)getTruncateToolOutputLines(default: 500)getUsageStatisticsEnabledgetFileExclusionswith ignore patterns
Sources: packages/cli/src/ui/hooks/atCommandProcessor.test.ts
Keyboard Navigation
The keyMatchers.ts defines command-to-key bindings:
| Command | Key Binding |
|---|---|
KILL_LINE_RIGHT | Ctrl+k |
KILL_LINE_LEFT | Ctrl+u |
CLEAR_INPUT | Ctrl+c |
DELETE_WORD_BACKWARD | Ctrl+Backspace or Meta+Backspace |
CLEAR_SCREEN | Ctrl+l |
HISTORY_UP/DOWN | Ctrl+p / Ctrl+n |
NAVIGATION_UP/DOWN | Arrow keys |
COMPLETION_UP/DOWN | Arrow keys only |
ACCEPT_SUGGESTION | Tab or Enter |
ESCAPE | Escape |
Note: Completion navigation uses only arrow keys to preserve Ctrl+P/N for history navigation.
Sources: packages/cli/src/ui/keyMatchers.test.ts
Error Handling Architecture
Status Types
| Status | Color | Usage |
|---|---|---|
success | Green | Completed tasks |
error | Red | Failed operations |
warning | Yellow | Lock-release and metadata write warnings |
running | Accent | Active sessions |
Lock-Release Warnings
When lock-release errors occur, the system displays:
"Subsequent dreams may be skipped as locked until the next session's staleness sweep cleans the file."
Metadata Write Warnings
For metadata write failures:
"The scheduler gate did not see this dream's timestamp; the next dream cycle may re-fire sooner than usual."
Sources: packages/cli/src/ui/components/background-view/BackgroundTasksDialog.tsx
Token Efficiency Tracking
The ArenaCards.tsx component tracks token efficiency per agent:
interface AgentMetrics {
label: string;
totalTokens: number;
durationMs: number;
toolCalls: number;
diffStats: {
additions: number;
deletions: number;
};
}
Metrics display with tree-style formatting for easy comparison.
Sources: packages/cli/src/ui/components/arena/ArenaCards.tsx
Sources: [packages/webui/README.md](packages/webui/README.md)
Core Agent Runtime
Related topics: Turn Processing and LLM Communication, Tools System, Session Management
Continue reading this section for the full explanation and source context.
Continue reading this section for the full explanation and source context.
Continue reading this section for the full explanation and source context.
Continue reading this section for the full explanation and source context.
Related Pages
Related topics: Turn Processing and LLM Communication, Tools System, Session Management
Core Agent Runtime
Overview
The Core Agent Runtime system in qwen-code provides the foundational infrastructure for executing AI agent tasks, managing subagents, handling tool scheduling, and coordinating background operations. This runtime architecture enables the CLI to execute complex multi-step coding tasks with support for tool calls, model routing, and persistent state management.
Architecture Components
Subagent Manager
The SubagentManager is the central coordinator for agent-level operations, handling registration, discovery, and lifecycle management of subagents across different storage levels.
graph TD
A[SubagentManager] --> B[BuiltinAgentRegistry]
A --> C[Project Level Agents]
A --> D[User Level Agents]
A --> E[Extension Agents]
C --> F[~/.qwen/agents/]
D --> G[~/.qwen/agents/]Key Responsibilities:
| Function | Description |
|---|---|
getSubagentConfig() | Retrieves subagent configuration by name and level |
listSubagentsAtLevel() | Lists all subagents at a specific storage level |
getSubagentPath() | Resolves the file path for a subagent configuration |
loadAllSubagents() | Loads all available subagents across all levels |
Storage Levels:
The system supports four distinct subagent levels:
| Level | Path | Description |
|---|---|---|
builtin | Built-in registry | Agents bundled with the application |
project | <project>/.qwen/agents/ | Project-scoped agents |
session | In-memory only | Session-specific agents |
extension | Extension-provided | Agents from loaded extensions |
Sources: packages/core/src/subagents/subagent-manager.ts:1-100
Agent Resolution Logic
The subagent path resolution follows a hierarchical pattern:
getSubagentPath(name: string, level: SubagentLevel): string {
if (level === 'builtin') return `<builtin:${name}>`;
if (level === 'session') return `<session:${name}>`;
const baseDir = level === 'project'
? path.join(this.config.getProjectRoot(), QWEN_DIR, AGENT_CONFIG_DIR)
: path.join(Storage.getGlobalQwenDir(), AGENT_CONFIG_DIR);
return path.join(baseDir, `${name}.md`);
}
Sources: packages/core/src/subagents/subagent-manager.ts:40-52
Project vs Home Directory Handling
A critical safety check prevents conflicts when the project root equals the home directory:
const homeDir = os.homedir();
const isHomeDirectory = path.resolve(projectRoot) === path.resolve(homeDir);
if (level === 'project' && isHomeDirectory) {
return [];
}
Sources: packages/core/src/subagents/subagent-manager.ts:77-82
Agent Result Display
Agent execution results are represented through the AgentResultDisplay interface, supporting various execution states and task types:
Result Types
| Type | Description |
|---|---|
task_execution | Subagent task execution result |
tool_execution | Individual tool call result |
Execution Status States
| Status | Description |
|---|---|
running | Agent is actively executing |
completed | Agent completed successfully |
failed | Agent encountered an error |
cancelled | Agent was cancelled |
Agent Result Structure
interface AgentResultDisplay {
type: 'task_execution';
subagentName: string;
taskDescription: string;
taskPrompt: string;
status: 'running' | 'completed' | 'failed' | 'cancelled';
toolCalls: ToolCall[];
}
Sources: packages/cli/src/ui/components/messages/ToolGroupMessage.test.tsx:10-35
Tool Call Integration
Tool Call Status
Tool calls within agent execution follow a status model:
| Status | Description |
|---|---|
Executing | Tool is currently running |
success | Tool completed successfully |
error | Tool failed with an error |
Tool Call Display
const createToolCall = ({
callId: string,
name: string,
status: ToolCallStatus,
resultDisplay?: AgentResultDisplay,
}) => ({
callId,
name,
status,
description: '...',
resultDisplay,
});
Performance Metrics
The runtime tracks comprehensive performance metrics for agent execution:
Computed Statistics
| Metric | Description |
|---|---|
agentActiveTime | Total time agent was actively processing |
totalApiTime | Time spent in API calls |
totalToolTime | Time spent executing tools |
apiTimePercent | Percentage of time in API calls |
toolTimePercent | Percentage of time in tool execution |
totalCachedTokens | Token usage from cache |
cacheEfficiency | Cache hit ratio |
Stats Display Component
The StatsDisplay component renders performance metrics with theme-aware coloring:
- Wall Time: Total elapsed time
- Agent Active: Time agent was processing
- API Time: Model interaction time with percentage
- Tool Time: Tool execution time with percentage
- Token Usage: Lines added/removed, token counts
Sources: packages/cli/src/ui/components/StatsDisplay.tsx:1-80
Arena Selection System
The arena system enables comparison of multiple agent implementations:
Agent Selection Dialog
The ArenaSelectDialog provides an interactive selection interface with keyboard navigation:
| Key | Action |
|---|---|
Escape | Close arena dialog |
P | Toggle preview |
D | Toggle detailed diff view |
Agent Display Metrics
Each agent candidate displays:
- Status (with color coding)
- Duration
- Token count
- File count (if applicable)
- Diff additions/deletions
const getAgentDisplay = (agent) => ({
key: agent.agentId,
value: agent.agentId,
title: agent.name,
description: `${statusInfo.text} Β· ${duration} Β· ${tokens} tokens`,
disabled: !isSuccessStatus(agent.status),
});
Sources: packages/cli/src/ui/components/arena/ArenaSelectDialog.tsx:1-60
Configuration Integration
The agent runtime integrates with the configuration system through the Config interface:
Required Configuration Methods
| Method | Purpose |
|---|---|
getSessionId() | Session identifier for state management |
getUsageStatisticsEnabled() | Enable/disable stats collection |
getDebugMode() | Enable verbose debugging |
getToolRegistry() | Access tool registry |
getApprovalMode() | Tool execution approval level |
getTruncateToolOutputThreshold() | Output truncation limit |
getTruncateToolOutputLines() | Line count truncation limit |
Default Test Configuration
const mockConfig = {
getSessionId: () => 'test-session-id',
getUsageStatisticsEnabled: () => true,
getDebugMode: () => false,
getApprovalMode: () => ApprovalMode.YOLO,
getToolRegistry: () => mockToolRegistry,
getTruncateToolOutputThreshold: () => 100,
getTruncateToolOutputLines: () => 10,
};
Sources: packages/core/src/core/coreToolScheduler.test.ts:1-80
Extension Agent Integration
Agents can also be provided by extensions through the extension registry:
if (level === 'extension') {
const extensions = this.config.getActiveExtensions();
return extensions.flatMap((extension) => extension.agents || []);
}
Extensions contribute agents via their agents property, which are merged with built-in and file-based agents.
Summary
The Core Agent Runtime provides a layered architecture for agent execution:
- SubagentManager - Coordinates agent discovery and lifecycle across storage levels
- ToolRegistry - Manages available tools and their execution
- Config System - Provides runtime configuration and state
- Extension System - Allows external contributions of agents
- UI Components - Renders agent status, results, and performance metrics
This architecture enables flexible agent composition while maintaining clear separation of concerns between agent definition, execution, and presentation layers.
Sources: [packages/core/src/subagents/subagent-manager.ts:1-100]()
Turn Processing and LLM Communication
Related topics: Core Agent Runtime, Authentication and Model Providers, Tools System
Continue reading this section for the full explanation and source context.
Continue reading this section for the full explanation and source context.
Continue reading this section for the full explanation and source context.
Continue reading this section for the full explanation and source context.
Related Pages
Related topics: Core Agent Runtime, Authentication and Model Providers, Tools System
Turn Processing and LLM Communication
Overview
Turn Processing and LLM Communication is the core message flow system that orchestrates the interaction between the Qwen Code CLI and Large Language Models. This system manages the complete lifecycle of a user interaction "turn" β from query processing through tool execution to final response delivery.
Architecture Components
The turn processing system consists of several interconnected components:
| Component | File | Responsibility |
|---|---|---|
| Turn Manager | turn.ts | Orchestrates turn lifecycle and state management |
| Client | client.ts | Handles session management and configuration |
| Content Generator | contentGenerator.ts | Generates prompts and processes responses |
| Base LLM Client | baseLlmClient.ts | Abstract base for LLM API communication |
| Tool Scheduler | coreToolScheduler.ts | Manages tool execution during turns |
Turn State Machine
A turn progresses through distinct states during its lifecycle. The system tracks both the overall turn state and individual tool call states.
graph TD
A[Turn Started] --> B[User Query Received]
B --> C[Content Generation]
C --> D{Awaiting Tool Calls?}
D -->|Yes| E[Tool Call Scheduled]
E --> F[Tool Execution]
F --> G[Tool Success?]
G -->|Yes| C
G -->|No| H[Tool Failure]
H --> I[Error Response]
D -->|No| J[Final Response]
I --> J
J --> K[Turn Complete]Message Flow
Input Processing
When a user submits a query, the system processes it through several stages:
- Query Reception β The CLI receives the user's input
- At-Command Processing β Any
@commands referencing subagents are parsed - Context Enrichment β Project context and memory are retrieved
- Prompt Construction β System prompts and context are assembled
LLM Communication
The communication with the LLM API follows a structured pattern:
graph LR
A[User Query] --> B[Content Generator]
B --> C[Base LLM Client]
C --> D[API Request]
D --> E[Streaming Response]
E --> F[Response Parser]
F --> G[Tool Call Detection]
G --> H[Tool Execution]
H --> B
F --> I[Final Response]Tool Call Lifecycle
Tool calls are processed through the Core Tool Scheduler. Each tool call transitions through these states:
| State | Description |
|---|---|
pending | Tool call queued for execution |
executing | Tool currently running |
success | Tool completed successfully |
failure | Tool encountered an error |
interrupted | Tool execution was cancelled |
The scheduler handles both native tools and MCP (Model Context Protocol) tools through a unified interface.
Response Handling
Streaming Architecture
The system supports real-time streaming responses with several message types:
- Stream chunks β Partial response text
- Thinking segments β Model reasoning (when enabled)
- Tool call updates β Progress on executing tools
- Waiting indicators β User feedback during processing
Result Display
Tool execution results are formatted into display objects that include:
| Field | Type | Description |
|---|---|---|
type | string | Result category (task_execution, error, etc.) |
status | string | Execution status |
toolCalls | array | Individual tool call results |
subagentName | string | Name of subagent (if applicable) |
Configuration
Model Configuration
The system supports multiple model providers with configurable parameters:
{
"modelProviders": {
"openai": [
{
"id": "qwen3.6-plus",
"name": "qwen3.6-plus (Coding Plan)",
"baseUrl": "https://coding.dashscope.aliyuncs.com/v1",
"envKey": "BAILIAN_CODING_PODING_PLAN_API_KEY"
}
]
}
}
Generation Config
Response generation can be customized per request:
| Parameter | Description |
|---|---|
temperature | Sampling temperature |
maxTokens | Maximum response length |
thinkingConfig.includeThoughts | Enable model thinking |
abortSignal | Cancellation token |
Telemetry and Metrics
The turn processing system records comprehensive metrics:
| Metric | Description | Tags |
|---|---|---|
TOOL_CALL_COUNT | Tool invocations | function_name, success, decision |
API_REQUEST_COUNT | LLM API calls | model, status_code |
TOKEN_USAGE | Token consumption | model, type (input/output/thought) |
These metrics enable monitoring of system performance and usage patterns.
Error Handling
Tool Execution Failures
When a tool fails, the scheduler:
- Records the error with type classification
- Fires post-tool-use failure hooks
- Optionally appends additional context from hooks
- Returns formatted error response to the LLM
Graceful Degradation
The system handles various error scenarios:
- Config errors β Individual config methods may throw; caught internally
- Network failures β Retry logic with timeout handling
- Tool unavailability β Tools excluded from execution but handled gracefully
Subagent Integration
Subagents can be invoked during turn processing. The system supports:
- Focused execution β Running subagent keeps focus for Ctrl+E expansion
- Task tracking β Subagent tasks displayed with status indicators
- Nested execution β Subagents can call other tools recursively
Data Flow Diagram
graph TD
subgraph Input
A[User Input] --> B[At-Command Processor]
B --> C[Query Parser]
end
subgraph Context
C --> D[Memory System]
C --> E[Project Context]
C --> F[Subagent Registry]
end
subgraph LLM
D --> G[Content Generator]
E --> G
F --> G
G --> H[Base LLM Client]
H --> I[Model API]
end
subgraph Execution
I --> J[Response Parser]
J --> K{Tool Calls?}
K -->|Yes| L[Core Tool Scheduler]
L --> M[Tool Registry]
M --> L
L --> N[Result Formatter]
N --> G
K -->|No| O[Final Response]
endKey Source Files
The following files implement the turn processing and LLM communication system:
| File | Purpose |
|---|---|
packages/core/src/core/turn.ts | Core turn state management |
packages/core/src/core/client.ts | Client session handling |
packages/core/src/core/contentGenerator.ts | Prompt and response handling |
packages/core/src/core/baseLlmClient.ts | Abstract LLM communication |
packages/core/src/core/coreToolScheduler.ts | Tool execution orchestration |
packages/core/src/telemetry/metrics.ts | Usage telemetry |
Summary
The Turn Processing and LLM Communication system provides the foundation for Qwen Code's interaction with language models. It coordinates query processing, manages tool execution through the scheduler, handles streaming responses, and maintains comprehensive telemetry. The modular architecture allows flexible configuration of model providers while maintaining consistent behavior across different LLM backends.
Source: https://github.com/QwenLM/qwen-code / Human Manual
Tools System
Related topics: Core Agent Runtime, Turn Processing and LLM Communication
Continue reading this section for the full explanation and source context.
Continue reading this section for the full explanation and source context.
Continue reading this section for the full explanation and source context.
Continue reading this section for the full explanation and source context.
Related Pages
Related topics: Core Agent Runtime, Turn Processing and LLM Communication
Tools System
Overview
The Tools System is a core architectural component of Qwen Code that enables the AI assistant to interact with the user's development environment. It provides a unified interface for executing code-related operations such as reading files, writing files, executing shell commands, editing code, and integrating with external services via the Model Context Protocol (MCP).
Tools extend the LLM's capabilities beyond text generation by allowing it to perform actions in the real world. When the model decides to use a tool, it generates a tool call that the system executes, returning results back to the model for further processing.
Architecture
The Tools System follows a plugin-based architecture with three main layers:
graph TD
subgraph "Presentation Layer"
UI[UI Components]
TL[ToolListStep]
MS[McpStatus]
end
subgraph "Core Layer"
TR[ToolRegistry]
TS[ToolScheduler]
TE[ToolExecutor]
end
subgraph "Integration Layer"
MCP[MCP Client]
LSP[LSP Client]
SH[Shell Tools]
FS[File System Tools]
end
UI --> TR
TL --> TR
MS --> TR
TR --> TS
TR --> TE
TE --> MCP
TE --> LSP
TE --> SH
TE --> FSCore Components
| Component | File | Responsibility |
|---|---|---|
| ToolRegistry | tool-registry.ts | Central registry for all available tools |
| ToolScheduler | coreToolScheduler.test.ts | Schedules and manages tool execution |
| BaseTool | tools.ts | Abstract base class for all tools |
| MCPToolClient | mcp-client.ts | Handles MCP server communication |
| LSPClient | lsp.ts | Language Server Protocol integration |
Built-in Tools
Qwen Code includes several built-in tools that provide fundamental file system and execution capabilities.
File Operations
#### ReadFileTool
Reads the contents of files from the file system.
// From packages/core/src/tools/read-file.ts
class ReadFileTool extends BaseTool {
readonly name = 'Bash';
readonly description = '...';
}
#### WriteFileTool
Creates or overwrites files with specified content.
// From packages/core/src/tools/write-file.ts
class WriteFileTool extends BaseTool {
readonly name = 'Write';
readonly description = '...';
}
#### EditTool
Modifies existing files by applying targeted changes, supporting search-and-replace operations.
// From packages/core/src/tools/edit.ts
class EditTool extends BaseTool {
readonly name = 'Edit';
readonly description = '...';
}
Shell Execution
#### ShellTool
Executes bash commands in the user's terminal environment.
// From packages/core/src/tools/shell.ts
class ShellTool extends BaseTool {
readonly name = 'Bash';
readonly description = 'Executes bash commands in the user\'s terminal';
}
The shell execution configuration includes terminal dimensions for proper output formatting:
getShellExecutionConfig: () => ({
terminalWidth: 90,
terminalHeight: 30,
}),
*Sources: packages/core/src/core/coreToolScheduler.test.ts:45-47*
Tool Registry
The ToolRegistry serves as the central knowledge base for all available tools in the system.
Registry Interface
interface ToolRegistry {
getToolByName(name: string): Tool | undefined;
getToolByDisplayName(displayName: string): Tool | undefined;
getTools(): Tool[];
getAllTools(): Tool[];
getAllToolNames(): string[];
getToolsByServer(serverName: string): Tool[];
discoverTools(): Promise<void>;
registerTool(tool: Tool): void;
}
*Sources: packages/core/src/core/coreToolScheduler.test.ts:18-27*
Registry Operations
Tools can be retrieved by various identifiers:
getToolByName: (name: string) =>
name === StrictStringTool.Name
? toolA
: name === StrictToolAlt.Name
? toolB
: undefined,
getToolByDisplayName: () => undefined,
getAllToolNames: () => [StrictStringTool.Name, StrictToolAlt.Name],
getToolsByServer: () => [],
*Sources: packages/core/src/core/coreToolScheduler.test.ts:28-35*
MCP Integration
The Model Context Protocol (MCP) allows Qwen Code to connect with external tools and services.
MCP Client Architecture
graph LR
LLM[LLM] -->|Tool Call| QC[Qwen Code]
QC -->|MCP Request| MS[MCP Server]
MS -->|Response| QC
QC -->|Result| LLM
subgraph "MCP Servers"
FS[File System]
DB[Database]
API[External APIs]
end
MS --> FS
MS --> DB
MS --> APIMCP Tool Display
MCP tools are displayed in the UI with their server information and validation status:
// From packages/cli/src/ui/components/views/McpStatus.tsx
{tools.map((tool) => {
const schemaContent =
showSchema &&
tool.schema &&
(tool.schema.parametersJsonSchema || tool.schema.parameters)
? JSON.stringify(tool.schema.parametersJsonSchema ?? tool.schema.parameters, null, 2)
: null;
return (
<Box key={tool.name} flexDirection="column">
<Text>- <Text color={theme.text.primary}>{tool.name}</Text></Text>
{showDescriptions && tool.description && (
<Box marginLeft={2}>
<Text color={theme.text.secondary}>{tool.description.trim()}</Text>
</Box>
)}
</Box>
);
})}
*Sources: packages/cli/src/ui/components/views/McpStatus.tsx:1-20*
MCP Servers Configuration
MCP servers can expose multiple components:
| Component | Description |
|---|---|
| Tools | Executable operations exposed by the server |
| Resources | Data sources that can be read |
| Prompts | Predefined prompt templates |
| MCP Servers | Named server connections |
// Displaying MCP servers in UI
{ext.mcpServers && Object.keys(ext.mcpServers).length > 0 && (
<Box>
<Box width={LABEL_WIDTH} flexShrink={0}>
<Text color={theme.text.primary}>{t('MCP Servers:')}</Text>
</Box>
<Text>{Object.keys(ext.mcpServers).join(', ')}</Text>
</Box>
)}
*Sources: packages/cli/src/ui/components/extensions/steps/ExtensionDetailStep.tsx:1-15*
LSP Integration
The Language Server Protocol (LSP) integration provides advanced code intelligence features including:
- Symbol navigation
- Hover information
- Go-to-definition
- Code completion
- Diagnostics
// From packages/core/src/tools/lsp.ts
class LSPTool extends BaseTool {
readonly name = 'LSP';
readonly description = 'Language Server Protocol integration';
}
Tool Execution Flow
sequenceDiagram
participant LLM as LLM Model
participant TS as Tool Scheduler
participant TR as Tool Registry
participant EX as Tool Executor
participant TOOL as Specific Tool
LLM->>TS: Request tool execution
TS->>TR: Lookup tool by name
TR-->>TS: Return tool instance
TS->>EX: Execute tool with parameters
EX->>TOOL: Call tool.run()
TOOL-->>EX: Return result
EX-->>TS: Return execution result
TS-->>LLM: Return result to modelExecution Configuration
The tool execution system supports various configuration options:
const mockConfig = {
getTruncateToolOutputThreshold: () => 100,
getTruncateToolOutputLines: () => 10,
getToolRegistry: () => mockToolRegistry,
getUseModelRouter: () => false,
getGeminiClient: () => null,
isInteractive: () => true,
};
*Sources: packages/core/src/core/coreToolScheduler.test.ts:40-48*
UI Components
Tool List Display
The ToolListStep component provides an interactive list of available tools:
// From packages/cli/src/ui/components/mcp/steps/ToolListStep.tsx
<Box width={toolNameWidth}>
<Text
color={isSelected ? theme.text.accent : theme.text.primary}
wrap="truncate"
>
{tool.name}
</Text>
</Box>
{!tool.isValid && (
<Text color={theme.status.warning}>
{t('invalid: {{reason}}', {
reason: tool.invalidReason || t('unknown'),
})}
</Text>
)}
*Sources: packages/cli/src/ui/components/mcp/steps/ToolListStep.tsx:1-15*
Context Usage Display
Tools contribute to the overall context window usage:
// From packages/cli/src/ui/components/views/ContextUsage.tsx
{/* Built-in tools detail */}
{sortedBuiltinTools.length > 0 && (
<Box flexDirection="column" marginTop={1}>
<Text bold color={theme.text.primary}>{t('Built-in tools')}</Text>
{sortedBuiltinTools.map((tool) => (
<DetailRow key={tool.name} name={tool.name} tokens={tool.tokens} />
))}
</Box>
)}
{/* MCP Tools detail */}
{sortedMcpTools.length > 0 && (
<Box flexDirection="column" marginTop={1}>
<Text bold color={theme.text.primary}>{t('MCP tools')}</Text>
{sortedMcpTools.map((tool) => (
<DetailRow key={tool.name} name={tool.name} tokens={tool.tokens} />
))}
</Box>
)}
*Sources: packages/cli/src/ui/components/views/ContextUsage.tsx:1-25*
Keyboard Shortcuts
The tool system integrates with keyboard shortcuts for quick access:
// From packages/cli/src/ui/keyMatchers.test.ts
[Command.TOGGLE_TOOL_DESCRIPTIONS]: (key: Key) => key.ctrl && key.name === 't',
[Command.TOGGLE_IDE_CONTEXT_DETAIL]: (key: Key) => key.ctrl && key.name === 'g',
*Sources: packages/cli/src/ui/keyMatchers.test.ts:1-5*
Tool Validation
Tools undergo validation before execution:
| Validation | Description |
|---|---|
| isValid | Boolean flag indicating if tool is valid |
| invalidReason | String explaining why tool is invalid |
| schema | JSON schema for parameters |
| parameters | Tool input parameters |
// Tool validation display
{annotations && tool.isValid && (
<Text color={theme.text.secondary}>{annotations}</Text>
)}
*Sources: packages/cli/src/ui/components/mcp/steps/ToolListStep.tsx:16-18*
Memory and Reference Tools
The system maintains reference memory for tools that interact with external systems:
// From packages/core/src/memory/prompt.ts
'<when_to_save>When you learn about resources in external systems and their purpose.</when_to_save>',
'<how_to_use>When the user references an external system or information that may be in an external system.</how_to_use>',
Examples of external system references:
- Bug tracking systems (e.g., Linear)
- Monitoring dashboards (e.g., Grafana)
- Communication channels (e.g., Slack)
Configuration
Tool Registry Configuration
The tool registry is configured through the main config interface:
getToolRegistry: () => mockToolRegistry,
getTruncateToolOutputThreshold: () => 100,
getTruncateToolOutputLines: () => 10,
*Sources: packages/core/src/core/coreToolScheduler.test.ts:40-42*
Display Configuration
Tools can be configured for display with various options:
interface ToolDisplayConfig {
showDescriptions: boolean;
showSchema: boolean;
visibleCount: number;
scrollOffset: number;
}
Summary
The Tools System is a comprehensive framework that enables Qwen Code to interact with the development environment through:
- Built-in Tools: File operations, shell execution, and code editing
- MCP Integration: Connection to external tools and services via Model Context Protocol
- LSP Integration: Language server features for code intelligence
- Central Registry: Unified management of all available tools
- UI Integration: User-friendly display and interaction with tools
- Validation System: Ensuring tool validity before execution
The architecture supports extensibility through the plugin-based design, allowing new tools to be registered and discovered dynamically at runtime.
Source: https://github.com/QwenLM/qwen-code / Human Manual
Authentication and Model Providers
Related topics: Turn Processing and LLM Communication
Continue reading this section for the full explanation and source context.
Continue reading this section for the full explanation and source context.
Continue reading this section for the full explanation and source context.
Continue reading this section for the full explanation and source context.
Related Pages
Related topics: Turn Processing and LLM Communication
Authentication and Model Providers
Overview
The authentication and model provider system in Qwen Code provides a flexible, pluggable architecture for connecting to various LLM providers. It handles credential management, provider configuration, authentication flows (including OAuth), and model selection across multiple backends including Alibaba ModelStudio, OpenAI-compatible APIs, Ollama, and vLLM.
The system is designed around a provider configuration model that abstracts authentication details (API keys, OAuth tokens, base URLs) from the core content generation logic, allowing users to seamlessly switch between different providers and models. Sources: packages/cli/src/auth/providerConfig.ts:1-50
Architecture
Core Components
graph TD
subgraph "User Interface Layer"
AD[AuthDialog]
AS[AuthenticateStep]
QP[QwenOAuthProgress]
end
subgraph "Configuration Layer"
PC[ProviderConfig]
MC[ModelConfig]
SS[Settings Schema]
end
subgraph "Provider Registry"
AP[All Providers]
PM[Provider Matching]
end
subgraph "Authentication Services"
OAuth[OAuth Flow]
APIKey[API Key Auth]
BaseURL[Base URL Resolution]
end
AD --> AS
AS --> QP
PC --> PM
PM --> AP
AP --> OAuth
AP --> APIKey
AP --> BaseURLProvider Configuration Model
The ProviderConfig interface defines the structure for all provider configurations:
| Field | Type | Description | |
|---|---|---|---|
id | string | Unique provider identifier | |
name | string | Display name for the provider | |
baseUrl | `string \ | Array<BaseUrlOption>` | API endpoint base URL |
envKey | string | Environment variable name for API key | |
modelsEditable | boolean | Whether users can modify model list | |
showAdvancedConfig | boolean | Show advanced configuration options | |
uiLabels | UILabelsConfig | UI text labels and titles | |
modelNamePrefix | string | Prefix for model names (e.g., provider tag) |
Sources: packages/cli/src/auth/providerConfig.ts:20-40
Provider Matching Logic
Credential-Based Matching
The system uses a matching algorithm to identify the correct provider based on user credentials:
graph TD
A[Input: baseUrl, envKey] --> B{envKey match?}
B -->|No| C[Return false]
B -->|Yes| D{baseUrl type?}
D -->|String| E{baseUrl matches?}
E -->|Yes| F[Return true]
E -->|No| C
D -->|Array| G{Any option matches?}
G -->|Yes| F
G -->|No| CThe providerMatchesCredentials function implements this logic:
export function providerMatchesCredentials(
config: ProviderConfig,
baseUrl: string | undefined,
envKey: string | undefined,
): boolean {
if (typeof config.envKey !== 'string' || config.envKey !== envKey) {
return false;
}
if (typeof config.baseUrl === 'string') {
return config.baseUrl === baseUrl;
}
if (Array.isArray(config.baseUrl)) {
return config.baseUrl.some((opt) => opt.url === baseUrl);
}
return false;
}
Sources: packages/cli/src/auth/providerConfig.ts:47-63
Model Configuration
Building Model Configurations
The buildModelConfigs function transforms provider specifications into usable model configurations:
function buildGenerationConfig(
spec: Pick<ModelSpec, 'enableThinking' | 'contextWindowSize' | 'modalities'>,
): ProviderModelConfig['generationConfig'] | undefined {
const parts: ProviderModelConfig['generationConfig'] = {};
let hasAny = false;
if (spec.enableThinking) {
parts.extra_body = { enable_thinking: true };
hasAny = true;
}
if (spec.contextWindowSize) {
parts.contextWindowSize = spec.contextWindowSize;
hasAny = true;
}
if (spec.modalities && Object.values(spec.modalities).some(Boolean)) {
parts.modalities = spec.modalities;
hasAny = true;
}
return hasAny ? parts : undefined;
}
Sources: packages/cli/src/auth/providerConfig.ts:90-107
Generation Configuration Options
| Option | Structure | Purpose |
|---|---|---|
enableThinking | extra_body: { enable_thinking: true } | Enable chain-of-thought reasoning |
contextWindowSize | contextWindowSize: number | Set maximum context length |
modalities | { text?: boolean, image?: boolean } | Enable multimodal capabilities |
Authentication Methods
Supported Authentication Types
| Method | Description | Status |
|---|---|---|
| Qwen OAuth | Alibaba Cloud OAuth flow | Discontinued (2026-04-15) |
| Coding Plan | Alibaba ModelStudio fixed subscription | Active |
| API Key | Direct OpenAI-compatible API access | Active |
| OAuth | Third-party OAuth providers | Active |
Sources: packages/vscode-ide-companion/src/webview/utils/discontinuedModel.ts:15-20
OAuth Authentication Flow
sequenceDiagram
participant User
participant CLI as AuthDialog
participant AuthStep as AuthenticateStep
participant OAuth as OAuthProvider
participant Browser
User->>CLI: Select OAuth provider
CLI->>AuthStep: Initialize OAuth flow
AuthStep->>OAuth: Request authorization URL
OAuth-->>AuthStep: Return verification URL
AuthStep->>User: Display URL + copy option
User->>Browser: Open verification URL
Browser->>OAuth: Complete authorization
OAuth-->>Browser: Authorization granted
Browser-->>User: Success confirmation
AuthStep->>OAuth: Poll for token
OAuth-->>AuthStep: Return access token
AuthStep-->>CLI: Authentication completeOAuth Progress UI
The QwenOAuthProgress component displays the device authorization flow:
export function QwenOAuthProgress({
deviceAuth,
timeRemaining,
}: QwenOAuthProgressProps): React.JSX.Element {
return (
<Box flexDirection="column" padding={1} width="100%">
<Text bold>{t('Qwen OAuth Authentication')}</Text>
<Link url={deviceAuth.verification_uri_complete || ''}>
{deviceAuth.verification_uri_complete}
</Link>
<Text>
{t('Waiting for authorization')}
{dots}
</Text>
<Text>{t('Time remaining:')} {formatTime(timeRemaining)}</Text>
</Box>
);
}
Sources: packages/cli/src/ui/components/QwenOAuthProgress.tsx:1-30
Discontinued Model Detection
ACP Model ID Parsing
The ACP (Agent Communication Protocol) server emits model IDs in a wrapped format for tracking discontinued models:
| Format | Example | ||
|---|---|---|---|
| Standard | qwen3-coder-plus(qwen-oauth) | ||
| Runtime | `$runtime\ | qwen-oauth\ | qwen3-coder-plus(qwen-oauth)` |
The ParsedAcpModelId interface extracts the base model ID and auth type:
export interface ParsedAcpModelId {
/** Model id with the trailing `(authType)` marker stripped. */
baseModelId: string;
/** Auth type extracted from the trailing `(authType)` marker. */
authType: string;
}
export const DISCONTINUED_MESSAGES = {
badge: '(Discontinued)',
description: 'Discontinued β switch to Coding Plan or API Key',
blockedError:
'Qwen OAuth free tier was discontinued on 2026-04-15. Please select a model from another provider or run /auth to switch.',
} as const;
Sources: packages/vscode-ide-companion/src/webview/utils/discontinuedModel.ts:20-35
Configuration Settings
Settings Schema Structure
The system uses a hierarchical settings structure defined in settingsSchema.ts:
graph TD
SS[settings.json] --> MP[modelProviders]
MP --> OP[openai Array]
OP --> PMC[ProviderModelConfig]
PMC --> id
PMC --> name
PMC --> baseUrl
PMC --> description
PMC --> envKey
PMC --> generationConfig
SS --> S[security]
S --> auth
auth --> selectedType
SS --> M[model]
M --> nameProvider Setup Inputs
| Field | Type | Required | Description |
|---|---|---|---|
baseUrl | string | Yes | API endpoint base URL |
apiKey | string | Yes | API key value (or empty for template) |
modelIds | string[] | No | Specific model IDs to include |
Supported Providers
Provider Configuration Examples
#### Alibaba ModelStudio (Coding Plan)
{
"modelProviders": {
"openai": [
{
"id": "qwen3.6-plus",
"name": "qwen3.6-plus (Coding Plan)",
"baseUrl": "https://coding.dashscope.aliyuncs.com/v1",
"description": "qwen3.6-plus from ModelStudio Coding Plan",
"envKey": "BAILIAN_CODING_PLAN_API_KEY"
}
]
}
}
Sources: README.md:50-65
#### Ollama (Local)
{
"modelProviders": {
"openai": [
{
"id": "qwen3:32b",
"name": "Qwen3 32B (Ollama)",
"baseUrl": "http://localhost:11434/v1",
"description": "Qwen3 32B running locally via Ollama",
"generationConfig": {
"contextWindowSize": 131072
}
}
]
}
}
Sources: README.md:150-165
#### vLLM (Local)
{
"modelProviders": {
"openai": [
{
"id": "Qwen/Qwen3-32B",
"name": "Qwen3 32B (vLLM)",
"baseUrl": "http://localhost:8000/v1",
"description": "Qwen3 32B running locally via vLLM",
"generationConfig": {
"contextWindowSize": 131072
}
}
]
}
}
Auth Dialog Workflow
View State Machine
graph TD
M[main] --> AS[alibaba-select]
M --> TS[thirdparty-select]
M --> OS[oauth-select]
AS --> BR[baseUrl Step]
TS --> BR
OS --> BR
BR --> PK[apiKey Step]
PK --> MD[models Step]
MD --> AC[advancedConfig Step]
AC --> RV[review Step]
RV --> MThe AuthDialog component manages this state:
export function AuthDialog(): React.JSX.Element {
const {
auth: { pendingAuthType, authError },
} = useUIState();
const {
auth: {
handleAuthSelect: onAuthSelect,
handleProviderSubmit,
handleOpenRouterSubmit,
onAuthError,
},
} = useUIActions();
const config = useConfig();
const settings = useSettings();
const [errorMessage, setErrorMessage] = useState<string | null>(null);
const [viewLevel, setViewLevel] = useState<ViewLevel>('main');
const [_viewStack, setViewStack] = useState<ViewStack>([]);
Sources: packages/cli/src/ui/auth/AuthDialog.tsx:60-85
Step Labels
| Step Key | Label | Description |
|---|---|---|
protocol | Protocol | Select communication protocol |
baseUrl | Base URL / Endpoint | Configure API endpoint |
apiKey | API Key | Enter credentials |
models | Model IDs | Select available models |
advancedConfig | Advanced Config | Show/hide advanced options |
review | Review | Confirm configuration |
Environment Variables
API Key Environment Variables
| Provider | Environment Variable | Description |
|---|---|---|
| Alibaba ModelStudio | DASHSCOPE_API_KEY | Standard API key |
| Alibaba Coding Plan | BAILIAN_CODING_PLAN_API_KEY | Subscription API key |
| OpenAI | OPENAI_API_KEY | OpenAI API key |
| Custom Providers | Variable defined in envKey field | Provider-specific |
Sources: README.md:80-85
Security Considerations
- Never commit API keys to version control β the
~/.qwen/settings.jsonfile should remain private - API keys via
exportor.envfiles take higher priority thansettings.jsonβenvconfiguration - The authentication system supports both key-based and OAuth-based authentication for different trust levels
Related Commands
| Command | Description |
|---|---|
/auth | Launch interactive authentication setup |
/model | Switch between configured models |
/mcp auth <server-name> | Authenticate with OAuth-enabled MCP servers |
Sources: packages/cli/src/ui/components/views/McpStatus.tsx:15-20
Sources: [packages/cli/src/auth/providerConfig.ts:20-40]()
Memory System
Related topics: Session Management, Core Agent Runtime
Continue reading this section for the full explanation and source context.
Continue reading this section for the full explanation and source context.
Continue reading this section for the full explanation and source context.
Continue reading this section for the full explanation and source context.
Related Pages
Related topics: Session Management, Core Agent Runtime
Memory System
Overview
The Memory System is a persistent, file-based knowledge management component in Qwen Code that enables the AI assistant to maintain context across conversations. It allows the system to remember information about users, projects, feedback, and external references, providing personalized and context-aware assistance over time.
The memory system is built around a directory structure at a configurable root location (~/.qwen/memory/ by default) and uses Markdown files with structured frontmatter for storing persistent information. Sources: packages/core/src/memory/prompt.ts:1-50
Architecture
graph TD
A[User Conversation] --> B[Memory Extraction Agent]
B --> C[Memory Files]
C --> D[Index File]
D --> E[Memory Recall]
E --> A
F[Dream Agent] -->|Periodic Consolidation| C
F --> D
G[CLI Remember Command] -->|Manual Save| C
G --> DCore Components
| Component | File | Responsibility |
|---|---|---|
| Memory Manager | manager.ts | Core memory operations and configuration |
| Memory Entries | entries.ts | Data structures for memory items |
| Memory Recall | recall.ts | Retrieval and context injection |
| Memory Extraction | extract.ts | Automatic memory extraction from conversations |
| Prompt Builder | prompt.ts | Prompt templates for memory operations |
| Dream Agent | dreamAgentPlanner.ts | Periodic memory consolidation |
| Extraction Agent | extractionAgentPlanner.ts | Extraction prompt generation |
Memory Types
The system supports four primary memory types, each stored in its own subdirectory:
Memory Type Structure
graph LR
A[Memory Root] --> B[user/]
A --> C[feedback/]
A --> D[project/]
A --> E[reference/]Type Definitions
| Type | Directory | Purpose | When to Save |
|---|---|---|---|
| User | user/ | User preferences, working style, collaboration patterns | When learning about user preferences, habits, or personal context |
| Feedback | feedback/ | Feedback on AI outputs, corrections, style preferences | When user corrects or provides feedback on AI responses |
| Project | project/ | Project-specific context, architecture, conventions | When learning about project structure, requirements, or technical decisions |
| Reference | reference/ | External systems, resources, documentation links | When learning about external systems (e.g., bug trackers, dashboards) |
Sources: packages/core/src/memory/prompt.ts:50-120
What NOT to Save
Per the system guidelines, the following should not be stored in memory:
- Code patterns, conventions, architecture, file paths, or project structure
- Git history, recent changes, or who-changed-what
- Debugging solutions or fix recipes
- Date-based information outside of the project directory
Sources: packages/core/src/memory/prompt.ts:100-115
Memory File Format
Memory files use structured Markdown with YAML frontmatter:
Sources: [packages/core/src/memory/prompt.ts:50-120]()
Session Management
Related topics: Memory System, Core Agent Runtime
Continue reading this section for the full explanation and source context.
Continue reading this section for the full explanation and source context.
Continue reading this section for the full explanation and source context.
Continue reading this section for the full explanation and source context.
Related Pages
Related topics: Memory System, Core Agent Runtime
Session Management
Overview
Session Management is a core system in Qwen Code that orchestrates the lifecycle of agent conversations. It handles creating new sessions, persisting conversation history, enabling session branching (forking), resuming previous sessions, and managing session metadata. The system ensures continuity across interactions and supports features like session recap generation, title derivation, and artifact preservation.
Session management operates across multiple packages including packages/core, packages/cli, and packages/vscode-ide-companion, with data persisted to the file system in JSONL format.
Architecture
graph TD
subgraph "CLI Layer"
UI[UI Components]
Actions[UIActionsContext]
BranchCmd[useBranchCommand]
end
subgraph "Core Services"
SessionService[SessionService]
SessionRecap[SessionRecap]
SessionTitle[SessionTitle]
end
subgraph "Storage Layer"
Storage[Storage Config]
FileSystem[File System]
ACP[ACP Protocol]
end
UI --> Actions
Actions --> BranchCmd
BranchCmd --> SessionService
SessionService --> Storage
SessionService --> SessionTitle
SessionService --> SessionRecap
Storage --> FileSystem
ACP --> SessionService
QwenAgent[QwenAgentManager] --> ACP
QwenAgent --> StorageCore Services
SessionService
The SessionService is the central orchestrator for all session operations. It provides APIs for:
| Method | Description |
|---|---|
createSession() | Creates a new session with unique ID |
forkSession() | Creates a branch (fork) of an existing session |
getSession() | Retrieves a session by ID |
listSessions() | Lists all sessions, optionally filtered by project |
deleteSession() | Removes a session and its artifacts |
saveSession() | Persists session state to disk |
loadSession() | Loads session from storage |
Sources: packages/core/src/services/sessionService.ts
#### Session Data Model
interface QwenSession {
sessionId: string;
title: string;
name: string;
startTime: number;
lastUpdated: number;
messageCount: number;
projectHash?: string;
filePath?: string;
cwd?: string;
}
Sources: packages/vscode-ide-companion/src/services/qwenAgentManager.ts:24-33
SessionTitle Service
The SessionTitle service automatically derives session titles from conversation content. It analyzes the first user prompt and generates a human-readable title that identifies the session's purpose.
| Feature | Description |
|---|---|
| Title Derivation | Extracts meaningful title from initial prompt |
| Auto-naming | Provides default names like "Untitled Session" when no title is available |
| Persistence | Titles are saved with session metadata |
Sources: packages/core/src/services/sessionTitle.ts
SessionRecap Service
The SessionRecap service generates summary information about sessions, providing context for:
- Session status display
- Background task tracking
- Conversation metadata
Sources: packages/core/src/services/sessionRecap.ts
Storage Architecture
File System Storage
Sessions are persisted to the file system using a structured directory layout:
graph TD
Root[Project/Root Directory]
QwenDir[.qwen/]
SessionsDir[sessions/]
Session1[session-id-1.jsonl]
Session2[session-id-2.jsonl]
Root --> QwenDir
QwenDir --> SessionsDir
SessionsDir --> Session1
SessionsDir --> Session2The Storage config provides methods for:
| Method | Purpose |
|---|---|
getProjectTempDir() | Get temporary directory for session artifacts |
getSessionDir() | Get the sessions directory path |
getSessionFile() | Get path for a specific session file |
Sources: packages/core/src/config/storage.ts
Session File Format
Session data is stored in JSONL (JSON Lines) format, with each line representing a single message or event in the conversation. This format allows for:
- Efficient streaming writes
- Incremental reading
- Easy append operations
ACP Protocol Fallback
When the Agent Communication Protocol (ACP) session list fails, the system automatically falls back to reading sessions directly from the file system:
// From qwenAgentManager.ts
try {
const items = await acpClient.listSessions();
if (items.length > 0) {
return items.map(/* transform to session format */);
}
} catch (error) {
console.warn('[QwenAgentManager] ACP session list failed, falling back...');
}
// Fallback to file system
const sessions = await this.sessionReader.getAllSessions(undefined, true);
Sources: packages/vscode-ide-companion/src/services/qwenAgentManager.ts:55-71
Session Lifecycle Operations
Creating a New Session
graph LR
A[Start] --> B[Generate Session ID]
B --> C[Create Session Object]
C --> D[Initialize Message Queue]
D --> E[Save to File System]
E --> F[Update UI State]Session Branching (Forking)
The branch command allows creating a fork of an existing session, enabling parallel exploration of different approaches:
graph TD
A[Original Session] --> B[Invoke /branch Command]
B --> C[Capture Parent Session ID]
B --> D[Finalize Current Recording]
C --> E[forkSession Service Call]
D --> E
E --> F[Write New JSONL File]
F --> G[Load Forked Session]
G --> H[Update UI Context]
H --> I[Fire SessionStart Hook]The branching process:
- Captures the current session ID for resume hint
- Finalizes the ChatRecordingService to persist last metadata
- Calls
SessionService.forkSession()to create a new JSONL file - Loads the fork back via
loadSession - Computes custom title with "(Branch)" suffix
- Announces the fork with Claude-style info
Sources: packages/cli/src/ui/hooks/useBranchCommand.ts
Session Resumption
Resuming a session allows returning to a previous conversation:
| Step | Action |
|---|---|
| 1 | User invokes /resume command |
| 2 | System loads session from storage |
| 3 | Chat history is restored |
| 4 | Context and configuration are restored |
Session Deletion
Sessions can be deleted individually or in bulk:
// From UIActionsContext.tsx
handleDelete: (sessionId: string) => void;
handleDeleteMany: (sessionIds: string[]) => void;
Sources: packages/cli/src/ui/contexts/UIActionsContext.tsx:89-90
UI Integration
UIActionsContext
The UIActionsContext provides a comprehensive interface for session-related UI operations:
| Action | Description |
|---|---|
openResumeDialog() | Opens dialog to resume a previous session |
closeResumeDialog() | Closes resume dialog |
handleResume(sessionId) | Resumes specific session |
handleBranch(name?) | Creates a branch/fork |
openDeleteDialog() | Opens delete confirmation dialog |
handleDelete(sessionId) | Deletes a single session |
handleDeleteMany(sessionIds) | Bulk deletes sessions |
Sources: packages/cli/src/ui/contexts/UIActionsContext.tsx:76-92
Background Tasks Dialog
Session information is displayed in the background tasks dialog, showing:
- Session review status
- Session count
- Topics touched in the conversation
- Error states and lock-release warnings
// From BackgroundTasksDialog.tsx
{entry.sessionCount !== undefined && (
<Fragment>
<Text bold dimColor>{t('Sessions reviewing')}</Text>
<Text>{String(entry.sessionCount)}</Text>
</Fragment>
)}
Arena Session Management
Arena sessions have specialized management options for handling artifacts:
type StopAction = 'cleanup' | 'preserve';
| Action | Behavior |
|---|---|
cleanup | Remove all worktrees and session files |
preserve | Keep worktrees and session files for later inspection |
Sources: packages/cli/src/ui/components/arena/ArenaStopDialog.tsx
Configuration
Session-Related Configuration
interface SessionConfig {
getSessionId: () => string;
getUsageStatisticsEnabled: () => boolean;
getDebugMode: () => boolean;
getApprovalMode: () => ApprovalMode;
storage: {
getProjectTempDir: () => string;
};
}
Related Commands
| Command | Description |
|---|---|
/branch | Fork current session |
/resume | Resume a previous session |
/delete | Delete session(s) |
/sessions | List all sessions |
Summary
The Session Management system in Qwen Code provides a robust framework for:
- Lifecycle Management - Creating, forking, resuming, and deleting sessions
- Persistence - Storing sessions in JSONL format on the file system
- Metadata - Managing titles, timestamps, and conversation statistics
- UI Integration - Rich dialogs and context providers for session operations
- Cross-Platform - Unified session management across CLI and VS Code IDE companion
All session operations are designed to be atomic and reliable, with automatic fallbacks (e.g., ACP β file system) to ensure data accessibility.
Sources: [packages/core/src/services/sessionService.ts]()
Skills System
Related topics: Extensions System, Core Agent Runtime
Continue reading this section for the full explanation and source context.
Continue reading this section for the full explanation and source context.
Continue reading this section for the full explanation and source context.
Continue reading this section for the full explanation and source context.
Related Pages
Related topics: Extensions System, Core Agent Runtime
Skills System
Overview
The Skills System is a modular extension framework within qwen-code that enables dynamic loading and activation of predefined capabilities. Skills are specialized modules that extend the agent's functionality beyond built-in tools, allowing users to configure and utilize domain-specific capabilities through a standardized interface.
Skills serve as a composition layer between the core agent and specialized functionality, providing:
- Modular capability packaging - Skills bundle related functionality into self-contained units
- Dynamic loading - Skills can be loaded on-demand without restarting the application
- Token-based resource tracking - Each skill reports its token consumption for context management
- Model override support - Skills can influence which model handles specific requests
Sources: packages/core/src/skills/types.ts
Architecture
The Skills System follows a layered architecture with clear separation of concerns:
graph TD
A[Agent Request] --> B[Skill Manager]
B --> C[Skill Loader]
C --> D[Skill Activation]
D --> E[Skill Execution]
F[Skill Manifest<br/>SKILL.md] --> C
G[User Config] --> B
H[Token Budget] --> E
E --> I[Response with<br/>Model Override]
E --> J[Tool Results]Core Components
| Component | File | Responsibility |
|---|---|---|
| Skill Manager | skill-manager.ts | Orchestrates skill lifecycle, registration, and retrieval |
| Skill Loader | skill-load.ts | Parses skill manifests, validates, and instantiates skills |
| Skill Activation | skill-activation.ts | Manages skill activation state and context injection |
| Skill Types | types.ts | Defines interfaces, enums, and type contracts |
Sources: packages/core/src/skills/skill-manager.ts
Skill Structure
Skill Manifest (SKILL.md)
Each skill is defined by a SKILL.md manifest file that describes its metadata and behavior:
# Skill: Review
## Description
Performs code review analysis with configurable rules.
## Triggers
- Command: `/review`
- Auto-suggest: On file save
## Actions
- analyze(code): ReviewResult
- suggest_fixes(issues): Fix[]
Sources: packages/core/src/skills/bundled/review/SKILL.md
Skill Data Model
interface Skill {
name: string; // Unique identifier
loaded: boolean; // Current activation state
tokens: number; // Token consumption for context
bodyTokens?: number; // Additional body tokens if loaded
description?: string; // Human-readable description
}
Sources: packages/cli/src/ui/components/views/ContextUsage.tsx:55-61
Skill Lifecycle
stateDiagram-v2
[*] --> Unregistered
Unregistered --> Registered: Register Skill
Registered --> Loading: Activate Skill
Loading --> Active: Load Complete
Active --> Loading: Re-activate
Active --> Inactive: Deactivate
Inactive --> Active: Reactivate
Inactive --> Unregistered: Unregister
Registered --> Unregistered: UnregisterStates
| State | Description |
|---|---|
Unregistered | Skill not known to the system |
Registered | Skill manifest parsed and indexed |
Loading | Skill resources being prepared |
Active | Skill ready for execution |
Inactive | Skill loaded but temporarily disabled |
Skill Loading Process
The skill loading process involves multiple stages:
sequenceDiagram
participant SM as Skill Manager
participant SL as Skill Loader
participant SA as Skill Activator
participant FS as File System
SM->>FS: Read SKILL.md manifest
FS-->>SL: Manifest content
SL->>SL: Parse YAML frontmatter
SL->>SL: Validate schema
SL->>SA: Validated manifest
SA->>SA: Allocate token budget
SA-->>SM: Skill activated
SM->>SM: Update skill registrySources: packages/core/src/skills/skill-load.ts
Integration with Tool System
Skills integrate with the core tool scheduler through a unified execution model:
graph LR
A[Agent Request] --> B{Request Type}
B -->|Tool Call| C[Tool Scheduler]
B -->|Skill Action| D[Skill Activation]
C --> E[Tool Executor]
D --> E
E --> F[Function Response]
F --> G[Response with Metadata]
H[Model Override] --> G
D --> HModel Override Propagation
Skills can return a modelOverride field that influences which model handles subsequent requests:
const successResponse: ToolCallResponseInfo = {
callId,
responseParts: response,
resultDisplay: toolResult.returnDisplay,
error: undefined,
errorType: undefined,
contentLength,
// Propagate modelOverride from skill tools
...('modelOverride' in toolResult
? { modelOverride: toolResult.modelOverride }
: {}),
};
Sources: packages/core/src/core/coreToolScheduler.ts:248-258
Context Usage Tracking
The system tracks skill resource consumption for context management:
interface ContextUsage {
modelName: string;
totalTokens: number;
contextWindowSize: number;
breakdown: TokenBreakdown;
skills: Skill[];
builtinTools: Tool[];
mcpTools: Tool[];
memoryFiles: FileInfo[];
isEstimated: boolean;
showDetails: boolean;
}
Sources: packages/cli/src/ui/components/HistoryItemDisplay.tsx:89-98
Skill Display in Context Usage
Skills are rendered with the following information hierarchy:
| Field | Display | Description |
|---|---|---|
name | Link text | Skill identifier |
loaded | Badge "active" | Green indicator when active |
tokens | Numeric count | Total tokens consumed |
bodyTokens | Italic secondary | Body content token count |
{sortedSkills.map((skill) => (
<Box key={skill.name} flexDirection="column">
<Box width={CONTENT_WIDTH} paddingLeft={2}>
<Text>{'\u2514'} </Text>
<Box width={32}>
<Text color={theme.text.link}>
{truncateName(skill.name, DETAIL_NAME_MAX_LEN)}
</Text>
{skill.loaded && (
<Text color={theme.status.success}> {t('active')}</Text>
)}
</Box>
<Box flexGrow={1} justifyContent="flex-end">
<Text color={theme.text.secondary}>
{formatTokens(skill.tokens)} {t('tokens')}
</Text>
</Box>
</Box>
</Box>
))}
Sources: packages/cli/src/ui/components/views/ContextUsage.tsx:55-73
User Interface Components
Skills List Component
The SkillsList component renders available skills in the history view:
{itemForDisplay.type === 'skills_list' && (
<SkillsList skills={itemForDisplay.skills} />
)}
Sources: packages/cli/src/ui/components/HistoryItemDisplay.tsx:54-56
Skill Registration Flow
graph TD
A[Start CLI] --> B[Load User Config]
B --> C[Scan Skill Directories]
C --> D{skill found?}
D -->|Yes| E[Parse SKILL.md]
D -->|No| F[Skip]
E --> G{Valid manifest?}
G -->|Yes| H[Register in Manager]
G -->|No| I[Log warning]
H --> J[Add to active list]
J --> K[Ready for use]Configuration
Skills can be configured through the main configuration system:
| Config Option | Type | Default | Description |
|---|---|---|---|
skills.enabled | boolean | true | Enable/disable skills system |
skills.maxTokens | number | 8000 | Maximum tokens for all skills |
skills.autoLoad | boolean | true | Load skills on startup |
Configuration is accessed through the central Config interface which provides access to skill-related settings.
Bundled Skills
The repository includes bundled skills that provide out-of-the-box functionality:
| Skill | Path | Purpose |
|---|---|---|
| Review | bundled/review/ | Code review and analysis |
Sources: packages/core/src/skills/bundled/review/SKILL.md
Error Handling
The skill system integrates with the tool scheduler's error handling mechanism:
// Failure handling in skill execution
if (hooksEnabled && messageBus) {
const failureHookResult = await safelyFirePostToolUseFailureHook(
messageBus,
toolUseId,
toolName,
toolInput,
toolResult.error.message,
false,
this.config.getApprovalMode(),
);
// Append additional context from hook if provided
if (failureHookResult.additionalContext) {
errorMessage += `\n\n${failureHookResult.additionalContext}`;
}
}
Sources: packages/core/src/core/coreToolScheduler.ts:263-274
Best Practices
- Manifest Validation - Always validate SKILL.md against the schema before distribution
- Token Budgeting - Monitor skill token usage to stay within context limits
- Lazy Loading - Prefer loading skills on-demand rather than at startup
- Model Override - Use sparingly and document the override behavior clearly
- Error Boundaries - Wrap skill execution in try-catch to prevent cascading failures
Summary
The Skills System provides a flexible, extensible framework for adding capabilities to the qwen-code agent. By standardizing skill definition through manifests, tracking resource consumption, and integrating with the tool execution pipeline, skills enable users to customize and expand the agent's functionality without modifying core code.
Sources: [packages/core/src/skills/types.ts]()
Extensions System
Related topics: Skills System
Continue reading this section for the full explanation and source context.
Continue reading this section for the full explanation and source context.
Continue reading this section for the full explanation and source context.
Continue reading this section for the full explanation and source context.
Related Pages
Related topics: Skills System
Extensions System
Overview
The Extensions System is a modular plugin architecture that allows Qwen Code to extend its core functionality through dynamically loadable extensions. Extensions can provide MCP servers, skills, tools, commands, and configuration options that integrate seamlessly with the main application.
Extensions enable third-party developers to extend Qwen Code without modifying the core codebase, while providing users with additional capabilities through a standardized interface.
Architecture
Extension Manager
The ExtensionManager is the central orchestrator responsible for loading, enabling, disabling, and managing all extensions. It maintains a registry of loaded extensions and handles their lifecycle events.
graph TD
A[User Request] --> B[ExtensionManager]
B --> C[Find Extension by Name]
C --> D{Extension Found?}
D -->|Yes| E[Enable/Disable Extension]
D -->|No| F[Raise Error]
E --> G[Refresh Tools]
G --> H[Update Available Skills]Extension Lifecycle
Extensions follow a defined lifecycle managed by the ExtensionManager:
| State | Description |
|---|---|
loaded | Extension binary is loaded into memory |
active | Extension is enabled and functional |
inactive | Extension is disabled but remains loaded |
The manager provides methods to control this lifecycle:
enableExtension(name, scope, cwd?)- Activates an extensiondisableExtension(name, scope, cwd?)- Deactivates an extensiongetLoadedExtensions()- Returns all currently loaded extensionsrefreshTools()- Updates the tool registry after extension changes
Sources: packages/core/src/extension/extensionManager.ts:1-50
Extension Configuration
Settings Scopes
Extensions support configuration at multiple scopes, following Qwen Code's hierarchical configuration model:
| Scope | Path | Priority |
|---|---|---|
| User | ~/.qwen/settings.json | Lower |
| Workspace | <project>/.qwen/settings.json | Higher |
Settings for extensions are stored with the extension ID as the namespace key, allowing multiple extensions to maintain independent configurations.
Sources: packages/cli/src/commands/extensions/settings.ts:1-30
Accessing Extension Settings
Extension settings can be retrieved at runtime using scoped environment contents:
const userSettings = await getScopedEnvContents(
extension.config,
extension.id,
ExtensionSettingScope.USER,
);
const workspaceSettings = await getScopedEnvContents(
extension.config,
extension.id,
ExtensionSettingScope.WORKSPACE,
);
const mergedSettings = { ...userSettings, ...workspaceSettings };
Settings merge with workspace settings taking precedence over user settings.
Sources: packages/cli/src/commands/extensions/settings.ts:40-55
Extension Metadata
Each extension carries metadata that describes its identity and capabilities:
| Property | Description |
|---|---|
name | Unique identifier for the extension |
version | Semantic version string |
path | Filesystem path to the extension |
isActive | Boolean indicating current activation state |
installMetadata | Source information (e.g., marketplace) |
mcpServers | Map of MCP server configurations |
commands | List of provided commands |
skills | List of provided skills |
Sources: packages/cli/src/ui/components/extensions/steps/ExtensionDetailStep.tsx:1-50
MCP Server Integration
Extensions can provide MCP (Model Context Protocol) servers that expose additional tools and capabilities to the AI model:
graph LR
A[Extension] --> B[MCP Servers Config]
B --> C[Server: tool1]
B --> D[Server: tool2]
C --> E[Available Tools]
D --> EWhen an extension provides MCP servers, they are listed in the extension detail view:
{ext.mcpServers && Object.keys(ext.mcpServers).length > 0 && (
<Box>
<Text color={theme.text.primary}>{t('MCP Servers:')}</Text>
<Text>{Object.keys(ext.mcpServers).join(', ')}</Text>
</Box>
)}
Sources: packages/cli/src/ui/components/extensions/steps/ExtensionDetailStep.tsx:50-65
Skills and Commands
Extensions can contribute skills that appear in the available skills list presented to the AI model. This integration uses XML-based skill descriptors:
<skill>
<name>
{skill.name}
</name>
<description>
{descText}
</description>
<location>
{skill.level}
</location>
</skill>
The skill system includes security measures to prevent injection attacks. Extension skill names and descriptions are properly escaped when generating the available skills block:
// Extension skills bypass the standard validator,
// so they must be escaped explicitly
allSkillEntries.push(`<skill>
<name>
${escapeXml(skill.name)}
</name>
<description>
${descText}
</description>
<location>
${skill.level}
</location>
</skill>`);
Sources: packages/core/src/tools/skill.ts:1-50
Command Sources
Extension-provided commands are labeled with their source for clarity in the UI:
| Source Type | Label Format | Description |
|---|---|---|
plugin-command | Extension: {name} | Commands from extensions |
skill-dir-command | Project or User | Commands from local skill directories |
Sources: packages/cli/src/services/SkillCommandLoader.ts:1-60
Extension UI Components
Extension List View
The CLI provides an interactive list view for browsing installed extensions:
<Text color={theme.text.secondary}>
{t('{{count}} extensions installed', {
count: extensions.length.toString(),
})}
</Text>
Each extension displays:
- Name
- Version
- Active status (with color coding)
- State indicator
Sources: packages/cli/src/ui/components/extensions/steps/ExtensionListStep.tsx:1-50
Extension Detail View
The detail view shows comprehensive information about a selected extension:
| Field | Display |
|---|---|
| Version | {ext.version} |
| Status | Active string with color |
| Path | Filesystem location |
| Source | Installation source |
| MCP Servers | Comma-separated list |
| Commands | When available |
Sources: packages/cli/src/ui/components/extensions/steps/ExtensionDetailStep.tsx:1-70
Extension Settings Commands
Users can view and configure extension settings through the CLI:
Viewing Settings
/extensions settings <name>
The command displays:
- Current setting values
- Scope where each setting is defined (user/workspace)
- Sensitive value indicators for secure settings
for (const setting of extension.settings) {
const value = mergedSettings[setting.envVar];
let displayValue: string;
let scopeInfo = '';
if (workspaceSettings[setting.envVar] !== undefined) {
scopeInfo = ' ' + t('(workspace)');
} else if (userSettings[setting.envVar] !== undefined) {
scopeInfo = ' ' + t('(user)');
}
if (value === undefined) {
displayValue = t('[not set]');
} else if (setting.sensitive) {
displayValue = t('[value stored in keychain]');
}
// ...
}
Sources: packages/cli/src/commands/extensions/settings.ts:60-100
Setting Storage
Extension settings support sensitive data storage via keychain integration:
| Setting Type | Storage Location |
|---|---|
| Sensitive | System keychain |
| Non-sensitive | JSON config files |
Extension Documentation
The bundled qc-helper skill provides documentation references for extension development:
| Topic | Documentation Path |
|---|---|
| Extension introduction | docs/extension/introduction.md |
| Getting started | docs/extension/getting-started-extensions.md |
| Releasing extensions | docs/extension/extension-releasing.md |
Sources: packages/core/src/skills/bundled/qc-helper/SKILL.md:1-100
Security Considerations
The extension system implements several security measures:
- XML Escaping: Skill names and descriptions from extensions are escaped to prevent injection attacks in the model-facing XML blocks.
- Scope Restrictions: System and SystemDefaults scopes are not supported for extension management to prevent privilege escalation.
- Keychain Storage: Sensitive extension settings are stored in the system keychain rather than plaintext config files.
- Validation Bypass Awareness: The codebase notes that extension skills bypass the standard validator, requiring explicit escaping in the skill generation code.
Sources: packages/core/src/extension/extensionManager.ts:10-30
Extension Workflow Summary
graph TD
A[Install Extension] --> B[Load Extension Binary]
B --> C[Register MCP Servers]
C --> D[Register Skills]
D --> E[Enable Extension]
E --> F[Refresh Tools]
F --> G[Available to AI Model]
H[User Configures] --> I[Write to Scope]
I --> J[Merge Settings]
J --> K[Apply to Extension]
L[Disable Extension] --> M[Mark Inactive]
M --> N[Tools Unavailable]See Also
Sources: [packages/core/src/extension/extensionManager.ts:1-50]()
Doramagic Pitfall Log
Source-linked risks stay visible on the manual page so the preview does not read like a recommendation.
Users may get misleading failures or incomplete behavior unless configuration is checked carefully.
The project should not be treated as fully validated until this signal is reviewed.
Users cannot judge support quality until recent activity, releases, and issue response are checked.
The project may affect permissions, credentials, data exposure, or host boundaries.
Doramagic Pitfall Log
Doramagic extracted 8 source-linked risk signals. Review them before installing or handing real data to the project.
1. Configuration risk: Configuration risk needs validation
- Severity: medium
- Finding: Configuration risk is backed by a source signal: Configuration risk needs validation. Treat it as a review item until the current version is checked.
- User impact: Users may get misleading failures or incomplete behavior unless configuration is checked carefully.
- Recommended check: Open the linked source, confirm whether it still applies to the current version, and keep the first run isolated.
- Evidence: capability.host_targets | art_875e03abe4cc4cb58b4a8ef8603b8a0b | https://github.com/QwenLM/qwen-code#readme | host_targets=claude, claude_code, chatgpt
2. Capability assumption: README/documentation is current enough for a first validation pass.
- Severity: medium
- Finding: README/documentation is current enough for a first validation pass.
- User impact: The project should not be treated as fully validated until this signal is reviewed.
- Recommended check: Open the linked source, confirm whether it still applies to the current version, and keep the first run isolated.
- Evidence: capability.assumptions | art_875e03abe4cc4cb58b4a8ef8603b8a0b | https://github.com/QwenLM/qwen-code#readme | README/documentation is current enough for a first validation pass.
3. Maintenance risk: Maintainer activity is unknown
- Severity: medium
- Finding: Maintenance risk is backed by a source signal: Maintainer activity is unknown. Treat it as a review item until the current version is checked.
- User impact: Users cannot judge support quality until recent activity, releases, and issue response are checked.
- Recommended check: Open the linked source, confirm whether it still applies to the current version, and keep the first run isolated.
- Evidence: evidence.maintainer_signals | art_875e03abe4cc4cb58b4a8ef8603b8a0b | https://github.com/QwenLM/qwen-code#readme | last_activity_observed missing
4. Security or permission risk: no_demo
- Severity: medium
- Finding: no_demo
- User impact: The project may affect permissions, credentials, data exposure, or host boundaries.
- Recommended check: Open the linked source, confirm whether it still applies to the current version, and keep the first run isolated.
- Evidence: downstream_validation.risk_items | art_875e03abe4cc4cb58b4a8ef8603b8a0b | https://github.com/QwenLM/qwen-code#readme | no_demo; severity=medium
5. Security or permission risk: No sandbox install has been executed yet; downstream must verify before user use.
- Severity: medium
- Finding: No sandbox install has been executed yet; downstream must verify before user use.
- User impact: The project may affect permissions, credentials, data exposure, or host boundaries.
- Recommended check: Open the linked source, confirm whether it still applies to the current version, and keep the first run isolated.
- Evidence: risks.safety_notes | art_875e03abe4cc4cb58b4a8ef8603b8a0b | https://github.com/QwenLM/qwen-code#readme | No sandbox install has been executed yet; downstream must verify before user use.
6. Security or permission risk: no_demo
- Severity: medium
- Finding: no_demo
- User impact: The project may affect permissions, credentials, data exposure, or host boundaries.
- Recommended check: Open the linked source, confirm whether it still applies to the current version, and keep the first run isolated.
- Evidence: risks.scoring_risks | art_875e03abe4cc4cb58b4a8ef8603b8a0b | https://github.com/QwenLM/qwen-code#readme | no_demo; severity=medium
7. Maintenance risk: issue_or_pr_quality=unknown
- Severity: low
- Finding: issue_or_pr_quality=unknownγ
- User impact: Users cannot judge support quality until recent activity, releases, and issue response are checked.
- Recommended check: Open the linked source, confirm whether it still applies to the current version, and keep the first run isolated.
- Evidence: evidence.maintainer_signals | art_875e03abe4cc4cb58b4a8ef8603b8a0b | https://github.com/QwenLM/qwen-code#readme | issue_or_pr_quality=unknown
8. Maintenance risk: release_recency=unknown
- Severity: low
- Finding: release_recency=unknownγ
- User impact: Users cannot judge support quality until recent activity, releases, and issue response are checked.
- Recommended check: Open the linked source, confirm whether it still applies to the current version, and keep the first run isolated.
- Evidence: evidence.maintainer_signals | art_875e03abe4cc4cb58b4a8ef8603b8a0b | https://github.com/QwenLM/qwen-code#readme | release_recency=unknown
Source: Doramagic discovery, validation, and Project Pack records
Community Discussion Evidence
These external discussion links are review inputs, not standalone proof that the project is production-ready.
Count of project-level external discussion links exposed on this manual page.
Open the linked issues or discussions before treating the pack as ready for your environment.
Community Discussion Evidence
Doramagic exposes project-level community discussion separately from official documentation. Review these links before using qwen-code with real data or production workflows.
- Community source 1 - github / github_issue
- node 26.0.0 - API Error: Connection error. (cause: fetch failed) - github / github_issue
- Π½Π΅ ΡΠ°Π±ΠΎΡΠ°Π΅Ρ ΡΠΆΠ°ΡΠΈΠ΅ ΠΊΠΎΠ½ΡΠ΅ΠΊΡΡΠ° - github / github_issue
- 400 {"type":"error","error":{"type":"invalid_request_error","message":"i - github / github_issue
- Daemon mode (qwen serve): proposal & open decisions - github / github_issue
- Release v0.15.11 - github / github_release
- Release v0.15.11-preview.2 - github / github_release
- Release v0.15.10-preview.1 - github / github_release
- Release v0.15.10-nightly.20260513.14512080e - github / github_release
- Release v0.15.11-preview.1 - github / github_release
- Release v0.15.11-preview.0 - github / github_release
- Release v0.15.10-nightly.20260511.0a05ea800 - github / github_release
Source: Project Pack community evidence and pitfall evidence