flow-frame-core 0.1.6 → 0.1.7
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 +32 -0
- package/TOOLS.md +1080 -0
- package/package.json +2 -1
package/README.md
CHANGED
|
@@ -43,6 +43,38 @@ Detailed documentation is available in the `docs/` folder:
|
|
|
43
43
|
- **[Email Automation](docs/email_automation.md)**: Gmail polling and filtering.
|
|
44
44
|
- **[Workflows](docs/workflows.md)**: How to build and run workflows.
|
|
45
45
|
|
|
46
|
+
## 🔧 Tool Reference (for Agent Integration)
|
|
47
|
+
|
|
48
|
+
`flow-frame-core` is designed to be used as a tool library by AI agents. The complete tool glossary is in **[TOOLS.md](./TOOLS.md)**, covering every function and REST endpoint organized by capability:
|
|
49
|
+
|
|
50
|
+
| Category | Tools | Integration |
|
|
51
|
+
|----------|-------|-------------|
|
|
52
|
+
| **LLM / AI** | `runPrompt`, `runPromptGrok`, `runImagePromptGrok` | Import or `POST /api/prompts/chat` |
|
|
53
|
+
| **Prompt Chains** | `executeChain` — serial/parallel steps with auto-repair | Import |
|
|
54
|
+
| **Workflow Engine** | `executeFlow` — 25+ node types in a DAG | Import or REST |
|
|
55
|
+
| **JSON Utilities** | `extractJSON`, `cleanJSONString`, `containsJSON` | Import |
|
|
56
|
+
| **Schema & Code Gen** | `inferSchema`, `generateJsTransformFromPrompt` | Import |
|
|
57
|
+
| **Prompt Optimization** | `runAutoPromptSearch` — iterative prompt refinement | Import |
|
|
58
|
+
| **Image Analysis** | `classifyImageQuery`, `findImageInImage` | Import or REST |
|
|
59
|
+
| **Audio / TTS** | `processAudio` — ElevenLabs TTS | Import or `POST /generateAudio` |
|
|
60
|
+
| **PDF Processing** | `extractPdf` — text, images, page renders | Import or `GET /pdf/extract` |
|
|
61
|
+
| **Email** | `extractGmailBodyText`, polling endpoints | Import or REST |
|
|
62
|
+
| **Web Scraping** | `crawl` — full-site depth-first crawl | Import or `POST /scrape` |
|
|
63
|
+
| **Storage** | `getItem`, `setItem`, profile management | Import or REST |
|
|
64
|
+
| **Queue** | `queueManager` — serial job queue with events | Import or REST |
|
|
65
|
+
| **File System** | 30+ file utilities (read, write, download, zip) | Import or REST |
|
|
66
|
+
| **Templates** | `generateTextFromTemplate` — LLM variable generation | Import or REST |
|
|
67
|
+
| **Browser / Desktop** | Chrome control, mouse, keyboard, app management | Import or REST |
|
|
68
|
+
| **Screenshots** | `captureScreenshotBase64`, `captureFullScreenshot` | Import or REST |
|
|
69
|
+
| **Self-Learning Vision** | Ingest, recognize, discover screens, transition graphs | Import or REST |
|
|
70
|
+
| **UI Planning** | `UiPlanner`, `StepByStepAiPlanner` — NL → automation steps | Import |
|
|
71
|
+
| **Workflows CRUD** | Create, load, save, validate `.workflow` files | REST |
|
|
72
|
+
| **Extensions** | Plugin discovery and execution via `api.json` | Import or REST |
|
|
73
|
+
| **Media** | Video/audio dimensions, YOLO training data | Import or REST |
|
|
74
|
+
| **Config** | File-based config CRUD with backup/validation | REST |
|
|
75
|
+
|
|
76
|
+
See **[TOOLS.md](./TOOLS.md)** for full function signatures, parameters, return types, and REST endpoint details.
|
|
77
|
+
|
|
46
78
|
## 🌟 Key Features
|
|
47
79
|
|
|
48
80
|
- **Agentic UI Planning**: Deeply integrated AI that maps web pages and uses `robotjs` to simulate human clicks and typing.
|
package/TOOLS.md
ADDED
|
@@ -0,0 +1,1080 @@
|
|
|
1
|
+
# Flow-Frame Tool Reference
|
|
2
|
+
|
|
3
|
+
> Complete glossary of every capability in `flow-frame-core` that can be used as a tool by an external agent (e.g. Woodbury).
|
|
4
|
+
|
|
5
|
+
**Package**: `flow-frame-core`
|
|
6
|
+
**Install**: `npm install flow-frame-core`
|
|
7
|
+
**Runtime**: Node.js 18+, ESM (`"type": "module"`)
|
|
8
|
+
**Two integration modes**: Import functions directly (programmatic), or run the server and call HTTP endpoints (REST API).
|
|
9
|
+
|
|
10
|
+
---
|
|
11
|
+
|
|
12
|
+
## Table of Contents
|
|
13
|
+
|
|
14
|
+
- [1. LLM / AI](#1-llm--ai)
|
|
15
|
+
- [2. Prompt Chains](#2-prompt-chains)
|
|
16
|
+
- [3. Workflow Engine](#3-workflow-engine)
|
|
17
|
+
- [4. JSON Utilities](#4-json-utilities)
|
|
18
|
+
- [5. Schema & Code Generation](#5-schema--code-generation)
|
|
19
|
+
- [6. Prompt Optimization](#6-prompt-optimization)
|
|
20
|
+
- [7. Image Analysis](#7-image-analysis)
|
|
21
|
+
- [8. Audio / TTS](#8-audio--tts)
|
|
22
|
+
- [9. PDF Processing](#9-pdf-processing)
|
|
23
|
+
- [10. Email](#10-email)
|
|
24
|
+
- [11. Web Scraping](#11-web-scraping)
|
|
25
|
+
- [12. Storage](#12-storage)
|
|
26
|
+
- [13. Queue Management](#13-queue-management)
|
|
27
|
+
- [14. File System Utilities](#14-file-system-utilities)
|
|
28
|
+
- [15. Template & Variable Generation](#15-template--variable-generation)
|
|
29
|
+
- [16. Browser & Desktop Automation](#16-browser--desktop-automation)
|
|
30
|
+
- [17. Screenshot & Screen Capture](#17-screenshot--screen-capture)
|
|
31
|
+
- [18. Self-Learning Vision Pipeline](#18-self-learning-vision-pipeline)
|
|
32
|
+
- [19. UI Automation Planning](#19-ui-automation-planning)
|
|
33
|
+
- [20. Workflow File Management](#20-workflow-file-management)
|
|
34
|
+
- [21. Extension System](#21-extension-system)
|
|
35
|
+
- [22. Media Processing](#22-media-processing)
|
|
36
|
+
- [23. Configuration Management](#23-configuration-management)
|
|
37
|
+
- [24. Constants & Selectors](#24-constants--selectors)
|
|
38
|
+
- [REST API Quick Reference](#rest-api-quick-reference)
|
|
39
|
+
|
|
40
|
+
---
|
|
41
|
+
|
|
42
|
+
## 1. LLM / AI
|
|
43
|
+
|
|
44
|
+
Send prompts to OpenAI or Groq models. All functions auto-route based on model name prefix.
|
|
45
|
+
|
|
46
|
+
### `runPrompt(messages, model, images?, jsonMode?, timeout?)`
|
|
47
|
+
|
|
48
|
+
**Import**: `import { runPrompt } from 'flow-frame-core/services/runPrompt.js'`
|
|
49
|
+
|
|
50
|
+
The unified LLM call. Routes to Groq for non-GPT models, OpenAI otherwise.
|
|
51
|
+
|
|
52
|
+
| Param | Type | Default | Description |
|
|
53
|
+
|-------|------|---------|-------------|
|
|
54
|
+
| `messages` | `{role, content}[]` | required | Chat message array |
|
|
55
|
+
| `model` | `string` | required | Model ID (e.g. `'gpt-4o'`, `'meta-llama/llama-4-scout-17b-16e-instruct'`) |
|
|
56
|
+
| `images` | `string[]` | `[]` | Base64 image data URLs to attach |
|
|
57
|
+
| `jsonMode` | `boolean` | `false` | Request JSON output format |
|
|
58
|
+
| `timeout` | `number` | `600000` | Timeout in ms |
|
|
59
|
+
|
|
60
|
+
**Returns**: `string` — the model's response text.
|
|
61
|
+
|
|
62
|
+
**REST**: `POST /api/prompts/chat`
|
|
63
|
+
```json
|
|
64
|
+
{ "messages": [...], "model": "gpt-4o", "jsonMode": false }
|
|
65
|
+
→ { "success": true, "result": "..." }
|
|
66
|
+
```
|
|
67
|
+
|
|
68
|
+
---
|
|
69
|
+
|
|
70
|
+
### `runPromptGrok(messages, model, jsonMode?, maxRetries?, baseDelay?)`
|
|
71
|
+
|
|
72
|
+
**Import**: `import { runPromptGrok } from 'flow-frame-core'`
|
|
73
|
+
|
|
74
|
+
Groq-specific with exponential backoff retry on 503 capacity errors.
|
|
75
|
+
|
|
76
|
+
| Param | Type | Default | Description |
|
|
77
|
+
|-------|------|---------|-------------|
|
|
78
|
+
| `messages` | `{role, content}[]` | required | Chat messages |
|
|
79
|
+
| `model` | `string` | required | Groq model ID |
|
|
80
|
+
| `jsonMode` | `boolean` | `false` | JSON response mode |
|
|
81
|
+
| `maxRetries` | `number` | `3` | Max retry attempts |
|
|
82
|
+
| `baseDelay` | `number` | `15000` | Base backoff delay in ms |
|
|
83
|
+
|
|
84
|
+
**Returns**: `string` — response content.
|
|
85
|
+
|
|
86
|
+
---
|
|
87
|
+
|
|
88
|
+
### `runImagePromptGrok(prompt, base64_image, model?)`
|
|
89
|
+
|
|
90
|
+
**Import**: `import { runImagePromptGrok } from 'flow-frame-core'`
|
|
91
|
+
|
|
92
|
+
Send a text prompt with an image to Groq's vision model.
|
|
93
|
+
|
|
94
|
+
| Param | Type | Default | Description |
|
|
95
|
+
|-------|------|---------|-------------|
|
|
96
|
+
| `prompt` | `string` | required | Text prompt |
|
|
97
|
+
| `base64_image` | `string` | required | Base64 data URL of the image |
|
|
98
|
+
| `model` | `string` | `'meta-llama/llama-4-scout-17b-16e-instruct'` | Vision model |
|
|
99
|
+
|
|
100
|
+
**Returns**: `string` — response text.
|
|
101
|
+
|
|
102
|
+
**REST**: `POST /analyze-image-grok`
|
|
103
|
+
```json
|
|
104
|
+
{ "prompt": "Describe this image", "base64_image": "data:image/png;base64,..." }
|
|
105
|
+
→ { "result": "..." }
|
|
106
|
+
```
|
|
107
|
+
|
|
108
|
+
---
|
|
109
|
+
|
|
110
|
+
### `processLLMResponse(response, model, provider?)`
|
|
111
|
+
|
|
112
|
+
**Import**: `import { processLLMResponse } from 'flow-frame-core/services/runPrompt.js'`
|
|
113
|
+
|
|
114
|
+
Parse JSON from raw LLM output. On failure, asks the same model to repair the output.
|
|
115
|
+
|
|
116
|
+
| Param | Type | Description |
|
|
117
|
+
|-------|------|-------------|
|
|
118
|
+
| `response` | `string` | Raw LLM text |
|
|
119
|
+
| `model` | `string` | Model to use for repair |
|
|
120
|
+
| `provider` | `string` | `'grok'` or `'openai'` |
|
|
121
|
+
|
|
122
|
+
**Returns**: Parsed object or repaired JSON.
|
|
123
|
+
|
|
124
|
+
---
|
|
125
|
+
|
|
126
|
+
## 2. Prompt Chains
|
|
127
|
+
|
|
128
|
+
Execute multi-step prompt sequences with validation and auto-repair.
|
|
129
|
+
|
|
130
|
+
### `executeChain({ chainDef, prompts, input?, preamble?, precontext?, serverUrl?, model?, logFn?, promptExecutor? })`
|
|
131
|
+
|
|
132
|
+
**Import**: `import { executeChain } from 'flow-frame-core/services/chainExecutor.js'`
|
|
133
|
+
|
|
134
|
+
Runs a chain of prompts in sequence or parallel, accumulating context across steps.
|
|
135
|
+
|
|
136
|
+
| Param | Type | Default | Description |
|
|
137
|
+
|-------|------|---------|-------------|
|
|
138
|
+
| `chainDef` | `object` | required | `{ steps: Step[] }` — each step is `{ promptKey, expectations? }` or an array (parallel block) |
|
|
139
|
+
| `prompts` | `object` | required | Map of prompt keys to prompt text strings |
|
|
140
|
+
| `input` | `string\|object` | `undefined` | Initial input/context |
|
|
141
|
+
| `preamble` | `string` | `undefined` | System preamble prepended to each step |
|
|
142
|
+
| `precontext` | `string` | `undefined` | Additional context |
|
|
143
|
+
| `serverUrl` | `string` | `undefined` | Base URL for API (mutually exclusive with `promptExecutor`) |
|
|
144
|
+
| `model` | `string` | `'gpt-4'` | LLM model ID |
|
|
145
|
+
| `logFn` | `function` | `console.log` | Logging callback |
|
|
146
|
+
| `promptExecutor` | `function` | `null` | Direct prompt execution function (bypasses HTTP) |
|
|
147
|
+
|
|
148
|
+
**Returns**: `{ result: object, history: StepResult[] }`
|
|
149
|
+
|
|
150
|
+
Each step with `expectations` triggers an LLM QA validation loop — if the output doesn't match expectations, a repair agent rewrites it (max 2 retries).
|
|
151
|
+
|
|
152
|
+
**Parallel blocks**: Wrap steps in an array to run them concurrently:
|
|
153
|
+
```js
|
|
154
|
+
{
|
|
155
|
+
steps: [
|
|
156
|
+
{ promptKey: 'step1' }, // serial
|
|
157
|
+
[{ promptKey: 'a' }, { promptKey: 'b' }], // parallel
|
|
158
|
+
{ promptKey: 'step3' } // serial
|
|
159
|
+
]
|
|
160
|
+
}
|
|
161
|
+
```
|
|
162
|
+
|
|
163
|
+
---
|
|
164
|
+
|
|
165
|
+
## 3. Workflow Engine
|
|
166
|
+
|
|
167
|
+
Execute visual node-graph workflows (DAGs).
|
|
168
|
+
|
|
169
|
+
### `executeFlow(nodes, edges, workflows, modelContext, initialCtx?, callback?, globalContext?)`
|
|
170
|
+
|
|
171
|
+
**Import**: `import { executeFlow } from 'flow-frame-core'`
|
|
172
|
+
|
|
173
|
+
The core workflow runtime. Topologically sorts a node-edge graph and executes each node.
|
|
174
|
+
|
|
175
|
+
| Param | Type | Description |
|
|
176
|
+
|-------|------|-------------|
|
|
177
|
+
| `nodes` | `Node[]` | Array of node objects with `{ id, type, data }` |
|
|
178
|
+
| `edges` | `Edge[]` | Array of `{ source, sourceHandle, target, targetHandle }` |
|
|
179
|
+
| `workflows` | `object` | Named workflow configs for subgraph references |
|
|
180
|
+
| `modelContext` | `object` | Configuration: `{ defaultServer?, loadConfiguration?, loadPromptLibrary?, promptExecutor?, extensionController? }` |
|
|
181
|
+
| `initialCtx` | `object` | `{}` — pre-populated node values |
|
|
182
|
+
| `callback` | `function` | `(nodeId, progress) => void` |
|
|
183
|
+
| `globalContext` | `object` | `{}` — shared mutable state across subgraphs |
|
|
184
|
+
|
|
185
|
+
#### Supported Node Types
|
|
186
|
+
|
|
187
|
+
| Node Type | Purpose |
|
|
188
|
+
|-----------|---------|
|
|
189
|
+
| **Data** | |
|
|
190
|
+
| `inputNode` | Reads named input or default value |
|
|
191
|
+
| `setNode` | Sets a key on modelContext |
|
|
192
|
+
| `getNode` | Reads a key from modelContext |
|
|
193
|
+
| `propertyNode` | Deep property access (dot notation) |
|
|
194
|
+
| `arrayItemNode` | Array index access |
|
|
195
|
+
| `inputArrayNode` | Parse raw JSON array |
|
|
196
|
+
| `globalNode` | Write to shared globalContext |
|
|
197
|
+
| `globalGetNode` | Read from globalContext (dot notation + default) |
|
|
198
|
+
| `resultNode` | Capture subgraph output |
|
|
199
|
+
| `outputNode` | POST result to a URL |
|
|
200
|
+
| **AI / Prompts** | |
|
|
201
|
+
| `promptNode` | LLM prompt with system/user/images handles |
|
|
202
|
+
| `autoPromptOptimizerNode` | Find best prompt via iterative search |
|
|
203
|
+
| `uiPlannerNode` | AI-powered UI automation planning |
|
|
204
|
+
| `uiPlannerExecNode` | Execute a UI plan's steps |
|
|
205
|
+
| **Control Flow** | |
|
|
206
|
+
| `switchNode` | Pattern-match input → route to handles |
|
|
207
|
+
| `ifNode` | Conditional branch (inline subgraphs) |
|
|
208
|
+
| `ifWorkflowNode` | Conditional branch (named workflow configs) |
|
|
209
|
+
| `ifGraphNode` | Conditional branch (automation ID match) |
|
|
210
|
+
| `forEachNode` | Iterate array → execute named graph per item |
|
|
211
|
+
| `forLoopNode` | Iterate array → execute inline bodyGraph per item |
|
|
212
|
+
| `pauseNode` | Sleep N seconds |
|
|
213
|
+
| **Network** | |
|
|
214
|
+
| `fetchNode` | HTTP request (method, timeout, body, response type) |
|
|
215
|
+
| `gmailNode` | Read filtered emails |
|
|
216
|
+
| `pollerNode` | Poll emails + LLM-route to labeled subgraphs |
|
|
217
|
+
| **Composition** | |
|
|
218
|
+
| `workflowNode` | Execute named workflow |
|
|
219
|
+
| `smartAutomationNode` | Execute named smart automation |
|
|
220
|
+
| `graphNode` | Load + execute named workflow config |
|
|
221
|
+
| **Code** | |
|
|
222
|
+
| `execJSNode` | Run arbitrary JS (inputs a-g, access to utils/fs/path/$global) |
|
|
223
|
+
| **Extensions** | |
|
|
224
|
+
| `extensionNode` | Resolve + run an extension by capability ID |
|
|
225
|
+
| **UI Map** | |
|
|
226
|
+
| `uiMapSelectorNode` | Generate UI map from workflow files |
|
|
227
|
+
| `uiMapProcessorNode` | Pass-through |
|
|
228
|
+
| `uiMapChatNode` | Return generated context |
|
|
229
|
+
| `uiDependencyGraphNode` | Parse bodyGraph JSON |
|
|
230
|
+
|
|
231
|
+
### `computeExecutionOrder(nodes, edges)`
|
|
232
|
+
|
|
233
|
+
Kahn's topological sort on a node graph. Returns ordered node array.
|
|
234
|
+
|
|
235
|
+
### `getSubgraph(startId, nodes, edges)`
|
|
236
|
+
|
|
237
|
+
BFS extraction of reachable nodes/edges from a start node.
|
|
238
|
+
|
|
239
|
+
---
|
|
240
|
+
|
|
241
|
+
## 4. JSON Utilities
|
|
242
|
+
|
|
243
|
+
Robust JSON extraction from messy LLM output.
|
|
244
|
+
|
|
245
|
+
### `extractJSON(input)`
|
|
246
|
+
|
|
247
|
+
**Import**: `import { extractJSON } from 'flow-frame-core'`
|
|
248
|
+
|
|
249
|
+
Strips markdown fences, prose preambles, and parses JSON. Returns objects as-is.
|
|
250
|
+
|
|
251
|
+
| Param | Type | Description |
|
|
252
|
+
|-------|------|-------------|
|
|
253
|
+
| `input` | `string\|object` | Raw text or object |
|
|
254
|
+
|
|
255
|
+
**Returns**: Parsed object, or `null` on failure.
|
|
256
|
+
|
|
257
|
+
### `cleanJSONString(str)`
|
|
258
|
+
|
|
259
|
+
Strips markdown code fences, text wrappers, normalizes escapes to isolate raw JSON.
|
|
260
|
+
|
|
261
|
+
### `safeExtractJSON(input, options?)`
|
|
262
|
+
|
|
263
|
+
Wraps `extractJSON` with configurable fallback: `{ returnOriginalOnFail?, defaultValue?, throwOnError? }`.
|
|
264
|
+
|
|
265
|
+
### `containsJSON(str)`
|
|
266
|
+
|
|
267
|
+
Returns `true` if string contains parseable JSON.
|
|
268
|
+
|
|
269
|
+
### `extractMultipleJSON(str)`
|
|
270
|
+
|
|
271
|
+
Finds all JSON objects in a string. Returns `object[]`.
|
|
272
|
+
|
|
273
|
+
---
|
|
274
|
+
|
|
275
|
+
## 5. Schema & Code Generation
|
|
276
|
+
|
|
277
|
+
### `inferSchema(prompt, model)`
|
|
278
|
+
|
|
279
|
+
**Import**: `import { inferSchema } from 'flow-frame-core/services/schemaInference.js'`
|
|
280
|
+
|
|
281
|
+
Uses OpenAI to generate a JSON Schema (draft-07) describing what a prompt's output should look like.
|
|
282
|
+
|
|
283
|
+
| Param | Type | Description |
|
|
284
|
+
|-------|------|-------------|
|
|
285
|
+
| `prompt` | `string` | The prompt to analyze |
|
|
286
|
+
| `model` | `string` | OpenAI model to use |
|
|
287
|
+
|
|
288
|
+
**Returns**: Parsed JSON Schema object.
|
|
289
|
+
|
|
290
|
+
---
|
|
291
|
+
|
|
292
|
+
### `generateJsTransformFromPrompt(opts)`
|
|
293
|
+
|
|
294
|
+
**Import**: `import { generateJsTransformFromPrompt } from 'flow-frame-core/services/generateJsTransformFromPrompt.js'`
|
|
295
|
+
|
|
296
|
+
Uses an LLM to generate a sandboxed JavaScript transform function from a natural language description.
|
|
297
|
+
|
|
298
|
+
| Param | Type | Default | Description |
|
|
299
|
+
|-------|------|---------|-------------|
|
|
300
|
+
| `opts.prompt` | `string` | required | Natural language description of the transform |
|
|
301
|
+
| `opts.inputSchema` | `object` | `undefined` | JSON Schema for input validation |
|
|
302
|
+
| `opts.outputSchema` | `object` | `undefined` | JSON Schema for output validation |
|
|
303
|
+
| `opts.examples` | `{input, expected}[]` | `[]` | Test cases |
|
|
304
|
+
| `opts.allowNet` | `boolean` | `false` | Allow network access in sandbox |
|
|
305
|
+
| `opts.maxExecMs` | `number` | `5000` | Sandbox execution timeout |
|
|
306
|
+
| `opts.model` | `string` | `'meta-llama/llama-4-maverick'` | LLM model |
|
|
307
|
+
| `opts.retries` | `number` | `3` | Retry count on failure |
|
|
308
|
+
|
|
309
|
+
**Returns**: `{ code: string, tests: object[], notes: string, plan: string, attempts: number, transform: Function }`
|
|
310
|
+
|
|
311
|
+
---
|
|
312
|
+
|
|
313
|
+
## 6. Prompt Optimization
|
|
314
|
+
|
|
315
|
+
### `runAutoPromptSearch(taskConfig?, opts?)`
|
|
316
|
+
|
|
317
|
+
**Import**: `import { runAutoPromptSearch } from 'flow-frame-core/services/autoPromptOptimizer.js'`
|
|
318
|
+
|
|
319
|
+
Iterative prompt optimization: generates candidate system prompts, evaluates them on a dataset, feeds top performers back.
|
|
320
|
+
|
|
321
|
+
| Param | Type | Default | Description |
|
|
322
|
+
|-------|------|---------|-------------|
|
|
323
|
+
| `taskConfig` | `TaskConfig` | `TASK_CONFIG` | Task definition with dataset |
|
|
324
|
+
| `opts.maxIterations` | `number` | `5` | Search iterations |
|
|
325
|
+
| `opts.promptsPerRound` | `number` | `3` | Candidates per round |
|
|
326
|
+
| `opts.topPromptsToFeedBack` | `number` | `2` | Best prompts to feed back |
|
|
327
|
+
| `opts.model` | `string` | `DEFAULT_MODEL` | LLM model |
|
|
328
|
+
|
|
329
|
+
**Returns**: `{ bestPrompt: { name, text, avgScore }, allResults: object[] }`
|
|
330
|
+
|
|
331
|
+
#### Helpers
|
|
332
|
+
|
|
333
|
+
- `createTaskConfig(overrides)` — merge overrides onto base template
|
|
334
|
+
- `addDatasetExamples(taskConfig, examples)` — append examples to dataset
|
|
335
|
+
- `buildDatasetExample({ id, input, expectedOutput })` — construct one example
|
|
336
|
+
|
|
337
|
+
---
|
|
338
|
+
|
|
339
|
+
## 7. Image Analysis
|
|
340
|
+
|
|
341
|
+
Vision-model queries on images.
|
|
342
|
+
|
|
343
|
+
### `classifyImageQuery(model, question, image)` / `classifyImageQuestion({...})`
|
|
344
|
+
|
|
345
|
+
**Import**: `import { classifyImageQuery } from 'flow-frame-core'`
|
|
346
|
+
|
|
347
|
+
Ask a yes/no question about an image.
|
|
348
|
+
|
|
349
|
+
| Param | Type | Description |
|
|
350
|
+
|-------|------|-------------|
|
|
351
|
+
| `model` | `string` | Vision model ID |
|
|
352
|
+
| `question` | `string` | Yes/no question |
|
|
353
|
+
| `image` | `string` | Base64 data URL |
|
|
354
|
+
|
|
355
|
+
**Returns**: `{ answer: 'yes'|'no', confidence: number, reason: string }`
|
|
356
|
+
|
|
357
|
+
### `generalClassifyImageQuery(model, question, image)` / `generalClassifyImageQuestion({...})`
|
|
358
|
+
|
|
359
|
+
Ask any question about an image. Returns arbitrary JSON as specified in the question.
|
|
360
|
+
|
|
361
|
+
### `findImageInImageQuery(model, imageA, imageB)` / `findImageInImage({...})`
|
|
362
|
+
|
|
363
|
+
Determine if imageA appears inside imageB.
|
|
364
|
+
|
|
365
|
+
**Returns**: `{ found: boolean, confidence: number, box: { x_center_rel, y_center_rel, width_rel, height_rel }, reason: string }`
|
|
366
|
+
|
|
367
|
+
**REST**: `POST /api/prompts/image-check`
|
|
368
|
+
```json
|
|
369
|
+
{ "base64_image": "data:image/...", "model": "..." }
|
|
370
|
+
→ { "success": true, "result": { "hasText": true, "text": "...", "hasIcon": false } }
|
|
371
|
+
```
|
|
372
|
+
|
|
373
|
+
---
|
|
374
|
+
|
|
375
|
+
## 8. Audio / TTS
|
|
376
|
+
|
|
377
|
+
### `processAudio(filePath, text, voice, keepExisting?)`
|
|
378
|
+
|
|
379
|
+
**Import**: `import { processAudio } from 'flow-frame-core/services/audioService.js'`
|
|
380
|
+
|
|
381
|
+
Generate speech audio from text via ElevenLabs and save to disk.
|
|
382
|
+
|
|
383
|
+
| Param | Type | Default | Description |
|
|
384
|
+
|-------|------|---------|-------------|
|
|
385
|
+
| `filePath` | `string` | required | Output MP3 path |
|
|
386
|
+
| `text` | `string` | required | Text to synthesize |
|
|
387
|
+
| `voice` | `string` | required | ElevenLabs voice ID |
|
|
388
|
+
| `keepExisting` | `boolean` | `true` | Skip if file exists |
|
|
389
|
+
|
|
390
|
+
**Returns**: `{ audioPath: string, srtPath?: string }`
|
|
391
|
+
|
|
392
|
+
### `generateAudio(text, voice, options?)`
|
|
393
|
+
|
|
394
|
+
Low-level: calls ElevenLabs API, returns raw buffer + alignment data.
|
|
395
|
+
|
|
396
|
+
**Returns**: `{ audioBuffer: Buffer, alignment: object }`
|
|
397
|
+
|
|
398
|
+
**REST**: `POST /generateAudio`
|
|
399
|
+
```json
|
|
400
|
+
{ "text": "Hello world", "filePath": "output.mp3", "voiceId": "..." }
|
|
401
|
+
→ { "ok": true }
|
|
402
|
+
```
|
|
403
|
+
|
|
404
|
+
---
|
|
405
|
+
|
|
406
|
+
## 9. PDF Processing
|
|
407
|
+
|
|
408
|
+
### `extractPdf({ pdfPath?, pdfBuffer?, outDir, extractText?, extractImages?, renderPages?, pageRenderScale?, password? })`
|
|
409
|
+
|
|
410
|
+
**Import**: `import { extractPdf } from 'flow-frame-core/services/extractPdf.js'`
|
|
411
|
+
|
|
412
|
+
Extract text, images, and page renders from a PDF.
|
|
413
|
+
|
|
414
|
+
| Param | Type | Default | Description |
|
|
415
|
+
|-------|------|---------|-------------|
|
|
416
|
+
| `pdfPath` | `string` | — | Path to PDF file |
|
|
417
|
+
| `pdfBuffer` | `Buffer` | — | PDF as buffer (alternative to path) |
|
|
418
|
+
| `outDir` | `string` | required | Output directory |
|
|
419
|
+
| `extractText` | `boolean` | `true` | Extract text per page |
|
|
420
|
+
| `extractImages` | `boolean` | `true` | Extract embedded images |
|
|
421
|
+
| `renderPages` | `boolean` | `false` | Render pages to PNG |
|
|
422
|
+
| `pageRenderScale` | `number` | `2` | Render scale factor |
|
|
423
|
+
| `password` | `string` | — | PDF password |
|
|
424
|
+
|
|
425
|
+
**Returns**: `{ pdfPath, numPages, textByPage: string[], images: string[], renderedPages: string[] }`
|
|
426
|
+
|
|
427
|
+
**REST**: `GET /pdf/extract?pdfPath=...&outDir=...`
|
|
428
|
+
**REST**: `POST /pdf/extract-folder` — batch extract from a folder.
|
|
429
|
+
|
|
430
|
+
---
|
|
431
|
+
|
|
432
|
+
## 10. Email
|
|
433
|
+
|
|
434
|
+
### `extractGmailBodyText(message)`
|
|
435
|
+
|
|
436
|
+
**Import**: `import { extractGmailBodyText } from 'flow-frame-core'`
|
|
437
|
+
|
|
438
|
+
Extract plain text from a Gmail API message object. Handles base64url decoding, MIME parts, HTML stripping.
|
|
439
|
+
|
|
440
|
+
| Param | Type | Description |
|
|
441
|
+
|-------|------|-------------|
|
|
442
|
+
| `message` | `object` | Gmail API message object |
|
|
443
|
+
|
|
444
|
+
**Returns**: `string` — extracted plain text.
|
|
445
|
+
|
|
446
|
+
### Gmail Polling (server mode only)
|
|
447
|
+
|
|
448
|
+
The server runs a `FilterGmailPoller` singleton that exposes:
|
|
449
|
+
|
|
450
|
+
| Endpoint | Method | Description |
|
|
451
|
+
|----------|--------|-------------|
|
|
452
|
+
| `/api/emails` | GET | Paginated filtered inbox |
|
|
453
|
+
| `/api/emails/:id` | GET | Specific email by ID |
|
|
454
|
+
| `/api/stats` | GET | Email statistics |
|
|
455
|
+
| `/api/polling/start` | POST | Start polling |
|
|
456
|
+
| `/api/polling/stop` | POST | Stop polling |
|
|
457
|
+
| `/api/polling/status` | GET | Auth + polling state |
|
|
458
|
+
| `/api/config/filter` | PUT | Update filter config |
|
|
459
|
+
|
|
460
|
+
---
|
|
461
|
+
|
|
462
|
+
## 11. Web Scraping
|
|
463
|
+
|
|
464
|
+
### `crawl(startUrl)`
|
|
465
|
+
|
|
466
|
+
**Import**: `import { crawl } from 'flow-frame-core/scraper.js'`
|
|
467
|
+
|
|
468
|
+
Depth-first crawl an entire website, staying on the same hostname.
|
|
469
|
+
|
|
470
|
+
| Param | Type | Description |
|
|
471
|
+
|-------|------|-------------|
|
|
472
|
+
| `startUrl` | `string` | Starting URL |
|
|
473
|
+
|
|
474
|
+
**Returns**: `Record<string, string>` — map of `{ url: pageText }`.
|
|
475
|
+
|
|
476
|
+
**REST**: `POST /scrape`
|
|
477
|
+
```json
|
|
478
|
+
{ "domain": "https://example.com" }
|
|
479
|
+
→ { "startUrl": "...", "pages": [...] }
|
|
480
|
+
```
|
|
481
|
+
|
|
482
|
+
---
|
|
483
|
+
|
|
484
|
+
## 12. Storage
|
|
485
|
+
|
|
486
|
+
JSON file-based key-value store with named profiles.
|
|
487
|
+
|
|
488
|
+
**Import**: `import { getItem, setItem, ... } from 'flow-frame-core'`
|
|
489
|
+
|
|
490
|
+
| Function | Params | Returns | Description |
|
|
491
|
+
|----------|--------|---------|-------------|
|
|
492
|
+
| `getItem(key)` | `string` | `any\|null` | Read a value by key |
|
|
493
|
+
| `setItem(key, value)` | `string, any` | `void` | Write a value by key |
|
|
494
|
+
| `listStorageProfiles()` | — | `string[]` | List available profiles |
|
|
495
|
+
| `getStorageProfile()` | — | `string` | Current active profile |
|
|
496
|
+
| `setStorageProfile(name)` | `string` | `void` | Switch active profile |
|
|
497
|
+
| `readStorageProfile(name)` | `string` | `object\|null` | Read a profile's full content |
|
|
498
|
+
| `saveStorageProfile(name, content)` | `string, any` | `void` | Save a profile |
|
|
499
|
+
| `deleteStorageProfile(name)` | `string` | `boolean` | Delete a profile (not `'default'`) |
|
|
500
|
+
| `isDocker()` | — | `boolean` | Detect Docker environment |
|
|
501
|
+
|
|
502
|
+
**REST endpoints**:
|
|
503
|
+
- `GET /storage-profiles` → `{ profiles, active }`
|
|
504
|
+
- `GET /storage-profiles/:name` → profile content
|
|
505
|
+
- `POST /storage-profiles` `{ name, content }` → create/update
|
|
506
|
+
- `DELETE /storage-profiles/:name` → delete
|
|
507
|
+
- `POST /storage-profiles/switch` `{ name }` → switch active
|
|
508
|
+
- `POST /get-key-value` `{ key }` → `{ value }`
|
|
509
|
+
- `POST /setObject` `{ key, value }` → `{ [key]: value }`
|
|
510
|
+
|
|
511
|
+
---
|
|
512
|
+
|
|
513
|
+
## 13. Queue Management
|
|
514
|
+
|
|
515
|
+
Serial job queue with progress tracking.
|
|
516
|
+
|
|
517
|
+
**Import**: `import queueManager from 'flow-frame-core'`
|
|
518
|
+
|
|
519
|
+
| Method | Params | Returns | Description |
|
|
520
|
+
|--------|--------|---------|-------------|
|
|
521
|
+
| `enqueue(fn)` | `(signal, progress) => Promise` | `number` (job ID) | Add job to queue |
|
|
522
|
+
| `status(id)` | `number` | `{ id, status, progress }\|null` | Check job status |
|
|
523
|
+
| `cancel(id)` | `number` | `boolean` | Cancel a running job |
|
|
524
|
+
| `list()` | — | `Job[]` | List all jobs |
|
|
525
|
+
| `waitForJobId(id, cb)` | `number, function` | `Promise` | Wait for job completion |
|
|
526
|
+
|
|
527
|
+
Events: `start`, `progress`, `done`, `aborted`, `error`.
|
|
528
|
+
|
|
529
|
+
**REST**:
|
|
530
|
+
- `GET /operations` → all queued jobs
|
|
531
|
+
- `GET /operations/:jobId/status` → job status
|
|
532
|
+
- `POST /operations/:jobId/cancel` → cancel job
|
|
533
|
+
|
|
534
|
+
---
|
|
535
|
+
|
|
536
|
+
## 14. File System Utilities
|
|
537
|
+
|
|
538
|
+
**Import**: `import { ... } from 'flow-frame-core'` (re-exported from utils.js)
|
|
539
|
+
|
|
540
|
+
| Function | Params | Returns | Description |
|
|
541
|
+
|----------|--------|---------|-------------|
|
|
542
|
+
| `ensureDir(dirPath)` | `string` | `Promise<void>` | Create directory recursively |
|
|
543
|
+
| `readProjectFile(filePath)` | `string` | `any[]` | Read JSON array or NDJSON file |
|
|
544
|
+
| `saveProjectFile(filePath, array)` | `string, any[]` | `void` | Write array as NDJSON |
|
|
545
|
+
| `downloadFile(url, destPath, onProgress?)` | `string, string, fn?` | `Promise<void>` | Download a file |
|
|
546
|
+
| `downloadFiles(urls, destFolder)` | `string[], string` | `Promise<string[]>` | Download multiple files |
|
|
547
|
+
| `deleteFileSync(filePath)` | `string` | `void` | Delete a file |
|
|
548
|
+
| `getFiles(dirPath)` | `string` | `Promise<string[]>` | List directory entries |
|
|
549
|
+
| `readJsonFiles(dirPath)` | `string` | `Promise<string[]>` | List `.json` file paths |
|
|
550
|
+
| `findFilesWithString(dir, str)` | `string, string` | `string[]` | Recursive file name search |
|
|
551
|
+
| `getDownloadsFolder()` | — | `string` | OS Downloads folder path |
|
|
552
|
+
| `unzipFile(zipPath, extractTo)` | `string, string` | `Promise<void>` | Extract zip file |
|
|
553
|
+
| `sanitizeFileName(name)` | `string` | `string` | Clean illegal characters |
|
|
554
|
+
| `sanitizeFolderName(name)` | `string` | `string` | Clean folder name |
|
|
555
|
+
| `getLastModifiedTimestampSync(path)` | `string` | `number` | File mtime in ms |
|
|
556
|
+
| `getSortedFilesByUpdatedAt(dir)` | `string` | `Promise<string[]>` | PNGs sorted by mtime |
|
|
557
|
+
| `createZipFromFolders(root, folders, name, opts?)` | various | `Promise<string>` | Create zip archive |
|
|
558
|
+
| `getLocalIp()` | — | `string` | Local IPv4 address |
|
|
559
|
+
| `applyTemplate(template, data)` | `string, object` | `string` | Fill `{key}` placeholders |
|
|
560
|
+
| `getMediaFileDuration(path)` | `string` | `Promise<number>` | Media duration in seconds |
|
|
561
|
+
| `getVideoDimensions(path)` | `string` | `Promise<{width,height}>` | Video pixel dimensions |
|
|
562
|
+
| `getVideoDuration(path)` | `string` | `Promise<{duration,width,height}>` | Full video info |
|
|
563
|
+
|
|
564
|
+
**REST**:
|
|
565
|
+
- `POST /readDir` `{ dirPath }` → directory listing
|
|
566
|
+
- `POST /readFiles` `{ filePaths }` → file contents
|
|
567
|
+
- `POST /readFile` `{ filePath, encoding? }` → single file content
|
|
568
|
+
- `POST /delete-files` `{ filePaths }` → per-file success/failure
|
|
569
|
+
- `POST /clear-directory` `{ directory }` → delete all files in dir
|
|
570
|
+
- `POST /moveFiles` `{ sourcePaths, destinationDir }` → move files
|
|
571
|
+
- `POST /waitForFiles` `{ directory, filePrefixes, timeout? }` → long-poll for file presence
|
|
572
|
+
- `POST /getFiles` `{ directory, filePrefixes, expectedCounts? }` → check file existence
|
|
573
|
+
- `POST /wait-for-file-stable` `{ file_path, min_size_mb?, max_wait_minutes? }` → wait for file to stop changing
|
|
574
|
+
|
|
575
|
+
---
|
|
576
|
+
|
|
577
|
+
## 15. Template & Variable Generation
|
|
578
|
+
|
|
579
|
+
Generate realistic fake data and fill templates.
|
|
580
|
+
|
|
581
|
+
### `generateTextFromTemplate(template, entities, options?)`
|
|
582
|
+
|
|
583
|
+
**Import**: `import { generateTextFromTemplate } from 'flow-frame-core/services/variableGenerator.js'`
|
|
584
|
+
|
|
585
|
+
Full pipeline: generate entity values via LLM, then fill a template.
|
|
586
|
+
|
|
587
|
+
| Param | Type | Description |
|
|
588
|
+
|-------|------|-------------|
|
|
589
|
+
| `template` | `string` | Template with `{{KEY}}` placeholders |
|
|
590
|
+
| `entities` | `EntityDef[]` | `[{ key, type, description }]` |
|
|
591
|
+
| `options.model` | `string` | LLM model for generation |
|
|
592
|
+
| `options.reuseProbability` | `number` | 0-1 chance of reusing existing pool value |
|
|
593
|
+
|
|
594
|
+
**Returns**: `{ email: string, valuesByKey: object }`
|
|
595
|
+
|
|
596
|
+
### `fillTemplate(template, valuesByKey)`
|
|
597
|
+
|
|
598
|
+
Simple `{{KEY}}` replacement without LLM.
|
|
599
|
+
|
|
600
|
+
### `generateEntityValues(entities, options?)`
|
|
601
|
+
|
|
602
|
+
Generate values for all entities, managing the value pool.
|
|
603
|
+
|
|
604
|
+
**Returns**: `{ valuesByKey: object, pools: object }`
|
|
605
|
+
|
|
606
|
+
**REST**: `POST /generate-text-from-template`
|
|
607
|
+
|
|
608
|
+
---
|
|
609
|
+
|
|
610
|
+
## 16. Browser & Desktop Automation
|
|
611
|
+
|
|
612
|
+
Control the OS desktop, browser windows, mouse, and keyboard.
|
|
613
|
+
|
|
614
|
+
### Browser Control
|
|
615
|
+
|
|
616
|
+
**Import**: `import { BrowserController } from 'flow-frame-core'`
|
|
617
|
+
|
|
618
|
+
| Method | Params | Description |
|
|
619
|
+
|--------|--------|-------------|
|
|
620
|
+
| `BrowserController.openChrome({ url })` | `string` | Open URL in Chrome |
|
|
621
|
+
| `BrowserController.closeChrome()` | — | Close Chrome |
|
|
622
|
+
| `BrowserController.closeChromeTab({ domain })` | `string` | Close tab by domain |
|
|
623
|
+
| `BrowserController.bringAppToFront({ appName })` | `string` | Focus an app window |
|
|
624
|
+
| `BrowserController.readFile({ filePath })` | `string` | Read a local file |
|
|
625
|
+
|
|
626
|
+
**REST**:
|
|
627
|
+
- `POST /openChrome` `{ url }`
|
|
628
|
+
- `POST /closeChrome`
|
|
629
|
+
- `POST /closeChromeTab` `{ domain }`
|
|
630
|
+
- `POST /bringAppToFront` `{ appName }`
|
|
631
|
+
- `POST /open-app` `{ appName }` — launch any app
|
|
632
|
+
- `POST /close-app` `{ appName, force? }` — kill any app
|
|
633
|
+
|
|
634
|
+
### Mouse & Keyboard (requires robotjs)
|
|
635
|
+
|
|
636
|
+
**Import**: `import { moveMouse, mouseClick, ... } from 'flow-frame-core/operations.js'`
|
|
637
|
+
|
|
638
|
+
| Function | Params | Description |
|
|
639
|
+
|----------|--------|-------------|
|
|
640
|
+
| `moveMouse(position)` | `{left, top, height, width}` | Move mouse to element center (with browser chrome offset) |
|
|
641
|
+
| `moveMouseDesktop(position)` | `{left, top, height, width}` | Move mouse (no offset) |
|
|
642
|
+
| `moveMouseRelative(offset)` | `{left, top}` | Relative mouse move |
|
|
643
|
+
| `mouseClick()` | — | Left click at current position |
|
|
644
|
+
| `pressEscapeAsync()` | — | Press Escape key |
|
|
645
|
+
| `pressKey(params)` | `{keys, ctrl?, shift?, alt?}` | Press key with modifiers |
|
|
646
|
+
| `typeText(params)` | `{keys, ctrl?, shift?, alt?}` | Type key combo |
|
|
647
|
+
| `pasteText(text)` | `string` | Clipboard paste |
|
|
648
|
+
| `clearAllText()` | — | Select-all + delete |
|
|
649
|
+
| `pressReturn()` | — | Press Enter |
|
|
650
|
+
| `scroll(x?, y?)` | `number, number` | Scroll mouse wheel |
|
|
651
|
+
| `fileModalOperate(filePath)` | `string` | Navigate OS file picker |
|
|
652
|
+
|
|
653
|
+
---
|
|
654
|
+
|
|
655
|
+
## 17. Screenshot & Screen Capture
|
|
656
|
+
|
|
657
|
+
### `captureScreenshotBase64(region?)`
|
|
658
|
+
|
|
659
|
+
**Import**: `import { captureScreenshotBase64 } from 'flow-frame-core/inference/capturescreenshot.js'`
|
|
660
|
+
|
|
661
|
+
Capture screen (or region) as base64 PNG data URL.
|
|
662
|
+
|
|
663
|
+
| Param | Type | Description |
|
|
664
|
+
|-------|------|-------------|
|
|
665
|
+
| `region` | `{x, y, width, height}` | Optional crop region |
|
|
666
|
+
|
|
667
|
+
**Returns**: `string` — `data:image/png;base64,...`
|
|
668
|
+
|
|
669
|
+
### `captureFullScreenshot(targetFolder)`
|
|
670
|
+
|
|
671
|
+
Save full-screen capture as a PNG file.
|
|
672
|
+
|
|
673
|
+
**Returns**: `string` — filename.
|
|
674
|
+
|
|
675
|
+
### `captureScreenshot(targetFolder, filename, region?)`
|
|
676
|
+
|
|
677
|
+
Save a named screenshot file.
|
|
678
|
+
|
|
679
|
+
**REST**: `POST /take-screenshot` `{ appName }` → `{ filename, filePath }`
|
|
680
|
+
|
|
681
|
+
---
|
|
682
|
+
|
|
683
|
+
## 18. Self-Learning Vision Pipeline
|
|
684
|
+
|
|
685
|
+
Computer vision system for recognizing and learning UI screens.
|
|
686
|
+
|
|
687
|
+
### `ingestScreenshot({ imagePath, meta?, tags? })`
|
|
688
|
+
|
|
689
|
+
**Import**: `import { ingestScreenshot } from 'flow-frame-core/services/self-learning/injest.js'`
|
|
690
|
+
|
|
691
|
+
Ingest a screenshot: copies to store, computes perceptual hashes, logs event.
|
|
692
|
+
|
|
693
|
+
**Returns**: Event object with `{ aHash, dHash, width, height, ... }`.
|
|
694
|
+
|
|
695
|
+
### `recognizeScreen(imagePath, options?)`
|
|
696
|
+
|
|
697
|
+
**Import**: `import { recognizeScreen } from 'flow-frame-core/services/self-learning/recognize.js'`
|
|
698
|
+
|
|
699
|
+
Match a screenshot against known screen signatures.
|
|
700
|
+
|
|
701
|
+
| Param | Type | Default | Description |
|
|
702
|
+
|-------|------|---------|-------------|
|
|
703
|
+
| `imagePath` | `string` | required | Path to screenshot |
|
|
704
|
+
| `options.topK` | `number` | `5` | Candidates to evaluate |
|
|
705
|
+
| `options.unknownThreshold` | `number` | — | Min score for a match |
|
|
706
|
+
|
|
707
|
+
**Returns**: `{ screenId, confidence, bestScore, candidates, reason? }`
|
|
708
|
+
|
|
709
|
+
### `discoverScreens(options?)`
|
|
710
|
+
|
|
711
|
+
**Import**: `import { discoverScreens } from 'flow-frame-core/services/self-learning/discover.js'`
|
|
712
|
+
|
|
713
|
+
Cluster ingested screenshots and auto-generate screen signatures.
|
|
714
|
+
|
|
715
|
+
**Returns**: `{ learned, catalogs, clusters, message }`
|
|
716
|
+
|
|
717
|
+
### `recordTransition({ takeScreenshot, recognizeScreen, performAction, action, meta? })`
|
|
718
|
+
|
|
719
|
+
Record a before/after screen state transition.
|
|
720
|
+
|
|
721
|
+
### `buildTransitionGraph()` / `findPath(graph, start, goal)`
|
|
722
|
+
|
|
723
|
+
Build a directed graph of screen transitions; find shortest path between screens.
|
|
724
|
+
|
|
725
|
+
### Perceptual Hashing
|
|
726
|
+
|
|
727
|
+
| Function | Description |
|
|
728
|
+
|----------|-------------|
|
|
729
|
+
| `aHashHex(imagePath)` | Average hash (64 hex chars) |
|
|
730
|
+
| `dHashHex(imagePath)` | Difference hash (64 hex chars) |
|
|
731
|
+
| `hammingHex(a, b)` | Hamming distance between hashes |
|
|
732
|
+
| `preScoreFromDistances(aDist, dDist)` | 0-1 similarity score |
|
|
733
|
+
|
|
734
|
+
### Image Utilities
|
|
735
|
+
|
|
736
|
+
| Function | Description |
|
|
737
|
+
|----------|-------------|
|
|
738
|
+
| `fileToDataUrl(imagePath)` | Image file → base64 data URL |
|
|
739
|
+
| `cropToDataUrl({ imagePath, bbox })` | Crop region → base64 data URL |
|
|
740
|
+
| `getImageSize(imagePath)` | `{ width, height }` |
|
|
741
|
+
|
|
742
|
+
**REST**:
|
|
743
|
+
- `POST /recognize-screen-signature` `{ filePath }` → recognition result
|
|
744
|
+
- `POST /api/self-learning/injest` `{ imagePath, metadata?, tags? }` → event
|
|
745
|
+
- `POST /api/self-learning/discover` `{ ...options }` → discovery result
|
|
746
|
+
- `POST /api/self-learning/enhance` `{ userPrompt, model? }` → LLM response
|
|
747
|
+
|
|
748
|
+
---
|
|
749
|
+
|
|
750
|
+
## 19. UI Automation Planning
|
|
751
|
+
|
|
752
|
+
AI-powered planning that converts natural language into executable desktop automation steps.
|
|
753
|
+
|
|
754
|
+
### `UiPlanner` class
|
|
755
|
+
|
|
756
|
+
**Import**: `import { UiPlanner } from 'flow-frame-core/services/uiPlanner.js'`
|
|
757
|
+
|
|
758
|
+
```js
|
|
759
|
+
const planner = new UiPlanner(uiMap, pathFinder, macroRegistry, automationFiles);
|
|
760
|
+
const plan = await planner.plan('Upload a video titled "Hello"', 'home', {}, 'gpt-4o');
|
|
761
|
+
```
|
|
762
|
+
|
|
763
|
+
**`plan(request, startStateId?, context?, model?)`** returns `{ steps: ExecutableStep[] }`.
|
|
764
|
+
|
|
765
|
+
### `StepByStepAiPlanner` class
|
|
766
|
+
|
|
767
|
+
**Import**: `import { StepByStepAiPlanner } from 'flow-frame-core/services/stepByStepAiPlanner.js'`
|
|
768
|
+
|
|
769
|
+
Extends `UiPlanner` with dependency-graph-aware planning. Identifies key automation steps by ID rather than generating field-level goals.
|
|
770
|
+
|
|
771
|
+
### `generateUIMap(files)`
|
|
772
|
+
|
|
773
|
+
**Import**: `import { generateUIMap } from 'flow-frame-core/services/uiMapService.js'`
|
|
774
|
+
|
|
775
|
+
Build a UI state machine map from automation recording files.
|
|
776
|
+
|
|
777
|
+
| Param | Type | Description |
|
|
778
|
+
|-------|------|-------------|
|
|
779
|
+
| `files` | `string[]` | Paths to `.automation` files |
|
|
780
|
+
|
|
781
|
+
**Returns**: `{ version, states, edges }`
|
|
782
|
+
|
|
783
|
+
**REST**: `POST /generate-ui-map` `{ files }` → `{ uiMap }`
|
|
784
|
+
|
|
785
|
+
---
|
|
786
|
+
|
|
787
|
+
## 20. Workflow File Management
|
|
788
|
+
|
|
789
|
+
CRUD for workflow/automation files.
|
|
790
|
+
|
|
791
|
+
### Programmatic
|
|
792
|
+
|
|
793
|
+
**Import**: `import { WorkflowController } from 'flow-frame-core'`
|
|
794
|
+
|
|
795
|
+
| Method | Params | Description |
|
|
796
|
+
|--------|--------|-------------|
|
|
797
|
+
| `loadConfiguration({ name, configFolder })` | `string, string` | Load a `.workflow` file |
|
|
798
|
+
| `getWorkflowConfig({ name, workflowDictionary })` | `string, object` | Lookup from in-memory dictionary |
|
|
799
|
+
|
|
800
|
+
### `buildWorkflowDirectory(jsonInput, targetDir)`
|
|
801
|
+
|
|
802
|
+
Materialize a `{ files: [{ path, content }] }` structure to disk.
|
|
803
|
+
|
|
804
|
+
### `runWorkflowCLI(targetDir, workflowJsonPath?, parameters?)`
|
|
805
|
+
|
|
806
|
+
Run `node src/cli.js` in a target directory.
|
|
807
|
+
|
|
808
|
+
### `installDependencies(targetDir)`
|
|
809
|
+
|
|
810
|
+
Run `npm install` in a target directory.
|
|
811
|
+
|
|
812
|
+
**REST**:
|
|
813
|
+
- `GET /configurations` → list all config files
|
|
814
|
+
- `GET /loadConfiguration?name=...` → load config
|
|
815
|
+
- `POST /saveConfiguration` `{ name, nodes, edges }` → save
|
|
816
|
+
- `POST /buildWorkflowDirectory` `{ jsonInput, targetDir }`
|
|
817
|
+
- `POST /runWorkflowCLI` `{ targetDir, workflowJsonPath?, parameters? }`
|
|
818
|
+
- `POST /installDependencies` `{ targetDir }`
|
|
819
|
+
- Full step-workflow CRUD at `/api/workflows/*` (see REST API section)
|
|
820
|
+
|
|
821
|
+
---
|
|
822
|
+
|
|
823
|
+
## 21. Extension System
|
|
824
|
+
|
|
825
|
+
Discover and run pluggable npm-based extensions.
|
|
826
|
+
|
|
827
|
+
### `scanExtensions(extensionFolders)`
|
|
828
|
+
|
|
829
|
+
**Import**: `import { scanExtensions } from 'flow-frame-core/extensionUtils.js'`
|
|
830
|
+
|
|
831
|
+
Scan directories for subdirectories containing `api.json` files.
|
|
832
|
+
|
|
833
|
+
| Param | Type | Description |
|
|
834
|
+
|-------|------|-------------|
|
|
835
|
+
| `extensionFolders` | `string\|string[]` | Paths to scan |
|
|
836
|
+
|
|
837
|
+
**Returns**: `{ location, ...apiJsonData }[]`
|
|
838
|
+
|
|
839
|
+
### `ExtensionController`
|
|
840
|
+
|
|
841
|
+
**Import**: `import { ExtensionController } from 'flow-frame-core'`
|
|
842
|
+
|
|
843
|
+
| Method | Description |
|
|
844
|
+
|--------|-------------|
|
|
845
|
+
| `getExtensions({ extensionFolders })` | Scan and return extensions |
|
|
846
|
+
| `getExtensionFolders()` | Get configured folders |
|
|
847
|
+
| `installDependencies({ targetDir })` | npm install in extension dir |
|
|
848
|
+
| `runWorkflowCLI({ targetDir, workflowJsonPath, parameters })` | Run extension CLI |
|
|
849
|
+
|
|
850
|
+
**REST**: `GET /get-extensions` → `{ extensions: [...] }`
|
|
851
|
+
|
|
852
|
+
---
|
|
853
|
+
|
|
854
|
+
## 22. Media Processing
|
|
855
|
+
|
|
856
|
+
### Video/Audio
|
|
857
|
+
|
|
858
|
+
| Function | Params | Returns | Description |
|
|
859
|
+
|----------|--------|---------|-------------|
|
|
860
|
+
| `getMediaFileDuration(path)` | `string` | `Promise<number>` | Duration in seconds |
|
|
861
|
+
| `getVideoDimensions(path)` | `string` | `Promise<{width,height}>` | Pixel dimensions |
|
|
862
|
+
| `getVideoDuration(path)` | `string` | `Promise<{duration,width,height}>` | Full video info |
|
|
863
|
+
| `processFile(targetFile)` | `string` | `void` | Process project file through media pipeline |
|
|
864
|
+
| `fix(text)` | `string` | `string` | Sanitize for filename/prompt use |
|
|
865
|
+
|
|
866
|
+
**REST**:
|
|
867
|
+
- `POST /get-video-dimensions` `{ filePath }` → dimensions
|
|
868
|
+
- `POST /getAudioDurations` `{ audioFiles, videos }` → duration map
|
|
869
|
+
- `GET /image-dimensions/:name` → `{ width, height }`
|
|
870
|
+
- `POST /get-media-dimensions` `{ imageName }` or `{ videoName, timestamp }` → dimensions
|
|
871
|
+
|
|
872
|
+
### YOLO Training Data
|
|
873
|
+
|
|
874
|
+
**REST**:
|
|
875
|
+
- `GET /fetch-training-folders` → folder names
|
|
876
|
+
- `GET /fetch-training-data/:folder/:size` → YAML config as JSON
|
|
877
|
+
- `GET /list-images/:folder/:size/:split` → image filenames
|
|
878
|
+
- `GET /fetch-labels/:folder/:size/:split/:image` → YOLO bounding boxes
|
|
879
|
+
|
|
880
|
+
---
|
|
881
|
+
|
|
882
|
+
## 23. Configuration Management
|
|
883
|
+
|
|
884
|
+
File-based config CRUD.
|
|
885
|
+
|
|
886
|
+
**REST**:
|
|
887
|
+
|
|
888
|
+
| Method | Path | Description |
|
|
889
|
+
|--------|------|-------------|
|
|
890
|
+
| GET | `/api/config/files` | List all config files + folder tree |
|
|
891
|
+
| GET | `/api/config/file/:name` | Read a config file |
|
|
892
|
+
| POST | `/api/config/file/:name` | Save/update (with optional backup) |
|
|
893
|
+
| POST | `/api/config/create` | Create new config file |
|
|
894
|
+
| DELETE | `/api/config/file/:name` | Delete (with optional backup) |
|
|
895
|
+
| PUT | `/api/config/rename/:name` | Rename a config file |
|
|
896
|
+
| POST | `/api/config/validate/:name` | Validate file content |
|
|
897
|
+
| GET | `/api/config/info` | Config folder metadata |
|
|
898
|
+
|
|
899
|
+
---
|
|
900
|
+
|
|
901
|
+
## 24. Constants & Selectors
|
|
902
|
+
|
|
903
|
+
**Import**: `import { KEYS, MODES, SUNO_SELECTORS, YOUTUBE_SELECTORS } from 'flow-frame-core'`
|
|
904
|
+
|
|
905
|
+
### `MODES`
|
|
906
|
+
|
|
907
|
+
Operating mode constants:
|
|
908
|
+
- `MIDJOURNEY`, `MIDJOURNEY_IMAGES_TO_VIDEO`, `MIDJOURNEY_DOWNLOAD_MEDIA`, `MIDJOURNEY_DOWNLOAD_PUBLIC_MEDIA`
|
|
909
|
+
- `CLEAR_MIDJOURNEY_IMAGES`
|
|
910
|
+
- `SUNO`, `SUNO_FILM`
|
|
911
|
+
- `YOUTUBE`
|
|
912
|
+
- `FLOW_FRAME`
|
|
913
|
+
|
|
914
|
+
### `KEYS`
|
|
915
|
+
|
|
916
|
+
80+ storage key constants for all configuration, paths, and state:
|
|
917
|
+
- Folder paths: `workflow_folder`, `ui_map_folder`, `prompt_lib_folder`, `media_folder`, `audio_folder`, `video_folder`, `config_folder`, `learning_dir`, `extension_folders`, `training_jobs_folder`
|
|
918
|
+
- LLM config: `default_llm_model`, `default_llm_multi_modal_model`
|
|
919
|
+
- Mode/state: `mode`, `procedure`, `sourceFile`, `current_folder`, `images_folder`
|
|
920
|
+
- Suno state: `suno_state`, `suno_current_name`
|
|
921
|
+
- UI automation: `boxes`, `element_selectors`, `chrome_requests`
|
|
922
|
+
- And many more.
|
|
923
|
+
|
|
924
|
+
### `SUNO_SELECTORS` / `YOUTUBE_SELECTORS`
|
|
925
|
+
|
|
926
|
+
CSS selector maps for Suno and YouTube Studio UI elements.
|
|
927
|
+
|
|
928
|
+
---
|
|
929
|
+
|
|
930
|
+
## REST API Quick Reference
|
|
931
|
+
|
|
932
|
+
All endpoints assume `Content-Type: application/json` unless noted. Server runs on port configured in `peers.ts` (default 3000).
|
|
933
|
+
|
|
934
|
+
### Core
|
|
935
|
+
|
|
936
|
+
| Method | Path | Purpose |
|
|
937
|
+
|--------|------|---------|
|
|
938
|
+
| GET | `/` | Health check |
|
|
939
|
+
| GET | `/health` | Detailed health (uptime, memory, WS count) |
|
|
940
|
+
| GET | `/health/detailed` | Full process info |
|
|
941
|
+
|
|
942
|
+
### LLM
|
|
943
|
+
|
|
944
|
+
| Method | Path | Purpose |
|
|
945
|
+
|--------|------|---------|
|
|
946
|
+
| POST | `/api/prompts/chat` | Run LLM prompt |
|
|
947
|
+
| POST | `/api/prompts/image-check` | Analyze image for text/icons |
|
|
948
|
+
| POST | `/analyze-image-grok` | Vision model image analysis |
|
|
949
|
+
|
|
950
|
+
### Workflows
|
|
951
|
+
|
|
952
|
+
| Method | Path | Purpose |
|
|
953
|
+
|--------|------|---------|
|
|
954
|
+
| GET | `/configurations` | List workflow configs |
|
|
955
|
+
| GET | `/loadConfiguration?name=` | Load a workflow |
|
|
956
|
+
| POST | `/saveConfiguration` | Save a workflow |
|
|
957
|
+
| GET | `/api/workflows` | List automation workflows |
|
|
958
|
+
| GET | `/api/workflows/:id` | Get workflow |
|
|
959
|
+
| POST | `/api/workflows/:id` | Save workflow |
|
|
960
|
+
| DELETE | `/api/workflows/:id` | Delete workflow |
|
|
961
|
+
| POST | `/api/workflows/:id/execute` | Execute workflow steps |
|
|
962
|
+
| POST | `/api/workflows/:id/validate` | Validate workflow |
|
|
963
|
+
| POST | `/api/workflows/:id/duplicate` | Duplicate workflow |
|
|
964
|
+
| POST | `/api/workflows/import` | Import workflow file |
|
|
965
|
+
|
|
966
|
+
### Storage & Config
|
|
967
|
+
|
|
968
|
+
| Method | Path | Purpose |
|
|
969
|
+
|--------|------|---------|
|
|
970
|
+
| POST | `/get-key-value` | Get storage value |
|
|
971
|
+
| POST | `/setObject` | Set storage value |
|
|
972
|
+
| GET | `/storage-profiles` | List profiles |
|
|
973
|
+
| POST | `/storage-profiles/switch` | Switch profile |
|
|
974
|
+
| GET | `/api/config/files` | List config files |
|
|
975
|
+
| GET | `/api/config/file/:name` | Read config |
|
|
976
|
+
| POST | `/api/config/file/:name` | Save config |
|
|
977
|
+
|
|
978
|
+
### Files
|
|
979
|
+
|
|
980
|
+
| Method | Path | Purpose |
|
|
981
|
+
|--------|------|---------|
|
|
982
|
+
| POST | `/readDir` | List directory |
|
|
983
|
+
| POST | `/readFile` | Read file |
|
|
984
|
+
| POST | `/readFiles` | Read multiple files |
|
|
985
|
+
| POST | `/delete-files` | Delete files |
|
|
986
|
+
| POST | `/moveFiles` | Move files |
|
|
987
|
+
| POST | `/waitForFiles` | Wait for files to appear |
|
|
988
|
+
| POST | `/wait-for-file-stable` | Wait for file to stabilize |
|
|
989
|
+
|
|
990
|
+
### Browser & Desktop
|
|
991
|
+
|
|
992
|
+
| Method | Path | Purpose |
|
|
993
|
+
|--------|------|---------|
|
|
994
|
+
| POST | `/openChrome` | Open Chrome URL |
|
|
995
|
+
| POST | `/closeChrome` | Close Chrome |
|
|
996
|
+
| POST | `/closeChromeTab` | Close Chrome tab |
|
|
997
|
+
| POST | `/bringAppToFront` | Focus app window |
|
|
998
|
+
| POST | `/open-app` | Launch application |
|
|
999
|
+
| POST | `/close-app` | Kill application |
|
|
1000
|
+
| POST | `/take-screenshot` | Capture screenshot |
|
|
1001
|
+
| POST | `/recognize-screen-signature` | Recognize UI screen |
|
|
1002
|
+
|
|
1003
|
+
### Media
|
|
1004
|
+
|
|
1005
|
+
| Method | Path | Purpose |
|
|
1006
|
+
|--------|------|---------|
|
|
1007
|
+
| POST | `/generate-audio` | Generate audio from text |
|
|
1008
|
+
| POST | `/generateAudio` | TTS via ElevenLabs |
|
|
1009
|
+
| POST | `/get-video-dimensions` | Video dimensions |
|
|
1010
|
+
| POST | `/getAudioDurations` | Media durations |
|
|
1011
|
+
| GET | `/image-dimensions/:name` | Image dimensions |
|
|
1012
|
+
| GET | `/api/media` | List media files |
|
|
1013
|
+
| GET | `/api/media/:filename` | Serve media file |
|
|
1014
|
+
| POST | `/api/media/upload` | Upload media |
|
|
1015
|
+
| DELETE | `/api/media/:filename` | Delete media |
|
|
1016
|
+
|
|
1017
|
+
### PDF
|
|
1018
|
+
|
|
1019
|
+
| Method | Path | Purpose |
|
|
1020
|
+
|--------|------|---------|
|
|
1021
|
+
| GET | `/pdf/extract` | Extract from PDF |
|
|
1022
|
+
| POST | `/pdf/extract-folder` | Extract from PDF folder |
|
|
1023
|
+
|
|
1024
|
+
### Scraping
|
|
1025
|
+
|
|
1026
|
+
| Method | Path | Purpose |
|
|
1027
|
+
|--------|------|---------|
|
|
1028
|
+
| POST | `/scrape` | Crawl a website |
|
|
1029
|
+
|
|
1030
|
+
### Self-Learning
|
|
1031
|
+
|
|
1032
|
+
| Method | Path | Purpose |
|
|
1033
|
+
|--------|------|---------|
|
|
1034
|
+
| POST | `/api/self-learning/injest` | Ingest screenshot |
|
|
1035
|
+
| POST | `/api/self-learning/discover` | Discover screens |
|
|
1036
|
+
| POST | `/api/self-learning/enhance` | LLM enhance prompt |
|
|
1037
|
+
| GET | `/api/self-learning/media-folder` | Get media folder |
|
|
1038
|
+
| POST | `/api/self-learning/media-folder` | Set media folder |
|
|
1039
|
+
|
|
1040
|
+
### UI Maps & Prompt Libraries
|
|
1041
|
+
|
|
1042
|
+
| Method | Path | Purpose |
|
|
1043
|
+
|--------|------|---------|
|
|
1044
|
+
| GET | `/api/ui-maps` | List UI maps |
|
|
1045
|
+
| GET | `/api/ui-maps/:id` | Get UI map |
|
|
1046
|
+
| POST | `/api/ui-maps/:id` | Save UI map |
|
|
1047
|
+
| DELETE | `/api/ui-maps/:id` | Delete UI map |
|
|
1048
|
+
| POST | `/generate-ui-map` | Generate from files |
|
|
1049
|
+
| GET | `/api/prompt-libs` | List prompt libraries |
|
|
1050
|
+
| GET | `/api/prompt-libs/:id` | Get prompt library |
|
|
1051
|
+
| POST | `/api/prompt-libs/:id` | Save prompt library |
|
|
1052
|
+
| DELETE | `/api/prompt-libs/:id` | Delete prompt library |
|
|
1053
|
+
|
|
1054
|
+
### Email
|
|
1055
|
+
|
|
1056
|
+
| Method | Path | Purpose |
|
|
1057
|
+
|--------|------|---------|
|
|
1058
|
+
| GET | `/api/emails` | Filtered inbox |
|
|
1059
|
+
| GET | `/api/emails/:id` | Email by ID |
|
|
1060
|
+
| GET | `/api/stats` | Email stats |
|
|
1061
|
+
| POST | `/api/polling/start` | Start polling |
|
|
1062
|
+
| POST | `/api/polling/stop` | Stop polling |
|
|
1063
|
+
|
|
1064
|
+
### Extensions
|
|
1065
|
+
|
|
1066
|
+
| Method | Path | Purpose |
|
|
1067
|
+
|--------|------|---------|
|
|
1068
|
+
| GET | `/get-extensions` | List extensions |
|
|
1069
|
+
| POST | `/buildWorkflowDirectory` | Build from JSON |
|
|
1070
|
+
| POST | `/runWorkflowCLI` | Run workflow CLI |
|
|
1071
|
+
| POST | `/installDependencies` | npm install |
|
|
1072
|
+
|
|
1073
|
+
### Training Data
|
|
1074
|
+
|
|
1075
|
+
| Method | Path | Purpose |
|
|
1076
|
+
|--------|------|---------|
|
|
1077
|
+
| GET | `/fetch-training-folders` | List training folders |
|
|
1078
|
+
| GET | `/fetch-training-data/:folder/:size` | Dataset config |
|
|
1079
|
+
| GET | `/list-images/:folder/:size/:split` | List images |
|
|
1080
|
+
| GET | `/fetch-labels/:folder/:size/:split/:image` | YOLO labels |
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "flow-frame-core",
|
|
3
|
-
"version": "0.1.
|
|
3
|
+
"version": "0.1.7",
|
|
4
4
|
"type": "module",
|
|
5
5
|
"main": "dist/index.js",
|
|
6
6
|
"types": "dist/index.d.ts",
|
|
@@ -10,6 +10,7 @@
|
|
|
10
10
|
"files": [
|
|
11
11
|
"dist",
|
|
12
12
|
"README.md",
|
|
13
|
+
"TOOLS.md",
|
|
13
14
|
"LICENSE"
|
|
14
15
|
],
|
|
15
16
|
"keywords": [
|