Skip to content

Commit 681b4bd

Browse files
committed
Format and fix lint issues
1 parent 472c452 commit 681b4bd

File tree

4 files changed

+162
-67
lines changed

4 files changed

+162
-67
lines changed

packages/ai/integration/constants.ts

Lines changed: 17 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -16,13 +16,7 @@
1616
*/
1717

1818
import { initializeApp } from '@firebase/app';
19-
import {
20-
AI,
21-
Backend,
22-
BackendType,
23-
VertexAIBackend,
24-
getAI
25-
} from '../src';
19+
import { AI, Backend, BackendType, VertexAIBackend, getAI } from '../src';
2620
import { FIREBASE_CONFIG } from './firebase-config';
2721

2822
const app = initializeApp(FIREBASE_CONFIG);
@@ -41,7 +35,7 @@ function formatConfigAsString(config: { ai: AI; model: string }): string {
4135
return `${backendNames.get(config.ai.backend.backendType)} ${config.model}`;
4236
}
4337

44-
const backends: ReadonlyArray<Backend> = [
38+
const backends: readonly Backend[] = [
4539
// new GoogleAIBackend(), TODO: activate once live
4640
new VertexAIBackend()
4741
];
@@ -51,23 +45,29 @@ const backendNames: Map<BackendType, string> = new Map([
5145
[BackendType.VERTEX_AI, 'Vertex AI']
5246
]);
5347

54-
const modelNames: ReadonlyArray<string> = [
55-
'gemini-2.0-flash',
48+
const modelNames: readonly string[] = [
49+
'gemini-2.0-flash'
5650
// 'gemini-2.0-flash-exp'
5751
];
5852

59-
export const testConfigs: ReadonlyArray<TestConfig> = backends.flatMap(backend => {
53+
/**
54+
* Array of test configurations that is iterated over to get full coverage
55+
* of backends and models. Contains all combinations of backends and models.
56+
*/
57+
export const testConfigs: readonly TestConfig[] = backends.flatMap(backend => {
6058
return modelNames.map(modelName => {
6159
const ai = getAI(app, { backend });
6260
return {
6361
ai: getAI(app, { backend }),
6462
model: modelName,
6563
toString: () => formatConfigAsString({ ai, model: modelName })
66-
}
67-
})
68-
})
64+
};
65+
});
66+
});
6967

70-
export const TINY_IMG_BASE64 = 'iVBORw0KGgoAAAANSUhEUgAAAAEAAAABAQMAAAAl21bKAAAAA1BMVEUAAACnej3aAAAAAXRSTlMAQObYZgAAAApJREFUCNdjYAAAAAIAAeIhvDMAAAAASUVORK5CYII=';
68+
export const TINY_IMG_BASE64 =
69+
'iVBORw0KGgoAAAANSUhEUgAAAAEAAAABAQMAAAAl21bKAAAAA1BMVEUAAACnej3aAAAAAXRSTlMAQObYZgAAAApJREFUCNdjYAAAAAIAAeIhvDMAAAAASUVORK5CYII=';
7170
export const IMAGE_MIME_TYPE = 'image/png';
72-
export const TINY_MP3_BASE64 = 'SUQzBAAAAAAAIlRTU0UAAAAOAAADTGF2ZjYxLjcuMTAwAAAAAAAAAAAAAAD/+0DAAAAAAAAAAAAAAAAAAAAAAABJbmZvAAAADwAAAAUAAAK+AGhoaGhoaGhoaGhoaGhoaGhoaGiOjo6Ojo6Ojo6Ojo6Ojo6Ojo6OjrS0tLS0tLS0tLS0tLS0tLS0tLS02tra2tra2tra2tra2tra2tra2tr//////////////////////////wAAAABMYXZjNjEuMTkAAAAAAAAAAAAAAAAkAwYAAAAAAAACvhC6DYoAAAAAAP/7EMQAA8AAAaQAAAAgAAA0gAAABExBTUUzLjEwMFVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVV//sQxCmDwAABpAAAACAAADSAAAAEVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVX/+xDEUwPAAAGkAAAAIAAANIAAAARVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVf/7EMR8g8AAAaQAAAAgAAA0gAAABFVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVV//sQxKYDwAABpAAAACAAADSAAAAEVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVU=';
73-
export const AUDIO_MIME_TYPE = 'audio/mpeg';
71+
export const TINY_MP3_BASE64 =
72+
'SUQzBAAAAAAAIlRTU0UAAAAOAAADTGF2ZjYxLjcuMTAwAAAAAAAAAAAAAAD/+0DAAAAAAAAAAAAAAAAAAAAAAABJbmZvAAAADwAAAAUAAAK+AGhoaGhoaGhoaGhoaGhoaGhoaGiOjo6Ojo6Ojo6Ojo6Ojo6Ojo6OjrS0tLS0tLS0tLS0tLS0tLS0tLS02tra2tra2tra2tra2tra2tra2tr//////////////////////////wAAAABMYXZjNjEuMTkAAAAAAAAAAAAAAAAkAwYAAAAAAAACvhC6DYoAAAAAAP/7EMQAA8AAAaQAAAAgAAA0gAAABExBTUUzLjEwMFVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVV//sQxCmDwAABpAAAACAAADSAAAAEVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVX/+xDEUwPAAAGkAAAAIAAANIAAAARVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVf/7EMR8g8AAAaQAAAAgAAA0gAAABFVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVV//sQxKYDwAABpAAAACAAADSAAAAEVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVU=';
73+
export const AUDIO_MIME_TYPE = 'audio/mpeg';

