Commit Graph
383 Commits
Author SHA1 Message Date
Matthew Meszaros 684152d699 feat: add the agent transcript client and hydrated turn and block types used to rehydrate a reopened assistant conversation 2026-07-15 17:54:16 +02:00
Matthew Meszaros a3e27c77da feat: add an AI agent workspace store slice holding per-tab conversations, the active tab, and expand state so assistant chats survive the panel closing 2026-07-15 17:54:16 +02:00
Matthew Meszaros fd36061901 feat: make the campaign live-activity empty state status-aware so a finished campaign reads as all caught up instead of waiting for the next send 2026-07-15 17:54:03 +02:00
Matthew Meszaros e7414f9f3b feat: surface the Done lead status in the campaign Leads table pill and the progress strip as a distinct indigo state 2026-07-15 17:54:03 +02:00
Matthew Meszaros a0f92ab284 feat: sidebar live panel shows a connected-but-quiet workspace as green READY with a solid halo and an active one as pulsing LIVE, leaving gray only for a real disconnect so IDLE no longer looks offline 2026-07-15 17:54:03 +02:00
Matthew Meszaros a6ccd90090 feat: lock plan-gated sidebar tabs and pop an upgrade dialog on click - a feature the org's plan doesn't include now renders a locked, dimmed sidebar row (lock icon + plan badge) that opens an access dialog on click instead of routing to a teasing empty upsell page, mirroring how permission-gated tabs already lock and pop AccessLockedDialog; the dialog gains a plan variant (sparkle, 'X is on the Starter plan', Upgrade CTA to billing for owners / 'ask the owner' for everyone else) so every no-access sidebar tab - by role permission or by plan - consistently locks and explains itself 2026-07-15 07:04:00 +02:00
Matthew Meszaros aa6a6a8525 feat: show the recipient address on the inbox-agent draft card so a reviewer sees who the suggested reply will go to before approving and sending 2026-07-14 07:33:09 +02:00
Matthew Meszaros 56de65380b feat: inbox agent that drafts a suggested unibox reply on inbound human replies for human approve/edit/discard - paid + per-org opt-in (organizations.inbox_agent_enabled) feature where the consumer's reply hook, on a non-automated reply, detaches a goroutine (panic-contained, never blocks ingest) that checks entitlement, dedupes via ai_thread_drafts partial unique indexes (one pending per thread, unique source_message_id), pre-checks balance, grounds a reply in the thread history + org voice + skills via generation.Provider.Complete, reserves a draft row then charges 5 credits (idempotency inbox_agent:<draft.ID>, row unwound on a fresh context if the charge fails so no unpaid draft lingers), and emits an org-scoped AI_DRAFT_READY event gated on access_unibox; the agent never sends - only a human POST to /unibox/agent-drafts/:id/approve sends through the normal reply path, claiming pending->approved before send with an approved->pending revert on send failure, alongside list + discard endpoints; plus the unibox awaiting_agent_draft badge + agent_drafts search scope, an AgentDraftCard in the thread view with inline-editable approve-and-send/discard, the workspace settings opt-in toggle, CanUseInboxAgent paid gate, migration 000065, and docs (inbox-agent guide, endpoints, realtime) 2026-07-14 06:13:27 +02:00
Matthew Meszaros a067bf5922 feat: AI action nodes in automations - ai_classify/ai_extract/ai_generate run one generation.Provider completion per node over the event data and merge the result back as a variable (ai_class, output_keys[], ai_text) so downstream conditions branch on it, charging 1 credit per node with a run_id+node_id idempotency key, refund on provider failure, out-of-credits fails only that node while the run continues, and a per-automation ai_credit_failures counter (migration 000064) auto-pauses a flow after 20 consecutive credit misses; classify/extract run deterministic (temperature 0), dry-run executes AI nodes for real and is charged but never touches the auto-pause lifecycle, provider + credit ledger wired into both backend and consumer integration services, plus the reply-classifier Layer 3 ported off its bespoke OpenAI client onto the platform provider via an injected ModelClassifyFunc (platform-paid, deterministic), a CompletionRequest.Temperature primitive threaded through the OpenAI and Anthropic providers, the flow builder palette/config panels/validation for the three AI steps, and a new AI-steps-in-automations guide 2026-07-14 05:30:55 +02:00
Matthew Meszaros 2aec6745fa feat: connect external MCP servers whose tools the AI assistant can use - ai_mcp_servers table with bearer tokens sealed by the org DEK cipher (never returned) and SSRF-validated https urls, a dependency-free streamable-HTTP JSON-RPC client (initialize/tools/list/tools/call over safehttp dial-time IP blocking with SSE+JSON handling and body caps), an mcp service that discovers tools on connect and contributes only enabled servers' tools to the dashboard agent as namespaced mcp_<server>_<tool> defs that are always write-class and never auto-allowed, a registry DynamicToolSource hook so per-org tools join the agent's tool set and resume executes them through ToolDefs, /ai/connections CRUD gated on manage_settings with an mcp_server audit entity and spine, a Connections settings page to add servers and review/enable discovered tools, and docs 2026-07-13 20:05:24 +02:00
Matthew Meszaros a2f50b6572 feat: org AI skills (playbooks) that every AI feature loads and follows - ai_skills table (org-scoped, unique name per org, 32KB content cap) with a skills service exposing CRUD plus an enabled-skills preamble injected into the dashboard agent, contact research, and reply-draft prompts and a load_skill read-tool that returns a playbook's full content by name, /ai/skills CRUD gated on manage_settings (JWT) or the AI_AGENT scope (API) with an ai_skill audit entity and spine entry, an AI skills settings page (list rows opening a right-side drawer with name, one-line description, enable toggle, and a markdown body), and docs with two example playbooks 2026-07-13 19:46:25 +02:00
Matthew Meszaros f48d51bf16 feat: AI contact research agent that gathers cited web findings per contact with sync and background-batch runs - contact_research_runs table plus a strict save_research schema (every signal and public_artifact must carry a url, confidence high/medium/low, signals<=5 hooks<=3, reject-and-reprompt once then fail), a text/template runtime prompt injecting org voice, contact record, objective, and 5-search/6-fetch budgets, a research service that drives search_web/fetch_url through the provider loop and charges 2 credits on save (billable even for nothing_found, refund-free since charged only on save, balance and abuse-cap pre-checked so a capped org never does free work), POST/GET /contacts/:id/research plus a 500-cap /contacts/research/batch draining through a bounded pool of 4 workers over FOR-UPDATE-SKIP-LOCKED claims (no new Kafka), an org-scoped AI_RESEARCH_PROGRESS realtime event gated to view_contacts, APIPermAIResearch bit 23, a ContactEdit Research tab and a ContactsTable bulk Research action, and docs; also org-scopes every credit and research idempotency key so a client-supplied Idempotency-Key can never replay across tenants 2026-07-13 19:34:11 +02:00
Matthew Meszaros 8d208d8c41 feat: org voice profile grounding every AI writing surface plus context-grounded unibox reply drafts - organizations gains product_description/icp_notes/voice_profile (000059) with a manage_settings workspace settings section, generation.BuildVoiceRules and BuildReplyRules fold the humanizer rules and org grounding into every prompt, WritingGenerator.GenerateWriting now takes a VoiceContext and a provider.Complete primitive powers single completions, POST /unibox/reply/draft assembles thread history plus the counterpart contact (custom fields and campaigns) plus the voice profile into a reply-tuned prompt that charges 2 credits with refund-on-failure and a client idempotency key and never sends, a Draft reply button fills the composer, and docs cover the voice profile and AI reply drafts 2026-07-13 19:04:57 +02:00
Matthew Meszaros 7f425c1624 feat: dashboard-wide AI assistant with streamed tool-use runs, per-action approvals, and per-iteration credits - agent_sessions/agent_messages/ai_tool_policies migration, aiagent service runs the M2 registry through the provider loop over a resumable jsonb transcript, streams text/tool-step/approval/done events over SSE, gates write tools behind approve/deny/always-allow (send always per-action) and charges 1 credit per iteration (budget 20, refund on provider failure, out-of-credits 402 insufficient_credits, cap 429 usage_cap_exceeded) with a resume-safe idempotency namespace, provider PreIteration budget hook, /ai/sessions endpoints (cursor list + two SSE runs) gated by membership with tools bound to the member's org-permission bits, APIPermAIAgent bit 22, ai_session audit entity + spine, and a right-side resizable panel (Cmd+I / sparkle button) with streamed text, collapsible tool steps, inline approval and draft-artifact deep-link cards, stop, new chat, and a credits/budget meter; tenancy enforced at the SQL layer and docs for the assistant, endpoints, permissions, and error codes 2026-07-13 18:46:43 +02:00
Matthew Meszaros 5d6ed2a068 feat: AI credit economy with monthly plan grants, non-expiring purchased top-ups, and Stripe billing - two-pool credit_ledger (monthly allowance reset each cycle on invoice.paid, purchased pool via checkout mode=payment fulfilled webhook-only), consume drains monthly-then-purchased, 3 fixed top-up packs, /subscription/credits balance+checkout+paginated transactions gated on manage_billing, one-time trial grant, billing credits card with balance ring and pack buttons, credit_purchase/credit_grant audit entities and spine, wired plan.monthly_credits through pg_plan reads/writes, retry-safe webhook idempotency, and an AI credits guide 2026-07-13 17:40:20 +02:00
Matthew Meszaros d6b7885e8b feat: mobile push notifications end to end - APNs provider-token client, device_tokens table with session-scoped register/delete endpoints, a push channel in notification preferences (web + iOS toggles), and Redis-backed immediate-then-digest batching (first event pushes now, bursts summarize when the 5h window closes) wired in backend and consumer, with iOS registration/badge sync and docs for the channel, endpoints, and APNS_* deploy env 2026-07-13 16:11:15 +02:00
Matthew Meszaros cc0871d1b8 feat: contacts search gains an additive lead_status filter plus per-status lead_counts on the first page when exactly one campaign_id is set - the SQL predicates reproduce the read-time status derivation exactly (unsubscribed > bounced > replied > active > pending via LATERAL bool_or rollups), invalid lead_status or multi-campaign combinations return 400, and the web types/table pick up the new lead_counts shape 2026-07-11 10:11:36 +02:00
Matthew Meszaros c311529576 feat: guard cursor chat against IME composition keys, keep a sent message lingering through an incidental blur, broadcast chat typed while the pointer is off the tracked surface, and close the input on page navigation 2026-07-02 20:33:44 +02:00
Matthew Meszaros 226e83683c feat: remount the automation and sequence canvases on param-only navigation and restrict jump-to-teammate to distinct in-app paths so a jump can never save one record's graph into another 2026-07-02 20:33:44 +02:00
Matthew Meszaros f804538ff5 feat: make canvas selections self-healing with a receiver-side TTL, a heartbeat that retries unsent deselects, and a clear frame for the old surface on in-place resource changes 2026-07-02 20:33:44 +02:00
Matthew Meszaros 954759a6ce feat: make each teammate in the header presence dropdown clickable to jump straight to the page they are on 2026-07-02 07:40:07 +02:00
Matthew Meszaros 9f2b5d5586 feat: show each teammate's selected cards on the automation and sequence canvases as a name-tagged outline in their cursor color, with a selection heartbeat for late joiners and an unmount clear, plus cursor chat on both canvases 2026-07-02 07:40:06 +02:00
Matthew Meszaros b1e68b3048 feat: add cursor chat to every collaborative surface, press / to type a message that floats next to your live cursor for teammates, riding the existing cursor frames with Enter-to-send and a linger-then-fade 2026-07-02 07:40:06 +02:00
Matthew Meszaros c21f170429 fix: ignore live:patch frames in useLivePatch when the subscriber has no resource yet, instead of receiving every org patch 2026-06-30 19:20:08 +02:00
Matthew Meszaros b85d2c8249 feat: refresh the deal board instantly when a teammate edits the pipeline's stages and show a live colored ring on a deal card while a teammate drags it 2026-06-30 19:18:55 +02:00
Matthew Meszaros 7f5cc010bb feat: broadcast CRM pipeline and stage edits over live:patch and refresh the pipelines view instantly for teammates 2026-06-30 19:18:55 +02:00
Matthew Meszaros a93868fc77 feat: broadcast CRM task create/update/delete over live:patch and refresh the tasks view instantly for teammates ahead of the audit refetch 2026-06-30 19:18:55 +02:00
Matthew Meszaros c1ad213dda feat: make useLivePatch send-only when given no onPatch so mutation hooks can broadcast a live:patch without opening a channel subscription 2026-06-30 19:18:55 +02:00
Matthew Meszaros 2e110814fc feat: make CRM deal-board stage moves land instantly for teammates on the same pipeline via a live:patch broadcast backed by the audit refetch 2026-06-30 10:34:14 +02:00
Matthew Meszaros cca4ea5817 feat: add a reusable useLivePatch hook over the live:patch transport for optimistic collaborative state updates scoped by resource 2026-06-30 10:34:14 +02:00
Matthew Meszaros 18fd48bfcb feat: render teammate avatars with initials fallback on live cursors so it is always clear who each pointer belongs to 2026-06-30 10:34:14 +02:00
Matthew Meszaros dfe8b89730 feat: claim integration-connection presence via a new Drawer headerExtra slot in the connection details drawer 2026-06-30 10:06:49 +02:00
Matthew Meszaros 5f090287c8 feat: claim mailbox presence and show teammate viewers in the mailbox details drawer header 2026-06-30 10:06:49 +02:00
Matthew Meszaros aef7fdf6d5 feat: claim template presence and suppress the page cursor layer while the email template editor is open 2026-06-30 10:06:49 +02:00
Matthew Meszaros e1f9460520 feat: claim task presence and suppress the page cursor layer while the CRM task dialog is open 2026-06-30 10:06:49 +02:00
Matthew Meszaros 04ee4cb331 feat: claim deal presence and suppress the page cursor layer while the CRM deal dialog is open 2026-06-30 10:06:49 +02:00
Matthew Meszaros 06c7a3502b feat: wire live cursors, live step drag, and persisted step positions seeded from x/y into the campaign sequence builder canvas 2026-06-30 10:06:49 +02:00
Matthew Meszaros 03453cc069 feat: wire live cursors, live card drag, and debounced drag-to-stick layout persistence into the automation builder canvas 2026-06-30 10:06:49 +02:00
Matthew Meszaros 4111a1960b feat: skip ephemeral LIVE_ frames in useRealtimeEvents so cursor and drag traffic never triggers react-query invalidation 2026-06-30 10:06:31 +02:00
Matthew Meszaros ba6847e985 feat: add the global per-route multiplayer cursor layer with a suppression context and mount it in AppShell around the page scroll container 2026-06-30 10:06:31 +02:00
Matthew Meszaros 49988fb8bd feat: add shared Cursor and CanvasCursors presence components that render teammate pointers in screen space and @xyflow flow space 2026-06-30 10:06:31 +02:00
Matthew Meszaros 4ca46317a5 feat: add the reusable useLiveCursors transport (throttle, heartbeat, TTL prune, gone-on-leave, gone-on-resource-change) and a useLiveCanvas wrapper that adds the live node-drag stream 2026-06-30 10:06:31 +02:00
Matthew Meszaros b618a9d6d4 feat: widen the billing compare-plans grid to the full settings panel (sm two / xl four columns) so all four plan cards fit comfortably 2026-06-28 05:58:31 +00:00
Matthew Meszaros bbc07be875 feat: default the settings Section primitive to a stacked full-width layout and keep the title-rail look as an opt-in split layout so wide content is no longer squeezed into a narrow column 2026-06-28 05:58:31 +00:00
Matthew Meszaros 2f4e4f7ee6 feat: bound the settings layout to its container height so the left rail and content panes scroll internally instead of sliding under the sticky Settings topbar 2026-06-28 05:58:31 +00:00
Matthew Meszaros db94ce0c47 feat: capture the ?ref= referral code in the web signup flow and thread it through registration 2026-06-28 05:10:04 +00:00
Matthew Meszaros faad54b6a3 feat: add a redeemed promo codes table to the web billing settings page with its client, hook, and model 2026-06-28 05:10:04 +00:00
Matthew Meszaros 8aec22ba71 feat: invalidate referral query keys on the referral and referral_credit realtime audit events in the web spine 2026-06-28 05:10:04 +00:00
Matthew Meszaros ae09a1646c feat: build the dashboard referral settings page with its API clients, hooks, models, and route registration in web 2026-06-28 05:10:04 +00:00
Matthew Meszaros 38e9ca980f fix: correct the dashboard /auth/me avatar and password endpoints, guard self-row actions on the members page, align the steps-page permission gate with the server, harden realtime event handling, and remove the dead admin roles client 2026-06-15 08:12:35 +02:00