Acts of Emergence

004: Agent/Call

A Call is a ready-to-go action. Think of a Tool as a recipe. A Call is when you actually use that recipe with specific ingredients to cook something. It’s an instruction for what should be done right now.

The Tool protocol sets up the basic menu of what an AI agent can do. This document explains the Call protocol, which is all about how the agent actually does those things.

A Call is a specific action, based on a Tool, that is filled out and ready to go. While Tools tell you what's possible, Calls are the commands that say how to do it now.

Heads up

When an agent gets a Request and decides on a set of actions (Calls), that whole decision package is called a Vessel. A Vessel is like a snapshot of the agent's plan at a single moment, choosing from its available Tools to figure out what to do next.

Combining Calls with Context

A Call on its own is just a simple instruction. Its real power comes from combining it with other rules that control how and where it runs. These rules are activated by special instructions (they start with an _ symbol) inside a Tool's design. This lets a single Call command trigger all sorts of interesting behaviors.

By giving these special instructions clear meanings, we let the AI (LLM) become a smart planner. It can think about how to mix and match these instructions to build clever and complex chains of actions. It's not just picking a tool from a list; it's building a custom workflow on the fly.

Tip

The next few points explain how this connects to other parts of the system. You don't need to jump ahead and read about them now; we'll get to them in order. You can always come back here later.

  • Doing Real Work (_activity): The most basic upgrade is connecting a Call to a piece of computer code that performs a specific task. The _activity instruction tells the system that this Call should be handled by a real program (Activity), not just thought about by the AI.

  • Passing the Job to Someone Else (_delegate): A Call can hand off its job to another, separate agent (Delegate). The _delegate instruction usually points to a saved Request, turning that request into a reusable tool. This gives the task its own clean workspace, so it doesn't get confused by other things happening at the same time.

  • Focusing Attention (_scopes): The Scopes protocol is like putting blinders on the AI to help it focus. It tells a Call exactly what information it's allowed to see. This prevents the AI from getting distracted by too much information and helps it give more reliable answers. When used with _delegate, it's even more powerful: it creates a completely sealed-off environment for the delegated task, defining everything it's allowed to know.

  • Saving the Result (_outputPath): You can make a Call save its work. The _outputPath instruction tells the Call where to put its result in a shared memory space called the State. This allows you to build step-by-step processes where the result of one action becomes the starting point for the next.

  • Working on a Specific Item (_instance): When you have a list of things to process, a Call can be told to work on just one specific item (Instance). The _instance instruction acts like a label, telling the Call which item to read from and write to in the shared State. This is great for doing the same job on many different items at the same time.

Different Ways to Run Calls

When an agent creates a list of Calls to run, you can choose how to execute them:

// Run just one Call
const result = await Tool(call);

// Run all Calls and wait for them all to finish
const results = await Tool.all(calls);

// Run all Calls and stop as soon as one succeeds
const result = await Tool.any(calls);

// Run all Calls and stop as soon as one finishes (whether it succeeded or failed)
const result = await Tool.race(calls);

These different ways of running things allow for:

  • Step-by-Step Control: Handle Calls one by one, with your own logic in between.
  • Doing Things in Parallel: Run a bunch of independent Calls at the same time to go faster.
  • Quick-Exit Plans: Stop as soon as you get what you need (.any()) or as soon as something finishes (.race()).
  • All-or-Nothing Jobs: Make sure a whole group of Calls succeeds together (.all()), which is important when they depend on each other.

Chaining Calls Together in a Loop

These patterns are great for managing a single batch of Calls, but agents often need to do tasks that have multiple steps, where the result of one action is needed for the next. This is handled by a bigger system that manages the flow of Requests and Calls in a sequence.

The next document, 005: Agent/Loop, explains how this bigger process works.