API — Nexus WebUI
façade WebUI, streaming chat, modèles, feedback et outils documentaires bornés
La façade /api/nexus-webui/* adapte les autorités Nexus à une interface de
chat compatible OpenAI/OpenWebUI : utilisateur courant, choix de scope,
catalogue de modèles, streaming, feedback et outils documentaires bornés.
Les schémas exhaustifs sont dans openapi.json.
Contrat disponible
| Méthode | Endpoint | Rôle |
|---|---|---|
GET | /api/nexus-webui/bootstrap | Utilisateur sûr, ACL sources, options et défauts de scope, features |
GET | /api/nexus-webui/models | Modèles Nexus actifs au format catalogue WebUI |
POST | /api/nexus-webui/chat/completions | JSON OpenAI-compatible si stream=false, SSE enrichi Nexus si stream=true |
POST | /api/nexus-webui/feedback | Feedback lié à un query_id du tenant |
POST | /api/nexus-webui/chat/stop | Accusé best-effort d'une demande d'arrêt |
POST | /api/nexus-webui/chat/completed | Accusé de fin de message WebUI |
GET | /api/nexus-webui/tools/openapi.json | Catalogue allowlist des outils documentaires |
POST | /api/nexus-webui/tools/inspect-scope | Volumes, facettes, dates Nexus et ressources récentes |
POST | /api/nexus-webui/tools/list-resources | Ressources dédupliquées et paginées |
POST | /api/nexus-webui/tools/search-documents | Retrieval de chunks sans seconde génération LLM |
POST | /api/nexus-webui/tools/read-document | Lecture textuelle bornée d'un document autorisé |
Les imports, actions externes et send-to-nexus décrits dans les anciennes
spécifications ne font pas partie du contrat actuel.
Authentification et scope
- Un sujet Nexus authentifié est requis sur chaque endpoint.
- Les modèles, le chat et les outils exigent
nexus.query. - Un
source_appdemandé doit appartenir aux sourcescan_readdu principal. workspaceexigesource_app;projectexigeworkspace.- Le backend réimpose le scope sélectionné à chaque appel d'outil. Ni le modèle ni un argument d'outil ne peuvent l'élargir.
- Le feedback vérifie que le
query_idappartient au tenant courant.
Le bootstrap retourne contract_version="nexus_webui.v2". Les tableaux
permissions.source_apps, scope_options.workspaces et
scope_options.projects sont déjà filtrés par les ACL Nexus. Un client ne doit
pas reconstruire des droits plus larges à partir d'autres données locales.
Chat completions
Exemple minimal :
{
"stream": true,
"model": "openai:gpt-5-mini",
"messages": [
{"role": "user", "content": "Résume les annonces récentes."}
],
"nexus_scope": {
"source_app": "articles",
"workspace": "veille",
"project": "produits"
},
"webui": {
"chat_id": "chat-local-123",
"message_id": "message-local-456"
}
}Le payload refuse les champs inconnus. Il doit contenir au moins un message
user.
- avec
stream=true, la réponse utilisetext/event-stream, désactive le buffering proxy et émet les chunks compatibles OpenAI ainsi que les métadonnées Nexus prévues par le flux ; - avec
stream=false, la réponse utiliseapplication/json, agrège les deltas danschoices[0].message.contentet conservesources,usageetnexuslorsqu'ils sont disponibles.
Les modes stream=false et stream=true sont disponibles sur le runtime de
référence. Une évolution locale ultérieure du contrat reste non déployée tant
qu'un build et un déploiement ciblés n'ont pas été séparément validés.
Historique conversationnel transmis au modèle
Nexus borne l'historique user/assistant transmis au gateway avec deux
paramètres système de la catégorie Assistant :
| Paramètre | Défaut | Valeurs acceptées |
|---|---|---|
NEXUS_WEBUI_HISTORY_MAX_MESSAGES | 20 | 1 à 100 |
NEXUS_WEBUI_HISTORY_MAX_CHARACTERS | 60000 | 1 à 120000 |
Ces paramètres sont modifiables depuis l'administration Nexus et s'appliquent à tous les clients de cette façade, sans champ supplémentaire dans les requêtes des applications appelantes.
Le dernier message utilisateur est réservé intégralement. Nexus complète le contexte avec les messages récents, privilégie les messages utilisateur et exclut les anciennes réponses assistant qui ne tiennent plus dans le budget, puis restaure l'ordre chronologique. Aucun message utilisateur courant n'est tronqué silencieusement.
Si ce dernier message dépasse à lui seul la limite de caractères, aucun appel
gateway n'est effectué. Le code non réessayable
nexus_webui_message_too_large est retourné avec HTTP 413 pour
stream=false, ou comme événement d'erreur SSE suivi de [DONE] pour
stream=true.
Les tâches internes qui ne doivent pas interroger le corpus, par exemple une génération de titre, restent sur le flux direct sans outils documentaires.
Contexte Web éphémère facultatif
Le même endpoint accepte facultativement un objet web_context. Il est destiné
aux résultats bruts d'une unique requête Search déjà effectuée par NWI avec
Perplexity ou Brave ; Nexus ne reçoit ni clé provider, ni header, ni cookie.
{
"web_context": {
"schema_version": "1.0",
"provider": "perplexity_search",
"query": "requête contextualisée produite par NWI",
"transient": true,
"sources": [
{
"source_id": "web:1",
"rank": 1,
"title": "Titre de la page",
"url": "https://example.com/page",
"domain": "example.com",
"snippet": "Extrait textuel borné",
"published_at": "2026-08-20",
"last_updated": "2026-08-21"
}
]
}
}Le contrat est fermé et refuse le payload en 422 au lieu de le tronquer :
- version
1.0, provider exactementperplexity_searchoubrave_search, ettransient=truestrict ; tout autre provider est refusé ; - requête de 1 à 4 096 caractères ;
- une à trois sources, dans l'ordre, avec rangs contigus
1..N; source_idunique préfixé parweb:, URL canonique unique HTTP/HTTPS et domaine égal à l'hôte ;- titre limité à 512 caractères, URL à 2 048, domaine à 253 et chaque snippet à 8 192 ; le total des snippets est limité à 24 576 caractères ;
- dates facultatives au format ISO
YYYY-MM-DD; - credentials dans l'URL, fragments, paramètres sensibles et champs inconnus refusés.
Le prompt système Nexus reste prioritaire. Le contexte est ajouté séparément comme donnée externe non fiable : ses instructions sont ignorées, il ne peut ni modifier les ACL ou le scope, ni déclencher un outil, ni demander un secret. Les outils Nexus restent read-only et leur scope est réimposé côté serveur.
Une réponse cite le Web avec les marqueurs [W1], [W2] ou [W3]. Seules les
sources ainsi référencées sont retournées dans sources, avec
source_type="web" et sans snippet. Les derniers événements SSE et la réponse
JSON agrégée exposent la même extension :
{
"nexus": {
"web_context": {
"accepted": true,
"schema_version": "1.0",
"provider": "perplexity_search",
"transient": true,
"provided_source_ids": ["web:1", "web:2"],
"cited_source_ids": ["web:1"]
},
"document_context": {
"queried": true,
"returned_source_count": 2
}
}
}Le contexte Web ne suit aucun chemin d'ingestion, de vectorisation, de cache ou
de création documentaire. Le query log existant conserve la question et la
réponse finale selon sa politique actuelle ; cette réponse peut donc contenir
des faits Web. Il ne reçoit ni requête Web brute, ni snippet, URL, titre,
domaine, date ou objet complet. Seuls accepted, la version, le provider et les
compteurs de sources fournies/citées peuvent être ajoutés à ses filtres d'audit.
Sans web_context, le chemin et les sorties historiques restent inchangés.
Le provider accepté est restitué sans transformation dans le contexte injecté,
les sources Open WebUI, nexus.web_context.provider et l'audit borné.
Modèles
GET /models expose uniquement les providers activés et les modèles non
archivés. Les credentials ne sont jamais retournés. Si le registre est
indisponible, Nexus peut exposer le modèle de configuration comme fallback avec
nexus.fallback=true.
Outils documentaires
Le catalogue ne contient que quatre opérations read-only :
inspect_scope;list_resources;search_documents;read_document.
Le chat peut enchaîner au maximum quatre appels pendant 120 secondes. Les limites principales sont :
| Outil | Limite |
|---|---|
inspect_scope | recent_limit de 1 à 25 |
list_resources | limit de 1 à 100, pagination bornée |
search_documents | 1 à 20 chunks, texte par chunk borné |
read_document | 500 à 30 000 caractères par page logique |
search_documents accepte déjà dans le contrat public l'enum facultatif
retrieval_mode: dense_mmr | hybrid_rrf. Pour les routes Query générales,
l'ajout du même champ reste local tant que l'OpenAPI live ne l'expose pas.
Les dates created et updated sont des métadonnées techniques Nexus. En
l'absence de date éditoriale canonique, les réponses portent
publication_date_unavailable; l'UI ne doit pas les présenter comme des dates
de publication.
Feedback, stop et completed
- Un feedback positif utilise
answer="yes". - Un feedback négatif utilise
answer="no"et exigereason; la raisonotherexige aussicomment. chat/stopest best-effort dans le MVP actuel :stopped=falsene prouve pas l'annulation effective du calcul backend.chat/completedaccuse réception des identifiants WebUI et de l'éventuelquery_id; il ne remplace pas la journalisation Nexus de la query.
Codes d'erreur utiles
| Statut | Cause fréquente |
|---|---|
400 | identifiant de feedback invalide |
401 | session ou bearer absent/invalide |
403 | scope OAuth ou ACL source_app insuffisant |
404 | query_id non visible pour le tenant |
413 | dernier message utilisateur supérieur à la limite Nexus WebUI configurée |
422 | payload, hiérarchie de scope ou enum invalide |
Ne jamais placer de token, cookie, credential provider ou contenu documentaire
complet dans metadata, features, files, un log ou une preuve de test.