@cobrowser/chatgpt 0.7.31-beta.2 → 0.7.31-beta.4
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.
|
@@ -79,16 +79,22 @@ class BaseService {
|
|
|
79
79
|
// Skip constructor, non-functions, and utility methods
|
|
80
80
|
// But include service methods like getReply, getAssistant, etc.
|
|
81
81
|
if (methodName === 'constructor' ||
|
|
82
|
+
methodName === 'suggest' ||
|
|
82
83
|
typeof method !== 'function' ||
|
|
83
|
-
(methodName.startsWith('get') &&
|
|
84
|
+
(methodName.startsWith('get') &&
|
|
85
|
+
!methodName.startsWith('getReply') &&
|
|
86
|
+
!methodName.startsWith('getAssist') &&
|
|
87
|
+
!methodName.startsWith('getChatGPT')) ||
|
|
84
88
|
methodName.startsWith('handle') ||
|
|
85
89
|
methodName.includes('Sanitize') ||
|
|
86
90
|
methodName.includes('sanitize')) {
|
|
87
91
|
continue;
|
|
88
92
|
}
|
|
89
93
|
const originalMethod = method.bind(this);
|
|
94
|
+
console.log('ORIGINAL METHOD: ', originalMethod);
|
|
90
95
|
// Replace the method with a sanitizing wrapper
|
|
91
96
|
this[methodName] = (...args) => __awaiter(this, void 0, void 0, function* () {
|
|
97
|
+
console.log('WRAPPER args: ', args);
|
|
92
98
|
try {
|
|
93
99
|
const result = this.response(yield originalMethod(...args)), sanitizedResult = this.clean(result);
|
|
94
100
|
console.log('BASE SERVICE processAsyncMethods sanitizedResult: ', sanitizedResult);
|
|
@@ -116,7 +122,7 @@ class BaseService {
|
|
|
116
122
|
catch (error) { }
|
|
117
123
|
}
|
|
118
124
|
const sanitized = xss_validation_1.XSSProtector.sanitize(value), encoded = xss_validation_1.XSSProtector.encode(sanitized);
|
|
119
|
-
console.log('BASE SERVICE clean sanitized
|
|
125
|
+
console.log('BASE SERVICE clean sanitized aaaaa: ', sanitized);
|
|
120
126
|
console.log('BASE SERVICE clean encoded: ', encoded);
|
|
121
127
|
console.log('BASE SERVICE clean encoded data: ', encoded.result.data);
|
|
122
128
|
logger_1.default.info({ value, sanitized, encoded }, ':: Sanitized Response ::');
|
|
@@ -2,6 +2,7 @@ import ChatGptMessage from '../../models/ChatGptMessage';
|
|
|
2
2
|
import Item from '../../models/Item';
|
|
3
3
|
import BaseService from '../BaseService/BaseService';
|
|
4
4
|
import ChatGPTResponse from '../../models/ChatGPTResponse';
|
|
5
|
+
import ChatGPTUsageTokens from 'src/models/ChatGPTUsageTokens';
|
|
5
6
|
export declare class CopilotService extends BaseService {
|
|
6
7
|
assistantId: string | undefined;
|
|
7
8
|
threadId: string | undefined;
|
|
@@ -24,11 +25,18 @@ export declare class CopilotService extends BaseService {
|
|
|
24
25
|
* @param conversation the whole chat conversation
|
|
25
26
|
* @param items the items to recommend from
|
|
26
27
|
*/
|
|
27
|
-
recommend(conversation: ChatGptMessage[], items: Item[]): Promise<
|
|
28
|
+
recommend(conversation: ChatGptMessage[], items: Item[]): Promise<{
|
|
29
|
+
data: string | undefined;
|
|
30
|
+
usageTokens: ChatGPTUsageTokens | undefined;
|
|
31
|
+
}>;
|
|
32
|
+
getChatGPTQuickReplies(conversation: string): Promise<{
|
|
33
|
+
data: string | undefined;
|
|
34
|
+
usageTokens: ChatGPTUsageTokens | undefined;
|
|
35
|
+
}>;
|
|
28
36
|
/**
|
|
29
37
|
* Get the reply of the assistant if the assistant_id is available
|
|
30
38
|
*
|
|
31
39
|
* @param message
|
|
32
40
|
*/
|
|
33
|
-
getAssistantReply(
|
|
41
|
+
getAssistantReply(conversation: string): Promise<ChatGPTResponse | undefined>;
|
|
34
42
|
}
|
|
@@ -34,6 +34,7 @@ class CopilotService extends BaseService_1.default {
|
|
|
34
34
|
});
|
|
35
35
|
this.assistantId = assistantId;
|
|
36
36
|
this.threadId = threadId;
|
|
37
|
+
console.log('API URL: ', apiUrl);
|
|
37
38
|
}
|
|
38
39
|
/**
|
|
39
40
|
* a method to be used to suggest some quick replies for the agent based on the conversation
|
|
@@ -49,40 +50,17 @@ class CopilotService extends BaseService_1.default {
|
|
|
49
50
|
*/
|
|
50
51
|
suggest(conversation) {
|
|
51
52
|
return __awaiter(this, void 0, void 0, function* () {
|
|
53
|
+
console.log('SUGGEST conversation: ', conversation);
|
|
52
54
|
if (!(conversation === null || conversation === void 0 ? void 0 : conversation.length)) {
|
|
53
|
-
logger_1.default.error('
|
|
54
|
-
return Promise.reject(new Error('
|
|
55
|
+
logger_1.default.error('Conversation must be provided');
|
|
56
|
+
return Promise.reject(new Error('Conversation must be provided'));
|
|
55
57
|
}
|
|
56
58
|
try {
|
|
57
59
|
if (this.assistantId) {
|
|
58
|
-
|
|
59
|
-
// as we are doing with the other approach
|
|
60
|
-
const conversationArray = conversation.split('\n');
|
|
61
|
-
const lastCustomerMessage = conversationArray.reverse().find(e => e.includes('customer:'));
|
|
62
|
-
if (!lastCustomerMessage) {
|
|
63
|
-
logger_1.default.error('last customer message not found');
|
|
64
|
-
return Promise.reject(new Error('last customer message not found'));
|
|
65
|
-
}
|
|
66
|
-
return yield this.getAssistantReply(lastCustomerMessage);
|
|
60
|
+
return yield this.getAssistantReply(conversation);
|
|
67
61
|
}
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
Your response must only contains a valid JSON array of strings like this:
|
|
71
|
-
["Reply 1", "Reply 2", "Reply 3"]. the conversation is:-\n${conversation}`,
|
|
72
|
-
// main prompt will be the whole conversation as string
|
|
73
|
-
mainPromptMessage = {
|
|
74
|
-
role: ChatGptMessage_1.ChatGptRole.USER,
|
|
75
|
-
content: mainPrompt,
|
|
76
|
-
},
|
|
77
|
-
// the body we need to send to the request
|
|
78
|
-
requestBody = {
|
|
79
|
-
model: this.chatGptModel,
|
|
80
|
-
messages: [mainPromptMessage],
|
|
81
|
-
}, response = yield this.request.post('', requestBody);
|
|
82
|
-
return {
|
|
83
|
-
data: this.getResponseFirstChoice(response),
|
|
84
|
-
usageTokens: this.getResponseUsageTokens(response),
|
|
85
|
-
};
|
|
62
|
+
console.log('NOT ASSISTANT 111111111111');
|
|
63
|
+
return yield this.getChatGPTQuickReplies(conversation);
|
|
86
64
|
}
|
|
87
65
|
catch (e) {
|
|
88
66
|
this.handleErrors(e);
|
|
@@ -114,7 +92,10 @@ class CopilotService extends BaseService_1.default {
|
|
|
114
92
|
model: this.chatGptModel,
|
|
115
93
|
messages: [firstMessage, ...conversation],
|
|
116
94
|
}, response = yield this.request.post('', requestBody);
|
|
117
|
-
return
|
|
95
|
+
return {
|
|
96
|
+
data: this.getResponseFirstChoice(response),
|
|
97
|
+
usageTokens: this.getResponseUsageTokens(response),
|
|
98
|
+
};
|
|
118
99
|
}
|
|
119
100
|
catch (e) {
|
|
120
101
|
this.handleErrors(e);
|
|
@@ -122,29 +103,58 @@ class CopilotService extends BaseService_1.default {
|
|
|
122
103
|
}
|
|
123
104
|
});
|
|
124
105
|
}
|
|
106
|
+
getChatGPTQuickReplies(conversation) {
|
|
107
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
108
|
+
// main prompt used to instruct chatGPT to suggest some quick replies
|
|
109
|
+
const mainPrompt = `Propose some quick replies for the agent to be used on the following conversation
|
|
110
|
+
Your response must only contains a valid JSON array of strings like this:
|
|
111
|
+
["Reply 1", "Reply 2", "Reply 3"]. the conversation is:-\n${conversation}`,
|
|
112
|
+
// main prompt will be the whole conversation as string
|
|
113
|
+
mainPromptMessage = {
|
|
114
|
+
role: ChatGptMessage_1.ChatGptRole.USER,
|
|
115
|
+
content: mainPrompt,
|
|
116
|
+
},
|
|
117
|
+
// the body we need to send to the request
|
|
118
|
+
requestBody = {
|
|
119
|
+
model: this.chatGptModel,
|
|
120
|
+
messages: [mainPromptMessage],
|
|
121
|
+
}, response = yield this.request.post('', requestBody);
|
|
122
|
+
return {
|
|
123
|
+
data: this.getResponseFirstChoice(response),
|
|
124
|
+
usageTokens: this.getResponseUsageTokens(response),
|
|
125
|
+
};
|
|
126
|
+
});
|
|
127
|
+
}
|
|
125
128
|
/**
|
|
126
129
|
* Get the reply of the assistant if the assistant_id is available
|
|
127
130
|
*
|
|
128
131
|
* @param message
|
|
129
132
|
*/
|
|
130
|
-
getAssistantReply(
|
|
133
|
+
getAssistantReply(conversation) {
|
|
131
134
|
var _a;
|
|
132
135
|
return __awaiter(this, void 0, void 0, function* () {
|
|
136
|
+
console.log('getAssistantReply conversation: ', conversation);
|
|
137
|
+
// Here we get the last customer message as we dont need the whole conversation
|
|
138
|
+
// as we are doing with the other approach
|
|
139
|
+
const conversationArray = conversation.split('\n'), lastCustomerMessage = conversationArray.reverse().find(e => e.includes('customer:'));
|
|
140
|
+
if (!lastCustomerMessage) {
|
|
141
|
+
logger_1.default.error('last customer message not found');
|
|
142
|
+
return Promise.reject(new Error('last customer message not found'));
|
|
143
|
+
}
|
|
133
144
|
const openai = new openai_1.default({ apiKey: this.openaiApiKey });
|
|
134
145
|
let run;
|
|
135
146
|
if (!this.threadId) {
|
|
136
147
|
const thread = yield openai.beta.threads.create();
|
|
137
148
|
this.threadId = thread.id;
|
|
138
149
|
}
|
|
139
|
-
const lastThreadMessasges = yield openai.beta.threads.messages.list(this.threadId, { order: "desc", limit: 2 });
|
|
140
|
-
const isRepeatedMessage = lastThreadMessasges.data.find(msg => msg.content[0].type === 'text' && msg.content[0].text.value === message);
|
|
150
|
+
const lastThreadMessasges = yield openai.beta.threads.messages.list(this.threadId, { order: "desc", limit: 2 }), isRepeatedMessage = lastThreadMessasges.data.find(msg => msg.content[0].type === 'text' && msg.content[0].text.value === lastCustomerMessage);
|
|
141
151
|
// making sure that we're not saving repeated messages
|
|
142
152
|
if (isRepeatedMessage) {
|
|
143
153
|
const runs = yield openai.beta.threads.runs.list(this.threadId, { order: "desc", limit: 1 });
|
|
144
154
|
run = runs.data[0];
|
|
145
155
|
}
|
|
146
156
|
else {
|
|
147
|
-
yield openai.beta.threads.messages.create(this.threadId, { role: "user", content:
|
|
157
|
+
yield openai.beta.threads.messages.create(this.threadId, { role: "user", content: lastCustomerMessage });
|
|
148
158
|
run = yield openai.beta.threads.runs.create(this.threadId, { assistant_id: (_a = this.assistantId) !== null && _a !== void 0 ? _a : '' });
|
|
149
159
|
}
|
|
150
160
|
while (['queued', 'in_progress', 'cancelling'].includes(run.status)) {
|
|
@@ -152,13 +162,13 @@ class CopilotService extends BaseService_1.default {
|
|
|
152
162
|
run = yield openai.beta.threads.runs.retrieve(run.thread_id, run.id);
|
|
153
163
|
}
|
|
154
164
|
if (run.status === 'completed') {
|
|
155
|
-
const { data } = yield openai.beta.threads.messages.list(run.thread_id, { order: 'desc', limit: 1 });
|
|
156
|
-
|
|
157
|
-
const assistantMessages = messages.filter(message => typeof message === 'object' && 'value' in message && typeof message.value === 'string');
|
|
165
|
+
const { data } = yield openai.beta.threads.messages.list(run.thread_id, { order: 'desc', limit: 1 }), messages = data.flatMap((message) => message === null || message === void 0 ? void 0 : message.content.map((content) => ((content.type === 'text' && message.role === 'assistant') ? content.text : ''))), assistantMessages = messages.filter(message => typeof message === 'object' && 'value' in message && typeof message.value === 'string');
|
|
166
|
+
console.log('GET ASSISTANT REPLY assistantMessages: ', assistantMessages);
|
|
158
167
|
if (assistantMessages.length) {
|
|
159
168
|
let answers = assistantMessages.map(message => message.value);
|
|
169
|
+
console.log('GET ASSISTANT REPLY answers: ', answers);
|
|
160
170
|
return {
|
|
161
|
-
data:
|
|
171
|
+
data: answers,
|
|
162
172
|
threadId: run.thread_id,
|
|
163
173
|
usageTokens: run.usage,
|
|
164
174
|
};
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@cobrowser/chatgpt",
|
|
3
|
-
"version": "0.7.31-beta.
|
|
3
|
+
"version": "0.7.31-beta.4",
|
|
4
4
|
"description": "chatgpt services to connect our projects with chatgpt api",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"chatgpt",
|
|
@@ -40,5 +40,5 @@
|
|
|
40
40
|
"bugs": {
|
|
41
41
|
"url": "https://bitbucket.org/cobrowser/cb_utils/issues"
|
|
42
42
|
},
|
|
43
|
-
"gitHead": "
|
|
43
|
+
"gitHead": "a9c0febce4f98443c3845381f58816a71423d82c"
|
|
44
44
|
}
|