3.1 KiB
Tess Plugin Authoring
Plugins are replaceable adapters. Declare capabilities, derive scope from trusted context, preserve correlation IDs, redact before persistence/egress, and return unsupported operations as fail-closed results. Names and identities are configuration data, not literals in keys or defaults.
Official channel adapter contract
Official Discord, Matrix, Slack, and future channel adapters share contracts exported from @mosaicstack/types under channel/:
OfficialChannelAdapterprovidesname,start(),stop(), and non-throwing connectionhealth().ChannelMessageDtoandChannelAttachmentDtonormalize transport data with JSON-safe metadata.ChannelBindingDtoandChannelAuthorizedPrincipalDtonormalize configuration-owned logical-agent binding and the already-allowlisted/paired external actor.ChannelIngressDtocarries operation, correlation, native message ID, authorized principal, normalized message, and stable route intoChannelIngressPort.ChannelConversationRouteDtobinds a configured channel tologicalAgentId, stableconversationId, authorization parent, and response target.ChannelEgressDtoandChannelEgressPortseparate where a response is delivered from the gateway's runtime/provider selection.
ChannelConversationRouteDto deliberately has no harness, provider, model, process, or native runtime-session field. The gateway owns runtime selection, durable enrollment, authorization, audit, and lease/fencing. A channel adapter must not call Claude, Codex, Pi, OpenCode, tmux, or Matrix runtime providers directly. Discord currently preserves its signed Socket.IO compatibility ingress for established gateway authentication/replay/approval controls while normalizing the same ingress DTO; supplied direct ports are the future registration path.
Adapter requirements
- Resolve configuration-owned channel and logical-agent bindings before dispatch. A binding may carry a trusted gateway agent-config reference, but the stable route contains only the logical agent; gateway verifies the reference resolves to that agent before runtime selection.
- Apply channel-native allowlists and paired-user roles before any external side effect such as thread creation.
- Preserve native message ID, correlation ID, channel/thread address, attachments, and response target.
- Treat normal channel parents (for example Discord categories) separately from thread parents.
- Keep reconnect and conversation identity independent of the active runtime provider.
- Report sanitized connection/routing failures without message bodies or credentials.
- Pass the shared route/authorization contract suite plus adapter-specific translation tests.
Discord establishes the first policy: authorized untagged messages respond in the configured channel; a mention creates a thread or reuses the thread already attached to that message; existing thread messages stay there. Runtime control commands remain on the current durable session. Matrix and Slack should translate native rooms/threads into the same route and response-target semantics rather than adding transport branches to gateway core.