Commit Graph

162 Commits

Author SHA1 Message Date
Abhinav Raut 6b8a0f9521 fix content loss in knowledge base chunking and harden AI agent limits
Final review pass before taking the AI agent branch live.

Knowledge base:
- Text not wrapped in a block tag was never collected, so prose around a
  table or list never reached the index. The assistant answered "no
  relevant information" for questions the snippet covered.
- Blocks over the token limit were truncated and the remainder dropped. They
  are split into several chunks now.
- Trimming an oversized block ran one rune at a time and re-tokenized the
  whole string each step. A large table took minutes. It uses a binary
  search now.
- Overlap text was not escaped, so a sentence containing markup swallowed
  the rest of the chunk.
- SVG and template text no longer reaches the index.

AI agent:
- Verification codes are capped per address and per conversation. The cap
  was per conversation only, so a customer correcting a mistyped email was
  told to check an inbox that never got a code.
- Livechat verification sends synchronously. A queued send returned nil even
  when SMTP failed, so a failure counted as a sent code.
- Queued jobs drain on shutdown and hand off to a human instead of being
  dropped with no reply.
- Deleting an assistant no longer moves resolved and closed conversations
  into the fallback team.
- Image decode is capped at 25 MP. The old bound allowed a 400 MB decode per
  attachment.

Auth and admin:
- A blank OIDC client secret no longer overwrites the stored one. Blank id
  or secret is rejected instead.
- OIDC token exchange uses the SSRF guarded client with a timeout.
- Renaming a tool auth header no longer attaches the secret of whichever row
  now sits at that position.
- Clearing embedding dimensions no longer refills 1536 on the next load,
  which pushed a wrong value to the provider on the next save.
- Copilot conversation lookups filter by access before capping at 10.
2026-07-25 03:52:32 +05:30
Abhinav Raut f460f6b163 expand copilot with customer-history tools, persona picker, and tag suggestions
Copilot and Generate Reply get four read-only, access-filtered tools to look up
a customer's history: list the contact's other conversations, search
conversations by exact email, fetch one conversation by reference number, and
search contacts. Tool output is marked untrusted and capped so a big response
can't blow the context window.

Copilot panel changes:
- per-agent persona picker that borrows an enabled assistant's voice, language
  and instructions without changing the tool set (stored in localStorage)
- answers render as HTML; copy, insert-into-reply, and add-as-private-note
  actions per answer
- chat history moves to its own copilot store; server history is persisted only
  after a successful reply and read back with a limit

Adds AI tag suggestions: a new endpoint suggests up to 3 existing tags for a
conversation, applied from the sidebar, never auto-applied.

Hardening and fixes:
- OIDC callback rejects non-agent users
- custom tool URLs and params schema validated on save; tool HTTP client no
  longer follows redirects; query keys pinned in the tool URL win
- GetAllConversationMessages takes an explicit limit (cap 1000)
- FAQ mining skips a candidate already pending review
- ai agent handoff records its event only after the move actually lands
- share chat message role constants; rename v2.7.0 migration to v2.6.0 and add
  the fix_grammar_spelling prompt
2026-07-19 23:33:18 +05:30
Abhinav Raut 97c227b6f8 skip AI agent on non-open status categories instead of hardcoded names 2026-07-18 01:38:30 +05:30
Abhinav Raut a7288e11b0 add AI assistant expectation message shown in the livechat widget 2026-07-12 13:29:59 +05:30
Abhinav Raut 60ebefebdc fix edge cases in private note soft-delete 2026-07-08 01:00:24 +05:30
Abhinav Raut 43b43a82ef Merge branch 'main' into delete-private-notes 2026-07-08 00:47:28 +05:30
Abhinav Raut d696b53c80 soft-delete private notes with a tombstone instead of removing them 2026-07-08 00:43:29 +05:30
Abhinav Raut 9e0c1f332d Merge branch 'main' into delete-private-notes 2026-07-07 23:37:05 +05:30
Abhinav Raut ec3938c365 save reply and private note drafts separately per type 2026-07-03 03:37:09 +05:30
Abhinav Raut 62a1fc836e add livechat widget preview and misc improvements
Livechat:
- Add a live widget preview that renders in the inbox settings help rail.
- Warn when the primary or header colors are too close to the background.
- Require gradient/image background values and notice banner text when enabled.
- Show a default launcher logo in the widget when none is set, matching the preview.
- Drop the Beta badge from the livechat channel.

General settings:
- Add "set agents away on login". Agents log in as away and must go online manually.
- Add "show subject in conversation list" toggle.

