nodebb-plugin-openai 1.4.4 → 2.0.0

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.
@@ -1,14 +1,57 @@
1
1
  'use strict';
2
2
 
3
- const groups = require.main.require('./src/groups');
3
+ const groups = nodebb.require('./src/groups');
4
4
 
5
5
  const Controllers = module.exports;
6
6
 
7
7
  Controllers.renderAdminPage = async function (req, res/* , next */) {
8
8
  const groupsData = await groups.getNonPrivilegeGroups('groups:createtime', 0, -1);
9
9
  groupsData.sort((a, b) => b.system - a.system);
10
+ // Uncomment the following lines to list available models
11
+ // const list = await openai.models.list();
12
+ // for await (const model of list) {
13
+ // console.log(model.id);
14
+ // }
15
+
10
16
  res.render('admin/plugins/openai', {
11
17
  title: 'OpenAI',
12
18
  groups: groupsData,
19
+ models: [
20
+ { id: 'gpt-3.5-turbo' },
21
+ { id: 'gpt-4' },
22
+ { id: 'gpt-4-turbo' },
23
+ { id: 'gpt-4.1' },
24
+ { id: 'gpt-4.1-mini' },
25
+ { id: 'gpt-4.1-nano' },
26
+ { id: 'gpt-4o' },
27
+ { id: 'gpt-4o-mini' },
28
+ { id: 'gpt-5-codex' },
29
+ { id: 'gpt-5-mini' },
30
+ { id: 'gpt-5-nano' },
31
+ { id: 'gpt-5-pro' },
32
+ { id: 'gpt-5.1' },
33
+ { id: 'gpt-5.1-codex' },
34
+ { id: 'gpt-5.1-codex-max' },
35
+ { id: 'gpt-5.1-codex-mini' },
36
+ { id: 'gpt-5.2' },
37
+ { id: 'gpt-5.2-codex' },
38
+ { id: 'gpt-5.2-pro' },
39
+ { id: 'gpt-5.3-codex' },
40
+ { id: 'gpt-5.4' },
41
+ { id: 'gpt-5.4-mini' },
42
+ { id: 'gpt-5.4-nano' },
43
+ { id: 'gpt-5.4-pro' },
44
+ { id: 'gpt-5.5' },
45
+ { id: 'gpt-5.5-pro' },
46
+ { id: 'gpt-5.6-luna' },
47
+ { id: 'gpt-5.6-sol' },
48
+ { id: 'gpt-5.6-terra' },
49
+ { id: 'gpt-5.6' },
50
+ { id: 'gpt-6-astra' },
51
+ { id: 'gpt-6-luna' },
52
+ { id: 'gpt-6-sol' },
53
+ { id: 'gpt-6.1-sol' },
54
+ { id: 'gemini-2.0-flash' },
55
+ ],
13
56
  });
14
57
  };
package/lib/summary.js CHANGED
@@ -1,10 +1,10 @@
1
1
  'use strict';
2
2
 
3
- const db = require.main.require('./src/database');
4
- const batch = require.main.require('./src/batch');
5
- const topics = require.main.require('./src/topics');
6
- const posts = require.main.require('./src/posts');
7
- const user = require.main.require('./src/user');
3
+ const db = nodebb.require('./src/database');
4
+ const batch = nodebb.require('./src/batch');
5
+ const topics = nodebb.require('./src/topics');
6
+ const posts = nodebb.require('./src/posts');
7
+ const user = nodebb.require('./src/user');
8
8
 
