Aller au contenu principal

Manifeste de paquet (apollia.toml)

Un paquet est un dossier qui porte un apollia.toml à sa racine. Le manifeste déclare ce que le paquet livre : des agents, qui sont des données, des outils Python, des workflows Python, les connexions dont il a besoin, les serveurs MCP qu'il apporte, ses dépendances Python et les déclencheurs qu'il propose. apollia-os package build fait du dossier une archive .apo, et lire le manifeste n'exécute jamais le code du paquet.

Ce fichier porte le même nom que le fichier de configuration du runtime, décrit dans Configuration (apollia.toml). Ce sont deux fichiers différents : celui-ci se trouve à la racine d'un dossier de paquet et voyage dans l'archive.

Schéma strict​

Le schéma est strict. Une clé que le schéma ne connaît pas est refusée, et le refus nomme le chemin complet de la clé :

apollia.toml: unknown key `agents[0].defaults.model.temprature`

Rien n'est ignoré : ce que vous écrivez est exactement ce qu'Apollia lit.

Tables​

TableCardinalitéDéclare
[package]une, obligatoireL'identité du paquet.
[[agents]]zéro ou plusDes agents : une mission, des exemples et des valeurs par défaut. Aucun code.
[[tools]]zéro ou plusDes outils Python, chacun joignable sous pkg:<paquet>/<nom>.
[[workflows]]zéro ou plusDes workflows Python avec leurs étapes déclarées.
[[requires]]zéro ou plusLes connexions dont le paquet a besoin.
[[mcp_servers]]zéro ou plusLes serveurs MCP que le paquet apporte.
[pip]zéro ou uneLes dépendances Python de l'environnement du paquet.
[[triggers]]zéro ou plusLes déclencheurs que le paquet propose.

Un paquet déclare au moins un agent, un outil ou un workflow.

[package]​

CléTypeObligatoireSens
namechaîneouiIdentifiant du paquet, [a-z0-9_-]+. Préfixe de ses outils : pkg:<name>/<outil>.
versionchaîneouiVersion semver du paquet, par exemple 1.2.0.
publisherchaîneouiÉditeur affiché à l'installation du paquet.
descriptionchaînenonCe que le paquet livre.
sdkchaîneouiContrainte semver sur le SDK pour lequel le paquet a été écrit, par exemple ">=0.3, <0.4".

[[agents]]​

Un agent est une donnée. Le moteur d'agent intégré l'exécute ; le paquet ne livre aucun code pour lui.

CléTypeObligatoireSens
idchaîneouiIdentifiant, [a-z0-9_-]+, unique dans le paquet.
namechaîneouiNom affiché.
missionchaîneouiCe à quoi sert l'agent, dans les mots de son auteur. Sert d'instructions.
examplesliste de chaînesnonExemples de demandes affichés sur la fiche de l'agent.

[agents.defaults]​

Chaque valeur est ici une valeur par défaut que le paquet recommande, jamais une contrainte : une surcharge posée par l'utilisateur sur sa machine l'emporte, et une mise à jour du paquet la conserve.

CléTypeSens
accessliste de chaînesOutils accordés par défaut : le nom d'un outil natif, mcp:<serveur>/<outil>, ou pkg:<paquet>/<outil>. Une entrée pkg: doit nommer un outil de ce paquet. agent:<id> et workflow:<paquet>/<workflow> permettent à l'agent d'appeler un autre agent ou un workflow, chacun lui étant proposé comme un outil de plus. Rien de ce que la liste ne nomme pas n'est proposé à l'agent.
sourcesliste de chaînesSources cochées par défaut. "profile" laisse l'agent lire le profil de l'utilisateur par ctx.profile ; "memory" ouvre sa mémoire, en lecture et en écriture. Toute autre entrée est un identifiant de source, tel que apollia-os source list l'affiche.
autonomychaînePalier d'autonomie : assisted, supervised, bounded_autonomous ou long_autonomous. Sans elle, le défaut global s'applique.
planningchaîneSi l'agent planifie une tâche avant d'agir : never, auto ou always. Sans elle, auto.

