@langchain/core 0.2.0-rc.0 → 0.2.1

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.
Files changed (134) hide show
  1. package/dist/callbacks/base.cjs +9 -1
  2. package/dist/callbacks/base.d.ts +3 -0
  3. package/dist/callbacks/base.js +9 -1
  4. package/dist/callbacks/manager.cjs +51 -0
  5. package/dist/callbacks/manager.js +51 -0
  6. package/dist/callbacks/tests/callbacks.test.d.ts +1 -0
  7. package/dist/callbacks/tests/callbacks.test.js +492 -0
  8. package/dist/callbacks/tests/manager.int.test.d.ts +1 -0
  9. package/dist/callbacks/tests/manager.int.test.js +29 -0
  10. package/dist/callbacks/tests/run_collector.test.d.ts +1 -0
  11. package/dist/callbacks/tests/run_collector.test.js +58 -0
  12. package/dist/chat_history.cjs +13 -0
  13. package/dist/chat_history.d.ts +9 -0
  14. package/dist/chat_history.js +13 -0
  15. package/dist/language_models/base.cjs +3 -0
  16. package/dist/language_models/base.js +3 -0
  17. package/dist/language_models/chat_models.cjs +21 -3
  18. package/dist/language_models/chat_models.d.ts +11 -2
  19. package/dist/language_models/chat_models.js +21 -3
  20. package/dist/language_models/tests/chat_models.test.d.ts +1 -0
  21. package/dist/language_models/tests/chat_models.test.js +154 -0
  22. package/dist/language_models/tests/count_tokens.test.d.ts +1 -0
  23. package/dist/language_models/tests/count_tokens.test.js +19 -0
  24. package/dist/language_models/tests/llms.test.d.ts +1 -0
  25. package/dist/language_models/tests/llms.test.js +39 -0
  26. package/dist/messages/tests/base_message.test.d.ts +1 -0
  27. package/dist/messages/tests/base_message.test.js +97 -0
  28. package/dist/output_parsers/openai_tools/tests/json_output_tools_parser.test.d.ts +1 -0
  29. package/dist/output_parsers/openai_tools/tests/json_output_tools_parser.test.js +81 -0
  30. package/dist/output_parsers/tests/json.test.d.ts +1 -0
  31. package/dist/output_parsers/tests/json.test.js +427 -0
  32. package/dist/output_parsers/tests/output_parser.test.d.ts +1 -0
  33. package/dist/output_parsers/tests/output_parser.test.js +78 -0
  34. package/dist/output_parsers/tests/string.test.d.ts +1 -0
  35. package/dist/output_parsers/tests/string.test.js +68 -0
  36. package/dist/output_parsers/tests/structured.test.d.ts +1 -0
  37. package/dist/output_parsers/tests/structured.test.js +166 -0
  38. package/dist/output_parsers/tests/xml.test.d.ts +1 -0
  39. package/dist/output_parsers/tests/xml.test.js +81 -0
  40. package/dist/prompts/tests/chat.mustache.test.d.ts +1 -0
  41. package/dist/prompts/tests/chat.mustache.test.js +61 -0
  42. package/dist/prompts/tests/chat.test.d.ts +1 -0
  43. package/dist/prompts/tests/chat.test.js +507 -0
  44. package/dist/prompts/tests/few_shot.test.d.ts +1 -0
  45. package/dist/prompts/tests/few_shot.test.js +224 -0
  46. package/dist/prompts/tests/pipeline.test.d.ts +1 -0
  47. package/dist/prompts/tests/pipeline.test.js +101 -0
  48. package/dist/prompts/tests/prompt.mustache.test.d.ts +1 -0
  49. package/dist/prompts/tests/prompt.mustache.test.js +85 -0
  50. package/dist/prompts/tests/prompt.test.d.ts +1 -0
  51. package/dist/prompts/tests/prompt.test.js +78 -0
  52. package/dist/prompts/tests/structured.test.d.ts +1 -0
  53. package/dist/prompts/tests/structured.test.js +37 -0
  54. package/dist/prompts/tests/template.test.d.ts +1 -0
  55. package/dist/prompts/tests/template.test.js +24 -0
  56. package/dist/runnables/base.cjs +174 -19
  57. package/dist/runnables/base.d.ts +47 -28
  58. package/dist/runnables/base.js +174 -19
  59. package/dist/runnables/history.cjs +87 -32
  60. package/dist/runnables/history.d.ts +1 -1
  61. package/dist/runnables/history.js +87 -32
  62. package/dist/runnables/iter.cjs +46 -0
  63. package/dist/runnables/iter.d.ts +5 -0
  64. package/dist/runnables/iter.js +39 -0
  65. package/dist/runnables/passthrough.cjs +1 -0
  66. package/dist/runnables/passthrough.d.ts +1 -1
  67. package/dist/runnables/passthrough.js +1 -0
  68. package/dist/runnables/remote.cjs +60 -48
  69. package/dist/runnables/remote.d.ts +8 -4
  70. package/dist/runnables/remote.js +61 -49
  71. package/dist/runnables/tests/runnable.test.d.ts +1 -0
  72. package/dist/runnables/tests/runnable.test.js +491 -0
  73. package/dist/runnables/tests/runnable_binding.test.d.ts +1 -0
  74. package/dist/runnables/tests/runnable_binding.test.js +46 -0
  75. package/dist/runnables/tests/runnable_branch.test.d.ts +1 -0
  76. package/dist/runnables/tests/runnable_branch.test.js +116 -0
  77. package/dist/runnables/tests/runnable_graph.test.d.ts +1 -0
  78. package/dist/runnables/tests/runnable_graph.test.js +84 -0
  79. package/dist/runnables/tests/runnable_history.test.d.ts +1 -0
  80. package/dist/runnables/tests/runnable_history.test.js +177 -0
  81. package/dist/runnables/tests/runnable_interface.test.d.ts +1 -0
  82. package/dist/runnables/tests/runnable_interface.test.js +209 -0
  83. package/dist/runnables/tests/runnable_map.test.d.ts +1 -0
  84. package/dist/runnables/tests/runnable_map.test.js +238 -0
  85. package/dist/runnables/tests/runnable_passthrough.test.d.ts +1 -0
  86. package/dist/runnables/tests/runnable_passthrough.test.js +96 -0
  87. package/dist/runnables/tests/runnable_remote.int.test.d.ts +1 -0
  88. package/dist/runnables/tests/runnable_remote.int.test.js +138 -0
  89. package/dist/runnables/tests/runnable_remote.test.d.ts +1 -0
  90. package/dist/runnables/tests/runnable_remote.test.js +200 -0
  91. package/dist/runnables/tests/runnable_retry.test.d.ts +1 -0
  92. package/dist/runnables/tests/runnable_retry.test.js +125 -0
  93. package/dist/runnables/tests/runnable_stream_events.test.d.ts +1 -0
  94. package/dist/runnables/tests/runnable_stream_events.test.js +1013 -0
  95. package/dist/runnables/tests/runnable_stream_events_v2.test.d.ts +1 -0
  96. package/dist/runnables/tests/runnable_stream_events_v2.test.js +973 -0
  97. package/dist/runnables/tests/runnable_stream_log.test.d.ts +1 -0
  98. package/dist/runnables/tests/runnable_stream_log.test.js +282 -0
  99. package/dist/runnables/tests/runnable_tracing.int.test.d.ts +1 -0
  100. package/dist/runnables/tests/runnable_tracing.int.test.js +37 -0
  101. package/dist/runnables/tests/runnable_with_fallbacks.test.d.ts +1 -0
  102. package/dist/runnables/tests/runnable_with_fallbacks.test.js +36 -0
  103. package/dist/runnables/utils.d.ts +1 -1
  104. package/dist/singletons/index.cjs +1 -1
  105. package/dist/singletons/index.d.ts +2 -2
  106. package/dist/singletons/index.js +1 -1
  107. package/dist/singletons/tests/async_local_storage.test.d.ts +1 -0
  108. package/dist/singletons/tests/async_local_storage.test.js +120 -0
  109. package/dist/structured_query/tests/utils.test.d.ts +1 -0
  110. package/dist/structured_query/tests/utils.test.js +47 -0
  111. package/dist/tracers/event_stream.cjs +493 -0
  112. package/dist/tracers/event_stream.d.ts +137 -0
  113. package/dist/tracers/event_stream.js +489 -0
  114. package/dist/tracers/log_stream.d.ts +2 -77
  115. package/dist/tracers/tests/langchain_tracer.int.test.d.ts +1 -0
  116. package/dist/tracers/tests/langchain_tracer.int.test.js +74 -0
  117. package/dist/tracers/tests/tracer.test.d.ts +1 -0
  118. package/dist/tracers/tests/tracer.test.js +378 -0
  119. package/dist/utils/stream.cjs +27 -11
  120. package/dist/utils/stream.d.ts +6 -1
  121. package/dist/utils/stream.js +27 -11
  122. package/dist/utils/testing/tests/chatfake.test.d.ts +1 -0
  123. package/dist/utils/testing/tests/chatfake.test.js +112 -0
  124. package/dist/utils/tests/async_caller.test.d.ts +1 -0
  125. package/dist/utils/tests/async_caller.test.js +27 -0
  126. package/dist/utils/tests/enviroment.test.d.ts +1 -0
  127. package/dist/utils/tests/enviroment.test.js +6 -0
  128. package/dist/utils/tests/function_calling.test.d.ts +1 -0
  129. package/dist/utils/tests/function_calling.test.js +107 -0
  130. package/dist/utils/tests/math_utils.test.d.ts +1 -0
  131. package/dist/utils/tests/math_utils.test.js +139 -0
  132. package/dist/utils/tests/polyfill_stream.test.d.ts +1 -0
  133. package/dist/utils/tests/polyfill_stream.test.js +15 -0
  134. package/package.json +7 -7
