The Query class returned by query() provides methods for controlling the query session, inspecting state, and modifying behavior mid-session.
Overview
A Query instance implements AsyncIterable<SDKMessage>, allowing you to iterate over messages:
import { query } from '@qwen-code/sdk';
const q = query({
prompt: 'Hello',
options: {},
});
// Iterate over messages
for await (const message of q) {
console.log(message);
}
// Or use methods
const sessionId = q.getSessionId();
Methods
getSessionId()
Get the unique session identifier.
Returns
The session ID (UUID format).
Example
const q = query({
prompt: 'Hello',
options: {},
});
const sessionId = q.getSessionId();
console.log('Session ID:', sessionId);
// Output: Session ID: 123e4567-e89b-12d3-a456-426614174000
Use Cases
- Resume sessions later with the
resume option
- Track sessions across multiple queries
- Link sessions with external systems
- Debug and logging
isClosed()
Check if the query session has been closed.
Returns
true if the session is closed, false otherwise.
Example
const q = query({
prompt: 'Hello',
options: {},
});
console.log('Closed?', q.isClosed()); // false
for await (const message of q) {
// Process messages
}
console.log('Closed?', q.isClosed()); // true (after iteration completes)
Use Cases
- Check session state before calling methods
- Conditional logic based on session status
- Resource cleanup verification
interrupt()
Interrupt the current operation. The AI will stop what it’s doing and await further instructions.
interrupt(): Promise<void>
Returns
Promise that resolves when the interrupt is acknowledged.
Example
const q = query({
prompt: 'Analyze this large codebase',
options: {},
});
// Interrupt after 5 seconds
setTimeout(async () => {
await q.interrupt();
console.log('Operation interrupted');
}, 5000);
for await (const message of q) {
console.log(message);
}
Notes
- Throws an error if the query is already closed
- The interrupt is sent as a control request to the CLI
- The AI will finish the current tool execution before stopping
setPermissionMode()
Change the permission mode during the session.
setPermissionMode(mode: PermissionMode): Promise<void>
Parameters
The new permission mode: 'default', 'plan', 'auto-edit', or 'yolo'.
Returns
Promise that resolves when the mode change is acknowledged.
Example
import { query } from '@qwen-code/sdk';
const q = query({
prompt: 'First, show me what you would do',
options: {
permissionMode: 'plan', // Start in plan mode
},
});
let planShown = false;
for await (const message of q) {
if (message.type === 'assistant' && !planShown) {
console.log('Plan:', message.message.content);
planShown = true;
// Switch to auto-edit after seeing the plan
await q.setPermissionMode('auto-edit');
console.log('Switched to auto-edit mode');
}
}
Notes
- Changes take effect immediately for subsequent tool requests
- Does not affect ongoing tool executions
- Throws an error if the query is closed
setModel()
Change the AI model during the session.
setModel(model: string): Promise<void>
Parameters
The new model identifier (e.g., 'gpt-4', 'qwen-max').
Returns
Promise that resolves when the model change is acknowledged.
Example
const q = query({
prompt: 'Start with a simple task',
options: {
model: 'gpt-3.5-turbo', // Start with faster model
},
});
let taskCount = 0;
for await (const message of q) {
if (message.type === 'result') {
taskCount++;
if (taskCount === 1) {
// Switch to more powerful model for complex tasks
await q.setModel('gpt-4');
console.log('Switched to GPT-4');
}
}
}
Notes
- The new model is used for subsequent AI requests
- Does not affect the current ongoing request
- Throws an error if the query is closed
close()
Manually close the query session and cleanup resources.
Returns
Promise that resolves when the session is fully closed.
Example
const q = query({
prompt: 'Long running task',
options: {},
});
let messageCount = 0;
for await (const message of q) {
messageCount++;
// Close after 10 messages
if (messageCount >= 10) {
await q.close();
break;
}
}
console.log('Session closed');
What Gets Cleaned Up
- CLI process terminated
- Pending control requests rejected
- MCP transports closed
- Input stream completed
- Event listeners removed
Notes
- Automatically called when iteration completes normally
- Safe to call multiple times (subsequent calls are no-ops)
- Pending operations will be rejected with “Query is closed” error
Stream user messages for multi-turn conversations.
streamInput(messages: AsyncIterable<SDKUserMessage>): Promise<void>
This is a low-level method. For most use cases, pass an async iterable as the prompt parameter to query() instead.
Parameters
messages
AsyncIterable<SDKUserMessage>
required
Async iterable of user messages to send.
Returns
Promise that resolves when all messages have been sent.
Example
import { query, type SDKUserMessage } from '@qwen-code/sdk';
const q = query({
prompt: '',
options: {},
});
// Stream messages programmatically
async function* generateMessages(): AsyncIterable<SDKUserMessage> {
yield {
type: 'user',
session_id: q.getSessionId(),
message: { role: 'user', content: 'First message' },
parent_tool_use_id: null,
};
await new Promise(resolve => setTimeout(resolve, 1000));
yield {
type: 'user',
session_id: q.getSessionId(),
message: { role: 'user', content: 'Second message' },
parent_tool_use_id: null,
};
}
q.streamInput(generateMessages());
for await (const message of q) {
console.log(message);
}
Signal that no more user messages will be sent (for multi-turn mode).
This is a low-level method. The SDK automatically calls this when using async iterables.
Example
const q = query({
prompt: '',
options: {},
});
// Send messages
q.streamInput(someMessages());
// Signal completion
q.endInput();
supportedCommands()
Get the list of control commands supported by the CLI.
supportedCommands(): Promise<Record<string, unknown> | null>
Returns
commands
Record<string, unknown> | null
Object containing supported command names and their metadata.
Example
const q = query({
prompt: 'Hello',
options: {},
});
const commands = await q.supportedCommands();
console.log('Supported commands:', commands);
mcpServerStatus()
Get the status of MCP servers connected to the session.
mcpServerStatus(): Promise<Record<string, unknown> | null>
Returns
status
Record<string, unknown> | null
Object containing MCP server status information.
Example
const q = query({
prompt: 'Hello',
options: {
mcpServers: {
calculator: myServer,
},
},
});
const status = await q.mcpServerStatus();
console.log('MCP servers:', status);
Complete Example
Here’s a comprehensive example using multiple methods:
import { query, isSDKAssistantMessage, isSDKResultMessage } from '@qwen-code/sdk';
async function advancedSession() {
const q = query({
prompt: 'Analyze the codebase',
options: {
permissionMode: 'plan',
model: 'gpt-3.5-turbo',
},
});
console.log('Session ID:', q.getSessionId());
console.log('Closed?', q.isClosed());
let planReceived = false;
let needsInterrupt = false;
for await (const message of q) {
if (isSDKAssistantMessage(message) && !planReceived) {
console.log('\n--- Plan ---');
console.log(message.message.content);
// Approve the plan and switch modes
await q.setPermissionMode('auto-edit');
await q.setModel('gpt-4');
console.log('Switched to auto-edit + GPT-4');
planReceived = true;
}
// Interrupt if something goes wrong
if (needsInterrupt) {
await q.interrupt();
console.log('Operation interrupted');
break;
}
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.log('Success:', message.result);
}
}
}
console.log('Closed?', q.isClosed());
// Explicit cleanup (optional, happens automatically)
await q.close();
}
advancedSession().catch(console.error);
Error Handling
All methods throw errors if called on a closed query:
const q = query({
prompt: 'Hello',
options: {},
});
for await (const message of q) {
// Process messages
}
// Query is now closed
try {
await q.setModel('gpt-4');
} catch (error) {
console.error(error.message); // "Query is closed"
}
See Also