Skip to content

Commit a38dc16

Browse files
committed
fix(deps): patch @tanstack/ai to fix in-place tool-call part mutations
Four message-updater functions mutated tool-call parts in-place after shallow-copying the parts array, breaking proxy-based reactivity in Svelte 5. Bun patch replaces mutations with immutable spread copies. Upstream PR: TanStack/ai#395
1 parent 1fa4007 commit a38dc16

File tree

2 files changed

+125
-0
lines changed

2 files changed

+125
-0
lines changed

package.json

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -101,5 +101,8 @@
101101
},
102102
"dependencies": {
103103
"tinyexec": "^1.0.4"
104+
},
105+
"patchedDependencies": {
106+
"@tanstack/ai@0.8.1": "patches/@tanstack%2Fai@0.8.1.patch"
104107
}
105108
}

patches/@tanstack%2Fai@0.8.1.patch

Lines changed: 122 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,122 @@
1+
diff --git a/dist/esm/activities/chat/stream/message-updaters.js b/dist/esm/activities/chat/stream/message-updaters.js
2+
index 535e88d124ae40e8346a58765d3b34cb4f74c42f..300b9e376f481661f1cee3af4d735ffeff22b031 100644
3+
--- a/dist/esm/activities/chat/stream/message-updaters.js
4+
+++ b/dist/esm/activities/chat/stream/message-updaters.js
5+
@@ -74,10 +74,14 @@ function updateToolCallApproval(messages, messageId, toolCallId, approvalId) {
6+
(p) => p.type === "tool-call" && p.id === toolCallId
7+
);
8+
if (toolCallPart) {
9+
- toolCallPart.state = "approval-requested";
10+
- toolCallPart.approval = {
11+
- id: approvalId,
12+
- needsApproval: true
13+
+ const index = parts.indexOf(toolCallPart);
14+
+ parts[index] = {
15+
+ ...toolCallPart,
16+
+ state: "approval-requested",
17+
+ approval: {
18+
+ id: approvalId,
19+
+ needsApproval: true
20+
+ }
21+
};
22+
}
23+
return { ...msg, parts };
24+
@@ -90,12 +94,12 @@ function updateToolCallWithOutput(messages, toolCallId, output, state, errorText
25+
(p) => p.type === "tool-call" && p.id === toolCallId
26+
);
27+
if (toolCallPart) {
28+
- toolCallPart.output = errorText ? { error: errorText } : output;
29+
- if (state) {
30+
- toolCallPart.state = state;
31+
- } else {
32+
- toolCallPart.state = "input-complete";
33+
- }
34+
+ const index = parts.indexOf(toolCallPart);
35+
+ parts[index] = {
36+
+ ...toolCallPart,
37+
+ output: errorText ? { error: errorText } : output,
38+
+ state: state ?? "input-complete"
39+
+ };
40+
}
41+
return { ...msg, parts };
42+
});
43+
@@ -107,8 +111,12 @@ function updateToolCallApprovalResponse(messages, approvalId, approved) {
44+
(p) => p.type === "tool-call" && p.approval?.id === approvalId
45+
);
46+
if (toolCallPart && toolCallPart.approval) {
47+
- toolCallPart.approval.approved = approved;
48+
- toolCallPart.state = "approval-responded";
49+
+ const index = parts.indexOf(toolCallPart);
50+
+ parts[index] = {
51+
+ ...toolCallPart,
52+
+ approval: { ...toolCallPart.approval, approved },
53+
+ state: "approval-responded"
54+
+ };
55+
}
56+
return { ...msg, parts };
57+
});
58+
diff --git a/src/activities/chat/stream/message-updaters.ts b/src/activities/chat/stream/message-updaters.ts
59+
index 80b94d59aac3eeed909e97fa3b559986d8947315..57ffbe2e6f4070ebae837acf3ba2a09e872f352a 100644
60+
--- a/src/activities/chat/stream/message-updaters.ts
61+
+++ b/src/activities/chat/stream/message-updaters.ts
62+
@@ -150,10 +150,14 @@ export function updateToolCallApproval(
63+
)
64+
65+
if (toolCallPart) {
66+
- toolCallPart.state = 'approval-requested'
67+
- toolCallPart.approval = {
68+
- id: approvalId,
69+
- needsApproval: true,
70+
+ const index = parts.indexOf(toolCallPart)
71+
+ parts[index] = {
72+
+ ...toolCallPart,
73+
+ state: 'approval-requested',
74+
+ approval: {
75+
+ id: approvalId,
76+
+ needsApproval: true,
77+
+ },
78+
}
79+
}
80+
81+
@@ -181,7 +185,8 @@ export function updateToolCallState(
82+
)
83+
84+
if (toolCallPart) {
85+
- toolCallPart.state = state
86+
+ const index = parts.indexOf(toolCallPart)
87+
+ parts[index] = { ...toolCallPart, state }
88+
}
89+
90+
return { ...msg, parts }
91+
@@ -206,11 +211,11 @@ export function updateToolCallWithOutput(
92+
)
93+
94+
if (toolCallPart) {
95+
- toolCallPart.output = errorText ? { error: errorText } : output
96+
- if (state) {
97+
- toolCallPart.state = state
98+
- } else {
99+
- toolCallPart.state = 'input-complete'
100+
+ const index = parts.indexOf(toolCallPart)
101+
+ parts[index] = {
102+
+ ...toolCallPart,
103+
+ output: errorText ? { error: errorText } : output,
104+
+ state: state ?? 'input-complete',
105+
}
106+
}
107+
108+
@@ -235,8 +240,12 @@ export function updateToolCallApprovalResponse(
109+
)
110+
111+
if (toolCallPart && toolCallPart.approval) {
112+
- toolCallPart.approval.approved = approved
113+
- toolCallPart.state = 'approval-responded'
114+
+ const index = parts.indexOf(toolCallPart)
115+
+ parts[index] = {
116+
+ ...toolCallPart,
117+
+ approval: { ...toolCallPart.approval, approved },
118+
+ state: 'approval-responded',
119+
+ }
120+
}
121+
122+
return { ...msg, parts }

0 commit comments

Comments
 (0)