Skip to content

Handle — a running sub-agent

Clojure (JVM) + cljgo · package net.clojars.muthuishere/toolnexus · SPEC §7D

The state machine for one spawned agent: pending, running, suspended, done.

A handle is the thing you hold while a child is working: it names the child, reports where it is, and gives you somewhere to hang a result. Its whole value is that the parent does not have to block.

An A2A task id is that handle. It is a string rather than an object, and its state lives in the store rather than in memory, which is exactly what makes it survive a restart:

(require '[toolnexus.serve :as serve])
(def store (serve/file-store "./tasks"))
(defn task-state
"The handle's state machine, read from wherever the task actually lives."
[id]
(let [t ((:get store) id)]
(case (get-in t [:status :state])
"submitted" :queued
"working" :running
"completed" {:done (->> (:artifacts t) (mapcat :parts) (map :text))}
"failed" {:failed (get-in t [:status :message :parts 0 :text])}
nil :unknown)))

The mapping is close but not complete. submitted and working cover pending and running; completed / failed / canceled cover done. There is no suspended state on a task — §10 suspension is a property of the client loop, not of the serve lifecycle, so a child that needs an answer from a human surfaces through the parent’s :wait-for rather than as a paused handle. And a process that dies mid-fulfilment leaves a task saved as working with nothing left to finish it; treat a long-stale working as failed, because nothing else will.

On the parent side there is no handle at all — calling a peer’s tool blocks until the task is terminal. The :metadata on the result is the post-hoc summary a handle would have carried live:

;; => {:agent "researcher" :taskId "3f2c..." :state "completed" :polls 7 :ms 3480}
(:metadata result)

If you want the parent to keep working while the child runs, hold the task id yourself: POST SendMessage directly (as in the serve examples), stash the returned :id, and poll GetTask on your own schedule instead of going through the peer tool.