Llamada a herramienta
ui.ToolCall es un componente para una acción de un agente de IA (leer un archivo, editarlo, ejecutar un comando), dibujado como en Zed: una línea con el estado, el título (title) y sobre qué trabaja (detail), y un clic despliega la entrada (input) y la salida (output), más las imágenes (images) si las hay. Las ediciones, los comandos (kind edit, delete, move o execute) y las llamadas que esperan son tarjetas. diffs muestra los cambios que hizo como diferencias de colores y, mientras se ejecuta, progress muestra las últimas líneas que imprimió un comando. Mientras status es "waiting" pregunta en la misma tarjeta: Permitir siempre, Permitir o Rechazar, que llegan a on_allow, on_allow_always y on_deny. El componente recuerda si está desplegado; tu app solo guarda los datos.
ui.ToolCall · Categoría: Agentes de IA · Referencia completa →


pz.column([ ui.ToolCall(title="Read file", detail="app/storage.py", kind="read", output="def save(path): ..."), ui.ToolCall(title="Search", detail="def save", kind="search", output="app/storage.py:12"), ui.ToolCall(title="Edit file", detail="app/storage.py", kind="edit", status="waiting", diffs=[{"path": "app/storage.py", "old": "def save(path):\n write(path)\n", "new": "def save(path, data):\n write(path, data)\n"}], on_allow=on_allow, on_allow_always=on_allow_always, on_deny=on_deny), ui.ToolCall(title="Run", detail="pytest -q", kind="execute", status="running", progress="collected 24 items\n........................"),], spacing=4, width=560)Cuándo usarlo
Sección titulada «Cuándo usarlo»- En el chat de un agente, una por cada paso que da.
- Con
status="waiting", para preguntar antes de un paso delicado como escribir archivos o ejecutar un comando. - Para un cambio suelto, fuera de una llamada a herramienta, usa la Vista de diferencias.
import pyzed as pzfrom pyzed import ui
class Chat(pz.App): def __init__(self): self.status = "waiting"
def answer(self, allowed): self.status = "done" if allowed else "rejected"
def view(self): return ui.ToolCall(title="Run", detail="pytest -q", kind="execute", status=self.status, input={"command": "pytest -q"}, output="24 passed", on_allow=lambda e: self.answer(True), on_deny=lambda e: self.answer(False))Variantes
Sección titulada «Variantes»Pendiente y en marcha muestran un spinner, esperando pregunta con Permitir, Permitir siempre y Rechazar, y fallida y rechazada lo dicen en rojo.


status="pending"Código
pz.container(ui.ToolCall(title="Edit file", detail="app.py", kind="edit", status="pending"), width=360)

status="running"Código
pz.container(ui.ToolCall(title="Edit file", detail="app.py", kind="edit", status="running"), width=360)

status="done"Código
pz.container(ui.ToolCall(title="Edit file", detail="app.py", kind="edit", status="done"), width=360)

status="waiting"Código
pz.container(ui.ToolCall(title="Edit file", detail="app.py", kind="edit", status="waiting", on_allow=on_allow, on_allow_always=on_allow_always, on_deny=on_deny), width=360)

status="failed"Código
pz.container(ui.ToolCall(title="Edit file", detail="app.py", kind="edit", status="failed"), width=360)

status="rejected"Código
pz.container(ui.ToolCall(title="Edit file", detail="app.py", kind="edit", status="rejected"), width=360)El tipo elige el icono de una llamada terminada.


kind="read"Código
pz.container(ui.ToolCall(title="Read file", detail="app.py", kind="read"), width=300)

kind="edit"Código
pz.container(ui.ToolCall(title="Edit file", detail="app.py", kind="edit"), width=300)

kind="delete"Código
pz.container(ui.ToolCall(title="Delete file", detail="old.py", kind="delete"), width=300)

kind="move"Código
pz.container(ui.ToolCall(title="Move file", detail="a.py → b.py", kind="move"), width=300)

kind="search"Código
pz.container(ui.ToolCall(title="Search", detail="def save", kind="search"), width=300)

kind="execute"Código
pz.container(ui.ToolCall(title="Run", detail="pytest -q", kind="execute"), width=300)

kind="think"Código
pz.container(ui.ToolCall(title="Think", kind="think"), width=300)

kind="fetch"Código
pz.container(ui.ToolCall(title="Fetch", detail="https://example.com", kind="fetch"), width=300)

kind="switch_mode"Código
pz.container(ui.ToolCall(title="Switch mode", detail="plan", kind="switch_mode"), width=300)

kind="other"Código
pz.container(ui.ToolCall(title="Tool", detail="custom", kind="other"), width=300)Contenido
Sección titulada «Contenido»Las desplegadas se dibujan como quedan tras un clic en la cabecera.


progress=Código
pz.container(ui.ToolCall(title="Run", detail="pytest -q", kind="execute", status="running", progress="collected 24 items\n............\n............"), width=360)

