# Build dialogue and support Agents

> Build conversational, generation, routing, triage, and customer-support Agents from bounded history, turns, Tools, and escalation.

## Before you begin {#before-you-begin}

Define the Channel that authenticates callers, the logical Model binding, the bounded history the Agent may read, and any Resources a support action requires. Decide which answers can complete automatically and which outcomes require an escalation or approval. Conversation history is context; a committed fact is workflow truth.

## Steps {#steps}

1. Start with `ledger → turn → commit`. Give the turn one objective, bounded prior facts, and only the Tools allowed for this caller.
2. Use a structured artifact or a second turn when routing must choose a queue, specialist, or child task. Do not let raw model text select a Resource CRN.
3. Use `await` for a human decision and `spawn` for independently durable specialist work. Use neither for ordinary in-process helper functions.
4. Commit the disposition, case reference, or final response that later Runs must trust.

```ts
import { agent, type HistoryView } from "@constal/sdk";

export default agent({
  id: "support", version: "1.0.0", model: "model",
  async onMessage(message, ctx) {
    const history = await ctx.ledger.view<HistoryView>("history");
    const response = await ctx.turn({
      system: "Resolve the request. Use offered Tools for facts; escalate when authority is missing.",
      objective: message,
      context: { facts: history.facts },
      tools: ["lookup_customer", "update_ticket"],
    });

    const result = { kind: "support-response", text: response.message.content };
    await ctx.commit(result);
    return result;
  },
});
```

For a pure content Agent, remove Tools and history that the task does not need. For a router, constrain `turn.artifact` to a small validated destination set, then dispatch through registered code. For support, keep customer-specific Resources and Credentials behind customer- or principal-scoped bindings established from authenticated Channel identity.

## Verify {#verify}

Start a controlled conversation and inspect the Run journal. Confirm history is bounded, only declared Tools appear, every Tool call targets a pinned Resource, and the final disposition is committed once. Test an unknown caller, a denied action, an ambiguous provider outcome, and an escalation timeout. Replaying the same event must not duplicate a ticket update.

## Next steps {#next-steps}

Read [Channels and Auth Providers](/docs/channels.md), [Resources and Tools](/docs/sdk/resources-and-tools.md), [Scoped bindings](/docs/credentials/scoped-bindings), and [Human waits and controls](/docs/runs/waits-and-controls.md).
