@xdarkicex/openclaw-memory-libravdb 1.4.6 → 1.4.7

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.
Files changed (75) hide show
  1. package/HOOK.md +14 -0
  2. package/README.md +32 -2
  3. package/dist/cli.d.ts +39 -0
  4. package/dist/cli.js +208 -0
  5. package/dist/context-engine.d.ts +56 -0
  6. package/dist/context-engine.js +125 -0
  7. package/dist/dream-promotion.d.ts +47 -0
  8. package/dist/dream-promotion.js +363 -0
  9. package/dist/dream-routing.d.ts +6 -0
  10. package/dist/dream-routing.js +31 -0
  11. package/dist/durable-namespace.d.ts +6 -0
  12. package/dist/durable-namespace.js +24 -0
  13. package/dist/grpc-client.d.ts +23 -0
  14. package/dist/grpc-client.js +104 -0
  15. package/dist/index.d.ts +10 -0
  16. package/dist/index.js +40 -0
  17. package/dist/lifecycle-hooks.d.ts +4 -0
  18. package/dist/lifecycle-hooks.js +64 -0
  19. package/dist/markdown-hash.d.ts +3 -0
  20. package/dist/markdown-hash.js +82 -0
  21. package/dist/markdown-ingest.d.ts +43 -0
  22. package/dist/markdown-ingest.js +464 -0
  23. package/dist/memory-provider.d.ts +4 -0
  24. package/dist/memory-provider.js +13 -0
  25. package/dist/memory-runtime.d.ts +118 -0
  26. package/dist/memory-runtime.js +217 -0
  27. package/dist/plugin-runtime.d.ts +28 -0
  28. package/dist/plugin-runtime.js +127 -0
  29. package/dist/proto/intelligence_kernel/v1/kernel.proto +378 -0
  30. package/dist/recall-cache.d.ts +2 -0
  31. package/dist/recall-cache.js +30 -0
  32. package/dist/rpc-protobuf-codecs.d.ts +70 -0
  33. package/dist/rpc-protobuf-codecs.js +77 -0
  34. package/dist/rpc.d.ts +14 -0
  35. package/dist/rpc.js +121 -0
  36. package/dist/sidecar.d.ts +34 -0
  37. package/dist/sidecar.js +535 -0
  38. package/dist/types.d.ts +163 -0
  39. package/dist/types.js +1 -0
  40. package/docs/contributing.md +14 -13
  41. package/docs/install.md +7 -9
  42. package/docs/installation.md +23 -16
  43. package/docs/uninstall.md +1 -1
  44. package/index.js +2 -0
  45. package/openclaw.plugin.json +2 -2
  46. package/package.json +39 -16
  47. package/packaging/README.md +0 -71
  48. package/packaging/homebrew/libravdbd.rb.tmpl +0 -224
  49. package/packaging/launchd/com.xdarkicex.libravdbd.plist +0 -32
  50. package/packaging/systemd/libravdbd.service +0 -12
  51. package/src/cli.ts +0 -299
  52. package/src/comparison-experiments.ts +0 -128
  53. package/src/context-engine.ts +0 -1645
  54. package/src/continuity.ts +0 -93
  55. package/src/dream-promotion.ts +0 -492
  56. package/src/dream-routing.ts +0 -40
  57. package/src/durable-namespace.ts +0 -34
  58. package/src/index.ts +0 -47
  59. package/src/lifecycle-hooks.ts +0 -96
  60. package/src/markdown-hash.ts +0 -104
  61. package/src/markdown-ingest.ts +0 -627
  62. package/src/memory-provider.ts +0 -25
  63. package/src/memory-runtime.ts +0 -283
  64. package/src/openclaw-plugin-sdk.d.ts +0 -59
  65. package/src/plugin-runtime.ts +0 -119
  66. package/src/recall-cache.ts +0 -34
  67. package/src/recall-utils.ts +0 -131
  68. package/src/rpc.ts +0 -92
  69. package/src/scoring.ts +0 -632
  70. package/src/sidecar.ts +0 -583
  71. package/src/temporal.ts +0 -1031
  72. package/src/tokens.ts +0 -52
  73. package/src/types.ts +0 -278
  74. package/tsconfig.json +0 -20
  75. package/tsconfig.tests.json +0 -12
