clay-server 2.22.0-beta.1 → 2.22.0-beta.2

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 (2) hide show
  1. package/lib/project.js +81 -31
  2. package/package.json +1 -1
package/lib/project.js CHANGED
@@ -3856,11 +3856,11 @@ function createProjectContext(opts) {
3856
3856
  initMemorySummary(mateCtx, mateId, function () {});
3857
3857
  }
3858
3858
 
3859
- // Build conversation content for gate check (500 char cap each side)
3859
+ // Build conversation content for gate check
3860
3860
  var userQ = userQuestion || "(unknown)";
3861
3861
  var mateR = mateResponse || "(unknown)";
3862
- var conversationContent = "User: " + (userQ.length > 500 ? userQ.substring(0, 500) + "..." : userQ) +
3863
- "\nMate: " + (mateR.length > 500 ? mateR.substring(0, 500) + "..." : mateR);
3862
+ var conversationContent = "User: " + (userQ.length > 2000 ? userQ.substring(0, 2000) + "..." : userQ) +
3863
+ "\nMate: " + (mateR.length > 2000 ? mateR.substring(0, 2000) + "..." : mateR);
3864
3864
 
3865
3865
  // Gate check: ask Haiku if this is worth remembering
3866
3866
  gateMemory(mateCtx, mateId, conversationContent, function (shouldRemember) {
@@ -3872,6 +3872,7 @@ function createProjectContext(opts) {
3872
3872
  var digestPrompt = [
3873
3873
  "[SYSTEM: Session Digest]",
3874
3874
  "Summarize this conversation from YOUR perspective for your long-term memory.",
3875
+ "Pay close attention to the user's exact words, preferences, and any personal/project context they shared.",
3875
3876
  "Output ONLY a single valid JSON object (no markdown, no code fences, no extra text).",
3876
3877
  "",
3877
3878
  "Schema:",
@@ -3879,6 +3880,9 @@ function createProjectContext(opts) {
3879
3880
  ' "date": "YYYY-MM-DD",',
3880
3881
  ' "type": "mention",',
3881
3882
  ' "topic": "short topic description",',
3883
+ ' "summary": "2-3 sentence summary of the full conversation",',
3884
+ ' "key_quotes": ["exact notable things the user said, verbatim or near-verbatim, max 5"],',
3885
+ ' "user_context": "personal info, project details, goals, preferences the user shared (null if none)",',
3882
3886
  ' "my_position": "what I said/recommended",',
3883
3887
  ' "decisions": "what was decided, or null if pending",',
3884
3888
  ' "open_items": "what remains unresolved",',
@@ -3889,7 +3893,8 @@ function createProjectContext(opts) {
3889
3893
  ' "tags": ["relevant", "topic", "tags"]',
3890
3894
  "}",
3891
3895
  "",
3892
- "IMPORTANT: Output ONLY the JSON object. Nothing else.",
3896
+ "IMPORTANT: Preserve the user's actual words in key_quotes. These are the most valuable part of memory.",
3897
+ "Output ONLY the JSON object. Nothing else.",
3893
3898
  ].join("\n");
3894
3899
 
3895
3900
  var digestText = "";
@@ -3941,19 +3946,42 @@ function createProjectContext(opts) {
3941
3946
  var mateCtx = matesModule.buildMateCtx(projectOwnerId);
3942
3947
  if (!matesModule.isMate(mateCtx, mateId)) return;
3943
3948
 
3944
- // Extract last user message from history
3945
- var lastUserText = "";
3946
- for (var hi = session.history.length - 1; hi >= 0; hi--) {
3949
+ // Collect full conversation from session history (all user + mate turns)
3950
+ var conversationParts = [];
3951
+ var totalLen = 0;
3952
+ var CONV_CAP = 6000; // generous cap for the full conversation
3953
+ for (var hi = 0; hi < session.history.length; hi++) {
3947
3954
  var entry = session.history[hi];
3948
3955
  if (entry.type === "user_message" && entry.text) {
3949
- lastUserText = entry.text;
3950
- break;
3956
+ var uText = entry.text;
3957
+ if (totalLen + uText.length > CONV_CAP) {
3958
+ uText = uText.substring(0, Math.max(200, CONV_CAP - totalLen)) + "...";
3959
+ }
3960
+ conversationParts.push("User: " + uText);
3961
+ totalLen += uText.length;
3962
+ } else if (entry.type === "assistant_message" && entry.text) {
3963
+ var aText = entry.text;
3964
+ if (totalLen + aText.length > CONV_CAP) {
3965
+ aText = aText.substring(0, Math.max(200, CONV_CAP - totalLen)) + "...";
3966
+ }
3967
+ conversationParts.push("Mate: " + aText);
3968
+ totalLen += aText.length;
3951
3969
  }
3970
+ if (totalLen >= CONV_CAP) break;
3952
3971
  }
3953
-
3954
- // Use responsePreview (full accumulated response) instead of delta fragments
3972
+ // Append the final response if not yet in history
3955
3973
  var lastResponseText = responsePreview || "";
3956
- if (!lastUserText && !lastResponseText) return;
3974
+ if (lastResponseText && conversationParts.length > 0) {
3975
+ var lastPart = conversationParts[conversationParts.length - 1];
3976
+ if (lastPart.indexOf("Mate:") !== 0 || lastPart.indexOf(lastResponseText.substring(0, 50)) === -1) {
3977
+ var rText = lastResponseText;
3978
+ if (totalLen + rText.length > CONV_CAP) {
3979
+ rText = rText.substring(0, Math.max(200, CONV_CAP - totalLen)) + "...";
3980
+ }
3981
+ conversationParts.push("Mate: " + rText);
3982
+ }
3983
+ }
3984
+ if (conversationParts.length === 0) return;
3957
3985
 
3958
3986
  var mateDir = matesModule.getMateDir(mateCtx, mateId);
3959
3987
  var knowledgeDir = path.join(mateDir, "knowledge");
@@ -3967,8 +3995,7 @@ function createProjectContext(opts) {
3967
3995
  });
3968
3996
  }
3969
3997
 
3970
- var conversationContent = "User: " + (lastUserText.length > 500 ? lastUserText.substring(0, 500) + "..." : lastUserText) +
3971
- "\nMate: " + (lastResponseText.length > 500 ? lastResponseText.substring(0, 500) + "..." : lastResponseText);
3998
+ var conversationContent = conversationParts.join("\n");
3972
3999
 
3973
4000
  _dmDigestPending = true;
3974
4001
 
@@ -3983,6 +4010,7 @@ function createProjectContext(opts) {
3983
4010
  var digestContext = [
3984
4011
  "[SYSTEM: Session Digest]",
3985
4012
  "Summarize this conversation from YOUR perspective for your long-term memory.",
4013
+ "Pay close attention to the user's exact words, preferences, and any personal/project context they shared.",
3986
4014
  "",
3987
4015
  conversationContent,
3988
4016
  ].join("\n");
@@ -3995,6 +4023,9 @@ function createProjectContext(opts) {
3995
4023
  ' "date": "YYYY-MM-DD",',
3996
4024
  ' "type": "dm",',
3997
4025
  ' "topic": "short topic description",',
4026
+ ' "summary": "2-3 sentence summary of the full conversation",',
4027
+ ' "key_quotes": ["exact notable things the user said, verbatim or near-verbatim, max 5"],',
4028
+ ' "user_context": "personal info, project details, goals, preferences the user shared (null if none)",',
3998
4029
  ' "my_position": "what I said/recommended",',
3999
4030
  ' "decisions": "what was decided, or null if pending",',
4000
4031
  ' "open_items": "what remains unresolved",',
@@ -4005,7 +4036,8 @@ function createProjectContext(opts) {
4005
4036
  ' "tags": ["relevant", "topic", "tags"]',
4006
4037
  "}",
4007
4038
  "",
4008
- "IMPORTANT: Output ONLY the JSON object. Nothing else.",
4039
+ "IMPORTANT: Preserve the user's actual words in key_quotes. These are the most valuable part of memory.",
4040
+ "Output ONLY the JSON object. Nothing else.",
4009
4041
  ].join("\n");
4010
4042
 
4011
4043
  var digestText = "";
@@ -4413,16 +4445,16 @@ function createProjectContext(opts) {
4413
4445
  } catch (e) {}
4414
4446
 
4415
4447
  if (hasSummary) {
4416
- // Load summary + latest 3 raw digests
4417
- var recent = allLines.slice(-3);
4448
+ // Load summary + latest 5 raw digests for richer context
4449
+ var recent = allLines.slice(-5);
4418
4450
  var result = "\n\nYour memory summary:\n" + summaryContent;
4419
4451
  if (recent.length > 0) {
4420
4452
  result += formatRawDigests(recent, "Latest raw session memories:");
4421
4453
  }
4422
4454
  return result;
4423
4455
  } else {
4424
- // Backward compatible: latest 5 raw digests
4425
- var recent = allLines.slice(-5);
4456
+ // Backward compatible: latest 8 raw digests
4457
+ var recent = allLines.slice(-8);
4426
4458
  return formatRawDigests(recent, "Your recent session memories:");
4427
4459
  }
4428
4460
  }
@@ -4453,10 +4485,10 @@ function createProjectContext(opts) {
4453
4485
  }
4454
4486
  } catch (e) {}
4455
4487
 
4456
- // Cap conversation content for gate (500 chars each side)
4488
+ // Cap conversation content for gate
4457
4489
  var cappedContent = conversationContent;
4458
- if (cappedContent.length > 1200) {
4459
- cappedContent = cappedContent.substring(0, 1200) + "...";
4490
+ if (cappedContent.length > 3000) {
4491
+ cappedContent = cappedContent.substring(0, 3000) + "...";
4460
4492
  }
4461
4493
 
4462
4494
  var gateContext = [
@@ -4475,20 +4507,25 @@ function createProjectContext(opts) {
4475
4507
 
4476
4508
  var gatePrompt = opts.gatePrompt || [
4477
4509
  'Should this conversation be saved to long-term memory?',
4478
- 'Answer "yes" ONLY if there is:',
4479
- "- A new decision or commitment",
4510
+ 'Answer "yes" if ANY of these apply:',
4511
+ "- A new decision, commitment, or direction",
4480
4512
  "- A change in position or strategy",
4481
4513
  "- New information relevant to this Mate's role",
4482
- "- A user preference or pattern not already in the summary",
4514
+ "- A user preference, opinion, or pattern not already in the summary",
4515
+ "- The user shared personal context, project details, or goals",
4516
+ "- The user expressed what they like, dislike, or care about",
4517
+ "- The user gave instructions on how they want things done",
4518
+ "- Anything the user would reasonably expect to be remembered next time",
4519
+ "",
4520
+ 'Answer "no" ONLY if:',
4521
+ "- It exactly duplicates what is already in the memory summary",
4522
+ "- The entire conversation is a single trivial exchange (e.g. just 'hi' / 'hello')",
4483
4523
  "",
4484
- 'Answer "no" if:',
4485
- "- It duplicates what is already in the memory summary",
4486
- "- It is casual/trivial conversation",
4487
- "- It is not relevant to this Mate's role",
4524
+ "When in doubt, answer yes. It is better to remember too much than to forget something important.",
4488
4525
  "",
4489
4526
  'Answer with ONLY "yes" or "no". Nothing else.',
4490
4527
  ].join("\n");
4491
- var defaultOnError = !!opts.defaultYes;
4528
+ var defaultOnError = opts.defaultYes !== undefined ? !!opts.defaultYes : true;
4492
4529
 
4493
4530
  var gateText = "";
4494
4531
  var _gateSession = null;
@@ -4575,20 +4612,27 @@ function createProjectContext(opts) {
4575
4612
  "3. Moving resolved open threads out of \"Open Threads\"",
4576
4613
  "4. Adding to \"My Track Record\" if a past prediction/recommendation can now be evaluated",
4577
4614
  "5. Removing outdated or redundant information",
4615
+ "6. Preserving important user quotes and context from key_quotes and user_context fields",
4578
4616
  "",
4579
4617
  "Maintain this structure:",
4580
4618
  "",
4581
4619
  "# Memory Summary",
4582
4620
  "Last updated: YYYY-MM-DD (session count: N+1)",
4583
4621
  "",
4622
+ "## User Context",
4623
+ "(who they are, what they work on, project details, goals)",
4584
4624
  "## User Patterns",
4625
+ "(preferences, work style, communication style, likes/dislikes)",
4585
4626
  "## Key Decisions",
4627
+ "## Notable Quotes",
4628
+ "(important things the user said, verbatim when possible)",
4586
4629
  "## My Track Record",
4587
4630
  "## Open Threads",
4588
4631
  "## Recurring Topics",
4589
4632
  "",
4590
4633
  "Keep it concise. Each section should have at most 10 bullet points.",
4591
4634
  "Drop the oldest/least relevant if needed.",
4635
+ "The Notable Quotes section is valuable for preserving the user's voice and intent.",
4592
4636
  "Output ONLY the updated markdown. Nothing else.",
4593
4637
  ].join("\n");
4594
4638
 
@@ -4679,14 +4723,20 @@ function createProjectContext(opts) {
4679
4723
  "# Memory Summary",
4680
4724
  "Last updated: YYYY-MM-DD (session count: N)",
4681
4725
  "",
4726
+ "## User Context",
4727
+ "(who they are, what they work on, project details, goals)",
4682
4728
  "## User Patterns",
4729
+ "(preferences, work style, communication style, likes/dislikes)",
4683
4730
  "## Key Decisions",
4731
+ "## Notable Quotes",
4732
+ "(important things the user said, verbatim when possible)",
4684
4733
  "## My Track Record",
4685
4734
  "## Open Threads",
4686
4735
  "## Recurring Topics",
4687
4736
  "",
4688
- "Keep it concise. Focus on patterns and decisions, not individual session details.",
4737
+ "Keep it concise. Focus on patterns, decisions, and the user's own words.",
4689
4738
  "Each section should have at most 10 bullet points.",
4739
+ "Preserve key_quotes from digests in the Notable Quotes section.",
4690
4740
  "Set session count to " + digestsText.length + ".",
4691
4741
  "Output ONLY the markdown. Nothing else.",
4692
4742
  ].join("\n");
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "clay-server",
3
- "version": "2.22.0-beta.1",
3
+ "version": "2.22.0-beta.2",
4
4
  "description": "Self-hosted Claude Code in your browser. Multi-session, multi-user, push notifications.",
5
5
  "bin": {
6
6
  "clay-server": "./bin/cli.js",