opc-agent 1.4.0 → 2.0.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +25 -0
- package/README.md +91 -32
- package/dist/channels/email.d.ts +32 -26
- package/dist/channels/email.js +239 -62
- package/dist/channels/feishu.d.ts +21 -6
- package/dist/channels/feishu.js +225 -126
- package/dist/channels/telegram.d.ts +30 -9
- package/dist/channels/telegram.js +125 -33
- package/dist/channels/websocket.d.ts +46 -3
- package/dist/channels/websocket.js +306 -37
- package/dist/channels/wechat.d.ts +33 -13
- package/dist/channels/wechat.js +229 -42
- package/dist/cli.js +1127 -19
- package/dist/core/a2a.d.ts +17 -0
- package/dist/core/a2a.js +43 -1
- package/dist/core/agent.d.ts +39 -0
- package/dist/core/agent.js +228 -3
- package/dist/core/runtime.d.ts +7 -0
- package/dist/core/runtime.js +205 -2
- package/dist/core/sandbox.d.ts +26 -0
- package/dist/core/sandbox.js +117 -0
- package/dist/core/scheduler.d.ts +52 -0
- package/dist/core/scheduler.js +168 -0
- package/dist/core/subagent.d.ts +28 -0
- package/dist/core/subagent.js +65 -0
- package/dist/core/workflow-graph.d.ts +93 -0
- package/dist/core/workflow-graph.js +247 -0
- package/dist/daemon.d.ts +3 -0
- package/dist/daemon.js +134 -0
- package/dist/doctor.d.ts +15 -0
- package/dist/doctor.js +183 -0
- package/dist/eval/index.d.ts +65 -0
- package/dist/eval/index.js +191 -0
- package/dist/index.d.ts +37 -6
- package/dist/index.js +75 -3
- package/dist/plugins/content-filter.d.ts +7 -0
- package/dist/plugins/content-filter.js +25 -0
- package/dist/plugins/index.d.ts +42 -0
- package/dist/plugins/index.js +108 -2
- package/dist/plugins/logger.d.ts +6 -0
- package/dist/plugins/logger.js +20 -0
- package/dist/plugins/rate-limiter.d.ts +7 -0
- package/dist/plugins/rate-limiter.js +35 -0
- package/dist/protocols/a2a/client.d.ts +25 -0
- package/dist/protocols/a2a/client.js +115 -0
- package/dist/protocols/a2a/index.d.ts +6 -0
- package/dist/protocols/a2a/index.js +12 -0
- package/dist/protocols/a2a/server.d.ts +41 -0
- package/dist/protocols/a2a/server.js +295 -0
- package/dist/protocols/a2a/types.d.ts +91 -0
- package/dist/protocols/a2a/types.js +15 -0
- package/dist/protocols/a2a/utils.d.ts +6 -0
- package/dist/protocols/a2a/utils.js +47 -0
- package/dist/protocols/agui/client.d.ts +10 -0
- package/dist/protocols/agui/client.js +75 -0
- package/dist/protocols/agui/index.d.ts +4 -0
- package/dist/protocols/agui/index.js +25 -0
- package/dist/protocols/agui/server.d.ts +37 -0
- package/dist/protocols/agui/server.js +191 -0
- package/dist/protocols/agui/types.d.ts +107 -0
- package/dist/protocols/agui/types.js +17 -0
- package/dist/protocols/index.d.ts +2 -0
- package/dist/protocols/index.js +19 -0
- package/dist/protocols/mcp/agent-tools.d.ts +11 -0
- package/dist/protocols/mcp/agent-tools.js +129 -0
- package/dist/protocols/mcp/index.d.ts +5 -0
- package/dist/protocols/mcp/index.js +11 -0
- package/dist/protocols/mcp/server.d.ts +31 -0
- package/dist/protocols/mcp/server.js +248 -0
- package/dist/protocols/mcp/types.d.ts +92 -0
- package/dist/protocols/mcp/types.js +17 -0
- package/dist/providers/index.d.ts +5 -1
- package/dist/providers/index.js +16 -9
- package/dist/publish/index.d.ts +45 -0
- package/dist/publish/index.js +350 -0
- package/dist/schema/oad.d.ts +859 -67
- package/dist/schema/oad.js +47 -3
- package/dist/security/approval.d.ts +36 -0
- package/dist/security/approval.js +113 -0
- package/dist/security/index.d.ts +4 -0
- package/dist/security/index.js +8 -0
- package/dist/security/keys.d.ts +16 -0
- package/dist/security/keys.js +117 -0
- package/dist/skills/auto-learn.d.ts +28 -0
- package/dist/skills/auto-learn.js +257 -0
- package/dist/studio/server.d.ts +63 -0
- package/dist/studio/server.js +625 -0
- package/dist/studio-ui/index.html +662 -0
- package/dist/telemetry/index.d.ts +93 -0
- package/dist/telemetry/index.js +285 -0
- package/dist/tools/builtin/datetime.d.ts +3 -0
- package/dist/tools/builtin/datetime.js +44 -0
- package/dist/tools/builtin/file.d.ts +3 -0
- package/dist/tools/builtin/file.js +151 -0
- package/dist/tools/builtin/index.d.ts +15 -0
- package/dist/tools/builtin/index.js +30 -0
- package/dist/tools/builtin/shell.d.ts +3 -0
- package/dist/tools/builtin/shell.js +43 -0
- package/dist/tools/builtin/web.d.ts +3 -0
- package/dist/tools/builtin/web.js +37 -0
- package/dist/tools/mcp-client.d.ts +24 -0
- package/dist/tools/mcp-client.js +119 -0
- package/package.json +5 -3
- package/scripts/install.ps1 +31 -0
- package/scripts/install.sh +40 -0
- package/src/channels/email.ts +351 -177
- package/src/channels/feishu.ts +349 -236
- package/src/channels/telegram.ts +212 -90
- package/src/channels/websocket.ts +399 -87
- package/src/channels/wechat.ts +329 -149
- package/src/cli.ts +1201 -20
- package/src/core/a2a.ts +60 -0
- package/src/core/agent.ts +420 -152
- package/src/core/runtime.ts +174 -0
- package/src/core/sandbox.ts +143 -0
- package/src/core/scheduler.ts +187 -0
- package/src/core/subagent.ts +98 -0
- package/src/core/workflow-graph.ts +365 -0
- package/src/daemon.ts +96 -0
- package/src/doctor.ts +156 -0
- package/src/eval/index.ts +211 -0
- package/src/eval/suites/basic.json +16 -0
- package/src/eval/suites/memory.json +12 -0
- package/src/eval/suites/safety.json +14 -0
- package/src/index.ts +65 -6
- package/src/plugins/content-filter.ts +23 -0
- package/src/plugins/index.ts +133 -2
- package/src/plugins/logger.ts +18 -0
- package/src/plugins/rate-limiter.ts +38 -0
- package/src/protocols/a2a/client.ts +132 -0
- package/src/protocols/a2a/index.ts +8 -0
- package/src/protocols/a2a/server.ts +333 -0
- package/src/protocols/a2a/types.ts +88 -0
- package/src/protocols/a2a/utils.ts +50 -0
- package/src/protocols/agui/client.ts +83 -0
- package/src/protocols/agui/index.ts +4 -0
- package/src/protocols/agui/server.ts +218 -0
- package/src/protocols/agui/types.ts +153 -0
- package/src/protocols/index.ts +2 -0
- package/src/protocols/mcp/agent-tools.ts +134 -0
- package/src/protocols/mcp/index.ts +8 -0
- package/src/protocols/mcp/server.ts +262 -0
- package/src/protocols/mcp/types.ts +69 -0
- package/src/providers/index.ts +354 -339
- package/src/publish/index.ts +376 -0
- package/src/schema/oad.ts +204 -154
- package/src/security/approval.ts +131 -0
- package/src/security/index.ts +3 -0
- package/src/security/keys.ts +87 -0
- package/src/skills/auto-learn.ts +262 -0
- package/src/studio/server.ts +629 -0
- package/src/studio-ui/index.html +662 -0
- package/src/telemetry/index.ts +324 -0
- package/src/tools/builtin/datetime.ts +41 -0
- package/src/tools/builtin/file.ts +107 -0
- package/src/tools/builtin/index.ts +28 -0
- package/src/tools/builtin/shell.ts +43 -0
- package/src/tools/builtin/web.ts +35 -0
- package/src/tools/mcp-client.ts +131 -0
- package/src/types/agent-workstation.d.ts +2 -0
- package/tests/a2a-protocol.test.ts +285 -0
- package/tests/agui-protocol.test.ts +246 -0
- package/tests/auto-learn.test.ts +105 -0
- package/tests/builtin-tools.test.ts +83 -0
- package/tests/channels/discord.test.ts +79 -0
- package/tests/channels/email.test.ts +148 -0
- package/tests/channels/feishu.test.ts +123 -0
- package/tests/channels/telegram.test.ts +129 -0
- package/tests/channels/websocket.test.ts +53 -0
- package/tests/channels/wechat.test.ts +170 -0
- package/tests/chat-cli.test.ts +160 -0
- package/tests/cli.test.ts +46 -0
- package/tests/daemon.test.ts +135 -0
- package/tests/deepbrain-wire.test.ts +234 -0
- package/tests/doctor.test.ts +38 -0
- package/tests/eval.test.ts +173 -0
- package/tests/init-role.test.ts +124 -0
- package/tests/mcp-client.test.ts +92 -0
- package/tests/mcp-server.test.ts +178 -0
- package/tests/plugin-a2a-enhanced.test.ts +230 -0
- package/tests/publish.test.ts +231 -0
- package/tests/scheduler.test.ts +200 -0
- package/tests/security-enhanced.test.ts +233 -0
- package/tests/skill-learner.test.ts +161 -0
- package/tests/studio.test.ts +229 -0
- package/tests/subagent.test.ts +193 -0
- package/tests/telegram-discord.test.ts +60 -0
- package/tests/telemetry.test.ts +186 -0
- package/tests/tools/builtin-extended.test.ts +138 -0
- package/tests/workflow-graph.test.ts +279 -0
- package/tutorial/customer-service-agent/README.md +612 -0
- package/tutorial/customer-service-agent/SOUL.md +26 -0
- package/tutorial/customer-service-agent/agent.yaml +63 -0
- package/tutorial/customer-service-agent/package.json +19 -0
- package/tutorial/customer-service-agent/src/index.ts +69 -0
- package/tutorial/customer-service-agent/src/skills/faq.ts +27 -0
- package/tutorial/customer-service-agent/src/skills/ticket.ts +22 -0
- package/tutorial/customer-service-agent/tsconfig.json +14 -0
|
@@ -0,0 +1,248 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.MCPServer = void 0;
|
|
4
|
+
const http_1 = require("http");
|
|
5
|
+
const readline_1 = require("readline");
|
|
6
|
+
const types_1 = require("./types");
|
|
7
|
+
class MCPServer {
|
|
8
|
+
config;
|
|
9
|
+
tools = new Map();
|
|
10
|
+
resources = new Map();
|
|
11
|
+
prompts = new Map();
|
|
12
|
+
sseClients = new Set();
|
|
13
|
+
httpServer = null;
|
|
14
|
+
constructor(config) {
|
|
15
|
+
this.config = config;
|
|
16
|
+
for (const t of config.tools ?? [])
|
|
17
|
+
this.addTool(t);
|
|
18
|
+
for (const r of config.resources ?? [])
|
|
19
|
+
this.addResource(r);
|
|
20
|
+
for (const p of config.prompts ?? [])
|
|
21
|
+
this.addPrompt(p);
|
|
22
|
+
}
|
|
23
|
+
addTool(tool) {
|
|
24
|
+
this.tools.set(tool.name, tool);
|
|
25
|
+
}
|
|
26
|
+
removeTool(name) {
|
|
27
|
+
this.tools.delete(name);
|
|
28
|
+
}
|
|
29
|
+
addResource(resource) {
|
|
30
|
+
this.resources.set(resource.uri, resource);
|
|
31
|
+
}
|
|
32
|
+
removeResource(uri) {
|
|
33
|
+
this.resources.delete(uri);
|
|
34
|
+
}
|
|
35
|
+
addPrompt(prompt) {
|
|
36
|
+
this.prompts.set(prompt.name, prompt);
|
|
37
|
+
}
|
|
38
|
+
getToolCount() { return this.tools.size; }
|
|
39
|
+
getResourceCount() { return this.resources.size; }
|
|
40
|
+
getPromptCount() { return this.prompts.size; }
|
|
41
|
+
getConnectedClients() { return this.sseClients.size; }
|
|
42
|
+
/** Serve over stdio — one JSON-RPC message per line */
|
|
43
|
+
async serveStdio() {
|
|
44
|
+
const rl = (0, readline_1.createInterface)({ input: process.stdin, terminal: false });
|
|
45
|
+
rl.on('line', async (line) => {
|
|
46
|
+
const trimmed = line.trim();
|
|
47
|
+
if (!trimmed)
|
|
48
|
+
return;
|
|
49
|
+
try {
|
|
50
|
+
const msg = JSON.parse(trimmed);
|
|
51
|
+
const response = await this.handleMessage(msg);
|
|
52
|
+
if (response) {
|
|
53
|
+
process.stdout.write(JSON.stringify(response) + '\n');
|
|
54
|
+
}
|
|
55
|
+
}
|
|
56
|
+
catch {
|
|
57
|
+
const err = {
|
|
58
|
+
jsonrpc: '2.0', id: null,
|
|
59
|
+
error: types_1.MCP_ERRORS.PARSE_ERROR,
|
|
60
|
+
};
|
|
61
|
+
process.stdout.write(JSON.stringify(err) + '\n');
|
|
62
|
+
}
|
|
63
|
+
});
|
|
64
|
+
}
|
|
65
|
+
/** Serve over HTTP + SSE */
|
|
66
|
+
async serveHTTP(port) {
|
|
67
|
+
this.httpServer = (0, http_1.createServer)((req, res) => this.handleHTTP(req, res));
|
|
68
|
+
return new Promise((resolve) => {
|
|
69
|
+
this.httpServer.listen(port, () => resolve());
|
|
70
|
+
});
|
|
71
|
+
}
|
|
72
|
+
/** Mount on existing HTTP server at a path prefix */
|
|
73
|
+
mount(server, path = '/mcp') {
|
|
74
|
+
const orig = server.listeners('request')[0];
|
|
75
|
+
server.removeAllListeners('request');
|
|
76
|
+
server.on('request', (req, res) => {
|
|
77
|
+
if (req.url?.startsWith(path)) {
|
|
78
|
+
// Rewrite URL to strip prefix
|
|
79
|
+
req.url = req.url.slice(path.length) || '/';
|
|
80
|
+
this.handleHTTP(req, res);
|
|
81
|
+
}
|
|
82
|
+
else if (orig) {
|
|
83
|
+
orig(req, res);
|
|
84
|
+
}
|
|
85
|
+
});
|
|
86
|
+
}
|
|
87
|
+
stop() {
|
|
88
|
+
this.httpServer?.close();
|
|
89
|
+
for (const client of this.sseClients) {
|
|
90
|
+
client.end();
|
|
91
|
+
}
|
|
92
|
+
this.sseClients.clear();
|
|
93
|
+
}
|
|
94
|
+
handleHTTP(req, res) {
|
|
95
|
+
res.setHeader('Access-Control-Allow-Origin', '*');
|
|
96
|
+
res.setHeader('Access-Control-Allow-Methods', 'GET, POST, OPTIONS');
|
|
97
|
+
res.setHeader('Access-Control-Allow-Headers', 'Content-Type');
|
|
98
|
+
if (req.method === 'OPTIONS') {
|
|
99
|
+
res.writeHead(204);
|
|
100
|
+
res.end();
|
|
101
|
+
return;
|
|
102
|
+
}
|
|
103
|
+
const url = new URL(req.url || '/', `http://${req.headers.host || 'localhost'}`);
|
|
104
|
+
if (url.pathname === '/sse' && req.method === 'GET') {
|
|
105
|
+
// SSE endpoint
|
|
106
|
+
res.writeHead(200, {
|
|
107
|
+
'Content-Type': 'text/event-stream',
|
|
108
|
+
'Cache-Control': 'no-cache',
|
|
109
|
+
'Connection': 'keep-alive',
|
|
110
|
+
});
|
|
111
|
+
this.sseClients.add(res);
|
|
112
|
+
// Send endpoint info
|
|
113
|
+
res.write(`data: ${JSON.stringify({ type: 'endpoint', url: '/message' })}\n\n`);
|
|
114
|
+
req.on('close', () => this.sseClients.delete(res));
|
|
115
|
+
return;
|
|
116
|
+
}
|
|
117
|
+
if (url.pathname === '/message' && req.method === 'POST') {
|
|
118
|
+
let body = '';
|
|
119
|
+
req.on('data', (chunk) => { body += chunk; });
|
|
120
|
+
req.on('end', async () => {
|
|
121
|
+
try {
|
|
122
|
+
const msg = JSON.parse(body);
|
|
123
|
+
const response = await this.handleMessage(msg);
|
|
124
|
+
if (response) {
|
|
125
|
+
// Send via SSE to all clients
|
|
126
|
+
for (const client of this.sseClients) {
|
|
127
|
+
client.write(`data: ${JSON.stringify(response)}\n\n`);
|
|
128
|
+
}
|
|
129
|
+
res.writeHead(200, { 'Content-Type': 'application/json' });
|
|
130
|
+
res.end(JSON.stringify(response));
|
|
131
|
+
}
|
|
132
|
+
else {
|
|
133
|
+
res.writeHead(202);
|
|
134
|
+
res.end();
|
|
135
|
+
}
|
|
136
|
+
}
|
|
137
|
+
catch {
|
|
138
|
+
res.writeHead(400, { 'Content-Type': 'application/json' });
|
|
139
|
+
res.end(JSON.stringify({ jsonrpc: '2.0', id: null, error: types_1.MCP_ERRORS.PARSE_ERROR }));
|
|
140
|
+
}
|
|
141
|
+
});
|
|
142
|
+
return;
|
|
143
|
+
}
|
|
144
|
+
res.writeHead(404);
|
|
145
|
+
res.end('Not Found');
|
|
146
|
+
}
|
|
147
|
+
async handleMessage(msg) {
|
|
148
|
+
// Notifications (no id) don't get responses
|
|
149
|
+
if (msg.id === undefined)
|
|
150
|
+
return null;
|
|
151
|
+
const id = msg.id;
|
|
152
|
+
try {
|
|
153
|
+
switch (msg.method) {
|
|
154
|
+
case 'initialize':
|
|
155
|
+
return this.rpcResult(id, {
|
|
156
|
+
protocolVersion: '2024-11-05',
|
|
157
|
+
capabilities: {
|
|
158
|
+
tools: this.tools.size > 0 ? { listChanged: true } : undefined,
|
|
159
|
+
resources: this.resources.size > 0 ? { subscribe: false, listChanged: true } : undefined,
|
|
160
|
+
prompts: this.prompts.size > 0 ? { listChanged: true } : undefined,
|
|
161
|
+
},
|
|
162
|
+
serverInfo: { name: this.config.name, version: this.config.version },
|
|
163
|
+
});
|
|
164
|
+
case 'tools/list':
|
|
165
|
+
return this.rpcResult(id, {
|
|
166
|
+
tools: Array.from(this.tools.values()).map(t => ({
|
|
167
|
+
name: t.name,
|
|
168
|
+
description: t.description,
|
|
169
|
+
inputSchema: t.inputSchema,
|
|
170
|
+
})),
|
|
171
|
+
});
|
|
172
|
+
case 'tools/call': {
|
|
173
|
+
const { name, arguments: args } = msg.params ?? {};
|
|
174
|
+
const tool = this.tools.get(name);
|
|
175
|
+
if (!tool)
|
|
176
|
+
return this.rpcError(id, types_1.MCP_ERRORS.TOOL_NOT_FOUND);
|
|
177
|
+
// Validate required fields
|
|
178
|
+
const schema = tool.inputSchema;
|
|
179
|
+
if (schema?.required && Array.isArray(schema.required)) {
|
|
180
|
+
for (const field of schema.required) {
|
|
181
|
+
if (args?.[field] === undefined) {
|
|
182
|
+
return this.rpcError(id, { code: -32602, message: `Missing required parameter: ${field}` });
|
|
183
|
+
}
|
|
184
|
+
}
|
|
185
|
+
}
|
|
186
|
+
try {
|
|
187
|
+
const result = await tool.handler(args ?? {});
|
|
188
|
+
return this.rpcResult(id, {
|
|
189
|
+
content: [{ type: 'text', text: typeof result === 'string' ? result : JSON.stringify(result) }],
|
|
190
|
+
});
|
|
191
|
+
}
|
|
192
|
+
catch (err) {
|
|
193
|
+
return this.rpcResult(id, {
|
|
194
|
+
content: [{ type: 'text', text: err.message || 'Tool execution failed' }],
|
|
195
|
+
isError: true,
|
|
196
|
+
});
|
|
197
|
+
}
|
|
198
|
+
}
|
|
199
|
+
case 'resources/list':
|
|
200
|
+
return this.rpcResult(id, {
|
|
201
|
+
resources: Array.from(this.resources.values()).map(r => ({
|
|
202
|
+
uri: r.uri, name: r.name, description: r.description, mimeType: r.mimeType,
|
|
203
|
+
})),
|
|
204
|
+
});
|
|
205
|
+
case 'resources/read': {
|
|
206
|
+
const { uri } = msg.params ?? {};
|
|
207
|
+
const resource = this.resources.get(uri);
|
|
208
|
+
if (!resource)
|
|
209
|
+
return this.rpcError(id, types_1.MCP_ERRORS.RESOURCE_NOT_FOUND);
|
|
210
|
+
const content = await resource.handler();
|
|
211
|
+
return this.rpcResult(id, {
|
|
212
|
+
contents: [{ uri, mimeType: resource.mimeType || 'text/plain', text: content }],
|
|
213
|
+
});
|
|
214
|
+
}
|
|
215
|
+
case 'prompts/list':
|
|
216
|
+
return this.rpcResult(id, {
|
|
217
|
+
prompts: Array.from(this.prompts.values()).map(p => ({
|
|
218
|
+
name: p.name, description: p.description,
|
|
219
|
+
arguments: p.arguments,
|
|
220
|
+
})),
|
|
221
|
+
});
|
|
222
|
+
case 'prompts/get': {
|
|
223
|
+
const { name, arguments: promptArgs } = msg.params ?? {};
|
|
224
|
+
const prompt = this.prompts.get(name);
|
|
225
|
+
if (!prompt)
|
|
226
|
+
return this.rpcError(id, types_1.MCP_ERRORS.PROMPT_NOT_FOUND);
|
|
227
|
+
const messages = prompt.handler
|
|
228
|
+
? await prompt.handler(promptArgs ?? {})
|
|
229
|
+
: [{ role: 'user', content: { type: 'text', text: prompt.description || '' } }];
|
|
230
|
+
return this.rpcResult(id, { description: prompt.description, messages });
|
|
231
|
+
}
|
|
232
|
+
default:
|
|
233
|
+
return this.rpcError(id, types_1.MCP_ERRORS.METHOD_NOT_FOUND);
|
|
234
|
+
}
|
|
235
|
+
}
|
|
236
|
+
catch (err) {
|
|
237
|
+
return this.rpcError(id, { ...types_1.MCP_ERRORS.INTERNAL_ERROR, data: err.message });
|
|
238
|
+
}
|
|
239
|
+
}
|
|
240
|
+
rpcResult(id, result) {
|
|
241
|
+
return { jsonrpc: '2.0', id, result };
|
|
242
|
+
}
|
|
243
|
+
rpcError(id, error) {
|
|
244
|
+
return { jsonrpc: '2.0', id, error };
|
|
245
|
+
}
|
|
246
|
+
}
|
|
247
|
+
exports.MCPServer = MCPServer;
|
|
248
|
+
//# sourceMappingURL=server.js.map
|
|
@@ -0,0 +1,92 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* MCP Server types — JSON-RPC 2.0 based Model Context Protocol
|
|
3
|
+
*/
|
|
4
|
+
export interface MCPServerConfig {
|
|
5
|
+
name: string;
|
|
6
|
+
version: string;
|
|
7
|
+
tools?: MCPServerToolDefinition[];
|
|
8
|
+
resources?: MCPResourceDefinition[];
|
|
9
|
+
prompts?: MCPPromptDefinition[];
|
|
10
|
+
}
|
|
11
|
+
export interface MCPServerToolDefinition {
|
|
12
|
+
name: string;
|
|
13
|
+
description: string;
|
|
14
|
+
inputSchema: Record<string, any>;
|
|
15
|
+
handler: (args: any) => Promise<any>;
|
|
16
|
+
}
|
|
17
|
+
export interface MCPResourceDefinition {
|
|
18
|
+
uri: string;
|
|
19
|
+
name: string;
|
|
20
|
+
description?: string;
|
|
21
|
+
mimeType?: string;
|
|
22
|
+
handler: () => Promise<string>;
|
|
23
|
+
}
|
|
24
|
+
export interface MCPPromptDefinition {
|
|
25
|
+
name: string;
|
|
26
|
+
description?: string;
|
|
27
|
+
arguments?: MCPPromptArgument[];
|
|
28
|
+
handler?: (args: Record<string, string>) => Promise<MCPPromptMessage[]>;
|
|
29
|
+
}
|
|
30
|
+
export interface MCPPromptArgument {
|
|
31
|
+
name: string;
|
|
32
|
+
description?: string;
|
|
33
|
+
required?: boolean;
|
|
34
|
+
}
|
|
35
|
+
export interface MCPPromptMessage {
|
|
36
|
+
role: 'user' | 'assistant';
|
|
37
|
+
content: {
|
|
38
|
+
type: 'text';
|
|
39
|
+
text: string;
|
|
40
|
+
};
|
|
41
|
+
}
|
|
42
|
+
export interface JsonRpcRequest {
|
|
43
|
+
jsonrpc: '2.0';
|
|
44
|
+
id?: number | string;
|
|
45
|
+
method: string;
|
|
46
|
+
params?: any;
|
|
47
|
+
}
|
|
48
|
+
export interface JsonRpcResponse {
|
|
49
|
+
jsonrpc: '2.0';
|
|
50
|
+
id: number | string | null;
|
|
51
|
+
result?: any;
|
|
52
|
+
error?: {
|
|
53
|
+
code: number;
|
|
54
|
+
message: string;
|
|
55
|
+
data?: any;
|
|
56
|
+
};
|
|
57
|
+
}
|
|
58
|
+
export declare const MCP_ERRORS: {
|
|
59
|
+
readonly PARSE_ERROR: {
|
|
60
|
+
readonly code: -32700;
|
|
61
|
+
readonly message: "Parse error";
|
|
62
|
+
};
|
|
63
|
+
readonly INVALID_REQUEST: {
|
|
64
|
+
readonly code: -32600;
|
|
65
|
+
readonly message: "Invalid Request";
|
|
66
|
+
};
|
|
67
|
+
readonly METHOD_NOT_FOUND: {
|
|
68
|
+
readonly code: -32601;
|
|
69
|
+
readonly message: "Method not found";
|
|
70
|
+
};
|
|
71
|
+
readonly INVALID_PARAMS: {
|
|
72
|
+
readonly code: -32602;
|
|
73
|
+
readonly message: "Invalid params";
|
|
74
|
+
};
|
|
75
|
+
readonly INTERNAL_ERROR: {
|
|
76
|
+
readonly code: -32603;
|
|
77
|
+
readonly message: "Internal error";
|
|
78
|
+
};
|
|
79
|
+
readonly TOOL_NOT_FOUND: {
|
|
80
|
+
readonly code: -32001;
|
|
81
|
+
readonly message: "Tool not found";
|
|
82
|
+
};
|
|
83
|
+
readonly RESOURCE_NOT_FOUND: {
|
|
84
|
+
readonly code: -32002;
|
|
85
|
+
readonly message: "Resource not found";
|
|
86
|
+
};
|
|
87
|
+
readonly PROMPT_NOT_FOUND: {
|
|
88
|
+
readonly code: -32003;
|
|
89
|
+
readonly message: "Prompt not found";
|
|
90
|
+
};
|
|
91
|
+
};
|
|
92
|
+
//# sourceMappingURL=types.d.ts.map
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
/**
|
|
3
|
+
* MCP Server types — JSON-RPC 2.0 based Model Context Protocol
|
|
4
|
+
*/
|
|
5
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
6
|
+
exports.MCP_ERRORS = void 0;
|
|
7
|
+
exports.MCP_ERRORS = {
|
|
8
|
+
PARSE_ERROR: { code: -32700, message: 'Parse error' },
|
|
9
|
+
INVALID_REQUEST: { code: -32600, message: 'Invalid Request' },
|
|
10
|
+
METHOD_NOT_FOUND: { code: -32601, message: 'Method not found' },
|
|
11
|
+
INVALID_PARAMS: { code: -32602, message: 'Invalid params' },
|
|
12
|
+
INTERNAL_ERROR: { code: -32603, message: 'Internal error' },
|
|
13
|
+
TOOL_NOT_FOUND: { code: -32001, message: 'Tool not found' },
|
|
14
|
+
RESOURCE_NOT_FOUND: { code: -32002, message: 'Resource not found' },
|
|
15
|
+
PROMPT_NOT_FOUND: { code: -32003, message: 'Prompt not found' },
|
|
16
|
+
};
|
|
17
|
+
//# sourceMappingURL=types.js.map
|
|
@@ -1,7 +1,11 @@
|
|
|
1
1
|
import type { Message } from '../core/types';
|
|
2
|
+
import type { MCPToolDefinition } from '../tools/mcp';
|
|
3
|
+
export interface ChatOptions {
|
|
4
|
+
tools?: MCPToolDefinition[];
|
|
5
|
+
}
|
|
2
6
|
export interface LLMProvider {
|
|
3
7
|
name: string;
|
|
4
|
-
chat(messages: Message[], systemPrompt?: string): Promise<string>;
|
|
8
|
+
chat(messages: Message[], systemPrompt?: string, options?: ChatOptions): Promise<string>;
|
|
5
9
|
chatStream(messages: Message[], systemPrompt?: string): AsyncIterable<string>;
|
|
6
10
|
}
|
|
7
11
|
export declare function createProvider(name?: string, model?: string, baseUrl?: string, apiKey?: string): LLMProvider;
|
package/dist/providers/index.js
CHANGED
|
@@ -43,6 +43,10 @@ function getApiKey() {
|
|
|
43
43
|
function getBaseUrl() {
|
|
44
44
|
return process.env.OPC_LLM_BASE_URL || 'https://api.openai.com/v1';
|
|
45
45
|
}
|
|
46
|
+
function buildToolPrompt(tools) {
|
|
47
|
+
const toolsDesc = tools.map(t => `- ${t.name}: ${t.description}\n Input schema: ${JSON.stringify(t.inputSchema)}`).join('\n');
|
|
48
|
+
return `\n\nYou have access to the following tools. To use a tool, respond with ONLY a JSON object in this format:\n<tool_call>{"name": "tool_name", "arguments": {...}}</tool_call>\n\nAvailable tools:\n${toolsDesc}\n\nIf you don't need a tool, respond normally with text.`;
|
|
49
|
+
}
|
|
46
50
|
class OpenAICompatibleProvider {
|
|
47
51
|
name;
|
|
48
52
|
model;
|
|
@@ -111,13 +115,16 @@ class OpenAICompatibleProvider {
|
|
|
111
115
|
req.end();
|
|
112
116
|
});
|
|
113
117
|
}
|
|
114
|
-
async chat(messages, systemPrompt) {
|
|
118
|
+
async chat(messages, systemPrompt, options) {
|
|
115
119
|
if (!this.apiKey) {
|
|
116
|
-
// Stub mode when no API key
|
|
117
120
|
const last = messages[messages.length - 1];
|
|
118
121
|
return `[${this.name}/${this.model} - no API key] Echo: ${last?.content ?? ''}`;
|
|
119
122
|
}
|
|
120
|
-
|
|
123
|
+
let effectivePrompt = systemPrompt;
|
|
124
|
+
if (options?.tools && options.tools.length > 0) {
|
|
125
|
+
effectivePrompt = (systemPrompt || '') + buildToolPrompt(options.tools);
|
|
126
|
+
}
|
|
127
|
+
const formatted = this.formatMessages(messages, effectivePrompt);
|
|
121
128
|
const result = await this.request({
|
|
122
129
|
model: this.model,
|
|
123
130
|
messages: formatted,
|
|
@@ -220,12 +227,16 @@ class GeminiNativeProvider {
|
|
|
220
227
|
}
|
|
221
228
|
return result;
|
|
222
229
|
}
|
|
223
|
-
async chat(messages, systemPrompt) {
|
|
230
|
+
async chat(messages, systemPrompt, options) {
|
|
224
231
|
if (!this.apiKey) {
|
|
225
232
|
const last = messages[messages.length - 1];
|
|
226
233
|
return `[gemini/${this.model} - no API key] Echo: ${last?.content ?? ''}`;
|
|
227
234
|
}
|
|
228
|
-
|
|
235
|
+
let effectivePrompt = systemPrompt;
|
|
236
|
+
if (options?.tools && options.tools.length > 0) {
|
|
237
|
+
effectivePrompt = (systemPrompt || '') + buildToolPrompt(options.tools);
|
|
238
|
+
}
|
|
239
|
+
const body = this.formatContents(messages, effectivePrompt);
|
|
229
240
|
const url = this.buildUrl(false);
|
|
230
241
|
const postData = JSON.stringify(body);
|
|
231
242
|
return new Promise((resolve, reject) => {
|
|
@@ -310,12 +321,10 @@ class GeminiNativeProvider {
|
|
|
310
321
|
function isGeminiNative() {
|
|
311
322
|
const baseUrl = process.env.OPC_LLM_BASE_URL || '';
|
|
312
323
|
const key = getApiKey();
|
|
313
|
-
// Use native Gemini API when: key starts with AQ. (new format) OR base URL points to googleapis
|
|
314
324
|
return key.startsWith('AQ.') || (baseUrl.includes('googleapis.com') && !baseUrl.includes('/openai'));
|
|
315
325
|
}
|
|
316
326
|
function createProvider(name = 'openai', model, baseUrl, apiKey) {
|
|
317
327
|
const finalModel = model || process.env.OPC_LLM_MODEL || 'gpt-4o-mini';
|
|
318
|
-
// Auto-detect ollama: use localhost:11434/v1 and dummy apiKey
|
|
319
328
|
if (name === 'ollama') {
|
|
320
329
|
const ollamaBase = baseUrl || process.env.OPC_LLM_BASE_URL || 'http://localhost:11434/v1';
|
|
321
330
|
const ollamaKey = apiKey || process.env.OPC_LLM_API_KEY || 'ollama';
|
|
@@ -323,11 +332,9 @@ function createProvider(name = 'openai', model, baseUrl, apiKey) {
|
|
|
323
332
|
}
|
|
324
333
|
const finalKey = apiKey || getApiKey();
|
|
325
334
|
const finalBaseUrl = baseUrl || getBaseUrl();
|
|
326
|
-
// Auto-detect Gemini native when key is new format or base URL points to googleapis
|
|
327
335
|
if (finalKey.startsWith('AQ.') || isGeminiNative()) {
|
|
328
336
|
return new GeminiNativeProvider(finalModel, finalKey);
|
|
329
337
|
}
|
|
330
|
-
// Auto-detect provider name from base URL
|
|
331
338
|
let resolvedName = name;
|
|
332
339
|
if (finalBaseUrl.includes('deepseek.com')) {
|
|
333
340
|
resolvedName = 'deepseek';
|
|
@@ -0,0 +1,45 @@
|
|
|
1
|
+
export interface PackageManifest {
|
|
2
|
+
name: string;
|
|
3
|
+
version: string;
|
|
4
|
+
description: string;
|
|
5
|
+
author: string;
|
|
6
|
+
license: string;
|
|
7
|
+
agent: {
|
|
8
|
+
model: string;
|
|
9
|
+
provider: string;
|
|
10
|
+
channels: string[];
|
|
11
|
+
skills: string[];
|
|
12
|
+
tools: string[];
|
|
13
|
+
};
|
|
14
|
+
files: string[];
|
|
15
|
+
checksum: string;
|
|
16
|
+
createdAt: string;
|
|
17
|
+
}
|
|
18
|
+
export interface PublishOptions {
|
|
19
|
+
dryRun?: boolean;
|
|
20
|
+
registry?: string;
|
|
21
|
+
tag?: string;
|
|
22
|
+
access?: 'public' | 'private';
|
|
23
|
+
}
|
|
24
|
+
export declare class AgentPackager {
|
|
25
|
+
validate(dir: string): Promise<{
|
|
26
|
+
valid: boolean;
|
|
27
|
+
errors: string[];
|
|
28
|
+
warnings: string[];
|
|
29
|
+
}>;
|
|
30
|
+
listFiles(dir: string): Promise<string[]>;
|
|
31
|
+
pack(dir: string): Promise<{
|
|
32
|
+
path: string;
|
|
33
|
+
manifest: PackageManifest;
|
|
34
|
+
}>;
|
|
35
|
+
}
|
|
36
|
+
export declare class AgentPublisher {
|
|
37
|
+
publish(packagePath: string, manifest: PackageManifest, options?: PublishOptions): Promise<{
|
|
38
|
+
success: boolean;
|
|
39
|
+
url?: string;
|
|
40
|
+
}>;
|
|
41
|
+
}
|
|
42
|
+
export declare class AgentInstaller {
|
|
43
|
+
install(source: string, targetDir: string): Promise<void>;
|
|
44
|
+
}
|
|
45
|
+
//# sourceMappingURL=index.d.ts.map
|