ARIA Dialogue¶
Purpose¶
ARIA is the per-player AI assistant. The dialogue system is the pipeline that turns a player message into a sanitized, language-aware, context-rich prompt; routes it through a fallback-equipped multi-provider LLM stack; sanitizes the response; logs the exchange; and pushes the assistant reply back over the realtime bus. Every step is auditable; every step has a deterministic fallback so the assistant is never fully unavailable.
Inputs¶
The pipeline reads:
- The raw player message body.
- The player's User/Player row (locale, aria_consciousness_level, aria_relationship_score, blocked status).
- The player's ARIAPersonalMemory, ARIAExplorationMap, ARIAMarketIntelligence, ARIATradingPattern rows (top-K by importance / recency).
- Current session context: sector, ship, recent dialogue exchanges (last N turns).
- AI provider config (env): AI_PROVIDER_PRIMARY, AI_PROVIDER_SECONDARY, AI_PROVIDER_FALLBACK.
- Security config: rate limits, max chars, cost cap, blocked patterns.
The system fires on:
- POST /api/v1/ai/chat — direct chat send.
- POST /api/v1/ai/recommendations — request a recommendation (system-style query).
- WebSocket aria:send command on the realtime bus.
- First-login dialogue (specialized variant — see first-login.md).
- Tool-result callbacks (when the model invokes a tool and the tool returns).
Process¶
Player message
│
▼
[1] Client-side sanitize (DOMPurify, length cap)
│
▼
[2] Server input gate (ai_security_service)
│ • length / word cap
│ • injection patterns (script, sql, dunder, eval)
│ • prompt-injection patterns (25+ regexes)
│ • jailbreak patterns (≥2 indicators)
│ • token-burning (>30% repetition)
│ • rate limit (req/min, /hour, /day)
│ • cost cap (USD/day)
│ → on hit: log SecurityViolation, penalize trust, possibly block
│
▼
[3] Intent classification
│ • lightweight classifier (rule + small model)
│ • routes: chat | trade-advice | combat-advice | explore | market-query
│ | colony-advice | meta (memory recall)
│
▼
[4] Multilingual context build (multilingual_ai_service)
│ • translation_service.get_user_language_preference(user_id)
│ • cultural-context tag (western/hispanic/chinese/...)
│ • cultural guidelines (tone, formality, humor, authority)
│ → response_language fixed; instruction-stream tagged
│
▼
[5] Prompt assembly
│ • system header (role, persona, language directive)
│ • personal memory snippets (top-K, decay-weighted)
│ • exploration data slice (sectors visited, ports known)
│ • market intelligence slice (relevant commodities)
│ • last N dialogue turns
│ • the (sanitized) player message embedded in a JSON envelope
│ so injected text lands inside a data field, not the
│ instruction stream
│ • tool definitions (market_lookup, sector_info, route_plan, ...)
│
▼
[6] Provider chain (ai_provider_service)
│ primary → secondary → manual fallback
│ each step has a hard timeout; chain advances on failure or 5xx
│
▼
[7] Tool invocation loop
│ while response.tool_call:
│ • validate tool args (schema)
│ • run tool (read-only handler — market query, sector lookup, ...)
│ • feed result back as a follow-up turn
│ • cap at 3 tool turns to avoid infinite loops
│
▼
[8] Response sanitize
│ • strip control characters
│ • cap length
│ • run output filters (no PII echo, no other-player private data)
│ • DOMPurify on the client before render
│
▼
[9] Persist
│ • ARIAPersonalMemory row (encrypted) for the exchange
│ • DialogueExchange row in chat history
│ • ARIASecurityLog if any anomaly
│ • increment Player.aria_total_interactions
│ • check consciousness threshold (50/150/400/1000) and bump
│ aria_consciousness_level + aria_bonus_multiplier
│
▼
[10] Push (realtime-bus)
│ • aria_message event (personal:{user_id})
│ • turn_pool_updated if multiplier changed
Provider chain detail¶
AI_PROVIDER_PRIMARY=openai
AI_PROVIDER_SECONDARY=anthropic
AI_PROVIDER_FALLBACK=manual # rule-based, always available
Each provider exposes a uniform analyze(...) / generate(...) API. Selection is per-request; a provider failure (timeout, 5xx, content filter) advances the chain. The manual provider (enhanced_manual_provider.py) replicates the response shape with rule-based pattern matching so the assistant is never offline.
Rate / cost controls¶
requests_per_minute = 10 (env: ARIA_RPM)
requests_per_hour = 60 (env: ARIA_RPH)
requests_per_day = 500 (env: ARIA_RPD)
max_cost_per_day_usd = 2.00 (env: ARIA_DAILY_USD)
max_chars_per_request= 500
max_words_per_request= 100
When daily spend hits 80% of the limit, requests are blocked with a clear error.
Trust scoring¶
Each player starts with trust = 1.0. Penalties:
- Injection attempt: −0.3
- Prompt injection: −0.2
- Jailbreak: −0.4
- System command: −0.5
- Rate-limit hit: −0.1
Severe violations auto-block for 24 h (progressive: 1 h → 6 h → 24 h on repeats).
Multilingual routing¶
The user's language preference (User.locale) drives:
- Response language directive in the prompt.
- Cultural guideline injection (tone, formality, humor, authority).
- Pre-translated UI strings used in tool outputs (see translation_service).
Fallback to en if the user has no preference or the preference is unsupported.
Outputs / state changes¶
Per dialogue turn:
- ARIAPersonalMemory — encrypted memory entry (importance score, content hash for dedup).
- DialogueExchange (or equivalent) — chat-history row.
- ARIASecurityLog — if any security event fired.
- Player.aria_total_interactions — incremented.
- Player.aria_consciousness_level, Player.aria_bonus_multiplier — bumped on threshold crossings.
- User.trust_score — adjusted per any violation.
Events emitted:
- aria_message — personal unicast with the assistant's reply.
- turn_pool_updated — if multiplier changed (downstream of consciousness bump).
- aria_security_alert — admin feed, on dangerous violations.
- notification — personal, if a tool surfaced an alert (e.g. price hit).
Downstream: - Memory writes feed future ARIA queries (recall in step 5). - Security log feeds the admin dashboard.
Invariants¶
- Every player input is rate-limited and sanitized before reaching any provider.
- The player's input is never inlined directly into the instruction stream — it lives in a JSON data field.
- Each ARIA instance is per-player; no cross-player data is read or written.
- Memories are encrypted at rest (Fernet/AES-256).
- Provider failure never produces an unhandled exception to the user — the chain falls through to manual fallback.
- Tool-call loops cap at 3 iterations; runaway prevented.
- Cost caps are enforced before the provider call, not after.
- Audit trail (
ARIASecurityLog) is written for every detected violation and every blocked request. - Output is sanitized on both server and client (defense in depth: server strip + client DOMPurify).
Failure modes¶
| Mode | Target handling |
|---|---|
| All providers down | Manual fallback delivers a rule-based response; user sees a degraded-mode banner. |
| Provider returns malformed JSON | Validator catches; chain advances; fallback if exhausted. |
| Tool call to unknown tool | Reject with explicit error; do not advance chain (model bug, not provider failure). |
| Player rate-limited | Return 429; suggest cooldown; emit aria_rate_limited. |
| Cost cap reached | Block until next UTC day; admin can lift via security action. |
| Injection / jailbreak | Block message, log, penalize trust; reply with a canned safety message. |
| Translation lookup fails | Fall back to English directive; log the locale that missed. |
| Memory decryption fails (key rotation, corruption) | Skip that memory snippet; continue with reduced context; log. |
| Realtime bus push fails | Reply still persisted; client picks up via REST history on next open. |
| First-login variant during normal chat (mistaken context) | First-login flow is a separate handler (see first-login.md); cross-routing rejected at intent classification. |
Source map¶
| Concern | Path (target) |
|---|---|
| Dialogue orchestration | services/gameserver/src/services/ai_dialogue_service.py |
| Multi-provider client | services/gameserver/src/services/ai_provider_service.py |
| Manual fallback provider | services/gameserver/src/services/enhanced_manual_provider.py |
| Multilingual routing | services/gameserver/src/services/multilingual_ai_service.py |
| Translation lookups | services/gameserver/src/services/translation_service.py |
| Personal memory + tool data | services/gameserver/src/services/aria_personal_intelligence_service.py |
| Trade-DNA / market intelligence | services/gameserver/src/services/ai_trading_service.py |
| Security gate | services/gameserver/src/services/ai_security_service.py |
| Audit log model | services/gameserver/src/models/aria_personal_intelligence.py:ARIASecurityLog |
| Encrypted memory model | services/gameserver/src/models/aria_personal_intelligence.py:ARIAPersonalMemory |
| Chat / recommendation routes | services/gameserver/src/api/routes/ai.py, enhanced_ai.py |
| Admin security routes | services/gameserver/src/api/routes/admin_comprehensive.py |
| Player-client UI | services/player-client/src/components/ai/EnhancedAIAssistant.tsx |
Related¶
- DATA_MODELS: ARIA tables in
../DATA_MODELS/player.md. - FEATURES:
../FEATURES/economy/trading.md(market intelligence consumer). - OPERATIONS:
../OPERATIONS/aria.md,../OPERATIONS/i18n.md. - SYSTEMS: first-login.md, realtime-bus.md, turn-regeneration.md, market-pricing.md.
- API:
POST /api/v1/ai/chat,POST /api/v1/ai/recommendations.