@m4trix/core 0.8.1 → 0.9.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.
- package/dist/index.cjs +169 -31
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.ts +1 -1
- package/dist/index.js +169 -31
- package/dist/index.js.map +1 -1
- package/dist/matrix/index.cjs +169 -31
- package/dist/matrix/index.cjs.map +1 -1
- package/dist/matrix/index.d.ts +82 -29
- package/dist/matrix/index.js +169 -31
- package/dist/matrix/index.js.map +1 -1
- package/package.json +1 -1
package/dist/matrix/index.cjs
CHANGED
|
@@ -73,8 +73,66 @@ var Channel = {
|
|
|
73
73
|
};
|
|
74
74
|
}
|
|
75
75
|
};
|
|
76
|
+
|
|
77
|
+
// src/helper/types/noop.ts
|
|
78
|
+
var asyncNoop = async () => {
|
|
79
|
+
};
|
|
80
|
+
|
|
81
|
+
// src/matrix/agent-network/stores/inmemory-network-store.ts
|
|
82
|
+
var createInMemoryNetworkStore = () => {
|
|
83
|
+
const store = /* @__PURE__ */ new Map();
|
|
84
|
+
return {
|
|
85
|
+
storeEvent: (contextId, runId, event) => {
|
|
86
|
+
let byRun = store.get(contextId);
|
|
87
|
+
if (!byRun) {
|
|
88
|
+
byRun = /* @__PURE__ */ new Map();
|
|
89
|
+
store.set(contextId, byRun);
|
|
90
|
+
}
|
|
91
|
+
let events = byRun.get(runId);
|
|
92
|
+
if (!events) {
|
|
93
|
+
events = [];
|
|
94
|
+
byRun.set(runId, events);
|
|
95
|
+
}
|
|
96
|
+
events.push(event);
|
|
97
|
+
},
|
|
98
|
+
getEvents: (contextId, runId) => {
|
|
99
|
+
const events = store.get(contextId)?.get(runId);
|
|
100
|
+
return events ? [...events] : [];
|
|
101
|
+
},
|
|
102
|
+
getContextEvents: (contextId) => {
|
|
103
|
+
const byRun = store.get(contextId);
|
|
104
|
+
const result = /* @__PURE__ */ new Map();
|
|
105
|
+
if (byRun) {
|
|
106
|
+
for (const [runId, events] of byRun) {
|
|
107
|
+
result.set(runId, [...events]);
|
|
108
|
+
}
|
|
109
|
+
}
|
|
110
|
+
return result;
|
|
111
|
+
},
|
|
112
|
+
getFullStore: () => {
|
|
113
|
+
const result = /* @__PURE__ */ new Map();
|
|
114
|
+
for (const [contextId, byRun] of store) {
|
|
115
|
+
const contextMap = /* @__PURE__ */ new Map();
|
|
116
|
+
for (const [runId, events] of byRun) {
|
|
117
|
+
contextMap.set(runId, [...events]);
|
|
118
|
+
}
|
|
119
|
+
result.set(contextId, contextMap);
|
|
120
|
+
}
|
|
121
|
+
return result;
|
|
122
|
+
},
|
|
123
|
+
persist: () => asyncNoop(),
|
|
124
|
+
load: () => asyncNoop()
|
|
125
|
+
};
|
|
126
|
+
};
|
|
127
|
+
|
|
128
|
+
// src/matrix/agent-network/event-plane.ts
|
|
76
129
|
var DEFAULT_CAPACITY = 16;
|
|
77
|
-
var createEventPlane = (
|
|
130
|
+
var createEventPlane = (options) => effect.Effect.gen(function* () {
|
|
131
|
+
const {
|
|
132
|
+
network,
|
|
133
|
+
capacity = DEFAULT_CAPACITY,
|
|
134
|
+
store = createInMemoryNetworkStore()
|
|
135
|
+
} = options;
|
|
78
136
|
const channels = network.getChannels();
|
|
79
137
|
const pubsubs = /* @__PURE__ */ new Map();
|
|
80
138
|
for (const channel of channels.values()) {
|
|
@@ -87,12 +145,42 @@ var createEventPlane = (network, capacity = DEFAULT_CAPACITY) => effect.Effect.g
|
|
|
87
145
|
throw new Error(`Channel not found: ${channel}`);
|
|
88
146
|
return p;
|
|
89
147
|
};
|
|
90
|
-
const
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
)
|
|
148
|
+
const recordEvent = (envelope) => {
|
|
149
|
+
const { contextId, runId } = envelope.meta;
|
|
150
|
+
store.storeEvent(contextId, runId, envelope);
|
|
151
|
+
};
|
|
152
|
+
const publishToPubSub = (channel, envelope) => effect.PubSub.publish(getPubsub(channel), envelope);
|
|
153
|
+
const publish = (channel, envelope) => effect.Effect.sync(() => recordEvent(envelope)).pipe(
|
|
154
|
+
effect.Effect.flatMap(() => publishToPubSub(channel, envelope))
|
|
155
|
+
);
|
|
156
|
+
const publishToChannels = (targetChannels, envelope) => effect.Effect.sync(() => recordEvent(envelope)).pipe(
|
|
157
|
+
effect.Effect.flatMap(
|
|
158
|
+
() => effect.Effect.all(
|
|
159
|
+
targetChannels.map((c) => publishToPubSub(c.name, envelope)),
|
|
160
|
+
{ concurrency: "unbounded" }
|
|
161
|
+
)
|
|
162
|
+
),
|
|
163
|
+
effect.Effect.map((results) => results.every(Boolean))
|
|
164
|
+
);
|
|
95
165
|
const subscribe = (channel) => effect.PubSub.subscribe(getPubsub(channel));
|
|
166
|
+
const getRunEvents = (runId, contextId) => {
|
|
167
|
+
return store.getEvents(contextId, runId).slice();
|
|
168
|
+
};
|
|
169
|
+
const getContextEvents = (contextId) => {
|
|
170
|
+
const byRun = store.getContextEvents(contextId);
|
|
171
|
+
const map = /* @__PURE__ */ new Map();
|
|
172
|
+
const all = [];
|
|
173
|
+
for (const [runId, events] of byRun) {
|
|
174
|
+
const readonlyEvents = events.slice();
|
|
175
|
+
map.set(runId, readonlyEvents);
|
|
176
|
+
all.push(...readonlyEvents);
|
|
177
|
+
}
|
|
178
|
+
return {
|
|
179
|
+
all,
|
|
180
|
+
byRun: (runId) => map.get(runId) ?? [],
|
|
181
|
+
map
|
|
182
|
+
};
|
|
183
|
+
};
|
|
96
184
|
const shutdown = effect.Effect.all([...pubsubs.values()].map(effect.PubSub.shutdown), {
|
|
97
185
|
concurrency: "unbounded"
|
|
98
186
|
}).pipe(effect.Effect.asVoid);
|
|
@@ -100,6 +188,8 @@ var createEventPlane = (network, capacity = DEFAULT_CAPACITY) => effect.Effect.g
|
|
|
100
188
|
publish,
|
|
101
189
|
publishToChannels,
|
|
102
190
|
subscribe,
|
|
191
|
+
getRunEvents,
|
|
192
|
+
getContextEvents,
|
|
103
193
|
shutdown
|
|
104
194
|
};
|
|
105
195
|
});
|
|
@@ -110,6 +200,11 @@ var runSubscriber = (agent, publishesTo, dequeue, plane, emitQueue) => effect.Ef
|
|
|
110
200
|
if (listensTo.length > 0 && !listensTo.includes(envelope.name)) {
|
|
111
201
|
return;
|
|
112
202
|
}
|
|
203
|
+
const runEvents = plane.getRunEvents(
|
|
204
|
+
envelope.meta.runId,
|
|
205
|
+
envelope.meta.contextId
|
|
206
|
+
);
|
|
207
|
+
const contextEvents = plane.getContextEvents(envelope.meta.contextId);
|
|
113
208
|
yield* effect.Effect.tryPromise({
|
|
114
209
|
try: () => agent.invoke({
|
|
115
210
|
triggerEvent: envelope,
|
|
@@ -132,7 +227,9 @@ var runSubscriber = (agent, publishesTo, dequeue, plane, emitQueue) => effect.Ef
|
|
|
132
227
|
plane.publishToChannels(publishesTo, fullEnvelope)
|
|
133
228
|
);
|
|
134
229
|
}
|
|
135
|
-
}
|
|
230
|
+
},
|
|
231
|
+
runEvents,
|
|
232
|
+
contextEvents
|
|
136
233
|
}),
|
|
137
234
|
catch: (e) => e
|
|
138
235
|
});
|
|
@@ -226,7 +323,15 @@ function streamFromDequeue(take, signal, eventFilter) {
|
|
|
226
323
|
};
|
|
227
324
|
}
|
|
228
325
|
function expose(network, options) {
|
|
229
|
-
const {
|
|
326
|
+
const {
|
|
327
|
+
auth,
|
|
328
|
+
select,
|
|
329
|
+
plane: providedPlane,
|
|
330
|
+
onRequest,
|
|
331
|
+
triggerEvents
|
|
332
|
+
} = options;
|
|
333
|
+
const triggerEventDef = triggerEvents?.[0];
|
|
334
|
+
const triggerEventName = triggerEventDef?.name ?? "request";
|
|
230
335
|
const channels = resolveChannels(network, select);
|
|
231
336
|
const eventFilter = select?.events;
|
|
232
337
|
const mainChannel = network.getMainChannel();
|
|
@@ -237,7 +342,7 @@ function expose(network, options) {
|
|
|
237
342
|
const payload = await extractPayload(req);
|
|
238
343
|
const signal = req.request?.signal;
|
|
239
344
|
const program = effect.Effect.gen(function* () {
|
|
240
|
-
const plane = providedPlane ?? (yield* createEventPlane(network));
|
|
345
|
+
const plane = providedPlane ?? (yield* createEventPlane({ network }));
|
|
241
346
|
if (!providedPlane) {
|
|
242
347
|
const emitQueue = yield* effect.Queue.unbounded();
|
|
243
348
|
yield* effect.Effect.fork(
|
|
@@ -253,25 +358,46 @@ function expose(network, options) {
|
|
|
253
358
|
yield* effect.Effect.sleep("10 millis");
|
|
254
359
|
}
|
|
255
360
|
const targetChannel = mainChannel?.name ?? channels[0];
|
|
256
|
-
|
|
257
|
-
|
|
361
|
+
let runId = req.runId ?? crypto.randomUUID();
|
|
362
|
+
let contextId = req.contextId ?? crypto.randomUUID();
|
|
363
|
+
const setRunId = (id) => {
|
|
364
|
+
runId = id;
|
|
365
|
+
};
|
|
366
|
+
const setContextId = (id) => {
|
|
367
|
+
contextId = id;
|
|
368
|
+
};
|
|
369
|
+
const emitStartEvent = (opts) => {
|
|
370
|
+
const meta = {
|
|
371
|
+
runId: opts.runId,
|
|
372
|
+
contextId: opts.contextId
|
|
373
|
+
};
|
|
258
374
|
const envelope = {
|
|
259
|
-
name:
|
|
260
|
-
meta
|
|
261
|
-
payload:
|
|
375
|
+
name: opts.event.name,
|
|
376
|
+
meta,
|
|
377
|
+
payload: opts.event.payload
|
|
262
378
|
};
|
|
263
|
-
effect.Effect.runPromise(plane.publish(targetChannel, envelope)).catch(
|
|
264
|
-
|
|
379
|
+
effect.Effect.runPromise(plane.publish(targetChannel, envelope)).catch(
|
|
380
|
+
() => {
|
|
381
|
+
}
|
|
382
|
+
);
|
|
265
383
|
};
|
|
266
384
|
const dequeue = yield* plane.subscribe(channels[0]);
|
|
267
385
|
if (onRequest) {
|
|
268
386
|
yield* effect.Effect.tryPromise(
|
|
269
|
-
() => Promise.resolve(
|
|
387
|
+
() => Promise.resolve(
|
|
388
|
+
onRequest({
|
|
389
|
+
setRunId,
|
|
390
|
+
setContextId,
|
|
391
|
+
emitStartEvent,
|
|
392
|
+
req,
|
|
393
|
+
payload
|
|
394
|
+
})
|
|
395
|
+
)
|
|
270
396
|
);
|
|
271
397
|
} else if (!providedPlane) {
|
|
272
398
|
const envelope = {
|
|
273
|
-
name:
|
|
274
|
-
meta: { runId
|
|
399
|
+
name: triggerEventName,
|
|
400
|
+
meta: { runId, contextId },
|
|
275
401
|
payload
|
|
276
402
|
};
|
|
277
403
|
yield* plane.publish(targetChannel, envelope);
|
|
@@ -410,7 +536,7 @@ var AgentNetwork = class _AgentNetwork {
|
|
|
410
536
|
*
|
|
411
537
|
* @example
|
|
412
538
|
* const api = network.expose({ protocol: "sse", auth, select });
|
|
413
|
-
* export const GET = NextEndpoint.from(api).handler();
|
|
539
|
+
* export const GET = NextEndpoint.from(api, { requestToContextId, requestToRunId }).handler();
|
|
414
540
|
*/
|
|
415
541
|
expose(options) {
|
|
416
542
|
return expose(this, options);
|
|
@@ -428,7 +554,7 @@ var AgentNetwork = class _AgentNetwork {
|
|
|
428
554
|
}
|
|
429
555
|
runScoped(network, capacity) {
|
|
430
556
|
return effect.Effect.gen(function* () {
|
|
431
|
-
const plane = yield* createEventPlane(network, capacity);
|
|
557
|
+
const plane = yield* createEventPlane({ network, capacity });
|
|
432
558
|
yield* effect.Effect.fork(run(network, plane));
|
|
433
559
|
return plane;
|
|
434
560
|
});
|
|
@@ -436,7 +562,7 @@ var AgentNetwork = class _AgentNetwork {
|
|
|
436
562
|
};
|
|
437
563
|
var EventMetaSchema = effect.Schema.Struct({
|
|
438
564
|
runId: effect.Schema.String,
|
|
439
|
-
contextId: effect.Schema.
|
|
565
|
+
contextId: effect.Schema.String,
|
|
440
566
|
correlationId: effect.Schema.optional(effect.Schema.String),
|
|
441
567
|
causationId: effect.Schema.optional(effect.Schema.String),
|
|
442
568
|
ts: effect.Schema.optional(effect.Schema.Number)
|
|
@@ -459,9 +585,7 @@ var AgentNetworkEvent = {
|
|
|
459
585
|
const makeBound = (meta, payload2) => effect.Effect.runSync(
|
|
460
586
|
decodeEnvelope({ name, meta, payload: payload2 })
|
|
461
587
|
);
|
|
462
|
-
const makeEffect = (payload2) => decodePayload(payload2).pipe(
|
|
463
|
-
effect.Effect.map((p) => ({ name, payload: p }))
|
|
464
|
-
);
|
|
588
|
+
const makeEffect = (payload2) => decodePayload(payload2).pipe(effect.Effect.map((p) => ({ name, payload: p })));
|
|
465
589
|
const makeBoundEffect = (meta, payload2) => decodeEnvelope({ name, meta, payload: payload2 });
|
|
466
590
|
const is = effect.Schema.is(envelopeSchema);
|
|
467
591
|
return {
|
|
@@ -494,13 +618,19 @@ var Agent = class {
|
|
|
494
618
|
return __privateGet(this, _listensTo);
|
|
495
619
|
}
|
|
496
620
|
async invoke(options) {
|
|
497
|
-
const { triggerEvent, emit } = options ?? {};
|
|
621
|
+
const { triggerEvent, emit, runEvents, contextEvents } = options ?? {};
|
|
498
622
|
const emitFn = emit ?? ((_event) => {
|
|
499
623
|
});
|
|
500
624
|
await __privateGet(this, _logic).call(this, {
|
|
501
625
|
params: __privateGet(this, _params),
|
|
502
626
|
triggerEvent: triggerEvent ?? void 0,
|
|
503
|
-
emit: emitFn
|
|
627
|
+
emit: emitFn,
|
|
628
|
+
runEvents: runEvents ?? [],
|
|
629
|
+
contextEvents: contextEvents ?? {
|
|
630
|
+
all: [],
|
|
631
|
+
byRun: () => [],
|
|
632
|
+
map: /* @__PURE__ */ new Map()
|
|
633
|
+
}
|
|
504
634
|
});
|
|
505
635
|
}
|
|
506
636
|
getId() {
|
|
@@ -613,14 +743,19 @@ function toSSEStream(source, signal) {
|
|
|
613
743
|
|
|
614
744
|
// src/matrix/io/adapters/next-endpoint.ts
|
|
615
745
|
var NextEndpoint = {
|
|
616
|
-
from(api) {
|
|
746
|
+
from(api, options) {
|
|
617
747
|
if (api.protocol !== "sse") {
|
|
618
748
|
throw new Error(`NextEndpoint: unsupported protocol "${api.protocol}"`);
|
|
619
749
|
}
|
|
750
|
+
const { requestToContextId, requestToRunId } = options;
|
|
620
751
|
return {
|
|
621
752
|
handler() {
|
|
622
753
|
return async (request) => {
|
|
623
|
-
const req = {
|
|
754
|
+
const req = {
|
|
755
|
+
request,
|
|
756
|
+
contextId: requestToContextId(request),
|
|
757
|
+
runId: requestToRunId(request)
|
|
758
|
+
};
|
|
624
759
|
try {
|
|
625
760
|
const encoder = new TextEncoder();
|
|
626
761
|
const { readable, writable } = new TransformStream();
|
|
@@ -665,12 +800,13 @@ var NextEndpoint = {
|
|
|
665
800
|
|
|
666
801
|
// src/matrix/io/adapters/express-endpoint.ts
|
|
667
802
|
var ExpressEndpoint = {
|
|
668
|
-
from(api) {
|
|
803
|
+
from(api, options) {
|
|
669
804
|
if (api.protocol !== "sse") {
|
|
670
805
|
throw new Error(
|
|
671
806
|
`ExpressEndpoint: unsupported protocol "${api.protocol}"`
|
|
672
807
|
);
|
|
673
808
|
}
|
|
809
|
+
const { requestToContextId, requestToRunId } = options;
|
|
674
810
|
return {
|
|
675
811
|
handler() {
|
|
676
812
|
return async (req, res) => {
|
|
@@ -679,7 +815,9 @@ var ExpressEndpoint = {
|
|
|
679
815
|
const exposeReq = {
|
|
680
816
|
request: { signal: controller.signal },
|
|
681
817
|
req,
|
|
682
|
-
res
|
|
818
|
+
res,
|
|
819
|
+
contextId: requestToContextId(req),
|
|
820
|
+
runId: requestToRunId(req)
|
|
683
821
|
};
|
|
684
822
|
try {
|
|
685
823
|
const encoder = new TextEncoder();
|
|
@@ -1 +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"]}
|
|
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/helper/types/noop.ts","../../src/matrix/agent-network/stores/inmemory-network-store.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, { requestToContextId, requestToRunId }).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 {\n ContextEvents,\n EventMeta,\n RunEvents,\n} from './agent-network-event';\nimport type { ChannelName, ConfiguredChannel } from './channel';\nimport type { AgentNetworkStore } from './stores/agent-network-store';\nimport { createInMemoryNetworkStore } from './stores/inmemory-network-store';\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 getRunEvents: (runId: string, contextId: string) => RunEvents;\n readonly getContextEvents: (contextId: string) => ContextEvents;\n readonly shutdown: Effect.Effect<void>;\n};\n\n/* ─── Create EventPlane ─── */\n\nconst DEFAULT_CAPACITY = 16;\n\ntype CreateEventPlaneOptions = {\n network: AgentNetwork;\n capacity?: number;\n store?: AgentNetworkStore<Envelope>;\n};\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 options: CreateEventPlaneOptions,\n): Effect.Effect<EventPlane> =>\n Effect.gen(function* () {\n const {\n network,\n capacity = DEFAULT_CAPACITY,\n store = createInMemoryNetworkStore<Envelope>(),\n } = options;\n\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 recordEvent = (envelope: Envelope): void => {\n const { contextId, runId } = envelope.meta;\n store.storeEvent(contextId, runId, envelope);\n };\n\n const publishToPubSub = (\n channel: ChannelName,\n envelope: Envelope,\n ): Effect.Effect<boolean> => PubSub.publish(getPubsub(channel), envelope);\n\n const publish = (\n channel: ChannelName,\n envelope: Envelope,\n ): Effect.Effect<boolean> =>\n Effect.sync(() => recordEvent(envelope)).pipe(\n Effect.flatMap(() => publishToPubSub(channel, envelope)),\n );\n\n const publishToChannels = (\n targetChannels: readonly ConfiguredChannel[],\n envelope: Envelope,\n ): Effect.Effect<boolean> =>\n Effect.sync(() => recordEvent(envelope)).pipe(\n Effect.flatMap(() =>\n Effect.all(\n targetChannels.map((c) => publishToPubSub(c.name, envelope)),\n { concurrency: 'unbounded' },\n ),\n ),\n Effect.map((results) => results.every(Boolean)),\n );\n\n const subscribe = (\n channel: ChannelName,\n ): Effect.Effect<Queue.Dequeue<Envelope>, never, Scope.Scope> =>\n PubSub.subscribe(getPubsub(channel));\n\n const getRunEvents = (runId: string, contextId: string): RunEvents => {\n return store.getEvents(contextId, runId).slice();\n };\n\n const getContextEvents = (contextId: string): ContextEvents => {\n const byRun = store.getContextEvents(contextId);\n const map = new Map<string, readonly Envelope[]>();\n const all: Envelope[] = [];\n for (const [runId, events] of byRun) {\n const readonlyEvents = events.slice();\n map.set(runId, readonlyEvents);\n all.push(...readonlyEvents);\n }\n return {\n all,\n byRun: (runId: string) => map.get(runId) ?? [],\n map,\n };\n };\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 getRunEvents,\n getContextEvents,\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 const runEvents = plane.getRunEvents(\n envelope.meta.runId,\n envelope.meta.contextId,\n );\n const contextEvents = plane.getContextEvents(envelope.meta.contextId);\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 runEvents,\n contextEvents,\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","/**\n * Type-safe no-operation stubs for use as default handlers.\n *\n * `noop` and `asyncNoop` are assignable to any callback that expects\n * additional parameters — TypeScript allows a function with fewer\n * parameters to substitute for one expecting more.\n *\n * @example\n * ```ts\n * type LogicFn = (ctx: { params: Config; emit: Emitter }) => Promise<void>;\n * const defaultLogic: LogicFn = asyncNoop;\n * ```\n */\n\n/** Synchronous no-op — safe default for any `(...) => void` handler. */\nexport const noop = (): void => {};\n\n/** Asynchronous no-op — safe default for any `(...) => Promise<void>` handler. */\nexport const asyncNoop = async (): Promise<void> => {};\n\n/** Synchronous no-op that returns a given value — for handlers that must return `R`. */\nexport const noopOf =\n <R>(value: R): (() => R) =>\n () =>\n value;\n\n/** Asynchronous no-op that resolves to a given value — for handlers that must return `Promise<R>`. */\nexport const asyncNoopOf =\n <R>(value: R): (() => Promise<R>) =>\n async () =>\n value;\n","import { asyncNoop } from '../../../helper/types/noop';\nimport type { AgentNetworkStore } from './agent-network-store';\n\n/**\n * In-memory implementation of AgentNetworkStore. Events are stored in a\n * nested map: contextId -> runId -> events.\n */\nexport const createInMemoryNetworkStore = <T>(): AgentNetworkStore<T> => {\n const store = new Map<string, Map<string, T[]>>();\n\n return {\n storeEvent: (contextId: string, runId: string, event: T): void => {\n let byRun = store.get(contextId);\n if (!byRun) {\n byRun = new Map();\n store.set(contextId, byRun);\n }\n let events = byRun.get(runId);\n if (!events) {\n events = [];\n byRun.set(runId, events);\n }\n events.push(event);\n },\n\n getEvents: (contextId: string, runId: string): T[] => {\n const events = store.get(contextId)?.get(runId);\n return events ? [...events] : [];\n },\n\n getContextEvents: (contextId: string): Map<string, T[]> => {\n const byRun = store.get(contextId);\n const result = new Map<string, T[]>();\n if (byRun) {\n for (const [runId, events] of byRun) {\n result.set(runId, [...events]);\n }\n }\n return result;\n },\n\n getFullStore: (): Map<string, Map<string, T[]>> => {\n const result = new Map<string, Map<string, T[]>>();\n for (const [contextId, byRun] of store) {\n const contextMap = new Map<string, T[]>();\n for (const [runId, events] of byRun) {\n contextMap.set(runId, [...events]);\n }\n result.set(contextId, contextMap);\n }\n return result;\n },\n\n persist: (): Promise<void> => asyncNoop(),\n load: (): Promise<void> => asyncNoop(),\n };\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, { requestToContextId, requestToRunId }).handler();\n */\nexport function expose(\n network: AgentNetwork,\n options: ExposeOptions,\n): ExposedAPI {\n const {\n auth,\n select,\n plane: providedPlane,\n onRequest,\n triggerEvents,\n } = options;\n const triggerEventDef = triggerEvents?.[0];\n const triggerEventName = triggerEventDef?.name ?? 'request';\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 let runId = req.runId ?? crypto.randomUUID();\n let contextId = req.contextId ?? crypto.randomUUID();\n\n const setRunId = (id: string): void => {\n runId = id;\n };\n const setContextId = (id: string): void => {\n contextId = id;\n };\n\n const emitStartEvent = (opts: {\n contextId: string;\n runId: string;\n event: { name: string; payload: unknown };\n }): void => {\n const meta = {\n runId: opts.runId,\n contextId: opts.contextId,\n };\n const envelope: Envelope = {\n name: opts.event.name,\n meta,\n payload: opts.event.payload,\n };\n Effect.runPromise(plane.publish(targetChannel, envelope)).catch(\n () => {},\n );\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(\n onRequest({\n setRunId,\n setContextId,\n emitStartEvent,\n req,\n payload,\n }),\n ),\n );\n } else if (!providedPlane) {\n const envelope: Envelope = {\n name: triggerEventName,\n meta: { runId, contextId },\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.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/** Envelope-like shape for events (avoids circular dep with event-plane) */\nexport type EnvelopeLike = { name: string; meta: EventMeta; payload: unknown };\nexport type RunEvents = readonly EnvelopeLike[];\n\nexport type ContextEvents = {\n /** All events in the context across all runs */\n readonly all: readonly EnvelopeLike[];\n /** Get events for a specific run */\n byRun(runId: string): readonly EnvelopeLike[];\n /** Map of runId -> events */\n readonly map: ReadonlyMap<string, readonly EnvelopeLike[]>;\n};\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: (\n payload: unknown,\n ) => 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 = (\n payload: unknown,\n ): { name: EventName; payload: S.Schema.Type<PS> } => {\n const decoded = Effect.runSync(\n decodePayload(payload) as unknown as Effect.Effect<\n S.Schema.Type<PS>,\n ParseError\n >,\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<\n { name: EventName; payload: S.Schema.Type<PS> },\n ParseError\n > =>\n (\n decodePayload(payload) as unknown as Effect.Effect<\n S.Schema.Type<PS>,\n ParseError\n >\n ).pipe(Effect.map((p) => ({ name, payload: p })));\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';\nimport type {\n ContextEvents,\n RunEvents,\n} from './agent-network/agent-network-event';\n\ntype LogicFn<TParams, TTriggerEvent, TEmitEvent> = (ctx: {\n params: TParams;\n triggerEvent: TTriggerEvent;\n emit: (event: TEmitEvent) => void;\n runEvents: RunEvents;\n contextEvents: ContextEvents;\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 runEvents?: RunEvents;\n contextEvents?: ContextEvents;\n }): Promise<void> {\n const { triggerEvent, emit, runEvents, contextEvents } = 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 runEvents: runEvents ?? [],\n contextEvents: contextEvents ?? {\n all: [],\n byRun: () => [],\n map: new Map(),\n },\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 ContextEvents,\n type EventMeta,\n type RunEvents,\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 runEvents: RunEvents;\n contextEvents: ContextEvents;\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/** Options for NextEndpoint.from() - required to define how request maps to contextId and runId */\nexport type NextEndpointOptions = {\n requestToContextId: (request: Request) => string;\n requestToRunId: (request: Request) => string;\n};\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, {\n * requestToContextId: (req) => req.headers.get('x-correlation-id') ?? crypto.randomUUID(),\n * requestToRunId: () => crypto.randomUUID(),\n * }).handler();\n * export const GET = handler;\n * export const POST = handler;\n */\nexport const NextEndpoint = {\n from(api: ExposedAPI, options: NextEndpointOptions): {\n handler(): NextGetHandler;\n } {\n if (api.protocol !== 'sse') {\n throw new Error(`NextEndpoint: unsupported protocol \"${api.protocol}\"`);\n }\n\n const { requestToContextId, requestToRunId } = options;\n\n return {\n handler(): NextGetHandler {\n return async (request: Request) => {\n const req = {\n request,\n contextId: requestToContextId(request),\n runId: requestToRunId(request),\n };\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/** Options for ExpressEndpoint.from() - required to define how request maps to contextId and runId */\nexport type ExpressEndpointOptions = {\n requestToContextId: (req: ExpressRequest) => string;\n requestToRunId: (req: ExpressRequest) => string;\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, {\n * requestToContextId: (req) => req.headers?.['x-correlation-id'] ?? crypto.randomUUID(),\n * requestToRunId: () => crypto.randomUUID(),\n * }).handler());\n */\nexport const ExpressEndpoint = {\n from(api: ExposedAPI, options: ExpressEndpointOptions): {\n handler(): ExpressHandler;\n } {\n if (api.protocol !== 'sse') {\n throw new Error(\n `ExpressEndpoint: unsupported protocol \"${api.protocol}\"`,\n );\n }\n\n const { requestToContextId, requestToRunId } = options;\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 contextId: requestToContextId(req),\n runId: requestToRunId(req),\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"]}
|