qwen-tools
Generated from plugins/qwen-tools/README.md.
Compatibility-oriented Qwen-style filesystem tools for the AI Agent Platform.
This package aims to match Qwen Code model-facing tool schemas, parameter names, major parameter semantics, important truncation and error wording, and LLM-visible tool result content closely while reusing shared Python filesystem helpers underneath.
Structured media payloads are preserved in raw tool results. In the current text-first tool message pipeline, those payloads are still rendered to the model as text/JSON.
Exposed tools
Current public tools in this package:
read_filelist_directorygrep_searchglobwrite_fileeditbashweb_fetch
Write/edit surface summary:
write_file(file_path, content)writes the full file at an absolute path and overwrites existing content.edit(file_path, old_string, new_string, replace_all=false)performs literal replacement and expects exactly one match unlessreplace_allis enabled.editalso supports file creation whenold_stringis the empty string and the target file does not yet exist.
The plugin repo exposes these classes through agent_plugin.json:
qwen_tools.qwen_read_file_tool.QwenReadFileToolqwen_tools.qwen_list_directory_tool.QwenListDirectoryToolqwen_tools.qwen_grep_search_tool.QwenGrepSearchToolqwen_tools.qwen_glob_tool.QwenGlobToolqwen_tools.qwen_write_file_tool.QwenWriteFileToolqwen_tools.qwen_edit_tool.QwenEditToolqwen_tools.qwen_shell_tool.QwenShellToolqwen_tools.qwen_web_fetch_tool.QwenWebFetchTool
Quickstart
Minimal global plugin loading with the application plugin manager:
{
"plugin_cache_dir": "~/.crystal/plugins",
"plugin_policy": {
"base_dir": ".",
"install_deps": true
},
"plugins": [
"path:./plugins/qwen-tools"
]
}
Combine it with a provider bundle such as OpenRouter:
{
"plugin_cache_dir": "~/.crystal/plugins",
"plugin_policy": {
"base_dir": ".",
"install_deps": true
},
"plugins": [
"path:./plugins/openrouter",
"path:./plugins/qwen-tools"
],
"agents": {
"default": {
"provider": "openrouter",
"model": "qwen/qwen3.5-flash-02-23"
}
}
}
install_deps matters for this package because it depends on the sibling
shared package under plugins/tool-compat-shared.
For now, the simplest setup is to load this package in the global plugins
list. Once subtask 040-agent-and-provider-plugin-package-config is completed,
agent-level and provider-level plugins placement will also be documented and
available for this package family.
Writer behavior notes
The Qwen-compatible writer entrypoint is write_file.
file_pathmust be absolute.contentis the full file body and overwrites existing content.- Missing parent directories are created automatically.
.qwenignorepatterns are honored relative toworking_directory.- Writes are restricted to
workspace_dirs,project_temp_dir,global_temp_dir, anduser_skills_dir.
Representative write_file call shape:
{
"type": "function",
"function": {
"name": "write_file",
"arguments": {
"file_path": "/workspace/src/note.txt",
"content": "alpha\n"
}
}
}
Representative outcomes:
Successfully created and wrote to new file: /workspace/src/note.txt.
Successfully overwrote file: /workspace/src/note.txt.
File path must be absolute: src/note.txt
Edit behavior notes
The Qwen-compatible edit entrypoint is edit.
edituses literal text matching, not regex.file_pathmust be absolute.- By default,
editexpects exactly one match. - Set
replace_alltotrueto replace every occurrence ofold_string. - If
old_stringis empty and the target file does not already exist,editcreates a new file withnew_stringas its content.
Representative edit call shape:
{
"type": "function",
"function": {
"name": "edit",
"arguments": {
"file_path": "/workspace/src/note.txt",
"old_string": "alpha",
"new_string": "beta"
}
}
}
Representative outcomes:
The file: /workspace/src/note.txt has been updated.
Failed to edit, 0 occurrences found for old_string in /workspace/src/note.txt. No edits made. The exact text in old_string was not found. Ensure you're not escaping content incorrectly and check whitespace, indentation, and context. Use read_file tool to verify.
Failed to edit. Found 2 occurrences for old_string in /workspace/src/note.txt but replace_all was not enabled.
Created new file: /workspace/src/note.txt with provided content.
Reader behavior notes
The Qwen-compatible reader entrypoint is read_file.
absolute_pathmust be absolute.offsetis 0-based.limitis a line count.- Output lines are right-trimmed to match Qwen-style text rendering.
- Truncation is controlled by package config and uses the Qwen-style wrapper
beginning with
Showing lines X-Y of Z total lines. .qwenignorepatterns are honored relative toworking_directory.- Allowed read/write roots include workspace directories,
project_temp_dir,global_temp_dir, anduser_skills_dir.
Representative read_file examples:
Successful text read:
line one
line two
line three
Truncated text read:
Showing lines 1-500 of 932 total lines.
---
line one
line two
...
Representative error cases:
Error: The 'absolute_path' parameter must be non-empty.
Error: File path must be absolute, but was relative: src/app.py. You must provide an absolute path.
Error: File path '/workspace/secret.txt' is ignored by .qwenignore pattern(s).
Search behavior notes
The Qwen-compatible search entrypoints are list_directory, grep_search,
and glob.
list_directory(path, ignore?, file_filtering_options?)requires an absolute directory path.grep_search(pattern, glob?, path?, limit?)keeps the simpler Qwen shape and is case-insensitive by default.glob(pattern, path?)follows the Qwen-style path parameter and truncates long results based on package config.list_directoryreports separategit-ignoredandqwen-ignoredcounts when those filters hide entries.grep_searchandglobboth reuse the workspace/temp path allowlist used by the rest of the Qwen bundle.
Representative list_directory output:
Directory listing for /workspace/src:
[DIR] nested
alpha.txt
(1 git-ignored, 1 qwen-ignored)
Representative glob output:
Found 3 file(s) matching "*.ts" in the workspace directory, sorted by modification time (newest first):
---
/workspace/src/app.ts
/workspace/src/api.ts
---
[1 file truncated] ...
Representative grep_search output:
Found 2 matches for pattern "todo" in the workspace directory (filter: "*.py"):
---
File: /workspace/src/main.py
L4: # TODO: tighten validation
---
Shell behavior notes
The Qwen-compatible shell entrypoint is bash.
commandis the shell command to execute (required).timeoutis in milliseconds (default: 120000, max: 600000).descriptionis an optional brief description of the command purpose.directorysets the working directory for execution.is_backgroundruns the command in background mode.- Output is truncated by lines first (1000 lines), then by characters (25000).
- Background output includes platform-specific kill hint (
killortaskkill).
Representative bash call shape:
{
"type": "function",
"function": {
"name": "bash",
"arguments": {
"command": "npm run build",
"description": "Build the project",
"directory": "/workspace",
"timeout": 300000
}
}
}
Representative outcomes:
Success (no stderr):
Build completed successfully.
Failure:
Stdout: (empty)
Stderr: Build failed
Error: (none)
Exit Code: 1
Signal: (none)
Background (Unix):
Background command started. PID: 12345 (Use kill 12345 to stop)
Background (Windows):
Background command started. PID: 12345 (Use taskkill /F /T /PID 12345 to stop)
Timeout:
Stdout: (empty)
Stderr: (empty)
Error: Command timed out after 2.0 seconds
Exit Code: (none)
Signal: (none)
Truncation:
Build output line 1...
Build output line 2...
[500 lines truncated]
Web Fetch behavior notes
The Qwen-compatible web fetch entrypoint is web_fetch.
urlis the URL to fetch content from (required).promptis the prompt to run on the fetched content (required).- Content is fetched directly using HTTP GET.
- HTML content is converted to plain text using trafilatura.
- Content is truncated to
web_fetch_max_content_charscharacters. - The configured provider is used to summarize content based on the prompt.
- Supports both public and private/localhost URLs.
- Rate limited per-host (default: 10 requests per 60 seconds).
Representative web_fetch call shape:
{
"type": "function",
"function": {
"name": "web_fetch",
"arguments": {
"url": "https://example.com/article",
"prompt": "Summarize the main points of this article"
}
}
}
Representative outcomes:
Success:
[LLM-summarized content based on the prompt]
Error:
Error: Error during fetch for https://example.com: HTTP 404
Rate limited:
Error: Rate limit exceeded. Please wait 30 seconds.
Configuration
| Key | Default | Description |
|---|---|---|
web_fetch_enabled |
true |
Enable the web_fetch tool |
web_fetch_timeout_seconds |
10 |
Fetch timeout in seconds |
web_fetch_max_content_chars |
100000 |
Max content length in characters |
web_fetch_rate_limit_requests |
10 |
Max requests per window per host |
web_fetch_rate_limit_window |
60 |
Rate limit window in seconds |
web_fetch_summarization_agent_id |
null |
Optional dedicated agent for summarization |
web_fetch_summarization_model |
null |
Optional model override for summarization |
Known Limitations
- No browser rendering for JavaScript-heavy pages
- Requires a configured provider for summarization
- No special handling for private IPs (fetches all URLs directly)
Compatibility contract
Parity for this package means:
- Qwen-facing tool names and parameter names stay stable.
- Important parameter semantics match Qwen expectations.
Absolute paths, 0-based
offset,limitas line count, andeditreplacement behavior are part of that contract. - Important truncation and validation wording stays close to Qwen Code.
- The LLM-visible result content stays aligned with Qwen-style tool usage, including truncation wrappers and major read/write/edit success and error messages.
This package does not attempt to mirror Qwen Code's internal service graph or application-side orchestration.
Cross-Package Edit Comparison
The three compatibility packages intentionally preserve different public edit tool names and flags:
- Gemini uses
replace(..., allow_multiple=false)and keeps the Gemini namereplace. - Qwen uses
edit(..., replace_all=false)and keeps the Qwen nameedit. - Grok uses
str_replace_editor(..., replace_all=false)and keeps the Grok namestr_replace_editor.
If you are choosing between packages, the shared behavior is literal text replacement inside workspace-safe paths. The public name, argument names, path rules, and some validation wording stay vendor-specific.
Configuration reference
Shared package-level config keys used by the current Qwen tools:
working_directoryDefault: current working directory. Used as the display root for relative output paths and ignore-file lookup.workspace_dirsDefault: falls back toallowed_paths, then[working_directory]. Primary allowlist for file access.allowed_pathsOptional compatibility alias forworkspace_dirs.project_temp_dirDefault:<working_directory>/.temp. Additional allowed location for reads and writes.global_temp_dirDefault: system temp directory. Additional allowed location for reads and writes.user_skills_dirDefault:~/.qwen/skills. Additional allowed location for reads and writes.shell_timeout_secondsDefault:120. Default timeout for shell command execution in seconds.shell_max_timeout_secondsDefault:600. Maximum allowed timeout for shell commands.shell_max_output_linesDefault:1000. Maximum lines to return in shell output before line truncation.shell_max_output_charsDefault:25000. Maximum characters to return in shell output before char truncation.truncate_tool_output_linesDefault:500. Default line window forread_filewhenlimitis omitted.truncate_tool_output_thresholdDefault:2500. Character budget used by Qwen-style truncation.list_directoryrequires an absolutepathvalue.glob.pathandgrep_search.pathmay be omitted, in which case the currentworking_directoryis used.
Write/edit safety notes:
write_fileandeditrequire absolutefile_pathvalues.- File access is restricted to
workspace_dirs,project_temp_dir,global_temp_dir, anduser_skills_dir. .qwenignorecan block both reads and edits.editis literal, not regex-based.replace_alldefaults tofalse, so repeated text requires an explicit opt-in.- Using
old_string: ""is the package-level creation path foreditwhen the file does not already exist.
Ignore behavior:
.qwenignoreis read fromworking_directorywhen present.list_directorycan report separategit-ignoredandqwen-ignoredcounts.globandgrep_searchreuse.qwenignorefiltering and the same workspace/temp allowlist as the Qwen reader and edit tools.
Compatibility and Limitations
In scope for this package:
- Qwen-style tool names and OpenAI chat-completions function schemas
- Qwen-style absolute-path validation, truncation behavior, and major success/error wording
- Qwen-style model-visible behavior for file reads, listing, globbing, grep-style search, full-file writes, and literal replacements
Intentionally out of scope for this tool-plugin package:
- host approval and confirmation UX
- IDE integration and diff handoff flows
- telemetry and internal service behavior from Qwen Code
- exact host-managed application prompting and orchestration
That means schema parity and tool behavior parity are the goal here. CLI confirmation screens, editor handoff, and approval workflows remain host-application concerns rather than tool-plugin concerns.
Notes
The current package scope includes writer/editor tools in addition to the first reader subtask because later subtasks extended the same compatibility bundle.
License
qwen-tools is a Qwen-compatible tool plugin bundle for Crystal Lattice. Copyright 2026 Dynamic Programming Solutions Kft.
Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License.