-
Notifications
You must be signed in to change notification settings - Fork 3.1k
feat(hitl): add human in the loop block #1832
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Merged
Merged
Changes from all commits
Commits
Show all changes
53 commits
Select commit
Hold shift + click to select a range
219a065
v0.4.12: guardrails, mistral models, privacy policy updates (#1608)
waleedlatif1 7f82ed3
v0.4.13: bugfixes for dev containers, posthog redirect, helm updates
icecrasher321 fb0fa1f
v0.4.14: canvas speedup and copilot context window
Sg312 2bc8c7b
v0.4.15: helm chart updates, telegram tools, youtube tools, file uplo…
waleedlatif1 04f109c
v0.4.16: executions dashboard, UI fixes, zep tools, slack fixes
icecrasher321 da091df
v0.4.17: input format + files support for webhooks, docs updates, das…
waleedlatif1 e4ddeb0
v0.4.18: file upload tools, copilot upgrade, docs changes, model filt…
icecrasher321 641e353
v0.4.19: landing page fix
icecrasher321 9751c9f
v0.4.20: internal request, kb url fixes, docs styling
icecrasher321 1b7437a
v0.4.21: more internal auth changes, supabase vector search tool
icecrasher321 71ae27b
v0.4.22: fix execution context pass for google sheets
icecrasher321 9b2490c
v0.4.23: webflow tools + triggers, copilot api key fix (#1723)
waleedlatif1 7f1ff7f
fix(billing): should allow restoring subscription (#1728)
icecrasher321 a02016e
v0.4.24: sso for chat deployment, usage indicator for file storage, m…
icecrasher321 9a4b9e2
v0.4.25: variables block, sort ordering for kb, careers page, storage…
waleedlatif1 f6e7891
Add pause resume block
Sg312 b994268
Add db schema
Sg312 bd06e6b
Initial test passes
Sg312 224b9b1
Tests pass
Sg312 99b27de
Execution pauses
Sg312 0f27f24
Snapshot serializer
Sg312 a7c3dea
Ui checkpoint
Sg312 dd0c1b6
Works 1
Sg312 ba9b46f
Pause resume simple v1
Sg312 cec668f
Hitl block works in parallel branches without timing overlap
Sg312 e28ee98
Pending status to logs
Sg312 2292661
Pause resume ui link
Sg312 517c5d3
Big context consolidation
Sg312 9b51546
HITL works in loops
Sg312 4871649
Fix parallels
Sg312 72ab4a0
Reference blocks properly
Sg312 be48de8
Fix tag dropdown and start block resolution
Sg312 a0b8dda
Filter console logs for hitl block
Sg312 c7f05f1
Fix notifs
Sg312 3df1e26
Fix logs page
Sg312 1e14a0c
Fix logs page again
Sg312 b4a2ef9
Fix
Sg312 d21ce2c
Merge remote-tracking branch 'origin' into feat/hitl-2
Sg312 01fbe7f
Checkpoint
Sg312 a29c443
Cleanup v1
Sg312 b390205
Refactor v2
Sg312 d40d899
Refactor v3
Sg312 07b1678
Refactor v4
Sg312 14a248f
Refactor v5
Sg312 1369be2
Resume page
Sg312 2f019b1
Fix variables in loops
Sg312 6449f77
Fix var res bugs
Sg312 2162026
Ui changes
Sg312 0b02471
Approval block
Sg312 d5f12ea
Hitl works e2e v1
Sg312 0180947
Merge with staging
Sg312 c64fe48
Fix tets
Sg312 b7026fe
Row level lock
Sg312 File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
116 changes: 116 additions & 0 deletions
116
apps/sim/app/api/resume/[workflowId]/[executionId]/[contextId]/route.ts
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,116 @@ | ||
| import { type NextRequest, NextResponse } from 'next/server' | ||
| import { createLogger } from '@/lib/logs/console/logger' | ||
| import { PauseResumeManager } from '@/lib/workflows/executor/pause-resume-manager' | ||
| import { validateWorkflowAccess } from '@/app/api/workflows/middleware' | ||
|
|
||
| const logger = createLogger('WorkflowResumeAPI') | ||
|
|
||
| export const runtime = 'nodejs' | ||
| export const dynamic = 'force-dynamic' | ||
|
|
||
| export async function POST( | ||
| request: NextRequest, | ||
| { | ||
| params, | ||
| }: { | ||
| params: Promise<{ workflowId: string; executionId: string; contextId: string }> | ||
| } | ||
| ) { | ||
| const { workflowId, executionId, contextId } = await params | ||
|
|
||
| const access = await validateWorkflowAccess(request, workflowId, false) | ||
| if (access.error) { | ||
| return NextResponse.json({ error: access.error.message }, { status: access.error.status }) | ||
| } | ||
|
|
||
| const workflow = access.workflow! | ||
|
|
||
| let payload: any = {} | ||
| try { | ||
| payload = await request.json() | ||
| } catch { | ||
| payload = {} | ||
| } | ||
|
|
||
| const resumeInput = payload?.input ?? payload ?? {} | ||
| const userId = workflow.userId ?? '' | ||
|
|
||
| try { | ||
| const enqueueResult = await PauseResumeManager.enqueueOrStartResume({ | ||
| executionId, | ||
| contextId, | ||
| resumeInput, | ||
| userId, | ||
| }) | ||
|
|
||
| if (enqueueResult.status === 'queued') { | ||
| return NextResponse.json({ | ||
| status: 'queued', | ||
| executionId: enqueueResult.resumeExecutionId, | ||
| queuePosition: enqueueResult.queuePosition, | ||
| message: 'Resume queued. It will run after current resumes finish.', | ||
| }) | ||
| } | ||
|
|
||
| PauseResumeManager.startResumeExecution({ | ||
| resumeEntryId: enqueueResult.resumeEntryId, | ||
| resumeExecutionId: enqueueResult.resumeExecutionId, | ||
| pausedExecution: enqueueResult.pausedExecution, | ||
| contextId: enqueueResult.contextId, | ||
| resumeInput: enqueueResult.resumeInput, | ||
| userId: enqueueResult.userId, | ||
| }).catch((error) => { | ||
| logger.error('Failed to start resume execution', { | ||
| workflowId, | ||
| parentExecutionId: executionId, | ||
| resumeExecutionId: enqueueResult.resumeExecutionId, | ||
| error, | ||
| }) | ||
| }) | ||
|
|
||
| return NextResponse.json({ | ||
| status: 'started', | ||
| executionId: enqueueResult.resumeExecutionId, | ||
| message: 'Resume execution started.', | ||
| }) | ||
| } catch (error: any) { | ||
| logger.error('Resume request failed', { | ||
| workflowId, | ||
| executionId, | ||
| contextId, | ||
| error, | ||
| }) | ||
| return NextResponse.json( | ||
| { error: error.message || 'Failed to queue resume request' }, | ||
| { status: 400 } | ||
| ) | ||
| } | ||
| } | ||
|
|
||
| export async function GET( | ||
| request: NextRequest, | ||
| { | ||
| params, | ||
| }: { | ||
| params: Promise<{ workflowId: string; executionId: string; contextId: string }> | ||
| } | ||
| ) { | ||
| const { workflowId, executionId, contextId } = await params | ||
|
|
||
| const access = await validateWorkflowAccess(request, workflowId, false) | ||
| if (access.error) { | ||
| return NextResponse.json({ error: access.error.message }, { status: access.error.status }) | ||
| } | ||
|
|
||
| const detail = await PauseResumeManager.getPauseContextDetail({ | ||
| workflowId, | ||
| executionId, | ||
| contextId, | ||
| }) | ||
|
|
||
| if (!detail) { | ||
| return NextResponse.json({ error: 'Pause context not found' }, { status: 404 }) | ||
| } | ||
|
|
||
| return NextResponse.json(detail) | ||
| } | ||
48 changes: 48 additions & 0 deletions
48
apps/sim/app/api/resume/[workflowId]/[executionId]/route.ts
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,48 @@ | ||
| import { type NextRequest, NextResponse } from 'next/server' | ||
| import { createLogger } from '@/lib/logs/console/logger' | ||
| import { PauseResumeManager } from '@/lib/workflows/executor/pause-resume-manager' | ||
| import { validateWorkflowAccess } from '@/app/api/workflows/middleware' | ||
|
|
||
| const logger = createLogger('WorkflowResumeExecutionAPI') | ||
|
|
||
| export const runtime = 'nodejs' | ||
| export const dynamic = 'force-dynamic' | ||
|
|
||
| export async function GET( | ||
| request: NextRequest, | ||
| { | ||
| params, | ||
| }: { | ||
| params: Promise<{ workflowId: string; executionId: string }> | ||
| } | ||
| ) { | ||
| const { workflowId, executionId } = await params | ||
|
|
||
| const access = await validateWorkflowAccess(request, workflowId, false) | ||
| if (access.error) { | ||
| return NextResponse.json({ error: access.error.message }, { status: access.error.status }) | ||
| } | ||
|
|
||
| try { | ||
| const detail = await PauseResumeManager.getPausedExecutionDetail({ | ||
| workflowId, | ||
| executionId, | ||
| }) | ||
|
|
||
| if (!detail) { | ||
| return NextResponse.json({ error: 'Paused execution not found' }, { status: 404 }) | ||
| } | ||
|
|
||
| return NextResponse.json(detail) | ||
| } catch (error: any) { | ||
| logger.error('Failed to load paused execution detail', { | ||
| workflowId, | ||
| executionId, | ||
| error, | ||
| }) | ||
| return NextResponse.json( | ||
| { error: error?.message || 'Failed to load paused execution detail' }, | ||
| { status: 500 } | ||
| ) | ||
| } | ||
| } |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
34 changes: 34 additions & 0 deletions
34
apps/sim/app/api/workflows/[id]/paused/[executionId]/route.ts
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,34 @@ | ||
| import { type NextRequest, NextResponse } from 'next/server' | ||
| import { PauseResumeManager } from '@/lib/workflows/executor/pause-resume-manager' | ||
| import { validateWorkflowAccess } from '@/app/api/workflows/middleware' | ||
|
|
||
| export const runtime = 'nodejs' | ||
| export const dynamic = 'force-dynamic' | ||
|
|
||
| export async function GET( | ||
| request: NextRequest, | ||
| { | ||
| params, | ||
| }: { | ||
| params: { id: string; executionId: string } | ||
| } | ||
| ) { | ||
| const workflowId = params.id | ||
| const executionId = params.executionId | ||
|
|
||
| const access = await validateWorkflowAccess(request, workflowId, false) | ||
| if (access.error) { | ||
| return NextResponse.json({ error: access.error.message }, { status: access.error.status }) | ||
| } | ||
|
|
||
| const detail = await PauseResumeManager.getPausedExecutionDetail({ | ||
| workflowId, | ||
| executionId, | ||
| }) | ||
|
|
||
| if (!detail) { | ||
| return NextResponse.json({ error: 'Paused execution not found' }, { status: 404 }) | ||
| } | ||
|
|
||
| return NextResponse.json(detail) | ||
| } |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,31 @@ | ||
| import { type NextRequest, NextResponse } from 'next/server' | ||
| import { PauseResumeManager } from '@/lib/workflows/executor/pause-resume-manager' | ||
| import { validateWorkflowAccess } from '@/app/api/workflows/middleware' | ||
|
|
||
| export const runtime = 'nodejs' | ||
| export const dynamic = 'force-dynamic' | ||
|
|
||
| export async function GET( | ||
| request: NextRequest, | ||
| { | ||
| params, | ||
| }: { | ||
| params: { id: string } | ||
| } | ||
| ) { | ||
| const workflowId = params.id | ||
|
|
||
| const access = await validateWorkflowAccess(request, workflowId, false) | ||
| if (access.error) { | ||
| return NextResponse.json({ error: access.error.message }, { status: access.error.status }) | ||
| } | ||
|
|
||
| const statusFilter = request.nextUrl.searchParams.get('status') || undefined | ||
|
|
||
| const pausedExecutions = await PauseResumeManager.listPausedExecutions({ | ||
| workflowId, | ||
| status: statusFilter, | ||
| }) | ||
|
|
||
| return NextResponse.json({ pausedExecutions }) | ||
| } |
15 changes: 15 additions & 0 deletions
15
apps/sim/app/resume/[workflowId]/[executionId]/[contextId]/page.tsx
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,15 @@ | ||
| import { redirect } from 'next/navigation' | ||
|
|
||
| export const runtime = 'nodejs' | ||
| export const dynamic = 'force-dynamic' | ||
|
|
||
| interface PageParams { | ||
| workflowId: string | ||
| executionId: string | ||
| contextId: string | ||
| } | ||
|
|
||
| export default async function ResumePage({ params }: { params: Promise<PageParams> }) { | ||
| const { workflowId, executionId, contextId } = await params | ||
| redirect(`/resume/${workflowId}/${executionId}?contextId=${contextId}`) | ||
| } |
Oops, something went wrong.
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
Uh oh!
There was an error while loading. Please reload this page.