You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Add the built-in tool run_command_in_terminal for AI to execute commands in the connected PowerShell session (#398)
Allow AIShell to run command in the connected PowerShell session and collect all output and error.
1. Add `Invoke-AICommand` cmdlet (alias: `airun`) to `AIShell` module. Commands sent from the sidecar AIShell will be executed through this command in the form of `airun { <command> }`. This command is designed to collect all output and error messages as they are displayed in the terminal, while preserving the streaming behavior as expected.
2. Add `RunCommand` and `PostResult` messages to the protocol.
3. Update the `Channel` class in `AIShell` module to support the `OnRunCommand` action. We already support posting command to the PowerShell's prompt, but it turns out not easy to make the command be accepted. On Windows, we have to call `AcceptLine` within an `OnIdle` event handler and it also requires changes to `PSReadLine`.
- `AcceptLine` only set a flag in `PSReadLine` to indicate the line was accepted. The flag is checked in `InputLoop`, however, when `PSReadLine` is waiting for input, it's blocked in the `ReadKey` call within `InputLoop`, so even if the flag is set, `InputLoop` won't be able to check the flag until after `ReadKey` call is returned.
- I need to change PSReadLine a bit: after it finishes handling the `OnIdle` event, it checks if the `_lineAccepted` flag is set. If it's set, it means `AcceptLine` got called within the `OnIdle` handler, and it throws a `LineAcceptedException` to break out from `ReadKey`. I catch this exception in `InputLoop` to continue with the flag check.
- However, a problem with this change is: the "readkey thread" is still blocked on `Console.ReadKey` when the command is returned to PowerShell to execute. On Windows, this could cause minor issues if the command also calls `Console.ReadKey` -- 2 threads calling `Console.ReadKey` in parallel, so it's uncertain which will get the next keystroke input. On macOS and Linux, the problem is way much bigger -- any subsequent writing to the terminal may be blocked, because on Unix platforms, reading cursor position will be blocked if another thread is calling `Console.ReadKey`.
- So, this approach can only work on Windows. On macOS, we will have to depend on `iTerm2`, which has a Python API server that allows to send keystrokes to a tab using the Python API, so we could possibly use that for macOS. But Windows Terminal doesn't support that, and thus we will have to use the above approach to accept the command on Windows.
- On macOS, if the Python API approach works fine, then we could even consider using it for the `PostCode` action.
4. Add `run_command_in_terminal` and `get_command_output` tools and expose them to agents.
0 commit comments