@digitalforgestudios/openclaw-sulcus 3.5.2 → 3.5.4
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/index.ts +40 -45
- package/package.json +1 -1
package/index.ts
CHANGED
|
@@ -213,7 +213,7 @@ class SulcusCloudClient {
|
|
|
213
213
|
async search_memory(query: string, limit?: number): Promise<{ results: any[] }> {
|
|
214
214
|
const body: any = { query };
|
|
215
215
|
if (limit !== undefined) body.limit = limit;
|
|
216
|
-
const res = await this.request("POST", "/agent/search", body);
|
|
216
|
+
const res = await this.request("POST", "/api/v1/agent/search", body);
|
|
217
217
|
const results = res?.results ?? res?.items ?? res?.nodes ?? (Array.isArray(res) ? res : []);
|
|
218
218
|
return { results };
|
|
219
219
|
}
|
|
@@ -225,7 +225,7 @@ class SulcusCloudClient {
|
|
|
225
225
|
async add_memory(content: string, memoryType?: string | null): Promise<{ id: string; [key: string]: any }> {
|
|
226
226
|
const body: any = { text: content };
|
|
227
227
|
if (memoryType) body.memory_type = memoryType;
|
|
228
|
-
const res = await this.request("POST", "/agent/nodes", body);
|
|
228
|
+
const res = await this.request("POST", "/api/v1/agent/nodes", body);
|
|
229
229
|
return res ?? { id: "unknown" };
|
|
230
230
|
}
|
|
231
231
|
|
|
@@ -234,7 +234,7 @@ class SulcusCloudClient {
|
|
|
234
234
|
* Returns hot_nodes list; normalised for memory_status tool.
|
|
235
235
|
*/
|
|
236
236
|
async list_hot_nodes(_limit?: number): Promise<{ nodes: any[] }> {
|
|
237
|
-
const res = await this.request("GET", "/agent/memory/status");
|
|
237
|
+
const res = await this.request("GET", "/api/v1/agent/memory/status");
|
|
238
238
|
const nodes = res?.hot_nodes ?? res?.nodes ?? [];
|
|
239
239
|
return { nodes };
|
|
240
240
|
}
|
|
@@ -245,7 +245,7 @@ class SulcusCloudClient {
|
|
|
245
245
|
async consolidate(minHeat?: number): Promise<any> {
|
|
246
246
|
const body: any = {};
|
|
247
247
|
if (minHeat !== undefined) body.min_heat = minHeat;
|
|
248
|
-
return this.request("POST", "/agent/consolidate", body);
|
|
248
|
+
return this.request("POST", "/api/v1/agent/consolidate", body);
|
|
249
249
|
}
|
|
250
250
|
|
|
251
251
|
/**
|
|
@@ -253,7 +253,7 @@ class SulcusCloudClient {
|
|
|
253
253
|
* Returns raw markdown string.
|
|
254
254
|
*/
|
|
255
255
|
async export_markdown(): Promise<string> {
|
|
256
|
-
const res = await this.request("GET", "/agent/export?format=markdown");
|
|
256
|
+
const res = await this.request("GET", "/api/v1/agent/export?format=markdown");
|
|
257
257
|
// Server may return { content: "..." } or raw string
|
|
258
258
|
if (typeof res === "string") return res;
|
|
259
259
|
return res?.content ?? res?.markdown ?? JSON.stringify(res, null, 2);
|
|
@@ -263,7 +263,7 @@ class SulcusCloudClient {
|
|
|
263
263
|
* import_markdown — maps to POST /agent/import
|
|
264
264
|
*/
|
|
265
265
|
async import_markdown(text: string): Promise<any> {
|
|
266
|
-
return this.request("POST", "/agent/import", { format: "markdown", content: text });
|
|
266
|
+
return this.request("POST", "/api/v1/agent/import", { format: "markdown", content: text });
|
|
267
267
|
}
|
|
268
268
|
|
|
269
269
|
/**
|
|
@@ -278,7 +278,7 @@ class SulcusCloudClient {
|
|
|
278
278
|
body.context = contextJson;
|
|
279
279
|
}
|
|
280
280
|
}
|
|
281
|
-
return this.request("POST", "/agent/triggers/evaluate", body);
|
|
281
|
+
return this.request("POST", "/api/v1/agent/triggers/evaluate", body);
|
|
282
282
|
}
|
|
283
283
|
}
|
|
284
284
|
|
|
@@ -770,53 +770,48 @@ const sulcusPlugin = {
|
|
|
770
770
|
// ── Load hooks config (config-driven dispatch) ──
|
|
771
771
|
const hooksConfig = loadHooksConfig(api.pluginConfig);
|
|
772
772
|
|
|
773
|
-
// ──
|
|
774
|
-
const nativeLoader = new NativeLibLoader(storeLibPath, vectorsLibPath);
|
|
775
|
-
nativeLoader.init(api.logger);
|
|
776
|
-
|
|
777
|
-
// ── Load WASM module ──
|
|
773
|
+
// ── Backend init: cloud-first, then local ──
|
|
778
774
|
let sulcusMem: any = null;
|
|
779
775
|
let backendMode = "unavailable";
|
|
776
|
+
const nativeLoader = new NativeLibLoader(storeLibPath, vectorsLibPath);
|
|
780
777
|
|
|
781
|
-
if
|
|
782
|
-
|
|
783
|
-
|
|
784
|
-
|
|
785
|
-
|
|
786
|
-
|
|
787
|
-
|
|
788
|
-
|
|
789
|
-
|
|
790
|
-
|
|
791
|
-
sulcusMem = SulcusMem.create(queryFn, embedFn);
|
|
792
|
-
backendMode = "wasm";
|
|
793
|
-
api.logger.info(`sulcus: SulcusMem created via WASM (wasm: ${wasmJsPath})`);
|
|
794
|
-
} catch (e: any) {
|
|
795
|
-
api.logger.warn(`sulcus: WASM load failed: ${e.message}`);
|
|
796
|
-
backendMode = "unavailable";
|
|
797
|
-
}
|
|
798
|
-
} else {
|
|
799
|
-
api.logger.warn(`sulcus: WASM module not found at ${wasmJsPath}`);
|
|
778
|
+
// Priority 1: Cloud mode — if serverUrl + apiKey are configured, use HTTP.
|
|
779
|
+
// No local dylibs needed. This is the path for cloud-only users.
|
|
780
|
+
if (serverUrl && apiKey) {
|
|
781
|
+
try {
|
|
782
|
+
const cloudClient = new SulcusCloudClient(serverUrl, apiKey);
|
|
783
|
+
sulcusMem = cloudClient;
|
|
784
|
+
backendMode = "cloud";
|
|
785
|
+
api.logger.info(`sulcus: using cloud backend (server: ${serverUrl})`);
|
|
786
|
+
} catch (e: any) {
|
|
787
|
+
api.logger.warn(`sulcus: cloud client init failed: ${e.message}`);
|
|
800
788
|
}
|
|
801
|
-
} else {
|
|
802
|
-
api.logger.warn(`sulcus: native libs unavailable — ${nativeLoader.error}`);
|
|
803
789
|
}
|
|
804
790
|
|
|
805
|
-
//
|
|
806
|
-
//
|
|
807
|
-
// serverUrl + apiKey are configured. Zero external dependencies.
|
|
791
|
+
// Priority 2: Local WASM+native — if cloud isn't configured or failed,
|
|
792
|
+
// try loading native dylibs + WASM module for fully local operation.
|
|
808
793
|
if (sulcusMem === null) {
|
|
809
|
-
|
|
810
|
-
|
|
811
|
-
|
|
812
|
-
|
|
813
|
-
|
|
814
|
-
|
|
815
|
-
|
|
816
|
-
|
|
794
|
+
nativeLoader.init(api.logger);
|
|
795
|
+
if (nativeLoader.loaded) {
|
|
796
|
+
const wasmJsPath = resolve(wasmDir, "sulcus_wasm.js");
|
|
797
|
+
if (existsSync(wasmJsPath)) {
|
|
798
|
+
try {
|
|
799
|
+
const { SulcusMem, on_init } = require(wasmJsPath);
|
|
800
|
+
if (typeof on_init === "function") on_init();
|
|
801
|
+
|
|
802
|
+
const queryFn = nativeLoader.makeQueryFn();
|
|
803
|
+
const embedFn = nativeLoader.makeEmbedFn();
|
|
804
|
+
sulcusMem = SulcusMem.create(queryFn, embedFn);
|
|
805
|
+
backendMode = "wasm";
|
|
806
|
+
api.logger.info(`sulcus: SulcusMem created via WASM (wasm: ${wasmJsPath})`);
|
|
807
|
+
} catch (e: any) {
|
|
808
|
+
api.logger.warn(`sulcus: WASM load failed: ${e.message}`);
|
|
809
|
+
}
|
|
810
|
+
} else {
|
|
811
|
+
api.logger.warn(`sulcus: WASM module not found at ${wasmJsPath}`);
|
|
817
812
|
}
|
|
818
813
|
} else {
|
|
819
|
-
api.logger.info(`sulcus:
|
|
814
|
+
api.logger.info(`sulcus: local mode skipped — ${nativeLoader.error || "dylibs not found"}`);
|
|
820
815
|
}
|
|
821
816
|
}
|
|
822
817
|
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@digitalforgestudios/openclaw-sulcus",
|
|
3
|
-
"version": "3.5.
|
|
3
|
+
"version": "3.5.4",
|
|
4
4
|
"description": "Sulcus — reactive, thermodynamic memory plugin for OpenClaw. Opt-in persistent memory with heat-based decay, semantic search, and cross-agent sync. Auto-recall and auto-capture disabled by default.",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"openclaw",
|