Skip to content

Conversation

@TooTallNate
Copy link
Member

@TooTallNate TooTallNate commented Jan 13, 2026

// Using with a token string (existing behavior)
await resumeHook("some-token-string", payload);

// Using with a Hook object (new behavior)
const hook = await getHookByToken("some-token");
await resumeHook(hook, payload);

Why make this change?

Optimization for resumeWebhook().

This change improves efficiency in cases where the caller already has the Hook object, eliminating the need to perform an additional database lookup by token. It maintains backward compatibility while providing a more flexible API.

@changeset-bot
Copy link

changeset-bot bot commented Jan 13, 2026

🦋 Changeset detected

Latest commit: 0551fe8

The changes in this PR will be included in the next version bump.

This PR includes changesets to release 13 packages
Name Type
@workflow/core Patch
@workflow/builders Patch
@workflow/cli Patch
@workflow/docs-typecheck Patch
@workflow/next Patch
@workflow/nitro Patch
@workflow/web-shared Patch
workflow Patch
@workflow/astro Patch
@workflow/sveltekit Patch
@workflow/world-testing Patch
@workflow/nuxt Patch
@workflow/ai Patch

Not sure what this means? Click here to learn what changesets are.

Click here if you're a maintainer who wants to add another changeset to this PR

@vercel
Copy link
Contributor

vercel bot commented Jan 13, 2026

The latest updates on your projects. Learn more about Vercel for GitHub.

Project Deployment Review Updated (UTC)
example-nextjs-workflow-turbopack Ready Ready Preview, Comment Jan 13, 2026 1:43am
example-nextjs-workflow-webpack Ready Ready Preview, Comment Jan 13, 2026 1:43am
example-workflow Ready Ready Preview, Comment Jan 13, 2026 1:43am
workbench-astro-workflow Ready Ready Preview, Comment Jan 13, 2026 1:43am
workbench-express-workflow Ready Ready Preview, Comment Jan 13, 2026 1:43am
workbench-fastify-workflow Ready Ready Preview, Comment Jan 13, 2026 1:43am
workbench-hono-workflow Ready Ready Preview, Comment Jan 13, 2026 1:43am
workbench-nitro-workflow Ready Ready Preview, Comment Jan 13, 2026 1:43am
workbench-nuxt-workflow Ready Ready Preview, Comment Jan 13, 2026 1:43am
workbench-sveltekit-workflow Ready Ready Preview, Comment Jan 13, 2026 1:43am
workbench-vite-workflow Ready Ready Preview, Comment Jan 13, 2026 1:43am
workflow-docs Ready Ready Preview, Comment Jan 13, 2026 1:43am

@github-actions
Copy link
Contributor

github-actions bot commented Jan 13, 2026

📊 Benchmark Results

📈 Comparing against baseline from main branch. Green 🟢 = faster, Red 🔺 = slower.

workflow with no steps

💻 Local Development

World Framework Workflow Time Wall Time Overhead Samples vs Fastest
💻 Local 🥇 Express 0.032s (-33.3% 🟢) 1.007s (~) 0.975s 10 1.00x
💻 Local Next.js (Turbopack) 0.036s (-7.5% 🟢) 1.016s (~) 0.980s 10 1.12x
🌐 Starter Next.js (Turbopack) 0.039s (+10.1% 🔺) 1.014s (~) 0.975s 10 1.22x
🌐 Redis Next.js (Turbopack) 0.041s (~) 1.018s (~) 0.977s 10 1.27x
💻 Local Nitro 0.042s (~) 1.006s (~) 0.964s 10 1.30x
🌐 MongoDB Next.js (Turbopack) 0.053s (-32.4% 🟢) 1.016s (~) 0.963s 10 1.66x
🌐 Turso Next.js (Turbopack) 0.078s (-27.3% 🟢) 1.014s (~) 0.936s 10 2.44x
🐘 Postgres Nitro 0.295s (+20.2% 🔺) 1.012s (-0.7%) 0.718s 10 9.18x
🐘 Postgres Express 0.422s (+26.0% 🔺) 1.013s (~) 0.591s 10 13.15x
🐘 Postgres Next.js (Turbopack) 0.429s (+173.4% 🔺) 1.039s (+2.0%) 0.610s 10 13.36x

