Hi everyone,
I’m currently developing an application using OpenAI’s API and I’ve run into an issue with function calls. I’ve defined three different functions that can be called based on user input. The functions are:
OracleInsight
: Provides a tarot reading based on a keyword.webPilot
: Performs an online search based on a user’s query.tool3
: Performs image recognition based on a vision keyword.
The parameters passed to each function are structured similarly. Here is the setup:
const tools = [
{
"type": "function",
"function": {
"name": "OracleInsight",
"description": "Provides a tarot reading and divination based on a keyword",
"parameters": {
"type": "object",
"properties": {
"keyword": { "type": "string" }
},
"required": ["keyword"]
}
}
},
{
"type": "function",
"function": {
"name": "webPilot",
"description": "Performs an online search based on a user's query",
"parameters": {
"type": "object",
"properties": {
"userQuery": { "type": "string" }
},
"required": ["userQuery"]
}
}
},
{
"type": "function",
"function": {
"name": "tool3",
"description": "Performs image recognition based on a vision keyword",
"parameters": {
"type": "object",
"properties": {
"visionKeyword": { "type": "string" }
},
"required": ["visionKeyword"]
}
}
}
];
When the user provides input, the appropriate function should be called. This logic is handled as follows:
const payload = {
"model": "gpt-4-turbo",
"messages": messages,
"tools": tools,
"tool_choice": "auto" // Let GPT automatically decide if it needs to call a tool
};
const options = {
"method": "post",
"headers": {
"Content-Type": "application/json",
'Authorization': 'Bearer ' + apiKey,
},
"payload": JSON.stringify(payload)
};
try {
var response = UrlFetchApp.fetch(ep, options);
var json = response.getContentText();
var data = JSON.parse(json);
var choice = data.choices[0];
if (choice.message.tool_calls && choice.message.tool_calls.length > 0) {
var toolCall = choice.message.tool_calls[0];
var functionCall = toolCall.function;
var functionArgs = JSON.parse(functionCall.arguments);
if (functionCall.name === "OracleInsight" && functionArgs.keyword) {
OracleInsight(functionArgs.keyword, replyToken);
} else if (functionCall.name === "webPilot" && functionArgs.userQuery) {
webPilot(functionArgs.userQuery, replyToken);
} else if (functionCall.name === "tool3" && functionArgs.visionKeyword) {
tool3(functionArgs.visionKeyword, replyToken);
} else {
Logger.log('Missing arguments for function call: ' + JSON.stringify(functionArgs));
}
} else {
gptreplyToLine(replyToken, [{ type: 'text', text: choice.message.content }]);
}
} catch(e) {
Logger.log('Error: ' + e.message);
if (e.response) {
Logger.log('Response Code: ' + e.response.getResponseCode());
Logger.log('Response Text: ' + e.response.getContentText());
}
}
While the OracleInsight and webPilot functions are called correctly, the tool3 function consistently fails to invoke, regardless of whether I use GPT-3.5-turbo, GPT-4-turbo, or GPT-4o models. The failure is indicated by missing arguments for the function call, as seen in the logs:
Missing arguments for function call: {"visionKeyword":"describe character features in the image"}
Here’s the definition and implementation of tool3 :
function tool3(visionKeyword, replyToken) {
var scriptProperties = PropertiesService.getScriptProperties();
var imageUrl = scriptProperties.getProperty('latestImageUrl'); // From PropertiesService
var requestContent = visionKeyword;
var chatHistory = GetAndUpdateChatHistory(visionKeyword, "");
var historyMessages = chatHistory.map(entry => ({
role: entry.role,
content: [{ type: "text", text: entry.content }]
}));
var gptRequest = {
model: "gpt-4o",
messages: [
{
role: "system",
content: [{ type: "text", text: "Your system prompt here." }],
},
...historyMessages,
{
role: "user",
content: [{
type: "text",
text: requestContent
}, {
type: "image_url",
image_url: {
url: imageUrl,
detail: "auto"
}
}]
}
],
max_tokens: 360
};
try {
var gptResponse = UrlFetchApp.fetch("https://api.openai.com/v1/chat/completions", {
method: "post",
contentType: "application/json",
payload: JSON.stringify(gptRequest),
headers: {
"Authorization": "Bearer " + apiKey
}
});
var gptResult = JSON.parse(gptResponse.getContentText());
var botResponse = gptResult.choices[0].message.content;
GetAndUpdateChatHistory(requestContent, botResponse);
replyVisionMessage(replyToken, gptResult.choices[0].message.content);
} catch (e) {
Logger.log('Error: ' + e.message);
if (e.response) {
Logger.log('Response Code: ' + e.response.getResponseCode());
Logger.log('Response Text: ' + e.response.getContentText());
}
}
}
I am unsure why fails while the other functions work perfectly with similar setups. Any insights or suggestions on resolving this issue would be greatly appreciated.tool3
Thank you!