CapabilitiesFiles and outputs

Artifacts

An Artifact is a file an Agent deliberately delivers from a Turn. Use one when an application must discover and download a finished output; workspace files that were never published remain private mutable Sandbox state.

From private file to Artifact

The save_artifacts Tool accepts workspace-relative paths. It resolves every path under /workspace, reads every file, and validates the whole batch before uploading bytes. One call accepts at most 10 paths, each file can be at most 10 MiB, and the complete batch can be at most 25 MiB. A Session can hold at most 100 active Artifacts.

After validation, the Tool uploads the files to private object storage and atomically records the batch metadata. A stored Artifact has a platform ID, filename, media type, byte size, creation time, and ownership fields. Partial uploads and later deletions enter the durable cleanup path rather than becoming public files.

Publish and download an Artifact

import { BlazingAgents } from "@blazing-agents/sdk";

const client = new BlazingAgents({
  apiKey: process.env.BLAZING_AGENTS_API_KEY!,
});
const sandbox = await client.sandboxes.create({ name: "Output Sandbox" });
const agent = await client.agents.create({
  name: "Artifact Writer",
  sandboxId: sandbox.id,
  tools: ["file_operation_sandbox"],
});
const expected = "# Release checklist\n\n- Ship docs\n";
const turn = await client.chat({
  agentId: agent.id,
  message: {
    id: crypto.randomUUID(),
    role: "user",
    parts: [{ type: "text", text: `Write release.md with exactly ${JSON.stringify(expected)}, then publish it.` }],
  },
});
const sessionId = await turn.sessionId;
for await (const _chunk of turn.toUIMessageStream()) {
  // Drain the Turn so publication and Session persistence finish.
}
const page = await client.artifacts.list(agent.id, { sessionId });
const artifact = page.data.find(({ filename }) => filename === "release.md");
if (!artifact) throw new Error("release.md was not published");
const response = await client.artifacts.download(agent.id, artifact.artifactId);
if ((await response.text()) !== expected) throw new Error("bytes differ");

The final assertion verifies that the downloaded bytes match the file the Agent created and published.

Ownership and discovery

Every Artifact belongs to one tenant, Agent, and stateful Session. It inherits the Session's Attribution userId and metadata; Attribution supports filtering and reporting, not access control.

A Task run creates its own fresh Session when execution starts. Artifacts that the run publishes belong to that Session, and the Task run exposes its sessionId after the Session is attached. Retrieve the run with client.tasks.getRun() or client.tasks.listRuns(), then pass its non-null sessionId to client.artifacts.list(agentId, { sessionId }) to discover only that run's Artifacts.

Artifact lists are scoped to an Agent, ordered newest first, and cursor paginated. They can be filtered by sessionId or userId; deleted records are excluded unless includeDeleted: true is set. Each item includes the ownership fields, filename, media type, byte size, timestamps, and tombstone state.

Download returns the raw bytes in a Response. The server supplies Content-Type, Content-Length, an attachment Content-Disposition, and X-Content-Type-Options: nosniff; the SDK does not convert the body.

Immutability and deletion

Artifact content is immutable. To replace an output, publish a new Artifact.

Deleting one atomically tombstones its product record and records cleanup of its private bytes. Normal lists no longer return it; lists with includeDeleted: true return it with deletedAt. Get, download, or repeated delete of that tombstone returns 410 Gone; an unknown or out-of-scope ID returns 404 Not Found. Existing Session transcripts are not rewritten.

Production considerations

  • Enforce the per-file, per-call, and per-Session limits before designing large-output workflows. See Artifact service limits.
  • Treat Agent-controlled filenames, media types, and bytes as untrusted even though download headers force attachment behavior.
  • Keep API keys on your backend. Tenant credentials can access all Artifacts in the tenant; userId is not authorization.
  • Define retention in your application and delete outputs when their private bytes are no longer needed.
  • Do not construct object-storage paths or assume Artifacts have public URLs. List and download them through the authenticated SDK or REST API.

Reference

On this page