AbstractProtectedavailableAll active agents, loaded at init for multi-word name matching. Sorted longest-name-first.
ProtecteddefaultDefault agent loaded from config DefaultAgentName.
ProtectedfallbackFallback context user (service account) loaded from config email.
ProtectedsettingsExtension settings from mj.config.cjs.
Get the list of available agent names, sorted longest-first. Useful for subclasses implementing multi-word agent name matching.
Protected AbstractPlatformHuman-readable platform name (e.g., "Slack", "Teams") used in conversation names and log messages. Subclasses must return their platform identifier.
ProtectedbuildBuild an AgentIdentity from an agent entity.
Only includes IconURL if it's a valid HTTPS URL.
Protected AbstractfetchFetch the thread history for the given message from the platform API.
Channel/conversation ID.
Thread/reply chain ID.
Array of messages in the thread, oldest first.
Protected AbstractformatConvert an agent execution result to the platform's rich format.
The full agent execution result.
The agent that produced the result.
Extracted human-readable response text.
Optionalmetadata: AgentResponseMetadataOptional metadata about the conversation/artifact for deep linking.
Protected AbstractgetGet the bot's own user ID on this platform (to identify bot messages in thread history).
Main entry point: handle an incoming message from the platform.
Orchestrates the full flow from message receipt to response delivery. Errors are caught and reported as user-facing error messages — this method never throws.
Normalized incoming message from the platform adapter.
Initialize the adapter: resolve the fallback context user, load the default MJ agent (using the fallback user as contextUser), load all available agents, then run platform init. Must be called before handling any messages.
Protected AbstractlookupLook up the email address for a platform user ID. Used for mapping platform identity to MJ user.
Platform-specific user ID.
Email address, or null if not available.
ProtectedmatchMatch agent names mentioned in the message text against known agents.
Strips the bot's platform mention, then checks for known agent names
preceded by @ (case-insensitive). Names are checked longest-first
to avoid prefix collisions (e.g., "Research Agent" before "Research").
The raw message text.
Array of matched agent names.
Protected AbstractonPlatform-specific initialization (e.g., fetch bot user ID, open WebSocket).
Called at the end of Initialize().
ProtectedresolveResolve which agent to use for this message.
Priority:
ProtectedresolveResolve the MJ user for the platform sender.
Flow:
lookupUserEmail() (platform API) then look upProtected AbstractsendSend the final formatted response as a new message in the thread.
Protected AbstractsendSend or update a streaming progress message. Returns the message ID.
If existingMessageId is null, posts a new message.
If existingMessageId is provided, updates the existing message in place.
The message being responded to.
Accumulated streamed content so far.
ID of an existing progress message to update, or null.
Optionalagent: MJAIAgentEntityExtendedThe agent generating the response (for per-agent identity).
The message ID of the progress message (new or existing).
ProtectedshouldDetermine whether the bot should respond to this message.
Responds to:
Protected AbstractshowShow a typing/thinking indicator in the channel. Some platforms (Teams) have explicit typing APIs; others (Slack) use a first streaming message as the "thinking" indicator.
The incoming message triggering the indicator.
Optionalagent: MJAIAgentEntityExtendedThe agent that will respond (for per-agent identity).
Protected AbstractstripProtected AbstractupdateUpdate an existing streaming message with the final formatted response.
Abstract base class for messaging platform adapters.
Handles the common orchestration flow that is shared across all messaging platforms (Slack, Teams, Discord, etc.):
AgentRunner.RunAgent()with streamingPlatform subclasses implement the abstract methods for platform-specific operations (sending messages, fetching threads, formatting responses).
This class is NOT a
BaseServerExtensionitself — the platform-specific Extension classes (e.g.,SlackMessagingExtension) own the Express route registration and delegate message handling to their adapter instance.Multi-Agent Routing
Users can
Mention
different agents in different messages within the same thread. Each message routes to exactly one agent. If multiple agents are mentioned in a single message, the first one is used and a note is included in the response.
Multi-Word Agent Names
Agent names can be multi-word (e.g., "Research Agent"). At initialization, all active agents are loaded from the database. When parsing @mentions, known agent names are matched longest-first to avoid prefix collisions.
User Identity Mapping
The adapter resolves the platform user's email to an MJ
UserInforecord. This gives proper per-user permission scoping without a separate auth flow. Falls back to the configured service account email if no MJ user matches.