fix(protocol): keep internal events off SSE (#35378)

This commit is contained in:
Kit Langton 2026-07-04 21:12:45 -04:00 committed by GitHub
commit 905123b9c0
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
9 changed files with 52 additions and 44 deletions

View file

@ -160,15 +160,22 @@ export interface Interface {
export class Service extends Context.Service<Service, Interface>()("@opencode/Event") {}
export const liveBounded = (events: Interface, capacity: number) =>
export const liveBounded = (
events: Interface,
options: { readonly capacity: number; readonly accept?: (event: Payload) => boolean },
) =>
Effect.gen(function* () {
const queue = yield* Queue.dropping<Payload, SubscriberOverflowError>(capacity)
const queue = yield* Queue.dropping<Payload, SubscriberOverflowError>(options.capacity)
const unsubscribe = yield* events.listen((event) =>
Queue.offer(queue, event).pipe(
Effect.flatMap((accepted) =>
accepted ? Effect.void : Queue.fail(queue, new SubscriberOverflowError({ capacity })).pipe(Effect.asVoid),
),
),
options.accept && !options.accept(event)
? Effect.void
: Queue.offer(queue, event).pipe(
Effect.flatMap((accepted) =>
accepted
? Effect.void
: Queue.fail(queue, new SubscriberOverflowError({ capacity: options.capacity })).pipe(Effect.asVoid),
),
),
)
yield* Effect.addFinalizer(() => unsubscribe.pipe(Effect.andThen(Queue.shutdown(queue)), Effect.asVoid))
return Stream.fromQueue(queue)

View file

@ -23,8 +23,6 @@ import { ToolHooks } from "../tool/hooks"
import { WorkspaceV2 } from "../workspace"
const mutable = <T>(value: T) => value as DeepMutable<T>
const isEvent = Schema.is(Schema.Union(EventManifest.ServerDefinitions))
export const make = Effect.fn("PluginHost.make")(function* (plugin: PluginV2.Interface) {
const agents = yield* AgentV2.Service
const aisdk = yield* AISDK.Service
@ -160,7 +158,7 @@ export const make = Effect.fn("PluginHost.make")(function* (plugin: PluginV2.Int
}),
},
event: {
subscribe: () => events.live().pipe(Stream.filter(isEvent)),
subscribe: () => events.live().pipe(Stream.filter(EventManifest.isServer)),
},
integration: {
list: () => response(integration.list()),