Skip to content

feat: durable remote session adapters and session telemetry - #2384

Open
jkyamog wants to merge 3 commits into
bastani-inc:mainfrom
jkyamog:fix/remote-session-telemetry-ui
Open

feat: durable remote session adapters and session telemetry#2384
jkyamog wants to merge 3 commits into
bastani-inc:mainfrom
jkyamog:fix/remote-session-telemetry-ui

Conversation

@jkyamog

@jkyamog jkyamog commented Aug 14, 2026

Copy link
Copy Markdown

This branch adds the Atomic-side support needed for extension-provided remote
session adapters, safe workflow continuation, and useful telemetry for stages
that do not expose a local AgentSession.

The branch is based on origin/main and contains three logical commits:

  1. feat(workflows): add named session adapters
  2. fix(workflows): harden remote session continuation and resume
  3. feat(ui): show adapter session telemetry

What changed

  • Added a versioned named-session-adapter registry with extension discovery,
    conflict detection, and late-registration support.
  • Added serializable stage adapter selection and an explicit adapter retry
    policy, including retryPolicy: "never" for adapters that require explicit
    workflow control for reconnects.
  • Hardened durable stage continuation and workflow resume:
    • preserves stable remote session identity;
    • recovers an accepted but unfinished turn with resume_unfinished_turn
      instead of submitting the prompt twice;
    • recovers a completed remote tail without another model turn;
    • settles queued steering/follow-up messages without creating synthetic
      duplicate continuation work;
    • keeps replay/postmortem stage chat aligned with durable session state.
  • Added adapter-backed session statistics to the interactive usage footer,
    including context usage, input/output tokens, cache read/write totals, cache
    hit rate, and cost when supplied by the adapter.
  • Refreshes the usage ribbon for adapter session_stats events without routing
    those telemetry-only events through the ordinary transcript reducer.
  • Added documentation and regression coverage for adapter registration,
    continuation, resume, queued steering, replay, and telemetry behavior.

View with [code]smith Autofix with [code]smith
Need help on this PR? Tag @codesmith-bot with what you need. Autofix is disabled.

Greptile Summary

This update adds named session-adapter support for workflow conversations, preserves remote-session identity and configuration through recovery, and exposes adapter usage statistics in interactive views. Focused checks confirmed that failed RPC continuation returns an error rather than success, unavailable retained adapters return the documented unavailable result, and restored remote sessions retain their selected adapter and configuration.

Confidence Score: 5/5

Safe to merge based on the exercised continuation, unavailable-adapter, persistence, and remote-session recovery paths.

No blocking failure remains.

T-Rex T-Rex Logs

What T-Rex did

  • Ran the focused RPC continuation-rejection regression from the coding-agent workspace and observed an RPC response with success: false and error: "continuation failed" when a continuation was rejected.
  • Restored persisted stage entries and validated named-adapter selector and configuration retention, then replayed the durable stage-session checkpoint and continued a mirrored remote session through its named adapter after reopening it by stable identity.
  • Confirmed no script was authored and no source code was modified, and verified via runtime that a continuation rejection emits an RPC failure rather than a false success.
  • Verified persistence run restored remote-pi with profile example-profile from a stage-end entry, retained selector metadata in durable checkpoints, reopened a prior transcript, and continued the continuation through the named remote adapter without falling back to the local adapter.

View all artifacts

T-Rex Ran code and verified through T-Rex

Reviews (3): Last reviewed commit: "feat(ui): show adapter session telemetry" | Re-trigger Greptile

Add named external AgentSessionAdapter selection, durable identity persistence, reload-safe discovery, retry controls, and replay hardening for workflow stages.
Comment thread packages/coding-agent/src/modes/rpc/rpc-command-handler.ts Outdated
Comment thread packages/workflows/src/runs/foreground/postmortem-stage-chat.ts Outdated
@jkyamog
jkyamog force-pushed the fix/remote-session-telemetry-ui branch from a4ef4e7 to 6f64254 Compare August 15, 2026 03:56
@jkyamog jkyamog changed the title durable remote session adapters and session telemetry feat: durable remote session adapters and session telemetry Aug 15, 2026
@lavaman131

