Cross-Session Context
Audience: Sales, management, support, QA, engineering · Where in app: Sections configured at Admin → Identity → Config; injected into every AI chat/call prompt · Plan availability: All plans (requires active subscription; verified sessions only)
This page describes what the AI actually sees about a returning visitor. When a session is verified, the Identity Graph assembles a structured context block and prepends it to the AI's prompt — so the agent greets by name, references prior conversations, knows the lifecycle stage, and skips already-answered qualification. When a session is only claimed, almost none of this is available.
What it does
- Assembles a per-section context block from the PersonProfile, sessions, chats/calls, CRM cache, bookings, forms, and extracted facts.
- Injects it into the chat agent, call/voice agent, and outbound campaign agent prompts.
- Lets super-admins choose which sections appear, cap list sizes, and prepend a free-form intro.
How it works
The context block is composed of sections. Super-admin chooses which are enabled (enabled_sections[]). The section IDs (as shown in the config UI) and what each contains:
Identity (identity)
Name, email, phone; company name + domain (from PersonProfile); country/city; HubSpot/GHL contact IDs; industry tags (if enriched). Verified names only — the name is emitted only when name_addressable (session verified); an enriched/claimed name never reaches the AI. Geo prefers the visitor's IP city over the enriched company city.
Suspected Identity (suspected_identity)
Owner-facing "⚠ Suspected Identity (UNCONFIRMED)" block built from the session's shadow markers (ip_shadow_person_id / device_shadow_person_id) — {name, email, phone, company_name, basis: ['ip'|'device']}. A hint for operators; the AI must not greet by it.
Company Contacts (company_contacts) — opt-in
Apollo colleague list for the enriched company. Excluded from the default section set (ALL_SECTIONS); renders only when explicitly listed in enabled_sections.
Company Insights (enrichment) — when enrichment connected
Domain, employee count, revenue band, industry tags. Sourced from B2B enrichment (RB2B / Snitcher / Clearbit / HubSpot company data).
Engagement (engagement)
Lead score (current value + recent trend), total session count, first/last seen, lifetime pages viewed.
Current Session (current_session)
Current page URL + title, traffic source (referrer, UTM), time on page, pages in this session so far.
Recent Pages (recent_pages)
Last unique pages across visits (deduped, newest first). Capped by max_recent_pages (default 5).
Past Conversations (past_conversations)
Last chat/call summaries — each with who handled it (AI/human), timestamp, a 1–2 line gist, and outcome. Pulled from chat enrichment + call transcripts. Capped by max_past_conversations (default 5).
Behavioral Signals (behavioral_signals)
High-intent pages, products searched, and bookings.
Bookings (bookings)
Meetings from PersonProfileModel.bookings[], each tagged [PAST] or [UPCOMING] by comparing booking_date/booking_time to now (IdentityGraphRendererService.bookings()), so the AI doesn't reference a past demo as if it's coming up.
CRM State (crm_state) — when HubSpot/GHL connected
Lifecycle stage (lead / MQL / SQL / customer …), open deals/opportunities (stage + amount), tags, recent notes. Cached and refreshed hourly to avoid CRM rate limits.
Form Responses (form_responses)
Captured form field answers for this PersonProfile (deduped — same form filled twice in 24h counts once).
Extracted Facts (extracted_facts)
AI-distilled facts from past conversations and page interactions, e.g. "budget under $5k", "interested in Pro plan", "decision-maker is the CTO", "evaluating against Competitor X". Each fact has a type (preference / intent / objection / follow_up / budget / role / competitor / fact), importance (1–5), and source. Capped by max_extracted_facts (default 15), keeping newest + highest-importance.
Note on caps: the code default for
max_extracted_factsis 15 (IdentityGraphDefaultsModel). Some older KB material says 30 — the singleton's saved value wins; check Admin → Identity → Config for the live number.
How verified vs unverified differs
This table is the practical contract — it's what changes the moment a session crosses the verification bar.
| Section | Verified | Unverified ("claimed") |
|---|---|---|
| Identity | Full (name + email + phone + company + location) | Only what they typed this session |
| Company Insights | ✅ (when enriched) | ❌ |
| Engagement | Full | Current session only |
| Current Session | ✅ | ✅ |
| Recent Pages | ✅ (cross-visit) | This session only |
| Past Conversations | ✅ | ❌ |
| Behavioral Signals | ✅ | Current session only |
| CRM State | ✅ | ❌ |
| Bookings | ✅ (all) | ❌ (only ones made this session) |
| Form Responses | ✅ | ❌ (only ones submitted this session) |
| Extracted Facts | ✅ | ❌ |
See Verification Policy for how a session becomes verified.
Configuration & options
Super-admin owned, under Admin → Identity → Config:
enabled_sections[]— which sections appear. (Implementation note: an empty array means the default setALL_SECTIONS— every section exceptcompany_contacts, which is opt-in only — while a populated array is an explicit allow-list. Valid keys:identity,suspected_identity,enrichment,company_contacts,engagement,current_session,recent_pages,past_conversations,behavioral_signals,crm_state,bookings,form_responses,extracted_facts.)custom_intro— a free-form paragraph prepended to the identity block, e.g. "You are speaking to our high-value customer. Be warm and reference their case-study contribution." This is the only free-form lever; section content is fixed schema.- Caps:
max_recent_pages(5),max_past_conversations(5),max_extracted_facts(15). - Per-company override: flips the whole config via
identity_graph_use_custom_config; tenants can't toggle individual sections themselves.
For QA/support: if a section is missing from the AI's context, check in order — subscription inactive, session only claimed (policy), the section disabled globally/for the tenant, or the source data simply absent (e.g. CRM not connected → no CRM State).
Behaviors & edge cases
- Sections are global per super-admin. Tenants can't toggle individual sections; the per-company override replaces the whole config.
- Fixed schema. Admins can't add custom sections;
custom_introis the only free-form addition. - CRM State staleness. It's hourly-cached — a change made in HubSpot/GHL seconds ago may not show until the next refresh.
- Bookings & forms are deduped across sources (Google/Calendly/GHL/widget for bookings;
submission_hashfor forms). - Config changes apply to the next conversation, not retroactively — an old conversation was rendered with the config in force then.
- ms-ai caches the assembled graph (~30s) and is invalidated by the backend when identity changes, so a just-captured form shows up quickly.
- Cross-tenant leak guard —
IdentityGraphService.buildContextgates cross-session sections (CRM enrichment, forms, facts, bookings) on a same-tenant PersonProfile existing (isCrossSessionVisible).
Plan & limits
All plans, verified sessions only, with an active subscription. Caps are operational settings, not plan tiers. (Any plan-tier restriction on enrichment or specific sections: verify with product.)
Technical implementation
| Section | Source |
|---|---|
| Identity, company | PersonModel, PersonProfileModel |
| Company Insights | enrichment data on the profile |
| Engagement | UserSessionModel.lead_score, visitor profiles |
| Recent Pages | visitor profile recent-session page trips |
| Past Conversations | chats + call transcripts |
| CRM State | PersonProfileModel.crm_enrichment (cached, refreshed_at) |
| Bookings | PersonProfileModel.bookings[] (deduped via booking_hash) |
| Form Responses | PersonProfileModel.form_submissions[] |
| Extracted Facts | PersonProfileModel.extracted_facts[] (+ agent memories) |
The block is composed by IdentityGraphRendererService and consumed by ms-ai. See Identity Graph (subsystem).
What Nox can tell you
- Exactly what was in the prompt for a specific session
- Why a section was missing (subscription, policy, disabled, no source data)
- How many extracted facts a person has
- The full identity graph for a person
Related
- Verification Policy — what unlocks each section
- Identity Graph Overview
- Person vs Profile — where each section's data lives
- Form Intercept
- Admin Controls
- Identity Graph (engineering subsystem)