Skip to content

Conversation

@devin-ai-integration
Copy link
Contributor

@devin-ai-integration devin-ai-integration bot commented Feb 10, 2026

feat: add Memory tab with custom vocabulary to AI settings

Summary

Restores custom vocabulary management as a Memory tab within AI settings. Users can add, edit, search, and delete industry/company-specific terms intended to improve transcription accuracy.

Changes across layers:

  • Schema: New memorySchema (Zod) and memories table (TinyBase) with user_id, type, text, created_at fields
  • Persistence: JSON file persister for memories table (memories.json), registered alongside existing persisters
  • Query: visibleVocabs query filtering memories by type === "vocab"
  • UI: CustomVocabularyView component with search/add/edit/delete, inline editing with duplicate detection
  • Routing: Memory variant added to AiTab enum (Rust + generated TS bindings), wired into ai.tsx

Updates since last revision

  • Fixed duplicate vocabulary creation via Enter key in the search field (addressed Graphite AI review). The onSubmit handler now checks for existing terms before calling mutations.create().
  • Fixed edit mode getting stuck when submitting with no changes — onCancelEdit() is now called unconditionally on submit so the user always exits edit mode.
  • Added user_id guard in useVocabMutations.create() to prevent persisting rows with empty user_id before the store is fully initialized (matches the guard pattern used elsewhere in the codebase, e.g. ai.tsx).
  • Resolved malformed onSubmit handler caused by a bad merge — a duplicated code block made CustomVocabularyView unparseable. The handler is now correctly structured with duplicate detection.
  • Merged with latest main.

Review & Testing Checklist for Human

Note: The UI has NOT been manually tested locally. CI passes (desktop_ci on macOS + Linux, fmt), confirming compilation. Runtime behavior needs human verification.

  • Run the app (ONBOARDING=0 pnpm -F desktop tauri dev) and verify the Memory tab appears in AI settings with the Brain icon, vocabulary can be added/edited/deleted, and items persist after restart
  • visibleVocabs query does not filter by user_id — unlike visibleTemplates and other queries that use where("user_id", param("user_id")), the new query only filters on where("type", "vocab"). If multi-user data isolation matters for this table, a user_id filter needs to be added to the query definition in main.ts.
  • Verify useSetPartialRowCallback type castupdateRow in useVocabMutations uses as (args: { rowId: string; text: string }) => void which could mask type mismatches at runtime
  • Confirm bindings.gen.ts stays in sync — it was manually edited to add "memory" alongside the Rust enum change; verify regeneration produces the same result
  • Decide if vocabulary needs to be wired to the STT pipeline — this PR only adds UI + storage; it does NOT pass stored vocabulary to the AM model's custom_vocabulary field during transcription (see plugins/local-stt/src/ext.rs). If end-to-end integration is expected, that's a follow-up

Recommended test plan: Open AI settings → click Memory tab → add a few terms → search → try adding a duplicate (Enter + button) → edit one → delete one → restart app → confirm terms persist.

Notes

@netlify
Copy link

netlify bot commented Feb 10, 2026

Deploy Preview for hyprnote ready!

Name Link
🔨 Latest commit d1bdc6f
🔍 Latest deploy log https://app.netlify.com/projects/hyprnote/deploys/698d76142d0d5600084fd20a
😎 Deploy Preview https://deploy-preview-3816--hyprnote.netlify.app
📱 Preview on mobile
Toggle QR Code...

QR Code

Use your smartphone camera to open QR code link.

To edit notification comments on pull requests, go to your Netlify project configuration.

@netlify
Copy link

netlify bot commented Feb 10, 2026

Deploy Preview for hyprnote-storybook canceled.

Name Link
🔨 Latest commit d1bdc6f
🔍 Latest deploy log https://app.netlify.com/projects/hyprnote-storybook/deploys/698d76140fdfc70008598c81

@devin-ai-integration
Copy link
Contributor Author

🤖 Devin AI Engineer

