wraith/internal/ai/tools.go
Vantz Stockwell 7ee5321d69
Some checks failed
Build & Sign Wraith / Build Windows + Sign (push) Has been cancelled
feat: AI copilot backend — OAuth PKCE, Claude API streaming, 16 tools, conversations
- OAuth PKCE flow for Max subscription auth (no API key needed)
- Claude API client with SSE streaming (Messages API v1)
- 16 tool definitions: terminal, SFTP, RDP, session management
- Tool dispatch router mapping to existing Wraith services
- Conversation manager with SQLite persistence
- Terminal output ring buffer for AI context
- RDP screenshot encoder (RGBA → JPEG with downscaling)
- Wired into Wails app as AIService

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-17 09:09:23 -04:00

208 lines
7.3 KiB
Go

package ai
import "encoding/json"
// CopilotTools defines all tools available to the AI copilot.
var CopilotTools = []Tool{
// ── SSH Terminal Tools ────────────────────────────────────────
{
Name: "terminal_write",
Description: "Type text into an active SSH terminal session. Use this to execute commands by including a trailing newline character.",
InputSchema: json.RawMessage(`{
"type": "object",
"properties": {
"sessionId": {"type": "string", "description": "The SSH session ID"},
"text": {"type": "string", "description": "Text to type into the terminal (include \\n for Enter)"}
},
"required": ["sessionId", "text"]
}`),
},
{
Name: "terminal_read",
Description: "Read recent output from an SSH terminal session. Returns the last N lines from the terminal buffer.",
InputSchema: json.RawMessage(`{
"type": "object",
"properties": {
"sessionId": {"type": "string", "description": "The SSH session ID"},
"lines": {"type": "integer", "description": "Number of recent lines to return (default 50)", "default": 50}
},
"required": ["sessionId"]
}`),
},
{
Name: "terminal_cwd",
Description: "Get the current working directory of an SSH terminal session by executing pwd.",
InputSchema: json.RawMessage(`{
"type": "object",
"properties": {
"sessionId": {"type": "string", "description": "The SSH session ID"}
},
"required": ["sessionId"]
}`),
},
// ── SFTP Tools ───────────────────────────────────────────────
{
Name: "sftp_list",
Description: "List files and directories at a remote path via SFTP.",
InputSchema: json.RawMessage(`{
"type": "object",
"properties": {
"sessionId": {"type": "string", "description": "The SSH/SFTP session ID"},
"path": {"type": "string", "description": "Remote directory path to list"}
},
"required": ["sessionId", "path"]
}`),
},
{
Name: "sftp_read",
Description: "Read the contents of a remote file via SFTP. Limited to files under 5MB.",
InputSchema: json.RawMessage(`{
"type": "object",
"properties": {
"sessionId": {"type": "string", "description": "The SSH/SFTP session ID"},
"path": {"type": "string", "description": "Remote file path to read"}
},
"required": ["sessionId", "path"]
}`),
},
{
Name: "sftp_write",
Description: "Write content to a remote file via SFTP. Creates or overwrites the file.",
InputSchema: json.RawMessage(`{
"type": "object",
"properties": {
"sessionId": {"type": "string", "description": "The SSH/SFTP session ID"},
"path": {"type": "string", "description": "Remote file path to write"},
"content": {"type": "string", "description": "File content to write"}
},
"required": ["sessionId", "path", "content"]
}`),
},
// ── RDP Tools ────────────────────────────────────────────────
{
Name: "rdp_screenshot",
Description: "Capture a screenshot of the current RDP desktop. Returns a base64 JPEG image.",
InputSchema: json.RawMessage(`{
"type": "object",
"properties": {
"sessionId": {"type": "string", "description": "The RDP session ID"}
},
"required": ["sessionId"]
}`),
},
{
Name: "rdp_click",
Description: "Click at a specific position on the RDP desktop.",
InputSchema: json.RawMessage(`{
"type": "object",
"properties": {
"sessionId": {"type": "string", "description": "The RDP session ID"},
"x": {"type": "integer", "description": "X coordinate in pixels"},
"y": {"type": "integer", "description": "Y coordinate in pixels"},
"button": {"type": "string", "enum": ["left", "right", "middle"], "default": "left", "description": "Mouse button to click"}
},
"required": ["sessionId", "x", "y"]
}`),
},
{
Name: "rdp_doubleclick",
Description: "Double-click at a specific position on the RDP desktop.",
InputSchema: json.RawMessage(`{
"type": "object",
"properties": {
"sessionId": {"type": "string", "description": "The RDP session ID"},
"x": {"type": "integer", "description": "X coordinate in pixels"},
"y": {"type": "integer", "description": "Y coordinate in pixels"}
},
"required": ["sessionId", "x", "y"]
}`),
},
{
Name: "rdp_type",
Description: "Type text into the focused element on the RDP desktop. Uses clipboard paste for reliability.",
InputSchema: json.RawMessage(`{
"type": "object",
"properties": {
"sessionId": {"type": "string", "description": "The RDP session ID"},
"text": {"type": "string", "description": "Text to type"}
},
"required": ["sessionId", "text"]
}`),
},
{
Name: "rdp_keypress",
Description: "Press a key or key combination on the RDP desktop (e.g., 'Enter', 'Tab', 'Ctrl+C').",
InputSchema: json.RawMessage(`{
"type": "object",
"properties": {
"sessionId": {"type": "string", "description": "The RDP session ID"},
"key": {"type": "string", "description": "Key name or combination (e.g., 'Enter', 'Ctrl+C', 'Alt+F4')"}
},
"required": ["sessionId", "key"]
}`),
},
{
Name: "rdp_scroll",
Description: "Scroll the mouse wheel at a position on the RDP desktop.",
InputSchema: json.RawMessage(`{
"type": "object",
"properties": {
"sessionId": {"type": "string", "description": "The RDP session ID"},
"x": {"type": "integer", "description": "X coordinate in pixels"},
"y": {"type": "integer", "description": "Y coordinate in pixels"},
"direction": {"type": "string", "enum": ["up", "down"], "description": "Scroll direction"},
"clicks": {"type": "integer", "description": "Number of scroll clicks (default 3)", "default": 3}
},
"required": ["sessionId", "x", "y", "direction"]
}`),
},
{
Name: "rdp_move",
Description: "Move the mouse cursor to a position on the RDP desktop without clicking.",
InputSchema: json.RawMessage(`{
"type": "object",
"properties": {
"sessionId": {"type": "string", "description": "The RDP session ID"},
"x": {"type": "integer", "description": "X coordinate in pixels"},
"y": {"type": "integer", "description": "Y coordinate in pixels"}
},
"required": ["sessionId", "x", "y"]
}`),
},
// ── Session Management Tools ─────────────────────────────────
{
Name: "list_sessions",
Description: "List all active SSH and RDP sessions with their IDs, connection info, and state.",
InputSchema: json.RawMessage(`{
"type": "object",
"properties": {},
"required": []
}`),
},
{
Name: "connect_ssh",
Description: "Open a new SSH connection to a saved connection by its ID.",
InputSchema: json.RawMessage(`{
"type": "object",
"properties": {
"connectionId": {"type": "integer", "description": "The saved connection ID from the connection manager"}
},
"required": ["connectionId"]
}`),
},
{
Name: "disconnect",
Description: "Disconnect an active session.",
InputSchema: json.RawMessage(`{
"type": "object",
"properties": {
"sessionId": {"type": "string", "description": "The session ID to disconnect"}
},
"required": ["sessionId"]
}`),
},
}