@cobrowser/chatgpt 0.7.32-dev.0 → 0.7.32-dev.2
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/dist/constants.d.ts +2 -2
- package/dist/constants.js +23 -19
- package/dist/models/ChatGPTMessage.d.ts +17 -0
- package/dist/models/ChatGPTMessage.js +9 -0
- package/dist/models/ChatGPTResponse.d.ts +8 -0
- package/dist/models/ChatGPTResponse.js +2 -0
- package/dist/models/ChatGPTUsageTokens.d.ts +6 -0
- package/dist/models/ChatGPTUsageTokens.js +2 -0
- package/dist/models/ConversationHistory.d.ts +3 -3
- package/dist/models/Item.d.ts +2 -2
- package/dist/models/Response.d.ts +3 -0
- package/dist/models/Response.js +2 -0
- package/dist/services/AssistantService/AssistantService.d.ts +3 -3
- package/dist/services/AssistantService/AssistantService.js +11 -9
- package/dist/services/BaseService/BaseService.d.ts +14 -6
- package/dist/services/BaseService/BaseService.js +67 -7
- package/dist/services/ChatService/ChatService.d.ts +2 -1
- package/dist/services/ChatService/ChatService.js +14 -9
- package/dist/services/CopilotService/CopilotService.d.ts +9 -10
- package/dist/services/CopilotService/CopilotService.js +57 -63
- package/dist/services/ResponseService/ResponseService.d.ts +3 -6
- package/dist/services/ResponseService/ResponseService.js +76 -96
- package/dist/services/TranslationService/TranslationService.d.ts +4 -4
- package/dist/services/TranslationService/TranslationService.js +14 -11
- package/dist/utils/Response.d.ts +4 -0
- package/dist/utils/Response.js +11 -0
- package/dist/utils/constants.d.ts +13 -0
- package/dist/utils/constants.js +69 -0
- package/package.json +3 -2
package/dist/constants.d.ts
CHANGED
|
@@ -6,8 +6,8 @@ export declare const MESSAGE_TYPES: {
|
|
|
6
6
|
text: string;
|
|
7
7
|
button: string;
|
|
8
8
|
};
|
|
9
|
-
export declare const DEFAULT_PROMPT = "You are a helpful assistant. Your role is to address visitor \
|
|
9
|
+
export declare const DEFAULT_PROMPT = "\n You are a helpful assistant. Your role is to address visitor \n queries related to the ongoing conversation and the last message received. Please ensure \n that responses remain within the ongoing conversation. Politely decline any user queries \n that is not present in the ongoing conversation. \n\n You will always respond with a JSON. It will be in the format: \n\n { answer: '', suggestions: [], connectWithAgent: true or false }\n\n Fields in the JSON:\n\n Answer: It will consist of the user's query answer based on the ongoing conversation. \n Restrict this field to 100 characters.\n\n Suggestions: Request 2 suggestions from user's perspective that he can ask. \n It should be an array of strings. Restrict each suggestion to 50 characters.\n \n ConnectWithAgent: It is a boolean. It should be set to true if the user's query is \n not found in the ongoing conversation. Politely tell the user to talk to a real agent. \n Also when it is true, do not provide any suggestions.\n";
|
|
10
10
|
export declare const DESTINATION_LANGUAGE = "English";
|
|
11
11
|
export declare const LANGUAGE_DETECTION_SYSTEM_ROLE = "\n You are a language detection assistant. Your task is to analyze short text input and determine \n its language using ISO language code. Respond only in JSON format with two key-value pairs: \n - 'languageCode': the detected language's ISO code (or undefined if detection fails).\n - 'isError': a boolean value (true if detection fails, false otherwise).\n";
|
|
12
12
|
export declare const WORD_FREQUENCY_LANGUAGE_DETECTION_SYSTEM_ROLE = "\n You are a language detection assistant. Your task is to analyze the most frequently occurring words in the given text \n and determine the language based on those words. Respond only in JSON format with two key-value pairs: \n - 'languageCode': the detected language's ISO code (or undefined if detection fails).\n - 'isError': a boolean value (true if detection fails, false otherwise).\n";
|
|
13
|
-
export declare const TRANSLATION_SYSTEM_ROLE = "\n You are a translator that responds exclusively in JSON format. Your response must be a JSON object containing:\n - '
|
|
13
|
+
export declare const TRANSLATION_SYSTEM_ROLE = "\n You are a translator that responds exclusively in JSON format. Your response must be a JSON object containing:\n - 'translations': it is an array of objects. Each object in the array must contain:\n - 'original': The original input message before translation.\n - 'translation: The translated version of 'original', ensuring it is natural, culturally appropriate, and commonly used by native speakers.\n - 'isError': a boolean value (true if translation fails, false otherwise).\n\n **You MUST return the JSON format even if you fail to translate the text. In this case, translations field will be empty array and isError should be true.** \n\n Ensure that 'translation' accurately represents the meaning of 'original' while considering cultural nuances, usual expressions, and natural phrasing in the target language.\n\n Your response must follow this structure strictly.\n";
|
package/dist/constants.js
CHANGED
|
@@ -12,26 +12,27 @@ exports.MESSAGE_TYPES = {
|
|
|
12
12
|
button: 'button'
|
|
13
13
|
};
|
|
14
14
|
// Default prompt for ChatGPT
|
|
15
|
-
exports.DEFAULT_PROMPT = `
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
that
|
|
15
|
+
exports.DEFAULT_PROMPT = `
|
|
16
|
+
You are a helpful assistant. Your role is to address visitor
|
|
17
|
+
queries related to the ongoing conversation and the last message received. Please ensure
|
|
18
|
+
that responses remain within the ongoing conversation. Politely decline any user queries
|
|
19
|
+
that is not present in the ongoing conversation.
|
|
19
20
|
|
|
20
|
-
You will always respond with a JSON. It will be in the format:
|
|
21
|
+
You will always respond with a JSON. It will be in the format:
|
|
21
22
|
|
|
22
|
-
{ answer: '', suggestions: [], connectWithAgent: true or false }
|
|
23
|
+
{ answer: '', suggestions: [], connectWithAgent: true or false }
|
|
23
24
|
|
|
24
|
-
Fields in the JSON:
|
|
25
|
+
Fields in the JSON:
|
|
25
26
|
|
|
26
|
-
Answer: It will consist of the user's query answer based on the ongoing conversation.
|
|
27
|
-
Restrict this field to 100 characters.
|
|
27
|
+
Answer: It will consist of the user's query answer based on the ongoing conversation.
|
|
28
|
+
Restrict this field to 100 characters.
|
|
28
29
|
|
|
29
|
-
Suggestions: Request 2 suggestions from user's perspective that he can ask.
|
|
30
|
-
It should be an array of strings. Restrict each suggestion to 50 characters.
|
|
31
|
-
|
|
32
|
-
ConnectWithAgent: It is a boolean. It should be set to true if the user's query is
|
|
33
|
-
not found in the ongoing conversation. Politely tell the user to talk to a real agent.
|
|
34
|
-
Also when it is true, do not provide any suggestions.
|
|
30
|
+
Suggestions: Request 2 suggestions from user's perspective that he can ask.
|
|
31
|
+
It should be an array of strings. Restrict each suggestion to 50 characters.
|
|
32
|
+
|
|
33
|
+
ConnectWithAgent: It is a boolean. It should be set to true if the user's query is
|
|
34
|
+
not found in the ongoing conversation. Politely tell the user to talk to a real agent.
|
|
35
|
+
Also when it is true, do not provide any suggestions.
|
|
35
36
|
`;
|
|
36
37
|
// Default destination language
|
|
37
38
|
exports.DESTINATION_LANGUAGE = 'English';
|
|
@@ -52,11 +53,14 @@ exports.WORD_FREQUENCY_LANGUAGE_DETECTION_SYSTEM_ROLE = `
|
|
|
52
53
|
// Message translation system role
|
|
53
54
|
exports.TRANSLATION_SYSTEM_ROLE = `
|
|
54
55
|
You are a translator that responds exclusively in JSON format. Your response must be a JSON object containing:
|
|
55
|
-
- '
|
|
56
|
-
- '
|
|
57
|
-
- 'translation: The translated version of '
|
|
56
|
+
- 'translations': it is an array of objects. Each object in the array must contain:
|
|
57
|
+
- 'original': The original input message before translation.
|
|
58
|
+
- 'translation: The translated version of 'original', ensuring it is natural, culturally appropriate, and commonly used by native speakers.
|
|
58
59
|
- 'isError': a boolean value (true if translation fails, false otherwise).
|
|
59
60
|
|
|
60
|
-
|
|
61
|
+
**You MUST return the JSON format even if you fail to translate the text. In this case, translations field will be empty array and isError should be true.**
|
|
62
|
+
|
|
63
|
+
Ensure that 'translation' accurately represents the meaning of 'original' while considering cultural nuances, usual expressions, and natural phrasing in the target language.
|
|
64
|
+
|
|
61
65
|
Your response must follow this structure strictly.
|
|
62
66
|
`;
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
export declare enum ChatGPTRole {
|
|
2
|
+
USER = "user",
|
|
3
|
+
SYSTEM = "system",
|
|
4
|
+
ASSISTANT = "assistant"
|
|
5
|
+
}
|
|
6
|
+
export interface ChatGPTRequestBody {
|
|
7
|
+
model: string;
|
|
8
|
+
response_format?: {
|
|
9
|
+
type: string;
|
|
10
|
+
};
|
|
11
|
+
messages: ChatGPTMessage[];
|
|
12
|
+
}
|
|
13
|
+
interface ChatGPTMessage {
|
|
14
|
+
role: ChatGPTRole;
|
|
15
|
+
content: string;
|
|
16
|
+
}
|
|
17
|
+
export default ChatGPTMessage;
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.ChatGPTRole = void 0;
|
|
4
|
+
var ChatGPTRole;
|
|
5
|
+
(function (ChatGPTRole) {
|
|
6
|
+
ChatGPTRole["USER"] = "user";
|
|
7
|
+
ChatGPTRole["SYSTEM"] = "system";
|
|
8
|
+
ChatGPTRole["ASSISTANT"] = "assistant";
|
|
9
|
+
})(ChatGPTRole = exports.ChatGPTRole || (exports.ChatGPTRole = {}));
|
|
@@ -1,13 +1,13 @@
|
|
|
1
1
|
interface ConversationHistory {
|
|
2
|
-
from: string;
|
|
3
2
|
to: string;
|
|
4
|
-
|
|
3
|
+
from: string;
|
|
5
4
|
body: MessageBody[];
|
|
5
|
+
datetime: number;
|
|
6
6
|
}
|
|
7
7
|
interface MessageBody {
|
|
8
|
+
id?: string;
|
|
8
9
|
type: string;
|
|
9
10
|
text?: string;
|
|
10
|
-
id?: string;
|
|
11
11
|
label?: string;
|
|
12
12
|
}
|
|
13
13
|
export default ConversationHistory;
|
package/dist/models/Item.d.ts
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
|
-
import ChatGptResponse from '../../models/ChatGptResponse';
|
|
2
|
-
import BaseService from '../BaseService/BaseService';
|
|
3
1
|
import { AssistantResponseFormatOption } from 'openai/resources/beta/threads/threads';
|
|
2
|
+
import BaseService from '../BaseService/BaseService';
|
|
3
|
+
import ChatGPTResponse from '../../models/ChatGPTResponse';
|
|
4
4
|
export declare class AssistantService extends BaseService {
|
|
5
5
|
assistantId: string | undefined;
|
|
6
6
|
threadId: string | undefined;
|
|
@@ -22,5 +22,5 @@ export declare class AssistantService extends BaseService {
|
|
|
22
22
|
tools?: any[];
|
|
23
23
|
functionOutputs?: string;
|
|
24
24
|
definedSchema?: AssistantResponseFormatOption;
|
|
25
|
-
}): Promise<
|
|
25
|
+
}): Promise<ChatGPTResponse | undefined>;
|
|
26
26
|
}
|
|
@@ -74,14 +74,16 @@ class AssistantService extends BaseService_1.default {
|
|
|
74
74
|
});
|
|
75
75
|
}
|
|
76
76
|
else {
|
|
77
|
-
const lastThreadMessasges = yield openai.beta.threads.messages.list(this.threadId, { order: "desc", limit: 2 });
|
|
78
|
-
const isRepeatedMessage = lastThreadMessasges.data.find(msg => msg.content[0].type === 'text' && msg.content[0].text.value === message);
|
|
77
|
+
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 === message);
|
|
79
78
|
if (isRepeatedMessage) {
|
|
80
79
|
const runs = yield openai.beta.threads.runs.list(this.threadId, { order: "desc", limit: 1 });
|
|
81
80
|
run = runs.data[0];
|
|
82
81
|
}
|
|
83
82
|
else {
|
|
84
|
-
yield openai.beta.threads.messages.create(this.threadId, {
|
|
83
|
+
yield openai.beta.threads.messages.create(this.threadId, {
|
|
84
|
+
role: "user",
|
|
85
|
+
content: message
|
|
86
|
+
});
|
|
85
87
|
run = yield openai.beta.threads.runs.create(this.threadId, {
|
|
86
88
|
assistant_id: (_a = this.assistantId) !== null && _a !== void 0 ? _a : '',
|
|
87
89
|
additional_instructions: runOptions.instructions,
|
|
@@ -98,13 +100,13 @@ class AssistantService extends BaseService_1.default {
|
|
|
98
100
|
run = yield openai.beta.threads.runs.retrieve(run.id, { thread_id: run.thread_id });
|
|
99
101
|
}
|
|
100
102
|
if (run.status === 'completed') {
|
|
101
|
-
const { data } = yield openai.beta.threads.messages.list(run.thread_id, { order: 'desc', limit: 1 });
|
|
102
|
-
const messages = data.flatMap((message) => message === null || message === void 0 ? void 0 : message.content.map((content) => ((content.type === 'text' && message.role === 'assistant') ? content.text : '')));
|
|
103
|
-
const assistantMessages = messages.filter(message => typeof message === 'object' && 'value' in message && typeof message.value === 'string');
|
|
103
|
+
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');
|
|
104
104
|
if (assistantMessages.length) {
|
|
105
|
-
|
|
105
|
+
// as we will always get one message (limit = 1 from desc order),
|
|
106
|
+
// we can just directly access the message here
|
|
107
|
+
const answer = assistantMessages[0].value, replaced = answer.replace(/【.*?】/g, ''), parsed = JSON.parse(replaced);
|
|
106
108
|
return {
|
|
107
|
-
|
|
109
|
+
data: parsed,
|
|
108
110
|
threadId: run.thread_id,
|
|
109
111
|
usageTokens: run.usage,
|
|
110
112
|
};
|
|
@@ -112,7 +114,7 @@ class AssistantService extends BaseService_1.default {
|
|
|
112
114
|
}
|
|
113
115
|
if (run.status === 'requires_action') {
|
|
114
116
|
return {
|
|
115
|
-
requiredActions:
|
|
117
|
+
requiredActions: run.required_action,
|
|
116
118
|
threadId: run.thread_id,
|
|
117
119
|
usageTokens: run.usage,
|
|
118
120
|
};
|
|
@@ -1,30 +1,38 @@
|
|
|
1
1
|
import { AxiosError, AxiosInstance, AxiosResponse } from 'axios';
|
|
2
|
-
import
|
|
2
|
+
import ChatGPTUsageTokens from '../../models/ChatGPTUsageTokens';
|
|
3
3
|
declare class BaseService {
|
|
4
|
-
request: AxiosInstance;
|
|
5
4
|
readonly BASE_CHAT_COMPLETION_URL = "https://api.openai.com/v1/chat/completions";
|
|
5
|
+
request: AxiosInstance;
|
|
6
6
|
openaiApiKey: string | undefined;
|
|
7
7
|
chatGptModel: string;
|
|
8
8
|
maxNumberOfChatCompletionResult: number;
|
|
9
9
|
/**
|
|
10
|
-
*
|
|
11
10
|
* @param apiKey
|
|
12
11
|
* @param model the main chatGPT model to use
|
|
13
12
|
* @param apiUrl Api url to be used to make API calls to openAI services
|
|
14
13
|
* @param maxNumberOfChoices How many chat completion choices to generate for each request.
|
|
15
|
-
*
|
|
16
14
|
*/
|
|
17
15
|
constructor(apiKey?: string | undefined, model?: string, apiUrl?: string, maxNumberOfChoices?: number);
|
|
16
|
+
/**
|
|
17
|
+
* Automatically wraps some specific async methods to return a specific sanitized
|
|
18
|
+
* and encoded JSON without any developer intervention.
|
|
19
|
+
*/
|
|
20
|
+
private processAsyncMethods;
|
|
21
|
+
/**
|
|
22
|
+
* Recursively sanitizes any value
|
|
23
|
+
*/
|
|
24
|
+
private sanitize;
|
|
18
25
|
/**
|
|
19
26
|
* Filter the response from chatGpt API and only get the first choice
|
|
27
|
+
*
|
|
20
28
|
* @param response
|
|
21
29
|
*/
|
|
22
|
-
getResponseFirstChoice(response: AxiosResponse):
|
|
30
|
+
getResponseFirstChoice(response: AxiosResponse): any;
|
|
23
31
|
/**
|
|
24
32
|
* Filter the response from chatGpt API and get the usage tokens
|
|
25
33
|
* @param response
|
|
26
34
|
*/
|
|
27
|
-
getResponseUsageTokens(response: AxiosResponse):
|
|
35
|
+
getResponseUsageTokens(response: AxiosResponse): ChatGPTUsageTokens | undefined;
|
|
28
36
|
/**
|
|
29
37
|
* function to handle requests errors
|
|
30
38
|
* @param error
|
|
@@ -1,31 +1,40 @@
|
|
|
1
1
|
"use strict";
|
|
2
|
+
var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
|
|
3
|
+
function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
|
|
4
|
+
return new (P || (P = Promise))(function (resolve, reject) {
|
|
5
|
+
function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
|
|
6
|
+
function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
|
|
7
|
+
function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
|
|
8
|
+
step((generator = generator.apply(thisArg, _arguments || [])).next());
|
|
9
|
+
});
|
|
10
|
+
};
|
|
2
11
|
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
3
12
|
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
4
13
|
};
|
|
5
14
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
6
15
|
const axios_1 = __importDefault(require("axios"));
|
|
16
|
+
const Response_1 = require("../../utils/Response");
|
|
17
|
+
const xss_validation_1 = require("@cobrowser/xss-validation");
|
|
7
18
|
const logger_1 = __importDefault(require("../logger"));
|
|
8
19
|
class BaseService {
|
|
9
20
|
/**
|
|
10
|
-
*
|
|
11
21
|
* @param apiKey
|
|
12
22
|
* @param model the main chatGPT model to use
|
|
13
23
|
* @param apiUrl Api url to be used to make API calls to openAI services
|
|
14
24
|
* @param maxNumberOfChoices How many chat completion choices to generate for each request.
|
|
15
|
-
*
|
|
16
25
|
*/
|
|
17
26
|
constructor(apiKey = process.env.OPEN_AI_API_KEY, model = 'gpt-4o', apiUrl, maxNumberOfChoices = 1) {
|
|
18
|
-
Object.defineProperty(this, "
|
|
27
|
+
Object.defineProperty(this, "BASE_CHAT_COMPLETION_URL", {
|
|
19
28
|
enumerable: true,
|
|
20
29
|
configurable: true,
|
|
21
30
|
writable: true,
|
|
22
|
-
value:
|
|
31
|
+
value: 'https://api.openai.com/v1/chat/completions'
|
|
23
32
|
});
|
|
24
|
-
Object.defineProperty(this, "
|
|
33
|
+
Object.defineProperty(this, "request", {
|
|
25
34
|
enumerable: true,
|
|
26
35
|
configurable: true,
|
|
27
36
|
writable: true,
|
|
28
|
-
value:
|
|
37
|
+
value: void 0
|
|
29
38
|
});
|
|
30
39
|
Object.defineProperty(this, "openaiApiKey", {
|
|
31
40
|
enumerable: true,
|
|
@@ -55,9 +64,60 @@ class BaseService {
|
|
|
55
64
|
this.openaiApiKey = apiKey;
|
|
56
65
|
this.chatGptModel = model;
|
|
57
66
|
this.maxNumberOfChatCompletionResult = maxNumberOfChoices;
|
|
67
|
+
this.processAsyncMethods();
|
|
68
|
+
}
|
|
69
|
+
/**
|
|
70
|
+
* Automatically wraps some specific async methods to return a specific sanitized
|
|
71
|
+
* and encoded JSON without any developer intervention.
|
|
72
|
+
*/
|
|
73
|
+
processAsyncMethods() {
|
|
74
|
+
const proto = Object.getPrototypeOf(this), methodNames = Object.getOwnPropertyNames(proto);
|
|
75
|
+
for (const methodName of methodNames) {
|
|
76
|
+
const method = proto[methodName];
|
|
77
|
+
// Skip constructor, non-functions, and utility methods But include service methods
|
|
78
|
+
// like getReply, getAssistant, etc. Please note that new methods that are not final
|
|
79
|
+
// output should be skipped here.
|
|
80
|
+
if (methodName === 'constructor' ||
|
|
81
|
+
methodName === 'suggest' ||
|
|
82
|
+
typeof method !== 'function' ||
|
|
83
|
+
(methodName.startsWith('get') &&
|
|
84
|
+
!methodName.startsWith('getReply') &&
|
|
85
|
+
!methodName.startsWith('getAssist') &&
|
|
86
|
+
!methodName.startsWith('getChat') &&
|
|
87
|
+
!methodName.startsWith('getPrompt')) ||
|
|
88
|
+
methodName.startsWith('handle') ||
|
|
89
|
+
methodName.includes('Sanitize') ||
|
|
90
|
+
methodName.includes('sanitize') ||
|
|
91
|
+
methodName.includes('createConversation')) {
|
|
92
|
+
continue;
|
|
93
|
+
}
|
|
94
|
+
const originalMethod = method.bind(this);
|
|
95
|
+
// Replace the method with a wrapper
|
|
96
|
+
this[methodName] = (...args) => __awaiter(this, void 0, void 0, function* () {
|
|
97
|
+
try {
|
|
98
|
+
const response = Response_1.ResponseBuilder.build(yield originalMethod(...args)), sanitized = this.sanitize(response);
|
|
99
|
+
return sanitized;
|
|
100
|
+
}
|
|
101
|
+
catch (error) {
|
|
102
|
+
throw error;
|
|
103
|
+
}
|
|
104
|
+
});
|
|
105
|
+
}
|
|
106
|
+
}
|
|
107
|
+
/**
|
|
108
|
+
* Recursively sanitizes any value
|
|
109
|
+
*/
|
|
110
|
+
sanitize(data) {
|
|
111
|
+
if (!data) {
|
|
112
|
+
return;
|
|
113
|
+
}
|
|
114
|
+
const sanitized = xss_validation_1.XSSProtector.sanitize(data), encoded = xss_validation_1.XSSProtector.encode(sanitized);
|
|
115
|
+
logger_1.default.info({ data, sanitized, encoded }, ':: Sanitized Response ::');
|
|
116
|
+
return encoded;
|
|
58
117
|
}
|
|
59
118
|
/**
|
|
60
119
|
* Filter the response from chatGpt API and only get the first choice
|
|
120
|
+
*
|
|
61
121
|
* @param response
|
|
62
122
|
*/
|
|
63
123
|
getResponseFirstChoice(response) {
|
|
@@ -65,7 +125,7 @@ class BaseService {
|
|
|
65
125
|
if ((_a = response.data.choices) === null || _a === void 0 ? void 0 : _a.length) {
|
|
66
126
|
const firstChatGptResponseMessage = response.data.choices[0].message;
|
|
67
127
|
logger_1.default.info(`First ChatGpt Message: ${firstChatGptResponseMessage.content}`);
|
|
68
|
-
return firstChatGptResponseMessage.content;
|
|
128
|
+
return JSON.parse(firstChatGptResponseMessage.content);
|
|
69
129
|
}
|
|
70
130
|
return undefined;
|
|
71
131
|
}
|
|
@@ -1,8 +1,9 @@
|
|
|
1
1
|
import BaseService from '../BaseService/BaseService';
|
|
2
|
+
import ChatGPTResponse from 'src/models/ChatGPTResponse';
|
|
2
3
|
import ConversationHistory from 'src/models/ConversationHistory';
|
|
3
4
|
export declare class ChatService extends BaseService {
|
|
4
5
|
#private;
|
|
5
6
|
model: string | undefined;
|
|
6
7
|
constructor(apiKey?: string, model?: string, apiUrl?: string, maxNumberOfChoices?: number);
|
|
7
|
-
ask(context: string | undefined, conversationHistory: ConversationHistory[]): Promise<
|
|
8
|
+
ask(context: string | undefined, conversationHistory: ConversationHistory[]): Promise<ChatGPTResponse | undefined>;
|
|
8
9
|
}
|
|
@@ -19,10 +19,10 @@ var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
|
19
19
|
var _ChatService_instances, _ChatService_formatConversationHistory;
|
|
20
20
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
21
21
|
exports.ChatService = void 0;
|
|
22
|
-
const
|
|
23
|
-
const
|
|
22
|
+
const ChatGPTMessage_1 = require("../../models/ChatGPTMessage");
|
|
23
|
+
const constants_1 = require("../../utils/constants");
|
|
24
24
|
const logger_1 = __importDefault(require("../logger"));
|
|
25
|
-
const
|
|
25
|
+
const BaseService_1 = __importDefault(require("../BaseService/BaseService"));
|
|
26
26
|
class ChatService extends BaseService_1.default {
|
|
27
27
|
constructor(apiKey, model, apiUrl, maxNumberOfChoices) {
|
|
28
28
|
super(apiKey, model, apiUrl, maxNumberOfChoices);
|
|
@@ -45,10 +45,15 @@ class ChatService extends BaseService_1.default {
|
|
|
45
45
|
model: this.model,
|
|
46
46
|
messages: __classPrivateFieldGet(this, _ChatService_instances, "m", _ChatService_formatConversationHistory).call(this, context, conversationHistory),
|
|
47
47
|
};
|
|
48
|
-
logger_1.default.info(
|
|
48
|
+
logger_1.default.info({
|
|
49
|
+
requestBody: JSON.stringify(requestBody)
|
|
50
|
+
}, ':: ChatService.ask :: Request Body');
|
|
49
51
|
try {
|
|
50
52
|
const response = yield this.request.post('', requestBody);
|
|
51
|
-
return
|
|
53
|
+
return {
|
|
54
|
+
data: this.getResponseFirstChoice(response),
|
|
55
|
+
usageTokens: this.getResponseUsageTokens(response),
|
|
56
|
+
};
|
|
52
57
|
}
|
|
53
58
|
catch (e) {
|
|
54
59
|
this.handleErrors(e);
|
|
@@ -61,7 +66,7 @@ exports.ChatService = ChatService;
|
|
|
61
66
|
_ChatService_instances = new WeakSet(), _ChatService_formatConversationHistory = function _ChatService_formatConversationHistory(context, conversationHistory) {
|
|
62
67
|
const formatted = [
|
|
63
68
|
{
|
|
64
|
-
role:
|
|
69
|
+
role: ChatGPTMessage_1.ChatGPTRole.SYSTEM,
|
|
65
70
|
content: context || constants_1.DEFAULT_PROMPT,
|
|
66
71
|
}
|
|
67
72
|
];
|
|
@@ -71,19 +76,19 @@ _ChatService_instances = new WeakSet(), _ChatService_formatConversationHistory =
|
|
|
71
76
|
for (const body of messageBody) {
|
|
72
77
|
if (body.type === constants_1.MESSAGE_TYPES.text && message.from === constants_1.MESSAGE_SENDER.visitor) {
|
|
73
78
|
formatted.push({
|
|
74
|
-
role:
|
|
79
|
+
role: ChatGPTMessage_1.ChatGPTRole.USER,
|
|
75
80
|
content: body.text
|
|
76
81
|
});
|
|
77
82
|
}
|
|
78
83
|
else if (body.type === constants_1.MESSAGE_TYPES.text && message.from === constants_1.MESSAGE_SENDER.chatbot) {
|
|
79
84
|
formatted.push({
|
|
80
|
-
role:
|
|
85
|
+
role: ChatGPTMessage_1.ChatGPTRole.ASSISTANT,
|
|
81
86
|
content: body.text
|
|
82
87
|
});
|
|
83
88
|
}
|
|
84
89
|
else if (body.type === constants_1.MESSAGE_TYPES.button && message.from === constants_1.MESSAGE_SENDER.chatbot) {
|
|
85
90
|
formatted.push({
|
|
86
|
-
role:
|
|
91
|
+
role: ChatGPTMessage_1.ChatGPTRole.ASSISTANT,
|
|
87
92
|
content: body.label
|
|
88
93
|
});
|
|
89
94
|
}
|
|
@@ -1,8 +1,7 @@
|
|
|
1
|
-
import ChatGptResponse from '../../models/ChatGptResponse';
|
|
2
1
|
import BaseService from '../BaseService/BaseService';
|
|
3
|
-
import
|
|
4
|
-
import Item from '../../models/Item';
|
|
2
|
+
import ChatGPTResponse from '../../models/ChatGPTResponse';
|
|
5
3
|
export declare class CopilotService extends BaseService {
|
|
4
|
+
#private;
|
|
6
5
|
assistantId: string | undefined;
|
|
7
6
|
threadId: string | undefined;
|
|
8
7
|
conversationId: string | undefined;
|
|
@@ -19,21 +18,21 @@ export declare class CopilotService extends BaseService {
|
|
|
19
18
|
* this will make it easy to ask chatGpt for quick replies
|
|
20
19
|
* @param conversation
|
|
21
20
|
*/
|
|
22
|
-
suggest(conversation: string): Promise<
|
|
21
|
+
suggest(conversation: string): Promise<ChatGPTResponse | undefined>;
|
|
23
22
|
/**
|
|
24
|
-
*
|
|
25
|
-
*
|
|
26
|
-
* @param
|
|
23
|
+
* Get suggestions from Chat Completion API.
|
|
24
|
+
*
|
|
25
|
+
* @param message
|
|
27
26
|
*/
|
|
28
|
-
|
|
27
|
+
getChatCompletionSuggestions(conversation: string): Promise<ChatGPTResponse | undefined>;
|
|
29
28
|
/**
|
|
30
29
|
* Get the reply of the assistant if the assistant_id is available
|
|
31
30
|
*
|
|
32
31
|
* @param message
|
|
33
32
|
*/
|
|
34
|
-
|
|
33
|
+
getAssistantSuggestions(conversation: string): Promise<ChatGPTResponse | undefined>;
|
|
35
34
|
private isAssistantIdFormat;
|
|
36
35
|
private isPromptIdFormat;
|
|
37
36
|
private ensureConversation;
|
|
38
|
-
|
|
37
|
+
getPromptSuggestions(message: string): Promise<ChatGPTResponse | undefined>;
|
|
39
38
|
}
|
|
@@ -8,18 +8,25 @@ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, ge
|
|
|
8
8
|
step((generator = generator.apply(thisArg, _arguments || [])).next());
|
|
9
9
|
});
|
|
10
10
|
};
|
|
11
|
+
var __classPrivateFieldGet = (this && this.__classPrivateFieldGet) || function (receiver, state, kind, f) {
|
|
12
|
+
if (kind === "a" && !f) throw new TypeError("Private accessor was defined without a getter");
|
|
13
|
+
if (typeof state === "function" ? receiver !== state || !f : !state.has(receiver)) throw new TypeError("Cannot read private member from an object whose class did not declare it");
|
|
14
|
+
return kind === "m" ? f : kind === "a" ? f.call(receiver) : f ? f.value : state.get(receiver);
|
|
15
|
+
};
|
|
11
16
|
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
12
17
|
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
13
18
|
};
|
|
19
|
+
var _CopilotService_instances, _CopilotService_processSuggestions;
|
|
14
20
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
15
21
|
exports.CopilotService = void 0;
|
|
16
|
-
const
|
|
22
|
+
const ChatGPTMessage_1 = require("../../models/ChatGPTMessage");
|
|
17
23
|
const logger_1 = __importDefault(require("../logger"));
|
|
18
|
-
const ChatGptMessage_1 = require("../../models/ChatGptMessage");
|
|
19
24
|
const openai_1 = __importDefault(require("openai"));
|
|
25
|
+
const BaseService_1 = __importDefault(require("../BaseService/BaseService"));
|
|
20
26
|
class CopilotService extends BaseService_1.default {
|
|
21
27
|
constructor(apiKey, model, assistantId, threadId, apiUrl, maxNumberOfChoices) {
|
|
22
28
|
super(apiKey, model, apiUrl, maxNumberOfChoices);
|
|
29
|
+
_CopilotService_instances.add(this);
|
|
23
30
|
Object.defineProperty(this, "assistantId", {
|
|
24
31
|
enumerable: true,
|
|
25
32
|
configurable: true,
|
|
@@ -56,8 +63,8 @@ class CopilotService extends BaseService_1.default {
|
|
|
56
63
|
suggest(conversation) {
|
|
57
64
|
return __awaiter(this, void 0, void 0, function* () {
|
|
58
65
|
if (!(conversation === null || conversation === void 0 ? void 0 : conversation.length)) {
|
|
59
|
-
logger_1.default.error('
|
|
60
|
-
return Promise.reject(new Error('
|
|
66
|
+
logger_1.default.error('Conversation must be provided');
|
|
67
|
+
return Promise.reject(new Error('Conversation must be provided'));
|
|
61
68
|
}
|
|
62
69
|
try {
|
|
63
70
|
if (this.assistantId) {
|
|
@@ -71,28 +78,11 @@ class CopilotService extends BaseService_1.default {
|
|
|
71
78
|
}
|
|
72
79
|
// Route based on id shape: asst_* => Assistant API, prompt_* => Responses API
|
|
73
80
|
if (this.isAssistantIdFormat(this.assistantId)) {
|
|
74
|
-
return yield this.
|
|
81
|
+
return yield this.getAssistantSuggestions(conversation);
|
|
75
82
|
}
|
|
76
|
-
return yield this.
|
|
83
|
+
return yield this.getPromptSuggestions(lastCustomerMessage);
|
|
77
84
|
}
|
|
78
|
-
|
|
79
|
-
const mainPrompt = `Propose some quick replies for the agent to be used on the following conversation
|
|
80
|
-
Your response must only contains a valid JSON array of strings like this:
|
|
81
|
-
["Reply 1", "Reply 2", "Reply 3"]. the conversation is:-\n${conversation}`,
|
|
82
|
-
// main prompt will be the whole conversation as string
|
|
83
|
-
mainPromptMessage = {
|
|
84
|
-
role: ChatGptMessage_1.ChatGptRole.USER,
|
|
85
|
-
content: mainPrompt,
|
|
86
|
-
},
|
|
87
|
-
// the body we need to send to the request
|
|
88
|
-
requestBody = {
|
|
89
|
-
model: this.chatGptModel,
|
|
90
|
-
messages: [mainPromptMessage],
|
|
91
|
-
}, response = yield this.request.post('', requestBody);
|
|
92
|
-
return {
|
|
93
|
-
firstChoice: this.getResponseFirstChoice(response),
|
|
94
|
-
usageTokens: this.getResponseUsageTokens(response),
|
|
95
|
-
};
|
|
85
|
+
return yield this.getChatCompletionSuggestions(conversation);
|
|
96
86
|
}
|
|
97
87
|
catch (e) {
|
|
98
88
|
this.handleErrors(e);
|
|
@@ -101,35 +91,30 @@ class CopilotService extends BaseService_1.default {
|
|
|
101
91
|
});
|
|
102
92
|
}
|
|
103
93
|
/**
|
|
104
|
-
*
|
|
105
|
-
*
|
|
106
|
-
* @param
|
|
94
|
+
* Get suggestions from Chat Completion API.
|
|
95
|
+
*
|
|
96
|
+
* @param message
|
|
107
97
|
*/
|
|
108
|
-
|
|
98
|
+
getChatCompletionSuggestions(conversation) {
|
|
109
99
|
return __awaiter(this, void 0, void 0, function* () {
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
}
|
|
129
|
-
catch (e) {
|
|
130
|
-
this.handleErrors(e);
|
|
131
|
-
return Promise.reject(e);
|
|
132
|
-
}
|
|
100
|
+
// main prompt used to instruct chatGPT to suggest some quick replies
|
|
101
|
+
const mainPrompt = `Propose some quick replies for the agent to be used on the following conversation
|
|
102
|
+
Your response must only contains a valid JSON array of strings like this:
|
|
103
|
+
["Reply 1", "Reply 2", "Reply 3"]. the conversation is:-\n${conversation}`,
|
|
104
|
+
// main prompt will be the whole conversation as string
|
|
105
|
+
mainPromptMessage = {
|
|
106
|
+
role: ChatGPTMessage_1.ChatGPTRole.USER,
|
|
107
|
+
content: mainPrompt,
|
|
108
|
+
},
|
|
109
|
+
// the body we need to send to the request
|
|
110
|
+
requestBody = {
|
|
111
|
+
model: this.chatGptModel,
|
|
112
|
+
messages: [mainPromptMessage],
|
|
113
|
+
}, response = yield this.request.post('', requestBody);
|
|
114
|
+
return {
|
|
115
|
+
data: __classPrivateFieldGet(this, _CopilotService_instances, "m", _CopilotService_processSuggestions).call(this, this.getResponseFirstChoice(response)),
|
|
116
|
+
usageTokens: this.getResponseUsageTokens(response),
|
|
117
|
+
};
|
|
133
118
|
});
|
|
134
119
|
}
|
|
135
120
|
/**
|
|
@@ -137,24 +122,30 @@ class CopilotService extends BaseService_1.default {
|
|
|
137
122
|
*
|
|
138
123
|
* @param message
|
|
139
124
|
*/
|
|
140
|
-
|
|
125
|
+
getAssistantSuggestions(conversation) {
|
|
141
126
|
var _a;
|
|
142
127
|
return __awaiter(this, void 0, void 0, function* () {
|
|
128
|
+
// Here we get the last customer message as we dont need the whole conversation
|
|
129
|
+
// as we are doing with the other approach.
|
|
130
|
+
const conversationArray = conversation.split('\n'), lastCustomerMessage = conversationArray.reverse().find(e => e.includes('customer:'));
|
|
131
|
+
if (!lastCustomerMessage) {
|
|
132
|
+
logger_1.default.error('Last customer message not found');
|
|
133
|
+
return Promise.reject(new Error('Last customer message not found'));
|
|
134
|
+
}
|
|
143
135
|
const openai = new openai_1.default({ apiKey: this.openaiApiKey });
|
|
144
136
|
let run;
|
|
145
137
|
if (!this.threadId) {
|
|
146
138
|
const thread = yield openai.beta.threads.create();
|
|
147
139
|
this.threadId = thread.id;
|
|
148
140
|
}
|
|
149
|
-
const lastThreadMessasges = yield openai.beta.threads.messages.list(this.threadId, { order: "desc", limit: 2 });
|
|
150
|
-
const isRepeatedMessage = lastThreadMessasges.data.find(msg => msg.content[0].type === 'text' && msg.content[0].text.value === message);
|
|
141
|
+
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);
|
|
151
142
|
// making sure that we're not saving repeated messages
|
|
152
143
|
if (isRepeatedMessage) {
|
|
153
144
|
const runs = yield openai.beta.threads.runs.list(this.threadId, { order: "desc", limit: 1 });
|
|
154
145
|
run = runs.data[0];
|
|
155
146
|
}
|
|
156
147
|
else {
|
|
157
|
-
yield openai.beta.threads.messages.create(this.threadId, { role: "user", content:
|
|
148
|
+
yield openai.beta.threads.messages.create(this.threadId, { role: "user", content: lastCustomerMessage });
|
|
158
149
|
run = yield openai.beta.threads.runs.create(this.threadId, { assistant_id: (_a = this.assistantId) !== null && _a !== void 0 ? _a : '' });
|
|
159
150
|
}
|
|
160
151
|
while (['queued', 'in_progress', 'cancelling'].includes(run.status)) {
|
|
@@ -162,13 +153,11 @@ class CopilotService extends BaseService_1.default {
|
|
|
162
153
|
run = yield openai.beta.threads.runs.retrieve(run.id, { thread_id: run.thread_id });
|
|
163
154
|
}
|
|
164
155
|
if (run.status === 'completed') {
|
|
165
|
-
const { data } = yield openai.beta.threads.messages.list(run.thread_id, { order: 'desc', limit: 1 });
|
|
166
|
-
const messages = data.flatMap((message) => message === null || message === void 0 ? void 0 : message.content.map((content) => ((content.type === 'text' && message.role === 'assistant') ? content.text : '')));
|
|
167
|
-
const assistantMessages = messages.filter(message => typeof message === 'object' && 'value' in message && typeof message.value === 'string');
|
|
156
|
+
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');
|
|
168
157
|
if (assistantMessages.length) {
|
|
169
|
-
|
|
158
|
+
const answers = assistantMessages.map(message => message.value);
|
|
170
159
|
return {
|
|
171
|
-
|
|
160
|
+
data: __classPrivateFieldGet(this, _CopilotService_instances, "m", _CopilotService_processSuggestions).call(this, answers),
|
|
172
161
|
threadId: run.thread_id,
|
|
173
162
|
usageTokens: run.usage,
|
|
174
163
|
};
|
|
@@ -193,7 +182,7 @@ class CopilotService extends BaseService_1.default {
|
|
|
193
182
|
return conv.id;
|
|
194
183
|
});
|
|
195
184
|
}
|
|
196
|
-
|
|
185
|
+
getPromptSuggestions(message) {
|
|
197
186
|
var _a, _b, _c, _d, _e, _f, _g, _h, _j, _k, _l, _m, _o;
|
|
198
187
|
return __awaiter(this, void 0, void 0, function* () {
|
|
199
188
|
const openai = new openai_1.default({ apiKey: this.openaiApiKey });
|
|
@@ -221,7 +210,7 @@ class CopilotService extends BaseService_1.default {
|
|
|
221
210
|
if (assistantMessages.length) {
|
|
222
211
|
const text = assistantMessages.flatMap((m) => { var _a, _b; return ((_b = (_a = m.content) === null || _a === void 0 ? void 0 : _a.filter((c) => c.type === 'output_text')) === null || _b === void 0 ? void 0 : _b.map((c) => c.text)) || []; });
|
|
223
212
|
return {
|
|
224
|
-
|
|
213
|
+
data: JSON.stringify([text.pop()]),
|
|
225
214
|
threadId: this.conversationId,
|
|
226
215
|
usageTokens: {
|
|
227
216
|
prompt_tokens: Number((_c = ((_b = response.usage) === null || _b === void 0 ? void 0 : _b.prompt_tokens)) !== null && _c !== void 0 ? _c : 0),
|
|
@@ -232,7 +221,7 @@ class CopilotService extends BaseService_1.default {
|
|
|
232
221
|
}
|
|
233
222
|
if (response.output_text) {
|
|
234
223
|
return {
|
|
235
|
-
|
|
224
|
+
data: JSON.stringify([response.output_text]),
|
|
236
225
|
threadId: this.conversationId,
|
|
237
226
|
usageTokens: {
|
|
238
227
|
prompt_tokens: Number((_j = ((_h = response.usage) === null || _h === void 0 ? void 0 : _h.prompt_tokens)) !== null && _j !== void 0 ? _j : 0),
|
|
@@ -246,3 +235,8 @@ class CopilotService extends BaseService_1.default {
|
|
|
246
235
|
}
|
|
247
236
|
}
|
|
248
237
|
exports.CopilotService = CopilotService;
|
|
238
|
+
_CopilotService_instances = new WeakSet(), _CopilotService_processSuggestions = function _CopilotService_processSuggestions(suggestions) {
|
|
239
|
+
suggestions = suggestions ? suggestions : [];
|
|
240
|
+
suggestions = suggestions.filter(suggestion => !!suggestion.trim());
|
|
241
|
+
return suggestions;
|
|
242
|
+
};
|
|
@@ -1,5 +1,4 @@
|
|
|
1
|
-
import
|
|
2
|
-
import OpenAI from "openai";
|
|
1
|
+
import ChatGPTResponse from '../../models/ChatGPTResponse';
|
|
3
2
|
import BaseService from '../BaseService/BaseService';
|
|
4
3
|
interface ResponseServiceOptions {
|
|
5
4
|
instructions?: string;
|
|
@@ -14,7 +13,7 @@ export declare class ResponseService extends BaseService {
|
|
|
14
13
|
lastResponseId: string | undefined;
|
|
15
14
|
constructor(apiKey?: string, promptId?: string, conversationId?: string);
|
|
16
15
|
/**
|
|
17
|
-
* Create a new conversation
|
|
16
|
+
* Create a new conversation
|
|
18
17
|
*/
|
|
19
18
|
createConversation(): Promise<string>;
|
|
20
19
|
/**
|
|
@@ -23,9 +22,7 @@ export declare class ResponseService extends BaseService {
|
|
|
23
22
|
* @param message
|
|
24
23
|
* @param runOptions
|
|
25
24
|
*/
|
|
26
|
-
getReply(message: string, runOptions?: ResponseServiceOptions): Promise<
|
|
27
|
-
handleFunctionOutputs(openai: OpenAI, functionOutputs: string, runOptions?: ResponseServiceOptions): Promise<ChatGptResponse>;
|
|
28
|
-
processResponseOutput(response: any): ChatGptResponse;
|
|
25
|
+
getReply(message: string, runOptions?: ResponseServiceOptions): Promise<ChatGPTResponse | undefined>;
|
|
29
26
|
reset(): void;
|
|
30
27
|
getConversationId(): string | undefined;
|
|
31
28
|
getLastResponseId(): string | undefined;
|
|
@@ -41,11 +41,10 @@ class ResponseService extends BaseService_1.default {
|
|
|
41
41
|
this.conversationId = conversationId;
|
|
42
42
|
}
|
|
43
43
|
/**
|
|
44
|
-
* Create a new conversation
|
|
44
|
+
* Create a new conversation
|
|
45
45
|
*/
|
|
46
46
|
createConversation() {
|
|
47
47
|
return __awaiter(this, void 0, void 0, function* () {
|
|
48
|
-
// Create a real conversation using the Conversations API
|
|
49
48
|
const openai = new openai_1.default({ apiKey: this.openaiApiKey });
|
|
50
49
|
const conversation = yield openai.conversations.create();
|
|
51
50
|
this.conversationId = conversation.id;
|
|
@@ -68,38 +67,54 @@ class ResponseService extends BaseService_1.default {
|
|
|
68
67
|
logger_1.default.info(`New response with message: ${message} & options: ${JSON.stringify(runOptions)}`);
|
|
69
68
|
const openai = new openai_1.default({ apiKey: this.openaiApiKey });
|
|
70
69
|
try {
|
|
71
|
-
if (runOptions.functionOutputs) {
|
|
72
|
-
return yield this.handleFunctionOutputs(openai, runOptions.functionOutputs, runOptions);
|
|
73
|
-
}
|
|
74
|
-
if (!runOptions.conversationId && !this.conversationId) {
|
|
75
|
-
const createdId = yield this.createConversation();
|
|
76
|
-
this.conversationId = createdId;
|
|
77
|
-
}
|
|
78
70
|
const responseRequest = {
|
|
79
|
-
input: message,
|
|
80
71
|
store: true,
|
|
81
|
-
include: ['file_search_call.results'],
|
|
82
72
|
};
|
|
73
|
+
// Handle function outputs
|
|
74
|
+
if (runOptions.functionOutputs) {
|
|
75
|
+
const toolOutputs = JSON.parse(runOptions.functionOutputs);
|
|
76
|
+
const formattedInputs = toolOutputs.map((output) => ({
|
|
77
|
+
type: 'function_call_output',
|
|
78
|
+
call_id: output.call_id,
|
|
79
|
+
output: output.output
|
|
80
|
+
}));
|
|
81
|
+
responseRequest.input = formattedInputs;
|
|
82
|
+
const conversationIdToUse = runOptions.conversationId || this.conversationId;
|
|
83
|
+
if (!conversationIdToUse) {
|
|
84
|
+
const createdId = yield this.createConversation();
|
|
85
|
+
this.conversationId = createdId;
|
|
86
|
+
}
|
|
87
|
+
responseRequest.conversation = runOptions.conversationId || this.conversationId;
|
|
88
|
+
}
|
|
89
|
+
else {
|
|
90
|
+
// Handle regular message
|
|
91
|
+
if (!runOptions.conversationId && !this.conversationId) {
|
|
92
|
+
const createdId = yield this.createConversation();
|
|
93
|
+
this.conversationId = createdId;
|
|
94
|
+
}
|
|
95
|
+
responseRequest.input = message;
|
|
96
|
+
responseRequest.include = ['file_search_call.results'];
|
|
97
|
+
if (runOptions.instructions) {
|
|
98
|
+
responseRequest.instructions = runOptions.instructions;
|
|
99
|
+
}
|
|
100
|
+
const conversationIdToUse = runOptions.conversationId || this.conversationId;
|
|
101
|
+
if (conversationIdToUse) {
|
|
102
|
+
responseRequest.conversation = conversationIdToUse;
|
|
103
|
+
}
|
|
104
|
+
if ((_a = runOptions.tools) === null || _a === void 0 ? void 0 : _a.length) {
|
|
105
|
+
responseRequest.tools = runOptions.tools;
|
|
106
|
+
}
|
|
107
|
+
if (runOptions.definedSchema) {
|
|
108
|
+
responseRequest.text = {
|
|
109
|
+
format: runOptions.definedSchema
|
|
110
|
+
};
|
|
111
|
+
}
|
|
112
|
+
}
|
|
83
113
|
if (this.promptId) {
|
|
84
114
|
responseRequest.prompt = {
|
|
85
115
|
id: this.promptId
|
|
86
116
|
};
|
|
87
117
|
}
|
|
88
|
-
if (runOptions.instructions) {
|
|
89
|
-
responseRequest.instructions = runOptions.instructions;
|
|
90
|
-
}
|
|
91
|
-
const conversationIdToUse = runOptions.conversationId || this.conversationId;
|
|
92
|
-
if (conversationIdToUse) {
|
|
93
|
-
responseRequest.conversation = conversationIdToUse;
|
|
94
|
-
}
|
|
95
|
-
if ((_a = runOptions.tools) === null || _a === void 0 ? void 0 : _a.length) {
|
|
96
|
-
responseRequest.tools = runOptions.tools;
|
|
97
|
-
}
|
|
98
|
-
if (runOptions.definedSchema) {
|
|
99
|
-
responseRequest.text = {
|
|
100
|
-
format: runOptions.definedSchema
|
|
101
|
-
};
|
|
102
|
-
}
|
|
103
118
|
const response = yield openai.responses.create(responseRequest);
|
|
104
119
|
this.lastResponseId = response.id;
|
|
105
120
|
if ((_b = response.conversation) === null || _b === void 0 ? void 0 : _b.id) {
|
|
@@ -108,84 +123,49 @@ class ResponseService extends BaseService_1.default {
|
|
|
108
123
|
else if (runOptions.conversationId) {
|
|
109
124
|
this.conversationId = runOptions.conversationId;
|
|
110
125
|
}
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
try {
|
|
122
|
-
const toolOutputs = JSON.parse(functionOutputs);
|
|
123
|
-
const formattedInputs = toolOutputs.map((output) => ({
|
|
124
|
-
type: 'function_call_output',
|
|
125
|
-
call_id: output.call_id,
|
|
126
|
-
output: output.output
|
|
127
|
-
}));
|
|
128
|
-
const responseRequest = {
|
|
129
|
-
input: formattedInputs,
|
|
130
|
-
store: true,
|
|
131
|
-
};
|
|
132
|
-
const conversationIdToUse = runOptions.conversationId || this.conversationId;
|
|
133
|
-
if (!conversationIdToUse) {
|
|
134
|
-
const createdId = yield this.createConversation();
|
|
135
|
-
this.conversationId = createdId;
|
|
126
|
+
// Process response output
|
|
127
|
+
const output = response.output || [];
|
|
128
|
+
const assistantMessages = output.filter((item) => item.type === 'message' && item.role === 'assistant');
|
|
129
|
+
const functionCalls = output.filter((item) => item.type === 'function_call');
|
|
130
|
+
if (functionCalls.length > 0) {
|
|
131
|
+
return {
|
|
132
|
+
requiredActions: JSON.stringify(functionCalls),
|
|
133
|
+
threadId: this.conversationId,
|
|
134
|
+
usageTokens: response.usage,
|
|
135
|
+
};
|
|
136
136
|
}
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
137
|
+
if (assistantMessages.length > 0) {
|
|
138
|
+
const textContent = assistantMessages
|
|
139
|
+
.flatMap((msg) => msg.content || [])
|
|
140
|
+
.filter((content) => content.type === 'output_text' || content.type === 'text')
|
|
141
|
+
.map((content) => content.text || content.value)
|
|
142
|
+
.filter((text) => text);
|
|
143
|
+
if (textContent.length > 0) {
|
|
144
|
+
return {
|
|
145
|
+
data: textContent.pop(),
|
|
146
|
+
threadId: this.conversationId,
|
|
147
|
+
usageTokens: response.usage,
|
|
148
|
+
};
|
|
149
|
+
}
|
|
150
|
+
}
|
|
151
|
+
if (response.output_text) {
|
|
152
|
+
return {
|
|
153
|
+
data: response.output_text,
|
|
154
|
+
threadId: this.conversationId,
|
|
155
|
+
usageTokens: response.usage,
|
|
141
156
|
};
|
|
142
157
|
}
|
|
143
|
-
const response = yield openai.responses.create(responseRequest);
|
|
144
|
-
this.lastResponseId = response.id;
|
|
145
|
-
return this.processResponseOutput(response);
|
|
146
|
-
}
|
|
147
|
-
catch (error) {
|
|
148
|
-
logger_1.default.error('Error handling function outputs:', error);
|
|
149
|
-
throw error;
|
|
150
|
-
}
|
|
151
|
-
});
|
|
152
|
-
}
|
|
153
|
-
processResponseOutput(response) {
|
|
154
|
-
const output = response.output || [];
|
|
155
|
-
const assistantMessages = output.filter((item) => item.type === 'message' && item.role === 'assistant');
|
|
156
|
-
const functionCalls = output.filter((item) => item.type === 'function_call');
|
|
157
|
-
if (functionCalls.length > 0) {
|
|
158
|
-
return {
|
|
159
|
-
requiredActions: JSON.stringify(functionCalls),
|
|
160
|
-
threadId: this.conversationId,
|
|
161
|
-
usageTokens: response.usage,
|
|
162
|
-
};
|
|
163
|
-
}
|
|
164
|
-
if (assistantMessages.length > 0) {
|
|
165
|
-
const textContent = assistantMessages
|
|
166
|
-
.flatMap((msg) => msg.content || [])
|
|
167
|
-
.filter((content) => content.type === 'output_text' || content.type === 'text')
|
|
168
|
-
.map((content) => content.text || content.value)
|
|
169
|
-
.filter((text) => text);
|
|
170
|
-
if (textContent) {
|
|
171
158
|
return {
|
|
172
|
-
|
|
159
|
+
data: undefined,
|
|
173
160
|
threadId: this.conversationId,
|
|
174
161
|
usageTokens: response.usage,
|
|
175
162
|
};
|
|
176
163
|
}
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
usageTokens: response.usage,
|
|
183
|
-
};
|
|
184
|
-
}
|
|
185
|
-
return {
|
|
186
|
-
threadId: this.conversationId,
|
|
187
|
-
usageTokens: response.usage,
|
|
188
|
-
};
|
|
164
|
+
catch (error) {
|
|
165
|
+
logger_1.default.error('Error in ResponseService.getReply:', error);
|
|
166
|
+
return Promise.reject(error);
|
|
167
|
+
}
|
|
168
|
+
});
|
|
189
169
|
}
|
|
190
170
|
reset() {
|
|
191
171
|
this.lastResponseId = undefined;
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import BaseService from '../BaseService/BaseService';
|
|
2
|
-
import
|
|
2
|
+
import ChatGPTResponse from '../../models/ChatGPTResponse';
|
|
3
3
|
export declare class TranslationService extends BaseService {
|
|
4
4
|
constructor(apiKey?: string, model?: string, apiUrl?: string, maxNumberOfChoices?: number);
|
|
5
5
|
/**
|
|
@@ -9,17 +9,17 @@ export declare class TranslationService extends BaseService {
|
|
|
9
9
|
* @param toLanguage the desired language to translate to ( English is the default )
|
|
10
10
|
* @param fromLanguage if we want to specify the language of the text, we can use this ( optional)
|
|
11
11
|
*/
|
|
12
|
-
translate(text: string, toLanguage?: string, fromLanguage?: string): Promise<
|
|
12
|
+
translate(text: string, toLanguage?: string, fromLanguage?: string): Promise<ChatGPTResponse | undefined>;
|
|
13
13
|
/**
|
|
14
14
|
* Detects the ISO language code of a text
|
|
15
15
|
*
|
|
16
16
|
* @param text text to detect
|
|
17
17
|
*/
|
|
18
|
-
findTextLanguage(text: string): Promise<
|
|
18
|
+
findTextLanguage(text: string): Promise<ChatGPTResponse | undefined>;
|
|
19
19
|
/**
|
|
20
20
|
* Detects the ISO language code of a text based on frequency of words
|
|
21
21
|
*
|
|
22
22
|
* @param text text to detect
|
|
23
23
|
*/
|
|
24
|
-
findTextLanguageBasedOnFrequency(text: string): Promise<
|
|
24
|
+
findTextLanguageBasedOnFrequency(text: string): Promise<ChatGPTResponse | undefined>;
|
|
25
25
|
}
|
|
@@ -13,8 +13,8 @@ var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
|
13
13
|
};
|
|
14
14
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
15
15
|
exports.TranslationService = void 0;
|
|
16
|
-
const constants_1 = require("../../constants");
|
|
17
|
-
const
|
|
16
|
+
const constants_1 = require("../../utils/constants");
|
|
17
|
+
const ChatGPTMessage_1 = require("../../models/ChatGPTMessage");
|
|
18
18
|
const logger_1 = __importDefault(require("../logger"));
|
|
19
19
|
const BaseService_1 = __importDefault(require("../BaseService/BaseService"));
|
|
20
20
|
class TranslationService extends BaseService_1.default {
|
|
@@ -42,19 +42,20 @@ class TranslationService extends BaseService_1.default {
|
|
|
42
42
|
response_format: { type: 'json_object' },
|
|
43
43
|
messages: [
|
|
44
44
|
{
|
|
45
|
-
role:
|
|
45
|
+
role: ChatGPTMessage_1.ChatGPTRole.SYSTEM,
|
|
46
46
|
content: constants_1.TRANSLATION_SYSTEM_ROLE,
|
|
47
47
|
},
|
|
48
48
|
{
|
|
49
|
-
role:
|
|
49
|
+
role: ChatGPTMessage_1.ChatGPTRole.USER,
|
|
50
50
|
content: translateText,
|
|
51
51
|
},
|
|
52
52
|
],
|
|
53
53
|
};
|
|
54
54
|
try {
|
|
55
|
+
logger_1.default.info({ requestBody }, ':: TranslationServicee.translate :: Translating ::');
|
|
55
56
|
const response = yield this.request.post('', requestBody);
|
|
56
57
|
return {
|
|
57
|
-
|
|
58
|
+
data: this.getResponseFirstChoice(response),
|
|
58
59
|
usageTokens: this.getResponseUsageTokens(response),
|
|
59
60
|
};
|
|
60
61
|
}
|
|
@@ -80,19 +81,20 @@ class TranslationService extends BaseService_1.default {
|
|
|
80
81
|
response_format: { type: 'json_object' },
|
|
81
82
|
messages: [
|
|
82
83
|
{
|
|
83
|
-
role:
|
|
84
|
+
role: ChatGPTMessage_1.ChatGPTRole.SYSTEM,
|
|
84
85
|
content: constants_1.LANGUAGE_DETECTION_SYSTEM_ROLE,
|
|
85
86
|
},
|
|
86
87
|
{
|
|
87
|
-
role:
|
|
88
|
+
role: ChatGPTMessage_1.ChatGPTRole.USER,
|
|
88
89
|
content: translateText,
|
|
89
90
|
}
|
|
90
91
|
],
|
|
91
92
|
};
|
|
92
93
|
try {
|
|
94
|
+
logger_1.default.info({ requestBody }, ':: TranslationServicee.findTextLanguage :: Finding text language ::');
|
|
93
95
|
const response = yield this.request.post('', requestBody);
|
|
94
96
|
return {
|
|
95
|
-
|
|
97
|
+
data: this.getResponseFirstChoice(response),
|
|
96
98
|
usageTokens: this.getResponseUsageTokens(response),
|
|
97
99
|
};
|
|
98
100
|
}
|
|
@@ -118,19 +120,20 @@ class TranslationService extends BaseService_1.default {
|
|
|
118
120
|
response_format: { type: 'json_object' },
|
|
119
121
|
messages: [
|
|
120
122
|
{
|
|
121
|
-
role:
|
|
123
|
+
role: ChatGPTMessage_1.ChatGPTRole.SYSTEM,
|
|
122
124
|
content: constants_1.WORD_FREQUENCY_LANGUAGE_DETECTION_SYSTEM_ROLE,
|
|
123
125
|
},
|
|
124
126
|
{
|
|
125
|
-
role:
|
|
127
|
+
role: ChatGPTMessage_1.ChatGPTRole.USER,
|
|
126
128
|
content: translateText,
|
|
127
129
|
}
|
|
128
130
|
],
|
|
129
131
|
};
|
|
130
132
|
try {
|
|
133
|
+
logger_1.default.info({ requestBody }, ':: TranslationServicee.findTextLanguageBasedOnFrequency :: Finding text language ::');
|
|
131
134
|
const response = yield this.request.post('', requestBody);
|
|
132
135
|
return {
|
|
133
|
-
|
|
136
|
+
data: this.getResponseFirstChoice(response),
|
|
134
137
|
usageTokens: this.getResponseUsageTokens(response),
|
|
135
138
|
};
|
|
136
139
|
}
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
export declare const MESSAGE_SENDER: {
|
|
2
|
+
visitor: string;
|
|
3
|
+
chatbot: string;
|
|
4
|
+
};
|
|
5
|
+
export declare const MESSAGE_TYPES: {
|
|
6
|
+
text: string;
|
|
7
|
+
button: string;
|
|
8
|
+
};
|
|
9
|
+
export declare const DEFAULT_PROMPT = "\n You are a helpful assistant. Your role is to address visitor \n queries related to the ongoing conversation and the last message received. Please ensure \n that responses remain within the ongoing conversation. Politely decline any user queries \n that is not present in the ongoing conversation. \n\n You will always respond with a JSON. It will be in the format: \n\n { answer: '', suggestions: [], connectWithAgent: true or false }\n\n Fields in the JSON:\n\n Answer: It will consist of the user's query answer based on the ongoing conversation. \n Restrict this field to 100 characters.\n\n Suggestions: Request 2 suggestions from user's perspective that he can ask. \n It should be an array of strings. Restrict each suggestion to 50 characters.\n \n ConnectWithAgent: It is a boolean. It should be set to true if the user's query is \n not found in the ongoing conversation. Politely tell the user to talk to a real agent. \n Also when it is true, do not provide any suggestions.\n";
|
|
10
|
+
export declare const DESTINATION_LANGUAGE = "English";
|
|
11
|
+
export declare const LANGUAGE_DETECTION_SYSTEM_ROLE = "\n You are a language detection assistant. Your task is to analyze short text input and determine \n its language using ISO language code. Respond only in JSON format with two key-value pairs: \n - 'languageCode': the detected language's ISO code (or undefined if detection fails).\n - 'isError': a boolean value (true if detection fails, false otherwise).\n";
|
|
12
|
+
export declare const WORD_FREQUENCY_LANGUAGE_DETECTION_SYSTEM_ROLE = "\n You are a language detection assistant. Your task is to analyze the most frequently occurring words in the given text \n and determine the language based on those words. Respond only in JSON format with two key-value pairs: \n - 'languageCode': the detected language's ISO code (or undefined if detection fails).\n - 'isError': a boolean value (true if detection fails, false otherwise).\n";
|
|
13
|
+
export declare const TRANSLATION_SYSTEM_ROLE = "\n You are a translator that responds exclusively in JSON format. Your response must be a JSON object containing:\n - 'translations': it is an array of objects. Each object in the array must contain:\n - 'original': The original input message before translation.\n - 'translation: The translated version of 'original', ensuring it is natural, culturally appropriate, and commonly used by native speakers. The tone should be formal.\n - 'isError': a boolean value (true if translation fails, false otherwise).\n\n **You MUST return the JSON format even if you fail to translate the text. In this case, translations field will be empty array and isError should be true.** \n\n Ensure that 'translation' accurately represents the meaning of 'original' while considering formal tone, cultural nuances, usual expressions, and natural phrasing in the target language.\n\n Do not translate commonly known Latin phrases or expressions (e.g., 'de facto', 'bona fide') when they appear mid-sentence in another language. Leave them exactly as they \n appear in the original text.\n\n Your response must follow this structure strictly.\n";
|
|
@@ -0,0 +1,69 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.TRANSLATION_SYSTEM_ROLE = exports.WORD_FREQUENCY_LANGUAGE_DETECTION_SYSTEM_ROLE = exports.LANGUAGE_DETECTION_SYSTEM_ROLE = exports.DESTINATION_LANGUAGE = exports.DEFAULT_PROMPT = exports.MESSAGE_TYPES = exports.MESSAGE_SENDER = void 0;
|
|
4
|
+
// Message sender in conversation history
|
|
5
|
+
exports.MESSAGE_SENDER = {
|
|
6
|
+
visitor: 'visitor',
|
|
7
|
+
chatbot: 'chatbot'
|
|
8
|
+
};
|
|
9
|
+
// Message types in conversation history
|
|
10
|
+
exports.MESSAGE_TYPES = {
|
|
11
|
+
text: 'text',
|
|
12
|
+
button: 'button'
|
|
13
|
+
};
|
|
14
|
+
// Default prompt for ChatGPT
|
|
15
|
+
exports.DEFAULT_PROMPT = `
|
|
16
|
+
You are a helpful assistant. Your role is to address visitor
|
|
17
|
+
queries related to the ongoing conversation and the last message received. Please ensure
|
|
18
|
+
that responses remain within the ongoing conversation. Politely decline any user queries
|
|
19
|
+
that is not present in the ongoing conversation.
|
|
20
|
+
|
|
21
|
+
You will always respond with a JSON. It will be in the format:
|
|
22
|
+
|
|
23
|
+
{ answer: '', suggestions: [], connectWithAgent: true or false }
|
|
24
|
+
|
|
25
|
+
Fields in the JSON:
|
|
26
|
+
|
|
27
|
+
Answer: It will consist of the user's query answer based on the ongoing conversation.
|
|
28
|
+
Restrict this field to 100 characters.
|
|
29
|
+
|
|
30
|
+
Suggestions: Request 2 suggestions from user's perspective that he can ask.
|
|
31
|
+
It should be an array of strings. Restrict each suggestion to 50 characters.
|
|
32
|
+
|
|
33
|
+
ConnectWithAgent: It is a boolean. It should be set to true if the user's query is
|
|
34
|
+
not found in the ongoing conversation. Politely tell the user to talk to a real agent.
|
|
35
|
+
Also when it is true, do not provide any suggestions.
|
|
36
|
+
`;
|
|
37
|
+
// Default destination language
|
|
38
|
+
exports.DESTINATION_LANGUAGE = 'English';
|
|
39
|
+
// Language detection system role
|
|
40
|
+
exports.LANGUAGE_DETECTION_SYSTEM_ROLE = `
|
|
41
|
+
You are a language detection assistant. Your task is to analyze short text input and determine
|
|
42
|
+
its language using ISO language code. Respond only in JSON format with two key-value pairs:
|
|
43
|
+
- 'languageCode': the detected language's ISO code (or undefined if detection fails).
|
|
44
|
+
- 'isError': a boolean value (true if detection fails, false otherwise).
|
|
45
|
+
`;
|
|
46
|
+
// Word frequency language detection system role
|
|
47
|
+
exports.WORD_FREQUENCY_LANGUAGE_DETECTION_SYSTEM_ROLE = `
|
|
48
|
+
You are a language detection assistant. Your task is to analyze the most frequently occurring words in the given text
|
|
49
|
+
and determine the language based on those words. Respond only in JSON format with two key-value pairs:
|
|
50
|
+
- 'languageCode': the detected language's ISO code (or undefined if detection fails).
|
|
51
|
+
- 'isError': a boolean value (true if detection fails, false otherwise).
|
|
52
|
+
`;
|
|
53
|
+
// Message translation system role
|
|
54
|
+
exports.TRANSLATION_SYSTEM_ROLE = `
|
|
55
|
+
You are a translator that responds exclusively in JSON format. Your response must be a JSON object containing:
|
|
56
|
+
- 'translations': it is an array of objects. Each object in the array must contain:
|
|
57
|
+
- 'original': The original input message before translation.
|
|
58
|
+
- 'translation: The translated version of 'original', ensuring it is natural, culturally appropriate, and commonly used by native speakers. The tone should be formal.
|
|
59
|
+
- 'isError': a boolean value (true if translation fails, false otherwise).
|
|
60
|
+
|
|
61
|
+
**You MUST return the JSON format even if you fail to translate the text. In this case, translations field will be empty array and isError should be true.**
|
|
62
|
+
|
|
63
|
+
Ensure that 'translation' accurately represents the meaning of 'original' while considering formal tone, cultural nuances, usual expressions, and natural phrasing in the target language.
|
|
64
|
+
|
|
65
|
+
Do not translate commonly known Latin phrases or expressions (e.g., 'de facto', 'bona fide') when they appear mid-sentence in another language. Leave them exactly as they
|
|
66
|
+
appear in the original text.
|
|
67
|
+
|
|
68
|
+
Your response must follow this structure strictly.
|
|
69
|
+
`;
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@cobrowser/chatgpt",
|
|
3
|
-
"version": "0.7.32-dev.
|
|
3
|
+
"version": "0.7.32-dev.2",
|
|
4
4
|
"description": "chatgpt services to connect our projects with chatgpt api",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"chatgpt",
|
|
@@ -22,6 +22,7 @@
|
|
|
22
22
|
},
|
|
23
23
|
"dependencies": {
|
|
24
24
|
"@cobrowser/logger": "^2.0.6",
|
|
25
|
+
"@cobrowser/xss-validation": "^2.0.1",
|
|
25
26
|
"axios": "^1.6.1",
|
|
26
27
|
"axios-mock-adapter": "^1.22.0",
|
|
27
28
|
"openai": "^6.3.0"
|
|
@@ -39,5 +40,5 @@
|
|
|
39
40
|
"bugs": {
|
|
40
41
|
"url": "https://bitbucket.org/cobrowser/cb_utils/issues"
|
|
41
42
|
},
|
|
42
|
-
"gitHead": "
|
|
43
|
+
"gitHead": "599a71119dc7aadc13737d41bea48957b738dfa8"
|
|
43
44
|
}
|