Skip to content

feat(runtime): add synchronous useAgent() over the request store (#95) - #402

Merged
ScriptedAlchemy merged 4 commits into
mainfrom
feat/95-use-agent
Sep 3, 2026
Merged

ScriptedAlchemy merged 4 commits into
mainfrom
feat/95-use-agent

Conversation

@ScriptedAlchemy

Copy link
Copy Markdown
Owner

Summary

Closes the last #95 delivery step still owned here — "Add agent() and synchronous useAgent()" — which the #96 closing audit explicitly handed back to #95 ("useAgent(): not shipped; tracked as a migration step on the open #95").

  • @agent-bundle/runtime exports useAgent(): AgentRequestContext: the synchronous convenience over await agent(). It returns the identical handle (useAgent() === await agent() within one invocation) from the same realm-singleton AsyncLocalStorage store, so every lease rule holds unchanged — outside-invocation outside a real request, request-closed through a captured handle after completion.
  • No React dependency and no suspension: the handle is already resolved in the request's async context, so unwrapping a promise through use() would only add a suspend/retry cycle for a value that is synchronously available. The core request store stays React-independent, as Add typed Agent request context and pluggable context providers #95 requires.
  • Docs: docs/framework-mode.md and docs/entry-conventions.md record useAgent() beside agent() (async components should still prefer await agent()). Changeset: @agent-bundle/runtime minor.

Evidence

  • packages/rsc-runtime/tests/agent-request.test.ts — new "returns the identical handle synchronously through useAgent() under the same lease rules" (same object as await agent(), stable across await, outside-invocation outside a request, captured handle request-closed afterward) plus the plugin-entry re-export pin. 15/15.
  • packages/agent-bundle/tests/route-unit/render-route.test.ts — new "serves useAgent() synchronously inside a rendered Server Component": a synchronous component rendered through the real Flight renderer observes invocation kind, injected workspace, and provider fixtures via useAgent(). Route-unit pool 37/37.
  • pnpm typecheck green, pnpm lint 0/0, pnpm test:projection 63/63, integration public-api + state-packaging 14/14.

Test plan

  • request-store unit, route-unit, projection, public-api
  • CI

@changeset-bot

changeset-bot Bot commented Sep 3, 2026 •

Copy link
Copy Markdown

🦋 Changeset detected

Latest commit: 99fb862

The changes in this PR will be included in the next version bump.

This PR includes changesets to release 1 package
Name Type
@agent-bundle/runtime Patch

Not sure what this means? Click here to learn what changesets are.

Click here if you're a maintainer who wants to add another changeset to this PR

@chatgpt-codex-connector

chatgpt-codex-connector Bot commented Sep 3, 2026 •

Copy link
Copy Markdown

Codex Review Summary

This comment shows the latest Codex review activity on this pull request.

Review Status Commit Review trigger
📝 Code Review ✅ Completed 2026-09-03T07:58:03.495252Z 99fb862 Manual request
ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review" or "@codex security review".

Codex reacts with 👀 while any review is running, comments if it has suggestions, and reacts with 👍 once all reviews finish with no findings.

@pkg-pr-new

pkg-pr-new Bot commented Sep 3, 2026 •

Copy link
Copy Markdown
npm i https://pkg.pr.new/ScriptedAlchemy/agent-bundle@402
npm i https://pkg.pr.new/ScriptedAlchemy/agent-bundle/create-agent-bundle@402
npm i https://pkg.pr.new/ScriptedAlchemy/agent-bundle/@agent-bundle/runtime@402

commit: 99fb862

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: 2c91fc992d

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

Comment thread docs/framework-mode.md
Comment on lines +75 to +76
Component or utility that cannot `await` calls `useAgent()` instead; it
returns the identical handle under the same lease rules and never suspends.

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P2 Badge Update the runtime README for the shipped API

The package README still states that useAgent() “arrive[s] later” at packages/rsc-runtime/README.md:66, directly contradicting this newly documented and exported API. Package users consulting the published README may therefore conclude that useAgent() is unavailable; update that section as part of this release.

Useful? React with 👍 / 👎.

Copy link
Copy Markdown
Owner Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Fixed in bf7c0ab: the package README now documents the shipped useAgent() (same handle, same lease rules) and the provider-populated providers slot instead of saying they arrive later; only state and notices remain reserved.

Copy link
Copy Markdown
Owner Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Acknowledged — the runtime README still says useAgent() arrives later. This PR is still open, so the fix belongs on feat/95-use-agent (the #95 useAgent lane) rather than a follow-up on main: update packages/rsc-runtime/README.md alongside the docs/framework-mode.md change before merge. Tracked by the late-review sweep; not fixed on main.

@ScriptedAlchemy

Copy link
Copy Markdown
Owner Author

@codex review

@chatgpt-codex-connector

Copy link
Copy Markdown

Codex Review: Didn't find any major issues. Hooray!

Reviewed commit: bf7c0ab798

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

useAgent() returns the identical request handle await agent() resolves,
from the same realm-singleton store under the same lease rules
(outside-invocation, request-closed), so synchronous Server Components and
utilities can read request context without suspending. Route-unit and
request-store tests pin identity and lease behavior; docs record the
convenience beside agent().
@ScriptedAlchemy

Copy link
Copy Markdown
Owner Author

@codex review

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: eafe997772

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

Comment thread packages/rsc-runtime/README.md Outdated
Comment on lines +76 to +77
returns the identical handle from the same store under the same lease rules
(`outside-invocation` before a request, `request-closed` after it). `providers`

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P2 Badge Distinguish post-request calls from captured handles

Calling useAgent() after awaiting runAgentRequest() does not produce request-closed: AsyncLocalStorage.run has restored the caller's context, so currentLease() throws outside-invocation, exactly as the added test verifies. Only accessing a captured handle—or calling from an escaped continuation that retained the closed lease—produces request-closed. Because these are public typed error codes, document those scenarios separately rather than promising request-closed for every call after a request.

Useful? React with 👍 / 👎.

Copy link
Copy Markdown
Owner Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Correct — fixed in 99fb862. The README, the useAgent() docblock, and the changeset now state the two scenarios separately: a call with no request in its async context (before a request, or after runAgentRequest has settled) throws outside-invocation; a handle captured inside the request (or a continuation that retained its lease) throws request-closed once the request completes. The runtime test now asserts both codes explicitly (outside-invocation on the fresh call, request-closed on the captured handle).

@ScriptedAlchemy

Copy link
Copy Markdown
Owner Author

@codex review

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: d2cfd472fa

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

@@ -0,0 +1,5 @@
---
"@agent-bundle/runtime": patch

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P2 Badge Mark the new public export as a minor change

When Changesets produces the release, this declares only a patch even though the commit adds and documents a new public useAgent() export. That ships an additive API without the expected minor-version signal for consumers and release tooling; the existing request-store API introduction is also classified as minor in .changeset/request-store-agent.md, so this entry should use minor as well.

Useful? React with 👍 / 👎.

Copy link
Copy Markdown
Owner Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Not a defect: patch is the repository's pre-1.0 convention, adopted on main in #403. AGENTS.md ("Pre-1.0 semver: minor = breaking, patch = everything else (features included). No major before 1.0.") and .changeset/README.md ("Semver before 1.0: minor = breaking change …; patch = everything else") both classify an additive export such as useAgent() as patch. The older request-store-agent.md entry predates that convention; the changeset here was deliberately switched from minor to patch in d2cfd47 to follow it.

@ScriptedAlchemy

Copy link
Copy Markdown
Owner Author

@codex review

@chatgpt-codex-connector

Copy link
Copy Markdown

Codex Review: Didn't find any major issues. Swish!

Reviewed commit: 99fb86284c

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

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

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant