Pair agentic contexts with profile attributes in the Vercel AI tutorial - #1896
Pair agentic contexts with profile attributes in the Vercel AI tutorial#1896jborlase-snowplow wants to merge 7 commits into
Conversation
The signals-ai-agent-context tutorial pre-dates agentic contexts and hand-rolled what the feature now provides: build-ai-integration.md composed a "Real-Time User Context" markdown block from attribute values via a custom formatAttributes() helper. Retrofit it as a pairing rather than a replacement. The tutorial now fetches both kinds of Signals context and lands both in the system prompt, and explains when each is the right tool: - user-level profile attributes (computed aggregates, via the service) - in-session agentic context (raw recent activity as an LLM-ready narrative, via getAgenticContext with format: "narrative") Changes: - configure-signals.md: add an agentic-context definition step with Console and Python SDK tabs, selecting event_name and page_urlpath so the narrative's table columns populate - build-ai-integration.md: replace formatAttributes() for session activity with getAgenticContext(); both fetches now run in parallel and degrade independently. The narrative example is a real capture - introduction.md: describe both context types and both fetches in the component flow; add the missing free-trial note; point the prerequisite at /docs/signals/setup/ instead of the credentials page - test.md: verify both prompt sections separately; add the Snowplow Inspector step - setup.md: correct the Signals base URL placeholder - conclusion.md: list the agentic context in the summary Verified against a live trial org: the Python SDK block publishes as written, and a scaffolded Next.js app composes a prompt containing both the profile attributes and the [START CONTEXT] narrative. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
A Signals service returns a key for every attribute it serves, with a
null value until the session has produced data. The guard checked only
for a missing or empty object:
if (!attributes || Object.keys(attributes).length === 0)
Neither branch fires on {"page_views_count": null, ...} — the object is
present and its key count is non-zero — so the guard never fired and the
agent injected "page_views_count: null" into the system prompt as though
it were a fact about the user.
Filter the null values out before testing for emptiness, and explain the
behavior on the page so a reader who sees nulls on their first run knows
what they are looking at.
Also fix the profile JSON example, which showed "unique_pages_viewed": 5.
The page's own attribute table and the sibling signals-google-adk-agent
tutorial both describe that attribute as a list of URLs, so the scalar was
wrong. The other values now match the real capture the page already shows
for the narrative.
Verified against a live trial org with a fresh, never-seen session
identifier: the old guard emitted a list of nulls, the new one emits
nothing, and a session with five real page views is unaffected.
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
vercel-architecture.png showed only the attributes-to-prompt flow, so it contradicted the retrofit: the tutorial now fetches profile attributes and the agentic-context narrative, and lands both in the system prompt. There is no design source to regenerate the PNG from, and the style guide prefers Mermaid for architecture visuals, so the diagram is now inline. The flowchart covers both fetches, with the /api/chat route calling getServiceAttributes against the service and getAgenticContext in narrative format against the agentic context. Delete the PNG, which nothing else references. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
The Console tab was written from the prose in docs/signals/agentic-contexts, which describes the form's fields rather than quoting their labels. That prose had been turned into literal control names that do not exist. Corrected against a live-Console walk: - it is not a stepped wizard but one scrolling Create context form, with Details, Prompt, Lookback Window, and Events and Properties sections - the field is Prompt, not Prompt instructions - the field is Primary owner, and Console fills it in for you, not Owner - Lookback Window takes Max events and Max age with a unit dropdown, and restates the resulting window below the fields - Events and Properties has Add event and Add property buttons - the create form saves a draft; Publish and Edit live on the details page The create button on the list page and the create form's submit button are deliberately not named, because neither label has been seen. Also carry over the publish() warning from the signals-agentic-contexts tutorial. In snowplow-signals 0.4.6 both publish() and unpublish() fail with a 409 for a name that already exists, so a Python-tab reader who edits and re-publishes hits it with no warning otherwise. Screenshots of this flow still need a browser; two markers show where they go. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Deploying with
|
| Status | Name | Latest Commit | Preview URL | Updated (UTC) |
|---|---|---|---|---|
| ✅ Deployment successful! View logs |
documentation | e69dbaf | Commit Preview URL Branch Preview URL |
Jul 31 2026, 03:50 PM |
Documentation style reviewScope: writing quality, style guide compliance, terminology, structure, frontmatter, links, and MDX components. Overall this is a well-written expansion — the prose is clear, active, and free of marketing language, and the swap from the PNG architecture diagram to Mermaid follows the style guide's preference for Mermaid architecture visuals. Both new external links ( A few things to fix: 1. TODO placeholders left in published content
{/* TODO(pending-browser): screenshot of the Create context form, Details and Prompt sections */}
{/* TODO(pending-browser): screenshot of the Lookback Window and Events and Properties sections */}These are the only 2. Wrong admonition type for the
|
Walked the attribute-group, service, and agentic-context flows in the live Console and captured the two screenshots the Console tab was missing. Blocking fix: the service name was invalid. Signals names take letters, numbers, and underscores only, so `web-agent-context` was rejected outright with "Name can only contain letters, numbers, and underscores". A reader following the Console tab could not get past this step. Renamed to `web_agent_context` in configure-signals.md, build-ai-integration.md, and conclusion.md, which also matches the sibling signals-google-adk-agent tutorial. The constraint is now stated on the page. Removed the Run Preview instructions from configure-signals.md and test.md. No such control exists in the attribute-group create form, edit form, or details page, in either draft or published state. Corrected against what the Console actually shows: - the sidebar reads Attribute groups and the field is Attribute key, both sentence case - the Basic Web template is applied with a Use button on its card, and its four attributes are now documented with the aggregation and property behind each one. unique_pages_viewed is a unique list of page_url, so it holds full URLs rather than paths - the create-context form submits with Create, and saves with a Draft status, not a Not Published badge - publishing an agentic context asks for confirmation - the Attribute groups picker on the service form lists published groups only, so publishing first is required rather than merely tidy Screenshots show the reader-facing resource name, so nothing on screen contradicts the instructions. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
|
Pushed
Remaining known gap (unchanged): the model call itself needs 🤖 Generated with Claude Code |
Remove the SDK bug warning from the Python tab and teach the Console edit-and-publish flow instead, rewrite the null-attribute guidance as a plain statement of product behavior, and drop references to captures from our own runs.
|
Pushed 🤖 Generated with Claude Code |
Featured the AI-assisted route: a new "Ask the Snowplow Assistant" section carries a copy/paste prompt that creates and publishes the attribute group, service, and agentic context, ahead of the manual Console steps. Trimmed to the owner's lens: dropped the Micro/"full pipeline" panel in favour of a minimal prerequisite, converted the "Existing projects" and model-provider panels to prose, cut rationale that restated the attributes-vs-narrative contrast, and reframed the verification steps positively instead of as failure lists. Load-bearing constraints verified by the earlier live-Console run are kept as positive prose: the page_url/page_urlpath contrast, the published-groups-only picker, the narrative column mapping, and the page-ping exclusion. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
|
Pushed 🤖 Generated with Claude Code |
What changed?
Retrofits
tutorials/signals-ai-agent-context/to use agentic contexts natively: an agentic-context definition step (Console + Python SDK tabs), andlib/signals-context.tsnow fetches BOTH the profile attributes (service) and the in-session narrative (getAgenticContext,format: "narrative") viaPromise.allSettled, landing both in the system prompt with when-to-use-which guidance. Replaces the hand-rolledformatAttributes()block for session activity while keeping attributes as the computed-profile complement (per product direction). Also: fixes a real guard bug (a fresh session returns every attribute asnull— the object is truthy, so the old empty-check never fired andpage_views_count: nullreached the prompt), and replaces the stale architecture PNG with a Mermaid diagram covering both fetches.Why?
The flagship agent tutorial pre-dated agentic contexts and hand-rolled what the feature now provides.
Reviewer guidance
AI_GATEWAY_API_KEY) wasn't available; no provider was substituted.format: "narrative"output leads with the configured prompt line before[START CONTEXT]; the applications docs page omits it — needs its own fix.🤖 Generated with Claude Code