Skip to content

th-137b91: Python server durable-executor selection seam (Q parity) - #452

Merged
brentrager merged 2 commits into
mainfrom
th-137b91-IQ-py-temporal-server
Aug 17, 2026
Merged

th-137b91: Python server durable-executor selection seam (Q parity)#452
brentrager merged 2 commits into
mainfrom
th-137b91-IQ-py-temporal-server

Conversation

@brentrager

Copy link
Copy Markdown
Contributor

Problem

Polyglot-parity item Q (ADR-030 durable execution) for the Python server.
TurnRunner called SmoothAgent.run_stream directly, so there was no single place
a durable backend could be selected — unlike the Rust server, whose turn_executor
(runner.rs) picks the executor a turn runs on.

Solution

Route each turn through the engine's AgentExecutor seam, selected once in
select_turn_executor — the Python analog of the Rust turn_executor.

  • Dependency injection: a durable backend is passed to TurnRunner(executor=...)
    as an opaque AgentExecutor, so the server keeps no hard dependency on the
    Temporal package. (The durable backend itself is the Python
    smooai-smooth-operator-temporal package, item I.)
  • Env-gated: SMOOTH_AGENT_DURABLE_EXECUTOR (1/true/on/yes) opts in. The
    injected backend is used only when the env asks; otherwise — and whenever nothing
    is injected — the turn runs on InProcessExecutor, a verbatim delegation to
    run_stream (behavior unchanged). Asking for durable mode with nothing injected
    warns and falls back rather than silently pretending a turn is durable.
  • durable_requested(value) is split out so the parse is testable without mutating
    process-global state.

Deliberate difference from Rust: there an injected executor wins unconditionally;
here the env var is the explicit opt-in, so an injected backend can never silently
take over a deployment that didn't ask. Noted inline.

Verification

  • New test_durable_executor_seam.py: durable_requested parse table;
    select_turn_executor (injected-when-on, ignored-when-off, warn-fallback,
    fresh-per-call); and two real turns driven through a fake injected executor
    (env on → durable used; off → in-process). 19 passed.
  • Full server suite: 350 passed — the run_streamexecute_streaming swap
    regresses nothing.
  • ruff check + ruff format --check clean.

🤖 Generated with Claude Code

https://claude.ai/code/session_01YbN45JeWDbcjvFqGJvmVD3

Route each TurnRunner turn through an AgentExecutor instead of calling
SmoothAgent.run_stream directly, so a durable backend (ADR-030) can be selected in
one place — the Python analog of the Rust server's turn_executor (runner.rs).

- select_turn_executor(injected, env_value): default in-process; a durable backend
  is dependency-INJECTED (TurnRunner(executor=...)) so the seam needs no hard
  dependency on the Temporal package. Selection is env-gated on
  SMOOTH_AGENT_DURABLE_EXECUTOR — the injected backend is used only when the env
  opts in (differs deliberately from Rust, where injection wins unconditionally:
  here the env is the explicit opt-in so an injected backend can never silently
  take over a deployment that didn't ask). Asking for durable mode with nothing
  injected warns and falls back to in-process.
- durable_requested(value): 1/true/on/yes parse, split out for testability.
- The turn's stream now flows through self._executor.execute_streaming(agent, ...).
  Default (nothing injected) = InProcessExecutor, a verbatim delegation to
  run_stream — behavior unchanged.

Tests: durable_requested parse table, select_turn_executor (injected-when-on,
ignored-when-off, warn-fallback, fresh-per-call), and two real turns driven
through a fake injected executor (env on -> durable used; off -> in-process).
Full server suite: 350 passed.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01YbN45JeWDbcjvFqGJvmVD3
@changeset-bot

changeset-bot Bot commented Aug 17, 2026

Copy link
Copy Markdown

🦋 Changeset detected

Latest commit: 8873083

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

This PR includes changesets to release 2 packages
Name Type
@smooai/smooth-operator Patch
@smooai/smooth-operator-web-chat-example 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

@brentrager
brentrager merged commit d8a6d43 into main Aug 17, 2026
3 checks passed
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.

1 participant