@rei-standard/amsg-server 2.4.1 → 2.5.1

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/dist/index.cjs CHANGED
@@ -525,7 +525,7 @@ function readReasoningContent(llmResponse) {
525
525
  }
526
526
  const content = _optionalChain([message, 'optionalAccess', _5 => _5.content]);
527
527
  if (typeof content === "string") {
528
- const match = content.match(/<(think|thinking|thought)>([\s\S]*?)<\/\1>/i);
528
+ const match = content.match(REASONING_TAG_RE);
529
529
  if (match) {
530
530
  const trimmed = match[2].trim();
531
531
  if (trimmed.length > 0) return trimmed;
@@ -533,6 +533,12 @@ function readReasoningContent(llmResponse) {
533
533
  }
534
534
  return null;
535
535
  }
536
+ var REASONING_TAG_RE = /<(think|thinking|thought)>([\s\S]*?)<\/\1>/i;
537
+ var REASONING_TAG_RE_G = /<(think|thinking|thought)>[\s\S]*?<\/\1>/gi;
538
+ function stripReasoningTags(content) {
539
+ if (typeof content !== "string" || !content.includes("<")) return content;
540
+ return content.replace(REASONING_TAG_RE_G, "").trim();
541
+ }
536
542
  async function processSingleMessage(task, ctx, providedMasterKey) {
537
543
  try {
538
544
  const masterKey = providedMasterKey || ctx.masterKey;
@@ -563,6 +569,10 @@ async function processSingleMessage(task, ctx, providedMasterKey) {
563
569
  } else {
564
570
  throw new Error("Invalid message configuration: no content source available");
565
571
  }
572
+ const reasoning = readReasoningContent(llmResponse);
573
+ if (reasoning) {
574
+ messageContent = stripReasoningTags(messageContent);
575
+ }
566
576
  const messages = splitMessageIntoSentences(messageContent, _nullishCoalesce(decryptedPayload.splitPattern, () => ( null)));
567
577
  if (!ctx.vapid.email || !ctx.vapid.publicKey || !ctx.vapid.privateKey) {
568
578
  throw new Error("VAPID configuration missing - push notifications cannot be sent");
@@ -574,7 +584,6 @@ async function processSingleMessage(task, ctx, providedMasterKey) {
574
584
  const avatarUrl = decryptedPayload.avatarUrl || null;
575
585
  const metadata = decryptedPayload.metadata || {};
576
586
  const messageIdBase = task.id != null ? `msg_task_${task.id}` : `msg_${_crypto.randomUUID.call(void 0, )}_instant`;
577
- const reasoning = readReasoningContent(llmResponse);
578
587
  if (reasoning) {
579
588
  const reasoningPush = _amsgshared.buildReasoningPush.call(void 0, {
580
589
  messageType: decryptedPayload.messageType,
package/dist/index.d.cts CHANGED
@@ -880,7 +880,7 @@ function readReasoningContent(llmResponse) {
880
880
  const choices = /** @type {{ choices?: unknown }} */ (llmResponse).choices;
881
881
  if (!Array.isArray(choices) || choices.length === 0) return null;
882
882
  const message = /** @type {{ message?: { reasoning_content?: unknown, content?: unknown } }} */ (choices[0])?.message;
883
-
883
+
884
884
  const raw = message?.reasoning_content;
885
885
  if (typeof raw === 'string') {
886
886
  const trimmed = raw.trim();
@@ -889,7 +889,7 @@ function readReasoningContent(llmResponse) {
889
889
 
890
890
  const content = message?.content;
891
891
  if (typeof content === 'string') {
892
- const match = content.match(/<(think|thinking|thought)>([\s\S]*?)<\/\1>/i);
892
+ const match = content.match(REASONING_TAG_RE);
893
893
  if (match) {
894
894
  const trimmed = match[2].trim();
895
895
  if (trimmed.length > 0) return trimmed;
@@ -899,6 +899,22 @@ function readReasoningContent(llmResponse) {
899
899
  return null;
900
900
  }
901
901
 
902
+ const REASONING_TAG_RE = /<(think|thinking|thought)>([\s\S]*?)<\/\1>/i;
903
+ const REASONING_TAG_RE_G = /<(think|thinking|thought)>[\s\S]*?<\/\1>/gi;
904
+
905
+ /**
906
+ * Mirrors `amsg-instant/src/message-processor.js#stripReasoningTags`.
907
+ * Removes any private chain-of-thought markup leaking through
908
+ * `message.content` so it does not also ship inside ContentPush.
909
+ *
910
+ * @param {string} content
911
+ * @returns {string}
912
+ */
913
+ function stripReasoningTags(content) {
914
+ if (typeof content !== 'string' || !content.includes('<')) return content;
915
+ return content.replace(REASONING_TAG_RE_G, '').trim();
916
+ }
917
+
902
918
  /**
903
919
  * @typedef {Object} ProcessorContext
904
920
  * @property {Object} webpush - The web-push module instance (already VAPID-configured).
@@ -952,6 +968,15 @@ async function processSingleMessage(task, ctx, providedMasterKey) {
952
968
  throw new Error('Invalid message configuration: no content source available');
953
969
  }
954
970
 
971
+ // Auto-extract reasoning BEFORE the sentence split: when reasoning
972
+ // came from the `<think>` fallback inside message.content, the same
973
+ // span is still embedded in messageContent and would otherwise leak
974
+ // as raw markup into ContentPush.
975
+ const reasoning = readReasoningContent(llmResponse);
976
+ if (reasoning) {
977
+ messageContent = stripReasoningTags(messageContent);
978
+ }
979
+
955
980
  // Sentence splitting (mirrors @rei-standard/amsg-instant
956
981
  // splitMessageIntoSentences — keep in lockstep; do not drift). Caller may
957
982
  // override the default regex via decryptedPayload.splitPattern (string
@@ -988,7 +1013,6 @@ async function processSingleMessage(task, ctx, providedMasterKey) {
988
1013
  // LLM response carried non-empty reasoning_content. `fixed` and
989
1014
  // explicit-userMessage paths produce no LLM response, so this
990
1015
  // block is naturally skipped for them (llmResponse stays null).
991
- const reasoning = readReasoningContent(llmResponse);
992
1016
  if (reasoning) {
993
1017
  const reasoningPush = buildReasoningPush({
994
1018
  messageType: decryptedPayload.messageType,
package/dist/index.d.ts CHANGED
@@ -880,7 +880,7 @@ function readReasoningContent(llmResponse) {
880
880
  const choices = /** @type {{ choices?: unknown }} */ (llmResponse).choices;
881
881
  if (!Array.isArray(choices) || choices.length === 0) return null;
882
882
  const message = /** @type {{ message?: { reasoning_content?: unknown, content?: unknown } }} */ (choices[0])?.message;
883
-
883
+
884
884
  const raw = message?.reasoning_content;
885
885
  if (typeof raw === 'string') {
886
886
  const trimmed = raw.trim();
@@ -889,7 +889,7 @@ function readReasoningContent(llmResponse) {
889
889
 
890
890
  const content = message?.content;
891
891
  if (typeof content === 'string') {
892
- const match = content.match(/<(think|thinking|thought)>([\s\S]*?)<\/\1>/i);
892
+ const match = content.match(REASONING_TAG_RE);
893
893
  if (match) {
894
894
  const trimmed = match[2].trim();
895
895
  if (trimmed.length > 0) return trimmed;
@@ -899,6 +899,22 @@ function readReasoningContent(llmResponse) {
899
899
  return null;
900
900
  }
901
901
 
902
+ const REASONING_TAG_RE = /<(think|thinking|thought)>([\s\S]*?)<\/\1>/i;
903
+ const REASONING_TAG_RE_G = /<(think|thinking|thought)>[\s\S]*?<\/\1>/gi;
904
+
905
+ /**
906
+ * Mirrors `amsg-instant/src/message-processor.js#stripReasoningTags`.
907
+ * Removes any private chain-of-thought markup leaking through
908
+ * `message.content` so it does not also ship inside ContentPush.
909
+ *
910
+ * @param {string} content
911
+ * @returns {string}
912
+ */
913
+ function stripReasoningTags(content) {
914
+ if (typeof content !== 'string' || !content.includes('<')) return content;
915
+ return content.replace(REASONING_TAG_RE_G, '').trim();
916
+ }
917
+
902
918
  /**
903
919
  * @typedef {Object} ProcessorContext
904
920
  * @property {Object} webpush - The web-push module instance (already VAPID-configured).
@@ -952,6 +968,15 @@ async function processSingleMessage(task, ctx, providedMasterKey) {
952
968
  throw new Error('Invalid message configuration: no content source available');
953
969
  }
954
970
 
971
+ // Auto-extract reasoning BEFORE the sentence split: when reasoning
972
+ // came from the `<think>` fallback inside message.content, the same
973
+ // span is still embedded in messageContent and would otherwise leak
974
+ // as raw markup into ContentPush.
975
+ const reasoning = readReasoningContent(llmResponse);
976
+ if (reasoning) {
977
+ messageContent = stripReasoningTags(messageContent);
978
+ }
979
+
955
980
  // Sentence splitting (mirrors @rei-standard/amsg-instant
956
981
  // splitMessageIntoSentences — keep in lockstep; do not drift). Caller may
957
982
  // override the default regex via decryptedPayload.splitPattern (string
@@ -988,7 +1013,6 @@ async function processSingleMessage(task, ctx, providedMasterKey) {
988
1013
  // LLM response carried non-empty reasoning_content. `fixed` and
989
1014
  // explicit-userMessage paths produce no LLM response, so this
990
1015
  // block is naturally skipped for them (llmResponse stays null).
991
- const reasoning = readReasoningContent(llmResponse);
992
1016
  if (reasoning) {
993
1017
  const reasoningPush = buildReasoningPush({
994
1018
  messageType: decryptedPayload.messageType,
package/dist/index.mjs CHANGED
@@ -525,7 +525,7 @@ function readReasoningContent(llmResponse) {
525
525
  }
526
526
  const content = message?.content;
527
527
  if (typeof content === "string") {
528
- const match = content.match(/<(think|thinking|thought)>([\s\S]*?)<\/\1>/i);
528
+ const match = content.match(REASONING_TAG_RE);
529
529
  if (match) {
530
530
  const trimmed = match[2].trim();
531
531
  if (trimmed.length > 0) return trimmed;
@@ -533,6 +533,12 @@ function readReasoningContent(llmResponse) {
533
533
  }
534
534
  return null;
535
535
  }
536
+ var REASONING_TAG_RE = /<(think|thinking|thought)>([\s\S]*?)<\/\1>/i;
537
+ var REASONING_TAG_RE_G = /<(think|thinking|thought)>[\s\S]*?<\/\1>/gi;
538
+ function stripReasoningTags(content) {
539
+ if (typeof content !== "string" || !content.includes("<")) return content;
540
+ return content.replace(REASONING_TAG_RE_G, "").trim();
541
+ }
536
542
  async function processSingleMessage(task, ctx, providedMasterKey) {
537
543
  try {
538
544
  const masterKey = providedMasterKey || ctx.masterKey;
@@ -563,6 +569,10 @@ async function processSingleMessage(task, ctx, providedMasterKey) {
563
569
  } else {
564
570
  throw new Error("Invalid message configuration: no content source available");
565
571
  }
572
+ const reasoning = readReasoningContent(llmResponse);
573
+ if (reasoning) {
574
+ messageContent = stripReasoningTags(messageContent);
575
+ }
566
576
  const messages = splitMessageIntoSentences(messageContent, decryptedPayload.splitPattern ?? null);
567
577
  if (!ctx.vapid.email || !ctx.vapid.publicKey || !ctx.vapid.privateKey) {
568
578
  throw new Error("VAPID configuration missing - push notifications cannot be sent");
@@ -574,7 +584,6 @@ async function processSingleMessage(task, ctx, providedMasterKey) {
574
584
  const avatarUrl = decryptedPayload.avatarUrl || null;
575
585
  const metadata = decryptedPayload.metadata || {};
576
586
  const messageIdBase = task.id != null ? `msg_task_${task.id}` : `msg_${randomUUID()}_instant`;
577
- const reasoning = readReasoningContent(llmResponse);
578
587
  if (reasoning) {
579
588
  const reasoningPush = buildReasoningPush({
580
589
  messageType: decryptedPayload.messageType,
package/package.json CHANGED
@@ -1,10 +1,10 @@
1
1
  {
2
2
  "name": "@rei-standard/amsg-server",
3
- "version": "2.4.1",
3
+ "version": "2.5.1",
4
4
  "description": "ReiStandard Active Messaging server SDK with pluggable database adapters. Three-axis push schema (messageKind / messageType / messageSubtype) from @rei-standard/amsg-shared. Auto-emits ReasoningPush when the LLM response carries reasoning_content.",
5
5
  "repository": {
6
6
  "type": "git",
7
- "url": "https://github.com/Tosd0/ReiStandard",
7
+ "url": "git+https://github.com/Tosd0/ReiStandard.git",
8
8
  "directory": "packages/rei-standard-amsg/server"
9
9
  },
10
10
  "license": "MIT",
@@ -33,7 +33,7 @@
33
33
  "node": ">=20"
34
34
  },
35
35
  "dependencies": {
36
- "@rei-standard/amsg-shared": "0.1.0",
36
+ "@rei-standard/amsg-shared": "0.2.0",
37
37
  "web-push": "^3.6.7",
38
38
  "@netlify/blobs": "^8.1.0"
39
39
  },