@trigger.dev/sdk 4.8.1 → 4.8.2

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 (89) hide show
  1. package/dist/commonjs/v3/ai-shared.d.ts +6 -0
  2. package/dist/commonjs/v3/ai-shared.js +7 -1
  3. package/dist/commonjs/v3/ai-shared.js.map +1 -1
  4. package/dist/commonjs/v3/ai.d.ts +45 -0
  5. package/dist/commonjs/v3/ai.js +110 -69
  6. package/dist/commonjs/v3/ai.js.map +1 -1
  7. package/dist/commonjs/v3/auth.d.ts +2 -1
  8. package/dist/commonjs/v3/auth.js +18 -12
  9. package/dist/commonjs/v3/auth.js.map +1 -1
  10. package/dist/commonjs/v3/chat-client.d.ts +11 -2
  11. package/dist/commonjs/v3/chat-client.js +28 -10
  12. package/dist/commonjs/v3/chat-client.js.map +1 -1
  13. package/dist/commonjs/v3/chat-react.d.ts +21 -0
  14. package/dist/commonjs/v3/chat-react.js +86 -30
  15. package/dist/commonjs/v3/chat-react.js.map +1 -1
  16. package/dist/commonjs/v3/chat.d.ts +1 -0
  17. package/dist/commonjs/v3/chat.js +4 -1
  18. package/dist/commonjs/v3/chat.js.map +1 -1
  19. package/dist/commonjs/v3/managedChatResponse.d.ts +13 -5
  20. package/dist/commonjs/v3/managedChatResponse.js +36 -18
  21. package/dist/commonjs/v3/managedChatResponse.js.map +1 -1
  22. package/dist/commonjs/v3/steeringContext.d.ts +11 -0
  23. package/dist/commonjs/v3/steeringContext.js +44 -3
  24. package/dist/commonjs/v3/steeringContext.js.map +1 -1
  25. package/dist/commonjs/v3/subAgentStream.d.ts +50 -0
  26. package/dist/commonjs/v3/subAgentStream.js +154 -0
  27. package/dist/commonjs/v3/subAgentStream.js.map +1 -0
  28. package/dist/commonjs/v3/transcriptStorage.js +3 -0
  29. package/dist/commonjs/v3/transcriptStorage.js.map +1 -1
  30. package/dist/commonjs/v3/uiMessageChunks.js +5 -1
  31. package/dist/commonjs/v3/uiMessageChunks.js.map +1 -1
  32. package/dist/commonjs/version.js +1 -1
  33. package/dist/esm/v3/ai-shared.d.ts +6 -0
  34. package/dist/esm/v3/ai-shared.js +6 -0
  35. package/dist/esm/v3/ai-shared.js.map +1 -1
  36. package/dist/esm/v3/ai.d.ts +45 -0
  37. package/dist/esm/v3/ai.js +113 -72
  38. package/dist/esm/v3/ai.js.map +1 -1
  39. package/dist/esm/v3/auth.d.ts +2 -1
  40. package/dist/esm/v3/auth.js +19 -13
  41. package/dist/esm/v3/auth.js.map +1 -1
  42. package/dist/esm/v3/chat-client.d.ts +11 -2
  43. package/dist/esm/v3/chat-client.js +29 -11
  44. package/dist/esm/v3/chat-client.js.map +1 -1
  45. package/dist/esm/v3/chat-react.d.ts +21 -0
  46. package/dist/esm/v3/chat-react.js +81 -30
  47. package/dist/esm/v3/chat-react.js.map +1 -1
  48. package/dist/esm/v3/chat.d.ts +1 -0
  49. package/dist/esm/v3/chat.js +1 -0
  50. package/dist/esm/v3/chat.js.map +1 -1
  51. package/dist/esm/v3/managedChatResponse.d.ts +13 -5
  52. package/dist/esm/v3/managedChatResponse.js +36 -18
  53. package/dist/esm/v3/managedChatResponse.js.map +1 -1
  54. package/dist/esm/v3/steeringContext.d.ts +11 -0
  55. package/dist/esm/v3/steeringContext.js +44 -4
  56. package/dist/esm/v3/steeringContext.js.map +1 -1
  57. package/dist/esm/v3/subAgentStream.d.ts +50 -0
  58. package/dist/esm/v3/subAgentStream.js +149 -0
  59. package/dist/esm/v3/subAgentStream.js.map +1 -0
  60. package/dist/esm/v3/transcriptStorage.js +3 -0
  61. package/dist/esm/v3/transcriptStorage.js.map +1 -1
  62. package/dist/esm/v3/uiMessageChunks.js +5 -1
  63. package/dist/esm/v3/uiMessageChunks.js.map +1 -1
  64. package/dist/esm/version.js +1 -1
  65. package/docs/ai-chat/background-injection.mdx +2 -0
  66. package/docs/ai-chat/client-protocol.mdx +1 -0
  67. package/docs/ai-chat/frontend.mdx +15 -0
  68. package/docs/ai-chat/overview.mdx +1 -1
  69. package/docs/ai-chat/patterns/sub-agents.mdx +81 -55
  70. package/docs/ai-chat/pending-messages.mdx +2 -0
  71. package/docs/ai-chat/quick-start.mdx +1 -1
  72. package/docs/ai-chat/reference.mdx +22 -0
  73. package/docs/ai-chat/server-chat.mdx +11 -7
  74. package/docs/config/config-file.mdx +2 -2
  75. package/docs/how-to-reduce-your-spend.mdx +4 -0
  76. package/docs/limits.mdx +41 -0
  77. package/docs/observability/query.mdx +29 -0
  78. package/docs/self-hosting/docker.mdx +62 -0
  79. package/docs/self-hosting/env/supervisor.mdx +3 -0
  80. package/docs/self-hosting/env/webapp.mdx +14 -0
  81. package/docs/self-hosting/kubernetes.mdx +2 -0
  82. package/docs/troubleshooting-alerts.mdx +39 -0
  83. package/docs/webhooks/deliveries.mdx +4 -0
  84. package/docs/webhooks/overview.mdx +8 -0
  85. package/docs/webhooks/sources.mdx +3 -1
  86. package/docs/webhooks/waiters.mdx +3 -3
  87. package/package.json +2 -2
  88. package/skills/trigger-chat-agent-advanced/SKILL.md +17 -7
  89. package/skills/trigger-cost-savings/SKILL.md +1 -0
