opc-agent 1.3.1 → 1.3.2

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 (160) hide show
  1. package/CHANGELOG.md +6 -0
  2. package/CONTRIBUTING.md +75 -75
  3. package/README.md +358 -235
  4. package/README.zh-CN.md +415 -415
  5. package/dist/cli.js +34 -118
  6. package/dist/core/dashboard.d.ts +35 -0
  7. package/dist/core/dashboard.js +157 -0
  8. package/dist/core/priority.d.ts +52 -0
  9. package/dist/core/priority.js +102 -0
  10. package/dist/deploy/hermes.js +22 -22
  11. package/dist/deploy/openclaw.js +40 -31
  12. package/dist/index.d.ts +10 -3
  13. package/dist/index.js +15 -6
  14. package/dist/schema/oad.d.ts +2 -1
  15. package/dist/templates/code-reviewer.d.ts +8 -0
  16. package/dist/templates/code-reviewer.js +9 -5
  17. package/dist/templates/customer-service.d.ts +8 -0
  18. package/dist/templates/customer-service.js +6 -2
  19. package/dist/templates/data-analyst.d.ts +8 -0
  20. package/dist/templates/data-analyst.js +9 -5
  21. package/dist/templates/knowledge-base.d.ts +8 -0
  22. package/dist/templates/knowledge-base.js +6 -2
  23. package/dist/templates/sales-assistant.d.ts +8 -0
  24. package/dist/templates/sales-assistant.js +8 -4
  25. package/dist/templates/teacher.d.ts +8 -0
  26. package/dist/templates/teacher.js +10 -6
  27. package/docs/.vitepress/config.ts +103 -103
  28. package/docs/api/cli.md +48 -48
  29. package/docs/api/oad-schema.md +64 -64
  30. package/docs/api/sdk.md +80 -80
  31. package/docs/guide/concepts.md +51 -51
  32. package/docs/guide/configuration.md +79 -79
  33. package/docs/guide/deployment.md +42 -42
  34. package/docs/guide/getting-started.md +44 -44
  35. package/docs/guide/templates.md +28 -28
  36. package/docs/guide/testing.md +84 -84
  37. package/docs/index.md +27 -27
  38. package/docs/zh/api/cli.md +54 -54
  39. package/docs/zh/api/oad-schema.md +87 -87
  40. package/docs/zh/api/sdk.md +102 -102
  41. package/docs/zh/guide/concepts.md +104 -104
  42. package/docs/zh/guide/configuration.md +135 -135
  43. package/docs/zh/guide/deployment.md +81 -81
  44. package/docs/zh/guide/getting-started.md +82 -82
  45. package/docs/zh/guide/templates.md +84 -84
  46. package/docs/zh/guide/testing.md +88 -88
  47. package/docs/zh/index.md +27 -27
  48. package/examples/customer-service-demo/README.md +90 -90
  49. package/examples/customer-service-demo/oad.yaml +107 -107
  50. package/package.json +1 -1
  51. package/src/analytics/index.ts +66 -66
  52. package/src/channels/discord.ts +192 -192
  53. package/src/channels/email.ts +177 -177
  54. package/src/channels/feishu.ts +236 -236
  55. package/src/channels/index.ts +15 -15
  56. package/src/channels/slack.ts +160 -160
  57. package/src/channels/telegram.ts +90 -90
  58. package/src/channels/voice.ts +106 -106
  59. package/src/channels/webhook.ts +199 -199
  60. package/src/channels/websocket.ts +87 -87
  61. package/src/channels/wechat.ts +149 -149
  62. package/src/cli.ts +32 -124
  63. package/src/core/a2a.ts +143 -143
  64. package/src/core/agent.ts +152 -152
  65. package/src/core/analytics-engine.ts +186 -186
  66. package/src/core/auth.ts +57 -57
  67. package/src/core/cache.ts +141 -141
  68. package/src/core/compose.ts +77 -77
  69. package/src/core/config.ts +14 -14
  70. package/src/core/dashboard.ts +219 -0
  71. package/src/core/errors.ts +148 -148
  72. package/src/core/hitl.ts +138 -138
  73. package/src/core/logger.ts +57 -57
  74. package/src/core/orchestrator.ts +215 -215
  75. package/src/core/performance.ts +187 -187
  76. package/src/core/priority.ts +140 -0
  77. package/src/core/rate-limiter.ts +128 -128
  78. package/src/core/room.ts +109 -109
  79. package/src/core/runtime.ts +152 -152
  80. package/src/core/sandbox.ts +101 -101
  81. package/src/core/security.ts +171 -171
  82. package/src/core/types.ts +68 -68
  83. package/src/core/versioning.ts +106 -106
  84. package/src/core/watch.ts +178 -178
  85. package/src/core/workflow.ts +235 -235
  86. package/src/deploy/hermes.ts +156 -156
  87. package/src/deploy/openclaw.ts +200 -190
  88. package/src/dtv/data.ts +29 -0
  89. package/src/dtv/trust.ts +43 -0
  90. package/src/dtv/value.ts +47 -0
  91. package/src/i18n/index.ts +216 -216
  92. package/src/index.ts +10 -3
  93. package/src/marketplace/index.ts +223 -0
  94. package/src/memory/deepbrain.ts +108 -108
  95. package/src/memory/index.ts +34 -34
  96. package/src/plugins/index.ts +208 -208
  97. package/src/schema/oad.ts +155 -154
  98. package/src/skills/base.ts +16 -16
  99. package/src/skills/document.ts +100 -100
  100. package/src/skills/http.ts +35 -35
  101. package/src/skills/index.ts +27 -27
  102. package/src/skills/scheduler.ts +80 -80
  103. package/src/skills/webhook-trigger.ts +59 -59
  104. package/src/templates/code-reviewer.ts +34 -30
  105. package/src/templates/customer-service.ts +80 -76
  106. package/src/templates/data-analyst.ts +70 -66
  107. package/src/templates/executive-assistant.ts +71 -71
  108. package/src/templates/financial-advisor.ts +60 -60
  109. package/src/templates/knowledge-base.ts +31 -27
  110. package/src/templates/legal-assistant.ts +71 -71
  111. package/src/templates/sales-assistant.ts +79 -75
  112. package/src/templates/teacher.ts +79 -75
  113. package/src/testing/index.ts +181 -181
  114. package/src/tools/calculator.ts +73 -73
  115. package/src/tools/datetime.ts +149 -149
  116. package/src/tools/json-transform.ts +187 -187
  117. package/src/tools/mcp.ts +76 -76
  118. package/src/tools/text-analysis.ts +116 -116
  119. package/templates/Dockerfile +15 -15
  120. package/templates/code-reviewer/README.md +27 -27
  121. package/templates/code-reviewer/oad.yaml +41 -41
  122. package/templates/customer-service/README.md +22 -22
  123. package/templates/customer-service/oad.yaml +36 -36
  124. package/templates/docker-compose.yml +21 -21
  125. package/templates/ecommerce-assistant/README.md +45 -45
  126. package/templates/ecommerce-assistant/oad.yaml +47 -47
  127. package/templates/knowledge-base/README.md +28 -28
  128. package/templates/knowledge-base/oad.yaml +38 -38
  129. package/templates/sales-assistant/README.md +26 -26
  130. package/templates/sales-assistant/oad.yaml +43 -43
  131. package/templates/tech-support/README.md +43 -43
  132. package/templates/tech-support/oad.yaml +45 -45
  133. package/tests/a2a.test.ts +66 -66
  134. package/tests/agent.test.ts +72 -72
  135. package/tests/analytics.test.ts +50 -50
  136. package/tests/channel.test.ts +39 -39
  137. package/tests/e2e.test.ts +134 -134
  138. package/tests/errors.test.ts +83 -83
  139. package/tests/hitl.test.ts +71 -71
  140. package/tests/i18n.test.ts +41 -41
  141. package/tests/mcp.test.ts +54 -54
  142. package/tests/oad.test.ts +68 -68
  143. package/tests/performance.test.ts +115 -115
  144. package/tests/plugin.test.ts +74 -74
  145. package/tests/room.test.ts +106 -106
  146. package/tests/runtime.test.ts +42 -42
  147. package/tests/sandbox.test.ts +46 -46
  148. package/tests/security.test.ts +60 -60
  149. package/tests/templates.test.ts +77 -77
  150. package/tests/v070.test.ts +76 -76
  151. package/tests/versioning.test.ts +75 -75
  152. package/tests/voice.test.ts +61 -61
  153. package/tests/webhook.test.ts +29 -29
  154. package/tests/workflow.test.ts +143 -143
  155. package/tsconfig.json +19 -19
  156. package/vitest.config.ts +9 -9
  157. package/.github/workflows/ci.yml +0 -24
  158. package/dist/traces/index.d.ts +0 -49
  159. package/dist/traces/index.js +0 -102
  160. package/src/traces/index.ts +0 -132
