@geravant/sinain 1.22.6 → 1.22.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.
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@geravant/sinain",
3
- "version": "1.22.6",
3
+ "version": "1.22.7",
4
4
  "description": "Ambient intelligence that sees what you see, hears what you hear, and acts on your behalf",
5
5
  "type": "module",
6
6
  "bin": {
@@ -60,14 +60,7 @@ async function queryKnowledgeFactsMulti(entities: string[], maxFacts: number): P
60
60
  `${workspaceDir}/knowledge-graph.db`,
61
61
  ];
62
62
 
63
- // Candidate script paths
64
- const __dir = dirname(fileURLToPath(import.meta.url));
65
- const scriptCandidates = [
66
- resolve(__dir, "..", "..", "sinain-hud-plugin", "sinain-memory", "graph_query.py"),
67
- resolve(__dir, "..", "sinain-memory", "graph_query.py"),
68
- `${resolveWorkspace()}/sinain-memory/graph_query.py`,
69
- ];
70
- const scriptPath = scriptCandidates.find(p => existsSync(p)) || scriptCandidates[0];
63
+ const scriptPath = resolveSinainMemoryScript("graph_query.py");
71
64
 
72
65
  // Step 1: Get candidates from Python (RRF-ranked, no embedding — avoids deadlock)
73
66
  // Request 2x candidates in JSON for re-ranking in Node.js
@@ -142,13 +135,7 @@ async function listKnowledgeEntitiesMulti(max: number): Promise<string> {
142
135
  `${workspaceDir}/knowledge-graph.db`,
143
136
  ];
144
137
 
145
- const __dir = dirname(fileURLToPath(import.meta.url));
146
- const scriptCandidates = [
147
- resolve(__dir, "..", "..", "sinain-hud-plugin", "sinain-memory", "graph_query.py"),
148
- resolve(__dir, "..", "sinain-memory", "graph_query.py"),
149
- `${resolveWorkspace()}/sinain-memory/graph_query.py`,
150
- ];
151
- const scriptPath = scriptCandidates.find(p => existsSync(p)) || scriptCandidates[0];
138
+ const scriptPath = resolveSinainMemoryScript("graph_query.py");
152
139
 
153
140
  const allFacts: any[] = [];
