@trigger.dev/sdk 4.5.0-rc.7 → 4.5.1

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.
Files changed (195) hide show
  1. package/dist/commonjs/v3/ai-shared.js +1 -4
  2. package/dist/commonjs/v3/ai-shared.js.map +1 -1
  3. package/dist/commonjs/v3/ai.d.ts +13 -10
  4. package/dist/commonjs/v3/ai.js +121 -66
  5. package/dist/commonjs/v3/ai.js.map +1 -1
  6. package/dist/commonjs/v3/auth.d.ts +1 -1
  7. package/dist/commonjs/v3/auth.js +3 -4
  8. package/dist/commonjs/v3/auth.js.map +1 -1
  9. package/dist/commonjs/v3/batch.d.ts +1 -1
  10. package/dist/commonjs/v3/batch.js.map +1 -1
  11. package/dist/commonjs/v3/chat-client.js +18 -14
  12. package/dist/commonjs/v3/chat-client.js.map +1 -1
  13. package/dist/commonjs/v3/chat-react.js +2 -4
  14. package/dist/commonjs/v3/chat-react.js.map +1 -1
  15. package/dist/commonjs/v3/chat-server.d.ts +69 -1
  16. package/dist/commonjs/v3/chat-server.js +162 -14
  17. package/dist/commonjs/v3/chat-server.js.map +1 -1
  18. package/dist/commonjs/v3/chat-server.test.js +156 -12
  19. package/dist/commonjs/v3/chat-server.test.js.map +1 -1
  20. package/dist/commonjs/v3/chat.js +4 -3
  21. package/dist/commonjs/v3/chat.js.map +1 -1
  22. package/dist/commonjs/v3/chat.test.js +9 -48
  23. package/dist/commonjs/v3/chat.test.js.map +1 -1
  24. package/dist/commonjs/v3/deployments.d.ts +2 -3
  25. package/dist/commonjs/v3/deployments.js.map +1 -1
  26. package/dist/commonjs/v3/envvars.js.map +1 -1
  27. package/dist/commonjs/v3/idempotencyKeys.js.map +1 -1
  28. package/dist/commonjs/v3/metadata.d.ts +2 -2
  29. package/dist/commonjs/v3/prompt.js +2 -6
  30. package/dist/commonjs/v3/prompt.js.map +1 -1
  31. package/dist/commonjs/v3/promptManagement.js.map +1 -1
  32. package/dist/commonjs/v3/query.js.map +1 -1
  33. package/dist/commonjs/v3/queues.d.ts +1 -1
  34. package/dist/commonjs/v3/queues.js.map +1 -1
  35. package/dist/commonjs/v3/retry.d.ts +1 -1
  36. package/dist/commonjs/v3/retry.js +1 -1
  37. package/dist/commonjs/v3/retry.js.map +1 -1
  38. package/dist/commonjs/v3/runs.d.ts +3 -4
  39. package/dist/commonjs/v3/runs.js.map +1 -1
  40. package/dist/commonjs/v3/schedules/index.d.ts +3 -3
  41. package/dist/commonjs/v3/schedules/index.js.map +1 -1
  42. package/dist/commonjs/v3/sessions.d.ts +3 -4
  43. package/dist/commonjs/v3/sessions.js +2 -1
  44. package/dist/commonjs/v3/sessions.js.map +1 -1
  45. package/dist/commonjs/v3/shared.d.ts +3 -4
  46. package/dist/commonjs/v3/shared.js +0 -12
  47. package/dist/commonjs/v3/shared.js.map +1 -1
  48. package/dist/commonjs/v3/skill.js.map +1 -1
  49. package/dist/commonjs/v3/streams.d.ts +1 -1
  50. package/dist/commonjs/v3/streams.js +4 -5
  51. package/dist/commonjs/v3/streams.js.map +1 -1
  52. package/dist/commonjs/v3/streams.test.js +3 -3
  53. package/dist/commonjs/v3/streams.test.js.map +1 -1
  54. package/dist/commonjs/v3/test/mock-chat-agent.js +1 -4
  55. package/dist/commonjs/v3/test/mock-chat-agent.js.map +1 -1
  56. package/dist/commonjs/v3/test/test-session-handle.d.ts +2 -1
  57. package/dist/commonjs/v3/test/test-session-handle.js.map +1 -1
  58. package/dist/commonjs/v3/triggerClient.test.js +1 -1
  59. package/dist/commonjs/v3/triggerClient.test.js.map +1 -1
  60. package/dist/commonjs/v3/triggerClient.types.test.js +11 -11
  61. package/dist/commonjs/v3/triggerClient.types.test.js.map +1 -1
  62. package/dist/commonjs/v3/wait.d.ts +2 -1
  63. package/dist/commonjs/v3/wait.js.map +1 -1
  64. package/dist/commonjs/v3/webhooks.js +1 -1
  65. package/dist/commonjs/v3/webhooks.js.map +1 -1
  66. package/dist/commonjs/version.js +1 -1
  67. package/dist/esm/v3/ai-shared.js +1 -4
  68. package/dist/esm/v3/ai-shared.js.map +1 -1
  69. package/dist/esm/v3/ai.d.ts +13 -10
  70. package/dist/esm/v3/ai.js +119 -54
  71. package/dist/esm/v3/ai.js.map +1 -1
  72. package/dist/esm/v3/auth.d.ts +1 -1
  73. package/dist/esm/v3/auth.js +1 -2
  74. package/dist/esm/v3/auth.js.map +1 -1
  75. package/dist/esm/v3/batch.d.ts +1 -1
  76. package/dist/esm/v3/batch.js +1 -1
  77. package/dist/esm/v3/batch.js.map +1 -1
  78. package/dist/esm/v3/chat-client.js +18 -14
  79. package/dist/esm/v3/chat-client.js.map +1 -1
  80. package/dist/esm/v3/chat-react.js +2 -4
  81. package/dist/esm/v3/chat-react.js.map +1 -1
  82. package/dist/esm/v3/chat-server.d.ts +69 -1
  83. package/dist/esm/v3/chat-server.js +162 -14
  84. package/dist/esm/v3/chat-server.js.map +1 -1
  85. package/dist/esm/v3/chat-server.test.js +156 -12
  86. package/dist/esm/v3/chat-server.test.js.map +1 -1
  87. package/dist/esm/v3/chat.js +4 -3
  88. package/dist/esm/v3/chat.js.map +1 -1
  89. package/dist/esm/v3/chat.test.js +9 -48
  90. package/dist/esm/v3/chat.test.js.map +1 -1
  91. package/dist/esm/v3/deployments.d.ts +2 -3
  92. package/dist/esm/v3/deployments.js +1 -1
  93. package/dist/esm/v3/deployments.js.map +1 -1
  94. package/dist/esm/v3/envvars.js.map +1 -1
  95. package/dist/esm/v3/idempotencyKeys.js +1 -1
  96. package/dist/esm/v3/idempotencyKeys.js.map +1 -1
  97. package/dist/esm/v3/metadata.d.ts +2 -2
  98. package/dist/esm/v3/prompt.js +2 -6
  99. package/dist/esm/v3/prompt.js.map +1 -1
  100. package/dist/esm/v3/promptManagement.js.map +1 -1
  101. package/dist/esm/v3/query.js.map +1 -1
  102. package/dist/esm/v3/queues.d.ts +1 -1
  103. package/dist/esm/v3/queues.js.map +1 -1
  104. package/dist/esm/v3/retry.d.ts +1 -1
  105. package/dist/esm/v3/retry.js +1 -1
  106. package/dist/esm/v3/retry.js.map +1 -1
  107. package/dist/esm/v3/runs.d.ts +2 -3
  108. package/dist/esm/v3/runs.js.map +1 -1
  109. package/dist/esm/v3/schedules/index.d.ts +3 -3
  110. package/dist/esm/v3/schedules/index.js.map +1 -1
  111. package/dist/esm/v3/sessions.d.ts +3 -4
  112. package/dist/esm/v3/sessions.js +2 -1
  113. package/dist/esm/v3/sessions.js.map +1 -1
  114. package/dist/esm/v3/shared.d.ts +3 -4
  115. package/dist/esm/v3/shared.js +1 -13
  116. package/dist/esm/v3/shared.js.map +1 -1
  117. package/dist/esm/v3/skill.js.map +1 -1
  118. package/dist/esm/v3/streams.d.ts +1 -1
  119. package/dist/esm/v3/streams.js +4 -5
  120. package/dist/esm/v3/streams.js.map +1 -1
  121. package/dist/esm/v3/streams.test.js +4 -4
  122. package/dist/esm/v3/streams.test.js.map +1 -1
  123. package/dist/esm/v3/test/mock-chat-agent.js +4 -7
  124. package/dist/esm/v3/test/mock-chat-agent.js.map +1 -1
  125. package/dist/esm/v3/test/test-session-handle.d.ts +2 -1
  126. package/dist/esm/v3/test/test-session-handle.js +1 -1
  127. package/dist/esm/v3/test/test-session-handle.js.map +1 -1
  128. package/dist/esm/v3/triggerClient.test.js +1 -1
  129. package/dist/esm/v3/triggerClient.test.js.map +1 -1
  130. package/dist/esm/v3/triggerClient.types.test.js +11 -11
  131. package/dist/esm/v3/triggerClient.types.test.js.map +1 -1
  132. package/dist/esm/v3/wait.d.ts +2 -1
  133. package/dist/esm/v3/wait.js.map +1 -1
  134. package/dist/esm/v3/webhooks.js +1 -1
  135. package/dist/esm/v3/webhooks.js.map +1 -1
  136. package/dist/esm/version.js +1 -1
  137. package/docs/ai/prompts.mdx +0 -4
  138. package/docs/ai-chat/actions.mdx +0 -4
  139. package/docs/ai-chat/anatomy.mdx +0 -4
  140. package/docs/ai-chat/backend.mdx +0 -4
  141. package/docs/ai-chat/background-injection.mdx +0 -4
  142. package/docs/ai-chat/changelog.mdx +109 -1
  143. package/docs/ai-chat/chat-local.mdx +0 -4
  144. package/docs/ai-chat/client-protocol.mdx +0 -4
  145. package/docs/ai-chat/compaction.mdx +0 -4
  146. package/docs/ai-chat/custom-agents.mdx +32 -4
  147. package/docs/ai-chat/error-handling.mdx +0 -4
  148. package/docs/ai-chat/fast-starts.mdx +86 -4
  149. package/docs/ai-chat/frontend.mdx +0 -4
  150. package/docs/ai-chat/how-it-works.mdx +0 -4
  151. package/docs/ai-chat/lifecycle-hooks.mdx +0 -4
  152. package/docs/ai-chat/mcp.mdx +0 -4
  153. package/docs/ai-chat/overview.mdx +0 -4
  154. package/docs/ai-chat/patterns/branching-conversations.mdx +0 -4
  155. package/docs/ai-chat/patterns/code-sandbox.mdx +0 -4
  156. package/docs/ai-chat/patterns/database-persistence.mdx +0 -4
  157. package/docs/ai-chat/patterns/human-in-the-loop.mdx +9 -5
  158. package/docs/ai-chat/patterns/large-payloads.mdx +0 -4
  159. package/docs/ai-chat/patterns/oom-resilience.mdx +0 -4
  160. package/docs/ai-chat/patterns/persistence-and-replay.mdx +0 -4
  161. package/docs/ai-chat/patterns/recovery-boot.mdx +0 -4
  162. package/docs/ai-chat/patterns/skills.mdx +0 -4
  163. package/docs/ai-chat/patterns/sub-agents.mdx +0 -4
  164. package/docs/ai-chat/patterns/tool-result-auditing.mdx +0 -4
  165. package/docs/ai-chat/patterns/trusted-edge-signals.mdx +0 -4
  166. package/docs/ai-chat/patterns/version-upgrades.mdx +0 -4
  167. package/docs/ai-chat/pending-messages.mdx +0 -4
  168. package/docs/ai-chat/prompt-caching.mdx +4 -4
  169. package/docs/ai-chat/quick-start.mdx +0 -4
  170. package/docs/ai-chat/reference.mdx +1 -5
  171. package/docs/ai-chat/server-chat.mdx +0 -4
  172. package/docs/ai-chat/sessions.mdx +0 -4
  173. package/docs/ai-chat/testing.mdx +0 -4
  174. package/docs/ai-chat/tools.mdx +0 -4
  175. package/docs/ai-chat/types.mdx +0 -4
  176. package/docs/ai-chat/upgrade-guide.mdx +0 -4
  177. package/docs/building-with-ai.mdx +1 -1
  178. package/docs/deploy-environment-variables.mdx +1 -1
  179. package/docs/deployment/dev-branches.mdx +92 -0
  180. package/docs/deployment/overview.mdx +1 -1
  181. package/docs/help-slack.mdx +1 -0
  182. package/docs/how-to-reduce-your-spend.mdx +14 -7
  183. package/docs/introduction.mdx +13 -13
  184. package/docs/mcp-agent-rules.mdx +1 -1
  185. package/docs/open-source-self-hosting.mdx +1 -1
  186. package/docs/self-hosting/kubernetes.mdx +8 -8
  187. package/docs/self-hosting/overview.mdx +2 -1
  188. package/docs/tasks/scheduled.mdx +2 -2
  189. package/docs/troubleshooting-debugging-in-vscode.mdx +1 -0
  190. package/docs/troubleshooting-github-issues.mdx +1 -1
  191. package/docs/troubleshooting-uptime-status.mdx +1 -0
  192. package/docs/video-walkthrough.mdx +1 -1
  193. package/docs/wait-for.mdx +1 -1
  194. package/package.json +2 -2
  195. package/docs/cli-dev.mdx +0 -8
