155 lines
5.3 KiB
Markdown
155 lines
5.3 KiB
Markdown
# Command Registration And Execution Paths
|
|
|
|
Status: authoritative local registration and routing contract for
|
|
`alpha 0.6.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 three local plugins added in `alpha 0.6.1.1015`, including bilingual
|
|
commands, person identity limitations and atomic single-player game settlement,
|
|
see [local plugin rules](local-plugins-0.6.1.md).
|
|
|
|
## Bundled Plugin Registration
|
|
|
|
Bundled command metadata has one source:
|
|
|
|
```text
|
|
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:
|
|
|
|
```sh
|
|
./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:
|
|
|
|
```sh
|
|
./tools/create-plugin.py weather-command /weather \
|
|
--author FriendName \
|
|
--description "查询指定城市天气" \
|
|
--help-entry "/weather 城市"
|
|
```
|
|
|
|
The command must also be registered in the plugin entrypoint:
|
|
|
|
```python
|
|
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:
|
|
|
|
```toml
|
|
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.
|
|
- `/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.
|