154
141
  for (const dbPath of dbPaths) {
@@ -174,17 +161,33 @@ async function listKnowledgeEntitiesMulti(max: number): Promise<string> {
174
161
  return JSON.stringify(unique.slice(0, max));
175
162
  }
176
163
 
177
- /** Resolve graph_query.py script path. Used by all knowledge-graph subprocess calls. */
178
- function resolveGraphQueryScript(): string {
164
+ /**
165
+ * Resolve a Python script under sinain-memory/. Two layouts are supported:
166
+ *
167
+ * - **dev repo**: code is at `<repo>/sinain-core/src/index.ts`, scripts at
168
+ * `<repo>/sinain-hud-plugin/sinain-memory/<name>` (so `__dir/../../sinain-hud-plugin/sinain-memory`).
169
+ * - **npm-installed**: code is at `node_modules/@geravant/sinain/sinain-core/src/index.ts`,
170
+ * scripts at `node_modules/@geravant/sinain/sinain-memory/<name>` (so `__dir/../../sinain-memory`).
171
+ *
172
+ * Plus a workspace fallback for OpenClaw layouts. ENOENT on the resolved
173
+ * path was Irina's bug — the npm path was missing from candidates.
174
+ */
175
+ function resolveSinainMemoryScript(scriptName: string): string {
179
176
  const __dir = new URL(import.meta.url).pathname.replace(/\/[^/]+$/, "");
180
177
  const candidates = [
181
- `${__dir}/../../sinain-hud-plugin/sinain-memory/graph_query.py`,
182
- `${__dir}/../sinain-memory/graph_query.py`,
183
- `${resolveWorkspace()}/sinain-memory/graph_query.py`,
178
+ `${__dir}/../../sinain-hud-plugin/sinain-memory/${scriptName}`, // dev repo
179
+ `${__dir}/../../sinain-memory/${scriptName}`, // npm install
180
+ `${__dir}/../sinain-memory/${scriptName}`, // legacy
181
+ `${resolveWorkspace()}/sinain-memory/${scriptName}`, // openclaw workspace
184
182
  ];
185
183
  return candidates.find(p => existsSync(p)) || candidates[0];
186
184
  }
187
185
 
186
+ /** Backward-compat alias used by legacy call sites. */
187
+ function resolveGraphQueryScript(): string {
188
+ return resolveSinainMemoryScript("graph_query.py");
189
+ }
190
+
188
191
  /** List of candidate knowledge DB paths (local + workspace). */
189
192
  function resolveKnowledgeDbPaths(): string[] {
190
193
  return [
@@ -237,13 +240,7 @@ async function exportConceptBundle(
237
240
  const { execFile } = await import("node:child_process");
238
241
  const { promisify } = await import("node:util");
239
242
  const pExecFile = promisify(execFile);
240
- const __dir = new URL(import.meta.url).pathname.replace(/\/[^/]+$/, "");
241
- const scriptCandidates = [
242
- `${__dir}/../../sinain-hud-plugin/sinain-memory/concept_export.py`,
243
- `${__dir}/../sinain-memory/concept_export.py`,
244
- `${resolveWorkspace()}/sinain-memory/concept_export.py`,
245
- ];
246
- const scriptPath = scriptCandidates.find(p => existsSync(p)) || scriptCandidates[0];
243
+ const scriptPath = resolveSinainMemoryScript("concept_export.py");
247
244
  const webDbPath = `${resolveLocalMemoryDir()}/web.db`;
248
245
 
249
246
  for (const dbPath of resolveKnowledgeDbPaths()) {
@@ -286,13 +283,7 @@ async function importConceptBundle(
286
283
  const { execFile } = await import("node:child_process");
287
284
  const { promisify } = await import("node:util");
288
285
  const pExecFile = promisify(execFile);
289
- const __dir = new URL(import.meta.url).pathname.replace(/\/[^/]+$/, "");
290
- const scriptCandidates = [
291
- `${__dir}/../../sinain-hud-plugin/sinain-memory/concept_import.py`,
292
- `${__dir}/../sinain-memory/concept_import.py`,
293
- `${resolveWorkspace()}/sinain-memory/concept_import.py`,
294
- ];
295
- const scriptPath = scriptCandidates.find(p => existsSync(p)) || scriptCandidates[0];
286
+ const scriptPath = resolveSinainMemoryScript("concept_import.py");
296
287
  const localDir = resolveLocalMemoryDir();
297
288
  const dbPath = `${localDir}/knowledge-graph.db`;
298
289
  const webDbPath = `${localDir}/web.db`;
@@ -336,13 +327,7 @@ async function retractOrRestoreFact(
336
327
  const { execFile } = await import("node:child_process");
337
328
  const { promisify } = await import("node:util");
338
329
  const pExecFile = promisify(execFile);
339
- const __dir = new URL(import.meta.url).pathname.replace(/\/[^/]+$/, "");
340
- const scriptCandidates = [
341
- `${__dir}/../../sinain-hud-plugin/sinain-memory/retract.py`,
342
- `${__dir}/../sinain-memory/retract.py`,
343
- `${resolveWorkspace()}/sinain-memory/retract.py`,
344
- ];
345
- const scriptPath = scriptCandidates.find(p => existsSync(p)) || scriptCandidates[0];
330
+ const scriptPath = resolveSinainMemoryScript("retract.py");
346
331
  const webDbPath = `${resolveLocalMemoryDir()}/web.db`;
347
332
 
348
333
  // Try DBs in order — the fact lives in one of them.
@@ -383,13 +368,7 @@ async function renderEntityPageMulti(
383
368
  const { execFile } = await import("node:child_process");
384
369
  const { promisify } = await import("node:util");
385
370
  const pExecFile = promisify(execFile);
386
- const __dir = new URL(import.meta.url).pathname.replace(/\/[^/]+$/, "");
387
- const scriptCandidates = [
388
- `${__dir}/../../sinain-hud-plugin/sinain-memory/page_renderer.py`,
389
- `${__dir}/../sinain-memory/page_renderer.py`,
390
- `${resolveWorkspace()}/sinain-memory/page_renderer.py`,
391
- ];
392
- const scriptPath = scriptCandidates.find(p => existsSync(p)) || scriptCandidates[0];
371
+ const scriptPath = resolveSinainMemoryScript("page_renderer.py");
393
372
  const webDbPath = `${resolveLocalMemoryDir()}/web.db`;
394
373
 
395
374
  // Try DBs in order; first one with the entity wins.
@@ -456,10 +435,12 @@ async function queryKnowledgeAsOfMulti(entity: string, date: string): Promise<st
456
435
  `${workspaceDir}/knowledge-graph.db`,
457
436
  ];
458
437
 
438
+ const __dir = dirname(new URL(import.meta.url).pathname);
459
439
  const scriptCandidates = [
460
- `${dirname(new URL(import.meta.url).pathname)}/../sinain-hud-plugin/sinain-memory`,
461
- `${dirname(new URL(import.meta.url).pathname)}/sinain-memory`,
462
- `${resolveWorkspace()}/sinain-memory`,
440
+ `${__dir}/../../sinain-hud-plugin/sinain-memory`, // dev repo
441
+ `${__dir}/../../sinain-memory`, // npm install
442
+ `${__dir}/../sinain-memory`, // legacy
443
+ `${resolveWorkspace()}/sinain-memory`, // workspace
463
444
  ];
464
445
  const scriptsDir = scriptCandidates.find(p => existsSync(`${p}/triplestore.py`)) || scriptCandidates[0];
465
446
 
@@ -499,12 +480,7 @@ async function exportKnowledgeMulti(domain: string | null, max: number): Promise
499
480
  `${workspaceDir}/knowledge-graph.db`,
500
481
  ];
501
482
 
502
- const __dir = dirname(fileURLToPath(import.meta.url));
503
- const scriptCandidates = [
504
- resolve(__dir, "..", "..", "sinain-hud-plugin", "sinain-memory", "graph_query.py"),
505
- `${resolveWorkspace()}/sinain-memory/graph_query.py`,
506
- ];
507
- const scriptPath = scriptCandidates.find(p => existsSync(p)) || scriptCandidates[0];
483
+ const scriptPath = resolveSinainMemoryScript("graph_query.py");
508
484
 
509
485
  const allFacts: any[] = [];
510
486
  for (const dbPath of dbPaths) {
@@ -749,6 +749,15 @@ const ShareManager = (() => {
749
749
  body: msg.payload,
750
750
  });
751
751
  console.log("[sinain-share:recipient] import response:", importR);
752
+ // CRITICAL: api() doesn't throw on {ok:false} responses — it
753
+ // returns the parsed body. We MUST check ok explicitly here, or
754
+ // a backend failure (script ENOENT, schema error, etc.) appears
755
+ // to the SPA as success and falls through to MissingConcept.
756
+ if (importR && importR.ok === false) {
757
+ cleanup();
758
+ reject(new Error(importR.error || "import failed"));
759
+ return;
760
+ }
752
761
  conn.send({ type: "ack" });
753
762
  setTimeout(cleanup, 500);
754
763
  resolve(importR);