Jump to content

Connect SuperML | Leeroopedia MCP: Equip your AI agents with best practices, code verification, and debugging knowledge. Powered by Leeroo — building Organizational Superintelligence. Contact us at founders@leeroo.com.

Principle:OpenHands OpenHands Agent Summary Callback

From Leeroopedia
Knowledge Sources
Domains Platform_Integration, Webhook_Processing
Last Updated 2026-02-11 21:00 GMT

Overview

Agent summary callback is the post-execution hook pattern that generates a summary of the agent's work upon completion and posts the results back to the originating platform.

Description

After an AI agent finishes working on a task (whether successfully or not), the system must close the loop by informing the user of the outcome. The agent summary callback pattern addresses this by registering a callback function that fires when the agent's conversation reaches a terminal state. The callback:

  1. Detects completion -- Listens for terminal events (agent finish, timeout, error) in the conversation's event stream.
  2. Generates a summary -- Condenses the agent's actions, findings, and results into a human-readable summary, often using an LLM to synthesize the raw event log into a concise narrative.
  3. Posts to the platform -- Delivers the summary to the originating GitHub issue, PR, or review thread as a comment, providing closure to the user.

This pattern separates the execution concern (running the agent) from the reporting concern (summarizing and posting results), enabling each to evolve independently.

Usage

Apply this pattern when:

  • Agent execution is decoupled from result reporting (different services or processes)
  • A human-readable summary is needed (raw agent logs are too verbose for end users)
  • The reporting logic varies by platform (GitHub comments vs. Slack messages vs. email)
  • Post-execution hooks are needed for cleanup, billing, or analytics beyond just reporting

Theoretical Basis

1. Callback Processor Pattern

The callback processor pattern registers functions that are invoked when specific events occur in an event stream. The processor subscribes to a conversation's event bus and is called for each event:

class CallbackProcessor:
    def __call__(event) -> Result | None:
        if is_terminal(event):
            summary = generate_summary(event.conversation)
            post_summary(summary)
            return Result(status=COMPLETED)
        return None  # not a terminal event, continue

The processor returns None for non-terminal events (indicating no action taken) and a Result for terminal events (indicating the callback has been executed).

2. Event-Driven Post-Execution Hooks

In event-driven architectures, post-execution hooks decouple the executor from the reporter. The executor emits events; the hook listens for specific event types:

EventStream:
    AgentStarted -> ... -> ToolCalled -> ... -> AgentFinished
                                                      |
                                                      v
                                             CallbackProcessor fires

This decoupling has several benefits:

  • The executor does not need to know about the reporting mechanism
  • Multiple hooks can be registered (e.g., one for GitHub posting, one for analytics, one for billing)
  • Hooks can be added or removed without modifying the executor

3. Summary Generation via LLM

The summary is typically generated by an LLM that reads the agent's conversation history and produces a concise, user-facing narrative:

generate_summary(conversation_history):
    prompt = SUMMARY_TEMPLATE.format(
        actions=conversation_history.actions,
        results=conversation_history.results,
        errors=conversation_history.errors,
    )
    return LLM(prompt)

The summary prompt is engineered to:

  • Highlight the key actions taken (files modified, tests run, PRs created)
  • Report the outcome (success, partial success, failure)
  • Include actionable next steps for the user

4. Conversation Lookup and State Recovery

The callback processor must recover the full conversation state from just a conversation ID, because the callback may execute in a different process or container than the original agent:

recover_state(conversation_id):
    metadata = lookup_metadata(conversation_id)
    events = fetch_event_history(conversation_id)
    view = reconstruct_view(metadata)
    return (metadata, events, view)

This requires that all conversation state is persisted durably (not just held in memory), enabling the callback to reconstruct the context needed for summary generation and posting.

5. Exactly-Once Posting

The callback must ensure the summary is posted exactly once, even if the terminal event is delivered multiple times (e.g., due to event stream replays):

process_terminal(event):
    if already_posted_summary(event.conversation_id):
        return  # idempotent guard
    summary = generate_summary(event.conversation_id)
    post_summary(summary)
    mark_summary_posted(event.conversation_id)

Related Pages

Implemented By

Page Connections

Double-click a node to navigate. Hold to expand connections.
Principle
Implementation
Heuristic
Environment