Skip to content

feat(chat): persist always-approve tool selections across sessions#561

Open
anfibiacreativa wants to merge 7 commits into
mainfrom
feat/da-always-approve-persist
Open

feat(chat): persist always-approve tool selections across sessions#561
anfibiacreativa wants to merge 7 commits into
mainfrom
feat/da-always-approve-persist

Conversation

@anfibiacreativa

Copy link
Copy Markdown
Member

Summary

  • Always-approve tool selections are now persisted to IndexedDB so they survive page reloads and conversation resets.
  • A new loadAutoApprovedTools / saveAutoApprovedTools API in persistence.js performs read-modify-write to avoid clobbering messages or sessionId.
  • loadInitialMessages loads persisted approvals in parallel with messages on startup.
  • clear() no longer resets _autoApprovedTools — approvals intentionally survive conversation resets per spec.

Problem / Root Cause

Previously _autoApprovedTools was an in-memory Set initialised to empty on every load (and cleared on every clear() call). Users who checked "always approve" for a tool had to re-approve on every page reload or after clicking "New conversation", which was friction-heavy for power users.


What Changed

nx2/blocks/chat/utils/persistence.js

  • Added blankRecord(room) factory to eliminate duplicated blank-record skeletons.
  • loadAutoApprovedTools(room) — readonly IndexedDB transaction; returns a Set<string>; resolves to an empty Set on any error or missing record.
  • saveAutoApprovedTools(room, toolNamesSet) — readwrite transaction with read-modify-write: reads the existing record, spreads in the new tool names array, writes back; wraps the entire async flow in a real Promise (resolves on tx.oncomplete, rejects on tx.onerror / req.onerror / thrown errors).

nx2/blocks/chat/chat-controller.js

  • loadInitialMessages now runs loadMessages and loadAutoApprovedTools in parallel via Promise.all and assigns the result to _autoApprovedTools.
  • approveToolCall (always path) fires saveAutoApprovedTools as a fire-and-forget with .catch(() => {}) to avoid unhandled rejections.
  • Removed the ??= new Set() guard from approveToolCall (the Set is always initialised before any tool call is possible).
  • Removed the _autoApprovedTools = new Set() reset from clear(); added a comment explaining the intentional omission.

test/nx2/blocks/chat/utils/persistence.test.js

  • Added 4 new tests for loadAutoApprovedTools and saveAutoApprovedTools:
    • Returns empty Set for unknown room.
    • Returns saved tool names as a Set.
    • Does not overwrite existing messages or sessionId on save.
    • Merges new tools into an existing list.

WORKLOG.md — updated with implementation notes (2 entries).


Diff stat

WORKLOG.md                                     | 33 +++++++++++++++++
nx2/blocks/chat/chat-controller.js             | 16 ++++++---
nx2/blocks/chat/utils/persistence.js           | 50 ++++++++++++++++++++++++++
test/nx2/blocks/chat/utils/persistence.test.js | 46 ++++++++++++++++++++++++
4 files changed, 141 insertions(+), 4 deletions(-)

How to Test

  1. Open the DA chat panel locally (da-live + da-admin + da-nx running).
  2. Trigger a tool call that requires approval.
  3. Click "Always approve" for that tool.
  4. Reload the page — the tool should be approved without a prompt.
  5. Click "New conversation" (clear) — the tool should still be auto-approved (approvals survive resets).
  6. Open DevTools → Application → IndexedDB → da-chatconversations; verify the record has an autoApprovedTools array containing the tool name.
  7. Run npm test — all 967 tests should pass.

Risk / Follow-ups

  • Risk (low): saveAutoApprovedTools is fire-and-forget from approveToolCall; a quota-exceeded failure logs a console.warn but does not surface to the user. Acceptable for this feature; a toast notification could be added later.
  • Follow-up: Consider a "Manage always-approved tools" UI to let users revoke individual approvals stored in IndexedDB.
  • Follow-up: DB version is still 1; if a future schema change needs to add the autoApprovedTools field to existing records a migration path will be needed (currently handled gracefully by the Array.isArray guard in loadAutoApprovedTools).

anfibiacreativa and others added 4 commits June 26, 2026 14:17
- add loadAutoApprovedTools / saveAutoApprovedTools to persistence.js;
  each does a read-modify-write so messages and sessionId are never overwritten
- load persisted approvals alongside messages in loadInitialMessages so
  the Set is restored from IndexedDB on every page load
- fire-and-forget saveAutoApprovedTools after each always-approve action
- remove the _autoApprovedTools reset from clear() so approvals survive
  conversation resets per spec

Co-Authored-By: Claude <noreply@anthropic.com>
@aem-code-sync

aem-code-sync Bot commented Jun 26, 2026

Copy link
Copy Markdown

Hello, I'm the AEM Code Sync Bot and I will run some actions to deploy your branch.
In case there are problems, just click the checkbox below to rerun the respective action.

  • Re-sync branch
Commits

@aem-code-sync aem-code-sync Bot temporarily deployed to feat/da-always-approve-persist June 26, 2026 13:30 Inactive
@hannessolo

Copy link
Copy Markdown
Contributor

Implementation wise I think it's good.

I'm wondering if this is what we want - this makes it so there's no way to ever revoke auto approval if I understand correctly?

I could see a usecase where in a session you want auto approve, but in a next session you want to review before approving. Maybe we should add a UI for resetting?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants