TERABRAIN NX Richiedi una demo
Manuale tecnicoTeraBrain NX · Agentic enterprise platform

Manuale tecnico di TeraBrain NX.

Come si progetta, sviluppa e governa un sistema agentico su TeraBrain NX: il modello a grafo, ogni tipo di nodo, l'SDK dei workspace TypeScript, la sicurezza e l'osservabilità.

Destinatari
Sviluppatori full stack, AI engineer
Edizione
Settembre 2026
Console
app.nx.terabrain.ai
Sezioni
17

01Introduzione

TeraBrain NX è una piattaforma per progettare, eseguire e governare sistemi agentici completi: agenti LLM, canali d'ingresso, dati, codice TypeScript e integrazioni MCP descritti come un unico grafo versionato. Lo stesso grafo si costruisce dall'editor visuale, conversando con il Builder, oppure da un assistente esterno (Claude, Codex, Cursor) collegato via MCP.

Questo manuale descrive il modello di esecuzione, ogni tipo di nodo, l'SDK dei workspace, la sicurezza e l'osservabilità. È scritto per sviluppatori full stack, architetti e AI engineer che devono progettare grafi di produzione, scrivere codice nei workspace o integrare la piattaforma con sistemi esistenti.

Convenzioni. I nomi di campi, porte, funzioni e percorsi sono in monospace e restano in inglese, come appaiono nella console e nelle API. I nomi delle etichette dell'interfaccia sono tra virgolette ("Uses tools"). Gli esempi di codice sono TypeScript.

Cosa ottieni dalla piattaforma, in sintesi:

02Modello concettuale

Un grafo è un insieme di nodi tipizzati collegati in due modi: tool edge (chi offre strumenti a chi li usa) e flow edge (chi avvia conversazioni e chi le risponde). Solo gli agenti ragionano; tutti gli altri nodi portano conversazioni agli agenti o danno loro strumenti.

Gli agenti ricevono conversazioni dai canali e strumenti dagli altri nodi CANALI · AVVIANO CONVERSAZIONI NODI TOOL · FORNISCONO STRUMENTI Web appTelegram botMailbox Voice ← Phone lineSchedulerMCP server MySQL databaseFile storageSkill library Connector (TypeScript)Sandbox / macchina on‑premMCP remoto / hosted Altro agente Agente istruzioni · modello delegate / handoff conversazione (flow edge) strumenti (tool edge)
Anatomia di un grafo. Le linee continue portano conversazioni verso l'agente; quelle tratteggiate gli portano strumenti. Un agente può delegare o passare la conversazione a un altro agente.

Nodi e porte

Ogni nodo ha un nodeId univoco nel grafo, un type (agent, webapp, connector, database, filestorage, sandbox, mcp, email, telegram, voice, …) e quattro famiglie di porte:

Famiglia Etichetta in console Direzione Esempi di portId
exposes Provides tools offre tool rw, ro, admin, functions, developer, sandbox
consumes Uses tools riceve tool tools
sources Starts conversations avvia flussi delegate, handoff, agent, inbound, outbound
sinks Answers riceve flussi sink ("Conversations"), calls, in

Una porta exposes può offrire meno di quanto il nodo sappia fare. Un database, per esempio, espone admin (DDL incluso) e rw (solo DML): il grafo decide chi riceve quale livello di privilegio.

Tool edge e flow edge

Nel JSON del grafo gli archi sono due liste separate:

"toolEdges": [
  { "consumerNodeId": "agent", "consumerPortId": "tools",
    "providerNodeId": "sandbox", "providerPortId": "sandbox" }
],
"flowEdges": [
  { "sourceNodeId": "webapp", "sourcePortId": "agent",
    "sinkNodeId": "agent", "sinkPortId": "sink" }
]

Regole strutturali da tenere a mente:

Documento del grafo e versioni

Il grafo è un documento JSON con graphId, name, organizationId, nodes, toolEdges, flowEdges, ui e revision. I campi computed* (URL pubblicati, tool esposti con i relativi JSON Schema, stato dei database) sono scritti dalla build e non vanno editati.

Ogni modifica, da editor, Builder o MCP, produce una nuova revisione registrata a nome di chi l'ha fatta. Le scritture usano concorrenza ottimistica: una modifica basata su una revisione superata è rifiutata con HTTP 409. rollback riporta il grafo a una versione precedente; oltre il punto in cui un nodo con dati è stato aggiunto, serve conferma esplicita.

Build e runtime

"Save" applica la nuova revisione e ricostruisce i nodi cambiati; il resto del grafo continua a girare. "Rebuild node" ricostruisce un singolo nodo. Un nodo resettato o rimosso distrugge i propri dati secondo il tipo (database svuotato, repository git e container del workspace ricreati, conversazioni dei canali perse): la documentazione di ogni tipo lo dichiara nella sezione "What removing or resetting it destroys".

03Mappa della console

La console è organizzata in tre aree: Build (progettare e sviluppare), Run (usare e osservare), Organization (amministrare). Il selettore in alto a sinistra cambia organizzazione o mostra "All organizations".

