diff --git a/src/gateway/server-methods-list.ts b/src/gateway/server-methods-list.ts index bb691f08ea3..a1d3c4af920 100644 --- a/src/gateway/server-methods-list.ts +++ b/src/gateway/server-methods-list.ts @@ -85,6 +85,8 @@ const BASE_METHODS = [ "agent", "agent.identity.get", "agent.wait", + "agent.subscribe", + "agent.unsubscribe", "browser.request", // WebChat WebSocket-native chat methods "chat.history", diff --git a/src/gateway/server-methods/agent.ts b/src/gateway/server-methods/agent.ts index 61c6bacca8d..25ef24932ab 100644 --- a/src/gateway/server-methods/agent.ts +++ b/src/gateway/server-methods/agent.ts @@ -38,6 +38,8 @@ import { validateAgentIdentityParams, validateAgentParams, validateAgentWaitParams, + validateAgentSubscribeParams, + validateAgentUnsubscribeParams, } from "../protocol/index.js"; import { canonicalizeSpawnedByForAgent, @@ -690,4 +692,47 @@ export const agentHandlers: GatewayRequestHandlers = { error: snapshot.error, }); }, + + "agent.subscribe": ({ params, client, respond, context }) => { + const validated = validateAgentSubscribeParams(params); + if (!validated.ok) { + respond( + false, + undefined, + errorShape(ErrorCodes.INVALID_PARAMS, formatValidationErrors(validated.errors)), + ); + return; + } + const p = validated.value; + const connId = client?.connId; + if (!connId) { + respond(false, undefined, errorShape(ErrorCodes.INVALID_PARAMS, "no connection id")); + return; + } + context.registerSessionSubscription(p.sessionKey, connId); + + // Replay buffered events past the caller's cursor. + const afterSeq = typeof p.afterSeq === "number" ? p.afterSeq : 0; + const replayed = context.replaySessionEvents(p.sessionKey, afterSeq, connId); + respond(true, { cursor: context.currentGlobalSeq(), replayed }); + }, + + "agent.unsubscribe": ({ params, client, respond, context }) => { + const validated = validateAgentUnsubscribeParams(params); + if (!validated.ok) { + respond( + false, + undefined, + errorShape(ErrorCodes.INVALID_PARAMS, formatValidationErrors(validated.errors)), + ); + return; + } + const connId = client?.connId; + if (!connId) { + respond(false, undefined, errorShape(ErrorCodes.INVALID_PARAMS, "no connection id")); + return; + } + context.unregisterSessionSubscription(validated.value.sessionKey, connId); + respond(true, {}); + }, };