Keyboard shortcuts

Press or to navigate between chapters

Press S or / to search in the book

Press ? to show this help

Press Esc to hide this help

Spawning & Awaiting

Agents are created with summon and their results are retrieved with await.

summon

Creates a new agent and returns a handle:

let worker = summon Worker { task: "process data" };

The spawned agent starts running immediately and concurrently with the spawning agent.

Summon Syntax

summon AgentName { field1: value1, field2: value2 }

All fields must be provided:

agent Point {
    x: Int
    y: Int

    on start {
        yield(self.x + self.y);
    }
}

// Correct
let p = summon Point { x: 10, y: 20 };

// Error: missing field `y`
let p = summon Point { x: 10 };

Agent Handle Type

summon returns an Agent<T> where T is the yield type:

agent Worker {
    on start {
        yield(42);  // Emits Int
    }
}

let w: Agent<Int> = summon Worker {};

await

Waits for an agent to yield its result. Since agents can fail, await is a fallible operation that requires try:

let worker = summon Worker {};
let result = try await worker;  // Blocks until Worker emits

Await Type

await returns the type that the agent yields:

agent StringWorker {
    on start {
        yield("done");
    }
}

agent Main {
    on start {
        let w = summon StringWorker {};
        let result: String = try await w;
        print(result);
        yield(0);
    }

    on error(e) {
        yield(1);
    }
}

run Main;

Await Blocks

await suspends the current agent until the result is ready. Other agents continue running.

Concurrent Execution

Spawned agents run concurrently:

agent Sleeper {
    ms: Int

    on start {
        sleep_ms(self.ms);
        yield(self.ms);
    }
}

agent Main {
    on start {
        // All three start immediately
        let s1 = summon Sleeper { ms: 100 };
        let s2 = summon Sleeper { ms: 200 };
        let s3 = summon Sleeper { ms: 300 };

        // Total time: ~300ms (not 600ms)
        let r1 = try await s1;
        let r2 = try await s2;
        let r3 = try await s3;

        yield(0);
    }

    on error(e) {
        yield(1);
    }
}

run Main;

Pattern: Fan-Out/Fan-In

Spawn multiple workers, await all results:

agent Researcher {
    topic: String

    on start {
        let result = try divine(
            "One sentence about: {self.topic}"
        );
        yield(result);
    }

    on error(e) {
        yield("Research failed");
    }
}

agent Coordinator {
    on start {
        // Fan out
        let r1 = summon Researcher { topic: "AI" };
        let r2 = summon Researcher { topic: "Robotics" };
        let r3 = summon Researcher { topic: "Quantum" };

        // Fan in
        let s1 = try await r1;
        let s2 = try await r2;
        let s3 = try await r3;

        print(s1);
        print(s2);
        print(s3);
        yield(0);
    }

    on error(e) {
        print("A researcher failed");
        yield(1);
    }
}

run Coordinator;

Pattern: Pipeline

Chain agents together:

agent Step1 {
    input: String

    on start {
        let result = self.input ++ " -> step1";
        yield(result);
    }
}

agent Step2 {
    input: String

    on start {
        let result = self.input ++ " -> step2";
        yield(result);
    }
}

agent Main {
    on start {
        let s1 = summon Step1 { input: "start" };
        let r1 = try await s1;

        let s2 = summon Step2 { input: r1 };
        let r2 = try await s2;

        print(r2);  // "start -> step1 -> step2"
        yield(0);
    }

    on error(e) {
        yield(1);
    }
}

run Main;