web-ai-service 1.0.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 +287 -0
- package/dist/engine/cli.d.ts +3 -0
- package/dist/engine/cli.d.ts.map +1 -0
- package/dist/engine/cli.js +4 -0
- package/dist/engine/cli.js.map +1 -0
- package/dist/engine/config/llm-costs.d.ts +16 -0
- package/dist/engine/config/llm-costs.d.ts.map +1 -0
- package/dist/engine/config/llm-costs.js +38 -0
- package/dist/engine/config/llm-costs.js.map +1 -0
- package/dist/engine/core/node-executor.d.ts +8 -0
- package/dist/engine/core/node-executor.d.ts.map +1 -0
- package/dist/engine/core/node-executor.js +150 -0
- package/dist/engine/core/node-executor.js.map +1 -0
- package/dist/engine/core/validator.d.ts +6 -0
- package/dist/engine/core/validator.d.ts.map +1 -0
- package/dist/engine/core/validator.js +498 -0
- package/dist/engine/core/validator.js.map +1 -0
- package/dist/engine/core/workflow-executor.d.ts +6 -0
- package/dist/engine/core/workflow-executor.d.ts.map +1 -0
- package/dist/engine/core/workflow-executor.js +187 -0
- package/dist/engine/core/workflow-executor.js.map +1 -0
- package/dist/engine/core/workflow-loader.d.ts +26 -0
- package/dist/engine/core/workflow-loader.d.ts.map +1 -0
- package/dist/engine/core/workflow-loader.js +265 -0
- package/dist/engine/core/workflow-loader.js.map +1 -0
- package/dist/engine/index.d.ts +5 -0
- package/dist/engine/index.d.ts.map +1 -0
- package/dist/engine/index.js +70 -0
- package/dist/engine/index.js.map +1 -0
- package/dist/engine/nodes/code-node.d.ts +6 -0
- package/dist/engine/nodes/code-node.d.ts.map +1 -0
- package/dist/engine/nodes/code-node.js +70 -0
- package/dist/engine/nodes/code-node.js.map +1 -0
- package/dist/engine/nodes/endpoint-node.d.ts +6 -0
- package/dist/engine/nodes/endpoint-node.d.ts.map +1 -0
- package/dist/engine/nodes/endpoint-node.js +47 -0
- package/dist/engine/nodes/endpoint-node.js.map +1 -0
- package/dist/engine/nodes/llm-node.d.ts +6 -0
- package/dist/engine/nodes/llm-node.d.ts.map +1 -0
- package/dist/engine/nodes/llm-node.js +164 -0
- package/dist/engine/nodes/llm-node.js.map +1 -0
- package/dist/engine/nodes/passthrough-node.d.ts +6 -0
- package/dist/engine/nodes/passthrough-node.d.ts.map +1 -0
- package/dist/engine/nodes/passthrough-node.js +13 -0
- package/dist/engine/nodes/passthrough-node.js.map +1 -0
- package/dist/engine/nodes/reduce-node.d.ts +6 -0
- package/dist/engine/nodes/reduce-node.d.ts.map +1 -0
- package/dist/engine/nodes/reduce-node.js +44 -0
- package/dist/engine/nodes/reduce-node.js.map +1 -0
- package/dist/engine/nodes/split-node.d.ts +10 -0
- package/dist/engine/nodes/split-node.d.ts.map +1 -0
- package/dist/engine/nodes/split-node.js +51 -0
- package/dist/engine/nodes/split-node.js.map +1 -0
- package/dist/engine/providers/gemini.d.ts +27 -0
- package/dist/engine/providers/gemini.d.ts.map +1 -0
- package/dist/engine/providers/gemini.js +163 -0
- package/dist/engine/providers/gemini.js.map +1 -0
- package/dist/engine/providers/grok.d.ts +28 -0
- package/dist/engine/providers/grok.d.ts.map +1 -0
- package/dist/engine/providers/grok.js +164 -0
- package/dist/engine/providers/grok.js.map +1 -0
- package/dist/engine/providers/registry.d.ts +33 -0
- package/dist/engine/providers/registry.d.ts.map +1 -0
- package/dist/engine/providers/registry.js +51 -0
- package/dist/engine/providers/registry.js.map +1 -0
- package/dist/engine/router.d.ts +8 -0
- package/dist/engine/router.d.ts.map +1 -0
- package/dist/engine/router.js +79 -0
- package/dist/engine/router.js.map +1 -0
- package/dist/engine/scripts/cleanup-port.d.ts +2 -0
- package/dist/engine/scripts/cleanup-port.d.ts.map +1 -0
- package/dist/engine/scripts/cleanup-port.js +54 -0
- package/dist/engine/scripts/cleanup-port.js.map +1 -0
- package/dist/engine/scripts/create-endpoint.d.ts +2 -0
- package/dist/engine/scripts/create-endpoint.d.ts.map +1 -0
- package/dist/engine/scripts/create-endpoint.js +83 -0
- package/dist/engine/scripts/create-endpoint.js.map +1 -0
- package/dist/engine/scripts/scan-deps.d.ts +2 -0
- package/dist/engine/scripts/scan-deps.d.ts.map +1 -0
- package/dist/engine/scripts/scan-deps.js +112 -0
- package/dist/engine/scripts/scan-deps.js.map +1 -0
- package/dist/engine/scripts/validate-workflows.d.ts +3 -0
- package/dist/engine/scripts/validate-workflows.d.ts.map +1 -0
- package/dist/engine/scripts/validate-workflows.js +75 -0
- package/dist/engine/scripts/validate-workflows.js.map +1 -0
- package/dist/engine/server.d.ts +10 -0
- package/dist/engine/server.d.ts.map +1 -0
- package/dist/engine/server.js +92 -0
- package/dist/engine/server.js.map +1 -0
- package/dist/engine/types/index.d.ts +320 -0
- package/dist/engine/types/index.d.ts.map +1 -0
- package/dist/engine/types/index.js +24 -0
- package/dist/engine/types/index.js.map +1 -0
- package/dist/engine/utils/file-cache.d.ts +31 -0
- package/dist/engine/utils/file-cache.d.ts.map +1 -0
- package/dist/engine/utils/file-cache.js +68 -0
- package/dist/engine/utils/file-cache.js.map +1 -0
- package/dist/engine/utils/file-resolver.d.ts +21 -0
- package/dist/engine/utils/file-resolver.d.ts.map +1 -0
- package/dist/engine/utils/file-resolver.js +33 -0
- package/dist/engine/utils/file-resolver.js.map +1 -0
- package/dist/engine/utils/jsonpath.d.ts +13 -0
- package/dist/engine/utils/jsonpath.d.ts.map +1 -0
- package/dist/engine/utils/jsonpath.js +38 -0
- package/dist/engine/utils/jsonpath.js.map +1 -0
- package/dist/engine/utils/logger.d.ts +11 -0
- package/dist/engine/utils/logger.d.ts.map +1 -0
- package/dist/engine/utils/logger.js +24 -0
- package/dist/engine/utils/logger.js.map +1 -0
- package/dist/engine/utils/metrics.d.ts +6 -0
- package/dist/engine/utils/metrics.d.ts.map +1 -0
- package/dist/engine/utils/metrics.js +82 -0
- package/dist/engine/utils/metrics.js.map +1 -0
- package/dist/engine/utils/schema-validator.d.ts +10 -0
- package/dist/engine/utils/schema-validator.d.ts.map +1 -0
- package/dist/engine/utils/schema-validator.js +61 -0
- package/dist/engine/utils/schema-validator.js.map +1 -0
- package/package.json +53 -0
package/README.md
ADDED
|
@@ -0,0 +1,287 @@
|
|
|
1
|
+
# Web AI Service
|
|
2
|
+
|
|
3
|
+
A TypeScript-based workflow engine that creates dynamic API endpoints from YAML workflow definitions. Build powerful API pipelines with LLM calls, custom code execution, and data transformations without writing server code.
|
|
4
|
+
|
|
5
|
+
## Features
|
|
6
|
+
|
|
7
|
+
- 🚀 **YAML-Based Configuration** - Define API endpoints declaratively
|
|
8
|
+
- 🤖 **LLM Integration** - Built-in support for Gemini and Grok
|
|
9
|
+
- 📝 **Custom Code Nodes** - Execute TypeScript functions in your workflows
|
|
10
|
+
- ⚡ **Parallel Execution** - Run multiple nodes concurrently with error strategies
|
|
11
|
+
- 🔄 **Data Transformation** - Reduce, split, and map data with JSONPath
|
|
12
|
+
- ✅ **Input Validation** - JSON Schema validation on request inputs
|
|
13
|
+
- 🎯 **Type-Safe** - Full TypeScript support with strict typing
|
|
14
|
+
- 🌐 **Auto-Routing** - Endpoint folders automatically become API routes
|
|
15
|
+
|
|
16
|
+
---
|
|
17
|
+
|
|
18
|
+
## Quick Start
|
|
19
|
+
|
|
20
|
+
### 1. Installation
|
|
21
|
+
|
|
22
|
+
You can install the engine globally or in your project:
|
|
23
|
+
|
|
24
|
+
```bash
|
|
25
|
+
npm install -g web-ai-service
|
|
26
|
+
```
|
|
27
|
+
|
|
28
|
+
Or just use `npx`:
|
|
29
|
+
|
|
30
|
+
```bash
|
|
31
|
+
npx web-ai-service
|
|
32
|
+
```
|
|
33
|
+
|
|
34
|
+
### 2. Setup (if running from source)
|
|
35
|
+
|
|
36
|
+
```bash
|
|
37
|
+
# Clone or navigate to your project directory
|
|
38
|
+
cd API-Workflow
|
|
39
|
+
|
|
40
|
+
# Install dependencies
|
|
41
|
+
npm install
|
|
42
|
+
|
|
43
|
+
# Copy environment template
|
|
44
|
+
cp .env.example .env
|
|
45
|
+
```
|
|
46
|
+
|
|
47
|
+
### 2. Configuration
|
|
48
|
+
|
|
49
|
+
Edit `.env` with your API keys:
|
|
50
|
+
|
|
51
|
+
```bash
|
|
52
|
+
PORT=3000
|
|
53
|
+
GEMINI_API_KEY=your-gemini-api-key-here
|
|
54
|
+
GROK_API_KEY=your-grok-api-key-here
|
|
55
|
+
```
|
|
56
|
+
|
|
57
|
+
### 3. Start the Server
|
|
58
|
+
|
|
59
|
+
```bash
|
|
60
|
+
# Development (with hot reload)
|
|
61
|
+
npm run dev
|
|
62
|
+
|
|
63
|
+
# Production
|
|
64
|
+
npm run build && npm start
|
|
65
|
+
```
|
|
66
|
+
|
|
67
|
+
The server starts at `http://localhost:3000`.
|
|
68
|
+
|
|
69
|
+
---
|
|
70
|
+
|
|
71
|
+
## Project Structure
|
|
72
|
+
|
|
73
|
+
```
|
|
74
|
+
API-Workflow/
|
|
75
|
+
├── engine/ # Core workflow engine (framework code)
|
|
76
|
+
│ ├── core/ # Core execution logic
|
|
77
|
+
│ ├── nodes/ # Node type executors
|
|
78
|
+
│ ├── providers/ # LLM provider implementations
|
|
79
|
+
│ ├── types/ # TypeScript type definitions
|
|
80
|
+
│ └── utils/ # Utility functions
|
|
81
|
+
│
|
|
82
|
+
├── src/ # User content (you edit this)
|
|
83
|
+
│ ├── endpoints/ # Your API endpoints
|
|
84
|
+
│ │ └── {endpoint-name}/ # One folder per endpoint route
|
|
85
|
+
│ │ ├── POST.yaml # Workflow definition (method = filename)
|
|
86
|
+
│ │ ├── codes/ # Endpoint-specific code files
|
|
87
|
+
│ │ └── prompts/ # Endpoint-specific prompt files
|
|
88
|
+
│ │
|
|
89
|
+
│ └── plugins/ # Shared code modules (via @code-plugins/*)
|
|
90
|
+
│
|
|
91
|
+
└── .env # API keys and configuration
|
|
92
|
+
```
|
|
93
|
+
|
|
94
|
+
### Key Concepts
|
|
95
|
+
|
|
96
|
+
| Concept | Description |
|
|
97
|
+
|---------|-------------|
|
|
98
|
+
| **Endpoint** | A folder in `src/endpoints/` that becomes an API route (e.g., `summarize/` → `/summarize`) |
|
|
99
|
+
| **Workflow** | A YAML file (e.g., `POST.yaml`) defining the request processing pipeline |
|
|
100
|
+
| **Stage** | A sequential step in the workflow containing one or more nodes |
|
|
101
|
+
| **Node** | An individual processing unit (LLM call, code execution, etc.) |
|
|
102
|
+
|
|
103
|
+
---
|
|
104
|
+
|
|
105
|
+
## Creating Your First Endpoint
|
|
106
|
+
|
|
107
|
+
### Example: Text Summarization API
|
|
108
|
+
|
|
109
|
+
**Goal**: Create `POST /summarize` that takes text and returns a summary.
|
|
110
|
+
|
|
111
|
+
#### Step 1: Create the Endpoint Folder
|
|
112
|
+
|
|
113
|
+
```bash
|
|
114
|
+
mkdir -p src/endpoints/summarize/prompts
|
|
115
|
+
```
|
|
116
|
+
|
|
117
|
+
#### Step 2: Create the System Prompt
|
|
118
|
+
|
|
119
|
+
Create `src/endpoints/summarize/prompts/summarizer-system.txt`:
|
|
120
|
+
|
|
121
|
+
```text
|
|
122
|
+
You are a concise summarization assistant. Summarize the provided text clearly.
|
|
123
|
+
|
|
124
|
+
Guidelines:
|
|
125
|
+
- Capture the main points and key information
|
|
126
|
+
- Use clear, professional language
|
|
127
|
+
- Keep the summary to 2-3 paragraphs
|
|
128
|
+
```
|
|
129
|
+
|
|
130
|
+
#### Step 3: Create the Workflow
|
|
131
|
+
|
|
132
|
+
Create `src/endpoints/summarize/POST.yaml`:
|
|
133
|
+
|
|
134
|
+
```yaml
|
|
135
|
+
version: "1.0"
|
|
136
|
+
|
|
137
|
+
stages:
|
|
138
|
+
- name: main
|
|
139
|
+
nodes:
|
|
140
|
+
summarize:
|
|
141
|
+
type: llm
|
|
142
|
+
input: $input
|
|
143
|
+
provider: gemini
|
|
144
|
+
model: gemini-2.0-flash-lite
|
|
145
|
+
temperature: 0.3
|
|
146
|
+
maxTokens: 1024
|
|
147
|
+
systemMessages:
|
|
148
|
+
- file: summarizer-system.txt
|
|
149
|
+
cache: true
|
|
150
|
+
```
|
|
151
|
+
|
|
152
|
+
#### Step 4: Test It
|
|
153
|
+
|
|
154
|
+
```bash
|
|
155
|
+
npm run dev
|
|
156
|
+
|
|
157
|
+
curl -X POST http://localhost:3000/summarize \
|
|
158
|
+
-H "Content-Type: application/json" \
|
|
159
|
+
-d '{"text": "Your long text to summarize goes here..."}'
|
|
160
|
+
```
|
|
161
|
+
|
|
162
|
+
---
|
|
163
|
+
|
|
164
|
+
## Adding Custom Code Nodes
|
|
165
|
+
|
|
166
|
+
For custom processing logic, add TypeScript files to your endpoint's `codes/` folder.
|
|
167
|
+
|
|
168
|
+
### Example: Validation + Processing
|
|
169
|
+
|
|
170
|
+
Create `src/endpoints/summarize/codes/validate-input.ts`:
|
|
171
|
+
|
|
172
|
+
```typescript
|
|
173
|
+
import type { NodeOutput } from '@workflow/types';
|
|
174
|
+
|
|
175
|
+
export default async function(input: unknown): Promise<NodeOutput> {
|
|
176
|
+
const body = input as { text?: string };
|
|
177
|
+
|
|
178
|
+
if (!body.text || typeof body.text !== 'string') {
|
|
179
|
+
throw new Error('Missing required field: text');
|
|
180
|
+
}
|
|
181
|
+
|
|
182
|
+
if (body.text.length < 10) {
|
|
183
|
+
throw new Error('Text must be at least 10 characters');
|
|
184
|
+
}
|
|
185
|
+
|
|
186
|
+
return { type: 'string', value: body.text };
|
|
187
|
+
}
|
|
188
|
+
```
|
|
189
|
+
|
|
190
|
+
Update `src/endpoints/summarize/POST.yaml`:
|
|
191
|
+
|
|
192
|
+
```yaml
|
|
193
|
+
version: "1.0"
|
|
194
|
+
|
|
195
|
+
stages:
|
|
196
|
+
- name: entry
|
|
197
|
+
nodes:
|
|
198
|
+
validate:
|
|
199
|
+
type: code
|
|
200
|
+
input: $input
|
|
201
|
+
file: validate-input.ts
|
|
202
|
+
|
|
203
|
+
- name: summarization
|
|
204
|
+
nodes:
|
|
205
|
+
summarize:
|
|
206
|
+
type: llm
|
|
207
|
+
input: entry.validate
|
|
208
|
+
provider: gemini
|
|
209
|
+
model: gemini-2.0-flash-lite
|
|
210
|
+
temperature: 0.3
|
|
211
|
+
maxTokens: 1024
|
|
212
|
+
systemMessages:
|
|
213
|
+
- file: summarizer-system.txt
|
|
214
|
+
cache: true
|
|
215
|
+
```
|
|
216
|
+
|
|
217
|
+
---
|
|
218
|
+
|
|
219
|
+
## Shared Plugins
|
|
220
|
+
|
|
221
|
+
For reusable code across endpoints, add files to `src/plugins/` and import via `@code-plugins/*`:
|
|
222
|
+
|
|
223
|
+
```typescript
|
|
224
|
+
// In any code file
|
|
225
|
+
import { myHelper } from '@code-plugins/my-shared-lib.js';
|
|
226
|
+
```
|
|
227
|
+
|
|
228
|
+
---
|
|
229
|
+
|
|
230
|
+
## Node Types Reference
|
|
231
|
+
|
|
232
|
+
| Type | Purpose | Key Properties |
|
|
233
|
+
|------|---------|----------------|
|
|
234
|
+
| `llm` | Call LLM provider | `provider`, `model`, `systemMessages`, `temperature`, `maxTokens` |
|
|
235
|
+
| `code` | Execute TypeScript | `file` |
|
|
236
|
+
| `reduce` | Combine outputs | `inputs`, `mapping` |
|
|
237
|
+
| `split` | Divide output | `mapping` |
|
|
238
|
+
| `passthrough` | Pass input unchanged | (none) |
|
|
239
|
+
|
|
240
|
+
---
|
|
241
|
+
|
|
242
|
+
## Available Commands
|
|
243
|
+
|
|
244
|
+
| Command | Description |
|
|
245
|
+
|---------|-------------|
|
|
246
|
+
| `npm run dev` | Start development server with hot reload |
|
|
247
|
+
| `npm run create-endpoint` | Scaffold a new API endpoint interactively |
|
|
248
|
+
| `npm run build` | Compile TypeScript to JavaScript |
|
|
249
|
+
| `npm start` | Start production server |
|
|
250
|
+
| `npm run validate` | Validate all workflows |
|
|
251
|
+
| `npm run scan-deps` | Scan and install code node dependencies |
|
|
252
|
+
| `npm run lint` | Run ESLint |
|
|
253
|
+
| `npm run format` | Format code with Prettier |
|
|
254
|
+
|
|
255
|
+
---
|
|
256
|
+
|
|
257
|
+
## Environment Variables
|
|
258
|
+
|
|
259
|
+
| Variable | Default | Description |
|
|
260
|
+
|----------|---------|-------------|
|
|
261
|
+
| `PORT` | `3000` | Server port |
|
|
262
|
+
| `GEMINI_API_KEY` | - | Gemini API key (required for Gemini) |
|
|
263
|
+
| `GROK_API_KEY` | - | Grok API key (required for Grok) |
|
|
264
|
+
| `LLM_TIMEOUT_MS` | `30000` | LLM call timeout |
|
|
265
|
+
| `LOG_LEVEL` | `info` | Logging level (`debug`, `info`, `warn`, `error`) |
|
|
266
|
+
|
|
267
|
+
---
|
|
268
|
+
|
|
269
|
+
## Troubleshooting
|
|
270
|
+
|
|
271
|
+
| Error | Solution |
|
|
272
|
+
|-------|----------|
|
|
273
|
+
| "Provider not found" | Check `provider` is `gemini` or `grok` and API key is set in `.env` |
|
|
274
|
+
| "Code node file not found" | Verify file exists in `codes/` folder with correct filename |
|
|
275
|
+
| "Cannot find module '@workflow/types'" | Run `npm run build` or restart TypeScript server |
|
|
276
|
+
| LLM Timeout | Increase `LLM_TIMEOUT_MS` in `.env` or use a faster model |
|
|
277
|
+
|
|
278
|
+
---
|
|
279
|
+
|
|
280
|
+
## Documentation
|
|
281
|
+
|
|
282
|
+
- [Full Specification](__dev_guide__/Dynamic-API-Service-SPEC.md) - Complete technical spec
|
|
283
|
+
- [Development Notes](_dev_notes_/plan.md) - Implementation roadmap
|
|
284
|
+
|
|
285
|
+
## License
|
|
286
|
+
|
|
287
|
+
ISC
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"cli.d.ts","sourceRoot":"","sources":["../../engine/cli.ts"],"names":[],"mappings":""}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"cli.js","sourceRoot":"","sources":["../../engine/cli.ts"],"names":[],"mappings":";AACA,OAAO,EAAE,IAAI,EAAE,MAAM,YAAY,CAAC;AAElC,IAAI,EAAE,CAAC"}
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* LLM Cost Configuration
|
|
3
|
+
* Costs are in USD per 1 million tokens
|
|
4
|
+
*/
|
|
5
|
+
export interface ModelCost {
|
|
6
|
+
inputCostPer1M: number;
|
|
7
|
+
outputCostPer1M: number;
|
|
8
|
+
cachedInputCostPer1M?: number;
|
|
9
|
+
}
|
|
10
|
+
export declare const defaultLLMCosts: Record<string, ModelCost>;
|
|
11
|
+
/**
|
|
12
|
+
* Get cost for a specific model
|
|
13
|
+
* Falls back to 0 if model not found
|
|
14
|
+
*/
|
|
15
|
+
export declare function getModelCost(model: string): ModelCost;
|
|
16
|
+
//# sourceMappingURL=llm-costs.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"llm-costs.d.ts","sourceRoot":"","sources":["../../../engine/config/llm-costs.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,MAAM,WAAW,SAAS;IACtB,cAAc,EAAE,MAAM,CAAC;IACvB,eAAe,EAAE,MAAM,CAAC;IACxB,oBAAoB,CAAC,EAAE,MAAM,CAAC;CACjC;AAED,eAAO,MAAM,eAAe,EAAE,MAAM,CAAC,MAAM,EAAE,SAAS,CAiBrD,CAAC;AAEF;;;GAGG;AACH,wBAAgB,YAAY,CAAC,KAAK,EAAE,MAAM,GAAG,SAAS,CAerD"}
|
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* LLM Cost Configuration
|
|
3
|
+
* Costs are in USD per 1 million tokens
|
|
4
|
+
*/
|
|
5
|
+
export const defaultLLMCosts = {
|
|
6
|
+
// Gemini 3 Preview Models
|
|
7
|
+
'gemini-3-pro-preview': { inputCostPer1M: 2.00, cachedInputCostPer1M: 0.20, outputCostPer1M: 12.00 },
|
|
8
|
+
'gemini-3-flash-preview': { inputCostPer1M: 0.50, cachedInputCostPer1M: 0.05, outputCostPer1M: 3.00 },
|
|
9
|
+
// Gemini 2.5 Models
|
|
10
|
+
'gemini-2.5-pro': { inputCostPer1M: 1.25, cachedInputCostPer1M: 0.125, outputCostPer1M: 10.00 }, // Corrected swapped values
|
|
11
|
+
'gemini-2.5-flash': { inputCostPer1M: 0.30, cachedInputCostPer1M: 0.03, outputCostPer1M: 2.50 },
|
|
12
|
+
'gemini-2.5-flash-lite': { inputCostPer1M: 0.10, cachedInputCostPer1M: 0.01, outputCostPer1M: 0.40 },
|
|
13
|
+
// Gemini 2.0 Models
|
|
14
|
+
'gemini-2.0-flash': { inputCostPer1M: 0.10, cachedInputCostPer1M: 0.025, outputCostPer1M: 0.40 },
|
|
15
|
+
'gemini-2.0-flash-lite': { inputCostPer1M: 0.075, cachedInputCostPer1M: 0.075, outputCostPer1M: 0.30 }, // User specified cached=input
|
|
16
|
+
// Grok Models
|
|
17
|
+
'grok-4-1-fast-reasoning': { inputCostPer1M: 0.20, cachedInputCostPer1M: 0.20, outputCostPer1M: 0.50 },
|
|
18
|
+
'grok-4-1-fast-non-reasoning': { inputCostPer1M: 0.20, cachedInputCostPer1M: 0.20, outputCostPer1M: 0.50 },
|
|
19
|
+
};
|
|
20
|
+
/**
|
|
21
|
+
* Get cost for a specific model
|
|
22
|
+
* Falls back to 0 if model not found
|
|
23
|
+
*/
|
|
24
|
+
export function getModelCost(model) {
|
|
25
|
+
// Exact match
|
|
26
|
+
if (defaultLLMCosts[model]) {
|
|
27
|
+
return defaultLLMCosts[model];
|
|
28
|
+
}
|
|
29
|
+
// Try finding matching prefix (e.g. gemini-1.5-flash-001 matches gemini-1.5-flash)
|
|
30
|
+
// This is a simple heuristic, might need refinement
|
|
31
|
+
const knownModels = Object.keys(defaultLLMCosts);
|
|
32
|
+
const match = knownModels.find(m => model.startsWith(m));
|
|
33
|
+
if (match) {
|
|
34
|
+
return defaultLLMCosts[match];
|
|
35
|
+
}
|
|
36
|
+
return { inputCostPer1M: 0, outputCostPer1M: 0 };
|
|
37
|
+
}
|
|
38
|
+
//# sourceMappingURL=llm-costs.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"llm-costs.js","sourceRoot":"","sources":["../../../engine/config/llm-costs.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAQH,MAAM,CAAC,MAAM,eAAe,GAA8B;IACtD,0BAA0B;IAC1B,sBAAsB,EAAE,EAAE,cAAc,EAAE,IAAI,EAAE,oBAAoB,EAAE,IAAI,EAAE,eAAe,EAAE,KAAK,EAAE;IACpG,wBAAwB,EAAE,EAAE,cAAc,EAAE,IAAI,EAAE,oBAAoB,EAAE,IAAI,EAAE,eAAe,EAAE,IAAI,EAAE;IAErG,oBAAoB;IACpB,gBAAgB,EAAE,EAAE,cAAc,EAAE,IAAI,EAAE,oBAAoB,EAAE,KAAK,EAAE,eAAe,EAAE,KAAK,EAAE,EAAE,2BAA2B;IAC5H,kBAAkB,EAAE,EAAE,cAAc,EAAE,IAAI,EAAE,oBAAoB,EAAE,IAAI,EAAE,eAAe,EAAE,IAAI,EAAE;IAC/F,uBAAuB,EAAE,EAAE,cAAc,EAAE,IAAI,EAAE,oBAAoB,EAAE,IAAI,EAAE,eAAe,EAAE,IAAI,EAAE;IAEpG,oBAAoB;IACpB,kBAAkB,EAAE,EAAE,cAAc,EAAE,IAAI,EAAE,oBAAoB,EAAE,KAAK,EAAE,eAAe,EAAE,IAAI,EAAE;IAChG,uBAAuB,EAAE,EAAE,cAAc,EAAE,KAAK,EAAE,oBAAoB,EAAE,KAAK,EAAE,eAAe,EAAE,IAAI,EAAE,EAAE,8BAA8B;IAEtI,cAAc;IACd,yBAAyB,EAAE,EAAE,cAAc,EAAE,IAAI,EAAE,oBAAoB,EAAE,IAAI,EAAE,eAAe,EAAE,IAAI,EAAE;IACtG,6BAA6B,EAAE,EAAE,cAAc,EAAE,IAAI,EAAE,oBAAoB,EAAE,IAAI,EAAE,eAAe,EAAE,IAAI,EAAE;CAC7G,CAAC;AAEF;;;GAGG;AACH,MAAM,UAAU,YAAY,CAAC,KAAa;IACtC,cAAc;IACd,IAAI,eAAe,CAAC,KAAK,CAAC,EAAE,CAAC;QACzB,OAAO,eAAe,CAAC,KAAK,CAAC,CAAC;IAClC,CAAC;IAED,mFAAmF;IACnF,oDAAoD;IACpD,MAAM,WAAW,GAAG,MAAM,CAAC,IAAI,CAAC,eAAe,CAAC,CAAC;IACjD,MAAM,KAAK,GAAG,WAAW,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,CAAC,KAAK,CAAC,UAAU,CAAC,CAAC,CAAC,CAAC,CAAC;IACzD,IAAI,KAAK,EAAE,CAAC;QACR,OAAO,eAAe,CAAC,KAAK,CAAC,CAAC;IAClC,CAAC;IAED,OAAO,EAAE,cAAc,EAAE,CAAC,EAAE,eAAe,EAAE,CAAC,EAAE,CAAC;AACrD,CAAC"}
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
import type { NodeDefinition, NodeOutput, ExecutionContext, WorkflowDefinition, StageDefinition } from '../types/index.js';
|
|
2
|
+
/**
|
|
3
|
+
* Execute a single node within a stage
|
|
4
|
+
* Outputs are stored as stageName.nodeId to allow stage-scoped references
|
|
5
|
+
* Input is passed from stage at runtime (nodes: { nodeId: input })
|
|
6
|
+
*/
|
|
7
|
+
export declare function executeNode(node: NodeDefinition, inputRef: string, stage: StageDefinition, context: ExecutionContext, workflow: WorkflowDefinition): Promise<NodeOutput>;
|
|
8
|
+
//# sourceMappingURL=node-executor.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"node-executor.d.ts","sourceRoot":"","sources":["../../../engine/core/node-executor.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EACR,cAAc,EACd,UAAU,EACV,gBAAgB,EAChB,kBAAkB,EAClB,eAAe,EAClB,MAAM,mBAAmB,CAAC;AAU3B;;;;GAIG;AACH,wBAAsB,WAAW,CAC7B,IAAI,EAAE,cAAc,EACpB,QAAQ,EAAE,MAAM,EAChB,KAAK,EAAE,eAAe,EACtB,OAAO,EAAE,gBAAgB,EACzB,QAAQ,EAAE,kBAAkB,GAC7B,OAAO,CAAC,UAAU,CAAC,CA6FrB"}
|
|
@@ -0,0 +1,150 @@
|
|
|
1
|
+
import { executeCodeNode } from '../nodes/code-node.js';
|
|
2
|
+
import { executeLLMNode } from '../nodes/llm-node.js';
|
|
3
|
+
import { executeReduceNode } from '../nodes/reduce-node.js';
|
|
4
|
+
import { executeSplitNode } from '../nodes/split-node.js';
|
|
5
|
+
import { executePassthroughNode } from '../nodes/passthrough-node.js';
|
|
6
|
+
import { executeEndpointNode } from '../nodes/endpoint-node.js';
|
|
7
|
+
import logger from '../utils/logger.js';
|
|
8
|
+
import { ErrorCode } from '../types/index.js';
|
|
9
|
+
/**
|
|
10
|
+
* Execute a single node within a stage
|
|
11
|
+
* Outputs are stored as stageName.nodeId to allow stage-scoped references
|
|
12
|
+
* Input is passed from stage at runtime (nodes: { nodeId: input })
|
|
13
|
+
*/
|
|
14
|
+
export async function executeNode(node, inputRef, stage, context, workflow) {
|
|
15
|
+
const outputKey = `${stage.name}.${node.id}`;
|
|
16
|
+
const startTime = Date.now();
|
|
17
|
+
try {
|
|
18
|
+
let output;
|
|
19
|
+
switch (node.type) {
|
|
20
|
+
case 'code': {
|
|
21
|
+
const input = resolveInput(inputRef, context);
|
|
22
|
+
output = await executeCodeNode(node, input, context, workflow);
|
|
23
|
+
break;
|
|
24
|
+
}
|
|
25
|
+
case 'llm': {
|
|
26
|
+
const input = resolveInput(inputRef, context);
|
|
27
|
+
output = await executeLLMNode(node, input, workflow, context);
|
|
28
|
+
break;
|
|
29
|
+
}
|
|
30
|
+
case 'reduce': {
|
|
31
|
+
output = await executeReduceNode(node, context);
|
|
32
|
+
break;
|
|
33
|
+
}
|
|
34
|
+
case 'split': {
|
|
35
|
+
const input = resolveInput(inputRef, context);
|
|
36
|
+
const splitOutputs = await executeSplitNode(node, input);
|
|
37
|
+
// Store split outputs with stage prefix
|
|
38
|
+
const stageKey = `${stage.name}.${node.id}`;
|
|
39
|
+
context.splitOutputs.set(stageKey, splitOutputs);
|
|
40
|
+
// Return a placeholder output (split doesn't have a single output)
|
|
41
|
+
output = {
|
|
42
|
+
type: 'json',
|
|
43
|
+
value: Object.fromEntries(Array.from(splitOutputs.entries()).map(([key, val]) => [key, val.value])),
|
|
44
|
+
};
|
|
45
|
+
break;
|
|
46
|
+
}
|
|
47
|
+
case 'passthrough': {
|
|
48
|
+
const input = resolveInput(inputRef, context);
|
|
49
|
+
if (!input) {
|
|
50
|
+
throw new Error(`${ErrorCode.NODE_NOT_FOUND}: Input '${inputRef}' not found`);
|
|
51
|
+
}
|
|
52
|
+
output = await executePassthroughNode(node, { type: 'json', value: input });
|
|
53
|
+
break;
|
|
54
|
+
}
|
|
55
|
+
case 'endpoint': {
|
|
56
|
+
const input = resolveInput(inputRef, context);
|
|
57
|
+
output = await executeEndpointNode(node, input, context);
|
|
58
|
+
break;
|
|
59
|
+
}
|
|
60
|
+
default:
|
|
61
|
+
throw new Error(`Unknown node type: ${node.type}`);
|
|
62
|
+
}
|
|
63
|
+
// Store output with stage-scoped key (no caching, always execute)
|
|
64
|
+
context.nodeOutputs.set(outputKey, output);
|
|
65
|
+
// Record timing with stage-scoped key
|
|
66
|
+
const duration = Date.now() - startTime;
|
|
67
|
+
context.timing.set(outputKey, duration);
|
|
68
|
+
logger.info('Node executed successfully', {
|
|
69
|
+
stage: stage.name,
|
|
70
|
+
nodeId: node.id,
|
|
71
|
+
outputKey,
|
|
72
|
+
type: node.type,
|
|
73
|
+
duration: `${duration}ms`,
|
|
74
|
+
outputType: output.type,
|
|
75
|
+
});
|
|
76
|
+
return output;
|
|
77
|
+
}
|
|
78
|
+
catch (error) {
|
|
79
|
+
const duration = Date.now() - startTime;
|
|
80
|
+
context.timing.set(outputKey, duration);
|
|
81
|
+
logger.error('Node execution failed', {
|
|
82
|
+
stage: stage.name,
|
|
83
|
+
nodeId: node.id,
|
|
84
|
+
type: node.type,
|
|
85
|
+
duration: `${duration}ms`,
|
|
86
|
+
error: error instanceof Error ? error.message : String(error),
|
|
87
|
+
});
|
|
88
|
+
throw error;
|
|
89
|
+
}
|
|
90
|
+
}
|
|
91
|
+
/**
|
|
92
|
+
* Resolve input value from context
|
|
93
|
+
* Supports: $input, $params.paramName, stageName.nodeId
|
|
94
|
+
*/
|
|
95
|
+
function resolveInput(inputRef, context) {
|
|
96
|
+
// Special case: $input refers to raw request body
|
|
97
|
+
if (inputRef === '$input') {
|
|
98
|
+
return context.input;
|
|
99
|
+
}
|
|
100
|
+
// Special case: $params.paramName refers to route parameters
|
|
101
|
+
if (inputRef.startsWith('$params.')) {
|
|
102
|
+
const paramName = inputRef.slice(8); // Remove '$params.'
|
|
103
|
+
const paramValue = context.params[paramName];
|
|
104
|
+
if (paramValue === undefined) {
|
|
105
|
+
throw new Error(`${ErrorCode.NODE_NOT_FOUND}: Route parameter '${paramName}' not found`);
|
|
106
|
+
}
|
|
107
|
+
return paramValue;
|
|
108
|
+
}
|
|
109
|
+
// Support $input.property access
|
|
110
|
+
if (inputRef.startsWith('$input.')) {
|
|
111
|
+
const key = inputRef.replace('$input.', '');
|
|
112
|
+
if (typeof context.input === 'object' && context.input !== null) {
|
|
113
|
+
return resolveObjectPath(context.input, key);
|
|
114
|
+
}
|
|
115
|
+
return undefined;
|
|
116
|
+
}
|
|
117
|
+
// Check for stage.node reference (e.g., "entry.summarize")
|
|
118
|
+
if (inputRef.includes('.')) {
|
|
119
|
+
const parts = inputRef.split('.');
|
|
120
|
+
// Handle split output reference (stageName.nodeId.outputName)
|
|
121
|
+
if (parts.length === 3) {
|
|
122
|
+
const [stageName, nodeId, outputName] = parts;
|
|
123
|
+
const stageKey = `${stageName}.${nodeId}`;
|
|
124
|
+
const splitOutputs = context.splitOutputs.get(stageKey);
|
|
125
|
+
if (splitOutputs) {
|
|
126
|
+
const splitOutput = splitOutputs.get(outputName);
|
|
127
|
+
if (splitOutput) {
|
|
128
|
+
return splitOutput.value;
|
|
129
|
+
}
|
|
130
|
+
}
|
|
131
|
+
throw new Error(`${ErrorCode.NODE_NOT_FOUND}: Split output '${inputRef}' not found`);
|
|
132
|
+
}
|
|
133
|
+
// Standard stage.node reference (stageName.nodeId)
|
|
134
|
+
const nodeOutput = context.nodeOutputs.get(inputRef);
|
|
135
|
+
if (nodeOutput) {
|
|
136
|
+
return nodeOutput.value;
|
|
137
|
+
}
|
|
138
|
+
throw new Error(`${ErrorCode.NODE_NOT_FOUND}: Output '${inputRef}' not found. Input must be in format 'stageName.nodeId'`);
|
|
139
|
+
}
|
|
140
|
+
throw new Error(`${ErrorCode.NODE_NOT_FOUND}: Invalid input reference '${inputRef}'. Must be '$input' or 'stageName.nodeId'`);
|
|
141
|
+
}
|
|
142
|
+
/**
|
|
143
|
+
* Helper to resolve object path (e.g., "prop.subprop")
|
|
144
|
+
*/
|
|
145
|
+
function resolveObjectPath(obj, path) {
|
|
146
|
+
return path.split('.').reduce((prev, curr) => {
|
|
147
|
+
return prev ? prev[curr] : undefined;
|
|
148
|
+
}, obj);
|
|
149
|
+
}
|
|
150
|
+
//# sourceMappingURL=node-executor.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"node-executor.js","sourceRoot":"","sources":["../../../engine/core/node-executor.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"validator.d.ts","sourceRoot":"","sources":["../../../engine/core/validator.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,kBAAkB,EAAE,gBAAgB,EAAsC,MAAM,mBAAmB,CAAC;AAOlH;;GAEG;AACH,wBAAsB,gBAAgB,CAAC,QAAQ,EAAE,kBAAkB,GAAG,OAAO,CAAC,gBAAgB,CAAC,CAwC9F"}
|