Jev is only as good as the state you send it.
Jev answers typed questions about a state object in a fraction of a second. Signals puts your customer's recent behavior in that object: compact, structured, current as of this click.
- 00:00Fourth price filter change, two failed searches
This customer is struggling to decide.
- +<1sIt is in
checkout_sessionCurrent as of this click, not last night.
- +6msOne call, into the state object
From your own code, inside the render budget.
- next renderJev picks the compare panel over the upsell
A typed choice with a probability you can gate on.
The state is the bottleneck now, not the model.
TypeSafe's own docs say to filter state in code before the call, because accuracy falls as it fills with what the question does not need. Easy for a support ticket. A customer's session is thousands of raw events your code cannot reach from a render.
Four decisions that only work on live state.
Each is a typed question asked on every render. The model does not change the answer. Whether the state describes this visit or last night's does.
Adaptive generative UI
The page composes itself around the job in hand. Give the model what this customer compared, abandoned and came back to, and it picks the components that fit them, not the average visitor.
engagement rate · conversion rateReal-time decisioning
Which offer, flow or message, chosen against what is happening now instead of a segment computed overnight. A rule over the same activity fires the moment the condition is met.
offer acceptance · revenue per sessionIn-session ranking
Results and recommendations reorder against three price filter changes and two failed searches in this visit, not what this customer wanted last week.
click-through · add to cart · search exit rateRouting and triage
Which flow the customer belongs in, when to escalate, and whether the question needs a frontier model at all. The cheapest decision is the one the live state already answers.
escalation rate · cost per conversationBehavioral context, ready for a typed decision.
Add a Snowplow SDK
Web, mobile or server. Events flow in, validated against your schemas.
Say what belongs in the context
Pick the activity the decision needs, as JSON for a state object or a narrative for a prompt.
One call, into the state
Named and typed, ready for Jev.
Signals on the left of the call, the model on the right.
The Node SDK reads the context, the TypeSafe SDK decides. Nothing between them but the object you were already sending.
npx plugins add snowplow/skillsimport { Signals } from "@snowplow/signals-node";
import { choice, noul, TypeSafeClient } from "@typesafe-ai/sdk";
const signals = new Signals({
baseUrl, apiKey, apiKeyId, organizationId,
});
const typesafe = new TypeSafeClient();
// Already shaped for a model, so it goes in as state without a mapping step.
const session = await signals.getAgenticContext({
name: "checkout_session",
identifier: sessionId,
format: "json",
});
const { answers } = await typesafe.systemOne({
state: { session },
questions: {
panel: choice("Which panel should this page lead with?", {
compare: "They are weighing two products against each other",
reassure: "They are hesitating on price or delivery",
resume: "They are returning to an unfinished basket",
}),
stalled: noul("This customer has stalled and would take help"),
},
});
if (answers.stalled.noul > 0.8) render(answers.panel.choice);Add Snowplow Signals to this app so the typed call runs on live behavior. Find where we already ask the model a typed question. Add the Node SDK, define an agentic context named for the surface that decision drives, read it with getAgenticContext in json format and pass it as the state on that call. Leave the questions unchanged, so the only thing that moves is what the model can see.
The JSON form returns the named log: its events, when the session started, and an optional prompt. Ask for narrative and the same call returns a string.
The feature: Agentic context →Full reference: Defining agentic contexts →
The decision runs on the moment.
Read the context, p50 in-region
Event in to attribute updated
JSON for the state object, narrative for the prompt
user · session · basket · listing · store
Before you wire it up
Does Signals decide anything?
No. Signals hands over what the customer is doing. Which panel renders, which offer fires and which flow runs is your model's call, in your code.
Does this only work with Jev?
No. Agentic context comes back as JSON over the REST API, the Node.js or Python SDK, or the MCP server, and as a string in narrative form. Anything that takes a state object or a prompt can read it, System One models included.
Why not send the raw event history instead?
Accuracy. TypeSafe's documentation says accuracy falls as state fills with material the question does not need, and to retrieve and filter in code first. A named context is that filter, applied before the call.
Can I not read this from my own database?
You can read what the customer bought. A current, model-shaped view of what they are doing right now is the part you would build: a stream processor, a store, windowing, late events, hot keys, and someone on call. That is what Signals is.
Do I need an event stream already?
No. Collection is part of Signals. Add a Snowplow SDK and events start flowing. If you already run Snowplow, Signals reads the pipeline you have.
Where does it run?
Managed SaaS, or a private deployment in your own AWS or GCP account. Same architecture either way.
Sources
- Jev 1.13 jaggedness TypeSafe AI, on why state the question does not need costs accuracy.
- Introducing System One Models and Jev TypeSafe AI, on what a System One model takes as input and returns.
Start with one attribute.
Define it, read it in your own product, and see it change while you click around. The free tier runs on the real engine: no card, no sales call.