nodebb-plugin-integration 0.3.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.
@@ -0,0 +1,283 @@
1
+ "use strict";
2
+
3
+ /*
4
+
5
+ NodeBB Integration Layer
6
+
7
+
8
+ Semantic Search
9
+
10
+
11
+
12
+ */
13
+
14
+
15
+
16
+
17
+ const Embeddings =
18
+ require("./embeddings");
19
+
20
+ const Qdrant =
21
+ require("./qdrant");
22
+
23
+
24
+
25
+
26
+
27
+
28
+
29
+
30
+
31
+
32
+
33
+
34
+
35
+ async function search(
36
+
37
+ query,
38
+
39
+ limit = 5
40
+
41
+ ) {
42
+
43
+
44
+
45
+
46
+ if(!query || !query.trim()) {
47
+
48
+
49
+ return [];
50
+
51
+
52
+ }
53
+
54
+
55
+
56
+
57
+
58
+
59
+
60
+
61
+ try {
62
+
63
+
64
+
65
+ const vector =
66
+
67
+ await Embeddings.create(
68
+
69
+ query
70
+
71
+ );
72
+
73
+
74
+
75
+
76
+
77
+
78
+
79
+
80
+ if(!vector) {
81
+
82
+
83
+
84
+ return [];
85
+
86
+
87
+ }
88
+
89
+
90
+
91
+
92
+
93
+
94
+
95
+
96
+ const results =
97
+
98
+ await Qdrant.search(
99
+
100
+ vector,
101
+
102
+ limit
103
+
104
+ );
105
+
106
+
107
+
108
+
109
+
110
+
111
+
112
+
113
+ return results.map(
114
+
115
+ item =>
116
+
117
+ ({
118
+
119
+
120
+ id:
121
+
122
+ item.id,
123
+
124
+
125
+
126
+ score:
127
+
128
+ item.score,
129
+
130
+
131
+
132
+ payload:
133
+
134
+ item.payload || {}
135
+
136
+
137
+
138
+ })
139
+
140
+ );
141
+
142
+
143
+
144
+ }
145
+
146
+
147
+ catch(error) {
148
+
149
+
150
+
151
+ console.error(
152
+
153
+ "[Search] error",
154
+
155
+ error.message
156
+
157
+ );
158
+
159
+
160
+
161
+ return [];
162
+
163
+
164
+ }
165
+
166
+
167
+
168
+
169
+ }
170
+
171
+
172
+
173
+
174
+
175
+
176
+
177
+
178
+
179
+
180
+
181
+
182
+
183
+ async function searchText(
184
+
185
+ text,
186
+
187
+ limit = 5
188
+
189
+ ) {
190
+
191
+ return search(
192
+
193
+ text,
194
+
195
+ limit
196
+
197
+ );
198
+
199
+ }
200
+
201
+
202
+
203
+
204
+
205
+
206
+
207
+
208
+
209
+
210
+
211
+
212
+
213
+ function formatResults(results) {
214
+
215
+
216
+
217
+
218
+ return results.map(
219
+
220
+ result =>
221
+
222
+ ({
223
+
224
+
225
+ score:
226
+
227
+ result.score,
228
+
229
+
230
+
231
+ text:
232
+
233
+ result.payload.text || "",
234
+
235
+
236
+
237
+ type:
238
+
239
+ result.payload.type || null,
240
+
241
+
242
+
243
+ sourceId:
244
+
245
+ result.payload.sourceId || null
246
+
247
+
248
+
249
+ })
250
+
251
+ );
252
+
253
+
254
+
255
+
256
+ }
257
+
258
+
259
+
260
+
261
+
262
+
263
+
264
+
265
+
266
+
267
+
268
+
269
+
270
+ module.exports = {
271
+
272
+ search,
273
+
274
+
275
+ searchText,
276
+
277
+
278
+ formatResults
279
+
280
+
281
+
282
+
283
+ };
@@ -0,0 +1,322 @@
1
+ "use strict";
2
+
3
+ /*
4
+
5
+ NodeBB Integration Layer
6
+
7
+
8
+ Global configuration
9
+
10
+
11
+
12
+ */
13
+
14
+ require("dotenv").config();
15
+
16
+
17
+
18
+
19
+
20
+
21
+
22
+
23
+
24
+
25
+
26
+
27
+
28
+ const Config = {
29
+
30
+
31
+
32
+
33
+ environment:
34
+
35
+ process.env.NODE_ENV ||
36
+
37
+ "development",
38
+
39
+
40
+
41
+
42
+
43
+ nodebb: {
44
+
45
+
46
+ url:
47
+
48
+ process.env.NODEBB_URL ||
49
+
50
+ "http://localhost:4567",
51
+
52
+
53
+
54
+ apiKey:
55
+
56
+ process.env.NODEBB_API_KEY ||
57
+
58
+ ""
59
+
60
+
61
+ },
62
+
63
+
64
+
65
+
66
+
67
+
68
+
69
+
70
+ redis: {
71
+
72
+
73
+ host:
74
+
75
+ process.env.REDIS_HOST ||
76
+
77
+ "localhost",
78
+
79
+
80
+
81
+ port:
82
+
83
+ Number(
84
+
85
+ process.env.REDIS_PORT ||
86
+
87
+ 6379
88
+
89
+ ),
90
+
91
+
92
+
93
+ password:
94
+
95
+ process.env.REDIS_PASSWORD ||
96
+
97
+ ""
98
+
99
+
100
+
101
+ },
102
+
103
+
104
+
105
+
106
+
107
+
108
+
109
+
110
+ qdrant: {
111
+
112
+
113
+ url:
114
+
115
+ process.env.QDRANT_URL ||
116
+
117
+ "http://localhost:6333",
118
+
119
+
120
+
121
+ collection:
122
+
123
+ process.env.QDRANT_COLLECTION ||
124
+
125
+ "nodebb_knowledge"
126
+
127
+
128
+
129
+ },
130
+
131
+
132
+
133
+
134
+
135
+
136
+
137
+
138
+ openai: {
139
+
140
+
141
+ apiKey:
142
+
143
+ process.env.OPENAI_API_KEY ||
144
+
145
+ "",
146
+
147
+
148
+
149
+ model:
150
+
151
+ process.env.OPENAI_MODEL ||
152
+
153
+ "gpt-4.1-mini",
154
+
155
+
156
+
157
+ embeddingModel:
158
+
159
+ process.env.OPENAI_EMBEDDING_MODEL ||
160
+
161
+ "text-embedding-3-small"
162
+
163
+
164
+
165
+ },
166
+
167
+
168
+
169
+
170
+
171
+
172
+
173
+
174
+ embeddings: {
175
+
176
+
177
+ provider:
178
+
179
+ process.env.AI_PROVIDER ||
180
+
181
+ "fake",
182
+
183
+
184
+
185
+ size:
186
+
187
+ Number(
188
+
189
+ process.env.EMBEDDING_SIZE ||
190
+
191
+ 1536
192
+
193
+ )
194
+
195
+
196
+
197
+ },
198
+
199
+
200
+
201
+
202
+
203
+
204
+
205
+
206
+ mcp: {
207
+
208
+
209
+ enabled:
210
+
211
+ process.env.MCP_ENABLED !== "false"
212
+
213
+
214
+
215
+ }
216
+
217
+
218
+
219
+
220
+
221
+
222
+
223
+
224
+
225
+
226
+
227
+
228
+
229
+ };
230
+
231
+
232
+
233
+
234
+
235
+
236
+
237
+
238
+
239
+
240
+
241
+
242
+
243
+ /*
244
+
245
+ Safe debug output
246
+
247
+
248
+ Does not expose API keys
249
+ */
250
+
251
+ Config.info = function() {
252
+
253
+
254
+
255
+
256
+ return {
257
+
258
+
259
+ environment:
260
+
261
+ Config.environment,
262
+
263
+
264
+
265
+ nodebb:
266
+
267
+ {
268
+
269
+ url:
270
+
271
+ Config.nodebb.url
272
+
273
+ },
274
+
275
+
276
+
277
+ qdrant:
278
+
279
+ {
280
+
281
+ url:
282
+
283
+ Config.qdrant.url,
284
+
285
+
286
+ collection:
287
+
288
+ Config.qdrant.collection
289
+
290
+ },
291
+
292
+
293
+
294
+ embeddings:
295
+
296
+ Config.embeddings,
297
+
298
+
299
+
300
+ mcp:
301
+
302
+ Config.mcp
303
+
304
+
305
+
306
+ };
307
+
308
+ };
309
+
310
+
311
+
312
+
313
+
314
+
315
+
316
+
317
+
318
+
319
+
320
+
321
+
322
+ module.exports = Config;