Agent SDK (@cef-ai/agent-sdk)
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". |