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.
- package/CHANGELOG.md +69 -23
- package/CONTRIBUTING.md +60 -21
- package/README.md +358 -235
- package/README.zh-CN.md +415 -415
- package/dist/channels/slack.js +10 -93
- package/dist/channels/web.d.ts +0 -10
- package/dist/channels/web.js +2 -33
- package/dist/cli.js +60 -255
- package/dist/core/dashboard.d.ts +35 -0
- package/dist/core/dashboard.js +157 -0
- package/dist/core/fast-mode.d.ts +27 -0
- package/dist/core/fast-mode.js +59 -0
- package/dist/core/priority.d.ts +52 -0
- package/dist/core/priority.js +102 -0
- package/dist/core/runtime.d.ts +0 -4
- package/dist/core/runtime.js +0 -27
- package/dist/deploy/hermes.js +22 -22
- package/dist/deploy/openclaw.js +40 -31
- package/dist/index.d.ts +14 -3
- package/dist/index.js +20 -6
- package/dist/memory/cloud-storage.d.ts +40 -0
- package/dist/memory/cloud-storage.js +211 -0
- package/dist/providers/index.d.ts +1 -1
- package/dist/providers/index.js +1 -7
- package/dist/schema/oad.d.ts +2 -1
- package/dist/templates/code-reviewer.d.ts +8 -0
- package/dist/templates/code-reviewer.js +9 -5
- package/dist/templates/customer-service.d.ts +8 -0
- package/dist/templates/customer-service.js +6 -2
- package/dist/templates/data-analyst.d.ts +8 -0
- package/dist/templates/data-analyst.js +9 -5
- package/dist/templates/knowledge-base.d.ts +8 -0
- package/dist/templates/knowledge-base.js +6 -2
- package/dist/templates/sales-assistant.d.ts +8 -0
- package/dist/templates/sales-assistant.js +8 -4
- package/dist/templates/teacher.d.ts +8 -0
- package/dist/templates/teacher.js +10 -6
- 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/customer-service-demo/README.md +90 -90
- package/examples/customer-service-demo/oad.yaml +107 -107
- 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 +160 -217
- package/src/channels/telegram.ts +90 -90
- package/src/channels/voice.ts +106 -106
- package/src/channels/web.ts +2 -38
- 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 +58 -282
- 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/dashboard.ts +219 -0
- package/src/core/errors.ts +148 -148
- package/src/core/fast-mode.ts +75 -0
- 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/priority.ts +140 -0
- package/src/core/rate-limiter.ts +128 -128
- package/src/core/room.ts +109 -109
- package/src/core/runtime.ts +152 -183
- 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 +200 -190
- package/src/dtv/data.ts +29 -0
- package/src/dtv/trust.ts +43 -0
- package/src/dtv/value.ts +47 -0
- package/src/i18n/index.ts +216 -216
- package/src/index.ts +16 -3
- package/src/marketplace/index.ts +223 -0
- package/src/memory/cloud-storage.ts +217 -0
- 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 +1 -9
- package/src/schema/oad.ts +155 -154
- 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 +34 -30
- package/src/templates/customer-service.ts +80 -76
- package/src/templates/data-analyst.ts +70 -66
- package/src/templates/executive-assistant.ts +71 -71
- package/src/templates/financial-advisor.ts +60 -60
- package/src/templates/knowledge-base.ts +31 -27
- package/src/templates/legal-assistant.ts +71 -71
- package/src/templates/sales-assistant.ts +79 -75
- package/src/templates/teacher.ts +79 -75
- 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/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/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/.github/ISSUE_TEMPLATE/bug_report.md +0 -20
- package/.github/ISSUE_TEMPLATE/feature_request.md +0 -14
- package/.github/PULL_REQUEST_TEMPLATE.md +0 -13
- package/.github/workflows/ci.yml +0 -24
- package/dist/traces/index.d.ts +0 -49
- package/dist/traces/index.js +0 -102
- package/examples/README.md +0 -22
- package/examples/basic-agent.ts +0 -90
- package/examples/brain-integration.ts +0 -71
- package/examples/multi-channel.ts +0 -74
- package/src/traces/index.ts +0 -132
- package/test-agent/Dockerfile +0 -9
- package/test-agent/README.md +0 -50
- package/test-agent/agent.yaml +0 -23
- package/test-agent/docker-compose.yml +0 -11
- package/test-agent/oad.yaml +0 -31
- package/test-agent/package-lock.json +0 -1492
- package/test-agent/package.json +0 -18
- package/test-agent/src/index.ts +0 -24
- package/test-agent/src/skills/echo.ts +0 -15
- package/test-agent/tsconfig.json +0 -25
|
@@ -0,0 +1,157 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
3
|
+
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
4
|
+
};
|
|
5
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
6
|
+
exports.Dashboard = void 0;
|
|
7
|
+
const express_1 = __importDefault(require("express"));
|
|
8
|
+
// ─── Dashboard Server ────────────────────────────────────────
|
|
9
|
+
class Dashboard {
|
|
10
|
+
app = (0, express_1.default)();
|
|
11
|
+
server = null;
|
|
12
|
+
config;
|
|
13
|
+
startTime = Date.now();
|
|
14
|
+
stats = {
|
|
15
|
+
sessions: new Map(),
|
|
16
|
+
toolInvocations: new Map(),
|
|
17
|
+
channelStats: new Map(),
|
|
18
|
+
};
|
|
19
|
+
constructor(config) {
|
|
20
|
+
this.config = {
|
|
21
|
+
enabled: config.enabled,
|
|
22
|
+
port: config.port ?? 4100,
|
|
23
|
+
host: config.host ?? '127.0.0.1',
|
|
24
|
+
cors: config.cors ?? false,
|
|
25
|
+
};
|
|
26
|
+
this.setupRoutes();
|
|
27
|
+
}
|
|
28
|
+
setupRoutes() {
|
|
29
|
+
if (this.config.cors) {
|
|
30
|
+
this.app.use((_req, res, next) => {
|
|
31
|
+
res.header('Access-Control-Allow-Origin', '*');
|
|
32
|
+
res.header('Access-Control-Allow-Headers', 'Content-Type');
|
|
33
|
+
next();
|
|
34
|
+
});
|
|
35
|
+
}
|
|
36
|
+
this.app.use(express_1.default.json());
|
|
37
|
+
// Health check
|
|
38
|
+
this.app.get('/api/health', (_req, res) => {
|
|
39
|
+
res.json({ status: 'ok', uptime: Date.now() - this.startTime });
|
|
40
|
+
});
|
|
41
|
+
// Overview state
|
|
42
|
+
this.app.get('/api/state', (_req, res) => {
|
|
43
|
+
res.json(this.getState());
|
|
44
|
+
});
|
|
45
|
+
// Sessions
|
|
46
|
+
this.app.get('/api/sessions', (_req, res) => {
|
|
47
|
+
res.json([...this.stats.sessions.values()]);
|
|
48
|
+
});
|
|
49
|
+
// Tools
|
|
50
|
+
this.app.get('/api/tools', (_req, res) => {
|
|
51
|
+
const tools = [];
|
|
52
|
+
for (const [name, stat] of this.stats.toolInvocations) {
|
|
53
|
+
tools.push({ name, type: 'builtin', enabled: true, invocations: stat.count, lastUsed: stat.lastUsed });
|
|
54
|
+
}
|
|
55
|
+
res.json(tools);
|
|
56
|
+
});
|
|
57
|
+
// Channels
|
|
58
|
+
this.app.get('/api/channels', (_req, res) => {
|
|
59
|
+
const channels = [];
|
|
60
|
+
for (const [name, stat] of this.stats.channelStats) {
|
|
61
|
+
channels.push({ name, type: name, connected: stat.connected, messageCount: stat.messages });
|
|
62
|
+
}
|
|
63
|
+
res.json(channels);
|
|
64
|
+
});
|
|
65
|
+
// Simple HTML dashboard
|
|
66
|
+
this.app.get('/', (_req, res) => {
|
|
67
|
+
res.send(this.renderHTML());
|
|
68
|
+
});
|
|
69
|
+
}
|
|
70
|
+
getState() {
|
|
71
|
+
return {
|
|
72
|
+
agent: { name: 'opc-agent', version: '1.3.0', status: 'running', uptime: Date.now() - this.startTime },
|
|
73
|
+
sessions: [...this.stats.sessions.values()],
|
|
74
|
+
tools: [...this.stats.toolInvocations.entries()].map(([name, s]) => ({
|
|
75
|
+
name, type: 'builtin', enabled: true, invocations: s.count, lastUsed: s.lastUsed,
|
|
76
|
+
})),
|
|
77
|
+
channels: [...this.stats.channelStats.entries()].map(([name, s]) => ({
|
|
78
|
+
name, type: name, connected: s.connected, messageCount: s.messages,
|
|
79
|
+
})),
|
|
80
|
+
memory: { provider: 'unknown', entries: 0 },
|
|
81
|
+
modelAuth: { providers: [] },
|
|
82
|
+
};
|
|
83
|
+
}
|
|
84
|
+
// ─── Event Tracking ──────────────────────────────────────
|
|
85
|
+
trackSession(session) {
|
|
86
|
+
this.stats.sessions.set(session.id, session);
|
|
87
|
+
}
|
|
88
|
+
trackToolCall(toolName) {
|
|
89
|
+
const existing = this.stats.toolInvocations.get(toolName) ?? { count: 0, lastUsed: 0 };
|
|
90
|
+
existing.count++;
|
|
91
|
+
existing.lastUsed = Date.now();
|
|
92
|
+
this.stats.toolInvocations.set(toolName, existing);
|
|
93
|
+
}
|
|
94
|
+
trackChannel(name, connected, messages) {
|
|
95
|
+
const existing = this.stats.channelStats.get(name) ?? { connected: false, messages: 0 };
|
|
96
|
+
existing.connected = connected;
|
|
97
|
+
if (messages !== undefined)
|
|
98
|
+
existing.messages = messages;
|
|
99
|
+
this.stats.channelStats.set(name, existing);
|
|
100
|
+
}
|
|
101
|
+
// ─── Lifecycle ───────────────────────────────────────────
|
|
102
|
+
async start() {
|
|
103
|
+
if (!this.config.enabled)
|
|
104
|
+
return;
|
|
105
|
+
return new Promise((resolve) => {
|
|
106
|
+
this.server = this.app.listen(this.config.port, this.config.host, () => {
|
|
107
|
+
console.log(`[dashboard] http://${this.config.host}:${this.config.port}`);
|
|
108
|
+
resolve();
|
|
109
|
+
});
|
|
110
|
+
});
|
|
111
|
+
}
|
|
112
|
+
async stop() {
|
|
113
|
+
return new Promise((resolve) => {
|
|
114
|
+
if (this.server)
|
|
115
|
+
this.server.close(() => resolve());
|
|
116
|
+
else
|
|
117
|
+
resolve();
|
|
118
|
+
});
|
|
119
|
+
}
|
|
120
|
+
renderHTML() {
|
|
121
|
+
return `<!DOCTYPE html>
|
|
122
|
+
<html><head><meta charset="utf-8"><title>OPC Agent Dashboard</title>
|
|
123
|
+
<meta name="viewport" content="width=device-width,initial-scale=1">
|
|
124
|
+
<style>
|
|
125
|
+
*{box-sizing:border-box;margin:0;padding:0}
|
|
126
|
+
body{font-family:system-ui,-apple-system,sans-serif;background:#0a0a0f;color:#e0e0e0;padding:24px}
|
|
127
|
+
h1{font-size:1.5rem;margin-bottom:20px;color:#7c9aff}
|
|
128
|
+
.grid{display:grid;grid-template-columns:repeat(auto-fill,minmax(280px,1fr));gap:16px}
|
|
129
|
+
.card{background:#14141f;border:1px solid #2a2a3a;border-radius:12px;padding:20px}
|
|
130
|
+
.card h2{font-size:0.85rem;text-transform:uppercase;letter-spacing:1px;color:#888;margin-bottom:12px}
|
|
131
|
+
.stat{font-size:2rem;font-weight:700;color:#7c9aff}
|
|
132
|
+
.sub{font-size:0.8rem;color:#666;margin-top:4px}
|
|
133
|
+
#data{margin-top:20px;font-family:monospace;font-size:0.75rem;color:#555;white-space:pre-wrap}
|
|
134
|
+
</style></head><body>
|
|
135
|
+
<h1>⚡ OPC Agent Dashboard</h1>
|
|
136
|
+
<div class="grid">
|
|
137
|
+
<div class="card"><h2>Status</h2><div class="stat" id="status">Loading…</div><div class="sub" id="uptime"></div></div>
|
|
138
|
+
<div class="card"><h2>Sessions</h2><div class="stat" id="sessions">-</div></div>
|
|
139
|
+
<div class="card"><h2>Tools</h2><div class="stat" id="tools">-</div></div>
|
|
140
|
+
<div class="card"><h2>Channels</h2><div class="stat" id="channels">-</div></div>
|
|
141
|
+
</div>
|
|
142
|
+
<div id="data"></div>
|
|
143
|
+
<script>
|
|
144
|
+
async function poll(){try{const r=await fetch('/api/state');const d=await r.json();
|
|
145
|
+
document.getElementById('status').textContent=d.agent.status;
|
|
146
|
+
document.getElementById('uptime').textContent='Uptime: '+Math.floor(d.agent.uptime/1000)+'s';
|
|
147
|
+
document.getElementById('sessions').textContent=d.sessions.length;
|
|
148
|
+
document.getElementById('tools').textContent=d.tools.length;
|
|
149
|
+
document.getElementById('channels').textContent=d.channels.length;
|
|
150
|
+
document.getElementById('data').textContent=JSON.stringify(d,null,2);
|
|
151
|
+
}catch(e){document.getElementById('status').textContent='offline'}}
|
|
152
|
+
poll();setInterval(poll,5000);
|
|
153
|
+
</script></body></html>`;
|
|
154
|
+
}
|
|
155
|
+
}
|
|
156
|
+
exports.Dashboard = Dashboard;
|
|
157
|
+
//# sourceMappingURL=dashboard.js.map
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
export interface FastModeConfig {
|
|
2
|
+
enabled: boolean;
|
|
3
|
+
supportedModels: string[];
|
|
4
|
+
priorityTier: 'standard' | 'fast' | 'turbo';
|
|
5
|
+
}
|
|
6
|
+
export interface FastModeStats {
|
|
7
|
+
requestsRouted: number;
|
|
8
|
+
avgLatencySavingMs: number;
|
|
9
|
+
}
|
|
10
|
+
export declare class FastModeRouter {
|
|
11
|
+
private config;
|
|
12
|
+
private requestsRouted;
|
|
13
|
+
private totalLatencySavingMs;
|
|
14
|
+
constructor(config: FastModeConfig);
|
|
15
|
+
/** Check if a model supports fast mode */
|
|
16
|
+
isSupported(model: string): boolean;
|
|
17
|
+
/**
|
|
18
|
+
* Get the fast-mode endpoint for a model.
|
|
19
|
+
* Appends /fast suffix or priority query param based on tier.
|
|
20
|
+
*/
|
|
21
|
+
getEndpoint(model: string, baseEndpoint: string): string;
|
|
22
|
+
/** Toggle enabled state, return new state */
|
|
23
|
+
toggle(): boolean;
|
|
24
|
+
/** Get routing stats */
|
|
25
|
+
getStats(): FastModeStats;
|
|
26
|
+
}
|
|
27
|
+
//# sourceMappingURL=fast-mode.d.ts.map
|
|
@@ -0,0 +1,59 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
// ─── Fast Mode Router ────────────────────────────────────────
|
|
3
|
+
// Higher-level fast mode abstraction on top of PriorityRouter.
|
|
4
|
+
// Routes requests through priority queues for lower latency on supported models.
|
|
5
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
6
|
+
exports.FastModeRouter = void 0;
|
|
7
|
+
class FastModeRouter {
|
|
8
|
+
config;
|
|
9
|
+
requestsRouted = 0;
|
|
10
|
+
totalLatencySavingMs = 0;
|
|
11
|
+
constructor(config) {
|
|
12
|
+
this.config = { ...config };
|
|
13
|
+
}
|
|
14
|
+
/** Check if a model supports fast mode */
|
|
15
|
+
isSupported(model) {
|
|
16
|
+
return this.config.supportedModels.some((pattern) => {
|
|
17
|
+
if (pattern.endsWith('*')) {
|
|
18
|
+
return model.startsWith(pattern.slice(0, -1));
|
|
19
|
+
}
|
|
20
|
+
return model === pattern;
|
|
21
|
+
});
|
|
22
|
+
}
|
|
23
|
+
/**
|
|
24
|
+
* Get the fast-mode endpoint for a model.
|
|
25
|
+
* Appends /fast suffix or priority query param based on tier.
|
|
26
|
+
*/
|
|
27
|
+
getEndpoint(model, baseEndpoint) {
|
|
28
|
+
if (!this.config.enabled || !this.isSupported(model)) {
|
|
29
|
+
return baseEndpoint;
|
|
30
|
+
}
|
|
31
|
+
this.requestsRouted++;
|
|
32
|
+
// Estimate ~120ms saving for fast, ~200ms for turbo
|
|
33
|
+
this.totalLatencySavingMs += this.config.priorityTier === 'turbo' ? 200 : 120;
|
|
34
|
+
const separator = baseEndpoint.includes('?') ? '&' : '?';
|
|
35
|
+
if (this.config.priorityTier === 'turbo') {
|
|
36
|
+
// Turbo uses a dedicated /fast path
|
|
37
|
+
const url = baseEndpoint.replace(/\/$/, '');
|
|
38
|
+
return `${url}/fast`;
|
|
39
|
+
}
|
|
40
|
+
// Fast tier uses query param
|
|
41
|
+
return `${baseEndpoint}${separator}priority=${this.config.priorityTier}`;
|
|
42
|
+
}
|
|
43
|
+
/** Toggle enabled state, return new state */
|
|
44
|
+
toggle() {
|
|
45
|
+
this.config.enabled = !this.config.enabled;
|
|
46
|
+
return this.config.enabled;
|
|
47
|
+
}
|
|
48
|
+
/** Get routing stats */
|
|
49
|
+
getStats() {
|
|
50
|
+
return {
|
|
51
|
+
requestsRouted: this.requestsRouted,
|
|
52
|
+
avgLatencySavingMs: this.requestsRouted > 0
|
|
53
|
+
? Math.round(this.totalLatencySavingMs / this.requestsRouted)
|
|
54
|
+
: 0,
|
|
55
|
+
};
|
|
56
|
+
}
|
|
57
|
+
}
|
|
58
|
+
exports.FastModeRouter = FastModeRouter;
|
|
59
|
+
//# sourceMappingURL=fast-mode.js.map
|
|
@@ -0,0 +1,52 @@
|
|
|
1
|
+
export interface PriorityConfig {
|
|
2
|
+
/** Enable priority mode (default: false) */
|
|
3
|
+
enabled: boolean;
|
|
4
|
+
/** Provider-specific priority settings */
|
|
5
|
+
providers?: PriorityProviderConfig[];
|
|
6
|
+
/** Default priority tier */
|
|
7
|
+
defaultTier?: PriorityTier;
|
|
8
|
+
}
|
|
9
|
+
export type PriorityTier = 'standard' | 'fast' | 'batch';
|
|
10
|
+
export interface PriorityProviderConfig {
|
|
11
|
+
provider: string;
|
|
12
|
+
tier: PriorityTier;
|
|
13
|
+
/** Custom endpoint override for priority routing */
|
|
14
|
+
endpoint?: string;
|
|
15
|
+
/** Supported models for this tier */
|
|
16
|
+
models?: string[];
|
|
17
|
+
}
|
|
18
|
+
interface PriorityHeaders {
|
|
19
|
+
[key: string]: string;
|
|
20
|
+
}
|
|
21
|
+
export declare class PriorityRouter {
|
|
22
|
+
private config;
|
|
23
|
+
private runtimeTier;
|
|
24
|
+
constructor(config: PriorityConfig);
|
|
25
|
+
/** Toggle fast mode on/off at runtime */
|
|
26
|
+
toggle(): PriorityTier;
|
|
27
|
+
/** Set specific tier */
|
|
28
|
+
setTier(tier: PriorityTier): void;
|
|
29
|
+
/** Get current tier */
|
|
30
|
+
getTier(): PriorityTier;
|
|
31
|
+
/** Check if fast mode is active */
|
|
32
|
+
isFast(): boolean;
|
|
33
|
+
/**
|
|
34
|
+
* Get priority headers for a provider + model combination.
|
|
35
|
+
* Returns empty object if provider doesn't support priority or model isn't eligible.
|
|
36
|
+
*/
|
|
37
|
+
getHeaders(provider: string, model: string): PriorityHeaders;
|
|
38
|
+
/**
|
|
39
|
+
* Get effective endpoint for a provider, allowing priority-specific routing.
|
|
40
|
+
*/
|
|
41
|
+
getEndpoint(provider: string, defaultEndpoint: string): string;
|
|
42
|
+
private getEffectiveTier;
|
|
43
|
+
private isModelEligible;
|
|
44
|
+
/** Status summary for dashboard / CLI */
|
|
45
|
+
status(): {
|
|
46
|
+
tier: PriorityTier;
|
|
47
|
+
enabled: boolean;
|
|
48
|
+
providers: string[];
|
|
49
|
+
};
|
|
50
|
+
}
|
|
51
|
+
export {};
|
|
52
|
+
//# sourceMappingURL=priority.d.ts.map
|
|
@@ -0,0 +1,102 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
// ─── Priority / Fast Mode ────────────────────────────────────
|
|
3
|
+
// Route requests through provider priority tiers for lower latency.
|
|
4
|
+
// Toggle via config or runtime command.
|
|
5
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
6
|
+
exports.PriorityRouter = void 0;
|
|
7
|
+
// Known priority-capable providers and their routing
|
|
8
|
+
const PROVIDER_PRIORITY_MAP = {
|
|
9
|
+
openai: {
|
|
10
|
+
headerKey: 'X-OpenAI-Processing-Priority',
|
|
11
|
+
headerValue: { fast: 'priority', standard: 'auto', batch: 'batch' },
|
|
12
|
+
supportedModels: ['gpt-5', 'gpt-5.4', 'gpt-4.1', 'codex-*', 'o3-*', 'o4-mini*'],
|
|
13
|
+
},
|
|
14
|
+
anthropic: {
|
|
15
|
+
headerKey: 'anthropic-priority',
|
|
16
|
+
headerValue: { fast: 'high', standard: 'normal', batch: 'low' },
|
|
17
|
+
supportedModels: ['claude-opus-*', 'claude-sonnet-*', 'claude-4*'],
|
|
18
|
+
},
|
|
19
|
+
google: {
|
|
20
|
+
headerKey: 'X-Goog-Priority',
|
|
21
|
+
headerValue: { fast: 'high', standard: 'normal', batch: 'low' },
|
|
22
|
+
supportedModels: ['gemini-2.5-*', 'gemini-3-*'],
|
|
23
|
+
},
|
|
24
|
+
};
|
|
25
|
+
class PriorityRouter {
|
|
26
|
+
config;
|
|
27
|
+
runtimeTier;
|
|
28
|
+
constructor(config) {
|
|
29
|
+
this.config = config;
|
|
30
|
+
this.runtimeTier = config.defaultTier ?? 'standard';
|
|
31
|
+
}
|
|
32
|
+
/** Toggle fast mode on/off at runtime */
|
|
33
|
+
toggle() {
|
|
34
|
+
this.runtimeTier = this.runtimeTier === 'fast' ? 'standard' : 'fast';
|
|
35
|
+
return this.runtimeTier;
|
|
36
|
+
}
|
|
37
|
+
/** Set specific tier */
|
|
38
|
+
setTier(tier) {
|
|
39
|
+
this.runtimeTier = tier;
|
|
40
|
+
}
|
|
41
|
+
/** Get current tier */
|
|
42
|
+
getTier() {
|
|
43
|
+
return this.runtimeTier;
|
|
44
|
+
}
|
|
45
|
+
/** Check if fast mode is active */
|
|
46
|
+
isFast() {
|
|
47
|
+
return this.runtimeTier === 'fast';
|
|
48
|
+
}
|
|
49
|
+
/**
|
|
50
|
+
* Get priority headers for a provider + model combination.
|
|
51
|
+
* Returns empty object if provider doesn't support priority or model isn't eligible.
|
|
52
|
+
*/
|
|
53
|
+
getHeaders(provider, model) {
|
|
54
|
+
if (!this.config.enabled)
|
|
55
|
+
return {};
|
|
56
|
+
const tier = this.getEffectiveTier(provider);
|
|
57
|
+
if (tier === 'standard')
|
|
58
|
+
return {};
|
|
59
|
+
const providerMap = PROVIDER_PRIORITY_MAP[provider.toLowerCase()];
|
|
60
|
+
if (!providerMap)
|
|
61
|
+
return {};
|
|
62
|
+
// Check model eligibility
|
|
63
|
+
if (!this.isModelEligible(providerMap.supportedModels, model))
|
|
64
|
+
return {};
|
|
65
|
+
return { [providerMap.headerKey]: providerMap.headerValue[tier] };
|
|
66
|
+
}
|
|
67
|
+
/**
|
|
68
|
+
* Get effective endpoint for a provider, allowing priority-specific routing.
|
|
69
|
+
*/
|
|
70
|
+
getEndpoint(provider, defaultEndpoint) {
|
|
71
|
+
const providerConfig = this.config.providers?.find((p) => p.provider.toLowerCase() === provider.toLowerCase());
|
|
72
|
+
if (providerConfig?.endpoint && this.runtimeTier === 'fast') {
|
|
73
|
+
return providerConfig.endpoint;
|
|
74
|
+
}
|
|
75
|
+
return defaultEndpoint;
|
|
76
|
+
}
|
|
77
|
+
getEffectiveTier(provider) {
|
|
78
|
+
// Check provider-specific override first
|
|
79
|
+
const providerConfig = this.config.providers?.find((p) => p.provider.toLowerCase() === provider.toLowerCase());
|
|
80
|
+
if (providerConfig)
|
|
81
|
+
return providerConfig.tier;
|
|
82
|
+
return this.runtimeTier;
|
|
83
|
+
}
|
|
84
|
+
isModelEligible(patterns, model) {
|
|
85
|
+
return patterns.some((pattern) => {
|
|
86
|
+
if (pattern.endsWith('*')) {
|
|
87
|
+
return model.startsWith(pattern.slice(0, -1));
|
|
88
|
+
}
|
|
89
|
+
return model === pattern;
|
|
90
|
+
});
|
|
91
|
+
}
|
|
92
|
+
/** Status summary for dashboard / CLI */
|
|
93
|
+
status() {
|
|
94
|
+
return {
|
|
95
|
+
tier: this.runtimeTier,
|
|
96
|
+
enabled: this.config.enabled,
|
|
97
|
+
providers: Object.keys(PROVIDER_PRIORITY_MAP),
|
|
98
|
+
};
|
|
99
|
+
}
|
|
100
|
+
}
|
|
101
|
+
exports.PriorityRouter = PriorityRouter;
|
|
102
|
+
//# sourceMappingURL=priority.js.map
|
package/dist/core/runtime.d.ts
CHANGED
|
@@ -1,5 +1,4 @@
|
|
|
1
1
|
import { BaseAgent } from './agent';
|
|
2
|
-
import { Analytics } from '../analytics';
|
|
3
2
|
import type { OADDocument } from '../schema/oad';
|
|
4
3
|
import type { ISkill } from './types';
|
|
5
4
|
export declare function truncateOutput(output: string, maxChars?: number): string;
|
|
@@ -10,7 +9,6 @@ export declare class AgentRuntime {
|
|
|
10
9
|
private historyLimit;
|
|
11
10
|
private shutdownHandlers;
|
|
12
11
|
private isShuttingDown;
|
|
13
|
-
private analytics;
|
|
14
12
|
loadConfig(filePath: string): Promise<OADDocument>;
|
|
15
13
|
setHistoryLimit(limit: number): void;
|
|
16
14
|
initialize(config?: OADDocument): Promise<BaseAgent>;
|
|
@@ -20,7 +18,5 @@ export declare class AgentRuntime {
|
|
|
20
18
|
private setupGracefulShutdown;
|
|
21
19
|
registerSkill(skill: ISkill): void;
|
|
22
20
|
getAgent(): BaseAgent | null;
|
|
23
|
-
getAnalytics(): Analytics;
|
|
24
|
-
getConfig(): OADDocument | null;
|
|
25
21
|
}
|
|
26
22
|
//# sourceMappingURL=runtime.d.ts.map
|
package/dist/core/runtime.js
CHANGED
|
@@ -9,7 +9,6 @@ const web_1 = require("../channels/web");
|
|
|
9
9
|
const telegram_1 = require("../channels/telegram");
|
|
10
10
|
const websocket_1 = require("../channels/websocket");
|
|
11
11
|
const deepbrain_1 = require("../memory/deepbrain");
|
|
12
|
-
const analytics_1 = require("../analytics");
|
|
13
12
|
const MAX_TOOL_OUTPUT = 5000;
|
|
14
13
|
const DEFAULT_HISTORY_LIMIT = 50;
|
|
15
14
|
function truncateOutput(output, maxChars = MAX_TOOL_OUTPUT) {
|
|
@@ -25,7 +24,6 @@ class AgentRuntime {
|
|
|
25
24
|
historyLimit = DEFAULT_HISTORY_LIMIT;
|
|
26
25
|
shutdownHandlers = [];
|
|
27
26
|
isShuttingDown = false;
|
|
28
|
-
analytics = new analytics_1.Analytics();
|
|
29
27
|
async loadConfig(filePath) {
|
|
30
28
|
this.config = (0, config_1.loadOAD)(filePath);
|
|
31
29
|
this.logger.info('Config loaded', { name: this.config.metadata.name });
|
|
@@ -60,12 +58,6 @@ class AgentRuntime {
|
|
|
60
58
|
const port = ch.port ?? 3000;
|
|
61
59
|
const webChannel = new web_1.WebChannel(port);
|
|
62
60
|
webChannel.setAgentName(cfg.metadata.name);
|
|
63
|
-
webChannel.setAgentVersion(cfg.metadata.version);
|
|
64
|
-
webChannel.setAnalyticsProvider(() => this.analytics.getSnapshot());
|
|
65
|
-
webChannel.setChannelNames(cfg.spec.channels.map((c) => c.type));
|
|
66
|
-
webChannel.setSkillNames(cfg.spec.skills.map((s) => s.name));
|
|
67
|
-
const memType = memCfg && typeof memCfg.longTerm === 'object' && memCfg.longTerm.provider === 'deepbrain' ? 'deepbrain' : 'in-memory';
|
|
68
|
-
webChannel.setMemoryType(memType);
|
|
69
61
|
// Wire streaming
|
|
70
62
|
webChannel.onStreamMessage(async (msg, res) => {
|
|
71
63
|
res.writeHead(200, {
|
|
@@ -74,18 +66,15 @@ class AgentRuntime {
|
|
|
74
66
|
Connection: 'keep-alive',
|
|
75
67
|
'Access-Control-Allow-Origin': '*',
|
|
76
68
|
});
|
|
77
|
-
const startTime = Date.now();
|
|
78
69
|
try {
|
|
79
70
|
for await (const chunk of this.agent.handleMessageStream(msg)) {
|
|
80
71
|
res.write(`data: ${JSON.stringify({ content: chunk })}\n\n`);
|
|
81
72
|
}
|
|
82
73
|
res.write('data: [DONE]\n\n');
|
|
83
|
-
this.analytics.recordMessage(Date.now() - startTime);
|
|
84
74
|
}
|
|
85
75
|
catch (err) {
|
|
86
76
|
const errMsg = err instanceof Error ? err.message : String(err);
|
|
87
77
|
res.write(`data: ${JSON.stringify({ error: errMsg })}\n\n`);
|
|
88
|
-
this.analytics.recordError();
|
|
89
78
|
}
|
|
90
79
|
res.end();
|
|
91
80
|
});
|
|
@@ -105,16 +94,6 @@ class AgentRuntime {
|
|
|
105
94
|
}
|
|
106
95
|
}
|
|
107
96
|
await this.agent.init();
|
|
108
|
-
// Wire analytics to agent events
|
|
109
|
-
this.agent.on('message:out', () => {
|
|
110
|
-
// responseTime is approximated; real timing is done via skill/llm events
|
|
111
|
-
});
|
|
112
|
-
this.agent.on('skill:execute', (skillName) => {
|
|
113
|
-
this.analytics.recordSkillUsage(skillName);
|
|
114
|
-
});
|
|
115
|
-
this.agent.on('error', () => {
|
|
116
|
-
this.analytics.recordError();
|
|
117
|
-
});
|
|
118
97
|
this.logger.info('Agent initialized', { name: cfg.metadata.name });
|
|
119
98
|
return this.agent;
|
|
120
99
|
}
|
|
@@ -163,12 +142,6 @@ class AgentRuntime {
|
|
|
163
142
|
getAgent() {
|
|
164
143
|
return this.agent;
|
|
165
144
|
}
|
|
166
|
-
getAnalytics() {
|
|
167
|
-
return this.analytics;
|
|
168
|
-
}
|
|
169
|
-
getConfig() {
|
|
170
|
-
return this.config;
|
|
171
|
-
}
|
|
172
145
|
}
|
|
173
146
|
exports.AgentRuntime = AgentRuntime;
|
|
174
147
|
//# sourceMappingURL=runtime.js.map
|
package/dist/deploy/hermes.js
CHANGED
|
@@ -113,32 +113,32 @@ function deployToHermes(options) {
|
|
|
113
113
|
fs.writeFileSync(settingsPath, JSON.stringify(settings, null, 2), 'utf-8');
|
|
114
114
|
files.push('settings.json');
|
|
115
115
|
// .env template
|
|
116
|
-
const envContent = `# Hermes Agent Environment
|
|
117
|
-
HERMES_CHARACTER=${oad.metadata.name}
|
|
118
|
-
HERMES_MODEL=${oad.spec.model}
|
|
119
|
-
HERMES_PROVIDER=${oad.spec.provider?.default ?? 'openai'}
|
|
120
|
-
# Add your API keys below:
|
|
121
|
-
# OPENAI_API_KEY=
|
|
122
|
-
# DEEPSEEK_API_KEY=
|
|
116
|
+
const envContent = `# Hermes Agent Environment
|
|
117
|
+
HERMES_CHARACTER=${oad.metadata.name}
|
|
118
|
+
HERMES_MODEL=${oad.spec.model}
|
|
119
|
+
HERMES_PROVIDER=${oad.spec.provider?.default ?? 'openai'}
|
|
120
|
+
# Add your API keys below:
|
|
121
|
+
# OPENAI_API_KEY=
|
|
122
|
+
# DEEPSEEK_API_KEY=
|
|
123
123
|
`;
|
|
124
124
|
fs.writeFileSync(path.join(outputDir, '.env.hermes'), envContent, 'utf-8');
|
|
125
125
|
files.push('.env.hermes');
|
|
126
126
|
// README
|
|
127
|
-
const readme = `# ${oad.metadata.name} - Hermes Agent
|
|
128
|
-
|
|
129
|
-
Converted from OAD format using \`opc deploy --target hermes\`.
|
|
130
|
-
|
|
131
|
-
## Usage
|
|
132
|
-
|
|
133
|
-
1. Copy \`character.json\` to your Hermes agents directory
|
|
134
|
-
2. Configure \`.env.hermes\` with your API keys
|
|
135
|
-
3. Start Hermes with this character
|
|
136
|
-
|
|
137
|
-
## Files
|
|
138
|
-
|
|
139
|
-
- \`character.json\` - Agent character definition
|
|
140
|
-
- \`settings.json\` - Runtime settings
|
|
141
|
-
- \`.env.hermes\` - Environment template
|
|
127
|
+
const readme = `# ${oad.metadata.name} - Hermes Agent
|
|
128
|
+
|
|
129
|
+
Converted from OAD format using \`opc deploy --target hermes\`.
|
|
130
|
+
|
|
131
|
+
## Usage
|
|
132
|
+
|
|
133
|
+
1. Copy \`character.json\` to your Hermes agents directory
|
|
134
|
+
2. Configure \`.env.hermes\` with your API keys
|
|
135
|
+
3. Start Hermes with this character
|
|
136
|
+
|
|
137
|
+
## Files
|
|
138
|
+
|
|
139
|
+
- \`character.json\` - Agent character definition
|
|
140
|
+
- \`settings.json\` - Runtime settings
|
|
141
|
+
- \`.env.hermes\` - Environment template
|
|
142
142
|
`;
|
|
143
143
|
fs.writeFileSync(path.join(outputDir, 'README.md'), readme, 'utf-8');
|
|
144
144
|
files.push('README.md');
|
package/dist/deploy/openclaw.js
CHANGED
|
@@ -41,27 +41,27 @@ const fs = __importStar(require("fs"));
|
|
|
41
41
|
const path = __importStar(require("path"));
|
|
42
42
|
function generateIdentityMd(oad) {
|
|
43
43
|
const m = oad.metadata;
|
|
44
|
-
return `# IDENTITY.md
|
|
45
|
-
|
|
46
|
-
- **Name:** ${m.name}
|
|
47
|
-
- **Version:** ${m.version}
|
|
48
|
-
- **Description:** ${m.description ?? 'An AI agent'}
|
|
49
|
-
- **Author:** ${m.author ?? 'Unknown'}
|
|
50
|
-
- **License:** ${m.license}
|
|
44
|
+
return `# IDENTITY.md
|
|
45
|
+
|
|
46
|
+
- **Name:** ${m.name}
|
|
47
|
+
- **Version:** ${m.version}
|
|
48
|
+
- **Description:** ${m.description ?? 'An AI agent'}
|
|
49
|
+
- **Author:** ${m.author ?? 'Unknown'}
|
|
50
|
+
- **License:** ${m.license}
|
|
51
51
|
`;
|
|
52
52
|
}
|
|
53
53
|
function generateSoulMd(oad) {
|
|
54
54
|
const prompt = oad.spec.systemPrompt ?? 'You are a helpful AI assistant.';
|
|
55
|
-
return `# SOUL.md - ${oad.metadata.name}
|
|
56
|
-
|
|
57
|
-
## System Prompt
|
|
58
|
-
|
|
59
|
-
${prompt}
|
|
60
|
-
|
|
61
|
-
## Model Configuration
|
|
62
|
-
|
|
63
|
-
- **Model:** ${oad.spec.model}
|
|
64
|
-
- **Provider:** ${oad.spec.provider?.default ?? 'deepseek'}
|
|
55
|
+
return `# SOUL.md - ${oad.metadata.name}
|
|
56
|
+
|
|
57
|
+
## System Prompt
|
|
58
|
+
|
|
59
|
+
${prompt}
|
|
60
|
+
|
|
61
|
+
## Model Configuration
|
|
62
|
+
|
|
63
|
+
- **Model:** ${oad.spec.model}
|
|
64
|
+
- **Provider:** ${oad.spec.provider?.default ?? 'deepseek'}
|
|
65
65
|
`;
|
|
66
66
|
}
|
|
67
67
|
function generateAgentsMd(oad) {
|
|
@@ -100,26 +100,35 @@ function generateAgentsMd(oad) {
|
|
|
100
100
|
md += `Default memory settings.\n`;
|
|
101
101
|
}
|
|
102
102
|
md += `\n`;
|
|
103
|
+
// DTV
|
|
104
|
+
if (dtv) {
|
|
105
|
+
md += `## Trust & Value\n\n`;
|
|
106
|
+
md += `- Trust Level: ${dtv.trust?.level ?? 'sandbox'}\n`;
|
|
107
|
+
if (dtv.value?.metrics?.length) {
|
|
108
|
+
md += `- Metrics: ${dtv.value.metrics.join(', ')}\n`;
|
|
109
|
+
}
|
|
110
|
+
md += `\n`;
|
|
111
|
+
}
|
|
103
112
|
return md;
|
|
104
113
|
}
|
|
105
114
|
function generateUserMd(oad) {
|
|
106
|
-
return `# USER.md
|
|
107
|
-
|
|
108
|
-
- **Name:** (your name)
|
|
109
|
-
- **Role:** User
|
|
110
|
-
- **Notes:** Configure this file with your preferences for ${oad.metadata.name}.
|
|
115
|
+
return `# USER.md
|
|
116
|
+
|
|
117
|
+
- **Name:** (your name)
|
|
118
|
+
- **Role:** User
|
|
119
|
+
- **Notes:** Configure this file with your preferences for ${oad.metadata.name}.
|
|
111
120
|
`;
|
|
112
121
|
}
|
|
113
122
|
function generateMemoryMd(oad) {
|
|
114
|
-
return `# MEMORY.md - ${oad.metadata.name}
|
|
115
|
-
|
|
116
|
-
## Persistent Knowledge
|
|
117
|
-
|
|
118
|
-
(Agent will store learned information here)
|
|
119
|
-
|
|
120
|
-
## User Preferences
|
|
121
|
-
|
|
122
|
-
(Discovered user preferences will be noted here)
|
|
123
|
+
return `# MEMORY.md - ${oad.metadata.name}
|
|
124
|
+
|
|
125
|
+
## Persistent Knowledge
|
|
126
|
+
|
|
127
|
+
(Agent will store learned information here)
|
|
128
|
+
|
|
129
|
+
## User Preferences
|
|
130
|
+
|
|
131
|
+
(Discovered user preferences will be noted here)
|
|
123
132
|
`;
|
|
124
133
|
}
|
|
125
134
|
function generateOpenClawConfig(oad, agentDir) {
|