One agent. Every app.
This is the AI agent behind everything in Ready, Set, Cloud. I wanted one place to go whenever I need an agent, whether it’s a chat window in a dashboard or something that runs at 2 AM while I’m asleep. Three of its four types run on a shared service you call. The fourth is a build tool you run yourself.
Which agent do you need?
Answer a question or two and I’ll point you at the right page. (No JavaScript? All four answers are listed below.)
1Is a person typing to it?
2Should it act on its own, over days or weeks?
3Does the run need a record and a completion event?
runAgent.
One call, one schema-validated object, nothing stored. It’s the right fit for fanning an input across a few analyses.
See it →
The four types, compared
Picked one already? Here’s how it stacks up against the others.
definePersistentAgent hands your app the handlers, and your stack runs them under the agent’s own event source.| Chat | Task | One-shot | Persistent agent | |
|---|---|---|---|---|
| What it is | A conversation streamed to a browser | “Do this, then tell me” | One stateless call, one typed answer | A long-lived agent with a job to do |
| Started by | A person opening a socket | An API call or a Run Agent Task event | Your code calling runAgent | Your trigger rules and its own scheduled check-ins |
| Identity | The verified user | A user, or an allowlisted system | Whatever your code passes | Its own: system <type>/<agentId>, with a persona |
| Lives | One session (snapshots ~30 days) | One run | One call | Indefinitely: state carries across every run |
| Keeps | Snapshots, per-user memory | A task row with the result | Nothing | An agenda, commitments, cooldowns |
| Paces itself | No | No | No | Yes: cooldowns and human-like delays |
| Runs on | Shared runtime | Shared task Lambda | Anywhere | Your stack |
| Entry point | createAssistant | requestAgentTask, runAgentTask | runAgent | definePersistentAgent |
What people build with it
These are real patterns running across the ecosystem today. The tag tells you which type each one is built on.
The one that started it all
The AI managers in my fantasy football league weigh the offers that land on them, chase their goals week after week, follow through on what they say in the group chat, and check in three times a day. Each one is a definePersistentAgent running in the league’s own stack.
In-app assistant
A support or research chat that lives inside a dashboard. It’s a session with the app’s system prompt plus an MCP server scoped to the user’s own data with authHeader.
Content review engine
Run a draft through grammar, fact-check, and style lenses all at once. Each lens is a runAgent call with its own model and schema, and one last call stitches them together. Wrap the whole thing in a task so a retry doesn’t pay for it twice.
Nightly digest
A schedule fires Run Agent Task as a system principal and the result fans out to email or Slack. Nobody is signed in. Nobody needs to be.
Workflow step
A Step Functions state or a Lambda calls POST /agent/tasks with wait: true. If it finishes in about 25 seconds, the answer comes back inline. If it takes longer, you get a ticket now and an event later.
Ecosystem automation
Any first-party stack with events:PutEvents can ask for a run and react when it’s done. It never has to touch the agent’s table or IAM.
Copy, paste, go
Install it, then pick a tab.
npm install @readysetcloud/agentNode 22 or newer. If a Lambda doesn’t need the Strands runtime, import from ./memory or ./agency and it stays out of your bundle. Full details are on npm.
import { requestAgentTask } from '@readysetcloud/agent/memory';
// Fire and forget from any first-party Lambda. All it needs is events:PutEvents.
const { taskId } = await requestAgentTask({
principal: { type: 'system', id: 'newsletter' },
request: 'Summarize this week’s new blog comments as three bullets.',
});
// Listen for "Agent Task Completed" with this taskId.# As the signed-in caller. Waits up to ~25s for the answer.
curl -X POST "$CORE_API_URL/agent/tasks" \
-H "Authorization: Bearer $ID_TOKEN" -H "Content-Type: application/json" \
-d '{"request":"Summarize this week’s new blog comments.","wait":true}'import { Chat } from '@readysetcloud/ui/chat';
// getConnectionUrl returns the socket URL plus the bearer subprotocol (see the Chat guide).
const { sessionId } = await authed('/agent/sessions', { systemPrompt });
<Chat sessionId={sessionId} userId={user.sub} getConnectionUrl={getConnectionUrl} title="Assistant" />import { runAgent } from '@readysetcloud/agent';
import { z } from 'zod';
const { output } = await runAgent({
input: draft,
systemPrompt: 'You are a grammar and spelling reviewer.',
outputSchema: z.object({ suggestions: z.array(z.object({ span: z.string(), fix: z.string() })) }),
});import { definePersistentAgent } from '@readysetcloud/agent/agency';
export const reviewer = definePersistentAgent({
name: 'reviewer',
profile: (agentId) => loadReviewer(agentId), // persona + pacing, or null
rules: { 'Pull Request Opened': { kind: 'review', agents: ({ detail }) => detail.reviewers, request: ({ detail }) => `Review #${detail.pr}` } },
checkIn: { agents: () => listReviewerIds() },
tasks: { review: (ctx) => review(ctx), check_in: (ctx) => followUp(ctx) },
observe: async (ctx) => ({ needs: await openReviewRequests(ctx.agentId) }),
});
export const route = (event) => reviewer.route(event); // your router Lambda
export const task = (event) => reviewer.handleTask(event.detail); // your task Lambdaimport { runAgent, createAssistant, runAgentTask } from '@readysetcloud/agent'; // the runtime
import { requestAgentTask, createSession } from '@readysetcloud/agent/memory'; // Strands-free data plane
import { routeTrigger, reconcileAgenda } from '@readysetcloud/agent/agency'; // Strands-free agencyHow a request gets around
Three rules shape everything here. Identity is verified at the edge. Behavior comes from data. Results leave as events.
@readysetcloud/agent core. Chat streams back over its socket. Tasks announce their result on the bus. The steps play in order, so pause it if you want to take in the whole picture.- 1Before connecting, the app creates a session (
POST /agent/sessions) and asks for a socket URL (POST /agent/connect). - 2The browser opens
wss://with its Cognito ID token as the bearer subprotocol. - 3The inbound JWT authorizer validates the token; the runtime reads the verified
sub, loads the session, and refuses a non-owner. - 4
stream_eventframes, thencomplete, stream back over the same socket. - 5
POST /agent/tasksrecords aPENDINGtask as the verified caller (or an allowlisted system)… - 6…and emits
Run Agent Taskon the bus, then polls its own row for up to ~25 seconds. - 7First-party backends emit
Run Agent Taskdirectly, now or later throughSchedule Event. Persistent agents never come this way. They run in your stack under their own source. - 8The task Lambda claims the task row (exactly one delivery wins) and runs one turn.
- 9
Agent Task Completedgoes back on the bus for any consumer, success or failure.
Everything it can do, and where to read about it
| Capability | How | Where to read | Types |
|---|---|---|---|
| Talk to a Bedrock model | Any Bedrock model id; the default is us.amazon.nova-lite-v1:0. Pin a model per session or per call. | Reference → Environment | All |
| Remember a conversation | Strands snapshots in DynamoDB, keyed by session, so a reconnect resumes exactly where it left off. | Chat → Memory | Chat · Task |
| Remember a person across sessions | AgentCore Memory extracts facts and preferences per verified user and injects the relevant ones each turn. Chat runtime only. | Chat → Memory | Chat |
| Call first-party tools | A host registry of named tool() factories a session opts into by name. Built-ins: http_request, notebook. | Tools → First-party | All |
| Call external tools over MCP | A session lists MCP servers by URL; the host allowlists hosts and forwards an authority-minted identity header. | Tools → MCP | All |
| Return structured output | runAgent({ outputSchema }) forces the model to emit against a Zod schema and returns the validated object. | Tasks → One-shot | One-shot · Persistent (in handlers) |
| Run as a system, not a person | A system principal for ecosystem work with no owning user. Free on the internal bus, allowlisted over the API. | Tools → Principals | Task · Persistent |
| Act on events, with pacing | Trigger rules route events to agents through atomic gates (cooldowns, once-per keys) with seeded, deadline-aware delays. | Agency → Waking up | Persistent |
| Pursue goals and keep promises | Typed agendas reconciled from observed state and commitments with an explicit lifecycle, both stored per agent. | Agency → Goals | Persistent |
| Run later | A delayed task rides the bus-level Schedule Event primitive; no scheduler client or IAM role in the caller. | Tasks → Later | Task · Persistent |