Skip to content

fix: DELETE /chats/<id> report actual delete result - #4516

Open
praisonai-triage-agent[bot] wants to merge 2 commits into
mainfrom
claude/issue-4495-20260827-1339
Open

fix: DELETE /chats/<id> report actual delete result#4516
praisonai-triage-agent[bot] wants to merge 2 commits into
mainfrom
claude/issue-4495-20260827-1339

Conversation

@praisonai-triage-agent

Copy link
Copy Markdown
Contributor

Fixes #4495

Problem

DELETE /chats/<id> answered {"ok": true} whether or not anything was deleted, and both UI delete paths blanked the transcript regardless. On a read-only or permission-changed data dir, or a synced folder mid-conflict, the conversation visibly closed and then reappeared in the sidebar on the next refresh or restart. A malformed id (a ValueError from _chat_path) was swallowed the same way.

Fix

  • engine/server.pydo_DELETE now returns 400 on an invalid id and 500 on an OSError, instead of swallowing both and always reporting success. The comment mirrors the per-message delete already in the codebase.
  • ui/index.html — the sidebar delete (.x) and runAction('clear') now check the response before blanking the transcript / clearing the list, and surface a toast on failure.
  • Tests
    • engine/test_train_routes.py (DeleteChats): a successful delete removes the chat; a delete that cannot happen (a directory blocking the unlink — deterministic even as root) is not reported as 200 and the chat stays listed; an empty id (../.. after the route is stripped) is refused with 400.
    • frontend/tests/buttons.test.mjs: a stubbed 500 DELETE leaves #turns children intact; a 200 DELETE clears them.

Testing

  • python -m unittest test_train_routes.DeleteChats — 3 passed
  • node --test frontend/tests/buttons.test.mjs — 19 passed

Generated with Claude Code

@praisonai-triage-agent

Copy link
Copy Markdown
Contributor Author

@coderabbitai review

@praisonai-triage-agent

Copy link
Copy Markdown
Contributor Author

/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 →

@greptile-apps

greptile-apps Bot commented Aug 27, 2026

Copy link
Copy Markdown
Contributor

Greptile Summary

The PR makes conversation deletion reflect the actual persistence result and keeps the desktop UI consistent with storage.

  • Returns client and server errors when deletion fails instead of unconditional success.
  • Preserves the transcript after failed sidebar deletion.
  • Tracks partial clear-all success so a successfully deleted active conversation is removed from view while failed conversations remain listed.
  • Adds backend and frontend regression coverage for successful, failed, and malformed deletion requests.

Confidence Score: 5/5

The PR appears safe to merge.

No blocking failure remains.

Important Files Changed

Filename Overview
src/praisonai-desktop/engine/server.py DELETE now distinguishes invalid identifiers and filesystem failures from successful removal.
src/praisonai-desktop/ui/index.html Sidebar and clear-all deletion paths update visible state only according to successful DELETE responses, resolving the previously reported partial-clear inconsistency.
src/praisonai-desktop/engine/test_train_routes.py Adds route-level coverage for successful deletion, unlink failure, and malformed identifiers.
src/praisonai-desktop/frontend/tests/buttons.test.mjs Adds UI regression coverage for failed and successful single deletion and partial clear-all behavior.

Flowchart

%%{init: {'theme': 'neutral'}}%%
flowchart TD
    A[User requests conversation deletion] --> B[DELETE /chats/id]
    B --> C{Path valid?}
    C -- No --> D[Return 400]
    C -- Yes --> E{Unlink succeeds?}
    E -- No --> F[Return 500]
    E -- Yes --> G[Return 200]
    D --> H[UI preserves transcript and list state]
    F --> H
    G --> I[UI clears deleted active transcript]
    I --> J[Refresh conversation list]
Loading

Reviews (4): Last reviewed commit: "fix: clear-all follows storage when a de..." | Re-trigger Greptile

