← Indice documentazione Guida all'architettura › API HTTP

Metnos

Chat web e API HTTP
Un solo confine per conversazione, amministrazione e stato riprendibile.

metnos_http_server serve la chat web, l'API dei turni e l'area Settings. Il valore predefinito è 127.0.0.1:8770; un'installazione può cambiare indirizzo e porta. Il protocollo degli executor remoti su 8765 e il servizio browser su 8771 sono componenti distinti, con autorità e rotte proprie.

Indice

  1. Un esempio in linguaggio naturale
  2. Composizione del server
  3. Rotte principali
  4. Identità e autorizzazione
  5. Sessioni e isolamento per utente
  6. Turni sincroni e riprendibili
  7. HTML, JSON e cache
  8. Settings e localizzazione
  9. Confini di rete e capacità
  10. Verifica e fonti canoniche

1. Un esempio in linguaggio naturale

Chiedi a Metnos con una richiesta come quella di questo esempio:

Mostrami dove posso verificare i turni recenti e cambiare la configurazione dei modelli.

La risposta deve iniziare dal percorso della chat: Settings > Attività > Turni e Settings > Sistema > Modelli. Se la domanda proviene da Telegram, va precisato che Settings si apre nella chat web. Solo a chi chiede un'integrazione tecnica servono poi i percorsi HTTP /admin/turns e /admin/virt.

2. Composizione del server

La factory make_app crea una sola applicazione aiohttp con limite del corpo a 50 MiB e monta tre registri di rotte:

ModuloResponsabilità
http_routes_agent.pyChat, discovery, turni, sessioni, dialoghi, allegati, associazione web e callback OAuth.
http_routes_admin.pySettings, utenti, modelli, servizi, dispositivi, scheduler, Safety ed evoluzione degli executor.
http_routes_stack.pyProntezza complessiva di server, catalogo e servizio browser.

I middleware vengono applicati nello stesso ordine a tutte le rotte: prima classificano il chiamante, poi impostano nel contesto della richiesta la lingua del suo utente. Il contesto linguistico viene copiato anche nel pool che esegue i turni, così richieste concorrenti non condividono una variabile di lingua globale.

2.1 Servizi adiacenti

3. Rotte principali

3.1 Accesso iniziale e discovery

Metodo e percorsoFunzioneAccesso
GET /Chat web; un anonimo viene rinviato all'accesso amministrativo.Utente o amministratore; apertura iniziale ammessa per il rinvio.
GET /agent/healthVitalità, versione dell'API, versione del prodotto e tempo di attività.Anonimo.
GET /.well-known/metnos.jsonDescrittore del nodo e URL di associazione; non pubblica chiavi o impronte amministrative.Anonimo.
POST /agent/registerConsuma il token monouso di un executor remoto.Anonimo con token valido.
GET /pair/{token}Consuma un token web e imposta il cookie del dispositivo associato.Anonimo con token valido.
GET /oauth/callbackCompleta un flusso OAuth usando lo stato breve emesso da Metnos.Pubblica per necessità del reindirizzamento; lo stato è il vincolo.

Manifesto PWA, service worker e file sotto /static/ sono leggibili senza autenticazione. Le fotografie sotto /agent/photos/ usano invece un URL firmato e a scadenza: l'URL stesso è una capacità e va trattato come riservato.

3.2 Turni, sessioni e dialoghi

GruppoPercorsiContratto
Turno direttoPOST /agent/turnJSON oppure flusso SSE sulla stessa connessione.
Turno riprendibilePOST /agent/turn/submit; GET /agent/turns/{id}/stream; GET /agent/turns/{id}Accettazione immediata, eventi ricollegabili e ripiego tramite polling.
Cronologia e giudizioGET /agent/turns/recent; POST /agent/turns/{id}/feedback; POST /agent/turns/{id}/retryCronologia della conversazione, riscontro esplicito e ripetizione.
Sessione di scrittura/agent/session/register, takeover, ping, revoke, eventsUn dispositivo scrivente per coppia utente-canale e trasferimento esplicito.
Dialoghi/agent/dialog/{id}/form, submit, cancel, preview, contextRaccolta di input con proprietario e, quando serve, capacità delegabile a breve durata.
Allegati/agent/gallery/{turn_id}, /agent/photos/{turn_id}/{idx}, /agent/photos/webGalleria vincolata al proprietario; file locali con URL firmati; proxy web con difese SSRF e limiti di dimensione.

3.3 Amministrazione

Tutte le rotte sotto /admin, salvo il modulo di accesso, richiedono il ruolo amministratore. Le aree principali sono:

Il registro completo delle rotte è nel codice e resta la fonte canonica. Questo raggruppamento spiega la superficie senza congelare un conteggio destinato a cambiare.

4. Identità e autorizzazione

Il middleware assegna uno dei tre ruoli anonymous, user o admin:

  1. un Bearer uguale alla chiave amministrativa assegna admin;
  2. un altro Bearer è valido soltanto se corrisponde a un dispositivo registrato;
  3. in assenza di Bearer, un cookie amministrativo o utente valido assegna il ruolo corrispondente; il cookie utente viene inoltre ricontrollato nel registro delle associazioni, che è l'autorità di revoca;
  4. in assenza di credenziali presentate, alcuni indirizzi locali possono ricevere il ruolo user come compatibilità di installazione;
  5. altrimenti il chiamante resta anonimo.

