langchain 0.0.71 → 0.0.73

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 (77) hide show
  1. package/dist/agents/index.cjs +2 -1
  2. package/dist/agents/index.d.ts +1 -1
  3. package/dist/agents/index.js +1 -1
  4. package/dist/chains/base.cjs +1 -1
  5. package/dist/chains/base.js +1 -1
  6. package/dist/chains/conversation.cjs +3 -3
  7. package/dist/chains/conversation.d.ts +1 -0
  8. package/dist/chains/conversation.js +2 -2
  9. package/dist/chains/index.cjs +10 -1
  10. package/dist/chains/index.d.ts +4 -0
  11. package/dist/chains/index.js +4 -0
  12. package/dist/chains/retrieval_qa.cjs +3 -1
  13. package/dist/chains/retrieval_qa.d.ts +2 -1
  14. package/dist/chains/retrieval_qa.js +4 -2
  15. package/dist/chains/router/llm_router.cjs +31 -0
  16. package/dist/chains/router/llm_router.d.ts +24 -0
  17. package/dist/chains/router/llm_router.js +27 -0
  18. package/dist/chains/router/multi_prompt.cjs +76 -0
  19. package/dist/chains/router/multi_prompt.d.ts +8 -0
  20. package/dist/chains/router/multi_prompt.js +72 -0
  21. package/dist/chains/router/multi_prompt_prompt.cjs +42 -0
  22. package/dist/chains/router/multi_prompt_prompt.d.ts +2 -0
  23. package/dist/chains/router/multi_prompt_prompt.js +38 -0
  24. package/dist/chains/router/multi_retrieval_prompt.cjs +42 -0
  25. package/dist/chains/router/multi_retrieval_prompt.d.ts +2 -0
  26. package/dist/chains/router/multi_retrieval_prompt.js +38 -0
  27. package/dist/chains/router/multi_retrieval_qa.cjs +89 -0
  28. package/dist/chains/router/multi_retrieval_qa.d.ts +15 -0
  29. package/dist/chains/router/multi_retrieval_qa.js +85 -0
  30. package/dist/chains/router/multi_route.cjs +86 -0
  31. package/dist/chains/router/multi_route.d.ts +38 -0
  32. package/dist/chains/router/multi_route.js +81 -0
  33. package/dist/chains/router/utils.cjs +34 -0
  34. package/dist/chains/router/utils.d.ts +3 -0
  35. package/dist/chains/router/utils.js +30 -0
  36. package/dist/chat_models/openai.cjs +33 -19
  37. package/dist/chat_models/openai.d.ts +1 -1
  38. package/dist/chat_models/openai.js +33 -19
  39. package/dist/embeddings/openai.d.ts +1 -1
  40. package/dist/llms/openai-chat.cjs +31 -19
  41. package/dist/llms/openai-chat.d.ts +1 -1
  42. package/dist/llms/openai-chat.js +31 -19
  43. package/dist/llms/openai.cjs +29 -9
  44. package/dist/llms/openai.d.ts +1 -1
  45. package/dist/llms/openai.js +29 -9
  46. package/dist/output_parsers/index.cjs +6 -1
  47. package/dist/output_parsers/index.d.ts +3 -1
  48. package/dist/output_parsers/index.js +3 -1
  49. package/dist/output_parsers/list.cjs +46 -1
  50. package/dist/output_parsers/list.d.ts +14 -0
  51. package/dist/output_parsers/list.js +44 -0
  52. package/dist/output_parsers/router.cjs +32 -0
  53. package/dist/output_parsers/router.d.ts +11 -0
  54. package/dist/output_parsers/router.js +28 -0
  55. package/dist/output_parsers/structured.cjs +43 -3
  56. package/dist/output_parsers/structured.d.ts +11 -1
  57. package/dist/output_parsers/structured.js +41 -2
  58. package/dist/schema/index.cjs +10 -1
  59. package/dist/schema/index.d.ts +5 -0
  60. package/dist/schema/index.js +8 -0
  61. package/dist/schema/output_parser.d.ts +7 -1
  62. package/dist/stores/message/dynamodb.cjs +126 -0
  63. package/dist/stores/message/dynamodb.d.ts +23 -0
  64. package/dist/stores/message/dynamodb.js +122 -0
  65. package/dist/stores/message/in_memory.cjs +3 -6
  66. package/dist/stores/message/in_memory.d.ts +3 -4
  67. package/dist/stores/message/in_memory.js +4 -7
  68. package/dist/stores/message/utils.cjs +31 -0
  69. package/dist/stores/message/utils.d.ts +8 -0
  70. package/dist/stores/message/utils.js +26 -0
  71. package/dist/types/openai-types.cjs +2 -0
  72. package/dist/types/openai-types.d.ts +101 -0
  73. package/dist/types/openai-types.js +1 -0
  74. package/package.json +14 -1
  75. package/stores/message/dynamodb.cjs +1 -0
  76. package/stores/message/dynamodb.d.ts +1 -0
  77. package/stores/message/dynamodb.js +1 -0
