opc-agent 1.3.2 → 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.
- package/.github/ISSUE_TEMPLATE/bug_report.md +20 -0
- package/.github/ISSUE_TEMPLATE/feature_request.md +14 -0
- package/.github/PULL_REQUEST_TEMPLATE.md +13 -0
- package/.github/workflows/ci.yml +24 -0
- package/CHANGELOG.md +48 -63
- package/CONTRIBUTING.md +21 -60
- package/README.md +284 -348
- package/README.zh-CN.md +415 -415
- package/dist/channels/slack.js +93 -10
- package/dist/channels/telegram.d.ts +30 -9
- package/dist/channels/telegram.js +125 -33
- package/dist/channels/web.d.ts +10 -0
- package/dist/channels/web.js +33 -2
- package/dist/cli.js +667 -65
- package/dist/core/agent.d.ts +23 -0
- package/dist/core/agent.js +120 -3
- package/dist/core/runtime.d.ts +5 -0
- package/dist/core/runtime.js +71 -0
- package/dist/core/scheduler.d.ts +52 -0
- package/dist/core/scheduler.js +168 -0
- package/dist/core/subagent.d.ts +28 -0
- package/dist/core/subagent.js +65 -0
- package/dist/daemon.d.ts +3 -0
- package/dist/daemon.js +134 -0
- package/dist/deploy/hermes.js +22 -22
- package/dist/deploy/openclaw.js +31 -40
- package/dist/index.d.ts +10 -10
- package/dist/index.js +22 -15
- package/dist/providers/index.d.ts +6 -2
- package/dist/providers/index.js +22 -9
- package/dist/schema/oad.d.ts +180 -6
- package/dist/schema/oad.js +12 -1
- package/dist/skills/auto-learn.d.ts +28 -0
- package/dist/skills/auto-learn.js +257 -0
- package/dist/templates/code-reviewer.d.ts +0 -8
- package/dist/templates/code-reviewer.js +5 -9
- package/dist/templates/customer-service.d.ts +0 -8
- package/dist/templates/customer-service.js +2 -6
- package/dist/templates/data-analyst.d.ts +0 -8
- package/dist/templates/data-analyst.js +5 -9
- package/dist/templates/knowledge-base.d.ts +0 -8
- package/dist/templates/knowledge-base.js +2 -6
- package/dist/templates/sales-assistant.d.ts +0 -8
- package/dist/templates/sales-assistant.js +4 -8
- package/dist/templates/teacher.d.ts +0 -8
- package/dist/templates/teacher.js +6 -10
- package/dist/tools/builtin/datetime.d.ts +3 -0
- package/dist/tools/builtin/datetime.js +44 -0
- package/dist/tools/builtin/file.d.ts +3 -0
- package/dist/tools/builtin/file.js +151 -0
- package/dist/tools/builtin/index.d.ts +15 -0
- package/dist/tools/builtin/index.js +30 -0
- package/dist/tools/builtin/shell.d.ts +3 -0
- package/dist/tools/builtin/shell.js +43 -0
- package/dist/tools/builtin/web.d.ts +3 -0
- package/dist/tools/builtin/web.js +37 -0
- package/dist/tools/mcp-client.d.ts +24 -0
- package/dist/tools/mcp-client.js +119 -0
- package/dist/traces/index.d.ts +49 -0
- package/dist/traces/index.js +102 -0
- package/docs/.vitepress/config.ts +103 -103
- package/docs/api/cli.md +48 -48
- package/docs/api/oad-schema.md +64 -64
- package/docs/api/sdk.md +80 -80
- package/docs/guide/concepts.md +51 -51
- package/docs/guide/configuration.md +79 -79
- package/docs/guide/deployment.md +42 -42
- package/docs/guide/getting-started.md +44 -44
- package/docs/guide/templates.md +28 -28
- package/docs/guide/testing.md +84 -84
- package/docs/index.md +27 -27
- package/docs/zh/api/cli.md +54 -54
- package/docs/zh/api/oad-schema.md +87 -87
- package/docs/zh/api/sdk.md +102 -102
- package/docs/zh/guide/concepts.md +104 -104
- package/docs/zh/guide/configuration.md +135 -135
- package/docs/zh/guide/deployment.md +81 -81
- package/docs/zh/guide/getting-started.md +82 -82
- package/docs/zh/guide/templates.md +84 -84
- package/docs/zh/guide/testing.md +88 -88
- package/docs/zh/index.md +27 -27
- package/examples/README.md +22 -0
- package/examples/basic-agent.ts +90 -0
- package/examples/brain-integration.ts +71 -0
- package/examples/customer-service-demo/README.md +90 -90
- package/examples/customer-service-demo/oad.yaml +107 -107
- package/examples/multi-channel.ts +74 -0
- package/package.json +1 -1
- package/src/analytics/index.ts +66 -66
- package/src/channels/discord.ts +192 -192
- package/src/channels/email.ts +177 -177
- package/src/channels/feishu.ts +236 -236
- package/src/channels/index.ts +15 -15
- package/src/channels/slack.ts +217 -160
- package/src/channels/telegram.ts +155 -33
- package/src/channels/voice.ts +106 -106
- package/src/channels/web.ts +38 -2
- package/src/channels/webhook.ts +199 -199
- package/src/channels/websocket.ts +87 -87
- package/src/channels/wechat.ts +149 -149
- package/src/cli.ts +697 -63
- package/src/core/a2a.ts +143 -143
- package/src/core/agent.ts +146 -3
- package/src/core/analytics-engine.ts +186 -186
- package/src/core/auth.ts +57 -57
- package/src/core/cache.ts +141 -141
- package/src/core/compose.ts +77 -77
- package/src/core/config.ts +14 -14
- package/src/core/errors.ts +148 -148
- package/src/core/hitl.ts +138 -138
- package/src/core/logger.ts +57 -57
- package/src/core/orchestrator.ts +215 -215
- package/src/core/performance.ts +187 -187
- package/src/core/rate-limiter.ts +128 -128
- package/src/core/room.ts +109 -109
- package/src/core/runtime.ts +230 -152
- package/src/core/sandbox.ts +101 -101
- package/src/core/scheduler.ts +187 -0
- package/src/core/security.ts +171 -171
- package/src/core/subagent.ts +98 -0
- package/src/core/types.ts +68 -68
- package/src/core/versioning.ts +106 -106
- package/src/core/watch.ts +178 -178
- package/src/core/workflow.ts +235 -235
- package/src/daemon.ts +96 -0
- package/src/deploy/hermes.ts +156 -156
- package/src/deploy/openclaw.ts +190 -200
- package/src/i18n/index.ts +216 -216
- package/src/index.ts +14 -10
- package/src/memory/deepbrain.ts +108 -108
- package/src/memory/index.ts +34 -34
- package/src/plugins/index.ts +208 -208
- package/src/providers/index.ts +354 -331
- package/src/schema/oad.ts +14 -2
- package/src/skills/auto-learn.ts +262 -0
- package/src/skills/base.ts +16 -16
- package/src/skills/document.ts +100 -100
- package/src/skills/http.ts +35 -35
- package/src/skills/index.ts +27 -27
- package/src/skills/scheduler.ts +80 -80
- package/src/skills/webhook-trigger.ts +59 -59
- package/src/templates/code-reviewer.ts +30 -34
- package/src/templates/customer-service.ts +76 -80
- package/src/templates/data-analyst.ts +66 -70
- package/src/templates/executive-assistant.ts +71 -71
- package/src/templates/financial-advisor.ts +60 -60
- package/src/templates/knowledge-base.ts +27 -31
- package/src/templates/legal-assistant.ts +71 -71
- package/src/templates/sales-assistant.ts +75 -79
- package/src/templates/teacher.ts +75 -79
- package/src/testing/index.ts +181 -181
- package/src/tools/builtin/datetime.ts +41 -0
- package/src/tools/builtin/file.ts +107 -0
- package/src/tools/builtin/index.ts +28 -0
- package/src/tools/builtin/shell.ts +43 -0
- package/src/tools/builtin/web.ts +35 -0
- package/src/tools/calculator.ts +73 -73
- package/src/tools/datetime.ts +149 -149
- package/src/tools/json-transform.ts +187 -187
- package/src/tools/mcp-client.ts +131 -0
- package/src/tools/mcp.ts +76 -76
- package/src/tools/text-analysis.ts +116 -116
- package/src/traces/index.ts +132 -0
- package/templates/Dockerfile +15 -15
- package/templates/code-reviewer/README.md +27 -27
- package/templates/code-reviewer/oad.yaml +41 -41
- package/templates/customer-service/README.md +22 -22
- package/templates/customer-service/oad.yaml +36 -36
- package/templates/docker-compose.yml +21 -21
- package/templates/ecommerce-assistant/README.md +45 -45
- package/templates/ecommerce-assistant/oad.yaml +47 -47
- package/templates/knowledge-base/README.md +28 -28
- package/templates/knowledge-base/oad.yaml +38 -38
- package/templates/sales-assistant/README.md +26 -26
- package/templates/sales-assistant/oad.yaml +43 -43
- package/templates/tech-support/README.md +43 -43
- package/templates/tech-support/oad.yaml +45 -45
- package/test-agent/Dockerfile +9 -0
- package/test-agent/README.md +50 -0
- package/test-agent/agent.yaml +23 -0
- package/test-agent/docker-compose.yml +11 -0
- package/test-agent/oad.yaml +31 -0
- package/test-agent/package-lock.json +1492 -0
- package/test-agent/package.json +18 -0
- package/test-agent/src/index.ts +24 -0
- package/test-agent/src/skills/echo.ts +15 -0
- package/test-agent/tsconfig.json +25 -0
- package/tests/a2a.test.ts +66 -66
- package/tests/agent.test.ts +72 -72
- package/tests/analytics.test.ts +50 -50
- package/tests/auto-learn.test.ts +105 -0
- package/tests/builtin-tools.test.ts +83 -0
- package/tests/channel.test.ts +39 -39
- package/tests/cli.test.ts +46 -0
- package/tests/e2e.test.ts +134 -134
- package/tests/errors.test.ts +83 -83
- package/tests/hitl.test.ts +71 -71
- package/tests/i18n.test.ts +41 -41
- package/tests/mcp.test.ts +54 -54
- package/tests/oad.test.ts +68 -68
- package/tests/performance.test.ts +115 -115
- package/tests/plugin.test.ts +74 -74
- package/tests/room.test.ts +106 -106
- package/tests/runtime.test.ts +42 -42
- package/tests/sandbox.test.ts +46 -46
- package/tests/security.test.ts +60 -60
- package/tests/subagent.test.ts +130 -0
- package/tests/telegram-discord.test.ts +60 -0
- package/tests/templates.test.ts +77 -77
- package/tests/v070.test.ts +76 -76
- package/tests/versioning.test.ts +75 -75
- package/tests/voice.test.ts +61 -61
- package/tests/webhook.test.ts +29 -29
- package/tests/workflow.test.ts +143 -143
- package/tsconfig.json +19 -19
- package/vitest.config.ts +9 -9
- package/dist/core/dashboard.d.ts +0 -35
- package/dist/core/dashboard.js +0 -157
- package/dist/core/priority.d.ts +0 -52
- package/dist/core/priority.js +0 -102
- package/src/core/dashboard.ts +0 -219
- package/src/core/priority.ts +0 -140
- package/src/dtv/data.ts +0 -29
- package/src/dtv/trust.ts +0 -43
- package/src/dtv/value.ts +0 -47
- package/src/marketplace/index.ts +0 -223
package/dist/channels/slack.js
CHANGED
|
@@ -1,4 +1,37 @@
|
|
|
1
1
|
"use strict";
|
|
2
|
+
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
|
|
3
|
+
if (k2 === undefined) k2 = k;
|
|
4
|
+
var desc = Object.getOwnPropertyDescriptor(m, k);
|
|
5
|
+
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
|
|
6
|
+
desc = { enumerable: true, get: function() { return m[k]; } };
|
|
7
|
+
}
|
|
8
|
+
Object.defineProperty(o, k2, desc);
|
|
9
|
+
}) : (function(o, m, k, k2) {
|
|
10
|
+
if (k2 === undefined) k2 = k;
|
|
11
|
+
o[k2] = m[k];
|
|
12
|
+
}));
|
|
13
|
+
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
|
|
14
|
+
Object.defineProperty(o, "default", { enumerable: true, value: v });
|
|
15
|
+
}) : function(o, v) {
|
|
16
|
+
o["default"] = v;
|
|
17
|
+
});
|
|
18
|
+
var __importStar = (this && this.__importStar) || (function () {
|
|
19
|
+
var ownKeys = function(o) {
|
|
20
|
+
ownKeys = Object.getOwnPropertyNames || function (o) {
|
|
21
|
+
var ar = [];
|
|
22
|
+
for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
|
|
23
|
+
return ar;
|
|
24
|
+
};
|
|
25
|
+
return ownKeys(o);
|
|
26
|
+
};
|
|
27
|
+
return function (mod) {
|
|
28
|
+
if (mod && mod.__esModule) return mod;
|
|
29
|
+
var result = {};
|
|
30
|
+
if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
|
|
31
|
+
__setModuleDefault(result, mod);
|
|
32
|
+
return result;
|
|
33
|
+
};
|
|
34
|
+
})();
|
|
2
35
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
36
|
exports.SlackChannel = void 0;
|
|
4
37
|
const index_1 = require("./index");
|
|
@@ -37,9 +70,51 @@ class SlackChannel extends index_1.BaseChannel {
|
|
|
37
70
|
}
|
|
38
71
|
/** Start Events API HTTP server */
|
|
39
72
|
async startEventsAPI() {
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
73
|
+
const http = await Promise.resolve().then(() => __importStar(require('http')));
|
|
74
|
+
const port = this.config.port ?? 3001;
|
|
75
|
+
const server = http.createServer(async (req, res) => {
|
|
76
|
+
if (req.method !== 'POST') {
|
|
77
|
+
res.writeHead(404);
|
|
78
|
+
res.end();
|
|
79
|
+
return;
|
|
80
|
+
}
|
|
81
|
+
const chunks = [];
|
|
82
|
+
for await (const chunk of req)
|
|
83
|
+
chunks.push(chunk);
|
|
84
|
+
const body = JSON.parse(Buffer.concat(chunks).toString());
|
|
85
|
+
// URL verification challenge
|
|
86
|
+
if (body.type === 'url_verification') {
|
|
87
|
+
res.writeHead(200, { 'Content-Type': 'application/json' });
|
|
88
|
+
res.end(JSON.stringify({ challenge: body.challenge }));
|
|
89
|
+
return;
|
|
90
|
+
}
|
|
91
|
+
// Event callback
|
|
92
|
+
if (body.type === 'event_callback' && body.event) {
|
|
93
|
+
const event = body.event;
|
|
94
|
+
if (event.type === 'message' || event.type === 'app_mention') {
|
|
95
|
+
// Don't block the HTTP response
|
|
96
|
+
this.handleMessage(event).catch(() => { });
|
|
97
|
+
}
|
|
98
|
+
}
|
|
99
|
+
// Slash commands (form-urlencoded, but we handle JSON for simplicity)
|
|
100
|
+
if (req.url === '/slack/commands' && body.command) {
|
|
101
|
+
const reply = await this.handleSlashCommand({
|
|
102
|
+
command: body.command,
|
|
103
|
+
text: body.text ?? '',
|
|
104
|
+
userId: body.user_id,
|
|
105
|
+
channelId: body.channel_id,
|
|
106
|
+
triggerId: body.trigger_id,
|
|
107
|
+
});
|
|
108
|
+
res.writeHead(200, { 'Content-Type': 'application/json' });
|
|
109
|
+
res.end(JSON.stringify({ response_type: 'ephemeral', text: reply }));
|
|
110
|
+
return;
|
|
111
|
+
}
|
|
112
|
+
res.writeHead(200);
|
|
113
|
+
res.end('ok');
|
|
114
|
+
});
|
|
115
|
+
server.listen(port, () => {
|
|
116
|
+
console.log(`[SlackChannel] Events API listening on port ${port}`);
|
|
117
|
+
});
|
|
43
118
|
}
|
|
44
119
|
/** Handle incoming Slack message */
|
|
45
120
|
async handleMessage(event) {
|
|
@@ -94,13 +169,21 @@ class SlackChannel extends index_1.BaseChannel {
|
|
|
94
169
|
}
|
|
95
170
|
/** Send a message to a Slack channel */
|
|
96
171
|
async sendMessage(channel, text, threadTs) {
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
172
|
+
const body = { channel, text };
|
|
173
|
+
if (threadTs)
|
|
174
|
+
body.thread_ts = threadTs;
|
|
175
|
+
const res = await fetch('https://slack.com/api/chat.postMessage', {
|
|
176
|
+
method: 'POST',
|
|
177
|
+
headers: {
|
|
178
|
+
'Authorization': `Bearer ${this.config.botToken}`,
|
|
179
|
+
'Content-Type': 'application/json',
|
|
180
|
+
},
|
|
181
|
+
body: JSON.stringify(body),
|
|
182
|
+
});
|
|
183
|
+
const data = await res.json();
|
|
184
|
+
if (!data.ok) {
|
|
185
|
+
console.error(`[SlackChannel] chat.postMessage failed: ${data.error}`);
|
|
186
|
+
}
|
|
104
187
|
}
|
|
105
188
|
}
|
|
106
189
|
exports.SlackChannel = SlackChannel;
|
|
@@ -1,21 +1,42 @@
|
|
|
1
1
|
import { BaseChannel } from './index';
|
|
2
2
|
/**
|
|
3
|
-
* Telegram channel —
|
|
4
|
-
*
|
|
3
|
+
* Telegram channel — supports both long-polling and webhook modes.
|
|
4
|
+
*
|
|
5
|
+
* Config:
|
|
6
|
+
* token: bot token (or TELEGRAM_BOT_TOKEN env var)
|
|
7
|
+
* mode: 'polling' | 'webhook' (default: 'polling')
|
|
8
|
+
* webhookUrl: required for webhook mode
|
|
9
|
+
* port: webhook server port (default: 3001)
|
|
10
|
+
*
|
|
11
|
+
* Polling mode requires no public URL — ideal for dev/local.
|
|
12
|
+
* Webhook mode is more efficient for production.
|
|
5
13
|
*/
|
|
14
|
+
export interface TelegramChannelConfig {
|
|
15
|
+
token?: string;
|
|
16
|
+
mode?: 'polling' | 'webhook';
|
|
17
|
+
webhookUrl?: string;
|
|
18
|
+
port?: number;
|
|
19
|
+
}
|
|
6
20
|
export declare class TelegramChannel extends BaseChannel {
|
|
7
21
|
readonly type = "telegram";
|
|
8
22
|
private token;
|
|
23
|
+
private mode;
|
|
9
24
|
private webhookUrl?;
|
|
10
|
-
private server;
|
|
11
25
|
private port;
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
});
|
|
26
|
+
private offset;
|
|
27
|
+
private polling;
|
|
28
|
+
private server;
|
|
29
|
+
constructor(config?: TelegramChannelConfig);
|
|
17
30
|
start(): Promise<void>;
|
|
18
31
|
stop(): Promise<void>;
|
|
19
|
-
private
|
|
32
|
+
private startPolling;
|
|
33
|
+
private poll;
|
|
34
|
+
private getUpdates;
|
|
35
|
+
private startWebhook;
|
|
36
|
+
private stopWebhook;
|
|
37
|
+
private processUpdate;
|
|
38
|
+
sendMessage(chatId: number | string, text: string): Promise<void>;
|
|
39
|
+
private apiCall;
|
|
40
|
+
private splitText;
|
|
20
41
|
}
|
|
21
42
|
//# sourceMappingURL=telegram.d.ts.map
|
|
@@ -35,58 +35,105 @@ var __importStar = (this && this.__importStar) || (function () {
|
|
|
35
35
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
36
36
|
exports.TelegramChannel = void 0;
|
|
37
37
|
const index_1 = require("./index");
|
|
38
|
-
/**
|
|
39
|
-
* Telegram channel — basic webhook handler for Telegram Bot API.
|
|
40
|
-
* Set TELEGRAM_BOT_TOKEN env var or pass in config.
|
|
41
|
-
*/
|
|
42
38
|
class TelegramChannel extends index_1.BaseChannel {
|
|
43
39
|
type = 'telegram';
|
|
44
40
|
token;
|
|
41
|
+
mode;
|
|
45
42
|
webhookUrl;
|
|
46
|
-
server = null;
|
|
47
43
|
port;
|
|
48
|
-
|
|
44
|
+
// Polling state
|
|
45
|
+
offset = 0;
|
|
46
|
+
polling = false;
|
|
47
|
+
// Webhook state
|
|
48
|
+
server = null;
|
|
49
|
+
constructor(config = {}) {
|
|
49
50
|
super();
|
|
50
|
-
this.token =
|
|
51
|
-
this.
|
|
52
|
-
this.
|
|
51
|
+
this.token = config.token ?? process.env.TELEGRAM_BOT_TOKEN ?? '';
|
|
52
|
+
this.mode = config.mode ?? 'polling';
|
|
53
|
+
this.webhookUrl = config.webhookUrl;
|
|
54
|
+
this.port = config.port ?? 3001;
|
|
53
55
|
}
|
|
54
56
|
async start() {
|
|
55
57
|
if (!this.token) {
|
|
56
58
|
console.warn('[TelegramChannel] No bot token provided. Set TELEGRAM_BOT_TOKEN or pass token in config.');
|
|
57
59
|
return;
|
|
58
60
|
}
|
|
61
|
+
if (this.mode === 'webhook') {
|
|
62
|
+
await this.startWebhook();
|
|
63
|
+
}
|
|
64
|
+
else {
|
|
65
|
+
await this.startPolling();
|
|
66
|
+
}
|
|
67
|
+
}
|
|
68
|
+
async stop() {
|
|
69
|
+
if (this.mode === 'webhook') {
|
|
70
|
+
await this.stopWebhook();
|
|
71
|
+
}
|
|
72
|
+
else {
|
|
73
|
+
this.polling = false;
|
|
74
|
+
}
|
|
75
|
+
}
|
|
76
|
+
// ─── Polling Mode ────────────────────────────────────────
|
|
77
|
+
async startPolling() {
|
|
78
|
+
// Delete any existing webhook so polling works
|
|
79
|
+
await this.apiCall('deleteWebhook');
|
|
80
|
+
console.log(`[TelegramChannel] Started long-polling mode`);
|
|
81
|
+
this.polling = true;
|
|
82
|
+
this.poll();
|
|
83
|
+
}
|
|
84
|
+
async poll() {
|
|
85
|
+
while (this.polling) {
|
|
86
|
+
try {
|
|
87
|
+
const updates = await this.getUpdates();
|
|
88
|
+
for (const update of updates) {
|
|
89
|
+
await this.processUpdate(update);
|
|
90
|
+
}
|
|
91
|
+
}
|
|
92
|
+
catch (err) {
|
|
93
|
+
console.error('[TelegramChannel] Polling error:', err);
|
|
94
|
+
// Back off on error
|
|
95
|
+
if (this.polling) {
|
|
96
|
+
await new Promise((r) => setTimeout(r, 5000));
|
|
97
|
+
}
|
|
98
|
+
}
|
|
99
|
+
}
|
|
100
|
+
}
|
|
101
|
+
async getUpdates() {
|
|
102
|
+
const url = `https://api.telegram.org/bot${this.token}/getUpdates?offset=${this.offset}&timeout=30&allowed_updates=["message"]`;
|
|
103
|
+
const controller = new AbortController();
|
|
104
|
+
const timeout = setTimeout(() => controller.abort(), 40000); // 30s long-poll + 10s buffer
|
|
105
|
+
try {
|
|
106
|
+
const res = await fetch(url, { signal: controller.signal });
|
|
107
|
+
const data = (await res.json());
|
|
108
|
+
if (data.ok && data.result.length > 0) {
|
|
109
|
+
this.offset = data.result[data.result.length - 1].update_id + 1;
|
|
110
|
+
}
|
|
111
|
+
return data.result || [];
|
|
112
|
+
}
|
|
113
|
+
finally {
|
|
114
|
+
clearTimeout(timeout);
|
|
115
|
+
}
|
|
116
|
+
}
|
|
117
|
+
// ─── Webhook Mode ────────────────────────────────────────
|
|
118
|
+
async startWebhook() {
|
|
119
|
+
if (this.webhookUrl) {
|
|
120
|
+
await this.apiCall('setWebhook', { url: `${this.webhookUrl}/webhook/${this.token}` });
|
|
121
|
+
}
|
|
59
122
|
const express = (await Promise.resolve().then(() => __importStar(require('express')))).default;
|
|
60
123
|
const app = express();
|
|
61
124
|
app.use(express.json());
|
|
62
125
|
app.post(`/webhook/${this.token}`, async (req, res) => {
|
|
63
126
|
try {
|
|
64
|
-
|
|
65
|
-
if (update.message?.text && this.handler) {
|
|
66
|
-
const msg = {
|
|
67
|
-
id: `tg_${update.message.message_id}`,
|
|
68
|
-
role: 'user',
|
|
69
|
-
content: update.message.text,
|
|
70
|
-
timestamp: update.message.date * 1000,
|
|
71
|
-
metadata: {
|
|
72
|
-
sessionId: `tg_${update.message.chat.id}`,
|
|
73
|
-
chatId: update.message.chat.id,
|
|
74
|
-
userId: update.message.from?.id,
|
|
75
|
-
platform: 'telegram',
|
|
76
|
-
},
|
|
77
|
-
};
|
|
78
|
-
const response = await this.handler(msg);
|
|
79
|
-
await this.sendMessage(update.message.chat.id, response.content);
|
|
80
|
-
}
|
|
127
|
+
await this.processUpdate(req.body);
|
|
81
128
|
res.json({ ok: true });
|
|
82
129
|
}
|
|
83
130
|
catch (err) {
|
|
84
|
-
console.error('[TelegramChannel]
|
|
131
|
+
console.error('[TelegramChannel] Webhook error:', err);
|
|
85
132
|
res.status(500).json({ error: 'Internal error' });
|
|
86
133
|
}
|
|
87
134
|
});
|
|
88
135
|
app.get('/health', (_req, res) => {
|
|
89
|
-
res.json({ status: 'ok', channel: 'telegram' });
|
|
136
|
+
res.json({ status: 'ok', channel: 'telegram', mode: 'webhook' });
|
|
90
137
|
});
|
|
91
138
|
return new Promise((resolve) => {
|
|
92
139
|
this.server = app.listen(this.port, () => {
|
|
@@ -95,25 +142,70 @@ class TelegramChannel extends index_1.BaseChannel {
|
|
|
95
142
|
});
|
|
96
143
|
});
|
|
97
144
|
}
|
|
98
|
-
async
|
|
145
|
+
async stopWebhook() {
|
|
99
146
|
return new Promise((resolve, reject) => {
|
|
100
147
|
if (!this.server)
|
|
101
148
|
return resolve();
|
|
102
149
|
this.server.close((err) => (err ? reject(err) : resolve()));
|
|
103
150
|
});
|
|
104
151
|
}
|
|
152
|
+
// ─── Shared ──────────────────────────────────────────────
|
|
153
|
+
async processUpdate(update) {
|
|
154
|
+
const message = update.message || update.edited_message;
|
|
155
|
+
if (!message?.text || !this.handler)
|
|
156
|
+
return;
|
|
157
|
+
const msg = {
|
|
158
|
+
id: `tg_${message.message_id}`,
|
|
159
|
+
role: 'user',
|
|
160
|
+
content: message.text,
|
|
161
|
+
timestamp: message.date * 1000,
|
|
162
|
+
metadata: {
|
|
163
|
+
sessionId: `tg_${message.chat.id}`,
|
|
164
|
+
chatId: message.chat.id,
|
|
165
|
+
userId: message.from?.id,
|
|
166
|
+
username: message.from?.username,
|
|
167
|
+
firstName: message.from?.first_name,
|
|
168
|
+
platform: 'telegram',
|
|
169
|
+
chatType: message.chat.type,
|
|
170
|
+
},
|
|
171
|
+
};
|
|
172
|
+
const response = await this.handler(msg);
|
|
173
|
+
await this.sendMessage(message.chat.id, response.content);
|
|
174
|
+
}
|
|
105
175
|
async sendMessage(chatId, text) {
|
|
106
|
-
|
|
176
|
+
// Telegram max message length is 4096
|
|
177
|
+
const chunks = this.splitText(text, 4096);
|
|
178
|
+
for (const chunk of chunks) {
|
|
179
|
+
await this.apiCall('sendMessage', {
|
|
180
|
+
chat_id: chatId,
|
|
181
|
+
text: chunk,
|
|
182
|
+
parse_mode: 'Markdown',
|
|
183
|
+
});
|
|
184
|
+
}
|
|
185
|
+
}
|
|
186
|
+
async apiCall(method, body) {
|
|
187
|
+
const url = `https://api.telegram.org/bot${this.token}/${method}`;
|
|
107
188
|
try {
|
|
108
|
-
await fetch(url, {
|
|
189
|
+
const res = await fetch(url, {
|
|
109
190
|
method: 'POST',
|
|
110
191
|
headers: { 'Content-Type': 'application/json' },
|
|
111
|
-
body: JSON.stringify(
|
|
192
|
+
body: body ? JSON.stringify(body) : undefined,
|
|
112
193
|
});
|
|
194
|
+
return await res.json();
|
|
113
195
|
}
|
|
114
196
|
catch (err) {
|
|
115
|
-
console.error(
|
|
197
|
+
console.error(`[TelegramChannel] API call ${method} failed:`, err);
|
|
198
|
+
throw err;
|
|
199
|
+
}
|
|
200
|
+
}
|
|
201
|
+
splitText(text, maxLen) {
|
|
202
|
+
if (text.length <= maxLen)
|
|
203
|
+
return [text];
|
|
204
|
+
const parts = [];
|
|
205
|
+
for (let i = 0; i < text.length; i += maxLen) {
|
|
206
|
+
parts.push(text.slice(i, i + maxLen));
|
|
116
207
|
}
|
|
208
|
+
return parts;
|
|
117
209
|
}
|
|
118
210
|
}
|
|
119
211
|
exports.TelegramChannel = TelegramChannel;
|
package/dist/channels/web.d.ts
CHANGED
|
@@ -9,6 +9,11 @@ export declare class WebChannel extends BaseChannel {
|
|
|
9
9
|
private port;
|
|
10
10
|
private streamHandler;
|
|
11
11
|
private agentName;
|
|
12
|
+
private agentVersion;
|
|
13
|
+
private memoryType;
|
|
14
|
+
private skillNames;
|
|
15
|
+
private channelNames;
|
|
16
|
+
private analyticsProvider;
|
|
12
17
|
private currentProvider;
|
|
13
18
|
private stats;
|
|
14
19
|
private eventHandlers;
|
|
@@ -23,6 +28,11 @@ export declare class WebChannel extends BaseChannel {
|
|
|
23
28
|
trackSession(): void;
|
|
24
29
|
constructor(port?: number, authConfig?: AuthConfig);
|
|
25
30
|
setAgentName(name: string): void;
|
|
31
|
+
setAgentVersion(version: string): void;
|
|
32
|
+
setMemoryType(type: string): void;
|
|
33
|
+
setSkillNames(names: string[]): void;
|
|
34
|
+
setChannelNames(names: string[]): void;
|
|
35
|
+
setAnalyticsProvider(fn: () => any): void;
|
|
26
36
|
onStreamMessage(handler: (msg: Message, res: Response) => Promise<void>): void;
|
|
27
37
|
private setupRoutes;
|
|
28
38
|
start(): Promise<void>;
|
package/dist/channels/web.js
CHANGED
|
@@ -286,6 +286,11 @@ class WebChannel extends index_1.BaseChannel {
|
|
|
286
286
|
port;
|
|
287
287
|
streamHandler = null;
|
|
288
288
|
agentName = 'OPC Agent';
|
|
289
|
+
agentVersion = '1.0.0';
|
|
290
|
+
memoryType = 'in-memory';
|
|
291
|
+
skillNames = [];
|
|
292
|
+
channelNames = ['web'];
|
|
293
|
+
analyticsProvider = null;
|
|
289
294
|
currentProvider = 'openai';
|
|
290
295
|
stats = { sessions: 0, messages: 0, totalResponseMs: 0, tokenUsage: 0, knowledgeFiles: 0, startedAt: Date.now(), errors: 0 };
|
|
291
296
|
eventHandlers = new Map();
|
|
@@ -326,6 +331,21 @@ class WebChannel extends index_1.BaseChannel {
|
|
|
326
331
|
setAgentName(name) {
|
|
327
332
|
this.agentName = name;
|
|
328
333
|
}
|
|
334
|
+
setAgentVersion(version) {
|
|
335
|
+
this.agentVersion = version;
|
|
336
|
+
}
|
|
337
|
+
setMemoryType(type) {
|
|
338
|
+
this.memoryType = type;
|
|
339
|
+
}
|
|
340
|
+
setSkillNames(names) {
|
|
341
|
+
this.skillNames = names;
|
|
342
|
+
}
|
|
343
|
+
setChannelNames(names) {
|
|
344
|
+
this.channelNames = names;
|
|
345
|
+
}
|
|
346
|
+
setAnalyticsProvider(fn) {
|
|
347
|
+
this.analyticsProvider = fn;
|
|
348
|
+
}
|
|
329
349
|
onStreamMessage(handler) {
|
|
330
350
|
this.streamHandler = handler;
|
|
331
351
|
}
|
|
@@ -334,7 +354,17 @@ class WebChannel extends index_1.BaseChannel {
|
|
|
334
354
|
res.type('html').send(CHAT_HTML);
|
|
335
355
|
});
|
|
336
356
|
this.app.get('/health', (_req, res) => {
|
|
337
|
-
res.json({
|
|
357
|
+
res.json({
|
|
358
|
+
status: 'ok',
|
|
359
|
+
agent: this.agentName,
|
|
360
|
+
version: this.agentVersion,
|
|
361
|
+
uptime: Date.now() - this.stats.startedAt,
|
|
362
|
+
memory: this.memoryType,
|
|
363
|
+
skills: this.skillNames,
|
|
364
|
+
channels: this.channelNames,
|
|
365
|
+
analytics: this.analyticsProvider ? this.analyticsProvider() : null,
|
|
366
|
+
timestamp: Date.now(),
|
|
367
|
+
});
|
|
338
368
|
});
|
|
339
369
|
this.app.get('/api/info', (_req, res) => {
|
|
340
370
|
res.json({ name: this.agentName });
|
|
@@ -408,7 +438,8 @@ class WebChannel extends index_1.BaseChannel {
|
|
|
408
438
|
res.type('html').send(DASHBOARD_HTML);
|
|
409
439
|
});
|
|
410
440
|
this.app.get('/api/dashboard', (_req, res) => {
|
|
411
|
-
|
|
441
|
+
const analytics = this.analyticsProvider ? this.analyticsProvider() : null;
|
|
442
|
+
res.json({ ...this.stats, analytics });
|
|
412
443
|
});
|
|
413
444
|
// --- Knowledge Base Upload ---
|
|
414
445
|
this.app.post('/api/kb/upload', async (req, res) => {
|