▲ Production (Vercel)

World Framework Workflow Time Wall Time Overhead Samples vs Fastest
▲ Vercel 🥇 Next.js (Turbopack) 0.586s (-57.4% 🟢) 1.467s (-44.8% 🟢) 0.881s 10 1.00x
▲ Vercel Express 0.613s (-62.1% 🟢) 1.644s (-35.0% 🟢) 1.031s 10 1.05x
▲ Vercel Nitro 0.620s (-5.7% 🟢) 1.616s (+4.6%) 0.996s 10 1.06x

🔍 Observability: Next.js (Turbopack) | Express | Nitro

workflow with 1 step

💻 Local Development

World Framework Workflow Time Wall Time Overhead Samples vs Fastest
💻 Local 🥇 Express 1.078s (-3.5%) 2.007s (~) 0.929s 10 1.00x
💻 Local Next.js (Turbopack) 1.090s (~) 2.013s (~) 0.924s 10 1.01x
🌐 Starter Next.js (Turbopack) 1.091s (+0.8%) 2.009s (~) 0.918s 10 1.01x
🌐 Redis Next.js (Turbopack) 1.096s (~) 2.012s (~) 0.916s 10 1.02x
💻 Local Nitro 1.111s (~) 2.005s (~) 0.894s 10 1.03x
🌐 Turso Next.js (Turbopack) 1.263s (-3.3%) 2.012s (~) 0.749s 10 1.17x
🌐 MongoDB Next.js (Turbopack) 1.313s (+5.4% 🔺) 2.018s (~) 0.706s 10 1.22x
🐘 Postgres Next.js (Turbopack) 1.763s (-27.2% 🟢) 2.015s (-33.2% 🟢) 0.251s 10 1.64x
🐘 Postgres Nitro 2.150s (-6.6% 🟢) 3.013s (~) 0.864s 10 1.99x
🐘 Postgres Express 2.284s (+4.7%) 3.012s (~) 0.729s 10 2.12x

▲ Production (Vercel)

World Framework Workflow Time Wall Time Overhead Samples vs Fastest
▲ Vercel 🥇 Express 2.755s (-15.1% 🟢) 3.803s (-10.5% 🟢) 1.048s 10 1.00x
▲ Vercel Next.js (Turbopack) 2.796s (-20.6% 🟢) 3.611s (-18.3% 🟢) 0.814s 10 1.02x
▲ Vercel Nitro 2.983s (-36.4% 🟢) 3.935s (-26.8% 🟢) 0.952s 10 1.08x

🔍 Observability: Express | Next.js (Turbopack) | Nitro

workflow with 10 sequential steps

💻 Local Development

World Framework Workflow Time Wall Time Overhead Samples vs Fastest
💻 Local 🥇 Express 10.529s (-2.6%) 11.012s (~) 0.483s 5 1.00x
💻 Local Next.js (Turbopack) 10.568s (-0.6%) 11.022s (~) 0.454s 5 1.00x
🌐 Starter Next.js (Turbopack) 10.578s (~) 11.010s (~) 0.432s 5 1.00x
🌐 Redis Next.js (Turbopack) 10.687s (~) 11.014s (~) 0.327s 5 1.02x
💻 Local Nitro 10.783s (~) 11.009s (~) 0.227s 5 1.02x
🌐 Turso Next.js (Turbopack) 12.166s (~) 13.023s (~) 0.857s 5 1.16x
🌐 MongoDB Next.js (Turbopack) 12.288s (+1.4%) 13.028s (+1.6%) 0.740s 5 1.17x
🐘 Postgres Next.js (Turbopack) 15.110s (-25.5% 🟢) 16.043s (-23.7% 🟢) 0.932s 5 1.44x
🐘 Postgres Express 18.622s (-7.9% 🟢) 19.435s (-6.7% 🟢) 0.813s 5 1.77x
🐘 Postgres Nitro 20.434s (~) 21.032s (~) 0.597s 5 1.94x

▲ Production (Vercel)

