opc-agent 1.4.0 → 1.4.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 (192) hide show
  1. package/CHANGELOG.md +69 -23
  2. package/CONTRIBUTING.md +60 -21
  3. package/README.md +358 -235
  4. package/README.zh-CN.md +415 -415
  5. package/dist/channels/slack.js +10 -93
  6. package/dist/channels/web.d.ts +0 -10
  7. package/dist/channels/web.js +2 -33
  8. package/dist/cli.js +60 -255
  9. package/dist/core/dashboard.d.ts +35 -0
  10. package/dist/core/dashboard.js +157 -0
  11. package/dist/core/fast-mode.d.ts +27 -0
  12. package/dist/core/fast-mode.js +59 -0
  13. package/dist/core/priority.d.ts +52 -0
  14. package/dist/core/priority.js +102 -0
  15. package/dist/core/runtime.d.ts +0 -4
  16. package/dist/core/runtime.js +0 -27
  17. package/dist/deploy/hermes.js +22 -22
  18. package/dist/deploy/openclaw.js +40 -31
  19. package/dist/index.d.ts +14 -3
  20. package/dist/index.js +20 -6
  21. package/dist/memory/cloud-storage.d.ts +40 -0
  22. package/dist/memory/cloud-storage.js +211 -0
  23. package/dist/providers/index.d.ts +1 -1
  24. package/dist/providers/index.js +1 -7
  25. package/dist/schema/oad.d.ts +2 -1
  26. package/dist/templates/code-reviewer.d.ts +8 -0
  27. package/dist/templates/code-reviewer.js +9 -5
  28. package/dist/templates/customer-service.d.ts +8 -0
  29. package/dist/templates/customer-service.js +6 -2
  30. package/dist/templates/data-analyst.d.ts +8 -0
  31. package/dist/templates/data-analyst.js +9 -5
  32. package/dist/templates/knowledge-base.d.ts +8 -0
  33. package/dist/templates/knowledge-base.js +6 -2
  34. package/dist/templates/sales-assistant.d.ts +8 -0
  35. package/dist/templates/sales-assistant.js +8 -4
  36. package/dist/templates/teacher.d.ts +8 -0
  37. package/dist/templates/teacher.js +10 -6
  38. package/docs/.vitepress/config.ts +103 -103
  39. package/docs/api/cli.md +48 -48
  40. package/docs/api/oad-schema.md +64 -64
  41. package/docs/api/sdk.md +80 -80
  42. package/docs/guide/concepts.md +51 -51
  43. package/docs/guide/configuration.md +79 -79
  44. package/docs/guide/deployment.md +42 -42
  45. package/docs/guide/getting-started.md +44 -44
  46. package/docs/guide/templates.md +28 -28
  47. package/docs/guide/testing.md +84 -84
  48. package/docs/index.md +27 -27
  49. package/docs/zh/api/cli.md +54 -54
  50. package/docs/zh/api/oad-schema.md +87 -87
  51. package/docs/zh/api/sdk.md +102 -102
  52. package/docs/zh/guide/concepts.md +104 -104
  53. package/docs/zh/guide/configuration.md +135 -135
  54. package/docs/zh/guide/deployment.md +81 -81
  55. package/docs/zh/guide/getting-started.md +82 -82
  56. package/docs/zh/guide/templates.md +84 -84
  57. package/docs/zh/guide/testing.md +88 -88
  58. package/docs/zh/index.md +27 -27
  59. package/examples/customer-service-demo/README.md +90 -90
  60. package/examples/customer-service-demo/oad.yaml +107 -107
  61. package/package.json +1 -1
  62. package/src/analytics/index.ts +66 -66
  63. package/src/channels/discord.ts +192 -192
  64. package/src/channels/email.ts +177 -177
  65. package/src/channels/feishu.ts +236 -236
  66. package/src/channels/index.ts +15 -15
  67. package/src/channels/slack.ts +160 -217
  68. package/src/channels/telegram.ts +90 -90
  69. package/src/channels/voice.ts +106 -106
  70. package/src/channels/web.ts +2 -38
  71. package/src/channels/webhook.ts +199 -199
  72. package/src/channels/websocket.ts +87 -87
  73. package/src/channels/wechat.ts +149 -149
  74. package/src/cli.ts +58 -282
  75. package/src/core/a2a.ts +143 -143
  76. package/src/core/agent.ts +152 -152
  77. package/src/core/analytics-engine.ts +186 -186
  78. package/src/core/auth.ts +57 -57
  79. package/src/core/cache.ts +141 -141
  80. package/src/core/compose.ts +77 -77
  81. package/src/core/config.ts +14 -14
  82. package/src/core/dashboard.ts +219 -0
  83. package/src/core/errors.ts +148 -148
  84. package/src/core/fast-mode.ts +75 -0
  85. package/src/core/hitl.ts +138 -138
  86. package/src/core/logger.ts +57 -57
  87. package/src/core/orchestrator.ts +215 -215
  88. package/src/core/performance.ts +187 -187
  89. package/src/core/priority.ts +140 -0
  90. package/src/core/rate-limiter.ts +128 -128
  91. package/src/core/room.ts +109 -109
  92. package/src/core/runtime.ts +152 -183
  93. package/src/core/sandbox.ts +101 -101
  94. package/src/core/security.ts +171 -171
  95. package/src/core/types.ts +68 -68
  96. package/src/core/versioning.ts +106 -106
  97. package/src/core/watch.ts +178 -178
  98. package/src/core/workflow.ts +235 -235
  99. package/src/deploy/hermes.ts +156 -156
  100. package/src/deploy/openclaw.ts +200 -190
  101. package/src/dtv/data.ts +29 -0
  102. package/src/dtv/trust.ts +43 -0
  103. package/src/dtv/value.ts +47 -0
  104. package/src/i18n/index.ts +216 -216
  105. package/src/index.ts +16 -3
  106. package/src/marketplace/index.ts +223 -0
  107. package/src/memory/cloud-storage.ts +217 -0
  108. package/src/memory/deepbrain.ts +108 -108
  109. package/src/memory/index.ts +34 -34
  110. package/src/plugins/index.ts +208 -208
  111. package/src/providers/index.ts +1 -9
  112. package/src/schema/oad.ts +155 -154
  113. package/src/skills/base.ts +16 -16
  114. package/src/skills/document.ts +100 -100
  115. package/src/skills/http.ts +35 -35
  116. package/src/skills/index.ts +27 -27
  117. package/src/skills/scheduler.ts +80 -80
  118. package/src/skills/webhook-trigger.ts +59 -59
  119. package/src/templates/code-reviewer.ts +34 -30
  120. package/src/templates/customer-service.ts +80 -76
  121. package/src/templates/data-analyst.ts +70 -66
  122. package/src/templates/executive-assistant.ts +71 -71
  123. package/src/templates/financial-advisor.ts +60 -60
  124. package/src/templates/knowledge-base.ts +31 -27
  125. package/src/templates/legal-assistant.ts +71 -71
  126. package/src/templates/sales-assistant.ts +79 -75
  127. package/src/templates/teacher.ts +79 -75
  128. package/src/testing/index.ts +181 -181
  129. package/src/tools/calculator.ts +73 -73
  130. package/src/tools/datetime.ts +149 -149
  131. package/src/tools/json-transform.ts +187 -187
  132. package/src/tools/mcp.ts +76 -76
  133. package/src/tools/text-analysis.ts +116 -116
  134. package/templates/Dockerfile +15 -15
  135. package/templates/code-reviewer/README.md +27 -27
  136. package/templates/code-reviewer/oad.yaml +41 -41
  137. package/templates/customer-service/README.md +22 -22
  138. package/templates/customer-service/oad.yaml +36 -36
  139. package/templates/docker-compose.yml +21 -21
  140. package/templates/ecommerce-assistant/README.md +45 -45
  141. package/templates/ecommerce-assistant/oad.yaml +47 -47
  142. package/templates/knowledge-base/README.md +28 -28
  143. package/templates/knowledge-base/oad.yaml +38 -38
  144. package/templates/sales-assistant/README.md +26 -26
  145. package/templates/sales-assistant/oad.yaml +43 -43
  146. package/templates/tech-support/README.md +43 -43
  147. package/templates/tech-support/oad.yaml +45 -45
  148. package/tests/a2a.test.ts +66 -66
  149. package/tests/agent.test.ts +72 -72
  150. package/tests/analytics.test.ts +50 -50
  151. package/tests/channel.test.ts +39 -39
  152. package/tests/e2e.test.ts +134 -134
  153. package/tests/errors.test.ts +83 -83
  154. package/tests/hitl.test.ts +71 -71
  155. package/tests/i18n.test.ts +41 -41
  156. package/tests/mcp.test.ts +54 -54
  157. package/tests/oad.test.ts +68 -68
  158. package/tests/performance.test.ts +115 -115
  159. package/tests/plugin.test.ts +74 -74
  160. package/tests/room.test.ts +106 -106
  161. package/tests/runtime.test.ts +42 -42
  162. package/tests/sandbox.test.ts +46 -46
  163. package/tests/security.test.ts +60 -60
  164. package/tests/templates.test.ts +77 -77
  165. package/tests/v070.test.ts +76 -76
  166. package/tests/versioning.test.ts +75 -75
  167. package/tests/voice.test.ts +61 -61
  168. package/tests/webhook.test.ts +29 -29
  169. package/tests/workflow.test.ts +143 -143
  170. package/tsconfig.json +19 -19
  171. package/vitest.config.ts +9 -9
  172. package/.github/ISSUE_TEMPLATE/bug_report.md +0 -20
  173. package/.github/ISSUE_TEMPLATE/feature_request.md +0 -14
  174. package/.github/PULL_REQUEST_TEMPLATE.md +0 -13
  175. package/.github/workflows/ci.yml +0 -24
  176. package/dist/traces/index.d.ts +0 -49
  177. package/dist/traces/index.js +0 -102
  178. package/examples/README.md +0 -22
  179. package/examples/basic-agent.ts +0 -90
  180. package/examples/brain-integration.ts +0 -71
  181. package/examples/multi-channel.ts +0 -74
  182. package/src/traces/index.ts +0 -132
  183. package/test-agent/Dockerfile +0 -9
  184. package/test-agent/README.md +0 -50
  185. package/test-agent/agent.yaml +0 -23
  186. package/test-agent/docker-compose.yml +0 -11
  187. package/test-agent/oad.yaml +0 -31
  188. package/test-agent/package-lock.json +0 -1492
  189. package/test-agent/package.json +0 -18
  190. package/test-agent/src/index.ts +0 -24
  191. package/test-agent/src/skills/echo.ts +0 -15
  192. package/test-agent/tsconfig.json +0 -25
