opc-agent 0.8.0 → 0.9.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/dist/cli.js +45 -17
- package/dist/core/analytics-engine.d.ts +51 -0
- package/dist/core/analytics-engine.js +186 -0
- package/dist/core/cache.d.ts +47 -0
- package/dist/core/cache.js +156 -0
- package/dist/core/rate-limiter.d.ts +47 -0
- package/dist/core/rate-limiter.js +92 -0
- package/dist/i18n/index.d.ts +6 -1
- package/dist/i18n/index.js +86 -0
- package/dist/index.d.ts +10 -0
- package/dist/index.js +18 -1
- package/dist/templates/data-analyst.d.ts +53 -0
- package/dist/templates/data-analyst.js +70 -0
- package/dist/templates/teacher.d.ts +58 -0
- package/dist/templates/teacher.js +78 -0
- package/dist/testing/index.d.ts +37 -0
- package/dist/testing/index.js +176 -0
- package/docs/.vitepress/config.ts +92 -0
- package/docs/api/cli.md +48 -0
- package/docs/api/sdk.md +80 -0
- package/docs/guide/configuration.md +79 -0
- package/docs/guide/deployment.md +42 -0
- package/docs/guide/testing.md +84 -0
- package/docs/index.md +27 -0
- package/docs/zh/api/oad-schema.md +3 -0
- package/docs/zh/guide/concepts.md +28 -0
- package/docs/zh/guide/configuration.md +39 -0
- package/docs/zh/guide/deployment.md +3 -0
- package/docs/zh/guide/getting-started.md +58 -0
- package/docs/zh/guide/templates.md +22 -0
- package/docs/zh/guide/testing.md +18 -0
- package/docs/zh/index.md +27 -0
- package/package.json +7 -3
- package/src/cli.ts +45 -19
- package/src/core/analytics-engine.ts +186 -0
- package/src/core/cache.ts +141 -0
- package/src/core/rate-limiter.ts +128 -0
- package/src/i18n/index.ts +87 -1
- package/src/index.ts +12 -0
- package/src/templates/data-analyst.ts +70 -0
- package/src/templates/teacher.ts +79 -0
- package/src/testing/index.ts +181 -0
|
@@ -0,0 +1,176 @@
|
|
|
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
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
36
|
+
exports.loadTestCases = loadTestCases;
|
|
37
|
+
exports.runTests = runTests;
|
|
38
|
+
exports.formatReport = formatReport;
|
|
39
|
+
/**
|
|
40
|
+
* Agent Testing Framework - Define test cases in OAD, run with `opc test`.
|
|
41
|
+
* Supports assertions on response content, tool calls, and latency.
|
|
42
|
+
*/
|
|
43
|
+
const fs = __importStar(require("fs"));
|
|
44
|
+
const path = __importStar(require("path"));
|
|
45
|
+
const yaml = __importStar(require("js-yaml"));
|
|
46
|
+
const runtime_1 = require("../core/runtime");
|
|
47
|
+
/**
|
|
48
|
+
* Load test cases from OAD spec.testing or a separate test file.
|
|
49
|
+
*/
|
|
50
|
+
function loadTestCases(oadPath) {
|
|
51
|
+
const raw = fs.readFileSync(oadPath, 'utf-8');
|
|
52
|
+
const config = yaml.load(raw);
|
|
53
|
+
// Check spec.testing.cases
|
|
54
|
+
if (config?.spec?.testing?.cases) {
|
|
55
|
+
return config.spec.testing.cases;
|
|
56
|
+
}
|
|
57
|
+
// Check for companion test file
|
|
58
|
+
const dir = path.dirname(oadPath);
|
|
59
|
+
const testFile = path.join(dir, 'tests.yaml');
|
|
60
|
+
if (fs.existsSync(testFile)) {
|
|
61
|
+
const testRaw = fs.readFileSync(testFile, 'utf-8');
|
|
62
|
+
const testConfig = yaml.load(testRaw);
|
|
63
|
+
return testConfig?.cases ?? testConfig ?? [];
|
|
64
|
+
}
|
|
65
|
+
return [];
|
|
66
|
+
}
|
|
67
|
+
/**
|
|
68
|
+
* Run all test cases against an agent.
|
|
69
|
+
*/
|
|
70
|
+
async function runTests(oadPath) {
|
|
71
|
+
const cases = loadTestCases(oadPath);
|
|
72
|
+
const results = [];
|
|
73
|
+
const startTime = Date.now();
|
|
74
|
+
if (cases.length === 0) {
|
|
75
|
+
// Generate default smoke test
|
|
76
|
+
cases.push({
|
|
77
|
+
name: 'smoke-test',
|
|
78
|
+
input: 'Hello! What can you help me with?',
|
|
79
|
+
expect: { maxLatencyMs: 30000 },
|
|
80
|
+
});
|
|
81
|
+
}
|
|
82
|
+
const runtime = new runtime_1.AgentRuntime();
|
|
83
|
+
await runtime.loadConfig(oadPath);
|
|
84
|
+
const agent = await runtime.initialize();
|
|
85
|
+
for (const tc of cases) {
|
|
86
|
+
const result = {
|
|
87
|
+
name: tc.name,
|
|
88
|
+
passed: true,
|
|
89
|
+
durationMs: 0,
|
|
90
|
+
failures: [],
|
|
91
|
+
};
|
|
92
|
+
const t0 = Date.now();
|
|
93
|
+
try {
|
|
94
|
+
const response = await agent.handleMessage({
|
|
95
|
+
id: `test_${Date.now()}`,
|
|
96
|
+
role: 'user',
|
|
97
|
+
content: tc.input,
|
|
98
|
+
timestamp: Date.now(),
|
|
99
|
+
});
|
|
100
|
+
result.durationMs = Date.now() - t0;
|
|
101
|
+
result.response = response.content;
|
|
102
|
+
if (tc.expect) {
|
|
103
|
+
// Check contains
|
|
104
|
+
if (tc.expect.contains) {
|
|
105
|
+
for (const s of tc.expect.contains) {
|
|
106
|
+
if (!response.content.toLowerCase().includes(s.toLowerCase())) {
|
|
107
|
+
result.failures.push(`Expected response to contain "${s}"`);
|
|
108
|
+
}
|
|
109
|
+
}
|
|
110
|
+
}
|
|
111
|
+
// Check notContains
|
|
112
|
+
if (tc.expect.notContains) {
|
|
113
|
+
for (const s of tc.expect.notContains) {
|
|
114
|
+
if (response.content.toLowerCase().includes(s.toLowerCase())) {
|
|
115
|
+
result.failures.push(`Expected response NOT to contain "${s}"`);
|
|
116
|
+
}
|
|
117
|
+
}
|
|
118
|
+
}
|
|
119
|
+
// Check latency
|
|
120
|
+
if (tc.expect.maxLatencyMs && result.durationMs > tc.expect.maxLatencyMs) {
|
|
121
|
+
result.failures.push(`Latency ${result.durationMs}ms exceeded max ${tc.expect.maxLatencyMs}ms`);
|
|
122
|
+
}
|
|
123
|
+
// Check tool calls (from metadata if available)
|
|
124
|
+
if (tc.expect.toolCalled && response.toolsCalled) {
|
|
125
|
+
for (const tool of tc.expect.toolCalled) {
|
|
126
|
+
if (!response.toolsCalled.includes(tool)) {
|
|
127
|
+
result.failures.push(`Expected tool "${tool}" to be called`);
|
|
128
|
+
}
|
|
129
|
+
}
|
|
130
|
+
}
|
|
131
|
+
}
|
|
132
|
+
result.passed = result.failures.length === 0;
|
|
133
|
+
}
|
|
134
|
+
catch (err) {
|
|
135
|
+
result.durationMs = Date.now() - t0;
|
|
136
|
+
result.passed = false;
|
|
137
|
+
result.failures.push(`Error: ${err instanceof Error ? err.message : String(err)}`);
|
|
138
|
+
}
|
|
139
|
+
results.push(result);
|
|
140
|
+
}
|
|
141
|
+
const totalDuration = Date.now() - startTime;
|
|
142
|
+
const passed = results.filter(r => r.passed).length;
|
|
143
|
+
return {
|
|
144
|
+
total: results.length,
|
|
145
|
+
passed,
|
|
146
|
+
failed: results.length - passed,
|
|
147
|
+
duration: totalDuration,
|
|
148
|
+
results,
|
|
149
|
+
};
|
|
150
|
+
}
|
|
151
|
+
/**
|
|
152
|
+
* Format test report for console output.
|
|
153
|
+
*/
|
|
154
|
+
function formatReport(report) {
|
|
155
|
+
const lines = [];
|
|
156
|
+
lines.push('');
|
|
157
|
+
lines.push('═══════════════════════════════════════════');
|
|
158
|
+
lines.push(' OPC Agent Test Report');
|
|
159
|
+
lines.push('═══════════════════════════════════════════');
|
|
160
|
+
lines.push('');
|
|
161
|
+
for (const r of report.results) {
|
|
162
|
+
const icon = r.passed ? '✔' : '✘';
|
|
163
|
+
const status = r.passed ? 'PASS' : 'FAIL';
|
|
164
|
+
lines.push(` ${icon} [${status}] ${r.name} (${r.durationMs}ms)`);
|
|
165
|
+
for (const f of r.failures) {
|
|
166
|
+
lines.push(` → ${f}`);
|
|
167
|
+
}
|
|
168
|
+
}
|
|
169
|
+
lines.push('');
|
|
170
|
+
lines.push('───────────────────────────────────────────');
|
|
171
|
+
lines.push(` Total: ${report.total} Passed: ${report.passed} Failed: ${report.failed} Duration: ${report.duration}ms`);
|
|
172
|
+
lines.push('───────────────────────────────────────────');
|
|
173
|
+
lines.push('');
|
|
174
|
+
return lines.join('\n');
|
|
175
|
+
}
|
|
176
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1,92 @@
|
|
|
1
|
+
import { defineConfig } from 'vitepress';
|
|
2
|
+
|
|
3
|
+
export default defineConfig({
|
|
4
|
+
title: 'OPC Agent',
|
|
5
|
+
description: 'Open Agent Framework - Build, test, and run AI Agents for business workstations',
|
|
6
|
+
|
|
7
|
+
locales: {
|
|
8
|
+
root: {
|
|
9
|
+
label: 'English',
|
|
10
|
+
lang: 'en',
|
|
11
|
+
themeConfig: {
|
|
12
|
+
nav: [
|
|
13
|
+
{ text: 'Guide', link: '/guide/getting-started' },
|
|
14
|
+
{ text: 'API', link: '/api/oad-schema' },
|
|
15
|
+
{ text: 'GitHub', link: 'https://github.com/Deepleaper/opc-agent' },
|
|
16
|
+
],
|
|
17
|
+
sidebar: {
|
|
18
|
+
'/guide/': [
|
|
19
|
+
{
|
|
20
|
+
text: 'Introduction',
|
|
21
|
+
items: [
|
|
22
|
+
{ text: 'Getting Started', link: '/guide/getting-started' },
|
|
23
|
+
{ text: 'Core Concepts', link: '/guide/concepts' },
|
|
24
|
+
],
|
|
25
|
+
},
|
|
26
|
+
{
|
|
27
|
+
text: 'Usage',
|
|
28
|
+
items: [
|
|
29
|
+
{ text: 'Templates', link: '/guide/templates' },
|
|
30
|
+
{ text: 'Configuration', link: '/guide/configuration' },
|
|
31
|
+
{ text: 'Testing', link: '/guide/testing' },
|
|
32
|
+
{ text: 'Deployment', link: '/guide/deployment' },
|
|
33
|
+
],
|
|
34
|
+
},
|
|
35
|
+
],
|
|
36
|
+
'/api/': [
|
|
37
|
+
{
|
|
38
|
+
text: 'Reference',
|
|
39
|
+
items: [
|
|
40
|
+
{ text: 'OAD Schema', link: '/api/oad-schema' },
|
|
41
|
+
{ text: 'CLI Commands', link: '/api/cli' },
|
|
42
|
+
{ text: 'SDK', link: '/api/sdk' },
|
|
43
|
+
],
|
|
44
|
+
},
|
|
45
|
+
],
|
|
46
|
+
},
|
|
47
|
+
},
|
|
48
|
+
},
|
|
49
|
+
zh: {
|
|
50
|
+
label: '中文',
|
|
51
|
+
lang: 'zh-CN',
|
|
52
|
+
themeConfig: {
|
|
53
|
+
nav: [
|
|
54
|
+
{ text: '指南', link: '/zh/guide/getting-started' },
|
|
55
|
+
{ text: 'API', link: '/zh/api/oad-schema' },
|
|
56
|
+
{ text: 'GitHub', link: 'https://github.com/Deepleaper/opc-agent' },
|
|
57
|
+
],
|
|
58
|
+
sidebar: {
|
|
59
|
+
'/zh/guide/': [
|
|
60
|
+
{
|
|
61
|
+
text: '介绍',
|
|
62
|
+
items: [
|
|
63
|
+
{ text: '快速开始', link: '/zh/guide/getting-started' },
|
|
64
|
+
{ text: '核心概念', link: '/zh/guide/concepts' },
|
|
65
|
+
],
|
|
66
|
+
},
|
|
67
|
+
{
|
|
68
|
+
text: '使用',
|
|
69
|
+
items: [
|
|
70
|
+
{ text: '模板', link: '/zh/guide/templates' },
|
|
71
|
+
{ text: '配置', link: '/zh/guide/configuration' },
|
|
72
|
+
{ text: '测试', link: '/zh/guide/testing' },
|
|
73
|
+
{ text: '部署', link: '/zh/guide/deployment' },
|
|
74
|
+
],
|
|
75
|
+
},
|
|
76
|
+
],
|
|
77
|
+
},
|
|
78
|
+
},
|
|
79
|
+
},
|
|
80
|
+
},
|
|
81
|
+
|
|
82
|
+
themeConfig: {
|
|
83
|
+
logo: '/logo.svg',
|
|
84
|
+
socialLinks: [
|
|
85
|
+
{ icon: 'github', link: 'https://github.com/Deepleaper/opc-agent' },
|
|
86
|
+
],
|
|
87
|
+
footer: {
|
|
88
|
+
message: 'Released under the Apache-2.0 License.',
|
|
89
|
+
copyright: 'Copyright © 2025 Deepleaper',
|
|
90
|
+
},
|
|
91
|
+
},
|
|
92
|
+
});
|
package/docs/api/cli.md
ADDED
|
@@ -0,0 +1,48 @@
|
|
|
1
|
+
# CLI Commands
|
|
2
|
+
|
|
3
|
+
## Reference
|
|
4
|
+
|
|
5
|
+
| Command | Description |
|
|
6
|
+
|---------|-------------|
|
|
7
|
+
| `opc init [name]` | Initialize a new agent project |
|
|
8
|
+
| `opc run` | Start agent with web server |
|
|
9
|
+
| `opc chat` | Interactive CLI chat |
|
|
10
|
+
| `opc test` | Run agent tests |
|
|
11
|
+
| `opc analytics` | Show usage analytics |
|
|
12
|
+
| `opc info` | Show agent info from OAD |
|
|
13
|
+
| `opc build` | Validate OAD |
|
|
14
|
+
| `opc dev` | Hot-reload development mode |
|
|
15
|
+
| `opc create <name>` | Create agent from template |
|
|
16
|
+
| `opc deploy` | Deploy to OpenClaw or Hermes |
|
|
17
|
+
| `opc publish` | Package for distribution |
|
|
18
|
+
| `opc install <source>` | Install agent from package |
|
|
19
|
+
| `opc search <query>` | Search OPC Registry |
|
|
20
|
+
| `opc stats` | Show runtime stats |
|
|
21
|
+
| `opc kb add <file>` | Add file to knowledge base |
|
|
22
|
+
| `opc kb search <query>` | Search knowledge base |
|
|
23
|
+
| `opc tool list` | List MCP tools |
|
|
24
|
+
| `opc workflow run <name>` | Run a workflow |
|
|
25
|
+
| `opc version-mgmt list` | List saved versions |
|
|
26
|
+
|
|
27
|
+
## Common Options
|
|
28
|
+
|
|
29
|
+
- `-f, --file <file>` — OAD file path (default: `oad.yaml`)
|
|
30
|
+
- `-t, --template <name>` — Template name
|
|
31
|
+
- `-p, --port <port>` — Port override
|
|
32
|
+
- `--json` — JSON output (for test/analytics)
|
|
33
|
+
|
|
34
|
+
## Examples
|
|
35
|
+
|
|
36
|
+
```bash
|
|
37
|
+
# Create a new project
|
|
38
|
+
opc init my-bot -t teacher
|
|
39
|
+
|
|
40
|
+
# Run tests
|
|
41
|
+
opc test --json
|
|
42
|
+
|
|
43
|
+
# View analytics
|
|
44
|
+
opc analytics
|
|
45
|
+
|
|
46
|
+
# Deploy
|
|
47
|
+
opc deploy --target openclaw --install
|
|
48
|
+
```
|
package/docs/api/sdk.md
ADDED
|
@@ -0,0 +1,80 @@
|
|
|
1
|
+
# SDK Reference
|
|
2
|
+
|
|
3
|
+
## Core Classes
|
|
4
|
+
|
|
5
|
+
### AgentRuntime
|
|
6
|
+
|
|
7
|
+
```typescript
|
|
8
|
+
import { AgentRuntime } from 'opc-agent';
|
|
9
|
+
|
|
10
|
+
const runtime = new AgentRuntime();
|
|
11
|
+
await runtime.loadConfig('oad.yaml');
|
|
12
|
+
const agent = await runtime.initialize();
|
|
13
|
+
await runtime.start();
|
|
14
|
+
```
|
|
15
|
+
|
|
16
|
+
### AnalyticsEngine
|
|
17
|
+
|
|
18
|
+
```typescript
|
|
19
|
+
import { AnalyticsEngine } from 'opc-agent';
|
|
20
|
+
|
|
21
|
+
const engine = new AnalyticsEngine('.');
|
|
22
|
+
engine.trackMessage('user-1', 250, 100, 50);
|
|
23
|
+
engine.trackToolUse('search', true, 120);
|
|
24
|
+
const stats = engine.getStats();
|
|
25
|
+
```
|
|
26
|
+
|
|
27
|
+
### RateLimiter
|
|
28
|
+
|
|
29
|
+
```typescript
|
|
30
|
+
import { RateLimiter } from 'opc-agent';
|
|
31
|
+
|
|
32
|
+
const limiter = new RateLimiter({
|
|
33
|
+
userLimit: { maxRequests: 60, windowMs: 60000 },
|
|
34
|
+
providerLimit: { maxRequests: 100, windowMs: 60000 },
|
|
35
|
+
});
|
|
36
|
+
|
|
37
|
+
await limiter.acquire('user-1', 'openai');
|
|
38
|
+
```
|
|
39
|
+
|
|
40
|
+
### LLMCache
|
|
41
|
+
|
|
42
|
+
```typescript
|
|
43
|
+
import { LLMCache } from 'opc-agent';
|
|
44
|
+
|
|
45
|
+
const cache = new LLMCache({ ttlMs: 3600000 });
|
|
46
|
+
const key = LLMCache.makeKey(messages, systemPrompt);
|
|
47
|
+
const cached = cache.get(key);
|
|
48
|
+
if (!cached) {
|
|
49
|
+
const response = await callLLM(messages);
|
|
50
|
+
cache.set(key, response);
|
|
51
|
+
}
|
|
52
|
+
```
|
|
53
|
+
|
|
54
|
+
### Testing
|
|
55
|
+
|
|
56
|
+
```typescript
|
|
57
|
+
import { runTests, formatReport } from 'opc-agent';
|
|
58
|
+
|
|
59
|
+
const report = await runTests('oad.yaml');
|
|
60
|
+
console.log(formatReport(report));
|
|
61
|
+
```
|
|
62
|
+
|
|
63
|
+
## Templates
|
|
64
|
+
|
|
65
|
+
13 built-in templates:
|
|
66
|
+
|
|
67
|
+
| Template | Description |
|
|
68
|
+
|----------|-------------|
|
|
69
|
+
| `customer-service` | FAQ + human handoff |
|
|
70
|
+
| `sales-assistant` | Product Q&A + lead capture |
|
|
71
|
+
| `knowledge-base` | RAG with DeepBrain |
|
|
72
|
+
| `code-reviewer` | Bug detection + style checks |
|
|
73
|
+
| `hr-recruiter` | Resume screening + interviews |
|
|
74
|
+
| `project-manager` | Task tracking + meeting notes |
|
|
75
|
+
| `content-writer` | Blog + social media + SEO |
|
|
76
|
+
| `legal-assistant` | Contract review + compliance |
|
|
77
|
+
| `financial-advisor` | Budget + expense tracking |
|
|
78
|
+
| `executive-assistant` | Calendar + email + meetings |
|
|
79
|
+
| `data-analyst` | Data querying + visualization |
|
|
80
|
+
| `teacher` | Lesson plans + quizzes |
|
|
@@ -0,0 +1,79 @@
|
|
|
1
|
+
# Configuration
|
|
2
|
+
|
|
3
|
+
## OAD File Structure
|
|
4
|
+
|
|
5
|
+
The `oad.yaml` file is the heart of your agent configuration:
|
|
6
|
+
|
|
7
|
+
```yaml
|
|
8
|
+
apiVersion: opc/v1
|
|
9
|
+
kind: Agent
|
|
10
|
+
metadata:
|
|
11
|
+
name: my-agent
|
|
12
|
+
version: 1.0.0
|
|
13
|
+
description: My AI agent
|
|
14
|
+
spec:
|
|
15
|
+
provider:
|
|
16
|
+
default: openai
|
|
17
|
+
allowed: [openai, deepseek, qwen]
|
|
18
|
+
model: gpt-4o-mini
|
|
19
|
+
systemPrompt: "You are a helpful assistant."
|
|
20
|
+
skills: []
|
|
21
|
+
channels:
|
|
22
|
+
- type: web
|
|
23
|
+
port: 3000
|
|
24
|
+
memory:
|
|
25
|
+
shortTerm: true
|
|
26
|
+
longTerm: false
|
|
27
|
+
testing:
|
|
28
|
+
cases:
|
|
29
|
+
- name: greeting-test
|
|
30
|
+
input: "Hello"
|
|
31
|
+
expect:
|
|
32
|
+
contains: ["hello", "help"]
|
|
33
|
+
maxLatencyMs: 5000
|
|
34
|
+
rateLimits:
|
|
35
|
+
perUser:
|
|
36
|
+
maxRequests: 60
|
|
37
|
+
windowMs: 60000
|
|
38
|
+
perProvider:
|
|
39
|
+
maxRequests: 100
|
|
40
|
+
windowMs: 60000
|
|
41
|
+
cache:
|
|
42
|
+
enabled: true
|
|
43
|
+
ttlMs: 3600000
|
|
44
|
+
```
|
|
45
|
+
|
|
46
|
+
## Environment Variables
|
|
47
|
+
|
|
48
|
+
| Variable | Description | Default |
|
|
49
|
+
|----------|-------------|---------|
|
|
50
|
+
| `OPC_LLM_API_KEY` | LLM API key | — |
|
|
51
|
+
| `OPC_LLM_BASE_URL` | LLM API base URL | `https://api.openai.com/v1` |
|
|
52
|
+
| `OPC_LLM_MODEL` | Model name | `gpt-4o-mini` |
|
|
53
|
+
|
|
54
|
+
## Rate Limiting
|
|
55
|
+
|
|
56
|
+
Configure per-user and per-provider rate limits in `oad.yaml`:
|
|
57
|
+
|
|
58
|
+
```yaml
|
|
59
|
+
spec:
|
|
60
|
+
rateLimits:
|
|
61
|
+
perUser:
|
|
62
|
+
maxRequests: 60
|
|
63
|
+
windowMs: 60000
|
|
64
|
+
perProvider:
|
|
65
|
+
maxRequests: 100
|
|
66
|
+
windowMs: 60000
|
|
67
|
+
```
|
|
68
|
+
|
|
69
|
+
## Caching
|
|
70
|
+
|
|
71
|
+
Enable LLM response caching to reduce API costs:
|
|
72
|
+
|
|
73
|
+
```yaml
|
|
74
|
+
spec:
|
|
75
|
+
cache:
|
|
76
|
+
enabled: true
|
|
77
|
+
ttlMs: 3600000 # 1 hour
|
|
78
|
+
maxEntries: 1000
|
|
79
|
+
```
|
|
@@ -0,0 +1,42 @@
|
|
|
1
|
+
# Deployment
|
|
2
|
+
|
|
3
|
+
## Docker
|
|
4
|
+
|
|
5
|
+
Every `opc init` project includes a `Dockerfile` and `docker-compose.yml`:
|
|
6
|
+
|
|
7
|
+
```bash
|
|
8
|
+
docker compose up -d
|
|
9
|
+
```
|
|
10
|
+
|
|
11
|
+
## Deploy to OpenClaw
|
|
12
|
+
|
|
13
|
+
```bash
|
|
14
|
+
opc deploy --target openclaw
|
|
15
|
+
opc deploy --target openclaw --install # Also register in config
|
|
16
|
+
```
|
|
17
|
+
|
|
18
|
+
## Deploy to Hermes
|
|
19
|
+
|
|
20
|
+
```bash
|
|
21
|
+
opc deploy --target hermes
|
|
22
|
+
opc deploy --target hermes --output ./my-hermes-deploy
|
|
23
|
+
```
|
|
24
|
+
|
|
25
|
+
## Environment Variables
|
|
26
|
+
|
|
27
|
+
Set your API keys in `.env`:
|
|
28
|
+
|
|
29
|
+
```bash
|
|
30
|
+
OPC_LLM_API_KEY=sk-xxx
|
|
31
|
+
OPC_LLM_BASE_URL=https://api.openai.com/v1
|
|
32
|
+
OPC_LLM_MODEL=gpt-4o-mini
|
|
33
|
+
```
|
|
34
|
+
|
|
35
|
+
## Production Checklist
|
|
36
|
+
|
|
37
|
+
- [ ] Set proper API keys in `.env`
|
|
38
|
+
- [ ] Configure rate limits in `oad.yaml`
|
|
39
|
+
- [ ] Enable caching for cost reduction
|
|
40
|
+
- [ ] Set up analytics monitoring
|
|
41
|
+
- [ ] Run `opc test` before deployment
|
|
42
|
+
- [ ] Review trust/DTV settings
|
|
@@ -0,0 +1,84 @@
|
|
|
1
|
+
# Testing
|
|
2
|
+
|
|
3
|
+
## Overview
|
|
4
|
+
|
|
5
|
+
OPC Agent includes a built-in testing framework. Define test cases in your `oad.yaml` or a separate `tests.yaml` file, then run them with `opc test`.
|
|
6
|
+
|
|
7
|
+
## Defining Tests in OAD
|
|
8
|
+
|
|
9
|
+
```yaml
|
|
10
|
+
spec:
|
|
11
|
+
testing:
|
|
12
|
+
cases:
|
|
13
|
+
- name: greeting
|
|
14
|
+
input: "Hello!"
|
|
15
|
+
expect:
|
|
16
|
+
contains: ["hello", "help"]
|
|
17
|
+
maxLatencyMs: 5000
|
|
18
|
+
|
|
19
|
+
- name: product-question
|
|
20
|
+
input: "What are your pricing plans?"
|
|
21
|
+
expect:
|
|
22
|
+
contains: ["pricing", "plan"]
|
|
23
|
+
notContains: ["error"]
|
|
24
|
+
|
|
25
|
+
- name: edge-case-empty
|
|
26
|
+
input: ""
|
|
27
|
+
expect:
|
|
28
|
+
maxLatencyMs: 2000
|
|
29
|
+
```
|
|
30
|
+
|
|
31
|
+
## Separate Test File
|
|
32
|
+
|
|
33
|
+
Create `tests.yaml` alongside your `oad.yaml`:
|
|
34
|
+
|
|
35
|
+
```yaml
|
|
36
|
+
cases:
|
|
37
|
+
- name: smoke-test
|
|
38
|
+
input: "Hi there"
|
|
39
|
+
expect:
|
|
40
|
+
maxLatencyMs: 10000
|
|
41
|
+
- name: faq-check
|
|
42
|
+
input: "What is your return policy?"
|
|
43
|
+
expect:
|
|
44
|
+
contains: ["return", "refund"]
|
|
45
|
+
```
|
|
46
|
+
|
|
47
|
+
## Running Tests
|
|
48
|
+
|
|
49
|
+
```bash
|
|
50
|
+
# Run tests
|
|
51
|
+
opc test
|
|
52
|
+
|
|
53
|
+
# JSON output
|
|
54
|
+
opc test --json
|
|
55
|
+
|
|
56
|
+
# Custom OAD file
|
|
57
|
+
opc test -f my-agent.yaml
|
|
58
|
+
```
|
|
59
|
+
|
|
60
|
+
## Test Report
|
|
61
|
+
|
|
62
|
+
```
|
|
63
|
+
═══════════════════════════════════════════
|
|
64
|
+
OPC Agent Test Report
|
|
65
|
+
═══════════════════════════════════════════
|
|
66
|
+
|
|
67
|
+
✔ [PASS] greeting (245ms)
|
|
68
|
+
✔ [PASS] product-question (312ms)
|
|
69
|
+
✘ [FAIL] edge-case (5120ms)
|
|
70
|
+
→ Latency 5120ms exceeded max 2000ms
|
|
71
|
+
|
|
72
|
+
───────────────────────────────────────────
|
|
73
|
+
Total: 3 Passed: 2 Failed: 1 Duration: 5677ms
|
|
74
|
+
───────────────────────────────────────────
|
|
75
|
+
```
|
|
76
|
+
|
|
77
|
+
## Assertions
|
|
78
|
+
|
|
79
|
+
| Assertion | Description |
|
|
80
|
+
|-----------|-------------|
|
|
81
|
+
| `contains` | Response must include these strings (case-insensitive) |
|
|
82
|
+
| `notContains` | Response must NOT include these strings |
|
|
83
|
+
| `toolCalled` | Specified tools must have been invoked |
|
|
84
|
+
| `maxLatencyMs` | Response must complete within this time |
|
package/docs/index.md
ADDED
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
---
|
|
2
|
+
layout: home
|
|
3
|
+
hero:
|
|
4
|
+
name: OPC Agent
|
|
5
|
+
text: Open Agent Framework
|
|
6
|
+
tagline: Build, test, and run AI Agents for business workstations
|
|
7
|
+
actions:
|
|
8
|
+
- theme: brand
|
|
9
|
+
text: Get Started
|
|
10
|
+
link: /guide/getting-started
|
|
11
|
+
- theme: alt
|
|
12
|
+
text: View on GitHub
|
|
13
|
+
link: https://github.com/Deepleaper/opc-agent
|
|
14
|
+
features:
|
|
15
|
+
- title: 🚀 Quick Start
|
|
16
|
+
details: Create an agent in under 2 minutes with 13 built-in templates
|
|
17
|
+
- title: 📝 OAD Schema
|
|
18
|
+
details: Declarative YAML-based agent definition with full validation
|
|
19
|
+
- title: 🔌 Multi-Channel
|
|
20
|
+
details: Web, Telegram, Slack, WeChat, Email, Voice, WebSocket
|
|
21
|
+
- title: 🧪 Testing Framework
|
|
22
|
+
details: Define test cases in OAD, run with `opc test`, get pass/fail reports
|
|
23
|
+
- title: 📊 Analytics
|
|
24
|
+
details: Track messages, LLM calls, tool usage, and errors with built-in analytics
|
|
25
|
+
- title: 🌍 i18n
|
|
26
|
+
details: English, Chinese, and Japanese out of the box
|
|
27
|
+
---
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
# 核心概念
|
|
2
|
+
|
|
3
|
+
## OAD(Open Agent Definition)
|
|
4
|
+
|
|
5
|
+
OAD 是智能体的声明式定义文件,使用 YAML 格式。包含:
|
|
6
|
+
|
|
7
|
+
- **metadata** — 名称、版本、描述
|
|
8
|
+
- **spec** — 模型、系统提示词、技能、渠道、记忆、DTV
|
|
9
|
+
|
|
10
|
+
## 技能(Skills)
|
|
11
|
+
|
|
12
|
+
技能是智能体的能力模块,每个技能处理特定类型的用户请求。
|
|
13
|
+
|
|
14
|
+
## 渠道(Channels)
|
|
15
|
+
|
|
16
|
+
渠道定义智能体与用户交互的方式:Web、Telegram、Slack、微信等。
|
|
17
|
+
|
|
18
|
+
## DTV(Data-Trust-Value)
|
|
19
|
+
|
|
20
|
+
DTV 框架确保智能体的数据安全、信任级别和价值追踪。
|
|
21
|
+
|
|
22
|
+
## 测试
|
|
23
|
+
|
|
24
|
+
在 OAD 中定义测试用例,使用 `opc test` 运行自动化测试。
|
|
25
|
+
|
|
26
|
+
## 缓存与限流
|
|
27
|
+
|
|
28
|
+
内置 LLM 响应缓存和多级限流,降低 API 成本,保护服务稳定性。
|