Comment thread src/praisonai-desktop/ui/index.html
@MervinPraison MervinPraison added pipeline/blocked:ci Blocked: CI not green on HEAD pipeline/blocked:no-final Blocked: no FINAL @claude trigger yet pipeline/final-claude-pending Reviews done; waiting for FINAL @claude labels Aug 27, 2026
@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: Review changes in this PR. Python SDK: praisonaiagents, praisonai. TypeScript SDK: src/praisonai-ts/. Do NOT modify src/praisonai-rust. 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 Aug 27, 2026
@praisonai-triage-agent

praisonai-triage-agent Bot commented Aug 27, 2026

Copy link
Copy Markdown
Contributor Author

Claude finished @MervinPraison's task —— View job


Final Architecture Review — PR #4516

Verdict: Approve ✅ (one valid P1 fixed and pushed to this branch)


Phase 1 — Architecture (per AGENTS.md)

This PR is entirely within src/praisonai-desktop/ (stdlib-only engine + shipped ui/index.html). It touches neither praisonaiagents core, the praisonai wrapper, nor src/praisonai-ts — so no protocol/wrapper routing, no Agent param bloat, no new deps. It fixes a genuine correctness bug (a DELETE that silently reports success while the conversation survives on disk), which strengthens robustness without adding surface area. In scope, in the right place.

  • Protocol-driven / routing: N/A — desktop app, no SDK change ✅
  • Backward compatible: {"ok": true} on success unchanged; only real failures now surface as 400/500 ✅
  • Performance: no hot-path impact ✅
  • SDK value / scope: minimal, no new knobs ✅

Phase 2 — Fixes

Greptile P1 (valid) — partial bulk-clear left a stale transcript. In runAction('clear'), any failed delete caused an early return before checking whether the currently-open chatId was one of the deletes that succeeded. Result: the active conversation could be gone on disk yet still visible on screen.

Fixed in ui/index.html — the clear loop now records whether the active id was successfully deleted (activeGone) and blanks the transcript accordingly, on both the partial-failure and all-success paths:

if(!r||!r.ok) failed++;
else if(c.id===chatId) activeGone=true;
...
if(activeGone){ chatId=rid(); turns.innerHTML=''; syncEmpty(); }
if(failed){ toast(...); refreshChats(); closeOverlay(); return; }
if(!activeGone){ chatId=rid(); turns.innerHTML=''; syncEmpty(); }

Added a regression test (buttons.test.mjs): a two-chat clear where the active chat deletes but the other fails must still blank #turns. Verified it fails without the fix and passes with it.

The sidebar per-chat delete (.x, index.html:1050) and the engine do_DELETE 400/500 handling were reviewed and are correct as written — no changes needed there.

Files modified on this branch

  • src/praisonai-desktop/ui/index.html — bulk-clear now follows storage, not the batch result
  • src/praisonai-desktop/frontend/tests/buttons.test.mjs — partial-clear regression test

Skipped

  • Qodo review (paused for this account) — no actionable items
  • No changes to src/praisonai-rust

Tests

  • node --test frontend/tests/buttons.test.mjs20 passed
  • npm run test:ci (full desktop frontend) → 179 passed
  • python -m unittest test_train_routes.DeleteChats3 passed

  • Read changed files
  • Evaluate Greptile P1 — valid
  • Fix bulk-clear partial-failure state inconsistency
  • Add frontend regression test
  • Run tests (all green)
  • Push & summarize
    · Branch: claude/issue-4495-20260827-1339

@praisonai-triage-agent praisonai-triage-agent Bot added pipeline/merge-ready Eligible for merge gate auto-merge and removed pipeline/awaiting-merge-gate FINAL done; waiting for merge gate / CI pipeline/blocked:ci Blocked: CI not green on HEAD pipeline/blocked:cooldown Blocked: post-push or @claude cooldown labels Aug 27, 2026
@MervinPraison

Copy link
Copy Markdown
Owner

