> ## Documentation Index
> Fetch the complete documentation index at: https://docs.switchbord.ai/llms.txt
> Use this file to discover all available pages before exploring further.

# Connettore gb-agent

> Come il connettore customer-agent gb-agent mostra bozze e passaggi in human-review nell'inbox di Switchbord, e il limite di dry-run che lo rende sicuro.

Il **connettore gb-agent** è un'integrazione Switchbord che permette a un servizio esterno customer-agent (GBCA) di proporre risposte per le conversazioni in entrata. Il connettore invia una risposta strutturata a Switchbord, il worker la persiste sulla riga del message draft, e l'inbox la mostra come una card che l'operatore può accettare, modificare, respingere o revisionare — a seconda del verdetto dell'agente.

Questa pagina è rivolta agli operatori. Spiega cosa fa il connettore, come l'inbox lo mostra e — soprattutto — cosa il connettore **non può** fare.

## Due varianti di card

Ogni risposta del connettore contiene un campo `route`. L'inbox mostra una delle due varianti di card in base a quel route.

### `draft_reply` — messaggio proposto

L'agente è sufficientemente sicuro da suggerire una risposta pronta per l'invio. L'operatore vede la card di bozza AI già esistente:

* Intestazione: ✨ AI draft · proposto *ora*
* Badge dei metadata: route, intent, confidence, destination/dateWindow/partySize opzionali
* Corpo: il testo del messaggio proposto
* Azioni: **Accetta e invia**, **Modifica**, **Rifiuta**

Questa card è invariata rispetto alle release precedenti di Switchbord.

### `human_review` — anteprima del passaggio a un operatore

L'agente non ha sufficiente confidence (oppure la policy non consente l'invio automatico) e restituisce la conversazione a un operatore umano. L'operatore vede la nuova card ambra di anteprima del passaggio:

* Intestazione: 🧭 Anteprima passaggio all'agente · proposto *ora*
* Badge: route (Human review), connector (gb-customer-agent), tipo di handoff opzionale
* Sezioni (mostrate solo se popolate):
  * **Handoff packet** — tipo, coda raccomandata, task aperti, verifica richiesta, limite di dry-run
  * **Azioni di revisione proposte** — chip di sola revisione (senza click handler, senza effetti collaterali); ognuno etichettato "Solo revisione"
  * **Riferimenti a evidenze** — fino a 5 visibili, link solo https, ID in stile mono per le evidenze non-link
* Azioni: solo **Ignora** (nessun Accetta/Invia, nessun bottone per creare task operatore, nessun bottone di assegnazione coda)

La card è di sola lettura per progettazione. Tutto ciò che l'operatore fa successivamente avviene tramite i controlli standard dell'inbox Switchbord — assegnare la coda, cambiare lo stato, inviare una risposta manuale, fare escalation. Il connettore non esegue mai nessuna di queste azioni per conto dell'operatore.

## Feature flag

La card di anteprima del passaggio è controllata dal feature flag `inbox.gbAgentHandoffPreview`.

* **Default**: OFF in tutti i workspace.
* **Abilitare per deployment**: impostare la env var `NEXT_PUBLIC_FLAG_INBOX_GB_AGENT_HANDOFF_PREVIEW=1` sul progetto Vercel `apps/app`. Il flag entra in vigore al deploy successivo.
* **Quando è OFF**: le bozze con `route === "human_review"` continuano a mostrare il badge sottile "Human review" all'interno della card di bozza esistente. Nulla altro cambia.
* **Quando è ON**: viene renderizzata la Variante B per quelle bozze.

Vedi [Operations → Feature Flags](/it/operations/feature-flags) per il catalogo completo dei flag.

## Il limite del dry-run

Di default il connettore gb-agent è limitato a **proporre** — non ad **agire**. Questo è imposto su tre livelli (UI, worker e schema di risposta) ed è il contratto per Draft with me manuale, bozze connector avviate manualmente, handoff `human_review` e modalità proattiva quando `proactive_draft_auto_send_first=false`:

