s as a vector of Unicode code points — koine.text/code-points.
Lived here first: this port found the divergence (nine sites sorting
differently on the two hosts) and carried the fix locally until koine 0.11.0
lifted it into the seam, where a clojure.core divergence belongs. The vars
stay so call sites and tests read tool/…, but there is ONE implementation.
`s` as a vector of Unicode code points — `koine.text/code-points`. Lived here first: this port found the divergence (nine sites sorting differently on the two hosts) and carried the fix locally until koine 0.11.0 lifted it into the seam, where a clojure.core divergence belongs. The vars stay so call sites and tests read `tool/…`, but there is ONE implementation.
Code-point string comparison, identical on both hosts — koine.text/compare-strings.
See code-points for why this delegates.
Code-point string comparison, identical on both hosts — `koine.text/compare-strings`. See `code-points` for why this delegates.
(execute tk name args)(execute tk name args ctx)Run a tool by name. A THROW from a tool becomes an error ToolResult — a misbehaving tool must not take down the loop (SPEC §0.8).
Run a tool by name. A THROW from a tool becomes an error ToolResult — a misbehaving tool must not take down the loop (SPEC §0.8).
(failure output)(failure output metadata)A failed ToolResult. Note a tool ERROR is a VALUE handed back to the model,
not a thrown exception — the model is meant to see it and try again.
NOT named err, for the reason given on success.
A failed ToolResult. Note a tool ERROR is a VALUE handed back to the model, not a thrown exception — the model is meant to see it and try again. NOT named `err`, for the reason given on `success`.
(sanitize s)SPEC §0.2 — replace [^a-zA-Z0-9_-] with _.
SPEC §0.2 — replace [^a-zA-Z0-9_-] with _.
(sort-strings coll)coll sorted by compare-strings — koine.text/sort-strings, returned as a
vector because every caller here treats tool lists as vectors.
`coll` sorted by `compare-strings` — `koine.text/sort-strings`, returned as a vector because every caller here treats tool lists as vectors.
(success output)(success output metadata)A successful ToolResult (SPEC §0.1).
NOT named ok: cljgo's clojure.core HAS ok and err (the JVM's does not),
so (defn ok ...) shadows a core name on one host only — measured 2026-07-31.
It warns today; per cljgo's static interop scan a bare core-shaped symbol can
reject the WHOLE namespace, and a hazard that fires on one host and not the
other is the exact thing this port exists to avoid.
A successful ToolResult (SPEC §0.1). NOT named `ok`: cljgo's clojure.core HAS `ok` and `err` (the JVM's does not), so `(defn ok ...)` shadows a core name on one host only — measured 2026-07-31. It warns today; per cljgo's static interop scan a bare core-shaped symbol can reject the WHOLE namespace, and a hazard that fires on one host and not the other is the exact thing this port exists to avoid.
(tool {:keys [name description input-schema source execute]})Build a Tool. execute takes (args) or (args ctx) and returns a ToolResult.
Build a Tool. `execute` takes (args) or (args ctx) and returns a ToolResult.
(tool-names tk)Sorted, always. Two runtimes must not disagree on order — which is why this
uses compare-strings and not sort; see there.
Sorted, always. Two runtimes must not disagree on order — which is why this uses `compare-strings` and not `sort`; see there.
(toolkit tools)(toolkit tools sources)A toolkit is {:tools {name -> Tool} :sources {source -> status}}. Later tools win on a name collision, which is how SPEC §0.11's MCP precedence over builtins is expressed: register builtins first, MCP after.
A toolkit is {:tools {name -> Tool} :sources {source -> status}}.
Later tools win on a name collision, which is how SPEC §0.11's MCP precedence
over builtins is expressed: register builtins first, MCP after.(with-parts result parts)SPEC §1B — attach non-text parts to a ToolResult.
cond->, so an EMPTY or absent parts list leaves the result byte-identical to
what success/failure produced. That is the whole compatibility story: the
52 construction sites in this port are untouched, and a text-only tool's JSON
does not move by a byte.
output stays REQUIRED and stays what the transcript, compaction, token
estimation and any text-only provider see — a tool returning an image sets
output to a description and parts to the image.
SPEC §1B — attach non-text `parts` to a ToolResult. `cond->`, so an EMPTY or absent parts list leaves the result byte-identical to what `success`/`failure` produced. That is the whole compatibility story: the 52 construction sites in this port are untouched, and a text-only tool's JSON does not move by a byte. `output` stays REQUIRED and stays what the transcript, compaction, token estimation and any text-only provider see — a tool returning an image sets `output` to a description and `parts` to the image.
cljdoc builds & hosts documentation for Clojure/Script libraries
| Ctrl+k | Jump to recent docs |
| ← | Move to previous article |
| → | Move to next article |
| Ctrl+/ | Jump to the search field |