Skip to content

feat(sdk): AI SDK custom useChat transport & chat.task harness#3173

Draft
ericallam wants to merge 27 commits intomainfrom
feature/tri-7532-ai-sdk-chat-transport-and-chat-task-system
Draft

feat(sdk): AI SDK custom useChat transport & chat.task harness#3173
ericallam wants to merge 27 commits intomainfrom
feature/tri-7532-ai-sdk-chat-transport-and-chat-task-system

Conversation

@ericallam
Copy link
Member

No description provided.

cursoragent and others added 27 commits March 4, 2026 13:48
New package that provides a custom AI SDK ChatTransport implementation
bridging Vercel AI SDK's useChat hook with Trigger.dev's durable task
execution and realtime streams.

Key exports:
- TriggerChatTransport class implementing ChatTransport<UIMessage>
- createChatTransport() factory function
- ChatTaskPayload type for task-side typing
- TriggerChatTransportOptions type

The transport triggers a Trigger.dev task with chat messages as payload,
then subscribes to the task's realtime stream to receive UIMessageChunk
data, which useChat processes natively.

Co-authored-by: Eric Allam <eric@trigger.dev>
Tests cover:
- Constructor with required and optional options
- sendMessages triggering task and returning UIMessageChunk stream
- Correct payload structure sent to trigger API
- Custom streamKey in stream URL
- Extra headers propagation
- reconnectToStream with existing and non-existing sessions
- createChatTransport factory function
- Error handling for API failures
- regenerate-message trigger type

Co-authored-by: Eric Allam <eric@trigger.dev>
- Cache ApiClient instance instead of creating per-call
- Add streamTimeoutSeconds option for customizable stream timeout
- Clean up subscribeToStream method (remove unused variable)
- Improve JSDoc with backend task example
- Minor code cleanup

Co-authored-by: Eric Allam <eric@trigger.dev>
Adds 3 additional test cases:
- Abort signal gracefully closes the stream
- Multiple independent chat sessions tracked correctly
- ChatRequestOptions.body is merged into task payload

Co-authored-by: Eric Allam <eric@trigger.dev>
Co-authored-by: Eric Allam <eric@trigger.dev>
ChatSessionState is an implementation detail of the transport's
session tracking. Users don't need to access it since the sessions
map is private.

Co-authored-by: Eric Allam <eric@trigger.dev>
The accessToken option now accepts either a string or a function
returning a string. This enables dynamic token refresh patterns:

  new TriggerChatTransport({
    taskId: 'my-task',
    accessToken: () => getLatestToken(),
  })

The function is called on each sendMessages() call, allowing fresh
tokens to be used for each task trigger.

Co-authored-by: Eric Allam <eric@trigger.dev>
Use the already-resolved token when creating ApiClient instead of
calling resolveAccessToken() again through getApiClient().

Co-authored-by: Eric Allam <eric@trigger.dev>
Two new subpath exports:

@trigger.dev/sdk/chat (frontend, browser-safe):
- TriggerChatTransport — ChatTransport implementation for useChat
- createChatTransport() — factory function
- TriggerChatTransportOptions type

@trigger.dev/sdk/ai (backend, adds to existing ai.tool/ai.currentToolOptions):
- chatTask() — pre-typed task wrapper with auto-pipe
- pipeChat() — pipe StreamTextResult to realtime stream
- CHAT_STREAM_KEY constant
- ChatTaskPayload type
- ChatTaskOptions type
- PipeChatOptions type

Co-authored-by: Eric Allam <eric@trigger.dev>
Move and adapt tests from packages/ai to packages/trigger-sdk.
- Import from ./chat.js instead of ./transport.js
- Use 'task' option instead of 'taskId'
- All 17 tests passing

Co-authored-by: Eric Allam <eric@trigger.dev>
All functionality now lives in:
- @trigger.dev/sdk/chat (frontend transport)
- @trigger.dev/sdk/ai (backend chatTask, pipeChat)

Co-authored-by: Eric Allam <eric@trigger.dev>
Co-authored-by: Eric Allam <eric@trigger.dev>
1. Add null/object guard before enqueuing UIMessageChunk from SSE stream
   to handle heartbeat or malformed events safely
2. Use incrementing counter instead of Date.now() in test message
   factories to avoid duplicate IDs
3. Add test covering publicAccessToken from trigger response being used
   for stream subscription auth

Co-authored-by: Eric Allam <eric@trigger.dev>
Comprehensive guide covering:
- Quick start with chatTask + TriggerChatTransport
- Backend patterns: simple (return streamText), complex (pipeChat),
  and manual (task + ChatTaskPayload)
- Frontend options: dynamic tokens, extra data, self-hosting
- ChatTaskPayload reference
- Added to Writing tasks navigation near Streams

Co-authored-by: Eric Allam <eric@trigger.dev>
Minimal example showcasing the new chatTask + TriggerChatTransport APIs:
- Backend: chatTask with streamText auto-pipe (src/trigger/chat.ts)
- Frontend: TriggerChatTransport with useChat (src/components/chat.tsx)
- Token generation via auth.createTriggerPublicToken (src/app/page.tsx)
- Tailwind v4 styling

Co-authored-by: Eric Allam <eric@trigger.dev>
…delMessages

@ai-sdk/openai v3 and @ai-sdk/react v3 are needed for ai v6 compatibility.
convertToModelMessages is async in newer AI SDK versions.

Co-authored-by: Eric Allam <eric@trigger.dev>
@changeset-bot
Copy link

changeset-bot bot commented Mar 4, 2026

🦋 Changeset detected

Latest commit: d7817e0

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

This PR includes changesets to release 29 packages
Name Type
@trigger.dev/sdk Minor
@trigger.dev/python Minor
@internal/sdk-compat-tests Patch
references-ai-chat Patch
d3-chat Patch
references-d3-openai-agents Patch
references-nextjs-realtime Patch
references-realtime-hooks-test Patch
references-realtime-streams Patch
references-telemetry Patch
@trigger.dev/build Minor
@trigger.dev/core Minor
@trigger.dev/react-hooks Minor
@trigger.dev/redis-worker Minor
@trigger.dev/rsc Minor
@trigger.dev/schema-to-json Minor
@trigger.dev/database Minor
@trigger.dev/otlp-importer Minor
trigger.dev Minor
@internal/cache Patch
@internal/clickhouse Patch
@internal/redis Patch
@internal/replication Patch
@internal/run-engine Patch
@internal/schedule-engine Patch
@internal/testcontainers Patch
@internal/tracing Patch
@internal/tsql Patch
@internal/zod-worker 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

@coderabbitai
Copy link
Contributor

coderabbitai bot commented Mar 4, 2026

Walkthrough

This PR introduces AI chat integration capabilities via new subpath exports (@trigger.dev/sdk/chat for frontend and @trigger.dev/sdk/ai for backend) that enable durable chat completions tasks with real-time streaming to Vercel AI SDK's useChat hook. It also implements graceful per-item oversized NDJSON handling by emitting error markers instead of throwing, adds input stream management methods for sequence tracking and buffer manipulation, extends realtime stream options with spanName and collapsed attributes for improved tracing, and updates package configuration to support new exports and optional peer dependencies (React and AI SDK).

Estimated code review effort

🎯 4 (Complex) | ⏱️ ~60 minutes

🚥 Pre-merge checks | ✅ 1 | ❌ 2

❌ Failed checks (2 warnings)

Check name Status Explanation Resolution
Description check ⚠️ Warning The PR description is empty; the author provided no description content despite a template being available with required sections like testing, changelog, and checklist. Complete the PR description by filling in the required template sections: checklist items, testing steps, and a changelog entry describing the chat transport and chat.task features.
Docstring Coverage ⚠️ Warning Docstring coverage is 63.16% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (1 passed)
Check name Status Explanation
Title check ✅ Passed The PR title clearly and concisely summarizes the main feature additions: a custom useChat transport for the AI SDK and a chat.task harness system.

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

✨ Finishing Touches
  • 📝 Generate docstrings (stacked PR)
  • 📝 Generate docstrings (commit on current branch)
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Post copyable unit tests in a comment
  • Commit unit tests in branch feature/tri-7532-ai-sdk-chat-transport-and-chat-task-system

Tip

Try Coding Plans. Let us write the prompt for your AI agent so you can ship faster (with fewer bugs).
Share your feedback on Discord.


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.

@ericallam ericallam changed the title feature/tri-7532-ai-sdk-chat-transport-and-chat-task-system feat(sdk): AI SDK custom useChat transport & chat.task harness Mar 4, 2026
Copy link
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: 3

🧹 Nitpick comments (3)
packages/trigger-sdk/src/v3/chat.test.ts (1)

22-23: Consider resetting messageIdCounter in beforeEach.

The messageIdCounter is a module-level variable that accumulates across all tests. While this doesn't cause functional issues (IDs just need to be unique within each test), resetting it in beforeEach would make tests more deterministic and easier to debug.

