Skip to content

Commit 8e0fef7

Browse files
committed
make test() accessor handle mixed-parts responses
1 parent 4c83b34 commit 8e0fef7

File tree

2 files changed

+99
-38
lines changed

2 files changed

+99
-38
lines changed

packages/vertexai/src/requests/response-helpers.test.ts

Lines changed: 88 additions & 33 deletions
Original file line numberDiff line numberDiff line change
@@ -40,54 +40,85 @@ const fakeResponseText: GenerateContentResponse = {
4040
]
4141
};
4242

43+
const functionCallPart1 = {
44+
functionCall: {
45+
name: 'find_theaters',
46+
args: {
47+
location: 'Mountain View, CA',
48+
movie: 'Barbie'
49+
}
50+
}
51+
};
52+
53+
const functionCallPart2 = {
54+
functionCall: {
55+
name: 'find_times',
56+
args: {
57+
location: 'Mountain View, CA',
58+
movie: 'Barbie',
59+
time: '20:00'
60+
}
61+
}
62+
};
63+
4364
const fakeResponseFunctionCall: GenerateContentResponse = {
4465
candidates: [
4566
{
4667
index: 0,
4768
content: {
4869
role: 'model',
49-
parts: [
50-
{
51-
functionCall: {
52-
name: 'find_theaters',
53-
args: {
54-
location: 'Mountain View, CA',
55-
movie: 'Barbie'
56-
}
57-
}
58-
}
59-
]
70+
parts: [functionCallPart1]
6071
}
6172
}
6273
]
6374
};
6475

6576
const fakeResponseFunctionCalls: GenerateContentResponse = {
77+
candidates: [
78+
{
79+
index: 0,
80+
content: {
81+
role: 'model',
82+
parts: [functionCallPart1, functionCallPart2]
83+
}
84+
}
85+
]
86+
};
87+
88+
const fakeResponseMixed1: GenerateContentResponse = {
89+
candidates: [
90+
{
91+
index: 0,
92+
content: {
93+
role: 'model',
94+
parts: [{ text: 'some text' }, functionCallPart2]
95+
}
96+
}
97+
]
98+
};
99+
100+
const fakeResponseMixed2: GenerateContentResponse = {
101+
candidates: [
102+
{
103+
index: 0,
104+
content: {
105+
role: 'model',
106+
parts: [functionCallPart1, { text: 'some text' }]
107+
}
108+
}
109+
]
110+
};
111+
112+
const fakeResponseMixed3: GenerateContentResponse = {
66113
candidates: [
67114
{
68115
index: 0,
69116
content: {
70117
role: 'model',
71118
parts: [
72-
{
73-
functionCall: {
74-
name: 'find_theaters',
75-
args: {
76-
location: 'Mountain View, CA',
77-
movie: 'Barbie'
78-
}
79-
}
80-
},
81-
{
82-
functionCall: {
83-
name: 'find_times',
84-
args: {
85-
location: 'Mountain View, CA',
86-
movie: 'Barbie',
87-
time: '20:00'
88-
}
89-
}
90-
}
119+
{ text: 'some text' },
120+
functionCallPart1,
121+
{ text: ' and more text' }
91122
]
92123
}
93124
}
@@ -109,19 +140,43 @@ describe('response-helpers methods', () => {
109140
it('good response text', async () => {
110141
const enhancedResponse = addHelpers(fakeResponseText);
111142
expect(enhancedResponse.text()).to.equal('Some text and some more text');
143+
expect(enhancedResponse.functionCalls()).to.be.undefined;
112144
});
113145
it('good response functionCall', async () => {
114146
const enhancedResponse = addHelpers(fakeResponseFunctionCall);
147+
expect(enhancedResponse.text()).to.equal('');
115148
expect(enhancedResponse.functionCalls()).to.deep.equal([
116-
fakeResponseFunctionCall.candidates?.[0].content.parts[0].functionCall
149+
functionCallPart1.functionCall
117150
]);
118151
});
119152
it('good response functionCalls', async () => {
120153
const enhancedResponse = addHelpers(fakeResponseFunctionCalls);
154+
expect(enhancedResponse.text()).to.equal('');
155+
expect(enhancedResponse.functionCalls()).to.deep.equal([
156+
functionCallPart1.functionCall,
157+
functionCallPart2.functionCall
158+
]);
159+
});
160+
it('good response text/functionCall', async () => {
161+
const enhancedResponse = addHelpers(fakeResponseMixed1);
162+
expect(enhancedResponse.functionCalls()).to.deep.equal([
163+
functionCallPart2.functionCall
164+
]);
165+
expect(enhancedResponse.text()).to.equal('some text');
166+
});
167+
it('good response functionCall/text', async () => {
168+
const enhancedResponse = addHelpers(fakeResponseMixed2);
169+
expect(enhancedResponse.functionCalls()).to.deep.equal([
170+
functionCallPart1.functionCall
171+
]);
172+
expect(enhancedResponse.text()).to.equal('some text');
173+
});
174+
it('good response text/functionCall/text', async () => {
175+
const enhancedResponse = addHelpers(fakeResponseMixed3);
121176
expect(enhancedResponse.functionCalls()).to.deep.equal([
122-
fakeResponseFunctionCalls.candidates?.[0].content.parts[0].functionCall,
123-
fakeResponseFunctionCalls.candidates?.[0].content.parts[1].functionCall
177+
functionCallPart1.functionCall
124178
]);
179+
expect(enhancedResponse.text()).to.equal('some text and more text');
125180
});
126181
it('bad response safety', async () => {
127182
const enhancedResponse = addHelpers(badFakeResponse);

packages/vertexai/src/requests/response-helpers.ts

Lines changed: 11 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -85,13 +85,19 @@ export function addHelpers(
8585
}
8686

8787
/**
88-
* Returns text of first candidate.
88+
* Returns all text found in all parts of first candidate.
8989
*/
9090
export function getText(response: GenerateContentResponse): string {
91-
if (response.candidates?.[0].content?.parts?.[0]?.text) {
92-
return response.candidates[0].content.parts
93-
.map(({ text }) => text)
94-
.join('');
91+
const textStrings = [];
92+
if (response.candidates?.[0].content?.parts) {
93+
for (const part of response.candidates?.[0].content?.parts) {
94+
if (part.text) {
95+
textStrings.push(part.text);
96+
}
97+
}
98+
}
99+
if (textStrings.length > 0) {
100+
return textStrings.join('');
95101
} else {
96102
return '';
97103
}

0 commit comments

Comments
 (0)