Graine AI

What lands in Call History

Every screen, field, tap, friction signal, action and identity the SDK reports ends up on the call record — here is exactly where each one shows up, and what it looks like.

Nothing needs instrumenting beyond what the screens already report. Each thing the SDK sends has one place it lands in Call History, on the session's panel and in the CSV export.

The mapping

You callThe agent receivesCall History shows
useGraineScreen / useGraineFieldapp_context — screen, fields, errorsWhat happened in the app · "opened privacy", "moved to favourites (from privacy)"
useGraineTap / useGraineTrackrecent_events on the next context frameWhat happened in the app · "tapped pay", "toggle_changed"
Friction rules (configure)app_event with the sentence the agent hearsWhat happened in the app · "stalled on step: agent spoke up" / "rage taps: agent stayed quiet — it had spoken up moments before"
client.reportEvent(...)app_eventWhat happened in the app · a signal row, same shape
useGraineAction handler resultsthe tool result the model readsWhat the agent did in the app · action, arguments, ✓ / refused / timeout, and your handler's own message
identify()prompt variables + app_user; the identifier only identifies the customerwho it was with on the row and the panel header — the identifier as label · value, else the name (below)
appVersion on the providerapp_version on the context framethe record, for telling a build apart
Nothing — the SDK reports itapp_event flagged telemetryWhat happened in the app · ⇅ rows: "transport: WebRTC", "connection quality: poor · rtt 480ms", "network: offline", "transport: fell back to WebSocket (media)". Never spoken by the agent

The panel also carries the transcript (both sides, WebRTC calls included), Result (Completed for a web call), Talk Time (the conversation's length; a web call has no carrier duration), and cost.

Who it was with

Each row and its panel name the customer by the identifier your app sent, with the label of the agent's identity setting: User ID · u_8812, Email · asha@acme.example, Customer ID · C-20931. Without an identifier the row shows the customer's name, from their traits, and failing that the connection's id. A phone call shows Phone · the caller's number; a call Graine rang shows the customer it was booked for. Search Call History by an identifier to find a customer's conversations.

Graine stores the identifier your app sends so your team can see who each conversation was with; the memory service only ever receives a one-way key derived from it — Identity and users.

Why a signal says the agent stayed quiet

A friction signal is a request, not a command. The agent stays quiet while it is already talking, inside nudge.cooldownSeconds of its last intervention, and past nudge.maxPerSession. The timeline records which — it was mid-sentence, it had just spoken up, it had reached its limit — so a product team can tell "the agent ignored a stuck customer" from "the agent was already helping".

CSV

Web-call exports carry Contact Name, App Actions (one line per action, with the app's reply) and App Timeline (one line per entry, oldest first), beside the columns every call has.

What is not there

Only what the app reported. A screen that never called useGraineScreen appears by route name only; a tap not wrapped in useGraineTap is not on the timeline. Calls made before this was stored show a transcript and a status and nothing of the above.

On this page