♻️ Suggested fix
 beforeEach(() => {
   originalFetch = global.fetch;
+  messageIdCounter = 0;
 });
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@packages/trigger-sdk/src/v3/chat.test.ts` around lines 22 - 23, The
module-level variable messageIdCounter in chat.test.ts accumulates across tests
making IDs non-deterministic; add a beforeEach hook in the test file that resets
messageIdCounter = 0 so each test starts with a fresh counter (locate the
variable by name messageIdCounter and place the reset inside the existing or new
beforeEach block in the test suite).
packages/trigger-sdk/src/v3/chat-react.ts (1)

76-84: Good memoization pattern, but options are captured only on first render.

The useRef pattern correctly preserves the transport instance across re-renders. Note that if baseURL, headers, streamKey, or other options change after the initial render, the transport won't pick up those changes. This is likely intentional (and documented via "created once"), but worth keeping in mind if callers expect reactive updates to options other than accessToken.

The accessToken function pattern works correctly for dynamic tokens since it's called per-request.

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

In `@packages/trigger-sdk/src/v3/chat-react.ts` around lines 76 - 84, The hook
useTriggerChatTransport currently creates a single TriggerChatTransport with the
options captured only on first render, so changes to baseURL, headers,
streamKey, etc. after mount are ignored; modify the hook to either (A) expose or
call an update method on the transport (e.g., ref.current.updateOptions or
ref.current.setConfig) and update relevant fields when
options.baseURL/headers/streamKey change, or (B) recreate the transport when
those non-dynamic options change by tracking them in a useEffect and replacing
ref.current = new TriggerChatTransport(options) (preserving any needed cleanup),
while keeping the accessToken-as-function behavior unchanged so per-request
tokens remain dynamic. Ensure you reference useTriggerChatTransport and
TriggerChatTransport and only treat accessToken as dynamically invoked per
request.
packages/trigger-sdk/src/v3/chat.ts (1)

198-212: Consider logging the error for debugging.

The silent catch when sending to an existing run's input stream makes debugging harder when things go wrong unexpectedly. While the fallthrough to trigger a new run is correct, a debug-level log could help diagnose issues.

🔧 Optional: Add debug logging
       } catch {
-        // If sending fails (run died, etc.), fall through to trigger a new run.
+        // If sending fails (run died, etc.), fall through to trigger a new run.
+        // Note: Consider adding debug logging here if debugging becomes difficult
         this.sessions.delete(chatId);
       }
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@packages/trigger-sdk/src/v3/chat.ts` around lines 198 - 212, The catch block
swallowing errors after ApiClient.sendInputStream makes failures hard to trace;
update the catch to log the caught error (including context like session.runId
and chatId) before deleting the session so you still fall through to start a new
run — use the class logger (e.g., this.logger.debug) if available or
console.debug as a fallback, referencing ApiClient.sendInputStream,
subscribeToStream, and this.sessions.delete to locate the code to change.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Inline comments:
In @.scratch/plan-graceful-oversized-batch-items.md:
- Around line 216-238: The fenced code block that starts with "NDJSON bytes
arrive" is missing a language identifier which triggers markdownlint MD040;
update the opening fence to include a language (e.g., change ``` to ```text) so
the block is explicitly marked as plain text (ensure the closing fence remains
```), preserving the existing block contents and indentation.

In `@packages/trigger-sdk/src/v3/ai.ts`:
- Around line 560-563: The handler currently captures multiple messages into
pendingMessages via messagesInput.on (msgSub) but later only consumes the first
entry, discarding the rest; change the logic that extracts from pendingMessages
(where it currently uses a single element) to drain and preserve the entire
backlog — e.g., move all items from pendingMessages into the processing queue
(or append them to the existing messages array) before proceeding, then clean up
the subscription (msgSub) as before so no buffered messages are lost; update
references to pendingMessages, msgSub, and messagesInput.on to reflect this
full-drain behavior.
- Around line 268-269: The global _chatPipeCount is race-prone; make the pipe
counter scoped to each chat run/turn instead. Remove the module-global
_chatPipeCount and initialize a run-scoped counter (for example add a numeric
property like run.__chatPipeCount or turn.chatPipeCount on the ChatRun/ChatTurn
object when a run/turn is created or at the start of the function that currently
uses _chatPipeCount), then replace every reference to _chatPipeCount (including
uses around lines 360-361 and 548-583) with the run/turn-scoped property and
update increment/decrement logic to use that property so concurrent runs don’t
share state. Ensure the counter is initialized to 0 at run start and cleaned up
or left on the run object when finished.

---

Nitpick comments:
In `@packages/trigger-sdk/src/v3/chat-react.ts`:
- Around line 76-84: The hook useTriggerChatTransport currently creates a single
TriggerChatTransport with the options captured only on first render, so changes
to baseURL, headers, streamKey, etc. after mount are ignored; modify the hook to
either (A) expose or call an update method on the transport (e.g.,
ref.current.updateOptions or ref.current.setConfig) and update relevant fields
when options.baseURL/headers/streamKey change, or (B) recreate the transport
when those non-dynamic options change by tracking them in a useEffect and
replacing ref.current = new TriggerChatTransport(options) (preserving any needed
cleanup), while keeping the accessToken-as-function behavior unchanged so
per-request tokens remain dynamic. Ensure you reference useTriggerChatTransport
and TriggerChatTransport and only treat accessToken as dynamically invoked per
request.

In `@packages/trigger-sdk/src/v3/chat.test.ts`:
- Around line 22-23: The module-level variable messageIdCounter in chat.test.ts
accumulates across tests making IDs non-deterministic; add a beforeEach hook in
the test file that resets messageIdCounter = 0 so each test starts with a fresh
counter (locate the variable by name messageIdCounter and place the reset inside
the existing or new beforeEach block in the test suite).

In `@packages/trigger-sdk/src/v3/chat.ts`:
- Around line 198-212: The catch block swallowing errors after
ApiClient.sendInputStream makes failures hard to trace; update the catch to log
the caught error (including context like session.runId and chatId) before
deleting the session so you still fall through to start a new run — use the
class logger (e.g., this.logger.debug) if available or console.debug as a
fallback, referencing ApiClient.sendInputStream, subscribeToStream, and
this.sessions.delete to locate the code to change.

ℹ️ Review info
⚙️ Run configuration

Configuration used: Repository UI

Review profile: CHILL

Plan: Pro

Run ID: ffd316a7-f5af-4416-88b4-2e7c865da47c

📥 Commits

Reviewing files that changed from the base of the PR and between c013322 and d7817e0.

⛔ Files ignored due to path filters (13)
  • pnpm-lock.yaml is excluded by !**/pnpm-lock.yaml
  • references/ai-chat/next-env.d.ts is excluded by !references/**
  • references/ai-chat/next.config.ts is excluded by !references/**
  • references/ai-chat/package.json is excluded by !references/**
  • references/ai-chat/postcss.config.mjs is excluded by !references/**
  • references/ai-chat/src/app/actions.ts is excluded by !references/**
  • references/ai-chat/src/app/globals.css is excluded by !references/**
  • references/ai-chat/src/app/layout.tsx is excluded by !references/**
  • references/ai-chat/src/app/page.tsx is excluded by !references/**
  • references/ai-chat/src/components/chat.tsx is excluded by !references/**
  • references/ai-chat/src/trigger/chat.ts is excluded by !references/**
  • references/ai-chat/trigger.config.ts is excluded by !references/**
  • references/ai-chat/tsconfig.json is excluded by !references/**
📒 Files selected for processing (18)
  • .changeset/ai-sdk-chat-transport.md
  • .claude/rules/package-installation.md
  • .scratch/plan-graceful-oversized-batch-items.md
  • CLAUDE.md
  • docs/docs.json
  • docs/guides/ai-chat.mdx
  • packages/core/src/v3/inputStreams/index.ts
  • packages/core/src/v3/inputStreams/manager.ts
  • packages/core/src/v3/inputStreams/noopManager.ts
  • packages/core/src/v3/inputStreams/types.ts
  • packages/core/src/v3/realtimeStreams/types.ts
  • packages/trigger-sdk/package.json
  • packages/trigger-sdk/src/v3/ai.ts
  • packages/trigger-sdk/src/v3/chat-constants.ts
  • packages/trigger-sdk/src/v3/chat-react.ts
  • packages/trigger-sdk/src/v3/chat.test.ts
  • packages/trigger-sdk/src/v3/chat.ts
  • packages/trigger-sdk/src/v3/streams.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). (27)
  • GitHub Check: units / internal / 🧪 Unit Tests: Internal (6, 8)
  • GitHub Check: units / webapp / 🧪 Unit Tests: Webapp (1, 8)
  • GitHub Check: units / webapp / 🧪 Unit Tests: Webapp (6, 8)
  • GitHub Check: units / internal / 🧪 Unit Tests: Internal (5, 8)
  • GitHub Check: units / internal / 🧪 Unit Tests: Internal (3, 8)
  • GitHub Check: units / internal / 🧪 Unit Tests: Internal (1, 8)
  • GitHub Check: units / internal / 🧪 Unit Tests: Internal (7, 8)
  • GitHub Check: units / internal / 🧪 Unit Tests: Internal (8, 8)
  • GitHub Check: units / webapp / 🧪 Unit Tests: Webapp (7, 8)
  • GitHub Check: units / webapp / 🧪 Unit Tests: Webapp (5, 8)
  • GitHub Check: units / internal / 🧪 Unit Tests: Internal (2, 8)
  • GitHub Check: units / webapp / 🧪 Unit Tests: Webapp (2, 8)
  • GitHub Check: units / webapp / 🧪 Unit Tests: Webapp (3, 8)
  • GitHub Check: units / internal / 🧪 Unit Tests: Internal (4, 8)
  • GitHub Check: units / webapp / 🧪 Unit Tests: Webapp (4, 8)
  • GitHub Check: units / webapp / 🧪 Unit Tests: Webapp (8, 8)
  • GitHub Check: sdk-compat / Bun Runtime
  • GitHub Check: units / packages / 🧪 Unit Tests: Packages (1, 1)
  • GitHub Check: e2e / 🧪 CLI v3 tests (ubuntu-latest - pnpm)
  • GitHub Check: sdk-compat / Cloudflare Workers
  • GitHub Check: sdk-compat / Node.js 20.20 (ubuntu-latest)
  • GitHub Check: e2e / 🧪 CLI v3 tests (windows-latest - pnpm)
  • GitHub Check: typecheck / typecheck
  • GitHub Check: e2e / 🧪 CLI v3 tests (windows-latest - npm)
  • GitHub Check: sdk-compat / Deno Runtime
  • GitHub Check: sdk-compat / Node.js 22.12 (ubuntu-latest)
  • GitHub Check: e2e / 🧪 CLI v3 tests (ubuntu-latest - npm)
🧰 Additional context used
📓 Path-based instructions (14)
**/*.{ts,tsx}

📄 CodeRabbit inference engine (.github/copilot-instructions.md)

**/*.{ts,tsx}: Use types over interfaces for TypeScript
Avoid using enums; prefer string unions or const objects instead

**/*.{ts,tsx}: In TypeScript SDK usage, always import from @trigger.dev/sdk, never from @trigger.dev/sdk/v3 or use deprecated client.defineJob
Import from @trigger.dev/core subpaths only, never from the root
Use the Run Engine 2.0 (@internal/run-engine) and redis-worker for all new work, not legacy V1 MarQS queue or deprecated V1 functions

Files:

  • packages/core/src/v3/inputStreams/manager.ts
  • packages/core/src/v3/inputStreams/index.ts
  • packages/core/src/v3/inputStreams/noopManager.ts
  • packages/trigger-sdk/src/v3/chat.ts
  • packages/core/src/v3/inputStreams/types.ts
  • packages/trigger-sdk/src/v3/chat-constants.ts
  • packages/trigger-sdk/src/v3/streams.ts
  • packages/trigger-sdk/src/v3/chat.test.ts
  • packages/trigger-sdk/src/v3/chat-react.ts
  • packages/core/src/v3/realtimeStreams/types.ts
  • packages/trigger-sdk/src/v3/ai.ts
{packages/core,apps/webapp}/**/*.{ts,tsx}

📄 CodeRabbit inference engine (.github/copilot-instructions.md)

Use zod for validation in packages/core and apps/webapp

Files:

  • packages/core/src/v3/inputStreams/manager.ts
  • packages/core/src/v3/inputStreams/index.ts
  • packages/core/src/v3/inputStreams/noopManager.ts
  • packages/core/src/v3/inputStreams/types.ts
  • packages/core/src/v3/realtimeStreams/types.ts
**/*.{ts,tsx,js,jsx}

📄 CodeRabbit inference engine (.github/copilot-instructions.md)

Use function declarations instead of default exports

Files:

  • packages/core/src/v3/inputStreams/manager.ts
  • packages/core/src/v3/inputStreams/index.ts
  • packages/core/src/v3/inputStreams/noopManager.ts
  • packages/trigger-sdk/src/v3/chat.ts
  • packages/core/src/v3/inputStreams/types.ts
  • packages/trigger-sdk/src/v3/chat-constants.ts
  • packages/trigger-sdk/src/v3/streams.ts
  • packages/trigger-sdk/src/v3/chat.test.ts
  • packages/trigger-sdk/src/v3/chat-react.ts
  • packages/core/src/v3/realtimeStreams/types.ts
  • packages/trigger-sdk/src/v3/ai.ts
**/*.ts

📄 CodeRabbit inference engine (.cursor/rules/otel-metrics.mdc)

**/*.ts: When creating or editing OTEL metrics (counters, histograms, gauges), ensure metric attributes have low cardinality by using only enums, booleans, bounded error codes, or bounded shard IDs
Do not use high-cardinality attributes in OTEL metrics such as UUIDs/IDs (envId, userId, runId, projectId, organizationId), unbounded integers (itemCount, batchSize, retryCount), timestamps (createdAt, startTime), or free-form strings (errorMessage, taskName, queueName)
When exporting OTEL metrics via OTLP to Prometheus, be aware that the exporter automatically adds unit suffixes to metric names (e.g., 'my_duration_ms' becomes 'my_duration_ms_milliseconds', 'my_counter' becomes 'my_counter_total'). Account for these transformations when writing Grafana dashboards or Prometheus queries

Files:

  • packages/core/src/v3/inputStreams/manager.ts
  • packages/core/src/v3/inputStreams/index.ts
  • packages/core/src/v3/inputStreams/noopManager.ts
  • packages/trigger-sdk/src/v3/chat.ts
  • packages/core/src/v3/inputStreams/types.ts
  • packages/trigger-sdk/src/v3/chat-constants.ts
  • packages/trigger-sdk/src/v3/streams.ts
  • packages/trigger-sdk/src/v3/chat.test.ts
  • packages/trigger-sdk/src/v3/chat-react.ts
  • packages/core/src/v3/realtimeStreams/types.ts
  • packages/trigger-sdk/src/v3/ai.ts
**/*.{js,ts,jsx,tsx,json,md,yaml,yml}

📄 CodeRabbit inference engine (AGENTS.md)

Format code using Prettier before committing

Files:

  • packages/core/src/v3/inputStreams/manager.ts
  • packages/core/src/v3/inputStreams/index.ts
  • packages/core/src/v3/inputStreams/noopManager.ts
  • docs/docs.json
  • packages/trigger-sdk/src/v3/chat.ts
  • CLAUDE.md
  • packages/core/src/v3/inputStreams/types.ts
  • packages/trigger-sdk/src/v3/chat-constants.ts
  • packages/trigger-sdk/src/v3/streams.ts
  • packages/trigger-sdk/src/v3/chat.test.ts
  • packages/trigger-sdk/src/v3/chat-react.ts
  • packages/trigger-sdk/package.json
  • packages/core/src/v3/realtimeStreams/types.ts
  • packages/trigger-sdk/src/v3/ai.ts
packages/core/**/*.{ts,tsx,js,jsx}

📄 CodeRabbit inference engine (packages/core/CLAUDE.md)

Never import the root package (@trigger.dev/core). Always use subpath imports such as @trigger.dev/core/v3, @trigger.dev/core/v3/utils, @trigger.dev/core/logger, or @trigger.dev/core/schemas

Files:

  • packages/core/src/v3/inputStreams/manager.ts
  • packages/core/src/v3/inputStreams/index.ts
  • packages/core/src/v3/inputStreams/noopManager.ts
  • packages/core/src/v3/inputStreams/types.ts
  • packages/core/src/v3/realtimeStreams/types.ts
docs/**/*.{md,mdx}

📄 CodeRabbit inference engine (CLAUDE.md)

Docs in docs/ directory should use Mintlify MDX format following conventions in docs/CLAUDE.md

Files:

  • docs/guides/ai-chat.mdx
docs/**/*.mdx

📄 CodeRabbit inference engine (docs/CLAUDE.md)

docs/**/*.mdx: MDX documentation pages must include frontmatter with title (required), description (required), and sidebarTitle (optional) in YAML format
Use Mintlify components for structured content: , , , , , , /, /
Always import from @trigger.dev/sdk in code examples (never from @trigger.dev/sdk/v3)
Code examples must be complete and runnable where possible
Use language tags in code fences: typescript, bash, json

Files:

  • docs/guides/ai-chat.mdx
docs/**/docs.json

📄 CodeRabbit inference engine (docs/CLAUDE.md)

docs/**/docs.json: Main documentation config must be defined in docs.json which includes navigation structure, theme, and metadata
Navigation structure in docs.json should be organized using navigation.dropdowns with groups and pages

Files:

  • docs/docs.json
packages/trigger-sdk/**/*.{ts,tsx}

📄 CodeRabbit inference engine (.github/copilot-instructions.md)

In the Trigger.dev SDK (packages/trigger-sdk), prefer isomorphic code like fetch and ReadableStream instead of Node.js-specific code

Files:

  • packages/trigger-sdk/src/v3/chat.ts
  • packages/trigger-sdk/src/v3/chat-constants.ts
  • packages/trigger-sdk/src/v3/streams.ts
  • packages/trigger-sdk/src/v3/chat.test.ts
  • packages/trigger-sdk/src/v3/chat-react.ts
  • packages/trigger-sdk/src/v3/ai.ts
packages/trigger-sdk/**/*.{ts,tsx,js,jsx}

📄 CodeRabbit inference engine (packages/trigger-sdk/CLAUDE.md)

Always import from @trigger.dev/sdk. Never use @trigger.dev/sdk/v3 (deprecated path alias)

Files:

  • packages/trigger-sdk/src/v3/chat.ts
  • packages/trigger-sdk/src/v3/chat-constants.ts
  • packages/trigger-sdk/src/v3/streams.ts
  • packages/trigger-sdk/src/v3/chat.test.ts
  • packages/trigger-sdk/src/v3/chat-react.ts
  • packages/trigger-sdk/src/v3/ai.ts
**/*.{test,spec}.{ts,tsx}

📄 CodeRabbit inference engine (.github/copilot-instructions.md)

Use vitest for all tests in the Trigger.dev repository

Files:

  • packages/trigger-sdk/src/v3/chat.test.ts
**/*.test.{ts,tsx,js,jsx}

📄 CodeRabbit inference engine (AGENTS.md)

**/*.test.{ts,tsx,js,jsx}: Test files should live beside the files under test and use descriptive describe and it blocks
Tests should avoid mocks or stubs and use the helpers from @internal/testcontainers when Redis or Postgres are needed
Use vitest for running unit tests

Files:

  • packages/trigger-sdk/src/v3/chat.test.ts
**/*.test.{ts,tsx,js}

📄 CodeRabbit inference engine (CLAUDE.md)

**/*.test.{ts,tsx,js}: Use vitest exclusively for testing - never mock anything, use testcontainers instead
Place test files next to source files with .test.ts naming convention (e.g., MyService.ts -> MyService.test.ts)
Test files using Redis or PostgreSQL should use testcontainers helpers (redisTest, postgresTest, containerTest) instead of mocks

Files:

  • packages/trigger-sdk/src/v3/chat.test.ts
🧠 Learnings (51)
📓 Common learnings
Learnt from: CR
Repo: triggerdotdev/trigger.dev PR: 0
File: .cursor/rules/writing-tasks.mdc:0-0
Timestamp: 2025-11-27T16:27:35.304Z
Learning: Applies to **/trigger/**/*.{ts,tsx,js,jsx} : Use `.withStreams()` to subscribe to realtime streams from task metadata in addition to run changes
Learnt from: CR
Repo: triggerdotdev/trigger.dev PR: 0
File: .github/copilot-instructions.md:0-0
Timestamp: 2025-11-27T16:26:37.432Z
Learning: Applies to packages/trigger-sdk/**/*.{ts,tsx} : In the Trigger.dev SDK (packages/trigger-sdk), prefer isomorphic code like fetch and ReadableStream instead of Node.js-specific code
Learnt from: CR
Repo: triggerdotdev/trigger.dev PR: 0
File: .github/copilot-instructions.md:0-0
Timestamp: 2025-11-27T16:26:37.432Z
Learning: The SDK at packages/trigger-sdk is an isomorphic TypeScript SDK
Learnt from: CR
Repo: triggerdotdev/trigger.dev PR: 0
File: .cursor/rules/writing-tasks.mdc:0-0
Timestamp: 2025-11-27T16:27:35.304Z
Learning: Applies to **/trigger/**/*.{ts,tsx,js,jsx} : Use `trigger.dev/sdk/v3` for all imports in Trigger.dev tasks
Learnt from: CR
Repo: triggerdotdev/trigger.dev PR: 0
File: .cursor/rules/webapp.mdc:0-0
Timestamp: 2025-11-27T16:26:58.661Z
Learning: Applies to apps/webapp/**/*.{ts,tsx} : When importing from `trigger.dev/core` in the webapp, use subpath exports from the package.json instead of importing from the root path
📚 Learning: 2026-03-02T12:43:34.140Z
Learnt from: CR
Repo: triggerdotdev/trigger.dev PR: 0
File: packages/cli-v3/CLAUDE.md:0-0
Timestamp: 2026-03-02T12:43:34.140Z
Learning: Keep SDK documentation in `rules/` and `.claude/skills/trigger-dev-tasks/` synchronized when features are added or changed

Applied to files:

  • docs/guides/ai-chat.mdx
  • CLAUDE.md
  • .claude/rules/package-installation.md
📚 Learning: 2025-11-27T16:27:35.304Z
Learnt from: CR
Repo: triggerdotdev/trigger.dev PR: 0
File: .cursor/rules/writing-tasks.mdc:0-0
Timestamp: 2025-11-27T16:27:35.304Z
Learning: Applies to **/trigger/**/*.{ts,tsx,js,jsx} : Use `trigger.dev/sdk/v3` for all imports in Trigger.dev tasks

Applied to files:

  • docs/guides/ai-chat.mdx
  • packages/trigger-sdk/src/v3/chat.ts
  • packages/trigger-sdk/src/v3/chat-constants.ts
  • packages/trigger-sdk/src/v3/chat.test.ts
  • packages/trigger-sdk/src/v3/chat-react.ts
  • packages/trigger-sdk/package.json
  • .changeset/ai-sdk-chat-transport.md
  • packages/trigger-sdk/src/v3/ai.ts
📚 Learning: 2026-03-02T12:43:37.906Z
Learnt from: CR
Repo: triggerdotdev/trigger.dev PR: 0
File: packages/core/CLAUDE.md:0-0
Timestamp: 2026-03-02T12:43:37.906Z
Learning: Exercise caution with changes to trigger.dev/core as they affect both the customer-facing SDK and server-side webapp - breaking changes can impact deployed user tasks and the platform simultaneously

Applied to files:

  • docs/guides/ai-chat.mdx
📚 Learning: 2025-11-27T16:27:35.304Z
Learnt from: CR
Repo: triggerdotdev/trigger.dev PR: 0
File: .cursor/rules/writing-tasks.mdc:0-0
Timestamp: 2025-11-27T16:27:35.304Z
Learning: Applies to **/trigger/**/*.{ts,tsx,js,jsx} : Use `.withStreams()` to subscribe to realtime streams from task metadata in addition to run changes

Applied to files:

  • docs/guides/ai-chat.mdx
  • packages/trigger-sdk/src/v3/chat.ts
  • packages/trigger-sdk/src/v3/chat-constants.ts
  • packages/trigger-sdk/src/v3/streams.ts
  • packages/trigger-sdk/src/v3/chat.test.ts
  • packages/trigger-sdk/src/v3/chat-react.ts
  • .changeset/ai-sdk-chat-transport.md
  • packages/core/src/v3/realtimeStreams/types.ts
  • packages/trigger-sdk/src/v3/ai.ts
📚 Learning: 2025-11-27T16:27:35.304Z
Learnt from: CR
Repo: triggerdotdev/trigger.dev PR: 0
File: .cursor/rules/writing-tasks.mdc:0-0
Timestamp: 2025-11-27T16:27:35.304Z
Learning: Applies to **/trigger/**/*.{ts,tsx,js,jsx} : Use the `task()` function from `trigger.dev/sdk/v3` to define tasks with id and run properties

Applied to files:

  • docs/guides/ai-chat.mdx
  • packages/trigger-sdk/src/v3/chat.ts
  • packages/trigger-sdk/src/v3/chat-react.ts
  • .changeset/ai-sdk-chat-transport.md
  • packages/trigger-sdk/src/v3/ai.ts
📚 Learning: 2025-11-27T16:27:35.304Z
Learnt from: CR
Repo: triggerdotdev/trigger.dev PR: 0
File: .cursor/rules/writing-tasks.mdc:0-0
Timestamp: 2025-11-27T16:27:35.304Z
Learning: Applies to **/trigger/**/*.{ts,tsx,js,jsx} : Use `yourTask.trigger()` to trigger a task from inside another task with specified payload

Applied to files:

  • docs/guides/ai-chat.mdx
📚 Learning: 2025-11-27T16:27:35.304Z
Learnt from: CR
Repo: triggerdotdev/trigger.dev PR: 0
File: .cursor/rules/writing-tasks.mdc:0-0
Timestamp: 2025-11-27T16:27:35.304Z
Learning: Applies to **/trigger/**/*.{ts,tsx,js,jsx} : Use `schemaTask()` from `trigger.dev/sdk/v3` with Zod schema for payload validation

Applied to files:

  • docs/guides/ai-chat.mdx
  • packages/trigger-sdk/src/v3/chat.ts
  • packages/trigger-sdk/src/v3/chat-react.ts
  • packages/trigger-sdk/package.json
  • .changeset/ai-sdk-chat-transport.md
  • packages/trigger-sdk/src/v3/ai.ts
📚 Learning: 2025-11-27T16:27:35.304Z
Learnt from: CR
Repo: triggerdotdev/trigger.dev PR: 0
File: .cursor/rules/writing-tasks.mdc:0-0
Timestamp: 2025-11-27T16:27:35.304Z
Learning: Applies to **/trigger/**/*.{ts,tsx,js,jsx} : Use `tasks.trigger()` with type-only imports to trigger tasks from backend code without importing the task implementation

Applied to files:

  • docs/guides/ai-chat.mdx
  • packages/trigger-sdk/src/v3/chat.ts
  • packages/trigger-sdk/src/v3/chat-react.ts
  • packages/trigger-sdk/package.json
  • .changeset/ai-sdk-chat-transport.md
  • packages/trigger-sdk/src/v3/ai.ts
📚 Learning: 2025-11-27T16:27:35.304Z
Learnt from: CR
Repo: triggerdotdev/trigger.dev PR: 0
File: .cursor/rules/writing-tasks.mdc:0-0
Timestamp: 2025-11-27T16:27:35.304Z
Learning: Use `TriggerAuthContext` provider to supply Public Access Token to Trigger.dev React hooks

Applied to files:

  • docs/guides/ai-chat.mdx
  • packages/trigger-sdk/src/v3/chat-react.ts
📚 Learning: 2026-02-25T17:28:20.456Z
Learnt from: isshaddad
Repo: triggerdotdev/trigger.dev PR: 3130
File: docs/v3-openapi.yaml:3134-3135
Timestamp: 2026-02-25T17:28:20.456Z
Learning: In the Trigger.dev codebase, the `publicAccessToken` returned by the SDK's `wait.createToken()` method is not part of the HTTP response body from `POST /api/v1/waitpoints/tokens`. The server returns only `{ id, isCached, url }`. The SDK's `prepareData` hook generates the JWT client-side from the `x-trigger-jwt-claims` response header after the HTTP call completes. The OpenAPI spec correctly documents only the HTTP response body, not SDK transformations.
<!-- [/add_learning]

Applied to files:

  • docs/guides/ai-chat.mdx
📚 Learning: 2025-11-27T16:26:37.432Z
Learnt from: CR
Repo: triggerdotdev/trigger.dev PR: 0
File: .github/copilot-instructions.md:0-0
Timestamp: 2025-11-27T16:26:37.432Z
Learning: The SDK at packages/trigger-sdk is an isomorphic TypeScript SDK

Applied to files:

  • docs/guides/ai-chat.mdx
  • packages/trigger-sdk/src/v3/chat.ts
  • packages/trigger-sdk/src/v3/chat-constants.ts
  • packages/trigger-sdk/src/v3/chat.test.ts
  • packages/trigger-sdk/src/v3/chat-react.ts
  • packages/trigger-sdk/package.json
  • .changeset/ai-sdk-chat-transport.md
📚 Learning: 2025-11-27T16:27:35.304Z
Learnt from: CR
Repo: triggerdotdev/trigger.dev PR: 0
File: .cursor/rules/writing-tasks.mdc:0-0
Timestamp: 2025-11-27T16:27:35.304Z
Learning: Applies to **/trigger/**/*.{ts,tsx,js,jsx} : Use `tasks.batchTrigger()` to trigger multiple runs of a single task with different payloads

Applied to files:

  • docs/guides/ai-chat.mdx
  • packages/trigger-sdk/src/v3/chat.test.ts
  • .scratch/plan-graceful-oversized-batch-items.md
📚 Learning: 2026-03-02T12:43:02.539Z
Learnt from: CR
Repo: triggerdotdev/trigger.dev PR: 0
File: docs/CLAUDE.md:0-0
Timestamp: 2026-03-02T12:43:02.539Z
Learning: Organize documentation across appropriate directories: `documentation/` for core conceptual docs, `guides/` for how-to guides, `config/` for configuration reference, `deployment/` for deployment guides, `tasks/` for task documentation, `realtime/` for real-time features, `runs/` for run management, and `images/` for assets

Applied to files:

  • docs/docs.json
📚 Learning: 2025-11-27T16:26:37.432Z
Learnt from: CR
Repo: triggerdotdev/trigger.dev PR: 0
File: .github/copilot-instructions.md:0-0
Timestamp: 2025-11-27T16:26:37.432Z
Learning: Applies to packages/trigger-sdk/**/*.{ts,tsx} : In the Trigger.dev SDK (packages/trigger-sdk), prefer isomorphic code like fetch and ReadableStream instead of Node.js-specific code

Applied to files:

  • packages/trigger-sdk/src/v3/chat.ts
  • packages/trigger-sdk/src/v3/chat-constants.ts
  • packages/trigger-sdk/src/v3/chat.test.ts
  • packages/trigger-sdk/src/v3/chat-react.ts
  • packages/trigger-sdk/package.json
  • .changeset/ai-sdk-chat-transport.md
📚 Learning: 2026-03-02T12:43:48.124Z
Learnt from: CR
Repo: triggerdotdev/trigger.dev PR: 0
File: packages/trigger-sdk/CLAUDE.md:0-0
Timestamp: 2026-03-02T12:43:48.124Z
Learning: Applies to packages/trigger-sdk/**/*.{ts,tsx,js,jsx} : Always import from `trigger.dev/sdk`. Never use `trigger.dev/sdk/v3` (deprecated path alias)

Applied to files:

  • packages/trigger-sdk/src/v3/chat.ts
  • packages/trigger-sdk/src/v3/chat-constants.ts
  • packages/trigger-sdk/src/v3/chat-react.ts
  • packages/trigger-sdk/package.json
  • .changeset/ai-sdk-chat-transport.md
  • packages/trigger-sdk/src/v3/ai.ts
📚 Learning: 2025-11-27T16:27:35.304Z
Learnt from: CR
Repo: triggerdotdev/trigger.dev PR: 0
File: .cursor/rules/writing-tasks.mdc:0-0
Timestamp: 2025-11-27T16:27:35.304Z
Learning: Applies to **/trigger/**/*.{ts,tsx,js,jsx} : Export tasks with unique IDs within the project to enable proper task discovery and execution

Applied to files:

  • packages/trigger-sdk/src/v3/chat.ts
  • packages/trigger-sdk/src/v3/chat-react.ts
  • packages/trigger-sdk/package.json
  • packages/trigger-sdk/src/v3/ai.ts
📚 Learning: 2026-03-02T12:42:41.110Z
Learnt from: CR
Repo: triggerdotdev/trigger.dev PR: 0
File: CLAUDE.md:0-0
Timestamp: 2026-03-02T12:42:41.110Z
Learning: Applies to **/*.{ts,tsx} : In TypeScript SDK usage, always import from trigger.dev/sdk, never from trigger.dev/sdk/v3 or use deprecated client.defineJob

Applied to files:

  • packages/trigger-sdk/src/v3/chat.ts
  • packages/trigger-sdk/src/v3/chat-react.ts
  • packages/trigger-sdk/package.json
  • .changeset/ai-sdk-chat-transport.md
📚 Learning: 2026-03-02T12:42:41.110Z
Learnt from: CR
Repo: triggerdotdev/trigger.dev PR: 0
File: CLAUDE.md:0-0
Timestamp: 2026-03-02T12:42:41.110Z
Learning: Applies to packages/**/*.{ts,tsx,js},integrations/**/*.{ts,tsx,js} : When modifying public packages (packages/* or integrations/*), add a changeset via pnpm run changeset:add

Applied to files:

  • CLAUDE.md
  • .claude/rules/package-installation.md
  • packages/trigger-sdk/package.json
📚 Learning: 2026-03-02T12:43:48.124Z
Learnt from: CR
Repo: triggerdotdev/trigger.dev PR: 0
File: packages/trigger-sdk/CLAUDE.md:0-0
Timestamp: 2026-03-02T12:43:48.124Z
Learning: Do NOT update `.claude/skills/trigger-dev-tasks/` directory files unless explicitly asked - these are maintained in separate dedicated passes

Applied to files:

  • CLAUDE.md
📚 Learning: 2026-03-02T12:43:34.140Z
Learnt from: CR
Repo: triggerdotdev/trigger.dev PR: 0
File: packages/cli-v3/CLAUDE.md:0-0
Timestamp: 2026-03-02T12:43:34.140Z
Learning: Applies to packages/cli-v3/.claude/skills/trigger-dev-tasks/**/* : Update `.claude/skills/trigger-dev-tasks/` in parallel with `rules/` when SDK features change

Applied to files:

  • CLAUDE.md
  • .claude/rules/package-installation.md
📚 Learning: 2026-03-02T12:42:41.110Z
Learnt from: CR
Repo: triggerdotdev/trigger.dev PR: 0
File: CLAUDE.md:0-0
Timestamp: 2026-03-02T12:42:41.110Z
Learning: Applies to docs/**/*.{md,mdx} : Docs in docs/ directory should use Mintlify MDX format following conventions in docs/CLAUDE.md

Applied to files:

  • CLAUDE.md
  • .claude/rules/package-installation.md
📚 Learning: 2026-03-02T12:43:34.140Z
Learnt from: CR
Repo: triggerdotdev/trigger.dev PR: 0
File: packages/cli-v3/CLAUDE.md:0-0
Timestamp: 2026-03-02T12:43:34.140Z
Learning: Applies to packages/cli-v3/rules/**/* : Update `rules/` directory with versioned SDK documentation when SDK features change

Applied to files:

  • CLAUDE.md
  • .claude/rules/package-installation.md
📚 Learning: 2026-03-02T12:42:41.110Z
Learnt from: CR
Repo: triggerdotdev/trigger.dev PR: 0
File: CLAUDE.md:0-0
Timestamp: 2026-03-02T12:42:41.110Z
Learning: This is a pnpm 10.23.0 monorepo using Turborepo - run commands from root with pnpm run

Applied to files:

  • CLAUDE.md
  • .claude/rules/package-installation.md
📚 Learning: 2025-11-27T16:26:44.496Z
Learnt from: CR
Repo: triggerdotdev/trigger.dev PR: 0
File: .cursor/rules/executing-commands.mdc:0-0
Timestamp: 2025-11-27T16:26:44.496Z
Learning: Execute most monorepo commands using `pnpm run` from the root directory, with `--filter` flag for specific packages (e.g., `pnpm run dev --filter webapp`)

Applied to files:

  • CLAUDE.md
  • .claude/rules/package-installation.md
📚 Learning: 2025-11-27T16:26:44.496Z
Learnt from: CR
Repo: triggerdotdev/trigger.dev PR: 0
File: .cursor/rules/executing-commands.mdc:0-0
Timestamp: 2025-11-27T16:26:44.496Z
Learning: For running tests, navigate into the package directory and run `pnpm run test --run` to enable single-file test execution (e.g., `pnpm run test ./src/engine/tests/ttl.test.ts --run`)

Applied to files:

  • CLAUDE.md
  • .claude/rules/package-installation.md
📚 Learning: 2026-01-15T10:48:02.687Z
Learnt from: CR
Repo: triggerdotdev/trigger.dev PR: 0
File: AGENTS.md:0-0
Timestamp: 2026-01-15T10:48:02.687Z
Learning: Use pnpm as the package manager (version 10.23.0 or later) and Node.js 20.20.0

Applied to files:

  • CLAUDE.md
  • .claude/rules/package-installation.md
📚 Learning: 2025-11-27T16:26:47.602Z
Learnt from: CR
Repo: triggerdotdev/trigger.dev PR: 0
File: .cursor/rules/repo.mdc:0-0
Timestamp: 2025-11-27T16:26:47.602Z
Learning: Refer to the monorepo structure documentation at repo.md before making changes or adding new files

Applied to files:

  • CLAUDE.md
  • .claude/rules/package-installation.md
📚 Learning: 2026-03-02T12:43:17.177Z
Learnt from: CR
Repo: triggerdotdev/trigger.dev PR: 0
File: internal-packages/database/CLAUDE.md:0-0
Timestamp: 2026-03-02T12:43:17.177Z
Learning: Edit Prisma schema at `prisma/schema.prisma` and generate migrations using `pnpm run db:migrate:dev:create --name "descriptive_name"` from the `internal-packages/database` directory

Applied to files:

  • CLAUDE.md
📚 Learning: 2026-03-02T12:43:37.906Z
Learnt from: CR
Repo: triggerdotdev/trigger.dev PR: 0
File: packages/core/CLAUDE.md:0-0
Timestamp: 2026-03-02T12:43:37.906Z
Learning: Applies to packages/core/**/*.{ts,tsx,js,jsx} : Never import the root package (trigger.dev/core). Always use subpath imports such as trigger.dev/core/v3, trigger.dev/core/v3/utils, trigger.dev/core/logger, or trigger.dev/core/schemas

Applied to files:

  • .claude/rules/package-installation.md
  • packages/trigger-sdk/package.json
📚 Learning: 2025-11-27T16:26:37.432Z
Learnt from: CR
Repo: triggerdotdev/trigger.dev PR: 0
File: .github/copilot-instructions.md:0-0
Timestamp: 2025-11-27T16:26:37.432Z
Learning: Applies to **/*.{test,spec}.{ts,tsx} : Use vitest for all tests in the Trigger.dev repository

Applied to files:

  • packages/trigger-sdk/src/v3/chat.test.ts
📚 Learning: 2025-11-27T16:27:35.304Z
Learnt from: CR
Repo: triggerdotdev/trigger.dev PR: 0
File: .cursor/rules/writing-tasks.mdc:0-0
Timestamp: 2025-11-27T16:27:35.304Z
Learning: Applies to **/trigger/**/*.{ts,tsx,js,jsx} : Use `batch.triggerAndWait()` to batch trigger multiple different tasks and wait for results

Applied to files:

  • packages/trigger-sdk/src/v3/chat.test.ts
📚 Learning: 2025-11-27T16:27:35.304Z
Learnt from: CR
Repo: triggerdotdev/trigger.dev PR: 0
File: .cursor/rules/writing-tasks.mdc:0-0
Timestamp: 2025-11-27T16:27:35.304Z
Learning: Applies to **/trigger/**/*.{ts,tsx,js,jsx} : Use `batch.triggerByTaskAndWait()` to batch trigger tasks by passing task instances and wait for results

Applied to files:

  • packages/trigger-sdk/src/v3/chat.test.ts
📚 Learning: 2025-11-27T16:27:35.304Z
Learnt from: CR
Repo: triggerdotdev/trigger.dev PR: 0
File: .cursor/rules/writing-tasks.mdc:0-0
Timestamp: 2025-11-27T16:27:35.304Z
Learning: Applies to **/trigger/**/*.{ts,tsx,js,jsx} : Use `yourTask.batchTrigger()` to trigger multiple runs of a task from inside another task

Applied to files:

  • packages/trigger-sdk/src/v3/chat.test.ts
📚 Learning: 2025-11-27T16:27:35.304Z
Learnt from: CR
Repo: triggerdotdev/trigger.dev PR: 0
File: .cursor/rules/writing-tasks.mdc:0-0
Timestamp: 2025-11-27T16:27:35.304Z
Learning: Applies to **/trigger/**/*.{ts,tsx,js,jsx} : Use `yourTask.triggerAndWait()` to trigger a task and wait for its result from a parent task

Applied to files:

  • packages/trigger-sdk/src/v3/chat.test.ts
📚 Learning: 2025-11-27T16:27:35.304Z
Learnt from: CR
Repo: triggerdotdev/trigger.dev PR: 0
File: .cursor/rules/writing-tasks.mdc:0-0
Timestamp: 2025-11-27T16:27:35.304Z
Learning: Applies to **/trigger/**/*.{ts,tsx,js,jsx} : Use `yourTask.batchTriggerAndWait()` to batch trigger tasks and wait for all results from a parent task

Applied to files:

  • packages/trigger-sdk/src/v3/chat.test.ts
📚 Learning: 2025-11-27T16:27:35.304Z
Learnt from: CR
Repo: triggerdotdev/trigger.dev PR: 0
File: .cursor/rules/writing-tasks.mdc:0-0
Timestamp: 2025-11-27T16:27:35.304Z
Learning: Use `trigger.dev/react-hooks` package for realtime subscriptions in React components

Applied to files:

  • packages/trigger-sdk/src/v3/chat-react.ts
📚 Learning: 2025-11-27T16:27:35.304Z
Learnt from: CR
Repo: triggerdotdev/trigger.dev PR: 0
File: .cursor/rules/writing-tasks.mdc:0-0
Timestamp: 2025-11-27T16:27:35.304Z
Learning: Use `useRun`, `useRealtimeRun` and other SWR/realtime hooks from `trigger.dev/react-hooks` for data fetching

Applied to files:

  • packages/trigger-sdk/src/v3/chat-react.ts
📚 Learning: 2026-03-03T13:07:33.177Z
Learnt from: ericallam
Repo: triggerdotdev/trigger.dev PR: 3166
File: internal-packages/run-engine/src/batch-queue/tests/index.test.ts:711-713
Timestamp: 2026-03-03T13:07:33.177Z
Learning: In `internal-packages/run-engine/src/batch-queue/tests/index.test.ts`, test assertions for rate limiter stubs can use `toBeGreaterThanOrEqual` rather than exact equality (`toBe`) because the consumer loop may call the rate limiter during empty pops in addition to actual item processing, and this over-calling is acceptable in integration tests.

Applied to files:

  • .scratch/plan-graceful-oversized-batch-items.md
📚 Learning: 2026-03-03T13:08:03.862Z
Learnt from: ericallam
Repo: triggerdotdev/trigger.dev PR: 3166
File: packages/redis-worker/src/fair-queue/index.ts:1114-1121
Timestamp: 2026-03-03T13:08:03.862Z
Learning: In packages/redis-worker/src/fair-queue/index.ts, it's acceptable for the worker queue depth cap check to allow overshooting by up to batchClaimSize messages per iteration, as the next iteration will recheck and prevent sustained growth beyond the limit.

Applied to files:

  • .scratch/plan-graceful-oversized-batch-items.md
📚 Learning: 2025-11-27T16:26:58.661Z
Learnt from: CR
Repo: triggerdotdev/trigger.dev PR: 0
File: .cursor/rules/webapp.mdc:0-0
Timestamp: 2025-11-27T16:26:58.661Z
Learning: Applies to apps/webapp/**/*.{ts,tsx} : When importing from `trigger.dev/core` in the webapp, use subpath exports from the package.json instead of importing from the root path

Applied to files:

  • packages/trigger-sdk/package.json
  • .changeset/ai-sdk-chat-transport.md
📚 Learning: 2025-11-27T16:27:35.304Z
Learnt from: CR
Repo: triggerdotdev/trigger.dev PR: 0
File: .cursor/rules/writing-tasks.mdc:0-0
Timestamp: 2025-11-27T16:27:35.304Z
Learning: Applies to **/trigger.config.ts : Configure build process in trigger.config.ts using `build` object with external packages, extensions, and JSX settings

Applied to files:

  • packages/trigger-sdk/package.json
📚 Learning: 2026-03-02T12:43:34.140Z
Learnt from: CR
Repo: triggerdotdev/trigger.dev PR: 0
File: packages/cli-v3/CLAUDE.md:0-0
Timestamp: 2026-03-02T12:43:34.140Z
Learning: Applies to packages/cli-v3/src/build/**/* : Build system in `src/build/` should use configuration from `trigger.config.ts` in user projects to determine bundling, build extensions, and output structure

Applied to files:

  • packages/trigger-sdk/package.json
📚 Learning: 2026-03-02T12:42:41.110Z
Learnt from: CR
Repo: triggerdotdev/trigger.dev PR: 0
File: CLAUDE.md:0-0
Timestamp: 2026-03-02T12:42:41.110Z
Learning: Applies to **/*.{ts,tsx} : Import from trigger.dev/core subpaths only, never from the root

Applied to files:

  • packages/trigger-sdk/package.json
📚 Learning: 2025-11-27T16:27:35.304Z
Learnt from: CR
Repo: triggerdotdev/trigger.dev PR: 0
File: .cursor/rules/writing-tasks.mdc:0-0
Timestamp: 2025-11-27T16:27:35.304Z
Learning: Applies to **/trigger.config.ts : Specify task locations in trigger.config.ts using the `dirs` array, with automatic exclusion of .test and .spec files

Applied to files:

  • packages/trigger-sdk/package.json
📚 Learning: 2025-11-27T16:26:58.661Z
Learnt from: CR
Repo: triggerdotdev/trigger.dev PR: 0
File: .cursor/rules/webapp.mdc:0-0
Timestamp: 2025-11-27T16:26:58.661Z
Learning: Applies to apps/webapp/**/*.{ts,tsx} : Follow the Remix 2.1.0 and Express server conventions when updating the main trigger.dev webapp

Applied to files:

  • packages/trigger-sdk/package.json
📚 Learning: 2025-11-27T16:27:35.304Z
Learnt from: CR
Repo: triggerdotdev/trigger.dev PR: 0
File: .cursor/rules/writing-tasks.mdc:0-0
Timestamp: 2025-11-27T16:27:35.304Z
Learning: Applies to **/trigger.config.ts : Use build extensions in trigger.config.ts (additionalFiles, additionalPackages, aptGet, prismaExtension, etc.) to customize the build

Applied to files:

  • packages/trigger-sdk/package.json
📚 Learning: 2025-11-26T14:40:07.146Z
Learnt from: ericallam
Repo: triggerdotdev/trigger.dev PR: 2710
File: packages/schema-to-json/package.json:0-0
Timestamp: 2025-11-26T14:40:07.146Z
Learning: Node.js 24+ has native TypeScript support and can execute .ts files directly without tsx or ts-node for scripts that use only erasable TypeScript syntax (type annotations, interfaces, etc.). The trigger.dev repository uses Node.js 24.11.1+ and scripts like updateVersion.ts can be run with `node` instead of `tsx`.

Applied to files:

  • packages/trigger-sdk/package.json
📚 Learning: 2025-11-27T16:27:35.304Z
Learnt from: CR
Repo: triggerdotdev/trigger.dev PR: 0
File: .cursor/rules/writing-tasks.mdc:0-0
Timestamp: 2025-11-27T16:27:35.304Z
Learning: Applies to **/trigger/**/*.{ts,tsx,js,jsx} : Attach metadata to task runs using the metadata option when triggering, and access/update it inside runs using metadata functions

Applied to files:

  • packages/trigger-sdk/src/v3/ai.ts
📚 Learning: 2025-11-27T16:27:35.304Z
Learnt from: CR
Repo: triggerdotdev/trigger.dev PR: 0
File: .cursor/rules/writing-tasks.mdc:0-0
Timestamp: 2025-11-27T16:27:35.304Z
Learning: Applies to **/trigger/**/*.{ts,tsx,js,jsx} : Use metadata methods (set, del, replace, append, remove, increment, decrement, stream, flush) to update metadata during task execution

Applied to files:

  • packages/trigger-sdk/src/v3/ai.ts
📚 Learning: 2025-11-27T16:27:35.304Z
Learnt from: CR
Repo: triggerdotdev/trigger.dev PR: 0
File: .cursor/rules/writing-tasks.mdc:0-0
Timestamp: 2025-11-27T16:27:35.304Z
Learning: Applies to **/trigger/**/*.{ts,tsx,js,jsx} : Use logger methods (debug, log, info, warn, error) from `trigger.dev/sdk/v3` for structured logging in tasks

Applied to files:

  • packages/trigger-sdk/src/v3/ai.ts
🪛 markdownlint-cli2 (0.21.0)
.scratch/plan-graceful-oversized-batch-items.md

[warning] 216-216: Fenced code blocks should have a language specified

(MD040, fenced-code-language)

🔇 Additional comments (24)
.claude/rules/package-installation.md (1)

10-22: Clear and actionable monorepo dependency install workflow.

The new guidance is explicit and practical for this repo setup.

CLAUDE.md (1)

9-10: Good top-level pointer to the package-installation rule.

This keeps root instructions concise while linking to the detailed process.

packages/core/src/v3/realtimeStreams/types.ts (1)

74-77: Nice API surface extension for tracing customization.

The new optional fields are additive and maintain compatibility.

Also applies to: 206-207, 244-245

packages/trigger-sdk/src/v3/chat-constants.ts (1)

1-13: Good centralization of chat stream identifiers.

This avoids string duplication across the chat transport stack.

packages/trigger-sdk/src/v3/streams.ts (1)

142-143: Trace/span and input-wait lifecycle updates look consistent.

The new options and waitpoint flow changes integrate cleanly with the stream abstractions.

Also applies to: 170-171, 644-645, 717-717, 754-804, 819-820

packages/trigger-sdk/package.json (1)

27-30: Export map and peer/type wiring for chat subpaths look solid.

./chat and ./chat/react are consistently mapped across build, runtime, and type resolution.

Also applies to: 42-48, 77-77, 90-100, 139-161

docs/docs.json (1)

77-77: Navigation update is correctly placed.

Adding guides/ai-chat under “Writing tasks” is consistent with the existing docs structure.

packages/core/src/v3/inputStreams/manager.ts (2)

43-61: LGTM! New stream management methods are well-implemented.

The setLastSeqNum correctly guards against backward sequence number movement, shiftBuffer properly handles cleanup when the buffer becomes empty, and both methods align with the documented behavior in types.ts.


181-188: LGTM! Clean stream disconnection implementation.

The disconnectStream method properly aborts the tail's AbortController and cleans up both the tail and buffer entries for the stream.

packages/core/src/v3/inputStreams/index.ts (1)

54-64: LGTM! API wrappers follow established patterns.

The new methods correctly delegate to the underlying manager and maintain consistency with the existing API surface.

packages/core/src/v3/inputStreams/noopManager.ts (1)

25-29: LGTM! Correct no-op implementations.

The no-op methods properly implement the InputStreamManager interface with appropriate default behavior: shiftBuffer returns false (nothing to shift), and the others are silent no-ops.

docs/guides/ai-chat.mdx (3)

1-5: LGTM! Well-structured documentation with proper Mintlify frontmatter.

The documentation follows the MDX guidelines with required frontmatter fields (title, description) and optional sidebarTitle.


69-112: Frontend example is clear and practical.

The React component example demonstrates the integration pattern well. The code is complete and follows React conventions.


19-21: Version requirement callout is clear and accurate. The @ai-sdk/react import path referenced in the file (line 72) is the correct path for AI SDK v5.0.0 and later. No issues found.

packages/core/src/v3/inputStreams/types.ts (1)

73-93: LGTM! Excellent documentation for the new interface methods.

The JSDoc comments clearly explain the purpose of each method in the context of waitpoint handling and SSE tail management. The documentation will help consumers understand when and why to use each method.

.changeset/ai-sdk-chat-transport.md (1)

1-42: LGTM! Well-documented changeset with clear examples.

The minor version bump is appropriate for adding new features. The examples clearly demonstrate the usage of both frontend and backend exports.

packages/trigger-sdk/src/v3/chat.test.ts (3)

49-59: LGTM! Good test setup/teardown pattern.

The beforeEach/afterEach correctly saves and restores global.fetch, and vi.restoreAllMocks() ensures clean state between tests.


919-1022: Excellent coverage of lastEventId tracking and SSE reconnection.

The tests thoroughly verify that Last-Event-ID is passed correctly on subsequent stream subscriptions, which is critical for proper SSE resumption behavior.


1264-1614: Comprehensive waitpoint/single-run mode test coverage.

The tests cover important edge cases: storing waitpoint tokens, completing waitpoints on subsequent messages, fallback behavior when streams close unexpectedly, and fallback when waitpoint completion fails. This is crucial for the durable chat session feature.

packages/trigger-sdk/src/v3/chat.ts (5)

1-31: LGTM!

Clear module documentation with a practical usage example. Imports are appropriate for a browser-safe module, using the ai package types and @trigger.dev/core/v3 utilities that are isomorphic.


38-116: LGTM!

Type definitions are well-structured with comprehensive JSDoc. The accessToken flexibility (supporting sync/async functions) is a nice pattern for dynamic token refresh and Next.js server actions.


308-389: Well-structured ReadableStream implementation.

The streaming logic correctly handles:

  • Turn completion via __trigger_turn_complete control chunks
  • Skip-to-turn-complete state for abort/resume scenarios
  • lastEventId tracking for stream resumption
  • Defensive cleanup with try-catch on controller.close()

The error handling properly distinguishes between AbortError (expected on stop) and other errors.


243-254: LGTM!

The reconnectToStream method correctly handles missing sessions by returning null. The createChatTransport factory function provides a clean functional alternative with good documentation.

Also applies to: 392-412


274-277: ⚠️ Potential issue | 🔴 Critical

Update minimum Node.js engine requirement to match AbortSignal.any() availability.

The SDK declares engines.node >= 18.20.0 in package.json, but uses AbortSignal.any() (line 276) which requires Node 20.3.0+. This mismatch will cause runtime errors for Node 18.x and Node 20.0–20.2.x users.

Either:

  • Update engines.node to >= 20.3.0 in package.json, or
  • Replace AbortSignal.any() with manual signal composition for backward compatibility
⛔ Skipped due to learnings
Learnt from: nicktrn
Repo: triggerdotdev/trigger.dev PR: 2593
File: packages/core/src/v3/workers/warmStartClient.ts:168-170
Timestamp: 2025-10-08T11:48:12.327Z
Learning: The trigger.dev runners execute only in Node 21 and 22 environments, so modern Node.js APIs like AbortSignal.any (introduced in v20.3.0) are supported.
Learnt from: CR
Repo: triggerdotdev/trigger.dev PR: 0
File: .github/copilot-instructions.md:0-0
Timestamp: 2025-11-27T16:26:37.432Z
Learning: Applies to packages/trigger-sdk/**/*.{ts,tsx} : In the Trigger.dev SDK (packages/trigger-sdk), prefer isomorphic code like fetch and ReadableStream instead of Node.js-specific code
Learnt from: CR
Repo: triggerdotdev/trigger.dev PR: 0
File: AGENTS.md:0-0
Timestamp: 2026-01-15T10:48:02.687Z
Learning: Use pnpm as the package manager (version 10.23.0 or later) and Node.js 20.20.0

Comment on lines +216 to +238
```
NDJSON bytes arrive
|
createNdjsonParserStream
|-- Line <= limit --> parse JSON --> enqueue object
`-- Line > limit --> extractIndexAndTask(bytes) --> enqueue OversizedItemMarker
|
StreamBatchItemsService for-await loop
|-- OversizedItemMarker --> engine.enqueueBatchItem() with __error in options
`-- Normal item --> validate --> engine.enqueueBatchItem()
|
FairQueue consumer (#handleMessage)
|-- __error in options --> processItemCallback detects it
| --> TriggerFailedTaskService.call()
| --> Creates pre-failed TaskRun with SYSTEM_FAILURE status
| --> Proper waitpoint + TaskRunWaitpoint connections created
| --> Returns { success: true, runId: failedRunFriendlyId }
`-- Normal item --> TriggerTaskService.call() --> creates normal run
|
Batch sealing: enqueuedCount === runCount (all items go through enqueueBatchItem)
Batch completion: all items have runs (real or pre-failed), waitpoints resolve normally
Parent run: batchTriggerAndWait resolves with per-item results
```
Copy link
Contributor

Choose a reason for hiding this comment

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

⚠️ Potential issue | 🟡 Minor

Add a language identifier to the fenced block (Line 216).

This fence is missing a language tag, which trips markdownlint MD040.

📝 Proposed fix
-```
+```text
 NDJSON bytes arrive
   |
 createNdjsonParserStream
   |-- Line <= limit --> parse JSON --> enqueue object
   `-- Line > limit  --> extractIndexAndTask(bytes) --> enqueue OversizedItemMarker
   |
 StreamBatchItemsService for-await loop
   |-- OversizedItemMarker --> engine.enqueueBatchItem() with __error in options
   `-- Normal item         --> validate --> engine.enqueueBatchItem()
   |
 FairQueue consumer (`#handleMessage`)
   |-- __error in options --> processItemCallback detects it
   |     --> TriggerFailedTaskService.call()
   |     --> Creates pre-failed TaskRun with SYSTEM_FAILURE status
   |     --> Proper waitpoint + TaskRunWaitpoint connections created
   |     --> Returns { success: true, runId: failedRunFriendlyId }
   `-- Normal item --> TriggerTaskService.call() --> creates normal run
   |
 Batch sealing: enqueuedCount === runCount (all items go through enqueueBatchItem)
 Batch completion: all items have runs (real or pre-failed), waitpoints resolve normally
 Parent run: batchTriggerAndWait resolves with per-item results
</details>

<!-- suggestion_start -->

<details>
<summary>📝 Committable suggestion</summary>

> ‼️ **IMPORTANT**
> Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

```suggestion

🧰 Tools
🪛 markdownlint-cli2 (0.21.0)

[warning] 216-216: Fenced code blocks should have a language specified

(MD040, fenced-code-language)

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

In @.scratch/plan-graceful-oversized-batch-items.md around lines 216 - 238, The
fenced code block that starts with "NDJSON bytes arrive" is missing a language
identifier which triggers markdownlint MD040; update the opening fence to
include a language (e.g., change ``` to ```text) so the block is explicitly
marked as plain text (ensure the closing fence remains ```), preserving the
existing block contents and indentation.

Comment on lines +268 to +269
let _chatPipeCount = 0;

Copy link
Contributor

Choose a reason for hiding this comment

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

⚠️ Potential issue | 🔴 Critical

Scope manual-pipe tracking per run/turn; global _chatPipeCount is race-prone.

_chatPipeCount is module-global, so concurrent chat runs can mutate the same counter and incorrectly suppress or trigger auto-piping in other runs.

💡 Suggested fix (run-scoped counter)
-import {
+import {
   accessoryAttributes,
   AnyTask,
   isSchemaZodEsque,
   SemanticInternalAttributes,
   Task,
+  taskContext,
   type inferSchemaIn,
   type PipeStreamOptions,
   type TaskIdentifier,
   type TaskOptions,
   type TaskSchema,
   type TaskWithSchema,
 } from "@trigger.dev/core/v3";

-let _chatPipeCount = 0;
+const _chatPipeCountByRun = new Map<string, number>();

 async function pipeChat(
   source: UIMessageStreamable | AsyncIterable<unknown> | ReadableStream<unknown>,
   options?: PipeChatOptions
 ): Promise<void> {
-  _chatPipeCount++;
+  const runId = taskContext.ctx?.run.id;
+  if (runId) {
+    _chatPipeCountByRun.set(runId, (_chatPipeCountByRun.get(runId) ?? 0) + 1);
+  }
   const streamKey = options?.streamKey ?? CHAT_STREAM_KEY;
   // ...
 }

 // inside chatTask turn:
-  _chatPipeCount = 0;
+  const activeRunId = taskContext.ctx?.run.id;
+  if (activeRunId) _chatPipeCountByRun.set(activeRunId, 0);

-  if (_chatPipeCount === 0 && isUIMessageStreamable(result)) {
+  if ((activeRunId ? _chatPipeCountByRun.get(activeRunId) ?? 0 : 0) === 0 && isUIMessageStreamable(result)) {
     await pipeChat(result, { signal: combinedSignal, spanName: "stream response" });
   }

Also applies to: 360-361, 548-583

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

In `@packages/trigger-sdk/src/v3/ai.ts` around lines 268 - 269, The global
_chatPipeCount is race-prone; make the pipe counter scoped to each chat run/turn
instead. Remove the module-global _chatPipeCount and initialize a run-scoped
counter (for example add a numeric property like run.__chatPipeCount or
turn.chatPipeCount on the ChatRun/ChatTurn object when a run/turn is created or
at the start of the function that currently uses _chatPipeCount), then replace
every reference to _chatPipeCount (including uses around lines 360-361 and
548-583) with the run/turn-scoped property and update increment/decrement logic
to use that property so concurrent runs don’t share state. Ensure the counter is
initialized to 0 at run start and cleaned up or left on the run object when
finished.

Comment on lines +560 to +563
const pendingMessages: ChatTaskWirePayload[] = [];
const msgSub = messagesInput.on((msg) => {
pendingMessages.push(msg);
});
Copy link
Contributor

Choose a reason for hiding this comment

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

⚠️ Potential issue | 🔴 Critical

Do not drop extra buffered messages captured during a turn.

At Line 605 only the first queued message is used, while additional messages collected at Line 561 are discarded. Since these were already consumed by the handler, they are lost.

💡 Suggested fix (preserve backlog across turns)
-      let currentWirePayload = payload;
+      let currentWirePayload = payload;
+      const queuedMessages: ChatTaskWirePayload[] = [];

       // ...
       const pendingMessages: ChatTaskWirePayload[] = [];
       const msgSub = messagesInput.on((msg) => {
         pendingMessages.push(msg);
       });

       // ...
       if (pendingMessages.length > 0) {
-        currentWirePayload = pendingMessages[0]!;
+        currentWirePayload = pendingMessages.shift()!;
+        if (pendingMessages.length > 0) {
+          queuedMessages.push(...pendingMessages);
+        }
         return "continue";
       }

+      if (queuedMessages.length > 0) {
+        currentWirePayload = queuedMessages.shift()!;
+        return "continue";
+      }

Also applies to: 605-607

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

In `@packages/trigger-sdk/src/v3/ai.ts` around lines 560 - 563, The handler
currently captures multiple messages into pendingMessages via messagesInput.on
(msgSub) but later only consumes the first entry, discarding the rest; change
the logic that extracts from pendingMessages (where it currently uses a single
element) to drain and preserve the entire backlog — e.g., move all items from
pendingMessages into the processing queue (or append them to the existing
messages array) before proceeding, then clean up the subscription (msgSub) as
before so no buffered messages are lost; update references to pendingMessages,
msgSub, and messagesInput.on to reflect this full-drain behavior.

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.

2 participants