Skip to content

fix(session): preserve agent identity across headless resume - #925

Open
breedx wants to merge 4 commits into
mpfaffenberger:mainfrom
breedx:fix/upstream-session-identity
Open

fix(session): preserve agent identity across headless resume#925
breedx wants to merge 4 commits into
mpfaffenberger:mainfrom
breedx:fix/upstream-session-identity

Conversation

@breedx

@breedx breedx commented Sep 8, 2026

Copy link
Copy Markdown
Contributor

Resuming a conversation in a fresh process currently gives the agent a new identity, even when its message history is restored. Persist identity with that history so headless runners and CLI resume continue the same agent, and reject conflicting explicit identities instead of silently switching ownership.

Related upstream work

Change

  • Add validated, optional runner-owned identity initialization before the conversation starts.
  • Carry versioned identity state on real ModelRequest.metadata, preserving unrelated metadata.
  • Restore centrally through set_message_history; a saved ID wins over a randomly generated process default, while a conflicting explicitly initialized ID fails before replacing active history.
  • Preserve identity through automatic history processing and manual compaction.
  • Keep the cached model agent when identity is unchanged; invalidate it when identity changes.
  • Enclose restoration in the existing /quick-resume and /load_context error boundaries. The existing interactive picker error boundary is exercised too.

The small command_line/session_commands.py change corrects existing load-error handling rather than adding a command. Given the plugin-first guidance, please flag a preferred supported seam before landing if this should be routed differently; the common history restore remains the authoritative identity boundary.

Validation

Base ce1fe372 (0.0.827), Linux / Python 3.13.13, unchanged upstream dependency lock in a dedicated environment. Tests use disposable HOME/XDG and no inherited credentials; socket connect/DNS/bind is blocked, including in subprocess fixtures.

  • Two new behavioral controls run unchanged on unpatched upstream and both fail: named-session and raw-pickle resumes produce three different IDs across three fresh processes. Candidate 2/2 pass, with message counts increasing 2 → 4 → 6 and no caller-side identity repair.
  • Existing identity/loading regression selection: 32 passed, covering explicit conflicts, invalid IDs, cache preservation/invalidation, manual compaction, real quick-resume and picker failure containment.
  • Broad agents/commands/CLI/headless/subagent selection: 1600 passed, 1 failed, 4 warnings. The sole failure is the unchanged test_open_project_and_select_session assertion requiring TODAY: the fixture subtracts one/two hours from the wall clock, so immediately after midnight both entries are correctly labeled yesterday. The exact failure reproduces on unpatched upstream. No tests were skipped or rewritten to hide it.
  • Changed-file Ruff lint, formatting and diff checks pass.

Two stream-callback coroutine warnings and the CLI test's unawaited main coroutine reproduce on base. Quick-resume still invokes the existing deprecated autosave setter; this patch does not suppress its warning. This is scoped evidence, not a green full-suite or live-provider claim.

Compatibility and boundaries

Existing metadata-free histories keep the current/default identity on first restore; after the next checkpoint, the identity is persisted. This deliberately does not infer an old identity from prose. It does not change session file names, formats, migration policy, retry custody, hooks, MCP behavior, dependencies or package versions. New metadata travels with the existing message-history serialization. No prompt-caching or measured cost-saving claim is made by the identity patch alone.

@breedx

breedx commented Sep 8, 2026

Copy link
Copy Markdown
Contributor Author

The new resume regressions pass in upstream CI, but the full suite hits an existing midnight-sensitive session-browser assertion. I reproduced the same failure on unpatched ce1fe372; it is a wall-clock fixture issue, not a failure of persisted identity or structural prompt restoration.

The CI test environment is Python 3.14.7 despite its 3.13 label; local controls were Python 3.13.13. Deprecation/resource/coroutine warnings were inspected, but not all CI warnings have independent base controls. The full suite is not claimed green. #926 remains a dependent draft awaiting #925 acceptance and subsequent requalification.

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