Skip to content

Commit ef893c9

Browse files
committed
Integrate chrome adapter into stream methods
1 parent 2fb2795 commit ef893c9

File tree

5 files changed

+72
-24
lines changed

5 files changed

+72
-24
lines changed

e2e/sample-apps/modular.js

Lines changed: 7 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -58,16 +58,7 @@ import {
5858
onValue,
5959
off
6060
} from 'firebase/database';
61-
<<<<<<< HEAD
6261
import { getGenerativeModel, getVertexAI } from 'firebase/vertexai';
63-
=======
64-
import {
65-
getGenerativeModel,
66-
getVertexAI,
67-
InferenceMode,
68-
VertexAI
69-
} from 'firebase/vertexai';
70-
>>>>>>> 3f02db006 (Run yarn format)
7162
import { getDataConnect, DataConnect } from 'firebase/data-connect';
7263

7364
/**
@@ -322,8 +313,13 @@ function callPerformance(app) {
322313
async function callVertexAI(app) {
323314
console.log('[VERTEXAI] start');
324315
const vertexAI = getVertexAI(app);
325-
const model = getGenerativeModel(vertexAI, { model: 'gemini-1.5-flash' });
326-
const result = await model.countTokens('abcdefg');
316+
const model = getGenerativeModel(vertexAI, {
317+
mode: 'prefer_in_cloud'
318+
});
319+
const result = await model.generateContentStream("What is Roko's Basalisk?");
320+
for await (const chunk of result.stream) {
321+
console.log(chunk.text());
322+
}
327323
console.log(`[VERTEXAI] counted tokens: ${result.totalTokens}`);
328324
}
329325

@@ -341,15 +337,6 @@ function callDataConnect(app) {
341337
console.log('[DATACONNECT] initialized');
342338
}
343339

344-
async function callVertex(app) {
345-
console.log('[VERTEX] start');
346-
const vertex = getVertexAI(app);
347-
const model = getGenerativeModel(vertex, { mode: 'prefer_on_device' });
348-
const result = await model.generateContent("What is Roko's Basalisk?");
349-
console.log(result.response.text());
350-
console.log('[VERTEX] initialized');
351-
}
352-
353340
/**
354341
* Run smoke tests for all products.
355342
* Comment out any products you want to ignore.
@@ -371,7 +358,6 @@ async function main() {
371358
await callVertexAI(app);
372359
callDataConnect(app);
373360
await authLogout(app);
374-
await callVertex(app);
375361
console.log('DONE');
376362
}
377363

packages/vertexai/src/methods/chat-session.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -149,6 +149,7 @@ export class ChatSession {
149149
this._apiSettings,
150150
this.model,
151151
generateContentRequest,
152+
this.chromeAdapter,
152153
this.requestOptions
153154
);
154155

packages/vertexai/src/methods/chrome-adapter.ts

Lines changed: 40 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -117,6 +117,46 @@ export class ChromeAdapter {
117117
} as Response;
118118
}
119119

120+
/**
121+
* Generates a stream of content.
122+
*/
123+
async generateContentStreamOnDevice(
124+
request: GenerateContentRequest
125+
): Promise<Response> {
126+
const session = await this.createSession(
127+
// TODO: normalize on-device params during construction.
128+
this.onDeviceParams || {}
129+
);
130+
const messages = ChromeAdapter.toLanguageModelMessages(request.contents);
131+
const stream = await session.promptStreaming(messages);
132+
return ChromeAdapter.toStreamResponse(stream);
133+
}
134+
// Formats string stream returned by Chrome as SSE returned by Vertex.
135+
private static async toStreamResponse(
136+
stream: ReadableStream<string>
137+
): Promise<Response> {
138+
const encoder = new TextEncoder();
139+
return {
140+
body: stream.pipeThrough(
141+
new TransformStream({
142+
transform(chunk, controller) {
143+
const json = JSON.stringify({
144+
candidates: [
145+
{
146+
content: {
147+
role: 'model',
148+
parts: [{ text: chunk }]
149+
}
150+
}
151+
]
152+
});
153+
controller.enqueue(encoder.encode(`data: ${json}\n\n`));
154+
}
155+
})
156+
)
157+
} as Response;
158+
}
159+
120160
/**
121161
* Asserts inference for the given request can be performed by an on-device model.
122162
*/

packages/vertexai/src/methods/generate-content.ts

Lines changed: 23 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -28,20 +28,40 @@ import { processStream } from '../requests/stream-reader';
2828
import { ApiSettings } from '../types/internal';
2929
import { ChromeAdapter } from './chrome-adapter';
3030

31-
export async function generateContentStream(
31+
async function generateContentStreamOnCloud(
3232
apiSettings: ApiSettings,
3333
model: string,
3434
params: GenerateContentRequest,
3535
requestOptions?: RequestOptions
36-
): Promise<GenerateContentStreamResult> {
37-
const response = await makeRequest(
36+
): Promise<Response> {
37+
return makeRequest(
3838
model,
3939
Task.STREAM_GENERATE_CONTENT,
4040
apiSettings,
4141
/* stream */ true,
4242
JSON.stringify(params),
4343
requestOptions
4444
);
45+
}
46+
47+
export async function generateContentStream(
48+
apiSettings: ApiSettings,
49+
model: string,
50+
params: GenerateContentRequest,
51+
chromeAdapter: ChromeAdapter,
52+
requestOptions?: RequestOptions
53+
): Promise<GenerateContentStreamResult> {
54+
let response;
55+
if (await chromeAdapter.isAvailable(params)) {
56+
response = await chromeAdapter.generateContentStreamOnDevice(params);
57+
} else {
58+
response = await generateContentStreamOnCloud(
59+
apiSettings,
60+
model,
61+
params,
62+
requestOptions
63+
);
64+
}
4565
return processStream(response);
4666
}
4767

packages/vertexai/src/models/generative-model.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -123,6 +123,7 @@ export class GenerativeModel extends VertexAIModel {
123123
systemInstruction: this.systemInstruction,
124124
...formattedParams
125125
},
126+
this.chromeAdapter,
126127
this.requestOptions
127128
);
128129
}

0 commit comments

Comments
 (0)