[agents.defaults.model]​

CléTypeSens
modelchaîneModèle que le paquet recommande.
presetchaînePréréglage de réglages de requête que le paquet recommande.

[agents.defaults.model.request] porte les réglages de requête eux-mêmes : temperature, top_p, top_k, repetition_penalty, max_tokens et seed.

[[tools]]​

Une entrée par outil Python. python -m apollia describe <dossier> écrit ces entrées depuis les fonctions décorées par @tool, si bien que le manifeste et le code ne peuvent pas se contredire.

CléTypeObligatoireSens
namechaîneouiIdentifiant, [a-z0-9_-]+, unique dans le paquet.
modulechaîneouiModule Python, relatif à la racine du paquet, par exemple tools/invoices.py.
descriptionchaîneouiCe que fait l'outil, pour le modèle et pour la fiche de l'agent.
actionchaîneouiFamille d'action, voir ci-dessous.
inputstablenonSchéma JSON des entrées.

Familles d'action​

Un outil et un workflow déclarent chacun une famille d'action : ce que l'appeler fait au monde. Toute famille sauf read rend l'accès sensible.

FamilleSensSensible
readLit des données qui ne sont pas personnelles.non
read_personalLit des données personnelles : courrier, agenda, documents d'un utilisateur.oui
write_or_deleteÉcrit ou supprime.oui
send_externalEnvoie quelque chose hors de la machine.oui
execute_codeExécute du code.oui

[[workflows]]​

Une entrée par workflow Python, écrite par python -m apollia describe <dossier> depuis les fonctions décorées par @workflow.

CléTypeObligatoireSens
namechaîneouiIdentifiant, [a-z0-9_-]+, unique dans le paquet. Le workflow s'adresse par <paquet>/<name>.
modulechaîneouiModule Python, relatif à la racine du paquet.
descriptionchaîneouiCe que fait le workflow.
actionchaîneouiFamille d'action : ce que le workflow fait de plus sensible.
inputstablenonSchéma JSON des entrées. Sa clé x-order les liste dans l'ordre que suit le formulaire de lancement.
stepsliste de chaînesnonNoms des étapes, dans l'ordre.

[[requires]]​

CléTypeObligatoireSens
typechaîneouiType de connexion, tel que le catalogue des connexions le nomme, par exemple gmail.
reasonchaînenonPourquoi le paquet en a besoin, affiché quand la connexion manque.

[[mcp_servers]]​

Les clés, leurs défauts et leur sens sont ceux d'un serveur de mcp.toml.

CléTypeDéfautSens
namechaîneobligatoireNom du serveur, [a-z0-9_-]+. Préfixe de ses outils : mcp:<name>/<outil>.
commandchaînevideExécutable à lancer ; vide pour un transport réseau.
argsliste de chaînesvideArguments passés à la commande.
envtablevideEnvironnement du processus du serveur ; les emplacements ${VAR} sont admis.
transportchaînestdiostdio, streamable-http ou sse.
urlchaîneaucuneURL du serveur pour un transport réseau.
init_timeout_secsentier30Délai de la poignée de main initialize.
call_timeout_secsentier60Délai d'un tools/call.
max_response_bytesentier8388608Plafond d'une réponse du serveur.
max_toolsentier256Plafond des outils retenus de tools/list.
tagsliste de chaînesvideÉtiquettes appliquées à chaque outil du serveur.

Un serveur ne porte aucun réglage d'approbation. requires_approval, une clé des versions précédentes, est encore lue, journalise un avertissement package.manifest.retired_key et n'a aucun effet : qu'un appel à l'un de ses outils demande d'abord se décide sur la famille d'action de cet outil.

[pip]​

CléTypeSens
packagesliste de chaînesDépendances installées dans l'environnement du paquet. Épinglez-les (pypdf==4.3.1).

[[triggers]]​

Un paquet propose des déclencheurs ; l'installer ne les arme pas de lui-même.