diffs=Código
pz.container(ui.ToolCall(title="Edit file", detail="app.py", kind="edit", status="running", diffs=[{"path": "app.py", "old": "x = 1\ny = 2\n", "new": "x = 10\ny = 2\n"}]), width=360)

allow_always=FalseCódigo
pz.container(ui.ToolCall(title="Run", detail="rm -rf build", kind="execute", status="waiting", allow_always=False, on_allow=on_allow, on_deny=on_deny), width=360)

input=, output=Código
pz.container(ui.ToolCall(title="Read file", detail="app.py", kind="read", input={"path": "app.py"}, output="import pyzed as pz\n\npz.run(App)"), width=360)

Código
pz.container(ui.ToolCall(title="Edit file", detail="app.py", kind="edit", diffs=[{"path": "app.py", "old": "x = 1\ny = 2\n", "new": "x = 10\ny = 2\n"}]), width=360)Eventos
Sección titulada «Eventos»Llamada a herramienta tiene 3 eventos propios, en la tabla de abajo. Como todo widget, también tiene los 18 eventos comunes (click, double_click, right_click, mouse_enter, drag, key_down, resize…), que se conectan con .on(...): mira Eventos y Eventos de cada componente.
Es un pz.Component, así que también lanza on_mount y on_unmount, y sus handlers reciben un pz.Event cuyo value trae el dato.
| Evento | El handler recibe | Cuándo |
|---|---|---|
on_allow |
(event) |
Se pulsó Permitir. |
on_allow_always |
(event) |
Se pulsó Permitir siempre. |
on_deny |
(event) |
Se pulsó Rechazar. |
El handler recibe es lo que Pyzed le pasa a tu función: () es nada. Cualquier handler también puede ser un mensaje (un valor que no se puede llamar), que va a update().
Manejar los eventos
Sección titulada «Manejar los eventos»Los mismos eventos escritos de tres formas. Imperativa: métodos de la app que cambian self. Declarativa: los handlers producen mensajes y un único update() decide. Funcional: una función pura dibuja un estado inmutable y pide cambios con set_state(...). Mira Imperativo, declarativo y funcional.
class Chat(pz.App): def __init__(self): self.status = "waiting"
def answer(self, status): self.status = status
def view(self): # a pz.Component: handlers get a pz.Event return ui.ToolCall(title="Run", detail="pytest -q", kind="execute", status=self.status, input={"command": "pytest -q"}, on_allow=lambda e: self.answer("done"), on_allow_always=lambda e: self.answer("done"), on_deny=lambda e: self.answer("rejected"))class Chat(pz.App): status = "waiting"
def update(self, message): match message: case "allow": self.status = "done" case "deny": self.status = "rejected"
def view(self): return ui.ToolCall(title="Run", detail="pytest -q", kind="execute", status=self.status, on_allow="allow", on_deny="deny") # messages work for components toofrom dataclasses import dataclass
@dataclass(frozen=True)class State: status: str = "waiting"
def view(state, set_state): return ui.ToolCall(title="Run", detail="pytest -q", kind="execute", status=state.status, on_allow=lambda e: set_state(status="done"), on_deny=lambda e: set_state(status="rejected"))Consejos
Sección titulada «Consejos»Propiedades y API
Sección titulada «Propiedades y API»ui.ToolCall
Sección titulada «ui.ToolCall»class ToolCallUn componente para una acción de un agente de IA, dibujada como en el panel Agent de Zed: una línea con su icono, lo que hace y dónde (se despliega para mostrar la entrada y la salida), o una tarjeta para las ediciones y los comandos, con el diff o la salida. Mientras status es "waiting" pregunta en la propia tarjeta: Permitir siempre, Permitir o Rechazar. Mira Agentes de IA.
| Propiedad | Por defecto | Descripción |
|---|---|---|
title |
"" |
Lo que hace (“Editar archivo”). |
detail |
"" |
Sobre qué trabaja, en letra monoespaciada. |
kind |
"" |
El tipo de ACP: read, edit, delete, move, search, execute, think, fetch u other (su icono). |
status |
"done" |
pending, running, waiting, done, failed, rejected o canceled. |
input |
None |
Los argumentos (un dict o texto). |
output |
None |
La respuesta (texto o un dict). |
images |
None |
Bytes PNG que se muestran bajo la salida. |
diffs |
None |
Los cambios que hizo: dicts {"path", "old", "new"}, que se muestran como diffs de colores (mira ui.diff_view). |
progress |
"" |
Lo que imprimió hasta ahora (la salida de un comando); sus últimas líneas se ven bajo la cabecera mientras corre. |
allow_always |
True |
Muestra Permitir siempre. |
theme |
None |
Tema. |
Eventos: on_allow, on_allow_always, on_deny (eventos).