feat(sdk,core,webapp): transcript storage for chat.agent - #4896
feat(sdk,core,webapp): transcript storage for chat.agent#4896ericallam wants to merge 5 commits into
Conversation
|
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:
WalkthroughAdds a Merge Risk: 🟡 Moderate · up to This change adds persisted chat transcripts, loading, paging, and recovery behavior. The remaining documentation issues could cause users to implement incompatible action handling or incomplete recovery flows, so they should be corrected before merge. 🚥 Pre-merge checks | ✅ 3 | ❌ 2❌ Failed checks (2 warnings)
✅ Passed checks (3 passed)
Full details: Description checkExplanation The description provides a detailed and relevant summary, but it does not follow the repository template. It omits the issue reference, checklist, Testing section, Changelog section, and Screenshots section. Full details: Docstring CoverageExplanation Docstring coverage is 47.06% which is insufficient. The required threshold is 80.00%. Docstring coverage is scoped to functions touched by this diff. Analyzed 17 functions across 17 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 |
🦋 Changeset detectedLatest commit: bca2b92 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 |
Observability mapAs of 19/100 over 457 measured of 475 entry points (base 19, no change) What this PR changed
FIX FIRST
AUDIT 3 of 50 sensitive mutations record an actor. 47 without one. What the score is made ofThe score and findings here are report-only and never gate the merge. Separately, a required test suite keeps this tool's symbol and route lists in sync with the code they name, and can fail a pull request that renames or removes a symbol they reference, or that adds the first route with a segment they anticipate. Each failure names the list to edit. The rules and their reasons: internal-packages/observability-map/README.md. |
2b2ea99 to
be72173
Compare
@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: |
be72173 to
5dc4365
Compare
5dc4365 to
3bdfd45
Compare
3bdfd45 to
db561bb
Compare
db561bb to
185360a
Compare
185360a to
461a6d2
Compare
461a6d2 to
1a3b477
Compare
1a3b477 to
d06408f
Compare
d06408f to
a4f1bfe
Compare
39a00da to
bf8496f
Compare
bf8496f to
84643b8
Compare
84643b8 to
7a6c3fd
Compare
7a6c3fd to
0a10002
Compare
…nformance suite chat.agent takes a storage option, with the platform snapshot as the default and the TranscriptStorage types, defaultStorage, snapshotTranscriptStorage, memoryTranscriptStorage and reduceTranscriptChanges exported from @trigger.dev/sdk/ai. chat.createLoadTranscriptAction(storage) reads a conversation on the server for any storage, and useLoadTranscript renders it in the browser and seeds the transport's resume cursor. runTranscriptStorageTests from @trigger.dev/sdk/ai/test is the contract a storage implementation has to meet. A new secret-key endpoint, GET /api/v1/sessions/:id/transcript, pages the platform snapshot server-side so rendering the last page of a long conversation does not download all of it; the default storage uses it for paged reads and falls back to the whole blob.
… message rows The real-schema conformance target for the storage contract: one row per message in chat_messages, with the runtime's state and cursors in two new nullable columns on chats. Paging is by position in SQL. The agent itself still persists through its hooks.
…, and the changeset
Treat a non-positive page limit as no limit instead of an empty page a caller cannot tell apart from the end of the transcript. Hold a seeded resume cursor until the session exists, so a transcript load that resolves before the session is created still opens the live stream past the persisted history instead of replaying it.
Consume a pending resume cursor in setSession() and stop seedResumeCursor from moving an existing session's cursor backward, so a transcript load that resolves around session creation, or after the live stream already advanced, does not replay persisted events. Add conformance coverage for a partial answer's non-final status, and drive the resume-cursor unit tests through a real transport. Docs: loadContext also fires on actions, a custom storage is not limited to row-per-message backends, and the bring-your-own example imports anthropic.
3ddfb85 to
bca2b92
Compare
| function isObjectNotFound(error: unknown): boolean { | ||
| if (!error) return false; | ||
| const name = (error as { name?: unknown }).name; | ||
| if (name === "NoSuchKey" || name === "NotFound") return true; | ||
| const status = (error as { $metadata?: { httpStatusCode?: number } }).$metadata?.httpStatusCode; | ||
| if (status === 404) return true; | ||
| const message = error instanceof Error ? error.message : String(error); | ||
| return /not found|nosuchkey|404|does not exist/i.test(message); |
Summary
The public surface for transcript storage:
chat.agent({ storage }), the exported types and factories, a read path that works for any storage, a conformance suite, and the docs.loadon the storage is the one read for every backend.chat.createLoadTranscriptActionwraps it for the app server anduseLoadTranscriptrenders the result and seeds the transport's resume cursor. A new secret-key endpoint,GET /api/v1/sessions/:id/transcript?limit=&before=, pages the platform snapshot server-side so rendering the last page of a long conversation does not download all of it; the default storage uses it for paged reads and falls back to the whole blob.runTranscriptStorageTestsfrom@trigger.dev/sdk/ai/testis the contract a storage has to meet: appends and in-place replacement, idempotentremoveandtruncateAfter,stateround-trips, cursors, replaying a changeset, paging, and chat isolation. It runs here againstmemoryTranscriptStorage(), the default snapshot storage, and a row-per-message adapter over the dashboard agent's own tables, which is the real-schema target and adds two nullable columns to its chats table.hydrateMessagesis documented as deprecated, withloadContexton a storage as the replacement. The changeset in this PR is the release note for the whole feature.