# Ask AI

Ask AI is the console assistant for understanding one app. Ask about delivery, click-through,
audiences, users, events, journeys, or recent changes in plain language. It reads the app's current
rows through the same scoped tools as the console, then returns an answer you can inspect and
continue with a follow-up question.

<div className="op-ask-guide-demo" aria-label="Illustrative Ask AI conversation">
  <div className="op-ask-guide-demo-head">
    <strong><i aria-hidden="true" />Ask AI</strong>
    <span>Illustrative answer</span>
  </div>
  <div className="op-ask-guide-turn op-ask-guide-turn-question">
    <div className="op-ask-guide-role"><b>YOU</b><span>Your question</span><time dateTime="2026-09-12T09:42:00">09:42</time></div>
    <p>How are my notifications doing this week?</p>
  </div>
  <div className="op-ask-guide-turn">
    <div className="op-ask-guide-role"><b className="is-openpush">OP</b><span>OpenPush</span><time dateTime="2026-09-12T09:42:10">09:42</time></div>
    <p>Delivery is steady, but <strong>click-through fell from 4.2% to 3.1%</strong>. Two re-engagement pushes account for most of the change. Review their audience and opening line first.</p>
    <div className="op-ask-guide-metric"><span><strong>3.1%</strong><small>Click-through · 7 days</small></span><b>−1.1 pp</b></div>
  </div>
</div>

The example above is illustrative. Your answers come from the rows in the app you have open; they
are not shared benchmarks and they are not generated on page load.

## Where to ask

Open **Ask AI** in the app sidebar for the full-page view. It contains the question composer,
starting points derived from that app's rows, recent recorded activity, and your own conversation
history.

From any other app screen, use the black **Ask** button in the top bar or press `Cmd/Ctrl+K`. The
drawer carries the page you are viewing as context when that page is a dashboard, push composer,
journey, message report, segment list, or user profile. Remove the context chip before sending if
you want a broader answer.

Both surfaces use the same conversation and the same permissions.

## What you can ask

| Task | Example question | What the answer can use |
|---|---|---|
| Review performance | “How are my notifications doing this week?” | Message reports, delivery stages, click-through, and recent trends |
| Diagnose delivery | “Why did user 2048 not receive this push?” | The user's subscriptions and the delivery trace for the named message |
| Understand an audience | “Who clicked in the last 30 days?” | Users, subscriptions, tags, segments, and audience previews |
| Investigate change | “What caused yesterday's traffic spike?” | Recorded app events, sessions, and the anomaly you opened from Recent activity |
| Plan the next step | “Draft a re-engagement push for inactive players.” | Your app's brand voice, top-performing copy, and a prepared message preview |
| Learn the product | “What can you help me with?” | A fixed allowlist of OpenPush documentation plus the tools available to your role |
| Find a page | “Take me to the delivery guards.” | A link to that section of the console, named for it |

Ask one concrete question first. A follow-up such as “Which audience should I review first?” stays
under the answer in the same thread, with its own timestamp and the earlier turns as context.

## How a turn works

1. **You ask.** The question is bound to the app currently open and to your signed-in identity.
2. **OpenPush reads.** It announces each app tool before it runs and summarizes the result afterward.
3. **You inspect the answer.** The response can include prose, a console-native chart, follow-up questions, or a prepared-action preview.
4. **You continue or confirm.** A follow-up remains in the thread. A prepared change waits for a separate human confirmation.

A turn can make up to eight tool calls before producing its answer. The console shows that work as it
happens so a slow data read does not look like a frozen screen.

## What Ask AI can change

The model changes nothing by itself.

- **Viewers** can ask questions and use every read-only tool their app access permits.
- **Managers and admins** can also ask OpenPush to prepare a message, segment, template, user-tag change, message cancellation, or journey draft.
- A prepared change appears below the answer with a preview, an expiry countdown, and **Confirm** and **Discard** controls.
- Confirming runs the ordinary server validation and permission checks. The model never receives the confirmation token and cannot press the button.

