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.
- package/client.cjs +1 -0
- package/client.d.ts +1 -0
- package/client.js +1 -0
- package/dist/base_language/count_tokens.cjs +5 -21
- package/dist/base_language/count_tokens.d.ts +1 -6
- package/dist/base_language/count_tokens.js +4 -19
- package/dist/base_language/index.cjs +16 -24
- package/dist/base_language/index.d.ts +22 -3
- package/dist/base_language/index.js +17 -25
- package/dist/cache/redis.d.ts +3 -1
- package/dist/callbacks/base.d.ts +17 -3
- package/dist/callbacks/handlers/console.cjs +15 -28
- package/dist/callbacks/handlers/console.d.ts +11 -20
- package/dist/callbacks/handlers/console.js +14 -27
- package/dist/callbacks/handlers/initialize.cjs +8 -3
- package/dist/callbacks/handlers/initialize.d.ts +4 -2
- package/dist/callbacks/handlers/initialize.js +6 -2
- package/dist/callbacks/handlers/tracer.cjs +193 -0
- package/dist/callbacks/handlers/tracer.d.ts +65 -0
- package/dist/callbacks/handlers/tracer.js +189 -0
- package/dist/callbacks/handlers/tracer_langchain.cjs +163 -0
- package/dist/callbacks/handlers/tracer_langchain.d.ts +39 -0
- package/dist/callbacks/handlers/tracer_langchain.js +159 -0
- package/dist/callbacks/handlers/tracer_langchain_v1.cjs +202 -0
- package/dist/callbacks/handlers/tracer_langchain_v1.d.ts +57 -0
- package/dist/callbacks/handlers/tracer_langchain_v1.js +198 -0
- package/dist/callbacks/index.cjs +10 -5
- package/dist/callbacks/index.d.ts +5 -3
- package/dist/callbacks/index.js +5 -3
- package/dist/callbacks/manager.cjs +39 -9
- package/dist/callbacks/manager.d.ts +5 -2
- package/dist/callbacks/manager.js +40 -10
- package/dist/chains/llm_chain.cjs +17 -5
- package/dist/chains/llm_chain.d.ts +9 -3
- package/dist/chains/llm_chain.js +17 -5
- package/dist/chains/question_answering/map_reduce_prompts.cjs +5 -5
- package/dist/chains/question_answering/map_reduce_prompts.d.ts +1 -1
- package/dist/chains/question_answering/map_reduce_prompts.js +1 -1
- package/dist/chains/question_answering/refine_prompts.cjs +5 -5
- package/dist/chains/question_answering/refine_prompts.d.ts +1 -1
- package/dist/chains/question_answering/refine_prompts.js +1 -1
- package/dist/chains/question_answering/stuff_prompts.cjs +2 -2
- package/dist/chains/question_answering/stuff_prompts.d.ts +1 -1
- package/dist/chains/question_answering/stuff_prompts.js +1 -1
- package/dist/chains/sequential_chain.cjs +2 -2
- package/dist/chains/sequential_chain.d.ts +2 -2
- package/dist/chains/sequential_chain.js +2 -2
- package/dist/chains/sql_db/sql_db_prompt.cjs +20 -1
- package/dist/chains/sql_db/sql_db_prompt.d.ts +1 -0
- package/dist/chains/sql_db/sql_db_prompt.js +19 -0
- package/dist/chains/summarization/load.cjs +14 -5
- package/dist/chains/summarization/load.d.ts +7 -2
- package/dist/chains/summarization/load.js +14 -5
- package/dist/chat_models/anthropic.cjs +36 -9
- package/dist/chat_models/anthropic.d.ts +6 -3
- package/dist/chat_models/anthropic.js +36 -9
- package/dist/chat_models/base.cjs +40 -13
- package/dist/chat_models/base.d.ts +14 -7
- package/dist/chat_models/base.js +41 -14
- package/dist/chat_models/openai.cjs +20 -14
- package/dist/chat_models/openai.d.ts +2 -1
- package/dist/chat_models/openai.js +20 -14
- package/dist/client/index.cjs +5 -0
- package/dist/client/index.d.ts +1 -0
- package/dist/client/index.js +1 -0
- package/dist/client/langchainplus.cjs +405 -0
- package/dist/client/langchainplus.d.ts +65 -0
- package/dist/client/langchainplus.js +398 -0
- package/dist/document_loaders/fs/unstructured.cjs +8 -0
- package/dist/document_loaders/fs/unstructured.d.ts +3 -0
- package/dist/document_loaders/fs/unstructured.js +8 -0
- package/dist/document_loaders/web/apify_dataset.cjs +64 -0
- package/dist/document_loaders/web/apify_dataset.d.ts +28 -0
- package/dist/document_loaders/web/apify_dataset.js +60 -0
- package/dist/embeddings/openai.cjs +2 -2
- package/dist/embeddings/openai.js +2 -2
- package/dist/llms/base.cjs +43 -17
- package/dist/llms/base.d.ts +16 -9
- package/dist/llms/base.js +44 -18
- package/dist/llms/cohere.cjs +3 -2
- package/dist/llms/cohere.d.ts +1 -1
- package/dist/llms/cohere.js +3 -2
- package/dist/llms/hf.cjs +2 -2
- package/dist/llms/hf.d.ts +1 -1
- package/dist/llms/hf.js +2 -2
- package/dist/llms/openai-chat.cjs +13 -14
- package/dist/llms/openai-chat.d.ts +2 -1
- package/dist/llms/openai-chat.js +13 -14
- package/dist/llms/openai.cjs +15 -13
- package/dist/llms/openai.d.ts +4 -3
- package/dist/llms/openai.js +15 -13
- package/dist/llms/replicate.cjs +2 -2
- package/dist/llms/replicate.d.ts +1 -1
- package/dist/llms/replicate.js +2 -2
- package/dist/memory/base.cjs +9 -1
- package/dist/memory/base.d.ts +1 -0
- package/dist/memory/base.js +7 -0
- package/dist/memory/entity_memory.cjs +151 -0
- package/dist/memory/entity_memory.d.ts +35 -0
- package/dist/memory/entity_memory.js +147 -0
- package/dist/memory/index.cjs +5 -1
- package/dist/memory/index.d.ts +2 -0
- package/dist/memory/index.js +2 -0
- package/dist/memory/prompt.cjs +84 -1
- package/dist/memory/prompt.d.ts +6 -0
- package/dist/memory/prompt.js +83 -0
- package/dist/memory/stores/entity/in_memory.cjs +32 -0
- package/dist/memory/stores/entity/in_memory.d.ts +10 -0
- package/dist/memory/stores/entity/in_memory.js +28 -0
- package/dist/prompts/index.cjs +6 -1
- package/dist/prompts/index.d.ts +1 -0
- package/dist/prompts/index.js +1 -0
- package/dist/{chains/prompt_selector.d.ts → prompts/selectors/conditional.d.ts} +4 -4
- package/dist/retrievers/document_compressors/chain_extract.cjs +9 -11
- package/dist/retrievers/document_compressors/chain_extract.js +9 -11
- package/dist/schema/index.cjs +13 -1
- package/dist/schema/index.d.ts +19 -0
- package/dist/schema/index.js +11 -0
- package/dist/stores/message/dynamodb.cjs +8 -6
- package/dist/stores/message/dynamodb.js +8 -6
- package/dist/stores/message/redis.cjs +69 -0
- package/dist/stores/message/redis.d.ts +18 -0
- package/dist/stores/message/redis.js +65 -0
- package/dist/stores/message/utils.cjs +30 -15
- package/dist/stores/message/utils.d.ts +4 -2
- package/dist/stores/message/utils.js +28 -14
- package/dist/text_splitter.cjs +3 -23
- package/dist/text_splitter.d.ts +1 -3
- package/dist/text_splitter.js +3 -23
- package/dist/tools/webbrowser.cjs +5 -7
- package/dist/tools/webbrowser.js +3 -5
- package/dist/types/openai-types.d.ts +3 -2
- package/dist/util/async_caller.cjs +16 -0
- package/dist/util/async_caller.d.ts +4 -0
- package/dist/util/async_caller.js +16 -0
- package/dist/util/axios-fetch-adapter.cjs +6 -0
- package/dist/util/axios-fetch-adapter.js +6 -0
- package/dist/util/env.cjs +39 -7
- package/dist/util/env.d.ts +19 -0
- package/dist/util/env.js +32 -6
- package/dist/util/sql_utils.cjs +18 -0
- package/dist/util/sql_utils.js +19 -1
- package/dist/util/tiktoken.cjs +26 -0
- package/dist/util/tiktoken.d.ts +9 -0
- package/dist/util/tiktoken.js +21 -0
- package/dist/vectorstores/redis.cjs +236 -0
- package/dist/vectorstores/redis.d.ts +80 -0
- package/dist/vectorstores/redis.js +232 -0
- package/document_loaders/web/apify_dataset.cjs +1 -0
- package/document_loaders/web/apify_dataset.d.ts +1 -0
- package/document_loaders/web/apify_dataset.js +1 -0
- package/package.json +41 -5
- package/stores/message/redis.cjs +1 -0
- package/stores/message/redis.d.ts +1 -0
- package/stores/message/redis.js +1 -0
- package/vectorstores/redis.cjs +1 -0
- package/vectorstores/redis.d.ts +1 -0
- package/vectorstores/redis.js +1 -0
- package/dist/callbacks/handlers/tracers.cjs +0 -341
- package/dist/callbacks/handlers/tracers.d.ts +0 -100
- package/dist/callbacks/handlers/tracers.js +0 -336
- /package/dist/{chains/prompt_selector.cjs → prompts/selectors/conditional.cjs} +0 -0
- /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,
|
|
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
|
-
|
|
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
|
-
},
|
|
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
|
|
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
|
+
}
|