Files
paseo/packages/voice-assistant/LLM_INTEGRATION.md
T
Mohamed Boudra 40b199e329 Based on the git diff showing extensive package-lock.json changes and modifications to the agent system prompt and configuration, here's the commit message:
```
feat: add AI SDK dependencies and refine agent voice interaction config

- Add @ai-sdk packages for enhanced AI capabilities
- Install Deepgram SDK, livekit-client, and werift for voice/WebRTC
- Expand agent system prompt with multi-tool workflows and Claude Code interaction patterns
- Adjust VAD timing (1.2s silence threshold) and turn detection for better voice UX
- Switch TTS to inworld/inworld-tts-1 with Olivia voice
- Configure interruption timing (0.2s detection, no word requirement)
- Add comprehensive guidelines for conversational responses vs structured output
- Document plan mode triggers and Claude response type handling

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>
```
2025-10-19 15:41:42 +02:00

227 lines
6.2 KiB
Markdown

# LLM Integration Guide
This document describes Phase 4 of the voice-assistant package: LLM Integration with OpenAI GPT-4.
## Overview
The LLM integration enables the voice assistant to understand natural language commands and execute terminal operations using OpenAI's function calling capabilities.
## Components
### 1. System Prompt (`agent-prompt.md`)
The system prompt defines the agent's personality and behavior. It's loaded from the package root and instructs the agent to:
- Acknowledge requests verbally before acting
- Report tool execution results back to the user
- Handle voice-to-text errors gracefully
- Be concise for mobile users
- Use the simplified "terminals" model for all terminal interactions
**Location**: `/packages/voice-assistant/agent-prompt.md`
### 2. System Prompt Loader (`src/server/agent/system-prompt.ts`)
Provides functions to load and cache the system prompt:
- `loadSystemPrompt()`: Loads the prompt from disk
- `getSystemPrompt()`: Returns cached prompt (loads if not cached)
### 3. OpenAI Integration (`src/server/agent/llm-openai.ts`)
Main LLM integration module with the following functions:
#### `initializeOpenAI(apiKey: string)`
Initializes the OpenAI client with your API key.
#### `callLLM(params: CallLLMParams): Promise<LLMResponse>`
Calls OpenAI's chat completions API with:
- Messages (conversation history)
- Tools (terminal operations)
- Optional streaming callback
Returns the LLM's response including any tool calls.
#### `executeToolCall(toolCall: ToolCall): Promise<string>`
Executes a tool call by mapping to terminal manager functions:
- `list_terminals` → `listTerminals()`
- `create_terminal` → `createTerminal(args)`
- `capture_terminal` → `captureTerminal(args.terminalId, args.lines, args.wait)`
- `send_text` → `sendText(args.terminalId, args.text, args.pressEnter, args.return_output)`
- `rename_terminal` → `renameTerminal(args.terminalId, args.newName)`
- `kill_terminal` → `killTerminal(args.terminalId)`
Returns the result as a JSON string.
#### `getTerminalTools(): ChatCompletionTool[]`
Returns the terminal tools in OpenAI's function calling format.
## Usage
### Environment Setup
Create a `.env` file in the package root:
```bash
OPENAI_API_KEY=sk-...
PORT=3000
NODE_ENV=development
```
### Testing the Integration
The package includes a test endpoint at `/api/test-llm` that demonstrates the LLM integration.
#### Manual Testing with curl
```bash
# Test 1: Create a terminal
curl -X POST http://localhost:3000/api/test-llm \
-H "Content-Type: application/json" \
-d '{"message": "create a terminal called llm-test"}' | jq .
# Test 2: List all terminals
curl -X POST http://localhost:3000/api/test-llm \
-H "Content-Type: application/json" \
-d '{"message": "list all terminals"}' | jq .
# Test 3: Run a command
curl -X POST http://localhost:3000/api/test-llm \
-H "Content-Type: application/json" \
-d '{"message": "run echo hello in the llm-test terminal"}' | jq .
```
#### Automated Testing
Run the provided test script:
```bash
./test-llm.sh
```
## API Response Format
The `/api/test-llm` endpoint returns:
```typescript
{
success: boolean;
userMessage: string;
llmResponse: string; // The LLM's text response
toolCalls?: Array<{
tool: string; // Tool name (e.g., "create_terminal")
arguments: any; // Tool arguments
result: string; // JSON result from tool execution
}>;
}
```
## Example Flow
1. **User sends message**: "create a terminal called web-dev at ~/projects/web"
2. **LLM processes request**:
- System prompt provides context about terminal operations
- User message is analyzed
- LLM decides to call `create_terminal` tool
3. **Tool execution**:
- Arguments: `{name: "web-dev", workingDirectory: "~/projects/web"}`
- `createTerminal()` is called
- Result returned as JSON
4. **Response to user**:
```json
{
"success": true,
"userMessage": "create a terminal called web-dev at ~/projects/web",
"llmResponse": "I'll create a terminal for you...",
"toolCalls": [{
"tool": "create_terminal",
"arguments": {"name": "web-dev", "workingDirectory": "~/projects/web"},
"result": "{\"id\":\"@123\",\"name\":\"web-dev\",\"workingDirectory\":\"/Users/user/projects/web\",...}"
}]
}
```
## Integration with Voice Assistant
The LLM integration is designed to work with the voice assistant's WebSocket server. Future phases will:
1. Connect WebSocket messages to LLM processing
2. Stream LLM responses back to the client
3. Handle multi-turn conversations
4. Maintain conversation context
## Error Handling
The LLM integration includes comprehensive error handling:
- Missing API key: Returns 500 error with message
- Tool execution failures: Returns error JSON in tool result
- Network errors: Caught and returned as 500 errors
- Invalid tool arguments: Caught by terminal manager functions
## Configuration
### Model Selection
Currently using `gpt-4o` (specified in `llm-openai.ts`). You can change this to:
- `gpt-4-turbo`: Faster, cheaper GPT-4
- `gpt-4`: Standard GPT-4
- `gpt-3.5-turbo`: Cheaper option (may have reduced performance)
### Streaming
Streaming is supported but not enabled by default in the test endpoint. To enable:
```typescript
const response = await callLLM({
messages,
tools: getTerminalTools(),
onChunk: (chunk) => {
// Handle streaming chunks
console.log(chunk);
}
});
```
## Development
### Building
```bash
npm run build
```
### Running in Development
```bash
npm start
```
The server will start on port 3000 (or `PORT` from `.env`).
## Troubleshooting
### "OpenAI client not initialized" error
Make sure you call `initializeOpenAI(apiKey)` before `callLLM()`.
### "OPENAI_API_KEY not set" error
Ensure you have a `.env` file with a valid `OPENAI_API_KEY`.
### Tool execution errors
Check that:
1. The default tmux session is initialized
2. Terminal IDs are valid (get them from `list_terminals`)
3. Arguments match the tool schema
### TypeScript errors
Run `npm run build` to check for compilation errors.
## Next Steps
Phase 5 will integrate the LLM with the WebSocket server to enable real-time voice conversations with terminal control.