@digitalforgestudios/openclaw-sulcus 6.6.5 → 6.6.6

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 (3) hide show
  1. package/index.js +81 -0
  2. package/index.ts +91 -0
  3. package/package.json +1 -1
package/index.js CHANGED
@@ -7817,6 +7817,87 @@ ${res.items.length} shown${res.total ? ` of ${res.total}` : ""}`);
7817
7817
  } else {
7818
7818
  logger.info("sulcus: registerCli not available \u2014 CLI commands skipped");
7819
7819
  }
7820
+ const registerCommand = api.registerCommand;
7821
+ if (typeof registerCommand === "function") {
7822
+ try {
7823
+ registerCommand({
7824
+ name: "sulcus",
7825
+ description: "Sulcus memory status and configuration. Usage: /sulcus [status|config|set <key> <value>]",
7826
+ acceptsArgs: true,
7827
+ requireAuth: false,
7828
+ handler: async (ctx) => {
7829
+ const rawArgs = (ctx.args ?? "").trim();
7830
+ const parts = rawArgs.split(/\s+/);
7831
+ const subcommand = (parts[0] || "status").toLowerCase();
7832
+ if (subcommand === "status" || subcommand === "") {
7833
+ const lines = [];
7834
+ lines.push(`\u{1F9E0} **Sulcus Memory** \u2014 v${api.version || "6.6.5"}`);
7835
+ lines.push(`**Backend:** ${backendMode}`);
7836
+ lines.push(`**Namespace:** ${namespace}`);
7837
+ lines.push(`**Token Budget:** ${tokenBudget}`);
7838
+ lines.push(`**Auto-Recall:** ${autoRecall ? "\u2705" : "\u274C"}`);
7839
+ lines.push(`**Auto-Capture:** ${autoCapture ? "\u2705" : "\u274C"}`);
7840
+ lines.push(`**Max Recall Results:** ${maxRecallResults}`);
7841
+ lines.push(`**Min Recall Score:** ${pluginConfig?.minRecallScore ?? 0.3}`);
7842
+ lines.push(`**Profile Frequency:** every ${profileFrequency} turns`);
7843
+ lines.push(`**Capture from Assistant:** ${captureFromAssistant ? "\u2705" : "\u274C"}`);
7844
+ lines.push(`**Context Rebuild:** ${contextRebuildEnabled ? "\u2705" : "\u274C"} (budget: ${contextRebuildBudget})`);
7845
+ lines.push(`**Boost on Recall:** ${boostOnRecallEnabled ? "\u2705" : "\u274C"}`);
7846
+ if (isAvailable && sulcusMem instanceof SulcusCloudClient) {
7847
+ try {
7848
+ const stats = await sulcusMem.get_stats();
7849
+ if (stats) {
7850
+ lines.push(`**Memories:** ${stats.total_memories ?? "?"} total`);
7851
+ if (stats.hot_count != null) lines.push(`**Hot Nodes:** ${stats.hot_count}`);
7852
+ }
7853
+ } catch {
7854
+ }
7855
+ }
7856
+ return { text: lines.join("\n") };
7857
+ }
7858
+ if (subcommand === "config") {
7859
+ const configKeys = [
7860
+ `tokenBudget: ${tokenBudget} (100\u201316000, default 10000)`,
7861
+ `maxRecallResults: ${maxRecallResults} (1\u201320, default 5)`,
7862
+ `minRecallScore: ${pluginConfig?.minRecallScore ?? 0.3} (0\u20131, default 0.3)`,
7863
+ `profileFrequency: ${profileFrequency} (1\u2013500, default 10)`,
7864
+ `autoRecall: ${autoRecall}`,
7865
+ `autoCapture: ${autoCapture}`,
7866
+ `captureFromAssistant: ${captureFromAssistant}`,
7867
+ `boostOnRecall: ${boostOnRecallEnabled}`,
7868
+ `contextWindowSize: ${contextWindowSize}`
7869
+ ];
7870
+ const lines = [
7871
+ "\u2699\uFE0F **Sulcus Configuration**",
7872
+ "",
7873
+ ...configKeys.map((k) => `\u2022 ${k}`),
7874
+ "",
7875
+ "**To change a value:**",
7876
+ "Set `tokenBudget` in your OpenClaw config:",
7877
+ "```json",
7878
+ JSON.stringify({ plugins: { entries: { "openclaw-sulcus": { config: { tokenBudget: 1e4 } } } } }, null, 2),
7879
+ "```",
7880
+ "Then restart to apply."
7881
+ ];
7882
+ return { text: lines.join("\n") };
7883
+ }
7884
+ if (subcommand === "help") {
7885
+ return { text: [
7886
+ "\u{1F9E0} **Sulcus Commands**",
7887
+ "",
7888
+ "\u2022 `/sulcus` or `/sulcus status` \u2014 Show memory status",
7889
+ "\u2022 `/sulcus config` \u2014 Show current configuration and how to change it",
7890
+ "\u2022 `/sulcus help` \u2014 This help message"
7891
+ ].join("\n") };
7892
+ }
7893
+ return { text: `Unknown subcommand: \`${subcommand}\`. Try \`/sulcus help\`.` };
7894
+ }
7895
+ });
7896
+ logger.info("sulcus: registered /sulcus chat command");
7897
+ } catch (e) {
7898
+ logger.warn(`sulcus: registerCommand failed: ${e instanceof Error ? e.message : e}`);
7899
+ }
7900
+ }
7820
7901
  if (isAvailable && sulcusMem instanceof SulcusCloudClient) {
7821
7902
  importOpenClawHistory(sulcusMem, logger).catch((e) => {
7822
7903
  logger.warn(`sulcus: history import failed: ${e instanceof Error ? e.message : String(e)}`);
package/index.ts CHANGED
@@ -6678,6 +6678,97 @@ ${finalContent}`;
6678
6678
  logger.info("sulcus: registerCli not available \u2014 CLI commands skipped");
6679
6679
  }
6680
6680
 
6681
+ // -------------------------------------------------------------------------
6682
+ // CHAT COMMAND REGISTRATION — /sulcus
6683
+ // -------------------------------------------------------------------------
6684
+ const registerCommand = api.registerCommand as ((command: unknown) => void) | undefined;
6685
+ if (typeof registerCommand === "function") {
6686
+ try {
6687
+ registerCommand({
6688
+ name: "sulcus",
6689
+ description: "Sulcus memory status and configuration. Usage: /sulcus [status|config|set <key> <value>]",
6690
+ acceptsArgs: true,
6691
+ requireAuth: false,
6692
+ handler: async (ctx: { args?: string; senderId?: string; isAuthorizedSender?: boolean; config?: unknown }) => {
6693
+ const rawArgs = (ctx.args ?? "").trim();
6694
+ const parts = rawArgs.split(/\s+/);
6695
+ const subcommand = (parts[0] || "status").toLowerCase();
6696
+
6697
+ // --- /sulcus status (default) ---
6698
+ if (subcommand === "status" || subcommand === "") {
6699
+ const lines: string[] = [];
6700
+ lines.push(`🧠 **Sulcus Memory** — v${(api as any).version || "6.6.5"}`);
6701
+ lines.push(`**Backend:** ${backendMode}`);
6702
+ lines.push(`**Namespace:** ${namespace}`);
6703
+ lines.push(`**Token Budget:** ${tokenBudget}`);
6704
+ lines.push(`**Auto-Recall:** ${autoRecall ? "✅" : "❌"}`);
6705
+ lines.push(`**Auto-Capture:** ${autoCapture ? "✅" : "❌"}`);
6706
+ lines.push(`**Max Recall Results:** ${maxRecallResults}`);
6707
+ lines.push(`**Min Recall Score:** ${(pluginConfig?.minRecallScore as number | undefined) ?? 0.3}`);
6708
+ lines.push(`**Profile Frequency:** every ${profileFrequency} turns`);
6709
+ lines.push(`**Capture from Assistant:** ${captureFromAssistant ? "✅" : "❌"}`);
6710
+ lines.push(`**Context Rebuild:** ${contextRebuildEnabled ? "✅" : "❌"} (budget: ${contextRebuildBudget})`);
6711
+ lines.push(`**Boost on Recall:** ${boostOnRecallEnabled ? "✅" : "❌"}`);
6712
+ if (isAvailable && sulcusMem instanceof SulcusCloudClient) {
6713
+ try {
6714
+ const stats = await sulcusMem.get_stats();
6715
+ if (stats) {
6716
+ lines.push(`**Memories:** ${stats.total_memories ?? "?"} total`);
6717
+ if (stats.hot_count != null) lines.push(`**Hot Nodes:** ${stats.hot_count}`);
6718
+ }
6719
+ } catch { /* stats fetch failed — skip */ }
6720
+ }
6721
+ return { text: lines.join("\n") };
6722
+ }
6723
+
6724
+ // --- /sulcus config ---
6725
+ if (subcommand === "config") {
6726
+ const configKeys = [
6727
+ `tokenBudget: ${tokenBudget} (100–16000, default 10000)`,
6728
+ `maxRecallResults: ${maxRecallResults} (1–20, default 5)`,
6729
+ `minRecallScore: ${(pluginConfig?.minRecallScore as number | undefined) ?? 0.3} (0–1, default 0.3)`,
6730
+ `profileFrequency: ${profileFrequency} (1–500, default 10)`,
6731
+ `autoRecall: ${autoRecall}`,
6732
+ `autoCapture: ${autoCapture}`,
6733
+ `captureFromAssistant: ${captureFromAssistant}`,
6734
+ `boostOnRecall: ${boostOnRecallEnabled}`,
6735
+ `contextWindowSize: ${contextWindowSize}`,
6736
+ ];
6737
+ const lines = [
6738
+ "⚙️ **Sulcus Configuration**",
6739
+ "",
6740
+ ...configKeys.map(k => `• ${k}`),
6741
+ "",
6742
+ "**To change a value:**",
6743
+ "Set `tokenBudget` in your OpenClaw config:",
6744
+ "```json",
6745
+ JSON.stringify({ plugins: { entries: { "openclaw-sulcus": { config: { tokenBudget: 10000 } } } } }, null, 2),
6746
+ "```",
6747
+ "Then restart to apply.",
6748
+ ];
6749
+ return { text: lines.join("\n") };
6750
+ }
6751
+
6752
+ // --- /sulcus help ---
6753
+ if (subcommand === "help") {
6754
+ return { text: [
6755
+ "🧠 **Sulcus Commands**",
6756
+ "",
6757
+ "• `/sulcus` or `/sulcus status` — Show memory status",
6758
+ "• `/sulcus config` — Show current configuration and how to change it",
6759
+ "• `/sulcus help` — This help message",
6760
+ ].join("\n") };
6761
+ }
6762
+
6763
+ return { text: `Unknown subcommand: \`${subcommand}\`. Try \`/sulcus help\`.` };
6764
+ },
6765
+ });
6766
+ logger.info("sulcus: registered /sulcus chat command");
6767
+ } catch (e: unknown) {
6768
+ logger.warn(`sulcus: registerCommand failed: ${e instanceof Error ? e.message : e}`);
6769
+ }
6770
+ }
6771
+
6681
6772
  // Fire-and-forget first-install history import
6682
6773
  if (isAvailable && sulcusMem instanceof SulcusCloudClient) {
6683
6774
  importOpenClawHistory(sulcusMem, logger).catch((e: unknown) => {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@digitalforgestudios/openclaw-sulcus",
3
- "version": "6.6.5",
3
+ "version": "6.6.6",
4
4
  "description": "Sulcus — thermodynamic memory + Apache AGE knowledge graph for OpenClaw agents. v6.0: Multi-signal recall (semantic + hot-context + entity-graph + profile), configurable guardrails (outputGuard + toolGuard), token budget enforcement, context rebuild post-compaction, sulcus.toml config layer, SIRU training data logging, session-scoped memory, batch heat-boost. SIU v2 pipeline (SIVU/SICU/SILU/SITU/SIRU). Interaction-based decay. Curator sleep-cycle. Cross-agent sync.",
5
5
  "keywords": [
6
6
  "openclaw",