import { CodeBlock } from '../views/docs/CodeBlock';
import { PropTable, NextLink } from '../views/docs/prose';

export const RUNNER_EX = `import os
from guava import Agent, Runner

agent_a = Agent(name="Grace", purpose="You are a helpful voice agent.")
agent_b = Agent(name="Jordan", purpose="You are a helpful voice agent.")

runner = Runner()
runner.listen_phone(agent_a, os.environ["GUAVA_AGENT_NUMBER"])
runner.listen_webrtc(agent_b)
runner.run()`;

## Runner

`guava.Runner` lets you serve multiple agents in a single process. Each agent can be attached to any number of channels — phone, WebRTC, SIP, or outbound campaigns. Call `run()` to start everything and block until all channels exit.

<CodeBlock code={RUNNER_EX} filename="run.py" language="python" />

### Methods

<PropTable rows={[
  { name: "listen_phone(agent, agent_number)", type: "Runner", desc: "Register an agent to receive inbound calls on the given phone number. Returns self for chaining." },
  { name: "listen_webrtc(agent, webrtc_code=None)", type: "Runner", desc: "Register an agent to accept WebRTC connections. A new code is generated if webrtc_code is omitted. Returns self for chaining." },
  { name: "listen_sip(agent, sip_code)", type: "Runner", desc: "Register an agent to receive inbound SIP calls on the given SIP code. Returns self for chaining." },
  { name: "attach_campaign(agent, campaign)", type: "Runner", desc: "Attach an outbound campaign to an agent. Returns self for chaining." },
  { name: "run()", type: "None", desc: "Start all registered channels in daemon threads and block until they all exit." },
]} />

<NextLink section="on-action-request-execute" label="on_action_request() / on_action()" />