@@ -1,37 +1,4 @@
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
- })();
35
2
  Object.defineProperty(exports, "__esModule", { value: true });
36
3
  exports.SlackChannel = void 0;
37
4
  const index_1 = require("./index");
@@ -70,51 +37,9 @@ class SlackChannel extends index_1.BaseChannel {
70
37
  }
71
38
  /** Start Events API HTTP server */
72
39
  async startEventsAPI() {
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
- });
40
+ // TODO: Implement with express or http
41
+ // const port = this.config.port ?? 3001;
42
+ // Listen for POST /slack/events and /slack/commands
118
43
  }
119
44
  /** Handle incoming Slack message */
120
45
  async handleMessage(event) {
@@ -169,21 +94,13 @@ class SlackChannel extends index_1.BaseChannel {
169
94
  }
170
95
  /** Send a message to a Slack channel */
171
96
  async sendMessage(channel, text, threadTs) {
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
- }
97
+ // TODO: Implement with @slack/web-api
98
+ // const { WebClient } = await import('@slack/web-api');
99
+ // const client = new WebClient(this.config.botToken);
100
+ // await client.chat.postMessage({ channel, text, thread_ts: threadTs });
101
+ void channel;
102
+ void text;
103
+ void threadTs;
187
104
  }
188
105
  }