9
9
  function formatPosts(posts) {
10
10
  return posts
package/library.js CHANGED
@@ -4,21 +4,23 @@ const { OpenAI } = require('openai');
4
4
 
5
5
  let openai;
6
6
 
7
- const db = require.main.require('./src/database');
8
- const meta = require.main.require('./src/meta');
7
+ const db = nodebb.require('./src/database');
8
+ const meta = nodebb.require('./src/meta');
9
9
  const controllers = require('./lib/controllers');
10
- const routeHelpers = require.main.require('./src/routes/helpers');
11
- const socketHelpers = require.main.require('./src/socket.io/helpers');
12
- const topics = require.main.require('./src/topics');
13
- const user = require.main.require('./src/user');
14
- const messaging = require.main.require('./src/messaging');
15
- const api = require.main.require('./src/api');
16
- const privileges = require.main.require('./src/privileges');
17
- const groups = require.main.require('./src/groups');
18
- const sockets = require.main.require('./src/socket.io');
19
- const socketPlugins = require.main.require('./src/socket.io/plugins');
20
10
  const summary = require('./lib/summary');
21
- const cacheCreate = require('../cache/lru');
11
+
12
+ const routeHelpers = nodebb.require('./src/routes/helpers');
13
+ const socketHelpers = nodebb.require('./src/socket.io/helpers');
14
+ const topics = nodebb.require('./src/topics');
15
+ const user = nodebb.require('./src/user');
16
+ const messaging = nodebb.require('./src/messaging');
17
+ const api = nodebb.require('./src/api');
18
+ const privileges = nodebb.require('./src/privileges');
19
+ const groups = nodebb.require('./src/groups');
20
+ const sockets = nodebb.require('./src/socket.io');
21
+ const socketPlugins = nodebb.require('./src/socket.io/plugins');
22
+ const cacheCreate = nodebb.require('./src/cache/lru');
23
+
22
24
  const summaryCache = cacheCreate({
23
25
  name: 'openai-summary',
24
26
  max: 200,
@@ -46,12 +48,6 @@ plugin.init = async (params) => {
46
48
  baseURL: settings.apiBaseUrl || 'https://api.openai.com/v1',
47
49
  });
48
50
 
49
- // Uncomment the following lines to list available models
50
- // const list = await openai.models.list();
51
- // for await (const model of list) {
52
- // console.log(model.id);
53
- // }
54
-
55
51
  plugin.openai = openai;
56
52
  }
57
53
 
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "nodebb-plugin-openai",
3
- "version": "1.4.4",
3
+ "version": "2.0.0",
4
4
  "description": "A NodeBB OpenAI plugin",
5
5
  "main": "library.js",
6
6
  "repository": {
@@ -33,7 +33,7 @@
33
33
  },
34
34
  "readmeFilename": "README.md",
35
35
  "nbbpm": {
36
- "compatibility": "^3.2.0 || ^4.0.0"
36
+ "compatibility": "4.15.0"
37
37
  },
38
38
  "dependencies": {
39
39
  "openai": "4.103.0"
@@ -41,7 +41,7 @@
41
41
  "devDependencies": {
42
42
  "@commitlint/cli": "19.3.0",
43
43
  "@commitlint/config-angular": "19.3.0",
44
- "eslint": "10.5.0",
44
+ "eslint": "10.11.0",
45
45
  "eslint-config-nodebb": "^2.0.3",
46
46
  "husky": "9.0.11",
47
47
  "lint-staged": "15.2.7"
@@ -12,30 +12,30 @@ $('document').ready(function () {
12
12
  $('.openai-summarize-topic').on('click', summarizeTopic);
13
13
  });
14
14
 
15
- function summarizeTopic() {
15
+ async function summarizeTopic() {
16
16
  const tid = ajaxify.data.tid;
17
- require(['bootbox'], function (bootbox) {
18
- const modal = bootbox.dialog({
19
- title: '[[openai:topic-summary]]',
20
- message: `<div class="openai-summarize-topic"><div class="loading text-center"><i class="fa-solid fa-spinner fa-spin fa-2x"></i></div></div>`,
21
- size: 'large',
22
- buttons: {
23
- ok: {
24
- label: '[[global:ok]]',
25
- className: 'btn-primary',
26
- },
17
+ const modals = await app.require('modals');
18
+
19
+ const modal = await modals.dialog({
20
+ title: '[[openai:topic-summary]]',
21
+ message: `<div class="openai-summarize-topic"><div class="loading text-center"><i class="fa-solid fa-spinner fa-spin fa-2x"></i></div></div>`,
22
+ size: 'large',
23
+ buttons: {
24
+ ok: {
25
+ label: '[[modules:bootbox.ok]]',
26
+ className: 'btn-primary',
27
27
  },
28
- });
29
- socket.emit('plugins.openai.summarizeTopic', { tid }, function (err, data) {
30
- if (err) {
31
- return alertType('error', err.message);
32
- }
33
- if (data) {
34
- modal.find('.openai-summarize-topic').text(data);
35
- } else {
36
- modal.modal('hide');
37
- }
38
- });
28
+ },
29
+ });
30
+ socket.emit('plugins.openai.summarizeTopic', { tid }, function (err, data) {
31
+ if (err) {
32
+ return alertType('error', err.message);
33
+ }
34
+ if (data) {
35
+ modal.find('.openai-summarize-topic').text(data);
36
+ } else {
37
+ modal.modal('hide');
38
+ }
39
39
  });
40
40
  }
41
41
  });
@@ -5,78 +5,73 @@
5
5
  <div id="spy-container" class="col-12 col-md-8 px-0 mb-4" tabindex="0">
6
6
  <form role="form" class="openai-settings">
7
7
  <div class="mb-4">
8
- <h5 class="fw-bold tracking-tight settings-header">[[openai:admin.general]]</h5>
8
+ <h5 class="fw-bold tracking-tight settings-header">{{tx("openai:admin.general")}}</h5>
9
9
 
10
10
  <div class="mb-3">
11
- <label class="form-label" for="apikey">[[openai:admin.apikey]]</label>
11
+ <label class="form-label" for="apikey">{{tx("openai:admin.apikey")}}</label>
12
12
  <input type="text" id="apikey" name="apikey" title="[[openai:admin.apikey]]" class="form-control">
13
13
  <p class="form-text">
14
- [[openai:admin.apikey-help]]
14
+ {{tx("openai:admin.apikey-help")}}
15
15
  </p>
16
16
  </div>
17
17
 
18
18
  <div class="mb-3">
19
- <label class="form-label" for="apiBaseUrl">[[openai:admin.api-base-url]]</label>
19
+ <label class="form-label" for="apiBaseUrl">{{tx("openai:admin.api-base-url")}}</label>
20
20
  <input type="text" id="apiBaseUrl" name="apiBaseUrl" title="[[openai:admin.api-base-url]]" class="form-control">
21
21
  <p class="form-text">
22
- [[openai:admin.api-base-url-help]]
22
+ {{tx("openai:admin.api-base-url-help")}}
23
23
  </p>
24
24
  </div>
25
25
 
26
26
  <div class="mb-3">
27
- <label class="form-label" for="chatgpt-username">[[openai:admin.chatgpt-username]]</label>
27
+ <label class="form-label" for="chatgpt-username">{{tx("openai:admin.chatgpt-username")}}</label>
28
28
  <input type="text" id="chatgpt-username" name="chatgpt-username" title="[[openai:admin.chatgpt-username]]" class="form-control">
29
29
  <p class="form-text">
30
- [[openai:admin.chatgpt-username-help, {config.relative_path}]]
30
+ {{tx("openai:admin.chatgpt-username-help", config.relative_path)}}
31
31
  </p>
32
32
  </div>
33
33
 
34
34
  <div class="form-check form-switch">
35
35
  <input type="checkbox" class="form-check-input" id="enablePrivateMessages" name="enablePrivateMessages">
36
- <label for="enablePrivateMessages" class="form-check-label">[[openai:admin.enable-private-messages]]</label>
36
+ <label for="enablePrivateMessages" class="form-check-label">{{tx("openai:admin.enable-private-messages")}}</label>
37
37
  <p class="form-text">
38
- [[openai:admin.enable-private-messages-help]]
38
+ {{tx("openai:admin.enable-private-messages-help")}}
39
39
  </p>
40
40
  </div>
41
41
 
42
42
  <div class="mb-3">
43
- <label class="form-label" for="model">[[openai:admin.model]]</label>
43
+ <label class="form-label" for="model">{{tx("openai:admin.model")}}</label>
44
44
  <select class="form-select" id="model" name="model" title="[[openai:admin.model]]">
45
- <option value="gpt-3.5-turbo">gpt-3.5-turbo</option>
46
- <option value="gpt-4o-mini">gpt-4o-mini</option>
47
- <option value="gpt-4o">gpt-4o</option>
48
- <option value="gpt-4-turbo">gpt-4-turbo</option>
49
- <option value="gpt-4">gpt-4</option>
50
- <option value="gpt-4.1-mini">gpt-4.1-mini</option>
51
- <option value="gpt-4.1">gpt-4.1</option>
52
- <option value="gemini-2.0-flash">gemini-2.0-flash</option>
45
+ {{{ each models }}}
46
+ <option value="{./id}">{./id}</option>
47
+ {{{ end }}}
53
48
  </select>
54
49
  </div>
55
50
  <div class="">
56
- <label class="form-label" for="systemPrompt">[[openai:admin.system-prompt]]</label>
57
- <textarea class="form-control" id="systemPrompt" name="systemPrompt" title="[[openai:admin.system-prompt]]" placeholder="[[openai:admin.system-prompt-placeholder]]" rows="8"></textarea>
51
+ <label class="form-label" for="systemPrompt">{{tx("openai:admin.system-prompt")}}</label>
52
+ <textarea class="form-control" id="systemPrompt" name="systemPrompt" title="{{tx("openai:admin.system-prompt")}}" placeholder="{{tx("openai:admin.system-prompt-placeholder")}}" rows="8"></textarea>
58
53
  </div>
59
54
  </div>
60
55
 
61
56
  <div class="">
62
- <h5 class="fw-bold tracking-tight settings-header">[[openai:admin.restrictions]]</h5>
57
+ <h5 class="fw-bold tracking-tight settings-header">{{tx("openai:admin.restrictions")}}</h5>
63
58
 
64
59
  <div class="mb-3">
65
- <label class="form-label" for="minimumReputation">[[openai:admin.minimum-reputation]]</label>
60
+ <label class="form-label" for="minimumReputation">{{tx("openai:admin.minimum-reputation")}}</label>
66
61
  <input type="text" id="minimumReputation" name="minimumReputation" title="[[openai:admin.minimum-reputation]]" class="form-control">
67
62
  <p class="form-text">
68
- [[openai:admin.minimum-reputation-help]]
63
+ {{tx("openai:admin.minimum-reputation-help")}}
69
64
  </p>
70
65
  </div>
71
66
  <div class="mb-3">
72
- <label class="form-label" form="allowedGroups">[[openai:admin.allowed-groups]]</label>
67
+ <label class="form-label" form="allowedGroups">{{tx("openai:admin.allowed-groups")}}</label>
73
68
  <select class="form-select" multiple id="allowedGroups" name="allowedGroups" size="10">
74
69
  {{{ each groups }}}
75
70
  <option value="{./displayName}">{./displayName}</option>
76
71
  {{{ end }}}
77
72
  </select>
78
73
  <p class="form-text">
79
- [[openai:admin.allowed-groups-help]]
74
+ {{tx("openai:admin.allowed-groups-help")}}
80
75
  </p>
81
76
  </div>
82
77
  </div>