Skip to content

Preserve routed context for agent.run in WebSocket callbacks#1365

Open
parteeksingh24 wants to merge 4 commits intomainfrom
fix/websocket-agent-context
Open

Preserve routed context for agent.run in WebSocket callbacks#1365
parteeksingh24 wants to merge 4 commits intomainfrom
fix/websocket-agent-context

Conversation

@parteeksingh24
Copy link
Copy Markdown
Contributor

@parteeksingh24 parteeksingh24 commented Apr 9, 2026

Summary

  • restore HTTP and agent async-local context in WebSocket callbacks
  • preserve routed session/thread/auth behavior for agent.run() inside ws.onMessage
  • add regression coverage for WebSocket agent context propagation

Verification

  • bun test packages/runtime/test/websocket-agent-context.test.ts
  • bun run --filter='./packages/runtime' build

Notes

  • reproduced the issue on a local WebSocket test app using agent.run() inside ws.onMessage, where the unfixed runtime threw AgentContextNotAvailableError

Summary by CodeRabbit

  • Bug Fixes

    • WebSocket context propagation improved so handlers preserve tracing root context plus async-local authentication/session state during open/message/close events.
  • Tests

    • Added end-to-end WebSocket test validating handshake, echo responses, and restoration of sessionId, threadId, and userId across message handling.

- restore HTTP and agent async-local context in websocket callbacks
- preserve routed session/thread/auth for `agent.run`
- add regression test for websocket context propagation
@agentuity-agent
Copy link
Copy Markdown

agentuity-agent bot commented Apr 9, 2026

The latest Agentuity deployment details.

Project Deployment Preview Updated (UTC)
docs 🟢 Ready (deploy_10999e6144df5c8dc5b8d83ef2d4fb7a) - 2026-04-09T15:13:37Z

@coderabbitai
Copy link
Copy Markdown
Contributor

coderabbitai bot commented Apr 9, 2026

No actionable comments were generated in the recent review. 🎉

ℹ️ Recent review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro

Run ID: 3177c940-809d-4502-ba9d-95e32bdae504

📥 Commits

Reviewing files that changed from the base of the PR and between 5aaa55b and 67e3698.

📒 Files selected for processing (1)
  • packages/runtime/test/websocket-agent-context.test.ts
🚧 Files skipped from review as they are similar to previous changes (1)
  • packages/runtime/test/websocket-agent-context.test.ts
📜 Recent review details
⏰ 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). (15)
  • GitHub Check: Standalone Agent Test
  • GitHub Check: Queue SDK Tests
  • GitHub Check: Cloud Deployment Tests
  • GitHub Check: Queue CLI Tests
  • GitHub Check: Storage CLI Tests
  • GitHub Check: Playwright E2E Smoke Test
  • GitHub Check: SDK Integration Test Suite
  • GitHub Check: Template Integration Tests
  • GitHub Check: Package Installation & Usage Test
  • GitHub Check: Postgres SSL Integration Test
  • GitHub Check: Sandbox CLI Tests
  • GitHub Check: Framework Integration Tests (TanStack & Next.js)
  • GitHub Check: Build
  • GitHub Check: Pack & Upload
  • GitHub Check: Agentuity Deployment

📝 Walkthrough

Walkthrough

Capture agent and HTTP async-local storage contexts and re-establish them (alongside the OpenTelemetry ROOT_CONTEXT) during WebSocket handler execution; added an end-to-end Bun test validating agent context propagation across the WebSocket lifecycle.

Changes

Cohort / File(s) Summary
WebSocket context propagation
packages/runtime/src/handlers/websocket.ts
Imported getAgentAsyncLocalStorage and getHTTPAsyncLocalStorage; added runWithCapturedContext to execute callbacks under otel ROOT_CONTEXT while restoring captured agent/http async-local storage; replaced prior otelContext.with(ROOT_CONTEXT, ...) usages for handler(...), ws.onOpen, ws.onMessage, and ws.onClose.
WebSocket agent context test
packages/runtime/test/websocket-agent-context.test.ts
Added Bun test that starts a real WebSocket server, sets up request-scoped context and lazy-bound auth via middleware, invokes echoAgent.run(...) inside ws.onMessage, and asserts echoed messages include route-scoped sessionId, thread.id, and late-bound userId.
🚥 Pre-merge checks | ✅ 1
✅ Passed checks (1 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.


Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

@parteeksingh24 parteeksingh24 changed the title Preserve routed context for agent.run in WebSocket callbacks Preserve routed context for agent.run in WebSocket callbacks Apr 9, 2026
@github-actions
Copy link
Copy Markdown

github-actions bot commented Apr 9, 2026

📦 Canary Packages Published

version: 2.0.9-67e3698

Packages
Package Version URL
@agentuity/cli 2.0.9-67e3698 https://agentuity-sdk-objects.t3.storageapi.dev/npm/2.0.9-67e3698/agentuity-cli-2.0.9-67e3698.tgz
@agentuity/email 2.0.9-67e3698 https://agentuity-sdk-objects.t3.storageapi.dev/npm/2.0.9-67e3698/agentuity-email-2.0.9-67e3698.tgz
@agentuity/coder 2.0.9-67e3698 https://agentuity-sdk-objects.t3.storageapi.dev/npm/2.0.9-67e3698/agentuity-coder-2.0.9-67e3698.tgz
@agentuity/server 2.0.9-67e3698 https://agentuity-sdk-objects.t3.storageapi.dev/npm/2.0.9-67e3698/agentuity-server-2.0.9-67e3698.tgz
@agentuity/coder-tui 2.0.9-67e3698 https://agentuity-sdk-objects.t3.storageapi.dev/npm/2.0.9-67e3698/agentuity-coder-tui-2.0.9-67e3698.tgz
@agentuity/task 2.0.9-67e3698 https://agentuity-sdk-objects.t3.storageapi.dev/npm/2.0.9-67e3698/agentuity-task-2.0.9-67e3698.tgz
@agentuity/schedule 2.0.9-67e3698 https://agentuity-sdk-objects.t3.storageapi.dev/npm/2.0.9-67e3698/agentuity-schedule-2.0.9-67e3698.tgz
@agentuity/opencode 2.0.9-67e3698 https://agentuity-sdk-objects.t3.storageapi.dev/npm/2.0.9-67e3698/agentuity-opencode-2.0.9-67e3698.tgz
@agentuity/webhook 2.0.9-67e3698 https://agentuity-sdk-objects.t3.storageapi.dev/npm/2.0.9-67e3698/agentuity-webhook-2.0.9-67e3698.tgz
@agentuity/core 2.0.9-67e3698 https://agentuity-sdk-objects.t3.storageapi.dev/npm/2.0.9-67e3698/agentuity-core-2.0.9-67e3698.tgz
@agentuity/db 2.0.9-67e3698 https://agentuity-sdk-objects.t3.storageapi.dev/npm/2.0.9-67e3698/agentuity-db-2.0.9-67e3698.tgz
@agentuity/migrate 2.0.9-67e3698 https://agentuity-sdk-objects.t3.storageapi.dev/npm/2.0.9-67e3698/agentuity-migrate-2.0.9-67e3698.tgz
@agentuity/auth 2.0.9-67e3698 https://agentuity-sdk-objects.t3.storageapi.dev/npm/2.0.9-67e3698/agentuity-auth-2.0.9-67e3698.tgz
@agentuity/evals 2.0.9-67e3698 https://agentuity-sdk-objects.t3.storageapi.dev/npm/2.0.9-67e3698/agentuity-evals-2.0.9-67e3698.tgz
@agentuity/claude-code 2.0.9-67e3698 https://agentuity-sdk-objects.t3.storageapi.dev/npm/2.0.9-67e3698/agentuity-claude-code-2.0.9-67e3698.tgz
@agentuity/postgres 2.0.9-67e3698 https://agentuity-sdk-objects.t3.storageapi.dev/npm/2.0.9-67e3698/agentuity-postgres-2.0.9-67e3698.tgz
@agentuity/runtime 2.0.9-67e3698 https://agentuity-sdk-objects.t3.storageapi.dev/npm/2.0.9-67e3698/agentuity-runtime-2.0.9-67e3698.tgz
@agentuity/drizzle 2.0.9-67e3698 https://agentuity-sdk-objects.t3.storageapi.dev/npm/2.0.9-67e3698/agentuity-drizzle-2.0.9-67e3698.tgz
@agentuity/frontend 2.0.9-67e3698 https://agentuity-sdk-objects.t3.storageapi.dev/npm/2.0.9-67e3698/agentuity-frontend-2.0.9-67e3698.tgz
@agentuity/queue 2.0.9-67e3698 https://agentuity-sdk-objects.t3.storageapi.dev/npm/2.0.9-67e3698/agentuity-queue-2.0.9-67e3698.tgz
@agentuity/schema 2.0.9-67e3698 https://agentuity-sdk-objects.t3.storageapi.dev/npm/2.0.9-67e3698/agentuity-schema-2.0.9-67e3698.tgz
@agentuity/vector 2.0.9-67e3698 https://agentuity-sdk-objects.t3.storageapi.dev/npm/2.0.9-67e3698/agentuity-vector-2.0.9-67e3698.tgz
@agentuity/workbench 2.0.9-67e3698 https://agentuity-sdk-objects.t3.storageapi.dev/npm/2.0.9-67e3698/agentuity-workbench-2.0.9-67e3698.tgz
@agentuity/react 2.0.9-67e3698 https://agentuity-sdk-objects.t3.storageapi.dev/npm/2.0.9-67e3698/agentuity-react-2.0.9-67e3698.tgz
@agentuity/sandbox 2.0.9-67e3698 https://agentuity-sdk-objects.t3.storageapi.dev/npm/2.0.9-67e3698/agentuity-sandbox-2.0.9-67e3698.tgz
@agentuity/keyvalue 2.0.9-67e3698 https://agentuity-sdk-objects.t3.storageapi.dev/npm/2.0.9-67e3698/agentuity-keyvalue-2.0.9-67e3698.tgz
Install

Add to your package.json:

{
  "dependencies": {
    "@agentuity/cli": "https://agentuity-sdk-objects.t3.storageapi.dev/npm/2.0.9-67e3698/agentuity-cli-2.0.9-67e3698.tgz",
    "@agentuity/email": "https://agentuity-sdk-objects.t3.storageapi.dev/npm/2.0.9-67e3698/agentuity-email-2.0.9-67e3698.tgz",
    "@agentuity/coder": "https://agentuity-sdk-objects.t3.storageapi.dev/npm/2.0.9-67e3698/agentuity-coder-2.0.9-67e3698.tgz",
    "@agentuity/server": "https://agentuity-sdk-objects.t3.storageapi.dev/npm/2.0.9-67e3698/agentuity-server-2.0.9-67e3698.tgz",
    "@agentuity/coder-tui": "https://agentuity-sdk-objects.t3.storageapi.dev/npm/2.0.9-67e3698/agentuity-coder-tui-2.0.9-67e3698.tgz",
    "@agentuity/task": "https://agentuity-sdk-objects.t3.storageapi.dev/npm/2.0.9-67e3698/agentuity-task-2.0.9-67e3698.tgz",
    "@agentuity/schedule": "https://agentuity-sdk-objects.t3.storageapi.dev/npm/2.0.9-67e3698/agentuity-schedule-2.0.9-67e3698.tgz",
    "@agentuity/opencode": "https://agentuity-sdk-objects.t3.storageapi.dev/npm/2.0.9-67e3698/agentuity-opencode-2.0.9-67e3698.tgz",
    "@agentuity/webhook": "https://agentuity-sdk-objects.t3.storageapi.dev/npm/2.0.9-67e3698/agentuity-webhook-2.0.9-67e3698.tgz",
    "@agentuity/core": "https://agentuity-sdk-objects.t3.storageapi.dev/npm/2.0.9-67e3698/agentuity-core-2.0.9-67e3698.tgz",
    "@agentuity/db": "https://agentuity-sdk-objects.t3.storageapi.dev/npm/2.0.9-67e3698/agentuity-db-2.0.9-67e3698.tgz",
    "@agentuity/migrate": "https://agentuity-sdk-objects.t3.storageapi.dev/npm/2.0.9-67e3698/agentuity-migrate-2.0.9-67e3698.tgz",
    "@agentuity/auth": "https://agentuity-sdk-objects.t3.storageapi.dev/npm/2.0.9-67e3698/agentuity-auth-2.0.9-67e3698.tgz",
    "@agentuity/evals": "https://agentuity-sdk-objects.t3.storageapi.dev/npm/2.0.9-67e3698/agentuity-evals-2.0.9-67e3698.tgz",
    "@agentuity/claude-code": "https://agentuity-sdk-objects.t3.storageapi.dev/npm/2.0.9-67e3698/agentuity-claude-code-2.0.9-67e3698.tgz",
    "@agentuity/postgres": "https://agentuity-sdk-objects.t3.storageapi.dev/npm/2.0.9-67e3698/agentuity-postgres-2.0.9-67e3698.tgz",
    "@agentuity/runtime": "https://agentuity-sdk-objects.t3.storageapi.dev/npm/2.0.9-67e3698/agentuity-runtime-2.0.9-67e3698.tgz",
    "@agentuity/drizzle": "https://agentuity-sdk-objects.t3.storageapi.dev/npm/2.0.9-67e3698/agentuity-drizzle-2.0.9-67e3698.tgz",
    "@agentuity/frontend": "https://agentuity-sdk-objects.t3.storageapi.dev/npm/2.0.9-67e3698/agentuity-frontend-2.0.9-67e3698.tgz",
    "@agentuity/queue": "https://agentuity-sdk-objects.t3.storageapi.dev/npm/2.0.9-67e3698/agentuity-queue-2.0.9-67e3698.tgz",
    "@agentuity/schema": "https://agentuity-sdk-objects.t3.storageapi.dev/npm/2.0.9-67e3698/agentuity-schema-2.0.9-67e3698.tgz",
    "@agentuity/vector": "https://agentuity-sdk-objects.t3.storageapi.dev/npm/2.0.9-67e3698/agentuity-vector-2.0.9-67e3698.tgz",
    "@agentuity/workbench": "https://agentuity-sdk-objects.t3.storageapi.dev/npm/2.0.9-67e3698/agentuity-workbench-2.0.9-67e3698.tgz",
    "@agentuity/react": "https://agentuity-sdk-objects.t3.storageapi.dev/npm/2.0.9-67e3698/agentuity-react-2.0.9-67e3698.tgz",
    "@agentuity/sandbox": "https://agentuity-sdk-objects.t3.storageapi.dev/npm/2.0.9-67e3698/agentuity-sandbox-2.0.9-67e3698.tgz",
    "@agentuity/keyvalue": "https://agentuity-sdk-objects.t3.storageapi.dev/npm/2.0.9-67e3698/agentuity-keyvalue-2.0.9-67e3698.tgz"
  }
}

Or install directly:

bun add https://agentuity-sdk-objects.t3.storageapi.dev/npm/2.0.9-67e3698/agentuity-cli-2.0.9-67e3698.tgz
bun add https://agentuity-sdk-objects.t3.storageapi.dev/npm/2.0.9-67e3698/agentuity-email-2.0.9-67e3698.tgz
bun add https://agentuity-sdk-objects.t3.storageapi.dev/npm/2.0.9-67e3698/agentuity-coder-2.0.9-67e3698.tgz
bun add https://agentuity-sdk-objects.t3.storageapi.dev/npm/2.0.9-67e3698/agentuity-server-2.0.9-67e3698.tgz
bun add https://agentuity-sdk-objects.t3.storageapi.dev/npm/2.0.9-67e3698/agentuity-coder-tui-2.0.9-67e3698.tgz
bun add https://agentuity-sdk-objects.t3.storageapi.dev/npm/2.0.9-67e3698/agentuity-task-2.0.9-67e3698.tgz
bun add https://agentuity-sdk-objects.t3.storageapi.dev/npm/2.0.9-67e3698/agentuity-schedule-2.0.9-67e3698.tgz
bun add https://agentuity-sdk-objects.t3.storageapi.dev/npm/2.0.9-67e3698/agentuity-opencode-2.0.9-67e3698.tgz
bun add https://agentuity-sdk-objects.t3.storageapi.dev/npm/2.0.9-67e3698/agentuity-webhook-2.0.9-67e3698.tgz
bun add https://agentuity-sdk-objects.t3.storageapi.dev/npm/2.0.9-67e3698/agentuity-core-2.0.9-67e3698.tgz
bun add https://agentuity-sdk-objects.t3.storageapi.dev/npm/2.0.9-67e3698/agentuity-db-2.0.9-67e3698.tgz
bun add https://agentuity-sdk-objects.t3.storageapi.dev/npm/2.0.9-67e3698/agentuity-migrate-2.0.9-67e3698.tgz
bun add https://agentuity-sdk-objects.t3.storageapi.dev/npm/2.0.9-67e3698/agentuity-auth-2.0.9-67e3698.tgz
bun add https://agentuity-sdk-objects.t3.storageapi.dev/npm/2.0.9-67e3698/agentuity-evals-2.0.9-67e3698.tgz
bun add https://agentuity-sdk-objects.t3.storageapi.dev/npm/2.0.9-67e3698/agentuity-claude-code-2.0.9-67e3698.tgz
bun add https://agentuity-sdk-objects.t3.storageapi.dev/npm/2.0.9-67e3698/agentuity-postgres-2.0.9-67e3698.tgz
bun add https://agentuity-sdk-objects.t3.storageapi.dev/npm/2.0.9-67e3698/agentuity-runtime-2.0.9-67e3698.tgz
bun add https://agentuity-sdk-objects.t3.storageapi.dev/npm/2.0.9-67e3698/agentuity-drizzle-2.0.9-67e3698.tgz
bun add https://agentuity-sdk-objects.t3.storageapi.dev/npm/2.0.9-67e3698/agentuity-frontend-2.0.9-67e3698.tgz
bun add https://agentuity-sdk-objects.t3.storageapi.dev/npm/2.0.9-67e3698/agentuity-queue-2.0.9-67e3698.tgz
bun add https://agentuity-sdk-objects.t3.storageapi.dev/npm/2.0.9-67e3698/agentuity-schema-2.0.9-67e3698.tgz
bun add https://agentuity-sdk-objects.t3.storageapi.dev/npm/2.0.9-67e3698/agentuity-vector-2.0.9-67e3698.tgz
bun add https://agentuity-sdk-objects.t3.storageapi.dev/npm/2.0.9-67e3698/agentuity-workbench-2.0.9-67e3698.tgz
bun add https://agentuity-sdk-objects.t3.storageapi.dev/npm/2.0.9-67e3698/agentuity-react-2.0.9-67e3698.tgz
bun add https://agentuity-sdk-objects.t3.storageapi.dev/npm/2.0.9-67e3698/agentuity-sandbox-2.0.9-67e3698.tgz
bun add https://agentuity-sdk-objects.t3.storageapi.dev/npm/2.0.9-67e3698/agentuity-keyvalue-2.0.9-67e3698.tgz

Copy link
Copy Markdown
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 1

🧹 Nitpick comments (1)
packages/runtime/test/websocket-agent-context.test.ts (1)

32-46: Use the shared test mock utilities here.

createMockAuth() is local test scaffolding. Please pull this from the repo’s shared test utilities instead so auth mock shape stays aligned across tests.

As per coding guidelines "Use @agentuity/test-utils for mocks in tests".

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@packages/runtime/test/websocket-agent-context.test.ts` around lines 32 - 46,
Replace the local test scaffolding function createMockAuth (which returns
AuthInterface-shaped objects) with the shared mock from the repo test utilities:
remove the local createMockAuth implementation and import/use the mock provider
from `@agentuity/test-utils` (the shared auth mock used across tests); update any
references in websocket-agent-context.test.ts to call the imported utility (and
adjust any argument shape if needed) so the test uses the canonical shared auth
mock instead of the local definition.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Inline comments:
In `@packages/runtime/test/websocket-agent-context.test.ts`:
- Around line 48-81: The waiters waitForOpen and waitForJsonMessage only reject
on 'error' and can hang if the socket emits 'close' before opening or before a
message; add 'close' event listeners in both functions that remove the paired
listeners (e.g., in waitForOpen remove 'error' and in waitForJsonMessage remove
'message') and call reject with a clear Error like 'WebSocket closed before
open' / 'WebSocket closed before message', and ensure the 'close' handlers are
registered with { once: true } and cleaned up when the other terminal event
fires.

---

Nitpick comments:
In `@packages/runtime/test/websocket-agent-context.test.ts`:
- Around line 32-46: Replace the local test scaffolding function createMockAuth
(which returns AuthInterface-shaped objects) with the shared mock from the repo
test utilities: remove the local createMockAuth implementation and import/use
the mock provider from `@agentuity/test-utils` (the shared auth mock used across
tests); update any references in websocket-agent-context.test.ts to call the
imported utility (and adjust any argument shape if needed) so the test uses the
canonical shared auth mock instead of the local definition.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro

Run ID: d8ba4ec1-ccbd-4084-8817-17cbc935eb29

📥 Commits

Reviewing files that changed from the base of the PR and between a8a1c3d and 8af363b.

📒 Files selected for processing (2)
  • packages/runtime/src/handlers/websocket.ts
  • packages/runtime/test/websocket-agent-context.test.ts
📜 Review details
⏰ 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). (15)
  • GitHub Check: Build
  • GitHub Check: Storage CLI Tests
  • GitHub Check: Playwright E2E Smoke Test
  • GitHub Check: Sandbox CLI Tests
  • GitHub Check: Framework Integration Tests (TanStack & Next.js)
  • GitHub Check: Queue CLI Tests
  • GitHub Check: Queue SDK Tests
  • GitHub Check: Package Installation & Usage Test
  • GitHub Check: SDK Integration Test Suite
  • GitHub Check: Postgres SSL Integration Test
  • GitHub Check: Standalone Agent Test
  • GitHub Check: Pack & Upload
  • GitHub Check: Cloud Deployment Tests
  • GitHub Check: Template Integration Tests
  • GitHub Check: Agentuity Deployment
🧰 Additional context used
📓 Path-based instructions (5)
packages/runtime/**/*.{ts,tsx}

📄 CodeRabbit inference engine (packages/runtime/AGENTS.md)

packages/runtime/**/*.{ts,tsx}: Every agent handler receives AgentContext with logger, tracer, storage (kv, vector, stream), and auth properties
Use ctx.logger instead of console.log for observability

Files:

  • packages/runtime/test/websocket-agent-context.test.ts
  • packages/runtime/src/handlers/websocket.ts
packages/runtime/**/*.test.{ts,tsx}

📄 CodeRabbit inference engine (packages/runtime/AGENTS.md)

packages/runtime/**/*.test.{ts,tsx}: Use app.request() for route testing, not testClient()
Mock contexts from test/helpers/test-context.ts when testing
Import from ../src/ in tests rather than from compiled output
When running tests, prefer using a subagent (Task tool) to avoid context bloat from test output

Files:

  • packages/runtime/test/websocket-agent-context.test.ts
**/*.{ts,tsx,js,jsx}

📄 CodeRabbit inference engine (AGENTS.md)

Use Biome as code formatter with tabs (width 3), single quotes, semicolons, lineWidth 100, and trailingCommas es5

Files:

  • packages/runtime/test/websocket-agent-context.test.ts
  • packages/runtime/src/handlers/websocket.ts
**/*.{ts,tsx}

📄 CodeRabbit inference engine (AGENTS.md)

**/*.{ts,tsx}: Use TypeScript Strict mode with ESNext target and bundler moduleResolution
Use StructuredError from @agentuity/core for error handling

Files:

  • packages/runtime/test/websocket-agent-context.test.ts
  • packages/runtime/src/handlers/websocket.ts
**/test/**/*.{ts,tsx}

📄 CodeRabbit inference engine (AGENTS.md)

**/test/**/*.{ts,tsx}: Place tests in test/ folder, never in src/ or __tests__/ directories
Import from ../src/ in test files
Use @agentuity/test-utils for mocks in tests

Files:

  • packages/runtime/test/websocket-agent-context.test.ts
🧠 Learnings (3)
📚 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/test/websocket-agent-context.test.ts
  • packages/runtime/src/handlers/websocket.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/test/websocket-agent-context.test.ts
  • packages/runtime/src/handlers/websocket.ts
📚 Learning: 2026-02-21T02:05:57.982Z
Learnt from: jhaynie
Repo: agentuity/sdk PR: 1010
File: packages/drizzle/test/proxy.test.ts:594-603
Timestamp: 2026-02-21T02:05:57.982Z
Learning: Do not rely on StructuredError from agentuity/core in test files or simple error handling paths. In tests and straightforward error handling, use plain Error objects to represent failures, reserving StructuredError for more complex error scenarios in application logic.

Applied to files:

  • packages/runtime/test/websocket-agent-context.test.ts
🔇 Additional comments (2)
packages/runtime/src/handlers/websocket.ts (1)

104-107: Nice fix for WebSocket context re-entry.

Capturing both async-local stores at upgrade time and re-entering them for the handler plus each lifecycle callback closes the routed agent.run() gap without disturbing the existing OTEL root-context workaround.

Also applies to: 145-160, 167-168, 182-182, 197-197, 208-208

packages/runtime/test/websocket-agent-context.test.ts (1)

95-209: Good regression coverage for the routed WebSocket path.

This exercises the real upgrade flow and asserts session/thread/auth propagation from the routed request through ws.onMessage, which is exactly the failure mode described in the PR.

Comment thread packages/runtime/test/websocket-agent-context.test.ts
- reject waiters when the socket closes before open/message
- clean up paired event listeners in websocket test helpers
Copy link
Copy Markdown
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

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

🧹 Nitpick comments (1)
packages/runtime/test/websocket-agent-context.test.ts (1)

32-46: Use shared test mock/context helpers instead of a bespoke AuthInterface stub.

Line 32 builds a custom auth mock inline. Please switch this to repository-standard test mocks/context helpers to reduce drift as auth contracts evolve.

As per coding guidelines: "Mock contexts from test/helpers/test-context.ts when testing" and "Use @agentuity/test-utils for mocks in tests".

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@packages/runtime/test/websocket-agent-context.test.ts` around lines 32 - 46,
The inline auth stub function createMockAuth should be replaced with the
repository-standard test helpers: import and use the mock/auth helper (e.g., the
test context factory or auth mock exported from test/helpers/test-context.ts or
`@agentuity/test-utils`) instead of the bespoke AuthInterface implementation;
update the test to call the shared helper to obtain an AuthInterface (preserving
the same userId variation used now) and remove createMockAuth, ensuring any
calls to getUser/getToken/getOrg/etc. come from the shared mock API (adjust
imports and variable names accordingly).
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Nitpick comments:
In `@packages/runtime/test/websocket-agent-context.test.ts`:
- Around line 32-46: The inline auth stub function createMockAuth should be
replaced with the repository-standard test helpers: import and use the mock/auth
helper (e.g., the test context factory or auth mock exported from
test/helpers/test-context.ts or `@agentuity/test-utils`) instead of the bespoke
AuthInterface implementation; update the test to call the shared helper to
obtain an AuthInterface (preserving the same userId variation used now) and
remove createMockAuth, ensuring any calls to getUser/getToken/getOrg/etc. come
from the shared mock API (adjust imports and variable names accordingly).

ℹ️ Review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro

Run ID: d7716029-b226-47a8-89dc-75523272123a

📥 Commits

Reviewing files that changed from the base of the PR and between 8af363b and 5aaa55b.

📒 Files selected for processing (1)
  • packages/runtime/test/websocket-agent-context.test.ts
📜 Review details
⏰ 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). (15)
  • GitHub Check: Template Integration Tests
  • GitHub Check: Storage CLI Tests
  • GitHub Check: Playwright E2E Smoke Test
  • GitHub Check: Sandbox CLI Tests
  • GitHub Check: Standalone Agent Test
  • GitHub Check: Queue CLI Tests
  • GitHub Check: Framework Integration Tests (TanStack & Next.js)
  • GitHub Check: Package Installation & Usage Test
  • GitHub Check: Queue SDK Tests
  • GitHub Check: Build
  • GitHub Check: Postgres SSL Integration Test
  • GitHub Check: Cloud Deployment Tests
  • GitHub Check: SDK Integration Test Suite
  • GitHub Check: Pack & Upload
  • GitHub Check: Agentuity Deployment
