@ryanfw/prompt-orchestration-pipeline 1.3.2 → 1.3.3

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 (46) hide show
  1. package/docs/http-api.md +66 -0
  2. package/package.json +1 -1
  3. package/src/api/__tests__/index.test.ts +311 -3
  4. package/src/api/index.ts +94 -45
  5. package/src/config/__tests__/statuses.test.ts +41 -0
  6. package/src/config/statuses.ts +20 -1
  7. package/src/core/__tests__/config.test.ts +31 -1
  8. package/src/core/__tests__/job-concurrency.test.ts +60 -0
  9. package/src/core/__tests__/job-view.test.ts +859 -0
  10. package/src/core/__tests__/orchestrator.test.ts +242 -0
  11. package/src/core/__tests__/runner-liveness.test.ts +865 -0
  12. package/src/core/__tests__/single-derivation.test.ts +159 -0
  13. package/src/core/config.ts +19 -0
  14. package/src/core/job-concurrency.ts +6 -1
  15. package/src/core/job-view.ts +329 -0
  16. package/src/core/orchestrator.ts +78 -6
  17. package/src/core/runner-liveness.ts +276 -0
  18. package/src/core/status-writer.ts +24 -5
  19. package/src/ui/client/__tests__/job-adapter.test.ts +78 -0
  20. package/src/ui/client/adapters/job-adapter.ts +10 -0
  21. package/src/ui/client/types.ts +2 -0
  22. package/src/ui/components/JobTable.tsx +29 -12
  23. package/src/ui/components/__tests__/JobTable.test.tsx +54 -1
  24. package/src/ui/components/types.ts +2 -0
  25. package/src/ui/dist/assets/{index--RH3sAt3.js → index-L6cvsCAx.js} +25 -12
  26. package/src/ui/dist/assets/{index--RH3sAt3.js.map → index-L6cvsCAx.js.map} +1 -1
  27. package/src/ui/dist/index.html +1 -1
  28. package/src/ui/embedded-assets.js +6 -6
  29. package/src/ui/server/__tests__/config-bridge.test.ts +9 -1
  30. package/src/ui/server/__tests__/job-control-endpoints.test.ts +57 -1
  31. package/src/ui/server/__tests__/job-endpoints.test.ts +115 -1
  32. package/src/ui/server/__tests__/sse-enhancer.test.ts +31 -0
  33. package/src/ui/server/config-bridge.ts +3 -4
  34. package/src/ui/server/endpoints/__tests__/meta-endpoint.test.ts +1 -0
  35. package/src/ui/server/endpoints/gate-endpoints.ts +2 -6
  36. package/src/ui/server/endpoints/job-control-endpoints.ts +7 -68
  37. package/src/ui/server/endpoints/job-endpoints.ts +6 -0
  38. package/src/ui/server/endpoints/meta-endpoint.ts +1 -1
  39. package/src/ui/state/__tests__/snapshot.test.ts +51 -0
  40. package/src/ui/state/__tests__/types.test.ts +98 -5
  41. package/src/ui/state/snapshot.ts +1 -1
  42. package/src/ui/state/transformers/__tests__/list-transformer.test.ts +43 -2
  43. package/src/ui/state/transformers/__tests__/status-transformer.test.ts +208 -22
  44. package/src/ui/state/transformers/list-transformer.ts +7 -3
  45. package/src/ui/state/transformers/status-transformer.ts +36 -170
  46. package/src/ui/state/types.ts +9 -47
@@ -22112,6 +22112,7 @@ const TASK_STATE_SYNONYMS = Object.freeze({
22112
22112
  });
22113
22113
  const JOB_STATUS_SYNONYMS = Object.freeze({
22114
22114
  completed: "complete",
22115
+ done: "complete",
22115
22116
  error: "failed"
22116
22117
  });
22117
22118
  const warnedUnknownTaskStates = /* @__PURE__ */ new Set();
@@ -22240,6 +22241,13 @@ function getWarnings(rawTasks) {
22240
22241
  if (Array.isArray(rawTasks) || isRecord$4(rawTasks)) return [];
22241
22242
  return ["Unsupported task collection shape"];
22242
22243
  }
22244
+ function isErrorShape(value) {
22245
+ if (!isRecord$4(value)) return false;
22246
+ if (typeof value["code"] !== "string") return false;
22247
+ if (typeof value["message"] !== "string") return false;
22248
+ if ("path" in value && typeof value["path"] !== "string") return false;
22249
+ return true;
22250
+ }
22243
22251
  function normalizeCostsSummary(costs) {
22244
22252
  if (!isRecord$4(costs)) return EMPTY_COSTS;
22245
22253
  return {
@@ -22316,7 +22324,9 @@ function adaptBaseJob(apiJob) {
22316
22324
  totalCost: toNumber(apiJob["totalCost"], normalizeCostsSummary(apiJob["costsSummary"]).totalCost),
22317
22325
  totalTokens: toNumber(apiJob["totalTokens"], normalizeCostsSummary(apiJob["costsSummary"]).totalTokens),
22318
22326
  displayCategory: getDisplayCategory(status),
22319
- __warnings: getWarnings(rawTasks)
22327
+ __warnings: getWarnings(rawTasks),
22328
+ ...typeof apiJob["readable"] === "boolean" ? { readable: apiJob["readable"] } : {},
22329
+ ...isErrorShape(apiJob["error"]) ? { error: apiJob["error"] } : {}
22320
22330
  };
22321
22331
  }
22322
22332
  function adaptJobSummary(apiJob) {
@@ -78623,6 +78633,8 @@ function JobTable({
78623
78633
  ] }) }),
