langchain 0.0.74 → 0.0.76

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 (163) hide show
  1. package/client.cjs +1 -0
  2. package/client.d.ts +1 -0
  3. package/client.js +1 -0
  4. package/dist/base_language/count_tokens.cjs +5 -21
  5. package/dist/base_language/count_tokens.d.ts +1 -6
  6. package/dist/base_language/count_tokens.js +4 -19
  7. package/dist/base_language/index.cjs +16 -24
  8. package/dist/base_language/index.d.ts +22 -3
  9. package/dist/base_language/index.js +17 -25
  10. package/dist/cache/redis.d.ts +3 -1
  11. package/dist/callbacks/base.d.ts +17 -3
  12. package/dist/callbacks/handlers/console.cjs +15 -28
  13. package/dist/callbacks/handlers/console.d.ts +11 -20
  14. package/dist/callbacks/handlers/console.js +14 -27
  15. package/dist/callbacks/handlers/initialize.cjs +8 -3
  16. package/dist/callbacks/handlers/initialize.d.ts +4 -2
  17. package/dist/callbacks/handlers/initialize.js +6 -2
  18. package/dist/callbacks/handlers/tracer.cjs +193 -0
  19. package/dist/callbacks/handlers/tracer.d.ts +65 -0
  20. package/dist/callbacks/handlers/tracer.js +189 -0
  21. package/dist/callbacks/handlers/tracer_langchain.cjs +163 -0
  22. package/dist/callbacks/handlers/tracer_langchain.d.ts +39 -0
  23. package/dist/callbacks/handlers/tracer_langchain.js +159 -0
  24. package/dist/callbacks/handlers/tracer_langchain_v1.cjs +202 -0
  25. package/dist/callbacks/handlers/tracer_langchain_v1.d.ts +57 -0
  26. package/dist/callbacks/handlers/tracer_langchain_v1.js +198 -0
  27. package/dist/callbacks/index.cjs +10 -5
  28. package/dist/callbacks/index.d.ts +5 -3
  29. package/dist/callbacks/index.js +5 -3
  30. package/dist/callbacks/manager.cjs +39 -9
  31. package/dist/callbacks/manager.d.ts +5 -2
  32. package/dist/callbacks/manager.js +40 -10
  33. package/dist/chains/llm_chain.cjs +17 -5
  34. package/dist/chains/llm_chain.d.ts +9 -3
  35. package/dist/chains/llm_chain.js +17 -5
  36. package/dist/chains/question_answering/map_reduce_prompts.cjs +5 -5
  37. package/dist/chains/question_answering/map_reduce_prompts.d.ts +1 -1
  38. package/dist/chains/question_answering/map_reduce_prompts.js +1 -1
  39. package/dist/chains/question_answering/refine_prompts.cjs +5 -5
  40. package/dist/chains/question_answering/refine_prompts.d.ts +1 -1
  41. package/dist/chains/question_answering/refine_prompts.js +1 -1
  42. package/dist/chains/question_answering/stuff_prompts.cjs +2 -2
  43. package/dist/chains/question_answering/stuff_prompts.d.ts +1 -1
  44. package/dist/chains/question_answering/stuff_prompts.js +1 -1
  45. package/dist/chains/sequential_chain.cjs +2 -2
  46. package/dist/chains/sequential_chain.d.ts +2 -2
  47. package/dist/chains/sequential_chain.js +2 -2
  48. package/dist/chains/sql_db/sql_db_prompt.cjs +20 -1
  49. package/dist/chains/sql_db/sql_db_prompt.d.ts +1 -0
  50. package/dist/chains/sql_db/sql_db_prompt.js +19 -0
  51. package/dist/chains/summarization/load.cjs +14 -5
  52. package/dist/chains/summarization/load.d.ts +7 -2
  53. package/dist/chains/summarization/load.js +14 -5
  54. package/dist/chat_models/anthropic.cjs +36 -9
  55. package/dist/chat_models/anthropic.d.ts +6 -3
  56. package/dist/chat_models/anthropic.js +36 -9
  57. package/dist/chat_models/base.cjs +40 -13
  58. package/dist/chat_models/base.d.ts +14 -7
  59. package/dist/chat_models/base.js +41 -14
  60. package/dist/chat_models/openai.cjs +20 -14
  61. package/dist/chat_models/openai.d.ts +2 -1
  62. package/dist/chat_models/openai.js +20 -14
  63. package/dist/client/index.cjs +5 -0
  64. package/dist/client/index.d.ts +1 -0
  65. package/dist/client/index.js +1 -0
  66. package/dist/client/langchainplus.cjs +405 -0
  67. package/dist/client/langchainplus.d.ts +65 -0
  68. package/dist/client/langchainplus.js +398 -0
  69. package/dist/document_loaders/fs/unstructured.cjs +8 -0
  70. package/dist/document_loaders/fs/unstructured.d.ts +3 -0
  71. package/dist/document_loaders/fs/unstructured.js +8 -0
  72. package/dist/document_loaders/web/apify_dataset.cjs +64 -0
  73. package/dist/document_loaders/web/apify_dataset.d.ts +28 -0
  74. package/dist/document_loaders/web/apify_dataset.js +60 -0
  75. package/dist/embeddings/openai.cjs +2 -2
  76. package/dist/embeddings/openai.js +2 -2
  77. package/dist/llms/base.cjs +43 -17
  78. package/dist/llms/base.d.ts +16 -9
  79. package/dist/llms/base.js +44 -18
  80. package/dist/llms/cohere.cjs +3 -2
  81. package/dist/llms/cohere.d.ts +1 -1
  82. package/dist/llms/cohere.js +3 -2
  83. package/dist/llms/hf.cjs +2 -2
  84. package/dist/llms/hf.d.ts +1 -1
  85. package/dist/llms/hf.js +2 -2
  86. package/dist/llms/openai-chat.cjs +13 -14
  87. package/dist/llms/openai-chat.d.ts +2 -1
  88. package/dist/llms/openai-chat.js +13 -14
  89. package/dist/llms/openai.cjs +15 -13
  90. package/dist/llms/openai.d.ts +4 -3
  91. package/dist/llms/openai.js +15 -13
  92. package/dist/llms/replicate.cjs +2 -2
  93. package/dist/llms/replicate.d.ts +1 -1
  94. package/dist/llms/replicate.js +2 -2
  95. package/dist/memory/base.cjs +9 -1
  96. package/dist/memory/base.d.ts +1 -0
  97. package/dist/memory/base.js +7 -0
  98. package/dist/memory/entity_memory.cjs +151 -0
  99. package/dist/memory/entity_memory.d.ts +35 -0
  100. package/dist/memory/entity_memory.js +147 -0
  101. package/dist/memory/index.cjs +5 -1
  102. package/dist/memory/index.d.ts +2 -0
  103. package/dist/memory/index.js +2 -0
  104. package/dist/memory/prompt.cjs +84 -1
  105. package/dist/memory/prompt.d.ts +6 -0
  106. package/dist/memory/prompt.js +83 -0
  107. package/dist/memory/stores/entity/in_memory.cjs +32 -0
  108. package/dist/memory/stores/entity/in_memory.d.ts +10 -0
  109. package/dist/memory/stores/entity/in_memory.js +28 -0
  110. package/dist/prompts/index.cjs +6 -1
  111. package/dist/prompts/index.d.ts +1 -0
  112. package/dist/prompts/index.js +1 -0
  113. package/dist/{chains/prompt_selector.d.ts → prompts/selectors/conditional.d.ts} +4 -4
  114. package/dist/retrievers/document_compressors/chain_extract.cjs +9 -11
  115. package/dist/retrievers/document_compressors/chain_extract.js +9 -11
  116. package/dist/schema/index.cjs +13 -1
  117. package/dist/schema/index.d.ts +19 -0
  118. package/dist/schema/index.js +11 -0
  119. package/dist/stores/message/dynamodb.cjs +8 -6
  120. package/dist/stores/message/dynamodb.js +8 -6
  121. package/dist/stores/message/redis.cjs +69 -0
  122. package/dist/stores/message/redis.d.ts +18 -0
  123. package/dist/stores/message/redis.js +65 -0
  124. package/dist/stores/message/utils.cjs +30 -15
  125. package/dist/stores/message/utils.d.ts +4 -2
  126. package/dist/stores/message/utils.js +28 -14
  127. package/dist/text_splitter.cjs +3 -23
  128. package/dist/text_splitter.d.ts +1 -3
  129. package/dist/text_splitter.js +3 -23
  130. package/dist/tools/webbrowser.cjs +5 -7
  131. package/dist/tools/webbrowser.js +3 -5
  132. package/dist/types/openai-types.d.ts +3 -2
  133. package/dist/util/async_caller.cjs +16 -0
  134. package/dist/util/async_caller.d.ts +4 -0
  135. package/dist/util/async_caller.js +16 -0
  136. package/dist/util/axios-fetch-adapter.cjs +6 -0
  137. package/dist/util/axios-fetch-adapter.js +6 -0
  138. package/dist/util/env.cjs +39 -7
  139. package/dist/util/env.d.ts +19 -0
  140. package/dist/util/env.js +32 -6
  141. package/dist/util/sql_utils.cjs +18 -0
  142. package/dist/util/sql_utils.js +19 -1
  143. package/dist/util/tiktoken.cjs +26 -0
  144. package/dist/util/tiktoken.d.ts +9 -0
  145. package/dist/util/tiktoken.js +21 -0
  146. package/dist/vectorstores/redis.cjs +236 -0
  147. package/dist/vectorstores/redis.d.ts +80 -0
  148. package/dist/vectorstores/redis.js +232 -0
  149. package/document_loaders/web/apify_dataset.cjs +1 -0
  150. package/document_loaders/web/apify_dataset.d.ts +1 -0
  151. package/document_loaders/web/apify_dataset.js +1 -0
  152. package/package.json +41 -5
  153. package/stores/message/redis.cjs +1 -0
  154. package/stores/message/redis.d.ts +1 -0
  155. package/stores/message/redis.js +1 -0
  156. package/vectorstores/redis.cjs +1 -0
  157. package/vectorstores/redis.d.ts +1 -0
  158. package/vectorstores/redis.js +1 -0
  159. package/dist/callbacks/handlers/tracers.cjs +0 -341
  160. package/dist/callbacks/handlers/tracers.d.ts +0 -100
  161. package/dist/callbacks/handlers/tracers.js +0 -336
  162. /package/dist/{chains/prompt_selector.cjs → prompts/selectors/conditional.cjs} +0 -0
  163. /package/dist/{chains/prompt_selector.js → prompts/selectors/conditional.js} +0 -0
