@trigger.dev/sdk 0.0.0-python-preview-20250226140121 → 0.0.0-rc-4-8-0-20261021151928
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +29 -9
- package/dist/commonjs/imports/ai-runtime-cjs.cjs.map +1 -0
- package/dist/commonjs/imports/ai-runtime.d.ts +1 -0
- package/dist/commonjs/imports/ai-runtime.js +31 -0
- package/dist/commonjs/imports/uncrypto.js +4 -4
- package/dist/commonjs/package.json +2 -1
- package/dist/commonjs/v3/agentSkillsRuntime.d.ts +28 -0
- package/dist/commonjs/v3/agentSkillsRuntime.js +173 -0
- package/dist/commonjs/v3/agentSkillsRuntime.js.map +1 -0
- package/dist/commonjs/v3/ai-shared.d.ts +156 -0
- package/dist/commonjs/v3/ai-shared.js +215 -0
- package/dist/commonjs/v3/ai-shared.js.map +1 -0
- package/dist/commonjs/v3/ai.d.ts +4225 -0
- package/dist/commonjs/v3/ai.js +11569 -0
- package/dist/commonjs/v3/ai.js.map +1 -0
- package/dist/commonjs/v3/aiAutoTelemetry.d.ts +2 -0
- package/dist/commonjs/v3/aiAutoTelemetry.js +81 -0
- package/dist/commonjs/v3/aiAutoTelemetry.js.map +1 -0
- package/dist/commonjs/v3/auth.d.ts +71 -10
- package/dist/commonjs/v3/auth.js +85 -19
- package/dist/commonjs/v3/auth.js.map +1 -1
- package/dist/commonjs/v3/batch.d.ts +3 -3
- package/dist/commonjs/v3/batch.js.map +1 -1
- package/dist/commonjs/v3/cache.js.map +1 -1
- package/dist/commonjs/v3/chat-client.d.ts +324 -0
- package/dist/commonjs/v3/chat-client.js +774 -0
- package/dist/commonjs/v3/chat-client.js.map +1 -0
- package/dist/commonjs/v3/chat-react.d.ts +244 -0
- package/dist/commonjs/v3/chat-react.js +463 -0
- package/dist/commonjs/v3/chat-react.js.map +1 -0
- package/dist/commonjs/v3/chat-server.d.ts +350 -0
- package/dist/commonjs/v3/chat-server.js +965 -0
- package/dist/commonjs/v3/chat-server.js.map +1 -0
- package/dist/commonjs/v3/chat-tab-coordinator.d.ts +65 -0
- package/dist/commonjs/v3/chat-tab-coordinator.js +235 -0
- package/dist/commonjs/v3/chat-tab-coordinator.js.map +1 -0
- package/dist/commonjs/v3/chat.d.ts +792 -0
- package/dist/commonjs/v3/chat.js +1662 -0
- package/dist/commonjs/v3/chat.js.map +1 -0
- package/dist/commonjs/v3/chatRouteWait.d.ts +21 -0
- package/dist/commonjs/v3/chatRouteWait.js +43 -0
- package/dist/commonjs/v3/chatRouteWait.js.map +1 -0
- package/dist/commonjs/v3/chatSnapshotIo.d.ts +2 -0
- package/dist/commonjs/v3/chatSnapshotIo.js +173 -0
- package/dist/commonjs/v3/chatSnapshotIo.js.map +1 -0
- package/dist/commonjs/v3/chatVersionSkew.d.ts +12 -0
- package/dist/commonjs/v3/chatVersionSkew.js +30 -0
- package/dist/commonjs/v3/chatVersionSkew.js.map +1 -0
- package/dist/commonjs/v3/compactionResponse.d.ts +9 -0
- package/dist/commonjs/v3/compactionResponse.js +37 -0
- package/dist/commonjs/v3/compactionResponse.js.map +1 -0
- package/dist/commonjs/v3/concurrency-shared.d.ts +13 -0
- package/dist/commonjs/v3/concurrency-shared.js +35 -0
- package/dist/commonjs/v3/concurrency-shared.js.map +1 -0
- package/dist/commonjs/v3/concurrencyLimits.d.ts +103 -0
- package/dist/commonjs/v3/concurrencyLimits.js +134 -0
- package/dist/commonjs/v3/concurrencyLimits.js.map +1 -0
- package/dist/commonjs/v3/config.js.map +1 -1
- package/dist/commonjs/v3/deployments.d.ts +25 -0
- package/dist/commonjs/v3/deployments.js +37 -0
- package/dist/commonjs/v3/deployments.js.map +1 -0
- package/dist/commonjs/v3/envvars.d.ts +5 -5
- package/dist/commonjs/v3/envvars.js.map +1 -1
- package/dist/commonjs/v3/externalDeploymentId.d.ts +23 -0
- package/dist/commonjs/v3/externalDeploymentId.js +43 -0
- package/dist/commonjs/v3/externalDeploymentId.js.map +1 -0
- package/dist/commonjs/v3/heartbeats.d.ts +37 -0
- package/dist/commonjs/v3/heartbeats.js +45 -0
- package/dist/commonjs/v3/heartbeats.js.map +1 -0
- package/dist/commonjs/v3/hooks.d.ts +26 -0
- package/dist/commonjs/v3/hooks.js +79 -0
- package/dist/commonjs/v3/hooks.js.map +1 -0
- package/dist/commonjs/v3/idempotencyKeys.d.ts +2 -1
- package/dist/commonjs/v3/idempotencyKeys.js +1 -0
- package/dist/commonjs/v3/idempotencyKeys.js.map +1 -1
- package/dist/commonjs/v3/index.d.ts +20 -5
- package/dist/commonjs/v3/index.js +56 -20
- package/dist/commonjs/v3/index.js.map +1 -1
- package/dist/commonjs/v3/locals.d.ts +3 -0
- package/dist/commonjs/v3/locals.js +6 -0
- package/dist/commonjs/v3/locals.js.map +1 -0
- package/dist/commonjs/v3/managedChatResponse.d.ts +44 -0
- package/dist/commonjs/v3/managedChatResponse.js +221 -0
- package/dist/commonjs/v3/managedChatResponse.js.map +1 -0
- package/dist/commonjs/v3/metadata.d.ts +5 -2
- package/dist/commonjs/v3/metadata.js +8 -1
- package/dist/commonjs/v3/metadata.js.map +1 -1
- package/dist/commonjs/v3/modelFileDownload.d.ts +10 -0
- package/dist/commonjs/v3/modelFileDownload.js +164 -0
- package/dist/commonjs/v3/modelFileDownload.js.map +1 -0
- package/dist/commonjs/v3/otel.d.ts +4 -0
- package/dist/commonjs/v3/otel.js +12 -0
- package/dist/commonjs/v3/otel.js.map +1 -0
- package/dist/commonjs/v3/prompt.d.ts +38 -0
- package/dist/commonjs/v3/prompt.js +146 -0
- package/dist/commonjs/v3/prompt.js.map +1 -0
- package/dist/commonjs/v3/promptManagement.d.ts +26 -0
- package/dist/commonjs/v3/promptManagement.js +180 -0
- package/dist/commonjs/v3/promptManagement.js.map +1 -0
- package/dist/commonjs/v3/prompts.d.ts +3 -0
- package/dist/commonjs/v3/prompts.js +15 -0
- package/dist/commonjs/v3/prompts.js.map +1 -0
- package/dist/commonjs/v3/query.d.ts +545 -0
- package/dist/commonjs/v3/query.js +163 -0
- package/dist/commonjs/v3/query.js.map +1 -0
- package/dist/commonjs/v3/queues.d.ts +107 -0
- package/dist/commonjs/v3/queues.js +225 -0
- package/dist/commonjs/v3/queues.js.map +1 -0
- package/dist/commonjs/v3/retry.d.ts +6 -2
- package/dist/commonjs/v3/retry.js +34 -23
- package/dist/commonjs/v3/retry.js.map +1 -1
- package/dist/commonjs/v3/runs.d.ts +182 -101
- package/dist/commonjs/v3/runs.js +99 -5
- package/dist/commonjs/v3/runs.js.map +1 -1
- package/dist/commonjs/v3/schedules/api.d.ts +8 -1
- package/dist/commonjs/v3/schedules/index.d.ts +29 -9
- package/dist/commonjs/v3/schedules/index.js +5 -1
- package/dist/commonjs/v3/schedules/index.js.map +1 -1
- package/dist/commonjs/v3/schemas.d.ts +1 -0
- package/dist/commonjs/{integrations.js → v3/schemas.js} +1 -1
- package/dist/commonjs/v3/schemas.js.map +1 -0
- package/dist/commonjs/v3/sessionTracing.d.ts +7 -0
- package/dist/commonjs/v3/sessionTracing.js +44 -0
- package/dist/commonjs/v3/sessionTracing.js.map +1 -0
- package/dist/commonjs/v3/sessions.d.ts +268 -0
- package/dist/commonjs/v3/sessions.js +776 -0
- package/dist/commonjs/v3/sessions.js.map +1 -0
- package/dist/commonjs/v3/shared.d.ts +129 -24
- package/dist/commonjs/v3/shared.js +1527 -689
- package/dist/commonjs/v3/shared.js.map +1 -1
- package/dist/commonjs/v3/skill.d.ts +99 -0
- package/dist/commonjs/v3/skill.js +165 -0
- package/dist/commonjs/v3/skill.js.map +1 -0
- package/dist/commonjs/v3/skills.d.ts +2 -0
- package/dist/commonjs/v3/skills.js +6 -0
- package/dist/commonjs/v3/skills.js.map +1 -0
- package/dist/commonjs/v3/steeringContext.d.ts +41 -0
- package/dist/commonjs/v3/steeringContext.js +118 -0
- package/dist/commonjs/v3/steeringContext.js.map +1 -0
- package/dist/commonjs/v3/streams.d.ts +298 -0
- package/dist/commonjs/v3/streams.js +584 -0
- package/dist/commonjs/v3/streams.js.map +1 -0
- package/dist/commonjs/v3/tasks.d.ts +19 -4
- package/dist/commonjs/v3/tasks.js +15 -1
- package/dist/commonjs/v3/tasks.js.map +1 -1
- package/dist/commonjs/v3/test/index.d.ts +5 -0
- package/dist/commonjs/v3/test/index.js +23 -0
- package/dist/commonjs/v3/test/index.js.map +1 -0
- package/dist/commonjs/v3/test/mock-channel-connector.d.ts +172 -0
- package/dist/commonjs/v3/test/mock-channel-connector.js +173 -0
- package/dist/commonjs/v3/test/mock-channel-connector.js.map +1 -0
- package/dist/commonjs/v3/test/mock-chat-agent.d.ts +388 -0
- package/dist/commonjs/v3/test/mock-chat-agent.js +689 -0
- package/dist/commonjs/v3/test/mock-chat-agent.js.map +1 -0
- package/dist/commonjs/v3/test/setup-catalog.d.ts +1 -0
- package/dist/commonjs/v3/test/setup-catalog.js +18 -0
- package/dist/commonjs/v3/test/setup-catalog.js.map +1 -0
- package/dist/commonjs/v3/test/test-session-handle.d.ts +24 -0
- package/dist/commonjs/v3/test/test-session-handle.js +271 -0
- package/dist/commonjs/v3/test/test-session-handle.js.map +1 -0
- package/dist/commonjs/v3/test/transcript-storage-tests.d.ts +40 -0
- package/dist/commonjs/v3/test/transcript-storage-tests.js +258 -0
- package/dist/commonjs/v3/test/transcript-storage-tests.js.map +1 -0
- package/dist/commonjs/v3/toolResultOrder.d.ts +15 -0
- package/dist/commonjs/v3/toolResultOrder.js +58 -0
- package/dist/commonjs/v3/toolResultOrder.js.map +1 -0
- package/dist/commonjs/v3/transcriptStorage.d.ts +307 -0
- package/dist/commonjs/v3/transcriptStorage.js +445 -0
- package/dist/commonjs/v3/transcriptStorage.js.map +1 -0
- package/dist/commonjs/v3/triggerClient.d.ts +45 -0
- package/dist/commonjs/v3/triggerClient.js +114 -0
- package/dist/commonjs/v3/triggerClient.js.map +1 -0
- package/dist/commonjs/v3/uiMessageChunks.d.ts +1 -0
- package/dist/commonjs/v3/uiMessageChunks.js +119 -0
- package/dist/commonjs/v3/uiMessageChunks.js.map +1 -0
- package/dist/commonjs/v3/usage.js +7 -6
- package/dist/commonjs/v3/usage.js.map +1 -1
- package/dist/commonjs/v3/wait.d.ts +218 -3
- package/dist/commonjs/v3/wait.js +433 -7
- package/dist/commonjs/v3/wait.js.map +1 -1
- package/dist/commonjs/v3/waitUntil.js.map +1 -1
- package/dist/commonjs/v3/webhookWaiters.d.ts +80 -0
- package/dist/commonjs/v3/webhookWaiters.js +156 -0
- package/dist/commonjs/v3/webhookWaiters.js.map +1 -0
- package/dist/commonjs/v3/webhooks.d.ts +192 -2
- package/dist/commonjs/v3/webhooks.js +340 -2
- package/dist/commonjs/v3/webhooks.js.map +1 -1
- package/dist/commonjs/version.js +1 -1
- package/dist/esm/imports/ai-runtime.d.ts +2 -0
- package/dist/esm/imports/ai-runtime.js +16 -0
- package/dist/esm/imports/ai-runtime.js.map +1 -0
- package/dist/esm/package.json +2 -1
- package/dist/esm/v3/agentSkillsRuntime.d.ts +28 -0
- package/dist/esm/v3/agentSkillsRuntime.js +136 -0
- package/dist/esm/v3/agentSkillsRuntime.js.map +1 -0
- package/dist/esm/v3/ai-shared.d.ts +156 -0
- package/dist/esm/v3/ai-shared.js +208 -0
- package/dist/esm/v3/ai-shared.js.map +1 -0
- package/dist/esm/v3/ai.d.ts +4225 -0
- package/dist/esm/v3/ai.js +11550 -0
- package/dist/esm/v3/ai.js.map +1 -0
- package/dist/esm/v3/aiAutoTelemetry.d.ts +2 -0
- package/dist/esm/v3/aiAutoTelemetry.js +78 -0
- package/dist/esm/v3/aiAutoTelemetry.js.map +1 -0
- package/dist/esm/v3/auth.d.ts +71 -10
- package/dist/esm/v3/auth.js +83 -17
- package/dist/esm/v3/auth.js.map +1 -1
- package/dist/esm/v3/batch.d.ts +3 -3
- package/dist/esm/v3/batch.js +2 -2
- package/dist/esm/v3/batch.js.map +1 -1
- package/dist/esm/v3/chat-client.d.ts +324 -0
- package/dist/esm/v3/chat-client.js +769 -0
- package/dist/esm/v3/chat-client.js.map +1 -0
- package/dist/esm/v3/chat-react.d.ts +244 -0
- package/dist/esm/v3/chat-react.js +455 -0
- package/dist/esm/v3/chat-react.js.map +1 -0
- package/dist/esm/v3/chat-server.d.ts +350 -0
- package/dist/esm/v3/chat-server.js +962 -0
- package/dist/esm/v3/chat-server.js.map +1 -0
- package/dist/esm/v3/chat-tab-coordinator.d.ts +65 -0
- package/dist/esm/v3/chat-tab-coordinator.js +231 -0
- package/dist/esm/v3/chat-tab-coordinator.js.map +1 -0
- package/dist/esm/v3/chat.d.ts +792 -0
- package/dist/esm/v3/chat.js +1655 -0
- package/dist/esm/v3/chat.js.map +1 -0
- package/dist/esm/v3/chatRouteWait.d.ts +21 -0
- package/dist/esm/v3/chatRouteWait.js +40 -0
- package/dist/esm/v3/chatRouteWait.js.map +1 -0
- package/dist/esm/v3/chatSnapshotIo.d.ts +2 -0
- package/dist/esm/v3/chatSnapshotIo.js +165 -0
- package/dist/esm/v3/chatSnapshotIo.js.map +1 -0
- package/dist/esm/v3/chatVersionSkew.d.ts +12 -0
- package/dist/esm/v3/chatVersionSkew.js +27 -0
- package/dist/esm/v3/chatVersionSkew.js.map +1 -0
- package/dist/esm/v3/compactionResponse.d.ts +9 -0
- package/dist/esm/v3/compactionResponse.js +34 -0
- package/dist/esm/v3/compactionResponse.js.map +1 -0
- package/dist/esm/v3/concurrency-shared.d.ts +13 -0
- package/dist/esm/v3/concurrency-shared.js +31 -0
- package/dist/esm/v3/concurrency-shared.js.map +1 -0
- package/dist/esm/v3/concurrencyLimits.d.ts +103 -0
- package/dist/esm/v3/concurrencyLimits.js +126 -0
- package/dist/esm/v3/concurrencyLimits.js.map +1 -0
- package/dist/esm/v3/deployments.d.ts +25 -0
- package/dist/esm/v3/deployments.js +34 -0
- package/dist/esm/v3/deployments.js.map +1 -0
- package/dist/esm/v3/envvars.d.ts +5 -5
- package/dist/esm/v3/envvars.js.map +1 -1
- package/dist/esm/v3/externalDeploymentId.d.ts +23 -0
- package/dist/esm/v3/externalDeploymentId.js +38 -0
- package/dist/esm/v3/externalDeploymentId.js.map +1 -0
- package/dist/esm/v3/heartbeats.d.ts +37 -0
- package/dist/esm/v3/heartbeats.js +42 -0
- package/dist/esm/v3/heartbeats.js.map +1 -0
- package/dist/esm/v3/hooks.d.ts +26 -0
- package/dist/esm/v3/hooks.js +66 -0
- package/dist/esm/v3/hooks.js.map +1 -0
- package/dist/esm/v3/idempotencyKeys.d.ts +2 -1
- package/dist/esm/v3/idempotencyKeys.js +2 -1
- package/dist/esm/v3/idempotencyKeys.js.map +1 -1
- package/dist/esm/v3/index.d.ts +20 -5
- package/dist/esm/v3/index.js +16 -2
- package/dist/esm/v3/index.js.map +1 -1
- package/dist/esm/v3/locals.d.ts +3 -0
- package/dist/esm/v3/locals.js +3 -0
- package/dist/esm/v3/locals.js.map +1 -0
- package/dist/esm/v3/managedChatResponse.d.ts +44 -0
- package/dist/esm/v3/managedChatResponse.js +216 -0
- package/dist/esm/v3/managedChatResponse.js.map +1 -0
- package/dist/esm/v3/metadata.d.ts +5 -2
- package/dist/esm/v3/metadata.js +8 -1
- package/dist/esm/v3/metadata.js.map +1 -1
- package/dist/esm/v3/modelFileDownload.d.ts +10 -0
- package/dist/esm/v3/modelFileDownload.js +161 -0
- package/dist/esm/v3/modelFileDownload.js.map +1 -0
- package/dist/esm/v3/otel.d.ts +4 -0
- package/dist/esm/v3/otel.js +9 -0
- package/dist/esm/v3/otel.js.map +1 -0
- package/dist/esm/v3/prompt.d.ts +38 -0
- package/dist/esm/v3/prompt.js +143 -0
- package/dist/esm/v3/prompt.js.map +1 -0
- package/dist/esm/v3/promptManagement.d.ts +26 -0
- package/dist/esm/v3/promptManagement.js +170 -0
- package/dist/esm/v3/promptManagement.js.map +1 -0
- package/dist/esm/v3/prompts.d.ts +3 -0
- package/dist/esm/v3/prompts.js +3 -0
- package/dist/esm/v3/prompts.js.map +1 -0
- package/dist/esm/v3/query.d.ts +545 -0
- package/dist/esm/v3/query.js +160 -0
- package/dist/esm/v3/query.js.map +1 -0
- package/dist/esm/v3/queues.d.ts +107 -0
- package/dist/esm/v3/queues.js +217 -0
- package/dist/esm/v3/queues.js.map +1 -0
- package/dist/esm/v3/retry.d.ts +6 -2
- package/dist/esm/v3/retry.js +27 -19
- package/dist/esm/v3/retry.js.map +1 -1
- package/dist/esm/v3/runs.d.ts +179 -98
- package/dist/esm/v3/runs.js +99 -5
- package/dist/esm/v3/runs.js.map +1 -1
- package/dist/esm/v3/schedules/api.d.ts +8 -1
- package/dist/esm/v3/schedules/index.d.ts +29 -9
- package/dist/esm/v3/schedules/index.js +6 -2
- package/dist/esm/v3/schedules/index.js.map +1 -1
- package/dist/esm/v3/schemas.d.ts +1 -0
- package/dist/esm/v3/schemas.js +2 -0
- package/dist/esm/v3/schemas.js.map +1 -0
- package/dist/esm/v3/sessionTracing.d.ts +7 -0
- package/dist/esm/v3/sessionTracing.js +40 -0
- package/dist/esm/v3/sessionTracing.js.map +1 -0
- package/dist/esm/v3/sessions.d.ts +268 -0
- package/dist/esm/v3/sessions.js +767 -0
- package/dist/esm/v3/sessions.js.map +1 -0
- package/dist/esm/v3/shared.d.ts +129 -24
- package/dist/esm/v3/shared.js +1521 -688
- package/dist/esm/v3/shared.js.map +1 -1
- package/dist/esm/v3/skill.d.ts +99 -0
- package/dist/esm/v3/skill.js +128 -0
- package/dist/esm/v3/skill.js.map +1 -0
- package/dist/esm/v3/skills.d.ts +2 -0
- package/dist/esm/v3/skills.js +2 -0
- package/dist/esm/v3/skills.js.map +1 -0
- package/dist/esm/v3/steeringContext.d.ts +41 -0
- package/dist/esm/v3/steeringContext.js +113 -0
- package/dist/esm/v3/steeringContext.js.map +1 -0
- package/dist/esm/v3/streams.d.ts +298 -0
- package/dist/esm/v3/streams.js +580 -0
- package/dist/esm/v3/streams.js.map +1 -0
- package/dist/esm/v3/tasks.d.ts +19 -4
- package/dist/esm/v3/tasks.js +16 -2
- package/dist/esm/v3/tasks.js.map +1 -1
- package/dist/esm/v3/test/index.d.ts +5 -0
- package/dist/esm/v3/test/index.js +15 -0
- package/dist/esm/v3/test/index.js.map +1 -0
- package/dist/esm/v3/test/mock-channel-connector.d.ts +172 -0
- package/dist/esm/v3/test/mock-channel-connector.js +170 -0
- package/dist/esm/v3/test/mock-channel-connector.js.map +1 -0
- package/dist/esm/v3/test/mock-chat-agent.d.ts +388 -0
- package/dist/esm/v3/test/mock-chat-agent.js +685 -0
- package/dist/esm/v3/test/mock-chat-agent.js.map +1 -0
- package/dist/esm/v3/test/setup-catalog.d.ts +1 -0
- package/dist/esm/v3/test/setup-catalog.js +16 -0
- package/dist/esm/v3/test/setup-catalog.js.map +1 -0
- package/dist/esm/v3/test/test-session-handle.d.ts +24 -0
- package/dist/esm/v3/test/test-session-handle.js +268 -0
- package/dist/esm/v3/test/test-session-handle.js.map +1 -0
- package/dist/esm/v3/test/transcript-storage-tests.d.ts +40 -0
- package/dist/esm/v3/test/transcript-storage-tests.js +255 -0
- package/dist/esm/v3/test/transcript-storage-tests.js.map +1 -0
- package/dist/esm/v3/toolResultOrder.d.ts +15 -0
- package/dist/esm/v3/toolResultOrder.js +55 -0
- package/dist/esm/v3/toolResultOrder.js.map +1 -0
- package/dist/esm/v3/transcriptStorage.d.ts +307 -0
- package/dist/esm/v3/transcriptStorage.js +431 -0
- package/dist/esm/v3/transcriptStorage.js.map +1 -0
- package/dist/esm/v3/triggerClient.d.ts +45 -0
- package/dist/esm/v3/triggerClient.js +77 -0
- package/dist/esm/v3/triggerClient.js.map +1 -0
- package/dist/esm/v3/uiMessageChunks.d.ts +1 -0
- package/dist/esm/v3/uiMessageChunks.js +116 -0
- package/dist/esm/v3/uiMessageChunks.js.map +1 -0
- package/dist/esm/v3/usage.js +7 -6
- package/dist/esm/v3/usage.js.map +1 -1
- package/dist/esm/v3/wait.d.ts +218 -3
- package/dist/esm/v3/wait.js +431 -7
- package/dist/esm/v3/wait.js.map +1 -1
- package/dist/esm/v3/webhookWaiters.d.ts +80 -0
- package/dist/esm/v3/webhookWaiters.js +149 -0
- package/dist/esm/v3/webhookWaiters.js.map +1 -0
- package/dist/esm/v3/webhooks.d.ts +192 -2
- package/dist/esm/v3/webhooks.js +336 -2
- package/dist/esm/v3/webhooks.js.map +1 -1
- package/dist/esm/version.js +1 -1
- package/docs/ai/observability.mdx +174 -0
- package/docs/ai/prompts.mdx +426 -0
- package/docs/ai-chat/actions.mdx +148 -0
- package/docs/ai-chat/anatomy.mdx +87 -0
- package/docs/ai-chat/backend.mdx +933 -0
- package/docs/ai-chat/background-injection.mdx +320 -0
- package/docs/ai-chat/changelog.mdx +958 -0
- package/docs/ai-chat/chat-local.mdx +170 -0
- package/docs/ai-chat/client-protocol.mdx +1091 -0
- package/docs/ai-chat/compaction.mdx +413 -0
- package/docs/ai-chat/custom-agents.mdx +545 -0
- package/docs/ai-chat/error-handling.mdx +379 -0
- package/docs/ai-chat/fast-starts.mdx +764 -0
- package/docs/ai-chat/frontend.mdx +634 -0
- package/docs/ai-chat/how-it-works.mdx +226 -0
- package/docs/ai-chat/lifecycle-hooks.mdx +532 -0
- package/docs/ai-chat/mcp.mdx +97 -0
- package/docs/ai-chat/migrating-from-a-route-handler.mdx +594 -0
- package/docs/ai-chat/migrating-from-hydrate-messages.mdx +299 -0
- package/docs/ai-chat/overview.mdx +86 -0
- package/docs/ai-chat/patterns/branching-conversations.mdx +145 -0
- package/docs/ai-chat/patterns/code-sandbox.mdx +122 -0
- package/docs/ai-chat/patterns/database-persistence.mdx +425 -0
- package/docs/ai-chat/patterns/human-in-the-loop.mdx +281 -0
- package/docs/ai-chat/patterns/large-payloads.mdx +165 -0
- package/docs/ai-chat/patterns/native-compaction.mdx +310 -0
- package/docs/ai-chat/patterns/oom-resilience.mdx +116 -0
- package/docs/ai-chat/patterns/persistence-and-replay.mdx +218 -0
- package/docs/ai-chat/patterns/recovery-boot.mdx +233 -0
- package/docs/ai-chat/patterns/redacting-telemetry.mdx +117 -0
- package/docs/ai-chat/patterns/skills.mdx +214 -0
- package/docs/ai-chat/patterns/sub-agents.mdx +412 -0
- package/docs/ai-chat/patterns/tool-result-auditing.mdx +145 -0
- package/docs/ai-chat/patterns/trusted-edge-signals.mdx +333 -0
- package/docs/ai-chat/patterns/version-upgrades.mdx +261 -0
- package/docs/ai-chat/pending-messages.mdx +363 -0
- package/docs/ai-chat/prompt-caching.mdx +204 -0
- package/docs/ai-chat/quick-start.mdx +163 -0
- package/docs/ai-chat/reference.mdx +1071 -0
- package/docs/ai-chat/server-chat.mdx +259 -0
- package/docs/ai-chat/sessions.mdx +334 -0
- package/docs/ai-chat/side-channels.mdx +172 -0
- package/docs/ai-chat/testing.mdx +691 -0
- package/docs/ai-chat/tools.mdx +192 -0
- package/docs/ai-chat/transcript-storage.mdx +247 -0
- package/docs/ai-chat/types.mdx +242 -0
- package/docs/ai-chat/upgrade-guide.mdx +511 -0
- package/docs/apikeys.mdx +170 -0
- package/docs/billing-limits.mdx +73 -0
- package/docs/building-with-ai.mdx +261 -0
- package/docs/bulk-actions.mdx +77 -0
- package/docs/changelog.mdx +6 -0
- package/docs/cli-deploy-commands.mdx +9 -0
- package/docs/cli-dev-commands.mdx +9 -0
- package/docs/cli-env-commands.mdx +115 -0
- package/docs/cli-init-commands.mdx +84 -0
- package/docs/cli-introduction.mdx +25 -0
- package/docs/cli-list-profiles-commands.mdx +42 -0
- package/docs/cli-login-commands.mdx +53 -0
- package/docs/cli-logout-commands.mdx +33 -0
- package/docs/cli-preview-archive.mdx +59 -0
- package/docs/cli-projects-commands.mdx +74 -0
- package/docs/cli-promote-commands.mdx +9 -0
- package/docs/cli-runs-commands.mdx +95 -0
- package/docs/cli-switch.mdx +43 -0
- package/docs/cli-tasks-commands.mdx +95 -0
- package/docs/cli-update-commands.mdx +48 -0
- package/docs/cli-whoami-commands.mdx +45 -0
- package/docs/community.mdx +6 -0
- package/docs/concurrency.mdx +416 -0
- package/docs/config/config-file.mdx +662 -0
- package/docs/config/extensions/additionalFiles.mdx +38 -0
- package/docs/config/extensions/additionalPackages.mdx +40 -0
- package/docs/config/extensions/aptGet.mdx +34 -0
- package/docs/config/extensions/audioWaveform.mdx +23 -0
- package/docs/config/extensions/custom.mdx +393 -0
- package/docs/config/extensions/emitDecoratorMetadata.mdx +52 -0
- package/docs/config/extensions/esbuildPlugin.mdx +31 -0
- package/docs/config/extensions/ffmpeg.mdx +45 -0
- package/docs/config/extensions/lightpanda.mdx +56 -0
- package/docs/config/extensions/overview.mdx +69 -0
- package/docs/config/extensions/playwright.mdx +195 -0
- package/docs/config/extensions/prismaExtension.mdx +1013 -0
- package/docs/config/extensions/puppeteer.mdx +28 -0
- package/docs/config/extensions/pythonExtension.mdx +190 -0
- package/docs/config/extensions/syncEnvVars.mdx +330 -0
- package/docs/context.mdx +235 -0
- package/docs/database-connections.mdx +213 -0
- package/docs/deploy-environment-variables.mdx +466 -0
- package/docs/deployment/atomic-deployment.mdx +470 -0
- package/docs/deployment/dev-branches.mdx +92 -0
- package/docs/deployment/overview.mdx +260 -0
- package/docs/deployment/preview-branches.mdx +227 -0
- package/docs/errors-retrying.mdx +383 -0
- package/docs/github-actions.mdx +260 -0
- package/docs/github-integration.mdx +148 -0
- package/docs/github-repo.mdx +8 -0
- package/docs/help-email.mdx +6 -0
- package/docs/help-slack.mdx +12 -0
- package/docs/hidden-tasks.mdx +56 -0
- package/docs/how-it-works.mdx +454 -0
- package/docs/how-to-reduce-your-spend.mdx +211 -0
- package/docs/idempotency.mdx +542 -0
- package/docs/introduction.mdx +135 -0
- package/docs/limits.mdx +284 -0
- package/docs/logging.mdx +195 -0
- package/docs/machines.mdx +952 -0
- package/docs/manual-setup.mdx +632 -0
- package/docs/mcp-agent-rules.mdx +41 -0
- package/docs/mcp-introduction.mdx +386 -0
- package/docs/mcp-tools.mdx +425 -0
- package/docs/migrating-from-v3.mdx +332 -0
- package/docs/observability/dashboards.mdx +166 -0
- package/docs/observability/query.mdx +614 -0
- package/docs/open-source-contributing.mdx +16 -0
- package/docs/private-networking/aws-console-setup.mdx +304 -0
- package/docs/private-networking/overview.mdx +144 -0
- package/docs/private-networking/troubleshooting.mdx +78 -0
- package/docs/queues.mdx +271 -0
- package/docs/quick-start.mdx +60 -0
- package/docs/realtime/auth.mdx +228 -0
- package/docs/realtime/backend/input-streams.mdx +159 -0
- package/docs/realtime/backend/overview.mdx +45 -0
- package/docs/realtime/backend/streams.mdx +433 -0
- package/docs/realtime/backend/subscribe.mdx +225 -0
- package/docs/realtime/how-it-works.mdx +94 -0
- package/docs/realtime/overview.mdx +63 -0
- package/docs/realtime/react-hooks/overview.mdx +73 -0
- package/docs/realtime/react-hooks/session-stream.mdx +126 -0
- package/docs/realtime/react-hooks/streams.mdx +517 -0
- package/docs/realtime/react-hooks/subscribe.mdx +690 -0
- package/docs/realtime/react-hooks/swr.mdx +87 -0
- package/docs/realtime/react-hooks/triggering.mdx +194 -0
- package/docs/realtime/react-hooks/use-wait-token.mdx +34 -0
- package/docs/realtime/run-object.mdx +197 -0
- package/docs/replaying.mdx +97 -0
- package/docs/reports.mdx +159 -0
- package/docs/request-feature.mdx +6 -0
- package/docs/roadmap.mdx +6 -0
- package/docs/run-tests.mdx +21 -0
- package/docs/run-usage.mdx +113 -0
- package/docs/runs/bulk-actions.mdx +183 -0
- package/docs/runs/heartbeats.mdx +38 -0
- package/docs/runs/list-best-practices.mdx +234 -0
- package/docs/runs/max-duration.mdx +143 -0
- package/docs/runs/metadata.mdx +731 -0
- package/docs/runs/priority.mdx +8 -0
- package/docs/runs.mdx +406 -0
- package/docs/self-hosting/docker.mdx +512 -0
- package/docs/self-hosting/env/supervisor.mdx +78 -0
- package/docs/self-hosting/env/webapp.mdx +305 -0
- package/docs/self-hosting/kubernetes.mdx +725 -0
- package/docs/self-hosting/overview.mdx +145 -0
- package/docs/self-hosting/security.mdx +67 -0
- package/docs/skills.mdx +85 -0
- package/docs/tags.mdx +126 -0
- package/docs/tasks/overview.mdx +695 -0
- package/docs/tasks/scheduled.mdx +479 -0
- package/docs/tasks/schemaTask.mdx +413 -0
- package/docs/tasks/streams.mdx +887 -0
- package/docs/triggering.mdx +1340 -0
- package/docs/troubleshooting-alerts.mdx +607 -0
- package/docs/troubleshooting-debugging-in-vscode.mdx +9 -0
- package/docs/troubleshooting-github-issues.mdx +6 -0
- package/docs/troubleshooting-uptime-status.mdx +7 -0
- package/docs/troubleshooting-zod.mdx +158 -0
- package/docs/troubleshooting.mdx +414 -0
- package/docs/upgrading-packages.mdx +80 -0
- package/docs/vercel-integration.mdx +250 -0
- package/docs/versioning.mdx +58 -0
- package/docs/video-walkthrough.mdx +23 -0
- package/docs/wait-for-token.mdx +540 -0
- package/docs/wait-for.mdx +42 -0
- package/docs/wait-until.mdx +53 -0
- package/docs/wait.mdx +18 -0
- package/docs/webhooks/channels.mdx +154 -0
- package/docs/webhooks/connect.mdx +91 -0
- package/docs/webhooks/deliveries.mdx +99 -0
- package/docs/webhooks/filters.mdx +146 -0
- package/docs/webhooks/human-in-the-loop.mdx +158 -0
- package/docs/webhooks/linear.mdx +186 -0
- package/docs/webhooks/overview.mdx +115 -0
- package/docs/webhooks/session-routing.mdx +141 -0
- package/docs/webhooks/slack.mdx +393 -0
- package/docs/webhooks/sources.mdx +250 -0
- package/docs/webhooks/waiters.mdx +190 -0
- package/docs/writing-tasks-introduction.mdx +34 -0
- package/package.json +143 -42
- package/skills/trigger-authoring-chat-agent/SKILL.md +308 -0
- package/skills/trigger-authoring-tasks/SKILL.md +254 -0
- package/skills/trigger-chat-agent-advanced/SKILL.md +403 -0
- package/skills/trigger-cost-savings/SKILL.md +116 -0
- package/skills/trigger-realtime-and-frontend/SKILL.md +276 -0
- package/dist/commonjs/apiClient.d.ts +0 -727
- package/dist/commonjs/apiClient.js +0 -692
- package/dist/commonjs/apiClient.js.map +0 -1
- package/dist/commonjs/concurrencyLimit.d.ts +0 -10
- package/dist/commonjs/concurrencyLimit.js +0 -17
- package/dist/commonjs/concurrencyLimit.js.map +0 -1
- package/dist/commonjs/errors.d.ts +0 -66
- package/dist/commonjs/errors.js +0 -109
- package/dist/commonjs/errors.js.map +0 -1
- package/dist/commonjs/httpEndpoint.d.ts +0 -87
- package/dist/commonjs/httpEndpoint.js +0 -130
- package/dist/commonjs/httpEndpoint.js.map +0 -1
- package/dist/commonjs/index.d.ts +0 -23
- package/dist/commonjs/index.js +0 -55
- package/dist/commonjs/index.js.map +0 -1
- package/dist/commonjs/integrations.d.ts +0 -11
- package/dist/commonjs/integrations.js.map +0 -1
- package/dist/commonjs/io.d.ts +0 -441
- package/dist/commonjs/io.js +0 -1165
- package/dist/commonjs/io.js.map +0 -1
- package/dist/commonjs/ioWithIntegrations.d.ts +0 -4
- package/dist/commonjs/ioWithIntegrations.js +0 -32
- package/dist/commonjs/ioWithIntegrations.js.map +0 -1
- package/dist/commonjs/job.d.ts +0 -96
- package/dist/commonjs/job.js +0 -210
- package/dist/commonjs/job.js.map +0 -1
- package/dist/commonjs/retry.d.ts +0 -20
- package/dist/commonjs/retry.js +0 -22
- package/dist/commonjs/retry.js.map +0 -1
- package/dist/commonjs/runLocalStorage.d.ts +0 -8
- package/dist/commonjs/runLocalStorage.js +0 -6
- package/dist/commonjs/runLocalStorage.js.map +0 -1
- package/dist/commonjs/security.d.ts +0 -18
- package/dist/commonjs/security.js +0 -41
- package/dist/commonjs/security.js.map +0 -1
- package/dist/commonjs/status.d.ts +0 -19
- package/dist/commonjs/status.js +0 -38
- package/dist/commonjs/status.js.map +0 -1
- package/dist/commonjs/store/keyValueStore.d.ts +0 -17
- package/dist/commonjs/store/keyValueStore.js +0 -138
- package/dist/commonjs/store/keyValueStore.js.map +0 -1
- package/dist/commonjs/store/keyValueStoreClient.d.ts +0 -19
- package/dist/commonjs/store/keyValueStoreClient.js +0 -65
- package/dist/commonjs/store/keyValueStoreClient.js.map +0 -1
- package/dist/commonjs/triggerClient.d.ts +0 -290
- package/dist/commonjs/triggerClient.js +0 -1366
- package/dist/commonjs/triggerClient.js.map +0 -1
- package/dist/commonjs/triggers/dynamic.d.ts +0 -56
- package/dist/commonjs/triggers/dynamic.js +0 -97
- package/dist/commonjs/triggers/dynamic.js.map +0 -1
- package/dist/commonjs/triggers/eventTrigger.d.ts +0 -58
- package/dist/commonjs/triggers/eventTrigger.js +0 -69
- package/dist/commonjs/triggers/eventTrigger.js.map +0 -1
- package/dist/commonjs/triggers/externalSource.d.ts +0 -148
- package/dist/commonjs/triggers/externalSource.js +0 -106
- package/dist/commonjs/triggers/externalSource.js.map +0 -1
- package/dist/commonjs/triggers/invokeTrigger.d.ts +0 -39
- package/dist/commonjs/triggers/invokeTrigger.js +0 -58
- package/dist/commonjs/triggers/invokeTrigger.js.map +0 -1
- package/dist/commonjs/triggers/notifications.d.ts +0 -111
- package/dist/commonjs/triggers/notifications.js +0 -101
- package/dist/commonjs/triggers/notifications.js.map +0 -1
- package/dist/commonjs/triggers/scheduled.d.ts +0 -145
- package/dist/commonjs/triggers/scheduled.js +0 -208
- package/dist/commonjs/triggers/scheduled.js.map +0 -1
- package/dist/commonjs/triggers/webhook.d.ts +0 -143
- package/dist/commonjs/triggers/webhook.js +0 -133
- package/dist/commonjs/triggers/webhook.js.map +0 -1
- package/dist/commonjs/typed-emitter.d.ts +0 -37
- package/dist/commonjs/typed-emitter.js +0 -3
- package/dist/commonjs/typed-emitter.js.map +0 -1
- package/dist/commonjs/types.d.ts +0 -204
- package/dist/commonjs/types.js +0 -23
- package/dist/commonjs/types.js.map +0 -1
- package/dist/commonjs/utils/formatSchemaErrors.d.ts +0 -3
- package/dist/commonjs/utils/formatSchemaErrors.js +0 -10
- package/dist/commonjs/utils/formatSchemaErrors.js.map +0 -1
- package/dist/commonjs/utils/typedAsyncLocalStorage.d.ts +0 -6
- package/dist/commonjs/utils/typedAsyncLocalStorage.js +0 -18
- package/dist/commonjs/utils/typedAsyncLocalStorage.js.map +0 -1
- package/dist/commonjs/utils.d.ts +0 -1
- package/dist/commonjs/utils.js +0 -11
- package/dist/commonjs/utils.js.map +0 -1
- package/dist/esm/apiClient.d.ts +0 -727
- package/dist/esm/apiClient.js +0 -687
- package/dist/esm/apiClient.js.map +0 -1
- package/dist/esm/concurrencyLimit.d.ts +0 -10
- package/dist/esm/concurrencyLimit.js +0 -13
- package/dist/esm/concurrencyLimit.js.map +0 -1
- package/dist/esm/errors.d.ts +0 -66
- package/dist/esm/errors.js +0 -95
- package/dist/esm/errors.js.map +0 -1
- package/dist/esm/httpEndpoint.d.ts +0 -87
- package/dist/esm/httpEndpoint.js +0 -125
- package/dist/esm/httpEndpoint.js.map +0 -1
- package/dist/esm/index.d.ts +0 -23
- package/dist/esm/index.js +0 -35
- package/dist/esm/index.js.map +0 -1
- package/dist/esm/integrations.d.ts +0 -11
- package/dist/esm/integrations.js +0 -2
- package/dist/esm/integrations.js.map +0 -1
- package/dist/esm/io.d.ts +0 -441
- package/dist/esm/io.js +0 -1159
- package/dist/esm/io.js.map +0 -1
- package/dist/esm/ioWithIntegrations.d.ts +0 -4
- package/dist/esm/ioWithIntegrations.js +0 -29
- package/dist/esm/ioWithIntegrations.js.map +0 -1
- package/dist/esm/job.d.ts +0 -96
- package/dist/esm/job.js +0 -206
- package/dist/esm/job.js.map +0 -1
- package/dist/esm/retry.d.ts +0 -20
- package/dist/esm/retry.js +0 -19
- package/dist/esm/retry.js.map +0 -1
- package/dist/esm/runLocalStorage.d.ts +0 -8
- package/dist/esm/runLocalStorage.js +0 -3
- package/dist/esm/runLocalStorage.js.map +0 -1
- package/dist/esm/security.d.ts +0 -18
- package/dist/esm/security.js +0 -34
- package/dist/esm/security.js.map +0 -1
- package/dist/esm/status.d.ts +0 -19
- package/dist/esm/status.js +0 -34
- package/dist/esm/status.js.map +0 -1
- package/dist/esm/store/keyValueStore.d.ts +0 -17
- package/dist/esm/store/keyValueStore.js +0 -134
- package/dist/esm/store/keyValueStore.js.map +0 -1
- package/dist/esm/store/keyValueStoreClient.d.ts +0 -19
- package/dist/esm/store/keyValueStoreClient.js +0 -61
- package/dist/esm/store/keyValueStoreClient.js.map +0 -1
- package/dist/esm/triggerClient.d.ts +0 -288
- package/dist/esm/triggerClient.js +0 -1359
- package/dist/esm/triggerClient.js.map +0 -1
- package/dist/esm/triggers/dynamic.d.ts +0 -56
- package/dist/esm/triggers/dynamic.js +0 -93
- package/dist/esm/triggers/dynamic.js.map +0 -1
- package/dist/esm/triggers/eventTrigger.d.ts +0 -58
- package/dist/esm/triggers/eventTrigger.js +0 -64
- package/dist/esm/triggers/eventTrigger.js.map +0 -1
- package/dist/esm/triggers/externalSource.d.ts +0 -148
- package/dist/esm/triggers/externalSource.js +0 -100
- package/dist/esm/triggers/externalSource.js.map +0 -1
- package/dist/esm/triggers/invokeTrigger.d.ts +0 -39
- package/dist/esm/triggers/invokeTrigger.js +0 -53
- package/dist/esm/triggers/invokeTrigger.js.map +0 -1
- package/dist/esm/triggers/notifications.d.ts +0 -111
- package/dist/esm/triggers/notifications.js +0 -94
- package/dist/esm/triggers/notifications.js.map +0 -1
- package/dist/esm/triggers/scheduled.d.ts +0 -145
- package/dist/esm/triggers/scheduled.js +0 -197
- package/dist/esm/triggers/scheduled.js.map +0 -1
- package/dist/esm/triggers/webhook.d.ts +0 -143
- package/dist/esm/triggers/webhook.js +0 -128
- package/dist/esm/triggers/webhook.js.map +0 -1
- package/dist/esm/typed-emitter.d.ts +0 -37
- package/dist/esm/typed-emitter.js +0 -2
- package/dist/esm/typed-emitter.js.map +0 -1
- package/dist/esm/types.d.ts +0 -204
- package/dist/esm/types.js +0 -19
- package/dist/esm/types.js.map +0 -1
- package/dist/esm/utils/formatSchemaErrors.d.ts +0 -3
- package/dist/esm/utils/formatSchemaErrors.js +0 -7
- package/dist/esm/utils/formatSchemaErrors.js.map +0 -1
- package/dist/esm/utils/typedAsyncLocalStorage.d.ts +0 -6
- package/dist/esm/utils/typedAsyncLocalStorage.js +0 -14
- package/dist/esm/utils/typedAsyncLocalStorage.js.map +0 -1
- package/dist/esm/utils.d.ts +0 -1
- package/dist/esm/utils.js +0 -8
- package/dist/esm/utils.js.map +0 -1
|
@@ -0,0 +1,299 @@
|
|
|
1
|
+
---
|
|
2
|
+
title: "Migrate from hydrateMessages to transcript storage"
|
|
3
|
+
sidebarTitle: "Migrating from hydrateMessages"
|
|
4
|
+
description: "Move a chat.agent that persists its own history through hydrateMessages onto a TranscriptStorage: map your tables, implement load and save, decide whether you need loadContext, and delete the recovery and compaction code you no longer own."
|
|
5
|
+
---
|
|
6
|
+
|
|
7
|
+
Learn how to replace a `hydrateMessages` hook with a `storage` on the same tables, so the runtime writes the conversation for you and your app stops re-deriving what the runtime already knows.
|
|
8
|
+
|
|
9
|
+
`hydrateMessages` keeps working with a one-time deprecation warning, so you can migrate one agent at a time. Setting both `hydrateMessages` and `storage` on one agent is a startup error, which makes the switch a swap rather than an overlap.
|
|
10
|
+
|
|
11
|
+
## What changes hands
|
|
12
|
+
|
|
13
|
+
With `hydrateMessages`, your hook was the source of truth and the runtime wrote nothing, so your app re-derived from its own rows everything the runtime already knew. A [transcript storage](/ai-chat/transcript-storage) inverts that: the runtime owns the transcript and calls your storage at the durable boundaries.
|
|
14
|
+
|
|
15
|
+
| Concern | With `hydrateMessages` | With `storage` |
|
|
16
|
+
| --- | --- | --- |
|
|
17
|
+
| Reading history | Your hook, on every turn and action | `load`, once when a run boots |
|
|
18
|
+
| Writing the user's message and the answer | Your `onTurnStart` / `onTurnComplete` code | `save` receives them as `put` changes |
|
|
19
|
+
| A message sent mid-answer (steering) | You wrote it, and placed it before the answer | Arrives in the same changeset, in order |
|
|
20
|
+
| Undo, edit, regenerate | Row writes paired with each `chat.history` call | Arrive as `truncateAfter` and `put` changes |
|
|
21
|
+
| Partial answer after a crash | Your partial rows and a recovery flag | A `put` with `final: false`; you report it back in `nonFinalIds` |
|
|
22
|
+
| Tool call the dead run never answered | Your repair pass | Cleaned up by the runtime before the save |
|
|
23
|
+
| Compaction summary | Your summary column and watermark, invalidated on every rollback path | An opaque `state` blob you store and return; the runtime discards it when a rollback crosses it |
|
|
24
|
+
| Resume cursors | Your `lastEventId` write, in the same transaction as the answer | `cursors` on the changeset; write them in the same transaction |
|
|
25
|
+
| Deciding what the model sees | The array your hook returned | The transcript, or `loadContext` if your database decides |
|
|
26
|
+
|
|
27
|
+
## Before you start
|
|
28
|
+
|
|
29
|
+
- Your message table needs three things per row: the message id, the `UIMessage` itself, and a column to order by. If you stored messages as `ModelMessage`s, convert your existing rows first; a storage holds `UIMessage`s only.
|
|
30
|
+
- Add somewhere to keep an opaque JSON blob per chat (the runtime's `state`) and two opaque string cursors per chat.
|
|
31
|
+
- If you have a `final`, `status` or `partial` flag already, keep it. If not, add one; it is how a cut-short answer stays marked across a continuation.
|
|
32
|
+
|
|
33
|
+
<Steps>
|
|
34
|
+
<Step title="Implement load">
|
|
35
|
+
`load` returns the conversation in order, the `state` blob, the cursors, and the ids of any rows you stored as partial. Scope the read by `clientData` where your backend enforces tenancy.
|
|
36
|
+
|
|
37
|
+
```ts lib/transcript-storage.ts
|
|
38
|
+
import type { TranscriptStorage } from "@trigger.dev/sdk/ai";
|
|
39
|
+
import { db } from "@/lib/db";
|
|
40
|
+
|
|
41
|
+
type Scope = { userId: string };
|
|
42
|
+
|
|
43
|
+
export const transcriptStorage: TranscriptStorage<Scope> = {
|
|
44
|
+
async load({ chatId, clientData }, opts) {
|
|
45
|
+
const chat = await db.chat.findUnique({
|
|
46
|
+
where: { id: chatId },
|
|
47
|
+
include: { session: true },
|
|
48
|
+
});
|
|
49
|
+
if (chat && chat.userId !== clientData.userId) {
|
|
50
|
+
throw new Error("This conversation could not be loaded.");
|
|
51
|
+
}
|
|
52
|
+
if (!chat) return { messages: [], state: null };
|
|
53
|
+
|
|
54
|
+
const cursors = {
|
|
55
|
+
lastOutEventId: chat.session?.lastEventId ?? undefined,
|
|
56
|
+
lastInEventId: chat.session?.lastInEventId ?? undefined,
|
|
57
|
+
};
|
|
58
|
+
|
|
59
|
+
let before: number | undefined;
|
|
60
|
+
if (opts?.before) {
|
|
61
|
+
const anchor = await db.message.findUnique({
|
|
62
|
+
where: { chatId_id: { chatId, id: opts.before } },
|
|
63
|
+
});
|
|
64
|
+
if (!anchor) return { messages: [], state: chat.transcriptState, cursors };
|
|
65
|
+
before = anchor.position;
|
|
66
|
+
}
|
|
67
|
+
const where = { chatId, ...(before !== undefined ? { position: { lt: before } } : {}) };
|
|
68
|
+
|
|
69
|
+
let rows;
|
|
70
|
+
let nextCursor: string | undefined;
|
|
71
|
+
if (opts?.limit) {
|
|
72
|
+
const page = await db.message.findMany({
|
|
73
|
+
where,
|
|
74
|
+
orderBy: { position: "desc" },
|
|
75
|
+
take: opts.limit + 1,
|
|
76
|
+
});
|
|
77
|
+
rows = page.slice(0, opts.limit).reverse();
|
|
78
|
+
if (page.length > opts.limit) nextCursor = rows[0]?.id;
|
|
79
|
+
} else {
|
|
80
|
+
rows = await db.message.findMany({ where, orderBy: { position: "asc" } });
|
|
81
|
+
}
|
|
82
|
+
|
|
83
|
+
return {
|
|
84
|
+
messages: rows.map((row) => row.message),
|
|
85
|
+
state: chat.transcriptState,
|
|
86
|
+
cursors,
|
|
87
|
+
nextCursor,
|
|
88
|
+
nonFinalIds: rows.filter((row) => row.status === "partial").map((row) => row.id),
|
|
89
|
+
};
|
|
90
|
+
},
|
|
91
|
+
|
|
92
|
+
async save(ctx, changeset) {
|
|
93
|
+
// next step
|
|
94
|
+
},
|
|
95
|
+
};
|
|
96
|
+
```
|
|
97
|
+
|
|
98
|
+
The runtime calls `load` with no options and wants the whole conversation. Your frontend's [history read](/ai-chat/transcript-storage#reading-the-transcript) passes `limit` (and later `before`), so the example fetches one extra row to tell whether earlier messages exist and returns the oldest included id as `nextCursor`.
|
|
99
|
+
</Step>
|
|
100
|
+
|
|
101
|
+
<Step title="Implement save">
|
|
102
|
+
Apply the changeset's `changes` to your rows and write the `cursors`, in one transaction. The cursor tells a reconnecting client what it has already seen; a cursor that lands ahead of the rows it accounts for makes that client skip chunks stored nowhere.
|
|
103
|
+
|
|
104
|
+
```ts lib/transcript-storage.ts
|
|
105
|
+
async save({ chatId, clientData }, changeset) {
|
|
106
|
+
await db.$transaction(async (tx) => {
|
|
107
|
+
const chat = await tx.chat.findUnique({ where: { id: chatId } });
|
|
108
|
+
if (chat && chat.userId !== clientData.userId) {
|
|
109
|
+
throw new Error("This conversation could not be saved.");
|
|
110
|
+
}
|
|
111
|
+
if (!chat) await tx.chat.create({ data: { id: chatId, userId: clientData.userId } });
|
|
112
|
+
|
|
113
|
+
let next = (await lastPosition(tx, chatId)) + 1;
|
|
114
|
+
|
|
115
|
+
for (const change of changeset.changes) {
|
|
116
|
+
switch (change.op) {
|
|
117
|
+
case "put": {
|
|
118
|
+
const status = change.final === false ? "partial" : "complete";
|
|
119
|
+
const existing = await tx.message.findUnique({
|
|
120
|
+
where: { chatId_id: { chatId, id: change.message.id } },
|
|
121
|
+
});
|
|
122
|
+
if (existing) {
|
|
123
|
+
await tx.message.update({
|
|
124
|
+
where: { chatId_id: { chatId, id: change.message.id } },
|
|
125
|
+
data: { message: change.message, status },
|
|
126
|
+
});
|
|
127
|
+
} else {
|
|
128
|
+
await tx.message.create({
|
|
129
|
+
data: { chatId, id: change.message.id, position: next++, message: change.message, status },
|
|
130
|
+
});
|
|
131
|
+
}
|
|
132
|
+
break;
|
|
133
|
+
}
|
|
134
|
+
case "remove":
|
|
135
|
+
await tx.message.deleteMany({ where: { chatId, id: change.id } });
|
|
136
|
+
break;
|
|
137
|
+
case "truncateAfter": {
|
|
138
|
+
const anchor = await tx.message.findUnique({
|
|
139
|
+
where: { chatId_id: { chatId, id: change.afterId } },
|
|
140
|
+
});
|
|
141
|
+
if (anchor) {
|
|
142
|
+
await tx.message.deleteMany({ where: { chatId, position: { gt: anchor.position } } });
|
|
143
|
+
next = anchor.position + 1;
|
|
144
|
+
}
|
|
145
|
+
break;
|
|
146
|
+
}
|
|
147
|
+
case "state":
|
|
148
|
+
await tx.chat.update({ where: { id: chatId }, data: { transcriptState: change.value } });
|
|
149
|
+
break;
|
|
150
|
+
}
|
|
151
|
+
}
|
|
152
|
+
|
|
153
|
+
if (changeset.cursors) {
|
|
154
|
+
await tx.chatSession.upsert({
|
|
155
|
+
where: { chatId },
|
|
156
|
+
create: { chatId, ...cursorColumns(changeset.cursors) },
|
|
157
|
+
update: cursorColumns(changeset.cursors),
|
|
158
|
+
});
|
|
159
|
+
}
|
|
160
|
+
});
|
|
161
|
+
}
|
|
162
|
+
```
|
|
163
|
+
|
|
164
|
+
Three rules keep the rows in the runtime's order:
|
|
165
|
+
|
|
166
|
+
- Assign a position only when a row is first inserted, in the order the `put`s arrive. Within one changeset that is conversation order, so a steer sent mid-answer lands before the answer it shaped.
|
|
167
|
+
- Leave the position alone on a `put` for a known id. A tool approval, a settled partial and a compaction all replace a message in place.
|
|
168
|
+
- Do not order by a write timestamp. A replaced message would jump to the end, and a steer written after the answer would sort after it.
|
|
169
|
+
|
|
170
|
+
If you keep the whole conversation as one document instead of rows, ignore `changes` and write `changeset.transcript` as-is. Pick one of the two and stay with it.
|
|
171
|
+
</Step>
|
|
172
|
+
|
|
173
|
+
<Step title="Decide whether you need loadContext">
|
|
174
|
+
Most `hydrateMessages` hooks did two jobs: they persisted the incoming message and they returned the history. `save` and `load` cover both, so most agents need nothing more.
|
|
175
|
+
|
|
176
|
+
Add `loadContext` only when your database decides what the model sees each turn: a branching conversation where only the active branch is context, or a trust boundary where the browser's history is not to be believed. The runtime calls it on every turn and action with the incoming messages and the transcript it had, and uses what you return as the conversation. `save` keeps receiving every change and crash recovery keeps running.
|
|
177
|
+
|
|
178
|
+
```ts lib/transcript-storage.ts
|
|
179
|
+
loadContext: async ({ chatId, clientData }, { incomingMessages }) => {
|
|
180
|
+
const branch = await db.activeBranch(chatId, clientData.userId);
|
|
181
|
+
return [...branch, ...incomingMessages];
|
|
182
|
+
},
|
|
183
|
+
```
|
|
184
|
+
|
|
185
|
+
Do not port the body of your `hydrateMessages` hook into `loadContext` wholesale. The writes in it belong in `save`, and the recovery and compaction logic in it is gone.
|
|
186
|
+
</Step>
|
|
187
|
+
|
|
188
|
+
<Step title="Swap the option">
|
|
189
|
+
Set `storage`, remove `hydrateMessages`, and let the agent boot. It throws on start if both are still present.
|
|
190
|
+
|
|
191
|
+
```ts trigger/chat.ts
|
|
192
|
+
export const myChat = chat.agent({
|
|
193
|
+
id: "my-chat",
|
|
194
|
+
storage: transcriptStorage,
|
|
195
|
+
clientDataSchema: z.object({ userId: z.string() }),
|
|
196
|
+
run: async ({ messages, signal, streamText }) =>
|
|
197
|
+
streamText({ model: anthropic("claude-sonnet-4-5"), messages, abortSignal: signal }),
|
|
198
|
+
});
|
|
199
|
+
```
|
|
200
|
+
</Step>
|
|
201
|
+
|
|
202
|
+
<Step title="Delete what the runtime now owns">
|
|
203
|
+
Work through your hooks and remove every write that duplicates a change the storage receives:
|
|
204
|
+
|
|
205
|
+
- Message writes in `onTurnStart` and `onTurnComplete`, including the steering messages you filed from `newUIMessages` or `pendingMessages.onReceived`.
|
|
206
|
+
- The `lastEventId` write in `onTurnComplete`. The cursor now arrives on the changeset.
|
|
207
|
+
- Row writes paired with `chat.history` calls in `onAction`. An undo is a `truncateAfter`, an edit is a `put` and a `truncateAfter`. To answer after an edit, return `chat.turn()`; returning a model response from `onAction` is no longer supported.
|
|
208
|
+
- Per-step partial writes in `onStepFinish`, and any run-state or "still streaming" flag. A crash is recovered from the durable session stream, and a partial that survives reaches `save` with `final: false`.
|
|
209
|
+
- Dangling tool-call repair. The runtime cleans a partial before it saves it.
|
|
210
|
+
- Your compaction summary column, its watermark, and the invalidation you ran on every rollback path. The summary travels in `state`, and the runtime discards it when a rollback crosses the point it covers.
|
|
211
|
+
- Any filter that dropped an empty assistant message. A turn that fails before the model writes anything is not handed to `save`.
|
|
212
|
+
|
|
213
|
+
Keep `onTurnStart` for the session token if your frontend hydrates from your own table, and keep `onTurnComplete` for side work such as naming the conversation.
|
|
214
|
+
</Step>
|
|
215
|
+
|
|
216
|
+
<Step title="Update the history read on your frontend">
|
|
217
|
+
Your page most likely reads history from your tables directly. That keeps working. To use the same read the runtime uses, and to seed the live subscription's cursor so a reload does not replay what it just loaded, wrap the storage in a server action and load it with the hook:
|
|
218
|
+
|
|
219
|
+
<CodeGroup>
|
|
220
|
+
```ts app/actions.ts
|
|
221
|
+
"use server";
|
|
222
|
+
import { chat } from "@trigger.dev/sdk/ai";
|
|
223
|
+
import { transcriptStorage } from "@/lib/transcript-storage";
|
|
224
|
+
|
|
225
|
+
const load = chat.createLoadTranscriptAction(transcriptStorage);
|
|
226
|
+
|
|
227
|
+
export async function loadTranscript(params: { chatId: string; limit?: number; before?: string }) {
|
|
228
|
+
const userId = await getUserId();
|
|
229
|
+
await assertOwnsChat(userId, params.chatId);
|
|
230
|
+
return load({ ...params, clientData: { userId } });
|
|
231
|
+
}
|
|
232
|
+
```
|
|
233
|
+
|
|
234
|
+
```tsx app/c/[chatId]/ChatPage.tsx
|
|
235
|
+
"use client";
|
|
236
|
+
import { useLoadTranscript, useTriggerChatTransport } from "@trigger.dev/sdk/chat/react";
|
|
237
|
+
import { loadTranscript } from "@/app/actions";
|
|
238
|
+
|
|
239
|
+
export function ChatPage({ chatId }: { chatId: string }) {
|
|
240
|
+
const transport = useTriggerChatTransport({ task: "my-chat", accessToken, startSession });
|
|
241
|
+
const { messages, isLoading, nextCursor } = useLoadTranscript(chatId, loadTranscript, {
|
|
242
|
+
transport,
|
|
243
|
+
limit: 50,
|
|
244
|
+
});
|
|
245
|
+
if (isLoading) return <Spinner />;
|
|
246
|
+
return <Chat chatId={chatId} initialMessages={messages} transport={transport} olderPage={nextCursor} />;
|
|
247
|
+
}
|
|
248
|
+
```
|
|
249
|
+
</CodeGroup>
|
|
250
|
+
|
|
251
|
+
<Warning>
|
|
252
|
+
The action receives `chatId` from the browser. Authorize it there, before calling the storage. The storage's own `clientData` check is a backstop, not the boundary.
|
|
253
|
+
</Warning>
|
|
254
|
+
</Step>
|
|
255
|
+
|
|
256
|
+
<Step title="Run the conformance suite">
|
|
257
|
+
Point `runTranscriptStorageTests` at your storage. It checks appends and in-place replacement, idempotent `remove` and `truncateAfter`, `state` round-trips, cursors, replaying the same changeset twice, paging, and chat isolation, against whatever database you give it.
|
|
258
|
+
|
|
259
|
+
```ts lib/transcript-storage.test.ts
|
|
260
|
+
import { runTranscriptStorageTests } from "@trigger.dev/sdk/ai/test";
|
|
261
|
+
import { describe, expect, it } from "vitest";
|
|
262
|
+
import { transcriptStorage } from "./transcript-storage";
|
|
263
|
+
|
|
264
|
+
runTranscriptStorageTests(() => transcriptStorage, {
|
|
265
|
+
api: { describe, it, expect },
|
|
266
|
+
clientData: { userId: "user_test" },
|
|
267
|
+
});
|
|
268
|
+
```
|
|
269
|
+
|
|
270
|
+
`memoryTranscriptStorage()` is the reference implementation. Use it in your agent tests to see exactly which changes the runtime hands a storage for a given turn.
|
|
271
|
+
</Step>
|
|
272
|
+
</Steps>
|
|
273
|
+
|
|
274
|
+
## Behaviour that changes
|
|
275
|
+
|
|
276
|
+
A few things your users and your tests will notice after the swap:
|
|
277
|
+
|
|
278
|
+
- **Actions are edits.** `onAction` mutates `chat.history` and returns nothing, or returns `chat.turn()` to have a full turn answer the edited history. The regenerated answer is saved and remembered like any other. See [Actions](/ai-chat/actions#answering-after-an-action).
|
|
279
|
+
- **`onRecoveryBoot` is informational.** It fires when a run boots after a crash and finds a half-written answer on the session stream. The runtime already reconciled the transcript; use the hook to tell the user, not to write rows.
|
|
280
|
+
- **A failed turn keeps its partial, marked.** An answer cut short reaches `save` with `final: false`; report those ids back from `load` in `nonFinalIds`.
|
|
281
|
+
- **Compaction survives a reboot without your help.** The summary travels in `state`.
|
|
282
|
+
- **Your rows do not have to be byte-identical.** Store messages in whatever shape your database prefers. The runtime does not depend on an exact JSON round-trip.
|
|
283
|
+
|
|
284
|
+
## Checklist
|
|
285
|
+
|
|
286
|
+
- [ ] `load` returns messages in conversation order, plus `state`, `cursors` and `nonFinalIds`
|
|
287
|
+
- [ ] `save` applies all four change kinds and writes the cursors in the same transaction
|
|
288
|
+
- [ ] Positions are assigned on first insert only, never by timestamp
|
|
289
|
+
- [ ] `hydrateMessages` removed; `storage` set; the agent boots
|
|
290
|
+
- [ ] Message, cursor, partial, repair and compaction writes deleted from hooks
|
|
291
|
+
- [ ] `onAction` returns `chat.turn()` where it used to stream an answer
|
|
292
|
+
- [ ] `runTranscriptStorageTests` passes against the real database
|
|
293
|
+
|
|
294
|
+
## See also
|
|
295
|
+
|
|
296
|
+
- [Transcript storage](/ai-chat/transcript-storage): the full contract and what `save` receives
|
|
297
|
+
- [Actions](/ai-chat/actions): what undo, edit and regenerate become in the changeset
|
|
298
|
+
- [Lifecycle hooks](/ai-chat/lifecycle-hooks#hydratemessages): the deprecated hook's reference entry
|
|
299
|
+
- [Database persistence](/ai-chat/patterns/database-persistence): the hook-based pattern this replaces
|
|
@@ -0,0 +1,86 @@
|
|
|
1
|
+
---
|
|
2
|
+
title: "AI Agents"
|
|
3
|
+
sidebarTitle: "Overview"
|
|
4
|
+
description: "Durable multi-turn AI chats — one Trigger.dev task per conversation, surviving refreshes, deploys, and crashes."
|
|
5
|
+
---
|
|
6
|
+
|
|
7
|
+
An AI chat isn't a request — it's a session. `chat.agent` runs every conversation as a single long-lived Trigger.dev task: you write the loop, it wakes up when a message arrives, freezes when none do, and the same in-memory state and on-disk workspace survive across page refreshes, deploys, idle gaps, and crashes. The substrate handles the parts most teams stitch together by hand — turn lifecycle, mid-stream resume, recovery from cancel/crash/OOM, HITL approvals, deploy upgrades — so your code is the loop you'd write anyway: messages in, `streamText` out.
|
|
8
|
+
|
|
9
|
+
## A minimal example
|
|
10
|
+
|
|
11
|
+
A `chat.agent` task takes `messages`, calls `streamText`, and returns the result. The frontend wires the [Vercel AI SDK's `useChat`](https://ai-sdk.dev/docs/reference/ai-sdk-ui/use-chat) to a `TriggerChatTransport`. No API routes.
|
|
12
|
+
|
|
13
|
+
```ts trigger/chat.ts
|
|
14
|
+
import { chat } from "@trigger.dev/sdk/ai";
|
|
15
|
+
import { streamText, stepCountIs } from "ai";
|
|
16
|
+
import { anthropic } from "@ai-sdk/anthropic";
|
|
17
|
+
|
|
18
|
+
export const myChat = chat.agent({
|
|
19
|
+
id: "my-chat",
|
|
20
|
+
run: async ({ messages, signal }) =>
|
|
21
|
+
streamText({
|
|
22
|
+
model: anthropic("claude-sonnet-4-5"),
|
|
23
|
+
messages,
|
|
24
|
+
abortSignal: signal,
|
|
25
|
+
stopWhen: stepCountIs(15),
|
|
26
|
+
}),
|
|
27
|
+
});
|
|
28
|
+
```
|
|
29
|
+
|
|
30
|
+
```tsx app/components/Chat.tsx
|
|
31
|
+
import { useChat } from "@ai-sdk/react";
|
|
32
|
+
import { useTriggerChatTransport } from "@trigger.dev/sdk/chat/react";
|
|
33
|
+
|
|
34
|
+
export function Chat() {
|
|
35
|
+
const transport = useTriggerChatTransport<typeof myChat>({
|
|
36
|
+
task: "my-chat",
|
|
37
|
+
accessToken: ({ chatId }) => mintChatAccessToken(chatId),
|
|
38
|
+
startSession: ({ chatId, clientData }) =>
|
|
39
|
+
startChatSession({ chatId, clientData }),
|
|
40
|
+
});
|
|
41
|
+
const { messages, sendMessage } = useChat({ transport });
|
|
42
|
+
// ... render UI
|
|
43
|
+
}
|
|
44
|
+
```
|
|
45
|
+
|
|
46
|
+
See [Quick Start](/ai-chat/quick-start) for the matching server actions and a runnable project.
|
|
47
|
+
|
|
48
|
+
## Why use AI Agents on Trigger.dev
|
|
49
|
+
|
|
50
|
+
- **Resume across refreshes, deploys, and crashes.** A chat in progress keeps streaming through a redeploy, pinned to the version it started on. Move it onto new code when you choose with a [version upgrade](/ai-chat/patterns/version-upgrades). Mid-stream refreshes pick up where they left off.
|
|
51
|
+
- **Native AI SDK support.** Text, tool calls, reasoning, and custom `data-*` parts all flow through `useChat` over a custom `ChatTransport`. No custom protocol to maintain.
|
|
52
|
+
- **Multi-turn for free.** Each turn is a step inside the same durable task; conversation history accumulates server-side, so clients only ship the new message.
|
|
53
|
+
- **Fast cold starts.** Opt-in [Head Start](/ai-chat/fast-starts#head-start) runs the first `streamText` step in your warm Next.js / Hono / SvelteKit server while the agent boots in parallel — cuts time-to-first-chunk roughly in half.
|
|
54
|
+
- **Production primitives ship in the box.** Stop generation, steering, edits, branching, sub-agents, HITL tool approvals, version upgrades, recovery from cancel/crash/OOM — all first-class.
|
|
55
|
+
- **Observable.** Every turn is a span in the Trigger.dev dashboard. Sessions are queryable via `sessions.list` for inbox-style UIs.
|
|
56
|
+
|
|
57
|
+
## How it fits together
|
|
58
|
+
|
|
59
|
+
Three primitives, related but distinct:
|
|
60
|
+
|
|
61
|
+
- **Chat agents** — the SDK surface you define with [`chat.agent()`](/ai-chat/backend#chat-agent). Owns the turn loop, lifecycle hooks, and the response stream.
|
|
62
|
+
- **Sessions** — the durable, bi-directional channel keyed on `chatId` that holds the conversation across run boundaries. A chat agent runs *on top of* a [Session](/ai-chat/sessions).
|
|
63
|
+
- **Sub-agents** — Delegate work from one agent to another via [`AgentChat`](/ai-chat/patterns/sub-agents). The sub-agent runs as its own durable agent on its own session; its response streams back through the parent as preliminary tool results, so the frontend sees the sub-agent working inside the parent's tool card.
|
|
64
|
+
|
|
65
|
+
## Next steps
|
|
66
|
+
|
|
67
|
+
<CardGroup cols={2}>
|
|
68
|
+
<Card title="Quick Start" icon="rocket" href="/ai-chat/quick-start">
|
|
69
|
+
Get a working chat in three steps — agent, token, frontend.
|
|
70
|
+
</Card>
|
|
71
|
+
<Card title="How it works" icon="diagram-project" href="/ai-chat/how-it-works">
|
|
72
|
+
Sessions, the turn loop, durable streams, and what survives a refresh.
|
|
73
|
+
</Card>
|
|
74
|
+
<Card title="Backend" icon="server" href="/ai-chat/backend">
|
|
75
|
+
`chat.agent` options, lifecycle hooks, and the raw-task primitives.
|
|
76
|
+
</Card>
|
|
77
|
+
<Card title="Tools" icon="wrench" href="/ai-chat/tools">
|
|
78
|
+
Declare tools so `toModelOutput` survives across turns, typed in `run()`.
|
|
79
|
+
</Card>
|
|
80
|
+
<Card title="Patterns" icon="puzzle-piece" href="/ai-chat/patterns/sub-agents">
|
|
81
|
+
HITL approvals, branching, sub-agents, OOM/crash recovery.
|
|
82
|
+
</Card>
|
|
83
|
+
<Card title="Database connections" icon="database" href="/database-connections">
|
|
84
|
+
Size and release connection pools so agents don't exhaust your database.
|
|
85
|
+
</Card>
|
|
86
|
+
</CardGroup>
|
|
@@ -0,0 +1,145 @@
|
|
|
1
|
+
---
|
|
2
|
+
title: "Branching conversations"
|
|
3
|
+
sidebarTitle: "Branching conversations"
|
|
4
|
+
description: "Persist an active conversation branch and use transcript storage and actions to switch the agent's context."
|
|
5
|
+
---
|
|
6
|
+
|
|
7
|
+
Keep an explicit active branch for each chat. Use your storage adapter's `loadContext` to give the model that branch, and use actions to fork or switch it.
|
|
8
|
+
|
|
9
|
+
A fork copies the conversation up to a selected message. Later messages belong to that branch only. For example, one branch can keep Oslo as a destination while another changes it to Tokyo.
|
|
10
|
+
|
|
11
|
+
## Store the active branch
|
|
12
|
+
|
|
13
|
+
Your database needs a chat record with an `activeBranchId`, plus messages for each branch. You can store each branch as a snapshot or use parent pointers to share message prefixes. Persist the selected branch explicitly; choosing the newest leaf loses the selection when someone switches to an older branch.
|
|
14
|
+
|
|
15
|
+
Keep the transcript's `final` flags, opaque runtime state, and stream cursors. A partial assistant response must stay partial after a reload. See [transcript storage](/ai-chat/transcript-storage) for the adapter contract and pagination helpers.
|
|
16
|
+
|
|
17
|
+
The examples below use application helpers from `@/lib/branches`. Implement them against your database with these guarantees:
|
|
18
|
+
|
|
19
|
+
| Helper | Behavior |
|
|
20
|
+
| --- | --- |
|
|
21
|
+
| `readActiveMessages(chatId)` | Return the selected branch in message order. |
|
|
22
|
+
| `forkBranch(chatId, messageId)` | Copy the active prefix through the selected message, create a branch, and select it in one transaction. Reject messages outside this chat. |
|
|
23
|
+
| `selectBranch(chatId, branchId)` | Select an existing branch belonging to this chat. |
|
|
24
|
+
| `branchStorage.load` | Return the active transcript, runtime state, final flags, and resume cursors. |
|
|
25
|
+
| `branchStorage.save` | Save the supplied transcript to the active branch and retain the supplied runtime state and cursors. |
|
|
26
|
+
|
|
27
|
+
Make repeated saves idempotent by message ID. Serialize branch changes with transcript writes so a turn can't save its response into a different branch.
|
|
28
|
+
|
|
29
|
+
## Load the selected context
|
|
30
|
+
|
|
31
|
+
A storage adapter with `loadContext` owns the model's context on every turn and action. Include incoming user messages in the selected branch. Handle regeneration explicitly by removing trailing assistant messages before returning the context.
|
|
32
|
+
|
|
33
|
+
```ts lib/branch-storage.ts
|
|
34
|
+
import type { UIMessage } from "ai";
|
|
35
|
+
import type {
|
|
36
|
+
LoadContextEvent,
|
|
37
|
+
TranscriptScope,
|
|
38
|
+
TranscriptStorage,
|
|
39
|
+
} from "@trigger.dev/sdk/ai";
|
|
40
|
+
import { branchStorage, readActiveMessages } from "@/lib/branches";
|
|
41
|
+
|
|
42
|
+
export const storage: TranscriptStorage = {
|
|
43
|
+
...branchStorage,
|
|
44
|
+
async loadContext<T extends UIMessage>(
|
|
45
|
+
{ chatId }: TranscriptScope,
|
|
46
|
+
event: LoadContextEvent<unknown, T>
|
|
47
|
+
): Promise<T[]> {
|
|
48
|
+
const messages = [...(await readActiveMessages(chatId))] as T[];
|
|
49
|
+
|
|
50
|
+
if (event.trigger === "regenerate-message") {
|
|
51
|
+
while (messages.length && messages.at(-1)!.role !== "user") {
|
|
52
|
+
messages.pop();
|
|
53
|
+
}
|
|
54
|
+
}
|
|
55
|
+
|
|
56
|
+
for (const incoming of event.incomingMessages) {
|
|
57
|
+
if (incoming.role === "user" && !messages.some((m) => m.id === incoming.id)) {
|
|
58
|
+
messages.push(incoming);
|
|
59
|
+
}
|
|
60
|
+
}
|
|
61
|
+
|
|
62
|
+
return messages;
|
|
63
|
+
},
|
|
64
|
+
};
|
|
65
|
+
```
|
|
66
|
+
|
|
67
|
+
This pattern supports plain user messages. For tools that wait for browser results or approval, retain the canonical assistant message in your returned context. The SDK merges incoming tool-result state into that message by ID.
|
|
68
|
+
|
|
69
|
+
`loadContext` also receives `previousMessages`, including any tail recovered from the session stream. If your database missed a save, reconcile that tail with the active branch before returning context. Recovery needs to preserve branch ownership; appending every recovered message to whichever branch is selected can mix conversations.
|
|
70
|
+
|
|
71
|
+
## Fork and switch through actions
|
|
72
|
+
|
|
73
|
+
Perform branch changes in `onAction` and update `chat.history` to match the selected branch. Returning without `chat.turn()` completes the action without asking the model for a response. The runtime still calls `storage.save` with reason `action`.
|
|
74
|
+
|
|
75
|
+
```ts trigger/chat.ts
|
|
76
|
+
import { chat } from "@trigger.dev/sdk/ai";
|
|
77
|
+
import { anthropic } from "@ai-sdk/anthropic";
|
|
78
|
+
import { z } from "zod";
|
|
79
|
+
import { storage } from "@/lib/branch-storage";
|
|
80
|
+
import { forkBranch, selectBranch, readActiveMessages } from "@/lib/branches";
|
|
81
|
+
|
|
82
|
+
export const myChat = chat.agent({
|
|
83
|
+
id: "branching-chat",
|
|
84
|
+
storage,
|
|
85
|
+
actionSchema: z.discriminatedUnion("type", [
|
|
86
|
+
z.object({ type: z.literal("fork"), messageId: z.string() }),
|
|
87
|
+
z.object({ type: z.literal("switch"), branchId: z.string() }),
|
|
88
|
+
]),
|
|
89
|
+
onAction: async ({ chatId, action }) => {
|
|
90
|
+
if (action.type === "fork") {
|
|
91
|
+
await forkBranch(chatId, action.messageId);
|
|
92
|
+
} else {
|
|
93
|
+
await selectBranch(chatId, action.branchId);
|
|
94
|
+
}
|
|
95
|
+
|
|
96
|
+
chat.history.set(await readActiveMessages(chatId));
|
|
97
|
+
},
|
|
98
|
+
run: async ({ messages, signal, streamText }) => {
|
|
99
|
+
return streamText({
|
|
100
|
+
model: anthropic("claude-sonnet-4-5"),
|
|
101
|
+
messages,
|
|
102
|
+
abortSignal: signal,
|
|
103
|
+
});
|
|
104
|
+
},
|
|
105
|
+
});
|
|
106
|
+
```
|
|
107
|
+
|
|
108
|
+
Wait for a response to finish before forking or switching. Start with forks at completed assistant messages. Forking inside an unresolved tool exchange needs a policy for pending tool calls and already-performed side effects.
|
|
109
|
+
|
|
110
|
+
## Update the frontend after the action
|
|
111
|
+
|
|
112
|
+
Use `useChatActions` with `useChat`'s `sendMessage`. It consumes the action's response stream and keeps request state in the chat hook. After the action completes, reload the selected transcript so the visible messages match the next model call.
|
|
113
|
+
|
|
114
|
+
```tsx app/chat/BranchPicker.tsx
|
|
115
|
+
import { useChat } from "@ai-sdk/react";
|
|
116
|
+
import { useChatActions } from "@trigger.dev/sdk/chat/react";
|
|
117
|
+
import { loadTranscript } from "@/app/actions";
|
|
118
|
+
|
|
119
|
+
// Inside your chat component, with its existing chatId and transport:
|
|
120
|
+
const { sendMessage, setMessages, status } = useChat({ id: chatId, transport });
|
|
121
|
+
const { sendAction } = useChatActions({ sendMessage });
|
|
122
|
+
const busy = status === "submitted" || status === "streaming";
|
|
123
|
+
|
|
124
|
+
async function switchBranch(branchId: string) {
|
|
125
|
+
await sendAction({ type: "switch", branchId });
|
|
126
|
+
const transcript = await loadTranscript({ chatId });
|
|
127
|
+
setMessages(transcript.messages);
|
|
128
|
+
}
|
|
129
|
+
|
|
130
|
+
<button disabled={busy} onClick={() => switchBranch(branch.id)}>
|
|
131
|
+
{branch.label}
|
|
132
|
+
</button>
|
|
133
|
+
```
|
|
134
|
+
|
|
135
|
+
Authenticate `loadTranscript` and check ownership before reading the chat. Validate branch IDs on the server even when the frontend only offers branches from that chat. If you use `transport.sendAction` directly, consume its returned stream before sending another message.
|
|
136
|
+
|
|
137
|
+
## Check branch isolation
|
|
138
|
+
|
|
139
|
+
1. Tell the agent the destination is Oslo and wait for the response.
|
|
140
|
+
2. Fork at that response, then change the destination to Tokyo.
|
|
141
|
+
3. Switch to the original branch and ask for the destination. It should answer Oslo.
|
|
142
|
+
4. Switch to the fork and ask again. It should answer Tokyo.
|
|
143
|
+
5. Reload the page and repeat the checks. The selected branch and its messages should survive the reload.
|
|
144
|
+
|
|
145
|
+
Also test regeneration, repeated storage saves, and continuation in a fresh run. An in-memory branch choice can pass the first four steps and still disappear when the worker restarts.
|
|
@@ -0,0 +1,122 @@
|
|
|
1
|
+
---
|
|
2
|
+
title: "Code execution sandbox"
|
|
3
|
+
sidebarTitle: "Code sandbox"
|
|
4
|
+
description: "Warm an isolated sandbox on each chat turn, run an AI SDK executeCode tool, and tear down right before the run suspends — using chat.agent hooks and chat.local."
|
|
5
|
+
---
|
|
6
|
+
|
|
7
|
+
Use a **hosted code sandbox** (for example [E2B](https://e2b.dev)) when the model should run short scripts to analyze tool output (PostHog queries, CSV-like data, math) without executing arbitrary code on the Trigger worker host.
|
|
8
|
+
|
|
9
|
+
This page describes a **durable chat** pattern that fits `chat.agent()`:
|
|
10
|
+
|
|
11
|
+
- **Warm** the sandbox at the start of each turn (**non-blocking**).
|
|
12
|
+
- **Reuse** it for every `executeCode` tool call during that turn (and across turns in the same run if you keep the handle).
|
|
13
|
+
- **Dispose** it **right before the run suspends** waiting for the next user message — using the **`onChatSuspend`** hook, not `onTurnComplete`.
|
|
14
|
+
|
|
15
|
+
|
|
16
|
+
## Why not tear down in `onTurnComplete`?
|
|
17
|
+
|
|
18
|
+
After a turn finishes, the chat runtime still goes through an **idle** window and only then suspends. During that window the run is still executing — useful for `chat.defer()` work — and the run hasn't suspended yet.
|
|
19
|
+
|
|
20
|
+
The boundary you want for “turn done, about to sleep” is **`onChatSuspend`**, which fires right before the run transitions from idle to suspended. It provides the `phase` (`”preload”` or `”turn”`) and full chat context. See [onChatSuspend / onChatResume](/ai-chat/lifecycle-hooks#onchatsuspend--onchatresume).
|
|
21
|
+
|
|
22
|
+
```mermaid
|
|
23
|
+
sequenceDiagram
|
|
24
|
+
participant TurnStart as onTurnStart
|
|
25
|
+
participant Run as run / streamText
|
|
26
|
+
participant TurnDone as onTurnComplete
|
|
27
|
+
participant Idle as Idle window
|
|
28
|
+
participant Suspend as onChatSuspend
|
|
29
|
+
participant Sleep as suspended
|
|
30
|
+
|
|
31
|
+
TurnStart->>Run: warm sandbox (async)
|
|
32
|
+
Run->>TurnDone: persist / inject / etc.
|
|
33
|
+
TurnDone->>Idle: still running
|
|
34
|
+
Idle->>Suspend: dispose sandbox
|
|
35
|
+
Suspend->>Sleep: waiting for next message
|
|
36
|
+
```
|
|
37
|
+
|
|
38
|
+
## Recommended provider: E2B
|
|
39
|
+
|
|
40
|
+
- **API key** auth — works from any Trigger.dev worker; no Vercel-only OIDC.
|
|
41
|
+
- **Code Interpreter** SDK (`@e2b/code-interpreter`): long-lived sandbox, `runCode()`, `kill()`.
|
|
42
|
+
|
|
43
|
+
Alternatives (Modal, Daytona, raw Docker) are fine but more DIY. Vercel’s sandbox + AI SDK helpers are a better fit when execution stays **on Vercel**, not on the Trigger worker.
|
|
44
|
+
|
|
45
|
+
## Implementation sketch
|
|
46
|
+
|
|
47
|
+
### 1. Run-scoped sandbox map
|
|
48
|
+
|
|
49
|
+
Keep a `Map<runId, Promise<Sandbox>>` (or similar) in a **task-only module** so your Next.js app never imports it.
|
|
50
|
+
|
|
51
|
+
### 2. `onTurnStart` — warm without blocking
|
|
52
|
+
|
|
53
|
+
```ts
|
|
54
|
+
onTurnStart: async ({ runId, ctx, ...rest }) => {
|
|
55
|
+
warmCodeSandbox(runId); // fire-and-forget Sandbox.create()
|
|
56
|
+
// ...persist messages, writer, etc.
|
|
57
|
+
},
|
|
58
|
+
```
|
|
59
|
+
|
|
60
|
+
### 3. `chat.local` — run id for tools
|
|
61
|
+
|
|
62
|
+
Tool `execute` functions do not receive hook payloads. Use [`chat.local()`](/ai-chat/chat-local) to store the current run id for the sandbox key, **initialized from `onTurnStart`** (same `runId` as the map):
|
|
63
|
+
|
|
64
|
+
```ts
|
|
65
|
+
// In the same task module as your tools
|
|
66
|
+
import { chat } from "@trigger.dev/sdk/ai";
|
|
67
|
+
|
|
68
|
+
export const codeSandboxRun = chat.local<{ runId: string }>({ id: "codeSandboxRun" });
|
|
69
|
+
|
|
70
|
+
export function warmCodeSandbox(runId: string) {
|
|
71
|
+
codeSandboxRun.init({ runId });
|
|
72
|
+
// ...start Sandbox.create(), store promise in Map by runId
|
|
73
|
+
}
|
|
74
|
+
```
|
|
75
|
+
|
|
76
|
+
The **`executeCode`** tool reads `codeSandboxRun.runId` and awaits the sandbox promise before `runCode`.
|
|
77
|
+
|
|
78
|
+
### 4. `onChatSuspend` / `onComplete` — teardown
|
|
79
|
+
|
|
80
|
+
Use **`onChatSuspend`** to dispose the sandbox right before the run suspends, and **`onComplete`** as a safety net when the run ends entirely.
|
|
81
|
+
|
|
82
|
+
```ts
|
|
83
|
+
export const aiChat = chat.agent({
|
|
84
|
+
id: "ai-chat",
|
|
85
|
+
// ...
|
|
86
|
+
onChatSuspend: async ({ phase, ctx }) => {
|
|
87
|
+
await disposeCodeSandboxForRun(ctx.run.id);
|
|
88
|
+
},
|
|
89
|
+
onComplete: async ({ ctx }) => {
|
|
90
|
+
await disposeCodeSandboxForRun(ctx.run.id);
|
|
91
|
+
},
|
|
92
|
+
});
|
|
93
|
+
```
|
|
94
|
+
|
|
95
|
+
Unlike `onWait` (which fires for all wait types), `onChatSuspend` only fires at chat suspension points — no need to filter on `wait.type`. The `phase` discriminator tells you if this is a preload or post-turn suspension.
|
|
96
|
+
|
|
97
|
+
Optional **`onChatResume`**: log or reset flags; a fresh sandbox can be warmed again on the next **`onTurnStart`**.
|
|
98
|
+
|
|
99
|
+
### 5. AI SDK tool
|
|
100
|
+
|
|
101
|
+
Wrap the provider in a normal AI SDK `tool({ inputSchema, execute })` (same pattern as `webFetch`). Keep tool definitions in **task code**, not in the Next.js server bundle.
|
|
102
|
+
|
|
103
|
+
### 6. Environment
|
|
104
|
+
|
|
105
|
+
Set **`E2B_API_KEY`** (or your provider’s secret) on the **Trigger environment** for the worker — not in public client env.
|
|
106
|
+
|
|
107
|
+
## Typing `ctx`
|
|
108
|
+
|
|
109
|
+
Every `chat.agent` lifecycle event and the `run` payload include **`ctx`**: the same **[`TaskRunContext`](/ai-chat/reference#task-context-ctx)** shape as `task({ run: (payload, { ctx }) => ... })`.
|
|
110
|
+
|
|
111
|
+
```ts
|
|
112
|
+
import type { TaskRunContext } from "@trigger.dev/sdk";
|
|
113
|
+
```
|
|
114
|
+
|
|
115
|
+
The alias **`Context`** is also exported from `@trigger.dev/sdk` and is the same type.
|
|
116
|
+
|
|
117
|
+
## See also
|
|
118
|
+
|
|
119
|
+
- [Database persistence for chat](/ai-chat/patterns/database-persistence) — conversation + session rows, hooks, token renewal
|
|
120
|
+
- [Lifecycle hooks](/ai-chat/lifecycle-hooks)
|
|
121
|
+
- [API Reference — `ctx` on events](/ai-chat/reference#task-context-ctx)
|
|
122
|
+
- [Per-run data with `chat.local`](/ai-chat/chat-local)
|