Research extension — NATIVE tools.
Three model-facing bindings, bound BARE (native, no alias) in the
sandbox alongside cat/rg/patch — same surface as the foundation
kernel, no ;; -- EXTENSION search -- prompt block:
search_web(query, opts?) — web search via Exa MCP search_code(query, opts?) — code/doc context via Exa MCP search_papers(query, opts?) — arxiv papers (Atom feed)
Output shape — consistent with the rest of the :tag :observation
tool surface (cat, ls, rg). Every search fn returns the
canonical tool envelope; the agent sees the unwrapped :result map:
{:op :search-web|:search-code|:search-papers :query "…" :citations [{:type :title :url :excerpt :source …} …] :citation-count N :truncated? B :source :exa|:arxiv :endpoint "…REDACTED…" ;; web/code only :error? true ;; only on failure :error {:message … …}} ;; only on failure
:excerpt is Markdown; the channel renderer parses it through
vis/markdown->ir so the TUI / Telegram / web channels render
commonmark blocks (headings, lists, code fences) instead of dumping
the raw blob. Errors are still surfaced inline as a single citation
with :error true AND on the envelope's :error slot so failures
stay visible no matter which lens the consumer reads.
Exa MCP: the public endpoint supports basic unauthenticated use;
set EXA_API_KEY (or EXA_MCP_API_KEY) for higher limits. The
key is never logged or surfaced; the endpoint shown in results is
redacted.
arxiv: free public Atom feed via https://export.arxiv.org/api/query.
Research extension — NATIVE tools.
Three model-facing bindings, bound BARE (native, no alias) in the
sandbox alongside cat/rg/patch — same surface as the foundation
kernel, no `;; -- EXTENSION search --` prompt block:
search_web(query, opts?) — web search via Exa MCP
search_code(query, opts?) — code/doc context via Exa MCP
search_papers(query, opts?) — arxiv papers (Atom feed)
Output shape — consistent with the rest of the `:tag :observation`
tool surface (cat, ls, rg). Every search fn returns the
canonical tool envelope; the agent sees the unwrapped `:result` map:
{:op :search-web|:search-code|:search-papers
:query "…"
:citations [{:type :title :url :excerpt :source …} …]
:citation-count N
:truncated? B
:source :exa|:arxiv
:endpoint "…REDACTED…" ;; web/code only
:error? true ;; only on failure
:error {:message … …}} ;; only on failure
`:excerpt` is Markdown; the channel renderer parses it through
`vis/markdown->ir` so the TUI / Telegram / web channels render
commonmark blocks (headings, lists, code fences) instead of dumping
the raw blob. Errors are still surfaced inline as a single citation
with `:error true` AND on the envelope's `:error` slot so failures
stay visible no matter which lens the consumer reads.
Exa MCP: the public endpoint supports basic unauthenticated use;
set `EXA_API_KEY` (or `EXA_MCP_API_KEY`) for higher limits. The
key is never logged or surfaced; the endpoint shown in results is
redacted.
arxiv: free public Atom feed via `https://export.arxiv.org/api/query`.Test seam. Function of [request-map] returning the
babashka.http-client response shape {:status :headers :body}.
Test seam. Function of `[request-map]` returning the
babashka.http-client response shape `{:status :headers :body}`.(effective-config)Return effective Exa MCP config. Public for diagnostics/tests.
Return effective Exa MCP config. Public for diagnostics/tests.
(redact-endpoint endpoint)Redact exaApiKey query param from an endpoint string.
Redact `exaApiKey` query param from an endpoint string.
(search-code query)(search-code query opts)await search_code("clojure core.async go-loop example") await search_code("…", {"tokens_num": N})
Live code/docs search via Exa (github repos, clojuredocs, readthedocs, API refs). Narrow with "site:github.com X" or "<repo> X". Returns {"query", "citations": [{"type": "code", "title", "url", "excerpt", "source"}, ...], "citation_count", "truncated", "source", "endpoint"}. Gotcha: "excerpt" is markdown text; on failure "citations"[0] has "error": True.
await search_code("clojure core.async go-loop example")
await search_code("…", {"tokens_num": N})
Live code/docs search via Exa (github repos, clojuredocs, readthedocs, API refs). Narrow with "site:github.com X" or "<repo> X".
Returns {"query", "citations": [{"type": "code", "title", "url", "excerpt", "source"}, ...], "citation_count", "truncated", "source", "endpoint"}.
Gotcha: "excerpt" is markdown text; on failure "citations"[0] has "error": True.(search-papers query)(search-papers query opts)await search_papers("diffusion models for protein folding") await search_papers("…", {"max_results": 10, "sort": "relevance", "timeout_ms": 20000})
arxiv paper search. Returns {"query", "citations": [{"type": "paper", "title", "url", "excerpt", "authors", "published", "source"}, ...], "citation_count", "truncated", "source"}. opts: "sort" is relevance|lastUpdatedDate|submittedDate (default relevance). Gotcha: "excerpt" is the abstract (plain text); on failure "citations"[0] has "error": True.
await search_papers("diffusion models for protein folding")
await search_papers("…", {"max_results": 10, "sort": "relevance", "timeout_ms": 20000})
arxiv paper search.
Returns {"query", "citations": [{"type": "paper", "title", "url", "excerpt", "authors", "published", "source"}, ...], "citation_count", "truncated", "source"}.
opts: "sort" is relevance|lastUpdatedDate|submittedDate (default relevance).
Gotcha: "excerpt" is the abstract (plain text); on failure "citations"[0] has "error": True.(search-web query)(search-web query opts)await search_web("rust async runtime comparison") await search_web("…", {"num_results": 5, "type": "auto", "livecrawl": "preferred", "context_max_characters": N})
Live web search via Exa. Returns {"query", "citations": [{"type": "web", "title", "url", "excerpt", "published", "authors", "source"}, ...], "citation_count", "truncated", "source", "endpoint"}. Gotcha: "excerpt" is markdown text — read it directly; on failure "citations"[0] carries "error": True with the message in "excerpt".
await search_web("rust async runtime comparison")
await search_web("…", {"num_results": 5, "type": "auto", "livecrawl": "preferred", "context_max_characters": N})
Live web search via Exa.
Returns {"query", "citations": [{"type": "web", "title", "url", "excerpt", "published", "authors", "source"}, ...], "citation_count", "truncated", "source", "endpoint"}.
Gotcha: "excerpt" is markdown text — read it directly; on failure "citations"[0] carries "error": True with the message in "excerpt".(truncate-text text {:keys [max-bytes max-lines]})Bound text by line and UTF-8 byte limits. Returns truncation map.
Bound `text` by line and UTF-8 byte limits. Returns truncation map.
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 |