@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.d.ts CHANGED
@@ -3,7 +3,7 @@ export { AiCursor } from './ui/index.js';
3
3
  export { HttpStreamOptions, MessageStream, Pump, Source, StreamChunk, StreamTransformer, ensureFullWords, httpStreamResponse } from './stream/index.js';
4
4
  export { BaseMessage, Message, Role, SocketEventName, SocketIoFactory, TextMessage, VoiceMessage } from './api/index.js';
5
5
  export { FormatType, MessageFilterType, TransformMessages } from './helper/index.js';
6
- export { Agent, AgentBinding, AgentFactory, AgentNetwork, AgentNetworkEvent, AgentNetworkEventDef, AnyAgent, AuthResult, Channel, ChannelDef, ChannelName, ConfiguredChannel, EmitPayload, EventEnvelope, EventMeta, EventMetaSchema, EventPlane, ExposeAuthError, ExposeOptions, ExposeRequest, ExposeSelect, ExposedAPI, ExposedStream, ExpressEndpoint, ExpressHandler, ExpressRequest, ExpressResponse, NextEndpoint, NextGetHandler, OnRequestContext, SetupContext, Sink, SinkDef, SpawnCallbackContext, SpawnFn, SpawnerBuilder, StreamFactory, formatSSE, isHttpStreamSink, toSSEStream } from './matrix/index.js';
6
+ export { Agent, AgentBinding, AgentFactory, AgentNetwork, AgentNetworkEvent, AgentNetworkEventDef, AnyAgent, AuthResult, Channel, ChannelDef, ChannelName, ConfiguredChannel, ContextEvents, EmitPayload, EnvelopeLike, EventEnvelope, EventMeta, EventMetaSchema, EventPlane, ExposeAuthError, ExposeOptions, ExposeRequest, ExposeSelect, ExposedAPI, ExposedStream, ExpressEndpoint, ExpressEndpointOptions, ExpressHandler, ExpressRequest, ExpressResponse, NextEndpoint, NextEndpointOptions, NextGetHandler, OnRequestContext, RunEvents, SetupContext, Sink, SinkDef, SpawnCallbackContext, SpawnFn, SpawnerBuilder, StreamFactory, UnboundEvent, formatSSE, isHttpStreamSink, toSSEStream } from './matrix/index.js';
7
7
  export { Schema as S } from 'effect';
8
8
  import 'socket.io';
9
9
  import '@langchain/core/messages';
package/dist/index.js CHANGED
@@ -2748,8 +2748,66 @@ var Channel = {
2748
2748
  };
2749
2749
  }
2750
2750
  };
2751
+
2752
+ // src/helper/types/noop.ts
2753
+ var asyncNoop = async () => {
2754
+ };
2755
+
2756
+ // src/matrix/agent-network/stores/inmemory-network-store.ts
2757
+ var createInMemoryNetworkStore = () => {
2758
+ const store = /* @__PURE__ */ new Map();
2759
+ return {
2760
+ storeEvent: (contextId, runId, event) => {
2761
+ let byRun = store.get(contextId);
2762
+ if (!byRun) {
2763
+ byRun = /* @__PURE__ */ new Map();
2764
+ store.set(contextId, byRun);
2765
+ }
2766
+ let events = byRun.get(runId);
2767
+ if (!events) {
2768
+ events = [];
2769
+ byRun.set(runId, events);
2770
+ }
2771
+ events.push(event);
2772
+ },
2773
+ getEvents: (contextId, runId) => {
2774
+ const events = store.get(contextId)?.get(runId);
2775
+ return events ? [...events] : [];
2776
+ },
2777
+ getContextEvents: (contextId) => {
2778
+ const byRun = store.get(contextId);
2779
+ const result = /* @__PURE__ */ new Map();
2780
+ if (byRun) {
2781
+ for (const [runId, events] of byRun) {
2782
+ result.set(runId, [...events]);
2783
+ }
2784
+ }
2785
+ return result;
2786
+ },
2787
+ getFullStore: () => {
2788
+ const result = /* @__PURE__ */ new Map();
2789
+ for (const [contextId, byRun] of store) {
2790
+ const contextMap = /* @__PURE__ */ new Map();
2791
+ for (const [runId, events] of byRun) {
2792
+ contextMap.set(runId, [...events]);
2793
+ }
2794
+ result.set(contextId, contextMap);
2795
+ }
2796
+ return result;
2797
+ },
2798
+ persist: () => asyncNoop(),
2799
+ load: () => asyncNoop()
2800
+ };
2801
+ };
2802
+
2803
+ // src/matrix/agent-network/event-plane.ts
2751
2804
  var DEFAULT_CAPACITY = 16;
2752
- var createEventPlane = (network, capacity = DEFAULT_CAPACITY) => Effect.gen(function* () {
2805
+ var createEventPlane = (options) => Effect.gen(function* () {
2806
+ const {
2807
+ network,
2808
+ capacity = DEFAULT_CAPACITY,
2809
+ store = createInMemoryNetworkStore()
2810
+ } = options;
2753
2811
  const channels = network.getChannels();
2754
2812
  const pubsubs = /* @__PURE__ */ new Map();
2755
2813
  for (const channel of channels.values()) {
@@ -2762,12 +2820,42 @@ var createEventPlane = (network, capacity = DEFAULT_CAPACITY) => Effect.gen(func
2762
2820
  throw new Error(`Channel not found: ${channel}`);
2763
2821
  return p;
2764
2822
  };
2765
- const publish = (channel, envelope) => PubSub.publish(getPubsub(channel), envelope);
2766
- const publishToChannels = (targetChannels, envelope) => Effect.all(
2767
- targetChannels.map((c) => publish(c.name, envelope)),
2768
- { concurrency: "unbounded" }
2769
- ).pipe(Effect.map((results) => results.every(Boolean)));
2823
+ const recordEvent = (envelope) => {
2824
+ const { contextId, runId } = envelope.meta;
2825
+ store.storeEvent(contextId, runId, envelope);
2826
+ };
2827
+ const publishToPubSub = (channel, envelope) => PubSub.publish(getPubsub(channel), envelope);
2828
+ const publish = (channel, envelope) => Effect.sync(() => recordEvent(envelope)).pipe(
2829
+ Effect.flatMap(() => publishToPubSub(channel, envelope))
2830
+ );
2831
+ const publishToChannels = (targetChannels, envelope) => Effect.sync(() => recordEvent(envelope)).pipe(
2832
+ Effect.flatMap(
2833
+ () => Effect.all(
2834
+ targetChannels.map((c) => publishToPubSub(c.name, envelope)),
2835
+ { concurrency: "unbounded" }
2836
+ )
2837
+ ),
2838
+ Effect.map((results) => results.every(Boolean))
2839
+ );
2770
2840
  const subscribe = (channel) => PubSub.subscribe(getPubsub(channel));
2841
+ const getRunEvents = (runId, contextId) => {
2842
+ return store.getEvents(contextId, runId).slice();
2843
+ };
2844
+ const getContextEvents = (contextId) => {
2845
+ const byRun = store.getContextEvents(contextId);
2846
+ const map = /* @__PURE__ */ new Map();
2847
+ const all = [];
2848
+ for (const [runId, events] of byRun) {
2849
+ const readonlyEvents = events.slice();
2850
+ map.set(runId, readonlyEvents);
2851
+ all.push(...readonlyEvents);
2852
+ }
2853
+ return {
2854
+ all,
2855
+ byRun: (runId) => map.get(runId) ?? [],
2856
+ map
2857
+ };
2858
+ };
2771
2859
  const shutdown = Effect.all([...pubsubs.values()].map(PubSub.shutdown), {
2772
2860
  concurrency: "unbounded"
2773
2861
  }).pipe(Effect.asVoid);
@@ -2775,6 +2863,8 @@ var createEventPlane = (network, capacity = DEFAULT_CAPACITY) => Effect.gen(func
2775
2863
  publish,
2776
2864
  publishToChannels,
2777
2865
  subscribe,
2866
+ getRunEvents,
2867
+ getContextEvents,
2778
2868
  shutdown
2779
2869
  };
2780
2870
  });
@@ -2785,6 +2875,11 @@ var runSubscriber = (agent, publishesTo, dequeue, plane, emitQueue) => Effect.ge
2785
2875
  if (listensTo.length > 0 && !listensTo.includes(envelope.name)) {
2786
2876
  return;
2787
2877
  }
2878
+ const runEvents = plane.getRunEvents(
2879
+ envelope.meta.runId,
2880
+ envelope.meta.contextId
2881
+ );
2882
+ const contextEvents = plane.getContextEvents(envelope.meta.contextId);
2788
2883
  yield* Effect.tryPromise({
2789
2884
  try: () => agent.invoke({
2790
2885
  triggerEvent: envelope,
@@ -2807,7 +2902,9 @@ var runSubscriber = (agent, publishesTo, dequeue, plane, emitQueue) => Effect.ge
2807
2902
  plane.publishToChannels(publishesTo, fullEnvelope)
2808
2903
  );
2809
2904
  }
2810
- }
2905
+ },
2906
+ runEvents,
2907
+ contextEvents
2811
2908
  }),
2812
2909
  catch: (e) => e
2813
2910
  });
