Example Agent: The Autonomous Boardroom
This walkthrough builds a complete multi-agent application that makes a real-world decision grounded in live data. Three board member agents run in parallel, read live tech news from the Hacker News API, debate a strategic motion, and a chairman synthesises their positions into a binding typed resolution.
What It Demonstrates
This example exercises every major Turn primitive working together:
| Feature | How It Is Used |
|---|---|
struct | BoardMemo and BoardResolution define the typed output contracts |
net.get (via std/net) | Live Hacker News headlines fetched at runtime (no mock data) |
spawn_link | CTO, CFO, and Legal run concurrently as isolated actor processes |
send / receive | Chairman collects all three memos via the mailbox |
infer | Each board member reasons over live data and returns a typed memo |
confidence | Chairman gates the final resolution on certainty threshold |
try/catch | Fault handling for HTTP failures |
The Code
struct BoardMemo {
executive: Str,
position: Str,
key_argument: Str,
confidence: Num
};
struct BoardResolution {
motion: Str,
decision: Str,
votes_for: Num,
votes_against: Num,
rationale: Str
};
let net = use "std/net";
let json = use "std/json";
// Fetch live Hacker News headlines for grounded context
let get_context = turn(topic: Str) -> Str {
try {
let id = grant identity::network("public");
let ids_raw = net.get({ "url": "https://hacker-news.firebaseio.com/v0/topstories.json", "identity": id });
let ids = json.parse(ids_raw);
let s1_raw = net.get({ "url": "https://hacker-news.firebaseio.com/v0/item/" + ids[0] + ".json", "identity": id });
let s1 = json.parse(s1_raw);
return s1["title"];
} catch(e) {
return "No live context available: " + e;
}
};
let motion = "Acquire a 22-person AI startup for $12M to accelerate our inference roadmap.";
let news = get_context("AI acquisition");
let parent = self;
// Board members run as isolated concurrent actors
let cto_pid = spawn_link turn() {
context.system("You are the CTO. Evaluate technical feasibility.");
context.append("Recent AI news: " + news);
let memo = infer BoardMemo {
"Evaluate this motion: " + motion;
};
send parent, memo;
};
let cfo_pid = spawn_link turn() {
context.system("You are the CFO. Evaluate financial risk.");
context.append("Recent AI news: " + news);
let memo = infer BoardMemo {
"Evaluate this motion: " + motion;
};
send parent, memo;
};
let legal_pid = spawn_link turn() {
context.system("You are General Counsel. Evaluate legal and regulatory risk.");
context.append("Recent AI news: " + news);
let memo = infer BoardMemo {
"Evaluate this motion: " + motion;
};
send parent, memo;
};
// Collect all three memos from the mailbox
let cto_memo = receive;
let cfo_memo = receive;
let legal_memo = receive;
// Chairman synthesises into a typed resolution
context.append("CTO says: " + cto_memo["key_argument"]);
context.append("CFO says: " + cfo_memo["key_argument"]);
context.append("Legal says: " + legal_memo["key_argument"]);
let resolution = infer BoardResolution {
"Motion: " + motion + " You have reviewed all three board memos above. Render a verdict.";
};
if confidence resolution < 0.75 {
call("echo", "Chairman deferred. Confidence below threshold.");
} else {
call("echo", "Decision: " + resolution["decision"]);
call("echo", "Rationale: " + resolution["rationale"]);
}What Makes This Real
The key distinction from typical AI demos is the absence of hardcoded data. The board members receive their context from a live API call that happens at runtime. Every time you run this program you get different headlines, a different sentiment reading, and potentially a different board decision, because the world has actually changed.
This is what agentic software should look like: deterministic structure, stochastic intelligence, real-world data.
How Actor Isolation Works
Each spawn_link turn() creates a process with its own memory, context, and mailbox. The actors all run concurrently, and the three board members evaluate in parallel. The chairman calls receive three times to collect each result as it arrives. If any board member agent crashes (bad LLM response, network failure), the spawn_link sends an exit signal to the chairman's mailbox.
NOTE
spawn_link ensures the chairman is always notified of failures. If a board member crashes and the chairman does not handle the exit signal, the chairman also exits. This is the "let it crash" principle: faults propagate structurally rather than silently.
Running It
export TURN_LLM_PROVIDER=openai
export OPENAI_API_KEY=sk-...
turn run impl/examples/boardroom.tn
The full implementation is in impl/examples/boardroom.tn.