Source branch: feature/ai-brain-router Source commit: c2a09e0460465201a58aaab56c71424e9a96405e
5.1 KiB
Connector and API contracts
Control-plane API
All write actions go to POST /api/actions as JSON. Input validation is in core/validation.ts.
| Action type | Fields | Behavior |
|---|---|---|
| createBot | name, role, race, recipeId, goal | Creates an offline identity |
| lifecycle | botId, action | spawn / pause / resume / despawn / retire |
| think | botId | One bounded decision for an online bot |
| saveRecipe | recipe | New recipe or optimistic versioned edit |
| applyRecipe | botId, recipeId | Applies the latest recipe snapshot |
| memory | botId, text, importance | Adds an operator-authored memory |
| relationship | botId, targetId, affinity, note | Upserts a directed bond |
| director | experience, playerName, zone, brief | Sets non-retired bots' goals |
| settings | connector, provider, model | Changes saved runtime selection |
| health | none | Tests the currently saved connector |
| gm | command, live, confirmed | Human-only GM channel |
GET /api/state returns the snapshot. GET /api/events accepts Last-Event-ID or ?after=<sequence> and emits realm events. The server closes each batch and asks EventSource to reconnect after 3 seconds. A gap event tells clients the cursor predates retention. GET /api/health reports database availability and credential configuration booleans only.
AzerothCore bot bridge (game-side implementation required)
Set BRIDGE_URL to your bridge root and BRIDGE_TOKEN to its bearer token. The adapter sends Authorization: Bearer ..., bounded requests, and an opaque requestId. The bridge must durably deduplicate request IDs. Do not blindly re-execute a request after a timeout.
| Endpoint | Request | Successful response |
|---|---|---|
| GET /v1/health | — | { "ok": true, "detail": "..." } |
| GET /v1/bots/:id/observation | — | { "zone":"Duskwood", "level":20, "availableActions":["quest","rest"], "summary":"..." } |
| POST /v1/bots/:id/lifecycle | { "action":"spawn", "identity": {"id":"...","name":"...","race":"Human","role":"Priest"}, "requestId":"..." } |
{ "accepted":true } |
| POST /v1/bots/:id/intent | { "decision": {"action":"quest","reason":"...","goal":"..."}, "requestId":"..." } |
{ "accepted":true, "summary":"Intent handed to the bot controller", "zone":"Duskwood" } |
The bridge maps stable AzerothAI IDs to actual character GUIDs, validates race/class/faction/version constraints, controls the chosen Playerbots integration, and translates high-level intents to supported game behavior. An accepted lifecycle response must mean the requested state is established, not merely queued. Intents may be accepted for execution; their response summaries must not claim completed quests or other outcomes that have not occurred. Reject unsupported operations with non-2xx responses.
The bridge, not the language model, decides whether a requested action is mechanically possible. The prototype does not write character/world tables directly or send a made-up generic Playerbots command.
Adding another game
Implement GameConnector in core/types.ts, register a factory in core/connectors/index.ts, and add its ID to validated settings/UI choices. Domain memory, relationships, recipe snapshots, and the LLM context remain unchanged. Extend the high-level action vocabulary only when both validation and the connector support it.
Models
Ollama uses POST <LLM_URL>/api/chat, stream:false, format:"json". Compatible servers use POST <LLM_URL>/v1/chat/completions and JSON-object response format. Set LLM_URL to the root without /v1; optionally set LLM_API_KEY for authenticated gateways. Requests have a 25-second timeout and an output limit. Decisions are schema-validated and intersected with both recipe activities and observed available actions. Invalid output fails visibly without fallback to fabricated success.
The context includes identity, recipe, current goal, eight important memories, ten relationships, and the latest observation. Memories/observations are marked untrusted. Memory retrieval is intentionally simple, not vector search. The deterministic provider is an explicitly labeled simulator, not an LLM.
GM SOAP
Configure SOAP_URL, SOAP_USER, and SOAP_PASSWORD. core/gm.ts posts a SOAP executeCommand envelope in namespace urn:AC, with Basic authentication. Leading dots are removed for console use; XML metacharacters are escaped. Multiple commands, control characters, and commands outside the allowlist are rejected.
Supported: server info, announce <text>, teleport name <character> <location>, pinfo <character>, server motd. Authorization and command availability still depend on the actual AzerothCore branch and account permissions. SOAP results and faults are reported; nothing calls the GM client from an LLM provider.
Position/selection-dependent commands such as summon, NPC spawning at the GM location, visibility, and flying require an in-game session or a purpose-built game-side adapter. They are not misleadingly offered as working remote buttons.
Official references used for the protocol: