M27 · AI Layer

AI Morning Summary

Every morning at 06:00 (tenant timezone) — 80-150 words of KPI delta + insight + action suggestion. No PII reaches the LLM.

Overview

What the morning summary tells you

Headline numbers from the last 24 hours + why + what to do.

  • 06:00 local

    06:00 in the tenant's timezone — 06:00 CET for EU, 06:00 local for US, etc. Cron runs per workspace.

  • 80-150 words

    Short, scannable. Headline KPI delta + 1-2 sentences of insight + a suggested action (with a link).

  • TR primary + EN

    Follows the workspace language. For ZH/AR, EN falls back for now (native translation in late Phase 3).

  • Where you see it

    Top card of the dashboard homepage — instantly when /app opens. Can also push to Discord/email webhooks via notification settings.

5-model fallback chain

Never-down profile

DeepSeek primary with 4 fallbacks. If any model fails, the next one runs automatically. The provider badge in the UI tells you which.

  1. 01

    Primary — DeepSeek

    Fast, cheap, strong in Turkish + English. Default primary.

    deepseek-chat · global
  2. 02

    Fallback 1 — MiniMax

    Chinese provider, reliable on long context. Kicks in if DeepSeek is down.

    abab6.5s-chat · global
  3. 03

    Fallback 2 — AWS Bedrock Nova

    eu-central-1 region. AWS region-locked managed AI (Bedrock exception) — strategic for never-down.

    amazon.nova-lite-v1 · eu-central-1
  4. 04

    Fallback 3 — Qwen

    Alibaba Cloud. Strong multi-language, stable structured output.

    qwen-max · global
  5. 05

    Fallback 4 — Kimi (Moonshot)

    Final fallback. If everything is down we fall back to a static template summary.

    moonshot-v1-32k · global

CH aggregation

events_canonical last 24h

Raw metrics aggregated in ClickHouse are passed to the prompt as context.

Which metrics?

Last 24 hours from events_canonical — granular enough to be useful, light enough not to overload the LLM.

  • Headline KPI delta (outcomes vs. previous 24h)
  • Top 5 events by volume
  • Top 5 source domains (UTM/referrer)
  • DAU/MAU + identity merge count + retention spot
  • Active health alarm count + new alarms in last 24h
-- 24-saatlik headline delta + top events + sources
SELECT
  countIf(event_class = 'outcome') AS outcomes_24h,
  countIf(event_class = 'interaction') AS interactions_24h,
  uniqExact(person_id) AS dau,
  topK(5)(event_name) AS top_events,
  topK(5)(source_context['source_domain']) AS top_sources
FROM events_canonical
WHERE
  tenant_id = {tenant_id:UUID}
  AND ts >= now() - INTERVAL 24 HOUR;

Pseudonymize-everything

No PII reaches the LLM

Email, phone, UUID, Stripe ID — all stripped before they hit the prompt. Deterministic aliases stand in.

Our promise

No PII is sent to any LLM provider. Regex strip + deterministic alias is mandatory — every value in the prompt is pseudonymized.

  • docsModules.aiMorning.pseudonymize.promise.bullets.email
  • docsModules.aiMorning.pseudonymize.promise.bullets.phone
  • docsModules.aiMorning.pseudonymize.promise.bullets.ids
  • Workspace-salted deterministic alias — the same user always lands on the same placeholder
// PII strip — LLM'e gönderilmeden önce
function pseudonymize(input: string, salt: string): string {
  return input
    .replace(/[\w.+-]+@[\w-]+\.[\w.-]+/g, '<EMAIL>')
    .replace(/\+?\d{10,15}/g, '<PHONE>')
    .replace(/cus_[A-Za-z0-9]+/g, '<STRIPE_CUSTOMER>')
    .replace(/sub_[A-Za-z0-9]+/g, '<STRIPE_SUB>')
    .replace(/[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}/gi, '<UUID>')
    .replace(/\b[A-Za-z0-9_-]{20,}\b/g, (m) => deterministicAlias(m, salt));
}

Sector pack

tenants.sector_pack prompt context

5 sector packs — the summary uses sector-specific terminology + KPIs.

E-commerce

Focus on cart, AOV, conversion rate, refunds.

SaaS

Focus on activation, MRR, expansion, churn risk.

Fintech

Focus on onboarding, KYC, first transaction, volume.

Content / publishing

Focus on active readers, session depth, paywall conversion.

Gambling / iGaming

Focus on bet count, GGR, deposits, responsible gaming.

Quota

Free 150 / Custom unlimited

M28 W3 quota dimension 'ai_calls'. Morning summary + Anomaly Explainer + every AI call comes from this bucket.

Plan
Monthly call limit
Dimension
Free
150 calls/month (morning + anomaly + manual rerun)
ai_calls
Custom
Unlimited (usage-based billing, PostHog unit −60% graduated)
ai_calls

Anomaly Explainer

Alarm → AI cause suggestion

When an M7 event-health alarm fires, POST /v1/ai/explain-anomaly returns AI-generated causes + actions + verification steps.

What it returns

Likely causes + suggested actions + verification steps (how to confirm in the playground). Provider badge for transparency.

curl -X POST https://api.gurulu.io/v1/ai/explain-anomaly \
  -H "Authorization: Bearer $GURULU_SECRET_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "alarm_id": "alm_01H8XYZ",
    "include_recommendations": true
  }'

# Yanıt
{
  "cause": "checkout_started event hacmi son 2 saatte %42 düştü",
  "likely_reasons": [
    "Frontend deploy 14:22 sonrası tag mismatch",
    "Ana kaynak google/cpc trafiği %38 azaldı"
  ],
  "suggested_actions": ["Rollback CDN bundle", "Google Ads kampanya pause"],
  "verification_steps": ["Playground'da add_to_cart selector test et"],
  "provider": "deepseek-chat"
}

Provider badge

Which model wrote this?

Every summary carries a badge — it tells you which model in the fallback chain ran.

Why we show it

Transparency + audit. If a summary feels off, knowing which model produced it makes debugging easier.

Badge samples

deepseek · deepseek-chatminimax · abab6.5s-chatbedrock · amazon.nova-lite-v1qwen · qwen-maxkimi · moonshot-v1-32k

Related docs

Read next

Watch audience movement in the digest, look for patterns in the playground, dive deep into the AI layer.

AI Morning Summary — Gurulu Docs