> ## Documentation Index
> Fetch the complete documentation index at: https://doc.agent-l.integria.app/llms.txt
> Use this file to discover all available pages before exploring further.

# Outils et hôte Python

> Reliez les contrats du programme aux capteurs et effets du monde réel.

Le couple `X.agent` / `X.py` est normatif. Le programme déclare les capacités ; l’hôte homonyme les implémente.

## Déclarer un outil

```text theme={"theme":{"light":"github-light","dark":"vesper"}}
TOOL isolate_endpoint {
    DESCRIPTION "Isole un poste du réseau."
    INPUT       { host: String BIND suspected_host }
    OUTPUT      { isolated: Symbol }
    SIDE_EFFECT { network.acl, endpoint.connectivity }
    RISK        { operational = HIGH }
    REQUIRES    { endpoint.inspected == yes }
    EFFECT      { threat.status = contained }
    COST        8
}
```

| Champ              | Sert à                                               |
| ------------------ | ---------------------------------------------------- |
| `INPUT` / `OUTPUT` | vérifier les arguments et borner le résultat attendu |
| `BIND`             | lier un argument à un chemin d’état                  |
| `SIDE_EFFECT`      | exposer la surface modifiée                          |
| `RISK`             | alimenter politiques et diagnostics                  |
| `REQUIRES`         | rendre l’opérateur applicable au planificateur       |
| `EFFECT`           | décrire l’état produit pour la planification         |
| `COST`             | comparer les routes possibles                        |

Un outil non déclaré n’existe pas. Un argument absent, inconnu ou mal typé est refusé avant le moteur de politiques.

## Implémenter l’hôte

```python endpoint_guard.py theme={"theme":{"light":"github-light","dark":"vesper"}}
from agentl import Host, MockLLM, Symbol


def build():
    host = Host()

    host.sensors["suspected_host"] = lambda: "PC-042"
    host.sensors["endpoint.inspected"] = lambda: Symbol("yes")

    @host.tool("isolate_endpoint")
    def isolate_endpoint(host: str):
        # appel réel vers votre EDR
        return {"isolated": Symbol("yes")}

    return host, MockLLM()
```

La fonction `build()` peut renvoyer `(host, llm)`. Pour une société, elle peut renvoyer des dictionnaires indexés par nom d’agent.

## API de l’hôte

<AccordionGroup>
  <Accordion title="Capteurs">
    Enregistrez une fonction sans argument sous le chemin déclaré dans `OBSERVE`.

    ```python theme={"theme":{"light":"github-light","dark":"vesper"}}
    host.sensors["service.http_status"] = probe_status
    ```
  </Accordion>

  <Accordion title="Outils">
    Enregistrez une fonction dont les arguments correspondent au contrat `INPUT`.

    ```python theme={"theme":{"light":"github-light","dark":"vesper"}}
    host.tools["restart_service"] = restart_service
    ```
  </Accordion>

  <Accordion title="Approbateur">
    Affectez `host.approver`. Seuls `True` ou un mot d’accord explicite sont acceptés. Toute valeur ambiguë, y compris la chaîne `"no"`, refuse.

    ```python theme={"theme":{"light":"github-light","dark":"vesper"}}
    host.approver = lambda request: ask_operator(request)
    ```
  </Accordion>

  <Accordion title="Événements">
    Injectez une charge utile avec `emit`; le runtime la récupère via `drain`.

    ```python theme={"theme":{"light":"github-light","dark":"vesper"}}
    host.emit("watchdog.alert", severity=Symbol("HIGH"))
    ```
  </Accordion>

  <Accordion title="Sous-agents">
    Enregistrez un callable sous le nom du contrat utilisé par `DELEGATE`.

    ```python theme={"theme":{"light":"github-light","dark":"vesper"}}
    host.subagents["prober"] = probe_subagent
    ```
  </Accordion>
</AccordionGroup>

## Garder la frontière honnête

Le test pratique est simple : **si une politique de l’entreprise changeait demain, cette ligne Python devrait-elle changer ?** Si oui, la décision appartient probablement au `.agent`.

<Tip>
  Rendez des mesures brutes : un code HTTP, un nombre de tentatives, un identifiant. Laissez le programme décider si ces valeurs signifient « sain », « urgent » ou « autorisé ».
</Tip>

## Échec fermé

* capteur absent : la valeur reste indéterminée ;
* outil absent : l’invocation lève une erreur ;
* approbateur absent : la demande est refusée ;
* LLM absent : `MockLLM` permet de conserver un flux déterministe lorsqu’il convient.

<Card title="Analyser la frontière" icon="scan-line" href="/core/boundary">
  Détectez les comparaisons, filtres et seuils métier cachés dans l’hôte.
</Card>
