@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
package/dist/esm/v3/shared.js
CHANGED
|
@@ -1,43 +1,121 @@
|
|
|
1
1
|
import { SpanKind } from "@opentelemetry/api";
|
|
2
|
-
import { accessoryAttributes, apiClientManager, conditionallyImportPacket, convertToolParametersToSchema, createErrorTaskError, defaultRetryOptions, getSchemaParseFn, makeIdempotencyKey, parsePacket, runtime, SemanticInternalAttributes, stringifyIO, SubtaskUnwrapError,
|
|
3
|
-
import {
|
|
2
|
+
import { accessoryAttributes, apiClientManager, ApiError, conditionallyExportPacket, conditionallyImportPacket, convertToolParametersToSchema, createErrorFromCauses, createErrorTaskError, defaultRetryOptions, flattenIdempotencyKey, generateFriendlyId, getIdempotencyKeyOptions, getSchemaParseFn, lifecycleHooks, makeIdempotencyKey, packetRequiresOffloading, parsePacket, RateLimitError, resourceCatalog, runtime, SemanticInternalAttributes, stringifyIO, SubtaskUnwrapError, taskContext, TaskRunPromise, } from "@trigger.dev/core/v3";
|
|
3
|
+
import { resolveTriggerExternalDeploymentId, scopedEnvVar } from "./externalDeploymentId.js";
|
|
4
4
|
import { tracer } from "./tracer.js";
|
|
5
|
+
import { triggerConcurrencyBody, validateConcurrencyLimitName } from "./concurrency-shared.js";
|
|
5
6
|
export { SubtaskUnwrapError, TaskRunPromise };
|
|
7
|
+
/** A task's `queue` is a queue object or a string reference to a queue defined elsewhere. */
|
|
8
|
+
function normalizeTaskQueue(queue) {
|
|
9
|
+
if (!queue) {
|
|
10
|
+
return {};
|
|
11
|
+
}
|
|
12
|
+
return { queue: typeof queue === "string" ? { name: queue } : queue };
|
|
13
|
+
}
|
|
14
|
+
/**
|
|
15
|
+
* Validates and normalizes the task `concurrency` option into its manifest shape:
|
|
16
|
+
* at most one inline limit (caps this task) plus up to two named limits (shared).
|
|
17
|
+
*/
|
|
18
|
+
function normalizeTaskConcurrency(taskId, concurrency) {
|
|
19
|
+
if (!concurrency) {
|
|
20
|
+
return undefined;
|
|
21
|
+
}
|
|
22
|
+
const items = Array.isArray(concurrency) ? concurrency : [concurrency];
|
|
23
|
+
const inline = [];
|
|
24
|
+
const limits = [];
|
|
25
|
+
for (const item of items) {
|
|
26
|
+
if (typeof item === "string") {
|
|
27
|
+
limits.push(item);
|
|
28
|
+
}
|
|
29
|
+
else if (item &&
|
|
30
|
+
typeof item === "object" &&
|
|
31
|
+
"name" in item &&
|
|
32
|
+
typeof item.name === "string") {
|
|
33
|
+
validateConcurrencyLimitName(item.name);
|
|
34
|
+
resourceCatalog.registerConcurrencyLimitMetadata(item);
|
|
35
|
+
limits.push(item.name);
|
|
36
|
+
}
|
|
37
|
+
else if (item && typeof item === "object") {
|
|
38
|
+
inline.push({ perKey: item.perKey, total: item.total });
|
|
39
|
+
}
|
|
40
|
+
}
|
|
41
|
+
if (inline.length > 1) {
|
|
42
|
+
throw new Error(`Task "${taskId}": concurrency accepts at most one inline limit. Give shared limits a name with concurrencyLimit().`);
|
|
43
|
+
}
|
|
44
|
+
if (limits.length > 2) {
|
|
45
|
+
throw new Error(`Task "${taskId}": concurrency accepts at most two named limits.`);
|
|
46
|
+
}
|
|
47
|
+
return {
|
|
48
|
+
inline: inline[0],
|
|
49
|
+
limits: limits.length > 0 ? limits : undefined,
|
|
50
|
+
};
|
|
51
|
+
}
|
|
52
|
+
/** Builds the queue field of a trigger request body. */
|
|
53
|
+
function triggerQueueBody(queue, fallbackQueueName) {
|
|
54
|
+
const name = queue ?? fallbackQueueName;
|
|
55
|
+
return { queue: name ? { name } : undefined };
|
|
56
|
+
}
|
|
6
57
|
export function queue(options) {
|
|
58
|
+
resourceCatalog.registerQueueMetadata(options);
|
|
59
|
+
// @ts-expect-error
|
|
60
|
+
options[Symbol.for("trigger.dev/queue")] = true;
|
|
61
|
+
return options;
|
|
62
|
+
}
|
|
63
|
+
/**
|
|
64
|
+
* Declares a named, shareable concurrency limit. Tasks hold it via their `concurrency`
|
|
65
|
+
* option; every task holding the same limit draws from the same pools.
|
|
66
|
+
*
|
|
67
|
+
* @example
|
|
68
|
+
*
|
|
69
|
+
* ```ts
|
|
70
|
+
* export const openaiLimit = concurrencyLimit({ name: "openai", total: 25 });
|
|
71
|
+
*
|
|
72
|
+
* export const generateSummary = task({
|
|
73
|
+
* id: "generate-summary",
|
|
74
|
+
* concurrency: [{ total: 5 }, openaiLimit],
|
|
75
|
+
* run: async (payload) => {},
|
|
76
|
+
* });
|
|
77
|
+
* ```
|
|
78
|
+
*/
|
|
79
|
+
export function concurrencyLimit(options) {
|
|
80
|
+
validateConcurrencyLimitName(options.name);
|
|
81
|
+
resourceCatalog.registerConcurrencyLimitMetadata(options);
|
|
82
|
+
// @ts-expect-error
|
|
83
|
+
options[Symbol.for("trigger.dev/concurrencyLimit")] = true;
|
|
7
84
|
return options;
|
|
8
85
|
}
|
|
9
86
|
export function createTask(params) {
|
|
10
|
-
const
|
|
11
|
-
? queue({
|
|
12
|
-
name: params.queue?.name ?? `task/${params.id}`,
|
|
13
|
-
...params.queue,
|
|
14
|
-
})
|
|
15
|
-
: undefined;
|
|
87
|
+
const normalizedQueue = normalizeTaskQueue(params.queue);
|
|
16
88
|
const task = {
|
|
17
89
|
id: params.id,
|
|
18
90
|
description: params.description,
|
|
91
|
+
jsonSchema: params.jsonSchema,
|
|
19
92
|
trigger: async (payload, options) => {
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
? `${taskMetadata.exportName}.trigger()`
|
|
23
|
-
: `trigger()`, params.id, payload, undefined, {
|
|
24
|
-
queue: customQueue,
|
|
93
|
+
return await trigger_internal("trigger()", params.id, payload, undefined, {
|
|
94
|
+
queue: normalizedQueue.queue?.name,
|
|
25
95
|
...options,
|
|
26
96
|
});
|
|
27
97
|
},
|
|
28
98
|
batchTrigger: async (items, options) => {
|
|
29
|
-
|
|
30
|
-
return await batchTrigger_internal(taskMetadata && taskMetadata.exportName
|
|
31
|
-
? `${taskMetadata.exportName}.batchTrigger()`
|
|
32
|
-
: `batchTrigger()`, params.id, items, options, undefined, undefined, customQueue);
|
|
99
|
+
return await batchTrigger_internal("batchTrigger()", params.id, items, options, undefined, undefined, normalizedQueue.queue?.name);
|
|
33
100
|
},
|
|
34
|
-
triggerAndWait: (payload, options) => {
|
|
35
|
-
|
|
101
|
+
triggerAndWait: (payload, options, requestOptions) => {
|
|
102
|
+
return new TaskRunPromise((resolve, reject) => {
|
|
103
|
+
triggerAndWait_internal("triggerAndWait()", params.id, payload, undefined, {
|
|
104
|
+
queue: normalizedQueue.queue?.name,
|
|
105
|
+
...options,
|
|
106
|
+
}, requestOptions)
|
|
107
|
+
.then((result) => {
|
|
108
|
+
resolve(result);
|
|
109
|
+
})
|
|
110
|
+
.catch((error) => {
|
|
111
|
+
reject(error);
|
|
112
|
+
});
|
|
113
|
+
}, params.id);
|
|
114
|
+
},
|
|
115
|
+
triggerAndSubscribe: (payload, options) => {
|
|
36
116
|
return new TaskRunPromise((resolve, reject) => {
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
: `triggerAndWait()`, params.id, payload, undefined, {
|
|
40
|
-
queue: customQueue,
|
|
117
|
+
triggerAndSubscribe_internal("triggerAndSubscribe()", params.id, payload, undefined, {
|
|
118
|
+
queue: normalizedQueue.queue?.name,
|
|
41
119
|
...options,
|
|
42
120
|
})
|
|
43
121
|
.then((result) => {
|
|
@@ -49,34 +127,46 @@ export function createTask(params) {
|
|
|
49
127
|
}, params.id);
|
|
50
128
|
},
|
|
51
129
|
batchTriggerAndWait: async (items, options) => {
|
|
52
|
-
|
|
53
|
-
return await batchTriggerAndWait_internal(taskMetadata && taskMetadata.exportName
|
|
54
|
-
? `${taskMetadata.exportName}.batchTriggerAndWait()`
|
|
55
|
-
: `batchTriggerAndWait()`, params.id, items, undefined, options, undefined, customQueue);
|
|
130
|
+
return await batchTriggerAndWait_internal("batchTriggerAndWait()", params.id, items, undefined, options, undefined, normalizedQueue.queue?.name);
|
|
56
131
|
},
|
|
57
132
|
};
|
|
58
|
-
|
|
133
|
+
registerTaskLifecycleHooks(params.id, params);
|
|
134
|
+
resourceCatalog.registerTaskMetadata({
|
|
59
135
|
id: params.id,
|
|
60
136
|
description: params.description,
|
|
61
|
-
queue:
|
|
137
|
+
queue: normalizedQueue.queue,
|
|
138
|
+
concurrency: normalizeTaskConcurrency(params.id, params.concurrency),
|
|
62
139
|
retry: params.retry ? { ...defaultRetryOptions, ...params.retry } : undefined,
|
|
63
140
|
machine: typeof params.machine === "string" ? { preset: params.machine } : params.machine,
|
|
141
|
+
triggerSource: params.triggerSource,
|
|
142
|
+
agentConfig: params.agentConfig,
|
|
64
143
|
maxDuration: params.maxDuration,
|
|
144
|
+
ttl: params.ttl,
|
|
145
|
+
payloadSchema: params.jsonSchema,
|
|
65
146
|
fns: {
|
|
66
147
|
run: params.run,
|
|
67
|
-
init: params.init,
|
|
68
|
-
cleanup: params.cleanup,
|
|
69
|
-
middleware: params.middleware,
|
|
70
|
-
handleError: params.handleError,
|
|
71
|
-
onSuccess: params.onSuccess,
|
|
72
|
-
onFailure: params.onFailure,
|
|
73
|
-
onStart: params.onStart,
|
|
74
148
|
},
|
|
75
149
|
});
|
|
150
|
+
const queue = normalizedQueue.queue;
|
|
151
|
+
/**
|
|
152
|
+
* A string queue name (bare or as a tuple's first element) is a REFERENCE to a
|
|
153
|
+
* queue defined elsewhere; registering it would create an empty definition that
|
|
154
|
+
* can shadow the real one depending on module evaluation order.
|
|
155
|
+
*/
|
|
156
|
+
const homeIsReference = typeof params.queue === "string";
|
|
157
|
+
if (queue && typeof queue.name === "string" && !homeIsReference) {
|
|
158
|
+
resourceCatalog.registerQueueMetadata({
|
|
159
|
+
name: queue.name,
|
|
160
|
+
concurrencyLimit: queue.concurrencyLimit,
|
|
161
|
+
});
|
|
162
|
+
}
|
|
76
163
|
// @ts-expect-error
|
|
77
164
|
task[Symbol.for("trigger.dev/task")] = true;
|
|
78
165
|
return task;
|
|
79
166
|
}
|
|
167
|
+
/**
|
|
168
|
+
* @deprecated Use `schemaTask` plus AI SDK `tool()` with `execute: ai.toolExecute(task)` instead.
|
|
169
|
+
*/
|
|
80
170
|
export function createToolTask(params) {
|
|
81
171
|
const task = createSchemaTask({
|
|
82
172
|
...params,
|
|
@@ -94,41 +184,41 @@ export function createToolTask(params) {
|
|
|
94
184
|
};
|
|
95
185
|
}
|
|
96
186
|
export function createSchemaTask(params) {
|
|
97
|
-
const customQueue = params.queue
|
|
98
|
-
? queue({
|
|
99
|
-
name: params.queue?.name ?? `task/${params.id}`,
|
|
100
|
-
...params.queue,
|
|
101
|
-
})
|
|
102
|
-
: undefined;
|
|
103
187
|
const parsePayload = params.schema
|
|
104
188
|
? getSchemaParseFn(params.schema)
|
|
105
189
|
: undefined;
|
|
190
|
+
const normalizedQueue = normalizeTaskQueue(params.queue);
|
|
106
191
|
const task = {
|
|
107
192
|
id: params.id,
|
|
108
193
|
description: params.description,
|
|
109
194
|
schema: params.schema,
|
|
110
195
|
trigger: async (payload, options, requestOptions) => {
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
? `${taskMetadata.exportName}.trigger()`
|
|
114
|
-
: `trigger()`, params.id, payload, parsePayload, {
|
|
115
|
-
queue: customQueue,
|
|
196
|
+
return await trigger_internal("trigger()", params.id, payload, parsePayload, {
|
|
197
|
+
queue: normalizedQueue.queue?.name,
|
|
116
198
|
...options,
|
|
117
199
|
}, requestOptions);
|
|
118
200
|
},
|
|
119
201
|
batchTrigger: async (items, options, requestOptions) => {
|
|
120
|
-
|
|
121
|
-
return await batchTrigger_internal(taskMetadata && taskMetadata.exportName
|
|
122
|
-
? `${taskMetadata.exportName}.batchTrigger()`
|
|
123
|
-
: `batchTrigger()`, params.id, items, options, parsePayload, requestOptions, customQueue);
|
|
202
|
+
return await batchTrigger_internal("batchTrigger()", params.id, items, options, parsePayload, requestOptions, normalizedQueue.queue?.name);
|
|
124
203
|
},
|
|
125
204
|
triggerAndWait: (payload, options) => {
|
|
126
|
-
const taskMetadata = taskCatalog.getTaskManifest(params.id);
|
|
127
205
|
return new TaskRunPromise((resolve, reject) => {
|
|
128
|
-
triggerAndWait_internal(
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
206
|
+
triggerAndWait_internal("triggerAndWait()", params.id, payload, parsePayload, {
|
|
207
|
+
queue: normalizedQueue.queue?.name,
|
|
208
|
+
...options,
|
|
209
|
+
})
|
|
210
|
+
.then((result) => {
|
|
211
|
+
resolve(result);
|
|
212
|
+
})
|
|
213
|
+
.catch((error) => {
|
|
214
|
+
reject(error);
|
|
215
|
+
});
|
|
216
|
+
}, params.id);
|
|
217
|
+
},
|
|
218
|
+
triggerAndSubscribe: (payload, options) => {
|
|
219
|
+
return new TaskRunPromise((resolve, reject) => {
|
|
220
|
+
triggerAndSubscribe_internal("triggerAndSubscribe()", params.id, payload, parsePayload, {
|
|
221
|
+
queue: normalizedQueue.queue?.name,
|
|
132
222
|
...options,
|
|
133
223
|
})
|
|
134
224
|
.then((result) => {
|
|
@@ -140,31 +230,40 @@ export function createSchemaTask(params) {
|
|
|
140
230
|
}, params.id);
|
|
141
231
|
},
|
|
142
232
|
batchTriggerAndWait: async (items, options) => {
|
|
143
|
-
|
|
144
|
-
return await batchTriggerAndWait_internal(taskMetadata && taskMetadata.exportName
|
|
145
|
-
? `${taskMetadata.exportName}.batchTriggerAndWait()`
|
|
146
|
-
: `batchTriggerAndWait()`, params.id, items, parsePayload, options, undefined, customQueue);
|
|
233
|
+
return await batchTriggerAndWait_internal("batchTriggerAndWait()", params.id, items, parsePayload, options, undefined, normalizedQueue.queue?.name);
|
|
147
234
|
},
|
|
148
235
|
};
|
|
149
|
-
|
|
236
|
+
registerTaskLifecycleHooks(params.id, params);
|
|
237
|
+
resourceCatalog.registerTaskMetadata({
|
|
150
238
|
id: params.id,
|
|
151
239
|
description: params.description,
|
|
152
|
-
queue:
|
|
240
|
+
queue: normalizedQueue.queue,
|
|
241
|
+
concurrency: normalizeTaskConcurrency(params.id, params.concurrency),
|
|
153
242
|
retry: params.retry ? { ...defaultRetryOptions, ...params.retry } : undefined,
|
|
154
243
|
machine: typeof params.machine === "string" ? { preset: params.machine } : params.machine,
|
|
244
|
+
triggerSource: params.triggerSource,
|
|
245
|
+
agentConfig: params.agentConfig,
|
|
155
246
|
maxDuration: params.maxDuration,
|
|
247
|
+
ttl: params.ttl,
|
|
156
248
|
fns: {
|
|
157
249
|
run: params.run,
|
|
158
|
-
init: params.init,
|
|
159
|
-
cleanup: params.cleanup,
|
|
160
|
-
middleware: params.middleware,
|
|
161
|
-
handleError: params.handleError,
|
|
162
|
-
onSuccess: params.onSuccess,
|
|
163
|
-
onFailure: params.onFailure,
|
|
164
|
-
onStart: params.onStart,
|
|
165
250
|
parsePayload,
|
|
166
251
|
},
|
|
252
|
+
schema: params.schema,
|
|
167
253
|
});
|
|
254
|
+
const queue = normalizedQueue.queue;
|
|
255
|
+
/**
|
|
256
|
+
* A string queue name (bare or as a tuple's first element) is a REFERENCE to a
|
|
257
|
+
* queue defined elsewhere; registering it would create an empty definition that
|
|
258
|
+
* can shadow the real one depending on module evaluation order.
|
|
259
|
+
*/
|
|
260
|
+
const homeIsReference = typeof params.queue === "string";
|
|
261
|
+
if (queue && typeof queue.name === "string" && !homeIsReference) {
|
|
262
|
+
resourceCatalog.registerQueueMetadata({
|
|
263
|
+
name: queue.name,
|
|
264
|
+
concurrencyLimit: queue.concurrencyLimit,
|
|
265
|
+
});
|
|
266
|
+
}
|
|
168
267
|
// @ts-expect-error
|
|
169
268
|
task[Symbol.for("trigger.dev/task")] = true;
|
|
170
269
|
return task;
|
|
@@ -217,6 +316,38 @@ export function triggerAndWait(id, payload, options, requestOptions) {
|
|
|
217
316
|
});
|
|
218
317
|
}, id);
|
|
219
318
|
}
|
|
319
|
+
/**
|
|
320
|
+
* Trigger a task and subscribe to its updates via realtime. Unlike `triggerAndWait`,
|
|
321
|
+
* this does NOT suspend the parent run — the parent stays alive and subscribes to updates.
|
|
322
|
+
* This enables parallel execution and proper abort signal handling.
|
|
323
|
+
*
|
|
324
|
+
* @param id - The id of the task to trigger
|
|
325
|
+
* @param payload
|
|
326
|
+
* @param options - Options for the task run, including an optional `signal` to cancel the subscription and child run
|
|
327
|
+
* @returns TaskRunPromise
|
|
328
|
+
* @example
|
|
329
|
+
* ```ts
|
|
330
|
+
* import { tasks } from "@trigger.dev/sdk/v3";
|
|
331
|
+
* const result = await tasks.triggerAndSubscribe("my-task", { foo: "bar" });
|
|
332
|
+
*
|
|
333
|
+
* if (result.ok) {
|
|
334
|
+
* console.log(result.output);
|
|
335
|
+
* } else {
|
|
336
|
+
* console.error(result.error);
|
|
337
|
+
* }
|
|
338
|
+
* ```
|
|
339
|
+
*/
|
|
340
|
+
export function triggerAndSubscribe(id, payload, options, requestOptions) {
|
|
341
|
+
return new TaskRunPromise((resolve, reject) => {
|
|
342
|
+
triggerAndSubscribe_internal("tasks.triggerAndSubscribe()", id, payload, undefined, options, requestOptions)
|
|
343
|
+
.then((result) => {
|
|
344
|
+
resolve(result);
|
|
345
|
+
})
|
|
346
|
+
.catch((error) => {
|
|
347
|
+
reject(error);
|
|
348
|
+
});
|
|
349
|
+
}, id);
|
|
350
|
+
}
|
|
220
351
|
/**
|
|
221
352
|
* Batch trigger multiple task runs with the given payloads, and wait for the results. Returns the results of the task runs.
|
|
222
353
|
* @param id - The id of the task to trigger
|
|
@@ -244,597 +375,946 @@ export function triggerAndWait(id, payload, options, requestOptions) {
|
|
|
244
375
|
export async function batchTriggerAndWait(id, items, options, requestOptions) {
|
|
245
376
|
return await batchTriggerAndWait_internal("tasks.batchTriggerAndWait()", id, items, undefined, options, requestOptions);
|
|
246
377
|
}
|
|
247
|
-
/**
|
|
248
|
-
* Trigger a task by its identifier with the given payload and poll until the run is completed.
|
|
249
|
-
*
|
|
250
|
-
* @example
|
|
251
|
-
*
|
|
252
|
-
* ```ts
|
|
253
|
-
* import { tasks, runs } from "@trigger.dev/sdk/v3";
|
|
254
|
-
* import type { myTask } from "./myTasks"; // Import just the type of the task
|
|
255
|
-
*
|
|
256
|
-
* const run = await tasks.triggerAndPoll<typeof myTask>("my-task", { foo: "bar" }); // The id and payload are fully typesafe
|
|
257
|
-
* console.log(run.output) // The output is also fully typed
|
|
258
|
-
* ```
|
|
259
|
-
*
|
|
260
|
-
* @returns {Run} The completed run, either successful or failed.
|
|
261
|
-
*/
|
|
262
|
-
export async function triggerAndPoll(id, payload, options, requestOptions) {
|
|
263
|
-
const handle = await trigger(id, payload, options, requestOptions);
|
|
264
|
-
return runs.poll(handle, options, requestOptions);
|
|
265
|
-
}
|
|
266
378
|
export async function batchTrigger(id, items, options, requestOptions) {
|
|
267
379
|
return await batchTrigger_internal("tasks.batchTrigger()", id, items, options, undefined, requestOptions);
|
|
268
380
|
}
|
|
269
|
-
|
|
270
|
-
|
|
271
|
-
|
|
272
|
-
|
|
273
|
-
|
|
274
|
-
|
|
275
|
-
|
|
276
|
-
|
|
277
|
-
|
|
278
|
-
* @returns {Promise<BatchRunHandleFromTypes<InferRunTypes<TTask>>>} A promise that resolves with the batch run handle
|
|
279
|
-
* containing batch ID, cached status, idempotency info, runs, and public access token
|
|
280
|
-
*
|
|
281
|
-
* @example
|
|
282
|
-
* ```ts
|
|
283
|
-
* import { batch } from "@trigger.dev/sdk/v3";
|
|
284
|
-
* import type { myTask1, myTask2 } from "~/trigger/myTasks";
|
|
285
|
-
*
|
|
286
|
-
* // Trigger multiple tasks with different payloads
|
|
287
|
-
* const result = await batch.trigger<typeof myTask1 | typeof myTask2>([
|
|
288
|
-
* {
|
|
289
|
-
* id: "my-task-1",
|
|
290
|
-
* payload: { some: "data" },
|
|
291
|
-
* options: {
|
|
292
|
-
* queue: "default",
|
|
293
|
-
* concurrencyKey: "key",
|
|
294
|
-
* idempotencyKey: "unique-key",
|
|
295
|
-
* delay: "5m",
|
|
296
|
-
* tags: ["tag1", "tag2"]
|
|
297
|
-
* }
|
|
298
|
-
* },
|
|
299
|
-
* {
|
|
300
|
-
* id: "my-task-2",
|
|
301
|
-
* payload: { other: "data" }
|
|
302
|
-
* }
|
|
303
|
-
* ]);
|
|
304
|
-
* ```
|
|
305
|
-
*
|
|
306
|
-
* @description
|
|
307
|
-
* Each task item in the array can include:
|
|
308
|
-
* - `id`: The unique identifier of the task
|
|
309
|
-
* - `payload`: The data to pass to the task
|
|
310
|
-
* - `options`: Optional task-specific settings including:
|
|
311
|
-
* - `queue`: Specify a queue for the task
|
|
312
|
-
* - `concurrencyKey`: Control concurrent execution
|
|
313
|
-
* - `idempotencyKey`: Prevent duplicate runs
|
|
314
|
-
* - `idempotencyKeyTTL`: Time-to-live for idempotency key
|
|
315
|
-
* - `delay`: Delay before task execution
|
|
316
|
-
* - `ttl`: Time-to-live for the task
|
|
317
|
-
* - `tags`: Array of tags for the task
|
|
318
|
-
* - `maxAttempts`: Maximum retry attempts
|
|
319
|
-
* - `metadata`: Additional metadata
|
|
320
|
-
* - `maxDuration`: Maximum execution duration
|
|
321
|
-
*/
|
|
322
|
-
export async function batchTriggerById(items, options, requestOptions) {
|
|
323
|
-
const apiClient = apiClientManager.clientOrThrow();
|
|
324
|
-
const response = await apiClient.batchTriggerV2({
|
|
325
|
-
items: await Promise.all(items.map(async (item) => {
|
|
326
|
-
const taskMetadata = taskCatalog.getTask(item.id);
|
|
381
|
+
// Implementation
|
|
382
|
+
export async function batchTriggerById(...args) {
|
|
383
|
+
const [items, options, requestOptions] = args;
|
|
384
|
+
const apiClient = apiClientManager.clientOrThrow(requestOptions?.clientConfig);
|
|
385
|
+
// Check if items is an array or a stream
|
|
386
|
+
if (Array.isArray(items)) {
|
|
387
|
+
// Array path: existing logic
|
|
388
|
+
const ndJsonItems = await Promise.all(items.map(async (item, index) => {
|
|
389
|
+
const taskMetadata = resourceCatalog.getTask(item.id);
|
|
327
390
|
const parsedPayload = taskMetadata?.fns.parsePayload
|
|
328
391
|
? await taskMetadata?.fns.parsePayload(item.payload)
|
|
329
392
|
: item.payload;
|
|
330
393
|
const payloadPacket = await stringifyIO(parsedPayload);
|
|
394
|
+
const batchItemIdempotencyKey = await makeIdempotencyKey(flattenIdempotencyKey([options?.idempotencyKey, `${index}`]));
|
|
331
395
|
return {
|
|
396
|
+
index,
|
|
332
397
|
task: item.id,
|
|
333
398
|
payload: payloadPacket.data,
|
|
334
399
|
options: {
|
|
335
|
-
|
|
400
|
+
...triggerQueueBody(item.options?.queue),
|
|
401
|
+
...triggerConcurrencyBody(item.options?.concurrency),
|
|
336
402
|
concurrencyKey: item.options?.concurrencyKey,
|
|
337
403
|
test: taskContext.ctx?.run.isTest,
|
|
338
404
|
payloadType: payloadPacket.dataType,
|
|
339
|
-
idempotencyKey: await makeIdempotencyKey(item.options?.idempotencyKey),
|
|
340
|
-
idempotencyKeyTTL: item.options?.idempotencyKeyTTL,
|
|
341
405
|
delay: item.options?.delay,
|
|
342
406
|
ttl: item.options?.ttl,
|
|
343
407
|
tags: item.options?.tags,
|
|
344
408
|
maxAttempts: item.options?.maxAttempts,
|
|
345
|
-
parentAttempt: taskContext.ctx?.attempt.id,
|
|
346
409
|
metadata: item.options?.metadata,
|
|
347
410
|
maxDuration: item.options?.maxDuration,
|
|
411
|
+
idempotencyKey: (await makeIdempotencyKey(item.options?.idempotencyKey)) ?? batchItemIdempotencyKey,
|
|
412
|
+
idempotencyKeyTTL: item.options?.idempotencyKeyTTL ?? options?.idempotencyKeyTTL,
|
|
348
413
|
machine: item.options?.machine,
|
|
414
|
+
priority: item.options?.priority,
|
|
415
|
+
region: item.options?.region,
|
|
416
|
+
lockToVersion: item.options?.version ?? scopedEnvVar("TRIGGER_VERSION"),
|
|
417
|
+
externalDeploymentId: resolveTriggerExternalDeploymentId(item.options?.externalDeploymentId),
|
|
418
|
+
debounce: item.options?.debounce,
|
|
349
419
|
},
|
|
350
420
|
};
|
|
351
|
-
}))
|
|
352
|
-
|
|
353
|
-
|
|
354
|
-
|
|
355
|
-
|
|
356
|
-
|
|
357
|
-
|
|
358
|
-
|
|
359
|
-
|
|
360
|
-
|
|
361
|
-
|
|
362
|
-
|
|
363
|
-
|
|
364
|
-
|
|
365
|
-
|
|
366
|
-
|
|
367
|
-
|
|
368
|
-
|
|
369
|
-
|
|
370
|
-
|
|
371
|
-
|
|
372
|
-
|
|
373
|
-
|
|
374
|
-
|
|
375
|
-
|
|
376
|
-
|
|
377
|
-
|
|
378
|
-
|
|
379
|
-
|
|
380
|
-
|
|
381
|
-
|
|
382
|
-
|
|
383
|
-
|
|
384
|
-
|
|
385
|
-
|
|
386
|
-
|
|
387
|
-
|
|
388
|
-
|
|
389
|
-
|
|
421
|
+
}));
|
|
422
|
+
// Execute 2-phase batch
|
|
423
|
+
const response = await tracer.startActiveSpan("batch.trigger()", async (span) => {
|
|
424
|
+
const result = await executeBatchTwoPhase(apiClient, ndJsonItems, {
|
|
425
|
+
parentRunId: taskContext.ctx?.run.id,
|
|
426
|
+
idempotencyKey: await makeIdempotencyKey(options?.idempotencyKey),
|
|
427
|
+
spanParentAsLink: true, // Fire-and-forget: child runs get separate trace IDs
|
|
428
|
+
}, requestOptions);
|
|
429
|
+
span.setAttribute("batchId", result.id);
|
|
430
|
+
span.setAttribute("runCount", result.runCount);
|
|
431
|
+
return result;
|
|
432
|
+
}, {
|
|
433
|
+
kind: SpanKind.PRODUCER,
|
|
434
|
+
attributes: {
|
|
435
|
+
[SemanticInternalAttributes.STYLE_ICON]: "trigger",
|
|
436
|
+
},
|
|
437
|
+
});
|
|
438
|
+
const handle = {
|
|
439
|
+
batchId: response.id,
|
|
440
|
+
runCount: response.runCount,
|
|
441
|
+
publicAccessToken: response.publicAccessToken,
|
|
442
|
+
};
|
|
443
|
+
return handle;
|
|
444
|
+
}
|
|
445
|
+
else {
|
|
446
|
+
// Stream path: convert to AsyncIterable and transform
|
|
447
|
+
const asyncItems = normalizeToAsyncIterable(items);
|
|
448
|
+
const transformedItems = transformBatchItemsStream(asyncItems, options);
|
|
449
|
+
// Execute streaming 2-phase batch
|
|
450
|
+
const response = await tracer.startActiveSpan("batch.trigger()", async (span) => {
|
|
451
|
+
const result = await executeBatchTwoPhaseStreaming(apiClient, transformedItems, {
|
|
452
|
+
parentRunId: taskContext.ctx?.run.id,
|
|
453
|
+
idempotencyKey: await makeIdempotencyKey(options?.idempotencyKey),
|
|
454
|
+
spanParentAsLink: true, // Fire-and-forget: child runs get separate trace IDs
|
|
455
|
+
}, requestOptions);
|
|
456
|
+
span.setAttribute("batchId", result.id);
|
|
457
|
+
span.setAttribute("runCount", result.runCount);
|
|
458
|
+
return result;
|
|
459
|
+
}, {
|
|
460
|
+
kind: SpanKind.PRODUCER,
|
|
461
|
+
attributes: {
|
|
462
|
+
[SemanticInternalAttributes.STYLE_ICON]: "trigger",
|
|
463
|
+
},
|
|
464
|
+
});
|
|
465
|
+
const handle = {
|
|
466
|
+
batchId: response.id,
|
|
467
|
+
runCount: response.runCount,
|
|
468
|
+
publicAccessToken: response.publicAccessToken,
|
|
469
|
+
};
|
|
470
|
+
return handle;
|
|
471
|
+
}
|
|
390
472
|
}
|
|
391
|
-
|
|
392
|
-
|
|
393
|
-
|
|
394
|
-
*
|
|
395
|
-
* @template TTask - Union type of tasks to be triggered, extends AnyTask
|
|
396
|
-
*
|
|
397
|
-
* @param {Array<BatchByIdAndWaitItem<InferRunTypes<TTask>>>} items - Array of task items to trigger
|
|
398
|
-
* @param {TriggerApiRequestOptions} [requestOptions] - Optional API request configuration
|
|
399
|
-
*
|
|
400
|
-
* @returns {Promise<BatchByIdResult<TTask>>} A promise that resolves with the batch results, including
|
|
401
|
-
* success/failure status and strongly-typed outputs for each task
|
|
402
|
-
*
|
|
403
|
-
* @throws {Error} If called outside of a task.run() context
|
|
404
|
-
* @throws {Error} If no API client is configured
|
|
405
|
-
*
|
|
406
|
-
* @example
|
|
407
|
-
* ```ts
|
|
408
|
-
* import { batch, task } from "@trigger.dev/sdk/v3";
|
|
409
|
-
*
|
|
410
|
-
* export const parentTask = task({
|
|
411
|
-
* id: "parent-task",
|
|
412
|
-
* run: async (payload: string) => {
|
|
413
|
-
* const results = await batch.triggerAndWait<typeof childTask1 | typeof childTask2>([
|
|
414
|
-
* {
|
|
415
|
-
* id: "child-task-1",
|
|
416
|
-
* payload: { foo: "World" },
|
|
417
|
-
* options: {
|
|
418
|
-
* queue: "default",
|
|
419
|
-
* delay: "5m",
|
|
420
|
-
* tags: ["batch", "child1"]
|
|
421
|
-
* }
|
|
422
|
-
* },
|
|
423
|
-
* {
|
|
424
|
-
* id: "child-task-2",
|
|
425
|
-
* payload: { bar: 42 }
|
|
426
|
-
* }
|
|
427
|
-
* ]);
|
|
428
|
-
*
|
|
429
|
-
* // Type-safe result handling
|
|
430
|
-
* for (const result of results) {
|
|
431
|
-
* if (result.ok) {
|
|
432
|
-
* switch (result.taskIdentifier) {
|
|
433
|
-
* case "child-task-1":
|
|
434
|
-
* console.log("Child task 1 output:", result.output); // string type
|
|
435
|
-
* break;
|
|
436
|
-
* case "child-task-2":
|
|
437
|
-
* console.log("Child task 2 output:", result.output); // number type
|
|
438
|
-
* break;
|
|
439
|
-
* }
|
|
440
|
-
* } else {
|
|
441
|
-
* console.error("Task failed:", result.error);
|
|
442
|
-
* }
|
|
443
|
-
* }
|
|
444
|
-
* }
|
|
445
|
-
* });
|
|
446
|
-
* ```
|
|
447
|
-
*
|
|
448
|
-
* @description
|
|
449
|
-
* Each task item in the array can include:
|
|
450
|
-
* - `id`: The task identifier (must match one of the tasks in the union type)
|
|
451
|
-
* - `payload`: Strongly-typed payload matching the task's input type
|
|
452
|
-
* - `options`: Optional task-specific settings including:
|
|
453
|
-
* - `queue`: Specify a queue for the task
|
|
454
|
-
* - `concurrencyKey`: Control concurrent execution
|
|
455
|
-
* - `delay`: Delay before task execution
|
|
456
|
-
* - `ttl`: Time-to-live for the task
|
|
457
|
-
* - `tags`: Array of tags for the task
|
|
458
|
-
* - `maxAttempts`: Maximum retry attempts
|
|
459
|
-
* - `metadata`: Additional metadata
|
|
460
|
-
* - `maxDuration`: Maximum execution duration
|
|
461
|
-
*
|
|
462
|
-
* The function provides full type safety for:
|
|
463
|
-
* - Task IDs
|
|
464
|
-
* - Payload types
|
|
465
|
-
* - Return value types
|
|
466
|
-
* - Error handling
|
|
467
|
-
*/
|
|
468
|
-
export async function batchTriggerByIdAndWait(items, options, requestOptions) {
|
|
473
|
+
// Implementation
|
|
474
|
+
export async function batchTriggerByIdAndWait(...args) {
|
|
475
|
+
const [items, options, requestOptions] = args;
|
|
469
476
|
const ctx = taskContext.ctx;
|
|
470
477
|
if (!ctx) {
|
|
471
478
|
throw new Error("batchTriggerAndWait can only be used from inside a task.run()");
|
|
472
479
|
}
|
|
473
|
-
const apiClient = apiClientManager.clientOrThrow();
|
|
474
|
-
|
|
475
|
-
|
|
476
|
-
|
|
477
|
-
|
|
478
|
-
|
|
479
|
-
|
|
480
|
-
|
|
481
|
-
|
|
482
|
-
|
|
483
|
-
|
|
484
|
-
|
|
485
|
-
|
|
486
|
-
|
|
487
|
-
|
|
488
|
-
|
|
489
|
-
|
|
490
|
-
|
|
491
|
-
|
|
492
|
-
|
|
493
|
-
|
|
494
|
-
|
|
495
|
-
|
|
496
|
-
|
|
497
|
-
|
|
498
|
-
|
|
499
|
-
|
|
500
|
-
|
|
501
|
-
|
|
480
|
+
const apiClient = apiClientManager.clientOrThrow(requestOptions?.clientConfig);
|
|
481
|
+
// Check if items is an array or a stream
|
|
482
|
+
if (Array.isArray(items)) {
|
|
483
|
+
// Array path: existing logic
|
|
484
|
+
const ndJsonItems = await Promise.all(items.map(async (item, index) => {
|
|
485
|
+
const taskMetadata = resourceCatalog.getTask(item.id);
|
|
486
|
+
const parsedPayload = taskMetadata?.fns.parsePayload
|
|
487
|
+
? await taskMetadata?.fns.parsePayload(item.payload)
|
|
488
|
+
: item.payload;
|
|
489
|
+
const payloadPacket = await stringifyIO(parsedPayload);
|
|
490
|
+
const batchItemIdempotencyKey = await makeIdempotencyKey(flattenIdempotencyKey([options?.idempotencyKey, `${index}`]));
|
|
491
|
+
return {
|
|
492
|
+
index,
|
|
493
|
+
task: item.id,
|
|
494
|
+
payload: payloadPacket.data,
|
|
495
|
+
options: {
|
|
496
|
+
lockToVersion: taskContext.worker?.version,
|
|
497
|
+
...triggerQueueBody(item.options?.queue),
|
|
498
|
+
...triggerConcurrencyBody(item.options?.concurrency),
|
|
499
|
+
concurrencyKey: item.options?.concurrencyKey,
|
|
500
|
+
test: taskContext.ctx?.run.isTest,
|
|
501
|
+
payloadType: payloadPacket.dataType,
|
|
502
|
+
delay: item.options?.delay,
|
|
503
|
+
ttl: item.options?.ttl,
|
|
504
|
+
tags: item.options?.tags,
|
|
505
|
+
maxAttempts: item.options?.maxAttempts,
|
|
506
|
+
metadata: item.options?.metadata,
|
|
507
|
+
maxDuration: item.options?.maxDuration,
|
|
508
|
+
idempotencyKey: (await makeIdempotencyKey(item.options?.idempotencyKey)) ?? batchItemIdempotencyKey,
|
|
509
|
+
idempotencyKeyTTL: item.options?.idempotencyKeyTTL ?? options?.idempotencyKeyTTL,
|
|
510
|
+
machine: item.options?.machine,
|
|
511
|
+
priority: item.options?.priority,
|
|
512
|
+
region: item.options?.region,
|
|
513
|
+
debounce: item.options?.debounce,
|
|
514
|
+
},
|
|
515
|
+
};
|
|
516
|
+
}));
|
|
517
|
+
return await tracer.startActiveSpan("batch.triggerAndWait()", async (span) => {
|
|
518
|
+
// Execute 2-phase batch
|
|
519
|
+
const response = await executeBatchTwoPhase(apiClient, ndJsonItems, {
|
|
520
|
+
parentRunId: ctx.run.id,
|
|
521
|
+
resumeParentOnCompletion: true,
|
|
522
|
+
idempotencyKey: await makeIdempotencyKey(options?.idempotencyKey),
|
|
523
|
+
spanParentAsLink: false, // Waiting: child runs share parent's trace ID
|
|
524
|
+
}, requestOptions);
|
|
525
|
+
span.setAttribute("batchId", response.id);
|
|
526
|
+
span.setAttribute("runCount", response.runCount);
|
|
527
|
+
const result = await runtime.waitForBatch({
|
|
528
|
+
id: response.id,
|
|
529
|
+
runCount: response.runCount,
|
|
530
|
+
ctx,
|
|
531
|
+
});
|
|
532
|
+
const runs = await handleBatchTaskRunExecutionResultV2(result.items, response.taskIdentifiers);
|
|
533
|
+
return {
|
|
534
|
+
id: result.id,
|
|
535
|
+
runs,
|
|
536
|
+
};
|
|
502
537
|
}, {
|
|
503
|
-
|
|
504
|
-
|
|
505
|
-
|
|
506
|
-
|
|
507
|
-
span.setAttribute("isCached", response.isCached);
|
|
508
|
-
if (response.isCached) {
|
|
509
|
-
console.warn(`Result is a cached response because the request was idempotent.`);
|
|
510
|
-
}
|
|
511
|
-
if (response.idempotencyKey) {
|
|
512
|
-
span.setAttribute("idempotencyKey", response.idempotencyKey);
|
|
513
|
-
}
|
|
514
|
-
const result = await runtime.waitForBatch({
|
|
515
|
-
id: response.id,
|
|
516
|
-
runs: response.runs.map((run) => run.id),
|
|
517
|
-
ctx,
|
|
538
|
+
kind: SpanKind.PRODUCER,
|
|
539
|
+
attributes: {
|
|
540
|
+
[SemanticInternalAttributes.STYLE_ICON]: "trigger",
|
|
541
|
+
},
|
|
518
542
|
});
|
|
519
|
-
|
|
520
|
-
|
|
521
|
-
|
|
522
|
-
|
|
523
|
-
|
|
524
|
-
|
|
525
|
-
|
|
526
|
-
|
|
527
|
-
|
|
528
|
-
|
|
529
|
-
|
|
543
|
+
}
|
|
544
|
+
else {
|
|
545
|
+
// Stream path: convert to AsyncIterable and transform
|
|
546
|
+
const asyncItems = normalizeToAsyncIterable(items);
|
|
547
|
+
const transformedItems = transformBatchItemsStreamForWait(asyncItems, options);
|
|
548
|
+
return await tracer.startActiveSpan("batch.triggerAndWait()", async (span) => {
|
|
549
|
+
// Execute streaming 2-phase batch
|
|
550
|
+
const response = await executeBatchTwoPhaseStreaming(apiClient, transformedItems, {
|
|
551
|
+
parentRunId: ctx.run.id,
|
|
552
|
+
resumeParentOnCompletion: true,
|
|
553
|
+
idempotencyKey: await makeIdempotencyKey(options?.idempotencyKey),
|
|
554
|
+
spanParentAsLink: false, // Waiting: child runs share parent's trace ID
|
|
555
|
+
}, requestOptions);
|
|
556
|
+
span.setAttribute("batchId", response.id);
|
|
557
|
+
span.setAttribute("runCount", response.runCount);
|
|
558
|
+
const result = await runtime.waitForBatch({
|
|
559
|
+
id: response.id,
|
|
560
|
+
runCount: response.runCount,
|
|
561
|
+
ctx,
|
|
562
|
+
});
|
|
563
|
+
const runs = await handleBatchTaskRunExecutionResultV2(result.items, response.taskIdentifiers);
|
|
564
|
+
return {
|
|
565
|
+
id: result.id,
|
|
566
|
+
runs,
|
|
567
|
+
};
|
|
568
|
+
}, {
|
|
569
|
+
kind: SpanKind.PRODUCER,
|
|
570
|
+
attributes: {
|
|
571
|
+
[SemanticInternalAttributes.STYLE_ICON]: "trigger",
|
|
572
|
+
},
|
|
573
|
+
});
|
|
574
|
+
}
|
|
530
575
|
}
|
|
531
|
-
|
|
532
|
-
|
|
533
|
-
|
|
534
|
-
|
|
535
|
-
|
|
536
|
-
|
|
537
|
-
|
|
538
|
-
|
|
539
|
-
|
|
540
|
-
* @returns {Promise<BatchByIdResult<TTask>>} A promise that resolves with the batch results, including
|
|
541
|
-
* success/failure status and strongly-typed outputs for each task
|
|
542
|
-
*
|
|
543
|
-
* @throws {Error} If called outside of a task.run() context
|
|
544
|
-
* @throws {Error} If no API client is configured
|
|
545
|
-
*
|
|
546
|
-
* @example
|
|
547
|
-
* ```ts
|
|
548
|
-
* import { batch, task } from "@trigger.dev/sdk/v3";
|
|
549
|
-
*
|
|
550
|
-
* export const parentTask = task({
|
|
551
|
-
* id: "parent-task",
|
|
552
|
-
* run: async (payload: string) => {
|
|
553
|
-
* const results = await batch.triggerAndWait<typeof childTask1 | typeof childTask2>([
|
|
554
|
-
* {
|
|
555
|
-
* id: "child-task-1",
|
|
556
|
-
* payload: { foo: "World" },
|
|
557
|
-
* options: {
|
|
558
|
-
* queue: "default",
|
|
559
|
-
* delay: "5m",
|
|
560
|
-
* tags: ["batch", "child1"]
|
|
561
|
-
* }
|
|
562
|
-
* },
|
|
563
|
-
* {
|
|
564
|
-
* id: "child-task-2",
|
|
565
|
-
* payload: { bar: 42 }
|
|
566
|
-
* }
|
|
567
|
-
* ]);
|
|
568
|
-
*
|
|
569
|
-
* // Type-safe result handling
|
|
570
|
-
* for (const result of results) {
|
|
571
|
-
* if (result.ok) {
|
|
572
|
-
* switch (result.taskIdentifier) {
|
|
573
|
-
* case "child-task-1":
|
|
574
|
-
* console.log("Child task 1 output:", result.output); // string type
|
|
575
|
-
* break;
|
|
576
|
-
* case "child-task-2":
|
|
577
|
-
* console.log("Child task 2 output:", result.output); // number type
|
|
578
|
-
* break;
|
|
579
|
-
* }
|
|
580
|
-
* } else {
|
|
581
|
-
* console.error("Task failed:", result.error);
|
|
582
|
-
* }
|
|
583
|
-
* }
|
|
584
|
-
* }
|
|
585
|
-
* });
|
|
586
|
-
* ```
|
|
587
|
-
*
|
|
588
|
-
* @description
|
|
589
|
-
* Each task item in the array can include:
|
|
590
|
-
* - `id`: The task identifier (must match one of the tasks in the union type)
|
|
591
|
-
* - `payload`: Strongly-typed payload matching the task's input type
|
|
592
|
-
* - `options`: Optional task-specific settings including:
|
|
593
|
-
* - `queue`: Specify a queue for the task
|
|
594
|
-
* - `concurrencyKey`: Control concurrent execution
|
|
595
|
-
* - `delay`: Delay before task execution
|
|
596
|
-
* - `ttl`: Time-to-live for the task
|
|
597
|
-
* - `tags`: Array of tags for the task
|
|
598
|
-
* - `maxAttempts`: Maximum retry attempts
|
|
599
|
-
* - `metadata`: Additional metadata
|
|
600
|
-
* - `maxDuration`: Maximum execution duration
|
|
601
|
-
*
|
|
602
|
-
* The function provides full type safety for:
|
|
603
|
-
* - Task IDs
|
|
604
|
-
* - Payload types
|
|
605
|
-
* - Return value types
|
|
606
|
-
* - Error handling
|
|
607
|
-
*/
|
|
608
|
-
export async function batchTriggerTasks(items, options, requestOptions) {
|
|
609
|
-
const apiClient = apiClientManager.clientOrThrow();
|
|
610
|
-
const response = await apiClient.batchTriggerV2({
|
|
611
|
-
items: await Promise.all(items.map(async (item) => {
|
|
612
|
-
const taskMetadata = taskCatalog.getTask(item.task.id);
|
|
576
|
+
// Implementation
|
|
577
|
+
export async function batchTriggerTasks(...args) {
|
|
578
|
+
const [items, options, requestOptions] = args;
|
|
579
|
+
const apiClient = apiClientManager.clientOrThrow(requestOptions?.clientConfig);
|
|
580
|
+
// Check if items is an array or a stream
|
|
581
|
+
if (Array.isArray(items)) {
|
|
582
|
+
// Array path: existing logic
|
|
583
|
+
const ndJsonItems = await Promise.all(items.map(async (item, index) => {
|
|
584
|
+
const taskMetadata = resourceCatalog.getTask(item.task.id);
|
|
613
585
|
const parsedPayload = taskMetadata?.fns.parsePayload
|
|
614
586
|
? await taskMetadata?.fns.parsePayload(item.payload)
|
|
615
587
|
: item.payload;
|
|
616
588
|
const payloadPacket = await stringifyIO(parsedPayload);
|
|
589
|
+
const batchItemIdempotencyKey = await makeIdempotencyKey(flattenIdempotencyKey([options?.idempotencyKey, `${index}`]));
|
|
617
590
|
return {
|
|
591
|
+
index,
|
|
618
592
|
task: item.task.id,
|
|
619
593
|
payload: payloadPacket.data,
|
|
620
594
|
options: {
|
|
621
|
-
|
|
595
|
+
...triggerQueueBody(item.options?.queue),
|
|
596
|
+
...triggerConcurrencyBody(item.options?.concurrency),
|
|
622
597
|
concurrencyKey: item.options?.concurrencyKey,
|
|
623
598
|
test: taskContext.ctx?.run.isTest,
|
|
624
599
|
payloadType: payloadPacket.dataType,
|
|
625
|
-
idempotencyKey: await makeIdempotencyKey(item.options?.idempotencyKey),
|
|
626
|
-
idempotencyKeyTTL: item.options?.idempotencyKeyTTL,
|
|
627
600
|
delay: item.options?.delay,
|
|
628
601
|
ttl: item.options?.ttl,
|
|
629
602
|
tags: item.options?.tags,
|
|
630
603
|
maxAttempts: item.options?.maxAttempts,
|
|
631
|
-
parentAttempt: taskContext.ctx?.attempt.id,
|
|
632
604
|
metadata: item.options?.metadata,
|
|
633
605
|
maxDuration: item.options?.maxDuration,
|
|
606
|
+
idempotencyKey: (await makeIdempotencyKey(item.options?.idempotencyKey)) ?? batchItemIdempotencyKey,
|
|
607
|
+
idempotencyKeyTTL: item.options?.idempotencyKeyTTL ?? options?.idempotencyKeyTTL,
|
|
634
608
|
machine: item.options?.machine,
|
|
609
|
+
priority: item.options?.priority,
|
|
610
|
+
region: item.options?.region,
|
|
611
|
+
lockToVersion: item.options?.version ?? scopedEnvVar("TRIGGER_VERSION"),
|
|
612
|
+
externalDeploymentId: resolveTriggerExternalDeploymentId(item.options?.externalDeploymentId),
|
|
613
|
+
debounce: item.options?.debounce,
|
|
635
614
|
},
|
|
636
615
|
};
|
|
637
|
-
}))
|
|
638
|
-
|
|
639
|
-
|
|
640
|
-
|
|
641
|
-
|
|
642
|
-
|
|
643
|
-
|
|
644
|
-
|
|
645
|
-
|
|
646
|
-
|
|
647
|
-
|
|
648
|
-
|
|
649
|
-
|
|
650
|
-
|
|
651
|
-
|
|
652
|
-
|
|
653
|
-
|
|
654
|
-
|
|
655
|
-
|
|
656
|
-
|
|
657
|
-
|
|
658
|
-
|
|
659
|
-
|
|
660
|
-
|
|
661
|
-
|
|
662
|
-
|
|
663
|
-
|
|
664
|
-
|
|
665
|
-
|
|
666
|
-
|
|
667
|
-
|
|
668
|
-
|
|
669
|
-
|
|
670
|
-
|
|
671
|
-
|
|
672
|
-
|
|
673
|
-
|
|
674
|
-
|
|
675
|
-
|
|
616
|
+
}));
|
|
617
|
+
// Execute 2-phase batch
|
|
618
|
+
const response = await tracer.startActiveSpan("batch.triggerByTask()", async (span) => {
|
|
619
|
+
const result = await executeBatchTwoPhase(apiClient, ndJsonItems, {
|
|
620
|
+
parentRunId: taskContext.ctx?.run.id,
|
|
621
|
+
idempotencyKey: await makeIdempotencyKey(options?.idempotencyKey),
|
|
622
|
+
spanParentAsLink: true, // Fire-and-forget: child runs get separate trace IDs
|
|
623
|
+
}, requestOptions);
|
|
624
|
+
span.setAttribute("batchId", result.id);
|
|
625
|
+
span.setAttribute("runCount", result.runCount);
|
|
626
|
+
return result;
|
|
627
|
+
}, {
|
|
628
|
+
kind: SpanKind.PRODUCER,
|
|
629
|
+
attributes: {
|
|
630
|
+
[SemanticInternalAttributes.STYLE_ICON]: "trigger",
|
|
631
|
+
},
|
|
632
|
+
});
|
|
633
|
+
const handle = {
|
|
634
|
+
batchId: response.id,
|
|
635
|
+
runCount: response.runCount,
|
|
636
|
+
publicAccessToken: response.publicAccessToken,
|
|
637
|
+
};
|
|
638
|
+
return handle;
|
|
639
|
+
}
|
|
640
|
+
else {
|
|
641
|
+
// Stream path: convert to AsyncIterable and transform
|
|
642
|
+
const streamItems = items;
|
|
643
|
+
const asyncItems = normalizeToAsyncIterable(streamItems);
|
|
644
|
+
const transformedItems = transformBatchByTaskItemsStream(asyncItems, options);
|
|
645
|
+
// Execute streaming 2-phase batch
|
|
646
|
+
const response = await tracer.startActiveSpan("batch.triggerByTask()", async (span) => {
|
|
647
|
+
const result = await executeBatchTwoPhaseStreaming(apiClient, transformedItems, {
|
|
648
|
+
parentRunId: taskContext.ctx?.run.id,
|
|
649
|
+
idempotencyKey: await makeIdempotencyKey(options?.idempotencyKey),
|
|
650
|
+
spanParentAsLink: true, // Fire-and-forget: child runs get separate trace IDs
|
|
651
|
+
}, requestOptions);
|
|
652
|
+
span.setAttribute("batchId", result.id);
|
|
653
|
+
span.setAttribute("runCount", result.runCount);
|
|
654
|
+
return result;
|
|
655
|
+
}, {
|
|
656
|
+
kind: SpanKind.PRODUCER,
|
|
657
|
+
attributes: {
|
|
658
|
+
[SemanticInternalAttributes.STYLE_ICON]: "trigger",
|
|
659
|
+
},
|
|
660
|
+
});
|
|
661
|
+
const handle = {
|
|
662
|
+
batchId: response.id,
|
|
663
|
+
runCount: response.runCount,
|
|
664
|
+
publicAccessToken: response.publicAccessToken,
|
|
665
|
+
};
|
|
666
|
+
return handle;
|
|
667
|
+
}
|
|
676
668
|
}
|
|
677
|
-
|
|
678
|
-
|
|
679
|
-
|
|
680
|
-
|
|
681
|
-
|
|
682
|
-
|
|
683
|
-
|
|
684
|
-
|
|
685
|
-
|
|
686
|
-
|
|
687
|
-
|
|
688
|
-
|
|
689
|
-
|
|
690
|
-
|
|
691
|
-
|
|
692
|
-
|
|
693
|
-
|
|
694
|
-
|
|
669
|
+
// Implementation
|
|
670
|
+
export async function batchTriggerAndWaitTasks(...args) {
|
|
671
|
+
const [items, options, requestOptions] = args;
|
|
672
|
+
const ctx = taskContext.ctx;
|
|
673
|
+
if (!ctx) {
|
|
674
|
+
throw new Error("batchTriggerAndWait can only be used from inside a task.run()");
|
|
675
|
+
}
|
|
676
|
+
const apiClient = apiClientManager.clientOrThrow(requestOptions?.clientConfig);
|
|
677
|
+
// Check if items is an array or a stream
|
|
678
|
+
if (Array.isArray(items)) {
|
|
679
|
+
// Array path: existing logic
|
|
680
|
+
const ndJsonItems = await Promise.all(items.map(async (item, index) => {
|
|
681
|
+
const taskMetadata = resourceCatalog.getTask(item.task.id);
|
|
682
|
+
const parsedPayload = taskMetadata?.fns.parsePayload
|
|
683
|
+
? await taskMetadata?.fns.parsePayload(item.payload)
|
|
684
|
+
: item.payload;
|
|
685
|
+
const payloadPacket = await stringifyIO(parsedPayload);
|
|
686
|
+
const batchItemIdempotencyKey = await makeIdempotencyKey(flattenIdempotencyKey([options?.idempotencyKey, `${index}`]));
|
|
687
|
+
return {
|
|
688
|
+
index,
|
|
689
|
+
task: item.task.id,
|
|
690
|
+
payload: payloadPacket.data,
|
|
691
|
+
options: {
|
|
692
|
+
lockToVersion: taskContext.worker?.version,
|
|
693
|
+
...triggerQueueBody(item.options?.queue),
|
|
694
|
+
...triggerConcurrencyBody(item.options?.concurrency),
|
|
695
|
+
concurrencyKey: item.options?.concurrencyKey,
|
|
696
|
+
test: taskContext.ctx?.run.isTest,
|
|
697
|
+
payloadType: payloadPacket.dataType,
|
|
698
|
+
delay: item.options?.delay,
|
|
699
|
+
ttl: item.options?.ttl,
|
|
700
|
+
tags: item.options?.tags,
|
|
701
|
+
maxAttempts: item.options?.maxAttempts,
|
|
702
|
+
metadata: item.options?.metadata,
|
|
703
|
+
maxDuration: item.options?.maxDuration,
|
|
704
|
+
idempotencyKey: (await makeIdempotencyKey(item.options?.idempotencyKey)) ?? batchItemIdempotencyKey,
|
|
705
|
+
idempotencyKeyTTL: item.options?.idempotencyKeyTTL ?? options?.idempotencyKeyTTL,
|
|
706
|
+
machine: item.options?.machine,
|
|
707
|
+
priority: item.options?.priority,
|
|
708
|
+
region: item.options?.region,
|
|
709
|
+
debounce: item.options?.debounce,
|
|
710
|
+
},
|
|
711
|
+
};
|
|
712
|
+
}));
|
|
713
|
+
return await tracer.startActiveSpan("batch.triggerByTaskAndWait()", async (span) => {
|
|
714
|
+
// Execute 2-phase batch
|
|
715
|
+
const response = await executeBatchTwoPhase(apiClient, ndJsonItems, {
|
|
716
|
+
parentRunId: ctx.run.id,
|
|
717
|
+
resumeParentOnCompletion: true,
|
|
718
|
+
idempotencyKey: await makeIdempotencyKey(options?.idempotencyKey),
|
|
719
|
+
spanParentAsLink: false, // Waiting: child runs share parent's trace ID
|
|
720
|
+
}, requestOptions);
|
|
721
|
+
span.setAttribute("batchId", response.id);
|
|
722
|
+
span.setAttribute("runCount", response.runCount);
|
|
723
|
+
const result = await runtime.waitForBatch({
|
|
724
|
+
id: response.id,
|
|
725
|
+
runCount: response.runCount,
|
|
726
|
+
ctx,
|
|
727
|
+
});
|
|
728
|
+
const runs = await handleBatchTaskRunExecutionResultV2(result.items, response.taskIdentifiers);
|
|
729
|
+
return {
|
|
730
|
+
id: result.id,
|
|
731
|
+
runs,
|
|
732
|
+
};
|
|
733
|
+
}, {
|
|
734
|
+
kind: SpanKind.PRODUCER,
|
|
735
|
+
attributes: {
|
|
736
|
+
[SemanticInternalAttributes.STYLE_ICON]: "trigger",
|
|
737
|
+
},
|
|
738
|
+
});
|
|
739
|
+
}
|
|
740
|
+
else {
|
|
741
|
+
// Stream path: convert to AsyncIterable and transform
|
|
742
|
+
const streamItems = items;
|
|
743
|
+
const asyncItems = normalizeToAsyncIterable(streamItems);
|
|
744
|
+
const transformedItems = transformBatchByTaskItemsStreamForWait(asyncItems, options);
|
|
745
|
+
return await tracer.startActiveSpan("batch.triggerByTaskAndWait()", async (span) => {
|
|
746
|
+
// Execute streaming 2-phase batch
|
|
747
|
+
const response = await executeBatchTwoPhaseStreaming(apiClient, transformedItems, {
|
|
748
|
+
parentRunId: ctx.run.id,
|
|
749
|
+
resumeParentOnCompletion: true,
|
|
750
|
+
idempotencyKey: await makeIdempotencyKey(options?.idempotencyKey),
|
|
751
|
+
spanParentAsLink: false, // Waiting: child runs share parent's trace ID
|
|
752
|
+
}, requestOptions);
|
|
753
|
+
span.setAttribute("batchId", response.id);
|
|
754
|
+
span.setAttribute("runCount", response.runCount);
|
|
755
|
+
const result = await runtime.waitForBatch({
|
|
756
|
+
id: response.id,
|
|
757
|
+
runCount: response.runCount,
|
|
758
|
+
ctx,
|
|
759
|
+
});
|
|
760
|
+
const runs = await handleBatchTaskRunExecutionResultV2(result.items, response.taskIdentifiers);
|
|
761
|
+
return {
|
|
762
|
+
id: result.id,
|
|
763
|
+
runs,
|
|
764
|
+
};
|
|
765
|
+
}, {
|
|
766
|
+
kind: SpanKind.PRODUCER,
|
|
767
|
+
attributes: {
|
|
768
|
+
[SemanticInternalAttributes.STYLE_ICON]: "trigger",
|
|
769
|
+
},
|
|
770
|
+
});
|
|
771
|
+
}
|
|
772
|
+
}
|
|
773
|
+
export function uniqueBatchTaskIdentifiers(items) {
|
|
774
|
+
return Array.from(new Set(items.map((item) => item.task))).sort();
|
|
775
|
+
}
|
|
776
|
+
/**
|
|
777
|
+
* Helper function that executes a 2-phase batch trigger:
|
|
778
|
+
* 1. Creates the batch record with expected run count
|
|
779
|
+
* 2. Streams items as NDJSON to the server
|
|
695
780
|
*
|
|
696
|
-
*
|
|
697
|
-
*
|
|
698
|
-
*
|
|
699
|
-
*
|
|
700
|
-
*
|
|
701
|
-
*
|
|
702
|
-
*
|
|
703
|
-
|
|
704
|
-
|
|
705
|
-
|
|
706
|
-
|
|
707
|
-
|
|
708
|
-
|
|
709
|
-
|
|
710
|
-
|
|
711
|
-
|
|
712
|
-
|
|
713
|
-
|
|
781
|
+
* @param apiClient - The API client instance
|
|
782
|
+
* @param items - Array of batch items
|
|
783
|
+
* @param options - Batch options including trace context settings
|
|
784
|
+
* @param options.spanParentAsLink - If true, child runs will have separate trace IDs with a link to parent.
|
|
785
|
+
* Use true for batchTrigger (fire-and-forget), false for batchTriggerAndWait.
|
|
786
|
+
* @param requestOptions - Optional request options
|
|
787
|
+
* @internal
|
|
788
|
+
*/
|
|
789
|
+
async function executeBatchTwoPhase(apiClient, items, options, requestOptions) {
|
|
790
|
+
// Offload any oversized per-item payloads to object storage before streaming, so a batch
|
|
791
|
+
// of large items keeps the request body small — the same treatment single triggers get.
|
|
792
|
+
// Both the array and streaming batch paths funnel through here, so this is the one place
|
|
793
|
+
// batch offloading needs to happen. Wrap failures so a presign/upload error carries the
|
|
794
|
+
// same batch context (phase, itemCount, rate-limit info) as the create/stream phases.
|
|
795
|
+
try {
|
|
796
|
+
items = await offloadBatchItemPayloads(items, apiClient);
|
|
797
|
+
}
|
|
798
|
+
catch (error) {
|
|
799
|
+
throw new BatchTriggerError(`Failed to offload payloads for batch with ${items.length} items`, {
|
|
800
|
+
cause: error,
|
|
801
|
+
phase: "offload",
|
|
802
|
+
itemCount: items.length,
|
|
803
|
+
});
|
|
804
|
+
}
|
|
805
|
+
let batch;
|
|
806
|
+
try {
|
|
807
|
+
// Phase 1: Create batch
|
|
808
|
+
batch = await apiClient.createBatch({
|
|
809
|
+
runCount: items.length,
|
|
810
|
+
taskIdentifiers: uniqueBatchTaskIdentifiers(items),
|
|
811
|
+
parentRunId: options.parentRunId,
|
|
812
|
+
resumeParentOnCompletion: options.resumeParentOnCompletion,
|
|
813
|
+
idempotencyKey: options.idempotencyKey,
|
|
814
|
+
idempotencyKeyOptions: options.idempotencyKeyOptions,
|
|
815
|
+
}, { spanParentAsLink: options.spanParentAsLink }, requestOptions);
|
|
816
|
+
}
|
|
817
|
+
catch (error) {
|
|
818
|
+
// Wrap with context about which phase failed
|
|
819
|
+
throw new BatchTriggerError(`Failed to create batch with ${items.length} items`, {
|
|
820
|
+
cause: error,
|
|
821
|
+
phase: "create",
|
|
822
|
+
itemCount: items.length,
|
|
823
|
+
});
|
|
824
|
+
}
|
|
825
|
+
// If the batch was cached (idempotent replay), skip streaming items
|
|
826
|
+
if (!batch.isCached) {
|
|
827
|
+
try {
|
|
828
|
+
// Phase 2: Stream items
|
|
829
|
+
await apiClient.streamBatchItems(batch.id, items, requestOptions);
|
|
830
|
+
}
|
|
831
|
+
catch (error) {
|
|
832
|
+
// Wrap with context about which phase failed and include batch ID
|
|
833
|
+
throw new BatchTriggerError(`Failed to stream items for batch ${batch.id} (${items.length} items)`, { cause: error, phase: "stream", batchId: batch.id, itemCount: items.length });
|
|
834
|
+
}
|
|
835
|
+
}
|
|
836
|
+
return {
|
|
837
|
+
id: batch.id,
|
|
838
|
+
runCount: batch.runCount,
|
|
839
|
+
publicAccessToken: batch.publicAccessToken,
|
|
840
|
+
taskIdentifiers: items.map((item) => item.task),
|
|
841
|
+
};
|
|
842
|
+
}
|
|
843
|
+
/**
|
|
844
|
+
* Offload any oversized per-item payloads in a batch to object storage, mirroring the
|
|
845
|
+
* single-trigger offload path. Small payloads pass through untouched. Every returned item
|
|
846
|
+
* carries `options.payloadSize` (the pre-offload serialized byte size) so the pipeline can
|
|
847
|
+
* reason about payload size without downloading an "application/store" reference.
|
|
714
848
|
*
|
|
715
|
-
*
|
|
716
|
-
*
|
|
717
|
-
* if (result.ok) {
|
|
718
|
-
* switch (result.taskIdentifier) {
|
|
719
|
-
* case "child-task-1":
|
|
720
|
-
* console.log("Child task 1 output:", result.output); // string type
|
|
721
|
-
* break;
|
|
722
|
-
* case "child-task-2":
|
|
723
|
-
* console.log("Child task 2 output:", result.output); // number type
|
|
724
|
-
* break;
|
|
725
|
-
* }
|
|
726
|
-
* } else {
|
|
727
|
-
* console.error("Task failed:", result.error);
|
|
728
|
-
* }
|
|
729
|
-
* }
|
|
730
|
-
* }
|
|
731
|
-
* });
|
|
732
|
-
* ```
|
|
849
|
+
* Uploads run with bounded concurrency so a batch of large items doesn't fire an unbounded
|
|
850
|
+
* number of simultaneous presigned PUTs.
|
|
733
851
|
*
|
|
734
|
-
* @
|
|
735
|
-
|
|
736
|
-
|
|
737
|
-
|
|
738
|
-
|
|
739
|
-
|
|
740
|
-
|
|
741
|
-
|
|
742
|
-
|
|
743
|
-
|
|
744
|
-
|
|
745
|
-
|
|
746
|
-
|
|
852
|
+
* @internal Exported for testing.
|
|
853
|
+
*/
|
|
854
|
+
export async function offloadBatchItemPayloads(items, apiClient, concurrency = 10) {
|
|
855
|
+
if (items.length === 0) {
|
|
856
|
+
return items;
|
|
857
|
+
}
|
|
858
|
+
const results = new Array(items.length);
|
|
859
|
+
let cursor = 0;
|
|
860
|
+
async function worker() {
|
|
861
|
+
while (cursor < items.length) {
|
|
862
|
+
const index = cursor++;
|
|
863
|
+
results[index] = await offloadBatchItemPayload(items[index], apiClient);
|
|
864
|
+
}
|
|
865
|
+
}
|
|
866
|
+
await Promise.all(Array.from({ length: Math.min(concurrency, items.length) }, () => worker()));
|
|
867
|
+
return results;
|
|
868
|
+
}
|
|
869
|
+
async function offloadBatchItemPayload(item, apiClient) {
|
|
870
|
+
// The batch builders serialize each payload to a string via stringifyIO before we get
|
|
871
|
+
// here; anything else has no inline body to offload or measure.
|
|
872
|
+
if (typeof item.payload !== "string" || item.payload.length === 0) {
|
|
873
|
+
return item;
|
|
874
|
+
}
|
|
875
|
+
const dataType = item.options?.payloadType ?? "application/json";
|
|
876
|
+
// Already an object-store reference — the caller pre-offloaded it, nothing to do.
|
|
877
|
+
if (dataType === "application/store") {
|
|
878
|
+
return item;
|
|
879
|
+
}
|
|
880
|
+
const packet = { data: item.payload, dataType };
|
|
881
|
+
// Measure before offload so the size reflects the real payload, not the small reference
|
|
882
|
+
// we may replace it with.
|
|
883
|
+
const { size: payloadSize } = packetRequiresOffloading(packet);
|
|
884
|
+
const exported = await conditionallyExportPacket(packet, createTriggerPayloadPathPrefix(), undefined, apiClient);
|
|
885
|
+
return {
|
|
886
|
+
...item,
|
|
887
|
+
payload: exported.data,
|
|
888
|
+
options: {
|
|
889
|
+
...item.options,
|
|
890
|
+
payloadType: exported.dataType,
|
|
891
|
+
payloadSize,
|
|
892
|
+
},
|
|
893
|
+
};
|
|
894
|
+
}
|
|
895
|
+
/**
|
|
896
|
+
* Error thrown when batch trigger operations fail.
|
|
897
|
+
* Includes context about which phase failed and the batch details.
|
|
747
898
|
*
|
|
748
|
-
*
|
|
749
|
-
* -
|
|
750
|
-
* -
|
|
751
|
-
* - Return value types
|
|
752
|
-
* - Error handling
|
|
899
|
+
* When the underlying error is a rate limit (429), additional properties are exposed:
|
|
900
|
+
* - `isRateLimited`: true
|
|
901
|
+
* - `retryAfterMs`: milliseconds until the rate limit resets
|
|
753
902
|
*/
|
|
754
|
-
export
|
|
755
|
-
|
|
756
|
-
|
|
757
|
-
|
|
903
|
+
export class BatchTriggerError extends Error {
|
|
904
|
+
phase;
|
|
905
|
+
batchId;
|
|
906
|
+
itemCount;
|
|
907
|
+
/** True if the error was caused by rate limiting (HTTP 429) */
|
|
908
|
+
isRateLimited;
|
|
909
|
+
/** Milliseconds until the rate limit resets. Only set when `isRateLimited` is true. */
|
|
910
|
+
retryAfterMs;
|
|
911
|
+
/** The underlying API error, if the cause was an ApiError */
|
|
912
|
+
apiError;
|
|
913
|
+
/** The underlying cause of the error */
|
|
914
|
+
cause;
|
|
915
|
+
constructor(message, options) {
|
|
916
|
+
// Build enhanced message that includes the cause's message
|
|
917
|
+
const fullMessage = buildBatchErrorMessage(message, options.cause);
|
|
918
|
+
super(fullMessage, { cause: options.cause });
|
|
919
|
+
this.name = "BatchTriggerError";
|
|
920
|
+
this.cause = options.cause;
|
|
921
|
+
this.phase = options.phase;
|
|
922
|
+
this.batchId = options.batchId;
|
|
923
|
+
this.itemCount = options.itemCount;
|
|
924
|
+
// Extract rate limit info from cause
|
|
925
|
+
if (options.cause instanceof RateLimitError) {
|
|
926
|
+
this.isRateLimited = true;
|
|
927
|
+
this.retryAfterMs = options.cause.millisecondsUntilReset;
|
|
928
|
+
this.apiError = options.cause;
|
|
929
|
+
}
|
|
930
|
+
else if (options.cause instanceof ApiError) {
|
|
931
|
+
this.isRateLimited = options.cause.status === 429;
|
|
932
|
+
this.apiError = options.cause;
|
|
933
|
+
}
|
|
934
|
+
else {
|
|
935
|
+
this.isRateLimited = false;
|
|
936
|
+
}
|
|
758
937
|
}
|
|
759
|
-
|
|
760
|
-
|
|
761
|
-
|
|
762
|
-
|
|
763
|
-
|
|
764
|
-
|
|
765
|
-
|
|
766
|
-
|
|
767
|
-
|
|
768
|
-
|
|
769
|
-
|
|
770
|
-
|
|
771
|
-
|
|
772
|
-
|
|
773
|
-
queue: item.options?.queue,
|
|
774
|
-
concurrencyKey: item.options?.concurrencyKey,
|
|
775
|
-
test: taskContext.ctx?.run.isTest,
|
|
776
|
-
payloadType: payloadPacket.dataType,
|
|
777
|
-
delay: item.options?.delay,
|
|
778
|
-
ttl: item.options?.ttl,
|
|
779
|
-
tags: item.options?.tags,
|
|
780
|
-
maxAttempts: item.options?.maxAttempts,
|
|
781
|
-
metadata: item.options?.metadata,
|
|
782
|
-
maxDuration: item.options?.maxDuration,
|
|
783
|
-
machine: item.options?.machine,
|
|
784
|
-
},
|
|
785
|
-
};
|
|
786
|
-
})),
|
|
787
|
-
dependentAttempt: ctx.attempt.id,
|
|
788
|
-
}, {
|
|
789
|
-
processingStrategy: options?.triggerSequentially ? "sequential" : undefined,
|
|
790
|
-
}, requestOptions);
|
|
791
|
-
span.setAttribute("batchId", response.id);
|
|
792
|
-
span.setAttribute("runCount", response.runs.length);
|
|
793
|
-
span.setAttribute("isCached", response.isCached);
|
|
794
|
-
if (response.isCached) {
|
|
795
|
-
console.warn(`Result is a cached response because the request was idempotent.`);
|
|
938
|
+
}
|
|
939
|
+
/**
|
|
940
|
+
* Build an enhanced error message that includes context from the cause.
|
|
941
|
+
*/
|
|
942
|
+
function buildBatchErrorMessage(baseMessage, cause) {
|
|
943
|
+
if (!cause) {
|
|
944
|
+
return baseMessage;
|
|
945
|
+
}
|
|
946
|
+
// Handle RateLimitError specifically for better messaging
|
|
947
|
+
if (cause instanceof RateLimitError) {
|
|
948
|
+
const retryMs = cause.millisecondsUntilReset;
|
|
949
|
+
if (retryMs !== undefined) {
|
|
950
|
+
const retrySeconds = Math.ceil(retryMs / 1000);
|
|
951
|
+
return `${baseMessage}: Rate limit exceeded - retry after ${retrySeconds}s`;
|
|
796
952
|
}
|
|
797
|
-
|
|
798
|
-
|
|
953
|
+
return `${baseMessage}: Rate limit exceeded`;
|
|
954
|
+
}
|
|
955
|
+
// Handle other ApiErrors
|
|
956
|
+
if (cause instanceof ApiError) {
|
|
957
|
+
return `${baseMessage}: ${cause.message}`;
|
|
958
|
+
}
|
|
959
|
+
// Handle generic errors
|
|
960
|
+
if (cause instanceof Error) {
|
|
961
|
+
return `${baseMessage}: ${cause.message}`;
|
|
962
|
+
}
|
|
963
|
+
return baseMessage;
|
|
964
|
+
}
|
|
965
|
+
/**
|
|
966
|
+
* Execute a streaming 2-phase batch trigger where items are streamed from an AsyncIterable.
|
|
967
|
+
* Unlike executeBatchTwoPhase, this doesn't know the count upfront.
|
|
968
|
+
*
|
|
969
|
+
* @param apiClient - The API client instance
|
|
970
|
+
* @param items - AsyncIterable of batch items
|
|
971
|
+
* @param options - Batch options including trace context settings
|
|
972
|
+
* @param options.spanParentAsLink - If true, child runs will have separate trace IDs with a link to parent.
|
|
973
|
+
* Use true for batchTrigger (fire-and-forget), false for batchTriggerAndWait.
|
|
974
|
+
* @param requestOptions - Optional request options
|
|
975
|
+
* @internal
|
|
976
|
+
*/
|
|
977
|
+
async function executeBatchTwoPhaseStreaming(apiClient, items, options, requestOptions) {
|
|
978
|
+
// For streaming, we need to buffer items to get the count first
|
|
979
|
+
// This is because createBatch requires runCount upfront
|
|
980
|
+
// In the future, we could add a streaming-first endpoint that doesn't require this
|
|
981
|
+
const itemsArray = [];
|
|
982
|
+
for await (const item of items) {
|
|
983
|
+
itemsArray.push(item);
|
|
984
|
+
}
|
|
985
|
+
// Now we can use the regular 2-phase approach
|
|
986
|
+
return executeBatchTwoPhase(apiClient, itemsArray, options, requestOptions);
|
|
987
|
+
}
|
|
988
|
+
/**
|
|
989
|
+
* Type guard to check if a value is a ReadableStream
|
|
990
|
+
*/
|
|
991
|
+
function isReadableStream(value) {
|
|
992
|
+
return (value != null &&
|
|
993
|
+
typeof value === "object" &&
|
|
994
|
+
"getReader" in value &&
|
|
995
|
+
typeof value.getReader === "function");
|
|
996
|
+
}
|
|
997
|
+
/**
|
|
998
|
+
* Convert a ReadableStream to an AsyncIterable.
|
|
999
|
+
* Properly cancels the stream when the consumer terminates early.
|
|
1000
|
+
*
|
|
1001
|
+
* @internal Exported for testing purposes
|
|
1002
|
+
*/
|
|
1003
|
+
export async function* readableStreamToAsyncIterable(stream) {
|
|
1004
|
+
const reader = stream.getReader();
|
|
1005
|
+
try {
|
|
1006
|
+
while (true) {
|
|
1007
|
+
const { done, value } = await reader.read();
|
|
1008
|
+
if (done)
|
|
1009
|
+
break;
|
|
1010
|
+
yield value;
|
|
799
1011
|
}
|
|
800
|
-
|
|
801
|
-
|
|
802
|
-
|
|
803
|
-
|
|
804
|
-
}
|
|
805
|
-
|
|
806
|
-
|
|
807
|
-
|
|
808
|
-
|
|
1012
|
+
}
|
|
1013
|
+
finally {
|
|
1014
|
+
try {
|
|
1015
|
+
await reader.cancel();
|
|
1016
|
+
}
|
|
1017
|
+
catch {
|
|
1018
|
+
// Ignore errors - stream might already be errored or closed
|
|
1019
|
+
}
|
|
1020
|
+
reader.releaseLock();
|
|
1021
|
+
}
|
|
1022
|
+
}
|
|
1023
|
+
/**
|
|
1024
|
+
* Normalize stream input to AsyncIterable
|
|
1025
|
+
*/
|
|
1026
|
+
function normalizeToAsyncIterable(input) {
|
|
1027
|
+
if (isReadableStream(input)) {
|
|
1028
|
+
return readableStreamToAsyncIterable(input);
|
|
1029
|
+
}
|
|
1030
|
+
return input;
|
|
1031
|
+
}
|
|
1032
|
+
/**
|
|
1033
|
+
* Transform a stream of BatchByIdItem to BatchItemNDJSON format.
|
|
1034
|
+
* Handles payload serialization and idempotency key generation.
|
|
1035
|
+
*
|
|
1036
|
+
* @internal
|
|
1037
|
+
*/
|
|
1038
|
+
async function* transformBatchItemsStream(items, options) {
|
|
1039
|
+
let index = 0;
|
|
1040
|
+
for await (const item of items) {
|
|
1041
|
+
const taskMetadata = resourceCatalog.getTask(item.id);
|
|
1042
|
+
const parsedPayload = taskMetadata?.fns.parsePayload
|
|
1043
|
+
? await taskMetadata?.fns.parsePayload(item.payload)
|
|
1044
|
+
: item.payload;
|
|
1045
|
+
const payloadPacket = await stringifyIO(parsedPayload);
|
|
1046
|
+
const batchItemIdempotencyKey = await makeIdempotencyKey(flattenIdempotencyKey([options?.idempotencyKey, `${index}`]));
|
|
1047
|
+
yield {
|
|
1048
|
+
index: index++,
|
|
1049
|
+
task: item.id,
|
|
1050
|
+
payload: payloadPacket.data,
|
|
1051
|
+
options: {
|
|
1052
|
+
...triggerQueueBody(item.options?.queue),
|
|
1053
|
+
...triggerConcurrencyBody(item.options?.concurrency),
|
|
1054
|
+
concurrencyKey: item.options?.concurrencyKey,
|
|
1055
|
+
test: taskContext.ctx?.run.isTest,
|
|
1056
|
+
payloadType: payloadPacket.dataType,
|
|
1057
|
+
delay: item.options?.delay,
|
|
1058
|
+
ttl: item.options?.ttl,
|
|
1059
|
+
tags: item.options?.tags,
|
|
1060
|
+
maxAttempts: item.options?.maxAttempts,
|
|
1061
|
+
metadata: item.options?.metadata,
|
|
1062
|
+
maxDuration: item.options?.maxDuration,
|
|
1063
|
+
idempotencyKey: (await makeIdempotencyKey(item.options?.idempotencyKey)) ?? batchItemIdempotencyKey,
|
|
1064
|
+
idempotencyKeyTTL: item.options?.idempotencyKeyTTL ?? options?.idempotencyKeyTTL,
|
|
1065
|
+
machine: item.options?.machine,
|
|
1066
|
+
priority: item.options?.priority,
|
|
1067
|
+
region: item.options?.region,
|
|
1068
|
+
lockToVersion: item.options?.version ?? scopedEnvVar("TRIGGER_VERSION"),
|
|
1069
|
+
externalDeploymentId: resolveTriggerExternalDeploymentId(item.options?.externalDeploymentId),
|
|
1070
|
+
debounce: item.options?.debounce,
|
|
1071
|
+
},
|
|
809
1072
|
};
|
|
810
|
-
}
|
|
811
|
-
|
|
812
|
-
|
|
813
|
-
|
|
814
|
-
|
|
815
|
-
|
|
1073
|
+
}
|
|
1074
|
+
}
|
|
1075
|
+
/**
|
|
1076
|
+
* Transform a stream of BatchByIdAndWaitItem to BatchItemNDJSON format for triggerAndWait.
|
|
1077
|
+
* Uses the current worker version for lockToVersion.
|
|
1078
|
+
*
|
|
1079
|
+
* @internal
|
|
1080
|
+
*/
|
|
1081
|
+
async function* transformBatchItemsStreamForWait(items, options) {
|
|
1082
|
+
let index = 0;
|
|
1083
|
+
for await (const item of items) {
|
|
1084
|
+
const taskMetadata = resourceCatalog.getTask(item.id);
|
|
1085
|
+
const parsedPayload = taskMetadata?.fns.parsePayload
|
|
1086
|
+
? await taskMetadata?.fns.parsePayload(item.payload)
|
|
1087
|
+
: item.payload;
|
|
1088
|
+
const payloadPacket = await stringifyIO(parsedPayload);
|
|
1089
|
+
const batchItemIdempotencyKey = await makeIdempotencyKey(flattenIdempotencyKey([options?.idempotencyKey, `${index}`]));
|
|
1090
|
+
yield {
|
|
1091
|
+
index: index++,
|
|
1092
|
+
task: item.id,
|
|
1093
|
+
payload: payloadPacket.data,
|
|
1094
|
+
options: {
|
|
1095
|
+
lockToVersion: taskContext.worker?.version,
|
|
1096
|
+
...triggerQueueBody(item.options?.queue),
|
|
1097
|
+
...triggerConcurrencyBody(item.options?.concurrency),
|
|
1098
|
+
concurrencyKey: item.options?.concurrencyKey,
|
|
1099
|
+
test: taskContext.ctx?.run.isTest,
|
|
1100
|
+
payloadType: payloadPacket.dataType,
|
|
1101
|
+
delay: item.options?.delay,
|
|
1102
|
+
ttl: item.options?.ttl,
|
|
1103
|
+
tags: item.options?.tags,
|
|
1104
|
+
maxAttempts: item.options?.maxAttempts,
|
|
1105
|
+
metadata: item.options?.metadata,
|
|
1106
|
+
maxDuration: item.options?.maxDuration,
|
|
1107
|
+
idempotencyKey: (await makeIdempotencyKey(item.options?.idempotencyKey)) ?? batchItemIdempotencyKey,
|
|
1108
|
+
idempotencyKeyTTL: item.options?.idempotencyKeyTTL ?? options?.idempotencyKeyTTL,
|
|
1109
|
+
machine: item.options?.machine,
|
|
1110
|
+
priority: item.options?.priority,
|
|
1111
|
+
region: item.options?.region,
|
|
1112
|
+
debounce: item.options?.debounce,
|
|
1113
|
+
},
|
|
1114
|
+
};
|
|
1115
|
+
}
|
|
1116
|
+
}
|
|
1117
|
+
/**
|
|
1118
|
+
* Transform a stream of BatchByTaskItem to BatchItemNDJSON format.
|
|
1119
|
+
*
|
|
1120
|
+
* @internal
|
|
1121
|
+
*/
|
|
1122
|
+
async function* transformBatchByTaskItemsStream(items, options) {
|
|
1123
|
+
let index = 0;
|
|
1124
|
+
for await (const item of items) {
|
|
1125
|
+
const taskMetadata = resourceCatalog.getTask(item.task.id);
|
|
1126
|
+
const parsedPayload = taskMetadata?.fns.parsePayload
|
|
1127
|
+
? await taskMetadata?.fns.parsePayload(item.payload)
|
|
1128
|
+
: item.payload;
|
|
1129
|
+
const payloadPacket = await stringifyIO(parsedPayload);
|
|
1130
|
+
const batchItemIdempotencyKey = await makeIdempotencyKey(flattenIdempotencyKey([options?.idempotencyKey, `${index}`]));
|
|
1131
|
+
yield {
|
|
1132
|
+
index: index++,
|
|
1133
|
+
task: item.task.id,
|
|
1134
|
+
payload: payloadPacket.data,
|
|
1135
|
+
options: {
|
|
1136
|
+
...triggerQueueBody(item.options?.queue),
|
|
1137
|
+
...triggerConcurrencyBody(item.options?.concurrency),
|
|
1138
|
+
concurrencyKey: item.options?.concurrencyKey,
|
|
1139
|
+
test: taskContext.ctx?.run.isTest,
|
|
1140
|
+
payloadType: payloadPacket.dataType,
|
|
1141
|
+
delay: item.options?.delay,
|
|
1142
|
+
ttl: item.options?.ttl,
|
|
1143
|
+
tags: item.options?.tags,
|
|
1144
|
+
maxAttempts: item.options?.maxAttempts,
|
|
1145
|
+
metadata: item.options?.metadata,
|
|
1146
|
+
maxDuration: item.options?.maxDuration,
|
|
1147
|
+
idempotencyKey: (await makeIdempotencyKey(item.options?.idempotencyKey)) ?? batchItemIdempotencyKey,
|
|
1148
|
+
idempotencyKeyTTL: item.options?.idempotencyKeyTTL ?? options?.idempotencyKeyTTL,
|
|
1149
|
+
machine: item.options?.machine,
|
|
1150
|
+
priority: item.options?.priority,
|
|
1151
|
+
region: item.options?.region,
|
|
1152
|
+
lockToVersion: item.options?.version ?? scopedEnvVar("TRIGGER_VERSION"),
|
|
1153
|
+
externalDeploymentId: resolveTriggerExternalDeploymentId(item.options?.externalDeploymentId),
|
|
1154
|
+
debounce: item.options?.debounce,
|
|
1155
|
+
},
|
|
1156
|
+
};
|
|
1157
|
+
}
|
|
1158
|
+
}
|
|
1159
|
+
/**
|
|
1160
|
+
* Transform a stream of BatchByTaskAndWaitItem to BatchItemNDJSON format for triggerAndWait.
|
|
1161
|
+
*
|
|
1162
|
+
* @internal
|
|
1163
|
+
*/
|
|
1164
|
+
async function* transformBatchByTaskItemsStreamForWait(items, options) {
|
|
1165
|
+
let index = 0;
|
|
1166
|
+
for await (const item of items) {
|
|
1167
|
+
const taskMetadata = resourceCatalog.getTask(item.task.id);
|
|
1168
|
+
const parsedPayload = taskMetadata?.fns.parsePayload
|
|
1169
|
+
? await taskMetadata?.fns.parsePayload(item.payload)
|
|
1170
|
+
: item.payload;
|
|
1171
|
+
const payloadPacket = await stringifyIO(parsedPayload);
|
|
1172
|
+
const batchItemIdempotencyKey = await makeIdempotencyKey(flattenIdempotencyKey([options?.idempotencyKey, `${index}`]));
|
|
1173
|
+
yield {
|
|
1174
|
+
index: index++,
|
|
1175
|
+
task: item.task.id,
|
|
1176
|
+
payload: payloadPacket.data,
|
|
1177
|
+
options: {
|
|
1178
|
+
lockToVersion: taskContext.worker?.version,
|
|
1179
|
+
...triggerQueueBody(item.options?.queue),
|
|
1180
|
+
...triggerConcurrencyBody(item.options?.concurrency),
|
|
1181
|
+
concurrencyKey: item.options?.concurrencyKey,
|
|
1182
|
+
test: taskContext.ctx?.run.isTest,
|
|
1183
|
+
payloadType: payloadPacket.dataType,
|
|
1184
|
+
delay: item.options?.delay,
|
|
1185
|
+
ttl: item.options?.ttl,
|
|
1186
|
+
tags: item.options?.tags,
|
|
1187
|
+
maxAttempts: item.options?.maxAttempts,
|
|
1188
|
+
metadata: item.options?.metadata,
|
|
1189
|
+
maxDuration: item.options?.maxDuration,
|
|
1190
|
+
idempotencyKey: (await makeIdempotencyKey(item.options?.idempotencyKey)) ?? batchItemIdempotencyKey,
|
|
1191
|
+
idempotencyKeyTTL: item.options?.idempotencyKeyTTL ?? options?.idempotencyKeyTTL,
|
|
1192
|
+
machine: item.options?.machine,
|
|
1193
|
+
priority: item.options?.priority,
|
|
1194
|
+
region: item.options?.region,
|
|
1195
|
+
debounce: item.options?.debounce,
|
|
1196
|
+
},
|
|
1197
|
+
};
|
|
1198
|
+
}
|
|
1199
|
+
}
|
|
1200
|
+
/**
|
|
1201
|
+
* Transform a stream of BatchItem (single task type) to BatchItemNDJSON format.
|
|
1202
|
+
*
|
|
1203
|
+
* @internal
|
|
1204
|
+
*/
|
|
1205
|
+
async function* transformSingleTaskBatchItemsStream(taskIdentifier, items, parsePayload, options, queue) {
|
|
1206
|
+
let index = 0;
|
|
1207
|
+
for await (const item of items) {
|
|
1208
|
+
const parsedPayload = parsePayload ? await parsePayload(item.payload) : item.payload;
|
|
1209
|
+
const payloadPacket = await stringifyIO(parsedPayload);
|
|
1210
|
+
const batchItemIdempotencyKey = await makeIdempotencyKey(flattenIdempotencyKey([options?.idempotencyKey, `${index}`]));
|
|
1211
|
+
yield {
|
|
1212
|
+
index: index++,
|
|
1213
|
+
task: taskIdentifier,
|
|
1214
|
+
payload: payloadPacket.data,
|
|
1215
|
+
options: {
|
|
1216
|
+
...triggerQueueBody(item.options?.queue, queue),
|
|
1217
|
+
...triggerConcurrencyBody(item.options?.concurrency),
|
|
1218
|
+
concurrencyKey: item.options?.concurrencyKey,
|
|
1219
|
+
test: taskContext.ctx?.run.isTest,
|
|
1220
|
+
payloadType: payloadPacket.dataType,
|
|
1221
|
+
delay: item.options?.delay,
|
|
1222
|
+
ttl: item.options?.ttl,
|
|
1223
|
+
tags: item.options?.tags,
|
|
1224
|
+
maxAttempts: item.options?.maxAttempts,
|
|
1225
|
+
metadata: item.options?.metadata,
|
|
1226
|
+
maxDuration: item.options?.maxDuration,
|
|
1227
|
+
idempotencyKey: (await makeIdempotencyKey(item.options?.idempotencyKey)) ?? batchItemIdempotencyKey,
|
|
1228
|
+
idempotencyKeyTTL: item.options?.idempotencyKeyTTL ?? options?.idempotencyKeyTTL,
|
|
1229
|
+
machine: item.options?.machine,
|
|
1230
|
+
priority: item.options?.priority,
|
|
1231
|
+
region: item.options?.region,
|
|
1232
|
+
lockToVersion: item.options?.version ?? scopedEnvVar("TRIGGER_VERSION"),
|
|
1233
|
+
externalDeploymentId: resolveTriggerExternalDeploymentId(item.options?.externalDeploymentId),
|
|
1234
|
+
debounce: item.options?.debounce,
|
|
1235
|
+
},
|
|
1236
|
+
};
|
|
1237
|
+
}
|
|
1238
|
+
}
|
|
1239
|
+
/**
|
|
1240
|
+
* Transform a stream of BatchTriggerAndWaitItem (single task type) to BatchItemNDJSON format.
|
|
1241
|
+
*
|
|
1242
|
+
* @internal
|
|
1243
|
+
*/
|
|
1244
|
+
async function* transformSingleTaskBatchItemsStreamForWait(taskIdentifier, items, parsePayload, options, queue) {
|
|
1245
|
+
let index = 0;
|
|
1246
|
+
for await (const item of items) {
|
|
1247
|
+
const parsedPayload = parsePayload ? await parsePayload(item.payload) : item.payload;
|
|
1248
|
+
const payloadPacket = await stringifyIO(parsedPayload);
|
|
1249
|
+
const batchItemIdempotencyKey = await makeIdempotencyKey(flattenIdempotencyKey([options?.idempotencyKey, `${index}`]));
|
|
1250
|
+
// Process item-specific idempotency key and extract options
|
|
1251
|
+
const itemIdempotencyKey = await makeIdempotencyKey(item.options?.idempotencyKey);
|
|
1252
|
+
const finalIdempotencyKey = itemIdempotencyKey ?? batchItemIdempotencyKey;
|
|
1253
|
+
const idempotencyKeyOptions = itemIdempotencyKey
|
|
1254
|
+
? getIdempotencyKeyOptions(itemIdempotencyKey)
|
|
1255
|
+
: undefined;
|
|
1256
|
+
yield {
|
|
1257
|
+
index: index++,
|
|
1258
|
+
task: taskIdentifier,
|
|
1259
|
+
payload: payloadPacket.data,
|
|
1260
|
+
options: {
|
|
1261
|
+
lockToVersion: taskContext.worker?.version,
|
|
1262
|
+
...triggerQueueBody(item.options?.queue, queue),
|
|
1263
|
+
...triggerConcurrencyBody(item.options?.concurrency),
|
|
1264
|
+
concurrencyKey: item.options?.concurrencyKey,
|
|
1265
|
+
test: taskContext.ctx?.run.isTest,
|
|
1266
|
+
payloadType: payloadPacket.dataType,
|
|
1267
|
+
delay: item.options?.delay,
|
|
1268
|
+
ttl: item.options?.ttl,
|
|
1269
|
+
tags: item.options?.tags,
|
|
1270
|
+
maxAttempts: item.options?.maxAttempts,
|
|
1271
|
+
metadata: item.options?.metadata,
|
|
1272
|
+
maxDuration: item.options?.maxDuration,
|
|
1273
|
+
idempotencyKey: finalIdempotencyKey?.toString(),
|
|
1274
|
+
idempotencyKeyTTL: item.options?.idempotencyKeyTTL ?? options?.idempotencyKeyTTL,
|
|
1275
|
+
idempotencyKeyOptions,
|
|
1276
|
+
machine: item.options?.machine,
|
|
1277
|
+
priority: item.options?.priority,
|
|
1278
|
+
region: item.options?.region,
|
|
1279
|
+
debounce: item.options?.debounce,
|
|
1280
|
+
},
|
|
1281
|
+
};
|
|
1282
|
+
}
|
|
816
1283
|
}
|
|
817
1284
|
async function trigger_internal(name, id, payload, parsePayload, options, requestOptions) {
|
|
818
|
-
const apiClient = apiClientManager.clientOrThrow();
|
|
1285
|
+
const apiClient = apiClientManager.clientOrThrow(requestOptions?.clientConfig);
|
|
819
1286
|
const parsedPayload = parsePayload ? await parsePayload(payload) : payload;
|
|
820
|
-
const
|
|
1287
|
+
const { packet: triggerPayloadPacket, payloadSize } = await prepareTriggerPayload(parsedPayload, apiClient);
|
|
1288
|
+
// Process idempotency key and extract options for storage
|
|
1289
|
+
const processedIdempotencyKey = await makeIdempotencyKey(options?.idempotencyKey);
|
|
1290
|
+
const idempotencyKeyOptions = processedIdempotencyKey
|
|
1291
|
+
? getIdempotencyKeyOptions(processedIdempotencyKey)
|
|
1292
|
+
: undefined;
|
|
821
1293
|
const handle = await apiClient.triggerTask(id, {
|
|
822
|
-
payload:
|
|
1294
|
+
payload: triggerPayloadPacket.data,
|
|
823
1295
|
options: {
|
|
824
|
-
|
|
1296
|
+
...triggerQueueBody(options?.queue),
|
|
1297
|
+
...triggerConcurrencyBody(options?.concurrency),
|
|
825
1298
|
concurrencyKey: options?.concurrencyKey,
|
|
826
1299
|
test: taskContext.ctx?.run.isTest,
|
|
827
|
-
payloadType:
|
|
828
|
-
|
|
1300
|
+
payloadType: triggerPayloadPacket.dataType,
|
|
1301
|
+
payloadSize,
|
|
1302
|
+
idempotencyKey: processedIdempotencyKey?.toString(),
|
|
829
1303
|
idempotencyKeyTTL: options?.idempotencyKeyTTL,
|
|
1304
|
+
idempotencyKeyOptions,
|
|
830
1305
|
delay: options?.delay,
|
|
831
1306
|
ttl: options?.ttl,
|
|
832
1307
|
tags: options?.tags,
|
|
833
1308
|
maxAttempts: options?.maxAttempts,
|
|
834
|
-
parentAttempt: taskContext.ctx?.attempt.id,
|
|
835
1309
|
metadata: options?.metadata,
|
|
836
1310
|
maxDuration: options?.maxDuration,
|
|
1311
|
+
parentRunId: taskContext.ctx?.run.id,
|
|
837
1312
|
machine: options?.machine,
|
|
1313
|
+
priority: options?.priority,
|
|
1314
|
+
region: options?.region,
|
|
1315
|
+
lockToVersion: options?.version ?? scopedEnvVar("TRIGGER_VERSION"),
|
|
1316
|
+
externalDeploymentId: resolveTriggerExternalDeploymentId(options?.externalDeploymentId),
|
|
1317
|
+
debounce: options?.debounce,
|
|
838
1318
|
},
|
|
839
1319
|
}, {
|
|
840
1320
|
spanParentAsLink: true,
|
|
@@ -854,96 +1334,169 @@ async function trigger_internal(name, id, payload, parsePayload, options, reques
|
|
|
854
1334
|
return handle;
|
|
855
1335
|
}
|
|
856
1336
|
async function batchTrigger_internal(name, taskIdentifier, items, options, parsePayload, requestOptions, queue) {
|
|
857
|
-
const apiClient = apiClientManager.clientOrThrow();
|
|
858
|
-
const
|
|
859
|
-
|
|
1337
|
+
const apiClient = apiClientManager.clientOrThrow(requestOptions?.clientConfig);
|
|
1338
|
+
const ctx = taskContext.ctx;
|
|
1339
|
+
// Check if items is an array or a stream
|
|
1340
|
+
if (Array.isArray(items)) {
|
|
1341
|
+
// Prepare items as BatchItemNDJSON
|
|
1342
|
+
const ndJsonItems = await Promise.all(items.map(async (item, index) => {
|
|
860
1343
|
const parsedPayload = parsePayload ? await parsePayload(item.payload) : item.payload;
|
|
861
1344
|
const payloadPacket = await stringifyIO(parsedPayload);
|
|
1345
|
+
const batchItemIdempotencyKey = await makeIdempotencyKey(flattenIdempotencyKey([options?.idempotencyKey, `${index}`]));
|
|
1346
|
+
// Process item-specific idempotency key and extract options
|
|
1347
|
+
const itemIdempotencyKey = await makeIdempotencyKey(item.options?.idempotencyKey);
|
|
1348
|
+
const finalIdempotencyKey = itemIdempotencyKey ?? batchItemIdempotencyKey;
|
|
1349
|
+
const idempotencyKeyOptions = itemIdempotencyKey
|
|
1350
|
+
? getIdempotencyKeyOptions(itemIdempotencyKey)
|
|
1351
|
+
: undefined;
|
|
862
1352
|
return {
|
|
1353
|
+
index,
|
|
863
1354
|
task: taskIdentifier,
|
|
864
1355
|
payload: payloadPacket.data,
|
|
865
1356
|
options: {
|
|
866
|
-
|
|
1357
|
+
...triggerQueueBody(item.options?.queue, queue),
|
|
1358
|
+
...triggerConcurrencyBody(item.options?.concurrency),
|
|
867
1359
|
concurrencyKey: item.options?.concurrencyKey,
|
|
868
1360
|
test: taskContext.ctx?.run.isTest,
|
|
869
1361
|
payloadType: payloadPacket.dataType,
|
|
870
|
-
idempotencyKey: await makeIdempotencyKey(item.options?.idempotencyKey),
|
|
871
|
-
idempotencyKeyTTL: item.options?.idempotencyKeyTTL,
|
|
872
1362
|
delay: item.options?.delay,
|
|
873
1363
|
ttl: item.options?.ttl,
|
|
874
1364
|
tags: item.options?.tags,
|
|
875
1365
|
maxAttempts: item.options?.maxAttempts,
|
|
876
|
-
parentAttempt: taskContext.ctx?.attempt.id,
|
|
877
1366
|
metadata: item.options?.metadata,
|
|
878
1367
|
maxDuration: item.options?.maxDuration,
|
|
1368
|
+
idempotencyKey: finalIdempotencyKey?.toString(),
|
|
1369
|
+
idempotencyKeyTTL: item.options?.idempotencyKeyTTL ?? options?.idempotencyKeyTTL,
|
|
1370
|
+
idempotencyKeyOptions,
|
|
879
1371
|
machine: item.options?.machine,
|
|
1372
|
+
priority: item.options?.priority,
|
|
1373
|
+
region: item.options?.region,
|
|
1374
|
+
lockToVersion: item.options?.version ?? scopedEnvVar("TRIGGER_VERSION"),
|
|
1375
|
+
externalDeploymentId: resolveTriggerExternalDeploymentId(item.options?.externalDeploymentId),
|
|
1376
|
+
debounce: item.options?.debounce,
|
|
880
1377
|
},
|
|
881
1378
|
};
|
|
882
|
-
}))
|
|
883
|
-
|
|
884
|
-
|
|
885
|
-
|
|
886
|
-
|
|
887
|
-
|
|
888
|
-
|
|
889
|
-
name,
|
|
890
|
-
|
|
891
|
-
|
|
892
|
-
|
|
893
|
-
|
|
894
|
-
|
|
895
|
-
|
|
896
|
-
|
|
897
|
-
|
|
898
|
-
|
|
899
|
-
|
|
900
|
-
|
|
901
|
-
|
|
902
|
-
|
|
903
|
-
|
|
904
|
-
|
|
905
|
-
|
|
906
|
-
|
|
907
|
-
|
|
908
|
-
|
|
909
|
-
|
|
910
|
-
|
|
911
|
-
|
|
912
|
-
|
|
913
|
-
|
|
914
|
-
|
|
915
|
-
|
|
916
|
-
|
|
917
|
-
|
|
918
|
-
|
|
919
|
-
|
|
920
|
-
|
|
1379
|
+
}));
|
|
1380
|
+
// Execute 2-phase batch
|
|
1381
|
+
// Process batch-level idempotency key
|
|
1382
|
+
const batchIdempotencyKey = await makeIdempotencyKey(options?.idempotencyKey);
|
|
1383
|
+
const batchIdempotencyKeyOptions = batchIdempotencyKey
|
|
1384
|
+
? getIdempotencyKeyOptions(batchIdempotencyKey)
|
|
1385
|
+
: undefined;
|
|
1386
|
+
const response = await tracer.startActiveSpan(name, async (span) => {
|
|
1387
|
+
const result = await executeBatchTwoPhase(apiClient, ndJsonItems, {
|
|
1388
|
+
parentRunId: ctx?.run.id,
|
|
1389
|
+
idempotencyKey: batchIdempotencyKey?.toString(),
|
|
1390
|
+
idempotencyKeyOptions: batchIdempotencyKeyOptions,
|
|
1391
|
+
spanParentAsLink: true, // Fire-and-forget: child runs get separate trace IDs
|
|
1392
|
+
}, requestOptions);
|
|
1393
|
+
span.setAttribute("batchId", result.id);
|
|
1394
|
+
span.setAttribute("runCount", result.runCount);
|
|
1395
|
+
return result;
|
|
1396
|
+
}, {
|
|
1397
|
+
kind: SpanKind.PRODUCER,
|
|
1398
|
+
attributes: {
|
|
1399
|
+
[SemanticInternalAttributes.STYLE_ICON]: "trigger",
|
|
1400
|
+
...accessoryAttributes({
|
|
1401
|
+
items: [
|
|
1402
|
+
{
|
|
1403
|
+
text: taskIdentifier,
|
|
1404
|
+
variant: "normal",
|
|
1405
|
+
},
|
|
1406
|
+
],
|
|
1407
|
+
style: "codepath",
|
|
1408
|
+
}),
|
|
1409
|
+
},
|
|
1410
|
+
});
|
|
1411
|
+
const handle = {
|
|
1412
|
+
batchId: response.id,
|
|
1413
|
+
runCount: response.runCount,
|
|
1414
|
+
publicAccessToken: response.publicAccessToken,
|
|
1415
|
+
};
|
|
1416
|
+
return handle;
|
|
1417
|
+
}
|
|
1418
|
+
else {
|
|
1419
|
+
// Stream path: convert to AsyncIterable and transform
|
|
1420
|
+
const asyncItems = normalizeToAsyncIterable(items);
|
|
1421
|
+
const transformedItems = transformSingleTaskBatchItemsStream(taskIdentifier, asyncItems, parsePayload, options, queue);
|
|
1422
|
+
// Execute streaming 2-phase batch
|
|
1423
|
+
// Process batch-level idempotency key
|
|
1424
|
+
const streamBatchIdempotencyKey = await makeIdempotencyKey(options?.idempotencyKey);
|
|
1425
|
+
const streamBatchIdempotencyKeyOptions = streamBatchIdempotencyKey
|
|
1426
|
+
? getIdempotencyKeyOptions(streamBatchIdempotencyKey)
|
|
1427
|
+
: undefined;
|
|
1428
|
+
const response = await tracer.startActiveSpan(name, async (span) => {
|
|
1429
|
+
const result = await executeBatchTwoPhaseStreaming(apiClient, transformedItems, {
|
|
1430
|
+
parentRunId: ctx?.run.id,
|
|
1431
|
+
idempotencyKey: streamBatchIdempotencyKey?.toString(),
|
|
1432
|
+
idempotencyKeyOptions: streamBatchIdempotencyKeyOptions,
|
|
1433
|
+
spanParentAsLink: true, // Fire-and-forget: child runs get separate trace IDs
|
|
1434
|
+
}, requestOptions);
|
|
1435
|
+
span.setAttribute("batchId", result.id);
|
|
1436
|
+
span.setAttribute("runCount", result.runCount);
|
|
1437
|
+
return result;
|
|
1438
|
+
}, {
|
|
1439
|
+
kind: SpanKind.PRODUCER,
|
|
1440
|
+
attributes: {
|
|
1441
|
+
[SemanticInternalAttributes.STYLE_ICON]: "trigger",
|
|
1442
|
+
...accessoryAttributes({
|
|
1443
|
+
items: [
|
|
1444
|
+
{
|
|
1445
|
+
text: taskIdentifier,
|
|
1446
|
+
variant: "normal",
|
|
1447
|
+
},
|
|
1448
|
+
],
|
|
1449
|
+
style: "codepath",
|
|
1450
|
+
}),
|
|
1451
|
+
},
|
|
1452
|
+
});
|
|
1453
|
+
const handle = {
|
|
1454
|
+
batchId: response.id,
|
|
1455
|
+
runCount: response.runCount,
|
|
1456
|
+
publicAccessToken: response.publicAccessToken,
|
|
1457
|
+
};
|
|
1458
|
+
return handle;
|
|
1459
|
+
}
|
|
921
1460
|
}
|
|
922
1461
|
async function triggerAndWait_internal(name, id, payload, parsePayload, options, requestOptions) {
|
|
923
1462
|
const ctx = taskContext.ctx;
|
|
924
1463
|
if (!ctx) {
|
|
925
1464
|
throw new Error("triggerAndWait can only be used from inside a task.run()");
|
|
926
1465
|
}
|
|
927
|
-
const apiClient = apiClientManager.clientOrThrow();
|
|
1466
|
+
const apiClient = apiClientManager.clientOrThrow(requestOptions?.clientConfig);
|
|
928
1467
|
const parsedPayload = parsePayload ? await parsePayload(payload) : payload;
|
|
929
|
-
const
|
|
1468
|
+
const { packet: triggerPayloadPacket, payloadSize } = await prepareTriggerPayload(parsedPayload, apiClient);
|
|
1469
|
+
// Process idempotency key and extract options for storage
|
|
1470
|
+
const processedIdempotencyKey = await makeIdempotencyKey(options?.idempotencyKey);
|
|
1471
|
+
const idempotencyKeyOptions = processedIdempotencyKey
|
|
1472
|
+
? getIdempotencyKeyOptions(processedIdempotencyKey)
|
|
1473
|
+
: undefined;
|
|
930
1474
|
return await tracer.startActiveSpan(name, async (span) => {
|
|
931
1475
|
const response = await apiClient.triggerTask(id, {
|
|
932
|
-
payload:
|
|
1476
|
+
payload: triggerPayloadPacket.data,
|
|
933
1477
|
options: {
|
|
934
|
-
dependentAttempt: ctx.attempt.id,
|
|
935
1478
|
lockToVersion: taskContext.worker?.version, // Lock to current version because we're waiting for it to finish
|
|
936
|
-
|
|
1479
|
+
...triggerQueueBody(options?.queue),
|
|
1480
|
+
...triggerConcurrencyBody(options?.concurrency),
|
|
937
1481
|
concurrencyKey: options?.concurrencyKey,
|
|
938
1482
|
test: taskContext.ctx?.run.isTest,
|
|
939
|
-
payloadType:
|
|
1483
|
+
payloadType: triggerPayloadPacket.dataType,
|
|
1484
|
+
payloadSize,
|
|
940
1485
|
delay: options?.delay,
|
|
941
1486
|
ttl: options?.ttl,
|
|
942
1487
|
tags: options?.tags,
|
|
943
1488
|
maxAttempts: options?.maxAttempts,
|
|
944
1489
|
metadata: options?.metadata,
|
|
945
1490
|
maxDuration: options?.maxDuration,
|
|
1491
|
+
resumeParentOnCompletion: true,
|
|
1492
|
+
parentRunId: ctx.run.id,
|
|
1493
|
+
idempotencyKey: processedIdempotencyKey?.toString(),
|
|
1494
|
+
idempotencyKeyTTL: options?.idempotencyKeyTTL,
|
|
1495
|
+
idempotencyKeyOptions,
|
|
946
1496
|
machine: options?.machine,
|
|
1497
|
+
priority: options?.priority,
|
|
1498
|
+
region: options?.region,
|
|
1499
|
+
debounce: options?.debounce,
|
|
947
1500
|
},
|
|
948
1501
|
}, {}, requestOptions);
|
|
949
1502
|
span.setAttribute("runId", response.id);
|
|
@@ -968,59 +1521,118 @@ async function triggerAndWait_internal(name, id, payload, parsePayload, options,
|
|
|
968
1521
|
},
|
|
969
1522
|
});
|
|
970
1523
|
}
|
|
971
|
-
async function
|
|
1524
|
+
async function triggerAndSubscribe_internal(name, id, payload, parsePayload, options, requestOptions) {
|
|
972
1525
|
const ctx = taskContext.ctx;
|
|
973
1526
|
if (!ctx) {
|
|
974
|
-
throw new Error("
|
|
1527
|
+
throw new Error("triggerAndSubscribe can only be used from inside a task.run()");
|
|
975
1528
|
}
|
|
976
|
-
const apiClient = apiClientManager.clientOrThrow();
|
|
1529
|
+
const apiClient = apiClientManager.clientOrThrow(requestOptions?.clientConfig);
|
|
1530
|
+
const parsedPayload = parsePayload ? await parsePayload(payload) : payload;
|
|
1531
|
+
const { packet: triggerPayloadPacket, payloadSize } = await prepareTriggerPayload(parsedPayload, apiClient);
|
|
1532
|
+
const processedIdempotencyKey = await makeIdempotencyKey(options?.idempotencyKey);
|
|
1533
|
+
const idempotencyKeyOptions = processedIdempotencyKey
|
|
1534
|
+
? getIdempotencyKeyOptions(processedIdempotencyKey)
|
|
1535
|
+
: undefined;
|
|
977
1536
|
return await tracer.startActiveSpan(name, async (span) => {
|
|
978
|
-
const response = await apiClient.
|
|
979
|
-
|
|
980
|
-
|
|
981
|
-
|
|
982
|
-
|
|
983
|
-
|
|
984
|
-
|
|
985
|
-
|
|
986
|
-
|
|
987
|
-
|
|
988
|
-
|
|
989
|
-
|
|
990
|
-
|
|
991
|
-
|
|
992
|
-
|
|
993
|
-
|
|
994
|
-
|
|
995
|
-
|
|
996
|
-
|
|
997
|
-
|
|
998
|
-
|
|
999
|
-
|
|
1000
|
-
|
|
1001
|
-
|
|
1002
|
-
|
|
1003
|
-
|
|
1004
|
-
}, requestOptions);
|
|
1005
|
-
|
|
1006
|
-
span.setAttribute("
|
|
1007
|
-
span.setAttribute("
|
|
1008
|
-
|
|
1009
|
-
|
|
1537
|
+
const response = await apiClient.triggerTask(id, {
|
|
1538
|
+
payload: triggerPayloadPacket.data,
|
|
1539
|
+
options: {
|
|
1540
|
+
lockToVersion: taskContext.worker?.version,
|
|
1541
|
+
...triggerQueueBody(options?.queue),
|
|
1542
|
+
...triggerConcurrencyBody(options?.concurrency),
|
|
1543
|
+
concurrencyKey: options?.concurrencyKey,
|
|
1544
|
+
test: taskContext.ctx?.run.isTest,
|
|
1545
|
+
payloadType: triggerPayloadPacket.dataType,
|
|
1546
|
+
payloadSize,
|
|
1547
|
+
delay: options?.delay,
|
|
1548
|
+
ttl: options?.ttl,
|
|
1549
|
+
tags: options?.tags,
|
|
1550
|
+
maxAttempts: options?.maxAttempts,
|
|
1551
|
+
metadata: options?.metadata,
|
|
1552
|
+
maxDuration: options?.maxDuration,
|
|
1553
|
+
parentRunId: ctx.run.id,
|
|
1554
|
+
// NOTE: no resumeParentOnCompletion — parent stays alive and subscribes
|
|
1555
|
+
idempotencyKey: processedIdempotencyKey?.toString(),
|
|
1556
|
+
idempotencyKeyTTL: options?.idempotencyKeyTTL,
|
|
1557
|
+
idempotencyKeyOptions,
|
|
1558
|
+
machine: options?.machine,
|
|
1559
|
+
priority: options?.priority,
|
|
1560
|
+
region: options?.region,
|
|
1561
|
+
debounce: options?.debounce,
|
|
1562
|
+
},
|
|
1563
|
+
}, {}, requestOptions);
|
|
1564
|
+
// Set attributes after trigger so the dashboard can link to the child run
|
|
1565
|
+
span.setAttribute("messaging.message.id", response.id);
|
|
1566
|
+
span.setAttribute("runId", response.id);
|
|
1567
|
+
span.setAttribute(SemanticInternalAttributes.ENTITY_TYPE, "run");
|
|
1568
|
+
span.setAttribute(SemanticInternalAttributes.ENTITY_ID, response.id);
|
|
1569
|
+
// Optionally cancel the child run when the abort signal fires (default: true)
|
|
1570
|
+
const cancelOnAbort = options?.cancelOnAbort !== false;
|
|
1571
|
+
let onAbort;
|
|
1572
|
+
if (options?.signal && cancelOnAbort) {
|
|
1573
|
+
if (options.signal.aborted) {
|
|
1574
|
+
await apiClient.cancelRun(response.id).catch(() => { });
|
|
1575
|
+
throw new DOMException("Aborted", "AbortError");
|
|
1576
|
+
}
|
|
1577
|
+
onAbort = () => {
|
|
1578
|
+
apiClient.cancelRun(response.id).catch(() => { });
|
|
1579
|
+
};
|
|
1580
|
+
// `{ once: true }` auto-removes the listener on abort, but if the
|
|
1581
|
+
// run completes normally the listener stays attached and pins
|
|
1582
|
+
// `apiClient` + `response.id` until the signal is GC'd. Long-lived
|
|
1583
|
+
// signals shared across many calls accumulate dead listeners; the
|
|
1584
|
+
// `finally` below removes the listener on every exit path.
|
|
1585
|
+
options.signal.addEventListener("abort", onAbort, { once: true });
|
|
1586
|
+
}
|
|
1587
|
+
try {
|
|
1588
|
+
for await (const run of apiClient.subscribeToRun(response.id, {
|
|
1589
|
+
closeOnComplete: true,
|
|
1590
|
+
signal: options?.signal,
|
|
1591
|
+
skipColumns: ["payload"],
|
|
1592
|
+
})) {
|
|
1593
|
+
if (run.isSuccess) {
|
|
1594
|
+
// run.output from subscribeToRun is already deserialized
|
|
1595
|
+
return {
|
|
1596
|
+
ok: true,
|
|
1597
|
+
id: response.id,
|
|
1598
|
+
taskIdentifier: id,
|
|
1599
|
+
output: run.output,
|
|
1600
|
+
};
|
|
1601
|
+
}
|
|
1602
|
+
if (run.isFailed || run.isCancelled) {
|
|
1603
|
+
// Note: this intentionally diverges from `triggerAndWait`'s
|
|
1604
|
+
// error shape. `triggerAndWait` receives a full `TaskRunError`
|
|
1605
|
+
// (with `type` discriminator: BUILT_IN_ERROR, CUSTOM_ERROR,
|
|
1606
|
+
// INTERNAL_ERROR, STRING_ERROR) via the completion message and
|
|
1607
|
+
// passes it through `createErrorTaskError` to preserve the
|
|
1608
|
+
// discriminator. `subscribeToRun` only surfaces a
|
|
1609
|
+
// `SerializedError` (`{ name, message, stackTrace, causes }`)
|
|
1610
|
+
// because `createJsonErrorObject` strips the discriminator before
|
|
1611
|
+
// the record hits the realtime stream. We can't reconstruct the
|
|
1612
|
+
// discriminator here without lossy guessing — callers that
|
|
1613
|
+
// need exact error-type matching should use `triggerAndWait`
|
|
1614
|
+
// instead; subscribers get message, name and the cause chain.
|
|
1615
|
+
const cause = run.error?.causes?.length
|
|
1616
|
+
? createErrorFromCauses(run.error.causes)
|
|
1617
|
+
: undefined;
|
|
1618
|
+
const error = new Error(run.error?.message ?? `Task ${id} failed (${run.status})`, cause ? { cause } : undefined);
|
|
1619
|
+
if (run.error?.name)
|
|
1620
|
+
error.name = run.error.name;
|
|
1621
|
+
return {
|
|
1622
|
+
ok: false,
|
|
1623
|
+
id: response.id,
|
|
1624
|
+
taskIdentifier: id,
|
|
1625
|
+
error,
|
|
1626
|
+
};
|
|
1627
|
+
}
|
|
1628
|
+
}
|
|
1629
|
+
throw new Error(`Task ${id}: subscription ended without completion`);
|
|
1010
1630
|
}
|
|
1011
|
-
|
|
1012
|
-
|
|
1631
|
+
finally {
|
|
1632
|
+
if (onAbort && options?.signal) {
|
|
1633
|
+
options.signal.removeEventListener("abort", onAbort);
|
|
1634
|
+
}
|
|
1013
1635
|
}
|
|
1014
|
-
const result = await runtime.waitForBatch({
|
|
1015
|
-
id: response.id,
|
|
1016
|
-
runs: response.runs.map((run) => run.id),
|
|
1017
|
-
ctx,
|
|
1018
|
-
});
|
|
1019
|
-
const runs = await handleBatchTaskRunExecutionResult(result.items, id);
|
|
1020
|
-
return {
|
|
1021
|
-
id: result.id,
|
|
1022
|
-
runs,
|
|
1023
|
-
};
|
|
1024
1636
|
}, {
|
|
1025
1637
|
kind: SpanKind.PRODUCER,
|
|
1026
1638
|
attributes: {
|
|
@@ -1037,6 +1649,141 @@ async function batchTriggerAndWait_internal(name, id, items, parsePayload, optio
|
|
|
1037
1649
|
},
|
|
1038
1650
|
});
|
|
1039
1651
|
}
|
|
1652
|
+
async function batchTriggerAndWait_internal(name, id, items, parsePayload, options, requestOptions, queue) {
|
|
1653
|
+
const ctx = taskContext.ctx;
|
|
1654
|
+
if (!ctx) {
|
|
1655
|
+
throw new Error("batchTriggerAndWait can only be used from inside a task.run()");
|
|
1656
|
+
}
|
|
1657
|
+
const apiClient = apiClientManager.clientOrThrow(requestOptions?.clientConfig);
|
|
1658
|
+
// Check if items is an array or a stream
|
|
1659
|
+
if (Array.isArray(items)) {
|
|
1660
|
+
// Prepare items as BatchItemNDJSON
|
|
1661
|
+
const ndJsonItems = await Promise.all(items.map(async (item, index) => {
|
|
1662
|
+
const parsedPayload = parsePayload ? await parsePayload(item.payload) : item.payload;
|
|
1663
|
+
const payloadPacket = await stringifyIO(parsedPayload);
|
|
1664
|
+
const batchItemIdempotencyKey = await makeIdempotencyKey(flattenIdempotencyKey([options?.idempotencyKey, `${index}`]));
|
|
1665
|
+
// Process item-specific idempotency key and extract options
|
|
1666
|
+
const itemIdempotencyKey = await makeIdempotencyKey(item.options?.idempotencyKey);
|
|
1667
|
+
const finalIdempotencyKey = itemIdempotencyKey ?? batchItemIdempotencyKey;
|
|
1668
|
+
const idempotencyKeyOptions = itemIdempotencyKey
|
|
1669
|
+
? getIdempotencyKeyOptions(itemIdempotencyKey)
|
|
1670
|
+
: undefined;
|
|
1671
|
+
return {
|
|
1672
|
+
index,
|
|
1673
|
+
task: id,
|
|
1674
|
+
payload: payloadPacket.data,
|
|
1675
|
+
options: {
|
|
1676
|
+
lockToVersion: taskContext.worker?.version,
|
|
1677
|
+
...triggerQueueBody(item.options?.queue, queue),
|
|
1678
|
+
...triggerConcurrencyBody(item.options?.concurrency),
|
|
1679
|
+
concurrencyKey: item.options?.concurrencyKey,
|
|
1680
|
+
test: taskContext.ctx?.run.isTest,
|
|
1681
|
+
payloadType: payloadPacket.dataType,
|
|
1682
|
+
delay: item.options?.delay,
|
|
1683
|
+
ttl: item.options?.ttl,
|
|
1684
|
+
tags: item.options?.tags,
|
|
1685
|
+
maxAttempts: item.options?.maxAttempts,
|
|
1686
|
+
metadata: item.options?.metadata,
|
|
1687
|
+
maxDuration: item.options?.maxDuration,
|
|
1688
|
+
idempotencyKey: finalIdempotencyKey?.toString(),
|
|
1689
|
+
idempotencyKeyTTL: item.options?.idempotencyKeyTTL ?? options?.idempotencyKeyTTL,
|
|
1690
|
+
idempotencyKeyOptions,
|
|
1691
|
+
machine: item.options?.machine,
|
|
1692
|
+
priority: item.options?.priority,
|
|
1693
|
+
region: item.options?.region,
|
|
1694
|
+
debounce: item.options?.debounce,
|
|
1695
|
+
},
|
|
1696
|
+
};
|
|
1697
|
+
}));
|
|
1698
|
+
// Process batch-level idempotency key
|
|
1699
|
+
const batchIdempotencyKey = await makeIdempotencyKey(options?.idempotencyKey);
|
|
1700
|
+
const batchIdempotencyKeyOptions = batchIdempotencyKey
|
|
1701
|
+
? getIdempotencyKeyOptions(batchIdempotencyKey)
|
|
1702
|
+
: undefined;
|
|
1703
|
+
return await tracer.startActiveSpan(name, async (span) => {
|
|
1704
|
+
// Execute 2-phase batch
|
|
1705
|
+
const response = await executeBatchTwoPhase(apiClient, ndJsonItems, {
|
|
1706
|
+
parentRunId: ctx.run.id,
|
|
1707
|
+
resumeParentOnCompletion: true,
|
|
1708
|
+
idempotencyKey: batchIdempotencyKey?.toString(),
|
|
1709
|
+
idempotencyKeyOptions: batchIdempotencyKeyOptions,
|
|
1710
|
+
spanParentAsLink: false, // Waiting: child runs share parent's trace ID
|
|
1711
|
+
}, requestOptions);
|
|
1712
|
+
span.setAttribute("batchId", response.id);
|
|
1713
|
+
span.setAttribute("runCount", response.runCount);
|
|
1714
|
+
const result = await runtime.waitForBatch({
|
|
1715
|
+
id: response.id,
|
|
1716
|
+
runCount: response.runCount,
|
|
1717
|
+
ctx,
|
|
1718
|
+
});
|
|
1719
|
+
const runs = await handleBatchTaskRunExecutionResult(result.items, id);
|
|
1720
|
+
return {
|
|
1721
|
+
id: result.id,
|
|
1722
|
+
runs,
|
|
1723
|
+
};
|
|
1724
|
+
}, {
|
|
1725
|
+
kind: SpanKind.PRODUCER,
|
|
1726
|
+
attributes: {
|
|
1727
|
+
[SemanticInternalAttributes.STYLE_ICON]: "trigger",
|
|
1728
|
+
...accessoryAttributes({
|
|
1729
|
+
items: [
|
|
1730
|
+
{
|
|
1731
|
+
text: id,
|
|
1732
|
+
variant: "normal",
|
|
1733
|
+
},
|
|
1734
|
+
],
|
|
1735
|
+
style: "codepath",
|
|
1736
|
+
}),
|
|
1737
|
+
},
|
|
1738
|
+
});
|
|
1739
|
+
}
|
|
1740
|
+
else {
|
|
1741
|
+
// Stream path: convert to AsyncIterable and transform
|
|
1742
|
+
const asyncItems = normalizeToAsyncIterable(items);
|
|
1743
|
+
const transformedItems = transformSingleTaskBatchItemsStreamForWait(id, asyncItems, parsePayload, options, queue);
|
|
1744
|
+
// Process batch-level idempotency key for streaming path
|
|
1745
|
+
const streamBatchIdempotencyKey = await makeIdempotencyKey(options?.idempotencyKey);
|
|
1746
|
+
const streamBatchIdempotencyKeyOptions = streamBatchIdempotencyKey
|
|
1747
|
+
? getIdempotencyKeyOptions(streamBatchIdempotencyKey)
|
|
1748
|
+
: undefined;
|
|
1749
|
+
return await tracer.startActiveSpan(name, async (span) => {
|
|
1750
|
+
// Execute streaming 2-phase batch
|
|
1751
|
+
const response = await executeBatchTwoPhaseStreaming(apiClient, transformedItems, {
|
|
1752
|
+
parentRunId: ctx.run.id,
|
|
1753
|
+
resumeParentOnCompletion: true,
|
|
1754
|
+
idempotencyKey: streamBatchIdempotencyKey?.toString(),
|
|
1755
|
+
idempotencyKeyOptions: streamBatchIdempotencyKeyOptions,
|
|
1756
|
+
spanParentAsLink: false, // Waiting: child runs share parent's trace ID
|
|
1757
|
+
}, requestOptions);
|
|
1758
|
+
span.setAttribute("batchId", response.id);
|
|
1759
|
+
span.setAttribute("runCount", response.runCount);
|
|
1760
|
+
const result = await runtime.waitForBatch({
|
|
1761
|
+
id: response.id,
|
|
1762
|
+
runCount: response.runCount,
|
|
1763
|
+
ctx,
|
|
1764
|
+
});
|
|
1765
|
+
const runs = await handleBatchTaskRunExecutionResult(result.items, id);
|
|
1766
|
+
return {
|
|
1767
|
+
id: result.id,
|
|
1768
|
+
runs,
|
|
1769
|
+
};
|
|
1770
|
+
}, {
|
|
1771
|
+
kind: SpanKind.PRODUCER,
|
|
1772
|
+
attributes: {
|
|
1773
|
+
[SemanticInternalAttributes.STYLE_ICON]: "trigger",
|
|
1774
|
+
...accessoryAttributes({
|
|
1775
|
+
items: [
|
|
1776
|
+
{
|
|
1777
|
+
text: id,
|
|
1778
|
+
variant: "normal",
|
|
1779
|
+
},
|
|
1780
|
+
],
|
|
1781
|
+
style: "codepath",
|
|
1782
|
+
}),
|
|
1783
|
+
},
|
|
1784
|
+
});
|
|
1785
|
+
}
|
|
1786
|
+
}
|
|
1040
1787
|
async function handleBatchTaskRunExecutionResult(items, taskIdentifier) {
|
|
1041
1788
|
const someObjectStoreOutputs = items.some((item) => item.ok && item.outputType === "application/store");
|
|
1042
1789
|
if (!someObjectStoreOutputs) {
|
|
@@ -1055,17 +1802,17 @@ async function handleBatchTaskRunExecutionResult(items, taskIdentifier) {
|
|
|
1055
1802
|
[SemanticInternalAttributes.STYLE_ICON]: "cloud-download",
|
|
1056
1803
|
});
|
|
1057
1804
|
}
|
|
1058
|
-
async function handleBatchTaskRunExecutionResultV2(items) {
|
|
1805
|
+
async function handleBatchTaskRunExecutionResultV2(items, taskIdentifiers) {
|
|
1059
1806
|
const someObjectStoreOutputs = items.some((item) => item.ok && item.outputType === "application/store");
|
|
1060
1807
|
if (!someObjectStoreOutputs) {
|
|
1061
|
-
const results = await Promise.all(items.map(async (item) => {
|
|
1062
|
-
return await handleTaskRunExecutionResult(item, item.taskIdentifier ?? "unknown");
|
|
1808
|
+
const results = await Promise.all(items.map(async (item, index) => {
|
|
1809
|
+
return await handleTaskRunExecutionResult(item, item.taskIdentifier ?? taskIdentifiers?.[index] ?? "unknown");
|
|
1063
1810
|
}));
|
|
1064
1811
|
return results;
|
|
1065
1812
|
}
|
|
1066
1813
|
return await tracer.startActiveSpan("store.downloadPayloads", async (span) => {
|
|
1067
|
-
const results = await Promise.all(items.map(async (item) => {
|
|
1068
|
-
return await handleTaskRunExecutionResult(item, item.taskIdentifier ?? "unknown");
|
|
1814
|
+
const results = await Promise.all(items.map(async (item, index) => {
|
|
1815
|
+
return await handleTaskRunExecutionResult(item, item.taskIdentifier ?? taskIdentifiers?.[index] ?? "unknown");
|
|
1069
1816
|
}));
|
|
1070
1817
|
return results;
|
|
1071
1818
|
}, {
|
|
@@ -1093,4 +1840,90 @@ async function handleTaskRunExecutionResult(execution, taskIdentifier) {
|
|
|
1093
1840
|
};
|
|
1094
1841
|
}
|
|
1095
1842
|
}
|
|
1843
|
+
function registerTaskLifecycleHooks(taskId, params) {
|
|
1844
|
+
if (params.init) {
|
|
1845
|
+
lifecycleHooks.registerTaskInitHook(taskId, {
|
|
1846
|
+
fn: params.init,
|
|
1847
|
+
});
|
|
1848
|
+
}
|
|
1849
|
+
if (params.onStart) {
|
|
1850
|
+
lifecycleHooks.registerTaskStartHook(taskId, {
|
|
1851
|
+
fn: params.onStart,
|
|
1852
|
+
});
|
|
1853
|
+
}
|
|
1854
|
+
if (params.onStartAttempt) {
|
|
1855
|
+
lifecycleHooks.registerTaskStartAttemptHook(taskId, {
|
|
1856
|
+
fn: params.onStartAttempt,
|
|
1857
|
+
});
|
|
1858
|
+
}
|
|
1859
|
+
if (params.onFailure) {
|
|
1860
|
+
lifecycleHooks.registerTaskFailureHook(taskId, {
|
|
1861
|
+
fn: params.onFailure,
|
|
1862
|
+
});
|
|
1863
|
+
}
|
|
1864
|
+
if (params.onSuccess) {
|
|
1865
|
+
lifecycleHooks.registerTaskSuccessHook(taskId, {
|
|
1866
|
+
fn: params.onSuccess,
|
|
1867
|
+
});
|
|
1868
|
+
}
|
|
1869
|
+
if (params.onComplete) {
|
|
1870
|
+
lifecycleHooks.registerTaskCompleteHook(taskId, {
|
|
1871
|
+
fn: params.onComplete,
|
|
1872
|
+
});
|
|
1873
|
+
}
|
|
1874
|
+
if (params.onWait) {
|
|
1875
|
+
lifecycleHooks.registerTaskWaitHook(taskId, {
|
|
1876
|
+
fn: params.onWait,
|
|
1877
|
+
});
|
|
1878
|
+
}
|
|
1879
|
+
if (params.onResume) {
|
|
1880
|
+
lifecycleHooks.registerTaskResumeHook(taskId, {
|
|
1881
|
+
fn: params.onResume,
|
|
1882
|
+
});
|
|
1883
|
+
}
|
|
1884
|
+
if (params.catchError) {
|
|
1885
|
+
// We don't need to use an adapter here because catchError is the new version of handleError
|
|
1886
|
+
lifecycleHooks.registerTaskCatchErrorHook(taskId, {
|
|
1887
|
+
fn: params.catchError,
|
|
1888
|
+
});
|
|
1889
|
+
}
|
|
1890
|
+
if (params.handleError) {
|
|
1891
|
+
lifecycleHooks.registerTaskCatchErrorHook(taskId, {
|
|
1892
|
+
fn: params.handleError,
|
|
1893
|
+
});
|
|
1894
|
+
}
|
|
1895
|
+
if (params.middleware) {
|
|
1896
|
+
lifecycleHooks.registerTaskMiddlewareHook(taskId, {
|
|
1897
|
+
fn: params.middleware,
|
|
1898
|
+
});
|
|
1899
|
+
}
|
|
1900
|
+
if (params.cleanup) {
|
|
1901
|
+
lifecycleHooks.registerTaskCleanupHook(taskId, {
|
|
1902
|
+
fn: params.cleanup,
|
|
1903
|
+
});
|
|
1904
|
+
}
|
|
1905
|
+
if (params.onCancel) {
|
|
1906
|
+
lifecycleHooks.registerTaskCancelHook(taskId, {
|
|
1907
|
+
fn: params.onCancel,
|
|
1908
|
+
});
|
|
1909
|
+
}
|
|
1910
|
+
}
|
|
1911
|
+
async function prepareTriggerPayload(payload, apiClient) {
|
|
1912
|
+
const payloadPacket = await stringifyIO(payload);
|
|
1913
|
+
// Measure the serialized size before any offload, so it reflects the real payload
|
|
1914
|
+
// size rather than the small "application/store" reference we may send instead.
|
|
1915
|
+
const { size: payloadSize } = packetRequiresOffloading(payloadPacket);
|
|
1916
|
+
const packet = await conditionallyExportPacket(payloadPacket, createTriggerPayloadPathPrefix(), undefined, apiClient);
|
|
1917
|
+
return { packet, payloadSize };
|
|
1918
|
+
}
|
|
1919
|
+
/**
|
|
1920
|
+
* Build the object-storage path prefix for an offloaded trigger payload.
|
|
1921
|
+
*
|
|
1922
|
+
* Every segment is generated here, so nothing caller-controlled reaches the key.
|
|
1923
|
+
* The id's alphabet is lowercase alphanumeric, which no layer between here and the
|
|
1924
|
+
* object store rewrites, so the path the SDK asks for is the path that gets stored.
|
|
1925
|
+
*/
|
|
1926
|
+
function createTriggerPayloadPathPrefix() {
|
|
1927
|
+
return `trigger/${generateFriendlyId("packet")}/payload`;
|
|
1928
|
+
}
|
|
1096
1929
|
//# sourceMappingURL=shared.js.map
|