@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
package/dist/cli.js CHANGED
@@ -1,17 +1,19 @@
1
1
  #!/usr/bin/env bun
2
- import {
3
- PluginManifestSchema
4
- } from "./chunk-AO2KJRDD.js";
5
2
  import {
6
3
  AGENT_PLUGIN_MANIFEST_FILE,
7
4
  AGENT_PLUGIN_MCP_FILE,
8
5
  isAgentPluginManifest,
9
6
  toAgentPlugin
10
- } from "./chunk-G6FLVEC4.js";
7
+ } from "./chunk-JX6DDRXV.js";
8
+ import {
9
+ PluginManifestSchema
10
+ } from "./chunk-NZKVOSC2.js";
11
+ import {
12
+ ModelClient
13
+ } from "./chunk-HACAGK65.js";
11
14
  import {
12
- ModelClient,
13
15
  resolveGatewayUrl
14
- } from "./chunk-ODFEUVPW.js";
16
+ } from "./chunk-IKEDLLFY.js";
15
17
 
16
18
  // src/cli.ts
17
19
  import { createHash } from "crypto";
@@ -19,17 +21,19 @@ import {
19
21
  existsSync,
20
22
  mkdirSync,
21
23
  readFileSync,
24
+ realpathSync,
22
25
  rmSync,
23
- writeFileSync
26
+ writeFileSync,
27
+ writeSync
24
28
  } from "fs";
25
- import { join, resolve } from "path";
29
+ import { isAbsolute, join, relative, resolve, sep } from "path";
26
30
 
27
31
  // src/cli/dev.ts
28
32
  import { createInterface } from "readline";
29
33
  var RE_ABSOLUTE_PATH = /^[A-Za-z]:[\\/]/;
