dev: add tools normalization/converting

This commit is contained in:
KernelDeimos 2025-01-23 16:15:32 -05:00
parent bcdec32ba2
commit 54a104276b
2 changed files with 98 additions and 0 deletions

View File

@ -26,6 +26,7 @@ const { TypeSpec } = require("../../services/drivers/meta/Construct");
const { TypedValue } = require("../../services/drivers/meta/Runtime");
const { Context } = require("../../util/context");
const { AsModeration } = require("./lib/AsModeration");
const FunctionCalling = require("./lib/FunctionCalling");
// Maximum number of fallback attempts when a model fails, including the first attempt
const MAX_FALLBACKS = 3 + 1; // includes first attempt
@ -354,6 +355,10 @@ class AIChatService extends BaseService {
}
}
if ( parameters.tools ) {
FunctionCalling.normalize_tools_object(parameters.tools);
}
if ( intended_service === this.service_name ) {
throw new Error('Calling ai-chat directly is not yet supported');
}

View File

@ -0,0 +1,93 @@
module.exports = class FunctionCalling {
/**
* Normalizes the 'tools' object in-place.
*
* This function will accept an array of tools provided by the
* user, and produce a normalized object that can then be
* converted to the apprpriate representation for another
* service.
*
* We will accept conventions from either service that a user
* might expect to work, prioritizing the OpenAI convention
* when conflicting conventions are present.
*
* @param {*} tools
*/
static normalize_tools_object (tools) {
for ( let i=0 ; i < tools.length ; i++ ) {
const tool = tools[i];
let normalized_tool = {};
const normalize_function = fn => {
const normal_fn = {};
const parameters =
fn.parameters ||
fn.input_schema;
normal_fn.parameters = parameters ?? {
type: 'object',
};
if ( fn.name ) {
normal_fn.name = fn.name;
}
if ( fn.description ) {
normal_fn.description = fn.description;
}
return normal_fn;
}
if ( tool.input_schema ) {
normalized_tool = {
type: 'function',
function: normalize_function(tool),
};
} else if ( tool.type === 'function' ) {
normalized_tool = {
type: 'function',
function: normalize_function(tool.function),
}
} else {
normalized_tool = {
type: 'function',
function: normalize_function(tool),
};
}
tools[i] = normalized_tool;
}
return tools;
}
/**
* This function will convert a normalized tools object to the
* format expected by OpenAI.
*
* @param {*} tools
* @returns
*/
static make_openai_tools (tools) {
return tools;
}
/**
* This function will convert a normalized tools object to the
* format expected by Claude.
*
* @param {*} tools
* @returns
*/
static make_claude_tools (tools) {
if ( ! tools ) return undefined;
return tools.map(tool => {
const { name, description, parameters } = tool.function;
return {
name,
description,
input_schema: parameters,
};
});
}
}