Skip to content

Pass request identity, lineage, and read-only state/notices handles to context providers #459

Description

@ScriptedAlchemy

Problem

A conventional src/providers/<name>.ts factory receives only { invocation, signal }. It cannot read the request's identity axes (host, session, workspace), its lineage, or the mounted state/notices handles, because generated scopes run providers before runAgentRequest opens the request. So a provider cannot expose a derived view of shared app state — which is exactly what examples/worktree-proximity's agent-topology provider was meant to be. The example ships it as a permanent unavailable stub, and routes read topology from (await agent()).state instead.

For the plugin use-case (a topology()/peers() accessor apps can call from any route), a provider is the natural home: it is typed by typegen, mounted once per request, and mockable through the route-unit fixture seam. Today that home cannot see the data.

Evidence (main @ 284141958)

  • packages/agent-bundle/src/routes/public.ts:95-102AgentProviderContext = { invocation, signal }; AgentProviderFactory = (context) => unknown.
  • packages/agent-bundle/src/routes/provider-execution.ts:80-101executeProviders calls each factory with { invocation, signal } only.
  • packages/agent-bundle/src/build/entry-shell.ts:300-332 — routed CLI: requestBindings() (state + noticeLedger) exist at :311, providers execute at :312-316, then runAgentRequest({ …, noticeLedger, providers, state }) at :317-332. Same ordering for the rendered-route worker at :508-527.
  • docs/entry-conventions.md:85, 217 — public contract documents the factory as receiving { invocation, signal }.
  • examples/worktree-proximity/src/providers/agent-topology.ts:6-12 — returns { state: 'unavailable', reason: 'Topology snapshots are available only from the mounted request state handle; providers execute before that handle is mounted.' }.
  • examples/worktree-proximity/README.md:42-43, 61-64: "providers execute before request state is mounted, so this provider reports an honest unavailable result and routes read snapshots from (await agent()).state.read() instead."
  • Add typed Agent request context and pluggable context providers #95's sketch had resolve(request: AgentRequest); what landed (feat(routes): execute conventional context providers in generated request scopes (#95 remainder) #255) is narrower. Add typed Agent request context and pluggable context providers #95 also states providers "do not implicitly observe events or mutate durable state" — this proposal keeps that: read access only.

Proposed shape (small)

Widen AgentProviderContext with the read-only parts of the request, and open the request before the provider loop:

interface AgentProviderContext {
  readonly invocation: AgentProviderInvocation;
  readonly signal: AbortSignal;
  // new, all read-only
  readonly host: Observed<AgentHostIdentity>;
  readonly session: Observed<AgentSessionIdentity>;
  readonly workspace: Observed<AgentWorkspaceIdentity>;
  readonly lineage: Observed<AgentLineage>;
  readonly state?: Pick<AgentStateHandle, 'read'>;
  readonly notices?: Pick<AgentNoticesHandle, 'inbox'>;
}

Implementation sketch: in the generated scopes, run runAgentRequest with providers as a lazily-filled frozen record (or run the provider loop as the first step inside the request and freeze providers afterwards), so factories can call the same handles routes get. dispatch/publish stay off the provider surface (#95 stance). Providers that already destructure { invocation, signal } are unaffected.

Out of scope / related

Acceptance

examples/worktree-proximity/src/providers/agent-topology.ts returns an available snapshot read from context.state.read() (or context.lineage) instead of the stub; src/mcp/coordinator/tools/status.tsx reads providers.agentTopology rather than withTopology(...); route-unit tests keep passing with the fixture seam (context.providers) and the cross-process suite packages/agent-bundle/tests/worktree-proximity-journeys.test.ts still shows exact-revision equality across processes. A framework test in entry-shell.test.ts proves a provider observes lineage and a read-only state on every generated surface.

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    enhancementNew feature or requestmeta-frameworkAgent Bundle compiler-coupled meta-frameworkruntimeRuntime context, state, rendering, or execution

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions