import { CodeTabs } from '../views/docs/CodeTabs';
import { Callout, NextLink } from '../views/docs/prose';

export const AGENT_EX_PY = `import os
import guava

# Define our agent
agent = guava.Agent(
    name="Nova",
    organization="Acme Corp",
    purpose="Help customers with their orders.",
)

# Register handlers
@agent.on_call_start
def on_call_start(call: guava.Call):
    ...

# Attach to a channel
agent.listen_phone(os.environ["GUAVA_AGENT_NUMBER"])`;

export const AGENT_EX_TS = `import * as guava from "@guava-ai/guava-sdk";

// Define our agent
const agent = new guava.Agent({
  name: "Nova",
  organization: "Acme Corp",
  purpose: "Help customers with their orders.",
});

// Register handlers
agent.onCallStart(async (call) => {
  ...
});

// Attach to a channel
agent.listenPhone(process.env.GUAVA_AGENT_NUMBER!);`;

## Agent

`guava.Agent` is the entrypoint for creating Guava voice agents. Create an `Agent` instance, attach handlers, then attach to a channel.

<CodeTabs
  python={{ code: AGENT_EX_PY, filename: "agent.py" }}
  typescript={{ code: AGENT_EX_TS, filename: "agent.ts" }}
/>

export const AGENT_SIG_PY = `guava.Agent(
    # The name the agent uses to identify itself to callers.
    name: str | None = None,

    # The organization the agent represents.
    organization: str | None = None,

    # High-level description of the agent's role.
    purpose: str | None = None,
)`;

export const AGENT_SIG_TS = `new guava.Agent({
  // The name the agent uses to identify itself to callers.
  name?: string,

  // The organization the agent represents.
  organization?: string,

  // High-level description of the agent's role.
  purpose?: string,
})`;

### Constructor

Use the constructor parameters to configure your Agent's persona and goal.

<CodeTabs
  python={{ code: AGENT_SIG_PY }}
  typescript={{ code: AGENT_SIG_TS }}
/>

### Handlers

Register handlers to control and react to the call in real-time.

| Handler | Description |
|---------|-------------|
| `on_call_received` | This handler is invoked on incoming calls. You can chose whether to reject or accept the call. The default behavior if not provided is to accept every call. |
| `on_call_start` | Called when a call begins. Unlike `on_call_received`, this handler is invoked for both incoming and outgoing calls. Use this handler to set initial tasks and context for the Agent. |
| [`on_caller_speech`](./on-caller-speech) | Called each time the caller speaks. |
| [`on_agent_speech`](./on-agent-speech) | Called each time the agent speaks. |
| [`on_question`](./on-question) | Called when the caller asks the agent a question it cannot answer from context alone. The provided answer is relayed back to the caller. |
| `on_task_complete` | Called when the Agent completes a [Task](./tasks) previously set using `call.set_task`. |
| `on_search_query` | Provide dynamic search results for a searchable [Field](./field). |
| [`on_action_request` / `on_action`](./on-action-request-execute) | Called when the caller asks for a specific action, e.g. "can I reset my password?" |
| `on_session_end` | Called when the session ends. |
| [`on_reach_person`](./reach-person) | Called when a `reach_person` task completes. |
| `on_outbound_failed` | Called when an outbound call fails to dial. |
| `on_escalate` | Called when an escalation is triggered. |

### Entrypoints / Channels

Attach the agent to a channel to start receiving calls.

| Entrypoint | Description |
|------------|-------------|
| `listen_phone("+1...")` | Listen for inbound phone calls on the given phone number. |
| `listen_webrtc("grtc-..." \| None)` | Listen for inbound WebRTC connections to the given agent code. If not provided, a temporarly agent code is automatically created. |
| `listen_sip("guavasip-...")` | Listen for inbound SIP connections to the given SIP code. |
| `call_phone(from_number, to_number, variables?)` | Place a single outbound phone call. |
| `call_local()` | Call the agent using your local audio device (for testing). |
| `attach_campaign(campaign)` | Attach an agent to an outbound [Campaign](./campaign). |

<Callout>
  To attach an agent to multiple channels, or run multiple agents in the same process, use <a href="./runner">guava.Runner</a>.
</Callout>

<NextLink section="tasks" label="Tasks" />
