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.
File System Tools
Qwen Code provides a comprehensive suite of tools for interacting with the local file system. All file system tools operate within the workspace directory for security.
read_file
Tool Name: read_file
Display Name: ReadFile
Kind: Read
Description: Reads and returns the content of a specified file. Handles text, images (PNG, JPG, GIF, WEBP, SVG, BMP), and PDF files.
Parameters
interface ReadFileParams {
absolute_path: string; // Required: Absolute path to file
offset?: number; // Optional: Starting line (0-based)
limit?: number; // Optional: Number of lines to read
}
Usage
// Read entire file
read_file({
absolute_path: '/home/user/project/src/index.ts'
});
// Read specific lines
read_file({
absolute_path: '/home/user/project/README.md',
offset: 0,
limit: 50
});
// Read image
read_file({
absolute_path: '/home/user/project/logo.png'
});
Behavior
- Text Files: Returns content as string with line numbers
- Images: Returns base64-encoded data with MIME type
- PDFs: Returns base64-encoded data
- Binary Files: Returns error message
- Large Files: Automatically truncates with indication
- Missing Files: Returns error
Confirmation
No confirmation required (read-only operation).
Implementation
Location: packages/core/src/tools/read-file.ts
export class ReadFileTool extends BaseDeclarativeTool<
ReadFileToolParams,
ToolResult
> {
static readonly Name = ToolNames.READ_FILE;
constructor(private config: Config) {
super(
ReadFileTool.Name,
ToolDisplayNames.READ_FILE,
'Reads and returns the content of a specified file...',
Kind.Read,
{ /* schema */ },
);
}
protected override validateToolParamValues(
params: ReadFileToolParams,
): string | null {
// Validate absolute path
if (!path.isAbsolute(params.absolute_path)) {
return 'Path must be absolute';
}
// Validate within workspace
if (!this.config.getWorkspaceContext()
.isPathWithinWorkspace(params.absolute_path)) {
return 'Path must be within workspace';
}
// Check .qwenignore
if (this.config.getFileService()
.shouldQwenIgnoreFile(params.absolute_path)) {
return 'File is ignored by .qwenignore';
}
return null;
}
}
write_file
Tool Name: write_file
Display Name: WriteFile
Kind: Edit
Description: Writes content to a specified file. Creates the file and parent directories if they don’t exist. Overwrites existing files.
Parameters
interface WriteFileParams {
file_path: string; // Required: Absolute path to file
content: string; // Required: Content to write
}
Usage
// Create new file
write_file({
file_path: '/home/user/project/src/new.ts',
content: 'export const value = 42;'
});
// Overwrite existing file
write_file({
file_path: '/home/user/project/README.md',
content: '# Updated README\n\nNew content...'
});
Behavior
- New Files: Creates file and parent directories
- Existing Files: Overwrites completely
- Encoding: Preserves existing BOM if present
- Permissions: Respects file system permissions
- User Modification: User can modify content before write
Confirmation
Yes. Shows a diff of changes and asks for user approval.
Implementation
Location: packages/core/src/tools/write-file.ts
export class WriteFileTool
extends BaseDeclarativeTool<WriteFileToolParams, ToolResult>
implements ModifiableDeclarativeTool<WriteFileToolParams>
{
static readonly Name = ToolNames.WRITE_FILE;
override async shouldConfirmExecute(
signal: AbortSignal,
): Promise<ToolCallConfirmationDetails | false> {
if (this.config.getApprovalMode() === ApprovalMode.AUTO_EDIT) {
return false;
}
// Generate diff for confirmation
const { originalContent, correctedContent } =
await getCorrectedFileContent(
this.config,
this.params.file_path,
this.params.content,
);
const fileDiff = Diff.createPatch(
fileName,
originalContent,
correctedContent,
'Current',
'Proposed',
);
return {
type: 'edit',
title: `Confirm Write: ${fileName}`,
fileDiff,
originalContent,
newContent: correctedContent,
};
}
}
edit
Tool Name: edit
Display Name: Edit
Kind: Edit
Description: Replaces text within a file. By default requires unique match. Set replace_all for multiple replacements.
Parameters
interface EditParams {
file_path: string; // Required: Absolute path
old_string: string; // Required: Text to replace
new_string: string; // Required: Replacement text
replace_all?: boolean; // Optional: Replace all occurrences
}
Usage
// Single replacement (default)
edit({
file_path: '/home/user/project/src/config.ts',
old_string: `export const API_URL = 'http://localhost:3000';`,
new_string: `export const API_URL = 'https://api.example.com';`,
});
// Multiple replacements
edit({
file_path: '/home/user/project/src/utils.ts',
old_string: 'oldFunction',
new_string: 'newFunction',
replace_all: true,
});
// Create new file (empty old_string)
edit({
file_path: '/home/user/project/src/new.ts',
old_string: '',
new_string: 'export const value = 42;',
});
Behavior
- Unique Match Required: By default,
old_string must match exactly once
- Replace All: Set
replace_all: true for multiple matches
- Context Required: Include sufficient context (3+ lines before/after)
- Whitespace Sensitive: Preserves exact indentation and spacing
- Line Ending Normalization: Handles CRLF/LF automatically
- Self-Correction: May attempt to fix ambiguous matches
Confirmation
Yes. Shows a diff of the proposed changes.
Common Errors
// Error: old_string not found
edit({
file_path: '/file.ts',
old_string: 'function foo() {', // No match
new_string: 'function bar() {',
});
// Solution: Read file first to get exact text
// Error: Multiple matches without replace_all
edit({
file_path: '/file.ts',
old_string: 'const x = 1;', // Matches 3 times
new_string: 'const x = 2;',
});
// Solution: Add more context or use replace_all: true
// Error: File already exists
edit({
file_path: '/existing.ts',
old_string: '', // Trying to create
new_string: 'content',
});
// Solution: Use write_file or provide old_string
Implementation
Location: packages/core/src/tools/edit.ts
export class EditTool
extends BaseDeclarativeTool<EditToolParams, ToolResult>
implements ModifiableDeclarativeTool<EditToolParams>
{
static readonly Name = ToolNames.EDIT;
async execute(signal: AbortSignal): Promise<ToolResult> {
const editData = await this.calculateEdit(this.params);
if (editData.error) {
return {
llmContent: editData.error.raw,
error: {
message: editData.error.raw,
type: editData.error.type,
},
};
}
// Apply replacement
const newContent = applyReplacement(
editData.currentContent,
finalOldString,
finalNewString,
editData.isNewFile,
);
// Write file
await this.config
.getFileSystemService()
.writeTextFile(this.params.file_path, newContent);
return {
llmContent: 'Successfully modified file',
returnDisplay: { fileDiff, fileName, /* ... */ },
};
}
}
glob
Tool Name: glob
Display Name: Glob
Kind: Read
Description: Finds files matching glob patterns, returning paths sorted by modification time (newest first).
Parameters
interface GlobParams {
pattern: string; // Required: Glob pattern
path?: string; // Optional: Directory to search
}
Usage
// Find all TypeScript files
glob({ pattern: '**/*.ts' });
// Find in specific directory
glob({
pattern: '*.md',
path: '/home/user/project/docs'
});
// Complex patterns
glob({ pattern: 'src/**/*.{ts,tsx}' });
glob({ pattern: '**/test/**/*.test.js' });
Patterns
* - Match any characters except /
** - Match any characters including /
? - Match single character
[abc] - Match any character in set
{js,ts} - Match any pattern in set
!pattern - Exclude pattern
Behavior
- Sorting: Most recently modified first
- Limit: Returns max 100 files
- Respects Ignores: Follows
.gitignore and .qwenignore
- Absolute Paths: Always returns absolute paths
Confirmation
No confirmation required.
Implementation
Location: packages/core/src/tools/glob.ts
grep_search
Tool Name: grep_search
Display Name: Grep
Kind: Read
Description: Searches for regex patterns within file contents. Returns matching lines with file paths and line numbers.
Parameters
interface GrepParams {
pattern: string; // Required: Regex pattern
path?: string; // Optional: File or directory
glob?: string; // Optional: File filter pattern
limit?: number; // Optional: Max results
}
Usage
// Search for pattern
grep_search({
pattern: 'function\\s+\\w+',
});
// Search in directory with filter
grep_search({
pattern: 'TODO',
path: 'src',
glob: '*.ts',
});
// Limit results
grep_search({
pattern: 'import',
limit: 50,
});
// Complex regex
grep_search({
pattern: 'class\\s+(\\w+)\\s+extends',
glob: '**/*.{ts,tsx}',
});
Behavior
- Engine: Uses ripgrep if available, falls back to JS implementation
- Case Insensitive: By default
- Respects Ignores: Follows
.gitignore and .qwenignore
- Line Context: Returns full matching lines
- Performance: Very fast with ripgrep
Confirmation
No confirmation required.
Implementation
Location: packages/core/src/tools/grep.ts and ripGrep.ts
list_directory
Tool Name: list_directory
Display Name: ListFiles
Kind: Read
Description: Lists files and subdirectories in a specified directory.
Parameters
interface ListDirectoryParams {
path: string; // Required: Directory path
ignore?: string[]; // Optional: Patterns to ignore
respect_git_ignore?: boolean; // Optional: Respect .gitignore
}
Usage
// List directory
list_directory({
path: '/home/user/project/src'
});
// With ignore patterns
list_directory({
path: '/home/user/project',
ignore: ['*.log', 'node_modules', '.git'],
});
// Ignore .gitignore
list_directory({
path: '/home/user/project',
respect_git_ignore: false,
});
Behavior
- Sorting: Directories first, then alphabetically
- Type Indication: Shows
[DIR] for directories
- Respects Ignores: Follows ignore patterns by default
Confirmation
No confirmation required.
Implementation
Location: packages/core/src/tools/ls.ts
Security
All file system tools enforce security measures:
Path Validation
- Absolute Paths Required: All paths must be absolute
- Workspace Boundary: Paths must be within workspace
- Ignore Patterns: Respects
.qwenignore and .gitignore
- Temp Directory Access: Limited temp directory access
Example Validation
protected override validateToolParamValues(
params: FileToolParams,
): string | null {
const filePath = params.path;
// Check absolute
if (!path.isAbsolute(filePath)) {
return `Path must be absolute: ${filePath}`;
}
// Check workspace
const workspaceContext = this.config.getWorkspaceContext();
if (!workspaceContext.isPathWithinWorkspace(filePath)) {
return `Path must be within workspace: ${filePath}`;
}
// Check ignore
if (this.config.getFileService().shouldQwenIgnoreFile(filePath)) {
return `Path is ignored: ${filePath}`;
}
return null;
}
Best Practices
- Read Before Edit: Always read files before editing
- Sufficient Context: Include 3+ lines of context in
old_string
- Use Glob First: Use glob to find files before reading
- Limit Results: Use limits to prevent overwhelming context
- Validate Paths: Always use absolute paths
- Handle Errors: Check for error results
Next Steps