UNPKG

@langchain/anthropic

Version:
102 lines (98 loc) 4.02 kB
import { XMLBuilder } from "fast-xml-parser"; import { PromptTemplate } from "@langchain/core/prompts"; export const DEFAULT_TOOL_SYSTEM_PROMPT = /* #__PURE__ */ PromptTemplate.fromTemplate(`In this environment you have access to a set of tools you can use to answer the user's question. You may call them like this: <function_calls> <invoke> <tool_name>$TOOL_NAME</tool_name> <parameters> <$PARAMETER_NAME>$PARAMETER_VALUE</$PARAMETER_NAME> ... </parameters> </invoke> </function_calls> Here are the tools available: {tools} If the schema above contains a property typed as an enum, you must only return values matching an allowed value for that enum.`); export function formatAsXMLRepresentation(tool) { const builder = new XMLBuilder(); // eslint-disable-next-line @typescript-eslint/no-explicit-any const toolParamProps = tool.function.parameters?.properties; const parameterXml = Object.keys(toolParamProps) .map((key) => { const parameterData = toolParamProps[key]; let xml = `<parameter> <name>${key}</name> <type>${parameterData.type}</type>`; if (parameterData.description) { xml += `\n<description>${parameterData.description}</description>`; } if (parameterData.type === "array" && parameterData.items) { xml += `\n<items>${builder.build(parameterData.items.properties)}</items>`; } if (parameterData.properties) { xml += `\n<properties>\n${builder.build(parameterData.properties)}\n</properties>`; } return `${xml}\n</parameter>`; }) .join("\n"); return `<tool_description> <tool_name>${tool.function.name}</tool_name> <description>${tool.function.description}</description> <parameters> ${parameterXml} </parameters> </tool_description>`; } export function fixArrayXMLParameters(schema, // eslint-disable-next-line @typescript-eslint/no-explicit-any xmlParameters // eslint-disable-next-line @typescript-eslint/no-explicit-any ) { // eslint-disable-next-line @typescript-eslint/no-explicit-any const fixedParameters = {}; for (const key of Object.keys(xmlParameters)) { // eslint-disable-next-line @typescript-eslint/no-explicit-any const schemaType = schema.properties[key].type; // Crawl for lists indistinguishable from single items if (schema.properties && schema.properties[key] && schemaType === "array") { const value = xmlParameters[key]; if (Array.isArray(value)) { fixedParameters[key] = value; } else if (typeof value === "string") { if (value.startsWith("[") && value.endsWith("]")) { fixedParameters[key] = JSON.parse(value); } else { fixedParameters[key] = value.split(","); } } else { fixedParameters[key] = [value]; } // Crawl for objects like {"item": "my string"} that should really just be "my string" if (schemaType !== "object" && typeof xmlParameters[key] === "object" && !Array.isArray(xmlParameters[key]) && Object.keys(xmlParameters[key]).length === 1) { // eslint-disable-next-line prefer-destructuring fixedParameters[key] = Object.values(xmlParameters[key])[0]; } } else if (typeof xmlParameters[key] === "object" && xmlParameters[key] !== null) { fixedParameters[key] = fixArrayXMLParameters({ ...schema.properties[key], // eslint-disable-next-line @typescript-eslint/no-explicit-any definitions: schema.definitions, // eslint-disable-next-line @typescript-eslint/no-explicit-any }, xmlParameters[key]); } else { fixedParameters[key] = xmlParameters[key]; } } return fixedParameters; }