Skip to content

Commit ff28112

Browse files
authoredJun 4, 2024··
fix(ai/rsc): Remove extra reconciliation of streamUI (#1818)
1 parent 4fb0e69 commit ff28112

File tree

3 files changed

+42
-46
lines changed

3 files changed

+42
-46
lines changed
 

‎.changeset/late-years-share.md

+5
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
---
2+
'ai': patch
3+
---
4+
5+
fix(ai/rsc): Remove extra reconcilation of streamUI

‎packages/core/rsc/stream-ui/__snapshots__/stream-ui.ui.test.tsx.snap

+11-39
Original file line numberDiff line numberDiff line change
@@ -63,13 +63,7 @@ exports[`result.value > should render text function returned ui 1`] = `
6363
"next": {
6464
"done": false,
6565
"next": {
66-
"done": false,
67-
"next": {
68-
"done": true,
69-
"value": <h1>
70-
{ "content": "Hello, world!" }
71-
</h1>,
72-
},
66+
"done": true,
7367
"value": <h1>
7468
{ "content": "Hello, world!" }
7569
</h1>,
@@ -115,22 +109,11 @@ exports[`result.value > should render tool call results 1`] = `
115109
"props": {
116110
"c": undefined,
117111
"n": {
118-
"done": false,
119-
"next": {
120-
"done": false,
121-
"next": {
122-
"done": true,
123-
"value": <div>
124-
tool1:
125-
value
126-
</div>,
127-
},
128-
"value": <div>
129-
tool1:
130-
value
131-
</div>,
132-
},
133-
"value": "",
112+
"done": true,
113+
"value": <div>
114+
tool1:
115+
value
116+
</div>,
134117
},
135118
},
136119
"type": "",
@@ -151,22 +134,11 @@ exports[`result.value > should render tool call results with generator render fu
151134
"n": {
152135
"done": false,
153136
"next": {
154-
"done": false,
155-
"next": {
156-
"done": false,
157-
"next": {
158-
"done": true,
159-
"value": <div>
160-
tool:
161-
value
162-
</div>,
163-
},
164-
"value": <div>
165-
tool:
166-
value
167-
</div>,
168-
},
169-
"value": "",
137+
"done": true,
138+
"value": <div>
139+
tool:
140+
value
141+
</div>,
170142
},
171143
"value": <div>
172144
Loading...

‎packages/core/rsc/stream-ui/stream-ui.tsx

+26-7
Original file line numberDiff line numberDiff line change
@@ -145,6 +145,7 @@ The tool choice strategy. Default: 'auto'.
145145
args: [payload: any] | [payload: any, options: any],
146146
renderer: undefined | Renderer<any>,
147147
res: ReturnType<typeof createStreamableUI>,
148+
lastCall = false,
148149
) {
149150
if (!renderer) return;
150151

@@ -165,7 +166,13 @@ The tool choice strategy. Default: 'auto'.
165166
typeof value.then === 'function')
166167
) {
167168
const node = await (value as Promise<React.ReactNode>);
168-
res.update(node);
169+
170+
if (lastCall) {
171+
res.done(node);
172+
} else {
173+
res.update(node);
174+
}
175+
169176
resolvable.resolve(void 0);
170177
} else if (
171178
value &&
@@ -179,20 +186,32 @@ The tool choice strategy. Default: 'auto'.
179186
>;
180187
while (true) {
181188
const { done, value } = await it.next();
182-
res.update(value);
189+
if (lastCall && done) {
190+
res.done(value);
191+
} else {
192+
res.update(value);
193+
}
183194
if (done) break;
184195
}
185196
resolvable.resolve(void 0);
186197
} else if (value && typeof value === 'object' && Symbol.iterator in value) {
187198
const it = value as Generator<React.ReactNode, React.ReactNode, void>;
188199
while (true) {
189200
const { done, value } = it.next();
190-
res.update(value);
201+
if (lastCall && done) {
202+
res.done(value);
203+
} else {
204+
res.update(value);
205+
}
191206
if (done) break;
192207
}
193208
resolvable.resolve(void 0);
194209
} else {
195-
res.update(value);
210+
if (lastCall) {
211+
res.done(value);
212+
} else {
213+
res.update(value);
214+
}
196215
resolvable.resolve(void 0);
197216
}
198217
}
@@ -257,6 +276,7 @@ The tool choice strategy. Default: 'auto'.
257276
});
258277
}
259278

279+
hasToolCall = true;
260280
const parseResult = safeParseJSON({
261281
text: value.args,
262282
schema: tool.parameters,
@@ -280,6 +300,7 @@ The tool choice strategy. Default: 'auto'.
280300
],
281301
tool.generate,
282302
ui,
303+
true,
283304
);
284305

285306
break;
@@ -297,11 +318,9 @@ The tool choice strategy. Default: 'auto'.
297318

298319
if (hasToolCall) {
299320
await finished;
300-
ui.done();
301321
} else {
302-
handleRender([{ content, done: true }], textRender, ui);
322+
handleRender([{ content, done: true }], textRender, ui, true);
303323
await finished;
304-
ui.done();
305324
}
306325
} catch (error) {
307326
// During the stream rendering, we don't want to throw the error to the

0 commit comments

Comments
 (0)
Please sign in to comment.