@@ -41,8 +41,10 @@ export class ChromeAdapter {
41
41
constructor (
42
42
private languageModelProvider ?: LanguageModel ,
43
43
private mode ?: InferenceMode ,
44
- private onDeviceParams ?: LanguageModelCreateOptions
45
- ) { }
44
+ private onDeviceParams : LanguageModelCreateOptions = { }
45
+ ) {
46
+ this . addImageTypeAsExpectedInput ( ) ;
47
+ }
46
48
47
49
/**
48
50
* Checks if a given request can be made on-device.
@@ -64,12 +66,8 @@ export class ChromeAdapter {
64
66
return false ;
65
67
}
66
68
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 ( ) ;
73
71
74
72
if ( this . mode === 'only_on_device' ) {
75
73
return true ;
@@ -91,10 +89,7 @@ export class ChromeAdapter {
91
89
* @returns {@link Response }, so we can reuse common response formatting.
92
90
*/
93
91
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 ( ) ;
98
93
// TODO: support multiple content objects when Chrome supports
99
94
// sequence<LanguageModelMessage>
100
95
const contents = await Promise . all (
@@ -115,10 +110,7 @@ export class ChromeAdapter {
115
110
async generateContentStream (
116
111
request : GenerateContentRequest
117
112
) : 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 ( ) ;
122
114
// TODO: support multiple content objects when Chrome supports
123
115
// sequence<LanguageModelMessage>
124
116
const contents = await Promise . all (
@@ -155,7 +147,22 @@ export class ChromeAdapter {
155
147
}
156
148
157
149
/**
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.
159
166
*
160
167
* <p>Chrome only downloads models as needed. Chrome knows a model is needed when code calls
161
168
* LanguageModel.create.</p>
@@ -168,10 +175,8 @@ export class ChromeAdapter {
168
175
return ;
169
176
}
170
177
this . isDownloading = true ;
171
- const options = this . onDeviceParams || { } ;
172
- ChromeAdapter . addImageTypeAsExpectedInput ( options ) ;
173
178
this . downloadPromise = this . languageModelProvider
174
- ?. create ( options )
179
+ ?. create ( this . onDeviceParams )
175
180
. then ( ( ) => {
176
181
this . isDownloading = false ;
177
182
} ) ;
@@ -214,19 +219,16 @@ export class ChromeAdapter {
214
219
* <p>Chrome will remove a model from memory if it's no longer in use, so this method ensures a
215
220
* new session is created before an old session is destroyed.</p>
216
221
*/
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 > {
221
223
if ( ! this . languageModelProvider ) {
222
224
throw new AIError (
223
225
AIErrorCode . REQUEST_ERROR ,
224
226
'Chrome AI requested for unsupported browser version.'
225
227
) ;
226
228
}
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
+ ) ;
230
232
if ( this . oldSession ) {
231
233
this . oldSession . destroy ( ) ;
232
234
}
@@ -235,11 +237,9 @@ export class ChromeAdapter {
235
237
return newSession ;
236
238
}
237
239
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' } ] ;
243
243
}
244
244
245
245
/**
0 commit comments