Initial commit: MUDlet AI Client with Telnet + Ollama integration
This commit is contained in:
commit
a1b7191098
22 files changed
+2197
No files matched your search
@@ -0,0 +1,273 @@
|
||||
# Architettura
|
||||
|
||||
## Panoramica
|
||||
|
||||
MUDlet AI Client usa un'architettura a 3 layer basata su Electron:
|
||||
|
||||
```
|
||||
┌─────────────────────────────────────────────────────────┐
|
||||
│ ELECTRON MAIN │
|
||||
│ ┌─────────────┐ ┌─────────────┐ ┌─────────────────┐ │
|
||||
│ │ TelnetService│ │ OllamaService│ │ AutoplayerService│ │
|
||||
│ └──────┬──────┘ └──────┬──────┘ └────────┬────────┘ │
|
||||
│ │ │ │ │
|
||||
│ └────────────────┼───────────────────┘ │
|
||||
│ ▼ │
|
||||
│ ┌─────────────────────┐ │
|
||||
│ │ IPC Handlers │ │
|
||||
│ └─────────┬───────────┘ │
|
||||
└────────────────────────┼────────────────────────────────┘
|
||||
│
|
||||
┌────────────────────────┼────────────────────────────────┐
|
||||
│ PRELOAD JS │
|
||||
│ contextBridge.exposeInMainWorld() │
|
||||
└────────────────────────┼────────────────────────────────┘
|
||||
│
|
||||
┌────────────────────────┼────────────────────────────────┐
|
||||
│ REACT RENDERER │
|
||||
│ ┌─────────┐ ┌─────────────┐ ┌─────────────────────┐ │
|
||||
│ │ App │ │ GameWindow │ │ AutoplayerPanel │ │
|
||||
│ └─────────┘ └─────────────┘ └─────────────────────┘ │
|
||||
└─────────────────────────────────────────────────────────┘
|
||||
```
|
||||
|
||||
## Layer 1: Electron Main Process
|
||||
|
||||
### Main Entry (`src/main/index.ts`)
|
||||
|
||||
Responsabilità:
|
||||
- Inizializzazione finestra BrowserWindow
|
||||
- Setup IPC handlers
|
||||
- Event forwarding tra servizi e renderer
|
||||
- Lifecycle management (app ready, window closed, etc.)
|
||||
|
||||
```typescript
|
||||
// Flusso dati Telnet
|
||||
telnetService.on('output', (data) => {
|
||||
mainWindow.webContents.send('telnet-output', data);
|
||||
autoplayerService.processOutput(data); // Forward all'autoplayer
|
||||
});
|
||||
```
|
||||
|
||||
### TelnetService (`src/main/services/TelnetService.ts`)
|
||||
|
||||
Wrapper attorno a `telnet-client` con funzionalità aggiuntive:
|
||||
|
||||
| Metodo | Descrizione |
|
||||
|--------|-------------|
|
||||
| `connect(host, port)` | Stabilisce connessione Telnet |
|
||||
| `send(data)` | Invia comando al server |
|
||||
| `getOutput()` | Restituisce buffer output |
|
||||
| `parseAnsiCodes(text)` | Converte ANSI escape codes in HTML |
|
||||
|
||||
**Eventi:**
|
||||
- `output` - Emesso quando arrives nuovo output
|
||||
- `connected` - Connessione stabilita
|
||||
- `disconnected` - Connessione chiusa
|
||||
- `error` - Errore di connessione
|
||||
|
||||
**Parsing ANSI:**
|
||||
```typescript
|
||||
// ansicolor converte sequenze ANSI in spans colorati
|
||||
// Ogni span viene convertito in <span style="...">
|
||||
```
|
||||
|
||||
### OllamaService (`src/main/services/OllamaService.ts`)
|
||||
|
||||
Client HTTP per Ollama API. Supporta:
|
||||
|
||||
| Metodo | Descrizione |
|
||||
|--------|-------------|
|
||||
| `chat(messages, options)` | Chat singola, attesa risposta |
|
||||
| `chatStream(messages, options)` | Streaming response token-by-token |
|
||||
| `getLocalModels()` | Lista modelli disponibili |
|
||||
| `isAvailable()` | Check server reachability |
|
||||
|
||||
**API Endpoint:**
|
||||
```
|
||||
POST http://ollama.solarpi.net/api/chat
|
||||
{
|
||||
"model": "llama3.2",
|
||||
"messages": [...],
|
||||
"stream": true,
|
||||
"options": {
|
||||
"temperature": 0.7,
|
||||
"num_predict": 512
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
### AutoplayerService (`src/main/services/AutoplayerService.ts`)
|
||||
|
||||
Decision engine che orchestrate il loop autoplayer:
|
||||
|
||||
```
|
||||
┌─────────────────────────────────────────────────────────┐
|
||||
│ AUTOPLAYER LOOP │
|
||||
│ │
|
||||
│ 1. OBSERVE ← processOutput(output) │
|
||||
│ 2. PARSE ← parseGameState() │
|
||||
│ 3. THINK ← ollamaService.chat() │
|
||||
│ 4. DECIDE ← extractAction() │
|
||||
│ 5. ACT ← executeAction() / queueAction() │
|
||||
│ │
|
||||
└─────────────────────────────────────────────────────────┘
|
||||
```
|
||||
|
||||
**Configurazione:**
|
||||
```typescript
|
||||
interface AutoplayerConfig {
|
||||
model: string; // Model LLM da usare
|
||||
systemPrompt: string; // Comportamento del bot
|
||||
temperature: number; // Creatività (0.0-1.0)
|
||||
autoSend: boolean; // Auto-esegui azioni
|
||||
}
|
||||
```
|
||||
|
||||
**Game State Parser:**
|
||||
```typescript
|
||||
parseGameState(output: string): GameState {
|
||||
// Estrae: location, exits, players, objects, description
|
||||
}
|
||||
```
|
||||
|
||||
**Decision Prompt:**
|
||||
```
|
||||
Context: [ultimi 30 righe output]
|
||||
Sei in: [location]
|
||||
Uscite disponibili: north, south, east
|
||||
|
||||
Cosa fai? (rispondi SOLO con il comando)
|
||||
```
|
||||
|
||||
## Layer 2: Preload Script
|
||||
|
||||
espone API sicure al renderer tramite `contextBridge`:
|
||||
|
||||
```javascript
|
||||
// Telnet
|
||||
telnetConnect(host, port)
|
||||
telnetSend(data)
|
||||
onTelnetOutput(callback)
|
||||
|
||||
// Ollama
|
||||
ollamaChat(messages, options)
|
||||
ollamaGetModels()
|
||||
ollamaIsAvailable()
|
||||
|
||||
// Autoplayer
|
||||
autoplayerConfigure(config)
|
||||
autoplayerStart()
|
||||
autoplayerStop()
|
||||
autoplayerExecuteAction(action)
|
||||
onAutoplayerDecision(callback)
|
||||
onAutoplayerAction(callback)
|
||||
```
|
||||
|
||||
## Layer 3: React Renderer
|
||||
|
||||
### App (`src/renderer/App.tsx`)
|
||||
|
||||
Root component con navigation:
|
||||
|
||||
```typescript
|
||||
// Navigation state
|
||||
const [activePanel, setActivePanel] = useState<'connection' | 'game' | 'autoplayer'>();
|
||||
|
||||
// Connection status
|
||||
const [isConnected, setIsConnected] = useState(false);
|
||||
```
|
||||
|
||||
### GameWindow (`src/renderer/components/GameWindow.tsx`)
|
||||
|
||||
Display principale del gioco:
|
||||
|
||||
| Componente | Funzione |
|
||||
|------------|----------|
|
||||
| Output div | Visualizza output HTML con colors |
|
||||
| Form | Input comandi + submit |
|
||||
| Auto-scroll | Mantiene focus su output recente |
|
||||
|
||||
```typescript
|
||||
// Subscribe a output Telnet
|
||||
useEffect(() => {
|
||||
window.electronAPI.onTelnetOutput((data) => {
|
||||
setOutput(prev => prev + data);
|
||||
});
|
||||
}, []);
|
||||
```
|
||||
|
||||
### AutoplayerPanel (`src/renderer/components/AutoplayerPanel.tsx`)
|
||||
|
||||
Pannello controllo autoplayer:
|
||||
|
||||
| Feature | UI |
|
||||
|---------|-----|
|
||||
| Toggle On/Off | Switch button |
|
||||
| Model selection | Dropdown (da Ollama) |
|
||||
| System prompt | Textarea modificabile |
|
||||
| Live status | Ultime decisioni/azioni |
|
||||
| Ollama availability | Check automatico |
|
||||
|
||||
## Flusso Dati
|
||||
|
||||
### Telnet → UI
|
||||
```
|
||||
1. Telnet server → telnet-client
|
||||
2. TelnetService → emits 'output'
|
||||
3. Main process → ipcRenderer.send('telnet-output')
|
||||
4. GameWindow → onTelnetOutput callback
|
||||
5. React state → setOutput()
|
||||
6. Render → HTML display
|
||||
```
|
||||
|
||||
### Autoplayer Decision
|
||||
```
|
||||
1. Output Telnet arrives
|
||||
2. AutoplayerService.processOutput()
|
||||
3. parseGameState() → GameState { location, exits, ... }
|
||||
4. shouldMakeDecision() → true/false
|
||||
5. ollamaService.chat(messages)
|
||||
6. extractAction() → "go north"
|
||||
7. autoSend ? executeAction() : queueAction()
|
||||
8. Events: 'decision', 'action'
|
||||
9. UI updates: lastDecision, lastAction
|
||||
```
|
||||
|
||||
## Configurazione
|
||||
|
||||
### Environment
|
||||
- Server Ollama: `http://ollama.solarpi.net` (hardcoded)
|
||||
- LPMUD default: `172.24.19.225:6666`
|
||||
|
||||
### Tipi Condivisi
|
||||
|
||||
```typescript
|
||||
// src/main/services/AutoplayerService.ts
|
||||
interface GameState {
|
||||
location: string;
|
||||
description: string;
|
||||
exits: string[];
|
||||
players: string[];
|
||||
objects: string[];
|
||||
health?: string;
|
||||
mana?: string;
|
||||
prompt?: string;
|
||||
}
|
||||
|
||||
interface OllamaMessage {
|
||||
role: 'user' | 'assistant' | 'system';
|
||||
content: string;
|
||||
}
|
||||
```
|
||||
|
||||
## Limitazioni Attuali
|
||||
|
||||
| Componente | Limitation | Piani |
|
||||
|------------|------------|-------|
|
||||
| ANSI Parsing | Solo colori basic | Parser completo |
|
||||
| Game Parser | Regex-based, fragile | ML parser |
|
||||
| Autoplayer | No memory persistent | SQLite storage |
|
||||
| Mapper | Non implementato | Fase 3 |
|
||||
| Triggers | Non implementati | Fase 3 |
|
||||
| Plugins | Non implementati | Fase 4 |
|
||||
Reference in new issue
Block a user