Files
LangBot/plugins/Runner/RunnerDemo/README.md

151 lines
8.3 KiB
Markdown
Raw Permalink Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# Runner Workshop
[简体中文](README.zh-CN.md)
A complete, deterministic **Runner** example for LangBot 4.11. It runs
plugin Python handlers directly, with no model, API subscription, or extra runtime
dependency. This is a developer example for the `dev/4.11.x` Host and SDK;
it does not work with older SDKs that lack `Runner`.
## Two selectable components
| Component | Events | Behavior |
|---|---|---|
| Community concierge | Member joined/left, message received/reaction, feedback, friend request | Typed handlers, profile lookups, replies, branching, progress and errors |
| Event observer | `*` | A fallback `EBAEvent` handler that records summaries and optionally the typed payload; never calls tools |
Installing the plugin does **not** activate either component. Create a processor
configuration, select its component in the detail-page header, and save. Add the configuration under **Plugin processor** in a
bot and save; declared events are delivered automatically. Subscriptions run
independently alongside the primary Agent/Pipeline route, and one failed
subscriber does not prevent other deliveries. The observer only receives events
from explicitly bound bots. Old Pipeline `EventListener` hooks are unchanged.
## Install and try
1. Use a running LangBot 4.11 Host and matching Plugin Runtime.
2. In this directory, run `lbp build` with that SDK. The package is written to
`dist/langbot-team-RunnerDemo-0.2.1.lbpkg`.
3. Upload it with **Add extension → local plugin installation** in LangBot.
4. Create two **Plugin processor** configurations. On each detail page, select
**Community concierge** or **Event observer** from the component selector.
5. Open the **Configuration** tab on the right, customize settings, and save.
6. Use the in-page event debugger. Select the event type from an example file,
switch the event editor to **Full JSON**, and paste **only its `data` object**.
The surrounding `{ "event_type": ..., "data": ... }` is the HTTP debug payload.
7. Click **Run test**. The plugin executes for real; platform actions use Mock.
Inspect its logs, action parameters/results, run status and elapsed time.
To receive real platform events, bind the processor configuration to a bot. You can
also create a configuration directly from the bot binding dialog.
Community replies then send real messages. Feedback/reaction/friend-request
handlers record logs only; this example never auto-approves friend requests.
## Scenarios
`examples/scenarios.json` enumerates 12 copyable HTTP debug payloads.
| File | Expected result |
|---|---|
| 01-member-joined | Query actor → query group → welcome reply; 3 traced actions |
| 02-member-left | Warning log; reply only if departure announcements are enabled |
| 03-help | List available `/demo` commands |
| 04-profile | Query the event actor and group, then acknowledge completion |
| 05-slow | Three progress logs over the configured delay, then reply |
| 06-failure | Warning only by default; with failure demo enabled, an error log and failed run |
| 07-feedback | Classify negative feedback; warning and details, no reply |
| 08-reaction | Record added/removed reaction; no reply |
| 09-friend-request | Record the request and a manual-review warning; no approval |
| 10-observer-custom | Observer handles `platform.specific`; enable payload logging to see custom fields |
| 11-echo-with-image | Unicode text is echoed; image type is logged without downloading it |
| 12-ignored-message | Normal non-command message completes without a reply |
Optional lookup failures are recorded as failed actions plus warning logs. The
welcome flow continues with the event's own data. Reply failures propagate and
fail the run, preserving previous logs.
## Configuration
Community settings: output language, welcome text, command prefix, departure
announcements (off by default), demo delay (600 ms by default; clamped to 0–2000),
and intentional failure (off by default). `/demo fail` is an explicit test hook,
not a random error. Welcome text is verbatim configuration and is not translated
automatically when changing output language.
Observer settings: output language and payload logging (off by default). Payload
logging includes typed event data but excludes the raw platform object.
## Shared-runtime certification profile
RunnerDemo declares `execution.sharedRuntime: shared-runtime-v1` and keeps its
runtime modules free of process-wide or mutable module state; configuration and
per-run data stay on `RunnerContext`. `tests/test_shared_runtime.py` reproduces
the two-binding proof locally with the released SDK: one real worker
(`PluginRuntimeController` + the `RunnerDemo` instance + one instance per
component) is attached twice, as workspace-A/installation-A and
workspace-B/installation-B, and both installations are driven concurrently
through the `community` component with distinct configuration, events and
results. The same test detaches one installation and checks that the sibling
graph survives, so a regression to per-installation object graphs fails it
instead of passing vacuously. Only Host/backend RPC responses are fixtures. A
local `lbp build` archive is still unsigned and has no certification comment.
Space approval is the separate gate that may issue and sign a certification
envelope; this repository does not claim that approval or certificate.
## Development and repeatable verification
```bash
# Use the matching SDK environment first.
python -m pip install -r requirements-dev.txt
python -m unittest discover -s tests -v
lbp build
# Optional: install and run all examples through the real Host HTTP API.
# Use a token or API key with resource manage and operate permissions.
export LANGBOT_API_KEY='your-key'
python scripts/smoke.py --base-url http://127.0.0.1:5399
```
`LANGBOT_TOKEN` can be used instead of an API key; optionally set
`LANGBOT_WORKSPACE_ID`. The smoke script installs the package, creates/reuses two
clearly named demo configurations, sets their parameters, executes 12 scenarios and verifies
that debug replies are Mock. It deliberately creates one failed run, then turns
the failure option off in `finally`. It enables departure announcements and
observer payload logging on its demo configurations. It creates no Bot bindings.
The receipt is saved to ignored `data/smoke-results.json`; credentials are never
saved. Re-running adds another set of run records.
## Source map
- `components/runner/community.py`: typed `@self.handler(...)` examples.
- `components/runner/observer.py`: generic event fallback handler.
- Matching YAML files: independent component configs, event declarations and permissions.
- `tests/test_processors.py`: all samples, trace pairing, fault handling, Unicode and config isolation.
- `tests/test_shared_runtime.py`: real SDK worker with two installation bindings — object-graph identity, per-binding configuration/results, slot detach.
- `scripts/smoke.py`: actual package installation and Host/runtime integration check.
The component API exposes `ctx.event`, `ctx.config`, `ctx.run_id`, `ctx.log()`,
`ctx.reply()` and `ctx.get_available_tools()`. Platform and LangBot APIs use `self.plugin` and automatically retain invocation grants. There is no legacy Pipeline Query or
Agent loop to construct; returning from the handler ends that invocation.
## Full event matrix
Create a dedicated **Event observer** configuration with payload logging enabled and
no Bot bindings. With the same authentication environment as above, run:
```bash
python scripts/event_matrix.py --base-url http://127.0.0.1:5399 --processor-id YOUR_PROCESSOR_UUID
```
`examples/event-matrix.json` covers all 17 standard events with minimal and
populated payloads, eight extra variants (including empty/image-only messages,
feedback values and temporary bans), and six invalid inputs: 48 cases total.
The script checks typed payload preservation, exactly one completed run per valid
input, persisted run status, no action calls, and rejection of invalid inputs.
It adds debug run records and writes an ignored receipt to
`data/event-matrix-results.json`. It does not install plugins or modify bindings.
This validates the Host/runtime processing path; platform-specific event support
and actual delivery must still be verified against each adapter.
Observer declares `usages: [agent, event]` and can be selected by either an Agent or a Plugin processor. Community declares `usages: [event]`. Both use the same Runner context and event handlers.