@ryuhq/sdk 0.1.14 → 0.2.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +69 -7
- package/dist/action.cjs +839 -0
- package/dist/action.d.cts +88 -0
- package/dist/action.d.ts +88 -0
- package/dist/action.js +8 -0
- package/dist/agent-plugin.cjs +46 -0
- package/dist/agent-plugin.d.cts +43 -33
- package/dist/agent-plugin.d.ts +43 -33
- package/dist/agent-plugin.js +1 -1
- package/dist/agent.cjs +16 -0
- package/dist/agent.d.cts +377 -1
- package/dist/agent.d.ts +377 -1
- package/dist/agent.js +4 -2
- package/dist/app-B0Z9Ew_R.d.cts +141 -0
- package/dist/app-C-BDJwfG.d.ts +141 -0
- package/dist/builder.cjs +1194 -0
- package/dist/builder.d.cts +217 -0
- package/dist/builder.d.ts +217 -0
- package/dist/builder.js +29 -0
- package/dist/chunk-4TPUZDTI.js +94 -0
- package/dist/chunk-BC3A7HMO.js +164 -0
- package/dist/chunk-FZSFZOIN.js +200 -0
- package/dist/{chunk-ODFEUVPW.js → chunk-HACAGK65.js} +1 -18
- package/dist/chunk-HLKJZAFK.js +361 -0
- package/dist/chunk-IKEDLLFY.js +19 -0
- package/dist/{chunk-G6FLVEC4.js → chunk-JX6DDRXV.js} +46 -0
- package/dist/{chunk-AO2KJRDD.js → chunk-NZKVOSC2.js} +192 -3
- package/dist/chunk-QYFUNJOH.js +83 -0
- package/dist/chunk-SN2QBJUF.js +148 -0
- package/dist/chunk-TLDPEGC7.js +21 -0
- package/dist/chunk-TXSHHZF2.js +0 -0
- package/dist/chunk-VLIRNNAE.js +154 -0
- package/dist/{chunk-MTUBUPIV.js → chunk-Z57QDDJR.js} +8 -227
- package/dist/chunk-ZTJWBRUL.js +282 -0
- package/dist/cli.cjs +347 -18
- package/dist/cli.js +128 -23
- package/dist/client-D5U6ssPc.d.cts +84 -0
- package/dist/client-D5U6ssPc.d.ts +84 -0
- package/dist/index.cjs +810 -86
- package/dist/index.d.cts +19 -634
- package/dist/index.d.ts +19 -634
- package/dist/index.js +82 -699
- package/dist/manifest.cjs +200 -4
- package/dist/manifest.d.cts +260 -5
- package/dist/manifest.d.ts +260 -5
- package/dist/manifest.js +15 -1
- package/dist/mcp/client.cjs +180 -0
- package/dist/mcp/client.d.cts +49 -0
- package/dist/mcp/client.d.ts +49 -0
- package/dist/mcp/client.js +10 -0
- package/dist/mcp/server.cjs +370 -0
- package/dist/mcp/server.d.cts +127 -0
- package/dist/mcp/server.d.ts +127 -0
- package/dist/mcp/server.js +9 -0
- package/dist/mcp.cjs +376 -0
- package/dist/mcp.d.cts +2 -0
- package/dist/mcp.d.ts +2 -0
- package/dist/mcp.js +17 -0
- package/dist/model.cjs +141 -0
- package/dist/model.d.cts +33 -0
- package/dist/model.d.ts +33 -0
- package/dist/model.js +18 -0
- package/dist/plugin.cjs +46 -0
- package/dist/plugin.d.cts +215 -0
- package/dist/plugin.d.ts +215 -0
- package/dist/plugin.js +8 -0
- package/dist/runnable.cjs +1438 -0
- package/dist/runnable.d.cts +274 -0
- package/dist/runnable.d.ts +274 -0
- package/dist/runnable.js +34 -0
- package/dist/{index-B6SkaAjJ.d.ts → tool-AjkdFvhE.d.ts} +88 -461
- package/dist/{index-BvAB5eMk.d.cts → tool-CgzW92O_.d.cts} +88 -461
- package/package.json +48 -3
- package/src/agent/loop.test.ts +4 -4
- package/src/agent/tools.ts +3 -3
- package/src/agent-plugin.test.ts +58 -0
- package/src/agent-plugin.ts +109 -36
- package/src/builder.ts +9 -0
- package/src/cli/dev.test.ts +26 -47
- package/src/cli/dev.ts +10 -2
- package/src/cli-security.test.ts +109 -0
- package/src/cli.ts +141 -25
- package/src/contracts-lockstep.test.ts +16 -2
- package/src/exports-lockstep.test.ts +93 -0
- package/src/generated/plugin-manifest.ts +322 -29
- package/src/index.ts +53 -0
- package/src/manifest-schema.test.ts +30 -1
- package/src/manifest.fixtures.test.ts +22 -6
- package/src/manifest.test.ts +165 -10
- package/src/manifest.ts +454 -188
- package/src/mcp/index.ts +18 -0
- package/src/mcp/server.ts +2 -1
- package/src/model/index.ts +22 -0
- package/src/plugin/ryu-plugin.ts +82 -0
- package/src/runnable/action.test.ts +128 -0
- package/src/runnable/action.ts +202 -0
- package/src/runnable/app.test.ts +2 -0
- package/src/runnable/app.ts +50 -14
- package/src/runnable/index.ts +20 -3
- package/src/runnable/primitives.test.ts +34 -0
- package/src/runnable/primitives.ts +116 -0
- package/src/runnable/runnable-types.ts +3 -0
- package/src/runnable/tool.ts +36 -5
- package/src/runnable/turn-hook.ts +8 -3
- package/src/slash-command.test.ts +69 -0
package/dist/mcp.cjs
ADDED
|
@@ -0,0 +1,376 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __defProp = Object.defineProperty;
|
|
3
|
+
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
|
|
4
|
+
var __getOwnPropNames = Object.getOwnPropertyNames;
|
|
5
|
+
var __hasOwnProp = Object.prototype.hasOwnProperty;
|
|
6
|
+
var __export = (target, all) => {
|
|
7
|
+
for (var name in all)
|
|
8
|
+
__defProp(target, name, { get: all[name], enumerable: true });
|
|
9
|
+
};
|
|
10
|
+
var __copyProps = (to, from, except, desc) => {
|
|
11
|
+
if (from && typeof from === "object" || typeof from === "function") {
|
|
12
|
+
for (let key of __getOwnPropNames(from))
|
|
13
|
+
if (!__hasOwnProp.call(to, key) && key !== except)
|
|
14
|
+
__defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
|
|
15
|
+
}
|
|
16
|
+
return to;
|
|
17
|
+
};
|
|
18
|
+
var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
|
|
19
|
+
|
|
20
|
+
// src/mcp/index.ts
|
|
21
|
+
var mcp_exports = {};
|
|
22
|
+
__export(mcp_exports, {
|
|
23
|
+
MCP_PROTOCOL_VERSION: () => MCP_PROTOCOL_VERSION,
|
|
24
|
+
McpServer: () => McpServer,
|
|
25
|
+
callTool: () => callTool,
|
|
26
|
+
listTools: () => listTools,
|
|
27
|
+
unwrapContent: () => unwrapContent
|
|
28
|
+
});
|
|
29
|
+
module.exports = __toCommonJS(mcp_exports);
|
|
30
|
+
|
|
31
|
+
// src/mcp/client.ts
|
|
32
|
+
var import_node_child_process = require("child_process");
|
|
33
|
+
var import_node_readline = require("readline");
|
|
34
|
+
var MCP_PROTOCOL_VERSION = "2024-11-05";
|
|
35
|
+
var RPC_TIMEOUT_MS = 6e4;
|
|
36
|
+
var McpConnection = class _McpConnection {
|
|
37
|
+
proc;
|
|
38
|
+
nextId = 1;
|
|
39
|
+
closed = false;
|
|
40
|
+
waiters = [];
|
|
41
|
+
constructor(proc) {
|
|
42
|
+
this.proc = proc;
|
|
43
|
+
}
|
|
44
|
+
/** Spawn the server and complete the MCP `initialize` handshake. */
|
|
45
|
+
static async connect(cmd) {
|
|
46
|
+
const env = { ...process.env, ...cmd.env ?? {} };
|
|
47
|
+
const proc = (0, import_node_child_process.spawn)(cmd.command, cmd.args ?? [], {
|
|
48
|
+
stdio: ["pipe", "pipe", "pipe"],
|
|
49
|
+
env
|
|
50
|
+
});
|
|
51
|
+
if (!(proc.stdin && proc.stdout)) {
|
|
52
|
+
proc.kill();
|
|
53
|
+
throw new Error(`MCP server '${cmd.command}' stdin/stdout unavailable`);
|
|
54
|
+
}
|
|
55
|
+
if (proc.stderr) {
|
|
56
|
+
proc.stderr.on("data", (chunk) => {
|
|
57
|
+
process.stderr.write(`[mcp-server] ${chunk.toString()}`);
|
|
58
|
+
});
|
|
59
|
+
}
|
|
60
|
+
const conn = new _McpConnection(proc);
|
|
61
|
+
const rl = (0, import_node_readline.createInterface)({
|
|
62
|
+
input: proc.stdout,
|
|
63
|
+
crlfDelay: Number.POSITIVE_INFINITY
|
|
64
|
+
});
|
|
65
|
+
rl.on("line", (rawLine) => {
|
|
66
|
+
const trimmed = rawLine.trim();
|
|
67
|
+
if (!trimmed) {
|
|
68
|
+
return;
|
|
69
|
+
}
|
|
70
|
+
let parsed;
|
|
71
|
+
try {
|
|
72
|
+
parsed = JSON.parse(trimmed);
|
|
73
|
+
} catch {
|
|
74
|
+
return;
|
|
75
|
+
}
|
|
76
|
+
if (parsed.id === void 0 || parsed.id === null) {
|
|
77
|
+
return;
|
|
78
|
+
}
|
|
79
|
+
const idx = conn.waiters.findIndex((w) => w.id === parsed.id);
|
|
80
|
+
if (idx === -1) {
|
|
81
|
+
return;
|
|
82
|
+
}
|
|
83
|
+
const [waiter] = conn.waiters.splice(idx, 1);
|
|
84
|
+
if (!waiter) {
|
|
85
|
+
return;
|
|
86
|
+
}
|
|
87
|
+
clearTimeout(waiter.timer);
|
|
88
|
+
if (parsed.error) {
|
|
89
|
+
waiter.reject(new Error(`MCP error: ${JSON.stringify(parsed.error)}`));
|
|
90
|
+
} else {
|
|
91
|
+
waiter.resolve(parsed.result ?? null);
|
|
92
|
+
}
|
|
93
|
+
});
|
|
94
|
+
rl.on("close", () => {
|
|
95
|
+
for (const waiter of conn.waiters.splice(0)) {
|
|
96
|
+
clearTimeout(waiter.timer);
|
|
97
|
+
waiter.reject(new Error("MCP server closed the connection"));
|
|
98
|
+
}
|
|
99
|
+
});
|
|
100
|
+
await conn.request("initialize", {
|
|
101
|
+
protocolVersion: MCP_PROTOCOL_VERSION,
|
|
102
|
+
capabilities: {},
|
|
103
|
+
clientInfo: { name: "ryu-sdk", version: "0.0.1" }
|
|
104
|
+
});
|
|
105
|
+
conn.notify("notifications/initialized", {});
|
|
106
|
+
return conn;
|
|
107
|
+
}
|
|
108
|
+
/** Send a JSON-RPC request and return the `result` field. */
|
|
109
|
+
request(method, params) {
|
|
110
|
+
const id = this.nextId++;
|
|
111
|
+
const frame = JSON.stringify({
|
|
112
|
+
jsonrpc: "2.0",
|
|
113
|
+
id,
|
|
114
|
+
method,
|
|
115
|
+
params
|
|
116
|
+
});
|
|
117
|
+
this.write(frame);
|
|
118
|
+
return new Promise((resolve, reject) => {
|
|
119
|
+
const timer = setTimeout(
|
|
120
|
+
() => reject(new Error(`MCP request '${method}' timed out`)),
|
|
121
|
+
RPC_TIMEOUT_MS
|
|
122
|
+
);
|
|
123
|
+
this.waiters.push({ id, resolve, reject, timer });
|
|
124
|
+
});
|
|
125
|
+
}
|
|
126
|
+
/** Send a JSON-RPC notification (no response expected). */
|
|
127
|
+
notify(method, params) {
|
|
128
|
+
const frame = JSON.stringify({ jsonrpc: "2.0", method, params });
|
|
129
|
+
this.write(frame);
|
|
130
|
+
}
|
|
131
|
+
write(frame) {
|
|
132
|
+
if (this.closed) {
|
|
133
|
+
return;
|
|
134
|
+
}
|
|
135
|
+
this.proc.stdin?.write(`${frame}
|
|
136
|
+
`);
|
|
137
|
+
}
|
|
138
|
+
/** Graceful shutdown: close stdin, then kill. */
|
|
139
|
+
async shutdown() {
|
|
140
|
+
this.closed = true;
|
|
141
|
+
this.proc.stdin?.end();
|
|
142
|
+
await new Promise((resolve) => {
|
|
143
|
+
this.proc.once("exit", () => resolve());
|
|
144
|
+
this.proc.kill();
|
|
145
|
+
setTimeout(resolve, 500);
|
|
146
|
+
});
|
|
147
|
+
}
|
|
148
|
+
};
|
|
149
|
+
async function listTools(cmd) {
|
|
150
|
+
const conn = await McpConnection.connect(cmd);
|
|
151
|
+
let result;
|
|
152
|
+
try {
|
|
153
|
+
result = await conn.request("tools/list", {});
|
|
154
|
+
} finally {
|
|
155
|
+
await conn.shutdown();
|
|
156
|
+
}
|
|
157
|
+
const tools = result?.tools ?? [];
|
|
158
|
+
return tools.map((t) => {
|
|
159
|
+
const tool = t;
|
|
160
|
+
const name = tool.name;
|
|
161
|
+
if (typeof name !== "string") {
|
|
162
|
+
return null;
|
|
163
|
+
}
|
|
164
|
+
return {
|
|
165
|
+
name,
|
|
166
|
+
description: typeof tool.description === "string" ? tool.description : void 0,
|
|
167
|
+
inputSchema: tool.inputSchema
|
|
168
|
+
};
|
|
169
|
+
}).filter((t) => t !== null);
|
|
170
|
+
}
|
|
171
|
+
async function callTool(cmd, tool, args) {
|
|
172
|
+
const conn = await McpConnection.connect(cmd);
|
|
173
|
+
try {
|
|
174
|
+
return await conn.request("tools/call", { name: tool, arguments: args });
|
|
175
|
+
} finally {
|
|
176
|
+
await conn.shutdown();
|
|
177
|
+
}
|
|
178
|
+
}
|
|
179
|
+
|
|
180
|
+
// src/mcp/server.ts
|
|
181
|
+
var import_node_readline2 = require("readline");
|
|
182
|
+
function respond(id, result) {
|
|
183
|
+
return { jsonrpc: "2.0", id: id ?? null, result };
|
|
184
|
+
}
|
|
185
|
+
function respondError(id, code, message) {
|
|
186
|
+
return { jsonrpc: "2.0", id: id ?? null, error: { code, message } };
|
|
187
|
+
}
|
|
188
|
+
function wrapContent(value) {
|
|
189
|
+
return {
|
|
190
|
+
content: [
|
|
191
|
+
{
|
|
192
|
+
type: "text",
|
|
193
|
+
text: typeof value === "string" ? value : JSON.stringify(value)
|
|
194
|
+
}
|
|
195
|
+
]
|
|
196
|
+
};
|
|
197
|
+
}
|
|
198
|
+
function unwrapContent(raw) {
|
|
199
|
+
const r = raw;
|
|
200
|
+
const text = r?.content?.[0]?.text;
|
|
201
|
+
if (text === void 0) {
|
|
202
|
+
return raw;
|
|
203
|
+
}
|
|
204
|
+
try {
|
|
205
|
+
return JSON.parse(text);
|
|
206
|
+
} catch {
|
|
207
|
+
return text;
|
|
208
|
+
}
|
|
209
|
+
}
|
|
210
|
+
var McpServer = class {
|
|
211
|
+
runnables = /* @__PURE__ */ new Map();
|
|
212
|
+
passthroughs = [];
|
|
213
|
+
/**
|
|
214
|
+
* Register an SDK Runnable as an MCP tool.
|
|
215
|
+
* Returns `this` for chaining.
|
|
216
|
+
*/
|
|
217
|
+
register(runnable) {
|
|
218
|
+
this.runnables.set(runnable.name, runnable);
|
|
219
|
+
return this;
|
|
220
|
+
}
|
|
221
|
+
/**
|
|
222
|
+
* Register a passthrough to an external MCP stdio server (e.g. Ghost or
|
|
223
|
+
* Shadow). Tools from that server are fetched lazily and re-advertised.
|
|
224
|
+
* Returns `this` for chaining.
|
|
225
|
+
*/
|
|
226
|
+
passthrough(registration) {
|
|
227
|
+
this.passthroughs.push(registration);
|
|
228
|
+
return this;
|
|
229
|
+
}
|
|
230
|
+
/** Fetch all tools: local Runnables + passthrough tools. */
|
|
231
|
+
async allTools() {
|
|
232
|
+
const local = [...this.runnables.values()].map((r) => ({
|
|
233
|
+
name: r.name,
|
|
234
|
+
description: r.description,
|
|
235
|
+
inputSchema: r.inputSchema
|
|
236
|
+
}));
|
|
237
|
+
const remote = [];
|
|
238
|
+
for (const pt of this.passthroughs) {
|
|
239
|
+
try {
|
|
240
|
+
const tools = await listTools(pt.command);
|
|
241
|
+
remote.push(...tools);
|
|
242
|
+
} catch (err) {
|
|
243
|
+
process.stderr.write(
|
|
244
|
+
`[mcp-server] passthrough '${pt.label}' list_tools failed: ${err}
|
|
245
|
+
`
|
|
246
|
+
);
|
|
247
|
+
}
|
|
248
|
+
}
|
|
249
|
+
return [...local, ...remote];
|
|
250
|
+
}
|
|
251
|
+
/** Handle a `tools/call` request. */
|
|
252
|
+
async handleCallTool(name, args) {
|
|
253
|
+
const local = this.runnables.get(name);
|
|
254
|
+
if (local) {
|
|
255
|
+
const result = await local.run(args);
|
|
256
|
+
return wrapContent(result);
|
|
257
|
+
}
|
|
258
|
+
for (const pt of this.passthroughs) {
|
|
259
|
+
try {
|
|
260
|
+
const tools = await listTools(pt.command);
|
|
261
|
+
if (tools.some((t) => t.name === name)) {
|
|
262
|
+
return await callTool(pt.command, name, args);
|
|
263
|
+
}
|
|
264
|
+
} catch {
|
|
265
|
+
}
|
|
266
|
+
}
|
|
267
|
+
throw new Error(`Unknown tool: ${name}`);
|
|
268
|
+
}
|
|
269
|
+
/**
|
|
270
|
+
* Handle a single parsed JSON-RPC request line. Returns the response to write
|
|
271
|
+
* (or null for notifications that require no response).
|
|
272
|
+
*/
|
|
273
|
+
async handleRequest(req, initialized, write) {
|
|
274
|
+
const { id, method, params } = req;
|
|
275
|
+
if (method === "initialize") {
|
|
276
|
+
initialized.value = true;
|
|
277
|
+
write(
|
|
278
|
+
respond(id, {
|
|
279
|
+
protocolVersion: MCP_PROTOCOL_VERSION,
|
|
280
|
+
capabilities: { tools: {} },
|
|
281
|
+
serverInfo: { name: "ryu-sdk-server", version: "0.0.1" }
|
|
282
|
+
})
|
|
283
|
+
);
|
|
284
|
+
return;
|
|
285
|
+
}
|
|
286
|
+
if (method === "notifications/initialized") {
|
|
287
|
+
return;
|
|
288
|
+
}
|
|
289
|
+
if (!initialized.value) {
|
|
290
|
+
write(respondError(id, -32002, "Server not initialized"));
|
|
291
|
+
return;
|
|
292
|
+
}
|
|
293
|
+
if (method === "tools/list") {
|
|
294
|
+
try {
|
|
295
|
+
const tools = await this.allTools();
|
|
296
|
+
write(respond(id, { tools }));
|
|
297
|
+
} catch (err) {
|
|
298
|
+
write(respondError(id, -32603, String(err)));
|
|
299
|
+
}
|
|
300
|
+
return;
|
|
301
|
+
}
|
|
302
|
+
if (method === "tools/call") {
|
|
303
|
+
await this.handleToolsCall(id, params, write);
|
|
304
|
+
return;
|
|
305
|
+
}
|
|
306
|
+
write(respondError(id, -32601, `Method not found: ${method}`));
|
|
307
|
+
}
|
|
308
|
+
/** Handle a `tools/call` JSON-RPC request. */
|
|
309
|
+
async handleToolsCall(id, params, write) {
|
|
310
|
+
const p = params;
|
|
311
|
+
const toolName = p?.name;
|
|
312
|
+
const toolArgs = p?.arguments ?? {};
|
|
313
|
+
if (typeof toolName !== "string") {
|
|
314
|
+
write(respondError(id, -32602, "tools/call requires 'name'"));
|
|
315
|
+
return;
|
|
316
|
+
}
|
|
317
|
+
try {
|
|
318
|
+
const result = await this.handleCallTool(toolName, toolArgs);
|
|
319
|
+
write(respond(id, result));
|
|
320
|
+
} catch (err) {
|
|
321
|
+
write(
|
|
322
|
+
respond(id, {
|
|
323
|
+
content: [{ type: "text", text: String(err) }],
|
|
324
|
+
isError: true
|
|
325
|
+
})
|
|
326
|
+
);
|
|
327
|
+
}
|
|
328
|
+
}
|
|
329
|
+
/**
|
|
330
|
+
* Start reading JSON-RPC requests from the given readable stream and writing
|
|
331
|
+
* responses to the given writable stream.
|
|
332
|
+
*
|
|
333
|
+
* Defaults to `process.stdin` / `process.stdout`. Passing explicit streams
|
|
334
|
+
* lets tests inject a pair of in-process pipes.
|
|
335
|
+
*
|
|
336
|
+
* Resolves when the input stream ends (EOF).
|
|
337
|
+
*/
|
|
338
|
+
serve(input = process.stdin, output = process.stdout) {
|
|
339
|
+
const write = (obj) => {
|
|
340
|
+
output.write(`${JSON.stringify(obj)}
|
|
341
|
+
`);
|
|
342
|
+
};
|
|
343
|
+
const initialized = { value: false };
|
|
344
|
+
return new Promise((resolve) => {
|
|
345
|
+
const rl = (0, import_node_readline2.createInterface)({
|
|
346
|
+
input,
|
|
347
|
+
crlfDelay: Number.POSITIVE_INFINITY
|
|
348
|
+
});
|
|
349
|
+
rl.on("line", (rawLine) => {
|
|
350
|
+
const line = rawLine.trim();
|
|
351
|
+
if (!line) {
|
|
352
|
+
return;
|
|
353
|
+
}
|
|
354
|
+
let req;
|
|
355
|
+
try {
|
|
356
|
+
req = JSON.parse(line);
|
|
357
|
+
} catch {
|
|
358
|
+
write(respondError(null, -32700, "Parse error"));
|
|
359
|
+
return;
|
|
360
|
+
}
|
|
361
|
+
this.handleRequest(req, initialized, write).catch((err) => {
|
|
362
|
+
write(respondError(req.id, -32603, String(err)));
|
|
363
|
+
});
|
|
364
|
+
});
|
|
365
|
+
rl.on("close", resolve);
|
|
366
|
+
});
|
|
367
|
+
}
|
|
368
|
+
};
|
|
369
|
+
// Annotate the CommonJS export names for ESM import in node:
|
|
370
|
+
0 && (module.exports = {
|
|
371
|
+
MCP_PROTOCOL_VERSION,
|
|
372
|
+
McpServer,
|
|
373
|
+
callTool,
|
|
374
|
+
listTools,
|
|
375
|
+
unwrapContent
|
|
376
|
+
});
|
package/dist/mcp.d.cts
ADDED
package/dist/mcp.d.ts
ADDED
package/dist/mcp.js
ADDED
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
import "./chunk-TXSHHZF2.js";
|
|
2
|
+
import {
|
|
3
|
+
McpServer,
|
|
4
|
+
unwrapContent
|
|
5
|
+
} from "./chunk-FZSFZOIN.js";
|
|
6
|
+
import {
|
|
7
|
+
MCP_PROTOCOL_VERSION,
|
|
8
|
+
callTool,
|
|
9
|
+
listTools
|
|
10
|
+
} from "./chunk-VLIRNNAE.js";
|
|
11
|
+
export {
|
|
12
|
+
MCP_PROTOCOL_VERSION,
|
|
13
|
+
McpServer,
|
|
14
|
+
callTool,
|
|
15
|
+
listTools,
|
|
16
|
+
unwrapContent
|
|
17
|
+
};
|
package/dist/model.cjs
ADDED
|
@@ -0,0 +1,141 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __create = Object.create;
|
|
3
|
+
var __defProp = Object.defineProperty;
|
|
4
|
+
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
|
|
5
|
+
var __getOwnPropNames = Object.getOwnPropertyNames;
|
|
6
|
+
var __getProtoOf = Object.getPrototypeOf;
|
|
7
|
+
var __hasOwnProp = Object.prototype.hasOwnProperty;
|
|
8
|
+
var __export = (target, all) => {
|
|
9
|
+
for (var name in all)
|
|
10
|
+
__defProp(target, name, { get: all[name], enumerable: true });
|
|
11
|
+
};
|
|
12
|
+
var __copyProps = (to, from, except, desc) => {
|
|
13
|
+
if (from && typeof from === "object" || typeof from === "function") {
|
|
14
|
+
for (let key of __getOwnPropNames(from))
|
|
15
|
+
if (!__hasOwnProp.call(to, key) && key !== except)
|
|
16
|
+
__defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
|
|
17
|
+
}
|
|
18
|
+
return to;
|
|
19
|
+
};
|
|
20
|
+
var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__getProtoOf(mod)) : {}, __copyProps(
|
|
21
|
+
// If the importer is in node compatibility mode or this is not an ESM
|
|
22
|
+
// file that has been converted to a CommonJS file using a Babel-
|
|
23
|
+
// compatible transform (i.e. "__esModule" has not been set), then set
|
|
24
|
+
// "default" to the CommonJS "module.exports" for node compatibility.
|
|
25
|
+
isNodeMode || !mod || !mod.__esModule ? __defProp(target, "default", { value: mod, enumerable: true }) : target,
|
|
26
|
+
mod
|
|
27
|
+
));
|
|
28
|
+
var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
|
|
29
|
+
|
|
30
|
+
// src/model/index.ts
|
|
31
|
+
var model_exports = {};
|
|
32
|
+
__export(model_exports, {
|
|
33
|
+
DEFAULT_GATEWAY_URL: () => DEFAULT_GATEWAY_URL,
|
|
34
|
+
ModelClient: () => ModelClient2,
|
|
35
|
+
assertAllowedEgressUrl: () => assertAllowedEgressUrl,
|
|
36
|
+
defineModel: () => defineModel,
|
|
37
|
+
resolveGatewayToken: () => resolveGatewayToken2,
|
|
38
|
+
resolveGatewayUrl: () => resolveGatewayUrl3
|
|
39
|
+
});
|
|
40
|
+
module.exports = __toCommonJS(model_exports);
|
|
41
|
+
|
|
42
|
+
// src/model/client.ts
|
|
43
|
+
var native = __toESM(require("@ryuhq/sdk-native"), 1);
|
|
44
|
+
var ModelClient2 = class {
|
|
45
|
+
model;
|
|
46
|
+
baseUrl;
|
|
47
|
+
native;
|
|
48
|
+
constructor(model, options = {}) {
|
|
49
|
+
this.native = new native.ModelClient(
|
|
50
|
+
model,
|
|
51
|
+
options.baseUrl ?? null,
|
|
52
|
+
options.token ?? null
|
|
53
|
+
);
|
|
54
|
+
this.model = model;
|
|
55
|
+
this.baseUrl = options.baseUrl ?? native.resolveGatewayUrl();
|
|
56
|
+
}
|
|
57
|
+
/** Send a non-streaming chat completion request to the gateway. */
|
|
58
|
+
async chat(messages) {
|
|
59
|
+
const res = await this.native.chat(messages);
|
|
60
|
+
const usage = res.promptTokens === void 0 && res.completionTokens === void 0 && res.totalTokens === void 0 ? void 0 : {
|
|
61
|
+
promptTokens: res.promptTokens ?? 0,
|
|
62
|
+
completionTokens: res.completionTokens ?? 0,
|
|
63
|
+
totalTokens: res.totalTokens ?? 0
|
|
64
|
+
};
|
|
65
|
+
return {
|
|
66
|
+
content: res.content,
|
|
67
|
+
finishReason: res.finishReason ?? null,
|
|
68
|
+
usage
|
|
69
|
+
};
|
|
70
|
+
}
|
|
71
|
+
/** Send a streaming chat completion request, yielding deltas as they arrive. */
|
|
72
|
+
async *stream(messages) {
|
|
73
|
+
const queue = [];
|
|
74
|
+
let done = false;
|
|
75
|
+
let failure = null;
|
|
76
|
+
let wake = null;
|
|
77
|
+
const notify = () => {
|
|
78
|
+
if (wake) {
|
|
79
|
+
const w = wake;
|
|
80
|
+
wake = null;
|
|
81
|
+
w();
|
|
82
|
+
}
|
|
83
|
+
};
|
|
84
|
+
this.native.stream(messages, (err, delta) => {
|
|
85
|
+
if (err) {
|
|
86
|
+
failure = err;
|
|
87
|
+
done = true;
|
|
88
|
+
} else if (delta === null || delta === void 0) {
|
|
89
|
+
done = true;
|
|
90
|
+
} else {
|
|
91
|
+
queue.push({
|
|
92
|
+
content: delta.content ?? null,
|
|
93
|
+
finishReason: delta.finishReason ?? null
|
|
94
|
+
});
|
|
95
|
+
}
|
|
96
|
+
notify();
|
|
97
|
+
});
|
|
98
|
+
while (true) {
|
|
99
|
+
while (queue.length > 0) {
|
|
100
|
+
const next = queue.shift();
|
|
101
|
+
if (next) {
|
|
102
|
+
yield next;
|
|
103
|
+
}
|
|
104
|
+
}
|
|
105
|
+
if (failure) {
|
|
106
|
+
throw failure;
|
|
107
|
+
}
|
|
108
|
+
if (done) {
|
|
109
|
+
return;
|
|
110
|
+
}
|
|
111
|
+
await new Promise((resolve) => {
|
|
112
|
+
wake = resolve;
|
|
113
|
+
});
|
|
114
|
+
}
|
|
115
|
+
}
|
|
116
|
+
};
|
|
117
|
+
function defineModel(modelId, options = {}) {
|
|
118
|
+
return new ModelClient2(modelId, options);
|
|
119
|
+
}
|
|
120
|
+
|
|
121
|
+
// src/model/gateway.ts
|
|
122
|
+
var native2 = __toESM(require("@ryuhq/sdk-native"), 1);
|
|
123
|
+
var DEFAULT_GATEWAY_URL = "http://127.0.0.1:7981";
|
|
124
|
+
function resolveGatewayUrl3() {
|
|
125
|
+
return native2.resolveGatewayUrl();
|
|
126
|
+
}
|
|
127
|
+
function resolveGatewayToken2() {
|
|
128
|
+
return native2.resolveGatewayToken() ?? void 0;
|
|
129
|
+
}
|
|
130
|
+
function assertAllowedEgressUrl(baseUrl) {
|
|
131
|
+
native2.assertAllowedEgress(baseUrl);
|
|
132
|
+
}
|
|
133
|
+
// Annotate the CommonJS export names for ESM import in node:
|
|
134
|
+
0 && (module.exports = {
|
|
135
|
+
DEFAULT_GATEWAY_URL,
|
|
136
|
+
ModelClient,
|
|
137
|
+
assertAllowedEgressUrl,
|
|
138
|
+
defineModel,
|
|
139
|
+
resolveGatewayToken,
|
|
140
|
+
resolveGatewayUrl
|
|
141
|
+
});
|
package/dist/model.d.cts
ADDED
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
export { C as ChatDelta, a as ChatMessage, b as ChatResult, M as ModelClient, c as ModelClientOptions, d as defineModel } from './client-D5U6ssPc.cjs';
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* Gateway configuration + egress enforcement for the Ryu SDK model client.
|
|
5
|
+
*
|
|
6
|
+
* Rust-cored: every function here delegates to the `@ryuhq/sdk-native` addon, so
|
|
7
|
+
* the gateway URL/token resolution and the direct-provider egress blocklist are
|
|
8
|
+
* the exact same implementation (`crates/ryu-sdk/src/gateway.rs`) used by the
|
|
9
|
+
* Go/Python bindings and Core itself — one source of truth, no drift.
|
|
10
|
+
*/
|
|
11
|
+
/** Default base URL for the local Ryu gateway — matches Core's DEFAULT_GATEWAY_URL. */
|
|
12
|
+
declare const DEFAULT_GATEWAY_URL = "http://127.0.0.1:7981";
|
|
13
|
+
/**
|
|
14
|
+
* Resolve the effective gateway base URL.
|
|
15
|
+
*
|
|
16
|
+
* Resolution order (in the Rust core):
|
|
17
|
+
* 1. `RYU_GATEWAY_URL` env var (when non-empty).
|
|
18
|
+
* 2. `DEFAULT_GATEWAY_URL`.
|
|
19
|
+
*/
|
|
20
|
+
declare function resolveGatewayUrl(): string;
|
|
21
|
+
/**
|
|
22
|
+
* Resolve the optional gateway bearer token (`RYU_GATEWAY_TOKEN`), or
|
|
23
|
+
* `undefined` when unset/empty.
|
|
24
|
+
*/
|
|
25
|
+
declare function resolveGatewayToken(): string | undefined;
|
|
26
|
+
/**
|
|
27
|
+
* Validate that `baseUrl` is an allowed egress target. Throws a descriptive
|
|
28
|
+
* `Error` (from the Rust core) when the URL matches a known direct-provider
|
|
29
|
+
* pattern, enforcing the BYOK-at-the-gateway rule.
|
|
30
|
+
*/
|
|
31
|
+
declare function assertAllowedEgressUrl(baseUrl: string): void;
|
|
32
|
+
|
|
33
|
+
export { DEFAULT_GATEWAY_URL, assertAllowedEgressUrl, resolveGatewayToken, resolveGatewayUrl };
|
package/dist/model.d.ts
ADDED
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
export { C as ChatDelta, a as ChatMessage, b as ChatResult, M as ModelClient, c as ModelClientOptions, d as defineModel } from './client-D5U6ssPc.js';
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* Gateway configuration + egress enforcement for the Ryu SDK model client.
|
|
5
|
+
*
|
|
6
|
+
* Rust-cored: every function here delegates to the `@ryuhq/sdk-native` addon, so
|
|
7
|
+
* the gateway URL/token resolution and the direct-provider egress blocklist are
|
|
8
|
+
* the exact same implementation (`crates/ryu-sdk/src/gateway.rs`) used by the
|
|
9
|
+
* Go/Python bindings and Core itself — one source of truth, no drift.
|
|
10
|
+
*/
|
|
11
|
+
/** Default base URL for the local Ryu gateway — matches Core's DEFAULT_GATEWAY_URL. */
|
|
12
|
+
declare const DEFAULT_GATEWAY_URL = "http://127.0.0.1:7981";
|
|
13
|
+
/**
|
|
14
|
+
* Resolve the effective gateway base URL.
|
|
15
|
+
*
|
|
16
|
+
* Resolution order (in the Rust core):
|
|
17
|
+
* 1. `RYU_GATEWAY_URL` env var (when non-empty).
|
|
18
|
+
* 2. `DEFAULT_GATEWAY_URL`.
|
|
19
|
+
*/
|
|
20
|
+
declare function resolveGatewayUrl(): string;
|
|
21
|
+
/**
|
|
22
|
+
* Resolve the optional gateway bearer token (`RYU_GATEWAY_TOKEN`), or
|
|
23
|
+
* `undefined` when unset/empty.
|
|
24
|
+
*/
|
|
25
|
+
declare function resolveGatewayToken(): string | undefined;
|
|
26
|
+
/**
|
|
27
|
+
* Validate that `baseUrl` is an allowed egress target. Throws a descriptive
|
|
28
|
+
* `Error` (from the Rust core) when the URL matches a known direct-provider
|
|
29
|
+
* pattern, enforcing the BYOK-at-the-gateway rule.
|
|
30
|
+
*/
|
|
31
|
+
declare function assertAllowedEgressUrl(baseUrl: string): void;
|
|
32
|
+
|
|
33
|
+
export { DEFAULT_GATEWAY_URL, assertAllowedEgressUrl, resolveGatewayToken, resolveGatewayUrl };
|
package/dist/model.js
ADDED
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
import {
|
|
2
|
+
ModelClient,
|
|
3
|
+
defineModel
|
|
4
|
+
} from "./chunk-HACAGK65.js";
|
|
5
|
+
import {
|
|
6
|
+
DEFAULT_GATEWAY_URL,
|
|
7
|
+
assertAllowedEgressUrl,
|
|
8
|
+
resolveGatewayToken,
|
|
9
|
+
resolveGatewayUrl
|
|
10
|
+
} from "./chunk-IKEDLLFY.js";
|
|
11
|
+
export {
|
|
12
|
+
DEFAULT_GATEWAY_URL,
|
|
13
|
+
ModelClient,
|
|
14
|
+
assertAllowedEgressUrl,
|
|
15
|
+
defineModel,
|
|
16
|
+
resolveGatewayToken,
|
|
17
|
+
resolveGatewayUrl
|
|
18
|
+
};
|
package/dist/plugin.cjs
ADDED
|
@@ -0,0 +1,46 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __defProp = Object.defineProperty;
|
|
3
|
+
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
|
|
4
|
+
var __getOwnPropNames = Object.getOwnPropertyNames;
|
|
5
|
+
var __hasOwnProp = Object.prototype.hasOwnProperty;
|
|
6
|
+
var __export = (target, all) => {
|
|
7
|
+
for (var name in all)
|
|
8
|
+
__defProp(target, name, { get: all[name], enumerable: true });
|
|
9
|
+
};
|
|
10
|
+
var __copyProps = (to, from, except, desc) => {
|
|
11
|
+
if (from && typeof from === "object" || typeof from === "function") {
|
|
12
|
+
for (let key of __getOwnPropNames(from))
|
|
13
|
+
if (!__hasOwnProp.call(to, key) && key !== except)
|
|
14
|
+
__defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
|
|
15
|
+
}
|
|
16
|
+
return to;
|
|
17
|
+
};
|
|
18
|
+
var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
|
|
19
|
+
|
|
20
|
+
// src/plugin/ryu-plugin.ts
|
|
21
|
+
var ryu_plugin_exports = {};
|
|
22
|
+
__export(ryu_plugin_exports, {
|
|
23
|
+
definePlugin: () => definePlugin,
|
|
24
|
+
toDisposable: () => toDisposable
|
|
25
|
+
});
|
|
26
|
+
module.exports = __toCommonJS(ryu_plugin_exports);
|
|
27
|
+
function toDisposable(teardown) {
|
|
28
|
+
let done = false;
|
|
29
|
+
return {
|
|
30
|
+
dispose() {
|
|
31
|
+
if (done) {
|
|
32
|
+
return;
|
|
33
|
+
}
|
|
34
|
+
done = true;
|
|
35
|
+
teardown();
|
|
36
|
+
}
|
|
37
|
+
};
|
|
38
|
+
}
|
|
39
|
+
function definePlugin(plugin) {
|
|
40
|
+
return plugin;
|
|
41
|
+
}
|
|
42
|
+
// Annotate the CommonJS export names for ESM import in node:
|
|
43
|
+
0 && (module.exports = {
|
|
44
|
+
definePlugin,
|
|
45
|
+
toDisposable
|
|
46
|
+
});
|