@firebase/ai 2.4.0-canary.261508183 → 2.4.0-canary.91c218db2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -558,6 +558,12 @@ export declare interface EnhancedGenerateContentResponse extends GenerateContent
558
558
  * set to `true`.
559
559
  */
560
560
  thoughtSummary: () => string | undefined;
561
+ /**
562
+ * Indicates whether inference happened on-device or in-cloud.
563
+ *
564
+ * @beta
565
+ */
566
+ inferenceSource?: InferenceSource;
561
567
  }
562
568
 
563
569
  /**
@@ -1833,6 +1839,23 @@ export declare const InferenceMode: {
1833
1839
  */
1834
1840
  export declare type InferenceMode = (typeof InferenceMode)[keyof typeof InferenceMode];
1835
1841
 
1842
+ /**
1843
+ * Indicates whether inference happened on-device or in-cloud.
1844
+ *
1845
+ * @beta
1846
+ */
1847
+ export declare const InferenceSource: {
1848
+ readonly ON_DEVICE: "on_device";
1849
+ readonly IN_CLOUD: "in_cloud";
1850
+ };
1851
+
1852
+ /**
1853
+ * Indicates whether inference happened on-device or in-cloud.
1854
+ *
1855
+ * @beta
1856
+ */
1857
+ export declare type InferenceSource = (typeof InferenceSource)[keyof typeof InferenceSource];
1858
+
1836
1859
  /**
1837
1860
  * Content part interface if the part represents an image.
1838
1861
  * @public
package/dist/ai.d.ts CHANGED
@@ -604,6 +604,12 @@ export declare interface EnhancedGenerateContentResponse extends GenerateContent
604
604
  * set to `true`.
605
605
  */
606
606
  thoughtSummary: () => string | undefined;
607
+ /**
608
+ * Indicates whether inference happened on-device or in-cloud.
609
+ *
610
+ * @beta
611
+ */
612
+ inferenceSource?: InferenceSource;
607
613
  }
608
614
 
609
615
  /**
@@ -1945,6 +1951,23 @@ export declare const InferenceMode: {
1945
1951
  */
1946
1952
  export declare type InferenceMode = (typeof InferenceMode)[keyof typeof InferenceMode];
1947
1953
 
1954
+ /**
1955
+ * Indicates whether inference happened on-device or in-cloud.
1956
+ *
1957
+ * @beta
1958
+ */
1959
+ export declare const InferenceSource: {
1960
+ readonly ON_DEVICE: "on_device";
1961
+ readonly IN_CLOUD: "in_cloud";
1962
+ };
1963
+
1964
+ /**
1965
+ * Indicates whether inference happened on-device or in-cloud.
1966
+ *
1967
+ * @beta
1968
+ */
1969
+ export declare type InferenceSource = (typeof InferenceSource)[keyof typeof InferenceSource];
1970
+
1948
1971
  /**
1949
1972
  * Content part interface if the part represents an image.
1950
1973
  * @public
@@ -4,7 +4,7 @@ import { FirebaseError, Deferred, getModularInstance } from '@firebase/util';
4
4
  import { Logger } from '@firebase/logger';
5
5
 
6
6
  var name = "@firebase/ai";
7
- var version = "2.4.0-canary.261508183";
7
+ var version = "2.4.0-canary.91c218db2";
8
8
 
9
9
  /**
10
10
  * @license
@@ -379,6 +379,15 @@ const InferenceMode = {
379
379
  'ONLY_IN_CLOUD': 'only_in_cloud',
380
380
  'PREFER_IN_CLOUD': 'prefer_in_cloud'
381
381
  };
382
+ /**
383
+ * Indicates whether inference happened on-device or in-cloud.
384
+ *
385
+ * @beta
386
+ */
387
+ const InferenceSource = {
388
+ 'ON_DEVICE': 'on_device',
389
+ 'IN_CLOUD': 'in_cloud'
390
+ };
382
391
  /**
383
392
  * Represents the result of the code execution.
384
393
  *
@@ -888,22 +897,35 @@ var Availability;
888
897
  * See the License for the specific language governing permissions and
889
898
  * limitations under the License.
890
899
  */
