NodeAgent's durable runtime is provider-neutral. The core frame runner does not
know about Convex, Postgres, DynamoDB, SQLite, SQS, Step Functions, or any other
database or queue. It depends on ports in
durableRuntime.ts, and
apps supply adapters.
npm run nodeagent:frame:smoke
npm run nodeagent:durable:smoke
npm run nodeagent:sqlite:smoke
npm run omnigent:nodeagent:smoke
npm run examples:guidance:smoke
npm run prepushnodeagent:durable:smoke uses the in-memory adapter to prove:
- a queued
ReasoningFramecan be scheduled and run - worker leases fence active jobs
- stale leases can be reclaimed with a higher fencing token
- the step journal is idempotent
- a duplicate run replays the stored receipt instead of executing again
- the verifier receipt is stored as an artifact and can be loaded later
The JSON receipt is written to
docs/eval/nodeagent-durable-smoke.json.
nodeagent:sqlite:smoke uses the real SQLite adapter in
examples/adapters/sqlite-local/sqliteDurableRuntime.ts.
It creates a temporary SQLite database, runs a durable frame, reopens through a
second runtime, and proves duplicate execution replays the persisted receipt.
| Port | Required behavior |
|---|---|
DurableJobStore |
create, update, and list runnable jobs by status, priority, and runAfter |
DurableFrameStore |
persist frame status, evidence, and receipt references |
LeaseStore |
claim, release, expire, and fence worker leases |
StepJournal |
writeOnce idempotency for frame/tool receipts |
DurableScheduler |
enqueue frames and return the next runnable job |
ArtifactStore |
store JSON receipts and result references |
ToolRuntime |
run typed tools behind policy context |
PolicyContext |
carry auth, tenant, scope, egress, and spend boundaries |
When porting NodeAgent into another repo, implement adapters behind the ports instead of changing the frame runner:
- Store jobs, frames, leases, and journal keys transactionally.
- Make
StepJournal.writeOnceatomic. - Make lease claim atomic and attach a monotonic fencing token.
- Store receipts/artifacts separately from prompt transcripts.
- Keep app-specific writes inside tools; do not mutate backend state directly from the frame runner.
- Add provider-specific smokes for resume, stale lease reclaim, duplicate journal replay, and one real app tool.
| Target | Job/frame/lease/journal | Scheduler | Artifacts |
|---|---|---|---|
| Convex | Convex tables with indexed ids and atomic mutations | Convex scheduled functions / action workers | Convex storage or object store |
| AWS | DynamoDB conditional writes | SQS, EventBridge, or Step Functions | S3 |
| Postgres | tables with unique journal keys and advisory/row locks | pg-boss, graphile-worker, or external queue | S3/R2/local object store |
| SQLite/local | SQLite tables with unique keys | local worker loop | filesystem |
| Cloudflare | D1 or Durable Objects | Queues / Workflows | R2 |
If a provider requires edits to runReasoningFrame or runDurableReasoningFrame,
the adapter is leaking provider concerns into NodeAgent core.
Use these folders when adapting NodeAgent into another repo:
examples/adapters: provider adapter guidance for SQLite/local, Convex, AWS DynamoDB/SQS/S3, Postgres, and Cloudflare D1/R2/Queues.examples/apps: sample app maps for a minimal portable agent, AWS-Hackathon/VisualLabs, local design dashboards, and video agent pipelines.
Every provider/app README must include credentials, spin-up commands, done criteria, and coding-agent handoff guidance. The structural check is:
npm run examples:guidance:smokeThe guided CLI wraps the same checks with Commander and Clack:
npm run nodeagent -- doctor
npm run nodeagent -- happy-path
npm run nodeagent -- smoke
npm run nodeagent -- adapters setup sqlite-local --runThe timed happy path writes:
npm run nodeagent:happy-path:smoke
# -> docs/eval/nodeagent-happy-path-speed.json