package/src/sidecar.ts DELETED
@@ -1,583 +0,0 @@
1
- import fs from "node:fs";
2
- import net from "node:net";
3
- import os from "node:os";
4
- import path from "node:path";
5
-
6
- import type { LoggerLike, PluginConfig, SidecarHandle, SidecarSocket } from "./types.js";
7
-
8
- type CloseHandler = () => void;
9
- type DataHandler = (chunk: string) => void;
10
- type ErrorHandler = (error: Error) => void;
11
-
12
- const STARTUP_CONNECT_MAX_RETRIES = 5;
13
- const STARTUP_CONNECT_BASE_DELAY_MS = 100;
14
- const STARTUP_CONNECT_MAX_TOTAL_WAIT_MS = 2000;
15
-
16
- export interface SidecarRuntime {
17
- resolveEndpoint(cfg: PluginConfig): string | Promise<string>;
18
- createSocket(endpoint: string): SidecarSocket;
19
- scheduleRestart(delayMs: number, restart: () => void): void;
20
- }
21
-
22
- class PlaceholderSocket implements SidecarSocket {
23
- private readonly onData = new Set<DataHandler>();
24
- private readonly onClose = new Set<CloseHandler>();
25
- private readonly onError = new Set<ErrorHandler>();
26
- private readonly connectOnce = new Set<CloseHandler>();
27
- private readonly errorOnce = new Set<ErrorHandler>();
28
-
29
- constructor() {
30
- queueMicrotask(() => {
31
- for (const handler of this.connectOnce) {
32
- handler();
33
- }
34
- this.connectOnce.clear();
35
- });
36
- }
37
-
38
- setEncoding(_encoding: string): void {}
39
-
40
- on(event: "data" | "close" | "error", handler: DataHandler | CloseHandler | ErrorHandler): void {
41
- if (event === "data") {
42
- this.onData.add(handler as DataHandler);
43
- return;
44
- }
45
- if (event === "error") {
46
- this.onError.add(handler as ErrorHandler);
47
- return;
48
- }
49
- this.onClose.add(handler as CloseHandler);
50
- }
51
-
52
- once(event: "connect" | "error", handler: CloseHandler | ErrorHandler): void {
53
- if (event === "connect") {
54
- this.connectOnce.add(handler as CloseHandler);
55
- return;
56
- }
57
- this.errorOnce.add(handler as ErrorHandler);
58
- }
59
-
60
- write(chunk: string): void {
61
- try {
62
- const msg = JSON.parse(chunk);
63
- const response = JSON.stringify({
64
- jsonrpc: "2.0",
65
- id: msg.id,
66
- result: msg.method === "health" ? { ok: true } : {},
67
- });
68
- for (const handler of this.onData) {
69
- handler(`${response}\n`);
70
- }
71
- } catch (error) {
72
- const err = error instanceof Error ? error : new Error(String(error));
73
- this.emitError(err);
74
- }
75
- }
76
-
77
- destroy(): void {
78
- for (const handler of this.onClose) {
79
- handler();
80
- }
81
- }
82
-
83
- private emitError(error: Error): void {
84
- for (const handler of this.onError) {
85
- handler(error);
86
- }
87
- for (const handler of this.errorOnce) {
88
- handler(error);
89
- }
90
- this.errorOnce.clear();
91
- }
92
- }
93
-
94
- class SupervisorSocket implements SidecarSocket {
95
- private readonly onData = new Set<DataHandler>();
96
- private readonly onClose = new Set<CloseHandler>();
97
- private readonly onError = new Set<ErrorHandler>();
98
- private readonly connectOnce = new Set<CloseHandler>();
99
- private readonly errorOnce = new Set<ErrorHandler>();
100
- private current?: SidecarSocket;
101
- private encoding = "utf8";
102
- private generation = 0;
103
-
104
- bind(socket: SidecarSocket): void {
105
- this.current = socket;
106
- this.generation += 1;
107
- const generation = this.generation;
108
-
109
- socket.setEncoding(this.encoding);
110
- socket.on("data", (chunk) => {
111
- if (generation !== this.generation) {
112
- return;
113
- }
114
- for (const handler of this.onData) {
115
- handler(chunk);
116
- }
117
- });
118
- socket.on("close", () => {
119
- if (generation !== this.generation) {
120
- return;
121
- }
122
- this.current = undefined;
123
- for (const handler of this.onClose) {
124
- handler();
125
- }
126
- });
127
- socket.on("error", (error) => {
128
- if (generation !== this.generation) {
129
- return;
130
- }
131
- this.current = undefined;
132
- for (const handler of this.onError) {
133
- handler(error);
134
- }
135
- for (const handler of this.errorOnce) {
136
- handler(error);
137
- }
138
- this.errorOnce.clear();
139
- });
140
-
141
- for (const handler of this.connectOnce) {
142
- handler();
143
- }
144
- this.connectOnce.clear();
145
- }
146
-
147
- setEncoding(encoding: string): void {
148
- this.encoding = encoding;
149
- this.current?.setEncoding(encoding);
150
- }
151
-
152
- on(event: "data" | "close" | "error", handler: DataHandler | CloseHandler | ErrorHandler): void {
153
- if (event === "data") {
154
- this.onData.add(handler as DataHandler);
155
- return;
156
- }
157
- if (event === "error") {
158
- this.onError.add(handler as ErrorHandler);
159
- return;
160
- }
161
- this.onClose.add(handler as CloseHandler);
162
- }
163
-
164
- once(event: "connect" | "error", handler: CloseHandler | ErrorHandler): void {
165
- if (event === "connect") {
166
- if (this.current) {
167
- (handler as CloseHandler)();
168
- return;
169
- }
170
- this.connectOnce.add(handler as CloseHandler);
171
- return;
172
- }
173
- this.errorOnce.add(handler as ErrorHandler);
174
- }
175
-
176
- write(chunk: string): void {
177
- if (!this.current) {
178
- throw new Error("Sidecar socket unavailable");
179
- }
180
- this.current.write(chunk);
181
- }
182
-
183
- destroy(): void {
184
- this.current?.destroy();
185
- }
186
- }
187
-
188
- class SidecarSupervisor implements SidecarHandle {
189
- private retries = 0;
190
- private degraded = false;
191
- private shuttingDown = false;
192
- private reconnectScheduled = false;
193
- public socket: SidecarSocket;
194
-
195
- constructor(
196
- private readonly cfg: PluginConfig,
197
- private readonly logger: LoggerLike,
198
- private readonly runtime: SidecarRuntime,
199
- ) {
200
- this.socket = new SupervisorSocket();
201
- }
202
-
203
- async start(): Promise<SidecarSocket> {
204
- const endpoint = await this.runtime.resolveEndpoint(this.cfg);
205
- const socket = await this.connectEndpointWithRetry(endpoint);
206
- this.reconnectScheduled = false;
207
- if (this.socket instanceof SupervisorSocket) {
208
- this.socket.bind(socket);
209
- } else {
210
- this.socket = socket;
211
- }
212
- return socket;
213
- }
214
-
215
- isDegraded(): boolean {
216
- return this.degraded;
217
- }
218
-
219
- async shutdown(): Promise<void> {
220
- this.shuttingDown = true;
221
- this.socket.destroy();
222
- }
223
-
224
- private async connectEndpointWithRetry(endpoint: string): Promise<SidecarSocket> {
225
- if (isTcpEndpoint(endpoint)) {
226
- this.logger.info?.(`[libravdb] using TCP endpoint ${endpoint}`);
227
- } else {
228
- this.logger.info?.(`[libravdb] using Unix socket ${endpoint}`);
229
- }
230
-
231
- let waitedMs = 0;
232
- for (let attempt = 0; ; attempt += 1) {
233
- try {
234
- return await this.connectEndpoint(endpoint);
235
- } catch (error) {
236
- if (!isStartupConnectRetryableError(error) || attempt >= STARTUP_CONNECT_MAX_RETRIES - 1) {
237
- throw error;
238
- }
239
-
240
- const delayMs = computeStartupConnectRetryDelay(attempt, waitedMs);
241
- if (delayMs <= 0) {
242
- throw error;
243
- }
244
- waitedMs += delayMs;
245
- this.logger.info?.(
246
- `[libravdb] Daemon not ready, retrying connection (attempt ${attempt + 1}/${STARTUP_CONNECT_MAX_RETRIES})...`,
247
- );
248
- await sleep(delayMs);
249
- }
250
- }
251
- }
252
-
253
- private async connectEndpoint(endpoint: string): Promise<SidecarSocket> {
254
- const socket = this.runtime.createSocket(endpoint);
255
- return await new Promise<SidecarSocket>((resolve, reject) => {
256
- socket.once("connect", () => {
257
- socket.on("close", () => {
258
- void this.handleExit(1);
259
- });
260
- resolve(socket);
261
- });
262
- socket.once("error", (error) => {
263
- socket.destroy();
264
- reject(formatConnectionError(endpoint, error));
265
- });
266
- });
267
- }
268
-
269
- private async handleExit(code: number | null): Promise<void> {
270
- if (this.shuttingDown) {
271
- return;
272
- }
273
- if (code === 0) {
274
- return;
275
- }
276
- if (this.reconnectScheduled) {
277
- return;
278
- }
279
-
280
- const maxRetries = this.cfg.maxRetries ?? 3;
281
- if (this.retries >= maxRetries) {
282
- this.logger.error("[libravdb] sidecar retries exhausted; degraded mode");
283
- this.degraded = true;
284
- return;
285
- }
286
-
287
- const backoffMs = computeBackoffMs(this.retries);
288
- this.retries += 1;
289
- this.reconnectScheduled = true;
290
- this.runtime.scheduleRestart(backoffMs, () => {
291
- void this.start().catch((error) => {
292
- this.reconnectScheduled = false;
293
- const message = error instanceof Error ? error.message : String(error);
294
- this.logger.error(`[libravdb] sidecar reconnect failed: ${message}`);
295
- });
296
- });
297
- }
298
- }
299
-
300
- export async function startSidecar(
301
- cfg: PluginConfig,
302
- logger: LoggerLike = console,
303
- runtime: SidecarRuntime = createDefaultRuntime(),
304
- ): Promise<SidecarHandle> {
305
- const supervisor = new SidecarSupervisor(cfg, logger, runtime);
306
- await supervisor.start();
307
- return supervisor;
308
- }
309
-
310
- export function computeBackoffMs(retries: number): number {
311
- return Math.min(500 * Math.pow(2, retries), 16000);
312
- }
313
-
314
- export function computeStartupConnectRetryDelay(attempt: number, waitedMs = 0): number {
315
- if (attempt < 0) {
316
- return 0;
317
- }
318
- const remainingMs = STARTUP_CONNECT_MAX_TOTAL_WAIT_MS - waitedMs;
319
- if (remainingMs <= 0) {
320
- return 0;
321
- }
322
- return Math.min(STARTUP_CONNECT_BASE_DELAY_MS * Math.pow(2, attempt), remainingMs);
323
- }
324
-
325
- export function isTcpEndpoint(endpoint: string): boolean {
326
- return endpoint.startsWith("tcp:");
327
- }
328
-
329
- export function resolveEndpoint(cfg: PluginConfig): string {
330
- const endpoint = resolveConfiguredEndpoint(cfg);
331
- return endpoint.replace(/^unix:/, "");
332
- }
333
-
334
- export function resolveConfiguredEndpoint(cfg: PluginConfig): string {
335
- const value = cfg.sidecarPath?.trim();
336
- if (!value || value === "auto") {
337
- return defaultEndpoint();
338
- }
339
- if (!isConfiguredEndpoint(value)) {
340
- throw new Error(
341
- `LibraVDB sidecarPath must be a daemon endpoint like unix:/path/to/libravdb.sock or tcp:127.0.0.1:37421. Executable paths are no longer supported.`,
342
- );
343
- }
344
- return value;
345
- }
346
-
347
- export function daemonProvisioningHint(): string {
348
- return "If you installed the npm package, install and start libravdbd separately; the package does not provision the daemon binary, ONNX Runtime, or model assets.";
349
- }
350
-
351
- export function defaultEndpoint(platform = process.platform, homeDir = os.homedir()): string {
352
- // Honour the daemon's own env var first (set by Homebrew LaunchAgent / systemd unit).
353
- const envEndpoint = process.env.LIBRAVDB_RPC_ENDPOINT?.trim();
354
- if (envEndpoint && isConfiguredEndpoint(envEndpoint)) {
355
- return envEndpoint;
356
- }
357
-
358
- if (platform === "win32") {
359
- return "tcp:127.0.0.1:37421";
360
- }
361
-
362
- const sockName = "libravdb.sock";
363
- const candidateDirs = [
364
- // User-local (npm plugin convention)
365
- homeDir?.trim() ? path.join(homeDir, ".clawdb", "run") : null,
366
- // Homebrew (Apple Silicon) — matches the Homebrew formula LaunchAgent
367
- "/opt/homebrew/var/clawdb/run",
368
- // Homebrew (Intel Mac) / manual Linux installs
369
- "/usr/local/var/clawdb/run",
370
- ].filter((d): d is string => d !== null);
371
-
372
- for (const dir of candidateDirs) {
373
- const sockPath = path.join(dir, sockName);
374
- try {
375
- if (fs.existsSync(sockPath)) {
376
- return `unix:${sockPath}`;
377
- }
378
- } catch {
379
- // Permission error or similar — skip this candidate.
380
- }
381
- }
382
-
383
- // Fallback to the original user-local path so error messages stay familiar.
384
- const baseDir = homeDir?.trim()
385
- ? path.join(homeDir, ".clawdb", "run")
386
- : path.join(".", ".clawdb", "run");
387
- return `unix:${path.join(baseDir, sockName)}`;
388
- }
389
-
390
- export function buildSidecarEnv(cfg: PluginConfig): Record<string, string> {
391
- const env: Record<string, string> = {};
392
-
393
- if (cfg.dbPath) {
394
- env.LIBRAVDB_DB_PATH = cfg.dbPath;
395
- }
396
- if (cfg.embeddingRuntimePath) {
397
- env.LIBRAVDB_ONNX_RUNTIME = cfg.embeddingRuntimePath;
398
- }
399
- if (cfg.embeddingBackend) {
400
- env.LIBRAVDB_EMBEDDING_BACKEND = cfg.embeddingBackend;
401
- }
402
- if (cfg.embeddingProfile) {
403
- env.LIBRAVDB_EMBEDDING_PROFILE = cfg.embeddingProfile;
404
- }
405
- if (cfg.fallbackProfile) {
406
- env.LIBRAVDB_FALLBACK_PROFILE = cfg.fallbackProfile;
407
- }
408
- if (cfg.embeddingModelPath) {
409
- env.LIBRAVDB_EMBEDDING_MODEL = cfg.embeddingModelPath;
410
- }
411
- if (cfg.embeddingTokenizerPath) {
412
- env.LIBRAVDB_EMBEDDING_TOKENIZER = cfg.embeddingTokenizerPath;
413
- }
414
- if (typeof cfg.embeddingDimensions === "number" && cfg.embeddingDimensions > 0) {
415
- env.LIBRAVDB_EMBEDDING_DIMENSIONS = String(cfg.embeddingDimensions);
416
- }
417
- if (typeof cfg.embeddingNormalize === "boolean") {
418
- env.LIBRAVDB_EMBEDDING_NORMALIZE = String(cfg.embeddingNormalize);
419
- }
420
- if (cfg.summarizerBackend) {
421
- env.LIBRAVDB_SUMMARIZER_BACKEND = cfg.summarizerBackend;
422
- }
423
- if (cfg.summarizerProfile) {
424
- env.LIBRAVDB_SUMMARIZER_PROFILE = cfg.summarizerProfile;
425
- }
426
- if (cfg.summarizerRuntimePath) {
427
- env.LIBRAVDB_SUMMARIZER_RUNTIME = cfg.summarizerRuntimePath;
428
- }
429
- if (cfg.summarizerModelPath) {
430
- env.LIBRAVDB_SUMMARIZER_MODEL_PATH = cfg.summarizerModelPath;
431
- }
432
- if (cfg.summarizerTokenizerPath) {
433
- env.LIBRAVDB_SUMMARIZER_TOKENIZER = cfg.summarizerTokenizerPath;
434
- }
435
- if (cfg.summarizerModel) {
436
- env.LIBRAVDB_SUMMARIZER_MODEL = cfg.summarizerModel;
437
- }
438
- if (cfg.summarizerEndpoint) {
439
- env.LIBRAVDB_SUMMARIZER_ENDPOINT = cfg.summarizerEndpoint;
440
- }
441
- if (cfg.ollamaUrl && !env.LIBRAVDB_SUMMARIZER_ENDPOINT) {
442
- env.LIBRAVDB_SUMMARIZER_ENDPOINT = cfg.ollamaUrl;
443
- }
444
- if (cfg.compactModel && !env.LIBRAVDB_SUMMARIZER_MODEL) {
445
- env.LIBRAVDB_SUMMARIZER_MODEL = cfg.compactModel;
446
- }
447
- if (cfg.gatingWeights?.w1c != null) {
448
- env.LIBRAVDB_GATING_W1C = String(cfg.gatingWeights.w1c);
449
- }
450
- if (cfg.gatingWeights?.w2c != null) {
451
- env.LIBRAVDB_GATING_W2C = String(cfg.gatingWeights.w2c);
452
- }
453
- if (cfg.gatingWeights?.w3c != null) {
454
- env.LIBRAVDB_GATING_W3C = String(cfg.gatingWeights.w3c);
455
- }
456
- if (cfg.gatingWeights?.w1t != null) {
457
- env.LIBRAVDB_GATING_W1T = String(cfg.gatingWeights.w1t);
458
- }
459
- if (cfg.gatingWeights?.w2t != null) {
460
- env.LIBRAVDB_GATING_W2T = String(cfg.gatingWeights.w2t);
461
- }
462
- if (cfg.gatingWeights?.w3t != null) {
463
- env.LIBRAVDB_GATING_W3T = String(cfg.gatingWeights.w3t);
464
- }
465
- if (typeof cfg.gatingTechNorm === "number" && cfg.gatingTechNorm > 0) {
466
- env.LIBRAVDB_GATING_TECH_NORM = String(cfg.gatingTechNorm);
467
- }
468
- if (typeof cfg.ingestionGateThreshold === "number" && cfg.ingestionGateThreshold >= 0) {
469
- env.LIBRAVDB_GATING_THRESHOLD = String(cfg.ingestionGateThreshold);
470
- }
471
- if (typeof cfg.gatingCentroidK === "number" && cfg.gatingCentroidK > 0) {
472
- env.LIBRAVDB_GATING_CENTROID_K = String(cfg.gatingCentroidK);
473
- }
474
- if (typeof cfg.lifecycleJournalMaxEntries === "number" && cfg.lifecycleJournalMaxEntries > 0) {
475
- env.LIBRAVDB_LIFECYCLE_JOURNAL_MAX_ENTRIES = String(cfg.lifecycleJournalMaxEntries);
476
- }
477
-
478
- return env;
479
- }
480
-
481
- function createDefaultRuntime(): SidecarRuntime {
482
- return {
483
- resolveEndpoint(cfg) {
484
- return resolveEndpoint(cfg);
485
- },
486
- createSocket(endpoint) {
487
- if (isTcpEndpoint(endpoint)) {
488
- const address = endpoint.slice("tcp:".length);
489
- const separator = address.lastIndexOf(":");
490
- if (separator <= 0) {
491
- throw new Error(`Invalid TCP sidecar endpoint: ${endpoint}`);
492
- }
493
- return net.connect({
494
- host: address.slice(0, separator),
495
- port: Number(address.slice(separator + 1)),
496
- }) as unknown as SidecarSocket;
497
- }
498
- return net.connect(endpoint) as unknown as SidecarSocket;
499
- },
500
- scheduleRestart(delayMs, restart) {
501
- setTimeout(restart, delayMs);
502
- },
503
- };
504
- }
505
-
506
- function isStartupConnectRetryableError(error: unknown): boolean {
507
- const code = typeof (error as NodeJS.ErrnoException | undefined)?.code === "string"
508
- ? (error as NodeJS.ErrnoException).code
509
- : "";
510
- return code === "ENOENT" || code === "ECONNREFUSED";
511
- }
512
-
513
- function formatConnectionError(endpoint: string, error: Error): Error {
514
- const code = typeof (error as NodeJS.ErrnoException).code === "string"
515
- ? (error as NodeJS.ErrnoException).code
516
- : "";
517
- const annotated = error instanceof Error ? error : new Error(String(error));
518
- if (code) {
519
- (annotated as NodeJS.ErrnoException).code = code;
520
- }
521
- if (code === "ENOENT" || code === "ECONNREFUSED") {
522
- const unavailable = new Error(
523
- `LibraVDB daemon unavailable at ${describeEndpoint(endpoint)}. ${daemonProvisioningHint()} Or set sidecarPath to a running daemon endpoint.`,
524
- );
525
- (unavailable as NodeJS.ErrnoException).code = code;
526
- return unavailable;
527
- }
528
- return annotated;
529
- }
530
-
531
- function describeEndpoint(endpoint: string): string {
532
- if (isTcpEndpoint(endpoint)) {
533
- return endpoint;
534
- }
535
- return `unix:${endpoint}`;
536
- }
537
-
538
- function isConfiguredEndpoint(value?: string): boolean {
539
- return value?.startsWith("tcp:") === true || value?.startsWith("unix:") === true;
540
- }
541
-
542
- export { PlaceholderSocket };
543
-
544
- function sleep(delayMs: number): Promise<void> {
545
- return new Promise((resolve) => setTimeout(resolve, delayMs));
546
- }
547
-
548
- export async function probeSidecarEndpoint(cfg: PluginConfig): Promise<string | null> {
549
- const endpoint = resolveConfiguredEndpoint(cfg);
550
- try {
551
- await new Promise<void>((resolve, reject) => {
552
- if (isTcpEndpoint(endpoint)) {
553
- const address = endpoint.slice("tcp:".length);
554
- const separator = address.lastIndexOf(":");
555
- if (separator <= 0) {
556
- reject(new Error("invalid tcp endpoint"));
557
- return;
558
- }
559
- const host = address.slice(0, separator);
560
- const port = Number(address.slice(separator + 1));
561
- const socket = net.connect({ host, port }, () => {
562
- socket.destroy();
563
- resolve();
564
- });
565
- socket.setTimeout(500);
566
- socket.on("error", reject);
567
- socket.on("timeout", reject);
568
- } else {
569
- const socketPath = endpoint.replace(/^unix:/, "");
570
- const socket = net.connect(socketPath, () => {
571
- socket.destroy();
572
- resolve();
573
- });
574
- socket.setTimeout(500);
575
- socket.on("error", reject);
576
- socket.on("timeout", reject);
577
- }
578
- });
579
- return endpoint;
580
- } catch {
581
- return null;
582
- }
583
- }