AgentStack
Browse Sign in
Browse Why AgentStack Sell Docs
Sign in
SKILL verified Apache-2.0 Self-run

Resonate Migrate From Temporal

skill-resonatehq-resonate-skills-resonate-migrate-from-temporal · by resonatehq

>-

— No reviews yet
0 installs
35 views
0.0% view→install

Install

$ agentstack add skill-resonatehq-resonate-skills-resonate-migrate-from-temporal

✓ scanned · ✓ verified, works with Claude Code, Cursor, and more.

Security review

✓ Passed

No issues found. Passed automated security review. · v0.1.0 How review works →

  • ✓ Prompt-injection patterns
  • ✓ Secret / credential exfiltration
  • ✓ Dangerous shell & filesystem operations
  • ✓ Untrusted network calls
  • ✓ Known-malicious package signatures

What it can access

  • ✓ Network access No
  • ✓ Filesystem access No
  • ✓ Shell / process execution No
  • ✓ Environment & secrets No
  • ✓ Dynamic code execution No

From automated source analysis of v0.1.0. “Used” means the capability is present in the source — more access means more to trust, not that it’s unsafe.

View the full security report →

Verified badge

Passed review? Show it. Paste this badge into your README, it links to the public security report.

AgentStack Verified badge Links to your public security report.
[![AgentStack Verified](https://agentstack.voostack.com/badges/verified.svg)](https://agentstack.voostack.com/security/report/skill-resonatehq-resonate-skills-resonate-migrate-from-temporal)

Reliability & compatibility

✓ Security review passed
0 installs to date
— no reviews yet
● 2mo ago

Declared compatibility

Claude CodeClaude Desktop

Compatibility is declared by the source manifest. End-to-end runtime verification is coming, see below.

Preview Execution monitoring

We're building live execution health for every listing: tool-call success rate, median latency, uptime, and last-checked timestamps, measured, not self-reported. It isn't live yet, so we don't show numbers we can't stand behind.

How agent discovery & health will work →
Are you the author of Resonate Migrate From Temporal? Claim this listing to set pricing, connect Stripe payouts, and keep 70% of every sale.
Sign up to claim

About

Migrate from Temporal to Resonate

A pattern-by-pattern playbook for porting a Temporal application to Resonate. Identify which Temporal construct each piece of the source uses, apply the matching transform, and reach for the linked per-SDK skill for idiomatic target code.

Ground rules

  • Never invent Temporal code. Quote it from the user's source or a named

temporalio/samples-* file. If you can't find it, say so.

  • Resonate has no @workflow/@activity split. A step is just a function

made durable by ctx.run. Don't invent decorators.

  • Temporal Rust samples live in-repo. Temporal's Rust SDK ships examples in

temporalio/sdk-rust/crates/sdk/examples/ (no separate samples-rust repo) — source Rust migrations from there (helloworld, childworkflows, timerexamples, messagepassing, saga, continueasnew, …). Only mutex and encryption have no Temporal Rust example; for those, source from the Temporal TypeScript idiom.

  • State coverage honestly. A missing example ≠ impossible; it means no worked

reference exists yet.

  • Verify APIs against the pinned version before emitting — the SDK surface

drifts between versions.

Pinned SDK versions (latest released at time of writing)

| SDK | Version | Source | |---|---|---| | TypeScript | @resonatehq/sdk v0.10.2 | npm | | Python | resonate-sdk v0.6.7 | PyPI | | Rust | resonate-sdk v0.4.0 | crates.io | | Go | pre-release, tracks main | GitHub |

Core mappings (apply everywhere)

| Temporal | Resonate | |---|---| | @workflow.defn / Workflow type | a registered function (@resonate.register, resonate.register("name", fn), #[resonate::function], resonate.Register(r, "name", fn)) | | @activity.defn / Activity | a plain function invoked via ctx.run(fn, args) | | workflow.execute_activity(fn, …, start_to_close_timeout=…) | yield ctx.run(fn, args) — no timeout policy required | | Task Queue + Worker wiring | a worker group (only when you need distributed dispatch) | | executeChild / ExecuteChildWorkflow(ChildType, …) | ctx.rpc("name", args) or ctx.run(fn, args) — invoke by registered name; recursion is trivial | | Promise.all / asyncio.gather / parallel futures (fan-out) | start each non-blocking (ctx.beginRun / ctx.rfi / .spawn() / ctx.RPC), then await each | | defineSignal + setHandler + condition | one latent durable promise: p = ctx.promise() then await p | | defineQuery / query handler | delete — promise/result state is the source of truth | | handle.signal(sig) (external) | resonate.promises.resolve(id, value) (HTTP-addressable from anywhere) | | workflow.sleep / NewTimer | ctx.sleep(duration) | | saga compensation stack + drain-on-catch | inline ctx.run(undo, …) in the error branch, guarded by what completed | | continueAsNew | bounded loop: a plain loop. Unbounded loop: ctx.detached(self, n+1) tail-recursion |


Pattern: Workflow + activity

  • DETECT: @workflow.defn/@activity.defn (py), proxyActivities (ts),

RegisterWorkflow+RegisterActivity / workflow.ExecuteActivity (go).

  • TRANSFORM: Register one function. Turn each activity into a plain function

called via ctx.run. Drop Task Queue wiring and start_to_close_timeout.

  • TEMPORAL SOURCE: samples-{python,typescript,go}/hello-world

(py: hello/hello_activity.py).

  • RESONATE TARGET: example-hello-world-{ts,py,rs,go}.
  • RELATED SKILL: resonate-basic-durable-world-usage-{typescript,python,rust,go}.
  • COVERAGE: ts ✅ py ✅ rs ✅ go ✅.

Pattern: Composing functions (child workflows)

  • DETECT: executeChild (ts), workflow.ExecuteChildWorkflow (go),

workflow.execute_child_workflow (py).

  • TRANSFORM: Replace the separate child Workflow type with a call to a

registered function by name (ctx.rpc("name", args) / ctx.run(fn, args)). A function can recurse on itself. Optionally pin child ids with .options(id=…).

  • TEMPORAL SOURCE: samples-typescript/child-workflows,

samples-go/child-workflow (no samples-python child-workflow example).

  • RESONATE TARGET: example-recursive-factorial-{ts,py,rs,go}.
  • RELATED SKILL: resonate-recursive-fan-out-pattern-{typescript,python,rust,go}.
  • COVERAGE: ts ✅ py ✅ rs ✅ go ✅.

Pattern: Fan-out / fan-in (parallel + join)

  • DETECT: Promise.all over executeChild/activities (ts), asyncio.gather

(py), multiple workflow.ExecuteActivity futures then .Get() (go).

  • TRANSFORM: Start each unit non-blocking — ctx.beginRun (ts) / ctx.rfi

(py) / ctx.run(...).spawn() (rs) / ctx.RPC (go); each returns a future immediately. Then await each future. Start ALL before awaiting ANY, or the work serializes.

  • TEMPORAL SOURCE: samples-typescript/child-workflows (Promise.all),

samples-python/hello/hello_parallel_activity.py, samples-go/splitmerge-future.

  • RESONATE TARGET: example-fan-out-fan-in-{ts,py,rs,go}.
  • RELATED SKILL: resonate-recursive-fan-out-pattern-{typescript,python,rust,go}.
  • COVERAGE: ts ✅ py ✅ rs ✅ go ✅.

Pattern: Durable timers

  • DETECT: workflow.sleep(timedelta) (py), sleep('30 days') (ts),

workflow.NewTimer (go).

  • TRANSFORM: Replace with ctx.sleep(duration). Mind the units:
  • TypeScript: milliseconds (ctx.sleep(ms)).
  • Python: seconds as float (ctx.sleep(secs)).
  • Go: time.Duration (ctx.Sleep(d) then f.Await(nil)).
  • Rust: std::time::Duration (ctx.sleep(Duration::from_secs(n)).await?).
  • TEMPORAL SOURCE: samples-{python,typescript,go}/sleep-for-days.
  • RESONATE TARGET: example-durable-sleep-{ts,py,rs,go}.
  • RELATED SKILL: resonate-durable-sleep-scheduled-work-{typescript,rust,go}.
  • COVERAGE: ts ✅ py ✅ rs ✅ go ✅.

Pattern: Signals → durable promises (human-in-the-loop)

  • DETECT: defineSignal/setHandler/condition/defineQuery (ts),

@workflow.signal/workflow.wait_condition (py), workflow.GetSignalChannel/workflow.Await/Selector (go).

  • TRANSFORM: Replace the signal definition + handler + flag + condition with a

single latent durable promise (p = ctx.promise(); await p). Surface p.id to whoever will resolve it (email/webhook/log). Replace handle.signal(...) with resonate.promises.resolve(id, value). Delete Query handlers.

  • RESOLVE API — verify against pinned version:
  • ts (0.10.2): resonate.promises.resolve(id, { data: Buffer.from(JSON.stringify(v)).toString("base64") })
  • py (0.6.7): resonate.promises.resolve(id=…, ikey=…)
  • rs (0.4.0): resonate.promises.resolve(&id, Value::from_serializable(v)?)

(the example repo tracks SDK main and uses json!(v), which does NOT compile against the released v0.4.0 crate — use the Value form)

  • go (main): no high-level resolve yet — use the CLI

resonate promises resolve --value '{"data":"…"}' or r.Sender().PromiseSettle(...) with a base64-encoded codec value (resonate-sdk-go#28).

  • TEMPORAL SOURCE: samples-typescript/signals-queries,

samples-python/hello/hello_signal.py, samples-go/await-signals.

  • RESONATE TARGET: example-human-in-the-loop-{ts,py,rs,go}.
  • RELATED SKILL: resonate-human-in-the-loop-pattern-{typescript,python,rust,go}.
  • COVERAGE: ts ✅ py ✅ rs ✅ go ✅ (Go resolve is lower-level).

Pattern: Saga / compensation

  • DETECT: a compensation list drained in catch (ts), stacked defer

compensations (go), handler-coordinated compensation (py).

  • TRANSFORM: Run each step with ctx.run. On failure, run the undo inline in

the catch/error branch, guarded by which steps actually completed. No compensation stack, no drain helper. Make compensations idempotent.

  • TEMPORAL SOURCE: samples-typescript/saga, samples-go/saga,

samples-python/message_passing/waiting_for_handlers_and_compensation.

  • RESONATE TARGET: example-saga-booking-ts, example-money-transfer-{py,rs}.
  • RELATED SKILL: resonate-saga-pattern-{typescript,python,rust,go}.
  • COVERAGE: ts ✅ py ✅ rs ✅ go ⚠️ (no Go example yet — map by analogy).

Pattern: Long-running loops

  • DETECT: continueAsNew (ts), workflow.NewContinueAsNewError (go),

workflow.continue_as_new (py).

  • TRANSFORM:
  • Bounded loop → plain while/for with ctx.run + ctx.sleep. No

continueAsNew equivalent needed.

  • Truly unbounded loop → ctx.detached(self, n+1) tail-recursion, split

inside the per-iteration function. A naive infinite loop in a single durable invocation accumulates child promises that get re-walked on replay; once replay time exceeds the task lease, the worker loop stalls. Do not emit a naive unbounded loop (while(true) / while True: / loop {}) for genuinely infinite loops.

  • TEMPORAL SOURCE: samples-typescript/continue-as-new,

samples-go/child-workflow-continue-as-new, samples-python/hello/hello_continue_as_new.py.

  • RESONATE TARGET: example-infinite-workflow-{ts,go}.
  • COVERAGE: ts ✅ go ✅ py ⚠️ rs ⚠️ (no py/rs example yet — map by analogy).

Pattern: Distributed mutex (TypeScript only)

  • DETECT: a lock-manager workflow with a signal queue, uuid4() release

tokens, and continueAsNew.

  • TRANSFORM: Delete the lock machinery. Sequential yield* ctx.run() calls in

a generator are serialized by the runtime — the generator is the lock. No signals, no tokens, no deadlock surface.

  • TEMPORAL SOURCE: samples-typescript/mutex.
  • RESONATE TARGET: example-distributed-mutex-ts.
  • COVERAGE: ts ✅ (TypeScript only).

Pattern: Encryption (TypeScript only)

  • DETECT: a PayloadCodec (encode/decode over Payload[]) + custom

DataConverter + codec server.

  • TRANSFORM: Replace with a single Encryptor (encrypt(Value): Value /

decrypt(Value): Value) passed as a constructor option: new Resonate({ encryptor }). Workflow code is unchanged; the SDK handles promise-store serialization.

  • TEMPORAL SOURCE: samples-typescript/encryption.
  • RESONATE TARGET: example-encryption-ts.
  • COVERAGE: ts ✅ (TypeScript only).

Coverage gaps (do not fabricate)

  • Saga: no Go example (example-saga-booking-go / example-money-transfer-go).
  • Long-running loops: no Python or Rust example (example-infinite-workflow-py / -rs).
  • Distributed mutex, Encryption: TypeScript only.
  • Rust source: Temporal Rust examples are in temporalio/sdk-rust/crates/sdk/examples/

(helloworld, childworkflows, timerexamples, messagepassing, saga, continueasnew, …); only mutex and encryption have no Temporal Rust example.

Source of truth

  • Resonate examples: https://github.com/resonatehq-examples
  • Temporal samples: https://github.com/temporalio (samples-typescript, samples-python, samples-go)
  • Side-by-side guide: https://docs.resonatehq.io/evaluate/coming-from/temporal
  • Concepts first: see the durable-execution and resonate-philosophy skills.

Source & license

This open-source skill is cataloged on AgentStack and links to its original source — we do not rehost the code.

Install and usage instructions live in the source repository linked above.

Reviews

No reviews yet, be the first.

Versions

  • v0.1.0 Imported from the upstream source.