World Framework Workflow Time Wall Time Overhead Samples vs Fastest
▲ Vercel 🥇 Next.js (Turbopack) 22.467s (-0.6%) 23.369s (-1.4%) 0.902s 5 1.00x
▲ Vercel Express 22.701s (+0.7%) 23.416s (-0.5%) 0.715s 5 1.01x
▲ Vercel Nitro 23.211s (+2.6%) 24.014s (+3.5%) 0.803s 5 1.03x

🔍 Observability: Next.js (Turbopack) | Express | Nitro

Promise.all with 10 concurrent steps

💻 Local Development

World Framework Workflow Time Wall Time Overhead Samples vs Fastest
💻 Local 🥇 Express 1.340s (-4.9%) 2.006s (~) 0.666s 15 1.00x
🌐 Starter Next.js (Turbopack) 1.341s (~) 2.008s (~) 0.667s 15 1.00x
🌐 Redis Next.js (Turbopack) 1.351s (~) 2.010s (~) 0.659s 15 1.01x
💻 Local Next.js (Turbopack) 1.375s (~) 2.014s (~) 0.639s 15 1.03x
💻 Local Nitro 1.418s (~) 2.005s (~) 0.587s 15 1.06x
🐘 Postgres Next.js (Turbopack) 1.827s (-15.6% 🟢) 2.015s (-16.1% 🟢) 0.188s 15 1.36x
🐘 Postgres Express 1.907s (-19.9% 🟢) 2.077s (-31.1% 🟢) 0.170s 15 1.42x
🌐 MongoDB Next.js (Turbopack) 2.135s (+0.6%) 3.013s (~) 0.878s 10 1.59x
🌐 Turso Next.js (Turbopack) 2.212s (~) 3.012s (~) 0.800s 10 1.65x
🐘 Postgres Nitro 2.468s (+2.3%) 3.012s (~) 0.543s 10 1.84x

▲ Production (Vercel)

World Framework Workflow Time Wall Time Overhead Samples vs Fastest
▲ Vercel 🥇 Nitro 2.769s (-2.2%) 3.847s (+7.4% 🔺) 1.077s 8 1.00x
▲ Vercel Next.js (Turbopack) 2.924s (+5.4% 🔺) 3.806s (+0.7%) 0.882s 8 1.06x
▲ Vercel Express 2.962s (+7.3% 🔺) 3.901s (+4.0%) 0.939s 8 1.07x

🔍 Observability: Nitro | Next.js (Turbopack) | Express

Promise.all with 25 concurrent steps

💻 Local Development

World Framework Workflow Time Wall Time Overhead Samples vs Fastest
💻 Local 🥇 Express 1.996s (-8.7% 🟢) 2.301s (-26.3% 🟢) 0.306s 14 1.00x
💻 Local Next.js (Turbopack) 2.095s (+3.2%) 2.757s (-4.0%) 0.663s 12 1.05x
💻 Local Nitro 2.181s (-0.8%) 3.138s (-0.9%) 0.958s 10 1.09x
🌐 Starter Next.js (Turbopack) 2.454s (~) 3.009s (~) 0.554s 10 1.23x
🌐 Redis Next.js (Turbopack) 2.474s (-1.2%) 3.011s (~) 0.538s 10 1.24x
🐘 Postgres Next.js (Turbopack) 2.766s (-3.0%) 3.036s (+0.5%) 0.270s 10 1.39x
🐘 Postgres Express 2.854s (+3.5%) 3.012s (~) 0.158s 10 1.43x
🐘 Postgres Nitro 2.923s (-5.8% 🟢) 3.111s (-10.6% 🟢) 0.188s 10 1.46x
🌐 MongoDB Next.js (Turbopack) 4.700s (-1.0%) 5.184s (~) 0.484s 6 2.35x
🌐 Turso Next.js (Turbopack) 4.702s (~) 5.180s (~) 0.478s 6 2.36x

▲ Production (Vercel)

World Framework Workflow Time Wall Time Overhead Samples vs Fastest
▲ Vercel 🥇 Nitro 3.224s (-11.7% 🟢) 3.819s (-8.1% 🟢) 0.595s 8 1.00x
▲ Vercel Next.js (Turbopack) 3.804s (+11.2% 🔺) 4.344s (+6.8% 🔺) 0.541s 8 1.18x
▲ Vercel Express 4.294s (+38.5% 🔺) 5.026s (+28.8% 🔺) 0.733s 7 1.33x

