@cellaware/utils 3.0.13 → 3.1.13

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/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@cellaware/utils",
3
- "version": "3.0.13",
3
+ "version": "3.1.13",
4
4
  "description": "Cellaware Utilities for Node.js",
5
5
  "author": "Cellaware Technologies",
6
6
  "type": "module",
@@ -1,13 +0,0 @@
1
- export declare const COSMOS_CURRENT_YEAR_CLAUSE = "DateTimePart('yyyy', GetCurrentDateTime())";
2
- export declare const COSMOS_RECORD_YEAR_CLAUSE = "DateTimePart('yyyy', TimestampToDateTime(c._ts*1000))";
3
- export declare const COSMOS_CURRENT_MONTH_CLAUSE = "DateTimePart('mm', GetCurrentDateTime())";
4
- export declare const COSMOS_RECORD_MONTH_CLAUSE = "DateTimePart('mm', TimestampToDateTime(c._ts*1000))";
5
- export declare const COSMOS_CURRENT_DAY_CLAUSE = "DateTimePart('dd', GetCurrentDateTime())";
6
- export declare const COSMOS_RECORD_DAY_CLAUSE = "DateTimePart('dd', TimestampToDateTime(c._ts*1000))";
7
- export declare const COSMOS_CURRENT_DAY_CONDITION_CLAUSE = "DateTimeDiff('dd', TimestampToDateTime(c._ts*1000), GetCurrentDateTime()) = 0";
8
- export declare const COSMOS_CURRENT_MONTH_CONDITION_CLAUSE = "DateTimeDiff('mm', TimestampToDateTime(c._ts*1000), GetCurrentDateTime()) = 0";
9
- export declare const COSMOS_CURRENT_YEAR_CONDITION_CLAUSE = "DateTimeDiff('yyyy', TimestampToDateTime(c._ts*1000), GetCurrentDateTime()) = 0";
10
- export declare function cosmosSelect(databaseId: string, collectionId: string, partitionKey: string, query: string): Promise<any[]>;
11
- export declare function cosmosInsert(databaseId: string, collectionId: string, partitionKey: string, data: any): Promise<boolean>;
12
- export declare function cosmosDelete(databaseId: string, collectionId: string, partitionKey: string, query: string): Promise<boolean>;
13
- export declare function cosmosUpdate(databaseId: string, collectionId: string, partitionKey: string, query: string, data: any): Promise<boolean>;
@@ -1,83 +0,0 @@
1
- import { CosmosClient } from '@azure/cosmos';
2
- export const COSMOS_CURRENT_YEAR_CLAUSE = `DateTimePart('yyyy', GetCurrentDateTime())`;
3
- export const COSMOS_RECORD_YEAR_CLAUSE = `DateTimePart('yyyy', TimestampToDateTime(c._ts*1000))`;
4
- export const COSMOS_CURRENT_MONTH_CLAUSE = `DateTimePart('mm', GetCurrentDateTime())`;
5
- export const COSMOS_RECORD_MONTH_CLAUSE = `DateTimePart('mm', TimestampToDateTime(c._ts*1000))`;
6
- export const COSMOS_CURRENT_DAY_CLAUSE = `DateTimePart('dd', GetCurrentDateTime())`;
7
- export const COSMOS_RECORD_DAY_CLAUSE = `DateTimePart('dd', TimestampToDateTime(c._ts*1000))`;
8
- export const COSMOS_CURRENT_DAY_CONDITION_CLAUSE = `DateTimeDiff('dd', TimestampToDateTime(c._ts*1000), GetCurrentDateTime()) = 0`;
9
- export const COSMOS_CURRENT_MONTH_CONDITION_CLAUSE = `DateTimeDiff('mm', TimestampToDateTime(c._ts*1000), GetCurrentDateTime()) = 0`;
10
- export const COSMOS_CURRENT_YEAR_CONDITION_CLAUSE = `DateTimeDiff('yyyy', TimestampToDateTime(c._ts*1000), GetCurrentDateTime()) = 0`;
11
- export async function cosmosSelect(databaseId, collectionId, partitionKey, query) {
12
- try {
13
- const cosmosClient = new CosmosClient({
14
- endpoint: process.env.COSMOS_DB_ENDPOINT ?? '',
15
- key: process.env.COSMOS_DB_KEY ?? ''
16
- });
17
- const { database } = await cosmosClient.databases.createIfNotExists({ id: databaseId });
18
- const { container } = await database.containers.createIfNotExists({
19
- id: collectionId,
20
- partitionKey
21
- });
22
- const { resources } = await container.items.query({
23
- query
24
- }).fetchAll();
25
- return resources;
26
- }
27
- catch (err) {
28
- console.log(`COSMOS: Read error: ${err.message}`);
29
- return [];
30
- }
31
- }
32
- export async function cosmosInsert(databaseId, collectionId, partitionKey, data) {
33
- try {
34
- const cosmosClient = new CosmosClient({
35
- endpoint: process.env.COSMOS_DB_ENDPOINT ?? '',
36
- key: process.env.COSMOS_DB_KEY ?? ''
37
- });
38
- const { database } = await cosmosClient.databases.createIfNotExists({ id: databaseId });
39
- const { container } = await database.containers.createIfNotExists({
40
- id: collectionId,
41
- partitionKey
42
- });
43
- await container.items.create(data);
44
- return true;
45
- }
46
- catch (err) {
47
- console.log(`COSMOS: Write error: ${err.message}`);
48
- return false;
49
- }
50
- }
51
- export async function cosmosDelete(databaseId, collectionId, partitionKey, query) {
52
- try {
53
- const cosmosClient = new CosmosClient({
54
- endpoint: process.env.COSMOS_DB_ENDPOINT ?? '',
55
- key: process.env.COSMOS_DB_KEY ?? ''
56
- });
57
- const { database } = await cosmosClient.databases.createIfNotExists({ id: databaseId });
58
- const { container } = await database.containers.createIfNotExists({
59
- id: collectionId,
60
- partitionKey
61
- });
62
- const { resources } = await container.items.query({
63
- query
64
- }).fetchAll();
65
- resources.forEach(doc => {
66
- container.item(doc.id, doc.clientId).delete();
67
- });
68
- return true;
69
- }
70
- catch (err) {
71
- console.log(`COSMOS: Delete error: ${err.message}`);
72
- return false;
73
- }
74
- }
75
- // Delete then insert -- partial item updates not possible.
76
- export async function cosmosUpdate(databaseId, collectionId, partitionKey, query, data) {
77
- const delRes = await cosmosDelete(databaseId, collectionId, partitionKey, query);
78
- if (!delRes) {
79
- return delRes;
80
- }
81
- const insRes = await cosmosInsert(databaseId, collectionId, partitionKey, data);
82
- return insRes;
83
- }
@@ -1,2 +0,0 @@
1
- export declare function functionFetchJson(url: string, method: string, key: string, body?: any): Promise<any>;
2
- export declare function functionFetchText(url: string, method: string, key: string, text: string): Promise<any>;
@@ -1,56 +0,0 @@
1
- import { sleep } from "../util.js";
2
- const STATUS_INTERNAL_SERVER_ERROR = 500;
3
- const STATUS_SERVICE_UNAVAILABLE = 503;
4
- const RETRY_SLEEP_MS = 3000;
5
- const MAX_RETRIES = 3;
6
- async function functionFetch(url, req) {
7
- let res;
8
- let status = STATUS_SERVICE_UNAVAILABLE;
9
- let retryNum = 0;
10
- do {
11
- if (retryNum > 0) {
12
- await sleep(RETRY_SLEEP_MS);
13
- }
14
- try {
15
- res = await fetch(url, req);
16
- status = res.status;
17
- }
18
- catch (err) {
19
- // if at max retries throw the error
20
- if (retryNum === MAX_RETRIES) {
21
- throw err;
22
- }
23
- }
24
- retryNum++;
25
- } while (retryNum < MAX_RETRIES &&
26
- (status === STATUS_INTERNAL_SERVER_ERROR || status === STATUS_SERVICE_UNAVAILABLE));
27
- return res;
28
- }
29
- export async function functionFetchJson(url, method, key, body) {
30
- const headers = {
31
- 'Content-Type': 'application/json',
32
- 'Accept': 'application/json',
33
- 'x-functions-key': key
34
- };
35
- let req = {
36
- method,
37
- headers
38
- };
39
- if (body != null) {
40
- req.body = JSON.stringify(body);
41
- }
42
- return functionFetch(url, req);
43
- }
44
- export async function functionFetchText(url, method, key, text) {
45
- const headers = {
46
- 'Content-Type': 'application/text',
47
- 'Accept': 'application/json',
48
- 'x-functions-key': key
49
- };
50
- let req = {
51
- method,
52
- headers,
53
- body: text
54
- };
55
- return functionFetch(url, req);
56
- }
@@ -1,4 +0,0 @@
1
- export declare function storageContainerCreate(containerClientId: string): Promise<void>;
2
- export declare function storageBlobUpload(containerClientId: string, blobId: string, data: any): Promise<void>;
3
- export declare function storageBlobDelete(containerClientId: string, blobId: string): Promise<void>;
4
- export declare function storageBlobDownload(containerClientId: string, blobId: string): Promise<any[]>;
@@ -1,67 +0,0 @@
1
- import { BlobServiceClient } from '@azure/storage-blob';
2
- function streamToBuffer(stream) {
3
- return new Promise((resolve, reject) => {
4
- const chunks = [];
5
- stream.on("data", (data) => {
6
- chunks.push(Buffer.isBuffer(data) ? data : Buffer.from(data));
7
- });
8
- stream.on("end", () => {
9
- resolve(Buffer.concat(chunks));
10
- });
11
- stream.on("error", reject);
12
- });
13
- }
14
- export async function storageContainerCreate(containerClientId) {
15
- try {
16
- const blobServiceClient = BlobServiceClient.fromConnectionString(process.env.STORAGE_CONNECTION_STRING ?? '');
17
- const containerClient = blobServiceClient.getContainerClient(containerClientId);
18
- await containerClient.create();
19
- }
20
- catch (err) {
21
- console.log(`STORAGE: CONTAINER create error: ${err.message}`);
22
- }
23
- }
24
- export async function storageBlobUpload(containerClientId, blobId, data) {
25
- try {
26
- const blobServiceClient = BlobServiceClient.fromConnectionString(process.env.STORAGE_CONNECTION_STRING ?? '');
27
- const containerClient = blobServiceClient.getContainerClient(containerClientId);
28
- const blockBlobClient = containerClient.getBlockBlobClient(blobId);
29
- await blockBlobClient.upload(data, data.length);
30
- }
31
- catch (err) {
32
- console.log(`STORAGE: BLOB upload error: ${err.message}`);
33
- }
34
- }
35
- export async function storageBlobDelete(containerClientId, blobId) {
36
- try {
37
- const blobServiceClient = BlobServiceClient.fromConnectionString(process.env.STORAGE_CONNECTION_STRING ?? '');
38
- const containerClient = blobServiceClient.getContainerClient(containerClientId);
39
- const blockBlobClient = containerClient.getBlockBlobClient(blobId);
40
- await blockBlobClient.delete();
41
- }
42
- catch (err) {
43
- console.log(`STORAGE: BLOB delete error: ${err.message}`);
44
- }
45
- }
46
- export async function storageBlobDownload(containerClientId, blobId) {
47
- if (!process.env.STORAGE_CONNECTION_STRING) {
48
- console.log(`STORAGE: No connection string set`);
49
- return [];
50
- }
51
- try {
52
- const blobServiceClient = BlobServiceClient.fromConnectionString(process.env.STORAGE_CONNECTION_STRING ?? '');
53
- const containerClient = blobServiceClient.getContainerClient(containerClientId);
54
- const blockBlobClient = containerClient.getBlockBlobClient(blobId);
55
- const downloadBlockBlobResponse = await blockBlobClient.download(0);
56
- let data;
57
- if (downloadBlockBlobResponse.readableStreamBody) {
58
- let buf = await streamToBuffer(downloadBlockBlobResponse.readableStreamBody);
59
- data = buf.toString();
60
- }
61
- return JSON.parse(data);
62
- }
63
- catch (err) {
64
- console.log(`STORAGE: BLOB download error: ${err.message}`);
65
- }
66
- return [];
67
- }
@@ -1,4 +0,0 @@
1
- export declare function chatwmsCosmosSelect(collectionId: string, query: string): Promise<any[]>;
2
- export declare function chatwmsCosmosInsert(collectionId: string, data: any): Promise<boolean>;
3
- export declare function chatwmsCosmosDelete(collectionId: string, query: string): Promise<boolean>;
4
- export declare function chatwmsCosmosUpdate(collectionId: string, query: string, data: any): Promise<boolean>;
@@ -1,15 +0,0 @@
1
- import { cosmosDelete, cosmosInsert, cosmosSelect, cosmosUpdate } from "../../azure/cosmos.js";
2
- const DATABASE_ID = 'chatwms';
3
- const PARTITION_KEY = '/clientId';
4
- export async function chatwmsCosmosSelect(collectionId, query) {
5
- return cosmosSelect(DATABASE_ID, collectionId, PARTITION_KEY, query);
6
- }
7
- export async function chatwmsCosmosInsert(collectionId, data) {
8
- return cosmosInsert(DATABASE_ID, collectionId, PARTITION_KEY, data);
9
- }
10
- export async function chatwmsCosmosDelete(collectionId, query) {
11
- return cosmosDelete(DATABASE_ID, collectionId, PARTITION_KEY, query);
12
- }
13
- export async function chatwmsCosmosUpdate(collectionId, query, data) {
14
- return cosmosUpdate(DATABASE_ID, collectionId, PARTITION_KEY, query, data);
15
- }
@@ -1,2 +0,0 @@
1
- export declare function chatwmsFunctionFetch(path: string, method: string, body?: any): Promise<any>;
2
- export declare function chatwmsFunctionQuery(path: string, method: string, query: string): Promise<any>;
@@ -1,9 +0,0 @@
1
- import { functionFetchJson, functionFetchText } from "../../azure/function.js";
2
- export function chatwmsFunctionFetch(path, method, body) {
3
- const url = `${process.env['CHATWMS_URL']}/${path}`;
4
- return functionFetchJson(url, method, process.env['CHATWMS_KEY'] ?? '', body);
5
- }
6
- export function chatwmsFunctionQuery(path, method, query) {
7
- const url = `${process.env['CHATWMS_URL']}/${path}`;
8
- return functionFetchText(url, method, process.env['CHATWMS_KEY'] ?? '', query);
9
- }
@@ -1,5 +0,0 @@
1
- export declare function chatwmsStorageGetBlobId(clientId: string, blobName: string): string;
2
- export declare function chatwmsStorageContainerCreate(): Promise<void>;
3
- export declare function chatwmsStorageBlobUpload(blobId: string, data: any): Promise<void>;
4
- export declare function chatwmsStorageBlobDelete(blobId: string): Promise<void>;
5
- export declare function chatwmsStorageBlobDownload(blobId: string): Promise<any[]>;
@@ -1,17 +0,0 @@
1
- import { storageBlobDelete, storageBlobDownload, storageBlobUpload, storageContainerCreate } from "../../azure/storage.js";
2
- const CONTAINER_CLIENT_ID = 'chatwms';
3
- export function chatwmsStorageGetBlobId(clientId, blobName) {
4
- return clientId.replace('_', '-') + '-' + blobName;
5
- }
6
- export async function chatwmsStorageContainerCreate() {
7
- return storageContainerCreate(CONTAINER_CLIENT_ID);
8
- }
9
- export async function chatwmsStorageBlobUpload(blobId, data) {
10
- return storageBlobUpload(CONTAINER_CLIENT_ID, blobId, data);
11
- }
12
- export async function chatwmsStorageBlobDelete(blobId) {
13
- return storageBlobDelete(CONTAINER_CLIENT_ID, blobId);
14
- }
15
- export async function chatwmsStorageBlobDownload(blobId) {
16
- return storageBlobDownload(CONTAINER_CLIENT_ID, blobId);
17
- }
@@ -1,2 +0,0 @@
1
- export declare const CHATWMS_GENERIC_CLIENT_ID = "chatwms";
2
- export declare function chatwmsGetClientId(customer: string, warehouse: string): string;
@@ -1,4 +0,0 @@
1
- export const CHATWMS_GENERIC_CLIENT_ID = 'chatwms';
2
- export function chatwmsGetClientId(customer, warehouse) {
3
- return `${customer}_${warehouse}`;
4
- }
@@ -1 +0,0 @@
1
- export declare function chatwmsGithubCreateIssue(title: string, body: any, labels: string[]): Promise<boolean>;
@@ -1,4 +0,0 @@
1
- import { githubCreateIssue } from "../../github/issue.js";
2
- export async function chatwmsGithubCreateIssue(title, body, labels) {
3
- return githubCreateIssue(`https://api.github.com/repos/cellaware/chatwms-feedback/issues`, title, body, labels);
4
- }
@@ -1 +0,0 @@
1
- export declare function chatwmsGetProductId(vendor: string, version: string): string;
@@ -1,3 +0,0 @@
1
- export function chatwmsGetProductId(vendor, version) {
2
- return `${vendor}_${version}`;
3
- }
@@ -1,6 +0,0 @@
1
- export interface ChatWMSUserData {
2
- userId: string;
3
- userDetails: string;
4
- identityProvider: string;
5
- }
6
- export declare function chatwmsInitUserData(): ChatWMSUserData;
@@ -1,7 +0,0 @@
1
- export function chatwmsInitUserData() {
2
- return {
3
- userId: '',
4
- userDetails: '',
5
- identityProvider: ''
6
- };
7
- }
@@ -1 +0,0 @@
1
- export declare function githubCreateIssue(issueUrl: string, issueTitle: string, issueBody: any, issueLabels: string[]): Promise<boolean>;
@@ -1,23 +0,0 @@
1
- export async function githubCreateIssue(issueUrl, issueTitle, issueBody, issueLabels) {
2
- const token = process.env.GITHUB_TOKEN ?? '';
3
- if (token.length === 0) {
4
- throw new Error('GITHUB: `GITHUB_TOKEN` environment variable is not set');
5
- }
6
- const headers = {
7
- 'Authorization': `token ${token}`,
8
- 'X-GitHub-Api-Version': '2022-11-28',
9
- 'Accept': 'application/vnd.github+json'
10
- };
11
- const body = {
12
- title: issueTitle,
13
- body: issueBody,
14
- labels: issueLabels
15
- };
16
- const req = {
17
- method: 'POST',
18
- headers,
19
- body: JSON.stringify(body)
20
- };
21
- let res = await fetch(issueUrl, req);
22
- return res.ok;
23
- }
@@ -1,50 +0,0 @@
1
- import { BaseChain } from 'langchain/chains';
2
- import { ModelName } from './model.js';
3
- /**
4
- * `SingleActionChain` only supports single interaction with LLM, and only 1
5
- * output key is allowed. Output key is defaulted to `answer`.
6
- */
7
- export declare class SingleActionChain extends BaseChain {
8
- private name;
9
- private llm;
10
- private _inputKeys;
11
- private _outputKey;
12
- private prompt;
13
- private promptTemplate;
14
- constructor(fields: any, name: string, inputKeys: string[]);
15
- _call(values: any, runManager: any): Promise<any>;
16
- _chainType(): string;
17
- get inputKeys(): string[];
18
- get outputKeys(): string[];
19
- getModelName(): ModelName;
20
- getPrompt(): string;
21
- }
22
- export declare function createSingleActionChain(name: string, modelName: ModelName, inputKeys: string[], prompt: string, temperature?: number, verbose?: boolean): SingleActionChain;
23
- /**
24
- * A `ChainStore` is a chain registry and calling interface. The `ChainStore`
25
- * keeps a map of all registered chains.
26
- *
27
- * The following chains are built-in:
28
- * - `translation_chain`: `translate()`
29
- *
30
- */
31
- export declare class ChainStore {
32
- private promptsPath;
33
- private chains;
34
- constructor(promptsPath: string, defaultModelName?: ModelName);
35
- private initBuiltinChains;
36
- private static getTokenUsage;
37
- private getPrompt;
38
- /**
39
- * - `name`: Chain name
40
- * - `modelName`: OpenAI model name
41
- * - `temperature`: OpenAI model temperature
42
- * - `verbose`: OpenAI verbose parameter
43
- * - `templateName`: Template chain name to copy prompt from
44
- */
45
- addChain(name: string, modelName: ModelName, temperature?: number, verbose?: boolean, templateName?: string): void;
46
- addExistingChain(chain: SingleActionChain): void;
47
- callChain(name: string, args: any, tokenUsages: any[]): Promise<import("langchain/dist/schema/index.js").ChainValues>;
48
- translate(statement: string, language: string, tokenUsages?: any[]): Promise<string>;
49
- getPrompts(): string;
50
- }
@@ -1,270 +0,0 @@
1
- import fs from 'fs';
2
- import { ChatOpenAI } from 'langchain/chat_models/openai';
3
- import { PromptTemplate } from 'langchain/prompts';
4
- import { LLMChain, BaseChain } from 'langchain/chains';
5
- import { getLLMTransactionCost } from './cost.js';
6
- const CHAIN_TIMEOUT_MS = 150_000;
7
- const TRANSLATION_CHAIN_NAME = 'translation_chain';
8
- /**
9
- * `SingleActionChain` only supports single interaction with LLM, and only 1
10
- * output key is allowed. Output key is defaulted to `answer`.
11
- */
12
- export class SingleActionChain extends BaseChain {
13
- constructor(fields, name, inputKeys) {
14
- super(fields);
15
- Object.defineProperty(this, "name", {
16
- enumerable: true,
17
- configurable: true,
18
- writable: true,
19
- value: void 0
20
- });
21
- Object.defineProperty(this, "llm", {
22
- enumerable: true,
23
- configurable: true,
24
- writable: true,
25
- value: void 0
26
- });
27
- Object.defineProperty(this, "_inputKeys", {
28
- enumerable: true,
29
- configurable: true,
30
- writable: true,
31
- value: void 0
32
- });
33
- Object.defineProperty(this, "_outputKey", {
34
- enumerable: true,
35
- configurable: true,
36
- writable: true,
37
- value: void 0
38
- });
39
- Object.defineProperty(this, "prompt", {
40
- enumerable: true,
41
- configurable: true,
42
- writable: true,
43
- value: void 0
44
- });
45
- Object.defineProperty(this, "promptTemplate", {
46
- enumerable: true,
47
- configurable: true,
48
- writable: true,
49
- value: void 0
50
- });
51
- if (inputKeys.length == 0) {
52
- throw new Error(`SINGLE_ACTION_CHAIN: Chain '${name}' needs at least one input key!`);
53
- }
54
- this.name = name;
55
- this.llm = fields.llm;
56
- this._inputKeys = inputKeys;
57
- this._outputKey = 'answer';
58
- this.prompt = fields.prompt;
59
- this.promptTemplate = new PromptTemplate({
60
- template: fields.prompt,
61
- inputVariables: this.inputKeys
62
- });
63
- }
64
- async _call(values, runManager) {
65
- let output = {
66
- [this._outputKey]: ''
67
- };
68
- const llmChain = new LLMChain({
69
- prompt: this.promptTemplate,
70
- llm: this.llm,
71
- outputKey: this._outputKey,
72
- memory: this.memory,
73
- });
74
- let llmInputs = {};
75
- for (const inputKey of this._inputKeys) {
76
- llmInputs[inputKey] = values[inputKey];
77
- }
78
- const llmAnswer = await llmChain.predict(llmInputs, runManager?.getChild());
79
- output[this._outputKey] = llmAnswer;
80
- return output;
81
- }
82
- _chainType() {
83
- return this.name;
84
- }
85
- get inputKeys() {
86
- return this._inputKeys;
87
- }
88
- get outputKeys() {
89
- return [this._outputKey];
90
- }
91
- getModelName() {
92
- return this.llm.modelName;
93
- }
94
- getPrompt() {
95
- return this.prompt;
96
- }
97
- }
98
- export function createSingleActionChain(name, modelName, inputKeys, prompt, temperature, verbose) {
99
- const llm = new ChatOpenAI({
100
- modelName, temperature: temperature ?? 0, configuration: {
101
- organization: process.env.OPENAI_ORGANIZATION,
102
- timeout: CHAIN_TIMEOUT_MS
103
- }
104
- });
105
- return new SingleActionChain({
106
- llm,
107
- prompt,
108
- verbose: verbose ?? false
109
- }, name, inputKeys);
110
- }
111
- /**
112
- * A `ChainStore` is a chain registry and calling interface. The `ChainStore`
113
- * keeps a map of all registered chains.
114
- *
115
- * The following chains are built-in:
116
- * - `translation_chain`: `translate()`
117
- *
118
- */
119
- export class ChainStore {
120
- constructor(promptsPath, defaultModelName) {
121
- Object.defineProperty(this, "promptsPath", {
122
- enumerable: true,
123
- configurable: true,
124
- writable: true,
125
- value: void 0
126
- });
127
- Object.defineProperty(this, "chains", {
128
- enumerable: true,
129
- configurable: true,
130
- writable: true,
131
- value: void 0
132
- });
133
- this.promptsPath = promptsPath;
134
- this.chains = new Map();
135
- this.initBuiltinChains(defaultModelName);
136
- }
137
- initBuiltinChains(defaultModelName) {
138
- // Translation Chain:
139
- {
140
- this.addExistingChain(createSingleActionChain(TRANSLATION_CHAIN_NAME, defaultModelName ?? 'gpt-4o-mini', ['statement', 'language'], `You are a helpful AI translator who translates an English statement to {language}.
141
-
142
- Given an English statement, translate the English statement into {language}.
143
-
144
- Here is the English statement that you need to translate to {language}:
145
- {statement}
146
-
147
- Your translation here:
148
- `));
149
- }
150
- }
151
- static getTokenUsage(chainName, modelName, tokenUsage) {
152
- return {
153
- chain: chainName,
154
- model: modelName,
155
- tokenUsage,
156
- cost: getLLMTransactionCost(tokenUsage, modelName)
157
- };
158
- }
159
- getPrompt(chainName, templateChainName) {
160
- let prompt = {
161
- content: '',
162
- variables: []
163
- };
164
- const path = !!templateChainName ? `${this.promptsPath}/${templateChainName}.md` : `${this.promptsPath}/${chainName}.md`;
165
- if (!fs.existsSync(path)) {
166
- throw new Error(`CHAIN_STORE: Prompt file '${path}' not found`);
167
- }
168
- const content = fs.readFileSync(path, 'utf8');
169
- if (content.length === 0) {
170
- throw new Error(`CHAIN_STORE: Prompt file '${path}' is empty`);
171
- }
172
- let matches = content.matchAll(/{.*?}/gm);
173
- let distinctMatches = new Set();
174
- for (const match of Array.from(matches)) {
175
- let matchStr = match[0];
176
- // Exclude escaped curly braces.
177
- if (!matchStr.startsWith('{{')) {
178
- distinctMatches.add(matchStr.substring(1, matchStr.length - 1));
179
- }
180
- }
181
- prompt.content = content;
182
- prompt.variables = Array.from(distinctMatches);
183
- return prompt;
184
- }
185
- /**
186
- * - `name`: Chain name
187
- * - `modelName`: OpenAI model name
188
- * - `temperature`: OpenAI model temperature
189
- * - `verbose`: OpenAI verbose parameter
190
- * - `templateName`: Template chain name to copy prompt from
191
- */
192
- addChain(name, modelName, temperature, verbose, templateName) {
193
- const prompt = this.getPrompt(name, templateName);
194
- const llm = new ChatOpenAI({
195
- modelName, temperature: temperature ?? 0, configuration: {
196
- organization: process.env.OPENAI_ORGANIZATION,
197
- timeout: CHAIN_TIMEOUT_MS
198
- }
199
- });
200
- const chain = new SingleActionChain({
201
- llm,
202
- prompt: prompt.content,
203
- verbose: verbose ?? false
204
- }, name, prompt.variables);
205
- this.chains.set(name, chain);
206
- }
207
- addExistingChain(chain) {
208
- this.chains.set(chain._chainType(), chain);
209
- }
210
- async callChain(name, args, tokenUsages) {
211
- let chain = this.chains.get(name);
212
- if (!chain) {
213
- throw new Error(`CHAIN_STORE: Chain '${name}' does not exist`);
214
- }
215
- let presentInputKeySet = new Set();
216
- for (const inputKey of Object.keys(args)) {
217
- presentInputKeySet.add(inputKey);
218
- }
219
- let presentInputKeys = Array.from(presentInputKeySet);
220
- // Make sure all input keys are present.
221
- for (const inputKey of chain.inputKeys) {
222
- if (!presentInputKeys.includes(inputKey)) {
223
- throw new Error(`CHAIN_STORE: Input key '${inputKey}' not present for chain '${chain._chainType()}'`);
224
- }
225
- }
226
- return await chain.call(args, [
227
- {
228
- handleLLMEnd: async (cbOutput) => {
229
- tokenUsages.push(ChainStore.getTokenUsage(chain._chainType(), chain.getModelName(), cbOutput.llmOutput?.tokenUsage));
230
- },
231
- }
232
- ]);
233
- }
234
- async translate(statement, language, tokenUsages) {
235
- // No need to translate if requested language is in default language.
236
- const DEFAULT_LANGUAGE = 'English';
237
- if (language.toLowerCase() === DEFAULT_LANGUAGE.toLowerCase()) {
238
- return statement;
239
- }
240
- const translationAnswer = await this.callChain(TRANSLATION_CHAIN_NAME, { statement, language }, tokenUsages ?? []);
241
- let translationAnswerStr = translationAnswer.answer;
242
- /*
243
- Need to check if AI indicator exists in the answer. It is possible that the
244
- translation chain will include this in an answer. Pretty sure this happens
245
- because the translation chain can see conversation history, and messages from
246
- AI will be prefixed as such.
247
- */
248
- const AI_PREFIX = 'AI: ';
249
- if (translationAnswerStr.includes(AI_PREFIX)) {
250
- console.log(`ANALYST: Removing AI indicator from translation answer`);
251
- translationAnswerStr = translationAnswerStr.substring(translationAnswerStr.indexOf(AI_PREFIX) + AI_PREFIX.length);
252
- }
253
- // Remove 'Your translation here:' if it is there.
254
- if (translationAnswerStr.includes('Your translation here:')) {
255
- translationAnswerStr = translationAnswerStr.substring(translationAnswerStr.indexOf('Your translation here:') + 'Your translation here:'.length);
256
- }
257
- return translationAnswerStr.trim();
258
- }
259
- getPrompts() {
260
- let buf = '';
261
- for (const chain of Array.from(this.chains.values())) {
262
- buf += `================================================= =================================================
263
- ${chain._chainType()}
264
- ================================================= =================================================
265
- ${chain.getPrompt()}
266
- `;
267
- }
268
- return buf;
269
- }
270
- }
@@ -1,3 +0,0 @@
1
- import { ModelName } from "./model";
2
- export declare function getLLMCostPerToken(modelName: ModelName): any;
3
- export declare function getLLMTransactionCost(tokenUsage: any, modelName: ModelName): number;
package/dist/llm/cost.js DELETED
@@ -1,59 +0,0 @@
1
- // https://openai.com/pricing
2
- export function getLLMCostPerToken(modelName) {
3
- let inputCost = 0.0;
4
- let outputCost = 0.0;
5
- switch (modelName) {
6
- case 'o1-preview':
7
- inputCost = 0.015;
8
- outputCost = 0.060;
9
- break;
10
- case 'o1-mini':
11
- inputCost = 0.003;
12
- outputCost = 0.012;
13
- break;
14
- case 'gpt-4o':
15
- inputCost = 0.005;
16
- outputCost = 0.015;
17
- break;
18
- case 'gpt-4o-2024-08-06':
19
- inputCost = 0.0025;
20
- outputCost = 0.010;
21
- break;
22
- case 'gpt-4o-mini':
23
- inputCost = 0.00015;
24
- outputCost = 0.0006;
25
- break;
26
- case 'gpt-4-turbo':
27
- inputCost = 0.01;
28
- outputCost = 0.03;
29
- break;
30
- case 'gpt-4':
31
- inputCost = 0.03;
32
- outputCost = 0.06;
33
- break;
34
- case 'gpt-4-32k':
35
- inputCost = 0.06;
36
- outputCost = 0.12;
37
- break;
38
- case 'gpt-3.5-turbo':
39
- inputCost = 0.0005;
40
- outputCost = 0.0015;
41
- break;
42
- default:
43
- inputCost = 0.0;
44
- outputCost = 0.0;
45
- break;
46
- }
47
- // OpenAI model costs are measured in thousands of tokens -- therefore we need to divide each figure by 1000 before returning.
48
- inputCost /= 1000.0;
49
- outputCost /= 1000.0;
50
- return { inputCost, outputCost };
51
- }
52
- export function getLLMTransactionCost(tokenUsage, modelName) {
53
- let cost = 0.0;
54
- if (!!tokenUsage) {
55
- const { inputCost, outputCost } = getLLMCostPerToken(modelName);
56
- cost = (tokenUsage.promptTokens * inputCost) + (tokenUsage.completionTokens * outputCost);
57
- }
58
- return cost;
59
- }
@@ -1 +0,0 @@
1
- export type ModelName = 'o1-preview' | 'o1-mini' | 'gpt-4o' | 'gpt-4o-2024-08-06' | 'gpt-4o-mini' | 'gpt-4-turbo' | 'gpt-4' | 'gpt-4-32k' | 'gpt-3.5-turbo';
package/dist/llm/model.js DELETED
@@ -1 +0,0 @@
1
- export {};
package/dist/util.d.ts DELETED
@@ -1,9 +0,0 @@
1
- export declare function sleep(ms: number): Promise<any>;
2
- export declare function removeMarkdownIndicators(input: string): string;
3
- export declare function removePrefixIndicators(input: string, prefixes: string[]): string;
4
- export declare function isLeapYear(): boolean;
5
- export declare function getDaysInMonth(): number;
6
- export declare function getCurrentDayInMonth(): number;
7
- export declare function getDaysInYear(): 366 | 365;
8
- export declare function getCurrentMonth(): number;
9
- export declare function getCurrentYear(): number;
package/dist/util.js DELETED
@@ -1,49 +0,0 @@
1
- export async function sleep(ms) {
2
- return new Promise(resolve => setTimeout(resolve, ms));
3
- }
4
- export function removeMarkdownIndicators(input) {
5
- let output = input;
6
- // Make sure markdown indicator exists.
7
- if (output.includes('```')) {
8
- // Remove first markdown indicator.
9
- output = output.substring(output.indexOf('```'));
10
- output = output.substring(output.indexOf('\n'));
11
- // First markdown indicator removed, now do the last.
12
- output = output.substring(0, output.indexOf('```')).trim();
13
- }
14
- return output;
15
- }
16
- export function removePrefixIndicators(input, prefixes) {
17
- let output = input;
18
- for (const prefix of prefixes) {
19
- if (output.includes(prefix)) {
20
- output = output.substring(output.indexOf(prefix) + prefix.length);
21
- }
22
- }
23
- return output;
24
- }
25
- export function isLeapYear() {
26
- let year = new Date().getFullYear();
27
- return ((year % 4 == 0) && (year % 100 != 0)) || (year % 400 == 0);
28
- }
29
- export function getDaysInMonth() {
30
- let date = new Date();
31
- // NOTE: month is 0-based.
32
- return new Date(date.getFullYear(), date.getMonth() + 1, 0).getDate();
33
- }
34
- export function getCurrentDayInMonth() {
35
- let date = new Date();
36
- return date.getDate();
37
- }
38
- export function getDaysInYear() {
39
- return isLeapYear() ? 366 : 365;
40
- }
41
- export function getCurrentMonth() {
42
- let date = new Date();
43
- // NOTE: month is 0-based.
44
- return date.getMonth() + 1;
45
- }
46
- export function getCurrentYear() {
47
- let date = new Date();
48
- return date.getFullYear();
49
- }