package/dist/esm/v3/ai.js CHANGED
@@ -1,8 +1,9 @@
1
- import { accessoryAttributes, apiClientManager, controlSubtype, getSchemaParseFn, headerValue, InputStreamOncePromise, isSchemaZodEsque, logger, ManualWaitpointPromise, OutOfMemoryError, sessionStreams, SemanticInternalAttributes, taskContext, SESSION_IN_EVENT_ID_HEADER, TRIGGER_CONTROL_SUBTYPE, generateJWT, } from "@trigger.dev/core/v3";
1
+ import { accessoryAttributes, apiClientManager, controlSubtype, generateJWT, getSchemaParseFn, headerValue, InputStreamOncePromise, isSchemaZodEsque, logger, ManualWaitpointPromise, OutOfMemoryError, resourceCatalog, SemanticInternalAttributes, SESSION_IN_EVENT_ID_HEADER, sessionStreams, taskContext, TRIGGER_CONTROL_SUBTYPE, } from "@trigger.dev/core/v3";
2
2
  // Runtime VALUES go through the ESM/CJS shim so the CJS build can `require`
3
3
  // ESM-only `ai@7` (see ../imports/ai-runtime.ts).
4
- import { convertToModelMessages, dynamicTool, generateId as generateMessageId, getToolName, isToolUIPart, jsonSchema, readUIMessageStream, tool as aiTool, zodSchema, } from "../imports/ai-runtime.js";
5
4
  import { trace } from "@opentelemetry/api";
