Skip to content

Commit 5a78b76

Browse files
committed
Convert backend types to classes
1 parent 4e831d1 commit 5a78b76

25 files changed

+194
-203
lines changed

common/api-review/vertexai.api.md

Lines changed: 1 addition & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@ import { FirebaseError } from '@firebase/util';
1212
// @public
1313
export interface AI {
1414
app: FirebaseApp;
15+
// Warning: (ae-forgotten-export) The symbol "Backend" needs to be exported by the entry point index.d.ts
1516
backend: Backend;
1617
// @deprecated
1718
location: string;
@@ -74,9 +75,6 @@ export class ArraySchema extends Schema {
7475
toJSON(): SchemaRequest;
7576
}
7677

77-
// @public
78-
export type Backend = GoogleAIBackend | VertexAIBackend;
79-
8078
// @public
8179
export const BackendType: {
8280
readonly VERTEX_AI: "VERTEX_AI";
@@ -422,14 +420,6 @@ export function getImagenModel(ai: AI, modelParams: ImagenModelParams, requestOp
422420
// @public
423421
export function getVertexAI(app?: FirebaseApp, options?: VertexAIOptions): VertexAI;
424422

425-
// @public
426-
export type GoogleAIBackend = {
427-
backendType: typeof BackendType.GOOGLE_AI;
428-
};
429-
430-
// @public
431-
export function googleAIBackend(): GoogleAIBackend;
432-
433423
// @public @deprecated (undocumented)
434424
export interface GroundingAttribution {
435425
// (undocumented)
@@ -859,15 +849,6 @@ export interface UsageMetadata {
859849
// @public
860850
export type VertexAI = AI;
861851

862-
// @public
863-
export type VertexAIBackend = {
864-
backendType: typeof BackendType.VERTEX_AI;
865-
location: string;
866-
};
867-
868-
// @public
869-
export function vertexAIBackend(location?: string): VertexAIBackend;
870-
871852
// @public
872853
export const VertexAIError: typeof AIError;
873854

config/.eslintrc.js

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -174,7 +174,8 @@ module.exports = {
174174
}
175175
}
176176
],
177-
'@typescript-eslint/consistent-type-definitions': ['error', 'interface'],
177+
// We prefer using interfaces, but we need to use types for aliases like '
178+
// '@typescript-eslint/consistent-type-definitions': ['error', 'interface'],
178179
'@typescript-eslint/explicit-member-accessibility': [
179180
'error',
180181
{

packages/vertexai/src/api.test.ts

Lines changed: 4 additions & 34 deletions
Original file line numberDiff line numberDiff line change
@@ -16,17 +16,11 @@
1616
*/
1717
import { ImagenModelParams, ModelParams, AIErrorCode } from './types';
1818
import { AIError } from './errors';
19-
import {
20-
ImagenModel,
21-
getGenerativeModel,
22-
getImagenModel,
23-
googleAIBackend,
24-
vertexAIBackend
25-
} from './api';
19+
import { ImagenModel, getGenerativeModel, getImagenModel } from './api';
2620
import { expect } from 'chai';
27-
import { BackendType, AI } from './public-types';
21+
import { AI } from './public-types';
2822
import { GenerativeModel } from './models/generative-model';
29-
import { DEFAULT_LOCATION } from './constants';
23+
import { VertexAIBackend } from './backend';
3024

3125
const fakeAI: AI = {
3226
app: {
@@ -38,7 +32,7 @@ const fakeAI: AI = {
3832
appId: 'my-appid'
3933
}
4034
},
41-
backend: vertexAIBackend('us-central1'),
35+
backend: new VertexAIBackend('us-central1'),
4236
location: 'us-central1'
4337
};
4438

@@ -171,28 +165,4 @@ describe('Top level API', () => {
171165
expect(genModel).to.be.an.instanceOf(ImagenModel);
172166
expect(genModel.model).to.equal('publishers/google/models/my-model');
173167
});
174-
it('googleAIBackend returns a backend with backendType GOOGLE_AI', () => {
175-
const backend = googleAIBackend();
176-
expect(backend.backendType).to.equal(BackendType.GOOGLE_AI);
177-
});
178-
it('vertexAIBackend returns a backend with backendType VERTEX_AI', () => {
179-
const backend = vertexAIBackend();
180-
expect(backend.backendType).to.equal(BackendType.VERTEX_AI);
181-
expect(backend.location).to.equal(DEFAULT_LOCATION);
182-
});
183-
it('vertexAIBackend sets custom location', () => {
184-
const backend = vertexAIBackend('test-location');
185-
expect(backend.backendType).to.equal(BackendType.VERTEX_AI);
186-
expect(backend.location).to.equal('test-location');
187-
});
188-
it('vertexAIBackend sets custom location even if empty string', () => {
189-
const backend = vertexAIBackend('');
190-
expect(backend.backendType).to.equal(BackendType.VERTEX_AI);
191-
expect(backend.location).to.equal('');
192-
});
193-
it('vertexAIBackend uses default location if location is null', () => {
194-
const backend = vertexAIBackend(null as any);
195-
expect(backend.backendType).to.equal(BackendType.VERTEX_AI);
196-
expect(backend.location).to.equal(DEFAULT_LOCATION);
197-
});
198168
});

packages/vertexai/src/api.ts

Lines changed: 21 additions & 41 deletions
Original file line numberDiff line numberDiff line change
@@ -24,9 +24,7 @@ import {
2424
BackendType,
2525
AI,
2626
AIOptions,
27-
GoogleAIBackend,
2827
VertexAI,
29-
VertexAIBackend,
3028
VertexAIOptions
3129
} from './public-types';
3230
import {
@@ -38,6 +36,7 @@ import {
3836
import { AIError } from './errors';
3937
import { AIModel, GenerativeModel, ImagenModel } from './models';
4038
import { encodeInstanceIdentifier } from './helpers';
39+
import { GoogleAIBackend, VertexAIBackend } from './backend';
4140

4241
export { ChatSession } from './methods/chat-session';
4342
export * from './requests/schema-builder';
@@ -72,7 +71,7 @@ declare module '@firebase/component' {
7271

7372
/**
7473
* It is recommended to use the new {@link getAI | getAI()}.
75-
*
74+
*
7675
* Returns a {@link VertexAI} instance for the given app.
7776
*
7877
* @public
@@ -109,13 +108,13 @@ export function getVertexAI(
109108
* @example
110109
* ```javascript
111110
* // Get an AI instance configured to use Google AI.
112-
* const ai = getAI(app, { backend: googleAIBackend() });
111+
* const ai = getAI(app, { backend: new GoogleAIBackend() });
113112
* ```
114113
*
115114
* @example
116115
* ```javascript
117116
* // Get an AI instance configured to use Vertex AI.
118-
* const ai = getAI(app, { backend: vertexAIBackend() });
117+
* const ai = getAI(app, { backend: new VertexAIBackend() });
119118
* ```
120119
*
121120
* @param app - The {@link @firebase/app#FirebaseApp} to use.
@@ -126,52 +125,33 @@ export function getVertexAI(
126125
*/
127126
export function getAI(
128127
app: FirebaseApp = getApp(),
129-
options: AIOptions = { backend: googleAIBackend() }
128+
options: AIOptions = { backend: new GoogleAIBackend() }
130129
): AI {
131130
app = getModularInstance(app);
132131
// Dependencies
133132
const AIProvider: Provider<'AI'> = _getProvider(app, AI_TYPE);
134133

135-
const identifier = encodeInstanceIdentifier(options.backend);
134+
let identifier: string;
135+
if (options.backend instanceof GoogleAIBackend) {
136+
identifier = encodeInstanceIdentifier({
137+
backendType: BackendType.GOOGLE_AI
138+
});
139+
} else if (options.backend instanceof VertexAIBackend) {
140+
identifier = encodeInstanceIdentifier({
141+
backendType: BackendType.VERTEX_AI,
142+
location: options.backend.location ?? DEFAULT_LOCATION
143+
});
144+
} else {
145+
throw new AIError(
146+
AIErrorCode.ERROR,
147+
`Invalid backend type: ${options.backend.backendType}`
148+
);
149+
}
136150
return AIProvider.getImmediate({
137151
identifier
138152
});
139153
}
140154

141-
/**
142-
* Creates a {@link Backend} instance configured to use Google AI.
143-
*
144-
* @returns A {@link GoogleAIBackend} object.
145-
*
146-
* @public
147-
*/
148-
export function googleAIBackend(): GoogleAIBackend {
149-
const backend: GoogleAIBackend = {
150-
backendType: BackendType.GOOGLE_AI
151-
};
152-
153-
return backend;
154-
}
155-
156-
/**
157-
* Creates a {@link Backend} instance configured to use Vertex AI.
158-
*
159-
* @param location - The region identifier, defaulting to `us-central1`;
160-
* see {@link https://firebase.google.com/docs/vertex-ai/locations?platform=ios#available-locations | Vertex AI locations}
161-
* for a list of supported locations.
162-
* @returns A {@link VertexAIBackend} object.
163-
*
164-
* @public
165-
*/
166-
export function vertexAIBackend(location?: string): VertexAIBackend {
167-
const backend: VertexAIBackend = {
168-
backendType: BackendType.VERTEX_AI,
169-
location: location ?? DEFAULT_LOCATION
170-
};
171-
172-
return backend;
173-
}
174-
175155
/**
176156
* Returns a {@link GenerativeModel} class with methods for inference
177157
* and other functionality.

packages/vertexai/src/backend.test.ts

Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,35 @@
1+
import { expect } from "chai";
2+
import { GoogleAIBackend, VertexAIBackend } from "./backend";
3+
import { BackendType } from "./public-types";
4+
import { DEFAULT_LOCATION } from "./constants";
5+
6+
describe('Backend', () => {
7+
describe('GoogleAIBackend', () => {
8+
it('sets backendType to GOOGLE_AI', () => {
9+
const backend = new GoogleAIBackend();
10+
expect(backend.backendType).to.equal(BackendType.GOOGLE_AI);
11+
});
12+
});
13+
describe('VertexAIBackend', () => {
14+
it('set backendType to VERTEX_AI', () => {
15+
const backend = new VertexAIBackend();
16+
expect(backend.backendType).to.equal(BackendType.VERTEX_AI);
17+
expect(backend.location).to.equal(DEFAULT_LOCATION);
18+
});
19+
it('sets custom location', () => {
20+
const backend = new VertexAIBackend('test-location');
21+
expect(backend.backendType).to.equal(BackendType.VERTEX_AI);
22+
expect(backend.location).to.equal('test-location');
23+
});
24+
it('sets custom location even if empty string', () => {
25+
const backend = new VertexAIBackend('');
26+
expect(backend.backendType).to.equal(BackendType.VERTEX_AI);
27+
expect(backend.location).to.equal('');
28+
});
29+
it('uses default location if location is null', () => {
30+
const backend = new VertexAIBackend(null as any);
31+
expect(backend.backendType).to.equal(BackendType.VERTEX_AI);
32+
expect(backend.location).to.equal(DEFAULT_LOCATION);
33+
});
34+
});
35+
});

packages/vertexai/src/backend.ts

Lines changed: 72 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,72 @@
1+
import { DEFAULT_LOCATION } from "./constants";
2+
import { BackendType } from "./public-types";
3+
4+
/**
5+
* Abstract base class representing the configuration for an AI service backend.
6+
* This class should not be instantiated directly. Use its subclasses
7+
* {@link GoogleAIBackend} or {@link VertexAIBackend}.
8+
*
9+
* @public
10+
*/
11+
export abstract class Backend {
12+
/**
13+
* Specifies the backend type (either 'GOOGLE_AI' or 'VERTEX_AI').
14+
*/
15+
readonly backendType: BackendType;
16+
17+
/**
18+
* Protected constructor for use by subclasses.
19+
* @param type - The specific backend type constant (e.g., BackendType.GOOGLE_AI).
20+
*/
21+
protected constructor(type: BackendType) {
22+
this.backendType = type;
23+
}
24+
}
25+
26+
/**
27+
* Represents the configuration class for the Google AI backend.
28+
* Use this with {@link AIOptions} when initializing the service with
29+
* {@link getAI | getAI()}.
30+
*
31+
* @public
32+
*/
33+
export class GoogleAIBackend extends Backend {
34+
/**
35+
* Creates a configuration object for the Google AI backend.
36+
*/
37+
constructor() {
38+
super(BackendType.GOOGLE_AI);
39+
}
40+
}
41+
42+
/**
43+
* Represents the configuration class for the Vertex AI backend.
44+
* Use this with {@link AIOptions} when initializing the server with
45+
* {@link getAI | getAI() }.
46+
*
47+
* @public
48+
*/
49+
export class VertexAIBackend extends Backend {
50+
/**
51+
* The region identifier.
52+
* See {@link https://firebase.google.com/docs/vertex-ai/locations?platform=ios#available-locations | Vertex AI locations}
53+
* for a list of supported locations.
54+
*/
55+
readonly location: string;
56+
57+
/**
58+
* Creates a configuration object for the Vertex AI backend.
59+
*
60+
* @param location - The region identifier, defaulting to `us-central1`;
61+
* see {@link https://firebase.google.com/docs/vertex-ai/locations?platform=ios#available-locations | Vertex AI locations}
62+
* for a list of supported locations.
63+
*/
64+
constructor(location: string = DEFAULT_LOCATION) {
65+
super(BackendType.VERTEX_AI);
66+
if (location === null) {
67+
this.location = DEFAULT_LOCATION;
68+
} else {
69+
this.location = location;
70+
}
71+
}
72+
}

packages/vertexai/src/backwards-compatbility.test.ts

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -24,10 +24,10 @@ import {
2424
VertexAIErrorCode,
2525
VertexAIModel,
2626
getGenerativeModel,
27-
getImagenModel,
28-
vertexAIBackend
27+
getImagenModel
2928
} from './api';
3029
import { AI, VertexAI, AIErrorCode } from './public-types';
30+
import { VertexAIBackend } from './backend';
3131

3232
function assertAssignable<T, _U extends T>(): void {}
3333

@@ -41,7 +41,7 @@ const fakeAI: AI = {
4141
appId: 'app-id'
4242
}
4343
},
44-
backend: vertexAIBackend('us-central1'),
44+
backend: new VertexAIBackend('us-central1'),
4545
location: 'us-central1'
4646
};
4747

packages/vertexai/src/errors.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,7 @@
1616
*/
1717

1818
import { FirebaseError } from '@firebase/util';
19-
import { AIErrorCode as AIErrorCode, CustomErrorData } from './types';
19+
import { AIErrorCode, CustomErrorData } from './types';
2020
import { VERTEX_TYPE } from './constants';
2121

2222
/**

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

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -23,7 +23,7 @@ import * as generateContentMethods from './generate-content';
2323
import { GenerateContentStreamResult } from '../types';
2424
import { ChatSession } from './chat-session';
2525
import { ApiSettings } from '../types/internal';
26-
import { vertexAIBackend } from '../api';
26+
import { VertexAIBackend } from '../backend';
2727

2828
use(sinonChai);
2929
use(chaiAsPromised);
@@ -33,7 +33,7 @@ const fakeApiSettings: ApiSettings = {
3333
project: 'my-project',
3434
appId: 'my-appid',
3535
location: 'us-central1',
36-
backend: vertexAIBackend()
36+
backend: new VertexAIBackend()
3737
};
3838

3939
describe('ChatSession', () => {

0 commit comments

Comments
 (0)