@maiyunnet/kebab 8.0.6 → 8.2.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.
- package/doc/kebab-rag.md +312 -74
- package/index.d.ts +1 -1
- package/index.js +1 -1
- package/lib/ai.d.ts +91 -2
- package/lib/ai.js +360 -6
- package/lib/net.js +33 -9
- package/lib/session.d.ts +1 -0
- package/lib/session.js +2 -1
- package/lib/time.js +6 -0
- package/package.json +9 -9
- package/sys/cmd.js +8 -0
- package/sys/monitor.js +4 -5
- package/www/example/ctr/test.js +177 -19
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@maiyunnet/kebab",
|
|
3
|
-
"version": "8.0
|
|
3
|
+
"version": "8.2.0",
|
|
4
4
|
"description": "Simple, easy-to-use, and fully-featured Node.js framework that is ready-to-use out of the box.",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"keywords": [
|
|
@@ -22,30 +22,30 @@
|
|
|
22
22
|
"#kebab/*": "./*"
|
|
23
23
|
},
|
|
24
24
|
"dependencies": {
|
|
25
|
-
"@aws-sdk/client-s3": "^3.
|
|
26
|
-
"@aws-sdk/lib-storage": "^3.
|
|
25
|
+
"@aws-sdk/client-s3": "^3.992.0",
|
|
26
|
+
"@aws-sdk/lib-storage": "^3.992.0",
|
|
27
27
|
"@litert/http-client": "^1.1.2",
|
|
28
28
|
"@litert/mime": "^0.1.3",
|
|
29
29
|
"@litert/redis": "^3.1.0",
|
|
30
30
|
"@litert/websocket": "^0.2.8",
|
|
31
31
|
"@types/ssh2": "^1.15.5",
|
|
32
|
-
"@zilliz/milvus2-sdk-node": "^2.6.
|
|
32
|
+
"@zilliz/milvus2-sdk-node": "^2.6.10",
|
|
33
33
|
"ejs": "^4.0.1",
|
|
34
34
|
"jszip": "^3.10.1",
|
|
35
|
-
"mysql2": "^3.
|
|
35
|
+
"mysql2": "^3.17.2",
|
|
36
36
|
"node-cron": "^4.2.1",
|
|
37
|
-
"openai": "^6.
|
|
37
|
+
"openai": "^6.22.0",
|
|
38
38
|
"pg": "^8.18.0",
|
|
39
39
|
"ssh2": "^1.17.0",
|
|
40
40
|
"svg-captcha": "^1.4.0",
|
|
41
|
-
"tencentcloud-sdk-nodejs": "^4.1.
|
|
41
|
+
"tencentcloud-sdk-nodejs": "^4.1.186"
|
|
42
42
|
},
|
|
43
43
|
"devDependencies": {
|
|
44
44
|
"@litert/eslint-plugin-rules": "^0.3.1",
|
|
45
45
|
"@types/ejs": "^3.1.5",
|
|
46
|
-
"@types/node": "^25.2.
|
|
46
|
+
"@types/node": "^25.2.3",
|
|
47
47
|
"@types/pg": "^8.16.0",
|
|
48
|
-
"typedoc": "^0.28.
|
|
48
|
+
"typedoc": "^0.28.17",
|
|
49
49
|
"typedoc-plugin-markdown": "^4.10.0",
|
|
50
50
|
"typescript": "^5.9.3"
|
|
51
51
|
}
|
package/sys/cmd.js
CHANGED
|
@@ -177,6 +177,14 @@ async function run() {
|
|
|
177
177
|
config.ai['AZURE3'] ??= {};
|
|
178
178
|
config.ai['AZURE3'].endpoint ??= '';
|
|
179
179
|
config.ai['AZURE3'].skey ??= '';
|
|
180
|
+
config.ai['GEMINI'] ??= {};
|
|
181
|
+
config.ai['GEMINI'].skey ??= '';
|
|
182
|
+
config.ai['GROK'] ??= {};
|
|
183
|
+
config.ai['GROK'].skey ??= '';
|
|
184
|
+
config.ai['VOLCN'] ??= {};
|
|
185
|
+
config.ai['VOLCN'].skey ??= '';
|
|
186
|
+
config.ai['VOLAS'] ??= {};
|
|
187
|
+
config.ai['VOLAS'].skey ??= '';
|
|
180
188
|
// --- config - vector ---
|
|
181
189
|
config.vector ??= {};
|
|
182
190
|
config.vector.host ??= '127.0.0.1';
|
package/sys/monitor.js
CHANGED
|
@@ -82,9 +82,8 @@ export function start(opt) {
|
|
|
82
82
|
memThreshold = opt?.mem ?? 0;
|
|
83
83
|
eloopThreshold = opt?.eloop ?? 500;
|
|
84
84
|
if (memThreshold === 0) {
|
|
85
|
-
// --- 自动计算:系统总内存的 80%
|
|
86
|
-
|
|
87
|
-
memThreshold = Math.floor((os.totalmem() * 0.8) / cpuCount / 1024 / 1024);
|
|
85
|
+
// --- 自动计算:系统总内存的 80% ---
|
|
86
|
+
memThreshold = Math.floor((os.totalmem() * 0.8) / 1024 / 1024);
|
|
88
87
|
}
|
|
89
88
|
lastCpuUsage = process.cpuUsage();
|
|
90
89
|
lastCpuTime = Date.now();
|
|
@@ -102,7 +101,7 @@ export function start(opt) {
|
|
|
102
101
|
timer = setInterval(check, INTERVAL);
|
|
103
102
|
// --- 启动看门狗线程 ---
|
|
104
103
|
startWatchdog();
|
|
105
|
-
lCore.debug(`[MONITOR] Started, CPU: ${cpuThreshold}%, MEM: ${memThreshold}MB, ELOOP: ${eloopThreshold}ms`);
|
|
104
|
+
lCore.debug(`[MONITOR] [PARENT] [${process.pid}] Started, CPU Threshold: ${cpuThreshold}%, MEM Threshold: ${memThreshold}MB, ELOOP Threshold: ${eloopThreshold}ms`);
|
|
106
105
|
}
|
|
107
106
|
/**
|
|
108
107
|
* --- 停止性能监控 ---
|
|
@@ -162,7 +161,7 @@ function startWatchdog() {
|
|
|
162
161
|
watchdog = null;
|
|
163
162
|
}
|
|
164
163
|
});
|
|
165
|
-
lCore.debug(
|
|
164
|
+
lCore.debug(`[MONITOR] [THREAD] [${process.pid}] Watchdog started`);
|
|
166
165
|
}
|
|
167
166
|
catch (e) {
|
|
168
167
|
lCore.debug('[MONITOR] Failed to start watchdog', e);
|
package/www/example/ctr/test.js
CHANGED
|
@@ -127,8 +127,12 @@ export default class extends sCtr.Ctr {
|
|
|
127
127
|
`<br><a href="${this._config.const.urlBase}test/mod-update-list">View "test/mod-update-list"</a>`,
|
|
128
128
|
'<br><br><b>Library test:</b>',
|
|
129
129
|
`<br><br><b>Ai:</b>`,
|
|
130
|
-
`<br><br><a href="${this._config.const.urlBase}test/ai">View "test/ai"</a>`,
|
|
131
130
|
`<br><a href="${this._config.const.urlBase}test/ai-stream">View "test/ai-stream"</a>`,
|
|
131
|
+
`<br><a href="${this._config.const.urlBase}test/ai?action=chat">View "test/ai?action=chat"</a>`,
|
|
132
|
+
`<br><a href="${this._config.const.urlBase}test/ai?action=text-to-image">View "test/ai?action=text-to-image"</a>`,
|
|
133
|
+
`<br><a href="${this._config.const.urlBase}test/ai?action=image-to-image">View "test/ai?action=image-to-image"</a>`,
|
|
134
|
+
`<br><a href="${this._config.const.urlBase}test/ai?action=text-to-video">View "test/ai?action=text-to-video"</a>`,
|
|
135
|
+
`<br><a href="${this._config.const.urlBase}test/ai?action=image-to-video">View "test/ai?action=image-to-video"</a>`,
|
|
132
136
|
'<br><br><b>Core:</b>',
|
|
133
137
|
`<br><br><a href="${this._config.const.urlBase}test/core-random">View "test/core-random"</a>`,
|
|
134
138
|
`<br><a href="${this._config.const.urlBase}test/core-rand">View "test/core-rand"</a>`,
|
|
@@ -1796,7 +1800,7 @@ error: ${JSON.stringify(res.error)}`);
|
|
|
1796
1800
|
lNet.get(this._internalUrl + 'test/net-cookie1', {
|
|
1797
1801
|
'cookie': cookie
|
|
1798
1802
|
});</pre>
|
|
1799
|
-
headers: <pre>${JSON.stringify(res.headers, null, 4)}</pre>
|
|
1803
|
+
headers: <pre>${lText.htmlescape(JSON.stringify(res.headers, null, 4))}</pre>
|
|
1800
1804
|
content: <pre>${(await res.getContent())?.toString() ?? 'null'}</pre>
|
|
1801
1805
|
cookie: <pre>${JSON.stringify(cookie, null, 4)}</pre><hr>`);
|
|
1802
1806
|
res = await lNet.get(this._internalUrl + 'test/net-cookie2', {
|
|
@@ -1868,6 +1872,14 @@ content: <pre>${(await res.getContent())?.toString() ?? 'null'}</pre>`);
|
|
|
1868
1872
|
'ttl': 60,
|
|
1869
1873
|
'httponly': true
|
|
1870
1874
|
});
|
|
1875
|
+
// --- 用于测试 BUG 的额外 Cookie ---
|
|
1876
|
+
this._res.setHeader('Set-Cookie', [
|
|
1877
|
+
...this._res.getHeader('Set-Cookie'),
|
|
1878
|
+
'test-del=; Max-Age=0; Path=/',
|
|
1879
|
+
'test-equals=val=with=equals; Path=/',
|
|
1880
|
+
'test-expires=val; Expires=Wed, 21 Oct 2035 07:28:00 GMT; Path=/',
|
|
1881
|
+
'test-invalid=%invalid; Path=/'
|
|
1882
|
+
]);
|
|
1871
1883
|
return `lCore.setCookie(this, 'test0', 'session');
|
|
1872
1884
|
lCore.setCookie(this, 'test1', 'normal', {
|
|
1873
1885
|
'ttl': 10
|
|
@@ -3337,31 +3349,177 @@ rtn.push(reader.readBCDString());</pre>${JSON.stringify(rtn)}`);
|
|
|
3337
3349
|
return echo.join('') + '<br>' + this._getEnd();
|
|
3338
3350
|
}
|
|
3339
3351
|
async ai() {
|
|
3340
|
-
const ai = lAi.get(this, {
|
|
3341
|
-
'service': lAi.ESERVICE.ALICN,
|
|
3342
|
-
});
|
|
3343
3352
|
const echo = [`<pre>const ai = lAi.get(this, {
|
|
3344
|
-
'service': lAi.ESERVICE.ALICN,
|
|
3353
|
+
'service': lAi.ESERVICE.${lText.htmlescape(this._get['service']?.toUpperCase() ?? 'ALICN')},
|
|
3345
3354
|
});</pre>`];
|
|
3346
|
-
const
|
|
3347
|
-
'
|
|
3348
|
-
'messages': [
|
|
3349
|
-
{ 'role': 'system', 'content': 'You are Kebab, a friendly and knowledgeable assistant based on an open-source Node framework. You do not mention any model names or AI identity. You can chat casually, answer questions, and provide guidance naturally. Respond in a human-like, approachable manner, as if you are a helpful companion rather than a traditional AI assistant.' },
|
|
3350
|
-
{ 'role': 'user', 'content': '你是谁?' },
|
|
3351
|
-
],
|
|
3355
|
+
const ai = lAi.get(this, {
|
|
3356
|
+
'service': lAi.ESERVICE[this._get['service']?.toUpperCase() ?? 'ALICN'] ?? lAi.ESERVICE.ALICN,
|
|
3352
3357
|
});
|
|
3353
|
-
|
|
3354
|
-
|
|
3358
|
+
switch (this._get['action']) {
|
|
3359
|
+
case 'text-to-image': {
|
|
3360
|
+
// --- 文生图 ---
|
|
3361
|
+
let model = 'z-image-turbo';
|
|
3362
|
+
let size = [1280, 720];
|
|
3363
|
+
if (ai.service !== lAi.ESERVICE.ALICN && ai.service !== lAi.ESERVICE.ALIAS) {
|
|
3364
|
+
switch (ai.service) {
|
|
3365
|
+
case lAi.ESERVICE.AZURE:
|
|
3366
|
+
case lAi.ESERVICE.AZURE2:
|
|
3367
|
+
case lAi.ESERVICE.AZURE3: {
|
|
3368
|
+
model = 'FLUX.2-pro';
|
|
3369
|
+
break;
|
|
3370
|
+
}
|
|
3371
|
+
default: {
|
|
3372
|
+
// --- 火山引擎 ---
|
|
3373
|
+
model = 'doubao-seedream-4-5-251128';
|
|
3374
|
+
size = [2560, 1440];
|
|
3375
|
+
}
|
|
3376
|
+
}
|
|
3377
|
+
}
|
|
3378
|
+
const imgResult = await ai.image({
|
|
3379
|
+
'model': model,
|
|
3380
|
+
'prompt': 'A cute cat sitting on a windowsill watching the sunset',
|
|
3381
|
+
'size': size,
|
|
3382
|
+
'n': 1,
|
|
3383
|
+
});
|
|
3384
|
+
echo.push(`<pre>await ai.image({
|
|
3385
|
+
'model': '${model}',
|
|
3386
|
+
'prompt': 'A cute cat sitting on a windowsill watching the sunset',
|
|
3387
|
+
'size': [${size[0]}, ${size[1]}],
|
|
3388
|
+
'n': 1,
|
|
3389
|
+
});</pre>`);
|
|
3390
|
+
if (imgResult && imgResult.list?.length) {
|
|
3391
|
+
for (const img of imgResult.list) {
|
|
3392
|
+
echo.push(`<div><img src="${img.url.startsWith('http') ? img.url : 'data:image/png;base64,' + img.url}" style="max-width: 512px;" /></div>${lText.htmlescape(img.text)}`);
|
|
3393
|
+
}
|
|
3394
|
+
echo.push('<br>request: ' + imgResult.request, ', seed: ' + imgResult.seed);
|
|
3395
|
+
}
|
|
3396
|
+
else {
|
|
3397
|
+
echo.push('Failed');
|
|
3398
|
+
}
|
|
3399
|
+
break;
|
|
3400
|
+
}
|
|
3401
|
+
case 'image-to-image': {
|
|
3402
|
+
// --- 图生图 ---
|
|
3403
|
+
let model = 'wan2.6-image';
|
|
3404
|
+
let size = [1280, 720];
|
|
3405
|
+
const prompt = '用图1的绘画风格重绘图2的场景,桌上增加一盘番茄炒蛋';
|
|
3406
|
+
if (ai.service !== lAi.ESERVICE.ALICN && ai.service !== lAi.ESERVICE.ALIAS) {
|
|
3407
|
+
switch (ai.service) {
|
|
3408
|
+
default: {
|
|
3409
|
+
// --- 火山引擎 ---
|
|
3410
|
+
model = 'doubao-seedream-4-5-251128';
|
|
3411
|
+
size = [2560, 1440];
|
|
3412
|
+
}
|
|
3413
|
+
}
|
|
3414
|
+
}
|
|
3415
|
+
const imgResult = await ai.image({
|
|
3416
|
+
'model': model,
|
|
3417
|
+
'imgs': [
|
|
3418
|
+
'https://cdn.wanx.aliyuncs.com/tmp/pressure/umbrella1.png',
|
|
3419
|
+
'https://img.alicdn.com/imgextra/i3/O1CN01SfG4J41UYn9WNt4X1_!!6000000002530-49-tps-1696-960.webp',
|
|
3420
|
+
],
|
|
3421
|
+
'prompt': prompt,
|
|
3422
|
+
'size': size,
|
|
3423
|
+
'n': 1,
|
|
3424
|
+
});
|
|
3425
|
+
echo.push(`<pre>await ai.image({
|
|
3426
|
+
'model': '${model}',
|
|
3427
|
+
'imgs': [
|
|
3428
|
+
'https://cdn.wanx.aliyuncs.com/tmp/pressure/umbrella1.png',
|
|
3429
|
+
'https://img.alicdn.com/imgextra/i3/O1CN01SfG4J41UYn9WNt4X1_!!6000000002530-49-tps-1696-960.webp',
|
|
3430
|
+
],
|
|
3431
|
+
'prompt': '${prompt}',
|
|
3432
|
+
'size': [${size[0]}, ${size[1]}],
|
|
3433
|
+
'n': 1,
|
|
3434
|
+
});</pre>`);
|
|
3435
|
+
if (imgResult && imgResult.list?.length) {
|
|
3436
|
+
echo.push(`<div>Reference Images:</div><div>
|
|
3437
|
+
<img src="https://cdn.wanx.aliyuncs.com/tmp/pressure/umbrella1.png" style="max-width: 256px; margin-right: 5px;" />
|
|
3438
|
+
<img src="https://img.alicdn.com/imgextra/i3/O1CN01SfG4J41UYn9WNt4X1_!!6000000002530-49-tps-1696-960.webp" style="max-width: 256px;" />
|
|
3439
|
+
</div>`);
|
|
3440
|
+
for (const img of imgResult.list) {
|
|
3441
|
+
echo.push(`<div><img src="${img.url.startsWith('http') ? img.url : 'data:image/png;base64,' + img.url}" style="max-width: 512px;" /></div>${lText.htmlescape(img.text || prompt)}`);
|
|
3442
|
+
}
|
|
3443
|
+
echo.push('<br>request: ' + imgResult.request, ', seed: ' + imgResult.seed);
|
|
3444
|
+
}
|
|
3445
|
+
else {
|
|
3446
|
+
echo.push('Failed');
|
|
3447
|
+
}
|
|
3448
|
+
break;
|
|
3449
|
+
}
|
|
3450
|
+
case 'text-to-video': {
|
|
3451
|
+
// --- 文生视频 ---
|
|
3452
|
+
const model = 'wan2.6-t2v';
|
|
3453
|
+
const vidResult = await ai.video({
|
|
3454
|
+
'prompt': 'A cat playing with a ball of yarn',
|
|
3455
|
+
'model': model,
|
|
3456
|
+
});
|
|
3457
|
+
echo.push(`<pre>await aiVid.video({
|
|
3458
|
+
'prompt': 'A cat playing with a ball of yarn',
|
|
3459
|
+
'model': '${model}',
|
|
3460
|
+
});</pre>`);
|
|
3461
|
+
if (vidResult) {
|
|
3462
|
+
echo.push(`<pre>${JSON.stringify(vidResult, null, 4)}</pre><a href="${this._config.const.urlBase}test/ai?action=video-poll&task=${vidResult.task}">poll</a>`);
|
|
3463
|
+
}
|
|
3464
|
+
else {
|
|
3465
|
+
echo.push('Failed');
|
|
3466
|
+
}
|
|
3467
|
+
break;
|
|
3468
|
+
}
|
|
3469
|
+
case 'image-to-video': {
|
|
3470
|
+
// --- 图生视频 ---
|
|
3471
|
+
echo.push('Not yet implemented');
|
|
3472
|
+
break;
|
|
3473
|
+
}
|
|
3474
|
+
case 'video-poll': {
|
|
3475
|
+
// --- 视频生成轮询 ---
|
|
3476
|
+
if (!this._get['task']) {
|
|
3477
|
+
echo.push('Task ID not found.');
|
|
3478
|
+
break;
|
|
3479
|
+
}
|
|
3480
|
+
const pollResult = await ai.poll({
|
|
3481
|
+
'type': 'video',
|
|
3482
|
+
'task': this._get['task'],
|
|
3483
|
+
});
|
|
3484
|
+
echo.push(`<pre>await ai.poll({
|
|
3485
|
+
'type': 'video',
|
|
3486
|
+
'task': '${this._get['task']}',
|
|
3487
|
+
});</pre>`);
|
|
3488
|
+
if (pollResult) {
|
|
3489
|
+
echo.push(`<pre>${JSON.stringify(pollResult, null, 4)}</pre>Result.`);
|
|
3490
|
+
}
|
|
3491
|
+
else {
|
|
3492
|
+
echo.push('Failed');
|
|
3493
|
+
}
|
|
3494
|
+
break;
|
|
3495
|
+
}
|
|
3496
|
+
default: {
|
|
3497
|
+
// --- CHAT ---
|
|
3498
|
+
let model = ai.service === lAi.ESERVICE.ALICN ? 'qwen-plus' : 'doubao-seed-2-0-mini-260215';
|
|
3499
|
+
if (ai.service === lAi.ESERVICE.AZURE) {
|
|
3500
|
+
model = 'gpt-4.1-nano';
|
|
3501
|
+
}
|
|
3502
|
+
const completion = await ai.chat({
|
|
3503
|
+
'model': model,
|
|
3504
|
+
'messages': [
|
|
3505
|
+
{ 'role': 'system', 'content': 'You are Kebab, a friendly and knowledgeable assistant based on an open-source Node framework. You do not mention any model names or AI identity. You can chat casually, answer questions, and provide guidance naturally. Respond in a human-like, approachable manner, as if you are a helpful companion rather than a traditional AI assistant.' },
|
|
3506
|
+
{ 'role': 'user', 'content': '你是谁?' },
|
|
3507
|
+
],
|
|
3508
|
+
});
|
|
3509
|
+
echo.push(`<pre>await ai.chat({
|
|
3510
|
+
'model': ${model},
|
|
3355
3511
|
'messages': [
|
|
3356
3512
|
{ 'role': 'system', 'content': 'You are Kebab, a friendly and knowledgeable assistant based on an open-source Node framework. You do not mention any model names or AI identity. You can chat casually, answer questions, and provide guidance naturally. Respond in a human-like, approachable manner, as if you are a helpful companion rather than a traditional AI assistant.' },
|
|
3357
3513
|
{ 'role': 'user', 'content': '你是谁?' },
|
|
3358
3514
|
],
|
|
3359
3515
|
});</pre>`);
|
|
3360
|
-
|
|
3361
|
-
|
|
3362
|
-
|
|
3363
|
-
|
|
3364
|
-
|
|
3516
|
+
if (completion) {
|
|
3517
|
+
echo.push(JSON.stringify(completion.choices[0].message.content));
|
|
3518
|
+
}
|
|
3519
|
+
else {
|
|
3520
|
+
echo.push('Failed');
|
|
3521
|
+
}
|
|
3522
|
+
}
|
|
3365
3523
|
}
|
|
3366
3524
|
return echo.join('') + '<br><br>' + this._getEnd();
|
|
3367
3525
|
}
|