How it is built
A Node.js orchestrator streams each turn to the browser over WebSockets. Before the main model call, a cheap intent classifier picks one domain (publishing, analytics, engagement, ads, content, calendar, team and more) so only that domain's tools are loaded; capabilities the user names by keyword are pinned on top. This keeps tool definitions from eating 40–50% of input tokens.
The system prompt is built in three cacheable layers: frozen voice rules, a capability summary derived from the tool registry, and session context (workspace, channels, date range, brand voice, user preferences). Conversation history is windowed per turn. Provider adapters for OpenAI, Anthropic and Gemini sit behind one client with timeouts, bounded retries and stream guards.
Answers are grounded in the workspace's own data: connected channels, recent posts, saved brand voice, uploaded brand guidelines and a rolling "learnings" memory of what performed. A per-plan quota service gates turns and image generation.
What I shipped on it
Brand logo on carousel slides
Brand profile gained a Logo upload (PNG/JPG/WebP, 5 MB) and an "Add logo to carousel slides" switch. When on, the renderer composites the real file bottom-right on every slide with sharp, keeps that corner clear in the image prompt, and never asks the model to draw a logo. The switch is tied atomically to a stored logo, and Switch's session context carries the logo state so it never over-promises.
Self-hosted brand fonts
A workspace can pick a non-Google brand font and have it render on designed posts and carousel overlays, applied by the browser over a text-free AI background rather than baked by the image model.
Workspace-scoped chat history
History lists the selected workspace by default; "All my chats" lists every workspace the caller can still open. Every id route re-checks current workspace access (404 otherwise) and a chat only takes turns in its origin workspace (409 on mismatch). Chats are private to their author. Shipped behind a server-evaluated flag with the account-wide list as rollback.
Rename chats
Inline rename on the history rail with optimistic update, rollback and an inline error on failure.
Plan-aware quotas
Trials sold as subscriptions had no plan document, so turns fell to the free tier and image caps to zero. Plan lookup now resolves TRIAL_X to X and still fails closed on unknown plans.
Prompt grounding facts
Switch told users sentiment could not be edited and that no sentiment chart existed; both were false. Added the facts to the system prompt, bumped the prompt version and left a spec so the bullet cannot silently disappear.
What changed
No more hand-placed logos
Agencies get branded slides from a chat message, at no extra image credits.
Tenant isolation
A chat can never be opened or continued from another workspace.
Correct entitlements
Trial customers get the quota they paid for; unknown plans still fail closed.
Fewer wrong answers
Product facts live in the prompt with regression specs, not in the model's guess.
Want the rest of the work?
Analytics suite, sentiment analysis, Brand Dashboard, MCP and n8n.