Other:
- Add a keyboard shortcuts dialog from the user menu.
- Show a "snoozed until" badge on snoozed conversations.
- Contact search now matches emails partially instead of exact.
- Give outgoing message bubbles a secondary background.
2026-07-03 02:34:42 +05:30
josephsellers 406a2941a1 Scope delete-private-message to its conversation (fix IDOR)
Address CodeRabbit review: the query deleted by message uuid alone, so an agent
with access to one conversation could delete a private note from another by
pairing an accessible cuuid with a foreign message uuid. The delete is now
scoped via conversation_id = (SELECT id FROM conversations WHERE uuid = $2), and
DeletePrivateMessage / the handler pass the conversation uuid alongside the
message uuid.

[Used Claude Code 🤖]
2026-06-18 12:07:31 +01:00
josephsellers b699cacd30 Add API endpoint to delete private notes
Adds DELETE /api/v1/conversations/{cuuid}/messages/{uuid} for removing private
notes via the API. Uses a dedicated `delete-private-message` query/stmt
(separate from the generic `delete-message` used internally by continuity) so
only messages with private=true can be deleted — sent/incoming messages are
protected. Returns 404 if the message doesn't exist or isn't private.

Useful for API consumers that create private notes programmatically and need to
clean them up (e.g. replacing an outdated note before adding a new one).

[Used Claude Code 🤖]
2026-06-18 11:33:19 +01:00
Abhinav Raut 1b87433de4 fixes autoassigner overriding a manual assignment
The autoassigner fetched the unassigned list once, then looped and
assigned each one. If the conversation was reassigned while that slow
batch was still running, the autoassigner's write still landed and
overrode it, because the UPDATE had no guard.

Adds an atomic claim that only assigns when the conversation is still
unassigned AND still in the team the user was picked from. A manual
user assignment or a team change between the list read and the claim
now makes the claim a no-op, and the side-effects (webhook, automation,
notification) are skipped. Manual assignment keeps its unconditional
override path.
2026-06-16 12:55:09 +05:30
Abhinav Raut eb6a195aaf feat: add conversation transcript download and CSAT in sidebar
Agents can download a full conversation as a .txt file from the
header menu. The conversation sidebar now shows the CSAT rating and
feedback once the customer responds.
2026-06-02 16:25:33 +05:30
Abhinav Raut 2874e78e97 fix: mark-unread no-op when latest message is a continuity email 2026-05-25 01:59:56 +05:30
Abhinav Raut a502039e59 perf: WS push for conv list, store/cache cleanups, ad-hoc UI polish
Convs and messages now push the full list-row payload to perm-authorized agents on create/assign/message, so livechat returning customers bubble up instantly without waiting for the timer refresh. Background list refresh bumped 30s ->  60s as a drift safety net.
2026-05-22 20:47:36 +05:30
Abhinav Raut edc82e9e55 refactor: drop Casbin, centralize agent cache invalidation, dedupe pending SLAs 2026-05-21 21:24:42 +05:30
Abhinav Raut 43ebed1c3a WS rewrite: per-client subscriptions and perf improvements
Targets broadcasts via per-tab list and open subs (validated at subscribe time)
instead of broadcasting message uuid to all agents. Adds frontend list typing, throttled sound,
and many perf improvements to reduce cpu memory & database queries.
Other fixes: Enforce message-to-conversation binding in handleGetMessage
2026-05-20 23:42:07 +05:30
Abhinav Raut 4e13e72cc3 fix: harden media + conversation queries against empty-uuid casts 2026-05-19 14:13:56 +05:30
Abhinav Raut f6a4ad537f fix auto-replies and csat fanning out to last message's cc list
Both now send to the contact only and carry meta.is_automated so the
reply-box prefill skips them and inherits CCs from the last human message.
2026-05-15 16:16:32 +05:30
Abhinav Raut dce33238e2 exclude inbox reply_to from reply recipients to prevent self-loop 2026-04-24 19:14:55 +05:30
Abhinav Raut 467a62b091 fix snoozed_until leak causing resolved/closed conversations to reopen 2026-04-23 11:36:03 +05:30
Abhinav Raut dd6c8f93a0 add conversation.subject_ref_format config for customizing outgoing email subject marker 2026-04-23 03:11:36 +05:30
Abhinav Raut aa9e4cdae2 feat: add conversation status categories and update related logic.
- Introduced a new category field for conversation statuses to classify them as 'open', 'waiting', or 'resolved'. Which allows max assignment limits in team to work with custom statuses as well.
2026-04-21 16:55:09 +05:30
Abhinav Raut fdb5a507d2 Add 7-day TTL window on visitor-to-contact upgrade via continuity email reply 2026-04-16 12:50:38 +05:30
Abhinav Raut d73a85ffb5 Fix continuity email threading: remove self-reference, drop unused meta field, cap source ID limit 2026-04-15 02:21:41 +05:30
Abhinav Raut c98c87d478 Fix visitor own messages counted as unread; set waiting_since on new conversations 2026-04-13 22:36:02 +05:30
Abhinav Raut 9424db2607 Fix continuity email re-sending same messages 2026-04-13 10:45:58 +05:30
Abhinav Raut d804e365cb Fix continuity email tracking to not reset contact_last_seen_at and exclude continuity messages from unread count 2026-04-13 00:59:16 +05:30
Abhinav Raut edb65650d9 Fix incorrect unread message count when a continuity message is auto sent in conversation
Remove dead widget code
Add config.toml to goreleaser
2026-04-12 03:18:47 +05:30
Abhinav Raut aaff1b1427 assign oldest convos first in auto assigner 2026-04-07 16:32:03 +05:30
Abhinav Raut 6abb6ad017 Move continuity config and intervals to live chat inbox form from toml.
- Refactor widget.js.
- Fix possible race conditions in inbox reload logic.
- Reload only the updated inbox when an inbox is updated / created not all.
- Retain last inbox while navigatin back from admin -> inbox
2026-04-04 21:35:04 +05:30
Abhinav Raut 9c43654021 Add conversation ref number to list conversations api response 2026-04-01 16:16:26 +05:30
Abhinav Raut 5590ae6ae3 Create contact from JWT in widget middleware for visitor merge, fix message input focus and pending cleanup 2026-03-30 00:28:33 +05:30
Abhinav Raut 395a4e80df Refactor ws updates to use direct json payloads instead of prop value pattern.
Add real-time agent availability status updates to widget.