🧰 Additional context used
📓 Path-based instructions (5)
packages/runtime/**/*.{ts,tsx}

📄 CodeRabbit inference engine (packages/runtime/AGENTS.md)

packages/runtime/**/*.{ts,tsx}: Every agent handler receives AgentContext with logger, tracer, storage (kv, vector, stream), and auth properties
Use ctx.logger instead of console.log for observability

Files:

  • packages/runtime/test/websocket-agent-context.test.ts
packages/runtime/**/*.test.{ts,tsx}

📄 CodeRabbit inference engine (packages/runtime/AGENTS.md)

packages/runtime/**/*.test.{ts,tsx}: Use app.request() for route testing, not testClient()
Mock contexts from test/helpers/test-context.ts when testing
Import from ../src/ in tests rather than from compiled output
When running tests, prefer using a subagent (Task tool) to avoid context bloat from test output

Files:

  • packages/runtime/test/websocket-agent-context.test.ts
**/*.{ts,tsx,js,jsx}

📄 CodeRabbit inference engine (AGENTS.md)

Use Biome as code formatter with tabs (width 3), single quotes, semicolons, lineWidth 100, and trailingCommas es5

Files:

  • packages/runtime/test/websocket-agent-context.test.ts
**/*.{ts,tsx}

📄 CodeRabbit inference engine (AGENTS.md)