@claude this PR has merge conflicts with main. Please rebase onto latest main, resolve conflicts (keep this PR's intent, merge in newer main logic), run targeted tests, and force-push with --force-with-lease. Comment which files you resolved. Do not bloat the Agent class with additional params — only if absolutely required; we already support many params. Keep the resolution minimal — the aim is a lightweight and powerful package; do not introduce scope creep while resolving conflicts.

@praisonai-triage-agent

praisonai-triage-agent Bot commented Aug 27, 2026

Copy link
Copy Markdown
Contributor Author

Claude finished @MervinPraison's task —— View job


Rebase PR #4516 onto latest main — Done ✅

  • Setup git identity & auth
  • Fetch origin/main and rebase
  • Resolve conflicts (keep PR intent + newer main logic)
  • Run targeted tests
  • Force-push with --force-with-lease
  • Comment files resolved

Conflicts resolved

1 file had a real conflict:

  • src/praisonai-desktop/engine/test_train_routes.pymain added a new ChatsListing test class in the exact spot where this PR adds DeleteChats. Resolved by keeping both classes side by side (ChatsListing from main, then DeleteChats from this PR). No test logic was dropped or altered from either side. SHORT_RUN (used by DeleteChats.setUp) is already defined upstream in the file, so no new helpers were needed.

The other three files rebased cleanly (auto-merged, no manual intervention):

  • src/praisonai-desktop/engine/server.py
  • src/praisonai-desktop/ui/index.html
  • src/praisonai-desktop/frontend/tests/buttons.test.mjs

Resolution was minimal — pure conflict reconciliation, no scope creep, no new params, no Agent changes. Changes remain entirely within src/praisonai-desktop/.

Tests (all green)

  • python -m unittest test_train_routes.DeleteChats test_train_routes.ChatsListing5 passed
  • npm run test:ci (full desktop frontend) → 179 passed

Result

Branch rebased onto 615ccc07d (latest main) and force-pushed with --force-with-lease. Merge conflicts resolved.

e1173df6b fix: clear-all follows storage when a delete partially fails
e691a3aab fix: DELETE /chats/<id> report actual delete result (fixes #4495)
615ccc07d Merge pull request #4512 ... (main HEAD)

· Branch: claude/issue-4495-20260827-1339

@praisonai-triage-agent
praisonai-triage-agent Bot force-pushed the claude/issue-4495-20260827-1339 branch from 2132fe4 to e1173df Compare August 27, 2026 15:23
@MervinPraison MervinPraison added pipeline/awaiting-merge-gate FINAL done; waiting for merge gate / CI pipeline/blocked:ci Blocked: CI not green on HEAD pipeline/blocked:cooldown Blocked: post-push or @claude cooldown and removed claude-conflict-pending pipeline/merge-ready Eligible for merge gate auto-merge labels Aug 27, 2026
@praisonai-triage-agent praisonai-triage-agent Bot removed pipeline/awaiting-merge-gate FINAL done; waiting for merge gate / CI pipeline/blocked:ci Blocked: CI not green on HEAD labels Aug 27, 2026
@praisonai-triage-agent praisonai-triage-agent Bot added pipeline/merge-ready Eligible for merge gate auto-merge pipeline/awaiting-merge-gate FINAL done; waiting for merge gate / CI pipeline/blocked:conflict Blocked: merge conflict or rebase pending and removed pipeline/blocked:cooldown Blocked: post-push or @claude cooldown pipeline/merge-ready Eligible for merge gate auto-merge labels Aug 27, 2026
@MervinPraison

Copy link
Copy Markdown
Owner

@claude this PR has merge conflicts with main. Please rebase onto latest main, resolve conflicts (keep this PR's intent, merge in newer main logic), run targeted tests, and force-push with --force-with-lease. Comment which files you resolved. Do not bloat the Agent class with additional params — only if absolutely required; we already support many params. Keep the resolution minimal — the aim is a lightweight and powerful package; do not introduce scope creep while resolving conflicts.

@praisonai-triage-agent

praisonai-triage-agent Bot commented Aug 28, 2026

Copy link
Copy Markdown
Contributor Author

Claude finished @MervinPraison's task —— View job


Rebase PR #4516 onto latest main — Done ✅

  • Setup git identity & auth
  • Fetch origin/main and rebase
  • Resolve conflicts (keep PR intent + newer main logic)
  • Run targeted tests
  • Force-push with --force-with-lease
  • Comment files resolved

Conflicts resolved

1 file had a real conflict:

  • src/praisonai-desktop/engine/test_train_routes.pymain added a new QuitStopsTheTrainer test class at the exact spot where this PR adds DeleteChats. Resolved by keeping both classes side by side (QuitStopsTheTrainer from main, then DeleteChats from this PR). No test logic dropped or altered from either side. SHORT_RUN (used by DeleteChats.setUp) is already defined upstream in the file, so no new helpers were needed.

The other three files rebased cleanly (auto-merged, no manual intervention):

  • src/praisonai-desktop/engine/server.py
  • src/praisonai-desktop/ui/index.html
  • src/praisonai-desktop/frontend/tests/buttons.test.mjs

Resolution was minimal — pure conflict reconciliation, no scope creep, no new params, no Agent changes. All changes remain within src/praisonai-desktop/.

Tests (all green)

  • python -m unittest test_train_routes.DeleteChats test_train_routes.ChatsListing5 passed
  • node --test frontend/tests/buttons.test.mjs20 passed
  • npm run test:ci (full desktop frontend) → 180 passed

Result

Branch rebased onto 660bd52ce (latest main) and force-pushed with --force-with-lease.

3b0101d1e fix: clear-all follows storage when a delete partially fails
faabad0b8 fix: DELETE /chats/<id> report actual delete result (fixes #4495)
660bd52ce Merge pull request #4506 ... (main HEAD)

· Branch: claude/issue-4495-20260827-1339

praisonai-triage-agent Bot and others added 2 commits August 28, 2026 03:42
The engine answered {"ok": true} whether or not the chat was removed,
and both UI delete paths blanked the transcript regardless. A read-only
or synced data dir left the conversation closed on screen and back in
the sidebar on the next refresh.

- engine/server.py: do_DELETE returns 400 on an invalid id and 500 on
  an OSError instead of swallowing both.
- ui/index.html: the sidebar delete and runAction('clear') now check the
  response before blanking the transcript, matching the per-message
  delete already in place.
- tests: engine DeleteChats route tests and two buttons.test.mjs cases.

Co-authored-by: MervinPraison <MervinPraison@users.noreply.github.com>
The bulk "Delete all conversations" path returned early on any failure
without checking whether the active conversation was among the deletes
that succeeded, leaving its transcript on screen while gone on disk.
Track the active id and blank the transcript when it was deleted, even
if a different conversation's delete failed. Adds a regression test.

🤖 Generated with [Claude Code](https://claude.ai/code)

Co-authored-by: Mervin Praison <MervinPraison@users.noreply.github.com>
@praisonai-triage-agent
praisonai-triage-agent Bot force-pushed the claude/issue-4495-20260827-1339 branch from e1173df to 3b0101d Compare August 28, 2026 03:43
@MervinPraison MervinPraison added pipeline/blocked:ci Blocked: CI not green on HEAD pipeline/blocked:cooldown Blocked: post-push or @claude cooldown and removed claude-conflict-pending pipeline/blocked:conflict Blocked: merge conflict or rebase pending labels Aug 28, 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:cooldown Blocked: post-push or @claude cooldown

Projects

None yet

Development

Successfully merging this pull request may close these issues.

desktop: DELETE /chats/<id> answers {"ok": true} whether or not anything was deleted, and the UI blanks the transcript regardless

1 participant