@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.
Files changed (105) hide show
  1. package/README.md +69 -7
  2. package/dist/action.cjs +839 -0
  3. package/dist/action.d.cts +88 -0
  4. package/dist/action.d.ts +88 -0
  5. package/dist/action.js +8 -0
  6. package/dist/agent-plugin.cjs +46 -0
  7. package/dist/agent-plugin.d.cts +43 -33
  8. package/dist/agent-plugin.d.ts +43 -33
  9. package/dist/agent-plugin.js +1 -1
  10. package/dist/agent.cjs +16 -0
  11. package/dist/agent.d.cts +377 -1
  12. package/dist/agent.d.ts +377 -1
  13. package/dist/agent.js +4 -2
  14. package/dist/app-B0Z9Ew_R.d.cts +141 -0
  15. package/dist/app-C-BDJwfG.d.ts +141 -0
  16. package/dist/builder.cjs +1194 -0
  17. package/dist/builder.d.cts +217 -0
  18. package/dist/builder.d.ts +217 -0
  19. package/dist/builder.js +29 -0
  20. package/dist/chunk-4TPUZDTI.js +94 -0
  21. package/dist/chunk-BC3A7HMO.js +164 -0
  22. package/dist/chunk-FZSFZOIN.js +200 -0
  23. package/dist/{chunk-ODFEUVPW.js → chunk-HACAGK65.js} +1 -18
  24. package/dist/chunk-HLKJZAFK.js +361 -0
  25. package/dist/chunk-IKEDLLFY.js +19 -0
  26. package/dist/{chunk-G6FLVEC4.js → chunk-JX6DDRXV.js} +46 -0
  27. package/dist/{chunk-AO2KJRDD.js → chunk-NZKVOSC2.js} +192 -3
  28. package/dist/chunk-QYFUNJOH.js +83 -0
  29. package/dist/chunk-SN2QBJUF.js +148 -0
  30. package/dist/chunk-TLDPEGC7.js +21 -0
  31. package/dist/chunk-TXSHHZF2.js +0 -0
  32. package/dist/chunk-VLIRNNAE.js +154 -0
  33. package/dist/{chunk-MTUBUPIV.js → chunk-Z57QDDJR.js} +8 -227
  34. package/dist/chunk-ZTJWBRUL.js +282 -0
  35. package/dist/cli.cjs +347 -18
  36. package/dist/cli.js +128 -23
  37. package/dist/client-D5U6ssPc.d.cts +84 -0
  38. package/dist/client-D5U6ssPc.d.ts +84 -0
  39. package/dist/index.cjs +810 -86
  40. package/dist/index.d.cts +19 -634
  41. package/dist/index.d.ts +19 -634
  42. package/dist/index.js +82 -699
  43. package/dist/manifest.cjs +200 -4
  44. package/dist/manifest.d.cts +260 -5
  45. package/dist/manifest.d.ts +260 -5
  46. package/dist/manifest.js +15 -1
  47. package/dist/mcp/client.cjs +180 -0
  48. package/dist/mcp/client.d.cts +49 -0
  49. package/dist/mcp/client.d.ts +49 -0
  50. package/dist/mcp/client.js +10 -0
  51. package/dist/mcp/server.cjs +370 -0
  52. package/dist/mcp/server.d.cts +127 -0
  53. package/dist/mcp/server.d.ts +127 -0
  54. package/dist/mcp/server.js +9 -0
  55. package/dist/mcp.cjs +376 -0
  56. package/dist/mcp.d.cts +2 -0
  57. package/dist/mcp.d.ts +2 -0
  58. package/dist/mcp.js +17 -0
  59. package/dist/model.cjs +141 -0
  60. package/dist/model.d.cts +33 -0
  61. package/dist/model.d.ts +33 -0
  62. package/dist/model.js +18 -0
  63. package/dist/plugin.cjs +46 -0
  64. package/dist/plugin.d.cts +215 -0
  65. package/dist/plugin.d.ts +215 -0
  66. package/dist/plugin.js +8 -0
  67. package/dist/runnable.cjs +1438 -0
  68. package/dist/runnable.d.cts +274 -0
  69. package/dist/runnable.d.ts +274 -0
  70. package/dist/runnable.js +34 -0
  71. package/dist/{index-B6SkaAjJ.d.ts → tool-AjkdFvhE.d.ts} +88 -461
  72. package/dist/{index-BvAB5eMk.d.cts → tool-CgzW92O_.d.cts} +88 -461
  73. package/package.json +48 -3
  74. package/src/agent/loop.test.ts +4 -4
  75. package/src/agent/tools.ts +3 -3
  76. package/src/agent-plugin.test.ts +58 -0
  77. package/src/agent-plugin.ts +109 -36
  78. package/src/builder.ts +9 -0
  79. package/src/cli/dev.test.ts +26 -47
  80. package/src/cli/dev.ts +10 -2
  81. package/src/cli-security.test.ts +109 -0
  82. package/src/cli.ts +141 -25
  83. package/src/contracts-lockstep.test.ts +16 -2
  84. package/src/exports-lockstep.test.ts +93 -0
  85. package/src/generated/plugin-manifest.ts +322 -29
  86. package/src/index.ts +53 -0
  87. package/src/manifest-schema.test.ts +30 -1
  88. package/src/manifest.fixtures.test.ts +22 -6
  89. package/src/manifest.test.ts +165 -10
  90. package/src/manifest.ts +454 -188
  91. package/src/mcp/index.ts +18 -0
  92. package/src/mcp/server.ts +2 -1
  93. package/src/model/index.ts +22 -0
  94. package/src/plugin/ryu-plugin.ts +82 -0
  95. package/src/runnable/action.test.ts +128 -0
  96. package/src/runnable/action.ts +202 -0
  97. package/src/runnable/app.test.ts +2 -0
  98. package/src/runnable/app.ts +50 -14
  99. package/src/runnable/index.ts +20 -3
  100. package/src/runnable/primitives.test.ts +34 -0
  101. package/src/runnable/primitives.ts +116 -0
  102. package/src/runnable/runnable-types.ts +3 -0
  103. package/src/runnable/tool.ts +36 -5
  104. package/src/runnable/turn-hook.ts +8 -3
  105. package/src/slash-command.test.ts +69 -0