189
106
  exports.SlackChannel = SlackChannel;
@@ -9,11 +9,6 @@ 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;
17
12
  private currentProvider;
18
13
  private stats;
19
14
  private eventHandlers;
@@ -28,11 +23,6 @@ export declare class WebChannel extends BaseChannel {
28
23
  trackSession(): void;
29
24
  constructor(port?: number, authConfig?: AuthConfig);
30
25
  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;
36
26
  onStreamMessage(handler: (msg: Message, res: Response) => Promise<void>): void;
37
27
  private setupRoutes;
38
28
  start(): Promise<void>;
@@ -286,11 +286,6 @@ 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;
294
289
  currentProvider = 'openai';
295
290
  stats = { sessions: 0, messages: 0, totalResponseMs: 0, tokenUsage: 0, knowledgeFiles: 0, startedAt: Date.now(), errors: 0 };
296
291
  eventHandlers = new Map();
@@ -331,21 +326,6 @@ class WebChannel extends index_1.BaseChannel {
331
326
  setAgentName(name) {
332
327
  this.agentName = name;
333
328
  }
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
- }
349
329
  onStreamMessage(handler) {
350
330
  this.streamHandler = handler;
351
331
  }
@@ -354,17 +334,7 @@ class WebChannel extends index_1.BaseChannel {
354
334
  res.type('html').send(CHAT_HTML);
355
335
  });