Un Bearer errato non cade nel ripiego della rete locale. Gli header CF-Connecting-IP e X-Forwarded-For sono considerati soltanto quando il peer TCP appartiene a METNOS_TRUSTED_PROXIES; un client ordinario non può dichiararsi locale tramite un header.

La chiave amministrativa vive in PATH_USER_CONFIG/admin.key, viene creata con permessi 0600 e serve anche a derivare firme e chiavi di cifratura con domini separati. Il cookie amministrativo dura sette giorni, è HttpOnly, Secure e SameSite=Strict; quello utente dura novanta giorni ed è HttpOnly, Secure e SameSite=Lax.

5. Sessioni e isolamento per utente

La sessione attiva è indicizzata dalla coppia (user_id, channel). Host e guest possono quindi usare la chat contemporaneamente senza condividere lease, conversazione o memoria locale del browser. Il client separa anche token, buffer dei comandi e cronologia mediante uno scope opaco derivato dall'utente.

Quando un secondo dispositivo trova una sessione attiva, il server emette un token monouso e lascia tre scelte all'interfaccia:

Il trasferimento ricontrolla atomicamente utente e vecchio scrivente. La cronologia recente richiede una conversazione appartenente all'utente. Anche stato, stream, galleria, feedback e ripetizione verificano il proprietario del turno: conoscere un turn_id non concede accesso. I vecchi record senza owner_user_id usano soltanto associazioni deterministiche di conversazione o attore; un errore del registro identità viene negato, non trasformato in permesso.

6. Turni sincroni e riprendibili

6.1 Chiamata diretta

POST /agent/turn accetta JSON oppure multipart con una richiesta e immagini di riferimento. Con Accept: text/event-stream invia eventi thinking, progress, tool_call e infine final o error; commenti periodici mantengono viva la connessione. Senza SSE restituisce un unico documento JSON.

6.2 Esecuzione disaccoppiata dalla connessione

POST /agent/turn/submit riserva prima una posizione nel pool e risponde 202 con turn_id e stream_url. Il turno continua anche se la pagina viene aggiornata o la rete cade. Lo stream accetta Last-Event-ID e riproduce gli eventi successivi; GET /agent/turns/{id} è il ripiego di polling.

Gli eventi in memoria restano per un intervallo limitato dopo la chiusura. Quando non sono più presenti, lo stato cerca il record persistito nel registro giornaliero. La persistenza non sostituisce il controllo del proprietario.

6.3 Capacità limitata

I turni bloccanti passano da un pool dedicato con limite globale, coda finita e limite per principal. Se la riserva non arriva entro il tempo ammesso, il server risponde 503 turn_capacity_exhausted con Retry-After: 1. Una disconnessione non libera prematuramente il posto mentre il thread continua a lavorare.

7. HTML, JSON e cache

Le collezioni amministrative che usano negotiate_collection restituiscono HTML quando Accept include text/html, altrimenti JSON. Il corpo riceve un ETag derivato da SHA-256; un If-None-Match uguale produce 304. Non tutte le rotte usano questa negoziazione: alcune sono solo HTML, solo JSON o SSE.

La chat imposta no-cache, no-store perché il client deve ricevere il contratto aggiornato. Le risposte negoziate amministrative hanno cache privata breve; configurazione dei modelli e servizi usano no-store. Gli URL firmati degli allegati hanno una durata propria e non vanno confusi con una sessione utente.

8. Settings e localizzazione

Settings usa template Jinja2, il registro runtime/ui_surfaces.py per navigazione e descrizioni, htmx per alcuni aggiornamenti e uPlot soltanto nella vista statistica degli executor. Non esiste una fase di compilazione front-end.

Ogni testo visibile deve provenire dal catalogo i18n o da dati già localizzati. La lingua è una preferenza del singolo utente e vive in un ContextVar per richiesta; una nuova lingua richiede voci del catalogo, lessico di riconoscimento e documentazione corrispondente, non condizioni per singole frasi nel template.

Settings è l'interfaccia amministrativa interattiva. Il rendiconto HTML generato da runtime.observability è invece un artefatto separato, descritto nella guida all'osservabilità operativa.

9. Confini di rete e capacità

10. Verifica e fonti canoniche

curl -fsS http://127.0.0.1:8770/agent/health
curl -fsS http://127.0.0.1:8770/.well-known/metnos.json
curl -fsS -H "Authorization: Bearer <chiave-amministrativa>" \
  http://127.0.0.1:8770/agent/stack/health

La prima sonda prova soltanto la vitalità. La terza è l'evidenza adatta prima di un riavvio o di un collaudo complessivo. Le suite sotto tests/runtime/http/ verificano autenticazione, sessioni, isolamento dei turni, SSE, cache, upload, rendering e pagine amministrative; la guida non fissa un numero di prove.