78624
78634
  /* @__PURE__ */ jsxRuntimeExports.jsx("tbody", { className: "divide-y divide-gray-200", children: jobs.map((job) => {
78625
78635
  const validId = Boolean(job.id);
78636
+ const readable = job.readable !== false;
78637
+ const clickable = validId && readable;
78626
78638
  const taskMap = Array.isArray(job.tasks) ? Object.fromEntries(job.tasks.map((task) => [task.name, task])) : job.tasks;
78627
78639
  const currentTaskId = typeof job.current === "string" ? job.current : job.current?.taskName;
78628
78640
  const currentTask = currentTaskId ? taskMap[currentTaskId] : void 0;
@@ -78633,37 +78645,38 @@ function JobTable({
78633
78645
  return /* @__PURE__ */ jsxRuntimeExports.jsxs(
78634
78646
  "tr",
78635
78647
  {
78636
- className: validId ? "cursor-pointer transition hover:bg-gray-50" : "cursor-not-allowed opacity-60",
78637
- onClick: () => validId && onOpenJob(job.id),
78638
- tabIndex: validId ? 0 : -1,
78648
+ className: clickable ? "cursor-pointer transition hover:bg-gray-50" : "cursor-not-allowed opacity-60",
78649
+ onClick: () => clickable && onOpenJob(job.id),
78650
+ tabIndex: clickable ? 0 : -1,
78639
78651
  onKeyDown: (event) => {
78640
- if (validId && (event.key === "Enter" || event.key === " ")) onOpenJob(job.id);
78652
+ if (clickable && (event.key === "Enter" || event.key === " ")) onOpenJob(job.id);
78641
78653
  },
78642
78654
  children: [
78643
78655
  /* @__PURE__ */ jsxRuntimeExports.jsxs("td", { className: "px-4 py-4", children: [
78644
78656
  /* @__PURE__ */ jsxRuntimeExports.jsx("div", { className: "font-medium text-[#6d28d9]", children: job.name }),
78645
- /* @__PURE__ */ jsxRuntimeExports.jsx("div", { className: "text-xs text-gray-500", children: job.id })
78657
+ /* @__PURE__ */ jsxRuntimeExports.jsx("div", { className: "text-xs text-gray-500", children: job.id }),
78658
+ !readable && job.error ? /* @__PURE__ */ jsxRuntimeExports.jsx("div", { className: "text-xs text-red-600", children: job.error.message }) : null
78646
78659
  ] }),
78647
78660
  /* @__PURE__ */ jsxRuntimeExports.jsx("td", { className: "px-4 py-4 text-sm text-gray-700", children: job.pipelineLabel ?? job.pipeline ?? pipeline?.name ?? "—" }),
78648
- /* @__PURE__ */ jsxRuntimeExports.jsx("td", { className: "px-4 py-4", children: /* @__PURE__ */ jsxRuntimeExports.jsx(Badge, { intent: getIntent(job.status), children: job.status }) }),
78661
+ /* @__PURE__ */ jsxRuntimeExports.jsx("td", { className: "px-4 py-4", children: readable ? /* @__PURE__ */ jsxRuntimeExports.jsx(Badge, { intent: getIntent(job.status), children: job.status }) : /* @__PURE__ */ jsxRuntimeExports.jsx(Badge, { intent: "red", children: "Unreadable" }) }),
78649
78662
  /* @__PURE__ */ jsxRuntimeExports.jsx("td", { className: "px-4 py-4 text-sm text-gray-700", children: currentTask?.name ?? currentTaskId ?? "—" }),
78650
- /* @__PURE__ */ jsxRuntimeExports.jsx("td", { className: "px-4 py-4", children: /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "flex min-w-[160px] items-center gap-3", children: [
78663
+ /* @__PURE__ */ jsxRuntimeExports.jsx("td", { className: "px-4 py-4", children: readable ? /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "flex min-w-[160px] items-center gap-3", children: [
78651
78664
  /* @__PURE__ */ jsxRuntimeExports.jsx(Progress, { value: job.progress, variant: job.status === "failed" ? "error" : job.status === "complete" ? "completed" : job.status === "running" ? "running" : "pending", className: "flex-1" }),
78652
78665
  /* @__PURE__ */ jsxRuntimeExports.jsxs("span", { className: "text-sm text-gray-600", children: [
78653
78666
  job.progress,
78654
78667
  "%"
78655
78668
  ] })
78656
- ] }) }),
78669
+ ] }) : "—" }),
78657
78670
  /* @__PURE__ */ jsxRuntimeExports.jsxs("td", { className: "px-4 py-4 text-sm text-gray-700", children: [
78658
78671
  countCompleted(job),
78659
78672
  " of ",
78660
78673
  job.taskCount
78661
78674
  ] }),
78662
- /* @__PURE__ */ jsxRuntimeExports.jsxs("td", { className: "px-4 py-4", children: [
78675
+ /* @__PURE__ */ jsxRuntimeExports.jsx("td", { className: "px-4 py-4", children: readable ? /* @__PURE__ */ jsxRuntimeExports.jsxs(jsxRuntimeExports.Fragment, { children: [
78663
78676
  /* @__PURE__ */ jsxRuntimeExports.jsx("div", { className: "text-sm text-gray-700", children: totalCost > 0 ? formatCurrency4(totalCost) : "—" }),
78664
78677
  totalTokens > 0 ? /* @__PURE__ */ jsxRuntimeExports.jsx("div", { className: "text-xs text-gray-500", children: formatTokensCompact(totalTokens) }) : null
78665
- ] }),
78666
- /* @__PURE__ */ jsxRuntimeExports.jsx("td", { className: "px-4 py-4 text-sm text-gray-700", children: startMs ? /* @__PURE__ */ jsxRuntimeExports.jsx(TimerText, { startMs, endMs, granularity: "second" }) : "—" })
78678
+ ] }) : "—" }),
78679
+ /* @__PURE__ */ jsxRuntimeExports.jsx("td", { className: "px-4 py-4 text-sm text-gray-700", children: readable ? startMs ? /* @__PURE__ */ jsxRuntimeExports.jsx(TimerText, { startMs, endMs, granularity: "second" }) : "—" : "—" })
78667
78680
  ]
78668
78681
  },
78669
78682
  job.jobId