Docs · Référence
Schémas et templates
Les questions et le contexte vivent côté plateforme, versionnés. L'application envoie des variables ; Jevis sait exactement quelle version a produit chaque décision.
Schémas
Un schéma regroupe des questions au format TypeSafe (type, instructions, criteria), un seuil d'abstention et une température par type de question. Il peut aussi fixer un backend (backend_id) ; sinon, le backend par défaut répond.
{
"slug": "triage",
"abstain_threshold": 0.6,
"temperature_by_type": { "choice": 1.0, "score": 1.0, "noul": 1.0 },
"questions": {
"department": {
"type": "choice",
"instructions": "Quel service doit traiter ce ticket ?",
"criteria": { "billing": "Facturation, paiement", "shipping": null }
},
"urgent": {
"type": "noul",
"instructions": "Le client attend-il une réponse aujourd'hui ?"
},
"tone": {
"type": "score",
"instructions": "Ton du message",
"criteria": ["calm", "annoyed", "angry"]
}
}
}| type | criteria | Limites |
|---|---|---|
choice | map option → description (ou null) | 1 à 255 options, 20 au plus recommandé |
score | tableau ordonné de niveaux | 2 à 10 niveaux |
noul | { true, false } optionnel | question oui/non |
Versions
Chaque schéma a des versions numérotées. Une version est d'abord un brouillon, modifiable. La publication la valide, calcule son empreinte et la fige : une version publiée est immuable. Pour changer quoi que ce soit, on crée une nouvelle version.
{
"id": "…", "slug": "triage", "name": "Triage tickets", "description": "",
"latest_version": 3, "published_version": 2, "created_at": "…",
"versions": [ {
"version": 2, "status": "published", "questions": { },
"abstain_threshold": 0.6,
"temperature_by_type": { "choice": 1.0, "score": 1.0, "noul": 1.0 },
"backend_id": null, "fingerprint": "sha256…", "published_at": "…", "created_at": "…"
} ]
}| Route admin | Effet |
|---|---|
POST /schemas | Crée le schéma et sa version 1 en brouillon. |
POST /schemas/{id}/versions | Nouveau brouillon, copie de from_version ou de la dernière. |
PATCH /schemas/{id}/versions/{v} | Brouillon uniquement, sinon 409. |
POST /schemas/{id}/versions/{v}/publish | Valide, calcule fingerprint, fige. |
DELETE /schemas/{id} | Refusé (409) si le schéma a des décisions. |
Une application n'appelle que les schémas qui lui sont attribués (schema_ids de l'application). Sinon : 403 schema_not_granted.
Empreinte structurelle
Un client TypeSafe envoie ses questions inline, sans x_schema. Jevis les rattache à un schéma publié par leur structure, pas par leur texte : on peut reformuler une instruction sans casser l'intégration.
// questions (textes exclus) → structure canonique, clés triées
{
"department": { "type": "choice", "criteria_keys": ["billing", "shipping"] },
"tone": { "type": "score", "criteria_keys": 3 },
"urgent": { "type": "noul", "criteria_keys": [] }
}
// empreinte = SHA-256 de ce JSON canoniquecriteria_keys= clés triées pourchoice, nombre de niveaux pourscore,[]pournoul. Instructions et descriptions sont exclues.- L'empreinte est unique parmi les versions publiées d'un même schéma.
- Deux schémas différents peuvent partager une empreinte : Jevis prend celui autorisé pour l'application, et répond 409 si c'est ambigu.
Templates
Un template transforme des variables en state. Jinja2 en environnement sandboxé (SandboxedEnvironment, autoescape désactivé, StrictUndefined : une variable manquante est une erreur, pas une chaîne vide). Mêmes règles de versions que les schémas.
{# template ticket-triage, version 3 #}
Sujet : {{ subject }}
{{ body }}
{% if tags %}
Étiquettes : {{ tags | join(", ") }}
{% endif %}Variables typées
Chaque version déclare ses variables. Types acceptés : string, number, boolean, array, object. Elles sont validées avant le rendu ; un écart donne 422 template_render_error.
{
"subject": { "type": "string", "required": true },
"body": { "type": "string", "required": true },
"tags": { "type": "array", "required": false }
}Prévisualiser un rendu (fonctionne aussi sur un brouillon) :
POST /admin/v1/templates/{id}/versions/{version}/render
{ "variables": { "subject": "Double prélèvement", "body": "Bonjour, …" } }
→ { "state": "Sujet : Double prélèvement\n\nBonjour, …" }Dans un appel
Avec x_template et x_schema, l'application n'envoie ni state ni questions. La réponse indique les versions utilisées (x_template, x_schema, x_schema_version).
{
"model": "kev-0.8b",
"x_template": {
"id": "ticket-triage",
"version": 3,
"variables": { "subject": "Double prélèvement", "body": "Bonjour, …", "tags": ["vip"] }
},
"x_schema": { "id": "triage" }
}version explicitement.