UNPKG

@just-every/ensemble

Version:

LLM provider abstraction layer with unified streaming interface

187 lines 7.41 kB
"use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.createToolFunction = createToolFunction; const validToolParameterTypes = ['string', 'number', 'boolean', 'array', 'object', 'null']; function createToolFunction(func, description, paramMap, returns, functionName) { const funcStr = func.toString(); const funcName = (functionName || '').replaceAll(' ', '_') || func.name; if (!funcName) { throw new Error('[createToolFunction] Function name is required'); } let toolDescription = description || `Tool for ${funcName}`; if (returns) { toolDescription += ` Returns: ${returns}`; } const cleanFuncStr = funcStr.replaceAll(/\n\s*/g, ' '); const paramMatch = cleanFuncStr.match(/\(([^)]*)\)/); const properties = {}; const required = []; let injectAgentId = false; let injectAbortSignal = false; const params = paramMap ? Object.keys(paramMap) : paramMatch && paramMatch[1] ? paramMatch[1] .split(',') .map(p => p.trim()) .filter(Boolean) : []; for (const paramUnknown of params) { if (typeof paramUnknown !== 'string') { console.warn(`Skipping non-string parameter in function signature analysis: ${paramUnknown}`); continue; } const param = paramUnknown; const paramParts = param.split('=').map(p => p.trim()); let paramName = paramParts[0].trim(); const defaultValue = paramParts.length > 1 ? paramParts[1].trim() : undefined; if (paramName.includes(':')) { paramName = paramName.split(':')[0].trim(); } const isRestParam = paramName.startsWith('...'); const cleanParamName = isRestParam ? paramName.substring(3) : paramName; if (cleanParamName === 'inject_agent_id') { injectAgentId = true; continue; } if (cleanParamName === 'abort_signal') { injectAbortSignal = true; continue; } const paramInfoRaw = paramMap?.[cleanParamName]; let paramInfoObj = undefined; let paramInfoDesc = undefined; if (typeof paramInfoRaw === 'string') { paramInfoDesc = paramInfoRaw; paramInfoObj = { type: 'string', description: paramInfoRaw }; } else if (typeof paramInfoRaw === 'object' && paramInfoRaw !== null) { paramInfoObj = paramInfoRaw; paramInfoDesc = typeof paramInfoRaw.description === 'function' ? paramInfoRaw.description() : paramInfoRaw.description; } const apiParamName = cleanParamName; let paramType = 'string'; if (paramInfoObj?.type && validToolParameterTypes.includes(paramInfoObj.type)) { paramType = paramInfoObj.type; } else if (isRestParam) { paramType = 'array'; } else if (defaultValue !== undefined) { if (defaultValue === 'false' || defaultValue === 'true') { paramType = 'boolean'; } else if (!isNaN(Number(defaultValue)) && !defaultValue.startsWith('"') && !defaultValue.startsWith("'")) { paramType = 'number'; } else if (defaultValue === '[]' || defaultValue.startsWith('[')) { paramType = 'array'; } else if (defaultValue === '{}' || defaultValue.startsWith('{')) { paramType = 'object'; } } const finalDescription = paramInfoDesc || `The ${cleanParamName} parameter`; const paramDef = { type: paramType, description: finalDescription, }; if (paramType === 'array') { if (paramInfoObj?.items) { paramDef.items = paramInfoObj.items; } else { paramDef.items = { type: 'string', }; } } if (paramType === 'object') { if (paramInfoObj?.properties) { paramDef.properties = paramInfoObj.properties; } else { throw new Error(`[createToolFunction] Parameter '${cleanParamName}' is of type 'object' but has no 'properties' defined. ` + `Object parameters must define their structure when used with strict mode. ` + `Either provide a 'properties' field or use a different type like 'string' for JSON data.`); } if (paramInfoObj?.required) { paramDef.required = paramInfoObj.required; } } if (paramInfoObj?.enum) { if (typeof paramInfoObj.enum === 'function') { const enumFn = paramInfoObj.enum; const fnStr = enumFn.toString(); const isAsync = fnStr.includes('__awaiter') || fnStr.startsWith('async ') || enumFn.constructor.name === 'AsyncFunction'; if (isAsync) { paramDef.enum = enumFn; } else { paramDef.enum = enumFn(); } } else { paramDef.enum = paramInfoObj.enum; } } if (paramInfoObj?.minimum !== undefined) { paramDef.minimum = paramInfoObj.minimum; } if (paramInfoObj?.maximum !== undefined) { paramDef.maximum = paramInfoObj.maximum; } if (paramInfoObj?.default !== undefined) { paramDef.default = paramInfoObj.default; } else if (defaultValue !== undefined) { paramDef.default = defaultValue; } if (paramInfoObj?.minLength !== undefined) { paramDef.minLength = paramInfoObj.minLength; } if (paramInfoObj?.maxLength !== undefined) { paramDef.maxLength = paramInfoObj.maxLength; } if (paramInfoObj?.pattern !== undefined) { paramDef.pattern = paramInfoObj.pattern; } if (paramInfoObj?.minItems !== undefined) { paramDef.minItems = paramInfoObj.minItems; } if (paramInfoObj?.additionalProperties !== undefined) { paramDef.additionalProperties = paramInfoObj.additionalProperties; } properties[apiParamName] = paramDef; if (paramDef.default === undefined && !paramInfoObj?.optional) { required.push(apiParamName); } } if (!injectAgentId && /\(\s*[^)]*\binject_agent_id\b/.test(funcStr)) { injectAgentId = true; } if (!injectAbortSignal && /\(\s*[^)]*\babort_signal\b/.test(funcStr)) { injectAbortSignal = true; } return { function: func, definition: { type: 'function', function: { name: funcName, description: toolDescription, parameters: { type: 'object', properties, required: required.length > 0 ? required : undefined, }, }, }, ...(injectAgentId && { injectAgentId }), ...(injectAbortSignal && { injectAbortSignal }), }; } //# sourceMappingURL=create_tool_function.js.map