@trigger.dev/sdk 0.0.0-chat-prerelease-20260507122230 → 0.0.0-chat-prerelease-20260507131256

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.
@@ -2516,9 +2516,8 @@ export declare const chat: {
2516
2516
  /** Read the current accumulated UI messages (copy). */
2517
2517
  all(): UIMessage[];
2518
2518
  /**
2519
- * Read the current chain as an ordered `UIMessage[]`. Alias for `all()` —
2520
- * use this when working alongside parent-aware APIs (TRI-9120) where
2521
- * "chain" disambiguates from "graph".
2519
+ * Read the current chain as an ordered `UIMessage[]`. Identical to
2520
+ * `all()`; use whichever name reads better in context.
2522
2521
  */
2523
2522
  getChain(): UIMessage[];
2524
2523
  /**
@@ -2527,13 +2526,22 @@ export declare const chat: {
2527
2526
  */
2528
2527
  findMessage(messageId: string): UIMessage | undefined;
2529
2528
  /**
2530
- * Tool calls on the leaf assistant message still waiting on an answer
2531
- * (`input-available` state). Use this to gate fresh user turns during
2532
- * HITL flows: if `getPendingToolCalls().length > 0`, an `addToolOutput`
2533
- * is expected before any new user message.
2529
+ * Tool calls on the *most recent* assistant message that are still in
2530
+ * `input-available` state (waiting on an `addToolOutput` answer). The
2531
+ * scan walks back from the tail and stops at the first assistant
2532
+ * message it finds, so a trailing user message does not change the
2533
+ * result — pending tool calls remain pending until they're resolved
2534
+ * on that assistant or the assistant is removed.
2534
2535
  *
2535
- * Returns `[]` if there is no assistant message yet, or if the leaf
2536
- * assistant has no pending tool calls.
2536
+ * Use this to gate fresh user turns or actions during HITL flows: if
2537
+ * `getPendingToolCalls().length > 0`, an `addToolOutput` is expected.
2538
+ *
2539
+ * Returns `[]` if there is no assistant message yet, or if the most
2540
+ * recent assistant has no pending tool calls.
2541
+ *
2542
+ * Approval flows (`approval-requested` / `approval-responded` states)
2543
+ * are not surfaced here. Those are about the user authorizing a tool
2544
+ * to run; "pending" is about the user *answering* a tool call.
2537
2545
  */
2538
2546
  getPendingToolCalls(): ChatToolCallRef[];
2539
2547
  /**
@@ -2547,6 +2555,8 @@ export declare const chat: {
2547
2555
  * not already represented in the current chain. Use this when
2548
2556
  * persisting tool results to your own store: each call surfaces only
2549
2557
  * the *new* answers, so writes stay idempotent across re-streams.
2558
+ * Duplicate `toolCallId`s within `message` itself are also collapsed
2559
+ * to a single entry.
2550
2560
  */
2551
2561
  extractNewToolResults(message: UIMessage): ChatNewToolResult[];
2552
2562
  /** Replace all accumulated messages. Same as `chat.setMessages()`. */
@@ -997,16 +997,24 @@ function getResolvedToolCallsFromHistory(messages) {
997
997
  * Pure helper: tool parts in `message` that have a fresh result not
998
998
  * already represented by the resolved toolCallIds in `messages`. The
999
999
  * `errorText` field is present only for `output-error` parts.
1000
+ *
1001
+ * Within a single `message`, duplicate `toolCallId`s emit only once
1002
+ * (first occurrence wins). This guards against malformed assistants
1003
+ * with repeated tool parts.
1000
1004
  * @internal
1001
1005
  */
1002
1006
  function extractNewToolResultsFromHistory(message, messages) {
1003
1007
  const resolved = new Set(getResolvedToolCallsFromHistory(messages).map((r) => r.toolCallId));
1008
+ const seen = new Set();
1004
1009
  const out = [];
1005
1010
  for (const { part, toolCallId, toolName, state } of iterateToolParts(message)) {
1006
1011
  if (!isResolvedToolState(state))
1007
1012
  continue;
1008
1013
  if (resolved.has(toolCallId))
1009
1014
  continue;
1015
+ if (seen.has(toolCallId))
1016
+ continue;
1017
+ seen.add(toolCallId);
1010
1018
  if (state === "output-error") {
1011
1019
  out.push({ toolCallId, toolName, output: undefined, errorText: part.errorText });
1012
1020
  }
@@ -1032,12 +1040,11 @@ const chatHistory = {
1032
1040
  return [...getChatHistoryState()];
1033
1041
  },
1034
1042
  /**
1035
- * Read the current chain as an ordered `UIMessage[]`. Alias for `all()` —
1036
- * use this when working alongside parent-aware APIs (TRI-9120) where
1037
- * "chain" disambiguates from "graph".
1043
+ * Read the current chain as an ordered `UIMessage[]`. Identical to
1044
+ * `all()`; use whichever name reads better in context.
1038
1045
  */
1039
1046
  getChain() {
1040
- return [...getChatHistoryState()];
1047
+ return chatHistory.all();
1041
1048
  },
1042
1049
  /**
1043
1050
  * Find a message by id. Returns `undefined` if no message with that id
@@ -1047,13 +1054,22 @@ const chatHistory = {
1047
1054
  return getChatHistoryState().find((m) => m.id === messageId);
1048
1055
  },
1049
1056
  /**
1050
- * Tool calls on the leaf assistant message still waiting on an answer
1051
- * (`input-available` state). Use this to gate fresh user turns during
1052
- * HITL flows: if `getPendingToolCalls().length > 0`, an `addToolOutput`
1053
- * is expected before any new user message.
1057
+ * Tool calls on the *most recent* assistant message that are still in
1058
+ * `input-available` state (waiting on an `addToolOutput` answer). The
1059
+ * scan walks back from the tail and stops at the first assistant
1060
+ * message it finds, so a trailing user message does not change the
1061
+ * result — pending tool calls remain pending until they're resolved
1062
+ * on that assistant or the assistant is removed.
1063
+ *
1064
+ * Use this to gate fresh user turns or actions during HITL flows: if
1065
+ * `getPendingToolCalls().length > 0`, an `addToolOutput` is expected.
1066
+ *
1067
+ * Returns `[]` if there is no assistant message yet, or if the most
1068
+ * recent assistant has no pending tool calls.
1054
1069
  *
1055
- * Returns `[]` if there is no assistant message yet, or if the leaf
1056
- * assistant has no pending tool calls.
1070
+ * Approval flows (`approval-requested` / `approval-responded` states)
1071
+ * are not surfaced here. Those are about the user authorizing a tool
1072
+ * to run; "pending" is about the user *answering* a tool call.
1057
1073
  */
1058
1074
  getPendingToolCalls() {
1059
1075
  return getPendingToolCallsFromHistory(getChatHistoryState());
@@ -1071,6 +1087,8 @@ const chatHistory = {
1071
1087
  * not already represented in the current chain. Use this when
1072
1088
  * persisting tool results to your own store: each call surfaces only
1073
1089
  * the *new* answers, so writes stay idempotent across re-streams.
1090
+ * Duplicate `toolCallId`s within `message` itself are also collapsed
1091
+ * to a single entry.
1074
1092
  */
1075
1093
  extractNewToolResults(message) {
1076
1094
  return extractNewToolResultsFromHistory(message, getChatHistoryState());