aether-server 0.1.0 → 1.0.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
@@ -1,5 +1,5 @@
1
1
  import { FastifyInstance } from 'fastify';
2
- import { AetherConfig, Aether } from 'aether-core';
2
+ import { Aether, AetherConfig } from 'aether-core';
3
3
 
4
4
  interface ServerConfig {
5
5
  /** Port to listen on */
@@ -8,12 +8,21 @@ interface ServerConfig {
8
8
  host?: string;
9
9
  /** CORS origin configuration */
10
10
  corsOrigin?: string | string[] | boolean;
11
- /** Aether configuration */
12
- aether: AetherConfig;
11
+ /**
12
+ * Pre-configured Aether instance. When provided, the server uses this
13
+ * instance instead of creating a new one from `aether` config.
14
+ */
15
+ aetherInstance?: Aether;
16
+ /** Aether configuration (used when aetherInstance is not provided) */
17
+ aether?: AetherConfig;
13
18
  /** Enable request logging */
14
19
  logging?: boolean;
15
20
  /** API key for authentication (optional) */
16
21
  apiKey?: string;
22
+ /** Enable Studio UI at / (default: true) */
23
+ studio?: boolean;
24
+ /** Custom path to studio static files */
25
+ studioPath?: string;
17
26
  }
18
27
 
19
28
  declare module 'fastify' {
package/dist/index.js CHANGED
@@ -1,6 +1,10 @@
1
1
  // src/app.ts
2
+ import { resolve, dirname } from "path";
3
+ import { fileURLToPath } from "url";
4
+ import { existsSync } from "fs";
2
5
  import Fastify from "fastify";
3
6
  import cors from "@fastify/cors";
7
+ import fastifyStatic from "@fastify/static";
4
8
  import websocket from "@fastify/websocket";
5
9
  import { Aether } from "aether-core";
6
10
 
@@ -10,7 +14,8 @@ function getDefaultConfig() {
10
14
  port: parseInt(process.env["PORT"] ?? "3000", 10),
11
15
  host: process.env["HOST"] ?? "0.0.0.0",
12
16
  corsOrigin: process.env["CORS_ORIGIN"] ?? true,
13
- logging: process.env["NODE_ENV"] !== "test"
17
+ logging: false,
18
+ studio: true
14
19
  };
15
20
  }
16
21
 
@@ -33,6 +38,10 @@ var batchAddSchema = z.object({
33
38
  events: z.array(addMemorySchema).min(1).max(100)
34
39
  });
35
40
  var memoryRoutes = async (fastify) => {
41
+ fastify.get("/events", async (request) => {
42
+ const limit = request.query.limit ? parseInt(request.query.limit, 10) : 100;
43
+ return fastify.aether.getAll(limit);
44
+ });
36
45
  fastify.post("/memory", async (request, reply) => {
37
46
  const result = addMemorySchema.safeParse(request.body);
38
47
  if (!result.success) {
@@ -124,66 +133,498 @@ var healthRoutes = async (fastify) => {
124
133
  });
125
134
  };
126
135
 
127
- // src/websocket/handler.ts
128
- var wsHandler = async (fastify) => {
129
- const clients = /* @__PURE__ */ new Set();
130
- const unsubscribe = fastify.aether.subscribe((event) => {
131
- const message = JSON.stringify({
132
- type: "memory:added",
133
- data: event
136
+ // src/routes/trajectory.ts
137
+ import { z as z2 } from "zod";
138
+ var startTrajectorySchema = z2.object({
139
+ actor: z2.string().min(1),
140
+ context: z2.record(z2.unknown()).optional()
141
+ });
142
+ var endTrajectorySchema = z2.object({
143
+ outcome: z2.enum(["success", "failure", "partial"]).optional()
144
+ });
145
+ var addEventSchema = z2.object({
146
+ eventId: z2.string().min(1)
147
+ });
148
+ var queryTrajectoriesSchema = z2.object({
149
+ actor: z2.string().optional(),
150
+ status: z2.array(z2.enum(["active", "completed", "abandoned"])).optional(),
151
+ outcome: z2.array(z2.enum(["success", "failure", "partial"])).optional(),
152
+ startTime: z2.string().optional(),
153
+ endTime: z2.string().optional(),
154
+ inferredFrom: z2.enum(["explicit", "auto"]).optional(),
155
+ limit: z2.coerce.number().min(1).max(100).optional(),
156
+ offset: z2.coerce.number().min(0).optional(),
157
+ order: z2.enum(["asc", "desc"]).optional()
158
+ });
159
+ var inferTrajectoriesSchema = z2.object({
160
+ actor: z2.string().min(1),
161
+ maxGapMs: z2.number().min(1e3).optional(),
162
+ minEvents: z2.number().min(1).optional(),
163
+ contextOverlapThreshold: z2.number().min(0).max(1).optional(),
164
+ useSemanticSimilarity: z2.boolean().optional(),
165
+ semanticThreshold: z2.number().min(0).max(1).optional(),
166
+ startTime: z2.string().optional(),
167
+ endTime: z2.string().optional(),
168
+ requiredContextKeys: z2.array(z2.string()).optional()
169
+ });
170
+ var trajectoryRoutes = async (fastify) => {
171
+ fastify.post("/trajectory", async (request, reply) => {
172
+ const result = startTrajectorySchema.safeParse(request.body);
173
+ if (!result.success) {
174
+ return reply.code(400).send({ error: "Invalid request", details: result.error.issues });
175
+ }
176
+ const { actor, context } = result.data;
177
+ const trajectoryId = await fastify.aether.startTrajectory(actor, context);
178
+ return reply.code(201).send({ id: trajectoryId });
179
+ });
180
+ fastify.patch("/trajectory/:id/end", async (request, reply) => {
181
+ const result = endTrajectorySchema.safeParse(request.body);
182
+ if (!result.success) {
183
+ return reply.code(400).send({ error: "Invalid request", details: result.error.issues });
184
+ }
185
+ try {
186
+ const trajectory = await fastify.aether.endTrajectory(
187
+ request.params.id,
188
+ result.data.outcome
189
+ );
190
+ return trajectory;
191
+ } catch (err) {
192
+ return reply.code(404).send({ error: "Trajectory not found or already ended" });
193
+ }
194
+ });
195
+ fastify.get("/trajectory/:id", async (request, reply) => {
196
+ const trajectory = await fastify.aether.getTrajectory(request.params.id);
197
+ if (!trajectory) {
198
+ return reply.code(404).send({ error: "Trajectory not found" });
199
+ }
200
+ return trajectory;
201
+ });
202
+ fastify.get("/trajectory/:id/events", async (request, reply) => {
203
+ try {
204
+ const events = await fastify.aether.getTrajectoryEvents(request.params.id);
205
+ return events;
206
+ } catch (err) {
207
+ return reply.code(404).send({ error: "Trajectory not found" });
208
+ }
209
+ });
210
+ fastify.post("/trajectory/:id/events", async (request, reply) => {
211
+ const result = addEventSchema.safeParse(request.body);
212
+ if (!result.success) {
213
+ return reply.code(400).send({ error: "Invalid request", details: result.error.issues });
214
+ }
215
+ try {
216
+ await fastify.aether.addEventToTrajectory(request.params.id, result.data.eventId);
217
+ return { success: true };
218
+ } catch (err) {
219
+ return reply.code(400).send({ error: String(err) });
220
+ }
221
+ });
222
+ fastify.get("/trajectories", async (request, reply) => {
223
+ const result = queryTrajectoriesSchema.safeParse(request.query);
224
+ if (!result.success) {
225
+ return reply.code(400).send({ error: "Invalid query", details: result.error.issues });
226
+ }
227
+ const { actor, status, outcome, startTime, endTime, inferredFrom, limit, offset, order } = result.data;
228
+ const trajectories = await fastify.aether.getTrajectories({
229
+ actor,
230
+ status,
231
+ outcome,
232
+ timeRange: startTime && endTime ? { start: startTime, end: endTime } : void 0,
233
+ inferredFrom,
234
+ limit: limit ?? 20,
235
+ offset,
236
+ order
134
237
  });
135
- for (const client of clients) {
136
- if (client.readyState === 1) {
137
- client.send(message);
238
+ return trajectories;
239
+ });
240
+ fastify.get("/trajectories/:actor/stats", async (request) => {
241
+ const stats = await fastify.aether.getTrajectoryStats(request.params.actor);
242
+ return stats;
243
+ });
244
+ fastify.post("/trajectories/infer", async (request, reply) => {
245
+ const result = inferTrajectoriesSchema.safeParse(request.body);
246
+ if (!result.success) {
247
+ return reply.code(400).send({ error: "Invalid request", details: result.error.issues });
248
+ }
249
+ const {
250
+ actor,
251
+ maxGapMs,
252
+ minEvents,
253
+ contextOverlapThreshold,
254
+ useSemanticSimilarity,
255
+ semanticThreshold,
256
+ startTime,
257
+ endTime,
258
+ requiredContextKeys
259
+ } = result.data;
260
+ const trajectories = await fastify.aether.inferTrajectories(actor, {
261
+ maxGapMs,
262
+ minEvents,
263
+ contextOverlapThreshold,
264
+ useSemanticSimilarity,
265
+ semanticThreshold,
266
+ timeRange: startTime && endTime ? { start: startTime, end: endTime } : void 0,
267
+ requiredContextKeys
268
+ });
269
+ return trajectories;
270
+ });
271
+ };
272
+
273
+ // src/routes/patterns.ts
274
+ import { z as z3 } from "zod";
275
+ var patternDetectionSchema = z3.object({
276
+ minFrequency: z3.number().min(1).optional(),
277
+ minConfidence: z3.number().min(0).max(1).optional(),
278
+ minSupport: z3.number().min(0).max(1).optional(),
279
+ maxPatternLength: z3.number().min(2).optional(),
280
+ timeRange: z3.object({
281
+ start: z3.string(),
282
+ end: z3.string()
283
+ }).optional()
284
+ });
285
+ var anomalyDetectionSchema = z3.object({
286
+ minDeviationScore: z3.number().min(0).max(1).optional(),
287
+ severities: z3.array(z3.enum(["low", "medium", "high"])).optional(),
288
+ limit: z3.number().min(1).max(100).optional(),
289
+ timeRange: z3.object({
290
+ start: z3.string(),
291
+ end: z3.string()
292
+ }).optional()
293
+ });
294
+ var predictNextSchema = z3.object({
295
+ actor: z3.string().min(1),
296
+ currentEventId: z3.string().min(1),
297
+ topK: z3.number().min(1).max(20).optional(),
298
+ includeConfidence: z3.boolean().optional(),
299
+ contextWeight: z3.number().min(0).max(1).optional()
300
+ });
301
+ var simulateSchema = z3.object({
302
+ actor: z3.string().min(1),
303
+ proposedAction: z3.string().min(1),
304
+ currentEventId: z3.string().optional(),
305
+ context: z3.record(z3.unknown()).optional(),
306
+ depth: z3.number().min(1).max(10).optional()
307
+ });
308
+ var patternsRoutes = async (fastify) => {
309
+ fastify.get(
310
+ "/patterns/:actor",
311
+ async (request, reply) => {
312
+ const query = request.query;
313
+ const options = patternDetectionSchema.safeParse({
314
+ minFrequency: query.minFrequency ? Number(query.minFrequency) : void 0,
315
+ minConfidence: query.minConfidence ? Number(query.minConfidence) : void 0,
316
+ minSupport: query.minSupport ? Number(query.minSupport) : void 0,
317
+ maxPatternLength: query.maxPatternLength ? Number(query.maxPatternLength) : void 0,
318
+ timeRange: query.startTime && query.endTime ? { start: query.startTime, end: query.endTime } : void 0
319
+ });
320
+ if (!options.success) {
321
+ return reply.code(400).send({ error: "Invalid query", details: options.error.issues });
322
+ }
323
+ const patterns = await fastify.aether.detectPatterns(request.params.actor, options.data);
324
+ return patterns;
325
+ }
326
+ );
327
+ fastify.get(
328
+ "/anomalies/:actor",
329
+ async (request, reply) => {
330
+ const query = request.query;
331
+ const options = anomalyDetectionSchema.safeParse({
332
+ minDeviationScore: query.minDeviationScore ? Number(query.minDeviationScore) : void 0,
333
+ severities: query.severities ? query.severities.split(",").map((s) => s.trim()) : void 0,
334
+ limit: query.limit ? Number(query.limit) : void 0,
335
+ timeRange: query.startTime && query.endTime ? { start: query.startTime, end: query.endTime } : void 0
336
+ });
337
+ if (!options.success) {
338
+ return reply.code(400).send({ error: "Invalid query", details: options.error.issues });
138
339
  }
340
+ const anomalies = await fastify.aether.findAnomalies(request.params.actor, {
341
+ ...options.data,
342
+ severities: options.data.severities
343
+ });
344
+ return anomalies;
345
+ }
346
+ );
347
+ fastify.get("/transitions/:actor", async (request) => {
348
+ const matrix = await fastify.aether.getTransitionProbabilities(request.params.actor);
349
+ return matrix;
350
+ });
351
+ fastify.post("/predict", async (request, reply) => {
352
+ const result = predictNextSchema.safeParse(request.body);
353
+ if (!result.success) {
354
+ return reply.code(400).send({ error: "Invalid request", details: result.error.issues });
355
+ }
356
+ const { actor, currentEventId, topK, includeConfidence, contextWeight } = result.data;
357
+ const predictions = await fastify.aether.predictNext(actor, currentEventId, {
358
+ topK,
359
+ includeConfidence,
360
+ contextWeight
361
+ });
362
+ return predictions;
363
+ });
364
+ fastify.post("/simulate", async (request, reply) => {
365
+ const result = simulateSchema.safeParse(request.body);
366
+ if (!result.success) {
367
+ return reply.code(400).send({ error: "Invalid request", details: result.error.issues });
139
368
  }
369
+ const { actor, proposedAction, currentEventId, context, depth } = result.data;
370
+ const simulation = await fastify.aether.simulate(actor, proposedAction, {
371
+ currentEventId,
372
+ context,
373
+ depth
374
+ });
375
+ return simulation;
376
+ });
377
+ };
378
+
379
+ // src/routes/ontology.ts
380
+ import { z as z4 } from "zod";
381
+ var discoverOptionsSchema = z4.object({
382
+ minFrequency: z4.number().min(1).optional(),
383
+ minConfidence: z4.number().min(0).max(1).optional(),
384
+ maxTypes: z4.number().min(1).max(100).optional(),
385
+ includeExamples: z4.boolean().optional(),
386
+ exampleLimit: z4.number().min(1).max(20).optional(),
387
+ actors: z4.array(z4.string()).optional(),
388
+ timeRange: z4.object({
389
+ start: z4.string(),
390
+ end: z4.string()
391
+ }).optional()
392
+ });
393
+ var schemaOptionsSchema = z4.object({
394
+ includeOptional: z4.boolean().optional(),
395
+ minConfidence: z4.number().min(0).max(1).optional(),
396
+ format: z4.enum(["typescript", "json-schema", "both"]).optional()
397
+ });
398
+ var ontologyRoutes = async (fastify) => {
399
+ fastify.get("/ontology/entities", async (request, reply) => {
400
+ const query = request.query;
401
+ const options = discoverOptionsSchema.safeParse({
402
+ minFrequency: query["minFrequency"] ? Number(query["minFrequency"]) : void 0,
403
+ minConfidence: query["minConfidence"] ? Number(query["minConfidence"]) : void 0,
404
+ maxTypes: query["maxTypes"] ? Number(query["maxTypes"]) : void 0,
405
+ includeExamples: query["includeExamples"] === "true",
406
+ exampleLimit: query["exampleLimit"] ? Number(query["exampleLimit"]) : void 0,
407
+ actors: query["actors"] ? query["actors"].split(",").map((s) => s.trim()) : void 0,
408
+ timeRange: query["startTime"] && query["endTime"] ? { start: query["startTime"], end: query["endTime"] } : void 0
409
+ });
410
+ if (!options.success) {
411
+ return reply.code(400).send({ error: "Invalid query", details: options.error.issues });
412
+ }
413
+ const entities = await fastify.aether.discoverEntities(options.data);
414
+ return entities;
415
+ });
416
+ fastify.get("/ontology/relationships", async (request, reply) => {
417
+ const query = request.query;
418
+ const options = discoverOptionsSchema.safeParse({
419
+ minFrequency: query["minFrequency"] ? Number(query["minFrequency"]) : void 0,
420
+ minConfidence: query["minConfidence"] ? Number(query["minConfidence"]) : void 0,
421
+ maxTypes: query["maxTypes"] ? Number(query["maxTypes"]) : void 0,
422
+ includeExamples: query["includeExamples"] === "true",
423
+ exampleLimit: query["exampleLimit"] ? Number(query["exampleLimit"]) : void 0,
424
+ actors: query["actors"] ? query["actors"].split(",").map((s) => s.trim()) : void 0,
425
+ timeRange: query["startTime"] && query["endTime"] ? { start: query["startTime"], end: query["endTime"] } : void 0
426
+ });
427
+ if (!options.success) {
428
+ return reply.code(400).send({ error: "Invalid query", details: options.error.issues });
429
+ }
430
+ const relationships = await fastify.aether.discoverRelationships(options.data);
431
+ return relationships;
432
+ });
433
+ fastify.get("/ontology/schema", async (request, reply) => {
434
+ const query = request.query;
435
+ const options = schemaOptionsSchema.safeParse({
436
+ includeOptional: query["includeOptional"] === "true",
437
+ minConfidence: query["minConfidence"] ? Number(query["minConfidence"]) : void 0,
438
+ format: query["format"]
439
+ });
440
+ if (!options.success) {
441
+ return reply.code(400).send({ error: "Invalid query", details: options.error.issues });
442
+ }
443
+ const schema = await fastify.aether.suggestSchema(options.data);
444
+ return schema;
445
+ });
446
+ };
447
+
448
+ // src/websocket/handler.ts
449
+ var wsHandler = async (fastify) => {
450
+ const clientStates = /* @__PURE__ */ new Map();
451
+ const broadcast = (type, data, subscriptionType, actorFilter) => {
452
+ const message = JSON.stringify({ type, data });
453
+ for (const [socket, state] of clientStates) {
454
+ if (socket.readyState !== 1) continue;
455
+ if (!state.subscriptions.has(subscriptionType)) continue;
456
+ if (actorFilter && state.actorFilter && state.actorFilter !== actorFilter) continue;
457
+ socket.send(message);
458
+ }
459
+ };
460
+ const unsubscribeMemory = fastify.aether.subscribe((event) => {
461
+ broadcast("memory:added", event, "memory", event.actor);
140
462
  });
141
463
  fastify.addHook("onClose", () => {
142
- unsubscribe();
143
- clients.clear();
464
+ unsubscribeMemory();
465
+ clientStates.clear();
144
466
  });
145
467
  fastify.get("/ws", { websocket: true }, (connection) => {
146
468
  const socket = connection.socket;
147
- clients.add(socket);
469
+ const state = {
470
+ socket,
471
+ subscriptions: /* @__PURE__ */ new Set(["memory"]),
472
+ // Default subscription
473
+ actorFilter: void 0
474
+ };
475
+ clientStates.set(socket, state);
148
476
  socket.send(
149
477
  JSON.stringify({
150
478
  type: "connected",
151
- data: { message: "Connected to Aether WebSocket" }
479
+ data: {
480
+ message: "Connected to Aether WebSocket",
481
+ availableSubscriptions: ["memory", "trajectory", "patterns", "anomalies"]
482
+ }
152
483
  })
153
484
  );
154
485
  socket.on("message", async (rawMessage) => {
155
486
  try {
156
487
  const message = JSON.parse(rawMessage.toString());
488
+ const data = message.data;
157
489
  switch (message.type) {
158
490
  case "ping":
159
491
  socket.send(JSON.stringify({ type: "pong" }));
160
492
  break;
161
493
  case "subscribe":
162
- socket.send(
163
- JSON.stringify({
164
- type: "subscribed",
165
- data: { message: "Subscribed to memory events" }
166
- })
167
- );
494
+ if (data && typeof data === "object") {
495
+ const types = data.types ?? ["memory"];
496
+ const actor = data.actor;
497
+ for (const t of types) {
498
+ state.subscriptions.add(t);
499
+ }
500
+ if (actor) state.actorFilter = actor;
501
+ socket.send(
502
+ JSON.stringify({
503
+ type: "subscribed",
504
+ data: {
505
+ subscriptions: Array.from(state.subscriptions),
506
+ actor: state.actorFilter
507
+ }
508
+ })
509
+ );
510
+ }
511
+ break;
512
+ case "unsubscribe":
513
+ if (data && typeof data === "object") {
514
+ const types = data.types ?? [];
515
+ for (const t of types) {
516
+ state.subscriptions.delete(t);
517
+ }
518
+ socket.send(
519
+ JSON.stringify({
520
+ type: "unsubscribed",
521
+ data: { subscriptions: Array.from(state.subscriptions) }
522
+ })
523
+ );
524
+ }
168
525
  break;
169
526
  case "add":
170
- if (message.data && typeof message.data === "object") {
171
- const input = message.data;
172
- if (input.content) {
173
- const event = await fastify.aether.add({
174
- content: input.content,
175
- actor: input.actor,
176
- context: input.context
177
- });
527
+ if (data && typeof data === "object" && data.content) {
528
+ const event = await fastify.aether.add({
529
+ content: data.content,
530
+ actor: data.actor,
531
+ action: data.action,
532
+ context: data.context
533
+ });
534
+ socket.send(
535
+ JSON.stringify({
536
+ type: "memory:added",
537
+ data: event
538
+ })
539
+ );
540
+ }
541
+ break;
542
+ case "trajectory:start":
543
+ if (data && typeof data === "object" && data.actor) {
544
+ const trajectoryId = await fastify.aether.startTrajectory(
545
+ data.actor,
546
+ data.context
547
+ );
548
+ socket.send(
549
+ JSON.stringify({
550
+ type: "trajectory:started",
551
+ data: { id: trajectoryId, actor: data.actor }
552
+ })
553
+ );
554
+ broadcast("trajectory:started", { id: trajectoryId, actor: data.actor }, "trajectory", data.actor);
555
+ }
556
+ break;
557
+ case "trajectory:end":
558
+ if (data && typeof data === "object" && data.trajectoryId) {
559
+ try {
560
+ const trajectory = await fastify.aether.endTrajectory(
561
+ data.trajectoryId,
562
+ data.outcome
563
+ );
178
564
  socket.send(
179
565
  JSON.stringify({
180
- type: "memory:added",
181
- data: event
566
+ type: "trajectory:ended",
567
+ data: trajectory
182
568
  })
183
569
  );
570
+ broadcast("trajectory:ended", trajectory, "trajectory", trajectory.actor);
571
+ } catch (err) {
572
+ socket.send(
573
+ JSON.stringify({
574
+ type: "error",
575
+ data: { message: "Failed to end trajectory" }
576
+ })
577
+ );
578
+ }
579
+ }
580
+ break;
581
+ case "patterns:detect":
582
+ if (data && typeof data === "object" && data.actor) {
583
+ const patterns = await fastify.aether.detectPatterns(data.actor, {
584
+ minFrequency: data.minFrequency,
585
+ minConfidence: data.minConfidence
586
+ });
587
+ socket.send(
588
+ JSON.stringify({
589
+ type: "patterns:detected",
590
+ data: { actor: data.actor, patterns }
591
+ })
592
+ );
593
+ }
594
+ break;
595
+ case "anomalies:detect":
596
+ if (data && typeof data === "object" && data.actor) {
597
+ const anomalies = await fastify.aether.findAnomalies(data.actor, {
598
+ minDeviationScore: data.minDeviationScore,
599
+ limit: data.limit
600
+ });
601
+ socket.send(
602
+ JSON.stringify({
603
+ type: "anomalies:detected",
604
+ data: { actor: data.actor, anomalies }
605
+ })
606
+ );
607
+ const highSeverity = anomalies.filter((a) => a.severity === "high");
608
+ if (highSeverity.length > 0) {
609
+ broadcast("anomalies:alert", { actor: data.actor, anomalies: highSeverity }, "anomalies", data.actor);
184
610
  }
185
611
  }
186
612
  break;
613
+ case "predict":
614
+ if (data && typeof data === "object" && data.actor && data.eventId) {
615
+ const predictions = await fastify.aether.predictNext(
616
+ data.actor,
617
+ data.eventId,
618
+ { topK: data.topK }
619
+ );
620
+ socket.send(
621
+ JSON.stringify({
622
+ type: "predictions",
623
+ data: { actor: data.actor, eventId: data.eventId, predictions }
624
+ })
625
+ );
626
+ }
627
+ break;
187
628
  default:
188
629
  socket.send(
189
630
  JSON.stringify({
@@ -196,38 +637,58 @@ var wsHandler = async (fastify) => {
196
637
  socket.send(
197
638
  JSON.stringify({
198
639
  type: "error",
199
- data: { message: "Invalid message format" }
640
+ data: { message: "Invalid message format or operation failed" }
200
641
  })
201
642
  );
202
643
  }
203
644
  });
204
645
  socket.on("close", () => {
205
- clients.delete(socket);
646
+ clientStates.delete(socket);
206
647
  });
207
648
  });
208
649
  };
209
650
 
210
651
  // src/app.ts
652
+ var __dirname = dirname(fileURLToPath(import.meta.url));
653
+ function findStudioPath() {
654
+ const possiblePaths = [
655
+ // Development: workspace structure
656
+ resolve(__dirname, "../../react/dist/studio"),
657
+ resolve(__dirname, "../../../react/dist/studio"),
658
+ // Production: node_modules
659
+ resolve(__dirname, "../node_modules/aether-react/dist/studio"),
660
+ resolve(__dirname, "../../node_modules/aether-react/dist/studio"),
661
+ // Fallback: look in parent node_modules
662
+ resolve(process.cwd(), "node_modules/aether-react/dist/studio")
663
+ ];
664
+ for (const p of possiblePaths) {
665
+ if (existsSync(p)) {
666
+ return p;
667
+ }
668
+ }
669
+ return null;
670
+ }
211
671
  async function createServer(config) {
212
672
  const mergedConfig = { ...getDefaultConfig(), ...config };
213
673
  const fastify = Fastify({
214
- logger: mergedConfig.logging ? {
215
- transport: {
216
- target: "pino-pretty",
217
- options: {
218
- translateTime: "HH:MM:ss Z",
219
- ignore: "pid,hostname"
220
- }
221
- }
222
- } : false
674
+ logger: mergedConfig.logging
223
675
  });
224
676
  await fastify.register(cors, {
225
677
  origin: mergedConfig.corsOrigin,
226
678
  methods: ["GET", "POST", "PUT", "DELETE", "OPTIONS"]
227
679
  });
228
680
  await fastify.register(websocket);
229
- const aether = new Aether(config.aether);
230
- await aether.initialize();
681
+ let aether;
682
+ let ownsAether = false;
683
+ if (config.aetherInstance) {
684
+ aether = config.aetherInstance;
685
+ } else if (config.aether) {
686
+ aether = new Aether(config.aether);
687
+ await aether.initialize();
688
+ ownsAether = true;
689
+ } else {
690
+ throw new Error("ServerConfig must include either aetherInstance or aether config");
691
+ }
231
692
  fastify.decorate("aether", aether);
232
693
  if (mergedConfig.apiKey) {
233
694
  fastify.addHook("onRequest", async (request, reply) => {
@@ -240,10 +701,31 @@ async function createServer(config) {
240
701
  }
241
702
  await fastify.register(healthRoutes);
242
703
  await fastify.register(memoryRoutes, { prefix: "/api/v1" });
704
+ await fastify.register(trajectoryRoutes, { prefix: "/api/v1" });
705
+ await fastify.register(patternsRoutes, { prefix: "/api/v1" });
706
+ await fastify.register(ontologyRoutes, { prefix: "/api/v1" });
243
707
  await fastify.register(wsHandler);
244
- fastify.addHook("onClose", async () => {
245
- await aether.close();
246
- });
708
+ if (mergedConfig.studio !== false) {
709
+ const studioPath = mergedConfig.studioPath || findStudioPath();
710
+ if (studioPath && existsSync(studioPath)) {
711
+ await fastify.register(fastifyStatic, {
712
+ root: studioPath,
713
+ prefix: "/"
714
+ });
715
+ fastify.setNotFoundHandler((request, reply) => {
716
+ if (request.url.startsWith("/api/") || request.url.startsWith("/ws")) {
717
+ reply.code(404).send({ error: "Not found" });
718
+ } else {
719
+ reply.sendFile("index.html");
720
+ }
721
+ });
722
+ }
723
+ }
724
+ if (ownsAether) {
725
+ fastify.addHook("onClose", async () => {
726
+ await aether.close();
727
+ });
728
+ }
247
729
  return fastify;
248
730
  }
249
731
 
package/dist/index.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/app.ts","../src/config.ts","../src/routes/memory.ts","../src/routes/health.ts","../src/websocket/handler.ts","../src/start.ts"],"sourcesContent":["import Fastify, { type FastifyInstance } from 'fastify';\nimport cors from '@fastify/cors';\nimport websocket from '@fastify/websocket';\nimport { Aether } from 'aether-core';\nimport { type ServerConfig, getDefaultConfig } from './config.js';\nimport { memoryRoutes } from './routes/memory.js';\nimport { healthRoutes } from './routes/health.js';\nimport { wsHandler } from './websocket/handler.js';\n\ndeclare module 'fastify' {\n interface FastifyInstance {\n aether: Aether;\n }\n}\n\nexport async function createServer(config: ServerConfig): Promise<FastifyInstance> {\n const mergedConfig = { ...getDefaultConfig(), ...config };\n\n const fastify = Fastify({\n logger: mergedConfig.logging\n ? {\n transport: {\n target: 'pino-pretty',\n options: {\n translateTime: 'HH:MM:ss Z',\n ignore: 'pid,hostname',\n },\n },\n }\n : false,\n });\n\n // Register plugins\n await fastify.register(cors, {\n origin: mergedConfig.corsOrigin,\n methods: ['GET', 'POST', 'PUT', 'DELETE', 'OPTIONS'],\n });\n\n await fastify.register(websocket);\n\n // Initialize Aether\n const aether = new Aether(config.aether);\n await aether.initialize();\n\n // Decorate fastify with aether instance\n fastify.decorate('aether', aether);\n\n // Optional API key authentication\n if (mergedConfig.apiKey) {\n fastify.addHook('onRequest', async (request, reply) => {\n // Skip auth for health check\n if (request.url === '/health') return;\n\n const authHeader = request.headers.authorization;\n if (!authHeader || authHeader !== `Bearer ${mergedConfig.apiKey}`) {\n reply.code(401).send({ error: 'Unauthorized' });\n }\n });\n }\n\n // Register routes\n await fastify.register(healthRoutes);\n await fastify.register(memoryRoutes, { prefix: '/api/v1' });\n\n // WebSocket for real-time updates\n await fastify.register(wsHandler);\n\n // Cleanup on close\n fastify.addHook('onClose', async () => {\n await aether.close();\n });\n\n return fastify;\n}\n","import type { AetherConfig } from 'aether-core';\n\nexport interface ServerConfig {\n /** Port to listen on */\n port?: number;\n /** Host to bind to */\n host?: string;\n /** CORS origin configuration */\n corsOrigin?: string | string[] | boolean;\n /** Aether configuration */\n aether: AetherConfig;\n /** Enable request logging */\n logging?: boolean;\n /** API key for authentication (optional) */\n apiKey?: string;\n}\n\nexport function getDefaultConfig(): Partial<ServerConfig> {\n return {\n port: parseInt(process.env['PORT'] ?? '3000', 10),\n host: process.env['HOST'] ?? '0.0.0.0',\n corsOrigin: process.env['CORS_ORIGIN'] ?? true,\n logging: process.env['NODE_ENV'] !== 'test',\n };\n}\n","import type { FastifyPluginAsync } from 'fastify';\nimport { z } from 'zod';\nimport type { RetrievalType } from 'aether-core';\n\n// Request schemas\nconst addMemorySchema = z.object({\n content: z.string().min(1),\n actor: z.string().optional(),\n action: z.string().optional(),\n context: z.record(z.unknown()).optional(),\n});\n\nconst querySchema = z.object({\n q: z.string().min(1),\n actor: z.string().optional(),\n type: z.enum(['semantic', 'temporal', 'relational', 'hybrid']).optional(),\n limit: z.coerce.number().min(1).max(100).optional(),\n threshold: z.coerce.number().min(0).max(1).optional(),\n});\n\nconst batchAddSchema = z.object({\n events: z.array(addMemorySchema).min(1).max(100),\n});\n\nexport const memoryRoutes: FastifyPluginAsync = async (fastify) => {\n // Add a single memory\n fastify.post('/memory', async (request, reply) => {\n const result = addMemorySchema.safeParse(request.body);\n if (!result.success) {\n return reply.code(400).send({ error: 'Invalid request', details: result.error.issues });\n }\n\n const { content, actor, action, context } = result.data;\n const event = await fastify.aether.add({ content, actor, action, context });\n\n return reply.code(201).send(event);\n });\n\n // Query memories\n fastify.get('/memory', async (request, reply) => {\n const result = querySchema.safeParse(request.query);\n if (!result.success) {\n return reply.code(400).send({ error: 'Invalid query', details: result.error.issues });\n }\n\n const { q, actor, type, limit, threshold } = result.data;\n const events = await fastify.aether.retrieve(q, {\n actor,\n retrievalType: type as RetrievalType | undefined,\n limit: limit ?? 10,\n threshold,\n });\n\n return events;\n });\n\n // Get memory by ID\n fastify.get<{ Params: { id: string } }>('/memory/:id', async (request, reply) => {\n const event = await fastify.aether.get(request.params.id);\n\n if (!event) {\n return reply.code(404).send({ error: 'Memory not found' });\n }\n\n return event;\n });\n\n // Delete memory by ID\n fastify.delete<{ Params: { id: string } }>('/memory/:id', async (request, reply) => {\n const deleted = await fastify.aether.delete(request.params.id);\n\n if (!deleted) {\n return reply.code(404).send({ error: 'Memory not found' });\n }\n\n return { success: true };\n });\n\n // Batch add memories\n fastify.post('/memory/batch', async (request, reply) => {\n const result = batchAddSchema.safeParse(request.body);\n if (!result.success) {\n return reply.code(400).send({ error: 'Invalid request', details: result.error.issues });\n }\n\n const events = await fastify.aether.addBatch(result.data.events);\n return reply.code(201).send(events);\n });\n\n // Get actor history\n fastify.get<{ Params: { actor: string }; Querystring: { limit?: string } }>(\n '/history/:actor',\n async (request) => {\n const limit = request.query.limit ? parseInt(request.query.limit, 10) : 20;\n const events = await fastify.aether.getHistory(request.params.actor, limit);\n return events;\n }\n );\n\n // Advanced search\n fastify.post('/search', async (request, reply) => {\n const body = request.body as Record<string, unknown>;\n\n // Basic validation\n if (!body || typeof body !== 'object') {\n return reply.code(400).send({ error: 'Invalid request body' });\n }\n\n try {\n const events = await fastify.aether.search({\n semantic: body['semantic'] as { query: string; weight?: number } | undefined,\n temporal: body['temporal'] as { actor: string; recency?: number; weight?: number } | undefined,\n relational: body['relational'] as { contextKeys: string[]; values: unknown[]; weight?: number } | undefined,\n limit: (body['limit'] as number) ?? 10,\n combineStrategy: body['combineStrategy'] as 'union' | 'intersection' | 'weighted' | undefined,\n });\n return events;\n } catch (err) {\n return reply.code(400).send({ error: String(err) });\n }\n });\n\n // Get statistics\n fastify.get('/stats', async () => {\n return fastify.aether.stats();\n });\n};\n","import type { FastifyPluginAsync } from 'fastify';\n\nexport const healthRoutes: FastifyPluginAsync = async (fastify) => {\n fastify.get('/health', async (_request, _reply) => {\n const stats = await fastify.aether.stats();\n\n return {\n status: 'ok',\n version: '0.1.0',\n timestamp: new Date().toISOString(),\n storage: stats.storageAdapter,\n embeddings: stats.embeddingProvider,\n events: stats.totalEvents,\n };\n });\n};\n","import type { FastifyPluginAsync } from 'fastify';\nimport type { WebSocket } from 'ws';\nimport type { MemoryEvent } from 'aether-core';\n\ninterface WebSocketMessage {\n type: string;\n data?: unknown;\n}\n\nexport const wsHandler: FastifyPluginAsync = async (fastify) => {\n // Track connected clients\n const clients = new Set<WebSocket>();\n\n // Subscribe to aether events and broadcast to all clients\n const unsubscribe = fastify.aether.subscribe((event: MemoryEvent) => {\n const message = JSON.stringify({\n type: 'memory:added',\n data: event,\n });\n\n for (const client of clients) {\n if (client.readyState === 1) {\n // WebSocket.OPEN\n client.send(message);\n }\n }\n });\n\n // Cleanup on server close\n fastify.addHook('onClose', () => {\n unsubscribe();\n clients.clear();\n });\n\n // WebSocket route\n fastify.get('/ws', { websocket: true }, (connection) => {\n const socket = connection.socket;\n clients.add(socket);\n\n // Send welcome message\n socket.send(\n JSON.stringify({\n type: 'connected',\n data: { message: 'Connected to Aether WebSocket' },\n })\n );\n\n // Handle incoming messages\n socket.on('message', async (rawMessage) => {\n try {\n const message = JSON.parse(rawMessage.toString()) as WebSocketMessage;\n\n switch (message.type) {\n case 'ping':\n socket.send(JSON.stringify({ type: 'pong' }));\n break;\n\n case 'subscribe':\n // Client is already subscribed via the global subscription\n socket.send(\n JSON.stringify({\n type: 'subscribed',\n data: { message: 'Subscribed to memory events' },\n })\n );\n break;\n\n case 'add':\n // Allow adding memories via WebSocket\n if (message.data && typeof message.data === 'object') {\n const input = message.data as { content?: string; actor?: string; context?: Record<string, unknown> };\n if (input.content) {\n const event = await fastify.aether.add({\n content: input.content,\n actor: input.actor,\n context: input.context,\n });\n socket.send(\n JSON.stringify({\n type: 'memory:added',\n data: event,\n })\n );\n }\n }\n break;\n\n default:\n socket.send(\n JSON.stringify({\n type: 'error',\n data: { message: `Unknown message type: ${message.type}` },\n })\n );\n }\n } catch (err) {\n socket.send(\n JSON.stringify({\n type: 'error',\n data: { message: 'Invalid message format' },\n })\n );\n }\n });\n\n // Handle disconnect\n socket.on('close', () => {\n clients.delete(socket);\n });\n });\n};\n","import { createServer } from './app.js';\nimport type { ServerConfig } from './config.js';\n\nexport async function startServer(config: ServerConfig): Promise<void> {\n const server = await createServer(config);\n\n const port = config.port ?? 3000;\n const host = config.host ?? '0.0.0.0';\n\n try {\n await server.listen({ port, host });\n console.log(`Aether server listening on http://${host}:${port}`);\n } catch (err) {\n server.log.error(err);\n process.exit(1);\n }\n\n // Handle graceful shutdown\n const shutdown = async () => {\n console.log('\\nShutting down...');\n await server.close();\n process.exit(0);\n };\n\n process.on('SIGINT', shutdown);\n process.on('SIGTERM', shutdown);\n}\n"],"mappings":"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","names":[]}
1
+ {"version":3,"sources":["../src/app.ts","../src/config.ts","../src/routes/memory.ts","../src/routes/health.ts","../src/routes/trajectory.ts","../src/routes/patterns.ts","../src/routes/ontology.ts","../src/websocket/handler.ts","../src/start.ts"],"sourcesContent":["import { resolve, dirname } from 'path';\nimport { fileURLToPath } from 'url';\nimport { existsSync } from 'fs';\nimport Fastify, { type FastifyInstance } from 'fastify';\nimport cors from '@fastify/cors';\nimport fastifyStatic from '@fastify/static';\nimport websocket from '@fastify/websocket';\nimport { Aether } from 'aether-core';\nimport { type ServerConfig, getDefaultConfig } from './config.js';\nimport { memoryRoutes } from './routes/memory.js';\nimport { healthRoutes } from './routes/health.js';\nimport { trajectoryRoutes } from './routes/trajectory.js';\nimport { patternsRoutes } from './routes/patterns.js';\nimport { ontologyRoutes } from './routes/ontology.js';\nimport { wsHandler } from './websocket/handler.js';\n\nconst __dirname = dirname(fileURLToPath(import.meta.url));\n\nfunction findStudioPath(): string | null {\n // Possible locations for studio files\n const possiblePaths = [\n // Development: workspace structure\n resolve(__dirname, '../../react/dist/studio'),\n resolve(__dirname, '../../../react/dist/studio'),\n // Production: node_modules\n resolve(__dirname, '../node_modules/aether-react/dist/studio'),\n resolve(__dirname, '../../node_modules/aether-react/dist/studio'),\n // Fallback: look in parent node_modules\n resolve(process.cwd(), 'node_modules/aether-react/dist/studio'),\n ];\n\n for (const p of possiblePaths) {\n if (existsSync(p)) {\n return p;\n }\n }\n\n return null;\n}\n\ndeclare module 'fastify' {\n interface FastifyInstance {\n aether: Aether;\n }\n}\n\nexport async function createServer(config: ServerConfig): Promise<FastifyInstance> {\n const mergedConfig = { ...getDefaultConfig(), ...config };\n\n const fastify = Fastify({\n logger: mergedConfig.logging,\n });\n\n // Register plugins\n await fastify.register(cors, {\n origin: mergedConfig.corsOrigin,\n methods: ['GET', 'POST', 'PUT', 'DELETE', 'OPTIONS'],\n });\n\n await fastify.register(websocket);\n\n // Use provided Aether instance or create a new one\n let aether: Aether;\n let ownsAether = false;\n\n if (config.aetherInstance) {\n aether = config.aetherInstance;\n } else if (config.aether) {\n aether = new Aether(config.aether);\n await aether.initialize();\n ownsAether = true;\n } else {\n throw new Error('ServerConfig must include either aetherInstance or aether config');\n }\n\n // Decorate fastify with aether instance\n fastify.decorate('aether', aether);\n\n // Optional API key authentication\n if (mergedConfig.apiKey) {\n fastify.addHook('onRequest', async (request, reply) => {\n // Skip auth for health check\n if (request.url === '/health') return;\n\n const authHeader = request.headers.authorization;\n if (!authHeader || authHeader !== `Bearer ${mergedConfig.apiKey}`) {\n reply.code(401).send({ error: 'Unauthorized' });\n }\n });\n }\n\n // Register routes\n await fastify.register(healthRoutes);\n await fastify.register(memoryRoutes, { prefix: '/api/v1' });\n await fastify.register(trajectoryRoutes, { prefix: '/api/v1' });\n await fastify.register(patternsRoutes, { prefix: '/api/v1' });\n await fastify.register(ontologyRoutes, { prefix: '/api/v1' });\n\n // WebSocket for real-time updates\n await fastify.register(wsHandler);\n\n // Serve Studio UI if enabled\n if (mergedConfig.studio !== false) {\n // Try to find studio files\n const studioPath = mergedConfig.studioPath || findStudioPath();\n\n if (studioPath && existsSync(studioPath)) {\n await fastify.register(fastifyStatic, {\n root: studioPath,\n prefix: '/',\n });\n\n // SPA fallback - serve index.html for all non-API routes\n fastify.setNotFoundHandler((request, reply) => {\n if (request.url.startsWith('/api/') || request.url.startsWith('/ws')) {\n reply.code(404).send({ error: 'Not found' });\n } else {\n reply.sendFile('index.html');\n }\n });\n }\n }\n\n // Cleanup on close - only close aether if we created it\n if (ownsAether) {\n fastify.addHook('onClose', async () => {\n await aether.close();\n });\n }\n\n return fastify;\n}\n","import type { Aether, AetherConfig } from 'aether-core';\n\nexport interface ServerConfig {\n /** Port to listen on */\n port?: number;\n /** Host to bind to */\n host?: string;\n /** CORS origin configuration */\n corsOrigin?: string | string[] | boolean;\n /**\n * Pre-configured Aether instance. When provided, the server uses this\n * instance instead of creating a new one from `aether` config.\n */\n aetherInstance?: Aether;\n /** Aether configuration (used when aetherInstance is not provided) */\n aether?: AetherConfig;\n /** Enable request logging */\n logging?: boolean;\n /** API key for authentication (optional) */\n apiKey?: string;\n /** Enable Studio UI at / (default: true) */\n studio?: boolean;\n /** Custom path to studio static files */\n studioPath?: string;\n}\n\nexport function getDefaultConfig(): Partial<ServerConfig> {\n return {\n port: parseInt(process.env['PORT'] ?? '3000', 10),\n host: process.env['HOST'] ?? '0.0.0.0',\n corsOrigin: process.env['CORS_ORIGIN'] ?? true,\n logging: false,\n studio: true,\n };\n}\n","import type { FastifyPluginAsync } from 'fastify';\nimport { z } from 'zod';\nimport type { RetrievalType } from 'aether-core';\n\n// Request schemas\nconst addMemorySchema = z.object({\n content: z.string().min(1),\n actor: z.string().optional(),\n action: z.string().optional(),\n context: z.record(z.unknown()).optional(),\n});\n\nconst querySchema = z.object({\n q: z.string().min(1),\n actor: z.string().optional(),\n type: z.enum(['semantic', 'temporal', 'relational', 'hybrid']).optional(),\n limit: z.coerce.number().min(1).max(100).optional(),\n threshold: z.coerce.number().min(0).max(1).optional(),\n});\n\nconst batchAddSchema = z.object({\n events: z.array(addMemorySchema).min(1).max(100),\n});\n\nexport const memoryRoutes: FastifyPluginAsync = async (fastify) => {\n // List all events (no search required)\n fastify.get<{ Querystring: { limit?: string } }>('/events', async (request) => {\n const limit = request.query.limit ? parseInt(request.query.limit, 10) : 100;\n return fastify.aether.getAll(limit);\n });\n\n // Add a single memory\n fastify.post('/memory', async (request, reply) => {\n const result = addMemorySchema.safeParse(request.body);\n if (!result.success) {\n return reply.code(400).send({ error: 'Invalid request', details: result.error.issues });\n }\n\n const { content, actor, action, context } = result.data;\n const event = await fastify.aether.add({ content, actor, action, context });\n\n return reply.code(201).send(event);\n });\n\n // Query memories\n fastify.get('/memory', async (request, reply) => {\n const result = querySchema.safeParse(request.query);\n if (!result.success) {\n return reply.code(400).send({ error: 'Invalid query', details: result.error.issues });\n }\n\n const { q, actor, type, limit, threshold } = result.data;\n const events = await fastify.aether.retrieve(q, {\n actor,\n retrievalType: type as RetrievalType | undefined,\n limit: limit ?? 10,\n threshold,\n });\n\n return events;\n });\n\n // Get memory by ID\n fastify.get<{ Params: { id: string } }>('/memory/:id', async (request, reply) => {\n const event = await fastify.aether.get(request.params.id);\n\n if (!event) {\n return reply.code(404).send({ error: 'Memory not found' });\n }\n\n return event;\n });\n\n // Delete memory by ID\n fastify.delete<{ Params: { id: string } }>('/memory/:id', async (request, reply) => {\n const deleted = await fastify.aether.delete(request.params.id);\n\n if (!deleted) {\n return reply.code(404).send({ error: 'Memory not found' });\n }\n\n return { success: true };\n });\n\n // Batch add memories\n fastify.post('/memory/batch', async (request, reply) => {\n const result = batchAddSchema.safeParse(request.body);\n if (!result.success) {\n return reply.code(400).send({ error: 'Invalid request', details: result.error.issues });\n }\n\n const events = await fastify.aether.addBatch(result.data.events);\n return reply.code(201).send(events);\n });\n\n // Get actor history\n fastify.get<{ Params: { actor: string }; Querystring: { limit?: string } }>(\n '/history/:actor',\n async (request) => {\n const limit = request.query.limit ? parseInt(request.query.limit, 10) : 20;\n const events = await fastify.aether.getHistory(request.params.actor, limit);\n return events;\n }\n );\n\n // Advanced search\n fastify.post('/search', async (request, reply) => {\n const body = request.body as Record<string, unknown>;\n\n // Basic validation\n if (!body || typeof body !== 'object') {\n return reply.code(400).send({ error: 'Invalid request body' });\n }\n\n try {\n const events = await fastify.aether.search({\n semantic: body['semantic'] as { query: string; weight?: number } | undefined,\n temporal: body['temporal'] as { actor: string; recency?: number; weight?: number } | undefined,\n relational: body['relational'] as { contextKeys: string[]; values: unknown[]; weight?: number } | undefined,\n limit: (body['limit'] as number) ?? 10,\n combineStrategy: body['combineStrategy'] as 'union' | 'intersection' | 'weighted' | undefined,\n });\n return events;\n } catch (err) {\n return reply.code(400).send({ error: String(err) });\n }\n });\n\n // Get statistics\n fastify.get('/stats', async () => {\n return fastify.aether.stats();\n });\n};\n","import type { FastifyPluginAsync } from 'fastify';\n\nexport const healthRoutes: FastifyPluginAsync = async (fastify) => {\n fastify.get('/health', async (_request, _reply) => {\n const stats = await fastify.aether.stats();\n\n return {\n status: 'ok',\n version: '0.1.0',\n timestamp: new Date().toISOString(),\n storage: stats.storageAdapter,\n embeddings: stats.embeddingProvider,\n events: stats.totalEvents,\n };\n });\n};\n","import type { FastifyPluginAsync } from 'fastify';\nimport { z } from 'zod';\nimport type { TrajectoryStatus, TrajectoryOutcome, TrajectoryInferenceMode } from 'aether-core';\n\n// Request schemas\nconst startTrajectorySchema = z.object({\n actor: z.string().min(1),\n context: z.record(z.unknown()).optional(),\n});\n\nconst endTrajectorySchema = z.object({\n outcome: z.enum(['success', 'failure', 'partial']).optional(),\n});\n\nconst addEventSchema = z.object({\n eventId: z.string().min(1),\n});\n\nconst queryTrajectoriesSchema = z.object({\n actor: z.string().optional(),\n status: z.array(z.enum(['active', 'completed', 'abandoned'])).optional(),\n outcome: z.array(z.enum(['success', 'failure', 'partial'])).optional(),\n startTime: z.string().optional(),\n endTime: z.string().optional(),\n inferredFrom: z.enum(['explicit', 'auto']).optional(),\n limit: z.coerce.number().min(1).max(100).optional(),\n offset: z.coerce.number().min(0).optional(),\n order: z.enum(['asc', 'desc']).optional(),\n});\n\nconst inferTrajectoriesSchema = z.object({\n actor: z.string().min(1),\n maxGapMs: z.number().min(1000).optional(),\n minEvents: z.number().min(1).optional(),\n contextOverlapThreshold: z.number().min(0).max(1).optional(),\n useSemanticSimilarity: z.boolean().optional(),\n semanticThreshold: z.number().min(0).max(1).optional(),\n startTime: z.string().optional(),\n endTime: z.string().optional(),\n requiredContextKeys: z.array(z.string()).optional(),\n});\n\nexport const trajectoryRoutes: FastifyPluginAsync = async (fastify) => {\n // Start a new trajectory\n fastify.post('/trajectory', async (request, reply) => {\n const result = startTrajectorySchema.safeParse(request.body);\n if (!result.success) {\n return reply.code(400).send({ error: 'Invalid request', details: result.error.issues });\n }\n\n const { actor, context } = result.data;\n const trajectoryId = await fastify.aether.startTrajectory(actor, context);\n\n return reply.code(201).send({ id: trajectoryId });\n });\n\n // End a trajectory\n fastify.patch<{ Params: { id: string } }>('/trajectory/:id/end', async (request, reply) => {\n const result = endTrajectorySchema.safeParse(request.body);\n if (!result.success) {\n return reply.code(400).send({ error: 'Invalid request', details: result.error.issues });\n }\n\n try {\n const trajectory = await fastify.aether.endTrajectory(\n request.params.id,\n result.data.outcome as TrajectoryOutcome | undefined\n );\n return trajectory;\n } catch (err) {\n return reply.code(404).send({ error: 'Trajectory not found or already ended' });\n }\n });\n\n // Get a single trajectory\n fastify.get<{ Params: { id: string } }>('/trajectory/:id', async (request, reply) => {\n const trajectory = await fastify.aether.getTrajectory(request.params.id);\n\n if (!trajectory) {\n return reply.code(404).send({ error: 'Trajectory not found' });\n }\n\n return trajectory;\n });\n\n // Get events for a trajectory\n fastify.get<{ Params: { id: string } }>('/trajectory/:id/events', async (request, reply) => {\n try {\n const events = await fastify.aether.getTrajectoryEvents(request.params.id);\n return events;\n } catch (err) {\n return reply.code(404).send({ error: 'Trajectory not found' });\n }\n });\n\n // Add an event to a trajectory\n fastify.post<{ Params: { id: string } }>('/trajectory/:id/events', async (request, reply) => {\n const result = addEventSchema.safeParse(request.body);\n if (!result.success) {\n return reply.code(400).send({ error: 'Invalid request', details: result.error.issues });\n }\n\n try {\n await fastify.aether.addEventToTrajectory(request.params.id, result.data.eventId);\n return { success: true };\n } catch (err) {\n return reply.code(400).send({ error: String(err) });\n }\n });\n\n // Query trajectories\n fastify.get('/trajectories', async (request, reply) => {\n const result = queryTrajectoriesSchema.safeParse(request.query);\n if (!result.success) {\n return reply.code(400).send({ error: 'Invalid query', details: result.error.issues });\n }\n\n const { actor, status, outcome, startTime, endTime, inferredFrom, limit, offset, order } = result.data;\n\n const trajectories = await fastify.aether.getTrajectories({\n actor,\n status: status as TrajectoryStatus[] | undefined,\n outcome: outcome as TrajectoryOutcome[] | undefined,\n timeRange: startTime && endTime ? { start: startTime, end: endTime } : undefined,\n inferredFrom: inferredFrom as TrajectoryInferenceMode | undefined,\n limit: limit ?? 20,\n offset,\n order,\n });\n\n return trajectories;\n });\n\n // Get trajectory stats for an actor\n fastify.get<{ Params: { actor: string } }>('/trajectories/:actor/stats', async (request) => {\n const stats = await fastify.aether.getTrajectoryStats(request.params.actor);\n return stats;\n });\n\n // Infer trajectories from events\n fastify.post('/trajectories/infer', async (request, reply) => {\n const result = inferTrajectoriesSchema.safeParse(request.body);\n if (!result.success) {\n return reply.code(400).send({ error: 'Invalid request', details: result.error.issues });\n }\n\n const {\n actor,\n maxGapMs,\n minEvents,\n contextOverlapThreshold,\n useSemanticSimilarity,\n semanticThreshold,\n startTime,\n endTime,\n requiredContextKeys,\n } = result.data;\n\n const trajectories = await fastify.aether.inferTrajectories(actor, {\n maxGapMs,\n minEvents,\n contextOverlapThreshold,\n useSemanticSimilarity,\n semanticThreshold,\n timeRange: startTime && endTime ? { start: startTime, end: endTime } : undefined,\n requiredContextKeys,\n });\n\n return trajectories;\n });\n};\n","import type { FastifyPluginAsync } from 'fastify';\nimport { z } from 'zod';\nimport type { AnomalySeverity } from 'aether-core';\n\n// Request schemas\nconst patternDetectionSchema = z.object({\n minFrequency: z.number().min(1).optional(),\n minConfidence: z.number().min(0).max(1).optional(),\n minSupport: z.number().min(0).max(1).optional(),\n maxPatternLength: z.number().min(2).optional(),\n timeRange: z\n .object({\n start: z.string(),\n end: z.string(),\n })\n .optional(),\n});\n\nconst anomalyDetectionSchema = z.object({\n minDeviationScore: z.number().min(0).max(1).optional(),\n severities: z.array(z.enum(['low', 'medium', 'high'])).optional(),\n limit: z.number().min(1).max(100).optional(),\n timeRange: z\n .object({\n start: z.string(),\n end: z.string(),\n })\n .optional(),\n});\n\nconst predictNextSchema = z.object({\n actor: z.string().min(1),\n currentEventId: z.string().min(1),\n topK: z.number().min(1).max(20).optional(),\n includeConfidence: z.boolean().optional(),\n contextWeight: z.number().min(0).max(1).optional(),\n});\n\nconst simulateSchema = z.object({\n actor: z.string().min(1),\n proposedAction: z.string().min(1),\n currentEventId: z.string().optional(),\n context: z.record(z.unknown()).optional(),\n depth: z.number().min(1).max(10).optional(),\n});\n\nexport const patternsRoutes: FastifyPluginAsync = async (fastify) => {\n // Detect patterns for an actor\n fastify.get<{ Params: { actor: string }; Querystring: Record<string, string> }>(\n '/patterns/:actor',\n async (request, reply) => {\n const query = request.query as Record<string, unknown>;\n\n // Parse numeric values from query string\n const options = patternDetectionSchema.safeParse({\n minFrequency: query.minFrequency ? Number(query.minFrequency) : undefined,\n minConfidence: query.minConfidence ? Number(query.minConfidence) : undefined,\n minSupport: query.minSupport ? Number(query.minSupport) : undefined,\n maxPatternLength: query.maxPatternLength ? Number(query.maxPatternLength) : undefined,\n timeRange:\n query.startTime && query.endTime\n ? { start: query.startTime as string, end: query.endTime as string }\n : undefined,\n });\n\n if (!options.success) {\n return reply.code(400).send({ error: 'Invalid query', details: options.error.issues });\n }\n\n const patterns = await fastify.aether.detectPatterns(request.params.actor, options.data);\n return patterns;\n }\n );\n\n // Find anomalies for an actor\n fastify.get<{ Params: { actor: string }; Querystring: Record<string, string> }>(\n '/anomalies/:actor',\n async (request, reply) => {\n const query = request.query as Record<string, unknown>;\n\n const options = anomalyDetectionSchema.safeParse({\n minDeviationScore: query.minDeviationScore ? Number(query.minDeviationScore) : undefined,\n severities: query.severities\n ? (query.severities as string).split(',').map((s) => s.trim())\n : undefined,\n limit: query.limit ? Number(query.limit) : undefined,\n timeRange:\n query.startTime && query.endTime\n ? { start: query.startTime as string, end: query.endTime as string }\n : undefined,\n });\n\n if (!options.success) {\n return reply.code(400).send({ error: 'Invalid query', details: options.error.issues });\n }\n\n const anomalies = await fastify.aether.findAnomalies(request.params.actor, {\n ...options.data,\n severities: options.data.severities as AnomalySeverity[] | undefined,\n });\n return anomalies;\n }\n );\n\n // Get transition probabilities for an actor\n fastify.get<{ Params: { actor: string } }>('/transitions/:actor', async (request) => {\n const matrix = await fastify.aether.getTransitionProbabilities(request.params.actor);\n return matrix;\n });\n\n // Predict next actions\n fastify.post('/predict', async (request, reply) => {\n const result = predictNextSchema.safeParse(request.body);\n if (!result.success) {\n return reply.code(400).send({ error: 'Invalid request', details: result.error.issues });\n }\n\n const { actor, currentEventId, topK, includeConfidence, contextWeight } = result.data;\n\n const predictions = await fastify.aether.predictNext(actor, currentEventId, {\n topK,\n includeConfidence,\n contextWeight,\n });\n\n return predictions;\n });\n\n // Simulate an action\n fastify.post('/simulate', async (request, reply) => {\n const result = simulateSchema.safeParse(request.body);\n if (!result.success) {\n return reply.code(400).send({ error: 'Invalid request', details: result.error.issues });\n }\n\n const { actor, proposedAction, currentEventId, context, depth } = result.data;\n\n const simulation = await fastify.aether.simulate(actor, proposedAction, {\n currentEventId,\n context,\n depth,\n });\n\n return simulation;\n });\n};\n","import type { FastifyPluginAsync } from 'fastify';\nimport { z } from 'zod';\n\n// Request schemas\nconst discoverOptionsSchema = z.object({\n minFrequency: z.number().min(1).optional(),\n minConfidence: z.number().min(0).max(1).optional(),\n maxTypes: z.number().min(1).max(100).optional(),\n includeExamples: z.boolean().optional(),\n exampleLimit: z.number().min(1).max(20).optional(),\n actors: z.array(z.string()).optional(),\n timeRange: z\n .object({\n start: z.string(),\n end: z.string(),\n })\n .optional(),\n});\n\nconst schemaOptionsSchema = z.object({\n includeOptional: z.boolean().optional(),\n minConfidence: z.number().min(0).max(1).optional(),\n format: z.enum(['typescript', 'json-schema', 'both']).optional(),\n});\n\nexport const ontologyRoutes: FastifyPluginAsync = async (fastify) => {\n // Discover entity types from events\n fastify.get('/ontology/entities', async (request, reply) => {\n const query = request.query as Record<string, unknown>;\n\n const options = discoverOptionsSchema.safeParse({\n minFrequency: query['minFrequency'] ? Number(query['minFrequency']) : undefined,\n minConfidence: query['minConfidence'] ? Number(query['minConfidence']) : undefined,\n maxTypes: query['maxTypes'] ? Number(query['maxTypes']) : undefined,\n includeExamples: query['includeExamples'] === 'true',\n exampleLimit: query['exampleLimit'] ? Number(query['exampleLimit']) : undefined,\n actors: query['actors']\n ? (query['actors'] as string).split(',').map((s) => s.trim())\n : undefined,\n timeRange:\n query['startTime'] && query['endTime']\n ? { start: query['startTime'] as string, end: query['endTime'] as string }\n : undefined,\n });\n\n if (!options.success) {\n return reply.code(400).send({ error: 'Invalid query', details: options.error.issues });\n }\n\n const entities = await fastify.aether.discoverEntities(options.data);\n return entities;\n });\n\n // Discover relationships between entities\n fastify.get('/ontology/relationships', async (request, reply) => {\n const query = request.query as Record<string, unknown>;\n\n const options = discoverOptionsSchema.safeParse({\n minFrequency: query['minFrequency'] ? Number(query['minFrequency']) : undefined,\n minConfidence: query['minConfidence'] ? Number(query['minConfidence']) : undefined,\n maxTypes: query['maxTypes'] ? Number(query['maxTypes']) : undefined,\n includeExamples: query['includeExamples'] === 'true',\n exampleLimit: query['exampleLimit'] ? Number(query['exampleLimit']) : undefined,\n actors: query['actors']\n ? (query['actors'] as string).split(',').map((s) => s.trim())\n : undefined,\n timeRange:\n query['startTime'] && query['endTime']\n ? { start: query['startTime'] as string, end: query['endTime'] as string }\n : undefined,\n });\n\n if (!options.success) {\n return reply.code(400).send({ error: 'Invalid query', details: options.error.issues });\n }\n\n const relationships = await fastify.aether.discoverRelationships(options.data);\n return relationships;\n });\n\n // Generate schema suggestion from discovered ontology\n fastify.get('/ontology/schema', async (request, reply) => {\n const query = request.query as Record<string, unknown>;\n\n const options = schemaOptionsSchema.safeParse({\n includeOptional: query['includeOptional'] === 'true',\n minConfidence: query['minConfidence'] ? Number(query['minConfidence']) : undefined,\n format: query['format'] as 'typescript' | 'json-schema' | 'both' | undefined,\n });\n\n if (!options.success) {\n return reply.code(400).send({ error: 'Invalid query', details: options.error.issues });\n }\n\n const schema = await fastify.aether.suggestSchema(options.data);\n return schema;\n });\n};\n","import type { FastifyPluginAsync } from 'fastify';\nimport type { WebSocket } from 'ws';\nimport type { MemoryEvent, Trajectory, Anomaly } from 'aether-core';\n\ninterface WebSocketMessage {\n type: string;\n data?: unknown;\n}\n\ninterface ClientState {\n socket: WebSocket;\n subscriptions: Set<string>;\n actorFilter?: string;\n}\n\nexport const wsHandler: FastifyPluginAsync = async (fastify) => {\n // Track connected clients with their state\n const clientStates = new Map<WebSocket, ClientState>();\n\n // Helper to broadcast to clients with specific subscription\n const broadcast = (type: string, data: unknown, subscriptionType: string, actorFilter?: string) => {\n const message = JSON.stringify({ type, data });\n\n for (const [socket, state] of clientStates) {\n if (socket.readyState !== 1) continue; // WebSocket.OPEN\n if (!state.subscriptions.has(subscriptionType)) continue;\n if (actorFilter && state.actorFilter && state.actorFilter !== actorFilter) continue;\n\n socket.send(message);\n }\n };\n\n // Subscribe to aether memory events\n const unsubscribeMemory = fastify.aether.subscribe((event: MemoryEvent) => {\n broadcast('memory:added', event, 'memory', event.actor);\n });\n\n // Cleanup on server close\n fastify.addHook('onClose', () => {\n unsubscribeMemory();\n clientStates.clear();\n });\n\n // WebSocket route\n fastify.get('/ws', { websocket: true }, (connection) => {\n const socket = connection.socket;\n const state: ClientState = {\n socket,\n subscriptions: new Set(['memory']), // Default subscription\n actorFilter: undefined,\n };\n clientStates.set(socket, state);\n\n // Send welcome message\n socket.send(\n JSON.stringify({\n type: 'connected',\n data: {\n message: 'Connected to Aether WebSocket',\n availableSubscriptions: ['memory', 'trajectory', 'patterns', 'anomalies'],\n },\n })\n );\n\n // Handle incoming messages\n socket.on('message', async (rawMessage) => {\n try {\n const message = JSON.parse(rawMessage.toString()) as WebSocketMessage;\n const data = message.data as Record<string, unknown> | undefined;\n\n switch (message.type) {\n case 'ping':\n socket.send(JSON.stringify({ type: 'pong' }));\n break;\n\n case 'subscribe':\n // Subscribe to specific event types\n if (data && typeof data === 'object') {\n const types = (data.types as string[]) ?? ['memory'];\n const actor = data.actor as string | undefined;\n\n for (const t of types) {\n state.subscriptions.add(t);\n }\n if (actor) state.actorFilter = actor;\n\n socket.send(\n JSON.stringify({\n type: 'subscribed',\n data: {\n subscriptions: Array.from(state.subscriptions),\n actor: state.actorFilter,\n },\n })\n );\n }\n break;\n\n case 'unsubscribe':\n // Unsubscribe from specific event types\n if (data && typeof data === 'object') {\n const types = (data.types as string[]) ?? [];\n for (const t of types) {\n state.subscriptions.delete(t);\n }\n socket.send(\n JSON.stringify({\n type: 'unsubscribed',\n data: { subscriptions: Array.from(state.subscriptions) },\n })\n );\n }\n break;\n\n case 'add':\n // Add a memory via WebSocket\n if (data && typeof data === 'object' && data.content) {\n const event = await fastify.aether.add({\n content: data.content as string,\n actor: data.actor as string | undefined,\n action: data.action as string | undefined,\n context: data.context as Record<string, unknown> | undefined,\n });\n socket.send(\n JSON.stringify({\n type: 'memory:added',\n data: event,\n })\n );\n }\n break;\n\n case 'trajectory:start':\n // Start a trajectory via WebSocket\n if (data && typeof data === 'object' && data.actor) {\n const trajectoryId = await fastify.aether.startTrajectory(\n data.actor as string,\n data.context as Record<string, unknown> | undefined\n );\n socket.send(\n JSON.stringify({\n type: 'trajectory:started',\n data: { id: trajectoryId, actor: data.actor },\n })\n );\n\n // Broadcast to trajectory subscribers\n broadcast('trajectory:started', { id: trajectoryId, actor: data.actor }, 'trajectory', data.actor as string);\n }\n break;\n\n case 'trajectory:end':\n // End a trajectory via WebSocket\n if (data && typeof data === 'object' && data.trajectoryId) {\n try {\n const trajectory = await fastify.aether.endTrajectory(\n data.trajectoryId as string,\n data.outcome as 'success' | 'failure' | 'partial' | undefined\n );\n socket.send(\n JSON.stringify({\n type: 'trajectory:ended',\n data: trajectory,\n })\n );\n\n // Broadcast to trajectory subscribers\n broadcast('trajectory:ended', trajectory, 'trajectory', trajectory.actor);\n } catch (err) {\n socket.send(\n JSON.stringify({\n type: 'error',\n data: { message: 'Failed to end trajectory' },\n })\n );\n }\n }\n break;\n\n case 'patterns:detect':\n // Detect patterns for an actor\n if (data && typeof data === 'object' && data.actor) {\n const patterns = await fastify.aether.detectPatterns(data.actor as string, {\n minFrequency: data.minFrequency as number | undefined,\n minConfidence: data.minConfidence as number | undefined,\n });\n socket.send(\n JSON.stringify({\n type: 'patterns:detected',\n data: { actor: data.actor, patterns },\n })\n );\n }\n break;\n\n case 'anomalies:detect':\n // Find anomalies for an actor\n if (data && typeof data === 'object' && data.actor) {\n const anomalies = await fastify.aether.findAnomalies(data.actor as string, {\n minDeviationScore: data.minDeviationScore as number | undefined,\n limit: data.limit as number | undefined,\n });\n socket.send(\n JSON.stringify({\n type: 'anomalies:detected',\n data: { actor: data.actor, anomalies },\n })\n );\n\n // Broadcast high-severity anomalies to subscribers\n const highSeverity = anomalies.filter((a) => a.severity === 'high');\n if (highSeverity.length > 0) {\n broadcast('anomalies:alert', { actor: data.actor, anomalies: highSeverity }, 'anomalies', data.actor as string);\n }\n }\n break;\n\n case 'predict':\n // Get predictions for next actions\n if (data && typeof data === 'object' && data.actor && data.eventId) {\n const predictions = await fastify.aether.predictNext(\n data.actor as string,\n data.eventId as string,\n { topK: data.topK as number | undefined }\n );\n socket.send(\n JSON.stringify({\n type: 'predictions',\n data: { actor: data.actor, eventId: data.eventId, predictions },\n })\n );\n }\n break;\n\n default:\n socket.send(\n JSON.stringify({\n type: 'error',\n data: { message: `Unknown message type: ${message.type}` },\n })\n );\n }\n } catch (err) {\n socket.send(\n JSON.stringify({\n type: 'error',\n data: { message: 'Invalid message format or operation failed' },\n })\n );\n }\n });\n\n // Handle disconnect\n socket.on('close', () => {\n clientStates.delete(socket);\n });\n });\n};\n","import { createServer } from './app.js';\nimport type { ServerConfig } from './config.js';\n\nexport async function startServer(config: ServerConfig): Promise<void> {\n const server = await createServer(config);\n\n const port = config.port ?? 3000;\n const host = config.host ?? '0.0.0.0';\n\n try {\n await server.listen({ port, host });\n console.log(`Aether server listening on http://${host}:${port}`);\n } catch (err) {\n server.log.error(err);\n process.exit(1);\n }\n\n // Handle graceful shutdown\n const shutdown = async () => {\n console.log('\\nShutting down...');\n await server.close();\n process.exit(0);\n };\n\n process.on('SIGINT', shutdown);\n process.on('SIGTERM', shutdown);\n}\n"],"mappings":"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","names":["z","z","z"]}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "aether-server",
3
- "version": "0.1.0",
3
+ "version": "1.0.0",
4
4
  "description": "REST/WebSocket server for Aether Memory Framework",
5
5
  "type": "module",
6
6
  "main": "./dist/index.js",
@@ -17,9 +17,11 @@
17
17
  "dependencies": {
18
18
  "fastify": "^4.25.0",
19
19
  "@fastify/cors": "^9.0.0",
20
+ "@fastify/static": "^7.0.0",
20
21
  "@fastify/websocket": "^9.0.0",
21
22
  "zod": "^3.22.0",
22
- "aether-core": "0.1.0"
23
+ "aether-core": "1.0.0",
24
+ "aether-react": "1.0.0"
23
25
  },
24
26
  "devDependencies": {
25
27
  "@types/node": "^20.10.0",