@langchain/core 0.2.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 (113) hide show
  1. package/dist/callbacks/tests/callbacks.test.d.ts +1 -0
  2. package/dist/callbacks/tests/callbacks.test.js +492 -0
  3. package/dist/callbacks/tests/manager.int.test.d.ts +1 -0
  4. package/dist/callbacks/tests/manager.int.test.js +29 -0
  5. package/dist/callbacks/tests/run_collector.test.d.ts +1 -0
  6. package/dist/callbacks/tests/run_collector.test.js +58 -0
  7. package/dist/chat_history.cjs +13 -0
  8. package/dist/chat_history.d.ts +9 -0
  9. package/dist/chat_history.js +13 -0
  10. package/dist/language_models/chat_models.d.ts +2 -2
  11. package/dist/language_models/tests/chat_models.test.d.ts +1 -0
  12. package/dist/language_models/tests/chat_models.test.js +154 -0
  13. package/dist/language_models/tests/count_tokens.test.d.ts +1 -0
  14. package/dist/language_models/tests/count_tokens.test.js +19 -0
  15. package/dist/language_models/tests/llms.test.d.ts +1 -0
  16. package/dist/language_models/tests/llms.test.js +39 -0
  17. package/dist/messages/tests/base_message.test.d.ts +1 -0
  18. package/dist/messages/tests/base_message.test.js +97 -0
  19. package/dist/output_parsers/openai_tools/tests/json_output_tools_parser.test.d.ts +1 -0
  20. package/dist/output_parsers/openai_tools/tests/json_output_tools_parser.test.js +81 -0
  21. package/dist/output_parsers/tests/json.test.d.ts +1 -0
  22. package/dist/output_parsers/tests/json.test.js +427 -0
  23. package/dist/output_parsers/tests/output_parser.test.d.ts +1 -0
  24. package/dist/output_parsers/tests/output_parser.test.js +78 -0
  25. package/dist/output_parsers/tests/string.test.d.ts +1 -0
  26. package/dist/output_parsers/tests/string.test.js +68 -0
  27. package/dist/output_parsers/tests/structured.test.d.ts +1 -0
  28. package/dist/output_parsers/tests/structured.test.js +166 -0
  29. package/dist/output_parsers/tests/xml.test.d.ts +1 -0
  30. package/dist/output_parsers/tests/xml.test.js +81 -0
  31. package/dist/prompts/tests/chat.mustache.test.d.ts +1 -0
  32. package/dist/prompts/tests/chat.mustache.test.js +61 -0
  33. package/dist/prompts/tests/chat.test.d.ts +1 -0
  34. package/dist/prompts/tests/chat.test.js +507 -0
  35. package/dist/prompts/tests/few_shot.test.d.ts +1 -0
  36. package/dist/prompts/tests/few_shot.test.js +224 -0
  37. package/dist/prompts/tests/pipeline.test.d.ts +1 -0
  38. package/dist/prompts/tests/pipeline.test.js +101 -0
  39. package/dist/prompts/tests/prompt.mustache.test.d.ts +1 -0
  40. package/dist/prompts/tests/prompt.mustache.test.js +85 -0
  41. package/dist/prompts/tests/prompt.test.d.ts +1 -0
  42. package/dist/prompts/tests/prompt.test.js +78 -0
  43. package/dist/prompts/tests/structured.test.d.ts +1 -0
  44. package/dist/prompts/tests/structured.test.js +37 -0
  45. package/dist/prompts/tests/template.test.d.ts +1 -0
  46. package/dist/prompts/tests/template.test.js +24 -0
  47. package/dist/runnables/base.cjs +87 -6
  48. package/dist/runnables/base.d.ts +45 -26
  49. package/dist/runnables/base.js +87 -6
  50. package/dist/runnables/history.cjs +87 -32
  51. package/dist/runnables/history.d.ts +1 -1
  52. package/dist/runnables/history.js +87 -32
  53. package/dist/runnables/remote.cjs +2 -2
  54. package/dist/runnables/remote.d.ts +3 -3
  55. package/dist/runnables/remote.js +2 -2
  56. package/dist/runnables/tests/runnable.test.d.ts +1 -0
  57. package/dist/runnables/tests/runnable.test.js +491 -0
  58. package/dist/runnables/tests/runnable_binding.test.d.ts +1 -0
  59. package/dist/runnables/tests/runnable_binding.test.js +46 -0
  60. package/dist/runnables/tests/runnable_branch.test.d.ts +1 -0
  61. package/dist/runnables/tests/runnable_branch.test.js +116 -0
  62. package/dist/runnables/tests/runnable_graph.test.d.ts +1 -0
  63. package/dist/runnables/tests/runnable_graph.test.js +84 -0
  64. package/dist/runnables/tests/runnable_history.test.d.ts +1 -0
  65. package/dist/runnables/tests/runnable_history.test.js +177 -0
  66. package/dist/runnables/tests/runnable_interface.test.d.ts +1 -0
  67. package/dist/runnables/tests/runnable_interface.test.js +209 -0
  68. package/dist/runnables/tests/runnable_map.test.d.ts +1 -0
  69. package/dist/runnables/tests/runnable_map.test.js +238 -0
  70. package/dist/runnables/tests/runnable_passthrough.test.d.ts +1 -0
  71. package/dist/runnables/tests/runnable_passthrough.test.js +96 -0
  72. package/dist/runnables/tests/runnable_remote.int.test.d.ts +1 -0
  73. package/dist/runnables/tests/runnable_remote.int.test.js +138 -0
  74. package/dist/runnables/tests/runnable_remote.test.d.ts +1 -0
  75. package/dist/runnables/tests/runnable_remote.test.js +200 -0
  76. package/dist/runnables/tests/runnable_retry.test.d.ts +1 -0
  77. package/dist/runnables/tests/runnable_retry.test.js +125 -0
  78. package/dist/runnables/tests/runnable_stream_events.test.d.ts +1 -0
  79. package/dist/runnables/tests/runnable_stream_events.test.js +1013 -0
  80. package/dist/runnables/tests/runnable_stream_events_v2.test.d.ts +1 -0
  81. package/dist/runnables/tests/runnable_stream_events_v2.test.js +973 -0
  82. package/dist/runnables/tests/runnable_stream_log.test.d.ts +1 -0
  83. package/dist/runnables/tests/runnable_stream_log.test.js +282 -0
  84. package/dist/runnables/tests/runnable_tracing.int.test.d.ts +1 -0
  85. package/dist/runnables/tests/runnable_tracing.int.test.js +37 -0
  86. package/dist/runnables/tests/runnable_with_fallbacks.test.d.ts +1 -0
  87. package/dist/runnables/tests/runnable_with_fallbacks.test.js +36 -0
  88. package/dist/runnables/utils.d.ts +1 -1
  89. package/dist/singletons/tests/async_local_storage.test.d.ts +1 -0
  90. package/dist/singletons/tests/async_local_storage.test.js +120 -0
  91. package/dist/structured_query/tests/utils.test.d.ts +1 -0
  92. package/dist/structured_query/tests/utils.test.js +47 -0
  93. package/dist/tracers/event_stream.cjs +493 -0
  94. package/dist/tracers/event_stream.d.ts +137 -0
  95. package/dist/tracers/event_stream.js +489 -0
  96. package/dist/tracers/log_stream.d.ts +2 -77
  97. package/dist/tracers/tests/langchain_tracer.int.test.d.ts +1 -0
  98. package/dist/tracers/tests/langchain_tracer.int.test.js +74 -0
  99. package/dist/tracers/tests/tracer.test.d.ts +1 -0
  100. package/dist/tracers/tests/tracer.test.js +378 -0
  101. package/dist/utils/testing/tests/chatfake.test.d.ts +1 -0
  102. package/dist/utils/testing/tests/chatfake.test.js +112 -0
  103. package/dist/utils/tests/async_caller.test.d.ts +1 -0
  104. package/dist/utils/tests/async_caller.test.js +27 -0
  105. package/dist/utils/tests/enviroment.test.d.ts +1 -0
  106. package/dist/utils/tests/enviroment.test.js +6 -0
  107. package/dist/utils/tests/function_calling.test.d.ts +1 -0
  108. package/dist/utils/tests/function_calling.test.js +107 -0
  109. package/dist/utils/tests/math_utils.test.d.ts +1 -0
  110. package/dist/utils/tests/math_utils.test.js +139 -0
  111. package/dist/utils/tests/polyfill_stream.test.d.ts +1 -0
  112. package/dist/utils/tests/polyfill_stream.test.js +15 -0
  113. package/package.json +6 -6
