Add function calling

This commit is contained in:
Aslan 2025-12-29 12:49:52 +01:00
parent f3a74bc46c
commit a5d6163ef9
13 changed files with 272 additions and 32 deletions

View file

@ -1,28 +1,123 @@
import { GoogleGenAI } from "@google/genai";
import { config } from "../../config.js";
import type { AIResponseImage, AIResponseText } from "./types.js";
import type {
AIResponseImage,
AIResponseText,
AIToolMatrixData,
} from "./types.js";
import type { IAIInstructions } from "../../modules/ai/types.js";
import { FunctionCallingConfigMode } from "@google/genai";
import { toolFunctions, tools } from "./tools.js";
import type { FunctionResponse } from "@google/genai";
import type { Content } from "@google/genai";
const googleAI = new GoogleGenAI({
apiKey: config.app.ai.api.key,
});
const getTextGemini = async (
matrixData: AIToolMatrixData,
instructions: IAIInstructions,
input: string,
oldInput?: string,
): Promise<AIResponseText> => {
const inputContent: Content = {
role: "user",
parts: [
{
text: input,
},
],
};
const oldInputContent: Content = {
role: "user",
parts: [
{
text: oldInput ?? "",
},
],
};
const contents: Content[] = oldInput
? [oldInputContent, inputContent]
: [inputContent];
const response = await googleAI.models.generateContent({
model: "gemini-3-flash-preview",
contents: oldInput ? [oldInput, input] : input,
contents: contents,
config: {
systemInstruction: JSON.stringify(instructions),
toolConfig: {
functionCallingConfig: {
mode: FunctionCallingConfigMode.AUTO,
},
},
tools: [{ functionDeclarations: tools }],
},
});
let text = response.text ?? "AI Error";
let token = response.usageMetadata?.totalTokenCount ?? 0;
const content = response.candidates?.at(0)?.content;
const functionCall = content?.parts?.at(0)?.functionCall;
if (response.text || !content || !functionCall) {
return {
text: text,
tokens: token,
};
}
text = `Calling function ${functionCall.name}`;
const func = toolFunctions.find(
(func) => func.name === functionCall.name,
)?.function;
if (!func) {
return {
text: text,
tokens: token,
};
}
const output = func(matrixData, functionCall.args);
const functionResponse: FunctionResponse = {
id: functionCall.id ?? "",
name: functionCall.name ?? "",
response: {
output: JSON.stringify(output),
},
};
const responseTool = await googleAI.models.generateContent({
model: "gemini-3-flash-preview",
contents: [
...contents,
content,
{
role: "tool",
parts: [
{
functionResponse: functionResponse,
},
],
},
],
config: {
systemInstruction: JSON.stringify(instructions),
toolConfig: {
functionCallingConfig: {
mode: FunctionCallingConfigMode.AUTO,
},
},
tools: [{ functionDeclarations: tools }],
},
});
return {
text: response.text ?? "AI Error",
tokens: response.usageMetadata?.totalTokenCount ?? 0,
text: responseTool.text ?? "AI Error",
tokens: token + (responseTool.usageMetadata?.totalTokenCount ?? 0),
};
};