CléTypeObligatoireSens
idchaîneouiIdentifiant, [a-z0-9_-]+, unique parmi les déclencheurs.
targetchaîneouiL'agent ou le workflow de ce paquet que le déclencheur lance.
inputchaînenonMessage envoyé à un agent à chaque déclenchement.
sourcetableouiQuand il se déclenche, voir ci-dessous.

[triggers.source] est étiquetée par type :

typeClésSe déclenche
cronscheduleSur une expression cron, par exemple "0 8 * * MON".
intervaleveryÀ intervalle fixe : "30m", "1h", "1d".
file_watchrecursive (défaut false)Quand un dossier change. L'utilisateur choisit le dossier à l'installation.
webhookaucuneSur un appel HTTP. Le secret se pose à l'installation, jamais dans le manifeste.

Validation​

Au-delà du schéma, un manifeste tient les règles suivantes. La première qui est enfreinte est signalée, et le paquet n'est ni construit ni installé.

RègleMessage
Le paquet déclare au moins un agent, un workflow ou un outil.the package declares no agent, no workflow and no tool
Le nom du paquet, chaque identifiant et chaque nom de serveur MCP respectent [a-z0-9_-]+.`<field>` value `<value>` must match [a-z0-9_-]+, ou MCP server name `<name>` must match [a-z0-9_-]+ pour un serveur MCP
version est semver.package version `<value>` is not semver
sdk est une contrainte semver.sdk requirement `<value>` is not a semver requirement
Agents, outils et workflows partagent un seul espace de noms, sans doublon. Les identifiants de déclencheur sont uniques, les noms de serveur MCP aussi.identifier `<id>` is declared more than once
Un accès par défaut pkg:<paquet>/<outil> nomme un outil de ce paquet.agent `<agent>` grants `<access>`, which is not a tool of package `<package>`
Un déclencheur vise un agent ou un workflow de ce paquet.trigger `<trigger>` targets `<target>`, which is no agent or workflow of the package

apollia-os package build ajoute un contrôle qui lui est propre : il refuse un dossier dont les modules Python définissent des outils ou des workflows que le manifeste ne décrit pas.

Exemple complet​

[package]
name = "invoices"
version = "1.2.0"
publisher = "Example Accounting"
description = "Reads supplier invoices and drafts the reminders."
sdk = ">=0.3, <0.4"

[[agents]]
id = "invoice-clerk"
name = "Invoice clerk"
mission = "Read the supplier invoices of the month and list the late ones."
examples = ["Which invoices are late?", "Draft a reminder for ACME."]

[agents.defaults]
access = ["file_read", "mcp:ledger/lookup", "pkg:invoices/extract_totals"]
sources = ["profile"]
autonomy = "supervised"
planning = "always"

[agents.defaults.model]
model = "qwen3-8b-instruct"
preset = "balanced"

[agents.defaults.model.request]
temperature = 0.2
max_tokens = 2048

[[tools]]
name = "extract_totals"
module = "tools/extract.py"
description = "Extract the total, the due date and the supplier of an invoice."
action = "read_personal"

[tools.inputs]
type = "object"
required = ["path"]

[tools.inputs.properties.path]
type = "string"
description = "Path of the invoice file."

[[workflows]]
name = "monthly-reminders"
module = "workflows/reminders.py"
description = "Find the late invoices and send one reminder per supplier."
action = "send_external"
steps = ["collect", "confirm", "send"]

[workflows.inputs]
type = "object"

[workflows.inputs.properties.month]
type = "string"

[[requires]]
type = "gmail"
reason = "Reminders are sent from the user's mailbox."

[[mcp_servers]]
name = "ledger"
command = "uvx"
args = ["ledger-mcp"]

[pip]
packages = ["pypdf==4.3.1"]

[[triggers]]
id = "first-monday"
target = "monthly-reminders"

[triggers.source]
type = "cron"
schedule = "0 8 1-7 * MON"

Voir aussi​