| Il connettore **di default non può**                              | Cosa succede invece                                                                             |
| ----------------------------------------------------------------- | ----------------------------------------------------------------------------------------------- |
| Inviare un messaggio visibile al cliente                          | L'operatore deve cliccare Accetta e invia (draft\_reply) o comporre manualmente (human\_review) |
| Scrivere su CRM / record contatto                                 | La risposta del connettore è metadata di sola lettura; non esistono percorsi di scrittura       |
| Assegnare una conversazione a una coda                            | L'operatore assegna manualmente tramite l'interfaccia coda esistente                            |
| Segnare una conversazione come letta/non letta                    | L'operatore cambia lo stato tramite i controlli dell'inbox esistenti                            |
| Creare task per l'operatore                                       | Non è esposta nessuna interfaccia di creazione task; il lavoro futuro è tracciato separatamente |
| Aprire URL esterni automaticamente                                | Gli URL delle evidenze sono solo https, senza `target="_blank"` su fonti non-https              |
| Esporre il proprio endpoint, runId, o token della superficie tool | Il mapper UI rimuove tutti i campi sensibili ai secret prima del rendering                      |

L'unica eccezione intenzionale è l'opt-in esplicito documentato sotto: `proactive_draft_auto_send_first=true` può accettare e inviare la prima bozza proattiva `draft_reply` riuscita da trigger Flow/keyword usando lo stesso RPC `accept_message_draft_for_dispatch` del pulsante operatore. Fuori da quel percorso ristretto, gli effetti restano azioni manuali dell'operatore dentro Switchbord. Se noti qualsiasi altra azione autonoma dell'inbox come risultato di una risposta del connettore, è un bug — segnalalo.

## "Draft with me" (assistenza streaming per singola conversazione)

Separatamente dalle due varianti di card sopra, il composer ha un trigger **"Draft with me"** — una singola pillola violetta (`SparklesIcon`) sul margine destro del composer, protetta dalla stessa access mode `draft_with_me` del resto della superficie del connettore (`/api/inbox/gb-agent/access`). Cliccandolo si avvia lo streaming di una bozza a contesto completo per la conversazione aperta, mostrata in una barra di stato minimizzata sopra il composer; nulla viene mai inviato automaticamente.

<Info>
  A partire dalla v0.18.29, Draft with me è l'**unico** trigger AI nel composer — la precedente run-action inline `BotMessageSquare` e il suo duplicato compatto sono stati ritirati, così gli operatori hanno un unico punto di accesso non ambiguo.
</Info>

### Run per conversazione, in background

A partire dalla v0.18.30, un'esecuzione di Draft with me è associata alla sua **conversazione**, non al componente montato del composer. Lo stato della run (status, phase, trace, testo finale della bozza, motivo dell'handoff) vive in uno store a livello di modulo (`gb-agent-draft-runs-store`) indicizzato per id di conversazione. In pratica, questo significa che:

