getmnemo 0.1.2 → 0.1.3

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
@@ -6,7 +6,7 @@ Official TypeScript / JavaScript SDK for [Mnemo Memory](https://mnemohq.com) —
6
6
  npm install getmnemo
7
7
  ```
8
8
 
9
- Zero runtime dependencies. Works in Node 18+, Bun, Deno, browsers, Cloudflare Workers, and any other modern JS runtime with `fetch`.
9
+ Zero runtime dependencies. Works in Node 18+, Bun, Deno, Cloudflare Workers, and any other modern server or edge JS runtime with `fetch`. The `apiKey` is a full-access credential — keep it server-side; for browser or client UIs, proxy through a server route.
10
10
 
11
11
  ## Quickstart
12
12
 
package/dist/index.cjs CHANGED
@@ -31,7 +31,7 @@ var MnemoTimeoutError = class extends MnemoError {
31
31
  var DEFAULT_BASE_URL = "https://api.mnemohq.com";
32
32
  var DEFAULT_TIMEOUT_MS = 3e4;
33
33
  var SDK_VERSION = "0.1.0";
34
- var USER_AGENT = `@mnemo/memory/${SDK_VERSION}`;
34
+ var USER_AGENT = `getmnemo/${SDK_VERSION}`;
35
35
  var DEFAULT_MAX_RETRIES = 3;
36
36
  var RETRY_BASE_DELAY_MS = 200;
37
37
  var RETRY_MAX_DELAY_MS = 5e3;
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/errors.ts","../src/client.ts"],"names":[],"mappings":"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","file":"index.cjs","sourcesContent":["export class MnemoError extends Error {\n constructor(message: string) {\n super(message)\n this.name = 'MnemoError'\n Object.setPrototypeOf(this, new.target.prototype)\n }\n}\n\nexport class MnemoHTTPError extends MnemoError {\n constructor(\n message: string,\n readonly status: number,\n readonly body?: unknown,\n ) {\n super(`[${status}] ${message}`)\n this.name = 'MnemoHTTPError'\n Object.setPrototypeOf(this, new.target.prototype)\n }\n}\n\nexport class MnemoTimeoutError extends MnemoError {\n constructor(timeoutMs: number) {\n super(`Request timed out after ${timeoutMs}ms`)\n this.name = 'MnemoTimeoutError'\n Object.setPrototypeOf(this, new.target.prototype)\n }\n}\n","/**\n * Mnemo Memory client.\n *\n * Zero runtime dependencies — uses the global `fetch` (Node 18+, Bun, browsers,\n * Cloudflare Workers, Deno, etc).\n *\n * @example\n * ```ts\n * import { Mnemo } from '@mnemo/memory'\n *\n * const memory = new Mnemo({\n * apiKey: process.env.GETMNEMO_API_KEY!,\n * workspaceId: process.env.GETMNEMO_WORKSPACE_ID!,\n * })\n *\n * await memory.add({ content: 'User prefers Japanese rice.' })\n * const { hits } = await memory.search({ query: 'what rice does the user like?' })\n * ```\n */\n\nimport { MnemoHTTPError, MnemoTimeoutError } from './errors.js'\nimport type {\n ClientConfig,\n Memory,\n PaginatedMemories,\n SearchResponse,\n} from './types.js'\n\nconst DEFAULT_BASE_URL = 'https://api.mnemohq.com'\nconst DEFAULT_TIMEOUT_MS = 30_000\nconst SDK_VERSION = '0.1.0'\nconst USER_AGENT = `@mnemo/memory/${SDK_VERSION}`\nconst DEFAULT_MAX_RETRIES = 3\nconst RETRY_BASE_DELAY_MS = 200\nconst RETRY_MAX_DELAY_MS = 5_000\n\n// Browsers reject `user-agent` as a forbidden header — setting it via fetch\n// throws or warns. Detect a browser-like environment so we can skip it there.\nconst IS_BROWSER_LIKE =\n typeof globalThis !== 'undefined' &&\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n typeof (globalThis as any).window !== 'undefined' &&\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n typeof (globalThis as any).document !== 'undefined'\n\nfunction retryDelayMs(attempt: number): number {\n const capped = Math.min(RETRY_BASE_DELAY_MS * 2 ** attempt, RETRY_MAX_DELAY_MS)\n // Full jitter.\n return Math.floor(Math.random() * capped)\n}\n\nfunction isRetryableStatus(status: number): boolean {\n // 501 Not Implemented is a permanent failure — retrying just wastes round-trips.\n if (status === 501) return false\n return status === 429 || (status >= 500 && status < 600)\n}\n\nfunction parseRetryAfterMs(headerValue: string | null): number | null {\n if (!headerValue) return null\n const trimmed = headerValue.trim()\n // Delta-seconds form.\n const seconds = Number(trimmed)\n if (Number.isFinite(seconds) && seconds >= 0) {\n return Math.min(seconds * 1000, RETRY_MAX_DELAY_MS)\n }\n // HTTP-date form.\n const epoch = Date.parse(trimmed)\n if (!Number.isNaN(epoch)) {\n const delta = epoch - Date.now()\n return Math.max(0, Math.min(delta, RETRY_MAX_DELAY_MS))\n }\n return null\n}\n\nfunction delayForResponse(res: Response, attempt: number): number {\n const hint = parseRetryAfterMs(res.headers.get('retry-after'))\n return hint !== null ? hint : retryDelayMs(attempt)\n}\n\nfunction sleep(ms: number): Promise<void> {\n return new Promise((resolve) => setTimeout(resolve, ms))\n}\n\nexport class Mnemo {\n readonly #baseUrl: string\n readonly #headers: Record<string, string>\n readonly #fetch: typeof fetch\n readonly #timeoutMs: number\n readonly #maxRetries: number\n readonly #defaultActorId: string | undefined\n\n constructor(cfg: ClientConfig) {\n if (!cfg.apiKey) throw new Error('Mnemo: apiKey is required')\n if (!cfg.workspaceId) throw new Error('Mnemo: workspaceId is required')\n this.#baseUrl = (cfg.baseUrl ?? DEFAULT_BASE_URL).replace(/\\/$/, '')\n this.#headers = {\n authorization: `Bearer ${cfg.apiKey}`,\n 'x-workspace-id': cfg.workspaceId,\n 'content-type': 'application/json',\n }\n // `user-agent` is on the forbidden header list in browsers — setting it\n // via fetch is silently dropped or throws. Send `x-getmnemo-client` as\n // an SDK identifier in browsers, and the standard User-Agent on Node.\n if (IS_BROWSER_LIKE) {\n this.#headers['x-getmnemo-client'] = USER_AGENT\n } else {\n this.#headers['user-agent'] = USER_AGENT\n }\n if (cfg.actorId) this.#headers['x-actor-id'] = cfg.actorId\n this.#defaultActorId = cfg.actorId\n this.#fetch = cfg.fetch ?? fetch\n this.#timeoutMs = cfg.timeoutMs ?? DEFAULT_TIMEOUT_MS\n this.#maxRetries = Math.max(0, cfg.maxRetries ?? DEFAULT_MAX_RETRIES)\n }\n\n async search(input: {\n query: string\n limit?: number\n actorId?: string\n }): Promise<SearchResponse> {\n return this.#request<SearchResponse>('POST', '/v1/search', {\n query: input.query,\n limit: input.limit ?? 8,\n ...(input.actorId !== undefined ? { actorId: input.actorId } : {}),\n })\n }\n\n async add(input: {\n content: string\n metadata?: Record<string, unknown>\n actorId?: string\n }): Promise<Memory> {\n return this.#request<Memory>('POST', '/v1/memories', {\n content: input.content,\n ...(input.metadata !== undefined ? { metadata: input.metadata } : {}),\n ...(input.actorId !== undefined ? { actorId: input.actorId } : {}),\n })\n }\n\n async update(\n id: string,\n input: { content?: string; metadata?: Record<string, unknown> },\n ): Promise<Memory> {\n if (input.content === undefined && input.metadata === undefined) {\n throw new Error('Mnemo.update: at least one of content/metadata must be provided')\n }\n return this.#request<Memory>('PATCH', `/v1/memories/${encodeURIComponent(id)}`, input)\n }\n\n async get(id: string): Promise<Memory> {\n return this.#request<Memory>('GET', `/v1/memories/${encodeURIComponent(id)}`)\n }\n\n async delete(id: string): Promise<void> {\n await this.#request<unknown>('DELETE', `/v1/memories/${encodeURIComponent(id)}`)\n }\n\n async list(input?: {\n limit?: number\n cursor?: string\n actorId?: string\n }): Promise<PaginatedMemories> {\n const params = new URLSearchParams()\n if (input?.limit !== undefined) params.set('limit', String(input.limit))\n if (input?.cursor !== undefined) params.set('cursor', input.cursor)\n if (input?.actorId !== undefined) params.set('actorId', input.actorId)\n const qs = params.toString()\n return this.#request<PaginatedMemories>('GET', `/v1/memories${qs ? `?${qs}` : ''}`)\n }\n\n /** Echoed back for debugging — never sent to the wire. */\n get defaultActorId(): string | undefined {\n return this.#defaultActorId\n }\n\n async #request<T>(method: string, path: string, body?: unknown): Promise<T> {\n const serializedBody = body === undefined ? undefined : JSON.stringify(body)\n let lastErr: unknown\n for (let attempt = 0; attempt <= this.#maxRetries; attempt++) {\n const ctrl = new AbortController()\n const timer = setTimeout(() => ctrl.abort(), this.#timeoutMs)\n try {\n const res = await this.#fetch(`${this.#baseUrl}${path}`, {\n method,\n headers: { ...this.#headers },\n body: serializedBody,\n signal: ctrl.signal,\n })\n if (isRetryableStatus(res.status) && attempt < this.#maxRetries) {\n // Capture Retry-After before draining; some runtimes invalidate\n // headers once the body is consumed.\n const wait = delayForResponse(res, attempt)\n // Drain body so the underlying connection can be reused.\n await res.text().catch(() => undefined)\n await sleep(wait)\n continue\n }\n const text = await res.text()\n const parsed: unknown = text ? safeJson(text) : undefined\n if (!res.ok) {\n const message =\n (parsed && typeof parsed === 'object' && 'message' in parsed\n ? String((parsed as { message: unknown }).message)\n : null) ?? `HTTP ${res.status} ${res.statusText}`\n throw new MnemoHTTPError(message, res.status, parsed)\n }\n return parsed as T\n } catch (err) {\n if (err instanceof Error && err.name === 'AbortError') {\n throw new MnemoTimeoutError(this.#timeoutMs)\n }\n if (err instanceof MnemoHTTPError) throw err\n lastErr = err\n if (attempt < this.#maxRetries) {\n await sleep(retryDelayMs(attempt))\n continue\n }\n throw err\n } finally {\n clearTimeout(timer)\n }\n }\n throw lastErr ?? new Error('Mnemo: request failed')\n }\n}\n\nfunction safeJson(s: string): unknown {\n try {\n return JSON.parse(s)\n } catch {\n return s\n }\n}\n"]}
1
+ {"version":3,"sources":["../src/errors.ts","../src/client.ts"],"names":[],"mappings":"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","file":"index.cjs","sourcesContent":["export class MnemoError extends Error {\n constructor(message: string) {\n super(message)\n this.name = 'MnemoError'\n Object.setPrototypeOf(this, new.target.prototype)\n }\n}\n\nexport class MnemoHTTPError extends MnemoError {\n constructor(\n message: string,\n readonly status: number,\n readonly body?: unknown,\n ) {\n super(`[${status}] ${message}`)\n this.name = 'MnemoHTTPError'\n Object.setPrototypeOf(this, new.target.prototype)\n }\n}\n\nexport class MnemoTimeoutError extends MnemoError {\n constructor(timeoutMs: number) {\n super(`Request timed out after ${timeoutMs}ms`)\n this.name = 'MnemoTimeoutError'\n Object.setPrototypeOf(this, new.target.prototype)\n }\n}\n","/**\n * Mnemo Memory client.\n *\n * Zero runtime dependencies — uses the global `fetch` (Node 18+, Bun, browsers,\n * Cloudflare Workers, Deno, etc).\n *\n * @example\n * ```ts\n * import { Mnemo } from 'getmnemo'\n *\n * const memory = new Mnemo({\n * apiKey: process.env.GETMNEMO_API_KEY!,\n * workspaceId: process.env.GETMNEMO_WORKSPACE_ID!,\n * })\n *\n * await memory.add({ content: 'User prefers Japanese rice.' })\n * const { hits } = await memory.search({ query: 'what rice does the user like?' })\n * ```\n */\n\nimport { MnemoHTTPError, MnemoTimeoutError } from './errors.js'\nimport type {\n ClientConfig,\n Memory,\n PaginatedMemories,\n SearchResponse,\n} from './types.js'\n\nconst DEFAULT_BASE_URL = 'https://api.mnemohq.com'\nconst DEFAULT_TIMEOUT_MS = 30_000\nconst SDK_VERSION = '0.1.0'\nconst USER_AGENT = `getmnemo/${SDK_VERSION}`\nconst DEFAULT_MAX_RETRIES = 3\nconst RETRY_BASE_DELAY_MS = 200\nconst RETRY_MAX_DELAY_MS = 5_000\n\n// Browsers reject `user-agent` as a forbidden header — setting it via fetch\n// throws or warns. Detect a browser-like environment so we can skip it there.\nconst IS_BROWSER_LIKE =\n typeof globalThis !== 'undefined' &&\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n typeof (globalThis as any).window !== 'undefined' &&\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n typeof (globalThis as any).document !== 'undefined'\n\nfunction retryDelayMs(attempt: number): number {\n const capped = Math.min(RETRY_BASE_DELAY_MS * 2 ** attempt, RETRY_MAX_DELAY_MS)\n // Full jitter.\n return Math.floor(Math.random() * capped)\n}\n\nfunction isRetryableStatus(status: number): boolean {\n // 501 Not Implemented is a permanent failure — retrying just wastes round-trips.\n if (status === 501) return false\n return status === 429 || (status >= 500 && status < 600)\n}\n\nfunction parseRetryAfterMs(headerValue: string | null): number | null {\n if (!headerValue) return null\n const trimmed = headerValue.trim()\n // Delta-seconds form.\n const seconds = Number(trimmed)\n if (Number.isFinite(seconds) && seconds >= 0) {\n return Math.min(seconds * 1000, RETRY_MAX_DELAY_MS)\n }\n // HTTP-date form.\n const epoch = Date.parse(trimmed)\n if (!Number.isNaN(epoch)) {\n const delta = epoch - Date.now()\n return Math.max(0, Math.min(delta, RETRY_MAX_DELAY_MS))\n }\n return null\n}\n\nfunction delayForResponse(res: Response, attempt: number): number {\n const hint = parseRetryAfterMs(res.headers.get('retry-after'))\n return hint !== null ? hint : retryDelayMs(attempt)\n}\n\nfunction sleep(ms: number): Promise<void> {\n return new Promise((resolve) => setTimeout(resolve, ms))\n}\n\nexport class Mnemo {\n readonly #baseUrl: string\n readonly #headers: Record<string, string>\n readonly #fetch: typeof fetch\n readonly #timeoutMs: number\n readonly #maxRetries: number\n readonly #defaultActorId: string | undefined\n\n constructor(cfg: ClientConfig) {\n if (!cfg.apiKey) throw new Error('Mnemo: apiKey is required')\n if (!cfg.workspaceId) throw new Error('Mnemo: workspaceId is required')\n this.#baseUrl = (cfg.baseUrl ?? DEFAULT_BASE_URL).replace(/\\/$/, '')\n this.#headers = {\n authorization: `Bearer ${cfg.apiKey}`,\n 'x-workspace-id': cfg.workspaceId,\n 'content-type': 'application/json',\n }\n // `user-agent` is on the forbidden header list in browsers — setting it\n // via fetch is silently dropped or throws. Send `x-getmnemo-client` as\n // an SDK identifier in browsers, and the standard User-Agent on Node.\n if (IS_BROWSER_LIKE) {\n this.#headers['x-getmnemo-client'] = USER_AGENT\n } else {\n this.#headers['user-agent'] = USER_AGENT\n }\n if (cfg.actorId) this.#headers['x-actor-id'] = cfg.actorId\n this.#defaultActorId = cfg.actorId\n this.#fetch = cfg.fetch ?? fetch\n this.#timeoutMs = cfg.timeoutMs ?? DEFAULT_TIMEOUT_MS\n this.#maxRetries = Math.max(0, cfg.maxRetries ?? DEFAULT_MAX_RETRIES)\n }\n\n async search(input: {\n query: string\n limit?: number\n actorId?: string\n }): Promise<SearchResponse> {\n return this.#request<SearchResponse>('POST', '/v1/search', {\n query: input.query,\n limit: input.limit ?? 8,\n ...(input.actorId !== undefined ? { actorId: input.actorId } : {}),\n })\n }\n\n async add(input: {\n content: string\n metadata?: Record<string, unknown>\n actorId?: string\n }): Promise<Memory> {\n return this.#request<Memory>('POST', '/v1/memories', {\n content: input.content,\n ...(input.metadata !== undefined ? { metadata: input.metadata } : {}),\n ...(input.actorId !== undefined ? { actorId: input.actorId } : {}),\n })\n }\n\n async update(\n id: string,\n input: { content?: string; metadata?: Record<string, unknown> },\n ): Promise<Memory> {\n if (input.content === undefined && input.metadata === undefined) {\n throw new Error('Mnemo.update: at least one of content/metadata must be provided')\n }\n return this.#request<Memory>('PATCH', `/v1/memories/${encodeURIComponent(id)}`, input)\n }\n\n async get(id: string): Promise<Memory> {\n return this.#request<Memory>('GET', `/v1/memories/${encodeURIComponent(id)}`)\n }\n\n async delete(id: string): Promise<void> {\n await this.#request<unknown>('DELETE', `/v1/memories/${encodeURIComponent(id)}`)\n }\n\n async list(input?: {\n limit?: number\n cursor?: string\n actorId?: string\n }): Promise<PaginatedMemories> {\n const params = new URLSearchParams()\n if (input?.limit !== undefined) params.set('limit', String(input.limit))\n if (input?.cursor !== undefined) params.set('cursor', input.cursor)\n if (input?.actorId !== undefined) params.set('actorId', input.actorId)\n const qs = params.toString()\n return this.#request<PaginatedMemories>('GET', `/v1/memories${qs ? `?${qs}` : ''}`)\n }\n\n /** Echoed back for debugging — never sent to the wire. */\n get defaultActorId(): string | undefined {\n return this.#defaultActorId\n }\n\n async #request<T>(method: string, path: string, body?: unknown): Promise<T> {\n const serializedBody = body === undefined ? undefined : JSON.stringify(body)\n let lastErr: unknown\n for (let attempt = 0; attempt <= this.#maxRetries; attempt++) {\n const ctrl = new AbortController()\n const timer = setTimeout(() => ctrl.abort(), this.#timeoutMs)\n try {\n const res = await this.#fetch(`${this.#baseUrl}${path}`, {\n method,\n headers: { ...this.#headers },\n body: serializedBody,\n signal: ctrl.signal,\n })\n if (isRetryableStatus(res.status) && attempt < this.#maxRetries) {\n // Capture Retry-After before draining; some runtimes invalidate\n // headers once the body is consumed.\n const wait = delayForResponse(res, attempt)\n // Drain body so the underlying connection can be reused.\n await res.text().catch(() => undefined)\n await sleep(wait)\n continue\n }\n const text = await res.text()\n const parsed: unknown = text ? safeJson(text) : undefined\n if (!res.ok) {\n const message =\n (parsed && typeof parsed === 'object' && 'message' in parsed\n ? String((parsed as { message: unknown }).message)\n : null) ?? `HTTP ${res.status} ${res.statusText}`\n throw new MnemoHTTPError(message, res.status, parsed)\n }\n return parsed as T\n } catch (err) {\n if (err instanceof Error && err.name === 'AbortError') {\n throw new MnemoTimeoutError(this.#timeoutMs)\n }\n if (err instanceof MnemoHTTPError) throw err\n lastErr = err\n if (attempt < this.#maxRetries) {\n await sleep(retryDelayMs(attempt))\n continue\n }\n throw err\n } finally {\n clearTimeout(timer)\n }\n }\n throw lastErr ?? new Error('Mnemo: request failed')\n }\n}\n\nfunction safeJson(s: string): unknown {\n try {\n return JSON.parse(s)\n } catch {\n return s\n }\n}\n"]}
package/dist/index.d.cts CHANGED
@@ -59,7 +59,7 @@ type ClientConfig = {
59
59
  *
60
60
  * @example
61
61
  * ```ts
62
- * import { Mnemo } from '@mnemo/memory'
62
+ * import { Mnemo } from 'getmnemo'
63
63
  *
64
64
  * const memory = new Mnemo({
65
65
  * apiKey: process.env.GETMNEMO_API_KEY!,
package/dist/index.d.ts CHANGED
@@ -59,7 +59,7 @@ type ClientConfig = {
59
59
  *
60
60
  * @example
61
61
  * ```ts
62
- * import { Mnemo } from '@mnemo/memory'
62
+ * import { Mnemo } from 'getmnemo'
63
63
  *
64
64
  * const memory = new Mnemo({
65
65
  * apiKey: process.env.GETMNEMO_API_KEY!,
package/dist/index.js CHANGED
@@ -29,7 +29,7 @@ var MnemoTimeoutError = class extends MnemoError {
29
29
  var DEFAULT_BASE_URL = "https://api.mnemohq.com";
30
30
  var DEFAULT_TIMEOUT_MS = 3e4;
31
31
  var SDK_VERSION = "0.1.0";
32
- var USER_AGENT = `@mnemo/memory/${SDK_VERSION}`;
32
+ var USER_AGENT = `getmnemo/${SDK_VERSION}`;
33
33
  var DEFAULT_MAX_RETRIES = 3;
34
34
  var RETRY_BASE_DELAY_MS = 200;
35
35
  var RETRY_MAX_DELAY_MS = 5e3;
package/dist/index.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/errors.ts","../src/client.ts"],"names":[],"mappings":"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","file":"index.js","sourcesContent":["export class MnemoError extends Error {\n constructor(message: string) {\n super(message)\n this.name = 'MnemoError'\n Object.setPrototypeOf(this, new.target.prototype)\n }\n}\n\nexport class MnemoHTTPError extends MnemoError {\n constructor(\n message: string,\n readonly status: number,\n readonly body?: unknown,\n ) {\n super(`[${status}] ${message}`)\n this.name = 'MnemoHTTPError'\n Object.setPrototypeOf(this, new.target.prototype)\n }\n}\n\nexport class MnemoTimeoutError extends MnemoError {\n constructor(timeoutMs: number) {\n super(`Request timed out after ${timeoutMs}ms`)\n this.name = 'MnemoTimeoutError'\n Object.setPrototypeOf(this, new.target.prototype)\n }\n}\n","/**\n * Mnemo Memory client.\n *\n * Zero runtime dependencies — uses the global `fetch` (Node 18+, Bun, browsers,\n * Cloudflare Workers, Deno, etc).\n *\n * @example\n * ```ts\n * import { Mnemo } from '@mnemo/memory'\n *\n * const memory = new Mnemo({\n * apiKey: process.env.GETMNEMO_API_KEY!,\n * workspaceId: process.env.GETMNEMO_WORKSPACE_ID!,\n * })\n *\n * await memory.add({ content: 'User prefers Japanese rice.' })\n * const { hits } = await memory.search({ query: 'what rice does the user like?' })\n * ```\n */\n\nimport { MnemoHTTPError, MnemoTimeoutError } from './errors.js'\nimport type {\n ClientConfig,\n Memory,\n PaginatedMemories,\n SearchResponse,\n} from './types.js'\n\nconst DEFAULT_BASE_URL = 'https://api.mnemohq.com'\nconst DEFAULT_TIMEOUT_MS = 30_000\nconst SDK_VERSION = '0.1.0'\nconst USER_AGENT = `@mnemo/memory/${SDK_VERSION}`\nconst DEFAULT_MAX_RETRIES = 3\nconst RETRY_BASE_DELAY_MS = 200\nconst RETRY_MAX_DELAY_MS = 5_000\n\n// Browsers reject `user-agent` as a forbidden header — setting it via fetch\n// throws or warns. Detect a browser-like environment so we can skip it there.\nconst IS_BROWSER_LIKE =\n typeof globalThis !== 'undefined' &&\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n typeof (globalThis as any).window !== 'undefined' &&\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n typeof (globalThis as any).document !== 'undefined'\n\nfunction retryDelayMs(attempt: number): number {\n const capped = Math.min(RETRY_BASE_DELAY_MS * 2 ** attempt, RETRY_MAX_DELAY_MS)\n // Full jitter.\n return Math.floor(Math.random() * capped)\n}\n\nfunction isRetryableStatus(status: number): boolean {\n // 501 Not Implemented is a permanent failure — retrying just wastes round-trips.\n if (status === 501) return false\n return status === 429 || (status >= 500 && status < 600)\n}\n\nfunction parseRetryAfterMs(headerValue: string | null): number | null {\n if (!headerValue) return null\n const trimmed = headerValue.trim()\n // Delta-seconds form.\n const seconds = Number(trimmed)\n if (Number.isFinite(seconds) && seconds >= 0) {\n return Math.min(seconds * 1000, RETRY_MAX_DELAY_MS)\n }\n // HTTP-date form.\n const epoch = Date.parse(trimmed)\n if (!Number.isNaN(epoch)) {\n const delta = epoch - Date.now()\n return Math.max(0, Math.min(delta, RETRY_MAX_DELAY_MS))\n }\n return null\n}\n\nfunction delayForResponse(res: Response, attempt: number): number {\n const hint = parseRetryAfterMs(res.headers.get('retry-after'))\n return hint !== null ? hint : retryDelayMs(attempt)\n}\n\nfunction sleep(ms: number): Promise<void> {\n return new Promise((resolve) => setTimeout(resolve, ms))\n}\n\nexport class Mnemo {\n readonly #baseUrl: string\n readonly #headers: Record<string, string>\n readonly #fetch: typeof fetch\n readonly #timeoutMs: number\n readonly #maxRetries: number\n readonly #defaultActorId: string | undefined\n\n constructor(cfg: ClientConfig) {\n if (!cfg.apiKey) throw new Error('Mnemo: apiKey is required')\n if (!cfg.workspaceId) throw new Error('Mnemo: workspaceId is required')\n this.#baseUrl = (cfg.baseUrl ?? DEFAULT_BASE_URL).replace(/\\/$/, '')\n this.#headers = {\n authorization: `Bearer ${cfg.apiKey}`,\n 'x-workspace-id': cfg.workspaceId,\n 'content-type': 'application/json',\n }\n // `user-agent` is on the forbidden header list in browsers — setting it\n // via fetch is silently dropped or throws. Send `x-getmnemo-client` as\n // an SDK identifier in browsers, and the standard User-Agent on Node.\n if (IS_BROWSER_LIKE) {\n this.#headers['x-getmnemo-client'] = USER_AGENT\n } else {\n this.#headers['user-agent'] = USER_AGENT\n }\n if (cfg.actorId) this.#headers['x-actor-id'] = cfg.actorId\n this.#defaultActorId = cfg.actorId\n this.#fetch = cfg.fetch ?? fetch\n this.#timeoutMs = cfg.timeoutMs ?? DEFAULT_TIMEOUT_MS\n this.#maxRetries = Math.max(0, cfg.maxRetries ?? DEFAULT_MAX_RETRIES)\n }\n\n async search(input: {\n query: string\n limit?: number\n actorId?: string\n }): Promise<SearchResponse> {\n return this.#request<SearchResponse>('POST', '/v1/search', {\n query: input.query,\n limit: input.limit ?? 8,\n ...(input.actorId !== undefined ? { actorId: input.actorId } : {}),\n })\n }\n\n async add(input: {\n content: string\n metadata?: Record<string, unknown>\n actorId?: string\n }): Promise<Memory> {\n return this.#request<Memory>('POST', '/v1/memories', {\n content: input.content,\n ...(input.metadata !== undefined ? { metadata: input.metadata } : {}),\n ...(input.actorId !== undefined ? { actorId: input.actorId } : {}),\n })\n }\n\n async update(\n id: string,\n input: { content?: string; metadata?: Record<string, unknown> },\n ): Promise<Memory> {\n if (input.content === undefined && input.metadata === undefined) {\n throw new Error('Mnemo.update: at least one of content/metadata must be provided')\n }\n return this.#request<Memory>('PATCH', `/v1/memories/${encodeURIComponent(id)}`, input)\n }\n\n async get(id: string): Promise<Memory> {\n return this.#request<Memory>('GET', `/v1/memories/${encodeURIComponent(id)}`)\n }\n\n async delete(id: string): Promise<void> {\n await this.#request<unknown>('DELETE', `/v1/memories/${encodeURIComponent(id)}`)\n }\n\n async list(input?: {\n limit?: number\n cursor?: string\n actorId?: string\n }): Promise<PaginatedMemories> {\n const params = new URLSearchParams()\n if (input?.limit !== undefined) params.set('limit', String(input.limit))\n if (input?.cursor !== undefined) params.set('cursor', input.cursor)\n if (input?.actorId !== undefined) params.set('actorId', input.actorId)\n const qs = params.toString()\n return this.#request<PaginatedMemories>('GET', `/v1/memories${qs ? `?${qs}` : ''}`)\n }\n\n /** Echoed back for debugging — never sent to the wire. */\n get defaultActorId(): string | undefined {\n return this.#defaultActorId\n }\n\n async #request<T>(method: string, path: string, body?: unknown): Promise<T> {\n const serializedBody = body === undefined ? undefined : JSON.stringify(body)\n let lastErr: unknown\n for (let attempt = 0; attempt <= this.#maxRetries; attempt++) {\n const ctrl = new AbortController()\n const timer = setTimeout(() => ctrl.abort(), this.#timeoutMs)\n try {\n const res = await this.#fetch(`${this.#baseUrl}${path}`, {\n method,\n headers: { ...this.#headers },\n body: serializedBody,\n signal: ctrl.signal,\n })\n if (isRetryableStatus(res.status) && attempt < this.#maxRetries) {\n // Capture Retry-After before draining; some runtimes invalidate\n // headers once the body is consumed.\n const wait = delayForResponse(res, attempt)\n // Drain body so the underlying connection can be reused.\n await res.text().catch(() => undefined)\n await sleep(wait)\n continue\n }\n const text = await res.text()\n const parsed: unknown = text ? safeJson(text) : undefined\n if (!res.ok) {\n const message =\n (parsed && typeof parsed === 'object' && 'message' in parsed\n ? String((parsed as { message: unknown }).message)\n : null) ?? `HTTP ${res.status} ${res.statusText}`\n throw new MnemoHTTPError(message, res.status, parsed)\n }\n return parsed as T\n } catch (err) {\n if (err instanceof Error && err.name === 'AbortError') {\n throw new MnemoTimeoutError(this.#timeoutMs)\n }\n if (err instanceof MnemoHTTPError) throw err\n lastErr = err\n if (attempt < this.#maxRetries) {\n await sleep(retryDelayMs(attempt))\n continue\n }\n throw err\n } finally {\n clearTimeout(timer)\n }\n }\n throw lastErr ?? new Error('Mnemo: request failed')\n }\n}\n\nfunction safeJson(s: string): unknown {\n try {\n return JSON.parse(s)\n } catch {\n return s\n }\n}\n"]}
1
+ {"version":3,"sources":["../src/errors.ts","../src/client.ts"],"names":[],"mappings":"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","file":"index.js","sourcesContent":["export class MnemoError extends Error {\n constructor(message: string) {\n super(message)\n this.name = 'MnemoError'\n Object.setPrototypeOf(this, new.target.prototype)\n }\n}\n\nexport class MnemoHTTPError extends MnemoError {\n constructor(\n message: string,\n readonly status: number,\n readonly body?: unknown,\n ) {\n super(`[${status}] ${message}`)\n this.name = 'MnemoHTTPError'\n Object.setPrototypeOf(this, new.target.prototype)\n }\n}\n\nexport class MnemoTimeoutError extends MnemoError {\n constructor(timeoutMs: number) {\n super(`Request timed out after ${timeoutMs}ms`)\n this.name = 'MnemoTimeoutError'\n Object.setPrototypeOf(this, new.target.prototype)\n }\n}\n","/**\n * Mnemo Memory client.\n *\n * Zero runtime dependencies — uses the global `fetch` (Node 18+, Bun, browsers,\n * Cloudflare Workers, Deno, etc).\n *\n * @example\n * ```ts\n * import { Mnemo } from 'getmnemo'\n *\n * const memory = new Mnemo({\n * apiKey: process.env.GETMNEMO_API_KEY!,\n * workspaceId: process.env.GETMNEMO_WORKSPACE_ID!,\n * })\n *\n * await memory.add({ content: 'User prefers Japanese rice.' })\n * const { hits } = await memory.search({ query: 'what rice does the user like?' })\n * ```\n */\n\nimport { MnemoHTTPError, MnemoTimeoutError } from './errors.js'\nimport type {\n ClientConfig,\n Memory,\n PaginatedMemories,\n SearchResponse,\n} from './types.js'\n\nconst DEFAULT_BASE_URL = 'https://api.mnemohq.com'\nconst DEFAULT_TIMEOUT_MS = 30_000\nconst SDK_VERSION = '0.1.0'\nconst USER_AGENT = `getmnemo/${SDK_VERSION}`\nconst DEFAULT_MAX_RETRIES = 3\nconst RETRY_BASE_DELAY_MS = 200\nconst RETRY_MAX_DELAY_MS = 5_000\n\n// Browsers reject `user-agent` as a forbidden header — setting it via fetch\n// throws or warns. Detect a browser-like environment so we can skip it there.\nconst IS_BROWSER_LIKE =\n typeof globalThis !== 'undefined' &&\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n typeof (globalThis as any).window !== 'undefined' &&\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n typeof (globalThis as any).document !== 'undefined'\n\nfunction retryDelayMs(attempt: number): number {\n const capped = Math.min(RETRY_BASE_DELAY_MS * 2 ** attempt, RETRY_MAX_DELAY_MS)\n // Full jitter.\n return Math.floor(Math.random() * capped)\n}\n\nfunction isRetryableStatus(status: number): boolean {\n // 501 Not Implemented is a permanent failure — retrying just wastes round-trips.\n if (status === 501) return false\n return status === 429 || (status >= 500 && status < 600)\n}\n\nfunction parseRetryAfterMs(headerValue: string | null): number | null {\n if (!headerValue) return null\n const trimmed = headerValue.trim()\n // Delta-seconds form.\n const seconds = Number(trimmed)\n if (Number.isFinite(seconds) && seconds >= 0) {\n return Math.min(seconds * 1000, RETRY_MAX_DELAY_MS)\n }\n // HTTP-date form.\n const epoch = Date.parse(trimmed)\n if (!Number.isNaN(epoch)) {\n const delta = epoch - Date.now()\n return Math.max(0, Math.min(delta, RETRY_MAX_DELAY_MS))\n }\n return null\n}\n\nfunction delayForResponse(res: Response, attempt: number): number {\n const hint = parseRetryAfterMs(res.headers.get('retry-after'))\n return hint !== null ? hint : retryDelayMs(attempt)\n}\n\nfunction sleep(ms: number): Promise<void> {\n return new Promise((resolve) => setTimeout(resolve, ms))\n}\n\nexport class Mnemo {\n readonly #baseUrl: string\n readonly #headers: Record<string, string>\n readonly #fetch: typeof fetch\n readonly #timeoutMs: number\n readonly #maxRetries: number\n readonly #defaultActorId: string | undefined\n\n constructor(cfg: ClientConfig) {\n if (!cfg.apiKey) throw new Error('Mnemo: apiKey is required')\n if (!cfg.workspaceId) throw new Error('Mnemo: workspaceId is required')\n this.#baseUrl = (cfg.baseUrl ?? DEFAULT_BASE_URL).replace(/\\/$/, '')\n this.#headers = {\n authorization: `Bearer ${cfg.apiKey}`,\n 'x-workspace-id': cfg.workspaceId,\n 'content-type': 'application/json',\n }\n // `user-agent` is on the forbidden header list in browsers — setting it\n // via fetch is silently dropped or throws. Send `x-getmnemo-client` as\n // an SDK identifier in browsers, and the standard User-Agent on Node.\n if (IS_BROWSER_LIKE) {\n this.#headers['x-getmnemo-client'] = USER_AGENT\n } else {\n this.#headers['user-agent'] = USER_AGENT\n }\n if (cfg.actorId) this.#headers['x-actor-id'] = cfg.actorId\n this.#defaultActorId = cfg.actorId\n this.#fetch = cfg.fetch ?? fetch\n this.#timeoutMs = cfg.timeoutMs ?? DEFAULT_TIMEOUT_MS\n this.#maxRetries = Math.max(0, cfg.maxRetries ?? DEFAULT_MAX_RETRIES)\n }\n\n async search(input: {\n query: string\n limit?: number\n actorId?: string\n }): Promise<SearchResponse> {\n return this.#request<SearchResponse>('POST', '/v1/search', {\n query: input.query,\n limit: input.limit ?? 8,\n ...(input.actorId !== undefined ? { actorId: input.actorId } : {}),\n })\n }\n\n async add(input: {\n content: string\n metadata?: Record<string, unknown>\n actorId?: string\n }): Promise<Memory> {\n return this.#request<Memory>('POST', '/v1/memories', {\n content: input.content,\n ...(input.metadata !== undefined ? { metadata: input.metadata } : {}),\n ...(input.actorId !== undefined ? { actorId: input.actorId } : {}),\n })\n }\n\n async update(\n id: string,\n input: { content?: string; metadata?: Record<string, unknown> },\n ): Promise<Memory> {\n if (input.content === undefined && input.metadata === undefined) {\n throw new Error('Mnemo.update: at least one of content/metadata must be provided')\n }\n return this.#request<Memory>('PATCH', `/v1/memories/${encodeURIComponent(id)}`, input)\n }\n\n async get(id: string): Promise<Memory> {\n return this.#request<Memory>('GET', `/v1/memories/${encodeURIComponent(id)}`)\n }\n\n async delete(id: string): Promise<void> {\n await this.#request<unknown>('DELETE', `/v1/memories/${encodeURIComponent(id)}`)\n }\n\n async list(input?: {\n limit?: number\n cursor?: string\n actorId?: string\n }): Promise<PaginatedMemories> {\n const params = new URLSearchParams()\n if (input?.limit !== undefined) params.set('limit', String(input.limit))\n if (input?.cursor !== undefined) params.set('cursor', input.cursor)\n if (input?.actorId !== undefined) params.set('actorId', input.actorId)\n const qs = params.toString()\n return this.#request<PaginatedMemories>('GET', `/v1/memories${qs ? `?${qs}` : ''}`)\n }\n\n /** Echoed back for debugging — never sent to the wire. */\n get defaultActorId(): string | undefined {\n return this.#defaultActorId\n }\n\n async #request<T>(method: string, path: string, body?: unknown): Promise<T> {\n const serializedBody = body === undefined ? undefined : JSON.stringify(body)\n let lastErr: unknown\n for (let attempt = 0; attempt <= this.#maxRetries; attempt++) {\n const ctrl = new AbortController()\n const timer = setTimeout(() => ctrl.abort(), this.#timeoutMs)\n try {\n const res = await this.#fetch(`${this.#baseUrl}${path}`, {\n method,\n headers: { ...this.#headers },\n body: serializedBody,\n signal: ctrl.signal,\n })\n if (isRetryableStatus(res.status) && attempt < this.#maxRetries) {\n // Capture Retry-After before draining; some runtimes invalidate\n // headers once the body is consumed.\n const wait = delayForResponse(res, attempt)\n // Drain body so the underlying connection can be reused.\n await res.text().catch(() => undefined)\n await sleep(wait)\n continue\n }\n const text = await res.text()\n const parsed: unknown = text ? safeJson(text) : undefined\n if (!res.ok) {\n const message =\n (parsed && typeof parsed === 'object' && 'message' in parsed\n ? String((parsed as { message: unknown }).message)\n : null) ?? `HTTP ${res.status} ${res.statusText}`\n throw new MnemoHTTPError(message, res.status, parsed)\n }\n return parsed as T\n } catch (err) {\n if (err instanceof Error && err.name === 'AbortError') {\n throw new MnemoTimeoutError(this.#timeoutMs)\n }\n if (err instanceof MnemoHTTPError) throw err\n lastErr = err\n if (attempt < this.#maxRetries) {\n await sleep(retryDelayMs(attempt))\n continue\n }\n throw err\n } finally {\n clearTimeout(timer)\n }\n }\n throw lastErr ?? new Error('Mnemo: request failed')\n }\n}\n\nfunction safeJson(s: string): unknown {\n try {\n return JSON.parse(s)\n } catch {\n return s\n }\n}\n"]}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "getmnemo",
3
- "version": "0.1.2",
3
+ "version": "0.1.3",
4
4
  "description": "Official TypeScript / JavaScript SDK for Mnemo Memory — long-term memory infrastructure for AI agents.",
5
5
  "type": "module",
6
6
  "license": "MIT",
@@ -45,7 +45,7 @@
45
45
  "url": "https://github.com/ledgermem/getmnemo-js.git"
46
46
  },
47
47
  "bugs": {
48
- "url": "https://github.com/getmnemo/getmnemo-js/issues"
48
+ "url": "https://github.com/ledgermem/getmnemo-js/issues"
49
49
  },
50
50
  "dependencies": {},
51
51
  "devDependencies": {