feat(runtime,cli,react): add typed SSE output schema support#875
feat(runtime,cli,react): add typed SSE output schema support#875
Conversation
Add support for typed SSE routes with proper output schema inference:
- runtime: Add SSEOptions<TOutput> interface and sse({ output }, handler) overload
- cli: Extract output schema from sse({ output: schema }) during route discovery
- react: Add TOutput generic override to useEventStream hook
- tests: Add comprehensive tests for SSE schema extraction and registry generation
This enables full type flow from SSE route definition to useEventStream:
- sse({ output: MySchema }, handler) -> routes.ts -> useEventStream typed data
Also supports type override escape hatch:
- useEventStream<'/path', MyType>('/path') when registry has outputSchema: never
Closes #855
📝 WalkthroughWalkthroughCLI now extracts SSE route output schemas from Changes
🚥 Pre-merge checks | ✅ 3✅ Passed checks (3 passed)
✏️ Tip: You can configure your own custom pre-merge checks in the settings. 📜 Recent review detailsConfiguration used: Organization UI Review profile: CHILL Plan: Pro 📒 Files selected for processing (1)
🧰 Additional context used📓 Path-based instructions (2)**/*.{ts,tsx}📄 CodeRabbit inference engine (AGENTS.md)
Files:
packages/cli/**/*.ts📄 CodeRabbit inference engine (packages/cli/AGENTS.md)
Files:
🧠 Learnings (1)📚 Learning: 2025-12-21T00:31:41.858ZApplied to files:
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (7)
🔇 Additional comments (4)
✏️ Tip: You can disable this entire section by setting Comment |
📦 Canary Packages Publishedversion: PackagesInstallAdd to your {
"dependencies": {
"@agentuity/auth": "https://agentuity-sdk-objects.t3.storageapi.dev/npm/1.0.1-70bf225/agentuity-auth-1.0.1-70bf225.tgz",
"@agentuity/cli": "https://agentuity-sdk-objects.t3.storageapi.dev/npm/1.0.1-70bf225/agentuity-cli-1.0.1-70bf225.tgz",
"@agentuity/react": "https://agentuity-sdk-objects.t3.storageapi.dev/npm/1.0.1-70bf225/agentuity-react-1.0.1-70bf225.tgz",
"@agentuity/core": "https://agentuity-sdk-objects.t3.storageapi.dev/npm/1.0.1-70bf225/agentuity-core-1.0.1-70bf225.tgz",
"@agentuity/server": "https://agentuity-sdk-objects.t3.storageapi.dev/npm/1.0.1-70bf225/agentuity-server-1.0.1-70bf225.tgz",
"@agentuity/schema": "https://agentuity-sdk-objects.t3.storageapi.dev/npm/1.0.1-70bf225/agentuity-schema-1.0.1-70bf225.tgz",
"@agentuity/runtime": "https://agentuity-sdk-objects.t3.storageapi.dev/npm/1.0.1-70bf225/agentuity-runtime-1.0.1-70bf225.tgz",
"@agentuity/drizzle": "https://agentuity-sdk-objects.t3.storageapi.dev/npm/1.0.1-70bf225/agentuity-drizzle-1.0.1-70bf225.tgz",
"@agentuity/frontend": "https://agentuity-sdk-objects.t3.storageapi.dev/npm/1.0.1-70bf225/agentuity-frontend-1.0.1-70bf225.tgz",
"@agentuity/postgres": "https://agentuity-sdk-objects.t3.storageapi.dev/npm/1.0.1-70bf225/agentuity-postgres-1.0.1-70bf225.tgz",
"@agentuity/workbench": "https://agentuity-sdk-objects.t3.storageapi.dev/npm/1.0.1-70bf225/agentuity-workbench-1.0.1-70bf225.tgz",
"@agentuity/opencode": "https://agentuity-sdk-objects.t3.storageapi.dev/npm/1.0.1-70bf225/agentuity-opencode-1.0.1-70bf225.tgz",
"@agentuity/evals": "https://agentuity-sdk-objects.t3.storageapi.dev/npm/1.0.1-70bf225/agentuity-evals-1.0.1-70bf225.tgz"
}
}Or install directly: bun add https://agentuity-sdk-objects.t3.storageapi.dev/npm/1.0.1-70bf225/agentuity-auth-1.0.1-70bf225.tgz
bun add https://agentuity-sdk-objects.t3.storageapi.dev/npm/1.0.1-70bf225/agentuity-cli-1.0.1-70bf225.tgz
bun add https://agentuity-sdk-objects.t3.storageapi.dev/npm/1.0.1-70bf225/agentuity-react-1.0.1-70bf225.tgz
bun add https://agentuity-sdk-objects.t3.storageapi.dev/npm/1.0.1-70bf225/agentuity-core-1.0.1-70bf225.tgz
bun add https://agentuity-sdk-objects.t3.storageapi.dev/npm/1.0.1-70bf225/agentuity-server-1.0.1-70bf225.tgz
bun add https://agentuity-sdk-objects.t3.storageapi.dev/npm/1.0.1-70bf225/agentuity-schema-1.0.1-70bf225.tgz
bun add https://agentuity-sdk-objects.t3.storageapi.dev/npm/1.0.1-70bf225/agentuity-runtime-1.0.1-70bf225.tgz
bun add https://agentuity-sdk-objects.t3.storageapi.dev/npm/1.0.1-70bf225/agentuity-drizzle-1.0.1-70bf225.tgz
bun add https://agentuity-sdk-objects.t3.storageapi.dev/npm/1.0.1-70bf225/agentuity-frontend-1.0.1-70bf225.tgz
bun add https://agentuity-sdk-objects.t3.storageapi.dev/npm/1.0.1-70bf225/agentuity-postgres-1.0.1-70bf225.tgz
bun add https://agentuity-sdk-objects.t3.storageapi.dev/npm/1.0.1-70bf225/agentuity-workbench-1.0.1-70bf225.tgz
bun add https://agentuity-sdk-objects.t3.storageapi.dev/npm/1.0.1-70bf225/agentuity-opencode-1.0.1-70bf225.tgz
bun add https://agentuity-sdk-objects.t3.storageapi.dev/npm/1.0.1-70bf225/agentuity-evals-1.0.1-70bf225.tgz |
There was a problem hiding this comment.
Actionable comments posted: 3
Caution
Some comments are outside the diff and can’t be posted inline due to platform limitations.
⚠️ Outside diff range comments (1)
packages/react/src/eventstream.ts (1)
85-151:⚠️ Potential issue | 🟠 MajorAdd an explicit SSR guard in the hook.
useEventStreamrunsEventStreamManager.connect()in a useEffect without checking if code is executing in the browser. SinceEventStreamManagerinstantiatesnew EventSource()(a browser-only API) during initialization, this will throw a ReferenceError during server-side rendering. Add a browser check to prevent manager initialization on the server.🛡️ Suggested SSR guard
export function useEventStream<TRoute extends SSERouteKey, TOutput = SSERouteOutput<TRoute>>( route: TRoute, options?: EventStreamOptions ): { @@ const context = useContext(AgentuityContext); + const isBrowser = typeof window !== 'undefined'; @@ - const esUrl = useMemo( - () => buildUrl(context.baseUrl!, route as string, options?.subpath, options?.query), - [context.baseUrl, route, options?.subpath, options?.query] - ); + const esUrl = useMemo( + () => + isBrowser + ? buildUrl(context.baseUrl!, route as string, options?.subpath, options?.query) + : '', + [isBrowser, context.baseUrl, route, options?.subpath, options?.query] + ); @@ useEffect(() => { + if (!isBrowser || !esUrl) return; const manager = new EventStreamManager<TOutput>({ url: esUrl,
🤖 Fix all issues with AI agents
In `@packages/cli/src/cmd/build/ast.ts`:
- Around line 2017-2032: After extracting sseSchemaInfo via
extractSSEOutputSchema, run the same export validation used for validator
schemas (call validateSchemaExports with the extracted output schema variable
and current file/module context) before assigning
routeConfig.outputSchemaVariable; if validateSchemaExports reports the schema is
locally defined but not exported, surface that error (or skip assignment) so
registry generation won't try to import a non-exported local schema. Use the
same inputs you use for validator validation and keep using importInfoMap to
detect imported schemas (i.e., only skip validateSchemaExports when
importInfoMap already has an entry for sseSchemaInfo.outputSchemaVariable).
In `@packages/react/src/eventstream.ts`:
- Around line 112-115: The useMemo for esUrl (which calls buildUrl in
eventstream.ts) currently depends on the options.query object reference and can
miss in-place mutations; update the dependency array for the useMemo that
defines esUrl to include options?.query?.toString() (i.e., track the string
representation) instead of options?.query so the memo recomputes when
URLSearchParams are mutated, keeping other deps (context.baseUrl, route,
options?.subpath) the same.
In `@packages/runtime/src/handlers/sse.ts`:
- Around line 204-211: The sse helper currently uses a non-null assertion on
maybeHandler which lets calls like sse({ output }) produce a cryptic runtime
error; update the sse function to explicitly check whether handler is undefined
after deriving it from handlerOrOptions/maybeHandler and, if missing, throw a
clear StructuredError (or the project's standard error type) with a descriptive
message explaining that an SSE handler was not provided; reference the sse
function, the handlerOrOptions/maybeHandler variables, and the SSEHandler type
when locating where to add this guard and ensure the thrown error follows the
project's StructuredError shape.
📜 Review details
Configuration used: Organization UI
Review profile: CHILL
Plan: Pro
📒 Files selected for processing (7)
packages/cli/src/cmd/build/ast.tspackages/cli/test/ast.test.tspackages/cli/test/cmd/build/vite/registry-generator.test.tspackages/react/src/eventstream.tspackages/runtime/src/handlers/index.tspackages/runtime/src/handlers/sse.tspackages/runtime/src/index.ts
🧰 Additional context used
📓 Path-based instructions (8)
**/*.{ts,tsx}
📄 CodeRabbit inference engine (AGENTS.md)
**/*.{ts,tsx}: Use Prettier formatter with tabs (width 3), single quotes, and semicolons for TypeScript files
Use TypeScript strict mode with ESNext target and bundler moduleResolution
UseStructuredErrorfrom@agentuity/corefor error handling
Files:
packages/runtime/src/handlers/index.tspackages/runtime/src/index.tspackages/cli/test/cmd/build/vite/registry-generator.test.tspackages/cli/test/ast.test.tspackages/react/src/eventstream.tspackages/cli/src/cmd/build/ast.tspackages/runtime/src/handlers/sse.ts
packages/runtime/**/*.{ts,tsx}
📄 CodeRabbit inference engine (packages/runtime/AGENTS.md)
packages/runtime/**/*.{ts,tsx}: Every agent handler receivesAgentContextwith logger, tracer, storage (kv, vector, stream), and auth properties
Usectx.loggerinstead ofconsole.logfor observability
Files:
packages/runtime/src/handlers/index.tspackages/runtime/src/index.tspackages/runtime/src/handlers/sse.ts
packages/*/src/index.ts
📄 CodeRabbit inference engine (AGENTS.md)
Use named exports from package
index.tsfile as the public API
Files:
packages/runtime/src/index.ts
packages/*/test/**/*.{ts,tsx}
📄 CodeRabbit inference engine (AGENTS.md)
packages/*/test/**/*.{ts,tsx}: Place test files intest/folder (never insrc/or__tests__/)
Import from../src/in test files to reference source code
Use@agentuity/test-utilsfor mocks and test helpers
Files:
packages/cli/test/cmd/build/vite/registry-generator.test.tspackages/cli/test/ast.test.ts
packages/cli/**/*.ts
📄 CodeRabbit inference engine (packages/cli/AGENTS.md)
Use
Bun.file(f).exists()instead ofexistsSync(f)for file existence checks
Files:
packages/cli/test/cmd/build/vite/registry-generator.test.tspackages/cli/test/ast.test.tspackages/cli/src/cmd/build/ast.ts
packages/react/**/*.{ts,tsx}
📄 CodeRabbit inference engine (packages/react/AGENTS.md)
packages/react/**/*.{ts,tsx}: All hooks must be used withinAgentuityProvider
UseuseAPI('GET /route')for GET requests which auto-execute and returnrefetch()
UseuseAPI('POST/PUT/PATCH/DELETE /route')with manual invocation viainvoke()for mutation requests
Types should be inferred from generated registries (RouteRegistry, etc.) rather than manually defined
UseuseJsonMemo(value)for deep equality memoization of complex objects and arrays
UsewithPageTracking(Component, pageName)HOC for automatic page tracking in components
Files:
packages/react/src/eventstream.ts
packages/react/src/**/*.ts?(x)
📄 CodeRabbit inference engine (packages/react/AGENTS.md)
packages/react/src/**/*.ts?(x): Include SSR guards in all hooks to ensure server-side rendering compatibility
Runtime environment is browser only - do not use Node.js APIs in hook implementations
Files:
packages/react/src/eventstream.ts
packages/react/src/eventstream.ts?(x)
📄 CodeRabbit inference engine (packages/react/AGENTS.md)
Configure
useEventStreamwith auto-reconnection on connection loss and JSON memoization fordata
Files:
packages/react/src/eventstream.ts
🧠 Learnings (2)
📚 Learning: 2025-12-13T14:15:18.261Z
Learnt from: jhaynie
Repo: agentuity/sdk PR: 168
File: packages/runtime/src/session.ts:536-546
Timestamp: 2025-12-13T14:15:18.261Z
Learning: The agentuity/runtime package is Bun-only; during code reviews, do not replace Bun-native APIs (e.g., Bun.CryptoHasher, Bun.serve, and other Bun namespace APIs) with Node.js alternatives. Review changes with the assumption that runtime runs on Bun, and ensure any edits preserve Bun compatibility and do not introduce Node.js-specific fallbacks. Apply this guidance broadly to files under packages/runtime (e.g., packages/runtime/src/...); if there are conditional environment checks, document why Bun is required and avoid dereferencing Bun-only APIs in non-Bun contexts.
Applied to files:
packages/runtime/src/handlers/index.tspackages/runtime/src/index.tspackages/runtime/src/handlers/sse.ts
📚 Learning: 2025-12-21T00:31:41.858Z
Learnt from: jhaynie
Repo: agentuity/sdk PR: 274
File: packages/cli/src/cmd/build/vite/server-bundler.ts:12-41
Timestamp: 2025-12-21T00:31:41.858Z
Learning: In Bun runtime, BuildMessage and ResolveMessage are global types and are not exported from the bun module. Do not import { BuildMessage } from 'bun' or similar; these types are available globally and should be used without import. This applies to all TypeScript files that target the Bun runtime within the repository.
Applied to files:
packages/runtime/src/handlers/index.tspackages/runtime/src/index.tspackages/cli/test/cmd/build/vite/registry-generator.test.tspackages/cli/test/ast.test.tspackages/react/src/eventstream.tspackages/cli/src/cmd/build/ast.tspackages/runtime/src/handlers/sse.ts
🧬 Code graph analysis (2)
packages/cli/test/cmd/build/vite/registry-generator.test.ts (2)
packages/cli/src/cmd/build/vite/route-discovery.ts (1)
RouteInfo(28-48)packages/cli/src/cmd/build/vite/registry-generator.ts (1)
generateRouteRegistry(589-1218)
packages/cli/test/ast.test.ts (1)
packages/cli/src/cmd/build/ast.ts (1)
parseRoute(1406-2080)
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (9)
- GitHub Check: Playwright E2E Smoke Test
- GitHub Check: Sandbox CLI Tests
- GitHub Check: SDK Integration Test Suite
- GitHub Check: Queue SDK Tests
- GitHub Check: Template Integration Tests
- GitHub Check: Framework Integration Tests (TanStack & Next.js)
- GitHub Check: Cloud Deployment Tests
- GitHub Check: Queue CLI Tests
- GitHub Check: Build
🔇 Additional comments (5)
packages/runtime/src/handlers/sse.ts (1)
64-185: Typed SSE options + docs are clear.The new SSEOptions interface and examples make the typing intent easy to follow and align well with the new overloads.
packages/runtime/src/handlers/index.ts (1)
2-10: Re-export keeps the public API in sync.Nice to see SSEOptions exposed alongside the existing SSE types.
packages/runtime/src/index.ts (1)
80-94: Public surface is consistent with handler exports.SSEOptions is now correctly reachable from the main runtime index.
packages/cli/test/ast.test.ts (1)
471-642: Solid coverage for SSE output schema extraction.The test matrix hits inline, imported, fallback, and precedence paths—nice coverage.
packages/cli/test/cmd/build/vite/registry-generator.test.ts (1)
2062-2189: Great end-to-end coverage for SSE registry typing.These tests validate typed SSE outputs, never fallbacks, RPC registry wiring, and import tracking—exactly what
#855needed.
✏️ Tip: You can disable this entire section by setting review_details to false in your review settings.
- cli: Add validateSchemaExports for SSE output schemas (locally defined must be exported) - react: Track query string representation to detect URLSearchParams mutations - runtime: Add SSEHandlerMissingError guard when handler is undefined - test: Add test for non-exported local schema error, fix existing test
There was a problem hiding this comment.
Actionable comments posted: 2
Caution
Some comments are outside the diff and can’t be posted inline due to platform limitations.
⚠️ Outside diff range comments (1)
packages/react/src/eventstream.ts (1)
122-156:⚠️ Potential issue | 🟡 MinorAdd an explicit SSR guard for the hook.
The
useEventStreamhook instantiatesEventStreamManagerin auseEffectwithout an explicit SSR guard. WhileuseEffectdoesn't run on the server, the coding guidelines require explicit SSR guards in all hooks to ensure server-side rendering compatibility.🛡️ Suggested SSR-safe guard
+ const isSSR = typeof window === 'undefined'; const esUrl = useMemo( - () => buildUrl(context.baseUrl!, route as string, options?.subpath, options?.query), + () => + isSSR + ? '' + : buildUrl(context.baseUrl!, route as string, options?.subpath, options?.query), // biome-ignore lint/correctness/useExhaustiveDependencies: queryString tracks URLSearchParams mutations that options?.query reference wouldn't catch - [context.baseUrl, route, options?.subpath, options?.query, queryString] + [isSSR, context.baseUrl, route, options?.subpath, options?.query, queryString] ); useEffect(() => { + if (isSSR || !esUrl) return; const manager = new EventStreamManager<TOutput>({ url: esUrl, callbacks: {
🤖 Fix all issues with AI agents
In `@packages/cli/src/cmd/build/ast.ts`:
- Around line 2017-2038: Update the comment above the SSE extraction block to
reflect that while SSE routes can accept schemas via sse({ output: schema },
handler) (see sseCallExpr and extractSSEOutputSchema), locally-defined schema
variables (sseSchemaInfo.outputSchemaVariable) must be exported and are
validated by validateSchemaExports; rephrase the line that currently says
"without requiring exported schemas" to indicate that imported schemas need not
be exported but locally-defined schemas are required to be exported and will be
validated.
- Around line 1249-1293: The loop in extractSSEOutputSchema assumes every entry
in objExpr.properties is a Property with key/value, which will throw for
SpreadElement entries; update the loop to skip any property whose node.type !==
'Property' before accessing prop.key/prop.value (i.e., guard prop.type ===
'Property'), then continue processing only Property nodes and perform the
existing key extraction and output check on those nodes.
📜 Review details
Configuration used: Organization UI
Review profile: CHILL
Plan: Pro
📒 Files selected for processing (4)
packages/cli/src/cmd/build/ast.tspackages/cli/test/ast.test.tspackages/react/src/eventstream.tspackages/runtime/src/handlers/sse.ts
🧰 Additional context used
📓 Path-based instructions (7)
**/*.{ts,tsx}
📄 CodeRabbit inference engine (AGENTS.md)
**/*.{ts,tsx}: Use Prettier formatter with tabs (width 3), single quotes, and semicolons for TypeScript files
Use TypeScript strict mode with ESNext target and bundler moduleResolution
UseStructuredErrorfrom@agentuity/corefor error handling
Files:
packages/cli/test/ast.test.tspackages/runtime/src/handlers/sse.tspackages/cli/src/cmd/build/ast.tspackages/react/src/eventstream.ts
packages/*/test/**/*.{ts,tsx}
📄 CodeRabbit inference engine (AGENTS.md)
packages/*/test/**/*.{ts,tsx}: Place test files intest/folder (never insrc/or__tests__/)
Import from../src/in test files to reference source code
Use@agentuity/test-utilsfor mocks and test helpers
Files:
packages/cli/test/ast.test.ts
packages/cli/**/*.ts
📄 CodeRabbit inference engine (packages/cli/AGENTS.md)
Use
Bun.file(f).exists()instead ofexistsSync(f)for file existence checks
Files:
packages/cli/test/ast.test.tspackages/cli/src/cmd/build/ast.ts
packages/runtime/**/*.{ts,tsx}
📄 CodeRabbit inference engine (packages/runtime/AGENTS.md)
packages/runtime/**/*.{ts,tsx}: Every agent handler receivesAgentContextwith logger, tracer, storage (kv, vector, stream), and auth properties
Usectx.loggerinstead ofconsole.logfor observability
Files:
packages/runtime/src/handlers/sse.ts
packages/react/**/*.{ts,tsx}
📄 CodeRabbit inference engine (packages/react/AGENTS.md)
packages/react/**/*.{ts,tsx}: All hooks must be used withinAgentuityProvider
UseuseAPI('GET /route')for GET requests which auto-execute and returnrefetch()
UseuseAPI('POST/PUT/PATCH/DELETE /route')with manual invocation viainvoke()for mutation requests
Types should be inferred from generated registries (RouteRegistry, etc.) rather than manually defined
UseuseJsonMemo(value)for deep equality memoization of complex objects and arrays
UsewithPageTracking(Component, pageName)HOC for automatic page tracking in components
Files:
packages/react/src/eventstream.ts
packages/react/src/**/*.ts?(x)
📄 CodeRabbit inference engine (packages/react/AGENTS.md)
packages/react/src/**/*.ts?(x): Include SSR guards in all hooks to ensure server-side rendering compatibility
Runtime environment is browser only - do not use Node.js APIs in hook implementations
Files:
packages/react/src/eventstream.ts
packages/react/src/eventstream.ts?(x)
📄 CodeRabbit inference engine (packages/react/AGENTS.md)
Configure
useEventStreamwith auto-reconnection on connection loss and JSON memoization fordata
Files:
packages/react/src/eventstream.ts
🧠 Learnings (2)
📚 Learning: 2025-12-21T00:31:41.858Z
Learnt from: jhaynie
Repo: agentuity/sdk PR: 274
File: packages/cli/src/cmd/build/vite/server-bundler.ts:12-41
Timestamp: 2025-12-21T00:31:41.858Z
Learning: In Bun runtime, BuildMessage and ResolveMessage are global types and are not exported from the bun module. Do not import { BuildMessage } from 'bun' or similar; these types are available globally and should be used without import. This applies to all TypeScript files that target the Bun runtime within the repository.
Applied to files:
packages/cli/test/ast.test.tspackages/runtime/src/handlers/sse.tspackages/cli/src/cmd/build/ast.tspackages/react/src/eventstream.ts
📚 Learning: 2025-12-13T14:15:18.261Z
Learnt from: jhaynie
Repo: agentuity/sdk PR: 168
File: packages/runtime/src/session.ts:536-546
Timestamp: 2025-12-13T14:15:18.261Z
Learning: The agentuity/runtime package is Bun-only; during code reviews, do not replace Bun-native APIs (e.g., Bun.CryptoHasher, Bun.serve, and other Bun namespace APIs) with Node.js alternatives. Review changes with the assumption that runtime runs on Bun, and ensure any edits preserve Bun compatibility and do not introduce Node.js-specific fallbacks. Apply this guidance broadly to files under packages/runtime (e.g., packages/runtime/src/...); if there are conditional environment checks, document why Bun is required and avoid dereferencing Bun-only APIs in non-Bun contexts.
Applied to files:
packages/runtime/src/handlers/sse.ts
🧬 Code graph analysis (2)
packages/cli/test/ast.test.ts (1)
packages/cli/src/cmd/build/ast.ts (1)
parseRoute(1406-2093)
packages/react/src/eventstream.ts (2)
packages/frontend/src/eventstream-manager.ts (1)
EventStreamManager(59-203)packages/frontend/src/url.ts (1)
buildUrl(3-19)
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (8)
- GitHub Check: Framework Integration Tests (TanStack & Next.js)
- GitHub Check: Build
- GitHub Check: Cloud Deployment Tests
- GitHub Check: Sandbox CLI Tests
- GitHub Check: Template Integration Tests
- GitHub Check: SDK Integration Test Suite
- GitHub Check: Playwright E2E Smoke Test
- GitHub Check: Pack & Upload
🔇 Additional comments (6)
packages/cli/test/ast.test.ts (1)
471-671: Solid SSE output schema extraction coverage.The new suite hits the key extraction paths (inline, imported, fallback, precedence, and validation errors) and should protect the new behavior well.
packages/cli/src/cmd/build/ast.ts (1)
1595-1861: Good capture of the SSE call expression for downstream schema extraction.The sse call tracking is straightforward and makes the later schema extraction logic much cleaner.
packages/react/src/eventstream.ts (2)
52-106: Typed output generic propagates cleanly through hook state and manager types.The defaulted
TOutputkeeps inference intact while allowing overrides.
112-119: Query string mutation tracking looks good.Using the string representation in dependencies closes the URLSearchParams mutation gap.
packages/runtime/src/handlers/sse.ts (2)
9-108: SSEOptions + StructuredError guard definition is clear and well-documented.The documentation makes the type-only intent explicit, which should reduce runtime expectations.
201-227: Handler validation in sse() is a solid safety improvement.Failing fast with a clear error message will save debugging time for misuses.
✏️ Tip: You can disable this entire section by setting review_details to false in your review settings.
- Update comment to clarify that locally-defined schemas must be exported - Add guard for SpreadElement in extractSSEOutputSchema loop - Skip non-Property nodes when iterating object expression properties
There was a problem hiding this comment.
Actionable comments posted: 1
🤖 Fix all issues with AI agents
In `@packages/cli/src/cmd/build/ast.ts`:
- Around line 2022-2051: The current logic only sets
routeConfig.outputSchemaVariable from SSE when routeConfig.outputSchemaVariable
is falsy, so validator-provided output masks sse({ output }) for SSE routes;
change the block that handles sseCallExpr to always consider the sseSchemaInfo
when sseCallExpr is present: call extractSSEOutputSchema(sseCallExpr) and if
sseSchemaInfo.outputSchemaVariable is set, override
routeConfig.outputSchemaVariable (and set
routeConfig.outputSchemaImportPath/outputSchemaImportedName from importInfoMap
lookup) or, if you prefer surfacing conflicts, detect when an existing
routeConfig.outputSchemaVariable differs and raise/log a clear conflict instead
of silently keeping the validator value; keep the validateSchemaExports call for
locally-defined schemas (use importInfoMap.get to decide) and retain use of
validateSchemaExports, importInfoMap, sseCallExpr, extractSSEOutputSchema, and
routeConfig.* names to locate the changes.
📜 Review details
Configuration used: Organization UI
Review profile: CHILL
Plan: Pro
📒 Files selected for processing (1)
packages/cli/src/cmd/build/ast.ts
🧰 Additional context used
📓 Path-based instructions (2)
**/*.{ts,tsx}
📄 CodeRabbit inference engine (AGENTS.md)
**/*.{ts,tsx}: Use Prettier formatter with tabs (width 3), single quotes, and semicolons for TypeScript files
Use TypeScript strict mode with ESNext target and bundler moduleResolution
UseStructuredErrorfrom@agentuity/corefor error handling
Files:
packages/cli/src/cmd/build/ast.ts
packages/cli/**/*.ts
📄 CodeRabbit inference engine (packages/cli/AGENTS.md)
Use
Bun.file(f).exists()instead ofexistsSync(f)for file existence checks
Files:
packages/cli/src/cmd/build/ast.ts
🧠 Learnings (1)
📚 Learning: 2025-12-21T00:31:41.858Z
Learnt from: jhaynie
Repo: agentuity/sdk PR: 274
File: packages/cli/src/cmd/build/vite/server-bundler.ts:12-41
Timestamp: 2025-12-21T00:31:41.858Z
Learning: In Bun runtime, BuildMessage and ResolveMessage are global types and are not exported from the bun module. Do not import { BuildMessage } from 'bun' or similar; these types are available globally and should be used without import. This applies to all TypeScript files that target the Bun runtime within the repository.
Applied to files:
packages/cli/src/cmd/build/ast.ts
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (12)
- GitHub Check: Sandbox CLI Tests
- GitHub Check: Package Installation & Usage Test
- GitHub Check: Cloud Deployment Tests
- GitHub Check: Pack & Upload
- GitHub Check: Template Integration Tests
- GitHub Check: Playwright E2E Smoke Test
- GitHub Check: Storage CLI Tests
- GitHub Check: Standalone Agent Test
- GitHub Check: Queue CLI Tests
- GitHub Check: Framework Integration Tests (TanStack & Next.js)
- GitHub Check: SDK Integration Test Suite
- GitHub Check: Build
🔇 Additional comments (3)
packages/cli/src/cmd/build/ast.ts (3)
1249-1301: Defensive SSE options parsing looks solid.
The guard against non-Propertyentries avoids crashes with spread elements in options objects.
1600-1601: Good setup for SSE schema extraction.
KeepingsseCallExprscoped per route simplifies downstream handling.
1863-1866: Nice capture ofsse()call context.
This cleanly enables schema extraction without affecting non-SSE routes.
✏️ Tip: You can disable this entire section by setting review_details to false in your review settings.
For SSE routes, the sse({ output }) pattern now overrides any validator-provided
schema. This ensures the explicit SSE output declaration is used for type
generation rather than being masked by validator middleware.
Summary
sse({ output: schema }, handler)overload to support typed SSE routesTOutputtouseEventStreamhook for escape hatchCloses #855
Changes
Runtime Package (
@agentuity/runtime)SSEOptions<TOutput>interface for typed SSE configurationsse(handler)- Original pattern (backward compatible)sse({ output: schema }, handler)- New typed patternCLI Package (
@agentuity/cli)extractSSEOutputSchema()function to parsesse({ output: schema }, handler)React Package (
@agentuity/react)TOutputgeneric touseEventStream:Usage
Option A: Typed SSE Route (Full Flow)
Frontend (auto-typed from registry)
Option B: Type Override (escape hatch)
Testing
ast.test.tsregistry-generator.test.tsSummary by CodeRabbit
New Features
Bug Fixes / Validation
Tests