Area: mobieusAI (audit p11) · Surface: mobieusAI Q&A drawer (POST /api/ai/assistant/ask) · Dimension: competitor-gap · Severity: major
Every major AI competitor streams tokens as they generate. Intercom Fin, Zendesk AI agent, and Circle/Skool AI helpers all render the answer word-by-word so the user sees progress within ~500ms. mobieusAI instead blocks for the full completion (up to 700 output tokens at ~12s curl timeout) behind a static 'reading the community sources…' message. On Haiku that may be 2-4s of dead air; on Sonnet/Opus it is worse. Perceived latency is the single biggest UX differentiator for chat AI, and we have none of it.
Evidence
platform/templates/partials/mobieus-ai-drawer.php:238-249 — the drawer does a single non-streaming fetch: `const r = await fetch('/api/ai/assistant/ask', {...}); const j = await r.json(); ... const msg = addMsg('ai', j.data.answer)`. The status text just says `mobieusAI is reading the community sources…` until the entire JSON arrives. AssistantAIController@ask (AssistantAIController.php:24-37) returns `$this->json(...)` — a buffered single response, no `text/event-stream`. AssistantAI::ask (AssistantAI.php:96-101) calls `AnthropicClient::complete()` with `max_tokens 700`; AnthropicClient (AnthropicClient.php:115-131) uses plain `curl_exec` with no stream callback. A repo-wide grep for `text/event-stream`/`EventSource` in the AI services returns zero hits (SSE exists only for chat rooms, ChatRoomController.php:409).
Suggested fix. Add an SSE variant of /api/ai/assistant/ask (the codebase already runs SSE on a dedicated FPM pool, mobieus-sse.sock, per ChatRoomController). Pass `stream:true` to the Anthropic Messages API and forward `content_block_delta` events to the drawer; append text incrementally in addMsg(). Keep the buffered path as a fallback for the spend-tracking record.
Filed by the automated tenant-app audit and adversarially evidence-verified. Status: verified. Open — not yet actioned.
Patrick Bass
@mobieus