Skip to content

Consolidate AgentServer subscribe API into subscribe/3 + unsubscribe/3#94

Merged
brainlid merged 1 commit into
mainfrom
me-subscribe-api-cleanup
May 5, 2026
Merged

Consolidate AgentServer subscribe API into subscribe/3 + unsubscribe/3#94
brainlid merged 1 commit into
mainfrom
me-subscribe-api-cleanup

Conversation

@brainlid
Copy link
Copy Markdown
Contributor

@brainlid brainlid commented May 5, 2026

Problem

The AgentServer pub/sub API had grown into four parallel functions — subscribe/1, unsubscribe/1, subscribe_debug/1, unsubscribe_debug/1 — each hard-coding both the channel (:main vs :debug) and the subscriber pid (always self()). That left no way to subscribe a foreign pid (e.g. a bridge GenServer proxying events to another transport) without dropping down to the low-level Sagents.Publisher API and hand-resolving the via-tuple. It also made the entry-point hierarchy hard to discover: nothing in Publisher's docs pointed callers at the higher-level wrappers, so new code tended to call Publisher.subscribe/3 directly even when AgentServer.subscribe/1 would have been the right choice.

Solution

Collapse the four functions into two parameterized ones:

  • AgentServer.subscribe(agent_id, channel \\ :main, subscriber_pid \\ nil)
  • AgentServer.unsubscribe(agent_id, channel \\ :main, subscriber_pid \\ nil)

Both default to the previous behaviour (:main channel, self() as the subscriber when subscriber_pid is nil), so existing single-arg call sites keep working unchanged. The new shape additionally supports :debug and explicit foreign-pid subscriptions in a single call.

Sagents.Subscriber now routes through AgentServer.subscribe/3 instead of calling Publisher.subscribe/3 with a hand-built via-tuple — eating its own dog food and keeping the via-tuple resolution in one place.

Sagents.Publisher's @moduledoc grew a 'Typical entry points' section that explicitly steers callers to AgentServer.subscribe/3, FileSystemServer.subscribe/1, or Sagents.Subscriber, and explains when reaching for Publisher.subscribe/3 directly is actually appropriate (only when implementing a new producer module).

Changes

  • `lib/sagents/agent_server.ex` — Replaced `subscribe/1`, `unsubscribe/1`, `subscribe_debug/1`, `unsubscribe_debug/1` with parameterized `subscribe/3` and `unsubscribe/3`. Merged and rewrote the @doc to cover all three arguments with examples for the common case, the debug channel, and the foreign-pid case.
  • `lib/sagents/publisher.ex` (@moduledoc) — Added a 'Typical entry points' section pointing callers at the higher-level wrappers and clarifying when direct `Publisher` use is warranted.
  • `lib/sagents/subscriber.ex` — Switched the internal subscribe call from `Publisher.subscribe(AgentServer.get_name(...), ...)` to `AgentServer.subscribe(agent_id, channel, subscriber_pid)`.
  • `test/sagents/agent_server_debug_pubsub_test.exs` — Renamed the `subscribe_debug/1` describe block to `subscribe/3 debug channel`, updated all call sites, and added three new describe blocks: `subscribe/3 with explicit subscriber_pid` (verifies foreign-pid delivery and that the caller does not also receive events), `subscribe/3 idempotency` (re-subscribing returns the same monitor_ref), and `unsubscribe/3` (debug-channel teardown plus the not-running case).
  • `test/sagents/agent_server_test.exs`, `test/sagents/agent_cancel_subagent_test.exs`, `test/sagents/agent_server_middleware_messaging_test.exs`, `test/sagents/conversation_title_integration_test.exs`, `test/sagents/sub_agent_server_broadcast_test.exs`, `test/support/testing_helpers.ex` — Mechanical migration from `subscribe_debug(agent_id)` to `subscribe(agent_id, :debug)`.

Testing

`mix test` covers the migration: every existing call site was updated and the existing debug-channel tests still pass under the new API. The new `subscribe/3` describe blocks specifically exercise the previously-unreachable behaviours — foreign-pid delivery, idempotent re-subscribe returning the same monitor_ref, and `unsubscribe/3` cleanly stopping delivery on the `:debug` channel (including the not-running case).

- document better for discoverability
@brainlid brainlid merged commit eac4348 into main May 5, 2026
3 of 4 checks passed
@brainlid brainlid deleted the me-subscribe-api-cleanup branch May 5, 2026 17:25
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