@persistmemory/sdk 0.4.0 → 0.5.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/index.cjs +25 -0
- package/dist/index.cjs.map +2 -2
- package/dist/index.js +25 -0
- package/dist/index.js.map +2 -2
- package/dist/resources/agent.d.ts +22 -1
- package/dist/types.d.ts +15 -0
- package/package.json +1 -1
package/dist/index.cjs.map
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"version": 3,
|
|
3
3
|
"sources": ["../src/index.ts", "../src/query.ts", "../src/backoff.ts", "../src/errors.ts", "../src/http.ts", "../src/pagination.ts", "../src/resources/memories.ts", "../src/resources/search.ts", "../src/resources/spaces.ts", "../src/resources/ingestion.ts", "../src/resources/knowledge.ts", "../src/resources/conversations.ts", "../src/resources/google.ts", "../src/resources/integrations.ts", "../src/resources/health.ts", "../src/resources/agent.ts", "../src/client.ts"],
|
|
4
|
-
"sourcesContent": ["/**\n * The official TypeScript client for the PersistMemory API.\n *\n * See the README for a quickstart. The three things worth knowing before you\n * read the types:\n *\n * remember is asynchronous it returns a job id, not a memory. Extraction\n * and consolidation run afterwards and may\n * produce one memory, several, or none.\n *\n * search degrades it falls back to deterministic retrieval when\n * embeddings are unavailable, and says so in\n * `diagnostics.degraded`. Read it.\n *\n * POSTs are not retried unless you pass an `idempotencyKey`. A POST\n * that timed out may already have been processed,\n * and this client will not guess.\n */\nexport { PersistMemory } from \"./client\";\nexport type { ClientOptions, RequestOptions } from \"./http\";\nexport type { BackoffOptions } from \"./backoff\";\nexport { backoffMs, delayFor, DEFAULT_BACKOFF } from \"./backoff\";\nexport { Paginated } from \"./pagination\";\n\nexport {\n PersistMemoryError,\n AuthenticationError,\n PermissionDeniedError,\n NotFoundError,\n ValidationError,\n ConflictError,\n RateLimitError,\n ServerError,\n ConnectionError,\n TimeoutError,\n AbortError\n} from \"./errors\";\nexport type { ErrorCode } from \"./errors\";\n\nexport type * from \"./types\";\n", "/**\n * Turning parameters into a query string the API's parser reads the way we mean.\n *\n * Its own module because both the request loop and every list resource need\n * it, and putting it in either one would have the other importing a transport\n * to build a string.\n */\n\nexport type QueryValue =\n | string\n | number\n | boolean\n | readonly string[]\n | readonly number[]\n | undefined;\n\nexport type QueryParams = Readonly<Record<string, QueryValue>>;\n\n/**\n * Builds a query string the API's parser will read the way we mean it.\n *\n * Arrays repeat the key - `?spaceIds=a&spaceIds=b` - because that is what\n * Express hands to the schemas, which accept either one value or a list.\n * Comma-joining would arrive as a single id containing a comma and match\n * nothing, with no error to say why.\n *\n * Booleans are sent as `true`/`false` strings. The API parses those\n * explicitly, because `Boolean(\"false\")` is `true` and a flag written that way\n * can never be turned off.\n */\nexport function encodeQuery(params?: QueryParams): string {\n if (!params) return \"\";\n\n const search = new URLSearchParams();\n for (const [key, value] of Object.entries(params)) {\n // Undefined is dropped, never sent. `?cursor=undefined` is a string the\n // server tries to decode, and the 400 it produces names the cursor rather\n // than the caller who forgot to omit it.\n if (value === undefined) continue;\n\n if (Array.isArray(value)) {\n for (const one of value as readonly (string | number)[]) search.append(key, String(one));\n continue;\n }\n search.append(key, String(value));\n }\n\n const encoded = search.toString();\n return encoded ? `?${encoded}` : \"\";\n}\n\n/**\n * The two parameters every list shares, plus whatever the endpoint adds.\n *\n * Shared because the cursor rule is subtle enough to get wrong once per\n * resource: the PAGINATOR's cursor wins over the caller's. The caller's seeds\n * the first page - resuming from a bookmark - and the paginator supplies every\n * page after that. Letting the caller's win would re-read the same page\n * forever, which looks like an account that never ends.\n */\nexport function pageQuery(\n params: { readonly limit?: number; readonly cursor?: string },\n cursor: string | undefined,\n extra: QueryParams\n): QueryParams {\n return {\n ...(params.limit !== undefined ? { limit: params.limit } : {}),\n ...(cursor !== undefined\n ? { cursor }\n : params.cursor !== undefined\n ? { cursor: params.cursor }\n : {}),\n ...extra\n };\n}\n", "/**\n * How long to wait before trying again.\n *\n * Exponential, capped, and jittered, for the reasons the rest of this repo\n * gives in `@persistmemory/async`:\n *\n * exponential a cause that has not cleared in 200ms may clear in two\n * seconds; hammering it every 200ms spends the attempts faster\n * without giving it time to recover.\n *\n * capped unbounded doubling reaches minutes, and a caller waiting\n * inside one function call cannot tell that from a hang.\n *\n * jittered the one that gets skipped, and the one that matters most. An\n * outage fails every in-flight request at once; without jitter\n * every client waits exactly two seconds and retries in the\n * same millisecond, so the recovering service is hit by the\n * whole fleet and knocked over again. The retry storm is caused\n * by the retry policy.\n *\n * Duplicated here rather than imported from `@persistmemory/async` on purpose:\n * this package is published to npm and installed by people who have no reason\n * to pull in a queue runtime, a Redis client and a dead-letter store to make\n * an HTTP request.\n */\nexport interface BackoffOptions {\n readonly baseMs?: number;\n readonly maxMs?: number;\n readonly factor?: number;\n /** 0 = none, 1 = full. Full is the right default; see below. */\n readonly jitter?: number;\n /** Injected so a test is not at the mercy of the random number generator. */\n readonly random?: () => number;\n}\n\n/**\n * Short by server standards.\n *\n * A queue worker can afford to come back in a minute. A caller is blocked\n * inside `await client.search(...)` and has a user watching, so the whole\n * retry budget has to fit inside a request timeout rather than outlast it.\n */\nexport const DEFAULT_BACKOFF = { baseMs: 250, maxMs: 8_000, factor: 2, jitter: 1 } as const;\n\n/**\n * The delay before attempt `attempt` (1-based).\n *\n * FULL jitter by default - a random point in [0, ceiling] rather than\n * ceiling plus or minus a wobble. It sounds worse and measures better:\n * partial jitter leaves the retries clustered around the same instant, which\n * is the thing that overwhelms a service coming back up.\n */\nexport function backoffMs(attempt: number, options: BackoffOptions = {}): number {\n const base = options.baseMs ?? DEFAULT_BACKOFF.baseMs;\n const max = options.maxMs ?? DEFAULT_BACKOFF.maxMs;\n const factor = options.factor ?? DEFAULT_BACKOFF.factor;\n const jitter = clamp01(options.jitter ?? DEFAULT_BACKOFF.jitter);\n const random = options.random ?? Math.random;\n\n // Clamped at 1: attempt 0 would give a negative exponent and a delay\n // shorter than the base, so the first retry would be the fastest one.\n const exponent = Math.max(0, Math.floor(attempt) - 1);\n // Capped BEFORE jitter. Capping after lets an un-jittered value of minutes\n // be scaled down to something that looks reasonable while the underlying\n // growth is still unbounded.\n const ceiling = Math.min(max, base * Math.pow(factor, exponent));\n\n if (jitter <= 0) return Math.round(ceiling);\n\n const fixed = ceiling * (1 - jitter);\n return Math.round(fixed + random() * (ceiling - fixed));\n}\n\n/**\n * The delay to actually use, honouring what the server asked for.\n *\n * `Retry-After` is taken as a FLOOR, not verbatim. Verbatim would let a\n * one-second hint on the fifth consecutive 429 undo the backoff entirely and\n * put us straight back into the limit; ignoring it would have us retry before\n * the window resets and spend an attempt learning what we were already told.\n *\n * A server asking for LONGER than our cap is believed. The cap exists to stop\n * our own growth running away, not to overrule a service that has told us\n * when it will be ready.\n */\nexport function delayFor(args: {\n attempt: number;\n retryAfterSeconds?: number;\n options?: BackoffOptions;\n}): number {\n const computed = backoffMs(args.attempt, args.options ?? {});\n if (args.retryAfterSeconds === undefined || !Number.isFinite(args.retryAfterSeconds)) {\n return computed;\n }\n return Math.max(computed, Math.max(0, args.retryAfterSeconds) * 1000);\n}\n\nfunction clamp01(value: number): number {\n if (!Number.isFinite(value)) return 0;\n return Math.min(1, Math.max(0, value));\n}\n", "/**\n * What went wrong, in a shape a caller can branch on.\n *\n * One class per thing a caller can DO about it, which is not the same as one\n * class per status code. `RateLimited` says wait, `Validation` says fix the\n * request, `NotFound` says the id is wrong or gone, `Conflict` says re-read\n * and try again. A code nobody branches on is a string that only looks like an\n * API, so 402 and 418 and anything else unmapped land on the base class rather\n * than growing a name each.\n *\n * The API's own error envelope is\n *\n * { error: { code, message, fields?, requestId } }\n *\n * and `code` is the stable part. Branch on the class or on `code`, never on\n * `message`: messages get rewritten for clarity, translated, and deliberately\n * made vaguer for security, and a client keyed to message text breaks silently\n * when any of that happens.\n *\n * NOTHING in here ever holds the API key. Errors are logged, serialised into\n * bug reports and posted into issue trackers, which is exactly how a\n * credential escapes - see `redact` at the bottom of this file, which every\n * message this module builds passes through.\n */\n\n/** The stable codes the API returns. Unknown strings are possible; see below. */\nexport type ErrorCode =\n | \"VALIDATION_ERROR\"\n | \"UNAUTHORIZED\"\n | \"FORBIDDEN\"\n | \"NOT_FOUND\"\n | \"CONFLICT\"\n | \"IDEMPOTENCY_MISMATCH\"\n | \"RATE_LIMITED\"\n | \"PAYLOAD_TOO_LARGE\"\n | \"DEPENDENCY_UNAVAILABLE\"\n | \"PROCESSING_FAILED\"\n | \"INTERNAL_ERROR\"\n // Widened on purpose. A server that adds a code should not make an older\n // SDK throw a TypeError while parsing the error that explains the problem.\n | (string & {});\n\nexport interface ApiErrorInit {\n readonly status: number;\n readonly code: ErrorCode;\n readonly message: string;\n /** Which fields were rejected, for a validation failure. */\n readonly fields?: Readonly<Record<string, string>>;\n /** Ties this failure to the server's log lines. Quote it in support. */\n readonly requestId?: string;\n /** Seconds the server asked us to wait, when it said. */\n readonly retryAfterSeconds?: number;\n}\n\n/**\n * The base every failure from this SDK inherits from.\n *\n * `retryable` is the single question the request loop asks. It lives on the\n * error rather than in a table beside it because the two drift: a table says\n * 429 is retryable while the error that reaches the loop is a transport\n * failure nobody thought to add.\n */\nexport class PersistMemoryError extends Error {\n readonly status: number;\n readonly code: ErrorCode;\n readonly fields?: Readonly<Record<string, string>>;\n readonly requestId?: string;\n readonly retryAfterSeconds?: number;\n /** Retrying this exact request could plausibly succeed. */\n readonly retryable: boolean = false;\n\n constructor(init: ApiErrorInit) {\n super(redact(init.message));\n this.name = new.target.name;\n this.status = init.status;\n this.code = init.code;\n if (init.fields) this.fields = init.fields;\n if (init.requestId) this.requestId = init.requestId;\n if (init.retryAfterSeconds !== undefined) this.retryAfterSeconds = init.retryAfterSeconds;\n }\n\n /**\n * A one-line summary safe to log.\n *\n * Provided so callers reach for this instead of `JSON.stringify(error)`,\n * which walks own properties and would pick up anything a future field\n * holds. Everything here is already server-supplied and key-free.\n */\n override toString(): string {\n const id = this.requestId ? ` requestId=${this.requestId}` : \"\";\n return `${this.name}: [${this.status} ${this.code}] ${this.message}${id}`;\n }\n}\n\n/** 401. The key is missing, malformed, revoked, or the session expired. */\nexport class AuthenticationError extends PersistMemoryError {}\n\n/**\n * 403. Known caller, and this credential will never be enough.\n *\n * Distinct from `AuthenticationError` because the fix is different: 401 means\n * present a credential, 403 means this key's scopes are wrong and no amount of\n * retrying or re-signing will change it. A read-only key calling `remember`\n * lands here.\n */\nexport class PermissionDeniedError extends PersistMemoryError {}\n\n/** 404. Does not exist, or is not yours - the API answers both the same way. */\nexport class NotFoundError extends PersistMemoryError {}\n\n/** 400 and 422. The request was wrong; `fields` says where. */\nexport class ValidationError extends PersistMemoryError {}\n\n/** 409. Something changed underneath. Re-read, then try again. */\nexport class ConflictError extends PersistMemoryError {}\n\n/**\n * 429. Slow down.\n *\n * `retryAfterSeconds` comes from the `Retry-After` header, which the API\n * always sets on a 429. It is not advice - it is the only number that knows\n * when the window resets, and computing our own backoff instead means being\n * refused again and spending an attempt to learn what we were already told.\n */\nexport class RateLimitError extends PersistMemoryError {\n override readonly retryable = true;\n}\n\n/**\n * 5xx. Ours, not yours.\n *\n * Retryable, because a 500 or a 503 is usually a dependency that has fallen\n * over and will come back - and the alternative, giving up on the first one,\n * turns a three-second blip into a failed job. Retryable does not mean\n * REPEATED: a POST still needs an idempotency key before this client will send\n * it again, because a 500 may have been raised after the work was done.\n */\nexport class ServerError extends PersistMemoryError {\n override readonly retryable = true;\n}\n\n/**\n * The request never got an answer: DNS, connect, reset, or a body that died\n * mid-stream.\n *\n * Status 0, because there was no status. Retryable in general - but see\n * `isRetryable` in `client.ts`, which refuses to retry a POST that may already\n * have been processed, since a connection dying after the server accepted the\n * request looks identical from here.\n */\nexport class ConnectionError extends PersistMemoryError {\n override readonly retryable = true;\n\n constructor(message: string) {\n super({ status: 0, code: \"CONNECTION_ERROR\", message });\n }\n}\n\n/** The deadline passed. A distinct class because the fix is often a bigger one. */\nexport class TimeoutError extends PersistMemoryError {\n override readonly retryable = true;\n\n constructor(message: string) {\n super({ status: 0, code: \"TIMEOUT\", message });\n }\n}\n\n/**\n * The caller's own AbortSignal fired.\n *\n * NOT retryable, and not a timeout: someone asked for this to stop, and\n * retrying it is the one thing they have said they do not want.\n */\nexport class AbortError extends PersistMemoryError {\n constructor(message = \"The request was aborted by the caller.\") {\n super({ status: 0, code: \"ABORTED\", message });\n }\n}\n\ninterface ErrorEnvelope {\n readonly error?: {\n readonly code?: unknown;\n readonly message?: unknown;\n readonly fields?: unknown;\n readonly requestId?: unknown;\n };\n}\n\n/**\n * A response the server refused, turned into the right class.\n *\n * Keyed on the CODE first and the status second. The code is the API's own\n * vocabulary and is the more precise of the two - `IDEMPOTENCY_MISMATCH` is a\n * 422 that means \"you reused a key with a different body\", which is a\n * validation problem and not a generic unprocessable entity.\n *\n * The body is parsed defensively at every step. A 502 from a proxy in front of\n * the API returns HTML, and an SDK that assumes JSON turns a bad gateway into\n * an unhelpful SyntaxError thrown from inside the error handler.\n */\nexport function errorFromResponse(\n status: number,\n body: unknown,\n headers: { get(name: string): string | null }\n): PersistMemoryError {\n const envelope = (body ?? {}) as ErrorEnvelope;\n const code = typeof envelope.error?.code === \"string\" ? envelope.error.code : codeForStatus(status);\n const message =\n typeof envelope.error?.message === \"string\" && envelope.error.message.length > 0\n ? envelope.error.message\n : defaultMessage(status);\n\n // Read for 429 and 503 alike. A 503 with a `Retry-After` is a service\n // telling us when it will be back, and ignoring it because the status was\n // not 429 means retrying into an outage that has said it is not over.\n const retryAfterSeconds =\n status === 429 || status === 503 ? retryAfterOf(headers) : undefined;\n\n const init: ApiErrorInit = {\n status,\n code,\n message,\n ...(isFieldMap(envelope.error?.fields) ? { fields: envelope.error.fields } : {}),\n ...(typeof envelope.error?.requestId === \"string\"\n ? { requestId: envelope.error.requestId }\n : {}),\n ...(retryAfterSeconds !== undefined ? { retryAfterSeconds } : {})\n };\n\n if (status === 429 || code === \"RATE_LIMITED\") return new RateLimitError(init);\n if (status === 401 || code === \"UNAUTHORIZED\") return new AuthenticationError(init);\n if (status === 403 || code === \"FORBIDDEN\") return new PermissionDeniedError(init);\n if (status === 404 || code === \"NOT_FOUND\") return new NotFoundError(init);\n if (status === 409 || code === \"CONFLICT\") return new ConflictError(init);\n if (status === 400 || status === 413 || status === 422) return new ValidationError(init);\n if (status >= 500) return new ServerError(init);\n\n // Anything else - a 405 from a misconfigured proxy, a 402 the API grows\n // later. Named honestly rather than forced into the nearest class, because\n // a caller catching `ValidationError` should not be handed a payment\n // problem.\n return new PersistMemoryError(init);\n}\n\n/**\n * `Retry-After`, in seconds, when the header is one we can trust.\n *\n * Only the delta-seconds form is honoured. The HTTP-date form is also legal\n * and is parsed against the CLIENT's clock, which on a laptop that has been\n * asleep can be minutes out - and a negative delay computed from a skewed\n * clock is a retry storm aimed at a service that just asked for quiet.\n */\nfunction retryAfterOf(headers: { get(name: string): string | null }): number | undefined {\n const raw = headers.get(\"retry-after\");\n if (!raw) return undefined;\n\n const seconds = Number(raw.trim());\n if (!Number.isFinite(seconds) || seconds < 0) return undefined;\n // Capped. A header saying 86400 would otherwise park a caller's retry for a\n // day inside a call they expected to return.\n return Math.min(seconds, 300);\n}\n\nfunction isFieldMap(value: unknown): value is Record<string, string> {\n if (typeof value !== \"object\" || value === null || Array.isArray(value)) return false;\n return Object.values(value).every((one) => typeof one === \"string\");\n}\n\nfunction codeForStatus(status: number): ErrorCode {\n if (status === 401) return \"UNAUTHORIZED\";\n if (status === 403) return \"FORBIDDEN\";\n if (status === 404) return \"NOT_FOUND\";\n if (status === 409) return \"CONFLICT\";\n if (status === 429) return \"RATE_LIMITED\";\n if (status === 413) return \"PAYLOAD_TOO_LARGE\";\n if (status >= 500) return \"INTERNAL_ERROR\";\n return \"VALIDATION_ERROR\";\n}\n\nfunction defaultMessage(status: number): string {\n // Deliberately says the body was unreadable rather than inventing a reason.\n // A message claiming \"not found\" for a 404 that was actually an HTML error\n // page from a proxy sends whoever is debugging to the wrong system.\n return `The API returned ${status} with no readable error body.`;\n}\n\n/**\n * Removes anything key-shaped from a string bound for an error message.\n *\n * Every message this module produces goes through here, including the\n * server's own. It should never contain a key - we never send it in a body\n * and the API never echoes it - but \"should never\" is how credentials end up\n * in issue trackers. The cost is one regex on a path that has already failed.\n */\nexport function redact(text: string): string {\n return text.replace(/pm_(live|test)_[A-Za-z0-9_-]+/g, \"pm_$1_[redacted]\");\n}\n", "import type { BackoffOptions } from \"./backoff\";\nimport type { QueryParams } from \"./query\";\nimport { encodeQuery } from \"./query\";\nimport { delayFor } from \"./backoff\";\nimport {\n AbortError,\n ConnectionError,\n PersistMemoryError,\n TimeoutError,\n errorFromResponse,\n redact\n} from \"./errors\";\n\n/**\n * The one place a request is made, retried, timed out and turned into an error.\n *\n * Every resource in this package goes through `request`. That is deliberate:\n * an SDK where each resource calls `fetch` for itself is an SDK with six\n * slightly different retry policies, and the differences only show up during\n * an outage, which is the moment nobody wants to be reading six files.\n *\n * `fetch` is injected rather than imported. It is what makes a test of this\n * incapable of opening a socket by accident, and it is the same reason every\n * provider client in this repo takes one.\n */\nexport type { QueryParams, QueryValue } from \"./query\";\n\nexport interface ClientOptions {\n /**\n * A `pm_live_...` API key, or a session JWT.\n *\n * Held privately and never returned, logged, stringified or put in an error.\n * See `#apiKey` below and the `toJSON` next to it.\n */\n readonly apiKey: string;\n readonly baseUrl?: string;\n readonly fetch?: typeof globalThis.fetch;\n /**\n * Per-attempt deadline, not a budget for the whole call.\n *\n * Per attempt because a whole-call deadline interacts badly with backoff: a\n * request that spent nine seconds waiting between retries would get one\n * second to actually run, and the failure would look like a slow server.\n */\n readonly timeoutMs?: number;\n /** Attempts, not retries. 3 means the original and two more. */\n readonly maxAttempts?: number;\n readonly backoff?: BackoffOptions;\n /** Injected so tests do not spend real seconds asleep. */\n readonly sleep?: (ms: number, signal?: AbortSignal) => Promise<void>;\n /** Sent on every request, for support and for server-side triage. */\n readonly userAgent?: string;\n}\n\nexport interface RequestOptions {\n /** Cancels the call. A caller's abort is never retried - they asked it to stop. */\n readonly signal?: AbortSignal;\n readonly timeoutMs?: number;\n readonly maxAttempts?: number;\n /**\n * Makes a POST safe to retry.\n *\n * The API deduplicates on this header, so a retry after a timeout finds the\n * first result rather than doing the work twice. Without one, this client\n * will NOT retry a POST that may already have been processed - see\n * `mayRetry`.\n *\n * Give it meaning: `remember:note-42`, not a fresh random value per call. A\n * random one makes every retry a new request, which is exactly what it\n * exists to prevent.\n */\n readonly idempotencyKey?: string;\n}\n\ninterface InternalRequest {\n readonly method: \"GET\" | \"POST\" | \"PATCH\" | \"DELETE\";\n readonly path: string;\n readonly query?: QueryParams;\n readonly body?: unknown;\n /**\n * Bytes, for the endpoints that take a file.\n *\n * Separate from `body` rather than sniffed out of it: `JSON.stringify` of a\n * `Uint8Array` produces `{\"0\":137,\"1\":80,...}`, which is a valid request and\n * a corrupt file - and the failure shows up as \"this PDF is not a PDF\" a\n * long way from the line that caused it.\n */\n readonly rawBody?: Uint8Array;\n readonly contentType?: string;\n /** Bytes back, for a download. JSON is parsed; a file is not. */\n readonly rawResponse?: boolean;\n readonly options?: RequestOptions;\n}\n\nconst DEFAULT_BASE_URL = \"https://api.persistmemory.com\";\nconst DEFAULT_TIMEOUT_MS = 30_000;\nconst DEFAULT_MAX_ATTEMPTS = 3;\n\n/**\n * Methods this client will retry without being told it is safe to.\n *\n * PATCH and DELETE are in here because of what they are in THIS API and not\n * because the RFC calls them idempotent: `PATCH /spaces/{id}` sets named\n * fields to given values, and `DELETE /spaces/{id}/memories` removes a set of\n * memberships. Applying either twice lands in the same state as applying it\n * once. POST is the one that does not - `remember` queues a job every time.\n */\nconst RETRY_WITHOUT_ASKING = new Set([\"GET\", \"HEAD\", \"PATCH\", \"DELETE\"]);\n\nexport class HttpClient {\n /**\n * The credential, in a private field, and never anywhere else.\n *\n * Private (`#`) rather than `readonly`: a public field is enumerable, so\n * `JSON.stringify(client)` and every structured logger that walks own\n * properties would write the key into a log line. `toJSON` and the inspect\n * hook below close the two remaining paths - a bug report pasted from\n * `console.log(client)` is exactly how a key gets shared with strangers.\n */\n readonly #apiKey: string;\n readonly #baseUrl: string;\n readonly #fetch: typeof globalThis.fetch;\n readonly #timeoutMs: number;\n readonly #maxAttempts: number;\n readonly #backoff: BackoffOptions;\n readonly #sleep: (ms: number, signal?: AbortSignal) => Promise<void>;\n readonly #userAgent: string;\n\n constructor(options: ClientOptions) {\n if (typeof options.apiKey !== \"string\" || options.apiKey.trim().length === 0) {\n // Refused here rather than as a 401 from the server, because the server\n // cannot say WHICH of \"missing\", \"empty\" and \"undefined stringified\"\n // happened, and all three come from the same forgotten environment\n // variable.\n throw new PersistMemoryError({\n status: 0,\n code: \"VALIDATION_ERROR\",\n message: \"An API key is required. Pass `apiKey`, or set PERSISTMEMORY_API_KEY.\"\n });\n }\n\n // A newline in a credential is header injection, and the usual source is\n // a key read from a file with `readFileSync` and never trimmed. Trimmed\n // rather than rejected for whitespace, then checked for anything a header\n // value may not carry.\n const key = options.apiKey.trim();\n if (/[\\r\\n\\0]/.test(key)) {\n // The key itself is NOT in this message. It is the one string in the\n // whole package that must never reach an error.\n throw new PersistMemoryError({\n status: 0,\n code: \"VALIDATION_ERROR\",\n message: \"The API key contains characters that cannot go in a header.\"\n });\n }\n\n this.#apiKey = key;\n // Trailing slashes stripped once, here. Left alone, `baseUrl + path`\n // produces `//api/v1/...`, which some proxies normalise and some route to\n // a 404 - a difference that only appears in production.\n this.#baseUrl = (options.baseUrl ?? DEFAULT_BASE_URL).replace(/\\/+$/, \"\");\n this.#fetch = options.fetch ?? globalThis.fetch;\n this.#timeoutMs = options.timeoutMs ?? DEFAULT_TIMEOUT_MS;\n this.#maxAttempts = Math.max(1, options.maxAttempts ?? DEFAULT_MAX_ATTEMPTS);\n this.#backoff = options.backoff ?? {};\n this.#sleep = options.sleep ?? defaultSleep;\n this.#userAgent = options.userAgent ?? \"persistmemory-sdk-js/0.1.0\";\n }\n\n /**\n * What this object looks like when something serialises it.\n *\n * Both hooks return the same key-free shape. `toJSON` covers\n * `JSON.stringify`, the inspect symbol covers `console.log` under Node, and\n * between them they cover how a credential actually escapes: not through a\n * deliberate log line, but through an object dumped into a bug report.\n */\n toJSON(): Record<string, unknown> {\n return { baseUrl: this.#baseUrl, apiKey: \"[redacted]\" };\n }\n\n [Symbol.for(\"nodejs.util.inspect.custom\")](): Record<string, unknown> {\n return this.toJSON();\n }\n\n async get<T>(path: string, query?: QueryParams, options?: RequestOptions): Promise<T> {\n return this.#request<T>({\n method: \"GET\",\n path,\n ...(query ? { query } : {}),\n ...(options ? { options } : {})\n });\n }\n\n async post<T>(path: string, body?: unknown, options?: RequestOptions): Promise<T> {\n return this.#request<T>({\n method: \"POST\",\n path,\n ...(body !== undefined ? { body } : {}),\n ...(options ? { options } : {})\n });\n }\n\n /** POST with a file as the body. The type describes the bytes, not JSON. */\n async postBytes<T>(\n path: string,\n bytes: Uint8Array,\n contentType: string,\n query?: QueryParams,\n options?: RequestOptions\n ): Promise<T> {\n return this.#request<T>({\n method: \"POST\",\n path,\n rawBody: bytes,\n contentType,\n ...(query ? { query } : {}),\n ...(options ? { options } : {})\n });\n }\n\n /** GET that returns bytes rather than JSON, for downloading a file. */\n async getBytes(\n path: string,\n query?: QueryParams,\n options?: RequestOptions\n ): Promise<{ bytes: Uint8Array; contentType: string; filename?: string }> {\n return this.#request({\n method: \"GET\",\n path,\n rawResponse: true,\n ...(query ? { query } : {}),\n ...(options ? { options } : {})\n });\n }\n\n async patch<T>(path: string, body?: unknown, options?: RequestOptions): Promise<T> {\n return this.#request<T>({\n method: \"PATCH\",\n path,\n ...(body !== undefined ? { body } : {}),\n ...(options ? { options } : {})\n });\n }\n\n async delete<T>(path: string, body?: unknown, options?: RequestOptions): Promise<T> {\n return this.#request<T>({\n method: \"DELETE\",\n path,\n ...(body !== undefined ? { body } : {}),\n ...(options ? { options } : {})\n });\n }\n\n async #request<T>(request: InternalRequest): Promise<T> {\n const maxAttempts = Math.max(1, request.options?.maxAttempts ?? this.#maxAttempts);\n const url = this.#baseUrl + request.path + encodeQuery(request.query);\n\n let attempt = 0;\n // Unbounded `while` with the exit conditions inside, rather than a `for`\n // over attempts: every path out of here either returns or throws, and a\n // loop that can fall off the end would silently return undefined as `T`.\n for (;;) {\n attempt += 1;\n\n let error: PersistMemoryError;\n try {\n return await this.#attempt<T>(request, url);\n } catch (thrown) {\n // Anything that is not one of ours is a programming error in this\n // package - a bad URL, a body that will not serialise - and rethrowing\n // it unchanged is right. Wrapping it as a retryable transport failure\n // would make the request loop retry a defect that fails identically\n // every time.\n if (!(thrown instanceof PersistMemoryError)) throw thrown;\n error = thrown;\n }\n\n if (attempt >= maxAttempts) throw error;\n if (!mayRetry(error, request)) throw error;\n\n const delay = delayFor({\n attempt,\n ...(error.retryAfterSeconds !== undefined\n ? { retryAfterSeconds: error.retryAfterSeconds }\n : {}),\n options: this.#backoff\n });\n\n // The caller's signal is passed into the wait too. Without it an aborted\n // call still sits out its full backoff before noticing, which to a user\n // who pressed cancel is indistinguishable from the cancel not working.\n await this.#sleep(delay, request.options?.signal);\n }\n }\n\n async #attempt<T>(request: InternalRequest, url: string): Promise<T> {\n const timeoutMs = request.options?.timeoutMs ?? this.#timeoutMs;\n const deadline = new AbortController();\n const timer = setTimeout(() => deadline.abort(), timeoutMs);\n // Linked rather than AbortSignal.any: this package supports Node 18, where\n // `any` does not exist. The listener is removed in the `finally`, because\n // a long-lived caller signal that accumulated one listener per request is\n // a leak that only shows up under load.\n const onCallerAbort = () => deadline.abort();\n const caller = request.options?.signal;\n caller?.addEventListener(\"abort\", onCallerAbort, { once: true });\n\n try {\n if (caller?.aborted) throw new AbortError();\n\n // Raced against the deadline rather than left to `fetch` alone.\n // `fetch` is injected here, and not every implementation honours a\n // signal - a mocked one in someone's test suite, an older polyfill, a\n // wrapper that forgets to forward it. When one does not, an unanswered\n // request hangs forever and the timeout this client documents is a\n // promise it does not keep.\n const response = await untilAborted(\n this.#fetch(url, {\n method: request.method,\n headers: this.#headers(request),\n ...(request.rawBody !== undefined\n ? { body: request.rawBody }\n : request.body !== undefined\n ? { body: JSON.stringify(request.body) }\n : {}),\n signal: deadline.signal\n }),\n deadline.signal\n );\n\n /*\n A failure is JSON even on a route that answers with bytes.\n\n Reading the body as an ArrayBuffer first would turn a 409 explaining\n that no Google account is connected into an unreadable buffer, and the\n caller would get \"download failed\" instead of the sentence telling them\n what to do.\n */\n if (request.rawResponse && response.ok) {\n const disposition = response.headers.get(\"content-disposition\") ?? \"\";\n const named = /filename=\"([^\"]+)\"/.exec(disposition)?.[1];\n\n return {\n bytes: new Uint8Array(await response.arrayBuffer()),\n contentType: response.headers.get(\"content-type\") ?? \"application/octet-stream\",\n ...(named ? { filename: named } : {})\n } as T;\n }\n\n const payload = await readBody(response);\n if (!response.ok) throw errorFromResponse(response.status, payload, response.headers);\n return payload as T;\n } catch (thrown) {\n if (thrown instanceof PersistMemoryError) throw thrown;\n\n // Three different things arrive here as one AbortError from fetch, and\n // they need three different answers: the caller cancelled (do not\n // retry), we ran out of time (retry), or the network failed (retry, but\n // not for a POST). Telling them apart by asking WHOSE signal fired is\n // the only reliable way - the DOMException looks the same either way.\n if (caller?.aborted) throw new AbortError();\n if (deadline.signal.aborted) {\n throw new TimeoutError(`The request did not complete within ${timeoutMs}ms.`);\n }\n\n const detail = thrown instanceof Error ? redact(thrown.message) : \"transport failure\";\n throw new ConnectionError(`Could not reach the API: ${detail}`);\n } finally {\n clearTimeout(timer);\n caller?.removeEventListener(\"abort\", onCallerAbort);\n }\n }\n\n #headers(request: InternalRequest): Record<string, string> {\n return {\n // The only place the key is ever read.\n authorization: `Bearer ${this.#apiKey}`,\n // A download route answers with the file's own type, so `*/*` rather\n // than a promise to accept only JSON that the server would have to break.\n accept: request.rawResponse ? \"*/*\" : \"application/json\",\n \"user-agent\": this.#userAgent,\n ...(request.rawBody !== undefined\n ? { \"content-type\": request.contentType ?? \"application/octet-stream\" }\n : request.body !== undefined\n ? { \"content-type\": \"application/json\" }\n : {}),\n ...(request.options?.idempotencyKey\n ? { \"idempotency-key\": request.options.idempotencyKey }\n : {})\n };\n }\n}\n\n/**\n * Whether this failure is worth another attempt.\n *\n * Two questions, and both have to say yes. The first is whether the failure\n * itself could clear - a 400 fails identically on every attempt, so retrying\n * spends two more calls to learn the same thing. The second is whether\n * repeating the REQUEST is safe, which is a different question and the one\n * that gets skipped.\n *\n * For a POST the honest answer is that we usually cannot tell. A connection\n * that died after the server accepted the request is indistinguishable from\n * one that died before, so retrying `remember` on a timeout would queue the\n * same note twice and the user would see it remembered twice. So a POST is\n * retried only when:\n *\n * an idempotency key was given the API deduplicates on it, so the retry\n * returns the first result rather than\n * repeating the work\n *\n * the status was 429 the request was refused BEFORE it was\n * processed. That is what a rate limit is,\n * and it is the one case where \"already\n * succeeded\" is not possible\n *\n * Every other retryable POST failure - a 500, a 503, a timeout, a reset - is\n * given back to the caller, who knows whether repeating it is safe and this\n * package does not.\n */\nexport function mayRetry(error: PersistMemoryError, request: InternalRequest): boolean {\n if (!error.retryable) return false;\n if (RETRY_WITHOUT_ASKING.has(request.method)) return true;\n if (request.options?.idempotencyKey) return true;\n return error.status === 429;\n}\n\n/**\n * The body, parsed if it is JSON and there is any.\n *\n * Never assumes JSON. A 502 from a load balancer in front of the API is an\n * HTML page, and an SDK that calls `response.json()` unconditionally turns a\n * bad gateway into a SyntaxError thrown from inside the error handler - which\n * hides the actual failure behind a parse error nobody can act on.\n */\nasync function readBody(response: Response): Promise<unknown> {\n if (response.status === 204) return undefined;\n\n const text = await response.text().catch(() => \"\");\n if (text.length === 0) return undefined;\n\n const type = response.headers.get(\"content-type\") ?? \"\";\n if (!type.includes(\"json\")) return { raw: text.slice(0, 500) };\n\n try {\n return JSON.parse(text) as unknown;\n } catch {\n // Truncated, because a body that failed to parse can be megabytes of an\n // upstream error page and this string reaches an error message.\n return { raw: text.slice(0, 500) };\n }\n}\n\n/**\n * The response, or a rejection the moment the signal fires.\n *\n * The original promise is left with a `catch` attached: it may still settle\n * long after we have stopped waiting, and an unattended rejection from an\n * abandoned request takes the process down under Node's default handling.\n */\nclass SignalFired extends Error {\n constructor() {\n // Deliberately NOT one of this package's errors. It is raised before we\n // know WHICH signal fired, and the catch in `#attempt` is the only place\n // that can tell a caller's cancel from a deadline - a `TimeoutError`\n // thrown here would be a timeout reported for a user pressing stop.\n super(\"signal fired\");\n this.name = \"SignalFired\";\n }\n}\n\nfunction untilAborted<T>(work: Promise<T>, signal: AbortSignal): Promise<T> {\n work.catch(() => undefined);\n\n return new Promise<T>((resolve, reject) => {\n if (signal.aborted) {\n reject(new SignalFired());\n return;\n }\n\n const onAbort = () => reject(new SignalFired());\n signal.addEventListener(\"abort\", onAbort, { once: true });\n\n work.then(\n (value) => {\n signal.removeEventListener(\"abort\", onAbort);\n resolve(value);\n },\n (error: unknown) => {\n signal.removeEventListener(\"abort\", onAbort);\n reject(error instanceof Error ? error : new Error(String(error)));\n }\n );\n });\n}\n\n/**\n * A wait that can be cancelled.\n *\n * The default. Injected in tests so a retry test does not spend real seconds\n * asleep - a suite that actually waits out an exponential backoff is a suite\n * people stop running.\n */\nfunction defaultSleep(ms: number, signal?: AbortSignal): Promise<void> {\n return new Promise((resolve, reject) => {\n if (signal?.aborted) {\n reject(new AbortError());\n return;\n }\n\n const timer = setTimeout(() => {\n signal?.removeEventListener(\"abort\", onAbort);\n resolve();\n }, ms);\n\n function onAbort(): void {\n clearTimeout(timer);\n reject(new AbortError());\n }\n\n signal?.addEventListener(\"abort\", onAbort, { once: true });\n });\n}\n", "import type { Page } from \"./types\";\n\n/**\n * Walking a cursor-paginated list.\n *\n * The list endpoints are keyset paginated: `?cursor=` carries where the last\n * page ended, and the response is `{ data, pagination: { nextCursor?, limit } }`\n * with `nextCursor` absent on the last page. The absence is the ONLY stop\n * signal - an empty `data` array is not the same thing, because a page can\n * come back empty when everything in it was filtered after the fetch while\n * more pages remain. A client that stops on an empty page silently truncates\n * the user's results and nothing anywhere reports an error.\n *\n * That rule is easy to state and easy to get wrong once per call site, which\n * is why every list method returns one of these instead of leaving the loop to\n * the caller.\n *\n * Not every list is paginated. `spaces/{id}/memories` and\n * `entities/{id}/memories` return a `pagination` block with no cursor at all,\n * so iterating them yields exactly one page and stops - which is correct, and\n * costs a caller nothing for using the same shape everywhere.\n */\nexport class Paginated<T> implements AsyncIterable<T> {\n readonly #fetchPage: (cursor: string | undefined) => Promise<Page<T>>;\n\n constructor(fetchPage: (cursor: string | undefined) => Promise<Page<T>>) {\n this.#fetchPage = fetchPage;\n }\n\n /** The first page, and nothing more. For a UI that renders one page at a time. */\n async first(): Promise<Page<T>> {\n return this.#fetchPage(undefined);\n }\n\n /**\n * Page by page, for a caller that wants the cursors or wants to stop early.\n *\n * A generator rather than an array of pages: fetching them all up front\n * would make \"show me the first ten\" cost every page in the account.\n */\n async *pages(): AsyncGenerator<Page<T>, void, undefined> {\n let cursor: string | undefined;\n const seen = new Set<string>();\n\n for (;;) {\n const page: Page<T> = await this.#fetchPage(cursor);\n yield page;\n\n const next = page.pagination.nextCursor;\n if (!next) return;\n\n // A cursor we have already followed means the server is handing back a\n // position that does not advance, and continuing is an infinite loop\n // that reads the same page forever while looking exactly like a slow\n // account. Stopping loses a page; looping loses the process.\n if (seen.has(next)) return;\n seen.add(next);\n cursor = next;\n }\n }\n\n /** Every item across every page. `for await (const memory of ...)`. */\n async *[Symbol.asyncIterator](): AsyncGenerator<T, void, undefined> {\n for await (const page of this.pages()) {\n for (const item of page.data) yield item;\n }\n }\n\n /**\n * Everything, in one array.\n *\n * `maxItems` is not optional, and that is the point. An unbounded `all()` on\n * an account with two hundred thousand memories is a request loop that runs\n * for minutes and an array that exhausts the heap, and the call site that\n * does it reads as innocently as any other. Ask for a number you can hold.\n */\n async all(maxItems: number): Promise<T[]> {\n const collected: T[] = [];\n if (maxItems <= 0) return collected;\n\n for await (const item of this) {\n collected.push(item);\n if (collected.length >= maxItems) break;\n }\n return collected;\n }\n}\n", "import type { HttpClient, QueryParams, RequestOptions } from \"../http\";\nimport { Paginated } from \"../pagination\";\nimport { pageQuery } from \"../query\";\nimport type { ListMemoriesParams, Memory, Page, RememberParams, RememberResult } from \"../types\";\n\n/**\n * Memories: browsing them, reading one, and handing over new material.\n *\n * Browsing is not searching. `list` is chronological and takes filters,\n * `search` ranks by relevance and takes a query - they are separate endpoints\n * because serving both from one would mean a caller who adds a filter silently\n * gets a differently ordered list.\n */\nexport class Memories {\n readonly #http: HttpClient;\n\n constructor(http: HttpClient) {\n this.#http = http;\n }\n\n /**\n * One page, plus the cursor loop.\n *\n * Returns a `Paginated`, so `await memories.list().first()` gets a page and\n * `for await (const memory of memories.list())` walks the lot. The filters\n * are carried into every page automatically - a caller re-passing them per\n * page is a caller who will eventually forget one, and the pages after that\n * come from a differently filtered list.\n */\n list(params: ListMemoriesParams = {}, options?: RequestOptions): Paginated<Memory> {\n return new Paginated<Memory>((cursor) =>\n this.#http.get<Page<Memory>>(\n \"/api/v1/memories\",\n pageQuery(params, cursor, toQuery(params)),\n options\n )\n );\n }\n\n async get(id: string, options?: RequestOptions): Promise<Memory> {\n return this.#http.get<Memory>(`/api/v1/memories/${encodeURIComponent(id)}`, undefined, options);\n }\n\n /**\n * Hands material to the ingestion pipeline. Needs a key with `write` scope.\n *\n * This does NOT create a memory, and the return type says so: it answers 202\n * with a job id. Extraction, entity resolution, deduplication and conflict\n * detection all run afterwards and may produce one memory, several, or none.\n * Poll `client.jobs.get(result.jobId)` to find out which.\n *\n * Pass an `idempotencyKey` if this can be retried by anything - a queue, a\n * user pressing a button twice, or this client's own retry loop, which\n * refuses to repeat a POST without one. `remember:note-42`, not a fresh\n * random value per call.\n */\n async remember(params: RememberParams, options?: RequestOptions): Promise<RememberResult> {\n return this.#http.post<RememberResult>(\"/api/v1/remember\", params, options);\n }\n}\n\nfunction toQuery(params: ListMemoriesParams): QueryParams {\n return {\n ...(params.type !== undefined ? { type: params.type } : {}),\n ...(params.state !== undefined ? { state: params.state } : {}),\n ...(params.scope !== undefined ? { scope: params.scope } : {}),\n ...(params.spaceIds !== undefined ? { spaceIds: params.spaceIds } : {}),\n ...(params.createdAfter !== undefined ? { createdAfter: params.createdAfter } : {}),\n ...(params.createdBefore !== undefined ? { createdBefore: params.createdBefore } : {}),\n ...(params.minConfidence !== undefined ? { minConfidence: params.minConfidence } : {}),\n ...(params.includeHistorical !== undefined\n ? { includeHistorical: params.includeHistorical }\n : {})\n };\n}\n", "import type { HttpClient, QueryParams, RequestOptions } from \"../http\";\nimport type { ContextParams, ContextResponse, SearchParams, SearchResponse } from \"../types\";\n\n/**\n * Asking the system what it knows.\n *\n * Two methods, and they answer different questions. `search` returns ranked\n * records for a person or a UI. `context` returns prose for a model, bounded\n * by TOKENS rather than by row count - which is the only bound that expresses\n * the real constraint, since ten long memories overflow a window that fifty\n * short ones fit inside.\n *\n * `search` is a GET and `context` is a POST, matching the API: a search is\n * linkable and cacheable, while a context request can carry two hundred\n * excluded ids and every proxy in between has its own idea of how long a URL\n * may be.\n */\nexport class Search {\n readonly #http: HttpClient;\n\n constructor(http: HttpClient) {\n this.#http = http;\n }\n\n /**\n * Ranked results, with an account of how they were found.\n *\n * Read `diagnostics.degraded` before showing the results. Search degrades\n * rather than fails - with embeddings unavailable it falls back to\n * deterministic retrieval and still answers - and a UI that cannot tell\n * degraded from healthy tells the user the system knows nothing when it is\n * merely looking with one eye.\n */\n async query(params: SearchParams, options?: RequestOptions): Promise<SearchResponse> {\n const query: QueryParams = {\n query: params.query,\n ...(params.limit !== undefined ? { limit: params.limit } : {}),\n ...(params.scope !== undefined ? { scope: params.scope } : {}),\n ...(params.spaceIds !== undefined ? { spaceIds: params.spaceIds } : {}),\n ...(params.types !== undefined ? { types: params.types } : {}),\n ...(params.minScore !== undefined ? { minScore: params.minScore } : {}),\n ...(params.asOf !== undefined ? { asOf: params.asOf } : {}),\n ...(params.includeHistorical !== undefined\n ? { includeHistorical: params.includeHistorical }\n : {}),\n ...(params.includeEvidence !== undefined\n ? { includeEvidence: params.includeEvidence }\n : {}),\n ...(params.explain !== undefined ? { explain: params.explain } : {})\n };\n\n return this.#http.get<SearchResponse>(\"/api/v1/search\", query, options);\n }\n\n /**\n * A context window, assembled and ready to paste into a prompt.\n *\n * A POST that is safe to repeat - it reads and returns, it writes nothing -\n * so this is one of the few places where retrying without an idempotency key\n * would be harmless. It still is not retried by default: the request loop\n * decides by METHOD, and a per-endpoint exception is a rule that holds until\n * someone adds a POST next to it that does write.\n */\n async context(params: ContextParams, options?: RequestOptions): Promise<ContextResponse> {\n return this.#http.post<ContextResponse>(\"/api/v1/context\", params, options);\n }\n}\n", "import type { HttpClient, RequestOptions } from \"../http\";\nimport { Paginated } from \"../pagination\";\nimport { pageQuery } from \"../query\";\nimport type {\n CreateSpaceParams,\n ListSpacesParams,\n Memory,\n Page,\n ShareSpaceParams,\n Space,\n SpaceCollaborator,\n GrantableSpaceRole,\n SpaceRole,\n UpdateSpaceParams,\n WorkingSpace\n} from \"../types\";\n\n/**\n * Spaces: a boundary around a set of memories.\n *\n * They exist because \"everything I know\" is the wrong scope for most\n * questions. Work and personal contexts hold contradictory truths - two\n * different \"my manager\" - and answering from both at once is wrong in a way\n * that is hard to notice.\n *\n * Membership is a LINK, not ownership. `removeMemories` takes a memory out of\n * a Space; it does not delete it, and the same memory can belong to several.\n */\nexport class Spaces {\n readonly #http: HttpClient;\n\n constructor(http: HttpClient) {\n this.#http = http;\n }\n\n list(params: ListSpacesParams = {}, options?: RequestOptions): Paginated<Space> {\n return new Paginated<Space>((cursor) =>\n this.#http.get<Page<Space>>(\n \"/api/v1/spaces\",\n pageQuery(params, cursor, {\n ...(params.includeArchived !== undefined\n ? { includeArchived: params.includeArchived }\n : {})\n }),\n options\n )\n );\n }\n\n async get(id: string, options?: RequestOptions): Promise<Space> {\n return this.#http.get<Space>(`/api/v1/spaces/${encodeURIComponent(id)}`, undefined, options);\n }\n\n /**\n * Creates a Space. Answers 201.\n *\n * Worth an idempotency key when a person is behind it: a double-clicked\n * \"create Space\" button makes two Spaces called Work, and nothing later can\n * tell which of them memories should have gone into.\n */\n async create(params: CreateSpaceParams, options?: RequestOptions): Promise<Space> {\n return this.#http.post<Space>(\"/api/v1/spaces\", params, options);\n }\n\n /**\n * Deletes a Space. You must say what happens to what is in it.\n *\n * There is no default, here or in the API, and that is deliberate: \"delete\n * this Space\" means the label to some people and everything inside it to\n * others, and a client that guessed would destroy or keep somebody's\n * material without being asked.\n *\n * `delete` never destroys a memory that is filed in another Space as well \u2014\n * that one is detached and left alone. `deleted` and `kept` come back so you\n * can say what actually happened.\n *\n * `moveTo` NAMES WHERE THE STRANDED ONES GO, and is refused-into rather than\n * required: most deletions strand nothing, because everything in the Space\n * is also filed elsewhere, and demanding a destination for those would be a\n * question about nothing. When something WOULD be left in no Space at all,\n * the server answers 400 naming this field. It used to file them into the\n * account's default, which no longer exists \u2014 nothing picks a Space on\n * anybody's behalf, so \"keep these\" has no answer unless you say where.\n */\n async delete(\n id: string,\n params: { readonly memories: \"keep\" | \"delete\"; readonly moveTo?: string },\n options?: RequestOptions\n ): Promise<{ deleted: number; kept: number; rehomed?: number }> {\n return this.#http.delete<{ deleted: number; kept: number; rehomed?: number }>(\n `/api/v1/spaces/${encodeURIComponent(id)}`,\n params,\n options\n );\n }\n\n /**\n * Merges Spaces into a NEW one, leaving every source exactly as it was.\n *\n * Additive, not destructive: a memory ends up in the sources AND the result,\n * every existing search over a source returns what it did before, and\n * undoing it is deleting the Space this returns. A memory in two sources is\n * filed once.\n */\n async merge(\n params: {\n readonly sourceIds: readonly string[];\n readonly name: string;\n readonly description?: string;\n },\n options?: RequestOptions\n ): Promise<{ space: Space; added: number }> {\n return this.#http.post<{ space: Space; added: number }>(\n \"/api/v1/spaces/merge\",\n params,\n options\n );\n }\n\n /* ------------------------- where this is working ------------------------- */\n\n /*\n `getDefault` AND `setDefault` ARE GONE, with the endpoints they called.\n\n They read and wrote the account-wide Space a capture fell into when nobody\n named one. Nothing falls anywhere now: a Space is chosen for the context\n doing the capturing, or `remember` answers 400. Keeping the methods would\n mean keeping two calls that 404, which is a worse break than removing them\n because it looks like a server fault rather than a change.\n */\n\n /**\n * Which Space a context is working in.\n *\n * `chosen` absent means NOTHING sent from that context is kept \u2014 there is no\n * default behind it and nothing picks one. The reply used to carry a\n * `fallback` for that case and no longer can.\n *\n * `profile` is the command line's own profile name, and `surface` says which\n * context is being asked about: `cli` for this profile, `email` for the\n * account's ingest address. Between them they are the whole of what a caller\n * may say about where it is working \u2014 the server builds the scope key\n * itself, so this can never read or move where a chat is filing.\n */\n async working(\n params: { readonly profile?: string; readonly surface?: \"cli\" | \"email\" } = {},\n options?: RequestOptions\n ): Promise<WorkingSpace> {\n return this.#http.get<WorkingSpace>(\n \"/api/v1/spaces/working\",\n {\n ...(params.profile !== undefined ? { profile: params.profile } : {}),\n ...(params.surface !== undefined ? { surface: params.surface } : {})\n },\n options\n );\n }\n\n /**\n * Works in one from here on. `null` stops working in any.\n *\n * Takes an id or a NAME, because that is how a person says it. `null` rather\n * than an omitted field: \"clear this\" and \"I did not mention it\" are\n * different instructions, and clearing means this context keeps nothing\n * until a Space is chosen again.\n */\n async chooseWorking(\n space: string | null,\n params: { readonly profile?: string; readonly surface?: \"cli\" | \"email\" } = {},\n options?: RequestOptions\n ): Promise<WorkingSpace> {\n return this.#http.patch<WorkingSpace>(\n \"/api/v1/spaces/working\",\n {\n space,\n ...(params.profile !== undefined ? { profile: params.profile } : {}),\n ...(params.surface !== undefined ? { surface: params.surface } : {})\n },\n options\n );\n }\n\n /** Renaming, retention, and archiving - `archived` is a field, not a verb. */\n async update(id: string, params: UpdateSpaceParams, options?: RequestOptions): Promise<Space> {\n return this.#http.patch<Space>(`/api/v1/spaces/${encodeURIComponent(id)}`, params, options);\n }\n\n /**\n * The memories filed in a Space.\n *\n * The cursor is PASSED. This fetch used to ignore the paginator's cursor\n * on the stale belief that the endpoint had none \u2014 the server has minted\n * `pagination.nextCursor` since it started paging, and its own comment\n * says \"both SDKs iterate by reading pagination\". Ignoring it meant every\n * page request was identical: the loop guard saw a non-advancing fetch and\n * stopped silently, so `all()` returned the first page twice and dropped\n * everything after it \u2014 duplicated AND truncated data, with no error.\n */\n memories(\n id: string,\n params: { readonly limit?: number } = {},\n options?: RequestOptions\n ): Paginated<Memory> {\n return new Paginated<Memory>((cursor) =>\n this.#http.get<Page<Memory>>(\n `/api/v1/spaces/${encodeURIComponent(id)}/memories`,\n {\n ...(params.limit !== undefined ? { limit: params.limit } : {}),\n ...(cursor !== undefined ? { cursor } : {})\n },\n options\n )\n );\n }\n\n async addMemories(\n id: string,\n memoryIds: readonly string[],\n options?: RequestOptions\n ): Promise<{ added: number }> {\n return this.#http.post<{ added: number }>(\n `/api/v1/spaces/${encodeURIComponent(id)}/memories`,\n { memoryIds },\n options\n );\n }\n\n /**\n * Removes memberships. The memories themselves are untouched.\n *\n * A body on a DELETE, which is unusual and is what the API takes: the\n * alternative is five hundred ids in a query string, and every proxy in\n * between has its own limit on how long a URL may be.\n */\n async removeMemories(\n id: string,\n memoryIds: readonly string[],\n options?: RequestOptions\n ): Promise<{ removed: number }> {\n return this.#http.delete<{ removed: number }>(\n `/api/v1/spaces/${encodeURIComponent(id)}/memories`,\n { memoryIds },\n options\n );\n }\n\n /* ----------------------- who else can see it ----------------------- */\n\n /**\n * Who can see this Space, including invitations nobody has accepted.\n *\n * A DIFFERENT EDGE from `memories()` next door, and the difference is worth\n * holding on to: that one maps a MEMORY to a Space, this one maps a PERSON\n * to a Space. The server keeps them in two tables with two names for exactly\n * that reason.\n *\n * Read `acceptedAt` before you render a row. An invitation grants nothing\n * until it is accepted, so a list that draws invited and accepted people the\n * same way tells its user somebody is reading their memories when nobody is.\n *\n * Paginated like every other list here. A Space has a handful of\n * collaborators rather than thousands, so this will usually be one page -\n * which costs a caller nothing and means the shape does not change if a\n * Space ever has an organisation on it.\n */\n collaborators(\n id: string,\n params: { readonly limit?: number } = {},\n options?: RequestOptions\n ): Paginated<SpaceCollaborator> {\n return new Paginated<SpaceCollaborator>((cursor) =>\n this.#http.get<Page<SpaceCollaborator>>(\n `/api/v1/sharing/spaces/${encodeURIComponent(id)}/collaborators`,\n {\n ...(params.limit !== undefined ? { limit: params.limit } : {}),\n ...(cursor !== undefined ? { cursor } : {})\n },\n options\n )\n );\n }\n\n /**\n * Offers somebody sight of a Space. Answers with the invitation.\n *\n * AN OFFER, NOT A GRANT, and the returned `acceptedAt` will be absent to\n * prove it. The recipient has to accept before they can see anything, which\n * is the property that keeps \"nothing enters your memory without you\" true\n * even when somebody else starts the sharing. Do not tell your user their\n * Space \"has been shared\" on the strength of a 2xx here.\n *\n * WHAT THEY GET IS THE WHOLE SPACE: every memory already filed in it and\n * every memory that lands in it afterwards. There is no narrower grant, and\n * `role` does not make one - it decides what they may do BESIDES read.\n *\n * Worth an idempotency key when a person is behind it. A double-clicked\n * \"share\" is two invitations to the same address, and the second one is a\n * second email arriving at somebody who has already been asked.\n */\n async share(\n id: string,\n params: ShareSpaceParams,\n options?: RequestOptions\n ): Promise<SpaceCollaborator> {\n return this.#http.post<SpaceCollaborator>(\n `/api/v1/sharing/spaces/${encodeURIComponent(id)}/collaborators`,\n params,\n options\n );\n }\n\n /**\n * Ends somebody's access, or withdraws an invitation they never accepted.\n *\n * Nothing was ever copied into their account - a collaborator SEES the\n * owner's memories rather than holding a duplicate - so this is one write\n * and not a cascade, and there is no orphaned copy left behind.\n *\n * A body on a DELETE, matching `removeMemories` above. The alternative is an\n * address in a path segment, where every `.`, `+` and `@` is a chance for a\n * proxy or a router to normalise somebody else's email into the one that\n * gets revoked.\n */\n async unshare(\n id: string,\n email: string,\n options?: RequestOptions\n ): Promise<{ email: string }> {\n return this.#http.delete<{ email: string }>(\n `/api/v1/sharing/spaces/${encodeURIComponent(id)}/collaborators`,\n { email },\n options\n );\n }\n\n /**\n * Changes what an existing collaborator may do. Never invites anybody.\n *\n * The quiet one. Moving somebody from `viewer` to `owner` sends no\n * invitation and needs no acceptance, and afterwards they can share the\n * Space onward and revoke the person who promoted them. Show your user what\n * `owner` means before you send this, not after.\n */\n async setRole(\n id: string,\n params: { readonly email: string; readonly role: GrantableSpaceRole },\n options?: RequestOptions\n ): Promise<SpaceCollaborator> {\n return this.#http.patch<SpaceCollaborator>(\n `/api/v1/sharing/spaces/${encodeURIComponent(id)}/collaborators`,\n params,\n options\n );\n }\n}\n", "import type { HttpClient, QueryParams, RequestOptions } from \"../http\";\nimport { Paginated } from \"../pagination\";\nimport { pageQuery } from \"../query\";\nimport type {\n Document,\n Job,\n ListDocumentsParams,\n ListJobsParams,\n ListSourcesParams,\n Page,\n Source\n} from \"../types\";\n\n/**\n * Where material came from, what it became, and the work in between.\n *\n * Three resources rather than one because they answer three questions a caller\n * asks separately: a source is an ORIGIN, a document is the normalised form\n * that was kept, and a job is the work that is still running. Collapsing them\n * would make \"nothing has appeared yet\" indistinguishable from \"it silently\n * failed\", which is the whole reason jobs are visible at all.\n */\nexport class Sources {\n readonly #http: HttpClient;\n\n constructor(http: HttpClient) {\n this.#http = http;\n }\n\n list(params: ListSourcesParams = {}, options?: RequestOptions): Paginated<Source> {\n return new Paginated<Source>((cursor) =>\n this.#http.get<Page<Source>>(\n \"/api/v1/sources\",\n pageQuery(params, cursor, {\n ...(params.provider !== undefined ? { provider: params.provider } : {})\n }),\n options\n )\n );\n }\n\n async get(id: string, options?: RequestOptions): Promise<Source> {\n return this.#http.get<Source>(`/api/v1/sources/${encodeURIComponent(id)}`, undefined, options);\n }\n}\n\nexport class Documents {\n readonly #http: HttpClient;\n\n constructor(http: HttpClient) {\n this.#http = http;\n }\n\n list(params: ListDocumentsParams = {}, options?: RequestOptions): Paginated<Document> {\n return new Paginated<Document>((cursor) =>\n this.#http.get<Page<Document>>(\n \"/api/v1/documents\",\n pageQuery(params, cursor, {\n ...(params.sourceId !== undefined ? { sourceId: params.sourceId } : {}),\n ...(params.status !== undefined ? { status: params.status } : {})\n }),\n options\n )\n );\n }\n\n async get(id: string, options?: RequestOptions): Promise<Document> {\n return this.#http.get<Document>(\n `/api/v1/documents/${encodeURIComponent(id)}`,\n undefined,\n options\n );\n }\n}\n\nexport class Jobs {\n readonly #http: HttpClient;\n\n constructor(http: HttpClient) {\n this.#http = http;\n }\n\n list(params: ListJobsParams = {}, options?: RequestOptions): Paginated<Job> {\n return new Paginated<Job>((cursor) =>\n this.#http.get<Page<Job>>(\n \"/api/v1/jobs\",\n pageQuery(params, cursor, {\n ...(params.status !== undefined ? { status: params.status } : {}),\n ...(params.type !== undefined ? { type: params.type } : {})\n }),\n options\n )\n );\n }\n\n /**\n * One job, by id. This is what `remember` hands back a reference to.\n *\n * `completed` is the terminal success state - the store's own word, not\n * `succeeded`. A caller polling for a state the API never writes waits\n * forever with nothing to show why.\n */\n async get(id: string, options?: RequestOptions): Promise<Job> {\n return this.#http.get<Job>(`/api/v1/jobs/${encodeURIComponent(id)}`, undefined, options);\n }\n}\n", "import type { HttpClient, RequestOptions } from \"../http\";\nimport { Paginated } from \"../pagination\";\nimport { pageQuery } from \"../query\";\nimport type {\n Conflict,\n Entity,\n EntityMemoriesParams,\n EntityMention,\n GraphResponse,\n ListConflictsParams,\n ListEntitiesParams,\n Page,\n ResolveConflictParams,\n TraverseParams\n} from \"../types\";\n\n/**\n * The people, places and things memories are about.\n *\n * Entities are RESOLVED rather than stored as strings: \"Sam\", \"Sam Patel\" and\n * \"sam@work.com\" are one person, and a system that treats them as three cannot\n * answer \"what do I know about Sam\" - the most obvious question anyone asks a\n * memory system.\n */\nexport class Entities {\n readonly #http: HttpClient;\n\n constructor(http: HttpClient) {\n this.#http = http;\n }\n\n list(params: ListEntitiesParams = {}, options?: RequestOptions): Paginated<Entity> {\n return new Paginated<Entity>((cursor) =>\n this.#http.get<Page<Entity>>(\n \"/api/v1/entities\",\n pageQuery(params, cursor, {\n ...(params.type !== undefined ? { type: params.type } : {}),\n ...(params.q !== undefined ? { q: params.q } : {})\n }),\n options\n )\n );\n }\n\n async get(id: string, options?: RequestOptions): Promise<Entity> {\n return this.#http.get<Entity>(`/api/v1/entities/${encodeURIComponent(id)}`, undefined, options);\n }\n\n /**\n * Which memories mention this entity, and how.\n *\n * Returns MENTIONS - a memory id, a role and a confidence - not the memories\n * themselves. \"Memories about Sam\" and \"memories Sam appears in\" are\n * different questions, and `role` is what separates them.\n *\n * Like the Space membership list, this endpoint answers with a `pagination`\n * block that carries no cursor, so it yields one page and stops.\n */\n memories(\n id: string,\n params: EntityMemoriesParams = {},\n options?: RequestOptions\n ): Paginated<EntityMention> {\n return new Paginated<EntityMention>((cursor) =>\n this.#http.get<Page<EntityMention>>(\n `/api/v1/entities/${encodeURIComponent(id)}/memories`,\n pageQuery(params, cursor, {\n ...(params.role !== undefined ? { role: params.role } : {}),\n ...(params.minConfidence !== undefined ? { minConfidence: params.minConfidence } : {})\n }),\n options\n )\n );\n }\n}\n\n/**\n * Walking the graph out from an entity.\n *\n * Every bound has a server-side ceiling, and that is the point: an unbounded\n * traversal on a well-connected graph visits everything, and the request that\n * does it is indistinguishable from a denial of service. Read `truncated` -\n * silence would read as \"this is the whole graph\", and a conclusion drawn from\n * a subset nobody knew was a subset is worse than no answer.\n */\nexport class Graph {\n readonly #http: HttpClient;\n\n constructor(http: HttpClient) {\n this.#http = http;\n }\n\n async traverse(params: TraverseParams, options?: RequestOptions): Promise<GraphResponse> {\n return this.#http.get<GraphResponse>(\n \"/api/v1/graph\",\n {\n from: params.from,\n ...(params.depth !== undefined ? { depth: params.depth } : {}),\n ...(params.maxNodes !== undefined ? { maxNodes: params.maxNodes } : {}),\n ...(params.memoryLimit !== undefined ? { memoryLimit: params.memoryLimit } : {})\n },\n options\n );\n }\n}\n\n/**\n * Two things the system believes that cannot both be true.\n *\n * Surfaced rather than settled silently, because the automatic answer is often\n * wrong: \"I moved to Berlin\" superseding \"I live in London\" is right, and \"the\n * deadline is Friday\" against \"the deadline is Monday\" is a question only the\n * user can answer.\n */\nexport class Conflicts {\n readonly #http: HttpClient;\n\n constructor(http: HttpClient) {\n this.#http = http;\n }\n\n list(params: ListConflictsParams = {}, options?: RequestOptions): Paginated<Conflict> {\n return new Paginated<Conflict>((cursor) =>\n this.#http.get<Page<Conflict>>(\n \"/api/v1/conflicts\",\n pageQuery(params, cursor, {\n ...(params.includeResolved !== undefined\n ? { includeResolved: params.includeResolved }\n : {}),\n ...(params.type !== undefined ? { type: params.type } : {})\n }),\n options\n )\n );\n }\n\n async get(id: string, options?: RequestOptions): Promise<Conflict> {\n return this.#http.get<Conflict>(\n `/api/v1/conflicts/${encodeURIComponent(id)}`,\n undefined,\n options\n );\n }\n\n /**\n * Settles one.\n *\n * `keep` names the winner and supersedes the loser; it does not delete it.\n * `dismiss` records that the detector was wrong, which is worth knowing when\n * the same pair trips it again.\n *\n * The parameter type is a union, so `keep` without a `keepId` does not\n * compile. The server rejects it too - this just moves the failure from a\n * 400 in production to a red squiggle.\n */\n async resolve(\n id: string,\n params: ResolveConflictParams,\n options?: RequestOptions\n ): Promise<{ status: string } & Record<string, unknown>> {\n return this.#http.post(\n `/api/v1/conflicts/${encodeURIComponent(id)}/resolve`,\n params,\n options\n );\n }\n}\n", "import type { HttpClient, RequestOptions } from \"../http\";\nimport { Paginated } from \"../pagination\";\nimport { pageQuery } from \"../query\";\nimport type {\n AppendMessagesParams,\n AppendMessagesResult,\n Conversation,\n CreateConversationParams,\n ListConversationsParams,\n Message,\n Page\n} from \"../types\";\n\n/**\n * A running exchange the system remembers across sessions.\n *\n * A conversation is both a SOURCE of memories and a place to spend them: turns\n * appended here go through the same extraction pipeline as `remember`, so they\n * get consolidation and entity resolution rather than a second, drifting path.\n */\nexport class Conversations {\n readonly #http: HttpClient;\n\n constructor(http: HttpClient) {\n this.#http = http;\n }\n\n list(\n params: ListConversationsParams = {},\n options?: RequestOptions\n ): Paginated<Conversation> {\n return new Paginated<Conversation>((cursor) =>\n this.#http.get<Page<Conversation>>(\n \"/api/v1/conversations\",\n pageQuery(params, cursor, {\n ...(params.channel !== undefined ? { channel: params.channel } : {})\n }),\n options\n )\n );\n }\n\n async get(id: string, options?: RequestOptions): Promise<Conversation> {\n return this.#http.get<Conversation>(\n `/api/v1/conversations/${encodeURIComponent(id)}`,\n undefined,\n options\n );\n }\n\n async create(\n params: CreateConversationParams = {},\n options?: RequestOptions\n ): Promise<Conversation> {\n return this.#http.post<Conversation>(\"/api/v1/conversations\", params, options);\n }\n\n messages(\n id: string,\n params: { readonly limit?: number; readonly cursor?: string } = {},\n options?: RequestOptions\n ): Paginated<Message> {\n return new Paginated<Message>((cursor) =>\n this.#http.get<Page<Message>>(\n `/api/v1/conversations/${encodeURIComponent(id)}/messages`,\n pageQuery(params, cursor, {}),\n options\n )\n );\n }\n\n /**\n * Appends turns, and by default extracts memories from them.\n *\n * Check `extracting` on the result. With no queue configured the turns are\n * stored and never become memory, and the API says so in `note` rather than\n * reporting a success - a caller that ignores it believes a memory is on its\n * way that never arrives.\n *\n * `system` and `tool` turns are stored but never extracted: a system prompt\n * is configuration, and remembering it would file our own instructions as\n * the user's facts.\n *\n * Give this an `idempotencyKey`. Appending the same turn twice is the most\n * likely duplicate in the whole API - a client reconnecting after a dropped\n * response has no other way to tell whether its last write landed.\n */\n async append(\n id: string,\n params: AppendMessagesParams,\n options?: RequestOptions\n ): Promise<AppendMessagesResult> {\n return this.#http.post<AppendMessagesResult>(\n `/api/v1/conversations/${encodeURIComponent(id)}/messages`,\n params,\n options\n );\n }\n}\n", "import type { HttpClient, RequestOptions } from \"../http\";\nimport type {\n DriveFile,\n MailMessage,\n MailSummary,\n Person,\n SaveToDriveParams,\n SearchDriveParams,\n SearchMailParams\n} from \"../types\";\n\n/**\n * A user's own Google, through this API rather than through Google.\n *\n * The distinction is the point. Google's tokens live encrypted on the server\n * and never reach a client, so an API key that leaks is an API key - not a\n * mailbox. Nothing here takes a Google credential, and nothing here ever will.\n *\n * Every method answers 409 when there is no connected account, or when Google\n * has stopped renewing one. Neither is a server fault and neither is fixed by\n * retrying: the user has to connect or reconnect at\n * persistmemory.com/dashboard/connect, and the error message says so.\n */\nexport class Google {\n readonly #http: HttpClient;\n\n constructor(http: HttpClient) {\n this.#http = http;\n }\n\n /** Files by name, newest first. Omit the query for recently changed ones. */\n async searchDrive(\n params: SearchDriveParams = {},\n options?: RequestOptions\n ): Promise<{ data: DriveFile[] }> {\n return this.#http.get<{ data: DriveFile[] }>(\n \"/api/v1/google/drive/files\",\n {\n ...(params.query !== undefined ? { query: params.query } : {}),\n ...(params.limit !== undefined ? { limit: params.limit } : {})\n },\n options\n );\n }\n\n async getDriveFile(fileId: string, options?: RequestOptions): Promise<DriveFile> {\n return this.#http.get<DriveFile>(\n `/api/v1/google/drive/files/${encodeURIComponent(fileId)}`,\n undefined,\n options\n );\n }\n\n /**\n * The bytes of a Drive file.\n *\n * A Google Doc, Sheet or Slide holds no bytes of its own and is exported on\n * the way - a document as PDF, a spreadsheet as CSV - so `filename` comes\n * back describing what it BECAME. Writing it under the id instead produces a\n * file nothing will open.\n */\n async downloadDriveFile(\n fileId: string,\n options?: RequestOptions\n ): Promise<{ bytes: Uint8Array; contentType: string; filename?: string }> {\n return this.#http.getBytes(\n `/api/v1/google/drive/files/${encodeURIComponent(fileId)}/content`,\n undefined,\n options\n );\n }\n\n /**\n * Writes a file into the user's Drive.\n *\n * Needs one of the Drive write permissions on their connection. A read-only\n * grant is refused by Google, and the error names the missing permission\n * rather than reporting a failed upload - one is fixed with a checkbox and\n * the other sends somebody looking for a bug.\n */\n async saveToDrive(\n params: SaveToDriveParams,\n options?: RequestOptions\n ): Promise<DriveFile> {\n return this.#http.postBytes<DriveFile>(\n \"/api/v1/google/drive/files\",\n params.bytes,\n params.contentType ?? \"application/octet-stream\",\n {\n name: params.name,\n ...(params.folderId !== undefined ? { folderId: params.folderId } : {})\n },\n options\n );\n }\n\n /**\n * Recent messages - senders, subjects and a one-line preview, never bodies.\n *\n * `query` is Gmail's own syntax passed through as written: `from:priya`,\n * `has:attachment`, `newer_than:7d`. It selects within the connected mailbox\n * and cannot reach another one.\n */\n async searchMail(\n params: SearchMailParams = {},\n options?: RequestOptions\n ): Promise<{ data: MailSummary[] }> {\n return this.#http.get<{ data: MailSummary[] }>(\n \"/api/v1/google/mail\",\n {\n ...(params.query !== undefined ? { query: params.query } : {}),\n ...(params.limit !== undefined ? { limit: params.limit } : {})\n },\n options\n );\n }\n\n /** One message, with its body and the names of what is attached. */\n async readMail(messageId: string, options?: RequestOptions): Promise<MailMessage> {\n return this.#http.get<MailMessage>(\n `/api/v1/google/mail/${encodeURIComponent(messageId)}`,\n undefined,\n options\n );\n }\n\n /**\n * The bytes of one attachment.\n *\n * Separate from `readMail` so listing a mailbox never drags attachments\n * across the network: a message with a 40 MB deck should not cost 40 MB to\n * summarise.\n */\n async downloadAttachment(\n messageId: string,\n attachmentId: string,\n options?: RequestOptions\n ): Promise<{ bytes: Uint8Array; contentType: string }> {\n return this.#http.getBytes(\n `/api/v1/google/mail/${encodeURIComponent(messageId)}/attachments/${encodeURIComponent(attachmentId)}`,\n undefined,\n options\n );\n }\n\n /** Sends as the connected account. Needs the send permission. */\n async sendMail(\n params: { to: string; subject: string; body: string; replyToMessageId?: string },\n options?: RequestOptions\n ): Promise<{ id: string }> {\n return this.#http.post<{ id: string }>(\"/api/v1/google/mail/send\", params, options);\n }\n\n /** People in the user's contacts. Omit the query to list them. */\n async contacts(\n params: { query?: string; limit?: number } = {},\n options?: RequestOptions\n ): Promise<{ data: Person[] }> {\n return this.#http.get<{ data: Person[] }>(\n \"/api/v1/google/contacts\",\n {\n ...(params.query !== undefined ? { query: params.query } : {}),\n ...(params.limit !== undefined ? { limit: params.limit } : {})\n },\n options\n );\n }\n}\n", "import type { HttpClient, RequestOptions } from \"../http\";\nimport { Paginated } from \"../pagination\";\nimport { pageQuery } from \"../query\";\nimport type {\n ConnectIntegrationParams,\n ConnectIntegrationResult,\n Integration,\n ListIntegrationsParams,\n Page,\n UpdateIntegrationParams\n} from \"../types\";\n\n/**\n * Live connections to somewhere material comes from.\n *\n * What is deliberately absent from every response: the access token, the\n * refresh token, and anything else that would let a caller act as the user on\n * the far side. They are held encrypted and never leave the server, so one\n * leaked API key does not become access to the user's Drive.\n *\n * `connect` returns a URL to send the user to. It does not take third-party\n * credentials, and no method here ever will - an endpoint that accepted a\n * password for another service would train users to hand them over, which is\n * the habit every phishing attack relies on.\n */\nexport class Integrations {\n readonly #http: HttpClient;\n\n constructor(http: HttpClient) {\n this.#http = http;\n }\n\n list(params: ListIntegrationsParams = {}, options?: RequestOptions): Paginated<Integration> {\n return new Paginated<Integration>((cursor) =>\n this.#http.get<Page<Integration>>(\n \"/api/v1/integrations\",\n pageQuery(params, cursor, {\n ...(params.provider !== undefined ? { provider: params.provider } : {}),\n ...(params.status !== undefined ? { status: params.status } : {})\n }),\n options\n )\n );\n }\n\n /** Providers that can be connected at all. Not the user's own connections. */\n async available(options?: RequestOptions): Promise<unknown> {\n return this.#http.get<unknown>(\"/api/v1/integrations/available\", undefined, options);\n }\n\n async get(id: string, options?: RequestOptions): Promise<Integration> {\n return this.#http.get<Integration>(\n `/api/v1/integrations/${encodeURIComponent(id)}`,\n undefined,\n options\n );\n }\n\n async connect(\n params: ConnectIntegrationParams,\n options?: RequestOptions\n ): Promise<ConnectIntegrationResult> {\n return this.#http.post<ConnectIntegrationResult>(\n \"/api/v1/integrations/connect\",\n params,\n options\n );\n }\n\n async update(\n id: string,\n params: UpdateIntegrationParams,\n options?: RequestOptions\n ): Promise<Integration> {\n return this.#http.patch<Integration>(\n `/api/v1/integrations/${encodeURIComponent(id)}`,\n params,\n options\n );\n }\n\n /**\n * Asks for a sync now rather than waiting for the schedule. Answers 202.\n *\n * `full` re-reads everything and is deliberately opt-in: on a large Drive\n * that is thousands of documents and a real bill. The incremental default is\n * what should run almost always.\n */\n async sync(\n id: string,\n params: { readonly full?: boolean } = {},\n options?: RequestOptions\n ): Promise<{ status: string; full: boolean }> {\n return this.#http.post<{ status: string; full: boolean }>(\n `/api/v1/integrations/${encodeURIComponent(id)}/sync`,\n params,\n options\n );\n }\n\n /**\n * Destroys the credentials. The row stays.\n *\n * History still has to attribute the memories this connection produced, and\n * deleting the row would leave them pointing at nothing.\n */\n async disconnect(id: string, options?: RequestOptions): Promise<{ status: string }> {\n return this.#http.delete<{ status: string }>(\n `/api/v1/integrations/${encodeURIComponent(id)}`,\n undefined,\n options\n );\n }\n}\n", "import type { HttpClient, RequestOptions } from \"../http\";\nimport type { HealthResponse } from \"../types\";\n\n/**\n * Is it up, and is it ready.\n *\n * Two endpoints because they answer different questions and a load balancer\n * needs both: `live` says the process is running, `ready` says it can serve.\n * Answering `ready` from a liveness probe restarts a healthy process that was\n * merely waiting on a dependency.\n *\n * Neither is under `/api/v1`, and neither needs the key - but the key is sent\n * anyway, because a client that builds a second, credential-free request path\n * has a second path that can be wrong.\n */\nexport class Health {\n readonly #http: HttpClient;\n\n constructor(http: HttpClient) {\n this.#http = http;\n }\n\n async live(options?: RequestOptions): Promise<HealthResponse> {\n return this.#http.get<HealthResponse>(\"/health/live\", undefined, options);\n }\n\n async ready(options?: RequestOptions): Promise<HealthResponse> {\n return this.#http.get<HealthResponse>(\"/health/ready\", undefined, options);\n }\n}\n", "import type { HttpClient, RequestOptions } from \"../http\";\nimport type { AgentDownloadLink, AgentRequest } from \"../types\";\n\n/**\n * Files fetched from the caller's own machine.\n *\n * A request is asked for on one surface, approved by a person, carried out by\n * an agent on their laptop, and finishes with the bytes in storage. Everything\n * up to that point was already visible through the API; `downloadLink` is what\n * makes the result retrievable rather than merely describable.\n */\nexport class Agent {\n readonly #http: HttpClient;\n\n constructor(http: HttpClient) {\n this.#http = http;\n }\n\n /** The row, including whether it finished and how large the result is. */\n async request(id: string, options?: RequestOptions): Promise<AgentRequest> {\n return this.#http.get<AgentRequest>(\n `/api/v1/agent/request/${encodeURIComponent(id)}`,\n undefined,\n options\n );\n }\n\n /**\n * A short-lived link to the bytes of a finished request.\n *\n * Returns the URL rather than the file, and that is a deliberate limit of\n * this package rather than an oversight. The transport under every other\n * method parses JSON, retries, and attaches the API key; none of those is\n * right for a hundred-megabyte binary body, and building a second request\n * path inside the SDK to serve one method is how a client ends up with two\n * retry policies that differ only during an outage. Fetch the URL with\n * whatever already streams in your runtime - it needs no credential, which\n * is the whole reason it is signed.\n *\n * Treat the URL as the file. It is a bearer credential for exactly one\n * object, it expires in minutes, and it should not be logged or stored.\n */\n async downloadLink(id: string, options?: RequestOptions): Promise<AgentDownloadLink> {\n return this.#http.get<AgentDownloadLink>(\n `/api/v1/agent/request/${encodeURIComponent(id)}/download`,\n undefined,\n options\n );\n }\n}\n", "import type { ClientOptions, RequestOptions } from \"./http\";\nimport { HttpClient } from \"./http\";\nimport { Memories } from \"./resources/memories\";\nimport { Search } from \"./resources/search\";\nimport { Spaces } from \"./resources/spaces\";\nimport { Documents, Jobs, Sources } from \"./resources/ingestion\";\nimport { Conflicts, Entities, Graph } from \"./resources/knowledge\";\nimport { Conversations } from \"./resources/conversations\";\nimport { Google } from \"./resources/google\";\nimport { Integrations } from \"./resources/integrations\";\nimport { Health } from \"./resources/health\";\nimport { Agent } from \"./resources/agent\";\n\n/**\n * The client.\n *\n * const client = new PersistMemory({ apiKey: process.env.PERSISTMEMORY_API_KEY! });\n * const found = await client.search.query({ query: \"what did we decide about Postgres\" });\n *\n * One transport underneath every resource, so retries, timeouts, error mapping\n * and the credential are decided once. Resources are plain objects hanging off\n * this one; they hold a reference to the transport and no state of their own,\n * which is what makes a client safe to share across a process.\n */\nexport class PersistMemory {\n readonly memories: Memories;\n readonly search: Search;\n readonly spaces: Spaces;\n readonly sources: Sources;\n readonly documents: Documents;\n readonly jobs: Jobs;\n readonly entities: Entities;\n readonly graph: Graph;\n readonly conflicts: Conflicts;\n readonly conversations: Conversations;\n readonly integrations: Integrations;\n /** Drive, mail and contacts on the user's connected Google account. */\n readonly google: Google;\n readonly health: Health;\n readonly agent: Agent;\n\n readonly #http: HttpClient;\n\n constructor(options: ClientOptions) {\n this.#http = new HttpClient(options);\n\n this.memories = new Memories(this.#http);\n this.search = new Search(this.#http);\n this.spaces = new Spaces(this.#http);\n this.sources = new Sources(this.#http);\n this.documents = new Documents(this.#http);\n this.jobs = new Jobs(this.#http);\n this.entities = new Entities(this.#http);\n this.graph = new Graph(this.#http);\n this.conflicts = new Conflicts(this.#http);\n this.conversations = new Conversations(this.#http);\n this.integrations = new Integrations(this.#http);\n this.google = new Google(this.#http);\n this.health = new Health(this.#http);\n this.agent = new Agent(this.#http);\n }\n\n /**\n * An escape hatch for an endpoint this package has not caught up with.\n *\n * Typed as `unknown` on purpose: a caller reaching past the typed surface is\n * taking responsibility for the shape, and handing them `any` would let that\n * responsibility spread silently through their codebase.\n */\n async request<T = unknown>(\n method: \"GET\" | \"POST\" | \"PATCH\" | \"DELETE\",\n path: string,\n body?: unknown,\n options?: RequestOptions\n ): Promise<T> {\n if (method === \"GET\") return this.#http.get<T>(path, undefined, options);\n if (method === \"POST\") return this.#http.post<T>(path, body, options);\n if (method === \"PATCH\") return this.#http.patch<T>(path, body, options);\n return this.#http.delete<T>(path, body, options);\n }\n\n /** Never the key. See `HttpClient.toJSON`, which this delegates to. */\n toJSON(): Record<string, unknown> {\n return this.#http.toJSON();\n }\n\n [Symbol.for(\"nodejs.util.inspect.custom\")](): Record<string, unknown> {\n return this.#http.toJSON();\n }\n}\n"],
|
|
5
|
-
"mappings": "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",
|
|
4
|
+
"sourcesContent": ["/**\n * The official TypeScript client for the PersistMemory API.\n *\n * See the README for a quickstart. The three things worth knowing before you\n * read the types:\n *\n * remember is asynchronous it returns a job id, not a memory. Extraction\n * and consolidation run afterwards and may\n * produce one memory, several, or none.\n *\n * search degrades it falls back to deterministic retrieval when\n * embeddings are unavailable, and says so in\n * `diagnostics.degraded`. Read it.\n *\n * POSTs are not retried unless you pass an `idempotencyKey`. A POST\n * that timed out may already have been processed,\n * and this client will not guess.\n */\nexport { PersistMemory } from \"./client\";\nexport type { ClientOptions, RequestOptions } from \"./http\";\nexport type { BackoffOptions } from \"./backoff\";\nexport { backoffMs, delayFor, DEFAULT_BACKOFF } from \"./backoff\";\nexport { Paginated } from \"./pagination\";\n\nexport {\n PersistMemoryError,\n AuthenticationError,\n PermissionDeniedError,\n NotFoundError,\n ValidationError,\n ConflictError,\n RateLimitError,\n ServerError,\n ConnectionError,\n TimeoutError,\n AbortError\n} from \"./errors\";\nexport type { ErrorCode } from \"./errors\";\n\nexport type * from \"./types\";\n", "/**\n * Turning parameters into a query string the API's parser reads the way we mean.\n *\n * Its own module because both the request loop and every list resource need\n * it, and putting it in either one would have the other importing a transport\n * to build a string.\n */\n\nexport type QueryValue =\n | string\n | number\n | boolean\n | readonly string[]\n | readonly number[]\n | undefined;\n\nexport type QueryParams = Readonly<Record<string, QueryValue>>;\n\n/**\n * Builds a query string the API's parser will read the way we mean it.\n *\n * Arrays repeat the key - `?spaceIds=a&spaceIds=b` - because that is what\n * Express hands to the schemas, which accept either one value or a list.\n * Comma-joining would arrive as a single id containing a comma and match\n * nothing, with no error to say why.\n *\n * Booleans are sent as `true`/`false` strings. The API parses those\n * explicitly, because `Boolean(\"false\")` is `true` and a flag written that way\n * can never be turned off.\n */\nexport function encodeQuery(params?: QueryParams): string {\n if (!params) return \"\";\n\n const search = new URLSearchParams();\n for (const [key, value] of Object.entries(params)) {\n // Undefined is dropped, never sent. `?cursor=undefined` is a string the\n // server tries to decode, and the 400 it produces names the cursor rather\n // than the caller who forgot to omit it.\n if (value === undefined) continue;\n\n if (Array.isArray(value)) {\n for (const one of value as readonly (string | number)[]) search.append(key, String(one));\n continue;\n }\n search.append(key, String(value));\n }\n\n const encoded = search.toString();\n return encoded ? `?${encoded}` : \"\";\n}\n\n/**\n * The two parameters every list shares, plus whatever the endpoint adds.\n *\n * Shared because the cursor rule is subtle enough to get wrong once per\n * resource: the PAGINATOR's cursor wins over the caller's. The caller's seeds\n * the first page - resuming from a bookmark - and the paginator supplies every\n * page after that. Letting the caller's win would re-read the same page\n * forever, which looks like an account that never ends.\n */\nexport function pageQuery(\n params: { readonly limit?: number; readonly cursor?: string },\n cursor: string | undefined,\n extra: QueryParams\n): QueryParams {\n return {\n ...(params.limit !== undefined ? { limit: params.limit } : {}),\n ...(cursor !== undefined\n ? { cursor }\n : params.cursor !== undefined\n ? { cursor: params.cursor }\n : {}),\n ...extra\n };\n}\n", "/**\n * How long to wait before trying again.\n *\n * Exponential, capped, and jittered, for the reasons the rest of this repo\n * gives in `@persistmemory/async`:\n *\n * exponential a cause that has not cleared in 200ms may clear in two\n * seconds; hammering it every 200ms spends the attempts faster\n * without giving it time to recover.\n *\n * capped unbounded doubling reaches minutes, and a caller waiting\n * inside one function call cannot tell that from a hang.\n *\n * jittered the one that gets skipped, and the one that matters most. An\n * outage fails every in-flight request at once; without jitter\n * every client waits exactly two seconds and retries in the\n * same millisecond, so the recovering service is hit by the\n * whole fleet and knocked over again. The retry storm is caused\n * by the retry policy.\n *\n * Duplicated here rather than imported from `@persistmemory/async` on purpose:\n * this package is published to npm and installed by people who have no reason\n * to pull in a queue runtime, a Redis client and a dead-letter store to make\n * an HTTP request.\n */\nexport interface BackoffOptions {\n readonly baseMs?: number;\n readonly maxMs?: number;\n readonly factor?: number;\n /** 0 = none, 1 = full. Full is the right default; see below. */\n readonly jitter?: number;\n /** Injected so a test is not at the mercy of the random number generator. */\n readonly random?: () => number;\n}\n\n/**\n * Short by server standards.\n *\n * A queue worker can afford to come back in a minute. A caller is blocked\n * inside `await client.search(...)` and has a user watching, so the whole\n * retry budget has to fit inside a request timeout rather than outlast it.\n */\nexport const DEFAULT_BACKOFF = { baseMs: 250, maxMs: 8_000, factor: 2, jitter: 1 } as const;\n\n/**\n * The delay before attempt `attempt` (1-based).\n *\n * FULL jitter by default - a random point in [0, ceiling] rather than\n * ceiling plus or minus a wobble. It sounds worse and measures better:\n * partial jitter leaves the retries clustered around the same instant, which\n * is the thing that overwhelms a service coming back up.\n */\nexport function backoffMs(attempt: number, options: BackoffOptions = {}): number {\n const base = options.baseMs ?? DEFAULT_BACKOFF.baseMs;\n const max = options.maxMs ?? DEFAULT_BACKOFF.maxMs;\n const factor = options.factor ?? DEFAULT_BACKOFF.factor;\n const jitter = clamp01(options.jitter ?? DEFAULT_BACKOFF.jitter);\n const random = options.random ?? Math.random;\n\n // Clamped at 1: attempt 0 would give a negative exponent and a delay\n // shorter than the base, so the first retry would be the fastest one.\n const exponent = Math.max(0, Math.floor(attempt) - 1);\n // Capped BEFORE jitter. Capping after lets an un-jittered value of minutes\n // be scaled down to something that looks reasonable while the underlying\n // growth is still unbounded.\n const ceiling = Math.min(max, base * Math.pow(factor, exponent));\n\n if (jitter <= 0) return Math.round(ceiling);\n\n const fixed = ceiling * (1 - jitter);\n return Math.round(fixed + random() * (ceiling - fixed));\n}\n\n/**\n * The delay to actually use, honouring what the server asked for.\n *\n * `Retry-After` is taken as a FLOOR, not verbatim. Verbatim would let a\n * one-second hint on the fifth consecutive 429 undo the backoff entirely and\n * put us straight back into the limit; ignoring it would have us retry before\n * the window resets and spend an attempt learning what we were already told.\n *\n * A server asking for LONGER than our cap is believed. The cap exists to stop\n * our own growth running away, not to overrule a service that has told us\n * when it will be ready.\n */\nexport function delayFor(args: {\n attempt: number;\n retryAfterSeconds?: number;\n options?: BackoffOptions;\n}): number {\n const computed = backoffMs(args.attempt, args.options ?? {});\n if (args.retryAfterSeconds === undefined || !Number.isFinite(args.retryAfterSeconds)) {\n return computed;\n }\n return Math.max(computed, Math.max(0, args.retryAfterSeconds) * 1000);\n}\n\nfunction clamp01(value: number): number {\n if (!Number.isFinite(value)) return 0;\n return Math.min(1, Math.max(0, value));\n}\n", "/**\n * What went wrong, in a shape a caller can branch on.\n *\n * One class per thing a caller can DO about it, which is not the same as one\n * class per status code. `RateLimited` says wait, `Validation` says fix the\n * request, `NotFound` says the id is wrong or gone, `Conflict` says re-read\n * and try again. A code nobody branches on is a string that only looks like an\n * API, so 402 and 418 and anything else unmapped land on the base class rather\n * than growing a name each.\n *\n * The API's own error envelope is\n *\n * { error: { code, message, fields?, requestId } }\n *\n * and `code` is the stable part. Branch on the class or on `code`, never on\n * `message`: messages get rewritten for clarity, translated, and deliberately\n * made vaguer for security, and a client keyed to message text breaks silently\n * when any of that happens.\n *\n * NOTHING in here ever holds the API key. Errors are logged, serialised into\n * bug reports and posted into issue trackers, which is exactly how a\n * credential escapes - see `redact` at the bottom of this file, which every\n * message this module builds passes through.\n */\n\n/** The stable codes the API returns. Unknown strings are possible; see below. */\nexport type ErrorCode =\n | \"VALIDATION_ERROR\"\n | \"UNAUTHORIZED\"\n | \"FORBIDDEN\"\n | \"NOT_FOUND\"\n | \"CONFLICT\"\n | \"IDEMPOTENCY_MISMATCH\"\n | \"RATE_LIMITED\"\n | \"PAYLOAD_TOO_LARGE\"\n | \"DEPENDENCY_UNAVAILABLE\"\n | \"PROCESSING_FAILED\"\n | \"INTERNAL_ERROR\"\n // Widened on purpose. A server that adds a code should not make an older\n // SDK throw a TypeError while parsing the error that explains the problem.\n | (string & {});\n\nexport interface ApiErrorInit {\n readonly status: number;\n readonly code: ErrorCode;\n readonly message: string;\n /** Which fields were rejected, for a validation failure. */\n readonly fields?: Readonly<Record<string, string>>;\n /** Ties this failure to the server's log lines. Quote it in support. */\n readonly requestId?: string;\n /** Seconds the server asked us to wait, when it said. */\n readonly retryAfterSeconds?: number;\n}\n\n/**\n * The base every failure from this SDK inherits from.\n *\n * `retryable` is the single question the request loop asks. It lives on the\n * error rather than in a table beside it because the two drift: a table says\n * 429 is retryable while the error that reaches the loop is a transport\n * failure nobody thought to add.\n */\nexport class PersistMemoryError extends Error {\n readonly status: number;\n readonly code: ErrorCode;\n readonly fields?: Readonly<Record<string, string>>;\n readonly requestId?: string;\n readonly retryAfterSeconds?: number;\n /** Retrying this exact request could plausibly succeed. */\n readonly retryable: boolean = false;\n\n constructor(init: ApiErrorInit) {\n super(redact(init.message));\n this.name = new.target.name;\n this.status = init.status;\n this.code = init.code;\n if (init.fields) this.fields = init.fields;\n if (init.requestId) this.requestId = init.requestId;\n if (init.retryAfterSeconds !== undefined) this.retryAfterSeconds = init.retryAfterSeconds;\n }\n\n /**\n * A one-line summary safe to log.\n *\n * Provided so callers reach for this instead of `JSON.stringify(error)`,\n * which walks own properties and would pick up anything a future field\n * holds. Everything here is already server-supplied and key-free.\n */\n override toString(): string {\n const id = this.requestId ? ` requestId=${this.requestId}` : \"\";\n return `${this.name}: [${this.status} ${this.code}] ${this.message}${id}`;\n }\n}\n\n/** 401. The key is missing, malformed, revoked, or the session expired. */\nexport class AuthenticationError extends PersistMemoryError {}\n\n/**\n * 403. Known caller, and this credential will never be enough.\n *\n * Distinct from `AuthenticationError` because the fix is different: 401 means\n * present a credential, 403 means this key's scopes are wrong and no amount of\n * retrying or re-signing will change it. A read-only key calling `remember`\n * lands here.\n */\nexport class PermissionDeniedError extends PersistMemoryError {}\n\n/** 404. Does not exist, or is not yours - the API answers both the same way. */\nexport class NotFoundError extends PersistMemoryError {}\n\n/** 400 and 422. The request was wrong; `fields` says where. */\nexport class ValidationError extends PersistMemoryError {}\n\n/** 409. Something changed underneath. Re-read, then try again. */\nexport class ConflictError extends PersistMemoryError {}\n\n/**\n * 429. Slow down.\n *\n * `retryAfterSeconds` comes from the `Retry-After` header, which the API\n * always sets on a 429. It is not advice - it is the only number that knows\n * when the window resets, and computing our own backoff instead means being\n * refused again and spending an attempt to learn what we were already told.\n */\nexport class RateLimitError extends PersistMemoryError {\n override readonly retryable = true;\n}\n\n/**\n * 5xx. Ours, not yours.\n *\n * Retryable, because a 500 or a 503 is usually a dependency that has fallen\n * over and will come back - and the alternative, giving up on the first one,\n * turns a three-second blip into a failed job. Retryable does not mean\n * REPEATED: a POST still needs an idempotency key before this client will send\n * it again, because a 500 may have been raised after the work was done.\n */\nexport class ServerError extends PersistMemoryError {\n override readonly retryable = true;\n}\n\n/**\n * The request never got an answer: DNS, connect, reset, or a body that died\n * mid-stream.\n *\n * Status 0, because there was no status. Retryable in general - but see\n * `isRetryable` in `client.ts`, which refuses to retry a POST that may already\n * have been processed, since a connection dying after the server accepted the\n * request looks identical from here.\n */\nexport class ConnectionError extends PersistMemoryError {\n override readonly retryable = true;\n\n constructor(message: string) {\n super({ status: 0, code: \"CONNECTION_ERROR\", message });\n }\n}\n\n/** The deadline passed. A distinct class because the fix is often a bigger one. */\nexport class TimeoutError extends PersistMemoryError {\n override readonly retryable = true;\n\n constructor(message: string) {\n super({ status: 0, code: \"TIMEOUT\", message });\n }\n}\n\n/**\n * The caller's own AbortSignal fired.\n *\n * NOT retryable, and not a timeout: someone asked for this to stop, and\n * retrying it is the one thing they have said they do not want.\n */\nexport class AbortError extends PersistMemoryError {\n constructor(message = \"The request was aborted by the caller.\") {\n super({ status: 0, code: \"ABORTED\", message });\n }\n}\n\ninterface ErrorEnvelope {\n readonly error?: {\n readonly code?: unknown;\n readonly message?: unknown;\n readonly fields?: unknown;\n readonly requestId?: unknown;\n };\n}\n\n/**\n * A response the server refused, turned into the right class.\n *\n * Keyed on the CODE first and the status second. The code is the API's own\n * vocabulary and is the more precise of the two - `IDEMPOTENCY_MISMATCH` is a\n * 422 that means \"you reused a key with a different body\", which is a\n * validation problem and not a generic unprocessable entity.\n *\n * The body is parsed defensively at every step. A 502 from a proxy in front of\n * the API returns HTML, and an SDK that assumes JSON turns a bad gateway into\n * an unhelpful SyntaxError thrown from inside the error handler.\n */\nexport function errorFromResponse(\n status: number,\n body: unknown,\n headers: { get(name: string): string | null }\n): PersistMemoryError {\n const envelope = (body ?? {}) as ErrorEnvelope;\n const code = typeof envelope.error?.code === \"string\" ? envelope.error.code : codeForStatus(status);\n const message =\n typeof envelope.error?.message === \"string\" && envelope.error.message.length > 0\n ? envelope.error.message\n : defaultMessage(status);\n\n // Read for 429 and 503 alike. A 503 with a `Retry-After` is a service\n // telling us when it will be back, and ignoring it because the status was\n // not 429 means retrying into an outage that has said it is not over.\n const retryAfterSeconds =\n status === 429 || status === 503 ? retryAfterOf(headers) : undefined;\n\n const init: ApiErrorInit = {\n status,\n code,\n message,\n ...(isFieldMap(envelope.error?.fields) ? { fields: envelope.error.fields } : {}),\n ...(typeof envelope.error?.requestId === \"string\"\n ? { requestId: envelope.error.requestId }\n : {}),\n ...(retryAfterSeconds !== undefined ? { retryAfterSeconds } : {})\n };\n\n if (status === 429 || code === \"RATE_LIMITED\") return new RateLimitError(init);\n if (status === 401 || code === \"UNAUTHORIZED\") return new AuthenticationError(init);\n if (status === 403 || code === \"FORBIDDEN\") return new PermissionDeniedError(init);\n if (status === 404 || code === \"NOT_FOUND\") return new NotFoundError(init);\n if (status === 409 || code === \"CONFLICT\") return new ConflictError(init);\n if (status === 400 || status === 413 || status === 422) return new ValidationError(init);\n if (status >= 500) return new ServerError(init);\n\n // Anything else - a 405 from a misconfigured proxy, a 402 the API grows\n // later. Named honestly rather than forced into the nearest class, because\n // a caller catching `ValidationError` should not be handed a payment\n // problem.\n return new PersistMemoryError(init);\n}\n\n/**\n * `Retry-After`, in seconds, when the header is one we can trust.\n *\n * Only the delta-seconds form is honoured. The HTTP-date form is also legal\n * and is parsed against the CLIENT's clock, which on a laptop that has been\n * asleep can be minutes out - and a negative delay computed from a skewed\n * clock is a retry storm aimed at a service that just asked for quiet.\n */\nfunction retryAfterOf(headers: { get(name: string): string | null }): number | undefined {\n const raw = headers.get(\"retry-after\");\n if (!raw) return undefined;\n\n const seconds = Number(raw.trim());\n if (!Number.isFinite(seconds) || seconds < 0) return undefined;\n // Capped. A header saying 86400 would otherwise park a caller's retry for a\n // day inside a call they expected to return.\n return Math.min(seconds, 300);\n}\n\nfunction isFieldMap(value: unknown): value is Record<string, string> {\n if (typeof value !== \"object\" || value === null || Array.isArray(value)) return false;\n return Object.values(value).every((one) => typeof one === \"string\");\n}\n\nfunction codeForStatus(status: number): ErrorCode {\n if (status === 401) return \"UNAUTHORIZED\";\n if (status === 403) return \"FORBIDDEN\";\n if (status === 404) return \"NOT_FOUND\";\n if (status === 409) return \"CONFLICT\";\n if (status === 429) return \"RATE_LIMITED\";\n if (status === 413) return \"PAYLOAD_TOO_LARGE\";\n if (status >= 500) return \"INTERNAL_ERROR\";\n return \"VALIDATION_ERROR\";\n}\n\nfunction defaultMessage(status: number): string {\n // Deliberately says the body was unreadable rather than inventing a reason.\n // A message claiming \"not found\" for a 404 that was actually an HTML error\n // page from a proxy sends whoever is debugging to the wrong system.\n return `The API returned ${status} with no readable error body.`;\n}\n\n/**\n * Removes anything key-shaped from a string bound for an error message.\n *\n * Every message this module produces goes through here, including the\n * server's own. It should never contain a key - we never send it in a body\n * and the API never echoes it - but \"should never\" is how credentials end up\n * in issue trackers. The cost is one regex on a path that has already failed.\n */\nexport function redact(text: string): string {\n return text.replace(/pm_(live|test)_[A-Za-z0-9_-]+/g, \"pm_$1_[redacted]\");\n}\n", "import type { BackoffOptions } from \"./backoff\";\nimport type { QueryParams } from \"./query\";\nimport { encodeQuery } from \"./query\";\nimport { delayFor } from \"./backoff\";\nimport {\n AbortError,\n ConnectionError,\n PersistMemoryError,\n TimeoutError,\n errorFromResponse,\n redact\n} from \"./errors\";\n\n/**\n * The one place a request is made, retried, timed out and turned into an error.\n *\n * Every resource in this package goes through `request`. That is deliberate:\n * an SDK where each resource calls `fetch` for itself is an SDK with six\n * slightly different retry policies, and the differences only show up during\n * an outage, which is the moment nobody wants to be reading six files.\n *\n * `fetch` is injected rather than imported. It is what makes a test of this\n * incapable of opening a socket by accident, and it is the same reason every\n * provider client in this repo takes one.\n */\nexport type { QueryParams, QueryValue } from \"./query\";\n\nexport interface ClientOptions {\n /**\n * A `pm_live_...` API key, or a session JWT.\n *\n * Held privately and never returned, logged, stringified or put in an error.\n * See `#apiKey` below and the `toJSON` next to it.\n */\n readonly apiKey: string;\n readonly baseUrl?: string;\n readonly fetch?: typeof globalThis.fetch;\n /**\n * Per-attempt deadline, not a budget for the whole call.\n *\n * Per attempt because a whole-call deadline interacts badly with backoff: a\n * request that spent nine seconds waiting between retries would get one\n * second to actually run, and the failure would look like a slow server.\n */\n readonly timeoutMs?: number;\n /** Attempts, not retries. 3 means the original and two more. */\n readonly maxAttempts?: number;\n readonly backoff?: BackoffOptions;\n /** Injected so tests do not spend real seconds asleep. */\n readonly sleep?: (ms: number, signal?: AbortSignal) => Promise<void>;\n /** Sent on every request, for support and for server-side triage. */\n readonly userAgent?: string;\n}\n\nexport interface RequestOptions {\n /** Cancels the call. A caller's abort is never retried - they asked it to stop. */\n readonly signal?: AbortSignal;\n readonly timeoutMs?: number;\n readonly maxAttempts?: number;\n /**\n * Makes a POST safe to retry.\n *\n * The API deduplicates on this header, so a retry after a timeout finds the\n * first result rather than doing the work twice. Without one, this client\n * will NOT retry a POST that may already have been processed - see\n * `mayRetry`.\n *\n * Give it meaning: `remember:note-42`, not a fresh random value per call. A\n * random one makes every retry a new request, which is exactly what it\n * exists to prevent.\n */\n readonly idempotencyKey?: string;\n}\n\ninterface InternalRequest {\n readonly method: \"GET\" | \"POST\" | \"PATCH\" | \"DELETE\";\n readonly path: string;\n readonly query?: QueryParams;\n readonly body?: unknown;\n /**\n * Bytes, for the endpoints that take a file.\n *\n * Separate from `body` rather than sniffed out of it: `JSON.stringify` of a\n * `Uint8Array` produces `{\"0\":137,\"1\":80,...}`, which is a valid request and\n * a corrupt file - and the failure shows up as \"this PDF is not a PDF\" a\n * long way from the line that caused it.\n */\n readonly rawBody?: Uint8Array;\n readonly contentType?: string;\n /** Bytes back, for a download. JSON is parsed; a file is not. */\n readonly rawResponse?: boolean;\n readonly options?: RequestOptions;\n}\n\nconst DEFAULT_BASE_URL = \"https://api.persistmemory.com\";\nconst DEFAULT_TIMEOUT_MS = 30_000;\nconst DEFAULT_MAX_ATTEMPTS = 3;\n\n/**\n * Methods this client will retry without being told it is safe to.\n *\n * PATCH and DELETE are in here because of what they are in THIS API and not\n * because the RFC calls them idempotent: `PATCH /spaces/{id}` sets named\n * fields to given values, and `DELETE /spaces/{id}/memories` removes a set of\n * memberships. Applying either twice lands in the same state as applying it\n * once. POST is the one that does not - `remember` queues a job every time.\n */\nconst RETRY_WITHOUT_ASKING = new Set([\"GET\", \"HEAD\", \"PATCH\", \"DELETE\"]);\n\nexport class HttpClient {\n /**\n * The credential, in a private field, and never anywhere else.\n *\n * Private (`#`) rather than `readonly`: a public field is enumerable, so\n * `JSON.stringify(client)` and every structured logger that walks own\n * properties would write the key into a log line. `toJSON` and the inspect\n * hook below close the two remaining paths - a bug report pasted from\n * `console.log(client)` is exactly how a key gets shared with strangers.\n */\n readonly #apiKey: string;\n readonly #baseUrl: string;\n readonly #fetch: typeof globalThis.fetch;\n readonly #timeoutMs: number;\n readonly #maxAttempts: number;\n readonly #backoff: BackoffOptions;\n readonly #sleep: (ms: number, signal?: AbortSignal) => Promise<void>;\n readonly #userAgent: string;\n\n constructor(options: ClientOptions) {\n if (typeof options.apiKey !== \"string\" || options.apiKey.trim().length === 0) {\n // Refused here rather than as a 401 from the server, because the server\n // cannot say WHICH of \"missing\", \"empty\" and \"undefined stringified\"\n // happened, and all three come from the same forgotten environment\n // variable.\n throw new PersistMemoryError({\n status: 0,\n code: \"VALIDATION_ERROR\",\n message: \"An API key is required. Pass `apiKey`, or set PERSISTMEMORY_API_KEY.\"\n });\n }\n\n // A newline in a credential is header injection, and the usual source is\n // a key read from a file with `readFileSync` and never trimmed. Trimmed\n // rather than rejected for whitespace, then checked for anything a header\n // value may not carry.\n const key = options.apiKey.trim();\n if (/[\\r\\n\\0]/.test(key)) {\n // The key itself is NOT in this message. It is the one string in the\n // whole package that must never reach an error.\n throw new PersistMemoryError({\n status: 0,\n code: \"VALIDATION_ERROR\",\n message: \"The API key contains characters that cannot go in a header.\"\n });\n }\n\n this.#apiKey = key;\n // Trailing slashes stripped once, here. Left alone, `baseUrl + path`\n // produces `//api/v1/...`, which some proxies normalise and some route to\n // a 404 - a difference that only appears in production.\n this.#baseUrl = (options.baseUrl ?? DEFAULT_BASE_URL).replace(/\\/+$/, \"\");\n this.#fetch = options.fetch ?? globalThis.fetch;\n this.#timeoutMs = options.timeoutMs ?? DEFAULT_TIMEOUT_MS;\n this.#maxAttempts = Math.max(1, options.maxAttempts ?? DEFAULT_MAX_ATTEMPTS);\n this.#backoff = options.backoff ?? {};\n this.#sleep = options.sleep ?? defaultSleep;\n this.#userAgent = options.userAgent ?? \"persistmemory-sdk-js/0.1.0\";\n }\n\n /**\n * What this object looks like when something serialises it.\n *\n * Both hooks return the same key-free shape. `toJSON` covers\n * `JSON.stringify`, the inspect symbol covers `console.log` under Node, and\n * between them they cover how a credential actually escapes: not through a\n * deliberate log line, but through an object dumped into a bug report.\n */\n toJSON(): Record<string, unknown> {\n return { baseUrl: this.#baseUrl, apiKey: \"[redacted]\" };\n }\n\n [Symbol.for(\"nodejs.util.inspect.custom\")](): Record<string, unknown> {\n return this.toJSON();\n }\n\n async get<T>(path: string, query?: QueryParams, options?: RequestOptions): Promise<T> {\n return this.#request<T>({\n method: \"GET\",\n path,\n ...(query ? { query } : {}),\n ...(options ? { options } : {})\n });\n }\n\n async post<T>(path: string, body?: unknown, options?: RequestOptions): Promise<T> {\n return this.#request<T>({\n method: \"POST\",\n path,\n ...(body !== undefined ? { body } : {}),\n ...(options ? { options } : {})\n });\n }\n\n /** POST with a file as the body. The type describes the bytes, not JSON. */\n async postBytes<T>(\n path: string,\n bytes: Uint8Array,\n contentType: string,\n query?: QueryParams,\n options?: RequestOptions\n ): Promise<T> {\n return this.#request<T>({\n method: \"POST\",\n path,\n rawBody: bytes,\n contentType,\n ...(query ? { query } : {}),\n ...(options ? { options } : {})\n });\n }\n\n /** GET that returns bytes rather than JSON, for downloading a file. */\n async getBytes(\n path: string,\n query?: QueryParams,\n options?: RequestOptions\n ): Promise<{ bytes: Uint8Array; contentType: string; filename?: string }> {\n return this.#request({\n method: \"GET\",\n path,\n rawResponse: true,\n ...(query ? { query } : {}),\n ...(options ? { options } : {})\n });\n }\n\n async patch<T>(path: string, body?: unknown, options?: RequestOptions): Promise<T> {\n return this.#request<T>({\n method: \"PATCH\",\n path,\n ...(body !== undefined ? { body } : {}),\n ...(options ? { options } : {})\n });\n }\n\n async delete<T>(path: string, body?: unknown, options?: RequestOptions): Promise<T> {\n return this.#request<T>({\n method: \"DELETE\",\n path,\n ...(body !== undefined ? { body } : {}),\n ...(options ? { options } : {})\n });\n }\n\n async #request<T>(request: InternalRequest): Promise<T> {\n const maxAttempts = Math.max(1, request.options?.maxAttempts ?? this.#maxAttempts);\n const url = this.#baseUrl + request.path + encodeQuery(request.query);\n\n let attempt = 0;\n // Unbounded `while` with the exit conditions inside, rather than a `for`\n // over attempts: every path out of here either returns or throws, and a\n // loop that can fall off the end would silently return undefined as `T`.\n for (;;) {\n attempt += 1;\n\n let error: PersistMemoryError;\n try {\n return await this.#attempt<T>(request, url);\n } catch (thrown) {\n // Anything that is not one of ours is a programming error in this\n // package - a bad URL, a body that will not serialise - and rethrowing\n // it unchanged is right. Wrapping it as a retryable transport failure\n // would make the request loop retry a defect that fails identically\n // every time.\n if (!(thrown instanceof PersistMemoryError)) throw thrown;\n error = thrown;\n }\n\n if (attempt >= maxAttempts) throw error;\n if (!mayRetry(error, request)) throw error;\n\n const delay = delayFor({\n attempt,\n ...(error.retryAfterSeconds !== undefined\n ? { retryAfterSeconds: error.retryAfterSeconds }\n : {}),\n options: this.#backoff\n });\n\n // The caller's signal is passed into the wait too. Without it an aborted\n // call still sits out its full backoff before noticing, which to a user\n // who pressed cancel is indistinguishable from the cancel not working.\n await this.#sleep(delay, request.options?.signal);\n }\n }\n\n async #attempt<T>(request: InternalRequest, url: string): Promise<T> {\n const timeoutMs = request.options?.timeoutMs ?? this.#timeoutMs;\n const deadline = new AbortController();\n const timer = setTimeout(() => deadline.abort(), timeoutMs);\n // Linked rather than AbortSignal.any: this package supports Node 18, where\n // `any` does not exist. The listener is removed in the `finally`, because\n // a long-lived caller signal that accumulated one listener per request is\n // a leak that only shows up under load.\n const onCallerAbort = () => deadline.abort();\n const caller = request.options?.signal;\n caller?.addEventListener(\"abort\", onCallerAbort, { once: true });\n\n try {\n if (caller?.aborted) throw new AbortError();\n\n // Raced against the deadline rather than left to `fetch` alone.\n // `fetch` is injected here, and not every implementation honours a\n // signal - a mocked one in someone's test suite, an older polyfill, a\n // wrapper that forgets to forward it. When one does not, an unanswered\n // request hangs forever and the timeout this client documents is a\n // promise it does not keep.\n const response = await untilAborted(\n this.#fetch(url, {\n method: request.method,\n headers: this.#headers(request),\n ...(request.rawBody !== undefined\n ? { body: request.rawBody }\n : request.body !== undefined\n ? { body: JSON.stringify(request.body) }\n : {}),\n signal: deadline.signal\n }),\n deadline.signal\n );\n\n /*\n A failure is JSON even on a route that answers with bytes.\n\n Reading the body as an ArrayBuffer first would turn a 409 explaining\n that no Google account is connected into an unreadable buffer, and the\n caller would get \"download failed\" instead of the sentence telling them\n what to do.\n */\n if (request.rawResponse && response.ok) {\n const disposition = response.headers.get(\"content-disposition\") ?? \"\";\n const named = /filename=\"([^\"]+)\"/.exec(disposition)?.[1];\n\n return {\n bytes: new Uint8Array(await response.arrayBuffer()),\n contentType: response.headers.get(\"content-type\") ?? \"application/octet-stream\",\n ...(named ? { filename: named } : {})\n } as T;\n }\n\n const payload = await readBody(response);\n if (!response.ok) throw errorFromResponse(response.status, payload, response.headers);\n return payload as T;\n } catch (thrown) {\n if (thrown instanceof PersistMemoryError) throw thrown;\n\n // Three different things arrive here as one AbortError from fetch, and\n // they need three different answers: the caller cancelled (do not\n // retry), we ran out of time (retry), or the network failed (retry, but\n // not for a POST). Telling them apart by asking WHOSE signal fired is\n // the only reliable way - the DOMException looks the same either way.\n if (caller?.aborted) throw new AbortError();\n if (deadline.signal.aborted) {\n throw new TimeoutError(`The request did not complete within ${timeoutMs}ms.`);\n }\n\n const detail = thrown instanceof Error ? redact(thrown.message) : \"transport failure\";\n throw new ConnectionError(`Could not reach the API: ${detail}`);\n } finally {\n clearTimeout(timer);\n caller?.removeEventListener(\"abort\", onCallerAbort);\n }\n }\n\n #headers(request: InternalRequest): Record<string, string> {\n return {\n // The only place the key is ever read.\n authorization: `Bearer ${this.#apiKey}`,\n // A download route answers with the file's own type, so `*/*` rather\n // than a promise to accept only JSON that the server would have to break.\n accept: request.rawResponse ? \"*/*\" : \"application/json\",\n \"user-agent\": this.#userAgent,\n ...(request.rawBody !== undefined\n ? { \"content-type\": request.contentType ?? \"application/octet-stream\" }\n : request.body !== undefined\n ? { \"content-type\": \"application/json\" }\n : {}),\n ...(request.options?.idempotencyKey\n ? { \"idempotency-key\": request.options.idempotencyKey }\n : {})\n };\n }\n}\n\n/**\n * Whether this failure is worth another attempt.\n *\n * Two questions, and both have to say yes. The first is whether the failure\n * itself could clear - a 400 fails identically on every attempt, so retrying\n * spends two more calls to learn the same thing. The second is whether\n * repeating the REQUEST is safe, which is a different question and the one\n * that gets skipped.\n *\n * For a POST the honest answer is that we usually cannot tell. A connection\n * that died after the server accepted the request is indistinguishable from\n * one that died before, so retrying `remember` on a timeout would queue the\n * same note twice and the user would see it remembered twice. So a POST is\n * retried only when:\n *\n * an idempotency key was given the API deduplicates on it, so the retry\n * returns the first result rather than\n * repeating the work\n *\n * the status was 429 the request was refused BEFORE it was\n * processed. That is what a rate limit is,\n * and it is the one case where \"already\n * succeeded\" is not possible\n *\n * Every other retryable POST failure - a 500, a 503, a timeout, a reset - is\n * given back to the caller, who knows whether repeating it is safe and this\n * package does not.\n */\nexport function mayRetry(error: PersistMemoryError, request: InternalRequest): boolean {\n if (!error.retryable) return false;\n if (RETRY_WITHOUT_ASKING.has(request.method)) return true;\n if (request.options?.idempotencyKey) return true;\n return error.status === 429;\n}\n\n/**\n * The body, parsed if it is JSON and there is any.\n *\n * Never assumes JSON. A 502 from a load balancer in front of the API is an\n * HTML page, and an SDK that calls `response.json()` unconditionally turns a\n * bad gateway into a SyntaxError thrown from inside the error handler - which\n * hides the actual failure behind a parse error nobody can act on.\n */\nasync function readBody(response: Response): Promise<unknown> {\n if (response.status === 204) return undefined;\n\n const text = await response.text().catch(() => \"\");\n if (text.length === 0) return undefined;\n\n const type = response.headers.get(\"content-type\") ?? \"\";\n if (!type.includes(\"json\")) return { raw: text.slice(0, 500) };\n\n try {\n return JSON.parse(text) as unknown;\n } catch {\n // Truncated, because a body that failed to parse can be megabytes of an\n // upstream error page and this string reaches an error message.\n return { raw: text.slice(0, 500) };\n }\n}\n\n/**\n * The response, or a rejection the moment the signal fires.\n *\n * The original promise is left with a `catch` attached: it may still settle\n * long after we have stopped waiting, and an unattended rejection from an\n * abandoned request takes the process down under Node's default handling.\n */\nclass SignalFired extends Error {\n constructor() {\n // Deliberately NOT one of this package's errors. It is raised before we\n // know WHICH signal fired, and the catch in `#attempt` is the only place\n // that can tell a caller's cancel from a deadline - a `TimeoutError`\n // thrown here would be a timeout reported for a user pressing stop.\n super(\"signal fired\");\n this.name = \"SignalFired\";\n }\n}\n\nfunction untilAborted<T>(work: Promise<T>, signal: AbortSignal): Promise<T> {\n work.catch(() => undefined);\n\n return new Promise<T>((resolve, reject) => {\n if (signal.aborted) {\n reject(new SignalFired());\n return;\n }\n\n const onAbort = () => reject(new SignalFired());\n signal.addEventListener(\"abort\", onAbort, { once: true });\n\n work.then(\n (value) => {\n signal.removeEventListener(\"abort\", onAbort);\n resolve(value);\n },\n (error: unknown) => {\n signal.removeEventListener(\"abort\", onAbort);\n reject(error instanceof Error ? error : new Error(String(error)));\n }\n );\n });\n}\n\n/**\n * A wait that can be cancelled.\n *\n * The default. Injected in tests so a retry test does not spend real seconds\n * asleep - a suite that actually waits out an exponential backoff is a suite\n * people stop running.\n */\nfunction defaultSleep(ms: number, signal?: AbortSignal): Promise<void> {\n return new Promise((resolve, reject) => {\n if (signal?.aborted) {\n reject(new AbortError());\n return;\n }\n\n const timer = setTimeout(() => {\n signal?.removeEventListener(\"abort\", onAbort);\n resolve();\n }, ms);\n\n function onAbort(): void {\n clearTimeout(timer);\n reject(new AbortError());\n }\n\n signal?.addEventListener(\"abort\", onAbort, { once: true });\n });\n}\n", "import type { Page } from \"./types\";\n\n/**\n * Walking a cursor-paginated list.\n *\n * The list endpoints are keyset paginated: `?cursor=` carries where the last\n * page ended, and the response is `{ data, pagination: { nextCursor?, limit } }`\n * with `nextCursor` absent on the last page. The absence is the ONLY stop\n * signal - an empty `data` array is not the same thing, because a page can\n * come back empty when everything in it was filtered after the fetch while\n * more pages remain. A client that stops on an empty page silently truncates\n * the user's results and nothing anywhere reports an error.\n *\n * That rule is easy to state and easy to get wrong once per call site, which\n * is why every list method returns one of these instead of leaving the loop to\n * the caller.\n *\n * Not every list is paginated. `spaces/{id}/memories` and\n * `entities/{id}/memories` return a `pagination` block with no cursor at all,\n * so iterating them yields exactly one page and stops - which is correct, and\n * costs a caller nothing for using the same shape everywhere.\n */\nexport class Paginated<T> implements AsyncIterable<T> {\n readonly #fetchPage: (cursor: string | undefined) => Promise<Page<T>>;\n\n constructor(fetchPage: (cursor: string | undefined) => Promise<Page<T>>) {\n this.#fetchPage = fetchPage;\n }\n\n /** The first page, and nothing more. For a UI that renders one page at a time. */\n async first(): Promise<Page<T>> {\n return this.#fetchPage(undefined);\n }\n\n /**\n * Page by page, for a caller that wants the cursors or wants to stop early.\n *\n * A generator rather than an array of pages: fetching them all up front\n * would make \"show me the first ten\" cost every page in the account.\n */\n async *pages(): AsyncGenerator<Page<T>, void, undefined> {\n let cursor: string | undefined;\n const seen = new Set<string>();\n\n for (;;) {\n const page: Page<T> = await this.#fetchPage(cursor);\n yield page;\n\n const next = page.pagination.nextCursor;\n if (!next) return;\n\n // A cursor we have already followed means the server is handing back a\n // position that does not advance, and continuing is an infinite loop\n // that reads the same page forever while looking exactly like a slow\n // account. Stopping loses a page; looping loses the process.\n if (seen.has(next)) return;\n seen.add(next);\n cursor = next;\n }\n }\n\n /** Every item across every page. `for await (const memory of ...)`. */\n async *[Symbol.asyncIterator](): AsyncGenerator<T, void, undefined> {\n for await (const page of this.pages()) {\n for (const item of page.data) yield item;\n }\n }\n\n /**\n * Everything, in one array.\n *\n * `maxItems` is not optional, and that is the point. An unbounded `all()` on\n * an account with two hundred thousand memories is a request loop that runs\n * for minutes and an array that exhausts the heap, and the call site that\n * does it reads as innocently as any other. Ask for a number you can hold.\n */\n async all(maxItems: number): Promise<T[]> {\n const collected: T[] = [];\n if (maxItems <= 0) return collected;\n\n for await (const item of this) {\n collected.push(item);\n if (collected.length >= maxItems) break;\n }\n return collected;\n }\n}\n", "import type { HttpClient, QueryParams, RequestOptions } from \"../http\";\nimport { Paginated } from \"../pagination\";\nimport { pageQuery } from \"../query\";\nimport type { ListMemoriesParams, Memory, Page, RememberParams, RememberResult } from \"../types\";\n\n/**\n * Memories: browsing them, reading one, and handing over new material.\n *\n * Browsing is not searching. `list` is chronological and takes filters,\n * `search` ranks by relevance and takes a query - they are separate endpoints\n * because serving both from one would mean a caller who adds a filter silently\n * gets a differently ordered list.\n */\nexport class Memories {\n readonly #http: HttpClient;\n\n constructor(http: HttpClient) {\n this.#http = http;\n }\n\n /**\n * One page, plus the cursor loop.\n *\n * Returns a `Paginated`, so `await memories.list().first()` gets a page and\n * `for await (const memory of memories.list())` walks the lot. The filters\n * are carried into every page automatically - a caller re-passing them per\n * page is a caller who will eventually forget one, and the pages after that\n * come from a differently filtered list.\n */\n list(params: ListMemoriesParams = {}, options?: RequestOptions): Paginated<Memory> {\n return new Paginated<Memory>((cursor) =>\n this.#http.get<Page<Memory>>(\n \"/api/v1/memories\",\n pageQuery(params, cursor, toQuery(params)),\n options\n )\n );\n }\n\n async get(id: string, options?: RequestOptions): Promise<Memory> {\n return this.#http.get<Memory>(`/api/v1/memories/${encodeURIComponent(id)}`, undefined, options);\n }\n\n /**\n * Hands material to the ingestion pipeline. Needs a key with `write` scope.\n *\n * This does NOT create a memory, and the return type says so: it answers 202\n * with a job id. Extraction, entity resolution, deduplication and conflict\n * detection all run afterwards and may produce one memory, several, or none.\n * Poll `client.jobs.get(result.jobId)` to find out which.\n *\n * Pass an `idempotencyKey` if this can be retried by anything - a queue, a\n * user pressing a button twice, or this client's own retry loop, which\n * refuses to repeat a POST without one. `remember:note-42`, not a fresh\n * random value per call.\n */\n async remember(params: RememberParams, options?: RequestOptions): Promise<RememberResult> {\n return this.#http.post<RememberResult>(\"/api/v1/remember\", params, options);\n }\n}\n\nfunction toQuery(params: ListMemoriesParams): QueryParams {\n return {\n ...(params.type !== undefined ? { type: params.type } : {}),\n ...(params.state !== undefined ? { state: params.state } : {}),\n ...(params.scope !== undefined ? { scope: params.scope } : {}),\n ...(params.spaceIds !== undefined ? { spaceIds: params.spaceIds } : {}),\n ...(params.createdAfter !== undefined ? { createdAfter: params.createdAfter } : {}),\n ...(params.createdBefore !== undefined ? { createdBefore: params.createdBefore } : {}),\n ...(params.minConfidence !== undefined ? { minConfidence: params.minConfidence } : {}),\n ...(params.includeHistorical !== undefined\n ? { includeHistorical: params.includeHistorical }\n : {})\n };\n}\n", "import type { HttpClient, QueryParams, RequestOptions } from \"../http\";\nimport type { ContextParams, ContextResponse, SearchParams, SearchResponse } from \"../types\";\n\n/**\n * Asking the system what it knows.\n *\n * Two methods, and they answer different questions. `search` returns ranked\n * records for a person or a UI. `context` returns prose for a model, bounded\n * by TOKENS rather than by row count - which is the only bound that expresses\n * the real constraint, since ten long memories overflow a window that fifty\n * short ones fit inside.\n *\n * `search` is a GET and `context` is a POST, matching the API: a search is\n * linkable and cacheable, while a context request can carry two hundred\n * excluded ids and every proxy in between has its own idea of how long a URL\n * may be.\n */\nexport class Search {\n readonly #http: HttpClient;\n\n constructor(http: HttpClient) {\n this.#http = http;\n }\n\n /**\n * Ranked results, with an account of how they were found.\n *\n * Read `diagnostics.degraded` before showing the results. Search degrades\n * rather than fails - with embeddings unavailable it falls back to\n * deterministic retrieval and still answers - and a UI that cannot tell\n * degraded from healthy tells the user the system knows nothing when it is\n * merely looking with one eye.\n */\n async query(params: SearchParams, options?: RequestOptions): Promise<SearchResponse> {\n const query: QueryParams = {\n query: params.query,\n ...(params.limit !== undefined ? { limit: params.limit } : {}),\n ...(params.scope !== undefined ? { scope: params.scope } : {}),\n ...(params.spaceIds !== undefined ? { spaceIds: params.spaceIds } : {}),\n ...(params.types !== undefined ? { types: params.types } : {}),\n ...(params.minScore !== undefined ? { minScore: params.minScore } : {}),\n ...(params.asOf !== undefined ? { asOf: params.asOf } : {}),\n ...(params.includeHistorical !== undefined\n ? { includeHistorical: params.includeHistorical }\n : {}),\n ...(params.includeEvidence !== undefined\n ? { includeEvidence: params.includeEvidence }\n : {}),\n ...(params.explain !== undefined ? { explain: params.explain } : {})\n };\n\n return this.#http.get<SearchResponse>(\"/api/v1/search\", query, options);\n }\n\n /**\n * A context window, assembled and ready to paste into a prompt.\n *\n * A POST that is safe to repeat - it reads and returns, it writes nothing -\n * so this is one of the few places where retrying without an idempotency key\n * would be harmless. It still is not retried by default: the request loop\n * decides by METHOD, and a per-endpoint exception is a rule that holds until\n * someone adds a POST next to it that does write.\n */\n async context(params: ContextParams, options?: RequestOptions): Promise<ContextResponse> {\n return this.#http.post<ContextResponse>(\"/api/v1/context\", params, options);\n }\n}\n", "import type { HttpClient, RequestOptions } from \"../http\";\nimport { Paginated } from \"../pagination\";\nimport { pageQuery } from \"../query\";\nimport type {\n CreateSpaceParams,\n ListSpacesParams,\n Memory,\n Page,\n ShareSpaceParams,\n Space,\n SpaceCollaborator,\n GrantableSpaceRole,\n SpaceRole,\n UpdateSpaceParams,\n WorkingSpace\n} from \"../types\";\n\n/**\n * Spaces: a boundary around a set of memories.\n *\n * They exist because \"everything I know\" is the wrong scope for most\n * questions. Work and personal contexts hold contradictory truths - two\n * different \"my manager\" - and answering from both at once is wrong in a way\n * that is hard to notice.\n *\n * Membership is a LINK, not ownership. `removeMemories` takes a memory out of\n * a Space; it does not delete it, and the same memory can belong to several.\n */\nexport class Spaces {\n readonly #http: HttpClient;\n\n constructor(http: HttpClient) {\n this.#http = http;\n }\n\n list(params: ListSpacesParams = {}, options?: RequestOptions): Paginated<Space> {\n return new Paginated<Space>((cursor) =>\n this.#http.get<Page<Space>>(\n \"/api/v1/spaces\",\n pageQuery(params, cursor, {\n ...(params.includeArchived !== undefined\n ? { includeArchived: params.includeArchived }\n : {})\n }),\n options\n )\n );\n }\n\n async get(id: string, options?: RequestOptions): Promise<Space> {\n return this.#http.get<Space>(`/api/v1/spaces/${encodeURIComponent(id)}`, undefined, options);\n }\n\n /**\n * Creates a Space. Answers 201.\n *\n * Worth an idempotency key when a person is behind it: a double-clicked\n * \"create Space\" button makes two Spaces called Work, and nothing later can\n * tell which of them memories should have gone into.\n */\n async create(params: CreateSpaceParams, options?: RequestOptions): Promise<Space> {\n return this.#http.post<Space>(\"/api/v1/spaces\", params, options);\n }\n\n /**\n * Deletes a Space. You must say what happens to what is in it.\n *\n * There is no default, here or in the API, and that is deliberate: \"delete\n * this Space\" means the label to some people and everything inside it to\n * others, and a client that guessed would destroy or keep somebody's\n * material without being asked.\n *\n * `delete` never destroys a memory that is filed in another Space as well \u2014\n * that one is detached and left alone. `deleted` and `kept` come back so you\n * can say what actually happened.\n *\n * `moveTo` NAMES WHERE THE STRANDED ONES GO, and is refused-into rather than\n * required: most deletions strand nothing, because everything in the Space\n * is also filed elsewhere, and demanding a destination for those would be a\n * question about nothing. When something WOULD be left in no Space at all,\n * the server answers 400 naming this field. It used to file them into the\n * account's default, which no longer exists \u2014 nothing picks a Space on\n * anybody's behalf, so \"keep these\" has no answer unless you say where.\n */\n async delete(\n id: string,\n params: { readonly memories: \"keep\" | \"delete\"; readonly moveTo?: string },\n options?: RequestOptions\n ): Promise<{ deleted: number; kept: number; rehomed?: number }> {\n return this.#http.delete<{ deleted: number; kept: number; rehomed?: number }>(\n `/api/v1/spaces/${encodeURIComponent(id)}`,\n params,\n options\n );\n }\n\n /**\n * Merges Spaces into a NEW one, leaving every source exactly as it was.\n *\n * Additive, not destructive: a memory ends up in the sources AND the result,\n * every existing search over a source returns what it did before, and\n * undoing it is deleting the Space this returns. A memory in two sources is\n * filed once.\n */\n async merge(\n params: {\n readonly sourceIds: readonly string[];\n readonly name: string;\n readonly description?: string;\n },\n options?: RequestOptions\n ): Promise<{ space: Space; added: number }> {\n return this.#http.post<{ space: Space; added: number }>(\n \"/api/v1/spaces/merge\",\n params,\n options\n );\n }\n\n /* ------------------------- where this is working ------------------------- */\n\n /*\n `getDefault` AND `setDefault` ARE GONE, with the endpoints they called.\n\n They read and wrote the account-wide Space a capture fell into when nobody\n named one. Nothing falls anywhere now: a Space is chosen for the context\n doing the capturing, or `remember` answers 400. Keeping the methods would\n mean keeping two calls that 404, which is a worse break than removing them\n because it looks like a server fault rather than a change.\n */\n\n /**\n * Which Space a context is working in.\n *\n * `chosen` absent means NOTHING sent from that context is kept \u2014 there is no\n * default behind it and nothing picks one. The reply used to carry a\n * `fallback` for that case and no longer can.\n *\n * `profile` is the command line's own profile name, and `surface` says which\n * context is being asked about: `cli` for this profile, `email` for the\n * account's ingest address. Between them they are the whole of what a caller\n * may say about where it is working \u2014 the server builds the scope key\n * itself, so this can never read or move where a chat is filing.\n */\n async working(\n params: { readonly profile?: string; readonly surface?: \"cli\" | \"email\" } = {},\n options?: RequestOptions\n ): Promise<WorkingSpace> {\n return this.#http.get<WorkingSpace>(\n \"/api/v1/spaces/working\",\n {\n ...(params.profile !== undefined ? { profile: params.profile } : {}),\n ...(params.surface !== undefined ? { surface: params.surface } : {})\n },\n options\n );\n }\n\n /**\n * Works in one from here on. `null` stops working in any.\n *\n * Takes an id or a NAME, because that is how a person says it. `null` rather\n * than an omitted field: \"clear this\" and \"I did not mention it\" are\n * different instructions, and clearing means this context keeps nothing\n * until a Space is chosen again.\n */\n async chooseWorking(\n space: string | null,\n params: { readonly profile?: string; readonly surface?: \"cli\" | \"email\" } = {},\n options?: RequestOptions\n ): Promise<WorkingSpace> {\n return this.#http.patch<WorkingSpace>(\n \"/api/v1/spaces/working\",\n {\n space,\n ...(params.profile !== undefined ? { profile: params.profile } : {}),\n ...(params.surface !== undefined ? { surface: params.surface } : {})\n },\n options\n );\n }\n\n /** Renaming, retention, and archiving - `archived` is a field, not a verb. */\n async update(id: string, params: UpdateSpaceParams, options?: RequestOptions): Promise<Space> {\n return this.#http.patch<Space>(`/api/v1/spaces/${encodeURIComponent(id)}`, params, options);\n }\n\n /**\n * The memories filed in a Space.\n *\n * The cursor is PASSED. This fetch used to ignore the paginator's cursor\n * on the stale belief that the endpoint had none \u2014 the server has minted\n * `pagination.nextCursor` since it started paging, and its own comment\n * says \"both SDKs iterate by reading pagination\". Ignoring it meant every\n * page request was identical: the loop guard saw a non-advancing fetch and\n * stopped silently, so `all()` returned the first page twice and dropped\n * everything after it \u2014 duplicated AND truncated data, with no error.\n */\n memories(\n id: string,\n params: { readonly limit?: number } = {},\n options?: RequestOptions\n ): Paginated<Memory> {\n return new Paginated<Memory>((cursor) =>\n this.#http.get<Page<Memory>>(\n `/api/v1/spaces/${encodeURIComponent(id)}/memories`,\n {\n ...(params.limit !== undefined ? { limit: params.limit } : {}),\n ...(cursor !== undefined ? { cursor } : {})\n },\n options\n )\n );\n }\n\n async addMemories(\n id: string,\n memoryIds: readonly string[],\n options?: RequestOptions\n ): Promise<{ added: number }> {\n return this.#http.post<{ added: number }>(\n `/api/v1/spaces/${encodeURIComponent(id)}/memories`,\n { memoryIds },\n options\n );\n }\n\n /**\n * Removes memberships. The memories themselves are untouched.\n *\n * A body on a DELETE, which is unusual and is what the API takes: the\n * alternative is five hundred ids in a query string, and every proxy in\n * between has its own limit on how long a URL may be.\n */\n async removeMemories(\n id: string,\n memoryIds: readonly string[],\n options?: RequestOptions\n ): Promise<{ removed: number }> {\n return this.#http.delete<{ removed: number }>(\n `/api/v1/spaces/${encodeURIComponent(id)}/memories`,\n { memoryIds },\n options\n );\n }\n\n /* ----------------------- who else can see it ----------------------- */\n\n /**\n * Who can see this Space, including invitations nobody has accepted.\n *\n * A DIFFERENT EDGE from `memories()` next door, and the difference is worth\n * holding on to: that one maps a MEMORY to a Space, this one maps a PERSON\n * to a Space. The server keeps them in two tables with two names for exactly\n * that reason.\n *\n * Read `acceptedAt` before you render a row. An invitation grants nothing\n * until it is accepted, so a list that draws invited and accepted people the\n * same way tells its user somebody is reading their memories when nobody is.\n *\n * Paginated like every other list here. A Space has a handful of\n * collaborators rather than thousands, so this will usually be one page -\n * which costs a caller nothing and means the shape does not change if a\n * Space ever has an organisation on it.\n */\n collaborators(\n id: string,\n params: { readonly limit?: number } = {},\n options?: RequestOptions\n ): Paginated<SpaceCollaborator> {\n return new Paginated<SpaceCollaborator>((cursor) =>\n this.#http.get<Page<SpaceCollaborator>>(\n `/api/v1/sharing/spaces/${encodeURIComponent(id)}/collaborators`,\n {\n ...(params.limit !== undefined ? { limit: params.limit } : {}),\n ...(cursor !== undefined ? { cursor } : {})\n },\n options\n )\n );\n }\n\n /**\n * Offers somebody sight of a Space. Answers with the invitation.\n *\n * AN OFFER, NOT A GRANT, and the returned `acceptedAt` will be absent to\n * prove it. The recipient has to accept before they can see anything, which\n * is the property that keeps \"nothing enters your memory without you\" true\n * even when somebody else starts the sharing. Do not tell your user their\n * Space \"has been shared\" on the strength of a 2xx here.\n *\n * WHAT THEY GET IS THE WHOLE SPACE: every memory already filed in it and\n * every memory that lands in it afterwards. There is no narrower grant, and\n * `role` does not make one - it decides what they may do BESIDES read.\n *\n * Worth an idempotency key when a person is behind it. A double-clicked\n * \"share\" is two invitations to the same address, and the second one is a\n * second email arriving at somebody who has already been asked.\n */\n async share(\n id: string,\n params: ShareSpaceParams,\n options?: RequestOptions\n ): Promise<SpaceCollaborator> {\n return this.#http.post<SpaceCollaborator>(\n `/api/v1/sharing/spaces/${encodeURIComponent(id)}/collaborators`,\n params,\n options\n );\n }\n\n /**\n * Ends somebody's access, or withdraws an invitation they never accepted.\n *\n * Nothing was ever copied into their account - a collaborator SEES the\n * owner's memories rather than holding a duplicate - so this is one write\n * and not a cascade, and there is no orphaned copy left behind.\n *\n * A body on a DELETE, matching `removeMemories` above. The alternative is an\n * address in a path segment, where every `.`, `+` and `@` is a chance for a\n * proxy or a router to normalise somebody else's email into the one that\n * gets revoked.\n */\n async unshare(\n id: string,\n email: string,\n options?: RequestOptions\n ): Promise<{ email: string }> {\n return this.#http.delete<{ email: string }>(\n `/api/v1/sharing/spaces/${encodeURIComponent(id)}/collaborators`,\n { email },\n options\n );\n }\n\n /**\n * Changes what an existing collaborator may do. Never invites anybody.\n *\n * The quiet one. Moving somebody from `viewer` to `owner` sends no\n * invitation and needs no acceptance, and afterwards they can share the\n * Space onward and revoke the person who promoted them. Show your user what\n * `owner` means before you send this, not after.\n */\n async setRole(\n id: string,\n params: { readonly email: string; readonly role: GrantableSpaceRole },\n options?: RequestOptions\n ): Promise<SpaceCollaborator> {\n return this.#http.patch<SpaceCollaborator>(\n `/api/v1/sharing/spaces/${encodeURIComponent(id)}/collaborators`,\n params,\n options\n );\n }\n}\n", "import type { HttpClient, QueryParams, RequestOptions } from \"../http\";\nimport { Paginated } from \"../pagination\";\nimport { pageQuery } from \"../query\";\nimport type {\n Document,\n Job,\n ListDocumentsParams,\n ListJobsParams,\n ListSourcesParams,\n Page,\n Source\n} from \"../types\";\n\n/**\n * Where material came from, what it became, and the work in between.\n *\n * Three resources rather than one because they answer three questions a caller\n * asks separately: a source is an ORIGIN, a document is the normalised form\n * that was kept, and a job is the work that is still running. Collapsing them\n * would make \"nothing has appeared yet\" indistinguishable from \"it silently\n * failed\", which is the whole reason jobs are visible at all.\n */\nexport class Sources {\n readonly #http: HttpClient;\n\n constructor(http: HttpClient) {\n this.#http = http;\n }\n\n list(params: ListSourcesParams = {}, options?: RequestOptions): Paginated<Source> {\n return new Paginated<Source>((cursor) =>\n this.#http.get<Page<Source>>(\n \"/api/v1/sources\",\n pageQuery(params, cursor, {\n ...(params.provider !== undefined ? { provider: params.provider } : {})\n }),\n options\n )\n );\n }\n\n async get(id: string, options?: RequestOptions): Promise<Source> {\n return this.#http.get<Source>(`/api/v1/sources/${encodeURIComponent(id)}`, undefined, options);\n }\n}\n\nexport class Documents {\n readonly #http: HttpClient;\n\n constructor(http: HttpClient) {\n this.#http = http;\n }\n\n list(params: ListDocumentsParams = {}, options?: RequestOptions): Paginated<Document> {\n return new Paginated<Document>((cursor) =>\n this.#http.get<Page<Document>>(\n \"/api/v1/documents\",\n pageQuery(params, cursor, {\n ...(params.sourceId !== undefined ? { sourceId: params.sourceId } : {}),\n ...(params.status !== undefined ? { status: params.status } : {})\n }),\n options\n )\n );\n }\n\n async get(id: string, options?: RequestOptions): Promise<Document> {\n return this.#http.get<Document>(\n `/api/v1/documents/${encodeURIComponent(id)}`,\n undefined,\n options\n );\n }\n}\n\nexport class Jobs {\n readonly #http: HttpClient;\n\n constructor(http: HttpClient) {\n this.#http = http;\n }\n\n list(params: ListJobsParams = {}, options?: RequestOptions): Paginated<Job> {\n return new Paginated<Job>((cursor) =>\n this.#http.get<Page<Job>>(\n \"/api/v1/jobs\",\n pageQuery(params, cursor, {\n ...(params.status !== undefined ? { status: params.status } : {}),\n ...(params.type !== undefined ? { type: params.type } : {})\n }),\n options\n )\n );\n }\n\n /**\n * One job, by id. This is what `remember` hands back a reference to.\n *\n * `completed` is the terminal success state - the store's own word, not\n * `succeeded`. A caller polling for a state the API never writes waits\n * forever with nothing to show why.\n */\n async get(id: string, options?: RequestOptions): Promise<Job> {\n return this.#http.get<Job>(`/api/v1/jobs/${encodeURIComponent(id)}`, undefined, options);\n }\n}\n", "import type { HttpClient, RequestOptions } from \"../http\";\nimport { Paginated } from \"../pagination\";\nimport { pageQuery } from \"../query\";\nimport type {\n Conflict,\n Entity,\n EntityMemoriesParams,\n EntityMention,\n GraphResponse,\n ListConflictsParams,\n ListEntitiesParams,\n Page,\n ResolveConflictParams,\n TraverseParams\n} from \"../types\";\n\n/**\n * The people, places and things memories are about.\n *\n * Entities are RESOLVED rather than stored as strings: \"Sam\", \"Sam Patel\" and\n * \"sam@work.com\" are one person, and a system that treats them as three cannot\n * answer \"what do I know about Sam\" - the most obvious question anyone asks a\n * memory system.\n */\nexport class Entities {\n readonly #http: HttpClient;\n\n constructor(http: HttpClient) {\n this.#http = http;\n }\n\n list(params: ListEntitiesParams = {}, options?: RequestOptions): Paginated<Entity> {\n return new Paginated<Entity>((cursor) =>\n this.#http.get<Page<Entity>>(\n \"/api/v1/entities\",\n pageQuery(params, cursor, {\n ...(params.type !== undefined ? { type: params.type } : {}),\n ...(params.q !== undefined ? { q: params.q } : {})\n }),\n options\n )\n );\n }\n\n async get(id: string, options?: RequestOptions): Promise<Entity> {\n return this.#http.get<Entity>(`/api/v1/entities/${encodeURIComponent(id)}`, undefined, options);\n }\n\n /**\n * Which memories mention this entity, and how.\n *\n * Returns MENTIONS - a memory id, a role and a confidence - not the memories\n * themselves. \"Memories about Sam\" and \"memories Sam appears in\" are\n * different questions, and `role` is what separates them.\n *\n * Like the Space membership list, this endpoint answers with a `pagination`\n * block that carries no cursor, so it yields one page and stops.\n */\n memories(\n id: string,\n params: EntityMemoriesParams = {},\n options?: RequestOptions\n ): Paginated<EntityMention> {\n return new Paginated<EntityMention>((cursor) =>\n this.#http.get<Page<EntityMention>>(\n `/api/v1/entities/${encodeURIComponent(id)}/memories`,\n pageQuery(params, cursor, {\n ...(params.role !== undefined ? { role: params.role } : {}),\n ...(params.minConfidence !== undefined ? { minConfidence: params.minConfidence } : {})\n }),\n options\n )\n );\n }\n}\n\n/**\n * Walking the graph out from an entity.\n *\n * Every bound has a server-side ceiling, and that is the point: an unbounded\n * traversal on a well-connected graph visits everything, and the request that\n * does it is indistinguishable from a denial of service. Read `truncated` -\n * silence would read as \"this is the whole graph\", and a conclusion drawn from\n * a subset nobody knew was a subset is worse than no answer.\n */\nexport class Graph {\n readonly #http: HttpClient;\n\n constructor(http: HttpClient) {\n this.#http = http;\n }\n\n async traverse(params: TraverseParams, options?: RequestOptions): Promise<GraphResponse> {\n return this.#http.get<GraphResponse>(\n \"/api/v1/graph\",\n {\n from: params.from,\n ...(params.depth !== undefined ? { depth: params.depth } : {}),\n ...(params.maxNodes !== undefined ? { maxNodes: params.maxNodes } : {}),\n ...(params.memoryLimit !== undefined ? { memoryLimit: params.memoryLimit } : {})\n },\n options\n );\n }\n}\n\n/**\n * Two things the system believes that cannot both be true.\n *\n * Surfaced rather than settled silently, because the automatic answer is often\n * wrong: \"I moved to Berlin\" superseding \"I live in London\" is right, and \"the\n * deadline is Friday\" against \"the deadline is Monday\" is a question only the\n * user can answer.\n */\nexport class Conflicts {\n readonly #http: HttpClient;\n\n constructor(http: HttpClient) {\n this.#http = http;\n }\n\n list(params: ListConflictsParams = {}, options?: RequestOptions): Paginated<Conflict> {\n return new Paginated<Conflict>((cursor) =>\n this.#http.get<Page<Conflict>>(\n \"/api/v1/conflicts\",\n pageQuery(params, cursor, {\n ...(params.includeResolved !== undefined\n ? { includeResolved: params.includeResolved }\n : {}),\n ...(params.type !== undefined ? { type: params.type } : {})\n }),\n options\n )\n );\n }\n\n async get(id: string, options?: RequestOptions): Promise<Conflict> {\n return this.#http.get<Conflict>(\n `/api/v1/conflicts/${encodeURIComponent(id)}`,\n undefined,\n options\n );\n }\n\n /**\n * Settles one.\n *\n * `keep` names the winner and supersedes the loser; it does not delete it.\n * `dismiss` records that the detector was wrong, which is worth knowing when\n * the same pair trips it again.\n *\n * The parameter type is a union, so `keep` without a `keepId` does not\n * compile. The server rejects it too - this just moves the failure from a\n * 400 in production to a red squiggle.\n */\n async resolve(\n id: string,\n params: ResolveConflictParams,\n options?: RequestOptions\n ): Promise<{ status: string } & Record<string, unknown>> {\n return this.#http.post(\n `/api/v1/conflicts/${encodeURIComponent(id)}/resolve`,\n params,\n options\n );\n }\n}\n", "import type { HttpClient, RequestOptions } from \"../http\";\nimport { Paginated } from \"../pagination\";\nimport { pageQuery } from \"../query\";\nimport type {\n AppendMessagesParams,\n AppendMessagesResult,\n Conversation,\n CreateConversationParams,\n ListConversationsParams,\n Message,\n Page\n} from \"../types\";\n\n/**\n * A running exchange the system remembers across sessions.\n *\n * A conversation is both a SOURCE of memories and a place to spend them: turns\n * appended here go through the same extraction pipeline as `remember`, so they\n * get consolidation and entity resolution rather than a second, drifting path.\n */\nexport class Conversations {\n readonly #http: HttpClient;\n\n constructor(http: HttpClient) {\n this.#http = http;\n }\n\n list(\n params: ListConversationsParams = {},\n options?: RequestOptions\n ): Paginated<Conversation> {\n return new Paginated<Conversation>((cursor) =>\n this.#http.get<Page<Conversation>>(\n \"/api/v1/conversations\",\n pageQuery(params, cursor, {\n ...(params.channel !== undefined ? { channel: params.channel } : {})\n }),\n options\n )\n );\n }\n\n async get(id: string, options?: RequestOptions): Promise<Conversation> {\n return this.#http.get<Conversation>(\n `/api/v1/conversations/${encodeURIComponent(id)}`,\n undefined,\n options\n );\n }\n\n async create(\n params: CreateConversationParams = {},\n options?: RequestOptions\n ): Promise<Conversation> {\n return this.#http.post<Conversation>(\"/api/v1/conversations\", params, options);\n }\n\n messages(\n id: string,\n params: { readonly limit?: number; readonly cursor?: string } = {},\n options?: RequestOptions\n ): Paginated<Message> {\n return new Paginated<Message>((cursor) =>\n this.#http.get<Page<Message>>(\n `/api/v1/conversations/${encodeURIComponent(id)}/messages`,\n pageQuery(params, cursor, {}),\n options\n )\n );\n }\n\n /**\n * Appends turns, and by default extracts memories from them.\n *\n * Check `extracting` on the result. With no queue configured the turns are\n * stored and never become memory, and the API says so in `note` rather than\n * reporting a success - a caller that ignores it believes a memory is on its\n * way that never arrives.\n *\n * `system` and `tool` turns are stored but never extracted: a system prompt\n * is configuration, and remembering it would file our own instructions as\n * the user's facts.\n *\n * Give this an `idempotencyKey`. Appending the same turn twice is the most\n * likely duplicate in the whole API - a client reconnecting after a dropped\n * response has no other way to tell whether its last write landed.\n */\n async append(\n id: string,\n params: AppendMessagesParams,\n options?: RequestOptions\n ): Promise<AppendMessagesResult> {\n return this.#http.post<AppendMessagesResult>(\n `/api/v1/conversations/${encodeURIComponent(id)}/messages`,\n params,\n options\n );\n }\n}\n", "import type { HttpClient, RequestOptions } from \"../http\";\nimport type {\n DriveFile,\n MailMessage,\n MailSummary,\n Person,\n SaveToDriveParams,\n SearchDriveParams,\n SearchMailParams\n} from \"../types\";\n\n/**\n * A user's own Google, through this API rather than through Google.\n *\n * The distinction is the point. Google's tokens live encrypted on the server\n * and never reach a client, so an API key that leaks is an API key - not a\n * mailbox. Nothing here takes a Google credential, and nothing here ever will.\n *\n * Every method answers 409 when there is no connected account, or when Google\n * has stopped renewing one. Neither is a server fault and neither is fixed by\n * retrying: the user has to connect or reconnect at\n * persistmemory.com/dashboard/connect, and the error message says so.\n */\nexport class Google {\n readonly #http: HttpClient;\n\n constructor(http: HttpClient) {\n this.#http = http;\n }\n\n /** Files by name, newest first. Omit the query for recently changed ones. */\n async searchDrive(\n params: SearchDriveParams = {},\n options?: RequestOptions\n ): Promise<{ data: DriveFile[] }> {\n return this.#http.get<{ data: DriveFile[] }>(\n \"/api/v1/google/drive/files\",\n {\n ...(params.query !== undefined ? { query: params.query } : {}),\n ...(params.limit !== undefined ? { limit: params.limit } : {})\n },\n options\n );\n }\n\n async getDriveFile(fileId: string, options?: RequestOptions): Promise<DriveFile> {\n return this.#http.get<DriveFile>(\n `/api/v1/google/drive/files/${encodeURIComponent(fileId)}`,\n undefined,\n options\n );\n }\n\n /**\n * The bytes of a Drive file.\n *\n * A Google Doc, Sheet or Slide holds no bytes of its own and is exported on\n * the way - a document as PDF, a spreadsheet as CSV - so `filename` comes\n * back describing what it BECAME. Writing it under the id instead produces a\n * file nothing will open.\n */\n async downloadDriveFile(\n fileId: string,\n options?: RequestOptions\n ): Promise<{ bytes: Uint8Array; contentType: string; filename?: string }> {\n return this.#http.getBytes(\n `/api/v1/google/drive/files/${encodeURIComponent(fileId)}/content`,\n undefined,\n options\n );\n }\n\n /**\n * Writes a file into the user's Drive.\n *\n * Needs one of the Drive write permissions on their connection. A read-only\n * grant is refused by Google, and the error names the missing permission\n * rather than reporting a failed upload - one is fixed with a checkbox and\n * the other sends somebody looking for a bug.\n */\n async saveToDrive(\n params: SaveToDriveParams,\n options?: RequestOptions\n ): Promise<DriveFile> {\n return this.#http.postBytes<DriveFile>(\n \"/api/v1/google/drive/files\",\n params.bytes,\n params.contentType ?? \"application/octet-stream\",\n {\n name: params.name,\n ...(params.folderId !== undefined ? { folderId: params.folderId } : {})\n },\n options\n );\n }\n\n /**\n * Recent messages - senders, subjects and a one-line preview, never bodies.\n *\n * `query` is Gmail's own syntax passed through as written: `from:priya`,\n * `has:attachment`, `newer_than:7d`. It selects within the connected mailbox\n * and cannot reach another one.\n */\n async searchMail(\n params: SearchMailParams = {},\n options?: RequestOptions\n ): Promise<{ data: MailSummary[] }> {\n return this.#http.get<{ data: MailSummary[] }>(\n \"/api/v1/google/mail\",\n {\n ...(params.query !== undefined ? { query: params.query } : {}),\n ...(params.limit !== undefined ? { limit: params.limit } : {})\n },\n options\n );\n }\n\n /** One message, with its body and the names of what is attached. */\n async readMail(messageId: string, options?: RequestOptions): Promise<MailMessage> {\n return this.#http.get<MailMessage>(\n `/api/v1/google/mail/${encodeURIComponent(messageId)}`,\n undefined,\n options\n );\n }\n\n /**\n * The bytes of one attachment.\n *\n * Separate from `readMail` so listing a mailbox never drags attachments\n * across the network: a message with a 40 MB deck should not cost 40 MB to\n * summarise.\n */\n async downloadAttachment(\n messageId: string,\n attachmentId: string,\n options?: RequestOptions\n ): Promise<{ bytes: Uint8Array; contentType: string }> {\n return this.#http.getBytes(\n `/api/v1/google/mail/${encodeURIComponent(messageId)}/attachments/${encodeURIComponent(attachmentId)}`,\n undefined,\n options\n );\n }\n\n /** Sends as the connected account. Needs the send permission. */\n async sendMail(\n params: { to: string; subject: string; body: string; replyToMessageId?: string },\n options?: RequestOptions\n ): Promise<{ id: string }> {\n return this.#http.post<{ id: string }>(\"/api/v1/google/mail/send\", params, options);\n }\n\n /** People in the user's contacts. Omit the query to list them. */\n async contacts(\n params: { query?: string; limit?: number } = {},\n options?: RequestOptions\n ): Promise<{ data: Person[] }> {\n return this.#http.get<{ data: Person[] }>(\n \"/api/v1/google/contacts\",\n {\n ...(params.query !== undefined ? { query: params.query } : {}),\n ...(params.limit !== undefined ? { limit: params.limit } : {})\n },\n options\n );\n }\n}\n", "import type { HttpClient, RequestOptions } from \"../http\";\nimport { Paginated } from \"../pagination\";\nimport { pageQuery } from \"../query\";\nimport type {\n ConnectIntegrationParams,\n ConnectIntegrationResult,\n Integration,\n ListIntegrationsParams,\n Page,\n UpdateIntegrationParams\n} from \"../types\";\n\n/**\n * Live connections to somewhere material comes from.\n *\n * What is deliberately absent from every response: the access token, the\n * refresh token, and anything else that would let a caller act as the user on\n * the far side. They are held encrypted and never leave the server, so one\n * leaked API key does not become access to the user's Drive.\n *\n * `connect` returns a URL to send the user to. It does not take third-party\n * credentials, and no method here ever will - an endpoint that accepted a\n * password for another service would train users to hand them over, which is\n * the habit every phishing attack relies on.\n */\nexport class Integrations {\n readonly #http: HttpClient;\n\n constructor(http: HttpClient) {\n this.#http = http;\n }\n\n list(params: ListIntegrationsParams = {}, options?: RequestOptions): Paginated<Integration> {\n return new Paginated<Integration>((cursor) =>\n this.#http.get<Page<Integration>>(\n \"/api/v1/integrations\",\n pageQuery(params, cursor, {\n ...(params.provider !== undefined ? { provider: params.provider } : {}),\n ...(params.status !== undefined ? { status: params.status } : {})\n }),\n options\n )\n );\n }\n\n /** Providers that can be connected at all. Not the user's own connections. */\n async available(options?: RequestOptions): Promise<unknown> {\n return this.#http.get<unknown>(\"/api/v1/integrations/available\", undefined, options);\n }\n\n async get(id: string, options?: RequestOptions): Promise<Integration> {\n return this.#http.get<Integration>(\n `/api/v1/integrations/${encodeURIComponent(id)}`,\n undefined,\n options\n );\n }\n\n async connect(\n params: ConnectIntegrationParams,\n options?: RequestOptions\n ): Promise<ConnectIntegrationResult> {\n return this.#http.post<ConnectIntegrationResult>(\n \"/api/v1/integrations/connect\",\n params,\n options\n );\n }\n\n async update(\n id: string,\n params: UpdateIntegrationParams,\n options?: RequestOptions\n ): Promise<Integration> {\n return this.#http.patch<Integration>(\n `/api/v1/integrations/${encodeURIComponent(id)}`,\n params,\n options\n );\n }\n\n /**\n * Asks for a sync now rather than waiting for the schedule. Answers 202.\n *\n * `full` re-reads everything and is deliberately opt-in: on a large Drive\n * that is thousands of documents and a real bill. The incremental default is\n * what should run almost always.\n */\n async sync(\n id: string,\n params: { readonly full?: boolean } = {},\n options?: RequestOptions\n ): Promise<{ status: string; full: boolean }> {\n return this.#http.post<{ status: string; full: boolean }>(\n `/api/v1/integrations/${encodeURIComponent(id)}/sync`,\n params,\n options\n );\n }\n\n /**\n * Destroys the credentials. The row stays.\n *\n * History still has to attribute the memories this connection produced, and\n * deleting the row would leave them pointing at nothing.\n */\n async disconnect(id: string, options?: RequestOptions): Promise<{ status: string }> {\n return this.#http.delete<{ status: string }>(\n `/api/v1/integrations/${encodeURIComponent(id)}`,\n undefined,\n options\n );\n }\n}\n", "import type { HttpClient, RequestOptions } from \"../http\";\nimport type { HealthResponse } from \"../types\";\n\n/**\n * Is it up, and is it ready.\n *\n * Two endpoints because they answer different questions and a load balancer\n * needs both: `live` says the process is running, `ready` says it can serve.\n * Answering `ready` from a liveness probe restarts a healthy process that was\n * merely waiting on a dependency.\n *\n * Neither is under `/api/v1`, and neither needs the key - but the key is sent\n * anyway, because a client that builds a second, credential-free request path\n * has a second path that can be wrong.\n */\nexport class Health {\n readonly #http: HttpClient;\n\n constructor(http: HttpClient) {\n this.#http = http;\n }\n\n async live(options?: RequestOptions): Promise<HealthResponse> {\n return this.#http.get<HealthResponse>(\"/health/live\", undefined, options);\n }\n\n async ready(options?: RequestOptions): Promise<HealthResponse> {\n return this.#http.get<HealthResponse>(\"/health/ready\", undefined, options);\n }\n}\n", "import type { HttpClient, RequestOptions } from \"../http\";\nimport type { AgentDownloadLink, AgentRequest, AgentRequestList, MachineShareResult } from \"../types\";\n\n/**\n * Files fetched from the caller's own machine.\n *\n * A request is asked for on one surface, approved by a person, carried out by\n * an agent on their laptop, and finishes with the bytes in storage. Everything\n * up to that point was already visible through the API; `downloadLink` is what\n * makes the result retrievable rather than merely describable.\n */\nexport class Agent {\n readonly #http: HttpClient;\n\n constructor(http: HttpClient) {\n this.#http = http;\n }\n\n /** The row, including whether it finished and how large the result is. */\n async request(id: string, options?: RequestOptions): Promise<AgentRequest> {\n return this.#http.get<AgentRequest>(\n `/api/v1/agent/request/${encodeURIComponent(id)}`,\n undefined,\n options\n );\n }\n\n /**\n * A short-lived link to the bytes of a finished request.\n *\n * Returns the URL rather than the file, and that is a deliberate limit of\n * this package rather than an oversight. The transport under every other\n * method parses JSON, retries, and attaches the API key; none of those is\n * right for a hundred-megabyte binary body, and building a second request\n * path inside the SDK to serve one method is how a client ends up with two\n * retry policies that differ only during an outage. Fetch the URL with\n * whatever already streams in your runtime - it needs no credential, which\n * is the whole reason it is signed.\n *\n * Treat the URL as the file. It is a bearer credential for exactly one\n * object, it expires in minutes, and it should not be logged or stored.\n */\n async downloadLink(id: string, options?: RequestOptions): Promise<AgentDownloadLink> {\n return this.#http.get<AgentDownloadLink>(\n `/api/v1/agent/request/${encodeURIComponent(id)}/download`,\n undefined,\n options\n );\n }\n\n /**\n * A Space's requests \u2014 what the project has in flight and what came back,\n * whoever raised it and whichever machine answered. For an editor or owner\n * of the Space; a viewer, and anybody not in it, is answered 404.\n */\n async spaceRequests(spaceId: string, options?: RequestOptions): Promise<AgentRequestList> {\n return this.#http.get<AgentRequestList>(\n `/api/v1/agent/spaces/${encodeURIComponent(spaceId)}/requests`,\n undefined,\n options\n );\n }\n\n /**\n * Shares one of your own machines into a Space, so the Space's editors can\n * ask it for files and commands. Every such ask waits for you, the\n * machine's owner, whatever your own approval settings say. Session\n * credentials only.\n */\n async shareMachine(\n args: { hostname: string; space: string },\n options?: RequestOptions\n ): Promise<MachineShareResult> {\n return this.#http.post<MachineShareResult>(\"/api/v1/agent/connections/share\", args, options);\n }\n\n /** Takes a machine back out of a Space. Requests already answered stay answered. */\n async unshareMachine(\n args: { hostname: string; space: string },\n options?: RequestOptions\n ): Promise<MachineShareResult> {\n return this.#http.delete<MachineShareResult>(\"/api/v1/agent/connections/share\", args, options);\n }\n}\n", "import type { ClientOptions, RequestOptions } from \"./http\";\nimport { HttpClient } from \"./http\";\nimport { Memories } from \"./resources/memories\";\nimport { Search } from \"./resources/search\";\nimport { Spaces } from \"./resources/spaces\";\nimport { Documents, Jobs, Sources } from \"./resources/ingestion\";\nimport { Conflicts, Entities, Graph } from \"./resources/knowledge\";\nimport { Conversations } from \"./resources/conversations\";\nimport { Google } from \"./resources/google\";\nimport { Integrations } from \"./resources/integrations\";\nimport { Health } from \"./resources/health\";\nimport { Agent } from \"./resources/agent\";\n\n/**\n * The client.\n *\n * const client = new PersistMemory({ apiKey: process.env.PERSISTMEMORY_API_KEY! });\n * const found = await client.search.query({ query: \"what did we decide about Postgres\" });\n *\n * One transport underneath every resource, so retries, timeouts, error mapping\n * and the credential are decided once. Resources are plain objects hanging off\n * this one; they hold a reference to the transport and no state of their own,\n * which is what makes a client safe to share across a process.\n */\nexport class PersistMemory {\n readonly memories: Memories;\n readonly search: Search;\n readonly spaces: Spaces;\n readonly sources: Sources;\n readonly documents: Documents;\n readonly jobs: Jobs;\n readonly entities: Entities;\n readonly graph: Graph;\n readonly conflicts: Conflicts;\n readonly conversations: Conversations;\n readonly integrations: Integrations;\n /** Drive, mail and contacts on the user's connected Google account. */\n readonly google: Google;\n readonly health: Health;\n readonly agent: Agent;\n\n readonly #http: HttpClient;\n\n constructor(options: ClientOptions) {\n this.#http = new HttpClient(options);\n\n this.memories = new Memories(this.#http);\n this.search = new Search(this.#http);\n this.spaces = new Spaces(this.#http);\n this.sources = new Sources(this.#http);\n this.documents = new Documents(this.#http);\n this.jobs = new Jobs(this.#http);\n this.entities = new Entities(this.#http);\n this.graph = new Graph(this.#http);\n this.conflicts = new Conflicts(this.#http);\n this.conversations = new Conversations(this.#http);\n this.integrations = new Integrations(this.#http);\n this.google = new Google(this.#http);\n this.health = new Health(this.#http);\n this.agent = new Agent(this.#http);\n }\n\n /**\n * An escape hatch for an endpoint this package has not caught up with.\n *\n * Typed as `unknown` on purpose: a caller reaching past the typed surface is\n * taking responsibility for the shape, and handing them `any` would let that\n * responsibility spread silently through their codebase.\n */\n async request<T = unknown>(\n method: \"GET\" | \"POST\" | \"PATCH\" | \"DELETE\",\n path: string,\n body?: unknown,\n options?: RequestOptions\n ): Promise<T> {\n if (method === \"GET\") return this.#http.get<T>(path, undefined, options);\n if (method === \"POST\") return this.#http.post<T>(path, body, options);\n if (method === \"PATCH\") return this.#http.patch<T>(path, body, options);\n return this.#http.delete<T>(path, body, options);\n }\n\n /** Never the key. See `HttpClient.toJSON`, which this delegates to. */\n toJSON(): Record<string, unknown> {\n return this.#http.toJSON();\n }\n\n [Symbol.for(\"nodejs.util.inspect.custom\")](): Record<string, unknown> {\n return this.#http.toJSON();\n }\n}\n"],
|
|
5
|
+
"mappings": "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",
|
|
6
6
|
"names": []
|
|
7
7
|
}
|