oh-pi 0.1.76 → 0.1.78
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/README.md +1 -1
- package/README.zh.md +1 -1
- package/dist/index.js +1 -1
- package/dist/registry.js +0 -1
- package/dist/utils/writers.js +12 -0
- package/dist/utils/writers.test.d.ts +1 -0
- package/dist/utils/writers.test.js +60 -0
- package/package.json +4 -2
- package/pi-package/agents/colony-operator.md +3 -2
- package/pi-package/extensions/ant-colony/index.ts +73 -3
- package/pi-package/extensions/ant-colony/concurrency.test.ts +0 -70
- package/pi-package/extensions/ant-colony/deps.test.ts +0 -62
- package/pi-package/extensions/ant-colony/nest.test.ts +0 -130
- package/pi-package/extensions/ant-colony/parser.test.ts +0 -143
- package/pi-package/extensions/ant-colony/prompts.test.ts +0 -99
- package/pi-package/extensions/ant-colony/queen.test.ts +0 -227
- package/pi-package/extensions/ant-colony/spawner.test.ts +0 -44
- package/pi-package/extensions/ant-colony/types.test.ts +0 -36
- package/pi-package/extensions/ant-colony/ui.test.ts +0 -84
- package/pi-package/extensions/auto-update.test.ts +0 -15
- package/pi-package/extensions/safe-guard.test.ts +0 -26
- package/pi-package/extensions/smart-compact.test.ts +0 -64
- package/pi-package/extensions/smart-compact.ts +0 -89
|
@@ -1,89 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* 智能压缩扩展 — 在发送给 LLM 前裁剪大块内容
|
|
3
|
-
*
|
|
4
|
-
* 策略:
|
|
5
|
-
* 1. 工具输出超过阈值 → 保留首尾,中间替换为 "[...truncated N lines]"
|
|
6
|
-
* 2. 用户粘贴的大块文本 → 同上
|
|
7
|
-
* 3. 越旧的消息裁剪越激进
|
|
8
|
-
*/
|
|
9
|
-
|
|
10
|
-
const MAX_TOOL_OUTPUT_CHARS = 8000;
|
|
11
|
-
const MAX_USER_BLOCK_CHARS = 12000;
|
|
12
|
-
const KEEP_HEAD = 1500;
|
|
13
|
-
const KEEP_TAIL = 2500;
|
|
14
|
-
|
|
15
|
-
export function truncateText(text: string, max: number, head = KEEP_HEAD, tail = KEEP_TAIL): string {
|
|
16
|
-
if (text.length <= max) return text;
|
|
17
|
-
const lines = text.split("\n");
|
|
18
|
-
if (lines.length <= 10) return text; // 短文本不裁
|
|
19
|
-
const headText = text.slice(0, head);
|
|
20
|
-
const tailText = text.slice(-tail);
|
|
21
|
-
const removedLines = text.slice(head, -tail).split("\n").length;
|
|
22
|
-
return `${headText}\n\n[...truncated ${removedLines} lines...]\n\n${tailText}`;
|
|
23
|
-
}
|
|
24
|
-
|
|
25
|
-
export function compactContent(content: any): any {
|
|
26
|
-
if (typeof content === "string") {
|
|
27
|
-
return truncateText(content, MAX_TOOL_OUTPUT_CHARS);
|
|
28
|
-
}
|
|
29
|
-
if (!Array.isArray(content)) return content;
|
|
30
|
-
return content.map((block: any) => {
|
|
31
|
-
if (block.type === "text" && typeof block.text === "string") {
|
|
32
|
-
return { ...block, text: truncateText(block.text, MAX_TOOL_OUTPUT_CHARS) };
|
|
33
|
-
}
|
|
34
|
-
return block;
|
|
35
|
-
});
|
|
36
|
-
}
|
|
37
|
-
|
|
38
|
-
export default function smartCompact(pi: any) {
|
|
39
|
-
pi.on("context", async (event: any) => {
|
|
40
|
-
const messages = event.messages;
|
|
41
|
-
if (!messages || messages.length < 4) return; // 太短不处理
|
|
42
|
-
|
|
43
|
-
// 只处理非最近 3 条消息(保留最近上下文完整)
|
|
44
|
-
const cutoff = messages.length - 3;
|
|
45
|
-
|
|
46
|
-
for (let i = 0; i < cutoff; i++) {
|
|
47
|
-
const msg = messages[i];
|
|
48
|
-
if (!msg) continue;
|
|
49
|
-
|
|
50
|
-
if (msg.role === "toolResult") {
|
|
51
|
-
msg.content = compactContent(msg.content);
|
|
52
|
-
} else if (msg.role === "user") {
|
|
53
|
-
// 用户消息用更宽松的阈值
|
|
54
|
-
if (typeof msg.content === "string" && msg.content.length > MAX_USER_BLOCK_CHARS) {
|
|
55
|
-
msg.content = truncateText(msg.content, MAX_USER_BLOCK_CHARS);
|
|
56
|
-
} else if (Array.isArray(msg.content)) {
|
|
57
|
-
msg.content = msg.content.map((block: any) => {
|
|
58
|
-
if (block.type === "text" && typeof block.text === "string" && block.text.length > MAX_USER_BLOCK_CHARS) {
|
|
59
|
-
return { ...block, text: truncateText(block.text, MAX_USER_BLOCK_CHARS) };
|
|
60
|
-
}
|
|
61
|
-
return block;
|
|
62
|
-
});
|
|
63
|
-
}
|
|
64
|
-
} else if (msg.role === "assistant" && Array.isArray(msg.content)) {
|
|
65
|
-
// 裁剪 assistant 的大块工具调用参数
|
|
66
|
-
msg.content = msg.content.map((block: any) => {
|
|
67
|
-
if (block.type === "toolCall" && block.arguments) {
|
|
68
|
-
const args = JSON.stringify(block.arguments);
|
|
69
|
-
if (args.length > MAX_TOOL_OUTPUT_CHARS) {
|
|
70
|
-
try {
|
|
71
|
-
const parsed = typeof block.arguments === "string" ? JSON.parse(block.arguments) : block.arguments;
|
|
72
|
-
// 裁剪大字符串参数
|
|
73
|
-
for (const key of Object.keys(parsed)) {
|
|
74
|
-
if (typeof parsed[key] === "string" && parsed[key].length > MAX_TOOL_OUTPUT_CHARS) {
|
|
75
|
-
parsed[key] = truncateText(parsed[key], MAX_TOOL_OUTPUT_CHARS);
|
|
76
|
-
}
|
|
77
|
-
}
|
|
78
|
-
return { ...block, arguments: parsed };
|
|
79
|
-
} catch { return block; }
|
|
80
|
-
}
|
|
81
|
-
}
|
|
82
|
-
return block;
|
|
83
|
-
});
|
|
84
|
-
}
|
|
85
|
-
}
|
|
86
|
-
|
|
87
|
-
return { messages };
|
|
88
|
-
});
|
|
89
|
-
}
|