@@ -30,6 +30,25 @@ import { GenerateContentRequest } from '../types';
30
30
use ( sinonChai ) ;
31
31
use ( chaiAsPromised ) ;
32
32
33
+ /**
34
+ * Converts the ReadableStream from response.body to an array of strings.
35
+ */
36
+ async function toStringArray (
37
+ stream : ReadableStream < Uint8Array >
38
+ ) : Promise < string [ ] > {
39
+ const decoder = new TextDecoder ( ) ;
40
+ const actual = [ ] ;
41
+ const reader = stream . getReader ( ) ;
42
+ while ( true ) {
43
+ const { done, value } = await reader . read ( ) ;
44
+ if ( done ) {
45
+ break ;
46
+ }
47
+ actual . push ( decoder . decode ( value ) ) ;
48
+ }
49
+ return actual ;
50
+ }
51
+
33
52
describe ( 'ChromeAdapter' , ( ) => {
34
53
describe ( 'isAvailable' , ( ) => {
35
54
it ( 'returns false if mode is only cloud' , async ( ) => {
@@ -307,4 +326,52 @@ describe('ChromeAdapter', () => {
307
326
} ) ;
308
327
} ) ;
309
328
} ) ;
329
+ describe ( 'generateContentStreamOnDevice' , ( ) => {
330
+ it ( 'generates content stream' , async ( ) => {
331
+ const languageModelProvider = {
332
+ create : ( ) => Promise . resolve ( { } )
333
+ } as LanguageModel ;
334
+ const languageModel = {
335
+ promptStreaming : _i => new ReadableStream ( )
336
+ } as LanguageModel ;
337
+ const createStub = stub ( languageModelProvider , 'create' ) . resolves (
338
+ languageModel
339
+ ) ;
340
+ const part = 'hi' ;
341
+ const promptStub = stub ( languageModel , 'promptStreaming' ) . returns (
342
+ new ReadableStream ( {
343
+ start ( controller ) {
344
+ controller . enqueue ( [ part ] ) ;
345
+ controller . close ( ) ;
346
+ }
347
+ } )
348
+ ) ;
349
+ const onDeviceParams = { } as LanguageModelCreateOptions ;
350
+ const adapter = new ChromeAdapter (
351
+ languageModelProvider ,
352
+ 'prefer_on_device' ,
353
+ onDeviceParams
354
+ ) ;
355
+ const request = {
356
+ contents : [ { role : 'user' , parts : [ { text : 'anything' } ] } ]
357
+ } as GenerateContentRequest ;
358
+ const response = await adapter . generateContentStreamOnDevice ( request ) ;
359
+ expect ( createStub ) . to . have . been . calledOnceWith ( onDeviceParams ) ;
360
+ expect ( promptStub ) . to . have . been . calledOnceWith ( [
361
+ {
362
+ role : request . contents [ 0 ] . role ,
363
+ content : [
364
+ {
365
+ type : 'text' ,
366
+ content : request . contents [ 0 ] . parts [ 0 ] . text
367
+ }
368
+ ]
369
+ }
370
+ ] ) ;
371
+ const actual = await toStringArray ( response . body ! ) ;
372
+ expect ( actual ) . to . deep . equal ( [
373
+ `data: {"candidates":[{"content":{"role":"model","parts":[{"text":["${ part } "]}]}}]}\n\n`
374
+ ] ) ;
375
+ } ) ;
376
+ } ) ;
310
377
} ) ;
0 commit comments