package/dist/esm/v3/ai.js CHANGED
@@ -1,4 +1,4 @@
1
- import { accessoryAttributes, apiClientManager, controlSubtype, generateJWT, getSchemaParseFn, headerValue, InputStreamOncePromise, isAdditionalApiKey, isSchemaZodEsque, logger, ManualWaitpointPromise, OutOfMemoryError, resourceCatalog, SemanticInternalAttributes, SESSION_IN_CONSUMED_ID_HEADER, SESSION_IN_EVENT_ID_HEADER, sessionStreams, SessionChannelRouter, InputStreamTimeoutError, taskContext, TRIGGER_CONTROL_SUBTYPE, SESSION_CLOSED_HEADER, SESSION_CLOSED_REASON_HEADER, tryCatch, } from "@trigger.dev/core/v3";
1
+ import { accessoryAttributes, apiClientManager, controlSubtype, generateJWT, getSchemaParseFn, headerValue, InputStreamOncePromise, isAdditionalApiKey, isRunToken, isSchemaZodEsque, logger, ManualWaitpointPromise, OutOfMemoryError, resourceCatalog, SemanticInternalAttributes, SESSION_IN_CONSUMED_ID_HEADER, SESSION_IN_EVENT_ID_HEADER, sessionStreams, SessionChannelRouter, InputStreamTimeoutError, taskContext, TRIGGER_CONTROL_SUBTYPE, SESSION_CLOSED_HEADER, SESSION_CLOSED_REASON_HEADER, tryCatch, } from "@trigger.dev/core/v3";
2
2
  import { chatEvent, normalizeKeyString } from "./webhooks.js";
3
3
  import { fetchPublicFile } from "./modelFileDownload.js";
4
4
  // Runtime VALUES go through the ESM/CJS shim so the CJS build can `require`
@@ -12,7 +12,8 @@ import { responseAfterCompaction } from "./compactionResponse.js";
12
12
  import { withToolResultsInCallOrder } from "./toolResultOrder.js";
