Prerequisite plugins (requires_plugins)
When a plugin needs another plugin installed first in order to work (the typical case: your ASR / MT plugin relies on another plugin providing an inference runtime such as
llama-server.exe), declare the dependency inmod.json.
Declaration
{
"id": "web.yourname.amd_hy_mt",
"type": "mt",
"requires_plugins": [
{
"id": "workshop.amd_llama",
"min_version": "1.0.0",
"reason": "提供 llama.cpp 运行时(llama-server.exe)"
}
]
}| Field | Required | Description |
|---|---|---|
id | Yes | the mod id of the prerequisite plugin; at most 8 entries (extras are dropped) |
min_version | No | the minimum version required (semver) |
reason | No | one sentence explaining why it is needed (shown to the user) |
Short form: when an entry only has an id you can write it as a string — "requires_plugins": ["workshop.amd_llama"].
Depending on official ids (such as
community.mt.haidass_143m) is allowed, and is not restricted by the "reserved segment" rule. Duplicate ids are de-duplicated.
Host behaviour
| Moment | Behaviour |
|---|---|
| Startup scan | Dependency not in place (not installed / not enabled / version too low) → force-disable the plugin (a backstop for leftover state) |
| Enable switch | Refuse to enable + an overlay hint (with the plugin name, what is missing, and how to handle it) |
| Selecting it as the ASR/MT/TTS engine | Refuse (the same gate as enabling) |
| Starting live interpreting | The readiness check reports missing_dependency → blocked + a clear hint (it will not just say "xxx runtime not found") |
| Extension Workshop card | Shows "requires prerequisite plugin: …" + one-click install / enable / update (when only one is missing) |
The host does not install a prerequisite plugin automatically (plugins that contain code may not be installed silently) — only after the user clicks "Install" is it downloaded from the workshop of the current channel.
How to get files from a prerequisite plugin's directory (important)
❌ Do not hard-code the sibling directory name: when installed from the workshop the directory name = the plugin id (
<data dir>/workshop/workshop.amd_llama), whereas what you dropped intoextensions/by hand may use the underscore spelling (extensions/workshop_amd_llama). Only looking it up by id is correct on both sides.
from pathlib import Path
def _locate_llama_server(self):
# ✅ Recommended: the host API
dep_dir = self.host.plugin_dir("workshop.amd_llama") # returns "" when not installed
if dep_dir:
exe = Path(dep_dir) / "llama" / "llama-server.exe"
if exe.exists():
return exe
# Alternative: iterate yourself (each entry carries source_path)
for m in self.host.list_installed_plugins():
if m.get("id") == "workshop.amd_llama":
exe = Path(m["source_path"]) / "llama" / "llama-server.exe"
if exe.exists():
return exe
return NoneCompanion advice: in check_ready(), when the runtime cannot be found return (False, "model_not_ready", "需要先安装「llama 运行时」插件") — the user then sees a plain-language hint before starting.
Related APIs: host.plugin_dir(id) / host.has_plugin(id) / host.list_installed_plugins(type_filter), see Session & host state.
Relationship with requires_runtime
If what you depend on is a native runtime of tens of MB, do not go the "plugin depends on plugin" route; use Host runtimes (requires_runtime) instead: the host brings download / verify / unpack, and the plugin only declares which one it needs.
Dependency chains take effect too: with A requires_plugins B and B requires_runtime llama_runtime, when the runtime is not installed A is blocked as well, with the hint "requires prerequisite plugin: B is missing runtime: llama.cpp runtime (not downloaded)".
