@langchain/core 0.3.75 β 0.3.76
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/README.md +3 -19
- package/dist/embeddings.d.ts +6 -6
- package/dist/messages/base.cjs +20 -4
- package/dist/messages/base.d.ts +1 -1
- package/dist/messages/base.js +20 -4
- package/dist/messages/transformers.cjs +1 -1
- package/dist/messages/transformers.js +1 -1
- package/dist/messages/utils.cjs +4 -0
- package/dist/messages/utils.js +4 -0
- package/dist/output_parsers/structured.cjs +8 -3
- package/dist/output_parsers/structured.js +8 -3
- package/dist/prompts/chat.cjs +15 -9
- package/dist/prompts/chat.js +15 -9
- package/dist/prompts/template.cjs +4 -2
- package/dist/prompts/template.js +4 -2
- package/dist/runnables/graph_mermaid.cjs +27 -3
- package/dist/runnables/graph_mermaid.d.ts +25 -1
- package/dist/runnables/graph_mermaid.js +26 -3
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
# π¦ποΈ @langchain/core
|
|
2
2
|
|
|
3
|
-
|
|
3
|
+
 [](https://opensource.org/licenses/MIT) [](https://twitter.com/langchainai)
|
|
4
4
|
|
|
5
5
|
`@langchain/core` contains the core abstractions and schemas of LangChain.js, including base classes for language models,
|
|
6
6
|
chat models, vectorstores, retrievers, and runnables.
|
|
@@ -8,7 +8,7 @@ chat models, vectorstores, retrievers, and runnables.
|
|
|
8
8
|
## πΎ Quick Install
|
|
9
9
|
|
|
10
10
|
```bash
|
|
11
|
-
|
|
11
|
+
yarn add @langchain/core
|
|
12
12
|
```
|
|
13
13
|
|
|
14
14
|
## π€ What is this?
|
|
@@ -21,7 +21,7 @@ The benefit of having these abstractions is that any provider can implement the
|
|
|
21
21
|
For example, you can install other provider-specific packages like this:
|
|
22
22
|
|
|
23
23
|
```bash
|
|
24
|
-
|
|
24
|
+
yarn add @langchain/openai
|
|
25
25
|
```
|
|
26
26
|
|
|
27
27
|
And use them as follows:
|
|
@@ -72,22 +72,6 @@ leigh
|
|
|
72
72
|
Note that for compatibility, all used LangChain packages (including the base LangChain package, which itself depends on core!) must share the same version of `@langchain/core`.
|
|
73
73
|
This means that you may need to install/resolve a specific version of `@langchain/core` that matches the dependencies of your used packages.
|
|
74
74
|
|
|
75
|
-
## π What is LangChain Expression Language?
|
|
76
|
-
|
|
77
|
-
LangChain Core also contains LangChain Expression Language, or LCEL, a runtime that allows users to compose arbitrary sequences together and get several benefits that are important when building LLM applications.
|
|
78
|
-
We call these sequences βrunnablesβ.
|
|
79
|
-
|
|
80
|
-
All runnables expose the same interface with single-invocation, batch, streaming and async methods.
|
|
81
|
-
This design is useful because it is not enough to have a single sync interface when building an LLM application.
|
|
82
|
-
Batch is needed for efficient processing of many inputs.
|
|
83
|
-
Streaming (and streaming of intermediate steps) is needed to show the user that progress is being made.
|
|
84
|
-
Async interfaces are nice when moving into production.
|
|
85
|
-
Rather than having to write multiple implementations for all of those, LCEL allows you to write a runnable once and invoke it in many different ways.
|
|
86
|
-
|
|
87
|
-
For more check out the [LCEL docs](https://js.langchain.com/docs/concepts/lcel).
|
|
88
|
-
|
|
89
|
-

|
|
90
|
-
|
|
91
75
|
## π Releases & Versioning
|
|
92
76
|
|
|
93
77
|
`@langchain/core` is currently on version `0.3.x`.
|
package/dist/embeddings.d.ts
CHANGED
|
@@ -4,7 +4,7 @@ import { AsyncCaller, AsyncCallerParams } from "./utils/async_caller.js";
|
|
|
4
4
|
* class.
|
|
5
5
|
*/
|
|
6
6
|
export type EmbeddingsParams = AsyncCallerParams;
|
|
7
|
-
export interface EmbeddingsInterface {
|
|
7
|
+
export interface EmbeddingsInterface<TOutput = number[]> {
|
|
8
8
|
/**
|
|
9
9
|
* An abstract method that takes an array of documents as input and
|
|
10
10
|
* returns a promise that resolves to an array of vectors for each
|
|
@@ -12,20 +12,20 @@ export interface EmbeddingsInterface {
|
|
|
12
12
|
* @param documents An array of documents to be embedded.
|
|
13
13
|
* @returns A promise that resolves to an array of vectors for each document.
|
|
14
14
|
*/
|
|
15
|
-
embedDocuments(documents: string[]): Promise<
|
|
15
|
+
embedDocuments(documents: string[]): Promise<TOutput[]>;
|
|
16
16
|
/**
|
|
17
17
|
* An abstract method that takes a single document as input and returns a
|
|
18
18
|
* promise that resolves to a vector for the query document.
|
|
19
19
|
* @param document A single document to be embedded.
|
|
20
20
|
* @returns A promise that resolves to a vector for the query document.
|
|
21
21
|
*/
|
|
22
|
-
embedQuery(document: string): Promise<
|
|
22
|
+
embedQuery(document: string): Promise<TOutput>;
|
|
23
23
|
}
|
|
24
24
|
/**
|
|
25
25
|
* An abstract class that provides methods for embedding documents and
|
|
26
26
|
* queries using LangChain.
|
|
27
27
|
*/
|
|
28
|
-
export declare abstract class Embeddings implements EmbeddingsInterface {
|
|
28
|
+
export declare abstract class Embeddings<TOutput = number[]> implements EmbeddingsInterface<TOutput> {
|
|
29
29
|
/**
|
|
30
30
|
* The async caller should be used by subclasses to make any async calls,
|
|
31
31
|
* which will thus benefit from the concurrency and retry logic.
|
|
@@ -39,12 +39,12 @@ export declare abstract class Embeddings implements EmbeddingsInterface {
|
|
|
39
39
|
* @param documents An array of documents to be embedded.
|
|
40
40
|
* @returns A promise that resolves to an array of vectors for each document.
|
|
41
41
|
*/
|
|
42
|
-
abstract embedDocuments(documents: string[]): Promise<
|
|
42
|
+
abstract embedDocuments(documents: string[]): Promise<TOutput[]>;
|
|
43
43
|
/**
|
|
44
44
|
* An abstract method that takes a single document as input and returns a
|
|
45
45
|
* promise that resolves to a vector for the query document.
|
|
46
46
|
* @param document A single document to be embedded.
|
|
47
47
|
* @returns A promise that resolves to a vector for the query document.
|
|
48
48
|
*/
|
|
49
|
-
abstract embedQuery(document: string): Promise<
|
|
49
|
+
abstract embedQuery(document: string): Promise<TOutput>;
|
|
50
50
|
}
|
package/dist/messages/base.cjs
CHANGED
|
@@ -285,7 +285,13 @@ right
|
|
|
285
285
|
// Do not merge 'type' fields
|
|
286
286
|
continue;
|
|
287
287
|
}
|
|
288
|
-
|
|
288
|
+
else if (["id", "output_version", "model_provider"].includes(key)) {
|
|
289
|
+
// Keep the incoming value for these fields
|
|
290
|
+
merged[key] = value;
|
|
291
|
+
}
|
|
292
|
+
else {
|
|
293
|
+
merged[key] += value;
|
|
294
|
+
}
|
|
289
295
|
}
|
|
290
296
|
else if (typeof merged[key] === "object" && !Array.isArray(merged[key])) {
|
|
291
297
|
merged[key] = _mergeDicts(merged[key], value);
|
|
@@ -302,7 +308,6 @@ right
|
|
|
302
308
|
}
|
|
303
309
|
return merged;
|
|
304
310
|
}
|
|
305
|
-
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
306
311
|
function _mergeLists(left, right) {
|
|
307
312
|
if (left === undefined && right === undefined) {
|
|
308
313
|
return undefined;
|
|
@@ -314,10 +319,20 @@ function _mergeLists(left, right) {
|
|
|
314
319
|
const merged = [...left];
|
|
315
320
|
for (const item of right) {
|
|
316
321
|
if (typeof item === "object" &&
|
|
322
|
+
item !== null &&
|
|
317
323
|
"index" in item &&
|
|
318
324
|
typeof item.index === "number") {
|
|
319
|
-
const toMerge = merged.findIndex((leftItem) => leftItem
|
|
320
|
-
|
|
325
|
+
const toMerge = merged.findIndex((leftItem) => leftItem !== null &&
|
|
326
|
+
typeof leftItem === "object" &&
|
|
327
|
+
"index" in leftItem &&
|
|
328
|
+
leftItem.index === item.index &&
|
|
329
|
+
// Only merge if IDs match (or both are undefined)
|
|
330
|
+
("id" in leftItem && "id" in item
|
|
331
|
+
? leftItem.id === item.id
|
|
332
|
+
: !("id" in leftItem) && !("id" in item)));
|
|
333
|
+
if (toMerge !== -1 &&
|
|
334
|
+
typeof merged[toMerge] === "object" &&
|
|
335
|
+
merged[toMerge] !== null) {
|
|
321
336
|
merged[toMerge] = _mergeDicts(merged[toMerge], item);
|
|
322
337
|
}
|
|
323
338
|
else {
|
|
@@ -325,6 +340,7 @@ function _mergeLists(left, right) {
|
|
|
325
340
|
}
|
|
326
341
|
}
|
|
327
342
|
else if (typeof item === "object" &&
|
|
343
|
+
item !== null &&
|
|
328
344
|
"text" in item &&
|
|
329
345
|
item.text === "") {
|
|
330
346
|
// No-op - skip empty text blocks
|
package/dist/messages/base.d.ts
CHANGED
|
@@ -156,7 +156,7 @@ export type OpenAIToolCall = {
|
|
|
156
156
|
};
|
|
157
157
|
export declare function isOpenAIToolCallArray(value?: unknown): value is OpenAIToolCall[];
|
|
158
158
|
export declare function _mergeDicts(left: Record<string, any>, right: Record<string, any>): Record<string, any>;
|
|
159
|
-
export declare function _mergeLists(left?:
|
|
159
|
+
export declare function _mergeLists<Content extends MessageContentComplex>(left?: Content[], right?: Content[]): Content[] | undefined;
|
|
160
160
|
export declare function _mergeObj<T = any>(left: T | undefined, right: T | undefined): T;
|
|
161
161
|
/**
|
|
162
162
|
* Represents a chunk of a message, which can be concatenated with other
|
package/dist/messages/base.js
CHANGED
|
@@ -272,7 +272,13 @@ right
|
|
|
272
272
|
// Do not merge 'type' fields
|
|
273
273
|
continue;
|
|
274
274
|
}
|
|
275
|
-
|
|
275
|
+
else if (["id", "output_version", "model_provider"].includes(key)) {
|
|
276
|
+
// Keep the incoming value for these fields
|
|
277
|
+
merged[key] = value;
|
|
278
|
+
}
|
|
279
|
+
else {
|
|
280
|
+
merged[key] += value;
|
|
281
|
+
}
|
|
276
282
|
}
|
|
277
283
|
else if (typeof merged[key] === "object" && !Array.isArray(merged[key])) {
|
|
278
284
|
merged[key] = _mergeDicts(merged[key], value);
|
|
@@ -289,7 +295,6 @@ right
|
|
|
289
295
|
}
|
|
290
296
|
return merged;
|
|
291
297
|
}
|
|
292
|
-
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
293
298
|
export function _mergeLists(left, right) {
|
|
294
299
|
if (left === undefined && right === undefined) {
|
|
295
300
|
return undefined;
|
|
@@ -301,10 +306,20 @@ export function _mergeLists(left, right) {
|
|
|
301
306
|
const merged = [...left];
|
|
302
307
|
for (const item of right) {
|
|
303
308
|
if (typeof item === "object" &&
|
|
309
|
+
item !== null &&
|
|
304
310
|
"index" in item &&
|
|
305
311
|
typeof item.index === "number") {
|
|
306
|
-
const toMerge = merged.findIndex((leftItem) => leftItem
|
|
307
|
-
|
|
312
|
+
const toMerge = merged.findIndex((leftItem) => leftItem !== null &&
|
|
313
|
+
typeof leftItem === "object" &&
|
|
314
|
+
"index" in leftItem &&
|
|
315
|
+
leftItem.index === item.index &&
|
|
316
|
+
// Only merge if IDs match (or both are undefined)
|
|
317
|
+
("id" in leftItem && "id" in item
|
|
318
|
+
? leftItem.id === item.id
|
|
319
|
+
: !("id" in leftItem) && !("id" in item)));
|
|
320
|
+
if (toMerge !== -1 &&
|
|
321
|
+
typeof merged[toMerge] === "object" &&
|
|
322
|
+
merged[toMerge] !== null) {
|
|
308
323
|
merged[toMerge] = _mergeDicts(merged[toMerge], item);
|
|
309
324
|
}
|
|
310
325
|
else {
|
|
@@ -312,6 +327,7 @@ export function _mergeLists(left, right) {
|
|
|
312
327
|
}
|
|
313
328
|
}
|
|
314
329
|
else if (typeof item === "object" &&
|
|
330
|
+
item !== null &&
|
|
315
331
|
"text" in item &&
|
|
316
332
|
item.text === "") {
|
|
317
333
|
// No-op - skip empty text blocks
|
|
@@ -182,7 +182,7 @@ async function _firstMaxTokens(messages, options) {
|
|
|
182
182
|
break;
|
|
183
183
|
}
|
|
184
184
|
}
|
|
185
|
-
if (idx < messagesCopy.length
|
|
185
|
+
if (idx < messagesCopy.length && partialStrategy) {
|
|
186
186
|
let includedPartial = false;
|
|
187
187
|
if (Array.isArray(messagesCopy[idx].content)) {
|
|
188
188
|
const excluded = messagesCopy[idx];
|
|
@@ -176,7 +176,7 @@ async function _firstMaxTokens(messages, options) {
|
|
|
176
176
|
break;
|
|
177
177
|
}
|
|
178
178
|
}
|
|
179
|
-
if (idx < messagesCopy.length
|
|
179
|
+
if (idx < messagesCopy.length && partialStrategy) {
|
|
180
180
|
let includedPartial = false;
|
|
181
181
|
if (Array.isArray(messagesCopy[idx].content)) {
|
|
182
182
|
const excluded = messagesCopy[idx];
|
package/dist/messages/utils.cjs
CHANGED
|
@@ -13,6 +13,7 @@ const base_js_1 = require("./base.cjs");
|
|
|
13
13
|
const chat_js_1 = require("./chat.cjs");
|
|
14
14
|
const function_js_1 = require("./function.cjs");
|
|
15
15
|
const human_js_1 = require("./human.cjs");
|
|
16
|
+
const modifier_js_1 = require("./modifier.cjs");
|
|
16
17
|
const system_js_1 = require("./system.cjs");
|
|
17
18
|
const tool_js_1 = require("./tool.cjs");
|
|
18
19
|
function _coerceToolCall(toolCall) {
|
|
@@ -113,6 +114,9 @@ function _constructMessageFromParams(params) {
|
|
|
113
114
|
name: rest.name,
|
|
114
115
|
});
|
|
115
116
|
}
|
|
117
|
+
else if (type === "remove" && "id" in rest && typeof rest.id === "string") {
|
|
118
|
+
return new modifier_js_1.RemoveMessage({ ...rest, id: rest.id });
|
|
119
|
+
}
|
|
116
120
|
else {
|
|
117
121
|
const error = (0, index_js_1.addLangChainErrorFields)(new Error(`Unable to coerce message from array: only human, AI, system, developer, or tool message coercion is currently supported.\n\nReceived: ${JSON.stringify(params, null, 2)}`), "MESSAGE_COERCION_FAILURE");
|
|
118
122
|
throw error;
|
package/dist/messages/utils.js
CHANGED
|
@@ -5,6 +5,7 @@ import { isBaseMessage, _isMessageFieldWithRole, } from "./base.js";
|
|
|
5
5
|
import { ChatMessage, ChatMessageChunk, } from "./chat.js";
|
|
6
6
|
import { FunctionMessage, FunctionMessageChunk, } from "./function.js";
|
|
7
7
|
import { HumanMessage, HumanMessageChunk } from "./human.js";
|
|
8
|
+
import { RemoveMessage } from "./modifier.js";
|
|
8
9
|
import { SystemMessage, SystemMessageChunk } from "./system.js";
|
|
9
10
|
import { ToolMessage, } from "./tool.js";
|
|
10
11
|
function _coerceToolCall(toolCall) {
|
|
@@ -105,6 +106,9 @@ function _constructMessageFromParams(params) {
|
|
|
105
106
|
name: rest.name,
|
|
106
107
|
});
|
|
107
108
|
}
|
|
109
|
+
else if (type === "remove" && "id" in rest && typeof rest.id === "string") {
|
|
110
|
+
return new RemoveMessage({ ...rest, id: rest.id });
|
|
111
|
+
}
|
|
108
112
|
else {
|
|
109
113
|
const error = addLangChainErrorFields(new Error(`Unable to coerce message from array: only human, AI, system, developer, or tool message coercion is currently supported.\n\nReceived: ${JSON.stringify(params, null, 2)}`), "MESSAGE_COERCION_FAILURE");
|
|
110
114
|
throw error;
|
|
@@ -75,9 +75,14 @@ ${JSON.stringify((0, json_schema_js_1.toJsonSchema)(this.schema))}
|
|
|
75
75
|
*/
|
|
76
76
|
async parse(text) {
|
|
77
77
|
try {
|
|
78
|
-
const
|
|
79
|
-
|
|
80
|
-
|
|
78
|
+
const trimmedText = text.trim();
|
|
79
|
+
const json =
|
|
80
|
+
// first case: if back ticks appear at the start of the text
|
|
81
|
+
trimmedText.match(/^```(?:json)?\s*([\s\S]*?)```/)?.[1] ||
|
|
82
|
+
// second case: if back ticks with `json` appear anywhere in the text
|
|
83
|
+
trimmedText.match(/```json\s*([\s\S]*?)```/)?.[1] ||
|
|
84
|
+
// otherwise, return the trimmed text
|
|
85
|
+
trimmedText;
|
|
81
86
|
const escapedJson = json
|
|
82
87
|
.replace(/"([^"\\]*(\\.[^"\\]*)*)"/g, (_match, capturedGroup) => {
|
|
83
88
|
const escapedInsideQuotes = capturedGroup.replace(/\n/g, "\\n");
|
|
@@ -72,9 +72,14 @@ ${JSON.stringify(toJsonSchema(this.schema))}
|
|
|
72
72
|
*/
|
|
73
73
|
async parse(text) {
|
|
74
74
|
try {
|
|
75
|
-
const
|
|
76
|
-
|
|
77
|
-
|
|
75
|
+
const trimmedText = text.trim();
|
|
76
|
+
const json =
|
|
77
|
+
// first case: if back ticks appear at the start of the text
|
|
78
|
+
trimmedText.match(/^```(?:json)?\s*([\s\S]*?)```/)?.[1] ||
|
|
79
|
+
// second case: if back ticks with `json` appear anywhere in the text
|
|
80
|
+
trimmedText.match(/```json\s*([\s\S]*?)```/)?.[1] ||
|
|
81
|
+
// otherwise, return the trimmed text
|
|
82
|
+
trimmedText;
|
|
78
83
|
const escapedJson = json
|
|
79
84
|
.replace(/"([^"\\]*(\\.[^"\\]*)*)"/g, (_match, capturedGroup) => {
|
|
80
85
|
const escapedInsideQuotes = capturedGroup.replace(/\n/g, "\\n");
|
package/dist/prompts/chat.cjs
CHANGED
|
@@ -723,15 +723,21 @@ class ChatPromptTemplate extends BaseChatPromptTemplate {
|
|
|
723
723
|
resultMessages.push(await this._parseImagePrompts(promptMessage, allValues));
|
|
724
724
|
}
|
|
725
725
|
else {
|
|
726
|
-
|
|
727
|
-
|
|
728
|
-
|
|
729
|
-
|
|
730
|
-
|
|
731
|
-
|
|
732
|
-
|
|
733
|
-
|
|
734
|
-
|
|
726
|
+
let inputValues;
|
|
727
|
+
if (this.templateFormat === "mustache") {
|
|
728
|
+
inputValues = { ...allValues };
|
|
729
|
+
}
|
|
730
|
+
else {
|
|
731
|
+
inputValues = promptMessage.inputVariables.reduce((acc, inputVariable) => {
|
|
732
|
+
if (!(inputVariable in allValues) &&
|
|
733
|
+
!(isMessagesPlaceholder(promptMessage) && promptMessage.optional)) {
|
|
734
|
+
const error = (0, index_js_2.addLangChainErrorFields)(new Error(`Missing value for input variable \`${inputVariable.toString()}\``), "INVALID_PROMPT_INPUT");
|
|
735
|
+
throw error;
|
|
736
|
+
}
|
|
737
|
+
acc[inputVariable] = allValues[inputVariable];
|
|
738
|
+
return acc;
|
|
739
|
+
}, {});
|
|
740
|
+
}
|
|
735
741
|
const message = await promptMessage.formatMessages(inputValues);
|
|
736
742
|
resultMessages = resultMessages.concat(message);
|
|
737
743
|
}
|
package/dist/prompts/chat.js
CHANGED
|
@@ -712,15 +712,21 @@ export class ChatPromptTemplate extends BaseChatPromptTemplate {
|
|
|
712
712
|
resultMessages.push(await this._parseImagePrompts(promptMessage, allValues));
|
|
713
713
|
}
|
|
714
714
|
else {
|
|
715
|
-
|
|
716
|
-
|
|
717
|
-
|
|
718
|
-
|
|
719
|
-
|
|
720
|
-
|
|
721
|
-
|
|
722
|
-
|
|
723
|
-
|
|
715
|
+
let inputValues;
|
|
716
|
+
if (this.templateFormat === "mustache") {
|
|
717
|
+
inputValues = { ...allValues };
|
|
718
|
+
}
|
|
719
|
+
else {
|
|
720
|
+
inputValues = promptMessage.inputVariables.reduce((acc, inputVariable) => {
|
|
721
|
+
if (!(inputVariable in allValues) &&
|
|
722
|
+
!(isMessagesPlaceholder(promptMessage) && promptMessage.optional)) {
|
|
723
|
+
const error = addLangChainErrorFields(new Error(`Missing value for input variable \`${inputVariable.toString()}\``), "INVALID_PROMPT_INPUT");
|
|
724
|
+
throw error;
|
|
725
|
+
}
|
|
726
|
+
acc[inputVariable] = allValues[inputVariable];
|
|
727
|
+
return acc;
|
|
728
|
+
}, {});
|
|
729
|
+
}
|
|
724
730
|
const message = await promptMessage.formatMessages(inputValues);
|
|
725
731
|
resultMessages = resultMessages.concat(message);
|
|
726
732
|
}
|
|
@@ -65,9 +65,10 @@ exports.parseFString = parseFString;
|
|
|
65
65
|
* to make it compatible with other LangChain string parsing template formats.
|
|
66
66
|
*
|
|
67
67
|
* @param {mustache.TemplateSpans} template The result of parsing a mustache template with the mustache.js library.
|
|
68
|
+
* @param {string[]} context Array of section variable names for nested context
|
|
68
69
|
* @returns {ParsedTemplateNode[]}
|
|
69
70
|
*/
|
|
70
|
-
const mustacheTemplateToNodes = (template) => {
|
|
71
|
+
const mustacheTemplateToNodes = (template, context = []) => {
|
|
71
72
|
const nodes = [];
|
|
72
73
|
for (const temp of template) {
|
|
73
74
|
if (temp[0] === "name") {
|
|
@@ -80,7 +81,8 @@ const mustacheTemplateToNodes = (template) => {
|
|
|
80
81
|
nodes.push({ type: "variable", name: temp[1] });
|
|
81
82
|
// If this is a section with nested content, recursively process it
|
|
82
83
|
if (temp[0] === "#" && temp.length > 4 && Array.isArray(temp[4])) {
|
|
83
|
-
const
|
|
84
|
+
const newContext = [...context, temp[1]];
|
|
85
|
+
const nestedNodes = mustacheTemplateToNodes(temp[4], newContext);
|
|
84
86
|
nodes.push(...nestedNodes);
|
|
85
87
|
}
|
|
86
88
|
}
|
package/dist/prompts/template.js
CHANGED
|
@@ -58,9 +58,10 @@ export const parseFString = (template) => {
|
|
|
58
58
|
* to make it compatible with other LangChain string parsing template formats.
|
|
59
59
|
*
|
|
60
60
|
* @param {mustache.TemplateSpans} template The result of parsing a mustache template with the mustache.js library.
|
|
61
|
+
* @param {string[]} context Array of section variable names for nested context
|
|
61
62
|
* @returns {ParsedTemplateNode[]}
|
|
62
63
|
*/
|
|
63
|
-
const mustacheTemplateToNodes = (template) => {
|
|
64
|
+
const mustacheTemplateToNodes = (template, context = []) => {
|
|
64
65
|
const nodes = [];
|
|
65
66
|
for (const temp of template) {
|
|
66
67
|
if (temp[0] === "name") {
|
|
@@ -73,7 +74,8 @@ const mustacheTemplateToNodes = (template) => {
|
|
|
73
74
|
nodes.push({ type: "variable", name: temp[1] });
|
|
74
75
|
// If this is a section with nested content, recursively process it
|
|
75
76
|
if (temp[0] === "#" && temp.length > 4 && Array.isArray(temp[4])) {
|
|
76
|
-
const
|
|
77
|
+
const newContext = [...context, temp[1]];
|
|
78
|
+
const nestedNodes = mustacheTemplateToNodes(temp[4], newContext);
|
|
77
79
|
nodes.push(...nestedNodes);
|
|
78
80
|
}
|
|
79
81
|
}
|
|
@@ -2,6 +2,7 @@
|
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
3
|
exports.drawMermaid = drawMermaid;
|
|
4
4
|
exports.drawMermaidPng = drawMermaidPng;
|
|
5
|
+
exports.drawMermaidImage = drawMermaidImage;
|
|
5
6
|
function _escapeNodeLabel(nodeLabel) {
|
|
6
7
|
// Escapes the node label for Mermaid syntax.
|
|
7
8
|
return nodeLabel.replace(/[^a-zA-Z-_0-9]/g, "_");
|
|
@@ -124,10 +125,33 @@ function drawMermaid(nodes, edges, config) {
|
|
|
124
125
|
return mermaidGraph;
|
|
125
126
|
}
|
|
126
127
|
/**
|
|
127
|
-
*
|
|
128
|
+
* @deprecated Use `drawMermaidImage` instead.
|
|
128
129
|
*/
|
|
129
130
|
async function drawMermaidPng(mermaidSyntax, config) {
|
|
130
|
-
|
|
131
|
+
return drawMermaidImage(mermaidSyntax, {
|
|
132
|
+
...config,
|
|
133
|
+
imageType: "png",
|
|
134
|
+
});
|
|
135
|
+
}
|
|
136
|
+
/**
|
|
137
|
+
* Renders Mermaid graph using the Mermaid.INK API.
|
|
138
|
+
*
|
|
139
|
+
* @example
|
|
140
|
+
* ```javascript
|
|
141
|
+
* const image = await drawMermaidImage(mermaidSyntax, {
|
|
142
|
+
* backgroundColor: "white",
|
|
143
|
+
* imageType: "png",
|
|
144
|
+
* });
|
|
145
|
+
* fs.writeFileSync("image.png", image);
|
|
146
|
+
* ```
|
|
147
|
+
*
|
|
148
|
+
* @param mermaidSyntax - The Mermaid syntax to render.
|
|
149
|
+
* @param config - The configuration for the image.
|
|
150
|
+
* @returns The image as a Blob.
|
|
151
|
+
*/
|
|
152
|
+
async function drawMermaidImage(mermaidSyntax, config) {
|
|
153
|
+
let backgroundColor = config?.backgroundColor ?? "white";
|
|
154
|
+
const imageType = config?.imageType ?? "png";
|
|
131
155
|
// Use btoa for compatibility, assume ASCII
|
|
132
156
|
const mermaidSyntaxEncoded = btoa(mermaidSyntax);
|
|
133
157
|
// Check if the background color is a hexadecimal color code using regex
|
|
@@ -137,7 +161,7 @@ async function drawMermaidPng(mermaidSyntax, config) {
|
|
|
137
161
|
backgroundColor = `!${backgroundColor}`;
|
|
138
162
|
}
|
|
139
163
|
}
|
|
140
|
-
const imageUrl = `https://mermaid.ink/img/${mermaidSyntaxEncoded}?bgColor=${backgroundColor}`;
|
|
164
|
+
const imageUrl = `https://mermaid.ink/img/${mermaidSyntaxEncoded}?bgColor=${backgroundColor}&type=${imageType}`;
|
|
141
165
|
const res = await fetch(imageUrl);
|
|
142
166
|
if (!res.ok) {
|
|
143
167
|
throw new Error([
|
|
@@ -11,8 +11,32 @@ export declare function drawMermaid(nodes: Record<string, Node>, edges: Edge[],
|
|
|
11
11
|
wrapLabelNWords?: number;
|
|
12
12
|
}): string;
|
|
13
13
|
/**
|
|
14
|
-
*
|
|
14
|
+
* @deprecated Use `drawMermaidImage` instead.
|
|
15
15
|
*/
|
|
16
16
|
export declare function drawMermaidPng(mermaidSyntax: string, config?: {
|
|
17
17
|
backgroundColor?: string;
|
|
18
18
|
}): Promise<Blob>;
|
|
19
|
+
/**
|
|
20
|
+
* Renders Mermaid graph using the Mermaid.INK API.
|
|
21
|
+
*
|
|
22
|
+
* @example
|
|
23
|
+
* ```javascript
|
|
24
|
+
* const image = await drawMermaidImage(mermaidSyntax, {
|
|
25
|
+
* backgroundColor: "white",
|
|
26
|
+
* imageType: "png",
|
|
27
|
+
* });
|
|
28
|
+
* fs.writeFileSync("image.png", image);
|
|
29
|
+
* ```
|
|
30
|
+
*
|
|
31
|
+
* @param mermaidSyntax - The Mermaid syntax to render.
|
|
32
|
+
* @param config - The configuration for the image.
|
|
33
|
+
* @returns The image as a Blob.
|
|
34
|
+
*/
|
|
35
|
+
export declare function drawMermaidImage(mermaidSyntax: string, config?: {
|
|
36
|
+
/**
|
|
37
|
+
* The type of image to render.
|
|
38
|
+
* @default "png"
|
|
39
|
+
*/
|
|
40
|
+
imageType?: "png" | "jpeg" | "webp";
|
|
41
|
+
backgroundColor?: string;
|
|
42
|
+
}): Promise<Blob>;
|
|
@@ -120,10 +120,33 @@ export function drawMermaid(nodes, edges, config) {
|
|
|
120
120
|
return mermaidGraph;
|
|
121
121
|
}
|
|
122
122
|
/**
|
|
123
|
-
*
|
|
123
|
+
* @deprecated Use `drawMermaidImage` instead.
|
|
124
124
|
*/
|
|
125
125
|
export async function drawMermaidPng(mermaidSyntax, config) {
|
|
126
|
-
|
|
126
|
+
return drawMermaidImage(mermaidSyntax, {
|
|
127
|
+
...config,
|
|
128
|
+
imageType: "png",
|
|
129
|
+
});
|
|
130
|
+
}
|
|
131
|
+
/**
|
|
132
|
+
* Renders Mermaid graph using the Mermaid.INK API.
|
|
133
|
+
*
|
|
134
|
+
* @example
|
|
135
|
+
* ```javascript
|
|
136
|
+
* const image = await drawMermaidImage(mermaidSyntax, {
|
|
137
|
+
* backgroundColor: "white",
|
|
138
|
+
* imageType: "png",
|
|
139
|
+
* });
|
|
140
|
+
* fs.writeFileSync("image.png", image);
|
|
141
|
+
* ```
|
|
142
|
+
*
|
|
143
|
+
* @param mermaidSyntax - The Mermaid syntax to render.
|
|
144
|
+
* @param config - The configuration for the image.
|
|
145
|
+
* @returns The image as a Blob.
|
|
146
|
+
*/
|
|
147
|
+
export async function drawMermaidImage(mermaidSyntax, config) {
|
|
148
|
+
let backgroundColor = config?.backgroundColor ?? "white";
|
|
149
|
+
const imageType = config?.imageType ?? "png";
|
|
127
150
|
// Use btoa for compatibility, assume ASCII
|
|
128
151
|
const mermaidSyntaxEncoded = btoa(mermaidSyntax);
|
|
129
152
|
// Check if the background color is a hexadecimal color code using regex
|
|
@@ -133,7 +156,7 @@ export async function drawMermaidPng(mermaidSyntax, config) {
|
|
|
133
156
|
backgroundColor = `!${backgroundColor}`;
|
|
134
157
|
}
|
|
135
158
|
}
|
|
136
|
-
const imageUrl = `https://mermaid.ink/img/${mermaidSyntaxEncoded}?bgColor=${backgroundColor}`;
|
|
159
|
+
const imageUrl = `https://mermaid.ink/img/${mermaidSyntaxEncoded}?bgColor=${backgroundColor}&type=${imageType}`;
|
|
137
160
|
const res = await fetch(imageUrl);
|
|
138
161
|
if (!res.ok) {
|
|
139
162
|
throw new Error([
|