-
-
Notifications
You must be signed in to change notification settings - Fork 1.1k
feat: Support parallel waits (native Promise.all) #3346
Description
Is your feature request related to a problem? Please describe.
Missing parallel waits (e.g., in Promise.all or just used by tools you don't control like Vercel AI SDK) is a potential deal-breaker for many agentic workflows, because it breaks quite natural behavior in the JS ecosystem.
In other words, AI agents cannot call trigger.dev subtasks themselves autonomously if they happen to call more than one tool that uses a subtask.
In other words, tasks themselves are NOT a valid, native primitive in AI/agentic flows or operations if any form of concurrency is required.
This is worse than it sounds in the first place. In some way it breaks the value-add provided by trigger dev.
The concept behind tools is dependency injection, so things like batchTriggerAndWait aren't helpful workarounds here. It's crazy to watch your entire code base and npm dependencies for nested Promise.all calls (a native primitive thought to be simply functioning in JS).
Also, for some models, preventing parallel tool calls might still be best effort not all have parallel_tool_calls: false
Of course you can use functions instead of subtask-triggering, but then you cannot vary machine sizes or other options like retries depending on the task type - which makes this an either or - use JS-native primitives OR be able to leverage the Trigger.dev primitives/features
I'm thinking about writing a helper that somehow collects all native trigger-invocations in a tick or some time-span, then batches them into one triggerByTaskAndWait call, then resolves them back to their respective call sites. But I feel strongly that should not be in userland, plus it's brittle and does not correctly represent the actual behavior of Promise.all.
Describe the solution you'd like to see
await Promise.all(multiplePromisesTriggeringTasks)or
await generateText({
messages: [systemMessage, userMessage],
// ....
tools: {
searchWeb: makeSearchWebTool({
searchWeb: effectiveSearchWeb,
}),
visitUrl: makeVisitUrlTool({
contentMode: VisitUrlToolContentMode.SAMPLED_MARKDOWN,
visitUrl: effectiveVisitUrl,
}),
},
})Should "just work" - when these tools might trigger new task runs concurrently - which would cause multiple parallel waits.
Describe alternate solutions
Requiring special wrappers would be ok, too:
await someSpecialWrapperHandlingMultipleAwaits(Promise.all(multiplePromisesTriggeringTasks))Additional information
No response