@lumetra/engram 0.3.1 → 0.3.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/index.cjs +1 -1
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +17 -0
- package/dist/index.d.ts +17 -0
- package/dist/index.js +1 -1
- package/dist/index.js.map +1 -1
- package/package.json +1 -1
package/dist/index.cjs
CHANGED
|
@@ -18,7 +18,7 @@ var DEFAULT_TIMEOUT_MS = 3e4;
|
|
|
18
18
|
var DEFAULT_STREAM_TIMEOUT_MS = 3e5;
|
|
19
19
|
var DEFAULT_MAX_RETRIES_ON_429 = 3;
|
|
20
20
|
var RETRY_AFTER_CAP_MS = 3e4;
|
|
21
|
-
var SDK_VERSION = "0.3.
|
|
21
|
+
var SDK_VERSION = "0.3.2";
|
|
22
22
|
var USER_AGENT = `engram-js/${SDK_VERSION}`;
|
|
23
23
|
function parseRetryAfterMs(header, defaultBackoffMs) {
|
|
24
24
|
if (header) {
|
package/dist/index.cjs.map
CHANGED
|
@@ -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 for buffered (non-streaming) calls.\n * Defaults to 30000 (30s).\n */\n timeoutMs?: number;\n /**\n * Timeout in milliseconds for `queryStream` calls. Streaming responses\n * can sit in the prep phase (retrieval + extractor pass) for 5–15s\n * before the first synthesis token arrives, so the buffered 30s\n * default would leave no headroom for the streamed body. Defaults to\n * 300000 (5 min). Use a higher value for very large synthesis bodies.\n */\n streamTimeoutMs?: number;\n /**\n * How many times to retry on a 429 (per-tenant concurrent-request cap).\n * Honors the server's `Retry-After` header, capped at 30s per sleep.\n * Defaults to 3. Set to 0 to disable retry and surface 429 as `EngramError`\n * on the first attempt.\n */\n maxRetriesOn429?: 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\n/**\n * One frame yielded by {@link EngramClient.queryStream}.\n *\n * The shape is discriminated by `type`:\n * - `delta` frames carry an incremental piece of the answer in `content`.\n * - `done` carries the final usage + (optional) explanation. Emitted\n * exactly once at the end of the stream.\n */\nexport type QueryStreamEvent =\n | { type: 'delta'; content: string }\n | {\n type: 'done';\n usage?: QueryUsage;\n synthesis_usage?: unknown;\n explanation?: QueryExplanation;\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 QueryStreamEvent,\n type StoreMemoryResult,\n} from './types.js';\n\nconst DEFAULT_BASE_URL = 'https://api.lumetra.io';\nconst DEFAULT_TIMEOUT_MS = 30_000;\nconst DEFAULT_STREAM_TIMEOUT_MS = 300_000;\nconst DEFAULT_MAX_RETRIES_ON_429 = 3;\n// Cap on per-attempt backoff so a misconfigured server can't force\n// callers to sleep for minutes.\nconst RETRY_AFTER_CAP_MS = 30_000;\nconst SDK_VERSION = '0.3.1';\nconst USER_AGENT = `engram-js/${SDK_VERSION}`;\n\nfunction parseRetryAfterMs(header: string | null, defaultBackoffMs: number): number {\n if (header) {\n const value = Number(header.trim());\n if (Number.isFinite(value) && value >= 0) {\n return Math.min(value * 1000, RETRY_AFTER_CAP_MS);\n }\n }\n return Math.min(defaultBackoffMs, RETRY_AFTER_CAP_MS);\n}\n\nfunction sleep(ms: number): Promise<void> {\n return new Promise((resolve) => setTimeout(resolve, ms));\n}\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 private readonly streamTimeoutMs: number;\n private readonly maxRetriesOn429: 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 this.streamTimeoutMs = options.streamTimeoutMs ?? DEFAULT_STREAM_TIMEOUT_MS;\n this.maxRetriesOn429 = Math.max(0, options.maxRetriesOn429 ?? DEFAULT_MAX_RETRIES_ON_429);\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 // 429-aware retry. The Engram API enforces a per-tenant concurrent-\n // request cap and sets Retry-After on 429s; without retry handling,\n // bursty clients fail immediately under load. The body is JSON-\n // serialized once outside the loop so each attempt sends an\n // identical request.\n const requestBody = init.body !== undefined ? JSON.stringify(init.body) : undefined;\n let attemptsRemaining = this.maxRetriesOn429;\n let backoffMs = 1000;\n\n // eslint-disable-next-line no-constant-condition\n while (true) {\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: requestBody,\n signal: controller.signal,\n });\n } finally {\n clearTimeout(timer);\n }\n\n if (res.status === 429 && attemptsRemaining > 0) {\n // Drain the body so the connection can return to the pool.\n await res.text().catch(() => undefined);\n const delay = parseRetryAfterMs(res.headers.get('Retry-After'), backoffMs);\n await sleep(delay);\n attemptsRemaining -= 1;\n backoffMs = Math.min(backoffMs * 2, RETRY_AFTER_CAP_MS);\n continue;\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\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 /**\n * Streaming variant of {@link query}. Returns an async-iterable that\n * yields {@link QueryStreamEvent} frames as the server produces them:\n *\n * for await (const ev of engram.queryStream('...')) {\n * if (ev.type === 'delta') process.stdout.write(ev.content);\n * else if (ev.type === 'done') console.log(ev.usage);\n * }\n *\n * Break out of the loop to abort the request (the underlying\n * AbortController is wired up to the fetch call).\n */\n queryStream(question: string, options: QueryOptions = {}): AsyncIterable<QueryStreamEvent> {\n const buckets = options.buckets ?? ['default'];\n const body = {\n query: question,\n buckets,\n stream: true,\n options: {\n top_k: options.topK ?? 8,\n return_explanation: options.returnExplanation ?? true,\n skip_synthesis: options.skipSynthesis ?? false,\n },\n };\n const url = `${this.baseUrl}/v1/query`;\n const apiKey = this.apiKey;\n const fetchImpl = this.fetchImpl;\n const timeoutMs = this.streamTimeoutMs;\n const maxRetriesOn429 = this.maxRetriesOn429;\n const bodyJson = JSON.stringify(body);\n\n return {\n [Symbol.asyncIterator]: () => {\n const controller = new AbortController();\n // The timeout caps total wall-clock for the stream. Set generously\n // because synthesis can run 10–25s before the first byte even with\n // streaming on slow paths; clamp to the user's configured timeout.\n const timer = setTimeout(() => controller.abort(), timeoutMs);\n\n let started = false;\n let reader: ReadableStreamDefaultReader<Uint8Array> | null = null;\n const decoder = new TextDecoder('utf-8');\n let buffer = '';\n let done = false;\n const queue: QueryStreamEvent[] = [];\n let pendingError: unknown = null;\n\n const ensureStarted = async (): Promise<void> => {\n if (started) return;\n started = true;\n // 429-aware retry at the connection-open stage only. Once\n // the response body starts flowing we can't resume mid-\n // stream safely.\n let attemptsRemaining = maxRetriesOn429;\n let backoffMs = 1000;\n // eslint-disable-next-line no-constant-condition\n while (true) {\n const res = await fetchImpl(url, {\n method: 'POST',\n headers: {\n Authorization: `Bearer ${apiKey}`,\n 'Content-Type': 'application/json',\n Accept: 'text/event-stream',\n 'User-Agent': USER_AGENT,\n },\n body: bodyJson,\n signal: controller.signal,\n });\n if (res.status === 429 && attemptsRemaining > 0) {\n await res.text().catch(() => undefined);\n const delay = parseRetryAfterMs(res.headers.get('Retry-After'), backoffMs);\n await sleep(delay);\n attemptsRemaining -= 1;\n backoffMs = Math.min(backoffMs * 2, RETRY_AFTER_CAP_MS);\n continue;\n }\n if (!res.ok) {\n const text = await res.text().catch(() => '');\n let parsed: unknown = text;\n try {\n parsed = text ? JSON.parse(text) : text;\n } catch {\n /* keep raw text */\n }\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 if (!res.body) {\n throw new EngramError('Engram API: streaming response has no body', res.status, null);\n }\n reader = res.body.getReader();\n return;\n }\n };\n\n const drainBuffer = (): void => {\n // SSE frames are separated by a blank line ('\\n\\n'). Each frame\n // is one or more 'field: value' lines. We only care about\n // 'data:' lines for this stream.\n let idx: number;\n while ((idx = buffer.indexOf('\\n\\n')) !== -1) {\n const frame = buffer.slice(0, idx);\n buffer = buffer.slice(idx + 2);\n const dataLines: string[] = [];\n for (const rawLine of frame.split('\\n')) {\n const line = rawLine.endsWith('\\r') ? rawLine.slice(0, -1) : rawLine;\n if (line.startsWith('data: ')) {\n dataLines.push(line.slice(6));\n } else if (line.startsWith('data:')) {\n dataLines.push(line.slice(5));\n }\n }\n if (dataLines.length === 0) continue;\n const payloadStr = dataLines.join('\\n');\n if (payloadStr === '[DONE]') {\n done = true;\n return;\n }\n let payload: unknown;\n try {\n payload = JSON.parse(payloadStr);\n } catch {\n // Malformed frame — skip rather than corrupt the stream.\n continue;\n }\n if (payload && typeof payload === 'object') {\n const obj = payload as Record<string, unknown>;\n if (obj.error) {\n pendingError = new EngramError(String(obj.error), 0, obj);\n done = true;\n return;\n }\n // OpenAI-style delta chunk\n const choices = obj.choices as Array<{ delta?: { content?: string } }> | undefined;\n if (Array.isArray(choices) && choices.length > 0) {\n const delta = choices[0]?.delta?.content;\n if (typeof delta === 'string' && delta.length > 0) {\n queue.push({ type: 'delta', content: delta });\n }\n continue;\n }\n // Final usage / explanation frame (no 'choices' key).\n queue.push({ type: 'done', ...(obj as Omit<Extract<QueryStreamEvent, { type: 'done' }>, 'type'>) });\n }\n }\n };\n\n return {\n next: async (): Promise<IteratorResult<QueryStreamEvent>> => {\n try {\n await ensureStarted();\n } catch (err) {\n clearTimeout(timer);\n throw err;\n }\n while (queue.length === 0 && !done) {\n if (!reader) {\n clearTimeout(timer);\n throw new EngramError('Engram API: stream reader missing', 0, null);\n }\n const chunk = await reader.read();\n if (chunk.done) {\n // Flush whatever's left in the buffer (some servers don't\n // terminate with a trailing blank line).\n if (buffer.length > 0) {\n buffer += '\\n\\n';\n drainBuffer();\n }\n done = true;\n break;\n }\n buffer += decoder.decode(chunk.value, { stream: true });\n drainBuffer();\n }\n if (queue.length > 0) {\n return { value: queue.shift() as QueryStreamEvent, done: false };\n }\n clearTimeout(timer);\n if (pendingError) throw pendingError;\n return { value: undefined as unknown as QueryStreamEvent, done: true };\n },\n return: async (): Promise<IteratorResult<QueryStreamEvent>> => {\n // Caller broke out of the for-await loop — cancel the upstream\n // request so we're not holding the connection open.\n clearTimeout(timer);\n controller.abort();\n try {\n await reader?.cancel();\n } catch {\n /* ignored */\n }\n return { value: undefined as unknown as QueryStreamEvent, done: true };\n },\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 for buffered (non-streaming) calls.\n * Defaults to 30000 (30s).\n */\n timeoutMs?: number;\n /**\n * Timeout in milliseconds for `queryStream` calls. Streaming responses\n * can sit in the prep phase (retrieval + extractor pass) for 5–15s\n * before the first synthesis token arrives, so the buffered 30s\n * default would leave no headroom for the streamed body. Defaults to\n * 300000 (5 min). Use a higher value for very large synthesis bodies.\n */\n streamTimeoutMs?: number;\n /**\n * How many times to retry on a 429 (per-tenant concurrent-request cap).\n * Honors the server's `Retry-After` header, capped at 30s per sleep.\n * Defaults to 3. Set to 0 to disable retry and surface 429 as `EngramError`\n * on the first attempt.\n */\n maxRetriesOn429?: number;\n}\n\nexport interface Bucket {\n id: string;\n name: string;\n /**\n * Mirror of `name`. The server emits both so callers iterating both\n * `listBuckets` and `storeMemory` responses can use one field name.\n * Prefer `name` in new code.\n */\n bucket_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 /**\n * Alias for `id` — older API docs / older SDKs referenced this name.\n * Always present; prefer `id` in new code.\n */\n memory_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 /**\n * Top-level count of retrieved memories. Equivalent to\n * `result.explanation?.retrieved_memories.length` but present even\n * when `returnExplanation` is false.\n */\n memories_found?: number;\n explanation?: QueryExplanation;\n usage?: QueryUsage;\n}\n\n/**\n * One frame yielded by {@link EngramClient.queryStream}.\n *\n * The shape is discriminated by `type`:\n * - `delta` frames carry an incremental piece of the answer in `content`.\n * - `done` carries the final usage + (optional) explanation. Emitted\n * exactly once at the end of the stream.\n */\nexport type QueryStreamEvent =\n | { type: 'delta'; content: string }\n | {\n type: 'done';\n usage?: QueryUsage;\n synthesis_usage?: unknown;\n explanation?: QueryExplanation;\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 QueryStreamEvent,\n type StoreMemoryResult,\n} from './types.js';\n\nconst DEFAULT_BASE_URL = 'https://api.lumetra.io';\nconst DEFAULT_TIMEOUT_MS = 30_000;\nconst DEFAULT_STREAM_TIMEOUT_MS = 300_000;\nconst DEFAULT_MAX_RETRIES_ON_429 = 3;\n// Cap on per-attempt backoff so a misconfigured server can't force\n// callers to sleep for minutes.\nconst RETRY_AFTER_CAP_MS = 30_000;\nconst SDK_VERSION = '0.3.2';\nconst USER_AGENT = `engram-js/${SDK_VERSION}`;\n\nfunction parseRetryAfterMs(header: string | null, defaultBackoffMs: number): number {\n if (header) {\n const value = Number(header.trim());\n if (Number.isFinite(value) && value >= 0) {\n return Math.min(value * 1000, RETRY_AFTER_CAP_MS);\n }\n }\n return Math.min(defaultBackoffMs, RETRY_AFTER_CAP_MS);\n}\n\nfunction sleep(ms: number): Promise<void> {\n return new Promise((resolve) => setTimeout(resolve, ms));\n}\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 private readonly streamTimeoutMs: number;\n private readonly maxRetriesOn429: 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 this.streamTimeoutMs = options.streamTimeoutMs ?? DEFAULT_STREAM_TIMEOUT_MS;\n this.maxRetriesOn429 = Math.max(0, options.maxRetriesOn429 ?? DEFAULT_MAX_RETRIES_ON_429);\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 // 429-aware retry. The Engram API enforces a per-tenant concurrent-\n // request cap and sets Retry-After on 429s; without retry handling,\n // bursty clients fail immediately under load. The body is JSON-\n // serialized once outside the loop so each attempt sends an\n // identical request.\n const requestBody = init.body !== undefined ? JSON.stringify(init.body) : undefined;\n let attemptsRemaining = this.maxRetriesOn429;\n let backoffMs = 1000;\n\n // eslint-disable-next-line no-constant-condition\n while (true) {\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: requestBody,\n signal: controller.signal,\n });\n } finally {\n clearTimeout(timer);\n }\n\n if (res.status === 429 && attemptsRemaining > 0) {\n // Drain the body so the connection can return to the pool.\n await res.text().catch(() => undefined);\n const delay = parseRetryAfterMs(res.headers.get('Retry-After'), backoffMs);\n await sleep(delay);\n attemptsRemaining -= 1;\n backoffMs = Math.min(backoffMs * 2, RETRY_AFTER_CAP_MS);\n continue;\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\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 /**\n * Streaming variant of {@link query}. Returns an async-iterable that\n * yields {@link QueryStreamEvent} frames as the server produces them:\n *\n * for await (const ev of engram.queryStream('...')) {\n * if (ev.type === 'delta') process.stdout.write(ev.content);\n * else if (ev.type === 'done') console.log(ev.usage);\n * }\n *\n * Break out of the loop to abort the request (the underlying\n * AbortController is wired up to the fetch call).\n */\n queryStream(question: string, options: QueryOptions = {}): AsyncIterable<QueryStreamEvent> {\n const buckets = options.buckets ?? ['default'];\n const body = {\n query: question,\n buckets,\n stream: true,\n options: {\n top_k: options.topK ?? 8,\n return_explanation: options.returnExplanation ?? true,\n skip_synthesis: options.skipSynthesis ?? false,\n },\n };\n const url = `${this.baseUrl}/v1/query`;\n const apiKey = this.apiKey;\n const fetchImpl = this.fetchImpl;\n const timeoutMs = this.streamTimeoutMs;\n const maxRetriesOn429 = this.maxRetriesOn429;\n const bodyJson = JSON.stringify(body);\n\n return {\n [Symbol.asyncIterator]: () => {\n const controller = new AbortController();\n // The timeout caps total wall-clock for the stream. Set generously\n // because synthesis can run 10–25s before the first byte even with\n // streaming on slow paths; clamp to the user's configured timeout.\n const timer = setTimeout(() => controller.abort(), timeoutMs);\n\n let started = false;\n let reader: ReadableStreamDefaultReader<Uint8Array> | null = null;\n const decoder = new TextDecoder('utf-8');\n let buffer = '';\n let done = false;\n const queue: QueryStreamEvent[] = [];\n let pendingError: unknown = null;\n\n const ensureStarted = async (): Promise<void> => {\n if (started) return;\n started = true;\n // 429-aware retry at the connection-open stage only. Once\n // the response body starts flowing we can't resume mid-\n // stream safely.\n let attemptsRemaining = maxRetriesOn429;\n let backoffMs = 1000;\n // eslint-disable-next-line no-constant-condition\n while (true) {\n const res = await fetchImpl(url, {\n method: 'POST',\n headers: {\n Authorization: `Bearer ${apiKey}`,\n 'Content-Type': 'application/json',\n Accept: 'text/event-stream',\n 'User-Agent': USER_AGENT,\n },\n body: bodyJson,\n signal: controller.signal,\n });\n if (res.status === 429 && attemptsRemaining > 0) {\n await res.text().catch(() => undefined);\n const delay = parseRetryAfterMs(res.headers.get('Retry-After'), backoffMs);\n await sleep(delay);\n attemptsRemaining -= 1;\n backoffMs = Math.min(backoffMs * 2, RETRY_AFTER_CAP_MS);\n continue;\n }\n if (!res.ok) {\n const text = await res.text().catch(() => '');\n let parsed: unknown = text;\n try {\n parsed = text ? JSON.parse(text) : text;\n } catch {\n /* keep raw text */\n }\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 if (!res.body) {\n throw new EngramError('Engram API: streaming response has no body', res.status, null);\n }\n reader = res.body.getReader();\n return;\n }\n };\n\n const drainBuffer = (): void => {\n // SSE frames are separated by a blank line ('\\n\\n'). Each frame\n // is one or more 'field: value' lines. We only care about\n // 'data:' lines for this stream.\n let idx: number;\n while ((idx = buffer.indexOf('\\n\\n')) !== -1) {\n const frame = buffer.slice(0, idx);\n buffer = buffer.slice(idx + 2);\n const dataLines: string[] = [];\n for (const rawLine of frame.split('\\n')) {\n const line = rawLine.endsWith('\\r') ? rawLine.slice(0, -1) : rawLine;\n if (line.startsWith('data: ')) {\n dataLines.push(line.slice(6));\n } else if (line.startsWith('data:')) {\n dataLines.push(line.slice(5));\n }\n }\n if (dataLines.length === 0) continue;\n const payloadStr = dataLines.join('\\n');\n if (payloadStr === '[DONE]') {\n done = true;\n return;\n }\n let payload: unknown;\n try {\n payload = JSON.parse(payloadStr);\n } catch {\n // Malformed frame — skip rather than corrupt the stream.\n continue;\n }\n if (payload && typeof payload === 'object') {\n const obj = payload as Record<string, unknown>;\n if (obj.error) {\n pendingError = new EngramError(String(obj.error), 0, obj);\n done = true;\n return;\n }\n // OpenAI-style delta chunk\n const choices = obj.choices as Array<{ delta?: { content?: string } }> | undefined;\n if (Array.isArray(choices) && choices.length > 0) {\n const delta = choices[0]?.delta?.content;\n if (typeof delta === 'string' && delta.length > 0) {\n queue.push({ type: 'delta', content: delta });\n }\n continue;\n }\n // Final usage / explanation frame (no 'choices' key).\n queue.push({ type: 'done', ...(obj as Omit<Extract<QueryStreamEvent, { type: 'done' }>, 'type'>) });\n }\n }\n };\n\n return {\n next: async (): Promise<IteratorResult<QueryStreamEvent>> => {\n try {\n await ensureStarted();\n } catch (err) {\n clearTimeout(timer);\n throw err;\n }\n while (queue.length === 0 && !done) {\n if (!reader) {\n clearTimeout(timer);\n throw new EngramError('Engram API: stream reader missing', 0, null);\n }\n const chunk = await reader.read();\n if (chunk.done) {\n // Flush whatever's left in the buffer (some servers don't\n // terminate with a trailing blank line).\n if (buffer.length > 0) {\n buffer += '\\n\\n';\n drainBuffer();\n }\n done = true;\n break;\n }\n buffer += decoder.decode(chunk.value, { stream: true });\n drainBuffer();\n }\n if (queue.length > 0) {\n return { value: queue.shift() as QueryStreamEvent, done: false };\n }\n clearTimeout(timer);\n if (pendingError) throw pendingError;\n return { value: undefined as unknown as QueryStreamEvent, done: true };\n },\n return: async (): Promise<IteratorResult<QueryStreamEvent>> => {\n // Caller broke out of the for-await loop — cancel the upstream\n // request so we're not holding the connection open.\n clearTimeout(timer);\n controller.abort();\n try {\n await reader?.cancel();\n } catch {\n /* ignored */\n }\n return { value: undefined as unknown as QueryStreamEvent, done: true };\n },\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,12 @@ interface EngramClientOptions {
|
|
|
36
36
|
interface Bucket {
|
|
37
37
|
id: string;
|
|
38
38
|
name: string;
|
|
39
|
+
/**
|
|
40
|
+
* Mirror of `name`. The server emits both so callers iterating both
|
|
41
|
+
* `listBuckets` and `storeMemory` responses can use one field name.
|
|
42
|
+
* Prefer `name` in new code.
|
|
43
|
+
*/
|
|
44
|
+
bucket_name?: string;
|
|
39
45
|
description?: string | null;
|
|
40
46
|
created_at: string;
|
|
41
47
|
memory_count?: number;
|
|
@@ -49,6 +55,11 @@ interface Memory {
|
|
|
49
55
|
}
|
|
50
56
|
interface StoreMemoryResult {
|
|
51
57
|
id: string;
|
|
58
|
+
/**
|
|
59
|
+
* Alias for `id` — older API docs / older SDKs referenced this name.
|
|
60
|
+
* Always present; prefer `id` in new code.
|
|
61
|
+
*/
|
|
62
|
+
memory_id?: string;
|
|
52
63
|
bucket_name: string;
|
|
53
64
|
token_count: number;
|
|
54
65
|
}
|
|
@@ -75,6 +86,12 @@ interface QueryUsage {
|
|
|
75
86
|
}
|
|
76
87
|
interface QueryResult {
|
|
77
88
|
answer: string;
|
|
89
|
+
/**
|
|
90
|
+
* Top-level count of retrieved memories. Equivalent to
|
|
91
|
+
* `result.explanation?.retrieved_memories.length` but present even
|
|
92
|
+
* when `returnExplanation` is false.
|
|
93
|
+
*/
|
|
94
|
+
memories_found?: number;
|
|
78
95
|
explanation?: QueryExplanation;
|
|
79
96
|
usage?: QueryUsage;
|
|
80
97
|
}
|
package/dist/index.d.ts
CHANGED
|
@@ -36,6 +36,12 @@ interface EngramClientOptions {
|
|
|
36
36
|
interface Bucket {
|
|
37
37
|
id: string;
|
|
38
38
|
name: string;
|
|
39
|
+
/**
|
|
40
|
+
* Mirror of `name`. The server emits both so callers iterating both
|
|
41
|
+
* `listBuckets` and `storeMemory` responses can use one field name.
|
|
42
|
+
* Prefer `name` in new code.
|
|
43
|
+
*/
|
|
44
|
+
bucket_name?: string;
|
|
39
45
|
description?: string | null;
|
|
40
46
|
created_at: string;
|
|
41
47
|
memory_count?: number;
|
|
@@ -49,6 +55,11 @@ interface Memory {
|
|
|
49
55
|
}
|
|
50
56
|
interface StoreMemoryResult {
|
|
51
57
|
id: string;
|
|
58
|
+
/**
|
|
59
|
+
* Alias for `id` — older API docs / older SDKs referenced this name.
|
|
60
|
+
* Always present; prefer `id` in new code.
|
|
61
|
+
*/
|
|
62
|
+
memory_id?: string;
|
|
52
63
|
bucket_name: string;
|
|
53
64
|
token_count: number;
|
|
54
65
|
}
|
|
@@ -75,6 +86,12 @@ interface QueryUsage {
|
|
|
75
86
|
}
|
|
76
87
|
interface QueryResult {
|
|
77
88
|
answer: string;
|
|
89
|
+
/**
|
|
90
|
+
* Top-level count of retrieved memories. Equivalent to
|
|
91
|
+
* `result.explanation?.retrieved_memories.length` but present even
|
|
92
|
+
* when `returnExplanation` is false.
|
|
93
|
+
*/
|
|
94
|
+
memories_found?: number;
|
|
78
95
|
explanation?: QueryExplanation;
|
|
79
96
|
usage?: QueryUsage;
|
|
80
97
|
}
|
package/dist/index.js
CHANGED
|
@@ -16,7 +16,7 @@ var DEFAULT_TIMEOUT_MS = 3e4;
|
|
|
16
16
|
var DEFAULT_STREAM_TIMEOUT_MS = 3e5;
|
|
17
17
|
var DEFAULT_MAX_RETRIES_ON_429 = 3;
|
|
18
18
|
var RETRY_AFTER_CAP_MS = 3e4;
|
|
19
|
-
var SDK_VERSION = "0.3.
|
|
19
|
+
var SDK_VERSION = "0.3.2";
|
|
20
20
|
var USER_AGENT = `engram-js/${SDK_VERSION}`;
|
|
21
21
|
function parseRetryAfterMs(header, defaultBackoffMs) {
|
|
22
22
|
if (header) {
|
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 for buffered (non-streaming) calls.\n * Defaults to 30000 (30s).\n */\n timeoutMs?: number;\n /**\n * Timeout in milliseconds for `queryStream` calls. Streaming responses\n * can sit in the prep phase (retrieval + extractor pass) for 5–15s\n * before the first synthesis token arrives, so the buffered 30s\n * default would leave no headroom for the streamed body. Defaults to\n * 300000 (5 min). Use a higher value for very large synthesis bodies.\n */\n streamTimeoutMs?: number;\n /**\n * How many times to retry on a 429 (per-tenant concurrent-request cap).\n * Honors the server's `Retry-After` header, capped at 30s per sleep.\n * Defaults to 3. Set to 0 to disable retry and surface 429 as `EngramError`\n * on the first attempt.\n */\n maxRetriesOn429?: 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\n/**\n * One frame yielded by {@link EngramClient.queryStream}.\n *\n * The shape is discriminated by `type`:\n * - `delta` frames carry an incremental piece of the answer in `content`.\n * - `done` carries the final usage + (optional) explanation. Emitted\n * exactly once at the end of the stream.\n */\nexport type QueryStreamEvent =\n | { type: 'delta'; content: string }\n | {\n type: 'done';\n usage?: QueryUsage;\n synthesis_usage?: unknown;\n explanation?: QueryExplanation;\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 QueryStreamEvent,\n type StoreMemoryResult,\n} from './types.js';\n\nconst DEFAULT_BASE_URL = 'https://api.lumetra.io';\nconst DEFAULT_TIMEOUT_MS = 30_000;\nconst DEFAULT_STREAM_TIMEOUT_MS = 300_000;\nconst DEFAULT_MAX_RETRIES_ON_429 = 3;\n// Cap on per-attempt backoff so a misconfigured server can't force\n// callers to sleep for minutes.\nconst RETRY_AFTER_CAP_MS = 30_000;\nconst SDK_VERSION = '0.3.1';\nconst USER_AGENT = `engram-js/${SDK_VERSION}`;\n\nfunction parseRetryAfterMs(header: string | null, defaultBackoffMs: number): number {\n if (header) {\n const value = Number(header.trim());\n if (Number.isFinite(value) && value >= 0) {\n return Math.min(value * 1000, RETRY_AFTER_CAP_MS);\n }\n }\n return Math.min(defaultBackoffMs, RETRY_AFTER_CAP_MS);\n}\n\nfunction sleep(ms: number): Promise<void> {\n return new Promise((resolve) => setTimeout(resolve, ms));\n}\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 private readonly streamTimeoutMs: number;\n private readonly maxRetriesOn429: 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 this.streamTimeoutMs = options.streamTimeoutMs ?? DEFAULT_STREAM_TIMEOUT_MS;\n this.maxRetriesOn429 = Math.max(0, options.maxRetriesOn429 ?? DEFAULT_MAX_RETRIES_ON_429);\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 // 429-aware retry. The Engram API enforces a per-tenant concurrent-\n // request cap and sets Retry-After on 429s; without retry handling,\n // bursty clients fail immediately under load. The body is JSON-\n // serialized once outside the loop so each attempt sends an\n // identical request.\n const requestBody = init.body !== undefined ? JSON.stringify(init.body) : undefined;\n let attemptsRemaining = this.maxRetriesOn429;\n let backoffMs = 1000;\n\n // eslint-disable-next-line no-constant-condition\n while (true) {\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: requestBody,\n signal: controller.signal,\n });\n } finally {\n clearTimeout(timer);\n }\n\n if (res.status === 429 && attemptsRemaining > 0) {\n // Drain the body so the connection can return to the pool.\n await res.text().catch(() => undefined);\n const delay = parseRetryAfterMs(res.headers.get('Retry-After'), backoffMs);\n await sleep(delay);\n attemptsRemaining -= 1;\n backoffMs = Math.min(backoffMs * 2, RETRY_AFTER_CAP_MS);\n continue;\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\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 /**\n * Streaming variant of {@link query}. Returns an async-iterable that\n * yields {@link QueryStreamEvent} frames as the server produces them:\n *\n * for await (const ev of engram.queryStream('...')) {\n * if (ev.type === 'delta') process.stdout.write(ev.content);\n * else if (ev.type === 'done') console.log(ev.usage);\n * }\n *\n * Break out of the loop to abort the request (the underlying\n * AbortController is wired up to the fetch call).\n */\n queryStream(question: string, options: QueryOptions = {}): AsyncIterable<QueryStreamEvent> {\n const buckets = options.buckets ?? ['default'];\n const body = {\n query: question,\n buckets,\n stream: true,\n options: {\n top_k: options.topK ?? 8,\n return_explanation: options.returnExplanation ?? true,\n skip_synthesis: options.skipSynthesis ?? false,\n },\n };\n const url = `${this.baseUrl}/v1/query`;\n const apiKey = this.apiKey;\n const fetchImpl = this.fetchImpl;\n const timeoutMs = this.streamTimeoutMs;\n const maxRetriesOn429 = this.maxRetriesOn429;\n const bodyJson = JSON.stringify(body);\n\n return {\n [Symbol.asyncIterator]: () => {\n const controller = new AbortController();\n // The timeout caps total wall-clock for the stream. Set generously\n // because synthesis can run 10–25s before the first byte even with\n // streaming on slow paths; clamp to the user's configured timeout.\n const timer = setTimeout(() => controller.abort(), timeoutMs);\n\n let started = false;\n let reader: ReadableStreamDefaultReader<Uint8Array> | null = null;\n const decoder = new TextDecoder('utf-8');\n let buffer = '';\n let done = false;\n const queue: QueryStreamEvent[] = [];\n let pendingError: unknown = null;\n\n const ensureStarted = async (): Promise<void> => {\n if (started) return;\n started = true;\n // 429-aware retry at the connection-open stage only. Once\n // the response body starts flowing we can't resume mid-\n // stream safely.\n let attemptsRemaining = maxRetriesOn429;\n let backoffMs = 1000;\n // eslint-disable-next-line no-constant-condition\n while (true) {\n const res = await fetchImpl(url, {\n method: 'POST',\n headers: {\n Authorization: `Bearer ${apiKey}`,\n 'Content-Type': 'application/json',\n Accept: 'text/event-stream',\n 'User-Agent': USER_AGENT,\n },\n body: bodyJson,\n signal: controller.signal,\n });\n if (res.status === 429 && attemptsRemaining > 0) {\n await res.text().catch(() => undefined);\n const delay = parseRetryAfterMs(res.headers.get('Retry-After'), backoffMs);\n await sleep(delay);\n attemptsRemaining -= 1;\n backoffMs = Math.min(backoffMs * 2, RETRY_AFTER_CAP_MS);\n continue;\n }\n if (!res.ok) {\n const text = await res.text().catch(() => '');\n let parsed: unknown = text;\n try {\n parsed = text ? JSON.parse(text) : text;\n } catch {\n /* keep raw text */\n }\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 if (!res.body) {\n throw new EngramError('Engram API: streaming response has no body', res.status, null);\n }\n reader = res.body.getReader();\n return;\n }\n };\n\n const drainBuffer = (): void => {\n // SSE frames are separated by a blank line ('\\n\\n'). Each frame\n // is one or more 'field: value' lines. We only care about\n // 'data:' lines for this stream.\n let idx: number;\n while ((idx = buffer.indexOf('\\n\\n')) !== -1) {\n const frame = buffer.slice(0, idx);\n buffer = buffer.slice(idx + 2);\n const dataLines: string[] = [];\n for (const rawLine of frame.split('\\n')) {\n const line = rawLine.endsWith('\\r') ? rawLine.slice(0, -1) : rawLine;\n if (line.startsWith('data: ')) {\n dataLines.push(line.slice(6));\n } else if (line.startsWith('data:')) {\n dataLines.push(line.slice(5));\n }\n }\n if (dataLines.length === 0) continue;\n const payloadStr = dataLines.join('\\n');\n if (payloadStr === '[DONE]') {\n done = true;\n return;\n }\n let payload: unknown;\n try {\n payload = JSON.parse(payloadStr);\n } catch {\n // Malformed frame — skip rather than corrupt the stream.\n continue;\n }\n if (payload && typeof payload === 'object') {\n const obj = payload as Record<string, unknown>;\n if (obj.error) {\n pendingError = new EngramError(String(obj.error), 0, obj);\n done = true;\n return;\n }\n // OpenAI-style delta chunk\n const choices = obj.choices as Array<{ delta?: { content?: string } }> | undefined;\n if (Array.isArray(choices) && choices.length > 0) {\n const delta = choices[0]?.delta?.content;\n if (typeof delta === 'string' && delta.length > 0) {\n queue.push({ type: 'delta', content: delta });\n }\n continue;\n }\n // Final usage / explanation frame (no 'choices' key).\n queue.push({ type: 'done', ...(obj as Omit<Extract<QueryStreamEvent, { type: 'done' }>, 'type'>) });\n }\n }\n };\n\n return {\n next: async (): Promise<IteratorResult<QueryStreamEvent>> => {\n try {\n await ensureStarted();\n } catch (err) {\n clearTimeout(timer);\n throw err;\n }\n while (queue.length === 0 && !done) {\n if (!reader) {\n clearTimeout(timer);\n throw new EngramError('Engram API: stream reader missing', 0, null);\n }\n const chunk = await reader.read();\n if (chunk.done) {\n // Flush whatever's left in the buffer (some servers don't\n // terminate with a trailing blank line).\n if (buffer.length > 0) {\n buffer += '\\n\\n';\n drainBuffer();\n }\n done = true;\n break;\n }\n buffer += decoder.decode(chunk.value, { stream: true });\n drainBuffer();\n }\n if (queue.length > 0) {\n return { value: queue.shift() as QueryStreamEvent, done: false };\n }\n clearTimeout(timer);\n if (pendingError) throw pendingError;\n return { value: undefined as unknown as QueryStreamEvent, done: true };\n },\n return: async (): Promise<IteratorResult<QueryStreamEvent>> => {\n // Caller broke out of the for-await loop — cancel the upstream\n // request so we're not holding the connection open.\n clearTimeout(timer);\n controller.abort();\n try {\n await reader?.cancel();\n } catch {\n /* ignored */\n }\n return { value: undefined as unknown as QueryStreamEvent, done: true };\n },\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 for buffered (non-streaming) calls.\n * Defaults to 30000 (30s).\n */\n timeoutMs?: number;\n /**\n * Timeout in milliseconds for `queryStream` calls. Streaming responses\n * can sit in the prep phase (retrieval + extractor pass) for 5–15s\n * before the first synthesis token arrives, so the buffered 30s\n * default would leave no headroom for the streamed body. Defaults to\n * 300000 (5 min). Use a higher value for very large synthesis bodies.\n */\n streamTimeoutMs?: number;\n /**\n * How many times to retry on a 429 (per-tenant concurrent-request cap).\n * Honors the server's `Retry-After` header, capped at 30s per sleep.\n * Defaults to 3. Set to 0 to disable retry and surface 429 as `EngramError`\n * on the first attempt.\n */\n maxRetriesOn429?: number;\n}\n\nexport interface Bucket {\n id: string;\n name: string;\n /**\n * Mirror of `name`. The server emits both so callers iterating both\n * `listBuckets` and `storeMemory` responses can use one field name.\n * Prefer `name` in new code.\n */\n bucket_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 /**\n * Alias for `id` — older API docs / older SDKs referenced this name.\n * Always present; prefer `id` in new code.\n */\n memory_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 /**\n * Top-level count of retrieved memories. Equivalent to\n * `result.explanation?.retrieved_memories.length` but present even\n * when `returnExplanation` is false.\n */\n memories_found?: number;\n explanation?: QueryExplanation;\n usage?: QueryUsage;\n}\n\n/**\n * One frame yielded by {@link EngramClient.queryStream}.\n *\n * The shape is discriminated by `type`:\n * - `delta` frames carry an incremental piece of the answer in `content`.\n * - `done` carries the final usage + (optional) explanation. Emitted\n * exactly once at the end of the stream.\n */\nexport type QueryStreamEvent =\n | { type: 'delta'; content: string }\n | {\n type: 'done';\n usage?: QueryUsage;\n synthesis_usage?: unknown;\n explanation?: QueryExplanation;\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 QueryStreamEvent,\n type StoreMemoryResult,\n} from './types.js';\n\nconst DEFAULT_BASE_URL = 'https://api.lumetra.io';\nconst DEFAULT_TIMEOUT_MS = 30_000;\nconst DEFAULT_STREAM_TIMEOUT_MS = 300_000;\nconst DEFAULT_MAX_RETRIES_ON_429 = 3;\n// Cap on per-attempt backoff so a misconfigured server can't force\n// callers to sleep for minutes.\nconst RETRY_AFTER_CAP_MS = 30_000;\nconst SDK_VERSION = '0.3.2';\nconst USER_AGENT = `engram-js/${SDK_VERSION}`;\n\nfunction parseRetryAfterMs(header: string | null, defaultBackoffMs: number): number {\n if (header) {\n const value = Number(header.trim());\n if (Number.isFinite(value) && value >= 0) {\n return Math.min(value * 1000, RETRY_AFTER_CAP_MS);\n }\n }\n return Math.min(defaultBackoffMs, RETRY_AFTER_CAP_MS);\n}\n\nfunction sleep(ms: number): Promise<void> {\n return new Promise((resolve) => setTimeout(resolve, ms));\n}\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 private readonly streamTimeoutMs: number;\n private readonly maxRetriesOn429: 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 this.streamTimeoutMs = options.streamTimeoutMs ?? DEFAULT_STREAM_TIMEOUT_MS;\n this.maxRetriesOn429 = Math.max(0, options.maxRetriesOn429 ?? DEFAULT_MAX_RETRIES_ON_429);\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 // 429-aware retry. The Engram API enforces a per-tenant concurrent-\n // request cap and sets Retry-After on 429s; without retry handling,\n // bursty clients fail immediately under load. The body is JSON-\n // serialized once outside the loop so each attempt sends an\n // identical request.\n const requestBody = init.body !== undefined ? JSON.stringify(init.body) : undefined;\n let attemptsRemaining = this.maxRetriesOn429;\n let backoffMs = 1000;\n\n // eslint-disable-next-line no-constant-condition\n while (true) {\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: requestBody,\n signal: controller.signal,\n });\n } finally {\n clearTimeout(timer);\n }\n\n if (res.status === 429 && attemptsRemaining > 0) {\n // Drain the body so the connection can return to the pool.\n await res.text().catch(() => undefined);\n const delay = parseRetryAfterMs(res.headers.get('Retry-After'), backoffMs);\n await sleep(delay);\n attemptsRemaining -= 1;\n backoffMs = Math.min(backoffMs * 2, RETRY_AFTER_CAP_MS);\n continue;\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\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 /**\n * Streaming variant of {@link query}. Returns an async-iterable that\n * yields {@link QueryStreamEvent} frames as the server produces them:\n *\n * for await (const ev of engram.queryStream('...')) {\n * if (ev.type === 'delta') process.stdout.write(ev.content);\n * else if (ev.type === 'done') console.log(ev.usage);\n * }\n *\n * Break out of the loop to abort the request (the underlying\n * AbortController is wired up to the fetch call).\n */\n queryStream(question: string, options: QueryOptions = {}): AsyncIterable<QueryStreamEvent> {\n const buckets = options.buckets ?? ['default'];\n const body = {\n query: question,\n buckets,\n stream: true,\n options: {\n top_k: options.topK ?? 8,\n return_explanation: options.returnExplanation ?? true,\n skip_synthesis: options.skipSynthesis ?? false,\n },\n };\n const url = `${this.baseUrl}/v1/query`;\n const apiKey = this.apiKey;\n const fetchImpl = this.fetchImpl;\n const timeoutMs = this.streamTimeoutMs;\n const maxRetriesOn429 = this.maxRetriesOn429;\n const bodyJson = JSON.stringify(body);\n\n return {\n [Symbol.asyncIterator]: () => {\n const controller = new AbortController();\n // The timeout caps total wall-clock for the stream. Set generously\n // because synthesis can run 10–25s before the first byte even with\n // streaming on slow paths; clamp to the user's configured timeout.\n const timer = setTimeout(() => controller.abort(), timeoutMs);\n\n let started = false;\n let reader: ReadableStreamDefaultReader<Uint8Array> | null = null;\n const decoder = new TextDecoder('utf-8');\n let buffer = '';\n let done = false;\n const queue: QueryStreamEvent[] = [];\n let pendingError: unknown = null;\n\n const ensureStarted = async (): Promise<void> => {\n if (started) return;\n started = true;\n // 429-aware retry at the connection-open stage only. Once\n // the response body starts flowing we can't resume mid-\n // stream safely.\n let attemptsRemaining = maxRetriesOn429;\n let backoffMs = 1000;\n // eslint-disable-next-line no-constant-condition\n while (true) {\n const res = await fetchImpl(url, {\n method: 'POST',\n headers: {\n Authorization: `Bearer ${apiKey}`,\n 'Content-Type': 'application/json',\n Accept: 'text/event-stream',\n 'User-Agent': USER_AGENT,\n },\n body: bodyJson,\n signal: controller.signal,\n });\n if (res.status === 429 && attemptsRemaining > 0) {\n await res.text().catch(() => undefined);\n const delay = parseRetryAfterMs(res.headers.get('Retry-After'), backoffMs);\n await sleep(delay);\n attemptsRemaining -= 1;\n backoffMs = Math.min(backoffMs * 2, RETRY_AFTER_CAP_MS);\n continue;\n }\n if (!res.ok) {\n const text = await res.text().catch(() => '');\n let parsed: unknown = text;\n try {\n parsed = text ? JSON.parse(text) : text;\n } catch {\n /* keep raw text */\n }\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 if (!res.body) {\n throw new EngramError('Engram API: streaming response has no body', res.status, null);\n }\n reader = res.body.getReader();\n return;\n }\n };\n\n const drainBuffer = (): void => {\n // SSE frames are separated by a blank line ('\\n\\n'). Each frame\n // is one or more 'field: value' lines. We only care about\n // 'data:' lines for this stream.\n let idx: number;\n while ((idx = buffer.indexOf('\\n\\n')) !== -1) {\n const frame = buffer.slice(0, idx);\n buffer = buffer.slice(idx + 2);\n const dataLines: string[] = [];\n for (const rawLine of frame.split('\\n')) {\n const line = rawLine.endsWith('\\r') ? rawLine.slice(0, -1) : rawLine;\n if (line.startsWith('data: ')) {\n dataLines.push(line.slice(6));\n } else if (line.startsWith('data:')) {\n dataLines.push(line.slice(5));\n }\n }\n if (dataLines.length === 0) continue;\n const payloadStr = dataLines.join('\\n');\n if (payloadStr === '[DONE]') {\n done = true;\n return;\n }\n let payload: unknown;\n try {\n payload = JSON.parse(payloadStr);\n } catch {\n // Malformed frame — skip rather than corrupt the stream.\n continue;\n }\n if (payload && typeof payload === 'object') {\n const obj = payload as Record<string, unknown>;\n if (obj.error) {\n pendingError = new EngramError(String(obj.error), 0, obj);\n done = true;\n return;\n }\n // OpenAI-style delta chunk\n const choices = obj.choices as Array<{ delta?: { content?: string } }> | undefined;\n if (Array.isArray(choices) && choices.length > 0) {\n const delta = choices[0]?.delta?.content;\n if (typeof delta === 'string' && delta.length > 0) {\n queue.push({ type: 'delta', content: delta });\n }\n continue;\n }\n // Final usage / explanation frame (no 'choices' key).\n queue.push({ type: 'done', ...(obj as Omit<Extract<QueryStreamEvent, { type: 'done' }>, 'type'>) });\n }\n }\n };\n\n return {\n next: async (): Promise<IteratorResult<QueryStreamEvent>> => {\n try {\n await ensureStarted();\n } catch (err) {\n clearTimeout(timer);\n throw err;\n }\n while (queue.length === 0 && !done) {\n if (!reader) {\n clearTimeout(timer);\n throw new EngramError('Engram API: stream reader missing', 0, null);\n }\n const chunk = await reader.read();\n if (chunk.done) {\n // Flush whatever's left in the buffer (some servers don't\n // terminate with a trailing blank line).\n if (buffer.length > 0) {\n buffer += '\\n\\n';\n drainBuffer();\n }\n done = true;\n break;\n }\n buffer += decoder.decode(chunk.value, { stream: true });\n drainBuffer();\n }\n if (queue.length > 0) {\n return { value: queue.shift() as QueryStreamEvent, done: false };\n }\n clearTimeout(timer);\n if (pendingError) throw pendingError;\n return { value: undefined as unknown as QueryStreamEvent, done: true };\n },\n return: async (): Promise<IteratorResult<QueryStreamEvent>> => {\n // Caller broke out of the for-await loop — cancel the upstream\n // request so we're not holding the connection open.\n clearTimeout(timer);\n controller.abort();\n try {\n await reader?.cancel();\n } catch {\n /* ignored */\n }\n return { value: undefined as unknown as QueryStreamEvent, done: true };\n },\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"]}
|