@ai2070/l0
Version:
L0: The Missing Reliability Substrate for AI
241 lines • 7.73 kB
JavaScript
export function formatTool(tool, options = {}) {
const { style = "json-schema", includeExamples = false, includeTypes = true, } = options;
switch (style) {
case "json-schema":
return formatToolJsonSchema(tool, includeTypes);
case "typescript":
return formatToolTypeScript(tool);
case "natural":
return formatToolNatural(tool, includeExamples);
case "xml":
return formatToolXml(tool);
default:
return formatToolJsonSchema(tool, includeTypes);
}
}
function formatToolJsonSchema(tool, includeTypes = true) {
const properties = {};
const required = [];
for (const param of tool.parameters) {
const propDef = {
description: param.description || "",
};
if (includeTypes) {
propDef.type = param.type;
}
if (param.enum) {
propDef.enum = param.enum;
}
if (param.default !== undefined) {
propDef.default = param.default;
}
properties[param.name] = propDef;
if (param.required) {
required.push(param.name);
}
}
const schema = {
name: tool.name,
description: tool.description,
parameters: {
type: "object",
properties,
required: required.length > 0 ? required : undefined,
},
};
return JSON.stringify(schema, null, 2);
}
function formatToolTypeScript(tool) {
const params = tool.parameters
.map((p) => {
const optional = p.required ? "" : "?";
const type = p.type === "integer" ? "number" : p.type;
return `${p.name}${optional}: ${type}`;
})
.join(", ");
let result = `/**\n * ${tool.description}\n`;
for (const param of tool.parameters) {
result += ` * @param ${param.name}`;
if (param.description) {
result += ` - ${param.description}`;
}
result += "\n";
}
result += ` */\nfunction ${tool.name}(${params}): void;`;
return result;
}
function formatToolNatural(tool, includeExamples) {
const lines = [];
lines.push(`Tool: ${tool.name}`);
lines.push(`Description: ${tool.description}`);
lines.push("");
lines.push("Parameters:");
for (const param of tool.parameters) {
const required = param.required ? "(required)" : "(optional)";
let line = ` - ${param.name} ${required}: ${param.type}`;
if (param.description) {
line += ` - ${param.description}`;
}
if (param.enum) {
line += ` [Options: ${param.enum.join(", ")}]`;
}
if (param.default !== undefined) {
line += ` [Default: ${param.default}]`;
}
lines.push(line);
}
if (includeExamples) {
lines.push("");
lines.push("Example usage:");
const exampleArgs = tool.parameters
.filter((p) => p.required)
.map((p) => {
const value = p.enum ? `"${p.enum[0]}"` : getExampleValue(p.type);
return `"${p.name}": ${value}`;
})
.join(", ");
lines.push(` ${tool.name}({ ${exampleArgs} })`);
}
return lines.join("\n");
}
function formatToolXml(tool) {
const lines = [];
lines.push(`<tool name="${tool.name}">`);
lines.push(` <description>${escapeXml(tool.description)}</description>`);
lines.push(` <parameters>`);
for (const param of tool.parameters) {
const attrs = [
`name="${param.name}"`,
`type="${param.type}"`,
param.required ? 'required="true"' : 'required="false"',
];
if (param.default !== undefined) {
attrs.push(`default="${param.default}"`);
}
lines.push(` <parameter ${attrs.join(" ")}>`);
if (param.description) {
lines.push(` <description>${escapeXml(param.description)}</description>`);
}
if (param.enum) {
lines.push(` <enum>${param.enum.join(", ")}</enum>`);
}
lines.push(` </parameter>`);
}
lines.push(` </parameters>`);
lines.push(`</tool>`);
return lines.join("\n");
}
export function formatTools(tools, options = {}) {
const { style = "json-schema" } = options;
if (style === "json-schema") {
return JSON.stringify(tools.map((tool) => JSON.parse(formatToolJsonSchema(tool, true))), null, 2);
}
return tools
.map((tool) => formatTool(tool, options))
.join("\n\n" + "=".repeat(50) + "\n\n");
}
export function createTool(name, description, parameters) {
return {
name,
description,
parameters,
};
}
export function createParameter(name, type, description, required = false) {
return {
name,
type,
description,
required,
};
}
export function validateTool(tool) {
const errors = [];
if (!tool.name || tool.name.trim().length === 0) {
errors.push("Tool name is required");
}
if (!/^[a-zA-Z_][a-zA-Z0-9_]*$/.test(tool.name)) {
errors.push("Tool name must be a valid identifier");
}
if (!tool.description || tool.description.trim().length === 0) {
errors.push("Tool description is required");
}
if (!tool.parameters || !Array.isArray(tool.parameters)) {
errors.push("Tool parameters must be an array");
}
else {
for (let i = 0; i < tool.parameters.length; i++) {
const param = tool.parameters[i];
if (!param.name || param.name.trim().length === 0) {
errors.push(`Parameter ${i} is missing a name`);
}
if (!/^[a-zA-Z_][a-zA-Z0-9_]*$/.test(param.name)) {
errors.push(`Parameter ${param.name} must be a valid identifier`);
}
if (!param.type) {
errors.push(`Parameter ${param.name} is missing a type`);
}
const validTypes = [
"string",
"number",
"integer",
"boolean",
"array",
"object",
];
if (!validTypes.includes(param.type)) {
errors.push(`Parameter ${param.name} has invalid type: ${param.type}`);
}
}
}
return errors;
}
function getExampleValue(type) {
switch (type) {
case "string":
return '"example"';
case "number":
case "integer":
return "42";
case "boolean":
return "true";
case "array":
return "[]";
case "object":
return "{}";
default:
return '""';
}
}
function escapeXml(str) {
return str
.replace(/&/g, "&")
.replace(/</g, "<")
.replace(/>/g, ">")
.replace(/"/g, """)
.replace(/'/g, "'");
}
export function formatFunctionArguments(args, pretty = false) {
return JSON.stringify(args, null, pretty ? 2 : 0);
}
export function parseFunctionCall(output) {
const patterns = [
/\{\s*"name"\s*:\s*"([^"]+)"\s*,\s*"arguments"\s*:\s*(\{[^}]*\})\s*\}/,
/([a-zA-Z_][a-zA-Z0-9_]*)\s*\(\s*(\{[^}]*\})\s*\)/,
];
for (const pattern of patterns) {
const match = output.match(pattern);
if (match && match[1] && match[2]) {
try {
const name = match[1];
const args = JSON.parse(match[2]);
return { name, arguments: args };
}
catch {
continue;
}
}
}
return null;
}
//# sourceMappingURL=tools.js.map