@bolloon/bolloon-agent 0.1.35 → 0.1.36
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/.playwright-mcp/page-2026-06-16T07-51-45-706Z.yml +130 -0
- package/.playwright-mcp/page-2026-06-16T07-56-44-116Z.yml +131 -0
- package/Bolloon.md +45 -4
- package/Dive-into/CITATION.cff +17 -0
- package/Dive-into/LICENSE +25 -0
- package/Dive-into/README.md +598 -0
- package/Dive-into/README_zh.md +599 -0
- package/Dive-into/assets/context.png +0 -0
- package/Dive-into/assets/extensibility.png +0 -0
- package/Dive-into/assets/iteration.png +0 -0
- package/Dive-into/assets/layered_architecture.png +0 -0
- package/Dive-into/assets/main_structure.png +0 -0
- package/Dive-into/assets/permission.png +0 -0
- package/Dive-into/assets/session_compact.png +0 -0
- package/Dive-into/assets/subagent.png +0 -0
- package/Dive-into/paper/Dive_into_Claude_Code.pdf +0 -0
- package/README.md +1 -1
- package/dist/agents/p2p-chat-tools.js +6 -6
- package/dist/agents/permission-mode.js +115 -0
- package/dist/agents/pi-sdk.js +435 -25
- package/dist/agents/pre-tool-validator.js +194 -0
- package/dist/agents/workflow-pivot-loop.js +113 -12
- package/dist/bollharness/src/scripts/checks/check_doc_freshness.js +1 -1
- package/dist/bollharness/src/scripts/checks/check_doc_links.js +1 -1
- package/dist/bollharness/src/scripts/context_router.js +1 -1
- package/dist/bollharness/src/scripts/deploy-guard.js +1 -1
- package/dist/bollharness/src/scripts/guard_router.js +1 -1
- package/dist/bollharness/src/scripts/hooks/_hook_output.js +1 -1
- package/dist/bollharness/src/scripts/hooks/risk-tracker.js +1 -1
- package/dist/bollharness-integration/context-router.js +2 -2
- package/dist/bollharness-integration/guard-checker.js +1 -1
- package/dist/bootstrap/bootstrap.js +3 -0
- package/dist/bootstrap/context-collector.js +17 -1
- package/dist/bootstrap/context-hierarchy.js +218 -0
- package/dist/bootstrap/lifecycle-hooks.js +86 -24
- package/dist/bootstrap/project-context.js +10 -3
- package/dist/context-compaction/auto-compact.js +144 -0
- package/dist/context-compaction/budget-gate.js +28 -0
- package/dist/context-compaction/budget-reduce.js +35 -0
- package/dist/context-compaction/context-collapse.js +66 -0
- package/dist/context-compaction/index.js +21 -0
- package/dist/context-compaction/microcompact.js +51 -0
- package/dist/context-compaction/pipeline.js +123 -0
- package/dist/context-compaction/snip.js +45 -0
- package/dist/context-compaction/token-estimator.js +35 -0
- package/dist/context-compaction/types.js +19 -0
- package/dist/heartbeat/HealthMonitor.js +3 -2
- package/dist/index.js +38 -2
- package/dist/llm/llm-judgment-client.js +32 -30
- package/dist/llm/pi-ai.js +103 -16
- package/dist/llm/system-prompt/health.js +129 -0
- package/dist/llm/system-prompt/registry.js +246 -0
- package/dist/llm/system-prompt/strip-hibsml.js +51 -0
- package/dist/llm/tool-manifest/ask_user_input.js +35 -0
- package/dist/llm/tool-manifest/bash.js +23 -0
- package/dist/llm/tool-manifest/create_file.js +24 -0
- package/dist/llm/tool-manifest/fetch_sports_data.js +26 -0
- package/dist/llm/tool-manifest/image_search.js +24 -0
- package/dist/llm/tool-manifest/index.js +69 -0
- package/dist/llm/tool-manifest/mcp.js +43 -0
- package/dist/llm/tool-manifest/message_compose.js +31 -0
- package/dist/llm/tool-manifest/places.js +83 -0
- package/dist/llm/tool-manifest/present_files.js +21 -0
- package/dist/llm/tool-manifest/recipe.js +40 -0
- package/dist/llm/tool-manifest/recommend_apps.js +23 -0
- package/dist/llm/tool-manifest/str_replace.js +27 -0
- package/dist/llm/tool-manifest/types.js +7 -0
- package/dist/llm/tool-manifest/view.js +24 -0
- package/dist/llm/tool-manifest/weather.js +27 -0
- package/dist/llm/tool-manifest/web.js +51 -0
- package/dist/network/p2p-direct.js +23 -0
- package/dist/network/source-intent-broadcaster.js +203 -0
- package/dist/network/source-intent.js +100 -0
- package/dist/pi-ecosystem-judgment/adaptive-scan.js +48 -0
- package/dist/pi-ecosystem-judgment/injection-gate.js +54 -12
- package/dist/pi-ecosystem-judgment/value-injection.js +8 -2
- package/dist/security/context-router-tool.js +1 -1
- package/dist/security/input-scanner.js +223 -0
- package/dist/web/client.js +3677 -4161
- package/dist/web/components/p2p/P2PModal.js +188 -0
- package/dist/web/components/p2p/index.js +264 -226
- package/dist/web/components/p2p/p2p-modal.js +657 -0
- package/dist/web/components/p2p/p2p-tools.js +248 -0
- package/dist/web/index.html +58 -67
- package/dist/web/server.js +299 -117
- package/dist/web/style.css +531 -249
- package/dist/web/ui/message-renderer.js +463 -0
- package/dist/web/ui/step-timeline.js +375 -0
- package/lefthook.yml +4 -0
- package/package.json +1 -1
- package/scripts/auto-evolve-loop.ts +105 -0
- package/scripts/build-web.ts +35 -1
- package/scripts/validate-system-prompt.ts +142 -0
- package/src/agents/p2p-chat-tools.ts +6 -6
- package/src/agents/permission-mode.ts +127 -0
- package/src/agents/pi-sdk.ts +461 -28
- package/src/agents/pre-tool-validator.ts +213 -0
- package/src/agents/workflow-pivot-loop.ts +110 -19
- package/src/bollharness/CLAUDE.md +1 -1
- package/src/bollharness/README.md +2 -2
- package/src/bollharness/README.zh-CN.md +2 -2
- package/src/bollharness/reference/boll-reference/scripts/hooks/find-boll-root.sh +2 -2
- package/src/bollharness/scripts/context-fragments/truth-source-hierarchy.md +2 -2
- package/src/bollharness/scripts/context-fragments/version-sources.md +1 -1
- package/src/bollharness/scripts/hooks/find-project-root.sh +4 -4
- package/src/bollharness/src/scripts/checks/check_doc_freshness.ts +1 -1
- package/src/bollharness/src/scripts/checks/check_doc_links.ts +1 -1
- package/src/bollharness/src/scripts/context_router.ts +1 -1
- package/src/bollharness/src/scripts/deploy-guard.ts +1 -1
- package/src/bollharness/src/scripts/guard_router.ts +1 -1
- package/src/bollharness/src/scripts/hooks/_hook_output.ts +1 -1
- package/src/bollharness/src/scripts/hooks/risk-tracker.ts +1 -1
- package/src/bollharness/templates/scaffold/.gitignore.append +1 -1
- package/src/bollharness/templates/scaffold/CLAUDE.md +2 -2
- package/src/bollharness-integration/context-router.ts +2 -2
- package/src/bollharness-integration/guard-checker.ts +1 -1
- package/src/bootstrap/bootstrap.ts +3 -0
- package/src/bootstrap/context-collector.ts +30 -1
- package/src/bootstrap/context-hierarchy.ts +283 -0
- package/src/bootstrap/lifecycle-hooks.ts +139 -26
- package/src/bootstrap/project-context.ts +11 -3
- package/src/context-compaction/auto-compact.ts +153 -0
- package/src/context-compaction/budget-gate.ts +32 -0
- package/src/context-compaction/budget-reduce.ts +37 -0
- package/src/context-compaction/context-collapse.ts +72 -0
- package/src/context-compaction/index.ts +24 -0
- package/src/context-compaction/microcompact.ts +54 -0
- package/src/context-compaction/pipeline.ts +133 -0
- package/src/context-compaction/snip.ts +51 -0
- package/src/context-compaction/token-estimator.ts +36 -0
- package/src/context-compaction/types.ts +99 -0
- package/src/heartbeat/HealthMonitor.ts +3 -2
- package/src/index.ts +36 -2
- package/src/llm/llm-judgment-client.ts +36 -35
- package/src/llm/pi-ai.ts +111 -16
- package/src/llm/system-prompt/health.ts +159 -0
- package/src/llm/system-prompt/layers/channel/local.md +14 -0
- package/src/llm/system-prompt/layers/channel/p2p-agent.md +18 -0
- package/src/llm/system-prompt/layers/channel/p2p-visitor.md +19 -0
- package/src/llm/system-prompt/layers/core/artifacts_storage.md +89 -0
- package/src/llm/system-prompt/layers/core/evenhandedness.md +21 -0
- package/src/llm/system-prompt/layers/core/hibs_reminders.md +15 -0
- package/src/llm/system-prompt/layers/core/identity.md +37 -0
- package/src/llm/system-prompt/layers/core/knowledge.md +17 -0
- package/src/llm/system-prompt/layers/core/memory_system.md +12 -0
- package/src/llm/system-prompt/layers/core/network_filesystem.md +28 -0
- package/src/llm/system-prompt/layers/core/refusal.md +37 -0
- package/src/llm/system-prompt/layers/core/tone.md +31 -0
- package/src/llm/system-prompt/layers/core/tools.thin.md +13 -0
- package/src/llm/system-prompt/layers/core/wellbeing.md +41 -0
- package/src/llm/system-prompt/layers/role/architect.md +20 -0
- package/src/llm/system-prompt/layers/role/expert.md +19 -0
- package/src/llm/system-prompt/layers/role/implementer.md +15 -0
- package/src/llm/system-prompt/layers/role/security.md +15 -0
- package/src/llm/system-prompt/layers/tool/artifacts.md +72 -0
- package/src/llm/system-prompt/layers/tool/bash.md +25 -0
- package/src/llm/system-prompt/layers/tool/hibs_api.md +171 -0
- package/src/llm/system-prompt/layers/tool/image_search.md +70 -0
- package/src/llm/system-prompt/layers/tool/manifest.md +89 -0
- package/src/llm/system-prompt/layers/tool/mcp_apps.md +53 -0
- package/src/llm/system-prompt/layers/tool/web_search.md +83 -0
- package/src/llm/system-prompt/registry.ts +325 -0
- package/src/llm/system-prompt/strip-hibsml.ts +52 -0
- package/src/llm/tool-manifest/ask_user_input.ts +37 -0
- package/src/llm/tool-manifest/bash.ts +25 -0
- package/src/llm/tool-manifest/create_file.ts +26 -0
- package/src/llm/tool-manifest/fetch_sports_data.ts +28 -0
- package/src/llm/tool-manifest/image_search.ts +26 -0
- package/src/llm/tool-manifest/index.ts +88 -0
- package/src/llm/tool-manifest/mcp.ts +46 -0
- package/src/llm/tool-manifest/message_compose.ts +33 -0
- package/src/llm/tool-manifest/places.ts +86 -0
- package/src/llm/tool-manifest/present_files.ts +23 -0
- package/src/llm/tool-manifest/recipe.ts +42 -0
- package/src/llm/tool-manifest/recommend_apps.ts +25 -0
- package/src/llm/tool-manifest/str_replace.ts +29 -0
- package/src/llm/tool-manifest/types.ts +52 -0
- package/src/llm/tool-manifest/view.ts +26 -0
- package/src/llm/tool-manifest/weather.ts +29 -0
- package/src/llm/tool-manifest/web.ts +54 -0
- package/src/network/p2p-direct.ts +22 -0
- package/src/network/source-intent-broadcaster.ts +242 -0
- package/src/network/source-intent.ts +167 -0
- package/src/security/context-router-tool.ts +1 -1
- package/src/security/input-scanner.ts +287 -0
- package/src/web/client.js +271 -2817
- package/src/web/client.ts +4326 -0
- package/src/web/index.html +58 -67
- package/src/web/server.ts +301 -141
- package/src/web/style.css +531 -249
- package/src/web/ui/message-renderer.ts +540 -0
- package/src/web/ui/step-timeline.ts +394 -0
- package/test-results/.last-run.json +6 -0
- package/test-results/src-test-web-loop-status-b-5734c-atus-bar-/346/230/276/347/244/272-spinner-/344/270/215/346/230/276/347/244/272/345/276/252/347/216/257/350/256/241/346/225/260/error-context.md +285 -0
|
@@ -0,0 +1,248 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* P2P 工具调用模块
|
|
3
|
+
* 支持文件和本地信息的 P2P 传递
|
|
4
|
+
*/
|
|
5
|
+
// 工具类型枚举
|
|
6
|
+
export var P2PToolType;
|
|
7
|
+
(function (P2PToolType) {
|
|
8
|
+
P2PToolType["FILE_TRANSFER"] = "file_transfer";
|
|
9
|
+
P2PToolType["LOCAL_INFO"] = "local_info";
|
|
10
|
+
P2PToolType["SYSTEM_INFO"] = "system_info";
|
|
11
|
+
P2PToolType["FILE_LIST"] = "file_list";
|
|
12
|
+
})(P2PToolType || (P2PToolType = {}));
|
|
13
|
+
// 文件传输
|
|
14
|
+
export async function transferFile(targetDid, fileInfo, messageId) {
|
|
15
|
+
try {
|
|
16
|
+
const payload = {
|
|
17
|
+
type: 'file',
|
|
18
|
+
tool: P2PToolType.FILE_TRANSFER,
|
|
19
|
+
data: {
|
|
20
|
+
name: fileInfo.name,
|
|
21
|
+
size: fileInfo.size,
|
|
22
|
+
mimeType: fileInfo.mimeType,
|
|
23
|
+
content: fileInfo.content
|
|
24
|
+
}
|
|
25
|
+
};
|
|
26
|
+
const res = await fetch('/api/message-p2p', {
|
|
27
|
+
method: 'POST',
|
|
28
|
+
headers: { 'Content-Type': 'application/json' },
|
|
29
|
+
body: JSON.stringify({
|
|
30
|
+
targetDid,
|
|
31
|
+
content: JSON.stringify(payload),
|
|
32
|
+
type: 'file'
|
|
33
|
+
})
|
|
34
|
+
});
|
|
35
|
+
if (res.ok) {
|
|
36
|
+
const data = await res.json();
|
|
37
|
+
return {
|
|
38
|
+
success: true,
|
|
39
|
+
messageId: data.messageId || messageId
|
|
40
|
+
};
|
|
41
|
+
}
|
|
42
|
+
else {
|
|
43
|
+
return { success: false, error: '文件传输失败' };
|
|
44
|
+
}
|
|
45
|
+
}
|
|
46
|
+
catch (e) {
|
|
47
|
+
return { success: false, error: e.message };
|
|
48
|
+
}
|
|
49
|
+
}
|
|
50
|
+
// 本地信息查询
|
|
51
|
+
export async function queryLocalInfo(targetDid, query) {
|
|
52
|
+
try {
|
|
53
|
+
const payload = {
|
|
54
|
+
type: 'info_query',
|
|
55
|
+
tool: P2PToolType.LOCAL_INFO,
|
|
56
|
+
query: query
|
|
57
|
+
};
|
|
58
|
+
const res = await fetch('/api/message-p2p', {
|
|
59
|
+
method: 'POST',
|
|
60
|
+
headers: { 'Content-Type': 'application/json' },
|
|
61
|
+
body: JSON.stringify({
|
|
62
|
+
targetDid,
|
|
63
|
+
content: JSON.stringify(payload),
|
|
64
|
+
type: 'ai-dialogue'
|
|
65
|
+
})
|
|
66
|
+
});
|
|
67
|
+
if (res.ok) {
|
|
68
|
+
const data = await res.json();
|
|
69
|
+
return {
|
|
70
|
+
success: true,
|
|
71
|
+
data: data.response,
|
|
72
|
+
messageId: data.messageId
|
|
73
|
+
};
|
|
74
|
+
}
|
|
75
|
+
else {
|
|
76
|
+
return { success: false, error: '信息查询失败' };
|
|
77
|
+
}
|
|
78
|
+
}
|
|
79
|
+
catch (e) {
|
|
80
|
+
return { success: false, error: e.message };
|
|
81
|
+
}
|
|
82
|
+
}
|
|
83
|
+
// 系统信息请求
|
|
84
|
+
export async function getSystemInfo(targetDid) {
|
|
85
|
+
try {
|
|
86
|
+
const payload = {
|
|
87
|
+
type: 'system_info_request',
|
|
88
|
+
tool: P2PToolType.SYSTEM_INFO
|
|
89
|
+
};
|
|
90
|
+
const res = await fetch('/api/message-p2p', {
|
|
91
|
+
method: 'POST',
|
|
92
|
+
headers: { 'Content-Type': 'application/json' },
|
|
93
|
+
body: JSON.stringify({
|
|
94
|
+
targetDid,
|
|
95
|
+
content: JSON.stringify(payload),
|
|
96
|
+
type: 'ai-dialogue'
|
|
97
|
+
})
|
|
98
|
+
});
|
|
99
|
+
if (res.ok) {
|
|
100
|
+
const data = await res.json();
|
|
101
|
+
return {
|
|
102
|
+
success: true,
|
|
103
|
+
data: data.response,
|
|
104
|
+
messageId: data.messageId
|
|
105
|
+
};
|
|
106
|
+
}
|
|
107
|
+
else {
|
|
108
|
+
return { success: false, error: '系统信息获取失败' };
|
|
109
|
+
}
|
|
110
|
+
}
|
|
111
|
+
catch (e) {
|
|
112
|
+
return { success: false, error: e.message };
|
|
113
|
+
}
|
|
114
|
+
}
|
|
115
|
+
// 文件列表请求
|
|
116
|
+
export async function listFiles(targetDid, path = '/') {
|
|
117
|
+
try {
|
|
118
|
+
const payload = {
|
|
119
|
+
type: 'file_list_request',
|
|
120
|
+
tool: P2PToolType.FILE_LIST,
|
|
121
|
+
path: path
|
|
122
|
+
};
|
|
123
|
+
const res = await fetch('/api/message-p2p', {
|
|
124
|
+
method: 'POST',
|
|
125
|
+
headers: { 'Content-Type': 'application/json' },
|
|
126
|
+
body: JSON.stringify({
|
|
127
|
+
targetDid,
|
|
128
|
+
content: JSON.stringify(payload),
|
|
129
|
+
type: 'ai-dialogue'
|
|
130
|
+
})
|
|
131
|
+
});
|
|
132
|
+
if (res.ok) {
|
|
133
|
+
const data = await res.json();
|
|
134
|
+
return {
|
|
135
|
+
success: true,
|
|
136
|
+
data: data.response,
|
|
137
|
+
messageId: data.messageId
|
|
138
|
+
};
|
|
139
|
+
}
|
|
140
|
+
else {
|
|
141
|
+
return { success: false, error: '文件列表获取失败' };
|
|
142
|
+
}
|
|
143
|
+
}
|
|
144
|
+
catch (e) {
|
|
145
|
+
return { success: false, error: e.message };
|
|
146
|
+
}
|
|
147
|
+
}
|
|
148
|
+
// 工具调用入口
|
|
149
|
+
export async function executeP2PTool(request) {
|
|
150
|
+
const { toolName, payload, targetDid } = request;
|
|
151
|
+
if (!targetDid) {
|
|
152
|
+
return { success: false, error: '未指定目标节点' };
|
|
153
|
+
}
|
|
154
|
+
switch (toolName) {
|
|
155
|
+
case P2PToolType.FILE_TRANSFER:
|
|
156
|
+
return transferFile(targetDid, payload.data);
|
|
157
|
+
case P2PToolType.LOCAL_INFO:
|
|
158
|
+
return queryLocalInfo(targetDid, payload.data);
|
|
159
|
+
case P2PToolType.SYSTEM_INFO:
|
|
160
|
+
return getSystemInfo(targetDid);
|
|
161
|
+
case P2PToolType.FILE_LIST:
|
|
162
|
+
return listFiles(targetDid, payload.data?.path || '/');
|
|
163
|
+
default:
|
|
164
|
+
return { success: false, error: `未知工具: ${toolName}` };
|
|
165
|
+
}
|
|
166
|
+
}
|
|
167
|
+
// 本地系统信息获取 (用于响应来自远程的请求)
|
|
168
|
+
export function getLocalSystemInfo() {
|
|
169
|
+
const memUsage = process.memoryUsage();
|
|
170
|
+
const cpuCores = require('os').cpus();
|
|
171
|
+
return {
|
|
172
|
+
platform: process.platform,
|
|
173
|
+
arch: process.arch,
|
|
174
|
+
nodeVersion: process.version,
|
|
175
|
+
memory: {
|
|
176
|
+
total: memUsage.heapTotal,
|
|
177
|
+
free: memUsage.heapTotal - memUsage.heapUsed,
|
|
178
|
+
used: memUsage.heapUsed
|
|
179
|
+
},
|
|
180
|
+
cpu: {
|
|
181
|
+
cores: cpuCores.length,
|
|
182
|
+
model: cpuCores[0]?.model || 'Unknown'
|
|
183
|
+
},
|
|
184
|
+
uptime: process.uptime()
|
|
185
|
+
};
|
|
186
|
+
}
|
|
187
|
+
// 本地文件列表 (用于响应来自远程的请求)
|
|
188
|
+
export function getLocalFileList(dirPath) {
|
|
189
|
+
try {
|
|
190
|
+
// Dynamic import for ESM compatibility
|
|
191
|
+
const pathModule = require('path');
|
|
192
|
+
const fs = require('fs');
|
|
193
|
+
const fullPath = pathModule.resolve(dirPath);
|
|
194
|
+
const files = fs.readdirSync(fullPath);
|
|
195
|
+
const fileList = files.map((name) => {
|
|
196
|
+
const fullFilePath = pathModule.join(fullPath, name);
|
|
197
|
+
let stat;
|
|
198
|
+
try {
|
|
199
|
+
stat = fs.statSync(fullFilePath);
|
|
200
|
+
}
|
|
201
|
+
catch {
|
|
202
|
+
return null;
|
|
203
|
+
}
|
|
204
|
+
return {
|
|
205
|
+
name: name,
|
|
206
|
+
size: stat.size,
|
|
207
|
+
isDirectory: stat.isDirectory(),
|
|
208
|
+
modified: stat.mtime.toISOString()
|
|
209
|
+
};
|
|
210
|
+
}).filter(Boolean);
|
|
211
|
+
return {
|
|
212
|
+
success: true,
|
|
213
|
+
path: fullPath,
|
|
214
|
+
files: fileList
|
|
215
|
+
};
|
|
216
|
+
}
|
|
217
|
+
catch (e) {
|
|
218
|
+
return {
|
|
219
|
+
success: false,
|
|
220
|
+
path: dirPath,
|
|
221
|
+
error: e.message
|
|
222
|
+
};
|
|
223
|
+
}
|
|
224
|
+
}
|
|
225
|
+
// 导出工具名称列表
|
|
226
|
+
export const P2P_TOOLS = [
|
|
227
|
+
{
|
|
228
|
+
name: P2PToolType.FILE_TRANSFER,
|
|
229
|
+
description: '传输文件到远程节点',
|
|
230
|
+
parameters: ['targetDid', 'fileInfo']
|
|
231
|
+
},
|
|
232
|
+
{
|
|
233
|
+
name: P2PToolType.LOCAL_INFO,
|
|
234
|
+
description: '查询远程节点本地信息',
|
|
235
|
+
parameters: ['targetDid', 'query']
|
|
236
|
+
},
|
|
237
|
+
{
|
|
238
|
+
name: P2PToolType.SYSTEM_INFO,
|
|
239
|
+
description: '获取远程节点系统信息',
|
|
240
|
+
parameters: ['targetDid']
|
|
241
|
+
},
|
|
242
|
+
{
|
|
243
|
+
name: P2PToolType.FILE_LIST,
|
|
244
|
+
description: '列出远程节点目录文件',
|
|
245
|
+
parameters: ['targetDid', 'path']
|
|
246
|
+
}
|
|
247
|
+
];
|
|
248
|
+
console.log('[P2P Tools] 工具模块已加载');
|
package/dist/web/index.html
CHANGED
|
@@ -36,10 +36,8 @@
|
|
|
36
36
|
<span class="brand-icon">◈</span>
|
|
37
37
|
<span class="brand-text">Bolloon</span>
|
|
38
38
|
</span>
|
|
39
|
-
<!-- 2026-06-11: 加载 Session 文件夹按钮删除 -->
|
|
39
|
+
<!-- 2026-06-11: 加载 Session 文件夹按钮删除 (2026-06-16: 残留注释 + input 占位同步清除) -->
|
|
40
40
|
</div>
|
|
41
|
-
<!-- 2026-06-11: session-file-input 已无用, 同步删除 -->
|
|
42
|
-
<!-- <input type="file" id="session-file-input" accept=".json" style="display:none"> -->
|
|
43
41
|
|
|
44
42
|
<div class="sidebar-section">
|
|
45
43
|
<div class="section-header">
|
|
@@ -63,19 +61,19 @@
|
|
|
63
61
|
|
|
64
62
|
<!-- v3 远端 P2P 好友 — 显式分享 + 持久化连接 -->
|
|
65
63
|
<div class="sidebar-section" id="remote-agents-section">
|
|
66
|
-
<div class="section-header" id="remote-agents-header"
|
|
67
|
-
<span
|
|
68
|
-
<span id="remote-agents-toggle"
|
|
69
|
-
<span class="section-title"
|
|
64
|
+
<div class="section-header is-compact is-clickable" id="remote-agents-header">
|
|
65
|
+
<span class="section-header-row">
|
|
66
|
+
<span id="remote-agents-toggle">▼</span>
|
|
67
|
+
<span class="section-title">P2P 好友</span>
|
|
70
68
|
</span>
|
|
71
|
-
<span
|
|
72
|
-
<button id="p2p-toggle-all-btn"
|
|
73
|
-
<button id="show-my-p2p-id-btn" title="查看并复制我的 P2P publicKey"
|
|
74
|
-
<button id="add-p2p-peer-btn" title="添加 P2P 好友 (输入对方的 publicKey)"
|
|
69
|
+
<span class="section-header-actions">
|
|
70
|
+
<button id="p2p-toggle-all-btn" class="sidebar-mini-btn" title="切换全部展开/折叠">⊞ 展开</button>
|
|
71
|
+
<button id="show-my-p2p-id-btn" class="sidebar-mini-btn" title="查看并复制我的 P2P publicKey">我的 ID</button>
|
|
72
|
+
<button id="add-p2p-peer-btn" class="sidebar-mini-btn" title="添加 P2P 好友 (输入对方的 publicKey)">+ 好友</button>
|
|
75
73
|
</span>
|
|
76
74
|
</div>
|
|
77
|
-
<ul class="channel-list" id="remote-channel-list"
|
|
78
|
-
<li
|
|
75
|
+
<ul class="channel-list" id="remote-channel-list">
|
|
76
|
+
<li class="sidebar-empty-hint">(暂无好友, 点 + 添加)</li>
|
|
79
77
|
</ul>
|
|
80
78
|
</div>
|
|
81
79
|
|
|
@@ -168,12 +166,11 @@
|
|
|
168
166
|
<div class="modal-body">
|
|
169
167
|
<div class="form-group">
|
|
170
168
|
<label>任务类型</label>
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
</select>
|
|
169
|
+
<select id="task-type">
|
|
170
|
+
<option value="chat">对话</option>
|
|
171
|
+
<option value="read">读取文档</option>
|
|
172
|
+
<option value="summarize">总结文档</option>
|
|
173
|
+
</select>
|
|
177
174
|
</div>
|
|
178
175
|
<div class="form-group">
|
|
179
176
|
<label>任务标题</label>
|
|
@@ -183,10 +180,6 @@
|
|
|
183
180
|
<label>任务描述</label>
|
|
184
181
|
<textarea id="task-desc" placeholder="输入任务描述或内容" rows="3"></textarea>
|
|
185
182
|
</div>
|
|
186
|
-
<div class="form-group workflow-steps" style="display:none;">
|
|
187
|
-
<label>工作流步骤(每行一个)</label>
|
|
188
|
-
<textarea id="task-steps" placeholder="步骤1 步骤2 步骤3" rows="4"></textarea>
|
|
189
|
-
</div>
|
|
190
183
|
<div class="btn-group">
|
|
191
184
|
<button id="task-cancel-btn" class="btn-secondary">取消</button>
|
|
192
185
|
<button id="task-create-btn" class="btn-primary">创建并执行</button>
|
|
@@ -211,8 +204,8 @@
|
|
|
211
204
|
<label>理由 (reason, 可选)</label>
|
|
212
205
|
<input type="text" id="judgment-reason" placeholder="例: 信任 Bolloon 的判断存储">
|
|
213
206
|
</div>
|
|
214
|
-
<div class="form-group
|
|
215
|
-
<label
|
|
207
|
+
<div class="form-group judgment-form-row">
|
|
208
|
+
<label>领域 (domain)</label>
|
|
216
209
|
<select id="judgment-domain">
|
|
217
210
|
<option value="general">general</option>
|
|
218
211
|
<option value="code">code</option>
|
|
@@ -220,7 +213,7 @@
|
|
|
220
213
|
<option value="security">security</option>
|
|
221
214
|
<option value="testing">testing</option>
|
|
222
215
|
</select>
|
|
223
|
-
<label
|
|
216
|
+
<label>风险 (stakes)</label>
|
|
224
217
|
<select id="judgment-stakes">
|
|
225
218
|
<option value="medium">medium</option>
|
|
226
219
|
<option value="low">low</option>
|
|
@@ -228,50 +221,40 @@
|
|
|
228
221
|
<option value="critical">critical</option>
|
|
229
222
|
</select>
|
|
230
223
|
</div>
|
|
231
|
-
<div class="btn-group"
|
|
224
|
+
<div class="btn-group">
|
|
232
225
|
<button id="judgment-submit-btn" class="btn-primary">记录</button>
|
|
233
226
|
<button id="judgment-import-btn" class="btn-secondary" title="从 .json / .yaml / .md / .txt / .html 文件批量导入">导入文件</button>
|
|
234
227
|
<input type="file" id="judgment-import-file" accept=".json,.yaml,.yml,.md,.txt,.html,.htm" style="display:none">
|
|
235
228
|
</div>
|
|
236
|
-
<div id="judgment-error" class="form-info
|
|
229
|
+
<div id="judgment-error" class="form-info judgment-error"></div>
|
|
237
230
|
<!-- v3 重做: tab 切换 — 默认显示当前 channel 的 judgment 上下文, 切换后才是全部 -->
|
|
238
|
-
<div id="judgments-tabs"
|
|
239
|
-
<button class="judgment-tab active" data-tab="channel"
|
|
240
|
-
|
|
241
|
-
本 channel <span id="judgments-tab-channel-name" style="font-weight:normal;color:#6b7280;"></span>
|
|
242
|
-
</button>
|
|
243
|
-
<button class="judgment-tab" data-tab="global"
|
|
244
|
-
style="flex:1;padding:10px 12px;background:none;border:none;border-bottom:2px solid transparent;color:#6b7280;font-size:13px;font-weight:600;cursor:pointer;">
|
|
245
|
-
全局
|
|
231
|
+
<div id="judgments-tabs" class="judgment-tab-bar">
|
|
232
|
+
<button class="judgment-tab active" data-tab="channel">
|
|
233
|
+
本 channel <span id="judgments-tab-channel-name" class="tab-channel-name"></span>
|
|
246
234
|
</button>
|
|
235
|
+
<button class="judgment-tab" data-tab="global">全局</button>
|
|
247
236
|
</div>
|
|
248
237
|
<!-- AI 演化 status 过滤: active / superseded / all / violations / 自适应 -->
|
|
249
|
-
<div id="judgments-status-filter"
|
|
250
|
-
<span
|
|
251
|
-
<button class="judgment-status-tab active" data-status="all"
|
|
252
|
-
|
|
253
|
-
<button class="judgment-status-tab" data-status="
|
|
254
|
-
|
|
255
|
-
<button class="judgment-status-tab" data-status="
|
|
256
|
-
|
|
257
|
-
<button class="judgment-status-tab" data-status="violations"
|
|
258
|
-
style="background:#e5e7eb;color:#374151;border:none;padding:3px 10px;border-radius:3px;cursor:pointer;font-size:11px;">违规记录</button>
|
|
259
|
-
<button class="judgment-status-tab" data-status="adaptive"
|
|
260
|
-
style="background:#e5e7eb;color:#374151;border:none;padding:3px 10px;border-radius:3px;cursor:pointer;font-size:11px;">📊 自适应</button>
|
|
261
|
-
<button class="judgment-status-tab" data-status="causal"
|
|
262
|
-
style="background:#e5e7eb;color:#374151;border:none;padding:3px 10px;border-radius:3px;cursor:pointer;font-size:11px;">🔍 因果分析</button>
|
|
238
|
+
<div id="judgments-status-filter" class="judgment-status-bar">
|
|
239
|
+
<span class="label">演化过滤:</span>
|
|
240
|
+
<button class="judgment-status-tab active" data-status="all">全部</button>
|
|
241
|
+
<button class="judgment-status-tab" data-status="active">活跃</button>
|
|
242
|
+
<button class="judgment-status-tab" data-status="superseded">已过时</button>
|
|
243
|
+
<button class="judgment-status-tab" data-status="violations">违规记录</button>
|
|
244
|
+
<button class="judgment-status-tab" data-status="adaptive">📊 自适应</button>
|
|
245
|
+
<button class="judgment-status-tab" data-status="causal">🔍 因果分析</button>
|
|
263
246
|
</div>
|
|
264
|
-
<h3
|
|
247
|
+
<h3 class="judgment-list-header">
|
|
265
248
|
<span id="judgments-list-title">本 channel 的判断力</span>
|
|
266
|
-
<span
|
|
267
|
-
<label
|
|
268
|
-
<input type="checkbox" id="judgment-select-all"
|
|
249
|
+
<span class="judgment-list-actions">
|
|
250
|
+
<label class="judgment-select-all-label">
|
|
251
|
+
<input type="checkbox" id="judgment-select-all"> 全选
|
|
269
252
|
</label>
|
|
270
|
-
<span id="judgment-selected-count"
|
|
271
|
-
<button id="judgment-bulk-delete-btn" class="
|
|
253
|
+
<span id="judgment-selected-count">已选 0</span>
|
|
254
|
+
<button id="judgment-bulk-delete-btn" class="judgment-bulk-delete" disabled>批量删除</button>
|
|
272
255
|
</span>
|
|
273
256
|
</h3>
|
|
274
|
-
<div id="judgments-list" class="task-list
|
|
257
|
+
<div id="judgments-list" class="task-list judgment-list">
|
|
275
258
|
<div class="task-empty">加载中...</div>
|
|
276
259
|
</div>
|
|
277
260
|
</div>
|
|
@@ -351,24 +334,30 @@
|
|
|
351
334
|
|
|
352
335
|
<div class="messages" id="messages"></div>
|
|
353
336
|
|
|
354
|
-
|
|
355
|
-
|
|
356
|
-
|
|
357
|
-
|
|
358
|
-
|
|
359
|
-
|
|
360
|
-
|
|
361
|
-
<
|
|
337
|
+
<!-- 2026-06-15: 旧 loop-timeline-panel 删除 — 步骤状态条改在每条 AI 消息气泡内挂 step-timeline 组件 -->
|
|
338
|
+
<!-- 2026-06-16: 循环 status bar — 渲染 tool='loop' | 'compactor' | 'recovery' 的 status 事件
|
|
339
|
+
三态机: loading (spinner, 循环中) / retrying (spinner + "自动重试中 X/N", 失败自动重试) / done (检查按钮)
|
|
340
|
+
重试是 server 端自动的, 不暴露按钮给用户. -->
|
|
341
|
+
<div id="loop-status-bar" class="loop-status-bar" hidden data-state="loading">
|
|
342
|
+
<span class="loop-status-spinner" aria-hidden="true"></span>
|
|
343
|
+
<span class="loop-status-icon" id="loop-status-icon" aria-hidden="true"></span>
|
|
344
|
+
<span class="loop-status-text" id="loop-status-text"></span>
|
|
345
|
+
<span class="loop-status-retry" id="loop-status-retry" hidden></span>
|
|
346
|
+
<button id="loop-status-check" class="loop-status-action" hidden type="button">✓ 检查</button>
|
|
362
347
|
</div>
|
|
363
348
|
|
|
364
349
|
<div class="input-area">
|
|
365
350
|
<div class="input-wrapper">
|
|
366
351
|
<input type="text" id="input" placeholder="输入消息..." autocomplete="off">
|
|
367
|
-
<button id="send" class="send-btn">
|
|
368
|
-
|
|
352
|
+
<button id="send" class="send-btn" data-state="idle" title="发送 (Enter)">
|
|
353
|
+
<!-- 2026-06-15: 状态机 — 流式期间切到 abort 模式 (▢ 图标 + 红色边框) -->
|
|
354
|
+
<svg class="send-icon" data-mode="send" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2">
|
|
369
355
|
<line x1="22" y1="2" x2="11" y2="13"></line>
|
|
370
356
|
<polygon points="22 2 15 22 11 13 2 9 22 2"></polygon>
|
|
371
357
|
</svg>
|
|
358
|
+
<svg class="send-icon" data-mode="abort" width="20" height="20" viewBox="0 0 24 24" fill="currentColor" stroke="currentColor" stroke-width="2" style="display:none;">
|
|
359
|
+
<rect x="6" y="6" width="12" height="12" rx="1.5"></rect>
|
|
360
|
+
</svg>
|
|
372
361
|
</button>
|
|
373
362
|
</div>
|
|
374
363
|
</div>
|
|
@@ -377,6 +366,8 @@
|
|
|
377
366
|
|
|
378
367
|
<script type="module" src="/components/wallet-viem.mjs"></script>
|
|
379
368
|
<script type="module" src="/components/p2p/index.js"></script>
|
|
369
|
+
<script type="module" src="/ui/step-timeline.js"></script>
|
|
370
|
+
<script type="module" src="/ui/message-renderer.js"></script>
|
|
380
371
|
<script src="/client.js"></script>
|
|
381
372
|
</body>
|
|
382
373
|
</html>
|