Skip to main content

Artifact Tools — docx / xlsx / pdf

Six node types give a deepAgent the ability to read documents the caller attaches and to generate downloadable documents of its own:

TypeGroupPurpose
docx_readreadExtract text and headings from an attached or previously-emitted .docx
xlsx_readreadRead headers and rows from each sheet of an attached or previously-emitted .xlsx
pdf_readreadExtract markdown text and page count from an attached or previously-emitted .pdf
docx_writewriteGenerate a Word document from a title and markdown body
xlsx_writewriteGenerate an Excel workbook from one or more typed sheet specifications
pdf_writewriteRender a PDF from HTML or markdown

Each is a first-class tool node with isTool: true and a single tool output handle. The agent calls them autonomously based on the user's prompt — they are first-party agent capabilities, not external connectors.

The direct-to-deepAgent exception

Unlike mcpServer, which must attach under a subagent, artifact tools edge directly off the deepAgent via a tools → tool edge. They are the single deliberate exception to the "no direct tools on the deepAgent" rule, because they are built-in agent capabilities rather than external tool sources. Do not place them under a subagent.

How availability is gated

There is no per-agent allowlist or permission table. A tool is callable iff its node exists in the graph and a tools → tool edge connects it to the deepAgent. Tools are discovered at compile time by walking out_edges(deepAgent, sourceHandle="tools") and looking up each target's type in the worker NODE_MAPPING. Add only the tools a workflow actually needs — fewer tools shorten the agent's tool-selection prompt and reduce wrong-tool calls.

For the full topology (input → deepAgent → six tools → output) and a complete worked example, see Wiring an Artifact-Capable Workflow.

Node shape

All six tools use the exact same minimal node shape — only id, type, label, and isOutput change. The node's own params map is empty ({}); the read tools take their target as a tool-call argument at runtime, not as a static node param.

FieldValueNotes
typeone of the six names abovesnake_case, e.g. docx_write
data.isTooltruemarks the node as a tool target
data.isOutputtrue for writers, false for readerswriters are graph outputs (they emit artifacts); readers are not
data.handles["tool"]the single output handle the tools → tool edge targets
data.params{}empty — there are no static parameters on these nodes

Read tools

docx_read, xlsx_read, pdf_read let the agent ingest a document so it can parse it. The caller attaches a document at runtime via the Files API (an input_file content part referencing an uploaded file_id); without the matching read node wired in, the attached file is unreadable by the agent.

The agent selects the target document at call time by passing one of:

  • a file_id — the public id of a file attached to the request via the Files API, or
  • an artifact_id — an artifact produced earlier in the same run, or
  • a raw s3_key — for cross-job reads by long-running agents.

These are tool-call arguments the agent supplies, not node params. The backend prepends a file preamble to the prompt listing each attached file_id and its MIME type, so the model can pick the right read tool (a .docx MIME nudges toward docx_read, etc.).

Output

A read tool returns the extracted content to the agent: docx_read returns text and headings; xlsx_read returns each sheet's headers and rows; pdf_read returns markdown text and page count.

Write tools

docx_write, xlsx_write, pdf_write let the agent generate a downloadable document. When the agent calls a write tool, the worker renders the bytes, uploads them to the artifacts bucket, deduplicates by sha256, mints a short-lived signed download URL, and emits the artifact into the live stream. Writers are graph outputs (isOutput: true).

The generated document is surfaced to clients as an ArtifactRef carried on a response.output_item.added event over the Responses API (translated from the worker's artifact.created event). The ArtifactRef.source_node field records which write tool produced it (e.g. "docx_write"). See Agent Artifacts for the ArtifactRef shape, the download endpoint, and per-node metadata keys (e.g. xlsx_write injects sheet_names: string[] into the artifact's metadata).

Output

A write tool produces no graph-data output; its effect is to emit an artifact. The artifact reference (id, filename, mime type, size, download URL) reaches the client over the streaming surface, not as a node output field.

Handles

Every artifact tool has a single output handle, tool. It is the target of a tools → tool edge from the deepAgent:

deepAgent (tools) ──▶ (tool) docxWrite

sourceHandle: "tools" and targetHandle: "tool" are the magic strings — any other handle combination is treated as a data-flow edge and the runtime will not register the target as a tool. A single deepAgent fans out to as many artifact-tool nodes as it needs, each its own tools → tool edge.

Example

A write tool node and the edge that makes it callable:

{
"id": "docxWrite-8",
"type": "docx_write",
"data": {
"label": "DOCX Write",
"isTool": true,
"isInput": false,
"isOutput": true,
"handles": ["tool"],
"params": {},
"inputs": [],
"outputs": [],
"errors": []
},
"position": { "x": 1250, "y": 280 }
}
{
"id": "e-deep-wDocx",
"source": "deepAgent-4",
"target": "docxWrite-8",
"sourceHandle": "tools",
"targetHandle": "tool"
}

A read tool node is identical except "type": "docx_read" (or xlsx_read / pdf_read), "label" to match, and "isOutput": false.

  • Wiring an Artifact-Capable Workflow — full topology, the tools → tool edge shape, a complete six-tool worked example, and system-prompt guidance.
  • Agent Artifacts — the artifact lifecycle, the ArtifactRef shape, per-node metadata keys, and the download endpoint.
  • Sending Documents to the Agent — how to upload docx/xlsx/pdf inputs via the Files API and reference them by file_id.
  • deepAgent — the orchestrator these tools edge directly off.
  • mcpServer — the contrasting tool node that must attach under a subagent.