@ryanfw/prompt-orchestration-pipeline 1.3.2 → 1.3.4

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.
Files changed (206) hide show
  1. package/docs/http-api.md +80 -4
  2. package/package.json +1 -4
  3. package/src/api/__tests__/index.test.ts +443 -32
  4. package/src/api/index.ts +108 -127
  5. package/src/cli/__tests__/analyze-task.test.ts +40 -7
  6. package/src/cli/__tests__/index.test.ts +337 -17
  7. package/src/cli/__tests__/types.test.ts +0 -18
  8. package/src/cli/__tests__/update-pipeline-json.test.ts +19 -9
  9. package/src/cli/analyze-task.ts +3 -14
  10. package/src/cli/index.ts +73 -61
  11. package/src/cli/types.ts +0 -13
  12. package/src/cli/update-pipeline-json.ts +3 -14
  13. package/src/config/__tests__/paths.test.ts +46 -1
  14. package/src/config/__tests__/pipeline-registry.test.ts +767 -0
  15. package/src/config/__tests__/sse-events.test.ts +470 -0
  16. package/src/config/__tests__/statuses.test.ts +41 -0
  17. package/src/config/paths.ts +11 -2
  18. package/src/config/pipeline-registry.ts +258 -0
  19. package/src/config/sse-events.ts +122 -0
  20. package/src/config/statuses.ts +20 -1
  21. package/src/core/__tests__/agent-step.test.ts +115 -0
  22. package/src/core/__tests__/config.test.ts +545 -105
  23. package/src/core/__tests__/core-boot-resolution.test.ts +181 -0
  24. package/src/core/__tests__/job-concurrency.test.ts +260 -0
  25. package/src/core/__tests__/job-submission.test.ts +396 -0
  26. package/src/core/__tests__/job-view.test.ts +1341 -0
  27. package/src/core/__tests__/json-file.test.ts +111 -0
  28. package/src/core/__tests__/lifecycle-policy.test.ts +81 -7
  29. package/src/core/__tests__/logger.test.ts +22 -0
  30. package/src/core/__tests__/orchestrator-no-deprecated-exports.test.ts +41 -0
  31. package/src/core/__tests__/orchestrator.test.ts +615 -2
  32. package/src/core/__tests__/pipeline-runner.test.ts +946 -9
  33. package/src/core/__tests__/redact.test.ts +153 -0
  34. package/src/core/__tests__/runner-liveness.test.ts +910 -0
  35. package/src/core/__tests__/seed-naming.test.ts +57 -0
  36. package/src/core/__tests__/single-derivation.test.ts +159 -0
  37. package/src/core/__tests__/task-runner.test.ts +594 -3
  38. package/src/core/__tests__/task-telemetry.test.ts +241 -0
  39. package/src/core/__tests__/workspace-root-resolution-guard.test.ts +62 -0
  40. package/src/core/agent-step.ts +4 -1
  41. package/src/core/agent-types.ts +5 -4
  42. package/src/core/config.ts +134 -222
  43. package/src/core/control.ts +3 -0
  44. package/src/core/job-concurrency.ts +56 -20
  45. package/src/core/job-submission.ts +133 -0
  46. package/src/core/job-view.ts +473 -0
  47. package/src/core/json-file.ts +45 -0
  48. package/src/core/lifecycle-policy.ts +23 -8
  49. package/src/core/logger.ts +0 -29
  50. package/src/core/orchestrator.ts +200 -74
  51. package/src/core/pipeline-runner.ts +85 -53
  52. package/src/core/redact.ts +40 -0
  53. package/src/core/runner-liveness.ts +280 -0
  54. package/src/core/seed-naming.ts +9 -0
  55. package/src/core/status-writer.ts +27 -33
  56. package/src/core/task-runner.ts +356 -319
  57. package/src/core/task-telemetry.ts +107 -0
  58. package/src/harness/__tests__/subprocess.test.ts +112 -1
  59. package/src/harness/subprocess.ts +55 -16
  60. package/src/llm/__tests__/index.test.ts +684 -33
  61. package/src/llm/index.ts +310 -67
  62. package/src/providers/__tests__/alibaba.test.ts +67 -6
  63. package/src/providers/__tests__/anthropic.test.ts +35 -14
  64. package/src/providers/__tests__/base.test.ts +62 -0
  65. package/src/providers/__tests__/claude-code.test.ts +99 -14
  66. package/src/providers/__tests__/deepseek.test.ts +16 -6
  67. package/src/providers/__tests__/gemini.test.ts +47 -25
  68. package/src/providers/__tests__/moonshot.test.ts +27 -0
  69. package/src/providers/__tests__/openai.test.ts +262 -74
  70. package/src/providers/__tests__/opencode.test.ts +77 -0
  71. package/src/providers/__tests__/request-timeout-contract.test.ts +226 -0
  72. package/src/providers/__tests__/stream-accumulator.test.ts +52 -0
  73. package/src/providers/__tests__/types.test.ts +85 -0
  74. package/src/providers/__tests__/zero-fill-guard.test.ts +62 -0
  75. package/src/providers/__tests__/zhipu.test.ts +27 -14
  76. package/src/providers/alibaba.ts +20 -39
  77. package/src/providers/anthropic.ts +23 -11
  78. package/src/providers/base.ts +19 -0
  79. package/src/providers/claude-code.ts +27 -18
  80. package/src/providers/deepseek.ts +9 -28
  81. package/src/providers/gemini.ts +20 -58
  82. package/src/providers/moonshot.ts +15 -11
  83. package/src/providers/openai.ts +79 -61
  84. package/src/providers/opencode.ts +16 -33
  85. package/src/providers/stream-accumulator.ts +27 -21
  86. package/src/providers/types.ts +29 -4
  87. package/src/providers/zhipu.ts +15 -44
  88. package/src/task-analysis/__tests__/analyzer.test.ts +0 -0
  89. package/src/task-analysis/__tests__/enrichers-schema-deducer.test.ts +34 -2
  90. package/src/task-analysis/__tests__/no-ast-imports.test.ts +52 -0
  91. package/src/task-analysis/__tests__/repository.test.ts +65 -0
  92. package/src/task-analysis/__tests__/types.test.ts +63 -130
  93. package/src/task-analysis/analyzer.ts +91 -0
  94. package/src/task-analysis/enrichers/schema-deducer.ts +13 -2
  95. package/src/task-analysis/index.ts +2 -36
  96. package/src/task-analysis/repository.ts +45 -0
  97. package/src/task-analysis/types.ts +42 -58
  98. package/src/ui/client/__tests__/api.test.ts +143 -1
  99. package/src/ui/client/__tests__/bootstrap.test.ts +178 -62
  100. package/src/ui/client/__tests__/job-adapter.test.ts +203 -2
  101. package/src/ui/client/__tests__/load-state.test.ts +70 -0
  102. package/src/ui/client/__tests__/types.test.ts +66 -3
  103. package/src/ui/client/__tests__/useJobDetailWithUpdates.test.ts +390 -77
  104. package/src/ui/client/__tests__/useJobList.test.ts +198 -23
  105. package/src/ui/client/__tests__/useJobListWithUpdates.test.ts +218 -7
  106. package/src/ui/client/adapters/__tests__/job-adapter.test.ts +186 -0
  107. package/src/ui/client/adapters/job-adapter.ts +41 -16
  108. package/src/ui/client/api.ts +38 -15
  109. package/src/ui/client/bootstrap.ts +19 -14
  110. package/src/ui/client/hooks/useJobDetailWithUpdates.ts +73 -97
  111. package/src/ui/client/hooks/useJobList.ts +26 -31
  112. package/src/ui/client/hooks/useJobListWithUpdates.ts +42 -76
  113. package/src/ui/client/load-state.ts +20 -0
  114. package/src/ui/client/reducers/__tests__/job-events.test.ts +568 -0
  115. package/src/ui/client/reducers/job-events.ts +137 -0
  116. package/src/ui/client/types.ts +16 -20
  117. package/src/ui/components/DAGGrid.tsx +6 -1
  118. package/src/ui/components/JobDetail.tsx +12 -4
  119. package/src/ui/components/JobTable.tsx +41 -13
  120. package/src/ui/components/StageTimeline.tsx +8 -20
  121. package/src/ui/components/TaskAnalysisDisplay.tsx +48 -6
  122. package/src/ui/components/__tests__/DAGGrid.test.tsx +36 -0
  123. package/src/ui/components/__tests__/JobDetail.test.tsx +112 -0
  124. package/src/ui/components/__tests__/JobTable.test.tsx +137 -1
  125. package/src/ui/components/__tests__/StageTimeline.test.tsx +5 -6
  126. package/src/ui/components/__tests__/TaskAnalysisDisplay.test.tsx +64 -0
  127. package/src/ui/components/types.ts +35 -15
  128. package/src/ui/dist/assets/{index--RH3sAt3.js → index-DN3-zvtP.js} +4324 -263
  129. package/src/ui/dist/assets/index-DN3-zvtP.js.map +1 -0
  130. package/src/ui/dist/assets/style-CtZBnjlR.css +2 -0
  131. package/src/ui/dist/index.html +2 -2
  132. package/src/ui/pages/PipelineDetail.tsx +60 -4
  133. package/src/ui/pages/PromptPipelineDashboard.tsx +59 -7
  134. package/src/ui/pages/__tests__/PromptPipelineDashboard.test.tsx +114 -32
  135. package/src/ui/pages/__tests__/pages.test.tsx +236 -42
  136. package/src/ui/server/__tests__/concurrency-endpoint.test.ts +54 -0
  137. package/src/ui/server/__tests__/config-bridge-node.test.ts +34 -1
  138. package/src/ui/server/__tests__/config-bridge.test.ts +9 -1
  139. package/src/ui/server/__tests__/embedded-assets.test.ts +66 -0
  140. package/src/ui/server/__tests__/file-endpoints.test.ts +183 -5
  141. package/src/ui/server/__tests__/gate-endpoints.test.ts +55 -0
  142. package/src/ui/server/__tests__/index.test.ts +63 -0
  143. package/src/ui/server/__tests__/job-control-endpoints.test.ts +512 -2
  144. package/src/ui/server/__tests__/job-endpoints.test.ts +158 -2
  145. package/src/ui/server/__tests__/read-static-path-guard.test.ts +94 -0
  146. package/src/ui/server/__tests__/router-root-isolation.test.ts +204 -0
  147. package/src/ui/server/__tests__/router-threading.test.ts +148 -0
  148. package/src/ui/server/__tests__/router.test.ts +104 -0
  149. package/src/ui/server/__tests__/sse-broadcast.test.ts +44 -0
  150. package/src/ui/server/__tests__/sse-enhancer.test.ts +70 -0
  151. package/src/ui/server/config-bridge-node.ts +8 -26
  152. package/src/ui/server/config-bridge.ts +3 -4
  153. package/src/ui/server/embedded-assets-imports.d.ts +44 -0
  154. package/src/ui/server/embedded-assets.ts +13 -2
  155. package/src/ui/server/endpoints/__tests__/meta-endpoint.test.ts +1 -0
  156. package/src/ui/server/endpoints/__tests__/pipeline-analysis-endpoint.test.ts +167 -0
  157. package/src/ui/server/endpoints/__tests__/schema-file-endpoint.test.ts +104 -0
  158. package/src/ui/server/endpoints/__tests__/task-analysis-endpoint.test.ts +103 -0
  159. package/src/ui/server/endpoints/__tests__/upload-endpoints.test.ts +162 -96
  160. package/src/ui/server/endpoints/concurrency-endpoint.ts +2 -1
  161. package/src/ui/server/endpoints/create-pipeline-endpoint.ts +14 -29
  162. package/src/ui/server/endpoints/file-endpoints.ts +15 -10
  163. package/src/ui/server/endpoints/gate-endpoints.ts +2 -6
  164. package/src/ui/server/endpoints/job-control-endpoints.ts +129 -141
  165. package/src/ui/server/endpoints/job-endpoints.ts +7 -0
  166. package/src/ui/server/endpoints/meta-endpoint.ts +1 -1
  167. package/src/ui/server/endpoints/pipeline-analysis-endpoint.ts +99 -11
  168. package/src/ui/server/endpoints/schema-file-endpoint.ts +11 -3
  169. package/src/ui/server/endpoints/task-analysis-endpoint.ts +21 -5
  170. package/src/ui/server/endpoints/task-save-endpoint.ts +1 -2
  171. package/src/ui/server/endpoints/upload-endpoints.ts +5 -40
  172. package/src/ui/server/index.ts +19 -14
  173. package/src/ui/server/job-reader.ts +14 -2
  174. package/src/ui/server/router.ts +33 -10
  175. package/src/ui/server/sse-broadcast.ts +14 -3
  176. package/src/ui/server/sse-enhancer.ts +12 -2
  177. package/src/ui/state/__tests__/schema-loader.test.ts +11 -1
  178. package/src/ui/state/__tests__/snapshot.test.ts +120 -14
  179. package/src/ui/state/__tests__/types.test.ts +104 -5
  180. package/src/ui/state/snapshot.ts +2 -2
  181. package/src/ui/state/transformers/__tests__/list-transformer.test.ts +85 -2
  182. package/src/ui/state/transformers/__tests__/status-transformer.test.ts +250 -22
  183. package/src/ui/state/transformers/list-transformer.ts +13 -3
  184. package/src/ui/state/transformers/status-transformer.ts +36 -170
  185. package/src/ui/state/types.ts +15 -48
  186. package/src/utils/__tests__/path-containment.test.ts +160 -0
  187. package/src/{ui/server/utils → utils}/path-containment.ts +21 -0
  188. package/src/task-analysis/__tests__/enrichers-analysis-writer.test.ts +0 -86
  189. package/src/task-analysis/__tests__/enrichers-artifact-resolver.test.ts +0 -124
  190. package/src/task-analysis/__tests__/extractors-artifacts.test.ts +0 -133
  191. package/src/task-analysis/__tests__/extractors-llm-calls.test.ts +0 -46
  192. package/src/task-analysis/__tests__/extractors-stages.test.ts +0 -52
  193. package/src/task-analysis/__tests__/index.test.ts +0 -143
  194. package/src/task-analysis/__tests__/parser.test.ts +0 -41
  195. package/src/task-analysis/__tests__/utils-ast.test.ts +0 -82
  196. package/src/task-analysis/enrichers/analysis-writer.ts +0 -75
  197. package/src/task-analysis/enrichers/artifact-resolver.ts +0 -89
  198. package/src/task-analysis/extractors/artifacts.ts +0 -143
  199. package/src/task-analysis/extractors/llm-calls.ts +0 -117
  200. package/src/task-analysis/extractors/stages.ts +0 -45
  201. package/src/task-analysis/parser.ts +0 -20
  202. package/src/task-analysis/utils/ast.ts +0 -45
  203. package/src/ui/dist/assets/index--RH3sAt3.js.map +0 -1
  204. package/src/ui/dist/assets/style-CSSKuMOe.css +0 -2
  205. package/src/ui/embedded-assets.js +0 -12
  206. package/src/ui/server/__tests__/path-containment.test.ts +0 -54