There are no delete tools, key-management tools, app-creation tools, platform-credential tools, or
journey-activation tools in the assistant registry. Test sends are not offered to Ask AI.

## What leaves the server

Each provider call receives the system prompt, the bounded conversation window, and the tool results
needed for that turn. The system prompt names the app and your role and includes the app's saved brand
voice. A later follow-up resends at most the last 20 messages; older tool results are compacted and the
whole replay is capped at 60,000 characters.

| Data | Does it leave? | Detail |
|---|---|---|
| Your question and recent conversation | Yes | Sent to the configured provider so it can answer the current turn |
| Rows returned by a tool | When needed | Only results for the current app; a person-level question can include that subscriber's external ID and tags |
| API keys and platform credentials | Never | Provider, REST, SDK, APNs, and FCM credentials stay server-side |
| Push tokens | Never in full | Tools mask every token to its first six and last four characters |
| Confirmation tokens | Never | The browser confirms by action ID; the server looks up the token internally |
| Another app's rows | Never | The tool principal is already bound to the app in the console |

Tenant and subscriber text is placed inside an untrusted-data envelope before it enters a prompt. This
reduces prompt-injection risk, but the stronger protection is the execution boundary: the model can
only read or prepare. A person still owns every state change.

## Provider and model settings

The provider and model are **deployment settings**, not per-user or per-app selectors. The OpenPush
operator configures OpenAI, Anthropic, or an OpenAI-compatible endpoint. **Settings → AI features**
reports the provider, model, and host that answered; it never shows the API key or the configured URL.

An OpenAI-compatible endpoint can be an Ollama or vLLM instance, or a gateway operated by the
deployment. Ask AI requires that endpoint to support tool calling. If it does not, Ask AI
names that limitation while compose and translation remain available.

Prompts sent to the configured provider are governed by that provider's terms. OpenPush does not use
app rows, copy, or conversations to train a model. See [AI data practices](#privacy-retention-and-audit)
for the storage boundary.

## Availability and budgets

Two switches are checked on every provider call:

| Switch | Location | Who controls it |
|---|---|---|
| Workspace AI | **Team → AI features** | Workspace admin |
| App AI | **Settings → AI features** | Manager or admin |

Both must be active. Turning either one inactive takes effect during an existing conversation; it does
not wait for a redeploy.

New workspaces and new apps start with AI features inactive. An administrator must activate workspace
AI, then a manager or administrator must activate AI for the app before any prompt can leave the server.

The default spend limits are 30 completed provider calls per app in a rolling hour and 2,000 per UTC
calendar month. A question can use several calls, so the call counters and “questions this month” are
different measurements. Failed calls are audited but do not consume the completed-call budget.

The shared sample app does not expose Ask AI because its visitors receive a shared role rather
than an individual app membership.

## Privacy, retention, and audit

Conversations are private to the person who typed them. Every conversation read checks both the app
and the actor; even a workspace admin has no screen for reading a colleague's thread. Someone else's
conversation returns the same not-found response as a conversation that does not exist.

Conversation content is deleted 30 days after its last activity. Active threads do not age out while
you are still using them, and conversation content is excluded from workspace exports so an export
cannot give an admin access the console itself does not grant.

OpenPush retains a separate audit trail without storing the prompt text in that trail:

- One AI action row per provider call records the app, feature, provider, model, actor, success,
  latency, timestamp, and a SHA-256 hash of the prompt.
- Each tool call and each confirmation or discard is recorded in the ordinary audit log.
- Brand voice settings and AI action rows are included in an export; private conversation content is not.

## If Ask AI is unavailable

The composer gives a specific reason rather than failing silently:

- **AI assist is unavailable** — the deployment has no provider configured.
- **AI features are disabled for this workspace** — a workspace or app switch is inactive.
- **AI limit reached** — the rolling hourly cap is full; try again after calls age out of the window.
- **AI budget reached** — the app reached its monthly cap; it resets on the first day of the next UTC month.
- **Ask AI is busy** — all per-process Ask workers are occupied; retry in a moment.
- **This endpoint does not support tool calling** — use a compatible provider/model for Ask AI, or continue using compose and translation.
