R RockAI docs

Run your workspace

Tickets

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.

How tickets get created

  1. The bot opens one mid-chat via the 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.
  2. An operator-configured CTA of kind 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.
  3. Inbox human-handoff β€” operators can convert a live conversation into a ticket from the Inbox UI when they realise it needs follow-up after the visitor leaves the page.

Ticket lifecycle

Status moves through four values backed by constants on App\Models\Ticket:

StatusMeaning
openCreated, not yet picked up. Default on insert.
pendingAssigned to an operator and being worked.
resolvedOperator marked done. resolved_at stamped.
closedArchived. Hidden from default views.

Priority is one of low, normal, high, urgent β€” set by the LLM at create time, mutable by operators.

Admin surface

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.

Schema

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.
  • Timestamps.

Linking back to chat history

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.

How the open_ticket tool works

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.