opc-agent 1.4.0 → 2.0.1

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.
Files changed (198) hide show
  1. package/CHANGELOG.md +25 -0
  2. package/README.md +91 -32
  3. package/dist/channels/email.d.ts +32 -26
  4. package/dist/channels/email.js +239 -62
  5. package/dist/channels/feishu.d.ts +21 -6
  6. package/dist/channels/feishu.js +225 -126
  7. package/dist/channels/telegram.d.ts +30 -9
  8. package/dist/channels/telegram.js +125 -33
  9. package/dist/channels/websocket.d.ts +46 -3
  10. package/dist/channels/websocket.js +306 -37
  11. package/dist/channels/wechat.d.ts +33 -13
  12. package/dist/channels/wechat.js +229 -42
  13. package/dist/cli.js +1127 -19
  14. package/dist/core/a2a.d.ts +17 -0
  15. package/dist/core/a2a.js +43 -1
  16. package/dist/core/agent.d.ts +39 -0
  17. package/dist/core/agent.js +228 -3
  18. package/dist/core/runtime.d.ts +7 -0
  19. package/dist/core/runtime.js +205 -2
  20. package/dist/core/sandbox.d.ts +26 -0
  21. package/dist/core/sandbox.js +117 -0
  22. package/dist/core/scheduler.d.ts +52 -0
  23. package/dist/core/scheduler.js +168 -0
  24. package/dist/core/subagent.d.ts +28 -0
  25. package/dist/core/subagent.js +65 -0
  26. package/dist/core/workflow-graph.d.ts +93 -0
  27. package/dist/core/workflow-graph.js +247 -0
  28. package/dist/daemon.d.ts +3 -0
  29. package/dist/daemon.js +134 -0
  30. package/dist/doctor.d.ts +15 -0
  31. package/dist/doctor.js +183 -0
  32. package/dist/eval/index.d.ts +65 -0
  33. package/dist/eval/index.js +191 -0
  34. package/dist/index.d.ts +37 -6
  35. package/dist/index.js +75 -3
  36. package/dist/plugins/content-filter.d.ts +7 -0
  37. package/dist/plugins/content-filter.js +25 -0
  38. package/dist/plugins/index.d.ts +42 -0
  39. package/dist/plugins/index.js +108 -2
  40. package/dist/plugins/logger.d.ts +6 -0
  41. package/dist/plugins/logger.js +20 -0
  42. package/dist/plugins/rate-limiter.d.ts +7 -0
  43. package/dist/plugins/rate-limiter.js +35 -0
  44. package/dist/protocols/a2a/client.d.ts +25 -0
  45. package/dist/protocols/a2a/client.js +115 -0
  46. package/dist/protocols/a2a/index.d.ts +6 -0
  47. package/dist/protocols/a2a/index.js +12 -0
  48. package/dist/protocols/a2a/server.d.ts +41 -0
  49. package/dist/protocols/a2a/server.js +295 -0
  50. package/dist/protocols/a2a/types.d.ts +91 -0
  51. package/dist/protocols/a2a/types.js +15 -0
  52. package/dist/protocols/a2a/utils.d.ts +6 -0
  53. package/dist/protocols/a2a/utils.js +47 -0
  54. package/dist/protocols/agui/client.d.ts +10 -0
  55. package/dist/protocols/agui/client.js +75 -0
  56. package/dist/protocols/agui/index.d.ts +4 -0
  57. package/dist/protocols/agui/index.js +25 -0
  58. package/dist/protocols/agui/server.d.ts +37 -0
  59. package/dist/protocols/agui/server.js +191 -0
  60. package/dist/protocols/agui/types.d.ts +107 -0
  61. package/dist/protocols/agui/types.js +17 -0
  62. package/dist/protocols/index.d.ts +2 -0
  63. package/dist/protocols/index.js +19 -0
  64. package/dist/protocols/mcp/agent-tools.d.ts +11 -0
  65. package/dist/protocols/mcp/agent-tools.js +129 -0
  66. package/dist/protocols/mcp/index.d.ts +5 -0
  67. package/dist/protocols/mcp/index.js +11 -0
  68. package/dist/protocols/mcp/server.d.ts +31 -0
  69. package/dist/protocols/mcp/server.js +248 -0
  70. package/dist/protocols/mcp/types.d.ts +92 -0
  71. package/dist/protocols/mcp/types.js +17 -0
  72. package/dist/providers/index.d.ts +5 -1
  73. package/dist/providers/index.js +16 -9
  74. package/dist/publish/index.d.ts +45 -0
  75. package/dist/publish/index.js +350 -0
  76. package/dist/schema/oad.d.ts +859 -67
  77. package/dist/schema/oad.js +47 -3
  78. package/dist/security/approval.d.ts +36 -0
  79. package/dist/security/approval.js +113 -0
  80. package/dist/security/index.d.ts +4 -0
  81. package/dist/security/index.js +8 -0
  82. package/dist/security/keys.d.ts +16 -0
  83. package/dist/security/keys.js +117 -0
  84. package/dist/skills/auto-learn.d.ts +28 -0
  85. package/dist/skills/auto-learn.js +257 -0
  86. package/dist/studio/server.d.ts +63 -0
  87. package/dist/studio/server.js +625 -0
  88. package/dist/studio-ui/index.html +662 -0
  89. package/dist/telemetry/index.d.ts +93 -0
  90. package/dist/telemetry/index.js +285 -0
  91. package/dist/tools/builtin/datetime.d.ts +3 -0
  92. package/dist/tools/builtin/datetime.js +44 -0
  93. package/dist/tools/builtin/file.d.ts +3 -0
  94. package/dist/tools/builtin/file.js +151 -0
  95. package/dist/tools/builtin/index.d.ts +15 -0
  96. package/dist/tools/builtin/index.js +30 -0
  97. package/dist/tools/builtin/shell.d.ts +3 -0
  98. package/dist/tools/builtin/shell.js +43 -0
  99. package/dist/tools/builtin/web.d.ts +3 -0
  100. package/dist/tools/builtin/web.js +37 -0
  101. package/dist/tools/mcp-client.d.ts +24 -0
  102. package/dist/tools/mcp-client.js +119 -0
  103. package/package.json +5 -3
  104. package/scripts/install.ps1 +31 -0
  105. package/scripts/install.sh +40 -0
  106. package/src/channels/email.ts +351 -177
  107. package/src/channels/feishu.ts +349 -236
  108. package/src/channels/telegram.ts +212 -90
  109. package/src/channels/websocket.ts +399 -87
  110. package/src/channels/wechat.ts +329 -149
  111. package/src/cli.ts +1201 -20
  112. package/src/core/a2a.ts +60 -0
  113. package/src/core/agent.ts +420 -152
  114. package/src/core/runtime.ts +174 -0
  115. package/src/core/sandbox.ts +143 -0
  116. package/src/core/scheduler.ts +187 -0
  117. package/src/core/subagent.ts +98 -0
  118. package/src/core/workflow-graph.ts +365 -0
  119. package/src/daemon.ts +96 -0
  120. package/src/doctor.ts +156 -0
  121. package/src/eval/index.ts +211 -0
  122. package/src/eval/suites/basic.json +16 -0
  123. package/src/eval/suites/memory.json +12 -0
  124. package/src/eval/suites/safety.json +14 -0
  125. package/src/index.ts +65 -6
  126. package/src/plugins/content-filter.ts +23 -0
  127. package/src/plugins/index.ts +133 -2
  128. package/src/plugins/logger.ts +18 -0
  129. package/src/plugins/rate-limiter.ts +38 -0
  130. package/src/protocols/a2a/client.ts +132 -0
  131. package/src/protocols/a2a/index.ts +8 -0
  132. package/src/protocols/a2a/server.ts +333 -0
  133. package/src/protocols/a2a/types.ts +88 -0
  134. package/src/protocols/a2a/utils.ts +50 -0
  135. package/src/protocols/agui/client.ts +83 -0
  136. package/src/protocols/agui/index.ts +4 -0
  137. package/src/protocols/agui/server.ts +218 -0
  138. package/src/protocols/agui/types.ts +153 -0
  139. package/src/protocols/index.ts +2 -0
  140. package/src/protocols/mcp/agent-tools.ts +134 -0
  141. package/src/protocols/mcp/index.ts +8 -0
  142. package/src/protocols/mcp/server.ts +262 -0
  143. package/src/protocols/mcp/types.ts +69 -0
  144. package/src/providers/index.ts +354 -339
  145. package/src/publish/index.ts +376 -0
  146. package/src/schema/oad.ts +204 -154
  147. package/src/security/approval.ts +131 -0
  148. package/src/security/index.ts +3 -0
  149. package/src/security/keys.ts +87 -0
  150. package/src/skills/auto-learn.ts +262 -0
  151. package/src/studio/server.ts +629 -0
  152. package/src/studio-ui/index.html +662 -0
  153. package/src/telemetry/index.ts +324 -0
  154. package/src/tools/builtin/datetime.ts +41 -0
  155. package/src/tools/builtin/file.ts +107 -0
  156. package/src/tools/builtin/index.ts +28 -0
  157. package/src/tools/builtin/shell.ts +43 -0
  158. package/src/tools/builtin/web.ts +35 -0
  159. package/src/tools/mcp-client.ts +131 -0
  160. package/src/types/agent-workstation.d.ts +2 -0
  161. package/tests/a2a-protocol.test.ts +285 -0
  162. package/tests/agui-protocol.test.ts +246 -0
  163. package/tests/auto-learn.test.ts +105 -0
  164. package/tests/builtin-tools.test.ts +83 -0
  165. package/tests/channels/discord.test.ts +79 -0
  166. package/tests/channels/email.test.ts +148 -0
  167. package/tests/channels/feishu.test.ts +123 -0
  168. package/tests/channels/telegram.test.ts +129 -0
  169. package/tests/channels/websocket.test.ts +53 -0
  170. package/tests/channels/wechat.test.ts +170 -0
  171. package/tests/chat-cli.test.ts +160 -0
  172. package/tests/cli.test.ts +46 -0
  173. package/tests/daemon.test.ts +135 -0
  174. package/tests/deepbrain-wire.test.ts +234 -0
  175. package/tests/doctor.test.ts +38 -0
  176. package/tests/eval.test.ts +173 -0
  177. package/tests/init-role.test.ts +124 -0
  178. package/tests/mcp-client.test.ts +92 -0
  179. package/tests/mcp-server.test.ts +178 -0
  180. package/tests/plugin-a2a-enhanced.test.ts +230 -0
  181. package/tests/publish.test.ts +231 -0
  182. package/tests/scheduler.test.ts +200 -0
  183. package/tests/security-enhanced.test.ts +233 -0
  184. package/tests/skill-learner.test.ts +161 -0
  185. package/tests/studio.test.ts +229 -0
  186. package/tests/subagent.test.ts +193 -0
  187. package/tests/telegram-discord.test.ts +60 -0
  188. package/tests/telemetry.test.ts +186 -0
  189. package/tests/tools/builtin-extended.test.ts +138 -0
  190. package/tests/workflow-graph.test.ts +279 -0
  191. package/tutorial/customer-service-agent/README.md +612 -0
  192. package/tutorial/customer-service-agent/SOUL.md +26 -0
  193. package/tutorial/customer-service-agent/agent.yaml +63 -0
  194. package/tutorial/customer-service-agent/package.json +19 -0
  195. package/tutorial/customer-service-agent/src/index.ts +69 -0
  196. package/tutorial/customer-service-agent/src/skills/faq.ts +27 -0
  197. package/tutorial/customer-service-agent/src/skills/ticket.ts +22 -0
  198. package/tutorial/customer-service-agent/tsconfig.json +14 -0
