Skip to content

Tools · Knowledge & Research

The ChromaDB knowledge base and outbound web/HTTP tools. See Tool Reference for how to read these signatures.

KnowledgeTools

Group knowledge. Both tools tier Standard.

search_knowledge

search_knowledge(query, max_results?, source_filter?, collection?) → results (Markdown)

Param Type Req Default Description
query string yes — Search query
max_results int no 5 (clamped 1–10) Max results
source_filter string no — Optional source-prefix filter
collection string no — Optional ChromaDB domain collection (e.g. ai-deployment, system)

What it searches. The calling node's knowledge scope, resolved once at session start: the team's packs (from knowledge_packs, or detected when that is unset), its target_collections domains, and the project's own collection. A node that runs code (run_shell, run_tests) also gets the packs its base image implies; a node holding comfyui_generate gets the image packs for the team's image_model; a node's knowledge_filters replace all of it. The global collection is filtered to the scope's packs before the nearest-neighbour search, so a team with no packs never reads it. A call outside a run searches every pack plus the project. collection replaces the scope with exactly that domain, or that pack when no such domain exists, and is never created by being searched; source_filter narrows pack and project hits by source prefix.

Returns ## Knowledge Base Results (N found) with per-hit relevance (cosine similarity), knowledge ID, and a content block of up to 1,600 characters — a whole chunk. Discards hits under ChromaDb:ScoreFloor (0.525, see Configuration), keeps at most two chunks per document, and drops build logs. Returns a "no results" string when nothing clears the floor. A search that could not run at all — no embedding model loaded, ChromaDB unreachable — returns Knowledge search is unavailable: <reason> with an instruction not to retry; "no results" is reserved for a search that ran.

write_knowledge

write_knowledge(filename, content, folder?, collection?) → JSON receipt

Param Type Req Default Description
filename string yes — Document name (e.g. findings.md); no .., /, or \
content string yes — Document content
folder string no agent-notes Subfolder within the knowledge base (same sanitization)
collection string no — Optional ChromaDB domain collection to index into

Returns a JSON string — load-bearing for worker loop-exit logic, so a worker can confirm the save and stop retrying. A document counts as written only when it was indexed: the file lands on disk either way, but ok is false when indexing was refused or failed (for example, no embedding model is loaded), and the payload then says why and tells the agent not to retry:

Field Type Meaning
ok bool true when the disk write and every requested indexing succeeded
path string <folder>/<filename>
chars_written int content.Length
project_scoped bool Whether a project-scoped collection was used
indexed bool true if RAG indexing succeeded
domain_indexed string | null Domain collection name if domain indexing succeeded
domain_candidate string Present only when collection is a shared domain: the domain the document now waits to join
index_error string Present only if primary indexing was refused or threw
domain_error string Present only if domain indexing was refused or threw
reason string Present only when ok is false — the indexing error
file_saved bool Present only when ok is false; true — the file is on disk
hint string Present only when ok is false — an infrastructure problem, not a content problem; do not retry the same write

A failed disk write returns a bare Error… string instead of JSON. The document is indexed into the project's collection (and, with collection, that domain too) under the same id on every write, so writing the same file again replaces its chunks. A shared domain, one that any loaded template names in target_collections, is the exception: it takes a project's document only once the owner approves it. The write then lands in the project's collection as a candidate, which the project can search at once; domain_indexed stays null and domain_candidate names the domain (API · Promotion candidates). Any other domain still takes the write directly. With no project behind the call there is nowhere to index it: the global collection takes only pack content, so the payload comes back ok: false.

ResearchTools

Group research. Five tools tier Elevated; download_pdf is Restricted. Every tool here reaches the network, so all pass the egress/DLP gate (§07).

web_search(query, max_results?) → results (Markdown)

Param Type Req Default Description
query string yes — The search query
max_results int no 5 (clamped 1–10) Max results

Returns ## Web Search Results for: <query> with ### [title](url) + snippet entries. Backend: SearXNG when the SearXNG_Url setting is present (the query goes to SearXNG's enabled engine set, categories=general; no engines are pinned by the tool), falling back to a DuckDuckGo HTML scrape.

web_fetch

web_fetch(url) → page text, plus the page's article links

Param Type Req Description
url string yes The URL to fetch (must start with http)

HTML is stripped to text and capped at 20,000 characters (with a [Truncated: …] marker); the reply then lists up to 40 same-site links that look like articles under ## Links on this page, so an agent that lands on a front page can open the story instead of quoting its teaser.

Returns ## Content from: <url> then the page text — scripts/styles/markup stripped, truncated at 10,000 chars. 30-second timeout.

http_request

http_request(url, method?, body?, headers?) → status + body

Param Type Req Default Description
url string yes — Target URL
method string no GET GET, POST, PUT, DELETE, PATCH, HEAD
body string no — Request body (POST/PUT/PATCH; sent as application/json)
headers string | object no — Headers as a JSON string or object; a Content-Type key is ignored

Returns "<status> <reason>\n\n<body>"; body is pretty-printed if JSON, truncated at 10,000 chars.

download_pdf

download_pdf(url, save_path) → confirmation + text preview · Restricted

Param Type Req Description
url string yes URL of the PDF
save_path string yes Relative workspace path (e.g. research/paper.pdf); rejects .., a path through a link, and treats a leading / as workspace-relative

The Engine's only Restricted tool — always requires human approval with no supervisor fallback (gated both by tier and by an in-method approval call). Returns a confirmation plus the first 3000 chars of extracted text. 50 MB size cap; text extracted via PdfPig.

capture_reference

capture_reference(url, slug, widths?) → JSON design facts + saved screenshot paths · Elevated

Param Type Req Default Description
url string yes — Page to capture; must start with http:// or https://
slug string yes — Short name for this reference, used as its folder (lowercase letters, digits, hyphens)
widths string no 1440,390 Comma-separated viewport widths — desktop then mobile

Drives headless Chrome over CDP and saves one screenshot per width into finishing/references/<slug>/ in the workspace, then returns a JSON object of the page's computed design facts — palette (each colour with the share of painted area it holds), type_scale, measure_px, spacing, breakpoints, density, plus files with the workspace paths of the screenshots. Every value is read off the live page rather than estimated, which is the point: it is evidence about a comparable product, not an impression of one.

Two consequences worth knowing. The capture runs on the host as the Engine's own user and writes straight into the bind-mounted workspace, so a /workspace directory left owned by root — anything a root-run container_init_commands created — makes it fail with a permission error while write_file beside it keeps working. And what comes back is the page's computed palette, not its designed one: on a site built with an unthemed CSS framework the result is the framework's defaults.

http_health_check

http_health_check(url, method?, timeout_ms?, expected_status?) → health block

Param Type Req Default Description
url string yes — URL to check (must start with http:///https://)
method string no GET GET or HEAD
timeout_ms int no 5000 (clamped 500–30000) Timeout
expected_status int no 200 Expected status code

Returns ## Health check: <url> with status, latency, expected, and a PASS / FAIL (got X, expected Y) / TIMEOUT / CONNECTION FAILED result.

Where to go next