30
- async function probeGateway(baseUrl) {
34
+ async function probeGateway(baseUrl, fetchImpl = fetch) {
31
35
  try {
32
- await fetch(`${baseUrl}/health`, {
36
+ await fetchImpl(`${baseUrl}/health`, {
33
37
  method: "HEAD",
34
38
  signal: AbortSignal.timeout(3e3)
35
39
  });
@@ -228,7 +232,9 @@ function printUsage() {
228
232
  "",
229
233
  "Usage:",
230
234
  " bunx ryu pack <dir> Validate and bundle a manifest.json Plugin",
231
- " bunx ryu publish <dir> Validate and publish a manifest.json Plugin to the Ryu Marketplace",
235
+ " bunx ryu github-publish <url>",
236
+ " Submit a GitHub repository/package URL to the Marketplace",
237
+ " bunx ryu publish <dir> Deprecated server-artifact publishing (migration only)",
232
238
  " bunx ryu dev <entry> Run a Runnable locally with an interactive chat loop",
233
239
  " bunx ryu agent-plugin <dir>",
234
240
  " Emit the Agent Plugins v1 interop pair (plugin.json + mcp.json)",
@@ -237,7 +243,7 @@ function printUsage() {
237
243
  );
238
244
  }
239
245
  function exitError(message) {
240
- process.stderr.write(`error: ${message}
246
+ writeSync(process.stderr.fd, `error: ${message}
241
247
  `);
242
248
  process.exit(1);
243
249
  }
@@ -247,16 +253,20 @@ var MANIFEST_FILE_NAMES = [
247
253
  "ryu.json"
248
254
  ];
249
255
  function resolveNativeManifestPath(dir) {
250
- return MANIFEST_FILE_NAMES.map((name) => join(dir, name)).find((candidate) => {
251
- if (!existsSync(candidate)) {
252
- return false;
253
- }
254
- try {
255
- return !isAgentPluginManifest(JSON.parse(readFileSync(candidate, "utf8")));
256
- } catch {
257
- return true;
256
+ return MANIFEST_FILE_NAMES.map((name) => join(dir, name)).find(
257
+ (candidate) => {
258
+ if (!existsSync(candidate)) {
259
+ return false;
260
+ }
261
+ try {
262
+ return !isAgentPluginManifest(
263
+ JSON.parse(readFileSync(candidate, "utf8"))
264
+ );
265
+ } catch {
266
+ return true;
267
+ }
258
268
  }
259
- });
269
+ );
260
270
  }
261
271
  function loadManifest(dir) {
262
272
  const manifestPath = resolveNativeManifestPath(dir);
@@ -286,13 +296,30 @@ function loadManifest(dir) {
286
296
  }
287
297
  var CODE_FILE_DIRS = ["hooks", "adapters"];
288
298
  var CODE_FILE_PATH = /^(hooks|adapters)\/[A-Za-z0-9_][A-Za-z0-9._-]*\.m?js$/;
299
+ function containedPackageFile(dir, rel, label) {
300
+ let realRoot;
301
+ let realTarget;
302
+ try {
303
+ realRoot = realpathSync(dir);
304
+ realTarget = realpathSync(join(dir, rel));
305
+ } catch (error) {
306
+ exitError(`${label}: could not resolve '${rel}': ${String(error)}`);
307
+ }
308
+ const fromRoot = relative(realRoot, realTarget);
309
+ if (fromRoot === ".." || fromRoot.startsWith(`..${sep}`) || isAbsolute(fromRoot)) {
310
+ exitError(
311
+ `${label}: '${rel}' resolves outside the plugin package (${realTarget})`
312
+ );
313
+ }
314
+ return realTarget;
315
+ }
289
316
  function readCodeFile(dir, rel, label) {
290
317
  if (!CODE_FILE_PATH.test(rel)) {
291
318
  exitError(
292
319
  `${label}: code_file '${rel}' must be exactly '<${CODE_FILE_DIRS.join("|")}>/<name>.js' with no traversal`
293
320
  );
294
321
  }
295
- const path = join(dir, rel);
322
+ const path = containedPackageFile(dir, rel, label);
296
323
  let body;
297
324
  try {
298
325
  body = readFileSync(path, "utf8");
@@ -342,7 +369,7 @@ function inlineOutputStyleFiles(manifest, dir) {
342
369
  }
343
370
  let body;
344
371
  try {
345
- body = readFileSync(join(dir, rel), "utf8");
372
+ body = readFileSync(containedPackageFile(dir, rel, label), "utf8");
346
373
  } catch (err) {
347
374
  exitError(`${label}: could not read file '${rel}': ${String(err)}`);
348
375
  }
@@ -388,6 +415,12 @@ function resolveUiFormat(manifest) {
388
415
  return "html";
389
416
  }
390
417
  }
418
+ for (const widget of manifest.contributes?.widgets ?? []) {
419
+ const entry = widget.ui_entry;
420
+ if (typeof entry === "string" && entry.trim().toLowerCase().endsWith(".html")) {
421
+ return "html";
422
+ }
423
+ }
391
424
  return "js";
392
425
  }
393
426
  function readUiEntryHtml(dir, uiEntry) {
@@ -519,8 +552,16 @@ async function commandPublish(rawDir) {
519
552
  ...manifest.description ? { description: manifest.description } : {},
520
553
  ...manifest.tagline ? { tagline: manifest.tagline } : {},
521
554
  ...developer ? { developer } : {},
555
+ ...manifest.author ? { author: manifest.author } : {},
556
+ ...manifest.repository ? { repository: manifest.repository } : {},
557
+ ...manifest.external ? { external: true } : {},
522
558
  ...manifest.category ? { category: manifest.category } : {},
559
+ ...manifest.license ? { license: manifest.license } : {},
560
+ ...manifest.keywords?.length ? { keywords: manifest.keywords } : {},
523
561
  ...manifest.iconUrl ? { iconUrl: manifest.iconUrl } : {},
562
+ ...manifest.icon ? { icon: manifest.icon } : {},
563
+ ...manifest.iconDither ? { iconDither: manifest.iconDither } : {},
564
+ ...manifest.banner ? { banner: manifest.banner } : {},
524
565
  ...manifest.screenshots?.length ? { screenshots: manifest.screenshots } : {},
525
566
  ...manifest.homepage ? { website: manifest.homepage } : {},
526
567
  ...manifest.privacyPolicyUrl ? { privacyPolicyUrl: manifest.privacyPolicyUrl } : {},
@@ -576,6 +617,55 @@ ${text}
576
617
  `
577
618
  );
578
619
  }
620
+ async function commandGithubPublish(repositoryUrl) {
621
+ const input = repositoryUrl.trim();
622
+ if (!input) {
623
+ exitError(
624
+ "github-publish requires a GitHub repository or package URL, for example https://github.com/acme/my-app"
625
+ );
626
+ }
627
+ const token = authToken();
628
+ const url = `${publishBaseUrl()}/api/marketplace/github/publish`;
629
+ const proof = process.env.RYU_GITHUB_INSTALLATION_PROOF?.trim();
630
+ const body = {
631
+ url: input,
632
+ ...proof ? { installationProof: proof } : {}
633
+ };
634
+ let response;
635
+ try {
636
+ response = await fetch(url, {
637
+ method: "POST",
638
+ headers: {
639
+ authorization: `Bearer ${token}`,
640
+ "content-type": "application/json"
641
+ },
642
+ body: JSON.stringify(body)
643
+ });
644
+ } catch (error) {
645
+ exitError(`could not reach ${url}: ${String(error)}`);
646
+ }
647
+ const text = await response.text();
648
+ if (!response.ok) {
649
+ try {
650
+ const error = JSON.parse(text);
651
+ if (error.installationUrl) {
652
+ exitError(
653
+ `${error.error ?? "GitHub App installation required"}. Open ${error.installationUrl}, then set RYU_GITHUB_INSTALLATION_PROOF to the callback proof and retry.`
654
+ );
655
+ }
656
+ exitError(
657
+ `github-publish failed (${response.status}): ${error.error ?? text}`
658
+ );
659
+ } catch {
660
+ exitError(`github-publish failed (${response.status}): ${text}`);
661
+ }
662
+ }
663
+ process.stdout.write(
664
+ `GitHub-backed listing submitted for moderation:
665
+ ${text}
666
+ `
667
+ );
668
+ }
579
669
  var [, , command, ...args] = process.argv;
580
670
  if (!command) {
581
671
  printUsage();
@@ -594,9 +684,24 @@ if (command === "pack") {
594
684
  if (!dir) {
595
685
  exitError("publish requires a directory argument: bunx ryu publish <dir>");
596
686
  }
687
+ if (process.env.RYU_ENABLE_LEGACY_MARKETPLACE_WRITES !== "true") {
688
+ exitError(
689
+ "ryu publish is deprecated because marketplace package contents now live in GitHub Releases; use bunx ryu github-publish <repository-or-package-url>"
690
+ );
691
+ }
597
692
  commandPublish(dir).catch((err) => {
598
693
  exitError(String(err));
599
694
  });
695
+ } else if (command === "github-publish") {
696
+ const repositoryUrl = args[0];
697
+ if (!repositoryUrl) {
698
+ exitError(
699
+ "github-publish requires a GitHub repository or package URL, for example https://github.com/acme/my-app"
700
+ );
701
+ }
702
+ commandGithubPublish(repositoryUrl).catch((err) => {
703
+ exitError(String(err));
704
+ });
600
705
  } else if (command === "agent-plugin") {
601
706
  const dir = args[0];
602
707
  if (!dir) {
@@ -0,0 +1,84 @@
1
+ /**
2
+ * Gateway-mandatory model client for the Ryu SDK.
3
+ *
4
+ * Rust-cored: this is a thin TypeScript wrapper over the `@ryuhq/sdk-native`
5
+ * addon's `ModelClient`, which is the `crates/ryu-sdk` Rust core. Every model
6
+ * call is routed by the Rust core to the Ryu gateway's OpenAI-compatible
7
+ * `/v1/chat/completions` endpoint; direct-provider base URLs are rejected at
8
+ * construction. No provider SDK or base URL is ever imported here.
9
+ *
10
+ * Usage:
11
+ *
12
+ * const model = defineModel("gpt-4o");
13
+ * const reply = await model.chat([{ role: "user", content: "hello" }]);
14
+ * for await (const delta of model.stream([{ role: "user", content: "hi" }])) {
15
+ * process.stdout.write(delta.content);
16
+ * }
17
+ */
18
+ /** A single message in a chat conversation. */
19
+ interface ChatMessage {
20
+ /** The message text. */
21
+ content: string;
22
+ /** The speaker: "system", "user", or "assistant". */
23
+ role: "system" | "user" | "assistant";
24
+ }
25
+ /** A streaming chat completion delta. */
26
+ interface ChatDelta {
27
+ /** Incremental text fragment from the model. */
28
+ content: string | null;
29
+ /** Non-null on the final chunk when `finish_reason` is set. */
30
+ finishReason: string | null;
31
+ }
32
+ /** Non-streaming chat completion result. */
33
+ interface ChatResult {
34
+ /** The full assistant reply text. */
35
+ content: string;
36
+ /** The gateway/model-reported finish reason. */
37
+ finishReason: string | null;
38
+ /** Usage stats as reported by the gateway (optional — gateway may omit). */
39
+ usage?: {
40
+ promptTokens: number;
41
+ completionTokens: number;
42
+ totalTokens: number;
43
+ };
44
+ }
45
+ /** Options accepted by `defineModel`. */
46
+ interface ModelClientOptions {
47
+ /**
48
+ * Gateway base URL (no trailing `/v1`). Defaults to `RYU_GATEWAY_URL` then
49
+ * the Rust core's default. Direct provider URLs are rejected at construction.
50
+ */
51
+ baseUrl?: string;
52
+ /**
53
+ * Bearer token forwarded to the gateway. Defaults to `RYU_GATEWAY_TOKEN`.
54
+ * This is the gateway token, never a provider API key.
55
+ */
56
+ token?: string;
57
+ }
58
+ /**
59
+ * A gateway-mandatory model client backed by the Rust core.
60
+ *
61
+ * All calls go through the native `ModelClient`; if the configured base URL is a
62
+ * direct provider, construction throws.
63
+ */
64
+ declare class ModelClient {
65
+ readonly model: string;
66
+ readonly baseUrl: string;
67
+ private readonly native;
68
+ constructor(model: string, options?: ModelClientOptions);
69
+ /** Send a non-streaming chat completion request to the gateway. */
70
+ chat(messages: ChatMessage[]): Promise<ChatResult>;
71
+ /** Send a streaming chat completion request, yielding deltas as they arrive. */
72
+ stream(messages: ChatMessage[]): AsyncGenerator<ChatDelta>;
73
+ }
74
+ /**
75
+ * Create a gateway-mandatory model client for `modelId`.
76
+ *
77
+ * const model = defineModel("gpt-4o");
78
+ * const model = defineModel("claude-3-5-sonnet", { baseUrl: "http://my-gateway:7981" });
79
+ *
80
+ * A direct provider URL throws immediately (egress enforcement in the Rust core).
81
+ */
82
+ declare function defineModel(modelId: string, options?: ModelClientOptions): ModelClient;
83
+
84
+ export { type ChatDelta as C, ModelClient as M, type ChatMessage as a, type ChatResult as b, type ModelClientOptions as c, defineModel as d };
@@ -0,0 +1,84 @@
1
+ /**
2
+ * Gateway-mandatory model client for the Ryu SDK.
3
+ *
4
+ * Rust-cored: this is a thin TypeScript wrapper over the `@ryuhq/sdk-native`
5
+ * addon's `ModelClient`, which is the `crates/ryu-sdk` Rust core. Every model
6
+ * call is routed by the Rust core to the Ryu gateway's OpenAI-compatible
7
+ * `/v1/chat/completions` endpoint; direct-provider base URLs are rejected at
8
+ * construction. No provider SDK or base URL is ever imported here.
9
+ *
10
+ * Usage:
11
+ *
12
+ * const model = defineModel("gpt-4o");
13
+ * const reply = await model.chat([{ role: "user", content: "hello" }]);
14
+ * for await (const delta of model.stream([{ role: "user", content: "hi" }])) {
15
+ * process.stdout.write(delta.content);
16
+ * }
17
+ */
18
+ /** A single message in a chat conversation. */
19
+ interface ChatMessage {
20
+ /** The message text. */
21
+ content: string;
22
+ /** The speaker: "system", "user", or "assistant". */
23
+ role: "system" | "user" | "assistant";
24
+ }
25
+ /** A streaming chat completion delta. */
26
+ interface ChatDelta {
27
+ /** Incremental text fragment from the model. */
28
+ content: string | null;
29
+ /** Non-null on the final chunk when `finish_reason` is set. */
30
+ finishReason: string | null;
31
+ }
32
+ /** Non-streaming chat completion result. */
33
+ interface ChatResult {
34
+ /** The full assistant reply text. */
35
+ content: string;
36
+ /** The gateway/model-reported finish reason. */
37
+ finishReason: string | null;
38
+ /** Usage stats as reported by the gateway (optional — gateway may omit). */
39
+ usage?: {
40
+ promptTokens: number;
41
+ completionTokens: number;
42
+ totalTokens: number;
43
+ };
44
+ }
45
+ /** Options accepted by `defineModel`. */
46
+ interface ModelClientOptions {
47
+ /**
48
+ * Gateway base URL (no trailing `/v1`). Defaults to `RYU_GATEWAY_URL` then
49
+ * the Rust core's default. Direct provider URLs are rejected at construction.
50
+ */
51
+ baseUrl?: string;
52
+ /**
53
+ * Bearer token forwarded to the gateway. Defaults to `RYU_GATEWAY_TOKEN`.
54
+ * This is the gateway token, never a provider API key.
55
+ */
56
+ token?: string;
57
+ }
58
+ /**
59
+ * A gateway-mandatory model client backed by the Rust core.
60
+ *
61
+ * All calls go through the native `ModelClient`; if the configured base URL is a
62
+ * direct provider, construction throws.
63
+ */
64
+ declare class ModelClient {
65
+ readonly model: string;
66
+ readonly baseUrl: string;
67
+ private readonly native;
68
+ constructor(model: string, options?: ModelClientOptions);
69
+ /** Send a non-streaming chat completion request to the gateway. */
70
+ chat(messages: ChatMessage[]): Promise<ChatResult>;
71
+ /** Send a streaming chat completion request, yielding deltas as they arrive. */
72
+ stream(messages: ChatMessage[]): AsyncGenerator<ChatDelta>;
73
+ }
74
+ /**
75
+ * Create a gateway-mandatory model client for `modelId`.
76
+ *
77
+ * const model = defineModel("gpt-4o");
78
+ * const model = defineModel("claude-3-5-sonnet", { baseUrl: "http://my-gateway:7981" });
79
+ *
80
+ * A direct provider URL throws immediately (egress enforcement in the Rust core).
81
+ */
82
+ declare function defineModel(modelId: string, options?: ModelClientOptions): ModelClient;
83
+
84
+ export { type ChatDelta as C, ModelClient as M, type ChatMessage as a, type ChatResult as b, type ModelClientOptions as c, defineModel as d };