Agents API
Quickstart
Run a task in a hosted sandbox, continue the conversation, then have an agent change code in a repository.
Prerequisites
- A LatentStack API key. It starts with
ls-, and you can copy it from your Account page. - A model on your tier. The examples use
bedrock/us.anthropic.claude-sonnet-5;latentcode modelslists yours. - For step 3, a GitHub token on your Agent Settings page that can read the repository.
export LS_API_KEY="ls-…"Install the SDK
The SDKs are distributed by LatentStack, not npm or PyPI. Install from the URL:
npm install https://latentstack.dev/dl/latentcode-sandbox-agents-0.1.1.tgzTypeScript runs on Node 22+, Bun and Deno, with no dependencies. The examples use top-level await, so run them as ES modules, for example with npx tsx quickstart.ts. Python needs 3.10+.
1. Run a task
This session has no repository: the agent works in an empty sandbox with a shell, Python 3 and Node.js. The agent normally asks before running shell commands. There's nothing to protect in an empty sandbox, so this example allows them.
import { LatentStack } from "@latentcode/sandbox-agents"
const client = new LatentStack({ apiKey: process.env.LS_API_KEY! })
const sessions = client.agents.sessions
const session = await sessions.create({
agent: {
model: "bedrock/us.anthropic.claude-sonnet-5",
instructions: "Answer briefly.",
// An empty sandbox has nothing to protect, so let the agent run commands without asking.
permissions: [{ action: "bash", effect: "allow" }],
},
input: "Write a Python script that prints the first 10 prime numbers, run it, and show me the output.",
})
for await (const event of sessions.events(session.id)) {
if (event.type === "tool.called") console.log("tool:", event.data?.tool)
if (event.type === "text.ended") console.log(event.data?.text)
if (event.type === "run.completed" || event.type === "run.failed") break
}tool: bash
I created primes.py, which checks divisibility up to the square root of each candidate, and ran it.
Output:
[2, 3, 5, 7, 11, 13, 17, 19, 23, 29]events() yields everything the agent does as it happens. The loop stops at run.completed, when the agent has finished the task.
2. Continue the conversation
A session keeps its conversation and its files. Send another message, and read only the new events by passing after:
const { last_seq } = await sessions.get(session.id)
await sessions.message(session.id, "Now make it print the first 20.")
for await (const event of sessions.events(session.id, { after: last_seq })) {
if (event.type === "text.ended") console.log(event.data?.text)
if (event.type === "run.completed" || event.type === "run.failed") break
}
await sessions.delete(session.id)Updated the loop to collect 20 primes and ran it.
Output:
[2, 3, 5, 7, 11, 13, 17, 19, 23, 29, 31, 37, 41, 43, 47, 53, 59, 61, 67, 71]3. Change code in a repository
Give the session a repository and a task, then download what it changed as a patch. The agent works on its own clone, and nothing is pushed.
import { writeFile } from "node:fs/promises"
import { LatentStack } from "@latentcode/sandbox-agents"
const client = new LatentStack({ apiKey: process.env.LS_API_KEY! })
const sessions = client.agents.sessions
const session = await sessions.create({
agent: {
model: "bedrock/us.anthropic.claude-sonnet-5",
instructions: "Keep changes small.",
// This task only needs the file tools. Denying the shell also means the agent never stops to ask.
permissions: [{ action: "bash", effect: "deny" }],
},
environment: { type: "repos", repos: ["acme/demo"] },
input: "Add a CONTRIBUTING.md that explains how to set up this project and run its tests, based on what you find in the repository.",
})
try {
for await (const event of sessions.events(session.id)) {
if (event.type === "text.ended") console.log(event.data?.text)
if (event.type === "run.completed" || event.type === "run.failed") break
}
const patch = await sessions.artifact(session.id)
await writeFile("contributing.patch", patch) // apply with: git apply contributing.patch
console.log(patch) // a unified diff adding CONTRIBUTING.md
} finally {
await sessions.delete(session.id)
}The patch is a unified diff against the commit the agent started from. Apply it with git apply contributing.patch, or open a pull request with it.
Next steps
- Configuring agents: model, instructions and permissions.
- Run and continue: steering, queueing and cancelling.
- Examples: complete programs to start from.