115 lines
5.0 KiB
Markdown
115 lines
5.0 KiB
Markdown
# MoonWell Playerbots AI
|
|
|
|
This module sends a local `/say` or public-channel message to the LLM only when
|
|
a real player mentions the complete name of an online bot. A channel bot must
|
|
be a channel member; a `/say` bot must be within the server's normal listening
|
|
range. HTTP work runs outside the AzerothCore world thread.
|
|
|
|
Alice AI LLM Flash can classify direct natural-language requests into a small
|
|
allowlisted set of native playerbots commands. The server validates the command
|
|
again and executes it only against the addressed bot; existing playerbots
|
|
ownership and group security checks still apply.
|
|
|
|
The routing prompt covers party movement and combat, LFG, combat/non-combat
|
|
strategies, spells, RTI/RTSC, focus healing, loot lists, inventory operations,
|
|
quests, pets, talents, glyphs, maintenance, and information commands documented
|
|
in the upstream Playerbot Commands wiki. Administrative, console, account,
|
|
debug/cheat, and destructive `destroy`/`drop`/mail commands are intentionally
|
|
not executable through the LLM.
|
|
|
|
Common Russian movement/combat phrases use a deterministic fast path. Other
|
|
requests first pass through a command-only classifier; ordinary conversation is
|
|
then sent separately to the roleplay prompt. While AI routing is enabled, the
|
|
legacy public-channel parser is bypassed and `setup-modules.sh` also forces
|
|
`AiPlayerbot.RandomBotTalk = 0`. RandomBotTalk consumes incoming chat packets
|
|
inside each bot, so bypassing only the parser does not prevent its delayed
|
|
stock replies. Whisper, party, raid, and guild command hooks remain unchanged.
|
|
|
|
Recognized commands produce a gender-aware local-chat acknowledgement
|
|
(`Понял команду.` or `Поняла команду.`) before they are handed to the native
|
|
playerbots command handler. Bot and player gender are also included in the LLM
|
|
context for pronoun, past-tense verb, and adjective agreement. Russian requests
|
|
to show bags or inventory use the native `inv` command; `open items` is reserved
|
|
for actually opening container items.
|
|
|
|
Trade and quest requests have deterministic link-preserving routes before the
|
|
LLM classifier:
|
|
|
|
- `дай/передай [item]` -> `t [item]`; `начни обмен` -> `t`
|
|
- `покажи задания` -> `quests all`; completed/incomplete filters are supported
|
|
- `покажи прогресс [quest]` -> `q [quest]`
|
|
- `прими [quest]` / `прими все задания` -> `accept [quest]` / `accept *`
|
|
- `поделись [quest]` -> `share [quest]`
|
|
- `выбери [item] в награду` -> `r [item]`
|
|
- `сдай готовое задание` -> `talk`
|
|
- `откажись от [quest]` -> `drop [quest]` only with an explicit quest link
|
|
|
|
These routes preserve the original WoW hyperlink byte-for-byte. The local
|
|
playerbots trade action continues processing after it creates the trade, so one
|
|
`t [item]` command both initiates the exchange and places the requested item in
|
|
the trade window.
|
|
|
|
The bundled `playerbots-ai` bridge uses the Yandex AI Studio OpenAI-compatible
|
|
Chat Completions API and defaults to Alice AI LLM Flash.
|
|
|
|
## Configuration
|
|
|
|
Set these values in the repository `.env`:
|
|
|
|
```dotenv
|
|
ACORE_PLAYERBOTS_AI_ENABLED=1
|
|
ACORE_PLAYERBOTS_AI_COMMANDS_ENABLED=1
|
|
YANDEX_AI_API_KEY=<service-account API key>
|
|
YANDEX_AI_FOLDER_ID=<Yandex Cloud folder ID>
|
|
```
|
|
|
|
Until the subscription system exists, public access is controlled by one
|
|
explicit switch:
|
|
|
|
```dotenv
|
|
ACORE_PLAYERBOTS_AI_AVAILABLE_FOR_ALL=1
|
|
```
|
|
|
|
`1` allows every player to reach the bridge. `0` denies LLM access to everyone
|
|
without spending tokens. When subscriptions are implemented, their entitlement
|
|
check will be added to the disabled branch instead of using a temporary manual
|
|
account list.
|
|
|
|
The command classifier has a persistent SQLite cache in the
|
|
`playerbots-ai-cache` Docker volume. The key excludes the addressed bot name,
|
|
so repeated phrases such as “покажи инвентарь” are shared across players and
|
|
bots. Both commands and “ordinary chat, not a command” decisions are cached.
|
|
The cache does not store roleplay responses or conversation history.
|
|
Obvious social phrases such as greetings, “как дела?” and “расскажи о себе”
|
|
skip the command classifier entirely: they still receive an Alice roleplay
|
|
reply, but do not pay the roughly 800-token command-catalog prompt first.
|
|
|
|
```dotenv
|
|
PLAYERBOTS_AI_CLASSIFIER_CACHE_ENABLED=1
|
|
PLAYERBOTS_AI_CLASSIFIER_CACHE_TTL_SECONDS=604800
|
|
PLAYERBOTS_AI_CLASSIFIER_CACHE_MAX_ENTRIES=10000
|
|
```
|
|
|
|
Changing the classifier prompt automatically creates a new cache namespace.
|
|
Old rows expire normally, and the oldest rows are removed at the size limit.
|
|
|
|
The default model URI is:
|
|
|
|
```text
|
|
gpt://<YANDEX_AI_FOLDER_ID>/aliceai-llm-flash
|
|
```
|
|
|
|
Run `./start-server.sh` or `scripts/prod-deploy.sh`. The deployment wrapper
|
|
builds and starts the bridge before `ac-worldserver`.
|
|
|
|
Never commit a populated API key.
|
|
|
|
Full Yandex response JSON is logged by default by the bridge:
|
|
|
|
```dotenv
|
|
PLAYERBOTS_AI_LOG_API_RESPONSES=1
|
|
```
|
|
|
|
Use `docker compose logs -f playerbots-ai` to follow classifier and chat
|
|
responses. Authentication headers and the API key are never logged.
|