@remind_ai/remind 0.1.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.
Files changed (79) hide show
  1. package/LICENSE +6 -0
  2. package/README.md +127 -0
  3. package/dist/src/brain/consolidation.d.ts +3 -0
  4. package/dist/src/brain/consolidation.js +153 -0
  5. package/dist/src/brain/constants.d.ts +18 -0
  6. package/dist/src/brain/constants.js +26 -0
  7. package/dist/src/brain/encoding.d.ts +10 -0
  8. package/dist/src/brain/encoding.js +45 -0
  9. package/dist/src/brain/forgetting.d.ts +3 -0
  10. package/dist/src/brain/forgetting.js +48 -0
  11. package/dist/src/brain/index.d.ts +6 -0
  12. package/dist/src/brain/index.js +13 -0
  13. package/dist/src/brain/llm-deps.d.ts +8 -0
  14. package/dist/src/brain/llm-deps.js +4 -0
  15. package/dist/src/brain/selftest.d.ts +1 -0
  16. package/dist/src/brain/selftest.js +229 -0
  17. package/dist/src/brain/similarity.d.ts +10 -0
  18. package/dist/src/brain/similarity.js +65 -0
  19. package/dist/src/brain/temporal.d.ts +9 -0
  20. package/dist/src/brain/temporal.js +65 -0
  21. package/dist/src/brain/tiering.d.ts +9 -0
  22. package/dist/src/brain/tiering.js +39 -0
  23. package/dist/src/config.d.ts +36 -0
  24. package/dist/src/config.js +61 -0
  25. package/dist/src/core/index.d.ts +12 -0
  26. package/dist/src/core/index.js +31 -0
  27. package/dist/src/core/ingest.d.ts +2 -0
  28. package/dist/src/core/ingest.js +117 -0
  29. package/dist/src/core/memory-types.d.ts +45 -0
  30. package/dist/src/core/memory-types.js +104 -0
  31. package/dist/src/core/retrieval.d.ts +2 -0
  32. package/dist/src/core/retrieval.js +55 -0
  33. package/dist/src/core/stores/doc.store.d.ts +2 -0
  34. package/dist/src/core/stores/doc.store.js +74 -0
  35. package/dist/src/core/stores/graph.store.d.ts +2 -0
  36. package/dist/src/core/stores/graph.store.js +61 -0
  37. package/dist/src/core/stores/vector.store.d.ts +2 -0
  38. package/dist/src/core/stores/vector.store.js +87 -0
  39. package/dist/src/engine.d.ts +33 -0
  40. package/dist/src/engine.js +63 -0
  41. package/dist/src/ids.d.ts +1 -0
  42. package/dist/src/ids.js +6 -0
  43. package/dist/src/index.d.ts +19 -0
  44. package/dist/src/index.js +25 -0
  45. package/dist/src/llm.d.ts +8 -0
  46. package/dist/src/llm.js +68 -0
  47. package/dist/src/memguard/auditor.d.ts +19 -0
  48. package/dist/src/memguard/auditor.js +48 -0
  49. package/dist/src/memguard/canary.d.ts +49 -0
  50. package/dist/src/memguard/canary.js +73 -0
  51. package/dist/src/memguard/detectors/exfiltration.d.ts +3 -0
  52. package/dist/src/memguard/detectors/exfiltration.js +18 -0
  53. package/dist/src/memguard/detectors/pii.d.ts +12 -0
  54. package/dist/src/memguard/detectors/pii.js +32 -0
  55. package/dist/src/memguard/detectors/secrets.d.ts +9 -0
  56. package/dist/src/memguard/detectors/secrets.js +25 -0
  57. package/dist/src/memguard/firewall.d.ts +15 -0
  58. package/dist/src/memguard/firewall.js +93 -0
  59. package/dist/src/memguard/index.d.ts +26 -0
  60. package/dist/src/memguard/index.js +24 -0
  61. package/dist/src/memguard/output-filter.d.ts +6 -0
  62. package/dist/src/memguard/output-filter.js +10 -0
  63. package/dist/src/memguard/provenance.d.ts +10 -0
  64. package/dist/src/memguard/provenance.js +36 -0
  65. package/dist/src/memguard/trust.d.ts +27 -0
  66. package/dist/src/memguard/trust.js +53 -0
  67. package/dist/src/queue/connection.d.ts +6 -0
  68. package/dist/src/queue/connection.js +23 -0
  69. package/dist/src/queue/queues.d.ts +29 -0
  70. package/dist/src/queue/queues.js +64 -0
  71. package/dist/src/types.d.ts +97 -0
  72. package/dist/src/types.js +3 -0
  73. package/dist/src/workers/consolidate.worker.d.ts +5 -0
  74. package/dist/src/workers/consolidate.worker.js +15 -0
  75. package/dist/src/workers/forget.worker.d.ts +4 -0
  76. package/dist/src/workers/forget.worker.js +8 -0
  77. package/dist/src/workers/ingest.worker.d.ts +6 -0
  78. package/dist/src/workers/ingest.worker.js +36 -0
  79. package/package.json +46 -0
