Repository navigation
feat(core): event monitor tool with throttled stdout streaming (Phase C) #3684
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Merged
+6,297
−147
Merged
Changes from 13 commits
Commits
Show all changes
56 commits
Select commit
Hold shift + click to select a range
80dc6d5
feat(core): event monitor tool with throttled stdout streaming (Phase C)
doudouOUC 4755dc0
fix(cli): hold-back loop waits for monitors + emit task_started for SDK
doudouOUC 7637731
fix(core): Windows process kill + pipeline sleep false-positive
doudouOUC a929fd0
merge: resolve conflicts with main (task_stop/send_message + hasUnfin…
doudouOUC 614b681
fix(test): resolve TS errors in monitor.test.ts mock types
doudouOUC 6e4b930
merge: resolve conflicts with main (backgroundShellRegistry from #3642)
doudouOUC 2ba425f
fix(core): remove false notification promise + add early-abort guard
doudouOUC 08104b7
fix(test): add getMonitorRegistry mock to useGeminiStream tests
doudouOUC 2783d3e
fix(test): add getMonitorRegistry mock to nonInteractiveCli tests
doudouOUC 273b036
fix(core): address PR review — CORE_TOOLS, directory param, test fix
doudouOUC 8d39c99
fix(core): address MonitorTool review #4186888042
doudouOUC 85ea4f0
fix(core): scope monitor always-allow permissions
doudouOUC 2c577f5
fix(core): decouple monitor permission scope from Bash rules
doudouOUC 6bf6376
fix(core): unify monitor error/exit cleanup to prevent resource leaks
doudouOUC 944687f
fix(core): add user-skills-directory guard to monitor directory valid…
doudouOUC c8c1446
feat(core): add Monitor(...) permission namespace for monitor tool (#…
doudouOUC 3c35a8f
fix(cli): decouple headless monitor lifetime from final result
doudouOUC da1f712
fix(cli): stabilize stream-json monitor session shutdown
doudouOUC 2fb383c
fix(cli): deny monitor in headless approval defaults
doudouOUC dc9c62f
fix(cli): honor tool aliases in headless allow checks
doudouOUC 9ca22e8
fix(core): address opus review — sleep regex, monitor cap, non-intera…
doudouOUC fd99c25
fix(cli): abort monitors and background shells on /clear
doudouOUC eb50fed
fix(cli): abort monitors on stream-json session shutdown
doudouOUC 49d6228
test(cli): use content event type in stream tests
doudouOUC fb0d8c1
fix(cli): isolate session cleanup on clear and shutdown
doudouOUC cc2deb5
fix(cli): finalize session cleanup after drain
doudouOUC 3aabffe
fix(core): close remaining monitor review gaps
doudouOUC c53741f
fix(core): preserve shell cwd in virtual permission checks
doudouOUC eac666b
fix(core): normalize trailing background ampersands
doudouOUC 123a175
fix(core): align monitor permission and wrapper handling
doudouOUC b5de523
test(core): make monitor CI assertions cross-platform
doudouOUC 2662706
fix(core): align monitor wrapper normalization
doudouOUC 119f160
fix(core): normalize wrapped monitor commands
doudouOUC f13165b
fix(core): harden monitor headless edge cases
doudouOUC 28f4023
fix(core): preserve monitor spawn errors
doudouOUC 6826b62
fix(core): harden monitor register cleanup
doudouOUC 90a8710
fix(core): parse monitor wrapper script token
doudouOUC 8ab3a7d
merge: resolve conflicts with origin/main
doudouOUC 98502c3
fix(core): address PR review comments for monitor tool
doudouOUC ddb77ba
merge: resolve conflicts with origin/main — unify abortAll notify option
doudouOUC 0e0a1c6
fix(cli): resolve clear command typecheck issues
doudouOUC 60a4c13
fix(core): preserve background tasks across shutdown abort
doudouOUC ce6ca5a
fix(core): close monitor review gaps
doudouOUC cde5c34
fix(core): address latest monitor review comments
doudouOUC 919e8b6
fix(cli): handle monitors across session switches
doudouOUC a0c8c7b
test(core): cover aborted monitor startup
doudouOUC a010898
fix(core): address remaining monitor PR review comments
doudouOUC f01e182
fix(core): abort running monitors in MonitorRegistry.reset()
doudouOUC ba1a5da
fix(core): harden monitor notification XML and displayText
doudouOUC 0ee664f
test(core): cover token-bucket throttling and commented-sleep bypass
doudouOUC 3bc8622
fix(core): address 3 remaining copilot review comments
doudouOUC fc6c21b
fix(core): address review comments — sanitize, notify, kill logging, …
doudouOUC 0037390
fix(core): resolve monitor tool typecheck errors
doudouOUC 71adaa4
fix(monitor): add missing stdio option in taskkill test assertions (#…
Copilot 71722f1
fix(core): address monitor review feedback
doudouOUC 681dda2
fix(core): harden monitor command lifecycle
doudouOUC File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Some comments aren't visible on the classic Files Changed page.
There are no files selected for viewing
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
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,44 @@ | ||
| /** | ||
| * @license | ||
| * Copyright 2025 Qwen Team | ||
| * SPDX-License-Identifier: Apache-2.0 | ||
| */ | ||
|
|
||
| import { describe, it, expect, afterEach } from 'vitest'; | ||
| import { TestRig, validateModelOutput } from '../test-helper.js'; | ||
|
|
||
| describe('monitor-tool', () => { | ||
| let rig: TestRig; | ||
|
|
||
| afterEach(async () => { | ||
| if (rig) { | ||
| await rig.cleanup(); | ||
| } | ||
| }); | ||
|
|
||
| it('should have monitor tool registered', async () => { | ||
| rig = new TestRig(); | ||
| await rig.setup('monitor-tool-registered'); | ||
|
|
||
| const result = await rig.run( | ||
| 'Do you have access to a tool called "monitor"? Reply with just "yes" or "no".', | ||
| ); | ||
|
|
||
| validateModelOutput(result, null, 'monitor tool registered'); | ||
| expect(result.toLowerCase()).toContain('yes'); | ||
| }); | ||
|
|
||
| it('should call monitor tool when asked to watch a command', async () => { | ||
| rig = new TestRig(); | ||
| await rig.setup('monitor-tool-call'); | ||
|
|
||
| const result = await rig.run( | ||
| 'Use the monitor tool to watch this command: for i in 1 2 3; do echo "EVENT_$i"; sleep 0.3; done. ' + | ||
| 'Set description to "test events". After starting the monitor, just say "Monitor launched."', | ||
| ); | ||
|
|
||
| const foundMonitor = await rig.waitForToolCall('monitor'); | ||
| expect(foundMonitor).toBeTruthy(); | ||
| validateModelOutput(result, null, 'monitor tool call'); | ||
| }, 30000); | ||
| }); |
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
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,55 @@ | ||
| /** | ||
| * @license | ||
| * Copyright 2025 Qwen Team | ||
| * SPDX-License-Identifier: Apache-2.0 | ||
| */ | ||
|
|
||
| import { describe, it, expect, afterEach } from 'vitest'; | ||
| import { TestRig, validateModelOutput } from '../test-helper.js'; | ||
|
|
||
| describe('sleep-interception', () => { | ||
| let rig: TestRig; | ||
|
|
||
| afterEach(async () => { | ||
| if (rig) { | ||
| await rig.cleanup(); | ||
| } | ||
| }); | ||
|
|
||
| it('should block sleep >= 2s and mention Monitor in guidance', async () => { | ||
| rig = new TestRig(); | ||
| await rig.setup('sleep-blocked'); | ||
|
|
||
| const result = await rig.run( | ||
| 'Run this exact shell command: sleep 5. ' + | ||
| 'If the command is blocked, say "BLOCKED" and explain why. ' + | ||
| 'If it succeeds, say "SUCCESS".', | ||
| ); | ||
|
|
||
| validateModelOutput(result, null, 'sleep blocked'); | ||
|
|
||
| // The model should report being blocked, since sleep 5 triggers interception | ||
| const foundShell = await rig.waitForToolCall('run_shell_command'); | ||
| expect(foundShell).toBeTruthy(); | ||
|
|
||
| // The model's output should mention it was blocked | ||
| expect(result.toLowerCase()).toContain('blocked'); | ||
| }, 30000); | ||
|
|
||
| it('should allow sleep < 2s', async () => { | ||
| rig = new TestRig(); | ||
| await rig.setup('sleep-allowed'); | ||
|
|
||
| const result = await rig.run( | ||
| 'Run this exact shell command: sleep 1. Then say "DONE".', | ||
| ); | ||
|
|
||
| validateModelOutput(result, null, 'sleep allowed'); | ||
|
|
||
| const foundShell = await rig.waitForToolCall('run_shell_command'); | ||
| expect(foundShell).toBeTruthy(); | ||
|
|
||
| // Should not be blocked — model should complete successfully | ||
| expect(result.toLowerCase()).not.toContain('blocked'); | ||
| }, 30000); | ||
| }); | ||
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
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
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
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
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
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
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
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
Oops, something went wrong.
Oops, something went wrong.
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.
Uh oh!
There was an error while loading. Please reload this page.