The Thread Model
A thread is an isolated conversation history. The agent sees the full entry log of a thread on every call to it, and nothing from other threads. You compose threads deliberately to control what context the agent has at each point in a task.
This is the primary tool for structuring complex multi-step work.
The execution thread
Every script runs on an execution thread. Calls with no thread option share it
automatically — the agent carries context across them without any explicit management.
const r1 = await axon.request("what's the current sprint status?")
const r2 = await axon.request("which issues are blocking the release?")
const r3 = await axon.request("draft a status update for the team")
// agent sees r1 and r2 when producing r3
The execution thread is implicit. You don't name it, you don't pass it anywhere. It's the natural context for a script that does one coherent piece of work.
Named threads
Pass a string name to create an isolated branch. The agent on that branch has no context from the execution thread, and vice versa.
const r1 = await axon.request("reviewing the codebase now") // execution thread
const research = await axon.request({
prompt: "analyse the error in this stack trace: ...",
thread: "sentry-debug", // isolated — agent has no context from r1
})
// bring the result back
const r2 = await axon.request(
`the debug analysis found: ${research.text}. incorporate this into the review.`
// no thread: — back on the execution thread, agent sees r1
)
Name threads for what they're doing. The name is stable within a session — any subsequent call with the same name continues the same conversation.
Thread handles
When you make multiple calls to the same named thread, a handle avoids repeating the name:
const debug = axon.thread("sentry-debug")
await debug.request("what's causing the null reference on line 47?")
await debug.request("is this related to the auth refactor last week?")
await debug.request("write a minimal reproduction case")
axon.thread(name) returns a handle with .request() and .stream() — same signatures
as the top-level calls, minus the thread field. Use handles whenever you're making more
than one call to the same thread.
Parallel branches
Independent sub-tasks can run concurrently on separate threads. Results come back together and get synthesised on the main thread.
const [securityAudit, perfAudit] = await Promise.all([
axon.request({
prompt: "audit this codebase for security vulnerabilities",
thread: "audit-security",
}),
axon.request({
prompt: "profile the hot paths and identify performance bottlenecks",
thread: "audit-perf",
}),
])
const summary = await axon.request(
`two audits just completed:\n\n` +
`Security: ${securityAudit.text}\n\n` +
`Performance: ${perfAudit.text}\n\n` +
`Write an executive summary with prioritised recommendations.`
)
Each branch runs the full agent loop independently. The final synthesis call has no context from either branch — just the results you explicitly inject via the prompt string.
Persistent threads
Named threads persist across script runs within a session. A thread named "project-alpha"
on Monday is still there on Tuesday, with full prior context intact.
// Monday
const project = axon.thread("project-alpha")
await project.request("we've decided to use a document model for the user store. document rationale.")
// Tuesday — same session, full history available
const project = axon.thread("project-alpha")
await project.request("what was the rationale for the database decision?")
// agent sees Monday's conversation and answers from it
Use persistent threads for ongoing projects where continuity across multiple work sessions matters. The thread name is the key — keep it stable and specific enough that it doesn't collide with unrelated work.
When to use each pattern
Execution thread — one coherent task with a natural progression. The agent should carry full context across every step.
Named side thread — a sub-task that would pollute the main context if run inline. Research, debugging, fetching reference material. Run it separately, inject the result.
Thread handle — whenever you're making more than two calls to a named thread. Cleaner
than repeating the name, and gives you .entries for the full history.
Parallel branches — independent tasks with no dependency between them. Both need the same agent, neither needs the other's context during execution. Merge at the end.
Persistent thread — ongoing work that spans multiple script runs or multiple days. The agent's memory of prior decisions is load-bearing for the current task.
What threads are not
A thread is not a record of external events. If a GitHub issue arrives via webhook, the issue content goes in the prompt — not the thread. The thread is the agent's reasoning about that issue, not the issue itself.
A thread is also not a global log. Each thread is a narrow, purposeful slice of working memory. An agent with twenty threads covering twenty different topics doesn't have a single tangled context — it has twenty clean ones.