@@ -0,0 +1,36 @@
1
+ // REMind · L2 provenance · Owner: Prayash
2
+ // tag(record, source) + lineage(id): every belief traceable to its source memory. Powers the audit log.
3
+ /** id -> the sources/parents that produced it, for the audit log. */
4
+ const lineageMap = new Map();
5
+ /** Stamp a freshly drafted record with its origin source. */
6
+ export function tag(record, source, sourceId) {
7
+ const provenance = {
8
+ source: source || record.provenance?.source || 'unknown',
9
+ derivedFrom: record.provenance?.derivedFrom,
10
+ };
11
+ const tagged = {
12
+ ...record,
13
+ provenance,
14
+ sourceId: sourceId ?? record.sourceId,
15
+ };
16
+ lineageMap.set(tagged.id, [provenance.source, ...(provenance.derivedFrom ?? [])]);
17
+ return tagged;
18
+ }
19
+ /**
20
+ * Stamp a consolidated belief with the source records it was derived from so the
21
+ * auditor's decision is always traceable back to concrete memories.
22
+ */
23
+ export function tagDerived(record, sources) {
24
+ const derivedFrom = sources.map((s) => s.id);
25
+ const provenance = {
26
+ source: record.provenance?.source || 'consolidation',
27
+ derivedFrom,
28
+ };
29
+ const tagged = { ...record, provenance };
30
+ lineageMap.set(tagged.id, derivedFrom);
31
+ return tagged;
32
+ }
33
+ /** Look up the recorded lineage for a record id (sources / parent ids). */
34
+ export function lineage(id) {
35
+ return lineageMap.get(id) ?? [];
36
+ }
@@ -0,0 +1,27 @@
1
+ import type { MemoryRecord } from '../types.js';
2
+ /** Below this, a record is quarantined at ingest. */
3
+ export declare const QUARANTINE_THRESHOLD = 0.4;
4
+ /** A consolidation source at/under this trust taints any belief derived from it. */
5
+ export declare const LOW_TRUST_SOURCE = 0.5;
6
+ /** Minimum trust for a record to reach the agent via onOutput. */
7
+ export declare const OUTPUT_MIN_TRUST = 0.4;
8
+ export interface TrustSignals {
9
+ source?: string;
10
+ isInstruction?: boolean;
11
+ hasSecrets?: boolean;
12
+ hasPII?: boolean;
13
+ hasExfiltration?: boolean;
14
+ }
15
+ /**
16
+ * Score a record's trustworthiness in 0..1 from its source and detector signals.
17
+ * Conservative by design: any attempt to command the agent or smuggle data out
18
+ * collapses trust well below the quarantine line.
19
+ */
20
+ export declare function scoreTrust(_record: MemoryRecord, signals: TrustSignals): number;
21
+ /**
22
+ * Mark a record quarantined: it is retained for audit/lineage but is never
23
+ * surfaced to the agent and can never be promoted into a belief.
24
+ */
25
+ export declare function quarantine(record: MemoryRecord): MemoryRecord;
26
+ /** Whether a record is safe to use as trusted material (not quarantined, above floor). */
27
+ export declare function isTrusted(record: MemoryRecord, floor?: number): boolean;
@@ -0,0 +1,53 @@
1
+ // REMind · L2 trust + quarantine · Owner: Prayash
2
+ // score(record, signals) -> 0..1 trust; quarantine(record) -> kept for audit, never surfaced or promoted.
3
+ /** Below this, a record is quarantined at ingest. */
4
+ export const QUARANTINE_THRESHOLD = 0.4;
5
+ /** A consolidation source at/under this trust taints any belief derived from it. */
6
+ export const LOW_TRUST_SOURCE = 0.5;
7
+ /** Minimum trust for a record to reach the agent via onOutput. */
8
+ export const OUTPUT_MIN_TRUST = 0.4;
9
+ /** Baseline trust by declared source. Unknown/web sources start skeptical. */
10
+ const SOURCE_BASE = {
11
+ system: 0.95,
12
+ user: 0.8,
13
+ tool: 0.6,
14
+ agent: 0.6,
15
+ import: 0.5,
16
+ web: 0.45,
17
+ unknown: 0.5,
18
+ };
19
+ function clamp(n) {
20
+ return Math.max(0, Math.min(1, n));
21
+ }
22
+ /**
23
+ * Score a record's trustworthiness in 0..1 from its source and detector signals.
24
+ * Conservative by design: any attempt to command the agent or smuggle data out
25
+ * collapses trust well below the quarantine line.
26
+ */
27
+ export function scoreTrust(_record, signals) {
28
+ let trust = SOURCE_BASE[(signals.source ?? 'unknown').toLowerCase()] ?? 0.5;
29
+ if (signals.isInstruction)
30
+ trust -= 0.6;
31
+ if (signals.hasExfiltration)
32
+ trust -= 0.5;
33
+ if (signals.hasSecrets)
34
+ trust -= 0.4;
35
+ if (signals.hasPII)
36
+ trust -= 0.15;
37
+ return clamp(trust);
38
+ }
39
+ /**
40
+ * Mark a record quarantined: it is retained for audit/lineage but is never
41
+ * surfaced to the agent and can never be promoted into a belief.
42
+ */
43
+ export function quarantine(record) {
44
+ return {
45
+ ...record,
46
+ quarantined: true,
47
+ trust: Math.min(record.trust ?? 0, QUARANTINE_THRESHOLD - 0.01),
48
+ };
49
+ }
50
+ /** Whether a record is safe to use as trusted material (not quarantined, above floor). */
51
+ export function isTrusted(record, floor = LOW_TRUST_SOURCE) {
52
+ return !record.quarantined && (record.trust ?? 0) >= floor;
53
+ }
@@ -0,0 +1,6 @@
1
+ import { Redis } from 'ioredis';
2
+ /** Use real BullMQ/Redis only when a Redis URL is configured AND we are not forcing inline (SYNC) mode. */
3
+ export declare function useRedis(): boolean;
4
+ /** Lazily open one shared ioredis connection (BullMQ requires maxRetriesPerRequest: null). */
5
+ export declare function getConnection(): Redis;
6
+ export declare function closeConnection(): Promise<void>;
@@ -0,0 +1,23 @@
1
+ // REMind · Queue connection · Owner: Yasho
2
+ // One shared Redis connection (Azure Cache for Redis) for BullMQ when REDIS_URL is set;
3
+ // otherwise the queues fall back to an inline in-process shim with the same .add() API.
4
+ import { Redis } from 'ioredis';
5
+ import { config } from '../config.js';
6
+ /** Use real BullMQ/Redis only when a Redis URL is configured AND we are not forcing inline (SYNC) mode. */
7
+ export function useRedis() {
8
+ return Boolean(config.redis.url) && !config.sync;
9
+ }
10
+ let connection = null;
11
+ /** Lazily open one shared ioredis connection (BullMQ requires maxRetriesPerRequest: null). */
12
+ export function getConnection() {
13
+ if (!connection) {
14
+ connection = new Redis(config.redis.url, { maxRetriesPerRequest: null });
15
+ }
16
+ return connection;
17
+ }
18
+ export async function closeConnection() {
19
+ if (connection) {
20
+ await connection.quit();
21
+ connection = null;
22
+ }
23
+ }
@@ -0,0 +1,29 @@
1
+ import type { IngestInput, MemoryRecord } from '../types.js';
2
+ export type Processor<T> = (data: T) => Promise<void>;
3
+ export interface JobQueue<T> {
4
+ readonly name: string;
5
+ add(data: T): Promise<void>;
6
+ process(handler: Processor<T>): void;
7
+ close(): Promise<void>;
8
+ }
9
+ export interface IngestJob {
10
+ input: IngestInput;
11
+ }
12
+ export interface ConsolidateJob {
13
+ agentId: string;
14
+ }
15
+ export interface ForgetJob {
16
+ agentId: string;
17
+ }
18
+ export interface QuarantineJob {
19
+ record: MemoryRecord;
20
+ reason: string;
21
+ }
22
+ export interface Queues {
23
+ ingest: JobQueue<IngestJob>;
24
+ consolidate: JobQueue<ConsolidateJob>;
25
+ forget: JobQueue<ForgetJob>;
26
+ quarantine: JobQueue<QuarantineJob>;
27
+ }
28
+ /** Build the four queues with the active backend. Call once and share the instances. */
29
+ export declare function createQueues(): Queues;
@@ -0,0 +1,64 @@
1
+ // REMind · Queue definitions · Owner: Yasho
2
+ // A tiny JobQueue abstraction with two backends: BullMQ over Azure Cache for Redis
3
+ // (durable, retried, crash-safe) and an inline in-process shim (SYNC / no-Redis) that runs
4
+ // the processor immediately. ingest / consolidate / forget / quarantine share the API.
5
+ import { Queue, Worker } from 'bullmq';
6
+ import { getConnection, useRedis } from './connection.js';
7
+ /** Inline backend: add() runs the registered processor right away (deterministic, no Redis). */
8
+ class InlineQueue {
9
+ name;
10
+ handler;
11
+ constructor(name) {
12
+ this.name = name;
13
+ }
14
+ process(handler) {
15
+ this.handler = handler;
16
+ }
17
+ async add(data) {
18
+ if (!this.handler)
19
+ throw new Error(`inline queue "${this.name}" has no processor`);
20
+ await this.handler(data);
21
+ }
22
+ async close() {
23
+ /* nothing to release */
24
+ }
25
+ }
26
+ /** BullMQ backend over Azure Cache for Redis: durable, retried, crash-safe. */
27
+ class RedisQueue {
28
+ name;
29
+ queue;
30
+ worker;
31
+ constructor(name) {
32
+ this.name = name;
33
+ this.queue = new Queue(name, { connection: getConnection() });
34
+ }
35
+ process(handler) {
36
+ this.worker = new Worker(this.name, (job) => handler(job.data), {
37
+ connection: getConnection(),
38
+ });
39
+ }
40
+ async add(data) {
41
+ await this.queue.add(this.name, data, {
42
+ removeOnComplete: true,
43
+ removeOnFail: 100,
44
+ attempts: 3,
45
+ backoff: { type: 'exponential', delay: 1000 },
46
+ });
47
+ }
48
+ async close() {
49
+ await this.worker?.close();
50
+ await this.queue.close();
51
+ }
52
+ }
53
+ function makeQueue(name) {
54
+ return useRedis() ? new RedisQueue(name) : new InlineQueue(name);
55
+ }
56
+ /** Build the four queues with the active backend. Call once and share the instances. */
57
+ export function createQueues() {
58
+ return {
59
+ ingest: makeQueue('remind-ingest'),
60
+ consolidate: makeQueue('remind-consolidate'),
61
+ forget: makeQueue('remind-forget'),
62
+ quarantine: makeQueue('remind-quarantine'),
63
+ };
64
+ }
@@ -0,0 +1,97 @@
1
+ export type MemoryType = 'episodic' | 'factual' | 'short' | 'working' | 'procedural';
2
+ export type Tier = 'hot' | 'warm' | 'cold';
3
+ export interface Provenance {
4
+ source: string;
5
+ derivedFrom?: string[];
6
+ }
7
+ /** A knowledge-graph edge extracted from an episodic memory. */
8
+ export interface Triple {
9
+ subject: string;
10
+ relation: string;
11
+ object: string;
12
+ }
13
+ export interface MemoryRecord {
14
+ id: string;
15
+ agentId: string;
16
+ type: MemoryType;
17
+ content: string;
18
+ embedding?: number[];
19
+ triples?: Triple[];
20
+ trust: number;
21
+ confidence: number;
22
+ provenance: Provenance;
23
+ validFrom?: string;
24
+ validTo?: string;
25
+ tier: Tier;
26
+ quarantined?: boolean;
27
+ sourceId?: string;
28
+ createdAt: string;
29
+ lastUsedAt?: string;
30
+ }
31
+ export interface IngestInput {
32
+ agentId: string;
33
+ messages: {
34
+ user: string;
35
+ assistant: string;
36
+ };
37
+ source?: string;
38
+ sourceId?: string;
39
+ }
40
+ export interface RetrievalResult {
41
+ context: string;
42
+ records: MemoryRecord[];
43
+ facts: string[];
44
+ }
45
+ export interface ConsolidationReport {
46
+ promoted: MemoryRecord[];
47
+ blocked: {
48
+ record: MemoryRecord;
49
+ reason: string;
50
+ }[];
51
+ merged: number;
52
+ }
53
+ export interface VectorStore {
54
+ upsert(record: MemoryRecord): Promise<void>;
55
+ search(agentId: string, query: string, k?: number, sourceId?: string): Promise<MemoryRecord[]>;
56
+ }
57
+ export interface GraphStore {
58
+ writeTriples(agentId: string, triples: Triple[]): Promise<void>;
59
+ fetchGraph(agentId: string): Promise<string>;
60
+ }
61
+ export interface DocStore {
62
+ pushFact(agentId: string, fact: string): Promise<void>;
63
+ getFacts(agentId: string): Promise<string[]>;
64
+ saveRecord(record: MemoryRecord): Promise<void>;
65
+ getRecords(agentId: string, filter?: Record<string, unknown>): Promise<MemoryRecord[]>;
66
+ }
67
+ export interface Stores {
68
+ vector: VectorStore;
69
+ graph: GraphStore;
70
+ doc: DocStore;
71
+ }
72
+ export interface MemoryEngineCore {
73
+ draft(input: IngestInput): Promise<MemoryRecord | null>;
74
+ persist(record: MemoryRecord): Promise<MemoryRecord>;
75
+ fetchMemory(agentId: string, query: string, sourceId?: string): Promise<RetrievalResult>;
76
+ }
77
+ export type PromotionGate = (candidate: MemoryRecord, from: MemoryRecord[]) => Promise<{
78
+ promote: boolean;
79
+ reason?: string;
80
+ }>;
81
+ export interface Brain {
82
+ consolidate(agentId: string, stores: Stores, gate: PromotionGate): Promise<ConsolidationReport>;
83
+ decay(agentId: string, stores: Stores): Promise<void>;
84
+ }
85
+ export interface MemGuardHooks {
86
+ onIngest(input: IngestInput, draft: MemoryRecord): Promise<{
87
+ allow: boolean;
88
+ record: MemoryRecord;
89
+ reason?: string;
90
+ }>;
91
+ onConsolidate: PromotionGate;
92
+ onOutput(records: MemoryRecord[]): Promise<MemoryRecord[]>;
93
+ checkCanaries(): Promise<{
94
+ drift: boolean;
95
+ details: string;
96
+ }>;
97
+ }
@@ -0,0 +1,3 @@
1
+ // REMind · Frozen Contract · Owner: Yasho
2
+ // Shared types + the three seam interfaces. The only file all four layers import.
3
+ export {};
@@ -0,0 +1,5 @@
1
+ import type { ConsolidationReport } from '../types.js';
2
+ import type { Layers } from '../engine.js';
3
+ import type { Queues } from '../queue/queues.js';
4
+ export declare function runConsolidate(layers: Layers, agentId: string): Promise<ConsolidationReport>;
5
+ export declare function registerConsolidateWorker(queues: Queues, layers: Layers): void;
@@ -0,0 +1,15 @@
1
+ // REMind · Consolidate worker (consumer) · Owner: Yasho
2
+ // The sleep cycle in sequence: guard.checkCanaries (before) -> brain.consolidate (each
3
+ // candidate gated by guard.onConsolidate) -> guard.checkCanaries (after). Returns the report so
4
+ // SYNC-mode callers can inspect it; in async mode BullMQ retries the whole job on crash.
5
+ export async function runConsolidate(layers, agentId) {
6
+ await layers.guard.checkCanaries();
7
+ const report = await layers.brain.consolidate(agentId, layers.stores, layers.guard.onConsolidate);
8
+ await layers.guard.checkCanaries();
9
+ return report;
10
+ }
11
+ export function registerConsolidateWorker(queues, layers) {
12
+ queues.consolidate.process(async ({ agentId }) => {
13
+ await runConsolidate(layers, agentId);
14
+ });
15
+ }
@@ -0,0 +1,4 @@
1
+ import type { Layers } from '../engine.js';
2
+ import type { Queues } from '../queue/queues.js';
3
+ export declare function runForget(layers: Layers, agentId: string): Promise<void>;
4
+ export declare function registerForgetWorker(queues: Queues, layers: Layers): void;
@@ -0,0 +1,8 @@
1
+ // REMind · Forget worker (repeatable) · Owner: Yasho
2
+ // Scheduled/idle decay pass -> brain.decay(agentId, stores). Idempotent: safe to repeat.
3
+ export async function runForget(layers, agentId) {
4
+ await layers.brain.decay(agentId, layers.stores);
5
+ }
6
+ export function registerForgetWorker(queues, layers) {
7
+ queues.forget.process(({ agentId }) => runForget(layers, agentId));
8
+ }
@@ -0,0 +1,6 @@
1
+ import type { IngestInput } from '../types.js';
2
+ import type { Layers } from '../engine.js';
3
+ import type { Queues } from '../queue/queues.js';
4
+ export declare function runIngest(layers: Layers, queues: Queues, input: IngestInput): Promise<void>;
5
+ /** Attach the ingest + quarantine (dead-letter) processors to their queues. */
6
+ export declare function registerIngestWorker(queues: Queues, layers: Layers): void;
@@ -0,0 +1,36 @@
1
+ // REMind · Ingest worker (consumer) · Owner: Yasho
2
+ // The one place the write pipeline runs in sequence: core.draft -> guard.onIngest ->
3
+ // (allow) core.persist | (block) quarantine. Then bump a per-agent write-count and enqueue
4
+ // a consolidate cycle at the threshold. Pure orchestration; layers make it retry-safe.
5
+ const CONSOLIDATE_THRESHOLD = 5;
6
+ const writeCounts = new Map();
7
+ export async function runIngest(layers, queues, input) {
8
+ const draft = await layers.core.draft(input);
9
+ if (!draft)
10
+ return; // not salient — nothing to store
11
+ const verdict = await layers.guard.onIngest(input, draft);
12
+ if (!verdict.allow) {
13
+ await queues.quarantine.add({
14
+ record: { ...verdict.record, quarantined: true },
15
+ reason: verdict.reason ?? 'blocked by ingest firewall',
16
+ });
17
+ return;
18
+ }
19
+ await layers.core.persist(verdict.record);
20
+ const next = (writeCounts.get(input.agentId) ?? 0) + 1;
21
+ if (next >= CONSOLIDATE_THRESHOLD) {
22
+ writeCounts.set(input.agentId, 0);
23
+ await queues.consolidate.add({ agentId: input.agentId });
24
+ }
25
+ else {
26
+ writeCounts.set(input.agentId, next);
27
+ }
28
+ }
29
+ /** Attach the ingest + quarantine (dead-letter) processors to their queues. */
30
+ export function registerIngestWorker(queues, layers) {
31
+ queues.ingest.process(({ input }) => runIngest(layers, queues, input));
32
+ queues.quarantine.process(async ({ record }) => {
33
+ // Persist quarantined records (never promoted) so the audit trail keeps the evidence.
34
+ await layers.stores.doc.saveRecord({ ...record, quarantined: true });
35
+ });
36
+ }
package/package.json ADDED
@@ -0,0 +1,46 @@
1
+ {
2
+ "name": "@remind_ai/remind",
3
+ "version": "0.1.0",
4
+ "description": "Brain-inspired AI-agent memory SDK with the MemGuard security layer.",
5
+ "type": "module",
6
+ "main": "dist/src/index.js",
7
+ "types": "dist/src/index.d.ts",
8
+ "files": ["dist/src"],
9
+ "publishConfig": { "access": "public" },
10
+ "scripts": {
11
+ "build": "tsc",
12
+ "prepublishOnly": "npm run build",
13
+ "typecheck": "tsc --noEmit",
14
+ "doctor": "tsx examples/doctor.ts",
15
+ "demo": "tsx examples/poison-demo.ts",
16
+ "demo:core": "tsx examples/core-demo.ts",
17
+ "demo:brain": "tsx examples/brain-demo.ts",
18
+ "bench:attack": "tsx benchmark/attack.ts",
19
+ "bench:retrieval": "tsx benchmark/retrieval.ts",
20
+ "start": "node dist/server/http.js"
21
+ },
22
+ "keywords": ["ai", "agent", "memory", "llm", "security", "memguard", "azure", "rag", "vector", "knowledge-graph"],
23
+ "license": "MIT",
24
+ "author": "remind_ai",
25
+ "homepage": "https://github.com/t-yassingh_microsoft/REMind-AI#readme",
26
+ "repository": { "type": "git", "url": "git+https://github.com/t-yassingh_microsoft/REMind-AI.git" },
27
+ "bugs": { "url": "https://github.com/t-yassingh_microsoft/REMind-AI/issues" },
28
+ "engines": { "node": ">=20" },
29
+ "dependencies": {
30
+ "@azure/search-documents": "^12.1.0",
31
+ "bullmq": "^5.13.0",
32
+ "dotenv": "^16.4.5",
33
+ "gremlin": "^3.7.2",
34
+ "ioredis": "^5.4.1",
35
+ "mongoose": "^8.6.0",
36
+ "openai": "^4.67.0"
37
+ },
38
+ "devDependencies": {
39
+ "@types/node": "^22.7.0",
40
+ "tsx": "^4.19.0",
41
+ "typescript": "^5.6.0"
42
+ },
43
+ "overrides": {
44
+ "uuid": "^11.1.1"
45
+ }
46
+ }