@langchain/anthropic 0.1.1 → 0.1.3

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -0,0 +1,260 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.ChatAnthropicTools = void 0;
4
+ const fast_xml_parser_1 = require("fast-xml-parser");
5
+ const messages_1 = require("@langchain/core/messages");
6
+ const chat_models_1 = require("@langchain/core/language_models/chat_models");
7
+ const runnables_1 = require("@langchain/core/runnables");
8
+ const openai_tools_1 = require("@langchain/core/output_parsers/openai_tools");
9
+ const zod_to_json_schema_1 = require("zod-to-json-schema");
10
+ const chat_models_js_1 = require("../chat_models.cjs");
11
+ const tool_calling_js_1 = require("./utils/tool_calling.cjs");
12
+ /**
13
+ * Experimental wrapper over Anthropic chat models that adds support for
14
+ * a function calling interface.
15
+ */
16
+ class ChatAnthropicTools extends chat_models_1.BaseChatModel {
17
+ static lc_name() {
18
+ return "ChatAnthropicTools";
19
+ }
20
+ constructor(fields) {
21
+ super(fields ?? {});
22
+ Object.defineProperty(this, "llm", {
23
+ enumerable: true,
24
+ configurable: true,
25
+ writable: true,
26
+ value: void 0
27
+ });
28
+ Object.defineProperty(this, "stopSequences", {
29
+ enumerable: true,
30
+ configurable: true,
31
+ writable: true,
32
+ value: void 0
33
+ });
34
+ Object.defineProperty(this, "systemPromptTemplate", {
35
+ enumerable: true,
36
+ configurable: true,
37
+ writable: true,
38
+ value: void 0
39
+ });
40
+ Object.defineProperty(this, "lc_namespace", {
41
+ enumerable: true,
42
+ configurable: true,
43
+ writable: true,
44
+ value: ["langchain", "experimental", "chat_models"]
45
+ });
46
+ this.llm = fields?.llm ?? new chat_models_js_1.ChatAnthropic(fields);
47
+ this.systemPromptTemplate =
48
+ fields?.systemPromptTemplate ?? tool_calling_js_1.DEFAULT_TOOL_SYSTEM_PROMPT;
49
+ this.stopSequences =
50
+ fields?.stopSequences ?? this.llm.stopSequences;
51
+ }
52
+ invocationParams() {
53
+ return this.llm.invocationParams();
54
+ }
55
+ /** @ignore */
56
+ _identifyingParams() {
57
+ return this.llm._identifyingParams();
58
+ }
59
+ async *_streamResponseChunks(messages, options, runManager) {
60
+ yield* this.llm._streamResponseChunks(messages, options, runManager);
61
+ }
62
+ async _prepareAndParseToolCall({ messages, options, runManager, systemPromptTemplate = tool_calling_js_1.DEFAULT_TOOL_SYSTEM_PROMPT, stopSequences, }) {
63
+ let promptMessages = messages;
64
+ let forced = false;
65
+ let toolCall;
66
+ const tools = options.tools === undefined ? [] : [...options.tools];
67
+ if (options.tools !== undefined && options.tools.length > 0) {
68
+ const content = await systemPromptTemplate.format({
69
+ tools: `<tools>\n${options.tools
70
+ .map(tool_calling_js_1.formatAsXMLRepresentation)
71
+ .join("\n\n")}</tools>`,
72
+ });
73
+ if (promptMessages.length && promptMessages[0]._getType() !== "system") {
74
+ const systemMessage = new messages_1.SystemMessage({ content });
75
+ promptMessages = [systemMessage].concat(promptMessages);
76
+ }
77
+ else {
78
+ const systemMessage = new messages_1.SystemMessage({
79
+ content: `${content}\n\n${promptMessages[0].content}`,
80
+ });
81
+ promptMessages = [systemMessage].concat(promptMessages.slice(1));
82
+ }
83
+ // eslint-disable-next-line no-param-reassign
84
+ options.stop = stopSequences.concat(["</function_calls>"]);
85
+ if (options.tool_choice && options.tool_choice !== "auto") {
86
+ toolCall = options.tool_choice.function.name;
87
+ forced = true;
88
+ const matchingFunction = options.tools.find(
89
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
90
+ (tool) => tool.function.name === toolCall);
91
+ if (!matchingFunction) {
92
+ throw new Error(`No matching function found for passed "tool_choice"`);
93
+ }
94
+ promptMessages = promptMessages.concat([
95
+ new messages_1.AIMessage({
96
+ content: `<function_calls>\n<invoke><tool_name>${toolCall}</tool_name>`,
97
+ }),
98
+ ]);
99
+ // eslint-disable-next-line no-param-reassign
100
+ delete options.tool_choice;
101
+ }
102
+ // eslint-disable-next-line no-param-reassign
103
+ delete options.tools;
104
+ }
105
+ else if (options.tool_choice !== undefined) {
106
+ throw new Error(`If "tool_choice" is provided, "tools" must also be.`);
107
+ }
108
+ const chatResult = await this.llm._generate(promptMessages, options, runManager);
109
+ const chatGenerationContent = chatResult.generations[0].message.content;
110
+ if (typeof chatGenerationContent !== "string") {
111
+ throw new Error("AnthropicFunctions does not support non-string output.");
112
+ }
113
+ if (forced) {
114
+ const parser = new fast_xml_parser_1.XMLParser();
115
+ const result = parser.parse(`<function_calls>\n<invoke><tool_name>${toolCall}</tool_name>${chatGenerationContent}</function_calls>`);
116
+ if (toolCall === undefined) {
117
+ throw new Error(`Could not parse called function from model output.`);
118
+ }
119
+ const invocations = Array.isArray(result.function_calls?.invoke ?? [])
120
+ ? result.function_calls.invoke
121
+ : [result.function_calls.invoke];
122
+ const responseMessageWithFunctions = new messages_1.AIMessage({
123
+ content: "",
124
+ additional_kwargs: {
125
+ tool_calls: invocations.map((toolInvocation, i) => {
126
+ const calledTool = tools.find((tool) => tool.function.name === toolCall);
127
+ if (calledTool === undefined) {
128
+ throw new Error(`Called tool "${toolCall}" did not match an existing tool.`);
129
+ }
130
+ return {
131
+ id: i.toString(),
132
+ type: "function",
133
+ function: {
134
+ name: toolInvocation.tool_name,
135
+ arguments: JSON.stringify((0, tool_calling_js_1.fixArrayXMLParameters)(calledTool.function.parameters, toolInvocation.parameters)),
136
+ },
137
+ };
138
+ }),
139
+ },
140
+ });
141
+ return {
142
+ generations: [{ message: responseMessageWithFunctions, text: "" }],
143
+ };
144
+ }
145
+ else if (chatGenerationContent.includes("<function_calls>")) {
146
+ const parser = new fast_xml_parser_1.XMLParser();
147
+ const result = parser.parse(`${chatGenerationContent}</function_calls>`);
148
+ const invocations = Array.isArray(result.function_calls?.invoke ?? [])
149
+ ? result.function_calls.invoke
150
+ : [result.function_calls.invoke];
151
+ const responseMessageWithFunctions = new messages_1.AIMessage({
152
+ content: chatGenerationContent.split("<function_calls>")[0],
153
+ additional_kwargs: {
154
+ tool_calls: invocations.map((toolInvocation, i) => {
155
+ const calledTool = tools.find((tool) => tool.function.name === toolInvocation.tool_name);
156
+ if (calledTool === undefined) {
157
+ throw new Error(`Called tool "${toolCall}" did not match an existing tool.`);
158
+ }
159
+ return {
160
+ id: i.toString(),
161
+ type: "function",
162
+ function: {
163
+ name: toolInvocation.tool_name,
164
+ arguments: JSON.stringify((0, tool_calling_js_1.fixArrayXMLParameters)(calledTool.function.parameters, toolInvocation.parameters)),
165
+ },
166
+ };
167
+ }),
168
+ },
169
+ });
170
+ return {
171
+ generations: [{ message: responseMessageWithFunctions, text: "" }],
172
+ };
173
+ }
174
+ return chatResult;
175
+ }
176
+ async _generate(messages, options, _runManager) {
177
+ return this._prepareAndParseToolCall({
178
+ messages,
179
+ options,
180
+ systemPromptTemplate: this.systemPromptTemplate,
181
+ stopSequences: this.stopSequences ?? [],
182
+ });
183
+ }
184
+ _llmType() {
185
+ return "anthropic_tool_calling";
186
+ }
187
+ withStructuredOutput({ schema, name, method, includeRaw, }) {
188
+ if (method === "jsonMode") {
189
+ throw new Error(`Anthropic only supports "functionCalling" as a method.`);
190
+ }
191
+ const functionName = name ?? "extract";
192
+ const outputParser = new openai_tools_1.JsonOutputKeyToolsParser({
193
+ returnSingle: true,
194
+ keyName: functionName,
195
+ });
196
+ let tools;
197
+ if (isZodSchema(schema)) {
198
+ const jsonSchema = (0, zod_to_json_schema_1.zodToJsonSchema)(schema);
199
+ tools = [
200
+ {
201
+ type: "function",
202
+ function: {
203
+ name: functionName,
204
+ description: jsonSchema.description,
205
+ parameters: jsonSchema,
206
+ },
207
+ },
208
+ ];
209
+ }
210
+ else {
211
+ tools = [
212
+ {
213
+ type: "function",
214
+ function: {
215
+ name: functionName,
216
+ description: schema.description,
217
+ parameters: schema,
218
+ },
219
+ },
220
+ ];
221
+ }
222
+ const llm = this.bind({
223
+ tools,
224
+ tool_choice: {
225
+ type: "function",
226
+ function: {
227
+ name: functionName,
228
+ },
229
+ },
230
+ });
231
+ if (!includeRaw) {
232
+ return llm.pipe(outputParser).withConfig({
233
+ runName: "ChatAnthropicStructuredOutput",
234
+ });
235
+ }
236
+ const parserAssign = runnables_1.RunnablePassthrough.assign({
237
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
238
+ parsed: (input, config) => outputParser.invoke(input.raw, config),
239
+ });
240
+ const parserNone = runnables_1.RunnablePassthrough.assign({
241
+ parsed: () => null,
242
+ });
243
+ const parsedWithFallback = parserAssign.withFallbacks({
244
+ fallbacks: [parserNone],
245
+ });
246
+ return runnables_1.RunnableSequence.from([
247
+ {
248
+ raw: llm,
249
+ },
250
+ parsedWithFallback,
251
+ ]).withConfig({
252
+ runName: "StructuredOutputRunnable",
253
+ });
254
+ }
255
+ }
256
+ exports.ChatAnthropicTools = ChatAnthropicTools;
257
+ function isZodSchema(input) {
258
+ // Check for a characteristic method of Zod schemas
259
+ return typeof input?.parse === "function";
260
+ }
@@ -0,0 +1,51 @@
1
+ import { BaseMessage } from "@langchain/core/messages";
2
+ import { ChatGenerationChunk, ChatResult } from "@langchain/core/outputs";
3
+ import { BaseChatModel, BaseChatModelParams } from "@langchain/core/language_models/chat_models";
4
+ import { CallbackManagerForLLMRun } from "@langchain/core/callbacks/manager";
5
+ import { BasePromptTemplate } from "@langchain/core/prompts";
6
+ import { BaseLanguageModelCallOptions, BaseLanguageModelInput, StructuredOutputMethodParams, ToolDefinition } from "@langchain/core/language_models/base";
7
+ import { Runnable } from "@langchain/core/runnables";
8
+ import { type AnthropicInput } from "../chat_models.js";
9
+ export interface ChatAnthropicToolsCallOptions extends BaseLanguageModelCallOptions {
10
+ tools?: ToolDefinition[];
11
+ tool_choice?: "auto" | {
12
+ function: {
13
+ name: string;
14
+ };
15
+ type: "function";
16
+ };
17
+ }
18
+ export type ChatAnthropicToolsInput = Partial<AnthropicInput> & BaseChatModelParams & {
19
+ llm?: BaseChatModel;
20
+ systemPromptTemplate?: BasePromptTemplate;
21
+ };
22
+ /**
23
+ * Experimental wrapper over Anthropic chat models that adds support for
24
+ * a function calling interface.
25
+ */
26
+ export declare class ChatAnthropicTools extends BaseChatModel<ChatAnthropicToolsCallOptions> {
27
+ llm: BaseChatModel;
28
+ stopSequences?: string[];
29
+ systemPromptTemplate: BasePromptTemplate;
30
+ lc_namespace: string[];
31
+ static lc_name(): string;
32
+ constructor(fields?: ChatAnthropicToolsInput);
33
+ invocationParams(): any;
34
+ /** @ignore */
35
+ _identifyingParams(): Record<string, any>;
36
+ _streamResponseChunks(messages: BaseMessage[], options: this["ParsedCallOptions"], runManager?: CallbackManagerForLLMRun): AsyncGenerator<ChatGenerationChunk>;
37
+ _prepareAndParseToolCall({ messages, options, runManager, systemPromptTemplate, stopSequences, }: {
38
+ messages: BaseMessage[];
39
+ options: ChatAnthropicToolsCallOptions;
40
+ runManager?: CallbackManagerForLLMRun;
41
+ systemPromptTemplate?: BasePromptTemplate;
42
+ stopSequences: string[];
43
+ }): Promise<ChatResult>;
44
+ _generate(messages: BaseMessage[], options: this["ParsedCallOptions"], _runManager?: CallbackManagerForLLMRun | undefined): Promise<ChatResult>;
45
+ _llmType(): string;
46
+ withStructuredOutput<RunOutput extends Record<string, any> = Record<string, any>>({ schema, name, method, includeRaw, }: StructuredOutputMethodParams<RunOutput, false>): Runnable<BaseLanguageModelInput, RunOutput>;
47
+ withStructuredOutput<RunOutput extends Record<string, any> = Record<string, any>>({ schema, name, method, includeRaw, }: StructuredOutputMethodParams<RunOutput, true>): Runnable<BaseLanguageModelInput, {
48
+ raw: BaseMessage;
49
+ parsed: RunOutput;
50
+ }>;
51
+ }
@@ -0,0 +1,256 @@
1
+ import { XMLParser } from "fast-xml-parser";
2
+ import { AIMessage, SystemMessage, } from "@langchain/core/messages";
3
+ import { BaseChatModel, } from "@langchain/core/language_models/chat_models";
4
+ import { RunnablePassthrough, RunnableSequence, } from "@langchain/core/runnables";
5
+ import { JsonOutputKeyToolsParser } from "@langchain/core/output_parsers/openai_tools";
6
+ import { zodToJsonSchema } from "zod-to-json-schema";
7
+ import { ChatAnthropic } from "../chat_models.js";
8
+ import { DEFAULT_TOOL_SYSTEM_PROMPT, formatAsXMLRepresentation, fixArrayXMLParameters, } from "./utils/tool_calling.js";
9
+ /**
10
+ * Experimental wrapper over Anthropic chat models that adds support for
11
+ * a function calling interface.
12
+ */
13
+ export class ChatAnthropicTools extends BaseChatModel {
14
+ static lc_name() {
15
+ return "ChatAnthropicTools";
16
+ }
17
+ constructor(fields) {
18
+ super(fields ?? {});
19
+ Object.defineProperty(this, "llm", {
20
+ enumerable: true,
21
+ configurable: true,
22
+ writable: true,
23
+ value: void 0
24
+ });
25
+ Object.defineProperty(this, "stopSequences", {
26
+ enumerable: true,
27
+ configurable: true,
28
+ writable: true,
29
+ value: void 0
30
+ });
31
+ Object.defineProperty(this, "systemPromptTemplate", {
32
+ enumerable: true,
33
+ configurable: true,
34
+ writable: true,
35
+ value: void 0
36
+ });
37
+ Object.defineProperty(this, "lc_namespace", {
38
+ enumerable: true,
39
+ configurable: true,
40
+ writable: true,
41
+ value: ["langchain", "experimental", "chat_models"]
42
+ });
43
+ this.llm = fields?.llm ?? new ChatAnthropic(fields);
44
+ this.systemPromptTemplate =
45
+ fields?.systemPromptTemplate ?? DEFAULT_TOOL_SYSTEM_PROMPT;
46
+ this.stopSequences =
47
+ fields?.stopSequences ?? this.llm.stopSequences;
48
+ }
49
+ invocationParams() {
50
+ return this.llm.invocationParams();
51
+ }
52
+ /** @ignore */
53
+ _identifyingParams() {
54
+ return this.llm._identifyingParams();
55
+ }
56
+ async *_streamResponseChunks(messages, options, runManager) {
57
+ yield* this.llm._streamResponseChunks(messages, options, runManager);
58
+ }
59
+ async _prepareAndParseToolCall({ messages, options, runManager, systemPromptTemplate = DEFAULT_TOOL_SYSTEM_PROMPT, stopSequences, }) {
60
+ let promptMessages = messages;
61
+ let forced = false;
62
+ let toolCall;
63
+ const tools = options.tools === undefined ? [] : [...options.tools];
64
+ if (options.tools !== undefined && options.tools.length > 0) {
65
+ const content = await systemPromptTemplate.format({
66
+ tools: `<tools>\n${options.tools
67
+ .map(formatAsXMLRepresentation)
68
+ .join("\n\n")}</tools>`,
69
+ });
70
+ if (promptMessages.length && promptMessages[0]._getType() !== "system") {
71
+ const systemMessage = new SystemMessage({ content });
72
+ promptMessages = [systemMessage].concat(promptMessages);
73
+ }
74
+ else {
75
+ const systemMessage = new SystemMessage({
76
+ content: `${content}\n\n${promptMessages[0].content}`,
77
+ });
78
+ promptMessages = [systemMessage].concat(promptMessages.slice(1));
79
+ }
80
+ // eslint-disable-next-line no-param-reassign
81
+ options.stop = stopSequences.concat(["</function_calls>"]);
82
+ if (options.tool_choice && options.tool_choice !== "auto") {
83
+ toolCall = options.tool_choice.function.name;
84
+ forced = true;
85
+ const matchingFunction = options.tools.find(
86
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
87
+ (tool) => tool.function.name === toolCall);
88
+ if (!matchingFunction) {
89
+ throw new Error(`No matching function found for passed "tool_choice"`);
90
+ }
91
+ promptMessages = promptMessages.concat([
92
+ new AIMessage({
93
+ content: `<function_calls>\n<invoke><tool_name>${toolCall}</tool_name>`,
94
+ }),
95
+ ]);
96
+ // eslint-disable-next-line no-param-reassign
97
+ delete options.tool_choice;
98
+ }
99
+ // eslint-disable-next-line no-param-reassign
100
+ delete options.tools;
101
+ }
102
+ else if (options.tool_choice !== undefined) {
103
+ throw new Error(`If "tool_choice" is provided, "tools" must also be.`);
104
+ }
105
+ const chatResult = await this.llm._generate(promptMessages, options, runManager);
106
+ const chatGenerationContent = chatResult.generations[0].message.content;
107
+ if (typeof chatGenerationContent !== "string") {
108
+ throw new Error("AnthropicFunctions does not support non-string output.");
109
+ }
110
+ if (forced) {
111
+ const parser = new XMLParser();
112
+ const result = parser.parse(`<function_calls>\n<invoke><tool_name>${toolCall}</tool_name>${chatGenerationContent}</function_calls>`);
113
+ if (toolCall === undefined) {
114
+ throw new Error(`Could not parse called function from model output.`);
115
+ }
116
+ const invocations = Array.isArray(result.function_calls?.invoke ?? [])
117
+ ? result.function_calls.invoke
118
+ : [result.function_calls.invoke];
119
+ const responseMessageWithFunctions = new AIMessage({
120
+ content: "",
121
+ additional_kwargs: {
122
+ tool_calls: invocations.map((toolInvocation, i) => {
123
+ const calledTool = tools.find((tool) => tool.function.name === toolCall);
124
+ if (calledTool === undefined) {
125
+ throw new Error(`Called tool "${toolCall}" did not match an existing tool.`);
126
+ }
127
+ return {
128
+ id: i.toString(),
129
+ type: "function",
130
+ function: {
131
+ name: toolInvocation.tool_name,
132
+ arguments: JSON.stringify(fixArrayXMLParameters(calledTool.function.parameters, toolInvocation.parameters)),
133
+ },
134
+ };
135
+ }),
136
+ },
137
+ });
138
+ return {
139
+ generations: [{ message: responseMessageWithFunctions, text: "" }],
140
+ };
141
+ }
142
+ else if (chatGenerationContent.includes("<function_calls>")) {
143
+ const parser = new XMLParser();
144
+ const result = parser.parse(`${chatGenerationContent}</function_calls>`);
145
+ const invocations = Array.isArray(result.function_calls?.invoke ?? [])
146
+ ? result.function_calls.invoke
147
+ : [result.function_calls.invoke];
148
+ const responseMessageWithFunctions = new AIMessage({
149
+ content: chatGenerationContent.split("<function_calls>")[0],
150
+ additional_kwargs: {
151
+ tool_calls: invocations.map((toolInvocation, i) => {
152
+ const calledTool = tools.find((tool) => tool.function.name === toolInvocation.tool_name);
153
+ if (calledTool === undefined) {
154
+ throw new Error(`Called tool "${toolCall}" did not match an existing tool.`);
155
+ }
156
+ return {
157
+ id: i.toString(),
158
+ type: "function",
159
+ function: {
160
+ name: toolInvocation.tool_name,
161
+ arguments: JSON.stringify(fixArrayXMLParameters(calledTool.function.parameters, toolInvocation.parameters)),
162
+ },
163
+ };
164
+ }),
165
+ },
166
+ });
167
+ return {
168
+ generations: [{ message: responseMessageWithFunctions, text: "" }],
169
+ };
170
+ }
171
+ return chatResult;
172
+ }
173
+ async _generate(messages, options, _runManager) {
174
+ return this._prepareAndParseToolCall({
175
+ messages,
176
+ options,
177
+ systemPromptTemplate: this.systemPromptTemplate,
178
+ stopSequences: this.stopSequences ?? [],
179
+ });
180
+ }
181
+ _llmType() {
182
+ return "anthropic_tool_calling";
183
+ }
184
+ withStructuredOutput({ schema, name, method, includeRaw, }) {
185
+ if (method === "jsonMode") {
186
+ throw new Error(`Anthropic only supports "functionCalling" as a method.`);
187
+ }
188
+ const functionName = name ?? "extract";
189
+ const outputParser = new JsonOutputKeyToolsParser({
190
+ returnSingle: true,
191
+ keyName: functionName,
192
+ });
193
+ let tools;
194
+ if (isZodSchema(schema)) {
195
+ const jsonSchema = zodToJsonSchema(schema);
196
+ tools = [
197
+ {
198
+ type: "function",
199
+ function: {
200
+ name: functionName,
201
+ description: jsonSchema.description,
202
+ parameters: jsonSchema,
203
+ },
204
+ },
205
+ ];
206
+ }
207
+ else {
208
+ tools = [
209
+ {
210
+ type: "function",
211
+ function: {
212
+ name: functionName,
213
+ description: schema.description,
214
+ parameters: schema,
215
+ },
216
+ },
217
+ ];
218
+ }
219
+ const llm = this.bind({
220
+ tools,
221
+ tool_choice: {
222
+ type: "function",
223
+ function: {
224
+ name: functionName,
225
+ },
226
+ },
227
+ });
228
+ if (!includeRaw) {
229
+ return llm.pipe(outputParser).withConfig({
230
+ runName: "ChatAnthropicStructuredOutput",
231
+ });
232
+ }
233
+ const parserAssign = RunnablePassthrough.assign({
234
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
235
+ parsed: (input, config) => outputParser.invoke(input.raw, config),
236
+ });
237
+ const parserNone = RunnablePassthrough.assign({
238
+ parsed: () => null,
239
+ });
240
+ const parsedWithFallback = parserAssign.withFallbacks({
241
+ fallbacks: [parserNone],
242
+ });
243
+ return RunnableSequence.from([
244
+ {
245
+ raw: llm,
246
+ },
247
+ parsedWithFallback,
248
+ ]).withConfig({
249
+ runName: "StructuredOutputRunnable",
250
+ });
251
+ }
252
+ }
253
+ function isZodSchema(input) {
254
+ // Check for a characteristic method of Zod schemas
255
+ return typeof input?.parse === "function";
256
+ }
@@ -0,0 +1,87 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.fixArrayXMLParameters = exports.formatAsXMLRepresentation = exports.DEFAULT_TOOL_SYSTEM_PROMPT = void 0;
4
+ const fast_xml_parser_1 = require("fast-xml-parser");
5
+ const prompts_1 = require("@langchain/core/prompts");
6
+ exports.DEFAULT_TOOL_SYSTEM_PROMPT =
7
+ /* #__PURE__ */ prompts_1.PromptTemplate.fromTemplate(`In this environment you have access to a set of tools you can use to answer the user's question.
8
+
9
+ You may call them like this:
10
+ <function_calls>
11
+ <invoke>
12
+ <tool_name>$TOOL_NAME</tool_name>
13
+ <parameters>
14
+ <$PARAMETER_NAME>$PARAMETER_VALUE</$PARAMETER_NAME>
15
+ ...
16
+ </parameters>
17
+ </invoke>
18
+ </function_calls>
19
+
20
+ Here are the tools available:
21
+ {tools}`);
22
+ function formatAsXMLRepresentation(tool) {
23
+ const builder = new fast_xml_parser_1.XMLBuilder();
24
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
25
+ const toolParamProps = tool.function.parameters?.properties;
26
+ const parameterXml = Object.keys(toolParamProps)
27
+ .map((key) => {
28
+ const parameterData = toolParamProps[key];
29
+ let xml = `<parameter>
30
+ <name>${key}</name>
31
+ <type>${parameterData.type}</type>`;
32
+ if (parameterData.description) {
33
+ xml += `\n<description>${parameterData.description}</description>`;
34
+ }
35
+ if (parameterData.type === "array" && parameterData.items) {
36
+ xml += `\n<items>${builder.build(parameterData.items.properties)}</items>`;
37
+ }
38
+ if (parameterData.properties) {
39
+ xml += `\n<properties>\n${builder.build(parameterData.properties)}\n</properties>`;
40
+ }
41
+ return `${xml}\n</parameter>`;
42
+ })
43
+ .join("\n");
44
+ return `<tool_description>
45
+ <tool_name>${tool.function.name}</tool_name>
46
+ <description>${tool.function.description}</description>
47
+ <parameters>
48
+ ${parameterXml}
49
+ </parameters>
50
+ </tool_description>`;
51
+ }
52
+ exports.formatAsXMLRepresentation = formatAsXMLRepresentation;
53
+ function fixArrayXMLParameters(schema,
54
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
55
+ xmlParameters
56
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
57
+ ) {
58
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
59
+ const fixedParameters = {};
60
+ for (const key of Object.keys(xmlParameters)) {
61
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
62
+ const schemaType = schema.properties[key].type;
63
+ // Crawl for lists indistinguishable from single items
64
+ if (schema.properties && schema.properties[key] && schemaType === "array") {
65
+ fixedParameters[key] = Array.isArray(xmlParameters[key])
66
+ ? xmlParameters[key]
67
+ : [xmlParameters[key]];
68
+ // Crawl for objects like {"item": "my string"} that should really just be "my string"
69
+ if (schemaType !== "object" &&
70
+ typeof xmlParameters[key] === "object" &&
71
+ !Array.isArray(xmlParameters[key]) &&
72
+ Object.keys(xmlParameters[key]).length === 1) {
73
+ // eslint-disable-next-line prefer-destructuring
74
+ fixedParameters[key] = Object.values(xmlParameters[key])[0];
75
+ }
76
+ }
77
+ else if (typeof xmlParameters[key] === "object" &&
78
+ xmlParameters[key] !== null) {
79
+ fixedParameters[key] = fixArrayXMLParameters(schema, xmlParameters[key]);
80
+ }
81
+ else {
82
+ fixedParameters[key] = xmlParameters[key];
83
+ }
84
+ }
85
+ return fixedParameters;
86
+ }
87
+ exports.fixArrayXMLParameters = fixArrayXMLParameters;
@@ -0,0 +1,10 @@
1
+ import { JsonSchema7ObjectType } from "zod-to-json-schema";
2
+ import { PromptTemplate } from "@langchain/core/prompts";
3
+ import { ToolDefinition } from "@langchain/core/language_models/base";
4
+ export declare const DEFAULT_TOOL_SYSTEM_PROMPT: PromptTemplate<import("@langchain/core/prompts").ParamsFromFString<"In this environment you have access to a set of tools you can use to answer the user's question.\n\nYou may call them like this:\n<function_calls>\n<invoke>\n<tool_name>$TOOL_NAME</tool_name>\n<parameters>\n<$PARAMETER_NAME>$PARAMETER_VALUE</$PARAMETER_NAME>\n...\n</parameters>\n</invoke>\n</function_calls>\n\nHere are the tools available:\n{tools}">, any>;
5
+ export type ToolInvocation = {
6
+ tool_name: string;
7
+ parameters: Record<string, unknown>;
8
+ };
9
+ export declare function formatAsXMLRepresentation(tool: ToolDefinition): string;
10
+ export declare function fixArrayXMLParameters(schema: JsonSchema7ObjectType, xmlParameters: Record<string, any>): Record<string, any>;