langchain 0.0.67 → 0.0.69

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 (84) hide show
  1. package/dist/callbacks/manager.cjs +2 -3
  2. package/dist/callbacks/manager.js +2 -3
  3. package/dist/chains/chat_vector_db_chain.cjs +4 -2
  4. package/dist/chains/chat_vector_db_chain.d.ts +2 -0
  5. package/dist/chains/chat_vector_db_chain.js +4 -2
  6. package/dist/chains/combine_docs_chain.cjs +22 -0
  7. package/dist/chains/combine_docs_chain.d.ts +7 -0
  8. package/dist/chains/combine_docs_chain.js +22 -0
  9. package/dist/chains/constitutional_ai/constitutional_chain.cjs +120 -0
  10. package/dist/chains/constitutional_ai/constitutional_chain.d.ts +31 -0
  11. package/dist/chains/constitutional_ai/constitutional_chain.js +116 -0
  12. package/dist/chains/constitutional_ai/constitutional_principle.cjs +38 -0
  13. package/dist/chains/constitutional_ai/constitutional_principle.d.ts +15 -0
  14. package/dist/chains/constitutional_ai/constitutional_principle.js +34 -0
  15. package/dist/chains/constitutional_ai/constitutional_prompts.cjs +88 -0
  16. package/dist/chains/constitutional_ai/constitutional_prompts.d.ts +13 -0
  17. package/dist/chains/constitutional_ai/constitutional_prompts.js +85 -0
  18. package/dist/chains/conversational_retrieval_chain.cjs +4 -2
  19. package/dist/chains/conversational_retrieval_chain.d.ts +3 -4
  20. package/dist/chains/conversational_retrieval_chain.js +4 -2
  21. package/dist/chains/index.cjs +8 -1
  22. package/dist/chains/index.d.ts +4 -1
  23. package/dist/chains/index.js +3 -0
  24. package/dist/chains/openai_moderation.cjs +128 -0
  25. package/dist/chains/openai_moderation.d.ts +26 -0
  26. package/dist/chains/openai_moderation.js +121 -0
  27. package/dist/chains/question_answering/load.cjs +27 -16
  28. package/dist/chains/question_answering/load.d.ts +16 -14
  29. package/dist/chains/question_answering/load.js +27 -16
  30. package/dist/chains/retrieval_qa.d.ts +2 -2
  31. package/dist/chains/serde.d.ts +14 -1
  32. package/dist/chains/summarization/load.cjs +2 -1
  33. package/dist/chains/summarization/load.d.ts +3 -3
  34. package/dist/chains/summarization/load.js +2 -1
  35. package/dist/document_loaders/web/confluence.cjs +105 -0
  36. package/dist/document_loaders/web/confluence.d.ts +34 -0
  37. package/dist/document_loaders/web/confluence.js +101 -0
  38. package/dist/embeddings/cohere.cjs +1 -1
  39. package/dist/embeddings/cohere.js +1 -1
  40. package/dist/memory/motorhead_memory.cjs +1 -1
  41. package/dist/memory/motorhead_memory.js +1 -1
  42. package/dist/output_parsers/list.cjs +1 -1
  43. package/dist/output_parsers/list.js +1 -1
  44. package/dist/output_parsers/regex.cjs +1 -1
  45. package/dist/output_parsers/regex.js +1 -1
  46. package/dist/output_parsers/structured.cjs +1 -1
  47. package/dist/output_parsers/structured.js +1 -1
  48. package/dist/retrievers/document_compressors/chain_extract.cjs +83 -0
  49. package/dist/retrievers/document_compressors/chain_extract.d.ts +16 -0
  50. package/dist/retrievers/document_compressors/chain_extract.js +79 -0
  51. package/dist/retrievers/document_compressors/chain_extract_prompt.cjs +14 -0
  52. package/dist/retrievers/document_compressors/chain_extract_prompt.d.ts +1 -0
  53. package/dist/retrievers/document_compressors/chain_extract_prompt.js +10 -0
  54. package/dist/retrievers/time_weighted.cjs +218 -0
  55. package/dist/retrievers/time_weighted.d.ts +110 -0
  56. package/dist/retrievers/time_weighted.js +214 -0
  57. package/dist/schema/output_parser.cjs +8 -1
  58. package/dist/schema/output_parser.d.ts +2 -1
  59. package/dist/schema/output_parser.js +8 -1
  60. package/dist/vectorstores/myscale.cjs +185 -0
  61. package/dist/vectorstores/myscale.d.ts +48 -0
  62. package/dist/vectorstores/myscale.js +181 -0
  63. package/dist/vectorstores/weaviate.cjs +39 -3
  64. package/dist/vectorstores/weaviate.d.ts +1 -0
  65. package/dist/vectorstores/weaviate.js +37 -2
  66. package/document_loaders/web/confluence.cjs +1 -0
  67. package/document_loaders/web/confluence.d.ts +1 -0
  68. package/document_loaders/web/confluence.js +1 -0
  69. package/package.json +46 -1
  70. package/retrievers/document_compressors/chain_extract.cjs +1 -0
  71. package/retrievers/document_compressors/chain_extract.d.ts +1 -0
  72. package/retrievers/document_compressors/chain_extract.js +1 -0
  73. package/retrievers/time_weighted.cjs +1 -0
  74. package/retrievers/time_weighted.d.ts +1 -0
  75. package/retrievers/time_weighted.js +1 -0
  76. package/schema/output_parser.cjs +1 -0
  77. package/schema/output_parser.d.ts +1 -0
  78. package/schema/output_parser.js +1 -0
  79. package/vectorstores/myscale.cjs +1 -0
  80. package/vectorstores/myscale.d.ts +1 -0
  81. package/vectorstores/myscale.js +1 -0
  82. package/dist/util/flatten.cjs +0 -21
  83. package/dist/util/flatten.d.ts +0 -1
  84. package/dist/util/flatten.js +0 -17
@@ -269,8 +269,7 @@ class CallbackManager extends BaseCallbackManager {
269
269
  const manager = new CallbackManager(this._parentRunId);
270
270
  for (const handler of this.handlers) {
271
271
  const inheritable = this.inheritableHandlers.includes(handler);
272
- const copied = handler.copy();
273
- manager.addHandler(copied, inheritable);
272
+ manager.addHandler(handler, inheritable);
274
273
  }
275
274
  for (const handler of additionalHandlers) {
276
275
  if (
@@ -280,7 +279,7 @@ class CallbackManager extends BaseCallbackManager {
280
279
  .some((h) => h.name === handler.name)) {
281
280
  continue;
282
281
  }
283
- manager.addHandler(handler.copy(), inherit);
282
+ manager.addHandler(handler, inherit);
284
283
  }
285
284
  return manager;
286
285
  }
@@ -262,8 +262,7 @@ export class CallbackManager extends BaseCallbackManager {
262
262
  const manager = new CallbackManager(this._parentRunId);
263
263
  for (const handler of this.handlers) {
264
264
  const inheritable = this.inheritableHandlers.includes(handler);
265
- const copied = handler.copy();
266
- manager.addHandler(copied, inheritable);
265
+ manager.addHandler(handler, inheritable);
267
266
  }
268
267
  for (const handler of additionalHandlers) {
269
268
  if (
@@ -273,7 +272,7 @@ export class CallbackManager extends BaseCallbackManager {
273
272
  .some((h) => h.name === handler.name)) {
274
273
  continue;
275
274
  }
276
- manager.addHandler(handler.copy(), inherit);
275
+ manager.addHandler(handler, inherit);
277
276
  }
278
277
  return manager;
279
278
  }
@@ -17,6 +17,7 @@ const qa_template = `Use the following pieces of context to answer the question
17
17
 
18
18
  Question: {question}
19
19
  Helpful Answer:`;
20
+ /** @deprecated use `ConversationalRetrievalQAChain` instead. */
20
21
  class ChatVectorDBQAChain extends base_js_1.BaseChain {
21
22
  get inputKeys() {
22
23
  return [this.inputKey, this.chatHistoryKey];
@@ -147,13 +148,14 @@ class ChatVectorDBQAChain extends base_js_1.BaseChain {
147
148
  };
148
149
  }
149
150
  static fromLLM(llm, vectorstore, options = {}) {
150
- const { questionGeneratorTemplate, qaTemplate, ...rest } = options;
151
+ const { questionGeneratorTemplate, qaTemplate, verbose, ...rest } = options;
151
152
  const question_generator_prompt = prompt_js_1.PromptTemplate.fromTemplate(questionGeneratorTemplate || question_generator_template);
152
153
  const qa_prompt = prompt_js_1.PromptTemplate.fromTemplate(qaTemplate || qa_template);
153
- const qaChain = (0, load_js_1.loadQAStuffChain)(llm, { prompt: qa_prompt });
154
+ const qaChain = (0, load_js_1.loadQAStuffChain)(llm, { prompt: qa_prompt, verbose });
154
155
  const questionGeneratorChain = new llm_chain_js_1.LLMChain({
155
156
  prompt: question_generator_prompt,
156
157
  llm,
158
+ verbose,
157
159
  });
158
160
  const instance = new this({
159
161
  vectorstore,
@@ -15,6 +15,7 @@ export interface ChatVectorDBQAChainInput extends ChainInputs {
15
15
  inputKey?: string;
16
16
  k?: number;
17
17
  }
18
+ /** @deprecated use `ConversationalRetrievalQAChain` instead. */
18
19
  export declare class ChatVectorDBQAChain extends BaseChain implements ChatVectorDBQAChainInput {
19
20
  k: number;
20
21
  inputKey: string;
@@ -39,5 +40,6 @@ export declare class ChatVectorDBQAChain extends BaseChain implements ChatVector
39
40
  returnSourceDocuments?: boolean;
40
41
  questionGeneratorTemplate?: string;
41
42
  qaTemplate?: string;
43
+ verbose?: boolean;
42
44
  }): ChatVectorDBQAChain;
43
45
  }
@@ -14,6 +14,7 @@ const qa_template = `Use the following pieces of context to answer the question
14
14
 
15
15
  Question: {question}
16
16
  Helpful Answer:`;
17
+ /** @deprecated use `ConversationalRetrievalQAChain` instead. */
17
18
  export class ChatVectorDBQAChain extends BaseChain {
18
19
  get inputKeys() {
19
20
  return [this.inputKey, this.chatHistoryKey];
@@ -144,13 +145,14 @@ export class ChatVectorDBQAChain extends BaseChain {
144
145
  };
145
146
  }
146
147
  static fromLLM(llm, vectorstore, options = {}) {
147
- const { questionGeneratorTemplate, qaTemplate, ...rest } = options;
148
+ const { questionGeneratorTemplate, qaTemplate, verbose, ...rest } = options;
148
149
  const question_generator_prompt = PromptTemplate.fromTemplate(questionGeneratorTemplate || question_generator_template);
149
150
  const qa_prompt = PromptTemplate.fromTemplate(qaTemplate || qa_template);
150
- const qaChain = loadQAStuffChain(llm, { prompt: qa_prompt });
151
+ const qaChain = loadQAStuffChain(llm, { prompt: qa_prompt, verbose });
151
152
  const questionGeneratorChain = new LLMChain({
152
153
  prompt: question_generator_prompt,
153
154
  llm,
155
+ verbose,
154
156
  });
155
157
  const instance = new this({
156
158
  vectorstore,
@@ -106,6 +106,12 @@ class MapReduceDocumentsChain extends base_js_1.BaseChain {
106
106
  writable: true,
107
107
  value: "context"
108
108
  });
109
+ Object.defineProperty(this, "returnIntermediateSteps", {
110
+ enumerable: true,
111
+ configurable: true,
112
+ writable: true,
113
+ value: false
114
+ });
109
115
  Object.defineProperty(this, "maxTokens", {
110
116
  enumerable: true,
111
117
  configurable: true,
@@ -138,6 +144,7 @@ class MapReduceDocumentsChain extends base_js_1.BaseChain {
138
144
  this.inputKey = fields.inputKey ?? this.inputKey;
139
145
  this.maxTokens = fields.maxTokens ?? this.maxTokens;
140
146
  this.maxIterations = fields.maxIterations ?? this.maxIterations;
147
+ this.returnIntermediateSteps = fields.returnIntermediateSteps ?? false;
141
148
  }
142
149
  /** @ignore */
143
150
  async _call(values, runManager) {
@@ -146,11 +153,14 @@ class MapReduceDocumentsChain extends base_js_1.BaseChain {
146
153
  }
147
154
  const { [this.inputKey]: docs, ...rest } = values;
148
155
  let currentDocs = docs;
156
+ let intermediateSteps = [];
157
+ // For each iteration, we'll use the `llmChain` to get a new result
149
158
  for (let i = 0; i < this.maxIterations; i += 1) {
150
159
  const inputs = currentDocs.map((d) => ({
151
160
  [this.documentVariableName]: d.pageContent,
152
161
  ...rest,
153
162
  }));
163
+ // Calculate the total tokens required in the input
154
164
  const promises = inputs.map(async (i) => {
155
165
  const prompt = await this.llmChain.prompt.format(i);
156
166
  return this.llmChain.llm.getNumTokens(prompt);
@@ -158,17 +168,29 @@ class MapReduceDocumentsChain extends base_js_1.BaseChain {
158
168
  const length = await Promise.all(promises).then((results) => results.reduce((a, b) => a + b, 0));
159
169
  const canSkipMapStep = i !== 0 || !this.ensureMapStep;
160
170
  const withinTokenLimit = length < this.maxTokens;
171
+ // If we can skip the map step, and we're within the token limit, we don't
172
+ // need to run the map step, so just break out of the loop.
161
173
  if (canSkipMapStep && withinTokenLimit) {
162
174
  break;
163
175
  }
164
176
  const results = await this.llmChain.apply(inputs, runManager ? [runManager.getChild()] : undefined);
165
177
  const { outputKey } = this.llmChain;
178
+ // If the flag is set, then concat that to the intermediate steps
179
+ if (this.returnIntermediateSteps) {
180
+ intermediateSteps = intermediateSteps.concat(results.map((r) => r[outputKey]));
181
+ }
166
182
  currentDocs = results.map((r) => ({
167
183
  pageContent: r[outputKey],
168
184
  }));
169
185
  }
186
+ // Now, with the final result of all the inputs from the `llmChain`, we can
187
+ // run the `combineDocumentChain` over them.
170
188
  const newInputs = { input_documents: currentDocs, ...rest };
171
189
  const result = await this.combineDocumentChain.call(newInputs, runManager?.getChild());
190
+ // Return the intermediate steps results if the flag is set
191
+ if (this.returnIntermediateSteps) {
192
+ return { ...result, intermediateSteps };
193
+ }
172
194
  return result;
173
195
  }
174
196
  _chainType() {
@@ -31,10 +31,16 @@ export declare class StuffDocumentsChain extends BaseChain implements StuffDocum
31
31
  serialize(): SerializedStuffDocumentsChain;
32
32
  }
33
33
  export interface MapReduceDocumentsChainInput extends StuffDocumentsChainInput {
34
+ /** The maximum number of tokens before requiring to do the reduction */
34
35
  maxTokens?: number;
36
+ /** The maximum number of iterations to run through the map */
35
37
  maxIterations?: number;
38
+ /** Ensures that the map step is taken regardless of max tokens */
36
39
  ensureMapStep?: boolean;
40
+ /** Chain to use to combine results of applying llm_chain to documents. */
37
41
  combineDocumentChain: BaseChain;
42
+ /** Return the results of the map steps in the output. */
43
+ returnIntermediateSteps?: boolean;
38
44
  }
39
45
  /**
40
46
  * Combine documents by mapping a chain over them, then combining results.
@@ -45,6 +51,7 @@ export declare class MapReduceDocumentsChain extends BaseChain implements MapRed
45
51
  llmChain: LLMChain;
46
52
  inputKey: string;
47
53
  documentVariableName: string;
54
+ returnIntermediateSteps: boolean;
48
55
  get inputKeys(): string[];
49
56
  get outputKeys(): string[];
50
57
  maxTokens: number;
@@ -102,6 +102,12 @@ export class MapReduceDocumentsChain extends BaseChain {
102
102
  writable: true,
103
103
  value: "context"
104
104
  });
105
+ Object.defineProperty(this, "returnIntermediateSteps", {
106
+ enumerable: true,
107
+ configurable: true,
108
+ writable: true,
109
+ value: false
110
+ });
105
111
  Object.defineProperty(this, "maxTokens", {
106
112
  enumerable: true,
107
113
  configurable: true,
@@ -134,6 +140,7 @@ export class MapReduceDocumentsChain extends BaseChain {
134
140
  this.inputKey = fields.inputKey ?? this.inputKey;
135
141
  this.maxTokens = fields.maxTokens ?? this.maxTokens;
136
142
  this.maxIterations = fields.maxIterations ?? this.maxIterations;
143
+ this.returnIntermediateSteps = fields.returnIntermediateSteps ?? false;
137
144
  }
138
145
  /** @ignore */
139
146
  async _call(values, runManager) {
@@ -142,11 +149,14 @@ export class MapReduceDocumentsChain extends BaseChain {
142
149
  }
143
150
  const { [this.inputKey]: docs, ...rest } = values;
144
151
  let currentDocs = docs;
152
+ let intermediateSteps = [];
153
+ // For each iteration, we'll use the `llmChain` to get a new result
145
154
  for (let i = 0; i < this.maxIterations; i += 1) {
146
155
  const inputs = currentDocs.map((d) => ({
147
156
  [this.documentVariableName]: d.pageContent,
148
157
  ...rest,
149
158
  }));
159
+ // Calculate the total tokens required in the input
150
160
  const promises = inputs.map(async (i) => {
151
161
  const prompt = await this.llmChain.prompt.format(i);
152
162
  return this.llmChain.llm.getNumTokens(prompt);
@@ -154,17 +164,29 @@ export class MapReduceDocumentsChain extends BaseChain {
154
164
  const length = await Promise.all(promises).then((results) => results.reduce((a, b) => a + b, 0));
155
165
  const canSkipMapStep = i !== 0 || !this.ensureMapStep;
156
166
  const withinTokenLimit = length < this.maxTokens;
167
+ // If we can skip the map step, and we're within the token limit, we don't
168
+ // need to run the map step, so just break out of the loop.
157
169
  if (canSkipMapStep && withinTokenLimit) {
158
170
  break;
159
171
  }
160
172
  const results = await this.llmChain.apply(inputs, runManager ? [runManager.getChild()] : undefined);
161
173
  const { outputKey } = this.llmChain;
174
+ // If the flag is set, then concat that to the intermediate steps
175
+ if (this.returnIntermediateSteps) {
176
+ intermediateSteps = intermediateSteps.concat(results.map((r) => r[outputKey]));
177
+ }
162
178
  currentDocs = results.map((r) => ({
163
179
  pageContent: r[outputKey],
164
180
  }));
165
181
  }
182
+ // Now, with the final result of all the inputs from the `llmChain`, we can
183
+ // run the `combineDocumentChain` over them.
166
184
  const newInputs = { input_documents: currentDocs, ...rest };
167
185
  const result = await this.combineDocumentChain.call(newInputs, runManager?.getChild());
186
+ // Return the intermediate steps results if the flag is set
187
+ if (this.returnIntermediateSteps) {
188
+ return { ...result, intermediateSteps };
189
+ }
168
190
  return result;
169
191
  }
170
192
  _chainType() {
@@ -0,0 +1,120 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.ConstitutionalChain = void 0;
4
+ const base_js_1 = require("../base.cjs");
5
+ const llm_chain_js_1 = require("../llm_chain.cjs");
6
+ const constitutional_principle_js_1 = require("./constitutional_principle.cjs");
7
+ const constitutional_prompts_js_1 = require("./constitutional_prompts.cjs");
8
+ class ConstitutionalChain extends base_js_1.BaseChain {
9
+ get inputKeys() {
10
+ return this.chain.inputKeys;
11
+ }
12
+ get outputKeys() {
13
+ return ["output"];
14
+ }
15
+ constructor(fields) {
16
+ super(fields.memory, fields.verbose, fields.callbackManager);
17
+ Object.defineProperty(this, "chain", {
18
+ enumerable: true,
19
+ configurable: true,
20
+ writable: true,
21
+ value: void 0
22
+ });
23
+ Object.defineProperty(this, "constitutionalPrinciples", {
24
+ enumerable: true,
25
+ configurable: true,
26
+ writable: true,
27
+ value: void 0
28
+ });
29
+ Object.defineProperty(this, "critiqueChain", {
30
+ enumerable: true,
31
+ configurable: true,
32
+ writable: true,
33
+ value: void 0
34
+ });
35
+ Object.defineProperty(this, "revisionChain", {
36
+ enumerable: true,
37
+ configurable: true,
38
+ writable: true,
39
+ value: void 0
40
+ });
41
+ this.chain = fields.chain;
42
+ this.constitutionalPrinciples = fields.constitutionalPrinciples;
43
+ this.critiqueChain = fields.critiqueChain;
44
+ this.revisionChain = fields.revisionChain;
45
+ }
46
+ async _call(values, runManager) {
47
+ let { [this.chain.outputKey]: response } = await this.chain.call(values, runManager?.getChild());
48
+ const inputPrompt = await this.chain.prompt.format(values);
49
+ for (let i = 0; i < this.constitutionalPrinciples.length; i += 1) {
50
+ const { [this.critiqueChain.outputKey]: rawCritique } = await this.critiqueChain.call({
51
+ input_prompt: inputPrompt,
52
+ output_from_model: response,
53
+ critique_request: this.constitutionalPrinciples[i].critiqueRequest,
54
+ }, runManager?.getChild());
55
+ const critique = ConstitutionalChain._parseCritique(rawCritique);
56
+ const { [this.revisionChain.outputKey]: revisionRaw } = await this.revisionChain.call({
57
+ input_prompt: inputPrompt,
58
+ output_from_model: response,
59
+ critique_request: this.constitutionalPrinciples[i].critiqueRequest,
60
+ critique,
61
+ revision_request: this.constitutionalPrinciples[i].revisionRequest,
62
+ }, runManager?.getChild());
63
+ response = revisionRaw;
64
+ }
65
+ return {
66
+ output: response,
67
+ };
68
+ }
69
+ static getPrinciples(names) {
70
+ if (names) {
71
+ return names.map((name) => constitutional_principle_js_1.PRINCIPLES[name]);
72
+ }
73
+ return Object.values(constitutional_principle_js_1.PRINCIPLES);
74
+ }
75
+ static fromLLM(llm, options) {
76
+ const critiqueChain = options.critiqueChain ??
77
+ new llm_chain_js_1.LLMChain({
78
+ llm,
79
+ prompt: constitutional_prompts_js_1.CRITIQUE_PROMPT,
80
+ });
81
+ const revisionChain = options.revisionChain ??
82
+ new llm_chain_js_1.LLMChain({
83
+ llm,
84
+ prompt: constitutional_prompts_js_1.REVISION_PROMPT,
85
+ });
86
+ return new this({
87
+ ...options,
88
+ chain: options.chain,
89
+ critiqueChain,
90
+ revisionChain,
91
+ constitutionalPrinciples: options.constitutionalPrinciples ?? [],
92
+ });
93
+ }
94
+ static _parseCritique(outputString) {
95
+ let output = outputString;
96
+ if (!output.includes("Revision request")) {
97
+ return output;
98
+ }
99
+ // eslint-disable-next-line prefer-destructuring
100
+ output = output.split("Revision request:")[0];
101
+ if (output.includes("\n\n")) {
102
+ // eslint-disable-next-line prefer-destructuring
103
+ output = output.split("\n\n")[0];
104
+ }
105
+ return output;
106
+ }
107
+ _chainType() {
108
+ return "constitutional_chain";
109
+ }
110
+ serialize() {
111
+ return {
112
+ _type: this._chainType(),
113
+ chain: this.chain.serialize(),
114
+ ConstitutionalPrinciple: this.constitutionalPrinciples.map((principle) => principle.serialize()),
115
+ critiqueChain: this.critiqueChain.serialize(),
116
+ revisionChain: this.revisionChain.serialize(),
117
+ };
118
+ }
119
+ }
120
+ exports.ConstitutionalChain = ConstitutionalChain;
@@ -0,0 +1,31 @@
1
+ import { BaseLanguageModel } from "../../base_language/index.js";
2
+ import { CallbackManagerForChainRun } from "../../callbacks/manager.js";
3
+ import { ChainValues } from "../../schema/index.js";
4
+ import { BaseChain, ChainInputs } from "../base.js";
5
+ import { LLMChain } from "../llm_chain.js";
6
+ import { SerializedBaseChain } from "../serde.js";
7
+ import { ConstitutionalPrinciple } from "./constitutional_principle.js";
8
+ export interface ConstitutionalChainInput extends ChainInputs {
9
+ chain: LLMChain;
10
+ constitutionalPrinciples: ConstitutionalPrinciple[];
11
+ critiqueChain: LLMChain;
12
+ revisionChain: LLMChain;
13
+ }
14
+ export declare class ConstitutionalChain extends BaseChain implements ConstitutionalChainInput {
15
+ chain: LLMChain;
16
+ constitutionalPrinciples: ConstitutionalPrinciple[];
17
+ critiqueChain: LLMChain;
18
+ revisionChain: LLMChain;
19
+ get inputKeys(): string[];
20
+ get outputKeys(): string[];
21
+ constructor(fields: ConstitutionalChainInput);
22
+ _call(values: ChainValues, runManager?: CallbackManagerForChainRun): Promise<ChainValues>;
23
+ static getPrinciples(names?: string[]): ConstitutionalPrinciple[];
24
+ static fromLLM(llm: BaseLanguageModel, options: Omit<ConstitutionalChainInput, "critiqueChain" | "revisionChain"> & {
25
+ critiqueChain?: LLMChain;
26
+ revisionChain?: LLMChain;
27
+ }): ConstitutionalChain;
28
+ private static _parseCritique;
29
+ _chainType(): "constitutional_chain";
30
+ serialize(): SerializedBaseChain;
31
+ }
@@ -0,0 +1,116 @@
1
+ import { BaseChain } from "../base.js";
2
+ import { LLMChain } from "../llm_chain.js";
3
+ import { PRINCIPLES, } from "./constitutional_principle.js";
4
+ import { CRITIQUE_PROMPT, REVISION_PROMPT } from "./constitutional_prompts.js";
5
+ export class ConstitutionalChain extends BaseChain {
6
+ get inputKeys() {
7
+ return this.chain.inputKeys;
8
+ }
9
+ get outputKeys() {
10
+ return ["output"];
11
+ }
12
+ constructor(fields) {
13
+ super(fields.memory, fields.verbose, fields.callbackManager);
14
+ Object.defineProperty(this, "chain", {
15
+ enumerable: true,
16
+ configurable: true,
17
+ writable: true,
18
+ value: void 0
19
+ });
20
+ Object.defineProperty(this, "constitutionalPrinciples", {
21
+ enumerable: true,
22
+ configurable: true,
23
+ writable: true,
24
+ value: void 0
25
+ });
26
+ Object.defineProperty(this, "critiqueChain", {
27
+ enumerable: true,
28
+ configurable: true,
29
+ writable: true,
30
+ value: void 0
31
+ });
32
+ Object.defineProperty(this, "revisionChain", {
33
+ enumerable: true,
34
+ configurable: true,
35
+ writable: true,
36
+ value: void 0
37
+ });
38
+ this.chain = fields.chain;
39
+ this.constitutionalPrinciples = fields.constitutionalPrinciples;
40
+ this.critiqueChain = fields.critiqueChain;
41
+ this.revisionChain = fields.revisionChain;
42
+ }
43
+ async _call(values, runManager) {
44
+ let { [this.chain.outputKey]: response } = await this.chain.call(values, runManager?.getChild());
45
+ const inputPrompt = await this.chain.prompt.format(values);
46
+ for (let i = 0; i < this.constitutionalPrinciples.length; i += 1) {
47
+ const { [this.critiqueChain.outputKey]: rawCritique } = await this.critiqueChain.call({
48
+ input_prompt: inputPrompt,
49
+ output_from_model: response,
50
+ critique_request: this.constitutionalPrinciples[i].critiqueRequest,
51
+ }, runManager?.getChild());
52
+ const critique = ConstitutionalChain._parseCritique(rawCritique);
53
+ const { [this.revisionChain.outputKey]: revisionRaw } = await this.revisionChain.call({
54
+ input_prompt: inputPrompt,
55
+ output_from_model: response,
56
+ critique_request: this.constitutionalPrinciples[i].critiqueRequest,
57
+ critique,
58
+ revision_request: this.constitutionalPrinciples[i].revisionRequest,
59
+ }, runManager?.getChild());
60
+ response = revisionRaw;
61
+ }
62
+ return {
63
+ output: response,
64
+ };
65
+ }
66
+ static getPrinciples(names) {
67
+ if (names) {
68
+ return names.map((name) => PRINCIPLES[name]);
69
+ }
70
+ return Object.values(PRINCIPLES);
71
+ }
72
+ static fromLLM(llm, options) {
73
+ const critiqueChain = options.critiqueChain ??
74
+ new LLMChain({
75
+ llm,
76
+ prompt: CRITIQUE_PROMPT,
77
+ });
78
+ const revisionChain = options.revisionChain ??
79
+ new LLMChain({
80
+ llm,
81
+ prompt: REVISION_PROMPT,
82
+ });
83
+ return new this({
84
+ ...options,
85
+ chain: options.chain,
86
+ critiqueChain,
87
+ revisionChain,
88
+ constitutionalPrinciples: options.constitutionalPrinciples ?? [],
89
+ });
90
+ }
91
+ static _parseCritique(outputString) {
92
+ let output = outputString;
93
+ if (!output.includes("Revision request")) {
94
+ return output;
95
+ }
96
+ // eslint-disable-next-line prefer-destructuring
97
+ output = output.split("Revision request:")[0];
98
+ if (output.includes("\n\n")) {
99
+ // eslint-disable-next-line prefer-destructuring
100
+ output = output.split("\n\n")[0];
101
+ }
102
+ return output;
103
+ }
104
+ _chainType() {
105
+ return "constitutional_chain";
106
+ }
107
+ serialize() {
108
+ return {
109
+ _type: this._chainType(),
110
+ chain: this.chain.serialize(),
111
+ ConstitutionalPrinciple: this.constitutionalPrinciples.map((principle) => principle.serialize()),
112
+ critiqueChain: this.critiqueChain.serialize(),
113
+ revisionChain: this.revisionChain.serialize(),
114
+ };
115
+ }
116
+ }
@@ -0,0 +1,38 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.PRINCIPLES = exports.ConstitutionalPrinciple = void 0;
4
+ class ConstitutionalPrinciple {
5
+ constructor({ critiqueRequest, revisionRequest, name, }) {
6
+ Object.defineProperty(this, "critiqueRequest", {
7
+ enumerable: true,
8
+ configurable: true,
9
+ writable: true,
10
+ value: void 0
11
+ });
12
+ Object.defineProperty(this, "revisionRequest", {
13
+ enumerable: true,
14
+ configurable: true,
15
+ writable: true,
16
+ value: void 0
17
+ });
18
+ Object.defineProperty(this, "name", {
19
+ enumerable: true,
20
+ configurable: true,
21
+ writable: true,
22
+ value: void 0
23
+ });
24
+ this.critiqueRequest = critiqueRequest;
25
+ this.revisionRequest = revisionRequest;
26
+ this.name = name ?? "Constitutional Principle";
27
+ }
28
+ serialize() {
29
+ return {
30
+ _type: "constitutional_principle",
31
+ critiqueRequest: this.critiqueRequest,
32
+ revisionRequest: this.revisionRequest,
33
+ name: this.name,
34
+ };
35
+ }
36
+ }
37
+ exports.ConstitutionalPrinciple = ConstitutionalPrinciple;
38
+ exports.PRINCIPLES = {};
@@ -0,0 +1,15 @@
1
+ import { SerializedConstitutionalPrinciple } from "../../chains/serde.js";
2
+ export declare class ConstitutionalPrinciple {
3
+ critiqueRequest: string;
4
+ revisionRequest: string;
5
+ name: string;
6
+ constructor({ critiqueRequest, revisionRequest, name, }: {
7
+ critiqueRequest: string;
8
+ revisionRequest: string;
9
+ name?: string;
10
+ });
11
+ serialize(): SerializedConstitutionalPrinciple;
12
+ }
13
+ export declare const PRINCIPLES: {
14
+ [key: string]: ConstitutionalPrinciple;
15
+ };
@@ -0,0 +1,34 @@
1
+ export class ConstitutionalPrinciple {
2
+ constructor({ critiqueRequest, revisionRequest, name, }) {
3
+ Object.defineProperty(this, "critiqueRequest", {
4
+ enumerable: true,
5
+ configurable: true,
6
+ writable: true,
7
+ value: void 0
8
+ });
9
+ Object.defineProperty(this, "revisionRequest", {
10
+ enumerable: true,
11
+ configurable: true,
12
+ writable: true,
13
+ value: void 0
14
+ });
15
+ Object.defineProperty(this, "name", {
16
+ enumerable: true,
17
+ configurable: true,
18
+ writable: true,
19
+ value: void 0
20
+ });
21
+ this.critiqueRequest = critiqueRequest;
22
+ this.revisionRequest = revisionRequest;
23
+ this.name = name ?? "Constitutional Principle";
24
+ }
25
+ serialize() {
26
+ return {
27
+ _type: "constitutional_principle",
28
+ critiqueRequest: this.critiqueRequest,
29
+ revisionRequest: this.revisionRequest,
30
+ name: this.name,
31
+ };
32
+ }
33
+ }
34
+ export const PRINCIPLES = {};