Area Sezione Cosa contiene
— Home Chat rapida con un agente, prompt al Builder, app e agenti (con preferiti), conversazioni recenti, grafi con stato
Build Build Il Builder: chat a sinistra, grafo disegnato in tempo reale a destra, toggle "Tool activity"
Build Graphs Elenco grafi con stato; New graph (vuoto o da recipe), Import…; per grafo: Rebuild, Export…, Duplicate…, Copy id, Delete
Build Code Tutti i workspace TypeScript: ultimo commit, stato, modifiche non committate; browser file, history, git clone, "Clone in VS Code"
Build Skills Libreria di skill: scrittura, import zip, download
Build Files Tutti i file storage: upload drag&drop, cartelle, condivisione con link a scadenza (ore)
Build Databases Tutti i database MySQL: Schema (colonne, chiavi, FK, diagramma), Query (Run, Run selection, Explain, history), Data
Build Docs Documentazione di ogni tipo di nodo e recipe; "What the Builder is told"
Run Agents Chat con gli agenti, raggruppati per grafo; conversazioni con filtro "Only mine" e tool activity
Run Apps Le web app pubblicate, con il livello d'accesso (public, organization, group)
Run Calls Registro chiamate telefoniche per grafo
Run Scheduled tasks Task dello scheduler ed esiti di ogni esecuzione
Run Logs Flows, Tool calls, Graph, Changes, Person (vedi §15)
Organization Organization Settings (provider LLM, model profile), Members, Secrets, Variables, Connections, Identity
Organization Sites Macchine on‑premise registrate con l'agente TeraBrain NX
— Profile Identità esterne (link Telegram), password, token per assistenti MCP, secrets, connections e variabili personali

L'editor di grafo

L'editor mostra i nodi come schede con le porte raggruppate per famiglia e il numero di tool per porta ("Tools · 20 from file-storage, sandbox…"). La legenda distingue le linee: tratteggiate per i tool, continue per le conversazioni, e le chiamate telefoniche.

04Agenti

L'agente è l'unico nodo che ragiona: legge la conversazione, sceglie i tool, risponde. Senza tool può solo conversare. Riceve conversazioni sulla porta sink ("Conversations") da canali, altri agenti, codice o dalla sezione Agents della console.

Campi principali

Campo Chi lo legge Note
nodeId sistema Obbligatorio, breve e parlante (support-agent)
Name persone Nome mostrato; default = nodeId
What it does, in one line persone e client MCP Mai letto dal modello dell'agente; letto dagli assistenti che lo raggiungono via server MCP
instructions modello System prompt, una lista di paragrafi. Qui va il lavoro dell'agente
modelProfile runtime Un model profile dell'organizzazione; vuoto = default dell'organizzazione
Who may talk to it console public, organization (default) o group. Riguarda solo la chat della console: ogni canale ha il proprio controllo d'accesso

Se l'organizzazione non ha alcun model profile, l'agente risponde con un eco fisso: utile per testare il cablaggio. In quella modalità un messaggio che inizia con /handoff passa la conversazione lungo la porta handoff, e /attach rimanda gli allegati ricevuti.

Parametri avanzati

Parametro Default Effetto
Look at images off Tool viewResource per guardare immagini su richiesta invece di includerle in ogni chiamata; richiede un modello multimodale
Listen to audio off viewResource trascrive l'audio; con STT a scelta tra elevenlabs, wyoming, openai
Transcribe incoming audio on Trascrive l'audio di un messaggio prima che il modello lo legga (limite 25 MB)
Tell the agent who it is talking to on Aggiunge nome ed email del membro al system prompt
Tell the agent the date and time on Aggiunge data, ora e fuso d'inizio conversazione
Let it split work into subtasks on Tool runSubtask: istanza vuota dello stesso agente, stessi tool, nessun contesto, conversazione figlia
See its own conversations off Tool listConversations e history sulle conversazioni figlie
Allow public file links off Tool linkResource: link pubblico a un file della conversazione, scaricabile senza sessione
Tool rounds per turn 64 (max 200) Round di tool per turno prima di fermarsi senza risposta finale
Tool timeout 600 s Oltre, il modello viene informato che il tool non ha risposto
Model timeout 600 s Durata massima (o silenzio massimo in streaming) di una chiamata al modello

Orchestrazione multi‑agente

Un agente collabora con altri attraverso due porte sources:

Ogni porta ha una description: è ciò che il modello legge sull'agente all'altro capo, quindi decide quando delegare. Il flag Inherit User (default on) fa sì che la conversazione delegata appartenga allo stesso utente. Per aggiungere un collaboratore si aggiunge una porta per agente, ognuna con la sua descrizione.

La porta Edit this agent (developer) espone readInstructions ed editInstructions: permette a un agente sviluppatore di leggere e riscrivere le istruzioni di un altro.

Errori tipici

05Canali

I canali portano conversazioni agli agenti. Ognuno ha il proprio controllo d'accesso, indipendente da "Who may talk to it" dell'agente.

Web app (webapp)

Un connector (§7) che serve anche HTTP: i file in public/ e l'handler esportato da app.ts sono pubblicati a un indirizzo dell'ambiente. Ha tutte le porte del connector (functions, developer, tools, agent). "Who may open the app" vale public (default), organization o group; l'identità del visitatore arriva sempre negli header della richiesta. Nome e descrizione compaiono nella sezione Apps; l'indirizzo viene scritto sul nodo dopo la build. Dettagli di sviluppo in §11.

Telegram bot (telegram)

Ogni messaggio al bot diventa una conversazione; le risposte tornano in chat con testo, file, foto e messaggi vocali. Si crea il bot con @BotFather e si imposta botToken, preferibilmente come {"secretRef": "TELEGRAM_BOT_TOKEN"}. Unica connessione: source → sink dell'agente.

Mailbox (email)

La posta in arrivo diventa una conversazione, una per thread; le risposte partono nello stesso thread. La porta inbound va all'agente che risponde; la porta tool mail ("Send & search mail") dà gli strumenti per scrivere, cercare e leggere a qualunque agente.

