mnemocyte 0.1.3 → 0.1.5
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +34 -7
- package/dist/embedders/index.d.mts +2 -0
- package/dist/embedders/index.mjs +2 -0
- package/dist/embedders/openai.d.mts +31 -0
- package/dist/embedders/openai.d.mts.map +1 -0
- package/dist/embedders/openai.mjs +78 -0
- package/dist/embedders/openai.mjs.map +1 -0
- package/dist/errors-BG3-mNur.mjs +53 -0
- package/dist/errors-BG3-mNur.mjs.map +1 -0
- package/dist/index.d.mts +2 -843
- package/dist/index.d.mts.map +1 -1
- package/dist/index.mjs +8 -50
- package/dist/index.mjs.map +1 -1
- package/dist/types-QK_43oKJ.d.mts +845 -0
- package/dist/types-QK_43oKJ.d.mts.map +1 -0
- package/package.json +12 -3
package/README.md
CHANGED
|
@@ -85,7 +85,21 @@ const client = createMnemocyte({
|
|
|
85
85
|
});
|
|
86
86
|
```
|
|
87
87
|
|
|
88
|
-
|
|
88
|
+
You can also use the optional OpenAI helper:
|
|
89
|
+
|
|
90
|
+
```ts
|
|
91
|
+
import { openaiEmbedder } from "mnemocyte/embedders";
|
|
92
|
+
|
|
93
|
+
const embedder = openaiEmbedder({
|
|
94
|
+
model: "text-embedding-3-small",
|
|
95
|
+
});
|
|
96
|
+
```
|
|
97
|
+
|
|
98
|
+
`openaiEmbedder()` reads `OPENAI_API_KEY` by default. Pass `apiKey`
|
|
99
|
+
explicitly when you use a different key source. The helper uses `fetch`
|
|
100
|
+
directly and does not depend on the OpenAI SDK; plain `import "mnemocyte"` also
|
|
101
|
+
stays provider-free. The direct subpath `mnemocyte/embedders/openai` is also
|
|
102
|
+
supported for consumers that prefer provider-specific imports.
|
|
89
103
|
|
|
90
104
|
## Postgres
|
|
91
105
|
|
|
@@ -111,8 +125,23 @@ backend currently requires a 1536-dimensional embedder.
|
|
|
111
125
|
If dimensions do not match, `createMnemocyte` throws a `MnemocyteError` with
|
|
112
126
|
code `"CONFIG"` before opening the connection pool.
|
|
113
127
|
|
|
114
|
-
The migration creates
|
|
115
|
-
|
|
128
|
+
The migration creates the bundled HNSW pgvector index
|
|
129
|
+
`mnemocyte_memories_embedding_hnsw_idx` for cosine search. HNSW is approximate:
|
|
130
|
+
it is fast for nearest-neighbor recall, but recall quality, index build memory,
|
|
131
|
+
and write overhead should be benchmarked against your data volume and write
|
|
132
|
+
rate. Postgres still applies ordinary filters such as `entity_id`, `type`, and
|
|
133
|
+
tags around vector search, so highly selective filters may need query tuning or
|
|
134
|
+
a workload-specific index strategy.
|
|
135
|
+
|
|
136
|
+
Large production tables should benchmark alternate indexes or custom
|
|
137
|
+
migrations with representative data before changing the default. IVFFlat can be
|
|
138
|
+
a good fit for some large, steady-state tables, but it needs tuning after the
|
|
139
|
+
table has representative vectors. The bundled migration intentionally does not
|
|
140
|
+
add full-text or tag-specific GIN indexes yet; add and benchmark expression
|
|
141
|
+
indexes such as `to_tsvector('english', content)` or tag-oriented indexes only
|
|
142
|
+
when your workload needs them.
|
|
143
|
+
|
|
144
|
+
Configurable embedding dimensions are planned for `0.2.0`.
|
|
116
145
|
|
|
117
146
|
## API
|
|
118
147
|
|
|
@@ -262,12 +291,10 @@ const client = createMnemocyte({
|
|
|
262
291
|
|
|
263
292
|
## Roadmap
|
|
264
293
|
|
|
265
|
-
|
|
294
|
+
Planned larger milestones:
|
|
266
295
|
|
|
267
|
-
- production safety and HNSW documentation
|
|
268
|
-
- official `openaiEmbedder()`
|
|
269
296
|
- configurable embedding dimensions with `mnemocyte_meta`
|
|
270
|
-
- `
|
|
297
|
+
- `MemoryStore` abstraction
|
|
271
298
|
- `drizzleStore(db)` for caller-owned Drizzle clients
|
|
272
299
|
- `@mnemocyte/mcp`
|
|
273
300
|
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
import { c as Embedder } from "../types-QK_43oKJ.mjs";
|
|
2
|
+
|
|
3
|
+
//#region src/embedders/openai.d.ts
|
|
4
|
+
interface OpenAIEmbedderOptions {
|
|
5
|
+
/**
|
|
6
|
+
* OpenAI API key. Defaults to `process.env.OPENAI_API_KEY`.
|
|
7
|
+
*/
|
|
8
|
+
readonly apiKey?: string;
|
|
9
|
+
/**
|
|
10
|
+
* OpenAI embedding model name.
|
|
11
|
+
*/
|
|
12
|
+
readonly model: string;
|
|
13
|
+
/**
|
|
14
|
+
* Output dimensions. Required for unknown/future model names and accepted
|
|
15
|
+
* only for OpenAI models that support configurable dimensions.
|
|
16
|
+
*/
|
|
17
|
+
readonly dimensions?: number;
|
|
18
|
+
/**
|
|
19
|
+
* Override the OpenAI API base URL. Intended for tests and compatible
|
|
20
|
+
* deployments; defaults to `https://api.openai.com/v1`.
|
|
21
|
+
*/
|
|
22
|
+
readonly baseUrl?: string;
|
|
23
|
+
}
|
|
24
|
+
/**
|
|
25
|
+
* Create an OpenAI-backed {@link Embedder}. This adapter uses `fetch`
|
|
26
|
+
* directly so provider SDKs never become part of Mnemocyte's dependency graph.
|
|
27
|
+
*/
|
|
28
|
+
declare function openaiEmbedder(options: OpenAIEmbedderOptions): Embedder;
|
|
29
|
+
//#endregion
|
|
30
|
+
export { OpenAIEmbedderOptions, openaiEmbedder };
|
|
31
|
+
//# sourceMappingURL=openai.d.mts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"openai.d.mts","names":[],"sources":["../../src/embedders/openai.ts"],"mappings":";;;UAciB,qBAAA;;AAAjB;;WAIU,MAAA;EAJ4B;;;EAAA,SAQ5B,KAAA;EAUA;;AAAO;AA4EjB;EA5EU,SALA,UAAA;;;;;WAKA,OAAA;AAAA;AA4E8D;;;;AAAA,iBAAxD,cAAA,CAAe,OAAA,EAAS,qBAAA,GAAwB,QAAQ"}
|
|
@@ -0,0 +1,78 @@
|
|
|
1
|
+
import { t as MnemocyteError } from "../errors-BG3-mNur.mjs";
|
|
2
|
+
//#region src/embedders/openai.ts
|
|
3
|
+
const KNOWN_MODEL_DIMENSIONS = {
|
|
4
|
+
"text-embedding-3-small": 1536,
|
|
5
|
+
"text-embedding-3-large": 3072,
|
|
6
|
+
"text-embedding-ada-002": 1536
|
|
7
|
+
};
|
|
8
|
+
const CONFIGURABLE_DIMENSION_MODELS = new Set(["text-embedding-3-small", "text-embedding-3-large"]);
|
|
9
|
+
function assertDimensions(dimensions) {
|
|
10
|
+
if (!Number.isInteger(dimensions) || dimensions < 1) throw new MnemocyteError("openaiEmbedder dimensions must be a positive integer.", "CONFIG");
|
|
11
|
+
}
|
|
12
|
+
function resolveApiKey(apiKey) {
|
|
13
|
+
const resolved = apiKey ?? process.env.OPENAI_API_KEY;
|
|
14
|
+
if (!resolved || resolved.trim().length === 0) throw new MnemocyteError("openaiEmbedder requires an API key. Pass apiKey or set OPENAI_API_KEY.", "CONFIG");
|
|
15
|
+
return resolved;
|
|
16
|
+
}
|
|
17
|
+
function resolveDimensions(options) {
|
|
18
|
+
const defaultDimensions = KNOWN_MODEL_DIMENSIONS[options.model];
|
|
19
|
+
if (defaultDimensions === void 0) {
|
|
20
|
+
if (options.dimensions === void 0) throw new MnemocyteError(`openaiEmbedder requires dimensions for unknown model "${options.model}".`, "CONFIG");
|
|
21
|
+
assertDimensions(options.dimensions);
|
|
22
|
+
return {
|
|
23
|
+
embedderDimensions: options.dimensions,
|
|
24
|
+
requestDimensions: options.dimensions
|
|
25
|
+
};
|
|
26
|
+
}
|
|
27
|
+
if (options.dimensions !== void 0 && !CONFIGURABLE_DIMENSION_MODELS.has(options.model)) throw new MnemocyteError(`openaiEmbedder does not support a dimensions override for "${options.model}".`, "CONFIG");
|
|
28
|
+
if (options.dimensions !== void 0) {
|
|
29
|
+
assertDimensions(options.dimensions);
|
|
30
|
+
return {
|
|
31
|
+
embedderDimensions: options.dimensions,
|
|
32
|
+
requestDimensions: options.dimensions
|
|
33
|
+
};
|
|
34
|
+
}
|
|
35
|
+
return { embedderDimensions: defaultDimensions };
|
|
36
|
+
}
|
|
37
|
+
/**
|
|
38
|
+
* Create an OpenAI-backed {@link Embedder}. This adapter uses `fetch`
|
|
39
|
+
* directly so provider SDKs never become part of Mnemocyte's dependency graph.
|
|
40
|
+
*/
|
|
41
|
+
function openaiEmbedder(options) {
|
|
42
|
+
const apiKey = resolveApiKey(options.apiKey);
|
|
43
|
+
const { embedderDimensions, requestDimensions } = resolveDimensions(options);
|
|
44
|
+
const baseUrl = options.baseUrl ?? "https://api.openai.com/v1";
|
|
45
|
+
return {
|
|
46
|
+
model: options.model,
|
|
47
|
+
dimensions: embedderDimensions,
|
|
48
|
+
async embed(texts, embedOptions) {
|
|
49
|
+
const response = await fetch(`${baseUrl}/embeddings`, {
|
|
50
|
+
method: "POST",
|
|
51
|
+
headers: {
|
|
52
|
+
authorization: `Bearer ${apiKey}`,
|
|
53
|
+
"content-type": "application/json"
|
|
54
|
+
},
|
|
55
|
+
body: JSON.stringify({
|
|
56
|
+
model: options.model,
|
|
57
|
+
input: [...texts],
|
|
58
|
+
encoding_format: "float",
|
|
59
|
+
...requestDimensions === void 0 ? {} : { dimensions: requestDimensions }
|
|
60
|
+
}),
|
|
61
|
+
...embedOptions?.signal === void 0 ? {} : { signal: embedOptions.signal }
|
|
62
|
+
});
|
|
63
|
+
if (!response.ok) throw Object.assign(/* @__PURE__ */ new Error(`OpenAI embeddings request failed with status ${response.status}.`), { status: response.status });
|
|
64
|
+
const body = await response.json();
|
|
65
|
+
const embeddings = Array.from({ length: texts.length });
|
|
66
|
+
for (const item of body.data) {
|
|
67
|
+
if (!Number.isInteger(item.index) || item.index < 0 || item.index >= texts.length) throw new MnemocyteError("OpenAI returned an embedding with an invalid index.", "EMBEDDING");
|
|
68
|
+
embeddings[item.index] = item.embedding;
|
|
69
|
+
}
|
|
70
|
+
if (embeddings.some((embedding) => embedding === void 0)) throw new MnemocyteError("OpenAI returned fewer embeddings than requested.", "EMBEDDING");
|
|
71
|
+
return embeddings;
|
|
72
|
+
}
|
|
73
|
+
};
|
|
74
|
+
}
|
|
75
|
+
//#endregion
|
|
76
|
+
export { openaiEmbedder };
|
|
77
|
+
|
|
78
|
+
//# sourceMappingURL=openai.mjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"openai.mjs","names":[],"sources":["../../src/embedders/openai.ts"],"sourcesContent":["import { MnemocyteError } from \"../errors.js\";\nimport type { Embedder } from \"../types.js\";\n\nconst KNOWN_MODEL_DIMENSIONS: Record<string, number> = {\n\t\"text-embedding-3-small\": 1536,\n\t\"text-embedding-3-large\": 3072,\n\t\"text-embedding-ada-002\": 1536,\n};\n\nconst CONFIGURABLE_DIMENSION_MODELS = new Set([\n\t\"text-embedding-3-small\",\n\t\"text-embedding-3-large\",\n]);\n\nexport interface OpenAIEmbedderOptions {\n\t/**\n\t * OpenAI API key. Defaults to `process.env.OPENAI_API_KEY`.\n\t */\n\treadonly apiKey?: string;\n\t/**\n\t * OpenAI embedding model name.\n\t */\n\treadonly model: string;\n\t/**\n\t * Output dimensions. Required for unknown/future model names and accepted\n\t * only for OpenAI models that support configurable dimensions.\n\t */\n\treadonly dimensions?: number;\n\t/**\n\t * Override the OpenAI API base URL. Intended for tests and compatible\n\t * deployments; defaults to `https://api.openai.com/v1`.\n\t */\n\treadonly baseUrl?: string;\n}\n\ninterface OpenAIEmbeddingItem {\n\treadonly embedding: number[];\n\treadonly index: number;\n}\n\ninterface OpenAIEmbeddingResponse {\n\treadonly data: OpenAIEmbeddingItem[];\n}\n\nfunction assertDimensions(dimensions: number): void {\n\tif (!Number.isInteger(dimensions) || dimensions < 1) {\n\t\tthrow new MnemocyteError(\n\t\t\t\"openaiEmbedder dimensions must be a positive integer.\",\n\t\t\t\"CONFIG\",\n\t\t);\n\t}\n}\n\nfunction resolveApiKey(apiKey: string | undefined): string {\n\tconst resolved = apiKey ?? process.env.OPENAI_API_KEY;\n\tif (!resolved || resolved.trim().length === 0) {\n\t\tthrow new MnemocyteError(\n\t\t\t\"openaiEmbedder requires an API key. Pass apiKey or set OPENAI_API_KEY.\",\n\t\t\t\"CONFIG\",\n\t\t);\n\t}\n\treturn resolved;\n}\n\nfunction resolveDimensions(options: OpenAIEmbedderOptions): {\n\tembedderDimensions: number;\n\trequestDimensions?: number;\n} {\n\tconst defaultDimensions = KNOWN_MODEL_DIMENSIONS[options.model];\n\tif (defaultDimensions === undefined) {\n\t\tif (options.dimensions === undefined) {\n\t\t\tthrow new MnemocyteError(\n\t\t\t\t`openaiEmbedder requires dimensions for unknown model \"${options.model}\".`,\n\t\t\t\t\"CONFIG\",\n\t\t\t);\n\t\t}\n\t\tassertDimensions(options.dimensions);\n\t\treturn {\n\t\t\tembedderDimensions: options.dimensions,\n\t\t\trequestDimensions: options.dimensions,\n\t\t};\n\t}\n\n\tif (\n\t\toptions.dimensions !== undefined &&\n\t\t!CONFIGURABLE_DIMENSION_MODELS.has(options.model)\n\t) {\n\t\tthrow new MnemocyteError(\n\t\t\t`openaiEmbedder does not support a dimensions override for \"${options.model}\".`,\n\t\t\t\"CONFIG\",\n\t\t);\n\t}\n\n\tif (options.dimensions !== undefined) {\n\t\tassertDimensions(options.dimensions);\n\t\treturn {\n\t\t\tembedderDimensions: options.dimensions,\n\t\t\trequestDimensions: options.dimensions,\n\t\t};\n\t}\n\n\treturn { embedderDimensions: defaultDimensions };\n}\n\n/**\n * Create an OpenAI-backed {@link Embedder}. This adapter uses `fetch`\n * directly so provider SDKs never become part of Mnemocyte's dependency graph.\n */\nexport function openaiEmbedder(options: OpenAIEmbedderOptions): Embedder {\n\tconst apiKey = resolveApiKey(options.apiKey);\n\tconst { embedderDimensions, requestDimensions } = resolveDimensions(options);\n\tconst baseUrl = options.baseUrl ?? \"https://api.openai.com/v1\";\n\n\treturn {\n\t\tmodel: options.model,\n\t\tdimensions: embedderDimensions,\n\t\tasync embed(texts, embedOptions) {\n\t\t\tconst response = await fetch(`${baseUrl}/embeddings`, {\n\t\t\t\tmethod: \"POST\",\n\t\t\t\theaders: {\n\t\t\t\t\tauthorization: `Bearer ${apiKey}`,\n\t\t\t\t\t\"content-type\": \"application/json\",\n\t\t\t\t},\n\t\t\t\tbody: JSON.stringify({\n\t\t\t\t\tmodel: options.model,\n\t\t\t\t\tinput: [...texts],\n\t\t\t\t\tencoding_format: \"float\",\n\t\t\t\t\t...(requestDimensions === undefined\n\t\t\t\t\t\t? {}\n\t\t\t\t\t\t: { dimensions: requestDimensions }),\n\t\t\t\t}),\n\t\t\t\t...(embedOptions?.signal === undefined\n\t\t\t\t\t? {}\n\t\t\t\t\t: { signal: embedOptions.signal }),\n\t\t\t});\n\n\t\t\tif (!response.ok) {\n\t\t\t\tthrow Object.assign(\n\t\t\t\t\tnew Error(\n\t\t\t\t\t\t`OpenAI embeddings request failed with status ${response.status}.`,\n\t\t\t\t\t),\n\t\t\t\t\t{ status: response.status },\n\t\t\t\t);\n\t\t\t}\n\n\t\t\tconst body = (await response.json()) as OpenAIEmbeddingResponse;\n\n\t\t\tconst embeddings: Array<number[] | undefined> = Array.from({\n\t\t\t\tlength: texts.length,\n\t\t\t});\n\t\t\tfor (const item of body.data) {\n\t\t\t\tif (\n\t\t\t\t\t!Number.isInteger(item.index) ||\n\t\t\t\t\titem.index < 0 ||\n\t\t\t\t\titem.index >= texts.length\n\t\t\t\t) {\n\t\t\t\t\tthrow new MnemocyteError(\n\t\t\t\t\t\t\"OpenAI returned an embedding with an invalid index.\",\n\t\t\t\t\t\t\"EMBEDDING\",\n\t\t\t\t\t);\n\t\t\t\t}\n\t\t\t\tembeddings[item.index] = item.embedding;\n\t\t\t}\n\t\t\tif (embeddings.some((embedding) => embedding === undefined)) {\n\t\t\t\tthrow new MnemocyteError(\n\t\t\t\t\t\"OpenAI returned fewer embeddings than requested.\",\n\t\t\t\t\t\"EMBEDDING\",\n\t\t\t\t);\n\t\t\t}\n\t\t\treturn embeddings as number[][];\n\t\t},\n\t};\n}\n"],"mappings":";;AAGA,MAAM,yBAAiD;CACtD,0BAA0B;CAC1B,0BAA0B;CAC1B,0BAA0B;AAC3B;AAEA,MAAM,gCAAgC,IAAI,IAAI,CAC7C,0BACA,wBACD,CAAC;AAgCD,SAAS,iBAAiB,YAA0B;CACnD,IAAI,CAAC,OAAO,UAAU,UAAU,KAAK,aAAa,GACjD,MAAM,IAAI,eACT,yDACA,QACD;AAEF;AAEA,SAAS,cAAc,QAAoC;CAC1D,MAAM,WAAW,UAAU,QAAQ,IAAI;CACvC,IAAI,CAAC,YAAY,SAAS,KAAK,EAAE,WAAW,GAC3C,MAAM,IAAI,eACT,0EACA,QACD;CAED,OAAO;AACR;AAEA,SAAS,kBAAkB,SAGzB;CACD,MAAM,oBAAoB,uBAAuB,QAAQ;CACzD,IAAI,sBAAsB,KAAA,GAAW;EACpC,IAAI,QAAQ,eAAe,KAAA,GAC1B,MAAM,IAAI,eACT,yDAAyD,QAAQ,MAAM,KACvE,QACD;EAED,iBAAiB,QAAQ,UAAU;EACnC,OAAO;GACN,oBAAoB,QAAQ;GAC5B,mBAAmB,QAAQ;EAC5B;CACD;CAEA,IACC,QAAQ,eAAe,KAAA,KACvB,CAAC,8BAA8B,IAAI,QAAQ,KAAK,GAEhD,MAAM,IAAI,eACT,8DAA8D,QAAQ,MAAM,KAC5E,QACD;CAGD,IAAI,QAAQ,eAAe,KAAA,GAAW;EACrC,iBAAiB,QAAQ,UAAU;EACnC,OAAO;GACN,oBAAoB,QAAQ;GAC5B,mBAAmB,QAAQ;EAC5B;CACD;CAEA,OAAO,EAAE,oBAAoB,kBAAkB;AAChD;;;;;AAMA,SAAgB,eAAe,SAA0C;CACxE,MAAM,SAAS,cAAc,QAAQ,MAAM;CAC3C,MAAM,EAAE,oBAAoB,sBAAsB,kBAAkB,OAAO;CAC3E,MAAM,UAAU,QAAQ,WAAW;CAEnC,OAAO;EACN,OAAO,QAAQ;EACf,YAAY;EACZ,MAAM,MAAM,OAAO,cAAc;GAChC,MAAM,WAAW,MAAM,MAAM,GAAG,QAAQ,cAAc;IACrD,QAAQ;IACR,SAAS;KACR,eAAe,UAAU;KACzB,gBAAgB;IACjB;IACA,MAAM,KAAK,UAAU;KACpB,OAAO,QAAQ;KACf,OAAO,CAAC,GAAG,KAAK;KAChB,iBAAiB;KACjB,GAAI,sBAAsB,KAAA,IACvB,CAAC,IACD,EAAE,YAAY,kBAAkB;IACpC,CAAC;IACD,GAAI,cAAc,WAAW,KAAA,IAC1B,CAAC,IACD,EAAE,QAAQ,aAAa,OAAO;GAClC,CAAC;GAED,IAAI,CAAC,SAAS,IACb,MAAM,OAAO,uBACZ,IAAI,MACH,gDAAgD,SAAS,OAAO,EACjE,GACA,EAAE,QAAQ,SAAS,OAAO,CAC3B;GAGD,MAAM,OAAQ,MAAM,SAAS,KAAK;GAElC,MAAM,aAA0C,MAAM,KAAK,EAC1D,QAAQ,MAAM,OACf,CAAC;GACD,KAAK,MAAM,QAAQ,KAAK,MAAM;IAC7B,IACC,CAAC,OAAO,UAAU,KAAK,KAAK,KAC5B,KAAK,QAAQ,KACb,KAAK,SAAS,MAAM,QAEpB,MAAM,IAAI,eACT,uDACA,WACD;IAED,WAAW,KAAK,SAAS,KAAK;GAC/B;GACA,IAAI,WAAW,MAAM,cAAc,cAAc,KAAA,CAAS,GACzD,MAAM,IAAI,eACT,oDACA,WACD;GAED,OAAO;EACR;CACD;AACD"}
|
|
@@ -0,0 +1,53 @@
|
|
|
1
|
+
//#region src/errors.ts
|
|
2
|
+
/**
|
|
3
|
+
* Error type thrown by every public Mnemocyte API.
|
|
4
|
+
*
|
|
5
|
+
* Use the {@link MnemocyteError.code} property — not the message — to branch
|
|
6
|
+
* on failure modes, or call {@link isMnemocyteError} as a type guard when
|
|
7
|
+
* working with `unknown` errors.
|
|
8
|
+
*
|
|
9
|
+
* @example
|
|
10
|
+
* ```ts
|
|
11
|
+
* try {
|
|
12
|
+
* await client.recall({ entityId: "u1", query: "hi" });
|
|
13
|
+
* } catch (err) {
|
|
14
|
+
* if (isMnemocyteError(err) && err.code === "DB") {
|
|
15
|
+
* // handle database failure
|
|
16
|
+
* }
|
|
17
|
+
* throw err;
|
|
18
|
+
* }
|
|
19
|
+
* ```
|
|
20
|
+
*/
|
|
21
|
+
var MnemocyteError = class extends Error {
|
|
22
|
+
/** Stable, machine-readable failure code. See {@link MnemocyteErrorCode}. */
|
|
23
|
+
code;
|
|
24
|
+
/** Underlying cause, if any (e.g. an original driver or embedder error). */
|
|
25
|
+
cause;
|
|
26
|
+
/**
|
|
27
|
+
* @param message - Human-readable error message.
|
|
28
|
+
* @param code - Stable failure code; see {@link MnemocyteErrorCode}.
|
|
29
|
+
* @param cause - Optional underlying cause (driver error, network error, etc.).
|
|
30
|
+
*/
|
|
31
|
+
constructor(message, code, cause) {
|
|
32
|
+
super(message);
|
|
33
|
+
this.name = "MnemocyteError";
|
|
34
|
+
this.code = code;
|
|
35
|
+
this.cause = cause;
|
|
36
|
+
}
|
|
37
|
+
};
|
|
38
|
+
/**
|
|
39
|
+
* Type guard for {@link MnemocyteError}.
|
|
40
|
+
*
|
|
41
|
+
* Prefer this over `instanceof` when working across module boundaries or
|
|
42
|
+
* bundlers where multiple copies of the class may exist.
|
|
43
|
+
*
|
|
44
|
+
* @param error - Value to test (typically a caught `unknown`).
|
|
45
|
+
* @returns `true` if `error` is a {@link MnemocyteError}.
|
|
46
|
+
*/
|
|
47
|
+
function isMnemocyteError(error) {
|
|
48
|
+
return error instanceof MnemocyteError;
|
|
49
|
+
}
|
|
50
|
+
//#endregion
|
|
51
|
+
export { isMnemocyteError as n, MnemocyteError as t };
|
|
52
|
+
|
|
53
|
+
//# sourceMappingURL=errors-BG3-mNur.mjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"errors-BG3-mNur.mjs","names":[],"sources":["../src/errors.ts"],"sourcesContent":["/**\n * Stable, machine-readable error code attached to every {@link MnemocyteError}.\n *\n * - `\"CONFIG\"` — invalid client configuration (e.g. missing or malformed embedder).\n * - `\"VALIDATION\"` — invalid argument passed to a client method.\n * - `\"DB\"` — Postgres or driver-level failure.\n * - `\"EMBEDDING\"` — embedder threw or returned an invalid vector.\n * - `\"NOT_FOUND\"` — referenced memory or entity does not exist.\n * - `\"MIGRATION\"` — schema/migration check failed against the target database.\n * - `\"TIMEOUT\"` — a provider call exceeded its configured timeout.\n * - `\"ABORTED\"` — the operation was cancelled via an `AbortSignal`.\n */\nexport type MnemocyteErrorCode =\n\t| \"CONFIG\"\n\t| \"VALIDATION\"\n\t| \"DB\"\n\t| \"EMBEDDING\"\n\t| \"NOT_FOUND\"\n\t| \"MIGRATION\"\n\t| \"TIMEOUT\"\n\t| \"ABORTED\";\n\n/**\n * Error type thrown by every public Mnemocyte API.\n *\n * Use the {@link MnemocyteError.code} property — not the message — to branch\n * on failure modes, or call {@link isMnemocyteError} as a type guard when\n * working with `unknown` errors.\n *\n * @example\n * ```ts\n * try {\n * await client.recall({ entityId: \"u1\", query: \"hi\" });\n * } catch (err) {\n * if (isMnemocyteError(err) && err.code === \"DB\") {\n * // handle database failure\n * }\n * throw err;\n * }\n * ```\n */\nexport class MnemocyteError extends Error {\n\t/** Stable, machine-readable failure code. See {@link MnemocyteErrorCode}. */\n\treadonly code: MnemocyteErrorCode;\n\t/** Underlying cause, if any (e.g. an original driver or embedder error). */\n\toverride readonly cause?: unknown;\n\n\t/**\n\t * @param message - Human-readable error message.\n\t * @param code - Stable failure code; see {@link MnemocyteErrorCode}.\n\t * @param cause - Optional underlying cause (driver error, network error, etc.).\n\t */\n\tconstructor(message: string, code: MnemocyteErrorCode, cause?: unknown) {\n\t\tsuper(message);\n\t\tthis.name = \"MnemocyteError\";\n\t\tthis.code = code;\n\t\tthis.cause = cause;\n\t}\n}\n\n/**\n * Type guard for {@link MnemocyteError}.\n *\n * Prefer this over `instanceof` when working across module boundaries or\n * bundlers where multiple copies of the class may exist.\n *\n * @param error - Value to test (typically a caught `unknown`).\n * @returns `true` if `error` is a {@link MnemocyteError}.\n */\nexport function isMnemocyteError(error: unknown): error is MnemocyteError {\n\treturn error instanceof MnemocyteError;\n}\n"],"mappings":";;;;;;;;;;;;;;;;;;;;AAyCA,IAAa,iBAAb,cAAoC,MAAM;;CAEzC;;CAEA;;;;;;CAOA,YAAY,SAAiB,MAA0B,OAAiB;EACvE,MAAM,OAAO;EACb,KAAK,OAAO;EACZ,KAAK,OAAO;EACZ,KAAK,QAAQ;CACd;AACD;;;;;;;;;;AAWA,SAAgB,iBAAiB,OAAyC;CACzE,OAAO,iBAAiB;AACzB"}
|