5
+ import { tool as aiTool, convertToModelMessages, dynamicTool, generateId as generateMessageId, getToolName, isToolUIPart, jsonSchema, readUIMessageStream, zodSchema, } from "../imports/ai-runtime.js";
6
+ import { PENDING_MESSAGE_INJECTED_TYPE, upsertIncomingMessage, } from "./ai-shared.js";
6
7
  import { auth } from "./auth.js";
7
8
  import { locals } from "./locals.js";
8
9
  import { metadata } from "./metadata.js";
@@ -14,12 +15,11 @@ import { metadata } from "./metadata.js";
14
15
  // that wants those primitives imports `./ai-shared.js` directly and
15
16
  // never touches `ai.ts`'s module graph, so the `node:*` builtins
16
17
  // pulled in transitively here never reach a client chunk.
17
- import { runBashInSkill, readFileInSkill } from "./agentSkillsRuntime.js";
18
- import { markChatAgentRunForStreamsWarning } from "./streams.js";
18
+ import { readFileInSkill, runBashInSkill } from "./agentSkillsRuntime.js";
19
+ import { ensureAiSdkTelemetry } from "./aiAutoTelemetry.js";
19
20
  import { sessions, } from "./sessions.js";
20
21
  import { createTask } from "./shared.js";
21
- import { ensureAiSdkTelemetry } from "./aiAutoTelemetry.js";
22
- import { resourceCatalog } from "@trigger.dev/core/v3";
22
+ import { markChatAgentRunForStreamsWarning } from "./streams.js";
23
23
  import { tracer } from "./tracer.js";
