@nocobase/plugin-ai 2.2.0-beta.7 → 2.2.0-beta.9
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.
- package/dist/ai/docs/nocobase/api/app/env.md +28 -1
- package/dist/ai/docs/nocobase/api/cli/config/delete.md +9 -6
- package/dist/ai/docs/nocobase/api/cli/config/get.md +8 -6
- package/dist/ai/docs/nocobase/api/cli/config/index.md +40 -26
- package/dist/ai/docs/nocobase/api/cli/config/set.md +15 -8
- package/dist/ai/docs/nocobase/api/cli/env/auth.md +53 -5
- package/dist/ai/docs/nocobase/api/cli/self/check.md +19 -2
- package/dist/ai/docs/nocobase/api/cli/self/index.md +1 -1
- package/dist/ai/docs/nocobase/api/cli/self/update.md +17 -3
- package/dist/ai/docs/nocobase/file-manager/field-attachment.md +6 -0
- package/dist/ai/docs/nocobase/file-manager/file-preview/index.md +3 -12
- package/dist/ai/docs/nocobase/file-manager/storage/aliyun-oss.md +9 -0
- package/dist/ai/docs/nocobase/file-manager/storage/amazon-s3.md +9 -0
- package/dist/ai/docs/nocobase/file-manager/storage/index.md +23 -0
- package/dist/ai/docs/nocobase/file-manager/storage/local.md +9 -0
- package/dist/ai/docs/nocobase/file-manager/storage/migrate-to-s3-pro.md +269 -0
- package/dist/ai/docs/nocobase/file-manager/storage/tencent-cos.md +9 -0
- package/dist/ai/docs/nocobase/get-started/installation/docker-caddy.mdx +175 -0
- package/dist/ai/docs/nocobase/get-started/installation/docker-nginx.mdx +176 -0
- package/dist/ai/docs/nocobase/get-started/installation/docker.mdx +94 -1
- package/dist/ai/docs/nocobase/get-started/installation/env.md +14 -4
- package/dist/ai/docs/nocobase/nocobase-cli/installation/cli.md +2 -0
- package/dist/ai/docs/nocobase/ops-management/version-control/index.md +1 -0
- package/dist/client/559.9f97ebcdb0bd6231.js +10 -0
- package/dist/client/{604.de96f3ec4d471afd.js → 604.89c674f35b52b4ef.js} +1 -1
- package/dist/client/index.js +3 -3
- package/dist/client/llm-providers/mistral/ModelSettings.d.ts +10 -0
- package/dist/client/llm-providers/mistral/index.d.ts +10 -0
- package/dist/client/llm-services/utils.d.ts +5 -0
- package/dist/externalVersion.js +16 -16
- package/dist/locale/en-US.json +1 -0
- package/dist/locale/zh-CN.json +1 -0
- package/dist/node_modules/@langchain/mistralai/LICENSE +21 -0
- package/dist/node_modules/@langchain/mistralai/dist/_virtual/rolldown_runtime.cjs +25 -0
- package/dist/node_modules/@langchain/mistralai/dist/chat_models.cjs +859 -0
- package/dist/node_modules/@langchain/mistralai/dist/chat_models.d.cts +541 -0
- package/dist/node_modules/@langchain/mistralai/dist/chat_models.d.ts +541 -0
- package/dist/node_modules/@langchain/mistralai/dist/chat_models.js +857 -0
- package/dist/node_modules/@langchain/mistralai/dist/embeddings.cjs +140 -0
- package/dist/node_modules/@langchain/mistralai/dist/embeddings.d.cts +116 -0
- package/dist/node_modules/@langchain/mistralai/dist/embeddings.d.ts +116 -0
- package/dist/node_modules/@langchain/mistralai/dist/embeddings.js +139 -0
- package/dist/node_modules/@langchain/mistralai/dist/index.cjs +21 -0
- package/dist/node_modules/@langchain/mistralai/dist/index.d.cts +4 -0
- package/dist/node_modules/@langchain/mistralai/dist/index.d.ts +4 -0
- package/dist/node_modules/@langchain/mistralai/dist/index.js +5 -0
- package/dist/node_modules/@langchain/mistralai/dist/llms.cjs +275 -0
- package/dist/node_modules/@langchain/mistralai/dist/llms.d.cts +147 -0
- package/dist/node_modules/@langchain/mistralai/dist/llms.d.ts +147 -0
- package/dist/node_modules/@langchain/mistralai/dist/llms.js +274 -0
- package/dist/node_modules/@langchain/mistralai/dist/utils.cjs +61 -0
- package/dist/node_modules/@langchain/mistralai/dist/utils.js +59 -0
- package/dist/node_modules/@langchain/mistralai/package.json +1 -0
- package/dist/node_modules/@langchain/xai/dist/index.cjs +2 -2
- package/dist/node_modules/@langchain/xai/package.json +1 -1
- package/dist/node_modules/fs-extra/package.json +1 -1
- package/dist/node_modules/jsonrepair/package.json +1 -1
- package/dist/node_modules/just-bash/package.json +1 -1
- package/dist/node_modules/nodejs-snowflake/package.json +1 -1
- package/dist/node_modules/openai/package.json +1 -1
- package/dist/node_modules/zod/package.json +1 -1
- package/dist/server/ai-employees/ai-employee.js +19 -6
- package/dist/server/ai-employees/checkpoints/cleaner.d.ts +2 -0
- package/dist/server/ai-employees/checkpoints/cleaner.js +11 -1
- package/dist/server/ai-employees/middleware/conversation.d.ts +2 -0
- package/dist/server/ai-employees/middleware/conversation.js +2 -1
- package/dist/server/ai-employees/middleware/index.d.ts +1 -0
- package/dist/server/ai-employees/middleware/index.js +2 -0
- package/dist/server/ai-employees/middleware/tool-call-sanitizer.d.ts +16 -0
- package/dist/server/ai-employees/middleware/tool-call-sanitizer.js +90 -0
- package/dist/server/ai-employees/tool-call-sanitizer.d.ts +26 -0
- package/dist/server/ai-employees/tool-call-sanitizer.js +84 -0
- package/dist/server/ai-employees/utils.d.ts +3 -1
- package/dist/server/ai-employees/utils.js +16 -2
- package/dist/server/llm-providers/mistral.d.ts +62 -0
- package/dist/server/llm-providers/mistral.js +265 -0
- package/dist/server/llm-providers/provider.d.ts +6 -2
- package/dist/server/llm-providers/provider.js +27 -14
- package/dist/server/plugin.js +2 -0
- package/dist/server/workflow/nodes/employee/index.js +92 -46
- package/dist/server/workflow/nodes/employee/tools.js +8 -1
- package/package.json +3 -2
- package/dist/client/559.a0f2f1cc2be3c039.js +0 -10
|
@@ -0,0 +1,857 @@
|
|
|
1
|
+
import { _convertToolCallIdToMistralCompatible, _mistralContentChunkToMessageContentComplex } from "./utils.js";
|
|
2
|
+
import { v4 } from "uuid";
|
|
3
|
+
import { Mistral } from "@mistralai/mistralai";
|
|
4
|
+
import { HTTPClient } from "@mistralai/mistralai/lib/http.js";
|
|
5
|
+
import { AIMessage, AIMessageChunk, ChatMessageChunk, FunctionMessageChunk, HumanMessage, HumanMessageChunk, ToolMessageChunk, isAIMessage } from "@langchain/core/messages";
|
|
6
|
+
import { BaseChatModel } from "@langchain/core/language_models/chat_models";
|
|
7
|
+
import { ChatGenerationChunk } from "@langchain/core/outputs";
|
|
8
|
+
import { AsyncCaller } from "@langchain/core/utils/async_caller";
|
|
9
|
+
import { getEnvironmentVariable } from "@langchain/core/utils/env";
|
|
10
|
+
import { JsonOutputParser, StructuredOutputParser } from "@langchain/core/output_parsers";
|
|
11
|
+
import { JsonOutputKeyToolsParser, convertLangChainToolCallToOpenAI, makeInvalidToolCall, parseToolCall } from "@langchain/core/output_parsers/openai_tools";
|
|
12
|
+
import { RunnableBinding, RunnablePassthrough, RunnableSequence } from "@langchain/core/runnables";
|
|
13
|
+
import { toJsonSchema } from "@langchain/core/utils/json_schema";
|
|
14
|
+
import { isLangChainTool } from "@langchain/core/utils/function_calling";
|
|
15
|
+
import { isInteropZodSchema } from "@langchain/core/utils/types";
|
|
16
|
+
|
|
17
|
+
//#region src/chat_models.ts
|
|
18
|
+
function convertMessagesToMistralMessages(messages) {
|
|
19
|
+
const getRole = (role) => {
|
|
20
|
+
switch (role) {
|
|
21
|
+
case "human": return "user";
|
|
22
|
+
case "ai": return "assistant";
|
|
23
|
+
case "system": return "system";
|
|
24
|
+
case "tool": return "tool";
|
|
25
|
+
case "function": return "assistant";
|
|
26
|
+
default: throw new Error(`Unknown message type: ${role}`);
|
|
27
|
+
}
|
|
28
|
+
};
|
|
29
|
+
const getContent = (content, type) => {
|
|
30
|
+
const _generateContentChunk = (complex, role) => {
|
|
31
|
+
if (complex.type === "image_url" && (role === "user" || role === "assistant")) return {
|
|
32
|
+
type: complex.type,
|
|
33
|
+
imageUrl: complex?.image_url
|
|
34
|
+
};
|
|
35
|
+
if (complex.type === "text") return {
|
|
36
|
+
type: complex.type,
|
|
37
|
+
text: complex?.text
|
|
38
|
+
};
|
|
39
|
+
throw new Error(`ChatMistralAI only supports messages of "image_url" for roles "user" and "assistant", and "text" for all others.\n\nReceived: ${JSON.stringify(content, null, 2)}`);
|
|
40
|
+
};
|
|
41
|
+
if (typeof content === "string") return content;
|
|
42
|
+
if (Array.isArray(content)) {
|
|
43
|
+
const mistralRole = getRole(type);
|
|
44
|
+
const newContent = [];
|
|
45
|
+
content.forEach((messageContentComplex) => {
|
|
46
|
+
if (messageContentComplex.type === "text" || messageContentComplex.type === "image_url") newContent.push(_generateContentChunk(messageContentComplex, mistralRole));
|
|
47
|
+
else throw new Error(`Mistral only supports types "text" or "image_url" for complex message types.`);
|
|
48
|
+
});
|
|
49
|
+
return newContent;
|
|
50
|
+
}
|
|
51
|
+
throw new Error(`Message content must be a string or an array.\n\nReceived: ${JSON.stringify(content, null, 2)}`);
|
|
52
|
+
};
|
|
53
|
+
const getTools = (message) => {
|
|
54
|
+
if (isAIMessage(message) && !!message.tool_calls?.length) return message.tool_calls.map((toolCall) => ({
|
|
55
|
+
...toolCall,
|
|
56
|
+
id: _convertToolCallIdToMistralCompatible(toolCall.id ?? "")
|
|
57
|
+
})).map(convertLangChainToolCallToOpenAI);
|
|
58
|
+
return void 0;
|
|
59
|
+
};
|
|
60
|
+
const toolResponseIds = /* @__PURE__ */ new Set();
|
|
61
|
+
for (const m of messages) if ("tool_call_id" in m && typeof m.tool_call_id === "string") toolResponseIds.add(_convertToolCallIdToMistralCompatible(m.tool_call_id));
|
|
62
|
+
return messages.flatMap((message) => {
|
|
63
|
+
const toolCalls = getTools(message);
|
|
64
|
+
const content = getContent(message.content, message.getType());
|
|
65
|
+
if ("tool_call_id" in message && typeof message.tool_call_id === "string") return [{
|
|
66
|
+
role: getRole(message.getType()),
|
|
67
|
+
content,
|
|
68
|
+
name: message.name,
|
|
69
|
+
toolCallId: _convertToolCallIdToMistralCompatible(message.tool_call_id)
|
|
70
|
+
}];
|
|
71
|
+
else if (isAIMessage(message)) if (toolCalls === void 0) return [{
|
|
72
|
+
role: getRole(message.getType()),
|
|
73
|
+
content
|
|
74
|
+
}];
|
|
75
|
+
else {
|
|
76
|
+
const filteredToolCalls = toolCalls.filter((tc) => toolResponseIds.has(_convertToolCallIdToMistralCompatible(tc.id ?? "")));
|
|
77
|
+
if (filteredToolCalls.length === 0) {
|
|
78
|
+
const isEmptyContent = typeof content === "string" && content.trim() === "" || Array.isArray(content) && content.length === 0;
|
|
79
|
+
if (isEmptyContent) return [];
|
|
80
|
+
return [{
|
|
81
|
+
role: getRole(message.getType()),
|
|
82
|
+
content
|
|
83
|
+
}];
|
|
84
|
+
}
|
|
85
|
+
return [{
|
|
86
|
+
role: getRole(message.getType()),
|
|
87
|
+
toolCalls: filteredToolCalls
|
|
88
|
+
}];
|
|
89
|
+
}
|
|
90
|
+
return [{
|
|
91
|
+
role: getRole(message.getType()),
|
|
92
|
+
content
|
|
93
|
+
}];
|
|
94
|
+
});
|
|
95
|
+
}
|
|
96
|
+
function mistralAIResponseToChatMessage(choice, usage) {
|
|
97
|
+
const { message } = choice;
|
|
98
|
+
if (message === void 0) throw new Error("No message found in response");
|
|
99
|
+
let rawToolCalls = [];
|
|
100
|
+
if ("toolCalls" in message && Array.isArray(message.toolCalls)) rawToolCalls = message.toolCalls;
|
|
101
|
+
const content = _mistralContentChunkToMessageContentComplex(message.content);
|
|
102
|
+
switch (message.role) {
|
|
103
|
+
case "assistant": {
|
|
104
|
+
const toolCalls = [];
|
|
105
|
+
const invalidToolCalls = [];
|
|
106
|
+
for (const rawToolCall of rawToolCalls) try {
|
|
107
|
+
const parsed = parseToolCall(rawToolCall, { returnId: true });
|
|
108
|
+
toolCalls.push({
|
|
109
|
+
...parsed,
|
|
110
|
+
id: parsed.id ?? v4().replace(/-/g, "")
|
|
111
|
+
});
|
|
112
|
+
} catch (e) {
|
|
113
|
+
invalidToolCalls.push(makeInvalidToolCall(rawToolCall, e.message));
|
|
114
|
+
}
|
|
115
|
+
return new AIMessage({
|
|
116
|
+
content,
|
|
117
|
+
tool_calls: toolCalls,
|
|
118
|
+
invalid_tool_calls: invalidToolCalls,
|
|
119
|
+
additional_kwargs: {},
|
|
120
|
+
usage_metadata: usage ? {
|
|
121
|
+
input_tokens: usage.promptTokens,
|
|
122
|
+
output_tokens: usage.completionTokens,
|
|
123
|
+
total_tokens: usage.totalTokens
|
|
124
|
+
} : void 0
|
|
125
|
+
});
|
|
126
|
+
}
|
|
127
|
+
default: return new HumanMessage({ content });
|
|
128
|
+
}
|
|
129
|
+
}
|
|
130
|
+
function _convertDeltaToMessageChunk(delta, usage) {
|
|
131
|
+
if (!delta.content && !delta.toolCalls) {
|
|
132
|
+
if (usage) return new AIMessageChunk({
|
|
133
|
+
content: "",
|
|
134
|
+
usage_metadata: usage ? {
|
|
135
|
+
input_tokens: usage.promptTokens,
|
|
136
|
+
output_tokens: usage.completionTokens,
|
|
137
|
+
total_tokens: usage.totalTokens
|
|
138
|
+
} : void 0
|
|
139
|
+
});
|
|
140
|
+
return null;
|
|
141
|
+
}
|
|
142
|
+
const rawToolCallChunksWithIndex = delta.toolCalls?.length ? delta.toolCalls?.map((toolCall, index) => ({
|
|
143
|
+
...toolCall,
|
|
144
|
+
index,
|
|
145
|
+
id: toolCall.id ?? v4().replace(/-/g, ""),
|
|
146
|
+
type: "function"
|
|
147
|
+
})) : void 0;
|
|
148
|
+
let role = "assistant";
|
|
149
|
+
if (delta.role) role = delta.role;
|
|
150
|
+
const content = _mistralContentChunkToMessageContentComplex(delta.content);
|
|
151
|
+
let additional_kwargs;
|
|
152
|
+
const toolCallChunks = [];
|
|
153
|
+
if (rawToolCallChunksWithIndex !== void 0) for (const rawToolCallChunk of rawToolCallChunksWithIndex) {
|
|
154
|
+
const rawArgs = rawToolCallChunk.function?.arguments;
|
|
155
|
+
const args = rawArgs === void 0 || typeof rawArgs === "string" ? rawArgs : JSON.stringify(rawArgs);
|
|
156
|
+
toolCallChunks.push({
|
|
157
|
+
name: rawToolCallChunk.function?.name,
|
|
158
|
+
args,
|
|
159
|
+
id: rawToolCallChunk.id,
|
|
160
|
+
index: rawToolCallChunk.index,
|
|
161
|
+
type: "tool_call_chunk"
|
|
162
|
+
});
|
|
163
|
+
}
|
|
164
|
+
else additional_kwargs = {};
|
|
165
|
+
if (role === "user") return new HumanMessageChunk({ content });
|
|
166
|
+
else if (role === "assistant") return new AIMessageChunk({
|
|
167
|
+
content,
|
|
168
|
+
tool_call_chunks: toolCallChunks,
|
|
169
|
+
additional_kwargs,
|
|
170
|
+
usage_metadata: usage ? {
|
|
171
|
+
input_tokens: usage.promptTokens,
|
|
172
|
+
output_tokens: usage.completionTokens,
|
|
173
|
+
total_tokens: usage.totalTokens
|
|
174
|
+
} : void 0
|
|
175
|
+
});
|
|
176
|
+
else if (role === "tool") return new ToolMessageChunk({
|
|
177
|
+
content,
|
|
178
|
+
additional_kwargs,
|
|
179
|
+
tool_call_id: rawToolCallChunksWithIndex?.[0].id ?? ""
|
|
180
|
+
});
|
|
181
|
+
else if (role === "function") return new FunctionMessageChunk({
|
|
182
|
+
content,
|
|
183
|
+
additional_kwargs
|
|
184
|
+
});
|
|
185
|
+
else return new ChatMessageChunk({
|
|
186
|
+
content,
|
|
187
|
+
role
|
|
188
|
+
});
|
|
189
|
+
}
|
|
190
|
+
function _convertToolToMistralTool(tools) {
|
|
191
|
+
if (!tools || !tools.length) return void 0;
|
|
192
|
+
return tools.map((tool) => {
|
|
193
|
+
if ("function" in tool) return {
|
|
194
|
+
type: tool.type ?? "function",
|
|
195
|
+
function: tool.function
|
|
196
|
+
};
|
|
197
|
+
if (isLangChainTool(tool)) {
|
|
198
|
+
const description = tool.description ?? `Tool: ${tool.name}`;
|
|
199
|
+
return {
|
|
200
|
+
type: "function",
|
|
201
|
+
function: {
|
|
202
|
+
name: tool.name,
|
|
203
|
+
description,
|
|
204
|
+
parameters: isInteropZodSchema(tool.schema) ? toJsonSchema(tool.schema) : tool.schema
|
|
205
|
+
}
|
|
206
|
+
};
|
|
207
|
+
}
|
|
208
|
+
throw new Error(`Unknown tool type passed to ChatMistral: ${JSON.stringify(tool, null, 2)}`);
|
|
209
|
+
});
|
|
210
|
+
}
|
|
211
|
+
/**
|
|
212
|
+
* Mistral AI chat model integration.
|
|
213
|
+
*
|
|
214
|
+
* Setup:
|
|
215
|
+
* Install `@langchain/mistralai` and set an environment variable named `MISTRAL_API_KEY`.
|
|
216
|
+
*
|
|
217
|
+
* ```bash
|
|
218
|
+
* npm install @langchain/mistralai
|
|
219
|
+
* export MISTRAL_API_KEY="your-api-key"
|
|
220
|
+
* ```
|
|
221
|
+
*
|
|
222
|
+
* ## [Constructor args](https://api.js.langchain.com/classes/_langchain_mistralai.ChatMistralAI.html#constructor)
|
|
223
|
+
*
|
|
224
|
+
* ## [Runtime args](https://api.js.langchain.com/interfaces/_langchain_mistralai.ChatMistralAICallOptions.html)
|
|
225
|
+
*
|
|
226
|
+
* Runtime args can be passed as the second argument to any of the base runnable methods `.invoke`. `.stream`, `.batch`, etc.
|
|
227
|
+
* They can also be passed via `.withConfig`, or the second arg in `.bindTools`, like shown in the examples below:
|
|
228
|
+
*
|
|
229
|
+
* ```typescript
|
|
230
|
+
* // When calling `.withConfig`, call options should be passed via the first argument
|
|
231
|
+
* const llmWithArgsBound = llm.bindTools([...]) // tools array
|
|
232
|
+
* .withConfig({
|
|
233
|
+
* stop: ["\n"], // other call options
|
|
234
|
+
* });
|
|
235
|
+
*
|
|
236
|
+
* // You can also bind tools and call options like this
|
|
237
|
+
* const llmWithTools = llm.bindTools([...], {
|
|
238
|
+
* tool_choice: "auto",
|
|
239
|
+
* });
|
|
240
|
+
* ```
|
|
241
|
+
*
|
|
242
|
+
* ## Examples
|
|
243
|
+
*
|
|
244
|
+
* <details open>
|
|
245
|
+
* <summary><strong>Instantiate</strong></summary>
|
|
246
|
+
*
|
|
247
|
+
* ```typescript
|
|
248
|
+
* import { ChatMistralAI } from '@langchain/mistralai';
|
|
249
|
+
*
|
|
250
|
+
* const llm = new ChatMistralAI({
|
|
251
|
+
* model: "mistral-large-2402",
|
|
252
|
+
* temperature: 0,
|
|
253
|
+
* // other params...
|
|
254
|
+
* });
|
|
255
|
+
* ```
|
|
256
|
+
* </details>
|
|
257
|
+
*
|
|
258
|
+
* <br />
|
|
259
|
+
*
|
|
260
|
+
* <details>
|
|
261
|
+
* <summary><strong>Invoking</strong></summary>
|
|
262
|
+
*
|
|
263
|
+
* ```typescript
|
|
264
|
+
* const input = `Translate "I love programming" into French.`;
|
|
265
|
+
*
|
|
266
|
+
* // Models also accept a list of chat messages or a formatted prompt
|
|
267
|
+
* const result = await llm.invoke(input);
|
|
268
|
+
* console.log(result);
|
|
269
|
+
* ```
|
|
270
|
+
*
|
|
271
|
+
* ```txt
|
|
272
|
+
* AIMessage {
|
|
273
|
+
* "content": "The translation of \"I love programming\" into French is \"J'aime la programmation\". Here's the breakdown:\n\n- \"I\" translates to \"Je\"\n- \"love\" translates to \"aime\"\n- \"programming\" translates to \"la programmation\"\n\nSo, \"J'aime la programmation\" means \"I love programming\" in French.",
|
|
274
|
+
* "additional_kwargs": {},
|
|
275
|
+
* "response_metadata": {
|
|
276
|
+
* "tokenUsage": {
|
|
277
|
+
* "completionTokens": 89,
|
|
278
|
+
* "promptTokens": 13,
|
|
279
|
+
* "totalTokens": 102
|
|
280
|
+
* },
|
|
281
|
+
* "finish_reason": "stop"
|
|
282
|
+
* },
|
|
283
|
+
* "tool_calls": [],
|
|
284
|
+
* "invalid_tool_calls": [],
|
|
285
|
+
* "usage_metadata": {
|
|
286
|
+
* "input_tokens": 13,
|
|
287
|
+
* "output_tokens": 89,
|
|
288
|
+
* "total_tokens": 102
|
|
289
|
+
* }
|
|
290
|
+
* }
|
|
291
|
+
* ```
|
|
292
|
+
* </details>
|
|
293
|
+
*
|
|
294
|
+
* <br />
|
|
295
|
+
*
|
|
296
|
+
* <details>
|
|
297
|
+
* <summary><strong>Streaming Chunks</strong></summary>
|
|
298
|
+
*
|
|
299
|
+
* ```typescript
|
|
300
|
+
* for await (const chunk of await llm.stream(input)) {
|
|
301
|
+
* console.log(chunk);
|
|
302
|
+
* }
|
|
303
|
+
* ```
|
|
304
|
+
*
|
|
305
|
+
* ```txt
|
|
306
|
+
* AIMessageChunk {
|
|
307
|
+
* "content": "The",
|
|
308
|
+
* "additional_kwargs": {},
|
|
309
|
+
* "response_metadata": {
|
|
310
|
+
* "prompt": 0,
|
|
311
|
+
* "completion": 0
|
|
312
|
+
* },
|
|
313
|
+
* "tool_calls": [],
|
|
314
|
+
* "tool_call_chunks": [],
|
|
315
|
+
* "invalid_tool_calls": []
|
|
316
|
+
* }
|
|
317
|
+
* AIMessageChunk {
|
|
318
|
+
* "content": " translation",
|
|
319
|
+
* "additional_kwargs": {},
|
|
320
|
+
* "response_metadata": {
|
|
321
|
+
* "prompt": 0,
|
|
322
|
+
* "completion": 0
|
|
323
|
+
* },
|
|
324
|
+
* "tool_calls": [],
|
|
325
|
+
* "tool_call_chunks": [],
|
|
326
|
+
* "invalid_tool_calls": []
|
|
327
|
+
* }
|
|
328
|
+
* AIMessageChunk {
|
|
329
|
+
* "content": " of",
|
|
330
|
+
* "additional_kwargs": {},
|
|
331
|
+
* "response_metadata": {
|
|
332
|
+
* "prompt": 0,
|
|
333
|
+
* "completion": 0
|
|
334
|
+
* },
|
|
335
|
+
* "tool_calls": [],
|
|
336
|
+
* "tool_call_chunks": [],
|
|
337
|
+
* "invalid_tool_calls": []
|
|
338
|
+
* }
|
|
339
|
+
* AIMessageChunk {
|
|
340
|
+
* "content": " \"",
|
|
341
|
+
* "additional_kwargs": {},
|
|
342
|
+
* "response_metadata": {
|
|
343
|
+
* "prompt": 0,
|
|
344
|
+
* "completion": 0
|
|
345
|
+
* },
|
|
346
|
+
* "tool_calls": [],
|
|
347
|
+
* "tool_call_chunks": [],
|
|
348
|
+
* "invalid_tool_calls": []
|
|
349
|
+
* }
|
|
350
|
+
* AIMessageChunk {
|
|
351
|
+
* "content": "I",
|
|
352
|
+
* "additional_kwargs": {},
|
|
353
|
+
* "response_metadata": {
|
|
354
|
+
* "prompt": 0,
|
|
355
|
+
* "completion": 0
|
|
356
|
+
* },
|
|
357
|
+
* "tool_calls": [],
|
|
358
|
+
* "tool_call_chunks": [],
|
|
359
|
+
* "invalid_tool_calls": []
|
|
360
|
+
* }
|
|
361
|
+
* AIMessageChunk {
|
|
362
|
+
* "content": ".",
|
|
363
|
+
* "additional_kwargs": {},
|
|
364
|
+
* "response_metadata": {
|
|
365
|
+
* "prompt": 0,
|
|
366
|
+
* "completion": 0
|
|
367
|
+
* },
|
|
368
|
+
* "tool_calls": [],
|
|
369
|
+
* "tool_call_chunks": [],
|
|
370
|
+
* "invalid_tool_calls": []
|
|
371
|
+
*}
|
|
372
|
+
*AIMessageChunk {
|
|
373
|
+
* "content": "",
|
|
374
|
+
* "additional_kwargs": {},
|
|
375
|
+
* "response_metadata": {
|
|
376
|
+
* "prompt": 0,
|
|
377
|
+
* "completion": 0
|
|
378
|
+
* },
|
|
379
|
+
* "tool_calls": [],
|
|
380
|
+
* "tool_call_chunks": [],
|
|
381
|
+
* "invalid_tool_calls": [],
|
|
382
|
+
* "usage_metadata": {
|
|
383
|
+
* "input_tokens": 13,
|
|
384
|
+
* "output_tokens": 89,
|
|
385
|
+
* "total_tokens": 102
|
|
386
|
+
* }
|
|
387
|
+
*}
|
|
388
|
+
* ```
|
|
389
|
+
* </details>
|
|
390
|
+
*
|
|
391
|
+
* <br />
|
|
392
|
+
*
|
|
393
|
+
* <details>
|
|
394
|
+
* <summary><strong>Aggregate Streamed Chunks</strong></summary>
|
|
395
|
+
*
|
|
396
|
+
* ```typescript
|
|
397
|
+
* import { AIMessageChunk } from '@langchain/core/messages';
|
|
398
|
+
* import { concat } from '@langchain/core/utils/stream';
|
|
399
|
+
*
|
|
400
|
+
* const stream = await llm.stream(input);
|
|
401
|
+
* let full: AIMessageChunk | undefined;
|
|
402
|
+
* for await (const chunk of stream) {
|
|
403
|
+
* full = !full ? chunk : concat(full, chunk);
|
|
404
|
+
* }
|
|
405
|
+
* console.log(full);
|
|
406
|
+
* ```
|
|
407
|
+
*
|
|
408
|
+
* ```txt
|
|
409
|
+
* AIMessageChunk {
|
|
410
|
+
* "content": "The translation of \"I love programming\" into French is \"J'aime la programmation\". Here's the breakdown:\n\n- \"I\" translates to \"Je\"\n- \"love\" translates to \"aime\"\n- \"programming\" translates to \"la programmation\"\n\nSo, \"J'aime la programmation\" means \"I love programming\" in French.",
|
|
411
|
+
* "additional_kwargs": {},
|
|
412
|
+
* "response_metadata": {
|
|
413
|
+
* "prompt": 0,
|
|
414
|
+
* "completion": 0
|
|
415
|
+
* },
|
|
416
|
+
* "tool_calls": [],
|
|
417
|
+
* "tool_call_chunks": [],
|
|
418
|
+
* "invalid_tool_calls": [],
|
|
419
|
+
* "usage_metadata": {
|
|
420
|
+
* "input_tokens": 13,
|
|
421
|
+
* "output_tokens": 89,
|
|
422
|
+
* "total_tokens": 102
|
|
423
|
+
* }
|
|
424
|
+
* }
|
|
425
|
+
* ```
|
|
426
|
+
* </details>
|
|
427
|
+
*
|
|
428
|
+
* <br />
|
|
429
|
+
*
|
|
430
|
+
* <details>
|
|
431
|
+
* <summary><strong>Bind tools</strong></summary>
|
|
432
|
+
*
|
|
433
|
+
* ```typescript
|
|
434
|
+
* import { z } from 'zod';
|
|
435
|
+
*
|
|
436
|
+
* const GetWeather = {
|
|
437
|
+
* name: "GetWeather",
|
|
438
|
+
* description: "Get the current weather in a given location",
|
|
439
|
+
* schema: z.object({
|
|
440
|
+
* location: z.string().describe("The city and state, e.g. San Francisco, CA")
|
|
441
|
+
* }),
|
|
442
|
+
* }
|
|
443
|
+
*
|
|
444
|
+
* const GetPopulation = {
|
|
445
|
+
* name: "GetPopulation",
|
|
446
|
+
* description: "Get the current population in a given location",
|
|
447
|
+
* schema: z.object({
|
|
448
|
+
* location: z.string().describe("The city and state, e.g. San Francisco, CA")
|
|
449
|
+
* }),
|
|
450
|
+
* }
|
|
451
|
+
*
|
|
452
|
+
* const llmWithTools = llm.bindTools([GetWeather, GetPopulation]);
|
|
453
|
+
* const aiMsg = await llmWithTools.invoke(
|
|
454
|
+
* "Which city is hotter today and which is bigger: LA or NY?"
|
|
455
|
+
* );
|
|
456
|
+
* console.log(aiMsg.tool_calls);
|
|
457
|
+
* ```
|
|
458
|
+
*
|
|
459
|
+
* ```txt
|
|
460
|
+
* [
|
|
461
|
+
* {
|
|
462
|
+
* name: 'GetWeather',
|
|
463
|
+
* args: { location: 'Los Angeles, CA' },
|
|
464
|
+
* type: 'tool_call',
|
|
465
|
+
* id: '47i216yko'
|
|
466
|
+
* },
|
|
467
|
+
* {
|
|
468
|
+
* name: 'GetWeather',
|
|
469
|
+
* args: { location: 'New York, NY' },
|
|
470
|
+
* type: 'tool_call',
|
|
471
|
+
* id: 'nb3v8Fpcn'
|
|
472
|
+
* },
|
|
473
|
+
* {
|
|
474
|
+
* name: 'GetPopulation',
|
|
475
|
+
* args: { location: 'Los Angeles, CA' },
|
|
476
|
+
* type: 'tool_call',
|
|
477
|
+
* id: 'EedWzByIB'
|
|
478
|
+
* },
|
|
479
|
+
* {
|
|
480
|
+
* name: 'GetPopulation',
|
|
481
|
+
* args: { location: 'New York, NY' },
|
|
482
|
+
* type: 'tool_call',
|
|
483
|
+
* id: 'jLdLia7zC'
|
|
484
|
+
* }
|
|
485
|
+
* ]
|
|
486
|
+
* ```
|
|
487
|
+
* </details>
|
|
488
|
+
*
|
|
489
|
+
* <br />
|
|
490
|
+
*
|
|
491
|
+
* <details>
|
|
492
|
+
* <summary><strong>Structured Output</strong></summary>
|
|
493
|
+
*
|
|
494
|
+
* ```typescript
|
|
495
|
+
* import { z } from 'zod';
|
|
496
|
+
*
|
|
497
|
+
* const Joke = z.object({
|
|
498
|
+
* setup: z.string().describe("The setup of the joke"),
|
|
499
|
+
* punchline: z.string().describe("The punchline to the joke"),
|
|
500
|
+
* rating: z.number().optional().describe("How funny the joke is, from 1 to 10")
|
|
501
|
+
* }).describe('Joke to tell user.');
|
|
502
|
+
*
|
|
503
|
+
* const structuredLlm = llm.withStructuredOutput(Joke, { name: "Joke" });
|
|
504
|
+
* const jokeResult = await structuredLlm.invoke("Tell me a joke about cats");
|
|
505
|
+
* console.log(jokeResult);
|
|
506
|
+
* ```
|
|
507
|
+
*
|
|
508
|
+
* ```txt
|
|
509
|
+
* {
|
|
510
|
+
* setup: "Why don't cats play poker in the jungle?",
|
|
511
|
+
* punchline: 'Too many cheetahs!',
|
|
512
|
+
* rating: 7
|
|
513
|
+
* }
|
|
514
|
+
* ```
|
|
515
|
+
* </details>
|
|
516
|
+
*
|
|
517
|
+
* <br />
|
|
518
|
+
*
|
|
519
|
+
* <details>
|
|
520
|
+
* <summary><strong>Usage Metadata</strong></summary>
|
|
521
|
+
*
|
|
522
|
+
* ```typescript
|
|
523
|
+
* const aiMsgForMetadata = await llm.invoke(input);
|
|
524
|
+
* console.log(aiMsgForMetadata.usage_metadata);
|
|
525
|
+
* ```
|
|
526
|
+
*
|
|
527
|
+
* ```txt
|
|
528
|
+
* { input_tokens: 13, output_tokens: 89, total_tokens: 102 }
|
|
529
|
+
* ```
|
|
530
|
+
* </details>
|
|
531
|
+
*
|
|
532
|
+
* <br />
|
|
533
|
+
*/
|
|
534
|
+
var ChatMistralAI = class extends BaseChatModel {
|
|
535
|
+
static lc_name() {
|
|
536
|
+
return "ChatMistralAI";
|
|
537
|
+
}
|
|
538
|
+
lc_namespace = [
|
|
539
|
+
"langchain",
|
|
540
|
+
"chat_models",
|
|
541
|
+
"mistralai"
|
|
542
|
+
];
|
|
543
|
+
model = "mistral-small-latest";
|
|
544
|
+
apiKey;
|
|
545
|
+
/**
|
|
546
|
+
* @deprecated use serverURL instead
|
|
547
|
+
*/
|
|
548
|
+
endpoint;
|
|
549
|
+
serverURL;
|
|
550
|
+
temperature = .7;
|
|
551
|
+
streaming = false;
|
|
552
|
+
topP = 1;
|
|
553
|
+
maxTokens;
|
|
554
|
+
/**
|
|
555
|
+
* @deprecated use safePrompt instead
|
|
556
|
+
*/
|
|
557
|
+
safeMode = false;
|
|
558
|
+
safePrompt = false;
|
|
559
|
+
randomSeed;
|
|
560
|
+
seed;
|
|
561
|
+
maxRetries;
|
|
562
|
+
lc_serializable = true;
|
|
563
|
+
streamUsage = true;
|
|
564
|
+
beforeRequestHooks;
|
|
565
|
+
requestErrorHooks;
|
|
566
|
+
responseHooks;
|
|
567
|
+
httpClient;
|
|
568
|
+
presencePenalty;
|
|
569
|
+
frequencyPenalty;
|
|
570
|
+
numCompletions;
|
|
571
|
+
constructor(fields) {
|
|
572
|
+
super(fields ?? {});
|
|
573
|
+
const apiKey = fields?.apiKey ?? getEnvironmentVariable("MISTRAL_API_KEY");
|
|
574
|
+
if (!apiKey) throw new Error("API key MISTRAL_API_KEY is missing for MistralAI, but it is required.");
|
|
575
|
+
this.apiKey = apiKey;
|
|
576
|
+
this.streaming = fields?.streaming ?? this.streaming;
|
|
577
|
+
this.serverURL = fields?.serverURL ?? this.serverURL;
|
|
578
|
+
this.temperature = fields?.temperature ?? this.temperature;
|
|
579
|
+
this.topP = fields?.topP ?? this.topP;
|
|
580
|
+
this.maxTokens = fields?.maxTokens ?? this.maxTokens;
|
|
581
|
+
this.safePrompt = fields?.safePrompt ?? this.safePrompt;
|
|
582
|
+
this.randomSeed = fields?.seed ?? fields?.randomSeed ?? this.seed;
|
|
583
|
+
this.seed = this.randomSeed;
|
|
584
|
+
this.maxRetries = fields?.maxRetries;
|
|
585
|
+
this.httpClient = fields?.httpClient;
|
|
586
|
+
this.model = fields?.model ?? fields?.modelName ?? this.model;
|
|
587
|
+
this.streamUsage = fields?.streamUsage ?? this.streamUsage;
|
|
588
|
+
this.beforeRequestHooks = fields?.beforeRequestHooks ?? this.beforeRequestHooks;
|
|
589
|
+
this.requestErrorHooks = fields?.requestErrorHooks ?? this.requestErrorHooks;
|
|
590
|
+
this.responseHooks = fields?.responseHooks ?? this.responseHooks;
|
|
591
|
+
this.presencePenalty = fields?.presencePenalty ?? this.presencePenalty;
|
|
592
|
+
this.frequencyPenalty = fields?.frequencyPenalty ?? this.frequencyPenalty;
|
|
593
|
+
this.numCompletions = fields?.numCompletions ?? this.numCompletions;
|
|
594
|
+
this.addAllHooksToHttpClient();
|
|
595
|
+
}
|
|
596
|
+
get lc_secrets() {
|
|
597
|
+
return { apiKey: "MISTRAL_API_KEY" };
|
|
598
|
+
}
|
|
599
|
+
get lc_aliases() {
|
|
600
|
+
return { apiKey: "mistral_api_key" };
|
|
601
|
+
}
|
|
602
|
+
getLsParams(options) {
|
|
603
|
+
const params = this.invocationParams(options);
|
|
604
|
+
return {
|
|
605
|
+
ls_provider: "mistral",
|
|
606
|
+
ls_model_name: this.model,
|
|
607
|
+
ls_model_type: "chat",
|
|
608
|
+
ls_temperature: params.temperature ?? void 0,
|
|
609
|
+
ls_max_tokens: params.maxTokens ?? void 0
|
|
610
|
+
};
|
|
611
|
+
}
|
|
612
|
+
_llmType() {
|
|
613
|
+
return "mistral_ai";
|
|
614
|
+
}
|
|
615
|
+
/**
|
|
616
|
+
* Get the parameters used to invoke the model
|
|
617
|
+
*/
|
|
618
|
+
invocationParams(options) {
|
|
619
|
+
const { response_format, tools, tool_choice } = options ?? {};
|
|
620
|
+
const mistralAITools = tools?.length ? _convertToolToMistralTool(tools) : void 0;
|
|
621
|
+
const params = {
|
|
622
|
+
model: this.model,
|
|
623
|
+
tools: mistralAITools,
|
|
624
|
+
temperature: this.temperature,
|
|
625
|
+
maxTokens: this.maxTokens,
|
|
626
|
+
topP: this.topP,
|
|
627
|
+
randomSeed: this.seed,
|
|
628
|
+
safePrompt: this.safePrompt,
|
|
629
|
+
toolChoice: tool_choice,
|
|
630
|
+
responseFormat: response_format,
|
|
631
|
+
presencePenalty: this.presencePenalty,
|
|
632
|
+
frequencyPenalty: this.frequencyPenalty,
|
|
633
|
+
n: this.numCompletions
|
|
634
|
+
};
|
|
635
|
+
return params;
|
|
636
|
+
}
|
|
637
|
+
bindTools(tools, kwargs) {
|
|
638
|
+
const mistralTools = _convertToolToMistralTool(tools);
|
|
639
|
+
return new RunnableBinding({
|
|
640
|
+
bound: this,
|
|
641
|
+
kwargs: {
|
|
642
|
+
...kwargs ?? {},
|
|
643
|
+
tools: mistralTools
|
|
644
|
+
},
|
|
645
|
+
config: {}
|
|
646
|
+
});
|
|
647
|
+
}
|
|
648
|
+
async completionWithRetry(input, streaming) {
|
|
649
|
+
const caller = new AsyncCaller({ maxRetries: this.maxRetries });
|
|
650
|
+
const client = new Mistral({
|
|
651
|
+
apiKey: this.apiKey,
|
|
652
|
+
serverURL: this.serverURL,
|
|
653
|
+
...this.httpClient ? { httpClient: this.httpClient } : {}
|
|
654
|
+
});
|
|
655
|
+
return caller.call(async () => {
|
|
656
|
+
try {
|
|
657
|
+
let res;
|
|
658
|
+
if (streaming) res = await client.chat.stream(input);
|
|
659
|
+
else res = await client.chat.complete(input);
|
|
660
|
+
return res;
|
|
661
|
+
} catch (e) {
|
|
662
|
+
if (e.message?.includes("status: 400") || e.message?.toLowerCase().includes("status 400") || e.message?.includes("validation failed")) e.status = 400;
|
|
663
|
+
throw e;
|
|
664
|
+
}
|
|
665
|
+
});
|
|
666
|
+
}
|
|
667
|
+
/** @ignore */
|
|
668
|
+
async _generate(messages, options, runManager) {
|
|
669
|
+
const tokenUsage = {};
|
|
670
|
+
const params = this.invocationParams(options);
|
|
671
|
+
const mistralMessages = convertMessagesToMistralMessages(messages);
|
|
672
|
+
const input = {
|
|
673
|
+
...params,
|
|
674
|
+
messages: mistralMessages
|
|
675
|
+
};
|
|
676
|
+
const shouldStream = options.signal ?? !!options.timeout;
|
|
677
|
+
if (this.streaming || shouldStream) {
|
|
678
|
+
const stream = this._streamResponseChunks(messages, options, runManager);
|
|
679
|
+
const finalChunks = {};
|
|
680
|
+
for await (const chunk of stream) {
|
|
681
|
+
const index = chunk.generationInfo?.completion ?? 0;
|
|
682
|
+
if (finalChunks[index] === void 0) finalChunks[index] = chunk;
|
|
683
|
+
else finalChunks[index] = finalChunks[index].concat(chunk);
|
|
684
|
+
}
|
|
685
|
+
const generations$1 = Object.entries(finalChunks).sort(([aKey], [bKey]) => parseInt(aKey, 10) - parseInt(bKey, 10)).map(([_, value]) => value);
|
|
686
|
+
return {
|
|
687
|
+
generations: generations$1,
|
|
688
|
+
llmOutput: { estimatedTokenUsage: tokenUsage }
|
|
689
|
+
};
|
|
690
|
+
}
|
|
691
|
+
const response = await this.completionWithRetry(input, false);
|
|
692
|
+
const { completionTokens, promptTokens, totalTokens } = response?.usage ?? {};
|
|
693
|
+
if (completionTokens) tokenUsage.completionTokens = (tokenUsage.completionTokens ?? 0) + completionTokens;
|
|
694
|
+
if (promptTokens) tokenUsage.promptTokens = (tokenUsage.promptTokens ?? 0) + promptTokens;
|
|
695
|
+
if (totalTokens) tokenUsage.totalTokens = (tokenUsage.totalTokens ?? 0) + totalTokens;
|
|
696
|
+
const generations = [];
|
|
697
|
+
for (const part of response?.choices ?? []) {
|
|
698
|
+
if ("delta" in part) throw new Error("Delta not supported in non-streaming mode.");
|
|
699
|
+
if (!("message" in part)) throw new Error("No message found in the choice.");
|
|
700
|
+
let text = part.message?.content ?? "";
|
|
701
|
+
if (Array.isArray(text)) text = text[0].type === "text" ? text[0].text : "";
|
|
702
|
+
const generation = {
|
|
703
|
+
text,
|
|
704
|
+
message: mistralAIResponseToChatMessage(part, response?.usage)
|
|
705
|
+
};
|
|
706
|
+
if (part.finishReason) generation.generationInfo = { finishReason: part.finishReason };
|
|
707
|
+
generations.push(generation);
|
|
708
|
+
}
|
|
709
|
+
return {
|
|
710
|
+
generations,
|
|
711
|
+
llmOutput: { tokenUsage }
|
|
712
|
+
};
|
|
713
|
+
}
|
|
714
|
+
async *_streamResponseChunks(messages, options, runManager) {
|
|
715
|
+
const mistralMessages = convertMessagesToMistralMessages(messages);
|
|
716
|
+
const params = this.invocationParams(options);
|
|
717
|
+
const input = {
|
|
718
|
+
...params,
|
|
719
|
+
messages: mistralMessages
|
|
720
|
+
};
|
|
721
|
+
const streamIterable = await this.completionWithRetry(input, true);
|
|
722
|
+
for await (const { data } of streamIterable) {
|
|
723
|
+
if (options.signal?.aborted) throw new Error("AbortError");
|
|
724
|
+
const choice = data?.choices[0];
|
|
725
|
+
if (!choice || !("delta" in choice)) continue;
|
|
726
|
+
const { delta } = choice;
|
|
727
|
+
if (!delta) continue;
|
|
728
|
+
const newTokenIndices = {
|
|
729
|
+
prompt: 0,
|
|
730
|
+
completion: choice.index ?? 0
|
|
731
|
+
};
|
|
732
|
+
const shouldStreamUsage = this.streamUsage || options.streamUsage;
|
|
733
|
+
const message = _convertDeltaToMessageChunk(delta, shouldStreamUsage ? data.usage : null);
|
|
734
|
+
if (message === null) continue;
|
|
735
|
+
let text = delta.content ?? "";
|
|
736
|
+
if (Array.isArray(text)) text = text[0].type === "text" ? text[0].text : "";
|
|
737
|
+
const generationChunk = new ChatGenerationChunk({
|
|
738
|
+
message,
|
|
739
|
+
text,
|
|
740
|
+
generationInfo: newTokenIndices
|
|
741
|
+
});
|
|
742
|
+
yield generationChunk;
|
|
743
|
+
runManager?.handleLLMNewToken(generationChunk.text ?? "", newTokenIndices, void 0, void 0, void 0, { chunk: generationChunk });
|
|
744
|
+
}
|
|
745
|
+
}
|
|
746
|
+
addAllHooksToHttpClient() {
|
|
747
|
+
try {
|
|
748
|
+
this.removeAllHooksFromHttpClient();
|
|
749
|
+
const hasHooks = [
|
|
750
|
+
this.beforeRequestHooks,
|
|
751
|
+
this.requestErrorHooks,
|
|
752
|
+
this.responseHooks
|
|
753
|
+
].some((hook) => hook && hook.length > 0);
|
|
754
|
+
if (hasHooks && !this.httpClient) this.httpClient = new HTTPClient();
|
|
755
|
+
if (this.beforeRequestHooks) for (const hook of this.beforeRequestHooks) this.httpClient?.addHook("beforeRequest", hook);
|
|
756
|
+
if (this.requestErrorHooks) for (const hook of this.requestErrorHooks) this.httpClient?.addHook("requestError", hook);
|
|
757
|
+
if (this.responseHooks) for (const hook of this.responseHooks) this.httpClient?.addHook("response", hook);
|
|
758
|
+
} catch {
|
|
759
|
+
throw new Error("Error in adding all hooks");
|
|
760
|
+
}
|
|
761
|
+
}
|
|
762
|
+
removeAllHooksFromHttpClient() {
|
|
763
|
+
try {
|
|
764
|
+
if (this.beforeRequestHooks) for (const hook of this.beforeRequestHooks) this.httpClient?.removeHook("beforeRequest", hook);
|
|
765
|
+
if (this.requestErrorHooks) for (const hook of this.requestErrorHooks) this.httpClient?.removeHook("requestError", hook);
|
|
766
|
+
if (this.responseHooks) for (const hook of this.responseHooks) this.httpClient?.removeHook("response", hook);
|
|
767
|
+
} catch {
|
|
768
|
+
throw new Error("Error in removing hooks");
|
|
769
|
+
}
|
|
770
|
+
}
|
|
771
|
+
removeHookFromHttpClient(hook) {
|
|
772
|
+
try {
|
|
773
|
+
this.httpClient?.removeHook("beforeRequest", hook);
|
|
774
|
+
this.httpClient?.removeHook("requestError", hook);
|
|
775
|
+
this.httpClient?.removeHook("response", hook);
|
|
776
|
+
} catch {
|
|
777
|
+
throw new Error("Error in removing hook");
|
|
778
|
+
}
|
|
779
|
+
}
|
|
780
|
+
/** @ignore */
|
|
781
|
+
_combineLLMOutput() {
|
|
782
|
+
return [];
|
|
783
|
+
}
|
|
784
|
+
withStructuredOutput(outputSchema, config) {
|
|
785
|
+
const schema = outputSchema;
|
|
786
|
+
const name = config?.name;
|
|
787
|
+
const method = config?.method;
|
|
788
|
+
const includeRaw = config?.includeRaw;
|
|
789
|
+
let llm;
|
|
790
|
+
let outputParser;
|
|
791
|
+
if (method === "jsonMode") {
|
|
792
|
+
let outputSchema$1;
|
|
793
|
+
if (isInteropZodSchema(schema)) {
|
|
794
|
+
outputParser = StructuredOutputParser.fromZodSchema(schema);
|
|
795
|
+
outputSchema$1 = toJsonSchema(schema);
|
|
796
|
+
} else outputParser = new JsonOutputParser();
|
|
797
|
+
llm = this.withConfig({
|
|
798
|
+
response_format: { type: "json_object" },
|
|
799
|
+
ls_structured_output_format: {
|
|
800
|
+
kwargs: { method: "jsonMode" },
|
|
801
|
+
schema: outputSchema$1
|
|
802
|
+
}
|
|
803
|
+
});
|
|
804
|
+
} else {
|
|
805
|
+
let functionName = name ?? "extract";
|
|
806
|
+
if (isInteropZodSchema(schema)) {
|
|
807
|
+
const asJsonSchema = toJsonSchema(schema);
|
|
808
|
+
llm = this.bindTools([{
|
|
809
|
+
type: "function",
|
|
810
|
+
function: {
|
|
811
|
+
name: functionName,
|
|
812
|
+
description: asJsonSchema.description,
|
|
813
|
+
parameters: asJsonSchema
|
|
814
|
+
}
|
|
815
|
+
}]).withConfig({
|
|
816
|
+
tool_choice: "any",
|
|
817
|
+
ls_structured_output_format: {
|
|
818
|
+
kwargs: { method: "functionCalling" },
|
|
819
|
+
schema: asJsonSchema
|
|
820
|
+
}
|
|
821
|
+
});
|
|
822
|
+
outputParser = new JsonOutputKeyToolsParser({
|
|
823
|
+
returnSingle: true,
|
|
824
|
+
keyName: functionName,
|
|
825
|
+
zodSchema: schema
|
|
826
|
+
});
|
|
827
|
+
} else {
|
|
828
|
+
let openAIFunctionDefinition;
|
|
829
|
+
if (typeof schema.name === "string" && typeof schema.parameters === "object" && schema.parameters != null) {
|
|
830
|
+
openAIFunctionDefinition = schema;
|
|
831
|
+
functionName = schema.name;
|
|
832
|
+
} else openAIFunctionDefinition = {
|
|
833
|
+
name: functionName,
|
|
834
|
+
description: schema.description ?? "",
|
|
835
|
+
parameters: schema
|
|
836
|
+
};
|
|
837
|
+
llm = this.bindTools([{
|
|
838
|
+
type: "function",
|
|
839
|
+
function: openAIFunctionDefinition
|
|
840
|
+
}]).withConfig({ tool_choice: "any" });
|
|
841
|
+
outputParser = new JsonOutputKeyToolsParser({
|
|
842
|
+
returnSingle: true,
|
|
843
|
+
keyName: functionName
|
|
844
|
+
});
|
|
845
|
+
}
|
|
846
|
+
}
|
|
847
|
+
if (!includeRaw) return llm.pipe(outputParser);
|
|
848
|
+
const parserAssign = RunnablePassthrough.assign({ parsed: (input, config$1) => outputParser.invoke(input.raw, config$1) });
|
|
849
|
+
const parserNone = RunnablePassthrough.assign({ parsed: () => null });
|
|
850
|
+
const parsedWithFallback = parserAssign.withFallbacks({ fallbacks: [parserNone] });
|
|
851
|
+
return RunnableSequence.from([{ raw: llm }, parsedWithFallback]);
|
|
852
|
+
}
|
|
853
|
+
};
|
|
854
|
+
|
|
855
|
+
//#endregion
|
|
856
|
+
export { ChatMistralAI, convertMessagesToMistralMessages };
|
|
857
|
+
//# sourceMappingURL=chat_models.js.map
|