opc-agent 2.0.2 → 3.0.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/README.md +603 -545
- package/dist/channels/voice.d.ts +59 -0
- package/dist/channels/voice.js +351 -1
- package/dist/cli.js +284 -5
- package/dist/core/agent.d.ts +9 -0
- package/dist/core/agent.js +49 -0
- package/dist/core/collaboration.d.ts +89 -0
- package/dist/core/collaboration.js +201 -0
- package/dist/deploy/index.d.ts +40 -0
- package/dist/deploy/index.js +261 -0
- package/dist/index.d.ts +7 -1
- package/dist/index.js +47 -3
- package/dist/mcp/servers/calculator-mcp.d.ts +3 -0
- package/dist/mcp/servers/calculator-mcp.js +65 -0
- package/dist/mcp/servers/crypto-mcp.d.ts +3 -0
- package/dist/mcp/servers/crypto-mcp.js +108 -0
- package/dist/mcp/servers/database-mcp.d.ts +3 -0
- package/dist/mcp/servers/database-mcp.js +73 -0
- package/dist/mcp/servers/datetime-mcp.d.ts +3 -0
- package/dist/mcp/servers/datetime-mcp.js +71 -0
- package/dist/mcp/servers/filesystem.d.ts +3 -0
- package/dist/mcp/servers/filesystem.js +101 -0
- package/dist/mcp/servers/github-mcp.d.ts +3 -0
- package/dist/mcp/servers/github-mcp.js +60 -0
- package/dist/mcp/servers/index.d.ts +21 -0
- package/dist/mcp/servers/index.js +50 -0
- package/dist/mcp/servers/json-mcp.d.ts +3 -0
- package/dist/mcp/servers/json-mcp.js +126 -0
- package/dist/mcp/servers/memory-mcp.d.ts +3 -0
- package/dist/mcp/servers/memory-mcp.js +60 -0
- package/dist/mcp/servers/regex-mcp.d.ts +3 -0
- package/dist/mcp/servers/regex-mcp.js +56 -0
- package/dist/mcp/servers/web-mcp.d.ts +3 -0
- package/dist/mcp/servers/web-mcp.js +51 -0
- package/dist/memory/index.d.ts +2 -0
- package/dist/memory/index.js +4 -1
- package/dist/memory/seed-loader.d.ts +51 -0
- package/dist/memory/seed-loader.js +200 -0
- package/dist/schema/oad.d.ts +292 -12
- package/dist/schema/oad.js +12 -1
- package/dist/security/guardrails.d.ts +50 -0
- package/dist/security/guardrails.js +197 -0
- package/dist/studio/server.d.ts +31 -1
- package/dist/studio/server.js +154 -3
- package/dist/studio-ui/index.html +1278 -662
- package/dist/tools/integrations/calendar.d.ts +3 -0
- package/dist/tools/integrations/calendar.js +73 -0
- package/dist/tools/integrations/code-exec.d.ts +3 -0
- package/dist/tools/integrations/code-exec.js +42 -0
- package/dist/tools/integrations/csv-analyzer.d.ts +3 -0
- package/dist/tools/integrations/csv-analyzer.js +142 -0
- package/dist/tools/integrations/database.d.ts +3 -0
- package/dist/tools/integrations/database.js +44 -0
- package/dist/tools/integrations/email-send.d.ts +3 -0
- package/dist/tools/integrations/email-send.js +104 -0
- package/dist/tools/integrations/git-tool.d.ts +3 -0
- package/dist/tools/integrations/git-tool.js +49 -0
- package/dist/tools/integrations/github-tool.d.ts +3 -0
- package/dist/tools/integrations/github-tool.js +77 -0
- package/dist/tools/integrations/image-gen.d.ts +3 -0
- package/dist/tools/integrations/image-gen.js +58 -0
- package/dist/tools/integrations/index.d.ts +30 -0
- package/dist/tools/integrations/index.js +107 -0
- package/dist/tools/integrations/jira.d.ts +3 -0
- package/dist/tools/integrations/jira.js +85 -0
- package/dist/tools/integrations/notion.d.ts +3 -0
- package/dist/tools/integrations/notion.js +71 -0
- package/dist/tools/integrations/npm-tool.d.ts +3 -0
- package/dist/tools/integrations/npm-tool.js +49 -0
- package/dist/tools/integrations/pdf-reader.d.ts +3 -0
- package/dist/tools/integrations/pdf-reader.js +91 -0
- package/dist/tools/integrations/slack.d.ts +3 -0
- package/dist/tools/integrations/slack.js +67 -0
- package/dist/tools/integrations/summarizer.d.ts +3 -0
- package/dist/tools/integrations/summarizer.js +49 -0
- package/dist/tools/integrations/translator.d.ts +3 -0
- package/dist/tools/integrations/translator.js +48 -0
- package/dist/tools/integrations/trello.d.ts +3 -0
- package/dist/tools/integrations/trello.js +60 -0
- package/dist/tools/integrations/vector-search.d.ts +3 -0
- package/dist/tools/integrations/vector-search.js +44 -0
- package/dist/tools/integrations/web-scraper.d.ts +3 -0
- package/dist/tools/integrations/web-scraper.js +48 -0
- package/dist/tools/integrations/web-search.d.ts +3 -0
- package/dist/tools/integrations/web-search.js +60 -0
- package/dist/tools/integrations/webhook.d.ts +3 -0
- package/dist/tools/integrations/webhook.js +39 -0
- package/dist/ui/components.d.ts +10 -0
- package/dist/ui/components.js +123 -0
- package/package.json +1 -1
- package/src/channels/voice.ts +365 -0
- package/src/cli.ts +294 -6
- package/src/core/agent.ts +56 -0
- package/src/core/collaboration.ts +275 -0
- package/src/deploy/index.ts +255 -0
- package/src/index.ts +21 -1
- package/src/mcp/servers/calculator-mcp.ts +65 -0
- package/src/mcp/servers/crypto-mcp.ts +73 -0
- package/src/mcp/servers/database-mcp.ts +72 -0
- package/src/mcp/servers/datetime-mcp.ts +69 -0
- package/src/mcp/servers/filesystem.ts +66 -0
- package/src/mcp/servers/github-mcp.ts +58 -0
- package/src/mcp/servers/index.ts +63 -0
- package/src/mcp/servers/json-mcp.ts +102 -0
- package/src/mcp/servers/memory-mcp.ts +56 -0
- package/src/mcp/servers/regex-mcp.ts +53 -0
- package/src/mcp/servers/web-mcp.ts +49 -0
- package/src/memory/index.ts +3 -0
- package/src/memory/seed-loader.ts +212 -0
- package/src/schema/oad.ts +13 -0
- package/src/security/guardrails.ts +248 -0
- package/src/studio/server.ts +166 -4
- package/src/studio-ui/index.html +1278 -662
- package/src/tools/integrations/calendar.ts +73 -0
- package/src/tools/integrations/code-exec.ts +39 -0
- package/src/tools/integrations/csv-analyzer.ts +92 -0
- package/src/tools/integrations/database.ts +44 -0
- package/src/tools/integrations/email-send.ts +76 -0
- package/src/tools/integrations/git-tool.ts +42 -0
- package/src/tools/integrations/github-tool.ts +76 -0
- package/src/tools/integrations/image-gen.ts +56 -0
- package/src/tools/integrations/index.ts +92 -0
- package/src/tools/integrations/jira.ts +83 -0
- package/src/tools/integrations/notion.ts +71 -0
- package/src/tools/integrations/npm-tool.ts +48 -0
- package/src/tools/integrations/pdf-reader.ts +58 -0
- package/src/tools/integrations/slack.ts +65 -0
- package/src/tools/integrations/summarizer.ts +49 -0
- package/src/tools/integrations/translator.ts +48 -0
- package/src/tools/integrations/trello.ts +60 -0
- package/src/tools/integrations/vector-search.ts +42 -0
- package/src/tools/integrations/web-scraper.ts +47 -0
- package/src/tools/integrations/web-search.ts +58 -0
- package/src/tools/integrations/webhook.ts +38 -0
- package/src/ui/components.ts +127 -0
- package/tests/brain-seed-extended.test.ts +490 -0
- package/tests/brain-seed.test.ts +239 -0
- package/tests/collaboration.test.ts +319 -0
- package/tests/deploy-and-dag.test.ts +196 -0
- package/tests/guardrails.test.ts +177 -0
- package/tests/integrations.test.ts +249 -0
- package/tests/mcp-servers.test.ts +260 -0
- package/tests/voice-enhanced.test.ts +169 -0
- package/dist/dtv/data.d.ts +0 -18
- package/dist/dtv/data.js +0 -25
- package/dist/dtv/trust.d.ts +0 -19
- package/dist/dtv/trust.js +0 -40
- package/dist/dtv/value.d.ts +0 -23
- package/dist/dtv/value.js +0 -38
- package/dist/marketplace/index.d.ts +0 -34
- package/dist/marketplace/index.js +0 -202
|
@@ -0,0 +1,126 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.createJsonServer = createJsonServer;
|
|
4
|
+
function jsonPathQuery(obj, path) {
|
|
5
|
+
const parts = path.replace(/^\$\.?/, '').split('.');
|
|
6
|
+
let current = [obj];
|
|
7
|
+
for (const part of parts) {
|
|
8
|
+
if (!part)
|
|
9
|
+
continue;
|
|
10
|
+
const next = [];
|
|
11
|
+
for (const item of current) {
|
|
12
|
+
if (part === '*') {
|
|
13
|
+
if (Array.isArray(item))
|
|
14
|
+
next.push(...item);
|
|
15
|
+
else if (typeof item === 'object' && item)
|
|
16
|
+
next.push(...Object.values(item));
|
|
17
|
+
}
|
|
18
|
+
else if (part.match(/^\[(\d+)\]$/)) {
|
|
19
|
+
const idx = parseInt(part.slice(1, -1));
|
|
20
|
+
if (Array.isArray(item) && item[idx] !== undefined)
|
|
21
|
+
next.push(item[idx]);
|
|
22
|
+
}
|
|
23
|
+
else {
|
|
24
|
+
if (item && typeof item === 'object' && part in item)
|
|
25
|
+
next.push(item[part]);
|
|
26
|
+
}
|
|
27
|
+
}
|
|
28
|
+
current = next;
|
|
29
|
+
}
|
|
30
|
+
return current;
|
|
31
|
+
}
|
|
32
|
+
function createJsonServer() {
|
|
33
|
+
return {
|
|
34
|
+
name: 'json',
|
|
35
|
+
version: '1.0.0',
|
|
36
|
+
tools: [
|
|
37
|
+
{
|
|
38
|
+
name: 'json_query',
|
|
39
|
+
description: 'Query JSON data using dot-notation path (e.g. "users.0.name", "items.*")',
|
|
40
|
+
inputSchema: { type: 'object', properties: { data: { description: 'JSON string or object' }, path: { type: 'string', description: 'Dot-notation path' } }, required: ['data', 'path'] },
|
|
41
|
+
handler: async (args) => {
|
|
42
|
+
const obj = typeof args.data === 'string' ? JSON.parse(args.data) : args.data;
|
|
43
|
+
return { results: jsonPathQuery(obj, args.path) };
|
|
44
|
+
},
|
|
45
|
+
},
|
|
46
|
+
{
|
|
47
|
+
name: 'json_transform',
|
|
48
|
+
description: 'Transform JSON: pick fields, rename keys, flatten',
|
|
49
|
+
inputSchema: { type: 'object', properties: { data: {}, operation: { type: 'string', enum: ['pick', 'omit', 'flatten', 'keys', 'values'] }, fields: { type: 'array', items: { type: 'string' } } }, required: ['data', 'operation'] },
|
|
50
|
+
handler: async (args) => {
|
|
51
|
+
const obj = typeof args.data === 'string' ? JSON.parse(args.data) : args.data;
|
|
52
|
+
switch (args.operation) {
|
|
53
|
+
case 'pick': {
|
|
54
|
+
const result = {};
|
|
55
|
+
for (const f of args.fields || [])
|
|
56
|
+
if (f in obj)
|
|
57
|
+
result[f] = obj[f];
|
|
58
|
+
return { result };
|
|
59
|
+
}
|
|
60
|
+
case 'omit': {
|
|
61
|
+
const result = { ...obj };
|
|
62
|
+
for (const f of args.fields || [])
|
|
63
|
+
delete result[f];
|
|
64
|
+
return { result };
|
|
65
|
+
}
|
|
66
|
+
case 'flatten': {
|
|
67
|
+
const result = {};
|
|
68
|
+
const recurse = (o, prefix) => {
|
|
69
|
+
for (const [k, v] of Object.entries(o)) {
|
|
70
|
+
const key = prefix ? `${prefix}.${k}` : k;
|
|
71
|
+
if (v && typeof v === 'object' && !Array.isArray(v))
|
|
72
|
+
recurse(v, key);
|
|
73
|
+
else
|
|
74
|
+
result[key] = v;
|
|
75
|
+
}
|
|
76
|
+
};
|
|
77
|
+
recurse(obj, '');
|
|
78
|
+
return { result };
|
|
79
|
+
}
|
|
80
|
+
case 'keys': return { result: Object.keys(obj) };
|
|
81
|
+
case 'values': return { result: Object.values(obj) };
|
|
82
|
+
default: throw new Error(`Unknown operation: ${args.operation}`);
|
|
83
|
+
}
|
|
84
|
+
},
|
|
85
|
+
},
|
|
86
|
+
{
|
|
87
|
+
name: 'json_validate',
|
|
88
|
+
description: 'Check if a string is valid JSON',
|
|
89
|
+
inputSchema: { type: 'object', properties: { data: { type: 'string' } }, required: ['data'] },
|
|
90
|
+
handler: async (args) => {
|
|
91
|
+
try {
|
|
92
|
+
JSON.parse(args.data);
|
|
93
|
+
return { valid: true };
|
|
94
|
+
}
|
|
95
|
+
catch (e) {
|
|
96
|
+
return { valid: false, error: e.message };
|
|
97
|
+
}
|
|
98
|
+
},
|
|
99
|
+
},
|
|
100
|
+
{
|
|
101
|
+
name: 'json_diff',
|
|
102
|
+
description: 'Compare two JSON objects and return differences',
|
|
103
|
+
inputSchema: { type: 'object', properties: { a: {}, b: {} }, required: ['a', 'b'] },
|
|
104
|
+
handler: async (args) => {
|
|
105
|
+
const a = typeof args.a === 'string' ? JSON.parse(args.a) : args.a;
|
|
106
|
+
const b = typeof args.b === 'string' ? JSON.parse(args.b) : args.b;
|
|
107
|
+
const diffs = [];
|
|
108
|
+
const compare = (x, y, path) => {
|
|
109
|
+
if (x === y)
|
|
110
|
+
return;
|
|
111
|
+
if (typeof x !== typeof y || typeof x !== 'object' || !x || !y) {
|
|
112
|
+
diffs.push({ path, a: x, b: y });
|
|
113
|
+
return;
|
|
114
|
+
}
|
|
115
|
+
const keys = new Set([...Object.keys(x), ...Object.keys(y)]);
|
|
116
|
+
for (const k of keys)
|
|
117
|
+
compare(x[k], y[k], path ? `${path}.${k}` : k);
|
|
118
|
+
};
|
|
119
|
+
compare(a, b, '');
|
|
120
|
+
return { equal: diffs.length === 0, differences: diffs };
|
|
121
|
+
},
|
|
122
|
+
},
|
|
123
|
+
],
|
|
124
|
+
};
|
|
125
|
+
}
|
|
126
|
+
//# sourceMappingURL=json-mcp.js.map
|
|
@@ -0,0 +1,60 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.createMemoryServer = createMemoryServer;
|
|
4
|
+
function createMemoryServer() {
|
|
5
|
+
const store = new Map();
|
|
6
|
+
return {
|
|
7
|
+
name: 'memory',
|
|
8
|
+
version: '1.0.0',
|
|
9
|
+
tools: [
|
|
10
|
+
{
|
|
11
|
+
name: 'memory_store',
|
|
12
|
+
description: 'Store a key-value pair in memory with optional tags',
|
|
13
|
+
inputSchema: { type: 'object', properties: { key: { type: 'string' }, value: { type: 'any' }, tags: { type: 'array', items: { type: 'string' } } }, required: ['key', 'value'] },
|
|
14
|
+
handler: async (args) => {
|
|
15
|
+
const now = new Date().toISOString();
|
|
16
|
+
const existing = store.get(args.key);
|
|
17
|
+
store.set(args.key, { value: args.value, tags: args.tags || [], created: existing?.created || now, updated: now });
|
|
18
|
+
return { stored: args.key };
|
|
19
|
+
},
|
|
20
|
+
},
|
|
21
|
+
{
|
|
22
|
+
name: 'memory_recall',
|
|
23
|
+
description: 'Recall a value by key',
|
|
24
|
+
inputSchema: { type: 'object', properties: { key: { type: 'string' } }, required: ['key'] },
|
|
25
|
+
handler: async (args) => {
|
|
26
|
+
const entry = store.get(args.key);
|
|
27
|
+
if (!entry)
|
|
28
|
+
return { found: false };
|
|
29
|
+
return { found: true, ...entry };
|
|
30
|
+
},
|
|
31
|
+
},
|
|
32
|
+
{
|
|
33
|
+
name: 'memory_search',
|
|
34
|
+
description: 'Search memory entries by tag or substring in key',
|
|
35
|
+
inputSchema: { type: 'object', properties: { query: { type: 'string' }, tag: { type: 'string' } }, required: [] },
|
|
36
|
+
handler: async (args) => {
|
|
37
|
+
let results = Array.from(store.entries()).map(([k, v]) => ({ key: k, ...v }));
|
|
38
|
+
if (args.tag)
|
|
39
|
+
results = results.filter(r => r.tags.includes(args.tag));
|
|
40
|
+
if (args.query)
|
|
41
|
+
results = results.filter(r => r.key.includes(args.query) || JSON.stringify(r.value).includes(args.query));
|
|
42
|
+
return { results, count: results.length };
|
|
43
|
+
},
|
|
44
|
+
},
|
|
45
|
+
{
|
|
46
|
+
name: 'memory_delete',
|
|
47
|
+
description: 'Delete a memory entry',
|
|
48
|
+
inputSchema: { type: 'object', properties: { key: { type: 'string' } }, required: ['key'] },
|
|
49
|
+
handler: async (args) => ({ deleted: store.delete(args.key) }),
|
|
50
|
+
},
|
|
51
|
+
{
|
|
52
|
+
name: 'memory_list',
|
|
53
|
+
description: 'List all memory keys',
|
|
54
|
+
inputSchema: { type: 'object', properties: {} },
|
|
55
|
+
handler: async () => ({ keys: Array.from(store.keys()), count: store.size }),
|
|
56
|
+
},
|
|
57
|
+
],
|
|
58
|
+
};
|
|
59
|
+
}
|
|
60
|
+
//# sourceMappingURL=memory-mcp.js.map
|
|
@@ -0,0 +1,56 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.createRegexServer = createRegexServer;
|
|
4
|
+
function createRegexServer() {
|
|
5
|
+
return {
|
|
6
|
+
name: 'regex',
|
|
7
|
+
version: '1.0.0',
|
|
8
|
+
tools: [
|
|
9
|
+
{
|
|
10
|
+
name: 'regex_test',
|
|
11
|
+
description: 'Test if a string matches a regex pattern',
|
|
12
|
+
inputSchema: { type: 'object', properties: { pattern: { type: 'string' }, flags: { type: 'string', default: '' }, text: { type: 'string' } }, required: ['pattern', 'text'] },
|
|
13
|
+
handler: async (args) => {
|
|
14
|
+
const re = new RegExp(args.pattern, args.flags || '');
|
|
15
|
+
return { matches: re.test(args.text), pattern: args.pattern };
|
|
16
|
+
},
|
|
17
|
+
},
|
|
18
|
+
{
|
|
19
|
+
name: 'regex_match',
|
|
20
|
+
description: 'Find all matches of a regex in text',
|
|
21
|
+
inputSchema: { type: 'object', properties: { pattern: { type: 'string' }, flags: { type: 'string', default: 'g' }, text: { type: 'string' } }, required: ['pattern', 'text'] },
|
|
22
|
+
handler: async (args) => {
|
|
23
|
+
const re = new RegExp(args.pattern, args.flags || 'g');
|
|
24
|
+
const matches = [];
|
|
25
|
+
let m;
|
|
26
|
+
while ((m = re.exec(args.text)) !== null) {
|
|
27
|
+
matches.push({ match: m[0], index: m.index, groups: m.groups });
|
|
28
|
+
if (!re.global)
|
|
29
|
+
break;
|
|
30
|
+
}
|
|
31
|
+
return { matches, count: matches.length };
|
|
32
|
+
},
|
|
33
|
+
},
|
|
34
|
+
{
|
|
35
|
+
name: 'regex_replace',
|
|
36
|
+
description: 'Replace matches in text using regex',
|
|
37
|
+
inputSchema: { type: 'object', properties: { pattern: { type: 'string' }, flags: { type: 'string', default: 'g' }, text: { type: 'string' }, replacement: { type: 'string' } }, required: ['pattern', 'text', 'replacement'] },
|
|
38
|
+
handler: async (args) => {
|
|
39
|
+
const re = new RegExp(args.pattern, args.flags || 'g');
|
|
40
|
+
return { result: args.text.replace(re, args.replacement) };
|
|
41
|
+
},
|
|
42
|
+
},
|
|
43
|
+
{
|
|
44
|
+
name: 'regex_split',
|
|
45
|
+
description: 'Split text by regex pattern',
|
|
46
|
+
inputSchema: { type: 'object', properties: { pattern: { type: 'string' }, text: { type: 'string' }, limit: { type: 'number' } }, required: ['pattern', 'text'] },
|
|
47
|
+
handler: async (args) => {
|
|
48
|
+
const re = new RegExp(args.pattern);
|
|
49
|
+
const parts = args.text.split(re, args.limit);
|
|
50
|
+
return { parts, count: parts.length };
|
|
51
|
+
},
|
|
52
|
+
},
|
|
53
|
+
],
|
|
54
|
+
};
|
|
55
|
+
}
|
|
56
|
+
//# sourceMappingURL=regex-mcp.js.map
|
|
@@ -0,0 +1,51 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.createWebServer = createWebServer;
|
|
4
|
+
function createWebServer() {
|
|
5
|
+
return {
|
|
6
|
+
name: 'web',
|
|
7
|
+
version: '1.0.0',
|
|
8
|
+
tools: [
|
|
9
|
+
{
|
|
10
|
+
name: 'web_fetch',
|
|
11
|
+
description: 'Fetch a URL and return its content',
|
|
12
|
+
inputSchema: { type: 'object', properties: { url: { type: 'string' }, method: { type: 'string', default: 'GET' }, headers: { type: 'object' }, body: { type: 'string' } }, required: ['url'] },
|
|
13
|
+
handler: async (args) => {
|
|
14
|
+
const res = await fetch(args.url, { method: args.method || 'GET', headers: args.headers, body: args.body });
|
|
15
|
+
const contentType = res.headers.get('content-type') || '';
|
|
16
|
+
const text = await res.text();
|
|
17
|
+
return { status: res.status, contentType, body: text.slice(0, 50000), truncated: text.length > 50000 };
|
|
18
|
+
},
|
|
19
|
+
},
|
|
20
|
+
{
|
|
21
|
+
name: 'web_extract_text',
|
|
22
|
+
description: 'Fetch a URL and extract readable text (strips HTML tags)',
|
|
23
|
+
inputSchema: { type: 'object', properties: { url: { type: 'string' } }, required: ['url'] },
|
|
24
|
+
handler: async (args) => {
|
|
25
|
+
const res = await fetch(args.url);
|
|
26
|
+
const html = await res.text();
|
|
27
|
+
const text = html.replace(/<script[\s\S]*?<\/script>/gi, '').replace(/<style[\s\S]*?<\/style>/gi, '').replace(/<[^>]+>/g, ' ').replace(/\s+/g, ' ').trim();
|
|
28
|
+
return { text: text.slice(0, 30000), truncated: text.length > 30000 };
|
|
29
|
+
},
|
|
30
|
+
},
|
|
31
|
+
{
|
|
32
|
+
name: 'web_search',
|
|
33
|
+
description: 'Search the web (simulated — returns search URL for manual use)',
|
|
34
|
+
inputSchema: { type: 'object', properties: { query: { type: 'string' }, engine: { type: 'string', enum: ['google', 'bing', 'duckduckgo'], default: 'duckduckgo' } }, required: ['query'] },
|
|
35
|
+
handler: async (args) => {
|
|
36
|
+
const engines = {
|
|
37
|
+
google: `https://www.google.com/search?q=${encodeURIComponent(args.query)}`,
|
|
38
|
+
bing: `https://www.bing.com/search?q=${encodeURIComponent(args.query)}`,
|
|
39
|
+
duckduckgo: `https://html.duckduckgo.com/html/?q=${encodeURIComponent(args.query)}`,
|
|
40
|
+
};
|
|
41
|
+
const url = engines[args.engine || 'duckduckgo'];
|
|
42
|
+
const res = await fetch(url, { headers: { 'User-Agent': 'Mozilla/5.0 opc-mcp/1.0' } });
|
|
43
|
+
const html = await res.text();
|
|
44
|
+
const text = html.replace(/<script[\s\S]*?<\/script>/gi, '').replace(/<style[\s\S]*?<\/style>/gi, '').replace(/<[^>]+>/g, ' ').replace(/\s+/g, ' ').trim();
|
|
45
|
+
return { query: args.query, engine: args.engine || 'duckduckgo', results: text.slice(0, 20000) };
|
|
46
|
+
},
|
|
47
|
+
},
|
|
48
|
+
],
|
|
49
|
+
};
|
|
50
|
+
}
|
|
51
|
+
//# sourceMappingURL=web-mcp.js.map
|
package/dist/memory/index.d.ts
CHANGED
|
@@ -1,4 +1,6 @@
|
|
|
1
1
|
import type { Message, MemoryStore } from '../core/types';
|
|
2
|
+
export { BrainSeedLoader, KnowledgeEvolver } from './seed-loader';
|
|
3
|
+
export type { BrainSeedConfig, SeedPage, SeedResult, PromotionResult, PromotionCandidate } from './seed-loader';
|
|
2
4
|
export declare class InMemoryStore implements MemoryStore {
|
|
3
5
|
private store;
|
|
4
6
|
private conversations;
|
package/dist/memory/index.js
CHANGED
|
@@ -1,6 +1,9 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
exports.InMemoryStore = void 0;
|
|
3
|
+
exports.InMemoryStore = exports.KnowledgeEvolver = exports.BrainSeedLoader = void 0;
|
|
4
|
+
var seed_loader_1 = require("./seed-loader");
|
|
5
|
+
Object.defineProperty(exports, "BrainSeedLoader", { enumerable: true, get: function () { return seed_loader_1.BrainSeedLoader; } });
|
|
6
|
+
Object.defineProperty(exports, "KnowledgeEvolver", { enumerable: true, get: function () { return seed_loader_1.KnowledgeEvolver; } });
|
|
4
7
|
class InMemoryStore {
|
|
5
8
|
store = new Map();
|
|
6
9
|
conversations = new Map();
|
|
@@ -0,0 +1,51 @@
|
|
|
1
|
+
export interface BrainSeedConfig {
|
|
2
|
+
seeds: string[];
|
|
3
|
+
autoSeed: boolean;
|
|
4
|
+
seedMarkerFile?: string;
|
|
5
|
+
evolve?: {
|
|
6
|
+
enabled: boolean;
|
|
7
|
+
direction: 'bottom-up' | 'top-down';
|
|
8
|
+
};
|
|
9
|
+
}
|
|
10
|
+
export interface SeedPage {
|
|
11
|
+
slug: string;
|
|
12
|
+
content: string;
|
|
13
|
+
tier: string;
|
|
14
|
+
}
|
|
15
|
+
export interface SeedResult {
|
|
16
|
+
imported: number;
|
|
17
|
+
pages: string[];
|
|
18
|
+
}
|
|
19
|
+
export interface PromotionCandidate {
|
|
20
|
+
slug: string;
|
|
21
|
+
content: string;
|
|
22
|
+
fromTier: string;
|
|
23
|
+
toTier: string;
|
|
24
|
+
confidence: number;
|
|
25
|
+
}
|
|
26
|
+
export interface PromotionResult {
|
|
27
|
+
candidates: PromotionCandidate[];
|
|
28
|
+
promoted: number;
|
|
29
|
+
}
|
|
30
|
+
export declare class BrainSeedLoader {
|
|
31
|
+
private agentDir;
|
|
32
|
+
private config;
|
|
33
|
+
private markerFile;
|
|
34
|
+
constructor(agentDir: string, config: BrainSeedConfig);
|
|
35
|
+
isSeeded(): Promise<boolean>;
|
|
36
|
+
seedBrain(brain: any): Promise<SeedResult>;
|
|
37
|
+
markSeeded(): Promise<void>;
|
|
38
|
+
parseSeedFile(filePath: string, tier: string): SeedPage[];
|
|
39
|
+
private inferTier;
|
|
40
|
+
private slugify;
|
|
41
|
+
}
|
|
42
|
+
export declare class KnowledgeEvolver {
|
|
43
|
+
private tierOrder;
|
|
44
|
+
checkPromotion(brain: any, options?: {
|
|
45
|
+
minInteractions?: number;
|
|
46
|
+
confidenceThreshold?: number;
|
|
47
|
+
}): Promise<PromotionResult>;
|
|
48
|
+
promoteToJob(brain: any, knowledge: string, jobSlug: string): Promise<void>;
|
|
49
|
+
promoteToIndustry(brain: any, knowledge: string, industrySlug: string): Promise<void>;
|
|
50
|
+
}
|
|
51
|
+
//# sourceMappingURL=seed-loader.d.ts.map
|
|
@@ -0,0 +1,200 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
|
|
3
|
+
if (k2 === undefined) k2 = k;
|
|
4
|
+
var desc = Object.getOwnPropertyDescriptor(m, k);
|
|
5
|
+
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
|
|
6
|
+
desc = { enumerable: true, get: function() { return m[k]; } };
|
|
7
|
+
}
|
|
8
|
+
Object.defineProperty(o, k2, desc);
|
|
9
|
+
}) : (function(o, m, k, k2) {
|
|
10
|
+
if (k2 === undefined) k2 = k;
|
|
11
|
+
o[k2] = m[k];
|
|
12
|
+
}));
|
|
13
|
+
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
|
|
14
|
+
Object.defineProperty(o, "default", { enumerable: true, value: v });
|
|
15
|
+
}) : function(o, v) {
|
|
16
|
+
o["default"] = v;
|
|
17
|
+
});
|
|
18
|
+
var __importStar = (this && this.__importStar) || (function () {
|
|
19
|
+
var ownKeys = function(o) {
|
|
20
|
+
ownKeys = Object.getOwnPropertyNames || function (o) {
|
|
21
|
+
var ar = [];
|
|
22
|
+
for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
|
|
23
|
+
return ar;
|
|
24
|
+
};
|
|
25
|
+
return ownKeys(o);
|
|
26
|
+
};
|
|
27
|
+
return function (mod) {
|
|
28
|
+
if (mod && mod.__esModule) return mod;
|
|
29
|
+
var result = {};
|
|
30
|
+
if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
|
|
31
|
+
__setModuleDefault(result, mod);
|
|
32
|
+
return result;
|
|
33
|
+
};
|
|
34
|
+
})();
|
|
35
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
36
|
+
exports.KnowledgeEvolver = exports.BrainSeedLoader = void 0;
|
|
37
|
+
const fs = __importStar(require("fs"));
|
|
38
|
+
const path = __importStar(require("path"));
|
|
39
|
+
class BrainSeedLoader {
|
|
40
|
+
agentDir;
|
|
41
|
+
config;
|
|
42
|
+
markerFile;
|
|
43
|
+
constructor(agentDir, config) {
|
|
44
|
+
this.agentDir = agentDir;
|
|
45
|
+
this.config = config;
|
|
46
|
+
this.markerFile = config.seedMarkerFile
|
|
47
|
+
? path.resolve(agentDir, config.seedMarkerFile)
|
|
48
|
+
: path.resolve(agentDir, '.brain-seeded');
|
|
49
|
+
}
|
|
50
|
+
async isSeeded() {
|
|
51
|
+
return fs.existsSync(this.markerFile);
|
|
52
|
+
}
|
|
53
|
+
async seedBrain(brain) {
|
|
54
|
+
const allPages = [];
|
|
55
|
+
for (const seedPath of this.config.seeds) {
|
|
56
|
+
const fullPath = path.resolve(this.agentDir, seedPath);
|
|
57
|
+
if (!fs.existsSync(fullPath))
|
|
58
|
+
continue;
|
|
59
|
+
const tier = this.inferTier(seedPath);
|
|
60
|
+
const pages = this.parseSeedFile(fullPath, tier);
|
|
61
|
+
allPages.push(...pages);
|
|
62
|
+
}
|
|
63
|
+
const importedSlugs = [];
|
|
64
|
+
for (const page of allPages) {
|
|
65
|
+
if (brain && typeof brain.store === 'function') {
|
|
66
|
+
await brain.store('brain-seeds', page.slug, page.content, {
|
|
67
|
+
tier: page.tier,
|
|
68
|
+
source: 'brain-seed',
|
|
69
|
+
});
|
|
70
|
+
}
|
|
71
|
+
else if (brain && typeof brain.learn === 'function') {
|
|
72
|
+
await brain.learn(page.content, {
|
|
73
|
+
tags: ['brain-seed', page.tier],
|
|
74
|
+
slug: page.slug,
|
|
75
|
+
});
|
|
76
|
+
}
|
|
77
|
+
importedSlugs.push(page.slug);
|
|
78
|
+
}
|
|
79
|
+
return { imported: importedSlugs.length, pages: importedSlugs };
|
|
80
|
+
}
|
|
81
|
+
async markSeeded() {
|
|
82
|
+
const dir = path.dirname(this.markerFile);
|
|
83
|
+
if (!fs.existsSync(dir))
|
|
84
|
+
fs.mkdirSync(dir, { recursive: true });
|
|
85
|
+
fs.writeFileSync(this.markerFile, JSON.stringify({
|
|
86
|
+
seededAt: new Date().toISOString(),
|
|
87
|
+
seeds: this.config.seeds,
|
|
88
|
+
}, null, 2));
|
|
89
|
+
}
|
|
90
|
+
parseSeedFile(filePath, tier) {
|
|
91
|
+
const content = fs.readFileSync(filePath, 'utf-8');
|
|
92
|
+
const pages = [];
|
|
93
|
+
const sections = content.split(/^## /m);
|
|
94
|
+
for (const section of sections) {
|
|
95
|
+
const trimmed = section.trim();
|
|
96
|
+
if (!trimmed)
|
|
97
|
+
continue;
|
|
98
|
+
const newlineIdx = trimmed.indexOf('\n');
|
|
99
|
+
if (newlineIdx === -1 && sections.indexOf(section) === 0 && !content.trimStart().startsWith('## ')) {
|
|
100
|
+
// This is preamble before any ## heading — skip or treat as intro
|
|
101
|
+
continue;
|
|
102
|
+
}
|
|
103
|
+
let title;
|
|
104
|
+
let body;
|
|
105
|
+
if (sections.indexOf(section) === 0 && !content.trimStart().startsWith('## ')) {
|
|
106
|
+
// Preamble (before first ##)
|
|
107
|
+
continue;
|
|
108
|
+
}
|
|
109
|
+
if (newlineIdx === -1) {
|
|
110
|
+
title = trimmed;
|
|
111
|
+
body = '';
|
|
112
|
+
}
|
|
113
|
+
else {
|
|
114
|
+
title = trimmed.slice(0, newlineIdx).trim();
|
|
115
|
+
body = trimmed.slice(newlineIdx + 1).trim();
|
|
116
|
+
}
|
|
117
|
+
const slug = `seed/${tier}/${this.slugify(title)}`;
|
|
118
|
+
pages.push({ slug, content: `## ${title}\n\n${body}`, tier });
|
|
119
|
+
}
|
|
120
|
+
return pages;
|
|
121
|
+
}
|
|
122
|
+
inferTier(seedPath) {
|
|
123
|
+
const basename = path.basename(seedPath, path.extname(seedPath)).toLowerCase();
|
|
124
|
+
if (basename.includes('industry'))
|
|
125
|
+
return 'industry';
|
|
126
|
+
if (basename.includes('job'))
|
|
127
|
+
return 'job';
|
|
128
|
+
if (basename.includes('workstation'))
|
|
129
|
+
return 'workstation';
|
|
130
|
+
return 'workstation';
|
|
131
|
+
}
|
|
132
|
+
slugify(text) {
|
|
133
|
+
return text
|
|
134
|
+
.toLowerCase()
|
|
135
|
+
.replace(/[^a-z0-9\u4e00-\u9fff]+/g, '-')
|
|
136
|
+
.replace(/^-|-$/g, '');
|
|
137
|
+
}
|
|
138
|
+
}
|
|
139
|
+
exports.BrainSeedLoader = BrainSeedLoader;
|
|
140
|
+
class KnowledgeEvolver {
|
|
141
|
+
tierOrder = ['workstation', 'job', 'industry'];
|
|
142
|
+
async checkPromotion(brain, options = {}) {
|
|
143
|
+
const minInteractions = options.minInteractions ?? 50;
|
|
144
|
+
const confidenceThreshold = options.confidenceThreshold ?? 0.8;
|
|
145
|
+
const result = { candidates: [], promoted: 0 };
|
|
146
|
+
// Search for frequently referenced seed knowledge
|
|
147
|
+
if (!brain || typeof brain.search !== 'function')
|
|
148
|
+
return result;
|
|
149
|
+
try {
|
|
150
|
+
const seedPages = await brain.search('brain-seeds', 'seed/', 100);
|
|
151
|
+
if (!Array.isArray(seedPages))
|
|
152
|
+
return result;
|
|
153
|
+
for (const page of seedPages) {
|
|
154
|
+
const meta = page.metadata || {};
|
|
155
|
+
const usageCount = meta.usageCount ?? 0;
|
|
156
|
+
const tier = meta.tier || 'workstation';
|
|
157
|
+
if (usageCount < minInteractions)
|
|
158
|
+
continue;
|
|
159
|
+
const confidence = Math.min(usageCount / (minInteractions * 2), 1.0);
|
|
160
|
+
if (confidence < confidenceThreshold)
|
|
161
|
+
continue;
|
|
162
|
+
const tierIdx = this.tierOrder.indexOf(tier);
|
|
163
|
+
if (tierIdx <= 0)
|
|
164
|
+
continue; // already at highest tier or unknown
|
|
165
|
+
const toTier = this.tierOrder[tierIdx - 1];
|
|
166
|
+
result.candidates.push({
|
|
167
|
+
slug: page.id || page.slug,
|
|
168
|
+
content: page.content,
|
|
169
|
+
fromTier: tier,
|
|
170
|
+
toTier,
|
|
171
|
+
confidence,
|
|
172
|
+
});
|
|
173
|
+
}
|
|
174
|
+
}
|
|
175
|
+
catch {
|
|
176
|
+
// Silent fail
|
|
177
|
+
}
|
|
178
|
+
return result;
|
|
179
|
+
}
|
|
180
|
+
async promoteToJob(brain, knowledge, jobSlug) {
|
|
181
|
+
if (brain && typeof brain.store === 'function') {
|
|
182
|
+
await brain.store('brain-seeds', jobSlug, knowledge, {
|
|
183
|
+
tier: 'job',
|
|
184
|
+
source: 'promotion',
|
|
185
|
+
promotedAt: new Date().toISOString(),
|
|
186
|
+
});
|
|
187
|
+
}
|
|
188
|
+
}
|
|
189
|
+
async promoteToIndustry(brain, knowledge, industrySlug) {
|
|
190
|
+
if (brain && typeof brain.store === 'function') {
|
|
191
|
+
await brain.store('brain-seeds', industrySlug, knowledge, {
|
|
192
|
+
tier: 'industry',
|
|
193
|
+
source: 'promotion',
|
|
194
|
+
promotedAt: new Date().toISOString(),
|
|
195
|
+
});
|
|
196
|
+
}
|
|
197
|
+
}
|
|
198
|
+
}
|
|
199
|
+
exports.KnowledgeEvolver = KnowledgeEvolver;
|
|
200
|
+
//# sourceMappingURL=seed-loader.js.map
|