🔍 Observability: Nitro | Next.js (Turbopack) | Express

Promise.race with 10 concurrent steps

💻 Local Development

World Framework Workflow Time Wall Time Overhead Samples vs Fastest
🌐 Starter 🥇 Next.js (Turbopack) 1.338s (-1.5%) 2.007s (~) 0.669s 15 1.00x
💻 Local Express 1.343s (-5.6% 🟢) 2.005s (~) 0.663s 15 1.00x
🌐 Redis Next.js (Turbopack) 1.355s (-2.1%) 2.010s (~) 0.655s 15 1.01x
💻 Local Next.js (Turbopack) 1.384s (-0.9%) 2.017s (~) 0.632s 15 1.03x
💻 Local Nitro 1.401s (-1.4%) 2.005s (~) 0.604s 15 1.05x
🐘 Postgres Express 1.569s (-17.0% 🟢) 2.010s (~) 0.441s 15 1.17x
🐘 Postgres Next.js (Turbopack) 1.619s (-2.8%) 2.013s (~) 0.393s 15 1.21x
🐘 Postgres Nitro 1.888s (-5.0%) 2.083s (-15.8% 🟢) 0.195s 15 1.41x
🌐 MongoDB Next.js (Turbopack) 2.128s (~) 3.014s (~) 0.886s 10 1.59x
🌐 Turso Next.js (Turbopack) 2.227s (+1.4%) 3.014s (~) 0.788s 10 1.66x

▲ Production (Vercel)

World Framework Workflow Time Wall Time Overhead Samples vs Fastest
▲ Vercel 🥇 Next.js (Turbopack) 2.805s (+3.0%) 3.625s (-4.0%) 0.820s 9 1.00x
▲ Vercel Express 2.888s (+6.2% 🔺) 3.785s (~) 0.897s 8 1.03x
▲ Vercel Nitro 2.990s (+7.9% 🔺) 3.794s (+5.2% 🔺) 0.804s 8 1.07x

🔍 Observability: Next.js (Turbopack) | Express | Nitro

Promise.race with 25 concurrent steps

💻 Local Development

World Framework Workflow Time Wall Time Overhead Samples vs Fastest
💻 Local 🥇 Express 1.987s (-13.1% 🟢) 2.327s (-27.8% 🟢) 0.340s 13 1.00x
💻 Local Nitro 2.187s (-1.8%) 3.116s (-1.3%) 0.929s 10 1.10x
💻 Local Next.js (Turbopack) 2.194s (~) 3.011s (-3.4%) 0.817s 10 1.10x
🌐 Starter Next.js (Turbopack) 2.454s (~) 3.010s (~) 0.556s 10 1.23x
🌐 Redis Next.js (Turbopack) 2.473s (-0.8%) 3.010s (~) 0.536s 10 1.24x
🐘 Postgres Express 2.497s (+2.1%) 3.017s (~) 0.519s 10 1.26x
🐘 Postgres Next.js (Turbopack) 2.659s (+7.5% 🔺) 3.035s (+0.6%) 0.377s 10 1.34x
🐘 Postgres Nitro 2.701s (-7.7% 🟢) 3.016s (-13.3% 🟢) 0.315s 10 1.36x
🌐 MongoDB Next.js (Turbopack) 4.652s (-2.5%) 5.185s (~) 0.532s 6 2.34x
🌐 Turso Next.js (Turbopack) 4.739s (+2.2%) 5.183s (~) 0.444s 6 2.39x

▲ Production (Vercel)

World Framework Workflow Time Wall Time Overhead Samples vs Fastest
▲ Vercel 🥇 Nitro 3.108s (-2.5%) 3.884s (+7.7% 🔺) 0.776s 8 1.00x
▲ Vercel Next.js (Turbopack) 3.144s (-8.5% 🟢) 3.840s (-8.5% 🟢) 0.696s 8 1.01x
▲ Vercel Express 3.282s (-15.5% 🟢) 3.904s (-15.1% 🟢) 0.623s 8 1.06x

🔍 Observability: Nitro | Next.js (Turbopack) | Express

Stream Benchmarks (includes TTFB metrics)
workflow with stream

💻 Local Development

