@langchain/core 0.2.8 → 0.2.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/language_models/base.cjs +21 -1
- package/dist/language_models/base.d.ts +6 -0
- package/dist/language_models/base.js +19 -0
- package/dist/language_models/chat_models.cjs +81 -0
- package/dist/language_models/chat_models.d.ts +10 -4
- package/dist/language_models/chat_models.js +81 -0
- package/dist/messages/base.d.ts +1 -0
- package/dist/messages/tests/base_message.test.js +16 -0
- package/dist/prompts/template.cjs +1 -1
- package/dist/prompts/template.js +1 -1
- package/package.json +1 -1
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
exports.BaseLanguageModel = exports.BaseLangChain = exports.calculateMaxTokens = exports.getModelContextSize = exports.getEmbeddingContextSize = exports.getModelNameForTiktoken = void 0;
|
|
3
|
+
exports.BaseLanguageModel = exports.BaseLangChain = exports.calculateMaxTokens = exports.isOpenAITool = exports.getModelContextSize = exports.getEmbeddingContextSize = exports.getModelNameForTiktoken = void 0;
|
|
4
4
|
const caches_js_1 = require("../caches.cjs");
|
|
5
5
|
const prompt_values_js_1 = require("../prompt_values.cjs");
|
|
6
6
|
const utils_js_1 = require("../messages/utils.cjs");
|
|
@@ -63,6 +63,26 @@ const getModelContextSize = (modelName) => {
|
|
|
63
63
|
}
|
|
64
64
|
};
|
|
65
65
|
exports.getModelContextSize = getModelContextSize;
|
|
66
|
+
/**
|
|
67
|
+
* Whether or not the input matches the OpenAI tool definition.
|
|
68
|
+
* @param {unknown} tool The input to check.
|
|
69
|
+
* @returns {boolean} Whether the input is an OpenAI tool definition.
|
|
70
|
+
*/
|
|
71
|
+
function isOpenAITool(tool) {
|
|
72
|
+
if (typeof tool !== "object" || !tool)
|
|
73
|
+
return false;
|
|
74
|
+
if ("type" in tool &&
|
|
75
|
+
tool.type === "function" &&
|
|
76
|
+
"function" in tool &&
|
|
77
|
+
typeof tool.function === "object" &&
|
|
78
|
+
tool.function &&
|
|
79
|
+
"name" in tool.function &&
|
|
80
|
+
"parameters" in tool.function) {
|
|
81
|
+
return true;
|
|
82
|
+
}
|
|
83
|
+
return false;
|
|
84
|
+
}
|
|
85
|
+
exports.isOpenAITool = isOpenAITool;
|
|
66
86
|
const calculateMaxTokens = async ({ prompt, modelName, }) => {
|
|
67
87
|
let numTokens;
|
|
68
88
|
try {
|
|
@@ -11,6 +11,12 @@ import { RunnableConfig } from "../runnables/config.js";
|
|
|
11
11
|
export declare const getModelNameForTiktoken: (modelName: string) => TiktokenModel;
|
|
12
12
|
export declare const getEmbeddingContextSize: (modelName?: string) => number;
|
|
13
13
|
export declare const getModelContextSize: (modelName: string) => number;
|
|
14
|
+
/**
|
|
15
|
+
* Whether or not the input matches the OpenAI tool definition.
|
|
16
|
+
* @param {unknown} tool The input to check.
|
|
17
|
+
* @returns {boolean} Whether the input is an OpenAI tool definition.
|
|
18
|
+
*/
|
|
19
|
+
export declare function isOpenAITool(tool: unknown): tool is ToolDefinition;
|
|
14
20
|
interface CalculateMaxTokenProps {
|
|
15
21
|
prompt: string;
|
|
16
22
|
modelName: TiktokenModel;
|
|
@@ -57,6 +57,25 @@ export const getModelContextSize = (modelName) => {
|
|
|
57
57
|
return 4097;
|
|
58
58
|
}
|
|
59
59
|
};
|
|
60
|
+
/**
|
|
61
|
+
* Whether or not the input matches the OpenAI tool definition.
|
|
62
|
+
* @param {unknown} tool The input to check.
|
|
63
|
+
* @returns {boolean} Whether the input is an OpenAI tool definition.
|
|
64
|
+
*/
|
|
65
|
+
export function isOpenAITool(tool) {
|
|
66
|
+
if (typeof tool !== "object" || !tool)
|
|
67
|
+
return false;
|
|
68
|
+
if ("type" in tool &&
|
|
69
|
+
tool.type === "function" &&
|
|
70
|
+
"function" in tool &&
|
|
71
|
+
typeof tool.function === "object" &&
|
|
72
|
+
tool.function &&
|
|
73
|
+
"name" in tool.function &&
|
|
74
|
+
"parameters" in tool.function) {
|
|
75
|
+
return true;
|
|
76
|
+
}
|
|
77
|
+
return false;
|
|
78
|
+
}
|
|
60
79
|
export const calculateMaxTokens = async ({ prompt, modelName, }) => {
|
|
61
80
|
let numTokens;
|
|
62
81
|
try {
|
|
@@ -1,13 +1,17 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
3
|
exports.SimpleChatModel = exports.BaseChatModel = exports.createChatMessageChunkEncoderStream = void 0;
|
|
4
|
+
const zod_to_json_schema_1 = require("zod-to-json-schema");
|
|
4
5
|
const index_js_1 = require("../messages/index.cjs");
|
|
5
6
|
const outputs_js_1 = require("../outputs.cjs");
|
|
6
7
|
const base_js_1 = require("./base.cjs");
|
|
7
8
|
const manager_js_1 = require("../callbacks/manager.cjs");
|
|
9
|
+
const base_js_2 = require("../runnables/base.cjs");
|
|
8
10
|
const event_stream_js_1 = require("../tracers/event_stream.cjs");
|
|
9
11
|
const log_stream_js_1 = require("../tracers/log_stream.cjs");
|
|
10
12
|
const stream_js_1 = require("../utils/stream.cjs");
|
|
13
|
+
const passthrough_js_1 = require("../runnables/passthrough.cjs");
|
|
14
|
+
const is_zod_schema_js_1 = require("../utils/types/is_zod_schema.cjs");
|
|
11
15
|
/**
|
|
12
16
|
* Creates a transform stream for encoding chat message chunks.
|
|
13
17
|
* @deprecated Use {@link BytesOutputParser} instead
|
|
@@ -415,6 +419,83 @@ class BaseChatModel extends base_js_1.BaseLanguageModel {
|
|
|
415
419
|
}
|
|
416
420
|
return result.content;
|
|
417
421
|
}
|
|
422
|
+
withStructuredOutput(outputSchema, config) {
|
|
423
|
+
if (typeof this.bindTools !== "function") {
|
|
424
|
+
throw new Error(`Chat model must implement ".bindTools()" to use withStructuredOutput.`);
|
|
425
|
+
}
|
|
426
|
+
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
427
|
+
const schema = outputSchema;
|
|
428
|
+
const name = config?.name;
|
|
429
|
+
const description = schema.description ?? "A function available to call.";
|
|
430
|
+
const method = config?.method;
|
|
431
|
+
const includeRaw = config?.includeRaw;
|
|
432
|
+
if (method === "jsonMode") {
|
|
433
|
+
throw new Error(`Base withStructuredOutput implementation only supports "functionCalling" as a method.`);
|
|
434
|
+
}
|
|
435
|
+
let functionName = name ?? "extract";
|
|
436
|
+
let tools;
|
|
437
|
+
if ((0, is_zod_schema_js_1.isZodSchema)(schema)) {
|
|
438
|
+
tools = [
|
|
439
|
+
{
|
|
440
|
+
type: "function",
|
|
441
|
+
function: {
|
|
442
|
+
name: functionName,
|
|
443
|
+
description,
|
|
444
|
+
parameters: (0, zod_to_json_schema_1.zodToJsonSchema)(schema),
|
|
445
|
+
},
|
|
446
|
+
},
|
|
447
|
+
];
|
|
448
|
+
}
|
|
449
|
+
else {
|
|
450
|
+
if ("name" in schema) {
|
|
451
|
+
functionName = schema.name;
|
|
452
|
+
}
|
|
453
|
+
tools = [
|
|
454
|
+
{
|
|
455
|
+
type: "function",
|
|
456
|
+
function: {
|
|
457
|
+
name: functionName,
|
|
458
|
+
description,
|
|
459
|
+
parameters: schema,
|
|
460
|
+
},
|
|
461
|
+
},
|
|
462
|
+
];
|
|
463
|
+
}
|
|
464
|
+
const llm = this.bindTools(tools);
|
|
465
|
+
const outputParser = base_js_2.RunnableLambda.from((input) => {
|
|
466
|
+
if (!input.tool_calls || input.tool_calls.length === 0) {
|
|
467
|
+
throw new Error("No tool calls found in the response.");
|
|
468
|
+
}
|
|
469
|
+
const toolCall = input.tool_calls.find((tc) => tc.name === functionName);
|
|
470
|
+
if (!toolCall) {
|
|
471
|
+
throw new Error(`No tool call found with name ${functionName}.`);
|
|
472
|
+
}
|
|
473
|
+
return toolCall.args;
|
|
474
|
+
});
|
|
475
|
+
if (!includeRaw) {
|
|
476
|
+
return llm.pipe(outputParser).withConfig({
|
|
477
|
+
runName: "StructuredOutput",
|
|
478
|
+
});
|
|
479
|
+
}
|
|
480
|
+
const parserAssign = passthrough_js_1.RunnablePassthrough.assign({
|
|
481
|
+
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
482
|
+
parsed: (input, config) => outputParser.invoke(input.raw, config),
|
|
483
|
+
});
|
|
484
|
+
const parserNone = passthrough_js_1.RunnablePassthrough.assign({
|
|
485
|
+
parsed: () => null,
|
|
486
|
+
});
|
|
487
|
+
const parsedWithFallback = parserAssign.withFallbacks({
|
|
488
|
+
fallbacks: [parserNone],
|
|
489
|
+
});
|
|
490
|
+
return base_js_2.RunnableSequence.from([
|
|
491
|
+
{
|
|
492
|
+
raw: llm,
|
|
493
|
+
},
|
|
494
|
+
parsedWithFallback,
|
|
495
|
+
]).withConfig({
|
|
496
|
+
runName: "StructuredOutputRunnable",
|
|
497
|
+
});
|
|
498
|
+
}
|
|
418
499
|
}
|
|
419
500
|
exports.BaseChatModel = BaseChatModel;
|
|
420
501
|
/**
|
|
@@ -1,7 +1,8 @@
|
|
|
1
|
+
import { z } from "zod";
|
|
1
2
|
import { type BaseMessage, BaseMessageChunk, type BaseMessageLike } from "../messages/index.js";
|
|
2
3
|
import type { BasePromptValueInterface } from "../prompt_values.js";
|
|
3
4
|
import { LLMResult, ChatGenerationChunk, type ChatResult, type Generation } from "../outputs.js";
|
|
4
|
-
import { BaseLanguageModel, type BaseLanguageModelCallOptions, type BaseLanguageModelInput, type BaseLanguageModelParams } from "./base.js";
|
|
5
|
+
import { BaseLanguageModel, StructuredOutputMethodOptions, ToolDefinition, type BaseLanguageModelCallOptions, type BaseLanguageModelInput, type BaseLanguageModelParams } from "./base.js";
|
|
5
6
|
import { type CallbackManagerForLLMRun, type Callbacks } from "../callbacks/manager.js";
|
|
6
7
|
import type { RunnableConfig } from "../runnables/config.js";
|
|
7
8
|
import type { BaseCache } from "../caches.js";
|
|
@@ -64,11 +65,11 @@ export declare abstract class BaseChatModel<CallOptions extends BaseChatModelCal
|
|
|
64
65
|
* Bind tool-like objects to this chat model.
|
|
65
66
|
*
|
|
66
67
|
* @param tools A list of tool definitions to bind to this chat model.
|
|
67
|
-
* Can be a structured tool or an object
|
|
68
|
-
* specific tool schema.
|
|
68
|
+
* Can be a structured tool, an OpenAI formatted tool, or an object
|
|
69
|
+
* matching the provider's specific tool schema.
|
|
69
70
|
* @param kwargs Any additional parameters to bind.
|
|
70
71
|
*/
|
|
71
|
-
bindTools?(tools: (StructuredToolInterface | Record<string, unknown>)[], kwargs?: Partial<CallOptions>): Runnable<BaseLanguageModelInput, OutputMessageType, CallOptions>;
|
|
72
|
+
bindTools?(tools: (StructuredToolInterface | Record<string, unknown> | ToolDefinition)[], kwargs?: Partial<CallOptions>): Runnable<BaseLanguageModelInput, OutputMessageType, CallOptions>;
|
|
72
73
|
/**
|
|
73
74
|
* Invokes the chat model with a single input.
|
|
74
75
|
* @param input The input for the language model.
|
|
@@ -152,6 +153,11 @@ export declare abstract class BaseChatModel<CallOptions extends BaseChatModelCal
|
|
|
152
153
|
* @returns A Promise that resolves to a string.
|
|
153
154
|
*/
|
|
154
155
|
predict(text: string, options?: string[] | CallOptions, callbacks?: Callbacks): Promise<string>;
|
|
156
|
+
withStructuredOutput<RunOutput extends Record<string, any> = Record<string, any>>(outputSchema: z.ZodType<RunOutput> | Record<string, any>, config?: StructuredOutputMethodOptions<false>): Runnable<BaseLanguageModelInput, RunOutput>;
|
|
157
|
+
withStructuredOutput<RunOutput extends Record<string, any> = Record<string, any>>(outputSchema: z.ZodType<RunOutput> | Record<string, any>, config?: StructuredOutputMethodOptions<true>): Runnable<BaseLanguageModelInput, {
|
|
158
|
+
raw: BaseMessage;
|
|
159
|
+
parsed: RunOutput;
|
|
160
|
+
}>;
|
|
155
161
|
}
|
|
156
162
|
/**
|
|
157
163
|
* An abstract class that extends BaseChatModel and provides a simple
|
|
@@ -1,10 +1,14 @@
|
|
|
1
|
+
import { zodToJsonSchema } from "zod-to-json-schema";
|
|
1
2
|
import { AIMessage, HumanMessage, coerceMessageLikeToMessage, } from "../messages/index.js";
|
|
2
3
|
import { RUN_KEY, } from "../outputs.js";
|
|
3
4
|
import { BaseLanguageModel, } from "./base.js";
|
|
4
5
|
import { CallbackManager, } from "../callbacks/manager.js";
|
|
6
|
+
import { RunnableLambda, RunnableSequence, } from "../runnables/base.js";
|
|
5
7
|
import { isStreamEventsHandler } from "../tracers/event_stream.js";
|
|
6
8
|
import { isLogStreamHandler } from "../tracers/log_stream.js";
|
|
7
9
|
import { concat } from "../utils/stream.js";
|
|
10
|
+
import { RunnablePassthrough } from "../runnables/passthrough.js";
|
|
11
|
+
import { isZodSchema } from "../utils/types/is_zod_schema.js";
|
|
8
12
|
/**
|
|
9
13
|
* Creates a transform stream for encoding chat message chunks.
|
|
10
14
|
* @deprecated Use {@link BytesOutputParser} instead
|
|
@@ -411,6 +415,83 @@ export class BaseChatModel extends BaseLanguageModel {
|
|
|
411
415
|
}
|
|
412
416
|
return result.content;
|
|
413
417
|
}
|
|
418
|
+
withStructuredOutput(outputSchema, config) {
|
|
419
|
+
if (typeof this.bindTools !== "function") {
|
|
420
|
+
throw new Error(`Chat model must implement ".bindTools()" to use withStructuredOutput.`);
|
|
421
|
+
}
|
|
422
|
+
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
423
|
+
const schema = outputSchema;
|
|
424
|
+
const name = config?.name;
|
|
425
|
+
const description = schema.description ?? "A function available to call.";
|
|
426
|
+
const method = config?.method;
|
|
427
|
+
const includeRaw = config?.includeRaw;
|
|
428
|
+
if (method === "jsonMode") {
|
|
429
|
+
throw new Error(`Base withStructuredOutput implementation only supports "functionCalling" as a method.`);
|
|
430
|
+
}
|
|
431
|
+
let functionName = name ?? "extract";
|
|
432
|
+
let tools;
|
|
433
|
+
if (isZodSchema(schema)) {
|
|
434
|
+
tools = [
|
|
435
|
+
{
|
|
436
|
+
type: "function",
|
|
437
|
+
function: {
|
|
438
|
+
name: functionName,
|
|
439
|
+
description,
|
|
440
|
+
parameters: zodToJsonSchema(schema),
|
|
441
|
+
},
|
|
442
|
+
},
|
|
443
|
+
];
|
|
444
|
+
}
|
|
445
|
+
else {
|
|
446
|
+
if ("name" in schema) {
|
|
447
|
+
functionName = schema.name;
|
|
448
|
+
}
|
|
449
|
+
tools = [
|
|
450
|
+
{
|
|
451
|
+
type: "function",
|
|
452
|
+
function: {
|
|
453
|
+
name: functionName,
|
|
454
|
+
description,
|
|
455
|
+
parameters: schema,
|
|
456
|
+
},
|
|
457
|
+
},
|
|
458
|
+
];
|
|
459
|
+
}
|
|
460
|
+
const llm = this.bindTools(tools);
|
|
461
|
+
const outputParser = RunnableLambda.from((input) => {
|
|
462
|
+
if (!input.tool_calls || input.tool_calls.length === 0) {
|
|
463
|
+
throw new Error("No tool calls found in the response.");
|
|
464
|
+
}
|
|
465
|
+
const toolCall = input.tool_calls.find((tc) => tc.name === functionName);
|
|
466
|
+
if (!toolCall) {
|
|
467
|
+
throw new Error(`No tool call found with name ${functionName}.`);
|
|
468
|
+
}
|
|
469
|
+
return toolCall.args;
|
|
470
|
+
});
|
|
471
|
+
if (!includeRaw) {
|
|
472
|
+
return llm.pipe(outputParser).withConfig({
|
|
473
|
+
runName: "StructuredOutput",
|
|
474
|
+
});
|
|
475
|
+
}
|
|
476
|
+
const parserAssign = RunnablePassthrough.assign({
|
|
477
|
+
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
478
|
+
parsed: (input, config) => outputParser.invoke(input.raw, config),
|
|
479
|
+
});
|
|
480
|
+
const parserNone = RunnablePassthrough.assign({
|
|
481
|
+
parsed: () => null,
|
|
482
|
+
});
|
|
483
|
+
const parsedWithFallback = parserAssign.withFallbacks({
|
|
484
|
+
fallbacks: [parserNone],
|
|
485
|
+
});
|
|
486
|
+
return RunnableSequence.from([
|
|
487
|
+
{
|
|
488
|
+
raw: llm,
|
|
489
|
+
},
|
|
490
|
+
parsedWithFallback,
|
|
491
|
+
]).withConfig({
|
|
492
|
+
runName: "StructuredOutputRunnable",
|
|
493
|
+
});
|
|
494
|
+
}
|
|
414
495
|
}
|
|
415
496
|
/**
|
|
416
497
|
* An abstract class that extends BaseChatModel and provides a simple
|
package/dist/messages/base.d.ts
CHANGED
|
@@ -8,6 +8,7 @@ export interface StoredMessageData {
|
|
|
8
8
|
additional_kwargs?: Record<string, any>;
|
|
9
9
|
/** Response metadata. For example: response headers, logprobs, token counts. */
|
|
10
10
|
response_metadata?: Record<string, any>;
|
|
11
|
+
id?: string;
|
|
11
12
|
}
|
|
12
13
|
export interface StoredMessage {
|
|
13
14
|
type: string;
|
|
@@ -95,3 +95,19 @@ test("Deserialisation and serialisation of tool_call_id", async () => {
|
|
|
95
95
|
const deserialized = await load(JSON.stringify(message), config);
|
|
96
96
|
expect(deserialized).toEqual(message);
|
|
97
97
|
});
|
|
98
|
+
test("Deserialisation and serialisation of messages with ID", async () => {
|
|
99
|
+
const config = {
|
|
100
|
+
importMap: { messages: { AIMessage } },
|
|
101
|
+
optionalImportEntrypoints: [],
|
|
102
|
+
optionalImportsMap: {},
|
|
103
|
+
secretsMap: {},
|
|
104
|
+
};
|
|
105
|
+
const messageId = "uuid-1234";
|
|
106
|
+
const message = new AIMessage({
|
|
107
|
+
content: "The sky is blue because...",
|
|
108
|
+
id: messageId,
|
|
109
|
+
});
|
|
110
|
+
const deserialized = await load(JSON.stringify(message), config);
|
|
111
|
+
expect(deserialized).toEqual(message);
|
|
112
|
+
expect(deserialized.id).toBe(messageId);
|
|
113
|
+
});
|
|
@@ -66,7 +66,7 @@ const mustacheTemplateToNodes = (template) => template.map((temp) => {
|
|
|
66
66
|
const name = temp[1].includes(".") ? temp[1].split(".")[0] : temp[1];
|
|
67
67
|
return { type: "variable", name };
|
|
68
68
|
}
|
|
69
|
-
else if (["#", "&"].includes(temp[0])) {
|
|
69
|
+
else if (["#", "&", "^", ">"].includes(temp[0])) {
|
|
70
70
|
// # represents a section, "&" represents an unescaped variable.
|
|
71
71
|
// These should both be considered variables.
|
|
72
72
|
return { type: "variable", name: temp[1] };
|
package/dist/prompts/template.js
CHANGED
|
@@ -59,7 +59,7 @@ const mustacheTemplateToNodes = (template) => template.map((temp) => {
|
|
|
59
59
|
const name = temp[1].includes(".") ? temp[1].split(".")[0] : temp[1];
|
|
60
60
|
return { type: "variable", name };
|
|
61
61
|
}
|
|
62
|
-
else if (["#", "&"].includes(temp[0])) {
|
|
62
|
+
else if (["#", "&", "^", ">"].includes(temp[0])) {
|
|
63
63
|
// # represents a section, "&" represents an unescaped variable.
|
|
64
64
|
// These should both be considered variables.
|
|
65
65
|
return { type: "variable", name: temp[1] };
|