@space3-npm/cybersoul-client 1.4.20 → 1.4.21

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/dist/client.js +22 -5
  2. package/package.json +1 -1
package/dist/client.js CHANGED
@@ -1061,23 +1061,40 @@ CRITICAL: Output MUST be ONLY valid JSON with no markdown block wrappers. Do NOT
1061
1061
  */
1062
1062
  async proactiveInteract(params) {
1063
1063
  try {
1064
- // 1. Spam guard (the only hard-coded gate). Counts assistant messages
1065
- // since the last user reply; bails out if the user has clearly
1066
- // stopped responding.
1064
+ // 1. Spam guard (the only hard-coded gate). Counts assistant
1065
+ // *turns* since the last user reply; bails out if the user has
1066
+ // clearly stopped responding.
1067
+ //
1068
+ // A single character response can be emitted as multiple
1069
+ // HistoryEntry rows (one per modality: text + image + voice).
1070
+ // The host typically writes them within seconds of each other.
1071
+ // Counting entries directly would treat one multimodal reply
1072
+ // as 2-3 "unreplied messages" and trip `maxUnreplied = 2` on
1073
+ // the very first proactive attempt. Collapse consecutive
1074
+ // assistant entries whose timestamps are within
1075
+ // SAME_TURN_WINDOW_MS into a single turn before counting.
1067
1076
  const history = params.history || [];
1068
1077
  const maxUnreplied = params.maxUnreplied ?? 2;
1078
+ const SAME_TURN_WINDOW_MS = 60_000;
1069
1079
  let consecutiveProactive = 0;
1080
+ let lastAssistantTs = null;
1070
1081
  for (let i = history.length - 1; i >= 0; i--) {
1071
1082
  const msg = history[i];
1072
1083
  if (msg.role === "user")
1073
1084
  break;
1074
- if (msg.role === "assistant")
1085
+ if (msg.role !== "assistant")
1086
+ continue;
1087
+ const ts = typeof msg.timestamp === "number" ? msg.timestamp : 0;
1088
+ if (lastAssistantTs === null ||
1089
+ Math.abs(lastAssistantTs - ts) > SAME_TURN_WINDOW_MS) {
1075
1090
  consecutiveProactive++;
1091
+ }
1092
+ lastAssistantTs = ts;
1076
1093
  }
1077
1094
  if (consecutiveProactive >= maxUnreplied) {
1078
1095
  return {
1079
1096
  status: "skipped",
1080
- reason: `Spam guard: ${consecutiveProactive} consecutive un-replied messages already sent.`,
1097
+ reason: `Spam guard: ${consecutiveProactive} consecutive un-replied turns already sent.`,
1081
1098
  };
1082
1099
  }
1083
1100
  // 2. Fetch state. baseContext below already includes stage,
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@space3-npm/cybersoul-client",
3
- "version": "1.4.20",
3
+ "version": "1.4.21",
4
4
  "type": "module",
5
5
  "main": "dist/index.js",
6
6
  "module": "dist/index.js",