13
13
  import { ManagedChatResponse, createOrderedChatWriter } from "./managedChatResponse.js";
14
14
  import { reduceUIMessageChunks } from "./uiMessageChunks.js";
15
- import { convertSteeredMessages, retainStepMessages, steeringMarkers, } from "./steeringContext.js";
15
+ import { forwardSubAgentChunks } from "./subAgentStream.js";
16
+ import { convertSteeredMessages, retainStepMessages, steeringMarkers, withoutInjectionMarkers, } from "./steeringContext.js";
16
17
  let transcriptStorageOverride;
17
18
  /**
18
19
  * Test-only override for the storage `chat.agent` persists through, so a
@@ -22,7 +23,7 @@ let transcriptStorageOverride;
22
23
  export function __setTranscriptStorageForTests(storage) {
23
24
  transcriptStorageOverride = storage;
24
25
  }
25
- import { PENDING_MESSAGE_INJECTED_TYPE, upsertIncomingMessage, chatRunTags, } from "./ai-shared.js";
26
+ import { BACKGROUND_INJECTION_TYPE, PENDING_MESSAGE_INJECTED_TYPE, upsertIncomingMessage, chatRunTags, } from "./ai-shared.js";
26
27
  import { auth } from "./auth.js";
27
28
  import { locals } from "./locals.js";
28
29
  import { metadata } from "./metadata.js";
@@ -924,6 +925,64 @@ const chatResponse = {
924
925
  managedResponse().writeData(part);
925
926
  },
926
927
  };
928
+ /**
929
+ * Stream a sub-agent's reply to the frontend from inside a parent tool call,
930
+ * and resolve with the sub-agent's final message once it finishes.
931
+ *
932
+ * Each chunk the sub-agent streams is written once to the parent chat as a
933
+ * transient `data-subagent` part, so the bytes written grow with the length of
934
+ * the reply. Render it while it runs with `useSubAgentMessages` from
935
+ * `@trigger.dev/sdk/chat/react`. The tool's output is the final message, which
936
+ * persists with the parent's history the way a tool result always does.
937
+ *
938
+ * Prefer this over yielding `stream.messages()` snapshots as preliminary tool
939
+ * results: every snapshot repeats the whole message so far, so that pattern
940
+ * writes bytes in proportion to the square of the reply length.
941
+ *
942
+ * Call it inside a `chat.agent` (or `chat.customAgent`) run.
943
+ *
944
+ * @example
945
+ * ```ts
946
+ * const research = tool({
947
+ * description: "Delegate research to the research agent.",
948
+ * inputSchema: z.object({ topic: z.string() }),
949
+ * execute: async ({ topic }, { toolCallId, abortSignal }) => {
950
+ * const agent = new AgentChat<typeof researchAgent>({ agent: "research-agent" });
951
+ * const stream = await agent.sendMessage(topic, { abortSignal });
952
+ * return await chat.forwardSubAgent(stream, { toolCallId });
953
+ * },
954
+ * toModelOutput: ({ output }) => ({ type: "text", value: lastText(output) }),
955
+ * });
956
+ * ```
957
+ */
958
+ async function forwardSubAgent(stream, options) {
959
+ const source = isReadableStream(stream)
960
+ ? stream
961
+ : stream.stream;
962
+ let outcome = { message: undefined };
963
+ const { waitUntilComplete } = chatStream.writer({
964
+ spanName: "forward sub-agent",
965
+ collapsed: true,
966
+ execute: async ({ write }) => {
967
+ try {
968
+ outcome = {
969
+ message: await forwardSubAgentChunks(source, {
970
+ toolCallId: options.toolCallId,
971
+ flushIntervalMs: options.flushIntervalMs ?? 50,
972
+ write,
973
+ }),
974
+ };
975
+ }
976
+ catch (error) {
977
+ outcome = { error };
978
+ }
979
+ },
980
+ });
981
+ await waitUntilComplete();
982
+ if ("error" in outcome)
983
+ throw outcome.error;
984
+ return outcome.message;
985
+ }
927
986
  /**
928
987
  * Creates a lazy ChatWriter that only opens a realtime stream on first use.
929
988
  * Call `flush()` after the callback returns to await stream completion.
@@ -1918,12 +1977,6 @@ function spliceHandoverPartial(modelMessages, uiMessages, signal) {
1918
1977
  * @internal
1919
1978
  */
