opc-agent 2.0.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 (156) hide show
  1. package/dist/channels/email.d.ts +32 -26
  2. package/dist/channels/email.js +239 -62
  3. package/dist/channels/feishu.d.ts +21 -6
  4. package/dist/channels/feishu.js +225 -126
  5. package/dist/channels/websocket.d.ts +46 -3
  6. package/dist/channels/websocket.js +306 -37
  7. package/dist/channels/wechat.d.ts +33 -13
  8. package/dist/channels/wechat.js +229 -42
  9. package/dist/cli.js +712 -11
  10. package/dist/core/a2a.d.ts +17 -0
  11. package/dist/core/a2a.js +43 -1
  12. package/dist/core/agent.d.ts +16 -0
  13. package/dist/core/agent.js +108 -0
  14. package/dist/core/runtime.d.ts +6 -0
  15. package/dist/core/runtime.js +161 -2
  16. package/dist/core/sandbox.d.ts +26 -0
  17. package/dist/core/sandbox.js +117 -0
  18. package/dist/core/workflow-graph.d.ts +93 -0
  19. package/dist/core/workflow-graph.js +247 -0
  20. package/dist/doctor.d.ts +15 -0
  21. package/dist/doctor.js +183 -0
  22. package/dist/eval/index.d.ts +65 -0
  23. package/dist/eval/index.js +191 -0
  24. package/dist/index.d.ts +30 -6
  25. package/dist/index.js +60 -4
  26. package/dist/plugins/content-filter.d.ts +7 -0
  27. package/dist/plugins/content-filter.js +25 -0
  28. package/dist/plugins/index.d.ts +42 -0
  29. package/dist/plugins/index.js +108 -2
  30. package/dist/plugins/logger.d.ts +6 -0
  31. package/dist/plugins/logger.js +20 -0
  32. package/dist/plugins/rate-limiter.d.ts +7 -0
  33. package/dist/plugins/rate-limiter.js +35 -0
  34. package/dist/protocols/a2a/client.d.ts +25 -0
  35. package/dist/protocols/a2a/client.js +115 -0
  36. package/dist/protocols/a2a/index.d.ts +6 -0
  37. package/dist/protocols/a2a/index.js +12 -0
  38. package/dist/protocols/a2a/server.d.ts +41 -0
  39. package/dist/protocols/a2a/server.js +295 -0
  40. package/dist/protocols/a2a/types.d.ts +91 -0
  41. package/dist/protocols/a2a/types.js +15 -0
  42. package/dist/protocols/a2a/utils.d.ts +6 -0
  43. package/dist/protocols/a2a/utils.js +47 -0
  44. package/dist/protocols/agui/client.d.ts +10 -0
  45. package/dist/protocols/agui/client.js +75 -0
  46. package/dist/protocols/agui/index.d.ts +4 -0
  47. package/dist/protocols/agui/index.js +25 -0
  48. package/dist/protocols/agui/server.d.ts +37 -0
  49. package/dist/protocols/agui/server.js +191 -0
  50. package/dist/protocols/agui/types.d.ts +107 -0
  51. package/dist/protocols/agui/types.js +17 -0
  52. package/dist/protocols/index.d.ts +2 -0
  53. package/dist/protocols/index.js +19 -0
  54. package/dist/protocols/mcp/agent-tools.d.ts +11 -0
  55. package/dist/protocols/mcp/agent-tools.js +129 -0
  56. package/dist/protocols/mcp/index.d.ts +5 -0
  57. package/dist/protocols/mcp/index.js +11 -0
  58. package/dist/protocols/mcp/server.d.ts +31 -0
  59. package/dist/protocols/mcp/server.js +248 -0
  60. package/dist/protocols/mcp/types.d.ts +92 -0
  61. package/dist/protocols/mcp/types.js +17 -0
  62. package/dist/publish/index.d.ts +45 -0
  63. package/dist/publish/index.js +350 -0
  64. package/dist/schema/oad.d.ts +682 -65
  65. package/dist/schema/oad.js +36 -3
  66. package/dist/security/approval.d.ts +36 -0
  67. package/dist/security/approval.js +113 -0
  68. package/dist/security/index.d.ts +4 -0
  69. package/dist/security/index.js +8 -0
  70. package/dist/security/keys.d.ts +16 -0
  71. package/dist/security/keys.js +117 -0
  72. package/dist/studio/server.d.ts +63 -0
  73. package/dist/studio/server.js +625 -0
  74. package/dist/studio-ui/index.html +662 -0
  75. package/dist/telemetry/index.d.ts +93 -0
  76. package/dist/telemetry/index.js +285 -0
  77. package/package.json +5 -3
  78. package/scripts/install.ps1 +31 -0
  79. package/scripts/install.sh +40 -0
  80. package/src/channels/email.ts +351 -177
  81. package/src/channels/feishu.ts +349 -236
  82. package/src/channels/websocket.ts +399 -87
  83. package/src/channels/wechat.ts +329 -149
  84. package/src/cli.ts +783 -12
  85. package/src/core/a2a.ts +60 -0
  86. package/src/core/agent.ts +125 -0
  87. package/src/core/runtime.ts +127 -0
  88. package/src/core/sandbox.ts +143 -0
  89. package/src/core/workflow-graph.ts +365 -0
  90. package/src/doctor.ts +156 -0
  91. package/src/eval/index.ts +211 -0
  92. package/src/eval/suites/basic.json +16 -0
  93. package/src/eval/suites/memory.json +12 -0
  94. package/src/eval/suites/safety.json +14 -0
  95. package/src/index.ts +54 -6
  96. package/src/plugins/content-filter.ts +23 -0
  97. package/src/plugins/index.ts +133 -2
  98. package/src/plugins/logger.ts +18 -0
  99. package/src/plugins/rate-limiter.ts +38 -0
  100. package/src/protocols/a2a/client.ts +132 -0
  101. package/src/protocols/a2a/index.ts +8 -0
  102. package/src/protocols/a2a/server.ts +333 -0
  103. package/src/protocols/a2a/types.ts +88 -0
  104. package/src/protocols/a2a/utils.ts +50 -0
  105. package/src/protocols/agui/client.ts +83 -0
  106. package/src/protocols/agui/index.ts +4 -0
  107. package/src/protocols/agui/server.ts +218 -0
  108. package/src/protocols/agui/types.ts +153 -0
  109. package/src/protocols/index.ts +2 -0
  110. package/src/protocols/mcp/agent-tools.ts +134 -0
  111. package/src/protocols/mcp/index.ts +8 -0
  112. package/src/protocols/mcp/server.ts +262 -0
  113. package/src/protocols/mcp/types.ts +69 -0
  114. package/src/publish/index.ts +376 -0
  115. package/src/schema/oad.ts +39 -2
  116. package/src/security/approval.ts +131 -0
  117. package/src/security/index.ts +3 -0
  118. package/src/security/keys.ts +87 -0
  119. package/src/studio/server.ts +629 -0
  120. package/src/studio-ui/index.html +662 -0
  121. package/src/telemetry/index.ts +324 -0
  122. package/src/types/agent-workstation.d.ts +2 -0
  123. package/tests/a2a-protocol.test.ts +285 -0
  124. package/tests/agui-protocol.test.ts +246 -0
  125. package/tests/channels/discord.test.ts +79 -0
  126. package/tests/channels/email.test.ts +148 -0
  127. package/tests/channels/feishu.test.ts +123 -0
  128. package/tests/channels/telegram.test.ts +129 -0
  129. package/tests/channels/websocket.test.ts +53 -0
  130. package/tests/channels/wechat.test.ts +170 -0
  131. package/tests/chat-cli.test.ts +160 -0
  132. package/tests/daemon.test.ts +135 -0
  133. package/tests/deepbrain-wire.test.ts +234 -0
  134. package/tests/doctor.test.ts +38 -0
  135. package/tests/eval.test.ts +173 -0
  136. package/tests/init-role.test.ts +124 -0
  137. package/tests/mcp-client.test.ts +92 -0
  138. package/tests/mcp-server.test.ts +178 -0
  139. package/tests/plugin-a2a-enhanced.test.ts +230 -0
  140. package/tests/publish.test.ts +231 -0
  141. package/tests/scheduler.test.ts +200 -0
  142. package/tests/security-enhanced.test.ts +233 -0
  143. package/tests/skill-learner.test.ts +161 -0
  144. package/tests/studio.test.ts +229 -0
  145. package/tests/subagent.test.ts +63 -0
  146. package/tests/telemetry.test.ts +186 -0
  147. package/tests/tools/builtin-extended.test.ts +138 -0
  148. package/tests/workflow-graph.test.ts +279 -0
  149. package/tutorial/customer-service-agent/README.md +612 -0
  150. package/tutorial/customer-service-agent/SOUL.md +26 -0
  151. package/tutorial/customer-service-agent/agent.yaml +63 -0
  152. package/tutorial/customer-service-agent/package.json +19 -0
  153. package/tutorial/customer-service-agent/src/index.ts +69 -0
  154. package/tutorial/customer-service-agent/src/skills/faq.ts +27 -0
  155. package/tutorial/customer-service-agent/src/skills/ticket.ts +22 -0
  156. package/tutorial/customer-service-agent/tsconfig.json +14 -0
@@ -1,6 +1,23 @@
1
1
  import { EventEmitter } from 'events';
2
2
  import { Room } from './room';
3
3
  import type { IAgent } from './types';
4
+ export interface AgentCard {
5
+ name: string;
6
+ description: string;
7
+ capabilities: string[];
8
+ endpoint?: string;
9
+ handler?: (message: string) => Promise<string>;
10
+ }
11
+ export declare class AgentCardRegistry {
12
+ private cards;
13
+ private logger;
14
+ register(card: AgentCard): void;
15
+ unregister(name: string): void;
16
+ get(name: string): AgentCard | undefined;
17
+ find(query: string): AgentCard[];
18
+ send(agentName: string, message: string): Promise<string>;
19
+ list(): AgentCard[];
20
+ }
4
21
  export interface AgentCapability {
5
22
  name: string;
6
23
  description: string;
package/dist/core/a2a.js CHANGED
@@ -1,9 +1,51 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.AgentRegistry = void 0;
3
+ exports.AgentRegistry = exports.AgentCardRegistry = void 0;
4
4
  const events_1 = require("events");
5
5
  const room_1 = require("./room");
6
6
  const logger_1 = require("./logger");
7
+ class AgentCardRegistry {
8
+ cards = new Map();
9
+ logger = new logger_1.Logger('a2a:cards');
10
+ register(card) {
11
+ this.cards.set(card.name, card);
12
+ this.logger.info('AgentCard registered', { name: card.name });
13
+ }
14
+ unregister(name) {
15
+ this.cards.delete(name);
16
+ }
17
+ get(name) {
18
+ return this.cards.get(name);
19
+ }
20
+ find(query) {
21
+ const lower = query.toLowerCase();
22
+ return Array.from(this.cards.values()).filter(a => a.name.toLowerCase().includes(lower) ||
23
+ a.description.toLowerCase().includes(lower) ||
24
+ a.capabilities.some(c => c.toLowerCase().includes(lower)));
25
+ }
26
+ async send(agentName, message) {
27
+ const agent = this.cards.get(agentName);
28
+ if (!agent)
29
+ throw new Error(`Agent '${agentName}' not found`);
30
+ if (agent.handler) {
31
+ return agent.handler(message);
32
+ }
33
+ else if (agent.endpoint) {
34
+ const res = await fetch(agent.endpoint, {
35
+ method: 'POST',
36
+ headers: { 'Content-Type': 'application/json' },
37
+ body: JSON.stringify({ message }),
38
+ });
39
+ const data = await res.json();
40
+ return data.response || data.content || '';
41
+ }
42
+ throw new Error(`Agent '${agentName}' has no handler or endpoint`);
43
+ }
44
+ list() {
45
+ return Array.from(this.cards.values());
46
+ }
47
+ }
48
+ exports.AgentCardRegistry = AgentCardRegistry;
7
49
  // ── Agent Registry ──────────────────────────────────────────
8
50
  class AgentRegistry extends events_1.EventEmitter {
9
51
  registrations = new Map();
@@ -5,6 +5,7 @@ import { SkillLearner } from '../skills/auto-learn';
5
5
  import type { MCPTool } from '../tools/mcp';
6
6
  import { MCPToolRegistry } from '../tools/mcp';
7
7
  import { type SubAgentConfig, type SubAgentResult } from './subagent';
8
+ import { Tracer } from '../telemetry';
8
9
  export declare class BaseAgent extends EventEmitter implements IAgent {
9
10
  readonly name: string;
10
11
  private _state;
@@ -19,6 +20,9 @@ export declare class BaseAgent extends EventEmitter implements IAgent {
19
20
  private skillLearner?;
20
21
  private autoLearnConfig;
21
22
  private _subAgentManager?;
23
+ private longTermMemory?;
24
+ private longTermMemoryConfig;
25
+ private tracer?;
22
26
  constructor(options: {
23
27
  name: string;
24
28
  systemPrompt?: string;
@@ -33,13 +37,25 @@ export declare class BaseAgent extends EventEmitter implements IAgent {
33
37
  improveOnUse?: boolean;
34
38
  };
35
39
  maxToolRounds?: number;
40
+ tracer?: Tracer;
36
41
  });
42
+ setLongTermMemory(brain: any, config?: {
43
+ autoLearn?: boolean;
44
+ autoRecall?: boolean;
45
+ }): void;
46
+ getLongTermMemory(): any;
47
+ getLongTermMemoryConfig(): {
48
+ autoLearn: boolean;
49
+ autoRecall: boolean;
50
+ };
37
51
  get state(): AgentState;
38
52
  get provider(): LLMProvider;
39
53
  getSystemPrompt(): string;
40
54
  getMemory(): MemoryStore;
41
55
  getSkillLearner(): SkillLearner | undefined;
42
56
  getToolRegistry(): MCPToolRegistry;
57
+ getTracer(): Tracer | undefined;
58
+ setTracer(tracer: Tracer): void;
43
59
  registerTool(tool: MCPTool): void;
44
60
  private transition;
45
61
  init(): Promise<void>;
@@ -21,6 +21,9 @@ class BaseAgent extends events_1.EventEmitter {
21
21
  skillLearner;
22
22
  autoLearnConfig;
23
23
  _subAgentManager;
24
+ longTermMemory;
25
+ longTermMemoryConfig = { autoLearn: true, autoRecall: true };
26
+ tracer;
24
27
  constructor(options) {
25
28
  super();
26
29
  this.name = options.name;
@@ -37,6 +40,22 @@ class BaseAgent extends events_1.EventEmitter {
37
40
  if (options.skillsDir) {
38
41
  this.skillLearner = new auto_learn_1.SkillLearner(options.skillsDir);
39
42
  }
43
+ this.tracer = options.tracer;
44
+ }
45
+ setLongTermMemory(brain, config) {
46
+ this.longTermMemory = brain;
47
+ if (config) {
48
+ this.longTermMemoryConfig = {
49
+ autoLearn: config.autoLearn !== false,
50
+ autoRecall: config.autoRecall !== false,
51
+ };
52
+ }
53
+ }
54
+ getLongTermMemory() {
55
+ return this.longTermMemory;
56
+ }
57
+ getLongTermMemoryConfig() {
58
+ return this.longTermMemoryConfig;
40
59
  }
41
60
  get state() {
42
61
  return this._state;
@@ -56,6 +75,12 @@ class BaseAgent extends events_1.EventEmitter {
56
75
  getToolRegistry() {
57
76
  return this.toolRegistry;
58
77
  }
78
+ getTracer() {
79
+ return this.tracer;
80
+ }
81
+ setTracer(tracer) {
82
+ this.tracer = tracer;
83
+ }
59
84
  registerTool(tool) {
60
85
  this.toolRegistry.register(tool);
61
86
  }
@@ -109,8 +134,45 @@ class BaseAgent extends events_1.EventEmitter {
109
134
  }
110
135
  async handleMessage(message) {
111
136
  this.emit('message:in', message);
137
+ // Start root span if tracer is configured
138
+ let rootSpan;
139
+ if (this.tracer) {
140
+ rootSpan = this.tracer.startSpan('handleMessage', {
141
+ kind: 'server',
142
+ attributes: {
143
+ 'message.channel': message.metadata?.channel || 'unknown',
144
+ 'message.sender': message.metadata?.sender || 'unknown',
145
+ 'message.length': message.content.length,
146
+ },
147
+ });
148
+ this.tracer.increment('agent.messages.total', 1, { agent: this.name });
149
+ }
112
150
  const sessionId = message.metadata?.sessionId ?? 'default';
113
151
  await this.memory.addMessage(sessionId, message);
152
+ // === Recall from long-term memory ===
153
+ let memoryContext = '';
154
+ if (this.longTermMemory && this.longTermMemoryConfig.autoRecall) {
155
+ let memorySpan;
156
+ if (this.tracer && rootSpan) {
157
+ memorySpan = this.tracer.startSpan('memory.recall', { parent: rootSpan, kind: 'client' });
158
+ }
159
+ try {
160
+ const recalled = await this.longTermMemory.recall(message.content);
161
+ if (recalled && (Array.isArray(recalled) ? recalled.length > 0 : true)) {
162
+ memoryContext = '\n\n[Relevant memories]\n' +
163
+ (Array.isArray(recalled)
164
+ ? recalled.map((r) => typeof r === 'string' ? r : r.content || r.compiled_truth || '').join('\n')
165
+ : String(recalled));
166
+ }
167
+ if (this.tracer && memorySpan)
168
+ this.tracer.endSpan(memorySpan, 'ok');
169
+ }
170
+ catch {
171
+ if (this.tracer && memorySpan)
172
+ this.tracer.endSpan(memorySpan, 'error');
173
+ // Silent fail — don't break chat if memory fails
174
+ }
175
+ }
114
176
  const context = {
115
177
  agentName: this.name,
116
178
  sessionId,
@@ -136,27 +198,58 @@ class BaseAgent extends events_1.EventEmitter {
136
198
  }
137
199
  // Check if a learned skill matches — prepend instructions to system prompt
138
200
  let effectiveSystemPrompt = this.systemPrompt;
201
+ // Inject long-term memory context
202
+ if (memoryContext) {
203
+ effectiveSystemPrompt = effectiveSystemPrompt + memoryContext;
204
+ }
139
205
  const matchedSkill = this.skillLearner?.matchSkill(message.content);
140
206
  if (matchedSkill) {
141
207
  matchedSkill.usageCount++;
142
208
  matchedSkill.lastUsed = new Date();
143
209
  effectiveSystemPrompt = `[Learned Skill: ${matchedSkill.name}]\n${matchedSkill.instructions}\n\n${this.systemPrompt}`;
144
210
  this.emit('skill:matched', matchedSkill);
211
+ if (this.tracer && rootSpan) {
212
+ this.tracer.addEvent(rootSpan, 'skill.matched', { 'skill.name': matchedSkill.name });
213
+ }
145
214
  }
146
215
  // Fall back to LLM with tool use loop
147
216
  const tools = this.toolRegistry.list();
148
217
  const llmMessages = [...context.messages];
149
218
  let finalResponse = '';
150
219
  for (let round = 0; round <= this.maxToolRounds; round++) {
220
+ let llmSpan;
221
+ if (this.tracer && rootSpan) {
222
+ llmSpan = this.tracer.startSpan('llm.chat', {
223
+ parent: rootSpan,
224
+ kind: 'client',
225
+ attributes: { 'llm.round': round },
226
+ });
227
+ }
151
228
  const llmResponse = await this._provider.chat(llmMessages, effectiveSystemPrompt, { tools: tools.length > 0 ? tools : undefined });
229
+ if (this.tracer && llmSpan) {
230
+ llmSpan.attributes['llm.response.length'] = llmResponse.length;
231
+ this.tracer.endSpan(llmSpan, 'ok');
232
+ }
152
233
  const toolCall = this.parseToolCall(llmResponse);
153
234
  if (!toolCall || tools.length === 0 || round === this.maxToolRounds) {
154
235
  finalResponse = llmResponse;
155
236
  break;
156
237
  }
157
238
  // Execute tool
239
+ let toolSpan;
240
+ if (this.tracer && rootSpan) {
241
+ toolSpan = this.tracer.startSpan('tool.execute', {
242
+ parent: rootSpan,
243
+ kind: 'internal',
244
+ attributes: { 'tool.name': toolCall.name },
245
+ });
246
+ }
158
247
  const toolResult = await this.toolRegistry.execute(toolCall.name, toolCall.arguments, context);
159
248
  this.emit('tool:execute', toolCall.name, toolResult);
249
+ if (this.tracer && toolSpan) {
250
+ toolSpan.attributes['tool.result.length'] = toolResult.content?.length || 0;
251
+ this.tracer.endSpan(toolSpan, 'ok');
252
+ }
160
253
  // Add tool call and result to messages for next round
161
254
  llmMessages.push({
162
255
  id: `tool_call_${Date.now()}`,
@@ -174,6 +267,21 @@ class BaseAgent extends events_1.EventEmitter {
174
267
  const response = this.createResponse(finalResponse, message);
175
268
  await this.memory.addMessage(sessionId, response);
176
269
  this.emit('message:out', response);
270
+ // End root telemetry span
271
+ if (this.tracer && rootSpan) {
272
+ rootSpan.attributes['response.length'] = finalResponse.length;
273
+ this.tracer.endSpan(rootSpan, 'ok');
274
+ this.tracer.histogram('agent.message.duration', rootSpan.endTime - rootSpan.startTime, { agent: this.name });
275
+ }
276
+ // === Learn from interaction ===
277
+ if (this.longTermMemory && this.longTermMemoryConfig.autoLearn) {
278
+ try {
279
+ await this.longTermMemory.learn(`User: ${message.content}\nAssistant: ${finalResponse}`, { tags: ['conversation', message.metadata?.channel || 'unknown'] });
280
+ }
281
+ catch {
282
+ // Silent fail
283
+ }
284
+ }
177
285
  // After response, check if we should learn a skill
178
286
  if (this.skillLearner &&
179
287
  this.autoLearnConfig.enabled &&
@@ -1,3 +1,4 @@
1
+ import { PluginManager } from '../plugins';
1
2
  import { BaseAgent } from './agent';
2
3
  import { Analytics } from '../analytics';
3
4
  import type { OADDocument } from '../schema/oad';
@@ -12,6 +13,10 @@ export declare class AgentRuntime {
12
13
  private isShuttingDown;
13
14
  private analytics;
14
15
  private scheduler;
16
+ private pluginManager;
17
+ private brain;
18
+ private agentBrain;
19
+ private evolveScheduler;
15
20
  loadConfig(filePath: string): Promise<OADDocument>;
16
21
  setHistoryLimit(limit: number): void;
17
22
  initialize(config?: OADDocument): Promise<BaseAgent>;
@@ -23,5 +28,6 @@ export declare class AgentRuntime {
23
28
  getAgent(): BaseAgent | null;
24
29
  getAnalytics(): Analytics;
25
30
  getConfig(): OADDocument | null;
31
+ getPluginManager(): PluginManager;
26
32
  }
27
33
  //# sourceMappingURL=runtime.d.ts.map
@@ -1,13 +1,53 @@
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.AgentRuntime = void 0;
4
37
  exports.truncateOutput = truncateOutput;
38
+ const plugins_1 = require("../plugins");
39
+ const logger_1 = require("../plugins/logger");
40
+ const rate_limiter_1 = require("../plugins/rate-limiter");
41
+ const content_filter_1 = require("../plugins/content-filter");
5
42
  const agent_1 = require("./agent");
6
43
  const config_1 = require("./config");
7
- const logger_1 = require("./logger");
44
+ const logger_2 = require("./logger");
8
45
  const web_1 = require("../channels/web");
9
46
  const telegram_1 = require("../channels/telegram");
10
47
  const websocket_1 = require("../channels/websocket");
48
+ const wechat_1 = require("../channels/wechat");
49
+ const feishu_1 = require("../channels/feishu");
50
+ const email_1 = require("../channels/email");
11
51
  const deepbrain_1 = require("../memory/deepbrain");
12
52
  const analytics_1 = require("../analytics");
13
53
  const scheduler_1 = require("./scheduler");
@@ -22,12 +62,16 @@ function truncateOutput(output, maxChars = MAX_TOOL_OUTPUT) {
22
62
  class AgentRuntime {
23
63
  agent = null;
24
64
  config = null;
25
- logger = new logger_1.Logger('runtime');
65
+ logger = new logger_2.Logger('runtime');
26
66
  historyLimit = DEFAULT_HISTORY_LIMIT;
27
67
  shutdownHandlers = [];
28
68
  isShuttingDown = false;
29
69
  analytics = new analytics_1.Analytics();
30
70
  scheduler = null;
71
+ pluginManager = new plugins_1.PluginManager();
72
+ brain = null;
73
+ agentBrain = null;
74
+ evolveScheduler = null;
31
75
  async loadConfig(filePath) {
32
76
  this.config = (0, config_1.loadOAD)(filePath);
33
77
  this.logger.info('Config loaded', { name: this.config.metadata.name });
@@ -105,8 +149,88 @@ class AgentRuntime {
105
149
  this.agent.bindChannel(new websocket_1.WebSocketChannel(ch.port ?? 3002));
106
150
  this.logger.info('Bound websocket channel', { port: ch.port ?? 3002 });
107
151
  }
152
+ else if (ch.type === 'wechat') {
153
+ this.agent.bindChannel(new wechat_1.WeChatChannel({
154
+ appId: ch.config?.appId ?? process.env.WECHAT_APP_ID ?? '',
155
+ appSecret: ch.config?.appSecret ?? process.env.WECHAT_APP_SECRET ?? '',
156
+ token: ch.config?.token ?? process.env.WECHAT_TOKEN ?? '',
157
+ encodingAESKey: ch.config?.encodingAESKey,
158
+ port: ch.port,
159
+ }));
160
+ this.logger.info('Bound wechat channel', { port: ch.port ?? 8080 });
161
+ }
162
+ else if (ch.type === 'feishu') {
163
+ this.agent.bindChannel(new feishu_1.FeishuChannel({
164
+ appId: ch.config?.appId ?? process.env.FEISHU_APP_ID,
165
+ appSecret: ch.config?.appSecret ?? process.env.FEISHU_APP_SECRET,
166
+ verificationToken: ch.config?.verificationToken ?? process.env.FEISHU_VERIFICATION_TOKEN,
167
+ encryptKey: ch.config?.encryptKey,
168
+ port: ch.port,
169
+ }));
170
+ this.logger.info('Bound feishu channel', { port: ch.port ?? 8081 });
171
+ }
172
+ else if (ch.type === 'email') {
173
+ this.agent.bindChannel(new email_1.EmailChannel({
174
+ mode: ch.config?.mode ?? 'webhook',
175
+ smtp: ch.config?.smtp,
176
+ imap: ch.config?.imap,
177
+ webhookPort: ch.port,
178
+ filters: ch.config?.filters,
179
+ }));
180
+ this.logger.info('Bound email channel', { mode: ch.config?.mode ?? 'webhook', port: ch.port ?? 8082 });
181
+ }
108
182
  }
109
183
  await this.agent.init();
184
+ // === Auto-wire DeepBrain long-term memory (Brain/AgentBrain) ===
185
+ const longTermCfg = memCfg && typeof memCfg.longTerm === 'object' ? memCfg.longTerm : null;
186
+ if (longTermCfg?.provider === 'deepbrain') {
187
+ try {
188
+ const deepbrainModule = await Promise.resolve().then(() => __importStar(require(/* webpackIgnore: true */ 'deepbrain')));
189
+ const BrainClass = deepbrainModule.Brain ?? deepbrainModule.default?.Brain;
190
+ const AgentBrainClass = deepbrainModule.AgentBrain ?? deepbrainModule.default?.AgentBrain;
191
+ if (BrainClass && AgentBrainClass) {
192
+ const dbConfig = longTermCfg.config ?? {};
193
+ const dbPath = dbConfig.database || './data/brain.db';
194
+ const embeddingProvider = dbConfig.embeddingProvider || 'ollama';
195
+ this.brain = new BrainClass({
196
+ database: dbPath,
197
+ embedding_provider: embeddingProvider,
198
+ });
199
+ await this.brain.connect();
200
+ this.agentBrain = new AgentBrainClass(this.brain, cfg.metadata.name);
201
+ this.agent.setLongTermMemory(this.agentBrain, {
202
+ autoLearn: dbConfig.autoLearn !== false,
203
+ autoRecall: dbConfig.autoRecall !== false,
204
+ });
205
+ this.logger.info('DeepBrain Brain/AgentBrain connected', { database: dbPath });
206
+ // Brain seed loading
207
+ const { existsSync, readFileSync, renameSync } = await Promise.resolve().then(() => __importStar(require('fs')));
208
+ const seedPath = './data/brain-seed.md';
209
+ if (existsSync(seedPath)) {
210
+ const seed = readFileSync(seedPath, 'utf-8');
211
+ await this.brain.put('brain-seed', seed, { type: 'seed', tags: ['seed', 'initial'] });
212
+ renameSync(seedPath, './data/brain-seed.loaded.md');
213
+ this.logger.info('Brain seed loaded');
214
+ }
215
+ // Auto-evolve scheduling
216
+ const evolveInterval = dbConfig.evolveInterval;
217
+ if (evolveInterval && evolveInterval > 0) {
218
+ const AutoEvolveSchedulerClass = deepbrainModule.AutoEvolveScheduler ?? deepbrainModule.default?.AutoEvolveScheduler;
219
+ if (AutoEvolveSchedulerClass) {
220
+ this.evolveScheduler = new AutoEvolveSchedulerClass();
221
+ this.evolveScheduler.start(this.agentBrain, evolveInterval);
222
+ this.logger.info('DeepBrain auto-evolve scheduled', { interval: evolveInterval });
223
+ }
224
+ }
225
+ }
226
+ else {
227
+ this.logger.warn('DeepBrain module found but Brain/AgentBrain classes not available');
228
+ }
229
+ }
230
+ catch (e) {
231
+ this.logger.warn('DeepBrain not available (install with: npm install deepbrain)', { error: e.message });
232
+ }
233
+ }
110
234
  // Wire analytics to agent events
111
235
  this.agent.on('message:out', () => {
112
236
  // responseTime is approximated; real timing is done via skill/llm events
@@ -118,6 +242,23 @@ class AgentRuntime {
118
242
  this.analytics.recordError();
119
243
  });
120
244
  this.logger.info('Agent initialized', { name: cfg.metadata.name });
245
+ // Load enhanced plugins from OAD config
246
+ const pluginsCfg = cfg.spec.plugins;
247
+ if (pluginsCfg && Array.isArray(pluginsCfg)) {
248
+ const builtinPlugins = {
249
+ 'logger': () => logger_1.loggerPlugin,
250
+ 'rate-limiter': (c) => (0, rate_limiter_1.createRateLimiterPlugin)(c?.maxPerMinute ?? 60),
251
+ 'content-filter': (c) => (0, content_filter_1.createContentFilterPlugin)(c?.blocklist ?? []),
252
+ };
253
+ for (const entry of pluginsCfg) {
254
+ const factory = builtinPlugins[entry.name];
255
+ if (factory) {
256
+ this.pluginManager.registerEnhanced(factory(entry.config));
257
+ this.logger.info('Enhanced plugin loaded from config', { name: entry.name });
258
+ }
259
+ }
260
+ }
261
+ await this.pluginManager.initAll(this);
121
262
  // Initialize scheduler if jobs are configured
122
263
  const schedulerCfg = cfg.spec.scheduler;
123
264
  if (schedulerCfg?.jobs && Array.isArray(schedulerCfg.jobs) && schedulerCfg.jobs.length > 0) {
@@ -169,10 +310,25 @@ class AgentRuntime {
169
310
  if (!this.agent)
170
311
  return;
171
312
  this.logger.info('Stopping agent...');
313
+ if (this.evolveScheduler) {
314
+ try {
315
+ this.evolveScheduler.stop();
316
+ }
317
+ catch { /* ignore */ }
318
+ this.logger.info('DeepBrain auto-evolve stopped');
319
+ }
320
+ if (this.brain) {
321
+ try {
322
+ await this.brain.disconnect();
323
+ this.logger.info('DeepBrain disconnected');
324
+ }
325
+ catch { /* ignore */ }
326
+ }
172
327
  if (this.scheduler) {
173
328
  this.scheduler.stop();
174
329
  this.logger.info('Scheduler stopped');
175
330
  }
331
+ await this.pluginManager.shutdownAll();
176
332
  await this.agent.stop();
177
333
  for (const handler of this.shutdownHandlers) {
178
334
  await handler();
@@ -213,6 +369,9 @@ class AgentRuntime {
213
369
  getConfig() {
214
370
  return this.config;
215
371
  }
372
+ getPluginManager() {
373
+ return this.pluginManager;
374
+ }
216
375
  }
217
376
  exports.AgentRuntime = AgentRuntime;
218
377
  //# sourceMappingURL=runtime.js.map
@@ -4,6 +4,22 @@ export interface SandboxConfig {
4
4
  agentDir: string;
5
5
  networkAllowlist?: string[];
6
6
  shellAllowed?: boolean;
7
+ allowedCommands?: string[];
8
+ blockedCommands?: string[];
9
+ maxFileSize?: number;
10
+ maxFiles?: number;
11
+ networkAccess?: boolean;
12
+ readOnlyPaths?: string[];
13
+ timeout?: number;
14
+ }
15
+ export interface ValidationResult {
16
+ allowed: boolean;
17
+ reason?: string;
18
+ }
19
+ export interface SandboxStatus {
20
+ files: number;
21
+ totalSize: number;
22
+ violations: number;
7
23
  }
8
24
  export interface SandboxRestrictions {
9
25
  fileSystem: {
@@ -18,11 +34,21 @@ export interface SandboxRestrictions {
18
34
  export declare class Sandbox {
19
35
  private config;
20
36
  private restrictions;
37
+ private violations;
38
+ private maxFileSize;
39
+ private maxFiles;
21
40
  constructor(config: SandboxConfig);
22
41
  get trustLevel(): TrustLevelType;
23
42
  getRestrictions(): SandboxRestrictions;
24
43
  checkFileAccess(filePath: string, mode: 'read' | 'write'): boolean;
25
44
  checkNetworkAccess(url: string): boolean;
26
45
  checkShellAccess(): boolean;
46
+ validateFileOp(action: 'read' | 'write' | 'delete', filePath: string): ValidationResult;
47
+ validateCommand(command: string): ValidationResult;
48
+ validateNetwork(url: string): ValidationResult;
49
+ getStatus(): SandboxStatus;
50
+ getViolations(): number;
51
+ getMaxFileSize(): number;
52
+ getMaxFiles(): number;
27
53
  }
28
54
  //# sourceMappingURL=sandbox.d.ts.map