@ryanfw/prompt-orchestration-pipeline 0.14.0 → 0.14.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/package.json +1 -1
- package/src/components/ui/RestartJobModal.jsx +24 -14
- package/src/core/pipeline-runner.js +30 -24
- package/src/llm/index.js +13 -2
- package/src/providers/anthropic.js +4 -1
- package/src/providers/base.js +27 -2
- package/src/providers/deepseek.js +8 -3
- package/src/providers/gemini.js +5 -2
- package/src/providers/openai.js +13 -5
- package/src/providers/zhipu.js +4 -1
- package/src/ui/dist/assets/{index-cjHV9mYW.js → index-B5HMRkR9.js} +22 -11
- package/src/ui/dist/assets/{index-cjHV9mYW.js.map → index-B5HMRkR9.js.map} +1 -1
- package/src/ui/dist/index.html +1 -1
- package/src/ui/endpoints/job-control-endpoints.js +72 -37
package/src/ui/dist/index.html
CHANGED
|
@@ -11,7 +11,7 @@
|
|
|
11
11
|
/>
|
|
12
12
|
<title>Prompt Pipeline Dashboard</title>
|
|
13
13
|
<link rel="icon" type="image/svg+xml" href="/favicon.svg" />
|
|
14
|
-
<script type="module" crossorigin src="/assets/index-
|
|
14
|
+
<script type="module" crossorigin src="/assets/index-B5HMRkR9.js"></script>
|
|
15
15
|
<link rel="stylesheet" crossorigin href="/assets/style-CoM9SoQF.css">
|
|
16
16
|
</head>
|
|
17
17
|
<body>
|
|
@@ -18,7 +18,6 @@ import {
|
|
|
18
18
|
getJobMetadataPath,
|
|
19
19
|
getJobPipelinePath,
|
|
20
20
|
} from "../../config/paths.js";
|
|
21
|
-
import { readRawBody } from "../utils/http-utils.js";
|
|
22
21
|
|
|
23
22
|
// Get __dirname equivalent in ES modules
|
|
24
23
|
const __filename = fileURLToPath(import.meta.url);
|
|
@@ -436,21 +435,8 @@ export async function handleJobRestart(req, res, jobId, dataDir, sendJson) {
|
|
|
436
435
|
}
|
|
437
436
|
|
|
438
437
|
// Parse optional fromTask from request body for targeted restart
|
|
439
|
-
|
|
440
|
-
|
|
441
|
-
const rawBody = await readRawBody(req);
|
|
442
|
-
if (rawBody && rawBody.length > 0) {
|
|
443
|
-
const bodyString = rawBody.toString("utf8");
|
|
444
|
-
body = JSON.parse(bodyString);
|
|
445
|
-
}
|
|
446
|
-
} catch (error) {
|
|
447
|
-
sendJson(res, 400, {
|
|
448
|
-
ok: false,
|
|
449
|
-
error: "bad_request",
|
|
450
|
-
message: "Invalid JSON in request body",
|
|
451
|
-
});
|
|
452
|
-
return;
|
|
453
|
-
}
|
|
438
|
+
// Note: Express's json() middleware already parsed the body into req.body
|
|
439
|
+
const body = req.body || {};
|
|
454
440
|
|
|
455
441
|
const { fromTask, singleTask } = body;
|
|
456
442
|
|
|
@@ -462,7 +448,7 @@ export async function handleJobRestart(req, res, jobId, dataDir, sendJson) {
|
|
|
462
448
|
if (fromTask && singleTask === true) {
|
|
463
449
|
await resetSingleTask(jobDir, fromTask, { clearTokenUsage: true });
|
|
464
450
|
} else if (fromTask) {
|
|
465
|
-
await
|
|
451
|
+
await resetSingleTask(jobDir, fromTask, { clearTokenUsage: true });
|
|
466
452
|
} else {
|
|
467
453
|
await resetJobToCleanSlate(jobDir, { clearTokenUsage: true });
|
|
468
454
|
}
|
|
@@ -843,16 +829,80 @@ export async function handleTaskStart(
|
|
|
843
829
|
return;
|
|
844
830
|
}
|
|
845
831
|
|
|
846
|
-
//
|
|
847
|
-
|
|
848
|
-
|
|
832
|
+
// Read job pipeline config (needed for both task validation and dependency checking)
|
|
833
|
+
const jobPipelinePath = getJobPipelinePath(dataDir, jobId, "current");
|
|
834
|
+
let jobPipeline;
|
|
835
|
+
try {
|
|
836
|
+
const content = await fs.promises.readFile(jobPipelinePath, "utf8");
|
|
837
|
+
jobPipeline = JSON.parse(content);
|
|
838
|
+
} catch (error) {
|
|
839
|
+
sendJson(res, 500, {
|
|
849
840
|
ok: false,
|
|
850
|
-
code: "
|
|
851
|
-
message: "
|
|
841
|
+
code: "pipeline_config_not_found",
|
|
842
|
+
message: "Pipeline configuration not found",
|
|
852
843
|
});
|
|
853
844
|
return;
|
|
854
845
|
}
|
|
855
846
|
|
|
847
|
+
// Helper function to extract task name from string or object
|
|
848
|
+
const getTaskName = (t) => (typeof t === "string" ? t : t.name);
|
|
849
|
+
|
|
850
|
+
// Check if task exists in pipeline.json
|
|
851
|
+
const pipelineTaskNames = (jobPipeline.tasks || []).map(getTaskName);
|
|
852
|
+
const taskExistsInPipeline = pipelineTaskNames.includes(taskId);
|
|
853
|
+
|
|
854
|
+
// Validate task existence - check both tasks-status.json and pipeline.json
|
|
855
|
+
if (!snapshot.tasks || !snapshot.tasks[taskId]) {
|
|
856
|
+
if (!taskExistsInPipeline) {
|
|
857
|
+
// Task not found in either file - true error case
|
|
858
|
+
sendJson(res, 400, {
|
|
859
|
+
ok: false,
|
|
860
|
+
code: "task_not_found",
|
|
861
|
+
message: "Task not found in pipeline definition",
|
|
862
|
+
});
|
|
863
|
+
return;
|
|
864
|
+
}
|
|
865
|
+
|
|
866
|
+
// Task exists in pipeline.json but not in tasks-status.json
|
|
867
|
+
// Auto-add it with default pending state
|
|
868
|
+
console.log(
|
|
869
|
+
`[handleTaskStart] Auto-adding missing task "${taskId}" to tasks-status.json for job ${jobId}`
|
|
870
|
+
);
|
|
871
|
+
|
|
872
|
+
await writeJobStatus(jobDir, (s) => {
|
|
873
|
+
if (!s.tasks) {
|
|
874
|
+
s.tasks = {};
|
|
875
|
+
}
|
|
876
|
+
if (!s.tasks[taskId]) {
|
|
877
|
+
s.tasks[taskId] = {
|
|
878
|
+
state: "pending",
|
|
879
|
+
currentStage: null,
|
|
880
|
+
attempts: 0,
|
|
881
|
+
refinementAttempts: 0,
|
|
882
|
+
files: {
|
|
883
|
+
artifacts: [],
|
|
884
|
+
logs: [],
|
|
885
|
+
tmp: [],
|
|
886
|
+
},
|
|
887
|
+
};
|
|
888
|
+
}
|
|
889
|
+
return s;
|
|
890
|
+
});
|
|
891
|
+
|
|
892
|
+
// Re-read the updated snapshot
|
|
893
|
+
try {
|
|
894
|
+
const content = await fs.promises.readFile(statusPath, "utf8");
|
|
895
|
+
snapshot = JSON.parse(content);
|
|
896
|
+
} catch (error) {
|
|
897
|
+
sendJson(res, 500, {
|
|
898
|
+
ok: false,
|
|
899
|
+
code: "internal_error",
|
|
900
|
+
message: "Failed to read updated job status",
|
|
901
|
+
});
|
|
902
|
+
return;
|
|
903
|
+
}
|
|
904
|
+
}
|
|
905
|
+
|
|
856
906
|
// Validate task state is Pending
|
|
857
907
|
if (snapshot.tasks[taskId].state !== "pending") {
|
|
858
908
|
sendJson(res, 400, {
|
|
@@ -863,21 +913,6 @@ export async function handleTaskStart(
|
|
|
863
913
|
return;
|
|
864
914
|
}
|
|
865
915
|
|
|
866
|
-
// Read job pipeline config
|
|
867
|
-
const jobPipelinePath = getJobPipelinePath(dataDir, jobId, "current");
|
|
868
|
-
let jobPipeline;
|
|
869
|
-
try {
|
|
870
|
-
const content = await fs.promises.readFile(jobPipelinePath, "utf8");
|
|
871
|
-
jobPipeline = JSON.parse(content);
|
|
872
|
-
} catch (error) {
|
|
873
|
-
sendJson(res, 500, {
|
|
874
|
-
ok: false,
|
|
875
|
-
code: "pipeline_config_not_found",
|
|
876
|
-
message: "Pipeline configuration not found",
|
|
877
|
-
});
|
|
878
|
-
return;
|
|
879
|
-
}
|
|
880
|
-
|
|
881
916
|
// Validate dependencies via validateUpstreamDone
|
|
882
917
|
const depCheck = validateUpstreamDone({
|
|
883
918
|
jobPipelineTasks: jobPipeline.tasks,
|