@pasko70/pibo 1.9.13 → 1.10.1

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 (163) hide show
  1. package/README.md +183 -183
  2. package/context/codex-base-prompt.md +148 -148
  3. package/context/compute-worker.md +23 -23
  4. package/context/pibo-compaction-prompt.md +100 -100
  5. package/context/pibo-native-tooling.md +18 -18
  6. package/context/pibo-system-prompt.md +77 -77
  7. package/dist/apps/chat/agent-profiles.js +2 -2
  8. package/dist/apps/chat/agent-store.js +263 -250
  9. package/dist/apps/chat/chat-request-normalizers.js +17 -0
  10. package/dist/apps/chat/data/chat-data-mappers.js +2 -0
  11. package/dist/apps/chat/data/project-service.js +168 -168
  12. package/dist/apps/chat/data/read-state-service.js +18 -18
  13. package/dist/apps/chat/data/session-query-service.js +25 -25
  14. package/dist/apps/chat/data/timeline-query-service.js +19 -19
  15. package/dist/apps/chat/loop-api.js +181 -0
  16. package/dist/apps/chat/static-assets.js +854 -854
  17. package/dist/apps/chat/web-app.js +36 -16
  18. package/dist/apps/chat/workflow-manual-trigger-runtime.js +149 -46
  19. package/dist/apps/chat/workflow-persistence.js +255 -255
  20. package/dist/apps/chat-ui/assets/{dist-BZ2eTC4f.js → dist-3Sts0Afa.js} +1 -1
  21. package/dist/apps/chat-ui/assets/{dist-BHa-kcGl.js → dist-4NlLjLs7.js} +1 -1
  22. package/dist/apps/chat-ui/assets/{dist-yCYNNb5d.js → dist-BA6mhAec.js} +1 -1
  23. package/dist/apps/chat-ui/assets/{dist-D811wJeV.js → dist-BPl-fzRB.js} +1 -1
  24. package/dist/apps/chat-ui/assets/{dist-Dq4GxJi3.js → dist-BPnn9e2B.js} +1 -1
  25. package/dist/apps/chat-ui/assets/{dist-CzE6k3F3.js → dist-BpfBSMzK.js} +1 -1
  26. package/dist/apps/chat-ui/assets/{dist-CnVsqwSG.js → dist-Cvx5M97R.js} +1 -1
  27. package/dist/apps/chat-ui/assets/{dist-WyXdYl-w.js → dist-DnXWNQRm.js} +1 -1
  28. package/dist/apps/chat-ui/assets/{dist-BNMu92bb.js → dist-hU-2oAb6.js} +1 -1
  29. package/dist/apps/chat-ui/assets/{dist-BCB6zezO.js → dist-r31x5Fcc.js} +1 -1
  30. package/dist/apps/chat-ui/assets/{dist-HqTN67dc.js → dist-uF6UXzI7.js} +1 -1
  31. package/dist/apps/chat-ui/assets/index-CaTGYBOS.js +173 -0
  32. package/dist/apps/chat-ui/assets/{index-C0x9nEcf.css → index-al8DeEjA.css} +1 -1
  33. package/dist/apps/chat-ui/index.html +18 -18
  34. package/dist/apps/chat-ui/manifest.webmanifest +25 -25
  35. package/dist/apps/chat-ui/sw.js +47 -47
  36. package/dist/apps/chat-vscode-web/assets/index-CK4SMZuu.js +41 -0
  37. package/dist/apps/chat-vscode-web/index.html +13 -13
  38. package/dist/apps/cli-ui/cliSessionsCommand.js +23 -23
  39. package/dist/apps/context-files-ui/index.html +11 -11
  40. package/dist/cli-session/localSessionSource.js +34 -12
  41. package/dist/cli.js +61 -44
  42. package/dist/compute/cli.js +54 -54
  43. package/dist/compute/resource-health.js +35 -2
  44. package/dist/core/events.js +6 -1
  45. package/dist/core/routed-session.js +97 -5
  46. package/dist/core/runtime.js +6 -1
  47. package/dist/core/session-router.js +27 -8
  48. package/dist/cron/cli.js +15 -15
  49. package/dist/cron/store.js +49 -49
  50. package/dist/data/cli.js +23 -23
  51. package/dist/data/event-log.js +23 -23
  52. package/dist/data/ingest-service.js +3 -1
  53. package/dist/data/message-store.js +27 -27
  54. package/dist/data/navigation-store.js +9 -9
  55. package/dist/data/observation-store.js +4 -4
  56. package/dist/data/payload-store.js +17 -17
  57. package/dist/data/schema.js +433 -433
  58. package/dist/data/session-store.js +4 -4
  59. package/dist/data/telemetry-queries.js +54 -54
  60. package/dist/data/telemetry.js +197 -197
  61. package/dist/debug/events.js +12 -12
  62. package/dist/debug/failures.js +6 -6
  63. package/dist/debug/index.js +231 -227
  64. package/dist/debug/messages.js +6 -6
  65. package/dist/debug/pty.js +124 -124
  66. package/dist/debug/session.js +29 -29
  67. package/dist/debug/tools.js +5 -5
  68. package/dist/debug/trace.js +42 -7
  69. package/dist/debug/web-snapshot-browser-scripts.js +294 -294
  70. package/dist/debug/web-streaming-browser-library.js +925 -925
  71. package/dist/debug/web-streaming-browser-scripts.js +232 -232
  72. package/dist/debug/web-streaming-provider-telemetry.js +4 -4
  73. package/dist/debug/web.js +93 -93
  74. package/dist/gateway/cli.js +19 -19
  75. package/dist/gateway/server.js +4 -2
  76. package/dist/gateway/web.js +2 -2
  77. package/dist/index.js +1 -0
  78. package/dist/loops/accounting.js +19 -0
  79. package/dist/loops/channel.js +8 -0
  80. package/dist/loops/cli.js +224 -0
  81. package/dist/loops/plugin.js +16 -0
  82. package/dist/loops/prompts.js +86 -0
  83. package/dist/loops/service.js +446 -0
  84. package/dist/loops/stopping.js +170 -0
  85. package/dist/loops/store.js +642 -0
  86. package/dist/loops/templates.js +232 -0
  87. package/dist/loops/tools.js +184 -0
  88. package/dist/loops/types.js +1 -0
  89. package/dist/mcp/config-command.js +53 -53
  90. package/dist/mcp/index.js +21 -21
  91. package/dist/mcp/registry.js +11 -11
  92. package/dist/pi-packages/cli.js +11 -11
  93. package/dist/plugins/builtin.js +8 -0
  94. package/dist/plugins/context-files-store.js +110 -110
  95. package/dist/plugins/context-files.js +4 -4
  96. package/dist/plugins/registry.js +23 -12
  97. package/dist/ralph/cli.js +18 -18
  98. package/dist/ralph/templates.js +140 -140
  99. package/dist/reliability/store.js +256 -229
  100. package/dist/runs/lifecycle.js +59 -0
  101. package/dist/runs/registry.js +47 -1
  102. package/dist/runs/tools.js +31 -13
  103. package/dist/session-ui/terminalRows.js +66 -2
  104. package/dist/sessions/pibo-data-store.js +16 -16
  105. package/dist/sessions/sqlite-store.js +53 -53
  106. package/dist/setup/cli.js +58 -58
  107. package/dist/shared/trace-async-agent-runs.js +4 -4
  108. package/dist/shared/trace-event-projection.js +59 -19
  109. package/dist/shared/trace-nodes.js +5 -0
  110. package/dist/shared/trace-page-merge.js +15 -0
  111. package/dist/shared/trace-run-notifications.js +3 -1
  112. package/dist/signals/projector.js +6 -2
  113. package/dist/tools/agent-browser-wrapper.js +80 -80
  114. package/dist/tools/browser-pool.js +50 -0
  115. package/dist/tools/browser-use-cdp.js +12 -12
  116. package/dist/tools/browser-use-leases.js +12 -8
  117. package/dist/tools/browser-use-wrapper.js +762 -762
  118. package/dist/tools/guides.js +596 -538
  119. package/dist/tools/index.js +123 -99
  120. package/dist/tools/registry.js +21 -3
  121. package/dist/tools/runtime/node-worker-source.js +205 -205
  122. package/dist/tools/runtime/python-worker-source.js +177 -177
  123. package/dist/vscode/cli.js +9 -9
  124. package/dist/web-annotations/cdp.js +900 -900
  125. package/dist/web-annotations/store.js +96 -96
  126. package/docs/README.md +23 -23
  127. package/docs/ops/install-developer-host.md +112 -112
  128. package/docs/ops/install-user-host.md +96 -96
  129. package/docs/ops/upgrade-user-to-developer-host.md +69 -69
  130. package/docs/ops/vscode-extension-release.md +160 -160
  131. package/package.json +99 -95
  132. package/skills/builtin/graphify/SKILL.md +52 -52
  133. package/skills/builtin/loop/SKILL.md +78 -0
  134. package/skills/builtin/pi-agent-harness/SKILL.md +319 -319
  135. package/skills/builtin/pi-agent-harness/agents/openai.yaml +4 -4
  136. package/skills/builtin/pibo-docker-system/SKILL.md +170 -170
  137. package/skills/builtin/pibo-spec-writing/SKILL.md +330 -330
  138. package/skills/builtin/prd/SKILL.md +143 -143
  139. package/skills/builtin/ralph-loop/SKILL.md +361 -359
  140. package/skills/builtin/ralph-prd-json/SKILL.md +123 -123
  141. package/skills/builtin/skill-creator/LICENSE.txt +201 -201
  142. package/skills/builtin/skill-creator/SKILL.md +513 -513
  143. package/skills/builtin/skill-creator/agents/analyzer.md +274 -274
  144. package/skills/builtin/skill-creator/agents/comparator.md +202 -202
  145. package/skills/builtin/skill-creator/agents/grader.md +223 -223
  146. package/skills/builtin/skill-creator/assets/eval_review.html +146 -146
  147. package/skills/builtin/skill-creator/eval-viewer/generate_review.py +471 -471
  148. package/skills/builtin/skill-creator/eval-viewer/viewer.html +1325 -1325
  149. package/skills/builtin/skill-creator/references/schemas.md +430 -430
  150. package/skills/builtin/skill-creator/scripts/aggregate_benchmark.py +401 -401
  151. package/skills/builtin/skill-creator/scripts/generate_report.py +326 -326
  152. package/skills/builtin/skill-creator/scripts/improve_description.py +247 -247
  153. package/skills/builtin/skill-creator/scripts/package_skill.py +136 -136
  154. package/skills/builtin/skill-creator/scripts/quick_validate.py +102 -102
  155. package/skills/builtin/skill-creator/scripts/run_eval.py +310 -310
  156. package/skills/builtin/skill-creator/scripts/run_loop.py +328 -328
  157. package/skills/builtin/skill-creator/scripts/utils.py +47 -47
  158. package/skills/builtin/web-annotations/SKILL.md +93 -93
  159. package/src/mcp/LICENSE.mcp-cli +21 -21
  160. package/dist/apps/chat-ui/assets/index-DwHJfmiF.js +0 -173
  161. package/dist/apps/chat-vscode-web/assets/index-BAMxIaI_.js +0 -41
  162. package/dist/apps/vscode-artifacts/latest.vsix +0 -0
  163. package/dist/apps/vscode-artifacts/pibo-vscode-ext-1.9.13.vsix +0 -0
