Durable workflows (Vercel Workflow)
Long-running assistants and chat backends often need durable execution: if a function restarts, the same logical run should resume, tool calls should retry safely, and each step should be observable. @github-tools/sdk supports this through the Vercel Workflow SDK and the @github-tools/sdk/workflow entry point.
What “durable” means here
"use workflow"— Your orchestration function is a workflow: the platform can pause, resume, and replay it across failures and deploys."use step"— Each GitHub tool implementation runs inside a named, module-level step. Every tool call is a durable step with retries and full Node.js access in the workflow runtime.createDurableGithubAgent— Wraps the same GitHub tools in aDurableAgentso LLM turns and tool invocations participate in that durable model (not just rawgenerateTextin a plain serverless handler).
Together, this is the recommended pattern when you build Nuxt, Next.js, or other apps that expose a chat or agent API and must not lose progress on timeout or cold start.
Install optional workflow dependencies
Durable agents are optional. Add them only when you use @github-tools/sdk/workflow:
pnpm add workflow @workflow/ai
npm install workflow @workflow/ai
yarn add workflow @workflow/ai
bun add workflow @workflow/ai
You still need ai, zod, and @github-tools/sdk as documented in Installation.
Minimal durable workflow
createDurableGithubAgent returns a DurableGithubAgent with two methods:
.stream()— real-time output to aWritableStream(for chat UIs).generate()— non-streaming, returns the full text response (for bots, background jobs, webhooks)
Both methods execute each tool call as a durable workflow step with automatic retries.
Streaming (chat UI)
import { createDurableGithubAgent } from '@github-tools/sdk/workflow'
import { getWritable } from 'workflow'
import type { ModelMessage, UIMessageChunk } from 'ai'
export async function durableGithubChat(
messages: ModelMessage[],
token: string,
model: string
) {
'use workflow'
const writable = getWritable<UIMessageChunk>()
const agent = createDurableGithubAgent({
model,
token,
preset: 'code-review',
})
await agent.stream({ messages, writable })
}
Non-streaming (bot / background job)
For non-streaming use cases (bots, webhooks, background jobs), use createGithubAgent inside a "use step" function. This gives you the full tool loop while keeping the step durable:
import { createGithubAgent } from '@github-tools/sdk'
async function runAgentTurn(prompt: string) {
'use step'
const agent = createGithubAgent({
model: 'anthropic/claude-sonnet-4.6',
preset: 'code-review',
requireApproval: false,
})
const { text } = await agent.generate({ prompt })
return text
}
export async function reviewWorkflow(prompt: string) {
'use workflow'
await runAgentTurn(prompt)
}
Wire these workflows from an API route or server handler provided by your framework’s Workflow integration (for example a Nuxt server route that starts the run and streams results to the client).
examples/pr-review-agent/ starter — a ~60-line PR review agent with multi-turn durable sessions and evlog AI observability.AI assistant prompt (durable workflow)
Integrate a durable GitHub assistant using @github-tools/sdk/workflow and the Vercel Workflow SDK in this repo.
- Add dependencies: workflow, @workflow/ai (and existing @github-tools/sdk, ai, zod)
- Define an async function with "use workflow" using createDurableGithubAgent, getWritable from "workflow", and agent.stream with ModelMessage[] and UIMessageChunk
- Document that requireApproval is ignored by DurableAgent: https://github-tools.com/guide/durable-workflows
- Match this framework’s workflow layout (e.g. server/workflows in Nuxt)
Presets and options
All presets (code-review, issue-triage, repo-explorer, ci-ops, maintainer) work with createDurableGithubAgent. Options mirror createGithubAgent for model, token, preset, instructions, and temperature, with additional pass-through for DurableAgentOptions fields like experimental_telemetry, onStepFinish, onFinish, and prepareStep.
Approval control and durable agents
requireApproval is accepted for forward compatibility but is currently ignored by DurableAgent. The Workflow SDK does not yet support interactive tool approval the same way as ToolLoopAgent — tools run as soon as the model invokes them.When you need human-in-the-loop approvals on writes, use createGithubAgent (standard AI SDK agent) instead, or gate dangerous operations outside the model (manual checks, feature flags, separate endpoints).Standard agents vs durable agents
createGithubAgent | createDurableGithubAgent | |
|---|---|---|
| Import | @github-tools/sdk | @github-tools/sdk/workflow |
| Runtime | In-process ToolLoopAgent | DurableGithubAgent inside "use workflow" |
| Methods | .generate(), .stream() | .generate(), .stream() |
| Retries / resume | You handle | Workflow-managed durable steps |
requireApproval | Supported | Ignored today (see above) |
Durable steps on every tool
Even if you do not use createDurableGithubAgent, spreading createGithubTools() inside a workflow still benefits from per-tool "use step" boundaries when the AI SDK executes tools — each GitHub operation remains a proper workflow step. The durable agent entry point additionally durably wraps the LLM loop itself.