I'll be helping with this pull request! Here's what you should know:

✅ I will automatically:

  • Address comments on this PR that start with 'DevinAI' or '@devin'.
  • Look at CI failures and help fix them

Note: I can only respond to comments from users who have write access to this repository.

⚙️ Control Options:

  • Disable automatic comment and CI monitoring

@ComputelessComputer ComputelessComputer force-pushed the devin/1770712735-add-memory-tab branch from b1133c9 to 389c98a Compare February 11, 2026 14:25
@ComputelessComputer ComputelessComputer force-pushed the devin/1770712735-add-memory-tab branch from 389c98a to b96e938 Compare February 11, 2026 14:25
Copy link
Contributor Author

@devin-ai-integration devin-ai-integration bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Devin Review found 1 potential issue.

View 6 additional findings in Devin Review.

Open in Devin Review

Copy link
Contributor Author

@devin-ai-integration devin-ai-integration bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Devin Review found 1 new potential issue.

View 8 additional findings in Devin Review.

Open in Devin Review

ComputelessComputer and others added 3 commits February 12, 2026 01:43
Co-authored-by: devin-ai-integration[bot] <158243242+devin-ai-integration[bot]@users.noreply.github.com>
Co-authored-by: graphite-app[bot] <96075541+graphite-app[bot]@users.noreply.github.com>
Co-authored-by: graphite-app[bot] <96075541+graphite-app[bot]@users.noreply.github.com>
Copy link
Contributor Author

@devin-ai-integration devin-ai-integration bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Devin Review found 1 new potential issue.

View 10 additional findings in Devin Review.

Open in Devin Review

Copy link
Contributor Author

@devin-ai-integration devin-ai-integration bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Devin Review found 1 new potential issue.

View 12 additional findings in Devin Review.

Open in Devin Review

Comment on lines +234 to +236
} else if (e.key === "Escape") {
e.preventDefault();
onCancelEdit();
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🟡 Edit form state not reset on cancel, showing stale value on re-edit

When a user edits a vocabulary item, modifies the text, then cancels (via Escape key or X button), and then re-opens the edit mode, the form input shows the previously typed (unsaved) value instead of the current item.text.

Root Cause

The VocabularyItem component creates a useForm instance with defaultValues: { text: item.text } at line 167-170. TanStack Form's defaultValues are only used for initial form state — they do not automatically reset when the user cancels editing.

Both cancel paths fail to call form.reset() before exiting edit mode:

  • Escape key handler at line 234-236: calls onCancelEdit() without resetting.
  • X button at line 267: calls onCancelEdit() without resetting.

Since VocabularyItem uses key={item.rowId} (apps/desktop/src/components/settings/memory/custom-vocabulary.tsx:122), the component does NOT unmount/remount between edit sessions — the form instance and its stale state persist across cancel → re-edit cycles.

Scenario:

  1. User clicks edit on item "hello"
  2. User types "world" into the input
  3. User presses Escape or clicks X → onCancelEdit() sets editingId to null, span shows "hello"
  4. User clicks edit again on the same item → input shows "world" (stale) instead of "hello"

Impact: Confusing UX — users see a value they previously discarded, and if they immediately press Enter to confirm, the item gets updated to the stale value they intended to cancel.

Prompt for agents
In apps/desktop/src/components/settings/memory/custom-vocabulary.tsx, the VocabularyItem component needs to reset its form state when cancelling an edit. There are two cancel paths that need fixing:

1. The Escape key handler around line 234-236: add form.reset() before onCancelEdit()
2. The X button onClick handler at line 267: change from onClick={onCancelEdit} to an inline handler that calls form.reset() then onCancelEdit()

Specifically:
- Line 235-236: change to:
    form.reset();
    onCancelEdit();

- Line 267: change onClick={onCancelEdit} to onClick={() => { form.reset(); onCancelEdit(); }}
Open in Devin Review

Was this helpful? React with 👍 or 👎 to provide feedback.

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.

1 participant