zilmate 1.8.0 → 1.8.5
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/.agents/skills/copywriting/SKILL.md +252 -0
- package/.agents/skills/copywriting/evals/evals.json +111 -0
- package/.agents/skills/copywriting/references/copy-frameworks.md +344 -0
- package/.agents/skills/copywriting/references/natural-transitions.md +272 -0
- package/.agents/skills/firecrawl-deep-research/SKILL.md +108 -0
- package/.agents/skills/shadcn/SKILL.md +267 -0
- package/.agents/skills/shadcn/agents/openai.yml +5 -0
- package/.agents/skills/shadcn/assets/shadcn-small.png +0 -0
- package/.agents/skills/shadcn/assets/shadcn.png +0 -0
- package/.agents/skills/shadcn/cli.md +290 -0
- package/.agents/skills/shadcn/customization.md +209 -0
- package/.agents/skills/shadcn/evals/evals.json +47 -0
- package/.agents/skills/shadcn/mcp.md +105 -0
- package/.agents/skills/shadcn/registry.md +277 -0
- package/.agents/skills/shadcn/rules/base-vs-radix.md +306 -0
- package/.agents/skills/shadcn/rules/composition.md +195 -0
- package/.agents/skills/shadcn/rules/forms.md +192 -0
- package/.agents/skills/shadcn/rules/icons.md +101 -0
- package/.agents/skills/shadcn/rules/styling.md +162 -0
- package/.agents/skills/tavily-research/SKILL.md +100 -0
- package/.agents/skills/upstash/SKILL.md +48 -0
- package/.agents/skills/upstash/upstash-box-js/overview.md +243 -0
- package/.agents/skills/upstash/upstash-box-py/overview.md +275 -0
- package/.agents/skills/upstash/upstash-cli/overview.md +138 -0
- package/.agents/skills/upstash/upstash-qstash-js/advanced/callbacks.md +147 -0
- package/.agents/skills/upstash/upstash-qstash-js/advanced/deduplication.md +86 -0
- package/.agents/skills/upstash/upstash-qstash-js/advanced/dlq.md +164 -0
- package/.agents/skills/upstash/upstash-qstash-js/advanced/multi-region/summary.md +388 -0
- package/.agents/skills/upstash/upstash-qstash-js/advanced/multi-region/verify-multi-region-setup.ts +388 -0
- package/.agents/skills/upstash/upstash-qstash-js/fundamentals/local-development.md +106 -0
- package/.agents/skills/upstash/upstash-qstash-js/fundamentals/publishing-messages.md +144 -0
- package/.agents/skills/upstash/upstash-qstash-js/fundamentals/queues-and-flow-control.md +148 -0
- package/.agents/skills/upstash/upstash-qstash-js/fundamentals/schedules.md +177 -0
- package/.agents/skills/upstash/upstash-qstash-js/fundamentals/url-groups.md +127 -0
- package/.agents/skills/upstash/upstash-qstash-js/overview.md +81 -0
- package/.agents/skills/upstash/upstash-qstash-js/verification/platform-specific/nextjs.md +171 -0
- package/.agents/skills/upstash/upstash-qstash-js/verification/receiver.md +213 -0
- package/.agents/skills/upstash/upstash-ratelimit-js/algorithms.md +84 -0
- package/.agents/skills/upstash/upstash-ratelimit-js/features.md +117 -0
- package/.agents/skills/upstash/upstash-ratelimit-js/methods-getting-started.md +77 -0
- package/.agents/skills/upstash/upstash-ratelimit-js/overview.md +26 -0
- package/.agents/skills/upstash/upstash-ratelimit-js/pricing-cost.md +146 -0
- package/.agents/skills/upstash/upstash-ratelimit-js/traffic-protection.md +77 -0
- package/.agents/skills/upstash/upstash-redis-js/advanced-features/auto-pipeline.md +49 -0
- package/.agents/skills/upstash/upstash-redis-js/advanced-features/pipeline-and-transactions.md +42 -0
- package/.agents/skills/upstash/upstash-redis-js/advanced-features/scripting.md +124 -0
- package/.agents/skills/upstash/upstash-redis-js/data-structures/hashes.md +71 -0
- package/.agents/skills/upstash/upstash-redis-js/data-structures/json.md +133 -0
- package/.agents/skills/upstash/upstash-redis-js/data-structures/lists.md +72 -0
- package/.agents/skills/upstash/upstash-redis-js/data-structures/sets.md +90 -0
- package/.agents/skills/upstash/upstash-redis-js/data-structures/sorted-sets.md +126 -0
- package/.agents/skills/upstash/upstash-redis-js/data-structures/streams.md +196 -0
- package/.agents/skills/upstash/upstash-redis-js/data-structures/strings.md +73 -0
- package/.agents/skills/upstash/upstash-redis-js/migrations/from-ioredis.md +163 -0
- package/.agents/skills/upstash/upstash-redis-js/migrations/from-redis-node.md +205 -0
- package/.agents/skills/upstash/upstash-redis-js/overview.md +183 -0
- package/.agents/skills/upstash/upstash-redis-js/patterns/caching.md +58 -0
- package/.agents/skills/upstash/upstash-redis-js/patterns/distributed-locks.md +130 -0
- package/.agents/skills/upstash/upstash-redis-js/patterns/leaderboard.md +134 -0
- package/.agents/skills/upstash/upstash-redis-js/patterns/rate-limiting.md +187 -0
- package/.agents/skills/upstash/upstash-redis-js/patterns/session-management.md +217 -0
- package/.agents/skills/upstash/upstash-redis-js/performance/batching-operations.md +76 -0
- package/.agents/skills/upstash/upstash-redis-js/performance/data-serialization.md +134 -0
- package/.agents/skills/upstash/upstash-redis-js/performance/error-handling.md +118 -0
- package/.agents/skills/upstash/upstash-redis-js/performance/pipeline-optimization.md +105 -0
- package/.agents/skills/upstash/upstash-redis-js/performance/redis-replicas.md +14 -0
- package/.agents/skills/upstash/upstash-redis-js/performance/ttl-expiration.md +32 -0
- package/.agents/skills/upstash/upstash-redis-js/search/adapters.md +99 -0
- package/.agents/skills/upstash/upstash-redis-js/search/commands/aggregating.md +234 -0
- package/.agents/skills/upstash/upstash-redis-js/search/commands/aliases.md +76 -0
- package/.agents/skills/upstash/upstash-redis-js/search/commands/index-management.md +124 -0
- package/.agents/skills/upstash/upstash-redis-js/search/commands/querying.md +315 -0
- package/.agents/skills/upstash/upstash-redis-js/search/overview.md +155 -0
- package/.agents/skills/upstash/upstash-redis-start/overview.md +71 -0
- package/.agents/skills/upstash/upstash-search-js/overview.md +48 -0
- package/.agents/skills/upstash/upstash-search-js/quick-start.md +158 -0
- package/.agents/skills/upstash/upstash-search-js/sdk-overview.md +158 -0
- package/.agents/skills/upstash/upstash-vector-js/features/filtering-and-metadata.md +82 -0
- package/.agents/skills/upstash/upstash-vector-js/features/index-structure.md +193 -0
- package/.agents/skills/upstash/upstash-vector-js/features/namespaces.md +32 -0
- package/.agents/skills/upstash/upstash-vector-js/overview.md +44 -0
- package/.agents/skills/upstash/upstash-vector-js/sdk-methods.md +210 -0
- package/.agents/skills/upstash/upstash-workflow-js/agents.md +248 -0
- package/.agents/skills/upstash/upstash-workflow-js/basics/client.md +180 -0
- package/.agents/skills/upstash/upstash-workflow-js/basics/context.md +230 -0
- package/.agents/skills/upstash/upstash-workflow-js/basics/serve.md +70 -0
- package/.agents/skills/upstash/upstash-workflow-js/features/flow-control.md +145 -0
- package/.agents/skills/upstash/upstash-workflow-js/features/invoke.md +97 -0
- package/.agents/skills/upstash/upstash-workflow-js/features/retries-failures-reliability.md +239 -0
- package/.agents/skills/upstash/upstash-workflow-js/features/wait-for-event.md +97 -0
- package/.agents/skills/upstash/upstash-workflow-js/features/webhooks.md +79 -0
- package/.agents/skills/upstash/upstash-workflow-js/how-to/local-dev.md +177 -0
- package/.agents/skills/upstash/upstash-workflow-js/how-to/middleware.md +166 -0
- package/.agents/skills/upstash/upstash-workflow-js/how-to/migrations.md +201 -0
- package/.agents/skills/upstash/upstash-workflow-js/how-to/realtime.md +186 -0
- package/.agents/skills/upstash/upstash-workflow-js/overview.md +55 -0
- package/.agents/skills/upstash/upstash-workflow-js/rest-api.md +156 -0
- package/.agents/skills/upstash/upstash-workflow-js/troubleshooting.md +201 -0
- package/.agents/skills/upstash-box-js/SKILL.md +248 -0
- package/.agents/skills/upstash-box-py/SKILL.md +280 -0
- package/.agents/skills/upstash-cli/SKILL.md +143 -0
- package/.agents/skills/upstash-qstash-js/SKILL.md +86 -0
- package/.agents/skills/upstash-qstash-js/advanced/callbacks.md +147 -0
- package/.agents/skills/upstash-qstash-js/advanced/deduplication.md +86 -0
- package/.agents/skills/upstash-qstash-js/advanced/dlq.md +164 -0
- package/.agents/skills/upstash-qstash-js/advanced/multi-region/summary.md +388 -0
- package/.agents/skills/upstash-qstash-js/advanced/multi-region/verify-multi-region-setup.ts +388 -0
- package/.agents/skills/upstash-qstash-js/fundamentals/local-development.md +106 -0
- package/.agents/skills/upstash-qstash-js/fundamentals/publishing-messages.md +144 -0
- package/.agents/skills/upstash-qstash-js/fundamentals/queues-and-flow-control.md +148 -0
- package/.agents/skills/upstash-qstash-js/fundamentals/schedules.md +177 -0
- package/.agents/skills/upstash-qstash-js/fundamentals/url-groups.md +127 -0
- package/.agents/skills/upstash-qstash-js/verification/platform-specific/nextjs.md +171 -0
- package/.agents/skills/upstash-qstash-js/verification/receiver.md +213 -0
- package/.agents/skills/upstash-ratelimit-js/SKILL.md +31 -0
- package/.agents/skills/upstash-ratelimit-js/algorithms.md +84 -0
- package/.agents/skills/upstash-ratelimit-js/features.md +117 -0
- package/.agents/skills/upstash-ratelimit-js/methods-getting-started.md +77 -0
- package/.agents/skills/upstash-ratelimit-js/pricing-cost.md +146 -0
- package/.agents/skills/upstash-ratelimit-js/traffic-protection.md +77 -0
- package/.agents/skills/upstash-redis-js/SKILL.md +188 -0
- package/.agents/skills/upstash-redis-js/advanced-features/auto-pipeline.md +49 -0
- package/.agents/skills/upstash-redis-js/advanced-features/pipeline-and-transactions.md +42 -0
- package/.agents/skills/upstash-redis-js/advanced-features/scripting.md +124 -0
- package/.agents/skills/upstash-redis-js/data-structures/hashes.md +71 -0
- package/.agents/skills/upstash-redis-js/data-structures/json.md +133 -0
- package/.agents/skills/upstash-redis-js/data-structures/lists.md +72 -0
- package/.agents/skills/upstash-redis-js/data-structures/sets.md +90 -0
- package/.agents/skills/upstash-redis-js/data-structures/sorted-sets.md +126 -0
- package/.agents/skills/upstash-redis-js/data-structures/streams.md +196 -0
- package/.agents/skills/upstash-redis-js/data-structures/strings.md +73 -0
- package/.agents/skills/upstash-redis-js/migrations/from-ioredis.md +163 -0
- package/.agents/skills/upstash-redis-js/migrations/from-redis-node.md +205 -0
- package/.agents/skills/upstash-redis-js/patterns/caching.md +58 -0
- package/.agents/skills/upstash-redis-js/patterns/distributed-locks.md +130 -0
- package/.agents/skills/upstash-redis-js/patterns/leaderboard.md +134 -0
- package/.agents/skills/upstash-redis-js/patterns/rate-limiting.md +187 -0
- package/.agents/skills/upstash-redis-js/patterns/session-management.md +217 -0
- package/.agents/skills/upstash-redis-js/performance/batching-operations.md +76 -0
- package/.agents/skills/upstash-redis-js/performance/data-serialization.md +134 -0
- package/.agents/skills/upstash-redis-js/performance/error-handling.md +118 -0
- package/.agents/skills/upstash-redis-js/performance/pipeline-optimization.md +105 -0
- package/.agents/skills/upstash-redis-js/performance/redis-replicas.md +14 -0
- package/.agents/skills/upstash-redis-js/performance/ttl-expiration.md +32 -0
- package/.agents/skills/upstash-redis-js/search/adapters.md +99 -0
- package/.agents/skills/upstash-redis-js/search/commands/aggregating.md +234 -0
- package/.agents/skills/upstash-redis-js/search/commands/aliases.md +76 -0
- package/.agents/skills/upstash-redis-js/search/commands/index-management.md +124 -0
- package/.agents/skills/upstash-redis-js/search/commands/querying.md +315 -0
- package/.agents/skills/upstash-redis-js/search/overview.md +155 -0
- package/.agents/skills/upstash-redis-start/SKILL.md +76 -0
- package/.agents/skills/upstash-search-js/SKILL.md +53 -0
- package/.agents/skills/upstash-search-js/quick-start.md +158 -0
- package/.agents/skills/upstash-search-js/sdk-overview.md +158 -0
- package/.agents/skills/upstash-vector-js/SKILL.md +49 -0
- package/.agents/skills/upstash-vector-js/features/filtering-and-metadata.md +82 -0
- package/.agents/skills/upstash-vector-js/features/index-structure.md +193 -0
- package/.agents/skills/upstash-vector-js/features/namespaces.md +32 -0
- package/.agents/skills/upstash-vector-js/sdk-methods.md +210 -0
- package/.agents/skills/upstash-workflow-js/SKILL.md +60 -0
- package/.agents/skills/upstash-workflow-js/agents.md +248 -0
- package/.agents/skills/upstash-workflow-js/basics/client.md +180 -0
- package/.agents/skills/upstash-workflow-js/basics/context.md +230 -0
- package/.agents/skills/upstash-workflow-js/basics/serve.md +70 -0
- package/.agents/skills/upstash-workflow-js/features/flow-control.md +145 -0
- package/.agents/skills/upstash-workflow-js/features/invoke.md +97 -0
- package/.agents/skills/upstash-workflow-js/features/retries-failures-reliability.md +239 -0
- package/.agents/skills/upstash-workflow-js/features/wait-for-event.md +97 -0
- package/.agents/skills/upstash-workflow-js/features/webhooks.md +79 -0
- package/.agents/skills/upstash-workflow-js/how-to/local-dev.md +177 -0
- package/.agents/skills/upstash-workflow-js/how-to/middleware.md +166 -0
- package/.agents/skills/upstash-workflow-js/how-to/migrations.md +201 -0
- package/.agents/skills/upstash-workflow-js/how-to/realtime.md +186 -0
- package/.agents/skills/upstash-workflow-js/rest-api.md +156 -0
- package/.agents/skills/upstash-workflow-js/troubleshooting.md +201 -0
- package/dist/agents/coding.agent.d.ts +185 -42
- package/dist/agents/coding.agent.d.ts.map +1 -1
- package/dist/agents/coding.agent.js +42 -5
- package/dist/agents/coding.agent.js.map +1 -1
- package/dist/agents/manager.d.ts +216 -41
- package/dist/agents/manager.d.ts.map +1 -1
- package/dist/agents/manager.js +103 -140
- package/dist/agents/manager.js.map +1 -1
- package/dist/agents/security.agent.d.ts +3 -3
- package/dist/agents/swarm/development/lead.d.ts +3 -0
- package/dist/agents/swarm/development/lead.d.ts.map +1 -0
- package/dist/agents/swarm/development/lead.js +24 -0
- package/dist/agents/swarm/development/lead.js.map +1 -0
- package/dist/agents/swarm/main.d.ts +69 -0
- package/dist/agents/swarm/main.d.ts.map +1 -1
- package/dist/agents/swarm/main.js +65 -11
- package/dist/agents/swarm/main.js.map +1 -1
- package/dist/agents/swarm/registry.d.ts +2 -1
- package/dist/agents/swarm/registry.d.ts.map +1 -1
- package/dist/agents/swarm/registry.js +225 -95
- package/dist/agents/swarm/registry.js.map +1 -1
- package/dist/cli/composer.d.ts.map +1 -1
- package/dist/cli/composer.js +85 -30
- package/dist/cli/composer.js.map +1 -1
- package/dist/cli/confirm.d.ts +2 -2
- package/dist/cli/confirm.d.ts.map +1 -1
- package/dist/cli/confirm.js +373 -4
- package/dist/cli/confirm.js.map +1 -1
- package/dist/cli/doctor.d.ts +1 -0
- package/dist/cli/doctor.d.ts.map +1 -1
- package/dist/cli/doctor.js +47 -2
- package/dist/cli/doctor.js.map +1 -1
- package/dist/cli/format.d.ts +4 -0
- package/dist/cli/format.d.ts.map +1 -1
- package/dist/cli/format.js +352 -65
- package/dist/cli/format.js.map +1 -1
- package/dist/cli/interactive.d.ts.map +1 -1
- package/dist/cli/interactive.js +80 -2
- package/dist/cli/interactive.js.map +1 -1
- package/dist/cli/menu.d.ts.map +1 -1
- package/dist/cli/menu.js +93 -83
- package/dist/cli/menu.js.map +1 -1
- package/dist/cli/render.d.ts.map +1 -1
- package/dist/cli/render.js +2 -1
- package/dist/cli/render.js.map +1 -1
- package/dist/cli/setup.d.ts.map +1 -1
- package/dist/cli/setup.js +262 -27
- package/dist/cli/setup.js.map +1 -1
- package/dist/cli/swarm.d.ts.map +1 -1
- package/dist/cli/swarm.js +13 -10
- package/dist/cli/swarm.js.map +1 -1
- package/dist/cli/theme.d.ts +7 -1
- package/dist/cli/theme.d.ts.map +1 -1
- package/dist/cli/theme.js +4 -16
- package/dist/cli/theme.js.map +1 -1
- package/dist/cli/update.d.ts.map +1 -1
- package/dist/cli/update.js +27 -4
- package/dist/cli/update.js.map +1 -1
- package/dist/config/env.d.ts +3 -1
- package/dist/config/env.d.ts.map +1 -1
- package/dist/config/env.js +22 -2
- package/dist/config/env.js.map +1 -1
- package/dist/config/models.d.ts +1 -0
- package/dist/config/models.d.ts.map +1 -1
- package/dist/config/models.js +17 -1
- package/dist/config/models.js.map +1 -1
- package/dist/documents/pdf.d.ts.map +1 -1
- package/dist/documents/pdf.js +282 -22
- package/dist/documents/pdf.js.map +1 -1
- package/dist/documents/slides.d.ts.map +1 -1
- package/dist/documents/slides.js +160 -30
- package/dist/documents/slides.js.map +1 -1
- package/dist/index.js +73 -18
- package/dist/index.js.map +1 -1
- package/dist/memory/history.js +1 -1
- package/dist/observability/doctor.d.ts.map +1 -1
- package/dist/observability/doctor.js +3 -0
- package/dist/observability/doctor.js.map +1 -1
- package/dist/runtime/progress.d.ts +5 -1
- package/dist/runtime/progress.d.ts.map +1 -1
- package/dist/runtime/progress.js.map +1 -1
- package/dist/runtime/swarm.d.ts +1 -1
- package/dist/runtime/swarm.d.ts.map +1 -1
- package/dist/runtime/swarm.js +19 -3
- package/dist/runtime/swarm.js.map +1 -1
- package/dist/runtime/tool-utils.d.ts +2 -0
- package/dist/runtime/tool-utils.d.ts.map +1 -1
- package/dist/runtime/tool-utils.js +91 -0
- package/dist/runtime/tool-utils.js.map +1 -1
- package/dist/server.js +1 -1
- package/dist/server.js.map +1 -1
- package/dist/skills/loader.d.ts.map +1 -1
- package/dist/skills/loader.js +16 -0
- package/dist/skills/loader.js.map +1 -1
- package/dist/test-call.d.ts +2 -0
- package/dist/test-call.d.ts.map +1 -0
- package/dist/test-call.js +29 -0
- package/dist/test-call.js.map +1 -0
- package/dist/test-manager-call.d.ts +2 -0
- package/dist/test-manager-call.d.ts.map +1 -0
- package/dist/test-manager-call.js +138 -0
- package/dist/test-manager-call.js.map +1 -0
- package/dist/test-manager-filtered.d.ts +2 -0
- package/dist/test-manager-filtered.d.ts.map +1 -0
- package/dist/test-manager-filtered.js +130 -0
- package/dist/test-manager-filtered.js.map +1 -0
- package/dist/test-mcp-call.d.ts +2 -0
- package/dist/test-mcp-call.d.ts.map +1 -0
- package/dist/test-mcp-call.js +103 -0
- package/dist/test-mcp-call.js.map +1 -0
- package/dist/tools/composio.tool.d.ts +1 -1
- package/dist/tools/composio.tool.d.ts.map +1 -1
- package/dist/tools/composio.tool.js +7 -16
- package/dist/tools/composio.tool.js.map +1 -1
- package/dist/tools/daytona-browser.tool.js +1 -1
- package/dist/tools/daytona-browser.tool.js.map +1 -1
- package/dist/tools/executive.tool.d.ts +40 -0
- package/dist/tools/executive.tool.d.ts.map +1 -0
- package/dist/tools/executive.tool.js +74 -0
- package/dist/tools/executive.tool.js.map +1 -0
- package/dist/tools/filesystem.tool.d.ts +183 -40
- package/dist/tools/filesystem.tool.d.ts.map +1 -1
- package/dist/tools/filesystem.tool.js +564 -111
- package/dist/tools/filesystem.tool.js.map +1 -1
- package/dist/tools/mcp.tool.d.ts +56 -0
- package/dist/tools/mcp.tool.d.ts.map +1 -0
- package/dist/tools/mcp.tool.js +285 -0
- package/dist/tools/mcp.tool.js.map +1 -0
- package/dist/tools/osint.tool.d.ts +4 -4
- package/dist/tools/pentest.tool.d.ts +2 -2
- package/dist/tools/setup-assistant.tool.d.ts +1 -1
- package/dist/tools/setup-assistant.tool.js +1 -1
- package/dist/tools/setup-assistant.tool.js.map +1 -1
- package/dist/workspace/paths.d.ts +1 -0
- package/dist/workspace/paths.d.ts.map +1 -1
- package/dist/workspace/paths.js +3 -4
- package/dist/workspace/paths.js.map +1 -1
- package/package.json +8 -4
- package/scripts/postinstall.mjs +19 -4
- package/scripts/release-github.mjs +11 -11
|
@@ -0,0 +1,166 @@
|
|
|
1
|
+
# Middlewares
|
|
2
|
+
|
|
3
|
+
This guide explains how to intercept workflow lifecycle and debug events using middleware. It covers how to attach middlewares, define event handlers, initialize resources, and combine functionality into efficient implementations.
|
|
4
|
+
|
|
5
|
+
## Overview
|
|
6
|
+
|
|
7
|
+
Middlewares plug into the workflow engine and listen to:
|
|
8
|
+
|
|
9
|
+
- Lifecycle events such as run start, run completion, and step execution
|
|
10
|
+
- Debug messages such as errors, warnings, and informational logs
|
|
11
|
+
|
|
12
|
+
They are useful for logging, monitoring, instrumentation, and integrating with external systems.
|
|
13
|
+
|
|
14
|
+
## Using Built‑in Middleware
|
|
15
|
+
|
|
16
|
+
Add middleware inside the `middlewares` array when serving a workflow:
|
|
17
|
+
|
|
18
|
+
```ts
|
|
19
|
+
import { serve } from "@upstash/workflow/nextjs";
|
|
20
|
+
import { loggingMiddleware } from "@upstash/workflow";
|
|
21
|
+
|
|
22
|
+
export const { POST } = serve(
|
|
23
|
+
async (ctx) => {
|
|
24
|
+
await ctx.run("step-1", () => "Hello World");
|
|
25
|
+
},
|
|
26
|
+
{
|
|
27
|
+
middlewares: [loggingMiddleware], // emits run/step logs
|
|
28
|
+
}
|
|
29
|
+
);
|
|
30
|
+
```
|
|
31
|
+
|
|
32
|
+
## Creating Custom Middleware
|
|
33
|
+
|
|
34
|
+
You define middleware by instantiating `WorkflowMiddleware` with callbacks for the events you want to handle.
|
|
35
|
+
|
|
36
|
+
### Direct Callback Definitions
|
|
37
|
+
|
|
38
|
+
All lifecycle and debug events can be defined in one object.
|
|
39
|
+
|
|
40
|
+
```ts
|
|
41
|
+
import { WorkflowMiddleware } from "@upstash/workflow";
|
|
42
|
+
|
|
43
|
+
const customMiddleware = new WorkflowMiddleware({
|
|
44
|
+
name: "custom-logger",
|
|
45
|
+
callbacks: {
|
|
46
|
+
// Lifecycle events
|
|
47
|
+
runStarted: async ({ context }) => {
|
|
48
|
+
console.log(`Run ${context.workflowRunId} started`);
|
|
49
|
+
},
|
|
50
|
+
beforeExecution: async ({ context, stepName }) => {
|
|
51
|
+
console.log(`→ Executing step: ${stepName}`);
|
|
52
|
+
},
|
|
53
|
+
afterExecution: async ({ context, stepName, result }) => {
|
|
54
|
+
console.log(`✓ Step ${stepName} completed`, result);
|
|
55
|
+
},
|
|
56
|
+
runCompleted: async ({ context, result }) => {
|
|
57
|
+
console.log(`Run ${context.workflowRunId} finished`, result);
|
|
58
|
+
},
|
|
59
|
+
|
|
60
|
+
// Debug events
|
|
61
|
+
onError: async ({ workflowRunId, error }) => {
|
|
62
|
+
console.error(`Error in ${workflowRunId}`, error);
|
|
63
|
+
},
|
|
64
|
+
onWarning: async ({ workflowRunId, warning }) => {
|
|
65
|
+
console.warn(`Warning from ${workflowRunId}`, warning);
|
|
66
|
+
},
|
|
67
|
+
onInfo: async ({ workflowRunId, info }) => {
|
|
68
|
+
console.info(`Info from ${workflowRunId}`, info);
|
|
69
|
+
},
|
|
70
|
+
},
|
|
71
|
+
});
|
|
72
|
+
```
|
|
73
|
+
|
|
74
|
+
### Initialization With `init`
|
|
75
|
+
|
|
76
|
+
Use `init` when you need setup logic (connecting to a DB, creating clients, loading configuration). `init` returns an object containing the callbacks.
|
|
77
|
+
|
|
78
|
+
```ts
|
|
79
|
+
import { WorkflowMiddleware } from "@upstash/workflow";
|
|
80
|
+
|
|
81
|
+
const databaseMiddleware = new WorkflowMiddleware({
|
|
82
|
+
name: "database-logger",
|
|
83
|
+
init: async () => {
|
|
84
|
+
const db = await connectToDatabase();
|
|
85
|
+
|
|
86
|
+
return {
|
|
87
|
+
runStarted: async ({ context }) => {
|
|
88
|
+
await db.insert({ workflowRunId: context.workflowRunId, status: "started" });
|
|
89
|
+
},
|
|
90
|
+
runCompleted: async ({ context, result }) => {
|
|
91
|
+
await db.update({ workflowRunId: context.workflowRunId, status: "completed", result });
|
|
92
|
+
},
|
|
93
|
+
onError: async ({ workflowRunId, error }) => {
|
|
94
|
+
await db.insert({ workflowRunId, level: "error", message: error.message });
|
|
95
|
+
},
|
|
96
|
+
};
|
|
97
|
+
},
|
|
98
|
+
});
|
|
99
|
+
```
|
|
100
|
+
|
|
101
|
+
## Event Reference
|
|
102
|
+
|
|
103
|
+
Below is a concise list of supported event handlers and what they receive.
|
|
104
|
+
|
|
105
|
+
### Lifecycle
|
|
106
|
+
|
|
107
|
+
- **runStarted**: `{ context }`
|
|
108
|
+
- **beforeExecution**: `{ context, stepName }`
|
|
109
|
+
- **afterExecution**: `{ context, stepName, result }`
|
|
110
|
+
- **runCompleted**: `{ context, result }`
|
|
111
|
+
|
|
112
|
+
### Debug
|
|
113
|
+
|
|
114
|
+
- **onError**: `{ workflowRunId?, error }`
|
|
115
|
+
- **onWarning**: `{ workflowRunId?, warning }`
|
|
116
|
+
- **onInfo**: `{ workflowRunId?, info }`
|
|
117
|
+
|
|
118
|
+
## Combined Example
|
|
119
|
+
|
|
120
|
+
Single snippet showing typical usage patterns.
|
|
121
|
+
|
|
122
|
+
```ts
|
|
123
|
+
import { serve } from "@upstash/workflow/nextjs";
|
|
124
|
+
import { WorkflowMiddleware } from "@upstash/workflow";
|
|
125
|
+
|
|
126
|
+
// Error tracking
|
|
127
|
+
const errorTrackingMiddleware = new WorkflowMiddleware({
|
|
128
|
+
name: "errors",
|
|
129
|
+
callbacks: {
|
|
130
|
+
onError: async ({ workflowRunId, error }) => {
|
|
131
|
+
await fetch("https://monitoring/errors", {
|
|
132
|
+
method: "POST",
|
|
133
|
+
body: JSON.stringify({ workflowRunId, error: error.message }),
|
|
134
|
+
});
|
|
135
|
+
},
|
|
136
|
+
},
|
|
137
|
+
});
|
|
138
|
+
|
|
139
|
+
// Performance measurement
|
|
140
|
+
const timings = new Map();
|
|
141
|
+
const performanceMiddleware = new WorkflowMiddleware({
|
|
142
|
+
name: "perf",
|
|
143
|
+
callbacks: {
|
|
144
|
+
beforeExecution: ({ stepName }) => timings.set(stepName, Date.now()),
|
|
145
|
+
afterExecution: ({ stepName }) => {
|
|
146
|
+
const t = timings.get(stepName);
|
|
147
|
+
if (t) console.log(`Step ${stepName} took ${Date.now() - t}ms`);
|
|
148
|
+
timings.delete(stepName);
|
|
149
|
+
},
|
|
150
|
+
},
|
|
151
|
+
});
|
|
152
|
+
|
|
153
|
+
export const { POST } = serve(
|
|
154
|
+
async (ctx) => {
|
|
155
|
+
await ctx.run("task", () => "done");
|
|
156
|
+
},
|
|
157
|
+
{
|
|
158
|
+
middlewares: [errorTrackingMiddleware, performanceMiddleware],
|
|
159
|
+
}
|
|
160
|
+
);
|
|
161
|
+
```
|
|
162
|
+
|
|
163
|
+
## Pitfalls and Tips
|
|
164
|
+
|
|
165
|
+
- Ensure `init` returns all callbacks; missing keys simply mean the event is ignored.
|
|
166
|
+
- Debug events may be called without a `workflowRunId` if errors occur before run id is identified.
|
|
@@ -0,0 +1,201 @@
|
|
|
1
|
+
# Migration Guide for Upstash Workflow (TypeScript)
|
|
2
|
+
|
|
3
|
+
This document provides a clear, task-focused overview of migrations between Workflow versions. It highlights breaking changes, how to update your code, and common pitfalls to avoid. Code samples combine multiple parameters in each example to reduce redundancy.
|
|
4
|
+
|
|
5
|
+
## January 2026 – Major Release 1.0.0
|
|
6
|
+
|
|
7
|
+
### Agents API → moved to a separate package
|
|
8
|
+
|
|
9
|
+
The Agents API was removed from the core workflow package and placed into `@upstash/workflow-agents` so the base SDK no longer depends on large AI-related libraries.
|
|
10
|
+
|
|
11
|
+
**Key changes**:
|
|
12
|
+
|
|
13
|
+
- Must install and import `agentWorkflow` from the new package.
|
|
14
|
+
- Agents access now happens through an `agents` helper created per workflow invocation.
|
|
15
|
+
|
|
16
|
+
```ts
|
|
17
|
+
// Before
|
|
18
|
+
import { serve } from "@upstash/workflow/nextjs";
|
|
19
|
+
export const { POST } = serve(async (context) => {
|
|
20
|
+
const model = context.agents.openai("gpt-3.5-turbo");
|
|
21
|
+
const agent = context.agents.agent({
|
|
22
|
+
/* ... */
|
|
23
|
+
});
|
|
24
|
+
const task = context.agents.task({
|
|
25
|
+
/* ... */
|
|
26
|
+
});
|
|
27
|
+
});
|
|
28
|
+
|
|
29
|
+
// After
|
|
30
|
+
import { serve } from "@upstash/workflow/nextjs";
|
|
31
|
+
import { agentWorkflow } from "@upstash/workflow-agents";
|
|
32
|
+
export const { POST } = serve(async (context) => {
|
|
33
|
+
const agents = agentWorkflow(context);
|
|
34
|
+
const model = agents.openai("gpt-3.5-turbo");
|
|
35
|
+
const agent = agents.agent({
|
|
36
|
+
/* ... */
|
|
37
|
+
});
|
|
38
|
+
const task = agents.task({
|
|
39
|
+
/* ... */
|
|
40
|
+
});
|
|
41
|
+
});
|
|
42
|
+
```
|
|
43
|
+
|
|
44
|
+
---
|
|
45
|
+
|
|
46
|
+
### `keepTriggerConfig` and `useFailureFunction` removed
|
|
47
|
+
|
|
48
|
+
These fields were redundant—both behaviors are now always enabled.
|
|
49
|
+
|
|
50
|
+
```ts
|
|
51
|
+
// Before
|
|
52
|
+
await client.trigger({
|
|
53
|
+
url: "...",
|
|
54
|
+
retries: 3,
|
|
55
|
+
keepTriggerConfig: true,
|
|
56
|
+
useFailureFunction: true,
|
|
57
|
+
});
|
|
58
|
+
|
|
59
|
+
// After
|
|
60
|
+
await client.trigger({ url: "...", retries: 3 });
|
|
61
|
+
```
|
|
62
|
+
|
|
63
|
+
---
|
|
64
|
+
|
|
65
|
+
### Configuration moved from `serve()` → `client.trigger()`
|
|
66
|
+
|
|
67
|
+
Options such as `retries`, `flowControl`, `retryDelay`, and `failureUrl` no longer belong in `serve()`.
|
|
68
|
+
|
|
69
|
+
```ts
|
|
70
|
+
// Before
|
|
71
|
+
export const { POST } = serve(
|
|
72
|
+
async (context) => {
|
|
73
|
+
/* ... */
|
|
74
|
+
},
|
|
75
|
+
{
|
|
76
|
+
retries: 3,
|
|
77
|
+
retryDelay: "1000 * (1 + retried)",
|
|
78
|
+
flowControl: { key: "my-key", rate: 10 },
|
|
79
|
+
}
|
|
80
|
+
);
|
|
81
|
+
await client.trigger({ url: "..." });
|
|
82
|
+
|
|
83
|
+
// After
|
|
84
|
+
export const { POST } = serve(async (context) => {
|
|
85
|
+
/* ... */
|
|
86
|
+
});
|
|
87
|
+
await client.trigger({
|
|
88
|
+
url: "...",
|
|
89
|
+
retries: 3,
|
|
90
|
+
retryDelay: "1000 * (1 + retried)",
|
|
91
|
+
flowControl: { key: "my-key", rate: 10 },
|
|
92
|
+
});
|
|
93
|
+
```
|
|
94
|
+
|
|
95
|
+
---
|
|
96
|
+
|
|
97
|
+
### `stringifyBody` removed from `context.call` and `context.invoke`
|
|
98
|
+
|
|
99
|
+
Bodies must now be strings.
|
|
100
|
+
|
|
101
|
+
```ts
|
|
102
|
+
// Before
|
|
103
|
+
await context.call("step", {
|
|
104
|
+
url: "https://api.example.com",
|
|
105
|
+
method: "POST",
|
|
106
|
+
body: { key: "value" },
|
|
107
|
+
stringifyBody: true,
|
|
108
|
+
});
|
|
109
|
+
|
|
110
|
+
// After
|
|
111
|
+
await context.call("step", {
|
|
112
|
+
url: "https://api.example.com",
|
|
113
|
+
method: "POST",
|
|
114
|
+
body: JSON.stringify({ key: "value" }),
|
|
115
|
+
});
|
|
116
|
+
|
|
117
|
+
// Same change applies to invoke
|
|
118
|
+
await context.invoke("other", {
|
|
119
|
+
workflow: otherWorkflow,
|
|
120
|
+
body: JSON.stringify({ key: "value" }),
|
|
121
|
+
});
|
|
122
|
+
```
|
|
123
|
+
|
|
124
|
+
---
|
|
125
|
+
|
|
126
|
+
### Logger removed → middleware system added
|
|
127
|
+
|
|
128
|
+
Removed `WorkflowLogger` class and added `WorkflowMiddleware`. Updated `verbose` param to only allow `true` (in this case, `loggingMiddleware` will be used which prints to console).
|
|
129
|
+
|
|
130
|
+
```ts
|
|
131
|
+
import { loggingMiddleware, WorkflowMiddleware } from "@upstash/workflow";
|
|
132
|
+
|
|
133
|
+
const stepFinish = new WorkflowMiddleware({
|
|
134
|
+
name: "step-finish",
|
|
135
|
+
callbacks: {
|
|
136
|
+
afterExecution: async ({ stepName, result }) =>
|
|
137
|
+
console.log(`Step ${stepName} finished`, result),
|
|
138
|
+
},
|
|
139
|
+
});
|
|
140
|
+
|
|
141
|
+
export const { POST } = serve(
|
|
142
|
+
async (context) => {
|
|
143
|
+
/* ... */
|
|
144
|
+
},
|
|
145
|
+
{
|
|
146
|
+
middlewares: [loggingMiddleware, stepFinish],
|
|
147
|
+
}
|
|
148
|
+
);
|
|
149
|
+
```
|
|
150
|
+
|
|
151
|
+
---
|
|
152
|
+
|
|
153
|
+
## October 2024 – Migration from `@upstash/qstash`
|
|
154
|
+
|
|
155
|
+
### Install the new package
|
|
156
|
+
|
|
157
|
+
Replace all workflow usage from `@upstash/qstash` with `@upstash/workflow`.
|
|
158
|
+
|
|
159
|
+
### Serve import and return shape changed
|
|
160
|
+
|
|
161
|
+
Most environments now require destructuring `{ POST }`.
|
|
162
|
+
|
|
163
|
+
```ts
|
|
164
|
+
// Before
|
|
165
|
+
import { serve } from "@upstash/qstash/nextjs";
|
|
166
|
+
export const POST = serve(...);
|
|
167
|
+
|
|
168
|
+
// After
|
|
169
|
+
import { serve } from "@upstash/workflow/nextjs";
|
|
170
|
+
export const { POST } = serve(...);
|
|
171
|
+
```
|
|
172
|
+
|
|
173
|
+
### `context.call` updated
|
|
174
|
+
|
|
175
|
+
Now returns `{ status, headers, body }` and **does not fail** the workflow if the HTTP call fails.
|
|
176
|
+
|
|
177
|
+
```ts
|
|
178
|
+
const { status, headers, body } = await context.call("call-step", {
|
|
179
|
+
url: "https://example.com/api",
|
|
180
|
+
method: "POST",
|
|
181
|
+
});
|
|
182
|
+
```
|
|
183
|
+
|
|
184
|
+
**Pitfall**: Old runs may not contain `status` or `headers` until fully migrated.
|
|
185
|
+
|
|
186
|
+
### Errors renamed
|
|
187
|
+
|
|
188
|
+
- `QStashWorkflowError` → `WorkflowError`
|
|
189
|
+
- `QStashWorkflowAbort` → `WorkflowAbort`
|
|
190
|
+
|
|
191
|
+
---
|
|
192
|
+
|
|
193
|
+
## Summary of Common Mistakes
|
|
194
|
+
|
|
195
|
+
- Using `context.agents` instead of the new `agentWorkflow()` helper.
|
|
196
|
+
- Leaving old serve-config options (`retries`, `flowControl`, etc.).
|
|
197
|
+
- Forgetting to `JSON.stringify` bodies.
|
|
198
|
+
- Assuming `context.call` failures stop workflow execution.
|
|
199
|
+
- Mix-and-matching `@upstash/qstash` and `@upstash/workflow` imports.
|
|
200
|
+
|
|
201
|
+
This guide ensures smooth migration with minimal friction while highlighting where behavioral changes may break existing workflows.
|
|
@@ -0,0 +1,186 @@
|
|
|
1
|
+
# Realtime Workflow Integration (TypeScript)
|
|
2
|
+
|
|
3
|
+
This Skill provides guidance for building real‑time and human‑in‑the‑loop workflows using Upstash Workflow + Upstash Realtime. It covers event schemas, workflow patterns, emitting/receiving updates, and handling interactive pauses.
|
|
4
|
+
|
|
5
|
+
Key capabilities:
|
|
6
|
+
|
|
7
|
+
- Emit strongly typed workflow events.
|
|
8
|
+
- Subscribe to live updates in the frontend.
|
|
9
|
+
- Implement pause/resume workflows using `waitForEvent` and `notify`.
|
|
10
|
+
|
|
11
|
+
---
|
|
12
|
+
|
|
13
|
+
## Core Concepts
|
|
14
|
+
|
|
15
|
+
### Realtime schema design
|
|
16
|
+
|
|
17
|
+
Define all workflow event types in one schema. Keep event definitions minimal and stable.
|
|
18
|
+
|
|
19
|
+
```ts
|
|
20
|
+
// lib/realtime.ts
|
|
21
|
+
const schema = {
|
|
22
|
+
workflow: {
|
|
23
|
+
// Completion events
|
|
24
|
+
runFinish: z.object({}),
|
|
25
|
+
stepFinish: z.object({ stepName: z.string(), result: z.unknown().optional() }),
|
|
26
|
+
|
|
27
|
+
// Human‑in‑the‑loop events
|
|
28
|
+
waitingForInput: z.object({ eventId: z.string(), message: z.string() }),
|
|
29
|
+
inputResolved: z.object({ eventId: z.string() }),
|
|
30
|
+
},
|
|
31
|
+
};
|
|
32
|
+
|
|
33
|
+
export const realtime = new Realtime({ schema, redis });
|
|
34
|
+
export type RealtimeEvents = InferRealtimeEvents<typeof realtime>;
|
|
35
|
+
```
|
|
36
|
+
|
|
37
|
+
Common mistakes:
|
|
38
|
+
|
|
39
|
+
- Forgetting to wrap events under a namespace (e.g. `workflow.*`).
|
|
40
|
+
|
|
41
|
+
---
|
|
42
|
+
|
|
43
|
+
## Emitting Events Inside Workflows
|
|
44
|
+
|
|
45
|
+
Emit inside `context.run()` whenever possible to avoid duplicate emissions on retries.
|
|
46
|
+
|
|
47
|
+
```ts
|
|
48
|
+
// app/api/workflow/route.ts
|
|
49
|
+
export const { POST } = serve(async (context) => {
|
|
50
|
+
const channel = realtime.channel(context.workflowRunId);
|
|
51
|
+
|
|
52
|
+
// Emit step updates
|
|
53
|
+
await context.run("validate", async () => {
|
|
54
|
+
const result = { ok: true };
|
|
55
|
+
await channel.emit("workflow.stepFinish", { stepName: "validate", result });
|
|
56
|
+
return result;
|
|
57
|
+
});
|
|
58
|
+
|
|
59
|
+
// Final event
|
|
60
|
+
await context.run("finish", () => channel.emit("workflow.runFinish", {}));
|
|
61
|
+
});
|
|
62
|
+
```
|
|
63
|
+
|
|
64
|
+
Pitfall:
|
|
65
|
+
|
|
66
|
+
- Emitting events _outside_ of `context.run()` risks duplicate delivery if retries happen.
|
|
67
|
+
|
|
68
|
+
---
|
|
69
|
+
|
|
70
|
+
## Human‑in‑the‑Loop Workflows
|
|
71
|
+
|
|
72
|
+
Use `waitForEvent()` with unique `eventId` values and emit a `waitingForInput` event immediately.
|
|
73
|
+
|
|
74
|
+
```ts
|
|
75
|
+
// Step that pauses for human input
|
|
76
|
+
const eventId = `approval-${context.workflowRunId}`;
|
|
77
|
+
|
|
78
|
+
const [{ eventData, timeout }] = await Promise.all([
|
|
79
|
+
context.waitForEvent("wait-for-approval", eventId, { timeout: "5m" }),
|
|
80
|
+
context.run("notify-wait", () =>
|
|
81
|
+
channel.emit("workflow.waitingForInput", {
|
|
82
|
+
eventId,
|
|
83
|
+
message: "Waiting for approval...",
|
|
84
|
+
})
|
|
85
|
+
),
|
|
86
|
+
]);
|
|
87
|
+
|
|
88
|
+
if (timeout) return { success: false, reason: "timeout" };
|
|
89
|
+
|
|
90
|
+
await context.run("resolved", () => channel.emit("workflow.inputResolved", { eventId }));
|
|
91
|
+
```
|
|
92
|
+
|
|
93
|
+
Important details:
|
|
94
|
+
|
|
95
|
+
- Always handle timeout: otherwise the workflow may appear stuck.
|
|
96
|
+
- Emit `inputResolved` so the UI can clear any pending state.
|
|
97
|
+
- Use deterministic `eventId` prefixes per action/approval.
|
|
98
|
+
|
|
99
|
+
---
|
|
100
|
+
|
|
101
|
+
## Notify Endpoint (User Response)
|
|
102
|
+
|
|
103
|
+
The frontend sends input back to the workflow using `client.notify()`.
|
|
104
|
+
|
|
105
|
+
```ts
|
|
106
|
+
// app/api/notify/route.ts
|
|
107
|
+
export async function POST(req: NextRequest) {
|
|
108
|
+
const { eventId, eventData } = await req.json();
|
|
109
|
+
|
|
110
|
+
await workflowClient.notify({ eventId, eventData }); // resumes workflow
|
|
111
|
+
return NextResponse.json({ success: true });
|
|
112
|
+
}
|
|
113
|
+
```
|
|
114
|
+
|
|
115
|
+
Common mistakes:
|
|
116
|
+
|
|
117
|
+
- Sending the wrong `eventId` → workflow never resumes.
|
|
118
|
+
- Sending `eventData` that doesn’t match the awaited type.
|
|
119
|
+
|
|
120
|
+
---
|
|
121
|
+
|
|
122
|
+
## Realtime Subscription in the Frontend
|
|
123
|
+
|
|
124
|
+
Use a single hook to consume all workflow‑related events and manage state.
|
|
125
|
+
|
|
126
|
+
```ts
|
|
127
|
+
// lib/realtime-client.ts & useWorkflow hooks
|
|
128
|
+
useRealtime({
|
|
129
|
+
enabled: !!workflowRunId,
|
|
130
|
+
channels: [workflowRunId],
|
|
131
|
+
events: [
|
|
132
|
+
"workflow.stepFinish",
|
|
133
|
+
"workflow.runFinish",
|
|
134
|
+
"workflow.waitingForInput",
|
|
135
|
+
"workflow.inputResolved",
|
|
136
|
+
],
|
|
137
|
+
onData({ event, data }) {
|
|
138
|
+
switch (event) {
|
|
139
|
+
case "workflow.stepFinish":
|
|
140
|
+
setSteps((prev) => [...prev, data]);
|
|
141
|
+
break;
|
|
142
|
+
case "workflow.waitingForInput":
|
|
143
|
+
setWaitingState(data);
|
|
144
|
+
break;
|
|
145
|
+
case "workflow.inputResolved":
|
|
146
|
+
setWaitingState((prev) => (prev?.eventId === data.eventId ? null : prev));
|
|
147
|
+
break;
|
|
148
|
+
case "workflow.runFinish":
|
|
149
|
+
setIsRunFinished(true);
|
|
150
|
+
}
|
|
151
|
+
},
|
|
152
|
+
});
|
|
153
|
+
```
|
|
154
|
+
|
|
155
|
+
Pitfalls:
|
|
156
|
+
|
|
157
|
+
- Forgetting to clear waiting state on `inputResolved`.
|
|
158
|
+
- Forgetting to reset state on re‑trigger.
|
|
159
|
+
|
|
160
|
+
---
|
|
161
|
+
|
|
162
|
+
## Triggering the Workflow
|
|
163
|
+
|
|
164
|
+
One simple endpoint triggers both basic and human‑in‑the‑loop flows.
|
|
165
|
+
|
|
166
|
+
```ts
|
|
167
|
+
// app/api/trigger/route.ts
|
|
168
|
+
export async function POST(req: NextRequest) {
|
|
169
|
+
const workflowUrl = `${req.nextUrl.origin}/api/workflow`; // or /human-in-loop
|
|
170
|
+
const { workflowRunId } = await workflowClient.trigger({
|
|
171
|
+
url: workflowUrl,
|
|
172
|
+
body: { userId: "123", action: "process" },
|
|
173
|
+
});
|
|
174
|
+
return NextResponse.json({ workflowRunId });
|
|
175
|
+
}
|
|
176
|
+
```
|
|
177
|
+
|
|
178
|
+
---
|
|
179
|
+
|
|
180
|
+
## Recommended Patterns
|
|
181
|
+
|
|
182
|
+
- Use one channel per workflow run (`workflowRunId`).
|
|
183
|
+
- Always place event emissions inside `context.run()`.
|
|
184
|
+
- Use stable `eventId` formats for all interactive steps.
|
|
185
|
+
- Subscribe to only the events your UI needs.
|
|
186
|
+
- Reset UI state before every new trigger.
|
|
@@ -0,0 +1,55 @@
|
|
|
1
|
+
# Upstash Workflow SDK
|
|
2
|
+
|
|
3
|
+
## Quick Start
|
|
4
|
+
|
|
5
|
+
The Upstash Workflow SDK lets you expose serverless workflow endpoints and run them reliably using QStash under the hood.
|
|
6
|
+
|
|
7
|
+
Install:
|
|
8
|
+
|
|
9
|
+
```bash
|
|
10
|
+
npm install @upstash/workflow
|
|
11
|
+
```
|
|
12
|
+
|
|
13
|
+
Define a simple workflow endpoint:
|
|
14
|
+
|
|
15
|
+
```ts
|
|
16
|
+
import { serve } from "@upstash/workflow";
|
|
17
|
+
|
|
18
|
+
export const { POST } = serve(async (context) => {
|
|
19
|
+
await context.run("step-1", () => console.log("step 1"));
|
|
20
|
+
await context.run("step-2", () => console.log("step 2"));
|
|
21
|
+
});
|
|
22
|
+
```
|
|
23
|
+
|
|
24
|
+
Trigger it from your backend:
|
|
25
|
+
|
|
26
|
+
```ts
|
|
27
|
+
import { Client } from "@upstash/workflow";
|
|
28
|
+
|
|
29
|
+
const client = new Client({ token: process.env.QSTASH_TOKEN! });
|
|
30
|
+
await client.trigger({ url: "https://your-app.com/api/workflow" });
|
|
31
|
+
```
|
|
32
|
+
|
|
33
|
+
## Other Skill Files
|
|
34
|
+
|
|
35
|
+
These files contain the full documentation. Use them for details, patterns, and advanced behavior.
|
|
36
|
+
|
|
37
|
+
- basics:
|
|
38
|
+
- **basics/serve** – How to expose workflow endpoints.
|
|
39
|
+
- **basics/context** – Full API for workflow `context` (steps, waits, webhooks, events, invoke, etc.).
|
|
40
|
+
- **basics/client** – Using the Workflow client to trigger, cancel, inspect, and notify runs.
|
|
41
|
+
- features:
|
|
42
|
+
- **features/invoke** – Cross‑workflow invocation.
|
|
43
|
+
- **features/reliability** – Retries, failure callbacks, and DLQ.
|
|
44
|
+
- **features/flow-control** – Rate limits, concurrency, and parallelism.
|
|
45
|
+
- **features/wait-for-event** – Notify and wait-for-event patterns.
|
|
46
|
+
- **features/webhooks** – Webhook creation and consumption.
|
|
47
|
+
- how to:
|
|
48
|
+
- **how-to/local-dev** – Local QStash dev server (auto via `QSTASH_DEV=true`) and tunneling.
|
|
49
|
+
- **how-to/realtime** – Realtime and human‑in‑the‑loop workflows.
|
|
50
|
+
- **how-to/migrations** – Migrating workflows safely.
|
|
51
|
+
- **how-to/middleware** – Adding middleware to workflows.
|
|
52
|
+
- other files:
|
|
53
|
+
- **rest-api** – Low-level REST endpoints for interacting with QStash/Workflow.
|
|
54
|
+
- **troubleshooting** – Common debugging and environment issues.
|
|
55
|
+
- **agents** – Using Workflow with agents, orchestrators, and automation patterns.
|