@inferencesh/ui 0.0.0-stage → 0.1.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (165) hide show
  1. package/LICENSE +22 -0
  2. package/README.md +68 -2
  3. package/components.json +22 -0
  4. package/package.json +231 -4
  5. package/src/components/audio-player.tsx +549 -0
  6. package/src/components/button.tsx +13 -0
  7. package/src/components/chart.tsx +403 -0
  8. package/src/components/circuit.tsx +276 -0
  9. package/src/components/code-block/code-block.tsx +260 -0
  10. package/src/components/code-block/index.ts +18 -0
  11. package/src/components/code-block/languages.ts +311 -0
  12. package/src/components/code-block/styles.ts +39 -0
  13. package/src/components/code-block/tokenizer.ts +290 -0
  14. package/src/components/code-block/types.ts +38 -0
  15. package/src/components/code-block/utils.ts +39 -0
  16. package/src/components/code.tsx +48 -0
  17. package/src/components/cookie-consent.tsx +137 -0
  18. package/src/components/copy-button.tsx +44 -0
  19. package/src/components/country-dropdown.tsx +188 -0
  20. package/src/components/glow-loader-fast.tsx +32 -0
  21. package/src/components/glow-loader-mono.tsx +33 -0
  22. package/src/components/glow-loader-sm-fast.tsx +32 -0
  23. package/src/components/glow-loader-sm-mono.tsx +34 -0
  24. package/src/components/glow-loader-sm.tsx +32 -0
  25. package/src/components/glow-loader.tsx +32 -0
  26. package/src/components/glow-logo.tsx +32 -0
  27. package/src/components/gradient.tsx +80 -0
  28. package/src/components/index.ts +45 -0
  29. package/src/components/inline-sidebar.tsx +351 -0
  30. package/src/components/input-color.tsx +349 -0
  31. package/src/components/logo-base.tsx +213 -0
  32. package/src/components/logo-color.tsx +23 -0
  33. package/src/components/logo-full.tsx +71 -0
  34. package/src/components/logo-svg.tsx +23 -0
  35. package/src/components/menu-navigation.tsx +359 -0
  36. package/src/components/multi-select.tsx +721 -0
  37. package/src/components/pastel-gradient.tsx +25 -0
  38. package/src/components/pixel-symmetry.tsx +151 -0
  39. package/src/components/progress.tsx +28 -0
  40. package/src/components/scroll-more.tsx +131 -0
  41. package/src/components/select.tsx +85 -0
  42. package/src/components/shimmering-text.tsx +108 -0
  43. package/src/components/sidebar-light.tsx +102 -0
  44. package/src/components/sonner.tsx +38 -0
  45. package/src/components/theme-switcher-sidebar.tsx +56 -0
  46. package/src/components/theme-switcher-simple.tsx +110 -0
  47. package/src/components/theme-switcher.tsx +47 -0
  48. package/src/components/toggle-group.tsx +55 -0
  49. package/src/components/tooltip-button.tsx +91 -0
  50. package/src/components/tooltip.tsx +71 -0
  51. package/src/components/tree-view.tsx +499 -0
  52. package/src/components/unglow-loader.tsx +33 -0
  53. package/src/components/waveform.tsx +1632 -0
  54. package/src/components/zoomable-image.tsx +76 -0
  55. package/src/docs/api-docs.tsx +763 -0
  56. package/src/docs/callout.tsx +160 -0
  57. package/src/docs/code-group.tsx +215 -0
  58. package/src/docs/copy-menu.tsx +143 -0
  59. package/src/docs/doc-tabs.tsx +84 -0
  60. package/src/docs/index.ts +16 -0
  61. package/src/docs/steps.tsx +105 -0
  62. package/src/docs/table-of-contents.tsx +174 -0
  63. package/src/examples/guide-markdown.ts +129 -0
  64. package/src/examples/index.ts +1153 -0
  65. package/src/global.d.ts +1 -0
  66. package/src/hooks/use-copy-to-clipboard.ts +36 -0
  67. package/src/hooks/use-mobile.ts +19 -0
  68. package/src/lib/display-name.ts +15 -0
  69. package/src/lib/example-input.ts +130 -0
  70. package/src/lib/plans.ts +44 -0
  71. package/src/lib/safe-content.ts +137 -0
  72. package/src/lib/schema.ts +320 -0
  73. package/src/lib/storage.ts +108 -0
  74. package/src/markdown/docs-markdown-renderer.tsx +518 -0
  75. package/src/markdown/helpers.ts +95 -0
  76. package/src/markdown/index.ts +24 -0
  77. package/src/markdown/markdown-renderer.tsx +232 -0
  78. package/src/markdown/youtube-embed.tsx +43 -0
  79. package/src/og/image.ts +312 -0
  80. package/src/og/index.tsx +430 -0
  81. package/src/og/query.ts +26 -0
  82. package/src/shadcn/accordion.tsx +71 -0
  83. package/src/shadcn/alert-dialog.tsx +187 -0
  84. package/src/shadcn/alert.tsx +75 -0
  85. package/src/shadcn/aspect-ratio.tsx +22 -0
  86. package/src/shadcn/attachment.tsx +207 -0
  87. package/src/shadcn/avatar.tsx +106 -0
  88. package/src/shadcn/badge.tsx +51 -0
  89. package/src/shadcn/breadcrumb.tsx +124 -0
  90. package/src/shadcn/bubble.tsx +127 -0
  91. package/src/shadcn/button-group.tsx +87 -0
  92. package/src/shadcn/button.tsx +57 -0
  93. package/src/shadcn/calendar.tsx +219 -0
  94. package/src/shadcn/card.tsx +102 -0
  95. package/src/shadcn/carousel.tsx +242 -0
  96. package/src/shadcn/chart.tsx +372 -0
  97. package/src/shadcn/checkbox.tsx +28 -0
  98. package/src/shadcn/collapsible.tsx +19 -0
  99. package/src/shadcn/combobox.tsx +297 -0
  100. package/src/shadcn/command.tsx +194 -0
  101. package/src/shadcn/context-menu.tsx +270 -0
  102. package/src/shadcn/dialog.tsx +158 -0
  103. package/src/shadcn/direction.tsx +4 -0
  104. package/src/shadcn/drawer.tsx +227 -0
  105. package/src/shadcn/dropdown-menu.tsx +265 -0
  106. package/src/shadcn/empty.tsx +103 -0
  107. package/src/shadcn/field.tsx +238 -0
  108. package/src/shadcn/form.tsx +173 -0
  109. package/src/shadcn/hover-card.tsx +50 -0
  110. package/src/shadcn/index.ts +53 -0
  111. package/src/shadcn/input-group.tsx +156 -0
  112. package/src/shadcn/input-otp.tsx +84 -0
  113. package/src/shadcn/input.tsx +19 -0
  114. package/src/shadcn/item.tsx +201 -0
  115. package/src/shadcn/kbd.tsx +26 -0
  116. package/src/shadcn/label.tsx +19 -0
  117. package/src/shadcn/marker.tsx +70 -0
  118. package/src/shadcn/menubar.tsx +278 -0
  119. package/src/shadcn/message-scroller.tsx +131 -0
  120. package/src/shadcn/message.tsx +91 -0
  121. package/src/shadcn/native-select.tsx +60 -0
  122. package/src/shadcn/navigation-menu.tsx +167 -0
  123. package/src/shadcn/pagination.tsx +130 -0
  124. package/src/shadcn/popover.tsx +87 -0
  125. package/src/shadcn/progress.tsx +82 -0
  126. package/src/shadcn/radio-group.tsx +35 -0
  127. package/src/shadcn/resizable.tsx +49 -0
  128. package/src/shadcn/scroll-area.tsx +52 -0
  129. package/src/shadcn/select.tsx +200 -0
  130. package/src/shadcn/separator.tsx +22 -0
  131. package/src/shadcn/sheet.tsx +136 -0
  132. package/src/shadcn/sidebar.tsx +721 -0
  133. package/src/shadcn/skeleton.tsx +13 -0
  134. package/src/shadcn/slider.tsx +51 -0
  135. package/src/shadcn/sonner.tsx +49 -0
  136. package/src/shadcn/spinner.tsx +10 -0
  137. package/src/shadcn/switch.tsx +29 -0
  138. package/src/shadcn/table.tsx +115 -0
  139. package/src/shadcn/tabs.tsx +79 -0
  140. package/src/shadcn/textarea.tsx +17 -0
  141. package/src/shadcn/toggle-group.tsx +89 -0
  142. package/src/shadcn/toggle.tsx +44 -0
  143. package/src/shadcn/tooltip.tsx +63 -0
  144. package/src/theme/config.ts +48 -0
  145. package/src/theme/css/base.css +92 -0
  146. package/src/theme/css/bitboy.css +75 -0
  147. package/src/theme/css/dark.css +47 -0
  148. package/src/theme/css/designer.css +122 -0
  149. package/src/theme/css/fonts.css +33 -0
  150. package/src/theme/css/globals.css +14 -0
  151. package/src/theme/css/hackintosh.css +57 -0
  152. package/src/theme/css/llama.css +103 -0
  153. package/src/theme/css/safelist.css +39 -0
  154. package/src/theme/css/shadcn.css +77 -0
  155. package/src/theme/css/theme.css +216 -0
  156. package/src/theme/embed-theme.ts +146 -0
  157. package/src/theme/fonts/FiraCode-VF.woff2 +0 -0
  158. package/src/theme/fonts/Hack-Regular.woff2 +0 -0
  159. package/src/theme/fonts/LICENSE-FiraCode.txt +93 -0
  160. package/src/theme/fonts/LICENSE-Hack.txt +45 -0
  161. package/src/theme/fonts/LICENSE-MonaSans.txt +93 -0
  162. package/src/theme/fonts/Mona-Sans.woff2 +0 -0
  163. package/src/theme/index.ts +15 -0
  164. package/src/utils/cn.ts +3 -0
  165. package/src/utils/index.ts +2 -0