@@ -70,7 +70,11 @@ class BaseChatModel extends base_js_1.BaseLanguageModel {
70
70
  const prompt = BaseChatModel._convertInputToPromptValue(input);
71
71
  const messages = prompt.toChatMessages();
72
72
  const [runnableConfig, callOptions] = this._separateRunnableConfigFromCallOptions(options);
73
- const callbackManager_ = await manager_js_1.CallbackManager.configure(runnableConfig.callbacks, this.callbacks, runnableConfig.tags, this.tags, runnableConfig.metadata, this.metadata, { verbose: this.verbose });
73
+ const inheritableMetadata = {
74
+ ...runnableConfig.metadata,
75
+ ...this.getLsParams(callOptions),
76
+ };
77
+ const callbackManager_ = await manager_js_1.CallbackManager.configure(runnableConfig.callbacks, this.callbacks, runnableConfig.tags, this.tags, inheritableMetadata, this.metadata, { verbose: this.verbose });
74
78
  const extra = {
75
79
  options: callOptions,
76
80
  invocation_params: this?.invocationParams(callOptions),
@@ -103,11 +107,21 @@ class BaseChatModel extends base_js_1.BaseLanguageModel {
103
107
  })));
104
108
  }
105
109
  }
110
+ getLsParams(options) {
111
+ return {
112
+ ls_model_type: "chat",
113
+ ls_stop: options.stop,
114
+ };
115
+ }
106
116
  /** @ignore */
