[User]— facts your server asserts about the signed-in person (plan, role, tenure, whatever you choose). Refreshed on every request.[Situation]— what their screen shows right now, plus any structured data you publish. Sent with the message, used for that turn only.
Assert facts about the user
Facts come from theuser resolver inside an
auth preset. Add a facts object beside the
display and email you already return.
1
Resolve identity through a preset
Facts are a preset-only channel: pass
auth, not the per-seam
principal/actAs/oauth trio. The preset already decodes the session
once per request, and facts ride that same decode, so they cost no second
verify. If vendo init detected no auth provider it wrote a principal:
demo line into your composition — delete it, or createVendo throws
VendoError("validation") for supplying both.2
Return facts from the user resolver
Values are any JSON. Returning
null still means “subject unknown to the
host” — the principal resolves to anonymous and no facts are asserted.
Edit the auth: line in the composition init already generated; keep its
other keys, such as catalog.key: value per line:
examples/demo-bank/src/vendo/server.ts (Maple).
The screen is already being sent
You do not wire this. On every send, the widget snapshots the visible host page and attaches it to the request ascontext. The snapshot is the page’s
accessibility tree — the URL and title, then headings, landmarks, links,
buttons, table contents, form values, and control states (checked, selected,
disabled).
For a transfer page, the agent receives roughly this:
Publish your own data
Anything the page knows but does not display — a cart total, a selected row id, a wizard step — goes throughuseVendoContext. It merges into the same
[Situation] block and retires automatically when the component unmounts, so
the agent never sees a screen the user has left.
It republishes whenever the
data object’s identity changes, so an inline
literal republishes on every render. Harmless, but wrap it in useMemo if
the object is expensive to build.<VendoRoot> supplies used to hold this name
and is now useVendoProvider; useVendoContext(data) is the host-facing one
described here.
Control what the snapshot sees
Exclude one element.data-vendo-ignore drops that element and everything
under it. Vendo’s own chrome already carries it, so the widget never snapshots
itself.
captureScreen={false} on the provider.
Data you publish through useVendoContext still rides; only the page snapshot
stops.
What actually reaches the model
[User]is server-trust and every turn. It comes from your own resolver on the server; the client cannot set it.- Anonymous visitors get no
[User]block. A visitor your host does not recognize has no profile to assert, so the facts seam is not even asked. They still send a situation. [Situation]is one turn only, and is never stored. It rides the request onto that turn’s prompt. The next turn on the same thread carries no situation, and nothing situation-shaped is written to the transcript.- 8 KB, enforced twice. The client truncates before sending — over budget
it retries from
<main>alone, then hard-truncates with a…[truncated]marker — and the server re-caps whatever arrives, dropping entries past the budget rather than refusing the turn. Acontextthat is not an object is ignored. - Values render as
key: value. Non-strings are JSON-encoded; every continuation line of a multi-line value is indented, so nothing in a fact or a snapshot can close its block and impersonate a prompt section.