blun-king-cli 9.1.198 → 9.1.199

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.
@@ -5,6 +5,10 @@ const MAX_RECENT_ASSISTANT_RESPONSES = 8;
5
5
  const REQUIRED_MATCHING_RESPONSES = 3;
6
6
  const RESPONSE_SIMILARITY_THRESHOLD = 0.78;
7
7
  const REPEATED_RESPONSE_PLACEHOLDER = '[Historical repeated assistant response omitted; newer user corrections and instructions supersede it.]';
8
+ const INTRA_MESSAGE_MIN_REPEATS = 3;
9
+ const INTRA_MESSAGE_MIN_BLOCK_CHARS = 40;
10
+ const INTRA_MESSAGE_MIN_SAVED_CHARS = 1_000;
11
+ const INTRA_MESSAGE_REPEAT_PLACEHOLDER = '[Exact repeated assistant paragraphs omitted from model projection; raw history preserved.]';
8
12
 
9
13
  function isUserPrompt(message) {
10
14
  if (message?.role !== 'user') return false;
@@ -100,12 +104,74 @@ function detectRepeatedAssistantResponse(history) {
100
104
  };
101
105
  }
102
106
 
107
+ function compactRepeatedAssistantParagraphs(message) {
108
+ if (
109
+ message?.role !== 'assistant'
110
+ || (message.toolCalls?.length ?? 0) > 0
111
+ || message.origin?.kind === 'injection'
112
+ || !Array.isArray(message.content)
113
+ ) return null;
114
+
115
+ const textParts = message.content.filter(
116
+ (part) => part?.type === 'text' && typeof part.text === 'string',
117
+ );
118
+ if (textParts.length !== 1 || message.content.some(
119
+ (part) => part?.type !== 'text' && part?.type !== 'think',
120
+ )) return null;
121
+
122
+ const text = textParts[0].text;
123
+ if (/```|~~~/u.test(text)) return null;
124
+ const blocks = text.split(/\n\s*\n/u).map((block) => block.trim()).filter(Boolean);
125
+ if (blocks.length < INTRA_MESSAGE_MIN_REPEATS + 1) return null;
126
+
127
+ const counts = new Map();
128
+ for (const block of blocks) counts.set(block, (counts.get(block) ?? 0) + 1);
129
+ const repeated = new Set([...counts]
130
+ .filter(([block, count]) => (
131
+ block.length >= INTRA_MESSAGE_MIN_BLOCK_CHARS
132
+ && count >= INTRA_MESSAGE_MIN_REPEATS
133
+ ))
134
+ .map(([block]) => block));
135
+ if (repeated.size === 0) return null;
136
+
137
+ const seen = new Set();
138
+ const projectedBlocks = [];
139
+ let markerAdded = false;
140
+ for (const block of blocks) {
141
+ if (!repeated.has(block) || !seen.has(block)) {
142
+ projectedBlocks.push(block);
143
+ if (repeated.has(block)) seen.add(block);
144
+ continue;
145
+ }
146
+ if (!markerAdded) {
147
+ projectedBlocks.push(INTRA_MESSAGE_REPEAT_PLACEHOLDER);
148
+ markerAdded = true;
149
+ }
150
+ }
151
+
152
+ const projectedText = projectedBlocks.join('\n\n');
153
+ if (text.length - projectedText.length < INTRA_MESSAGE_MIN_SAVED_CHARS) return null;
154
+ return {
155
+ ...message,
156
+ content: message.content.map((part) => (
157
+ part === textParts[0] ? { ...part, text: projectedText } : part
158
+ )),
159
+ };
160
+ }
161
+
103
162
  function projectRepeatedAssistantResponses(history) {
104
163
  const detection = detectRepeatedAssistantResponse(history);
105
- if (detection === null) return history;
164
+ let changed = false;
165
+ const intraMessageProjected = history.map((message) => {
166
+ const projected = compactRepeatedAssistantParagraphs(message);
167
+ if (projected === null) return message;
168
+ changed = true;
169
+ return projected;
170
+ });
171
+ if (detection === null) return changed ? intraMessageProjected : history;
106
172
 
107
173
  const repeatedIndexes = new Set(detection.indexes);
108
- return history.map((message, index) => {
174
+ return intraMessageProjected.map((message, index) => {
109
175
  if (!repeatedIndexes.has(index)) return message;
110
176
  return {
111
177
  ...message,
@@ -115,12 +181,17 @@ function projectRepeatedAssistantResponses(history) {
115
181
  }
116
182
 
117
183
  module.exports = {
184
+ INTRA_MESSAGE_MIN_BLOCK_CHARS,
185
+ INTRA_MESSAGE_MIN_REPEATS,
186
+ INTRA_MESSAGE_MIN_SAVED_CHARS,
187
+ INTRA_MESSAGE_REPEAT_PLACEHOLDER,
118
188
  MAX_RECENT_ASSISTANT_RESPONSES,
119
189
  MIN_RESPONSE_CHARS,
120
190
  REQUIRED_MATCHING_RESPONSES,
121
191
  REPEATED_RESPONSE_PLACEHOLDER,
122
192
  RESPONSE_SIMILARITY_THRESHOLD,
123
193
  assistantResponseText,
194
+ compactRepeatedAssistantParagraphs,
124
195
  detectRepeatedAssistantResponse,
125
196
  projectRepeatedAssistantResponses,
126
197
  responseSimilarity,
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "blun-king-cli",
3
- "version": "9.1.198",
3
+ "version": "9.1.199",
4
4
  "description": "BLUN CLI - your own AI agent with a Telegram channel. Get it done. With BLUN.",
5
5
  "license": "MIT",
6
6
  "bin": {