opc-agent 0.5.1 → 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.
@@ -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;
@@ -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
@@ -0,0 +1,21 @@
1
+ import { BaseSkill } from './base';
2
+ import type { AgentContext, Message, SkillResult } from '../core/types';
3
+ export interface ScheduledTask {
4
+ id: string;
5
+ name: string;
6
+ cronExpr: string;
7
+ action: string;
8
+ enabled: boolean;
9
+ lastRun?: number;
10
+ nextRun?: number;
11
+ }
12
+ export declare class SchedulerSkill extends BaseSkill {
13
+ name: string;
14
+ description: string;
15
+ private tasks;
16
+ private timers;
17
+ execute(context: AgentContext, message: Message): Promise<SkillResult>;
18
+ private parseCronToInterval;
19
+ destroy(): void;
20
+ }
21
+ //# sourceMappingURL=scheduler.d.ts.map
@@ -0,0 +1,70 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.SchedulerSkill = void 0;
4
+ const base_1 = require("./base");
5
+ class SchedulerSkill extends base_1.BaseSkill {
6
+ name = 'scheduler';
7
+ description = 'Schedule recurring tasks. Usage: schedule list | schedule add <name> <cron> <action> | schedule remove <id>';
8
+ tasks = new Map();
9
+ timers = new Map();
10
+ async execute(context, message) {
11
+ const text = message.content.trim();
12
+ if (/^schedule\s+list$/i.test(text)) {
13
+ if (this.tasks.size === 0)
14
+ return this.match('No scheduled tasks.');
15
+ const lines = Array.from(this.tasks.values()).map(t => `• ${t.name} (${t.id}) — ${t.cronExpr} — ${t.enabled ? '✅' : '❌'} — Last: ${t.lastRun ? new Date(t.lastRun).toISOString() : 'never'}`);
16
+ return this.match(`Scheduled tasks:\n${lines.join('\n')}`);
17
+ }
18
+ const addMatch = text.match(/^schedule\s+add\s+(\S+)\s+(".*?"|\S+)\s+(.+)$/i);
19
+ if (addMatch) {
20
+ const [, name, cronExpr, action] = addMatch;
21
+ const id = `task_${Date.now().toString(36)}`;
22
+ const task = {
23
+ id, name, cronExpr: cronExpr.replace(/"/g, ''), action, enabled: true,
24
+ };
25
+ this.tasks.set(id, task);
26
+ // Simple interval-based scheduling (parse cron for interval in minutes)
27
+ const intervalMs = this.parseCronToInterval(task.cronExpr);
28
+ if (intervalMs > 0) {
29
+ const timer = setInterval(() => {
30
+ task.lastRun = Date.now();
31
+ }, intervalMs);
32
+ this.timers.set(id, timer);
33
+ }
34
+ return this.match(`Task scheduled: ${name} (${id}) — ${task.cronExpr} → "${action}"`);
35
+ }
36
+ const rmMatch = text.match(/^schedule\s+remove\s+(\S+)$/i);
37
+ if (rmMatch) {
38
+ const id = rmMatch[1];
39
+ const timer = this.timers.get(id);
40
+ if (timer)
41
+ clearInterval(timer);
42
+ this.timers.delete(id);
43
+ const removed = this.tasks.delete(id);
44
+ return this.match(removed ? `Task ${id} removed.` : `Task ${id} not found.`);
45
+ }
46
+ return this.noMatch();
47
+ }
48
+ parseCronToInterval(expr) {
49
+ // Simple: support "every Xm" or "every Xh" or basic intervals
50
+ const m = expr.match(/every\s+(\d+)\s*(m|min|h|hr|s|sec)/i);
51
+ if (m) {
52
+ const val = parseInt(m[1]);
53
+ const unit = m[2].toLowerCase();
54
+ if (unit.startsWith('h'))
55
+ return val * 3600_000;
56
+ if (unit.startsWith('m'))
57
+ return val * 60_000;
58
+ if (unit.startsWith('s'))
59
+ return val * 1000;
60
+ }
61
+ return 0; // Unknown cron format, no auto-schedule
62
+ }
63
+ destroy() {
64
+ for (const timer of this.timers.values())
65
+ clearInterval(timer);
66
+ this.timers.clear();
67
+ }
68
+ }
69
+ exports.SchedulerSkill = SchedulerSkill;
70
+ //# sourceMappingURL=scheduler.js.map
@@ -0,0 +1,17 @@
1
+ import { BaseSkill } from './base';
2
+ import type { AgentContext, Message, SkillResult } from '../core/types';
3
+ export interface WebhookTarget {
4
+ name: string;
5
+ url: string;
6
+ method?: string;
7
+ headers?: Record<string, string>;
8
+ secret?: string;
9
+ }
10
+ export declare class WebhookTriggerSkill extends BaseSkill {
11
+ name: string;
12
+ description: string;
13
+ private targets;
14
+ registerTarget(target: WebhookTarget): void;
15
+ execute(context: AgentContext, message: Message): Promise<SkillResult>;
16
+ }
17
+ //# sourceMappingURL=webhook-trigger.d.ts.map
@@ -0,0 +1,49 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.WebhookTriggerSkill = void 0;
4
+ const base_1 = require("./base");
5
+ class WebhookTriggerSkill extends base_1.BaseSkill {
6
+ name = 'webhook-trigger';
7
+ description = 'Trigger external webhooks. Usage: webhook <name> [payload JSON]';
8
+ targets = new Map();
9
+ registerTarget(target) {
10
+ this.targets.set(target.name, target);
11
+ }
12
+ async execute(context, message) {
13
+ const match = message.content.trim().match(/^webhook\s+(\S+)(?:\s+(.+))?$/is);
14
+ if (!match)
15
+ return this.noMatch();
16
+ const [, name, payloadStr] = match;
17
+ const target = this.targets.get(name);
18
+ if (!target) {
19
+ const available = Array.from(this.targets.keys()).join(', ') || 'none';
20
+ return this.match(`Unknown webhook "${name}". Available: ${available}`);
21
+ }
22
+ try {
23
+ const headers = {
24
+ 'Content-Type': 'application/json',
25
+ 'User-Agent': 'OPC-Agent/0.7.0',
26
+ ...target.headers,
27
+ };
28
+ if (target.secret) {
29
+ headers['X-Webhook-Secret'] = target.secret;
30
+ }
31
+ const body = payloadStr ?? JSON.stringify({
32
+ agent: context.agentName,
33
+ timestamp: Date.now(),
34
+ trigger: 'manual',
35
+ });
36
+ const res = await fetch(target.url, {
37
+ method: target.method ?? 'POST',
38
+ headers,
39
+ body,
40
+ });
41
+ return this.match(`Webhook "${name}" triggered → ${res.status} ${res.statusText}`);
42
+ }
43
+ catch (err) {
44
+ return this.match(`Webhook error: ${err instanceof Error ? err.message : String(err)}`);
45
+ }
46
+ }
47
+ }
48
+ exports.WebhookTriggerSkill = WebhookTriggerSkill;
49
+ //# sourceMappingURL=webhook-trigger.js.map
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "opc-agent",
3
- "version": "0.5.1",
3
+ "version": "0.7.0",
4
4
  "description": "Open Agent Framework — Build, test, and run AI Agents for business workstations",
5
5
  "main": "dist/index.js",
6
6
  "types": "dist/index.d.ts",