feat(sdk): chat sessions accept concurrencyKey and trigger-time named limits - #4906
matt-aitken wants to merge 8 commits into
Conversation
🦋 Changeset detectedLatest commit: d511299 The changes in this PR will be included in the next version bump. This PR includes changesets to release 27 packages
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 |
|
Note Reviews pausedIt looks like this branch is under active development. To avoid overwhelming you with review comments due to an influx of new commits, CodeRabbit has automatically paused this review. You can configure this behavior by changing the Use the following commands to manage reviews:
Use the checkboxes below for quick actions:
WalkthroughThe change adds shared validation for named concurrency limits and adds Priority: ⬇️ Low Merge Risk: 🟡 Moderate · up to When two requests both start the same chat session at nearly the same time, whichever request's configuration loses the race can silently override the intended per-session concurrency limits or key, so the session may not get the concurrency scoping the caller expects. This should be fixed with a create-if-absent write before merging, though it is a narrow timing window rather than a broad outage risk. 🚥 Pre-merge checks | ✅ 3 | ❌ 2❌ Failed checks (2 warnings)
✅ Passed checks (3 passed)
Full details: Docstring CoverageExplanation Docstring coverage is 55.56% which is insufficient. The required threshold is 80.00%. Docstring coverage is scoped to functions touched by this diff. Analyzed 9 functions across 9 files. (2 skipped: 2 unsupported.) ✨ Finishing Touches 💡 1📝 Generate docstrings 💡
🧪 Generate unit tests (beta)
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. Comment |
@trigger.dev/build
trigger.dev
@trigger.dev/core
@trigger.dev/python
@trigger.dev/react-hooks
@trigger.dev/redis-worker
@trigger.dev/rsc
@trigger.dev/schema-to-json
@trigger.dev/sdk
commit: |
e827c3a to
1dbb27b
Compare
d126a77 to
12e74ba
Compare
12e74ba to
26e870e
Compare
26e870e to
eae339e
Compare
eae339e to
1f029e0
Compare
1f029e0 to
723efdb
Compare
723efdb to
6fc3aca
Compare
6fc3aca to
783acbb
Compare
783acbb to
58ec45f
Compare
58ec45f to
3d315ae
Compare
3d315ae to
f9ea87f
Compare
f9ea87f to
b900600
Compare
b900600 to
6a02ae6
Compare
c5fa7ea to
534623e
Compare
534623e to
dfe4e61
Compare
c6c49c0 to
856e0e8
Compare
856e0e8 to
19cb375
Compare
19cb375 to
94c9edf
Compare
94c9edf to
173b8e2
Compare
173b8e2 to
f27f13e
Compare
…r-time named limits Chat agents already accept the task-level concurrency option, but the session trigger path had no way to scope runs: SessionTriggerConfig now carries concurrencyKey and up to two named limits, threaded through the session run trigger (initial, continuation, and upgrade re-triggers) and forwarded by all three session starters (createStartSessionAction, the AgentChat client, and handover). Keys are never defaulted from the chat ID; a session without one shares the task's keyless pool. Named limits are validated client-side with the same rules as tasks.trigger.
…e module triggerConcurrencyBody and validateConcurrencyLimitName move to a dependency-free module so the chat-server route-handler entrypoint stays lean instead of pulling the task runtime's import graph into customer bundles.
…rsists The session trigger config's concurrency names now carry the charset rule in the schema itself, so an invalid name fails session creation instead of poisoning a persisted, run-less session that fails every retry. The AgentChat client validates through the same dependency-free helper as the other starters, tests pin per-call concurrency precedence and the empty-array clear, and the chat-server import allowlist names the new module.
…ting Webhook deliveries parse the assembled trigger config before creating the session, failing terminally on a bad routing-target template instead of persisting a session that every continuation re-parse would strand. The trigger and batch bodies share the session config's limit-name rule (1-122 chars, letters/numbers/underscores/hyphens), so a bad name is a uniform up-front 400 on every path rather than a late validation error after earlier batch items already triggered.
…ever resumes Template validation moves inside the create branch: resume deliveries to existing sessions never touch the template, so editing a routing target to an invalid template can't terminally fail events to healthy live sessions. A non-object basePayload is rejected instead of being spread into index-keyed garbage, and unknown template keys persist as before with only the known fields normalized by the parse.
…y dropped Truthiness guards at the trigger call sites swallowed falsey concurrency values before validation, so a JavaScript caller passing an empty string or null started the session without the intended limits. Only undefined counts as absent now; everything else flows into validation and throws.
…ng the action default Nullish coalescing treated a per-call null as unspecified, silently selecting the action default (or skipping validation entirely when no default exists). Per-call selection now treats only undefined as absent, matching the other chat trigger surfaces.
f27f13e to
d511299
Compare
|
Closing: this stack was flattened into a single change that has now been merged and will land in this repository via the automated sync. All review feedback from these PRs is incorporated, along with further review rounds on the flattened change. |
Summary
Stacked on #4853. Chat agents already accept the task-level
concurrencyoption, but the session trigger path had no way to scope runs per chat or tenant. Session trigger config now carriesconcurrencyKeyand up to two trigger-time named limits, so a chat agent declaringconcurrency: { perKey: 1 }can actually get one run per tenant by passing a key when the session starts:Design
The two fields ride the existing session trigger config, so every run the session schedules (initial, continuation, and upgrade re-triggers) carries them through one choke point on the server. All three session starters forward them:
chat.createStartSessionAction, the browserAgentChatclient, and handover. Named limits are validated client-side with the same rules and error messages astasks.trigger.The key is never defaulted from the chat ID: a session without an explicit
concurrencyKeyshares the task's keyless pool, so existing chat agents keep their current concurrency accounting.