Integrate session ownership and state routing / 集成会话归属与状态路由#4250
Conversation
Integrates the session ownership foundation from PR esengine#4215 and compatible state-routing fixes from PR esengine#4073 and PR esengine#3935. Contributor attribution and verification details are documented in the pull request body.
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: 5c4aa0fd84
ℹ️ 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".
| for i := len(msgs) - 1; i >= start; i-- { | ||
| for j := len(msgs[i].ToolCalls) - 1; j >= 0; j-- { | ||
| tc := msgs[i].ToolCalls[j] | ||
| if tc.Name == "todo_write" { | ||
| return tc.Arguments, true |
There was a problem hiding this comment.
Account for complete_step when ending approval bypass
When an approved plan follows the documented workflow (an initial todo_write followed by complete_step sign-offs, with no final todo_write), this scan keeps returning the initial incomplete todo list; the host-advanced state from complete_step is recorded in the agent ledger/events rather than as a todo_write in Session().Messages. That leaves approvedPlanActive true after the plan is actually complete, so a later user message such as “continue” can still bypass writer approvals for work no longer covered by the approved plan.
Useful? React with 👍 / 👎.
There was a problem hiding this comment.
| value={selectedTabId ?? ""} | ||
| onChange={(e) => setSelectedTabId(e.target.value || null)} |
There was a problem hiding this comment.
Scope suggestions to the selected memory tab
This selector is also shown on the Suggestions subtab, but refreshSuggestions, AcceptMemorySuggestion, and AcceptSkillSuggestion still call the active-tab APIs. When the user selects a non-active project here and generates or accepts a suggestion, the candidate is based on and written to the active project instead, while the panel reloads the selected project and makes the save appear to disappear.
Useful? React with 👍 / 👎.
There was a problem hiding this comment.
Addressed in #4273 with tab-scoped MemorySuggestionsForTab, AcceptMemorySuggestionForTab, and AcceptSkillSuggestionForTab APIs, plus frontend routing from the selected Memory panel tab. Covered by TestMemorySuggestionsForTabUsesSelectedTab.
| if err := os.WriteFile(path, []byte(render(m, name)), 0o644); err != nil { | ||
| return "", err | ||
| } | ||
| if err := s.reindex(name, m); err != nil { | ||
| if err := reindexIn(dir, name, m); err != nil { |
There was a problem hiding this comment.
Remove stale copies when a memory changes scope
If a saved memory already exists in the other directory and is updated with the same name but a type routed to this dir (for example a global user memory is later saved as project), this write leaves the old copy and its index line behind. Because Index, List, and Path read GlobalDir first and dedupe by name, the stale global copy continues to be shown and read, so the apparent overwrite silently does not take effect.
Useful? React with 👍 / 👎.
There was a problem hiding this comment.
Addressed in #4273 by archiving/removing stale active copies from the other memory scope after saving the new scoped copy, and by flushing the old scope index. Covered by TestStoreSaveRemovesStaleCopyWhenScopeChanges.
|
Merged after a full read + local verification (root build/vet/staticcheck/tests clean; desktop build/vet/tests pass aside from two failures that reproduce identically on Two non-blocking observations left as-is, flagged for the record rather than changed here since they're judgment calls:
Tiny lint nit the new desktop test introduced ( |
emitReady returns before touching ctx when a readyHook is set, so the test behaves identically — this only silences staticcheck SA1012 (do not pass a nil Context). Follow-up to #4250, which added the test.
) #4250 carried an approved plan's writer auto-approval across a user pause when the next turn matched a fixed phrase whitelist (继续 / continue / …). That is the brittle intent-detection the project removed elsewhere, and a false positive silently widens auto-approval. Auto-approval now covers the execution turn only; any later turn — including "continue" — returns to the normal per-tool approval posture (ask/auto/yolo still govern it). The plan still seeds todos and avoids clobbering the model's own todo_write. Removes approvedPlanActive/approvedPlanContinuationTurn, the execution marker, and isApprovedPlanContinuation.
Follow-up to #4250: flush stale MEMORY.md entries when the active file is absent, archive the old active copy + stale index line on cross-scope save, wait on already-killed-but-unwinding jobs in DestroySession, and route memory suggestion generation/acceptance through the selected Memory panel tab. Each fix has a regression test. Co-authored-by: lifu963 <56394323+lifu963@users.noreply.github.com> Co-authored-by: ashishexee <144021866+ashishexee@users.noreply.github.com> Co-authored-by: AresNing <49557311+AresNing@users.noreply.github.com>
Summary
This maintainer integration PR uses #4215 as the foundation and folds in compatible state-routing fixes from #4073 and #3935.
The combined change keeps session-owned runtime state aligned across Desktop and controller paths:
Credits / Attribution
This integration PR builds on prior contributor work:
SubagentStore, background job ownership, session destroy cleanup, Desktop restore guarding, and late writeback prevention. Incorporated as the foundation of this PR.Not included in this integration PR:
Verification
gofmt -l $(git diff --name-only origin/main-v2...HEAD -- '*.go')produced no outputgit diff --check origin/main-v2...HEADpassedgo test ./internal/jobs ./internal/control ./internal/agent ./internal/boot ./internal/tool/builtin ./internal/memorypassedgo test ./...passedgo test ./...indesktop/passedgo vet ./...passedgo vet ./...indesktop/passedpnpm --dir desktop/frontend check:csspassedpnpm --dir desktop/frontend typecheckpassed after generating Wails bindings with Wails 2.12.0pnpm --dir desktop/frontend buildpassed after generating Wails bindings with Wails 2.12.0