107
117
  async _generateUncached(messages, parsedOptions, handledOptions) {
108
118
  const baseMessages = messages.map((messageList) => messageList.map(index_js_1.coerceMessageLikeToMessage));
119
+ const inheritableMetadata = {
120
+ ...handledOptions.metadata,
121
+ ...this.getLsParams(parsedOptions),
122
+ };
109
123
  // create callback manager and start run
110
- const callbackManager_ = await manager_js_1.CallbackManager.configure(handledOptions.callbacks, this.callbacks, handledOptions.tags, this.tags, handledOptions.metadata, this.metadata, { verbose: this.verbose });
124
+ const callbackManager_ = await manager_js_1.CallbackManager.configure(handledOptions.callbacks, this.callbacks, handledOptions.tags, this.tags, inheritableMetadata, this.metadata, { verbose: this.verbose });
111
125
  const extra = {
112
126
  options: parsedOptions,
113
127
  invocation_params: this?.invocationParams(parsedOptions),
@@ -164,8 +178,12 @@ class BaseChatModel extends base_js_1.BaseLanguageModel {
164
178
  }
165
179
  async _generateCached({ messages, cache, llmStringKey, parsedOptions, handledOptions, }) {
166
180
  const baseMessages = messages.map((messageList) => messageList.map(index_js_1.coerceMessageLikeToMessage));
181
+ const inheritableMetadata = {
182
+ ...handledOptions.metadata,
183
+ ...this.getLsParams(parsedOptions),
184
+ };
167
185
  // create callback manager and start run
168
- const callbackManager_ = await manager_js_1.CallbackManager.configure(handledOptions.callbacks, this.callbacks, handledOptions.tags, this.tags, handledOptions.metadata, this.metadata, { verbose: this.verbose });
186
+ const callbackManager_ = await manager_js_1.CallbackManager.configure(handledOptions.callbacks, this.callbacks, handledOptions.tags, this.tags, inheritableMetadata, this.metadata, { verbose: this.verbose });
169
187
  const extra = {
170
188
  options: parsedOptions,
171
189
  invocation_params: this?.invocationParams(parsedOptions),
@@ -6,7 +6,7 @@ import { type CallbackManagerForLLMRun, type Callbacks } from "../callbacks/mana
6
6
  import type { RunnableConfig } from "../runnables/config.js";
7
7
  import type { BaseCache } from "../caches.js";
8
8
  import { StructuredToolInterface } from "../tools.js";
9
- import { RunnableInterface } from "../runnables/types.js";
9
+ import { Runnable } from "../runnables/base.js";
10
10
  /**
11
11
  * Represents a serialized chat model.
12
12
  */
@@ -35,6 +35,14 @@ export type BaseChatModelCallOptions = BaseLanguageModelCallOptions;
35
35
  * @returns A TransformStream instance that encodes chat message chunks.
36
36
  */
37
37
  export declare function createChatMessageChunkEncoderStream(): TransformStream<BaseMessageChunk, any>;
38
+ export type LangSmithParams = {
39
+ ls_provider?: string;
40
+ ls_model_name?: string;
41
+ ls_model_type: "chat";
42
+ ls_temperature?: number;
43
+ ls_max_tokens?: number;
44
+ ls_stop?: Array<string>;
45
+ };
38
46
  interface ChatModelGenerateCachedParameters<T extends BaseChatModel<CallOptions>, CallOptions extends BaseChatModelCallOptions = BaseChatModelCallOptions> {
39
47
  messages: BaseMessageLike[][];
40
48
  cache: BaseCache<Generation[]>;
@@ -60,7 +68,7 @@ export declare abstract class BaseChatModel<CallOptions extends BaseChatModelCal
60
68
  * specific tool schema.
61
69
  * @param kwargs Any additional parameters to bind.
62
70
  */
63
- bindTools?(tools: (StructuredToolInterface | Record<string, unknown>)[], kwargs?: Partial<CallOptions>): RunnableInterface<BaseLanguageModelInput, OutputMessageType, CallOptions>;
71
+ bindTools?(tools: (StructuredToolInterface | Record<string, unknown>)[], kwargs?: Partial<CallOptions>): Runnable<BaseLanguageModelInput, OutputMessageType, CallOptions>;
64
72
  /**
65
73
  * Invokes the chat model with a single input.
66
74
  * @param input The input for the language model.
@@ -70,6 +78,7 @@ export declare abstract class BaseChatModel<CallOptions extends BaseChatModelCal
70
78
  invoke(input: BaseLanguageModelInput, options?: CallOptions): Promise<OutputMessageType>;
71
79
  _streamResponseChunks(_messages: BaseMessage[], _options: this["ParsedCallOptions"], _runManager?: CallbackManagerForLLMRun): AsyncGenerator<ChatGenerationChunk>;
72
80
  _streamIterator(input: BaseLanguageModelInput, options?: CallOptions): AsyncGenerator<OutputMessageType>;
81
+ protected getLsParams(options: this["ParsedCallOptions"]): LangSmithParams;
73
82
  /** @ignore */
74
83
  _generateUncached(messages: BaseMessageLike[][], parsedOptions: this["ParsedCallOptions"], handledOptions: RunnableConfig): Promise<LLMResult>;
75
84
  _generateCached({ messages, cache, llmStringKey, parsedOptions, handledOptions, }: ChatModelGenerateCachedParameters<typeof this>): Promise<LLMResult & {
@@ -66,7 +66,11 @@ export class BaseChatModel extends BaseLanguageModel {
66
66
  const prompt = BaseChatModel._convertInputToPromptValue(input);
67
67
  const messages = prompt.toChatMessages();
68
68
  const [runnableConfig, callOptions] = this._separateRunnableConfigFromCallOptions(options);
69
- const callbackManager_ = await CallbackManager.configure(runnableConfig.callbacks, this.callbacks, runnableConfig.tags, this.tags, runnableConfig.metadata, this.metadata, { verbose: this.verbose });
69
+ const inheritableMetadata = {
70
+ ...runnableConfig.metadata,
71
+ ...this.getLsParams(callOptions),
72
+ };
73
+ const callbackManager_ = await CallbackManager.configure(runnableConfig.callbacks, this.callbacks, runnableConfig.tags, this.tags, inheritableMetadata, this.metadata, { verbose: this.verbose });
70
74
  const extra = {
71
75
  options: callOptions,
72
76
  invocation_params: this?.invocationParams(callOptions),
@@ -99,11 +103,21 @@ export class BaseChatModel extends BaseLanguageModel {
99
103
  })));
100
104
  }
101
105
  }
106
+ getLsParams(options) {
107
+ return {
108
+ ls_model_type: "chat",
109
+ ls_stop: options.stop,
110
+ };
111
+ }
102
112
  /** @ignore */
103
113
  async _generateUncached(messages, parsedOptions, handledOptions) {
104
114
  const baseMessages = messages.map((messageList) => messageList.map(coerceMessageLikeToMessage));
115
+ const inheritableMetadata = {
116
+ ...handledOptions.metadata,
117
+ ...this.getLsParams(parsedOptions),
118
+ };
105
119
  // create callback manager and start run
106
- const callbackManager_ = await CallbackManager.configure(handledOptions.callbacks, this.callbacks, handledOptions.tags, this.tags, handledOptions.metadata, this.metadata, { verbose: this.verbose });
120
+ const callbackManager_ = await CallbackManager.configure(handledOptions.callbacks, this.callbacks, handledOptions.tags, this.tags, inheritableMetadata, this.metadata, { verbose: this.verbose });
107
121
  const extra = {
108
122
  options: parsedOptions,
109
123
  invocation_params: this?.invocationParams(parsedOptions),
@@ -160,8 +174,12 @@ export class BaseChatModel extends BaseLanguageModel {
160
174
  }
161
175
  async _generateCached({ messages, cache, llmStringKey, parsedOptions, handledOptions, }) {
162
176
  const baseMessages = messages.map((messageList) => messageList.map(coerceMessageLikeToMessage));
177
+ const inheritableMetadata = {
178
+ ...handledOptions.metadata,
179
+ ...this.getLsParams(parsedOptions),
180
+ };
163
181
  // create callback manager and start run
164
- const callbackManager_ = await CallbackManager.configure(handledOptions.callbacks, this.callbacks, handledOptions.tags, this.tags, handledOptions.metadata, this.metadata, { verbose: this.verbose });
182
+ const callbackManager_ = await CallbackManager.configure(handledOptions.callbacks, this.callbacks, handledOptions.tags, this.tags, inheritableMetadata, this.metadata, { verbose: this.verbose });
165
183
  const extra = {
166
184
  options: parsedOptions,
167
185
  invocation_params: this?.invocationParams(parsedOptions),
@@ -0,0 +1 @@
1
+ export {};
@@ -0,0 +1,154 @@
1
+ /* eslint-disable no-promise-executor-return */
2
+ import { test } from "@jest/globals";
3
+ import { z } from "zod";
4
+ import { zodToJsonSchema } from "zod-to-json-schema";
5
+ import { FakeChatModel, FakeListChatModel } from "../../utils/testing/index.js";
6
+ test("Test ChatModel uses callbacks", async () => {
7
+ const model = new FakeChatModel({});
8
+ let acc = "";
9
+ const response = await model.invoke("Hello there!", {
10
+ callbacks: [
11
+ {
12
+ handleLLMNewToken: (token) => {
13
+ console.log(token);
14
+ acc += token;
15
+ },
16
+ },
17
+ ],
18
+ });
19
+ expect(response.content).toEqual(acc);
20
+ });
21
+ test("Test ChatModel uses callbacks with a cache", async () => {
22
+ const model = new FakeChatModel({
23
+ cache: true,
24
+ });
25
+ let acc = "";
26
+ const response = await model.invoke("Hello there!");
27
+ const response2 = await model.invoke("Hello there!", {
28
+ callbacks: [
29
+ {
30
+ handleLLMNewToken: (token) => {
31
+ console.log(token);
32
+ acc += token;
33
+ },
34
+ },
35
+ ],
36
+ });
37
+ // If callbacks are backgrounded
38
+ await new Promise((resolve) => setTimeout(resolve, 1000));
39
+ expect(response.content).toEqual(response2.content);
40
+ expect(response2.content).toEqual(acc);
41
+ });
42
+ test("Test ChatModel legacy params withStructuredOutput", async () => {
43
+ const model = new FakeListChatModel({
44
+ responses: [`{ "test": true, "nested": { "somethingelse": "somevalue" } }`],
45
+ }).withStructuredOutput({
46
+ includeRaw: false,
47
+ schema: z.object({
48
+ test: z.boolean(),
49
+ nested: z.object({
50
+ somethingelse: z.string(),
51
+ }),
52
+ }),
53
+ });
54
+ const response = await model.invoke("Hello there!");
55
+ // @ts-expect-error not in run output type
56
+ console.log(response.notthere);
57
+ console.log(response.nested.somethingelse);
58
+ expect(response).toEqual({
59
+ test: true,
60
+ nested: { somethingelse: "somevalue" },
61
+ });
62
+ });
63
+ // test("Test ChatModel legacy params includeRaw withStructuredOutput", async () => {
64
+ // const model = new FakeListChatModel({
65
+ // responses: [`{ "test": true, "nested": { "somethingelse": "somevalue" } }`],
66
+ // }).withStructuredOutput({
67
+ // includeRaw: true,
68
+ // schema: z.object({
69
+ // test: z.boolean(),
70
+ // nested: z.object({
71
+ // somethingelse: z.string(),
72
+ // }),
73
+ // }),
74
+ // });
75
+ // const response = await model.invoke("Hello there!");
76
+ // // @ts-expect-error legacy
77
+ // console.log(response.nested);
78
+ // console.log(response.parsed.nested);
79
+ // });
80
+ test("Test ChatModel withStructuredOutput with supplied type arg", async () => {
81
+ const model = new FakeListChatModel({
82
+ responses: [`{ "test": true, "nested": { "somethingelse": "somevalue" } }`],
83
+ }).withStructuredOutput({
84
+ includeRaw: false,
85
+ schema: z.object({
86
+ test: z.boolean(),
87
+ nested: z.object({
88
+ somethingelse: z.string(),
89
+ }),
90
+ }),
91
+ });
92
+ const response = await model.invoke("Hello there!");
93
+ // @ts-expect-error run output type forced to something else
94
+ console.log(response.nested.somethingelse);
95
+ // No error here
96
+ console.log(response.forcedArg);
97
+ expect(response).toEqual({
98
+ test: true,
99
+ nested: { somethingelse: "somevalue" },
100
+ });
101
+ });
102
+ test("Test ChatModel withStructuredOutput new syntax", async () => {
103
+ const model = new FakeListChatModel({
104
+ responses: [`{ "test": true, "nested": { "somethingelse": "somevalue" } }`],
105
+ }).withStructuredOutput(z.object({
106
+ test: z.boolean(),
107
+ nested: z.object({
108
+ somethingelse: z.string(),
109
+ }),
110
+ }));
111
+ const response = await model.invoke("Hello there!");
112
+ // @ts-expect-error run output type forced to something else
113
+ console.log(response.nested.somethingelse);
114
+ // No error here
115
+ console.log(response.forcedArg);
116
+ expect(response).toEqual({
117
+ test: true,
118
+ nested: { somethingelse: "somevalue" },
119
+ });
120
+ });
121
+ test("Test ChatModel withStructuredOutput new syntax and JSON schema", async () => {
122
+ const model = new FakeListChatModel({
123
+ responses: [`{ "test": true, "nested": { "somethingelse": "somevalue" } }`],
124
+ }).withStructuredOutput(zodToJsonSchema(z.object({
125
+ test: z.boolean(),
126
+ nested: z.object({
127
+ somethingelse: z.string(),
128
+ }),
129
+ })));
130
+ const response = await model.invoke("Hello there!");
131
+ // No error here
132
+ console.log(response.nested.somethingelse);
133
+ // Also no error here
134
+ console.log(response.forcedArg);
135
+ expect(response).toEqual({
136
+ test: true,
137
+ nested: { somethingelse: "somevalue" },
138
+ });
139
+ });
140
+ test("Test ChatModel withStructuredOutput new syntax and includeRaw", async () => {
141
+ const model = new FakeListChatModel({
142
+ responses: [`{ "test": true, "nested": { "somethingelse": "somevalue" } }`],
143
+ }).withStructuredOutput(z.object({
144
+ test: z.boolean(),
145
+ nested: z.object({
146
+ somethingelse: z.string(),
147
+ }),
148
+ }), { includeRaw: true });
149
+ const response = await model.invoke("Hello there!");
150
+ // @ts-expect-error run output includes raw
151
+ console.log(response.nested.somethingelse);
152
+ // No error
153
+ console.log(response.parsed);
154
+ });
@@ -0,0 +1 @@
1
+ export {};
@@ -0,0 +1,19 @@
1
+ import { test, expect } from "@jest/globals";
2
+ import { calculateMaxTokens, getModelContextSize } from "../base.js";
3
+ test("properly calculates correct max tokens", async () => {
4
+ expect(await calculateMaxTokens({ prompt: "", modelName: "gpt-3.5-turbo-16k" })).toBe(16384);
5
+ expect(await calculateMaxTokens({
6
+ prompt: "",
7
+ modelName: "gpt-3.5-turbo-16k-0613",
8
+ })).toBe(16384);
9
+ expect(await calculateMaxTokens({ prompt: "", modelName: "gpt-3.5-turbo" })).toBe(4096);
10
+ expect(await calculateMaxTokens({ prompt: "", modelName: "gpt-4" })).toBe(8192);
11
+ expect(await calculateMaxTokens({ prompt: "", modelName: "gpt-4-32k" })).toBe(32768);
12
+ });
13
+ test("properly gets model context size", async () => {
14
+ expect(await getModelContextSize("gpt-3.5-turbo-16k")).toBe(16384);
15
+ expect(await getModelContextSize("gpt-3.5-turbo-16k-0613")).toBe(16384);
16
+ expect(await getModelContextSize("gpt-3.5-turbo")).toBe(4096);
17
+ expect(await getModelContextSize("gpt-4")).toBe(8192);
18
+ expect(await getModelContextSize("gpt-4-32k")).toBe(32768);
19
+ });
@@ -0,0 +1 @@
1
+ export {};
@@ -0,0 +1,39 @@
1
+ /* eslint-disable no-promise-executor-return */
2
+ import { test } from "@jest/globals";
3
+ import { FakeLLM } from "../../utils/testing/index.js";
4
+ test("Test FakeLLM uses callbacks", async () => {
5
+ const model = new FakeLLM({});
6
+ let acc = "";
7
+ const response = await model.invoke("Hello there!", {
8
+ callbacks: [
9
+ {
10
+ handleLLMNewToken: (token) => {
11
+ console.log(token);
12
+ acc += token;
13
+ },
14
+ },
15
+ ],
16
+ });
17
+ expect(response).toEqual(acc);
18
+ });
19
+ test("Test FakeLLM uses callbacks with a cache", async () => {
20
+ const model = new FakeLLM({
21
+ cache: true,
22
+ });
23
+ let acc = "";
24
+ const response = await model.invoke("Hello there!");
25
+ const response2 = await model.invoke("Hello there!", {
26
+ callbacks: [
27
+ {
28
+ handleLLMNewToken: (token) => {
29
+ console.log(token);
30
+ acc += token;
31
+ },
32
+ },
33
+ ],
34
+ });
35
+ // If callbacks are backgrounded
36
+ await new Promise((resolve) => setTimeout(resolve, 1000));
37
+ expect(response).toEqual(response2);
38
+ expect(response2).toEqual(acc);
39
+ });
@@ -0,0 +1 @@
1
+ export {};
@@ -0,0 +1,97 @@
1
+ import { test } from "@jest/globals";
2
+ import { ChatPromptTemplate } from "../../prompts/chat.js";
3
+ import { HumanMessage, AIMessage, ToolMessage } from "../index.js";
4
+ import { load } from "../../load/index.js";
5
+ test("Test ChatPromptTemplate can format OpenAI content image messages", async () => {
6
+ const message = new HumanMessage({
7
+ content: [
8
+ {
9
+ type: "image_url",
10
+ image_url: {
11
+ url: `data:image/jpeg;base64,{image_string}`,
12
+ },
13
+ },
14
+ ],
15
+ });
16
+ const prompt = ChatPromptTemplate.fromMessages([
17
+ message,
18
+ ["ai", "Will this format with multiple messages?: {yes_or_no}"],
19
+ ]);
20
+ const formatted = await prompt.invoke({
21
+ image_string: "base_64_encoded_string",
22
+ yes_or_no: "YES!",
23
+ });
24
+ expect(formatted.messages[0].content[0]).toEqual({
25
+ type: "image_url",
26
+ image_url: {
27
+ url: "data:image/jpeg;base64,base_64_encoded_string",
28
+ },
29
+ });
30
+ expect(formatted.messages[1].content).toEqual("Will this format with multiple messages?: YES!");
31
+ });
32
+ test("Test ChatPromptTemplate can format OpenAI content image messages", async () => {
33
+ const message = new HumanMessage({
34
+ content: [
35
+ {
36
+ type: "image_url",
37
+ image_url: {
38
+ url: `data:image/jpeg;base64,{image_string}`,
39
+ },
40
+ },
41
+ ],
42
+ });
43
+ const prompt = ChatPromptTemplate.fromMessages([
44
+ message,
45
+ ["ai", "Will this format with multiple messages?: {yes_or_no}"],
46
+ ]);
47
+ const formatted = await prompt.invoke({
48
+ image_string: "base_64_encoded_string",
49
+ yes_or_no: "YES!",
50
+ });
51
+ expect(formatted.messages[0].content[0]).toEqual({
52
+ type: "image_url",
53
+ image_url: {
54
+ url: "data:image/jpeg;base64,base_64_encoded_string",
55
+ },
56
+ });
57
+ expect(formatted.messages[1].content).toEqual("Will this format with multiple messages?: YES!");
58
+ });
59
+ test("Deserialisation and serialisation of additional_kwargs and tool_call_id", async () => {
60
+ const config = {
61
+ importMap: { messages: { AIMessage } },
62
+ optionalImportEntrypoints: [],
63
+ optionalImportsMap: {},
64
+ secretsMap: {},
65
+ };
66
+ const message = new AIMessage({
67
+ content: "",
68
+ additional_kwargs: {
69
+ tool_calls: [
70
+ {
71
+ id: "call_tXJNP1S6LHT5tLfaNHCbYCtH",
72
+ type: "function",
73
+ function: {
74
+ name: "Weather",
75
+ arguments: '{\n "location": "Prague"\n}',
76
+ },
77
+ },
78
+ ],
79
+ },
80
+ });
81
+ const deserialized = await load(JSON.stringify(message), config);
82
+ expect(deserialized).toEqual(message);
83
+ });
84
+ test("Deserialisation and serialisation of tool_call_id", async () => {
85
+ const config = {
86
+ importMap: { messages: { ToolMessage } },
87
+ optionalImportEntrypoints: [],
88
+ optionalImportsMap: {},
89
+ secretsMap: {},
90
+ };
91
+ const message = new ToolMessage({
92
+ content: '{"value": 32}',
93
+ tool_call_id: "call_tXJNP1S6LHT5tLfaNHCbYCtH",
94
+ });
95
+ const deserialized = await load(JSON.stringify(message), config);
96
+ expect(deserialized).toEqual(message);
97
+ });
@@ -0,0 +1,81 @@
1
+ import { test } from "@jest/globals";
2
+ import { z } from "zod";
3
+ import { JsonOutputKeyToolsParser } from "../json_output_tools_parsers.js";
4
+ import { AIMessage } from "../../../messages/index.js";
5
+ import { OutputParserException } from "../../base.js";
6
+ test("JSONOutputKeyToolsParser invoke", async () => {
7
+ const outputParser = new JsonOutputKeyToolsParser({
8
+ keyName: "testing",
9
+ returnSingle: true,
10
+ });
11
+ const result = await outputParser.invoke(new AIMessage({
12
+ content: "",
13
+ additional_kwargs: {
14
+ tool_calls: [
15
+ {
16
+ id: "test",
17
+ type: "function",
18
+ function: {
19
+ name: "testing",
20
+ arguments: JSON.stringify({ testKey: 9 }),
21
+ },
22
+ },
23
+ ],
24
+ },
25
+ }));
26
+ expect(result).toEqual({ testKey: 9 });
27
+ });
28
+ test("JSONOutputKeyToolsParser with a passed schema throws", async () => {
29
+ const outputParser = new JsonOutputKeyToolsParser({
30
+ keyName: "testing",
31
+ returnSingle: true,
32
+ zodSchema: z.object({
33
+ testKey: z.string(),
34
+ }),
35
+ });
36
+ try {
37
+ await outputParser.invoke(new AIMessage({
38
+ content: "",
39
+ additional_kwargs: {
40
+ tool_calls: [
41
+ {
42
+ id: "test",
43
+ type: "function",
44
+ function: {
45
+ name: "testing",
46
+ arguments: JSON.stringify({ testKey: 9 }),
47
+ },
48
+ },
49
+ ],
50
+ },
51
+ }));
52
+ }
53
+ catch (e) {
54
+ expect(e).toBeInstanceOf(OutputParserException);
55
+ }
56
+ });
57
+ test("JSONOutputKeyToolsParser can validate a proper input", async () => {
58
+ const outputParser = new JsonOutputKeyToolsParser({
59
+ keyName: "testing",
60
+ returnSingle: true,
61
+ zodSchema: z.object({
62
+ testKey: z.string(),
63
+ }),
64
+ });
65
+ const result = await outputParser.invoke(new AIMessage({
66
+ content: "",
67
+ additional_kwargs: {
68
+ tool_calls: [
69
+ {
70
+ id: "test",
71
+ type: "function",
72
+ function: {
73
+ name: "testing",
74
+ arguments: JSON.stringify({ testKey: "testval" }),
75
+ },
76
+ },
77
+ ],
78
+ },
79
+ }));
80
+ expect(result).toEqual({ testKey: "testval" });
81
+ });
@@ -0,0 +1 @@
1
+ export {};