@ryanfw/prompt-orchestration-pipeline 0.17.0 → 0.17.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 +100 -635
- package/docs/pop-task-guide.md +64 -13
- package/package.json +1 -1
- package/src/api/validators/json.js +6 -1
- package/src/components/ui/RestartJobModal.jsx +21 -17
- package/src/providers/moonshot.js +56 -0
- package/src/ui/client/api.js +3 -0
- package/src/ui/dist/assets/{index-xx8otyG0.js → index-jIuZSALW.js} +44 -38
- package/src/ui/dist/assets/{index-xx8otyG0.js.map → index-jIuZSALW.js.map} +1 -1
- package/src/ui/dist/assets/style-CdV-vuS0.css +180 -0
- package/src/ui/dist/index.html +2 -2
- package/src/ui/endpoints/job-control-endpoints.js +9 -7
- package/src/ui/server.js +5 -13
- package/src/ui/dist/assets/style-CVd3RRU2.css +0 -180
package/README.md
CHANGED
|
@@ -1,680 +1,145 @@
|
|
|
1
|
-
#
|
|
1
|
+
# Prompt Orchestration Pipeline (POP)
|
|
2
2
|
|
|
3
|
-
A
|
|
3
|
+
**A local-first, process-isolated framework for building reliable, autonomous AI agents.**
|
|
4
4
|
|
|
5
|
-
Instead of relying on
|
|
6
|
-
|
|
7
|
-
This repository provides a reference implementation of a prompt‑orchestration pipeline that can be consumed as an npm package by other Node.js projects. It is intentionally lightweight: just enough orchestration to run complex pipelines, inspect intermediate artifacts, and evolve new strategies.
|
|
5
|
+
This system allows engineers to compose complex chains of LLM tasks into resilient pipelines. Instead of relying on fragile "mega-prompts" or black-box scripts, POP decomposes work into standardized stages, enforcing quality through autonomous critique loops and robust architecture.
|
|
8
6
|
|
|
9
7
|
---
|
|
10
8
|
|
|
11
|
-
##
|
|
12
|
-
|
|
13
|
-
Single‑prompt strategies are fragile:
|
|
9
|
+
## Documentation
|
|
14
10
|
|
|
15
|
-
-
|
|
16
|
-
-
|
|
17
|
-
-
|
|
11
|
+
- **[Architecture Deep-Dive](docs/current-architecture.md)**: Detailed breakdown of the orchestrator, runner, and state management.
|
|
12
|
+
- **[Task Development Guide](docs/pop-task-guide.md)**: How to build valid pipeline tasks using the 11-stage lifecycle.
|
|
13
|
+
- **[LLM Provider Requirements](docs/provider-requirements.md)**: Standards for implementing new model providers.
|
|
14
|
+
- **[Feature Audit](docs/feature-audit.md)**: Comprehensive list of current system capabilities.
|
|
15
|
+
- **[Jobs to be Done (JTBD)](docs/jtbd.md)**: User motivations and desired outcomes for the framework.
|
|
18
16
|
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
- **Chained reasoning** – break down complex problems into sequential tasks.
|
|
22
|
-
- **Context compression & stacking** – condense outputs into artifacts that feed the next stage.
|
|
23
|
-
- **Multi‑model strategies** – route subtasks to the most appropriate model (fast vs. large, cheap vs. accurate).
|
|
24
|
-
- **Validation loops** – enforce structure, apply quality checks, and retry when needed.
|
|
25
|
-
- **Experimentation** – swap tasks in and out to try new ideas without rewriting the whole system.
|
|
17
|
+
---
|
|
26
18
|
|
|
27
|
-
|
|
19
|
+
## What It Does (and Why It Matters)
|
|
20
|
+
|
|
21
|
+
This framework is designed for AI Engineers and Systems Integrators who need to move beyond simple chatbots to build reliable, multi-step workflows.
|
|
22
|
+
|
|
23
|
+
### 1. Orchestrate Reliable, Multi-Stage Workflows
|
|
24
|
+
Running long-duration AI tasks locally can be fragile. A single script crash or API timeout can waste hours of execution and dollars in token costs.
|
|
25
|
+
* **Process Isolation**: Every pipeline runs in its own dedicated child process. If one agent crashes, your orchestrator stays alive.
|
|
26
|
+
* **Resumability**: Pause, stop, and resume jobs from any specific task. Fix a bug in step 5 and restart exactly where you left off.
|
|
27
|
+
* **Atomic State**: Every stage transition is saved to disk instantly. You never lose progress.
|
|
28
|
+
|
|
29
|
+
### 2. Gain Radical Observability
|
|
30
|
+
"Black box" agents are impossible to debug. POP provides deep visibility into the "thought process" of your pipelines.
|
|
31
|
+
* **Real-Time Dashboard**: Watch jobs progress stage-by-stage via a built-in UI (Server-Sent Events).
|
|
32
|
+
* **Granular Logging**: Every input, output, and internal thought is captured in dedicated log files.
|
|
33
|
+
* **Cost Tracking**: See exact token usage and cost breakdown for every task and model call.
|
|
34
|
+
|
|
35
|
+
### 3. Enforce Quality Autonomously
|
|
36
|
+
LLMs are probabilistic and prone to errors. POP enforces a rigid **11-stage lifecycle** for every task to catch mistakes before they propagate.
|
|
37
|
+
* **Standardized Flow**: `Ingestion` → `Inference` → `Validation` → `Critique` → `Refinement`.
|
|
38
|
+
* **Self-Correction**: Configurable loops allow the system to detect invalid outputs, critique itself, and refine the answer automatically.
|
|
39
|
+
* **Structured Output**: Built-in validators ensuring JSON schema compliance.
|
|
40
|
+
|
|
41
|
+
### 4. Avoid Vendor Lock-In
|
|
42
|
+
Switch models globally or per-task without rewriting your logic.
|
|
43
|
+
* **Supported Providers**:
|
|
44
|
+
* **OpenAI** (GPT-4, GPT-4o)
|
|
45
|
+
* **Anthropic** (Claude 3.5 Sonnet, Haiku, Opus)
|
|
46
|
+
* **DeepSeek** (V3, R1)
|
|
47
|
+
* **Google Gemini** (Pro, Flash)
|
|
48
|
+
* **Moonshot** (Kimi)
|
|
49
|
+
* **Zhipu** (GLM-4)
|
|
50
|
+
* **Claude Code** (CLI integration)
|
|
28
51
|
|
|
29
52
|
---
|
|
30
53
|
|
|
31
|
-
## Architecture
|
|
54
|
+
## System Architecture
|
|
32
55
|
|
|
33
|
-
|
|
56
|
+
The system follows a "Watch Folder" architectural pattern, designed for simplicity and ease of integration.
|
|
34
57
|
|
|
35
|
-
### 1
|
|
58
|
+
### Level 1: System Context
|
|
59
|
+
The **Prompt Orchestration Pipeline** sits between your external triggers (users, scripts, cron jobs) and the LLM Providers.
|
|
36
60
|
|
|
37
|
-
|
|
61
|
+
* **Input**: A JSON "seed" file dropped into a watched folder.
|
|
62
|
+
* **Processing**: The system orchestrates the flow of data through defined tasks.
|
|
63
|
+
* **Output**: Completed artifacts and logs written to disk.
|
|
38
64
|
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
- Spawning isolated processes for each task (so one failure doesn't crash others).
|
|
42
|
-
- Tracking progress in a run‑scoped status file.
|
|
43
|
-
- Promoting completed runs into a repository of results with audit metadata.
|
|
65
|
+
### Level 2: Containers
|
|
66
|
+
The system comprises three main runtime containers:
|
|
44
67
|
|
|
45
|
-
**
|
|
68
|
+
1. **Orchestrator (Daemon)**
|
|
69
|
+
* **Role**: The long-running supervisor.
|
|
70
|
+
* **Responsibility**: Watches the `pipeline-data/pending/` directory. When a file appears, it initializes the job and spawns a Runner.
|
|
71
|
+
2. **Pipeline Runner (Process)**
|
|
72
|
+
* **Role**: An ephemeral, isolated worker.
|
|
73
|
+
* **Responsibility**: Loads the specific pipeline configuration (e.g., "Content Gen") and executes the sequence of tasks.
|
|
74
|
+
3. **UI Server (Optional)**
|
|
75
|
+
* **Role**: Observability layer.
|
|
76
|
+
* **Responsibility**: Reads state files and pushes real-time updates to the web dashboard via SSE.
|
|
46
77
|
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
└── pipeline-data/
|
|
50
|
-
├── pending/ # queue seeds here (e.g., *.json)
|
|
51
|
-
├── current/ # active run state (auto‑managed)
|
|
52
|
-
└── complete/ # archived runs (auto‑managed)
|
|
53
|
-
```
|
|
78
|
+
### Level 3: Components
|
|
79
|
+
Inside the **Pipeline Runner**, the logic is structured into:
|
|
54
80
|
|
|
55
|
-
**
|
|
81
|
+
* **Task Runner**: The engine that drives a specific task (e.g., "Research") through the standardized lifecycle.
|
|
82
|
+
* **LLM Layer**: A unified abstraction for all model providers, handling retries, cost calculation, and normalization.
|
|
83
|
+
* **Symlink Bridge**: A specialized component that ensures every task has deterministic access to `node_modules` and shared utilities, regardless of where it is defined on disk.
|
|
84
|
+
* **Status Writer**: An atomic file-writer that updates `tasks-status.json` safely, preventing data corruption.
|
|
56
85
|
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
A["pipeline-data/pending/*-seed.json"] --> B[Orchestrator]
|
|
60
|
-
B --> C["create pipeline-data/current/{jobId}/seed.json"]
|
|
61
|
-
B --> D["init pipeline-data/current/{jobId}/tasks-status.json"]
|
|
62
|
-
B --> E[Read pipeline-config/pipeline.json]
|
|
63
|
-
E --> F[Spawn task runner]
|
|
64
|
-
F --> H[Run task inner pipeline]
|
|
65
|
-
H --> I["write tasks/<task>/output.json"]
|
|
66
|
-
I --> J[Update tasks-status.json]
|
|
67
|
-
J --> K{More tasks?}
|
|
68
|
-
K -->|yes| F
|
|
69
|
-
K -->|no| L[Promote to complete]
|
|
70
|
-
L --> M["pipeline-data/complete/{jobId}/**"]
|
|
71
|
-
L --> N["append pipeline-data/complete/runs.jsonl"]
|
|
72
|
-
```
|
|
73
|
-
|
|
74
|
-
### 2) Task orchestration (inner layer)
|
|
75
|
-
|
|
76
|
-
Each pipeline step runs through a **task runner** that executes canonical sub‑steps:
|
|
77
|
-
|
|
78
|
-
1. **Ingestion** – retrieve existing data or context.
|
|
79
|
-
2. **Pre‑processing** – compress or transform input to fit model constraints.
|
|
80
|
-
3. **Prompt templating** – assemble the instruction.
|
|
81
|
-
4. **Inference** – run the model call(s).
|
|
82
|
-
5. **Parsing** – normalize outputs into structured form.
|
|
83
|
-
6. **Validation** – check schema, quality, and semantic correctness.
|
|
84
|
-
7. **Critique & refinement** – generate hints, re‑prompt, and retry if needed.
|
|
85
|
-
8. **Finalization** – confirm valid output and persist artifacts.
|
|
86
|
+
### Level 4: Code (The Task Lifecycle)
|
|
87
|
+
Every task implementation enforces a strict 11-stage flow to ensure consistency:
|
|
86
88
|
|
|
87
89
|
```mermaid
|
|
88
|
-
flowchart
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
VQ -->|ok| FIN[Finalize & persist]
|
|
98
|
-
VQ -->|fail| HINTS[Critique & hints]
|
|
99
|
-
HINTS --> T1
|
|
100
|
-
FIN --> DONE[Done]
|
|
101
|
-
ERR --> DONE
|
|
102
|
-
```
|
|
103
|
-
|
|
104
|
-
---
|
|
105
|
-
|
|
106
|
-
## Section A — Library (this package)
|
|
107
|
-
|
|
108
|
-
### Repository layout
|
|
109
|
-
|
|
110
|
-
```
|
|
111
|
-
@ryan-fw/prompt-orchestration-pipeline/
|
|
112
|
-
├── src/
|
|
113
|
-
│ ├── core/
|
|
114
|
-
│ │ ├── task-runner.js # Core pipeline execution
|
|
115
|
-
│ │ ├── pipeline-runner.js # Pipeline management
|
|
116
|
-
│ │ └── orchestrator.js # Workflow orchestration
|
|
117
|
-
│ ├── cli/
|
|
118
|
-
│ │ └── index.js # CLI entry point
|
|
119
|
-
│ ├── api/
|
|
120
|
-
│ │ └── index.js # Programmatic API
|
|
121
|
-
│ └── ui/
|
|
122
|
-
│ └── server.js # Optional UI server
|
|
123
|
-
├── bin/
|
|
124
|
-
│ └── pipeline-orchestrator # CLI executable
|
|
125
|
-
├── package.json
|
|
126
|
-
└── README.md
|
|
127
|
-
```
|
|
128
|
-
|
|
129
|
-
### Package exports & CLI
|
|
130
|
-
|
|
131
|
-
```json
|
|
132
|
-
{
|
|
133
|
-
"name": "@ryan-fw/prompt-orchestration-pipeline",
|
|
134
|
-
"version": "1.0.0",
|
|
135
|
-
"type": "module",
|
|
136
|
-
"exports": {
|
|
137
|
-
".": "./src/api/index.js",
|
|
138
|
-
"./cli": "./src/cli/index.js",
|
|
139
|
-
"./runner": "./src/core/task-runner.js"
|
|
140
|
-
},
|
|
141
|
-
"bin": {
|
|
142
|
-
"pipeline-orchestrator": "./bin/pipeline-orchestrator"
|
|
143
|
-
},
|
|
144
|
-
"dependencies": {
|
|
145
|
-
"chokidar": "^3.5.3",
|
|
146
|
-
"commander": "^11.0.0",
|
|
147
|
-
"express": "^4.18.0"
|
|
148
|
-
}
|
|
149
|
-
}
|
|
90
|
+
flowchart LR
|
|
91
|
+
Ingest[1. Ingestion] --> Templ[3. Templating]
|
|
92
|
+
Templ --> Infer[4. Inference]
|
|
93
|
+
Infer --> Parse[5. Parsing]
|
|
94
|
+
Parse --> Val[6. Validate]
|
|
95
|
+
Val -->|Pass| Integ[11. Integration]
|
|
96
|
+
Val -->|Fail| Crit[8. Critique]
|
|
97
|
+
Crit --> Refine[9. Refine]
|
|
98
|
+
Refine --> Templ
|
|
150
99
|
```
|
|
151
100
|
|
|
152
|
-
|
|
153
|
-
- **Programmatic API:** import from `@ryan-fw/prompt-orchestration-pipeline` (see `src/api/index.js`).
|
|
154
|
-
- **Task runner (advanced):** `@ryan-fw/prompt-orchestration-pipeline/runner`.
|
|
101
|
+
*(Note: PreProcessing, ValidateQuality, and FinalValidation stages are also available but optional)*
|
|
155
102
|
|
|
156
103
|
---
|
|
157
104
|
|
|
158
|
-
##
|
|
105
|
+
## Getting Started
|
|
159
106
|
|
|
160
|
-
###
|
|
161
|
-
|
|
162
|
-
```
|
|
163
|
-
|
|
164
|
-
├── pipeline-config/
|
|
165
|
-
│ ├── registry.json # Pipeline registry (maps slugs → configurations)
|
|
166
|
-
│ └── pipelines/ # Pipeline definitions (slugged layout)
|
|
167
|
-
│ ├── content/
|
|
168
|
-
│ │ ├── pipeline.json # Pipeline definition (ordered list of task IDs)
|
|
169
|
-
│ │ └── tasks/ # Task implementations
|
|
170
|
-
│ │ ├── index.js # Task registry (maps task IDs → modules)
|
|
171
|
-
│ │ ├── task-a/
|
|
172
|
-
│ │ │ └── index.js
|
|
173
|
-
│ │ └── task-b/
|
|
174
|
-
│ │ └── index.js
|
|
175
|
-
│ └── analytics/ # Additional pipeline (example)
|
|
176
|
-
│ ├── pipeline.json
|
|
177
|
-
│ └── tasks/
|
|
178
|
-
│ └── index.js
|
|
179
|
-
├── pipeline-data/ # Runtime directories (auto‑created/managed)
|
|
180
|
-
│ ├── pending/
|
|
181
|
-
│ ├── current/
|
|
182
|
-
│ └── complete/
|
|
183
|
-
├── package.json
|
|
184
|
-
└── .pipelinerc.json # Optional CLI config
|
|
185
|
-
```
|
|
186
|
-
|
|
187
|
-
**`pipeline-config/registry.json` (example)**
|
|
188
|
-
|
|
189
|
-
```json
|
|
190
|
-
{
|
|
191
|
-
"pipelines": {
|
|
192
|
-
"content": {
|
|
193
|
-
"name": "Content Generation Pipeline",
|
|
194
|
-
"description": "Generates and processes content using LLM tasks",
|
|
195
|
-
"pipelinePath": "pipeline-config/content/pipeline.json",
|
|
196
|
-
"taskRegistryPath": "pipeline-config/content/tasks/index.js"
|
|
197
|
-
},
|
|
198
|
-
"analytics": {
|
|
199
|
-
"name": "Analytics Pipeline",
|
|
200
|
-
"description": "Processes data for analytics and reporting",
|
|
201
|
-
"pipelinePath": "pipeline-config/analytics/pipeline.json",
|
|
202
|
-
"taskRegistryPath": "pipeline-config/analytics/tasks/index.js"
|
|
203
|
-
}
|
|
204
|
-
}
|
|
205
|
-
}
|
|
206
|
-
```
|
|
207
|
-
|
|
208
|
-
**`pipeline-config/pipelines/content/pipeline.json` (example)**
|
|
209
|
-
|
|
210
|
-
```json
|
|
211
|
-
{
|
|
212
|
-
"tasks": ["task-a", "task-b"]
|
|
213
|
-
}
|
|
107
|
+
### 1. Install
|
|
108
|
+
Add the orchestrator as a dependency in your Node.js project:
|
|
109
|
+
```bash
|
|
110
|
+
npm install @ryan-fw/prompt-orchestration-pipeline
|
|
214
111
|
```
|
|
215
112
|
|
|
216
|
-
|
|
217
|
-
|
|
218
|
-
```
|
|
219
|
-
|
|
220
|
-
export default {
|
|
221
|
-
"task-a": () => import("./task-a/index.js"),
|
|
222
|
-
"task-b": () => import("./task-b/index.js"),
|
|
223
|
-
};
|
|
113
|
+
### 2. Initialize Structure
|
|
114
|
+
Scaffold the required `pipeline-config` and `pipeline-data` directories:
|
|
115
|
+
```bash
|
|
116
|
+
npx pipeline-orchestrator init --root ./pipelines
|
|
224
117
|
```
|
|
225
118
|
|
|
226
|
-
|
|
227
|
-
|
|
228
|
-
### Install & scripts
|
|
229
|
-
|
|
230
|
-
Add the package and scripts to your consumer project:
|
|
231
|
-
|
|
119
|
+
### 3. Configure Scripts
|
|
120
|
+
Add the following to your `package.json` for easy access:
|
|
232
121
|
```json
|
|
233
122
|
{
|
|
234
123
|
"scripts": {
|
|
235
|
-
"pipeline": "pipeline-orchestrator start"
|
|
236
|
-
"pipeline:ui": "pipeline-orchestrator start --ui",
|
|
237
|
-
"pipeline:init": "pipeline-orchestrator init",
|
|
238
|
-
"pipeline:submit": "pipeline-orchestrator submit"
|
|
239
|
-
},
|
|
240
|
-
"dependencies": {
|
|
241
|
-
"@ryan-fw/prompt-orchestration-pipeline": "^1.0.0"
|
|
242
|
-
}
|
|
243
|
-
}
|
|
244
|
-
```
|
|
245
|
-
|
|
246
|
-
### CLI overview
|
|
247
|
-
|
|
248
|
-
- **`pipeline-orchestrator init`** – scaffolds `pipeline-config/` with registry and default pipeline, plus `pipeline-data/` if missing.
|
|
249
|
-
- **`pipeline-orchestrator start`** – starts the orchestrator; watches `pipeline-data/pending/` for new seeds and processes them using the default pipeline from `pipeline-config/registry.json`.
|
|
250
|
-
- **`pipeline-orchestrator start --ui`** – starts the orchestrator and the optional UI server.
|
|
251
|
-
- **`pipeline-orchestrator submit [path]`** – submits a seed into `pipeline-data/pending/` (path can point to a JSON file).
|
|
252
|
-
|
|
253
|
-
> Run `pipeline-orchestrator --help` in your project for the most current flags.
|
|
254
|
-
|
|
255
|
-
### Optional configuration: `.pipelinerc.json`
|
|
256
|
-
|
|
257
|
-
If present in the project root, this file can provide defaults for the CLI (e.g., custom locations). A minimal example:
|
|
258
|
-
|
|
259
|
-
```json
|
|
260
|
-
{
|
|
261
|
-
"configDir": "./pipeline-config",
|
|
262
|
-
"dataDir": "./pipeline-data"
|
|
263
|
-
}
|
|
264
|
-
```
|
|
265
|
-
|
|
266
|
-
_(Keys and defaults may vary by version; prefer `--help` for authoritative options.)_
|
|
267
|
-
|
|
268
|
-
### Seed format
|
|
269
|
-
|
|
270
|
-
All seeds must include a `pipeline` field that references a valid pipeline slug from the registry. The pipeline field is mandatory and no fallbacks are allowed.
|
|
271
|
-
|
|
272
|
-
**Minimal seed example:**
|
|
273
|
-
|
|
274
|
-
```json
|
|
275
|
-
{
|
|
276
|
-
"name": "my-job",
|
|
277
|
-
"pipeline": "content",
|
|
278
|
-
"data": {
|
|
279
|
-
"type": "content-creation",
|
|
280
|
-
"topic": "AI-Powered Development Tools"
|
|
124
|
+
"pipeline": "npx pipeline-orchestrator start --root pipelines --port 3010"
|
|
281
125
|
}
|
|
282
126
|
}
|
|
283
127
|
```
|
|
284
128
|
|
|
285
|
-
|
|
286
|
-
|
|
287
|
-
|
|
288
|
-
- `pipeline`: Valid pipeline slug from `pipeline-config/registry.json`
|
|
289
|
-
- `data`: Object containing the input data for the pipeline
|
|
290
|
-
|
|
291
|
-
### Example flow in a consumer project
|
|
292
|
-
|
|
293
|
-
1. **Initialize**: `npm run pipeline:init` to create the registry and default pipeline structure.
|
|
294
|
-
2. **Define**: Edit `pipeline-config/pipelines/{slug}/pipeline.json` and implement tasks under `pipeline-config/pipelines/{slug}/tasks/`.
|
|
295
|
-
3. **Configure**: Update `pipeline-config/registry.json` to add new pipelines or change the default.
|
|
296
|
-
4. **Run**: `npm run pipeline` (or `npm run pipeline:ui` for the UI).
|
|
297
|
-
5. **Submit**: Add a seed JSON to `pipeline-data/pending/` or run `npm run pipeline:submit -- ./path/to/seed.json`.
|
|
298
|
-
6. **Inspect**: Watch `pipeline-data/current/{jobId}` for in‑progress artifacts and `pipeline-data/complete/{jobId}` for results.
|
|
299
|
-
|
|
300
|
-
---
|
|
301
|
-
|
|
302
|
-
## Section C — UI and JobId-Only Navigation
|
|
303
|
-
|
|
304
|
-
This project includes a web UI for monitoring pipeline execution and inspecting results.
|
|
305
|
-
|
|
306
|
-
### JobId-Only Policy
|
|
307
|
-
|
|
308
|
-
**Important**: The UI uses JobId-only navigation. All pipeline detail pages use `/pipeline/:jobId` URLs with no slug-based fallbacks.
|
|
309
|
-
|
|
310
|
-
#### Directory Structure
|
|
311
|
-
|
|
312
|
-
The UI uses ID-based storage exclusively:
|
|
313
|
-
|
|
314
|
-
```
|
|
315
|
-
pipeline-data/
|
|
316
|
-
├── pending/
|
|
317
|
-
│ ├── {jobId}/
|
|
318
|
-
│ │ ├── seed.json
|
|
319
|
-
│ │ └── ...
|
|
320
|
-
├── current/
|
|
321
|
-
│ ├── {jobId}/
|
|
322
|
-
│ │ ├── seed.json
|
|
323
|
-
│ │ ├── tasks-status.json
|
|
324
|
-
│ │ └── ...
|
|
325
|
-
├── complete/
|
|
326
|
-
│ ├── {jobId}/
|
|
327
|
-
│ │ ├── seed.json
|
|
328
|
-
│ │ ├── tasks-status.json
|
|
329
|
-
│ │ └── ...
|
|
330
|
-
└── rejected/
|
|
331
|
-
├── {jobId}/
|
|
332
|
-
│ ├── seed.json
|
|
333
|
-
│ └── ...
|
|
334
|
-
```
|
|
335
|
-
|
|
336
|
-
#### Accessing Pipeline Details
|
|
337
|
-
|
|
338
|
-
- **Valid**: `/pipeline/abc123def456` - Loads job with ID `abc123def456`
|
|
339
|
-
- **Invalid**: `/pipeline/content-generation` - Shows "Invalid job ID" error
|
|
340
|
-
|
|
341
|
-
#### Error Handling
|
|
342
|
-
|
|
343
|
-
- **Invalid job ID**: Shows "Invalid job ID" for malformed IDs
|
|
344
|
-
- **Job not found**: Shows "Job not found" for valid IDs that don't exist
|
|
345
|
-
- **Network errors**: Shows appropriate network error messages
|
|
346
|
-
|
|
347
|
-
---
|
|
348
|
-
|
|
349
|
-
## Section D — File I/O System (New)
|
|
350
|
-
|
|
351
|
-
### Scoped File Operations
|
|
352
|
-
|
|
353
|
-
The pipeline now includes a **scoped file I/O system** that provides each task with isolated file operations through a `context.files` API. This replaces the legacy artifacts system with a more organized approach.
|
|
354
|
-
|
|
355
|
-
#### File Structure
|
|
356
|
-
|
|
357
|
-
Each task gets its own directory structure:
|
|
358
|
-
|
|
359
|
-
```
|
|
360
|
-
pipeline-data/current/{jobId}/
|
|
361
|
-
├── tasks/
|
|
362
|
-
│ └── {taskName}/
|
|
363
|
-
│ ├── artifacts/ # Generated outputs (replace mode)
|
|
364
|
-
│ ├── logs/ # Process logs (append mode)
|
|
365
|
-
│ └── tmp/ # Temporary files (replace mode
|
|
366
|
-
└── tasks-status.json # Updated with files.* arrays
|
|
367
|
-
```
|
|
368
|
-
|
|
369
|
-
#### File I/O API
|
|
370
|
-
|
|
371
|
-
Tasks receive a `context.files` object with these methods:
|
|
372
|
-
|
|
373
|
-
```javascript
|
|
374
|
-
// Write artifacts (default: replace mode)
|
|
375
|
-
await context.files.writeArtifact("output.json", data);
|
|
376
|
-
await context.files.writeArtifact("report.txt", content, { mode: "replace" });
|
|
377
|
-
|
|
378
|
-
// Write logs (default: append mode)
|
|
379
|
-
await context.files.writeLog("process.log", "Starting process\n");
|
|
380
|
-
await context.files.writeLog("debug.log", error, { mode: "append" });
|
|
381
|
-
|
|
382
|
-
// Write temporary files (default: replace mode)
|
|
383
|
-
await context.files.writeTmp("temp.json", intermediateData);
|
|
384
|
-
|
|
385
|
-
// Read files
|
|
386
|
-
const artifact = await context.files.readArtifact("output.json");
|
|
387
|
-
const logs = await context.files.readLog("process.log");
|
|
388
|
-
const temp = await context.files.readTmp("temp.json");
|
|
129
|
+
### 4. Start the System
|
|
130
|
+
```bash
|
|
131
|
+
npm run pipeline
|
|
389
132
|
```
|
|
133
|
+
This starts the file watcher and the web dashboard at `http://localhost:3010`.
|
|
390
134
|
|
|
391
|
-
|
|
392
|
-
|
|
393
|
-
The `tasks-status.json` now includes `files.*` arrays:
|
|
394
|
-
|
|
135
|
+
### 5. Run a Job
|
|
136
|
+
Drop a JSON file into `pipelines/pipeline-data/pending/`:
|
|
395
137
|
```json
|
|
396
138
|
{
|
|
397
|
-
"
|
|
398
|
-
"
|
|
399
|
-
"
|
|
400
|
-
"artifacts": ["raw-research.json", "analysis-output.json", "summary.txt"],
|
|
401
|
-
"logs": ["ingestion.log", "integration.log"],
|
|
402
|
-
"tmp": ["temp-data.json"]
|
|
403
|
-
},
|
|
404
|
-
"tasks": {
|
|
405
|
-
"analysis": {
|
|
406
|
-
"state": "complete",
|
|
407
|
-
"files": {
|
|
408
|
-
"artifacts": ["raw-research.json", "analysis-output.json"],
|
|
409
|
-
"logs": ["ingestion.log"],
|
|
410
|
-
"tmp": []
|
|
411
|
-
}
|
|
412
|
-
}
|
|
413
|
-
}
|
|
139
|
+
"name": "my-first-run",
|
|
140
|
+
"pipeline": "default",
|
|
141
|
+
"data": { "topic": "AI Architecture" }
|
|
414
142
|
}
|
|
415
143
|
```
|
|
416
144
|
|
|
417
|
-
|
|
418
|
-
|
|
419
|
-
The new system **breaks backward compatibility** intentionally:
|
|
420
|
-
|
|
421
|
-
- **Old**: `task.artifacts` array with file objects
|
|
422
|
-
- **New**: `task.files.artifacts` array with filenames only
|
|
423
|
-
- **Old**: Files stored in task root directory
|
|
424
|
-
- **New**: Files organized in `artifacts/`, `logs/`, `tmp/` subdirectories
|
|
425
|
-
|
|
426
|
-
To migrate existing demo data:
|
|
427
|
-
|
|
428
|
-
```bash
|
|
429
|
-
node scripts/migrate-demo-files.js
|
|
430
|
-
```
|
|
431
|
-
|
|
432
|
-
#### Verification
|
|
433
|
-
|
|
434
|
-
To verify the file I/O system is working:
|
|
435
|
-
|
|
436
|
-
1. **Check test suite**: All 882 tests should pass
|
|
437
|
-
2. **Run demo pipeline**: Files should appear in correct subdirectories
|
|
438
|
-
3. **Inspect tasks-status.json**: Should contain `files.*` arrays
|
|
439
|
-
4. **Check UI**: Job details should show files from new schema
|
|
440
|
-
|
|
441
|
-
#### Example Task Usage
|
|
442
|
-
|
|
443
|
-
```javascript
|
|
444
|
-
export async function ingestion(context) {
|
|
445
|
-
const researchContent = context.seed.data.content;
|
|
446
|
-
|
|
447
|
-
// Log the start of ingestion
|
|
448
|
-
await context.files.writeLog(
|
|
449
|
-
"ingestion.log",
|
|
450
|
-
`[${new Date().toISOString()}] Starting data ingestion\n`
|
|
451
|
-
);
|
|
452
|
-
|
|
453
|
-
// Store raw research data
|
|
454
|
-
await context.files.writeArtifact(
|
|
455
|
-
"raw-research.json",
|
|
456
|
-
JSON.stringify(
|
|
457
|
-
{
|
|
458
|
-
content: researchContent,
|
|
459
|
-
type: context.seed.data.type,
|
|
460
|
-
ingestedAt: new Date().toISOString(),
|
|
461
|
-
},
|
|
462
|
-
null,
|
|
463
|
-
2
|
|
464
|
-
)
|
|
465
|
-
);
|
|
466
|
-
|
|
467
|
-
return { output: { researchContent } };
|
|
468
|
-
}
|
|
469
|
-
|
|
470
|
-
export async function integration(context) {
|
|
471
|
-
const { analysisContent } = context.output;
|
|
472
|
-
|
|
473
|
-
// Store final analysis output
|
|
474
|
-
await context.files.writeArtifact(
|
|
475
|
-
"analysis-output.json",
|
|
476
|
-
JSON.stringify(
|
|
477
|
-
{
|
|
478
|
-
content: analysisContent,
|
|
479
|
-
timestamp: new Date().toISOString(),
|
|
480
|
-
taskName: context.taskName,
|
|
481
|
-
},
|
|
482
|
-
null,
|
|
483
|
-
2
|
|
484
|
-
)
|
|
485
|
-
);
|
|
486
|
-
|
|
487
|
-
// Log completion
|
|
488
|
-
await context.files.writeLog(
|
|
489
|
-
"integration.log",
|
|
490
|
-
`[${new Date().toISOString()}] ✓ Analysis integration completed\n`
|
|
491
|
-
);
|
|
492
|
-
|
|
493
|
-
return { output: { analysis: { content: analysisContent } } };
|
|
494
|
-
}
|
|
495
|
-
```
|
|
496
|
-
|
|
497
|
-
---
|
|
498
|
-
|
|
499
|
-
## Concepts & conventions (carry‑overs)
|
|
500
|
-
|
|
501
|
-
- **Determinism** – each task persists its inputs/outputs; you can re‑run or debug any stage.
|
|
502
|
-
- **Isolation** – tasks run in separate processes when appropriate.
|
|
503
|
-
- **Scoped File I/O** – tasks use `context.files` API for organized file operations.
|
|
504
|
-
- **Status** – a `tasks-status.json` file tracks progress and file inventories across the pipeline.
|
|
505
|
-
- **JobId-only** – all job identification and navigation uses unique job IDs, not pipeline names.
|
|
506
|
-
|
|
507
|
-
---
|
|
508
|
-
|
|
509
|
-
## Section E — Logging and Debugging
|
|
510
|
-
|
|
511
|
-
### Per-Stage Logging
|
|
512
|
-
|
|
513
|
-
The pipeline captures console output from each stage execution to dedicated log files. This helps with debugging specific stages and understanding the flow of data through the pipeline.
|
|
514
|
-
|
|
515
|
-
#### Log File Locations
|
|
516
|
-
|
|
517
|
-
```
|
|
518
|
-
pipeline-data/current/{jobId}/
|
|
519
|
-
├── files/
|
|
520
|
-
│ └── logs/
|
|
521
|
-
│ ├── stage-validateStructure.log
|
|
522
|
-
│ ├── stage-critique.log
|
|
523
|
-
│ └── stage-refine.log
|
|
524
|
-
└── tasks-status.json
|
|
525
|
-
```
|
|
526
|
-
|
|
527
|
-
#### Log Contents
|
|
528
|
-
|
|
529
|
-
Each `stage-{stageName}.log` file contains:
|
|
530
|
-
|
|
531
|
-
- All console output from that stage (console.log, console.error, console.warn, console.info)
|
|
532
|
-
- Timestamped entries for debugging
|
|
533
|
-
- Error messages and stack traces if the stage fails
|
|
534
|
-
|
|
535
|
-
#### Status File
|
|
536
|
-
|
|
537
|
-
The `tasks-status.json` file contains the complete execution state:
|
|
538
|
-
|
|
539
|
-
- `data` object with all stage outputs (`data.validateStructure`, `data.critique`, etc.)
|
|
540
|
-
- `flags` object with accumulated pipeline flags (`validationFailed`, `critiqueComplete`, etc.)
|
|
541
|
-
- `logs` array with audit trail entries
|
|
542
|
-
- `files` arrays tracking all generated files
|
|
543
|
-
|
|
544
|
-
#### Debugging Examples
|
|
545
|
-
|
|
546
|
-
**Check stage output:**
|
|
547
|
-
|
|
548
|
-
```bash
|
|
549
|
-
# View validation stage logs
|
|
550
|
-
cat pipeline-data/current/{jobId}/files/logs/stage-validateStructure.log
|
|
551
|
-
|
|
552
|
-
# View critique stage logs
|
|
553
|
-
cat pipeline-data/current/{jobId}/files/logs/stage-critique.log
|
|
554
|
-
```
|
|
555
|
-
|
|
556
|
-
**Inspect execution state:**
|
|
557
|
-
|
|
558
|
-
```bash
|
|
559
|
-
# View complete pipeline state
|
|
560
|
-
cat pipeline-data/current/{jobId}/tasks-status.json | jq '.data, .flags'
|
|
561
|
-
```
|
|
562
|
-
|
|
563
|
-
**Debug failed stages:**
|
|
564
|
-
|
|
565
|
-
```bash
|
|
566
|
-
# Check error logs for specific stage
|
|
567
|
-
grep -i error pipeline-data/current/{jobId}/files/logs/stage-*.log
|
|
568
|
-
```
|
|
569
|
-
|
|
570
|
-
---
|
|
571
|
-
|
|
572
|
-
## Quick troubleshooting
|
|
573
|
-
|
|
574
|
-
- **Nothing happens when I submit a seed** → Ensure the orchestrator is running and watching `pipeline-data/pending/`.
|
|
575
|
-
- **Task not found** → Confirm the task ID exists in `pipeline-config/tasks/index.js` and matches `pipeline.json`.
|
|
576
|
-
- **UI doesn't load** → Try `pipeline-orchestrator start --ui` and check for port conflicts.
|
|
577
|
-
- **Invalid job ID error** → Ensure you're using a valid job ID from the job list, not a pipeline name.
|
|
578
|
-
- **Stage failed** → Check `pipeline-data/current/{jobId}/files/logs/stage-{stageName}.log` for detailed error messages.
|
|
579
|
-
- **Missing output** → Inspect `tasks-status.json` to see what data and flags were generated by each stage.
|
|
580
|
-
|
|
581
|
-
---
|
|
582
|
-
|
|
583
|
-
## Scaffolding
|
|
584
|
-
|
|
585
|
-
Use the CLI commands to quickly scaffold a new pipeline structure. These examples show the minimal commands and resulting directory trees.
|
|
586
|
-
|
|
587
|
-
### Initialize pipeline structure
|
|
588
|
-
|
|
589
|
-
```bash
|
|
590
|
-
pipeline-orchestrator init --root ./pipelines
|
|
591
|
-
```
|
|
592
|
-
|
|
593
|
-
**Resulting directory tree:**
|
|
594
|
-
|
|
595
|
-
```
|
|
596
|
-
pipelines/
|
|
597
|
-
├── pipeline-config/
|
|
598
|
-
│ └── registry.json
|
|
599
|
-
└── pipeline-data/
|
|
600
|
-
├── pending/.gitkeep
|
|
601
|
-
├── current/.gitkeep
|
|
602
|
-
├── complete/.gitkeep
|
|
603
|
-
└── rejected/.gitkeep
|
|
604
|
-
```
|
|
605
|
-
|
|
606
|
-
### Add a pipeline
|
|
607
|
-
|
|
608
|
-
```bash
|
|
609
|
-
pipeline-orchestrator add-pipeline content-generation --root ./pipelines
|
|
610
|
-
```
|
|
611
|
-
|
|
612
|
-
**Resulting directory tree:**
|
|
613
|
-
|
|
614
|
-
```
|
|
615
|
-
pipelines/
|
|
616
|
-
├── pipeline-config/
|
|
617
|
-
│ ├── registry.json
|
|
618
|
-
│ └── content-generation/
|
|
619
|
-
│ ├── pipeline.json
|
|
620
|
-
│ └── tasks/
|
|
621
|
-
│ └── index.js
|
|
622
|
-
└── pipeline-data/
|
|
623
|
-
├── pending/.gitkeep
|
|
624
|
-
├── current/.gitkeep
|
|
625
|
-
├── complete/.gitkeep
|
|
626
|
-
└── rejected/.gitkeep
|
|
627
|
-
```
|
|
628
|
-
|
|
629
|
-
### Add a pipeline task
|
|
630
|
-
|
|
631
|
-
```bash
|
|
632
|
-
pipeline-orchestrator add-pipeline-task content-generation research --root ./pipelines
|
|
633
|
-
```
|
|
634
|
-
|
|
635
|
-
**Resulting directory tree:**
|
|
636
|
-
|
|
637
|
-
```
|
|
638
|
-
pipelines/
|
|
639
|
-
├── pipeline-config/
|
|
640
|
-
│ ├── registry.json
|
|
641
|
-
│ └── content-generation/
|
|
642
|
-
│ ├── pipeline.json
|
|
643
|
-
│ └── tasks/
|
|
644
|
-
│ ├── index.js
|
|
645
|
-
│ └── research.js
|
|
646
|
-
└── pipeline-data/
|
|
647
|
-
├── pending/.gitkeep
|
|
648
|
-
├── current/.gitkeep
|
|
649
|
-
├── complete/.gitkeep
|
|
650
|
-
└── rejected/.gitkeep
|
|
651
|
-
```
|
|
652
|
-
|
|
653
|
-
---
|
|
654
|
-
|
|
655
|
-
## Getting started (TL;DR)
|
|
656
|
-
|
|
657
|
-
```bash
|
|
658
|
-
# 1) Install
|
|
659
|
-
npm i -S @ryan-fw/prompt-orchestration-pipeline
|
|
660
|
-
|
|
661
|
-
# 2) Initialize scaffold
|
|
662
|
-
npm run pipeline:init
|
|
663
|
-
|
|
664
|
-
# 3) Start orchestrator (optionally with UI)
|
|
665
|
-
npm run pipeline
|
|
666
|
-
# or
|
|
667
|
-
npm run pipeline:ui
|
|
668
|
-
|
|
669
|
-
# 4) Submit a seed (JSON file)
|
|
670
|
-
npm run pipeline:submit -- ./seeds/example-seed.json
|
|
671
|
-
|
|
672
|
-
# 5) Access UI (if running with --ui)
|
|
673
|
-
# Navigate to job details using /pipeline/{jobId} URLs
|
|
674
|
-
```
|
|
675
|
-
|
|
676
|
-
---
|
|
677
|
-
|
|
678
|
-
## Status
|
|
679
|
-
|
|
680
|
-
This is an **experimental framework**. The goal is to explore and evolve best practices for orchestrating prompts, models, and validations into reliable workflows. Feedback, issues, and contributions are welcome.
|
|
145
|
+
The Orchestrator will pick it up, move it to `current/`, and start processing.
|