opc-agent 1.3.2 → 1.4.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 +23 -63
- package/CONTRIBUTING.md +21 -60
- package/README.md +235 -358
- package/README.zh-CN.md +415 -415
- package/dist/channels/slack.js +93 -10
- package/dist/channels/web.d.ts +10 -0
- package/dist/channels/web.js +33 -2
- package/dist/cli.js +255 -60
- package/dist/core/runtime.d.ts +4 -0
- package/dist/core/runtime.js +27 -0
- package/dist/deploy/hermes.js +22 -22
- package/dist/deploy/openclaw.js +31 -40
- package/dist/index.d.ts +3 -10
- package/dist/index.js +6 -15
- package/dist/providers/index.d.ts +1 -1
- package/dist/providers/index.js +7 -1
- package/dist/schema/oad.d.ts +1 -2
- 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/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 +90 -90
- 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 +282 -58
- package/src/core/a2a.ts +143 -143
- package/src/core/agent.ts +152 -152
- 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 +183 -152
- package/src/core/sandbox.ts +101 -101
- package/src/core/security.ts +171 -171
- 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/deploy/hermes.ts +156 -156
- package/src/deploy/openclaw.ts +190 -200
- package/src/i18n/index.ts +216 -216
- package/src/index.ts +3 -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 +9 -1
- package/src/schema/oad.ts +154 -155
- 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/calculator.ts +73 -73
- package/src/tools/datetime.ts +149 -149
- package/src/tools/json-transform.ts +187 -187
- 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/channel.test.ts +39 -39
- 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/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/src/cli.ts
CHANGED
|
@@ -27,9 +27,9 @@ import { WorkflowEngine } from './core/workflow';
|
|
|
27
27
|
import { VersionManager } from './core/versioning';
|
|
28
28
|
import { createProvider } from './providers';
|
|
29
29
|
import { KnowledgeBase } from './core/knowledge';
|
|
30
|
-
import { publishAgent, installAgent } from './marketplace';
|
|
31
30
|
|
|
32
31
|
import { PluginManager, createLoggingPlugin, createAnalyticsPlugin, createRateLimitPlugin } from './plugins';
|
|
32
|
+
import type { Span } from './traces';
|
|
33
33
|
|
|
34
34
|
const program = new Command();
|
|
35
35
|
|
|
@@ -94,7 +94,7 @@ async function select(question: string, options: { value: string; label: string
|
|
|
94
94
|
program
|
|
95
95
|
.name('opc')
|
|
96
96
|
.description('OPC Agent - Open Agent Framework for business workstations')
|
|
97
|
-
.version('1.
|
|
97
|
+
.version('1.4.0');
|
|
98
98
|
|
|
99
99
|
// ── Init command ─────────────────────────────────────────────
|
|
100
100
|
|
|
@@ -119,6 +119,8 @@ program
|
|
|
119
119
|
}
|
|
120
120
|
|
|
121
121
|
fs.mkdirSync(dir, { recursive: true });
|
|
122
|
+
fs.mkdirSync(path.join(dir, 'src', 'skills'), { recursive: true });
|
|
123
|
+
|
|
122
124
|
const factory = TEMPLATES[template]?.factory ?? createCustomerServiceConfig;
|
|
123
125
|
const config = factory();
|
|
124
126
|
config.metadata.name = name;
|
|
@@ -130,6 +132,113 @@ program
|
|
|
130
132
|
|
|
131
133
|
fs.writeFileSync(path.join(dir, 'oad.yaml'), yaml.dump(config, { lineWidth: 120 }));
|
|
132
134
|
|
|
135
|
+
// agent.yaml — standalone OAD config for runtime usage
|
|
136
|
+
fs.writeFileSync(
|
|
137
|
+
path.join(dir, 'agent.yaml'),
|
|
138
|
+
`apiVersion: opc/v1
|
|
139
|
+
kind: Agent
|
|
140
|
+
metadata:
|
|
141
|
+
name: ${name}
|
|
142
|
+
version: 1.0.0
|
|
143
|
+
description: My AI Agent
|
|
144
|
+
spec:
|
|
145
|
+
model: qwen2.5
|
|
146
|
+
provider:
|
|
147
|
+
default: ollama
|
|
148
|
+
systemPrompt: |
|
|
149
|
+
You are a helpful AI assistant named ${name}.
|
|
150
|
+
Be concise, helpful, and friendly.
|
|
151
|
+
channels:
|
|
152
|
+
- type: web
|
|
153
|
+
port: 3000
|
|
154
|
+
memory:
|
|
155
|
+
shortTerm: true
|
|
156
|
+
longTerm:
|
|
157
|
+
provider: deepbrain
|
|
158
|
+
skills:
|
|
159
|
+
- name: echo
|
|
160
|
+
description: Echo test skill
|
|
161
|
+
`,
|
|
162
|
+
);
|
|
163
|
+
|
|
164
|
+
// src/index.ts — entry point
|
|
165
|
+
fs.writeFileSync(
|
|
166
|
+
path.join(dir, 'src', 'index.ts'),
|
|
167
|
+
`import { AgentRuntime } from 'opc-agent';
|
|
168
|
+
import { EchoSkill } from './skills/echo';
|
|
169
|
+
|
|
170
|
+
async function main() {
|
|
171
|
+
const runtime = new AgentRuntime();
|
|
172
|
+
|
|
173
|
+
// Load OAD config
|
|
174
|
+
await runtime.loadConfig('./agent.yaml');
|
|
175
|
+
|
|
176
|
+
// Initialize agent with channels, memory, etc.
|
|
177
|
+
const agent = await runtime.initialize();
|
|
178
|
+
|
|
179
|
+
// Register custom skills
|
|
180
|
+
runtime.registerSkill(new EchoSkill());
|
|
181
|
+
|
|
182
|
+
// Start serving
|
|
183
|
+
await runtime.start();
|
|
184
|
+
|
|
185
|
+
console.log('🤖 Agent is running!');
|
|
186
|
+
console.log(' Web UI: http://localhost:3000');
|
|
187
|
+
console.log(' Press Ctrl+C to stop');
|
|
188
|
+
}
|
|
189
|
+
|
|
190
|
+
main().catch(console.error);
|
|
191
|
+
`,
|
|
192
|
+
);
|
|
193
|
+
|
|
194
|
+
// src/skills/echo.ts — example skill
|
|
195
|
+
fs.writeFileSync(
|
|
196
|
+
path.join(dir, 'src', 'skills', 'echo.ts'),
|
|
197
|
+
`import { BaseSkill } from 'opc-agent';
|
|
198
|
+
import type { AgentContext, Message, SkillResult } from 'opc-agent';
|
|
199
|
+
|
|
200
|
+
export class EchoSkill extends BaseSkill {
|
|
201
|
+
name = 'echo';
|
|
202
|
+
description = 'Echo back the message (test skill)';
|
|
203
|
+
|
|
204
|
+
async execute(context: AgentContext, message: Message): Promise<SkillResult> {
|
|
205
|
+
if (message.content.toLowerCase().startsWith('/echo ')) {
|
|
206
|
+
const text = message.content.slice(6);
|
|
207
|
+
return this.match(\`🔊 Echo: \${text}\`);
|
|
208
|
+
}
|
|
209
|
+
return this.noMatch();
|
|
210
|
+
}
|
|
211
|
+
}
|
|
212
|
+
`,
|
|
213
|
+
);
|
|
214
|
+
|
|
215
|
+
// tsconfig.json
|
|
216
|
+
fs.writeFileSync(
|
|
217
|
+
path.join(dir, 'tsconfig.json'),
|
|
218
|
+
JSON.stringify(
|
|
219
|
+
{
|
|
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
|
+
},
|
|
237
|
+
null,
|
|
238
|
+
2,
|
|
239
|
+
),
|
|
240
|
+
);
|
|
241
|
+
|
|
133
242
|
// .env.example
|
|
134
243
|
fs.writeFileSync(
|
|
135
244
|
path.join(dir, '.env.example'),
|
|
@@ -142,9 +251,9 @@ OPC_LLM_MODEL=gpt-4o-mini
|
|
|
142
251
|
# OPC_LLM_BASE_URL=https://api.deepseek.com/v1
|
|
143
252
|
# OPC_LLM_MODEL=deepseek-chat
|
|
144
253
|
|
|
145
|
-
# For local Ollama:
|
|
254
|
+
# For local Ollama (default in agent.yaml):
|
|
146
255
|
# OPC_LLM_BASE_URL=http://localhost:11434/v1
|
|
147
|
-
# OPC_LLM_MODEL=
|
|
256
|
+
# OPC_LLM_MODEL=qwen2.5
|
|
148
257
|
`,
|
|
149
258
|
);
|
|
150
259
|
|
|
@@ -167,10 +276,16 @@ OPC_LLM_MODEL=gpt-4o-mini
|
|
|
167
276
|
private: true,
|
|
168
277
|
scripts: {
|
|
169
278
|
start: 'opc run',
|
|
279
|
+
dev: 'opc dev',
|
|
170
280
|
chat: 'opc chat',
|
|
281
|
+
build: 'tsc',
|
|
171
282
|
},
|
|
172
283
|
dependencies: {
|
|
173
|
-
'opc-agent': '^
|
|
284
|
+
'opc-agent': '^1.3.0',
|
|
285
|
+
},
|
|
286
|
+
devDependencies: {
|
|
287
|
+
typescript: '^5.5.0',
|
|
288
|
+
tsx: '^4.0.0',
|
|
174
289
|
},
|
|
175
290
|
},
|
|
176
291
|
null,
|
|
@@ -179,7 +294,7 @@ OPC_LLM_MODEL=gpt-4o-mini
|
|
|
179
294
|
);
|
|
180
295
|
|
|
181
296
|
// .gitignore
|
|
182
|
-
fs.writeFileSync(path.join(dir, '.gitignore'), 'node_modules\n.env\n.opc-knowledge.json\ndata/\n');
|
|
297
|
+
fs.writeFileSync(path.join(dir, '.gitignore'), 'node_modules\ndist\n.env\n.opc-knowledge.json\ndata/\n');
|
|
183
298
|
|
|
184
299
|
// Dockerfile
|
|
185
300
|
fs.writeFileSync(
|
|
@@ -188,7 +303,8 @@ OPC_LLM_MODEL=gpt-4o-mini
|
|
|
188
303
|
WORKDIR /app
|
|
189
304
|
COPY package.json package-lock.json* ./
|
|
190
305
|
RUN npm ci --production 2>/dev/null || npm install --production
|
|
191
|
-
COPY oad.yaml .env* ./
|
|
306
|
+
COPY oad.yaml agent.yaml .env* ./
|
|
307
|
+
COPY src/ ./src/
|
|
192
308
|
COPY prompts/ ./prompts/ 2>/dev/null || true
|
|
193
309
|
EXPOSE 3000
|
|
194
310
|
CMD ["npx", "opc", "run"]
|
|
@@ -207,7 +323,7 @@ services:
|
|
|
207
323
|
env_file:
|
|
208
324
|
- .env
|
|
209
325
|
volumes:
|
|
210
|
-
- ./
|
|
326
|
+
- ./agent.yaml:/app/agent.yaml:ro
|
|
211
327
|
restart: unless-stopped
|
|
212
328
|
`,
|
|
213
329
|
);
|
|
@@ -221,53 +337,69 @@ Created with [OPC Agent](https://github.com/Deepleaper/opc-agent) using the \`${
|
|
|
221
337
|
|
|
222
338
|
## Quick Start
|
|
223
339
|
|
|
224
|
-
1. **
|
|
340
|
+
1. **Install dependencies:**
|
|
225
341
|
\`\`\`bash
|
|
226
|
-
|
|
227
|
-
cp .env.example .env
|
|
228
|
-
# Then edit .env with your actual key
|
|
342
|
+
npm install
|
|
229
343
|
\`\`\`
|
|
230
344
|
|
|
231
|
-
2. **
|
|
345
|
+
2. **Run with Ollama (default):**
|
|
232
346
|
\`\`\`bash
|
|
233
|
-
|
|
347
|
+
# Make sure Ollama is running with qwen2.5 model
|
|
348
|
+
ollama pull qwen2.5
|
|
349
|
+
npx tsx src/index.ts
|
|
234
350
|
\`\`\`
|
|
235
351
|
|
|
236
|
-
3. **
|
|
352
|
+
3. **Or use OpenAI/other providers:**
|
|
237
353
|
\`\`\`bash
|
|
354
|
+
# Edit .env and set your API key
|
|
238
355
|
npx opc run
|
|
239
356
|
\`\`\`
|
|
240
357
|
|
|
241
358
|
4. **Open browser:** [http://localhost:3000](http://localhost:3000)
|
|
242
359
|
|
|
243
|
-
##
|
|
360
|
+
## Development
|
|
244
361
|
|
|
245
362
|
\`\`\`bash
|
|
246
|
-
npx opc
|
|
363
|
+
npx opc dev # Hot-reload mode
|
|
364
|
+
npx opc chat # CLI chat
|
|
365
|
+
\`\`\`
|
|
366
|
+
|
|
367
|
+
## Project Structure
|
|
368
|
+
|
|
369
|
+
\`\`\`
|
|
370
|
+
${name}/
|
|
371
|
+
├── agent.yaml # OAD agent config (used by src/index.ts)
|
|
372
|
+
├── oad.yaml # OAD config (used by opc CLI)
|
|
373
|
+
├── src/
|
|
374
|
+
│ ├── index.ts # Entry point
|
|
375
|
+
│ └── skills/
|
|
376
|
+
│ └── echo.ts # Example skill
|
|
377
|
+
├── package.json
|
|
378
|
+
└── tsconfig.json
|
|
247
379
|
\`\`\`
|
|
248
380
|
|
|
249
381
|
## Configuration
|
|
250
382
|
|
|
251
|
-
Edit \`
|
|
383
|
+
Edit \`agent.yaml\` to customize your agent's personality, skills, and behavior.
|
|
252
384
|
`,
|
|
253
385
|
);
|
|
254
386
|
|
|
255
387
|
console.log(`\n${icon.success} Created agent project: ${color.bold(name + '/')}`);
|
|
256
|
-
console.log(` ${icon.file}
|
|
257
|
-
console.log(` ${icon.file}
|
|
258
|
-
console.log(` ${icon.file} .
|
|
259
|
-
console.log(` ${icon.file} .
|
|
388
|
+
console.log(` ${icon.file} agent.yaml - Agent definition (OAD)`);
|
|
389
|
+
console.log(` ${icon.file} src/index.ts - Entry point`);
|
|
390
|
+
console.log(` ${icon.file} src/skills/echo.ts - Example skill`);
|
|
391
|
+
console.log(` ${icon.file} package.json - Dependencies`);
|
|
392
|
+
console.log(` ${icon.file} tsconfig.json - TypeScript config`);
|
|
393
|
+
console.log(` ${icon.file} .env.example - Environment template`);
|
|
260
394
|
console.log(` ${icon.file} .gitignore`);
|
|
261
395
|
console.log(` ${icon.file} Dockerfile`);
|
|
262
|
-
console.log(` ${icon.file} docker-compose.yml`);
|
|
263
396
|
console.log(` ${icon.file} README.md`);
|
|
264
397
|
console.log(`\n Template: ${color.cyan(template)}`);
|
|
265
398
|
console.log(`\n${color.bold('Next steps:')}`);
|
|
266
399
|
console.log(` 1. cd ${name}`);
|
|
267
|
-
console.log(` 2.
|
|
268
|
-
console.log(` 3.
|
|
269
|
-
console.log(` 4.
|
|
270
|
-
console.log(` 5. Open http://localhost:3000\n`);
|
|
400
|
+
console.log(` 2. npm install`);
|
|
401
|
+
console.log(` 3. npx tsx src/index.ts ${color.dim('# or: npx opc run')}`);
|
|
402
|
+
console.log(` 4. Open http://localhost:3000\n`);
|
|
271
403
|
});
|
|
272
404
|
|
|
273
405
|
// ── Chat command ─────────────────────────────────────────────
|
|
@@ -721,7 +853,7 @@ kbCmd.command('clear').action(() => {
|
|
|
721
853
|
console.log(`${icon.success} Knowledge base cleared.`);
|
|
722
854
|
});
|
|
723
855
|
|
|
724
|
-
// 📦
|
|
856
|
+
// 📦 Package commands ───────────────────────────────────
|
|
725
857
|
|
|
726
858
|
program
|
|
727
859
|
.command('publish')
|
|
@@ -729,23 +861,8 @@ program
|
|
|
729
861
|
.option('-f, --file <file>', 'OAD file', 'oad.yaml')
|
|
730
862
|
.option('-o, --output <dir>', 'Output directory', '.')
|
|
731
863
|
.option('--include-kb', 'Include knowledge base')
|
|
732
|
-
.action(async (
|
|
733
|
-
|
|
734
|
-
console.log(`\n${icon.package} Packaging agent...\n`);
|
|
735
|
-
const result = await publishAgent({
|
|
736
|
-
oadPath: opts.file,
|
|
737
|
-
outputDir: opts.output,
|
|
738
|
-
includeKnowledge: opts.includeKb,
|
|
739
|
-
});
|
|
740
|
-
console.log(`${icon.success} Published: ${color.bold(result.archivePath)}`);
|
|
741
|
-
console.log(` Name: ${result.manifest.name}`);
|
|
742
|
-
console.log(` Version: ${result.manifest.version}`);
|
|
743
|
-
console.log(` Files: ${result.manifest.files.length}`);
|
|
744
|
-
console.log();
|
|
745
|
-
} catch (err) {
|
|
746
|
-
console.error(`${icon.error} Publish failed:`, err instanceof Error ? err.message : err);
|
|
747
|
-
process.exit(1);
|
|
748
|
-
}
|
|
864
|
+
.action(async () => {
|
|
865
|
+
console.log(`\n${icon.package} Agent packaging coming soon.\n`);
|
|
749
866
|
});
|
|
750
867
|
|
|
751
868
|
program
|
|
@@ -753,19 +870,8 @@ program
|
|
|
753
870
|
.description('Install agent from package')
|
|
754
871
|
.argument('<source>', 'Package file path or URL')
|
|
755
872
|
.option('-d, --dir <dir>', 'Install directory')
|
|
756
|
-
.action(async (
|
|
757
|
-
|
|
758
|
-
console.log(`\n${icon.package} Installing agent from ${color.bold(source)}...\n`);
|
|
759
|
-
const result = await installAgent({ source, targetDir: opts.dir });
|
|
760
|
-
console.log(`${icon.success} Installed: ${color.bold(result.manifest.name)} v${result.manifest.version}`);
|
|
761
|
-
console.log(` Directory: ${result.dir}`);
|
|
762
|
-
console.log(`\n${color.bold('Next steps:')}`);
|
|
763
|
-
console.log(` cd ${result.dir}`);
|
|
764
|
-
console.log(` opc run\n`);
|
|
765
|
-
} catch (err) {
|
|
766
|
-
console.error(`${icon.error} Install failed:`, err instanceof Error ? err.message : err);
|
|
767
|
-
process.exit(1);
|
|
768
|
-
}
|
|
873
|
+
.action(async () => {
|
|
874
|
+
console.log(`\n${icon.package} Agent install coming soon.\n`);
|
|
769
875
|
});
|
|
770
876
|
|
|
771
877
|
// 🔌 Plugin commands ────────────────────────────────────────
|
|
@@ -873,4 +979,122 @@ program
|
|
|
873
979
|
}
|
|
874
980
|
});
|
|
875
981
|
|
|
982
|
+
// ── Brain command ────────────────────────────────────────────
|
|
983
|
+
|
|
984
|
+
program
|
|
985
|
+
.command('brain')
|
|
986
|
+
.description('Show agent memory/brain status from DeepBrain')
|
|
987
|
+
.option('--url <url>', 'DeepBrain server URL', 'http://localhost:3333')
|
|
988
|
+
.action(async (opts: { url: string }) => {
|
|
989
|
+
console.log(`\n${icon.gear} ${color.bold('DeepBrain Status')} — ${color.dim(opts.url)}\n`);
|
|
990
|
+
try {
|
|
991
|
+
const res = await fetch(`${opts.url}/api/stats`);
|
|
992
|
+
if (!res.ok) throw new Error(`HTTP ${res.status} ${res.statusText}`);
|
|
993
|
+
const stats = (await res.json()) as Record<string, any>;
|
|
994
|
+
const rows: [string, string][] = [
|
|
995
|
+
['Total Pages', String(stats.totalPages ?? stats.pages ?? '-')],
|
|
996
|
+
['Total Chunks', String(stats.totalChunks ?? stats.chunks ?? '-')],
|
|
997
|
+
['Memory Tiers', String(stats.memoryTiers ?? stats.tiers ?? '-')],
|
|
998
|
+
['Index Size', stats.indexSize ?? '-'],
|
|
999
|
+
['Last Updated', stats.lastUpdated ?? stats.updatedAt ?? '-'],
|
|
1000
|
+
];
|
|
1001
|
+
const maxKey = Math.max(...rows.map(([k]) => k.length));
|
|
1002
|
+
for (const [key, val] of rows) {
|
|
1003
|
+
console.log(` ${color.cyan(key.padEnd(maxKey))} ${val}`);
|
|
1004
|
+
}
|
|
1005
|
+
console.log();
|
|
1006
|
+
} catch (err) {
|
|
1007
|
+
const msg = err instanceof Error ? err.message : String(err);
|
|
1008
|
+
if (msg.includes('ECONNREFUSED') || msg.includes('fetch failed')) {
|
|
1009
|
+
console.log(` ${icon.warn} Cannot connect to DeepBrain at ${opts.url}`);
|
|
1010
|
+
console.log(` ${color.dim('Is the server running? Start with: deepbrain serve')}\n`);
|
|
1011
|
+
} else {
|
|
1012
|
+
console.error(` ${icon.error} ${msg}\n`);
|
|
1013
|
+
}
|
|
1014
|
+
}
|
|
1015
|
+
});
|
|
1016
|
+
|
|
1017
|
+
// ── Logs command ─────────────────────────────────────────────
|
|
1018
|
+
|
|
1019
|
+
program
|
|
1020
|
+
.command('logs')
|
|
1021
|
+
.description('Show recent agent traces')
|
|
1022
|
+
.option('-n, --limit <n>', 'Number of spans to show', '20')
|
|
1023
|
+
.option('-f, --follow', 'Keep watching for new spans')
|
|
1024
|
+
.action(async (opts: { limit: string; follow?: boolean }) => {
|
|
1025
|
+
const { TraceCollector } = await import('./traces');
|
|
1026
|
+
const collector = new TraceCollector();
|
|
1027
|
+
const limit = parseInt(opts.limit) || 20;
|
|
1028
|
+
|
|
1029
|
+
const printSpans = (spans: readonly Span[]) => {
|
|
1030
|
+
const slice = spans.slice(-limit);
|
|
1031
|
+
if (slice.length === 0) {
|
|
1032
|
+
console.log(` ${icon.info} No traces yet. Interact with the agent to generate traces.`);
|
|
1033
|
+
return;
|
|
1034
|
+
}
|
|
1035
|
+
for (const span of slice) {
|
|
1036
|
+
const duration = span.endTime
|
|
1037
|
+
? `${span.endTime.getTime() - span.startTime.getTime()}ms`
|
|
1038
|
+
: 'ongoing';
|
|
1039
|
+
const statusIcon = span.status === 'ok' ? icon.success : span.status === 'error' ? icon.error : color.dim('○');
|
|
1040
|
+
const time = span.startTime.toLocaleTimeString();
|
|
1041
|
+
console.log(` ${statusIcon} ${color.dim(time)} ${color.bold(span.name)} ${color.dim(duration)}`);
|
|
1042
|
+
}
|
|
1043
|
+
};
|
|
1044
|
+
|
|
1045
|
+
console.log(`\n${icon.gear} ${color.bold('Agent Traces')}\n`);
|
|
1046
|
+
const spans = collector.getBufferedSpans();
|
|
1047
|
+
printSpans(spans);
|
|
1048
|
+
|
|
1049
|
+
if (opts.follow) {
|
|
1050
|
+
console.log(`\n ${color.dim('Watching for new traces... (Ctrl+C to stop)')}\n`);
|
|
1051
|
+
let lastCount = spans.length;
|
|
1052
|
+
const interval = setInterval(() => {
|
|
1053
|
+
const current = collector.getBufferedSpans();
|
|
1054
|
+
if (current.length > lastCount) {
|
|
1055
|
+
const newSpans = current.slice(lastCount);
|
|
1056
|
+
printSpans(newSpans);
|
|
1057
|
+
lastCount = current.length;
|
|
1058
|
+
}
|
|
1059
|
+
}, 1000);
|
|
1060
|
+
process.on('SIGINT', () => { clearInterval(interval); process.exit(0); });
|
|
1061
|
+
} else {
|
|
1062
|
+
console.log();
|
|
1063
|
+
}
|
|
1064
|
+
});
|
|
1065
|
+
|
|
1066
|
+
// ── Score command ────────────────────────────────────────────
|
|
1067
|
+
|
|
1068
|
+
program
|
|
1069
|
+
.command('score')
|
|
1070
|
+
.description('Show agent performance score')
|
|
1071
|
+
.action(async () => {
|
|
1072
|
+
console.log(`\n${icon.gear} ${color.bold('Agent Performance Score')}\n`);
|
|
1073
|
+
try {
|
|
1074
|
+
const engine = new AnalyticsEngine('.');
|
|
1075
|
+
const stats = engine.getStats();
|
|
1076
|
+
if (!stats || stats.totalMessages === 0) {
|
|
1077
|
+
console.log(` ${icon.info} No score data yet. Run the agent first.\n`);
|
|
1078
|
+
return;
|
|
1079
|
+
}
|
|
1080
|
+
const errorRate = stats.totalMessages > 0 ? (stats.totalErrors / stats.totalMessages) : 0;
|
|
1081
|
+
const rows: [string, string][] = [
|
|
1082
|
+
['Total Messages', String(stats.totalMessages)],
|
|
1083
|
+
['Total LLM Calls', String(stats.totalLLMCalls)],
|
|
1084
|
+
['Total Tool Uses', String(stats.totalToolUses)],
|
|
1085
|
+
['Avg Response Time', `${stats.avgResponseTimeMs}ms`],
|
|
1086
|
+
['Error Rate', `${(errorRate * 100).toFixed(1)}%`],
|
|
1087
|
+
['Token Usage', `${stats.totalTokens.total} tokens (in: ${stats.totalTokens.input}, out: ${stats.totalTokens.output})`],
|
|
1088
|
+
];
|
|
1089
|
+
const maxKey = Math.max(...rows.map(([k]) => k.length));
|
|
1090
|
+
for (const [key, val] of rows) {
|
|
1091
|
+
console.log(` ${color.cyan(key.padEnd(maxKey))} ${val}`);
|
|
1092
|
+
}
|
|
1093
|
+
console.log();
|
|
1094
|
+
} catch {
|
|
1095
|
+
console.log(` ${icon.info} No score data yet. Run the agent first.\n`);
|
|
1096
|
+
}
|
|
1097
|
+
});
|
|
1098
|
+
|
|
876
1099
|
program.parse();
|
|
1100
|
+
|