@@ -1,6 +1,7 @@
1
1
  import { createHash, randomUUID } from "node:crypto";
2
2
  import os from "node:os";
3
3
  import { monitorEventLoopDelay } from "node:perf_hooks";
4
+ import { PiboSteeringUnavailableError } from "../../core/events.js";
4
5
  import { summarizeSessionSignalStatus } from "../../signals/status.js";
5
6
  import { PiboWebHttpError, readJsonBody, responseJson } from "../../web/http.js";
6
7
  import { OutputCompactor } from "./output-compactor.js";
@@ -33,9 +34,9 @@ import { ChatTimelineQueryService } from "./data/timeline-query-service.js";
33
34
  import { ChatProjectService } from "./data/project-service.js";
34
35
  import { PiboDataStore } from "../../data/pibo-store.js";
35
36
  import { createDefaultPiboCronStore } from "../../cron/store.js";
36
- import { createDefaultPiboRalphStore } from "../../ralph/store.js";
37
+ import { createDefaultPiboLoopStore } from "../../loops/store.js";
37
38
  import { handleChatCronApiRequest } from "./cron-api.js";
38
- import { handleChatRalphApiRequest } from "./ralph-api.js";
39
+ import { handleChatLoopApiRequest } from "./loop-api.js";
39
40
  import { prepareWebAnnotationMessageAttachments } from "../../web-annotations/attachments.js";
