@lumetra/engram 0.1.0 → 0.2.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/README.md CHANGED
@@ -53,26 +53,28 @@ new EngramClient({
53
53
  ## API surface
54
54
 
55
55
  ### Memories
56
- - `storeMemory(content, bucket?)` — store a single fact
57
- - `storeMemories(contents[], bucket?)` — batched store
58
- - `listMemories(bucket?, { limit?, offset? })` — paginated list
59
- - `deleteMemory(memoryId, bucket?)` — delete one memory
60
- - `clearMemories(bucket)` — delete every memory in a bucket
56
+ - `storeMemory(content, bucket?)` — store a single fact. `bucket` defaults to `"default"`.
57
+ - `storeMemories(contents[], bucket?)` — batched store. `bucket` defaults to `"default"`.
58
+ - `listMemories(bucket?, { limit?, offset? })` — paginated list (`limit` defaults to 20, `offset` to 0).
59
+ - `deleteMemory(memoryId, bucket?)` — delete one memory. `bucket` defaults to `"default"`.
60
+ - `clearMemories(bucket)` — delete every memory in a bucket. **No default — explicit bucket required** (prevents accidental wipes).
61
61
 
62
62
  ### Query
63
63
  - `query(question, { buckets?, topK?, skipSynthesis?, returnExplanation? })`
64
- - `buckets` fuses across multiple buckets in one call
65
- - `skipSynthesis: true` returns retrieval-only — no server-side LLM call
64
+ - `buckets` fuses across multiple buckets in one call. Defaults to `["default"]`.
65
+ - `topK` defaults to `8`.
66
+ - `skipSynthesis: true` returns retrieval-only — no server-side LLM call. Defaults to `false`.
67
+ - `returnExplanation` defaults to `true`.
66
68
  - response shape: `{ answer, explanation: { retrieved_memories, profile, graph_facts }, usage }`
67
69
 
68
70
  ### Buckets
69
71
  - `listBuckets()` — all buckets in your tenant
70
72
  - `createBucket(name, description?)`
71
- - `deleteBucket(bucket)`
73
+ - `deleteBucket(bucket)` — **No default — explicit bucket required** (prevents accidental wipes).
72
74
 
73
75
  ### Profile
74
- - `getProfile(bucket?)` — the canonical profile prepended to recall
75
- - `regenerateProfile(bucket?)` — rebuild from current memories
76
+ - `getProfile(bucket?)` — the canonical profile prepended to recall. `bucket` defaults to `"default"`.
77
+ - `regenerateProfile(bucket?)` — rebuild from current memories. `bucket` defaults to `"default"`.
76
78
 
77
79
  ### Errors
78
80
 
package/dist/index.cjs CHANGED
@@ -15,6 +15,8 @@ var EngramError = class extends Error {
15
15
  // src/client.ts
16
16
  var DEFAULT_BASE_URL = "https://api.lumetra.io";
17
17
  var DEFAULT_TIMEOUT_MS = 3e4;
18
+ var SDK_VERSION = "0.2.0";
19
+ var USER_AGENT = `engram-js/${SDK_VERSION}`;
18
20
  var EngramClient = class {
19
21
  apiKey;
20
22
  baseUrl;
@@ -55,7 +57,8 @@ var EngramClient = class {
55
57
  method: init.method,
56
58
  headers: {
57
59
  Authorization: `Bearer ${this.apiKey}`,
58
- "Content-Type": "application/json"
60
+ "Content-Type": "application/json",
61
+ "User-Agent": USER_AGENT
59
62
  },
60
63
  body: init.body !== void 0 ? JSON.stringify(init.body) : void 0,
61
64
  signal: controller.signal
@@ -90,10 +93,11 @@ var EngramClient = class {
90
93
  );
91
94
  }
92
95
  async storeMemories(contents, bucket = "default") {
93
- return this.request(
96
+ const result = await this.request(
94
97
  `/v1/buckets/${encodeURIComponent(bucket)}/memories`,
95
98
  { method: "POST", body: { memories: contents.map((content) => ({ content })) } }
96
99
  );
100
+ return Array.isArray(result) ? { memories: result } : result;
97
101
  }
98
102
  async listMemories(bucket = "default", options = {}) {
99
103
  return this.request(
@@ -111,10 +115,11 @@ var EngramClient = class {
111
115
  );
112
116
  }
113
117
  async clearMemories(bucket) {
114
- await this.request(
118
+ const res = await this.request(
115
119
  `/v1/buckets/${encodeURIComponent(bucket)}/memories`,
116
120
  { method: "DELETE" }
117
121
  );
122
+ return res ?? { success: true, cleared_count: 0 };
118
123
  }
119
124
  // ---------- Query ----------
120
125
  async query(question, options = {}) {
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/types.ts","../src/client.ts"],"names":[],"mappings":"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","file":"index.cjs","sourcesContent":["export interface EngramClientOptions {\n /**\n * Engram API key. Looks like `eng_live_...`. Defaults to `process.env.ENGRAM_API_KEY`.\n */\n apiKey?: string;\n /**\n * API base URL. Defaults to `process.env.ENGRAM_BASE_URL` or `https://api.lumetra.io`.\n */\n baseUrl?: string;\n /**\n * Custom fetch implementation. Defaults to the global `fetch`.\n * Useful for proxying, retry middleware, or non-Node runtimes.\n */\n fetch?: typeof fetch;\n /**\n * Request timeout in milliseconds. Defaults to 30000 (30s).\n */\n timeoutMs?: number;\n}\n\nexport interface Bucket {\n id: string;\n name: string;\n description?: string | null;\n created_at: string;\n memory_count?: number;\n}\n\nexport interface Memory {\n id: string;\n content: string;\n bucket_name?: string;\n created_at?: string;\n token_count?: number;\n}\n\nexport interface StoreMemoryResult {\n id: string;\n bucket_name: string;\n token_count: number;\n}\n\nexport interface RetrievedMemory {\n id?: string;\n content: string;\n score?: number;\n bucket?: string;\n}\n\nexport interface QueryExplanation {\n retrieved_memories?: RetrievedMemory[];\n profile?: string | null;\n graph_facts?: string[];\n}\n\nexport interface QueryUsage {\n prompt_tokens?: number;\n completion_tokens?: number;\n total_tokens?: number;\n}\n\nexport interface QueryResult {\n answer: string;\n explanation?: QueryExplanation;\n usage?: QueryUsage;\n}\n\nexport interface QueryOptions {\n /**\n * Buckets to fuse across. Defaults to `['default']`.\n */\n buckets?: string[];\n /**\n * Maximum number of memories to retrieve. Defaults to 8.\n */\n topK?: number;\n /**\n * If true, server skips the synthesis LLM call and returns retrieval-only.\n * `answer` will be an empty string in that case. Defaults to false.\n */\n skipSynthesis?: boolean;\n /**\n * Whether to populate the `explanation` field. Defaults to true.\n */\n returnExplanation?: boolean;\n}\n\nexport interface ListMemoriesOptions {\n limit?: number;\n offset?: number;\n}\n\nexport interface ListMemoriesResult {\n memories: Memory[];\n total: number;\n limit: number;\n offset: number;\n}\n\nexport class EngramError extends Error {\n override readonly name = 'EngramError';\n readonly status: number;\n readonly body: unknown;\n\n constructor(message: string, status: number, body: unknown) {\n super(message);\n this.status = status;\n this.body = body;\n }\n}\n","import {\n EngramError,\n type Bucket,\n type EngramClientOptions,\n type ListMemoriesOptions,\n type ListMemoriesResult,\n type QueryOptions,\n type QueryResult,\n type StoreMemoryResult,\n} from './types.js';\n\nconst DEFAULT_BASE_URL = 'https://api.lumetra.io';\nconst DEFAULT_TIMEOUT_MS = 30_000;\n\nexport class EngramClient {\n private readonly apiKey: string;\n private readonly baseUrl: string;\n private readonly fetchImpl: typeof fetch;\n private readonly timeoutMs: number;\n\n constructor(options: EngramClientOptions = {}) {\n const apiKey =\n options.apiKey ??\n (typeof process !== 'undefined' ? process.env?.ENGRAM_API_KEY : undefined) ??\n '';\n if (!apiKey) {\n throw new Error(\n 'EngramClient: apiKey is required. Pass it explicitly or set ENGRAM_API_KEY in your environment.',\n );\n }\n const baseUrl =\n options.baseUrl ??\n (typeof process !== 'undefined' ? process.env?.ENGRAM_BASE_URL : undefined) ??\n DEFAULT_BASE_URL;\n\n this.apiKey = apiKey;\n this.baseUrl = baseUrl.replace(/\\/+$/, '');\n this.fetchImpl = options.fetch ?? globalThis.fetch;\n this.timeoutMs = options.timeoutMs ?? DEFAULT_TIMEOUT_MS;\n\n if (typeof this.fetchImpl !== 'function') {\n throw new Error(\n 'EngramClient: no fetch implementation available. Use Node 18+, or pass options.fetch.',\n );\n }\n }\n\n private async request<T>(\n path: string,\n init: { method: string; body?: unknown; query?: Record<string, string | number | undefined> } = {\n method: 'GET',\n },\n ): Promise<T> {\n const url = new URL(`${this.baseUrl}${path}`);\n if (init.query) {\n for (const [k, v] of Object.entries(init.query)) {\n if (v !== undefined) url.searchParams.set(k, String(v));\n }\n }\n\n const controller = new AbortController();\n const timer = setTimeout(() => controller.abort(), this.timeoutMs);\n\n let res: Response;\n try {\n res = await this.fetchImpl(url.toString(), {\n method: init.method,\n headers: {\n Authorization: `Bearer ${this.apiKey}`,\n 'Content-Type': 'application/json',\n },\n body: init.body !== undefined ? JSON.stringify(init.body) : undefined,\n signal: controller.signal,\n });\n } finally {\n clearTimeout(timer);\n }\n\n const text = await res.text();\n let parsed: unknown = undefined;\n if (text) {\n try {\n parsed = JSON.parse(text);\n } catch {\n parsed = text;\n }\n }\n\n if (!res.ok) {\n const detail =\n parsed && typeof parsed === 'object' && parsed !== null && 'error' in parsed\n ? (parsed as { error: unknown }).error\n : parsed;\n throw new EngramError(\n `Engram API ${res.status}: ${typeof detail === 'string' ? detail : JSON.stringify(detail ?? '')}`,\n res.status,\n parsed,\n );\n }\n\n return parsed as T;\n }\n\n // ---------- Memories ----------\n\n async storeMemory(content: string, bucket: string = 'default'): Promise<StoreMemoryResult> {\n return this.request<StoreMemoryResult>(\n `/v1/buckets/${encodeURIComponent(bucket)}/memories`,\n { method: 'POST', body: { content } },\n );\n }\n\n async storeMemories(\n contents: string[],\n bucket: string = 'default',\n ): Promise<{ memories: StoreMemoryResult[] }> {\n return this.request<{ memories: StoreMemoryResult[] }>(\n `/v1/buckets/${encodeURIComponent(bucket)}/memories`,\n { method: 'POST', body: { memories: contents.map((content) => ({ content })) } },\n );\n }\n\n async listMemories(\n bucket: string = 'default',\n options: ListMemoriesOptions = {},\n ): Promise<ListMemoriesResult> {\n return this.request<ListMemoriesResult>(\n `/v1/buckets/${encodeURIComponent(bucket)}/memories`,\n {\n method: 'GET',\n query: { limit: options.limit ?? 20, offset: options.offset ?? 0 },\n },\n );\n }\n\n async deleteMemory(memoryId: string, bucket: string = 'default'): Promise<void> {\n await this.request<unknown>(\n `/v1/buckets/${encodeURIComponent(bucket)}/memories/${encodeURIComponent(memoryId)}`,\n { method: 'DELETE' },\n );\n }\n\n async clearMemories(bucket: string): Promise<void> {\n await this.request<unknown>(\n `/v1/buckets/${encodeURIComponent(bucket)}/memories`,\n { method: 'DELETE' },\n );\n }\n\n // ---------- Query ----------\n\n async query(question: string, options: QueryOptions = {}): Promise<QueryResult> {\n const buckets = options.buckets ?? ['default'];\n return this.request<QueryResult>('/v1/query', {\n method: 'POST',\n body: {\n query: question,\n buckets,\n options: {\n top_k: options.topK ?? 8,\n return_explanation: options.returnExplanation ?? true,\n skip_synthesis: options.skipSynthesis ?? false,\n },\n },\n });\n }\n\n // ---------- Buckets ----------\n\n async listBuckets(): Promise<Bucket[]> {\n const result = await this.request<{ buckets: Bucket[] } | Bucket[]>(`/v1/buckets`, {\n method: 'GET',\n });\n return Array.isArray(result) ? result : result.buckets;\n }\n\n async createBucket(name: string, description?: string): Promise<Bucket> {\n return this.request<Bucket>('/v1/buckets', {\n method: 'POST',\n body: { name, description },\n });\n }\n\n async deleteBucket(bucket: string): Promise<void> {\n await this.request<unknown>(`/v1/buckets/${encodeURIComponent(bucket)}`, {\n method: 'DELETE',\n });\n }\n\n // ---------- Profile ----------\n\n async getProfile(bucket: string = 'default'): Promise<{ profile: string | null }> {\n return this.request<{ profile: string | null }>(\n `/v1/buckets/${encodeURIComponent(bucket)}/profile`,\n { method: 'GET' },\n );\n }\n\n async regenerateProfile(bucket: string = 'default'): Promise<{ profile: string | null }> {\n return this.request<{ profile: string | null }>(\n `/v1/buckets/${encodeURIComponent(bucket)}/profile/regenerate`,\n { method: 'POST' },\n );\n }\n}\n"]}
1
+ {"version":3,"sources":["../src/types.ts","../src/client.ts"],"names":[],"mappings":"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","file":"index.cjs","sourcesContent":["export interface EngramClientOptions {\n /**\n * Engram API key. Looks like `eng_live_...`. Defaults to `process.env.ENGRAM_API_KEY`.\n */\n apiKey?: string;\n /**\n * API base URL. Defaults to `process.env.ENGRAM_BASE_URL` or `https://api.lumetra.io`.\n */\n baseUrl?: string;\n /**\n * Custom fetch implementation. Defaults to the global `fetch`.\n * Useful for proxying, retry middleware, or non-Node runtimes.\n */\n fetch?: typeof fetch;\n /**\n * Request timeout in milliseconds. Defaults to 30000 (30s).\n */\n timeoutMs?: number;\n}\n\nexport interface Bucket {\n id: string;\n name: string;\n description?: string | null;\n created_at: string;\n memory_count?: number;\n}\n\nexport interface Memory {\n id: string;\n content: string;\n bucket_name?: string;\n created_at?: string;\n token_count?: number;\n}\n\nexport interface StoreMemoryResult {\n id: string;\n bucket_name: string;\n token_count: number;\n}\n\nexport interface ClearMemoriesResult {\n success: boolean;\n /** Number of memories actually deleted (server-reported). */\n cleared_count: number;\n}\n\nexport interface RetrievedMemory {\n id?: string;\n content: string;\n score?: number;\n bucket?: string;\n}\n\nexport interface QueryExplanation {\n retrieved_memories?: RetrievedMemory[];\n profile?: string | null;\n graph_facts?: string[];\n}\n\nexport interface QueryUsage {\n prompt_tokens?: number;\n completion_tokens?: number;\n total_tokens?: number;\n}\n\nexport interface QueryResult {\n answer: string;\n explanation?: QueryExplanation;\n usage?: QueryUsage;\n}\n\nexport interface QueryOptions {\n /**\n * Buckets to fuse across. Defaults to `['default']`.\n */\n buckets?: string[];\n /**\n * Maximum number of memories to retrieve. Defaults to 8.\n */\n topK?: number;\n /**\n * If true, server skips the synthesis LLM call and returns retrieval-only.\n * `answer` will be an empty string in that case. Defaults to false.\n */\n skipSynthesis?: boolean;\n /**\n * Whether to populate the `explanation` field. Defaults to true.\n */\n returnExplanation?: boolean;\n}\n\nexport interface ListMemoriesOptions {\n limit?: number;\n offset?: number;\n}\n\nexport interface ListMemoriesResult {\n memories: Memory[];\n total: number;\n limit: number;\n offset: number;\n}\n\nexport class EngramError extends Error {\n override readonly name = 'EngramError';\n readonly status: number;\n readonly body: unknown;\n\n constructor(message: string, status: number, body: unknown) {\n super(message);\n this.status = status;\n this.body = body;\n }\n}\n","import {\n EngramError,\n type Bucket,\n type ClearMemoriesResult,\n type EngramClientOptions,\n type ListMemoriesOptions,\n type ListMemoriesResult,\n type QueryOptions,\n type QueryResult,\n type StoreMemoryResult,\n} from './types.js';\n\nconst DEFAULT_BASE_URL = 'https://api.lumetra.io';\nconst DEFAULT_TIMEOUT_MS = 30_000;\nconst SDK_VERSION = '0.2.0';\nconst USER_AGENT = `engram-js/${SDK_VERSION}`;\n\nexport class EngramClient {\n private readonly apiKey: string;\n private readonly baseUrl: string;\n private readonly fetchImpl: typeof fetch;\n private readonly timeoutMs: number;\n\n constructor(options: EngramClientOptions = {}) {\n const apiKey =\n options.apiKey ??\n (typeof process !== 'undefined' ? process.env?.ENGRAM_API_KEY : undefined) ??\n '';\n if (!apiKey) {\n throw new Error(\n 'EngramClient: apiKey is required. Pass it explicitly or set ENGRAM_API_KEY in your environment.',\n );\n }\n const baseUrl =\n options.baseUrl ??\n (typeof process !== 'undefined' ? process.env?.ENGRAM_BASE_URL : undefined) ??\n DEFAULT_BASE_URL;\n\n this.apiKey = apiKey;\n this.baseUrl = baseUrl.replace(/\\/+$/, '');\n this.fetchImpl = options.fetch ?? globalThis.fetch;\n this.timeoutMs = options.timeoutMs ?? DEFAULT_TIMEOUT_MS;\n\n if (typeof this.fetchImpl !== 'function') {\n throw new Error(\n 'EngramClient: no fetch implementation available. Use Node 18+, or pass options.fetch.',\n );\n }\n }\n\n private async request<T>(\n path: string,\n init: { method: string; body?: unknown; query?: Record<string, string | number | undefined> } = {\n method: 'GET',\n },\n ): Promise<T> {\n const url = new URL(`${this.baseUrl}${path}`);\n if (init.query) {\n for (const [k, v] of Object.entries(init.query)) {\n if (v !== undefined) url.searchParams.set(k, String(v));\n }\n }\n\n const controller = new AbortController();\n const timer = setTimeout(() => controller.abort(), this.timeoutMs);\n\n let res: Response;\n try {\n res = await this.fetchImpl(url.toString(), {\n method: init.method,\n headers: {\n Authorization: `Bearer ${this.apiKey}`,\n 'Content-Type': 'application/json',\n 'User-Agent': USER_AGENT,\n },\n body: init.body !== undefined ? JSON.stringify(init.body) : undefined,\n signal: controller.signal,\n });\n } finally {\n clearTimeout(timer);\n }\n\n const text = await res.text();\n let parsed: unknown = undefined;\n if (text) {\n try {\n parsed = JSON.parse(text);\n } catch {\n parsed = text;\n }\n }\n\n if (!res.ok) {\n const detail =\n parsed && typeof parsed === 'object' && parsed !== null && 'error' in parsed\n ? (parsed as { error: unknown }).error\n : parsed;\n throw new EngramError(\n `Engram API ${res.status}: ${typeof detail === 'string' ? detail : JSON.stringify(detail ?? '')}`,\n res.status,\n parsed,\n );\n }\n\n return parsed as T;\n }\n\n // ---------- Memories ----------\n\n async storeMemory(content: string, bucket: string = 'default'): Promise<StoreMemoryResult> {\n return this.request<StoreMemoryResult>(\n `/v1/buckets/${encodeURIComponent(bucket)}/memories`,\n { method: 'POST', body: { content } },\n );\n }\n\n async storeMemories(\n contents: string[],\n bucket: string = 'default',\n ): Promise<{ memories: StoreMemoryResult[] }> {\n // Defensively unwrap: depending on server version the batch endpoint\n // returns either { memories: [...] } or a bare array. Normalize to the\n // wrapped shape so callers don't have to switch on it.\n const result = await this.request<{ memories: StoreMemoryResult[] } | StoreMemoryResult[]>(\n `/v1/buckets/${encodeURIComponent(bucket)}/memories`,\n { method: 'POST', body: { memories: contents.map((content) => ({ content })) } },\n );\n return Array.isArray(result) ? { memories: result } : result;\n }\n\n async listMemories(\n bucket: string = 'default',\n options: ListMemoriesOptions = {},\n ): Promise<ListMemoriesResult> {\n return this.request<ListMemoriesResult>(\n `/v1/buckets/${encodeURIComponent(bucket)}/memories`,\n {\n method: 'GET',\n query: { limit: options.limit ?? 20, offset: options.offset ?? 0 },\n },\n );\n }\n\n async deleteMemory(memoryId: string, bucket: string = 'default'): Promise<void> {\n await this.request<unknown>(\n `/v1/buckets/${encodeURIComponent(bucket)}/memories/${encodeURIComponent(memoryId)}`,\n { method: 'DELETE' },\n );\n }\n\n async clearMemories(bucket: string): Promise<ClearMemoriesResult> {\n const res = await this.request<ClearMemoriesResult>(\n `/v1/buckets/${encodeURIComponent(bucket)}/memories`,\n { method: 'DELETE' },\n );\n // Defensive default: older servers / proxies may strip the body. The\n // contract surface is {success, cleared_count}; if the server stayed\n // silent we still return the same shape so callers can rely on it.\n return res ?? { success: true, cleared_count: 0 };\n }\n\n // ---------- Query ----------\n\n async query(question: string, options: QueryOptions = {}): Promise<QueryResult> {\n const buckets = options.buckets ?? ['default'];\n return this.request<QueryResult>('/v1/query', {\n method: 'POST',\n body: {\n query: question,\n buckets,\n options: {\n top_k: options.topK ?? 8,\n return_explanation: options.returnExplanation ?? true,\n skip_synthesis: options.skipSynthesis ?? false,\n },\n },\n });\n }\n\n // ---------- Buckets ----------\n\n async listBuckets(): Promise<Bucket[]> {\n const result = await this.request<{ buckets: Bucket[] } | Bucket[]>(`/v1/buckets`, {\n method: 'GET',\n });\n return Array.isArray(result) ? result : result.buckets;\n }\n\n async createBucket(name: string, description?: string): Promise<Bucket> {\n return this.request<Bucket>('/v1/buckets', {\n method: 'POST',\n body: { name, description },\n });\n }\n\n async deleteBucket(bucket: string): Promise<void> {\n await this.request<unknown>(`/v1/buckets/${encodeURIComponent(bucket)}`, {\n method: 'DELETE',\n });\n }\n\n // ---------- Profile ----------\n\n async getProfile(bucket: string = 'default'): Promise<{ profile: string | null }> {\n return this.request<{ profile: string | null }>(\n `/v1/buckets/${encodeURIComponent(bucket)}/profile`,\n { method: 'GET' },\n );\n }\n\n async regenerateProfile(bucket: string = 'default'): Promise<{ profile: string | null }> {\n return this.request<{ profile: string | null }>(\n `/v1/buckets/${encodeURIComponent(bucket)}/profile/regenerate`,\n { method: 'POST' },\n );\n }\n}\n"]}
package/dist/index.d.cts CHANGED
@@ -36,6 +36,11 @@ interface StoreMemoryResult {
36
36
  bucket_name: string;
37
37
  token_count: number;
38
38
  }
39
+ interface ClearMemoriesResult {
40
+ success: boolean;
41
+ /** Number of memories actually deleted (server-reported). */
42
+ cleared_count: number;
43
+ }
39
44
  interface RetrievedMemory {
40
45
  id?: string;
41
46
  content: string;
@@ -106,7 +111,7 @@ declare class EngramClient {
106
111
  }>;
107
112
  listMemories(bucket?: string, options?: ListMemoriesOptions): Promise<ListMemoriesResult>;
108
113
  deleteMemory(memoryId: string, bucket?: string): Promise<void>;
109
- clearMemories(bucket: string): Promise<void>;
114
+ clearMemories(bucket: string): Promise<ClearMemoriesResult>;
110
115
  query(question: string, options?: QueryOptions): Promise<QueryResult>;
111
116
  listBuckets(): Promise<Bucket[]>;
112
117
  createBucket(name: string, description?: string): Promise<Bucket>;
@@ -119,4 +124,4 @@ declare class EngramClient {
119
124
  }>;
120
125
  }
121
126
 
122
- export { type Bucket, EngramClient, type EngramClientOptions, EngramError, type ListMemoriesOptions, type ListMemoriesResult, type Memory, type QueryExplanation, type QueryOptions, type QueryResult, type QueryUsage, type RetrievedMemory, type StoreMemoryResult };
127
+ export { type Bucket, type ClearMemoriesResult, EngramClient, type EngramClientOptions, EngramError, type ListMemoriesOptions, type ListMemoriesResult, type Memory, type QueryExplanation, type QueryOptions, type QueryResult, type QueryUsage, type RetrievedMemory, type StoreMemoryResult };
package/dist/index.d.ts CHANGED
@@ -36,6 +36,11 @@ interface StoreMemoryResult {
36
36
  bucket_name: string;
37
37
  token_count: number;
38
38
  }
39
+ interface ClearMemoriesResult {
40
+ success: boolean;
41
+ /** Number of memories actually deleted (server-reported). */
42
+ cleared_count: number;
43
+ }
39
44
  interface RetrievedMemory {
40
45
  id?: string;
41
46
  content: string;
@@ -106,7 +111,7 @@ declare class EngramClient {
106
111
  }>;
107
112
  listMemories(bucket?: string, options?: ListMemoriesOptions): Promise<ListMemoriesResult>;
108
113
  deleteMemory(memoryId: string, bucket?: string): Promise<void>;
109
- clearMemories(bucket: string): Promise<void>;
114
+ clearMemories(bucket: string): Promise<ClearMemoriesResult>;
110
115
  query(question: string, options?: QueryOptions): Promise<QueryResult>;
111
116
  listBuckets(): Promise<Bucket[]>;
112
117
  createBucket(name: string, description?: string): Promise<Bucket>;
@@ -119,4 +124,4 @@ declare class EngramClient {
119
124
  }>;
120
125
  }
121
126
 
122
- export { type Bucket, EngramClient, type EngramClientOptions, EngramError, type ListMemoriesOptions, type ListMemoriesResult, type Memory, type QueryExplanation, type QueryOptions, type QueryResult, type QueryUsage, type RetrievedMemory, type StoreMemoryResult };
127
+ export { type Bucket, type ClearMemoriesResult, EngramClient, type EngramClientOptions, EngramError, type ListMemoriesOptions, type ListMemoriesResult, type Memory, type QueryExplanation, type QueryOptions, type QueryResult, type QueryUsage, type RetrievedMemory, type StoreMemoryResult };
package/dist/index.js CHANGED
@@ -13,6 +13,8 @@ var EngramError = class extends Error {
13
13
  // src/client.ts
14
14
  var DEFAULT_BASE_URL = "https://api.lumetra.io";
15
15
  var DEFAULT_TIMEOUT_MS = 3e4;
16
+ var SDK_VERSION = "0.2.0";
17
+ var USER_AGENT = `engram-js/${SDK_VERSION}`;
16
18
  var EngramClient = class {
17
19
  apiKey;
18
20
  baseUrl;
@@ -53,7 +55,8 @@ var EngramClient = class {
53
55
  method: init.method,
54
56
  headers: {
55
57
  Authorization: `Bearer ${this.apiKey}`,
56
- "Content-Type": "application/json"
58
+ "Content-Type": "application/json",
59
+ "User-Agent": USER_AGENT
57
60
  },
58
61
  body: init.body !== void 0 ? JSON.stringify(init.body) : void 0,
59
62
  signal: controller.signal
@@ -88,10 +91,11 @@ var EngramClient = class {
88
91
  );
89
92
  }
90
93
  async storeMemories(contents, bucket = "default") {
91
- return this.request(
94
+ const result = await this.request(
92
95
  `/v1/buckets/${encodeURIComponent(bucket)}/memories`,
93
96
  { method: "POST", body: { memories: contents.map((content) => ({ content })) } }
94
97
  );
98
+ return Array.isArray(result) ? { memories: result } : result;
95
99
  }
96
100
  async listMemories(bucket = "default", options = {}) {
97
101
  return this.request(
@@ -109,10 +113,11 @@ var EngramClient = class {
109
113
  );
110
114
  }
111
115
  async clearMemories(bucket) {
112
- await this.request(
116
+ const res = await this.request(
113
117
  `/v1/buckets/${encodeURIComponent(bucket)}/memories`,
114
118
  { method: "DELETE" }
115
119
  );
120
+ return res ?? { success: true, cleared_count: 0 };
116
121
  }
117
122
  // ---------- Query ----------
118
123
  async query(question, options = {}) {
package/dist/index.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/types.ts","../src/client.ts"],"names":[],"mappings":"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","file":"index.js","sourcesContent":["export interface EngramClientOptions {\n /**\n * Engram API key. Looks like `eng_live_...`. Defaults to `process.env.ENGRAM_API_KEY`.\n */\n apiKey?: string;\n /**\n * API base URL. Defaults to `process.env.ENGRAM_BASE_URL` or `https://api.lumetra.io`.\n */\n baseUrl?: string;\n /**\n * Custom fetch implementation. Defaults to the global `fetch`.\n * Useful for proxying, retry middleware, or non-Node runtimes.\n */\n fetch?: typeof fetch;\n /**\n * Request timeout in milliseconds. Defaults to 30000 (30s).\n */\n timeoutMs?: number;\n}\n\nexport interface Bucket {\n id: string;\n name: string;\n description?: string | null;\n created_at: string;\n memory_count?: number;\n}\n\nexport interface Memory {\n id: string;\n content: string;\n bucket_name?: string;\n created_at?: string;\n token_count?: number;\n}\n\nexport interface StoreMemoryResult {\n id: string;\n bucket_name: string;\n token_count: number;\n}\n\nexport interface RetrievedMemory {\n id?: string;\n content: string;\n score?: number;\n bucket?: string;\n}\n\nexport interface QueryExplanation {\n retrieved_memories?: RetrievedMemory[];\n profile?: string | null;\n graph_facts?: string[];\n}\n\nexport interface QueryUsage {\n prompt_tokens?: number;\n completion_tokens?: number;\n total_tokens?: number;\n}\n\nexport interface QueryResult {\n answer: string;\n explanation?: QueryExplanation;\n usage?: QueryUsage;\n}\n\nexport interface QueryOptions {\n /**\n * Buckets to fuse across. Defaults to `['default']`.\n */\n buckets?: string[];\n /**\n * Maximum number of memories to retrieve. Defaults to 8.\n */\n topK?: number;\n /**\n * If true, server skips the synthesis LLM call and returns retrieval-only.\n * `answer` will be an empty string in that case. Defaults to false.\n */\n skipSynthesis?: boolean;\n /**\n * Whether to populate the `explanation` field. Defaults to true.\n */\n returnExplanation?: boolean;\n}\n\nexport interface ListMemoriesOptions {\n limit?: number;\n offset?: number;\n}\n\nexport interface ListMemoriesResult {\n memories: Memory[];\n total: number;\n limit: number;\n offset: number;\n}\n\nexport class EngramError extends Error {\n override readonly name = 'EngramError';\n readonly status: number;\n readonly body: unknown;\n\n constructor(message: string, status: number, body: unknown) {\n super(message);\n this.status = status;\n this.body = body;\n }\n}\n","import {\n EngramError,\n type Bucket,\n type EngramClientOptions,\n type ListMemoriesOptions,\n type ListMemoriesResult,\n type QueryOptions,\n type QueryResult,\n type StoreMemoryResult,\n} from './types.js';\n\nconst DEFAULT_BASE_URL = 'https://api.lumetra.io';\nconst DEFAULT_TIMEOUT_MS = 30_000;\n\nexport class EngramClient {\n private readonly apiKey: string;\n private readonly baseUrl: string;\n private readonly fetchImpl: typeof fetch;\n private readonly timeoutMs: number;\n\n constructor(options: EngramClientOptions = {}) {\n const apiKey =\n options.apiKey ??\n (typeof process !== 'undefined' ? process.env?.ENGRAM_API_KEY : undefined) ??\n '';\n if (!apiKey) {\n throw new Error(\n 'EngramClient: apiKey is required. Pass it explicitly or set ENGRAM_API_KEY in your environment.',\n );\n }\n const baseUrl =\n options.baseUrl ??\n (typeof process !== 'undefined' ? process.env?.ENGRAM_BASE_URL : undefined) ??\n DEFAULT_BASE_URL;\n\n this.apiKey = apiKey;\n this.baseUrl = baseUrl.replace(/\\/+$/, '');\n this.fetchImpl = options.fetch ?? globalThis.fetch;\n this.timeoutMs = options.timeoutMs ?? DEFAULT_TIMEOUT_MS;\n\n if (typeof this.fetchImpl !== 'function') {\n throw new Error(\n 'EngramClient: no fetch implementation available. Use Node 18+, or pass options.fetch.',\n );\n }\n }\n\n private async request<T>(\n path: string,\n init: { method: string; body?: unknown; query?: Record<string, string | number | undefined> } = {\n method: 'GET',\n },\n ): Promise<T> {\n const url = new URL(`${this.baseUrl}${path}`);\n if (init.query) {\n for (const [k, v] of Object.entries(init.query)) {\n if (v !== undefined) url.searchParams.set(k, String(v));\n }\n }\n\n const controller = new AbortController();\n const timer = setTimeout(() => controller.abort(), this.timeoutMs);\n\n let res: Response;\n try {\n res = await this.fetchImpl(url.toString(), {\n method: init.method,\n headers: {\n Authorization: `Bearer ${this.apiKey}`,\n 'Content-Type': 'application/json',\n },\n body: init.body !== undefined ? JSON.stringify(init.body) : undefined,\n signal: controller.signal,\n });\n } finally {\n clearTimeout(timer);\n }\n\n const text = await res.text();\n let parsed: unknown = undefined;\n if (text) {\n try {\n parsed = JSON.parse(text);\n } catch {\n parsed = text;\n }\n }\n\n if (!res.ok) {\n const detail =\n parsed && typeof parsed === 'object' && parsed !== null && 'error' in parsed\n ? (parsed as { error: unknown }).error\n : parsed;\n throw new EngramError(\n `Engram API ${res.status}: ${typeof detail === 'string' ? detail : JSON.stringify(detail ?? '')}`,\n res.status,\n parsed,\n );\n }\n\n return parsed as T;\n }\n\n // ---------- Memories ----------\n\n async storeMemory(content: string, bucket: string = 'default'): Promise<StoreMemoryResult> {\n return this.request<StoreMemoryResult>(\n `/v1/buckets/${encodeURIComponent(bucket)}/memories`,\n { method: 'POST', body: { content } },\n );\n }\n\n async storeMemories(\n contents: string[],\n bucket: string = 'default',\n ): Promise<{ memories: StoreMemoryResult[] }> {\n return this.request<{ memories: StoreMemoryResult[] }>(\n `/v1/buckets/${encodeURIComponent(bucket)}/memories`,\n { method: 'POST', body: { memories: contents.map((content) => ({ content })) } },\n );\n }\n\n async listMemories(\n bucket: string = 'default',\n options: ListMemoriesOptions = {},\n ): Promise<ListMemoriesResult> {\n return this.request<ListMemoriesResult>(\n `/v1/buckets/${encodeURIComponent(bucket)}/memories`,\n {\n method: 'GET',\n query: { limit: options.limit ?? 20, offset: options.offset ?? 0 },\n },\n );\n }\n\n async deleteMemory(memoryId: string, bucket: string = 'default'): Promise<void> {\n await this.request<unknown>(\n `/v1/buckets/${encodeURIComponent(bucket)}/memories/${encodeURIComponent(memoryId)}`,\n { method: 'DELETE' },\n );\n }\n\n async clearMemories(bucket: string): Promise<void> {\n await this.request<unknown>(\n `/v1/buckets/${encodeURIComponent(bucket)}/memories`,\n { method: 'DELETE' },\n );\n }\n\n // ---------- Query ----------\n\n async query(question: string, options: QueryOptions = {}): Promise<QueryResult> {\n const buckets = options.buckets ?? ['default'];\n return this.request<QueryResult>('/v1/query', {\n method: 'POST',\n body: {\n query: question,\n buckets,\n options: {\n top_k: options.topK ?? 8,\n return_explanation: options.returnExplanation ?? true,\n skip_synthesis: options.skipSynthesis ?? false,\n },\n },\n });\n }\n\n // ---------- Buckets ----------\n\n async listBuckets(): Promise<Bucket[]> {\n const result = await this.request<{ buckets: Bucket[] } | Bucket[]>(`/v1/buckets`, {\n method: 'GET',\n });\n return Array.isArray(result) ? result : result.buckets;\n }\n\n async createBucket(name: string, description?: string): Promise<Bucket> {\n return this.request<Bucket>('/v1/buckets', {\n method: 'POST',\n body: { name, description },\n });\n }\n\n async deleteBucket(bucket: string): Promise<void> {\n await this.request<unknown>(`/v1/buckets/${encodeURIComponent(bucket)}`, {\n method: 'DELETE',\n });\n }\n\n // ---------- Profile ----------\n\n async getProfile(bucket: string = 'default'): Promise<{ profile: string | null }> {\n return this.request<{ profile: string | null }>(\n `/v1/buckets/${encodeURIComponent(bucket)}/profile`,\n { method: 'GET' },\n );\n }\n\n async regenerateProfile(bucket: string = 'default'): Promise<{ profile: string | null }> {\n return this.request<{ profile: string | null }>(\n `/v1/buckets/${encodeURIComponent(bucket)}/profile/regenerate`,\n { method: 'POST' },\n );\n }\n}\n"]}
1
+ {"version":3,"sources":["../src/types.ts","../src/client.ts"],"names":[],"mappings":"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","file":"index.js","sourcesContent":["export interface EngramClientOptions {\n /**\n * Engram API key. Looks like `eng_live_...`. Defaults to `process.env.ENGRAM_API_KEY`.\n */\n apiKey?: string;\n /**\n * API base URL. Defaults to `process.env.ENGRAM_BASE_URL` or `https://api.lumetra.io`.\n */\n baseUrl?: string;\n /**\n * Custom fetch implementation. Defaults to the global `fetch`.\n * Useful for proxying, retry middleware, or non-Node runtimes.\n */\n fetch?: typeof fetch;\n /**\n * Request timeout in milliseconds. Defaults to 30000 (30s).\n */\n timeoutMs?: number;\n}\n\nexport interface Bucket {\n id: string;\n name: string;\n description?: string | null;\n created_at: string;\n memory_count?: number;\n}\n\nexport interface Memory {\n id: string;\n content: string;\n bucket_name?: string;\n created_at?: string;\n token_count?: number;\n}\n\nexport interface StoreMemoryResult {\n id: string;\n bucket_name: string;\n token_count: number;\n}\n\nexport interface ClearMemoriesResult {\n success: boolean;\n /** Number of memories actually deleted (server-reported). */\n cleared_count: number;\n}\n\nexport interface RetrievedMemory {\n id?: string;\n content: string;\n score?: number;\n bucket?: string;\n}\n\nexport interface QueryExplanation {\n retrieved_memories?: RetrievedMemory[];\n profile?: string | null;\n graph_facts?: string[];\n}\n\nexport interface QueryUsage {\n prompt_tokens?: number;\n completion_tokens?: number;\n total_tokens?: number;\n}\n\nexport interface QueryResult {\n answer: string;\n explanation?: QueryExplanation;\n usage?: QueryUsage;\n}\n\nexport interface QueryOptions {\n /**\n * Buckets to fuse across. Defaults to `['default']`.\n */\n buckets?: string[];\n /**\n * Maximum number of memories to retrieve. Defaults to 8.\n */\n topK?: number;\n /**\n * If true, server skips the synthesis LLM call and returns retrieval-only.\n * `answer` will be an empty string in that case. Defaults to false.\n */\n skipSynthesis?: boolean;\n /**\n * Whether to populate the `explanation` field. Defaults to true.\n */\n returnExplanation?: boolean;\n}\n\nexport interface ListMemoriesOptions {\n limit?: number;\n offset?: number;\n}\n\nexport interface ListMemoriesResult {\n memories: Memory[];\n total: number;\n limit: number;\n offset: number;\n}\n\nexport class EngramError extends Error {\n override readonly name = 'EngramError';\n readonly status: number;\n readonly body: unknown;\n\n constructor(message: string, status: number, body: unknown) {\n super(message);\n this.status = status;\n this.body = body;\n }\n}\n","import {\n EngramError,\n type Bucket,\n type ClearMemoriesResult,\n type EngramClientOptions,\n type ListMemoriesOptions,\n type ListMemoriesResult,\n type QueryOptions,\n type QueryResult,\n type StoreMemoryResult,\n} from './types.js';\n\nconst DEFAULT_BASE_URL = 'https://api.lumetra.io';\nconst DEFAULT_TIMEOUT_MS = 30_000;\nconst SDK_VERSION = '0.2.0';\nconst USER_AGENT = `engram-js/${SDK_VERSION}`;\n\nexport class EngramClient {\n private readonly apiKey: string;\n private readonly baseUrl: string;\n private readonly fetchImpl: typeof fetch;\n private readonly timeoutMs: number;\n\n constructor(options: EngramClientOptions = {}) {\n const apiKey =\n options.apiKey ??\n (typeof process !== 'undefined' ? process.env?.ENGRAM_API_KEY : undefined) ??\n '';\n if (!apiKey) {\n throw new Error(\n 'EngramClient: apiKey is required. Pass it explicitly or set ENGRAM_API_KEY in your environment.',\n );\n }\n const baseUrl =\n options.baseUrl ??\n (typeof process !== 'undefined' ? process.env?.ENGRAM_BASE_URL : undefined) ??\n DEFAULT_BASE_URL;\n\n this.apiKey = apiKey;\n this.baseUrl = baseUrl.replace(/\\/+$/, '');\n this.fetchImpl = options.fetch ?? globalThis.fetch;\n this.timeoutMs = options.timeoutMs ?? DEFAULT_TIMEOUT_MS;\n\n if (typeof this.fetchImpl !== 'function') {\n throw new Error(\n 'EngramClient: no fetch implementation available. Use Node 18+, or pass options.fetch.',\n );\n }\n }\n\n private async request<T>(\n path: string,\n init: { method: string; body?: unknown; query?: Record<string, string | number | undefined> } = {\n method: 'GET',\n },\n ): Promise<T> {\n const url = new URL(`${this.baseUrl}${path}`);\n if (init.query) {\n for (const [k, v] of Object.entries(init.query)) {\n if (v !== undefined) url.searchParams.set(k, String(v));\n }\n }\n\n const controller = new AbortController();\n const timer = setTimeout(() => controller.abort(), this.timeoutMs);\n\n let res: Response;\n try {\n res = await this.fetchImpl(url.toString(), {\n method: init.method,\n headers: {\n Authorization: `Bearer ${this.apiKey}`,\n 'Content-Type': 'application/json',\n 'User-Agent': USER_AGENT,\n },\n body: init.body !== undefined ? JSON.stringify(init.body) : undefined,\n signal: controller.signal,\n });\n } finally {\n clearTimeout(timer);\n }\n\n const text = await res.text();\n let parsed: unknown = undefined;\n if (text) {\n try {\n parsed = JSON.parse(text);\n } catch {\n parsed = text;\n }\n }\n\n if (!res.ok) {\n const detail =\n parsed && typeof parsed === 'object' && parsed !== null && 'error' in parsed\n ? (parsed as { error: unknown }).error\n : parsed;\n throw new EngramError(\n `Engram API ${res.status}: ${typeof detail === 'string' ? detail : JSON.stringify(detail ?? '')}`,\n res.status,\n parsed,\n );\n }\n\n return parsed as T;\n }\n\n // ---------- Memories ----------\n\n async storeMemory(content: string, bucket: string = 'default'): Promise<StoreMemoryResult> {\n return this.request<StoreMemoryResult>(\n `/v1/buckets/${encodeURIComponent(bucket)}/memories`,\n { method: 'POST', body: { content } },\n );\n }\n\n async storeMemories(\n contents: string[],\n bucket: string = 'default',\n ): Promise<{ memories: StoreMemoryResult[] }> {\n // Defensively unwrap: depending on server version the batch endpoint\n // returns either { memories: [...] } or a bare array. Normalize to the\n // wrapped shape so callers don't have to switch on it.\n const result = await this.request<{ memories: StoreMemoryResult[] } | StoreMemoryResult[]>(\n `/v1/buckets/${encodeURIComponent(bucket)}/memories`,\n { method: 'POST', body: { memories: contents.map((content) => ({ content })) } },\n );\n return Array.isArray(result) ? { memories: result } : result;\n }\n\n async listMemories(\n bucket: string = 'default',\n options: ListMemoriesOptions = {},\n ): Promise<ListMemoriesResult> {\n return this.request<ListMemoriesResult>(\n `/v1/buckets/${encodeURIComponent(bucket)}/memories`,\n {\n method: 'GET',\n query: { limit: options.limit ?? 20, offset: options.offset ?? 0 },\n },\n );\n }\n\n async deleteMemory(memoryId: string, bucket: string = 'default'): Promise<void> {\n await this.request<unknown>(\n `/v1/buckets/${encodeURIComponent(bucket)}/memories/${encodeURIComponent(memoryId)}`,\n { method: 'DELETE' },\n );\n }\n\n async clearMemories(bucket: string): Promise<ClearMemoriesResult> {\n const res = await this.request<ClearMemoriesResult>(\n `/v1/buckets/${encodeURIComponent(bucket)}/memories`,\n { method: 'DELETE' },\n );\n // Defensive default: older servers / proxies may strip the body. The\n // contract surface is {success, cleared_count}; if the server stayed\n // silent we still return the same shape so callers can rely on it.\n return res ?? { success: true, cleared_count: 0 };\n }\n\n // ---------- Query ----------\n\n async query(question: string, options: QueryOptions = {}): Promise<QueryResult> {\n const buckets = options.buckets ?? ['default'];\n return this.request<QueryResult>('/v1/query', {\n method: 'POST',\n body: {\n query: question,\n buckets,\n options: {\n top_k: options.topK ?? 8,\n return_explanation: options.returnExplanation ?? true,\n skip_synthesis: options.skipSynthesis ?? false,\n },\n },\n });\n }\n\n // ---------- Buckets ----------\n\n async listBuckets(): Promise<Bucket[]> {\n const result = await this.request<{ buckets: Bucket[] } | Bucket[]>(`/v1/buckets`, {\n method: 'GET',\n });\n return Array.isArray(result) ? result : result.buckets;\n }\n\n async createBucket(name: string, description?: string): Promise<Bucket> {\n return this.request<Bucket>('/v1/buckets', {\n method: 'POST',\n body: { name, description },\n });\n }\n\n async deleteBucket(bucket: string): Promise<void> {\n await this.request<unknown>(`/v1/buckets/${encodeURIComponent(bucket)}`, {\n method: 'DELETE',\n });\n }\n\n // ---------- Profile ----------\n\n async getProfile(bucket: string = 'default'): Promise<{ profile: string | null }> {\n return this.request<{ profile: string | null }>(\n `/v1/buckets/${encodeURIComponent(bucket)}/profile`,\n { method: 'GET' },\n );\n }\n\n async regenerateProfile(bucket: string = 'default'): Promise<{ profile: string | null }> {\n return this.request<{ profile: string | null }>(\n `/v1/buckets/${encodeURIComponent(bucket)}/profile/regenerate`,\n { method: 'POST' },\n );\n }\n}\n"]}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@lumetra/engram",
3
- "version": "0.1.0",
3
+ "version": "0.2.0",
4
4
  "description": "Official TypeScript client for Engram — durable, explainable memory for AI agents.",
5
5
  "keywords": [
6
6
  "engram",
@@ -47,8 +47,9 @@
47
47
  "build": "tsup",
48
48
  "dev": "tsup --watch",
49
49
  "typecheck": "tsc --noEmit",
50
+ "test": "npm run build && node --test test/*.test.mjs",
50
51
  "clean": "rm -rf dist",
51
- "prepublishOnly": "npm run clean && npm run typecheck && npm run build"
52
+ "prepublishOnly": "npm run clean && npm run typecheck && npm run build && npm test"
52
53
  },
53
54
  "devDependencies": {
54
55
  "@types/node": "^20.11.0",