@@ -0,0 +1,1153 @@
1
+ /**
2
+ * Centralized SDK Code Examples
3
+ *
4
+ * All SDK usage examples in one place for easy maintenance.
5
+ * Used by: app ApiUsage component, docs, README files
6
+ */
7
+
8
+ /**
9
+ * The one API key variable: belt, the SDKs and curl examples all read it.
10
+ * belt still accepts INFSH_API_KEY as a deprecated fallback (go/cli internal/config).
11
+ */
12
+ export const API_KEY_ENV = 'INFERENCE_API_KEY';
13
+
14
+ /** @deprecated Use API_KEY_ENV. */
15
+ export const SDK_API_KEY_ENV = API_KEY_ENV;
16
+
17
+ /** @deprecated Use API_KEY_ENV. belt reads INFERENCE_API_KEY now. */
18
+ export const CLI_API_KEY_ENV = API_KEY_ENV;
19
+
20
+ export interface ExampleParams {
21
+ /** App reference: namespace/name@shortId */
22
+ appRef: string;
23
+ /** Short ID of the version (for comments) */
24
+ shortId?: string;
25
+ /** Input data */
26
+ input?: Record<string, unknown>;
27
+ /** Setup data (optional) */
28
+ setup?: Record<string, unknown>;
29
+ /** Infrastructure mode */
30
+ infra?: string;
31
+ /** Worker IDs for private infra */
32
+ workers?: string[];
33
+ }
34
+
35
+ export interface ExampleOptions {
36
+ /** Include streaming example */
37
+ includeStreaming?: boolean;
38
+ /** Include fire-and-forget example */
39
+ includeFireAndForget?: boolean;
40
+ /** JSON indentation */
41
+ indent?: number;
42
+ }
43
+
44
+ /**
45
+ * Build the request data object used in all examples
46
+ */
47
+ export function buildRequestData(params: ExampleParams): Record<string, unknown> {
48
+ const { appRef, input, setup, infra, workers } = params;
49
+ const hasSetup = setup && Object.keys(setup).length > 0;
50
+
51
+ return {
52
+ app: appRef,
53
+ ...(hasSetup && { setup }),
54
+ input: input || {},
55
+ ...(infra && infra !== 'cloud' && { infra }),
56
+ ...(infra === 'private' && workers && { workers }),
57
+ };
58
+ }
59
+
60
+ /**
61
+ * Generate Python SDK example
62
+ */
63
+ export function generatePythonExample(
64
+ params: ExampleParams,
65
+ options: ExampleOptions = {}
66
+ ): string {
67
+ const { shortId } = params;
68
+ const { includeStreaming = true } = options;
69
+ const requestData = buildRequestData(params);
70
+ const jsonStr = formatJson(requestData, 4, ' ');
71
+
72
+ const versionComment = shortId
73
+ ? `# version @${shortId} pinned`
74
+ : ``;
75
+
76
+ let code = `import os
77
+ from inferencesh import inference, TaskStatus
78
+
79
+ # initialize client
80
+ client = inference(api_key=os.environ["INFERENCE_API_KEY"])
81
+
82
+ ${versionComment}
83
+ # run and wait for completion (default)
84
+ task = client.tasks.run(${jsonStr})
85
+
86
+ print(f"Task ID: {task['id']}")
87
+
88
+ if task["status"] == TaskStatus.COMPLETED:
89
+ print("Task completed!")
90
+ print(f"Output: {task['output']}")
91
+ elif task["status"] == TaskStatus.FAILED:
92
+ print(f"Task failed: {task.get('error')}")`;
93
+
94
+ if (includeStreaming) {
95
+ code += `
96
+
97
+ # stream updates for real-time progress
98
+ for update in client.tasks.run(${jsonStr}, stream=True):
99
+ print(f"Status: {update['status']}")
100
+ if update["status"] == TaskStatus.COMPLETED:
101
+ print(f"Result: {update['output']}")`;
102
+ }
103
+
104
+ return code;
105
+ }
106
+
107
+ /**
108
+ * Generate TypeScript SDK example
109
+ */
110
+ export function generateTypeScriptExample(
111
+ params: ExampleParams,
112
+ options: ExampleOptions = {}
113
+ ): string {
114
+ const { shortId } = params;
115
+ const { includeStreaming = true, includeFireAndForget = true } = options;
116
+ const requestData = buildRequestData(params);
117
+ const jsonStr = formatJson(requestData, 2);
118
+
119
+ const versionComment = shortId
120
+ ? `// version @${shortId} pinned`
121
+ : ``;
122
+
123
+ let code = `import { inference, TaskStatusCompleted, TaskStatusFailed } from '@inferencesh/sdk'
124
+
125
+ // initialize client
126
+ const client = inference({ apiKey: process.env.INFERENCE_API_KEY })
127
+
128
+ ${versionComment}
129
+ // run and wait for completion (default)
130
+ const task = await client.tasks.run(${jsonStr})
131
+
132
+ console.log("Task ID:", task.id)
133
+
134
+ if (task.status === TaskStatusCompleted) {
135
+ console.log("Task completed!")
136
+ console.log("Output:", task.output)
137
+ } else if (task.status === TaskStatusFailed) {
138
+ console.log("Task failed:", task.error)
139
+ }`;
140
+
141
+ if (includeStreaming) {
142
+ code += `
143
+
144
+ // with real-time status updates
145
+ const result = await client.tasks.run(
146
+ ${jsonStr},
147
+ {
148
+ onUpdate: (update) => {
149
+ console.log("Status:", update.status)
150
+ }
151
+ }
152
+ )`;
153
+ }
154
+
155
+ if (includeFireAndForget) {
156
+ code += `
157
+
158
+ // fire and forget (returns immediately)
159
+ const pending = await client.tasks.run(
160
+ ${jsonStr},
161
+ { wait: false }
162
+ )
163
+ console.log("Task submitted:", pending.id)`;
164
+ }
165
+
166
+ return code;
167
+ }
168
+
169
+ /**
170
+ * Generate JavaScript (CommonJS) SDK example
171
+ */
172
+ export function generateJavaScriptExample(
173
+ params: ExampleParams,
174
+ options: ExampleOptions = {}
175
+ ): string {
176
+ const { shortId } = params;
177
+ const { includeStreaming = true, includeFireAndForget = true } = options;
178
+ const requestData = buildRequestData(params);
179
+ const jsonStr = formatJson(requestData, 2);
180
+
181
+ const versionComment = shortId
182
+ ? `// version @${shortId} pinned`
183
+ : ``;
184
+
185
+ let code = `const { inference, TaskStatusCompleted, TaskStatusFailed } = require('@inferencesh/sdk')
186
+
187
+ // initialize client
188
+ const client = inference({ apiKey: process.env.INFERENCE_API_KEY })
189
+
190
+ ${versionComment}
191
+ // run and wait for completion (default)
192
+ const task = await client.tasks.run(${jsonStr})
193
+
194
+ console.log("Task ID:", task.id)
195
+
196
+ if (task.status === TaskStatusCompleted) {
197
+ console.log("Task completed!")
198
+ console.log("Output:", task.output)
199
+ } else if (task.status === TaskStatusFailed) {
200
+ console.log("Task failed:", task.error)
201
+ }`;
202
+
203
+ if (includeStreaming) {
204
+ code += `
205
+
206
+ // with real-time status updates
207
+ const result = await client.tasks.run(
208
+ ${jsonStr},
209
+ {
210
+ onUpdate: (update) => {
211
+ console.log("Status:", update.status)
212
+ }
213
+ }
214
+ )`;
215
+ }
216
+
217
+ if (includeFireAndForget) {
218
+ code += `
219
+
220
+ // fire and forget (returns immediately)
221
+ const pending = await client.tasks.run(
222
+ ${jsonStr},
223
+ { wait: false }
224
+ )
225
+ console.log("Task submitted:", pending.id)`;
226
+ }
227
+
228
+ return code;
229
+ }
230
+
231
+ // =============================================================================
232
+ // Swift helpers
233
+ // =============================================================================
234
+
235
+ const SWIFT_INDENT = ' ';
236
+
237
+ /** Escape a string as a Swift string literal (quotes included). */
238
+ export function swiftString(value: string): string {
239
+ let out = '"';
240
+ for (const ch of value) {
241
+ switch (ch) {
242
+ case '\\': out += '\\\\'; break;
243
+ case '"': out += '\\"'; break;
244
+ case '\n': out += '\\n'; break;
245
+ case '\r': out += '\\r'; break;
246
+ case '\t': out += '\\t'; break;
247
+ case '\0': out += '\\0'; break;
248
+ default: {
249
+ const code = ch.codePointAt(0)!;
250
+ // other control characters (and line/paragraph separators) as \u{...}
251
+ if (code < 0x20 || code === 0x7f || code === 0x2028 || code === 0x2029) {
252
+ out += `\\u{${code.toString(16)}}`;
253
+ } else {
254
+ out += ch;
255
+ }
256
+ }
257
+ }
258
+ }
259
+ return out + '"';
260
+ }
261
+
262
+ /**
263
+ * Format a JSON value as a Swift literal for a `JSONValue` context
264
+ * (dictionaries, arrays, strings, numbers, booleans, `nil`).
265
+ * Continuation lines are indented relative to `level`.
266
+ */
267
+ export function formatSwiftValue(value: unknown, level: number = 0): string {
268
+ if (value === null || value === undefined) return 'nil';
269
+ if (typeof value === 'string') return swiftString(value);
270
+ if (typeof value === 'boolean') return value ? 'true' : 'false';
271
+ if (typeof value === 'number' || typeof value === 'bigint') {
272
+ const n = Number(value);
273
+ if (!Number.isFinite(n)) return 'nil';
274
+ // integers beyond Int64 would overflow an integer literal; emit a float literal
275
+ if (Number.isInteger(n) && !Number.isSafeInteger(n)) {
276
+ const s = String(n);
277
+ return /[.e]/i.test(s) ? s : `${s}.0`;
278
+ }
279
+ return String(n);
280
+ }
281
+
282
+ const pad = SWIFT_INDENT.repeat(level + 1);
283
+ const closePad = SWIFT_INDENT.repeat(level);
284
+
285
+ if (Array.isArray(value)) {
286
+ if (value.length === 0) return '[]';
287
+ // short arrays of scalars stay on one line: ["a", "b"], [512, 768]
288
+ if (value.every((v) => v === null || typeof v !== 'object')) {
289
+ const inline = `[${value.map((v) => formatSwiftValue(v, level)).join(', ')}]`;
290
+ if (inline.length <= 60) return inline;
291
+ }
292
+ const items = value.map((v) => `${pad}${formatSwiftValue(v, level + 1)},`);
293
+ return `[\n${items.join('\n')}\n${closePad}]`;
294
+ }
295
+
296
+ if (typeof value === 'object') {
297
+ const entries = Object.entries(value as Record<string, unknown>).filter(([, v]) => v !== undefined);
298
+ if (entries.length === 0) return '[:]';
299
+ const items = entries.map(([k, v]) => `${pad}${swiftString(k)}: ${formatSwiftValue(v, level + 1)},`);
300
+ return `[\n${items.join('\n')}\n${closePad}]`;
301
+ }
302
+
303
+ return swiftString(String(value));
304
+ }
305
+
306
+ /** Swift expression for an infra value (`Infra` is a string-backed struct). */
307
+ function swiftInfra(infra: string): string {
308
+ switch (infra) {
309
+ case 'cloud': return '.cloud';
310
+ case 'private': return '.private';
311
+ case 'private_first': return '.privateFirst';
312
+ default: return `Infra(rawValue: ${swiftString(infra)})`;
313
+ }
314
+ }
315
+
316
+ export interface SwiftAppRunRequestFields {
317
+ app: string;
318
+ infra?: string;
319
+ workers?: string[];
320
+ webhook?: string;
321
+ setup?: Record<string, unknown>;
322
+ input?: Record<string, unknown>;
323
+ }
324
+
325
+ /**
326
+ * Format an `ApiAppRunRequest(...)` initializer call.
327
+ * Labels follow the initializer's declaration order
328
+ * (app, infra, workers, webhook, setup, input).
329
+ */
330
+ export function formatSwiftAppRunRequest(fields: SwiftAppRunRequestFields, level: number = 0): string {
331
+ const pad = SWIFT_INDENT.repeat(level + 1);
332
+ const args: string[] = [`app: ${swiftString(fields.app)}`];
333
+ if (fields.infra) args.push(`infra: ${swiftInfra(fields.infra)}`);
334
+ if (fields.workers) args.push(`workers: ${formatSwiftValue(fields.workers, level + 1)}`);
335
+ if (fields.webhook) args.push(`webhook: ${swiftString(fields.webhook)}`);
336
+ if (fields.setup) args.push(`setup: ${formatSwiftValue(fields.setup, level + 1)}`);
337
+ args.push(`input: ${formatSwiftValue(fields.input || {}, level + 1)}`);
338
+ return `ApiAppRunRequest(\n${args.map((a) => pad + a).join(',\n')}\n${SWIFT_INDENT.repeat(level)})`;
339
+ }
340
+
341
+ /** The app run request for the example params, as a Swift initializer call. */
342
+ function swiftRequest(params: ExampleParams, level: number = 0): string {
343
+ const data = buildRequestData(params) as {
344
+ app: string;
345
+ setup?: Record<string, unknown>;
346
+ input: Record<string, unknown>;
347
+ infra?: string;
348
+ workers?: string[];
349
+ };
350
+ return formatSwiftAppRunRequest(data, level);
351
+ }
352
+
353
+ /**
354
+ * Generate Swift SDK example
355
+ */
356
+ export function generateSwiftExample(
357
+ params: ExampleParams,
358
+ options: ExampleOptions = {}
359
+ ): string {
360
+ const { shortId } = params;
361
+ const { includeStreaming = true, includeFireAndForget = true } = options;
362
+
363
+ const versionComment = shortId
364
+ ? `// version @${shortId} pinned`
365
+ : ``;
366
+
367
+ let code = `import Foundation
368
+ import InferenceSDK
369
+
370
+ // initialize client
371
+ let client = InferenceClient(apiKey: ProcessInfo.processInfo.environment["INFERENCE_API_KEY"] ?? "")
372
+
373
+ ${versionComment}
374
+ let request = ${swiftRequest(params)}
375
+
376
+ // run and wait for completion (default)
377
+ do {
378
+ let task = try await client.tasks.run(request)
379
+ print("Task ID:", task.id)
380
+ print("Output:", task.output)
381
+ } catch let error as TaskRunError {
382
+ // failed and cancelled tasks throw
383
+ print("Task failed:", error.localizedDescription)
384
+ }`;
385
+
386
+ if (includeStreaming) {
387
+ code += `
388
+
389
+ // with real-time status updates
390
+ let result = try await client.tasks.run(
391
+ request,
392
+ options: TaskRunOptions(onUpdate: { update in
393
+ print("Status:", update.status.rawValue)
394
+ })
395
+ )
396
+ print("Output:", result.output)`;
397
+ }
398
+
399
+ if (includeFireAndForget) {
400
+ code += `
401
+
402
+ // fire and forget (returns immediately)
403
+ let pending = try await client.tasks.run(
404
+ request,
405
+ options: TaskRunOptions(wait: false)
406
+ )
407
+ print("Task submitted:", pending.id)`;
408
+ }
409
+
410
+ return code;
411
+ }
412
+
413
+ /**
414
+ * Swift file upload examples (the Swift SDK does not auto-upload local files)
415
+ */
416
+ export function generateSwiftFileExamples(appRef: string): { auto: string; manual: string } {
417
+ return {
418
+ auto: `// pass file URLs directly as input
419
+ let result = try await client.tasks.run(ApiAppRunRequest(
420
+ app: ${swiftString(appRef)},
421
+ input: [
422
+ "image": "https://example.com/image.png",
423
+ ]
424
+ ))`,
425
+ manual: `// upload a local file and pass its hosted URL
426
+ let data = try Data(contentsOf: URL(fileURLWithPath: "/path/to/file.png"))
427
+ let file = try await client.files.upload(data, filename: "file.png", contentType: "image/png")
428
+ print(file.uri) // https://cloud.inference.sh/...`,
429
+ };
430
+ }
431
+
432
+ /**
433
+ * Swift webhook example (fire and forget, result POSTed to the webhook)
434
+ */
435
+ export function generateSwiftWebhookExample(appRef: string, input: Record<string, unknown>): string {
436
+ return `let task = try await client.tasks.run(
437
+ ${formatSwiftAppRunRequest({ app: appRef, webhook: 'https://your-server.com/webhook', input }, 1)},
438
+ options: TaskRunOptions(wait: false)
439
+ )`;
440
+ }
441
+
442
+ /**
443
+ * Generate cURL example
444
+ */
445
+ export function generateCurlExample(params: ExampleParams): string {
446
+ const { shortId } = params;
447
+ const requestData = buildRequestData(params);
448
+ const jsonStr = JSON.stringify(requestData, null, 2).split('\n').join('\n ');
449
+
450
+ const versionComment = shortId
451
+ ? `# version @${shortId} pinned`
452
+ : ``;
453
+
454
+ const waitJson = JSON.stringify({ ...requestData, wait: true }, null, 2).split('\n').join('\n ');
455
+ const streamJson = JSON.stringify({ ...requestData, stream: true }, null, 2).split('\n').join('\n ');
456
+
457
+ return `${versionComment}
458
+ # run and wait for the result
459
+ curl -X POST https://api.inference.sh/apps/run \\
460
+ -H "Authorization: Bearer $INFERENCE_API_KEY" \\
461
+ -H "Content-Type: application/json" \\
462
+ -d ${shellQuote(waitJson)}
463
+
464
+ # or stream live updates (server-sent events)
465
+ curl -N -X POST https://api.inference.sh/apps/run \\
466
+ -H "Authorization: Bearer $INFERENCE_API_KEY" \\
467
+ -H "Content-Type: application/json" \\
468
+ -d ${shellQuote(streamJson)}`;
469
+ }
470
+
471
+ /**
472
+ * Generate all examples for a given set of parameters
473
+ */
474
+ export function generateAllExamples(
475
+ params: ExampleParams,
476
+ options: ExampleOptions = {}
477
+ ): Record<string, string> {
478
+ return {
479
+ python: generatePythonExample(params, options),
480
+ typescript: generateTypeScriptExample(params, options),
481
+ javascript: generateJavaScriptExample(params, options),
482
+ swift: generateSwiftExample(params, options),
483
+ curl: generateCurlExample(params),
484
+ belt: generateBeltExample(params),
485
+ };
486
+ }
487
+
488
+ /**
489
+ * Generate result-only examples (no streaming, just wait for completion)
490
+ */
491
+ export function generateResultOnlyExamples(params: ExampleParams): Record<string, string> {
492
+ const requestData = buildRequestData(params);
493
+ const { shortId } = params;
494
+
495
+ const versionCommentPy = shortId
496
+ ? `# version @${shortId} pinned`
497
+ : ``;
498
+
499
+ const versionCommentJs = shortId
500
+ ? `// version @${shortId} pinned`
501
+ : ``;
502
+
503
+ const jsonStrPy = formatJson(requestData, 4, ' ');
504
+ const jsonStrJs = formatJson(requestData, 2);
505
+ const jsonStrCurl = JSON.stringify({ ...requestData, wait: true }, null, 2).split('\n').join('\n ');
506
+ const swiftReq = swiftRequest(params);
507
+
508
+ return {
509
+ python: `import os
510
+ from inferencesh import inference
511
+
512
+ client = inference(api_key=os.environ["INFERENCE_API_KEY"])
513
+
514
+ ${versionCommentPy}
515
+ result = client.run(${jsonStrPy})
516
+
517
+ print(result["output"])`,
518
+
519
+ typescript: `import { inference } from "@inferencesh/sdk"
520
+
521
+ const client = inference({ apiKey: process.env.INFERENCE_API_KEY })
522
+
523
+ ${versionCommentJs}
524
+ const result = await client.run(${jsonStrJs})
525
+
526
+ console.log(result.output)`,
527
+
528
+ javascript: `const { inference } = require("@inferencesh/sdk")
529
+
530
+ const client = inference({ apiKey: process.env.INFERENCE_API_KEY })
531
+
532
+ ${versionCommentJs}
533
+ const result = await client.run(${jsonStrJs})
534
+
535
+ console.log(result.output)`,
536
+
537
+ swift: `import Foundation
538
+ import InferenceSDK
539
+
540
+ let client = InferenceClient(apiKey: ProcessInfo.processInfo.environment["INFERENCE_API_KEY"] ?? "")
541
+
542
+ ${versionCommentJs}
543
+ let result = try await client.tasks.run(${swiftReq})
544
+
545
+ print(result.output)`,
546
+
547
+ curl: `${versionCommentPy}
548
+ # "wait": true holds the connection until the task finishes.
549
+ # the response is {"data": {"id", "status", "status_text", "output", ...}}
550
+ curl -X POST https://api.inference.sh/apps/run \\
551
+ -H "Authorization: Bearer $INFERENCE_API_KEY" \\
552
+ -H "Content-Type: application/json" \\
553
+ -d ${shellQuote(jsonStrCurl)}`,
554
+
555
+ belt: `${versionCommentPy}
556
+ belt app run ${params.appRef} --input ${shellQuote(JSON.stringify(requestData.input || {}))}`,
557
+ };
558
+ }
559
+
560
+ /**
561
+ * Generate streaming examples (real-time updates)
562
+ */
563
+ export function generateStreamingExamples(params: ExampleParams): Record<string, string> {
564
+ const requestData = buildRequestData(params);
565
+ const { shortId } = params;
566
+
567
+ const versionCommentPy = shortId
568
+ ? `# version @${shortId} pinned`
569
+ : ``;
570
+
571
+ const versionCommentJs = shortId
572
+ ? `// version @${shortId} pinned`
573
+ : ``;
574
+
575
+ const jsonStrPy = formatJson(requestData, 4, ' ');
576
+ const jsonStrJs = formatJson(requestData, 2);
577
+ const jsonStrCurl = JSON.stringify({ ...requestData, stream: true }, null, 2).split('\n').join('\n ');
578
+
579
+ return {
580
+ python: `import os
581
+ from inferencesh import inference
582
+
583
+ client = inference(api_key=os.environ["INFERENCE_API_KEY"])
584
+
585
+ ${versionCommentPy}
586
+ # stream=True yields updates as they arrive
587
+ for update in client.run(${jsonStrPy}, stream=True):
588
+ if update.get("progress"):
589
+ print(f"progress: {update['progress']}%")
590
+ if update.get("output"):
591
+ print(f"output: {update['output']}")`,
592
+
593
+ typescript: `import { inference } from "@inferencesh/sdk"
594
+
595
+ const client = inference({ apiKey: process.env.INFERENCE_API_KEY })
596
+
597
+ ${versionCommentJs}
598
+ // onUpdate callback fires on each status change
599
+ const result = await client.run(${jsonStrJs}, {
600
+ onUpdate: (update) => {
601
+ if (update.progress) {
602
+ console.log(\`progress: \${update.progress}%\`)
603
+ }
604
+ if (update.output) {
605
+ console.log("output:", update.output)
606
+ }
607
+ }
608
+ })`,
609
+
610
+ javascript: `const { inference } = require("@inferencesh/sdk")
611
+
612
+ const client = inference({ apiKey: process.env.INFERENCE_API_KEY })
613
+
614
+ ${versionCommentJs}
615
+ // onUpdate callback fires on each status change
616
+ const result = await client.run(${jsonStrJs}, {
617
+ onUpdate: (update) => {
618
+ if (update.progress) {
619
+ console.log(\`progress: \${update.progress}%\`)
620
+ }
621
+ if (update.output) {
622
+ console.log("output:", update.output)
623
+ }
624
+ }
625
+ })`,
626
+
627
+ swift: `import Foundation
628
+ import InferenceSDK
629
+
630
+ let client = InferenceClient(apiKey: ProcessInfo.processInfo.environment["INFERENCE_API_KEY"] ?? "")
631
+
632
+ ${versionCommentJs}
633
+ // onUpdate fires on each status change
634
+ let result = try await client.tasks.run(
635
+ ${swiftRequest(params, 1)},
636
+ options: TaskRunOptions(onUpdate: { update in
637
+ print("status:", update.status.rawValue)
638
+ })
639
+ )
640
+
641
+ print("output:", result.output)`,
642
+
643
+ curl: `${versionCommentPy}
644
+ # "stream": true answers with server-sent events until the task finishes
645
+ curl -N -X POST https://api.inference.sh/apps/run \\
646
+ -H "Authorization: Bearer $INFERENCE_API_KEY" \\
647
+ -H "Content-Type: application/json" \\
648
+ -d ${shellQuote(jsonStrCurl)}`,
649
+
650
+ belt: `${versionCommentPy}
651
+ # belt streams progress by default
652
+ belt app run ${params.appRef} --input ${shellQuote(JSON.stringify(requestData.input || {}))}`,
653
+ };
654
+ }
655
+
656
+ /**
657
+ * Run without waiting, then check on the task later.
658
+ * Each SDK returns the task right away; GET /tasks/{id} reads its state.
659
+ */
660
+ export function generateBackgroundExamples(params: ExampleParams): Record<string, string> {
661
+ const requestData = buildRequestData(params);
662
+ const jsonStrPy = formatJson(requestData, 4, ' ');
663
+ const jsonStrJs = formatJson(requestData, 2);
664
+ const jsonStrCurl = JSON.stringify(requestData, null, 2).split('\n').join('\n ');
665
+ const jsClient = (importLine: string) => `${importLine}
666
+
667
+ const client = inference({ apiKey: process.env.INFERENCE_API_KEY })
668
+
669
+ // returns as soon as the task is created
670
+ const task = await client.run(${jsonStrJs}, { wait: false })
671
+
672
+ // later: read its current state
673
+ const { data: state } = await client.tasks.get(task.id)
674
+ if (state.status === TaskStatusCompleted) {
675
+ console.log(state.output)
676
+ }`;
677
+
678
+ return {
679
+ python: `import os
680
+ from inferencesh import inference, TaskStatus
681
+
682
+ client = inference(api_key=os.environ["INFERENCE_API_KEY"])
683
+
684
+ # returns as soon as the task is created
685
+ task = client.run(${jsonStrPy}, wait=False)
686
+
687
+ # later: read its current state
688
+ state = client.tasks.get(task["id"]).data
689
+ if state["status"] == TaskStatus.COMPLETED:
690
+ print(state["output"])`,
691
+
692
+ typescript: jsClient(`import { inference, TaskStatusCompleted } from "@inferencesh/sdk"`),
693
+ javascript: jsClient(`const { inference, TaskStatusCompleted } = require("@inferencesh/sdk")`),
694
+
695
+ swift: `import Foundation
696
+ import InferenceSDK
697
+
698
+ let client = InferenceClient(apiKey: ProcessInfo.processInfo.environment["INFERENCE_API_KEY"] ?? "")
699
+
700
+ // returns as soon as the task is created
701
+ let task = try await client.tasks.run(
702
+ ${swiftRequest(params, 1)},
703
+ options: TaskRunOptions(wait: false)
704
+ )
705
+
706
+ // later: read its current state
707
+ let state = try await client.tasks.get(task.id)
708
+ print(state.status, state.output)`,
709
+
710
+ curl: `# without "wait" the call returns the task right away (status 1, "received")
711
+ TASK_ID=$(curl -s -X POST https://api.inference.sh/apps/run \\
712
+ -H "Authorization: Bearer $INFERENCE_API_KEY" \\
713
+ -H "Content-Type: application/json" \\
714
+ -d ${shellQuote(jsonStrCurl)} | jq -r '.data.id')
715
+
716
+ # later: read its state. done when status is 10 (completed), 11 (failed) or 12 (cancelled)
717
+ curl -s https://api.inference.sh/tasks/$TASK_ID \\
718
+ -H "Authorization: Bearer $INFERENCE_API_KEY" | jq '.data | {status, status_text, output}'`,
719
+
720
+ belt: `# returns the task id without waiting
721
+ belt app run ${params.appRef} --input ${shellQuote(JSON.stringify(requestData.input || {}))} --no-wait
722
+
723
+ # later: read its state (-f follows it until it finishes)
724
+ belt task get TASK_ID -f`,
725
+ };
726
+ }
727
+
728
+ /**
729
+ * File input examples: passing files in, and uploading one by hand.
730
+ */
731
+ export function generateFileExamples(appRef: string): Record<string, { auto: string; manual: string }> {
732
+ const js = {
733
+ auto: `// File/Blob objects and data URIs are automatically uploaded
734
+ const result = await client.run({
735
+ app: "${appRef}",
736
+ input: {
737
+ image: fileInput.files[0], // File from <input> - uploaded
738
+ photo: await fetch(url).then(r => r.blob()), // Blob - uploaded
739
+ icon: "data:image/png;base64,...", // data URI - uploaded
740
+ }
741
+ })`,
742
+ manual: `// upload and get a hosted URL
743
+ const file = await client.files.upload(blob, {
744
+ filename: "image.png",
745
+ contentType: "image/png"
746
+ })
747
+ console.log(file.uri) // https://cloud.inference.sh/...`,
748
+ };
749
+ return {
750
+ python: {
751
+ auto: `# local file paths are automatically uploaded
752
+ result = client.run({
753
+ "app": "${appRef}",
754
+ "input": {
755
+ "image": "/path/to/local/image.png", # detected & uploaded
756
+ "audio": "https://example.com/audio.mp3", # url passed through
757
+ }
758
+ })`,
759
+ manual: `# upload and get a hosted URL
760
+ file = client.files.upload("/path/to/file.png")
761
+ print(file.uri) # https://cloud.inference.sh/...`,
762
+ },
763
+ typescript: js,
764
+ javascript: js,
765
+ swift: generateSwiftFileExamples(appRef),
766
+ curl: {
767
+ auto: `# pass URLs or data URIs as input values
768
+ curl -X POST https://api.inference.sh/apps/run \\
769
+ -H "Authorization: Bearer $INFERENCE_API_KEY" \\
770
+ -H "Content-Type: application/json" \\
771
+ -d '{
772
+ "app": "${appRef}",
773
+ "input": {
774
+ "image": "https://example.com/image.png",
775
+ "audio": "data:audio/mp3;base64,..."
776
+ },
777
+ "wait": true
778
+ }'`,
779
+ manual: `# 1. create the file: the response has an upload_url and the file's uri
780
+ FILE=$(curl -s -X POST https://api.inference.sh/files \\
781
+ -H "Authorization: Bearer $INFERENCE_API_KEY" \\
782
+ -H "Content-Type: application/json" \\
783
+ -d '{"files": [{"filename": "image.png", "content_type": "image/png"}]}')
784
+
785
+ # 2. PUT the bytes to upload_url
786
+ curl -X PUT "$(echo "$FILE" | jq -r '.data[0].upload_url')" \\
787
+ -H "Content-Type: image/png" \\
788
+ --data-binary @image.png
789
+
790
+ # 3. pass the uri as an input value
791
+ echo "$FILE" | jq -r '.data[0].uri'`,
792
+ },
793
+ belt: {
794
+ auto: `# belt uploads local paths in the input for you
795
+ belt app run ${appRef} --input '{"image": "/path/to/local/image.png"}'`,
796
+ manual: `# files are handled automatically by belt
797
+ # pass local paths or URLs in the input JSON`,
798
+ },
799
+ };
800
+ }
801
+
802
+ /**
803
+ * Generate belt CLI example
804
+ */
805
+ export function generateBeltExample(params: ExampleParams): string {
806
+ const { appRef, input } = params;
807
+ const inputJson = shellQuote(JSON.stringify(input || {}));
808
+
809
+ return `# install belt
810
+ curl -fsSL https://cli.inference.sh | sh
811
+
812
+ # sign in (or set ${API_KEY_ENV} on a headless machine)
813
+ belt login
814
+
815
+ # run and wait for result
816
+ belt app run ${appRef} --input ${inputJson}
817
+
818
+ # save output to file
819
+ belt app run ${appRef} --input ${inputJson} -o result.json
820
+
821
+ # get app details and schema
822
+ belt app get ${appRef}`;
823
+ }
824
+
825
+ /**
826
+ * Install commands for each language
827
+ */
828
+ export const installCommands: Record<string, { command: string; label: string } | null> = {
829
+ python: { command: 'pip install inferencesh', label: '$' },
830
+ typescript: { command: 'npm install @inferencesh/sdk', label: '$' },
831
+ javascript: { command: 'npm install @inferencesh/sdk', label: '$' },
832
+ swift: { command: '.package(url: "https://github.com/inference-sh/sdk-swift", from: "0.1.0")', label: 'spm' },
833
+ curl: null,
834
+ belt: { command: 'curl -fsSL https://cli.inference.sh | sh', label: '$' },
835
+ };
836
+
837
+ /**
838
+ * How each language picks up the API key. Every tool reads the same variable,
839
+ * API_KEY_ENV; belt also uses its saved login.
840
+ */
841
+ export const apiKeySetup: Record<string, { variable: string; command: string }> = {
842
+ python: { variable: API_KEY_ENV, command: `export ${API_KEY_ENV}="inf_your_key"` },
843
+ typescript: { variable: API_KEY_ENV, command: `export ${API_KEY_ENV}="inf_your_key"` },
844
+ javascript: { variable: API_KEY_ENV, command: `export ${API_KEY_ENV}="inf_your_key"` },
845
+ swift: { variable: API_KEY_ENV, command: `export ${API_KEY_ENV}="inf_your_key"` },
846
+ curl: { variable: API_KEY_ENV, command: `export ${API_KEY_ENV}="inf_your_key"` },
847
+ belt: {
848
+ variable: API_KEY_ENV,
849
+ command: `# sign in from a browser
850
+ belt login
851
+
852
+ # or, on a headless machine
853
+ export ${API_KEY_ENV}="inf_your_key"`,
854
+ },
855
+ };
856
+
857
+ /** Quote a string for a POSIX shell: single quotes, with any single quote spliced in. */
858
+ export function shellQuote(value: string): string {
859
+ return `'${value.replace(/'/g, `'\\''`)}'`;
860
+ }
861
+
862
+ // Helper to format JSON with custom indentation for nested content
863
+ function formatJson(obj: Record<string, unknown>, indent: number, prefix: string = ''): string {
864
+ const json = JSON.stringify(obj, null, indent);
865
+ if (!prefix) return json;
866
+ return json.split('\n').map((line, i) => i === 0 ? line : prefix + line).join('\n');
867
+ }
868
+
869
+ // =============================================================================
870
+ // Agent Examples
871
+ // =============================================================================
872
+
873
+ export interface AgentExampleParams {
874
+ /** Agent reference: namespace/name@shortVersionId */
875
+ agentRef: string;
876
+ /** Short version ID (for comments) */
877
+ shortVersionId?: string;
878
+ }
879
+
880
+ /**
881
+ * Generate Python Agent SDK example
882
+ */
883
+ export function generateAgentPythonExample(params: AgentExampleParams): string {
884
+ const { agentRef, shortVersionId } = params;
885
+
886
+ const versionComment = shortVersionId
887
+ ? `# version @${shortVersionId} pinned`
888
+ : ``;
889
+
890
+ return `import os
891
+ from inferencesh import inference
892
+
893
+ # initialize client
894
+ client = inference(api_key=os.environ["INFERENCE_API_KEY"])
895
+
896
+ ${versionComment}
897
+ # create agent from template
898
+ agent = client.agents.create("${agentRef}")
899
+
900
+ # send a message
901
+ response = agent.send_message("Hello!")
902
+ print(response)
903
+
904
+ # with streaming
905
+ def on_message(msg):
906
+ if msg.get("content"):
907
+ print(msg["content"], end="", flush=True)
908
+
909
+ def on_tool_call(call):
910
+ print(f"\\n[Tool: {call.name}]")
911
+ result = handle_tool(call.name, call.args)
912
+ agent.submit_tool_result(call.id, result)
913
+
914
+ response = agent.send_message(
915
+ "Help me with something",
916
+ on_message=on_message,
917
+ on_tool_call=on_tool_call
918
+ )
919
+
920
+ # get chat history
921
+ chat = agent.get_chat()
922
+ print(f"Chat ID: {chat['id']}")
923
+
924
+ # stop generation
925
+ agent.stop_chat()
926
+
927
+ # start fresh conversation
928
+ agent.reset()`;
929
+ }
930
+
931
+ /**
932
+ * Generate TypeScript Agent SDK example
933
+ */
934
+ export function generateAgentTypeScriptExample(params: AgentExampleParams): string {
935
+ const { agentRef, shortVersionId } = params;
936
+
937
+ const versionComment = shortVersionId
938
+ ? `// version @${shortVersionId} pinned`
939
+ : ``;
940
+
941
+ return `import { inference } from '@inferencesh/sdk'
942
+
943
+ // initialize client
944
+ const client = inference({ apiKey: process.env.INFERENCE_API_KEY })
945
+
946
+ ${versionComment}
947
+ // create agent from template
948
+ const agent = client.agents.create('${agentRef}')
949
+
950
+ // send a message
951
+ const response = await agent.sendMessage('Hello!')
952
+ console.log(response)
953
+
954
+ // with streaming
955
+ await agent.sendMessage('Help me with something', {
956
+ onMessage: (msg) => {
957
+ if (msg.content) {
958
+ for (const c of msg.content) {
959
+ if (c.type === 'text' && c.text) {
960
+ process.stdout.write(c.text)
961
+ }
962
+ }
963
+ }
964
+ },
965
+ onToolCall: async (call) => {
966
+ console.log(\`\\n[Tool: \${call.name}]\`)
967
+ const result = await handleTool(call.name, call.args)
968
+ await agent.submitToolResult(call.id, result)
969
+ }
970
+ })
971
+
972
+ // get chat history
973
+ const chat = await agent.getChat()
974
+ console.log('Chat ID:', chat?.id)
975
+
976
+ // stop generation
977
+ await agent.stopChat()
978
+
979
+ // cleanup
980
+ agent.disconnect()`;
981
+ }
982
+
983
+ /**
984
+ * Generate JavaScript Agent SDK example
985
+ */
986
+ export function generateAgentJavaScriptExample(params: AgentExampleParams): string {
987
+ const { agentRef, shortVersionId } = params;
988
+
989
+ const versionComment = shortVersionId
990
+ ? `// version @${shortVersionId} pinned`
991
+ : ``;
992
+
993
+ return `const { inference } = require('@inferencesh/sdk')
994
+
995
+ // initialize client
996
+ const client = inference({ apiKey: process.env.INFERENCE_API_KEY })
997
+
998
+ ${versionComment}
999
+ // create agent from template
1000
+ const agent = client.agents.create('${agentRef}')
1001
+
1002
+ // send a message
1003
+ const response = await agent.sendMessage('Hello!')
1004
+ console.log(response)
1005
+
1006
+ // with streaming
1007
+ await agent.sendMessage('Help me with something', {
1008
+ onMessage: (msg) => {
1009
+ if (msg.content) {
1010
+ for (const c of msg.content) {
1011
+ if (c.type === 'text' && c.text) {
1012
+ process.stdout.write(c.text)
1013
+ }
1014
+ }
1015
+ }
1016
+ },
1017
+ onToolCall: async (call) => {
1018
+ console.log(\`\\n[Tool: \${call.name}]\`)
1019
+ const result = await handleTool(call.name, call.args)
1020
+ await agent.submitToolResult(call.id, result)
1021
+ }
1022
+ })
1023
+
1024
+ // get chat history
1025
+ const chat = await agent.getChat()
1026
+ console.log('Chat ID:', chat?.id)
1027
+
1028
+ // stop generation
1029
+ await agent.stopChat()
1030
+
1031
+ // cleanup
1032
+ agent.disconnect()`;
1033
+ }
1034
+
1035
+ /**
1036
+ * Generate Swift Agent SDK example
1037
+ */
1038
+ export function generateAgentSwiftExample(params: AgentExampleParams): string {
1039
+ const { agentRef, shortVersionId } = params;
1040
+
1041
+ const versionComment = shortVersionId
1042
+ ? `// version @${shortVersionId} pinned`
1043
+ : ``;
1044
+
1045
+ return `import InferenceSDK
1046
+
1047
+ // initialize client
1048
+ let client = InferenceClient(apiKey: ProcessInfo.processInfo.environment["INFERENCE_API_KEY"] ?? "")
1049
+
1050
+ ${versionComment}
1051
+ // one-shot run: streams snapshots of the reply until it finishes
1052
+ let request = ApiAgentRunRequest(agent: ${swiftString(agentRef)}, input: LLMInput(text: "Hello!"))
1053
+ for try await message in client.runAgentStream(request) {
1054
+ if message.status.isTerminal {
1055
+ print(message.text)
1056
+ break
1057
+ }
1058
+ }
1059
+
1060
+ // chat session: keeps the conversation and follows its stream
1061
+ // (AgentChatSession is @MainActor)
1062
+ let session = AgentChatSession(client: client, agent: ${swiftString(agentRef)})
1063
+
1064
+ session.onChange = { state in
1065
+ // every state change: messages, chat status, connection, errors
1066
+ if let last = state.messages.last {
1067
+ print(last.role.rawValue, last.text)
1068
+ }
1069
+ }
1070
+ session.callbacks.onTurnEnd = { chat in
1071
+ print("Chat ID:", chat.id)
1072
+ }
1073
+
1074
+ // send a message
1075
+ await session.sendMessage("Help me with something")
1076
+
1077
+ // tool calls that need the user wait in message.toolInvocations:
1078
+ // try await session.approveTool(invocation.id)
1079
+ // try await session.submitToolResult(invocation.id, result: resultJSON)
1080
+
1081
+ // stop generation
1082
+ session.stopGeneration()
1083
+
1084
+ // start fresh conversation
1085
+ session.reset()`;
1086
+ }
1087
+
1088
+ /**
1089
+ * Generate cURL Agent example
1090
+ */
1091
+ export function generateAgentCurlExample(params: AgentExampleParams): string {
1092
+ const { agentRef, shortVersionId } = params;
1093
+
1094
+ const versionComment = shortVersionId
1095
+ ? `# Using pinned version @${shortVersionId} (recommended for production)`
1096
+ : `# Using latest version (add version_id for production stability)`;
1097
+
1098
+ return `${versionComment}
1099
+ # send a message with streaming
1100
+ curl -N -X POST \\
1101
+ -H "Authorization: Bearer $INFERENCE_API_KEY" \\
1102
+ -H "Content-Type: application/json" \\
1103
+ -d '{
1104
+ "agent": "${agentRef}",
1105
+ "input": {"text": "Hello!", "role": "user"},
1106
+ "stream": true
1107
+ }' \\
1108
+ https://api.inference.sh/agents/run
1109
+
1110
+ # without streaming (returns JSON with chat_id)
1111
+ curl -X POST \\
1112
+ -H "Authorization: Bearer $INFERENCE_API_KEY" \\
1113
+ -H "Content-Type: application/json" \\
1114
+ -d '{
1115
+ "agent": "${agentRef}",
1116
+ "input": {"text": "Hello!", "role": "user"}
1117
+ }' \\
1118
+ https://api.inference.sh/agents/run
1119
+
1120
+ # continue conversation (use chat_id from previous response)
1121
+ curl -N -X POST \\
1122
+ -H "Authorization: Bearer $INFERENCE_API_KEY" \\
1123
+ -H "Content-Type: application/json" \\
1124
+ -d '{
1125
+ "agent": "${agentRef}",
1126
+ "chat_id": "CHAT_ID",
1127
+ "input": {"text": "Tell me more", "role": "user"},
1128
+ "stream": true
1129
+ }' \\
1130
+ https://api.inference.sh/agents/run
1131
+
1132
+ # stop generation
1133
+ curl -X POST \\
1134
+ -H "Authorization: Bearer $INFERENCE_API_KEY" \\
1135
+ https://api.inference.sh/chats/CHAT_ID/stop`;
1136
+ }
1137
+
1138
+ /**
1139
+ * Generate all agent examples
1140
+ */
1141
+ export function generateAllAgentExamples(params: AgentExampleParams): Record<string, string> {
1142
+ return {
1143
+ python: generateAgentPythonExample(params),
1144
+ typescript: generateAgentTypeScriptExample(params),
1145
+ javascript: generateAgentJavaScriptExample(params),
1146
+ swift: generateAgentSwiftExample(params),
1147
+ curl: generateAgentCurlExample(params),
1148
+ };
1149
+ }
1150
+
1151
+ // Re-export guide markdown generator
1152
+ export { generateGuideMarkdown } from './guide-markdown'
1153
+ export type { GuideApp, GuideVersion, GuideLanguage } from './guide-markdown'