@@ -271,6 +271,7 @@ class OpenAIChat extends base_js_1.LLM {
271
271
  ? await new Promise((resolve, reject) => {
272
272
  let response;
273
273
  let rejected = false;
274
+ let resolved = false;
274
275
  this.completionWithRetry({
275
276
  ...params,
276
277
  messages: this.formatMessages(prompt),
@@ -280,6 +281,10 @@ class OpenAIChat extends base_js_1.LLM {
280
281
  responseType: "stream",
281
282
  onmessage: (event) => {
282
283
  if (event.data?.trim?.() === "[DONE]") {
284
+ if (resolved) {
285
+ return;
286
+ }
287
+ resolved = true;
283
288
  resolve(response);
284
289
  }
285
290
  else {
@@ -295,26 +300,33 @@ class OpenAIChat extends base_js_1.LLM {
295
300
  };
296
301
  }
297
302
  // on all messages, update choice
298
- const part = message.choices[0];
299
- if (part != null) {
300
- let choice = response.choices.find((c) => c.index === part.index);
301
- if (!choice) {
302
- choice = {
303
- index: part.index,
304
- finish_reason: part.finish_reason ?? undefined,
305
- };
306
- response.choices.push(choice);
307
- }
308
- if (!choice.message) {
309
- choice.message = {
310
- role: part.delta
311
- ?.role,
312
- content: part.delta?.content ?? "",
313
- };
303
+ for (const part of message.choices) {
304
+ if (part != null) {
305
+ let choice = response.choices.find((c) => c.index === part.index);
306
+ if (!choice) {
307
+ choice = {
308
+ index: part.index,
309
+ finish_reason: part.finish_reason ?? undefined,
310
+ };
311
+ response.choices.push(choice);
312
+ }
313
+ if (!choice.message) {
314
+ choice.message = {
315
+ role: part.delta
316
+ ?.role,
317
+ content: part.delta?.content ?? "",
318
+ };
319
+ }
320
+ choice.message.content += part.delta?.content ?? "";
321
+ // eslint-disable-next-line no-void
322
+ void runManager?.handleLLMNewToken(part.delta?.content ?? "");
314
323
  }
315
- choice.message.content += part.delta?.content ?? "";
316
- // eslint-disable-next-line no-void
317
- void runManager?.handleLLMNewToken(part.delta?.content ?? "");
324
+ }
325
+ // when all messages are finished, resolve
326
+ if (!resolved &&
327
+ message.choices.every((c) => c.finish_reason != null)) {
328
+ resolved = true;
329
+ resolve(response);
318
330
  }
319
331
  }
320
332
  },
@@ -1,5 +1,5 @@
1
1
  import { ChatCompletionRequestMessage, CreateChatCompletionRequest, ConfigurationParameters, CreateChatCompletionResponse } from "openai";
2
- import { AzureOpenAIInput, OpenAICallOptions, OpenAIChatInput } from "../types/open-ai-types.js";
2
+ import { AzureOpenAIInput, OpenAICallOptions, OpenAIChatInput } from "../types/openai-types.js";
3
3
  import type { StreamingAxiosConfiguration } from "../util/axios-types.js";
4
4
  import { BaseLLMParams, LLM } from "./base.js";
5
5
  import { CallbackManagerForLLMRun } from "../callbacks/manager.js";
@@ -265,6 +265,7 @@ export class OpenAIChat extends LLM {
265
265
  ? await new Promise((resolve, reject) => {
266
266
  let response;
267
267
  let rejected = false;
268
+ let resolved = false;
268
269
  this.completionWithRetry({
269
270
  ...params,
270
271
  messages: this.formatMessages(prompt),
@@ -274,6 +275,10 @@ export class OpenAIChat extends LLM {
274
275
  responseType: "stream",
275
276
  onmessage: (event) => {
276
277
  if (event.data?.trim?.() === "[DONE]") {
278
+ if (resolved) {
279
+ return;
280
+ }
281
+ resolved = true;
277
282
  resolve(response);
278
283
  }
279
284
  else {
@@ -289,26 +294,33 @@ export class OpenAIChat extends LLM {
289
294
  };
290
295
  }
291
296
  // on all messages, update choice
292
- const part = message.choices[0];
293
- if (part != null) {
294
- let choice = response.choices.find((c) => c.index === part.index);
295
- if (!choice) {
296
- choice = {
297
- index: part.index,
298
- finish_reason: part.finish_reason ?? undefined,
299
- };
300
- response.choices.push(choice);
301
- }
302
- if (!choice.message) {
303
- choice.message = {
304
- role: part.delta
305
- ?.role,
306
- content: part.delta?.content ?? "",
307
- };
297
+ for (const part of message.choices) {
298
+ if (part != null) {
299
+ let choice = response.choices.find((c) => c.index === part.index);
300
+ if (!choice) {
301
+ choice = {
302
+ index: part.index,
303
+ finish_reason: part.finish_reason ?? undefined,
304
+ };
305
+ response.choices.push(choice);
306
+ }
307
+ if (!choice.message) {
308
+ choice.message = {
309
+ role: part.delta
310
+ ?.role,
311
+ content: part.delta?.content ?? "",
312
+ };
313
+ }
314
+ choice.message.content += part.delta?.content ?? "";
315
+ // eslint-disable-next-line no-void
316
+ void runManager?.handleLLMNewToken(part.delta?.content ?? "");
308
317
  }
309
- choice.message.content += part.delta?.content ?? "";
310
- // eslint-disable-next-line no-void
311
- void runManager?.handleLLMNewToken(part.delta?.content ?? "");
318
+ }
319
+ // when all messages are finished, resolve
320
+ if (!resolved &&
321
+ message.choices.every((c) => c.finish_reason != null)) {
322
+ resolved = true;
323
+ resolve(response);
312
324
  }
313
325
  }
314
326
  },
@@ -305,9 +305,10 @@ class OpenAI extends base_js_1.BaseLLM {
305
305
  for (let i = 0; i < subPrompts.length; i += 1) {
306
306
  const data = params.stream
307
307
  ? await new Promise((resolve, reject) => {
308
- const choice = {};
308
+ const choices = [];
309
309
  let response;
310
310
  let rejected = false;
311
+ let resolved = false;
311
312
  this.completionWithRetry({
312
313
  ...params,
313
314
  prompt: subPrompts[i],
@@ -317,9 +318,13 @@ class OpenAI extends base_js_1.BaseLLM {
317
318
  responseType: "stream",
318
319
  onmessage: (event) => {
319
320
  if (event.data?.trim?.() === "[DONE]") {
321
+ if (resolved) {
322
+ return;
323
+ }
324
+ resolved = true;
320
325
  resolve({
321
326
  ...response,
322
- choices: [choice],
327
+ choices,
323
328
  });
324
329
  }
325
330
  else {
@@ -334,13 +339,28 @@ class OpenAI extends base_js_1.BaseLLM {
334
339
  };
335
340
  }
336
341
  // on all messages, update choice
337
- const part = message.choices[0];
338
- if (part != null) {
339
- choice.text = (choice.text ?? "") + (part.text ?? "");
340
- choice.finish_reason = part.finish_reason;
341
- choice.logprobs = part.logprobs;
342
- // eslint-disable-next-line no-void
343
- void runManager?.handleLLMNewToken(part.text ?? "");
342
+ for (const part of message.choices) {
343
+ if (part != null && part.index != null) {
344
+ if (!choices[part.index])
345
+ choices[part.index] = {};
346
+ const choice = choices[part.index];
347
+ choice.text = (choice.text ?? "") + (part.text ?? "");
348
+ choice.finish_reason = part.finish_reason;
349
+ choice.logprobs = part.logprobs;
350
+ // TODO this should pass part.index to the callback
351
+ // when that's supported there
352
+ // eslint-disable-next-line no-void
353
+ void runManager?.handleLLMNewToken(part.text ?? "");
354
+ }
355
+ }
356
+ // when all messages are finished, resolve
357
+ if (!resolved &&
358
+ choices.every((c) => c.finish_reason != null)) {
359
+ resolved = true;
360
+ resolve({
361
+ ...response,
362
+ choices,
363
+ });
344
364
  }
345
365
  }
346
366
  },
@@ -1,5 +1,5 @@
1
1
  import { ConfigurationParameters, CreateCompletionRequest, CreateCompletionResponse } from "openai";
2
- import { AzureOpenAIInput, OpenAICallOptions, OpenAIInput } from "../types/open-ai-types.js";
2
+ import { AzureOpenAIInput, OpenAICallOptions, OpenAIInput } from "../types/openai-types.js";
3
3
  import type { StreamingAxiosConfiguration } from "../util/axios-types.js";
4
4
  import { BaseLLM, BaseLLMParams } from "./base.js";
5
5
  import { LLMResult } from "../schema/index.js";
@@ -299,9 +299,10 @@ export class OpenAI extends BaseLLM {
299
299
  for (let i = 0; i < subPrompts.length; i += 1) {
300
300
  const data = params.stream
301
301
  ? await new Promise((resolve, reject) => {
302
- const choice = {};
302
+ const choices = [];
303
303
  let response;
304
304
  let rejected = false;
305
+ let resolved = false;
305
306
  this.completionWithRetry({
306
307
  ...params,
307
308
  prompt: subPrompts[i],
@@ -311,9 +312,13 @@ export class OpenAI extends BaseLLM {
311
312
  responseType: "stream",
312
313
  onmessage: (event) => {
313
314
  if (event.data?.trim?.() === "[DONE]") {
315
+ if (resolved) {
316
+ return;
317
+ }
318
+ resolved = true;
314
319
  resolve({
315
320
  ...response,
316
- choices: [choice],
321
+ choices,
317
322
  });
318
323
  }
319
324
  else {
@@ -328,13 +333,28 @@ export class OpenAI extends BaseLLM {
328
333
  };
329
334
  }
330
335
  // on all messages, update choice
331
- const part = message.choices[0];
332
- if (part != null) {
333
- choice.text = (choice.text ?? "") + (part.text ?? "");
334
- choice.finish_reason = part.finish_reason;
335
- choice.logprobs = part.logprobs;
336
- // eslint-disable-next-line no-void
337
- void runManager?.handleLLMNewToken(part.text ?? "");
336
+ for (const part of message.choices) {
337
+ if (part != null && part.index != null) {
338
+ if (!choices[part.index])
339
+ choices[part.index] = {};
340
+ const choice = choices[part.index];
341
+ choice.text = (choice.text ?? "") + (part.text ?? "");
342
+ choice.finish_reason = part.finish_reason;
343
+ choice.logprobs = part.logprobs;
344
+ // TODO this should pass part.index to the callback
345
+ // when that's supported there
346
+ // eslint-disable-next-line no-void
347
+ void runManager?.handleLLMNewToken(part.text ?? "");
348
+ }
349
+ }
350
+ // when all messages are finished, resolve
351
+ if (!resolved &&
352
+ choices.every((c) => c.finish_reason != null)) {
353
+ resolved = true;
354
+ resolve({
355
+ ...response,
356
+ choices,
357
+ });
338
358
  }
339
359
  }
340
360
  },
@@ -1,6 +1,6 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.CombiningOutputParser = exports.OutputFixingParser = exports.StructuredOutputParser = exports.RegexParser = exports.CommaSeparatedListOutputParser = exports.ListOutputParser = void 0;
3
+ exports.CustomListOutputParser = exports.RouterOutputParser = exports.CombiningOutputParser = exports.OutputFixingParser = exports.JsonMarkdownStructuredOutputParser = exports.StructuredOutputParser = exports.RegexParser = exports.CommaSeparatedListOutputParser = exports.ListOutputParser = void 0;
4
4
  var list_js_1 = require("./list.cjs");
5
5
  Object.defineProperty(exports, "ListOutputParser", { enumerable: true, get: function () { return list_js_1.ListOutputParser; } });
6
6
  Object.defineProperty(exports, "CommaSeparatedListOutputParser", { enumerable: true, get: function () { return list_js_1.CommaSeparatedListOutputParser; } });
@@ -8,7 +8,12 @@ var regex_js_1 = require("./regex.cjs");
8
8
  Object.defineProperty(exports, "RegexParser", { enumerable: true, get: function () { return regex_js_1.RegexParser; } });
9
9
  var structured_js_1 = require("./structured.cjs");
10
10
  Object.defineProperty(exports, "StructuredOutputParser", { enumerable: true, get: function () { return structured_js_1.StructuredOutputParser; } });
11
+ Object.defineProperty(exports, "JsonMarkdownStructuredOutputParser", { enumerable: true, get: function () { return structured_js_1.JsonMarkdownStructuredOutputParser; } });
11
12
  var fix_js_1 = require("./fix.cjs");
12
13
  Object.defineProperty(exports, "OutputFixingParser", { enumerable: true, get: function () { return fix_js_1.OutputFixingParser; } });
13
14
  var combining_js_1 = require("./combining.cjs");
14
15
  Object.defineProperty(exports, "CombiningOutputParser", { enumerable: true, get: function () { return combining_js_1.CombiningOutputParser; } });
16
+ var router_js_1 = require("./router.cjs");
17
+ Object.defineProperty(exports, "RouterOutputParser", { enumerable: true, get: function () { return router_js_1.RouterOutputParser; } });
18
+ var list_js_2 = require("./list.cjs");
19
+ Object.defineProperty(exports, "CustomListOutputParser", { enumerable: true, get: function () { return list_js_2.CustomListOutputParser; } });
@@ -1,5 +1,7 @@
1
1
  export { ListOutputParser, CommaSeparatedListOutputParser } from "./list.js";
2
2
  export { RegexParser } from "./regex.js";
3
- export { StructuredOutputParser } from "./structured.js";
3
+ export { StructuredOutputParser, JsonMarkdownStructuredOutputParser, JsonMarkdownFormatInstructionsOptions, JsonMarkdownStructuredOutputParserInput, } from "./structured.js";
4
4
  export { OutputFixingParser } from "./fix.js";
5
5
  export { CombiningOutputParser } from "./combining.js";
6
+ export { RouterOutputParser, RouterOutputParserInput } from "./router.js";
7
+ export { CustomListOutputParser } from "./list.js";
@@ -1,5 +1,7 @@
1
1
  export { ListOutputParser, CommaSeparatedListOutputParser } from "./list.js";
2
2
  export { RegexParser } from "./regex.js";
3
- export { StructuredOutputParser } from "./structured.js";
3
+ export { StructuredOutputParser, JsonMarkdownStructuredOutputParser, } from "./structured.js";
4
4
  export { OutputFixingParser } from "./fix.js";
5
5
  export { CombiningOutputParser } from "./combining.js";
6
+ export { RouterOutputParser } from "./router.js";
7
+ export { CustomListOutputParser } from "./list.js";
@@ -1,6 +1,6 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.CommaSeparatedListOutputParser = exports.ListOutputParser = void 0;
3
+ exports.CustomListOutputParser = exports.CommaSeparatedListOutputParser = exports.ListOutputParser = void 0;
4
4
  const output_parser_js_1 = require("../schema/output_parser.cjs");
5
5
  /**
6
6
  * Class to parse the output of an LLM call to a list.
@@ -30,3 +30,48 @@ class CommaSeparatedListOutputParser extends ListOutputParser {
30
30
  }
31
31
  }
32
32
  exports.CommaSeparatedListOutputParser = CommaSeparatedListOutputParser;
33
+ /**
34
+ * Class to parse the output of an LLM call to a list with a specific length and separator.
35
+ * @augments ListOutputParser
36
+ */
37
+ class CustomListOutputParser extends ListOutputParser {
38
+ constructor({ length, separator }) {
39
+ super();
40
+ Object.defineProperty(this, "length", {
41
+ enumerable: true,
42
+ configurable: true,
43
+ writable: true,
44
+ value: void 0
45
+ });
46
+ Object.defineProperty(this, "separator", {
47
+ enumerable: true,
48
+ configurable: true,
49
+ writable: true,
50
+ value: void 0
51
+ });
52
+ this.length = length;
53
+ this.separator = separator || ",";
54
+ }
55
+ async parse(text) {
56
+ try {
57
+ const items = text
58
+ .trim()
59
+ .split(this.separator)
60
+ .map((s) => s.trim());
61
+ if (this.length !== undefined && items.length !== this.length) {
62
+ throw new output_parser_js_1.OutputParserException(`Incorrect number of items. Expected ${this.length}, got ${items.length}.`);
63
+ }
64
+ return items;
65
+ }
66
+ catch (e) {
67
+ if (Object.getPrototypeOf(e) === output_parser_js_1.OutputParserException.prototype) {
68
+ throw e;
69
+ }
70
+ throw new output_parser_js_1.OutputParserException(`Could not parse output: ${text}`);
71
+ }
72
+ }
73
+ getFormatInstructions() {
74
+ return `Your response should be a list of ${this.length} items separated by "${this.separator}" (eg: \`foo${this.separator} bar${this.separator} baz\`)`;
75
+ }
76
+ }
77
+ exports.CustomListOutputParser = CustomListOutputParser;
@@ -13,3 +13,17 @@ export declare class CommaSeparatedListOutputParser extends ListOutputParser {
13
13
  parse(text: string): Promise<string[]>;
14
14
  getFormatInstructions(): string;
15
15
  }
16
+ /**
17
+ * Class to parse the output of an LLM call to a list with a specific length and separator.
18
+ * @augments ListOutputParser
19
+ */
20
+ export declare class CustomListOutputParser extends ListOutputParser {
21
+ private length;
22
+ private separator;
23
+ constructor({ length, separator }: {
24
+ length?: number;
25
+ separator?: string;
26
+ });
27
+ parse(text: string): Promise<string[]>;
28
+ getFormatInstructions(): string;
29
+ }
@@ -25,3 +25,47 @@ export class CommaSeparatedListOutputParser extends ListOutputParser {
25
25
  return `Your response should be a list of comma separated values, eg: \`foo, bar, baz\``;
26
26
  }
27
27
  }
28
+ /**
29
+ * Class to parse the output of an LLM call to a list with a specific length and separator.
30
+ * @augments ListOutputParser
31
+ */
32
+ export class CustomListOutputParser extends ListOutputParser {
33
+ constructor({ length, separator }) {
34
+ super();
35
+ Object.defineProperty(this, "length", {
36
+ enumerable: true,
37
+ configurable: true,
38
+ writable: true,
39
+ value: void 0
40
+ });
41
+ Object.defineProperty(this, "separator", {
42
+ enumerable: true,
43
+ configurable: true,
44
+ writable: true,
45
+ value: void 0
46
+ });
47
+ this.length = length;
48
+ this.separator = separator || ",";
49
+ }
50
+ async parse(text) {
51
+ try {
52
+ const items = text
53
+ .trim()
54
+ .split(this.separator)
55
+ .map((s) => s.trim());
56
+ if (this.length !== undefined && items.length !== this.length) {
57
+ throw new OutputParserException(`Incorrect number of items. Expected ${this.length}, got ${items.length}.`);
58
+ }
59
+ return items;
60
+ }
61
+ catch (e) {
62
+ if (Object.getPrototypeOf(e) === OutputParserException.prototype) {
63
+ throw e;
64
+ }
65
+ throw new OutputParserException(`Could not parse output: ${text}`);
66
+ }
67
+ }
68
+ getFormatInstructions() {
69
+ return `Your response should be a list of ${this.length} items separated by "${this.separator}" (eg: \`foo${this.separator} bar${this.separator} baz\`)`;
70
+ }
71
+ }
@@ -0,0 +1,32 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.RouterOutputParser = void 0;
4
+ const structured_js_1 = require("./structured.cjs");
5
+ const output_parser_js_1 = require("../schema/output_parser.cjs");
6
+ class RouterOutputParser extends structured_js_1.JsonMarkdownStructuredOutputParser {
7
+ constructor(schema, options) {
8
+ super(schema);
9
+ Object.defineProperty(this, "defaultDestination", {
10
+ enumerable: true,
11
+ configurable: true,
12
+ writable: true,
13
+ value: "DEFAULT"
14
+ });
15
+ this.defaultDestination =
16
+ options?.defaultDestination ?? this.defaultDestination;
17
+ }
18
+ async parse(text) {
19
+ try {
20
+ const parsedText = await super.parse(text);
21
+ if (parsedText.destination?.toLowerCase() ===
22
+ this.defaultDestination.toLowerCase()) {
23
+ parsedText.destination = null;
24
+ }
25
+ return parsedText;
26
+ }
27
+ catch (e) {
28
+ throw new output_parser_js_1.OutputParserException(`Failed to parse. Text: "${text}". Error: ${e}`, text);
29
+ }
30
+ }
31
+ }
32
+ exports.RouterOutputParser = RouterOutputParser;
@@ -0,0 +1,11 @@
1
+ import { z } from "zod";
2
+ import { JsonMarkdownStructuredOutputParser } from "./structured.js";
3
+ export type RouterOutputParserInput = {
4
+ defaultDestination?: string;
5
+ interpolationDepth?: number;
6
+ };
7
+ export declare class RouterOutputParser<Y extends z.ZodTypeAny> extends JsonMarkdownStructuredOutputParser<Y> {
8
+ defaultDestination: string;
9
+ constructor(schema: Y, options?: RouterOutputParserInput);
10
+ parse(text: string): Promise<z.infer<Y>>;
11
+ }
@@ -0,0 +1,28 @@
1
+ import { JsonMarkdownStructuredOutputParser } from "./structured.js";
2
+ import { OutputParserException } from "../schema/output_parser.js";
3
+ export class RouterOutputParser extends JsonMarkdownStructuredOutputParser {
4
+ constructor(schema, options) {
5
+ super(schema);
6
+ Object.defineProperty(this, "defaultDestination", {
7
+ enumerable: true,
8
+ configurable: true,
9
+ writable: true,
10
+ value: "DEFAULT"
11
+ });
12
+ this.defaultDestination =
13
+ options?.defaultDestination ?? this.defaultDestination;
14
+ }
15
+ async parse(text) {
16
+ try {
17
+ const parsedText = await super.parse(text);
18
+ if (parsedText.destination?.toLowerCase() ===
19
+ this.defaultDestination.toLowerCase()) {
20
+ parsedText.destination = null;
21
+ }
22
+ return parsedText;
23
+ }
24
+ catch (e) {
25
+ throw new OutputParserException(`Failed to parse. Text: "${text}". Error: ${e}`, text);
26
+ }
27
+ }
28
+ }
@@ -1,6 +1,6 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.StructuredOutputParser = void 0;
3
+ exports.JsonMarkdownStructuredOutputParser = exports.StructuredOutputParser = void 0;
4
4
  const zod_1 = require("zod");
5
5
  const zod_to_json_schema_1 = require("zod-to-json-schema");
6
6
  const output_parser_js_1 = require("../schema/output_parser.cjs");
@@ -30,9 +30,9 @@ For example, the example "JSON Schema" instance {{"properties": {{"foo": {{"desc
30
30
  would match an object with one required property, "foo". The "type" property specifies "foo" must be an "array", and the "description" property semantically describes it as "a list of test words". The items within "foo" must be strings.
31
31
  Thus, the object {{"foo": ["bar", "baz"]}} is a well-formatted instance of this example "JSON Schema". The object {{"properties": {{"foo": ["bar", "baz"]}}}} is not well-formatted.
32
32
 
33
- Your output will be parsed and type-checked according to the provided schema instance, so make sure all fields in your output match exactly!
33
+ Your output will be parsed and type-checked according to the provided schema instance, so make sure all fields in your output match the schema exactly and there are no trailing commas!
34
34
 
35
- Here is the JSON Schema instance your output must adhere to:
35
+ Here is the JSON Schema instance your output must adhere to. Include the enclosing markdown codeblock:
36
36
  \`\`\`json
37
37
  ${JSON.stringify((0, zod_to_json_schema_1.zodToJsonSchema)(this.schema))}
38
38
  \`\`\`
@@ -51,3 +51,43 @@ ${JSON.stringify((0, zod_to_json_schema_1.zodToJsonSchema)(this.schema))}
51
51
  }
52
52
  }
53
53
  exports.StructuredOutputParser = StructuredOutputParser;
54
+ class JsonMarkdownStructuredOutputParser extends StructuredOutputParser {
55
+ getFormatInstructions(options) {
56
+ const interpolationDepth = options?.interpolationDepth ?? 1;
57
+ if (interpolationDepth < 1) {
58
+ throw new Error("f string interpolation depth must be at least 1");
59
+ }
60
+ return `Return a markdown code snippet with a JSON object formatted to look like:\n\`\`\`json\n${this._schemaToInstruction((0, zod_to_json_schema_1.zodToJsonSchema)(this.schema))
61
+ .replaceAll("{", "{".repeat(interpolationDepth))
62
+ .replaceAll("}", "}".repeat(interpolationDepth))}\n\`\`\``;
63
+ }
64
+ _schemaToInstruction(schemaInput, indent = 2) {
65
+ const schema = schemaInput;
66
+ let nullable = false;
67
+ if (Array.isArray(schema.type)) {
68
+ const [actualType, nullStr] = schema.type;
69
+ nullable = nullStr === "null";
70
+ schema.type = actualType;
71
+ }
72
+ if (schema.type === "object" && schema.properties) {
73
+ const description = schema.description ? ` // ${schema.description}` : "";
74
+ const properties = Object.entries(schema.properties)
75
+ .map(([key, value]) => {
76
+ const isOptional = schema.required?.includes(key)
77
+ ? ""
78
+ : " (optional)";
79
+ return `${" ".repeat(indent)}"${key}": ${this._schemaToInstruction(value, indent + 2)}${isOptional}`;
80
+ })
81
+ .join("\n");
82
+ return `{\n${properties}\n${" ".repeat(indent - 2)}}${description}`;
83
+ }
84
+ if (schema.type === "array" && schema.items) {
85
+ const description = schema.description ? ` // ${schema.description}` : "";
86
+ return `array[\n${" ".repeat(indent)}${this._schemaToInstruction(schema.items)}\n${" ".repeat(indent - 2)}] ${description}`;
87
+ }
88
+ const isNullable = nullable ? " (nullable)" : "";
89
+ const description = schema.description ? ` // ${schema.description}` : "";
90
+ return `${schema.type}${description}${isNullable}`;
91
+ }
92
+ }
93
+ exports.JsonMarkdownStructuredOutputParser = JsonMarkdownStructuredOutputParser;
@@ -1,5 +1,11 @@
1
1
  import { z } from "zod";
2
- import { BaseOutputParser } from "../schema/output_parser.js";
2
+ import { BaseOutputParser, FormatInstructionsOptions } from "../schema/output_parser.js";
3
+ export type JsonMarkdownStructuredOutputParserInput = {
4
+ interpolationDepth?: number;
5
+ };
6
+ export interface JsonMarkdownFormatInstructionsOptions extends FormatInstructionsOptions {
7
+ interpolationDepth?: number;
8
+ }
3
9
  export declare class StructuredOutputParser<T extends z.ZodTypeAny> extends BaseOutputParser<z.infer<T>> {
4
10
  schema: T;
5
11
  constructor(schema: T);
@@ -16,3 +22,7 @@ export declare class StructuredOutputParser<T extends z.ZodTypeAny> extends Base
16
22
  getFormatInstructions(): string;
17
23
  parse(text: string): Promise<z.infer<T>>;
18
24
  }
25
+ export declare class JsonMarkdownStructuredOutputParser<T extends z.ZodTypeAny> extends StructuredOutputParser<T> {
26
+ getFormatInstructions(options?: JsonMarkdownFormatInstructionsOptions): string;
27
+ private _schemaToInstruction;
28
+ }