-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathNodeAWSBot.js
More file actions
142 lines (135 loc) · 4.5 KB
/
NodeAWSBot.js
File metadata and controls
142 lines (135 loc) · 4.5 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
require('es6-promise').polyfill();
require('isomorphic-fetch');
const {v4: uuidv4} = require('uuid');
const {SecretsManagerClient, GetSecretValueCommand} = require("@aws-sdk/client-secrets-manager");
const {AWSAppSyncClient} = require('aws-appsync');
const gql = require('graphql-tag');
const {createMessage} = require('./graphql.js');
const { Configuration, OpenAIApi } = require("openai");
const {encode} = require('./mod');
async function updateAppSync(appSyncKey, text, chatId, botId) {
const client = new AWSAppSyncClient({
url: 'https://INSERTURL.appsync-api.us-west-2.amazonaws.com/graphql',
region: 'us-west-2',
auth: {
type: 'API_KEY',
apiKey: 'INSERT-KEY',
},
disableOffline: true,
});
await client.mutate({
mutation: gql(createMessage),
variables: {
input: {
id: uuidv4(),
type: 'Message',
chatId: chatId,
botId: botId,
content: text,
createdAt: new Date(Date.now()).toISOString(),
},
},
});
return {
statusCode: 200,
body: text,
};
}
function sliceIntoChunks(arr, chunkSize) {
const res = [];
for (let i = 0; i < arr.length; i += chunkSize) {
const chunk = arr.slice(i, i + chunkSize);
res.push(chunk);
}
return res;
}
function getTokenCount(string) {
let tokenCount = 0;
let encoded = encode(string);
for (let token of encoded) {
tokenCount++;
}
return tokenCount;
}
// ${params.bot.name} is a talkative, flirtatious woman who lives in Japan
exports.handler = async (event, context, callback) => {
let secretClient = new SecretsManagerClient({region: "us-west-2"});
let response = await secretClient.send(new GetSecretValueCommand({ SecretId: "Chatbot", VersionStage: "AWSCURRENT"}));
let secret = JSON.parse(response.SecretString);
let configuration = new Configuration({apiKey: secret.OpenAIKey});
let openai = new OpenAIApi(configuration);
let params = event;
let max_allowed_tokens = 2048;
let max_generated_tokens = 100;
let background = `This is a conversation between ${params.user.name} and ${params.bot.name}.\n\n`;
let prompt = background;
let userFirstName = params.user.name.split(' ')[0];
let botFirstName = params.bot.name.split(' ')[0];
let newInput = `${userFirstName}: ${params.content}\n${botFirstName}:`;
let stopString = `${userFirstName}:`;
let previous_messages_chunks = sliceIntoChunks(params.lastMessages, 2).reverse();
if (params.lastMessages.length === 8) {
max_allowed_tokens =
max_allowed_tokens -
max_generated_tokens -
getTokenCount(prompt + newInput);
for (let chunk of previous_messages_chunks) {
let pair = `${userFirstName}: ${chunk[1].content}\n${botFirstName}: ${chunk[0].content}\n`;
let tokenCount = getTokenCount(pair);
if (max_allowed_tokens - tokenCount >= 0) {
newInput = pair + newInput;
max_allowed_tokens = max_allowed_tokens - tokenCount;
} else {
break;
}
}
} else {
let messagesArray = params.lastMessages.map(message => {
let name = message.userId ? userFirstName : botFirstName;
return `${name}: ${message.content}\n`;
});
newInput = messagesArray.join('') + newInput;
}
prompt = prompt + newInput;
await openai
.createCompletion({
model: 'text-davinci-003',
prompt: prompt,
max_tokens: max_generated_tokens,
temperature: 0,
stop: stopString,
})
.then(async function (response) {
await updateAppSync(
secret.AWSKey,
response.data.choices[0].text.trim(),
params.chatId,
params.bot.id,
);
})
.catch(async function (err) {
// This is a fallback just in case OpenAI flags the input or output
console.log(err);
const NLPCloudClient = require('nlpcloud');
const nlp = new NLPCloudClient(
'finetuned-gpt-neox-20b',
secret.NLPCloudKey,
true,
);
let messagesArray = previous_messages_chunks.map(chunk => {
return {input: chunk[1].content, response: chunk[0].content};
});
await nlp
.chatbot(params.content, background, messagesArray)
.then(async function (response) {
await updateAppSync(
secret.AWSKey,
response.data.response,
params.chatId,
params.bot.id,
).catch(async function (error) {
console.log(error);
});
});
});
};