@langchain/core 0.3.46 → 0.3.48

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.
@@ -27,6 +27,33 @@ function createChatMessageChunkEncoderStream() {
27
27
  });
28
28
  }
29
29
  exports.createChatMessageChunkEncoderStream = createChatMessageChunkEncoderStream;
30
+ function _formatForTracing(messages) {
31
+ const messagesToTrace = [];
32
+ for (const message of messages) {
33
+ let messageToTrace = message;
34
+ if (Array.isArray(message.content)) {
35
+ for (let idx = 0; idx < message.content.length; idx++) {
36
+ const block = message.content[idx];
37
+ if ((0, index_js_1.isURLContentBlock)(block) || (0, index_js_1.isBase64ContentBlock)(block)) {
38
+ if (messageToTrace === message) {
39
+ // Also shallow-copy content
40
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
41
+ messageToTrace = new message.constructor({
42
+ ...messageToTrace,
43
+ content: [
44
+ ...message.content.slice(0, idx),
45
+ (0, index_js_1.convertToOpenAIImageBlock)(block),
46
+ ...message.content.slice(idx + 1),
47
+ ],
48
+ });
49
+ }
50
+ }
51
+ }
52
+ }
53
+ messagesToTrace.push(messageToTrace);
54
+ }
55
+ return messagesToTrace;
56
+ }
30
57
  /**
31
58
  * Base class for chat models. It extends the BaseLanguageModel class and
32
59
  * provides methods for generating chat based on input messages.
@@ -92,7 +119,7 @@ class BaseChatModel extends base_js_1.BaseLanguageModel {
92
119
  invocation_params: this?.invocationParams(callOptions),
93
120
  batch_size: 1,
94
121
  };
95
- const runManagers = await callbackManager_?.handleChatModelStart(this.toJSON(), [messages], runnableConfig.runId, undefined, extra, undefined, undefined, runnableConfig.runName);
122
+ const runManagers = await callbackManager_?.handleChatModelStart(this.toJSON(), [_formatForTracing(messages)], runnableConfig.runId, undefined, extra, undefined, undefined, runnableConfig.runName);
96
123
  let generationChunk;
97
124
  // eslint-disable-next-line @typescript-eslint/no-explicit-any
98
125
  let llmOutput;
@@ -167,7 +194,7 @@ class BaseChatModel extends base_js_1.BaseLanguageModel {
167
194
  invocation_params: this?.invocationParams(parsedOptions),
168
195
  batch_size: 1,
169
196
  };
170
- runManagers = await callbackManager_?.handleChatModelStart(this.toJSON(), baseMessages, handledOptions.runId, undefined, extra, undefined, undefined, handledOptions.runName);
197
+ runManagers = await callbackManager_?.handleChatModelStart(this.toJSON(), baseMessages.map(_formatForTracing), handledOptions.runId, undefined, extra, undefined, undefined, handledOptions.runName);
171
198
  }
172
199
  const generations = [];
173
200
  const llmOutputs = [];
@@ -288,7 +315,7 @@ class BaseChatModel extends base_js_1.BaseLanguageModel {
288
315
  invocation_params: this?.invocationParams(parsedOptions),
289
316
  batch_size: 1,
290
317
  };
291
- const runManagers = await callbackManager_?.handleChatModelStart(this.toJSON(), baseMessages, handledOptions.runId, undefined, extra, undefined, undefined, handledOptions.runName);
318
+ const runManagers = await callbackManager_?.handleChatModelStart(this.toJSON(), baseMessages.map(_formatForTracing), handledOptions.runId, undefined, extra, undefined, undefined, handledOptions.runName);
292
319
  // generate results
293
320
  const missingPromptIndices = [];
294
321
  const results = await Promise.allSettled(baseMessages.map(async (baseMessage, index) => {
@@ -1,5 +1,5 @@
1
1
  import { zodToJsonSchema } from "zod-to-json-schema";
2
- import { AIMessage, HumanMessage, coerceMessageLikeToMessage, isAIMessageChunk, isBaseMessage, isAIMessage, } from "../messages/index.js";
2
+ import { AIMessage, HumanMessage, coerceMessageLikeToMessage, isAIMessageChunk, isBaseMessage, isAIMessage, convertToOpenAIImageBlock, isURLContentBlock, isBase64ContentBlock, } from "../messages/index.js";
3
3
  import { RUN_KEY, } from "../outputs.js";
4
4
  import { BaseLanguageModel, } from "./base.js";
5
5
  import { CallbackManager, } from "../callbacks/manager.js";
@@ -23,6 +23,33 @@ export function createChatMessageChunkEncoderStream() {
23
23
  },
24
24
  });
25
25
  }
26
+ function _formatForTracing(messages) {
27
+ const messagesToTrace = [];
28
+ for (const message of messages) {
29
+ let messageToTrace = message;
30
+ if (Array.isArray(message.content)) {
31
+ for (let idx = 0; idx < message.content.length; idx++) {
32
+ const block = message.content[idx];
33
+ if (isURLContentBlock(block) || isBase64ContentBlock(block)) {
34
+ if (messageToTrace === message) {
35
+ // Also shallow-copy content
36
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
37
+ messageToTrace = new message.constructor({
38
+ ...messageToTrace,
39
+ content: [
40
+ ...message.content.slice(0, idx),
41
+ convertToOpenAIImageBlock(block),
42
+ ...message.content.slice(idx + 1),
43
+ ],
44
+ });
45
+ }
46
+ }
47
+ }
48
+ }
49
+ messagesToTrace.push(messageToTrace);
50
+ }
51
+ return messagesToTrace;
52
+ }
26
53
  /**
27
54
  * Base class for chat models. It extends the BaseLanguageModel class and
28
55
  * provides methods for generating chat based on input messages.
@@ -88,7 +115,7 @@ export class BaseChatModel extends BaseLanguageModel {
88
115
  invocation_params: this?.invocationParams(callOptions),
89
116
  batch_size: 1,
90
117
  };
91
- const runManagers = await callbackManager_?.handleChatModelStart(this.toJSON(), [messages], runnableConfig.runId, undefined, extra, undefined, undefined, runnableConfig.runName);
118
+ const runManagers = await callbackManager_?.handleChatModelStart(this.toJSON(), [_formatForTracing(messages)], runnableConfig.runId, undefined, extra, undefined, undefined, runnableConfig.runName);
92
119
  let generationChunk;
93
120
  // eslint-disable-next-line @typescript-eslint/no-explicit-any
94
121
  let llmOutput;
@@ -163,7 +190,7 @@ export class BaseChatModel extends BaseLanguageModel {
163
190
  invocation_params: this?.invocationParams(parsedOptions),
164
191
  batch_size: 1,
165
192
  };
166
- runManagers = await callbackManager_?.handleChatModelStart(this.toJSON(), baseMessages, handledOptions.runId, undefined, extra, undefined, undefined, handledOptions.runName);
193
+ runManagers = await callbackManager_?.handleChatModelStart(this.toJSON(), baseMessages.map(_formatForTracing), handledOptions.runId, undefined, extra, undefined, undefined, handledOptions.runName);
167
194
  }
168
195
  const generations = [];
169
196
  const llmOutputs = [];
@@ -284,7 +311,7 @@ export class BaseChatModel extends BaseLanguageModel {
284
311
  invocation_params: this?.invocationParams(parsedOptions),
285
312
  batch_size: 1,
286
313
  };
287
- const runManagers = await callbackManager_?.handleChatModelStart(this.toJSON(), baseMessages, handledOptions.runId, undefined, extra, undefined, undefined, handledOptions.runName);
314
+ const runManagers = await callbackManager_?.handleChatModelStart(this.toJSON(), baseMessages.map(_formatForTracing), handledOptions.runId, undefined, extra, undefined, undefined, handledOptions.runName);
288
315
  // generate results
289
316
  const missingPromptIndices = [];
290
317
  const results = await Promise.allSettled(baseMessages.map(async (baseMessage, index) => {
@@ -2,6 +2,7 @@
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
3
  exports.isBaseMessageChunk = exports.isBaseMessage = exports._isMessageFieldWithRole = exports.BaseMessageChunk = exports._mergeObj = exports._mergeLists = exports._mergeDicts = exports.isOpenAIToolCallArray = exports.BaseMessage = exports._mergeStatus = exports.mergeContent = void 0;
4
4
  const serializable_js_1 = require("../load/serializable.cjs");
5
+ const content_blocks_js_1 = require("./content_blocks.cjs");
5
6
  function mergeContent(firstContent, secondContent) {
6
7
  // If first content is a string
7
8
  if (typeof firstContent === "string") {
@@ -11,6 +12,17 @@ function mergeContent(firstContent, secondContent) {
11
12
  if (typeof secondContent === "string") {
12
13
  return firstContent + secondContent;
13
14
  }
15
+ else if (Array.isArray(secondContent) &&
16
+ secondContent.some((c) => (0, content_blocks_js_1.isDataContentBlock)(c))) {
17
+ return [
18
+ {
19
+ type: "text",
20
+ source_type: "text",
21
+ text: firstContent,
22
+ },
23
+ ...secondContent,
24
+ ];
25
+ }
14
26
  else {
15
27
  return [{ type: "text", text: firstContent }, ...secondContent];
16
28
  }
@@ -26,8 +38,20 @@ function mergeContent(firstContent, secondContent) {
26
38
  if (secondContent === "") {
27
39
  return firstContent;
28
40
  }
29
- // Otherwise, add the second content as a new element of the list
30
- return [...firstContent, { type: "text", text: secondContent }];
41
+ else if (Array.isArray(firstContent) &&
42
+ firstContent.some((c) => (0, content_blocks_js_1.isDataContentBlock)(c))) {
43
+ return [
44
+ ...firstContent,
45
+ {
46
+ type: "file",
47
+ source_type: "text",
48
+ text: secondContent,
49
+ },
50
+ ];
51
+ }
52
+ else {
53
+ return [...firstContent, { type: "text", text: secondContent }];
54
+ }
31
55
  }
32
56
  }
33
57
  exports.mergeContent = mergeContent;
@@ -1,4 +1,5 @@
1
1
  import { Serializable } from "../load/serializable.js";
2
+ import { isDataContentBlock, } from "./content_blocks.js";
2
3
  export function mergeContent(firstContent, secondContent) {
3
4
  // If first content is a string
4
5
  if (typeof firstContent === "string") {
@@ -8,6 +9,17 @@ export function mergeContent(firstContent, secondContent) {
8
9
  if (typeof secondContent === "string") {
9
10
  return firstContent + secondContent;
10
11
  }
12
+ else if (Array.isArray(secondContent) &&
13
+ secondContent.some((c) => isDataContentBlock(c))) {
14
+ return [
15
+ {
16
+ type: "text",
17
+ source_type: "text",
18
+ text: firstContent,
19
+ },
20
+ ...secondContent,
21
+ ];
22
+ }
11
23
  else {
12
24
  return [{ type: "text", text: firstContent }, ...secondContent];
13
25
  }
@@ -23,8 +35,20 @@ export function mergeContent(firstContent, secondContent) {
23
35
  if (secondContent === "") {
24
36
  return firstContent;
25
37
  }
26
- // Otherwise, add the second content as a new element of the list
27
- return [...firstContent, { type: "text", text: secondContent }];
38
+ else if (Array.isArray(firstContent) &&
39
+ firstContent.some((c) => isDataContentBlock(c))) {
40
+ return [
41
+ ...firstContent,
42
+ {
43
+ type: "file",
44
+ source_type: "text",
45
+ text: secondContent,
46
+ },
47
+ ];
48
+ }
49
+ else {
50
+ return [...firstContent, { type: "text", text: secondContent }];
51
+ }
28
52
  }
29
53
  }
30
54
  /**
@@ -0,0 +1,166 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.convertToProviderContentBlock = exports.parseBase64DataUrl = exports.parseMimeType = exports.convertToOpenAIImageBlock = exports.isIDContentBlock = exports.isPlainTextContentBlock = exports.isBase64ContentBlock = exports.isURLContentBlock = exports.isDataContentBlock = void 0;
4
+ function isDataContentBlock(content_block) {
5
+ return (typeof content_block === "object" &&
6
+ content_block !== null &&
7
+ "type" in content_block &&
8
+ typeof content_block.type === "string" &&
9
+ "source_type" in content_block &&
10
+ (content_block.source_type === "url" ||
11
+ content_block.source_type === "base64" ||
12
+ content_block.source_type === "text" ||
13
+ content_block.source_type === "id"));
14
+ }
15
+ exports.isDataContentBlock = isDataContentBlock;
16
+ function isURLContentBlock(content_block) {
17
+ return (isDataContentBlock(content_block) &&
18
+ content_block.source_type === "url" &&
19
+ "url" in content_block &&
20
+ typeof content_block.url === "string");
21
+ }
22
+ exports.isURLContentBlock = isURLContentBlock;
23
+ function isBase64ContentBlock(content_block) {
24
+ return (isDataContentBlock(content_block) &&
25
+ content_block.source_type === "base64" &&
26
+ "data" in content_block &&
27
+ typeof content_block.data === "string");
28
+ }
29
+ exports.isBase64ContentBlock = isBase64ContentBlock;
30
+ function isPlainTextContentBlock(content_block) {
31
+ return (isDataContentBlock(content_block) &&
32
+ content_block.source_type === "text" &&
33
+ "text" in content_block &&
34
+ typeof content_block.text === "string");
35
+ }
36
+ exports.isPlainTextContentBlock = isPlainTextContentBlock;
37
+ function isIDContentBlock(content_block) {
38
+ return (isDataContentBlock(content_block) &&
39
+ content_block.source_type === "id" &&
40
+ "id" in content_block &&
41
+ typeof content_block.id === "string");
42
+ }
43
+ exports.isIDContentBlock = isIDContentBlock;
44
+ function convertToOpenAIImageBlock(content_block) {
45
+ if (isDataContentBlock(content_block)) {
46
+ if (content_block.source_type === "url") {
47
+ return {
48
+ type: "image_url",
49
+ image_url: {
50
+ url: content_block.url,
51
+ },
52
+ };
53
+ }
54
+ if (content_block.source_type === "base64") {
55
+ if (!content_block.mime_type) {
56
+ throw new Error("mime_type key is required for base64 data.");
57
+ }
58
+ const mime_type = content_block.mime_type;
59
+ return {
60
+ type: "image_url",
61
+ image_url: {
62
+ url: `data:${mime_type};base64,${content_block.data}`,
63
+ },
64
+ };
65
+ }
66
+ }
67
+ throw new Error("Unsupported source type. Only 'url' and 'base64' are supported.");
68
+ }
69
+ exports.convertToOpenAIImageBlock = convertToOpenAIImageBlock;
70
+ /**
71
+ * Utility function for ChatModelProviders. Parses a mime type into a type, subtype, and parameters.
72
+ *
73
+ * @param mime_type - The mime type to parse.
74
+ * @returns An object containing the type, subtype, and parameters.
75
+ */
76
+ function parseMimeType(mime_type) {
77
+ const parts = mime_type.split(";")[0].split("/");
78
+ if (parts.length !== 2) {
79
+ throw new Error(`Invalid mime type: "${mime_type}" - does not match type/subtype format.`);
80
+ }
81
+ const type = parts[0].trim();
82
+ const subtype = parts[1].trim();
83
+ if (type === "" || subtype === "") {
84
+ throw new Error(`Invalid mime type: "${mime_type}" - type or subtype is empty.`);
85
+ }
86
+ const parameters = {};
87
+ for (const parameterKvp of mime_type.split(";").slice(1)) {
88
+ const parameterParts = parameterKvp.split("=");
89
+ if (parameterParts.length !== 2) {
90
+ throw new Error(`Invalid parameter syntax in mime type: "${mime_type}".`);
91
+ }
92
+ const key = parameterParts[0].trim();
93
+ const value = parameterParts[1].trim();
94
+ if (key === "") {
95
+ throw new Error(`Invalid parameter syntax in mime type: "${mime_type}".`);
96
+ }
97
+ parameters[key] = value;
98
+ }
99
+ return {
100
+ type,
101
+ subtype,
102
+ parameters,
103
+ };
104
+ }
105
+ exports.parseMimeType = parseMimeType;
106
+ /**
107
+ * Utility function for ChatModelProviders. Parses a base64 data URL into a typed array or string.
108
+ *
109
+ * @param dataUrl - The base64 data URL to parse.
110
+ * @param asTypedArray - Whether to return the data as a typed array.
111
+ * @returns The parsed data and mime type, or undefined if the data URL is invalid.
112
+ */
113
+ function parseBase64DataUrl({ dataUrl: data_url, asTypedArray = false, }) {
114
+ const formatMatch = data_url.match(/^data:(\w+\/\w+);base64,([A-Za-z0-9+/]+=*)$/);
115
+ let mime_type;
116
+ if (formatMatch) {
117
+ mime_type = formatMatch[1].toLowerCase();
118
+ const data = asTypedArray
119
+ ? Uint8Array.from(atob(formatMatch[2]), (c) => c.charCodeAt(0))
120
+ : formatMatch[2];
121
+ return {
122
+ mime_type,
123
+ data,
124
+ };
125
+ }
126
+ return undefined;
127
+ }
128
+ exports.parseBase64DataUrl = parseBase64DataUrl;
129
+ /**
130
+ * Convert from a standard data content block to a provider's proprietary data content block format.
131
+ *
132
+ * Don't override this method. Instead, override the more specific conversion methods and use this
133
+ * method unmodified.
134
+ *
135
+ * @param block - The standard data content block to convert.
136
+ * @returns The provider data content block.
137
+ * @throws An error if the standard data content block type is not supported.
138
+ */
139
+ function convertToProviderContentBlock(block, converter) {
140
+ if (block.type === "text") {
141
+ if (!converter.fromStandardTextBlock) {
142
+ throw new Error(`Converter for ${converter.providerName} does not implement \`fromStandardTextBlock\` method.`);
143
+ }
144
+ return converter.fromStandardTextBlock(block);
145
+ }
146
+ if (block.type === "image") {
147
+ if (!converter.fromStandardImageBlock) {
148
+ throw new Error(`Converter for ${converter.providerName} does not implement \`fromStandardImageBlock\` method.`);
149
+ }
150
+ return converter.fromStandardImageBlock(block);
151
+ }
152
+ if (block.type === "audio") {
153
+ if (!converter.fromStandardAudioBlock) {
154
+ throw new Error(`Converter for ${converter.providerName} does not implement \`fromStandardAudioBlock\` method.`);
155
+ }
156
+ return converter.fromStandardAudioBlock(block);
157
+ }
158
+ if (block.type === "file") {
159
+ if (!converter.fromStandardFileBlock) {
160
+ throw new Error(`Converter for ${converter.providerName} does not implement \`fromStandardFileBlock\` method.`);
161
+ }
162
+ return converter.fromStandardFileBlock(block);
163
+ }
164
+ throw new Error(`Unable to convert content block type '${block.type}' to provider-specific format: not recognized.`);
165
+ }
166
+ exports.convertToProviderContentBlock = convertToProviderContentBlock;
@@ -0,0 +1,151 @@
1
+ export interface BaseDataContentBlock {
2
+ mime_type?: string;
3
+ metadata?: Record<string, unknown>;
4
+ }
5
+ export interface URLContentBlock extends BaseDataContentBlock {
6
+ type: "image" | "audio" | "file";
7
+ source_type: "url";
8
+ url: string;
9
+ }
10
+ export interface Base64ContentBlock extends BaseDataContentBlock {
11
+ type: "image" | "audio" | "file";
12
+ source_type: "base64";
13
+ data: string;
14
+ }
15
+ export interface PlainTextContentBlock extends BaseDataContentBlock {
16
+ type: "file" | "text";
17
+ source_type: "text";
18
+ text: string;
19
+ }
20
+ export interface IDContentBlock extends BaseDataContentBlock {
21
+ type: "image" | "audio" | "file";
22
+ source_type: "id";
23
+ id: string;
24
+ }
25
+ export type DataContentBlock = URLContentBlock | Base64ContentBlock | PlainTextContentBlock | IDContentBlock;
26
+ export type StandardImageBlock = (URLContentBlock | Base64ContentBlock | IDContentBlock) & {
27
+ type: "image";
28
+ };
29
+ export type StandardAudioBlock = (URLContentBlock | Base64ContentBlock | IDContentBlock) & {
30
+ type: "audio";
31
+ };
32
+ export type StandardFileBlock = (URLContentBlock | Base64ContentBlock | IDContentBlock | PlainTextContentBlock) & {
33
+ type: "file";
34
+ };
35
+ export type StandardTextBlock = PlainTextContentBlock & {
36
+ type: "text";
37
+ };
38
+ export type DataContentBlockType = DataContentBlock["type"];
39
+ export declare function isDataContentBlock(content_block: object): content_block is DataContentBlock;
40
+ export declare function isURLContentBlock(content_block: object): content_block is URLContentBlock;
41
+ export declare function isBase64ContentBlock(content_block: object): content_block is Base64ContentBlock;
42
+ export declare function isPlainTextContentBlock(content_block: object): content_block is PlainTextContentBlock;
43
+ export declare function isIDContentBlock(content_block: object): content_block is IDContentBlock;
44
+ export declare function convertToOpenAIImageBlock(content_block: URLContentBlock | Base64ContentBlock): {
45
+ type: string;
46
+ image_url: {
47
+ url: string;
48
+ };
49
+ };
50
+ /**
51
+ * Utility function for ChatModelProviders. Parses a mime type into a type, subtype, and parameters.
52
+ *
53
+ * @param mime_type - The mime type to parse.
54
+ * @returns An object containing the type, subtype, and parameters.
55
+ */
56
+ export declare function parseMimeType(mime_type: string): {
57
+ type: string;
58
+ subtype: string;
59
+ parameters: Record<string, string>;
60
+ };
61
+ /**
62
+ * Utility function for ChatModelProviders. Parses a base64 data URL into a typed array or string.
63
+ *
64
+ * @param dataUrl - The base64 data URL to parse.
65
+ * @param asTypedArray - Whether to return the data as a typed array.
66
+ * @returns An object containing the parsed data and mime type, or undefined if the data URL is invalid.
67
+ */
68
+ export declare function parseBase64DataUrl({ dataUrl, asTypedArray, }: {
69
+ dataUrl: string;
70
+ asTypedArray: true;
71
+ }): {
72
+ data: Uint8Array;
73
+ mime_type: string;
74
+ } | undefined;
75
+ /**
76
+ * Utility function for ChatModelProviders. Parses a base64 data URL into a typed array or string.
77
+ *
78
+ * @param dataUrl - The base64 data URL to parse.
79
+ * @param asTypedArray - Whether to return the data as a typed array.
80
+ * @returns The parsed data and mime type, or undefined if the data URL is invalid.
81
+ */
82
+ export declare function parseBase64DataUrl({ dataUrl, asTypedArray, }: {
83
+ dataUrl: string;
84
+ asTypedArray?: false;
85
+ }): {
86
+ data: string;
87
+ mime_type: string;
88
+ } | undefined;
89
+ /**
90
+ * A bag of provider-specific content block types.
91
+ *
92
+ * Allows implementations of {@link StandardContentBlockConverter} and related to be defined only in
93
+ * terms of the types they support. Also allows for forward compatibility as the set of known
94
+ * standard types grows, as the set of types can be extended without breaking existing
95
+ * implementations of the aforementioned interfaces.
96
+ */
97
+ export type ProviderFormatTypes<TextFormat = unknown, ImageFormat = unknown, AudioFormat = unknown, FileFormat = unknown> = {
98
+ text: TextFormat;
99
+ image: ImageFormat;
100
+ audio: AudioFormat;
101
+ file: FileFormat;
102
+ };
103
+ /**
104
+ * Utility interface for converting between standard and provider-specific data content blocks, to be
105
+ * used when implementing chat model providers.
106
+ *
107
+ * Meant to be used with {@link convertToProviderContentBlock} and
108
+ * {@link convertToStandardContentBlock} rather than being consumed directly.
109
+ */
110
+ export interface StandardContentBlockConverter<Formats extends Partial<ProviderFormatTypes>> {
111
+ /**
112
+ * The name of the provider type that corresponds to the provider-specific content block types
113
+ * that this converter supports.
114
+ */
115
+ providerName: string;
116
+ /**
117
+ * Convert from a standard image block to a provider's proprietary image block format.
118
+ * @param block - The standard image block to convert.
119
+ * @returns The provider image block.
120
+ */
121
+ fromStandardImageBlock?(block: StandardImageBlock): Formats["image"];
122
+ /**
123
+ * Convert from a standard audio block to a provider's proprietary audio block format.
124
+ * @param block - The standard audio block to convert.
125
+ * @returns The provider audio block.
126
+ */
127
+ fromStandardAudioBlock?(block: StandardAudioBlock): Formats["audio"];
128
+ /**
129
+ * Convert from a standard file block to a provider's proprietary file block format.
130
+ * @param block - The standard file block to convert.
131
+ * @returns The provider file block.
132
+ */
133
+ fromStandardFileBlock?(block: StandardFileBlock): Formats["file"];
134
+ /**
135
+ * Convert from a standard text block to a provider's proprietary text block format.
136
+ * @param block - The standard text block to convert.
137
+ * @returns The provider text block.
138
+ */
139
+ fromStandardTextBlock?(block: StandardTextBlock): Formats["text"];
140
+ }
141
+ /**
142
+ * Convert from a standard data content block to a provider's proprietary data content block format.
143
+ *
144
+ * Don't override this method. Instead, override the more specific conversion methods and use this
145
+ * method unmodified.
146
+ *
147
+ * @param block - The standard data content block to convert.
148
+ * @returns The provider data content block.
149
+ * @throws An error if the standard data content block type is not supported.
150
+ */
151
+ export declare function convertToProviderContentBlock<Formats extends Partial<ProviderFormatTypes>>(block: DataContentBlock, converter: StandardContentBlockConverter<Formats>): Formats[keyof Formats];
@@ -0,0 +1,154 @@
1
+ export function isDataContentBlock(content_block) {
2
+ return (typeof content_block === "object" &&
3
+ content_block !== null &&
4
+ "type" in content_block &&
5
+ typeof content_block.type === "string" &&
6
+ "source_type" in content_block &&
7
+ (content_block.source_type === "url" ||
8
+ content_block.source_type === "base64" ||
9
+ content_block.source_type === "text" ||
10
+ content_block.source_type === "id"));
11
+ }
12
+ export function isURLContentBlock(content_block) {
13
+ return (isDataContentBlock(content_block) &&
14
+ content_block.source_type === "url" &&
15
+ "url" in content_block &&
16
+ typeof content_block.url === "string");
17
+ }
18
+ export function isBase64ContentBlock(content_block) {
19
+ return (isDataContentBlock(content_block) &&
20
+ content_block.source_type === "base64" &&
21
+ "data" in content_block &&
22
+ typeof content_block.data === "string");
23
+ }
24
+ export function isPlainTextContentBlock(content_block) {
25
+ return (isDataContentBlock(content_block) &&
26
+ content_block.source_type === "text" &&
27
+ "text" in content_block &&
28
+ typeof content_block.text === "string");
29
+ }
30
+ export function isIDContentBlock(content_block) {
31
+ return (isDataContentBlock(content_block) &&
32
+ content_block.source_type === "id" &&
33
+ "id" in content_block &&
34
+ typeof content_block.id === "string");
35
+ }
36
+ export function convertToOpenAIImageBlock(content_block) {
37
+ if (isDataContentBlock(content_block)) {
38
+ if (content_block.source_type === "url") {
39
+ return {
40
+ type: "image_url",
41
+ image_url: {
42
+ url: content_block.url,
43
+ },
44
+ };
45
+ }
46
+ if (content_block.source_type === "base64") {
47
+ if (!content_block.mime_type) {
48
+ throw new Error("mime_type key is required for base64 data.");
49
+ }
50
+ const mime_type = content_block.mime_type;
51
+ return {
52
+ type: "image_url",
53
+ image_url: {
54
+ url: `data:${mime_type};base64,${content_block.data}`,
55
+ },
56
+ };
57
+ }
58
+ }
59
+ throw new Error("Unsupported source type. Only 'url' and 'base64' are supported.");
60
+ }
61
+ /**
62
+ * Utility function for ChatModelProviders. Parses a mime type into a type, subtype, and parameters.
63
+ *
64
+ * @param mime_type - The mime type to parse.
65
+ * @returns An object containing the type, subtype, and parameters.
66
+ */
67
+ export function parseMimeType(mime_type) {
68
+ const parts = mime_type.split(";")[0].split("/");
69
+ if (parts.length !== 2) {
70
+ throw new Error(`Invalid mime type: "${mime_type}" - does not match type/subtype format.`);
71
+ }
72
+ const type = parts[0].trim();
73
+ const subtype = parts[1].trim();
74
+ if (type === "" || subtype === "") {
75
+ throw new Error(`Invalid mime type: "${mime_type}" - type or subtype is empty.`);
76
+ }
77
+ const parameters = {};
78
+ for (const parameterKvp of mime_type.split(";").slice(1)) {
79
+ const parameterParts = parameterKvp.split("=");
80
+ if (parameterParts.length !== 2) {
81
+ throw new Error(`Invalid parameter syntax in mime type: "${mime_type}".`);
82
+ }
83
+ const key = parameterParts[0].trim();
84
+ const value = parameterParts[1].trim();
85
+ if (key === "") {
86
+ throw new Error(`Invalid parameter syntax in mime type: "${mime_type}".`);
87
+ }
88
+ parameters[key] = value;
89
+ }
90
+ return {
91
+ type,
92
+ subtype,
93
+ parameters,
94
+ };
95
+ }
96
+ /**
97
+ * Utility function for ChatModelProviders. Parses a base64 data URL into a typed array or string.
98
+ *
99
+ * @param dataUrl - The base64 data URL to parse.
100
+ * @param asTypedArray - Whether to return the data as a typed array.
101
+ * @returns The parsed data and mime type, or undefined if the data URL is invalid.
102
+ */
103
+ export function parseBase64DataUrl({ dataUrl: data_url, asTypedArray = false, }) {
104
+ const formatMatch = data_url.match(/^data:(\w+\/\w+);base64,([A-Za-z0-9+/]+=*)$/);
105
+ let mime_type;
106
+ if (formatMatch) {
107
+ mime_type = formatMatch[1].toLowerCase();
108
+ const data = asTypedArray
109
+ ? Uint8Array.from(atob(formatMatch[2]), (c) => c.charCodeAt(0))
110
+ : formatMatch[2];
111
+ return {
112
+ mime_type,
113
+ data,
114
+ };
115
+ }
116
+ return undefined;
117
+ }
118
+ /**
119
+ * Convert from a standard data content block to a provider's proprietary data content block format.
120
+ *
121
+ * Don't override this method. Instead, override the more specific conversion methods and use this
122
+ * method unmodified.
123
+ *
124
+ * @param block - The standard data content block to convert.
125
+ * @returns The provider data content block.
126
+ * @throws An error if the standard data content block type is not supported.
127
+ */
128
+ export function convertToProviderContentBlock(block, converter) {
129
+ if (block.type === "text") {
130
+ if (!converter.fromStandardTextBlock) {
131
+ throw new Error(`Converter for ${converter.providerName} does not implement \`fromStandardTextBlock\` method.`);
132
+ }
133
+ return converter.fromStandardTextBlock(block);
134
+ }
135
+ if (block.type === "image") {
136
+ if (!converter.fromStandardImageBlock) {
137
+ throw new Error(`Converter for ${converter.providerName} does not implement \`fromStandardImageBlock\` method.`);
138
+ }
139
+ return converter.fromStandardImageBlock(block);
140
+ }
141
+ if (block.type === "audio") {
142
+ if (!converter.fromStandardAudioBlock) {
143
+ throw new Error(`Converter for ${converter.providerName} does not implement \`fromStandardAudioBlock\` method.`);
144
+ }
145
+ return converter.fromStandardAudioBlock(block);
146
+ }
147
+ if (block.type === "file") {
148
+ if (!converter.fromStandardFileBlock) {
149
+ throw new Error(`Converter for ${converter.providerName} does not implement \`fromStandardFileBlock\` method.`);
150
+ }
151
+ return converter.fromStandardFileBlock(block);
152
+ }
153
+ throw new Error(`Unable to convert content block type '${block.type}' to provider-specific format: not recognized.`);
154
+ }
@@ -12,6 +12,11 @@ class HumanMessage extends base_js_1.BaseMessage {
12
12
  _getType() {
13
13
  return "human";
14
14
  }
15
+ constructor(fields,
16
+ /** @deprecated */
17
+ kwargs) {
18
+ super(fields, kwargs);
19
+ }
15
20
  }