40
41
  import { createDefaultWebAnnotationStore } from "../../web-annotations/store.js";
41
42
  import { CHAT_WEB_MOUNT_PATH, isChatAppPath, responseBuiltChatAsset, responseBuiltChatPublicFile, responseChatAppShell, isVscodeAppPath, responseBuiltVscodeAsset, responseVscodeAppShell } from "./static-assets.js";
@@ -45,7 +46,7 @@ import { chatSettingsRoute, chatSettingsRouteInvalidatesBootstrapCatalog, chatSe
45
46
  import { chatCapabilityRoute, chatCapabilityRouteRequiresSameOrigin, handleChatCapabilityRoute, } from "./chat-capability-routes.js";
46
47
  import { chatUserSkillRoute, chatUserSkillRouteRequiresSameOrigin, handleChatUserSkillRoute, syncChatUserSkills, } from "./chat-user-skill-routes.js";
47
48
  import { CHAT_WEB_API_PREFIX, agentResourceId, projectResourcePath, projectSessionResourceId, projectWorkflowHumanActionsResource, projectWorkflowSessionStartResource, roomResourcePath, sessionActionResource, sessionResourceId, signalResource, workflowArchiveResourceId, workflowCatalogResourceId, workflowDraftActionResource, workflowDraftManualTriggerRunResource, workflowDraftResourceId, workflowDuplicateResourceId, workflowNextDraftResourceId, workflowPickerKind, workflowPromptAssetResourceId, workflowVersionResource, } from "./chat-api-routes.js";
48
- import { assertProjectSessionPatchFields, buildStreamingFixtureSchedule, createAgentInput, createAgentUpdate, createRoomUpdate, createSessionUpdate, normalizeAgentArchived, normalizeClientTxnId, normalizeMessageText, normalizeParentRoomId, normalizeProjectArchived, normalizeProjectDescription, normalizeProjectPath, normalizeProjectSessionArchived, normalizeRoomDeleteConfirmation, normalizeRoomName, normalizeRoomTopic, normalizeRoomType, normalizeRoomWorkspace, normalizeSessionDeleteConfirmation, normalizeSessionTitle, normalizeStreamingFixtureCadenceMs, normalizeStreamingFixtureDeltas, normalizeStreamingFixtureMix, normalizeStreamingFixturePreludeMessages, normalizeStreamingFixturePreludeOnly, normalizeStreamingFixtureProfile, normalizeStreamingFixtureSuppressLiveDeltas, normalizeStreamingFixtureTraceSnapshots, resolveCreateSessionProfile, } from "./chat-request-normalizers.js";
49
+ import { assertProjectSessionPatchFields, buildStreamingFixtureSchedule, createAgentInput, createAgentUpdate, createRoomUpdate, createSessionUpdate, normalizeAgentArchived, normalizeClientTxnId, normalizeMessageDelivery, normalizeMessageText, normalizeParentRoomId, normalizeProjectArchived, normalizeProjectDescription, normalizeProjectPath, normalizeProjectSessionArchived, normalizeRoomDeleteConfirmation, normalizeRoomName, normalizeRoomTopic, normalizeRoomType, normalizeRoomWorkspace, normalizeSessionDeleteConfirmation, normalizeSessionTitle, normalizeStreamingFixtureCadenceMs, normalizeStreamingFixtureDeltas, normalizeStreamingFixtureMix, normalizeStreamingFixturePreludeMessages, normalizeStreamingFixturePreludeOnly, normalizeStreamingFixtureProfile, normalizeStreamingFixtureSuppressLiveDeltas, normalizeStreamingFixtureTraceSnapshots, resolveCreateSessionProfile, } from "./chat-request-normalizers.js";
49
50
  import { ChatWorkflowArchiveStore, ChatWorkflowDraftStore, ChatWorkflowLifecycleEventStore, ChatWorkflowPromptAssetStore, ChatWorkflowPublishedVersionStore, ChatWorkflowTombstoneStore, hashWorkflowDefinitionJson, normalizeWorkflowPromptAssetLabel, sanitizeWorkflowDiagnostics, } from "./workflow-persistence.js";
50
51
  import { normalizeProjectWorkflowHumanActionBody, projectWorkflowHumanActionDiagnosticResponse, projectWorkflowHumanActionLifecyclePayload, projectWorkflowHumanActionRuntimeDiagnostic, projectWorkflowHumanActionSubmittedLifecyclePayload, projectWorkflowPendingHumanActionFromToken, validateProjectWorkflowHumanActionRequest, } from "./project-workflow-human-actions.js";
51
52
  import { createProjectWorkflowRunCurrent, createProjectWorkflowSessionSnapshot, normalizeProjectWorkflowSessionConfiguration, workflowVersionFromSnapshot, } from "./project-workflow-sessions.js";
@@ -2785,6 +2786,7 @@ function applyProjectSessionArchiveState(nodes, archivedBySessionId) {
2785
2786
  }
2786
2787
  async function sendProjectMessage(input) {
2787
2788
  const text = normalizeMessageText(input.body.text);
2789
+ const delivery = normalizeMessageDelivery(input.body.delivery);
2788
2790
  const clientTxnId = normalizeClientTxnId(input.body.clientTxnId);
2789
2791
  if (typeof input.body.piboSessionId !== "string")
2790
2792
  throw new PiboWebHttpError("Project session is required", 400);
@@ -2808,20 +2810,30 @@ async function sendProjectMessage(input) {
2808
2810
  piboSessionId: selectedSession.id,
2809
2811
  projectId: projectSession.projectId,
2810
2812
  text,
2813
+ delivery,
2811
2814
  ...(clientTxnId ? { clientTxnId } : {}),
2812
2815
  },
2813
2816
  });
