feat: add workspace SSH execution tool for AI SDK (#18924)

# Add SSH Command Execution Tool for Coder Workspaces

This PR adds a new AI tool `coder_workspace_ssh_exec` that allows executing commands in Coder workspaces via SSH. The tool provides functionality similar to the `coder ssh <workspace> <command>` CLI command.

Key features:
- Executes commands in workspaces via SSH and returns the output and exit code
- Automatically starts workspaces if they're stopped
- Waits for the agent to be ready before executing commands
- Trims leading and trailing whitespace from command output
- Supports various workspace identifier formats:
  - `workspace` (uses current user)
  - `owner/workspace`
  - `owner--workspace`
  - `workspace.agent` (specific agent)
  - `owner/workspace.agent`

The implementation includes:
- A new tool definition with schema and handler
- Helper functions for workspace and agent discovery
- Workspace name normalization to handle different input formats
- Comprehensive test coverage including integration tests

This tool enables AI assistants to execute commands in user workspaces, making it possible to automate tasks and provide more interactive assistance.

<!-- This is an auto-generated comment: release notes by coderabbit.ai -->
## Summary by CodeRabbit

* **New Features**
  * Introduced the ability to execute bash commands inside a Coder workspace via SSH, supporting multiple workspace identification formats.
* **Tests**
  * Added comprehensive unit and integration tests for executing bash commands in workspaces, including input validation, output handling, and error scenarios.
* **Chores**
  * Registered the new bash execution tool in the global tools list.
<!-- end of auto-generated comment: release notes by coderabbit.ai -->
This commit is contained in:
Thomas Kosiewski
2025-07-21 21:24:00 +02:00
committed by GitHub
parent 75c124013f
commit 326c02459f
4 changed files with 533 additions and 2 deletions
+2
View File
@@ -33,6 +33,7 @@ const (
ToolNameUploadTarFile = "coder_upload_tar_file"
ToolNameCreateTemplate = "coder_create_template"
ToolNameDeleteTemplate = "coder_delete_template"
ToolNameWorkspaceBash = "coder_workspace_bash"
)
func NewDeps(client *codersdk.Client, opts ...func(*Deps)) (Deps, error) {
@@ -183,6 +184,7 @@ var All = []GenericTool{
ReportTask.Generic(),
UploadTarFile.Generic(),
UpdateTemplateActiveVersion.Generic(),
WorkspaceBash.Generic(),
}
type ReportTaskArgs struct {