The Session Service Your Agent Can't Skip: Identity, Idempotency, and Real Cancel
Without these mechanisms, agents duplicate work on retry, leak cross-tenant data via model-injected IDs, and burn money after users hit cancel. These are the failure modes that make production agents untrustworthy.
Production agent failures rarely come from the model itself. They come from identity passed as model parameters, sessions kept in memory instead of a database, double-clicks spawning two runs, and cancellation that only closes the SSE stream. The fix is a dedicated session service that owns conversation persistence, Run lifecycle, and a trusted RequestContext built from login state at the entry layer.
The article walks through the schema and flow: a RequestContext with tenant, user, roles, and scopes that every tool call must use; a runs table with a unique constraint on (tenant_id, idempotency_key) so one click creates one task; and a cancel path that writes cancel_requested, calls abort(), and distinguishes cancel_requested from cancelled. It also stresses that isolation must be enforced in queries, not filtered after fetch, and that keys never enter prompts or chat history.
Agent frameworks like LangGraph track graph execution but not the operational concerns of identity, persistence, and cancellation, so a separate session service is necessary regardless of framework.
Isolate before query is a sharp principle: filtering after retrieval still exposes data to logs, cache, and model context, making it a leak vector even if the final response is safe.
Trusting model-provided userId is a classic prompt-injection hazard; the security boundary is an explicit server-side context, not the model's compliance.