@@ -0,0 +1,224 @@
1
+ import { expect, test } from "@jest/globals";
2
+ import { FewShotChatMessagePromptTemplate, FewShotPromptTemplate, } from "../few_shot.js";
3
+ import { ChatPromptTemplate } from "../index.js";
4
+ import { PromptTemplate } from "../prompt.js";
5
+ import { LengthBasedExampleSelector } from "../../example_selectors/length_based.js";
6
+ import { AIMessage, HumanMessage } from "../../messages/index.js";
7
+ describe("FewShotPromptTemplate", () => {
8
+ test("Test using partial", async () => {
9
+ const examplePrompt = PromptTemplate.fromTemplate("{foo}{bar}");
10
+ const prompt = new FewShotPromptTemplate({
11
+ prefix: "{foo}{bar}",
12
+ examples: [],
13
+ suffix: "",
14
+ templateFormat: "f-string",
15
+ exampleSeparator: "\n",
16
+ examplePrompt,
17
+ inputVariables: ["foo"],
18
+ partialVariables: { bar: "baz" },
19
+ });
20
+ expect(await prompt.format({ foo: "foo" })).toBe("foobaz\n");
21
+ });
22
+ test("Test using full partial", async () => {
23
+ const examplePrompt = PromptTemplate.fromTemplate("{foo}{bar}");
24
+ const prompt = new FewShotPromptTemplate({
25
+ prefix: "{foo}{bar}",
26
+ examples: [],
27
+ suffix: "",
28
+ templateFormat: "f-string",
29
+ exampleSeparator: "\n",
30
+ examplePrompt,
31
+ inputVariables: [],
32
+ partialVariables: { bar: "baz", foo: "boo" },
33
+ });
34
+ expect(await prompt.format({})).toBe("boobaz\n");
35
+ });
36
+ test("Test partial with string", async () => {
37
+ const examplePrompt = PromptTemplate.fromTemplate("{foo}{bar}");
38
+ const prompt = new FewShotPromptTemplate({
39
+ prefix: "{foo}{bar}",
40
+ examples: [],
41
+ suffix: "",
42
+ templateFormat: "f-string",
43
+ exampleSeparator: "\n",
44
+ examplePrompt,
45
+ inputVariables: ["foo", "bar"],
46
+ });
47
+ const partialPrompt = await prompt.partial({ foo: "foo" });
48
+ expect(await partialPrompt.format({ bar: "baz" })).toBe("foobaz\n");
49
+ expect(prompt.inputVariables).toEqual(["foo", "bar"]);
50
+ });
51
+ test("Test partial with function", async () => {
52
+ const examplePrompt = PromptTemplate.fromTemplate("{foo}{bar}");
53
+ const prompt = new FewShotPromptTemplate({
54
+ prefix: "{foo}{bar}",
55
+ examples: [],
56
+ suffix: "",
57
+ templateFormat: "f-string",
58
+ exampleSeparator: "\n",
59
+ examplePrompt,
60
+ inputVariables: ["foo", "bar"],
61
+ });
62
+ const partialPrompt = await prompt.partial({
63
+ foo: () => Promise.resolve("boo"),
64
+ });
65
+ expect(await partialPrompt.format({ bar: "baz" })).toBe("boobaz\n");
66
+ });
67
+ test("Test partial with function and examples", async () => {
68
+ const examplePrompt = PromptTemplate.fromTemplate("An example about {x}");
69
+ const prompt = new FewShotPromptTemplate({
70
+ prefix: "{foo}{bar}",
71
+ examples: [{ x: "foo" }, { x: "bar" }],
72
+ suffix: "",
73
+ templateFormat: "f-string",
74
+ exampleSeparator: "\n",
75
+ examplePrompt,
76
+ inputVariables: ["foo", "bar"],
77
+ });
78
+ const partialPrompt = await prompt.partial({
79
+ foo: () => Promise.resolve("boo"),
80
+ });
81
+ expect(await partialPrompt.format({ bar: "baz" })).toBe(`boobaz
82
+ An example about foo
83
+ An example about bar
84
+ `);
85
+ });
86
+ test("Test partial with function and example selector", async () => {
87
+ const examplePrompt = PromptTemplate.fromTemplate("An example about {x}");
88
+ const exampleSelector = await LengthBasedExampleSelector.fromExamples([{ x: "foo" }, { x: "bar" }], { examplePrompt, maxLength: 200 });
89
+ const prompt = new FewShotPromptTemplate({
90
+ prefix: "{foo}{bar}",
91
+ exampleSelector,
92
+ suffix: "",
93
+ templateFormat: "f-string",
94
+ exampleSeparator: "\n",
95
+ examplePrompt,
96
+ inputVariables: ["foo", "bar"],
97
+ });
98
+ const partialPrompt = await prompt.partial({
99
+ foo: () => Promise.resolve("boo"),
100
+ });
101
+ expect(await partialPrompt.format({ bar: "baz" })).toBe(`boobaz
102
+ An example about foo
103
+ An example about bar
104
+ `);
105
+ });
106
+ });
107
+ describe("FewShotChatMessagePromptTemplate", () => {
108
+ test("Format messages", async () => {
109
+ const examplePrompt = ChatPromptTemplate.fromMessages([
110
+ ["ai", "{ai_input_var}"],
111
+ ["human", "{human_input_var}"],
112
+ ]);
113
+ const examples = [
114
+ {
115
+ ai_input_var: "ai-foo",
116
+ human_input_var: "human-bar",
117
+ },
118
+ {
119
+ ai_input_var: "ai-foo2",
120
+ human_input_var: "human-bar2",
121
+ },
122
+ ];
123
+ const prompt = new FewShotChatMessagePromptTemplate({
124
+ examplePrompt,
125
+ inputVariables: ["ai_input_var", "human_input_var"],
126
+ examples,
127
+ });
128
+ const messages = await prompt.formatMessages({});
129
+ expect(messages).toEqual([
130
+ new AIMessage("ai-foo"),
131
+ new HumanMessage("human-bar"),
132
+ new AIMessage("ai-foo2"),
133
+ new HumanMessage("human-bar2"),
134
+ ]);
135
+ });
136
+ test("Test using partial", async () => {
137
+ const examplePrompt = ChatPromptTemplate.fromMessages([
138
+ ["ai", "{foo}{bar}"],
139
+ ]);
140
+ const prompt = new FewShotChatMessagePromptTemplate({
141
+ prefix: "{foo}{bar}",
142
+ examples: [],
143
+ suffix: "",
144
+ templateFormat: "f-string",
145
+ exampleSeparator: "\n",
146
+ examplePrompt,
147
+ inputVariables: ["foo"],
148
+ partialVariables: { bar: "baz" },
149
+ });
150
+ expect(await prompt.format({ foo: "foo" })).toBe("foobaz\n");
151
+ });
152
+ test("Test using full partial", async () => {
153
+ const examplePrompt = ChatPromptTemplate.fromMessages([
154
+ ["ai", "{foo}{bar}"],
155
+ ]);
156
+ const prompt = new FewShotChatMessagePromptTemplate({
157
+ prefix: "{foo}{bar}",
158
+ examples: [],
159
+ suffix: "",
160
+ templateFormat: "f-string",
161
+ exampleSeparator: "\n",
162
+ examplePrompt,
163
+ inputVariables: [],
164
+ partialVariables: { bar: "baz", foo: "boo" },
165
+ });
166
+ expect(await prompt.format({})).toBe("boobaz\n");
167
+ });
168
+ test("Test partial with string", async () => {
169
+ const examplePrompt = ChatPromptTemplate.fromMessages([
170
+ ["ai", "{foo}{bar}"],
171
+ ]);
172
+ const prompt = new FewShotChatMessagePromptTemplate({
173
+ prefix: "{foo}{bar}",
174
+ examples: [],
175
+ suffix: "",
176
+ templateFormat: "f-string",
177
+ exampleSeparator: "\n",
178
+ examplePrompt,
179
+ inputVariables: ["foo", "bar"],
180
+ });
181
+ const partialPrompt = await prompt.partial({ foo: "foo" });
182
+ expect(await partialPrompt.format({ bar: "baz" })).toBe("foobaz\n");
183
+ expect(prompt.inputVariables).toEqual(["foo", "bar"]);
184
+ });
185
+ test("Test partial with function", async () => {
186
+ const examplePrompt = ChatPromptTemplate.fromMessages([
187
+ ["ai", "{foo}{bar}"],
188
+ ]);
189
+ const prompt = new FewShotChatMessagePromptTemplate({
190
+ prefix: "{foo}{bar}",
191
+ examples: [],
192
+ suffix: "",
193
+ templateFormat: "f-string",
194
+ exampleSeparator: "\n",
195
+ examplePrompt,
196
+ inputVariables: ["foo", "bar"],
197
+ });
198
+ const partialPrompt = await prompt.partial({
199
+ foo: () => Promise.resolve("boo"),
200
+ });
201
+ expect(await partialPrompt.format({ bar: "baz" })).toBe("boobaz\n");
202
+ });
203
+ test("Test partial with function and examples", async () => {
204
+ const examplePrompt = ChatPromptTemplate.fromMessages([
205
+ ["ai", "An example about {x}"],
206
+ ]);
207
+ const prompt = new FewShotChatMessagePromptTemplate({
208
+ prefix: "{foo}{bar}",
209
+ examples: [{ x: "foo" }, { x: "bar" }],
210
+ suffix: "",
211
+ templateFormat: "f-string",
212
+ exampleSeparator: "\n",
213
+ examplePrompt,
214
+ inputVariables: ["foo", "bar"],
215
+ });
216
+ const partialPrompt = await prompt.partial({
217
+ foo: () => Promise.resolve("boo"),
218
+ });
219
+ expect(await partialPrompt.format({ bar: "baz" })).toBe(`boobaz
220
+ An example about foo
221
+ An example about bar
222
+ `);
223
+ });
224
+ });
@@ -0,0 +1 @@
1
+ export {};
@@ -0,0 +1,101 @@
1
+ import { expect, test } from "@jest/globals";
2
+ import { PromptTemplate } from "../prompt.js";
3
+ import { ChatPromptTemplate, HumanMessagePromptTemplate, MessagesPlaceholder, SystemMessagePromptTemplate, } from "../chat.js";
4
+ import { PipelinePromptTemplate } from "../pipeline.js";
5
+ test("Test pipeline input variables", async () => {
6
+ const prompt = new PipelinePromptTemplate({
7
+ pipelinePrompts: [
8
+ {
9
+ name: "bar",
10
+ prompt: PromptTemplate.fromTemplate("{foo}"),
11
+ },
12
+ ],
13
+ finalPrompt: PromptTemplate.fromTemplate("{bar}"),
14
+ });
15
+ expect(prompt.inputVariables).toEqual(["foo"]);
16
+ });
17
+ test("Test simple pipeline", async () => {
18
+ const prompt = new PipelinePromptTemplate({
19
+ pipelinePrompts: [
20
+ {
21
+ name: "bar",
22
+ prompt: PromptTemplate.fromTemplate("{foo}"),
23
+ },
24
+ ],
25
+ finalPrompt: PromptTemplate.fromTemplate("{bar}"),
26
+ });
27
+ expect(await prompt.format({
28
+ foo: "jim",
29
+ })).toEqual("jim");
30
+ });
31
+ test("Test multi variable pipeline", async () => {
32
+ const prompt = new PipelinePromptTemplate({
33
+ pipelinePrompts: [
34
+ {
35
+ name: "bar",
36
+ prompt: PromptTemplate.fromTemplate("{foo}"),
37
+ },
38
+ ],
39
+ finalPrompt: PromptTemplate.fromTemplate("okay {bar} {baz}"),
40
+ });
41
+ expect(await prompt.format({
42
+ foo: "jim",
43
+ baz: "halpert",
44
+ })).toEqual("okay jim halpert");
45
+ });
46
+ test("Test longer pipeline", async () => {
47
+ const prompt = new PipelinePromptTemplate({
48
+ pipelinePrompts: [
49
+ {
50
+ name: "bar",
51
+ prompt: PromptTemplate.fromTemplate("{foo}"),
52
+ },
53
+ {
54
+ name: "qux",
55
+ prompt: PromptTemplate.fromTemplate("hi {bar}"),
56
+ },
57
+ ],
58
+ finalPrompt: PromptTemplate.fromTemplate("okay {qux} {baz}"),
59
+ });
60
+ expect(await prompt.format({
61
+ foo: "pam",
62
+ baz: "beasley",
63
+ })).toEqual("okay hi pam beasley");
64
+ });
65
+ test("Test with .partial", async () => {
66
+ const prompt = new PipelinePromptTemplate({
67
+ pipelinePrompts: [
68
+ {
69
+ name: "bar",
70
+ prompt: PromptTemplate.fromTemplate("{foo}"),
71
+ },
72
+ ],
73
+ finalPrompt: PromptTemplate.fromTemplate("okay {bar} {baz}"),
74
+ });
75
+ const partialPrompt = await prompt.partial({
76
+ baz: "schrute",
77
+ });
78
+ expect(await partialPrompt.format({
79
+ foo: "dwight",
80
+ })).toEqual("okay dwight schrute");
81
+ });
82
+ test("Test with chat prompts", async () => {
83
+ const prompt = new PipelinePromptTemplate({
84
+ pipelinePrompts: [
85
+ {
86
+ name: "foo",
87
+ prompt: ChatPromptTemplate.fromMessages([
88
+ HumanMessagePromptTemplate.fromTemplate(`{name} halpert`),
89
+ ]),
90
+ },
91
+ ],
92
+ finalPrompt: ChatPromptTemplate.fromMessages([
93
+ SystemMessagePromptTemplate.fromTemplate("What is your name?"),
94
+ new MessagesPlaceholder("foo"),
95
+ ]),
96
+ });
97
+ const formattedPromptValue = await prompt.formatPromptValue({
98
+ name: "pam",
99
+ });
100
+ expect(formattedPromptValue.messages[1].content).toEqual("pam halpert");
101
+ });
@@ -0,0 +1 @@
1
+ export {};
@@ -0,0 +1,85 @@
1
+ import { test, expect } from "@jest/globals";
2
+ import { PromptTemplate } from "../prompt.js";
3
+ test("Single input variable.", async () => {
4
+ const template = "This is a {{foo}} test.";
5
+ const prompt = PromptTemplate.fromTemplate(template, {
6
+ templateFormat: "mustache",
7
+ });
8
+ const formattedPrompt = await prompt.format({ foo: "bar" });
9
+ expect(formattedPrompt).toBe("This is a bar test.");
10
+ expect(prompt.inputVariables).toEqual(["foo"]);
11
+ });
12
+ test("Multiple input variables.", async () => {
13
+ const template = "This {{bar}} is a {{foo}} test.";
14
+ const prompt = PromptTemplate.fromTemplate(template, {
15
+ templateFormat: "mustache",
16
+ });
17
+ const formattedPrompt = await prompt.format({ bar: "baz", foo: "bar" });
18
+ expect(formattedPrompt).toBe("This baz is a bar test.");
19
+ expect(prompt.inputVariables).toEqual(["bar", "foo"]);
20
+ });
21
+ test("Multiple input variables with repeats.", async () => {
22
+ const template = "This {{bar}} is a {{foo}} test {{foo}}.";
23
+ const prompt = PromptTemplate.fromTemplate(template, {
24
+ templateFormat: "mustache",
25
+ });
26
+ const formattedPrompt = await prompt.format({ bar: "baz", foo: "bar" });
27
+ expect(formattedPrompt).toBe("This baz is a bar test bar.");
28
+ expect(prompt.inputVariables).toEqual(["bar", "foo"]);
29
+ });
30
+ test("Ignores f-string inputs input variables with repeats.", async () => {
31
+ const template = "This {bar} is a {foo} test {foo}.";
32
+ const prompt = PromptTemplate.fromTemplate(template, {
33
+ templateFormat: "mustache",
34
+ });
35
+ const formattedPrompt = await prompt.format({ bar: "baz", foo: "bar" });
36
+ expect(formattedPrompt).toBe("This {bar} is a {foo} test {foo}.");
37
+ expect(prompt.inputVariables).toEqual([]);
38
+ });
39
+ test("Nested variables.", async () => {
40
+ const template = "This {{obj.bar}} is a {{obj.foo}} test {{foo.bar.baz}}. Single: {{single}}";
41
+ const prompt = PromptTemplate.fromTemplate(template, {
42
+ templateFormat: "mustache",
43
+ });
44
+ const formattedPrompt = await prompt.format({
45
+ obj: { bar: "foo", foo: "bar" },
46
+ foo: {
47
+ bar: {
48
+ baz: "baz",
49
+ },
50
+ },
51
+ single: "one",
52
+ });
53
+ expect(formattedPrompt).toBe("This foo is a bar test baz. Single: one");
54
+ expect(prompt.inputVariables).toEqual(["obj", "foo", "single"]);
55
+ });
56
+ test("section/context variables", async () => {
57
+ const template = `This{{#foo}}
58
+ {{bar}}
59
+ {{/foo}}is a test.`;
60
+ const prompt = PromptTemplate.fromTemplate(template, {
61
+ templateFormat: "mustache",
62
+ });
63
+ const formattedPrompt = await prompt.format({ foo: { bar: "yo" } });
64
+ expect(formattedPrompt).toEqual(`This
65
+ yo
66
+ is a test.`);
67
+ expect(prompt.inputVariables).toEqual(["foo"]);
68
+ });
69
+ test("section/context variables with repeats", async () => {
70
+ const template = `This{{#foo}}
71
+ {{bar}}
72
+ {{/foo}}is a test.`;
73
+ const promptWithRepeats = PromptTemplate.fromTemplate(template, {
74
+ templateFormat: "mustache",
75
+ });
76
+ const formattedPrompt = await promptWithRepeats.format({
77
+ foo: [{ bar: "yo" }, { bar: "hello" }],
78
+ });
79
+ expect(formattedPrompt).toEqual(`This
80
+ yo
81
+
82
+ hello
83
+ is a test.`);
84
+ expect(promptWithRepeats.inputVariables).toEqual(["foo"]);
85
+ });
@@ -0,0 +1 @@
1
+ export {};
@@ -0,0 +1,78 @@
1
+ import { expect, test } from "@jest/globals";
2
+ import { PromptTemplate } from "../prompt.js";
3
+ test("Test using partial", async () => {
4
+ const prompt = new PromptTemplate({
5
+ template: "{foo}{bar}",
6
+ inputVariables: ["foo"],
7
+ partialVariables: { bar: "baz" },
8
+ });
9
+ expect(await prompt.format({ foo: "foo" })).toBe("foobaz");
10
+ });
11
+ test("Test using partial with an extra variable", async () => {
12
+ const prompt = new PromptTemplate({
13
+ template: "{foo}{bar}",
14
+ inputVariables: ["foo"],
15
+ partialVariables: { bar: "baz" },
16
+ });
17
+ expect(await prompt.format({ foo: "foo", unused: "nada" })).toBe("foobaz");
18
+ });
19
+ test("Test fromTemplate", async () => {
20
+ const prompt = PromptTemplate.fromTemplate("{foo}{bar}");
21
+ expect((await prompt.invoke({ foo: "foo", bar: "baz", unused: "eee" })).value).toBe("foobaz");
22
+ });
23
+ test("Test fromTemplate with escaped strings", async () => {
24
+ const prompt = PromptTemplate.fromTemplate("{{foo}}{{bar}}");
25
+ expect(await prompt.format({ unused: "eee" })).toBe("{foo}{bar}");
26
+ });
27
+ test("Test fromTemplate with type parameter", async () => {
28
+ const prompt = PromptTemplate.fromTemplate("test");
29
+ // @ts-expect-error TS compiler should flag
30
+ expect(await prompt.format({ unused: "eee" })).toBe("test");
31
+ });
32
+ test("Test fromTemplate with missing variable should raise compiler error", async () => {
33
+ const prompt = PromptTemplate.fromTemplate("{foo}");
34
+ await expect(async () => {
35
+ // @ts-expect-error TS compiler should flag missing variable
36
+ await prompt.format({ unused: "eee" });
37
+ }).rejects.toThrow();
38
+ await expect(async () => {
39
+ // @ts-expect-error TS compiler should flag missing variable
40
+ await prompt.invoke({ unused: "eee" });
41
+ }).rejects.toThrow();
42
+ });
43
+ test("Test fromTemplate with extra variable should work", async () => {
44
+ const prompt = PromptTemplate.fromTemplate("{foo}");
45
+ expect(await prompt.format({ foo: "test", unused: "eee" })).toBe("test");
46
+ expect((await prompt.invoke({ foo: "test", unused: "eee" })).value).toBe("test");
47
+ });
48
+ test("Test using full partial", async () => {
49
+ const prompt = new PromptTemplate({
50
+ template: "{foo}{bar}",
51
+ inputVariables: [],
52
+ partialVariables: { bar: "baz", foo: "boo" },
53
+ });
54
+ expect(await prompt.format({})).toBe("boobaz");
55
+ });
56
+ test("Test partial", async () => {
57
+ const prompt = new PromptTemplate({
58
+ template: "{foo}{bar}",
59
+ inputVariables: ["foo", "bar"],
60
+ });
61
+ expect(prompt.inputVariables).toEqual(["foo", "bar"]);
62
+ const partialPrompt = await prompt.partial({ foo: "foo" });
63
+ // original prompt is not modified
64
+ expect(prompt.inputVariables).toEqual(["foo", "bar"]);
65
+ // partial prompt has only remaining variables
66
+ expect(partialPrompt.inputVariables).toEqual(["bar"]);
67
+ expect(await partialPrompt.format({ bar: "baz" })).toBe("foobaz");
68
+ });
69
+ test("Test partial with function", async () => {
70
+ const prompt = new PromptTemplate({
71
+ template: "{foo}{bar}",
72
+ inputVariables: ["foo", "bar"],
73
+ });
74
+ const partialPrompt = await prompt.partial({
75
+ foo: () => Promise.resolve("boo"),
76
+ });
77
+ expect(await partialPrompt.format({ bar: "baz" })).toBe("boobaz");
78
+ });
@@ -0,0 +1 @@
1
+ export {};
@@ -0,0 +1,37 @@
1
+ import { RunnableLambda } from "../../runnables/base.js";
2
+ import { FakeListChatModel } from "../../utils/testing/index.js";
3
+ import { StructuredPrompt } from "../structured.js";
4
+ import { load } from "../../load/index.js";
5
+ class FakeStructuredChatModel extends FakeListChatModel {
6
+ withStructuredOutput(_params, _config) {
7
+ if (!_config?.includeRaw) {
8
+ if (typeof _params === "object") {
9
+ const func = RunnableLambda.from((_) => _params);
10
+ return func;
11
+ }
12
+ }
13
+ throw new Error("Invalid schema");
14
+ }
15
+ }
16
+ test("Test format", async () => {
17
+ const schema = {
18
+ name: "yo",
19
+ description: "a structured output",
20
+ parameters: {
21
+ name: { type: "string" },
22
+ value: { type: "integer" },
23
+ },
24
+ };
25
+ const prompt = StructuredPrompt.fromMessagesAndSchema([["human", "I'm very structured, how about you?"]], schema);
26
+ const model = new FakeStructuredChatModel({ responses: [] });
27
+ const chain = prompt.pipe(model);
28
+ await chain.invoke({});
29
+ await expect(chain.invoke({})).resolves.toEqual(schema);
30
+ const revived = await load(JSON.stringify(prompt));
31
+ expect(JSON.stringify(prompt)).toEqual('{"lc":1,"type":"constructor","id":["langchain_core","prompts","structured","StructuredPrompt"],"kwargs":{"schema_":{"name":"yo","description":"a structured output","parameters":{"name":{"type":"string"},"value":{"type":"integer"}}},"input_variables":[],"messages":[{"lc":1,"type":"constructor","id":["langchain_core","prompts","chat","HumanMessagePromptTemplate"],"kwargs":{"prompt":{"lc":1,"type":"constructor","id":["langchain_core","prompts","prompt","PromptTemplate"],"kwargs":{"input_variables":[],"template_format":"f-string","template":"I\'m very structured, how about you?","schema":{"name":"yo","description":"a structured output","parameters":{"name":{"type":"string"},"value":{"type":"integer"}}}}}}}]}}');
32
+ const revivedChain = revived.pipe(model);
33
+ await expect(revivedChain.invoke({})).resolves.toEqual(schema);
34
+ const boundModel = model.bind({ runName: "boundModel" });
35
+ const chainWithBoundModel = prompt.pipe(boundModel);
36
+ await expect(chainWithBoundModel.invoke({})).resolves.toEqual(schema);
37
+ });
@@ -0,0 +1 @@
1
+ export {};
@@ -0,0 +1,24 @@
1
+ import { expect, test, describe } from "@jest/globals";
2
+ import { interpolateFString } from "../template.js";
3
+ describe.each([
4
+ ["{foo}", { foo: "bar" }, "bar"],
5
+ ["pre{foo}post", { foo: "bar" }, "prebarpost"],
6
+ ["{{pre{foo}post}}", { foo: "bar" }, "{prebarpost}"],
7
+ ["text", {}, "text"],
8
+ ["}}{{", {}, "}{"],
9
+ ["{first}_{second}", { first: "foo", second: "bar" }, "foo_bar"],
10
+ ])("Valid f-string", (template, variables, result) => {
11
+ test(`Interpolation works: ${template}`, () => {
12
+ expect(interpolateFString(template, variables)).toBe(result);
13
+ });
14
+ });
15
+ describe.each([
16
+ ["{", {}],
17
+ ["}", {}],
18
+ ["{foo", {}],
19
+ ["foo}", {}],
20
+ ])("Invalid f-string", (template, variables) => {
21
+ test(`Interpolation throws: ${template}`, () => {
22
+ expect(() => interpolateFString(template, variables)).toThrow();
23
+ });
24
+ });