mirror of
https://github.com/langbot-app/LangBot.git
synced 2026-09-11 04:17:14 +00:00
93 lines
5.3 KiB
Markdown
93 lines
5.3 KiB
Markdown
# Runner components and Pipeline plugin compatibility
|
|
|
|
## Product boundary
|
|
|
|
| Product | Implementation | Event entry |
|
|
| --- | --- | --- |
|
|
| Pipeline | Pipeline stages and an agent-capable Runner | Received messages |
|
|
| Agent | A Runner with `spec.usages: [agent]` | Configured events |
|
|
| Plugin processor | A Runner with `spec.usages: [event]` | Events declared in `spec.events` |
|
|
|
|
Runner is the only component for these execution styles. `spec.usages` can contain
|
|
both `agent` and `event`; these are selection capabilities, not mutually exclusive
|
|
execution modes. An installed component is reusable code. Users create processor
|
|
instances, select a Runner and configure it, then bind Bot events to the instance.
|
|
Installation alone never subscribes a component to incoming events.
|
|
|
|
## Legacy EventListener contract
|
|
|
|
EventListener remains a Pipeline extension. Existing plugins retain their import
|
|
paths, handler registration syntax, event classes, Query-based APIs, and Pipeline
|
|
plugin selection behavior. No conversion of installed listeners into standalone
|
|
processor instances takes place.
|
|
|
|
Compatibility must cover execution behavior, not just successful deserialization:
|
|
|
|
| Hook | Required behavior |
|
|
| --- | --- |
|
|
| PersonMessageReceived / GroupMessageReceived | Read the returned EventContext before later stages; retain message edits and default prevention |
|
|
| PromptPreProcessing | Preserve timing and apply returned default_prompt and prompt |
|
|
| PersonNormalMessageReceived / GroupNormalMessageReceived | Preserve user_message_alter, default prevention, and replacement replies |
|
|
| PersonCommandSent / GroupCommandSent | Preserve command stage timing, default prevention, and replacement replies |
|
|
| NormalMessageResponded | Preserve response-stage timing, default prevention, and replacement message chains, including streaming behavior |
|
|
| All hooks | Preserve plugin ordering, prevent_postorder across installations, bound-plugin filtering, Query identity, and Workspace scope |
|
|
|
|
RPC responses are new Python objects. Host code must consume returned values
|
|
rather than assume mutations reached the original Query by object identity.
|
|
Host-only references, including the active Query and raw adapter message, must
|
|
remain available for legacy reply APIs without being exposed in serialized
|
|
plugin events.
|
|
|
|
Preserve source event fields across EBA-to-legacy conversion, including group
|
|
member permissions, bot group permissions, and member titles. Missing platform
|
|
information must be distinguished from fields that were dropped during conversion.
|
|
|
|
Direct Agent and Event processor execution must not synthesize Pipeline lifecycle
|
|
hooks. Those hooks describe actual Pipeline stages.
|
|
|
|
## SDK and runtime
|
|
|
|
`lbp comp Runner` generates `components/runner`. Every component uses
|
|
`plugin:author/plugin/name` as its identity. Names are unique within a plugin.
|
|
The component can override `async run(ctx)` and yield RunnerResult objects, or
|
|
register typed platform callbacks through `@self.handler(EventClass)` in
|
|
`initialize()`. Default run dispatches an exact handler, falling back to EBAEvent.
|
|
A custom run can delegate to this dispatch with `await super().run(ctx)`.
|
|
|
|
Both styles share RunnerContext, invocation-bound ctx.api, logs, replies, deadlines,
|
|
cancellation, worker isolation and the run ledger. ctx.event is the envelope;
|
|
ctx.platform_event is the typed platform payload. Each invocation owns its context;
|
|
never put the current context or run ID on a shared component or plugin instance.
|
|
|
|
The runtime emits completion on normal return unless the Runner already emitted a
|
|
terminal result. Exceptions fail the run and retain preceding results. Cancelling
|
|
the result stream cancels execution. There is no implicit retry or hidden model
|
|
loop. Returned text and logs do not send platform messages: replies are explicit
|
|
ctx.reply / ctx.reply_stream actions. Pipeline retains its configured output stage.
|
|
|
|
`self.plugin` continues to expose ordinary plugin APIs. ctx.api carries run-scoped
|
|
resource grants and records tool actions. Workspace and installation authorization
|
|
remain Host-enforced. Run identity and API operation scope are separate concepts.
|
|
|
|
## Selection and observability
|
|
|
|
Both product selectors discover the same Runner catalog and filter by usage.
|
|
Validate usage again before execution. Event-capable Runners must declare events;
|
|
users can route a subset, but cannot expand the manifest capability. Unconfigured
|
|
instances expose no event subscriptions. Workspace ownership, plugin scope and
|
|
instance identity are checked for routing, execution, cancellation and run reads.
|
|
|
|
Plugin processor details keep event debugging on the left and configuration/logs
|
|
on the right. Component settings use the existing schema form. Logs and action
|
|
results remain distinct from actual platform delivery; debug delivery is Mock.
|
|
Agent-native interactions stay on the Agent product path; typed handlers consume
|
|
platform events. Legacy Pipeline lifecycle hooks remain on the Pipeline path.
|
|
|
|
## Validation
|
|
|
|
SDK tests cover both execution styles, event matrices, concurrent contexts,
|
|
termination, cancellation and permissions. Packaged CLI tests generate, build and
|
|
execute the published component. Core tests cover usage-filtered discovery, event
|
|
routing, Workspace authorization and real plugin-runtime transport. RunnerDemo
|
|
provides multi-step actions, configuration isolation and controlled failures.
|