1920
1979
  const chatBackgroundQueueKey = locals.create("chat.backgroundQueue");
1921
- /**
1922
- * Background injections a step-boundary drain handed to the model this turn,
1923
- * with the transcript message they followed. Reconciled into the model lane
1924
- * and the persisted injections once the turn's response is in.
1925
- */
1926
- const chatPendingBackgroundKey = locals.create("chat.pendingBackground");
1927
1980
  /**
1928
1981
  * System-role context injected mid-conversation, held for the instructions lane.
1929
1982
  *
@@ -2886,6 +2939,25 @@ const EMPTY_DRAIN = { injected: [], claimed: [] };
2886
2939
  function modelFormOf(m, batch, injected) {
2887
2940
  return batch[0] === m ? injected : [];
2888
2941
  }
2942
+ /**
2943
+ * Record a prepared injection and write its marker into the response, so the
2944
+ * model lane rebuilds it at the step boundary where the model received it.
2945
+ */
2946
+ function markInjection(steps, messageIds, messages, markerMessages, kind) {
2947
+ const id = generateMessageId();
2948
+ const injections = locals.get(chatSteeringInjectionsKey) ?? new Map();
2949
+ injections.set(id, { id, messageIds, messages, ...(kind ? { kind } : {}) });
2950
+ locals.set(chatSteeringInjectionsKey, injections);
2951
+ const response = managedResponse();
2952
+ // prepareStep can run ahead of the UI consumer. Admit the marker only
2953
+ // once the actual preceding finish-step chunk has entered this stream.
2954
+ response.afterToolStep(steps.at(-1)?.content.flatMap((part) => (part.toolCallId ? [part.toolCallId] : [])) ?? []);
2955
+ response.writeData({
2956
+ type: kind === "background" ? BACKGROUND_INJECTION_TYPE : PENDING_MESSAGE_INJECTED_TYPE,
2957
+ id,
2958
+ data: { messageIds, messages: markerMessages },
2959
+ });
2960
+ }
2889
2961
  /**
2890
2962
  * Drain the steering queue as a batch. Calls `shouldInject` once with all
2891
2963
  * pending messages. If it returns true, calls `prepareMessages` once to
@@ -2899,8 +2971,6 @@ function modelFormOf(m, batch, injected) {
2899
2971
  * @internal
2900
2972
  */
2901
2973
  async function drainSteeringQueue(config, messages, steps, queueOverride) {
2902
- if (steps.length === 0)
2903
- managedResponse().beginGeneration();
2904
2974
  const queue = queueOverride ?? locals.get(chatSteeringQueueKey);
2905
2975
  if (!queue || queue.length === 0)
2906
2976
  return EMPTY_DRAIN;
@@ -3033,23 +3103,7 @@ async function drainSteeringQueue(config, messages, steps, queueOverride) {
3033
3103
  locals.set(chatPendingSteerKey, pendingSteer);
3034
3104
  }
3035
3105
  if (injected.length > 0) {
3036
- const id = generateMessageId();
3037
- const messageIds = claimedUIMessages.map((m) => m.id);
3038
- const injections = locals.get(chatSteeringInjectionsKey) ?? new Map();
3039
- injections.set(id, { id, messageIds, messages: injected });
3040
- locals.set(chatSteeringInjectionsKey, injections);
3041
- const response = managedResponse();
3042
- // prepareStep can run ahead of the UI consumer. Admit the marker only
3043
- // once the actual preceding finish-step chunk has entered this stream.
3044
- response.afterStep(steps.length);
3045
- response.writeData({
3046
- type: PENDING_MESSAGE_INJECTED_TYPE,
3047
- id,
3048
- data: {
3049
- messageIds,
3050
- messages: claimedUIMessages.map((m) => ({ id: m.id, text: textOfUIMessage(m) })),
3051
- },
3052
- });
3106
+ markInjection(steps, claimedUIMessages.map((m) => m.id), injected, claimedUIMessages.map((m) => ({ id: m.id, text: textOfUIMessage(m) })));
3053
3107
  }
3054
3108
  // Fire onInjected callback
3055
3109
  if (config.onInjected && injected.length > 0) {
@@ -3614,12 +3668,7 @@ function toStreamTextOptions(options, retain = true) {
3614
3668
  if (bgQueue && bgQueue.length > 0) {
3615
3669
  const injected = bgQueue.splice(0); // drain
3616
3670
  resultMessages = [...(resultMessages ?? messages), ...injected];
3617
- const pendingBackground = locals.get(chatPendingBackgroundKey) ?? [];
3618
- pendingBackground.push({
3619
- afterId: locals.get(chatCurrentUIMessagesKey)?.at(-1)?.id ?? "",
3620
- messages: injected,
3621
- });
3622
- locals.set(chatPendingBackgroundKey, pendingBackground);
3671
+ markInjection(steps, [], injected, [], "background");
3623
3672
  }
3624
3673
  // 4. Parallel tool results in call order, the order the next turn's history
3625
3674
  // will list them in. See `withToolResultsInCallOrder`.
@@ -4969,24 +5018,6 @@ function chatAgent(options) {
4969
5018
  // durable snapshot + `session.out` replay (or `hydrateMessages` if
4970
5019
  // registered) — the wire is delta-only now, no longer a seed.
4971
5020
  let accumulatedMessages = [];
4972
- /**
4973
- * Give the model accumulator the background injections a step-boundary
4974
- * drain handed to the model this turn, and record them for persistence.
4975
- * Returns how many model messages were appended.
4976
- */
4977
- const reconcilePendingBackground = () => {
4978
- const pending = locals.get(chatPendingBackgroundKey);
4979
- if (!pending || pending.length === 0)
4980
- return 0;
4981
- locals.set(chatPendingBackgroundKey, []);
4982
- let appended = 0;
4983
- for (const entry of pending) {
4984
- accumulatedMessages.push(...entry.messages);
4985
- laneInjections.push(entry);
4986
- appended += entry.messages.length;
4987
- }
4988
- return appended;
4989
- };
4990
5021
  /**
4991
5022
  * Give the model accumulator the steering messages a drain consumed,
4992
5023
  * in the form the model actually received. Appended, never reconverted
@@ -5010,6 +5041,15 @@ function chatAgent(options) {
5010
5041
  // Accumulated UI messages for persistence. Mirrors the model accumulator
5011
5042
  // but in frontend-friendly UIMessage format (with parts, id, etc.).
5012
5043
  let accumulatedUIMessages = [];
5044
+ const cleanIncomingMessage = (msg) => {
5045
+ if (msg.role !== "assistant")
5046
+ return withoutInjectionMarkers(msg);
5047
+ const cleaned = cleanupAbortedParts(msg);
5048
+ // Markers are the agent's own; only a known assistant message keeps them.
5049
+ return accumulatedUIMessages.some((m) => m.id === msg.id)
5050
+ ? cleaned
5051
+ : withoutInjectionMarkers(cleaned);
5052
+ };
5013
5053
  // ── Snapshot + replay (gated on prior-state signals) ─────────────
5014
5054
  //
5015
5055
  // With `hydrateMessages` registered the customer owns history — the
@@ -6526,7 +6566,7 @@ function chatAgent(options) {
6526
6566
  // Cleaning happens once here so `extractLastUserMessageText` and
6527
6567
  // every downstream consumer see the same message shape — and
6528
6568
  // `cleanupAbortedParts` no longer has to be re-applied below.
6529
- const cleanedIncomingMessages = incomingMessages.map((msg) => msg.role === "assistant" ? cleanupAbortedParts(msg) : msg);
6569
+ const cleanedIncomingMessages = incomingMessages.map(cleanIncomingMessage);
6530
6570
  const lastUserMessage = extractLastUserMessageText(cleanedIncomingMessages);
6531
6571
  channelTurnRan =
6532
6572
  !!channelConn &&
@@ -6587,7 +6627,6 @@ function chatAgent(options) {
6587
6627
  locals.set(chatOutGateKey, createChatOutGate());
6588
6628
  locals.set(chatCompactionStateKey, undefined);
6589
6629
  locals.set(chatSteeringQueueKey, []);
6590
- locals.set(chatPendingBackgroundKey, []);
6591
6630
  await locals.get(chatManagedResponseKey)?.close();
6592
6631
  locals.set(chatManagedResponseKey, undefined);
6593
6632
  locals.set(chatManagedResponseActiveKey, true);
@@ -7686,7 +7725,7 @@ function chatAgent(options) {
7686
7725
  const steerTailThisTurn = reconcilePendingSteer({
7687
7726
  turnNew: turnNewModelMessages,
7688
7727
  response: capturedResponseMessage,
7689
- }).reduce((n, e) => n + e.model.length, 0) + reconcilePendingBackground();
7728
+ }).reduce((n, e) => n + e.model.length, 0);
7690
7729
  // Append the assistant's response (partial or complete) to the accumulator.
7691
7730
  // The onFinish callback fires even on abort/stop, so partial responses
7692
7731
  // from stopped generation are captured correctly.
@@ -8569,7 +8608,8 @@ function chatAgent(options) {
8569
8608
  // yet (a pre-run hook threw), so fold the wire message in for the
8570
8609
  // error event + snapshot — the cursor has already advanced past it,
8571
8610
  // so otherwise it survives in neither the snapshot nor the `.in` tail.
8572
- const erroredWireMessage = currentWirePayload.message;
8611
+ const rawWireMessage = currentWirePayload.message;
8612
+ const erroredWireMessage = rawWireMessage && cleanIncomingMessage(rawWireMessage);
8573
8613
  const erroredUIMessages = erroredWireMessage &&
8574
8614
  !accumulatedUIMessages.some((m) => m.id === erroredWireMessage.id)
8575
8615
  ? [...accumulatedUIMessages, erroredWireMessage]
@@ -8626,7 +8666,6 @@ function chatAgent(options) {
8626
8666
  let erroredNewUIMessages = buildErroredNew();
8627
8667
  let erroredNewModelMessages = [];
8628
8668
  const reconciledSteer = reconcilePendingSteer({ response: partialResponse });
8629
- const backgroundTailThisTurn = reconcilePendingBackground();
8630
8669
  if (!responseCommitted) {
8631
8670
  try {
8632
8671
  if (erroredNewUIMessages.length > 0) {
@@ -8644,8 +8683,7 @@ function chatAgent(options) {
8644
8683
  accumulatedMessages.push(...(await toModelMessages(appended.map((m) => stripProviderMetadata(m)))));
8645
8684
  }
8646
8685
  else {
8647
- const ok = await replaceModelRun(accumulatedMessages, erroredUIMessages[partialIdx], partialResponse, reconciledSteer.reduce((n, e) => n + e.model.length, 0) +
8648
- backgroundTailThisTurn);
8686
+ const ok = await replaceModelRun(accumulatedMessages, erroredUIMessages[partialIdx], partialResponse, reconciledSteer.reduce((n, e) => n + e.model.length, 0));
8649
8687
  if (!ok) {
8650
8688
  logger.warn("chat.agent: replaced partial not found at the model lane tail; reconverting the lane");
8651
8689
  accumulatedMessages = await toModelMessages(erroredUIMessagesWithPartial, erroredUIMessagesWithPartial);
@@ -11045,10 +11083,10 @@ function resolveChatStartBaseURL(endpoint, chatId, option) {
11045
11083
  const raw = typeof option === "function" ? option({ endpoint, chatId }) : (option ?? fallback);
11046
11084
  return raw.replace(/\/$/, "");
11047
11085
  }
11048
- function overrideRequestHeaders(accessToken) {
11086
+ function overrideRequestHeaders(authHeaders) {
11049
11087
  const headers = {
11050
11088
  "Content-Type": "application/json",
11051
- Authorization: `Bearer ${accessToken}`,
11089
+ ...authHeaders,
11052
11090
  "x-trigger-source": "sdk",
11053
11091
  };
11054
11092
  // Forward the preview-branch hint so override-mode requests land on the
@@ -11061,15 +11099,16 @@ function overrideRequestHeaders(accessToken) {
11061
11099
  return headers;
11062
11100
  }
11063
11101
  async function callSessionsCreateWithOverride(args) {
11064
- const accessToken = apiClientManager.accessToken;
11065
- if (!accessToken) {
11102
+ const apiClient = apiClientManager.client;
11103
+ if (!apiClient) {
11066
11104
  throw new Error("chat.createStartSessionAction: no API access token configured. Set TRIGGER_SECRET_KEY or call apiClientManager.setGlobalAPIClientConfiguration before invoking the action.");
11067
11105
  }
11106
+ const authHeaders = apiClient.getAuthenticationHeaders("createSession");
11068
11107
  const ctx = { endpoint: "sessions", chatId: args.chatId };
11069
11108
  const url = `${resolveChatStartBaseURL("sessions", args.chatId, args.baseURLOption)}/api/v1/sessions`;
11070
11109
  const init = {
11071
11110
  method: "POST",
11072
- headers: overrideRequestHeaders(accessToken),
11111
+ headers: overrideRequestHeaders(authHeaders),
11073
11112
  // This path bypasses `sessions.start`, so it resolves the pin itself.
11074
11113
  body: JSON.stringify(withResolvedExternalDeploymentId(args.body)),
11075
11114
  };
@@ -11084,18 +11123,20 @@ async function callSessionsCreateWithOverride(args) {
11084
11123
  return json;
11085
11124
  }
11086
11125
  async function mintPublicTokenWithOverride(args) {
11087
- const accessToken = apiClientManager.accessToken;
11088
- if (!accessToken) {
11126
+ const apiClient = apiClientManager.client;
11127
+ if (!apiClient) {
11089
11128
  throw new Error("chat.createStartSessionAction: no API access token configured for JWT mint.");
11090
11129
  }
11130
+ const authHeaders = apiClient.getAuthenticationHeaders("createPublicToken");
11131
+ const accessToken = authHeaders.Authorization.slice("Bearer ".length);
11091
11132
  const ctx = { endpoint: "auth", chatId: args.chatId };
11092
11133
  const scopes = [`read:sessions:${args.chatId}`, `write:sessions:${args.chatId}`];
11093
- const serverMint = isAdditionalApiKey(accessToken);
11134
+ const serverMint = isAdditionalApiKey(accessToken) || isRunToken(accessToken);
11094
11135
  const endpoint = serverMint ? "/api/v1/auth/public-tokens" : "/api/v1/auth/jwt/claims";
11095
11136
  const url = `${resolveChatStartBaseURL("auth", args.chatId, args.baseURLOption)}${endpoint}`;
11096
11137
  const init = {
11097
11138
  method: "POST",
11098
- headers: overrideRequestHeaders(accessToken),
11139
+ headers: overrideRequestHeaders(authHeaders),
11099
11140
  ...(serverMint
11100
11141
  ? {
11101
11142
  body: JSON.stringify({
@@ -11111,11 +11152,9 @@ async function mintPublicTokenWithOverride(args) {
11111
11152
  ? await args.fetchOverride(url, init, ctx)
11112
11153
  : await fetch(url, init);
11113
11154
  if (!response.ok) {
11114
- // An additional API key cannot self-sign, so it must use the server mint
11115
- // endpoint. On a server too old to expose it, explain the recovery path
11116
- // instead of surfacing a bare 404 (mirrors auth.createServerPublicToken).
11117
11155
  if (serverMint && response.status === 404) {
11118
- throw new Error("This additional API key cannot self-sign public tokens, and the server does not support public-token minting. Upgrade the server or use the root API key.");
11156
+ const credentialType = isRunToken(accessToken) ? "run token" : "additional API key";
11157
+ throw new Error(`This ${credentialType} cannot self-sign public tokens, and the server does not support public-token minting. Upgrade the server or use the root API key.`);
11119
11158
  }
11120
11159
  const text = await response.text().catch(() => "");
11121
11160
  throw new Error(`auth.createPublicToken failed: ${response.status} ${text}`);
@@ -11229,6 +11268,8 @@ export const chat = {
11229
11268
  stream: chatStream,
11230
11269
  /** Write data parts that persist to the response message. See {@link chatResponse}. */
11231
11270
  response: chatResponse,
11271
+ /** Stream a sub-agent's reply through a parent tool call. See {@link forwardSubAgent}. */
11272
+ forwardSubAgent,
11232
11273
  /** Pre-built input stream for receiving messages from the transport. */
11233
11274
  messages: messagesInput,
11234
11275
  /** The current chat.agent run's Session handle. See {@link SessionHandle}. */