World Framework Workflow Time TTFB Slurp Wall Time Overhead Samples vs Fastest
💻 Local 🥇 Express 0.114s (-38.6% 🟢) 0.999s (+0.7%) 0.015s (+2.7%) 1.022s (~) 0.907s 10 1.00x
💻 Local Next.js (Turbopack) 0.120s (-11.2% 🟢) 1.004s (~) 0.022s (+40.3% 🔺) 1.035s (+0.7%) 0.915s 10 1.05x
🌐 Starter Next.js (Turbopack) 0.123s (-2.5%) 1.006s (~) 0.000s (+Infinity% 🔺) 1.012s (~) 0.889s 10 1.07x
🌐 Redis Next.js (Turbopack) 0.146s (~) 1.005s (~) 0.000s (NaN%) 1.014s (~) 0.868s 10 1.27x
💻 Local Nitro 0.172s (-2.8%) 0.992s (~) 0.014s (-20.6% 🟢) 1.020s (~) 0.847s 10 1.51x
🌐 Turso Next.js (Turbopack) 0.509s (+8.2% 🔺) 0.939s (-4.1%) 0.000s (-100.0% 🟢) 1.013s (~) 0.504s 10 4.45x
🌐 MongoDB Next.js (Turbopack) 0.514s (+9.8% 🔺) 0.941s (-3.6%) 0.000s (-100.0% 🟢) 1.015s (~) 0.501s 10 4.49x
🐘 Postgres Next.js (Turbopack) 1.373s (-1.0%) 1.674s (-21.3% 🟢) 0.000s (-100.0% 🟢) 2.020s (-8.9% 🟢) 0.647s 10 12.00x
🐘 Postgres Express 1.452s (+6.1% 🔺) 1.667s (-3.2%) 0.000s (-100.0% 🟢) 2.015s (~) 0.563s 10 12.69x
🐘 Postgres Nitro 2.380s (+7.5% 🔺) 2.662s (-5.9% 🟢) 0.000s (-100.0% 🟢) 3.014s (~) 0.634s 10 20.80x

▲ Production (Vercel)

World Framework Workflow Time TTFB Slurp Wall Time Overhead Samples vs Fastest
▲ Vercel 🥇 Next.js (Turbopack) 2.761s (-9.3% 🟢) 3.332s (+0.7%) 0.239s (-59.3% 🟢) 3.992s (-9.1% 🟢) 1.231s 10 1.00x
▲ Vercel Express 2.827s (~) 3.333s (+2.4%) 0.410s (-17.7% 🟢) 4.302s (+1.4%) 1.475s 10 1.02x
▲ Vercel Nitro 2.887s (+5.0% 🔺) 3.307s (+3.5%) 0.424s (+29.6% 🔺) 4.276s (+8.4% 🔺) 1.390s 10 1.05x

🔍 Observability: Next.js (Turbopack) | Express | Nitro

Summary

Fastest Framework by World

Winner determined by most benchmark wins

World 🥇 Fastest Framework Wins
💻 Local Express 8/8
🐘 Postgres Next.js (Turbopack) 5/8
▲ Vercel Next.js (Turbopack) 4/8
Fastest World by Framework

Winner determined by most benchmark wins

Framework 🥇 Fastest World Wins
Express 💻 Local 8/8
Next.js (Turbopack) 💻 Local 6/8
Nitro 💻 Local 8/8
Column Definitions
  • Workflow Time: Runtime reported by workflow (completedAt - createdAt) - primary metric
  • TTFB: Time to First Byte - time from workflow start until first stream byte received (stream benchmarks only)
  • Slurp: Time from first byte to complete stream consumption (stream benchmarks only)
  • Wall Time: Total testbench time (trigger workflow + poll for result)
  • Overhead: Testbench overhead (Wall Time - Workflow Time)
  • Samples: Number of benchmark iterations run
  • vs Fastest: How much slower compared to the fastest configuration for this benchmark

Worlds:

  • 💻 Local: In-memory filesystem world (local development)
  • 🐘 Postgres: PostgreSQL database world (local development)
  • ▲ Vercel: Vercel production/preview deployment
  • 🌐 Starter: Community world (local development)
  • 🌐 Turso: Community world (local development)
  • 🌐 MongoDB: Community world (local development)
  • 🌐 Redis: Community world (local development)
  • 🌐 Jazz: Community world (local development)