@@ -1,90 +1,212 @@
1
- import type { Message } from '../core/types';
2
- import { BaseChannel } from './index';
3
-
4
- /**
5
- * Telegram channel — basic webhook handler for Telegram Bot API.
6
- * Set TELEGRAM_BOT_TOKEN env var or pass in config.
7
- */
8
- export class TelegramChannel extends BaseChannel {
9
- readonly type = 'telegram';
10
- private token: string;
11
- private webhookUrl?: string;
12
- private server: import('http').Server | null = null;
13
- private port: number;
14
-
15
- constructor(options: { token?: string; webhookUrl?: string; port?: number } = {}) {
16
- super();
17
- this.token = options.token ?? process.env.TELEGRAM_BOT_TOKEN ?? '';
18
- this.webhookUrl = options.webhookUrl;
19
- this.port = options.port ?? 3001;
20
- }
21
-
22
- async start(): Promise<void> {
23
- if (!this.token) {
24
- console.warn('[TelegramChannel] No bot token provided. Set TELEGRAM_BOT_TOKEN or pass token in config.');
25
- return;
26
- }
27
-
28
- const express = (await import('express')).default;
29
- const app = express();
30
- app.use(express.json());
31
-
32
- app.post(`/webhook/${this.token}`, async (req, res) => {
33
- try {
34
- const update = req.body;
35
- if (update.message?.text && this.handler) {
36
- const msg: Message = {
37
- id: `tg_${update.message.message_id}`,
38
- role: 'user',
39
- content: update.message.text,
40
- timestamp: update.message.date * 1000,
41
- metadata: {
42
- sessionId: `tg_${update.message.chat.id}`,
43
- chatId: update.message.chat.id,
44
- userId: update.message.from?.id,
45
- platform: 'telegram',
46
- },
47
- };
48
-
49
- const response = await this.handler(msg);
50
- await this.sendMessage(update.message.chat.id, response.content);
51
- }
52
- res.json({ ok: true });
53
- } catch (err) {
54
- console.error('[TelegramChannel] Error handling update:', err);
55
- res.status(500).json({ error: 'Internal error' });
56
- }
57
- });
58
-
59
- app.get('/health', (_req, res) => {
60
- res.json({ status: 'ok', channel: 'telegram' });
61
- });
62
-
63
- return new Promise((resolve) => {
64
- this.server = app.listen(this.port, () => {
65
- console.log(`[TelegramChannel] Webhook server on port ${this.port}`);
66
- resolve();
67
- });
68
- });
69
- }
70
-
71
- async stop(): Promise<void> {
72
- return new Promise((resolve, reject) => {
73
- if (!this.server) return resolve();
74
- this.server.close((err) => (err ? reject(err) : resolve()));
75
- });
76
- }
77
-
78
- private async sendMessage(chatId: number, text: string): Promise<void> {
79
- const url = `https://api.telegram.org/bot${this.token}/sendMessage`;
80
- try {
81
- await fetch(url, {
82
- method: 'POST',
83
- headers: { 'Content-Type': 'application/json' },
84
- body: JSON.stringify({ chat_id: chatId, text, parse_mode: 'Markdown' }),
85
- });
86
- } catch (err) {
87
- console.error('[TelegramChannel] Failed to send message:', err);
88
- }
89
- }
90
- }
1
+ import type { Message } from '../core/types';
2
+ import { BaseChannel } from './index';
3
+
4
+ /**
5
+ * Telegram channel — supports both long-polling and webhook modes.
6
+ *
7
+ * Config:
8
+ * token: bot token (or TELEGRAM_BOT_TOKEN env var)
9
+ * mode: 'polling' | 'webhook' (default: 'polling')
10
+ * webhookUrl: required for webhook mode
11
+ * port: webhook server port (default: 3001)
12
+ *
13
+ * Polling mode requires no public URL — ideal for dev/local.
14
+ * Webhook mode is more efficient for production.
15
+ */
16
+
17
+ export interface TelegramChannelConfig {
18
+ token?: string;
19
+ mode?: 'polling' | 'webhook';
20
+ webhookUrl?: string;
21
+ port?: number;
22
+ }
23
+
24
+ export class TelegramChannel extends BaseChannel {
25
+ readonly type = 'telegram';
26
+ private token: string;
27
+ private mode: 'polling' | 'webhook';
28
+ private webhookUrl?: string;
29
+ private port: number;
30
+
31
+ // Polling state
32
+ private offset: number = 0;
33
+ private polling: boolean = false;
34
+
35
+ // Webhook state
36
+ private server: import('http').Server | null = null;
37
+
38
+ constructor(config: TelegramChannelConfig = {}) {
39
+ super();
40
+ this.token = config.token ?? process.env.TELEGRAM_BOT_TOKEN ?? '';
41
+ this.mode = config.mode ?? 'polling';
42
+ this.webhookUrl = config.webhookUrl;
43
+ this.port = config.port ?? 3001;
44
+ }
45
+
46
+ async start(): Promise<void> {
47
+ if (!this.token) {
48
+ console.warn('[TelegramChannel] No bot token provided. Set TELEGRAM_BOT_TOKEN or pass token in config.');
49
+ return;
50
+ }
51
+
52
+ if (this.mode === 'webhook') {
53
+ await this.startWebhook();
54
+ } else {
55
+ await this.startPolling();
56
+ }
57
+ }
58
+
59
+ async stop(): Promise<void> {
60
+ if (this.mode === 'webhook') {
61
+ await this.stopWebhook();
62
+ } else {
63
+ this.polling = false;
64
+ }
65
+ }
66
+
67
+ // ─── Polling Mode ────────────────────────────────────────
68
+
69
+ private async startPolling(): Promise<void> {
70
+ // Delete any existing webhook so polling works
71
+ await this.apiCall('deleteWebhook');
72
+ console.log(`[TelegramChannel] Started long-polling mode`);
73
+ this.polling = true;
74
+ this.poll();
75
+ }
76
+
77
+ private async poll(): Promise<void> {
78
+ while (this.polling) {
79
+ try {
80
+ const updates = await this.getUpdates();
81
+ for (const update of updates) {
82
+ await this.processUpdate(update);
83
+ }
84
+ } catch (err) {
85
+ console.error('[TelegramChannel] Polling error:', err);
86
+ // Back off on error
87
+ if (this.polling) {
88
+ await new Promise((r) => setTimeout(r, 5000));
89
+ }
90
+ }
91
+ }
92
+ }
93
+
94
+ private async getUpdates(): Promise<any[]> {
95
+ const url = `https://api.telegram.org/bot${this.token}/getUpdates?offset=${this.offset}&timeout=30&allowed_updates=["message"]`;
96
+ const controller = new AbortController();
97
+ const timeout = setTimeout(() => controller.abort(), 40000); // 30s long-poll + 10s buffer
98
+
99
+ try {
100
+ const res = await fetch(url, { signal: controller.signal });
101
+ const data = (await res.json()) as { ok: boolean; result: any[] };
102
+ if (data.ok && data.result.length > 0) {
103
+ this.offset = data.result[data.result.length - 1].update_id + 1;
104
+ }
105
+ return data.result || [];
106
+ } finally {
107
+ clearTimeout(timeout);
108
+ }
109
+ }
110
+
111
+ // ─── Webhook Mode ────────────────────────────────────────
112
+
113
+ private async startWebhook(): Promise<void> {
114
+ if (this.webhookUrl) {
115
+ await this.apiCall('setWebhook', { url: `${this.webhookUrl}/webhook/${this.token}` });
116
+ }
117
+
118
+ const express = (await import('express')).default;
119
+ const app = express();
120
+ app.use(express.json());
121
+
122
+ app.post(`/webhook/${this.token}`, async (req, res) => {
123
+ try {
124
+ await this.processUpdate(req.body);
125
+ res.json({ ok: true });
126
+ } catch (err) {
127
+ console.error('[TelegramChannel] Webhook error:', err);
128
+ res.status(500).json({ error: 'Internal error' });
129
+ }
130
+ });
131
+
132
+ app.get('/health', (_req, res) => {
133
+ res.json({ status: 'ok', channel: 'telegram', mode: 'webhook' });
134
+ });
135
+
136
+ return new Promise((resolve) => {
137
+ this.server = app.listen(this.port, () => {
138
+ console.log(`[TelegramChannel] Webhook server on port ${this.port}`);
139
+ resolve();
140
+ });
141
+ });
142
+ }
143
+
144
+ private async stopWebhook(): Promise<void> {
145
+ return new Promise((resolve, reject) => {
146
+ if (!this.server) return resolve();
147
+ this.server.close((err) => (err ? reject(err) : resolve()));
148
+ });
149
+ }
150
+
151
+ // ─── Shared ──────────────────────────────────────────────
152
+
153
+ private async processUpdate(update: any): Promise<void> {
154
+ const message = update.message || update.edited_message;
155
+ if (!message?.text || !this.handler) return;
156
+
157
+ const msg: Message = {
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
+
173
+ const response = await this.handler(msg);
174
+ await this.sendMessage(message.chat.id, response.content);
175
+ }
176
+
177
+ async sendMessage(chatId: number | string, text: string): Promise<void> {
178
+ // Telegram max message length is 4096
179
+ const chunks = this.splitText(text, 4096);
180
+ for (const chunk of chunks) {
181
+ await this.apiCall('sendMessage', {
182
+ chat_id: chatId,
183
+ text: chunk,
184
+ parse_mode: 'Markdown',
185
+ });
186
+ }
187
+ }
188
+
189
+ private async apiCall(method: string, body?: Record<string, unknown>): Promise<any> {
190
+ const url = `https://api.telegram.org/bot${this.token}/${method}`;
191
+ try {
192
+ const res = await fetch(url, {
193
+ method: 'POST',
194
+ headers: { 'Content-Type': 'application/json' },
195
+ body: body ? JSON.stringify(body) : undefined,
196
+ });
197
+ return await res.json();
198
+ } catch (err) {
199
+ console.error(`[TelegramChannel] API call ${method} failed:`, err);
200
+ throw err;
201
+ }
202
+ }
203
+
204
+ private splitText(text: string, maxLen: number): string[] {
205
+ if (text.length <= maxLen) return [text];
206
+ const parts: string[] = [];
207
+ for (let i = 0; i < text.length; i += maxLen) {
208
+ parts.push(text.slice(i, i + maxLen));
209
+ }
210
+ return parts;
211
+ }
212
+ }