16
21
  exports.HumanMessage = HumanMessage;
17
22
  /**
@@ -25,6 +30,11 @@ class HumanMessageChunk extends base_js_1.BaseMessageChunk {
25
30
  _getType() {
26
31
  return "human";
27
32
  }
33
+ constructor(fields,
34
+ /** @deprecated */
35
+ kwargs) {
36
+ super(fields, kwargs);
37
+ }
28
38
  concat(chunk) {
29
39
  return new HumanMessageChunk({
30
40
  content: (0, base_js_1.mergeContent)(this.content, chunk.content),
@@ -1,18 +1,30 @@
1
- import { BaseMessage, BaseMessageChunk, type MessageType } from "./base.js";
1
+ import { BaseMessage, BaseMessageChunk, type MessageType, type BaseMessageFields, type MessageContentComplex } from "./base.js";
2
+ import type { DataContentBlock } from "./content_blocks.js";
3
+ export type HumanMessageFields = BaseMessageFields & {
4
+ content: string | (MessageContentComplex | DataContentBlock)[];
5
+ };
2
6
  /**
3
7
  * Represents a human message in a conversation.
4
8
  */
5
9
  export declare class HumanMessage extends BaseMessage {
10
+ content: string | (MessageContentComplex | DataContentBlock)[];
6
11
  static lc_name(): string;
7
12
  _getType(): MessageType;
13
+ constructor(fields: string | HumanMessageFields,
14
+ /** @deprecated */
15
+ kwargs?: Record<string, unknown>);
8
16
  }
9
17
  /**
10
18
  * Represents a chunk of a human message, which can be concatenated with
11
19
  * other human message chunks.
12
20
  */
13
21
  export declare class HumanMessageChunk extends BaseMessageChunk {
22
+ content: string | (MessageContentComplex | DataContentBlock)[];
14
23
  static lc_name(): string;
15
24
  _getType(): MessageType;
25
+ constructor(fields: string | HumanMessageFields,
26
+ /** @deprecated */
27
+ kwargs?: Record<string, unknown>);
16
28
  concat(chunk: HumanMessageChunk): HumanMessageChunk;
17
29
  }
18
30
  export declare function isHumanMessage(x: BaseMessage): x is HumanMessage;
@@ -9,6 +9,11 @@ export class HumanMessage extends BaseMessage {
9
9
  _getType() {
10
10
  return "human";
11
11
  }
12
+ constructor(fields,
13
+ /** @deprecated */
14
+ kwargs) {
15
+ super(fields, kwargs);
16
+ }
12
17
  }
13
18
  /**
14
19
  * Represents a chunk of a human message, which can be concatenated with
@@ -21,6 +26,11 @@ export class HumanMessageChunk extends BaseMessageChunk {
21
26
  _getType() {
22
27
  return "human";
23
28
  }
29
+ constructor(fields,
30
+ /** @deprecated */
31
+ kwargs) {
32
+ super(fields, kwargs);
33
+ }
24
34
  concat(chunk) {
25
35
  return new HumanMessageChunk({
26
36
  content: mergeContent(this.content, chunk.content),
@@ -24,6 +24,7 @@ __exportStar(require("./system.cjs"), exports);
24
24
  __exportStar(require("./utils.cjs"), exports);
25
25
  __exportStar(require("./transformers.cjs"), exports);
26
26
  __exportStar(require("./modifier.cjs"), exports);
27
+ __exportStar(require("./content_blocks.cjs"), exports);
27
28
  // TODO: Use a star export when we deprecate the
28
29
  // existing "ToolCall" type in "base.js".
29
30
  var tool_js_1 = require("./tool.cjs");
@@ -7,4 +7,5 @@ export * from "./system.js";
7
7
  export * from "./utils.js";
8
8
  export * from "./transformers.js";
9
9
  export * from "./modifier.js";
10
+ export * from "./content_blocks.js";
10
11
  export { type ToolMessageFieldsWithToolCallId, ToolMessage, ToolMessageChunk, type InvalidToolCall, isToolMessage, isToolMessageChunk, } from "./tool.js";
@@ -7,6 +7,7 @@ export * from "./system.js";
7
7
  export * from "./utils.js";
8
8
  export * from "./transformers.js";
9
9
  export * from "./modifier.js";
10
+ export * from "./content_blocks.js";
10
11
  // TODO: Use a star export when we deprecate the
11
12
  // existing "ToolCall" type in "base.js".
12
13
  export { ToolMessage, ToolMessageChunk, isToolMessage, isToolMessageChunk, } from "./tool.js";
@@ -12,6 +12,11 @@ class SystemMessage extends base_js_1.BaseMessage {
12
12
  _getType() {
13
13
  return "system";
14
14
  }
15
+ constructor(fields,
16
+ /** @deprecated */
17
+ kwargs) {
18
+ super(fields, kwargs);
19
+ }
15
20
  }
16
21
  exports.SystemMessage = SystemMessage;
17
22
  /**
@@ -25,6 +30,11 @@ class SystemMessageChunk extends base_js_1.BaseMessageChunk {
25
30
  _getType() {
26
31
  return "system";
27
32
  }
33
+ constructor(fields,
34
+ /** @deprecated */
35
+ kwargs) {
36
+ super(fields, kwargs);
37
+ }
28
38
  concat(chunk) {
29
39
  return new SystemMessageChunk({
30
40
  content: (0, base_js_1.mergeContent)(this.content, chunk.content),
@@ -1,18 +1,30 @@
1
- import { BaseMessage, BaseMessageChunk, type MessageType } from "./base.js";
1
+ import { BaseMessage, BaseMessageChunk, type MessageType, type BaseMessageFields, type MessageContentComplex } from "./base.js";
2
+ import type { DataContentBlock } from "./content_blocks.js";
3
+ export type SystemMessageFields = BaseMessageFields & {
4
+ content: string | (MessageContentComplex | DataContentBlock)[];
5
+ };
2
6
  /**
3
7
  * Represents a system message in a conversation.
4
8
  */
5
9
  export declare class SystemMessage extends BaseMessage {
10
+ content: string | (MessageContentComplex | DataContentBlock)[];
6
11
  static lc_name(): string;
7
12
  _getType(): MessageType;
13
+ constructor(fields: string | SystemMessageFields,
14
+ /** @deprecated */
15
+ kwargs?: Record<string, unknown>);
8
16
  }
9
17
  /**
10
18
  * Represents a chunk of a system message, which can be concatenated with
11
19
  * other system message chunks.
12
20
  */
13
21
  export declare class SystemMessageChunk extends BaseMessageChunk {
22
+ content: string | (MessageContentComplex | DataContentBlock)[];
14
23
  static lc_name(): string;
15
24
  _getType(): MessageType;
25
+ constructor(fields: string | SystemMessageFields,
26
+ /** @deprecated */
27
+ kwargs?: Record<string, unknown>);
16
28
  concat(chunk: SystemMessageChunk): SystemMessageChunk;
17
29
  }
18
30
  export declare function isSystemMessage(x: BaseMessage): x is SystemMessage;
@@ -9,6 +9,11 @@ export class SystemMessage extends BaseMessage {
9
9
  _getType() {
10
10
  return "system";
11
11
  }
12
+ constructor(fields,
13
+ /** @deprecated */
14
+ kwargs) {
15
+ super(fields, kwargs);
16
+ }
12
17
  }
13
18
  /**
14
19
  * Represents a chunk of a system message, which can be concatenated with
@@ -21,6 +26,11 @@ export class SystemMessageChunk extends BaseMessageChunk {
21
26
  _getType() {
22
27
  return "system";
23
28
  }
29
+ constructor(fields,
30
+ /** @deprecated */
31
+ kwargs) {
32
+ super(fields, kwargs);
33
+ }
24
34
  concat(chunk) {
25
35
  return new SystemMessageChunk({
26
36
  content: mergeContent(this.content, chunk.content),
@@ -1,5 +1,9 @@
1
- import { BaseMessage, BaseMessageChunk, type BaseMessageFields, type MessageType } from "./base.js";
2
- export interface ToolMessageFieldsWithToolCallId extends BaseMessageFields {
1
+ import { BaseMessage, BaseMessageChunk, type BaseMessageFields, type MessageType, type MessageContentComplex } from "./base.js";
2
+ import type { DataContentBlock } from "./content_blocks.js";
3
+ export interface ToolMessageFields extends BaseMessageFields {
4
+ content: string | (MessageContentComplex | DataContentBlock)[];
5
+ }
6
+ export interface ToolMessageFieldsWithToolCallId extends ToolMessageFields {
3
7
  /**
4
8
  * Artifact of the Tool execution which is not meant to be sent to the model.
5
9
  *
@@ -30,6 +34,7 @@ export declare function isDirectToolOutput(x: unknown): x is DirectToolOutput;
30
34
  * Represents a tool message in a conversation.
31
35
  */
32
36
  export declare class ToolMessage extends BaseMessage implements DirectToolOutput {
37
+ content: string | (MessageContentComplex | DataContentBlock)[];
33
38
  static lc_name(): string;
34
39
  get lc_aliases(): Record<string, string>;
35
40
  lc_direct_tool_output: boolean;
@@ -48,7 +53,7 @@ export declare class ToolMessage extends BaseMessage implements DirectToolOutput
48
53
  */
49
54
  artifact?: any;
50
55
  constructor(fields: ToolMessageFieldsWithToolCallId);
51
- constructor(fields: string | BaseMessageFields, tool_call_id: string, name?: string);
56
+ constructor(fields: string | ToolMessageFields, tool_call_id: string, name?: string);
52
57
  _getType(): MessageType;
53
58
  static isInstance(message: BaseMessage): message is ToolMessage;
54
59
  get _printableFields(): Record<string, unknown>;
@@ -58,6 +63,7 @@ export declare class ToolMessage extends BaseMessage implements DirectToolOutput
58
63
  * with other tool message chunks.
59
64
  */
60
65
  export declare class ToolMessageChunk extends BaseMessageChunk {
66
+ content: string | (MessageContentComplex | DataContentBlock)[];
61
67
  tool_call_id: string;
62
68
  /**
63
69
  * Status of the tool invocation.
@@ -5,7 +5,9 @@ const base_js_1 = require("../runnables/base.cjs");
5
5
  const template_js_1 = require("./template.cjs");
6
6
  class DictPromptTemplate extends base_js_1.Runnable {
7
7
  constructor(fields) {
8
- super(fields);
8
+ const templateFormat = fields.templateFormat ?? "f-string";
9
+ const inputVariables = _getInputVariables(fields.template, templateFormat);
10
+ super({ inputVariables, ...fields });
9
11
  Object.defineProperty(this, "lc_namespace", {
10
12
  enumerable: true,
11
13
  configurable: true,
@@ -28,13 +30,17 @@ class DictPromptTemplate extends base_js_1.Runnable {
28
30
  enumerable: true,
29
31
  configurable: true,
30
32
  writable: true,
31
- value: "f-string"
33
+ value: void 0
34
+ });
35
+ Object.defineProperty(this, "inputVariables", {
36
+ enumerable: true,
37
+ configurable: true,
38
+ writable: true,
39
+ value: void 0
32
40
  });
33
41
  this.template = fields.template;
34
- this.templateFormat = fields.templateFormat ?? this.templateFormat;
35
- }
36
- get inputVariables() {
37
- return _getInputVariables(this.template, this.templateFormat);
42
+ this.templateFormat = templateFormat;
43
+ this.inputVariables = inputVariables;
38
44
  }
39
45
  async format(values) {
40
46
  return _insertInputVariables(this.template, values, this.templateFormat);
@@ -7,11 +7,11 @@ export declare class DictPromptTemplate<RunInput extends InputValues = InputValu
7
7
  lc_serializable: boolean;
8
8
  template: Record<string, unknown>;
9
9
  templateFormat: TemplateFormat;
10
+ inputVariables: Array<Extract<keyof RunInput, string>>;
10
11
  constructor(fields: {
11
12
  template: Record<string, unknown>;
12
13
  templateFormat?: TemplateFormat;
13
14
  });
14
- get inputVariables(): Array<Extract<keyof RunInput, string>>;
15
15
  format(values: TypedPromptInputValues<RunInput>): Promise<RunOutput>;
16
16
  invoke(values: TypedPromptInputValues<InputValues>): Promise<RunOutput>;
17
17
  }
@@ -2,7 +2,9 @@ import { Runnable } from "../runnables/base.js";
2
2
  import { parseTemplate, renderTemplate } from "./template.js";
3
3
  export class DictPromptTemplate extends Runnable {
4
4
  constructor(fields) {
5
- super(fields);
5
+ const templateFormat = fields.templateFormat ?? "f-string";
6
+ const inputVariables = _getInputVariables(fields.template, templateFormat);
7
+ super({ inputVariables, ...fields });
6
8
  Object.defineProperty(this, "lc_namespace", {
7
9
  enumerable: true,
8
10
  configurable: true,
@@ -25,13 +27,17 @@ export class DictPromptTemplate extends Runnable {
25
27
  enumerable: true,
26
28
  configurable: true,
27
29
  writable: true,
28
- value: "f-string"
30
+ value: void 0
31
+ });
32
+ Object.defineProperty(this, "inputVariables", {
33
+ enumerable: true,
34
+ configurable: true,
35
+ writable: true,
36
+ value: void 0
29
37
  });
30
38
  this.template = fields.template;
31
- this.templateFormat = fields.templateFormat ?? this.templateFormat;
32
- }
33
- get inputVariables() {
34
- return _getInputVariables(this.template, this.templateFormat);
39
+ this.templateFormat = templateFormat;
40
+ this.inputVariables = inputVariables;
35
41
  }
36
42
  async format(values) {
37
43
  return _insertInputVariables(this.template, values, this.templateFormat);
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@langchain/core",
3
- "version": "0.3.46",
3
+ "version": "0.3.48",
4
4
  "description": "Core LangChain.js abstractions and schemas",
5
5
  "type": "module",
6
6
  "engines": {