lavaman131 commented Aug 17, 2026

Copy link
Copy Markdown
Collaborator

Make the run, not the stage, the unit of remote placement

Thanks for the thought put into this. The continuation and resume hardening is the hard part of the problem, and most of it survives what I am about to propose. But sessionAdapter is a per-stage option, and I think placement belongs at the run.

Why the stage is the wrong place to split:

  • Tool gates check the wrong tree. ctx.tool callbacks run in the host process against the local filesystem. A remote stage writes somewhere else, so the build gate after it passes on unchanged source and nothing reports that.
  • Artifacts and reads are host paths. workflowArtifactRunPath() resolves under the local agent dir, so "Read the file at <path>" fails on another node. Copying artifacts across nodes means writing a distributed filesystem.
  • Two parallel stages can write one file. Split across nodes there is no lock, no last writer, and no conflict to report — just two trees, and the next tool node reads one of them. Worktrees are local paths.
  • Steering, prompts, and intercom run in process today. Each becomes a network protocol with its own ordering rules, and stages in one group stop reaching each other.
  • Recovery repeats per stage. This PR already needs resume_unfinished_turn, retryPolicy: "never", and "never resend on an uncertain transcript tail". That is exactly-once delivery over a lossy link. Per-stage placement solves it once per stage, with the checkpoint on one node and the session on another.
  • A dead node leaves a run neither failed nor resumable, which breaks the root failure boundary we promise authors.
  • The selector crosses ~18 durable, persistence, replay, and TUI files. At run level it is one field, read once at launch.

A run already owns one durable record, one artifact root, one intercom group, one worktree contract. Move a whole run and all of that still holds. Throughput does not suffer: run independent workflows at once, which is how we dispatch them anyway.

Where this is going

I am looking at Coder, and at GitHub, so we can back several cloud providers. The model I want is one VM per workflow run, with the durable store on a hosted PostgreSQL so any VM can resume any run.

One VM per run matches the run boundary exactly. A VM has one filesystem, one clone, one worktree, one set of local paths, which is what every stage and tool node in a run already assumes. Stage-level placement leaves two choices and both are bad: a VM per stage, which costs more and brings back every problem above, or all stages in one VM, which is run-level placement with extra plumbing.

The hosted database needs little from us. The backend is already DBOS on Postgres, effectiveSystemDatabaseUrl() already reads DBOS_SYSTEM_DATABASE_URL, and the embedded local Postgres becomes one choice among several. Point a fresh VM at the shared database and it can claim a run and replay it.

Note what that does not solve. DBOS keys durable state by workflow, and stage and tool checkpoints hang off a workflow ID, so a shared database hands us run-level resumption and nothing finer. It cannot give stage-level resumption, because what a remote stage needs back is the live session and its transcript, and that is not in Postgres. So the shared database makes the run the recoverable unit, and per-stage placement then splits recovery between a database one node owns and a session another node owns.

Placing at the run also keeps the provider out of the workflow definition. sessionAdapter on a stage writes a provider choice into the authoring contract, where it turns wrong as soon as there is a second provider. At the run it is a launch input, and Coder, GitHub, or a local host is one more backend behind it.

Keep and change

Keep: resumeUnfinishedTurn and its RPC command, success: false on a rejected continuation, and the no-double-submit path. A remote run needs all of it.

Change: drop StageOptions.sessionAdapter and its threading, keep AgentSessionAdapter internal, and select at launch. The registry shape is fine — it needs a run-level caller.

Tell me if there is a plan for the filesystem problem that I have missed. Otherwise let us talk through the rework before you spend time on it, since the part I want cut is separable from the part I want kept.

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.

2 participants