356
336
  this.app.get('/health', (_req, res) => {
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
- });
337
+ res.json({ status: 'ok', timestamp: Date.now() });
368
338
  });
369
339
  this.app.get('/api/info', (_req, res) => {
370
340
  res.json({ name: this.agentName });
@@ -438,8 +408,7 @@ class WebChannel extends index_1.BaseChannel {
438
408
  res.type('html').send(DASHBOARD_HTML);
439
409
  });
440
410
  this.app.get('/api/dashboard', (_req, res) => {
441
- const analytics = this.analyticsProvider ? this.analyticsProvider() : null;
442
- res.json({ ...this.stats, analytics });
411
+ res.json(this.stats);
443
412
  });
444
413
  // --- Knowledge Base Upload ---
445
414
  this.app.post('/api/kb/upload', async (req, res) => {
package/dist/cli.js CHANGED
@@ -61,6 +61,7 @@ const workflow_1 = require("./core/workflow");
61
61
  const versioning_1 = require("./core/versioning");
62
62
  const providers_1 = require("./providers");
63
63
  const knowledge_1 = require("./core/knowledge");
64
+ const marketplace_1 = require("./marketplace");
64
65
  const program = new commander_1.Command();
65
66
  const color = {
66
67
  green: (s) => `\x1b[32m${s}\x1b[0m`,
@@ -118,7 +119,7 @@ async function select(question, options) {
118
119
  program
119
120
  .name('opc')
120
121
  .description('OPC Agent - Open Agent Framework for business workstations')
121
- .version('1.4.0');
122
+ .version('1.0.0');
122
123
  // ── Init command ─────────────────────────────────────────────
123
124
  program
124
125
  .command('init')
@@ -138,7 +139,6 @@ program
138
139
  process.exit(1);
139
140
  }
140
141
  fs.mkdirSync(dir, { recursive: true });
141
- fs.mkdirSync(path.join(dir, 'src', 'skills'), { recursive: true });
142
142
  const factory = TEMPLATES[template]?.factory ?? customer_service_1.createCustomerServiceConfig;
143
143
  const config = factory();
144
144
  config.metadata.name = name;
@@ -147,93 +147,6 @@ program
147
147
  config.spec.channels.push({ type: 'web', port: 3000 });
148
148
  }
149
149
  fs.writeFileSync(path.join(dir, 'oad.yaml'), yaml.dump(config, { lineWidth: 120 }));
150
- // agent.yaml — standalone OAD config for runtime usage
151
- fs.writeFileSync(path.join(dir, 'agent.yaml'), `apiVersion: opc/v1
152
- kind: Agent
153
- metadata:
154
- name: ${name}
155
- version: 1.0.0
156
- description: My AI Agent
157
- spec:
158
- model: qwen2.5
159
- provider:
160
- default: ollama
161
- systemPrompt: |
162
- You are a helpful AI assistant named ${name}.
163
- Be concise, helpful, and friendly.
164
- channels:
165
- - type: web
166
- port: 3000
167
- memory:
168
- shortTerm: true
169
- longTerm:
170
- provider: deepbrain
171
- skills:
172
- - name: echo
173
- description: Echo test skill
174
- `);
175
- // src/index.ts — entry point
176
- fs.writeFileSync(path.join(dir, 'src', 'index.ts'), `import { AgentRuntime } from 'opc-agent';
177
- import { EchoSkill } from './skills/echo';
178
-
179
- async function main() {
180
- const runtime = new AgentRuntime();
181
-
182
- // Load OAD config
183
- await runtime.loadConfig('./agent.yaml');
184
-
185
- // Initialize agent with channels, memory, etc.
186
- const agent = await runtime.initialize();
187
-
188
- // Register custom skills
189
- runtime.registerSkill(new EchoSkill());
190
-
191
- // Start serving
192
- await runtime.start();
193
-
194
- console.log('🤖 Agent is running!');
195
- console.log(' Web UI: http://localhost:3000');
196
- console.log(' Press Ctrl+C to stop');
197
- }
198
-
199
- main().catch(console.error);
200
- `);
201
- // src/skills/echo.ts — example skill
202
- fs.writeFileSync(path.join(dir, 'src', 'skills', 'echo.ts'), `import { BaseSkill } from 'opc-agent';
203
- import type { AgentContext, Message, SkillResult } from 'opc-agent';
204
-
205
- export class EchoSkill extends BaseSkill {
206
- name = 'echo';
207
- description = 'Echo back the message (test skill)';
208
-
209
- async execute(context: AgentContext, message: Message): Promise<SkillResult> {
210
- if (message.content.toLowerCase().startsWith('/echo ')) {
211
- const text = message.content.slice(6);
212
- return this.match(\`🔊 Echo: \${text}\`);
213
- }
214
- return this.noMatch();
215
- }
216
- }
217
- `);
218
- // tsconfig.json
219
- fs.writeFileSync(path.join(dir, 'tsconfig.json'), JSON.stringify({
220
- compilerOptions: {
221
- target: 'ES2022',
222
- module: 'commonjs',
223
- lib: ['ES2022'],
224
- outDir: 'dist',
225
- rootDir: 'src',
226
- strict: true,
227
- esModuleInterop: true,
228
- skipLibCheck: true,
229
- forceConsistentCasingInFileNames: true,
230
- resolveJsonModule: true,
231
- declaration: true,
232
- sourceMap: true,
233
- },
234
- include: ['src/**/*'],
235
- exclude: ['node_modules', 'dist'],
236
- }, null, 2));
237
150
  // .env.example
238
151
  fs.writeFileSync(path.join(dir, '.env.example'), `# LLM API Configuration
239
152
  OPC_LLM_API_KEY=your-api-key-here
@@ -244,9 +157,9 @@ OPC_LLM_MODEL=gpt-4o-mini
244
157
  # OPC_LLM_BASE_URL=https://api.deepseek.com/v1
245
158
  # OPC_LLM_MODEL=deepseek-chat
246
159
 
247
- # For local Ollama (default in agent.yaml):
160
+ # For local Ollama:
248
161
  # OPC_LLM_BASE_URL=http://localhost:11434/v1
249
- # OPC_LLM_MODEL=qwen2.5
162
+ # OPC_LLM_MODEL=llama3
250
163
  `);
251
164
  // .env (copy of example)
252
165
  fs.writeFileSync(path.join(dir, '.env'), `OPC_LLM_API_KEY=your-api-key-here
@@ -260,27 +173,20 @@ OPC_LLM_MODEL=gpt-4o-mini
260
173
  private: true,
261
174
  scripts: {
262
175
  start: 'opc run',
263
- dev: 'opc dev',
264
176
  chat: 'opc chat',
265
- build: 'tsc',
266
177
  },
267
178
  dependencies: {
268
- 'opc-agent': '^1.3.0',
269
- },
270
- devDependencies: {
271
- typescript: '^5.5.0',
272
- tsx: '^4.0.0',
179
+ 'opc-agent': '^0.5.0',
273
180
  },
274
181
  }, null, 2));
275
182
  // .gitignore
276
- fs.writeFileSync(path.join(dir, '.gitignore'), 'node_modules\ndist\n.env\n.opc-knowledge.json\ndata/\n');
183
+ fs.writeFileSync(path.join(dir, '.gitignore'), 'node_modules\n.env\n.opc-knowledge.json\ndata/\n');
277
184
  // Dockerfile
278
185
  fs.writeFileSync(path.join(dir, 'Dockerfile'), `FROM node:22-alpine
279
186
  WORKDIR /app
280
187
  COPY package.json package-lock.json* ./
281
188
  RUN npm ci --production 2>/dev/null || npm install --production
282
- COPY oad.yaml agent.yaml .env* ./
283
- COPY src/ ./src/
189
+ COPY oad.yaml .env* ./
284
190
  COPY prompts/ ./prompts/ 2>/dev/null || true
285
191
  EXPOSE 3000
286
192
  CMD ["npx", "opc", "run"]
@@ -295,7 +201,7 @@ services:
295
201
  env_file:
296
202
  - .env
297
203
  volumes:
298
- - ./agent.yaml:/app/agent.yaml:ro
204
+ - ./oad.yaml:/app/oad.yaml:ro
299
205
  restart: unless-stopped
300
206
  `);
301
207
  // README.md
@@ -305,67 +211,51 @@ Created with [OPC Agent](https://github.com/Deepleaper/opc-agent) using the \`${
305
211
 
306
212
  ## Quick Start
307
213
 
308
- 1. **Install dependencies:**
214
+ 1. **Set your API key:**
309
215
  \`\`\`bash
310
- npm install
216
+ # Edit .env and add your API key
217
+ cp .env.example .env
218
+ # Then edit .env with your actual key
311
219
  \`\`\`
312
220
 
313
- 2. **Run with Ollama (default):**
221
+ 2. **Install dependencies:**
314
222
  \`\`\`bash
315
- # Make sure Ollama is running with qwen2.5 model
316
- ollama pull qwen2.5
317
- npx tsx src/index.ts
223
+ npm install
318
224
  \`\`\`
319
225
 
320
- 3. **Or use OpenAI/other providers:**
226
+ 3. **Start the web server:**
321
227
  \`\`\`bash
322
- # Edit .env and set your API key
323
228
  npx opc run
324
229
  \`\`\`
325
230
 
326
231
  4. **Open browser:** [http://localhost:3000](http://localhost:3000)
327
232
 
328
- ## Development
233
+ ## CLI Chat
329
234
 
330
235
  \`\`\`bash
331
- npx opc dev # Hot-reload mode
332
- npx opc chat # CLI chat
333
- \`\`\`
334
-
335
- ## Project Structure
336
-
337
- \`\`\`
338
- ${name}/
339
- ├── agent.yaml # OAD agent config (used by src/index.ts)
340
- ├── oad.yaml # OAD config (used by opc CLI)
341
- ├── src/
342
- │ ├── index.ts # Entry point
343
- │ └── skills/
344
- │ └── echo.ts # Example skill
345
- ├── package.json
346
- └── tsconfig.json
236
+ npx opc chat
347
237
  \`\`\`
348
238
 
349
239
  ## Configuration
350
240
 
351
- Edit \`agent.yaml\` to customize your agent's personality, skills, and behavior.
241
+ Edit \`oad.yaml\` to customize your agent's personality, skills, and behavior.
352
242
  `);
353
243
  console.log(`\n${icon.success} Created agent project: ${color.bold(name + '/')}`);
354
- console.log(` ${icon.file} agent.yaml - Agent definition (OAD)`);
355
- console.log(` ${icon.file} src/index.ts - Entry point`);
356
- console.log(` ${icon.file} src/skills/echo.ts - Example skill`);
357
- console.log(` ${icon.file} package.json - Dependencies`);
358
- console.log(` ${icon.file} tsconfig.json - TypeScript config`);
359
- console.log(` ${icon.file} .env.example - Environment template`);
244
+ console.log(` ${icon.file} oad.yaml - Agent definition`);
245
+ console.log(` ${icon.file} package.json - Dependencies`);
246
+ console.log(` ${icon.file} .env.example - Environment template`);
247
+ console.log(` ${icon.file} .env - Environment config (edit this!)`);
360
248
  console.log(` ${icon.file} .gitignore`);
361
249
  console.log(` ${icon.file} Dockerfile`);
250
+ console.log(` ${icon.file} docker-compose.yml`);
362
251
  console.log(` ${icon.file} README.md`);
363
252
  console.log(`\n Template: ${color.cyan(template)}`);
364
253
  console.log(`\n${color.bold('Next steps:')}`);
365
254
  console.log(` 1. cd ${name}`);
366
- console.log(` 2. npm install`);
367
- console.log(` 3. npx tsx src/index.ts ${color.dim('# or: npx opc run')}`);
368
- console.log(` 4. Open http://localhost:3000\n`);
255
+ console.log(` 2. Edit .env — set your OPC_LLM_API_KEY`);
256
+ console.log(` 3. npm install`);
257
+ console.log(` 4. npx opc run`);
258
+ console.log(` 5. Open http://localhost:3000\n`);
369
259
  });
370
260
  // ── Chat command ─────────────────────────────────────────────
371
261
  program
@@ -794,23 +684,51 @@ kbCmd.command('clear').action(() => {
794
684
  kb.clear();
795
685
  console.log(`${icon.success} Knowledge base cleared.`);
796
686
  });
797
- // 📦 Package commands ───────────────────────────────────
687
+ // 📦 Marketplace commands ───────────────────────────────────
798
688
  program
799
689
  .command('publish')
800
690
  .description('Package agent for distribution')
801
691
  .option('-f, --file <file>', 'OAD file', 'oad.yaml')
802
692
  .option('-o, --output <dir>', 'Output directory', '.')
803
693
  .option('--include-kb', 'Include knowledge base')
804
- .action(async () => {
805
- console.log(`\n${icon.package} Agent packaging coming soon.\n`);
694
+ .action(async (opts) => {
695
+ try {
696
+ console.log(`\n${icon.package} Packaging agent...\n`);
697
+ const result = await (0, marketplace_1.publishAgent)({
698
+ oadPath: opts.file,
699
+ outputDir: opts.output,
700
+ includeKnowledge: opts.includeKb,
701
+ });
702
+ console.log(`${icon.success} Published: ${color.bold(result.archivePath)}`);
703
+ console.log(` Name: ${result.manifest.name}`);
704
+ console.log(` Version: ${result.manifest.version}`);
705
+ console.log(` Files: ${result.manifest.files.length}`);
706
+ console.log();
707
+ }
708
+ catch (err) {
709
+ console.error(`${icon.error} Publish failed:`, err instanceof Error ? err.message : err);
710
+ process.exit(1);
711
+ }
806
712
  });
807
713
  program
808
714
  .command('install')
809
715
  .description('Install agent from package')
810
716
  .argument('<source>', 'Package file path or URL')
811
717
  .option('-d, --dir <dir>', 'Install directory')
812
- .action(async () => {
813
- console.log(`\n${icon.package} Agent install coming soon.\n`);
718
+ .action(async (source, opts) => {
719
+ try {
720
+ console.log(`\n${icon.package} Installing agent from ${color.bold(source)}...\n`);
721
+ const result = await (0, marketplace_1.installAgent)({ source, targetDir: opts.dir });
722
+ console.log(`${icon.success} Installed: ${color.bold(result.manifest.name)} v${result.manifest.version}`);
723
+ console.log(` Directory: ${result.dir}`);
724
+ console.log(`\n${color.bold('Next steps:')}`);
725
+ console.log(` cd ${result.dir}`);
726
+ console.log(` opc run\n`);
727
+ }
728
+ catch (err) {
729
+ console.error(`${icon.error} Install failed:`, err instanceof Error ? err.message : err);
730
+ process.exit(1);
731
+ }
814
732
  });
815
733
  // 🔌 Plugin commands ────────────────────────────────────────
816
734
  const pluginCmd = program.command('plugin').description('Manage plugins');
@@ -920,118 +838,5 @@ program
920
838
  process.exit(1);
921
839
  }
922
840
  });
923
- // ── Brain command ────────────────────────────────────────────
924
- program
925
- .command('brain')
926
- .description('Show agent memory/brain status from DeepBrain')
927
- .option('--url <url>', 'DeepBrain server URL', 'http://localhost:3333')
928
- .action(async (opts) => {
929
- console.log(`\n${icon.gear} ${color.bold('DeepBrain Status')} — ${color.dim(opts.url)}\n`);
930
- try {
931
- const res = await fetch(`${opts.url}/api/stats`);
932
- if (!res.ok)
933
- throw new Error(`HTTP ${res.status} ${res.statusText}`);
934
- const stats = (await res.json());
935
- const rows = [
936
- ['Total Pages', String(stats.totalPages ?? stats.pages ?? '-')],
937
- ['Total Chunks', String(stats.totalChunks ?? stats.chunks ?? '-')],
938
- ['Memory Tiers', String(stats.memoryTiers ?? stats.tiers ?? '-')],
939
- ['Index Size', stats.indexSize ?? '-'],
940
- ['Last Updated', stats.lastUpdated ?? stats.updatedAt ?? '-'],
941
- ];
942
- const maxKey = Math.max(...rows.map(([k]) => k.length));
943
- for (const [key, val] of rows) {
944
- console.log(` ${color.cyan(key.padEnd(maxKey))} ${val}`);
945
- }
946
- console.log();
947
- }
948
- catch (err) {
949
- const msg = err instanceof Error ? err.message : String(err);
950
- if (msg.includes('ECONNREFUSED') || msg.includes('fetch failed')) {
951
- console.log(` ${icon.warn} Cannot connect to DeepBrain at ${opts.url}`);
952
- console.log(` ${color.dim('Is the server running? Start with: deepbrain serve')}\n`);
953
- }
954
- else {
955
- console.error(` ${icon.error} ${msg}\n`);
956
- }
957
- }
958
- });
959
- // ── Logs command ─────────────────────────────────────────────
960
- program
961
- .command('logs')
962
- .description('Show recent agent traces')
963
- .option('-n, --limit <n>', 'Number of spans to show', '20')
964
- .option('-f, --follow', 'Keep watching for new spans')
965
- .action(async (opts) => {
966
- const { TraceCollector } = await Promise.resolve().then(() => __importStar(require('./traces')));
967
- const collector = new TraceCollector();
968
- const limit = parseInt(opts.limit) || 20;
969
- const printSpans = (spans) => {
970
- const slice = spans.slice(-limit);
971
- if (slice.length === 0) {
972
- console.log(` ${icon.info} No traces yet. Interact with the agent to generate traces.`);
973
- return;
974
- }
975
- for (const span of slice) {
976
- const duration = span.endTime
977
- ? `${span.endTime.getTime() - span.startTime.getTime()}ms`
978
- : 'ongoing';
979
- const statusIcon = span.status === 'ok' ? icon.success : span.status === 'error' ? icon.error : color.dim('○');
980
- const time = span.startTime.toLocaleTimeString();
981
- console.log(` ${statusIcon} ${color.dim(time)} ${color.bold(span.name)} ${color.dim(duration)}`);
982
- }
983
- };
984
- console.log(`\n${icon.gear} ${color.bold('Agent Traces')}\n`);
985
- const spans = collector.getBufferedSpans();
986
- printSpans(spans);
987
- if (opts.follow) {
988
- console.log(`\n ${color.dim('Watching for new traces... (Ctrl+C to stop)')}\n`);
989
- let lastCount = spans.length;
990
- const interval = setInterval(() => {
991
- const current = collector.getBufferedSpans();
992
- if (current.length > lastCount) {
993
- const newSpans = current.slice(lastCount);
994
- printSpans(newSpans);
995
- lastCount = current.length;
996
- }
997
- }, 1000);
998
- process.on('SIGINT', () => { clearInterval(interval); process.exit(0); });
999
- }
1000
- else {
1001
- console.log();
1002
- }
1003
- });
1004
- // ── Score command ────────────────────────────────────────────
1005
- program
1006
- .command('score')
1007
- .description('Show agent performance score')
1008
- .action(async () => {
1009
- console.log(`\n${icon.gear} ${color.bold('Agent Performance Score')}\n`);
1010
- try {
1011
- const engine = new analytics_engine_1.AnalyticsEngine('.');
1012
- const stats = engine.getStats();
1013
- if (!stats || stats.totalMessages === 0) {
1014
- console.log(` ${icon.info} No score data yet. Run the agent first.\n`);
1015
- return;
1016
- }
1017
- const errorRate = stats.totalMessages > 0 ? (stats.totalErrors / stats.totalMessages) : 0;
1018
- const rows = [
1019
- ['Total Messages', String(stats.totalMessages)],
1020
- ['Total LLM Calls', String(stats.totalLLMCalls)],
1021
- ['Total Tool Uses', String(stats.totalToolUses)],
1022
- ['Avg Response Time', `${stats.avgResponseTimeMs}ms`],
1023
- ['Error Rate', `${(errorRate * 100).toFixed(1)}%`],
1024
- ['Token Usage', `${stats.totalTokens.total} tokens (in: ${stats.totalTokens.input}, out: ${stats.totalTokens.output})`],
1025
- ];
1026
- const maxKey = Math.max(...rows.map(([k]) => k.length));
1027
- for (const [key, val] of rows) {
1028
- console.log(` ${color.cyan(key.padEnd(maxKey))} ${val}`);
1029
- }
1030
- console.log();
1031
- }
1032
- catch {
1033
- console.log(` ${icon.info} No score data yet. Run the agent first.\n`);
1034
- }
1035
- });
1036
841
  program.parse();
1037
842
  //# sourceMappingURL=cli.js.map
@@ -0,0 +1,35 @@
1
+ export interface DashboardConfig {
2
+ /** Enable the dashboard (default: false) */
3
+ enabled: boolean;
4
+ /** HTTP port (default: 4100) */
5
+ port?: number;
6
+ /** Bind address (default: 127.0.0.1 for security) */
7
+ host?: string;
8
+ /** Enable CORS (default: false) */
9
+ cors?: boolean;
10
+ }
11
+ interface SessionSummary {
12
+ id: string;
13
+ channel: string;
14
+ messages: number;
15
+ lastActive: number;
16
+ status: 'active' | 'idle' | 'closed';
17
+ }
18
+ export declare class Dashboard {
19
+ private app;
20
+ private server;
21
+ private config;
22
+ private startTime;
23
+ private stats;
24
+ constructor(config: DashboardConfig);
25
+ private setupRoutes;
26
+ private getState;
27
+ trackSession(session: SessionSummary): void;
28
+ trackToolCall(toolName: string): void;
29
+ trackChannel(name: string, connected: boolean, messages?: number): void;
30
+ start(): Promise<void>;
31
+ stop(): Promise<void>;
32
+ private renderHTML;
33
+ }
34
+ export {};
35
+ //# sourceMappingURL=dashboard.d.ts.map