@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
@@ -1,178 +1,5 @@
1
1
  import { RunnableMeta } from './manifest.cjs';
2
-
3
- /**
4
- * Native tool-calling model call for the Ryu agent runtime.
5
- *
6
- * The gateway-mandatory `ModelClient` (packages/sdk/src/model/client.ts) only
7
- * exposes text `chat`/`stream` — it cannot pass a `tools` array or receive
8
- * `tool_calls`. The autonomous agent loop needs both, so this module makes a
9
- * direct request to the node's gateway `POST /v1/chat/completions` endpoint
10
- * with the caller's own `tools` and reads back `message.tool_calls`.
11
- *
12
- * The no-direct-provider guarantee is preserved: `assertAllowedEgressUrl` (the
13
- * same Rust-cored blocklist the ModelClient uses) is called before every fetch,
14
- * so a direct provider base URL throws exactly as it would elsewhere in the SDK.
15
- *
16
- * `x-ryu-raw-tools: on` is always sent. On a plain gateway it is a harmless
17
- * no-op; on a Composio-on managed node it forces the plain completion branch so
18
- * the caller's `tool_calls` are returned verbatim instead of being intercepted
19
- * and executed by Core's own tool loop (see apps/gateway/src/pipeline/mod.rs).
20
- */
21
- /** An OpenAI function tool definition passed to the model. */
22
- interface ToolFunctionDef {
23
- function: {
24
- description?: string;
25
- name: string;
26
- /** JSON Schema for the function's arguments. */
27
- parameters: Record<string, unknown>;
28
- };
29
- type: "function";
30
- }
31
- /** A single tool call emitted by the model. */
32
- interface ToolCall {
33
- function: {
34
- /** JSON-encoded arguments string (per the OpenAI wire format). */
35
- arguments: string;
36
- name: string;
37
- };
38
- id: string;
39
- type: "function";
40
- }
41
- /** An assistant turn — may carry text, tool calls, or both. */
42
- interface AssistantMessage {
43
- content: string | null;
44
- role: "assistant";
45
- tool_calls?: ToolCall[];
46
- }
47
- /** A message in the loop's running transcript. */
48
- type LoopMessage = {
49
- content: string;
50
- role: "system" | "user";
51
- } | AssistantMessage | {
52
- content: string;
53
- role: "tool";
54
- tool_call_id: string;
55
- };
56
- /** Token usage as reported by the gateway (optional — gateway may omit). */
57
- interface ModelUsage {
58
- completionTokens: number;
59
- promptTokens: number;
60
- totalTokens: number;
61
- }
62
- /** Options for a single native tool-calling completion. */
63
- interface ModelCallOptions {
64
- /** Gateway base URL (no trailing `/v1`). */
65
- baseUrl: string;
66
- /** Running transcript. */
67
- messages: LoopMessage[];
68
- /** Model id routed by the gateway (provider is derived from the id). */
69
- model: string;
70
- /** Abort signal for cancellation. */
71
- signal?: AbortSignal;
72
- /** Bearer token forwarded to the gateway (never a provider key). */
73
- token?: string;
74
- /** How the model should choose tools; defaults to gateway/provider default. */
75
- toolChoice?: "auto" | "none" | "required";
76
- /** Function tool definitions the model may call. */
77
- tools?: ToolFunctionDef[];
78
- }
79
- /** Result of a single completion. */
80
- interface ModelCallResult {
81
- finishReason: string | null;
82
- message: AssistantMessage;
83
- usage?: ModelUsage;
84
- }
85
- /**
86
- * Call the node's gateway with the caller's own tools and return the first
87
- * choice, including any `tool_calls`.
88
- *
89
- * Throws when the base URL is a direct provider (egress enforcement) or when
90
- * the gateway returns a non-2xx status.
91
- */
92
- declare function callModelWithTools(options: ModelCallOptions): Promise<ModelCallResult>;
93
-
94
- /**
95
- * Gateway-mandatory model client for the Ryu SDK.
96
- *
97
- * Rust-cored: this is a thin TypeScript wrapper over the `@ryuhq/sdk-native`
98
- * addon's `ModelClient`, which is the `crates/ryu-sdk` Rust core. Every model
99
- * call is routed by the Rust core to the Ryu gateway's OpenAI-compatible
100
- * `/v1/chat/completions` endpoint; direct-provider base URLs are rejected at
101
- * construction. No provider SDK or base URL is ever imported here.
102
- *
103
- * Usage:
104
- *
105
- * const model = defineModel("gpt-4o");
106
- * const reply = await model.chat([{ role: "user", content: "hello" }]);
107
- * for await (const delta of model.stream([{ role: "user", content: "hi" }])) {
108
- * process.stdout.write(delta.content);
109
- * }
110
- */
111
- /** A single message in a chat conversation. */
112
- interface ChatMessage {
113
- /** The message text. */
114
- content: string;
115
- /** The speaker: "system", "user", or "assistant". */
116
- role: "system" | "user" | "assistant";
117
- }
118
- /** A streaming chat completion delta. */
119
- interface ChatDelta {
120
- /** Incremental text fragment from the model. */
121
- content: string | null;
122
- /** Non-null on the final chunk when `finish_reason` is set. */
123
- finishReason: string | null;
124
- }
125
- /** Non-streaming chat completion result. */
126
- interface ChatResult {
127
- /** The full assistant reply text. */
128
- content: string;
129
- /** The gateway/model-reported finish reason. */
130
- finishReason: string | null;
131
- /** Usage stats as reported by the gateway (optional — gateway may omit). */
132
- usage?: {
133
- promptTokens: number;
134
- completionTokens: number;
135
- totalTokens: number;
136
- };
137
- }
138
- /** Options accepted by `defineModel`. */
139
- interface ModelClientOptions {
140
- /**
141
- * Gateway base URL (no trailing `/v1`). Defaults to `RYU_GATEWAY_URL` then
142
- * the Rust core's default. Direct provider URLs are rejected at construction.
143
- */
144
- baseUrl?: string;
145
- /**
146
- * Bearer token forwarded to the gateway. Defaults to `RYU_GATEWAY_TOKEN`.
147
- * This is the gateway token, never a provider API key.
148
- */
149
- token?: string;
150
- }
151
- /**
152
- * A gateway-mandatory model client backed by the Rust core.
153
- *
154
- * All calls go through the native `ModelClient`; if the configured base URL is a
155
- * direct provider, construction throws.
156
- */
157
- declare class ModelClient {
158
- readonly model: string;
159
- readonly baseUrl: string;
160
- private readonly native;
161
- constructor(model: string, options?: ModelClientOptions);
162
- /** Send a non-streaming chat completion request to the gateway. */
163
- chat(messages: ChatMessage[]): Promise<ChatResult>;
164
- /** Send a streaming chat completion request, yielding deltas as they arrive. */
165
- stream(messages: ChatMessage[]): AsyncGenerator<ChatDelta>;
166
- }
167
- /**
168
- * Create a gateway-mandatory model client for `modelId`.
169
- *
170
- * const model = defineModel("gpt-4o");
171
- * const model = defineModel("claude-3-5-sonnet", { baseUrl: "http://my-gateway:7981" });
172
- *
173
- * A direct provider URL throws immediately (egress enforcement in the Rust core).
174
- */
175
- declare function defineModel(modelId: string, options?: ModelClientOptions): ModelClient;
2
+ import { a as ChatMessage, b as ChatResult, C as ChatDelta } from './client-D5U6ssPc.cjs';
176
3
 
177
4
  /**
178
5
  * Composable primitive-client surface for the Ryu SDK runtime context.
@@ -420,6 +247,67 @@ interface EnginesClient {
420
247
  model?: string;
421
248
  }): Promise<number[][]>;
422
249
  }
250
+ /** One process visible through the shared Core background registry. */
251
+ interface BackgroundProcess {
252
+ command: string;
253
+ cwd: string;
254
+ description?: string | null;
255
+ elapsed_ms: number;
256
+ exit_code?: number | null;
257
+ exit_signal?: string | null;
258
+ kind: string;
259
+ label?: string | null;
260
+ pid?: number | null;
261
+ process_id: string;
262
+ producer: string;
263
+ running: boolean;
264
+ shell_id?: string | null;
265
+ started_at: number;
266
+ }
267
+ /** Background-process registry and cooperative stop requests. */
268
+ interface BackgroundClient {
269
+ list(input?: {
270
+ producer?: string;
271
+ runningOnly?: boolean;
272
+ }): Promise<BackgroundProcess[]>;
273
+ stop(input: {
274
+ processId: string;
275
+ }): Promise<{
276
+ ok: boolean;
277
+ requested: boolean;
278
+ process_id: string;
279
+ }>;
280
+ }
281
+ /** Durable app-owned key/value state (`storage:kv` via the host bridge). */
282
+ interface StorageClient {
283
+ /** Atomically replace a value when it still equals `expected`. */
284
+ compareAndSet(input: {
285
+ expected: string | null;
286
+ key: string;
287
+ namespace?: string;
288
+ value: string | null;
289
+ }): Promise<boolean>;
290
+ /** Delete one value. */
291
+ delete(input: {
292
+ key: string;
293
+ namespace?: string;
294
+ }): Promise<void>;
295
+ /** Read one value; missing keys return `null`. */
296
+ get(input: {
297
+ key: string;
298
+ namespace?: string;
299
+ }): Promise<string | null>;
300
+ /** List keys in an app-owned namespace. */
301
+ keys(input?: {
302
+ namespace?: string;
303
+ }): Promise<string[]>;
304
+ /** Write one string value. JSON can be encoded by the app when needed. */
305
+ set(input: {
306
+ key: string;
307
+ namespace?: string;
308
+ value: string;
309
+ }): Promise<void>;
310
+ }
423
311
  /** TTS primitive — speech synthesis (`crates/ryu-tts`). */