Variante Configurazione
Hosted by TeraBrain NX receive: {"kind":"hosted","localPart":"nome"}, send: {"kind":"hosted"}; indirizzo attivo alla build
Gmail / Google Workspace Connection Google con set "Gmail via IMAP/SMTP", senza password
Microsoft 365 Connection Microsoft 365 con set "Mail"; supporta mailbox condivise
IMAP + SMTP Qualunque provider o server proprio, con utente e password

Una mailbox lavora senza nessuno collegato: con una connection personale va indicato in "Member whose account is used" di chi è il token. "Access (advanced)" accetta solo posta autenticata di membri o di un gruppo. Sulla connessione mail il campo allow limita i destinatari.

MCP server (mcp)

È la porta d'ingresso per assistenti esterni (Claude, ChatGPT, Claude Code, Cursor) come custom connector. Due porte, anche insieme:

Dopo la build il nodo mostra l'indirizzo: si incolla nelle impostazioni connector dell'assistente, oppure si apre nel browser per le istruzioni (Claude Desktop può installarlo come estensione). L'indirizzo equivale a una password: chi lo possiede può fare tutto ciò che tool e agente consentono. Un nuovo apiKey (avanzato) lo cambia. Il campo instructions (avanzato) è ciò che il modello del client legge sul server.

Questo nodo espone un grafo. Per far costruire e sviluppare grafi a un assistente si usa invece il token personale del profilo (§12).

Voice (voice)