@@ -2901,7 +2998,15 @@ function streamFromDequeue(take, signal, eventFilter) {
2901
2998
  };
2902
2999
  }
2903
3000
  function expose(network, options) {
2904
- const { auth, select, plane: providedPlane, onRequest, startEventName = "request" } = options;
3001
+ const {
3002
+ auth,
3003
+ select,
3004
+ plane: providedPlane,
3005
+ onRequest,
3006
+ triggerEvents
3007
+ } = options;
3008
+ const triggerEventDef = triggerEvents?.[0];
3009
+ const triggerEventName = triggerEventDef?.name ?? "request";
2905
3010
  const channels = resolveChannels(network, select);
2906
3011
  const eventFilter = select?.events;
2907
3012
  const mainChannel = network.getMainChannel();
@@ -2912,7 +3017,7 @@ function expose(network, options) {
2912
3017
  const payload = await extractPayload(req);
2913
3018
  const signal = req.request?.signal;
2914
3019
  const program = Effect.gen(function* () {
2915
- const plane = providedPlane ?? (yield* createEventPlane(network));
3020
+ const plane = providedPlane ?? (yield* createEventPlane({ network }));
2916
3021
  if (!providedPlane) {
2917
3022
  const emitQueue = yield* Queue.unbounded();
2918
3023
  yield* Effect.fork(
@@ -2928,25 +3033,46 @@ function expose(network, options) {
2928
3033
  yield* Effect.sleep("10 millis");
2929
3034
  }
2930
3035
  const targetChannel = mainChannel?.name ?? channels[0];
2931
- const emitStartEvent = (p) => {
2932
- const pld = p ?? payload;
3036
+ let runId = req.runId ?? crypto.randomUUID();
3037
+ let contextId = req.contextId ?? crypto.randomUUID();
3038
+ const setRunId = (id) => {
3039
+ runId = id;
3040
+ };
3041
+ const setContextId = (id) => {
3042
+ contextId = id;
3043
+ };
3044
+ const emitStartEvent = (opts) => {
3045
+ const meta = {
3046
+ runId: opts.runId,
3047
+ contextId: opts.contextId
3048
+ };
2933
3049
  const envelope = {
2934
- name: startEventName,
2935
- meta: { runId: crypto.randomUUID() },
2936
- payload: pld
3050
+ name: opts.event.name,
3051
+ meta,
3052
+ payload: opts.event.payload
2937
3053
  };
2938
- Effect.runPromise(plane.publish(targetChannel, envelope)).catch(() => {
2939
- });
3054
+ Effect.runPromise(plane.publish(targetChannel, envelope)).catch(
3055
+ () => {
3056
+ }
3057
+ );
2940
3058
  };
2941
3059
  const dequeue = yield* plane.subscribe(channels[0]);
2942
3060
  if (onRequest) {
2943
3061
  yield* Effect.tryPromise(
2944
- () => Promise.resolve(onRequest({ emitStartEvent, req, payload }))
3062
+ () => Promise.resolve(
3063
+ onRequest({
3064
+ setRunId,
3065
+ setContextId,
3066
+ emitStartEvent,
3067
+ req,
3068
+ payload
3069
+ })
3070
+ )
2945
3071
  );
2946
3072
  } else if (!providedPlane) {
2947
3073
  const envelope = {
2948
- name: startEventName,
2949
- meta: { runId: crypto.randomUUID() },
3074
+ name: triggerEventName,
3075
+ meta: { runId, contextId },
2950
3076
  payload
2951
3077
  };
2952
3078
  yield* plane.publish(targetChannel, envelope);
@@ -3085,7 +3211,7 @@ var AgentNetwork = class _AgentNetwork {
3085
3211
  *
3086
3212
  * @example
3087
3213
  * const api = network.expose({ protocol: "sse", auth, select });
3088
- * export const GET = NextEndpoint.from(api).handler();
3214
+ * export const GET = NextEndpoint.from(api, { requestToContextId, requestToRunId }).handler();
3089
3215
  */
3090
3216
  expose(options) {
3091
3217
  return expose(this, options);
@@ -3103,7 +3229,7 @@ var AgentNetwork = class _AgentNetwork {
3103
3229
  }
3104
3230
  runScoped(network, capacity) {
3105
3231
  return Effect.gen(function* () {
3106
- const plane = yield* createEventPlane(network, capacity);
3232
+ const plane = yield* createEventPlane({ network, capacity });
3107
3233
  yield* Effect.fork(run(network, plane));
3108
3234
  return plane;
3109
3235
  });
@@ -3111,7 +3237,7 @@ var AgentNetwork = class _AgentNetwork {
3111
3237
  };
3112
3238
  var EventMetaSchema = Schema.Struct({
3113
3239
  runId: Schema.String,
3114
- contextId: Schema.optional(Schema.String),
3240
+ contextId: Schema.String,
3115
3241
  correlationId: Schema.optional(Schema.String),
3116
3242
  causationId: Schema.optional(Schema.String),
3117
3243
  ts: Schema.optional(Schema.Number)
@@ -3134,9 +3260,7 @@ var AgentNetworkEvent = {
3134
3260
  const makeBound = (meta, payload2) => Effect.runSync(
3135
3261
  decodeEnvelope({ name, meta, payload: payload2 })
3136
3262
  );
3137
- const makeEffect = (payload2) => decodePayload(payload2).pipe(
3138
- Effect.map((p) => ({ name, payload: p }))
3139
- );
3263
+ const makeEffect = (payload2) => decodePayload(payload2).pipe(Effect.map((p) => ({ name, payload: p })));
3140
3264
  const makeBoundEffect = (meta, payload2) => decodeEnvelope({ name, meta, payload: payload2 });
3141
3265
  const is = Schema.is(envelopeSchema);
3142
3266
  return {
@@ -3169,13 +3293,19 @@ var Agent = class {
3169
3293
  return __privateGet(this, _listensTo);
3170
3294
  }
3171
3295
  async invoke(options) {
3172
- const { triggerEvent, emit } = options ?? {};
3296
+ const { triggerEvent, emit, runEvents, contextEvents } = options ?? {};
3173
3297
  const emitFn = emit ?? ((_event) => {
3174
3298
  });
3175
3299
  await __privateGet(this, _logic).call(this, {
3176
3300
  params: __privateGet(this, _params),
3177
3301
  triggerEvent: triggerEvent ?? void 0,
3178
- emit: emitFn
3302
+ emit: emitFn,
3303
+ runEvents: runEvents ?? [],
3304
+ contextEvents: contextEvents ?? {
3305
+ all: [],
3306
+ byRun: () => [],
3307
+ map: /* @__PURE__ */ new Map()
3308
+ }
3179
3309
  });
3180
3310
  }
3181
3311
  getId() {
@@ -3288,14 +3418,19 @@ function toSSEStream(source, signal) {
3288
3418
 
3289
3419
  // src/matrix/io/adapters/next-endpoint.ts
3290
3420
  var NextEndpoint = {
3291
- from(api) {
3421
+ from(api, options) {
3292
3422
  if (api.protocol !== "sse") {
3293
3423
  throw new Error(`NextEndpoint: unsupported protocol "${api.protocol}"`);
3294
3424
  }
3425
+ const { requestToContextId, requestToRunId } = options;
3295
3426
  return {
3296
3427
  handler() {
3297
3428
  return async (request) => {
3298
- const req = { request };
3429
+ const req = {
3430
+ request,
3431
+ contextId: requestToContextId(request),
3432
+ runId: requestToRunId(request)
3433
+ };
3299
3434
  try {
3300
3435
  const encoder = new TextEncoder();
3301
3436
  const { readable, writable } = new TransformStream();
@@ -3340,12 +3475,13 @@ var NextEndpoint = {
3340
3475
 
3341
3476
  // src/matrix/io/adapters/express-endpoint.ts
3342
3477
  var ExpressEndpoint = {
3343
- from(api) {
3478
+ from(api, options) {
3344
3479
  if (api.protocol !== "sse") {
3345
3480
  throw new Error(
3346
3481
  `ExpressEndpoint: unsupported protocol "${api.protocol}"`
3347
3482
  );
3348
3483
  }
3484
+ const { requestToContextId, requestToRunId } = options;
3349
3485
  return {
3350
3486
  handler() {
3351
3487
  return async (req, res) => {
@@ -3354,7 +3490,9 @@ var ExpressEndpoint = {
3354
3490
  const exposeReq = {
3355
3491
  request: { signal: controller.signal },
3356
3492
  req,
3357
- res
3493
+ res,
3494
+ contextId: requestToContextId(req),
3495
+ runId: requestToRunId(req)
3358
3496
  };
3359
3497
  try {
3360
3498
  const encoder = new TextEncoder();