📋 View full workflow run

@github-actions
Copy link
Contributor

github-actions bot commented Jan 13, 2026

🧪 E2E Test Results

Some tests failed

Summary

Passed Failed Skipped Total
✅ ▲ Vercel Production 374 0 11 385
✅ 💻 Local Development 342 0 8 350
✅ 📦 Local Production 342 0 8 350
✅ 🐘 Local Postgres 342 0 8 350
✅ 🪟 Windows 35 0 0 35
❌ 🌍 Community Worlds 135 17 0 152
Total 1570 17 35 1622

❌ Failed Tests

🌍 Community Worlds (17 failed)

mongodb (1 failed):

  • webhookWorkflow

redis (1 failed):

  • webhookWorkflow

starter (14 failed):

  • addTenWorkflow
  • addTenWorkflow
  • error handling error propagation workflow errors nested function calls preserve message and stack trace
  • error handling error propagation workflow errors cross-file imports preserve message and stack trace
  • error handling error propagation step errors basic step error preserves message and stack trace
  • error handling error propagation step errors cross-file step error preserves message and function names in stack
  • error handling retry behavior regular Error retries until success
  • error handling retry behavior FatalError fails immediately without retries
  • error handling catchability FatalError can be caught and detected with FatalError.is()
  • hookCleanupTestWorkflow - hook token reuse after workflow completion
  • stepFunctionPassingWorkflow - step function references can be passed as arguments (without closure vars)
  • stepFunctionWithClosureWorkflow - step function with closure variables passed as argument
  • spawnWorkflowFromStepWorkflow - spawning a child workflow using start() inside a step
  • pathsAliasWorkflow - TypeScript path aliases resolve correctly

turso (1 failed):

  • webhookWorkflow

Details by Category

✅ ▲ Vercel Production
App Passed Failed Skipped
✅ astro 34 0 1
✅ example 34 0 1
✅ express 34 0 1
✅ fastify 34 0 1
✅ hono 34 0 1
✅ nextjs-turbopack 34 0 1
✅ nextjs-webpack 34 0 1
✅ nitro 34 0 1
✅ nuxt 34 0 1
✅ sveltekit 34 0 1
✅ vite 34 0 1
✅ 💻 Local Development
App Passed Failed Skipped
✅ astro-stable 34 0 1
✅ express-stable 34 0 1
✅ fastify-stable 34 0 1
✅ hono-stable 34 0 1
✅ nextjs-turbopack-stable 35 0 0
✅ nextjs-webpack-stable 35 0 0
✅ nitro-stable 34 0 1
✅ nuxt-stable 34 0 1
✅ sveltekit-stable 34 0 1
✅ vite-stable 34 0 1
✅ 📦 Local Production
App Passed Failed Skipped
✅ astro-stable 34 0 1
✅ express-stable 34 0 1
✅ fastify-stable 34 0 1
✅ hono-stable 34 0 1
✅ nextjs-turbopack-stable 35 0 0
✅ nextjs-webpack-stable 35 0 0
✅ nitro-stable 34 0 1
✅ nuxt-stable 34 0 1
✅ sveltekit-stable 34 0 1
✅ vite-stable 34 0 1
✅ 🐘 Local Postgres
App Passed Failed Skipped
✅ astro-stable 34 0 1
✅ express-stable 34 0 1
✅ fastify-stable 34 0 1
✅ hono-stable 34 0 1
✅ nextjs-turbopack-stable 35 0 0
✅ nextjs-webpack-stable 35 0 0
✅ nitro-stable 34 0 1
✅ nuxt-stable 34 0 1
✅ sveltekit-stable 34 0 1
✅ vite-stable 34 0 1
✅ 🪟 Windows
App Passed Failed Skipped
✅ nextjs-turbopack 35 0 0
❌ 🌍 Community Worlds
App Passed Failed Skipped
✅ mongodb-dev 3 0 0
❌ mongodb 34 1 0
✅ redis-dev 3 0 0
❌ redis 34 1 0
✅ starter-dev 3 0 0
❌ starter 21 14 0
✅ turso-dev 3 0 0
❌ turso 34 1 0

