@flowscale/sdk 1.0.0 → 1.2.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +430 -0
- package/dist/http.d.ts +87 -0
- package/dist/http.d.ts.map +1 -0
- package/dist/http.js +140 -0
- package/dist/http.js.map +1 -0
- package/dist/index.d.ts +3 -0
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +4 -1
- package/dist/index.js.map +1 -1
- package/dist/tools.d.ts +7 -1
- package/dist/tools.d.ts.map +1 -1
- package/dist/tools.js +8 -0
- package/dist/tools.js.map +1 -1
- package/dist/types.d.ts +27 -2
- package/dist/types.d.ts.map +1 -1
- package/package.json +3 -3
package/README.md
ADDED
|
@@ -0,0 +1,430 @@
|
|
|
1
|
+
# @flowscale/sdk — External App Guide
|
|
2
|
+
|
|
3
|
+
This guide covers building apps that run **outside** FlowScale using the HTTP transport. You can use any language or framework — Node.js scripts, Express servers, Next.js apps, Python backends calling a Node wrapper, anything that can make HTTP requests.
|
|
4
|
+
|
|
5
|
+
> **Prerequisite:** A running FlowScale AIOS instance. Default local address: `http://localhost:14173`.
|
|
6
|
+
|
|
7
|
+
---
|
|
8
|
+
|
|
9
|
+
## Installation
|
|
10
|
+
|
|
11
|
+
```bash
|
|
12
|
+
npm install @flowscale/sdk
|
|
13
|
+
# or
|
|
14
|
+
pnpm add @flowscale/sdk
|
|
15
|
+
```
|
|
16
|
+
|
|
17
|
+
Requires Node.js 18+ (uses the native `fetch` API).
|
|
18
|
+
|
|
19
|
+
---
|
|
20
|
+
|
|
21
|
+
## Authentication
|
|
22
|
+
|
|
23
|
+
Every request requires a session. Call `login()` once to get a token, then pass it to `createClient()`. Tokens are valid for **7 days**.
|
|
24
|
+
|
|
25
|
+
```ts
|
|
26
|
+
import { login, createClient } from '@flowscale/sdk'
|
|
27
|
+
|
|
28
|
+
const token = await login({
|
|
29
|
+
baseUrl: 'http://localhost:14173',
|
|
30
|
+
username: 'admin',
|
|
31
|
+
password: 'your-password',
|
|
32
|
+
})
|
|
33
|
+
|
|
34
|
+
const client = createClient({
|
|
35
|
+
baseUrl: 'http://localhost:14173',
|
|
36
|
+
sessionToken: token,
|
|
37
|
+
})
|
|
38
|
+
```
|
|
39
|
+
|
|
40
|
+
> `login()` reads the session token from the `Set-Cookie` response header. This works in **Node.js** (`fetch` exposes `Set-Cookie`). In a browser context, the browser handles the cookie automatically and you do not need to call `login()` — just make requests with `credentials: 'include'` against `http://localhost:14173` directly.
|
|
41
|
+
|
|
42
|
+
### Persisting the token
|
|
43
|
+
|
|
44
|
+
```ts
|
|
45
|
+
import { writeFileSync, readFileSync, existsSync } from 'fs'
|
|
46
|
+
|
|
47
|
+
const TOKEN_FILE = '.flowscale-token'
|
|
48
|
+
|
|
49
|
+
async function getToken(): Promise<string> {
|
|
50
|
+
if (existsSync(TOKEN_FILE)) {
|
|
51
|
+
return readFileSync(TOKEN_FILE, 'utf-8').trim()
|
|
52
|
+
}
|
|
53
|
+
const token = await login({
|
|
54
|
+
baseUrl: 'http://localhost:14173',
|
|
55
|
+
username: 'admin',
|
|
56
|
+
password: process.env.FS_PASSWORD!,
|
|
57
|
+
})
|
|
58
|
+
writeFileSync(TOKEN_FILE, token)
|
|
59
|
+
return token
|
|
60
|
+
}
|
|
61
|
+
```
|
|
62
|
+
|
|
63
|
+
---
|
|
64
|
+
|
|
65
|
+
## Creating a client
|
|
66
|
+
|
|
67
|
+
```ts
|
|
68
|
+
const client = createClient({
|
|
69
|
+
baseUrl: 'http://localhost:14173', // required
|
|
70
|
+
sessionToken: token, // required
|
|
71
|
+
|
|
72
|
+
// Optional:
|
|
73
|
+
timeout: 300_000, // ms to wait for a tool to finish (default: 5 minutes)
|
|
74
|
+
pollInterval: 2_000, // ms between status polls for API-engine tools (default: 2s)
|
|
75
|
+
})
|
|
76
|
+
```
|
|
77
|
+
|
|
78
|
+
---
|
|
79
|
+
|
|
80
|
+
## Listing tools
|
|
81
|
+
|
|
82
|
+
`client.tools.list()` returns all tools with `status = 'production'`. Each row is the raw DB record — the key field for running tools is `id`, and `schemaJson` (a JSON string) describes the inputs.
|
|
83
|
+
|
|
84
|
+
```ts
|
|
85
|
+
const tools = await client.tools.list()
|
|
86
|
+
|
|
87
|
+
for (const tool of tools) {
|
|
88
|
+
console.log(tool.id, tool.name, tool.description)
|
|
89
|
+
}
|
|
90
|
+
```
|
|
91
|
+
|
|
92
|
+
---
|
|
93
|
+
|
|
94
|
+
## Inspecting a tool's inputs
|
|
95
|
+
|
|
96
|
+
The `schemaJson` field on each tool is a JSON string containing an array of `WorkflowIO` objects — one per configurable input or output node.
|
|
97
|
+
|
|
98
|
+
```ts
|
|
99
|
+
const tool = await client.tools.get('your-tool-id')
|
|
100
|
+
|
|
101
|
+
interface WorkflowIO {
|
|
102
|
+
nodeId: string // ComfyUI node ID, e.g. "6"
|
|
103
|
+
nodeType: string // e.g. "CLIPTextEncode"
|
|
104
|
+
nodeTitle: string // human label, e.g. "Positive Prompt"
|
|
105
|
+
paramName: string // e.g. "text"
|
|
106
|
+
paramType: 'string' | 'number' | 'boolean' | 'image' | 'select'
|
|
107
|
+
defaultValue?: unknown
|
|
108
|
+
options?: string[] // for paramType 'select'
|
|
109
|
+
isInput: boolean // false = output node
|
|
110
|
+
}
|
|
111
|
+
|
|
112
|
+
const schema: WorkflowIO[] = JSON.parse(tool.schemaJson)
|
|
113
|
+
const inputs = schema.filter(f => f.isInput)
|
|
114
|
+
|
|
115
|
+
for (const field of inputs) {
|
|
116
|
+
console.log(`${field.nodeId}__${field.paramName}`, field.paramType, field.defaultValue)
|
|
117
|
+
}
|
|
118
|
+
```
|
|
119
|
+
|
|
120
|
+
---
|
|
121
|
+
|
|
122
|
+
## Running a tool
|
|
123
|
+
|
|
124
|
+
### Input key format
|
|
125
|
+
|
|
126
|
+
Input keys are always **`"${nodeId}__${paramName}"`** (double underscore). You can see the exact keys by inspecting `schemaJson` as shown above, or read them from the tool's form in the FlowScale UI.
|
|
127
|
+
|
|
128
|
+
```ts
|
|
129
|
+
const result = await client.tools.run('your-tool-id', {
|
|
130
|
+
'6__text': 'a photorealistic cat on the moon, cinematic lighting',
|
|
131
|
+
'7__text': 'blurry, low quality, watermark',
|
|
132
|
+
'5__width': 1024,
|
|
133
|
+
'5__height': 1024,
|
|
134
|
+
'3__steps': 20,
|
|
135
|
+
'3__cfg': 7,
|
|
136
|
+
})
|
|
137
|
+
```
|
|
138
|
+
|
|
139
|
+
`tools.run()` blocks until the tool finishes and returns a `ToolRunResult`:
|
|
140
|
+
|
|
141
|
+
```ts
|
|
142
|
+
interface ToolRunResult {
|
|
143
|
+
executionId: string
|
|
144
|
+
toolId: string
|
|
145
|
+
status: 'completed'
|
|
146
|
+
outputs: ToolOutputItem[]
|
|
147
|
+
}
|
|
148
|
+
|
|
149
|
+
interface ToolOutputItem {
|
|
150
|
+
kind: 'image' | 'video' | 'audio' | 'file'
|
|
151
|
+
filename: string
|
|
152
|
+
subfolder: string
|
|
153
|
+
path: string // relative URL, e.g. /api/outputs/tool-id/abc12345_output.png
|
|
154
|
+
}
|
|
155
|
+
```
|
|
156
|
+
|
|
157
|
+
### Accessing outputs
|
|
158
|
+
|
|
159
|
+
Output `path` values are **relative URLs**. Use `client.resolveUrl()` to get the full URL for downloading or displaying:
|
|
160
|
+
|
|
161
|
+
```ts
|
|
162
|
+
for (const output of result.outputs) {
|
|
163
|
+
const url = client.resolveUrl(output.path)
|
|
164
|
+
console.log(output.kind, url)
|
|
165
|
+
// e.g. image http://localhost:14173/api/outputs/tool-id/abc12345_output.png
|
|
166
|
+
}
|
|
167
|
+
```
|
|
168
|
+
|
|
169
|
+
### Downloading an output to disk
|
|
170
|
+
|
|
171
|
+
```ts
|
|
172
|
+
import { writeFileSync } from 'fs'
|
|
173
|
+
import path from 'path'
|
|
174
|
+
|
|
175
|
+
for (const output of result.outputs) {
|
|
176
|
+
const url = client.resolveUrl(output.path)
|
|
177
|
+
const res = await fetch(url, {
|
|
178
|
+
headers: { Cookie: `fs_session=${token}` },
|
|
179
|
+
})
|
|
180
|
+
const buffer = Buffer.from(await res.arrayBuffer())
|
|
181
|
+
writeFileSync(path.basename(output.filename), buffer)
|
|
182
|
+
console.log('Saved', output.filename)
|
|
183
|
+
}
|
|
184
|
+
```
|
|
185
|
+
|
|
186
|
+
### Progress callback
|
|
187
|
+
|
|
188
|
+
```ts
|
|
189
|
+
const result = await client.tools.run('your-tool-id', inputs, {
|
|
190
|
+
onProgress: (status) => console.log('[progress]', status),
|
|
191
|
+
timeout: 120_000, // override the client default for this call
|
|
192
|
+
})
|
|
193
|
+
```
|
|
194
|
+
|
|
195
|
+
`onProgress` is called with `'running'` when the job starts and `'completed'` when it finishes. For API-engine tools it is also called on each poll cycle.
|
|
196
|
+
|
|
197
|
+
---
|
|
198
|
+
|
|
199
|
+
## Error handling
|
|
200
|
+
|
|
201
|
+
`tools.run()` throws a plain `Error` on failure. The message is either the error from FlowScale or a timeout message.
|
|
202
|
+
|
|
203
|
+
```ts
|
|
204
|
+
try {
|
|
205
|
+
const result = await client.tools.run('your-tool-id', inputs)
|
|
206
|
+
console.log('outputs:', result.outputs)
|
|
207
|
+
} catch (err) {
|
|
208
|
+
if (err instanceof Error) {
|
|
209
|
+
console.error('Tool failed:', err.message)
|
|
210
|
+
// Possible messages:
|
|
211
|
+
// - 'Tool not found'
|
|
212
|
+
// - 'No ComfyUI port configured for this tool'
|
|
213
|
+
// - 'ComfyUI reported an error'
|
|
214
|
+
// - 'Execution timed out after 300s'
|
|
215
|
+
// - Node-level error details from ComfyUI
|
|
216
|
+
}
|
|
217
|
+
}
|
|
218
|
+
```
|
|
219
|
+
|
|
220
|
+
`login()` throws with the server's error message on bad credentials, disabled account, or network failure.
|
|
221
|
+
|
|
222
|
+
---
|
|
223
|
+
|
|
224
|
+
## Image inputs
|
|
225
|
+
|
|
226
|
+
For tools with `paramType: 'image'` inputs, you need to upload the image to the ComfyUI instance first, then pass the returned filename as the input value.
|
|
227
|
+
|
|
228
|
+
First discover which ComfyUI port the tool uses:
|
|
229
|
+
|
|
230
|
+
```ts
|
|
231
|
+
const tool = await client.tools.get('your-tool-id')
|
|
232
|
+
const comfyPort = tool.comfyPort // e.g. 8188
|
|
233
|
+
```
|
|
234
|
+
|
|
235
|
+
Then upload the image via the ComfyUI proxy:
|
|
236
|
+
|
|
237
|
+
```ts
|
|
238
|
+
import { readFileSync } from 'fs'
|
|
239
|
+
|
|
240
|
+
async function uploadImage(
|
|
241
|
+
baseUrl: string,
|
|
242
|
+
token: string,
|
|
243
|
+
comfyPort: number,
|
|
244
|
+
filePath: string,
|
|
245
|
+
): Promise<string> {
|
|
246
|
+
const fileBuffer = readFileSync(filePath)
|
|
247
|
+
const filename = path.basename(filePath)
|
|
248
|
+
|
|
249
|
+
const form = new FormData()
|
|
250
|
+
form.append('image', new Blob([fileBuffer]), filename)
|
|
251
|
+
form.append('overwrite', 'true')
|
|
252
|
+
|
|
253
|
+
const res = await fetch(`${baseUrl}/api/comfy/${comfyPort}/upload/image`, {
|
|
254
|
+
method: 'POST',
|
|
255
|
+
headers: { Cookie: `fs_session=${token}` },
|
|
256
|
+
body: form,
|
|
257
|
+
})
|
|
258
|
+
if (!res.ok) throw new Error(`Upload failed: ${res.statusText}`)
|
|
259
|
+
const data = await res.json() as { name: string }
|
|
260
|
+
return data.name // filename to pass as input
|
|
261
|
+
}
|
|
262
|
+
|
|
263
|
+
// Then run the tool:
|
|
264
|
+
const uploadedFilename = await uploadImage(
|
|
265
|
+
'http://localhost:14173',
|
|
266
|
+
token,
|
|
267
|
+
tool.comfyPort,
|
|
268
|
+
'./photo.jpg',
|
|
269
|
+
)
|
|
270
|
+
|
|
271
|
+
const result = await client.tools.run('your-tool-id', {
|
|
272
|
+
'10__image': uploadedFilename,
|
|
273
|
+
})
|
|
274
|
+
```
|
|
275
|
+
|
|
276
|
+
---
|
|
277
|
+
|
|
278
|
+
## Full example — text-to-image script
|
|
279
|
+
|
|
280
|
+
```ts
|
|
281
|
+
import { login, createClient } from '@flowscale/sdk'
|
|
282
|
+
import { writeFileSync } from 'fs'
|
|
283
|
+
import path from 'path'
|
|
284
|
+
|
|
285
|
+
const BASE = 'http://localhost:14173'
|
|
286
|
+
|
|
287
|
+
async function main() {
|
|
288
|
+
// 1. Authenticate
|
|
289
|
+
const token = await login({ baseUrl: BASE, username: 'admin', password: 'your-password' })
|
|
290
|
+
const client = createClient({ baseUrl: BASE, sessionToken: token })
|
|
291
|
+
|
|
292
|
+
// 2. List available tools
|
|
293
|
+
const tools = await client.tools.list()
|
|
294
|
+
console.log('Available tools:', tools.map(t => `${t.name} (${t.id})`))
|
|
295
|
+
|
|
296
|
+
// 3. Inspect a tool's inputs
|
|
297
|
+
const tool = tools[0]
|
|
298
|
+
const schema = JSON.parse(tool.schemaJson)
|
|
299
|
+
console.log('Inputs:')
|
|
300
|
+
for (const field of schema.filter((f: { isInput: boolean }) => f.isInput)) {
|
|
301
|
+
console.log(` ${field.nodeId}__${field.paramName} (${field.paramType})`)
|
|
302
|
+
}
|
|
303
|
+
|
|
304
|
+
// 4. Run the tool
|
|
305
|
+
const result = await client.tools.run(tool.id, {
|
|
306
|
+
'6__text': 'a majestic mountain landscape at golden hour',
|
|
307
|
+
'7__text': 'blurry, noise, watermark',
|
|
308
|
+
'5__width': 1024,
|
|
309
|
+
'5__height': 1024,
|
|
310
|
+
'3__steps': 20,
|
|
311
|
+
}, {
|
|
312
|
+
onProgress: (s) => process.stdout.write(`\r${s}...`),
|
|
313
|
+
})
|
|
314
|
+
|
|
315
|
+
console.log('\nDone. Outputs:')
|
|
316
|
+
|
|
317
|
+
// 5. Download outputs
|
|
318
|
+
for (const output of result.outputs) {
|
|
319
|
+
const url = client.resolveUrl(output.path)
|
|
320
|
+
const res = await fetch(url, { headers: { Cookie: `fs_session=${token}` } })
|
|
321
|
+
const buffer = Buffer.from(await res.arrayBuffer())
|
|
322
|
+
const outFile = `output_${output.filename}`
|
|
323
|
+
writeFileSync(outFile, buffer)
|
|
324
|
+
console.log(` Saved ${outFile} (${output.kind})`)
|
|
325
|
+
}
|
|
326
|
+
}
|
|
327
|
+
|
|
328
|
+
main().catch(console.error)
|
|
329
|
+
```
|
|
330
|
+
|
|
331
|
+
---
|
|
332
|
+
|
|
333
|
+
## Full example — Express server wrapping a tool
|
|
334
|
+
|
|
335
|
+
```ts
|
|
336
|
+
import express from 'express'
|
|
337
|
+
import { login, createClient } from '@flowscale/sdk'
|
|
338
|
+
|
|
339
|
+
const app = express()
|
|
340
|
+
app.use(express.json())
|
|
341
|
+
|
|
342
|
+
const BASE = 'http://localhost:14173'
|
|
343
|
+
let client: Awaited<ReturnType<typeof createClient>> | null = null
|
|
344
|
+
|
|
345
|
+
async function getClient() {
|
|
346
|
+
if (!client) {
|
|
347
|
+
const token = await login({ baseUrl: BASE, username: 'admin', password: process.env.FS_PASSWORD! })
|
|
348
|
+
client = createClient({ baseUrl: BASE, sessionToken: token })
|
|
349
|
+
}
|
|
350
|
+
return client
|
|
351
|
+
}
|
|
352
|
+
|
|
353
|
+
app.post('/generate', async (req, res) => {
|
|
354
|
+
try {
|
|
355
|
+
const { prompt, negativePrompt = '' } = req.body as { prompt: string; negativePrompt?: string }
|
|
356
|
+
const c = await getClient()
|
|
357
|
+
|
|
358
|
+
const result = await c.tools.run('your-tool-id', {
|
|
359
|
+
'6__text': prompt,
|
|
360
|
+
'7__text': negativePrompt,
|
|
361
|
+
})
|
|
362
|
+
|
|
363
|
+
const urls = result.outputs.map(o => ({
|
|
364
|
+
kind: o.kind,
|
|
365
|
+
url: c.resolveUrl(o.path),
|
|
366
|
+
}))
|
|
367
|
+
|
|
368
|
+
res.json({ executionId: result.executionId, outputs: urls })
|
|
369
|
+
} catch (err) {
|
|
370
|
+
const message = err instanceof Error ? err.message : 'Unknown error'
|
|
371
|
+
res.status(500).json({ error: message })
|
|
372
|
+
}
|
|
373
|
+
})
|
|
374
|
+
|
|
375
|
+
app.listen(3000, () => console.log('Server running on http://localhost:3000'))
|
|
376
|
+
```
|
|
377
|
+
|
|
378
|
+
---
|
|
379
|
+
|
|
380
|
+
## API reference
|
|
381
|
+
|
|
382
|
+
### `login(opts)`
|
|
383
|
+
|
|
384
|
+
```ts
|
|
385
|
+
login({
|
|
386
|
+
baseUrl: string,
|
|
387
|
+
username: string,
|
|
388
|
+
password: string,
|
|
389
|
+
}): Promise<string> // returns session token
|
|
390
|
+
```
|
|
391
|
+
|
|
392
|
+
Throws if credentials are invalid, the account is pending/disabled, or the server is unreachable.
|
|
393
|
+
|
|
394
|
+
### `createClient(opts)`
|
|
395
|
+
|
|
396
|
+
```ts
|
|
397
|
+
createClient({
|
|
398
|
+
baseUrl: string,
|
|
399
|
+
sessionToken: string,
|
|
400
|
+
timeout?: number, // default 300_000 ms
|
|
401
|
+
pollInterval?: number, // default 2_000 ms
|
|
402
|
+
}): HttpClient
|
|
403
|
+
```
|
|
404
|
+
|
|
405
|
+
### `client.resolveUrl(path)`
|
|
406
|
+
|
|
407
|
+
Prepends `baseUrl` to a relative path. Returns the path unchanged if it is already an absolute URL.
|
|
408
|
+
|
|
409
|
+
### `client.tools.list()`
|
|
410
|
+
|
|
411
|
+
Returns all tools with `status = 'production'`. Each item includes the raw DB row with `id`, `name`, `description`, `schemaJson`, `comfyPort`, `engine`, etc.
|
|
412
|
+
|
|
413
|
+
### `client.tools.get(id)`
|
|
414
|
+
|
|
415
|
+
Returns a single tool by ID. Throws `'Tool not found'` (HTTP 404) if it does not exist.
|
|
416
|
+
|
|
417
|
+
### `client.tools.run(id, inputs, options?)`
|
|
418
|
+
|
|
419
|
+
```ts
|
|
420
|
+
client.tools.run(
|
|
421
|
+
id: string,
|
|
422
|
+
inputs: Record<string, unknown>,
|
|
423
|
+
options?: {
|
|
424
|
+
timeout?: number,
|
|
425
|
+
onProgress?: (status: string) => void,
|
|
426
|
+
}
|
|
427
|
+
): Promise<ToolRunResult>
|
|
428
|
+
```
|
|
429
|
+
|
|
430
|
+
Blocks until the tool completes. Input keys are `"${nodeId}__${paramName}"`. Throws on error or timeout.
|
package/dist/http.d.ts
ADDED
|
@@ -0,0 +1,87 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* HTTP transport for the FlowScale SDK.
|
|
3
|
+
*
|
|
4
|
+
* Use this when building apps that run **outside** FlowScale (e.g. a standalone
|
|
5
|
+
* web app, a Node.js script, or a CLI tool). It talks to a running FlowScale
|
|
6
|
+
* AIOS instance via its REST API instead of the iframe postMessage bridge.
|
|
7
|
+
*
|
|
8
|
+
* @example
|
|
9
|
+
* ```ts
|
|
10
|
+
* import { createClient } from '@flowscale/sdk/http'
|
|
11
|
+
*
|
|
12
|
+
* const client = createClient({
|
|
13
|
+
* baseUrl: 'http://localhost:14173',
|
|
14
|
+
* sessionToken: '<your-fs_session-cookie>', // POST /api/auth/login to obtain one
|
|
15
|
+
* })
|
|
16
|
+
*
|
|
17
|
+
* const result = await client.tools.run('sdxl-txt2img', {
|
|
18
|
+
* '6.text': 'a cat on the moon',
|
|
19
|
+
* })
|
|
20
|
+
* console.log(result.outputs) // [{ kind, filename, path }]
|
|
21
|
+
*
|
|
22
|
+
* // Prepend baseUrl to relative paths for direct access:
|
|
23
|
+
* const imageUrl = client.resolveUrl(result.outputs[0].path)
|
|
24
|
+
* ```
|
|
25
|
+
*/
|
|
26
|
+
import type { ToolDefinition, ToolRunResult } from './types';
|
|
27
|
+
export interface HttpClientOptions {
|
|
28
|
+
/**
|
|
29
|
+
* Base URL of your FlowScale AIOS instance.
|
|
30
|
+
* @example 'http://localhost:14173'
|
|
31
|
+
*/
|
|
32
|
+
baseUrl: string;
|
|
33
|
+
/**
|
|
34
|
+
* API key generated in FlowScale Settings → API Keys.
|
|
35
|
+
* Sent as `Authorization: Bearer <apiKey>` on every request.
|
|
36
|
+
* Use this instead of `sessionToken` for keyless external access.
|
|
37
|
+
* @example 'fs_abc123...'
|
|
38
|
+
*/
|
|
39
|
+
apiKey?: string;
|
|
40
|
+
/**
|
|
41
|
+
* Session token obtained from `POST /api/auth/login`.
|
|
42
|
+
* Sent as the `fs_session` cookie on every request.
|
|
43
|
+
* Not needed when using `apiKey`.
|
|
44
|
+
*/
|
|
45
|
+
sessionToken?: string;
|
|
46
|
+
/**
|
|
47
|
+
* How long (ms) to wait for a tool execution to complete before timing out.
|
|
48
|
+
* @default 300_000 (5 minutes)
|
|
49
|
+
*/
|
|
50
|
+
timeout?: number;
|
|
51
|
+
/**
|
|
52
|
+
* How often (ms) to poll for execution status.
|
|
53
|
+
* @default 2_000
|
|
54
|
+
*/
|
|
55
|
+
pollInterval?: number;
|
|
56
|
+
}
|
|
57
|
+
export interface LoginOptions {
|
|
58
|
+
baseUrl: string;
|
|
59
|
+
username: string;
|
|
60
|
+
password: string;
|
|
61
|
+
}
|
|
62
|
+
/** Log in and return a session token without creating a full client. */
|
|
63
|
+
export declare function login(opts: LoginOptions): Promise<string>;
|
|
64
|
+
export interface HttpClient {
|
|
65
|
+
/** Resolve a relative output path (e.g. `/api/outputs/...`) to a full URL. */
|
|
66
|
+
resolveUrl(path: string): string;
|
|
67
|
+
tools: {
|
|
68
|
+
/** List all production tools. */
|
|
69
|
+
list(): Promise<ToolDefinition[]>;
|
|
70
|
+
/** Get a single tool by ID. */
|
|
71
|
+
get(id: string): Promise<ToolDefinition>;
|
|
72
|
+
/**
|
|
73
|
+
* Run a tool and wait for it to complete.
|
|
74
|
+
*
|
|
75
|
+
* For ComfyUI tools, inputs use `"${nodeId}__${paramName}"` keys.
|
|
76
|
+
* For registry tools, inputs use `"${nodeId}.${paramName}"` keys.
|
|
77
|
+
* Image inputs can be passed as base64 data URLs (`data:image/png;base64,...`).
|
|
78
|
+
*/
|
|
79
|
+
run(id: string, inputs: Record<string, unknown>, options?: {
|
|
80
|
+
timeout?: number;
|
|
81
|
+
onProgress?: (status: string) => void;
|
|
82
|
+
}): Promise<ToolRunResult>;
|
|
83
|
+
};
|
|
84
|
+
}
|
|
85
|
+
/** Create an HTTP client connected to a FlowScale AIOS instance. */
|
|
86
|
+
export declare function createClient(options: HttpClientOptions): HttpClient;
|
|
87
|
+
//# sourceMappingURL=http.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"http.d.ts","sourceRoot":"","sources":["../src/http.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;GAwBG;AAEH,OAAO,KAAK,EAAE,cAAc,EAAE,aAAa,EAAkB,MAAM,SAAS,CAAC;AAE7E,MAAM,WAAW,iBAAiB;IAChC;;;OAGG;IACH,OAAO,EAAE,MAAM,CAAC;IAChB;;;;;OAKG;IACH,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB;;;;OAIG;IACH,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB;;;OAGG;IACH,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB;;;OAGG;IACH,YAAY,CAAC,EAAE,MAAM,CAAC;CACvB;AAED,MAAM,WAAW,YAAY;IAC3B,OAAO,EAAE,MAAM,CAAC;IAChB,QAAQ,EAAE,MAAM,CAAC;IACjB,QAAQ,EAAE,MAAM,CAAC;CAClB;AAED,wEAAwE;AACxE,wBAAsB,KAAK,CAAC,IAAI,EAAE,YAAY,GAAG,OAAO,CAAC,MAAM,CAAC,CAe/D;AAED,MAAM,WAAW,UAAU;IACzB,8EAA8E;IAC9E,UAAU,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,CAAC;IACjC,KAAK,EAAE;QACL,iCAAiC;QACjC,IAAI,IAAI,OAAO,CAAC,cAAc,EAAE,CAAC,CAAC;QAClC,+BAA+B;QAC/B,GAAG,CAAC,EAAE,EAAE,MAAM,GAAG,OAAO,CAAC,cAAc,CAAC,CAAC;QACzC;;;;;;WAMG;QACH,GAAG,CACD,EAAE,EAAE,MAAM,EACV,MAAM,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,EAC/B,OAAO,CAAC,EAAE;YAAE,OAAO,CAAC,EAAE,MAAM,CAAC;YAAC,UAAU,CAAC,EAAE,CAAC,MAAM,EAAE,MAAM,KAAK,IAAI,CAAA;SAAE,GACpE,OAAO,CAAC,aAAa,CAAC,CAAC;KAC3B,CAAC;CACH;AAMD,oEAAoE;AACpE,wBAAgB,YAAY,CAAC,OAAO,EAAE,iBAAiB,GAAG,UAAU,CAoHnE"}
|
package/dist/http.js
ADDED
|
@@ -0,0 +1,140 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
/**
|
|
3
|
+
* HTTP transport for the FlowScale SDK.
|
|
4
|
+
*
|
|
5
|
+
* Use this when building apps that run **outside** FlowScale (e.g. a standalone
|
|
6
|
+
* web app, a Node.js script, or a CLI tool). It talks to a running FlowScale
|
|
7
|
+
* AIOS instance via its REST API instead of the iframe postMessage bridge.
|
|
8
|
+
*
|
|
9
|
+
* @example
|
|
10
|
+
* ```ts
|
|
11
|
+
* import { createClient } from '@flowscale/sdk/http'
|
|
12
|
+
*
|
|
13
|
+
* const client = createClient({
|
|
14
|
+
* baseUrl: 'http://localhost:14173',
|
|
15
|
+
* sessionToken: '<your-fs_session-cookie>', // POST /api/auth/login to obtain one
|
|
16
|
+
* })
|
|
17
|
+
*
|
|
18
|
+
* const result = await client.tools.run('sdxl-txt2img', {
|
|
19
|
+
* '6.text': 'a cat on the moon',
|
|
20
|
+
* })
|
|
21
|
+
* console.log(result.outputs) // [{ kind, filename, path }]
|
|
22
|
+
*
|
|
23
|
+
* // Prepend baseUrl to relative paths for direct access:
|
|
24
|
+
* const imageUrl = client.resolveUrl(result.outputs[0].path)
|
|
25
|
+
* ```
|
|
26
|
+
*/
|
|
27
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
28
|
+
exports.login = login;
|
|
29
|
+
exports.createClient = createClient;
|
|
30
|
+
/** Log in and return a session token without creating a full client. */
|
|
31
|
+
async function login(opts) {
|
|
32
|
+
const res = await fetch(`${opts.baseUrl}/api/auth/login`, {
|
|
33
|
+
method: 'POST',
|
|
34
|
+
headers: { 'Content-Type': 'application/json' },
|
|
35
|
+
body: JSON.stringify({ username: opts.username, password: opts.password }),
|
|
36
|
+
});
|
|
37
|
+
if (!res.ok) {
|
|
38
|
+
const err = await res.json().catch(() => ({ error: res.statusText }));
|
|
39
|
+
throw new Error(err.error ?? `Login failed: HTTP ${res.status}`);
|
|
40
|
+
}
|
|
41
|
+
// Session token comes back as a Set-Cookie header (fs_session=<token>)
|
|
42
|
+
const cookie = res.headers.get('set-cookie') ?? '';
|
|
43
|
+
const match = cookie.match(/fs_session=([^;]+)/);
|
|
44
|
+
if (!match)
|
|
45
|
+
throw new Error('No session token in login response');
|
|
46
|
+
return match[1];
|
|
47
|
+
}
|
|
48
|
+
function sleep(ms) {
|
|
49
|
+
return new Promise((resolve) => setTimeout(resolve, ms));
|
|
50
|
+
}
|
|
51
|
+
/** Create an HTTP client connected to a FlowScale AIOS instance. */
|
|
52
|
+
function createClient(options) {
|
|
53
|
+
const { baseUrl, sessionToken, apiKey, timeout: defaultTimeout = 300000, pollInterval = 2000, } = options;
|
|
54
|
+
if (!apiKey && !sessionToken) {
|
|
55
|
+
throw new Error('createClient requires either apiKey or sessionToken');
|
|
56
|
+
}
|
|
57
|
+
const authHeaders = apiKey
|
|
58
|
+
? { Authorization: `Bearer ${apiKey}` }
|
|
59
|
+
: { Cookie: `fs_session=${sessionToken}` };
|
|
60
|
+
async function apiFetch(path, init) {
|
|
61
|
+
const res = await fetch(`${baseUrl}${path}`, {
|
|
62
|
+
...init,
|
|
63
|
+
headers: {
|
|
64
|
+
'Content-Type': 'application/json',
|
|
65
|
+
...authHeaders,
|
|
66
|
+
...(init?.headers ?? {}),
|
|
67
|
+
},
|
|
68
|
+
});
|
|
69
|
+
if (!res.ok) {
|
|
70
|
+
const err = await res.json().catch(() => ({ error: res.statusText }));
|
|
71
|
+
throw new Error(err.error ?? `HTTP ${res.status} ${path}`);
|
|
72
|
+
}
|
|
73
|
+
return res.json();
|
|
74
|
+
}
|
|
75
|
+
function resolveUrl(path) {
|
|
76
|
+
if (path.startsWith('http://') || path.startsWith('https://'))
|
|
77
|
+
return path;
|
|
78
|
+
return `${baseUrl}${path}`;
|
|
79
|
+
}
|
|
80
|
+
const tools = {
|
|
81
|
+
async list() {
|
|
82
|
+
return apiFetch('/api/tools?status=production');
|
|
83
|
+
},
|
|
84
|
+
async get(id) {
|
|
85
|
+
return apiFetch(`/api/tools/${id}`);
|
|
86
|
+
},
|
|
87
|
+
async run(id, inputs, runOptions = {}) {
|
|
88
|
+
const { timeout = defaultTimeout, onProgress } = runOptions;
|
|
89
|
+
onProgress?.('running');
|
|
90
|
+
// ?wait=true — server polls ComfyUI internally and returns only when done.
|
|
91
|
+
// For API-engine tools the server also runs to completion before responding.
|
|
92
|
+
// Either way we get back a finished execution row directly.
|
|
93
|
+
const execution = await apiFetch(`/api/tools/${id}/executions?wait=true`, {
|
|
94
|
+
method: 'POST',
|
|
95
|
+
body: JSON.stringify({ inputs }),
|
|
96
|
+
signal: AbortSignal.timeout(timeout),
|
|
97
|
+
});
|
|
98
|
+
if (execution.error)
|
|
99
|
+
throw new Error(execution.error);
|
|
100
|
+
// API-engine tools still return 202 immediately — poll the execution record
|
|
101
|
+
if (execution.status === 'running' && execution.executionId) {
|
|
102
|
+
const executionId = execution.executionId;
|
|
103
|
+
const deadline = Date.now() + timeout;
|
|
104
|
+
while (Date.now() < deadline) {
|
|
105
|
+
await sleep(pollInterval);
|
|
106
|
+
const row = await apiFetch(`/api/executions/${executionId}`);
|
|
107
|
+
if (row.status === 'completed') {
|
|
108
|
+
onProgress?.('completed');
|
|
109
|
+
let outputs = [];
|
|
110
|
+
try {
|
|
111
|
+
outputs = JSON.parse(row.outputsJson ?? '[]');
|
|
112
|
+
}
|
|
113
|
+
catch { /* empty */ }
|
|
114
|
+
return { executionId, toolId: id, status: 'completed', outputs };
|
|
115
|
+
}
|
|
116
|
+
if (row.status === 'error')
|
|
117
|
+
throw new Error(row.errorMessage ?? 'Execution failed');
|
|
118
|
+
onProgress?.(row.status);
|
|
119
|
+
}
|
|
120
|
+
throw new Error(`Execution timed out after ${timeout / 1000}s`);
|
|
121
|
+
}
|
|
122
|
+
if (execution.status === 'error')
|
|
123
|
+
throw new Error(execution.errorMessage ?? 'Execution failed');
|
|
124
|
+
onProgress?.('completed');
|
|
125
|
+
let outputs = [];
|
|
126
|
+
try {
|
|
127
|
+
outputs = JSON.parse(execution.outputsJson ?? '[]');
|
|
128
|
+
}
|
|
129
|
+
catch { /* empty */ }
|
|
130
|
+
return {
|
|
131
|
+
executionId: execution.id,
|
|
132
|
+
toolId: id,
|
|
133
|
+
status: 'completed',
|
|
134
|
+
outputs,
|
|
135
|
+
};
|
|
136
|
+
},
|
|
137
|
+
};
|
|
138
|
+
return { resolveUrl, tools };
|
|
139
|
+
}
|
|
140
|
+
//# sourceMappingURL=http.js.map
|
package/dist/http.js.map
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"http.js","sourceRoot":"","sources":["../src/http.ts"],"names":[],"mappings":"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"}
|
package/dist/index.d.ts
CHANGED
|
@@ -4,10 +4,13 @@ export { providers } from './providers';
|
|
|
4
4
|
export { storage } from './storage';
|
|
5
5
|
export { ui } from './ui';
|
|
6
6
|
export { app } from './app';
|
|
7
|
+
export { createClient, login } from './http';
|
|
8
|
+
export type { HttpClient, HttpClientOptions, LoginOptions } from './http';
|
|
7
9
|
export * from './types';
|
|
8
10
|
/** Convenience default export with all namespaces. */
|
|
9
11
|
declare const FlowScale: {
|
|
10
12
|
readonly tools: {
|
|
13
|
+
outputRef(output: import("./types").ToolOutputItem): import("./types").OutputRef;
|
|
11
14
|
list(): Promise<import("./types").ToolDefinition[]>;
|
|
12
15
|
get(id: string): Promise<import("./types").ToolDefinition>;
|
|
13
16
|
run(id: string, inputs: Record<string, unknown>, options?: import("./types").ToolRunOptions): Promise<import("./types").ToolRunResult>;
|
package/dist/index.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,MAAM,EAAE,MAAM,UAAU,CAAC;AAClC,OAAO,EAAE,KAAK,EAAE,MAAM,SAAS,CAAC;AAChC,OAAO,EAAE,SAAS,EAAE,MAAM,aAAa,CAAC;AACxC,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AACpC,OAAO,EAAE,EAAE,EAAE,MAAM,MAAM,CAAC;AAC1B,OAAO,EAAE,GAAG,EAAE,MAAM,OAAO,CAAC;AAC5B,cAAc,SAAS,CAAC;AAQxB,sDAAsD;AACtD,QAAA,MAAM,SAAS
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,MAAM,EAAE,MAAM,UAAU,CAAC;AAClC,OAAO,EAAE,KAAK,EAAE,MAAM,SAAS,CAAC;AAChC,OAAO,EAAE,SAAS,EAAE,MAAM,aAAa,CAAC;AACxC,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AACpC,OAAO,EAAE,EAAE,EAAE,MAAM,MAAM,CAAC;AAC1B,OAAO,EAAE,GAAG,EAAE,MAAM,OAAO,CAAC;AAC5B,OAAO,EAAE,YAAY,EAAE,KAAK,EAAE,MAAM,QAAQ,CAAC;AAC7C,YAAY,EAAE,UAAU,EAAE,iBAAiB,EAAE,YAAY,EAAE,MAAM,QAAQ,CAAC;AAC1E,cAAc,SAAS,CAAC;AAQxB,sDAAsD;AACtD,QAAA,MAAM,SAAS;;;;;;;;;;;;;;;;;;;;;;;;;;;;CAAkD,CAAC;AAClE,eAAe,SAAS,CAAC"}
|
package/dist/index.js
CHANGED
|
@@ -14,7 +14,7 @@ var __exportStar = (this && this.__exportStar) || function(m, exports) {
|
|
|
14
14
|
for (var p in m) if (p !== "default" && !Object.prototype.hasOwnProperty.call(exports, p)) __createBinding(exports, m, p);
|
|
15
15
|
};
|
|
16
16
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
17
|
-
exports.app = exports.ui = exports.storage = exports.providers = exports.tools = exports.bridge = void 0;
|
|
17
|
+
exports.login = exports.createClient = exports.app = exports.ui = exports.storage = exports.providers = exports.tools = exports.bridge = void 0;
|
|
18
18
|
var bridge_1 = require("./bridge");
|
|
19
19
|
Object.defineProperty(exports, "bridge", { enumerable: true, get: function () { return bridge_1.bridge; } });
|
|
20
20
|
var tools_1 = require("./tools");
|
|
@@ -27,6 +27,9 @@ var ui_1 = require("./ui");
|
|
|
27
27
|
Object.defineProperty(exports, "ui", { enumerable: true, get: function () { return ui_1.ui; } });
|
|
28
28
|
var app_1 = require("./app");
|
|
29
29
|
Object.defineProperty(exports, "app", { enumerable: true, get: function () { return app_1.app; } });
|
|
30
|
+
var http_1 = require("./http");
|
|
31
|
+
Object.defineProperty(exports, "createClient", { enumerable: true, get: function () { return http_1.createClient; } });
|
|
32
|
+
Object.defineProperty(exports, "login", { enumerable: true, get: function () { return http_1.login; } });
|
|
30
33
|
__exportStar(require("./types"), exports);
|
|
31
34
|
const tools_2 = require("./tools");
|
|
32
35
|
const providers_2 = require("./providers");
|
package/dist/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":";;;;;;;;;;;;;;;;;AAAA,mCAAkC;AAAzB,gGAAA,MAAM,OAAA;AACf,iCAAgC;AAAvB,8FAAA,KAAK,OAAA;AACd,yCAAwC;AAA/B,sGAAA,SAAS,OAAA;AAClB,qCAAoC;AAA3B,kGAAA,OAAO,OAAA;AAChB,2BAA0B;AAAjB,wFAAA,EAAE,OAAA;AACX,6BAA4B;AAAnB,0FAAA,GAAG,OAAA;AACZ,0CAAwB;AAExB,mCAAgC;AAChC,2CAAwC;AACxC,uCAAoC;AACpC,6BAA0B;AAC1B,+BAA4B;AAE5B,sDAAsD;AACtD,MAAM,SAAS,GAAG,EAAE,KAAK,EAAL,aAAK,EAAE,SAAS,EAAT,qBAAS,EAAE,OAAO,EAAP,iBAAO,EAAE,EAAE,EAAF,OAAE,EAAE,GAAG,EAAH,SAAG,EAAW,CAAC;AAClE,kBAAe,SAAS,CAAC"}
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":";;;;;;;;;;;;;;;;;AAAA,mCAAkC;AAAzB,gGAAA,MAAM,OAAA;AACf,iCAAgC;AAAvB,8FAAA,KAAK,OAAA;AACd,yCAAwC;AAA/B,sGAAA,SAAS,OAAA;AAClB,qCAAoC;AAA3B,kGAAA,OAAO,OAAA;AAChB,2BAA0B;AAAjB,wFAAA,EAAE,OAAA;AACX,6BAA4B;AAAnB,0FAAA,GAAG,OAAA;AACZ,+BAA6C;AAApC,oGAAA,YAAY,OAAA;AAAE,6FAAA,KAAK,OAAA;AAE5B,0CAAwB;AAExB,mCAAgC;AAChC,2CAAwC;AACxC,uCAAoC;AACpC,6BAA0B;AAC1B,+BAA4B;AAE5B,sDAAsD;AACtD,MAAM,SAAS,GAAG,EAAE,KAAK,EAAL,aAAK,EAAE,SAAS,EAAT,qBAAS,EAAE,OAAO,EAAP,iBAAO,EAAE,EAAE,EAAF,OAAE,EAAE,GAAG,EAAH,SAAG,EAAW,CAAC;AAClE,kBAAe,SAAS,CAAC"}
|
package/dist/tools.d.ts
CHANGED
|
@@ -1,5 +1,11 @@
|
|
|
1
|
-
import { ToolDefinition, ToolRunOptions, ToolRunResult } from './types';
|
|
1
|
+
import { ToolDefinition, ToolOutputItem, ToolRunOptions, ToolRunResult, OutputRef } from './types';
|
|
2
2
|
export declare const tools: {
|
|
3
|
+
/**
|
|
4
|
+
* Create an output reference for chaining one tool's output into another's input.
|
|
5
|
+
* Pass the returned value as an image input to the next tools.run() call.
|
|
6
|
+
* The bridge handles the ComfyUI output→input transfer server-side.
|
|
7
|
+
*/
|
|
8
|
+
outputRef(output: ToolOutputItem): OutputRef;
|
|
3
9
|
/** List all tools available to this app. */
|
|
4
10
|
list(): Promise<ToolDefinition[]>;
|
|
5
11
|
/** Get a single tool by ID. */
|
package/dist/tools.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"tools.d.ts","sourceRoot":"","sources":["../src/tools.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,cAAc,EAAE,cAAc,EAAE,aAAa,EAAE,MAAM,SAAS,CAAC;
|
|
1
|
+
{"version":3,"file":"tools.d.ts","sourceRoot":"","sources":["../src/tools.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,cAAc,EAAE,cAAc,EAAE,cAAc,EAAE,aAAa,EAAE,SAAS,EAAE,MAAM,SAAS,CAAC;AAEnG,eAAO,MAAM,KAAK;IAChB;;;;OAIG;sBACe,cAAc,GAAG,SAAS;IAI5C,4CAA4C;YAC9B,OAAO,CAAC,cAAc,EAAE,CAAC;IAIvC,+BAA+B;YACjB,MAAM,GAAG,OAAO,CAAC,cAAc,CAAC;IAI9C,2CAA2C;YAErC,MAAM,UACF,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,YACtB,cAAc,GACtB,OAAO,CAAC,aAAa,CAAC;CAiB1B,CAAC"}
|
package/dist/tools.js
CHANGED
|
@@ -3,6 +3,14 @@ Object.defineProperty(exports, "__esModule", { value: true });
|
|
|
3
3
|
exports.tools = void 0;
|
|
4
4
|
const bridge_1 = require("./bridge");
|
|
5
5
|
exports.tools = {
|
|
6
|
+
/**
|
|
7
|
+
* Create an output reference for chaining one tool's output into another's input.
|
|
8
|
+
* Pass the returned value as an image input to the next tools.run() call.
|
|
9
|
+
* The bridge handles the ComfyUI output→input transfer server-side.
|
|
10
|
+
*/
|
|
11
|
+
outputRef(output) {
|
|
12
|
+
return { __comfy_output__: { filename: output.filename, subfolder: output.subfolder } };
|
|
13
|
+
},
|
|
6
14
|
/** List all tools available to this app. */
|
|
7
15
|
async list() {
|
|
8
16
|
return bridge_1.bridge.call('tools.list');
|
package/dist/tools.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"tools.js","sourceRoot":"","sources":["../src/tools.ts"],"names":[],"mappings":";;;AAAA,qCAAkC;AAGrB,QAAA,KAAK,GAAG;IACnB,4CAA4C;IAC5C,KAAK,CAAC,IAAI;QACR,OAAO,eAAM,CAAC,IAAI,CAAmB,YAAY,CAAC,CAAC;IACrD,CAAC;IAED,+BAA+B;IAC/B,KAAK,CAAC,GAAG,CAAC,EAAU;QAClB,OAAO,eAAM,CAAC,IAAI,CAAiB,WAAW,EAAE,EAAE,EAAE,EAAE,CAAC,CAAC;IAC1D,CAAC;IAED,2CAA2C;IAC3C,KAAK,CAAC,GAAG,CACP,EAAU,EACV,MAA+B,EAC/B,UAA0B,EAAE;QAE5B,MAAM,EAAE,OAAO,EAAE,UAAU,EAAE,GAAG,OAAO,CAAC;QAExC,IAAI,WAAqC,CAAC;QAC1C,IAAI,UAAU,EAAE,CAAC;YACf,WAAW,GAAG,eAAM,CAAC,EAAE,CAAC,kBAAkB,EAAE,EAAE,EAAE,CAAC,MAAM,EAAE,EAAE;gBACzD,MAAM,CAAC,GAAG,MAAgD,CAAC;gBAC3D,UAAU,CAAC,CAAC,CAAC,QAAQ,EAAE,CAAC,CAAC,OAAO,CAAC,CAAC;YACpC,CAAC,CAAC,CAAC;QACL,CAAC;QAED,IAAI,CAAC;YACH,OAAO,MAAM,eAAM,CAAC,IAAI,CAAgB,WAAW,EAAE,EAAE,EAAE,EAAE,MAAM,EAAE,EAAE,OAAO,CAAC,CAAC;QAChF,CAAC;gBAAS,CAAC;YACT,WAAW,EAAE,EAAE,CAAC;QAClB,CAAC;IACH,CAAC;CACF,CAAC"}
|
|
1
|
+
{"version":3,"file":"tools.js","sourceRoot":"","sources":["../src/tools.ts"],"names":[],"mappings":";;;AAAA,qCAAkC;AAGrB,QAAA,KAAK,GAAG;IACnB;;;;OAIG;IACH,SAAS,CAAC,MAAsB;QAC9B,OAAO,EAAE,gBAAgB,EAAE,EAAE,QAAQ,EAAE,MAAM,CAAC,QAAQ,EAAE,SAAS,EAAE,MAAM,CAAC,SAAS,EAAE,EAAE,CAAC;IAC1F,CAAC;IAED,4CAA4C;IAC5C,KAAK,CAAC,IAAI;QACR,OAAO,eAAM,CAAC,IAAI,CAAmB,YAAY,CAAC,CAAC;IACrD,CAAC;IAED,+BAA+B;IAC/B,KAAK,CAAC,GAAG,CAAC,EAAU;QAClB,OAAO,eAAM,CAAC,IAAI,CAAiB,WAAW,EAAE,EAAE,EAAE,EAAE,CAAC,CAAC;IAC1D,CAAC;IAED,2CAA2C;IAC3C,KAAK,CAAC,GAAG,CACP,EAAU,EACV,MAA+B,EAC/B,UAA0B,EAAE;QAE5B,MAAM,EAAE,OAAO,EAAE,UAAU,EAAE,GAAG,OAAO,CAAC;QAExC,IAAI,WAAqC,CAAC;QAC1C,IAAI,UAAU,EAAE,CAAC;YACf,WAAW,GAAG,eAAM,CAAC,EAAE,CAAC,kBAAkB,EAAE,EAAE,EAAE,CAAC,MAAM,EAAE,EAAE;gBACzD,MAAM,CAAC,GAAG,MAAgD,CAAC;gBAC3D,UAAU,CAAC,CAAC,CAAC,QAAQ,EAAE,CAAC,CAAC,OAAO,CAAC,CAAC;YACpC,CAAC,CAAC,CAAC;QACL,CAAC;QAED,IAAI,CAAC;YACH,OAAO,MAAM,eAAM,CAAC,IAAI,CAAgB,WAAW,EAAE,EAAE,EAAE,EAAE,MAAM,EAAE,EAAE,OAAO,CAAC,CAAC;QAChF,CAAC;gBAAS,CAAC;YACT,WAAW,EAAE,EAAE,CAAC;QAClB,CAAC;IACH,CAAC;CACF,CAAC"}
|
package/dist/types.d.ts
CHANGED
|
@@ -53,9 +53,34 @@ export interface ToolRunOptions {
|
|
|
53
53
|
timeout?: number;
|
|
54
54
|
onProgress?: (progress: number, message?: string) => void;
|
|
55
55
|
}
|
|
56
|
+
export interface ToolOutputItem {
|
|
57
|
+
kind: 'image' | 'video' | 'audio' | 'file';
|
|
58
|
+
filename: string;
|
|
59
|
+
subfolder: string;
|
|
60
|
+
/** Relative URL served by the host — use directly in <img src> or fetch() */
|
|
61
|
+
path: string;
|
|
62
|
+
}
|
|
63
|
+
/**
|
|
64
|
+
* Pass as an image input to FlowScale.tools.run() to chain the output of one
|
|
65
|
+
* step into the input of the next. The bridge handles the transfer server-side.
|
|
66
|
+
*
|
|
67
|
+
* @example
|
|
68
|
+
* const step1 = await FlowScale.tools.run(TOOL_A, { '1__image': dataUrl })
|
|
69
|
+
* const step2 = await FlowScale.tools.run(TOOL_B, {
|
|
70
|
+
* '1__image': FlowScale.tools.outputRef(step1.outputs[0]),
|
|
71
|
+
* })
|
|
72
|
+
*/
|
|
73
|
+
export interface OutputRef {
|
|
74
|
+
__comfy_output__: {
|
|
75
|
+
filename: string;
|
|
76
|
+
subfolder: string;
|
|
77
|
+
};
|
|
78
|
+
}
|
|
56
79
|
export interface ToolRunResult {
|
|
57
|
-
|
|
58
|
-
|
|
80
|
+
executionId: string;
|
|
81
|
+
toolId: string;
|
|
82
|
+
status: 'completed';
|
|
83
|
+
outputs: ToolOutputItem[];
|
|
59
84
|
}
|
|
60
85
|
export type ProviderName = 'fal' | 'replicate' | 'openrouter' | 'huggingface';
|
|
61
86
|
export interface ProviderStatus {
|
package/dist/types.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":"AAEA,MAAM,WAAW,cAAc;IAC7B,OAAO,EAAE,KAAK,CAAC;IACf,EAAE,EAAE,MAAM,GAAG,MAAM,CAAC;IACpB,MAAM,EAAE,MAAM,CAAC;IACf,MAAM,CAAC,EAAE,OAAO,CAAC;CAClB;AAED,MAAM,WAAW,eAAe;IAC9B,OAAO,EAAE,KAAK,CAAC;IACf,EAAE,EAAE,MAAM,GAAG,MAAM,CAAC;IACpB,MAAM,CAAC,EAAE,OAAO,CAAC;IACjB,KAAK,CAAC,EAAE,YAAY,CAAC;CACtB;AAED,MAAM,WAAW,YAAY;IAC3B,IAAI,EAAE,MAAM,CAAC;IACb,OAAO,EAAE,MAAM,CAAC;IAChB,IAAI,CAAC,EAAE,OAAO,CAAC;CAChB;AAED,MAAM,MAAM,cAAc,GAAG,cAAc,GAAG,eAAe,CAAC;AAI9D,eAAO,MAAM,SAAS;;;;;;;CAOZ,CAAC;AAIX,MAAM,WAAW,SAAS;IACxB,IAAI,EAAE,MAAM,CAAC;IACb,IAAI,EAAE,QAAQ,GAAG,QAAQ,GAAG,SAAS,GAAG,OAAO,GAAG,QAAQ,CAAC;IAC3D,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,QAAQ,CAAC,EAAE,OAAO,CAAC;IACnB,OAAO,CAAC,EAAE,OAAO,CAAC;IAClB,OAAO,CAAC,EAAE,MAAM,EAAE,CAAC;IACnB,GAAG,CAAC,EAAE,MAAM,CAAC;IACb,GAAG,CAAC,EAAE,MAAM,CAAC;IACb,IAAI,CAAC,EAAE,MAAM,CAAC;CACf;AAED,MAAM,WAAW,UAAU;IACzB,IAAI,EAAE,MAAM,CAAC;IACb,IAAI,EAAE,QAAQ,GAAG,QAAQ,GAAG,OAAO,GAAG,MAAM,CAAC;IAC7C,KAAK,CAAC,EAAE,MAAM,CAAC;CAChB;AAED,MAAM,WAAW,cAAc;IAC7B,EAAE,EAAE,MAAM,CAAC;IACX,IAAI,EAAE,MAAM,CAAC;IACb,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,MAAM,EAAE,SAAS,EAAE,CAAC;IACpB,OAAO,EAAE,UAAU,EAAE,CAAC;IACtB,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,OAAO,CAAC,EAAE,MAAM,CAAC;CAClB;AAED,MAAM,WAAW,cAAc;IAC7B,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,UAAU,CAAC,EAAE,CAAC,QAAQ,EAAE,MAAM,EAAE,OAAO,CAAC,EAAE,MAAM,KAAK,IAAI,CAAC;CAC3D;AAED,MAAM,WAAW,
|
|
1
|
+
{"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":"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"}
|
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@flowscale/sdk",
|
|
3
|
-
"version": "1.
|
|
4
|
-
"description": "FlowScale
|
|
3
|
+
"version": "1.2.0",
|
|
4
|
+
"description": "FlowScale AIOS SDK — build apps inside FlowScale or externally via HTTP",
|
|
5
5
|
"license": "AGPL-3.0-only",
|
|
6
6
|
"files": [
|
|
7
7
|
"dist"
|
|
@@ -26,7 +26,7 @@
|
|
|
26
26
|
},
|
|
27
27
|
"repository": {
|
|
28
28
|
"type": "git",
|
|
29
|
-
"url": "git+https://github.com/FlowScale-AI/flowscale-
|
|
29
|
+
"url": "git+https://github.com/FlowScale-AI/flowscale-aios.git"
|
|
30
30
|
},
|
|
31
31
|
"devDependencies": {
|
|
32
32
|
"typescript": "^5.8.3"
|