opc-agent 0.6.0 → 0.7.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/channels/web.d.ts +7 -1
- package/dist/channels/web.js +165 -4
- package/dist/core/auth.d.ts +13 -0
- package/dist/core/auth.js +41 -0
- package/dist/index.d.ts +9 -0
- package/dist/index.js +13 -1
- package/dist/schema/oad.d.ts +69 -0
- package/dist/schema/oad.js +7 -1
- package/dist/skills/document.d.ts +27 -0
- package/dist/skills/document.js +80 -0
- package/dist/skills/http.d.ts +8 -0
- package/dist/skills/http.js +34 -0
- package/dist/skills/scheduler.d.ts +21 -0
- package/dist/skills/scheduler.js +70 -0
- package/dist/skills/webhook-trigger.d.ts +17 -0
- package/dist/skills/webhook-trigger.js +49 -0
- package/package.json +1 -1
- package/src/channels/web.ts +175 -4
- package/src/core/auth.ts +57 -0
- package/src/index.ts +11 -0
- package/src/schema/oad.ts +7 -0
- package/src/skills/document.ts +100 -0
- package/src/skills/http.ts +35 -0
- package/src/skills/scheduler.ts +80 -0
- package/src/skills/webhook-trigger.ts +59 -0
- package/tests/v070.test.ts +76 -0
package/dist/channels/web.d.ts
CHANGED
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import { type Response } from 'express';
|
|
2
2
|
import type { Message } from '../core/types';
|
|
3
3
|
import { BaseChannel } from './index';
|
|
4
|
+
import { type AuthConfig } from '../core/auth';
|
|
4
5
|
export declare class WebChannel extends BaseChannel {
|
|
5
6
|
readonly type = "web";
|
|
6
7
|
private app;
|
|
@@ -11,11 +12,16 @@ export declare class WebChannel extends BaseChannel {
|
|
|
11
12
|
private currentProvider;
|
|
12
13
|
private stats;
|
|
13
14
|
private eventHandlers;
|
|
15
|
+
private conversations;
|
|
16
|
+
private requestCount;
|
|
17
|
+
private llmLatencySum;
|
|
18
|
+
private llmCalls;
|
|
14
19
|
private emit;
|
|
15
20
|
onConfigChange(handler: (config: any) => void): void;
|
|
16
21
|
trackMessage(responseMs: number, tokens?: number): void;
|
|
22
|
+
trackError(): void;
|
|
17
23
|
trackSession(): void;
|
|
18
|
-
constructor(port?: number);
|
|
24
|
+
constructor(port?: number, authConfig?: AuthConfig);
|
|
19
25
|
setAgentName(name: string): void;
|
|
20
26
|
onStreamMessage(handler: (msg: Message, res: Response) => Promise<void>): void;
|
|
21
27
|
private setupRoutes;
|
package/dist/channels/web.js
CHANGED
|
@@ -7,6 +7,57 @@ exports.WebChannel = void 0;
|
|
|
7
7
|
const express_1 = __importDefault(require("express"));
|
|
8
8
|
const index_1 = require("./index");
|
|
9
9
|
const knowledge_1 = require("../core/knowledge");
|
|
10
|
+
const auth_1 = require("../core/auth");
|
|
11
|
+
const AGENT_TEMPLATES = [
|
|
12
|
+
{ id: 'customer-service', name: 'Customer Service', description: 'Handle support tickets, FAQs, and customer inquiries', icon: '🎧', category: 'Business' },
|
|
13
|
+
{ id: 'code-reviewer', name: 'Code Reviewer', description: 'Review PRs, suggest improvements, check for bugs', icon: '🔍', category: 'Engineering' },
|
|
14
|
+
{ id: 'content-writer', name: 'Content Writer', description: 'Write blogs, social media posts, and marketing copy', icon: '✍️', category: 'Marketing' },
|
|
15
|
+
{ id: 'executive-assistant', name: 'Executive Assistant', description: 'Schedule management, email drafting, meeting prep', icon: '📋', category: 'Business' },
|
|
16
|
+
{ id: 'knowledge-base', name: 'Knowledge Base', description: 'RAG-powered Q&A over your documents', icon: '📚', category: 'Knowledge' },
|
|
17
|
+
{ id: 'project-manager', name: 'Project Manager', description: 'Track tasks, milestones, and team coordination', icon: '📊', category: 'Business' },
|
|
18
|
+
{ id: 'sales-assistant', name: 'Sales Assistant', description: 'Lead qualification, outreach drafting, CRM updates', icon: '💼', category: 'Sales' },
|
|
19
|
+
{ id: 'financial-advisor', name: 'Financial Advisor', description: 'Budget analysis, financial planning, cost optimization', icon: '💰', category: 'Finance' },
|
|
20
|
+
{ id: 'hr-recruiter', name: 'HR Recruiter', description: 'Resume screening, interview scheduling, candidate comms', icon: '👥', category: 'HR' },
|
|
21
|
+
{ id: 'legal-assistant', name: 'Legal Assistant', description: 'Contract review, compliance checks, legal research', icon: '⚖️', category: 'Legal' },
|
|
22
|
+
];
|
|
23
|
+
const TEMPLATES_HTML = `<!DOCTYPE html>
|
|
24
|
+
<html lang="en">
|
|
25
|
+
<head>
|
|
26
|
+
<meta charset="UTF-8"><meta name="viewport" content="width=device-width,initial-scale=1.0">
|
|
27
|
+
<title>Agent Templates</title>
|
|
28
|
+
<style>
|
|
29
|
+
*{margin:0;padding:0;box-sizing:border-box}
|
|
30
|
+
body{background:#0a0a0f;color:#e0e0e0;font-family:-apple-system,BlinkMacSystemFont,'Segoe UI',Roboto,sans-serif;padding:24px}
|
|
31
|
+
h1{font-size:28px;margin-bottom:8px;color:#fff}
|
|
32
|
+
.sub{color:#888;margin-bottom:32px;font-size:14px}
|
|
33
|
+
nav{margin-bottom:24px}
|
|
34
|
+
nav a{color:#818cf8;text-decoration:none;margin-right:16px;font-size:14px}
|
|
35
|
+
.grid{display:grid;grid-template-columns:repeat(auto-fill,minmax(280px,1fr));gap:16px}
|
|
36
|
+
.card{background:#12121a;border:1px solid #1e1e2e;border-radius:12px;padding:24px;cursor:pointer;transition:all .2s}
|
|
37
|
+
.card:hover{border-color:#818cf8;transform:translateY(-2px)}
|
|
38
|
+
.card .icon{font-size:32px;margin-bottom:12px}
|
|
39
|
+
.card h3{font-size:16px;color:#fff;margin-bottom:8px}
|
|
40
|
+
.card p{font-size:13px;color:#888;line-height:1.5}
|
|
41
|
+
.card .cat{font-size:11px;color:#818cf8;text-transform:uppercase;letter-spacing:1px;margin-top:12px}
|
|
42
|
+
.btn{display:inline-block;background:#2563eb;color:#fff;border:none;border-radius:8px;padding:8px 16px;font-size:13px;cursor:pointer;margin-top:12px}
|
|
43
|
+
.btn:hover{background:#1d4ed8}
|
|
44
|
+
</style>
|
|
45
|
+
</head>
|
|
46
|
+
<body>
|
|
47
|
+
<nav><a href="/">← Chat</a><a href="/dashboard">Dashboard</a><a href="/templates">Templates</a></nav>
|
|
48
|
+
<h1>🧩 Agent Templates</h1>
|
|
49
|
+
<p class="sub">Create a new agent from a pre-built template in one click.</p>
|
|
50
|
+
<div class="grid" id="grid"></div>
|
|
51
|
+
<script>
|
|
52
|
+
fetch('/api/templates').then(r=>r.json()).then(d=>{
|
|
53
|
+
const g=document.getElementById('grid');
|
|
54
|
+
d.templates.forEach(t=>{
|
|
55
|
+
g.innerHTML+=\`<div class="card"><div class="icon">\${t.icon}</div><h3>\${t.name}</h3><p>\${t.description}</p><div class="cat">\${t.category}</div><button class="btn" onclick="alert('Creating agent from template: '+'\${t.id}'+'\\\\nRun: opc init --template \${t.id}')">Use Template</button></div>\`;
|
|
56
|
+
});
|
|
57
|
+
});
|
|
58
|
+
</script>
|
|
59
|
+
</body>
|
|
60
|
+
</html>`;
|
|
10
61
|
const CHAT_HTML = `<!DOCTYPE html>
|
|
11
62
|
<html lang="en">
|
|
12
63
|
<head>
|
|
@@ -157,8 +208,12 @@ class WebChannel extends index_1.BaseChannel {
|
|
|
157
208
|
streamHandler = null;
|
|
158
209
|
agentName = 'OPC Agent';
|
|
159
210
|
currentProvider = 'openai';
|
|
160
|
-
stats = { sessions: 0, messages: 0, totalResponseMs: 0, tokenUsage: 0, knowledgeFiles: 0, startedAt: Date.now() };
|
|
211
|
+
stats = { sessions: 0, messages: 0, totalResponseMs: 0, tokenUsage: 0, knowledgeFiles: 0, startedAt: Date.now(), errors: 0 };
|
|
161
212
|
eventHandlers = new Map();
|
|
213
|
+
conversations = new Map();
|
|
214
|
+
requestCount = 0;
|
|
215
|
+
llmLatencySum = 0;
|
|
216
|
+
llmCalls = 0;
|
|
162
217
|
emit(event, data) {
|
|
163
218
|
const handlers = this.eventHandlers.get(event) ?? [];
|
|
164
219
|
for (const h of handlers)
|
|
@@ -173,13 +228,20 @@ class WebChannel extends index_1.BaseChannel {
|
|
|
173
228
|
this.stats.messages++;
|
|
174
229
|
this.stats.totalResponseMs += responseMs;
|
|
175
230
|
this.stats.tokenUsage += tokens;
|
|
231
|
+
this.requestCount++;
|
|
232
|
+
this.llmLatencySum += responseMs;
|
|
233
|
+
this.llmCalls++;
|
|
176
234
|
}
|
|
235
|
+
trackError() { this.stats.errors++; }
|
|
177
236
|
trackSession() { this.stats.sessions++; }
|
|
178
|
-
constructor(port = 3000) {
|
|
237
|
+
constructor(port = 3000, authConfig) {
|
|
179
238
|
super();
|
|
180
239
|
this.port = port;
|
|
181
240
|
this.app = (0, express_1.default)();
|
|
182
|
-
this.app.use(express_1.default.json());
|
|
241
|
+
this.app.use(express_1.default.json({ limit: '10mb' }));
|
|
242
|
+
if (authConfig && authConfig.apiKeys.length > 0) {
|
|
243
|
+
this.app.use((0, auth_1.createAuthMiddleware)(authConfig));
|
|
244
|
+
}
|
|
183
245
|
this.setupRoutes();
|
|
184
246
|
}
|
|
185
247
|
setAgentName(name) {
|
|
@@ -201,6 +263,7 @@ class WebChannel extends index_1.BaseChannel {
|
|
|
201
263
|
// Streaming chat endpoint
|
|
202
264
|
this.app.post('/api/chat', async (req, res) => {
|
|
203
265
|
const { message, sessionId } = req.body;
|
|
266
|
+
const sid = sessionId ?? 'default';
|
|
204
267
|
if (!message) {
|
|
205
268
|
res.status(400).json({ error: 'message is required' });
|
|
206
269
|
return;
|
|
@@ -210,8 +273,12 @@ class WebChannel extends index_1.BaseChannel {
|
|
|
210
273
|
role: 'user',
|
|
211
274
|
content: message,
|
|
212
275
|
timestamp: Date.now(),
|
|
213
|
-
metadata: { sessionId:
|
|
276
|
+
metadata: { sessionId: sid },
|
|
214
277
|
};
|
|
278
|
+
// Track conversation
|
|
279
|
+
if (!this.conversations.has(sid))
|
|
280
|
+
this.conversations.set(sid, []);
|
|
281
|
+
this.conversations.get(sid).push(msg);
|
|
215
282
|
if (this.streamHandler) {
|
|
216
283
|
try {
|
|
217
284
|
await this.streamHandler(msg, res);
|
|
@@ -290,6 +357,100 @@ class WebChannel extends index_1.BaseChannel {
|
|
|
290
357
|
res.json({ totalEntries: 0, sources: [] });
|
|
291
358
|
}
|
|
292
359
|
});
|
|
360
|
+
// --- Health Check (detailed) ---
|
|
361
|
+
this.app.get('/api/health', (_req, res) => {
|
|
362
|
+
const uptimeMs = Date.now() - this.stats.startedAt;
|
|
363
|
+
res.json({
|
|
364
|
+
status: 'ok',
|
|
365
|
+
timestamp: Date.now(),
|
|
366
|
+
uptime: uptimeMs,
|
|
367
|
+
uptimeHuman: `${Math.floor(uptimeMs / 3600000)}h ${Math.floor((uptimeMs % 3600000) / 60000)}m`,
|
|
368
|
+
version: '0.7.0',
|
|
369
|
+
agent: this.agentName,
|
|
370
|
+
stats: {
|
|
371
|
+
sessions: this.stats.sessions,
|
|
372
|
+
messages: this.stats.messages,
|
|
373
|
+
errors: this.stats.errors,
|
|
374
|
+
avgResponseMs: this.stats.messages > 0 ? Math.round(this.stats.totalResponseMs / this.stats.messages) : 0,
|
|
375
|
+
},
|
|
376
|
+
memory: {
|
|
377
|
+
rss: process.memoryUsage().rss,
|
|
378
|
+
heapUsed: process.memoryUsage().heapUsed,
|
|
379
|
+
},
|
|
380
|
+
});
|
|
381
|
+
});
|
|
382
|
+
// --- Prometheus Metrics ---
|
|
383
|
+
this.app.get('/api/metrics', (_req, res) => {
|
|
384
|
+
const uptimeMs = Date.now() - this.stats.startedAt;
|
|
385
|
+
const avgLatency = this.llmCalls > 0 ? this.llmLatencySum / this.llmCalls : 0;
|
|
386
|
+
const mem = process.memoryUsage();
|
|
387
|
+
res.type('text/plain').send(`# HELP opc_uptime_seconds Agent uptime in seconds\n` +
|
|
388
|
+
`# TYPE opc_uptime_seconds gauge\n` +
|
|
389
|
+
`opc_uptime_seconds ${(uptimeMs / 1000).toFixed(1)}\n` +
|
|
390
|
+
`# HELP opc_requests_total Total requests\n` +
|
|
391
|
+
`# TYPE opc_requests_total counter\n` +
|
|
392
|
+
`opc_requests_total ${this.requestCount}\n` +
|
|
393
|
+
`# HELP opc_messages_total Total messages processed\n` +
|
|
394
|
+
`# TYPE opc_messages_total counter\n` +
|
|
395
|
+
`opc_messages_total ${this.stats.messages}\n` +
|
|
396
|
+
`# HELP opc_errors_total Total errors\n` +
|
|
397
|
+
`# TYPE opc_errors_total counter\n` +
|
|
398
|
+
`opc_errors_total ${this.stats.errors}\n` +
|
|
399
|
+
`# HELP opc_llm_latency_avg_ms Average LLM response latency\n` +
|
|
400
|
+
`# TYPE opc_llm_latency_avg_ms gauge\n` +
|
|
401
|
+
`opc_llm_latency_avg_ms ${avgLatency.toFixed(1)}\n` +
|
|
402
|
+
`# HELP opc_sessions_total Total sessions\n` +
|
|
403
|
+
`# TYPE opc_sessions_total counter\n` +
|
|
404
|
+
`opc_sessions_total ${this.stats.sessions}\n` +
|
|
405
|
+
`# HELP opc_token_usage_total Total token usage\n` +
|
|
406
|
+
`# TYPE opc_token_usage_total counter\n` +
|
|
407
|
+
`opc_token_usage_total ${this.stats.tokenUsage}\n` +
|
|
408
|
+
`# HELP process_resident_memory_bytes Resident memory size\n` +
|
|
409
|
+
`# TYPE process_resident_memory_bytes gauge\n` +
|
|
410
|
+
`process_resident_memory_bytes ${mem.rss}\n`);
|
|
411
|
+
});
|
|
412
|
+
// --- Conversation tracking & export ---
|
|
413
|
+
this.app.get('/api/conversations/export', (req, res) => {
|
|
414
|
+
const sessionId = req.query.sessionId;
|
|
415
|
+
const format = req.query.format ?? 'json';
|
|
416
|
+
const messages = sessionId ? (this.conversations.get(sessionId) ?? []) : Array.from(this.conversations.values()).flat();
|
|
417
|
+
if (format === 'markdown') {
|
|
418
|
+
const md = messages.map(m => `**${m.role}** (${new Date(m.timestamp).toISOString()}):\n${m.content}`).join('\n\n---\n\n');
|
|
419
|
+
res.type('text/markdown').send(md);
|
|
420
|
+
}
|
|
421
|
+
else if (format === 'csv') {
|
|
422
|
+
const header = 'id,role,content,timestamp\n';
|
|
423
|
+
const rows = messages.map(m => `"${m.id}","${m.role}","${m.content.replace(/"/g, '""')}",${m.timestamp}`).join('\n');
|
|
424
|
+
res.type('text/csv').send(header + rows);
|
|
425
|
+
}
|
|
426
|
+
else {
|
|
427
|
+
res.json({ sessionId: sessionId ?? 'all', messages, count: messages.length });
|
|
428
|
+
}
|
|
429
|
+
});
|
|
430
|
+
// --- Document Upload ---
|
|
431
|
+
this.app.post('/api/documents/upload', async (req, res) => {
|
|
432
|
+
try {
|
|
433
|
+
const { content, filename, mimeType } = req.body;
|
|
434
|
+
if (!content || !filename) {
|
|
435
|
+
res.status(400).json({ error: 'content and filename are required' });
|
|
436
|
+
return;
|
|
437
|
+
}
|
|
438
|
+
const kb = new knowledge_1.KnowledgeBase('.');
|
|
439
|
+
const result = await kb.addText(content, filename);
|
|
440
|
+
this.stats.knowledgeFiles++;
|
|
441
|
+
res.json({ ok: true, filename, chunks: result.chunks, chars: content.length });
|
|
442
|
+
}
|
|
443
|
+
catch (err) {
|
|
444
|
+
res.status(500).json({ error: err instanceof Error ? err.message : 'Upload failed' });
|
|
445
|
+
}
|
|
446
|
+
});
|
|
447
|
+
// --- Agent Templates Gallery ---
|
|
448
|
+
this.app.get('/api/templates', (_req, res) => {
|
|
449
|
+
res.json({ templates: AGENT_TEMPLATES });
|
|
450
|
+
});
|
|
451
|
+
this.app.get('/templates', (_req, res) => {
|
|
452
|
+
res.type('html').send(TEMPLATES_HTML);
|
|
453
|
+
});
|
|
293
454
|
// Legacy endpoint
|
|
294
455
|
this.app.post('/chat', async (req, res) => {
|
|
295
456
|
if (!this.handler) {
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
import type { Request, Response, NextFunction } from 'express';
|
|
2
|
+
export interface AuthConfig {
|
|
3
|
+
apiKeys: string[];
|
|
4
|
+
sessionIsolation?: boolean;
|
|
5
|
+
}
|
|
6
|
+
export interface AuthSession {
|
|
7
|
+
apiKey: string;
|
|
8
|
+
userId: string;
|
|
9
|
+
createdAt: number;
|
|
10
|
+
}
|
|
11
|
+
export declare function createAuthMiddleware(config: AuthConfig): (req: Request, res: Response, next: NextFunction) => void;
|
|
12
|
+
export declare function getActiveSessions(): AuthSession[];
|
|
13
|
+
//# sourceMappingURL=auth.d.ts.map
|
|
@@ -0,0 +1,41 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.createAuthMiddleware = createAuthMiddleware;
|
|
4
|
+
exports.getActiveSessions = getActiveSessions;
|
|
5
|
+
const sessions = new Map();
|
|
6
|
+
function createAuthMiddleware(config) {
|
|
7
|
+
return (req, res, next) => {
|
|
8
|
+
// Skip auth for non-API routes and health/metrics
|
|
9
|
+
if (!req.path.startsWith('/api/') || req.path === '/api/health' || req.path === '/api/metrics') {
|
|
10
|
+
next();
|
|
11
|
+
return;
|
|
12
|
+
}
|
|
13
|
+
const apiKey = req.headers['x-api-key']
|
|
14
|
+
?? req.headers['authorization']?.replace(/^Bearer\s+/i, '')
|
|
15
|
+
?? req.query.apiKey;
|
|
16
|
+
if (!apiKey || !config.apiKeys.includes(apiKey)) {
|
|
17
|
+
res.status(401).json({ error: 'Unauthorized. Provide a valid API key via X-API-Key header, Bearer token, or ?apiKey query.' });
|
|
18
|
+
return;
|
|
19
|
+
}
|
|
20
|
+
// Derive userId from API key for session isolation
|
|
21
|
+
const userId = `user_${hashKey(apiKey)}`;
|
|
22
|
+
if (!sessions.has(apiKey)) {
|
|
23
|
+
sessions.set(apiKey, { apiKey, userId, createdAt: Date.now() });
|
|
24
|
+
}
|
|
25
|
+
// Attach user info to request
|
|
26
|
+
req.userId = userId;
|
|
27
|
+
req.sessionPrefix = config.sessionIsolation ? `${userId}:` : '';
|
|
28
|
+
next();
|
|
29
|
+
};
|
|
30
|
+
}
|
|
31
|
+
function hashKey(key) {
|
|
32
|
+
let h = 0;
|
|
33
|
+
for (let i = 0; i < key.length; i++) {
|
|
34
|
+
h = ((h << 5) - h + key.charCodeAt(i)) | 0;
|
|
35
|
+
}
|
|
36
|
+
return Math.abs(h).toString(36);
|
|
37
|
+
}
|
|
38
|
+
function getActiveSessions() {
|
|
39
|
+
return Array.from(sessions.values());
|
|
40
|
+
}
|
|
41
|
+
//# sourceMappingURL=auth.js.map
|
package/dist/index.d.ts
CHANGED
|
@@ -47,4 +47,13 @@ export { deployToHermes } from './deploy/hermes';
|
|
|
47
47
|
export type { HermesDeployOptions, HermesDeployResult } from './deploy/hermes';
|
|
48
48
|
export { publishAgent, installAgent } from './marketplace';
|
|
49
49
|
export type { AgentManifest, PublishOptions, InstallOptions } from './marketplace';
|
|
50
|
+
export { createAuthMiddleware, getActiveSessions } from './core/auth';
|
|
51
|
+
export type { AuthConfig, AuthSession } from './core/auth';
|
|
52
|
+
export { HttpSkill } from './skills/http';
|
|
53
|
+
export { WebhookTriggerSkill } from './skills/webhook-trigger';
|
|
54
|
+
export type { WebhookTarget } from './skills/webhook-trigger';
|
|
55
|
+
export { SchedulerSkill } from './skills/scheduler';
|
|
56
|
+
export type { ScheduledTask } from './skills/scheduler';
|
|
57
|
+
export { DocumentSkill } from './skills/document';
|
|
58
|
+
export type { DocumentChunk } from './skills/document';
|
|
50
59
|
//# sourceMappingURL=index.d.ts.map
|
package/dist/index.js
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
exports.installAgent = exports.publishAgent = exports.deployToHermes = exports.KnowledgeBase = exports.addMessages = exports.detectLocale = exports.getLocale = exports.setLocale = exports.t = exports.LazyLoader = exports.RequestBatcher = exports.ConnectionPool = exports.VersionManager = exports.WebhookChannel = exports.VoiceChannel = exports.HITLManager = exports.AgentRegistry = exports.WorkflowEngine = exports.Analytics = exports.Sandbox = exports.PluginManager = exports.createMCPTool = exports.MCPToolRegistry = exports.Room = exports.SUPPORTED_PROVIDERS = exports.createProvider = exports.MRGConfigReader = exports.ValueTracker = exports.TrustManager = exports.DeepBrainMemoryStore = exports.InMemoryStore = exports.SkillRegistry = exports.BaseSkill = exports.WebSocketChannel = exports.TelegramChannel = exports.WebChannel = exports.BaseChannel = exports.OADSchema = exports.validateOAD = exports.loadOAD = exports.Logger = exports.truncateOutput = exports.AgentRuntime = exports.BaseAgent = void 0;
|
|
3
|
+
exports.DocumentSkill = exports.SchedulerSkill = exports.WebhookTriggerSkill = exports.HttpSkill = exports.getActiveSessions = exports.createAuthMiddleware = exports.installAgent = exports.publishAgent = exports.deployToHermes = exports.KnowledgeBase = exports.addMessages = exports.detectLocale = exports.getLocale = exports.setLocale = exports.t = exports.LazyLoader = exports.RequestBatcher = exports.ConnectionPool = exports.VersionManager = exports.WebhookChannel = exports.VoiceChannel = exports.HITLManager = exports.AgentRegistry = exports.WorkflowEngine = exports.Analytics = exports.Sandbox = exports.PluginManager = exports.createMCPTool = exports.MCPToolRegistry = exports.Room = exports.SUPPORTED_PROVIDERS = exports.createProvider = exports.MRGConfigReader = exports.ValueTracker = exports.TrustManager = exports.DeepBrainMemoryStore = exports.InMemoryStore = exports.SkillRegistry = exports.BaseSkill = exports.WebSocketChannel = exports.TelegramChannel = exports.WebChannel = exports.BaseChannel = exports.OADSchema = exports.validateOAD = exports.loadOAD = exports.Logger = exports.truncateOutput = exports.AgentRuntime = exports.BaseAgent = void 0;
|
|
4
4
|
// OPC Agent — Open Agent Framework
|
|
5
5
|
var agent_1 = require("./core/agent");
|
|
6
6
|
Object.defineProperty(exports, "BaseAgent", { enumerable: true, get: function () { return agent_1.BaseAgent; } });
|
|
@@ -82,4 +82,16 @@ Object.defineProperty(exports, "deployToHermes", { enumerable: true, get: functi
|
|
|
82
82
|
var marketplace_1 = require("./marketplace");
|
|
83
83
|
Object.defineProperty(exports, "publishAgent", { enumerable: true, get: function () { return marketplace_1.publishAgent; } });
|
|
84
84
|
Object.defineProperty(exports, "installAgent", { enumerable: true, get: function () { return marketplace_1.installAgent; } });
|
|
85
|
+
// v0.7.0 modules
|
|
86
|
+
var auth_1 = require("./core/auth");
|
|
87
|
+
Object.defineProperty(exports, "createAuthMiddleware", { enumerable: true, get: function () { return auth_1.createAuthMiddleware; } });
|
|
88
|
+
Object.defineProperty(exports, "getActiveSessions", { enumerable: true, get: function () { return auth_1.getActiveSessions; } });
|
|
89
|
+
var http_1 = require("./skills/http");
|
|
90
|
+
Object.defineProperty(exports, "HttpSkill", { enumerable: true, get: function () { return http_1.HttpSkill; } });
|
|
91
|
+
var webhook_trigger_1 = require("./skills/webhook-trigger");
|
|
92
|
+
Object.defineProperty(exports, "WebhookTriggerSkill", { enumerable: true, get: function () { return webhook_trigger_1.WebhookTriggerSkill; } });
|
|
93
|
+
var scheduler_1 = require("./skills/scheduler");
|
|
94
|
+
Object.defineProperty(exports, "SchedulerSkill", { enumerable: true, get: function () { return scheduler_1.SchedulerSkill; } });
|
|
95
|
+
var document_1 = require("./skills/document");
|
|
96
|
+
Object.defineProperty(exports, "DocumentSkill", { enumerable: true, get: function () { return document_1.DocumentSkill; } });
|
|
85
97
|
//# sourceMappingURL=index.js.map
|
package/dist/schema/oad.d.ts
CHANGED
|
@@ -77,6 +77,19 @@ export declare const HITLSchema: z.ZodObject<{
|
|
|
77
77
|
defaultTimeoutMs?: number | undefined;
|
|
78
78
|
defaultAction?: "approve" | "deny" | undefined;
|
|
79
79
|
}>;
|
|
80
|
+
export declare const AuthSchema: z.ZodObject<{
|
|
81
|
+
enabled: z.ZodDefault<z.ZodBoolean>;
|
|
82
|
+
apiKeys: z.ZodDefault<z.ZodArray<z.ZodString, "many">>;
|
|
83
|
+
sessionIsolation: z.ZodDefault<z.ZodBoolean>;
|
|
84
|
+
}, "strip", z.ZodTypeAny, {
|
|
85
|
+
enabled: boolean;
|
|
86
|
+
apiKeys: string[];
|
|
87
|
+
sessionIsolation: boolean;
|
|
88
|
+
}, {
|
|
89
|
+
enabled?: boolean | undefined;
|
|
90
|
+
apiKeys?: string[] | undefined;
|
|
91
|
+
sessionIsolation?: boolean | undefined;
|
|
92
|
+
}>;
|
|
80
93
|
export declare const ChannelSchema: z.ZodObject<{
|
|
81
94
|
type: z.ZodEnum<["web", "websocket", "telegram", "cli", "voice", "webhook"]>;
|
|
82
95
|
port: z.ZodOptional<z.ZodNumber>;
|
|
@@ -453,6 +466,19 @@ export declare const SpecSchema: z.ZodObject<{
|
|
|
453
466
|
defaultTimeoutMs?: number | undefined;
|
|
454
467
|
defaultAction?: "approve" | "deny" | undefined;
|
|
455
468
|
}>>;
|
|
469
|
+
auth: z.ZodOptional<z.ZodObject<{
|
|
470
|
+
enabled: z.ZodDefault<z.ZodBoolean>;
|
|
471
|
+
apiKeys: z.ZodDefault<z.ZodArray<z.ZodString, "many">>;
|
|
472
|
+
sessionIsolation: z.ZodDefault<z.ZodBoolean>;
|
|
473
|
+
}, "strip", z.ZodTypeAny, {
|
|
474
|
+
enabled: boolean;
|
|
475
|
+
apiKeys: string[];
|
|
476
|
+
sessionIsolation: boolean;
|
|
477
|
+
}, {
|
|
478
|
+
enabled?: boolean | undefined;
|
|
479
|
+
apiKeys?: string[] | undefined;
|
|
480
|
+
sessionIsolation?: boolean | undefined;
|
|
481
|
+
}>>;
|
|
456
482
|
}, "strip", z.ZodTypeAny, {
|
|
457
483
|
model: string;
|
|
458
484
|
skills: {
|
|
@@ -469,6 +495,11 @@ export declare const SpecSchema: z.ZodObject<{
|
|
|
469
495
|
enabled: boolean;
|
|
470
496
|
chunkSize?: number | undefined;
|
|
471
497
|
};
|
|
498
|
+
auth?: {
|
|
499
|
+
enabled: boolean;
|
|
500
|
+
apiKeys: string[];
|
|
501
|
+
sessionIsolation: boolean;
|
|
502
|
+
} | undefined;
|
|
472
503
|
voice?: {
|
|
473
504
|
enabled: boolean;
|
|
474
505
|
sttProvider?: string | undefined;
|
|
@@ -522,6 +553,11 @@ export declare const SpecSchema: z.ZodObject<{
|
|
|
522
553
|
defaultAction: "approve" | "deny";
|
|
523
554
|
} | undefined;
|
|
524
555
|
}, {
|
|
556
|
+
auth?: {
|
|
557
|
+
enabled?: boolean | undefined;
|
|
558
|
+
apiKeys?: string[] | undefined;
|
|
559
|
+
sessionIsolation?: boolean | undefined;
|
|
560
|
+
} | undefined;
|
|
525
561
|
voice?: {
|
|
526
562
|
enabled?: boolean | undefined;
|
|
527
563
|
sttProvider?: string | undefined;
|
|
@@ -830,6 +866,19 @@ export declare const OADSchema: z.ZodObject<{
|
|
|
830
866
|
defaultTimeoutMs?: number | undefined;
|
|
831
867
|
defaultAction?: "approve" | "deny" | undefined;
|
|
832
868
|
}>>;
|
|
869
|
+
auth: z.ZodOptional<z.ZodObject<{
|
|
870
|
+
enabled: z.ZodDefault<z.ZodBoolean>;
|
|
871
|
+
apiKeys: z.ZodDefault<z.ZodArray<z.ZodString, "many">>;
|
|
872
|
+
sessionIsolation: z.ZodDefault<z.ZodBoolean>;
|
|
873
|
+
}, "strip", z.ZodTypeAny, {
|
|
874
|
+
enabled: boolean;
|
|
875
|
+
apiKeys: string[];
|
|
876
|
+
sessionIsolation: boolean;
|
|
877
|
+
}, {
|
|
878
|
+
enabled?: boolean | undefined;
|
|
879
|
+
apiKeys?: string[] | undefined;
|
|
880
|
+
sessionIsolation?: boolean | undefined;
|
|
881
|
+
}>>;
|
|
833
882
|
}, "strip", z.ZodTypeAny, {
|
|
834
883
|
model: string;
|
|
835
884
|
skills: {
|
|
@@ -846,6 +895,11 @@ export declare const OADSchema: z.ZodObject<{
|
|
|
846
895
|
enabled: boolean;
|
|
847
896
|
chunkSize?: number | undefined;
|
|
848
897
|
};
|
|
898
|
+
auth?: {
|
|
899
|
+
enabled: boolean;
|
|
900
|
+
apiKeys: string[];
|
|
901
|
+
sessionIsolation: boolean;
|
|
902
|
+
} | undefined;
|
|
849
903
|
voice?: {
|
|
850
904
|
enabled: boolean;
|
|
851
905
|
sttProvider?: string | undefined;
|
|
@@ -899,6 +953,11 @@ export declare const OADSchema: z.ZodObject<{
|
|
|
899
953
|
defaultAction: "approve" | "deny";
|
|
900
954
|
} | undefined;
|
|
901
955
|
}, {
|
|
956
|
+
auth?: {
|
|
957
|
+
enabled?: boolean | undefined;
|
|
958
|
+
apiKeys?: string[] | undefined;
|
|
959
|
+
sessionIsolation?: boolean | undefined;
|
|
960
|
+
} | undefined;
|
|
902
961
|
voice?: {
|
|
903
962
|
enabled?: boolean | undefined;
|
|
904
963
|
sttProvider?: string | undefined;
|
|
@@ -999,6 +1058,11 @@ export declare const OADSchema: z.ZodObject<{
|
|
|
999
1058
|
enabled: boolean;
|
|
1000
1059
|
chunkSize?: number | undefined;
|
|
1001
1060
|
};
|
|
1061
|
+
auth?: {
|
|
1062
|
+
enabled: boolean;
|
|
1063
|
+
apiKeys: string[];
|
|
1064
|
+
sessionIsolation: boolean;
|
|
1065
|
+
} | undefined;
|
|
1002
1066
|
voice?: {
|
|
1003
1067
|
enabled: boolean;
|
|
1004
1068
|
sttProvider?: string | undefined;
|
|
@@ -1069,6 +1133,11 @@ export declare const OADSchema: z.ZodObject<{
|
|
|
1069
1133
|
} | undefined;
|
|
1070
1134
|
};
|
|
1071
1135
|
spec: {
|
|
1136
|
+
auth?: {
|
|
1137
|
+
enabled?: boolean | undefined;
|
|
1138
|
+
apiKeys?: string[] | undefined;
|
|
1139
|
+
sessionIsolation?: boolean | undefined;
|
|
1140
|
+
} | undefined;
|
|
1072
1141
|
voice?: {
|
|
1073
1142
|
enabled?: boolean | undefined;
|
|
1074
1143
|
sttProvider?: string | undefined;
|
package/dist/schema/oad.js
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
exports.OADSchema = exports.SpecSchema = exports.StreamingSchema = exports.RoomSchema = exports.MetadataSchema = exports.MarketplaceSchema = exports.ProviderSchema = exports.DTVSchema = exports.TrustLevel = exports.MemorySchema = exports.LongTermMemorySchema = exports.ChannelSchema = exports.HITLSchema = exports.WebhookSchema = exports.VoiceSchema = exports.WorkflowSchema = exports.WorkflowStepSchema = exports.SkillRefSchema = void 0;
|
|
3
|
+
exports.OADSchema = exports.SpecSchema = exports.StreamingSchema = exports.RoomSchema = exports.MetadataSchema = exports.MarketplaceSchema = exports.ProviderSchema = exports.DTVSchema = exports.TrustLevel = exports.MemorySchema = exports.LongTermMemorySchema = exports.ChannelSchema = exports.AuthSchema = exports.HITLSchema = exports.WebhookSchema = exports.VoiceSchema = exports.WorkflowSchema = exports.WorkflowStepSchema = exports.SkillRefSchema = void 0;
|
|
4
4
|
const zod_1 = require("zod");
|
|
5
5
|
// ─── OAD Schema v1 ───────────────────────────────────────────
|
|
6
6
|
exports.SkillRefSchema = zod_1.z.object({
|
|
@@ -43,6 +43,11 @@ exports.HITLSchema = zod_1.z.object({
|
|
|
43
43
|
defaultTimeoutMs: zod_1.z.number().default(60000),
|
|
44
44
|
defaultAction: zod_1.z.enum(['approve', 'deny']).default('deny'),
|
|
45
45
|
});
|
|
46
|
+
exports.AuthSchema = zod_1.z.object({
|
|
47
|
+
enabled: zod_1.z.boolean().default(false),
|
|
48
|
+
apiKeys: zod_1.z.array(zod_1.z.string()).default([]),
|
|
49
|
+
sessionIsolation: zod_1.z.boolean().default(true),
|
|
50
|
+
});
|
|
46
51
|
exports.ChannelSchema = zod_1.z.object({
|
|
47
52
|
type: zod_1.z.enum(['web', 'websocket', 'telegram', 'cli', 'voice', 'webhook']),
|
|
48
53
|
port: zod_1.z.number().optional(),
|
|
@@ -109,6 +114,7 @@ exports.SpecSchema = zod_1.z.object({
|
|
|
109
114
|
voice: exports.VoiceSchema.optional(),
|
|
110
115
|
webhook: exports.WebhookSchema.optional(),
|
|
111
116
|
hitl: exports.HITLSchema.optional(),
|
|
117
|
+
auth: exports.AuthSchema.optional(),
|
|
112
118
|
});
|
|
113
119
|
exports.OADSchema = zod_1.z.object({
|
|
114
120
|
apiVersion: zod_1.z.literal('opc/v1'),
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
import { BaseSkill } from './base';
|
|
2
|
+
import type { AgentContext, Message, SkillResult } from '../core/types';
|
|
3
|
+
export interface DocumentChunk {
|
|
4
|
+
content: string;
|
|
5
|
+
metadata: {
|
|
6
|
+
filename: string;
|
|
7
|
+
mimeType: string;
|
|
8
|
+
chunkIndex: number;
|
|
9
|
+
totalChunks: number;
|
|
10
|
+
};
|
|
11
|
+
}
|
|
12
|
+
export declare class DocumentSkill extends BaseSkill {
|
|
13
|
+
name: string;
|
|
14
|
+
description: string;
|
|
15
|
+
private knowledgeBase;
|
|
16
|
+
constructor(kbPath?: string);
|
|
17
|
+
execute(context: AgentContext, message: Message): Promise<SkillResult>;
|
|
18
|
+
extractText(content: string, mimeType: string): string;
|
|
19
|
+
chunk(text: string, size?: number, overlap?: number): DocumentChunk[];
|
|
20
|
+
private guessMime;
|
|
21
|
+
/** Process raw text content directly (for API uploads) */
|
|
22
|
+
processText(content: string, filename: string): Promise<{
|
|
23
|
+
chunks: number;
|
|
24
|
+
chars: number;
|
|
25
|
+
}>;
|
|
26
|
+
}
|
|
27
|
+
//# sourceMappingURL=document.d.ts.map
|
|
@@ -0,0 +1,80 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.DocumentSkill = void 0;
|
|
4
|
+
const base_1 = require("./base");
|
|
5
|
+
const knowledge_1 = require("../core/knowledge");
|
|
6
|
+
class DocumentSkill extends base_1.BaseSkill {
|
|
7
|
+
name = 'document';
|
|
8
|
+
description = 'Process uploaded documents (PDF, TXT, MD, DOCX). Chunks content and adds to knowledge base.';
|
|
9
|
+
knowledgeBase;
|
|
10
|
+
constructor(kbPath = '.') {
|
|
11
|
+
super();
|
|
12
|
+
this.knowledgeBase = new knowledge_1.KnowledgeBase(kbPath);
|
|
13
|
+
}
|
|
14
|
+
async execute(context, message) {
|
|
15
|
+
// Check if message has document attachment metadata
|
|
16
|
+
const meta = message.metadata;
|
|
17
|
+
if (!meta?.document)
|
|
18
|
+
return this.noMatch();
|
|
19
|
+
const { content, filename, mimeType } = meta.document;
|
|
20
|
+
try {
|
|
21
|
+
const text = this.extractText(content, mimeType ?? this.guessMime(filename));
|
|
22
|
+
const chunks = this.chunk(text, 1000, 100);
|
|
23
|
+
const result = await this.knowledgeBase.addText(chunks.map(c => c.content).join('\n\n---\n\n'), filename);
|
|
24
|
+
return this.match(`📄 Processed "${filename}": ${chunks.length} chunks, ${text.length} chars → added to knowledge base (${result.chunks} KB entries)`);
|
|
25
|
+
}
|
|
26
|
+
catch (err) {
|
|
27
|
+
return this.match(`Document processing error: ${err instanceof Error ? err.message : String(err)}`);
|
|
28
|
+
}
|
|
29
|
+
}
|
|
30
|
+
extractText(content, mimeType) {
|
|
31
|
+
// For plain text formats, content is already text
|
|
32
|
+
if (mimeType.includes('text/') || mimeType.includes('markdown')) {
|
|
33
|
+
return content;
|
|
34
|
+
}
|
|
35
|
+
// For other formats, assume base64-encoded or pre-extracted text
|
|
36
|
+
// In a real implementation, you'd use pdf-parse, mammoth, etc.
|
|
37
|
+
return content;
|
|
38
|
+
}
|
|
39
|
+
chunk(text, size = 1000, overlap = 100) {
|
|
40
|
+
const chunks = [];
|
|
41
|
+
let start = 0;
|
|
42
|
+
while (start < text.length) {
|
|
43
|
+
const end = Math.min(start + size, text.length);
|
|
44
|
+
chunks.push({
|
|
45
|
+
content: text.slice(start, end),
|
|
46
|
+
metadata: {
|
|
47
|
+
filename: '',
|
|
48
|
+
mimeType: '',
|
|
49
|
+
chunkIndex: chunks.length,
|
|
50
|
+
totalChunks: 0, // filled after
|
|
51
|
+
},
|
|
52
|
+
});
|
|
53
|
+
start = end - overlap;
|
|
54
|
+
if (start >= text.length)
|
|
55
|
+
break;
|
|
56
|
+
}
|
|
57
|
+
// Fill totalChunks
|
|
58
|
+
for (const c of chunks)
|
|
59
|
+
c.metadata.totalChunks = chunks.length;
|
|
60
|
+
return chunks;
|
|
61
|
+
}
|
|
62
|
+
guessMime(filename) {
|
|
63
|
+
const ext = filename.split('.').pop()?.toLowerCase();
|
|
64
|
+
switch (ext) {
|
|
65
|
+
case 'pdf': return 'application/pdf';
|
|
66
|
+
case 'txt': return 'text/plain';
|
|
67
|
+
case 'md': return 'text/markdown';
|
|
68
|
+
case 'docx': return 'application/vnd.openxmlformats-officedocument.wordprocessingml.document';
|
|
69
|
+
default: return 'text/plain';
|
|
70
|
+
}
|
|
71
|
+
}
|
|
72
|
+
/** Process raw text content directly (for API uploads) */
|
|
73
|
+
async processText(content, filename) {
|
|
74
|
+
const chunks = this.chunk(content);
|
|
75
|
+
const result = await this.knowledgeBase.addText(content, filename);
|
|
76
|
+
return { chunks: chunks.length, chars: content.length };
|
|
77
|
+
}
|
|
78
|
+
}
|
|
79
|
+
exports.DocumentSkill = DocumentSkill;
|
|
80
|
+
//# sourceMappingURL=document.js.map
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
import { BaseSkill } from './base';
|
|
2
|
+
import type { AgentContext, Message, SkillResult } from '../core/types';
|
|
3
|
+
export declare class HttpSkill extends BaseSkill {
|
|
4
|
+
name: string;
|
|
5
|
+
description: string;
|
|
6
|
+
execute(context: AgentContext, message: Message): Promise<SkillResult>;
|
|
7
|
+
}
|
|
8
|
+
//# sourceMappingURL=http.d.ts.map
|
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.HttpSkill = void 0;
|
|
4
|
+
const base_1 = require("./base");
|
|
5
|
+
class HttpSkill extends base_1.BaseSkill {
|
|
6
|
+
name = 'http';
|
|
7
|
+
description = 'Make HTTP requests to external APIs. Usage: http GET|POST|PUT|DELETE <url> [body]';
|
|
8
|
+
async execute(context, message) {
|
|
9
|
+
const text = message.content.trim();
|
|
10
|
+
const match = text.match(/^http\s+(GET|POST|PUT|PATCH|DELETE)\s+(\S+)(?:\s+(.+))?$/is);
|
|
11
|
+
if (!match)
|
|
12
|
+
return this.noMatch();
|
|
13
|
+
const [, method, url, bodyStr] = match;
|
|
14
|
+
try {
|
|
15
|
+
const opts = {
|
|
16
|
+
method: method.toUpperCase(),
|
|
17
|
+
headers: { 'Content-Type': 'application/json', 'User-Agent': 'OPC-Agent/0.7.0' },
|
|
18
|
+
};
|
|
19
|
+
if (bodyStr && ['POST', 'PUT', 'PATCH'].includes(method.toUpperCase())) {
|
|
20
|
+
opts.body = bodyStr;
|
|
21
|
+
}
|
|
22
|
+
const res = await fetch(url, opts);
|
|
23
|
+
const contentType = res.headers.get('content-type') ?? '';
|
|
24
|
+
const body = contentType.includes('json') ? JSON.stringify(await res.json(), null, 2) : await res.text();
|
|
25
|
+
const truncated = body.length > 4000 ? body.slice(0, 4000) + '\n...[truncated]' : body;
|
|
26
|
+
return this.match(`HTTP ${res.status} ${res.statusText}\n\n${truncated}`);
|
|
27
|
+
}
|
|
28
|
+
catch (err) {
|
|
29
|
+
return this.match(`HTTP Error: ${err instanceof Error ? err.message : String(err)}`);
|
|
30
|
+
}
|
|
31
|
+
}
|
|
32
|
+
}
|
|
33
|
+
exports.HttpSkill = HttpSkill;
|
|
34
|
+
//# sourceMappingURL=http.js.map
|