900
+ // Defaults to support image inputs for convenience.
901
+ const defaultExpectedInputs = [{ type: 'image' }];
891
902
  /**
892
903
  * Defines an inference "backend" that uses Chrome's on-device model,
893
904
  * and encapsulates logic for detecting when on-device inference is
894
905
  * possible.
895
906
  */
896
907
  class ChromeAdapterImpl {
897
- constructor(languageModelProvider, mode, onDeviceParams = {
898
- createOptions: {
899
- // Defaults to support image inputs for convenience.
900
- expectedInputs: [{ type: 'image' }]
901
- }
902
- }) {
908
+ constructor(languageModelProvider, mode, onDeviceParams) {
903
909
  this.languageModelProvider = languageModelProvider;
904
910
  this.mode = mode;
905
- this.onDeviceParams = onDeviceParams;
906
911
  this.isDownloading = false;
912
+ this.onDeviceParams = {
913
+ createOptions: {
914
+ expectedInputs: defaultExpectedInputs
915
+ }
916
+ };
917
+ if (onDeviceParams) {
918
+ this.onDeviceParams = onDeviceParams;
919
+ if (!this.onDeviceParams.createOptions) {
920
+ this.onDeviceParams.createOptions = {
921
+ expectedInputs: defaultExpectedInputs
922
+ };
923
+ }
924
+ else if (!this.onDeviceParams.createOptions.expectedInputs) {
925
+ this.onDeviceParams.createOptions.expectedInputs =
926
+ defaultExpectedInputs;
927
+ }
928
+ }
907
929
  }
908
930
  /**
909
931
  * Checks if a given request can be made on-device.
@@ -1592,7 +1614,7 @@ function hasValidCandidates(response) {
1592
1614
  * Creates an EnhancedGenerateContentResponse object that has helper functions and
1593
1615
  * other modifications that improve usability.
1594
1616
  */
1595
- function createEnhancedContentResponse(response) {
1617
+ function createEnhancedContentResponse(response, inferenceSource = InferenceSource.IN_CLOUD) {
1596
1618
  /**
1597
1619
  * The Vertex AI backend omits default values.
1598
1620
  * This causes the `index` property to be omitted from the first candidate in the
@@ -1603,6 +1625,7 @@ function createEnhancedContentResponse(response) {
1603
1625
  response.candidates[0].index = 0;
1604
1626
  }
1605
1627
  const responseWithHelpers = addHelpers(response);
1628
+ responseWithHelpers.inferenceSource = inferenceSource;
1606
1629
  return responseWithHelpers;
1607
1630
  }
1608
1631
  /**
@@ -1979,16 +2002,16 @@ const responseLineRE = /^data\: (.*)(?:\n\n|\r\r|\r\n\r\n)/;
1979
2002
  *
1980
2003
  * @param response - Response from a fetch call
1981
2004
  */
1982
- function processStream(response, apiSettings) {
2005
+ function processStream(response, apiSettings, inferenceSource) {
1983
2006
  const inputStream = response.body.pipeThrough(new TextDecoderStream('utf8', { fatal: true }));
1984
2007
  const responseStream = getResponseStream(inputStream);
1985
2008
  const [stream1, stream2] = responseStream.tee();
1986
2009
  return {
1987
- stream: generateResponseSequence(stream1, apiSettings),
1988
- response: getResponsePromise(stream2, apiSettings)
2010
+ stream: generateResponseSequence(stream1, apiSettings, inferenceSource),
2011
+ response: getResponsePromise(stream2, apiSettings, inferenceSource)
1989
2012
  };
1990
2013
  }
1991
- async function getResponsePromise(stream, apiSettings) {
2014
+ async function getResponsePromise(stream, apiSettings, inferenceSource) {
1992
2015
  const allResponses = [];
1993
2016
  const reader = stream.getReader();
1994
2017
  while (true) {
@@ -1998,12 +2021,12 @@ async function getResponsePromise(stream, apiSettings) {
1998
2021
  if (apiSettings.backend.backendType === BackendType.GOOGLE_AI) {
1999
2022
  generateContentResponse = mapGenerateContentResponse(generateContentResponse);
2000
2023
  }
2001
- return createEnhancedContentResponse(generateContentResponse);
2024
+ return createEnhancedContentResponse(generateContentResponse, inferenceSource);
2002
2025
  }
2003
2026
  allResponses.push(value);
2004
2027
  }
2005
2028
  }
2006
- async function* generateResponseSequence(stream, apiSettings) {
2029
+ async function* generateResponseSequence(stream, apiSettings, inferenceSource) {
2007
2030
  const reader = stream.getReader();
2008
2031
  while (true) {
2009
2032
  const { value, done } = await reader.read();
@@ -2012,10 +2035,10 @@ async function* generateResponseSequence(stream, apiSettings) {
2012
2035
  }
2013
2036
  let enhancedResponse;
2014
2037
  if (apiSettings.backend.backendType === BackendType.GOOGLE_AI) {
2015
- enhancedResponse = createEnhancedContentResponse(mapGenerateContentResponse(value));
2038
+ enhancedResponse = createEnhancedContentResponse(mapGenerateContentResponse(value), inferenceSource);
2016
2039
  }
2017
2040
  else {
2018
- enhancedResponse = createEnhancedContentResponse(value);
2041
+ enhancedResponse = createEnhancedContentResponse(value, inferenceSource);
2019
2042
  }
2020
2043
  const firstCandidate = enhancedResponse.candidates?.[0];
2021
2044
  // Don't yield a response with no useful data for the developer.
@@ -2185,31 +2208,52 @@ const errorsCausingFallback = [
2185
2208
  */
2186
2209
  async function callCloudOrDevice(request, chromeAdapter, onDeviceCall, inCloudCall) {
2187
2210
  if (!chromeAdapter) {
2188
- return inCloudCall();
2211
+ return {
2212
+ response: await inCloudCall(),
2213
+ inferenceSource: InferenceSource.IN_CLOUD
2214
+ };
2189
2215
  }
2190
2216
  switch (chromeAdapter.mode) {
2191
2217
  case InferenceMode.ONLY_ON_DEVICE:
2192
2218
  if (await chromeAdapter.isAvailable(request)) {
2193
- return onDeviceCall();
2219
+ return {
2220
+ response: await onDeviceCall(),
2221
+ inferenceSource: InferenceSource.ON_DEVICE
2222
+ };
2194
2223
  }
2195
2224
  throw new AIError(AIErrorCode.UNSUPPORTED, 'Inference mode is ONLY_ON_DEVICE, but an on-device model is not available.');
2196
2225
  case InferenceMode.ONLY_IN_CLOUD:
2197
- return inCloudCall();
2226
+ return {
2227
+ response: await inCloudCall(),
2228
+ inferenceSource: InferenceSource.IN_CLOUD
2229
+ };
2198
2230
  case InferenceMode.PREFER_IN_CLOUD:
2199
2231
  try {
2200
- return await inCloudCall();
2232
+ return {
2233
+ response: await inCloudCall(),
2234
+ inferenceSource: InferenceSource.IN_CLOUD
2235
+ };
2201
2236
  }
2202
2237
  catch (e) {
2203
2238
  if (e instanceof AIError && errorsCausingFallback.includes(e.code)) {
2204
- return onDeviceCall();
2239
+ return {
2240
+ response: await onDeviceCall(),
2241
+ inferenceSource: InferenceSource.ON_DEVICE
2242
+ };
2205
2243
  }
2206
2244
  throw e;
2207
2245
  }
2208
2246
  case InferenceMode.PREFER_ON_DEVICE:
2209
2247
  if (await chromeAdapter.isAvailable(request)) {
2210
- return onDeviceCall();
2248
+ return {
2249
+ response: await onDeviceCall(),
2250
+ inferenceSource: InferenceSource.ON_DEVICE
2251
+ };
2211
2252
  }
2212
- return inCloudCall();
2253
+ return {
2254
+ response: await inCloudCall(),
2255
+ inferenceSource: InferenceSource.IN_CLOUD
2256
+ };
2213
2257
  default:
2214
2258
  throw new AIError(AIErrorCode.ERROR, `Unexpected infererence mode: ${chromeAdapter.mode}`);
2215
2259
  }
@@ -2239,8 +2283,8 @@ async function generateContentStreamOnCloud(apiSettings, model, params, requestO
2239
2283
  /* stream */ true, JSON.stringify(params), requestOptions);
2240
2284
  }
2241
2285
  async function generateContentStream(apiSettings, model, params, chromeAdapter, requestOptions) {
2242
- const response = await callCloudOrDevice(params, chromeAdapter, () => chromeAdapter.generateContentStream(params), () => generateContentStreamOnCloud(apiSettings, model, params, requestOptions));
2243
- return processStream(response, apiSettings); // TODO: Map streaming responses
2286
+ const callResult = await callCloudOrDevice(params, chromeAdapter, () => chromeAdapter.generateContentStream(params), () => generateContentStreamOnCloud(apiSettings, model, params, requestOptions));
2287
+ return processStream(callResult.response, apiSettings); // TODO: Map streaming responses
2244
2288
  }
2245
2289
  async function generateContentOnCloud(apiSettings, model, params, requestOptions) {
2246
2290
  if (apiSettings.backend.backendType === BackendType.GOOGLE_AI) {
@@ -2250,9 +2294,9 @@ async function generateContentOnCloud(apiSettings, model, params, requestOptions
2250
2294
  /* stream */ false, JSON.stringify(params), requestOptions);
2251
2295
  }
2252
2296
  async function generateContent(apiSettings, model, params, chromeAdapter, requestOptions) {
2253
- const response = await callCloudOrDevice(params, chromeAdapter, () => chromeAdapter.generateContent(params), () => generateContentOnCloud(apiSettings, model, params, requestOptions));
2254
- const generateContentResponse = await processGenerateContentResponse(response, apiSettings);
2255
- const enhancedResponse = createEnhancedContentResponse(generateContentResponse);
2297
+ const callResult = await callCloudOrDevice(params, chromeAdapter, () => chromeAdapter.generateContent(params), () => generateContentOnCloud(apiSettings, model, params, requestOptions));
2298
+ const generateContentResponse = await processGenerateContentResponse(callResult.response, apiSettings);
2299
+ const enhancedResponse = createEnhancedContentResponse(generateContentResponse, callResult.inferenceSource);
2256
2300
  return {
2257
2301
  response: enhancedResponse
2258
2302
  };
@@ -4109,5 +4153,5 @@ function registerAI() {
4109
4153
  }
4110
4154
  registerAI();
4111
4155
 
4112
- export { AIError, AIErrorCode, AIModel, AnyOfSchema, ArraySchema, Backend, BackendType, BlockReason, BooleanSchema, ChatSession, FinishReason, FunctionCallingMode, GenerativeModel, GoogleAIBackend, HarmBlockMethod, HarmBlockThreshold, HarmCategory, HarmProbability, HarmSeverity, ImagenAspectRatio, ImagenImageFormat, ImagenModel, ImagenPersonFilterLevel, ImagenSafetyFilterLevel, InferenceMode, IntegerSchema, Language, LiveGenerativeModel, LiveResponseType, LiveSession, Modality, NumberSchema, ObjectSchema, Outcome, POSSIBLE_ROLES, ResponseModality, Schema, SchemaType, StringSchema, URLRetrievalStatus, VertexAIBackend, getAI, getGenerativeModel, getImagenModel, getLiveGenerativeModel, startAudioConversation };
4156
+ export { AIError, AIErrorCode, AIModel, AnyOfSchema, ArraySchema, Backend, BackendType, BlockReason, BooleanSchema, ChatSession, FinishReason, FunctionCallingMode, GenerativeModel, GoogleAIBackend, HarmBlockMethod, HarmBlockThreshold, HarmCategory, HarmProbability, HarmSeverity, ImagenAspectRatio, ImagenImageFormat, ImagenModel, ImagenPersonFilterLevel, ImagenSafetyFilterLevel, InferenceMode, InferenceSource, IntegerSchema, Language, LiveGenerativeModel, LiveResponseType, LiveSession, Modality, NumberSchema, ObjectSchema, Outcome, POSSIBLE_ROLES, ResponseModality, Schema, SchemaType, StringSchema, URLRetrievalStatus, VertexAIBackend, getAI, getGenerativeModel, getImagenModel, getLiveGenerativeModel, startAudioConversation };
4113
4157
  //# sourceMappingURL=index.esm.js.map