Capability Patterns
A Capability is an atomic tool with encapsulated context: it exposes a simple Input/Output contract to callers while hiding internal implementation - services, connections, state. Deterministic by default, composable everywhere.
Simple - data in, data out
The base case: an input schema, an output schema, and execution logic.
const FormatText = Capability('FormatText', 'Formats text in various styles')
.Input(z.object({
text: z.string().describe('Text to format'),
style: z.enum(['upper', 'lower', 'title']).describe('Format style'),
}))
.Output(z.object({ formatted: z.string().describe('Formatted result') }))
.Execute(async (ctx) => {
const { text, style } = ctx.Input;
const formatted = style === 'upper'
? text.toUpperCase()
: style === 'lower'
? text.toLowerCase()
: text.replace(/\b\w/g, (c) => c.toUpperCase());
return { formatted };
});
With services (IoC)
Declare dependencies with .Services(); they resolve from the IoC container at
execution and are reachable as ctx.Services. Declaring services is an act of
Integration - the Capability joins the dependency graph without hard-wiring how
those services are constructed.
const UserLookup = Capability('UserLookup', 'Looks up a user, cached')
.Input(z.object({ id: z.string() }))
.Output(z.object({ name: z.string() }))
.Services(async (ctx, ioc) => ({
db: await ioc.Resolve<Database>(ioc.Symbol('Database')),
cache: await ioc.Resolve<Cache>(ioc.Symbol('Cache')),
}))
.Execute(async (ctx) => {
const cached = await ctx.Services.cache.get(ctx.Input.id);
return cached ?? await ctx.Services.db.findUser(ctx.Input.id);
});
With self-governance
Attach a guardrail with .Governance() and it travels with the Capability
everywhere - it runs at the Capability level, independently of whatever hosts it
(the no-aggregation rule).
const SecretRead = Capability('SecretRead', 'Reads a secret')
.Input(z.object({ key: z.string() }))
.Output(z.object({ value: z.string() }))
.Governance(TrustLevelPolicy('high')) // only high-trust initiators
.Execute(async (ctx) => ({ value: await vault.get(ctx.Input.key) }));
Output hooks and lifecycle handles
Not every Capability maps input to a value. Some open a resource and return a handle of typed methods - the caller interacts with what's inside without knowing the implementation; the lifecycle stays in the Capability.
const Transaction = Capability('Transaction', 'Managed DB transaction')
.Input(z.object({ poolKey: z.string() }))
.Output(z.custom<TransactionHandle>())
.Execute(async (ctx) => {
const client = await getPool(ctx.Input.poolKey).connect();
await client.query('BEGIN');
return {
Query: (sql: string, p: unknown[]) => client.query(sql, p),
Commit: async () => {
await client.query('COMMIT');
client.release();
},
Rollback: async () => {
await client.query('ROLLBACK');
client.release();
},
};
});
The same shape powers long-lived resources - an embedded server with
Start/Stop/Send, a deployment with Scale/Pause/Resume/Destroy. The
handle IS the contract.
Composition - Capabilities using Capabilities
A Capability can compose other Capabilities (and wrap them with cross-cutting behavior like monitoring) without the inner ones knowing. Each stays whole.
With agents
A Capability can compose Agents via .Agents({}) and reach them through
ctx.Agents. Always close agent handles when done.
const TextProcessing = Capability('TextProcessing', 'Extract + summarize')
.Agents({ Extractor: EntityExtractorAgent, Summarizer: TextSummarizerAgent })
.Input(z.object({ text: z.string() }))
.Output(z.object({ entities: z.array(z.string()), summary: z.string() }))
.Execute(async (ctx) => {
const ents = await ctx.Agents!.Extractor({ text: ctx.Input.text });
const sum = await ctx.Agents!.Summarizer({ text: ctx.Input.text });
const entities = await ents.SendMessage('list entities');
const summary = await sum.SendMessage('summarize');
await ents.Close();
await sum.Close();
return { entities, summary };
});
Every Capability is reusable, self-documenting (its schemas + .describe() are
read by callers and AI alike), and self-governing where it needs to be.
- Operation Patterns → - composing Capabilities into named actions