[contextune]
[section: intro]

nail your agent's first reply.

For customer-facing agents, the first response decides the conversation. Give yours the behavioural context a human rep would have — what the user was doing before they typed — and it lands the first reply instead of stalling on a clarifying question.

Early integrators see double-digit lifts in first-response engagement: fewer clarifying-question loops, fewer abandoned threads. Right now your agent is flying blind — it sees what the user typed, not the 45 seconds of idle time, the three rage clicks, or the tab they keep switching to.

We built the SDK we wished existed — three lines, no collector, no signup. MIT-licensed, runs entirely in the browser.

[snapshot output]live
{
  behavior: {
    session_duration_s: 45,
    scroll_depth_pct: 78,
    rage_clicks: { count: 3, by_target: [...] },
    tab_switches: 2,
    idle_periods: [{ start_ms: 8000, end_ms: 28000 }],
    current_element_focus: "#checkout-button"
  },
  device_info: { viewport_w: 1440, device_type: "desktop" },
  marketing_params: { utm_source: "organic", ... },
  event_log: [...]
}
what your agents don't know.

The gap between what agents see and what actually happened.

Your agents see typed text.
A user asks a question. Your agent reads it. But the agent has no idea the user clicked the same button seventeen times before typing, or has been idle for three minutes, or switched tabs twice while thinking.
Behavioural context already exists.
Scroll depth, idle periods, rage clicks, tab switches — these signals are already flowing through your app. They go to dashboards, not to agents. We turn them into structured context your agent can actually use.
Most solutions are overkill.
Session replay, full event pipelines, analytics collectors — they're powerful, but they're also heavyweight. We do one thing: capture what's in the browser, structure it, inject it into your agent. That's it.
how it works.

three lines, three minutes.

  1. Initialize the SDK.

    Three lines: import, call init(). Runs entirely in the browser, no collector, no dashboard.

  2. Call getSnapshot().

    Returns a structured object: behaviour, device info, marketing params, event log.

  3. Inject into your agent prompt.

    Drop the snapshot into your system prompt. Your agent now sees what the user was doing.

integration.

show the agent what the user is doing.

[example]
import { AgentContext } from '@contextune/sdk'

// Initialize (three lines, zero config)
AgentContext.init()

// Whenever the user interacts, get a snapshot
const snapshot = AgentContext.getSnapshot()

// Inject into your system prompt
const systemPrompt = `
You are a helpful shopping assistant.

Live behavioral context:
${JSON.stringify(snapshot, null, 2)}

Use this context to understand the user's intent.
`
[section: why this exists]

zero latency.

Runs client-side. No round trip. getSnapshot()is a synchronous read from in-memory state — sub-millisecond on a populated engine.

Nothing leaves the browser when you read the snapshot. The behavioural profile is maintained in the user's session, and you inject it into the system prompt at the moment you call your model. No collector hop, no server fetch, no network waterfall between behaviour and decision.

snapshot read
< 1ms
round trips
0
servers to provision
0

open source.

MIT-licensed. No account. No per-seat. No per-event. Drop it into your own app and keep the data where it already lives.

Phase 1 runs entirely in your application. There's nothing to provision and nothing to bill. The hosted state layer is the paid product, later — you opt in when you need it, not before. Until then: pnpm add, init(), inject the snapshot. That's the integration.

agent first-reply quality.

Early integrators see directionally better first replies when the agent reads behavioural context — fewer clarifying-question loops, fewer abandoned threads.

When the agent knows the user has been idle for a minute, has rage-clicked the size selector, or jumped tabs twice, its first reply lands differently. The shape of the effect is consistent across early integrators; we'll publish the numbers when launch-partner studies land — we'd rather flag it than overclaim.

Directional finding across early integrators; structured measurement pending with launch partners later this year.

why now.

agents are the first consumer of behavioural signals.

For fifteen years, behavioural tracking served dashboards and funnels. Analytics platforms got better at asking "what happened?" — but the data never went to the product agents shipped to users. Agents are different. They make decisions in real time based on context. When a user is frustrated, your agent should see that. When they've been idle for three minutes, your agent should know. That signals are captured in the browser is a solved problem. What's new is that they can now become live input to the decisions agents make.

We built this because we knew the gap existed. Every serious product team building agents has discovered it independently. This SDK is the connection we all wished we'd had.

[section: faq]

questions a real integrator would ask.

01does my data leave the browser?

No. Zero network egress from the SDK itself. The behavioural profile is built and maintained in memory in the user's session. getSnapshot()is a synchronous read — no fetch, no beacon, no collector.

If you bring your own event source (Segment, GA4), that sourcewill keep making its own network calls. The SDK doesn't.

02how does it work with my existing analytics?

It intercepts, it doesn't replace. Point the SDK at your existing source (eventSource: 'segment', GA4 / GTM landing in M1.8) and it passively listens to events you're already firing, normalises them, and folds them into the snapshot.

Your dashboards keep working. The agent gets the same signal stream, structured.

03what about CSP?

The SDK is a bundled dependency, not a remote script. It doesn't inject <script>tags, doesn't inline styles, doesn't make cross-origin requests of its own. Strict CSPs pass.

If you've wired in an external event source, allow that source's domain in your CSP — that part isn't ours.

04do you support react native or mobile?

Not yet. The capture surface depends on browser-only APIs — scroll, focus, visibilitychange, AbortController, the DOM event loop. A React Native build would be a separate target with a different signal set.

Mobile web works the same as desktop web. If you're shipping a PWA, you're covered today.

05how big is the bundle?

~33KB minified, ~10KB gzipped. Zero peer dependencies you don't already have. The ESM build tree-shakes, so source plugins you don't use don't ship.

A typical snapshot in the prompt runs 1–3KB of JSON. Configurable per block if you're token-sensitive.

06how do I add custom events?

Call AgentContext.track(name, properties?). The event lands in the event_log block with source: 'custom' alongside whatever your existing analytics source is emitting. No source plugin required.

AgentContext.track('added_to_cart', {
  product_id: 'field-jacket-olive',
  size: 'M',
});
07browser compatibility?

Chromium ≥ 100, Firefox ≥ 100, Safari ≥ 15.4. The hard requirement is AbortController, which lets us tear capture down cleanly on destroy().

Older browsers fail silently — your app keeps working, the snapshot is just empty.