* Passare a una chat diversa mentre una bozza è in generazione **non** la annulla — la run continua lo streaming in background e sarà ancora lì (terminata, passata a un operatore, o fallita) quando l'operatore torna indietro.
* Ogni riga di conversazione, l'intestazione della chat aperta e la striscia delle tab (vedi [Funzionalità avanzate dell'inbox](/it/features/inbox-advanced#scheda-delle-conversazioni-persistenti)) mostrano un badge di stato `BotMessageSquare` in tempo reale, colorato in base alla run di quella conversazione — violetto/pulsante durante lo streaming, verde quando una bozza è pronta, ambra su un passaggio a human-review, rosso in caso di errore, e nascosto quando inattivo.
* Solo il controllo esplicito ✕ / Stop annulla una run. Smontare il composer (navigando altrove) non la interrompe più.
* Avviare una nuova run per la stessa conversazione sostituisce qualsiasi run in corso precedentemente.

### Barra di stato minimizzata

Il panel (v0.18.17) non coprirà mai la chat — viene mostrato come una barra sottile con un punto di stato colorato e un'espansione al click:

| Colore del punto   | Significato                                                     |
| ------------------ | --------------------------------------------------------------- |
| Violetto, pulsante | Bozza in corso                                                  |
| Verde              | Bozza pronta — clicca per espandere e **Inserire nel composer** |
| Ambra              | Passato a human review (nessuna bozza utilizzabile)             |
| Rosso              | Generazione fallita                                             |

Espandendo la barra si rivela il testo della risposta in streaming, una traccia di ragionamento/tool collassabile e (mentre è attiva) un controllo **Stop** più la ✕ sempre visibile che chiude completamente la barra (annullando una run ancora in streaming). `panelDismissed` e `panelExpanded` si azzerano entrambi al cambio di conversazione e a ogni nuova run, così una barra obsoleta non si sovrappone mai fra chat diverse. Se un nuovo messaggio in entrata arriva a metà run, un banner ambra chiudibile "contesto obsoleto" avvisa l'operatore che la bozza in corso potrebbe rispondere a un messaggio non più attuale — la run **non** viene annullata automaticamente.

### Catena di fallback

A partire dalla v0.18.20, un'esecuzione di Draft with me è una catena di tentativi, non una singola richiesta: **streaming → retry dello streaming con backoff con jitter → fallback deterministico non-stream `draft-run`**. L'operatore ottiene sempre una bozza pronta e utilizzabile oppure un errore esplicito e chiaro — mai un composer vuoto in silenzio. Mentre la catena procede tra i retry o il fallback deterministico, la barra espansa mostra un suggerimento "retrying…" / "falling back…" così l'attesa viene spiegata invece di rimanere silenziosa.

### Copy chat → traccia di debug della bozza

Il pulsante **Copy chat** del pannello della chat (in alto a destra, icona appunti) scrive un export JSON strutturato negli appunti contenente il contesto completo della conversazione (v0.18.13). A partire dalla v0.18.33, se una run di Draft with me è mai stata eseguita per quella conversazione, l'export porta anche con sé un blocco `draftWithMe` — omesso interamente quando non è mai stata eseguita alcuna run (status è `idle`), così le conversazioni per cui non è mai stata generata una bozza restano pulite:

* `finalDraftText` e ciclo di vita (`status` / `phase`, se è stato usato il fallback deterministico)
* `handoffReason` quando la run è stata instradata a human review
* `traceEvents` (etichette, tipo di decisione/evento, stato ok/warn) — la stessa traccia di ragionamento mostrata nella barra espansa
* `sessionId` e `inboundMessageId` per correlare con i log server-side
* `lastError` (messaggio, flag `recoverable`, e — a partire dalla v0.18.34 — un `detail` upstream privo di contenuto sensibile come `AI_APICallError status=429 cause=RateLimitError`, limitato a 200 caratteri) quando lo stato terminale della run è stato un fallimento

Questo permette a un operatore di ottenere una bozza più tutto il necessario per fare il triage di un problema senza aprire i devtools.

### Bozze proattive per Flow campagna e auto-send-first

Indipendentemente dal trigger manuale "Draft with me", un workspace può attivare la generazione **proattiva** delle bozze (v0.18.12, BORD-818): GB-Agent genera una bozza in background e la mette nel composer prima che l'operatore apra la conversazione.

Per i Flow di campagna GB, la forma reale in produzione è:

* Webhook Meta: `type: "interactive"`, `interactive.type: "nfm_reply"`, `interactive.nfm_reply.name: "flow"`.
* Placeholder visibile nel messaggio: `"Sent"`.
* Messaggio normalizzato in Switchbord: `body = "Sent"`, `payload.messageType = "interactive"`, `payload.replyKind = "interactive_flow"`, e `payload.flowResponseRedacted` presente.
* Le conversazioni originate da campagna di solito hanno label `campaign`/`Campaign`, ma il trigger Flow deve basarsi su `payload.replyKind = "interactive_flow"`; la keyword `sent` è solo fallback per payload degradati.

Set di toggle consigliati:

| Risultato                                             | Settings → Integrations → GB-Agent                                                                                                                                                                                                                                                           |
| ----------------------------------------------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| Silenzio sui submit Flow                              | `proactive_draft_enabled = false` (master off). GB-Agent non fa nulla quando arriva `Sent`.                                                                                                                                                                                                  |
| Bozza nel composer, nessun invio automatico           | `enabled = true`, `mode_draft_reply_enabled = true`, `proactive_draft_enabled = true`, `proactive_draft_trigger_mode = flow_completion`, `proactive_draft_trigger_keywords = ['sent']`, opzionale `proactive_draft_label_filters = ['campaign']`, `proactive_draft_auto_send_first = false`. |
| Invio automatico della prima risposta Flow completata | Come draft mode, più `proactive_draft_auto_send_first = true` e il kill switch worker non deve essere `GB_AGENT_PROACTIVE_AUTO_SEND_ENABLED=false`.                                                                                                                                          |

Note operative:

* `proactive_draft_delay_seconds` (0–300, default 10) attende dopo il messaggio inbound prima di generare. Un nuovo inbound cancella un job proattivo ancora pending e riavvia il delay sul messaggio più recente.
* `proactive_draft_label_filters` è case-insensitive; `campaign` matcha label come `Campaign`. Lascia vuoto per consentire qualunque Flow completion.
* `proactive_draft_auto_send_first` è stretto: solo la prima bozza proattiva `draft_reply` da trigger `flow_completion`/`keyword` in una conversazione può essere accettata automaticamente. Job legacy `all_inbound`, bozze `human_review`, conversazioni con draft già accettato, outbound umano, o blocchi RPC degradano a draft-only.
* L'auto-send usa comunque lo stesso RPC `accept_message_draft_for_dispatch` del pulsante Send operatore, preservando idempotenza, audit, gate consenso/finestra servizio e outbox `message.dispatch`.

<Warning>
  Tieni `proactive_draft_auto_send_first` off per la modalità review con bozza nel composer. Attivalo solo quando il workspace vuole inviare automaticamente la prima bozza Flow riuscita; le risposte successive restano draft-only.
</Warning>

## GB-Agent Insights

`/insights` ha una tab **GB-Agent** (v0.18.16, BORD-741) — analytics di sola lettura, scoped al workspace, per il rollout e il perfezionamento, basata su `responder_runs` (la stessa tabella di telemetria su cui scrivono Draft with me e le bozze proattive). Non c'è nessun gate di controllo dei costi qui; la tab esiste puramente per rendere visibile l'utilizzo di GB-Agent.

La tab mostra:

* **Tile di riepilogo** — richieste, completamenti, timeout, fallimenti, più i tassi di completamento/timeout/fallimento.
* **Suddivisione degli outcome** — `sent_unmodified`, `sent_modified`, `rejected`, `abandoned`, `timeout`, `failed`, con il tasso di modifica derivato (`sent_modified / (sent_unmodified + sent_modified)`) e il tasso di rifiuto.
* **Distribuzione della edit-distance** — un istogramma a bucket (0–10%, 10–25%, 25–50%, 50–75%, 75%+) di quanto testo di una bozza `sent_modified` è stato modificato dall'operatore prima dell'invio, più il rapporto medio.
* **Percentili del tempo di invio** — latenza p50 / p90 / p99 / media della decisione operatore (`time_to_action_ms`).
* **Rollup per modalità** e **per operatore/agente** — la stessa suddivisione aggregata raggruppata per `responder_type` (Response AI vs. campagna) o per `agent_id`.

La tab legge `GET /api/insights/gb-agent`, che accetta `sinceDays` (default 30, limitato tra 1–365) oppure `from`/`to` espliciti e condivide i selettori SSR di channel/intervallo di date con il resto di `/insights`. L'accesso è controllato allo stesso modo del resto di `/insights` (`requireOperationsAccess`).

## Configurare il connettore

La configurazione dell'operatore avviene in **Settings → Integrations → gb-agent**. (Quando questa superficie sarà rilasciata completamente, la guida in-product ne coprirà i passaggi in dettaglio; questa pagina è la fonte attuale di verità.)

Configurazione richiesta:

1. **Endpoint URL** — l'endpoint completo di draft-run su cui Switchbord invia il contesto del messaggio in entrata per la valutazione. Per GBCA in produzione, usa `https://gb-customer-agent-production.up.railway.app/api/agent/draft-run`, non solo la root del servizio. Deve essere https senza userinfo, query string o fragment.
2. **Tool-surface token** — archiviato come secret di workspace nel Supabase Vault, non viene mai restituito in nessuna risposta API. Ruotarlo tramite la UI del Vault.
3. **Test connection** — la pagina Settings esegue un `GET` autenticato sicuro all'endpoint configurato e si aspetta che il connettore riporti una capability `draft_run` prima di mostrare il successo.

## Stati di triage

Quando il trigger dell'inbox è disabilitato, il badge indica perché:

| Stato                     | Significato                                                      | Cosa fare                                                      |
| ------------------------- | ---------------------------------------------------------------- | -------------------------------------------------------------- |
| "Endpoint not configured" | Nessun URL o token archiviato                                    | Configura in Settings → Integrations                           |
| "Endpoint unsafe"         | L'URL configurato non è https o contiene userinfo/query/fragment | Sostituiscilo con un URL https pulito                          |
| "Draft already queued"    | Esiste già una bozza in attesa dal connettore                    | Risolvi prima la bozza esistente (Accetta, Modifica o Rifiuta) |
| "No inbound message"      | Nessun messaggio in entrata disponibile da valutare              | Attendi il prossimo messaggio del cliente                      |

## Vedi anche

* [Operations → Runbook](/it/operations/runbook) — blocco di triage gb-agent
* [Operations → Feature Flags](/it/operations/feature-flags) — catalogo dei flag
* [Security → Vault Architecture](/it/security/vault-architecture) — secret di workspace
* [Platform → Data Model](/it/platform/data-model) — struttura di `message_drafts` e `responder_runs`
* [Features → Advanced Inbox Features](/it/features/inbox-advanced) — banner di connessione e tab di conversazione che mostrano lo stato di Draft with me
