Skip to content

Apply saved agent config when resuming chats - #2776

Merged
zeroliu merged 2 commits into
v4-previewfrom
codex/resume-initial-agent-config
Aug 8, 2026
Merged

Apply saved agent config when resuming chats#2776
zeroliu merged 2 commits into
v4-previewfrom
codex/resume-initial-agent-config

Conversation

@zeroliu

@zeroliu zeroliu commented Aug 7, 2026

Copy link
Copy Markdown
Collaborator

Relates to logancyang/obsidian-copilot-preview#130

Why

When Agent Home reopens a saved Claude chat, the resumed backend reports its fallback effort (low) and the history path makes that session active without replaying the user's saved default effort. Fresh chats already replay the same initial configuration, so a user who selected high sees different behavior depending on whether a chat is new or resumed.

What

Before: Reopening a saved Claude chat can show and use low even when the agent's default effort is high.

After: The resumed chat applies the backend's initial configuration before it becomes active, so it opens with high and cannot accept a prompt while that write is pending.

If initial configuration fails, the chat still opens with the backend-reported state, matching fresh-chat fallback behavior.

Non goal

  • Persisting and restoring each chat's own model and effort selection; that remains the broader work in logancyang/obsidian-copilot-preview#130.
  • Changing fresh-chat or fan-out initialization.
  • Addressing OpenCode's delayed effort-option startup tracked in logancyang/obsidian-copilot-preview#252.

Screenshot

Not applicable — this changes resumed-session initialization; Agent Home layout and copy are unchanged.

Risk

High

Criterion Status Reason
No behavior change, or a cosmetic/copy/docs/config change visible where it renders, or deterministic tests cover the changed behavior The resumed-session regression test covers the low to high transition and send gating
A defect would fail CI or be obvious on first use The manager test fails if the resumed session returns before initial configuration settles
A revert fully restores prior state, including persisted data The change performs no migration or irreversible write
No auth, permissions, secrets, or input-handling surface changes Session model configuration is the only affected surface
No public API, plugin API, message, or on-disk contract changes Only internal resume sequencing changes
No core-path concurrency, async-lifecycle, or state-machine changes Resumed session creation now awaits backend initialization and handles shutdown during that await
No hot-path behavior lacks deterministic coverage History-resume application and delayed completion are covered deterministically
No new dependency Dependency manifests are unchanged
Human-only behavior stays in one feature area and surfaces quickly Any regression appears immediately when a saved Agent chat is reopened

Review: inspect AgentSessionManager.tryResumeSessionFromHistory in src/agentMode/session/AgentSessionManager.ts and the loadNativeSessionFromHistory() tests in src/agentMode/session/AgentSessionManager.test.ts line by line, then run Verification steps 2–4.

Verification

  1. Load the branch in the documented test vault and enable Claude.
  2. Set Claude's default model to Sonnet and default effort to high, create a chat, then return it to Recent Chats.
  3. Reload the plugin, reopen that saved chat, and confirm the picker shows high before the composer becomes sendable.
  4. Repeat with a Claude model that does not expose effort, then reload while reopening the chat; confirm Agent Home does not hang or retain an orphaned resumed session.

@zeroliu
zeroliu marked this pull request as ready for review August 8, 2026 02:42

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: cda9594dd1

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

});
if (descriptor.applyInitialSessionConfig) {
try {
await descriptor.applyInitialSessionConfig(session, getSettings());

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P2 Badge Prevent stale resume completions from stealing focus

When a user opens another history row while the first resumed Claude chat is awaiting this configuration hook, both rows can remain actionable because the first session is not added to this.sessions until the await finishes. If the second load completes first, the older load subsequently continues and unconditionally makes itself active, returning the user to the chat they selected first; opening the same row twice can additionally create duplicate AgentSession objects whose backend handlers overwrite each other. Deduplicate in-flight loads by (backendId, sessionId) and/or guard activation with a latest-load token before introducing this new suspension point.

Useful? React with 👍 / 👎.

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Fixed in 56acb7a. Resume work is now single-flighted by the native (backendId, sessionId) identity, and history opens use a latest-request guard before activating the pooled session. The new regressions cover both out-of-order completion keeping focus on the newer row and opening the same row twice producing one AgentSession.

});
if (descriptor.applyInitialSessionConfig) {
try {
await descriptor.applyInitialSessionConfig(session, getSettings());

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P2 Badge Replay the persisted mode on resumed sessions

When a user has a sticky defaultMode such as auto or plan, a resumed Claude session still opens in default: ClaudeSdkBackendProcess.resumeSession() initializes no permissionMode, and this new block invokes only applyInitialSessionConfig, which replays effort. Fresh sessions subsequently call replayPersistedMode(session, this.getDefaultMode(...)), but the resume path never does, so the same saved configuration remains inconsistent between new and reopened chats. Replay the persisted mode before returning the resumed session as well.

Useful? React with 👍 / 👎.

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Fixed in 56acb7a. The resume path now awaits replayPersistedMode after backend-specific config and before the session is returned or activated. The regression starts a resumed Claude session in default mode with auto persisted, asserts the bypassPermissions mode write, and verifies the returned state is auto.

});
if (descriptor.applyInitialSessionConfig) {
try {
await descriptor.applyInitialSessionConfig(session, getSettings());

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P2 Badge Update the hook contract to include resumed sessions

This call broadens BackendDescriptor.applyInitialSessionConfig to restored sessions even though the exported interface contract still says it runs only on a freshly created session after createSession, and Claude's implementation documents the same restriction. A backend author can therefore legitimately add fresh-only or non-idempotent setup based on that contract and have it unexpectedly executed against an existing transcript here. Update the descriptor and implementation documentation to define resume semantics, or introduce a separate resume hook.

AGENTS.md reference: AGENTS.md:L27-L27

Useful? React with 👍 / 👎.

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Fixed in 56acb7a. The exported BackendDescriptor contract now explicitly defines the hook for both fresh and resumed sessions, including that seededSelection is absent on resume. The Claude descriptor documentation now matches that lifecycle and clarifies that mode replay remains manager-owned.

@zeroliu
zeroliu force-pushed the codex/resume-initial-agent-config branch from cda9594 to 5a07c7a Compare August 8, 2026 03:17
@zeroliu
zeroliu merged commit e910305 into v4-preview Aug 8, 2026
2 checks passed
@zeroliu
zeroliu deleted the codex/resume-initial-agent-config branch August 8, 2026 03:45
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