packages/ai/integration/count-tokens.test.ts

Lines changed: 106 additions & 36 deletions
Original file line numberDiff line numberDiff line change
@@ -27,7 +27,6 @@ import {
2727
getGenerativeModel,
2828
Part,
2929
CountTokensRequest,
30-
Schema,
3130
InlineDataPart,
3231
FileDataPart
3332
} from '../src';
@@ -40,11 +39,9 @@ import {
4039
} from './constants';
4140
import { FIREBASE_CONFIG } from './firebase-config';
4241

43-
4442
describe('Count Tokens', () => {
4543
testConfigs.forEach(testConfig => {
4644
describe(`${testConfig.toString()}`, () => {
47-
4845
it('text input', async () => {
4946
const generationConfig: GenerationConfig = {
5047
temperature: 0,
@@ -94,12 +91,16 @@ describe('Count Tokens', () => {
9491
expect(response.totalBillableCharacters).to.equal(16);
9592
expect(response.promptTokensDetails).to.not.be.null;
9693
expect(response.promptTokensDetails!.length).to.equal(1);
97-
expect(response.promptTokensDetails![0].modality).to.equal(Modality.TEXT);
94+
expect(response.promptTokensDetails![0].modality).to.equal(
95+
Modality.TEXT
96+
);
9897
expect(response.promptTokensDetails![0].tokenCount).to.equal(6);
9998
});
10099

101100
it('image input', async () => {
102-
const model = getGenerativeModel(testConfig.ai, { model: testConfig.model });
101+
const model = getGenerativeModel(testConfig.ai, {
102+
model: testConfig.model
103+
});
103104
const imagePart: Part = {
104105
inlineData: {
105106
mimeType: IMAGE_MIME_TYPE,
@@ -109,15 +110,32 @@ describe('Count Tokens', () => {
109110
const response = await model.countTokens([imagePart]);
110111

111112
const expectedImageTokens = 258;
112-
expect(response.totalTokens, 'totalTokens should have correct token count').to.equal(expectedImageTokens);
113-
expect(response.totalBillableCharacters, 'totalBillableCharacters should be undefined').to.be.undefined; // Incorrect behavior
114-
expect(response.promptTokensDetails!.length, 'promptTokensDetails should have one entry').to.equal(1);
115-
expect(response.promptTokensDetails![0].modality, 'modality should be IMAGE').to.equal(Modality.IMAGE);
116-
expect(response.promptTokensDetails![0].tokenCount, 'promptTokenDetails tokenCount should be correct').to.equal(expectedImageTokens);
113+
expect(
114+
response.totalTokens,
115+
'totalTokens should have correct token count'
116+
).to.equal(expectedImageTokens);
117+
expect(
118+
response.totalBillableCharacters,
119+
'totalBillableCharacters should be undefined'
120+
).to.be.undefined; // Incorrect behavior
121+
expect(
122+
response.promptTokensDetails!.length,
123+
'promptTokensDetails should have one entry'
124+
).to.equal(1);
125+
expect(
126+
response.promptTokensDetails![0].modality,
127+
'modality should be IMAGE'
128+
).to.equal(Modality.IMAGE);
129+
expect(
130+
response.promptTokensDetails![0].tokenCount,
131+
'promptTokenDetails tokenCount should be correct'
132+
).to.equal(expectedImageTokens);
117133
});
118134

119135
it('audio input', async () => {
120-
const model = getGenerativeModel(testConfig.ai, { model: testConfig.model });
136+
const model = getGenerativeModel(testConfig.ai, {
137+
model: testConfig.model
138+
});
121139
const audioPart: InlineDataPart = {
122140
inlineData: {
123141
mimeType: AUDIO_MIME_TYPE,
@@ -127,40 +145,82 @@ describe('Count Tokens', () => {
127145

128146
const response = await model.countTokens([audioPart]);
129147
// This may be different on Google AI
130-
expect(response.totalTokens, 'totalTokens is expected to be undefined').to.be.undefined;
131-
expect(response.totalBillableCharacters, 'totalBillableCharacters should be undefined').to.be.undefined; // Incorrect behavior
132-
expect(response.promptTokensDetails!.length, 'promptTokensDetails should have one entry').to.equal(1);
133-
expect(response.promptTokensDetails![0].modality, 'modality should be AUDIO').to.equal(Modality.AUDIO);
134-
expect(response.promptTokensDetails![0].tokenCount, 'promptTokenDetails tokenCount is expected to be undefined').to.be.undefined;
148+
expect(response.totalTokens, 'totalTokens is expected to be undefined')
149+
.to.be.undefined;
150+
expect(
151+
response.totalBillableCharacters,
152+
'totalBillableCharacters should be undefined'
153+
).to.be.undefined; // Incorrect behavior
154+
expect(
155+
response.promptTokensDetails!.length,
156+
'promptTokensDetails should have one entry'
157+
).to.equal(1);
158+
expect(
159+
response.promptTokensDetails![0].modality,
160+
'modality should be AUDIO'
161+
).to.equal(Modality.AUDIO);
162+
expect(
163+
response.promptTokensDetails![0].tokenCount,
164+
'promptTokenDetails tokenCount is expected to be undefined'
165+
).to.be.undefined;
135166
});
136167

137168
it('text, image, and audio input', async () => {
138-
const model = getGenerativeModel(testConfig.ai, { model: testConfig.model });
169+
const model = getGenerativeModel(testConfig.ai, {
170+
model: testConfig.model
171+
});
139172
const textPart: Part = { text: 'Describe these:' };
140-
const imagePart: Part = { inlineData: { mimeType: IMAGE_MIME_TYPE, data: TINY_IMG_BASE64 } };
141-
const audioPart: Part = { inlineData: { mimeType: AUDIO_MIME_TYPE, data: TINY_MP3_BASE64 } };
173+
const imagePart: Part = {
174+
inlineData: { mimeType: IMAGE_MIME_TYPE, data: TINY_IMG_BASE64 }
175+
};
176+
const audioPart: Part = {
177+
inlineData: { mimeType: AUDIO_MIME_TYPE, data: TINY_MP3_BASE64 }
178+
};
142179

143180
const request: CountTokensRequest = {
144181
contents: [{ role: 'user', parts: [textPart, imagePart, audioPart] }]
145182
};
146183
const response = await model.countTokens(request);
147184

148-
expect(response.totalTokens, 'totalTokens should have correct token count').to.equal(261);
149-
expect(response.totalBillableCharacters, 'totalBillableCharacters should have correct count').to.equal('Describe these:'.length - 1); // For some reason it's the length-1
150-
151-
expect(response.promptTokensDetails!.length, 'promptTokensDetails should have three entries').to.equal(3);
152-
153-
const textDetails = response.promptTokensDetails!.find(d => d.modality === Modality.TEXT);
154-
const visionDetails = response.promptTokensDetails!.find(d => d.modality === Modality.IMAGE);
155-
const audioDetails = response.promptTokensDetails!.find(d => d.modality === Modality.AUDIO);
156-
157-
expect(textDetails).to.deep.equal({ modality: Modality.TEXT, tokenCount: 3 });
158-
expect(visionDetails).to.deep.equal({ modality: Modality.IMAGE, tokenCount: 258 });
185+
expect(
186+
response.totalTokens,
187+
'totalTokens should have correct token count'
188+
).to.equal(261);
189+
expect(
190+
response.totalBillableCharacters,
191+
'totalBillableCharacters should have correct count'
192+
).to.equal('Describe these:'.length - 1); // For some reason it's the length-1
193+
194+
expect(
195+
response.promptTokensDetails!.length,
196+
'promptTokensDetails should have three entries'
197+
).to.equal(3);
198+
199+
const textDetails = response.promptTokensDetails!.find(
200+
d => d.modality === Modality.TEXT
201+
);
202+
const visionDetails = response.promptTokensDetails!.find(
203+
d => d.modality === Modality.IMAGE
204+
);
205+
const audioDetails = response.promptTokensDetails!.find(
206+
d => d.modality === Modality.AUDIO
207+
);
208+
209+
expect(textDetails).to.deep.equal({
210+
modality: Modality.TEXT,
211+
tokenCount: 3
212+
});
213+
expect(visionDetails).to.deep.equal({
214+
modality: Modality.IMAGE,
215+
tokenCount: 258
216+
});
159217
expect(audioDetails).to.deep.equal({ modality: Modality.AUDIO }); // Incorrect behavior because there's no tokenCount
160218
});
161219

162220
it('public storage reference', async () => {
163-
const model = getGenerativeModel(testConfig.ai, { model: testConfig.model });
221+
const model = getGenerativeModel(testConfig.ai, {
222+
model: testConfig.model
223+
});
164224
const filePart: FileDataPart = {
165225
fileData: {
166226
mimeType: IMAGE_MIME_TYPE,
@@ -170,13 +230,23 @@ describe('Count Tokens', () => {
170230
const response = await model.countTokens([filePart]);
171231

172232
const expectedFileTokens = 258;
173-
expect(response.totalTokens, 'totalTokens should have correct token count').to.equal(expectedFileTokens);
174-
expect(response.totalBillableCharacters, 'totalBillableCharacters should be undefined').to.be.undefined;
233+
expect(
234+
response.totalTokens,
235+
'totalTokens should have correct token count'
236+
).to.equal(expectedFileTokens);
237+
expect(
238+
response.totalBillableCharacters,
239+
'totalBillableCharacters should be undefined'
240+
).to.be.undefined;
175241
expect(response.promptTokensDetails).to.not.be.null;
176242
expect(response.promptTokensDetails!.length).to.equal(1);
177-
expect(response.promptTokensDetails![0].modality).to.equal(Modality.IMAGE);
178-
expect(response.promptTokensDetails![0].tokenCount).to.equal(expectedFileTokens);
243+
expect(response.promptTokensDetails![0].modality).to.equal(
244+
Modality.IMAGE
245+
);
246+
expect(response.promptTokensDetails![0].tokenCount).to.equal(
247+
expectedFileTokens
248+
);
179249
});
180250
});
181-
})
251+
});
182252
});
Lines changed: 18 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,20 @@
1+
/**
2+
* @license
3+
* Copyright 2025 Google LLC
4+
*
5+
* Licensed under the Apache License, Version 2.0 (the "License");
6+
* you may not use this file except in compliance with the License.
7+
* You may obtain a copy of the License at
8+
*
9+
* http://www.apache.org/licenses/LICENSE-2.0
10+
*
11+
* Unless required by applicable law or agreed to in writing, software
12+
* distributed under the License is distributed on an "AS IS" BASIS,
13+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14+
* See the License for the specific language governing permissions and
15+
* limitations under the License.
16+
*/
17+
118
import * as config from '../../../config/project.json';
219

3-
export const FIREBASE_CONFIG = config;
20+
export const FIREBASE_CONFIG = config;

packages/ai/integration/generate-content.test.ts

Lines changed: 21 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -16,10 +16,17 @@
1616
*/
1717

1818
import { expect } from 'chai';
19-
import { Content, GenerationConfig, HarmBlockMethod, HarmBlockThreshold, HarmCategory, Modality, SafetySetting, getGenerativeModel } from '../src';
2019
import {
21-
testConfigs
22-
} from './constants';
20+
Content,
21+
GenerationConfig,
22+
HarmBlockMethod,
23+
HarmBlockThreshold,
24+
HarmCategory,
25+
Modality,
26+
SafetySetting,
27+
getGenerativeModel
28+
} from '../src';
29+
import { testConfigs } from './constants';
2330

2431
// Token counts are only expected to differ by at most this number of tokens.
2532
// Set to 1 for whitespace that is not always present.
@@ -28,7 +35,6 @@ const TOKEN_COUNT_DELTA = 1;
2835
describe('Generate Content', () => {
2936
testConfigs.forEach(testConfig => {
3037
describe(`${testConfig.toString()}`, () => {
31-
3238
it('text input, text output', async () => {
3339
const generationConfig: GenerationConfig = {
3440
temperature: 0,
@@ -96,14 +102,16 @@ describe('Generate Content', () => {
96102
);
97103
expect(response.usageMetadata!.promptTokensDetails).to.not.be.null;
98104
expect(response.usageMetadata!.promptTokensDetails!.length).to.equal(1);
99-
expect(response.usageMetadata!.promptTokensDetails![0].modality).to.equal(
100-
Modality.TEXT
101-
);
102-
expect(response.usageMetadata!.promptTokensDetails![0].tokenCount).to.equal(
103-
21
104-
);
105+
expect(
106+
response.usageMetadata!.promptTokensDetails![0].modality
107+
).to.equal(Modality.TEXT);
108+
expect(
109+
response.usageMetadata!.promptTokensDetails![0].tokenCount
110+
).to.equal(21);
105111
expect(response.usageMetadata!.candidatesTokensDetails).to.not.be.null;
106-
expect(response.usageMetadata!.candidatesTokensDetails!.length).to.equal(1);
112+
expect(
113+
response.usageMetadata!.candidatesTokensDetails!.length
114+
).to.equal(1);
107115
expect(
108116
response.usageMetadata!.candidatesTokensDetails![0].modality
109117
).to.equal(Modality.TEXT);
@@ -112,6 +120,6 @@ describe('Generate Content', () => {
112120
).to.be.closeTo(4, TOKEN_COUNT_DELTA);
113121
});
114122
// TODO (dlarocque): Test generateContentStream
115-
})
116-
})
123+
});
124+
});
117125
});

0 commit comments

Comments
 (0)