@@ -11,20 +11,19 @@ afterEach(() => {
11
11
  document.body.innerHTML = "";
12
12
  });
13
13
 
14
- test("StageTimeline sorts by order and puts unordered stages last", () => {
14
+ test("StageTimeline renders each stage name and purpose in order", () => {
15
15
  const view = render(
16
16
  <StageTimeline
17
17
  stages={[
18
- { name: "B", order: 2 },
19
- { name: "A", order: 1, isAsync: true },
20
- { name: "C" },
18
+ { name: "ingestion", purpose: "Load raw input" },
19
+ { name: "inference", purpose: "Run the model" },
21
20
  ]}
22
21
  />,
23
22
  );
24
23
 
25
24
  const items = Array.from(view.container.querySelectorAll("li")).map((node) => node.textContent?.trim());
26
- expect(items).toEqual(["Aasync", "B", "C"]);
27
- expect(view.getByText("async")).toBeTruthy();
25
+ expect(items).toEqual(["ingestionLoad raw input", "inferenceRun the model"]);
26
+ expect(view.getByText("Load raw input")).toBeTruthy();
28
27
  });
29
28
 
30
29
  test("PageSubheader renders breadcrumbs", () => {
@@ -0,0 +1,64 @@
1
+ import "./test-dom";
2
+
3
+ import { render } from "@testing-library/react";
4
+ import { afterEach, expect, test } from "bun:test";
5
+
6
+ import { TaskAnalysisDisplay } from "../TaskAnalysisDisplay";
7
+ import type { TaskAnalysis } from "../types";
8
+
9
+ afterEach(() => {
10
+ document.body.innerHTML = "";
11
+ });
12
+
13
+ function makeAnalysis(overrides: Partial<TaskAnalysis> = {}): TaskAnalysis {
14
+ return {
15
+ summary: "Summarizes the input document.",
16
+ stages: [{ name: "ingestion", purpose: "Load raw input" }],
17
+ artifacts: {
18
+ reads: [{ fileName: "input.json", role: "source data" }],
19
+ writes: [{ fileName: "output.json", role: "result data" }],
20
+ },
21
+ models: [{ provider: "deepseek", method: "chat", stage: "ingestion" }],
22
+ analyzedAt: "2026-06-22T00:00:00.000Z",
23
+ analysisStatus: "ok",
24
+ ...overrides,
25
+ };
26
+ }
27
+
28
+ test("ok renders summary, stage purpose, artifacts, models, and the AI-generated label", () => {
29
+ const view = render(
30
+ <TaskAnalysisDisplay analysis={makeAnalysis()} loading={false} error={null} pipelineSlug="demo" />,
31
+ );
32
+
33
+ expect(view.getByText("Summarizes the input document.")).toBeTruthy();
34
+ expect(view.getByText("Load raw input")).toBeTruthy();
35
+ expect(view.getByText("input.json")).toBeTruthy();
36
+ expect(view.getByText("source data")).toBeTruthy();
37
+ expect(view.getByText("output.json")).toBeTruthy();
38
+ expect(view.getByText("result data")).toBeTruthy();
39
+ expect(view.getByText("deepseek · chat · ingestion")).toBeTruthy();
40
+ expect(view.container.textContent).toContain("AI-generated, approximate");
41
+ });
42
+
43
+ test("unconfigured renders the configure message and CTA", () => {
44
+ const analysis = makeAnalysis({ analysisStatus: "unconfigured" });
45
+ const view = render(
46
+ <TaskAnalysisDisplay analysis={analysis} loading={false} error={null} pipelineSlug="demo" />,
47
+ );
48
+
49
+ expect(view.container.textContent).toContain("No analysis model is configured");
50
+ expect(view.getByRole("button", { name: "Configure model" })).toBeTruthy();
51
+ });
52
+
53
+ test("error renders an error note with the analysis error detail", () => {
54
+ const analysis = makeAnalysis({
55
+ analysisStatus: "error",
56
+ analysisError: "validation failed for field summary",
57
+ });
58
+ const view = render(
59
+ <TaskAnalysisDisplay analysis={analysis} loading={false} error={null} pipelineSlug="demo" />,
60
+ );
61
+
62
+ expect(view.getByText("Analysis failed")).toBeTruthy();
63
+ expect(view.getByText("validation failed for field summary")).toBeTruthy();
64
+ });
@@ -15,6 +15,22 @@ export interface CostsSummary {
15
15
  totalCost: number;
16
16
  totalInputCost: number;
17
17
  totalOutputCost: number;
18
+ estimatedCost: number;
19
+ hasEstimated: boolean;
20
+ unavailableCost: number;
21
+ }
22
+
23
+ export type UsageSource = "reported" | "estimated" | "unavailable" | "zero";
24
+
25
+ export interface TaskCostBreakdown {
26
+ inputTokens: number;
27
+ outputTokens: number;
28
+ inputCost: number;
29
+ outputCost: number;
30
+ totalCost: number;
31
+ source?: UsageSource;
32
+ failed?: boolean;
33
+ costEstimated?: boolean;
18
34
  }
19
35
 
20
36
  export interface TaskError {
@@ -73,6 +89,8 @@ export interface JobSummary {
73
89
  totalTokens?: number;
74
90
  displayCategory: DisplayCategory;
75
91
  gate?: GateInfo | null;
92
+ readable?: boolean;
93
+ error?: { code: string; message: string; path?: string };
76
94
  }
77
95
 
78
96
  export interface GateInfo {
@@ -80,6 +98,7 @@ export interface GateInfo {
80
98
  message: string;
81
99
  artifacts?: string[];
82
100
  requestedAt: string;
101
+ kind?: "approval" | "control_invalid";
83
102
  }
84
103
 
85
104
  export function normalizeTaskCollection(
@@ -98,10 +117,7 @@ export interface JobDetail {
98
117
  status: string;
99
118
  tasks: TaskCollection;
100
119
  pipeline: { tasks: string[] };
101
- costs?: {
102
- summary: CostsSummary;
103
- taskBreakdown: Record<string, unknown>;
104
- };
120
+ costs?: Record<string, TaskCostBreakdown>;
105
121
  totalCost?: number;
106
122
  totalTokens?: number;
107
123
  current: string | { taskName: string; stage?: string } | null;
@@ -119,6 +135,7 @@ export interface DagItem {
119
135
  startedAt: string | number;
120
136
  endedAt: string | number | null;
121
137
  restartCount?: number;
138
+ costEstimated?: boolean;
122
139
  }
123
140
 
124
141
  export interface PipelineTask {
@@ -133,16 +150,16 @@ export interface PipelineType {
133
150
  tasks: PipelineTask[];
134
151
  }
135
152
 
136
- export interface Artifact {
137
- fileName: string;
138
- stage: string;
139
- required?: boolean;
140
- }
153
+ export type AnalysisStatusKind = "ok" | "unconfigured" | "error";
141
154
 
142
- export interface Stage {
155
+ export interface AnalysisStage {
143
156
  name: string;
144
- order?: number;
145
- isAsync?: boolean;
157
+ purpose: string;
158
+ }
159
+
160
+ export interface AnalysisArtifact {
161
+ fileName: string;
162
+ role: string;
146
163
  }
147
164
 
148
165
  export interface AnalysisModel {
@@ -152,13 +169,16 @@ export interface AnalysisModel {
152
169
  }
153
170
 
154
171
  export interface TaskAnalysis {
172
+ summary: string;
173
+ stages: AnalysisStage[];
155
174
  artifacts: {
156
- reads: Artifact[];
157
- writes: Artifact[];
175
+ reads: AnalysisArtifact[];
176
+ writes: AnalysisArtifact[];
158
177
  };
159
- stages: Stage[];
160
178
  models: AnalysisModel[];
161
179
  analyzedAt: string;
180
+ analysisStatus: AnalysisStatusKind;
181
+ analysisError?: string;
162
182
  }
163
183
 
164
184
  export interface TaskProposal {