AWorld Plugin SDK
This document describes the current host-supported contract for framework plugins.
Manifest Contract
- Canonical manifest path:
plugin_root/.aworld-plugin/plugin.json - JSON schema file:
aworld/plugins/plugin.schema.json - Required fields:
idversion- Common optional fields:
nameactivation_scopeentrypointsdependenciesconflicts
Validation
Validate an installed plugin by name:
aworld-cli plugins validate aworld-hud
Validate an arbitrary plugin root on disk:
aworld-cli plugins validate --path /path/to/plugin
Validate an installed plugin from inside the interactive CLI:
/plugins validate aworld-hud
Validation currently checks:
- manifest shape can be loaded
- entrypoint targets resolve inside the plugin root
- legacy plugin roots still expose
agents/orskills/
If you only need to manage installed plugins from the interactive session, see Plugins.
Activation Resolution
At runtime, manifest-declared activation metadata is now consumed:
dependencies: a plugin is skipped unless all declared plugin IDs are already activeconflicts: a plugin is skipped if it conflicts with any already active plugin ID
Resolution is deterministic and follows plugin discovery order.
Public Capability Surface
Host-owned plugin capability helpers live under aworld_cli.plugin_capabilities.
Legacy alias namespaces aworld_cli.plugin_runtime.* and aworld_cli.plugin_framework.* have been removed.
Interactive Slash Command Contract
Framework plugins may contribute interactive slash commands through manifest entrypoints.commands.
Minimal markdown-backed manifest example:
{
"id": "example-command-plugin",
"version": "1.0.0",
"entrypoints": {
"commands": [
{
"id": "review-loop",
"name": "review-loop",
"target": "commands/review-loop.md",
"scope": "workspace"
}
]
}
}
Markdown-backed command behavior:
- the target file is loaded as prompt text
- the CLI appends
User args: ... - the generated prompt is executed through the active agent session
Framework plugins may also contribute Python-backed interactive commands.
Minimal Python-backed manifest example:
{
"id": "example-command-plugin",
"version": "1.0.0",
"entrypoints": {
"commands": [
{
"id": "goal",
"name": "goal",
"target": "commands/goal.py",
"scope": "session",
"metadata": {
"factory": "build_command"
}
}
]
}
}
Python target module contract:
- default factory name is
build_command - the factory is called as
build_command(plugin, entrypoint) - the factory must return an
aworld_cli.core.command_system.Commandinstance
Useful host integration points for Python-backed commands:
CommandContext.cwdCommandContext.user_argsCommandContext.runtimeCommandContext.session_id
If a command needs access to plugin-scoped persisted state, it should resolve state through the runtime-owned plugin state store rather than creating ad hoc dotfiles.
CLI Command Contract
Framework plugins may contribute top-level CLI commands through manifest entrypoints.cli_commands.
Minimal manifest example:
{
"id": "example-cli-plugin",
"version": "1.0.0",
"entrypoints": {
"cli_commands": [
{
"id": "example",
"name": "example",
"target": "cli_commands/example.py",
"metadata": {
"factory": "build_command",
"aliases": ["example-short"]
}
}
]
}
}
Target module contract:
- default factory name is
build_command - the factory must return a
TopLevelCommand-compatible object - alternatively, the module may expose a
COMMANDobject directly
Command object requirements:
namedescriptionregister_parser(subparsers)run(args, context)
Current bootstrap behavior:
- only enabled framework plugins contribute top-level CLI commands
metadata.aliasesregisters additional top-level command aliases- aliases are normalized to the canonical command name before
argparsedispatch visibility: "hidden"suppresses registration- reserved kernel command names cannot be overridden by plugins
Reserved top-level kernel commands:
interactivelistservebatchbatch-jobpluginsgateway
Current plugin-safe HUD helper API:
aworld_cli.plugin_capabilities.hud_helpers.format_hud_tokensaworld_cli.plugin_capabilities.hud_helpers.format_hud_elapsedaworld_cli.plugin_capabilities.hud_helpers.format_hud_context_bar
Current plugin-safe hook typing API:
aworld_cli.plugin_capabilities.hooks.StopHookEventaworld_cli.plugin_capabilities.hooks.TaskStartedHookEventaworld_cli.plugin_capabilities.hooks.TaskProgressHookEventaworld_cli.plugin_capabilities.hooks.TaskCompletedHookEventaworld_cli.plugin_capabilities.hooks.TaskErrorHookEventaworld_cli.plugin_capabilities.hooks.TaskInterruptedHookEventaworld_cli.plugin_capabilities.hooks.HookEventPayload
Hook State Contract
Hook handlers receive:
event: host-owned event payload for the current hook pointstate: plugin-scoped persisted state plus host-owned identifiers likesession_id,workspace_path,task_id
Writable plugin state is exposed through:
state["__plugin_state__"].read()state["__plugin_state__"].write(payload)state["__plugin_state__"].update(payload)state["__plugin_state__"].clear()
Current task lifecycle hook points available to plugins:
task_startedtask_progresstask_completedtask_errortask_interruptedstop
Event payload fields currently emitted by the host:
stoptranscript_pathworkspace_pathsession_idtask_idtask_startedtask_idsession_idworkspace_pathmessagetask_progresstask_idsession_idworkspace_pathcurrent_toolelapsed_secondsusagetask_completedtask_idsession_idworkspace_pathtask_statusfinal_answertask_errortask_idsession_idworkspace_pathtask_statuserrorerror_typetask_interruptedtask_idsession_idworkspace_pathtask_statuspartial_answer
HUD Contract
HUD providers are plugin-owned. The host only collects and renders lines.
Supported provider signatures:
render_lines(context)render_lines(context, plugin_state)
context is host-owned runtime data. plugin_state is plugin-owned state read from the plugin state store.