@m4trix/core 0.8.0 → 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/README.md CHANGED
@@ -1,5 +1,8 @@
1
1
 
2
- [![CircleCI](https://dl.circleci.com/status-badge/img/gh/Pascal-Lohscheidt/build-ai/tree/main.svg?style=svg)](https://dl.circleci.com/status-badge/redirect/gh/Pascal-Lohscheidt/build-ai/tree/main)
2
+ [![CircleCI](https://dl.circleci.com/status-badge/img/gh/Pascal-Lohscheidt/m4trix/tree/main.svg?style=svg)](https://dl.circleci.com/status-badge/redirect/gh/Pascal-Lohscheidt/m4trix/tree/main)
3
+ [![npm version](https://img.shields.io/npm/v/@m4trix%2Fcore)](https://www.npmjs.com/package/@m4trix/core)
4
+ [![npm downloads](https://img.shields.io/npm/dm/@m4trix%2Fcore)](https://www.npmjs.com/package/@m4trix/core)
5
+ [![license](https://img.shields.io/npm/l/@m4trix%2Fcore)](https://www.npmjs.com/package/@m4trix/core)
3
6
 
4
7
  # @m4trix/core
5
8
 
package/dist/index.cjs CHANGED
@@ -2749,8 +2749,66 @@ var Channel = {
2749
2749
  };
2750
2750
  }
2751
2751
  };
2752
+
2753
+ // src/helper/types/noop.ts
2754
+ var asyncNoop = async () => {
2755
+ };
2756
+
2757
+ // src/matrix/agent-network/stores/inmemory-network-store.ts
2758
+ var createInMemoryNetworkStore = () => {
2759
+ const store = /* @__PURE__ */ new Map();
2760
+ return {
2761
+ storeEvent: (contextId, runId, event) => {
2762
+ let byRun = store.get(contextId);
2763
+ if (!byRun) {
2764
+ byRun = /* @__PURE__ */ new Map();
2765
+ store.set(contextId, byRun);
2766
+ }
2767
+ let events = byRun.get(runId);
2768
+ if (!events) {
2769
+ events = [];
2770
+ byRun.set(runId, events);
2771
+ }
2772
+ events.push(event);
2773
+ },
2774
+ getEvents: (contextId, runId) => {
2775
+ const events = store.get(contextId)?.get(runId);
2776
+ return events ? [...events] : [];
2777
+ },
2778
+ getContextEvents: (contextId) => {
2779
+ const byRun = store.get(contextId);
2780
+ const result = /* @__PURE__ */ new Map();
2781
+ if (byRun) {
2782
+ for (const [runId, events] of byRun) {
2783
+ result.set(runId, [...events]);
2784
+ }
2785
+ }
2786
+ return result;
2787
+ },
2788
+ getFullStore: () => {
2789
+ const result = /* @__PURE__ */ new Map();
2790
+ for (const [contextId, byRun] of store) {
2791
+ const contextMap = /* @__PURE__ */ new Map();
2792
+ for (const [runId, events] of byRun) {
2793
+ contextMap.set(runId, [...events]);
2794
+ }
2795
+ result.set(contextId, contextMap);
2796
+ }
2797
+ return result;
2798
+ },
2799
+ persist: () => asyncNoop(),
2800
+ load: () => asyncNoop()
2801
+ };
2802
+ };
2803
+
2804
+ // src/matrix/agent-network/event-plane.ts
2752
2805
  var DEFAULT_CAPACITY = 16;
2753
- var createEventPlane = (network, capacity = DEFAULT_CAPACITY) => effect.Effect.gen(function* () {
2806
+ var createEventPlane = (options) => effect.Effect.gen(function* () {
2807
+ const {
2808
+ network,
2809
+ capacity = DEFAULT_CAPACITY,
2810
+ store = createInMemoryNetworkStore()
2811
+ } = options;
2754
2812
  const channels = network.getChannels();
2755
2813
  const pubsubs = /* @__PURE__ */ new Map();
2756
2814
  for (const channel of channels.values()) {
@@ -2763,12 +2821,42 @@ var createEventPlane = (network, capacity = DEFAULT_CAPACITY) => effect.Effect.g
2763
2821
  throw new Error(`Channel not found: ${channel}`);
2764
2822
  return p;
2765
2823
  };
2766
- const publish = (channel, envelope) => effect.PubSub.publish(getPubsub(channel), envelope);
2767
- const publishToChannels = (targetChannels, envelope) => effect.Effect.all(
2768
- targetChannels.map((c) => publish(c.name, envelope)),
2769
- { concurrency: "unbounded" }
2770
- ).pipe(effect.Effect.map((results) => results.every(Boolean)));
2824
+ const recordEvent = (envelope) => {
2825
+ const { contextId, runId } = envelope.meta;
2826
+ store.storeEvent(contextId, runId, envelope);
2827
+ };
2828
+ const publishToPubSub = (channel, envelope) => effect.PubSub.publish(getPubsub(channel), envelope);
2829
+ const publish = (channel, envelope) => effect.Effect.sync(() => recordEvent(envelope)).pipe(
2830
+ effect.Effect.flatMap(() => publishToPubSub(channel, envelope))
2831
+ );
2832
+ const publishToChannels = (targetChannels, envelope) => effect.Effect.sync(() => recordEvent(envelope)).pipe(
2833
+ effect.Effect.flatMap(
2834
+ () => effect.Effect.all(
2835
+ targetChannels.map((c) => publishToPubSub(c.name, envelope)),
2836
+ { concurrency: "unbounded" }
2837
+ )
2838
+ ),
2839
+ effect.Effect.map((results) => results.every(Boolean))
2840
+ );
2771
2841
  const subscribe = (channel) => effect.PubSub.subscribe(getPubsub(channel));
2842
+ const getRunEvents = (runId, contextId) => {
2843
+ return store.getEvents(contextId, runId).slice();
2844
+ };
2845
+ const getContextEvents = (contextId) => {
2846
+ const byRun = store.getContextEvents(contextId);
2847
+ const map = /* @__PURE__ */ new Map();
2848
+ const all = [];
2849
+ for (const [runId, events] of byRun) {
2850
+ const readonlyEvents = events.slice();
2851
+ map.set(runId, readonlyEvents);
2852
+ all.push(...readonlyEvents);
2853
+ }
2854
+ return {
2855
+ all,
2856
+ byRun: (runId) => map.get(runId) ?? [],
2857
+ map
2858
+ };
2859
+ };
2772
2860
  const shutdown = effect.Effect.all([...pubsubs.values()].map(effect.PubSub.shutdown), {
2773
2861
  concurrency: "unbounded"
2774
2862
  }).pipe(effect.Effect.asVoid);
@@ -2776,6 +2864,8 @@ var createEventPlane = (network, capacity = DEFAULT_CAPACITY) => effect.Effect.g
2776
2864
  publish,
2777
2865
  publishToChannels,
2778
2866
  subscribe,
2867
+ getRunEvents,
2868
+ getContextEvents,
2779
2869
  shutdown
2780
2870
  };
2781
2871
  });
@@ -2786,6 +2876,11 @@ var runSubscriber = (agent, publishesTo, dequeue, plane, emitQueue) => effect.Ef
2786
2876
  if (listensTo.length > 0 && !listensTo.includes(envelope.name)) {
2787
2877
  return;
2788
2878
  }
2879
+ const runEvents = plane.getRunEvents(
2880
+ envelope.meta.runId,
2881
+ envelope.meta.contextId
2882
+ );
2883
+ const contextEvents = plane.getContextEvents(envelope.meta.contextId);
2789
2884
  yield* effect.Effect.tryPromise({
2790
2885
  try: () => agent.invoke({
2791
2886
  triggerEvent: envelope,
@@ -2808,7 +2903,9 @@ var runSubscriber = (agent, publishesTo, dequeue, plane, emitQueue) => effect.Ef
2808
2903
  plane.publishToChannels(publishesTo, fullEnvelope)
2809
2904
  );
2810
2905
  }
2811
- }
2906
+ },
2907
+ runEvents,
2908
+ contextEvents
2812
2909
  }),
2813
2910
  catch: (e) => e
2814
2911
  });
@@ -2902,7 +2999,15 @@ function streamFromDequeue(take, signal, eventFilter) {
2902
2999
  };
2903
3000
  }
2904
3001
  function expose(network, options) {
2905
- const { auth, select, plane: providedPlane, onRequest, startEventName = "request" } = options;
3002
+ const {
3003
+ auth,
3004
+ select,
3005
+ plane: providedPlane,
3006
+ onRequest,
3007
+ triggerEvents
3008
+ } = options;
3009
+ const triggerEventDef = triggerEvents?.[0];
3010
+ const triggerEventName = triggerEventDef?.name ?? "request";
2906
3011
  const channels = resolveChannels(network, select);
2907
3012
  const eventFilter = select?.events;
2908
3013
  const mainChannel = network.getMainChannel();
@@ -2913,7 +3018,7 @@ function expose(network, options) {
2913
3018
  const payload = await extractPayload(req);
2914
3019
  const signal = req.request?.signal;
2915
3020
  const program = effect.Effect.gen(function* () {
2916
- const plane = providedPlane ?? (yield* createEventPlane(network));
3021
+ const plane = providedPlane ?? (yield* createEventPlane({ network }));
2917
3022
  if (!providedPlane) {
2918
3023
  const emitQueue = yield* effect.Queue.unbounded();
2919
3024
  yield* effect.Effect.fork(
@@ -2929,25 +3034,46 @@ function expose(network, options) {
2929
3034
  yield* effect.Effect.sleep("10 millis");
2930
3035
  }
2931
3036
  const targetChannel = mainChannel?.name ?? channels[0];
2932
- const emitStartEvent = (p) => {
2933
- const pld = p ?? payload;
3037
+ let runId = req.runId ?? crypto.randomUUID();
3038
+ let contextId = req.contextId ?? crypto.randomUUID();
3039
+ const setRunId = (id) => {
3040
+ runId = id;
3041
+ };
3042
+ const setContextId = (id) => {
3043
+ contextId = id;
3044
+ };
3045
+ const emitStartEvent = (opts) => {
3046
+ const meta = {
3047
+ runId: opts.runId,
3048
+ contextId: opts.contextId
3049
+ };
2934
3050
  const envelope = {
2935
- name: startEventName,
2936
- meta: { runId: crypto.randomUUID() },
2937
- payload: pld
3051
+ name: opts.event.name,
3052
+ meta,
3053
+ payload: opts.event.payload
2938
3054
  };
2939
- effect.Effect.runPromise(plane.publish(targetChannel, envelope)).catch(() => {
2940
- });
3055
+ effect.Effect.runPromise(plane.publish(targetChannel, envelope)).catch(
3056
+ () => {
3057
+ }
3058
+ );
2941
3059
  };
2942
3060
  const dequeue = yield* plane.subscribe(channels[0]);
2943
3061
  if (onRequest) {
2944
3062
  yield* effect.Effect.tryPromise(
2945
- () => Promise.resolve(onRequest({ emitStartEvent, req, payload }))
3063
+ () => Promise.resolve(
3064
+ onRequest({
3065
+ setRunId,
3066
+ setContextId,
3067
+ emitStartEvent,
3068
+ req,
3069
+ payload
3070
+ })
3071
+ )
2946
3072
  );
2947
3073
  } else if (!providedPlane) {
2948
3074
  const envelope = {
2949
- name: startEventName,
2950
- meta: { runId: crypto.randomUUID() },
3075
+ name: triggerEventName,
3076
+ meta: { runId, contextId },
2951
3077
  payload
2952
3078
  };
2953
3079
  yield* plane.publish(targetChannel, envelope);
@@ -3086,7 +3212,7 @@ var AgentNetwork = class _AgentNetwork {
3086
3212
  *
3087
3213
  * @example
3088
3214
  * const api = network.expose({ protocol: "sse", auth, select });
3089
- * export const GET = NextEndpoint.from(api).handler();
3215
+ * export const GET = NextEndpoint.from(api, { requestToContextId, requestToRunId }).handler();
3090
3216
  */
3091
3217
  expose(options) {
3092
3218
  return expose(this, options);
@@ -3104,7 +3230,7 @@ var AgentNetwork = class _AgentNetwork {
3104
3230
  }
3105
3231
  runScoped(network, capacity) {
3106
3232
  return effect.Effect.gen(function* () {
3107
- const plane = yield* createEventPlane(network, capacity);
3233
+ const plane = yield* createEventPlane({ network, capacity });
3108
3234
  yield* effect.Effect.fork(run(network, plane));
3109
3235
  return plane;
3110
3236
  });
@@ -3112,7 +3238,7 @@ var AgentNetwork = class _AgentNetwork {
3112
3238
  };
3113
3239
  var EventMetaSchema = effect.Schema.Struct({
3114
3240
  runId: effect.Schema.String,
3115
- contextId: effect.Schema.optional(effect.Schema.String),
3241
+ contextId: effect.Schema.String,
3116
3242
  correlationId: effect.Schema.optional(effect.Schema.String),
3117
3243
  causationId: effect.Schema.optional(effect.Schema.String),
3118
3244
  ts: effect.Schema.optional(effect.Schema.Number)
@@ -3135,9 +3261,7 @@ var AgentNetworkEvent = {
3135
3261
  const makeBound = (meta, payload2) => effect.Effect.runSync(
3136
3262
  decodeEnvelope({ name, meta, payload: payload2 })
3137
3263
  );
3138
- const makeEffect = (payload2) => decodePayload(payload2).pipe(
3139
- effect.Effect.map((p) => ({ name, payload: p }))
3140
- );
3264
+ const makeEffect = (payload2) => decodePayload(payload2).pipe(effect.Effect.map((p) => ({ name, payload: p })));
3141
3265
  const makeBoundEffect = (meta, payload2) => decodeEnvelope({ name, meta, payload: payload2 });
3142
3266
  const is = effect.Schema.is(envelopeSchema);
3143
3267
  return {
@@ -3170,13 +3294,19 @@ var Agent = class {
3170
3294
  return __privateGet(this, _listensTo);
3171
3295
  }
3172
3296
  async invoke(options) {
3173
- const { triggerEvent, emit } = options ?? {};
3297
+ const { triggerEvent, emit, runEvents, contextEvents } = options ?? {};
3174
3298
  const emitFn = emit ?? ((_event) => {
3175
3299
  });
3176
3300
  await __privateGet(this, _logic).call(this, {
3177
3301
  params: __privateGet(this, _params),
3178
3302
  triggerEvent: triggerEvent ?? void 0,
3179
- emit: emitFn
3303
+ emit: emitFn,
3304
+ runEvents: runEvents ?? [],
3305
+ contextEvents: contextEvents ?? {
3306
+ all: [],
3307
+ byRun: () => [],
3308
+ map: /* @__PURE__ */ new Map()
3309
+ }
3180
3310
  });
3181
3311
  }
3182
3312
  getId() {
@@ -3289,14 +3419,19 @@ function toSSEStream(source, signal) {
3289
3419
 
3290
3420
  // src/matrix/io/adapters/next-endpoint.ts
3291
3421
  var NextEndpoint = {
3292
- from(api) {
3422
+ from(api, options) {
3293
3423
  if (api.protocol !== "sse") {
3294
3424
  throw new Error(`NextEndpoint: unsupported protocol "${api.protocol}"`);
3295
3425
  }
3426
+ const { requestToContextId, requestToRunId } = options;
3296
3427
  return {
3297
3428
  handler() {
3298
3429
  return async (request) => {
3299
- const req = { request };
3430
+ const req = {
3431
+ request,
3432
+ contextId: requestToContextId(request),
3433
+ runId: requestToRunId(request)
3434
+ };
3300
3435
  try {
3301
3436
  const encoder = new TextEncoder();
3302
3437
  const { readable, writable } = new TransformStream();
@@ -3341,12 +3476,13 @@ var NextEndpoint = {
3341
3476
 
3342
3477
  // src/matrix/io/adapters/express-endpoint.ts
3343
3478
  var ExpressEndpoint = {
3344
- from(api) {
3479
+ from(api, options) {
3345
3480
  if (api.protocol !== "sse") {
3346
3481
  throw new Error(
3347
3482
  `ExpressEndpoint: unsupported protocol "${api.protocol}"`
3348
3483
  );
3349
3484
  }
3485
+ const { requestToContextId, requestToRunId } = options;
3350
3486
  return {
3351
3487
  handler() {
3352
3488
  return async (req, res) => {
@@ -3355,7 +3491,9 @@ var ExpressEndpoint = {
3355
3491
  const exposeReq = {
3356
3492
  request: { signal: controller.signal },
3357
3493
  req,
3358
- res
3494
+ res,
3495
+ contextId: requestToContextId(req),
3496
+ runId: requestToRunId(req)
3359
3497
  };
3360
3498
  try {
3361
3499
  const encoder = new TextEncoder();