promotional bannermobile promotional banner

NexusAI

Async AI bridge for Paper via PlaceholderAPI — unique pools, TTL cache, prewarm
Back to Files

NexusAI 1.1.0

File nameNexusAI-1.1.0.jar
Uploader
NearestStepNearestStep
Uploaded
Oct 4, 2026
Downloads
10
Size
3.7 MB
File ID
9055132
Type
R
Release
Supported game versions
  • 26.2
  • 26.1.2
  • 26.1.1
  • 26.1
  • 1.21.11
  • 1.21.10
  • 1.21.9
  • 1.21.8
  • 1.21.7
  • 1.21.6
  • 1.21.5
  • 1.21.4
  • 1.21.3
  • 1.21.1
  • 1.21
  • 1.20.6

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.jar with NexusAI-1.1.0.jar and restart. api-version stays 1.20.6. Commands, permissions and placeholders are unchanged.
  • You do not need to edit config.yml, and do not change config-version. On the first start, missing keys are copied from the jar default: model-queue-strategy (failover), eight context.* keys, six dialogue.summary.* keys inside your existing dialogue: section, and http.max-in-flight and http.queue-size (both 64). The log shows Added missing config keys: …, and that start writes one config.yml.bak (or config.yml.bak.<timestamp> when a backup already exists). Values you already set and your comments stay.
  • The appended defaults keep 1.0.2 behaviour: failover is the 1.0.2 queue order and dialogue summaries are off. context.enabled is true, but a prompt uses context only when it lists context: and another plugin registers a provider.
  • api-key-file is not inserted. Add it under a provider yourself if you want to keep keys in a file.
  • prompts.yml stays on version 1. A prompt without context: keeps its 1.0.2 text and cache key. usage.yml and pool.yml are 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 lower http.max-in-flight for a small or self-hosted endpoint.
  • To roll back: stop the server, put NexusAI-1.0.2.jar back and start it. 1.0.2 ignores the new keys, so config.yml can stay as it is (or restore the config.yml.bak written by 1.1.0). 1.0.2 does not read api-key-file, so move such keys back to api-key or NEXUSAI_API_KEY first. Details are in docs/migration-1.1.0.md.

API keys

  • providers.<id>.api-key-file reads keys from a UTF-8 file, one per line, at startup and on /nai reload. A relative path is under plugins/NexusAI/; an absolute path is allowed. A non-empty path wins over api-key, and NEXUSAI_API_KEY does not replace keys from the file. An empty file still falls back to NEXUSAI_API_KEY on 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 logs chmod 600 <path>.
  • ${ENV:VAR} works the same as ${VAR}. An unset variable is logged by name and becomes an empty string.
  • /nai status and the startup API keys: line show ****abcd (file) or ****abcd (env); a literal key stays ****abcd. Logs, /nai status, /nai test and a failed /nai reload use the same mask. A key from the environment or a key file is never written into config.yml or a backup.
  • A key of 4 characters or fewer is masked as ****, and startup and /nai reload log 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-robin starts each new request at the next available row. Both skip rows on cooldown, over daily-request-limit or at the model-queue-remaining-threshold.
  • An unknown value is treated as failover, with one warning on startup and on /nai reload.
  • /nai status shows the strategy and the next row, for example failover (next: groq/llama). usage.yml accounting is unchanged.

Context providers

  • Other plugins can register a NexusContextProvider through Bukkit's services manager or NexusAIApi.registerContextProvider. NexusAIApi.API_VERSION is now 2.
  • A prompt that lists context: (provider ids, or all) 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 test and literal placeholders do not use context.
  • Providers run on two nexusai-context-N threads, never on the main thread, with the timeouts under context.*. A provider still running at its timeout is interrupted and its value skipped; five timeouts or errors in a row suspend it for context.suspend-seconds. /nai status lists 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.enabled is false by default; while it is off, /nai talk and dialogue-memory.yml work 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-turns player 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.provider and dialogue.summary.model to send summaries to one fixed model.
  • With summaries on, dialogue-memory.yml becomes format: 2; the first such rewrite copies the old file to dialogue-memory.yml.bak once. /nai status shows Dialogue summaries: off or on (N ok, M failed today).
  • Saves of dialogue-memory.yml, pool.yml, usage.yml, config rewrites and prompts.yml imports now write a temporary file and move it into place, keeping the file mode. New files are created as 0600.

HTTP pool

  • Placeholder and queue calls no longer block the four nexusai-http-* threads. http.max-in-flight caps calls in flight and http.queue-size caps how many more may wait (both 64 by default). 0 or a negative value is replaced with 64, with one warning per key. /nai reload applies 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=X becomes http://host/v1/chat/completions?key=X). A URL that already ends in /chat/completions is not extended again, and a trailing slash is ignored.
  • config.yml and prompts.yml created by the plugin for the first time are mode 0600. 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 reload ends it. A pool refill for that prompt sends at most one request in that window, instead of up to size requests in 1.0.2.

Talk, knowledge and logs

  • Fix: /nai talk keeps 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-model is not used, and the player sees The 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.yml or is nai 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 in examples/.

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.yml is also present in config.yml.bak, because the backup is a copy of your config. Use api-key-file or an environment variable to keep keys out of both.
  • A key placed in the base URL query string is not masked in /nai status. Use api-key or api-key-file instead.
  • Small models such as allam-2-7b answer weakly. Do not use a small model alone: put another model later in model-queue and keep a fallback.
  • Groq's free tier has a per-minute output-token quota per account, and max-tokens 256 does not remove it. Frequent long /nai talk turns, 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