ProtectedavailableAll 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.
ProtectedPlatformHuman-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.
ProtectedfetchFetch all messages in a Slack thread using conversations.replies.
ProtectedformatFormat agent response as rich Slack Block Kit blocks.
When a full ExecuteAgentResult is available, builds a rich layout with
agent header, artifact cards, action buttons, and metadata footer.
Falls back to simple markdown→blocks conversion for plain text.
Optionalmetadata: AgentResponseMetadataProtectedgetGet 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.
ProtectedlookupLook up a Slack user's email address via the Web API.
Requires the users:read.email scope on the bot token.
Slack user ID (e.g., U0123456).
Email address, or null if not available.
Convert a raw Slack event payload into a normalized IncomingMessage.
Called by SlackMessagingExtension when a webhook event is received.
Uses multi-word agent name matching against the loaded agent list.
Raw Slack event object from the Events API.
Normalized incoming message.
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.
ProtectedonFetch the bot's own user ID from the Slack API. This is needed to identify bot messages in thread history.
ProtectedresolveResolve which agent to use for this message.
Priority:
ProtectedresolveResolve the MJ user for the platform sender.
Flow:
lookupUserEmail() (platform API) then look upProtectedsendSend the final formatted response. If a "Thinking..." message exists (no streaming occurred), update it in-place instead of posting a new message.
ProtectedsendPost a new streaming message or update an existing one. Shows the agent's identity on new messages.
Optionalagent: MJAIAgentEntityExtendedProtectedshouldDetermine whether the bot should respond to this message.
Responds to:
ProtectedshowPost a "Thinking..." message as the typing indicator. Shows the agent's identity if available. This message gets replaced in-place by the first streaming update.
Optionalagent: MJAIAgentEntityExtendedProtectedstripProtectedupdateUpdate the streaming progress message with the final formatted response.
Slack-specific adapter that implements all platform operations using the Slack Web API (
@slack/web-api).Features
conversations.replieschat.postMessage/chat.update@Research Agent)users.infofor MJ user mappingAuthentication
Requires a Bot User OAuth Token (
xoxb-...) with these scopes:chat:write— Post and update messageschat:write.customize— Post with custom username and iconchannels:history/groups:history/im:history— Read thread historyusers:read/users:read.email— Look up user email addressesapp_mentions:read— ReceiveMention
events