Outils de développement (adk-devtools)

adk-devtools est l’ensemble d’outils de boucle interne dont un agent de codage a besoin — lire, modifier, rechercher et exĂ©cuter — avec chaque opĂ©ration limitĂ©e Ă  un rĂ©pertoire de travail. C’est un crate autonome publiable, ne dĂ©pendant que de adk-core, donc il s’intĂšgre avec n’importe quel LlmAgent (le CodingAgent le configure pour vous).

Les outils

DevToolset est un Toolset regroupant six outils :

OutilParamĂštresComportement
read_filepath, offset?, limit?Retourne le contenu du fichier, avec numéros de ligne
write_filepath, contentCrée/écrase un fichier (crée les répertoires parents)
edit_filepath, old_string, new_string, replace_all?Remplacement exact de chaĂźne
globpattern, path?Lister les fichiers correspondant Ă  un glob (par ex. src/**/*.rs)
greppattern, path?, glob?, case_insensitive?Recherche de contenu par expression réguliÚre
bashcommand, timeout_secs?ExĂ©cuter une commande shell Ă  la racine de l’espace de travail

Deux comportements de sécurité à connaßtre :

  • edit_file nĂ©cessite un read_file prĂ©alable de ce fichier dans la session, et par dĂ©faut la chaĂźne cible doit apparaĂźtre exactement une fois (replace_all pour outrepasser cela). Cela protĂšge contre les Ă©crasements aveugles.
  • grep ignore les rĂ©pertoires de build/VCS courants (target, .git, node_modules, 
) ainsi que les fichiers binaires/surdimensionnĂ©s.

L’outil bash streame sa sortie stdout/stderr ligne par ligne via ToolContext::emit_progress pendant l’exĂ©cution de la commande, afin que les UIs puissent afficher un terminal en direct. Chaque bloc arrive comme un Ă©vĂ©nement partiel sur le EventStream de l’agent (dĂ©tectez-le avec event.tool_progress_stream()) ; la sortie complĂšte est toujours renvoyĂ©e comme rĂ©sultat final de l’outil. Voir l’ streaming_bash exemple et Streaming Progress from a Tool.

Le Workspace

Un Workspace ancre chaque opération dans un répertoire et applique une petite politique :

use adk_devtools::Workspace;
use std::time::Duration;

let ws = Workspace::new("./my-repo");              // read-write, bash enabled
let ws = Workspace::read_only("./my-repo");        // explore/plan: no writes, no bash
let ws = Workspace::new("./my-repo")
    .allow_bash(false)                              // file edits, but no shell
    .bash_timeout(Duration::from_secs(60))
    .max_output_bytes(512 * 1024);
  • Contenance du chemin — tout chemin qui se rĂ©sout en dehors de la racine est rejetĂ©, donc l’agent ne peut pas lire ou Ă©crire ../../etc/.... La contenance est appliquĂ©e au chemin rĂ©solu, pas seulement au chemin littĂ©ral : un lien symbolique pointant hors de la racine est rejetĂ© mĂȘme s’il se trouve lexicalement Ă  l’intĂ©rieur. Cela couvre un composant final liĂ© par symlink et un rĂ©pertoire parent liĂ© par symlink, donc la crĂ©ation via un rĂ©pertoire redirigĂ© est aussi refusĂ©e. Un symlink dont la cible reste Ă  l’intĂ©rieur de l’espace de travail continue de fonctionner, puisque les dĂ©pĂŽts contiennent lĂ©gitimement des liens internes.

    La vĂ©rification n’est pas un verrou. Un symlink placĂ© entre la vĂ©rification et l’ouverture suivante serait quand mĂȘme suivi ; pour fermer cette fenĂȘtre, il faut un parcours relatif aux descripteurs avec les sĂ©mantiques no-follow de la plateforme. ConsidĂ©rez les outils de fichiers comme une contenance face Ă  un agent qui erre, et non comme une isolation face Ă  un adversaire qui peut Ă©crire simultanĂ©ment dans l’espace de travail.

  • Mode lecture seule — Workspace::read_only(..) masque entiĂšrement les outils modifiants (le modĂšle ne voit que read_file/glob/grep).

  • L’environnement de bash est vidĂ© — la commande reçoit seulement PATH, HOME, LANG, LC_ALL, TMPDIR, TERM, USER et SHELL, donc les clĂ©s API du fournisseur dĂ©tenues par le processus de l’agent ne sont pas lisibles avec env. Workspace::inherit_env(true) rĂ©tablit l’ancien comportement consistant Ă  tout transmettre, et env_allowlist remplace l’ensemble.

  • DĂ©lai d’attente de bash + limites de sortie — les commandes longues ou bavardes sont bornĂ©es. Une commande arrivĂ©e au timeout est tuĂ©e comme un groupe de processus, donc tout ce qu’elle a lancĂ© est tuĂ© aussi ; auparavant seul l’enfant direct Ă©tait signalĂ© et les descendants survivaient.

L’utiliser directement

Attachez l’ensemble d’outils à n’importe quel agent :

use adk_devtools::{DevToolset, Workspace};
use adk_agent::LlmAgentBuilder;
use std::sync::Arc;

let agent = LlmAgentBuilder::new("coder")
    .model(model)
    .toolset(Arc::new(DevToolset::new(Workspace::new("./my-repo"))))
    .build()?;

DevToolset n’expose que les outils autorisĂ©s par l’espace de travail, donc un espace de travail en lecture seule donne automatiquement un agent en lecture seule.

ModĂšle de sandboxing

La phase 1 exĂ©cute bash localement sur l’hĂŽte (sh -c, rĂ©pertoire de travail fixĂ© Ă  la racine) avec un dĂ©lai d’attente et un environnement vidĂ©. Ce que cela vous apporte, et ce que cela ne vous apporte pas :

ImposéNon imposé
Les outils de fichiers ne peuvent pas rĂ©soudre en dehors de la racine, y compris via des liens symboliquesbash peut toujours utiliser des chemins absolus — le rĂ©pertoire de travail n’est pas une frontiĂšre du systĂšme d’exploitation
La commande ne peut pas lire les variables d’environnement de l’agentLa commande peut accĂ©der au rĂ©seau
Un dĂ©lai d’attente interrompt la commande et ses descendantsRien ne limite la mĂ©moire ou le CPU

Il est donc contenu dans le chemin, isolĂ© de l’environnement et bornĂ©, mais pas isolĂ© du systĂšme d’exploitation. Le vocabulaire de la politique s’aligne sur adk-code et SandboxPolicy ; pour une isolation forte, exĂ©cutez bash derriĂšre un exĂ©cuteur conteneurisĂ© (voir le design doc). Combinez-le avec adk-guardrail (listes d’autorisations des commandes, redaction des secrets) et adk-auth pour les outils avec jeton (p. ex. GitHub).

Suivant : The harness →

Outils de développement (`adk-devtools`) - Documentation ADK-Rust | ADK-Rust