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
@@ -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
@@ -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
@@ -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
@@ -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');
@@ -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) {