Use the provided Pi harness
Submit a task and consume progress from the agent loop provided by Assemble.
The provided harness uses Pi's four standard tools: read, bash, edit, and write. Their operations use the VM's writable /workspace mount, shared with the file API and SSH processes. Model calls run in the service, using the operator's configured model credentials.
Use an operator-issued product key to access the hosted API. The service operator configures the model credentials and default model for the provided harness.
Submit a task
Use the client setup from the quickstart:
const session = await client.sessions.open({ name: "provided-agent-demo" });
const controller = new AbortController();
for await (const event of session.agent.run(
{
message: "Write a short project plan to plan.md, then read it back.",
},
{ signal: controller.signal },
)) {
if (event.type === "text") process.stdout.write(event.delta);
if (event.type === "tool_start") console.log(`\nUsing ${event.tool}`);
if (event.type === "tool_end")
console.log(`${event.tool}: ${event.isError ? "failed" : "finished"}`);
if (event.type === "error") throw new Error(`${event.code}: ${event.message}`);
}
console.log(new TextDecoder().decode(await session.files.read("plan.md")));
await session.pause();The service operator configures the default provider and model. To override them, supply both fields together:
session.agent.run({
message: "Summarize the project.",
provider: "openai",
model: "gpt-4.1",
});Consume the returned iterator as in the first example. The service must have a key for the selected provider, and the model must exist in the installed Pi registry. Supported API-key providers are OpenAI, Anthropic, Google, Mistral, OpenRouter, Groq, Cerebras, xAI, and DeepSeek. The model identifier above is illustrative; choose one available to your operator's account.
Events
| Event | Fields | Meaning |
|---|---|---|
text | delta | A piece of assistant text |
tool_start | tool | A session tool has started |
tool_end | tool, isError | That tool has finished |
done | — | The request completed successfully |
error | code, message | The request failed or was stopped |
These events arrive as newline-delimited JSON. Agent events are streamed for this request; there is no persisted agent-event cursor or reconnect endpoint.
Fresh conversation per request
Each call starts a fresh, memory-only conversation. Session files persist independently. Include the context needed for the new task in its message or in files the agent can read.
Version 1 performs ordinary filesystem mutations. Stopping a task does not undo its file changes. The same durability and flush behavior applies across harness modes.
The initial interface has no follow-up-message endpoint or user-question interrupt flow. It does not load the service host's skills, extensions, authentication files, or saved conversations.
Cancellation and limits
Call controller.abort() to stop the request. Disconnecting this agent stream also requests cancellation of its active command. The API sets a 15-minute task deadline; individual commands have a maximum one-hour timeout.
Bash text sent to the model is bounded and includes a truncation notice when needed. Pending agent output is capped at 1 MiB to stop an unbounded queue when the consumer is slow. For large results, ask the agent to write an output file and read it through the file API.