e1acad4a27
Esc è riservato alla built-in app.interrupt di pi: la shortcut veniva scartata con warning 'conflicts with built-in shortcut'. Rimossa anche la registrazione ridondante 'esc' (stesso tasto fisico). Aggiornati messaggi di stato e documentazione.
123 lines
5.7 KiB
Markdown
123 lines
5.7 KiB
Markdown
# Workflow Vocale (Registrazione F12)
|
|
|
|
L'estensione `agy-pi` trasforma `pi` in un assistente multimodale completo grazie all'integrazione di un workflow di input vocale nativo attivabile con il tasto **F12** o tramite il comando `/agy:record`.
|
|
|
|
---
|
|
|
|
## Diagramma di Flusso della Registrazione Vocale
|
|
|
|
```mermaid
|
|
flowchart TD
|
|
A[Pressione F12] --> B{Recording in corso?}
|
|
B -- No --> C[startRecording: Spawn ffmpeg]
|
|
C --> D[Play Sound: Start PowerUp]
|
|
C --> E[Avvia Timer TUI Status]
|
|
|
|
B -- Yes --> F[stopRecording: Send SIGINT]
|
|
F --> G[Play Sound: Stop Deactivate]
|
|
F --> H[optimizeAudio: silenceremove ffmpeg]
|
|
H --> I[audioHasSpeech: volumedetect check]
|
|
I -- Parlato Assente --> J[Errore: Silenzio o volume basso]
|
|
I -- Parlato Presente --> K[transcribeAudio: API Gemini / enne2]
|
|
K --> L[Legge editorText da TUI]
|
|
L --> M[Unisce Voce + Testo Editor + Contesto]
|
|
M --> N[executeAgy: plan-first, genera PIANO]
|
|
N --> N1{vocalPlanningMode?}
|
|
N1 -- true --> N2[Overlay TUI: trascrizione + piano]
|
|
N2 --> N3[Enter=Esegui | Esc=Annulla | E=Modifica | F12=Registra]
|
|
N3 -- Enter --> O[Svuota editorText TUI]
|
|
N3 -- Esc --> X[Annulla: playSound cancel]
|
|
N1 -- false --> O
|
|
O --> P[sendUserMessage prompt a pi]
|
|
P --> Q[Play Sound: Done Chime & TTS Notify]
|
|
```
|
|
|
|
---
|
|
|
|
## Fasi del Workflow Vocale
|
|
|
|
### 1. Avvio & Cattura dell'Audio (`startRecording`)
|
|
Alla pressione del tasto **F12**:
|
|
- Viene avviato un sottoprocesso `ffmpeg` che cattura dal dispositivo PulseAudio predefinito (`-f pulse -i default`).
|
|
- L'audio viene campionato a 16.000 Hz in mono (`-ac 1 -ar 16000`).
|
|
- Viene attivato un timer TUI che aggiorna dinamicamente lo stato di `pi`:
|
|
`🔴 REGISTRAZIONE... 00:14 / 02:00 (Ctrl+Esc per annullare)`
|
|
|
|
### 2. Feedback Acustici Sci-Fi Procedurali (`playSound`)
|
|
Per non dipendere da file audio esterni, i suoni di feedback vengono generati proceduralmente usando il filtro `aevalsrc` di `ffmpeg` e riprodotti tramite `paplay` (fallback su `aplay` o `ffplay`):
|
|
|
|
- **`start`**: Sweep di frequenza ascendente ($440 \text{ Hz} \to 1760 \text{ Hz}$).
|
|
- **`stop`**: Sweep di frequenza discendente ($1200 \text{ Hz} \to 300 \text{ Hz}$).
|
|
- **`cancel`**: Suono modulato a bassa frequenza ($350 \text{ Hz} \to 200 \text{ Hz}$).
|
|
- **`timeout`**: Pulsazione bi-tono di avviso radar.
|
|
- **`done`**: Arpeggio scintillante acuto ($C_5 - E_5 - G_5$).
|
|
|
|
### 3. Ottimizzazione & Rilevamento del Parlato
|
|
Prima della trascrizione:
|
|
- **`optimizeAudio()`**: Utilizza il filtro `silenceremove` di `ffmpeg` per eliminare il silenzio iniziale e finale con soglia a `-50dB`.
|
|
- **`audioHasSpeech()`**: Esegue una passata `volumedetect`. Se `max_volume` è inferiore a `-35dB` o `mean_volume` è sotto a `-45dB`, la registrazione viene classificata come silenzio, evitando di effettuare chiamate API inutili ed evitando allucinazioni da parte del modello STT.
|
|
|
|
### 4. Compressione & Inizio Trascrizione
|
|
- L'audio ottimizzato WAV viene convertito al volo in formato **Opus/OGG** (`libopus` a 16kbps). Questo riduce il payload di oltre il 60%, evitando errori `HTTP 413 Payload Too Large`.
|
|
- Invio della richiesta alle API Gemini (`gemini-3.5-flash`) o al server `enne2`.
|
|
|
|
### 5. Multimodalità Ibrida (Voce + Testo Editor)
|
|
Una funzionalità distintiva di `agy-pi` è la capacità di fondere il testo digitato dall'utente prima di premere F12 con l'audio registrato:
|
|
|
|
```typescript
|
|
const editorText = (ctx.ui.getEditorText?.() ?? "").trim();
|
|
```
|
|
|
|
Se l'utente ha scritto una nota o del codice nell'editor di `pi` e poi preme **F12** per aggiungere un commento vocale, l'estensione unisce i due input in un unico prompt interpretativo per Gemini:
|
|
|
|
$$\text{Prompt Finale} = \text{Trascrizione Vocale} + \text{Testo Editor} + \text{Contesto Conversazione}$$
|
|
|
|
Dopo l'invio riuscito, l'editor dell'interfaccia TUI viene svuotato automaticamente (`setEditorText("")`) per evitare duplicazioni.
|
|
|
|
### 6. Invio del Prompt all'Agente `pi`
|
|
Se `pi` è in stato di attesa (`isIdle()`), l'input viene inviato immediatamente tramite `sendUserMessage(finalText)`. Se `pi` sta eseguendo un altro task, viene accodato come `followUp`.
|
|
|
|
### 7. Workflow a 2 Fasi con Piano + Conferma (`vocalPlanningMode`)
|
|
Con `vocalPlanningMode=true` (default) il flusso di interpretazione vocale è
|
|
**plan-first**: Gemini produce **solo** la trascrizione corretta e un **piano
|
|
d'azione sintetico** (nessuna esecuzione). Questo evita che l'interpretazione
|
|
avvii autonomamente loop agentici o modifiche a sorpresa a causa di errori di STT.
|
|
|
|
L'interpretazione usa un **framing inter-agent**: Gemini agisce come **analista
|
|
tecnico/middleware** che scrive un briefing per l'orchestratore (NON risponde
|
|
all'utente), in **JSON strutturato**:
|
|
|
|
```json
|
|
{
|
|
"trascrizione_corretta": "...",
|
|
"intent_analisi": "...",
|
|
"note_per_agent": "...",
|
|
"azioni_raccomandate": ["..."],
|
|
"prompt_utente_pulito": "...",
|
|
"ricerca_necessaria": true/false,
|
|
"suggerimenti_ricerca": ["..."]
|
|
}
|
|
```
|
|
|
|
Il campo `prompt_utente_pulito` diventa il prompt finale per l'orchestratore. Se
|
|
`ricerca_necessaria=true`, al prompt finale viene aggiunta una **nota che
|
|
indica all'agente successivo di usare la ricerca web (Perplexity)** per
|
|
verificare best practices, versioni o documentazione aggiornate.
|
|
|
|
Poi un **overlay TUI** mostra trascrizione + piano e attende la conferma:
|
|
|
|
```
|
|
🎙️ Conferma vocale
|
|
Trascrizione: "Aggiorna i docs..."
|
|
📋 Piano proposto: ...
|
|
Enter esegui • Esc annulla • E modifica • F12 registra di nuovo
|
|
```
|
|
|
|
- **Enter** → esegue (invia il risultato a pi)
|
|
- **Esc** → annulla, nessuna azione
|
|
- **E** → modifica il testo del piano manualmente
|
|
- **F12** → registra di nuovo
|
|
|
|
Per tornare all'esecuzione diretta (autonomia piena):
|
|
`/agy:config set vocalPlanningMode false`.
|