Commit Graph
165 Commits
Author SHA1 Message Date
Matthew Meszaros 4f9e6e6282 feat: full attribution on every AI credit charge — new actor_user_id + context jsonb columns on the transaction log (migration 000070), a typed models.CreditContext carried via request context (models.WithCreditMeta) so base charges, usage settles, web-search fees, and refunds all inherit it without signature churn, wired at every spend site (campaign switches record campaign/step/contact, automation nodes and Ask AI record automation/node/run and the question asked, reply drafts and inbox agent record the thread, the dashboard agent records the session, research records contact/run, and manual features record the triggering user), rendered as a detail line with token counts in the billing transaction log with corrected reason labels, and documented in the AI credits guide 2026-07-18 08:52:16 +02:00
Matthew Meszaros 163d3057de feat: add web-search and extended-thinking capabilities to the campaign switch AI decider — a per-step web lookup about the contact's company (query derived from contact fields only, results fenced as untrusted, +1 credit charged only when results land, wired through a new tasks SetAISearch) and a thinking toggle that routes to the stronger model tier with a 2048-token budget priced through usage metering, with editor toggles under Capabilities and sequences/ai-credits docs 2026-07-18 08:42:08 +02:00
Matthew Meszaros 053ca6a71d feat: usage-based AI credit system — every AI call reserves its flat minimum then settles the real token cost per model (light 1500/standard 400 tokens per credit, drain-to-zero overage settle wired into writing assistant, reply drafts, dashboard agent, inbox agent, research, automation nodes, and campaign switches), org spend controls in a new org_ai_settings table (day/week/month hard limits enforced in Consume, low-balance alert threshold, auto top-up config), a credit-watch monitor hook that fires BILLING_CREDITS_LOW realtime alerts once per day and buys the configured pack off-session via a new Stripe AutoTopUpCredits (idempotent on the PaymentIntent, bounded per month, Redis-locked), GET /subscription/credits/usage + GET/PATCH settings endpoints, and an AI usage & spend controls billing card (spend vs limits, 30-day chart, per-feature and per-model breakdowns, limits/reminder/auto-top-up form) with a realtime low-credit toast 2026-07-18 08:39:41 +02:00
Matthew Meszaros f36c1a5001 feat: replace the campaign AI step with a Switch step — a multi-way router whose cases are rows on the canvas node, each with its own draggable source dot (per-case ai_label branches wired by handle, retarget on re-drag, purple case edges with no IF boxes, bottom dot as the otherwise fallback), decided per contact by an AI prompt (1 credit, fenced context, same credit lifecycle) or a free deterministic template-value match, with a mode toggle + case list editor (stale case paths healed on save), drag-to-empty-canvas creating the target and wiring the case, and sequences/ai-credits/automation docs rewritten for the switch 2026-07-18 05:42:50 +02:00
Matthew Meszaros 4399bb8e82 feat: collapse the campaign AI step to a prompt plus draggable named outcome paths — the connections drawn out of the step are the choice set (outcome names live on the ai_label branch conditions, deduped per step and read at run time), drop the ai_labels/ai_output_fields/ai_actions config and the whole AI action palette (side effects are ordinary action steps placed on the chosen path), and fence the contact's email, profile fields, and automation event data as untrusted content in every campaign and automation AI prompt so injected instructions inside replies are ignored 2026-07-18 05:18:24 +02:00
Matthew Meszaros 2945974ca7 feat: build the campaign AI step editor and canvas routing — instruction with contact variables, label/output-field lists, an AI action palette reusing the extracted ActionConfigFields with per-action when-hints and AI-picked tag/label choice sets with max-pick caps, what-AI-can-see context toggles, and AI-label connection paths with inline new-label creation that writes the label back to the step 2026-07-17 16:26:50 +00:00
Matthew Meszaros fd2994bdd8 feat: build the automations builder UI for AI branching — an Ask AI (yes/no) condition field with prompt textarea, event-variable chips and credit note, per-label connection routing on AI classify nodes via a node-editor "Route connections by label" section with purple label edges, and stale label-edge healing on save 2026-07-17 16:26:42 +00:00
Matthew Meszaros 1e1e357c06 feat: add a 0-100 deliverability score plus per-provider seed placement and per-domain warmup placement breakdowns to GET /analytics/deliverability, surface them on a customizable deliverability dashboard (toggleable sections + persisted view), and document the new fields in the guides and API reference 2026-07-16 17:55:34 +02:00
Matthew Meszaros 79c43e2168 feat: add free_model to the agent stream event and transcript client types 2026-07-15 18:52:07 +02:00
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 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 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 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 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 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 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
Matthew Meszaros a72addabeb feat: add OAuth app webhook configuration with an event picker, signing-secret reveal and rotate, per-org installs, and a cross-org delivery log 2026-06-15 08:11:35 +02:00
Matthew Meszaros d655ff4f59 feat: add the webhooks settings page with delivery observability, an onboarding setup step, and the webhook API client, hooks, and models 2026-06-15 08:11:35 +02:00
Matthew Meszaros c5dfa5e4e7 feat: remove the HTTP-request action from campaign steps and automations in favor of signed webhooks, keep fire_event for custom payloads, and drop the now-unused outbound quota plumbing 2026-06-15 08:11:35 +02:00
Matthew Meszaros fcafac4195 refactor: remove the campaign 'notify (webhook)' step type now that the HTTP request step covers outbound calls and there is no webhook setup surface 2026-06-14 10:48:06 +02:00
Matthew Meszaros ab24d8bbc8 feat: add a 'Fire event' action and campaign step that publish custom events to the realtime gateway (no public URL), an HTTP-request campaign step, a configurable automation dry-run test with per-step toggles, and fix the false 'updated by a teammate' toast on your own save 2026-06-14 09:52:49 +02:00
Matthew Meszaros e3c49fe571 feat: move the OAuth apps developer portal into Settings with a multi-step registration onboarding wizard (stepper, animated modal, logo upload) and an animated apps/authorized tab switch 2026-06-14 09:52:49 +02:00
Matthew Meszaros b06a11315f feat: add the OAuth 2.1 dashboard UI: an OAuth apps page (register apps with a scope picker, one-time client secret, rotate, delete, authorized-apps tab with revoke) and a standalone consent screen at /oauth/authorize, plus the API client, hooks, and sidebar entry 2026-06-13 14:07:21 +02:00
Matthew Meszaros 501b5009b4 feat: add an on-error branch to automation action nodes (try/catch routing, rose on-error handle, executor follows the error edge and treats the failure as handled instead of failing the run) 2026-06-13 13:15:41 +02:00
Matthew Meszaros 977daf8a01 feat: surface the inbound webhook trigger in the automations builder with a copyable per-automation webhook URL and caller-defined payload conditions 2026-06-13 13:08:04 +02:00
Matthew Meszaros 534928cfdd feat: add a safe Set-variables (transform) automation node — computes named values from Go templates against the event + prior step output and writes them back for later steps to reuse, running the same sandboxed text/template engine as every other action value (no I/O, no arbitrary code execution) 2026-06-13 12:18:45 +02:00
Matthew Meszaros dfdb304033 feat: add the HTTP request / webhook node to the automation builder — method/url/headers/body/output-key editor, registered in the action picker with a globe glyph, surfacing how to read the response in later steps and branch on {{.response.ok}} 2026-06-13 12:07:04 +02:00
Matthew Meszaros aed4a06190 feat: unify pagination by making the offset-based CRM deals/tasks search and meetings endpoints expose the same opaque next_cursor and {total, next_cursor, has_more} envelope as every keyset list (offset hidden inside the token), updating web clients, the OpenAPI spec, and the reference docs 2026-06-13 10:47:17 +02:00
Matthew Meszaros 587eae774e feat: serve the entire customer API (auth + resources) only under /v1 with no unversioned alias, and repoint the web and admin clients to the versioned base accordingly 2026-06-13 07:18:23 +02:00
Matthew Meszaros 71abb12a38 feat: stop campaigns silently stalling on a transient scheduler error by retrying instead of completing the task, end past-end-date campaigns cleanly, record scheduler failures to the campaign log, add a campaign-chain reconciler, and surface failures live in the dashboard activity panel 2026-06-13 06:27:01 +02:00
Matthew Meszaros 13e7663b03 feat: add the label_email action to the web action models — the campaign label_ids field plus the automation NATIVE_ACTIONS/labels/needs entries and a triggerCarriesThread reply-trigger gate 2026-06-12 16:44:29 +02:00
Matthew Meszaros aba0878833 feat: replace the per-node amber if-dot with a single output dot that opens a drag-drop create menu (email, action, or condition) on release, and add a Condition router node (kind wait) you can chain into nested decision trees 2026-06-12 09:51:11 +02:00
Matthew Meszaros a7a43e0c4c feat: rename the campaign sequences resource to steps across the API and URL (/campaigns/:id/steps), the JSON fields (target_step_id, step_id/step_name/step_index, analytics steps[], create body steps), the web client/models/route segment/labels, the audit step entity type, and the wire-contract docs; internal Go type names and the Kafka avro schema stay 2026-06-12 09:38:11 +02:00
Matthew Meszaros 6e9f2b4807 feat: add a Team presence section to workspace settings with admin-gated Show who's online and Show activity toggles, and make ToggleRow support a controlled persisted mode 2026-06-12 05:59:01 +02:00
Matthew Meszaros a0221dd312 feat: show one clear, app-wide 'you don't have permission' popup whenever a write action (edit/save/delete) is denied with 403, naming the missing permission or plan, instead of silent failures and generic error toasts across the dashboard 2026-06-11 18:30:53 +02:00
Matthew Meszaros 5bcc2baaa8 feat: implement the coming-soon security features — logged-in change-password (verify current, policy-checked, POST /me/password) with a real dialog, and new-device sign-in alerts (security notification category fired from the token service on an unrecognized OS+browser, delivered in-app and by email), removing the comingSoon stub helper and updating docs 2026-06-11 12:30:44 +02:00
Matthew Meszaros 160dc0bc76 feat: implement the coming-soon notification delivery channels — Email (SES/SMTP to the account email) and Slack (posts to the org's connected workspace via a new integration NotifySlack), wired in both backend and consumer with per-channel gating, real toggles replacing the coming-soon labels, and updated docs 2026-06-11 12:21:48 +02:00