Files
JWeBot/docs/command-routing.md
JWeBot Contributors afc71e63a7
check / local-gate (push) Failing after 1m35s
Release beta 1.0.0 baseline
2026-10-16 01:07:07 +08:00

5.4 KiB

Command Registration And Execution Paths

Status: authoritative local registration and routing contract for beta 1.0.x.

Three Execution Paths

Every accepted message resolves to exactly one named execution path:

Execution path Input Runtime Reply behavior
local-command Registered /command Kernel command or reviewed plugin Synchronous local reply, except explicitly asynchronous Steam
deepseek Ordinary @JWeBot message Direct DeepSeek client Fast ACK, background generation, ACK-gated final reply
openclaw @JWeBot #task OpenClaw cloud runner Fast ACK, durable cloud outbox, ACK-gated final reply

The compatibility route values remain local, chat, and cloud in stored events. API responses and telemetry also include the explicit execution_path, so operators and plugin authors do not need to infer the actual provider from a legacy storage label.

Unknown slash commands remain on local-command and fail with a local command error. They never fall through to DeepSeek or OpenClaw.

Fast Local Ingress

The local command path is:

  1. XDamage reports a relevant message-region change, or a two-second idle reconciliation capture detects a missed final drawing.
  2. OpenCV segments incoming bubbles without running OCR over the whole screen.
  3. The OCR engine reuses exact visual-fingerprint matches from a bounded LRU.
  4. Only new or changed sender/body crops use RapidOCR.
  5. Both recognition-only and detection fallback paths are prewarmed at startup.
  6. A command event is written to an atomic, fsynced spool file.
  7. The in-process responder is signalled immediately after durable replacement.
  8. Edge durably records and executes the local command.
  9. The guarded GUI sender revalidates the selected group and sends the reply.

The queue directory remains the recovery source of truth. The wake signal is only a latency optimization; a separate responder process or a missed signal still discovers work through the bounded one-second fallback scan.

Exact image bytes, crop dimensions, and sender pixels participate in the OCR cache key. Identical repeated messages remain separate visible occurrences because each bubble position still produces its own IncomingMessage. Changed pixels force fresh OCR. The cache is bounded and periodically revalidated.

For the local plugins introduced during the 0.6.x line, including bilingual commands, person identity limitations and atomic single-player game settlement, see local plugin rules.

Bundled Plugin Registration

Bundled command metadata has one source:

packages/jwebot-official-extensions/
  src/jwebot_official_extensions/descriptors.py

Each LocalExtensionDescriptor declares:

  • extension_id;
  • author;
  • user-visible description;
  • user-visible help_entries;
  • owned internal command_kinds.

Aliases are resolved from the same inventory. Run:

./tools/sync-local-extensions.py

The generator writes matching:

  • plugin.toml;
  • SDK adapter source;
  • package README;
  • package registration test;
  • in-process compatibility adapter.

--check is part of the repository gate and rejects generated drift.

Friend Plugin Registration

Create a command plugin with explicit user-facing metadata:

./tools/create-plugin.py weather-command /weather \
  --author FriendName \
  --description "查询指定城市天气" \
  --help-entry "/weather 城市"

The command must also be registered in the plugin entrypoint:

def plugin(context):
    context.commands.register("/weather", handle)

Startup fails if registered commands differ from signed manifest commands. The catalog freezes after startup, so command ownership cannot change during request processing.

Automatic Help

/功能列表, /帮助, and /help are Kernel commands. Their visible output is generated from:

  • Kernel command descriptors;
  • each bundled plugin's description;
  • each bundled plugin's help_entries;
  • the fixed DeepSeek and OpenClaw path descriptions.

There is no separate hand-maintained help list. Adding or changing a bundled plugin command without updating its descriptor changes generated files and fails the sync gate.

Signed Host health responses include description and help metadata. Edge compares them with the startup inventory together with author, commands, and service profiles before activating the Host.

Manifest Metadata

Command manifests must declare:

description = "查询指定城市天气"
help = ["/weather 城市"]

description and help must be declared together. Help entries are bounded, single-line command usage strings beginning with /. Bundled plugins require both fields.

User-visible help text is metadata only. It grants no capability and cannot change routing ownership.

Official Operational Plugins

Operational slash commands are implemented through official reviewed plugin descriptors unless they are strictly Kernel-only. The current official operational commands are:

  • /状态 and /status: server, Edge, OCR, and queue status.
  • /version: installed JWeBot package versions plus the latest changelog date and summary.
  • /debug: recent privacy-safe telemetry p50/p95/max summary.

These commands delegate to Kernel-owned service profiles through generated adapters. They do not give plugin code direct access to raw SQLite, systemd, journal, GUI, shell, or secrets.