Skip to content

Commit f39406f

Browse files
OrKoNDevtools-frontend LUCI CQ
authored andcommitted
[AI Assistance] Refactor function calling
Bug: 385082492 Change-Id: I8bb2b553b7825d2a2fa88071dcd7d77fde7ed71d Reviewed-on: https://chromium-review.googlesource.com/c/devtools/devtools-frontend/+/6110476 Commit-Queue: Alex Rudenko <[email protected]> Reviewed-by: Wolfgang Beyer <[email protected]> Auto-Submit: Alex Rudenko <[email protected]> Commit-Queue: Wolfgang Beyer <[email protected]>
1 parent 26aebbe commit f39406f

File tree

3 files changed

+24
-17
lines changed

3 files changed

+24
-17
lines changed

front_end/core/host/AidaClient.ts

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -68,7 +68,7 @@ export interface FunctionPrimitiveParams extends BaseFunctionParam {
6868

6969
interface FunctionArrayParam extends BaseFunctionParam {
7070
type: ParametersTypes.ARRAY;
71-
items: FunctionPrimitiveParams[];
71+
items: FunctionPrimitiveParams;
7272
}
7373

7474
export interface FunctionObjectParam extends BaseFunctionParam {
@@ -87,7 +87,7 @@ export interface FunctionDeclaration {
8787
* A description for the LLM to understand what the specific function will do once called.
8888
*/
8989
description: string;
90-
parameters: FunctionObjectParam|FunctionPrimitiveParams;
90+
parameters: FunctionObjectParam|FunctionPrimitiveParams|FunctionArrayParam;
9191
}
9292

9393
// Raw media bytes.
@@ -141,7 +141,7 @@ export type RpcGlobalId = string|number;
141141
export interface AidaRequest {
142142
client: string;
143143
// eslint-disable-next-line @typescript-eslint/naming-convention
144-
current_message?: Content;
144+
current_message: Content;
145145
preamble?: string;
146146
// eslint-disable-next-line @typescript-eslint/naming-convention
147147
historical_contexts?: Content[];

front_end/panels/ai_assistance/agents/AiAgent.test.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -551,7 +551,7 @@ describeWithEnvironment('AiAgent', () => {
551551

552552
constructor(opts: AiAssistance.AgentOptions) {
553553
super(opts);
554-
this.functionDeclarations.set('testFn', {
554+
this.declareFunction('testFn', {
555555
description: 'test fn description',
556556
parameters: {type: Host.AidaClient.ParametersTypes.OBJECT, properties: {}, description: 'arg description'},
557557
handler: this.#test.bind(this),

front_end/panels/ai_assistance/agents/AiAgent.ts

Lines changed: 20 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -155,14 +155,12 @@ export abstract class ConversationContext<T> {
155155
}
156156
}
157157

158-
export type FunctionDeclaration<Args extends Record<string, unknown>, ReturnType = Record<string, unknown>> = {
158+
export type FunctionDeclaration<Args, ReturnType> = {
159159
description: string,
160160
parameters: Host.AidaClient.FunctionObjectParam,
161161
handler: (args: Args) => Promise<ReturnType>,
162162
};
163163

164-
export type FunctionDeclarations = Map<string, FunctionDeclaration<Record<string, unknown>, Record<string, unknown>>>;
165-
166164
export abstract class AiAgent<T> {
167165
static validTemperature(temperature: number|undefined): number|undefined {
168166
return typeof temperature === 'number' && temperature >= 0 ? temperature : undefined;
@@ -178,7 +176,7 @@ export abstract class AiAgent<T> {
178176
abstract readonly clientFeature: Host.AidaClient.ClientFeature;
179177
abstract readonly userTier: string|undefined;
180178
abstract handleContextDetails(select: ConversationContext<T>|null): AsyncGenerator<ContextResponse, void, void>;
181-
protected functionDeclarations: FunctionDeclarations = new Map();
179+
#functionDeclarations = new Map<string, FunctionDeclaration<unknown, unknown>>();
182180
#generatedFromHistory = false;
183181

184182
/**
@@ -203,7 +201,21 @@ export abstract class AiAgent<T> {
203201
}
204202

205203
get chatHistoryForTesting(): Array<Host.AidaClient.Content> {
206-
return this.#buildChatHistoryForAida();
204+
return this.buildChatHistoryForAida();
205+
}
206+
207+
declareFunction<Args, ReturnType>(name: string, declaration: FunctionDeclaration<Args, ReturnType>): void {
208+
if (this.#functionDeclarations.has(name)) {
209+
throw new Error(`Duplicate function declaration ${name}`);
210+
}
211+
this.#functionDeclarations.set(name, declaration as FunctionDeclaration<unknown, unknown>);
212+
}
213+
214+
async callFunction(name: string, args: unknown): Promise<Record<string, unknown>> {
215+
const call = this.#functionDeclarations.get(name);
216+
return (call ? await call.handler(args) : {
217+
error: `Function ${name} is not found.`,
218+
}) as Record<string, unknown>;
207219
}
208220

209221
set chatNewHistoryForTesting(history: HistoryEntryStorage) {
@@ -241,7 +253,7 @@ export abstract class AiAgent<T> {
241253

242254
#buildFunctionDeclarationsForAida(): Host.AidaClient.FunctionDeclaration[] {
243255
const result: Host.AidaClient.FunctionDeclaration[] = [];
244-
for (const [name, definition] of this.functionDeclarations.entries()) {
256+
for (const [name, definition] of this.#functionDeclarations.entries()) {
245257
result.push({
246258
name,
247259
description: definition.description,
@@ -278,11 +290,6 @@ export abstract class AiAgent<T> {
278290
for await (aidaResponse of this.#aidaClient.fetch(request, options)) {
279291
response = aidaResponse.explanation;
280292
rpcId = aidaResponse.metadata.rpcGlobalId ?? rpcId;
281-
282-
if (aidaResponse.functionCalls) {
283-
throw new Error('Function calling not supported yet');
284-
}
285-
286293
const parsedResponse = this.parseResponse(aidaResponse);
287294
yield {
288295
rpcId,
@@ -309,7 +316,7 @@ export abstract class AiAgent<T> {
309316
parts: [part],
310317
role: Host.AidaClient.Role.USER,
311318
};
312-
const history = this.#buildChatHistoryForAida();
319+
const history = this.buildChatHistoryForAida();
313320
const declarations = this.#buildFunctionDeclarationsForAida();
314321
const request: Host.AidaClient.AidaRequest = {
315322
client: Host.AidaClient.CLIENT_NAME,
@@ -380,7 +387,7 @@ STOP`;
380387
return text;
381388
}
382389

383-
#buildChatHistoryForAida(): Host.AidaClient.Content[] {
390+
buildChatHistoryForAida(): Host.AidaClient.Content[] {
384391
const history: Array<Host.AidaClient.Content> = [];
385392
let currentParsedStep: ParsedStep = {};
386393
let lastRunStartIdx = 0;

0 commit comments

Comments
 (0)