@m4trix/core 0.9.0 → 0.10.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.
@@ -151,7 +151,16 @@ var createEventPlane = (options) => effect.Effect.gen(function* () {
151
151
  };
152
152
  const publishToPubSub = (channel, envelope) => effect.PubSub.publish(getPubsub(channel), envelope);
153
153
  const publish = (channel, envelope) => effect.Effect.sync(() => recordEvent(envelope)).pipe(
154
- effect.Effect.flatMap(() => publishToPubSub(channel, envelope))
154
+ effect.Effect.flatMap(() => publishToPubSub(channel, envelope)),
155
+ effect.Effect.withSpan("event.publish", {
156
+ attributes: {
157
+ "event.name": envelope.name,
158
+ "event.payload": payloadForSpan(envelope.payload),
159
+ channel,
160
+ runId: envelope.meta.runId,
161
+ contextId: envelope.meta.contextId
162
+ }
163
+ })
155
164
  );
156
165
  const publishToChannels = (targetChannels, envelope) => effect.Effect.sync(() => recordEvent(envelope)).pipe(
157
166
  effect.Effect.flatMap(
@@ -160,7 +169,15 @@ var createEventPlane = (options) => effect.Effect.gen(function* () {
160
169
  { concurrency: "unbounded" }
161
170
  )
162
171
  ),
163
- effect.Effect.map((results) => results.every(Boolean))
172
+ effect.Effect.map((results) => results.every(Boolean)),
173
+ effect.Effect.withSpan("event.publish", {
174
+ attributes: {
175
+ "event.name": envelope.name,
176
+ "event.payload": payloadForSpan(envelope.payload),
177
+ runId: envelope.meta.runId,
178
+ contextId: envelope.meta.contextId
179
+ }
180
+ })
164
181
  );
165
182
  const subscribe = (channel) => effect.PubSub.subscribe(getPubsub(channel));
166
183
  const getRunEvents = (runId, contextId) => {
@@ -193,8 +210,17 @@ var createEventPlane = (options) => effect.Effect.gen(function* () {
193
210
  shutdown
194
211
  };
195
212
  });
196
- var runSubscriber = (agent, publishesTo, dequeue, plane, emitQueue) => effect.Effect.gen(function* () {
213
+ function payloadForSpan(payload, maxLen = 500) {
214
+ try {
215
+ const s = JSON.stringify(payload);
216
+ return s.length > maxLen ? `${s.slice(0, maxLen)}...` : s;
217
+ } catch {
218
+ return String(payload);
219
+ }
220
+ }
221
+ var runSubscriber = (agent, publishesTo, dequeue, plane, emitQueue, channelName) => effect.Effect.gen(function* () {
197
222
  const listensTo = agent.getListensTo?.() ?? [];
223
+ const agentId = agent.getId();
198
224
  const processOne = () => effect.Effect.gen(function* () {
199
225
  const envelope = yield* effect.Queue.take(dequeue);
200
226
  if (listensTo.length > 0 && !listensTo.includes(envelope.name)) {
@@ -205,34 +231,51 @@ var runSubscriber = (agent, publishesTo, dequeue, plane, emitQueue) => effect.Ef
205
231
  envelope.meta.contextId
206
232
  );
207
233
  const contextEvents = plane.getContextEvents(envelope.meta.contextId);
208
- yield* effect.Effect.tryPromise({
209
- try: () => agent.invoke({
210
- triggerEvent: envelope,
211
- emit: (userEvent) => {
212
- const fullEnvelope = {
213
- name: userEvent.name,
214
- meta: envelope.meta,
215
- payload: userEvent.payload
216
- };
217
- if (emitQueue) {
218
- effect.Effect.runPromise(
219
- effect.Queue.offer(emitQueue, {
220
- channels: publishesTo,
221
- envelope: fullEnvelope
222
- })
223
- ).catch(() => {
224
- });
225
- } else {
226
- effect.Effect.runFork(
227
- plane.publishToChannels(publishesTo, fullEnvelope)
228
- );
229
- }
230
- },
231
- runEvents,
232
- contextEvents
233
- }),
234
- catch: (e) => e
235
- });
234
+ yield* effect.Effect.withSpan("agent.listen", {
235
+ attributes: {
236
+ agentId,
237
+ "event.name": envelope.name,
238
+ "event.payload": payloadForSpan(envelope.payload),
239
+ ...channelName !== void 0 && { channel: channelName }
240
+ }
241
+ })(
242
+ effect.Effect.withSpan("agent.invoke", {
243
+ attributes: {
244
+ agentId,
245
+ "event.name": envelope.name,
246
+ "event.payload": payloadForSpan(envelope.payload)
247
+ }
248
+ })(
249
+ effect.Effect.tryPromise({
250
+ try: () => agent.invoke({
251
+ triggerEvent: envelope,
252
+ emit: (userEvent) => {
253
+ const fullEnvelope = {
254
+ name: userEvent.name,
255
+ meta: envelope.meta,
256
+ payload: userEvent.payload
257
+ };
258
+ if (emitQueue) {
259
+ effect.Effect.runPromise(
260
+ effect.Queue.offer(emitQueue, {
261
+ channels: publishesTo,
262
+ envelope: fullEnvelope
263
+ })
264
+ ).catch(() => {
265
+ });
266
+ } else {
267
+ effect.Effect.runFork(
268
+ plane.publishToChannels(publishesTo, fullEnvelope)
269
+ );
270
+ }
271
+ },
272
+ runEvents,
273
+ contextEvents
274
+ }),
275
+ catch: (e) => e
276
+ })
277
+ )
278
+ );
236
279
  }).pipe(
237
280
  effect.Effect.catchAllCause(
238
281
  (cause) => effect.Cause.isInterrupted(cause) ? effect.Effect.void : effect.Effect.sync(() => {
@@ -254,7 +297,8 @@ var run = (network, plane, options) => effect.Effect.gen(function* () {
254
297
  reg.publishesTo,
255
298
  dequeue,
256
299
  plane,
257
- emitQueue
300
+ emitQueue,
301
+ channel.name
258
302
  );
259
303
  }
260
304
  }
@@ -328,7 +372,8 @@ function expose(network, options) {
328
372
  select,
329
373
  plane: providedPlane,
330
374
  onRequest,
331
- triggerEvents
375
+ triggerEvents,
376
+ tracingLayer
332
377
  } = options;
333
378
  const triggerEventDef = triggerEvents?.[0];
334
379
  const triggerEventName = triggerEventDef?.name ?? "request";
@@ -342,7 +387,7 @@ function expose(network, options) {
342
387
  const payload = await extractPayload(req);
343
388
  const signal = req.request?.signal;
344
389
  const program = effect.Effect.gen(function* () {
345
- const plane = providedPlane ?? (yield* createEventPlane({ network }));
390
+ const plane = providedPlane ?? (yield* createEventPlane({ network, store: network.getStore() }));
346
391
  if (!providedPlane) {
347
392
  const emitQueue = yield* effect.Queue.unbounded();
348
393
  yield* effect.Effect.fork(
@@ -410,7 +455,8 @@ function expose(network, options) {
410
455
  }
411
456
  return stream;
412
457
  });
413
- return effect.Effect.runPromise(program.pipe(effect.Effect.scoped));
458
+ const runnable = tracingLayer ? program.pipe(effect.Effect.provide(tracingLayer), effect.Effect.scoped) : program.pipe(effect.Effect.scoped);
459
+ return effect.Effect.runPromise(runnable);
414
460
  };
415
461
  return {
416
462
  protocol: "sse",
@@ -442,6 +488,7 @@ var AgentNetwork = class _AgentNetwork {
442
488
  this.channels = /* @__PURE__ */ new Map();
443
489
  this.agentRegistrations = /* @__PURE__ */ new Map();
444
490
  this.spawnerRegistrations = [];
491
+ this._store = createInMemoryNetworkStore();
445
492
  }
446
493
  /* ─── Public Static Factory ─── */
447
494
  static setup(callback) {
@@ -529,6 +576,10 @@ var AgentNetwork = class _AgentNetwork {
529
576
  getSpawnerRegistrations() {
530
577
  return this.spawnerRegistrations;
531
578
  }
579
+ /** Store defined at network setup time. Shared across all event planes created for this network. */
580
+ getStore() {
581
+ return this._store;
582
+ }
532
583
  /**
533
584
  * Expose the network as a streamable API (e.g. SSE). Returns an ExposedAPI
534
585
  * that adapters (NextEndpoint, ExpressEndpoint) consume to produce streamed
@@ -554,7 +605,11 @@ var AgentNetwork = class _AgentNetwork {
554
605
  }
555
606
  runScoped(network, capacity) {
556
607
  return effect.Effect.gen(function* () {
557
- const plane = yield* createEventPlane({ network, capacity });
608
+ const plane = yield* createEventPlane({
609
+ network,
610
+ capacity,
611
+ store: network.getStore()
612
+ });
558
613
  yield* effect.Effect.fork(run(network, plane));
559
614
  return plane;
560
615
  });
@@ -849,6 +904,78 @@ var ExpressEndpoint = {
849
904
  };
850
905
  }
851
906
  };
907
+ var randomHexString = (length) => {
908
+ const chars = "abcdef0123456789";
909
+ let result = "";
910
+ for (let i = 0; i < length; i++) {
911
+ result += chars.charAt(Math.floor(Math.random() * chars.length));
912
+ }
913
+ return result;
914
+ };
915
+ var ConsoleSpan = class {
916
+ constructor(name, parent, context, links, startTime, kind, depth) {
917
+ this.name = name;
918
+ this.parent = parent;
919
+ this.context = context;
920
+ this.startTime = startTime;
921
+ this.kind = kind;
922
+ this.depth = depth;
923
+ this._tag = "Span";
924
+ this.sampled = true;
925
+ this.attributes = /* @__PURE__ */ new Map();
926
+ this.links = [];
927
+ this.traceId = parent._tag === "Some" ? parent.value.traceId : randomHexString(32);
928
+ this.spanId = randomHexString(16);
929
+ this.links = Array.from(links);
930
+ this.status = { _tag: "Started", startTime };
931
+ }
932
+ end(endTime, exit) {
933
+ if (this.status._tag === "Ended")
934
+ return;
935
+ const startTime = this.status.startTime;
936
+ const durationNs = endTime - startTime;
937
+ const durationMs = Number(durationNs) / 1e6;
938
+ const indent = " ".repeat(this.depth);
939
+ const attrs = Object.fromEntries(this.attributes);
940
+ const status = effect.Exit.isSuccess(exit) ? "ok" : "error";
941
+ console.log(
942
+ `${indent}[trace] ${this.name} ${durationMs.toFixed(2)}ms (${status})`,
943
+ Object.keys(attrs).length > 0 ? attrs : ""
944
+ );
945
+ this.status = { _tag: "Ended", startTime, endTime, exit };
946
+ }
947
+ attribute(key, value) {
948
+ this.attributes.set(key, value);
949
+ }
950
+ event(_name, _startTime, _attributes) {
951
+ }
952
+ addLinks(links) {
953
+ this.links.push(...links);
954
+ }
955
+ };
956
+ function getDepth(parent) {
957
+ if (parent._tag === "None")
958
+ return 0;
959
+ const p = parent.value;
960
+ if (p._tag === "ExternalSpan")
961
+ return 0;
962
+ return 1 + getDepth(p.parent);
963
+ }
964
+ var consoleTracer = effect.Tracer.make({
965
+ span: (name, parent, context, links, startTime, kind) => new ConsoleSpan(
966
+ name,
967
+ parent,
968
+ context,
969
+ links,
970
+ startTime,
971
+ kind,
972
+ getDepth(parent)
973
+ ),
974
+ context: (f) => f()
975
+ });
976
+ var consoleTracerLayer = effect.Layer.setTracer(
977
+ consoleTracer
978
+ );
852
979
 
853
980
  Object.defineProperty(exports, 'S', {
854
981
  enumerable: true,
@@ -866,6 +993,8 @@ exports.ExposeAuthError = ExposeAuthError;
866
993
  exports.ExpressEndpoint = ExpressEndpoint;
867
994
  exports.NextEndpoint = NextEndpoint;
868
995
  exports.Sink = Sink;
996
+ exports.consoleTracer = consoleTracer;
997
+ exports.consoleTracerLayer = consoleTracerLayer;
869
998
  exports.formatSSE = formatSSE;
870
999
  exports.isHttpStreamSink = isHttpStreamSink;
871
1000
  exports.toSSEStream = toSSEStream;