ARIA Dialogue¶
Status: π§ Partial β ARIA chat is reachable, sanitized, and per-player-isolated, but its replies are deterministic intent-templates with NO LLM call β the documented provider chain, encrypted-memory writes β¦ Β· β οΈ contains codeβspec divergence (impl audit 2026-06-16)
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, and recent ARIATradingObservation rows (top-K by recency or aggregate-relevance).
- 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)
β Server-side: build dialogue context with auth_snapshot
β β’ subscription_tier (User.subscription_tier at this instant)
β β’ aria_consciousness_level (Player.aria_consciousness_level)
β β’ aria_bonus_multiplier (Player.aria_bonus_multiplier)
β Per ADR-0058 A-F1, all subsequent steps read these from the
β snapshot, never from the live row. A subscription upgrade or
β consciousness level-up landing mid-exchange takes effect on
β the NEXT exchange β the in-flight one completes consistently.
β
βΌ
[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, /day β per-hour retired per AU2-18)
β β’ cost cap (USD/day, USD/request)
β β 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
β
β Multiplier semantics (per ADR-0057 A-D2): the multiplier applies
β CONTINUOUSLY on every ARIA interaction β read on each call to
β scale recommendation strength, narration richness, observation
β depth. Level transitions are atomic boundary events; the
β multiplier itself is not gated to those transitions.
β
βΌ
[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) # anti-burst cap
requests_per_day = 500 (env: ARIA_RPD) # long-term ceiling
max_cost_per_day_usd = 2.00 (env: ARIA_DAILY_USD) # per-player daily spend cap
max_cost_per_request = 0.05 (env: ARIA_REQ_USD) # per-request hard ceiling
max_chars_per_request = 500
max_words_per_request = 100
Plus a per-instance circuit breaker: instance_max_cost_per_day_usd = 50.00 (env: ARIA_INSTANCE_DAILY_USD) β defense-in-depth backstop on aggregate spend across all players. Per-hour cap retired (AU2-18) β was dominated by per-minute math. When daily spend hits 80% of the per-player limit, the player is blocked for the rest of the UTC day with ERR_DAILY_BUDGET_EXHAUSTED.
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.