Neutron Agents
File-based agents: a definition, a system prompt, and typed tools in a directory. Composes the AI SDK with the Workflow SDK so an agent IS a durable workflow — it can pause for human approval, survive a restart, and resume exactly where it stopped.
File-based agents that plan, act, and survive restarts.
An agent is a folder, not a framework config.
Most agent frameworks make you assemble the agent in code — register tools, thread a system prompt, wire a loop. Neutron Agents uses the same file conventions as the rest of Neutron. An agent is a directory: agent.ts defines it, instructions.md is the always-on system prompt, and every file under tools/ is one typed tool. The loader reads the directory, merges the tools files over the inline ones, and hands you a runnable agent. No registry, no wiring.
Teploy Ship — the autonomous coding agent that turns a GitHub issue into a pull request — is built on Neutron Agents. This is the authoring model behind a shipping product, not a demo.
review-agent/
├── agent.ts # defineAgent({...}) — model, budget, inline tools
├── instructions.md # always-on system prompt
└── tools/
├── read-file.ts # default-exports a typed Tool
└── open-pr.ts # one file, one toolimport { defineAgent } from "@neutron-build/agents";
import { anthropic } from "@neutron-build/ai/anthropic";
export default defineAgent({
name: "review-agent",
model: anthropic("claude-sonnet-4-5"),
maxSteps: 8, // model-call budget per turn
});agent.ts, instructions.md, and one file per tool under tools/. loadAgent(dir) reads the directory and hands back a runnable, name-deduped agent.execute. Types flow from the schema into the handler, so a tool call is checked, not stringly-typed.agentWorkflow and every model round becomes a recorded step. The run survives crashes, deploys, and weeks of waiting.needsApproval and the run parks on a decision instead of executing. Deliver the approval later and it resumes, never re-calling the model.defineTeam, pipeline, and roundtrip compose multiple agents into one turn — hand-offs and multi-member runs without a bespoke orchestrator.LocalExecutor or a SandboxExecutor lets an agent run commands in a controlled environment — the mechanism behind coding agents.Run a turn. Or make it durable.
The simple path is runTurn — instructions plus tools through the AI SDK's multi-step loop, back in one call. The durable path wraps the same agent as a workflow, so a turn that pauses for approval or crashes mid-flight picks up exactly where it left off.
import { loadAgent, runTurn } from "@neutron-build/agents";
import { agentWorkflow } from "@neutron-build/agents/durable";
import { executeRun, MemoryEventStore } from "@neutron-build/workflow";
const agent = await loadAgent("./review-agent");
// Ephemeral: one turn, back in one call.
const result = await runTurn(agent, { input: "Review PR #482" });
console.log(result.text);
// Durable: the same agent as an event-sourced workflow.
const wf = agentWorkflow(agent);
await executeRun({
workflow: wf,
runId: "review-482",
store: new MemoryEventStore(), // NucleusEventStore in production
input: { input: "Review PR #482" },
});Approval that parks the run, not a thread.
A tool with side effects — open a pull request, delete a resource, spend money — can require approval. When the model calls it, the durable run suspends and waits. No process stays alive. Deliver the decision minutes or days later and the run resumes, feeding the outcome back to the model without re-running a single earlier step.
import { tool, jsonSchema } from "@neutron-build/ai";
export default tool({
name: "open_pr",
description: "Open a pull request from the working branch.",
inputSchema: jsonSchema<{ title: string; body: string }>({
type: "object",
properties: { title: { type: "string" }, body: { type: "string" } },
required: ["title", "body"],
}),
needsApproval: true, // durable run suspends here, waits for a decision
execute: async ({ title, body }) => openPullRequest(title, body),
});What it's for
Autonomous coding agents that read a repo, run commands, and open pull requests — exactly what Teploy Ship does. Long-running assistants that pause for a human on anything irreversible. Scheduled agents that wake on an interval and do a bounded piece of work. Multi-agent pipelines where one agent's output is another's input. Anything where "call the model in a loop" needs to also mean "and survive the process dying."
Why file-based?
Because conventions beat configuration once you have more than one agent. A directory you can read top-to-bottom is easier to review, diff, and reason about than an agent assembled across a codebase. It mirrors how the rest of Neutron works — routes, tools, schedules are all files — so there's one mental model, not five.
Part of a bigger system
Neutron Agents sits between two SDKs: it uses Neutron AI for the model calls, tools, and streaming, and Neutron Workflow for durability. An agent turn is a workflow step; approvals are workflow suspensions; scheduled agents are parked runs the scheduler wakes. Same contract, same errors, same Nucleus database as everything else in the stack.