NexusAI 1.1.0
What's new
Feature release: API key files, a round-robin model queue, context providers for other plugins, optional dialogue summaries and a non-blocking HTTP pool. Everyone on 1.0.2 can update; the 17 new keys are appended to config.yml automatically and it stays at config-version: 2.
Upgrading
- Replace
NexusAI-1.0.2.jarwithNexusAI-1.1.0.jarand restart.api-versionstays1.20.6. Commands, permissions and placeholders are unchanged. - You do not need to edit
config.yml, and do not changeconfig-version. On the first start, missing keys are copied from the jar default:model-queue-strategy(failover), eightcontext.*keys, sixdialogue.summary.*keys inside your existingdialogue:section, andhttp.max-in-flightandhttp.queue-size(both64). The log showsAdded missing config keys: …, and that start writes oneconfig.yml.bak(orconfig.yml.bak.<timestamp>when a backup already exists). Values you already set and your comments stay. - The appended defaults keep 1.0.2 behaviour:
failoveris the 1.0.2 queue order and dialogue summaries are off.context.enabledistrue, but a prompt uses context only when it listscontext:and another plugin registers a provider. api-key-fileis not inserted. Add it under a provider yourself if you want to keep keys in a file.prompts.ymlstays on version 1. A prompt withoutcontext:keeps its 1.0.2 text and cache key.usage.ymlandpool.ymlare not changed.- Up to 64 requests can now be in flight at once (
http.max-in-flight); in 1.0.2 the four HTTP threads limited this. One connection error still pauses a provider for 60 seconds, so lowerhttp.max-in-flightfor a small or self-hosted endpoint. - To roll back: stop the server, put
NexusAI-1.0.2.jarback and start it. 1.0.2 ignores the new keys, soconfig.ymlcan stay as it is (or restore theconfig.yml.bakwritten by 1.1.0). 1.0.2 does not readapi-key-file, so move such keys back toapi-keyorNEXUSAI_API_KEYfirst. Details are indocs/migration-1.1.0.md.
API keys
providers.<id>.api-key-filereads keys from a UTF-8 file, one per line, at startup and on/nai reload. A relative path is underplugins/NexusAI/; an absolute path is allowed. A non-empty path wins overapi-key, andNEXUSAI_API_KEYdoes not replace keys from the file. An empty file still falls back toNEXUSAI_API_KEYon the active provider.- A missing file, a file over 64 KB, or a line with a space or
:logs one warning with the path, never the line text. A key file readable by the group or by others logschmod 600 <path>. ${ENV:VAR}works the same as${VAR}. An unset variable is logged by name and becomes an empty string./nai statusand the startupAPI keys:line show****abcd (file)or****abcd (env); a literal key stays****abcd. Logs,/nai status,/nai testand a failed/nai reloaduse the same mask. A key from the environment or a key file is never written intoconfig.ymlor a backup.- A key of 4 characters or fewer is masked as
****, and startup and/nai reloadlog one warning that names the provider and the key length. - Keys in the config are not encrypted.
Model queue
model-queue-strategy: failover(default) starts every request at the first available row, as before.round-robinstarts each new request at the next available row. Both skip rows on cooldown, overdaily-request-limitor at themodel-queue-remaining-threshold.- An unknown value is treated as
failover, with one warning on startup and on/nai reload. /nai statusshows the strategy and the next row, for examplefailover (next: groq/llama).usage.ymlaccounting is unchanged.
Context providers
- Other plugins can register a
NexusContextProviderthrough Bukkit's services manager orNexusAIApi.registerContextProvider.NexusAIApi.API_VERSIONis now2. - A prompt that lists
context:(provider ids, orall) gets a sanitized player-context block in%ainexus_cached_<prompt>%, in/nai talk/NexusAIApi.talk, and in/nai test <id>run by a player.generate_, the pool, prewarm, console/nai testand literal placeholders do not use context. - Providers run on two
nexusai-context-Nthreads, never on the main thread, with the timeouts undercontext.*. A provider still running at its timeout is interrupted and its value skipped; five timeouts or errors in a row suspend it forcontext.suspend-seconds./nai statuslists providers without their values. - The context block is part of the
cached_cache key, so players with different context do not share an answer.
Dialogue summaries
dialogue.summary.enabledisfalseby default; while it is off,/nai talkanddialogue-memory.ymlwork as in 1.0.2.- When it is on, lines that drop out of the memory window are folded into a short summary by one extra model request after
dialogue.summary.threshold-turnsplayer lines. The summary is kept in the character prompt; the recent window is unchanged. - A refused summary request drops the waiting lines and keeps the previous summary. Set both
dialogue.summary.provideranddialogue.summary.modelto send summaries to one fixed model. - With summaries on,
dialogue-memory.ymlbecomesformat: 2; the first such rewrite copies the old file todialogue-memory.yml.bakonce./nai statusshowsDialogue summaries: offoron (N ok, M failed today). - Saves of
dialogue-memory.yml,pool.yml,usage.yml, config rewrites andprompts.ymlimports now write a temporary file and move it into place, keeping the file mode. New files are created as0600.
HTTP pool
- Placeholder and queue calls no longer block the four
nexusai-http-*threads.http.max-in-flightcaps calls in flight andhttp.queue-sizecaps how many more may wait (both64by default).0or a negative value is replaced with64, with one warning per key./nai reloadapplies a new cap. - A request beyond the cap fails at once with
HTTP queue is full, and the placeholder shows its fallback. At most one warning is written per 30 seconds. - A base URL with a query string keeps it after
/chat/completions(http://host/v1?key=Xbecomeshttp://host/v1/chat/completions?key=X). A URL that already ends in/chat/completionsis not extended again, and a trailing slash is ignored. config.ymlandprompts.ymlcreated by the plugin for the first time are mode0600. Existing files keep their mode.- Fix: a successful reply no longer ends the 30-second wait after a markup-only reply; only the timer or
/nai reloadends it. A pool refill for that prompt sends at most one request in that window, instead of up tosizerequests in 1.0.2.
Talk, knowledge and logs
- Fix:
/nai talkkeeps the character id as it was typed for the whole session; later replies no longer switch it to lowercase. - While a provider is paused (HTTP 429, quota, authentication failure or a connection error), player replies are paused too: the turn is not sent,
fallback-modelis not used, and the player seesThe character is busy. Try again later.(talk.busy). The provider error goes to the server log with secrets masked, not to chat. - Fix: the length-trim INFO line names a prompt only when the id is loaded from
prompts.ymlor isnai talk. For any other placeholder it shows only the length. - Fix: a knowledge file that is not valid UTF-8 logs one warning naming the file and asking for a UTF-8 re-save, without a stack trace. The file is skipped.
- New guides in the repository:
docs/quickstart.md,docs/faq.md,docs/migration-1.1.0.md, and examples for TAB, AnimatedScoreboard and DeluxeMenus inexamples/.
Known issues
- The player-input boundary and the reply filter reduce prompt-injection risk. They do not eliminate it. A reply that complies directly and never mentions the guard, the boundary, the request or an injection phrase from the player text still reaches the player.
- An HTTP 429 on one model pauses its whole provider. With
round-robin, rows on the same provider are paused together; put independent rows on different providers. - A literal key written in
config.ymlis also present inconfig.yml.bak, because the backup is a copy of your config. Useapi-key-fileor an environment variable to keep keys out of both. - A key placed in the base URL query string is not masked in
/nai status. Useapi-keyorapi-key-fileinstead. - Small models such as
allam-2-7banswer weakly. Do not use a small model alone: put another model later inmodel-queueand keep afallback. - Groq's free tier has a per-minute output-token quota per account, and
max-tokens256 does not remove it. Frequent long/nai talkturns, or many long placeholders, can still return HTTP 429 and pause requests to that provider.
Compatibility
- Paper and Purpur 1.20.6–26.2; Folia is not supported; Java 21 or newer
- PlaceholderAPI 2.11.6+ (soft-depend)
- Tested with PlaceholderAPI 2.12.3 on Paper 1.20.6-151, 1.21.1-133, 1.21.4-232, 1.21.8-60 and 26.2-129, and on Purpur 1.20.6-2233 and 26.2-2633 (Java 21 on 1.20.6–1.21.8, Java 25 on 26.2).
- Paper and Purpur 26.3, Spigot and CraftBukkit are not supported.
Download
NexusAI-1.1.0.jar, SHA-256 8d3414fc3214f5b77f0ee04d3cf37509034b4e451b6019c5eb1b8fdc33611112
Full history: CHANGELOG.md
This mod has no additional files

