Skip to content

Add typed event emitter to BaseConversation#744

Draft
kraenhansen wants to merge 1 commit into
kh/event-emitter-event-mapfrom
kh/event-emitter-base
Draft

Add typed event emitter to BaseConversation#744
kraenhansen wants to merge 1 commit into
kh/event-emitter-event-mapfrom
kh/event-emitter-base

Conversation

@kraenhansen

@kraenhansen kraenhansen commented May 7, 2026

Copy link
Copy Markdown
Member

Summary

  • Add on(), off(), and emit() methods to BaseConversation with full ConversationEventMap typing
  • on() returns an unsubscribe function; multiple listeners per event are supported
  • Constructor-provided callbacks are automatically registered as initial listeners via CALLBACK_KEY_TO_EVENT_NAME
  • Replace all this.options.onXxx() invocations in BaseConversation with this.emit() calls
  • Add changeset for @elevenlabs/client minor bump

Part of #738 (PR 4/6).

Test plan

  • All 97 client tests pass (including agent_response_correction callback test)
  • All 30 turbo tasks pass (build, check-types, lint across all packages)
  • Existing Conversation.startSession({ onMessage: ... }) API unchanged
  • Manual: verify events fire correctly in agent-testbench example

🤖 Generated with Claude Code


Note

Medium Risk
Refactors how conversation events are dispatched (callbacks now routed through an emitter), which could subtly change event ordering/duplication and error propagation across the SDK.

Overview
Adds a typed event emitter API to conversations via new BaseConversation.on()/off() (with on() returning an unsubscribe) and an internal emit().

Re-routes all existing constructor callback options (onMessage, onDisconnect, etc.) through the emitter by auto-registering them at construction time and replacing direct options.onXxx() calls with emit() invocations (including guarded handling for unhandled-client-tool-call).

Includes a @elevenlabs/client changeset for a minor version bump and updates the BaseConversation test harness to call the renamed message handler.

Reviewed by Cursor Bugbot for commit 269e93c. Bugbot is set up for automated code reviews on this repo. Configure here.

Replace direct this.options.onXxx() callback invocations with
this.emit() calls through a typed event emitter. Constructor-provided
callbacks are automatically registered as initial listeners.

The emitter supports multiple listeners per event, with on() returning
an unsubscribe function for ergonomic cleanup.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>

@cursor cursor Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Cursor Bugbot has reviewed your changes and found 1 potential issue.

Fix All in Cursor

❌ Bugbot Autofix is OFF. To automatically fix reported issues with cloud agents, have a team admin enable autofix in the Cursor dashboard.

Reviewed by Cursor Bugbot for commit 269e93c. Configure here.

if (event !== "error") {
this.emit("error", String(error));
}
}

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Listener errors silently swallowed, bypassing console.error

Medium Severity

When a non-error listener throws, the emit catch block calls this.emit("error", String(error)) instead of this.onError(...). This bypasses the console.error call in the private onError method. Since getFullOptions registers a default no-op onError: () => {} as a listener, listener errors are completely silenced when no custom error handler is provided. Calling this.onError(String(error)) instead would preserve console visibility while still being safe from infinite recursion (the existing event !== "error" guard in the catch block would prevent it).

Additional Locations (1)
Fix in Cursor Fix in Web

Reviewed by Cursor Bugbot for commit 269e93c. Configure here.

@kraenhansen
kraenhansen marked this pull request as draft May 7, 2026 14:22
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant