@sesamespace/hivemind 0.5.15 → 0.5.17

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/README.md CHANGED
@@ -67,6 +67,36 @@ cd packages/memory && cargo build --release && cd ../..
67
67
  | L3 | Semantic Memory | Promoted knowledge (high-access patterns) |
68
68
  | L4 | External Memory | Git, files, APIs (on-demand) |
69
69
 
70
+ ## Dashboard
71
+
72
+ Local web UI for debugging memory and LLM request formation.
73
+
74
+ ```
75
+ http://localhost:9485
76
+ ```
77
+
78
+ - **Request Inspector:** View every LLM call with full prompt breakdown (identity files, L3 knowledge, L2 episodes with scores, L1 history, config snapshot, token estimates)
79
+ - **Memory Browser:** Search L2 episodes, view/delete L3 entries per context
80
+ - **Context Overview:** List contexts with episode counts
81
+
82
+ Bound to localhost only, no auth required. Starts automatically with the agent.
83
+
84
+ ## Agent Introspection Commands
85
+
86
+ Use `hm:` prefix in DMs (not group chats — may collide with other agents' platforms):
87
+
88
+ | Command | Description |
89
+ |---------|-------------|
90
+ | `hm:status` | Agent health, memory daemon, model, active context |
91
+ | `hm:config` | Full configuration details |
92
+ | `hm:contexts` | All contexts with L1/L2 info |
93
+ | `hm:memory stats` | Episode counts and L3 entries per context |
94
+ | `hm:memory search <query>` | Search L2 memories with similarity scores |
95
+ | `hm:memory l3 [context]` | View promoted L3 knowledge entries |
96
+ | `hm:help` | List all available commands |
97
+
98
+ These bypass the LLM — deterministic, direct daemon queries.
99
+
70
100
  ## CLI Commands
71
101
 
72
102
  | Command | Description |
@@ -1,10 +1,10 @@
1
1
  import {
2
2
  Watchdog
3
- } from "./chunk-JV3WKYNF.js";
3
+ } from "./chunk-KTOAREXT.js";
4
4
  import {
5
5
  defaultSentinelConfig,
6
6
  loadConfig
7
- } from "./chunk-MKVGEXKO.js";
7
+ } from "./chunk-OPOXV53N.js";
8
8
 
9
9
  // packages/cli/src/commands/watchdog.ts
10
10
  import { resolve } from "path";
@@ -76,4 +76,4 @@ Options:
76
76
  export {
77
77
  runWatchdogCommand
78
78
  };
79
- //# sourceMappingURL=chunk-2EUG64XE.js.map
79
+ //# sourceMappingURL=chunk-2PCF2ADI.js.map
@@ -6,7 +6,7 @@ import {
6
6
  PRIMARY_ROUTES,
7
7
  SesameClient,
8
8
  WORKER_ROUTES
9
- } from "./chunk-MKVGEXKO.js";
9
+ } from "./chunk-OPOXV53N.js";
10
10
 
11
11
  // packages/runtime/src/watchdog.ts
12
12
  import { execSync } from "child_process";
@@ -1048,4 +1048,4 @@ export {
1048
1048
  WorkerMemorySync,
1049
1049
  PrimaryMemorySync
1050
1050
  };
1051
- //# sourceMappingURL=chunk-JV3WKYNF.js.map
1051
+ //# sourceMappingURL=chunk-KTOAREXT.js.map
@@ -546,6 +546,7 @@ ${charter}
546
546
  Messages are prefixed with [sender_handle]: or [sender_handle in group chat]: to tell you who's talking.
547
547
  In group chats, multiple people (humans and agents) may be present. Address them by name when relevant.
548
548
  Don't repeat or quote these prefixes in your responses \u2014 just respond naturally.
549
+ Keep responses concise \u2014 especially in group chats. A few sentences is usually enough. Don't write essays.
549
550
  If you decide not to respond to a group message, reply with exactly: __SKIP__
