@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.d.ts
CHANGED
|
@@ -2,31 +2,30 @@ import { Schema, Effect, Brand, Queue, Scope } from 'effect';
|
|
|
2
2
|
export { Schema as S } from 'effect';
|
|
3
3
|
import { ParseError } from 'effect/ParseResult';
|
|
4
4
|
|
|
5
|
-
type LogicFn$1<TParams, TTriggerEvent, TEmitEvent> = (ctx: {
|
|
6
|
-
params: TParams;
|
|
7
|
-
triggerEvent: TTriggerEvent;
|
|
8
|
-
emit: (event: TEmitEvent) => void;
|
|
9
|
-
}) => Promise<void>;
|
|
10
|
-
declare class Agent<TParams, TTriggerEvent = never, TEmitEvent = never> {
|
|
11
|
-
#private;
|
|
12
|
-
constructor(logic: LogicFn$1<TParams, TTriggerEvent, TEmitEvent>, params: TParams, listensTo?: readonly string[]);
|
|
13
|
-
getListensTo(): readonly string[];
|
|
14
|
-
invoke(options?: {
|
|
15
|
-
triggerEvent?: TTriggerEvent;
|
|
16
|
-
emit?: (event: TEmitEvent) => void;
|
|
17
|
-
}): Promise<void>;
|
|
18
|
-
getId(): string;
|
|
19
|
-
}
|
|
20
|
-
|
|
21
5
|
/** Standard meta carried by every event */
|
|
22
6
|
declare const EventMetaSchema: Schema.Struct<{
|
|
23
7
|
runId: typeof Schema.String;
|
|
24
|
-
contextId:
|
|
8
|
+
contextId: typeof Schema.String;
|
|
25
9
|
correlationId: Schema.optional<typeof Schema.String>;
|
|
26
10
|
causationId: Schema.optional<typeof Schema.String>;
|
|
27
11
|
ts: Schema.optional<typeof Schema.Number>;
|
|
28
12
|
}>;
|
|
29
13
|
type EventMeta = Schema.Schema.Type<typeof EventMetaSchema>;
|
|
14
|
+
/** Envelope-like shape for events (avoids circular dep with event-plane) */
|
|
15
|
+
type EnvelopeLike = {
|
|
16
|
+
name: string;
|
|
17
|
+
meta: EventMeta;
|
|
18
|
+
payload: unknown;
|
|
19
|
+
};
|
|
20
|
+
type RunEvents = readonly EnvelopeLike[];
|
|
21
|
+
type ContextEvents = {
|
|
22
|
+
/** All events in the context across all runs */
|
|
23
|
+
readonly all: readonly EnvelopeLike[];
|
|
24
|
+
/** Get events for a specific run */
|
|
25
|
+
byRun(runId: string): readonly EnvelopeLike[];
|
|
26
|
+
/** Map of runId -> events */
|
|
27
|
+
readonly map: ReadonlyMap<string, readonly EnvelopeLike[]>;
|
|
28
|
+
};
|
|
30
29
|
|
|
31
30
|
type AgentNetworkEventDef<EventName extends string, PayloadSchema extends Schema.Schema.Any> = {
|
|
32
31
|
readonly _tag: 'AgentNetworkEventDef';
|
|
@@ -85,6 +84,26 @@ declare const AgentNetworkEvent: {
|
|
|
85
84
|
of<const EventName extends string, PS extends Schema.Schema.Any>(name: EventName, payload: PS): AgentNetworkEventDef<EventName, PS>;
|
|
86
85
|
};
|
|
87
86
|
|
|
87
|
+
type LogicFn$1<TParams, TTriggerEvent, TEmitEvent> = (ctx: {
|
|
88
|
+
params: TParams;
|
|
89
|
+
triggerEvent: TTriggerEvent;
|
|
90
|
+
emit: (event: TEmitEvent) => void;
|
|
91
|
+
runEvents: RunEvents;
|
|
92
|
+
contextEvents: ContextEvents;
|
|
93
|
+
}) => Promise<void>;
|
|
94
|
+
declare class Agent<TParams, TTriggerEvent = never, TEmitEvent = never> {
|
|
95
|
+
#private;
|
|
96
|
+
constructor(logic: LogicFn$1<TParams, TTriggerEvent, TEmitEvent>, params: TParams, listensTo?: readonly string[]);
|
|
97
|
+
getListensTo(): readonly string[];
|
|
98
|
+
invoke(options?: {
|
|
99
|
+
triggerEvent?: TTriggerEvent;
|
|
100
|
+
emit?: (event: TEmitEvent) => void;
|
|
101
|
+
runEvents?: RunEvents;
|
|
102
|
+
contextEvents?: ContextEvents;
|
|
103
|
+
}): Promise<void>;
|
|
104
|
+
getId(): string;
|
|
105
|
+
}
|
|
106
|
+
|
|
88
107
|
type BaseSchemaDefintion = Schema.Schema.Any;
|
|
89
108
|
|
|
90
109
|
type EventDef$2 = AgentNetworkEventDef<string, Schema.Schema.Any>;
|
|
@@ -104,6 +123,8 @@ type LogicFn<TParams, TTriggerEvent, TEmitEvent> = (ctx: {
|
|
|
104
123
|
params: TParams;
|
|
105
124
|
triggerEvent: TTriggerEvent;
|
|
106
125
|
emit: (event: TEmitEvent) => void;
|
|
126
|
+
runEvents: RunEvents;
|
|
127
|
+
contextEvents: ContextEvents;
|
|
107
128
|
}) => Promise<void>;
|
|
108
129
|
declare class AgentFactory<TParams = unknown, TListensTo extends EventDef$2 = never, TEmits extends EventDef$2 = never> {
|
|
109
130
|
private _listensTo;
|
|
@@ -184,6 +205,8 @@ type EventPlane = {
|
|
|
184
205
|
readonly publish: (channel: ChannelName, envelope: Envelope) => Effect.Effect<boolean>;
|
|
185
206
|
readonly publishToChannels: (channels: readonly ConfiguredChannel[], envelope: Envelope) => Effect.Effect<boolean>;
|
|
186
207
|
readonly subscribe: (channel: ChannelName) => Effect.Effect<Queue.Dequeue<Envelope>, never, Scope.Scope>;
|
|
208
|
+
readonly getRunEvents: (runId: string, contextId: string) => RunEvents;
|
|
209
|
+
readonly getContextEvents: (contextId: string) => ContextEvents;
|
|
187
210
|
readonly shutdown: Effect.Effect<void>;
|
|
188
211
|
};
|
|
189
212
|
|
|
@@ -195,6 +218,10 @@ type ExposeRequest = {
|
|
|
195
218
|
req?: unknown;
|
|
196
219
|
/** Express res (when using ExpressEndpoint) */
|
|
197
220
|
res?: unknown;
|
|
221
|
+
/** Set by adapters via requestToContextId. Correlation ID between runs. */
|
|
222
|
+
contextId?: string;
|
|
223
|
+
/** Set by adapters via requestToRunId. Unique per run. */
|
|
224
|
+
runId?: string;
|
|
198
225
|
};
|
|
199
226
|
/** Auth result: allow or deny with optional status */
|
|
200
227
|
type AuthResult = {
|
|
@@ -211,10 +238,21 @@ type ExposeSelect = {
|
|
|
211
238
|
/** Event names to filter. Empty = all events. */
|
|
212
239
|
events?: string[];
|
|
213
240
|
};
|
|
241
|
+
/** Unbound event shape (name + payload, no meta) - use eventDef.make(payload) to create */
|
|
242
|
+
type UnboundEvent = {
|
|
243
|
+
name: string;
|
|
244
|
+
payload: unknown;
|
|
245
|
+
};
|
|
214
246
|
/** Context passed to onRequest callback */
|
|
215
247
|
type OnRequestContext<T = unknown> = {
|
|
216
|
-
|
|
217
|
-
|
|
248
|
+
setRunId: (id: string) => void;
|
|
249
|
+
setContextId: (id: string) => void;
|
|
250
|
+
/** Emit the start event. Pass { contextId, runId, event } where event is the unbound version of one of triggerEvents (e.g. MessageEvent.make(payload)). */
|
|
251
|
+
emitStartEvent: (opts: {
|
|
252
|
+
contextId: string;
|
|
253
|
+
runId: string;
|
|
254
|
+
event: UnboundEvent;
|
|
255
|
+
}) => void;
|
|
218
256
|
/** The raw request context */
|
|
219
257
|
req: ExposeRequest;
|
|
220
258
|
/** Pre-parsed request body (JSON for POST, or {} for GET) */
|
|
@@ -229,10 +267,9 @@ type ExposeOptions = {
|
|
|
229
267
|
select?: ExposeSelect;
|
|
230
268
|
/** Optional: use existing EventPlane instead of creating one per request */
|
|
231
269
|
plane?: EventPlane;
|
|
232
|
-
/** Event
|
|
233
|
-
|
|
234
|
-
/** Called when a client connects, after plane is ready.
|
|
235
|
-
* Call emitStartEvent() for default payload, emitStartEvent(mapped) for custom mapping, or omit to skip. */
|
|
270
|
+
/** Event definitions that can trigger a run (e.g. from AgentNetworkEvent.of). First is used for default emit. Default: "request" when omitted. */
|
|
271
|
+
triggerEvents?: ReadonlyArray<AgentNetworkEventDef<string, Schema.Schema.Any>>;
|
|
272
|
+
/** Called when a client connects, after plane is ready. Use setRunId/setContextId and emitStartEvent. */
|
|
236
273
|
onRequest?: <T = unknown>(ctx: OnRequestContext<T>) => void | Promise<void>;
|
|
237
274
|
};
|
|
238
275
|
/** Protocol-agnostic stream source that adapters consume */
|
|
@@ -335,7 +372,7 @@ declare class AgentNetwork {
|
|
|
335
372
|
*
|
|
336
373
|
* @example
|
|
337
374
|
* const api = network.expose({ protocol: "sse", auth, select });
|
|
338
|
-
* export const GET = NextEndpoint.from(api).handler();
|
|
375
|
+
* export const GET = NextEndpoint.from(api, { requestToContextId, requestToRunId }).handler();
|
|
339
376
|
*/
|
|
340
377
|
expose(options: ExposeOptions): ExposedAPI;
|
|
341
378
|
/**
|
|
@@ -363,6 +400,11 @@ declare function toSSEStream(source: AsyncIterable<Envelope>, signal?: AbortSign
|
|
|
363
400
|
|
|
364
401
|
/** Next.js App Router GET/POST handler signature */
|
|
365
402
|
type NextGetHandler = (request: Request) => Promise<Response>;
|
|
403
|
+
/** Options for NextEndpoint.from() - required to define how request maps to contextId and runId */
|
|
404
|
+
type NextEndpointOptions = {
|
|
405
|
+
requestToContextId: (request: Request) => string;
|
|
406
|
+
requestToRunId: (request: Request) => string;
|
|
407
|
+
};
|
|
366
408
|
/**
|
|
367
409
|
* Adapter for Next.js App Router. Maps an ExposedAPI to a route handler
|
|
368
410
|
* that streams events as SSE. Use for both GET and POST; POST with JSON body
|
|
@@ -370,12 +412,15 @@ type NextGetHandler = (request: Request) => Promise<Response>;
|
|
|
370
412
|
*
|
|
371
413
|
* @example
|
|
372
414
|
* const api = agentNetwork.expose({ protocol: "sse", auth, select });
|
|
373
|
-
* const handler = NextEndpoint.from(api
|
|
415
|
+
* const handler = NextEndpoint.from(api, {
|
|
416
|
+
* requestToContextId: (req) => req.headers.get('x-correlation-id') ?? crypto.randomUUID(),
|
|
417
|
+
* requestToRunId: () => crypto.randomUUID(),
|
|
418
|
+
* }).handler();
|
|
374
419
|
* export const GET = handler;
|
|
375
420
|
* export const POST = handler;
|
|
376
421
|
*/
|
|
377
422
|
declare const NextEndpoint: {
|
|
378
|
-
from(api: ExposedAPI): {
|
|
423
|
+
from(api: ExposedAPI, options: NextEndpointOptions): {
|
|
379
424
|
handler(): NextGetHandler;
|
|
380
425
|
};
|
|
381
426
|
};
|
|
@@ -384,6 +429,11 @@ declare const NextEndpoint: {
|
|
|
384
429
|
type ExpressRequest = {
|
|
385
430
|
on(event: 'close', fn: () => void): void;
|
|
386
431
|
};
|
|
432
|
+
/** Options for ExpressEndpoint.from() - required to define how request maps to contextId and runId */
|
|
433
|
+
type ExpressEndpointOptions = {
|
|
434
|
+
requestToContextId: (req: ExpressRequest) => string;
|
|
435
|
+
requestToRunId: (req: ExpressRequest) => string;
|
|
436
|
+
};
|
|
387
437
|
/** Minimal Express-like response (compatible with express.Response) */
|
|
388
438
|
type ExpressResponse = {
|
|
389
439
|
setHeader(name: string, value: string | number): void;
|
|
@@ -402,12 +452,15 @@ type ExpressHandler = (req: ExpressRequest, res: ExpressResponse) => void | Prom
|
|
|
402
452
|
*
|
|
403
453
|
* @example
|
|
404
454
|
* const api = agentNetwork.expose({ protocol: "sse", auth, select });
|
|
405
|
-
* app.get("/events", ExpressEndpoint.from(api
|
|
455
|
+
* app.get("/events", ExpressEndpoint.from(api, {
|
|
456
|
+
* requestToContextId: (req) => req.headers?.['x-correlation-id'] ?? crypto.randomUUID(),
|
|
457
|
+
* requestToRunId: () => crypto.randomUUID(),
|
|
458
|
+
* }).handler());
|
|
406
459
|
*/
|
|
407
460
|
declare const ExpressEndpoint: {
|
|
408
|
-
from(api: ExposedAPI): {
|
|
461
|
+
from(api: ExposedAPI, options: ExpressEndpointOptions): {
|
|
409
462
|
handler(): ExpressHandler;
|
|
410
463
|
};
|
|
411
464
|
};
|
|
412
465
|
|
|
413
|
-
export { Agent, AgentBinding, AgentFactory, AgentNetwork, AgentNetworkEvent, AgentNetworkEventDef, AnyAgent, AuthResult, Channel, ChannelDef, ChannelName, ConfiguredChannel, EmitPayload, EventEnvelope, EventMeta, EventMetaSchema, EventPlane, ExposeAuthError, ExposeOptions, ExposeRequest, ExposeSelect, ExposedAPI, ExposedStream, ExpressEndpoint, ExpressHandler, ExpressRequest, ExpressResponse, NextEndpoint, NextGetHandler, OnRequestContext, SetupContext, Sink, SinkDef, SpawnCallbackContext, SpawnFn, SpawnerBuilder, StreamFactory, formatSSE, isHttpStreamSink, toSSEStream };
|
|
466
|
+
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 };
|
package/dist/matrix/index.js
CHANGED
|
@@ -72,8 +72,66 @@ var Channel = {
|
|
|
72
72
|
};
|
|
73
73
|
}
|
|
74
74
|
};
|
|
75
|
+
|
|
76
|
+
// src/helper/types/noop.ts
|
|
77
|
+
var asyncNoop = async () => {
|
|
78
|
+
};
|
|
79
|
+
|
|
80
|
+
// src/matrix/agent-network/stores/inmemory-network-store.ts
|
|
81
|
+
var createInMemoryNetworkStore = () => {
|
|
82
|
+
const store = /* @__PURE__ */ new Map();
|
|
83
|
+
return {
|
|
84
|
+
storeEvent: (contextId, runId, event) => {
|
|
85
|
+
let byRun = store.get(contextId);
|
|
86
|
+
if (!byRun) {
|
|
87
|
+
byRun = /* @__PURE__ */ new Map();
|
|
88
|
+
store.set(contextId, byRun);
|
|
89
|
+
}
|
|
90
|
+
let events = byRun.get(runId);
|
|
91
|
+
if (!events) {
|
|
92
|
+
events = [];
|
|
93
|
+
byRun.set(runId, events);
|
|
94
|
+
}
|
|
95
|
+
events.push(event);
|
|
96
|
+
},
|
|
97
|
+
getEvents: (contextId, runId) => {
|
|
98
|
+
const events = store.get(contextId)?.get(runId);
|
|
99
|
+
return events ? [...events] : [];
|
|
100
|
+
},
|
|
101
|
+
getContextEvents: (contextId) => {
|
|
102
|
+
const byRun = store.get(contextId);
|
|
103
|
+
const result = /* @__PURE__ */ new Map();
|
|
104
|
+
if (byRun) {
|
|
105
|
+
for (const [runId, events] of byRun) {
|
|
106
|
+
result.set(runId, [...events]);
|
|
107
|
+
}
|
|
108
|
+
}
|
|
109
|
+
return result;
|
|
110
|
+
},
|
|
111
|
+
getFullStore: () => {
|
|
112
|
+
const result = /* @__PURE__ */ new Map();
|
|
113
|
+
for (const [contextId, byRun] of store) {
|
|
114
|
+
const contextMap = /* @__PURE__ */ new Map();
|
|
115
|
+
for (const [runId, events] of byRun) {
|
|
116
|
+
contextMap.set(runId, [...events]);
|
|
117
|
+
}
|
|
118
|
+
result.set(contextId, contextMap);
|
|
119
|
+
}
|
|
120
|
+
return result;
|
|
121
|
+
},
|
|
122
|
+
persist: () => asyncNoop(),
|
|
123
|
+
load: () => asyncNoop()
|
|
124
|
+
};
|
|
125
|
+
};
|
|
126
|
+
|
|
127
|
+
// src/matrix/agent-network/event-plane.ts
|
|
75
128
|
var DEFAULT_CAPACITY = 16;
|
|
76
|
-
var createEventPlane = (
|
|
129
|
+
var createEventPlane = (options) => Effect.gen(function* () {
|
|
130
|
+
const {
|
|
131
|
+
network,
|
|
132
|
+
capacity = DEFAULT_CAPACITY,
|
|
133
|
+
store = createInMemoryNetworkStore()
|
|
134
|
+
} = options;
|
|
77
135
|
const channels = network.getChannels();
|
|
78
136
|
const pubsubs = /* @__PURE__ */ new Map();
|
|
79
137
|
for (const channel of channels.values()) {
|
|
@@ -86,12 +144,42 @@ var createEventPlane = (network, capacity = DEFAULT_CAPACITY) => Effect.gen(func
|
|
|
86
144
|
throw new Error(`Channel not found: ${channel}`);
|
|
87
145
|
return p;
|
|
88
146
|
};
|
|
89
|
-
const
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
147
|
+
const recordEvent = (envelope) => {
|
|
148
|
+
const { contextId, runId } = envelope.meta;
|
|
149
|
+
store.storeEvent(contextId, runId, envelope);
|
|
150
|
+
};
|
|
151
|
+
const publishToPubSub = (channel, envelope) => PubSub.publish(getPubsub(channel), envelope);
|
|
152
|
+
const publish = (channel, envelope) => Effect.sync(() => recordEvent(envelope)).pipe(
|
|
153
|
+
Effect.flatMap(() => publishToPubSub(channel, envelope))
|
|
154
|
+
);
|
|
155
|
+
const publishToChannels = (targetChannels, envelope) => Effect.sync(() => recordEvent(envelope)).pipe(
|
|
156
|
+
Effect.flatMap(
|
|
157
|
+
() => Effect.all(
|
|
158
|
+
targetChannels.map((c) => publishToPubSub(c.name, envelope)),
|
|
159
|
+
{ concurrency: "unbounded" }
|
|
160
|
+
)
|
|
161
|
+
),
|
|
162
|
+
Effect.map((results) => results.every(Boolean))
|
|
163
|
+
);
|
|
94
164
|
const subscribe = (channel) => PubSub.subscribe(getPubsub(channel));
|
|
165
|
+
const getRunEvents = (runId, contextId) => {
|
|
166
|
+
return store.getEvents(contextId, runId).slice();
|
|
167
|
+
};
|
|
168
|
+
const getContextEvents = (contextId) => {
|
|
169
|
+
const byRun = store.getContextEvents(contextId);
|
|
170
|
+
const map = /* @__PURE__ */ new Map();
|
|
171
|
+
const all = [];
|
|
172
|
+
for (const [runId, events] of byRun) {
|
|
173
|
+
const readonlyEvents = events.slice();
|
|
174
|
+
map.set(runId, readonlyEvents);
|
|
175
|
+
all.push(...readonlyEvents);
|
|
176
|
+
}
|
|
177
|
+
return {
|
|
178
|
+
all,
|
|
179
|
+
byRun: (runId) => map.get(runId) ?? [],
|
|
180
|
+
map
|
|
181
|
+
};
|
|
182
|
+
};
|
|
95
183
|
const shutdown = Effect.all([...pubsubs.values()].map(PubSub.shutdown), {
|
|
96
184
|
concurrency: "unbounded"
|
|
97
185
|
}).pipe(Effect.asVoid);
|
|
@@ -99,6 +187,8 @@ var createEventPlane = (network, capacity = DEFAULT_CAPACITY) => Effect.gen(func
|
|
|
99
187
|
publish,
|
|
100
188
|
publishToChannels,
|
|
101
189
|
subscribe,
|
|
190
|
+
getRunEvents,
|
|
191
|
+
getContextEvents,
|
|
102
192
|
shutdown
|
|
103
193
|
};
|
|
104
194
|
});
|
|
@@ -109,6 +199,11 @@ var runSubscriber = (agent, publishesTo, dequeue, plane, emitQueue) => Effect.ge
|
|
|
109
199
|
if (listensTo.length > 0 && !listensTo.includes(envelope.name)) {
|
|
110
200
|
return;
|
|
111
201
|
}
|
|
202
|
+
const runEvents = plane.getRunEvents(
|
|
203
|
+
envelope.meta.runId,
|
|
204
|
+
envelope.meta.contextId
|
|
205
|
+
);
|
|
206
|
+
const contextEvents = plane.getContextEvents(envelope.meta.contextId);
|
|
112
207
|
yield* Effect.tryPromise({
|
|
113
208
|
try: () => agent.invoke({
|
|
114
209
|
triggerEvent: envelope,
|
|
@@ -131,7 +226,9 @@ var runSubscriber = (agent, publishesTo, dequeue, plane, emitQueue) => Effect.ge
|
|
|
131
226
|
plane.publishToChannels(publishesTo, fullEnvelope)
|
|
132
227
|
);
|
|
133
228
|
}
|
|
134
|
-
}
|
|
229
|
+
},
|
|
230
|
+
runEvents,
|
|
231
|
+
contextEvents
|
|
135
232
|
}),
|
|
136
233
|
catch: (e) => e
|
|
137
234
|
});
|
|
@@ -225,7 +322,15 @@ function streamFromDequeue(take, signal, eventFilter) {
|
|
|
225
322
|
};
|
|
226
323
|
}
|
|
227
324
|
function expose(network, options) {
|
|
228
|
-
const {
|
|
325
|
+
const {
|
|
326
|
+
auth,
|
|
327
|
+
select,
|
|
328
|
+
plane: providedPlane,
|
|
329
|
+
onRequest,
|
|
330
|
+
triggerEvents
|
|
331
|
+
} = options;
|
|
332
|
+
const triggerEventDef = triggerEvents?.[0];
|
|
333
|
+
const triggerEventName = triggerEventDef?.name ?? "request";
|
|
229
334
|
const channels = resolveChannels(network, select);
|
|
230
335
|
const eventFilter = select?.events;
|
|
231
336
|
const mainChannel = network.getMainChannel();
|
|
@@ -236,7 +341,7 @@ function expose(network, options) {
|
|
|
236
341
|
const payload = await extractPayload(req);
|
|
237
342
|
const signal = req.request?.signal;
|
|
238
343
|
const program = Effect.gen(function* () {
|
|
239
|
-
const plane = providedPlane ?? (yield* createEventPlane(network));
|
|
344
|
+
const plane = providedPlane ?? (yield* createEventPlane({ network }));
|
|
240
345
|
if (!providedPlane) {
|
|
241
346
|
const emitQueue = yield* Queue.unbounded();
|
|
242
347
|
yield* Effect.fork(
|
|
@@ -252,25 +357,46 @@ function expose(network, options) {
|
|
|
252
357
|
yield* Effect.sleep("10 millis");
|
|
253
358
|
}
|
|
254
359
|
const targetChannel = mainChannel?.name ?? channels[0];
|
|
255
|
-
|
|
256
|
-
|
|
360
|
+
let runId = req.runId ?? crypto.randomUUID();
|
|
361
|
+
let contextId = req.contextId ?? crypto.randomUUID();
|
|
362
|
+
const setRunId = (id) => {
|
|
363
|
+
runId = id;
|
|
364
|
+
};
|
|
365
|
+
const setContextId = (id) => {
|
|
366
|
+
contextId = id;
|
|
367
|
+
};
|
|
368
|
+
const emitStartEvent = (opts) => {
|
|
369
|
+
const meta = {
|
|
370
|
+
runId: opts.runId,
|
|
371
|
+
contextId: opts.contextId
|
|
372
|
+
};
|
|
257
373
|
const envelope = {
|
|
258
|
-
name:
|
|
259
|
-
meta
|
|
260
|
-
payload:
|
|
374
|
+
name: opts.event.name,
|
|
375
|
+
meta,
|
|
376
|
+
payload: opts.event.payload
|
|
261
377
|
};
|
|
262
|
-
Effect.runPromise(plane.publish(targetChannel, envelope)).catch(
|
|
263
|
-
|
|
378
|
+
Effect.runPromise(plane.publish(targetChannel, envelope)).catch(
|
|
379
|
+
() => {
|
|
380
|
+
}
|
|
381
|
+
);
|
|
264
382
|
};
|
|
265
383
|
const dequeue = yield* plane.subscribe(channels[0]);
|
|
266
384
|
if (onRequest) {
|
|
267
385
|
yield* Effect.tryPromise(
|
|
268
|
-
() => Promise.resolve(
|
|
386
|
+
() => Promise.resolve(
|
|
387
|
+
onRequest({
|
|
388
|
+
setRunId,
|
|
389
|
+
setContextId,
|
|
390
|
+
emitStartEvent,
|
|
391
|
+
req,
|
|
392
|
+
payload
|
|
393
|
+
})
|
|
394
|
+
)
|
|
269
395
|
);
|
|
270
396
|
} else if (!providedPlane) {
|
|
271
397
|
const envelope = {
|
|
272
|
-
name:
|
|
273
|
-
meta: { runId
|
|
398
|
+
name: triggerEventName,
|
|
399
|
+
meta: { runId, contextId },
|
|
274
400
|
payload
|
|
275
401
|
};
|
|
276
402
|
yield* plane.publish(targetChannel, envelope);
|
|
@@ -409,7 +535,7 @@ var AgentNetwork = class _AgentNetwork {
|
|
|
409
535
|
*
|
|
410
536
|
* @example
|
|
411
537
|
* const api = network.expose({ protocol: "sse", auth, select });
|
|
412
|
-
* export const GET = NextEndpoint.from(api).handler();
|
|
538
|
+
* export const GET = NextEndpoint.from(api, { requestToContextId, requestToRunId }).handler();
|
|
413
539
|
*/
|
|
414
540
|
expose(options) {
|
|
415
541
|
return expose(this, options);
|
|
@@ -427,7 +553,7 @@ var AgentNetwork = class _AgentNetwork {
|
|
|
427
553
|
}
|
|
428
554
|
runScoped(network, capacity) {
|
|
429
555
|
return Effect.gen(function* () {
|
|
430
|
-
const plane = yield* createEventPlane(network, capacity);
|
|
556
|
+
const plane = yield* createEventPlane({ network, capacity });
|
|
431
557
|
yield* Effect.fork(run(network, plane));
|
|
432
558
|
return plane;
|
|
433
559
|
});
|
|
@@ -435,7 +561,7 @@ var AgentNetwork = class _AgentNetwork {
|
|
|
435
561
|
};
|
|
436
562
|
var EventMetaSchema = Schema.Struct({
|
|
437
563
|
runId: Schema.String,
|
|
438
|
-
contextId: Schema.
|
|
564
|
+
contextId: Schema.String,
|
|
439
565
|
correlationId: Schema.optional(Schema.String),
|
|
440
566
|
causationId: Schema.optional(Schema.String),
|
|
441
567
|
ts: Schema.optional(Schema.Number)
|
|
@@ -458,9 +584,7 @@ var AgentNetworkEvent = {
|
|
|
458
584
|
const makeBound = (meta, payload2) => Effect.runSync(
|
|
459
585
|
decodeEnvelope({ name, meta, payload: payload2 })
|
|
460
586
|
);
|
|
461
|
-
const makeEffect = (payload2) => decodePayload(payload2).pipe(
|
|
462
|
-
Effect.map((p) => ({ name, payload: p }))
|
|
463
|
-
);
|
|
587
|
+
const makeEffect = (payload2) => decodePayload(payload2).pipe(Effect.map((p) => ({ name, payload: p })));
|
|
464
588
|
const makeBoundEffect = (meta, payload2) => decodeEnvelope({ name, meta, payload: payload2 });
|
|
465
589
|
const is = Schema.is(envelopeSchema);
|
|
466
590
|
return {
|
|
@@ -493,13 +617,19 @@ var Agent = class {
|
|
|
493
617
|
return __privateGet(this, _listensTo);
|
|
494
618
|
}
|
|
495
619
|
async invoke(options) {
|
|
496
|
-
const { triggerEvent, emit } = options ?? {};
|
|
620
|
+
const { triggerEvent, emit, runEvents, contextEvents } = options ?? {};
|
|
497
621
|
const emitFn = emit ?? ((_event) => {
|
|
498
622
|
});
|
|
499
623
|
await __privateGet(this, _logic).call(this, {
|
|
500
624
|
params: __privateGet(this, _params),
|
|
501
625
|
triggerEvent: triggerEvent ?? void 0,
|
|
502
|
-
emit: emitFn
|
|
626
|
+
emit: emitFn,
|
|
627
|
+
runEvents: runEvents ?? [],
|
|
628
|
+
contextEvents: contextEvents ?? {
|
|
629
|
+
all: [],
|
|
630
|
+
byRun: () => [],
|
|
631
|
+
map: /* @__PURE__ */ new Map()
|
|
632
|
+
}
|
|
503
633
|
});
|
|
504
634
|
}
|
|
505
635
|
getId() {
|
|
@@ -612,14 +742,19 @@ function toSSEStream(source, signal) {
|
|
|
612
742
|
|
|
613
743
|
// src/matrix/io/adapters/next-endpoint.ts
|
|
614
744
|
var NextEndpoint = {
|
|
615
|
-
from(api) {
|
|
745
|
+
from(api, options) {
|
|
616
746
|
if (api.protocol !== "sse") {
|
|
617
747
|
throw new Error(`NextEndpoint: unsupported protocol "${api.protocol}"`);
|
|
618
748
|
}
|
|
749
|
+
const { requestToContextId, requestToRunId } = options;
|
|
619
750
|
return {
|
|
620
751
|
handler() {
|
|
621
752
|
return async (request) => {
|
|
622
|
-
const req = {
|
|
753
|
+
const req = {
|
|
754
|
+
request,
|
|
755
|
+
contextId: requestToContextId(request),
|
|
756
|
+
runId: requestToRunId(request)
|
|
757
|
+
};
|
|
623
758
|
try {
|
|
624
759
|
const encoder = new TextEncoder();
|
|
625
760
|
const { readable, writable } = new TransformStream();
|
|
@@ -664,12 +799,13 @@ var NextEndpoint = {
|
|
|
664
799
|
|
|
665
800
|
// src/matrix/io/adapters/express-endpoint.ts
|
|
666
801
|
var ExpressEndpoint = {
|
|
667
|
-
from(api) {
|
|
802
|
+
from(api, options) {
|
|
668
803
|
if (api.protocol !== "sse") {
|
|
669
804
|
throw new Error(
|
|
670
805
|
`ExpressEndpoint: unsupported protocol "${api.protocol}"`
|
|
671
806
|
);
|
|
672
807
|
}
|
|
808
|
+
const { requestToContextId, requestToRunId } = options;
|
|
673
809
|
return {
|
|
674
810
|
handler() {
|
|
675
811
|
return async (req, res) => {
|
|
@@ -678,7 +814,9 @@ var ExpressEndpoint = {
|
|
|
678
814
|
const exposeReq = {
|
|
679
815
|
request: { signal: controller.signal },
|
|
680
816
|
req,
|
|
681
|
-
res
|
|
817
|
+
res,
|
|
818
|
+
contextId: requestToContextId(req),
|
|
819
|
+
runId: requestToRunId(req)
|
|
682
820
|
};
|
|
683
821
|
try {
|
|
684
822
|
const encoder = new TextEncoder();
|