Skip to content

Agent SDK (@cef-ai/agent-sdk)

Terminal window
npm install @cef-ai/agent-sdk@5.8.0
Import Contains Used in
@cef-ai/agent-sdk Decorators and types (Context, Event, …). Agent source.
@cef-ai/agent-sdk/config defineAgent, defineWorkflow, isWorkflow, config types. cef.config.ts.
@cef-ai/agent-sdk/workflow The workflow engine: WorkflowRunner, graph helpers, WORKFLOW_RUNNER_ENTRY. Tools that inspect or test workflows.
@cef-ai/agent-sdk/workflow/runner The runner module itself; the default entry of every workflow. defineWorkflow({ runner }).
@cef-ai/agent-sdk/runtime The in-bundle implementation of ctx. Wired in by cef build; never imported by agents.

Decorators need "experimentalDecorators": true in tsconfig.json.

Decorators

Decorator Target Signature / effect
@Engagement({ id, goal }) class Names an engagement.
@OnEvent(type) method (event: Event<P>, ctx: Context) => Promise<void>. type must be a string literal. A second handler for the same type is ignored with a warning.
@OnStart / @OnStart() method Runs once when the Job starts.
@OnClose / @OnClose() method (ctx: Context, reason: OnCloseReason).
@Condition(expr) class CEL selection expression. Repeatable; ANDed.
@Priority(n) class Lower value wins. Last application wins.
@Weight(n) class Split within a priority tier.
@Limit(n, per) class per: "day", "connection/day", "connection/month".
@Params(values) class Param values for the engagement; repeated applications merge.

OnCloseReason is "revoked" | "idle_timeout" | "closed_by_agent" | "failed".

Event<P>

Field Type Notes
type string
payload P
timestamp string ISO 8601, set by the vault.
context string The stream key.
role "source" | "user" | "agent"
from string? Publisher identity.
eventId string?
parents string[]? Events this one was caused by.

Context

Member Type
cubby(alias, attribution?) CubbyHandle: query<T>(sql, params?) → Promise<T[]>, exec(sql, params?) → Promise<{ changes, lastInsertRowid }>. The cubby belongs to the Agent Service. attribution.nodeId names the workflow step making the call.
models KnownModels & Record<string, ModelHandle>. ModelHandle<I, O>: infer(input: I) → Promise<O>, stream(input: I) → AsyncIterable<O> (yields the complete output once).
vault.publish(type, payload, opts?) opts: PublishOptions = { target?, title?, description?, correlation? }.
vault.objects upload(path, data: Uint8Array, { contentType? }), get(path), head(path), presignedUrl(path, { ttlSeconds? }), list({ prefix? }). No delete.
memory MemoryHandle: upsert(record), update(id, { title?, body? }), setPrivacy(id, privacy), delete(id), relation(edge), search(match, { limit? }), get(id), neighbours(id, { limit? }), countByType().
self { agentId?, vaultId?, scope?, context?, jobId?, taskId? }, frozen.
settings Readonly<Record<string, unknown>>.
params Readonly<Record<string, unknown>>.
close(reason?) Promise<void>.

MemoryRecordInput: { id, type, title?, body?, scope, privacy }. MemoryRelationInput: { in, out, type, scope, privacy }. MemoryPrivacy: "public" | "internal" | "private" | "restricted", required on every write. neighbours returns MemoryNeighbourRow: { id, type, title, scope, privacy, edgeType }.

KnownEventTypes and KnownModels are interfaces filled by cef typegen for typed @OnEvent, vault.publish, and models.

defineAgent(config)

Returns the config unchanged, with its literal types. Fields of AgentConfig:

Field Type Default
id string required; the alias
version string required
alias string id
agentServicePubkey string —
source string —
card { name, description, iconUrl?, capabilities? } —
entry string one of entry / engagements
engagements { id, entry, goal?, condition?, priority?, weight?, limit?: { n, per }, params?, enabled? }[]
requiredScopes string[] ["default"]
idleTimeout duration string "30m"; "0s" disables
models Record<string, string> —
params Record<string, ParamDecl> —
settings SettingDecl[] —
cubbies CubbyDecl[] = { alias, migrations? }[] —
schedules ScheduleDecl[] —
widgets WidgetDecl[] —
eventSchemas Record<string, JSONSchema> —
uses Record<string, string> Peer agents, typed by cef typegen.
agents AgentConfig[] Several agents in one config.
kind "internal" | "external" | "workflow" A classification; dispatch does not depend on it.
Type Shape
ParamDecl { type: "number" | "string" | "boolean" | "modelAlias", default, min?, max?, enum? }
SettingDecl { key, type: "string" | "number" | "boolean" | "url" | "secret", required?, label?, description?, default? }
ScheduleDecl { id, cron, timezone?, eventType, payload? }
WidgetDecl { id, name?, description?, cubbyAlias?, kind?, config?, queries?, events?, dir, entry }; a query is { id, label?, sql?, cubby?, tool?, limit?, timeoutMs? }

Guides: Write an agent, Build a widget.

defineWorkflow(spec)

Declares a workflow and returns an AgentConfig, so a workflow builds, pushes, deploys, and connects like any agent.

import { defineWorkflow } from "@cef-ai/agent-sdk/config";
export default defineWorkflow({
id: "triage",
version: "0.1.0",
goal: "Classify incoming requests",
models: { llm: "https://cdn.ddc-dragon.com/<bucket>/models/<name>/<version>/model.json" },
nodes: [
{ id: "start", kind: "trigger" },
{ id: "classify", kind: "model", params: { alias: "llm", input: { prompt: "={{ $json.text }}" } } },
{ id: "done", kind: "output" },
],
edges: [
{ from: "start", to: "classify" },
{ from: "classify", to: "done" },
],
});
WorkflowSpec field Meaning
id, version As for an agent.
goal Description; also the default card description.
nodes WorkflowNode[]: { id, kind, use?, emit?, params?, label?, question?, position? }.
edges { from, to, when?, loop? }; from/to must be node ids (checked by the type). when: { field, op, value? }, op one of eq, ne, gt, gte, lt, lte, contains, exists. loop: { max, counter, exhausted? }.
models, cubbies, schedules, card, idleTimeout As for an agent. idleTimeout defaults to "30m".
runner Runner entry. Defaults to "@cef-ai/agent-sdk/workflow/runner".

Node kinds: trigger, agent, branch, join, publish, remember, relate, recall, transform, code, human, model, cubbyQuery, cubbyExec, action, output, split, aggregate. Step semantics: Steps.

defineWorkflow throws at config load (that is, at cef build) when two nodes share an id, a kind is unknown, an agent node has no use, a model node names an alias not in models, there is no trigger, an edge names an unknown node, a schedule id is not a trigger with params.mode: "schedule", a non-trigger node has no incoming edge, or the runner’s own validation finds a fatal problem.

The returned config uses the runner as its entry, adds a runs cubby for the runner’s state, and carries the graph as the graph param. A deployment can override that param.

isWorkflow(manifest)

Returns true when a manifest carries a non-empty graph param, which is what makes an agent a workflow. WORKFLOW_GRAPH_PARAM is "graph".

@cef-ai/agent-sdk/workflow

Export Use
WorkflowRunner The engine class every workflow runs.
WORKFLOW_RUNNER_ENTRY "@cef-ai/agent-sdk/workflow/runner".
validate(doc), isFatal(issue) The runner’s graph validation.
readContinuation(raw) Which step, pass, and item an answer was for.
readResultSpec, narrowResult, RESULT_TYPES A workflow’s declared Result, used by evaluations.
STEP_ASK_EVENT "workflow.step".