@gatanot/qualia_core 0.1.0
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/agent/background.d.ts +6 -0
- package/dist/agent/background.d.ts.map +1 -0
- package/dist/agent/background.js +58 -0
- package/dist/agent/background.js.map +1 -0
- package/dist/agent/context-builder.d.ts +23 -0
- package/dist/agent/context-builder.d.ts.map +1 -0
- package/dist/agent/context-builder.js +102 -0
- package/dist/agent/context-builder.js.map +1 -0
- package/dist/agent/diary.d.ts +4 -0
- package/dist/agent/diary.d.ts.map +1 -0
- package/dist/agent/diary.js +67 -0
- package/dist/agent/diary.js.map +1 -0
- package/dist/agent/index.d.ts +22 -0
- package/dist/agent/index.d.ts.map +1 -0
- package/dist/agent/index.js +20 -0
- package/dist/agent/index.js.map +1 -0
- package/dist/agent/logger.d.ts +23 -0
- package/dist/agent/logger.d.ts.map +1 -0
- package/dist/agent/logger.js +70 -0
- package/dist/agent/logger.js.map +1 -0
- package/dist/agent/logger.test.d.ts +2 -0
- package/dist/agent/logger.test.d.ts.map +1 -0
- package/dist/agent/logger.test.js +28 -0
- package/dist/agent/logger.test.js.map +1 -0
- package/dist/agent/loop.d.ts +52 -0
- package/dist/agent/loop.d.ts.map +1 -0
- package/dist/agent/loop.js +557 -0
- package/dist/agent/loop.js.map +1 -0
- package/dist/agent/message-sanitizer.d.ts +13 -0
- package/dist/agent/message-sanitizer.d.ts.map +1 -0
- package/dist/agent/message-sanitizer.js +138 -0
- package/dist/agent/message-sanitizer.js.map +1 -0
- package/dist/agent/message-sanitizer.test.d.ts +2 -0
- package/dist/agent/message-sanitizer.test.d.ts.map +1 -0
- package/dist/agent/message-sanitizer.test.js +110 -0
- package/dist/agent/message-sanitizer.test.js.map +1 -0
- package/dist/agent/prompts.d.ts +15 -0
- package/dist/agent/prompts.d.ts.map +1 -0
- package/dist/agent/prompts.js +34 -0
- package/dist/agent/prompts.js.map +1 -0
- package/dist/agent/summarize-worker.d.ts +6 -0
- package/dist/agent/summarize-worker.d.ts.map +1 -0
- package/dist/agent/summarize-worker.js +62 -0
- package/dist/agent/summarize-worker.js.map +1 -0
- package/dist/agent/summarizer.d.ts +10 -0
- package/dist/agent/summarizer.d.ts.map +1 -0
- package/dist/agent/summarizer.js +133 -0
- package/dist/agent/summarizer.js.map +1 -0
- package/dist/agent/types.d.ts +135 -0
- package/dist/agent/types.d.ts.map +1 -0
- package/dist/agent/types.js +21 -0
- package/dist/agent/types.js.map +1 -0
- package/dist/ai/base.d.ts +19 -0
- package/dist/ai/base.d.ts.map +1 -0
- package/dist/ai/base.js +2 -0
- package/dist/ai/base.js.map +1 -0
- package/dist/ai/deepseek.d.ts +15 -0
- package/dist/ai/deepseek.d.ts.map +1 -0
- package/dist/ai/deepseek.js +24 -0
- package/dist/ai/deepseek.js.map +1 -0
- package/dist/ai/factory.d.ts +4 -0
- package/dist/ai/factory.d.ts.map +1 -0
- package/dist/ai/factory.js +53 -0
- package/dist/ai/factory.js.map +1 -0
- package/dist/ai/index.d.ts +43 -0
- package/dist/ai/index.d.ts.map +1 -0
- package/dist/ai/index.js +36 -0
- package/dist/ai/index.js.map +1 -0
- package/dist/ai/models.d.ts +13 -0
- package/dist/ai/models.d.ts.map +1 -0
- package/dist/ai/models.js +67 -0
- package/dist/ai/models.js.map +1 -0
- package/dist/ai/ollama.d.ts +13 -0
- package/dist/ai/ollama.d.ts.map +1 -0
- package/dist/ai/ollama.js +32 -0
- package/dist/ai/ollama.js.map +1 -0
- package/dist/ai/openai.d.ts +46 -0
- package/dist/ai/openai.d.ts.map +1 -0
- package/dist/ai/openai.js +90 -0
- package/dist/ai/openai.js.map +1 -0
- package/dist/ai/types.d.ts +154 -0
- package/dist/ai/types.d.ts.map +1 -0
- package/dist/ai/types.js +2 -0
- package/dist/ai/types.js.map +1 -0
- package/dist/ai/utils.d.ts +47 -0
- package/dist/ai/utils.d.ts.map +1 -0
- package/dist/ai/utils.js +145 -0
- package/dist/ai/utils.js.map +1 -0
- package/dist/ai/xiaomi.d.ts +15 -0
- package/dist/ai/xiaomi.d.ts.map +1 -0
- package/dist/ai/xiaomi.js +23 -0
- package/dist/ai/xiaomi.js.map +1 -0
- package/dist/chat-confirm.d.ts +4 -0
- package/dist/chat-confirm.d.ts.map +1 -0
- package/dist/chat-confirm.js +2 -0
- package/dist/chat-confirm.js.map +1 -0
- package/dist/chat-steering.d.ts +6 -0
- package/dist/chat-steering.d.ts.map +1 -0
- package/dist/chat-steering.js +2 -0
- package/dist/chat-steering.js.map +1 -0
- package/dist/concurrency/background-worker.d.ts +16 -0
- package/dist/concurrency/background-worker.d.ts.map +1 -0
- package/dist/concurrency/background-worker.js +62 -0
- package/dist/concurrency/background-worker.js.map +1 -0
- package/dist/concurrency/background-worker.test.d.ts +2 -0
- package/dist/concurrency/background-worker.test.d.ts.map +1 -0
- package/dist/concurrency/background-worker.test.js +55 -0
- package/dist/concurrency/background-worker.test.js.map +1 -0
- package/dist/concurrency/file-mutex.d.ts +8 -0
- package/dist/concurrency/file-mutex.d.ts.map +1 -0
- package/dist/concurrency/file-mutex.js +41 -0
- package/dist/concurrency/file-mutex.js.map +1 -0
- package/dist/concurrency/file-mutex.test.d.ts +2 -0
- package/dist/concurrency/file-mutex.test.d.ts.map +1 -0
- package/dist/concurrency/file-mutex.test.js +50 -0
- package/dist/concurrency/file-mutex.test.js.map +1 -0
- package/dist/concurrency/index.d.ts +5 -0
- package/dist/concurrency/index.d.ts.map +1 -0
- package/dist/concurrency/index.js +4 -0
- package/dist/concurrency/index.js.map +1 -0
- package/dist/concurrency/session-lock.d.ts +8 -0
- package/dist/concurrency/session-lock.d.ts.map +1 -0
- package/dist/concurrency/session-lock.js +41 -0
- package/dist/concurrency/session-lock.js.map +1 -0
- package/dist/concurrency/session-lock.test.d.ts +2 -0
- package/dist/concurrency/session-lock.test.d.ts.map +1 -0
- package/dist/concurrency/session-lock.test.js +51 -0
- package/dist/concurrency/session-lock.test.js.map +1 -0
- package/dist/config/index.d.ts +12 -0
- package/dist/config/index.d.ts.map +1 -0
- package/dist/config/index.js +10 -0
- package/dist/config/index.js.map +1 -0
- package/dist/config/store.d.ts +17 -0
- package/dist/config/store.d.ts.map +1 -0
- package/dist/config/store.js +214 -0
- package/dist/config/store.js.map +1 -0
- package/dist/config/types.d.ts +44 -0
- package/dist/config/types.d.ts.map +1 -0
- package/dist/config/types.js +2 -0
- package/dist/config/types.js.map +1 -0
- package/dist/gateway/adapters/email.d.ts +23 -0
- package/dist/gateway/adapters/email.d.ts.map +1 -0
- package/dist/gateway/adapters/email.js +145 -0
- package/dist/gateway/adapters/email.js.map +1 -0
- package/dist/gateway/adapters/telegram-sessions.d.ts +4 -0
- package/dist/gateway/adapters/telegram-sessions.d.ts.map +1 -0
- package/dist/gateway/adapters/telegram-sessions.js +39 -0
- package/dist/gateway/adapters/telegram-sessions.js.map +1 -0
- package/dist/gateway/adapters/telegram.d.ts +22 -0
- package/dist/gateway/adapters/telegram.d.ts.map +1 -0
- package/dist/gateway/adapters/telegram.js +131 -0
- package/dist/gateway/adapters/telegram.js.map +1 -0
- package/dist/gateway/dispatcher.d.ts +19 -0
- package/dist/gateway/dispatcher.d.ts.map +1 -0
- package/dist/gateway/dispatcher.js +81 -0
- package/dist/gateway/dispatcher.js.map +1 -0
- package/dist/gateway/inbound-handler.d.ts +3 -0
- package/dist/gateway/inbound-handler.d.ts.map +1 -0
- package/dist/gateway/inbound-handler.js +95 -0
- package/dist/gateway/inbound-handler.js.map +1 -0
- package/dist/gateway/index.d.ts +9 -0
- package/dist/gateway/index.d.ts.map +1 -0
- package/dist/gateway/index.js +6 -0
- package/dist/gateway/index.js.map +1 -0
- package/dist/gateway/lifecycle.d.ts +3 -0
- package/dist/gateway/lifecycle.d.ts.map +1 -0
- package/dist/gateway/lifecycle.js +38 -0
- package/dist/gateway/lifecycle.js.map +1 -0
- package/dist/gateway/types.d.ts +32 -0
- package/dist/gateway/types.d.ts.map +1 -0
- package/dist/gateway/types.js +2 -0
- package/dist/gateway/types.js.map +1 -0
- package/dist/index.d.ts +23 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +14 -0
- package/dist/index.js.map +1 -0
- package/dist/markdown.d.ts +2 -0
- package/dist/markdown.d.ts.map +1 -0
- package/dist/markdown.js +94 -0
- package/dist/markdown.js.map +1 -0
- package/dist/paths.d.ts +5 -0
- package/dist/paths.d.ts.map +1 -0
- package/dist/paths.js +17 -0
- package/dist/paths.js.map +1 -0
- package/dist/storage/index.d.ts +10 -0
- package/dist/storage/index.d.ts.map +1 -0
- package/dist/storage/index.js +18 -0
- package/dist/storage/index.js.map +1 -0
- package/dist/storage/memory.d.ts +39 -0
- package/dist/storage/memory.d.ts.map +1 -0
- package/dist/storage/memory.js +252 -0
- package/dist/storage/memory.js.map +1 -0
- package/dist/storage/sqlite.d.ts +44 -0
- package/dist/storage/sqlite.d.ts.map +1 -0
- package/dist/storage/sqlite.js +275 -0
- package/dist/storage/sqlite.js.map +1 -0
- package/dist/storage/types.d.ts +134 -0
- package/dist/storage/types.d.ts.map +1 -0
- package/dist/storage/types.js +2 -0
- package/dist/storage/types.js.map +1 -0
- package/dist/storage/utils.d.ts +2 -0
- package/dist/storage/utils.d.ts.map +1 -0
- package/dist/storage/utils.js +8 -0
- package/dist/storage/utils.js.map +1 -0
- package/dist/task/executor.d.ts +3 -0
- package/dist/task/executor.d.ts.map +1 -0
- package/dist/task/executor.js +80 -0
- package/dist/task/executor.js.map +1 -0
- package/dist/task/index.d.ts +5 -0
- package/dist/task/index.d.ts.map +1 -0
- package/dist/task/index.js +4 -0
- package/dist/task/index.js.map +1 -0
- package/dist/task/scheduler.d.ts +5 -0
- package/dist/task/scheduler.d.ts.map +1 -0
- package/dist/task/scheduler.js +47 -0
- package/dist/task/scheduler.js.map +1 -0
- package/dist/task/store.d.ts +14 -0
- package/dist/task/store.d.ts.map +1 -0
- package/dist/task/store.js +156 -0
- package/dist/task/store.js.map +1 -0
- package/dist/task/types.d.ts +13 -0
- package/dist/task/types.d.ts.map +1 -0
- package/dist/task/types.js +2 -0
- package/dist/task/types.js.map +1 -0
- package/dist/tool/env.d.ts +20 -0
- package/dist/tool/env.d.ts.map +1 -0
- package/dist/tool/env.js +26 -0
- package/dist/tool/env.js.map +1 -0
- package/dist/tool/env.test.d.ts +2 -0
- package/dist/tool/env.test.d.ts.map +1 -0
- package/dist/tool/env.test.js +42 -0
- package/dist/tool/env.test.js.map +1 -0
- package/dist/tool/index.d.ts +42 -0
- package/dist/tool/index.d.ts.map +1 -0
- package/dist/tool/index.js +53 -0
- package/dist/tool/index.js.map +1 -0
- package/dist/tool/registry.d.ts +43 -0
- package/dist/tool/registry.d.ts.map +1 -0
- package/dist/tool/registry.js +79 -0
- package/dist/tool/registry.js.map +1 -0
- package/dist/tool/safeguard.d.ts +21 -0
- package/dist/tool/safeguard.d.ts.map +1 -0
- package/dist/tool/safeguard.js +212 -0
- package/dist/tool/safeguard.js.map +1 -0
- package/dist/tool/tools/delete-file.d.ts +10 -0
- package/dist/tool/tools/delete-file.d.ts.map +1 -0
- package/dist/tool/tools/delete-file.js +52 -0
- package/dist/tool/tools/delete-file.js.map +1 -0
- package/dist/tool/tools/edit.d.ts +10 -0
- package/dist/tool/tools/edit.d.ts.map +1 -0
- package/dist/tool/tools/edit.js +159 -0
- package/dist/tool/tools/edit.js.map +1 -0
- package/dist/tool/tools/exec.d.ts +12 -0
- package/dist/tool/tools/exec.d.ts.map +1 -0
- package/dist/tool/tools/exec.js +170 -0
- package/dist/tool/tools/exec.js.map +1 -0
- package/dist/tool/tools/file-utils.d.ts +13 -0
- package/dist/tool/tools/file-utils.d.ts.map +1 -0
- package/dist/tool/tools/file-utils.js +65 -0
- package/dist/tool/tools/file-utils.js.map +1 -0
- package/dist/tool/tools/read-file.d.ts +10 -0
- package/dist/tool/tools/read-file.d.ts.map +1 -0
- package/dist/tool/tools/read-file.js +116 -0
- package/dist/tool/tools/read-file.js.map +1 -0
- package/dist/tool/tools/read-memory.d.ts +3 -0
- package/dist/tool/tools/read-memory.d.ts.map +1 -0
- package/dist/tool/tools/read-memory.js +58 -0
- package/dist/tool/tools/read-memory.js.map +1 -0
- package/dist/tool/tools/read-tasks.d.ts +3 -0
- package/dist/tool/tools/read-tasks.d.ts.map +1 -0
- package/dist/tool/tools/read-tasks.js +29 -0
- package/dist/tool/tools/read-tasks.js.map +1 -0
- package/dist/tool/tools/schedule-task.d.ts +3 -0
- package/dist/tool/tools/schedule-task.d.ts.map +1 -0
- package/dist/tool/tools/schedule-task.js +50 -0
- package/dist/tool/tools/schedule-task.js.map +1 -0
- package/dist/tool/tools/search-history.d.ts +4 -0
- package/dist/tool/tools/search-history.d.ts.map +1 -0
- package/dist/tool/tools/search-history.js +58 -0
- package/dist/tool/tools/search-history.js.map +1 -0
- package/dist/tool/tools/web-search.d.ts +3 -0
- package/dist/tool/tools/web-search.d.ts.map +1 -0
- package/dist/tool/tools/web-search.js +89 -0
- package/dist/tool/tools/web-search.js.map +1 -0
- package/dist/tool/tools/write-file.d.ts +11 -0
- package/dist/tool/tools/write-file.d.ts.map +1 -0
- package/dist/tool/tools/write-file.js +79 -0
- package/dist/tool/tools/write-file.js.map +1 -0
- package/dist/tool/tools/write-memory.d.ts +3 -0
- package/dist/tool/tools/write-memory.d.ts.map +1 -0
- package/dist/tool/tools/write-memory.js +99 -0
- package/dist/tool/tools/write-memory.js.map +1 -0
- package/dist/tool/types.d.ts +63 -0
- package/dist/tool/types.d.ts.map +1 -0
- package/dist/tool/types.js +33 -0
- package/dist/tool/types.js.map +1 -0
- package/package.json +53 -0
|
@@ -0,0 +1,138 @@
|
|
|
1
|
+
function extractTextContent(content) {
|
|
2
|
+
if (typeof content === 'string')
|
|
3
|
+
return content;
|
|
4
|
+
return content
|
|
5
|
+
.filter((p) => p.type === 'text')
|
|
6
|
+
.map((p) => p.text)
|
|
7
|
+
.join('\n');
|
|
8
|
+
}
|
|
9
|
+
function mergeContent(a, b) {
|
|
10
|
+
return extractTextContent(a) + '\n\n' + extractTextContent(b);
|
|
11
|
+
}
|
|
12
|
+
const SURROGATE_RE = /[\uD800-\uDFFF]/g;
|
|
13
|
+
function stripSurrogates(text) {
|
|
14
|
+
return text.replace(SURROGATE_RE, '\uFFFD');
|
|
15
|
+
}
|
|
16
|
+
function cleanContent(content) {
|
|
17
|
+
if (typeof content === 'string')
|
|
18
|
+
return stripSurrogates(content);
|
|
19
|
+
return content.map((part) => {
|
|
20
|
+
if (part.type === 'text') {
|
|
21
|
+
return { ...part, text: stripSurrogates(part.text) };
|
|
22
|
+
}
|
|
23
|
+
return part;
|
|
24
|
+
});
|
|
25
|
+
}
|
|
26
|
+
/**
|
|
27
|
+
* 修复相邻相同角色消息:
|
|
28
|
+
* - 连续 user → 合并为一条(内容拼接)
|
|
29
|
+
* - 连续 assistant(不含 tool_calls)→ 合并
|
|
30
|
+
* - 连续 assistant 其中之一有 tool_calls → 保留两者(tool_calls 不能合并)
|
|
31
|
+
*/
|
|
32
|
+
function repairRoleAlternation(messages) {
|
|
33
|
+
if (messages.length <= 1)
|
|
34
|
+
return messages;
|
|
35
|
+
const result = [messages[0]];
|
|
36
|
+
for (let i = 1; i < messages.length; i++) {
|
|
37
|
+
const prev = result[result.length - 1];
|
|
38
|
+
const curr = messages[i];
|
|
39
|
+
if (prev.role === curr.role && curr.role === 'user') {
|
|
40
|
+
result[result.length - 1] = {
|
|
41
|
+
role: 'user',
|
|
42
|
+
content: mergeContent(prev.content, curr.content)
|
|
43
|
+
};
|
|
44
|
+
}
|
|
45
|
+
else if (prev.role === curr.role && curr.role === 'assistant') {
|
|
46
|
+
if (prev.tool_calls || curr.tool_calls) {
|
|
47
|
+
result.push(curr);
|
|
48
|
+
}
|
|
49
|
+
else {
|
|
50
|
+
const merged = {
|
|
51
|
+
role: 'assistant',
|
|
52
|
+
content: mergeContent(prev.content, curr.content)
|
|
53
|
+
};
|
|
54
|
+
if (prev.reasoning_content || curr.reasoning_content) {
|
|
55
|
+
merged.reasoning_content = [prev.reasoning_content, curr.reasoning_content]
|
|
56
|
+
.filter(Boolean)
|
|
57
|
+
.join('\n\n');
|
|
58
|
+
}
|
|
59
|
+
if (prev.name)
|
|
60
|
+
merged.name = prev.name;
|
|
61
|
+
result[result.length - 1] = merged;
|
|
62
|
+
}
|
|
63
|
+
}
|
|
64
|
+
else {
|
|
65
|
+
result.push(curr);
|
|
66
|
+
}
|
|
67
|
+
}
|
|
68
|
+
return result;
|
|
69
|
+
}
|
|
70
|
+
/**
|
|
71
|
+
* 移除孤儿 tool 结果:
|
|
72
|
+
* tool role 消息的 tool_call_id 必须在前面的 assistant.tool_calls 中存在。
|
|
73
|
+
*/
|
|
74
|
+
function stripOrphanToolResults(messages) {
|
|
75
|
+
const activeToolIds = new Set();
|
|
76
|
+
for (const msg of messages) {
|
|
77
|
+
if (msg.role === 'assistant' && msg.tool_calls) {
|
|
78
|
+
for (const tc of msg.tool_calls) {
|
|
79
|
+
activeToolIds.add(tc.id);
|
|
80
|
+
}
|
|
81
|
+
}
|
|
82
|
+
}
|
|
83
|
+
return messages.filter((msg) => {
|
|
84
|
+
if (msg.role !== 'tool')
|
|
85
|
+
return true;
|
|
86
|
+
if (!msg.tool_call_id)
|
|
87
|
+
return false;
|
|
88
|
+
return activeToolIds.has(msg.tool_call_id);
|
|
89
|
+
});
|
|
90
|
+
}
|
|
91
|
+
function stripEmptyMessages(messages) {
|
|
92
|
+
return messages.filter((msg) => {
|
|
93
|
+
const text = extractTextContent(msg.content);
|
|
94
|
+
if (text.trim() === '' && !msg.tool_calls && msg.role !== 'tool') {
|
|
95
|
+
return false;
|
|
96
|
+
}
|
|
97
|
+
return true;
|
|
98
|
+
});
|
|
99
|
+
}
|
|
100
|
+
/**
|
|
101
|
+
* 消息清洗管道
|
|
102
|
+
*
|
|
103
|
+
* 1. 移除空消息(无内容且无 tool_calls)
|
|
104
|
+
* 2. 清除 Unicode surrogate(\uD800-\uDFFF)
|
|
105
|
+
* 3. 修复角色交替(合并连续 user/assistant)
|
|
106
|
+
* 4. 移除孤儿 tool 结果(无匹配 tool_call_id)
|
|
107
|
+
*
|
|
108
|
+
* 返回新的 Message 数组,不修改原数组。
|
|
109
|
+
*/
|
|
110
|
+
export function sanitizeMessages(messages) {
|
|
111
|
+
let result = stripEmptyMessages(messages);
|
|
112
|
+
result = result.map((msg) => {
|
|
113
|
+
const cleaned = {
|
|
114
|
+
role: msg.role,
|
|
115
|
+
content: cleanContent(msg.content)
|
|
116
|
+
};
|
|
117
|
+
if (msg.name)
|
|
118
|
+
cleaned.name = stripSurrogates(msg.name);
|
|
119
|
+
if (msg.tool_call_id)
|
|
120
|
+
cleaned.tool_call_id = stripSurrogates(msg.tool_call_id);
|
|
121
|
+
if (msg.reasoning_content)
|
|
122
|
+
cleaned.reasoning_content = stripSurrogates(msg.reasoning_content);
|
|
123
|
+
if (msg.tool_calls) {
|
|
124
|
+
cleaned.tool_calls = msg.tool_calls.map((tc) => ({
|
|
125
|
+
...tc,
|
|
126
|
+
function: {
|
|
127
|
+
name: stripSurrogates(tc.function.name),
|
|
128
|
+
arguments: stripSurrogates(tc.function.arguments)
|
|
129
|
+
}
|
|
130
|
+
}));
|
|
131
|
+
}
|
|
132
|
+
return cleaned;
|
|
133
|
+
});
|
|
134
|
+
result = repairRoleAlternation(result);
|
|
135
|
+
result = stripOrphanToolResults(result);
|
|
136
|
+
return result;
|
|
137
|
+
}
|
|
138
|
+
//# sourceMappingURL=message-sanitizer.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"message-sanitizer.js","sourceRoot":"","sources":["../../src/agent/message-sanitizer.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"message-sanitizer.test.d.ts","sourceRoot":"","sources":["../../src/agent/message-sanitizer.test.ts"],"names":[],"mappings":""}
|
|
@@ -0,0 +1,110 @@
|
|
|
1
|
+
import { describe, it, expect } from 'vitest';
|
|
2
|
+
import { sanitizeMessages } from './message-sanitizer.js';
|
|
3
|
+
function msg(role, content, extra) {
|
|
4
|
+
return { role, content, ...extra };
|
|
5
|
+
}
|
|
6
|
+
describe('sanitizeMessages', () => {
|
|
7
|
+
it('strips empty non-tool messages', () => {
|
|
8
|
+
const input = [
|
|
9
|
+
msg('system', 'sys'),
|
|
10
|
+
msg('user', ''),
|
|
11
|
+
msg('assistant', 'hello'),
|
|
12
|
+
];
|
|
13
|
+
const result = sanitizeMessages(input);
|
|
14
|
+
expect(result).toHaveLength(2);
|
|
15
|
+
expect(result[0].role).toBe('system');
|
|
16
|
+
expect(result[1].role).toBe('assistant');
|
|
17
|
+
});
|
|
18
|
+
it('keeps tool messages even when empty', () => {
|
|
19
|
+
const input = [
|
|
20
|
+
msg('system', 's'),
|
|
21
|
+
msg('assistant', '', { tool_calls: [{ id: '1', type: 'function', function: { name: 'x', arguments: '{}' } }] }),
|
|
22
|
+
msg('tool', '', { tool_call_id: '1', name: 'x' }),
|
|
23
|
+
];
|
|
24
|
+
const result = sanitizeMessages(input);
|
|
25
|
+
expect(result).toHaveLength(3);
|
|
26
|
+
});
|
|
27
|
+
it('strips surrogate characters', () => {
|
|
28
|
+
const input = [
|
|
29
|
+
msg('system', 'sys'),
|
|
30
|
+
msg('user', 'hello \uD800 world'),
|
|
31
|
+
];
|
|
32
|
+
const result = sanitizeMessages(input);
|
|
33
|
+
expect(result[1].content).toBe('hello \uFFFD world');
|
|
34
|
+
});
|
|
35
|
+
it('merges consecutive user messages', () => {
|
|
36
|
+
const input = [
|
|
37
|
+
msg('system', 'sys'),
|
|
38
|
+
msg('user', 'first'),
|
|
39
|
+
msg('user', 'second'),
|
|
40
|
+
];
|
|
41
|
+
const result = sanitizeMessages(input);
|
|
42
|
+
expect(result).toHaveLength(2);
|
|
43
|
+
expect(result[1].content).toContain('first');
|
|
44
|
+
expect(result[1].content).toContain('second');
|
|
45
|
+
});
|
|
46
|
+
it('merges consecutive assistant messages without tool_calls', () => {
|
|
47
|
+
const input = [
|
|
48
|
+
msg('system', 'sys'),
|
|
49
|
+
msg('user', 'q'),
|
|
50
|
+
msg('assistant', 'part1'),
|
|
51
|
+
msg('assistant', 'part2'),
|
|
52
|
+
];
|
|
53
|
+
const result = sanitizeMessages(input);
|
|
54
|
+
expect(result).toHaveLength(3);
|
|
55
|
+
expect(result[2].content).toBe('part1\n\npart2');
|
|
56
|
+
});
|
|
57
|
+
it('keeps consecutive assistants if either has tool_calls', () => {
|
|
58
|
+
const input = [
|
|
59
|
+
msg('system', 'sys'),
|
|
60
|
+
msg('user', 'q'),
|
|
61
|
+
msg('assistant', 'a1', { tool_calls: [{ id: '1', type: 'function', function: { name: 'x', arguments: '{}' } }] }),
|
|
62
|
+
msg('assistant', 'a2'),
|
|
63
|
+
];
|
|
64
|
+
const result = sanitizeMessages(input);
|
|
65
|
+
expect(result).toHaveLength(4);
|
|
66
|
+
});
|
|
67
|
+
it('strips orphan tool results without matching tool_call_id', () => {
|
|
68
|
+
const input = [
|
|
69
|
+
msg('system', 'sys'),
|
|
70
|
+
msg('user', 'q'),
|
|
71
|
+
msg('assistant', '', { tool_calls: [{ id: '1', type: 'function', function: { name: 'x', arguments: '{}' } }] }),
|
|
72
|
+
msg('tool', 'result1', { tool_call_id: '1', name: 'x' }),
|
|
73
|
+
msg('tool', 'orphan', { tool_call_id: '2', name: 'y' }),
|
|
74
|
+
];
|
|
75
|
+
const result = sanitizeMessages(input);
|
|
76
|
+
expect(result).toHaveLength(4);
|
|
77
|
+
const toolMsgs = result.filter(m => m.role === 'tool');
|
|
78
|
+
expect(toolMsgs).toHaveLength(1);
|
|
79
|
+
expect(toolMsgs[0].content).toBe('result1');
|
|
80
|
+
});
|
|
81
|
+
it('strips tool results without tool_call_id', () => {
|
|
82
|
+
const input = [
|
|
83
|
+
msg('system', 'sys'),
|
|
84
|
+
msg('tool', 'orphan'),
|
|
85
|
+
];
|
|
86
|
+
const result = sanitizeMessages(input);
|
|
87
|
+
expect(result).toHaveLength(1);
|
|
88
|
+
});
|
|
89
|
+
it('returns new array without mutating input', () => {
|
|
90
|
+
const input = [
|
|
91
|
+
msg('system', 'sys'),
|
|
92
|
+
msg('user', 'first'),
|
|
93
|
+
msg('user', 'second'),
|
|
94
|
+
];
|
|
95
|
+
const result = sanitizeMessages(input);
|
|
96
|
+
expect(input).toHaveLength(3);
|
|
97
|
+
expect(result).toHaveLength(2);
|
|
98
|
+
});
|
|
99
|
+
it('cleans surrogates in tool_calls arguments', () => {
|
|
100
|
+
const input = [
|
|
101
|
+
msg('system', 'sys'),
|
|
102
|
+
msg('assistant', '', {
|
|
103
|
+
tool_calls: [{ id: '1', type: 'function', function: { name: 'x', arguments: '{"key":"\uD800"}' } }]
|
|
104
|
+
}),
|
|
105
|
+
];
|
|
106
|
+
const result = sanitizeMessages(input);
|
|
107
|
+
expect(result[1].tool_calls[0].function.arguments).toBe('{"key":"\uFFFD"}');
|
|
108
|
+
});
|
|
109
|
+
});
|
|
110
|
+
//# sourceMappingURL=message-sanitizer.test.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"message-sanitizer.test.js","sourceRoot":"","sources":["../../src/agent/message-sanitizer.test.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* 默认系统提示词
|
|
3
|
+
*
|
|
4
|
+
* 定义 Qualia 的角色和行为准则。
|
|
5
|
+
* 用户可在设置页面自定义覆盖此内容。
|
|
6
|
+
*/
|
|
7
|
+
export declare const DEFAULT_SYSTEM_PROMPT = "\u4F60\u662F Qualia\uFF0C\u4E00\u4E2A\u8FD0\u884C\u5728\u7528\u6237\u672C\u5730\u73AF\u5883\u4E2D\u7684\u865A\u62DF AI \u4F19\u4F34\u3002\n\n## \u884C\u4E3A\u51C6\u5219\n\n1. \u4F7F\u7528\u4E2D\u6587\u56DE\u590D\uFF0C\u4EE3\u7801\u548C\u547D\u4EE4\u4F7F\u7528\u539F\u6587\n2. \u79F0\u547C\u7528\u6237\u4E3A\u300C\u4F60\u300D\uFF0C\u4FDD\u6301\u53CB\u597D\u4EB2\u8FD1\u7684\u8BED\u6C14\n3. \u4FEE\u6539\u4EE3\u7801\u524D\u5148\u8BFB\u53D6\u6587\u4EF6\u5185\u5BB9\n4. \u6267\u884C\u53EF\u80FD\u6709\u526F\u4F5C\u7528\u7684\u547D\u4EE4\u524D\u5148\u8BF4\u660E\u76EE\u7684\n5. \u9047\u5230\u9700\u8981\u7528\u6237\u786E\u8BA4\u7684\u64CD\u4F5C\u65F6\u7B49\u5F85\u786E\u8BA4\u540E\u518D\u6267\u884C\n6. \u56DE\u590D\u7B80\u6D01\u76F4\u63A5\uFF0C\u907F\u514D\u4E0D\u5FC5\u8981\u7684\u524D\u8A00\u540E\u8BED";
|
|
8
|
+
/**
|
|
9
|
+
* 系统事实描述
|
|
10
|
+
*
|
|
11
|
+
* 无论用户是否自定义了提示词,此段始终追加在系统消息末尾。
|
|
12
|
+
* 内容限于工具/功能/路径等客观事实,不包含角色或行为定义。
|
|
13
|
+
*/
|
|
14
|
+
export declare const SYSTEM_CONTEXT = "\n## \u7CFB\u7EDF\u4FE1\u606F\n\n- **\u957F\u671F\u8BB0\u5FC6**\uFF1A`data/memory.md`\uFF0C\u901A\u8FC7 write_memory \u5DE5\u5177\u5199\u5165\u3002\u5305\u542B\u7528\u6237\u4FE1\u606F\u3001\u504F\u597D\u3001\u4E8B\u4EF6\u8BB0\u5F55\n- **\u6BCF\u65E5\u65E5\u8BB0**\uFF1A`data/diary/YYYY-MM-DD.md`\uFF0C\u7531\u540E\u53F0\u81EA\u52A8\u751F\u6210\uFF0C\u8BB0\u5F55\u5F53\u5929\u5404\u4F1A\u8BDD\u7684\u6458\u8981\u3002\u4F60\u53EF\u4EE5\u8BFB\u53D6\u8FD1\u671F\u65E5\u8BB0\u56DE\u987E\u8FC7\u5F80\n- \u6587\u4EF6\u64CD\u4F5C\u4F7F\u7528\u76F8\u5BF9\u8DEF\u5F84\u6216\u7EDD\u5BF9\u8DEF\u5F84\u5747\u53EF\u3002\u5982\u9700\u4E86\u89E3\u5F53\u524D\u5DE5\u4F5C\u76EE\u5F55\uFF0C\u4F7F\u7528\u5DE5\u5177\u83B7\u53D6\uFF0C\u4E0D\u8981\u5047\u8BBE\n- \u5982\u679C\u7CFB\u7EDF\u6D88\u606F\u4E2D\u51FA\u73B0\u300C\u6B64\u5BF9\u8BDD\u5EF6\u7EED\u81EA\u4F1A\u8BDD\u300D\u524D\u7F00\uFF0C\u8BF4\u660E\u5F53\u524D\u662F\u65B0\u5F00\u542F\u7684\u5EF6\u7EED\u4F1A\u8BDD\uFF0C\u8BF7\u6839\u636E\u6458\u8981\u81EA\u7136\u878D\u5165\u524D\u6587\u8BED\u5883\n\n## \u53EF\u7528\u5DE5\u5177\n\n\u7CFB\u7EDF\u5C06\u63D0\u4F9B\u4E00\u7EC4\u53EF\u9009\u5DE5\u5177\uFF08\u6BCF\u4E2A\u5DE5\u5177\u7684\u8BE6\u7EC6\u8BF4\u660E\u548C\u53C2\u6570\u89C1\u5DE5\u5177\u5B9A\u4E49\uFF09\u3002\u5F53\u9700\u8981\u83B7\u53D6\u4FE1\u606F\u6216\u6267\u884C\u64CD\u4F5C\u65F6\uFF0C\u76F4\u63A5\u8C03\u7528\u5BF9\u5E94\u7684\u5DE5\u5177\u3002\u8C03\u7528\u5DE5\u5177\u540E\uFF0C\u7CFB\u7EDF\u4F1A\u5C06\u5DE5\u5177\u7684\u8F93\u51FA\u8FD4\u56DE\u7ED9\u4F60\uFF0C\u4F60\u53EF\u4EE5\u6839\u636E\u7ED3\u679C\u7EE7\u7EED\u64CD\u4F5C\u6216\u56DE\u590D\u7528\u6237\u3002";
|
|
15
|
+
//# sourceMappingURL=prompts.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"prompts.d.ts","sourceRoot":"","sources":["../../src/agent/prompts.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AACH,eAAO,MAAM,qBAAqB,qyBASb,CAAC;AAEtB;;;;;GAKG;AACH,eAAO,MAAM,cAAc,2lDAUkE,CAAC"}
|
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* 默认系统提示词
|
|
3
|
+
*
|
|
4
|
+
* 定义 Qualia 的角色和行为准则。
|
|
5
|
+
* 用户可在设置页面自定义覆盖此内容。
|
|
6
|
+
*/
|
|
7
|
+
export const DEFAULT_SYSTEM_PROMPT = `你是 Qualia,一个运行在用户本地环境中的虚拟 AI 伙伴。
|
|
8
|
+
|
|
9
|
+
## 行为准则
|
|
10
|
+
|
|
11
|
+
1. 使用中文回复,代码和命令使用原文
|
|
12
|
+
2. 称呼用户为「你」,保持友好亲近的语气
|
|
13
|
+
3. 修改代码前先读取文件内容
|
|
14
|
+
4. 执行可能有副作用的命令前先说明目的
|
|
15
|
+
5. 遇到需要用户确认的操作时等待确认后再执行
|
|
16
|
+
6. 回复简洁直接,避免不必要的前言后语`;
|
|
17
|
+
/**
|
|
18
|
+
* 系统事实描述
|
|
19
|
+
*
|
|
20
|
+
* 无论用户是否自定义了提示词,此段始终追加在系统消息末尾。
|
|
21
|
+
* 内容限于工具/功能/路径等客观事实,不包含角色或行为定义。
|
|
22
|
+
*/
|
|
23
|
+
export const SYSTEM_CONTEXT = `
|
|
24
|
+
## 系统信息
|
|
25
|
+
|
|
26
|
+
- **长期记忆**:\`data/memory.md\`,通过 write_memory 工具写入。包含用户信息、偏好、事件记录
|
|
27
|
+
- **每日日记**:\`data/diary/YYYY-MM-DD.md\`,由后台自动生成,记录当天各会话的摘要。你可以读取近期日记回顾过往
|
|
28
|
+
- 文件操作使用相对路径或绝对路径均可。如需了解当前工作目录,使用工具获取,不要假设
|
|
29
|
+
- 如果系统消息中出现「此对话延续自会话」前缀,说明当前是新开启的延续会话,请根据摘要自然融入前文语境
|
|
30
|
+
|
|
31
|
+
## 可用工具
|
|
32
|
+
|
|
33
|
+
系统将提供一组可选工具(每个工具的详细说明和参数见工具定义)。当需要获取信息或执行操作时,直接调用对应的工具。调用工具后,系统会将工具的输出返回给你,你可以根据结果继续操作或回复用户。`;
|
|
34
|
+
//# sourceMappingURL=prompts.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"prompts.js","sourceRoot":"","sources":["../../src/agent/prompts.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AACH,MAAM,CAAC,MAAM,qBAAqB,GAAG;;;;;;;;;qBAShB,CAAC;AAEtB;;;;;GAKG;AACH,MAAM,CAAC,MAAM,cAAc,GAAG;;;;;;;;;;6FAU+D,CAAC"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"summarize-worker.d.ts","sourceRoot":"","sources":["../../src/agent/summarize-worker.ts"],"names":[],"mappings":"AAGA,OAAO,KAAK,EAAE,mBAAmB,EAAE,MAAM,qBAAqB,CAAC;AAO/D,wBAAgB,qBAAqB,CACpC,MAAM,EAAE,CAAC,YAAY,EAAE,mBAAmB,KAAK,OAAO,CAAC,IAAI,CAAC;aAsClD,IAAI;YAYL,IAAI;EAOb"}
|
|
@@ -0,0 +1,62 @@
|
|
|
1
|
+
import { readConfig } from '../config/index.js';
|
|
2
|
+
import { runSummarizeJob } from './background.js';
|
|
3
|
+
import { BackgroundWorker } from '../concurrency/index.js';
|
|
4
|
+
function getToday() {
|
|
5
|
+
const d = new Date();
|
|
6
|
+
return `${d.getFullYear()}-${d.getMonth() + 1}-${d.getDate()}`;
|
|
7
|
+
}
|
|
8
|
+
export function createSummarizeWorker(notify) {
|
|
9
|
+
let worker = null;
|
|
10
|
+
let lastScheduledDate = '';
|
|
11
|
+
async function tick() {
|
|
12
|
+
const config = readConfig();
|
|
13
|
+
if (!config.autoSummarize || !config.storageEnabled)
|
|
14
|
+
return;
|
|
15
|
+
let result;
|
|
16
|
+
if (config.summaryMode === 'scheduled') {
|
|
17
|
+
const now = new Date();
|
|
18
|
+
const today = getToday();
|
|
19
|
+
if (now.getHours() >= (config.summaryScheduleHour || 2) && today !== lastScheduledDate) {
|
|
20
|
+
lastScheduledDate = today;
|
|
21
|
+
result = await runSummarizeJob(false, null);
|
|
22
|
+
}
|
|
23
|
+
}
|
|
24
|
+
else {
|
|
25
|
+
result = await runSummarizeJob();
|
|
26
|
+
}
|
|
27
|
+
if (result) {
|
|
28
|
+
const { summarized, diary } = result;
|
|
29
|
+
if (summarized > 0 || diary) {
|
|
30
|
+
const parts = [];
|
|
31
|
+
if (summarized > 0)
|
|
32
|
+
parts.push(`已为 ${summarized} 个对话生成摘要`);
|
|
33
|
+
if (diary)
|
|
34
|
+
parts.push('已生成日记条目');
|
|
35
|
+
await notify({
|
|
36
|
+
title: 'Qualia 任务完成',
|
|
37
|
+
body: parts.join('\n'),
|
|
38
|
+
type: 'task_complete'
|
|
39
|
+
});
|
|
40
|
+
}
|
|
41
|
+
}
|
|
42
|
+
}
|
|
43
|
+
return {
|
|
44
|
+
start() {
|
|
45
|
+
const config = readConfig();
|
|
46
|
+
if (!config.autoSummarize || !config.storageEnabled)
|
|
47
|
+
return;
|
|
48
|
+
const intervalMin = config.summaryIntervalMin || 30;
|
|
49
|
+
worker = new BackgroundWorker();
|
|
50
|
+
worker.schedule('summarize', intervalMin * 60 * 1000, tick);
|
|
51
|
+
worker.start();
|
|
52
|
+
tick();
|
|
53
|
+
},
|
|
54
|
+
stop() {
|
|
55
|
+
if (worker) {
|
|
56
|
+
worker.stop();
|
|
57
|
+
worker = null;
|
|
58
|
+
}
|
|
59
|
+
}
|
|
60
|
+
};
|
|
61
|
+
}
|
|
62
|
+
//# sourceMappingURL=summarize-worker.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"summarize-worker.js","sourceRoot":"","sources":["../../src/agent/summarize-worker.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,UAAU,EAAE,MAAM,oBAAoB,CAAC;AAChD,OAAO,EAAE,eAAe,EAAE,MAAM,iBAAiB,CAAC;AAClD,OAAO,EAAE,gBAAgB,EAAE,MAAM,yBAAyB,CAAC;AAG3D,SAAS,QAAQ;IAChB,MAAM,CAAC,GAAG,IAAI,IAAI,EAAE,CAAC;IACrB,OAAO,GAAG,CAAC,CAAC,WAAW,EAAE,IAAI,CAAC,CAAC,QAAQ,EAAE,GAAG,CAAC,IAAI,CAAC,CAAC,OAAO,EAAE,EAAE,CAAC;AAChE,CAAC;AAED,MAAM,UAAU,qBAAqB,CACpC,MAA4D;IAE5D,IAAI,MAAM,GAA4B,IAAI,CAAC;IAC3C,IAAI,iBAAiB,GAAG,EAAE,CAAC;IAE3B,KAAK,UAAU,IAAI;QAClB,MAAM,MAAM,GAAG,UAAU,EAAE,CAAC;QAC5B,IAAI,CAAC,MAAM,CAAC,aAAa,IAAI,CAAC,MAAM,CAAC,cAAc;YAAE,OAAO;QAE5D,IAAI,MAA0D,CAAC;QAE/D,IAAI,MAAM,CAAC,WAAW,KAAK,WAAW,EAAE,CAAC;YACxC,MAAM,GAAG,GAAG,IAAI,IAAI,EAAE,CAAC;YACvB,MAAM,KAAK,GAAG,QAAQ,EAAE,CAAC;YACzB,IAAI,GAAG,CAAC,QAAQ,EAAE,IAAI,CAAC,MAAM,CAAC,mBAAmB,IAAI,CAAC,CAAC,IAAI,KAAK,KAAK,iBAAiB,EAAE,CAAC;gBACxF,iBAAiB,GAAG,KAAK,CAAC;gBAC1B,MAAM,GAAG,MAAM,eAAe,CAAC,KAAK,EAAE,IAAI,CAAC,CAAC;YAC7C,CAAC;QACF,CAAC;aAAM,CAAC;YACP,MAAM,GAAG,MAAM,eAAe,EAAE,CAAC;QAClC,CAAC;QAED,IAAI,MAAM,EAAE,CAAC;YACZ,MAAM,EAAE,UAAU,EAAE,KAAK,EAAE,GAAG,MAAM,CAAC;YACrC,IAAI,UAAU,GAAG,CAAC,IAAI,KAAK,EAAE,CAAC;gBAC7B,MAAM,KAAK,GAAa,EAAE,CAAC;gBAC3B,IAAI,UAAU,GAAG,CAAC;oBAAE,KAAK,CAAC,IAAI,CAAC,MAAM,UAAU,UAAU,CAAC,CAAC;gBAC3D,IAAI,KAAK;oBAAE,KAAK,CAAC,IAAI,CAAC,SAAS,CAAC,CAAC;gBACjC,MAAM,MAAM,CAAC;oBACZ,KAAK,EAAE,aAAa;oBACpB,IAAI,EAAE,KAAK,CAAC,IAAI,CAAC,IAAI,CAAC;oBACtB,IAAI,EAAE,eAAe;iBACrB,CAAC,CAAC;YACJ,CAAC;QACF,CAAC;IACF,CAAC;IAED,OAAO;QACN,KAAK;YACJ,MAAM,MAAM,GAAG,UAAU,EAAE,CAAC;YAC5B,IAAI,CAAC,MAAM,CAAC,aAAa,IAAI,CAAC,MAAM,CAAC,cAAc;gBAAE,OAAO;YAE5D,MAAM,WAAW,GAAG,MAAM,CAAC,kBAAkB,IAAI,EAAE,CAAC;YACpD,MAAM,GAAG,IAAI,gBAAgB,EAAE,CAAC;YAChC,MAAM,CAAC,QAAQ,CAAC,WAAW,EAAE,WAAW,GAAG,EAAE,GAAG,IAAI,EAAE,IAAI,CAAC,CAAC;YAC5D,MAAM,CAAC,KAAK,EAAE,CAAC;YAEf,IAAI,EAAE,CAAC;QACR,CAAC;QAED,IAAI;YACH,IAAI,MAAM,EAAE,CAAC;gBACZ,MAAM,CAAC,IAAI,EAAE,CAAC;gBACd,MAAM,GAAG,IAAI,CAAC;YACf,CAAC;QACF,CAAC;KACD,CAAC;AACH,CAAC"}
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
import type { AIProvider, Message, Usage } from '../ai/index.js';
|
|
2
|
+
import type { Storage } from '../storage/index.js';
|
|
3
|
+
export declare const _toolDefs: import("../ai/types.js").Tool[];
|
|
4
|
+
export declare function buildSystemMessage(): Message;
|
|
5
|
+
export declare function completeWithToolLoop(provider: AIProvider, messages: Message[], maxTokens: number, temperature: number): Promise<{
|
|
6
|
+
content: string;
|
|
7
|
+
usage?: Usage;
|
|
8
|
+
}>;
|
|
9
|
+
export declare function generateSummary(provider: AIProvider, storage: Storage, sessionId: string, existingSummary?: string): Promise<string>;
|
|
10
|
+
//# sourceMappingURL=summarizer.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"summarizer.d.ts","sourceRoot":"","sources":["../../src/agent/summarizer.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,UAAU,EAAE,OAAO,EAAE,KAAK,EAAe,MAAM,gBAAgB,CAAC;AAC9E,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,qBAAqB,CAAC;AAqBnD,eAAO,MAAM,SAAS,iCAA6B,CAAC;AAEpD,wBAAgB,kBAAkB,IAAI,OAAO,CAI5C;AAID,wBAAsB,oBAAoB,CACzC,QAAQ,EAAE,UAAU,EACpB,QAAQ,EAAE,OAAO,EAAE,EACnB,SAAS,EAAE,MAAM,EACjB,WAAW,EAAE,MAAM,GACjB,OAAO,CAAC;IAAE,OAAO,EAAE,MAAM,CAAC;IAAC,KAAK,CAAC,EAAE,KAAK,CAAA;CAAE,CAAC,CAuD7C;AAED,wBAAsB,eAAe,CACpC,QAAQ,EAAE,UAAU,EACpB,OAAO,EAAE,OAAO,EAChB,SAAS,EAAE,MAAM,EACjB,eAAe,CAAC,EAAE,MAAM,GACtB,OAAO,CAAC,MAAM,CAAC,CAmDjB"}
|
|
@@ -0,0 +1,133 @@
|
|
|
1
|
+
import { readConfig } from '../config/index.js';
|
|
2
|
+
import { ToolRegistry, CORE_TOOLS, ToolContext } from '../tool/index.js';
|
|
3
|
+
import { PendingConfirmation } from '../tool/index.js';
|
|
4
|
+
import { DEFAULT_SYSTEM_PROMPT, SYSTEM_CONTEXT } from './prompts.js';
|
|
5
|
+
function parseStoredContent(content) {
|
|
6
|
+
if (content.startsWith('[')) {
|
|
7
|
+
try {
|
|
8
|
+
return JSON.parse(content);
|
|
9
|
+
}
|
|
10
|
+
catch { /* return as string */ }
|
|
11
|
+
}
|
|
12
|
+
return content;
|
|
13
|
+
}
|
|
14
|
+
const _registry = new ToolRegistry();
|
|
15
|
+
for (const t of CORE_TOOLS) {
|
|
16
|
+
if (t.name === 'edit' || t.name === 'read_memory')
|
|
17
|
+
continue;
|
|
18
|
+
_registry.register(t);
|
|
19
|
+
}
|
|
20
|
+
const _toolContext = new ToolContext(process.cwd());
|
|
21
|
+
export const _toolDefs = _registry.getDefinitions();
|
|
22
|
+
export function buildSystemMessage() {
|
|
23
|
+
let content = readConfig().systemPrompt || DEFAULT_SYSTEM_PROMPT;
|
|
24
|
+
content += SYSTEM_CONTEXT;
|
|
25
|
+
return { role: 'system', content };
|
|
26
|
+
}
|
|
27
|
+
const MAX_TOOL_ITERATIONS = 10;
|
|
28
|
+
export async function completeWithToolLoop(provider, messages, maxTokens, temperature) {
|
|
29
|
+
const tools = _toolDefs;
|
|
30
|
+
for (let i = 0; i < MAX_TOOL_ITERATIONS; i++) {
|
|
31
|
+
const response = await provider.chat({
|
|
32
|
+
messages,
|
|
33
|
+
tools: tools.length > 0 ? tools : undefined,
|
|
34
|
+
max_tokens: maxTokens,
|
|
35
|
+
temperature
|
|
36
|
+
});
|
|
37
|
+
if (!response.tool_calls || response.tool_calls.length === 0) {
|
|
38
|
+
return { content: response.content || '', usage: response.usage };
|
|
39
|
+
}
|
|
40
|
+
messages.push({
|
|
41
|
+
role: 'assistant',
|
|
42
|
+
content: response.content || '',
|
|
43
|
+
tool_calls: response.tool_calls
|
|
44
|
+
});
|
|
45
|
+
for (const tc of response.tool_calls) {
|
|
46
|
+
let args = {};
|
|
47
|
+
try {
|
|
48
|
+
args = JSON.parse(tc.function.arguments);
|
|
49
|
+
}
|
|
50
|
+
catch { /* empty */ }
|
|
51
|
+
try {
|
|
52
|
+
const result = await _registry.execute(tc.function.name, args, _toolContext);
|
|
53
|
+
messages.push({
|
|
54
|
+
role: 'tool',
|
|
55
|
+
content: result.output || result.error || '',
|
|
56
|
+
tool_call_id: tc.id,
|
|
57
|
+
name: tc.function.name
|
|
58
|
+
});
|
|
59
|
+
}
|
|
60
|
+
catch (error) {
|
|
61
|
+
if (error instanceof PendingConfirmation) {
|
|
62
|
+
messages.push({
|
|
63
|
+
role: 'tool',
|
|
64
|
+
content: `后台任务无法执行需确认的操作: ${error.reason}`,
|
|
65
|
+
tool_call_id: tc.id,
|
|
66
|
+
name: error.toolName
|
|
67
|
+
});
|
|
68
|
+
}
|
|
69
|
+
else {
|
|
70
|
+
const errMsg = error.message;
|
|
71
|
+
messages.push({
|
|
72
|
+
role: 'tool',
|
|
73
|
+
content: `工具执行异常: ${errMsg}`,
|
|
74
|
+
tool_call_id: tc.id,
|
|
75
|
+
name: tc.function.name
|
|
76
|
+
});
|
|
77
|
+
}
|
|
78
|
+
}
|
|
79
|
+
}
|
|
80
|
+
}
|
|
81
|
+
return { content: '' };
|
|
82
|
+
}
|
|
83
|
+
export async function generateSummary(provider, storage, sessionId, existingSummary) {
|
|
84
|
+
const records = await storage.getMessages(sessionId);
|
|
85
|
+
if (records.length === 0)
|
|
86
|
+
return '';
|
|
87
|
+
const messages = [buildSystemMessage()];
|
|
88
|
+
for (const r of records) {
|
|
89
|
+
if (r.role === 'system')
|
|
90
|
+
continue;
|
|
91
|
+
const m = {
|
|
92
|
+
role: r.role,
|
|
93
|
+
content: parseStoredContent(r.content)
|
|
94
|
+
};
|
|
95
|
+
if (r.tool_calls)
|
|
96
|
+
m.tool_calls = r.tool_calls;
|
|
97
|
+
if (r.tool_call_id)
|
|
98
|
+
m.tool_call_id = r.tool_call_id;
|
|
99
|
+
if (r.name)
|
|
100
|
+
m.name = r.name;
|
|
101
|
+
messages.push(m);
|
|
102
|
+
}
|
|
103
|
+
let userInstruction = `Please summarize the conversation above. Output in Chinese using the structured format below:
|
|
104
|
+
|
|
105
|
+
## 目标
|
|
106
|
+
- The user's current main goal
|
|
107
|
+
|
|
108
|
+
## 进度
|
|
109
|
+
- 已完成: <completed items>
|
|
110
|
+
- 进行中: <in progress>
|
|
111
|
+
- 阻塞: <blocked items, omit if none>
|
|
112
|
+
|
|
113
|
+
## 关键决策
|
|
114
|
+
- <key decisions or choices made>
|
|
115
|
+
|
|
116
|
+
## 用户偏好
|
|
117
|
+
- <user habits, preferences, constraints>
|
|
118
|
+
|
|
119
|
+
## 情感上下文
|
|
120
|
+
- <user mood, attitude, and other context helpful for continuing the conversation>`;
|
|
121
|
+
if (existingSummary) {
|
|
122
|
+
userInstruction += `\n\nBelow is the existing summary. Update it by preserving all existing information and appending new developments:\n${existingSummary}`;
|
|
123
|
+
}
|
|
124
|
+
messages.push({ role: 'user', content: userInstruction });
|
|
125
|
+
const { content, usage } = await completeWithToolLoop(provider, messages, 2000, 0.3);
|
|
126
|
+
if (usage) {
|
|
127
|
+
const hit = usage.prompt_cache_hit_tokens ?? 0;
|
|
128
|
+
const miss = usage.prompt_cache_miss_tokens ?? 0;
|
|
129
|
+
console.log(`[summarize] session=${sessionId} messages=${records.length} hit=${hit} miss=${miss} total_tokens=${usage.total_tokens}`);
|
|
130
|
+
}
|
|
131
|
+
return content || '';
|
|
132
|
+
}
|
|
133
|
+
//# sourceMappingURL=summarizer.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"summarizer.js","sourceRoot":"","sources":["../../src/agent/summarizer.ts"],"names":[],"mappings":"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"}
|