Skip to main content

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_facts is 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.

SectionVerifiedUnverified ("claimed")
IdentityFull (name + email + phone + company + location)Only what they typed this session
Company Insights✅ (when enriched)
EngagementFullCurrent session only
Current Session
Recent Pages✅ (cross-visit)This session only
Past Conversations
Behavioral SignalsCurrent 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 set ALL_SECTIONS — every section except company_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_intro is 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_hash for 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 guardIdentityGraphService.buildContext gates 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

SectionSource
Identity, companyPersonModel, PersonProfileModel
Company Insightsenrichment data on the profile
EngagementUserSessionModel.lead_score, visitor profiles
Recent Pagesvisitor profile recent-session page trips
Past Conversationschats + call transcripts
CRM StatePersonProfileModel.crm_enrichment (cached, refreshed_at)
BookingsPersonProfileModel.bookings[] (deduped via booking_hash)
Form ResponsesPersonProfileModel.form_submissions[]
Extracted FactsPersonProfileModel.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