**/*.{ts,tsx}: Use TypeScript Strict mode with ESNext target and bundler moduleResolution
Use StructuredError from @agentuity/core for error handling

Files:

  • packages/runtime/test/websocket-agent-context.test.ts
**/test/**/*.{ts,tsx}

📄 CodeRabbit inference engine (AGENTS.md)

**/test/**/*.{ts,tsx}: Place tests in test/ folder, never in src/ or __tests__/ directories
Import from ../src/ in test files
Use @agentuity/test-utils for mocks in tests

Files:

  • packages/runtime/test/websocket-agent-context.test.ts
🧠 Learnings (3)
📚 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/test/websocket-agent-context.test.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/test/websocket-agent-context.test.ts
📚 Learning: 2026-02-21T02:05:57.982Z
Learnt from: jhaynie
Repo: agentuity/sdk PR: 1010
File: packages/drizzle/test/proxy.test.ts:594-603
Timestamp: 2026-02-21T02:05:57.982Z
Learning: Do not rely on StructuredError from agentuity/core in test files or simple error handling paths. In tests and straightforward error handling, use plain Error objects to represent failures, reserving StructuredError for more complex error scenarios in application logic.

Applied to files:

  • packages/runtime/test/websocket-agent-context.test.ts
🔇 Additional comments (2)
packages/runtime/test/websocket-agent-context.test.ts (2)

48-104: Nice hardening of WebSocket waiter lifecycle handling.

The symmetric cleanup + close rejection paths prevent dangling waiters and reduce test hangs in close-before-open/message scenarios.


151-218: Regression coverage is well-targeted to the fix.

This directly exercises agent.run() inside ws.onMessage and verifies propagated sessionId, threadId, and late-bound auth, which matches the reported failure mode.

parteeksingh24 and others added 2 commits April 8, 2026 21:05
- replace createApp setup with direct Hono websocket wiring
- keep real websocket routing and agent middleware coverage
- avoid suite collisions from mocked app service modules
@parteeksingh24
Copy link
Copy Markdown
Contributor Author

This PR preserves routed context for agent.run() in WebSocket callbacks and includes runtime regression coverage for that path.

The regression test uses a real Bun.serve() WebSocket route with createAgentMiddleware(''), and verifies that agent.run() inside ws.onMessage preserves session/thread continuity and late-bound routed auth context.

Verification:

  • bun test packages/runtime/test/websocket-agent-context.test.ts
  • cd packages/runtime && bun test --max-concurrency=1
  • bun run --filter='./packages/runtime' build

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