web-ai-service 1.0.1 → 1.0.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +199 -27
- package/package.json +2 -2
package/README.md
CHANGED
|
@@ -284,96 +284,268 @@ stages:
|
|
|
284
284
|
|
|
285
285
|
## Node Types
|
|
286
286
|
|
|
287
|
+
All nodes share these common properties:
|
|
288
|
+
- **type** (required) - The node type: `llm`, `code`, `reduce`, `split`, or `passthrough`
|
|
289
|
+
- **input** (required for most) - The input source: `$input`, `$input.field`, `stageName.nodeName`
|
|
290
|
+
|
|
287
291
|
### LLM Node
|
|
288
292
|
|
|
289
|
-
|
|
293
|
+
Calls an LLM provider with a prompt.
|
|
290
294
|
|
|
295
|
+
**Required Properties:**
|
|
291
296
|
```yaml
|
|
292
297
|
my_llm_node:
|
|
293
298
|
type: llm
|
|
294
|
-
input: $input
|
|
295
|
-
provider: gemini
|
|
296
|
-
model: gemini-2.0-flash-lite
|
|
297
|
-
|
|
298
|
-
|
|
299
|
-
|
|
300
|
-
|
|
301
|
-
|
|
299
|
+
input: $input # Input source
|
|
300
|
+
provider: gemini # Provider name: gemini | openai | anthropic | grok
|
|
301
|
+
model: gemini-2.0-flash-lite # Model identifier
|
|
302
|
+
```
|
|
303
|
+
|
|
304
|
+
**Optional Properties:**
|
|
305
|
+
```yaml
|
|
306
|
+
temperature: 0.7 # Default: 1.0. Controls randomness (0.0-1.0)
|
|
307
|
+
maxTokens: 1024 # Default: provider default. Max output tokens
|
|
308
|
+
systemMessages: # System prompts (optional)
|
|
309
|
+
- file: prompt.txt # Load from file
|
|
310
|
+
cache: true # Enable caching (default: false)
|
|
311
|
+
- text: "Direct prompt" # Or use inline text
|
|
312
|
+
config: # Provider-specific config (optional)
|
|
313
|
+
topP: 0.9
|
|
314
|
+
topK: 40
|
|
302
315
|
```
|
|
303
316
|
|
|
304
317
|
**Supported Providers & Models:**
|
|
305
318
|
|
|
306
|
-
| Provider | Example Models |
|
|
307
|
-
|
|
308
|
-
| `gemini` | `gemini-2.0-flash-lite`, `gemini-2.0-flash`, `gemini-1.5-pro` |
|
|
309
|
-
| `openai` | `gpt-4o`, `gpt-4o-mini`, `gpt-4-turbo` |
|
|
310
|
-
| `anthropic` | `claude-3-5-sonnet-latest`, `claude-3-haiku-20240307` |
|
|
311
|
-
| `grok` | `grok-2`, `grok-2-mini` |
|
|
319
|
+
| Provider | Example Models | Notes |
|
|
320
|
+
|----------|----------------|-------|
|
|
321
|
+
| `gemini` | `gemini-2.0-flash-lite`, `gemini-2.0-flash`, `gemini-1.5-pro` | Fast, cost-effective |
|
|
322
|
+
| `openai` | `gpt-4o`, `gpt-4o-mini`, `gpt-4-turbo` | High quality |
|
|
323
|
+
| `anthropic` | `claude-3-5-sonnet-latest`, `claude-3-haiku-20240307` | Long context |
|
|
324
|
+
| `grok` | `grok-2`, `grok-2-mini` | xAI models |
|
|
325
|
+
|
|
326
|
+
**Using LLM References (Alternative):**
|
|
327
|
+
|
|
328
|
+
Define reusable LLM configurations:
|
|
329
|
+
|
|
330
|
+
```yaml
|
|
331
|
+
llm:
|
|
332
|
+
my-summarizer:
|
|
333
|
+
provider: gemini
|
|
334
|
+
model: gemini-2.0-flash-lite
|
|
335
|
+
temperature: 0.3
|
|
336
|
+
|
|
337
|
+
nodes:
|
|
338
|
+
summarize:
|
|
339
|
+
type: llm
|
|
340
|
+
input: $input
|
|
341
|
+
llmRef: my-summarizer # Reference the config
|
|
342
|
+
systemMessages:
|
|
343
|
+
- file: prompt.txt
|
|
344
|
+
```
|
|
345
|
+
|
|
346
|
+
---
|
|
312
347
|
|
|
313
348
|
### Code Node
|
|
314
349
|
|
|
315
|
-
|
|
350
|
+
Executes a custom TypeScript function.
|
|
316
351
|
|
|
352
|
+
**Required Properties:**
|
|
317
353
|
```yaml
|
|
318
354
|
my_code_node:
|
|
319
355
|
type: code
|
|
320
356
|
input: $input
|
|
321
|
-
file: my-processor.ts
|
|
357
|
+
file: my-processor.ts # Relative to endpoint's codes/ folder
|
|
322
358
|
```
|
|
323
359
|
|
|
324
|
-
|
|
360
|
+
**TypeScript Function Signature:**
|
|
361
|
+
|
|
362
|
+
Your code file must export a default async function:
|
|
325
363
|
|
|
326
364
|
```typescript
|
|
327
365
|
import type { NodeOutput } from '@workflow/types';
|
|
328
366
|
|
|
329
367
|
export default async function(input: unknown): Promise<NodeOutput> {
|
|
330
368
|
// Your logic here
|
|
369
|
+
const processed = /* ... */;
|
|
370
|
+
|
|
331
371
|
return {
|
|
332
372
|
type: 'json', // 'string' | 'json' | 'number' | 'boolean' | 'array'
|
|
333
|
-
value:
|
|
373
|
+
value: processed
|
|
334
374
|
};
|
|
335
375
|
}
|
|
336
376
|
```
|
|
337
377
|
|
|
378
|
+
**Notes:**
|
|
379
|
+
- The `input` parameter is the **unwrapped value** from the previous node
|
|
380
|
+
- Must return a `NodeOutput` object with `type` and `value`
|
|
381
|
+
- Can import from `@code-plugins/*` for shared code
|
|
382
|
+
- Can use any npm packages (run `npm run scan-deps` to auto-install)
|
|
383
|
+
|
|
384
|
+
---
|
|
385
|
+
|
|
338
386
|
### Reduce Node
|
|
339
387
|
|
|
340
|
-
|
|
388
|
+
Combines multiple node outputs into a single JSON object.
|
|
341
389
|
|
|
390
|
+
**Required Properties:**
|
|
342
391
|
```yaml
|
|
343
392
|
merge_results:
|
|
344
393
|
type: reduce
|
|
345
|
-
inputs:
|
|
394
|
+
inputs: # Array of node references
|
|
346
395
|
- stageName.node1
|
|
347
396
|
- stageName.node2
|
|
348
|
-
mapping:
|
|
397
|
+
mapping: # JSONPath mappings
|
|
349
398
|
firstResult: $.0
|
|
350
399
|
secondResult: $.1
|
|
400
|
+
nested:
|
|
401
|
+
data: $.0.someField
|
|
402
|
+
```
|
|
403
|
+
|
|
404
|
+
**How it Works:**
|
|
405
|
+
- Takes outputs from multiple nodes specified in `inputs`
|
|
406
|
+
- Uses JSONPath expressions in `mapping` to extract values
|
|
407
|
+
- `$.0` refers to first input, `$.1` to second input, etc.
|
|
408
|
+
- Returns a single `{ type: 'json', value: {...} }` object
|
|
409
|
+
|
|
410
|
+
**Example:**
|
|
411
|
+
|
|
412
|
+
If `node1` outputs `{ value: { count: 10 } }` and `node2` outputs `{ value: { total: 100 } }`:
|
|
413
|
+
|
|
414
|
+
```yaml
|
|
415
|
+
mapping:
|
|
416
|
+
count: $.0.count # Gets 10 from first input
|
|
417
|
+
total: $.1.total # Gets 100 from second input
|
|
418
|
+
# Result: { count: 10, total: 100 }
|
|
351
419
|
```
|
|
352
420
|
|
|
421
|
+
---
|
|
422
|
+
|
|
353
423
|
### Split Node
|
|
354
424
|
|
|
355
|
-
|
|
425
|
+
Divides a single output into multiple named outputs.
|
|
356
426
|
|
|
427
|
+
**Required Properties:**
|
|
357
428
|
```yaml
|
|
358
429
|
split_data:
|
|
359
430
|
type: split
|
|
360
431
|
input: stageName.nodeName
|
|
361
|
-
mapping:
|
|
362
|
-
header: $.header
|
|
432
|
+
mapping: # JSONPath expressions for each output
|
|
433
|
+
header: $.metadata.header
|
|
363
434
|
body: $.content
|
|
364
|
-
footer: $.footer
|
|
435
|
+
footer: $.metadata.footer
|
|
436
|
+
```
|
|
437
|
+
|
|
438
|
+
**How it Works:**
|
|
439
|
+
- Takes a single input (usually JSON)
|
|
440
|
+
- Extracts multiple values using JSONPath
|
|
441
|
+
- Creates named outputs accessible as `nodeId.outputName`
|
|
442
|
+
|
|
443
|
+
**Example:**
|
|
444
|
+
|
|
445
|
+
Input: `{ metadata: { header: 'Title' }, content: 'Body text' }`
|
|
446
|
+
|
|
447
|
+
```yaml
|
|
448
|
+
split_data:
|
|
449
|
+
type: split
|
|
450
|
+
input: previous.node
|
|
451
|
+
mapping:
|
|
452
|
+
title: $.metadata.header # Accessible as split_data.title
|
|
453
|
+
text: $.content # Accessible as split_data.text
|
|
454
|
+
```
|
|
455
|
+
|
|
456
|
+
Later nodes can reference:
|
|
457
|
+
```yaml
|
|
458
|
+
another_node:
|
|
459
|
+
type: code
|
|
460
|
+
input: split_data.title # Gets 'Title'
|
|
365
461
|
```
|
|
366
462
|
|
|
463
|
+
---
|
|
464
|
+
|
|
367
465
|
### Passthrough Node
|
|
368
466
|
|
|
369
|
-
|
|
467
|
+
Passes input directly to output unchanged (useful for routing).
|
|
370
468
|
|
|
469
|
+
**Required Properties:**
|
|
371
470
|
```yaml
|
|
372
471
|
forward:
|
|
373
472
|
type: passthrough
|
|
374
473
|
input: $input
|
|
375
474
|
```
|
|
376
475
|
|
|
476
|
+
**Notes:**
|
|
477
|
+
- No transformation applied
|
|
478
|
+
- Preserves the input type
|
|
479
|
+
- Useful for conditional routing or stage organization
|
|
480
|
+
|
|
481
|
+
---
|
|
482
|
+
|
|
483
|
+
## Input References
|
|
484
|
+
|
|
485
|
+
All nodes (except `reduce`) use the `input` property to specify data source:
|
|
486
|
+
|
|
487
|
+
| Reference Pattern | Description | Example |
|
|
488
|
+
|-------------------|-------------|---------|
|
|
489
|
+
| `$input` | Full request body | `input: $input` |
|
|
490
|
+
| `$input.field` | Specific field from request | `input: $input.text` |
|
|
491
|
+
| `$input.nested.field` | Nested field access | `input: $input.user.name` |
|
|
492
|
+
| `stageName.nodeName` | Output from another node | `input: extract.parser` |
|
|
493
|
+
| `nodeName.outputName` | Split node output | `input: splitter.header` |
|
|
494
|
+
|
|
495
|
+
---
|
|
496
|
+
|
|
497
|
+
## Workflow Structure
|
|
498
|
+
|
|
499
|
+
Every workflow must follow these rules:
|
|
500
|
+
|
|
501
|
+
**Single-Stage Workflows:**
|
|
502
|
+
```yaml
|
|
503
|
+
version: "1.0"
|
|
504
|
+
stages:
|
|
505
|
+
- name: main # Must be named 'main'
|
|
506
|
+
nodes:
|
|
507
|
+
my_node: # Must have exactly 1 node
|
|
508
|
+
type: llm
|
|
509
|
+
input: $input # Must use $input
|
|
510
|
+
# ... node config ...
|
|
511
|
+
```
|
|
512
|
+
|
|
513
|
+
**Multi-Stage Workflows:**
|
|
514
|
+
```yaml
|
|
515
|
+
version: "1.0"
|
|
516
|
+
stages:
|
|
517
|
+
- name: preprocess # First stage: any name
|
|
518
|
+
nodes:
|
|
519
|
+
validator: # First node must use $input
|
|
520
|
+
type: code
|
|
521
|
+
input: $input
|
|
522
|
+
# ... config ...
|
|
523
|
+
|
|
524
|
+
- name: process # Middle stage(s): any name, multiple nodes OK
|
|
525
|
+
nodes:
|
|
526
|
+
analyze:
|
|
527
|
+
type: llm
|
|
528
|
+
input: preprocess.validator
|
|
529
|
+
# ... config ...
|
|
530
|
+
extract:
|
|
531
|
+
type: code
|
|
532
|
+
input: preprocess.validator
|
|
533
|
+
# ... config ...
|
|
534
|
+
|
|
535
|
+
- name: postprocess # Last stage: any name
|
|
536
|
+
nodes:
|
|
537
|
+
formatter: # Must have exactly 1 node (exit node)
|
|
538
|
+
type: code
|
|
539
|
+
input: process.analyze
|
|
540
|
+
# ... config ...
|
|
541
|
+
```
|
|
542
|
+
|
|
543
|
+
**Rules:**
|
|
544
|
+
- **First stage's first node** must use `$input` or `$input.field` as input
|
|
545
|
+
- **Last stage** must have exactly 1 node (its output becomes the API response)
|
|
546
|
+
- Middle stages can have any number of nodes
|
|
547
|
+
- Stage names can be anything (no longer required to be "entry" and "exit")
|
|
548
|
+
|
|
377
549
|
---
|
|
378
550
|
|
|
379
551
|
## Using Plugins
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "web-ai-service",
|
|
3
|
-
"version": "1.0.
|
|
3
|
+
"version": "1.0.2",
|
|
4
4
|
"description": "TypeScript-based Web AI Service that creates configurable AI-powered endpoints from YAML definitions",
|
|
5
5
|
"main": "dist/engine/index.js",
|
|
6
6
|
"bin": {
|
|
@@ -53,4 +53,4 @@
|
|
|
53
53
|
"tsx": "^4.7.0",
|
|
54
54
|
"typescript": "^5.3.3"
|
|
55
55
|
}
|
|
56
|
-
}
|
|
56
|
+
}
|