@neo4j-labs/agent-memory 0.3.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.
@@ -0,0 +1,226 @@
1
+ import { ConnectionError, AuthenticationError, TransportError } from './chunk-ASQMU7YC.js';
2
+
3
+ // src/version.ts
4
+ var VERSION = "0.3.0";
5
+
6
+ // src/observability.ts
7
+ function defaultUserAgent() {
8
+ const runtime = detectRuntime();
9
+ return runtime ? `@neo4j-labs/agent-memory/${VERSION} (${runtime})` : `@neo4j-labs/agent-memory/${VERSION}`;
10
+ }
11
+ function supportsUserAgentHeader() {
12
+ return detectRuntime() !== null;
13
+ }
14
+ function detectRuntime() {
15
+ const denoObj = globalThis.Deno;
16
+ if (denoObj?.version?.deno) {
17
+ return `deno/${denoObj.version.deno}`;
18
+ }
19
+ const bunObj = globalThis.Bun;
20
+ if (bunObj?.version) {
21
+ return `bun/${bunObj.version}`;
22
+ }
23
+ if (typeof process !== "undefined" && process.versions?.node) {
24
+ const platform = process.platform ?? "unknown";
25
+ return `node/${process.versions.node}; ${platform}`;
26
+ }
27
+ return null;
28
+ }
29
+ function extractRequestId(headers) {
30
+ return headers.get("x-request-id") ?? headers.get("request-id") ?? headers.get("x-amzn-requestid") ?? void 0;
31
+ }
32
+
33
+ // src/transport/bridge.ts
34
+ function trimTrailingSlashes(s) {
35
+ let end = s.length;
36
+ while (end > 0 && s.charCodeAt(end - 1) === 47) end--;
37
+ return s.slice(0, end);
38
+ }
39
+ function nowMs() {
40
+ if (typeof performance !== "undefined" && typeof performance.now === "function") {
41
+ return performance.now();
42
+ }
43
+ return Date.now();
44
+ }
45
+ var BridgeTransport = class {
46
+ endpoint;
47
+ apiKey;
48
+ timeout;
49
+ headers;
50
+ logger;
51
+ constructor(options) {
52
+ this.endpoint = trimTrailingSlashes(options.endpoint);
53
+ this.apiKey = options.apiKey;
54
+ this.timeout = options.timeout ?? 3e4;
55
+ this.headers = options.headers ?? {};
56
+ this.logger = options.logger;
57
+ }
58
+ async connect() {
59
+ const url = `${this.endpoint}/setup`;
60
+ const start = nowMs();
61
+ this.emit({ kind: "request", method: "connect", url, httpMethod: "POST" });
62
+ let response;
63
+ try {
64
+ response = await fetch(url, {
65
+ method: "POST",
66
+ headers: this.buildHeaders(),
67
+ signal: AbortSignal.timeout(this.timeout)
68
+ });
69
+ } catch (error) {
70
+ const durationMs2 = nowMs() - start;
71
+ if (error instanceof TypeError) {
72
+ const err = new ConnectionError(
73
+ `Failed to connect to ${this.endpoint}: ${error.message}`,
74
+ { cause: error }
75
+ );
76
+ this.emit({ kind: "error", method: "connect", url, durationMs: durationMs2, message: err.message });
77
+ throw err;
78
+ }
79
+ if (error instanceof DOMException && error.name === "TimeoutError") {
80
+ const err = new ConnectionError(
81
+ `Connection to ${this.endpoint} timed out after ${this.timeout}ms`,
82
+ { cause: error }
83
+ );
84
+ this.emit({ kind: "error", method: "connect", url, durationMs: durationMs2, message: err.message });
85
+ throw err;
86
+ }
87
+ throw error;
88
+ }
89
+ const durationMs = nowMs() - start;
90
+ const requestId = extractRequestId(response.headers);
91
+ if (response.status === 401 || response.status === 403) {
92
+ const err = new AuthenticationError(
93
+ `Authentication failed: ${response.status} ${response.statusText}`,
94
+ { requestId }
95
+ );
96
+ this.emit({
97
+ kind: "error",
98
+ method: "connect",
99
+ url,
100
+ status: response.status,
101
+ requestId,
102
+ durationMs,
103
+ message: err.message
104
+ });
105
+ throw err;
106
+ }
107
+ this.emit({
108
+ kind: "response",
109
+ method: "connect",
110
+ url,
111
+ status: response.status,
112
+ requestId,
113
+ durationMs
114
+ });
115
+ }
116
+ async close() {
117
+ }
118
+ async request(method, params) {
119
+ const url = `${this.endpoint}/${method}`;
120
+ const body = {};
121
+ for (const [key, value] of Object.entries(params)) {
122
+ if (value !== void 0 && value !== null) {
123
+ body[key] = value;
124
+ }
125
+ }
126
+ const start = nowMs();
127
+ this.emit({ kind: "request", method, url, httpMethod: "POST" });
128
+ let response;
129
+ try {
130
+ response = await fetch(url, {
131
+ method: "POST",
132
+ headers: this.buildHeaders(),
133
+ body: JSON.stringify(body),
134
+ signal: AbortSignal.timeout(this.timeout)
135
+ });
136
+ } catch (error) {
137
+ const durationMs2 = nowMs() - start;
138
+ if (error instanceof TypeError) {
139
+ const err = new ConnectionError(
140
+ `Request to ${url} failed: ${error.message}`,
141
+ { cause: error }
142
+ );
143
+ this.emit({ kind: "error", method, url, durationMs: durationMs2, message: err.message });
144
+ throw err;
145
+ }
146
+ throw error;
147
+ }
148
+ const requestId = extractRequestId(response.headers);
149
+ const durationMs = nowMs() - start;
150
+ if (response.status === 401 || response.status === 403) {
151
+ const err = new AuthenticationError(
152
+ `Authentication failed: ${response.status} ${response.statusText}`,
153
+ { requestId }
154
+ );
155
+ this.emit({
156
+ kind: "error",
157
+ method,
158
+ url,
159
+ status: response.status,
160
+ requestId,
161
+ durationMs,
162
+ message: err.message
163
+ });
164
+ throw err;
165
+ }
166
+ if (response.status === 204) {
167
+ this.emit({ kind: "response", method, url, status: 204, requestId, durationMs });
168
+ return void 0;
169
+ }
170
+ const text = await response.text();
171
+ if (!response.ok) {
172
+ let errorBody;
173
+ try {
174
+ errorBody = JSON.parse(text);
175
+ } catch {
176
+ errorBody = text;
177
+ }
178
+ const errorMessage = typeof errorBody === "object" && errorBody !== null && "error" in errorBody ? String(errorBody["error"]) : `HTTP ${response.status}`;
179
+ const err = new TransportError(
180
+ `${method} failed: ${errorMessage}`,
181
+ response.status,
182
+ errorBody,
183
+ { requestId }
184
+ );
185
+ this.emit({
186
+ kind: "error",
187
+ method,
188
+ url,
189
+ status: response.status,
190
+ requestId,
191
+ durationMs,
192
+ message: err.message
193
+ });
194
+ throw err;
195
+ }
196
+ this.emit({ kind: "response", method, url, status: response.status, requestId, durationMs });
197
+ if (!text) return void 0;
198
+ return JSON.parse(text);
199
+ }
200
+ emit(event) {
201
+ if (!this.logger) return;
202
+ try {
203
+ this.logger(event);
204
+ } catch {
205
+ }
206
+ }
207
+ buildHeaders() {
208
+ const headers = { "Content-Type": "application/json" };
209
+ const canSendUserAgent = supportsUserAgentHeader();
210
+ for (const [key, value] of Object.entries(this.headers)) {
211
+ if (key.toLowerCase() === "user-agent" && !canSendUserAgent) continue;
212
+ headers[key] = value;
213
+ }
214
+ if (canSendUserAgent && !Object.keys(headers).some((key) => key.toLowerCase() === "user-agent")) {
215
+ headers["User-Agent"] = defaultUserAgent();
216
+ }
217
+ if (this.apiKey) {
218
+ headers["Authorization"] = `Bearer ${this.apiKey}`;
219
+ }
220
+ return headers;
221
+ }
222
+ };
223
+
224
+ export { BridgeTransport, VERSION, defaultUserAgent, extractRequestId, supportsUserAgentHeader };
225
+ //# sourceMappingURL=chunk-TGBKROHO.js.map
226
+ //# sourceMappingURL=chunk-TGBKROHO.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/version.ts","../src/observability.ts","../src/transport/bridge.ts"],"names":["durationMs"],"mappings":"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","file":"chunk-TGBKROHO.js","sourcesContent":["/**\n * Package version constant. Kept in sync with package.json via a\n * dedicated version-check script run in CI. Imported by the transports to build\n * the default User-Agent header.\n */\nexport const VERSION = \"0.3.0\";\n","/**\n * Observability primitives — User-Agent header building and the typed\n * logger event stream emitted by both transports.\n */\n\nimport { VERSION } from \"./version.js\";\n\n/**\n * Build the default User-Agent string. Mirrors the convention used by other\n * Anthropic / OpenAI SDKs: `<package>/<version> (<runtime>; <platform>)`.\n *\n * Detection is best-effort and silently degrades on edge runtimes where\n * `process` is unavailable.\n */\nexport function defaultUserAgent(): string {\n const runtime = detectRuntime();\n return runtime\n ? `@neo4j-labs/agent-memory/${VERSION} (${runtime})`\n : `@neo4j-labs/agent-memory/${VERSION}`;\n}\n\nexport function supportsUserAgentHeader(): boolean {\n return detectRuntime() !== null;\n}\n\nfunction detectRuntime(): string | null {\n // Deno\n const denoObj = (globalThis as { Deno?: { version?: { deno?: string } } }).Deno;\n if (denoObj?.version?.deno) {\n return `deno/${denoObj.version.deno}`;\n }\n // Bun\n const bunObj = (globalThis as { Bun?: { version?: string } }).Bun;\n if (bunObj?.version) {\n return `bun/${bunObj.version}`;\n }\n // Node\n if (typeof process !== \"undefined\" && process.versions?.node) {\n const platform = process.platform ?? \"unknown\";\n return `node/${process.versions.node}; ${platform}`;\n }\n return null;\n}\n\n// ---------------------------------------------------------------------------\n// Logger\n// ---------------------------------------------------------------------------\n\n/** Single event emitted to the user-supplied logger. */\nexport type LogEvent =\n | {\n kind: \"request\";\n method: string;\n url: string;\n httpMethod?: string;\n }\n | {\n kind: \"response\";\n method: string;\n url: string;\n status: number;\n requestId?: string;\n durationMs: number;\n }\n | {\n kind: \"error\";\n method: string;\n url: string;\n status?: number;\n requestId?: string;\n durationMs: number;\n message: string;\n };\n\nexport type Logger = (event: LogEvent) => void;\n\n/**\n * Extract a request-id from a Response. The hosted service emits one of\n * `x-request-id`, `request-id`, or `x-amzn-RequestId` depending on the edge\n * the request lands on. Caller-side correlation works as long as one is\n * present.\n */\nexport function extractRequestId(headers: Headers): string | undefined {\n return (\n headers.get(\"x-request-id\") ??\n headers.get(\"request-id\") ??\n headers.get(\"x-amzn-requestid\") ??\n undefined\n );\n}\n","/**\n * BridgeTransport — TCK bridge protocol transport.\n *\n * Speaks the bridge wire format (POST {endpoint}/{snake_case_method}) used by\n * conformance servers and the local reference adapter. Compatible with every\n * fetch-capable runtime (Node 20+, Bun, Deno, Workers, Edge).\n */\n\nimport { AuthenticationError, ConnectionError, TransportError } from \"../errors.js\";\nimport {\n defaultUserAgent,\n extractRequestId,\n supportsUserAgentHeader,\n type Logger,\n} from \"../observability.js\";\nimport type { Transport } from \"./index.js\";\n\n/** Strip trailing `/` from a URL without using a polynomial regex. */\nfunction trimTrailingSlashes(s: string): string {\n let end = s.length;\n while (end > 0 && s.charCodeAt(end - 1) === 47) end--;\n return s.slice(0, end);\n}\n\nfunction nowMs(): number {\n if (typeof performance !== \"undefined\" && typeof performance.now === \"function\") {\n return performance.now();\n }\n return Date.now();\n}\n\nexport interface BridgeTransportOptions {\n /** Base URL of the bridge endpoint (no trailing /v1). */\n endpoint: string;\n\n /** API key for Bearer auth. Optional for local bridge servers. */\n apiKey?: string;\n\n /** Request timeout in milliseconds. Default: 30000. */\n timeout?: number;\n\n /** Additional headers to include in every request. */\n headers?: Record<string, string>;\n\n /** Per-request logger. */\n logger?: Logger;\n}\n\nexport class BridgeTransport implements Transport {\n private readonly endpoint: string;\n private readonly apiKey?: string;\n private readonly timeout: number;\n private readonly headers: Record<string, string>;\n private readonly logger?: Logger;\n\n constructor(options: BridgeTransportOptions) {\n this.endpoint = trimTrailingSlashes(options.endpoint);\n this.apiKey = options.apiKey;\n this.timeout = options.timeout ?? 30_000;\n this.headers = options.headers ?? {};\n this.logger = options.logger;\n }\n\n async connect(): Promise<void> {\n const url = `${this.endpoint}/setup`;\n const start = nowMs();\n this.emit({ kind: \"request\", method: \"connect\", url, httpMethod: \"POST\" });\n let response: Response;\n try {\n response = await fetch(url, {\n method: \"POST\",\n headers: this.buildHeaders(),\n signal: AbortSignal.timeout(this.timeout),\n });\n } catch (error) {\n const durationMs = nowMs() - start;\n if (error instanceof TypeError) {\n const err = new ConnectionError(\n `Failed to connect to ${this.endpoint}: ${(error as Error).message}`,\n { cause: error },\n );\n this.emit({ kind: \"error\", method: \"connect\", url, durationMs, message: err.message });\n throw err;\n }\n if (error instanceof DOMException && error.name === \"TimeoutError\") {\n const err = new ConnectionError(\n `Connection to ${this.endpoint} timed out after ${this.timeout}ms`,\n { cause: error },\n );\n this.emit({ kind: \"error\", method: \"connect\", url, durationMs, message: err.message });\n throw err;\n }\n throw error;\n }\n const durationMs = nowMs() - start;\n const requestId = extractRequestId(response.headers);\n if (response.status === 401 || response.status === 403) {\n const err = new AuthenticationError(\n `Authentication failed: ${response.status} ${response.statusText}`,\n { requestId },\n );\n this.emit({\n kind: \"error\",\n method: \"connect\",\n url,\n status: response.status,\n requestId,\n durationMs,\n message: err.message,\n });\n throw err;\n }\n this.emit({\n kind: \"response\",\n method: \"connect\",\n url,\n status: response.status,\n requestId,\n durationMs,\n });\n }\n\n async close(): Promise<void> {}\n\n async request<T>(method: string, params: Record<string, unknown>): Promise<T> {\n const url = `${this.endpoint}/${method}`;\n\n const body: Record<string, unknown> = {};\n for (const [key, value] of Object.entries(params)) {\n if (value !== undefined && value !== null) {\n body[key] = value;\n }\n }\n\n const start = nowMs();\n this.emit({ kind: \"request\", method, url, httpMethod: \"POST\" });\n let response: Response;\n try {\n response = await fetch(url, {\n method: \"POST\",\n headers: this.buildHeaders(),\n body: JSON.stringify(body),\n signal: AbortSignal.timeout(this.timeout),\n });\n } catch (error) {\n const durationMs = nowMs() - start;\n if (error instanceof TypeError) {\n const err = new ConnectionError(\n `Request to ${url} failed: ${(error as Error).message}`,\n { cause: error },\n );\n this.emit({ kind: \"error\", method, url, durationMs, message: err.message });\n throw err;\n }\n throw error;\n }\n\n const requestId = extractRequestId(response.headers);\n const durationMs = nowMs() - start;\n\n if (response.status === 401 || response.status === 403) {\n const err = new AuthenticationError(\n `Authentication failed: ${response.status} ${response.statusText}`,\n { requestId },\n );\n this.emit({\n kind: \"error\",\n method,\n url,\n status: response.status,\n requestId,\n durationMs,\n message: err.message,\n });\n throw err;\n }\n\n if (response.status === 204) {\n this.emit({ kind: \"response\", method, url, status: 204, requestId, durationMs });\n return undefined as T;\n }\n\n const text = await response.text();\n\n if (!response.ok) {\n let errorBody: unknown;\n try {\n errorBody = JSON.parse(text);\n } catch {\n errorBody = text;\n }\n const errorMessage =\n typeof errorBody === \"object\" && errorBody !== null && \"error\" in errorBody\n ? String((errorBody as Record<string, unknown>)[\"error\"])\n : `HTTP ${response.status}`;\n const err = new TransportError(\n `${method} failed: ${errorMessage}`,\n response.status,\n errorBody,\n { requestId },\n );\n this.emit({\n kind: \"error\",\n method,\n url,\n status: response.status,\n requestId,\n durationMs,\n message: err.message,\n });\n throw err;\n }\n\n this.emit({ kind: \"response\", method, url, status: response.status, requestId, durationMs });\n\n if (!text) return undefined as T;\n return JSON.parse(text) as T;\n }\n\n private emit(event: Parameters<Logger>[0]): void {\n if (!this.logger) return;\n try {\n this.logger(event);\n } catch {\n // Logger errors must never propagate.\n }\n }\n\n private buildHeaders(): Record<string, string> {\n const headers: Record<string, string> = { \"Content-Type\": \"application/json\" };\n const canSendUserAgent = supportsUserAgentHeader();\n for (const [key, value] of Object.entries(this.headers)) {\n if (key.toLowerCase() === \"user-agent\" && !canSendUserAgent) continue;\n headers[key] = value;\n }\n if (canSendUserAgent && !Object.keys(headers).some((key) => key.toLowerCase() === \"user-agent\")) {\n headers[\"User-Agent\"] = defaultUserAgent();\n }\n if (this.apiKey) {\n headers[\"Authorization\"] = `Bearer ${this.apiKey}`;\n }\n return headers;\n }\n}\n"]}