MCPcopy
hub / github.com/lightningpixel/modly / continueRun

Function continueRun

src/areas/workflows/workflowRunStore.ts:514–603  ·  view source on GitHub ↗
(waitId)

Source from the content-addressed store, hash-verified

512 },
513
514 async continueRun(waitId) {
515 const state = get()
516 if (state.runningBranchId !== null) return
517 // Only runnable Waits: blocked (parent not done) and running are not.
518 const ws = state.waitStates[waitId]
519 if (ws !== 'pending' && ws !== 'done' && ws !== 'error') return
520 // A pending Wait only runs after a clean handoff. If the run errored in the
521 // pre-phase, it never handed off — don't start a branch with missing inputs.
522 if (ws === 'pending' && state.runState.status === 'error') return
523 const ctx = _ctx.current
524 if (!ctx) {
525 console.warn('continueRun: no active run context — was the module hot-reloaded mid-run?')
526 return
527 }
528
529 const branch = ctx.branches.get(waitId) ?? []
530 // Re-running a Wait invalidates everything downstream: descendant branches
531 // were computed against the old output, so drop their outputs and reset
532 // them to blocked until this branch produces a fresh result.
533 const descendants = descendantWaits(waitId, ctx)
534
535 _cancel.current = false
536
537 // Reset outputs for this branch's nodes so Retry re-executes cleanly.
538 for (const node of branch) ctx.nodeOutputs.delete(node.id)
539 for (const d of descendants) for (const node of ctx.branches.get(d) ?? []) ctx.nodeOutputs.delete(node.id)
540
541 set((s) => {
542 const waitStates = { ...s.waitStates, [waitId]: 'running' as WaitState }
543 for (const d of descendants) waitStates[d] = 'blocked'
544 return {
545 runningBranchId: waitId,
546 waitStates,
547 runState: { ...s.runState, status: 'running', blockIndex: 0, blockTotal: branch.length, blockProgress: 0, blockStep: branch.length === 0 ? 'Done' : 'Starting…' },
548 }
549 })
550
551 const finishBranch = (next: WaitState, err?: string): void => {
552 if (_cancel.current) return
553 const newWaitStates = { ...get().waitStates, [waitId]: next }
554 // Unblock nested Waits whose parent branch just finished, and push this
555 // branch's scene output to the viewer.
556 if (next === 'done') {
557 for (const w of ctx.waitIds) {
558 if (ctx.parentWait.get(w) === waitId && newWaitStates[w] === 'blocked') newWaitStates[w] = 'pending'
559 }
560 pushBranchSceneMesh(ctx, waitId)
561 }
562 // A failed branch can never feed its descendants — surface them as error
563 // too, otherwise they stay 'blocked' and the run hangs on 'paused' forever.
564 if (next === 'error') {
565 for (const d of descendantWaits(waitId, ctx)) {
566 if (newWaitStates[d] === 'blocked') newWaitStates[d] = 'error'
567 }
568 }
569 const allFinished = ctx.waitIds.every((id) => newWaitStates[id] === 'done' || newWaitStates[id] === 'error')
570 const anyError = ctx.waitIds.some((id) => newWaitStates[id] === 'error')
571

Callers 1

useWaitButtonFunction · 0.85

Calls 3

descendantWaitsFunction · 0.85
executeExtensionNodeFunction · 0.85
finishBranchFunction · 0.85

Tested by

no test coverage detected