nodebb-plugin-openai 1.3.1 → 1.3.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/eslint.config.mjs +10 -0
- package/lib/summary.js +8 -9
- package/library.js +6 -4
- package/package.json +8 -6
- package/templates/admin/plugins/openai.tpl +2 -0
package/lib/summary.js
CHANGED
|
@@ -8,7 +8,7 @@ const user = require.main.require('./src/user');
|
|
|
8
8
|
|
|
9
9
|
function formatPosts(posts) {
|
|
10
10
|
return posts
|
|
11
|
-
.map(
|
|
11
|
+
.map(post => `User ${post.username}:\n${post.content}`)
|
|
12
12
|
.join('\n---\n');
|
|
13
13
|
}
|
|
14
14
|
|
|
@@ -17,7 +17,6 @@ function chunkPosts(posts, maxTokensPerChunk = 3000) {
|
|
|
17
17
|
let currentChunk = [];
|
|
18
18
|
let currentTokens = 0;
|
|
19
19
|
|
|
20
|
-
// eslint-disable-next-line no-restricted-syntax
|
|
21
20
|
for (const post of posts) {
|
|
22
21
|
const estimatedTokens = Math.ceil(post.content.length / 4) + 10;
|
|
23
22
|
if (currentTokens + estimatedTokens > maxTokensPerChunk) {
|
|
@@ -59,7 +58,7 @@ async function summarizeChunk(chunk, openai, settings) {
|
|
|
59
58
|
return response.choices[0].message.content.trim();
|
|
60
59
|
}
|
|
61
60
|
|
|
62
|
-
exports.summarizeTopic = async function(tid, openai, settings) {
|
|
61
|
+
exports.summarizeTopic = async function (tid, openai, settings) {
|
|
63
62
|
const allPids = await topics.getPids(tid);
|
|
64
63
|
|
|
65
64
|
const userMap = {};
|
|
@@ -68,11 +67,11 @@ exports.summarizeTopic = async function(tid, openai, settings) {
|
|
|
68
67
|
|
|
69
68
|
await batch.processArray(allPids, async function (pids) {
|
|
70
69
|
let postData = await posts.getPostsFields(pids, ['uid', 'content', 'deleted']);
|
|
71
|
-
postData = postData.filter(
|
|
70
|
+
postData = postData.filter(p => !p.deleted);
|
|
72
71
|
const missingUids = [];
|
|
73
72
|
postData.forEach((p) => {
|
|
74
73
|
if (!userMap.hasOwnProperty(p.uid)) {
|
|
75
|
-
missingUids.push(p.uid)
|
|
74
|
+
missingUids.push(p.uid);
|
|
76
75
|
}
|
|
77
76
|
});
|
|
78
77
|
const userData = await user.getUsersFields(missingUids, ['username']);
|
|
@@ -86,7 +85,7 @@ exports.summarizeTopic = async function(tid, openai, settings) {
|
|
|
86
85
|
const chunks = chunkPosts(postData);
|
|
87
86
|
|
|
88
87
|
chunkSummaries.push(...await Promise.all(chunks.map(async (chunk) => {
|
|
89
|
-
return summarizeChunk(chunk, openai, settings)
|
|
88
|
+
return summarizeChunk(chunk, openai, settings);
|
|
90
89
|
})));
|
|
91
90
|
}, {
|
|
92
91
|
batch: 500,
|
|
@@ -96,7 +95,7 @@ exports.summarizeTopic = async function(tid, openai, settings) {
|
|
|
96
95
|
return chunkSummaries[0];
|
|
97
96
|
}
|
|
98
97
|
// Final summary from all summaries
|
|
99
|
-
const finalInput = chunkSummaries.join(
|
|
98
|
+
const finalInput = chunkSummaries.join('\n\n');
|
|
100
99
|
if (!finalInput) {
|
|
101
100
|
return '';
|
|
102
101
|
}
|
|
@@ -118,6 +117,6 @@ exports.summarizeTopic = async function(tid, openai, settings) {
|
|
|
118
117
|
return finalResponse.choices[0].message.content.trim();
|
|
119
118
|
};
|
|
120
119
|
|
|
121
|
-
exports.clearTopicSummary = async function(tids) {
|
|
122
|
-
await db.deleteObjectFields(tids.map(
|
|
120
|
+
exports.clearTopicSummary = async function (tids) {
|
|
121
|
+
await db.deleteObjectFields(tids.map(tid => `topic:${tid}`), ['openai:summary']);
|
|
123
122
|
};
|
package/library.js
CHANGED
|
@@ -34,18 +34,19 @@ const defaults = {
|
|
|
34
34
|
|
|
35
35
|
plugin.init = async (params) => {
|
|
36
36
|
const { router /* , middleware , controllers */ } = params;
|
|
37
|
-
const settings = await meta.settings.get('openai')
|
|
37
|
+
const settings = await meta.settings.get('openai');
|
|
38
38
|
if (settings && settings.apikey) {
|
|
39
39
|
openai = new OpenAI({
|
|
40
40
|
apiKey: settings.apikey,
|
|
41
41
|
});
|
|
42
|
+
plugin.openai = openai;
|
|
42
43
|
}
|
|
43
44
|
|
|
44
45
|
routeHelpers.setupAdminPageRoute(router, '/admin/plugins/openai', controllers.renderAdminPage);
|
|
45
46
|
};
|
|
46
47
|
|
|
47
48
|
async function getSettings() {
|
|
48
|
-
const settings = await meta.settings.get('openai')
|
|
49
|
+
const settings = await meta.settings.get('openai');
|
|
49
50
|
return {...defaults, ...settings };
|
|
50
51
|
}
|
|
51
52
|
|
|
@@ -150,7 +151,7 @@ plugin.actionMessagingSave = async function (hookData) {
|
|
|
150
151
|
let messages = await messaging.getMessagesFields(mids, ['fromuid', 'content', 'system']);
|
|
151
152
|
messages = messages.filter(m => m && !m.system);
|
|
152
153
|
conversation = messages.map(
|
|
153
|
-
|
|
154
|
+
msg => ({ role: msg.fromuid === chatgptUid ? 'assistant' : 'user', content: msg.content })
|
|
154
155
|
);
|
|
155
156
|
}
|
|
156
157
|
|
|
@@ -180,7 +181,8 @@ async function canUseOpenAI(uid, settings, silent = false) {
|
|
|
180
181
|
|
|
181
182
|
async function checkReputation(uid, settings, silent) {
|
|
182
183
|
const reputation = await user.getUserField(uid, 'reputation');
|
|
183
|
-
const hasEnoughRep = parseInt(settings.minimumReputation, 10) === 0 ||
|
|
184
|
+
const hasEnoughRep = parseInt(settings.minimumReputation, 10) === 0 ||
|
|
185
|
+
parseInt(reputation, 10) >= parseInt(settings.minimumReputation, 10);
|
|
184
186
|
|
|
185
187
|
if (!hasEnoughRep && !silent) {
|
|
186
188
|
sockets.server.in(`uid_${uid}`).emit('event:alert', {
|
package/package.json
CHANGED
|
@@ -1,12 +1,15 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "nodebb-plugin-openai",
|
|
3
|
-
"version": "1.3.
|
|
3
|
+
"version": "1.3.2",
|
|
4
4
|
"description": "A NodeBB OpenAI plugin",
|
|
5
5
|
"main": "library.js",
|
|
6
6
|
"repository": {
|
|
7
7
|
"type": "git",
|
|
8
8
|
"url": "https://github.com/nodebb/nodebb-plugin-openai"
|
|
9
9
|
},
|
|
10
|
+
"scripts": {
|
|
11
|
+
"lint": "eslint ."
|
|
12
|
+
},
|
|
10
13
|
"keywords": [
|
|
11
14
|
"nodebb",
|
|
12
15
|
"plugin",
|
|
@@ -30,17 +33,16 @@
|
|
|
30
33
|
},
|
|
31
34
|
"readmeFilename": "README.md",
|
|
32
35
|
"nbbpm": {
|
|
33
|
-
"compatibility": "^3.2.0"
|
|
36
|
+
"compatibility": "^3.2.0 || ^4.0.0"
|
|
34
37
|
},
|
|
35
38
|
"dependencies": {
|
|
36
|
-
"openai": "4.
|
|
39
|
+
"openai": "4.98.0"
|
|
37
40
|
},
|
|
38
41
|
"devDependencies": {
|
|
39
42
|
"@commitlint/cli": "19.3.0",
|
|
40
43
|
"@commitlint/config-angular": "19.3.0",
|
|
41
|
-
"eslint": "
|
|
42
|
-
"eslint-config-nodebb": "
|
|
43
|
-
"eslint-plugin-import": "2.29.1",
|
|
44
|
+
"eslint": "9.26.0",
|
|
45
|
+
"eslint-config-nodebb": "^1.1.4",
|
|
44
46
|
"husky": "9.0.11",
|
|
45
47
|
"lint-staged": "15.2.7"
|
|
46
48
|
}
|
|
@@ -38,6 +38,8 @@
|
|
|
38
38
|
<option value="gpt-4o">gpt-4o</option>
|
|
39
39
|
<option value="gpt-4-turbo">gpt-4-turbo</option>
|
|
40
40
|
<option value="gpt-4">gpt-4</option>
|
|
41
|
+
<option value="gpt-4.1-mini">gpt-4.1-mini</option>
|
|
42
|
+
<option value="gpt-4.1">gpt-4.1</option>
|
|
41
43
|
</select>
|
|
42
44
|
</div>
|
|
43
45
|
<div class="">
|