📋 View full workflow run

Copy link
Member Author

This stack of pull requests is managed by Graphite. Learn more about stacking.

Copy link
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

This pull request enhances the resumeHook() function to accept either a token string (existing behavior) or a Hook object directly (new behavior), providing an optimization for resumeWebhook() by eliminating an unnecessary database lookup when the Hook object is already available.

Changes:

  • Modified resumeHook() parameter from string to string | Hook with conditional logic to handle both types
  • Updated resumeWebhook() to pass the Hook object directly instead of its token
  • Updated JSDoc parameter documentation to reflect the new signature

Reviewed changes

Copilot reviewed 2 out of 2 changed files in this pull request and generated 3 comments.

File Description
packages/core/src/runtime/resume-hook.ts Modified resumeHook signature to accept Hook objects, added type checking logic, and updated resumeWebhook to utilize the optimization
.changeset/new-crabs-hope.md Added changeset documenting the patch-level API enhancement

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

const hook =
typeof tokenOrHook === 'string'
? await getHookByToken(tokenOrHook)
: tokenOrHook;
Copy link

Copilot AI Jan 13, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

When a Hook object is passed directly to resumeHook, it bypasses the metadata hydration logic that exists in getHookByToken(). The getHookByToken function hydrates the metadata property using hydrateStepArguments if it was set from within the workflow run. This could lead to bugs when the hook's metadata is used elsewhere in the workflow execution, as it would remain in its serialized/dehydrated form rather than being properly deserialized. Consider either: 1) documenting that callers must ensure the Hook object has already been processed through getHookByToken, or 2) adding metadata hydration logic here to handle Hook objects that haven't been hydrated yet.

Suggested change
: tokenOrHook;
: (() => {
const directHook = tokenOrHook;
if (typeof directHook.metadata !== 'undefined') {
directHook.metadata = hydrateStepArguments(
directHook.metadata as any,
[],
directHook.runId
);
}
return directHook;
})();

Copilot uses AI. Check for mistakes.
Comment on lines 59 to +71
export async function resumeHook<T = any>(
token: string,
tokenOrHook: string | Hook,
payload: T
): Promise<Hook> {
return await waitedUntil(() => {
return trace('HOOK.resume', async (span) => {
const world = getWorld();

try {
const hook = await getHookByToken(token);
const hook =
typeof tokenOrHook === 'string'
? await getHookByToken(tokenOrHook)
: tokenOrHook;
Copy link

Copilot AI Jan 13, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The new functionality allowing resumeHook to accept a Hook object lacks test coverage. Given that the codebase has comprehensive test coverage for similar runtime functions (e.g., start.test.ts), tests should be added to verify: 1) that resumeHook correctly handles Hook objects, 2) that the hook's token is properly extracted for telemetry attributes, and 3) that the optimization in resumeWebhook works as expected. This is especially important because of the metadata hydration concern.

Copilot uses AI. Check for mistakes.
Comment on lines +68 to +71
const hook =
typeof tokenOrHook === 'string'
? await getHookByToken(tokenOrHook)
: tokenOrHook;
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
const hook =
typeof tokenOrHook === 'string'
? await getHookByToken(tokenOrHook)
: tokenOrHook;
let hook: Hook;
if (typeof tokenOrHook === 'string') {
hook = await getHookByToken(tokenOrHook);
} else {
hook = tokenOrHook;
// Hydrate the metadata if it was set from within the workflow run
// (same as getHookByToken does for consistency)
if (typeof hook.metadata !== 'undefined') {
hook.metadata = hydrateStepArguments(hook.metadata as any, [], hook.runId);
}
}

When a Hook object is passed directly to resumeHook(), its metadata is not hydrated via hydrateStepArguments() like it is when a token string is passed, causing inconsistent behavior.

Fix on Vercel

Copy link
Collaborator

@pranaygp pranaygp left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@pranaygp approved this PR from Slack with Graphite

@TooTallNate TooTallNate merged commit 3dd5b27 into main Jan 13, 2026
152 of 154 checks passed
@TooTallNate TooTallNate deleted the 01-12-make_resumehook_accept_a_hook_object_or_string branch January 13, 2026 21:29
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants