Skip to content

Commit a9d69bc

Browse files
committed
Docs and tests
1 parent 5afb9c6 commit a9d69bc

File tree

15 files changed

+299
-37
lines changed

15 files changed

+299
-37
lines changed

.changeset/nasty-rings-drop.md

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
---
2+
'@firebase/ai': minor
3+
'firebase': minor
4+
---
5+
6+
Add App Check limited use token option to `getAI()`.

common/api-review/ai.api.md

Lines changed: 15 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -4,10 +4,18 @@
44
55
```ts
66

7+
import { AppCheckInternalComponentName } from '@firebase/app-check-interop-types';
78
import { AppCheckTokenResult } from '@firebase/app-check-interop-types';
9+
import { ComponentContainer } from '@firebase/component';
810
import { FirebaseApp } from '@firebase/app';
11+
import { FirebaseAppCheckInternal } from '@firebase/app-check-interop-types';
12+
import { FirebaseAuthInternal } from '@firebase/auth-interop-types';
13+
import { FirebaseAuthInternalName } from '@firebase/auth-interop-types';
914
import { FirebaseAuthTokenData } from '@firebase/auth-interop-types';
1015
import { FirebaseError } from '@firebase/util';
16+
import { _FirebaseService } from '@firebase/app';
17+
import { InstanceFactoryOptions } from '@firebase/component';
18+
import { Provider } from '@firebase/component';
1119

1220
// @public
1321
export interface AI {
@@ -54,7 +62,7 @@ export abstract class AIModel {
5462
// Warning: (ae-forgotten-export) The symbol "ApiSettings" needs to be exported by the entry point index.d.ts
5563
//
5664
// @internal (undocumented)
57-
protected _apiSettings: ApiSettings;
65+
_apiSettings: ApiSettings;
5866
readonly model: string;
5967
// @internal
6068
static normalizeModelName(modelName: string, backendType: BackendType): string;
@@ -63,7 +71,7 @@ export abstract class AIModel {
6371
// @public
6472
export interface AIOptions {
6573
appCheck?: AppCheckOptions;
66-
backend: Backend;
74+
backend?: Backend;
6775
}
6876

6977
// @public
@@ -79,7 +87,6 @@ export class AnyOfSchema extends Schema {
7987

8088
// @public
8189
export interface AppCheckOptions {
82-
// (undocumented)
8390
limitedUseTokens?: boolean;
8491
}
8592

@@ -228,6 +235,11 @@ export interface ErrorDetails {
228235
reason?: string;
229236
}
230237

238+
// Warning: (ae-forgotten-export) The symbol "AIService" needs to be exported by the entry point index.d.ts
239+
//
240+
// @public (undocumented)
241+
export function factory(container: ComponentContainer, { instanceIdentifier }: InstanceFactoryOptions): AIService;
242+
231243
// @public
232244
export interface FileData {
233245
// (undocumented)

docs-devsite/_toc.yaml

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,8 @@ toc:
1414
path: /docs/reference/js/ai.aioptions.md
1515
- title: AnyOfSchema
1616
path: /docs/reference/js/ai.anyofschema.md
17+
- title: AppCheckOptions
18+
path: /docs/reference/js/ai.appcheckoptions.md
1719
- title: ArraySchema
1820
path: /docs/reference/js/ai.arrayschema.md
1921
- title: Backend

docs-devsite/ai.ai.md

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,7 @@ export interface AI
2727
| [app](./ai.ai.md#aiapp) | [FirebaseApp](./app.firebaseapp.md#firebaseapp_interface) | The [FirebaseApp](./app.firebaseapp.md#firebaseapp_interface) this [AI](./ai.ai.md#ai_interface) instance is associated with. |
2828
| [backend](./ai.ai.md#aibackend) | [Backend](./ai.backend.md#backend_class) | A [Backend](./ai.backend.md#backend_class) instance that specifies the configuration for the target backend, either the Gemini Developer API (using [GoogleAIBackend](./ai.googleaibackend.md#googleaibackend_class)<!-- -->) or the Vertex AI Gemini API (using [VertexAIBackend](./ai.vertexaibackend.md#vertexaibackend_class)<!-- -->). |
2929
| [location](./ai.ai.md#ailocation) | string | |
30+
| [options](./ai.ai.md#aioptions) | [AIOptions](./ai.aioptions.md#aioptions_interface) | Options applied to this [AI](./ai.ai.md#ai_interface) instance. |
3031

3132
## AI.app
3233

@@ -62,3 +63,13 @@ backend: Backend;
6263
```typescript
6364
location: string;
6465
```
66+
67+
## AI.options
68+
69+
Options applied to this [AI](./ai.ai.md#ai_interface) instance.
70+
71+
<b>Signature:</b>
72+
73+
```typescript
74+
options?: AIOptions;
75+
```

docs-devsite/ai.aioptions.md

Lines changed: 14 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -22,14 +22,25 @@ export interface AIOptions
2222

2323
| Property | Type | Description |
2424
| --- | --- | --- |
25-
| [backend](./ai.aioptions.md#aioptionsbackend) | [Backend](./ai.backend.md#backend_class) | The backend configuration to use for the AI service instance. |
25+
| [appCheck](./ai.aioptions.md#aioptionsappcheck) | [AppCheckOptions](./ai.appcheckoptions.md#appcheckoptions_interface) | Configures App Check usage for this AI service instance. |
26+
| [backend](./ai.aioptions.md#aioptionsbackend) | [Backend](./ai.backend.md#backend_class) | The backend configuration to use for the AI service instance. Defaults to [GoogleAIBackend](./ai.googleaibackend.md#googleaibackend_class)<!-- -->. |
27+
28+
## AIOptions.appCheck
29+
30+
Configures App Check usage for this AI service instance.
31+
32+
<b>Signature:</b>
33+
34+
```typescript
35+
appCheck?: AppCheckOptions;
36+
```
2637

2738
## AIOptions.backend
2839

29-
The backend configuration to use for the AI service instance.
40+
The backend configuration to use for the AI service instance. Defaults to [GoogleAIBackend](./ai.googleaibackend.md#googleaibackend_class)<!-- -->.
3041

3142
<b>Signature:</b>
3243

3344
```typescript
34-
backend: Backend;
45+
backend?: Backend;
3546
```

docs-devsite/ai.appcheckoptions.md

Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,35 @@
1+
Project: /docs/reference/js/_project.yaml
2+
Book: /docs/reference/_book.yaml
3+
page_type: reference
4+
5+
{% comment %}
6+
DO NOT EDIT THIS FILE!
7+
This is generated by the JS SDK team, and any local changes will be
8+
overwritten. Changes should be made in the source code at
9+
https://github.com/firebase/firebase-js-sdk
10+
{% endcomment %}
11+
12+
# AppCheckOptions interface
13+
Configures App Check usage for this AI service instance.
14+
15+
<b>Signature:</b>
16+
17+
```typescript
18+
export interface AppCheckOptions
19+
```
20+
21+
## Properties
22+
23+
| Property | Type | Description |
24+
| --- | --- | --- |
25+
| [limitedUseTokens](./ai.appcheckoptions.md#appcheckoptionslimitedusetokens) | boolean | Defaults to false. |
26+
27+
## AppCheckOptions.limitedUseTokens
28+
29+
Defaults to false.
30+
31+
<b>Signature:</b>
32+
33+
```typescript
34+
limitedUseTokens?: boolean;
35+
```

docs-devsite/ai.md

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,8 @@ The Firebase AI Web SDK.
2121
| <b>function(ai, ...)</b> |
2222
| [getGenerativeModel(ai, modelParams, requestOptions)](./ai.md#getgenerativemodel_80bd839) | Returns a [GenerativeModel](./ai.generativemodel.md#generativemodel_class) class with methods for inference and other functionality. |
2323
| [getImagenModel(ai, modelParams, requestOptions)](./ai.md#getimagenmodel_e1f6645) | <b><i>(Public Preview)</i></b> Returns an [ImagenModel](./ai.imagenmodel.md#imagenmodel_class) class with methods for using Imagen.<!-- -->Only Imagen 3 models (named <code>imagen-3.0-*</code>) are supported. |
24+
| <b>function(container, ...)</b> |
25+
| [factory(container, { instanceIdentifier })](./ai.md#factory_6581aeb) | |
2426

2527
## Classes
2628

@@ -50,6 +52,7 @@ The Firebase AI Web SDK.
5052
| --- | --- |
5153
| [AI](./ai.ai.md#ai_interface) | An instance of the Firebase AI SDK.<!-- -->Do not create this instance directly. Instead, use [getAI()](./ai.md#getai_a94a413)<!-- -->. |
5254
| [AIOptions](./ai.aioptions.md#aioptions_interface) | Options for initializing the AI service using [getAI()](./ai.md#getai_a94a413)<!-- -->. This allows specifying which backend to use (Vertex AI Gemini API or Gemini Developer API) and configuring its specific options (like location for Vertex AI). |
55+
| [AppCheckOptions](./ai.appcheckoptions.md#appcheckoptions_interface) | Configures App Check usage for this AI service instance. |
5356
| [BaseParams](./ai.baseparams.md#baseparams_interface) | Base parameters for a number of methods. |
5457
| [Citation](./ai.citation.md#citation_interface) | A single citation. |
5558
| [CitationMetadata](./ai.citationmetadata.md#citationmetadata_interface) | Citation metadata that may be found on a [GenerateContentCandidate](./ai.generatecontentcandidate.md#generatecontentcandidate_interface)<!-- -->. |
@@ -264,6 +267,27 @@ export declare function getImagenModel(ai: AI, modelParams: ImagenModelParams, r
264267

265268
If the `apiKey` or `projectId` fields are missing in your Firebase config.
266269

270+
## function(container, ...)
271+
272+
### factory(container, { instanceIdentifier }) {:#factory_6581aeb}
273+
274+
<b>Signature:</b>
275+
276+
```typescript
277+
export declare function factory(container: ComponentContainer, { instanceIdentifier }: InstanceFactoryOptions): AIService;
278+
```
279+
280+
#### Parameters
281+
282+
| Parameter | Type | Description |
283+
| --- | --- | --- |
284+
| container | ComponentContainer | |
285+
| { instanceIdentifier } | InstanceFactoryOptions | |
286+
287+
<b>Returns:</b>
288+
289+
AIService
290+
267291
## AIErrorCode
268292

269293
Standardized error codes that [AIError](./ai.aierror.md#aierror_class) can have.

packages/ai/src/api.test.ts

Lines changed: 29 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -16,12 +16,13 @@
1616
*/
1717
import { ImagenModelParams, ModelParams, AIErrorCode } from './types';
1818
import { AIError } from './errors';
19-
import { ImagenModel, getGenerativeModel, getImagenModel } from './api';
19+
import { getAI, ImagenModel, getGenerativeModel, getImagenModel } from './api';
2020
import { expect } from 'chai';
2121
import { AI } from './public-types';
2222
import { GenerativeModel } from './models/generative-model';
23-
import { VertexAIBackend } from './backend';
23+
import { GoogleAIBackend, VertexAIBackend } from './backend';
2424
import { AI_TYPE } from './constants';
25+
import { getFullApp } from '../test-utils/get-fake-firebase-services';
2526

2627
const fakeAI: AI = {
2728
app: {
@@ -38,6 +39,32 @@ const fakeAI: AI = {
3839
};
3940

4041
describe('Top level API', () => {
42+
describe('getAI()', () => {
43+
it('works without options', () => {
44+
const ai = getAI(getFullApp());
45+
expect(ai.backend).to.be.instanceOf(GoogleAIBackend);
46+
});
47+
it('works with options: no backend, limited use token', () => {
48+
const ai = getAI(getFullApp(), { appCheck: { limitedUseTokens: true } });
49+
expect(ai.backend).to.be.instanceOf(GoogleAIBackend);
50+
expect(ai.options?.appCheck?.limitedUseTokens).to.be.true;
51+
});
52+
it('works with options: backend specified, limited use token', () => {
53+
const ai = getAI(getFullApp(), {
54+
backend: new VertexAIBackend('us-central1'),
55+
appCheck: { limitedUseTokens: true }
56+
});
57+
expect(ai.backend).to.be.instanceOf(VertexAIBackend);
58+
expect(ai.options?.appCheck?.limitedUseTokens).to.be.true;
59+
});
60+
it('works with options: backend specified only', () => {
61+
const ai = getAI(getFullApp(), {
62+
backend: new VertexAIBackend('us-central1')
63+
});
64+
expect(ai.backend).to.be.instanceOf(VertexAIBackend);
65+
expect(ai.options?.appCheck?.limitedUseTokens).to.be.false;
66+
});
67+
});
4168
it('getGenerativeModel throws if no model is provided', () => {
4269
try {
4370
getGenerativeModel(fakeAI, {} as ModelParams);

packages/ai/src/api.ts

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -77,12 +77,13 @@ export function getAI(app: FirebaseApp = getApp(), options?: AIOptions): AI {
7777
// Dependencies
7878
const AIProvider: Provider<'AI'> = _getProvider(app, AI_TYPE);
7979

80+
const backend = options?.backend ?? new GoogleAIBackend();
81+
8082
const finalOptions = {
81-
backend: options?.backend ?? new GoogleAIBackend(),
8283
appCheck: options?.appCheck ?? { limitedUseTokens: false }
8384
};
8485

85-
const identifier = encodeInstanceIdentifier(finalOptions.backend);
86+
const identifier = encodeInstanceIdentifier(backend);
8687
const aiInstance = AIProvider.getImmediate({
8788
identifier
8889
});

packages/ai/src/index.ts

Lines changed: 29 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -24,7 +24,12 @@
2424
import { registerVersion, _registerComponent } from '@firebase/app';
2525
import { AIService } from './service';
2626
import { AI_TYPE } from './constants';
27-
import { Component, ComponentType } from '@firebase/component';
27+
import {
28+
Component,
29+
ComponentContainer,
30+
ComponentType,
31+
InstanceFactoryOptions
32+
} from '@firebase/component';
2833
import { name, version } from '../package.json';
2934
import { decodeInstanceIdentifier } from './helpers';
3035
import { AIError } from './api';
@@ -36,28 +41,31 @@ declare global {
3641
}
3742
}
3843

39-
function registerAI(): void {
40-
_registerComponent(
41-
new Component(
42-
AI_TYPE,
43-
(container, { instanceIdentifier }) => {
44-
if (!instanceIdentifier) {
45-
throw new AIError(
46-
AIErrorCode.ERROR,
47-
'AIService instance identifier is undefined.'
48-
);
49-
}
44+
export function factory(
45+
container: ComponentContainer,
46+
{ instanceIdentifier }: InstanceFactoryOptions
47+
): AIService {
48+
if (!instanceIdentifier) {
49+
throw new AIError(
50+
AIErrorCode.ERROR,
51+
'AIService instance identifier is undefined.'
52+
);
53+
}
5054

51-
const backend = decodeInstanceIdentifier(instanceIdentifier);
55+
const backend = decodeInstanceIdentifier(instanceIdentifier);
5256

53-
// getImmediate for FirebaseApp will always succeed
54-
const app = container.getProvider('app').getImmediate();
55-
const auth = container.getProvider('auth-internal');
56-
const appCheckProvider = container.getProvider('app-check-internal');
57-
return new AIService(app, backend, auth, appCheckProvider);
58-
},
59-
ComponentType.PUBLIC
60-
).setMultipleInstances(true)
57+
// getImmediate for FirebaseApp will always succeed
58+
const app = container.getProvider('app').getImmediate();
59+
const auth = container.getProvider('auth-internal');
60+
const appCheckProvider = container.getProvider('app-check-internal');
61+
return new AIService(app, backend, auth, appCheckProvider);
62+
}
63+
64+
function registerAI(): void {
65+
_registerComponent(
66+
new Component(AI_TYPE, factory, ComponentType.PUBLIC).setMultipleInstances(
67+
true
68+
)
6169
);
6270

6371
registerVersion(name, version);

0 commit comments

Comments
 (0)