Documentation Index
Fetch the complete documentation index at: https://mintlify.com/QwenLM/qwen-code/llms.txt
Use this file to discover all available pages before exploring further.
The SDK emits different message types as the query progresses. Each message type provides specific information about the session state, AI responses, and execution results.
Message Type Overview
import {
isSDKUserMessage,
isSDKAssistantMessage,
isSDKSystemMessage,
isSDKResultMessage,
isSDKPartialAssistantMessage,
} from '@qwen-code/sdk';
for await (const message of result) {
if (isSDKAssistantMessage(message)) {
// Handle assistant message
} else if (isSDKResultMessage(message)) {
// Handle result message
} else if (isSDKSystemMessage(message)) {
// Handle system message
}
}
SDKAssistantMessage
Contains responses from the AI assistant.
Type Definition
interface SDKAssistantMessage {
type: 'assistant';
uuid: string;
session_id: string;
message: APIAssistantMessage;
parent_tool_use_id: string | null;
}
interface APIAssistantMessage {
id: string;
type: 'message';
role: 'assistant';
model: string;
content: ContentBlock[];
stop_reason?: string | null;
usage: Usage;
}
Type Guard
import { isSDKAssistantMessage } from '@qwen-code/sdk';
if (isSDKAssistantMessage(message)) {
// TypeScript knows message is SDKAssistantMessage
console.log(message.message.model);
}
Example Usage
for await (const message of result) {
if (isSDKAssistantMessage(message)) {
console.log('Model:', message.message.model);
console.log('Stop reason:', message.message.stop_reason);
// Process content blocks
for (const block of message.message.content) {
if (block.type === 'text') {
console.log('Text:', block.text);
} else if (block.type === 'thinking') {
console.log('Thinking:', block.thinking);
} else if (block.type === 'tool_use') {
console.log(`Tool: ${block.name}(${JSON.stringify(block.input)})`);
}
}
}
}
Fields
Unique identifier for this message.
Model used to generate this response (e.g., 'gpt-4', 'qwen-max').
Reason why generation stopped:
'end_turn': Normal completion
'max_tokens': Token limit reached
'stop_sequence': Stop sequence encountered
Token usage information:{
input_tokens: number;
output_tokens: number;
cache_creation_input_tokens?: number;
cache_read_input_tokens?: number;
}
ID of the parent tool use, if this is a response to a tool invocation.
SDKResultMessage
Indicates query completion with success or error information.
Type Definition
type SDKResultMessage = SDKResultMessageSuccess | SDKResultMessageError;
interface SDKResultMessageSuccess {
type: 'result';
subtype: 'success';
uuid: string;
session_id: string;
is_error: false;
duration_ms: number;
duration_api_ms: number;
num_turns: number;
result: string;
usage: ExtendedUsage;
modelUsage?: Record<string, ModelUsage>;
permission_denials: CLIPermissionDenial[];
}
interface SDKResultMessageError {
type: 'result';
subtype: 'error_max_turns' | 'error_during_execution';
uuid: string;
session_id: string;
is_error: true;
duration_ms: number;
duration_api_ms: number;
num_turns: number;
usage: ExtendedUsage;
modelUsage?: Record<string, ModelUsage>;
permission_denials: CLIPermissionDenial[];
error?: {
type?: string;
message: string;
};
}
Type Guard
import { isSDKResultMessage } from '@qwen-code/sdk';
if (isSDKResultMessage(message)) {
if (message.is_error) {
console.error('Error:', message.error);
} else {
console.log('Success:', message.result);
}
}
Example Usage
for await (const message of result) {
if (isSDKResultMessage(message)) {
console.log(`Completed in ${message.duration_ms}ms`);
console.log(`API time: ${message.duration_api_ms}ms`);
console.log(`Turns: ${message.num_turns}`);
console.log(`Total tokens: ${message.usage.input_tokens + message.usage.output_tokens}`);
if (message.is_error) {
console.error('Error type:', message.subtype);
console.error('Error message:', message.error?.message);
} else {
console.log('Result:', message.result);
}
if (message.permission_denials.length > 0) {
console.log('Permission denials:', message.permission_denials);
}
}
}
Fields
Whether the query completed with an error.
Result subtype:
'success': Query completed successfully
'error_max_turns': Exceeded maximum turns
'error_during_execution': Error during execution
Total duration of the query in milliseconds.
Time spent in API calls in milliseconds.
Number of conversation turns executed.
Result message (only present when is_error is false).
Extended usage information including web search requests and cache metrics.
modelUsage
Record<string, ModelUsage>
Per-model usage breakdown.
Array of tools that were denied permission during execution.
Error information (only present when is_error is true):{
type?: string;
message: string;
}
SDKSystemMessage
Provides session information and configuration.
Type Definition
interface SDKSystemMessage {
type: 'system';
subtype: string;
uuid: string;
session_id: string;
data?: unknown;
cwd?: string;
tools?: string[];
mcp_servers?: Array<{ name: string; status: string }>;
model?: string;
permission_mode?: string;
slash_commands?: string[];
qwen_code_version?: string;
output_style?: string;
agents?: string[];
skills?: string[];
capabilities?: Record<string, unknown>;
}
Type Guard
import { isSDKSystemMessage } from '@qwen-code/sdk';
if (isSDKSystemMessage(message)) {
console.log('Session info:', message);
}
Example Usage
for await (const message of result) {
if (isSDKSystemMessage(message)) {
console.log('Session ID:', message.session_id);
console.log('Working directory:', message.cwd);
console.log('Model:', message.model);
console.log('Permission mode:', message.permission_mode);
console.log('Available tools:', message.tools);
console.log('MCP servers:', message.mcp_servers);
console.log('Qwen Code version:', message.qwen_code_version);
}
}
SDKUserMessage
Represents a user message sent to the AI.
Type Definition
interface SDKUserMessage {
type: 'user';
uuid?: string;
session_id: string;
message: APIUserMessage;
parent_tool_use_id: string | null;
options?: Record<string, unknown>;
}
interface APIUserMessage {
role: 'user';
content: string | ContentBlock[];
}
Type Guard
import { isSDKUserMessage } from '@qwen-code/sdk';
if (isSDKUserMessage(message)) {
console.log('User message:', message.message.content);
}
Example Usage
You typically create these messages when using multi-turn conversations:
const userMessage: SDKUserMessage = {
type: 'user',
session_id: 'my-session',
message: {
role: 'user',
content: 'Create a hello.txt file',
},
parent_tool_use_id: null,
};
SDKPartialAssistantMessage
Streaming events emitted during message generation (when includePartialMessages: true).
Type Definition
interface SDKPartialAssistantMessage {
type: 'stream_event';
uuid: string;
session_id: string;
event: StreamEvent;
parent_tool_use_id: string | null;
}
type StreamEvent =
| MessageStartStreamEvent
| ContentBlockStartEvent
| ContentBlockDeltaEvent
| ContentBlockStopEvent
| MessageStopStreamEvent;
Type Guard
import { isSDKPartialAssistantMessage } from '@qwen-code/sdk';
if (isSDKPartialAssistantMessage(message)) {
// Handle streaming event
}
Example Usage
import { query, isSDKPartialAssistantMessage } from '@qwen-code/sdk';
const result = query({
prompt: 'Explain async/await',
options: { includePartialMessages: true },
});
for await (const message of result) {
if (isSDKPartialAssistantMessage(message)) {
const event = message.event;
if (event.type === 'message_start') {
console.log('Message started:', event.message.model);
} else if (event.type === 'content_block_start') {
console.log('Block started:', event.content_block.type);
} else if (event.type === 'content_block_delta') {
if (event.delta.type === 'text_delta') {
process.stdout.write(event.delta.text);
} else if (event.delta.type === 'thinking_delta') {
process.stdout.write(`[Thinking: ${event.delta.thinking}]`);
}
} else if (event.type === 'content_block_stop') {
console.log('\nBlock stopped at index:', event.index);
} else if (event.type === 'message_stop') {
console.log('Message complete');
}
}
}
Stream Event Types
Signals the start of a new message:{
type: 'message_start';
message: {
id: string;
role: 'assistant';
model: string;
};
}
Signals the start of a new content block:{
type: 'content_block_start';
index: number;
content_block: ContentBlock;
}
Incremental update to a content block:{
type: 'content_block_delta';
index: number;
delta: ContentBlockDelta;
}
Delta types:
{ type: 'text_delta', text: string }
{ type: 'thinking_delta', thinking: string }
{ type: 'input_json_delta', partial_json: string }
Signals completion of a content block:{
type: 'content_block_stop';
index: number;
}
Signals completion of the entire message:{
type: 'message_stop';
}
Content Blocks
Content blocks represent different types of content in messages:
TextBlock
interface TextBlock {
type: 'text';
text: string;
annotations?: Annotation[];
}
Plain text content from the assistant.
ThinkingBlock
interface ThinkingBlock {
type: 'thinking';
thinking: string;
signature?: string;
annotations?: Annotation[];
}
Internal reasoning/thinking process of the AI.
interface ToolUseBlock {
type: 'tool_use';
id: string;
name: string;
input: unknown;
annotations?: Annotation[];
}
Represents a tool being invoked.
interface ToolResultBlock {
type: 'tool_result';
tool_use_id: string;
content?: string | ContentBlock[];
is_error?: boolean;
annotations?: Annotation[];
}
Result from a tool execution.
Type Guards for Content Blocks
import {
isTextBlock,
isThinkingBlock,
isToolUseBlock,
isToolResultBlock,
} from '@qwen-code/sdk';
for (const block of message.message.content) {
if (isTextBlock(block)) {
console.log(block.text);
} else if (isThinkingBlock(block)) {
console.log('[Thinking]:', block.thinking);
} else if (isToolUseBlock(block)) {
console.log(`Tool: ${block.name}`);
} else if (isToolResultBlock(block)) {
console.log(`Result: ${block.content}`);
}
}
Complete Example
import {
query,
isSDKAssistantMessage,
isSDKResultMessage,
isSDKSystemMessage,
isSDKPartialAssistantMessage,
isTextBlock,
isThinkingBlock,
isToolUseBlock,
} from '@qwen-code/sdk';
const result = query({
prompt: 'List files in the current directory',
options: {
includePartialMessages: true,
},
});
for await (const message of result) {
if (isSDKSystemMessage(message)) {
console.log('Session started:', message.session_id);
console.log('Model:', message.model);
} else if (isSDKPartialAssistantMessage(message)) {
if (message.event.type === 'content_block_delta') {
if (message.event.delta.type === 'text_delta') {
process.stdout.write(message.event.delta.text);
}
}
} else if (isSDKAssistantMessage(message)) {
console.log('\n--- Complete Message ---');
for (const block of message.message.content) {
if (isTextBlock(block)) {
console.log('Text:', block.text);
} else if (isThinkingBlock(block)) {
console.log('Thinking:', block.thinking);
} else if (isToolUseBlock(block)) {
console.log(`Tool: ${block.name}(${JSON.stringify(block.input)})`);
}
}
} else if (isSDKResultMessage(message)) {
console.log('\n--- Result ---');
console.log('Duration:', message.duration_ms, 'ms');
console.log('Tokens:', message.usage.input_tokens + message.usage.output_tokens);
if (message.is_error) {
console.error('Error:', message.error?.message);
} else {
console.log('Success:', message.result);
}
}
}
See Also