Workflows
Build a workflow in your application by combining agent prompts, commands, and files. Use Tangle Workflows for saved workflows with schedules, connected apps, and human decisions.
Compose agent steps
Set TANGLE_API_KEY and TANGLE_SANDBOX_ID to a running sandbox containing your project.
Install the TypeScript SDK.
This example inspects the project, writes a report, and checks that the file exists. Both prompts share a session, so the second step can use the first step’s findings.
import { Sandbox } from "@tangle-network/sandbox";
const apiKey = process.env.TANGLE_API_KEY;
const sandboxId = process.env.TANGLE_SANDBOX_ID;
if (!apiKey || !sandboxId) {
throw new Error("Set TANGLE_API_KEY and TANGLE_SANDBOX_ID");
}
const client = new Sandbox({
apiKey, baseUrl: "https://sandbox.tangle.tools",
});
const box = await client.get(sandboxId);
if (!box) throw new Error("Sandbox not found");
await box.waitFor("running");
const sessionId = crypto.randomUUID();
const steps = [
"Inspect this project's files and explain its main packages. Do not edit files.",
"Write your findings to /workspace/project-overview.md. Include the paths you inspected.",
];
for (const prompt of steps) {
const result = await box.prompt(prompt, { sessionId });
console.log(result.status, result.response);
if (!result.success) throw new Error(result.error ?? result.status);
}
const check = await box.exec("test -s /workspace/project-overview.md");
if (check.exitCode !== 0) throw new Error("The report was not written");
console.log(await box.read("/workspace/project-overview.md"));The sandbox stays available so you can read or continue the work. A failed or waiting agent stops the sequence; handle its result before advancing.
For independent tasks, use parallel agents or batches. For work that must survive your application’s disconnect, use durable sessions. Save each step’s sandbox, session, and turn IDs in your job record before dispatching.
Run a saved workflow
Create and enable a workflow in Tangle Workflows.
Set TANGLE_WORKFLOW_ID to its ID and TANGLE_API_KEY to your API key.
Python examples require pip install httpx.
The example starts a workflow with no required inputs and reads its progress.
For workflows with inputs, replace inputs: {} with their input names and values.
import { setTimeout } from "node:timers/promises";
const apiKey = process.env.TANGLE_API_KEY;
const workflowId = process.env.TANGLE_WORKFLOW_ID;
if (!apiKey || !workflowId) {
throw new Error("Set TANGLE_API_KEY and TANGLE_WORKFLOW_ID");
}
const url = "https://id.tangle.tools/api/v1/workflows/"
+ encodeURIComponent(workflowId);
const headers = {
Authorization: "Bearer " + apiKey, "Content-Type": "application/json",
};
const response = await fetch(url + "/run", {
method: "POST", headers, body: JSON.stringify({ inputs: {} }),
signal: AbortSignal.timeout(30_000),
});
if (!response.ok) throw new Error(await response.text());
const { data: { runId } } = await response.json();
console.log("Run ID:", runId);
const runUrl = url + "/runs/" + encodeURIComponent(runId);
for (let attempt = 0; attempt < 60; attempt++) {
const response = await fetch(runUrl, {
headers, signal: AbortSignal.timeout(30_000),
});
if (!response.ok) throw new Error(await response.text());
const { data: run } = await response.json();
console.log(run.status);
if (["succeeded", "failed", "cancelled", "waiting"].includes(run.status)) {
console.log(run.actionResults);
break;
}
await setTimeout(2_000);
}
console.log("https://id.tangle.tools/app/workflows/" + workflowId);Keep the printed run ID to retrieve the same run later.
The workflow continues if this client stops polling.
Submitting another POST /run creates another run.
waiting means the workflow needs a human decision; open its page to respond.
succeeded, failed, and cancelled are terminal states.
Saved workflows use https://id.tangle.tools/api/v1/workflows.
Sandbox commands and sessions use https://sandbox.tangle.tools/v1/sandboxes.