Strumenti agent integrati
Questi sono gli strumenti vincolati al server che il runtime integrato degli agenti registra direttamente — language server, ricerca strutturale, debugger, kernel, domande e controllo dei worker — in contrapposizione agli strumenti MCP che collega dall’esterno e agli strumenti generici per file, ricerca e shell del runtime dell’harness. Non sono nel registro MCP: un client MCP esterno non li vedrà, perché ciascuno è vincolato a una risorsa viva lato server — un processo del language server, un adattatore di debug, un interprete — che appartiene a una singola esecuzione.
Ogni strumento qui è registrato solo quando la risorsa che lo sostiene è cablata per l’esecuzione — un supervisor del language server o del debug, un parser tree-sitter, una factory di kernel, una porta per le domande, un roster di vibe. Il rilevamento di un language server o di un adattatore di debug per questo checkout è un controllo separato e successivo (status / adapters): quegli strumenti restano sulla superficie, così l’agente può chiedere perché nulla è utilizzabile invece di tirare a indovinare.
Livelli di approvazione
Sezione intitolata “Livelli di approvazione”Ogni strumento dichiara un livello, e il livello decide quali superfici lo vedono — non soltanto se chiede un’approvazione. La modalità Piano e i sottoagenti in sola lettura sono limitati a read, quindi uno strumento di livello write o exec è del tutto assente dal loro schema.
| Livello | Significato | Strumenti qui |
|---|---|---|
read |
Nessun effetto collaterale | lsp, ast_grep, ask_user, i cinque vibe_* |
write |
Modifica i file | lsp_rename, ast_edit, resolve |
exec |
Avvia o controlla un processo | debug, eval |
lsp — query al language server
Sezione intitolata “lsp — query al language server”Registrato quando l’esecuzione ha un supervisor del language server e una directory di lavoro. Se un server può davvero rispondere viene rilevato al momento della chiamata, come un’intersezione: deve esistere un marcatore di radice e il binario del server deve essere risolvibile. Uno solo dei due significa che nessun server parte — status lo dice — invece di un’ipotesi silenziosa.
Le posizioni si indicano con line più una sottostringa symbol, mai con la colonna. Un modello a cui viene chiesta una colonna tira a indovinare, e un’ipotesi sbagliata risolve in un simbolo diverso sulla stessa riga — una risposta che sembra giusta ma parla d’altro. Omettere symbol in un’azione di navigazione è un errore, non un’ipotesi sulla prima colonna.
| Azione | Argomenti | Restituisce |
|---|---|---|
diagnostics |
file (o "*") |
Errori e avvisi; "*" esegue invece il checker del progetto |
definition |
file, line, symbol |
Dove è dichiarato il simbolo |
type_definition |
file, line, symbol |
Dove è dichiarato il suo tipo |
implementation |
file, line, symbol |
Le implementazioni concrete |
references |
file, line, symbol |
Ogni uso, limitato a 50 |
hover |
file, line, symbol |
Firma e commento di documentazione |
symbols |
query o file |
Ricerca nello spazio di lavoro con query (limitata a 100); simboli del documento con file (limitati a 200) |
code_actions |
file, line, symbol |
Correzioni rapide offerte dal server |
status |
— | Quali server sono in esecuzione, e per quali radici |
reload |
— | Riavvia il server per questa radice |
Diagnostici alla scrittura
Sezione intitolata “Diagnostici alla scrittura”Il vantaggio non è lo strumento. write, edit e apply_patch sono avvolti: dopo la scrittura il file viene sincronizzato e salvato tramite il language server, e solo i diagnostici nuovi vengono inseriti nel risultato dello strumento. Un agente scopre di aver rotto la build nel momento in cui l’ha rotta, senza doversi ricordare di chiederlo.
I diagnostici già segnalati vengono soppressi da un registro per esecuzione con chiave su gravità, codice e messaggio — la posizione è deliberatamente esclusa, così un diagnostico che si è semplicemente spostato di quattro righe più in basso non viene segnalato di nuovo come nuovo.
lsp_rename — rinomina a livello di progetto
Sezione intitolata “lsp_rename — rinomina a livello di progetto”Uno strumento separato, di livello write, per un motivo preciso: il livello decide la visibilità. Incorporare la rinomina in lsp darebbe a un esploratore in sola lettura la capacità di riscrivere il repo, oppure metterebbe ogni hover dietro una richiesta di approvazione.
| Argomento | Significato |
|---|---|
file |
Dove si trova il simbolo |
line |
Riga indicizzata a partire da 1 |
symbol |
Sottostringa che lo identifica su quella riga |
new_name |
Come chiamarlo |
ast_grep — ricerca strutturale
Sezione intitolata “ast_grep — ricerca strutturale”Trova il codice per forma anziché per testo. $NAME corrisponde a qualsiasi nodo, $$$NAME corrisponde a una sequenza di fratelli, e $_ è un carattere jolly che non associa nulla.
La proprietà che lo rende un matcher e non una regex con qualche passaggio in più: una metavariabile ripetuta in uno stesso pattern deve catturare lo stesso testo.
ast_grep(pattern: "if ($X != null) $X.dispose()", language: "dart")trova una guardia che libera ciò che ha verificato, e non ne trova una che libera qualcos’altro.
| Argomento | Significato |
|---|---|
pattern |
Un frammento di codice con metavariabili |
path |
File o directory in cui cercare; il valore predefinito è l’intero spazio di lavoro |
language |
Un id di grammatica distribuito (dart, python, rust, c, …). Viene dedotto quando path indica un file |
max_results |
Predefinito: 50 |
ast_edit — riscrittura strutturale, in staging
Sezione intitolata “ast_edit — riscrittura strutturale, in staging”Stessa corrispondenza, più un template rewrite in cui le metavariabili vengono sostituite di nuovo. Non viene scritto nulla. La modifica va in staging e il risultato indica un edit_id.
ast_edit(pattern: "dispose($X)", rewrite: "$X.dispose()", language: "dart")→ (proposed) 12 replacements in 4 files … call resolve with edit_id "edit_1"| Argomento | Significato |
|---|---|
pattern |
Cosa far corrispondere |
rewrite |
Cosa mettere al suo posto, con $NAME sostituito |
path |
Ambito; il valore predefinito è l’intero spazio di lavoro |
language |
Id della lingua |
resolve — conferma o scarta una modifica in staging
Sezione intitolata “resolve — conferma o scarta una modifica in staging”| Argomento | Significato |
|---|---|
edit_id |
Dal risultato (proposed) |
action |
accept o discard |
Ogni file viene confrontato con il contenuto acquisito al momento dello staging, e qualsiasi discrepanza rifiuta l’intera modifica. Una riscrittura strutturale applicata solo in parte lascia un albero che non compila né nella vecchia forma né in quella nuova.
debug — pilota un debugger
Sezione intitolata “debug — pilota un debugger”Registrato quando l’esecuzione ha un supervisor della sessione di debug, una directory di lavoro e un id della conversazione. Se un adattatore può davvero partire viene rilevato al momento della chiamata, con la stessa regola di intersezione del language server (marcatore di radice e binario). Livello exec; non sicuro in parallelo (una sessione è stato che attraversa le chiamate, quindi un continue che scavalca stack leggerebbe un frame che si è già spostato).
Una sessione per conversazione, con un TTL rigido (30 minuti). Un secondo launch viene rifiutato invece di sostituire silenziosamente il primo.
| Op | Argomenti | Note |
|---|---|---|
adapters |
— | Quali adattatori sono utilizzabili qui, e perché no |
status |
— | Se una sessione è in esecuzione, e dove si è fermata |
breakpoints |
file, lines[] |
Un lines vuoto cancella il file. Si possono impostare prima del lancio |
launch |
program, args[] |
Avvia il programma fermo sui tuoi breakpoint |
attach |
port |
Si aggancia a un processo già in esecuzione |
continue |
thread_id? |
Esegue fino alla prossima sosta |
pause |
thread_id? |
Lo ferma dove si trova |
step_over / step_in / step_out |
thread_id? |
Avanza di un passo |
threads |
— | Id e nomi dei thread |
stack |
thread_id? |
I frame, limitati a 30 |
scopes |
frame_id |
Gli scope su un frame, ciascuno con un reference |
variables |
reference |
I figli, limitati a 50, valori limitati a 400 caratteri |
evaluate |
expression, frame_id? |
Valutata nello scope del frame stesso |
output |
— | stdout/stderr del processo in debug, con limiti |
terminate |
— | Termina la sessione e chiude l’adattatore |
Adattatori
Sezione intitolata “Adattatori”| Id | Comando | Marcatori di radice |
|---|---|---|
dart |
dart debug_adapter |
pubspec.yaml |
debugpy |
python3 -m debugpy.adapter |
pyproject.toml, setup.py, requirements.txt |
lldb |
lldb-dap |
Cargo.toml, CMakeLists.txt |
delve |
dlv dap |
go.mod |
debugpy preferisce un .venv/bin o venv/bin locale al progetto rispetto a $PATH: un python preso da $PATH è un ambiente diverso, e agganciarsi da quello sbagliato fallisce in un modo che si legge come codice rotto.
eval — interpreti persistenti
Sezione intitolata “eval — interpreti persistenti”Una cella Python o JavaScript le cui variabili, import e dati caricati sopravvivono tra una chiamata e l’altra. Livello exec; non sicuro in parallelo.
| Argomento | Significato |
|---|---|
code |
La cella |
description |
Obbligatorio. 5–10 parole per l’etichetta della trascrizione |
language |
python (predefinito) o javascript |
reset |
Scarta l’interprete e riparte pulito |
- L’ultima espressione viene restituita come farebbe un notebook.
display()funziona, un frame pandas viene mostrato come tabella e una figura matplotlib torna come un’immagine mostrata nella trascrizione.- Gli idiomi IPython che si digitano d’istinto —
%pip,%cd,!cmd,%%bash,%%timeit— vengono riscritti in codice semplice.%pipsvuota anchesys.modules, così il successivoimportvede ciò che è appena stato installato.
Chiamare i propri strumenti dall’interno di una cella
Sezione intitolata “Chiamare i propri strumenti dall’interno di una cella”contents = tool("read", {"path": "lib/auth.dart"})Il bridge rientra nel registro degli strumenti dell’harness, quindi guardrail, approvazione e ogni wrapper si applicano esattamente come a una chiamata emessa dal modello. Viaggia sulla pipe del kernel stesso anziché su un socket di loopback: nessuna porta, nessun segreto, nessuna regola di uscita in rete.
Il timeout della cella è un budget di inattività (predefinito: 5 minuti) e viene sospeso finché una chiamata tramite bridge è in corso, così una cella che si dirama verso i sottoagenti non viene uccisa a metà diramazione.
ask_user — poni una domanda alla persona
Sezione intitolata “ask_user — poni una domanda alla persona”Livello read. L’unico modo in cui un’esecuzione chiede qualcosa all’operatore. Mostra una scheda numerata nella conversazione e si blocca finché qualcuno non risponde, salta o la domanda va in timeout. Non scrivere mai la domanda come messaggio di chat — questo termina il turno.
| Argomento | Significato |
|---|---|
question |
Cosa chiedere |
context |
Facoltativo: perché lo stai chiedendo e cosa dipende dalla risposta |
options[] |
Le scelte, ciascuna {label, description?} |
allow_free_text |
Se una risposta digitata è accettata |
multi_select |
Se è possibile scegliere più opzioni |
Un salto è un successo: procedi su un’ipotesi dichiarata e non chiedere di nuovo. Un timeout è un errore con la stessa istruzione. Le richieste di autorizzazione («posso farlo?») sono un gate separato e appaiono come la stessa scheda nella conversazione.
Registrato solo quando esistono sia una porta per le domande sia uno spazio di destinazione. Senza una persona collegata la chiamata fallisce anziché bloccarsi per sempre — la stessa postura fail-closed che un prompt di guardrail assume quando non c’è alcun approvatore collegato.
vibe_* — dirigere i worker in background
Sezione intitolata “vibe_* — dirigere i worker in background”Registrato solo mentre la modalità vibe è attiva. Tutti e cinque sono di livello read: il gate appartiene agli strumenti del worker, dove avviene davvero la modifica.
| Strumento | Argomenti | Note |
|---|---|---|
vibe_spawn |
brief, label, tier? |
Ritorna subito; il worker continua a girare |
vibe_send |
worker_id, message |
Si aggiunge al brief e lo riesegue |
vibe_wait |
worker_id, timeout_seconds? |
Si blocca finché non si assesta |
vibe_kill |
worker_id |
Lo ferma |
vibe_list |
— | Livello, stato, tempo trascorso e ultimo risultato |
tier è fast (lavoro meccanico con una specifica chiara) o good (progettazione, giudizio o revisione dell’output di un worker fast).