MCPcopy Index your code
hub / github.com/simstudioai/sim / runCheckpointLoop

Function runCheckpointLoop

apps/sim/lib/copilot/request/lifecycle/run.ts:533–880  ·  view source on GitHub ↗
(
  initialPayload: Record<string, unknown>,
  context: StreamingContext,
  execContext: ExecutionContext,
  options: CopilotLifecycleOptions,
  initialRoute: string
)

Source from the content-addressed store, hash-verified

531// ---------------------------------------------------------------------------
532
533async function runCheckpointLoop(
534 initialPayload: Record<string, unknown>,
535 context: StreamingContext,
536 execContext: ExecutionContext,
537 options: CopilotLifecycleOptions,
538 initialRoute: string
539): Promise<void> {
540 let route = initialRoute
541 let payload: Record<string, unknown> = initialPayload
542 let resumeAttempt = 0
543 const callerOnEvent = options.onEvent
544 const mothershipBaseURL = await getMothershipBaseURL({ userId: options.userId })
545 const lifecycleWorkspaceId = nonBlankString(options.workspaceId)
546
547 // Go's auth middleware re-validates every Sim -> Go request by reading
548 // workspaceId from the JSON body and forwarding it to Sim's validate route,
549 // where it is required for the per-member usage gate. Normalize the initial
550 // leg from the lifecycle option so callers that only set the option (not the
551 // raw payload) still send it on the first request.
552 if (lifecycleWorkspaceId && !nonBlankString(payload.workspaceId)) {
553 payload = { ...payload, workspaceId: lifecycleWorkspaceId }
554 }
555
556 // Enterprise BYOK eligibility hint: set once on the initial mothership request
557 // so Go only attempts a BYOK lookup for entitled workspaces. This is only a
558 // gate — Go re-confirms entitlement authoritatively before using any key.
559 payload = await withByokEligibilityHint(payload, route, lifecycleWorkspaceId)
560
561 for (;;) {
562 context.streamComplete = false
563 const isResume = route === '/api/tools/resume'
564
565 if (isResume && isAborted(options, context)) {
566 cancelPendingTools(context)
567 context.awaitingAsyncContinuation = undefined
568 break
569 }
570
571 const loopOptions = {
572 ...options,
573 onEvent: async (event: StreamEvent) => {
574 if (
575 event.type === MothershipStreamV1EventType.run &&
576 event.payload.kind === MothershipStreamV1RunKind.checkpoint_pause &&
577 options.runId
578 ) {
579 try {
580 await updateRunStatus(options.runId, 'paused_waiting_for_tool')
581 } catch (error) {
582 logger.warn('Failed to mark run as paused_waiting_for_tool', {
583 runId: options.runId,
584 error: toError(error).message,
585 })
586 }
587 }
588 await callerOnEvent?.(event)
589 },
590 }

Callers 1

runCopilotLifecycleFunction · 0.85

Calls 15

getMothershipBaseURLFunction · 0.90
updateRunStatusFunction · 0.90
toErrorFunction · 0.90
runStreamLoopFunction · 0.90
toolWatchdogTimeoutMsFunction · 0.90
sleepFunction · 0.90
forceFailHungToolCallFunction · 0.90
executeToolAndReportFunction · 0.90
getToolCallTerminalDataFunction · 0.90
nonBlankStringFunction · 0.85

Tested by

no test coverage detected