@@ -0,0 +1,164 @@
1
+ import {
2
+ PluginManifestSchema
3
+ } from "./chunk-NZKVOSC2.js";
4
+
5
+ // src/runnable/agent.ts
6
+ var CAPABILITY_SLOTS = ["rag", "memory", "tts", "stt"];
7
+ function lowerChatSlot(chat) {
8
+ if (chat === void 0) {
9
+ return {};
10
+ }
11
+ if (typeof chat === "string") {
12
+ return { model: chat };
13
+ }
14
+ return {
15
+ model: chat.model,
16
+ engine: chat.engine,
17
+ persona: chat.persona,
18
+ modelPrefKey: chat.modelPrefKey
19
+ };
20
+ }
21
+ function lowerCapabilitySlot(capability, slot, card) {
22
+ if (slot === void 0 || slot === false) {
23
+ return;
24
+ }
25
+ if (slot === true) {
26
+ card.capabilities.push({ capability });
27
+ return;
28
+ }
29
+ if (typeof slot === "string") {
30
+ card.capabilities.push({ capability });
31
+ card.providers[capability] = slot;
32
+ return;
33
+ }
34
+ card.capabilities.push(
35
+ slot.minVersion ? { capability, min_version: slot.minVersion } : { capability }
36
+ );
37
+ if (slot.provider) {
38
+ card.providers[capability] = slot.provider;
39
+ }
40
+ }
41
+ function lowerSlots(options) {
42
+ const card = {
43
+ ...lowerChatSlot(options.chat),
44
+ capabilities: [],
45
+ providers: {},
46
+ tools: []
47
+ };
48
+ for (const capability of CAPABILITY_SLOTS) {
49
+ lowerCapabilitySlot(capability, options[capability], card);
50
+ }
51
+ for (const t of options.tools ?? []) {
52
+ card.tools.push(typeof t === "string" ? t : t.id);
53
+ }
54
+ return card;
55
+ }
56
+ function defaultRun(card) {
57
+ return async (input, ctx) => {
58
+ const content = typeof input === "string" ? input : JSON.stringify(input ?? "");
59
+ const messages = card.persona ? [
60
+ { role: "system", content: card.persona },
61
+ { role: "user", content }
62
+ ] : [{ role: "user", content }];
63
+ const result = await ctx.gateway.chat(messages);
64
+ return result.content;
65
+ };
66
+ }
67
+ function cardConfig(card) {
68
+ const config = {};
69
+ if (card.model) {
70
+ config.model = card.model;
71
+ }
72
+ if (card.engine) {
73
+ config.engine = card.engine;
74
+ }
75
+ if (card.persona) {
76
+ config.persona = card.persona;
77
+ }
78
+ if (card.modelPrefKey) {
79
+ config.model_pref_key = card.modelPrefKey;
80
+ }
81
+ if (Object.keys(card.providers).length > 0) {
82
+ config.capability_providers = card.providers;
83
+ }
84
+ if (card.tools.length > 0) {
85
+ config.tools = card.tools;
86
+ }
87
+ return config;
88
+ }
89
+ function agentToManifest(agent, options) {
90
+ const config = cardConfig(agent.card);
91
+ const meta = {
92
+ id: agent.id,
93
+ name: agent.name,
94
+ kind: "agent",
95
+ ...Object.keys(config).length > 0 ? { config } : {}
96
+ };
97
+ const hasRequires = agent.card.capabilities.length > 0 || (options.grants?.length ?? 0) > 0;
98
+ const raw = {
99
+ id: options.id,
100
+ name: options.name ?? agent.name,
101
+ version: options.version,
102
+ runnables: [meta],
103
+ ...hasRequires ? {
104
+ requires: {
105
+ apps: [],
106
+ capabilities: agent.card.capabilities,
107
+ grants: options.grants ?? []
108
+ }
109
+ } : {}
110
+ };
111
+ const result = PluginManifestSchema.safeParse(raw);
112
+ if (!result.success) {
113
+ const first = result.error.issues[0];
114
+ const field = first?.path.join(".") ?? "unknown";
115
+ const message = first?.message ?? "validation failed";
116
+ throw new Error(
117
+ `agent manifest validation failed at '${field}': ${message}`
118
+ );
119
+ }
120
+ return result.data;
121
+ }
122
+ function defineAgent(options) {
123
+ const { id, name } = options;
124
+ const card = lowerSlots(options);
125
+ const run = options.run ?? defaultRun(card);
126
+ return {
127
+ id,
128
+ name,
129
+ kind: "agent",
130
+ run,
131
+ card,
132
+ toManifest(manifestOptions) {
133
+ return agentToManifest(this, manifestOptions);
134
+ }
135
+ };
136
+ }
137
+
138
+ // src/runnable/skill.ts
139
+ function defineSkill(options) {
140
+ const { id, name, run } = options;
141
+ return {
142
+ id,
143
+ name,
144
+ kind: "skill",
145
+ run
146
+ };
147
+ }
148
+
149
+ // src/runnable/workflow.ts
150
+ function defineWorkflow(options) {
151
+ const { id, name, run } = options;
152
+ return {
153
+ id,
154
+ name,
155
+ kind: "workflow",
156
+ run
157
+ };
158
+ }
159
+
160
+ export {
161
+ defineAgent,
162
+ defineSkill,
163
+ defineWorkflow
164
+ };
@@ -0,0 +1,200 @@
1
+ import {
2
+ MCP_PROTOCOL_VERSION,
3
+ callTool,
4
+ listTools
5
+ } from "./chunk-VLIRNNAE.js";
6
+
7
+ // src/mcp/server.ts
8
+ import { createInterface } from "readline";
9
+ function respond(id, result) {
10
+ return { jsonrpc: "2.0", id: id ?? null, result };
11
+ }
12
+ function respondError(id, code, message) {
13
+ return { jsonrpc: "2.0", id: id ?? null, error: { code, message } };
14
+ }
15
+ function wrapContent(value) {
16
+ return {
17
+ content: [
18
+ {
19
+ type: "text",
20
+ text: typeof value === "string" ? value : JSON.stringify(value)
21
+ }
22
+ ]
23
+ };
24
+ }
25
+ function unwrapContent(raw) {
26
+ const r = raw;
27
+ const text = r?.content?.[0]?.text;
28
+ if (text === void 0) {
29
+ return raw;
30
+ }
31
+ try {
32
+ return JSON.parse(text);
33
+ } catch {
34
+ return text;
35
+ }
36
+ }
37
+ var McpServer = class {
38
+ runnables = /* @__PURE__ */ new Map();
39
+ passthroughs = [];
40
+ /**
41
+ * Register an SDK Runnable as an MCP tool.
42
+ * Returns `this` for chaining.
43
+ */
44
+ register(runnable) {
45
+ this.runnables.set(runnable.name, runnable);
46
+ return this;
47
+ }
48
+ /**
49
+ * Register a passthrough to an external MCP stdio server (e.g. Ghost or
50
+ * Shadow). Tools from that server are fetched lazily and re-advertised.
51
+ * Returns `this` for chaining.
52
+ */
53
+ passthrough(registration) {
54
+ this.passthroughs.push(registration);
55
+ return this;
56
+ }
57
+ /** Fetch all tools: local Runnables + passthrough tools. */
58
+ async allTools() {
59
+ const local = [...this.runnables.values()].map((r) => ({
60
+ name: r.name,
61
+ description: r.description,
62
+ inputSchema: r.inputSchema
63
+ }));
64
+ const remote = [];
65
+ for (const pt of this.passthroughs) {
66
+ try {
67
+ const tools = await listTools(pt.command);
68
+ remote.push(...tools);
69
+ } catch (err) {
70
+ process.stderr.write(
71
+ `[mcp-server] passthrough '${pt.label}' list_tools failed: ${err}
72
+ `
73
+ );
74
+ }
75
+ }
76
+ return [...local, ...remote];
77
+ }
78
+ /** Handle a `tools/call` request. */
79
+ async handleCallTool(name, args) {
80
+ const local = this.runnables.get(name);
81
+ if (local) {
82
+ const result = await local.run(args);
83
+ return wrapContent(result);
84
+ }
85
+ for (const pt of this.passthroughs) {
86
+ try {
87
+ const tools = await listTools(pt.command);
88
+ if (tools.some((t) => t.name === name)) {
89
+ return await callTool(pt.command, name, args);
90
+ }
91
+ } catch {
92
+ }
93
+ }
94
+ throw new Error(`Unknown tool: ${name}`);
95
+ }
96
+ /**
97
+ * Handle a single parsed JSON-RPC request line. Returns the response to write
98
+ * (or null for notifications that require no response).
99
+ */
100
+ async handleRequest(req, initialized, write) {
101
+ const { id, method, params } = req;
102
+ if (method === "initialize") {
103
+ initialized.value = true;
104
+ write(
105
+ respond(id, {
106
+ protocolVersion: MCP_PROTOCOL_VERSION,
107
+ capabilities: { tools: {} },
108
+ serverInfo: { name: "ryu-sdk-server", version: "0.0.1" }
109
+ })
110
+ );
111
+ return;
112
+ }
113
+ if (method === "notifications/initialized") {
114
+ return;
115
+ }
116
+ if (!initialized.value) {
117
+ write(respondError(id, -32002, "Server not initialized"));
118
+ return;
119
+ }
120
+ if (method === "tools/list") {
121
+ try {
122
+ const tools = await this.allTools();
123
+ write(respond(id, { tools }));
124
+ } catch (err) {
125
+ write(respondError(id, -32603, String(err)));
126
+ }
127
+ return;
128
+ }
129
+ if (method === "tools/call") {
130
+ await this.handleToolsCall(id, params, write);
131
+ return;
132
+ }
133
+ write(respondError(id, -32601, `Method not found: ${method}`));
134
+ }
135
+ /** Handle a `tools/call` JSON-RPC request. */
136
+ async handleToolsCall(id, params, write) {
137
+ const p = params;
138
+ const toolName = p?.name;
139
+ const toolArgs = p?.arguments ?? {};
140
+ if (typeof toolName !== "string") {
141
+ write(respondError(id, -32602, "tools/call requires 'name'"));
142
+ return;
143
+ }
144
+ try {
145
+ const result = await this.handleCallTool(toolName, toolArgs);
146
+ write(respond(id, result));
147
+ } catch (err) {
148
+ write(
149
+ respond(id, {
150
+ content: [{ type: "text", text: String(err) }],
151
+ isError: true
152
+ })
153
+ );
154
+ }
155
+ }
156
+ /**
157
+ * Start reading JSON-RPC requests from the given readable stream and writing
158
+ * responses to the given writable stream.
159
+ *
160
+ * Defaults to `process.stdin` / `process.stdout`. Passing explicit streams
161
+ * lets tests inject a pair of in-process pipes.
162
+ *
163
+ * Resolves when the input stream ends (EOF).
164
+ */
165
+ serve(input = process.stdin, output = process.stdout) {
166
+ const write = (obj) => {
167
+ output.write(`${JSON.stringify(obj)}
168
+ `);
169
+ };
170
+ const initialized = { value: false };
171
+ return new Promise((resolve) => {
172
+ const rl = createInterface({
173
+ input,
174
+ crlfDelay: Number.POSITIVE_INFINITY
175
+ });
176
+ rl.on("line", (rawLine) => {
177
+ const line = rawLine.trim();
178
+ if (!line) {
179
+ return;
180
+ }
181
+ let req;
182
+ try {
183
+ req = JSON.parse(line);
184
+ } catch {
185
+ write(respondError(null, -32700, "Parse error"));
186
+ return;
187
+ }
188
+ this.handleRequest(req, initialized, write).catch((err) => {
189
+ write(respondError(req.id, -32603, String(err)));
190
+ });
191
+ });
192
+ rl.on("close", resolve);
193
+ });
194
+ }
195
+ };
196
+
197
+ export {
198
+ unwrapContent,
199
+ McpServer
200
+ };
@@ -77,24 +77,7 @@ function defineModel(modelId, options = {}) {
77
77
  return new ModelClient2(modelId, options);
78
78
  }
79
79
 
80
- // src/model/gateway.ts
81
- import * as native2 from "@ryuhq/sdk-native";
82
- var DEFAULT_GATEWAY_URL = "http://127.0.0.1:7981";
83
- function resolveGatewayUrl3() {
84
- return native2.resolveGatewayUrl();
85
- }
86
- function resolveGatewayToken2() {
87
- return native2.resolveGatewayToken() ?? void 0;
88
- }
89
- function assertAllowedEgressUrl(baseUrl) {
90
- native2.assertAllowedEgress(baseUrl);
91
- }
92
-
93
80
  export {
94
81
  ModelClient2 as ModelClient,
95
- defineModel,
96
- DEFAULT_GATEWAY_URL,
97
- resolveGatewayUrl3 as resolveGatewayUrl,
98
- resolveGatewayToken2 as resolveGatewayToken,
99
- assertAllowedEgressUrl
82
+ defineModel
100
83
  };