Dà voce a un agente testuale al telefono: ascolta, parla, trasferisce e chiude. Porte: calls (sink, chiamate da linea, orari, menu, routing o interno), agent (source, l'agente che parla) e control (tool "Call controls" per lo stesso agente). L'agente vede una conversazione normale più una riga che indica chi chiama.

Scheduler

L'orologio del grafo. Tre porte: agent (source, l'agente a cui un task scrive; il testo del task è il messaggio), tools (consumes, tool eseguibili direttamente senza agente) e schedule (exposes, tool per far pianificare all'agente i propri follow‑up, con limiti di frequenza, numero e durata). I task si scrivono nella sezione Scheduled tasks o da un agente, non nel nodo; ogni esecuzione è registrata. A quell'ora nessuno è collegato: il task usa solo risorse dell'organizzazione o dell'account fissato nel nodo.

06Dati e conoscenza

Tre nodi gestiti dalla piattaforma danno agli agenti e al codice uno stato persistente: un database relazionale, un file storage e una libreria di skill. In tutti e tre la description del nodo è contesto per il modello: dice cosa contiene, e l'agente la legge prima di cercare.

MySQL database (database)

Un database MySQL (InnoDB) creato e mantenuto dalla piattaforma, interrogabile da agenti e codice e consultabile dalla sezione Databases.

Porta Privilegi Uso tipico
admin ("Full access") DDL + DML Agente sviluppatore o codice che crea lo schema
rw ("Read & write") SELECT, INSERT, UPDATE, DELETE Agenti e app in esercizio
ro (aggiuntiva) sola lettura Analisi, reporting; con tableFilter (orders, order_*)

Ogni porta espone due tool:

Il tableFilter è applicato alla build: dopo aver creato le tabelle che nomina, si ricostruisce. Reset = database svuotato con stessi account e porte; rimozione = dati distrutti. Una richiesta di DDL su rw viene rifiutata.

Skill library

Istruzioni operative (procedure, checklist, stile, con file allegati) che l'agente carica solo quando servono. L'agente tiene in contesto l'elenco di una riga delle skill e legge per intero quella pertinente: una libreria lunga non costa finché non si usa. Il formato è Agent Skills (SKILL.md con name e description), lo stesso usato da Claude.

Una procedura nelle istruzioni dell'agente viene letta a ogni turno e non è riutilizzabile; come skill, no.

File storage (filestorage)

Un drive condiviso: gli agenti salvano e leggono file, le persone li aprono dalla sezione Files o dall'indirizzo del nodo.

Porta Tool
rw ("Read & write files") listFiles, getFile, putFile, deleteFile, moveFile, shareFile, unshareFile
ro ("Read files") listFiles, getFile

Non dare rw a un agente pubblico: potrebbe cancellare o condividere file.

07Codice ed esecuzione

Quattro nodi portano codice ed esecuzione nel grafo: il connector (funzioni TypeScript come tool), la sandbox (una shell Linux per l'agente) e le loro controparti on‑premise. Un quinto nodo avanzato, il graph editor, permette a un agente di modificare il proprio grafo.

Nodo Dove gira Cosa offre all'agente Persistenza
Connector Container cloud, Node.js 22 Le funzioni di tools.ts come tool tipizzati Repository git per nodo
Sandbox Container cloud Shell e file: exec, readFile, writeFile, editFile, listFiles Scope flow: effimera; scope node: condivisa e persistente
Machine at your site Server Linux o PC Windows del cliente Shell (sh o cmd) e file File system della macchina
Connector at your site Node.js sulla macchina del cliente Funzioni TypeScript vicino ai sistemi locali Repository git della piattaforma

Connector (connector)

Ogni funzione esportata da tools.ts diventa un tool con i suoi argomenti reali. È il modo per raggiungere un'API senza integrazione pronta, un calcolo proprio, una pulizia dati.

Porta Ruolo
functions ("Your functions") Le funzioni come tool, più call e listFunctions
developer ("Edit this workspace") Tool di sviluppo: exec, readFile, writeFile, editFile, listFiles, logs, commit, status, log
tools ("Tools the code can call") Tool di altri nodi raggiungibili dal codice come targets.<node>.<tool>(…)
agent ("Start a conversation") Un agente con cui il codice può conversare

"Start from" sceglie un template per il workspace (example, microsoft365). La variante Microsoft 365 offre posta, calendario, OneDrive/SharePoint, Teams e persone come funzioni estendibili: con una connection per‑membro ogni chiamata avviene come la persona che parla con l'agente, con una connection applicativa agisce sull'intera azienda. "Secrets" dichiara per nome le credenziali che il codice può leggere. Reset o rimozione distruggono repository, working copy e container: il workspace viene ricreato dal template.

Una funzione nuova raggiunge gli agenti al reload del codice, senza ricostruire il grafo. Fino ad allora è raggiungibile con listFunctions + call. Il tipo avanzato Hello world è un connector minimo che risponde con un saluto: serve a testare un collegamento.

Sandbox (sandbox)

Una macchina Linux in container dove l'agente esegue comandi e tiene file: analisi con Python, conversioni di documenti, script di prova.

I dati importanti vanno in un file storage o in un database, non nella sandbox.

Machine at your site

Una macchina del cliente (server Linux o PC Windows) dove l'agente esegue comandi e legge o scrive file, accanto a sistemi senza API: un client di database legacy, cartelle condivise, un programma desktop. La macchina va prima registrata in Sites installando l'agente TeraBrain NX; poi si seleziona nel campo "Site". "Working directory" (avanzato) indica dove partono i comandi. Se la macchina è offline il nodo si costruisce comunque e ogni comando risponde che è offline. I comandi girano con i diritti con cui l'agente del sito è stato installato: mai a un agente pubblico.

Connector at your site

Un connector che gira su una macchina del cliente invece che in cloud: funzioni TypeScript vicino a un ERP in rete locale, un database senza indirizzo pubblico, una cartella condivisa. Node.js gira sulla macchina; il codice resta nel repository della piattaforma. Stesse porte del connector. Offline, si costruisce comunque e si riallinea da solo alla riconnessione. Se il codice non ha bisogno di nulla di locale, un connector cloud è più semplice.

Graph editor (avanzato)

La porta graph ("Edit this graph") dà a un agente i tool per leggere il proprio grafo, aggiungere e collegare nodi, cambiare campi, ricostruire e tornare a una versione precedente. Agisce solo sul grafo in cui vive. Ogni modifica è una nuova versione; i tool dell'agente stesso si aggiornano al turno successivo. Rimuovere un nodo con dati chiede conferma.

08Integrazioni MCP in ingresso

TeraBrain NX usa MCP in entrambe le direzioni. Il nodo MCP server (§5) espone il grafo all'esterno; i due nodi qui sotto portano dentro il grafo i tool di server MCP di terzi, come se fossero tool nativi. Entrambi hanno una sola porta, tools, da collegare alla porta tools degli agenti.

Remote MCP server Hosted MCP server
Per server pubblicati sul web (GitHub, Linear, Notion, un altro grafo TeraBrain NX) distribuiti come comando (npx …, uvx …)
Dove gira presso il fornitore in un container dedicato della piattaforma
Configurazione Server URL command come array, variabili d'ambiente
Credenziali nessuna, bearer token o OAuth variabili d'ambiente: valori o secret dell'organizzazione
Credenziali per‑membro sì (userSecretRef o OAuth per membro) no: un processo per tutti
Variante pronta — Playwright browser

Remote MCP server

L'autenticazione può essere assente, un bearer token (valore, secret dell'organizzazione {"secretRef": …}, secret personale {"userSecretRef": …} o connection {"connection": …}), oppure OAuth, collegato una volta dall'admin per tutta l'organizzazione o da ogni membro dal proprio profilo.

I tool vengono elencati alla build. Se il server non è raggiungibile o nessuno si è ancora collegato, il nodo si costruisce comunque con un tool generico e una nota; dopo il collegamento si ricostruisce per ottenere i tool reali. La description del nodo dà il nome ai tool letti dall'agente.

Un token personale su un agente che lavora senza nessuno collegato (mailbox, task schedulato) non funziona: non c'è un utente di cui usare il token.

Hosted MCP server

Esegue il programma del server nel proprio container, per esempio ["npx", "-y", "pkg@latest"]. Il primo avvio scarica il server e può richiedere minuti; se non parte, il nodo si costruisce con una nota e un tool generico, e i log ne spiegano il motivo.

09Telefonia

La telefonia è un piccolo centralino SIP dentro il grafo. Una chiamata entra dalla linea, attraversa nodi di instradamento (orari, routing per numero, menu a tasti) e arriva a un nodo voice, che la trasforma in una conversazione con un agente, oppure a un interno per una persona reale. Una chiamata non va mai direttamente a un agente.

Nodo Porte Funzione
Phone line inbound, outbound (source); calls (tool "Place a call") Account SIP presso il provider o centralino proprio
Phone extension calls (sink e source), noAnswer Interno per telefono fisso, softphone o browser
Call routing in + route dichiarate Instrada per numero chiamato (to) e chiamante (from)
Opening hours in, open, closed Instrada in base a giorni, orari e festività
Phone menu in + route per tasto IVR "premi 1 per…" con messaggio sintetizzato

Phone line

Si configurano host SIP del provider, utente e password (meglio come secret). Il pannello del nodo indica se la linea è registrata; una password errata non fa fallire la build, lascia la linea non registrata. Più numeri sullo stesso account = più voci in ingresso, ognuna con i suoi numeri. I chiamanti con numero presente nel profilo di un membro vengono riconosciuti. "Record every call" è tra i campi avanzati.

La porta tool calls permette a un agente di telefonare: la chiamata è poi condotta dall'agente dietro outbound, attraverso un nodo voice, sulla base del brief scritto dal primo agente. Limitare sempre i numeri con allow (es. ["+39*"]).

Phone extension

Un numero interno unico nel grafo. Senza password impostata ne viene generata una, sufficiente per il telefono nel browser ("Open phone" nel pannello, con "Usable from the browser"); per un telefono fisso o un'app si imposta una password, meglio come secret. "Whose phone this is" attribuisce le chiamate a un membro. Se nessuno risponde (25 s di default) la chiamata va su noAnswer, per esempio a un nodo voice che prende un messaggio; se scollegata, si chiude. Due interni non si chiamano direttamente: il numero composto è instradato da un nodo Call routing. Per trasferire un chiamante su un interno, il numero va nella directory del nodo voice.

Call routing

Le regole si valutano in ordine e vince la prima che corrisponde. Ogni regola guarda to, from o entrambi con pattern come +3902*; una regola senza condizioni prende tutto. Le route in uscita vanno dichiarate nel nodo (una per destinazione, con id breve come sales, support); una regola la cui route non è collegata viene saltata. "Where unmatched calls go" nomina la route di default; senza, la chiamata viene chiusa. I pattern vanno scritti con il prefisso internazionale se la linea riporta i numeri come +39…: il formato reale si vede in Calls.

Opening hours

Time zone IANA (es. Europe/Rome), fasce di giorni (mon…sun) e orari HH:MM, festività YYYY-MM-DD nei campi avanzati. Due fasce per la pausa pranzo. Una fascia a cavallo della mezzanotte non corrisponde mai: si scrivono due fasce, fino alle 24:00 e dalle 00:00. closed scollegato = chiamata chiusa senza messaggio.

Phone menu

Il messaggio è sintetizzato una volta dal TTS scelto e riutilizzato: va scritto per intero, opzioni comprese. Ogni tasto (0–9, *, #) nomina una route verso un nodo voice, un interno o un altro menu. Senza tasto o con un tasto non valido il messaggio si ripete (due volte di default), poi la chiamata va a "Where invalid keys go" o si chiude. Per richieste espresse a parole è meglio un nodo voice che lasci decidere all'agente.

10Sviluppo dei workspace TypeScript

Connector, web app e connector at your site contengono un workspace: un progetto Node.js 22 eseguito in container e, insieme, una working copy git il cui origin è il repository del nodo. Il file autorevole è teranext/README.md, rigenerato a ogni build con i target reali del nodo: va letto prima di toccare il codice.

Struttura e ciclo di vita

/workspace
├── tools.ts          # funzioni esposte come tool
├── app.ts            # solo web app: handler HTTP
├── public/           # solo web app: file statici
├── package.json, tsconfig.json
└── teranext/         # generato a ogni build, committato, da non modificare
    ├── README.md     # documentazione del workspace
    ├── functions.ts  # defineFunction
    ├── tools.ts      # targets, secrets, users, organization, file helper
    └── agents.ts     # solo con porte agent collegate

Lavorare da IDE

Ogni workspace ha un repository clonabile, mostrato nella sezione Code con il pulsante "Clone in VS Code":

git clone https://<utente>@api.nx.terabrain.ai/admin/repo/<graphId>/<nodeId> <nodeId>

La password è quella della console o un token. Chi fa push da un clone aggiorna main; la working copy del container segue main mantenendo le modifiche non committate, salvo conflitti (il tool status segnala quando è indietro). La vista Code mostra working copy o main, history per file e cartella.

Esporre funzioni: tools.ts

import { z } from "zod";
import { defineFunction } from "./teranext/functions";

export const tools = {
  greet: defineFunction({
    description: "Greets someone by name.",
    input: z.object({ name: z.string().describe("Who to greet") }),
    output: z.object({ greeting: z.string() }),
    handler: async ({ name }) => ({ greeting: `Hello, ${name}!` }),
  }),
};

L'input è validato con Zod prima dell'handler; il risultato deve essere serializzabile in JSON. La description è ciò che l'agente legge. call e listFunctions sono nomi riservati. L'handler riceve un secondo argomento ctx con flowId (la conversazione) e userId (l'utente per cui avviene la chiamata).

Chiamare altri nodi: targets

I tool collegati alla porta tools del nodo sono disponibili in teranext/tools.ts come funzioni async tipizzate, indirizzate per nodo provider:

import { targets } from "./teranext/tools";

const rows = await targets.tasks_db.query(
  { sql: "SELECT id, title FROM tasks WHERE status = ?", params: ["open"] },
  { userId: ctx.userId },
);

File e risorse

Tutti i tool TeraBrain NX rispondono con la stessa forma: testo piccolo inline, il resto allegato alla conversazione come risorsa (resourceId).

import { fileResult, resourceInput } from "./teranext/tools";

handler: async ({ asResource, resourceId }, ctx) => {
  const source = resourceId ? await resourceInput(ctx, resourceId) : undefined;
  const data = render(source);
  return fileResult(ctx, { name: "report.csv", mimeType: "text/csv", data, asResource });
}

fileResult restituisce inline fino a 64 KB di testo e allega il resto. asResource: true forza il riferimento. Conviene offrire asResource e resourceId come input opzionali di ogni funzione che produce o consuma file. Senza conversazione (ctx.flowId assente) non c'è dove allegare: la regola automatica degrada a ciò che sta inline, e un asResource esplicito lancia errore.

Secrets

Nessuna variabile d'ambiente né file: il codice chiede il valore quando serve, per nome dichiarato nel nodo.

import { secrets } from "./teranext/tools";

const token = await secrets.get("openaiToken");            // secret dell'organizzazione
const mine  = await secrets.get("crmToken", { userId });    // secret per‑utente

Utenti e variabili

users.get, users.getByEmail, users.getByIdentity(provider, id), users.list() restituiscono membri con userId, email, name, identities, role, groups. Le variabili per utente (users.getVariable/setVariable/deleteVariable/listVariables) e per organizzazione (organization.getVariable/…) sono valori JSON condivisi da tutti i nodi dell'organizzazione: preferenze, cursori, memorie. Mai credenziali.

Variabili d'ambiente del runtime

Variabile Contenuto
TERANEXT_BRIDGE_URL, TERANEXT_BRIDGE_TOKEN Usate da teranext/tools.ts; mai inviarle al browser
TERANEXT_REPO_URL Repository del nodo (origin)
TERANEXT_WORKDIR Directory del workspace
TERANEXT_PUBLIC_URL Solo web app: URL pubblico
TERANEXT_AUTH_URL Solo web app: pagine di login e logout

11Web app con assistente

Una web app con una chat all'interno è il caso d'uso principale della piattaforma. Il turno dell'agente gira dentro TeraBrain NX; la pagina si limita a osservarlo. Per questo un reload a metà risposta o una risposta di un'ora non perdono nulla.

L'applicazione HTTP

L'app risponde su https://api.nx.terabrain.ai/graph/<graphId>/node/<nodeId>/app/ (o su un hostname dedicato). Un file in public/ che corrisponde al percorso è servito così com'è (index.html per le directory). Altrimenti risponde app.ts, che esporta di default una di queste forme:

L'app è montata sotto un prefisso: l'handler vede percorsi relativi e i link nelle pagine devono essere relativi (./style.css, api/hello), mai assoluti. Il prefisso arriva nell'header X-Forwarded-Prefix. Solo HTTP request/response viene proxato: niente WebSocket, quindi lo streaming usa Server‑Sent Events.

Identità del visitatore

La piattaforma imposta questi header e rimuove quelli in ingresso, quindi non sono falsificabili:

Header Contenuto
x-teranext-principal anonymous, user o operator
x-teranext-user-id Id del visitatore
x-teranext-email, x-teranext-name (URL‑encoded) Solo membri
x-teranext-role, x-teranext-groups (separati da virgola) Solo membri

Il userId si legge sempre dall'header, mai da ciò che invia il browser. Un'app riservata reindirizza il browser anonimo al login (TERANEXT_AUTH_URL). Il logout è un form POST a ${TERANEXT_AUTH_URL}logout con un campo next; la sessione è unica per il deployment, quindi esce da console e app insieme.

Parlare con gli agenti: teranext/agents.ts

Gli agenti collegati alle porte source del nodo sono client di conversazione (agents.<porta>). Il codice nomina la porta; quale agente risponde lo decide il cablaggio del grafo.

Metodo Scopo
open({ key?, userId?, parentFlowId?, traces? }) Apre (o ritrova per key) una conversazione → { flowId, created }
send(text, { flowId?, userId?, resourceIds?, mode?, timeoutSeconds? }) Invia e attende, oppure mode: "background" e ritorna subito. Un turno alla volta: il secondo è 409
events(flowId, { userId? }) Stream infinito: state, poi chunk, reply, trace, heartbeat
cancel(flowId, { userId? }) Ferma il turno in corso
stream(…) Eventi di questa chiamata fino a result: per funzioni che inoltrano il progresso
list({ key?, userId?, parentFlowId?, limit?, cursor? }) Conversazioni con preview e lastMessageAt
history(flowId, { userId?, limit?, cursor?, reverse? }) Messaggi, tool activity come trace, risorse, busy

Il bridge risponde 403 per una conversazione che non appartiene al userId passato. Le conversazioni senza messaggi oltre il periodo di retention dei log (30 giorni di default) vengono eliminate: list non le mostra più e il flowId risponde 404.

Il pattern di chat corretto

La recipe "Web app with an assistant" e il README del workspace descrivono una chat completa con sette route:

Route Implementazione
GET /api/conversations chat.list({ userId, limit: 50 }): la sidebar
POST /api/conversations chat.open({ userId, traces: true }): pulsante New conversation, senza key
GET /api/history chat.history(flowId, { userId }): il passato
GET /api/events eventStreamResponse(chat.events(flowId, { userId })): il presente, in SSE
POST /api/message uploadResource per ogni file (max 25 MB), poi chat.send(…, { mode: "background" }) e risposta 202
POST /api/cancel chat.cancel(flowId, { userId }): pulsante Stop
GET /api/resource Controllo di proprietà via history, poi readResource(flowId, resourceId) con il MIME type

Regole di UX che il README rende obbligatorie:

Una funzione può passare un file ricevuto a un agente senza leggerne i byte: agents.agent.send(task, { parentFlowId: ctx.flowId, userId: ctx.userId, resourceIds: [input.resourceId] }).

12Builder e assistenti esterni

I grafi si possono costruire e sviluppare conversando: con il Builder integrato (sezione Build) o con un assistente esterno collegato dal profilo. Entrambi lavorano con i diritti della persona, in una organizzazione, e ogni modifica diventa una nuova versione del grafo registrata a suo nome; nel log Changes compare come "via Builder" o "via MCP".

Collegare un assistente esterno

In Profile → "Connect an assistant" si sceglie l'organizzazione, si dà un nome al client ("Claude Desktop sul mio laptop") e si crea un token. Client supportati: Claude Desktop, Cowork, Claude Code, Codex. Ogni assistente ha il proprio token, revocabile in qualsiasi momento; la creazione è tracciata come access-token.create.

Non va confuso con il nodo MCP server (§5): quello espone i tool e un agente di un singolo grafo, questo espone la piattaforma per costruire grafi.

Cosa legge il Builder

La pagina Docs → "What the Builder is told" pubblica il primer che il Builder e gli assistenti collegati leggono prima di costruire; le pagine dei tipi di nodo e delle recipe sono lo stesso testo servito dal tool catalog. Il ciclo di lavoro prescritto:

  1. Capire cosa c'è: organization (secret e connection per nome, model profile, sites, servizi), recipes, listGraphs, describeGraph.
  2. Leggere prima di scrivere: catalog {type} per ogni tipo usato, con guida, campi (JSON Schema), id delle porte ed esempi. Mai indovinare un nome di campo.
  3. Partire da una recipe quando calza: createGraph {name, recipe}.
  4. Costruire con applyGraph, una chiamata per pezzo coerente (un canale, il suo agente, i suoi tool), con dryRun: true in caso di dubbio. updateNode, connect e simili servono per le correzioni.
  5. Verificare con checkGraph dopo ogni modifica.
  6. In caso di errore: status, poi logs (solo admin), correggere la causa. rollback è la via d'uscita da una build rotta.

Per il codice: workspace {graph, node} per primo, sempre, perché restituisce il README; poi readFile, editFile (sostituzione esatta, preferita a writeFile), exec (es. npx tsc --noEmit), appLogs, nodeTools e callNodeTool per provare le funzioni, e commit dopo ogni modifica coerente.

Protezioni

Il Builder risponde nella lingua dell'utente, senza gergo né JSON, dice cosa ha costruito e cosa resta da fare all'utente (impostare un secret, creare un bot, registrare un numero). Nella vista Build il grafo si disegna in tempo reale e ogni nodo diventa verde quando gira.

13Modelli LLM

I modelli si configurano per organizzazione in Organization → Settings, in due livelli: AI Providers (gli endpoint) e Model Profiles (configurazioni nominate che gli agenti referenziano). Qualunque endpoint compatibile con le API OpenAI può essere un provider, quindi anche un LLM privato o on‑premise esposto con un'interfaccia compatibile.

AI Providers

Campo Descrizione
Provider Id Nome con cui i model profile si riferiscono al provider (es. openrouter, openai)
Api Type Protocollo: completions (OpenAI Chat Completions) o responses (OpenAI Responses)
Base Url URL base dell'API, es. https://api.openai.com/v1
Api Key Inviata come bearer token; mascherata in console

Model Profiles

Campo Descrizione
Profile Id Nome usato dagli agenti nel campo Model
Provider Id Uno dei provider dell'organizzazione
Model Nome del modello come lo attende il provider
Settings Parametri di chiamata; il loro apiType deve coincidere con quello del provider

Parametri disponibili secondo il protocollo:

Default e scelta per agente

"Default model" indica il profilo usato dagli agenti che non ne nominano uno (se non impostato, il primo profilo). Ogni agente può sceglierne un altro: in un team di agenti conviene un modello piccolo e veloce in prima linea e uno più capace per il lavoro difficile. Il campo Model dell'agente mostra sempre quale sia il default corrente dell'organizzazione.

Il Timezone dell'organizzazione (IANA, Europe/Rome se non impostato) è il fuso degli orologi dell'organizzazione e il default dei task schedulati che non ne indicano uno.

14Sicurezza e governance

La sicurezza di un grafo si regge su quattro leve: i ruoli delle persone, le credenziali referenziate per nome e mai esposte, il minimo privilegio sulle porte, e il controllo d'accesso di ogni canale. Tutte le modifiche restano tracciate (§15).

Organizzazioni e ruoli

Una persona può appartenere a più organizzazioni e cambiarle dal selettore in console. In Organization → Members ogni membro ha un ruolo, gruppi e un'eventuale identità Telegram collegata.

Ruolo Permessi
user Conversa con gli agenti consentiti e apre le app dell'organizzazione
fullmember In più costruisce: grafi, codice, dati
admin In più gestisce impostazioni, membri, secret e connection dell'organizzazione

I gruppi servono a restringere agenti ("Who may talk to it"), web app, bot, mailbox e librerie di skill a un sottoinsieme di membri.

Secrets

I valori sensibili non transitano mai verso il browser: scriverne uno lo sostituisce, nessuno può rileggerlo. Un nodo li referenzia così:

Riferimento Significato
{"secretRef": "NAME"} Secret dell'organizzazione, impostato da un admin in Organization → Secrets
{"userSecretRef": "NAME"} Secret personale di ogni membro, impostato dal proprio profilo
{"connection": "name"} Token OAuth di una connection, rinnovato dalla piattaforma

La tabella Secrets mostra per ogni nome lo stato (set, connected (OAuth)), chi l'ha impostato e quale nodo lo richiede.

Connections (OAuth)

Una connection è un'applicazione OAuth registrata una volta presso un provider (Microsoft 365, Google, un CRM). Scope organization: la collega un admin; scope user: la collega ogni membro dal proprio profilo, e il token finisce in un suo secret. Il redirect URI da registrare presso il provider è unico per tutto il deployment: https://api.nx.terabrain.ai/auth/connect/callback.

Identità e SSO

Organization → Identity abilita il login tramite directory aziendale; oggi è implementato Microsoft Entra ID. Chi ha un account nel tenant e un'email di uno dei domini configurati entra con un pulsante, senza password TeraBrain NX.

Variabili

Organization → Variables e Profile → Variables contengono stato di runtime non segreto (valori JSON), leggibile e scrivibile dai nodi. Le credenziali vanno sempre nei secret.

Minimo privilegio: checklist

15Osservabilità

Ogni conversazione, chiamata di tool e modifica del grafo è registrata e consultabile dalla sezione Logs, con export CSV e JSONL. In fase di sviluppo si aggiungono Checks e Try it nell'editor e il tool logs dei workspace.

Logs

Vista Cosa mostra Filtri
Flows Una riga per conversazione: quando, origine, persona, primo messaggio, numero di tool call, errori, durata Grafo, periodo, origine, nodo, persona, "With errors"
Tool calls Una riga per chiamata: tool, provider, chiamante (e conversazione), persona, esito, durata Grafo, periodo, tool, provider, persona, connection, esito
Graph Il grafo con le linee pesate per numero di chiamate (scala log) e colorate per tasso d'errore Grafo, periodo
Changes Audit: chi (anche "via Builder" o "via MCP"), azione (graph.create, graph.update, node.rebuild, access-token.create…), oggetto, dettagli, esito, Diff Periodo, grafo, persona, azione
Person Tutto ciò che un membro ha fatto o causato Membro, periodo

Le origini filtrabili sono Console chat or app, Telegram, Email, Phone, Scheduled task, Delegated, Request, Operator, System. I periodi vanno da un'ora a 30 giorni o personalizzati.

Tracing di una conversazione

Aprendo un flow si ottiene la sua traccia completa, con tre viste:

Il pannello di dettaglio riporta origine, persona, chi ha aperto e chi ha risposto (nodo e porta), inizio e durata, numero di tool call ed errori, ultimo errore, e i token dichiarati dal modello in ingresso e in uscita. Sotto c'è la trascrizione con ogni calling / result of in ordine.

La vista Graph segnala anche le chiamate tra nodi che nessuna linea di tool collega più (per esempio dopo una modifica), utile per trovare dipendenze rimaste nel codice.

In fase di sviluppo

La retention dei log dipende dall'organizzazione (30 giorni se non diversamente configurato); le conversazioni inattive oltre quel periodo vengono eliminate.

16Recipes

Una recipe è un grafo di partenza già cablato: si usa da Graphs → New graph, si inserisce in un grafo esistente dai Patterns dell'editor, oppure si chiede al Builder (createGraph {name, recipe}).

Recipe Nodi Da compilare Nota tecnica
Telegram assistant telegram, agente Token del bot (o nome di un secret) Di default risponde a chiunque trovi il bot
Web app with an assistant webapp, agente Nome dell'app, riga descrittiva Accesso di default organization; le funzioni dell'app sono i tool dell'assistente
Mailbox assistant mailbox hosted, agente Parte prima della @ Lavora senza nessuno collegato: solo risorse dell'organizzazione o di un account fissato
Phone receptionist linea SIP, orari, voice, agente Host SIP, account, password, chiavi ElevenLabs Orari iniziali lun–ven 9–13 e 14–18, Europe/Rome; closed scollegato
Agent with your code connector, database, agente Descrizione del codice e del database L'agente ha rw sul database (non crea tabelle); "Edit this workspace" lasciato scollegato di proposito
Team of agents tre agenti: Front desk, Specialist, Colleague Ruolo di specialist e colleague Specialist via delegate, Colleague via handoff; per un terzo collega si copia un link

Dopo la creazione, ogni recipe richiede gli stessi passi: scegliere il modello (o lasciare il default), riscrivere le istruzioni dell'agente, salvare e costruire, poi collegare i tool o il canale che mancano.

17Best practice e riferimento rapido

Progettazione

Sviluppo

Errori tipici

Sintomo Causa probabile
Il bot Telegram non riceve messaggi Stesso token su un altro nodo o grafo costruito dopo
La linea SIP non riceve chiamate Password errata (linea non registrata) o stesso account su due linee
L'agente non riesce a creare tabelle Ha solo rw: serve admin o uno sviluppatore
L'agente al telefono non trasferisce control non collegato o directory vuota
Una regola di routing non scatta mai Pattern senza prefisso internazionale, o route non collegata
Gli orari notturni non funzionano Fascia a cavallo della mezzanotte: usare due fasce
Hosted MCP non parte Server Python su immagine Node, o browser senza memoria sufficiente
I file della sandbox spariscono Scope flow: la macchina è per conversazione
Un task schedulato fallisce sull'account Nessuno è collegato all'ora del task: usare risorse dell'organizzazione
Errore 409 da send Un turno è già in corso sulla conversazione

Riferimento rapido delle porte

Tipo Provides tools Uses tools Starts conversations Answers
Agent developer tools delegate, handoff sink
Web app functions, developer tools agent —
Connector / at your site functions, developer tools agent —
Telegram bot — — source —
Mailbox mail — inbound —
MCP server — tools agent —
Voice control — agent calls
Scheduler schedule tools agent —
MySQL database admin, rw (+ ro) — — —
Skill library rw, ro — — —
File storage rw, ro — — —
Sandbox sandbox — — —
Machine at your site site — — —
Graph editor graph — — —
Remote / Hosted MCP server tools — — —
Phone line calls — inbound, outbound —
Phone extension — — calls, noAnswer calls
Call routing — — route dichiarate in
Opening hours — — open, closed in
Phone menu — — route per tasto in