TypeScript authoring helpers
Declare providers, agents and tools, then start a session with automatic initialization.
defineProvider and defineAgent keep configuration in your application code.
Neither makes a network request when declared. Agent actions initialize their
dependencies automatically, so there is no setup script or readiness promise to coordinate.
Define a provider and agent
import { defineAgent, defineProvider } from "@trycereal/sdk"
export const primary = defineProvider({
slug: "primary",
type: "anthropic",
secret: process.env.ANTHROPIC_API_KEY
})
export const assistant = defineAgent({
agent: {
slug: "assistant",
model: { provider: primary, model: "claude-sonnet-4.6" },
system: "Help the customer."
}
})
const session = await assistant.sessions.start({ message: "Hello" })Set CEREAL_API_KEY to a credential with read, data and control in your
target environment. The key selects the organization and environment. An agent
without application tool or hook handlers needs no public application URL.
A provider object can be shared by agents and used in fallback model entries.
The stored agent definition contains its slug; provider credentials stay out of
that document. A string model.provider refers to an existing provider. Omitting
a provider's secret preserves the stored credential. Providers
explains adapter types and reachable model endpoints.
One initialization lifecycle
The first session or approval action initializes providers, referenced sub-agents and the agent. Concurrent actions share that work. A failed initialization rejects the action, and the next action can retry. An unchanged definition reuses its version.
await assistant.init() // optional early initialization during app startupinit() is idempotent within the process. sessions.stream() initializes when
its iterable is consumed. Initialization registers a sandbox specification but
does not wait for its image build; a sandbox-backed agent can still return
AgentNotReadyError while Cereal builds the image.
| Member | Behavior |
|---|---|
definition() | Returns the serialized definition without a network request |
init() | Initializes dependencies and registers the agent early |
sessions.start/send/stream/streamToken/children | Initializes as needed, then performs the session action |
sessions.feedback/evaluations/evaluate | Initializes as needed, then manages evaluation data |
approvals.pending/allow/deny | Reads or answers tool decisions after initialization |
authorizations.pending | Reads pending OAuth authorizations after initialization |
fetch(request) / handlers | Verifies and dispatches incoming tool and hook requests |
close() | Stops outbound channels owned by this agent and its referenced agents |
Configure the application once
Use environment variables, or call configureCereal at application startup:
import { configureCereal } from "@trycereal/sdk"
configureCereal({
apiKey: process.env.CEREAL_API_KEY,
publicUrl: process.env.CEREAL_PUBLIC_URL
})publicUrl is your application's public HTTPS origin. It is an application setting,
separate from the agent definition and the model provider's endpoint. The agent uses
the shared runtime without receiving a client argument. Configuration is captured
on first use; a later configuration change does not move an initialized agent to another tenant.
With NODE_ENV=development, local tools automatically use outbound channels.
With NODE_ENV=production, they use HTTP callbacks; set CEREAL_PUBLIC_URL. The same agent and session code works in both environments.
See local development.
Tools, hooks and frameworks
tool() accepts a name, description, Standard Schema input validator and handler.
Handlers receive validated input and verified session identity, metadata, connection,
claims, cancellation signal and a sandbox handle when available. Authorize access to
your application's resources inside the tool. See tool schemas.
hooks.onSessionEvent receives event deliveries. hooks.onToolCall decides allow,
deny or ask. hooks.onSandboxPrepare participates in sandbox preparation. Their
configuration is registered with the code that implements them.
Serve agent.fetch or agent.handlers using framework integrations.
A fresh serving process learns its verification tenant from the API key before
handling signed requests. There is no separate tenant setup step.
Pass defined agents by reference in subagents; their dependencies initialize first.
Referenced agents receive separate paths, served through the parent's handlers.
For several independent agents, use createAgentRouter.
sync() remains available for deployment tooling that needs explicit registration
results or route overrides. Ordinary application code uses init() or an agent action.
Direct API clients operate on explicit resources and do not
initialize local definitions.