24
24
  const METADATA_KEY = "tool.execute.options";
25
25
  /**
@@ -141,7 +141,9 @@ async function seedSessionInResumeCursorForCustomLoop(payload) {
141
141
  }
142
142
  }
143
143
  catch (error) {
144
- logger.warn("chat session: session.in resume cursor lookup failed; old messages may replay", { error: error instanceof Error ? error.message : String(error) });
144
+ logger.warn("chat session: session.in resume cursor lookup failed; old messages may replay", {
145
+ error: error instanceof Error ? error.message : String(error),
146
+ });
145
147
  }
146
148
  }
147
149
  let readChatSnapshotImpl;
@@ -1227,8 +1229,7 @@ const handoverInput = {
1227
1229
  const result = await getChatSession().in.waitWithIdleTimeout(options);
1228
1230
  if (!result.ok)
1229
1231
  return result;
1230
- if (result.output.kind === "handover" ||
1231
- result.output.kind === "handover-skip") {
1232
+ if (result.output.kind === "handover" || result.output.kind === "handover-skip") {
1232
1233
  return { ok: true, output: result.output };
1233
1234
  }
1234
1235
  // Other kinds (message, stop) are not expected during handover-prepare.
@@ -1893,8 +1894,7 @@ const chatAgentCompactionKey = locals.create("chat.agentCompaction");
1893
1894
  // React hooks (`@trigger.dev/sdk/chat/react`) can import it without
1894
1895
  // dragging `ai.ts` into the browser graph. Re-exported here so
1895
1896
  // `@trigger.dev/sdk/ai` consumers still see it.
1896
- export { PENDING_MESSAGE_INJECTED_TYPE, upsertIncomingMessage } from "./ai-shared.js";
1897
- import { PENDING_MESSAGE_INJECTED_TYPE } from "./ai-shared.js";
1897
+ export { PENDING_MESSAGE_INJECTED_TYPE, upsertIncomingMessage };
1898
1898
  /** @internal */
1899
1899
  const chatPendingMessagesKey = locals.create("chat.pendingMessages");
1900
1900
  /** @internal */
@@ -1939,6 +1939,55 @@ function isStepBoundarySafe(step) {
1939
1939
  .map((p) => p.toolCallId));
1940
1940
  return ![...callIds].some((id) => !settledIds.has(id));
1941
1941
  }