Consolidate multiple WS broadcasts into single calls
2026-03-22 19:34:21 +05:30
Abhinav Raut 34aecd268f Fix widget business hours: use assigned team hours instead of always defaulting, fix timezone offset calculation. Show continuity email indicator in agent UI, broadcast email replies to widget as a user could have widget open and reply from email at the same time. 2026-03-18 10:50:55 +05:30
Abhinav Raut a788553137 Use first unread message as subject for continuity emails, add ref number to continuity email subject.
- Continuity email layout fixes and improvments.
- Replace haikunator with email local part for visitor names, fallback to "Visitor"
- Add optional website_url config field for "go to chat" link in continuity email footer
- Remove unused / unncessary i18n keys.
2026-03-16 00:49:20 +05:30
Abhinav Raut e7ab571c48 add reply guards, gravatar fallbacks for avatars, draft preview in conversation list, clickable agent avatars. Show sent messages immediately instead of waiting for WebSocket response. 2026-03-11 14:52:21 +05:30
Abhinav Raut 678239027e Refactor incoming message flow, add visitor upgrade on email reply, rate-limit livechat conversations 2026-03-11 12:19:58 +05:30
Abhinav Raut eb0a7b437d Add page visit tracking to widget
- fix duplicate initialization guard
- notification bell for agents
- Refactor and clean up dead code
- Fixes to pre chat form
- Add new column country to users table
- Update ratelimit pkg to be generic
2026-03-11 03:52:07 +05:30
Abhinav Raut f0e9266d28 more fixes to LC 2026-01-21 00:13:02 +05:30
Abhinav Raut 107f1adb0d fix issues with threading with widget messages
- fix: live chat email inbox not being initialized.
- make launcher logo take entire launcher space.
- New columns last_interaction_sender_id and last_message_sender_id to track who sent last message in conversation
2026-01-18 13:47:07 +05:30
Abhinav Raut 7958d7e212 Merge branch 'main' into feat/live-chat-channel 2026-01-14 00:33:51 +05:30
Abhinav Raut 91445d7dda Merge branch 'main' into feat-notifications 2026-01-09 01:06:34 +05:30
Abhinav Raut c8bfe36e2e feat: mark conversation as unread from context menu on conversation list 2026-01-07 11:56:51 +05:30
Abhinav Raut aac40f48b9 add type and private message filters to fetch messages api. 2026-01-01 19:41:51 +05:30
Abhinav Raut 1aa2d91432 feat: mentions for private notes
- mentioning an agents sends an email to the agent.
- mentioning a team sends an email to to the entire team.
2026-01-01 13:59:34 +05:30
Abhinav Raut 532cd7f563 feat(navigation): add pluralization for navigation items
feat: make data table item names clickable.

fix(conversation): focus reply box editor on conversation change

fix(conversation): focus editor on tab change in ReplyBoxContent

fix(conversation): update conversation list item to use router-link

fix(conversation): update message bubble to use router-link for author

fix(conversation): update last interaction fields on message insert

fix(conversation): add last interaction fields to conversation model

fix(conversation): update SQL queries to include last interaction fields

feat(migrations): add migration for last interaction fields in conversations

fix(schema): update schema to include last interaction fields in conversations
2025-12-31 12:34:04 +05:30
Abhinav Raut 914bcc1f87 simplify stale draft deletion sql 2025-12-27 17:38:33 +05:30
Abhinav Raut 9c17f98d73 show subject instead of contacts name in previous conversation list
allow previous conversation timestamps to wrap
2025-12-27 14:26:03 +05:30