alepha@docs:~/docs/.content/release/framework/docs/reference/primitives$
cat $ai.md | pretty2 min read
#$ai
#Import
typescript
1import { $ai } from "alepha/ai";
#Overview
Declares an assistant: a system prompt, the $actions it may call, and a
tool loop that runs them as the signed-in user.
- Tools are
$actions. Each becomes a tool named after the action, described by itsdescription, taking{ params, query, body }for the parts the action declares. It runs throughaction.run(input, { user }), so the action's ownuse: [$secure(...)]decides, and the assistant can never do more than the user could. A refusal, a validation error or a thrown error goes back to the model as a tool error. - Mutations wait for the user. A call to a non-GET action (or whatever
confirmsays) pauses the turn with aconfirmevent; a client tool (seeclientTool) pauses with aclient_toolevent. - Re-entrant. The loop's whole state is the message list. A pause ends
the stream; resuming is a new
stream()with the stored messages andresume: { callId, decision }or{ callId, result }. An approved call runs the input stored in the messages, never input sent back by a browser. Nothing lives in memory between requests, which is the shape that works on Workers. - Page context rides on the latest user message, capped at 8 KB, never in the system prompt, which stays cacheable.
#Options
| Option | Type | Required | Description |
|---|---|---|---|
name |
string |
No | Name of the assistant, in logs |
model |
string |
No | Model id for this assistant |
system |
string | ((ctx: { user?: UserAccountToken }) => string) |
Yes | The system prompt, or a function of the user |
tools |
Array<ActionPrimitive<any> | AiClientTool> |
No | The tools: $actions, and client tools from clientTool. |
confirm |
Object |
No | Whether a call to this action waits for the user's approval |
maxSteps |
number |
No | Model calls per turn before the loop stops with end: length. |
timeout |
DurationLike |
No | Wall-clock bound on one stream(), aborting the model call in flight. |
maxTokens |
number |
No | Upper bound on the tokens of each model response. |
#Examples
ts
1class Support { 2 invoices = $inject(InvoiceApi); 3 4 assistant = $ai({ 5 system: "You help with invoices. Be brief.", 6 tools: [this.invoices.list, this.invoices.create], 7 }); 8 9 async answer(messages: AiMessage[], user: UserAccountToken) {10 for await (const event of this.assistant.stream({ messages, user })) {11 // persist `message` events, forward `text`, stop on a pause12 }13 }14}