2814
2817
  for (const listener of input.state.liveListeners)
2815
2818
  listener(accepted);
2816
2819
  const messageId = clientTxnId ?? randomUUID();
2817
- const output = await input.context.channelContext.emit({
2818
- type: "message",
2819
- piboSessionId: selectedSession.id,
2820
- id: messageId,
2821
- text,
2822
- source: "user",
2823
- });
2824
- return responseJson({ accepted, output });
2820
+ try {
2821
+ const output = await input.context.channelContext.emit({
2822
+ type: "message",
2823
+ piboSessionId: selectedSession.id,
2824
+ id: messageId,
2825
+ text,
2826
+ delivery,
2827
+ source: "user",
2828
+ });
2829
+ return responseJson({ accepted, output });
2830
+ }
2831
+ catch (error) {
2832
+ if (error instanceof PiboSteeringUnavailableError) {
2833
+ throw new PiboWebHttpError(error.message, 409);
2834
+ }
2835
+ throw error;
2836
+ }
2825
2837
  }
2826
2838
  function startChatStreamingFixture(input) {
2827
2839
  const requestedRoomId = typeof input.body.roomId === "string" ? input.body.roomId : undefined;
@@ -2918,6 +2930,7 @@ function startChatStreamingFixture(input) {
2918
2930
  }
2919
2931
  async function sendChatMessage(input) {
2920
2932
  const text = normalizeMessageText(input.body.text);
2933
+ const delivery = normalizeMessageDelivery(input.body.delivery);
2921
2934
  const clientTxnId = normalizeClientTxnId(input.body.clientTxnId);
2922
2935
  const requestedRoomId = input.forcedRoomId ?? (typeof input.body.roomId === "string" ? input.body.roomId : undefined);
2923
2936
  const selectedSession = resolveRequestedSession(input.state, input.context, input.webSession, input.defaultProfile, typeof input.body.piboSessionId === "string" ? input.body.piboSessionId : undefined, requestedRoomId);
@@ -2955,6 +2968,7 @@ async function sendChatMessage(input) {
2955
2968
  piboSessionId: selectedSession.id,
2956
2969
  roomId: room.id,
2957
2970
  text: fileAttachmentContext.messageText,
2971
+ delivery,
2958
2972
  ...(webAnnotationContext.attachments.length ? {
2959
2973
  webAnnotationIds: webAnnotationContext.ids,
2960
2974
  webAnnotationAttachments: webAnnotationContext.attachments,
@@ -2991,12 +3005,15 @@ async function sendChatMessage(input) {
2991
3005
  piboSessionId: selectedSession.id,
2992
3006
  id: messageId,
2993
3007
  text: fileAttachmentContext.messageText,
3008
+ delivery,
2994
3009
  source: "user",
2995
3010
  });
2996
3011
  }
2997
3012
  catch (error) {
2998
3013
  const errorMessage = error instanceof Error ? error.message : String(error);
2999
- input.context.channelContext.reportSessionError?.(selectedSession.id, errorMessage, { eventId: messageId, source: "pibo" });
3014
+ if (!(error instanceof PiboSteeringUnavailableError)) {
3015
+ input.context.channelContext.reportSessionError?.(selectedSession.id, errorMessage, { eventId: messageId, source: "pibo" });
3016
+ }
3000
3017
  const failed = input.state.eventCommands.appendEvent({
3001
3018
  roomId: room.id,
3002
3019
  piboSessionId: selectedSession.id,
@@ -3014,6 +3031,9 @@ async function sendChatMessage(input) {
3014
3031
  });
3015
3032
  for (const listener of input.state.liveListeners)
3016
3033
  listener(failed);
3034
+ if (error instanceof PiboSteeringUnavailableError) {
3035
+ throw new PiboWebHttpError(error.message, 409);
3036
+ }
3017
3037
  throw error;
3018
3038
  }
3019
3039
  markWebAnnotationsAttached(webAnnotationContext);
@@ -3034,7 +3054,7 @@ export function createChatWebApp(options = {}) {
3034
3054
  agentStore: createAgentStore(options.agentStorePath),
3035
3055
  reliabilityStore: createReliabilityStore(options.reliabilityStorePath),
3036
3056
  cronStore: createDefaultPiboCronStore({ path: options.cronStorePath }),
3037
- ralphStore: createDefaultPiboRalphStore({ path: options.ralphStorePath }),
3057
+ loopStore: createDefaultPiboLoopStore({ path: options.ralphStorePath }),
3038
3058
  dataStore,
3039
3059
  ingestService: new ChatDataIngestService(dataStore),
3040
3060
  traceCache: new Map(),
@@ -3222,14 +3242,14 @@ export function createChatWebApp(options = {}) {
3222
3242
  if (response)
3223
3243
  return response;
3224
3244
  }
3225
- if (url.pathname.startsWith(`${CHAT_WEB_API_PREFIX}/ralph`)) {
3245
+ if (url.pathname.startsWith(`${CHAT_WEB_API_PREFIX}/loops`) || url.pathname.startsWith(`${CHAT_WEB_API_PREFIX}/loop`) || url.pathname.startsWith(`${CHAT_WEB_API_PREFIX}/ralph`)) {
3226
3246
  const webSession = await requireSession(request, context);
3227
- const response = await handleChatRalphApiRequest({
3247
+ const response = await handleChatLoopApiRequest({
3228
3248
  request,
3229
3249
  context,
3230
3250
  webSession,
3231
3251
  roomService: state.roomService,
3232
- ralphStore: state.ralphStore,
3252
+ loopStore: state.loopStore,
3233
3253
  defaultProfile,
3234
3254
  });
3235
3255
  if (response)
@@ -1,4 +1,8 @@
1
1
  import { randomUUID } from "node:crypto";
2
+ import { Annotation, END, START, StateGraph } from "@langchain/langgraph";
3
+ const WorkflowManualTriggerState = Annotation.Root({
4
+ execution: Annotation(),
5
+ });
2
6
  export async function runWorkflowManualTextTrigger(options) {
3
7
  const diagnostics = validateWorkflowManualTextTrigger(options.definition, options.triggerNodeId, options.input, options.resolveProfile);
4
8
  if (diagnostics.some((diagnostic) => diagnostic.severity === "error")) {
@@ -17,8 +21,6 @@ export async function runWorkflowManualTextTrigger(options) {
17
21
  createdAt: now,
18
22
  updatedAt: now,
19
23
  };
20
- const nodeAttempts = [];
21
- const edgeTransfers = [];
22
24
  const triggerAttempt = {
23
25
  id: `wna_${randomUUID()}`,
24
26
  workflowRunId: run.id,
@@ -30,52 +32,153 @@ export async function runWorkflowManualTextTrigger(options) {
30
32
  startedAt: now,
31
33
  completedAt: now,
32
34
  };
33
- nodeAttempts.push(triggerAttempt);
34
- const queue = [];
35
- enqueueOutgoingEdges(options.definition, run.id, triggerAttempt, queue, edgeTransfers);
36
- const executedNodes = new Set();
37
- let lastOutput = options.input;
38
- while (queue.length) {
39
- const pending = queue.shift();
40
- if (executedNodes.has(pending.nodeId)) {
41
- const failedAt = new Date().toISOString();
42
- run.status = "failed";
43
- run.failedAt = failedAt;
44
- run.updatedAt = failedAt;
45
- return {
46
- ok: false,
47
- run,
48
- nodeAttempts,
49
- edgeTransfers,
50
- diagnostics: [{
51
- code: "WorkflowRuntimeError.joinUnsupported",
52
- message: `Workflow node '${pending.nodeId}' received more than one input, but manual trigger V1 does not support joins yet.`,
53
- severity: "error",
54
- nodeId: pending.nodeId,
55
- edgeId: pending.viaEdgeId,
56
- path: `$.edges.${pending.viaEdgeId}`,
57
- }],
58
- error: { code: "WorkflowRuntimeError.joinUnsupported", message: "Manual trigger run failed because a join node was reached." },
59
- };
60
- }
61
- executedNodes.add(pending.nodeId);
62
- const result = await runAgentNode({ ...options, runId: run.id, nodeId: pending.nodeId, input: pending.input });
63
- nodeAttempts.push(result.attempt);
64
- if (!result.ok) {
65
- const failedAt = new Date().toISOString();
66
- run.status = "failed";
67
- run.failedAt = failedAt;
68
- run.updatedAt = failedAt;
69
- return { ok: false, run, nodeAttempts, edgeTransfers, diagnostics: result.diagnostics, error: result.attempt.error };
70
- }
71
- lastOutput = result.output;
72
- enqueueOutgoingEdges(options.definition, run.id, result.attempt, queue, edgeTransfers);
35
+ const initialState = {
36
+ run,
37
+ nodeAttempts: [triggerAttempt],
38
+ edgeTransfers: [],
39
+ pending: [],
40
+ executedNodeIds: [],
41
+ lastOutput: options.input,
42
+ };
43
+ let execution;
44
+ try {
45
+ const graph = compileWorkflowManualTriggerGraph(options);
46
+ const result = await graph.invoke({ execution: initialState }, { recursionLimit: workflowGraphRecursionLimit(options.definition) });
47
+ execution = result.execution;
48
+ }
49
+ catch (error) {
50
+ const failedAt = new Date().toISOString();
51
+ run.status = "failed";
52
+ run.failedAt = failedAt;
53
+ run.updatedAt = failedAt;
54
+ return {
55
+ ok: false,
56
+ run,
57
+ nodeAttempts: initialState.nodeAttempts,
58
+ edgeTransfers: initialState.edgeTransfers,
59
+ diagnostics: [{
60
+ code: "WorkflowRuntimeError.langGraphExecutionFailed",
61
+ message: error instanceof Error ? error.message : "LangGraph execution failed with a non-Error value.",
62
+ severity: "error",
63
+ path: "$",
64
+ }],
65
+ error: {
66
+ code: "WorkflowRuntimeError.langGraphExecutionFailed",
67
+ message: "Manual trigger run failed during LangGraph execution.",
68
+ },
69
+ };
70
+ }
71
+ if (execution.failure) {
72
+ return {
73
+ ok: false,
74
+ run: execution.run,
75
+ nodeAttempts: execution.nodeAttempts,
76
+ edgeTransfers: execution.edgeTransfers,
77
+ diagnostics: execution.failure.diagnostics,
78
+ error: execution.failure.error,
79
+ };
73
80
  }
74
81
  const completedAt = new Date().toISOString();
75
- run.output = lastOutput;
76
- run.completedAt = completedAt;
77
- run.updatedAt = completedAt;
78
- return { ok: true, run, nodeAttempts, edgeTransfers, diagnostics, output: lastOutput };
82
+ execution.run.output = execution.lastOutput;
83
+ execution.run.completedAt = completedAt;
84
+ execution.run.updatedAt = completedAt;
85
+ return {
86
+ ok: true,
87
+ run: execution.run,
88
+ nodeAttempts: execution.nodeAttempts,
89
+ edgeTransfers: execution.edgeTransfers,
90
+ diagnostics,
91
+ output: execution.lastOutput,
92
+ };
93
+ }
94
+ function compileWorkflowManualTriggerGraph(options) {
95
+ const nodes = objectValue(options.definition.nodes) ?? {};
96
+ const graphNodeNames = new Map();
97
+ for (const nodeId of Object.keys(nodes))
98
+ graphNodeNames.set(nodeId, workflowGraphNodeName(nodeId));
99
+ const triggerGraphNode = graphNodeNames.get(options.triggerNodeId) ?? workflowGraphNodeName(options.triggerNodeId);
100
+ const graph = new StateGraph(WorkflowManualTriggerState);
101
+ graph.addNode(triggerGraphNode, async (state) => {
102
+ const execution = state.execution;
103
+ const triggerAttempt = execution.nodeAttempts[0];
104
+ enqueueOutgoingEdges(options.definition, execution.run.id, triggerAttempt, execution.pending, execution.edgeTransfers);
105
+ execution.current = execution.pending.shift();
106
+ return { execution };
107
+ });
108
+ for (const [nodeId, rawNode] of Object.entries(nodes)) {
109
+ if (nodeId === options.triggerNodeId || objectValue(rawNode)?.kind !== "agent")
110
+ continue;
111
+ const graphNodeName = graphNodeNames.get(nodeId);
112
+ graph.addNode(graphNodeName, async (state) => {
113
+ const execution = state.execution;
114
+ const pending = execution.current;
115
+ if (!pending || pending.nodeId !== nodeId) {
116
+ markWorkflowGraphFailure(execution, {
117
+ diagnostics: [{
118
+ code: "WorkflowRuntimeError.langGraphStateMismatch",
119
+ message: `LangGraph scheduled workflow node '${nodeId}' without its pending input.`,
120
+ severity: "error",
121
+ nodeId,
122
+ path: `$.nodes.${nodeId}`,
123
+ }],
124
+ error: { code: "WorkflowRuntimeError.langGraphStateMismatch", message: "Manual trigger run reached an invalid LangGraph state." },
125
+ });
126
+ return { execution };
127
+ }
128
+ if (execution.executedNodeIds.includes(nodeId)) {
129
+ markWorkflowGraphFailure(execution, {
130
+ diagnostics: [{
131
+ code: "WorkflowRuntimeError.joinUnsupported",
132
+ message: `Workflow node '${nodeId}' received more than one input, but manual trigger V1 does not support joins yet.`,
133
+ severity: "error",
134
+ nodeId,
135
+ edgeId: pending.viaEdgeId,
136
+ path: `$.edges.${pending.viaEdgeId}`,
137
+ }],
138
+ error: { code: "WorkflowRuntimeError.joinUnsupported", message: "Manual trigger run failed because a join node was reached." },
139
+ });
140
+ return { execution };
141
+ }
142
+ execution.executedNodeIds.push(nodeId);
143
+ const result = await runAgentNode({ ...options, runId: execution.run.id, nodeId, input: pending.input });
144
+ execution.nodeAttempts.push(result.attempt);
145
+ if (!result.ok) {
146
+ markWorkflowGraphFailure(execution, { diagnostics: result.diagnostics, error: result.attempt.error });
147
+ return { execution };
148
+ }
149
+ execution.lastOutput = result.output;
150
+ enqueueOutgoingEdges(options.definition, execution.run.id, result.attempt, execution.pending, execution.edgeTransfers);
151
+ execution.current = execution.pending.shift();
152
+ return { execution };
153
+ });
154
+ }
155
+ const route = (state) => {
156
+ if (state.execution.failure || !state.execution.current)
157
+ return END;
158
+ return graphNodeNames.get(state.execution.current.nodeId) ?? END;
159
+ };
160
+ graph.addEdge(START, triggerGraphNode);
161
+ graph.addConditionalEdges(triggerGraphNode, route);
162
+ for (const [nodeId, rawNode] of Object.entries(nodes)) {
163
+ if (nodeId === options.triggerNodeId || objectValue(rawNode)?.kind !== "agent")
164
+ continue;
165
+ graph.addConditionalEdges(graphNodeNames.get(nodeId), route);
166
+ }
167
+ return graph.compile();
168
+ }
169
+ function workflowGraphNodeName(nodeId) {
170
+ return `pibo_${Buffer.from(nodeId).toString("base64url")}`;
171
+ }
172
+ function workflowGraphRecursionLimit(definition) {
173
+ return Math.max(25, Object.keys(objectValue(definition.nodes) ?? {}).length * 2 + 2);
174
+ }
175
+ function markWorkflowGraphFailure(execution, failure) {
176
+ const failedAt = new Date().toISOString();
177
+ execution.run.status = "failed";
178
+ execution.run.failedAt = failedAt;
179
+ execution.run.updatedAt = failedAt;
180
+ execution.failure = failure;
181
+ execution.current = undefined;
79
182
  }
80
183
  export function validateWorkflowManualTextTrigger(definition, triggerNodeId, input, resolveProfile) {
81
184
  const diagnostics = [];