@rws-framework/ai-tools 0.0.1
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/.bin/add-v.sh +10 -0
- package/.bin/emerge.sh +11 -0
- package/.emerge-vis-output/rws-server/emerge-file_result_dependency_graph.graphml +2067 -0
- package/.emerge-vis-output/rws-server/emerge-filesystem_graph.graphml +1505 -0
- package/.emerge-vis-output/rws-server/emerge-statistics-and-metrics.json +1 -0
- package/.emerge-vis-output/rws-server/emerge-statistics-metrics.txt +1147 -0
- package/.emerge-vis-output/rws-server/html/emerge.html +501 -0
- package/.emerge-vis-output/rws-server/html/jsconfig.json +9 -0
- package/.emerge-vis-output/rws-server/html/resources/css/custom.css +211 -0
- package/.emerge-vis-output/rws-server/html/resources/js/emerge_common.js +45 -0
- package/.emerge-vis-output/rws-server/html/resources/js/emerge_data.js +13 -0
- package/.emerge-vis-output/rws-server/html/resources/js/emerge_git.js +1414 -0
- package/.emerge-vis-output/rws-server/html/resources/js/emerge_graph.js +539 -0
- package/.emerge-vis-output/rws-server/html/resources/js/emerge_heatmap.js +220 -0
- package/.emerge-vis-output/rws-server/html/resources/js/emerge_hull.js +180 -0
- package/.emerge-vis-output/rws-server/html/resources/js/emerge_main.js +1003 -0
- package/.emerge-vis-output/rws-server/html/resources/js/emerge_search.js +71 -0
- package/.emerge-vis-output/rws-server/html/resources/js/emerge_ui.js +199 -0
- package/.emerge-vis-output/rws-server/html/vendors/bootstrap/css/bootstrap-grid.css +4124 -0
- package/.emerge-vis-output/rws-server/html/vendors/bootstrap/css/bootstrap-grid.css.map +1 -0
- package/.emerge-vis-output/rws-server/html/vendors/bootstrap/css/bootstrap-grid.min.css +7 -0
- package/.emerge-vis-output/rws-server/html/vendors/bootstrap/css/bootstrap-grid.min.css.map +1 -0
- package/.emerge-vis-output/rws-server/html/vendors/bootstrap/css/bootstrap-grid.rtl.css +4123 -0
- package/.emerge-vis-output/rws-server/html/vendors/bootstrap/css/bootstrap-grid.rtl.css.map +1 -0
- package/.emerge-vis-output/rws-server/html/vendors/bootstrap/css/bootstrap-grid.rtl.min.css +7 -0
- package/.emerge-vis-output/rws-server/html/vendors/bootstrap/css/bootstrap-grid.rtl.min.css.map +1 -0
- package/.emerge-vis-output/rws-server/html/vendors/bootstrap/css/bootstrap-reboot.css +488 -0
- package/.emerge-vis-output/rws-server/html/vendors/bootstrap/css/bootstrap-reboot.css.map +1 -0
- package/.emerge-vis-output/rws-server/html/vendors/bootstrap/css/bootstrap-reboot.min.css +7 -0
- package/.emerge-vis-output/rws-server/html/vendors/bootstrap/css/bootstrap-reboot.min.css.map +1 -0
- package/.emerge-vis-output/rws-server/html/vendors/bootstrap/css/bootstrap-reboot.rtl.css +485 -0
- package/.emerge-vis-output/rws-server/html/vendors/bootstrap/css/bootstrap-reboot.rtl.css.map +1 -0
- package/.emerge-vis-output/rws-server/html/vendors/bootstrap/css/bootstrap-reboot.rtl.min.css +7 -0
- package/.emerge-vis-output/rws-server/html/vendors/bootstrap/css/bootstrap-reboot.rtl.min.css.map +1 -0
- package/.emerge-vis-output/rws-server/html/vendors/bootstrap/css/bootstrap-utilities.css +4266 -0
- package/.emerge-vis-output/rws-server/html/vendors/bootstrap/css/bootstrap-utilities.css.map +1 -0
- package/.emerge-vis-output/rws-server/html/vendors/bootstrap/css/bootstrap-utilities.min.css +7 -0
- package/.emerge-vis-output/rws-server/html/vendors/bootstrap/css/bootstrap-utilities.min.css.map +1 -0
- package/.emerge-vis-output/rws-server/html/vendors/bootstrap/css/bootstrap-utilities.rtl.css +4257 -0
- package/.emerge-vis-output/rws-server/html/vendors/bootstrap/css/bootstrap-utilities.rtl.css.map +1 -0
- package/.emerge-vis-output/rws-server/html/vendors/bootstrap/css/bootstrap-utilities.rtl.min.css +7 -0
- package/.emerge-vis-output/rws-server/html/vendors/bootstrap/css/bootstrap-utilities.rtl.min.css.map +1 -0
- package/.emerge-vis-output/rws-server/html/vendors/bootstrap/css/bootstrap.css +10878 -0
- package/.emerge-vis-output/rws-server/html/vendors/bootstrap/css/bootstrap.css.map +1 -0
- package/.emerge-vis-output/rws-server/html/vendors/bootstrap/css/bootstrap.min.css +7 -0
- package/.emerge-vis-output/rws-server/html/vendors/bootstrap/css/bootstrap.min.css.map +1 -0
- package/.emerge-vis-output/rws-server/html/vendors/bootstrap/css/bootstrap.rtl.css +10842 -0
- package/.emerge-vis-output/rws-server/html/vendors/bootstrap/css/bootstrap.rtl.css.map +1 -0
- package/.emerge-vis-output/rws-server/html/vendors/bootstrap/css/bootstrap.rtl.min.css +7 -0
- package/.emerge-vis-output/rws-server/html/vendors/bootstrap/css/bootstrap.rtl.min.css.map +1 -0
- package/.emerge-vis-output/rws-server/html/vendors/bootstrap/js/bootstrap.bundle.js +7075 -0
- package/.emerge-vis-output/rws-server/html/vendors/bootstrap/js/bootstrap.bundle.js.map +1 -0
- package/.emerge-vis-output/rws-server/html/vendors/bootstrap/js/bootstrap.bundle.min.js +7 -0
- package/.emerge-vis-output/rws-server/html/vendors/bootstrap/js/bootstrap.bundle.min.js.map +1 -0
- package/.emerge-vis-output/rws-server/html/vendors/bootstrap/js/bootstrap.esm.js +5202 -0
- package/.emerge-vis-output/rws-server/html/vendors/bootstrap/js/bootstrap.esm.js.map +1 -0
- package/.emerge-vis-output/rws-server/html/vendors/bootstrap/js/bootstrap.esm.min.js +7 -0
- package/.emerge-vis-output/rws-server/html/vendors/bootstrap/js/bootstrap.esm.min.js.map +1 -0
- package/.emerge-vis-output/rws-server/html/vendors/bootstrap/js/bootstrap.js +5249 -0
- package/.emerge-vis-output/rws-server/html/vendors/bootstrap/js/bootstrap.js.map +1 -0
- package/.emerge-vis-output/rws-server/html/vendors/bootstrap/js/bootstrap.min.js +7 -0
- package/.emerge-vis-output/rws-server/html/vendors/bootstrap/js/bootstrap.min.js.map +1 -0
- package/.emerge-vis-output/rws-server/html/vendors/d3/d3.v7.8.4.min.js +2 -0
- package/.emerge-vis-output/rws-server/html/vendors/d3/d3.v7.min.js +2 -0
- package/.emerge-vis-output/rws-server/html/vendors/dark-mode-switch/css/dark-mode.css +148 -0
- package/.emerge-vis-output/rws-server/html/vendors/dark-mode-switch/js/dark-mode-switch.min.js +1 -0
- package/.emerge-vis-output/rws-server/html/vendors/daterangepicker/daterangepicker.css +410 -0
- package/.emerge-vis-output/rws-server/html/vendors/daterangepicker/daterangepicker.min.js +8 -0
- package/.emerge-vis-output/rws-server/html/vendors/daterangepicker/moment.min.js +7 -0
- package/.emerge-vis-output/rws-server/html/vendors/hull/hull.js +373 -0
- package/.emerge-vis-output/rws-server/html/vendors/jquery/jquery-3.6.0.min.js +2 -0
- package/.emerge-vis-output/rws-server/html/vendors/popper/popper.min.js +6 -0
- package/.emerge-vis-output/rws-server/html/vendors/simpleheat/simpleheat.js +141 -0
- package/.eslintrc.json +53 -0
- package/README.md +862 -0
- package/package.json +49 -0
- package/src/index.ts +22 -0
- package/src/models/convo/ConvoLoader.ts +415 -0
- package/src/models/convo/VectorStore.ts +33 -0
- package/src/models/prompts/_prompt.ts +388 -0
- package/src/services/VectorStoreService.ts +15 -0
- package/tsconfig.json +24 -0
package/package.json
ADDED
|
@@ -0,0 +1,49 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "@rws-framework/ai-tools",
|
|
3
|
+
"private": false,
|
|
4
|
+
"version": "0.0.1",
|
|
5
|
+
"description": "",
|
|
6
|
+
"main": "src/index.ts",
|
|
7
|
+
"scripts": {
|
|
8
|
+
},
|
|
9
|
+
"author": "papablack",
|
|
10
|
+
"license": "ISC",
|
|
11
|
+
"dependencies": {
|
|
12
|
+
"@nestjs/common": "^10.3.2",
|
|
13
|
+
"@nestjs/core": "^10.3.2",
|
|
14
|
+
"@rws-framework/console": "*",
|
|
15
|
+
"@langchain/community": "^0.2.27",
|
|
16
|
+
"@langchain/core": "^0.2.27",
|
|
17
|
+
"langchain": "^0.2.16",
|
|
18
|
+
"uuid": "^9.0.0",
|
|
19
|
+
"xml2js": "^0.6.2"
|
|
20
|
+
},
|
|
21
|
+
"devDependencies": {
|
|
22
|
+
},
|
|
23
|
+
"resolutions": {
|
|
24
|
+
"@langchain/community/**/@langchain/core": "0.2.27",
|
|
25
|
+
"@langchain/core": "0.2.27",
|
|
26
|
+
"langchain": "0.2.16"
|
|
27
|
+
},
|
|
28
|
+
"jest": {
|
|
29
|
+
"moduleFileExtensions": [
|
|
30
|
+
"js",
|
|
31
|
+
"json",
|
|
32
|
+
"ts"
|
|
33
|
+
],
|
|
34
|
+
"rootDir": "src",
|
|
35
|
+
"testRegex": ".*\\.spec\\.ts$",
|
|
36
|
+
"transform": {
|
|
37
|
+
"^.+\\.(t|j)s$": "ts-jest"
|
|
38
|
+
},
|
|
39
|
+
"collectCoverageFrom": [
|
|
40
|
+
"**/*.(t|j)s"
|
|
41
|
+
],
|
|
42
|
+
"coverageDirectory": "../coverage",
|
|
43
|
+
"testEnvironment": "node"
|
|
44
|
+
},
|
|
45
|
+
"repository": {
|
|
46
|
+
"type": "git",
|
|
47
|
+
"url": "https://github.com/papablack/rws.git"
|
|
48
|
+
}
|
|
49
|
+
}
|
package/src/index.ts
ADDED
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
|
|
2
|
+
import RWSPrompt, { ILLMChunk, IRWSPromptRequestExecutor, IRWSSinglePromptRequestExecutor, IRWSPromptStreamExecutor, IChainCallOutput, IRWSPromptJSON, ChainStreamType } from './models/prompts/_prompt';
|
|
3
|
+
import RWSConvo, { IConvoDebugXMLData, IEmbeddingsHandler, ISplitterParams } from './models/convo/ConvoLoader';
|
|
4
|
+
import RWSVectorStore from './models/convo/VectorStore';
|
|
5
|
+
import { VectorStoreService } from './services/VectorStoreService';
|
|
6
|
+
|
|
7
|
+
export {
|
|
8
|
+
VectorStoreService,
|
|
9
|
+
RWSVectorStore,
|
|
10
|
+
RWSConvo,
|
|
11
|
+
RWSPrompt,
|
|
12
|
+
ILLMChunk,
|
|
13
|
+
IRWSPromptRequestExecutor,
|
|
14
|
+
IRWSSinglePromptRequestExecutor,
|
|
15
|
+
IRWSPromptStreamExecutor,
|
|
16
|
+
IChainCallOutput,
|
|
17
|
+
IRWSPromptJSON,
|
|
18
|
+
ChainStreamType,
|
|
19
|
+
IConvoDebugXMLData,
|
|
20
|
+
IEmbeddingsHandler,
|
|
21
|
+
ISplitterParams
|
|
22
|
+
};
|
|
@@ -0,0 +1,415 @@
|
|
|
1
|
+
import {AppConfigService, ConsoleService, RWSErrorCodes, InjectServices} from '@rws-framework/server';
|
|
2
|
+
|
|
3
|
+
import RWSPrompt, { IRWSPromptJSON, ILLMChunk } from '../prompts/_prompt';
|
|
4
|
+
import {VectorStoreService} from '../../services/VectorStoreService';
|
|
5
|
+
import RWSVectorStore, { VectorDocType } from './VectorStore';
|
|
6
|
+
|
|
7
|
+
import { Document } from 'langchain/document';
|
|
8
|
+
import { BaseChain, ConversationChain } from 'langchain/chains';
|
|
9
|
+
import { TextLoader } from 'langchain/document_loaders/fs/text';
|
|
10
|
+
import { RecursiveCharacterTextSplitter } from 'langchain/text_splitter';
|
|
11
|
+
import { BaseChatModel } from "@langchain/core/language_models/chat_models";
|
|
12
|
+
import { BaseLanguageModelInterface, BaseLanguageModelInput } from '@langchain/core/language_models/base';
|
|
13
|
+
import { PromptTemplate } from '@langchain/core/prompts';
|
|
14
|
+
import { RunnableConfig, Runnable } from '@langchain/core/runnables';
|
|
15
|
+
import { BaseMessage } from '@langchain/core/messages';
|
|
16
|
+
import { ChainValues } from '@langchain/core/utils/types';
|
|
17
|
+
|
|
18
|
+
import { v4 as uuid } from 'uuid';
|
|
19
|
+
import xml2js from 'xml2js';
|
|
20
|
+
import fs from 'fs';
|
|
21
|
+
import path from 'path';
|
|
22
|
+
|
|
23
|
+
|
|
24
|
+
const { Error500 } = RWSErrorCodes;
|
|
25
|
+
|
|
26
|
+
interface ISplitterParams {
|
|
27
|
+
chunkSize: number
|
|
28
|
+
chunkOverlap: number
|
|
29
|
+
separators: string[]
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
const logConvo = (txt: string) => {
|
|
33
|
+
ConsoleService.rwsLog(ConsoleService.color().blueBright(txt));
|
|
34
|
+
};
|
|
35
|
+
|
|
36
|
+
interface IBaseLangchainHyperParams {
|
|
37
|
+
temperature: number;
|
|
38
|
+
topK: number;
|
|
39
|
+
topP: number;
|
|
40
|
+
maxTokens: number;
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
interface IConvoDebugXMLData {
|
|
44
|
+
conversation: {
|
|
45
|
+
$: {
|
|
46
|
+
id: string
|
|
47
|
+
[key: string]: string
|
|
48
|
+
},
|
|
49
|
+
message: IRWSPromptJSON[]
|
|
50
|
+
}
|
|
51
|
+
}
|
|
52
|
+
|
|
53
|
+
interface IConvoDebugXMLOutput {
|
|
54
|
+
xml: IConvoDebugXMLData,
|
|
55
|
+
path: string
|
|
56
|
+
}
|
|
57
|
+
|
|
58
|
+
interface IChainCallOutput {
|
|
59
|
+
text: string
|
|
60
|
+
}
|
|
61
|
+
|
|
62
|
+
interface IEmbeddingsHandler<T extends object> {
|
|
63
|
+
generateEmbeddings: (text?: string) => Promise<T>
|
|
64
|
+
storeEmbeddings: (embeddings: any, convoId: string) => Promise<void>
|
|
65
|
+
}
|
|
66
|
+
|
|
67
|
+
type LLMType = BaseLanguageModelInterface | Runnable<BaseLanguageModelInput, string> | Runnable<BaseLanguageModelInput, BaseMessage>;
|
|
68
|
+
|
|
69
|
+
@InjectServices([VectorStoreService])
|
|
70
|
+
class ConvoLoader<LLMChat extends BaseChatModel> {
|
|
71
|
+
private loader: TextLoader;
|
|
72
|
+
private docSplitter: RecursiveCharacterTextSplitter;
|
|
73
|
+
|
|
74
|
+
private embeddings: IEmbeddingsHandler<any>;
|
|
75
|
+
|
|
76
|
+
private docs: Document[] = [];
|
|
77
|
+
private _initiated = false;
|
|
78
|
+
private store: RWSVectorStore;
|
|
79
|
+
private convo_id: string;
|
|
80
|
+
private llmChain: BaseChain;
|
|
81
|
+
private llmChat: LLMChat;
|
|
82
|
+
private chatConstructor: new (config: any) => LLMChat;
|
|
83
|
+
private thePrompt: RWSPrompt;
|
|
84
|
+
|
|
85
|
+
vectorStoreService: VectorStoreService;
|
|
86
|
+
configService: AppConfigService;
|
|
87
|
+
|
|
88
|
+
public _baseSplitterParams: ISplitterParams;
|
|
89
|
+
|
|
90
|
+
constructor(chatConstructor: new (config: any) => LLMChat, embeddings: IEmbeddingsHandler<any> | null = null, convoId: string | null = null, baseSplitterParams: ISplitterParams = {
|
|
91
|
+
chunkSize:400, chunkOverlap:80, separators: ['/n/n','.']
|
|
92
|
+
}){
|
|
93
|
+
this.embeddings = embeddings;
|
|
94
|
+
|
|
95
|
+
if(convoId === null){
|
|
96
|
+
this.convo_id = ConvoLoader.uuid();
|
|
97
|
+
} else {
|
|
98
|
+
this.convo_id = convoId;
|
|
99
|
+
}
|
|
100
|
+
|
|
101
|
+
this.chatConstructor = chatConstructor;
|
|
102
|
+
this._baseSplitterParams = baseSplitterParams;
|
|
103
|
+
}
|
|
104
|
+
|
|
105
|
+
static uuid(): string
|
|
106
|
+
{
|
|
107
|
+
return uuid();
|
|
108
|
+
}
|
|
109
|
+
|
|
110
|
+
|
|
111
|
+
async splitDocs(filePath: string, params: ISplitterParams)
|
|
112
|
+
{
|
|
113
|
+
|
|
114
|
+
if(!this.embeddings){
|
|
115
|
+
throw new Error500('No embeddings provided for ConvoLoader\'s constructor. ConvoLoader.splitDocs aborting...');
|
|
116
|
+
}
|
|
117
|
+
|
|
118
|
+
const splitDir = ConvoLoader.debugSplitDir(this.getId());
|
|
119
|
+
|
|
120
|
+
if(!fs.existsSync(splitDir)){
|
|
121
|
+
console.log(`Split dir ${ConsoleService.color().magentaBright(splitDir)} doesn't exist. Splitting docs...`);
|
|
122
|
+
this.loader = new TextLoader(filePath);
|
|
123
|
+
|
|
124
|
+
this.docSplitter = new RecursiveCharacterTextSplitter({
|
|
125
|
+
chunkSize: params.chunkSize, // The size of the chunk that should be split.
|
|
126
|
+
chunkOverlap: params.chunkOverlap, // Adding overalap so that if a text is broken inbetween, next document may have part of the previous document
|
|
127
|
+
separators: params.separators // In this case we are assuming that /n/n would mean one whole sentence. In case there is no nearing /n/n then "." will be used instead. This can be anything that helps derive a complete sentence .
|
|
128
|
+
});
|
|
129
|
+
|
|
130
|
+
fs.mkdirSync(splitDir, { recursive: true });
|
|
131
|
+
|
|
132
|
+
const orgDocs = await this.loader.load();
|
|
133
|
+
const splitDocs = await this.docSplitter.splitDocuments(orgDocs);
|
|
134
|
+
|
|
135
|
+
const avgCharCountPre = this.avgDocLength(orgDocs);
|
|
136
|
+
const avgCharCountPost = this.avgDocLength(splitDocs);
|
|
137
|
+
|
|
138
|
+
logConvo(`Average length among ${orgDocs.length} documents loaded is ${avgCharCountPre} characters.`);
|
|
139
|
+
logConvo(`After the split we have ${splitDocs.length} documents more than the original ${orgDocs.length}.`);
|
|
140
|
+
logConvo(`Average length among ${orgDocs.length} documents (after split) is ${avgCharCountPost} characters.`);
|
|
141
|
+
|
|
142
|
+
this.docs = splitDocs;
|
|
143
|
+
|
|
144
|
+
let i = 0;
|
|
145
|
+
this.docs.forEach((doc: Document) => {
|
|
146
|
+
fs.writeFileSync(this.debugSplitFile(i), doc.pageContent);
|
|
147
|
+
i++;
|
|
148
|
+
});
|
|
149
|
+
}else{
|
|
150
|
+
const splitFiles = fs.readdirSync(splitDir);
|
|
151
|
+
|
|
152
|
+
for(const filePath of splitFiles) {
|
|
153
|
+
const txt = fs.readFileSync(splitDir + '/' + filePath, 'utf-8');
|
|
154
|
+
this.docs.push(new Document({ pageContent: txt }));
|
|
155
|
+
}
|
|
156
|
+
}
|
|
157
|
+
|
|
158
|
+
this.store = await this.vectorStoreService.createStore(this.docs, await this.embeddings.generateEmbeddings());
|
|
159
|
+
}
|
|
160
|
+
|
|
161
|
+
getId(): string {
|
|
162
|
+
return this.convo_id;
|
|
163
|
+
}
|
|
164
|
+
|
|
165
|
+
getDocs(): VectorDocType
|
|
166
|
+
{
|
|
167
|
+
return this.docs;
|
|
168
|
+
}
|
|
169
|
+
getStore(): RWSVectorStore
|
|
170
|
+
{
|
|
171
|
+
return this.store;
|
|
172
|
+
}
|
|
173
|
+
|
|
174
|
+
isInitiated(): boolean
|
|
175
|
+
{
|
|
176
|
+
return this._initiated;
|
|
177
|
+
}
|
|
178
|
+
|
|
179
|
+
setPrompt(prompt: RWSPrompt): ConvoLoader<LLMChat>
|
|
180
|
+
{
|
|
181
|
+
this.thePrompt = prompt;
|
|
182
|
+
|
|
183
|
+
this.llmChat = new this.chatConstructor({
|
|
184
|
+
streaming: true,
|
|
185
|
+
region: this.configService.get('aws_bedrock_region'),
|
|
186
|
+
credentials: {
|
|
187
|
+
accessKeyId: this.configService.get('aws_access_key'),
|
|
188
|
+
secretAccessKey: this.configService.get('aws_secret_key'),
|
|
189
|
+
},
|
|
190
|
+
model: 'anthropic.claude-v2',
|
|
191
|
+
maxTokens: prompt.getHyperParameter<number>('max_tokens_to_sample'),
|
|
192
|
+
temperature: prompt.getHyperParameter<number>('temperature'),
|
|
193
|
+
modelKwargs: {
|
|
194
|
+
top_p: prompt.getHyperParameter<number>('top_p'),
|
|
195
|
+
top_k: prompt.getHyperParameter<number>('top_k'),
|
|
196
|
+
}
|
|
197
|
+
});
|
|
198
|
+
|
|
199
|
+
return this;
|
|
200
|
+
}
|
|
201
|
+
|
|
202
|
+
getChat(): LLMChat
|
|
203
|
+
{
|
|
204
|
+
return this.llmChat;
|
|
205
|
+
}
|
|
206
|
+
|
|
207
|
+
private avgDocLength = (documents: Document[]): number => {
|
|
208
|
+
return documents.reduce((sum, doc: Document) => sum + doc.pageContent.length, 0) / documents.length;
|
|
209
|
+
};
|
|
210
|
+
|
|
211
|
+
async call(values: ChainValues, cfg: Partial<RunnableConfig>, debugCallback: (debugData: IConvoDebugXMLData) => Promise<IConvoDebugXMLData> = null): Promise<RWSPrompt>
|
|
212
|
+
{
|
|
213
|
+
const output = await (this.chain()).invoke(values, cfg) as IChainCallOutput;
|
|
214
|
+
this.thePrompt.listen(output.text);
|
|
215
|
+
|
|
216
|
+
await this.debugCall(debugCallback);
|
|
217
|
+
|
|
218
|
+
return this.thePrompt;
|
|
219
|
+
}
|
|
220
|
+
|
|
221
|
+
async *callStreamGenerator(
|
|
222
|
+
this: ConvoLoader<LLMChat>,
|
|
223
|
+
values: ChainValues,
|
|
224
|
+
cfg: Partial<RunnableConfig>,
|
|
225
|
+
debugCallback: (debugData: IConvoDebugXMLData) => Promise<IConvoDebugXMLData> = null
|
|
226
|
+
): AsyncGenerator<string>
|
|
227
|
+
{
|
|
228
|
+
// const _self = this;
|
|
229
|
+
// const chain = this.chain() as ConversationChain;
|
|
230
|
+
// console.log('call stream');
|
|
231
|
+
// const stream = await chain.call(values, [{
|
|
232
|
+
// handleLLMNewToken(token: string) {
|
|
233
|
+
// yield token;
|
|
234
|
+
// }
|
|
235
|
+
// }
|
|
236
|
+
// ]);
|
|
237
|
+
|
|
238
|
+
// console.log('got stream');
|
|
239
|
+
|
|
240
|
+
|
|
241
|
+
|
|
242
|
+
// Listen to the stream and yield data chunks as they come
|
|
243
|
+
// for await (const chunk of stream) {
|
|
244
|
+
// yield chunk.response;
|
|
245
|
+
// }
|
|
246
|
+
}
|
|
247
|
+
|
|
248
|
+
async callStream(values: ChainValues, callback: (streamChunk: ILLMChunk) => void, end: () => void = () => {}, cfg: Partial<RunnableConfig> = {}, debugCallback?: (debugData: IConvoDebugXMLData) => Promise<IConvoDebugXMLData>): Promise<RWSPrompt>
|
|
249
|
+
{
|
|
250
|
+
const _self = this;
|
|
251
|
+
|
|
252
|
+
await this.chain().invoke(values, { callbacks: [{
|
|
253
|
+
handleLLMNewToken(token: string) {
|
|
254
|
+
callback({
|
|
255
|
+
content: token,
|
|
256
|
+
status: 'rws_streaming'
|
|
257
|
+
});
|
|
258
|
+
|
|
259
|
+
_self.thePrompt.listen(token, true);
|
|
260
|
+
}
|
|
261
|
+
}
|
|
262
|
+
]});
|
|
263
|
+
|
|
264
|
+
end();
|
|
265
|
+
|
|
266
|
+
this.debugCall(debugCallback);
|
|
267
|
+
|
|
268
|
+
return this.thePrompt;
|
|
269
|
+
}
|
|
270
|
+
|
|
271
|
+
async similaritySearch(query: string, splitCount: number): Promise<string>
|
|
272
|
+
{
|
|
273
|
+
console.log('Store is ready. Searching for embedds...');
|
|
274
|
+
const texts = await this.getStore().getFaiss().similaritySearchWithScore(`${query}`, splitCount);
|
|
275
|
+
console.log('Found best parts: ' + texts.length);
|
|
276
|
+
return texts.map(([doc, score]: [any, number]) => `${doc['pageContent']}`).join('\n\n');
|
|
277
|
+
}
|
|
278
|
+
|
|
279
|
+
private async debugCall(debugCallback: (debugData: IConvoDebugXMLData) => Promise<IConvoDebugXMLData> = null)
|
|
280
|
+
{
|
|
281
|
+
try {
|
|
282
|
+
const debug = this.initDebugFile();
|
|
283
|
+
|
|
284
|
+
let callData: IConvoDebugXMLData = debug.xml;
|
|
285
|
+
|
|
286
|
+
callData.conversation.message.push(this.thePrompt.toJSON());
|
|
287
|
+
|
|
288
|
+
if(debugCallback){
|
|
289
|
+
callData = await debugCallback(callData);
|
|
290
|
+
}
|
|
291
|
+
|
|
292
|
+
this.debugSave(callData);
|
|
293
|
+
|
|
294
|
+
}catch(error: Error | unknown){
|
|
295
|
+
console.log(error);
|
|
296
|
+
}
|
|
297
|
+
}
|
|
298
|
+
|
|
299
|
+
chain(): BaseChain
|
|
300
|
+
{
|
|
301
|
+
if(this.llmChain){
|
|
302
|
+
return this.llmChain;
|
|
303
|
+
}
|
|
304
|
+
|
|
305
|
+
if(!this.thePrompt){
|
|
306
|
+
throw new Error500(new Error('No prompt initialized for conversation'), __filename);
|
|
307
|
+
}
|
|
308
|
+
|
|
309
|
+
const chainParams: { prompt: PromptTemplate, values?: ChainValues } = {
|
|
310
|
+
prompt: this.thePrompt.getMultiTemplate()
|
|
311
|
+
};
|
|
312
|
+
|
|
313
|
+
this.createChain(chainParams);
|
|
314
|
+
|
|
315
|
+
return this.llmChain;
|
|
316
|
+
}
|
|
317
|
+
|
|
318
|
+
private async createChain(input: { prompt: PromptTemplate, values?: ChainValues }): Promise<BaseChain>
|
|
319
|
+
{
|
|
320
|
+
this.llmChain = new ConversationChain({
|
|
321
|
+
llm: this.llmChat,
|
|
322
|
+
prompt: input.prompt,
|
|
323
|
+
});
|
|
324
|
+
|
|
325
|
+
return this.llmChain;
|
|
326
|
+
}
|
|
327
|
+
|
|
328
|
+
async waitForInit(): Promise<ConvoLoader<LLMChat> | null>
|
|
329
|
+
{
|
|
330
|
+
const _self = this;
|
|
331
|
+
return new Promise((resolve, reject)=>{
|
|
332
|
+
let i = 0;
|
|
333
|
+
|
|
334
|
+
const interval: NodeJS.Timeout = setInterval(() => {
|
|
335
|
+
if(this.isInitiated()){
|
|
336
|
+
clearInterval(interval);
|
|
337
|
+
resolve(_self);
|
|
338
|
+
}
|
|
339
|
+
|
|
340
|
+
if(i>9){
|
|
341
|
+
clearInterval(interval);
|
|
342
|
+
reject(null);
|
|
343
|
+
}
|
|
344
|
+
|
|
345
|
+
i++;
|
|
346
|
+
}, 300);
|
|
347
|
+
});
|
|
348
|
+
}
|
|
349
|
+
|
|
350
|
+
private parseXML(xml: string, callback: (err: Error, result: any) => void): xml2js.Parser
|
|
351
|
+
{
|
|
352
|
+
const parser = new xml2js.Parser();
|
|
353
|
+
|
|
354
|
+
parser.parseString(xml, callback);
|
|
355
|
+
return parser;
|
|
356
|
+
}
|
|
357
|
+
|
|
358
|
+
static debugConvoDir(id: string){
|
|
359
|
+
return path.resolve(process.cwd(), 'debug', 'conversations', id);
|
|
360
|
+
}
|
|
361
|
+
|
|
362
|
+
static debugSplitDir(id: string){
|
|
363
|
+
return path.resolve(process.cwd(), 'debug', 'conversations', id, 'split');
|
|
364
|
+
}
|
|
365
|
+
|
|
366
|
+
public debugConvoFile(){
|
|
367
|
+
return `${ConvoLoader.debugConvoDir(this.getId())}/conversation.xml`;
|
|
368
|
+
}
|
|
369
|
+
|
|
370
|
+
public debugSplitFile(i: number){
|
|
371
|
+
return `${ConvoLoader.debugSplitDir(this.getId())}/${i}.splitfile`;
|
|
372
|
+
}
|
|
373
|
+
|
|
374
|
+
private initDebugFile(): IConvoDebugXMLOutput
|
|
375
|
+
{
|
|
376
|
+
let xmlContent: string;
|
|
377
|
+
let debugXML: IConvoDebugXMLData = null;
|
|
378
|
+
|
|
379
|
+
const convoDir = ConvoLoader.debugConvoDir(this.getId());
|
|
380
|
+
|
|
381
|
+
if(!fs.existsSync(convoDir)){
|
|
382
|
+
fs.mkdirSync(convoDir, { recursive: true });
|
|
383
|
+
}
|
|
384
|
+
|
|
385
|
+
const convoFilePath = this.debugConvoFile();
|
|
386
|
+
|
|
387
|
+
if(!fs.existsSync(convoFilePath)){
|
|
388
|
+
xmlContent = '<conversation id="conversation"></conversation>';
|
|
389
|
+
|
|
390
|
+
fs.writeFileSync(convoFilePath, xmlContent);
|
|
391
|
+
}else{
|
|
392
|
+
xmlContent = fs.readFileSync(convoFilePath, 'utf-8');
|
|
393
|
+
}
|
|
394
|
+
|
|
395
|
+
this.parseXML(xmlContent, (error: Error, result) => {
|
|
396
|
+
debugXML = result;
|
|
397
|
+
});
|
|
398
|
+
|
|
399
|
+
if(!debugXML.conversation.message){
|
|
400
|
+
debugXML.conversation.message = [];
|
|
401
|
+
}
|
|
402
|
+
|
|
403
|
+
return { xml: debugXML, path: convoFilePath };
|
|
404
|
+
}
|
|
405
|
+
|
|
406
|
+
private debugSave(xml: IConvoDebugXMLData): void
|
|
407
|
+
{
|
|
408
|
+
const builder = new xml2js.Builder();
|
|
409
|
+
fs.writeFileSync(this.debugConvoFile(), builder.buildObject(xml), 'utf-8');
|
|
410
|
+
}
|
|
411
|
+
|
|
412
|
+
}
|
|
413
|
+
|
|
414
|
+
export default ConvoLoader;
|
|
415
|
+
export { IChainCallOutput, IConvoDebugXMLData, IEmbeddingsHandler, ISplitterParams, IBaseLangchainHyperParams };
|
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
import { FaissStore } from '@langchain/community/vectorstores/faiss';
|
|
2
|
+
import { EmbeddingsInterface } from '@langchain/core/embeddings';
|
|
3
|
+
import { Document } from '@langchain/core/documents';
|
|
4
|
+
|
|
5
|
+
type VectorDocType = Document<Record<string, any>>[];
|
|
6
|
+
|
|
7
|
+
export default class RWSVectorStore
|
|
8
|
+
{
|
|
9
|
+
private faiss: FaissStore;
|
|
10
|
+
private docs: VectorDocType;
|
|
11
|
+
private embeddings: EmbeddingsInterface;
|
|
12
|
+
|
|
13
|
+
constructor(docs: VectorDocType, embeddings: EmbeddingsInterface){
|
|
14
|
+
this.docs = docs;
|
|
15
|
+
this.embeddings = embeddings;
|
|
16
|
+
}
|
|
17
|
+
|
|
18
|
+
async init(): Promise<RWSVectorStore>
|
|
19
|
+
{
|
|
20
|
+
this.faiss = await FaissStore.fromDocuments(this.docs, this.embeddings);
|
|
21
|
+
|
|
22
|
+
return this;
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
getFaiss(): FaissStore
|
|
26
|
+
{
|
|
27
|
+
return this.faiss;
|
|
28
|
+
}
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
export {
|
|
32
|
+
VectorDocType
|
|
33
|
+
};
|