Merge upstream QwenLM/qwen-code v0.14.4#8
Open
lukemarsden wants to merge 2838 commits intomainfrom
Open
Conversation
Save approved plans to ~/.qwen/plans/{sessionId}.md so they can be
referenced later in the session or reviewed outside the CLI.
Changes:
- Storage: add getPlansDir() and getPlanFilePath()
- Config: add savePlan(), loadPlan(), getPlanFilePath() methods
- ExitPlanModeTool: persist plan to disk when user approves
- Tests: 4 new Config tests, 2 new ExitPlanModeTool assertions
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Covers configuration, JSON stdin fields, examples (model+tokens, git branch, script file), behavior details, and troubleshooting. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
- Add jq prerequisite section - Clarify that settings changes take effect without restart - Provide complete JSON in troubleshooting test command - Move script filename out of code block to avoid shebang confusion Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Add size > 0 check before computing context percentage to prevent division by zero when context_window_size is unavailable. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
The settings parser uses stripJsonComments + JSON.parse, which does not support trailing commas. Changed the config example from jsonc to json and removed trailing commas so users can copy-paste safely. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
- Fix "three distinct permission modes" → "four" (Plan was always listed) - Update refactor example to use /plan command instead of /approval-mode - Fix grammar in example description Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Use echo "$input" instead of echo $input for proper shell variable quoting, consistent with the script file example. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
PS1 \n should be removed or replaced with a space since the status line only displays the first line of stdout. Also added a guideline that commands must produce exactly one line of output. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
- Footer comment now accurately states only the "? for shortcuts" hint is suppressed, not all left-section items - Docs now note that Windows uses cmd.exe by default and suggest wrapping commands with bash -c or using a bash script Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Inline shell snippets need sh -c to execute via pipe, matching how child_process.exec() runs the configured command. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
"Use the Agent tool with subagent_type" is more direct than "Create an Agent", reducing ambiguity for the model. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
…, autofix, and security hardening
Comprehensive improvements to the /review skill based on competitive analysis
of Copilot Code Review, Claude Code /ultrareview, and Gemini CLI async-pr-review.
Key changes (all prompt-only, no TypeScript code changes):
- P0: Integrate linter/typecheck (Step 1.5) — run project tools before LLM agents,
with error/warning severity distinction
- P1: Add Agent 5 for build & test verification with env/code failure distinction
- P1: Cross-file impact analysis for Agents 1-4 with 10-symbol prioritization limit
- P1: Project custom review rules (.qwen/review-rules.md, copilot-instructions.md,
AGENTS.md, QWEN.md) with base-branch reading for PR security
- P2: Autofix with user confirmation, PR branch commit, and verdict split
(terminal vs PR submission)
- P2: Pattern aggregation for same-type findings across locations
- P2: Confidence levels (high/low) with "Needs Human Review" section
- P2: Skip "Nice to have" from PR inline comments to reduce noise
- P3: Incremental review via .qwen/review-cache/ with rebase fallback
- P3: Report persistence to .qwen/reviews/ with timestamp filenames
Security hardening:
- PR description prompt injection defense (untrusted DATA marker)
- Base-branch rule loading prevents review-bypass injection
- Concurrency-safe temp file paths with {target} suffix
- Safe git stash handling (conditional pop)
- Argument disambiguation (integer vs URL vs file path)
Audited through 14 rounds of undirected review with 40 issues found and fixed.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
- Add tsc --incremental flag to speed up repeated type checks
- Increase type checker timeout to 120s (linters remain 60s)
- Improve cross-file grep patterns to cover .functionName, import { functionName }
- Don't truncate Critical pattern groups — list all locations
- Clarify pre-commit hook as a commit failure scenario in autofix
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
…atus Per maintainer review (tanzhenxin): default verboseMode reverted to true to preserve existing behavior — compact mode is opt-in via Ctrl+O. Also addresses wenshao's security concern: in compact mode, tool groups now force-expand on Error status (in addition to existing Confirming handling), and ToolMessage force-shows result for both Confirming and Error statuses so users always see diffs before approval and error details for debugging. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
- Fix filter-then-truncate ordering: capture full linter output first, filter to changed files, then truncate (not head before filter) - Record informational notes for skipped checks instead of silent skip - Agent 5: capture full build/test output, keep first 50 + last 100 lines instead of tail-only (preserves error context) - Fix [Needs Review] vs severity tag contradiction: use both [Needs Review][Suggestion] format Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
- Fix Step 1.5 intro: clarify whole-project vs per-file tool handling and filter-then-report approach - Fix dedup + deterministic finding ambiguity: merged findings with any deterministic source are pre-confirmed and skip verification - Fix autofix stash orphan: stop and let user handle commit failure instead of silently stashing (which Step 5 wouldn't pop) Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
The autofix step (Step 3.5) needs targeted text replacement to apply fixes safely. Without the edit tool, only full-file rewrites via write_file would be available, which is risky for partial fixes. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
- Fix golangci-lint: use ./... (package pattern) instead of file paths - Unify PR comment prefix format: define canonical prefixes for normal, auto-fixed, and low-confidence findings in the template - Stop workflow entirely on autofix commit failure (dirty tree would block Step 5 branch restore) - Accept broader .gitignore patterns like .qwen/* for cache/reviews dirs Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
- Add Source field to Step 2 output schema (Agents 1-4: [review], Agent 5: [build]/[test]) so Step 2.5 dedup can detect pre-confirmed - Require Agent 5 to emit [build]/[test] tags explicitly - Use grep -F (fixed-string) instead of -E regex for cross-file search to avoid metacharacter issues with JS symbols like $ Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
After presenting findings for a PR review, append a tip: "Tip: run /review <number> --comment to post these as PR inline comments." This leverages the existing follow-up suggestion system — it will read the tip in context and likely suggest the command as ghost text, letting users discover the feature via Tab without blocking prompts. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
- Fix Source vs Issue field inconsistency: deterministic findings now use Source field ([linter]/[typecheck]) consistently with the schema - Add base branch ref resolution with origin/<base> fallback and git fetch for fresh/non-standard checkouts Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
When PR checkout fails or incremental review finds no new changes, restore the environment (checkout original branch, pop stash) before stopping. Previously these early exits left the stash orphaned. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
When deduplication merges findings with different severities (e.g., a Critical typecheck error with a Suggestion from LLM review), the merged finding now uses the highest severity. Deterministic severity is treated as authoritative and cannot be downgraded. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Step 1.5 said "the diff output" (singular) but local reviews produce two diffs (git diff + git diff --staged). Changed files list now explicitly takes the union of both. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Add {{model}} template variable support in BundledSkillLoader. When a
skill body contains {{model}}, it is replaced with the runtime model ID
from config.getModel(). Only skills that use the variable are affected.
The /review skill now appends a model attribution footer to PR review
summaries: "Reviewed by {model} via Qwen Code /review"
This enables cross-model review workflows (e.g., develop with model A,
review with model B) with accurate attribution in PR comments.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
- Copilot-instructions.md precedence: prefer .github/ path, do not load both when both exist - Simplify getModel() call: remove unnecessary typeof guard since Config already defines getModel() - Fix TS2352 type error in test: use proper mock cast pattern - Add getModel to base mockConfig for test consistency Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Rename "should use unknown when model is not available" to "when getModel returns undefined" — the mock config does define getModel, it just returns undefined. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
…ment (QwenLM#3207) Add news item about: - Daily quota reduced from 1,000 to 100 requests/day - Free tier discontinuation on 2026-04-15 - Migration path to Alibaba Cloud Coding Plan Co-authored-by: Qwen-Coder <qwen-coder@alibabacloud.com>
…chable (QwenLM#3181) * fix(cli): recover from stuck bracketed-paste mode and keep Ctrl+C reachable If bracketed-paste-start (`ESC[200~`) arrives but paste-end (`ESC[201~`) is lost — for example on Ghostty + Sogou pinyin on macOS, which a user reported in a working directory with only three files — `isPaste` stays `true` forever. The order of checks inside `handleKeypress`: 1. `key.name === 'paste-start'` → set isPaste = true, return 2. `key.name === 'paste-end'` → reset + flush + return 3. `if (isPaste) { pasteBuffer.append; return }` 4. backslash / return handling 5. arrow keys 6. Ctrl+C means that every subsequent key — **including Ctrl+C** — is appended to the paste buffer and silently returned. The user has no keyboard escape hatch; they must kill the process / restart the terminal. Two layered fixes: 1. **Ctrl+C escape hatch.** Move the Ctrl+C check above the `isPaste` branch and clear paste state when it fires. Ctrl+C now always reaches the broadcast regardless of any stuck paste state. 2. **Idle timeout auto-recovery.** Add `PASTE_IDLE_TIMEOUT_MS = 1000`. Start the timer on paste-start, reset it on each paste content byte, clear it on paste-end. If the timer fires, force-flush the paste buffer as a regular paste event and reset `isPaste`. A `pasteAlreadyFlushed` flag guards against a stale paste-end event arriving later and broadcasting a spurious empty/image paste. Two regression tests cover both paths: - `Ctrl+C escapes a paste mode that never received its paste-end marker` - `auto-recovers from a stuck paste mode via idle timeout` Both fail on main and pass with this change. Full cli test suite: 3968 pass / 7 skipped, no regressions. * test(cli): derive paste idle-timeout wait from PASTE_IDLE_TIMEOUT_MS Address review feedback: the auto-recovery regression test hard-coded a 1500ms sleep instead of referencing the production constant. Import PASTE_IDLE_TIMEOUT_MS and derive the wait as `constant + 200ms buffer` so the test stays in sync if the production timeout is ever tuned. * docs(cli): clarify paste state-machine comments from review feedback Address review bot nits: - forceFlushStuckPaste: explain why the empty-guard is asymmetric (isPaste/buffer can be out of sync after a Ctrl+C vs idle-timeout race) - paste-end handler: note that pasteAlreadyFlushed=false is the reset for the next paste cycle - auto-recovers test: frame it as the "automatic recovery safety net" counterpart to the manual Ctrl+C escape test above Comments only, no behavioural change.
…enLM#3199) Remove directories and files that are no longer needed for Qwen Code: - .gcp/: Google Cloud Platform build configs (legacy from Gemini CLI) - .aoneci/: Alibaba AoneCI workflow (replaced by GitHub Actions) - hello/: Example extension template (not needed in repo root) - .allstar/: Google Allstar security policy config (Google legacy artifact) These artifacts are either obsolete or superseded by GitHub Actions workflows and the current Dockerfile. Co-authored-by: Qwen-Coder <qwen-coder@alibabacloud.com>
* refactor: merge test-utils package into core Consolidate the standalone @qwen-code/qwen-code-test-utils package into packages/core/src/test-utils/, eliminating the need for a separate package that only provided createTmpDir, cleanupTmpDir, and FileSystemStructure type. Changes: - Move file-system-test-helpers.ts into core/src/test-utils/ - Re-export from core's test-utils index - Update 3 core test files to use relative imports - Update cli useAtCompletion test to import from @qwen-code/qwen-code-core - Remove test-utils devDependency from core and cli package.json - Delete packages/test-utils/ directory All affected tests pass (fileSearch, crawler, ignore, useAtCompletion). Co-authored-by: Qwen-Coder <qwen-coder@alibabacloud.com> * fix: remove deleted test-utils from build order The test-utils package was merged into core but the build script still tried to build it separately, causing CI failures. Co-authored-by: Qwen-Coder <qwen-coder@alibabacloud.com> --------- Co-authored-by: Qwen-Coder <qwen-coder@alibabacloud.com>
) - Change default model from qwen3.6-plus to qwen3.5-plus for both China and Global regions - qwen3.6-plus requires Pro subscription, Lite users cannot use it - Add description to qwen3.6-plus indicating Pro subscription requirement - Update MAINLINE_CODER_MODEL to qwen3.5-plus for OpenAI-compatible API default Fixes QwenLM#3037 Co-authored-by: Qwen-Coder <qwen-coder@alibabacloud.com>
* ci(release): parallelize release validation * ci(release): allow publish when tests are skipped * ci(release): drop planning artifact from workflow PR * ci(release): address workflow review findings * ci(release): fix quality job bootstrap * ci(release): fix docker test and dry-run notify flow
…QwenLM#2904) * feat: add contextual tips system with post-response context awareness Add a context-aware tips system that proactively shows helpful tips based on session state. Post-response tips warn when context usage exceeds 80% or 95%, suggesting /compress. Startup tips rotate across sessions via LRU scheduling with cross-session persistence (~/.qwen/tip_history.json). Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com> * fix: use value import for runtime values in useContextualTips Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com> * fix: address PR review feedback - Use lastSessionTimestamp instead of totalShown for cross-session LRU - Move getTipHistory singleton from Tips.tsx to services/tips/index.ts - Defer TipHistory.load() when hideTips is true (no side effects) - Use os.tmpdir() in tests for cross-platform portability - Add proper translations for de/ja/pt/ru locale files - Accept TipHistory | null in useContextualTips Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com> * fix: address Copilot review feedback - Validate tips field type in TipHistory.load() to handle corrupted JSON - Split approval-mode tip into platform-specific variants using ctx.platform - Add afterEach cleanup for temp files in all test suites - Guard useContextualTips against null tipHistory Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com> * fix: import shared DEFAULT_TOKEN_LIMIT, harden tipHistory, set file permissions - Import DEFAULT_TOKEN_LIMIT from @qwen-code/qwen-code-core instead of hardcoding 1_048_576 in tipRegistry.ts and useContextualTips.ts - Add normalizeEntry() to defensively handle corrupted tip history entries - Write tip_history.json with mode 0o600 for privacy on multi-user systems Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com> * fix: remove unused compressionThreshold from TipContext compressionThreshold was defined in TipContext but never used by any tip's isRelevant check. Remove it to avoid misleading consumers into thinking tips respect the user's compression settings. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com> * fix: sanitize sessionCount and getLastShown against corrupted tip history - Validate sessionCount is finite and non-negative in TipHistory.load() - Use normalizeEntry() in getLastShown() for corrupted lastSessionTimestamp Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com> * docs: add contextual tips user documentation Add docs/users/features/tips.md covering startup tips, post-response context warnings, tip history persistence, and the hideTips setting. Update settings.md description and register the new page in _meta.ts. --------- Co-authored-by: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
* feat(subagents): propagate approval mode to sub-agents Replace hardcoded PermissionMode.Default with resolution logic: - Permissive parent modes (yolo, auto-edit) always win - Plan-mode parents keep sub-agents in plan mode - Agent definitions can declare approvalMode in frontmatter - Default fallback is auto-edit in trusted folders - Untrusted folders block privileged mode escalation Also maps Claude permission aliases (acceptEdits, bypassPermissions, dontAsk) to qwen-code approval modes in the converter. * fix(subagents): correct dontAsk mapping and add approval mode resolution tests Map Claude's `dontAsk` to `default` instead of `auto-edit` — `dontAsk` denies prompts (restrictive) so `default` is a closer semantic match. Add 9 unit tests covering the full `resolveSubagentApprovalMode` decision matrix: permissive parent override, agent-declared modes, trusted/untrusted folder blocking, and plan-mode fallback. * test: remove flaky InputPrompt tab-suggestion test on Windows
…wenLM#3197) pathReader.ts hardcoded respectGitIgnore: true when filtering files for @{path} injection (used by slash commands), ignoring the user's context.fileFiltering.respectGitIgnore setting. This meant gitignored files were silently dropped even when the user explicitly set the setting to false. Now reads the filtering options from config instead of hardcoding. Fixes QwenLM#3142
…M#2949) * feat(skills): add model override support via skill frontmatter Allow skills to specify a `model` field in YAML frontmatter to override which model is used for subsequent turns within the same agentic loop. The override flows through ToolResult → ToolCallResponseInfo → SendMessageOptions and naturally expires when the loop ends. Resolves QwenLM#2052 * fix(core): only include modelOverride in response when defined Fixes strict equality test failures in nonInteractiveToolExecutor.test.ts where the extra undefined modelOverride field caused object mismatch. * fix(skills): fix model override pipeline issues - Wire up modelOverride in interactive CLI path (useGeminiStream) - Fix inherit/no-model unable to clear a prior override by using 'in' operator instead of truthiness checks in scheduler and CLI - Reject empty/whitespace model strings in parseModelField() - Extract shared parseModelField() to deduplicate skill-load and skill-manager parsing logic - Propagate modelOverride through stop-hook continuation in client * fix(skills): persist model override across turns in interactive and cron paths The interactive path stored the skill model override in a local variable, causing it to be lost when subsequent non-skill tool turns ran. Use a ref to persist the override for the duration of the agentic loop, resetting on new user messages. Also propagate modelOverride in the cron execution loop for consistency with the main non-interactive path. * fix(skills): preserve model override on retry and add unit tests Retry in interactive mode was clearing modelOverrideRef, causing the skill-selected model to silently fall back to session default. Guard the reset so retries preserve the active override. Add unit tests for parseModelField (edge cases, type validation) and modelOverride propagation through the skill tool result path.
…M#3192) * fix(core): show clear error when MCP server cwd does not exist Validate that the configured cwd directory exists before spawning the MCP server process. Previously, a non-existent cwd caused Node.js to emit "spawn <cmd> ENOENT" — indistinguishable from the command binary being missing. Now throws a descriptive error naming the server and the missing path. Fixes QwenLM#3163 * test(core): add test for MCP stdio transport without cwd
…wenLM#3187) validateAuthMethod's pre-flight check only inspected OPENAI_API_KEY (and settings.security.auth.apiKey), so credentials supplied via --openai-api-key were rejected even though refreshAuth would have accepted them. macOS users were unaffected because OPENAI_API_KEY is commonly exported in their shell profile; on Linux without that env var, the CLI failed to start. hasApiKeyForAuth now prefers the API key already resolved into generationConfig.apiKey when a Config is provided. The unified resolver folds CLI flags, env vars, settings, and modelProvider envKey lookups into this single value, so validation matches runtime behavior. Fixes QwenLM#3171
Co-authored-by: Qwen-Coder <qwen-coder@alibabacloud.com>
When ESC (or Ctrl+C) cancelled an in-progress model response, the input buffer was being repopulated with the just-submitted prompt. The handler unconditionally read userMessages.at(-1) and called buffer.setText with it, surprising users who expected ESC to leave the input clean. The previous prompt is still recoverable via Up arrow / Ctrl+P history navigation. Queued follow-up messages still get moved into the buffer for editing on cancel, but now via the atomic popAllMessages helper, and any in-progress draft the user typed is preserved by prepending the queued text instead of clobbering it (matching the existing popQueueIntoInput convention in InputPrompt). Fixes QwenLM#3204
Typing `exit`, `quit`, `:q`, `:q!`, `:wq`, or `:wq!` at the prompt now exits the CLI — same as `/quit`. This matches Claude Code behavior and helps users on mobile (e.g. Termux) where Ctrl+C is harder to type. Closes QwenLM#3169
…LM#3064) * feat(subagents): add disallowedTools field to agent definitions Add a `disallowedTools` blocklist to agent frontmatter, letting agents specify tools they should not have access to. Supports exact tool names, MCP server-level patterns (e.g., `mcp__slack`), and display name aliases. Applied as a post-filter in AgentCore.prepareTools() after the existing `tools` allowlist. Persisted through serialize/parse roundtrips. * docs: document disallowedTools and MCP tool behavior for subagents Add Tool Configuration section to sub-agents docs explaining: - tools allowlist and disallowedTools blocklist - How MCP tools follow the same allowlist/blocklist rules - MCP server-level patterns in disallowedTools * fix(subagents): validate disallowedTools in SubagentValidator Reuse the existing validateTools() method to validate disallowedTools entries at config validation time, catching non-string and empty entries before they reach runtime. * test: remove flaky BaseSelectionList scroll test on Windows
The agent name validation regex only permitted ASCII letters, numbers,
hyphens, and underscores, silently rejecting agents with non-ASCII names
(e.g., Chinese "项目管理"). Replace the regex with Unicode property
escapes (\p{L}\p{N}) to allow letters and numbers from any script.
Also guard the lowercase naming convention warning so it only fires when
the name contains ASCII letters, since case is meaningless for CJK
scripts.
Fixes QwenLM#3149
* feat(core): add microcompaction for idle context cleanup
Clear old tool result content from chat history when the user returns
after an idle period (default 60 min). Replaces functionResponse output
with a sentinel string for compactable tools (read_file, shell, grep,
glob, web_fetch, web_search, edit, write_file), keeping the N most
recent results intact (default 5). Runs before full compression so it
can shed tokens cheaply without an API call.
- Time-based trigger reuses lastApiCompletionTimestamp from thinking cleanup
- Per-part counting so keepRecent applies to individual tool results
even when batched in parallel
- Preserves tool error responses (only clears successful outputs)
- Configurable via settings.json (context.microcompaction) with env var
overrides for E2E testing
- Enabled by default
* refactor(config): unify idle cleanup settings under clearContextOnIdle
Consolidate thinking block cleanup and tool results microcompaction
config into a single `context.clearContextOnIdle` settings group:
{
"context": {
"clearContextOnIdle": {
"thinkingThresholdMinutes": 5,
"toolResultsThresholdMinutes": 60,
"toolResultsNumToKeep": 5
}
}
}
- Use -1 on either threshold to disable that cleanup (no enabled bool)
- Remove separate `microcompaction` and `gapThresholdMinutes` settings
- Thinking cleanup: 5 min default (unchanged)
- Tool results cleanup: 60 min default
- Preserve tool error responses (only clear successful outputs)
* feat(vscode-ide-companion): add clearContextOnIdle settings configuration
- Add gapThresholdMinutes settings for thinking blocks, tool results, and retention count
- Remove deprecated gapThresholdMinutes from root settings level
This reorganizes the context clearing settings into a dedicated clearContextOnIdle object with configurable thresholds for thinking blocks and tool results.
Co-authored-by: Qwen-Coder <qwen-coder@alibabacloud.com>
* fix(core): restrict microcompaction to user-initiated messages only
Move microcompactHistory() inside the UserQuery/Cron guard so model
latency during tool-call loops doesn't count as user idle time.
* docs: update settings docs for clearContextOnIdle config rename
Replace stale `context.gapThresholdMinutes` entry with the new
`context.clearContextOnIdle.*` settings group introduced in the
microcompaction feature.
* fix(core): address review comments on microcompaction PR
- Guard against NaN in toolResultsNumToKeep with Number.isFinite()
- Report effective keepRecent (after Math.max) in meta, not raw config
- Fix comment to mention cron messages alongside user messages
---------
Co-authored-by: Qwen-Coder <qwen-coder@alibabacloud.com>
…wenLM#3217) * docs: update quota exceeded alternatives to OpenRouter and Fireworks - Update README.md news section to recommend OpenRouter and Fireworks as primary alternatives, with ModelStudio as third option - Update retry.ts quota error message to include OpenRouter and Fireworks URLs for users whose OAuth quota has been exhausted Co-authored-by: Qwen-Coder <qwen-coder@alibabacloud.com> * fix(test): update retry test assertions to match new quota error message * docs: update free tier quota to 100 req/day with sunset notice and alternatives Update all references to reflect the Qwen OAuth free tier policy change: - 1,000 → 100 requests/day across code, i18n, and docs - Add 2026-04-15 sunset date everywhere - Guide users to OpenRouter, Fireworks AI, or ModelStudio in docs - Remove CHANGELOG.md --------- Co-authored-by: Qwen-Coder <qwen-coder@alibabacloud.com> Co-authored-by: tanzhenxin <tanzhenxing1987@gmail.com>
… SDK API (QwenLM#2916) * feat(cli): implement non-interactive /context output and diagnostic - Extract collectContextData() from contextCommand.ts for shared usage. - Register /context in ALLOWED_BUILTIN_COMMANDS_NON_INTERACTIVE. - Extend SDK control protocol with GET_CONTEXT_USAGE request. - Implement handleGetContextUsage in SystemController for programmatic token queries. - Expose getContextUsage() method in the TypeScript SDK Query interface. * fix: address review feedback and fix critical bugs in context usage feature - Add missing `get_context_usage` route in ControlDispatcher (SDK calls would throw) - Fix `executionMode` defaulting: use `?? 'interactive'` to match other commands - Validate dynamic import of `collectContextData` before invoking - Preserve original error message in handleGetContextUsage catch block - Add ControlDispatcher test for get_context_usage routing - Add JSDoc comment for context command in non-interactive allowlist Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com> * fix: re-check abort signal after async operations in handleGetContextUsage Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com> * docs: add getContextUsage() to SDK TypeScript documentation Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com> * docs: clarify getContextUsage showDetails is a display hint, not a data filter Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com> * fix: make showDetails affect response shape, add getContextUsage test - When showDetails is false, return empty detail arrays instead of full data so /context and /context detail produce different payloads - Add unit test for Query.getContextUsage() covering request payload and response handling * fix: strip UI type from SDK response, sync Java SDK protocol - Remove leaked `type: 'context_usage'` from control response payload - Add GET_CONTEXT_USAGE to Java SDK protocol mirror (enum, interface, union type) --------- Co-authored-by: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
feat(cli): add startup performance profiler (QwenLM#3219) Add a lightweight startup profiler activated via QWEN_CODE_PROFILE_STARTUP=1. When enabled, collects performance.now() timestamps at 7 key phases in main() and writes a JSON report to ~/.qwen/startup-perf/. Also records process.uptime() at T0 to capture module loading time not covered by checkpoint-based measurement. Key design decisions: - Only profiles inside sandbox child process to avoid duplicate reports - initStartupProfiler() is idempotent (resets state on each call) - Filename uses report.sessionId for consistency with JSON content - Zero overhead when disabled (single env var check) Initial measurement: module loading ~1342ms (94%), main() ~85ms (6%), confirming barrel exports and eager dependency loading as primary optimization targets for QwenLM#3011. Co-authored-by: Qwen-Coder <qwen-coder@alibabacloud.com>
* feat(core): implement fork subagent for context sharing
- Make subagent_type optional in AgentTool
- Add forkSubagent.ts to build identical tool result prefixes
- Run fork processes in the background to preserve UX
* fix(core): fix test failures related to root execution and optional subagent_type
- Skip pathReader and edit tool permission tests when running as root
- Fix agent.test.ts to correctly mock execute call with extraHistory
- Remove unused imports in forkSubagent.ts
* fix(core): fix fork subagent bugs and add CacheSafeParams integration
Bug fixes:
- Fix AgentParams.subagent_type type: string -> string? (match schema)
- Fix undefined agentType passed to hook system (fallback to subagentConfig.name)
- Fix hook continuation missing extraHistory parameter
- Fix functionResponse missing id field (match coreToolScheduler pattern)
- Fix consecutive user messages in Gemini API (ensure history ends with model)
- Fix duplicate task_prompt when directive already in extraHistory
- Fix FORK_AGENT.systemPrompt empty string causing createChat to throw
- Fix redundant dynamic import of forkSubagent.js (merge into single import)
- Fix non-fork agent returning empty string on execution failure
- Fix misleading fork child rule referencing non-existent system prompt config
- Fix functionResponse.response key from {result:} to {output:} for consistency
CacheSafeParams integration:
- Retrieve parent's generationConfig via getCacheSafeParams() for cache sharing
- Add generationConfigOverride to CreateChatOptions and AgentHeadless.execute()
- Add toolsOverride to AgentHeadless.execute() for parent tool declarations
- Fork API requests now share byte-identical prefix with parent (DashScope cache hits)
- Graceful degradation when CacheSafeParams unavailable (first turn)
Docs:
- Add Fork Subagent section to sub-agents.md user manual
- Add fork-subagent-design.md design document
* fix(core): apply subagent tool exclusion to forked agents
Fork children were inheriting parent's cached tool declarations directly,
bypassing prepareTools() filtering and gaining access to AgentTool and
cron tools. Extract EXCLUDED_TOOLS_FOR_SUBAGENTS as a shared constant
and apply it to forkToolsOverride.
* fix(core): skip env history whenever extraHistory is provided
Previously gated on generationConfigOverride, which meant the no-cache
fallback path (CacheSafeParams unavailable) still ran getInitialChatHistory
and duplicated env bootstrap messages already present in the parent's
history. Gate on extraHistory instead so both fork paths skip env init.
* fix(core): use explicit skipEnvHistory flag for fork env handling
The previous fix gated env-init skipping on the presence of extraHistory,
but agent-interactive (arena) also passes extraHistory — its chatHistory is
env-stripped by stripStartupContext() and DOES need fresh env init for the
child's working directory. Skipping env there broke the interactive path.
Replace the implicit gate with an explicit skipEnvHistory option that only
fork sets (when extraHistory is present, since fork's history comes from
getHistory(true) and already contains env).
* fix(core): defend skipEnvHistory gate against empty extraHistory
Edge case: when the parent's rawHistory ends with a user message and has
length 1, extraHistory becomes []. The previous gate (extraHistory !==
undefined) would set skipEnvHistory: true, leaving the fork with neither
env bootstrap nor parent history. Check length > 0 so empty arrays fall
through to the normal env-init path.
* fix(core): apply skipEnvHistory to stop-hook retry execute
The second subagent.execute() call in the SubagentStop retry loop was
missing skipEnvHistory, so on retry the fork's env context would be
duplicated — same bug as the initial tanzhenxin report, just on a less
common code path.
…2984) * feat(vscode-ide-companion): add /account for account display * fix(account): intercept typed /account command and read session-level config 1. Handle literal /account in useMessageSubmit.ts so typing it triggers the account dialog instead of sending it as a chat message. 2. Pass sessionId through extMethod params and read from session config instead of agent-level config, so /account reflects model changes made via /model within the current session. Co-authored-by: Qwen-Coder <qwen-coder@alibabacloud.com> --------- Co-authored-by: Qwen-Coder <qwen-coder@alibabacloud.com>
…3246) DashScope throttling (`Throttling.AllocationQuota`) surfaces as an SSE `event:error` frame mid-stream with `:HTTP_STATUS/429` as a comment and a non-numeric `code` in the payload. The existing detection paths missed it, so subagents failed immediately with `Failed to run subagent: id:1 event:error ...` instead of retrying. - `getErrorStatus`: add a final fallback that parses `HTTP_STATUS/NNN` out of `error.message`, bounded by `\b` and the 100-599 range, so streamed errors where the SDK never sees a real HTTP status can still be classified. - `getErrorCode`: fix three `|| null` early-returns that swallowed later fall-through paths when the provider code was non-numeric (`isApiError` top-level, `isApiError` JSON-in-message, and `isStructuredError`). The branches now fall through on non-numeric values so `.status` or the new `HTTP_STATUS/NNN` fallback can recover the real code.
…ow (QwenLM#3249) * fix(vscode): limit session tab title length to prevent tab bar overflow - Extract truncatePanelTitle() into panelTitleUtils.ts; operates on Unicode code points to avoid splitting surrogate pairs (e.g. emoji); truncates to first 50 code points + '…' - Apply truncation uniformly in WebViewProvider for all updatePanelTitle messages, covering both createOrShowPanel and restorePanel paths - Remove redundant 50-char truncation in SessionMessageHandler; panel title truncation is now the sole responsibility of WebViewProvider - Align getSessionTitle() to use the same limit (50 code points + '…') for visual consistency between session list and tab title - Add unit tests for truncatePanelTitle covering empty string, boundary, long title, and emoji surrogate-pair edge cases Fixes QwenLM#2873 Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com> * refactor(vscode): reuse truncatePanelTitle in getSessionTitle and fix fallback title logic --------- Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com>
Merges upstream main (v0.14.4) into our fork (previously at v0.4.1). ~10 major version jump with ~2800 new upstream commits. Conflict resolution (11 files): - Took upstream: acpAgent.ts, cli/errors.ts, edit.ts, glob.ts, shell-utils.ts, tools.ts - Deleted (upstream removed): schema.ts, smart-edit.ts - Manual merge: chatRecordingService.ts, ls.ts, paths.ts Cleaned up fork debug logging in: HistoryReplayer.ts, Session.ts, config.ts, sessionService.ts Fork changes kept: bind-mount path normalization, QWEN_DATA_DIR, is_background instruction, XML tool call suppression, callId queue fix Fork changes dropped: schema.ts, smart-edit.ts, ACP v0.10.0 alignment, debug logging, error display fix, shell security disabling
| {iconUrl && ( | ||
| <div className="relative"> | ||
| <img | ||
| src={iconUrl} |
| this.sendToWebView({ | ||
| type: 'sessionTitleUpdated', | ||
| data: { | ||
| sessionId: this.currentConversationId, |
| // macOS/Linux: All VSCode-like IDEs (VSCode, Cursor, Windsurf, etc.) | ||
| // are Electron-based, so we always need ELECTRON_RUN_AS_NODE=1 | ||
| // to run Node.js scripts using the IDE's bundled runtime. | ||
| const quotePosix = (s: string) => `"${s.replace(/"/g, '\\"')}"`; |
| // On Windows, we rely on the race logic below to handle background tasks. | ||
| // We just ensure the command string is clean. | ||
| if (isWindows && shouldRunInBackground) { | ||
| finalCommand = finalCommand.trim().replace(/&+$/, '').trim(); |
Comment on lines
+55
to
+59
| return str.replace(regex, (match, key) => | ||
| context[key as keyof VariableContext] == null | ||
| ? match | ||
| : (context[key as keyof VariableContext] as string), | ||
| ); |
Comment on lines
+11
to
+12
| return text | ||
| .replace(/```[\s\S]*?\n([\s\S]*?)```/g, '$1') |
| }); | ||
| } catch { | ||
| // Fallback to plain text for the failed chunk only | ||
| await this.bot.api.sendMessage(chatId, chunk.replace(/<[^>]*>/g, '')); |
Comment on lines
+790
to
+793
| proxyProcess = spawn(proxyShell, proxyShellArgs, { | ||
| stdio: ['ignore', 'pipe', 'pipe'], | ||
| detached: true, | ||
| }); |
| buildArgs += `-f ${path.resolve(projectSandboxDockerfile)} -i ${image}`; | ||
| } | ||
| execSync( | ||
| `cd ${gcRoot} && node scripts/build_sandbox.js -s ${buildArgs}`, |
| // Fallback to 'bash' and let the system handle it | ||
| cachedBashPath = 'bash'; | ||
| return 'bash'; | ||
| } |
Code Coverage Summary
CLI Package - Full Text ReportCore Package - Full Text ReportFor detailed HTML reports, please see the 'coverage-reports-22.x-ubuntu-latest' artifact from the main CI run. |
- QwenLogger.getInstance() now unconditionally returns undefined, preventing any events from being collected or sent to Alibaba's RUM endpoint (gb4w8c3ygj-default-sea.rum.aliyuncs.com) - Change usageStatisticsEnabled default from true to false in both settingsSchema.ts and config.ts - Gut updateCheck.ts to always return null, preventing npm registry queries for version checks (our fork is not published to npm) - OpenTelemetry OTLP left intact (defaults to localhost:4317, requires explicit opt-in, useful for our own observability) Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
Merges upstream
QwenLM/qwen-codemain (v0.14.4) into our fork, which was pinned at v0.4.1. This is a ~10 major version jump bringing in ~2800 upstream commits with significant improvements to ACP protocol support (now using@agentclientprotocol/sdkv0.14.1), new features (fork subagents, startup profiler, hooks), and bug fixes.Changes
schema.ts,smart-edit.ts), manually merged 3 filesconsole.errorstatements) from 4 files that the linter flaggedQWEN_DATA_DIRenv var, shell prompt customizations (is_background, XML tool call suppression), session history callId queue fix[object Object]error fix, shell security disablingWhat was kept from our fork
normalizeProjectPath()inpaths.ts— handles bind-mount path equivalence for containerized environmentsnormalizeProjectPathusage inchatRecordingService.ts— ensures session hashing works across bind-mount pathsQWEN_DATA_DIRinstorage.ts— persistent storage location override (consider migrating to upstream'sQWEN_RUNTIME_DIR)prompts.ts—is_backgroundparameter instruction and XML tool call suppressiongetErrorMessageimport retained inls.tswhere still usedWhat was dropped
schema.ts— custom Zod-based ACP type definitions, superseded by@agentclientprotocol/sdktypessmart-edit.ts— tool removed by upstream entirelyconsole.errorlogging — 6 commits worth of temporary debugging statementsNotes for review
QWEN_DATA_DIRenv var may want to be migrated to upstream'sQWEN_RUNTIME_DIRpattern in a follow-up🔗 Open in Helix
📋 Spec:
🚀 Built with Helix