Conversation
The Quick/Reasoning composer toggle switches the active agent profile (default/reasoning), not a model dropdown. Editing + saving the built-in Reasoning profile once made `store.rs::upsert` wrongly stamp it with a numeric `memory_dir_suffix`, routing it to a scoped `session_raw-<n>/` + `memory-<n>/` subtree. A mid-thread switch then rebuilt the agent from the scoped dir, so it could not see the conversation the previous profile wrote to the shared subtree — dropping the earlier plan and all prior context. - `normalise_state` now pins built-in non-default, non-`dedicated_memory` profiles (reasoning/research/planner/review) to the shared memory + session_raw subtree. It runs on every load and save, so it both prevents a fresh mis-assignment and heals an already-persisted stale suffix. Custom profiles and a user-set `dedicated_memory` are untouched. - `seed_resume_from_thread_transcript` now resolves the thread's transcript with the cross-dir, newest-wins `find_root_transcript_for_thread` (scans the shared `session_raw/` plus every `session_raw-<id>/`), so a thread's conversation follows the thread across any profile switch — including already-scoped installs — and stays aligned with the transcript view. Keyed on `thread_id`, so it never bleeds an unrelated session across profiles. Known limitation: the heal recovers the conversation transcript but not semantic captures written to a bug-era `memory-<n>/` during the scoped window. This does not affect the issue's scenario (a plan built under Quick lives in shared memory and is recalled); it is non-destructive (files remain). Tests: profile-scoped resume finds the shared transcript; newest-wins across profile dirs; normalise heals a stale suffix while preserving custom-profile suffixes; upsert of the built-in Reasoning profile stays on the shared subtree. Closes tinyhumansai#5351 Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
|
No actionable comments were generated in the recent review. 🎉 ℹ️ Recent review info⚙️ Run configurationConfiguration used: Organization UI Review profile: CHILL Plan: Pro Run ID: 📒 Files selected for processing (1)
🚧 Files skipped from review as they are similar to previous changes (1)
📝 WalkthroughWalkthroughThe change expands thread transcript resume across shared and profile-scoped directories. It also clears stale memory directory suffixes from built-in profiles without dedicated memory while preserving custom and dedicated-memory profile behavior. ChangesThread transcript resume
Built-in profile normalization
Estimated code review effort: 3 (Moderate) | ~20 minutes Possibly related PRs
Suggested labels: Poem
🚥 Pre-merge checks | ✅ 5✅ Passed checks (5 passed)
Comment |
There was a problem hiding this comment.
YellowSnnowmann has reached the 50-credit limit for trial accounts. To continue receiving code reviews, upgrade your plan.
There was a problem hiding this comment.
Actionable comments posted: 2
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
Inline comments:
In `@src/openhuman/agent/harness/session/runtime.rs`:
- Around line 456-462: Update the debug logging around
find_root_transcript_for_thread in the session resume flow to use the stable
[domain][session_resume] prefix instead of [web-channel]. Add matching prefixed
debug logs for the cross-directory lookup start, successful hit, and fallback
branches, retaining thread={thread_id} as the correlation field.
In `@src/openhuman/agent/profiles/store.rs`:
- Around line 478-493: Add a debug-level [domain] event immediately before the
assignment in the built-in shared-memory normalization branch guarded by
built_in_ids.contains(&profile.id) && !profile.dedicated_memory. Include
profile_id in the event fields, then retain the existing
profile.memory_dir_suffix = None behavior.
🪄 Autofix
Fix all unresolved CodeRabbit comments on this PR:
- Push a commit to this branch (recommended)
- Create a new PR with the fixes
ℹ️ Review info
⚙️ Run configuration
Configuration used: Organization UI
Review profile: CHILL
Plan: Pro
Run ID: 185b85fd-3c89-45eb-b683-fa663971664f
📒 Files selected for processing (3)
src/openhuman/agent/harness/session/runtime.rssrc/openhuman/agent/harness/session/tests.rssrc/openhuman/agent/profiles/store.rs
Address CodeRabbit review on tinyhumansai#5401: the tinyhumansai#5351 heal branch mutated persisted state (memory_dir_suffix) without a debug record. Add a [profiles] debug event with profile_id + had_suffix before the pin. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
There was a problem hiding this comment.
YellowSnnowmann has reached the 50-credit limit for trial accounts. To continue receiving code reviews, upgrade your plan.
M3gA-Mind
left a comment
There was a problem hiding this comment.
Reviewed against upstream/main: CI green on every lane that applies to the changed areas, no unresolved review threads, and the diff does what the title and body claim. Checked correctness, blast radius on shared seams, that the behaviour change is pinned by a test rather than only asserted, and i18n/em-dash compliance on any new user-facing string. Nothing blocking found.
Summary
default/reasoning), not a model dropdown. Switching it mid-thread no longer drops the in-progress conversation and plan.normalise_statenow pins built-in non-default, non-dedicated_memoryprofiles (reasoning/research/planner/review) to the shared memory +session_rawsubtree — preventing and healing the mis-scoping on every load/save.seed_resume_from_thread_transcriptnow resolves the thread's transcript across all profile dirs (newest-wins), so a thread's conversation follows the thread across any profile switch, including already-scoped installs.Problem
Reported in #5351: switching quick↔reasoning mid-session drops the earlier plan and all prior context; the new tier behaves like a fresh session.
Root cause:
store.rs::upsertauto-assigns a numericmemory_dir_suffixto any non-defaultprofile withmemory_dir_suffix.is_none()— it excludes onlydefault, not the other built-ins. So editing + saving the built-in Reasoning profile once stamps it with"-1", routing it to a scopedsession_raw-1/+memory-1/subtree. A mid-thread switch is a session-cache miss that rebuilds the agent from that scoped dir, which cannot see the conversation the previous profile wrote to the shared subtree. It is conditional (needs a prior profile edit) and partial (the plain-text prose fallback survived; tool-call/reasoning transcript fidelity and semantic recall did not).Solution
normalise_statepin (store.rs). In the canonical normalization point (runs on everyloadandsave, wheredefaultis already pinned), built-in non-default, non-dedicated_memoryprofiles are forced tomemory_dir_suffix = None→ shared subtree. This both prevents a fresh mis-assignment and heals an already-persisted stale suffix. Custom profiles and a user-setdedicated_memoryare untouched. Non-destructive — no filesystem move/delete; orphanedmemory-<n>/dirs are left in place.runtime.rs).seed_resume_from_thread_transcriptnow uses the cross-dir, newest-winsfind_root_transcript_for_thread(scans the sharedsession_raw/plus everysession_raw-<id>/) instead of an own-dir-first lookup. A thread's conversation follows the thread across any profile switch and stays aligned with the transcript view + turn mirror, which already use this same resolver. Matching is keyed onthread_id, so it never bleeds an unrelated session across profiles.try_load_session_transcript/find_latest_transcript_in_subdir) is deliberately left untouched; it keeps enforcing profile isolation for its (non-thread-keyed) use.Submission Checklist
normalise_stateheals a stale suffix while preserving a custom profile's suffix; upsert of the built-in Reasoning profile stays on the shared subtree.pnpm test:coverage/cargo-llvm-covneed a full build the local disk could not fit); the 4 tests exercise both changed code paths. Deferred to the CI coverage gate.N/A: behaviour-only bugfix, no feature row added/removed/renamed.## Related—N/A: behaviour-only change.N/A: internal profile-normalization + transcript-resume logic, no release-cut surface.Closes #NNNin## Related.Impact
session_rawsubtree — their shipped intent (dedicated_memory: false). This heals bug-created scoping; any bug-eramemory-<n>/data is orphaned non-destructively (files remain). A dedicated-memory personality active on a thread may now resume that thread's transcript written under another profile (read-only, same conversation; its writes still go to its scoped dir).memory-<n>/during the scoped window. This does not affect the issue's scenario — a plan built under Quick (default) lives in shared memory and is recalled. A proper fix (embeddings/SQLite merge) is invasive and out of scope.workspace_dir(users/<id>/workspace), so there is no cross-tenant transcript access.Related
memory-<n>merge for bug-era captures — out of scope here.AI Authored PR Metadata (required for Codex/Linear PRs)
Linear Issue
Commit & Branch
fix/5351-session-context-model-switcha37feb743Validation Run
pnpm --filter openhuman-app format:check—N/A: no app/src (TypeScript) changes.pnpm typecheck—N/A: no TypeScript changes.cargo test --lib— 4 new tests plus 51 inagent::profiles::store+agent::harness::sessionpass, 0 failed.cargo check --manifest-path Cargo.tomlclean;cargo fmt --checkclean on all 3 changed files.N/A: app/src-tauri untouched; change is core-internal, public API unchanged.Validation Blocked
command:pnpm test:coverage/pnpm rust:check(Tauri shell) / fullcargo testlinkerror:local APFS container saturation during large Rust buildsimpact:diff-coverage gate + Tauri shell check deferred to CI; core crate verified viacargo check+ targeted testsBehavior Changes
session_rawsubtree.Parity Contract
memory_dir_suffix_auto_assigned_on_upsertpasses); default-profile pinning unchanged; the agent-name warm-resume isolation path is untouched.thread_id(no cross-session bleed);dedicated_memoryis honored; blankthread_idshort-circuits toNone.Duplicate / Superseded PR Handling
🤖 Generated with Claude Code
Summary by CodeRabbit
Bug Fixes
Tests