424
312
  interface TtsClient {
425
313
  /**
@@ -465,12 +353,14 @@ interface ImageClient {
465
353
  * Core node) — the same "what runs vs what is allowed" split as `ctx.gateway`.
466
354
  */
467
355
  interface RyuPrimitives {
356
+ background: BackgroundClient;
468
357
  durable: DurableClient;
469
358
  engines: EnginesClient;
470
359
  image: ImageClient;
471
360
  memory: MemoryClient;
472
361
  rag: RagClient;
473
362
  realtime: RealtimeClient;
363
+ storage: StorageClient;
474
364
  stt: SttClient;
475
365
  tts: TtsClient;
476
366
  }
@@ -534,6 +424,8 @@ interface RunnableContext {
534
424
  sessionId?: string;
535
425
  /** Signal to abort a long-running run. */
536
426
  signal?: AbortSignal;
427
+ /** Durable app-owned KV state, gated by the manifest's `storage:kv` grant. */
428
+ storage?: StorageClient;
537
429
  /** STT primitive: transcribe (`crates/ryu-stt`). */
538
430
  stt?: SttClient;
539
431
  /** TTS primitive: speak (`crates/ryu-tts`). */
@@ -613,9 +505,13 @@ interface ToolSchema {
613
505
  required?: string[];
614
506
  /** Type is always "object" for a tool's top-level input schema. */
615
507
  type: "object";
508
+ /** Preserve additional JSON Schema keywords for Core/MCP consumers. */
509
+ [key: string]: unknown;
616
510
  }
617
511
  /** Options accepted by `defineTool`. */
618
512
  interface ToolOptions<TInput extends Record<string, unknown>, TOutput> {
513
+ /** Optional description surfaced to models and tool discovery. */
514
+ description?: string;
619
515
  /** Stable unique identifier (e.g. "tool-web-search"). */
620
516
  id: string;
621
517
  /** Human-readable display name. */
@@ -655,6 +551,8 @@ interface ToolRunnable<TInput extends Record<string, unknown> = Record<string, u
655
551
  * the sandbox form is the second parameter aliased to `host`.
656
552
  */
657
553
  readonly code: string;
554
+ /** Optional description surfaced to models and tool discovery. */
555
+ readonly description?: string;
658
556
  readonly kind: "tool";
659
557
  /** JSON Schema for this tool's input — compatible with Core's ToolInfo.schema. */
660
558
  readonly schema: ToolSchema;
@@ -689,300 +587,29 @@ interface ToolRunnable<TInput extends Record<string, unknown> = Record<string, u
689
587
  * ```
690
588
  */
691
589
  declare function defineTool<TInput extends Record<string, unknown> = Record<string, unknown>, TOutput = unknown>(options: ToolOptions<TInput, TOutput>): ToolRunnable<TInput, TOutput>;
590
+ /** Optional metadata lowered alongside a tool's executable backend. */
591
+ interface InlineToolManifestOptions {
592
+ /** Marks the entry as a semantic Ryu Action. */
593
+ action?: boolean;
594
+ /** MCP-style effect annotations, for example `readOnlyHint`. */
595
+ annotations?: Record<string, boolean | undefined>;
596
+ /** Description shown in Core's unified tool catalog. */
597
+ description?: string;
598
+ /** Force the human approval gate before the tool runs. */
599
+ needsApproval?: boolean;
600
+ /** JSON Schema for the structured result. */
601
+ outputSchema?: Record<string, unknown>;
602
+ }
692
603
  /**
693
604
  * Convert a {@link ToolRunnable} into a `manifest.json` `kind:"tool"` runnable that
694
605
  * ships its `run` body as Core's `inline_deno` backend. The emitted config
695
606
  * mirrors Core's `ToolConfig` (`apps/core/src/plugin_manifest/schema.rs`):
696
607
  * `{ slug, backend:"inline_deno", code, description?, input_schema }`. Core
697
- * registers it as `app__<slug>` — discoverable via `/api/tools/search` and
608
+ * registers it as `app.<slug>` — discoverable via `/api/tools/search` and
698
609
  * executed in the grant-gated sandbox.
699
610
  *
700
611
  * The plugin must declare the `tool:execute` grant (see `definePlugin`).
701
612
  */
702
- declare function inlineToolRunnable(tool: ToolRunnable, options?: {
703
- description?: string;
704
- }): RunnableMeta;
705
-
706
- /**
707
- * Tool resolution + execution for the Ryu agent runtime.
708
- *
709
- * Two kinds of tool feed the same model `tools[]` array:
710
- *
711
- * - **Local** tools are `ToolRunnable`s from `defineTool` — they run in-process
712
- * via their `run(input, ctx)` implementation.
713
- * - **Remote** tools are references to existing Ryu tools (e.g.
714
- * `composio__GMAIL_SEARCH_EMAILS`) created with `ryuTool(id)`. Their schema is
715
- * lazily fetched from Core `GET /api/tools/describe` and they execute through
716
- * Core `POST /api/mcp/tools/call`, which enforces the agent's allowlist and
717
- * selects the Composio connected-account entity via `user_id`.
718
- *
719
- * The model-facing function name is the **config key** the developer chose (e.g.
720
- * `gmailSearch`), not the raw Composio slug — internals stay hidden and names
721
- * stay OpenAI-safe.
722
- */
723
-
724
- /** A reference to an existing Ryu tool, resolved + executed via Core. */
725
- interface RemoteToolRef {
726
- /** One-line description shown to the model (overrides Core's describe). */
727
- description?: string;
728
- /** Fully-qualified Ryu tool id, e.g. `composio__GMAIL_SEARCH_EMAILS`. */
729
- id: string;
730
- readonly kind: "remote";
731
- /**
732
- * JSON Schema for the tool's arguments. Optional: when omitted, a permissive
733
- * open-object schema is used (Composio `describe` is shallow), so supplying
734
- * this materially improves the model's tool-call accuracy.
735
- */
736
- parameters?: Record<string, unknown>;
737
- }
738
- /** Options accepted by `ryuTool`. */
739
- interface RyuToolOptions {
740
- description?: string;
741
- parameters?: Record<string, unknown>;
742
- }
743
- /**
744
- * Reference an existing Ryu tool by id so an `Agent` can call it.
745
- *
746
- * @example
747
- * ```ts
748
- * ryuTool("composio__GMAIL_SEARCH_EMAILS", {
749
- * description: "Search the user's Gmail",
750
- * parameters: { type: "object", properties: { query: { type: "string" } }, required: ["query"] },
751
- * });
752
- * ```
753
- */
754
- declare function ryuTool(id: string, opts?: RyuToolOptions): RemoteToolRef;
755
- /** A tool an `Agent` can expose to the model: local runnable or remote ref. */
756
- type AgentTool = RemoteToolRef | ToolRunnable;
757
- /** Everything the tool layer needs to resolve schemas + execute calls. */
758
- interface ToolExecContext {
759
- /** Core agent id — REQUIRED for remote tools (governs execution). */
760
- agentId?: string;
761
- /** Core base URL (no trailing `/api`). */
762
- coreBaseUrl: string;
763
- /** Bearer token for Core (`RYU_TOKEN`); may be undefined on loopback dev. */
764
- coreToken?: string;
765
- /** RunnableContext handed to local tools so they may call the gateway. */
766
- runnableContext: RunnableContext;
767
- /** Abort signal. */
768
- signal?: AbortSignal;
769
- /** Composio connected-account entity selector. */
770
- userId?: string;
771
- }
772
- /**
773
- * Build the OpenAI `tools[]` array the model sees, keyed by the developer's
774
- * config names. Remote tools without an explicit `parameters` schema are
775
- * described from Core (`describe` is shallow) and given a permissive schema.
776
- */
777
- declare function resolveToolDefs(tools: Record<string, AgentTool>, ctx: ToolExecContext): Promise<ToolFunctionDef[]>;
778
- /** Result of executing one tool call. */
779
- interface ToolExecResult {
780
- /** Raw tool output (already JSON-parsed when the tool returned JSON). */
781
- output: unknown;
782
- }
783
- /**
784
- * Execute a single model tool call by config `name`, dispatching to the local
785
- * runnable or the Core `/api/mcp/tools/call` endpoint.
786
- *
787
- * `argsJson` is the raw JSON string from `tool_call.function.arguments`.
788
- */
789
- declare function executeTool(name: string, argsJson: string, tools: Record<string, AgentTool>, ctx: ToolExecContext): Promise<ToolExecResult>;
790
- /** The connect-required envelope Core returns when an account isn't linked. */
791
- interface Elicitation {
792
- kind?: string;
793
- message?: string;
794
- url?: string;
795
- }
796
- /**
797
- * Detect Ryu's connection-required envelope in a tool output. Mirrors Core's
798
- * `detect_elicitation` (apps/core/src/sidecar/mcp/composio.rs): the first Gmail
799
- * call for an unconnected account returns `{ "__ryu_elicitation__": { url } }`.
800
- */
801
- declare function detectElicitation(output: unknown): Elicitation | null;
802
-
803
- /**
804
- * The autonomous agent loop for the Ryu SDK runtime.
805
- *
806
- * This is what `defineAgent` never had: a real multi-turn tool-calling loop that
807
- * runs in TypeScript. Each round calls the node's gateway with the resolved
808
- * tool definitions; if the model emits `tool_calls`, each is executed (local
809
- * runnable or Core `/api/mcp/tools/call`), results are fed back, and the loop
810
- * repeats until the model stops calling tools or `maxSteps` is reached.
811
- *
812
- * Emitted events mirror Core's `AcpEvent` categories (see cli/dev.ts) plus an
813
- * `auth_required` pause — when a remote tool returns Ryu's connection-required
814
- * envelope (first-run Gmail OAuth), the loop surfaces the connect URL and stops
815
- * instead of feeding the envelope back as a normal tool result.
816
- */
817
-
818
- /** A streamed text fragment from the assistant. */
819
- interface AgentEventText {
820
- content: string;
821
- type: "text";
822
- }
823
- /** The model initiated a tool call. */
824
- interface AgentEventToolCall {
825
- id: string;
826
- input: unknown;
827
- name: string;
828
- type: "tool_call";
829
- }
830
- /** A tool finished (or failed with an error output the model can recover from). */
831
- interface AgentEventToolResult {
832
- id: string;
833
- name: string;
834
- output: unknown;
835
- type: "tool_result";
836
- }
837
- /** A remote tool needs an account connection — the loop paused. */
838
- interface AgentEventAuthRequired {
839
- message?: string;
840
- tool: string;
841
- type: "auth_required";
842
- url?: string;
843
- }
844
- /** A fatal loop error — the stream ends after this. */
845
- interface AgentEventError {
846
- message: string;
847
- type: "error";
848
- }
849
- /** Terminal event carrying the final text, step count, and aggregate usage. */
850
- interface AgentEventResult {
851
- steps: number;
852
- text: string;
853
- type: "result";
854
- usage?: ModelUsage;
855
- }
856
- /** Union of everything the loop yields. */
857
- type AgentEvent = AgentEventAuthRequired | AgentEventError | AgentEventResult | AgentEventText | AgentEventToolCall | AgentEventToolResult;
858
- /** Inputs for a single loop run. */
859
- interface LoopConfig {
860
- /** Gateway base URL for inference (the target node). */
861
- gatewayBaseUrl: string;
862
- /** Gateway bearer token. */
863
- gatewayToken?: string;
864
- /** Hard ceiling on model→tool rounds. */
865
- maxSteps: number;
866
- /** Seed transcript (system + user messages already assembled). */
867
- messages: LoopMessage[];
868
- /** Model id routed by the gateway. */
869
- model: string;
870
- /** Abort signal. */
871
- signal?: AbortSignal;
872
- /** Context for resolving + executing tools. */
873
- toolCtx: ToolExecContext;
874
- /** Tools keyed by model-facing name. */
875
- tools: Record<string, AgentTool>;
876
- }
877
- /**
878
- * Run the autonomous loop, yielding events as they occur. The generator returns
879
- * after a terminal `result`, `auth_required`, or `error` event.
880
- */
881
- declare function runAgentLoop(config: LoopConfig): AsyncGenerator<AgentEvent>;
882
-
883
- /**
884
- * `Agent` — the declarative agent runtime for `@ryu/sdk`.
885
- *
886
- * Unlike `defineAgent` (a declaration wrapper whose `run()` you write by hand),
887
- * `Agent` OWNS the loop: give it instructions, a model, a target node, and a
888
- * set of tools, then call `generate()` / `stream()`. Inference is pointed at the
889
- * node's gateway; tool calls resolve to local `defineTool` runnables or existing
890
- * Ryu tools (`ryuTool`) executed through Core.
891
- *
892
- * Mirrors Mastra's config-object + `.generate()`/`.stream()` shape; `query()`
893
- * (see query.ts) wraps the same runtime in a Claude-Agent-SDK-style streaming
894
- * call.
895
- */
896
-
897
- /** A target node for inference / tool execution: a base URL + optional token. */
898
- interface Endpoint {
899
- baseUrl?: string;
900
- token?: string;
901
- }
902
- /** Declarative configuration for an `Agent`. */
903
- interface AgentConfig {
904
- /** Core agent id — REQUIRED when using `ryuTool` remote tools (governance). */
905
- agentId?: string;
906
- /** Core endpoint for tool discovery/execution. Defaults to env/localhost. */
907
- core?: Endpoint;
908
- /** System prompt / persona. */
909
- instructions?: string;
910
- /** Hard ceiling on model→tool rounds (default 10). */
911
- maxSteps?: number;
912
- /** Model id routed by the node's gateway. */
913
- model: string;
914
- /** Display name. */
915
- name: string;
916
- /** Target node for inference. Defaults to the local gateway. */
917
- node?: Endpoint;
918
- /**
919
- * Reverse-domain plugin id. When set, the composable primitive surface
920
- * (`ctx.rag`, `ctx.memory`, `ctx.engines`, …) is mounted on the run context,
921
- * routed through this node via the governed host bridge / capability broker.
922
- * Omitted = no primitives mounted (the bridge families authenticate a plugin
923
- * id, so a half-wired transport is never attached).
924
- */
925
- pluginId?: string;
926
- /** Tools keyed by the model-facing name. */
927
- tools?: Record<string, AgentTool>;
928
- /** Composio connected-account entity selector. */
929
- userId?: string;
930
- }
931
- /** Result of a non-streaming `generate()`. */
932
- interface GenerateResult {
933
- /** Present when the run paused for an account connection. */
934
- authRequired?: AgentEventAuthRequired;
935
- /** Number of model→tool rounds taken. */
936
- steps: number;
937
- /** Final assistant text. */
938
- text: string;
939
- /** Aggregate token usage across all rounds (when reported). */
940
- usage?: ModelUsage;
941
- }
942
- /** A declarative, loop-owning agent. */
943
- declare class Agent {
944
- readonly config: AgentConfig;
945
- constructor(config: AgentConfig);
946
- /** Assemble the loop config for a given prompt. */
947
- private buildLoopConfig;
948
- /** Stream loop events (text / tool_call / tool_result / auth_required / …). */
949
- stream(prompt: string, signal?: AbortSignal): AsyncGenerator<AgentEvent>;
950
- /** Run to completion and return the final text, step count, and usage. */
951
- generate(prompt: string, signal?: AbortSignal): Promise<GenerateResult>;
952
- }
953
- /** Factory alias for `new Agent(config)`. */
954
- declare function createAgent(config: AgentConfig): Agent;
955
-
956
- /**
957
- * `query()` — Claude-Agent-SDK-style streaming entry over the same `Agent`.
958
- *
959
- * Where `Agent` gives you Mastra's config-object + method shape, `query()` gives
960
- * you the `for await (const msg of query({ prompt, options }))` ergonomics of
961
- * the Claude Agent SDK. Both drive the identical loop; this is a thin wrapper.
962
- */
963
-
964
- /** Options accepted by `query` — an `AgentConfig` with an optional `name`. */
965
- type QueryOptions = Omit<AgentConfig, "name"> & {
966
- name?: string;
967
- };
968
- /** Input to `query`: a prompt plus agent options. */
969
- interface QueryInput {
970
- options: QueryOptions;
971
- prompt: string;
972
- }
973
- /**
974
- * Run an agent for a single prompt and stream its events.
975
- *
976
- * @example
977
- * ```ts
978
- * for await (const msg of query({
979
- * prompt: "Find my expenses from last month.",
980
- * options: { model: "gpt-4o", agentId: "agent-expense", tools: { gmailSearch } },
981
- * })) {
982
- * if (msg.type === "result") console.log(msg.text);
983
- * }
984
- * ```
985
- */
986
- declare function query(input: QueryInput): AsyncGenerator<AgentEvent>;
613
+ declare function inlineToolRunnable(tool: Pick<ToolRunnable, "code" | "description" | "id" | "name" | "schema">, options?: InlineToolManifestOptions): RunnableMeta;
987
614
 
988
- export { type Elicitation as $, Agent as A, defineModel as B, type ChatDelta as C, type DurableClient as D, type Endpoint as E, defineTool as F, type GatewayClient as G, type HttpPrimitiveTransportOptions as H, type ImageClient as I, type JsonSchemaProperty as J, httpPrimitiveTransport as K, inlineToolRunnable as L, type MemoryClient as M, query as N, ryuTool as O, PRIMITIVE_BINDINGS as P, type QueryInput as Q, type Runnable as R, type SttClient as S, type ToolRunnable as T, type AgentEventAuthRequired as U, type AgentEventError as V, type AgentEventResult as W, type AgentEventText as X, type AgentEventToolCall as Y, type AgentEventToolResult as Z, type AssistantMessage as _, type RunnableContext as a, type LoopConfig as a0, type LoopMessage as a1, type ModelCallOptions as a2, type ModelCallResult as a3, type ModelUsage as a4, type RyuToolOptions as a5, type ToolCall as a6, type ToolExecContext as a7, type ToolExecResult as a8, type ToolFunctionDef as a9, callModelWithTools as aa, detectElicitation as ab, executeTool as ac, resolveToolDefs as ad, runAgentLoop as ae, type AgentConfig as b, type AgentEvent as c, type AgentTool as d, type ChatMessage as e, type ChatResult as f, type EnginesClient as g, type GenerateResult as h, type MemoryItem as i, ModelClient as j, type ModelClientOptions as k, type PrimitiveBinding as l, type PrimitiveTransport as m, type QueryOptions as n, type RagChunk as o, type RagClient as p, type RagRerankResult as q, type RealtimeClient as r, type RealtimeSubscription as s, type RemoteToolRef as t, type RyuPrimitives as u, type ToolOptions as v, type ToolSchema as w, type TtsClient as x, createAgent as y, createPrimitives as z };
615
+ export { type BackgroundClient as B, type DurableClient as D, type EnginesClient as E, type GatewayClient as G, type HttpPrimitiveTransportOptions as H, type ImageClient as I, type JsonSchemaProperty as J, type MemoryClient as M, PRIMITIVE_BINDINGS as P, type RagChunk as R, type StorageClient as S, type ToolRunnable as T, type BackgroundProcess as a, type InlineToolManifestOptions as b, type MemoryItem as c, type PrimitiveBinding as d, type PrimitiveTransport as e, type RagClient as f, type RagRerankResult as g, type RealtimeClient as h, type RealtimeSubscription as i, type Runnable as j, type RunnableContext as k, type RyuPrimitives as l, type SttClient as m, type ToolOptions as n, type ToolSchema as o, type TtsClient as p, createPrimitives as q, defineTool as r, httpPrimitiveTransport as s, inlineToolRunnable as t };
package/package.json CHANGED
@@ -1,8 +1,12 @@
1
1
  {
2
2
  "name": "@ryuhq/sdk",
3
- "version": "0.1.14",
3
+ "version": "0.2.2",
4
4
  "type": "module",
5
5
  "description": "Ryu developer SDK: typed builders and CLI for authoring manifest.json Plugin bundles",
6
+ "repository": {
7
+ "type": "git",
8
+ "url": "https://github.com/amajorai/ryu"
9
+ },
6
10
  "main": "./dist/index.cjs",
7
11
  "types": "./dist/index.d.ts",
8
12
  "exports": {
@@ -26,6 +30,46 @@
26
30
  "import": "./dist/agent.js",
27
31
  "require": "./dist/agent.cjs"
28
32
  },
33
+ "./action": {
34
+ "types": "./dist/action.d.ts",
35
+ "import": "./dist/action.js",
36
+ "require": "./dist/action.cjs"
37
+ },
38
+ "./model": {
39
+ "types": "./dist/model.d.ts",
40
+ "import": "./dist/model.js",
41
+ "require": "./dist/model.cjs"
42
+ },
43
+ "./mcp": {
44
+ "types": "./dist/mcp.d.ts",
45
+ "import": "./dist/mcp.js",
46
+ "require": "./dist/mcp.cjs"
47
+ },
48
+ "./mcp/server": {
49
+ "types": "./dist/mcp/server.d.ts",
50
+ "import": "./dist/mcp/server.js",
51
+ "require": "./dist/mcp/server.cjs"
52
+ },
53
+ "./mcp/client": {
54
+ "types": "./dist/mcp/client.d.ts",
55
+ "import": "./dist/mcp/client.js",
56
+ "require": "./dist/mcp/client.cjs"
57
+ },
58
+ "./plugin": {
59
+ "types": "./dist/plugin.d.ts",
60
+ "import": "./dist/plugin.js",
61
+ "require": "./dist/plugin.cjs"
62
+ },
63
+ "./runnable": {
64
+ "types": "./dist/runnable.d.ts",
65
+ "import": "./dist/runnable.js",
66
+ "require": "./dist/runnable.cjs"
67
+ },
68
+ "./builder": {
69
+ "types": "./dist/builder.d.ts",
70
+ "import": "./dist/builder.js",
71
+ "require": "./dist/builder.cjs"
72
+ },
29
73
  "./cli": {
30
74
  "import": "./dist/cli.js"
31
75
  }
@@ -49,11 +93,12 @@
49
93
  "clean": "rm -rf dist"
50
94
  },
51
95
  "dependencies": {
52
- "@ryuhq/sdk-native": "0.1.14",
96
+ "@ryuhq/sdk-native": "workspace:*",
53
97
  "zod": "^4.1.13"
54
98
  },
55
99
  "devDependencies": {
56
- "@types/bun": "^1.3.4",
100
+ "@types/bun": "catalog:",
101
+ "@types/node": "^22.20.1",
57
102
  "json-schema-to-typescript": "^15.0.4",
58
103
  "tsup": "^8.5.1",
59
104
  "typescript": "^5"