configuration

The options AgentContext.init() accepts, the blocks getSnapshot() returns, and their defaults. All fields are optional; the minimal call is AgentContext.init().

every option set explicitlyts
import { AgentContext } from '@contextune/sdk';

AgentContext.init({
  eventSource: 'segment',
  blocks: {
    behavior: true,
    device_info: true,
    marketing_params: false, // opt out of UTM capture
    event_log: true,
  },
  eventLogSize: 100,
  namespace: 'my-app',
});

1 / init() options

The top-level options object passed to AgentContext.init(options?).

AgentContextOptions
nametypedefaultexample
eventSource

Tap an existing analytics stream instead of native Snowplow capture for the event log. GA4 and GTM both wrap window.dataLayer.push; pick the one your site already uses. Framework-noise events (gtag config commands, gtm.js, gtm.dom, gtm.load) are filtered automatically.

'segment' | 'ga4' | 'gtm' | undefinedundefined'segment'
blocks.behavior

Include the behavior block (session duration, scroll depth, rage clicks, etc.) in the snapshot.

booleantruefalse
blocks.device_info

Include the device_info block (viewport, user agent, device type, language, platform).

booleantruefalse
blocks.marketing_params

Include marketing_params (UTM, referrer, landing page). Disable if your app doesn't need attribution context.

booleantruefalse
blocks.event_log

Include the rolling event log. Disable to drop the chronological event stream from the snapshot.

booleantruefalse
eventLogSize

Maximum events retained in event_log. Oldest dropped FIFO when capacity is reached.

number50100
namespace

Snowplow tracker namespace. You almost never want to set this — the random default keeps the SDK's tracker isolated from any host-site Snowplow tracker.

string'contextune-<random>''my-app'

2 / behavior block

Computed behavioural attributes. Every string field is passed through sanitiseForLLM before it lands in the snapshot — see Security.

snapshot.behavior
nametypedefaultexample
session_duration_s

Seconds since AgentContext.init() was first called.

number142
scroll_depth_pct

Highest scroll percentage reached this session (0–100).

number67
idle_periods

Gaps with no activity, derived from the time between events. Capped at the most recent 64 periods.

IdlePeriod[][{ start_ms: 45000, end_ms: 57000 }]
rage_clicks.count

Total rapid repeated clicks across the session.

number3
rage_clicks.by_target

Per-selector breakdown. Selector fragments are validated against /^[A-Za-z0-9_:.\-]{1,40}$/ to defang DOM-id prompt-injection.

RageClickAggregate[][{ target_selector: 'button#submit', count: 3 }]
tab_switches

Number of times the page visibilityState moved to hidden.

number2
current_element_focus

CSS selector of the currently focused element. Built by describeTarget() with the same validation as rage_clicks selectors.

string | null'input#email'
current_page_url

URL of the page the user is currently on. Captured on each page view (including the initial one), routed through redactUrl + sanitiseForLLM. null until the first page view fires.

string | null'https://shop.example.com/checkout'
current_page_title

Title of the current page, read from document.title at page-view time and sanitised for LLM consumption.

string | null'Checkout — Field Jacket Co'
last_page_url

Previous page URL. null for the first page view of the session. Useful for SPA route-change reasoning.

string | null'https://shop.example.com/cart'
last_page_title

Previous page title. null for the first page view of the session.

string | null'Cart — Field Jacket Co'

3 / device_info block

Static device information, read at snapshot time from navigator and window.

snapshot.device_info
nametypedefaultexample
user_agent

navigator.userAgent verbatim.

string'Mozilla/5.0 ...'
viewport_w

window.innerWidth in CSS pixels at snapshot time.

number1440
viewport_h

window.innerHeight in CSS pixels at snapshot time.

number900
language

navigator.language.

string'en-GB'
platform

navigator.platform (legacy field; still useful as a coarse OS hint).

string'MacIntel'
device_type

Derived from user agent + viewport width.

'desktop' | 'tablet' | 'mobile''desktop'

4 / marketing_params block

Frozen-at-init marketing context. Every URL field is passed through redactUrl which strips sensitive query params and replaces numeric path IDs.

snapshot.marketing_params
nametypedefaultexample
utm_source

utm_source query param at landing time, decoded and sanitised.

string | null'google'
utm_medium

utm_medium query param at landing time.

string | null'cpc'
utm_campaign

utm_campaign query param at landing time.

string | null'summer'
utm_term

utm_term query param at landing time.

string | null'field-jacket'
utm_content

utm_content query param at landing time.

string | null'hero-cta'
referrer

document.referrer at init, routed through redactUrl. null when there is no referrer.

string | null'https://www.google.com/'
landing_page

Full window.location.href at init, routed through redactUrl (sensitive query params replaced with [REDACTED]).

string | null'https://app.example.com/?utm_source=google'

5 / event_log block

A rolling FIFO window of normalised events. Default size is 50; raise with eventLogSize.

snapshot.event_log[i]
nametypedefaultexample
name

Normalised event name. page_view, page_ping, struct events, Segment track names, or your custom track() name.

string'page_view'
t_s

Seconds from session start.

number67
properties

Optional event payload. Recursively sanitised: redacted keys dropped, URL-shaped values redacted, depth bounded at 4.

Record<string, unknown> | undefined{ form: 'checkout' }

lifecycle & size

The snapshot lives only in JavaScript memory for the life of the tab. There is no cookie, no localStorage, no server — so it is purged the moment the tab closes and is never shared across tabs. Open a fresh tab and you start from an empty snapshot.

event_log is a fixed-size FIFO: once it reaches eventLogSize (50 by default) the oldest event is dropped as each new one arrives, so the log is always the most-recent N events, never an unbounded history. The behavioural counters (clicks, idle_periods) are bounded the same way. There is no time-based expiry today — events persist until evicted by the FIFO cap or the tab closes — so on a long-lived tab a high eventLogSize can retain older events; keep the cap modest if recency matters. A configurable time horizon is on the roadmap.

full snapshot shape

For reference — the complete TypeScript shape of getSnapshot()'s return value with every block enabled. See API reference for per-method signatures.

snapshot.d.tsts
interface Snapshot {
  behavior?: BehaviorBlock;
  device_info?: DeviceInfoBlock;
  marketing_params?: MarketingParamsBlock;
  event_log?: EventLogEntry[];
}