1942
+ /**
1943
+ * True when a model message is a `tool` message carrying a
1944
+ * `tool-approval-response` part — the trailing row a head-start handover
1945
+ * reshapes a pending first-turn tool call into. AI SDK's `collectToolApprovals`
1946
+ * only inspects the conversation's last message, so this row must survive to
1947
+ * `streamText` intact for the agent to execute the handed-over call.
1948
+ * @internal
1949
+ */
1950
+ function hasToolApprovalResponse(message) {
1951
+ return (message?.role === "tool" &&
1952
+ Array.isArray(message.content) &&
1953
+ message.content.some((part) => part != null &&
1954
+ typeof part === "object" &&
1955
+ part.type === "tool-approval-response"));
1956
+ }
1957
+ /**
1958
+ * Keep a head-start handover's tool-approval tail intact across `prepareMessages`.
1959
+ *
1960
+ * The handover reshapes the warm step-1's pending tool call into AI SDK's
1961
+ * tool-approval round: a `tool-approval-request` on the assistant plus a
1962
+ * trailing `tool` message with `tool-approval-response { approved: true }`. The
1963
+ * agent's next `streamText` runs `collectToolApprovals`, which ONLY looks at the
1964
+ * last message — so that tool row must stay last and unmodified for the pending
1965
+ * call to execute. A user `prepareMessages` hook that rewrites or drops the last
1966
+ * message (e.g. rolling a provider cache breakpoint onto it) silently breaks the
1967
+ * resume: the agent sends a bare `tool_use` and the turn dies with
1968
+ * "tool_use ids were found without tool_result". If the hook's input ended with
1969
+ * that approval tail, re-assert the original tail as the last message.
1970
+ *
1971
+ * No-op for every normal turn — only fires when the input genuinely ended with a
1972
+ * pending tool-approval response (i.e. a head-start resume).
1973
+ * @internal
1974
+ */
1975
+ function preserveToolApprovalTail(original, prepared) {
1976
+ const originalTail = original[original.length - 1];
1977
+ if (!hasToolApprovalResponse(originalTail))
1978
+ return prepared;
1979
+ // Hook left the exact tail object in place — nothing to do.
1980
+ if (prepared[prepared.length - 1] === originalTail)
1981
+ return prepared;
1982
+ // Otherwise drop only the trailing approval tail the hook produced (the
1983
+ // original moved, or a rewritten copy) and re-append the original so it is
1984
+ // last and intact. Older approval rounds deeper in history must survive.
1985
+ const withoutMovedOriginal = prepared.filter((m) => m !== originalTail);
1986
+ while (hasToolApprovalResponse(withoutMovedOriginal[withoutMovedOriginal.length - 1])) {
1987
+ withoutMovedOriginal.pop();
1988
+ }
1989
+ return [...withoutMovedOriginal, originalTail];
1990
+ }
1942
1991
  /**
1943
1992
  * Apply the prepareMessages hook if one is set in locals.
1944
1993
  * @internal
@@ -1948,7 +1997,7 @@ async function applyPrepareMessages(messages, reason) {
1948
1997
  if (!hook)
1949
1998
  return messages;
1950
1999
  const turnCtx = locals.get(chatTurnContextKey);
1951
- return tracer.startActiveSpan("prepareMessages()", async () => {
2000
+ const prepared = await tracer.startActiveSpan("prepareMessages()", async () => {
1952
2001
  return hook({
1953
2002
  messages,
1954
2003
  reason,
@@ -1964,6 +2013,9 @@ async function applyPrepareMessages(messages, reason) {
1964
2013
  "chat.prepareMessages.messageCount": messages.length,
1965
2014
  },
1966
2015
  });
2016
+ // A user hook must never be able to break the head-start handover resume by
2017
+ // disturbing the trailing tool-approval row (see preserveToolApprovalTail).
2018
+ return preserveToolApprovalTail(messages, prepared);
1967
2019
  }
1968
2020
  /**
1969
2021
  * Resolve the `tools` option into a concrete `ToolSet` and cache it in locals so
@@ -2234,7 +2286,7 @@ async function drainSteeringQueue(config, messages, steps, queueOverride) {
2234
2286
  .filter((p) => p.type === "text")
2235
2287
  .map((p) => p.text)
2236
2288
  .join("") || "");
2237
- const previewText = messageTexts.length === 1 ? messageTexts[0].slice(0, 80) : `${queue.length} messages`;
2289
+ const _previewText = messageTexts.length === 1 ? messageTexts[0].slice(0, 80) : `${queue.length} messages`;
2238
2290
  return tracer.startActiveSpan("pending message injected", async () => {
2239
2291
  // Transform the batch — default: concatenate all pre-converted model messages
2240
2292
  const injected = config.prepare
@@ -2912,7 +2964,9 @@ function chatAgent(options) {
2912
2964
  const replayOutPhase = async () => {
2913
2965
  const replayOutStart = Date.now();
2914
2966
  try {
2915
- const replayResult = await replaySessionOutTail(sessionIdForSnapshot, { lastEventId: bootSnapshot?.lastOutEventId });
2967
+ const replayResult = await replaySessionOutTail(sessionIdForSnapshot, {
2968
+ lastEventId: bootSnapshot?.lastOutEventId,
2969
+ });
2916
2970
  replayedSettled = replayResult.settled;
2917
2971
  replayedPartial = replayResult.partial;
2918
2972
  replayedPartialRaw = replayResult.partialRaw;
@@ -3009,9 +3063,7 @@ function chatAgent(options) {
3009
3063
  // crashed / was canceled / requested upgrade
3010
3064
  // - Snapshot exists at all (catches edge cases where the wire
3011
3065
  // didn't set `continuation` but a snapshot indicates prior turns)
3012
- const needsResumeCursor = ctx.attempt.number > 1 ||
3013
- payload.continuation === true ||
3014
- bootSnapshot !== undefined;
3066
+ const needsResumeCursor = ctx.attempt.number > 1 || payload.continuation === true || bootSnapshot !== undefined;
3015
3067
  if (needsResumeCursor) {
3016
3068
  try {
3017
3069
  // Reuse the cursor the boot block already resolved (snapshot
@@ -3358,9 +3410,7 @@ function chatAgent(options) {
3358
3410
  // Wait for the first real message — task-level idle settings win over
3359
3411
  // `transport.preload(..., { idleTimeoutInSeconds })` / wire payload so
3360
3412
  // `chat.agent({ idleTimeoutInSeconds, preloadIdleTimeoutInSeconds })` is authoritative.
3361
- const effectivePreloadIdleTimeout = preloadIdleTimeoutInSeconds ??
3362
- idleTimeoutInSeconds ??
3363
- payload.idleTimeoutInSeconds;
3413
+ const effectivePreloadIdleTimeout = preloadIdleTimeoutInSeconds ?? idleTimeoutInSeconds ?? payload.idleTimeoutInSeconds;
3364
3414
  const effectivePreloadTimeout = metadata.get(TURN_TIMEOUT_METADATA_KEY) ??
3365
3415
  preloadTimeout ??
3366
3416
  turnTimeout;
@@ -3605,7 +3655,9 @@ function chatAgent(options) {
3605
3655
  if (lastUserMessage) {
3606
3656
  turnAttributes["chat.user_message"] = lastUserMessage;
3607
3657
  // Show a truncated preview of the user message as an accessory
3608
- const preview = lastUserMessage.length > 80 ? lastUserMessage.slice(0, 80) + "..." : lastUserMessage;
3658
+ const preview = lastUserMessage.length > 80
3659
+ ? lastUserMessage.slice(0, 80) + "..."
3660
+ : lastUserMessage;
3609
3661
  Object.assign(turnAttributes, accessoryAttributes({
3610
3662
  items: [{ text: preview, variant: "normal" }],
3611
3663
  style: "codepath",
@@ -3892,8 +3944,7 @@ function chatAgent(options) {
3892
3944
  if (currentWirePayload.trigger === "submit-message" &&
3893
3945
  cleanedUIMessages.length > 0) {
3894
3946
  const lastUI = cleanedUIMessages[cleanedUIMessages.length - 1];
3895
- const matchedExisting = lastUI.id !== undefined &&
3896
- previouslyKnownMessageIds.has(lastUI.id);
3947
+ const matchedExisting = lastUI.id !== undefined && previouslyKnownMessageIds.has(lastUI.id);
3897
3948
  if (!matchedExisting) {
3898
3949
  turnNewUIMessages.push(lastUI);
3899
3950
  const lastModel = (await toModelMessages([lastUI]))[0];
@@ -4228,7 +4279,8 @@ function chatAgent(options) {
4228
4279
  // We call toUIMessageStream ourselves to attach onFinish for response capture.
4229
4280
  // Pass originalMessages so the AI SDK reuses message IDs across turns
4230
4281
  // (e.g. for tool approval continuations / HITL flows).
4231
- if ((locals.get(chatPipeCountKey) ?? 0) === 0 && isUIMessageStreamable(runResult)) {
4282
+ if ((locals.get(chatPipeCountKey) ?? 0) === 0 &&
4283
+ isUIMessageStreamable(runResult)) {
4232
4284
  onFinishAttached = true;
4233
4285
  const resolvedOptions = resolveUIMessageStreamOptions();
4234
4286
  // For action turns, don't pass originalMessages: the response
@@ -4241,9 +4293,7 @@ function chatAgent(options) {
4241
4293
  // Pass originalMessages so the AI SDK reuses message IDs across
4242
4294
  // turns (e.g. for tool approval continuations / HITL flows).
4243
4295
  // Omit for action turns to force a fresh response ID.
4244
- ...(isActionTurn
4245
- ? {}
4246
- : { originalMessages: accumulatedUIMessages }),
4296
+ ...(isActionTurn ? {} : { originalMessages: accumulatedUIMessages }),
4247
4297
  // Always provide generateMessageId so the start chunk carries a
4248
4298
  // messageId. Without this, the frontend and backend generate IDs
4249
4299
  // independently and they won't match for ID-based dedup.
@@ -4254,7 +4304,10 @@ function chatAgent(options) {
4254
4304
  resolveOnFinish();
4255
4305
  },
4256
4306
  });
4257
- await pipeChat(uiStream, { signal: combinedSignal, spanName: "stream response" });
4307
+ await pipeChat(uiStream, {
4308
+ signal: combinedSignal,
4309
+ spanName: "stream response",
4310
+ });
4258
4311
  }
4259
4312
  }
4260
4313
  catch (error) {
@@ -4289,7 +4342,8 @@ function chatAgent(options) {
4289
4342
  // never reports final usage), which would block the turn loop
4290
4343
  // from ever firing onTurnComplete / writeTurnComplete.
4291
4344
  let turnUsage;
4292
- if (runResult != null && typeof runResult.totalUsage?.then === "function") {
4345
+ if (runResult != null &&
4346
+ typeof runResult.totalUsage?.then === "function") {
4293
4347
  try {
4294
4348
  turnUsage = (await Promise.race([
4295
4349
  runResult.totalUsage,
@@ -4375,7 +4429,10 @@ function chatAgent(options) {
4375
4429
  // may produce a message with an empty ID since IDs are normally
4376
4430
  // assigned by the frontend's useChat).
4377
4431
  if (!capturedResponseMessage.id) {
4378
- capturedResponseMessage = { ...capturedResponseMessage, id: generateMessageId() };
4432
+ capturedResponseMessage = {
4433
+ ...capturedResponseMessage,
4434
+ id: generateMessageId(),
4435
+ };
4379
4436
  }
4380
4437
  // Append any non-transient data parts queued via chat.response or writer.write()
4381
4438
  const queuedParts = locals.get(chatResponsePartsKey);
@@ -4676,7 +4733,9 @@ function chatAgent(options) {
4676
4733
  ? { "gen_ai.usage.total_tokens": turnUsage.totalTokens }
4677
4734
  : {}),
4678
4735
  ...(cumulativeUsage.totalTokens != null
4679
- ? { "gen_ai.usage.cumulative_total_tokens": cumulativeUsage.totalTokens }
4736
+ ? {
4737
+ "gen_ai.usage.cumulative_total_tokens": cumulativeUsage.totalTokens,
4738
+ }
4680
4739
  : {}),
4681
4740
  },
4682
4741
  });
@@ -4708,9 +4767,7 @@ function chatAgent(options) {
4708
4767
  savedAt: Date.now(),
4709
4768
  messages: accumulatedUIMessages,
4710
4769
  lastOutEventId: turnCompleteResult?.lastEventId,
4711
- lastInEventId: snapshotInCursor !== undefined
4712
- ? String(snapshotInCursor)
4713
- : undefined,
4770
+ lastInEventId: snapshotInCursor !== undefined ? String(snapshotInCursor) : undefined,
4714
4771
  });
4715
4772
  }, {
4716
4773
  attributes: {
@@ -4752,8 +4809,7 @@ function chatAgent(options) {
4752
4809
  // chat.requestUpgrade() was called — exit the loop so the
4753
4810
  // transport triggers a new run on the latest version.
4754
4811
  // chat.endRun() — same exit, no upgrade semantics.
4755
- if (locals.get(chatUpgradeRequestedKey) ||
4756
- locals.get(chatEndRunRequestedKey)) {
4812
+ if (locals.get(chatUpgradeRequestedKey) || locals.get(chatEndRunRequestedKey)) {
4757
4813
  return "exit";
4758
4814
  }
4759
4815
  // Wait for the next message — stay idle briefly, then suspend
@@ -4833,7 +4889,9 @@ function chatAgent(options) {
4833
4889
  // Turn error handler: write an error chunk + turn-complete to the stream
4834
4890
  // so the client sees the error, then wait for the next message instead
4835
4891
  // of killing the entire run. This keeps the conversation alive.
4836
- if (turnError instanceof Error && turnError.name === "AbortError" && runSignal.aborted) {
4892
+ if (turnError instanceof Error &&
4893
+ turnError.name === "AbortError" &&
4894
+ runSignal.aborted) {
4837
4895
  // Full run cancellation — exit immediately
4838
4896
  throw turnError;
4839
4897
  }
@@ -4929,9 +4987,7 @@ function chatAgent(options) {
4929
4987
  savedAt: Date.now(),
4930
4988
  messages: erroredUIMessages,
4931
4989
  lastOutEventId: errorTurnCompleteResult?.lastEventId,
4932
- lastInEventId: errorSnapshotInCursor !== undefined
4933
- ? String(errorSnapshotInCursor)
4934
- : undefined,
4990
+ lastInEventId: errorSnapshotInCursor !== undefined ? String(errorSnapshotInCursor) : undefined,
4935
4991
  });
4936
4992
  }
4937
4993
  catch (error) {
@@ -4942,8 +4998,7 @@ function chatAgent(options) {
4942
4998
  }
4943
4999
  }
4944
5000
  // chat.requestUpgrade() / chat.endRun() — exit after error turn too
4945
- if (locals.get(chatUpgradeRequestedKey) ||
4946
- locals.get(chatEndRunRequestedKey)) {
5001
+ if (locals.get(chatUpgradeRequestedKey) || locals.get(chatEndRunRequestedKey)) {
4947
5002
  return;
4948
5003
  }
4949
5004
  // Drain remaining recovered turns before idling — a thrown
@@ -4976,7 +5031,7 @@ function chatAgent(options) {
4976
5031
  // cleanup so a missing subscription doesn't throw.
4977
5032
  stopSub?.off();
4978
5033
  }
4979
- }
5034
+ },
4980
5035
  });
4981
5036
  // Register clientDataSchema so the CLI converts it to JSONSchema
4982
5037
  // and stores it as payloadSchema — used by the Playground UI
@@ -5068,7 +5123,7 @@ function createChatBuilder(config) {
5068
5123
  agent(options) {
5069
5124
  const mergedUiStream = config.uiStreamOptions && options.uiMessageStreamOptions
5070
5125
  ? { ...config.uiStreamOptions, ...options.uiMessageStreamOptions }
5071
- : options.uiMessageStreamOptions ?? config.uiStreamOptions;
5126
+ : (options.uiMessageStreamOptions ?? config.uiStreamOptions);
5072
5127
  return chatAgent({
5073
5128
  ...options,
5074
5129
  ...(config.clientDataSchema ? { clientDataSchema: config.clientDataSchema } : {}),
@@ -5896,7 +5951,9 @@ function createChatSession(payload, options) {
5896
5951
  if (turn === 0 && currentPayload.trigger === "handover-prepare") {
5897
5952
  const signal = await waitForHandover({
5898
5953
  payload: currentPayload,
5899
- idleTimeoutInSeconds: sessionIdleTimeoutOpt ?? currentPayload.idleTimeoutInSeconds ?? idleTimeoutInSeconds,
5954
+ idleTimeoutInSeconds: sessionIdleTimeoutOpt ??
5955
+ currentPayload.idleTimeoutInSeconds ??
5956
+ idleTimeoutInSeconds,
5900
5957
  timeout,
5901
5958
  });
5902
5959
  if (!signal || signal.kind === "handover-skip" || runSignal.aborted) {
@@ -5915,7 +5972,8 @@ function createChatSession(payload, options) {
5915
5972
  // arrive with the sticky boot-payload fields stripped, so running
5916
5973
  // a turn immediately would invoke the model with no user input.
5917
5974
  const isMessagelessContinuationBoot = currentPayload.continuation === true && !currentPayload.message;
5918
- if (turn === 0 && (currentPayload.trigger === "preload" || isMessagelessContinuationBoot)) {
5975
+ if (turn === 0 &&
5976
+ (currentPayload.trigger === "preload" || isMessagelessContinuationBoot)) {
5919
5977
  const result = await messagesInput.waitWithIdleTimeout({
5920
5978
  idleTimeoutInSeconds: sessionIdleTimeoutOpt ?? currentPayload.idleTimeoutInSeconds ?? 30,
5921
5979
  timeout,
@@ -5939,8 +5997,7 @@ function createChatSession(payload, options) {
5939
5997
  // Subsequent turns: wait for the next message
5940
5998
  if (turn > 0) {
5941
5999
  // chat.requestUpgrade() / chat.endRun() — exit before waiting
5942
- if (locals.get(chatUpgradeRequestedKey) ||
5943
- locals.get(chatEndRunRequestedKey)) {
6000
+ if (locals.get(chatUpgradeRequestedKey) || locals.get(chatEndRunRequestedKey)) {
5944
6001
  stop.cleanup();
5945
6002
  return { done: true, value: undefined };
5946
6003
  }
@@ -6014,7 +6071,7 @@ function createChatSession(payload, options) {
6014
6071
  const incomingForAccumulator = currentPayload.message
6015
6072
  ? [currentPayload.message]
6016
6073
  : [];
6017
- const messages = await accumulator.addIncoming(incomingForAccumulator, currentPayload.trigger, turn);
6074
+ const _messages = await accumulator.addIncoming(incomingForAccumulator, currentPayload.trigger, turn);
6018
6075
  // Apply the head-start handover AFTER addIncoming — turn-0 addIncoming
6019
6076
  // replaces accumulator state, which would wipe a pre-applied splice.
6020
6077
  // Seed prior history first, then splice the warm step-1 partial.
@@ -6187,7 +6244,8 @@ function createChatSession(payload, options) {
6187
6244
  },
6188
6245
  ];
6189
6246
  if (sessionCompaction.compactUIMessages) {
6190
- accumulator.uiMessages = await sessionCompaction.compactUIMessages(compactEvent);
6247
+ accumulator.uiMessages =
6248
+ await sessionCompaction.compactUIMessages(compactEvent);
6191
6249
  }
6192
6250
  }
6193
6251
  }
@@ -6199,7 +6257,10 @@ function createChatSession(payload, options) {
6199
6257
  // Append any non-transient data parts queued via chat.response or writer.write()
6200
6258
  const queuedParts = locals.get(chatResponsePartsKey);
6201
6259
  if (queuedParts && queuedParts.length > 0) {
6202
- response = { ...response, parts: [...(response.parts ?? []), ...queuedParts] };
6260
+ response = {
6261
+ ...response,
6262
+ parts: [...(response.parts ?? []), ...queuedParts],
6263
+ };
6203
6264
  locals.set(chatResponsePartsKey, []);
6204
6265
  }
6205
6266
  await accumulator.addResponse(response);
@@ -6468,6 +6529,12 @@ function createChatStartSessionAction(taskId, options) {
6468
6529
  if (!params.chatId) {
6469
6530
  throw new Error("chat.createStartSessionAction: params.chatId is required — used as the session externalId.");
6470
6531
  }
6532
+ // Scope the action to `apiClient`'s env: re-enter without it so the body
6533
+ // runs once, under that config (read via apiClientManager.accessToken/.baseURL).
6534
+ if (options?.apiClient) {
6535
+ const { apiClient, ...rest } = options;
6536
+ return apiClientManager.runWithConfig(apiClient, () => createChatStartSessionAction(taskId, rest)(params));
6537
+ }
6471
6538
  // The first run boots before the user's first message lands on
6472
6539
  // `.in/append`, so it sees an empty `messages` array and `trigger:
6473
6540
  // "preload"`. This matches the pre-Sessions preload semantics:
@@ -6575,9 +6642,7 @@ function createChatStartSessionAction(taskId, options) {
6575
6642
  }
6576
6643
  function resolveChatStartBaseURL(endpoint, chatId, option) {
6577
6644
  const fallback = apiClientManager.baseURL ?? "https://api.trigger.dev";
6578
- const raw = typeof option === "function"
6579
- ? option({ endpoint, chatId })
6580
- : option ?? fallback;
6645
+ const raw = typeof option === "function" ? option({ endpoint, chatId }) : (option ?? fallback);
6581
6646
  return raw.replace(/\/$/, "");
6582
6647
  }
6583
6648
  function overrideRequestHeaders(accessToken) {