Replies: 1 comment
|
@pranaygp some feedback/things I would need from this.
|
0 replies
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Uh oh!
There was an error while loading. Please reload this page.
Uh oh!
There was an error while loading. Please reload this page.
Linked implementation PR: #2062
Summary
This RFC proposes an experimental dynamic workflow source MVP: allow
start()to accept a trusted JavaScript workflow source string, compile it into per-run workflow VM code, persist that code with the run, and execute/replay it without requiring the workflow function to exist in the build-time manifest.The main use case is AI-generated or UI-generated orchestration over step functions that the deployment has already registered.
Motivation
Today workflows must be discovered and bundled ahead of time. That is great for normal app code, but it blocks dynamic orchestration where the workflow shape is produced after deployment, for example:
This MVP keeps the execution model conservative: steps are still registered at build time, and dynamic source only decides how to orchestrate those steps.
Proposed MVP
start(source: string, args?: unknown[], options: DynamicStartOptions): Promise<Run<unknown>>.options.dynamic.stepsto map safe aliases to imported step functions with.stepId, or explicit{ stepId }references.workflow//dynamic/<source-hash>//<exportName>.import/export,async function <exportName>(...) { "use workflow"; ... },globalThis.__private_workflows.Preferred Source Storage Design
Dynamic source/code should be encrypted and ref-backed, not stored as plaintext run metadata.
Preferred model:
executionContext.dynamicWorkflow:version,sourceHash,exportName, generated workflow ID, and step aliases/step IDs.dynamicWorkflowCodeordynamicWorkflowSourceserialized data field torun_created.eventDataand the run entity.runWorkflow().This supports sensitive generated source and allows longer dynamic workflows without pushing DynamoDB item-size limits. The current implementation stores
workflowCodeinexecutionContext.dynamicWorkflowonly becauseexecutionContextis already opaque client-side metadata and avoids a world/server storage change. Before shipping this more broadly, source/code should move into the encrypted ref-backed field above.Predefined Runtime Globals
Dynamic workflow source does not use imports in this MVP. Instead, the generated workflow VM code predefines a small runtime surface before evaluating the source:
steps: a frozen object containing the step aliases passed throughdynamic.steps. Each alias is backed byWORKFLOW_USE_STEP(stepId).sleep: the Workflow SDK sleep primitive for durable waits and timers.createHook: the Workflow SDK hook primitive for durable external resume signals.The source also runs inside the normal deterministic workflow VM, so standard sandbox globals such as
Date,Math.random,crypto,URL,URLSearchParams,TextEncoder,TextDecoder,structuredClone,atob, andbtoaare available with the same determinism constraints as static workflows.For the MVP,
createWebhookandgetWritableare not predefined in dynamic source.Example with steps, a timer, and a hook:
Step Exposure and Safety Model
stepsis injected as a lexical capability object inside the generated VM code. It is frozen and only includes aliases passed throughdynamic.steps, so normal generated code that callssteps.notAllowed()fails the run instead of dispatching an arbitrary step.This is an allowlist convenience, not a hard malicious-code sandbox. Dynamic source is still treated as trusted application code in this MVP. A stronger version should gate the underlying dynamic step primitive so only allowed step IDs can be materialized even if source attempts to reach private VM symbols directly.
Longer-term we may still consider virtual imports like
workflow:steps, but the MVP API should stay with the predefined runtime bindings above.Observability Plan
Dynamic runs should show the code that actually executed from the run detail view.
MVP observability plan:
Dynamic workflowsection for runs whoseexecutionContext.dynamicWorkflow.version === 1.With encrypted source refs, observability should follow the existing encrypted-field UX: show a locked placeholder by default and reveal the source only after the user chooses to decrypt.
AI / LLM Usage Pattern
Applications should provide the model with an explicit step catalog and require it to generate only one workflow function. The generated source should be reviewed, validated, or constrained by the application before calling
start().Limitations
"use step"functions.Open Questions
start()?workflow//dynamic/<source-hash>//<exportName>the right durable workflow ID shape for queue names, filtering, and observability?All reactions