Operations
Copy MarkdownEverything people and programs do with agents is an operation. Each is defined once, and works the same from your code, HTTP, Slack or a terminal.
Setup
In a fresh IEx session:
Mix.install([{:wardrik, "~> 0.1.0-rc.1"}])
{:ok, _} = Wardrik.start_link(name: MyApp.AgentRuntime)
scope = Wardrik.as(MyApp.AgentRuntime, "acme/@maria", roles: [:owner], resources: ["acme/@maria/*"])As functions
Each operation is a function named by its ID. agent.define is Wardrik.Agent.define/3:
{:ok, books} =
Wardrik.Agent.define(scope, "acme/@maria/books",
model: "anthropic:claude-haiku-4-5",
instructions: "You keep Maria's books."
)
Wardrik.Agent.read(scope, books)
#=> {:ok,
#=> %Wardrik.Agent{
#=> id: "acme/@maria/books",
#=> name: "books",
#=> status: :idle,
#=> node: "nonode@nohost",
#=> pending: 0,
#=> activity: %Wardrik.Activity{doing: [], ...},
#=> interrupts: [],
#=> cursor: "eyJhY21lL0BtYXJpYS9ib29rcyI6MX0"
#=> }}
Wardrik.Agents.list(scope)
#=> {:ok, [%Wardrik.Agent{id: "acme/@maria/books", status: :idle, ...}]}
Wardrik.Agent.cancel(scope, books)
#=> :ok
Wardrik.Agent.read(scope, "acme/@maria/ledger")
#=> {:error, %Wardrik.Error{type: :not_found, message: "There's no agent acme/@maria/ledger."}}agent.ask is Wardrik.Agent.ask/3, and needs the model's API key; see Talk to agents.
Each function takes, in order:
- the scope.
- the operation's path parameters, each as text or as the struct it names, like
%Wardrik.Agent{}for an agent or%Wardrik.Interrupt{}for a call it waits on. - the rest of its input, as a keyword list.
Each returns a struct, a list of them, or :ok. It returns {:error, %Wardrik.Error{}}, with the
error's type and message, when it fails. Operations that can be streamed also have a stream_
function; see Events and the audit.
| Returns | Operations |
|---|---|
%Wardrik.Agent{} | define, read, clear, spawn, stop, move; a list from Wardrik.Agents.list/2 |
%Wardrik.Message{} | ask |
[%Wardrik.Decision{}] | decide, approve, deny |
[%Wardrik.Interrupt{}] | Wardrik.Interrupts.list/2 |
%Wardrik.Page{} of %Wardrik.Event{} | events, Wardrik.Events.list/2, Wardrik.Audit.list/2 |
%Wardrik.Timeline{}, %Wardrik.Runs{} | timeline, runs |
[%Wardrik.Call{}], %Wardrik.Authorization{} | calls, authorization |
:ok | cancel, forget, kill |
An event's data, an activity's doing and a timeline's items stay as the protocol's maps, since
their shape depends on their type.
| Module | Operations |
|---|---|
Wardrik.Agent | One agent: define, ask, read, cancel, decide, approve, deny, stop, spawn, clear, forget, move, its triggers, calls, events, timeline and runs. |
Wardrik.Agents | The agents a scope can see: list, cancel and forget them. |
Wardrik.Interrupts | What agents wait on. |
Wardrik.Events | Agents' events. |
Wardrik.Audit | What people did. |
Wardrik.Tokens | API tokens. |
Wardrik.Connections | Accounts people and orgs connect. |
Wardrik.MCPServers | MCP servers orgs and people add. |
Wardrik.Ceilings | What orgs have spent. |
Wardrik.Deployment | Nodes and reloading. |
Wardrik.Hook | Webhook requests to triggers. |
By ID
Wardrik.run/3 runs an operation by its ID. It takes and returns the protocol's JSON, which is how
a surface you build reaches operations:
Wardrik.run(scope, "agent.read", %{"agent" => "acme/@maria/books"})
#=> {:ok,
#=> %{
#=> "agent" => %{"id" => "acme/@maria/books", "name" => "books"},
#=> "status" => "idle",
#=> "cursor" => "eyJhY21lL0BtYXJpYS9ib29rcyI6MX0",
#=> ...
#=> }}