550
551
  `;
551
552
  let contextInfo = "";
@@ -750,7 +751,7 @@ var Agent = class {
750
751
  let stripped = message.replace(/^\[.+?\s+in\s+group\s+chat\]:\s*/, "");
751
752
  stripped = stripped.replace(/^\[.+?\]:\s*/, "");
752
753
  const cmdText = stripped;
753
- if (/^\/status\b/i.test(cmdText)) {
754
+ if (/^hm[:\s]status\b/i.test(cmdText)) {
754
755
  const memoryOk = await this.memory.healthCheck();
755
756
  const contexts = this.contextManager.listContexts();
756
757
  let contextStats = "";
@@ -778,7 +779,7 @@ var Agent = class {
778
779
  ].join("\n");
779
780
  return { content: response, model: "system", context: activeCtx };
780
781
  }
781
- if (/^\/memory\s+stats\b/i.test(cmdText)) {
782
+ if (/^hm[:\s]memory\s+stats\b/i.test(cmdText)) {
782
783
  try {
783
784
  const contexts = await this.memory.listContexts();
784
785
  let totalEpisodes = 0;
@@ -810,7 +811,7 @@ var Agent = class {
810
811
  return { content: `Memory stats failed: ${err.message}`, model: "system", context: activeCtx };
811
812
  }
812
813
  }
813
- const memSearchMatch = cmdText.match(/^\/memory\s+search\s+(.+)/i);
814
+ const memSearchMatch = cmdText.match(/^hm[:\s]memory\s+search\s+(.+)/i);
814
815
  if (memSearchMatch) {
815
816
  const query = memSearchMatch[1].trim();
816
817
  try {
@@ -831,7 +832,7 @@ var Agent = class {
831
832
  return { content: `Memory search failed: ${err.message}`, model: "system", context: activeCtx };
832
833
  }
833
834
  }
834
- const l3Match = cmdText.match(/^\/memory\s+l3(?:\s+(\S+))?/i);
835
+ const l3Match = cmdText.match(/^hm[:\s]memory\s+l3(?:\s+(\S+))?/i);
835
836
  if (l3Match) {
836
837
  const targetCtx = l3Match[1] || activeCtx;
837
838
  try {
@@ -852,7 +853,7 @@ var Agent = class {
852
853
  return { content: `L3 query failed: ${err.message}`, model: "system", context: activeCtx };
853
854
  }
854
855
  }
855
- if (/^\/config\b/i.test(cmdText)) {
856
+ if (/^hm[:\s]config\b/i.test(cmdText)) {
856
857
  const response = [
857
858
  `## Configuration`,
858
859
  ``,
@@ -878,7 +879,7 @@ var Agent = class {
878
879
  ].join("\n");
879
880
  return { content: response, model: "system", context: activeCtx };
880
881
  }
