Skip to content

Commit fafa6a8

Browse files
authored
VinF Hybrid Inference: consolidate onDeviceParams initialization (#8969)
1 parent dd0c4b1 commit fafa6a8

File tree

1 file changed

+32
-32
lines changed

1 file changed

+32
-32
lines changed

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

+32-32
Original file line numberDiff line numberDiff line change
@@ -41,8 +41,10 @@ export class ChromeAdapter {
4141
constructor(
4242
private languageModelProvider?: LanguageModel,
4343
private mode?: InferenceMode,
44-
private onDeviceParams?: LanguageModelCreateOptions
45-
) {}
44+
private onDeviceParams: LanguageModelCreateOptions = {}
45+
) {
46+
this.addImageTypeAsExpectedInput();
47+
}
4648

4749
/**
4850
* Checks if a given request can be made on-device.
@@ -64,12 +66,8 @@ export class ChromeAdapter {
6466
return false;
6567
}
6668

67-
const availability = await this.languageModelProvider?.availability();
68-
69-
// Triggers async model download so it'll be available next time.
70-
if (availability === Availability.downloadable) {
71-
this.download();
72-
}
69+
// Triggers out-of-band download so model will eventually become available.
70+
const availability = await this.downloadIfAvailable();
7371

7472
if (this.mode === 'only_on_device') {
7573
return true;
@@ -91,10 +89,7 @@ export class ChromeAdapter {
9189
* @returns {@link Response}, so we can reuse common response formatting.
9290
*/
9391
async generateContent(request: GenerateContentRequest): Promise<Response> {
94-
const session = await this.createSession(
95-
// TODO: normalize on-device params during construction.
96-
this.onDeviceParams || {}
97-
);
92+
const session = await this.createSession();
9893
// TODO: support multiple content objects when Chrome supports
9994
// sequence<LanguageModelMessage>
10095
const contents = await Promise.all(
@@ -115,10 +110,7 @@ export class ChromeAdapter {
115110
async generateContentStream(
116111
request: GenerateContentRequest
117112
): Promise<Response> {
118-
const session = await this.createSession(
119-
// TODO: normalize on-device params during construction.
120-
this.onDeviceParams || {}
121-
);
113+
const session = await this.createSession();
122114
// TODO: support multiple content objects when Chrome supports
123115
// sequence<LanguageModelMessage>
124116
const contents = await Promise.all(
@@ -155,7 +147,22 @@ export class ChromeAdapter {
155147
}
156148

157149
/**
158-
* Triggers the download of an on-device model.
150+
* Encapsulates logic to get availability and download a model if one is downloadable.
151+
*/
152+
private async downloadIfAvailable(): Promise<Availability | undefined> {
153+
const availability = await this.languageModelProvider?.availability(
154+
this.onDeviceParams
155+
);
156+
157+
if (availability === Availability.downloadable) {
158+
this.download();
159+
}
160+
161+
return availability;
162+
}
163+
164+
/**
165+
* Triggers out-of-band download of an on-device model.
159166
*
160167
* <p>Chrome only downloads models as needed. Chrome knows a model is needed when code calls
161168
* LanguageModel.create.</p>
@@ -168,10 +175,8 @@ export class ChromeAdapter {
168175
return;
169176
}
170177
this.isDownloading = true;
171-
const options = this.onDeviceParams || {};
172-
ChromeAdapter.addImageTypeAsExpectedInput(options);
173178
this.downloadPromise = this.languageModelProvider
174-
?.create(options)
179+
?.create(this.onDeviceParams)
175180
.then(() => {
176181
this.isDownloading = false;
177182
});
@@ -214,19 +219,16 @@ export class ChromeAdapter {
214219
* <p>Chrome will remove a model from memory if it's no longer in use, so this method ensures a
215220
* new session is created before an old session is destroyed.</p>
216221
*/
217-
private async createSession(
218-
// TODO: define a default value, since these are optional.
219-
options: LanguageModelCreateOptions
220-
): Promise<LanguageModel> {
222+
private async createSession(): Promise<LanguageModel> {
221223
if (!this.languageModelProvider) {
222224
throw new AIError(
223225
AIErrorCode.REQUEST_ERROR,
224226
'Chrome AI requested for unsupported browser version.'
225227
);
226228
}
227-
// TODO: could we use this.onDeviceParams instead of passing in options?
228-
ChromeAdapter.addImageTypeAsExpectedInput(options);
229-
const newSession = await this.languageModelProvider!.create(options);
229+
const newSession = await this.languageModelProvider.create(
230+
this.onDeviceParams
231+
);
230232
if (this.oldSession) {
231233
this.oldSession.destroy();
232234
}
@@ -235,11 +237,9 @@ export class ChromeAdapter {
235237
return newSession;
236238
}
237239

238-
private static addImageTypeAsExpectedInput(
239-
options: LanguageModelCreateOptions
240-
): void {
241-
options.expectedInputs = options.expectedInputs || [];
242-
options.expectedInputs.push({ type: 'image' });
240+
private addImageTypeAsExpectedInput(): void {
241+
// Defaults to support image inputs for convenience.
242+
this.onDeviceParams.expectedInputs ??= [{ type: 'image' }];
243243
}
244244

245245
/**

0 commit comments

Comments
 (0)