Skip to content

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

  1. Every player input is rate-limited and sanitized before reaching any provider.
  2. The player's input is never inlined directly into the instruction stream — it lives in a JSON data field.
  3. Each ARIA instance is per-player; no cross-player data is read or written.
  4. Memories are encrypted at rest (Fernet/AES-256).
  5. Provider failure never produces an unhandled exception to the user — the chain falls through to manual fallback.
  6. Tool-call loops cap at 3 iterations; runaway prevented.
  7. Cost caps are enforced before the provider call, not after.
  8. Audit trail (ARIASecurityLog) is written for every detected violation and every blocked request.
  9. 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