@@ -1,5 +1,5 @@
1
- import { isNode } from "browser-or-node";
2
1
  import { Configuration, OpenAIApi, } from "openai";
2
+ import { isNode } from "../util/env.js";
3
3
  import fetchAdapter from "../util/axios-fetch-adapter.js";
4
4
  import { BaseChatModel } from "./base.js";
5
5
  import { AIChatMessage, ChatMessage, HumanChatMessage, SystemChatMessage, } from "../schema/index.js";
@@ -47,6 +47,9 @@ function openAIResponseToChatMessage(role, text) {
47
47
  * if not explicitly available on this class.
48
48
  */
49
49
  export class ChatOpenAI extends BaseChatModel {
50
+ get callKeys() {
51
+ return ["stop", "signal", "timeout", "options"];
52
+ }
50
53
  constructor(fields, configuration) {
51
54
  super(fields ?? {});
52
55
  Object.defineProperty(this, "temperature", {
@@ -253,19 +256,13 @@ export class ChatOpenAI extends BaseChatModel {
253
256
  return this._identifyingParams();
254
257
  }
255
258
  /** @ignore */
256
- async _generate(messages, stopOrOptions, runManager) {
257
- const stop = Array.isArray(stopOrOptions)
258
- ? stopOrOptions
259
- : stopOrOptions?.stop;
260
- const options = Array.isArray(stopOrOptions)
261
- ? {}
262
- : stopOrOptions?.options ?? {};
259
+ async _generate(messages, options, runManager) {
263
260
  const tokenUsage = {};
264
- if (this.stop && stop) {
261
+ if (this.stop && options?.stop) {
265
262
  throw new Error("Stop found in input and default params");
266
263
  }
267
264
  const params = this.invocationParams();
268
- params.stop = stop ?? params.stop;
265
+ params.stop = options?.stop ?? params.stop;
269
266
  const messagesMapped = messages.map((message) => ({
270
267
  role: messageTypeToOpenAIRole(message._getType()),
271
268
  content: message.text,
@@ -280,7 +277,8 @@ export class ChatOpenAI extends BaseChatModel {
280
277
  ...params,
281
278
  messages: messagesMapped,
282
279
  }, {
283
- ...options,
280
+ signal: options?.signal,
281
+ ...options?.options,
284
282
  adapter: fetchAdapter,
285
283
  responseType: "stream",
286
284
  onmessage: (event) => {
@@ -346,7 +344,10 @@ export class ChatOpenAI extends BaseChatModel {
346
344
  : await this.completionWithRetry({
347
345
  ...params,
348
346
  messages: messagesMapped,
349
- }, options);
347
+ }, {
348
+ signal: options?.signal,
349
+ ...options?.options,
350
+ });
350
351
  const { completion_tokens: completionTokens, prompt_tokens: promptTokens, total_tokens: totalTokens, } = data.usage ?? {};
351
352
  if (completionTokens) {
352
353
  tokenUsage.completionTokens =
@@ -387,10 +388,15 @@ export class ChatOpenAI extends BaseChatModel {
387
388
  }
388
389
  const countPerMessage = await Promise.all(messages.map(async (message) => {
389
390
  const textCount = await this.getNumTokens(message.text);
390
- const count = textCount + tokensPerMessage + (message.name ? tokensPerName : 0);
391
+ const roleCount = await this.getNumTokens(messageTypeToOpenAIRole(message._getType()));
392
+ const nameCount = message.name !== undefined
393
+ ? tokensPerName + (await this.getNumTokens(message.name))
394
+ : 0;
395
+ const count = textCount + tokensPerMessage + roleCount + nameCount;
391
396
  totalCount += count;
392
397
  return count;
393
398
  }));
399
+ totalCount += 3; // every reply is primed with <|start|>assistant<|message|>
394
400
  return { totalCount, countPerMessage };
395
401
  }
396
402
  /** @ignore */
@@ -410,7 +416,7 @@ export class ChatOpenAI extends BaseChatModel {
410
416
  this.client = new OpenAIApi(clientConfig);
411
417
  }
412
418
  const axiosOptions = {
413
- adapter: isNode ? undefined : fetchAdapter,
419
+ adapter: isNode() ? undefined : fetchAdapter,
414
420
  ...this.clientConfig.baseOptions,
415
421
  ...options,
416
422
  };
@@ -0,0 +1,5 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.LangChainPlusClient = void 0;
4
+ var langchainplus_js_1 = require("./langchainplus.cjs");
5
+ Object.defineProperty(exports, "LangChainPlusClient", { enumerable: true, get: function () { return langchainplus_js_1.LangChainPlusClient; } });
@@ -0,0 +1 @@
1
+ export { LangChainPlusClient, Dataset, Example, DatasetRunResults, } from "./langchainplus.js";
@@ -0,0 +1 @@
1
+ export { LangChainPlusClient, } from "./langchainplus.js";
@@ -0,0 +1,405 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.LangChainPlusClient = exports.isChain = exports.isChatModel = exports.isLLM = void 0;
4
+ const tracer_langchain_js_1 = require("../callbacks/handlers/tracer_langchain.cjs");
5
+ const utils_js_1 = require("../stores/message/utils.cjs");
6
+ // utility functions
7
+ const isLocalhost = (url) => {
8
+ const strippedUrl = url.replace("http://", "").replace("https://", "");
9
+ const hostname = strippedUrl.split("/")[0].split(":")[0];
10
+ return (hostname === "localhost" || hostname === "127.0.0.1" || hostname === "::1");
11
+ };
12
+ const getSeededTenantId = async (apiUrl, apiKey) => {
13
+ // Get the tenant ID from the seeded tenant
14
+ const url = `${apiUrl}/tenants`;
15
+ let response;
16
+ try {
17
+ response = await fetch(url, {
18
+ method: "GET",
19
+ headers: apiKey ? { authorization: `Bearer ${apiKey}` } : undefined,
20
+ });
21
+ }
22
+ catch (err) {
23
+ throw new Error("Unable to get seeded tenant ID. Please manually provide.");
24
+ }
25
+ if (!response.ok) {
26
+ throw new Error(`Failed to fetch seeded tenant ID: ${response.status} ${response.statusText}`);
27
+ }
28
+ const tenants = await response.json();
29
+ if (!Array.isArray(tenants)) {
30
+ throw new Error(`Expected tenants GET request to return an array, but got ${tenants}`);
31
+ }
32
+ if (tenants.length === 0) {
33
+ throw new Error("No seeded tenant found");
34
+ }
35
+ return tenants[0].id;
36
+ };
37
+ const stringifyError = (err) => {
38
+ let result;
39
+ if (err == null) {
40
+ result = "Error null or undefined";
41
+ }
42
+ else {
43
+ const error = err;
44
+ result = `Error: ${error?.name}: ${error?.message}`;
45
+ }
46
+ return result;
47
+ };
48
+ function isLLM(llm) {
49
+ const blm = llm;
50
+ return (typeof blm?._modelType === "function" && blm?._modelType() === "base_llm");
51
+ }
52
+ exports.isLLM = isLLM;
53
+ function isChatModel(llm) {
54
+ const blm = llm;
55
+ return (typeof blm?._modelType === "function" &&
56
+ blm?._modelType() === "base_chat_model");
57
+ }
58
+ exports.isChatModel = isChatModel;
59
+ async function isChain(llm) {
60
+ if (isLLM(llm)) {
61
+ return false;
62
+ }
63
+ const bchFactory = llm;
64
+ const bch = await bchFactory();
65
+ return (typeof bch?._chainType === "function" && bch?._chainType() !== undefined);
66
+ }
67
+ exports.isChain = isChain;
68
+ async function getModelOrFactoryType(llm) {
69
+ if (isLLM(llm)) {
70
+ return "llm";
71
+ }
72
+ if (isChatModel(llm)) {
73
+ return "chatModel";
74
+ }
75
+ const bchFactory = llm;
76
+ const bch = await bchFactory();
77
+ if (typeof bch?._chainType === "function") {
78
+ return "chainFactory";
79
+ }
80
+ throw new Error("Unknown model or factory type");
81
+ }
82
+ class LangChainPlusClient {
83
+ constructor(apiUrl, tenantId, apiKey) {
84
+ Object.defineProperty(this, "apiKey", {
85
+ enumerable: true,
86
+ configurable: true,
87
+ writable: true,
88
+ value: void 0
89
+ });
90
+ Object.defineProperty(this, "apiUrl", {
91
+ enumerable: true,
92
+ configurable: true,
93
+ writable: true,
94
+ value: void 0
95
+ });
96
+ Object.defineProperty(this, "tenantId", {
97
+ enumerable: true,
98
+ configurable: true,
99
+ writable: true,
100
+ value: void 0
101
+ });
102
+ this.apiUrl = apiUrl;
103
+ this.apiKey = apiKey;
104
+ this.tenantId = tenantId;
105
+ this.validateApiKeyIfHosted();
106
+ }
107
+ static async create(apiUrl, apiKey = undefined, tenantId = undefined) {
108
+ let tenantId_ = tenantId;
109
+ if (!tenantId_) {
110
+ tenantId_ = await getSeededTenantId(apiUrl, apiKey);
111
+ }
112
+ return new LangChainPlusClient(apiUrl, tenantId_, apiKey);
113
+ }
114
+ validateApiKeyIfHosted() {
115
+ const isLocal = isLocalhost(this.apiUrl);
116
+ if (!isLocal && !this.apiKey) {
117
+ throw new Error("API key must be provided when using hosted LangChain+ API");
118
+ }
119
+ }
120
+ get headers() {
121
+ const headers = {};
122
+ if (this.apiKey) {
123
+ headers.authorization = `Bearer ${this.apiKey}`;
124
+ }
125
+ return headers;
126
+ }
127
+ get queryParams() {
128
+ return { tenant_id: this.tenantId };
129
+ }
130
+ async _get(path, queryParams = {}) {
131
+ const params = { ...this.queryParams, ...queryParams };
132
+ let queryString = "";
133
+ for (const key in params) {
134
+ if (Object.prototype.hasOwnProperty.call(params, key)) {
135
+ queryString = queryString
136
+ ? `${queryString}&${encodeURIComponent(key)}=${encodeURIComponent(params[key])}`
137
+ : `${encodeURIComponent(key)}=${encodeURIComponent(params[key])}`;
138
+ }
139
+ }
140
+ const url = `${this.apiUrl}${path}${queryString ? `?${queryString}` : ""}`;
141
+ const response = await fetch(url, {
142
+ method: "GET",
143
+ headers: this.headers,
144
+ });
145
+ if (!response.ok) {
146
+ throw new Error(`Failed to fetch ${path}: ${response.status} ${response.statusText}`);
147
+ }
148
+ return response.json();
149
+ }
150
+ async uploadCsv(csvFile, fileName, description, inputKeys, outputKeys) {
151
+ const url = `${this.apiUrl}/datasets/upload`;
152
+ const formData = new FormData();
153
+ formData.append("file", csvFile, fileName);
154
+ formData.append("input_keys", inputKeys.join(","));
155
+ formData.append("output_keys", outputKeys.join(","));
156
+ formData.append("description", description);
157
+ formData.append("tenant_id", this.tenantId);
158
+ const response = await fetch(url, {
159
+ method: "POST",
160
+ headers: this.headers,
161
+ body: formData,
162
+ });
163
+ if (!response.ok) {
164
+ const result = await response.json();
165
+ if (result.detail && result.detail.includes("already exists")) {
166
+ throw new Error(`Dataset ${fileName} already exists`);
167
+ }
168
+ throw new Error(`Failed to upload CSV: ${response.status} ${response.statusText}`);
169
+ }
170
+ const result = await response.json();
171
+ return result;
172
+ }
173
+ async createDataset(name, description) {
174
+ const response = await fetch(`${this.apiUrl}/datasets`, {
175
+ method: "POST",
176
+ headers: { ...this.headers, "Content-Type": "application/json" },
177
+ body: JSON.stringify({
178
+ name,
179
+ description,
180
+ tenant_id: this.tenantId,
181
+ }),
182
+ });
183
+ if (!response.ok) {
184
+ const result = await response.json();
185
+ if (result.detail && result.detail.includes("already exists")) {
186
+ throw new Error(`Dataset ${name} already exists`);
187
+ }
188
+ throw new Error(`Failed to create dataset ${response.status} ${response.statusText}`);
189
+ }
190
+ const result = await response.json();
191
+ return result;
192
+ }
193
+ async readDataset(datasetId, datasetName) {
194
+ let path = "/datasets";
195
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
196
+ const params = { limit: 1 };
197
+ if (datasetId !== undefined && datasetName !== undefined) {
198
+ throw new Error("Must provide either datasetName or datasetId, not both");
199
+ }
200
+ else if (datasetId !== undefined) {
201
+ path += `/${datasetId}`;
202
+ }
203
+ else if (datasetName !== undefined) {
204
+ params.name = datasetName;
205
+ }
206
+ else {
207
+ throw new Error("Must provide datasetName or datasetId");
208
+ }
209
+ const response = await this._get(path, params);
210
+ let result;
211
+ if (Array.isArray(response)) {
212
+ if (response.length === 0) {
213
+ throw new Error(`Dataset[id=${datasetId}, name=${datasetName}] not found`);
214
+ }
215
+ result = response[0];
216
+ }
217
+ else {
218
+ result = response;
219
+ }
220
+ return result;
221
+ }
222
+ async listDatasets(limit = 100) {
223
+ const path = "/datasets";
224
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
225
+ const params = { limit };
226
+ const response = await this._get(path, params);
227
+ if (!Array.isArray(response)) {
228
+ throw new Error(`Expected ${path} to return an array, but got ${response}`);
229
+ }
230
+ return response;
231
+ }
232
+ async deleteDataset(datasetId, datasetName) {
233
+ let path = "/datasets";
234
+ let datasetId_ = datasetId;
235
+ if (datasetId !== undefined && datasetName !== undefined) {
236
+ throw new Error("Must provide either datasetName or datasetId, not both");
237
+ }
238
+ else if (datasetName !== undefined) {
239
+ const dataset = await this.readDataset(undefined, datasetName);
240
+ datasetId_ = dataset.id;
241
+ }
242
+ if (datasetId_ !== undefined) {
243
+ path += `/${datasetId_}`;
244
+ }
245
+ else {
246
+ throw new Error("Must provide datasetName or datasetId");
247
+ }
248
+ const response = await fetch(this.apiUrl + path, {
249
+ method: "DELETE",
250
+ headers: this.headers,
251
+ });
252
+ if (!response.ok) {
253
+ throw new Error(`Failed to delete ${path}: ${response.status} ${response.statusText}`);
254
+ }
255
+ const results = await response.json();
256
+ return results;
257
+ }
258
+ async createExample(inputs, outputs = {}, datasetId = undefined, datasetName = undefined, createdAt = undefined) {
259
+ let datasetId_ = datasetId;
260
+ if (datasetId_ === undefined && datasetName === undefined) {
261
+ throw new Error("Must provide either datasetName or datasetId");
262
+ }
263
+ else if (datasetId_ !== undefined && datasetName !== undefined) {
264
+ throw new Error("Must provide either datasetName or datasetId, not both");
265
+ }
266
+ else if (datasetId_ === undefined) {
267
+ const dataset = await this.readDataset(undefined, datasetName);
268
+ datasetId_ = dataset.id;
269
+ }
270
+ const createdAt_ = createdAt || new Date();
271
+ const data = {
272
+ dataset_id: datasetId_,
273
+ inputs,
274
+ outputs,
275
+ created_at: createdAt_.toISOString(),
276
+ };
277
+ const response = await fetch(`${this.apiUrl}/examples`, {
278
+ method: "POST",
279
+ headers: { ...this.headers, "Content-Type": "application/json" },
280
+ body: JSON.stringify(data),
281
+ });
282
+ if (!response.ok) {
283
+ throw new Error(`Failed to create example: ${response.status} ${response.statusText}`);
284
+ }
285
+ const result = await response.json();
286
+ return result;
287
+ }
288
+ async readExample(exampleId) {
289
+ const path = `/examples/${exampleId}`;
290
+ return await this._get(path);
291
+ }
292
+ async listExamples(datasetId = undefined, datasetName = undefined) {
293
+ let datasetId_;
294
+ if (datasetId !== undefined && datasetName !== undefined) {
295
+ throw new Error("Must provide either datasetName or datasetId, not both");
296
+ }
297
+ else if (datasetId !== undefined) {
298
+ datasetId_ = datasetId;
299
+ }
300
+ else if (datasetName !== undefined) {
301
+ const dataset = await this.readDataset(undefined, datasetName);
302
+ datasetId_ = dataset.id;
303
+ }
304
+ else {
305
+ throw new Error("Must provide a datasetName or datasetId");
306
+ }
307
+ const response = await this._get("/examples", {
308
+ dataset: datasetId_,
309
+ });
310
+ if (!Array.isArray(response)) {
311
+ throw new Error(`Expected /examples to return an array, but got ${response}`);
312
+ }
313
+ return response;
314
+ }
315
+ async deleteExample(exampleId) {
316
+ const path = `/examples/${exampleId}`;
317
+ const response = await fetch(this.apiUrl + path, {
318
+ method: "DELETE",
319
+ headers: this.headers,
320
+ });
321
+ if (!response.ok) {
322
+ throw new Error(`Failed to delete ${path}: ${response.status} ${response.statusText}`);
323
+ }
324
+ const result = await response.json();
325
+ return result;
326
+ }
327
+ async runLLM(example, tracer, llm, numRepetitions = 1) {
328
+ const results = await Promise.all(Array.from({ length: numRepetitions }).map(async () => {
329
+ try {
330
+ const prompt = example.inputs.prompt;
331
+ return llm.generate([prompt], undefined, [tracer]);
332
+ }
333
+ catch (e) {
334
+ console.error(e);
335
+ return stringifyError(e);
336
+ }
337
+ }));
338
+ return results;
339
+ }
340
+ async runChain(example, tracer, chainFactory, numRepetitions = 1) {
341
+ const results = await Promise.all(Array.from({ length: numRepetitions }).map(async () => {
342
+ try {
343
+ const chain = await chainFactory();
344
+ return chain.call(example.inputs, [tracer]);
345
+ }
346
+ catch (e) {
347
+ console.error(e);
348
+ return stringifyError(e);
349
+ }
350
+ }));
351
+ return results;
352
+ }
353
+ async runChatModel(example, tracer, chatModel, numRepetitions = 1) {
354
+ const results = await Promise.all(Array.from({ length: numRepetitions }).map(async () => {
355
+ try {
356
+ const messages = example.inputs.messages;
357
+ return chatModel.generate([(0, utils_js_1.mapStoredMessagesToChatMessages)(messages)], undefined, [tracer]);
358
+ }
359
+ catch (e) {
360
+ console.error(e);
361
+ return stringifyError(e);
362
+ }
363
+ }));
364
+ return results;
365
+ }
366
+ async runOnDataset(datasetName, llmOrChainFactory, numRepetitions = 1, sessionName = undefined) {
367
+ const examples = await this.listExamples(undefined, datasetName);
368
+ let sessionName_;
369
+ if (sessionName === undefined) {
370
+ const currentTime = new Date().toISOString();
371
+ sessionName_ = `${datasetName}-${llmOrChainFactory.constructor.name}-${currentTime}`;
372
+ }
373
+ else {
374
+ sessionName_ = sessionName;
375
+ }
376
+ const results = {};
377
+ const modelOrFactoryType = await getModelOrFactoryType(llmOrChainFactory);
378
+ await Promise.all(examples.map(async (example) => {
379
+ const tracer = new tracer_langchain_js_1.LangChainTracer({
380
+ exampleId: example.id,
381
+ sessionName: sessionName_,
382
+ });
383
+ if (modelOrFactoryType === "llm") {
384
+ const llm = llmOrChainFactory;
385
+ const llmResult = await this.runLLM(example, tracer, llm, numRepetitions);
386
+ results[example.id] = llmResult;
387
+ }
388
+ else if (modelOrFactoryType === "chainFactory") {
389
+ const chainFactory = llmOrChainFactory;
390
+ const chainResult = await this.runChain(example, tracer, chainFactory, numRepetitions);
391
+ results[example.id] = chainResult;
392
+ }
393
+ else if (modelOrFactoryType === "chatModel") {
394
+ const chatModel = llmOrChainFactory;
395
+ const chatModelResult = await this.runChatModel(example, tracer, chatModel, numRepetitions);
396
+ results[example.id] = chatModelResult;
397
+ }
398
+ else {
399
+ throw new Error(` llm or chain type: ${llmOrChainFactory}`);
400
+ }
401
+ }));
402
+ return results;
403
+ }
404
+ }
405
+ exports.LangChainPlusClient = LangChainPlusClient;
@@ -0,0 +1,65 @@
1
+ import { BaseRun } from "../callbacks/handlers/tracer.js";
2
+ import { LangChainTracer } from "../callbacks/handlers/tracer_langchain.js";
3
+ import { ChainValues, LLMResult, RunInputs, RunOutputs } from "../schema/index.js";
4
+ import { BaseLanguageModel } from "../base_language/index.js";
5
+ import { BaseChain } from "../chains/base.js";
6
+ import { BaseLLM } from "../llms/base.js";
7
+ import { BaseChatModel } from "../chat_models/base.js";
8
+ export interface RunResult extends BaseRun {
9
+ name: string;
10
+ session_id: string;
11
+ parent_run_id?: string;
12
+ }
13
+ export interface BaseDataset {
14
+ name: string;
15
+ description: string;
16
+ tenant_id: string;
17
+ }
18
+ export interface Dataset extends BaseDataset {
19
+ id: string;
20
+ created_at: string;
21
+ modified_at: string;
22
+ }
23
+ export interface BaseExample {
24
+ dataset_id: string;
25
+ inputs: RunInputs;
26
+ outputs: RunOutputs;
27
+ }
28
+ export interface ExampleCreate extends BaseExample {
29
+ id?: string;
30
+ created_at: string;
31
+ }
32
+ export interface Example extends BaseExample {
33
+ id: string;
34
+ created_at: string;
35
+ modified_at: string;
36
+ runs: RunResult[];
37
+ }
38
+ export type DatasetRunResults = Record<string, (string | LLMResult | ChainValues)[]>;
39
+ export declare function isLLM(llm: BaseLanguageModel | (() => Promise<BaseChain>)): llm is BaseLLM;
40
+ export declare function isChatModel(llm: BaseLanguageModel | (() => Promise<BaseChain>)): llm is BaseChatModel;
41
+ export declare function isChain(llm: BaseLanguageModel | (() => Promise<BaseChain>)): Promise<boolean>;
42
+ export declare class LangChainPlusClient {
43
+ private apiKey?;
44
+ private apiUrl;
45
+ private tenantId;
46
+ constructor(apiUrl: string, tenantId: string, apiKey?: string);
47
+ static create(apiUrl: string, apiKey?: string | undefined, tenantId?: string | undefined): Promise<LangChainPlusClient>;
48
+ private validateApiKeyIfHosted;
49
+ private get headers();
50
+ private get queryParams();
51
+ private _get;
52
+ uploadCsv(csvFile: Blob, fileName: string, description: string, inputKeys: string[], outputKeys: string[]): Promise<Dataset>;
53
+ createDataset(name: string, description: string): Promise<Dataset>;
54
+ readDataset(datasetId: string | undefined, datasetName: string | undefined): Promise<Dataset>;
55
+ listDatasets(limit?: number): Promise<Dataset[]>;
56
+ deleteDataset(datasetId: string | undefined, datasetName: string | undefined): Promise<Dataset>;
57
+ createExample(inputs: RunInputs, outputs?: RunOutputs, datasetId?: string | undefined, datasetName?: string | undefined, createdAt?: Date | undefined): Promise<Example>;
58
+ readExample(exampleId: string): Promise<Example>;
59
+ listExamples(datasetId?: string | undefined, datasetName?: string | undefined): Promise<Example[]>;
60
+ deleteExample(exampleId: string): Promise<Example>;
61
+ protected runLLM(example: Example, tracer: LangChainTracer, llm: BaseLLM, numRepetitions?: number): Promise<(LLMResult | string)[]>;
62
+ protected runChain(example: Example, tracer: LangChainTracer, chainFactory: () => Promise<BaseChain>, numRepetitions?: number): Promise<(ChainValues | string)[]>;
63
+ protected runChatModel(example: Example, tracer: LangChainTracer, chatModel: BaseChatModel, numRepetitions?: number): Promise<(LLMResult | string)[]>;
64
+ runOnDataset(datasetName: string, llmOrChainFactory: BaseLanguageModel | (() => Promise<BaseChain>), numRepetitions?: number, sessionName?: string | undefined): Promise<DatasetRunResults>;
65
+ }