881
- if (/^\/contexts\b/i.test(cmdText)) {
882
+ if (/^hm[:\s]contexts\b/i.test(cmdText)) {
882
883
  const localContexts = this.contextManager.listContexts();
883
884
  let daemonInfo = "";
884
885
  try {
@@ -905,17 +906,18 @@ var Agent = class {
905
906
  ].join("\n");
906
907
  return { content: response, model: "system", context: activeCtx };
907
908
  }
908
- if (/^\/help\b/i.test(cmdText)) {
909
+ if (/^hm[:\s]help\b/i.test(cmdText)) {
909
910
  const response = [
910
911
  `## Available Commands`,
911
912
  ``,
912
913
  `### Introspection`,
913
- `- \`/status\` \u2014 Agent health, memory status, config summary`,
914
- `- \`/config\` \u2014 Full configuration details`,
915
- `- \`/contexts\` \u2014 List all contexts with L1/L2 info`,
916
- `- \`/memory stats\` \u2014 Episode counts, L3 entries per context`,
917
- `- \`/memory search <query>\` \u2014 Search L2 memories with scores`,
918
- `- \`/memory l3 [context]\` \u2014 Show L3 knowledge entries`,
914
+ `- \`hm:status\` \u2014 Agent health, memory status, config summary`,
915
+ `- \`hm:config\` \u2014 Full configuration details`,
916
+ `- \`hm:contexts\` \u2014 List all contexts with L1/L2 info`,
917
+ `- \`hm:memory stats\` \u2014 Episode counts, L3 entries per context`,
918
+ `- \`hm:memory search <query>\` \u2014 Search L2 memories with scores`,
919
+ `- \`hm:memory l3 [context]\` \u2014 Show L3 knowledge entries`,
920
+ `- \`hm:help\` \u2014 This help message`,
919
921
  ``,
920
922
  `### Context Management`,
921
923
  `- \`switch to <name>\` \u2014 Switch active context`,
@@ -1894,7 +1896,12 @@ var SesameClient2 = class {
1894
1896
  this.sdk.on("message", (event) => {
1895
1897
  const msg = event.data || event.message || event;
1896
1898
  const senderId = msg.senderId || msg.sender?.id;
1897
- if (senderId === this.agentId) return;
1899
+ if (senderId === this.agentId) {
1900
+ const content = msg.content?.trim() || "";
1901
+ const isHmCommand = /^hm[:\s]/i.test(content);
1902
+ const isTextCommand = /^(?:list contexts|switch to|create context|search all:|task )/i.test(content);
1903
+ if (!isHmCommand && !isTextCommand) return;
1904
+ }
1898
1905
  if (!this.messageHandler || !msg.content) return;
1899
1906
  const channelInfo = this.channels.get(msg.channelId);
1900
1907
  this.messageHandler({
@@ -2340,8 +2347,41 @@ async function startSesameLoop(config, agent) {
2340
2347
  };
2341
2348
  process.on("SIGTERM", () => shutdown("SIGTERM"));
2342
2349
  process.on("SIGINT", () => shutdown("SIGINT"));
2350
+ const processedIds = /* @__PURE__ */ new Set();
2351
+ const MAX_SEEN = 500;
2352
+ let processing = false;
2353
+ const messageQueue = [];
2354
+ async function processQueue() {
2355
+ if (processing || messageQueue.length === 0) return;
2356
+ processing = true;
2357
+ while (messageQueue.length > 0) {
2358
+ const msg = messageQueue.shift();
2359
+ await handleMessage(msg);
2360
+ }
2361
+ processing = false;
2362
+ }
2343
2363
  sesame.onMessage(async (msg) => {
2344
2364
  if (shuttingDown) return;
2365
+ if (processedIds.has(msg.id)) {
2366
+ console.log(`[sesame] Skipping duplicate message ${msg.id}`);
2367
+ return;
2368
+ }
2369
+ processedIds.add(msg.id);
2370
+ if (processedIds.size > MAX_SEEN) {
2371
+ const iter = processedIds.values();
2372
+ for (let i = 0; i < 100; i++) iter.next();
2373
+ const keep = /* @__PURE__ */ new Set();
2374
+ for (const id of processedIds) {
2375
+ if (keep.size >= MAX_SEEN - 100) break;
2376
+ keep.add(id);
2377
+ }
2378
+ processedIds.clear();
2379
+ for (const id of keep) processedIds.add(id);
2380
+ }
2381
+ messageQueue.push(msg);
2382
+ processQueue();
2383
+ });
2384
+ async function handleMessage(msg) {
2345
2385
  console.log(`[sesame] ${msg.author.handle} (${msg.channelKind}): ${msg.content}`);
2346
2386
  sesame.startTyping(msg.channelId);
2347
2387
  sesame.updatePresence("thinking", { detail: `Replying to ${msg.author.handle}`, emoji: "\u{1F4AD}" });
@@ -2376,7 +2416,7 @@ async function startSesameLoop(config, agent) {
2376
2416
  sesame.updatePresence("online", { emoji: "\u{1F7E2}" });
2377
2417
  console.error("[sesame] Error processing message:", err.message);
2378
2418
  }
2379
- });
2419
+ }
2380
2420
  await sesame.connect();
2381
2421
  sesameConnected = true;
2382
2422
  console.log("[hivemind] Listening for Sesame messages");
@@ -2923,4 +2963,4 @@ smol-toml/dist/index.js:
2923
2963
  * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
2924
2964
  *)
2925
2965
  */
2926
- //# sourceMappingURL=chunk-MKVGEXKO.js.map
2966
+ //# sourceMappingURL=chunk-OPOXV53N.js.map