Matthew Meszaros
273dd7ce33
feat: merge main (deliverability auth-state sweep, watch-band cold throttle, research roadmap) plus the 000067 email-auth-state migration renumber into the campaign AI step branch
2026-07-17 18:29:06 +02:00
Matthew Meszaros
d18c5ebe4a
feat: execute campaign AI steps in the scheduler path — one metered completion per contact (SetAI-wired provider + credits with per-step idempotency and refund-on-failure) that labels progress, fills contact custom fields which feed the chosen actions' templates, runs AI-picked pre-configured actions with per-decision campaign logging and tag/label choice resolution, grounds decisions in campaign history and the newest inbound reply via LatestInboundFromContact, and hands instant chains back to the scheduler at AI nodes
2026-07-17 16:26:23 +00:00
Matthew Meszaros
cd5e1e9cf7
Merge pull request #72 from warmbly/research/warmup-abuse-cold-effectiveness
...
feat: deliverability research + observe-only SPF/DKIM/DMARC auth state and watch-band cold throttle
2026-07-17 05:29:58 +02:00
Matthew Meszaros
d0e8bc1c97
feat: add one-command MCP OAuth connect on api.warmbly.com/v1/mcp — RFC 7591 dynamic client registration for public PKCE clients (dcr.go), RFC 9728 protected-resource metadata + WWW-Authenticate challenge via MCPAuthMiddleware, /v1/mcp now accepts an API key or OAuth token, public-client auth with no secret and mandatory PKCE reusing the existing OAuth 2.1 server (nullable-org clients, migration 000066), executable-redirect-scheme hardening on the open register endpoint, plus mcp/oauth/authentication/endpoints docs
2026-07-16 08:57:19 +02:00
Matthew Meszaros
29e3bb3a64
feat: drop the legacy OPENAI_*/ANTHROPIC_API_KEY/AI_LOCAL_MODEL env fallbacks (no prod deployments exist): AI_PROVIDER/AI_API_KEY/AI_MODEL/AI_BASE_URL/AI_FREE are the only AI vars, empty provider means openai, the anthropic preset and writing client key off AI_API_KEY, and the warmup Batch generator runs only when the selected provider is OpenAI
2026-07-16 06:39:06 +02:00
Matthew Meszaros
917451b105
feat: select the AI provider via AI_PROVIDER + AI_* vars in the backend and consumer (legacy OPENAI_*/ANTHROPIC_API_KEY still honored as fallbacks), logging a clear message when the provider is misconfigured
2026-07-16 06:14:19 +02:00
Matthew Meszaros
d94bd70f88
feat: wire AI_LOCAL_MODEL into the backend and consumer provider config and pass the agent voice preamble into the dashboard agent service
2026-07-15 18:51:51 +02:00
Matthew Meszaros
78ff73e45c
feat: ground inbox-agent reply drafts in the counterpart contact's CRM record - the inbox agent now folds the replying contact's name, company, and known custom fields into the draft prompt (mirroring the manual unibox reply draft) via an optional ContactReader wired from repository.ContactRepository in both the backend and consumer, best-effort so a lookup miss just drops the grounding, so suggested replies reference what Warmbly already knows about the person
2026-07-14 07:29:56 +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
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
6ad2f13a39
feat: shared AI tool registry (internal/app/aitools) that runs 16 permission-gated tools as the invoking user over existing service-layer calls - Registry+Invocation enforce org-permission bits (JWT) or API-key bits per tool, ToolDefs binds handlers into the provider agent loop and Call powers direct MCP invocation; tools cover contacts (search/get/update/add_tag/remove_tag), CRM (create_task/create_deal), campaigns (list/stats/create_campaign_draft), unibox (list_threads/get_thread/draft_reply, gated on CanUseUnibox, draft never sends), create_automation_draft (disabled), and web search_web + fetch_url (webhook SSRF validator + safehttp dial-block + 2MB cap + html-to-text + 15min Redis cache + rune-safe truncation); every write audits via AuditService.LogAction so the spine refreshes teammates, registry built once in main and exposed on the handler for M3/M8
2026-07-13 18:15:58 +02:00
Matthew Meszaros
e07c33d3cd
feat: provider-agnostic LLM agent-loop layer (OpenAI-first, Anthropic self-host connector) with RunAgent tool-use loop, approval/resume contract, pluggable web search, and extracted voice-rules builder - generation.Provider.RunAgent executes Go tool handlers over a resumable transcript with a read-auto/write-approve gate, openAIProvider drives it via a lean HTTP client retargetable with OPENAI_BASE_URL for any OpenAI-compatible endpoint and also serves the writing assistant, anthropicProvider mirrors it with tool_use/tool_result multi-turn plus hosted web_search, NewProvider prefers OPENAI_API_KEY, SearchClient supports Serper/SearXNG with a clean not-configured error, and BuildVoiceRules extracts the humanizer prompt for reuse; refreshed stale model ids to sonnet-4-6 and haiku-4-5
2026-07-13 17:52:09 +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
b9a99f91a9
Merge pull request #67 from warmbly/feature/ios-realtime-steps-preview
...
iOS realtime parity, richer sequence preview, and mobile push notifications
2026-07-13 16:15:18 +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
262d25779c
feat: realtime admin dashboard + diagnosability - new Elixir admin:platform channel (JWT-only, gated on users.admin_permissions) mirrors every platform event, the admin app connects through a /getaway-tokenized Phoenix socket client with a throttled react-query invalidation spine, a Live Events firehose page streams the platform with filters/pause/JSON expand, a System Status page runs parallel infra probes (postgres/redis/kafka/schema-registry/realtime/tracking via /admin/system/status), and the worker logs viewer gains follow mode, line-count selection, and copy
2026-07-12 09:00:10 +02:00
Matthew Meszaros
48ec53d781
feat: add the sandbox seeder and simulator (cmd/sandbox, internal/sandbox) - seeds the Sunrise Labs showcase org (paid plan, six live mailboxes with sealed mailpit/dovecot credentials, active tracked campaigns, pre-verified contacts, warmup pool membership) and repairs every fixture smtp_imap account and .test contact; the simulator plays the internet by polling mailpit, appending mail into dovecot inboxes for the real IMAP sync to pick up, hitting tracking pixels and click tickets, and replying as hash-stable contact personas with correct In-Reply-To threading
2026-07-11 17:31:42 +02:00
Matthew Meszaros
6bc2073379
feat: honor CODEC_PROVIDER=json across backend and consumer (previously worker-only) and round-trip untyped event bodies into their typed payloads in both dispatchers - the worker command/result envelopes carry any-typed bodies that Avro cannot serialize, so worker messaging only works on the JSON codec; also wires the credentials encrypter into both mains
2026-07-11 17:31:02 +02:00
Matthew Meszaros
a20ba926cb
feat: add native Apple/Google sign-in to the backend - POST /auth/apple and /auth/google exchange provider-signed ID tokens for sessions, GET /auth/providers exposes configured providers for app discovery, with a JWKS-verifying idtoken package, auth config, stable error codes, and API/security docs
2026-07-07 05:56:35 +02:00
Matthew Meszaros
cb13c65d5d
feat: load active mailboxes onto their assigned workers via a backend reconciler and immediately on onboarding, decrypting each account's credentials into the AddWorkerEmail payload, fixing gmail/outlook/smtp accounts that were assigned but never loaded
2026-07-04 08:07:49 +02:00
Matthew Meszaros
52c5f224fa
feat: rebuild the provider oauth2 config locally on the worker so delegated mailbox tokens refresh, and ship BOX_ google/outlook client credentials to provisioned workers through the orchestrator env
2026-07-04 08:07:49 +02:00
Matthew Meszaros
eb0a5654fd
feat: persist the opaque per-folder Graph delta cursor in a new email_delta_links table via a repository and a GRAPH_DELTA_UPDATE consumer handler wired into the consumer service
2026-07-04 08:07:49 +02:00
Matthew Meszaros
ffe823cfa8
feat: persist and surface per-mailbox SPF/DKIM/DMARC authentication state via an hourly observe-only consumer sweep, threaded through the mailbox list/detail API and documented in the deliverability guide and mailboxes API reference
2026-07-01 02:32:23 +00:00
Matthew Meszaros
f49816a7b1
feat: construct and bidirectionally wire the referral service into the backend bootstrap
2026-06-28 05:09:50 +00: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
660d717456
feat: register the webhook and oauth-app-webhook routes and wire the delivery worker, audit-to-webhook bridge, and app domain resolver into the backend
2026-06-15 08:11:20 +02:00
Matthew Meszaros
8c175d4221
feat: add an OAuth 2.1 authorization server (migration 000047 apps/codes/grants, app registration CRUD, authorization-code-with-PKCE authorize+token+refresh-rotation+revoke endpoints, RFC 8414 discovery, bearer-token validation wired into the auth middleware reusing the API-permission gates, scopes mapped to API permission bits)
2026-06-13 13:56:39 +02:00
Matthew Meszaros
20935ef061
feat: add a nil-safe per-org daily outbound-action quota (Redis daily counter, anti-abuse ceiling on the HTTP-request automation node, wired in both backend and consumer, fail-open) to bound webhook relay abuse
2026-06-13 13:41:20 +02:00
Matthew Meszaros
7901e9a92c
feat: wire the Pub/Sub realtime provisioning, the instant-branch automation runner, and the campaign-chain reconciler into the backend and consumer binaries
2026-06-13 06:27:06 +02:00
Matthew Meszaros
ba89a932cd
feat: run the label_email action on reply — campaign instant and scheduled paths via advanced LabelThread/LabelLatestThreadForContact, automations via execNativeAction reading thread_id and _user_id from the reply payload — and move the native-actions adapter to a shared package wired into the consumer too so reply/bounce/warmup automation actions stop silently failing
2026-06-12 16:44:16 +02:00
Matthew Meszaros
ba3ab98e1e
feat: bridge realtime events over Redis pub/sub when Google Pub/Sub is unconfigured (RedisBus publisher in backend/consumer plus Realtime.Redis.EventSubscriber and a shared EventBroadcaster) so dashboard live updates and presence-driven collaboration actually fire in local dev
2026-06-12 04:49:58 +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
Matthew Meszaros
8732805934
feat: replace signed click redirects with server-side link tickets (tracked_links store, internal resolver API, opaque /c/<id> URLs, layered anti-probe caches with miss budget and circuit breaker) removing TRACKING_LINK_SECRET entirely
2026-06-11 09:30:21 +02:00
Matthew Meszaros
2c5e8b2cbd
feat: make TRACKING_LINK_SECRET a required boot-time secret on backend and tracking service with no unsigned mode and no rotation grace, so rotating the key revokes old links immediately
2026-06-11 09:00:04 +02:00
Matthew Meszaros
abdfd05c34
feat: org-scope realtime events (inbox, campaign, tracking, account health) and emit EMAIL_SENT/EMAIL_REPLIED/EMAIL_DELETED pulses so the whole team's dashboard updates live
2026-06-11 07:43:57 +02:00
Matthew Meszaros
4013b33008
feat: expose security notification APIs
...
Wires notification and two-factor services into the backend and consumer, adds the authenticated notification feed/preferences endpoints, and exposes the public 2FA login verification endpoint.
2026-06-08 15:04:47 +02:00
Matthew Meszaros
5f7ac801ba
feat: execute automation graphs
2026-06-08 12:03:11 +02:00
Matthew Meszaros
e6b2f233a1
feat: expand integration and meeting APIs
2026-06-08 06:25:40 +02:00
Matthew Meszaros
51c99458ad
feat: fire instant actions from tracking events
2026-06-07 17:24:32 +02:00
Matthew Meszaros
051ae73fd2
feat: resolve named sender contacts
2026-06-07 07:54:02 +02:00
Matthew Meszaros
62da3c3e3d
feat: add organization teams API
2026-06-07 07:03:49 +02:00
Matthew Meszaros
ab82cacbff
feat: run migrations before seeding
2026-06-07 07:03:21 +02:00
Matthew Meszaros
da82993846
feat: add campaign workflow backend support
...
Add sequence action-node storage and execution, template conditional rendering, lead progress state, profile updates, webhook fan-out throttling, and supporting repository fixes.
2026-06-06 07:49:52 +02:00
Matthew Meszaros
3c440a9f0c
feat: add campaign attachment endpoints
...
Persist campaign attachment metadata, enforce attachment storage quotas, and expose list, upload, and delete routes backed by object storage.
2026-06-05 06:03:13 +02:00
Matthew Meszaros
d6f055da19
feat: add lead sync backend
2026-06-04 11:49:55 +02:00