Tickets are durable support records. Conversations expire after 24 hours; tickets persist forever. Use them for issues that need a human follow-up beyond the live chat window — billing disputes, bug reports, account problems, feature complaints.
open_ticket LLM tool. Auto-enabled for agents whose
vertical is help_center (the
HelpCenterPreset ships the ticketing
capability the tool requires). Other verticals can opt in by
adding ticketing to the agent's
vertical_overrides.capabilities.
open_ticket renders a button inside the chat that
opens a ticket directly when the visitor clicks it. Useful when
you want a deterministic escalation path that doesn't depend on
the LLM choosing the tool.
Status moves through four values backed by constants on
App\Models\Ticket:
| Status | Meaning |
|---|---|
open | Created, not yet picked up. Default on insert. |
pending | Assigned to an operator and being worked. |
resolved | Operator marked done. resolved_at stamped. |
closed | Archived. Hidden from default views. |
Priority is one of low, normal, high, urgent — set by the LLM at create time, mutable by operators.
Operators see workspace tickets at /app/tickets:
GET /app/tickets — paginated list, filter by status / priority / assignee. Workspace-scoped via the BelongsToWorkspace trait.GET /app/tickets/{ticket} — single ticket with the linked conversation history if one exists.PATCH /app/tickets/{ticket} — change status, priority, assignee, or notes.The tickets table (migration 2026_05_13_092105_create_tickets_table.php):
workspace_id, agent_id, conversation_id (nullable — operator-opened tickets needn't be tied to a chat).subject (≤ 120 chars), body.status (open / pending / resolved / closed), priority (low / normal / high / urgent).assigned_to_user_id — nullable.metadata JSON — free-form bag for source-specific context (the open_ticket tool stores source: 'open_ticket_tool'; the CTA path stores the rule id; the human-escalation path stores the operator's id).resolved_at stamped when status flips to resolved.
Every ticket carries conversation_id when one is
available. The admin page renders the full chat thread side-by-side
with the ticket body so the operator can answer with the visitor's
own words for context — no "what did they actually ask?" hunt.
See Tools & rich messages for the registry shape. The tool's input schema:
subject — required, ≤ 120 chars.body — required. The LLM is prompted to include the visitor's account / order references, what they tried, and what went wrong.priority — optional, defaults to normal.
On invoke the tool inserts a Ticket row tied to the
current conversation and returns a confirmation the LLM weaves into
its final reply ("I've opened ticket #ABC-1234 for our team…").
Operators get a notification via the same channel they receive
new-lead pings.