Skip to content

Commit 5cd29bd

Browse files
authoredApr 10, 2024··
ai/core: add toTextStreamResponse to streamText result (#1318)
1 parent 87d3db5 commit 5cd29bd

File tree

3 files changed

+70
-0
lines changed

3 files changed

+70
-0
lines changed
 

‎.changeset/pretty-poets-switch.md

+5
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
---
2+
'ai': patch
3+
---
4+
5+
ai/core: add toTextStreamResponse() method to streamText result

‎packages/core/core/generate-text/stream-text.test.ts

+39
Original file line numberDiff line numberDiff line change
@@ -231,3 +231,42 @@ describe('result.fullStream', () => {
231231
);
232232
});
233233
});
234+
235+
describe('result.toTextStreamResponse', () => {
236+
it('should create a Response with a text stream', async () => {
237+
const result = await experimental_streamText({
238+
model: new MockLanguageModelV1({
239+
doStream: async ({ prompt, mode }) => {
240+
return {
241+
stream: convertArrayToReadableStream([
242+
{ type: 'text-delta', textDelta: 'Hello' },
243+
{ type: 'text-delta', textDelta: ', ' },
244+
{ type: 'text-delta', textDelta: 'world!' },
245+
]),
246+
rawCall: { rawPrompt: 'prompt', rawSettings: {} },
247+
};
248+
},
249+
}),
250+
prompt: 'test-input',
251+
});
252+
253+
const response = result.toTextStreamResponse();
254+
255+
assert.strictEqual(response.status, 200);
256+
assert.strictEqual(
257+
response.headers.get('Content-Type'),
258+
'text/plain; charset=utf-8',
259+
);
260+
261+
// Read the chunks into an array
262+
const reader = response.body!.getReader();
263+
const chunks = [];
264+
while (true) {
265+
const { value, done } = await reader.read();
266+
if (done) break;
267+
chunks.push(new TextDecoder().decode(value));
268+
}
269+
270+
assert.deepStrictEqual(chunks, ['Hello', ', ', 'world!']);
271+
});
272+
});

‎packages/core/core/generate-text/stream-text.ts

+26
Original file line numberDiff line numberDiff line change
@@ -219,4 +219,30 @@ Stream callbacks that will be called when the stream emits events.
219219
.pipeThrough(createCallbacksTransformer(callbacks))
220220
.pipeThrough(createStreamDataTransformer());
221221
}
222+
223+
/**
224+
Creates a simple text stream response.
225+
Each text delta is encoded as UTF-8 and sent as a separate chunk.
226+
Non-text-delta events are ignored.
227+
*/
228+
toTextStreamResponse(init?: ResponseInit): Response {
229+
const encoder = new TextEncoder();
230+
return new Response(
231+
this.textStream.pipeThrough(
232+
new TransformStream({
233+
transform(chunk, controller) {
234+
controller.enqueue(encoder.encode(chunk));
235+
},
236+
}),
237+
),
238+
{
239+
...init,
240+
status: 200,
241+
headers: {
242+
'Content-Type': 'text/plain; charset=utf-8',
243+
...init?.headers,
244+
},
245+
},
246+
);
247+
}
222248
}

0 commit comments

Comments
 (0)
Please sign in to comment.