@m4trix/core 0.5.0 → 0.7.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../../src/matrix/agent-network/agent-network.ts","../../src/matrix/identifiers/channel-name.ts","../../src/matrix/agent-network/channel.ts","../../src/matrix/agent-network/event-plane.ts","../../src/matrix/io/expose.ts","../../src/matrix/agent-network/agent-network-event.ts","../../src/matrix/agent.ts","../../src/matrix/agent-factory.ts","../../src/matrix/io/protocols/sse.ts","../../src/matrix/io/adapters/next-endpoint.ts","../../src/matrix/io/adapters/express-endpoint.ts"],"names":["Effect","Queue","payload"],"mappings":"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","sourcesContent":["import { Effect, Scope } from 'effect';\nimport type { Schema as S } from 'effect';\nimport type { AgentFactory } from '../agent-factory';\nimport type { AgentNetworkEventDef } from './agent-network-event';\nimport { ChannelName, ConfiguredChannel, Sink } from './channel';\nimport { createEventPlane, run } from './event-plane';\nimport type { EventPlane } from './event-plane';\nimport { expose } from '../io/expose';\nimport type { ExposeOptions, ExposedAPI } from '../io/types';\n\n/* ─── Helper Types ─── */\n\ntype EventDef = AgentNetworkEventDef<string, S.Schema.Any>;\n\n/** Structural interface for any Agent – avoids variance issues with private fields. */\nexport interface AnyAgent {\n getId(): string;\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n invoke(options?: any): Promise<void>;\n /** Event names this agent listens to. Empty = listen to all. */\n getListensTo?(): readonly string[];\n}\n\n/* ─── Agent Binding (returned by registerAgent) ─── */\n\nexport type AgentBinding = {\n subscribe(channel: ConfiguredChannel): AgentBinding;\n publishTo(channel: ConfiguredChannel): AgentBinding;\n};\n\n/* ─── Spawner Builder ─── */\n\nexport type SpawnFn = (\n agent: AnyAgent,\n bindings?: { subscribe?: string[]; publishTo?: string[] },\n) => void;\n\nexport type SpawnCallbackContext<\n TRegistry extends Record<string, AgentFactory> = Record<string, AgentFactory>,\n> = {\n kind: keyof TRegistry & string;\n factory: TRegistry[keyof TRegistry & string];\n payload: {\n id: string;\n params: Record<string, unknown>;\n subscribe?: string[];\n publishTo?: string[];\n };\n spawn: SpawnFn;\n};\n\nexport type SpawnerBuilder<\n TRegistry extends Record<string, AgentFactory> = Record<string, AgentFactory>,\n> = {\n listen(\n channel: ConfiguredChannel,\n event: EventDef,\n ): SpawnerBuilder<TRegistry>;\n registry<R extends Record<string, AgentFactory>>(reg: R): SpawnerBuilder<R>;\n defaultBinding(\n fn: (ctx: { kind: string }) => {\n subscribe: string[];\n publishTo: string[];\n },\n ): SpawnerBuilder<TRegistry>;\n onSpawn(\n fn: (ctx: SpawnCallbackContext<TRegistry>) => AnyAgent,\n ): SpawnerBuilder<TRegistry>;\n};\n\n/* ─── Setup Context ─── */\n\nexport type SetupContext = {\n mainChannel: (name: string) => ConfiguredChannel;\n createChannel: (name: string) => ConfiguredChannel;\n sink: typeof Sink;\n registerAgent: (agent: AnyAgent) => AgentBinding;\n spawner: (factory: typeof AgentFactory) => SpawnerBuilder;\n};\n\n/* ─── Internal Registration Records ─── */\n\ntype AgentRegistration = {\n agent: AnyAgent;\n subscribedTo: ConfiguredChannel[];\n publishesTo: ConfiguredChannel[];\n};\n\ntype SpawnerRegistration = {\n factoryClass: typeof AgentFactory;\n listenChannel?: ConfiguredChannel;\n listenEvent?: EventDef;\n registry: Record<string, AgentFactory>;\n defaultBindingFn?: (ctx: { kind: string }) => {\n subscribe: string[];\n publishTo: string[];\n };\n onSpawnFn?: (\n ctx: SpawnCallbackContext<Record<string, AgentFactory>>,\n ) => AnyAgent;\n};\n\n/* ─── AgentNetwork ─── */\n\nexport class AgentNetwork {\n private _mainChannel: ConfiguredChannel | undefined;\n private channels: Map<ChannelName, ConfiguredChannel> = new Map();\n private agentRegistrations: Map<string, AgentRegistration> = new Map();\n private spawnerRegistrations: SpawnerRegistration[] = [];\n\n private constructor() {}\n\n /* ─── Public Static Factory ─── */\n\n static setup(callback: (ctx: SetupContext) => void): AgentNetwork {\n const network = new AgentNetwork();\n\n const ctx: SetupContext = {\n mainChannel: (name: string) => {\n const channel = network.addChannel(name);\n network.setMainChannel(channel);\n return channel;\n },\n createChannel: (name: string) => network.addChannel(name),\n sink: Sink,\n registerAgent: (agent) => network.registerAgentInternal(agent),\n spawner: (factory) => network.createSpawnerInternal(factory),\n };\n\n callback(ctx);\n\n return network;\n }\n\n /* ─── Internal Builders ─── */\n\n private addChannel(name: string): ConfiguredChannel {\n const channelName = ChannelName(name);\n const channel = new ConfiguredChannel(channelName);\n this.channels.set(channelName, channel);\n return channel;\n }\n\n private setMainChannel(channel: ConfiguredChannel): void {\n this._mainChannel = channel;\n }\n\n private registerAgentInternal(agent: AnyAgent): AgentBinding {\n const registration: AgentRegistration = {\n agent,\n subscribedTo: [],\n publishesTo: [],\n };\n this.agentRegistrations.set(agent.getId(), registration);\n\n const binding: AgentBinding = {\n subscribe(channel: ConfiguredChannel) {\n registration.subscribedTo.push(channel);\n return binding;\n },\n publishTo(channel: ConfiguredChannel) {\n registration.publishesTo.push(channel);\n return binding;\n },\n };\n\n return binding;\n }\n\n private createSpawnerInternal(\n factoryClass: typeof AgentFactory,\n ): SpawnerBuilder {\n const reg: SpawnerRegistration = {\n factoryClass,\n registry: {},\n };\n\n this.spawnerRegistrations.push(reg);\n\n const builder: SpawnerBuilder = {\n listen(channel: ConfiguredChannel, event: EventDef) {\n reg.listenChannel = channel;\n reg.listenEvent = event;\n return builder;\n },\n registry(registry: Record<string, AgentFactory>) {\n reg.registry = registry;\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n return builder as SpawnerBuilder<any>;\n },\n defaultBinding(\n fn: (ctx: { kind: string }) => {\n subscribe: string[];\n publishTo: string[];\n },\n ) {\n reg.defaultBindingFn = fn;\n return builder;\n },\n onSpawn(\n fn: (\n ctx: SpawnCallbackContext<Record<string, AgentFactory>>,\n ) => AnyAgent,\n ) {\n reg.onSpawnFn = fn;\n return builder;\n },\n };\n\n return builder;\n }\n\n /* ─── Accessors ─── */\n\n getChannels(): Map<string, ConfiguredChannel> {\n return this.channels;\n }\n\n getMainChannel(): ConfiguredChannel | undefined {\n return this._mainChannel;\n }\n\n getAgentRegistrations(): Map<string, AgentRegistration> {\n return this.agentRegistrations;\n }\n\n getSpawnerRegistrations(): ReadonlyArray<SpawnerRegistration> {\n return this.spawnerRegistrations;\n }\n\n /**\n * Expose the network as a streamable API (e.g. SSE). Returns an ExposedAPI\n * that adapters (NextEndpoint, ExpressEndpoint) consume to produce streamed\n * responses.\n *\n * @example\n * const api = network.expose({ protocol: \"sse\", auth, select });\n * export const GET = NextEndpoint.from(api).handler();\n */\n expose(options: ExposeOptions): ExposedAPI {\n return expose(this, options);\n }\n\n /**\n * Starts the event plane: creates one PubSub per channel and runs subscriber\n * loops for each (agent, channel) pair. Agents subscribed to a channel are\n * invoked concurrently when events are published to that channel.\n *\n * Returns the EventPlane for publishing. Use `Effect.scoped` so the run is\n * interrupted when the scope ends.\n */\n run(capacity?: number): Effect.Effect<EventPlane, never, Scope.Scope> {\n return this.runScoped(this, capacity);\n }\n\n private runScoped(\n network: AgentNetwork,\n capacity?: number,\n ): Effect.Effect<EventPlane, never, Scope.Scope> {\n return Effect.gen(function* () {\n const plane = yield* createEventPlane(network, capacity);\n yield* Effect.fork(run(network, plane));\n return plane;\n });\n }\n}\n","import { Brand } from 'effect';\n\n/** Regex: lowercase alphanumeric segments separated by hyphens (e.g. my-channel-name) */\nconst KEBAB_CASE_REGEX = /^[a-z0-9]+(-[a-z0-9]+)*$/;\n\n/**\n * Branded type for channel names. Enforces kebab-case at runtime via refinement.\n *\n * **Branded types** add a nominal marker so TypeScript treats `ChannelName` as\n * distinct from plain `string`, preventing accidental substitution (e.g. passing\n * a raw string where a validated channel name is expected).\n *\n * **Refinement** validates at runtime that the value matches kebab-case before\n * the brand is applied. Use `ChannelName(value)` to create a validated instance.\n */\nexport type ChannelName = string & Brand.Brand<'ChannelName'>;\n\nexport const ChannelName = Brand.refined<ChannelName>(\n (s) => typeof s === 'string' && KEBAB_CASE_REGEX.test(s),\n (s) => Brand.error(`Expected kebab-case (e.g. my-channel-name), got: ${s}`),\n);\n","import { type Schema as S } from 'effect';\nimport type { AgentNetworkEventDef } from './agent-network-event';\nimport { ChannelName } from '../identifiers/channel-name';\n\nexport { ChannelName } from '../identifiers/channel-name';\n\n/* ─── Sink ─── */\n\nexport type SinkDef = {\n readonly _tag: 'SinkDef';\n readonly type: string;\n readonly config: unknown;\n};\n\nexport const Sink = {\n kafka(config: { topic: string }): SinkDef {\n return { _tag: 'SinkDef', type: 'kafka', config };\n },\n httpStream(): SinkDef {\n return { _tag: 'SinkDef', type: 'http-stream', config: {} };\n },\n};\n\nexport function isHttpStreamSink(sink: SinkDef): boolean {\n return sink.type === 'http-stream';\n}\n\n/* ─── Channel Definitions ─── */\n\ntype EventDef = AgentNetworkEventDef<string, S.Schema.Any>;\n\nexport type ChannelDef = {\n readonly _tag: 'ChannelDef';\n readonly name: ChannelName;\n};\n\n/**\n * A channel configured via the builder pattern inside `AgentNetwork.setup()`.\n * Supports `.events()`, `.sink()`, and `.sinks()` chaining.\n */\nexport class ConfiguredChannel {\n readonly _tag = 'ConfiguredChannel' as const;\n readonly name: ChannelName;\n private _events: ReadonlyArray<EventDef> = [];\n private _sinks: ReadonlyArray<SinkDef> = [];\n\n constructor(name: ChannelName) {\n this.name = name;\n }\n\n events(events: ReadonlyArray<EventDef>): this {\n this._events = [...events];\n return this;\n }\n\n sink(sink: SinkDef): this {\n this._sinks = [...this._sinks, sink];\n return this;\n }\n\n sinks(sinks: ReadonlyArray<SinkDef>): this {\n this._sinks = [...sinks];\n return this;\n }\n\n getEvents(): ReadonlyArray<EventDef> {\n return this._events;\n }\n\n getSinks(): ReadonlyArray<SinkDef> {\n return this._sinks;\n }\n}\n\nexport const Channel = {\n of(name: ChannelName): ChannelDef {\n return {\n _tag: 'ChannelDef' as const,\n name,\n };\n },\n};\n","import { Cause, Effect, Fiber, PubSub, Queue, Scope } from 'effect';\nimport type { AgentNetwork, AnyAgent } from './agent-network';\nimport type { EventMeta } from './agent-network-event';\nimport type { ChannelName, ConfiguredChannel } from './channel';\n\n/* ─── Envelope ─── */\n\nexport type Envelope = {\n name: string;\n meta: EventMeta;\n payload: unknown;\n};\n\n/* ─── EventPlane ─── */\n\nexport type EventPlane = {\n readonly publish: (\n channel: ChannelName,\n envelope: Envelope,\n ) => Effect.Effect<boolean>;\n readonly publishToChannels: (\n channels: readonly ConfiguredChannel[],\n envelope: Envelope,\n ) => Effect.Effect<boolean>;\n readonly subscribe: (\n channel: ChannelName,\n ) => Effect.Effect<Queue.Dequeue<Envelope>, never, Scope.Scope>;\n readonly shutdown: Effect.Effect<void>;\n};\n\n/* ─── Create EventPlane ─── */\n\nconst DEFAULT_CAPACITY = 16;\n\n/**\n * Creates an EventPlane from an AgentNetwork. One PubSub per channel with\n * bounded back-pressure. Use `Effect.scoped` when running to ensure proper\n * cleanup.\n */\nexport const createEventPlane = (\n network: AgentNetwork,\n capacity: number = DEFAULT_CAPACITY,\n): Effect.Effect<EventPlane> =>\n Effect.gen(function* () {\n const channels = network.getChannels();\n const pubsubs = new Map<ChannelName, PubSub.PubSub<Envelope>>();\n\n for (const channel of channels.values()) {\n const pubsub = yield* PubSub.bounded<Envelope>(capacity);\n pubsubs.set(channel.name, pubsub);\n }\n\n const getPubsub = (channel: ChannelName): PubSub.PubSub<Envelope> => {\n const p = pubsubs.get(channel);\n if (!p) throw new Error(`Channel not found: ${channel}`);\n return p;\n };\n\n const publish = (\n channel: ChannelName,\n envelope: Envelope,\n ): Effect.Effect<boolean> => PubSub.publish(getPubsub(channel), envelope);\n\n const publishToChannels = (\n targetChannels: readonly ConfiguredChannel[],\n envelope: Envelope,\n ): Effect.Effect<boolean> =>\n Effect.all(\n targetChannels.map((c) => publish(c.name, envelope)),\n { concurrency: 'unbounded' },\n ).pipe(Effect.map((results) => results.every(Boolean)));\n\n const subscribe = (\n channel: ChannelName,\n ): Effect.Effect<Queue.Dequeue<Envelope>, never, Scope.Scope> =>\n PubSub.subscribe(getPubsub(channel));\n\n const shutdown = Effect.all([...pubsubs.values()].map(PubSub.shutdown), {\n concurrency: 'unbounded',\n }).pipe(Effect.asVoid);\n\n return {\n publish,\n publishToChannels,\n subscribe,\n shutdown,\n };\n });\n\n/* ─── Run Subscriber Loop ─── */\n\n/**\n * Runs a single agent's subscription loop on one channel. Takes messages from\n * the dequeue, invokes the agent with the envelope as triggerEvent when the\n * event name matches the agent's listensTo, and wires emit to publish to the\n * agent's output channels.\n */\ntype EmitQueue = Queue.Queue<{\n channels: readonly ConfiguredChannel[];\n envelope: Envelope;\n}>;\n\nexport const runSubscriber = (\n agent: AnyAgent,\n publishesTo: readonly ConfiguredChannel[],\n dequeue: Queue.Dequeue<Envelope>,\n plane: EventPlane,\n emitQueue?: EmitQueue,\n): Effect.Effect<Fiber.RuntimeFiber<void, never>> =>\n Effect.gen(function* () {\n const listensTo = agent.getListensTo?.() ?? [];\n\n const processOne = (): Effect.Effect<void, never, never> =>\n Effect.gen(function* () {\n const envelope = yield* Queue.take(dequeue);\n if (listensTo.length > 0 && !listensTo.includes(envelope.name)) {\n return;\n }\n yield* Effect.tryPromise({\n try: () =>\n agent.invoke({\n triggerEvent: envelope,\n emit: (userEvent: { name: string; payload: unknown }) => {\n const fullEnvelope: Envelope = {\n name: userEvent.name,\n meta: envelope.meta,\n payload: userEvent.payload,\n };\n if (emitQueue) {\n Effect.runPromise(\n Queue.offer(emitQueue, {\n channels: publishesTo,\n envelope: fullEnvelope,\n }),\n ).catch(() => {});\n } else {\n Effect.runFork(\n plane.publishToChannels(publishesTo, fullEnvelope),\n );\n }\n },\n }),\n catch: (e) => e,\n });\n }).pipe(\n Effect.catchAllCause((cause) =>\n Cause.isInterrupted(cause)\n ? Effect.void\n : Effect.sync(() => {\n console.error(`Agent ${agent.getId()} failed:`, cause);\n }).pipe(Effect.asVoid),\n ),\n );\n\n const loop = (): Effect.Effect<void, never, never> =>\n processOne().pipe(Effect.flatMap(() => loop()));\n\n return yield* Effect.fork(loop());\n });\n\n/* ─── Run Network ─── */\n\nexport type RunOptions = {\n /** When provided, agent emits are queued and published by a drain fiber in the same Effect context. Use when run is forked from expose without a shared plane. */\n emitQueue?: EmitQueue;\n};\n\n/**\n * Runs the event plane: starts a subscriber loop for each (agent, channel)\n * pair. Runs until the scope ends (e.g. on interrupt). Use Effect.scoped\n * to ensure subscriptions are properly cleaned up.\n */\nexport const run = (\n network: AgentNetwork,\n plane: EventPlane,\n options?: RunOptions,\n): Effect.Effect<void, never, Scope.Scope> =>\n Effect.gen(function* () {\n const registrations = network.getAgentRegistrations();\n const emitQueue = options?.emitQueue;\n\n for (const reg of registrations.values()) {\n for (const channel of reg.subscribedTo) {\n const dequeue = yield* plane.subscribe(channel.name);\n yield* runSubscriber(\n reg.agent,\n reg.publishesTo,\n dequeue,\n plane,\n emitQueue,\n );\n }\n }\n\n yield* Effect.never;\n });\n","import { Effect, Queue } from 'effect';\nimport type { AgentNetwork } from '../agent-network/agent-network';\nimport type { ConfiguredChannel } from '../agent-network/channel';\nimport { createEventPlane, run } from '../agent-network/event-plane';\nimport type { Envelope } from '../agent-network/event-plane';\nimport { ChannelName, isHttpStreamSink } from '../agent-network/channel';\nimport type {\n ExposeOptions,\n ExposeRequest,\n ExposedAPI,\n ExposedStream,\n StreamFactory,\n} from './types';\n\n/** Extract JSON payload from ExposeRequest. POST with JSON body, or Express req.body, else {}. */\nasync function extractPayload(req: ExposeRequest): Promise<unknown> {\n const webRequest = req.request as Request | undefined;\n if (webRequest?.method === 'POST') {\n const ct = webRequest.headers?.get?.('content-type') ?? '';\n if (ct.includes('application/json')) {\n try {\n return await webRequest.json();\n } catch {\n return {};\n }\n }\n }\n const expressReq = req.req as { body?: unknown } | undefined;\n if (expressReq?.body != null) {\n return expressReq.body;\n }\n return {};\n}\n\n/** Resolve which channel(s) to subscribe to from select options */\nfunction resolveChannels(\n network: AgentNetwork,\n select?: ExposeOptions['select'],\n): ChannelName[] {\n const channels = network.getChannels();\n if (select?.channels) {\n const ch = select.channels;\n const arr = Array.isArray(ch) ? ch : [ch];\n return arr.map((c) => ChannelName(c as string));\n }\n // Prefer channels with http-stream sink (explicitly marked for frontend)\n const httpStreamChannels = [...channels.values()]\n .filter((ch) => ch.getSinks().some(isHttpStreamSink))\n .map((ch) => ch.name);\n if (httpStreamChannels.length > 0) return httpStreamChannels;\n // Fallback: prefer \"client\", else first channel\n const client = channels.get('client' as ChannelName);\n if (client) return [client.name];\n const first = channels.values().next().value;\n return first ? [first.name] : [];\n}\n\n/** Create async iterable from Queue.Dequeue, respecting AbortSignal */\nfunction streamFromDequeue(\n take: () => Promise<Envelope>,\n signal?: AbortSignal | null,\n eventFilter?: string[],\n): ExposedStream {\n const shouldInclude = (e: Envelope): boolean =>\n !eventFilter?.length || eventFilter.includes(e.name);\n\n return {\n async *[Symbol.asyncIterator](): AsyncIterableIterator<Envelope> {\n while (!signal?.aborted) {\n const takePromise = take();\n const abortPromise = signal\n ? new Promise<never>((_, reject) => {\n signal.addEventListener(\n 'abort',\n () => reject(new DOMException('Aborted', 'AbortError')),\n { once: true },\n );\n })\n : new Promise<never>(() => {});\n\n let envelope: Envelope;\n try {\n envelope = await Promise.race([takePromise, abortPromise]);\n } catch (e) {\n if (e instanceof DOMException && e.name === 'AbortError') break;\n throw e;\n }\n\n if (shouldInclude(envelope)) yield envelope;\n }\n },\n };\n}\n\n/**\n * Expose the agent network as a streamable API. Returns an ExposedAPI that\n * adapters (NextEndpoint, ExpressEndpoint) consume to produce SSE responses.\n *\n * @example\n * const api = agentNetwork.expose({ protocol: \"sse\", auth, select });\n * export const GET = NextEndpoint.from(api).handler();\n */\nexport function expose(\n network: AgentNetwork,\n options: ExposeOptions,\n): ExposedAPI {\n const { auth, select, plane: providedPlane, onRequest, startEventName = 'request' } = options;\n const channels = resolveChannels(network, select);\n const eventFilter = select?.events;\n const mainChannel = network.getMainChannel();\n\n if (channels.length === 0) {\n throw new Error('expose: no channels to subscribe to');\n }\n\n const createStream = (async (\n req: ExposeRequest,\n consumer?: (stream: ExposedStream) => Promise<unknown>,\n ) => {\n const payload = await extractPayload(req);\n const signal = req.request?.signal;\n\n const program = Effect.gen(function* () {\n const plane = providedPlane ?? (yield* createEventPlane(network));\n if (!providedPlane) {\n const emitQueue = yield* Queue.unbounded<{\n channels: readonly ConfiguredChannel[];\n envelope: Envelope;\n }>();\n yield* Effect.fork(\n Effect.forever(\n Queue.take(emitQueue).pipe(\n Effect.flatMap(({ channels: chs, envelope }) =>\n plane.publishToChannels(chs, envelope),\n ),\n ),\n ),\n );\n yield* Effect.fork(run(network, plane, { emitQueue }));\n // Allow run() to subscribe agents before we publish (PubSub does not buffer for future subscribers)\n yield* Effect.sleep('10 millis');\n }\n\n const targetChannel = mainChannel?.name ?? channels[0]!;\n const emitStartEvent = (p?: unknown): void => {\n const pld = p ?? payload;\n const envelope: Envelope = {\n name: startEventName,\n meta: { runId: crypto.randomUUID() },\n payload: pld,\n };\n Effect.runPromise(plane.publish(targetChannel, envelope)).catch(() => {});\n };\n\n // Subscribe to first channel before emitting (so we don't miss agent output)\n const dequeue = yield* plane.subscribe(channels[0]!);\n\n if (onRequest) {\n yield* Effect.tryPromise(() =>\n Promise.resolve(onRequest({ emitStartEvent, req, payload })),\n );\n } else if (!providedPlane) {\n const envelope: Envelope = {\n name: startEventName,\n meta: { runId: crypto.randomUUID() },\n payload,\n };\n yield* plane.publish(targetChannel, envelope);\n yield* Effect.sleep('10 millis');\n }\n const take = (): Promise<Envelope> =>\n Effect.runPromise(Queue.take(dequeue)) as Promise<Envelope>;\n\n const stream = streamFromDequeue(take, signal ?? undefined, eventFilter);\n if (consumer) {\n return yield* Effect.tryPromise(() => consumer(stream));\n }\n return stream;\n });\n\n return Effect.runPromise(program.pipe(Effect.scoped));\n }) as StreamFactory;\n\n return {\n protocol: 'sse',\n createStream: (async (\n req: ExposeRequest,\n consumer?: (stream: ExposedStream) => Promise<unknown>,\n ) => {\n if (auth) {\n const result = await auth(req);\n if (!result.allowed) {\n throw new ExposeAuthError(\n result.message ?? 'Unauthorized',\n result.status ?? 401,\n );\n }\n }\n return consumer ? createStream(req, consumer) : createStream(req);\n }) as StreamFactory,\n };\n}\n\n/** Thrown when auth denies the request */\nexport class ExposeAuthError extends Error {\n constructor(\n message: string,\n public readonly status: number = 401,\n ) {\n super(message);\n this.name = 'ExposeAuthError';\n }\n}\n","import { Effect, Schema as S } from 'effect';\nimport type { ParseError } from 'effect/ParseResult';\n\n/** Standard meta carried by every event */\nexport const EventMetaSchema = S.Struct({\n runId: S.String,\n contextId: S.optional(S.String),\n correlationId: S.optional(S.String),\n causationId: S.optional(S.String),\n ts: S.optional(S.Number),\n});\n\nexport type EventMeta = S.Schema.Type<typeof EventMetaSchema>;\n\n// Re-export Schema from effect for convenience\nexport { Schema as S } from 'effect';\n\nexport type AgentNetworkEventDef<\n EventName extends string,\n PayloadSchema extends S.Schema.Any,\n> = {\n readonly _tag: 'AgentNetworkEventDef';\n readonly name: EventName;\n readonly payload: PayloadSchema;\n\n /** Decode unknown payload -> typed payload (Effect) */\n readonly decodePayload: (\n u: unknown,\n ) => Effect.Effect<S.Schema.Type<PayloadSchema>, ParseError>;\n\n /** Decode the full envelope (meta + payload) */\n readonly decode: (\n u: unknown,\n ) => Effect.Effect<\n { name: EventName; meta: EventMeta; payload: S.Schema.Type<PayloadSchema> },\n ParseError\n >;\n\n /**\n * Create an unbound event (name + payload only) for emit. Validates payload via schema.\n * Meta is injected by the runtime when the event is emitted.\n */\n readonly make: (payload: unknown) => {\n name: EventName;\n payload: S.Schema.Type<PayloadSchema>;\n };\n\n /**\n * Create a full envelope (meta + payload) for tests or manual trigger events.\n * Sync, throws on validation error.\n */\n readonly makeBound: (\n meta: unknown,\n payload: unknown,\n ) => {\n name: EventName;\n meta: EventMeta;\n payload: S.Schema.Type<PayloadSchema>;\n };\n\n /**\n * Effect version of make. Use when composing in Effect pipelines.\n */\n readonly makeEffect: (payload: unknown) => Effect.Effect<\n { name: EventName; payload: S.Schema.Type<PayloadSchema> },\n ParseError\n >;\n\n /**\n * Effect version of makeBound. Use when composing in Effect pipelines.\n */\n readonly makeBoundEffect: (\n meta: unknown,\n payload: unknown,\n ) => Effect.Effect<\n { name: EventName; meta: EventMeta; payload: S.Schema.Type<PayloadSchema> },\n ParseError\n >;\n\n /**\n * Type guard: returns true if `u` is a valid event of this type.\n */\n readonly is: (u: unknown) => u is {\n name: EventName;\n meta: EventMeta;\n payload: S.Schema.Type<PayloadSchema>;\n };\n};\n\ntype Envelope<EventName extends string, Meta, Payload> = {\n name: EventName;\n meta: Meta;\n payload: Payload;\n};\n\nexport const AgentNetworkEvent = {\n of<const EventName extends string, PS extends S.Schema.Any>(\n name: EventName,\n payload: PS,\n ): AgentNetworkEventDef<EventName, PS> {\n const decodePayload = S.decodeUnknown(payload);\n const envelopeSchema = S.Struct({\n name: S.Literal(name),\n meta: EventMetaSchema,\n payload,\n });\n const decodeEnvelope = S.decodeUnknown(envelopeSchema);\n\n const make = (payload: unknown): { name: EventName; payload: S.Schema.Type<PS> } => {\n const decoded = Effect.runSync(\n decodePayload(payload) as unknown as Effect.Effect<S.Schema.Type<PS>, ParseError>,\n );\n return { name, payload: decoded };\n };\n\n const makeBound = (\n meta: unknown,\n payload: unknown,\n ): Envelope<EventName, EventMeta, S.Schema.Type<PS>> =>\n Effect.runSync(\n decodeEnvelope({ name, meta, payload }) as unknown as Effect.Effect<\n Envelope<EventName, EventMeta, S.Schema.Type<PS>>,\n ParseError\n >,\n );\n\n const makeEffect = (\n payload: unknown,\n ): Effect.Effect<{ name: EventName; payload: S.Schema.Type<PS> }, ParseError> =>\n (decodePayload(payload) as unknown as Effect.Effect<S.Schema.Type<PS>, ParseError>).pipe(\n Effect.map((p) => ({ name, payload: p })),\n );\n\n const makeBoundEffect = (\n meta: unknown,\n payload: unknown,\n ): Effect.Effect<\n Envelope<EventName, EventMeta, S.Schema.Type<PS>>,\n ParseError\n > =>\n decodeEnvelope({ name, meta, payload }) as unknown as Effect.Effect<\n Envelope<EventName, EventMeta, S.Schema.Type<PS>>,\n ParseError\n >;\n\n const is = S.is(envelopeSchema) as unknown as (\n u: unknown,\n ) => u is Envelope<EventName, EventMeta, S.Schema.Type<PS>>;\n\n return {\n _tag: 'AgentNetworkEventDef' as const,\n name,\n payload,\n decodePayload: decodePayload as unknown as AgentNetworkEventDef<\n EventName,\n PS\n >['decodePayload'],\n decode: decodeEnvelope as unknown as AgentNetworkEventDef<\n EventName,\n PS\n >['decode'],\n make,\n makeBound,\n makeEffect,\n makeBoundEffect,\n is,\n };\n },\n};\n","import { randomUUID } from 'crypto';\n\ntype LogicFn<TParams, TTriggerEvent, TEmitEvent> = (ctx: {\n params: TParams;\n triggerEvent: TTriggerEvent;\n emit: (event: TEmitEvent) => void;\n}) => Promise<void>;\n\nexport class Agent<TParams, TTriggerEvent = never, TEmitEvent = never> {\n #params: TParams;\n #logic: LogicFn<TParams, TTriggerEvent, TEmitEvent>;\n #id: string;\n #listensTo: readonly string[];\n\n constructor(\n logic: LogicFn<TParams, TTriggerEvent, TEmitEvent>,\n params: TParams,\n listensTo?: readonly string[],\n ) {\n this.#logic = logic;\n this.#params = params;\n this.#id = `agent-${randomUUID()}`;\n this.#listensTo = listensTo ?? [];\n }\n\n getListensTo(): readonly string[] {\n return this.#listensTo;\n }\n\n async invoke(options?: {\n triggerEvent?: TTriggerEvent;\n emit?: (event: TEmitEvent) => void;\n }): Promise<void> {\n const { triggerEvent, emit } = options ?? {};\n\n const emitFn =\n emit ??\n ((_event: TEmitEvent): void => {\n // no-op – will be wired by the network at runtime\n });\n\n await this.#logic({\n params: this.#params,\n triggerEvent: triggerEvent ?? (undefined as TTriggerEvent),\n emit: emitFn,\n });\n }\n\n getId(): string {\n return this.#id;\n }\n}\n","import { Schema as S } from 'effect';\nimport { Agent } from './agent';\nimport {\n AgentNetworkEventDef,\n type EventMeta,\n} from './agent-network/agent-network-event';\nimport { BaseSchemaDefintion } from './types';\n\ntype EventDef = AgentNetworkEventDef<string, S.Schema.Any>;\n\n/** Extracts the envelope type (name, meta, payload) from an event definition */\nexport type EventEnvelope<E extends EventDef> =\n E extends AgentNetworkEventDef<infer N, infer PS>\n ? { name: N; meta: EventMeta; payload: S.Schema.Type<PS> }\n : never;\n\n/** What the user passes to emit() – no meta required */\nexport type EmitPayload<E extends EventDef> =\n E extends AgentNetworkEventDef<infer N, infer PS>\n ? { name: N; payload: S.Schema.Type<PS> }\n : never;\n\n/** Internal logic function */\ntype LogicFn<TParams, TTriggerEvent, TEmitEvent> = (ctx: {\n params: TParams;\n triggerEvent: TTriggerEvent;\n emit: (event: TEmitEvent) => void;\n}) => Promise<void>;\n\ntype ConstructorParams<\n TParams,\n TListensTo extends EventDef,\n TEmits extends EventDef,\n> = {\n logic?: LogicFn<TParams, EventEnvelope<TListensTo>, EmitPayload<TEmits>>;\n paramsSchema?: BaseSchemaDefintion;\n listensTo?: ReadonlyArray<TListensTo>;\n emits?: ReadonlyArray<TEmits>;\n};\n\nexport class AgentFactory<\n TParams = unknown,\n TListensTo extends EventDef = never,\n TEmits extends EventDef = never,\n> {\n private _listensTo: ReadonlyArray<TListensTo>;\n private _emits: ReadonlyArray<TEmits>;\n private _logic:\n | LogicFn<TParams, EventEnvelope<TListensTo>, EmitPayload<TEmits>>\n | undefined;\n private _paramsSchema: BaseSchemaDefintion | undefined;\n\n private constructor({\n logic,\n paramsSchema,\n listensTo = [],\n emits = [],\n }: ConstructorParams<TParams, TListensTo, TEmits>) {\n this._logic = logic;\n this._paramsSchema = paramsSchema;\n this._listensTo = listensTo;\n this._emits = emits;\n }\n\n private getConstructorState(): ConstructorParams<\n TParams,\n TListensTo,\n TEmits\n > {\n return {\n logic: this._logic,\n paramsSchema: this._paramsSchema,\n listensTo: this._listensTo,\n emits: this._emits,\n };\n }\n\n /** Union of all event definitions this agent listens to */\n getListensTo(): ReadonlyArray<TListensTo> {\n return this._listensTo;\n }\n\n /** Union of all event definitions this agent can emit */\n getEmits(): ReadonlyArray<TEmits> {\n return this._emits;\n }\n\n getLogic():\n | LogicFn<TParams, EventEnvelope<TListensTo>, EmitPayload<TEmits>>\n | undefined {\n return this._logic;\n }\n\n static run(): AgentFactory<unknown, never, never> {\n return new AgentFactory<unknown, never, never>({});\n }\n\n params<TSchema extends BaseSchemaDefintion>(\n params: TSchema,\n ): AgentFactory<TSchema['Type'], TListensTo, TEmits> {\n const { logic, ...rest } = this.getConstructorState();\n\n return new AgentFactory({\n ...rest,\n logic: logic as LogicFn<\n TSchema['Type'],\n EventEnvelope<TListensTo>,\n EmitPayload<TEmits>\n >,\n paramsSchema: params,\n });\n }\n\n listensTo<E extends EventDef>(\n events: Array<E>,\n ): AgentFactory<TParams, TListensTo | E, TEmits> {\n return new AgentFactory<TParams, TListensTo | E, TEmits>({\n ...(this.getConstructorState() as unknown as ConstructorParams<\n TParams,\n TListensTo | E,\n TEmits\n >),\n listensTo: [...this._listensTo, ...events] as ReadonlyArray<\n TListensTo | E\n >,\n });\n }\n\n emits<E extends EventDef>(\n events: Array<E>,\n ): AgentFactory<TParams, TListensTo, TEmits | E> {\n return new AgentFactory<TParams, TListensTo, TEmits | E>({\n ...(this.getConstructorState() as unknown as ConstructorParams<\n TParams,\n TListensTo,\n TEmits | E\n >),\n emits: [...this._emits, ...events] as ReadonlyArray<TEmits | E>,\n });\n }\n\n logic(\n fn: LogicFn<TParams, EventEnvelope<TListensTo>, EmitPayload<TEmits>>,\n ): AgentFactory<TParams, TListensTo, TEmits> {\n return new AgentFactory<TParams, TListensTo, TEmits>({\n ...this.getConstructorState(),\n logic: fn,\n });\n }\n\n produce(\n params: TParams,\n ): Agent<TParams, EventEnvelope<TListensTo>, EmitPayload<TEmits>> {\n const listensTo = this._listensTo.map((e) => e.name);\n return new Agent<TParams, EventEnvelope<TListensTo>, EmitPayload<TEmits>>(\n this._logic!,\n params,\n listensTo,\n );\n }\n}\n","import type { Envelope } from '../../agent-network/event-plane';\n\n/** Format a single SSE message (event + data) */\nexport function formatSSE(envelope: Envelope): string {\n const data = JSON.stringify(envelope);\n return `event: ${envelope.name}\\ndata: ${data}\\n\\n`;\n}\n\n/** Create a ReadableStream that encodes envelopes as SSE */\nexport function toSSEStream(\n source: AsyncIterable<Envelope>,\n signal?: AbortSignal | null,\n): ReadableStream<Uint8Array> {\n const encoder = new TextEncoder();\n\n return new ReadableStream<Uint8Array>({\n async start(controller): Promise<void> {\n const onAbort = (): void => controller.close();\n signal?.addEventListener('abort', onAbort, { once: true });\n\n try {\n for await (const envelope of source) {\n if (signal?.aborted) break;\n controller.enqueue(encoder.encode(formatSSE(envelope)));\n }\n } finally {\n signal?.removeEventListener('abort', onAbort);\n controller.close();\n }\n },\n });\n}\n","import type { ExposedAPI } from '../types';\nimport { ExposeAuthError } from '../expose';\nimport { formatSSE } from '../protocols/sse';\n\n/** Next.js App Router GET/POST handler signature */\nexport type NextGetHandler = (request: Request) => Promise<Response>;\n\n/**\n * Adapter for Next.js App Router. Maps an ExposedAPI to a route handler\n * that streams events as SSE. Use for both GET and POST; POST with JSON body\n * is recommended for passing the start event payload.\n *\n * @example\n * const api = agentNetwork.expose({ protocol: \"sse\", auth, select });\n * const handler = NextEndpoint.from(api).handler();\n * export const GET = handler;\n * export const POST = handler;\n */\nexport const NextEndpoint = {\n from(api: ExposedAPI): {\n handler(): NextGetHandler;\n } {\n if (api.protocol !== 'sse') {\n throw new Error(`NextEndpoint: unsupported protocol \"${api.protocol}\"`);\n }\n\n return {\n handler(): NextGetHandler {\n return async (request: Request) => {\n const req = { request };\n\n try {\n const encoder = new TextEncoder();\n const { readable, writable } =\n new TransformStream<Uint8Array>();\n\n // Signal that the consumer callback has been entered (auth passed, stream ready)\n let consumerStarted!: () => void;\n const started = new Promise<void>((resolve) => {\n consumerStarted = resolve;\n });\n\n const streamDone = api.createStream(req, async (stream) => {\n consumerStarted();\n const writer = writable.getWriter();\n try {\n for await (const envelope of stream) {\n if (request.signal?.aborted) break;\n await writer.write(encoder.encode(formatSSE(envelope)));\n }\n } finally {\n await writer.close();\n }\n });\n\n // Race: consumer starts (auth passed) vs. createStream rejects (auth failed)\n await Promise.race([started, streamDone]);\n\n // Auth passed. Stream is being written in the background.\n streamDone.catch(() => {}); // prevent unhandled rejection\n\n return new Response(readable, {\n headers: {\n 'Content-Type': 'text/event-stream',\n 'Cache-Control': 'no-cache',\n Connection: 'keep-alive',\n },\n });\n } catch (e) {\n if (e instanceof ExposeAuthError) {\n return new Response(e.message, { status: e.status });\n }\n throw e;\n }\n };\n },\n };\n },\n};\n","import type { ExposedAPI } from '../types';\nimport { ExposeAuthError } from '../expose';\nimport { formatSSE } from '../protocols/sse';\n\n/** Minimal Express-like request (compatible with express.Request) */\nexport type ExpressRequest = {\n on(event: 'close', fn: () => void): void;\n};\n\n/** Minimal Express-like response (compatible with express.Response) */\nexport type ExpressResponse = {\n setHeader(name: string, value: string | number): void;\n flushHeaders?(): void;\n write(chunk: Uint8Array): void;\n flush?(): void;\n end(): void;\n status(code: number): ExpressResponse;\n send(body: string): void;\n};\n\n/** Express route handler signature */\nexport type ExpressHandler = (\n req: ExpressRequest,\n res: ExpressResponse,\n) => void | Promise<void>;\n\n/**\n * Adapter for Express. Maps an ExposedAPI to an Express route handler\n * that streams events as SSE.\n *\n * @example\n * const api = agentNetwork.expose({ protocol: \"sse\", auth, select });\n * app.get(\"/events\", ExpressEndpoint.from(api).handler());\n */\nexport const ExpressEndpoint = {\n from(api: ExposedAPI): {\n handler(): ExpressHandler;\n } {\n if (api.protocol !== 'sse') {\n throw new Error(\n `ExpressEndpoint: unsupported protocol \"${api.protocol}\"`,\n );\n }\n\n return {\n handler(): ExpressHandler {\n return async (req: ExpressRequest, res: ExpressResponse) => {\n const controller = new AbortController();\n req.on('close', () => controller.abort());\n\n const exposeReq = {\n request: { signal: controller.signal } as Request,\n req,\n res,\n };\n\n try {\n const encoder = new TextEncoder();\n await api.createStream(exposeReq, async (stream) => {\n // Set SSE headers only after auth has passed\n res.setHeader('Content-Type', 'text/event-stream');\n res.setHeader('Cache-Control', 'no-cache');\n res.setHeader('Connection', 'keep-alive');\n res.flushHeaders?.();\n\n try {\n for await (const envelope of stream) {\n if (controller.signal.aborted) break;\n res.write(encoder.encode(formatSSE(envelope)));\n res.flush?.();\n }\n } finally {\n res.end();\n }\n });\n } catch (e) {\n if (e instanceof ExposeAuthError) {\n res.status(e.status).send(e.message);\n return;\n }\n throw e;\n }\n };\n },\n };\n },\n};\n"]}
@@ -0,0 +1,413 @@
1
+ import { Schema, Effect, Brand, Queue, Scope } from 'effect';
2
+ export { Schema as S } from 'effect';
3
+ import { ParseError } from 'effect/ParseResult';
4
+
5
+ type LogicFn$1<TParams, TTriggerEvent, TEmitEvent> = (ctx: {
6
+ params: TParams;
7
+ triggerEvent: TTriggerEvent;
8
+ emit: (event: TEmitEvent) => void;
9
+ }) => Promise<void>;
10
+ declare class Agent<TParams, TTriggerEvent = never, TEmitEvent = never> {
11
+ #private;
12
+ constructor(logic: LogicFn$1<TParams, TTriggerEvent, TEmitEvent>, params: TParams, listensTo?: readonly string[]);
13
+ getListensTo(): readonly string[];
14
+ invoke(options?: {
15
+ triggerEvent?: TTriggerEvent;
16
+ emit?: (event: TEmitEvent) => void;
17
+ }): Promise<void>;
18
+ getId(): string;
19
+ }
20
+
21
+ /** Standard meta carried by every event */
22
+ declare const EventMetaSchema: Schema.Struct<{
23
+ runId: typeof Schema.String;
24
+ contextId: Schema.optional<typeof Schema.String>;
25
+ correlationId: Schema.optional<typeof Schema.String>;
26
+ causationId: Schema.optional<typeof Schema.String>;
27
+ ts: Schema.optional<typeof Schema.Number>;
28
+ }>;
29
+ type EventMeta = Schema.Schema.Type<typeof EventMetaSchema>;
30
+
31
+ type AgentNetworkEventDef<EventName extends string, PayloadSchema extends Schema.Schema.Any> = {
32
+ readonly _tag: 'AgentNetworkEventDef';
33
+ readonly name: EventName;
34
+ readonly payload: PayloadSchema;
35
+ /** Decode unknown payload -> typed payload (Effect) */
36
+ readonly decodePayload: (u: unknown) => Effect.Effect<Schema.Schema.Type<PayloadSchema>, ParseError>;
37
+ /** Decode the full envelope (meta + payload) */
38
+ readonly decode: (u: unknown) => Effect.Effect<{
39
+ name: EventName;
40
+ meta: EventMeta;
41
+ payload: Schema.Schema.Type<PayloadSchema>;
42
+ }, ParseError>;
43
+ /**
44
+ * Create an unbound event (name + payload only) for emit. Validates payload via schema.
45
+ * Meta is injected by the runtime when the event is emitted.
46
+ */
47
+ readonly make: (payload: unknown) => {
48
+ name: EventName;
49
+ payload: Schema.Schema.Type<PayloadSchema>;
50
+ };
51
+ /**
52
+ * Create a full envelope (meta + payload) for tests or manual trigger events.
53
+ * Sync, throws on validation error.
54
+ */
55
+ readonly makeBound: (meta: unknown, payload: unknown) => {
56
+ name: EventName;
57
+ meta: EventMeta;
58
+ payload: Schema.Schema.Type<PayloadSchema>;
59
+ };
60
+ /**
61
+ * Effect version of make. Use when composing in Effect pipelines.
62
+ */
63
+ readonly makeEffect: (payload: unknown) => Effect.Effect<{
64
+ name: EventName;
65
+ payload: Schema.Schema.Type<PayloadSchema>;
66
+ }, ParseError>;
67
+ /**
68
+ * Effect version of makeBound. Use when composing in Effect pipelines.
69
+ */
70
+ readonly makeBoundEffect: (meta: unknown, payload: unknown) => Effect.Effect<{
71
+ name: EventName;
72
+ meta: EventMeta;
73
+ payload: Schema.Schema.Type<PayloadSchema>;
74
+ }, ParseError>;
75
+ /**
76
+ * Type guard: returns true if `u` is a valid event of this type.
77
+ */
78
+ readonly is: (u: unknown) => u is {
79
+ name: EventName;
80
+ meta: EventMeta;
81
+ payload: Schema.Schema.Type<PayloadSchema>;
82
+ };
83
+ };
84
+ declare const AgentNetworkEvent: {
85
+ of<const EventName extends string, PS extends Schema.Schema.Any>(name: EventName, payload: PS): AgentNetworkEventDef<EventName, PS>;
86
+ };
87
+
88
+ type BaseSchemaDefintion = Schema.Schema.Any;
89
+
90
+ type EventDef$2 = AgentNetworkEventDef<string, Schema.Schema.Any>;
91
+ /** Extracts the envelope type (name, meta, payload) from an event definition */
92
+ type EventEnvelope<E extends EventDef$2> = E extends AgentNetworkEventDef<infer N, infer PS> ? {
93
+ name: N;
94
+ meta: EventMeta;
95
+ payload: Schema.Schema.Type<PS>;
96
+ } : never;
97
+ /** What the user passes to emit() – no meta required */
98
+ type EmitPayload<E extends EventDef$2> = E extends AgentNetworkEventDef<infer N, infer PS> ? {
99
+ name: N;
100
+ payload: Schema.Schema.Type<PS>;
101
+ } : never;
102
+ /** Internal logic function */
103
+ type LogicFn<TParams, TTriggerEvent, TEmitEvent> = (ctx: {
104
+ params: TParams;
105
+ triggerEvent: TTriggerEvent;
106
+ emit: (event: TEmitEvent) => void;
107
+ }) => Promise<void>;
108
+ declare class AgentFactory<TParams = unknown, TListensTo extends EventDef$2 = never, TEmits extends EventDef$2 = never> {
109
+ private _listensTo;
110
+ private _emits;
111
+ private _logic;
112
+ private _paramsSchema;
113
+ private constructor();
114
+ private getConstructorState;
115
+ /** Union of all event definitions this agent listens to */
116
+ getListensTo(): ReadonlyArray<TListensTo>;
117
+ /** Union of all event definitions this agent can emit */
118
+ getEmits(): ReadonlyArray<TEmits>;
119
+ getLogic(): LogicFn<TParams, EventEnvelope<TListensTo>, EmitPayload<TEmits>> | undefined;
120
+ static run(): AgentFactory<unknown, never, never>;
121
+ params<TSchema extends BaseSchemaDefintion>(params: TSchema): AgentFactory<TSchema['Type'], TListensTo, TEmits>;
122
+ listensTo<E extends EventDef$2>(events: Array<E>): AgentFactory<TParams, TListensTo | E, TEmits>;
123
+ emits<E extends EventDef$2>(events: Array<E>): AgentFactory<TParams, TListensTo, TEmits | E>;
124
+ logic(fn: LogicFn<TParams, EventEnvelope<TListensTo>, EmitPayload<TEmits>>): AgentFactory<TParams, TListensTo, TEmits>;
125
+ produce(params: TParams): Agent<TParams, EventEnvelope<TListensTo>, EmitPayload<TEmits>>;
126
+ }
127
+
128
+ /**
129
+ * Branded type for channel names. Enforces kebab-case at runtime via refinement.
130
+ *
131
+ * **Branded types** add a nominal marker so TypeScript treats `ChannelName` as
132
+ * distinct from plain `string`, preventing accidental substitution (e.g. passing
133
+ * a raw string where a validated channel name is expected).
134
+ *
135
+ * **Refinement** validates at runtime that the value matches kebab-case before
136
+ * the brand is applied. Use `ChannelName(value)` to create a validated instance.
137
+ */
138
+ type ChannelName = string & Brand.Brand<'ChannelName'>;
139
+ declare const ChannelName: Brand.Brand.Constructor<ChannelName>;
140
+
141
+ type SinkDef = {
142
+ readonly _tag: 'SinkDef';
143
+ readonly type: string;
144
+ readonly config: unknown;
145
+ };
146
+ declare const Sink: {
147
+ kafka(config: {
148
+ topic: string;
149
+ }): SinkDef;
150
+ httpStream(): SinkDef;
151
+ };
152
+ declare function isHttpStreamSink(sink: SinkDef): boolean;
153
+ type EventDef$1 = AgentNetworkEventDef<string, Schema.Schema.Any>;
154
+ type ChannelDef = {
155
+ readonly _tag: 'ChannelDef';
156
+ readonly name: ChannelName;
157
+ };
158
+ /**
159
+ * A channel configured via the builder pattern inside `AgentNetwork.setup()`.
160
+ * Supports `.events()`, `.sink()`, and `.sinks()` chaining.
161
+ */
162
+ declare class ConfiguredChannel {
163
+ readonly _tag: "ConfiguredChannel";
164
+ readonly name: ChannelName;
165
+ private _events;
166
+ private _sinks;
167
+ constructor(name: ChannelName);
168
+ events(events: ReadonlyArray<EventDef$1>): this;
169
+ sink(sink: SinkDef): this;
170
+ sinks(sinks: ReadonlyArray<SinkDef>): this;
171
+ getEvents(): ReadonlyArray<EventDef$1>;
172
+ getSinks(): ReadonlyArray<SinkDef>;
173
+ }
174
+ declare const Channel: {
175
+ of(name: ChannelName): ChannelDef;
176
+ };
177
+
178
+ type Envelope = {
179
+ name: string;
180
+ meta: EventMeta;
181
+ payload: unknown;
182
+ };
183
+ type EventPlane = {
184
+ readonly publish: (channel: ChannelName, envelope: Envelope) => Effect.Effect<boolean>;
185
+ readonly publishToChannels: (channels: readonly ConfiguredChannel[], envelope: Envelope) => Effect.Effect<boolean>;
186
+ readonly subscribe: (channel: ChannelName) => Effect.Effect<Queue.Dequeue<Envelope>, never, Scope.Scope>;
187
+ readonly shutdown: Effect.Effect<void>;
188
+ };
189
+
190
+ /** Request context passed to auth and used by adapters */
191
+ type ExposeRequest = {
192
+ /** Web API Request (Next.js, Fetch) */
193
+ request?: Request;
194
+ /** Express req (when using ExpressEndpoint) */
195
+ req?: unknown;
196
+ /** Express res (when using ExpressEndpoint) */
197
+ res?: unknown;
198
+ };
199
+ /** Auth result: allow or deny with optional status */
200
+ type AuthResult = {
201
+ allowed: true;
202
+ } | {
203
+ allowed: false;
204
+ status?: number;
205
+ message?: string;
206
+ };
207
+ /** Channel/event selection for the exposed stream */
208
+ type ExposeSelect = {
209
+ /** Channel(s) to subscribe to. Plain strings are validated as kebab-case. Default: client channel or first channel. */
210
+ channels?: ChannelName | ChannelName[] | string | string[];
211
+ /** Event names to filter. Empty = all events. */
212
+ events?: string[];
213
+ };
214
+ /** Context passed to onRequest callback */
215
+ type OnRequestContext<T = unknown> = {
216
+ /** Emit the start event. Call with no arg to use default payload (request body), or pass custom payload. */
217
+ emitStartEvent: (payload?: T) => void;
218
+ /** The raw request context */
219
+ req: ExposeRequest;
220
+ /** Pre-parsed request body (JSON for POST, or {} for GET) */
221
+ payload: T;
222
+ };
223
+ /** Options for agentNetwork.expose() */
224
+ type ExposeOptions = {
225
+ protocol: 'sse';
226
+ /** Called per-request. Return { allowed: false } to reject. */
227
+ auth?: (req: ExposeRequest) => AuthResult | Promise<AuthResult>;
228
+ /** Which channels/events to stream */
229
+ select?: ExposeSelect;
230
+ /** Optional: use existing EventPlane instead of creating one per request */
231
+ plane?: EventPlane;
232
+ /** Event name when publishing the start event. Default: "request" */
233
+ startEventName?: string;
234
+ /** Called when a client connects, after plane is ready. Receives emitStartEvent (not the plane).
235
+ * Call emitStartEvent() for default payload, emitStartEvent(mapped) for custom mapping, or omit to skip. */
236
+ onRequest?: <T = unknown>(ctx: OnRequestContext<T>) => void | Promise<void>;
237
+ };
238
+ /** Protocol-agnostic stream source that adapters consume */
239
+ type ExposedStream = AsyncIterable<Envelope>;
240
+ /** Factory that creates a stream for a given request. Runs the network in scope. */
241
+ type StreamFactory = {
242
+ (req: ExposeRequest): Promise<ExposedStream>;
243
+ <T>(req: ExposeRequest, consumer: (stream: ExposedStream) => Promise<T>): Promise<T>;
244
+ };
245
+ /** API returned by agentNetwork.expose() - consumed by adapters */
246
+ type ExposedAPI = {
247
+ protocol: 'sse';
248
+ /** Create a stream for this request. Adapter calls this when handling a request.
249
+ * When consumer is provided, runs the consumer with the stream (scope stays open during consumption). */
250
+ createStream: StreamFactory;
251
+ };
252
+
253
+ type EventDef = AgentNetworkEventDef<string, Schema.Schema.Any>;
254
+ /** Structural interface for any Agent – avoids variance issues with private fields. */
255
+ interface AnyAgent {
256
+ getId(): string;
257
+ invoke(options?: any): Promise<void>;
258
+ /** Event names this agent listens to. Empty = listen to all. */
259
+ getListensTo?(): readonly string[];
260
+ }
261
+ type AgentBinding = {
262
+ subscribe(channel: ConfiguredChannel): AgentBinding;
263
+ publishTo(channel: ConfiguredChannel): AgentBinding;
264
+ };
265
+ type SpawnFn = (agent: AnyAgent, bindings?: {
266
+ subscribe?: string[];
267
+ publishTo?: string[];
268
+ }) => void;
269
+ type SpawnCallbackContext<TRegistry extends Record<string, AgentFactory> = Record<string, AgentFactory>> = {
270
+ kind: keyof TRegistry & string;
271
+ factory: TRegistry[keyof TRegistry & string];
272
+ payload: {
273
+ id: string;
274
+ params: Record<string, unknown>;
275
+ subscribe?: string[];
276
+ publishTo?: string[];
277
+ };
278
+ spawn: SpawnFn;
279
+ };
280
+ type SpawnerBuilder<TRegistry extends Record<string, AgentFactory> = Record<string, AgentFactory>> = {
281
+ listen(channel: ConfiguredChannel, event: EventDef): SpawnerBuilder<TRegistry>;
282
+ registry<R extends Record<string, AgentFactory>>(reg: R): SpawnerBuilder<R>;
283
+ defaultBinding(fn: (ctx: {
284
+ kind: string;
285
+ }) => {
286
+ subscribe: string[];
287
+ publishTo: string[];
288
+ }): SpawnerBuilder<TRegistry>;
289
+ onSpawn(fn: (ctx: SpawnCallbackContext<TRegistry>) => AnyAgent): SpawnerBuilder<TRegistry>;
290
+ };
291
+ type SetupContext = {
292
+ mainChannel: (name: string) => ConfiguredChannel;
293
+ createChannel: (name: string) => ConfiguredChannel;
294
+ sink: typeof Sink;
295
+ registerAgent: (agent: AnyAgent) => AgentBinding;
296
+ spawner: (factory: typeof AgentFactory) => SpawnerBuilder;
297
+ };
298
+ type AgentRegistration = {
299
+ agent: AnyAgent;
300
+ subscribedTo: ConfiguredChannel[];
301
+ publishesTo: ConfiguredChannel[];
302
+ };
303
+ type SpawnerRegistration = {
304
+ factoryClass: typeof AgentFactory;
305
+ listenChannel?: ConfiguredChannel;
306
+ listenEvent?: EventDef;
307
+ registry: Record<string, AgentFactory>;
308
+ defaultBindingFn?: (ctx: {
309
+ kind: string;
310
+ }) => {
311
+ subscribe: string[];
312
+ publishTo: string[];
313
+ };
314
+ onSpawnFn?: (ctx: SpawnCallbackContext<Record<string, AgentFactory>>) => AnyAgent;
315
+ };
316
+ declare class AgentNetwork {
317
+ private _mainChannel;
318
+ private channels;
319
+ private agentRegistrations;
320
+ private spawnerRegistrations;
321
+ private constructor();
322
+ static setup(callback: (ctx: SetupContext) => void): AgentNetwork;
323
+ private addChannel;
324
+ private setMainChannel;
325
+ private registerAgentInternal;
326
+ private createSpawnerInternal;
327
+ getChannels(): Map<string, ConfiguredChannel>;
328
+ getMainChannel(): ConfiguredChannel | undefined;
329
+ getAgentRegistrations(): Map<string, AgentRegistration>;
330
+ getSpawnerRegistrations(): ReadonlyArray<SpawnerRegistration>;
331
+ /**
332
+ * Expose the network as a streamable API (e.g. SSE). Returns an ExposedAPI
333
+ * that adapters (NextEndpoint, ExpressEndpoint) consume to produce streamed
334
+ * responses.
335
+ *
336
+ * @example
337
+ * const api = network.expose({ protocol: "sse", auth, select });
338
+ * export const GET = NextEndpoint.from(api).handler();
339
+ */
340
+ expose(options: ExposeOptions): ExposedAPI;
341
+ /**
342
+ * Starts the event plane: creates one PubSub per channel and runs subscriber
343
+ * loops for each (agent, channel) pair. Agents subscribed to a channel are
344
+ * invoked concurrently when events are published to that channel.
345
+ *
346
+ * Returns the EventPlane for publishing. Use `Effect.scoped` so the run is
347
+ * interrupted when the scope ends.
348
+ */
349
+ run(capacity?: number): Effect.Effect<EventPlane, never, Scope.Scope>;
350
+ private runScoped;
351
+ }
352
+
353
+ /** Thrown when auth denies the request */
354
+ declare class ExposeAuthError extends Error {
355
+ readonly status: number;
356
+ constructor(message: string, status?: number);
357
+ }
358
+
359
+ /** Format a single SSE message (event + data) */
360
+ declare function formatSSE(envelope: Envelope): string;
361
+ /** Create a ReadableStream that encodes envelopes as SSE */
362
+ declare function toSSEStream(source: AsyncIterable<Envelope>, signal?: AbortSignal | null): ReadableStream<Uint8Array>;
363
+
364
+ /** Next.js App Router GET/POST handler signature */
365
+ type NextGetHandler = (request: Request) => Promise<Response>;
366
+ /**
367
+ * Adapter for Next.js App Router. Maps an ExposedAPI to a route handler
368
+ * that streams events as SSE. Use for both GET and POST; POST with JSON body
369
+ * is recommended for passing the start event payload.
370
+ *
371
+ * @example
372
+ * const api = agentNetwork.expose({ protocol: "sse", auth, select });
373
+ * const handler = NextEndpoint.from(api).handler();
374
+ * export const GET = handler;
375
+ * export const POST = handler;
376
+ */
377
+ declare const NextEndpoint: {
378
+ from(api: ExposedAPI): {
379
+ handler(): NextGetHandler;
380
+ };
381
+ };
382
+
383
+ /** Minimal Express-like request (compatible with express.Request) */
384
+ type ExpressRequest = {
385
+ on(event: 'close', fn: () => void): void;
386
+ };
387
+ /** Minimal Express-like response (compatible with express.Response) */
388
+ type ExpressResponse = {
389
+ setHeader(name: string, value: string | number): void;
390
+ flushHeaders?(): void;
391
+ write(chunk: Uint8Array): void;
392
+ flush?(): void;
393
+ end(): void;
394
+ status(code: number): ExpressResponse;
395
+ send(body: string): void;
396
+ };
397
+ /** Express route handler signature */
398
+ type ExpressHandler = (req: ExpressRequest, res: ExpressResponse) => void | Promise<void>;
399
+ /**
400
+ * Adapter for Express. Maps an ExposedAPI to an Express route handler
401
+ * that streams events as SSE.
402
+ *
403
+ * @example
404
+ * const api = agentNetwork.expose({ protocol: "sse", auth, select });
405
+ * app.get("/events", ExpressEndpoint.from(api).handler());
406
+ */
407
+ declare const ExpressEndpoint: {
408
+ from(api: ExposedAPI): {
409
+ handler(): ExpressHandler;
410
+ };
411
+ };
412
+
413
+ export { Agent, AgentBinding, AgentFactory, AgentNetwork, AgentNetworkEvent, AgentNetworkEventDef, AnyAgent, AuthResult, Channel, ChannelDef, ChannelName, ConfiguredChannel, EmitPayload, EventEnvelope, EventMeta, EventMetaSchema, EventPlane, ExposeAuthError, ExposeOptions, ExposeRequest, ExposeSelect, ExposedAPI, ExposedStream, ExpressEndpoint, ExpressHandler, ExpressRequest, ExpressResponse, NextEndpoint, NextGetHandler, OnRequestContext, SetupContext, Sink, SinkDef, SpawnCallbackContext, SpawnFn, SpawnerBuilder, StreamFactory, formatSSE, isHttpStreamSink, toSSEStream };