@bolloon/bolloon-agent 0.6.5 → 0.6.7
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/agents/chain/chain-settlement.js +0 -1
- package/dist/agents/chat-segmenter.js +4 -16
- package/dist/agents/contacts/human-directory.js +155 -0
- package/dist/agents/contacts/tools.js +79 -0
- package/dist/agents/experience-review.js +0 -3
- package/dist/agents/goal-flywheel/goal-change.js +3 -4
- package/dist/agents/goal-resume.js +0 -4
- package/dist/agents/ha-daemon.js +85 -0
- package/dist/agents/ha-supervisor.js +146 -0
- package/dist/agents/intent-classifier.js +1 -1
- package/dist/agents/iteration-budget.js +12 -0
- package/dist/agents/knowledge-organizer.js +0 -2
- package/dist/agents/lesson-to-skill.js +0 -1
- package/dist/agents/loop-review.js +2 -2
- package/dist/agents/memory-store.js +384 -0
- package/dist/agents/opportunity-match.js +15 -3
- package/dist/agents/opportunity-web-search.js +39 -0
- package/dist/agents/p2p-chat-tools.js +1 -2
- package/dist/agents/parse-tool-call.js +9 -22
- package/dist/agents/pi-harness.js +1 -2
- package/dist/agents/pi-sdk-session-manager.js +8 -0
- package/dist/agents/pi-sdk-tools.js +180 -5
- package/dist/agents/pi-sdk.js +210 -503
- package/dist/agents/process-runner.js +28 -9
- package/dist/agents/react-loop.js +9 -17
- package/dist/agents/runner-resolver.js +4 -3
- package/dist/agents/skill-loader.js +22 -15
- package/dist/agents/skills-manager.js +1 -25
- package/dist/agents/workflow-pivot-loop.js +152 -61
- package/dist/bootstrap/context-collector.js +67 -7
- package/dist/bootstrap/context-hierarchy.js +13 -1
- package/dist/bootstrap/persona-loader.js +26 -0
- package/dist/cli/ink-app.js +44 -17
- package/dist/cli/intent-command.js +22 -12
- package/dist/cli/loading-tui.js +8 -2
- package/dist/cli/log-gate.js +40 -8
- package/dist/cli/mention-data.js +1 -0
- package/dist/cli/reply-hygiene.js +22 -0
- package/dist/cli/trace-line.js +61 -2
- package/dist/electron-build/agents/agent-gateway.js.map +1 -1
- package/dist/electron-build/agents/chain/chain-indexer.js.map +1 -1
- package/dist/electron-build/agents/chain/chain-settlement.js +0 -1
- package/dist/electron-build/agents/chain/chain-settlement.js.map +1 -1
- package/dist/electron-build/agents/contacts/chain.js.map +1 -1
- package/dist/electron-build/agents/contacts/human-directory.js +204 -0
- package/dist/electron-build/agents/contacts/human-directory.js.map +1 -0
- package/dist/electron-build/agents/contacts/policy.js.map +1 -1
- package/dist/electron-build/agents/contacts/tools.js +112 -0
- package/dist/electron-build/agents/contacts/tools.js.map +1 -1
- package/dist/electron-build/agents/experience-review.js +0 -3
- package/dist/electron-build/agents/experience-review.js.map +1 -1
- package/dist/electron-build/agents/external-events.js.map +1 -1
- package/dist/electron-build/agents/goal-flywheel/goal-change.js +3 -4
- package/dist/electron-build/agents/goal-flywheel/goal-change.js.map +1 -1
- package/dist/electron-build/agents/goal-flywheel-wiring.js.map +1 -1
- package/dist/electron-build/agents/goal-resume.js +0 -4
- package/dist/electron-build/agents/goal-resume.js.map +1 -1
- package/dist/electron-build/agents/intent-classifier.js +1 -1
- package/dist/electron-build/agents/lesson-to-skill.js +0 -1
- package/dist/electron-build/agents/lesson-to-skill.js.map +1 -1
- package/dist/electron-build/agents/loop-review.js +2 -2
- package/dist/electron-build/agents/loop-review.js.map +1 -1
- package/dist/electron-build/agents/memory-recall.js.map +1 -1
- package/dist/electron-build/agents/memory-store.js +430 -0
- package/dist/electron-build/agents/memory-store.js.map +1 -0
- package/dist/electron-build/agents/parse-tool-call.js +9 -22
- package/dist/electron-build/agents/parse-tool-call.js.map +1 -1
- package/dist/electron-build/agents/pi-harness.js +1 -2
- package/dist/electron-build/agents/pi-harness.js.map +1 -1
- package/dist/electron-build/agents/pi-sdk-session-manager.js +8 -0
- package/dist/electron-build/agents/pi-sdk-session-manager.js.map +1 -1
- package/dist/electron-build/agents/pi-sdk-tools.js +180 -5
- package/dist/electron-build/agents/pi-sdk-tools.js.map +1 -1
- package/dist/electron-build/agents/pi-sdk.js +208 -501
- package/dist/electron-build/agents/pi-sdk.js.map +1 -1
- package/dist/electron-build/agents/pre-tool-validator.js.map +1 -1
- package/dist/electron-build/agents/process-runner.js +28 -9
- package/dist/electron-build/agents/process-runner.js.map +1 -1
- package/dist/electron-build/agents/runner-resolver.js +4 -3
- package/dist/electron-build/agents/runner-resolver.js.map +1 -1
- package/dist/electron-build/agents/skill-loader.js +22 -16
- package/dist/electron-build/agents/skill-loader.js.map +1 -1
- package/dist/electron-build/agents/skill-supervisor-link.js.map +1 -1
- package/dist/electron-build/agents/skills-manager.js +0 -24
- package/dist/electron-build/agents/skills-manager.js.map +1 -1
- package/dist/electron-build/agents/task/task-runner.js.map +1 -1
- package/dist/electron-build/agents/workflow-engine.js.map +1 -1
- package/dist/electron-build/agents/workflow-pivot-loop.js +155 -62
- package/dist/electron-build/agents/workflow-pivot-loop.js.map +1 -1
- package/dist/electron-build/agents/x402/goal-run-bridge.js.map +1 -1
- package/dist/electron-build/bollharness-integration/gate-state-machine.js.map +1 -1
- package/dist/electron-build/bootstrap/context-collector.js +68 -7
- package/dist/electron-build/bootstrap/context-collector.js.map +1 -1
- package/dist/electron-build/bootstrap/context-hierarchy.js +13 -1
- package/dist/electron-build/bootstrap/context-hierarchy.js.map +1 -1
- package/dist/electron-build/bootstrap/persona-loader.js +27 -0
- package/dist/electron-build/bootstrap/persona-loader.js.map +1 -1
- package/dist/electron-build/electron-preload.js.map +1 -1
- package/dist/electron-build/external-engines/delegate.js.map +1 -1
- package/dist/electron-build/kernel/channel-actor.js +31 -2
- package/dist/electron-build/kernel/channel-actor.js.map +1 -1
- package/dist/electron-build/kernel/model-runtime.js +8 -1
- package/dist/electron-build/kernel/model-runtime.js.map +1 -1
- package/dist/electron-build/llm/config-store.js +20 -0
- package/dist/electron-build/llm/config-store.js.map +1 -1
- package/dist/electron-build/llm/embedding-adapter.js +75 -0
- package/dist/electron-build/llm/embedding-adapter.js.map +1 -0
- package/dist/electron-build/llm/pi-ai.js +112 -38
- package/dist/electron-build/llm/pi-ai.js.map +1 -1
- package/dist/electron-build/llm/system-prompt/registry.js +8 -6
- package/dist/electron-build/llm/system-prompt/registry.js.map +1 -1
- package/dist/electron-build/network/agent-network.js.map +1 -1
- package/dist/electron-build/orbitdb/memory-sync.js +76 -0
- package/dist/electron-build/orbitdb/memory-sync.js.map +1 -0
- package/dist/electron-build/pi-ecosystem-judgment/adaptive-scan.js.map +1 -1
- package/dist/electron-build/security/tool-gate.js +2 -0
- package/dist/electron-build/security/tool-gate.js.map +1 -1
- package/dist/electron-build/setup/setup-store.js +34 -6
- package/dist/electron-build/setup/setup-store.js.map +1 -1
- package/dist/electron-build/social/heartbeat.js +18 -5
- package/dist/electron-build/social/heartbeat.js.map +1 -1
- package/dist/electron-build/utils/update-manager.js.map +1 -1
- package/dist/index.js +250 -12
- package/dist/ios/bolloon-web.json +3 -3
- package/dist/ios/client.js +74 -35
- package/dist/ios/icons/icon-1400x1400.png +0 -0
- package/dist/ios/icons/icon-1400x1400.webp +0 -0
- package/dist/ios/index.html +122 -108
- package/dist/ios/mobile-agent.js +572 -45
- package/dist/ios/mobile-contacts.js +0 -4
- package/dist/ios/mobile-core.js +8079 -4590
- package/dist/ios/mobile-harness.js +1004 -0
- package/dist/ios/mobile-memory.js +317 -0
- package/dist/ios/mobile-orbitdb.js +194 -0
- package/dist/ios/mobile-persona.js +80 -0
- package/dist/ios/mobile-privacy.js +2 -3
- package/dist/ios/mobile.css +286 -21
- package/dist/ios/mobile.html +122 -108
- package/dist/ios/mobile.js +434 -152
- package/dist/ios/routes-contacts.js +94 -1
- package/dist/ios/routes-world.js +13 -2
- package/dist/ios/server.js +54 -41
- package/dist/ios/style.css +13 -5
- package/dist/ios/sw.js +1 -1
- package/dist/ios/ui/message-renderer.js +4 -18
- package/dist/ios/ui/step-timeline.js +14 -1
- package/dist/kernel/channel-actor.js +30 -2
- package/dist/kernel/gate-scan.js +2 -2
- package/dist/kernel/ha/ha-arbiter.js +177 -0
- package/dist/kernel/ha/ha-guard.js +151 -0
- package/dist/kernel/index.js +36 -0
- package/dist/kernel/model-runtime.js +8 -1
- package/dist/kernel/plan.js +5 -5
- package/dist/kernel/roster.js +3 -3
- package/dist/llm/config-store.js +20 -0
- package/dist/llm/embedding-adapter.js +69 -0
- package/dist/llm/pi-ai.js +110 -37
- package/dist/llm/system-prompt/registry.js +8 -6
- package/dist/orbitdb/memory-sync.js +70 -0
- package/dist/pi-ecosystem-judgment/adaptive-scan.js +1 -1
- package/dist/security/tool-gate.js +2 -0
- package/dist/setup/setup-store.js +34 -6
- package/dist/social/heartbeat.js +18 -5
- package/dist/web/bolloon-web.json +3 -3
- package/dist/web/client.js +74 -35
- package/dist/web/icons/icon-1400x1400.png +0 -0
- package/dist/web/icons/icon-1400x1400.webp +0 -0
- package/dist/web/index.html +37 -25
- package/dist/web/mobile-agent.js +572 -45
- package/dist/web/mobile-contacts.js +0 -4
- package/dist/web/mobile-core.js +8079 -4590
- package/dist/web/mobile-harness.js +1004 -0
- package/dist/web/mobile-memory.js +317 -0
- package/dist/web/mobile-orbitdb.js +194 -0
- package/dist/web/mobile-persona.js +80 -0
- package/dist/web/mobile-privacy.js +2 -3
- package/dist/web/mobile.css +286 -21
- package/dist/web/mobile.html +122 -108
- package/dist/web/mobile.js +434 -152
- package/dist/web/routes-contacts.js +94 -1
- package/dist/web/routes-world.js +13 -2
- package/dist/web/server.js +54 -41
- package/dist/web/style.css +13 -5
- package/dist/web/sw.js +1 -1
- package/dist/web/ui/message-renderer.js +4 -18
- package/dist/web/ui/step-timeline.js +14 -1
- package/package.json +3 -2
- package/scripts/build-web.ts +16 -1
package/dist/web/client.js
CHANGED
|
@@ -33,6 +33,15 @@
|
|
|
33
33
|
var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
|
|
34
34
|
|
|
35
35
|
// src/web/ui/step-timeline.ts
|
|
36
|
+
function formatDuration(ms) {
|
|
37
|
+
if (!Number.isFinite(ms) || ms < 0) return "(\u8017\u65F6\u672A\u77E5)";
|
|
38
|
+
if (ms < 1e3) return `${ms}ms`;
|
|
39
|
+
const s = ms / 1e3;
|
|
40
|
+
if (s < 60) return `${s.toFixed(1)}s`;
|
|
41
|
+
const m = Math.floor(s / 60);
|
|
42
|
+
const rem = Math.round(s % 60);
|
|
43
|
+
return `${m}m${rem}s`;
|
|
44
|
+
}
|
|
36
45
|
function readExpanded(channelId) {
|
|
37
46
|
if (!channelId) return false;
|
|
38
47
|
try {
|
|
@@ -152,7 +161,10 @@
|
|
|
152
161
|
}
|
|
153
162
|
node.setAttribute("data-status", step.status);
|
|
154
163
|
const label = node.querySelector(".step-timeline-label");
|
|
155
|
-
if (label)
|
|
164
|
+
if (label) {
|
|
165
|
+
const dur = step.durationMs !== void 0 && step.status !== "active" ? ` \xB7 ${formatDuration(step.durationMs)}` : "";
|
|
166
|
+
label.textContent = step.name + dur;
|
|
167
|
+
}
|
|
156
168
|
const argsEl = node.querySelector(".step-timeline-args");
|
|
157
169
|
if (argsEl) {
|
|
158
170
|
const argStr = step.args && Object.keys(step.args).length > 0 ? JSON.stringify(step.args).slice(0, 60) : "";
|
|
@@ -296,6 +308,7 @@
|
|
|
296
308
|
steps[targetIdx].status = data.success === false ? "error" : "done";
|
|
297
309
|
if (data.output) steps[targetIdx].output = data.output;
|
|
298
310
|
if (data.error) steps[targetIdx].error = data.error;
|
|
311
|
+
if (data.durationMs !== void 0) steps[targetIdx].durationMs = data.durationMs;
|
|
299
312
|
} else {
|
|
300
313
|
steps[targetIdx].status = "error";
|
|
301
314
|
if (data.error) steps[targetIdx].error = data.error;
|
|
@@ -595,21 +608,10 @@
|
|
|
595
608
|
if (remaining.trim()) {
|
|
596
609
|
remaining = filterFillerText(remaining);
|
|
597
610
|
}
|
|
598
|
-
const
|
|
599
|
-
let beforeFinalText = remaining;
|
|
600
|
-
if (finalIdx >= 0) {
|
|
601
|
-
beforeFinalText = remaining.substring(0, finalIdx);
|
|
602
|
-
}
|
|
603
|
-
const textContent = beforeFinalText.trim();
|
|
611
|
+
const textContent = remaining.trim();
|
|
604
612
|
if (textContent) {
|
|
605
613
|
segments.push({ type: "text", content: textContent });
|
|
606
614
|
}
|
|
607
|
-
if (finalIdx >= 0) {
|
|
608
|
-
const afterFinal = remaining.substring(finalIdx + "<final gen>".length).trim();
|
|
609
|
-
if (afterFinal) {
|
|
610
|
-
segments.push({ type: "final", content: afterFinal });
|
|
611
|
-
}
|
|
612
|
-
}
|
|
613
615
|
return segments;
|
|
614
616
|
}
|
|
615
617
|
function extractAndPush(type, text, out, re) {
|
|
@@ -879,11 +881,7 @@
|
|
|
879
881
|
div.className = `message message-${type}`;
|
|
880
882
|
let cleanContent = content;
|
|
881
883
|
if (type === "ai") {
|
|
882
|
-
cleanContent = cleanContent.replace(
|
|
883
|
-
const finalGenIdx = cleanContent.indexOf("<final gen>");
|
|
884
|
-
if (finalGenIdx >= 0) {
|
|
885
|
-
cleanContent = cleanContent.substring(0, finalGenIdx).trim();
|
|
886
|
-
}
|
|
884
|
+
cleanContent = cleanContent.replace(/ thinking[\s\S]*?<\/think>/g, "");
|
|
887
885
|
}
|
|
888
886
|
const knownToolNames2 = ctx && ctx.knownToolNames || /* @__PURE__ */ new Set();
|
|
889
887
|
const segments = segmentChatReply(cleanContent, { knownToolNames: knownToolNames2 });
|
|
@@ -1207,7 +1205,8 @@
|
|
|
1207
1205
|
args: data.args,
|
|
1208
1206
|
success: data.success,
|
|
1209
1207
|
output: data.output,
|
|
1210
|
-
error: data.error
|
|
1208
|
+
error: data.error,
|
|
1209
|
+
durationMs: data.durationMs
|
|
1211
1210
|
});
|
|
1212
1211
|
}
|
|
1213
1212
|
function flushStepEventBuffer(channelId, ctx) {
|
|
@@ -1547,6 +1546,8 @@
|
|
|
1547
1546
|
var renderLoopStatusBar2 = (...args) => _getLS().renderLoopStatusBar?.(...args);
|
|
1548
1547
|
var hideLoopStatusBar2 = (...args) => _getLS().hideLoopStatusBar?.(...args);
|
|
1549
1548
|
var sidebarToggle = document.getElementById("sidebar-toggle");
|
|
1549
|
+
var sidebarCollapsedBar = document.getElementById("sidebar-collapsed-bar");
|
|
1550
|
+
var sidebarExpandBtn = document.getElementById("sidebar-expand-btn");
|
|
1550
1551
|
var themeToggle = document.getElementById("theme-toggle");
|
|
1551
1552
|
var channelList = document.getElementById("channel-list");
|
|
1552
1553
|
var newChannelBtn = document.getElementById("new-channel-btn");
|
|
@@ -1720,13 +1721,16 @@
|
|
|
1720
1721
|
isSidebarCollapsed = !isSidebarCollapsed;
|
|
1721
1722
|
if (isSidebarCollapsed) {
|
|
1722
1723
|
sidebar.classList.add("collapsed");
|
|
1724
|
+
if (sidebarCollapsedBar) sidebarCollapsedBar.classList.remove("hidden");
|
|
1723
1725
|
} else {
|
|
1724
1726
|
sidebar.classList.remove("collapsed");
|
|
1727
|
+
if (sidebarCollapsedBar) sidebarCollapsedBar.classList.add("hidden");
|
|
1725
1728
|
}
|
|
1726
1729
|
}
|
|
1727
1730
|
function expandSidebar() {
|
|
1728
1731
|
isSidebarCollapsed = false;
|
|
1729
1732
|
sidebar.classList.remove("collapsed");
|
|
1733
|
+
if (sidebarCollapsedBar) sidebarCollapsedBar.classList.add("hidden");
|
|
1730
1734
|
}
|
|
1731
1735
|
async function loadChannels() {
|
|
1732
1736
|
try {
|
|
@@ -1736,7 +1740,6 @@
|
|
|
1736
1740
|
const text = await res.text().catch(() => "");
|
|
1737
1741
|
if (!text.trim().startsWith("[") && !text.trim().startsWith("{")) {
|
|
1738
1742
|
console.warn("[\u52A0\u8F7D\u9891\u9053] \u68C0\u6D4B\u5230 IPFS \u9759\u6001\u6A21\u5F0F (\u65E0\u540E\u7AEF server), \u529F\u80FD\u53D7\u9650");
|
|
1739
|
-
showStaticModeNotice();
|
|
1740
1743
|
return;
|
|
1741
1744
|
}
|
|
1742
1745
|
}
|
|
@@ -1762,17 +1765,6 @@
|
|
|
1762
1765
|
console.error("[\u52A0\u8F7D\u9891\u9053] \u5931\u8D25:", err);
|
|
1763
1766
|
}
|
|
1764
1767
|
}
|
|
1765
|
-
function showStaticModeNotice() {
|
|
1766
|
-
if (document.getElementById("ipfs-static-notice")) return;
|
|
1767
|
-
const notice = document.createElement("div");
|
|
1768
|
-
notice.id = "ipfs-static-notice";
|
|
1769
|
-
notice.style.cssText = "position:fixed;bottom:60px;left:50%;transform:translateX(-50%);z-index:9999;background:#1a1a18;border:1px solid #c4d640;color:#d8d8c8;padding:10px 16px;border-radius:8px;font-size:12px;box-shadow:0 4px 20px rgba(0,0,0,.5);max-width:560px;text-align:center;";
|
|
1770
|
-
notice.innerHTML = `\u{1F4E1} <b style="color:#c4d640">IPFS \u9759\u6001\u6A21\u5F0F</b> \u2014 \u6B64\u9875\u9762\u901A\u8FC7 IPNS \u4ECE\u53BB\u4E2D\u5FC3\u5316\u7F51\u7EDC\u52A0\u8F7D.<br>\u5B8C\u6574\u529F\u80FD (\u5BF9\u8BDD/\u5DE5\u5177/\u5224\u65AD\u529B) \u9700\u8FDE\u63A5\u672C\u5730 Bolloon server: <code style="color:#c4d640">bolloon --web</code>`;
|
|
1771
|
-
document.body.appendChild(notice);
|
|
1772
|
-
setTimeout(() => {
|
|
1773
|
-
notice.remove();
|
|
1774
|
-
}, 15e3);
|
|
1775
|
-
}
|
|
1776
1768
|
var gwGroups = [];
|
|
1777
1769
|
var gwNetworks = [];
|
|
1778
1770
|
var gwActiveChat = null;
|
|
@@ -3232,6 +3224,13 @@ ${data.error || "channel not found"}`, "error");
|
|
|
3232
3224
|
async function sendMessage() {
|
|
3233
3225
|
const text = input.value.trim();
|
|
3234
3226
|
if (!text) return;
|
|
3227
|
+
if (text === "/world" || text === "/chat") {
|
|
3228
|
+
const panel = text === "/world" ? "world" : "chat";
|
|
3229
|
+
if (typeof switchPanel === "function") switchPanel(panel);
|
|
3230
|
+
input.value = "";
|
|
3231
|
+
if (typeof showSimpleToast === "function") showSimpleToast(panel === "world" ? "\u{1F30D} \u5DF2\u5207\u6362\u5230\u4E16\u754C\u6A21\u5F0F" : "\u{1F4AC} \u5DF2\u5207\u6362\u5230\u804A\u5929\u6A21\u5F0F");
|
|
3232
|
+
return;
|
|
3233
|
+
}
|
|
3235
3234
|
setSendMode("abort");
|
|
3236
3235
|
const container = messagesContainers.get(currentChannelId) || messagesEl;
|
|
3237
3236
|
addMessage2(text, "user", true, container);
|
|
@@ -3528,6 +3527,8 @@ ${data.error || "channel not found"}`, "error");
|
|
|
3528
3527
|
{ cmd: "goal", desc: "\u6682\u505C\u76EE\u6807 (park_goal)", args: "\u76EE\u6807ID; \u539F\u56E0" },
|
|
3529
3528
|
{ cmd: "skill", desc: "\u6C89\u6DC0\u6280\u80FD (create_skill)", args: "\u6280\u80FD\u540D; \u63CF\u8FF0; \u6B65\u9AA4" },
|
|
3530
3529
|
{ cmd: "add-friend", desc: "\u6DFB\u52A0 P2P \u597D\u53CB", args: "\u516C\u94A5; \u5907\u6CE8" },
|
|
3530
|
+
{ cmd: "world", desc: "\u5207\u6362\u5230\u4E16\u754C\u6A21\u5F0F (\u673A\u4F1A\u6D41)", args: "" },
|
|
3531
|
+
{ cmd: "chat", desc: "\u5207\u6362\u5230\u804A\u5929\u6A21\u5F0F (\u5BF9\u8BDD)", args: "" },
|
|
3531
3532
|
{ cmd: "help", desc: "\u663E\u793A\u53EF\u7528\u547D\u4EE4", args: "" }
|
|
3532
3533
|
];
|
|
3533
3534
|
var slashDropdownEl = null;
|
|
@@ -3550,6 +3551,14 @@ ${data.error || "channel not found"}`, "error");
|
|
|
3550
3551
|
slashBlockEnd = -1;
|
|
3551
3552
|
}
|
|
3552
3553
|
function applySlashCommand(cmdObj) {
|
|
3554
|
+
if (cmdObj.cmd === "world" || cmdObj.cmd === "chat") {
|
|
3555
|
+
const panel = cmdObj.cmd === "world" ? "world" : "chat";
|
|
3556
|
+
if (typeof switchPanel === "function") switchPanel(panel);
|
|
3557
|
+
input.value = "";
|
|
3558
|
+
closeSlashDropdown();
|
|
3559
|
+
if (typeof showSimpleToast === "function") showSimpleToast(panel === "world" ? "\u{1F30D} \u5DF2\u5207\u6362\u5230\u4E16\u754C\u6A21\u5F0F" : "\u{1F4AC} \u5DF2\u5207\u6362\u5230\u804A\u5929\u6A21\u5F0F");
|
|
3560
|
+
return;
|
|
3561
|
+
}
|
|
3553
3562
|
const anchor = slashAnchor;
|
|
3554
3563
|
const blockEnd = slashBlockEnd >= 0 ? slashBlockEnd : anchor + 1 + (getCurrentSlashQuery()?.query || "").length;
|
|
3555
3564
|
if (anchor < 0 || anchor > input.value.length || input.value[anchor] !== "/") {
|
|
@@ -4084,6 +4093,9 @@ ${data.error || "channel not found"}`, "error");
|
|
|
4084
4093
|
if (sidebarToggle) {
|
|
4085
4094
|
sidebarToggle.addEventListener("click", toggleSidebar);
|
|
4086
4095
|
}
|
|
4096
|
+
if (sidebarExpandBtn) {
|
|
4097
|
+
sidebarExpandBtn.addEventListener("click", expandSidebar);
|
|
4098
|
+
}
|
|
4087
4099
|
if (newChannelBtn) {
|
|
4088
4100
|
newChannelBtn.addEventListener("click", () => {
|
|
4089
4101
|
createChannel("\u667A\u80FD\u4F53");
|
|
@@ -5002,7 +5014,9 @@ ${data.error || "channel not found"}`, "error");
|
|
|
5002
5014
|
}
|
|
5003
5015
|
var worldView = document.getElementById("world-view");
|
|
5004
5016
|
var worldBtn = document.getElementById("world-btn");
|
|
5005
|
-
var
|
|
5017
|
+
var worldIntentCol = document.getElementById("world-intent-col");
|
|
5018
|
+
var worldColToggle = document.getElementById("world-col-toggle");
|
|
5019
|
+
var worldColClose = document.getElementById("world-col-close");
|
|
5006
5020
|
var worldIntentsList = document.getElementById("world-intents-list");
|
|
5007
5021
|
var worldOpportunities = document.getElementById("world-opportunities");
|
|
5008
5022
|
var worldStats = document.getElementById("world-stats");
|
|
@@ -5190,16 +5204,36 @@ ${data.error || "channel not found"}`, "error");
|
|
|
5190
5204
|
if (tabWorld) tabWorld.addEventListener("click", () => switchPanel("world"));
|
|
5191
5205
|
if (tabChat) tabChat.addEventListener("click", () => switchPanel("chat"));
|
|
5192
5206
|
if (worldBtn) worldBtn.addEventListener("click", () => switchPanel("world"));
|
|
5193
|
-
|
|
5194
|
-
|
|
5195
|
-
|
|
5207
|
+
function toggleWorldIntentCol(show) {
|
|
5208
|
+
if (!worldIntentCol) return;
|
|
5209
|
+
worldIntentCol.style.display = show ? "" : "none";
|
|
5210
|
+
if (worldColToggle) worldColToggle.textContent = show ? "\u25BE \u6211\u7684\u610F\u56FE" : "\u25B8 \u6211\u7684\u610F\u56FE";
|
|
5211
|
+
}
|
|
5212
|
+
if (worldColToggle) worldColToggle.addEventListener("click", () => {
|
|
5213
|
+
toggleWorldIntentCol(worldIntentCol ? worldIntentCol.style.display === "none" : false);
|
|
5196
5214
|
});
|
|
5215
|
+
if (worldColClose) worldColClose.addEventListener("click", () => toggleWorldIntentCol(false));
|
|
5197
5216
|
var worldInput = document.getElementById("world-input");
|
|
5198
5217
|
var worldInputSend = document.getElementById("world-input-send");
|
|
5199
5218
|
async function tellWorld() {
|
|
5200
5219
|
const text = (worldInput && worldInput.value || "").trim();
|
|
5201
5220
|
if (!text) return;
|
|
5221
|
+
if (text === "/chat" || text === "/world") {
|
|
5222
|
+
const panel = text === "/chat" ? "chat" : "world";
|
|
5223
|
+
if (typeof switchPanel === "function") switchPanel(panel);
|
|
5224
|
+
worldInput.value = "";
|
|
5225
|
+
if (typeof showSimpleToast === "function") showSimpleToast(panel === "world" ? "\u{1F30D} \u5DF2\u5207\u6362\u5230\u4E16\u754C\u6A21\u5F0F" : "\u{1F4AC} \u5DF2\u5207\u6362\u5230\u804A\u5929\u6A21\u5F0F");
|
|
5226
|
+
return;
|
|
5227
|
+
}
|
|
5202
5228
|
worldInput.value = "";
|
|
5229
|
+
if (worldOpportunities) {
|
|
5230
|
+
const echo = document.createElement("div");
|
|
5231
|
+
echo.className = "world-opp-card";
|
|
5232
|
+
echo.style.cssText = "border:1px dashed var(--accent,#c4d640);border-radius:12px;padding:10px 14px;margin-bottom:10px;background:var(--bg-card,#222220);font-size:13px;color:var(--text,#f0f0ea);";
|
|
5233
|
+
echo.innerHTML = `<div style="font-weight:700;margin-bottom:4px;">\u270D \u4F60\u544A\u8BC9\u4E16\u754C</div><div>${String(text).replace(/</g, "<")}</div><div style="color:#909088;font-size:11px;margin-top:6px;">\u5DF2\u58F0\u660E\u610F\u56FE \xB7 \u6B63\u5728\u4E3A\u4F60\u5339\u914D\u673A\u4F1A\u2026</div>`;
|
|
5234
|
+
worldOpportunities.prepend(echo);
|
|
5235
|
+
}
|
|
5236
|
+
if (typeof showSimpleToast === "function") showSimpleToast("\u{1F30D} \u5DF2\u544A\u8BC9\u4E16\u754C\uFF1A" + text, "success");
|
|
5203
5237
|
try {
|
|
5204
5238
|
const res = await fetch("/api/intents", { method: "POST", headers: { "Content-Type": "application/json" }, body: JSON.stringify({ text, priority: 3 }) });
|
|
5205
5239
|
if (!res.ok) {
|
|
@@ -5207,6 +5241,11 @@ ${data.error || "channel not found"}`, "error");
|
|
|
5207
5241
|
return;
|
|
5208
5242
|
}
|
|
5209
5243
|
await fetchWorldIntents();
|
|
5244
|
+
try {
|
|
5245
|
+
await fetch("/api/world/search", { method: "POST", headers: { "Content-Type": "application/json" }, body: JSON.stringify({ topic: text }) });
|
|
5246
|
+
} catch (e) {
|
|
5247
|
+
console.info("[world] \u4E3B\u52A8\u641C\u7D22\u5931\u8D25", e);
|
|
5248
|
+
}
|
|
5210
5249
|
await refreshWorldOpportunities();
|
|
5211
5250
|
} catch (e) {
|
|
5212
5251
|
console.info("[world] \u58F0\u660E\u5931\u8D25", e);
|
|
Binary file
|
|
Binary file
|
package/dist/web/index.html
CHANGED
|
@@ -125,10 +125,19 @@
|
|
|
125
125
|
<span class="status-text">已连接</span>
|
|
126
126
|
</div>
|
|
127
127
|
</div>
|
|
128
|
-
|
|
128
|
+
</aside>
|
|
129
|
+
|
|
130
|
+
<!-- 2026-10-06 (用户): 左侧导航收起的恢复条 — 收起后滑出的方式不留下展开按钮就打不开, 补窄条 + 展开按钮 -->
|
|
131
|
+
<div class="sidebar-collapsed hidden" id="sidebar-collapsed-bar">
|
|
132
|
+
<button class="expand-btn" id="sidebar-expand-btn" title="展开侧边栏">
|
|
133
|
+
<svg width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2">
|
|
134
|
+
<polyline points="9 18 15 12 9 6"></polyline>
|
|
135
|
+
</svg>
|
|
136
|
+
</button>
|
|
137
|
+
</div>
|
|
129
138
|
|
|
130
|
-
|
|
131
|
-
|
|
139
|
+
<main class="main">
|
|
140
|
+
<header class="header">
|
|
132
141
|
<div class="header-left">
|
|
133
142
|
<span class="channel-indicator" id="channel-indicator"></span>
|
|
134
143
|
<h1 id="channel-name">Bolloon Agent</h1>
|
|
@@ -421,28 +430,31 @@
|
|
|
421
430
|
<!-- World View (2026-10-05, leo Intent Network) — 主页内嵌面板 (不再全屏跳转):
|
|
422
431
|
顶部 tab 切换 世界/聊天, 默认世界; 无嵌套无跳转 -->
|
|
423
432
|
<div id="world-view" style="position:relative;background:var(--bg,#1a1a18);display:flex;flex-direction:column;flex:1;min-height:0;">
|
|
424
|
-
<!-- 面板头 (
|
|
425
|
-
|
|
426
|
-
|
|
427
|
-
|
|
428
|
-
|
|
429
|
-
|
|
430
|
-
|
|
431
|
-
|
|
432
|
-
|
|
433
|
-
|
|
434
|
-
|
|
435
|
-
|
|
436
|
-
|
|
437
|
-
|
|
438
|
-
|
|
439
|
-
|
|
440
|
-
|
|
441
|
-
|
|
442
|
-
|
|
443
|
-
|
|
444
|
-
|
|
445
|
-
|
|
433
|
+
<!-- 面板头 (刷新按钮已按用户要求去掉; 内容自动流入) -->
|
|
434
|
+
<div style="display:flex;align-items:center;justify-content:space-between;padding:8px 18px;border-bottom:1px solid var(--border,#3a3a36);flex-shrink:0;">
|
|
435
|
+
<div style="font-weight:700;font-size:14px;">🌍 World <span style="color:#606058;font-weight:400;font-size:11px;">世界在给你送东西 · 自动流入</span></div>
|
|
436
|
+
<button id="world-col-toggle" class="btn-secondary btn-sm" style="font-size:11px;padding:3px 12px;" title="展开/折叠我的意图栏">▸ 我的意图</button>
|
|
437
|
+
</div>
|
|
438
|
+
<!-- Twitter 式两栏: 左 = 机会时间线, 右 = 我的意图 (可折叠, 2026-10-06 用户要求右置 + 折叠) -->
|
|
439
|
+
<div style="display:flex;flex:1;overflow:hidden;">
|
|
440
|
+
<!-- 左栏: 机会时间线 (Twitter feed 自动流入, 全宽) -->
|
|
441
|
+
<main style="flex:1;overflow-y:auto;padding:16px 24px;max-width:760px;margin:0 auto;width:100%;">
|
|
442
|
+
<div style="font-size:12px;color:#909088;margin-bottom:12px;">✦ 世界在给你送东西 (自动匹配, 持续流入)</div>
|
|
443
|
+
<div id="world-opportunities" style="min-height:120px;">
|
|
444
|
+
<div class="form-hint">世界正在观察…</div>
|
|
445
|
+
</div>
|
|
446
|
+
</main>
|
|
447
|
+
<!-- 右栏: 我的意图 (nav 风格, 可折叠隐藏) -->
|
|
448
|
+
<aside style="width:240px;border-left:1px solid var(--border,#3a3a36);overflow-y:auto;padding:12px;flex-shrink:0;transition:width .2s;" id="world-intent-col">
|
|
449
|
+
<div style="display:flex;align-items:center;justify-content:space-between;margin-bottom:8px;">
|
|
450
|
+
<div style="font-size:12px;color:#909088;font-weight:600;">我的意图 (Intent)</div>
|
|
451
|
+
<button id="world-col-close" class="btn-secondary btn-sm" style="font-size:10px;padding:1px 7px;" title="折叠意图栏">✕</button>
|
|
452
|
+
</div>
|
|
453
|
+
<div id="world-intents-list" style="margin-bottom:12px;"><div class="form-hint">(还没有意图)</div></div>
|
|
454
|
+
<div style="font-size:12px;color:#909088;font-weight:600;margin-bottom:8px;">世界变化</div>
|
|
455
|
+
<div id="world-stats" style="font-size:12px;color:#606058;"></div>
|
|
456
|
+
</aside>
|
|
457
|
+
</div>
|
|
446
458
|
<!-- 2026-10-05 (leo): 世界底部输入框 — 想做什么直接说, 自动触发匹配 (不是聊天输入框) -->
|
|
447
459
|
<div class="world-input-bar" style="display:flex;gap:8px;align-items:center;padding:10px 18px;border-top:1px solid var(--border,#3a3a36);flex-shrink:0;background:var(--bg-sidebar,#222220);">
|
|
448
460
|
<input type="text" id="world-input" placeholder="告诉世界你在做什么 / 需要什么… (Enter 自动匹配)" autocomplete="off"
|