Fix close_session final save being a guaranteed no-op (#52030)

`close_session` removed the session from `self.sessions` before calling
`save_thread`, but `save_thread` immediately looks up the session in
`self.sessions` and returns early if it's not found. This meant the
explicit final save was always a no-op.

Additionally, when the local `session` variable was dropped at the end
of the closure, it cancelled any in-flight save from a prior observe
callback by dropping `session.pending_save`.

So on session close:
- The explicit final save was a guaranteed no-op
- Any in-flight save from an earlier observation was cancelled

**Fix:** Call `save_thread` while the session is still in the map, then
extract the `pending_save` task and return it so the caller can actually
await the save completing.

**Test:** Added `test_close_session_saves_thread` which sets a draft
prompt without a `run_until_parked()` before `close_session`, so the
only way the data gets persisted is if `close_session` itself performs
the save. Also strengthened the existing `test_save_load_thread`
similarly.

Closes AI-95

Release Notes:

- Fixed a bug where closing an agent thread could lose unsaved changes
(e.g. draft prompts) made in the same frame.
2938ab95dbRichard Feldman committed on 3/23/2026, 3:48:00 PM· committed by GitHubparent4049a4c
1 file changedLine totals unavailable