foliko 1.1.83 → 1.1.84
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/cli/src/ui/chat-ui.js
CHANGED
|
@@ -549,7 +549,7 @@ class ChatUI {
|
|
|
549
549
|
if (!this._lineBuffer) return;
|
|
550
550
|
|
|
551
551
|
// 渲染剩余的 partial line(没有 \n 结尾的尾部文字)
|
|
552
|
-
const rendered = renderLine(this._lineBuffer, this._renderState, true);
|
|
552
|
+
const rendered = this._lineBuffer//renderLine(this._lineBuffer, this._renderState, true);
|
|
553
553
|
if (!this._currentBotMessage) {
|
|
554
554
|
this._currentBotMessage = this.create_message(rendered, colored('● ', GREEN), true);
|
|
555
555
|
} else {
|
package/package.json
CHANGED
|
@@ -764,8 +764,11 @@ class ContextCompressor {
|
|
|
764
764
|
content: summaryContent
|
|
765
765
|
};
|
|
766
766
|
|
|
767
|
+
const combined = [...systemMessages, summary, ...recentMessages];
|
|
768
|
+
this._cleanupOrphanedToolResults(combined);
|
|
769
|
+
|
|
767
770
|
messages.length = 0;
|
|
768
|
-
messages.push(...
|
|
771
|
+
messages.push(...combined);
|
|
769
772
|
|
|
770
773
|
this._compressionCount++;
|
|
771
774
|
const tokenCount = this._tokenCounter.countMessages(messages);
|
|
@@ -794,19 +797,81 @@ class ContextCompressor {
|
|
|
794
797
|
content: summaryContent
|
|
795
798
|
};
|
|
796
799
|
|
|
800
|
+
const combined = [...systemMessages, summary, ...recentMessages];
|
|
801
|
+
this._cleanupOrphanedToolResults(combined);
|
|
802
|
+
|
|
797
803
|
messages.length = 0;
|
|
798
|
-
messages.push(...
|
|
804
|
+
messages.push(...combined);
|
|
799
805
|
|
|
800
806
|
this._compressionCount++;
|
|
801
807
|
if (messageStore.compressionState) {
|
|
802
808
|
messageStore.compressionState.count++;
|
|
803
809
|
messageStore.compressionState.lastCompressedAt = Date.now();
|
|
804
|
-
messageStore.compressionState.lastTokenCount = this._tokenCounter.countMessages(
|
|
810
|
+
messageStore.compressionState.lastTokenCount = this._tokenCounter.countMessages(combined);
|
|
805
811
|
}
|
|
806
812
|
|
|
807
813
|
logger.info(`Context simple compressed. Messages: ${messages.length}`);
|
|
808
814
|
}
|
|
809
815
|
|
|
816
|
+
/**
|
|
817
|
+
* 清理孤立的 tool-result 消息(没有对应 tool-call 的)
|
|
818
|
+
* 压缩/裁剪后 recentMessages 可能切碎 tool-call/tool-result 配对,
|
|
819
|
+
* 必须就地清理,否则下游 API 会报 "tool result's tool id not found"
|
|
820
|
+
*/
|
|
821
|
+
_cleanupOrphanedToolResults(messages) {
|
|
822
|
+
const validToolCallIds = new Set();
|
|
823
|
+
for (const msg of messages) {
|
|
824
|
+
if (msg.role !== 'assistant') continue;
|
|
825
|
+
if (Array.isArray(msg.content)) {
|
|
826
|
+
for (const item of msg.content) {
|
|
827
|
+
if ((item.type === 'tool-call' || item.type === 'tool-use') && item.toolCallId) {
|
|
828
|
+
validToolCallIds.add(item.toolCallId);
|
|
829
|
+
}
|
|
830
|
+
}
|
|
831
|
+
}
|
|
832
|
+
if (Array.isArray(msg.tool_calls)) {
|
|
833
|
+
for (const tc of msg.tool_calls) {
|
|
834
|
+
if (tc.id) validToolCallIds.add(tc.id);
|
|
835
|
+
}
|
|
836
|
+
}
|
|
837
|
+
}
|
|
838
|
+
|
|
839
|
+
let removedItems = 0;
|
|
840
|
+
let removedMsgs = 0;
|
|
841
|
+
for (const msg of messages) {
|
|
842
|
+
if (msg.role !== 'tool' || !Array.isArray(msg.content)) continue;
|
|
843
|
+
const originalLength = msg.content.length;
|
|
844
|
+
msg.content = msg.content.filter((item) => {
|
|
845
|
+
if (
|
|
846
|
+
item &&
|
|
847
|
+
(item.type === 'tool-result' || item.type === 'tool_result') &&
|
|
848
|
+
item.toolCallId &&
|
|
849
|
+
!validToolCallIds.has(item.toolCallId)
|
|
850
|
+
) {
|
|
851
|
+
removedItems++;
|
|
852
|
+
return false;
|
|
853
|
+
}
|
|
854
|
+
return true;
|
|
855
|
+
});
|
|
856
|
+
if (msg.content.length === 0 && originalLength > 0) {
|
|
857
|
+
msg._orphaned = true;
|
|
858
|
+
}
|
|
859
|
+
}
|
|
860
|
+
|
|
861
|
+
for (let i = messages.length - 1; i >= 0; i--) {
|
|
862
|
+
if (messages[i]._orphaned) {
|
|
863
|
+
messages.splice(i, 1);
|
|
864
|
+
removedMsgs++;
|
|
865
|
+
}
|
|
866
|
+
}
|
|
867
|
+
|
|
868
|
+
if (removedItems > 0 || removedMsgs > 0) {
|
|
869
|
+
logger.debug(
|
|
870
|
+
`[ContextCompressor] cleanup: removed ${removedItems} orphaned tool-result items, ${removedMsgs} orphaned tool messages`
|
|
871
|
+
);
|
|
872
|
+
}
|
|
873
|
+
}
|
|
874
|
+
|
|
810
875
|
async _summarizeMessages(messages) {
|
|
811
876
|
if (!this.framework) {
|
|
812
877
|
throw new Error('Framework not available');
|