feat(cron): add in-session loop scheduling with cron tools#2731
feat(cron): add in-session loop scheduling with cron tools#2731tanzhenxin merged 21 commits intomainfrom
Conversation
Add session-scoped recurring jobs that fire while you work. Jobs live inside the current Qwen Code process and are gone when you exit. New tools: - cron_create: schedule a prompt to run on a cron expression - cron_list: list active cron jobs - cron_delete: cancel a scheduled job Components: - CronScheduler service for in-process job management - cronParser utility for 5-field cron expressions - /loop skill for natural language scheduling - Non-interactive mode integration to keep process alive Constraints: - Max 50 jobs per session - 3-day expiry for recurring jobs - Jitter to prevent thundering herd - No catch-up for missed fire times Co-authored-by: Qwen-Coder <qwen-coder@alibabacloud.com>
📋 Review SummaryThis PR introduces an in-session cron scheduling system that enables the model to periodically check on long-running operations without user intervention. The implementation includes a cron parser, scheduler service, three new tools ( 🔍 General Feedback
🎯 Specific Feedback🔴 Critical
🟡 High
🟢 Medium
🔵 Low
✅ Highlights
|
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. |
- Add isCronDisabled mock returning true - Add getCronScheduler mock returning null This aligns test mocks with the new cron scheduler config interface. Co-authored-by: Qwen-Coder <qwen-coder@alibabacloud.com>
- Test cron_create, cron_list, cron_delete tool registration - Test create-list-delete workflow in single turn - Test one-shot (non-recurring) job creation This validates the cron scheduler tool functionality end-to-end. Co-authored-by: Qwen-Coder <qwen-coder@alibabacloud.com>
Change cron/loop tools from opt-out to opt-in. Cron tools are now
disabled by default and can be enabled via:
- settings.json: { "experimental": { "cron": true } }
- Environment variable: QWEN_CODE_ENABLE_CRON=1
This ensures experimental features are explicitly enabled by users
who want to try them.
Co-authored-by: Qwen-Coder <qwen-coder@alibabacloud.com>
…mentation - Rename cron_expression parameter to cron for brevity across CronCreateTool - Expand tool description with comprehensive usage guidance for one-shot and recurring tasks - Add best practices for avoiding :00/:30 minute marks to reduce API load spikes - Document 3-day auto-expiration for recurring jobs and session-only lifetime - Add additionalProperties: false to all cron tool schemas for stricter validation - Update integration tests and loop SKILL to use renamed parameter This improves the developer experience with clearer parameter names and provides users with detailed guidance on scheduling patterns and runtime behavior. Co-authored-by: Qwen-Coder <qwen-coder@alibabacloud.com>
…les and examples - Add detailed parsing priority order (leading token, trailing "every" clause, default) - Include concrete examples for each parsing rule - Clarify interval-to-cron conversion table with edge cases - Document rounding behavior for non-divisible intervals - Specify immediate execution after scheduling first cron fire - Update action steps with clearer confirmation requirements This enhances the /loop skill documentation to make interval parsing behavior more predictable and provides better guidance for handling edge cases. Co-authored-by: Qwen-Coder <qwen-coder@alibabacloud.com>
- Update cron-create to validate cron expression before scheduling and improve success messages with clearer session-lifetime guidance - Simplify cron-delete messages from 'deleted' to 'cancelled' for better clarity - Streamline cron-list output to single-line format per job (ID — expression (type) [session-only]: prompt) - Remove unused nextFireTime calculations from cron tools - Update corresponding tests to match new output formats This makes cron tool responses more concise and user-friendly while providing clearer information about session-only job lifetime. Co-authored-by: Qwen-Coder <qwen-coder@alibabacloud.com>
- Add getScreenText() to TerminalCapture for reading rendered xterm.js screen - Add E2E tests for in-session cron: inline firing, user priority, error resilience - Fix cron prompts not processing by adding cronTrigger state dependency This ensures cron-injected prompts are processed immediately when fired, not just when streaming state changes, and provides comprehensive test coverage for the in-session cron feature. Co-authored-by: Qwen-Coder <qwen-coder@alibabacloud.com>
- Add list and clear subcommands to loop skill - Create human-readable cron display utility for common patterns - Update tool descriptions and return displays for better UX - Separate LLM content from user-facing display in cron tools This enhances the loop skill with convenient subcommands while making cron job displays more readable by converting common cron expressions into natural language (e.g., 'Every 5 minutes' instead of '*/5 * * * *'). Co-authored-by: Qwen-Coder <qwen-coder@alibabacloud.com>
…mantics - Update cron scheduler with separate jitter strategies for recurring (up to 10% of period, capped at 15 min) and one-shot jobs (up to 90s early for :00/:30 minute marks) - Accept 7 as valid day-of-week value (Sunday) and normalize to 0 in parser - Implement vixie-cron day matching: OR logic when both dom and dow are constrained, AND logic when only one is constrained - Update tests to use every-minute cron expressions for faster execution and add coverage for new day matching behavior This improves cron job reliability by using smarter jitter calculation based on job type and fixes day-of-week matching to follow standard vixie-cron behavior where either day field can trigger execution when both are specified. Co-authored-by: Qwen-Coder <qwen-coder@alibabacloud.com>
…g features - Add scheduled-tasks.md with comprehensive guide on using /loop and CronCreate/CronList/CronDelete tools - Update _meta.ts sidebar to include new Scheduled Tasks page in documentation navigation This provides users with complete documentation for session-scoped scheduled tasks, including interval syntax, one-time reminders, task management, and scheduling behavior details. Co-authored-by: Qwen-Coder <qwen-coder@alibabacloud.com>
Also adds terminal capture test scenario for cron-loop feature. Co-authored-by: Qwen-Coder <qwen-coder@alibabacloud.com>
Move non-interactive tests to cli/, interactive tests to interactive/. Add cron-interactive.test.ts wrapping terminal-capture E2E in vitest. Update npm scripts and release workflow for new directory layout.
Use @xterm/headless (pure Node.js terminal emulator) instead of Playwright + browser-based xterm.js for cron interactive tests. Add InteractiveSession utility for future interactive tests.
- Introduce SendMessageType.Cron to differentiate cron-triggered prompts from user queries - Skip UserPromptSubmit hook for cron messages - Add getExitSummary() to display active loops when session ends - Add tests for exit summary functionality This improves cron loop handling by treating scheduled prompts differently from user-initiated queries and provides better UX when sessions end with active loops running. Co-authored-by: Qwen-Coder <qwen-coder@alibabacloud.com>
- Add cron queue and scheduler state management to Session class - Handle cron cancellation on user prompt and cancelPendingPrompt - Start cron scheduler after prompt execution completes - Drain cron queue sequentially to prevent concurrent chat access - Execute cron prompts with proper message echoing and tool handling - Add integration test for cron firing and sessionUpdate streaming This enables cron jobs created during an ACP session to fire in the background and stream results back to the client via sessionUpdate notifications, even after the originating prompt has returned. Co-authored-by: Qwen-Coder <qwen-coder@alibabacloud.com>
Keep both changes: SendMessageType.Cron skip from our branch and hasHooksForEvent check from main.
Adds missing isCronEnabled mock function to the test configuration to support the cron feature implementation. Co-authored-by: Qwen-Coder <qwen-coder@alibabacloud.com>
- Add queue-based cron processing in nonInteractiveCli for sequential execution - Block cron processing while user prompt is active in Session - Drain cron queue after prompt completion to process queued jobs - Reduce recurring task auto-expiry from 7 days to 3 days This fixes race conditions where cron jobs could fire during active prompts and ensures cron prompts are processed sequentially. Co-authored-by: Qwen-Coder <qwen-coder@alibabacloud.com>
- Scan a window of minutes around current time to find matching cron minutes - Track matched cron minute in lastFiredAt instead of wall-clock time - Add tests for positive jitter (recurring) and negative jitter (one-shot) This ensures jittered jobs fire correctly when their delayed or advanced fire time falls outside the original matching minute. Co-authored-by: Qwen-Coder <qwen-coder@alibabacloud.com>
TLDR
Add session-scoped recurring jobs ("loops") that fire while you work. Jobs live inside the current Qwen Code process and are gone when you exit. This enables the model to periodically check on long-running operations (deploys, CI, migrations) without user intervention.
New tools:
cron_create— schedule a prompt to run on a cron expressioncron_list— list active cron jobs with IDs, schedules, and next fire timescron_delete— cancel a scheduled job by IDNew skill:
/loop— natural language scheduling (e.g.,/loop 5m check the build)Screenshots / Video Demo
Dive Deeper
Problem Solved
Users kick off long-running operations and want the agent to check on them periodically without re-asking. Previously, users had to manually re-type prompts to check status.
Architecture
packages/core/src/services/cronScheduler.ts) — In-process job manager with 1-second tick intervalpackages/core/src/utils/cronParser.ts) — Minimal 5-field cron expression parser (no dependencies)Constraints
Usage Examples
Or via natural language:
Reviewer Test Plan
npm run buildnpm run test(new tests for cronParser, CronScheduler, and cron tools)npm start/loop 1m echo helloto create a recurring jobcron_listto see active jobscron_delete <id>to cancelTesting Matrix
Linked issues / bugs
No linked issues
🤖 Generated with Qwen Code