Skip to content

fix: workspace-aware default session identity (#3154)#3157

Open
praisonai-triage-agent[bot] wants to merge 2 commits into
mainfrom
claude/issue-3154-20260718-0851
Open

fix: workspace-aware default session identity (#3154)#3157
praisonai-triage-agent[bot] wants to merge 2 commits into
mainfrom
claude/issue-3154-20260718-0851

Conversation

@praisonai-triage-agent

@praisonai-triage-agent praisonai-triage-agent Bot commented Jul 18, 2026

Copy link
Copy Markdown
Contributor

Fixes #3154

Problem

When history/memory is enabled but no explicit session_id is given, the core Agent derived its default session id from the agent name only (history_<sha256(name)[:8]>). Two agents sharing a name across different projects resolved to the same session file and silently cross-contaminated conversation history (a correctness and privacy issue).

Fix (core, minimal)

  • New praisonaiagents/session/workspace.py with workspace_id(): prefers a stable git root-commit identity, falls back to the resolved cwd, then global. Cached for the process lifetime.
  • Auto-derived session id is now history_<sha256("{workspace}:{name}")[:8]>, so identical agent names in different projects no longer collide.
  • Backward compatible: resolution falls back to the pre-workspace name-only sha256 id, then the legacy md5 id, so existing history_*.json sessions still load.
  • Opt-out: PRAISONAI_GLOBAL_SESSIONS=true restores name-only global continuity.
  • workspace_id lazy-exported from session/__init__.py.

Scope

Core-only, no new Agent params, no new dependencies, no new exported knobs beyond the internal resolver. Explicit session_id continues to win and remains fully global.

Tests

  • Added TestWorkspaceScopedSessionId (3 tests) to tests/unit/test_history_parameter.py: stable workspace_id(), workspace-folded auto id differs from name-only, and the global opt-out.
  • tests/unit/test_history_parameter.py: 16/16 pass. Remaining session-suite failures are pre-existing and unrelated (verified against a clean tree).

Generated with Claude Code

Summary by CodeRabbit

  • New Features

    • Added workspace-aware session continuity for agents using history.
    • Added an option to use globally shared sessions through PRAISONAI_GLOBAL_SESSIONS.
    • Added stable workspace identification based on the project context.
    • Preserved compatibility with existing legacy session files.
  • Bug Fixes

    • Improved automatic history session ID generation when no session ID is provided.

Same-named agents in different projects no longer share conversation
history by default. The auto-derived session id now folds in a stable
workspace/project component (git root-commit, else resolved cwd, else
global) instead of being a function of the agent name alone.

- Add praisonaiagents/session/workspace.py with workspace_id() resolver
- Derive auto id as history_<sha256("{workspace}:{name}")[:8]>
- Keep name-only sha256 + md5 fallbacks so prior sessions still resolve
- Add PRAISONAI_GLOBAL_SESSIONS=true opt-out for name-only continuity

Co-authored-by: MervinPraison <MervinPraison@users.noreply.github.com>
@MervinPraison

Copy link
Copy Markdown
Owner

@coderabbitai review

@MervinPraison

Copy link
Copy Markdown
Owner

/review

@qodo-code-review

Copy link
Copy Markdown

Qodo reviews are paused for this user.

Troubleshooting steps vary by plan Learn more β†’

On a Teams plan?
Reviews resume once this user has a paid seat and their Git account is linked in Qodo.
Link Git account β†’

Using GitHub Enterprise Server, GitLab Self-Managed, or Bitbucket Data Center?
These require an Enterprise plan - Contact us
Contact us β†’

@MervinPraison MervinPraison added pipeline/blocked:ci Blocked: CI not green on HEAD pipeline/blocked:manual-review Blocked: requires manual review pipeline/blocked:no-final Blocked: no FINAL @claude trigger yet pipeline/final-claude-pending Reviews done; waiting for FINAL @claude labels Jul 18, 2026
@coderabbitai

coderabbitai Bot commented Jul 18, 2026

Copy link
Copy Markdown
Contributor
βœ… Action performed

Review finished.

Note: CodeRabbit is an incremental review system and does not re-review already reviewed commits. This command is applicable only when automatic reviews are paused.

@coderabbitai

coderabbitai Bot commented Jul 18, 2026

Copy link
Copy Markdown
Contributor

Review Change Stack

Important

Review skipped

Bot user detected.

To trigger a single review, invoke the @coderabbitai review command.

βš™οΈ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro

Run ID: dc74e268-b448-4135-a608-f21f4ce22dd3

You can disable this status message by setting the reviews.review_status to false in the CodeRabbit configuration file.

Use the checkbox below for a quick retry:

  • πŸ” Trigger review
πŸ“ Walkthrough

Walkthrough

The change adds cached workspace identity resolution, exposes it through the session package, and incorporates it into automatic history session IDs. Global opt-out behavior and fallback lookup for legacy SHA-256 and MD5 session files are retained.

Changes

Workspace-scoped session identity

Layer / File(s) Summary
Workspace identity resolver
src/praisonai-agents/praisonaiagents/session/workspace.py, src/praisonai-agents/praisonaiagents/session/__init__.py
workspace_id() resolves a cached Git root-commit, resolved-directory, or global identity and is lazily exported by the session package.
History session derivation and compatibility
src/praisonai-agents/praisonaiagents/agent/agent.py, src/praisonai-agents/tests/unit/test_history_parameter.py
Automatic history IDs hash the workspace identity with the agent name, support PRAISONAI_GLOBAL_SESSIONS=true, prefer the new ID’s JSON file, and fall back to legacy SHA-256 and MD5 files. Tests cover stability, workspace scoping, and global mode.

Estimated code review effort: 3 (Moderate) | ~20 minutes

Sequence Diagram(s)

sequenceDiagram
  participant Agent
  participant workspace_id
  participant SessionJSONFiles
  Agent->>workspace_id: resolve workspace identity
  workspace_id-->>Agent: return scoped or global identity
  Agent->>SessionJSONFiles: check derived history session ID
  SessionJSONFiles-->>Agent: load new or legacy session JSON
Loading

Suggested labels: pipeline/awaiting-merge-gate

Suggested reviewers: mervinpraison

πŸš₯ Pre-merge checks | βœ… 5
βœ… Passed checks (5 passed)
Check name Status Explanation
Description Check βœ… Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check βœ… Passed The title clearly and concisely summarizes the main change: workspace-aware default session identity.
Linked Issues check βœ… Passed The changes add workspace-scoped auto session IDs, legacy fallbacks, and a global opt-out, matching the issue goals.
Out of Scope Changes check βœ… Passed The added workspace resolver, export wiring, and tests are directly related to the session-identity fix.
Docstring Coverage βœ… Passed No functions found in the changed files to evaluate docstring coverage. Skipping docstring coverage check.
✨ Finishing Touches
πŸ§ͺ Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch claude/issue-3154-20260718-0851

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❀️ Share

Comment @coderabbitai help to get the list of available commands.

@greptile-apps

greptile-apps Bot commented Jul 18, 2026

Copy link
Copy Markdown
Contributor

Greptile Summary

This PR makes automatically generated history sessions workspace-aware. The main changes are:

  • Derive default session IDs from the workspace and agent name.
  • Identify workspaces by Git root commit or resolved working directory.
  • Preserve explicit global session behavior through an environment setting.
  • Resolve session files through the configured session directory.
  • Add coverage for workspace changes and legacy session handling.

Confidence Score: 5/5

The latest fixes look safe to merge.

  • Legacy sessions are no longer adopted across workspace boundaries.
  • Custom session directories are used during migration lookup.
  • Workspace identity is recalculated when the working directory changes.
  • No additional blocking issue qualifies for this follow-up.

Important Files Changed

Filename Overview
src/praisonai-agents/praisonaiagents/agent/agent.py Adds workspace-scoped session IDs and limits legacy session adoption to explicit global scope.
src/praisonai-agents/praisonaiagents/session/workspace.py Adds workspace identity resolution with per-directory caching.
src/praisonai-agents/praisonaiagents/session/init.py Adds a lazy export for workspace identity resolution.
src/praisonai-agents/tests/unit/test_history_parameter.py Adds tests for workspace-scoped IDs, directory changes, global scope, and legacy fallback behavior.

Reviews (2): Last reviewed commit: "fix: harden workspace session isolation ..." | Re-trigger Greptile

Comment thread src/praisonai-agents/praisonaiagents/agent/agent.py Outdated
Comment thread src/praisonai-agents/praisonaiagents/session/workspace.py Outdated
Comment thread src/praisonai-agents/praisonaiagents/agent/agent.py Outdated
@MervinPraison

Copy link
Copy Markdown
Owner

@claude You are the FINAL architecture reviewer. If the branch is under MervinPraison/PraisonAI (not a fork), you are able to make modifications to this branch and push directly. SCOPE: Focus ONLY on Python packages (praisonaiagents, praisonai). Do NOT modify praisonai-rust or praisonai-ts. Read ALL comments above from Gemini, Qodo, CodeRabbit, and Copilot carefully before responding.

Phase 1: Review per AGENTS.md

  1. Protocol-driven: check heavy implementations vs core SDK
  2. Backward compatible: ensure zero feature regressions
  3. Performance: no hot-path regressions
  4. SDK value: review in depth whether the change genuinely adds value to the SDK β€” never add features for the sake of adding them. It must strengthen the SDK (simpler, more user-friendly, robust, world-class, secure). If it does not clearly add value, request changes or recommend rejecting/closing rather than merging scope creep
  5. Do not bloat the Agent class with additional params β€” only if absolutely required; we already support many params.
  6. Repo routing: agent-callable tools β†’ PraisonAI-Tools; lifecycle plugins β†’ PraisonAI-Plugins; optional sandbox backends β†’ PraisonAI-Plugins (praisonai.sandbox entry point) β€” request changes if wrongly added to praisonaiagents/

Phase 2: FIX Valid Issues
7. For any VALID bugs or architectural flaws found by Gemini, CodeRabbit, Qodo, Copilot, or any other reviewer: implement the fix
8. Also independently identify and fix any gaps or issues you find in the changed code β€” do not rely only on prior reviewer feedback
9. Push all code fixes directly to THIS branch (do NOT create a new PR)
10. Comment a summary of exact files modified and what you skipped

Phase 3: Final Verdict
11. If all issues are resolved, approve the PR / close the Issue
12. If blocking issues remain, request changes / leave clear action items

@MervinPraison MervinPraison added pipeline/awaiting-merge-gate FINAL done; waiting for merge gate / CI pipeline/blocked:cooldown Blocked: post-push or @claude cooldown and removed pipeline/final-claude-pending Reviews done; waiting for FINAL @claude pipeline/blocked:no-final Blocked: no FINAL @claude trigger yet labels Jul 18, 2026
@praisonai-triage-agent

praisonai-triage-agent Bot commented Jul 18, 2026

Copy link
Copy Markdown
Contributor Author

Claude finished @MervinPraison's task β€”β€” View job


Final Architecture Review β€” PR #3157 βœ…

  • Read AGENTS.md + changed files
  • Evaluate reviewer feedback (greptile P1s)
  • Independent architecture review
  • Fix valid issues
  • Test (18/18 pass in test_history_parameter.py)
  • Commit & push (a752c3c01)
  • Final verdict

Phase 1 β€” Architecture review (per AGENTS.md)

Check Verdict
Protocol-driven / core-vs-wrapper βœ… Pure-Python identity helper in core; no heavy impl, no new deps. Correctly stays in praisonaiagents/.
Backward compatible βœ… Explicit session_id still wins & stays global. Legacy files still resolve (now safely).
Performance (hot path) βœ… git subprocess is cached per-directory (lru_cache); constructing an Agent doesn't re-shell-out. Rejected greptile's "drop the cache" suggestion β€” it would add a git call to every Agent construction.
SDK value βœ… Genuine correctness+privacy fix (same-named agents in different projects no longer cross-contaminate). Not scope creep.
No Agent-param bloat βœ… Zero new Agent params. Only an internal resolver + one env opt-out (PRAISONAI_GLOBAL_SESSIONS).
Repo routing βœ… Correct β€” this is a core session-identity concern, not a tool/plugin/sandbox.

Phase 2 β€” Fixes implemented

Greptile raised 3 P1s. Assessment + action:

  1. Custom Session Home Skips Migration β€” βœ… VALID, FIXED. The migration lookup hardcoded ~/.praisonai/sessions, but the store reads from get_sessions_dir() which honors PRAISONAI_HOME. Now the lookup uses the same helper, so migration works under a custom home. (agent.py:1292-1300)

  2. Legacy Fallback Bypasses Isolation β€” βœ… VALID, FIXED. The name-only fallback could let Project B silently adopt Project A's history. The legacy fallback is now gated to global scope only (elif _global_scope and …), so a workspace-scoped run never inherits another project's session. Legacy continuity remains available explicitly via PRAISONAI_GLOBAL_SESSIONS=true. (agent.py:1301-1313)

  3. Workspace Cache Survives Directory Changes β€” βœ… VALID (partially), FIXED without perf cost. Rather than removing caching (greptile's suggestion, which regresses the hot path), the cache is now keyed by resolved cwd and git rev-list runs with cwd=<dir>. A long-lived process that chdirs resolves the correct identity per directory, while repeated calls in the same directory stay cached. (workspace.py:27-75)

Files modified

  • praisonaiagents/agent/agent.py β€” PRAISONAI_HOME-aware lookup + global-scoped legacy fallback
  • praisonaiagents/session/workspace.py β€” per-directory (cwd-keyed) identity resolution
  • tests/unit/test_history_parameter.py β€” +2 tests (directory-change identity, global-only legacy fallback)

Skipped: No changes to praisonai-rust/praisonai-ts (out of scope). qodo review was paused (no actionable items).

Phase 3 β€” Verdict

βœ… Approve. All three P1 reviewer concerns are resolved with minimal, backward-compatible, hot-path-safe changes. Tests: 18/18 passing in the history suite. No Agent-param bloat, no new dependencies, correct repo routing. The PR now delivers the intended isolation guarantee (Issue #3154) without the leakage/edge-case gaps.

Note: I can post review feedback but cannot submit a formal GitHub approval for security reasons β€” a maintainer should click Approve/Merge.

Job run β€’ Branch claude/issue-3154-20260718-0851

- Honor PRAISONAI_HOME in legacy-session migration lookup via
  get_sessions_dir() instead of a hardcoded ~/.praisonai/sessions path.
- Gate legacy name-only fallback to global scope only, so a workspace-scoped
  run never silently adopts another project's history (isolation, #3154).
- Resolve workspace identity per-directory (cache keyed by cwd) so a
  long-lived process that changes directory gets the correct identity while
  still avoiding repeated git calls per directory.
- Add tests for directory-change identity and global-scoped legacy fallback.

Co-authored-by: Mervin Praison <MervinPraison@users.noreply.github.com>
@MervinPraison MervinPraison added pipeline/blocked:stale-final Blocked: FINAL stale after new commits and removed pipeline/blocked:stale-final Blocked: FINAL stale after new commits labels Jul 18, 2026
@praisonai-triage-agent praisonai-triage-agent Bot removed the pipeline/blocked:cooldown Blocked: post-push or @claude cooldown label Jul 18, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

pipeline/awaiting-merge-gate FINAL done; waiting for merge gate / CI pipeline/blocked:ci Blocked: CI not green on HEAD pipeline/blocked:manual-review Blocked: requires manual review

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Workspace-aware default session identity: same-named agents in different projects silently share conversation history

1 participant