@sesamespace/hivemind 0.12.6 → 0.12.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.
@@ -9258,6 +9258,12 @@ var SesameAPI = class {
9258
9258
  getRateLimitRemaining() {
9259
9259
  return this.rateLimitRemaining;
9260
9260
  }
9261
+ getBaseUrl() {
9262
+ return this.baseUrl;
9263
+ }
9264
+ getApiKey() {
9265
+ return this.apiKey;
9266
+ }
9261
9267
  };
9262
9268
 
9263
9269
  // packages/runtime/src/sesame-sync.ts
@@ -9367,9 +9373,45 @@ var SesameSync = class {
9367
9373
  return false;
9368
9374
  }
9369
9375
  }
9376
+ // ── L3 Classification ──
9377
+ /**
9378
+ * Classify an L3 entry into a Sesame memory category based on content keywords.
9379
+ * Categories: people, preferences, projects, context-recovery, lessons (default)
9380
+ */
9381
+ classifyL3Entry(content) {
9382
+ const lower = content.toLowerCase();
9383
+ const peoplePatterns = [
9384
+ /\b(ryan|bailey|caitlin|human|user|agent)\b/,
9385
+ /\bwork(ing|ed|s)?\s+(with|together|alongside)\b/,
9386
+ /\b(collaborat|communicat|partner|teammate)/,
9387
+ /\b(prefers?|expects?|wants?)\s+(me|us|the agent)\b/
9388
+ ];
9389
+ if (peoplePatterns.some((p) => p.test(lower))) return "people";
9390
+ const prefPatterns = [
9391
+ /\b(i prefer|always use|never use|best practice|my workflow)\b/,
9392
+ /\b(default to|opt for|choose|convention)\b/,
9393
+ /\b(style|format|approach|pattern)\s+(is|should be|works best)\b/
9394
+ ];
9395
+ if (prefPatterns.some((p) => p.test(lower))) return "preferences";
9396
+ const projectPatterns = [
9397
+ /\b(hivemind|sesame|openclaw)\b/,
9398
+ /\b(repo(sitory)?|codebase|project|package)\b/,
9399
+ /\bgithub\.com\b/,
9400
+ /\b(src\/|packages\/|\.ts|\.js|\.py)\b/
9401
+ ];
9402
+ if (projectPatterns.some((p) => p.test(lower))) return "projects";
9403
+ const recoveryPatterns = [
9404
+ /\b(recover|restart|compaction|cold start|wake)\b/,
9405
+ /\b(rebuild|restore|flush|checkpoint)\b/,
9406
+ /\b(memory\.md|agent state|sync state)\b/
9407
+ ];
9408
+ if (recoveryPatterns.some((p) => p.test(lower))) return "context-recovery";
9409
+ return "lessons";
9410
+ }
9370
9411
  // ── Push: L3 Knowledge -> Agent Memory ──
9371
9412
  /**
9372
9413
  * Sync L3 promoted knowledge to Sesame agent memory.
9414
+ * Classifies entries into categories: people, preferences, projects, context-recovery, lessons.
9373
9415
  * Only pushes entries that haven't been synced yet.
9374
9416
  *
9375
9417
  * @param memoryDaemonUrl - URL of the local memory daemon
@@ -9395,15 +9437,17 @@ var SesameSync = class {
9395
9437
  const key = entry.key || `l3-${simpleHash(entry.content)}`;
9396
9438
  if (syncedKeys.has(key)) continue;
9397
9439
  try {
9440
+ const category = this.classifyL3Entry(entry.content);
9398
9441
  await this.api.setMemory(
9399
9442
  this.agentId,
9400
- "lessons",
9443
+ category,
9401
9444
  key,
9402
9445
  entry.content,
9403
9446
  {
9404
9447
  source: "hivemind-l3-promotion",
9405
9448
  l3Score: entry.score,
9406
9449
  l3Context: entry.context || "global",
9450
+ l3Category: category,
9407
9451
  syncedAt: (/* @__PURE__ */ new Date()).toISOString()
9408
9452
  }
9409
9453
  );
@@ -9438,6 +9482,55 @@ var SesameSync = class {
9438
9482
  return null;
9439
9483
  }
9440
9484
  }
9485
+ // ── Pull: Recent Channel Messages ──
9486
+ /**
9487
+ * Pull recent messages from unread channels after wake.
9488
+ * Wake gives tasks/state but not conversational context — this fills that gap.
9489
+ *
9490
+ * @param wakeResponse - The response from pullOnWake()
9491
+ * @param limit - Messages per channel (default: 30)
9492
+ * @returns Map of channelId -> messages
9493
+ */
9494
+ async pullRecentMessages(wakeResponse, limit = 30) {
9495
+ const result = /* @__PURE__ */ new Map();
9496
+ const unreadChannels = wakeResponse.unreads || [];
9497
+ if (unreadChannels.length === 0) {
9498
+ console.log("[sesame-sync] No unread channels to pull messages from");
9499
+ return result;
9500
+ }
9501
+ for (const channel of unreadChannels) {
9502
+ const channelId = channel.channelId || channel.id;
9503
+ if (!channelId) continue;
9504
+ try {
9505
+ const response = await fetch(
9506
+ `${this.api.getBaseUrl()}/channels/${channelId}/messages?limit=${limit}&direction=before`,
9507
+ {
9508
+ headers: {
9509
+ Authorization: `Bearer ${this.api.getApiKey()}`,
9510
+ "Content-Type": "application/json"
9511
+ }
9512
+ }
9513
+ );
9514
+ if (!response.ok) {
9515
+ console.warn(`[sesame-sync] Failed to fetch messages for channel ${channelId}: ${response.status}`);
9516
+ continue;
9517
+ }
9518
+ const data = await response.json();
9519
+ const messages = (data.messages || data.data || []).map((msg) => ({
9520
+ content: msg.content || msg.plaintext || "",
9521
+ sender: msg.senderHandle || msg.sender || "unknown",
9522
+ timestamp: msg.createdAt || msg.timestamp || ""
9523
+ }));
9524
+ if (messages.length > 0) {
9525
+ result.set(channelId, messages);
9526
+ }
9527
+ } catch (err) {
9528
+ console.warn(`[sesame-sync] Failed to pull messages for ${channelId}:`, err.message);
9529
+ }
9530
+ }
9531
+ console.log(`[sesame-sync] Pulled messages from ${result.size} channels`);
9532
+ return result;
9533
+ }
9441
9534
  // ── Pull: Agent State -> MEMORY.md Recovery ──
9442
9535
  /**
9443
9536
  * Pull agent state and restore MEMORY.md if local copy is missing or empty.
@@ -10490,4 +10583,4 @@ smol-toml/dist/index.js:
10490
10583
  * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
10491
10584
  *)
10492
10585
  */
10493
- //# sourceMappingURL=chunk-TETVPYWD.js.map
10586
+ //# sourceMappingURL=chunk-CEJEBZTB.js.map