Skip to content

[Feature]: Expose onToolStart/onCompactionStart callbacks to plugin-sdk #53122

Description

@jeket3

Summary

Allow channel plugins to react to agent lifecycle events (tool calls, compaction) by exposing onToolStart/onCompactionStart callbacks through dispatchInboundReplyWithBase.

Problem to solve

Channel plugins (Max Messenger, WhatsApp, etc.) cannot react to agent lifecycle events. When the agent works with tools (file reads, command execution, API calls), users see nothing until the entire response is ready.

The Discord plugin uses internal statusReactions to show "🔧 Working with [tool]" reactions, but this is only available to built-in channels. External plugins using dispatchInboundReplyWithBase from plugin-sdk have no access to these hooks.

This creates poor UX:

  • Users think the bot is frozen during long tool calls
  • No feedback while agent is working
  • Can't extend typing indicator during processing

Proposed solution

Add lifecycle callbacks to dispatcherOptions in plugin-sdk:

interface DispatcherOptions {
// ... existing options
onToolStart?: (payload: { name?: string; phase: string }) => Promise;
onCompactionStart?: () => Promise;
onCompactionEnd?: () => Promise;
}

These callbacks would be passed through dispatchInboundReplyWithBase and called at appropriate points during agent execution.

Implementation: The internal statusReactions in Discord channel already uses these hooks. Extract and expose to plugin-sdk.

Alternatives considered

  1. Polling agent status from plugin - inefficient, adds latency
  2. Sending periodic "still working" messages from core - requires core changes anyway
  3. Typing timeout extension (current workaround) - only hides the problem, doesn't solve it

Impact

Affected: All external channel plugins (Max Messenger, WhatsApp, etc.)
Severity: Blocks good UX - users confused when bot appears frozen
Frequency: Every response with tool calls (common for LLM agents)
Consequence: Users may think bot is broken or slow, poor user retention

Evidence/examples

Current workaround in Max Messenger plugin:
const maxMs = params.maxMs ?? 300_000; // Extended from 90s to 5min

Discord's internal implementation already has:
statusReactions.setTool(payload.name) // Called via onToolStart

Additional information

Related code locations:

  • Discord implementation: dist/discord-CcCLMjHw.js:131502 - uses onToolStart
  • Current plugin-sdk: dist/plugin-sdk/inbound-reply-dispatch-0KQ4b86b.js - doesn't expose callbacks

Metadata

Metadata

Assignees

No one assigned

    Labels

    enhancementNew feature or request

    Type

    No type

    Fields

    Priority

    None yet

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions