Skip to content

Commit f02446f

Browse files
committed
VertexAI: add test cases for countTokens()
1 parent a90255a commit f02446f

File tree

5 files changed

+133
-0
lines changed

5 files changed

+133
-0
lines changed
Lines changed: 93 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,93 @@
1+
import { expect, use } from 'chai';
2+
import { match, restore, stub } from 'sinon';
3+
import sinonChai from 'sinon-chai';
4+
import chaiAsPromised from 'chai-as-promised';
5+
import { getMockResponse } from '../../test-utils/mock-response';
6+
import * as request from '../requests/request';
7+
import { countTokens } from './count-tokens';
8+
import { CountTokensRequest } from '../types';
9+
import { ApiSettings } from '../types/internal';
10+
import { Task } from '../requests/request';
11+
12+
use(sinonChai);
13+
use(chaiAsPromised);
14+
15+
const fakeApiSettings: ApiSettings = {
16+
apiKey: 'key',
17+
project: 'my-project',
18+
location: 'us-central1'
19+
};
20+
21+
const fakeRequestParams: CountTokensRequest = {
22+
contents: [{ parts: [{ text: 'hello' }], role: 'user' }]
23+
};
24+
25+
describe('countTokens()', () => {
26+
afterEach(() => {
27+
restore();
28+
});
29+
it('total tokens', async () => {
30+
const mockResponse = getMockResponse(
31+
'count-tokens-success-total-tokens.json'
32+
);
33+
const makeRequestStub = stub(request, 'makeRequest').resolves(
34+
mockResponse as Response
35+
);
36+
const result = await countTokens(
37+
fakeApiSettings,
38+
'model',
39+
fakeRequestParams
40+
);
41+
expect(result.totalTokens).to.equal(6);
42+
expect(result.totalBillableCharacters).to.equal(16);
43+
expect(makeRequestStub).to.be.calledWith(
44+
'model',
45+
Task.COUNT_TOKENS,
46+
fakeApiSettings,
47+
false,
48+
match((value: string) => {
49+
return value.includes('contents');
50+
}),
51+
undefined
52+
);
53+
});
54+
it('total tokens no billable characters', async () => {
55+
const mockResponse = getMockResponse(
56+
'count-tokens-success-no-billable-characters.json'
57+
);
58+
const makeRequestStub = stub(request, 'makeRequest').resolves(
59+
mockResponse as Response
60+
);
61+
const result = await countTokens(
62+
fakeApiSettings,
63+
'model',
64+
fakeRequestParams
65+
);
66+
expect(result.totalTokens).to.equal(258);
67+
expect(result).to.not.have.property('totalBillableCharacters');
68+
expect(makeRequestStub).to.be.calledWith(
69+
'model',
70+
Task.COUNT_TOKENS,
71+
fakeApiSettings,
72+
false,
73+
match((value: string) => {
74+
return value.includes('contents');
75+
}),
76+
undefined
77+
);
78+
});
79+
it('model not found', async () => {
80+
const mockResponse = getMockResponse(
81+
'count-tokens-failure-model-not-found.json'
82+
);
83+
const mockFetch = stub(globalThis, 'fetch').resolves({
84+
ok: false,
85+
status: 404,
86+
json: mockResponse.json
87+
} as Response);
88+
await expect(
89+
countTokens(fakeApiSettings, 'model', fakeRequestParams)
90+
).to.be.rejectedWith(/404.*not found/);
91+
expect(mockFetch).to.be.called;
92+
});
93+
});

packages/vertexai/src/models/generative-model.test.ts

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -262,4 +262,24 @@ describe('GenerativeModel', () => {
262262
);
263263
restore();
264264
});
265+
it('calls countTokens', async () => {
266+
const genModel = new GenerativeModel(fakeVertexAI, { model: 'my-model' });
267+
const mockResponse = getMockResponse(
268+
'count-tokens-success-total-tokens.json'
269+
);
270+
const makeRequestStub = stub(request, 'makeRequest').resolves(
271+
mockResponse as Response
272+
);
273+
await genModel.countTokens('hello');
274+
expect(makeRequestStub).to.be.calledWith(
275+
'publishers/google/models/my-model',
276+
request.Task.COUNT_TOKENS,
277+
match.any,
278+
false,
279+
match((value: string) => {
280+
return value.includes('hello');
281+
})
282+
);
283+
restore();
284+
});
265285
});
Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
{
2+
"error": {
3+
"code": 404,
4+
"message": "models/test-model-name is not found for API version v1beta, or is not supported for countTokens. Call ListModels to see the list of available models and their supported methods.",
5+
"status": "NOT_FOUND",
6+
"details": [
7+
{
8+
"@type": "type.googleapis.com/google.rpc.DebugInfo",
9+
"detail": "[ORIGINAL ERROR] generic::not_found: models/test-model-name is not found for API version v1beta, or is not supported for countTokens. Call ListModels to see the list of available models and their supported methods. [google.rpc.error_details_ext] { message: \"models/test-model-name is not found for API version v1beta, or is not supported for countTokens. Call ListModels to see the list of available models and their supported methods.\" }"
10+
}
11+
]
12+
}
13+
}
Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
{
2+
"totalTokens": 258
3+
}
Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
{
2+
"totalTokens": 6,
3+
"totalBillableCharacters": 16
4+
}

0 commit comments

Comments
 (0)