Skip to content

Commit a60f3d0

Browse files
authored
fix(ai): Add a warning when setting top-level params in hybrid mode (#9577)
1 parent 22476e1 commit a60f3d0

2 files changed

Lines changed: 42 additions & 2 deletions

File tree

‎packages/ai/src/api.test.ts‎

Lines changed: 23 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,12 @@
1414
* See the License for the specific language governing permissions and
1515
* limitations under the License.
1616
*/
17-
import { ImagenModelParams, ModelParams, AIErrorCode } from './types';
17+
import {
18+
ImagenModelParams,
19+
ModelParams,
20+
AIErrorCode,
21+
InferenceMode
22+
} from './types';
1823
import { AIError } from './errors';
1924
import {
2025
getAI,
@@ -28,12 +33,17 @@ import {
2833
getTemplateImagenModel,
2934
TemplateImagenModel
3035
} from './api';
31-
import { expect } from 'chai';
36+
import { expect, use } from 'chai';
37+
import { stub } from 'sinon';
3238
import { AI } from './public-types';
3339
import { GenerativeModel } from './models/generative-model';
3440
import { GoogleAIBackend, VertexAIBackend } from './backend';
3541
import { getFullApp } from '../test-utils/get-fake-firebase-services';
3642
import { AI_TYPE } from './constants';
43+
import { logger } from './logger';
44+
import sinonChai from 'sinon-chai';
45+
46+
use(sinonChai);
3747

3848
const fakeAI: AI = {
3949
app: {
@@ -148,6 +158,17 @@ describe('Top level API', () => {
148158
expect(genModel).to.be.an.instanceOf(GenerativeModel);
149159
expect(genModel.model).to.equal('publishers/google/models/my-model');
150160
});
161+
it('getGenerativeModel warns in hybrid mode if top-level params are set', () => {
162+
const warnStub = stub(logger, 'warn');
163+
const genModel = getGenerativeModel(fakeAI, {
164+
mode: InferenceMode.PREFER_ON_DEVICE,
165+
generationConfig: {}
166+
});
167+
expect(genModel).to.be.an.instanceOf(GenerativeModel);
168+
expect(warnStub).to.be.calledWithMatch(InferenceMode.PREFER_ON_DEVICE);
169+
expect(warnStub).to.be.calledWithMatch('generationConfig');
170+
warnStub.restore();
171+
});
151172
it('getImagenModel throws if no model is provided', () => {
152173
try {
153174
getImagenModel(fakeAI, {} as ImagenModelParams);

‎packages/ai/src/api.ts‎

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -41,6 +41,7 @@ import { GoogleAIBackend } from './backend';
4141
import { WebSocketHandlerImpl } from './websocket';
4242
import { TemplateGenerativeModel } from './models/template-generative-model';
4343
import { TemplateImagenModel } from './models/template-imagen-model';
44+
import { logger } from './logger';
4445

4546
export { ChatSession } from './methods/chat-session';
4647
export { LiveSession } from './methods/live-session';
@@ -117,6 +118,12 @@ export function getAI(app: FirebaseApp = getApp(), options?: AIOptions): AI {
117118
return aiInstance;
118119
}
119120

121+
const hybridParamKeys: Array<keyof HybridParams> = [
122+
'mode',
123+
'onDeviceParams',
124+
'inCloudParams'
125+
];
126+
120127
/**
121128
* Returns a {@link GenerativeModel} class with methods for inference
122129
* and other functionality.
@@ -132,6 +139,18 @@ export function getGenerativeModel(
132139
const hybridParams = modelParams as HybridParams;
133140
let inCloudParams: ModelParams;
134141
if (hybridParams.mode) {
142+
for (const param of Object.keys(modelParams)) {
143+
if (!hybridParamKeys.includes(param as keyof HybridParams)) {
144+
logger.warn(
145+
`When a hybrid inference mode is specified (mode is currently set` +
146+
` to ${hybridParams.mode}), "${param}" cannot be ` +
147+
`configured at the top level. Configuration for in-cloud and ` +
148+
`on-device must be done separately in inCloudParams and onDeviceParams. ` +
149+
`Configuration values set outside of inCloudParams and onDeviceParams will` +
150+
` be ignored.`
151+
);
152+
}
153+
}
135154
inCloudParams = hybridParams.inCloudParams || {
136155
model: DEFAULT_HYBRID_IN_CLOUD_MODEL
137156
};

0 commit comments

Comments
 (0)