package/dist/cli.js CHANGED
@@ -61,6 +61,7 @@ const workflow_1 = require("./core/workflow");
61
61
  const versioning_1 = require("./core/versioning");
62
62
  const providers_1 = require("./providers");
63
63
  const knowledge_1 = require("./core/knowledge");
64
+ const marketplace_1 = require("./marketplace");
64
65
  const program = new commander_1.Command();
65
66
  const color = {
66
67
  green: (s) => `\x1b[32m${s}\x1b[0m`,
@@ -683,23 +684,51 @@ kbCmd.command('clear').action(() => {
683
684
  kb.clear();
684
685
  console.log(`${icon.success} Knowledge base cleared.`);
685
686
  });
686
- // 📦 Package commands ───────────────────────────────────
687
+ // 📦 Marketplace commands ───────────────────────────────────
687
688
  program
688
689
  .command('publish')
689
690
  .description('Package agent for distribution')
690
691
  .option('-f, --file <file>', 'OAD file', 'oad.yaml')
691
692
  .option('-o, --output <dir>', 'Output directory', '.')
692
693
  .option('--include-kb', 'Include knowledge base')
693
- .action(async () => {
694
- console.log(`\n${icon.package} Agent packaging coming soon.\n`);
694
+ .action(async (opts) => {
695
+ try {
696
+ console.log(`\n${icon.package} Packaging agent...\n`);
697
+ const result = await (0, marketplace_1.publishAgent)({
698
+ oadPath: opts.file,
699
+ outputDir: opts.output,
700
+ includeKnowledge: opts.includeKb,
701
+ });
702
+ console.log(`${icon.success} Published: ${color.bold(result.archivePath)}`);
703
+ console.log(` Name: ${result.manifest.name}`);
704
+ console.log(` Version: ${result.manifest.version}`);
705
+ console.log(` Files: ${result.manifest.files.length}`);
706
+ console.log();
707
+ }
708
+ catch (err) {
709
+ console.error(`${icon.error} Publish failed:`, err instanceof Error ? err.message : err);
710
+ process.exit(1);
711
+ }
695
712
  });
696
713
  program
697
714
  .command('install')
698
715
  .description('Install agent from package')
699
716
  .argument('<source>', 'Package file path or URL')
700
717
  .option('-d, --dir <dir>', 'Install directory')
701
- .action(async () => {
702
- console.log(`\n${icon.package} Agent install coming soon.\n`);
718
+ .action(async (source, opts) => {
719
+ try {
720
+ console.log(`\n${icon.package} Installing agent from ${color.bold(source)}...\n`);
721
+ const result = await (0, marketplace_1.installAgent)({ source, targetDir: opts.dir });
722
+ console.log(`${icon.success} Installed: ${color.bold(result.manifest.name)} v${result.manifest.version}`);
723
+ console.log(` Directory: ${result.dir}`);
724
+ console.log(`\n${color.bold('Next steps:')}`);
725
+ console.log(` cd ${result.dir}`);
726
+ console.log(` opc run\n`);
727
+ }
728
+ catch (err) {
729
+ console.error(`${icon.error} Install failed:`, err instanceof Error ? err.message : err);
730
+ process.exit(1);
731
+ }
703
732
  });
704
733
  // 🔌 Plugin commands ────────────────────────────────────────
705
734
  const pluginCmd = program.command('plugin').description('Manage plugins');
@@ -809,118 +838,5 @@ program
809
838
  process.exit(1);
810
839
  }
811
840
  });
812
- // ── Brain command ────────────────────────────────────────────
813
- program
814
- .command('brain')
815
- .description('Show agent memory/brain status from DeepBrain')
816
- .option('--url <url>', 'DeepBrain server URL', 'http://localhost:3333')
817
- .action(async (opts) => {
818
- console.log(`\n${icon.gear} ${color.bold('DeepBrain Status')} — ${color.dim(opts.url)}\n`);
819
- try {
820
- const res = await fetch(`${opts.url}/api/stats`);
821
- if (!res.ok)
822
- throw new Error(`HTTP ${res.status} ${res.statusText}`);
823
- const stats = (await res.json());
824
- const rows = [
825
- ['Total Pages', String(stats.totalPages ?? stats.pages ?? '-')],
826
- ['Total Chunks', String(stats.totalChunks ?? stats.chunks ?? '-')],
827
- ['Memory Tiers', String(stats.memoryTiers ?? stats.tiers ?? '-')],
828
- ['Index Size', stats.indexSize ?? '-'],
829
- ['Last Updated', stats.lastUpdated ?? stats.updatedAt ?? '-'],
830
- ];
831
- const maxKey = Math.max(...rows.map(([k]) => k.length));
832
- for (const [key, val] of rows) {
833
- console.log(` ${color.cyan(key.padEnd(maxKey))} ${val}`);
834
- }
835
- console.log();
836
- }
837
- catch (err) {
838
- const msg = err instanceof Error ? err.message : String(err);
839
- if (msg.includes('ECONNREFUSED') || msg.includes('fetch failed')) {
840
- console.log(` ${icon.warn} Cannot connect to DeepBrain at ${opts.url}`);
841
- console.log(` ${color.dim('Is the server running? Start with: deepbrain serve')}\n`);
842
- }
843
- else {
844
- console.error(` ${icon.error} ${msg}\n`);
845
- }
846
- }
847
- });
848
- // ── Logs command ─────────────────────────────────────────────
849
- program
850
- .command('logs')
851
- .description('Show recent agent traces')
852
- .option('-n, --limit <n>', 'Number of spans to show', '20')
853
- .option('-f, --follow', 'Keep watching for new spans')
854
- .action(async (opts) => {
855
- const { TraceCollector } = await Promise.resolve().then(() => __importStar(require('./traces')));
856
- const collector = new TraceCollector();
857
- const limit = parseInt(opts.limit) || 20;
858
- const printSpans = (spans) => {
859
- const slice = spans.slice(-limit);
860
- if (slice.length === 0) {
861
- console.log(` ${icon.info} No traces yet. Interact with the agent to generate traces.`);
862
- return;
863
- }
864
- for (const span of slice) {
865
- const duration = span.endTime
866
- ? `${span.endTime.getTime() - span.startTime.getTime()}ms`
867
- : 'ongoing';
868
- const statusIcon = span.status === 'ok' ? icon.success : span.status === 'error' ? icon.error : color.dim('○');
869
- const time = span.startTime.toLocaleTimeString();
870
- console.log(` ${statusIcon} ${color.dim(time)} ${color.bold(span.name)} ${color.dim(duration)}`);
871
- }
872
- };
873
- console.log(`\n${icon.gear} ${color.bold('Agent Traces')}\n`);
874
- const spans = collector.getBufferedSpans();
875
- printSpans(spans);
876
- if (opts.follow) {
877
- console.log(`\n ${color.dim('Watching for new traces... (Ctrl+C to stop)')}\n`);
878
- let lastCount = spans.length;
879
- const interval = setInterval(() => {
880
- const current = collector.getBufferedSpans();
881
- if (current.length > lastCount) {
882
- const newSpans = current.slice(lastCount);
883
- printSpans(newSpans);
884
- lastCount = current.length;
885
- }
886
- }, 1000);
887
- process.on('SIGINT', () => { clearInterval(interval); process.exit(0); });
888
- }
889
- else {
890
- console.log();
891
- }
892
- });
893
- // ── Score command ────────────────────────────────────────────
894
- program
895
- .command('score')
896
- .description('Show agent performance score')
897
- .action(async () => {
898
- console.log(`\n${icon.gear} ${color.bold('Agent Performance Score')}\n`);
899
- try {
900
- const engine = new analytics_engine_1.AnalyticsEngine('.');
901
- const stats = engine.getStats();
902
- if (!stats || stats.totalMessages === 0) {
903
- console.log(` ${icon.info} No score data yet. Run the agent first.\n`);
904
- return;
905
- }
906
- const errorRate = stats.totalMessages > 0 ? (stats.totalErrors / stats.totalMessages) : 0;
907
- const rows = [
908
- ['Total Messages', String(stats.totalMessages)],
909
- ['Total LLM Calls', String(stats.totalLLMCalls)],
910
- ['Total Tool Uses', String(stats.totalToolUses)],
911
- ['Avg Response Time', `${stats.avgResponseTimeMs}ms`],
912
- ['Error Rate', `${(errorRate * 100).toFixed(1)}%`],
913
- ['Token Usage', `${stats.totalTokens.total} tokens (in: ${stats.totalTokens.input}, out: ${stats.totalTokens.output})`],
914
- ];
915
- const maxKey = Math.max(...rows.map(([k]) => k.length));
916
- for (const [key, val] of rows) {
917
- console.log(` ${color.cyan(key.padEnd(maxKey))} ${val}`);
918
- }
919
- console.log();
920
- }
921
- catch {
922
- console.log(` ${icon.info} No score data yet. Run the agent first.\n`);
923
- }
924
- });
925
841
  program.parse();
926
842
  //# sourceMappingURL=cli.js.map
@@ -0,0 +1,35 @@
1
+ export interface DashboardConfig {
2
+ /** Enable the dashboard (default: false) */
3
+ enabled: boolean;
4
+ /** HTTP port (default: 4100) */
5
+ port?: number;
6
+ /** Bind address (default: 127.0.0.1 for security) */
7
+ host?: string;
8
+ /** Enable CORS (default: false) */
9
+ cors?: boolean;
10
+ }
11
+ interface SessionSummary {
12
+ id: string;
13
+ channel: string;
14
+ messages: number;
15
+ lastActive: number;
16
+ status: 'active' | 'idle' | 'closed';
17
+ }
18
+ export declare class Dashboard {
19
+ private app;
20
+ private server;
21
+ private config;
22
+ private startTime;
23
+ private stats;
24
+ constructor(config: DashboardConfig);
25
+ private setupRoutes;
26
+ private getState;
27
+ trackSession(session: SessionSummary): void;
28
+ trackToolCall(toolName: string): void;
29
+ trackChannel(name: string, connected: boolean, messages?: number): void;
30
+ start(): Promise<void>;
31
+ stop(): Promise<void>;
32
+ private renderHTML;
33
+ }
34
+ export {};
35
+ //# sourceMappingURL=dashboard.d.ts.map
@@ -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,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
@@ -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) {