@bolloon/bolloon-agent 0.4.21 → 0.4.23
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/gateway-join.js +271 -0
- package/dist/agents/pi-sdk-tools.js +75 -2
- package/dist/agents/pi-sdk.js +6 -3
- package/dist/llm/pi-ai.js +35 -2
- package/dist/network/agent-network.js +78 -6
- package/dist/web/mobile-core.js +17 -0
- package/dist/web/mobile.css +24 -0
- package/dist/web/mobile.html +23 -13
- package/dist/web/mobile.js +480 -46
- package/dist/web/server.js +67 -9
- package/dist/web/sw.js +26 -2
- package/package.json +1 -1
package/dist/web/server.js
CHANGED
|
@@ -2886,6 +2886,16 @@ ${goalDesc}
|
|
|
2886
2886
|
out.judgments = [];
|
|
2887
2887
|
out.judgmentsError = e?.message;
|
|
2888
2888
|
}
|
|
2889
|
+
// 本机 skills (~/.bolloon/skills/) — 手机端「智能体控制 (MCP / Skills)」页读取
|
|
2890
|
+
try {
|
|
2891
|
+
const { loadSkillsFromPaths, defaultSkillPaths } = await import('../agents/skill-loader.js');
|
|
2892
|
+
const list = await loadSkillsFromPaths(defaultSkillPaths());
|
|
2893
|
+
out.skills = list.map((k) => ({ name: String(k.name || ''), description: String(k.description || '').slice(0, 200) }));
|
|
2894
|
+
}
|
|
2895
|
+
catch (e) {
|
|
2896
|
+
out.skills = [];
|
|
2897
|
+
out.skillsError = e?.message;
|
|
2898
|
+
}
|
|
2889
2899
|
// Agent 服务 Registry (发现层)
|
|
2890
2900
|
try {
|
|
2891
2901
|
const { getAgentRegistry } = await import('../agents/agent-registry.js');
|
|
@@ -3007,6 +3017,21 @@ ${goalDesc}
|
|
|
3007
3017
|
res.status(500).json({ ok: false, error: e?.message });
|
|
3008
3018
|
}
|
|
3009
3019
|
});
|
|
3020
|
+
// 2026-09-15: agent-delegate (manifest 协议 + agent_delegate) **启动即挂载**
|
|
3021
|
+
// 文档 bolloon-gateway-join.md 第 3 节要求 POST /api/agent/register 可用;
|
|
3022
|
+
// 之前只在 iroh 懒初始化 (/api/iroh/info 首次访问) 的收尾挂上 → 没触发时恒 404。
|
|
3023
|
+
let agentDelegateMounted = false;
|
|
3024
|
+
try {
|
|
3025
|
+
const delegateTransport = createIrohDelegateTransport({ verbose: true });
|
|
3026
|
+
// 注意: createAgentDelegateApp 内部声明的是绝对路径 (/api/agent/...),
|
|
3027
|
+
// 所以挂载时**不能**再带 '/api/agent' 前缀 (否则变成 /api/agent/api/agent/... 恒 404)
|
|
3028
|
+
app.use(createAgentDelegateApp(delegateTransport));
|
|
3029
|
+
agentDelegateMounted = true;
|
|
3030
|
+
console.log('[agent-delegate] 已挂载到 /api/agent (启动即用: local-manifest / register / pick / delegate)');
|
|
3031
|
+
}
|
|
3032
|
+
catch (e) {
|
|
3033
|
+
console.warn('[agent-delegate] 挂载失败 (非致命):', e?.message);
|
|
3034
|
+
}
|
|
3010
3035
|
// 2026-08-14: Agent Gateway — 网络加入 / 分享链接 / 成员 / 状态 (入口要小: 一条链接)
|
|
3011
3036
|
app.post('/api/gateway/join', async (req, res) => {
|
|
3012
3037
|
try {
|
|
@@ -3043,6 +3068,36 @@ ${goalDesc}
|
|
|
3043
3068
|
res.status(500).json({ error: e?.message });
|
|
3044
3069
|
}
|
|
3045
3070
|
});
|
|
3071
|
+
// 2026-09-15: 文档驱动「加入全球智能体网络」— 人类/手机只给一句 read <doc>, 这里做落地执行.
|
|
3072
|
+
// GET: 查入网态 (joined/url/did/networkLink); POST: 真执行 (可指定 url/name/capabilities/force).
|
|
3073
|
+
app.get('/api/gateway/join-global', async (_req, res) => {
|
|
3074
|
+
try {
|
|
3075
|
+
const { getGatewayJoinState, DEFAULT_GATEWAY_JOIN_DOC } = await import('../agents/gateway-join.js');
|
|
3076
|
+
const state = await getGatewayJoinState();
|
|
3077
|
+
res.json({ ok: true, joined: !!state, docUrl: DEFAULT_GATEWAY_JOIN_DOC, state });
|
|
3078
|
+
}
|
|
3079
|
+
catch (e) {
|
|
3080
|
+
res.status(500).json({ ok: false, error: e?.message });
|
|
3081
|
+
}
|
|
3082
|
+
});
|
|
3083
|
+
app.post('/api/gateway/join-global', async (req, res) => {
|
|
3084
|
+
try {
|
|
3085
|
+
const { joinGlobalGateway } = await import('../agents/gateway-join.js');
|
|
3086
|
+
const identity = await loadOrCreateUserIdentity();
|
|
3087
|
+
const caps = String(req.body?.capabilities || '').split(',').map((s) => s.trim()).filter(Boolean);
|
|
3088
|
+
const r = await joinGlobalGateway({
|
|
3089
|
+
url: String(req.body?.url || '').trim() || undefined,
|
|
3090
|
+
did: identity?.did || undefined,
|
|
3091
|
+
name: String(req.body?.name || '').trim() || identity?.name || undefined,
|
|
3092
|
+
capabilities: caps.length ? caps : undefined,
|
|
3093
|
+
force: req.body?.force === true,
|
|
3094
|
+
});
|
|
3095
|
+
res.status(r.ok ? 200 : 400).json(r);
|
|
3096
|
+
}
|
|
3097
|
+
catch (e) {
|
|
3098
|
+
res.status(500).json({ ok: false, error: e?.message });
|
|
3099
|
+
}
|
|
3100
|
+
});
|
|
3046
3101
|
app.get('/api/gateway/status', async (_req, res) => {
|
|
3047
3102
|
try {
|
|
3048
3103
|
const { gatewayStatus } = await import('../agents/agent-gateway.js');
|
|
@@ -6529,15 +6584,18 @@ ${goalDesc}
|
|
|
6529
6584
|
};
|
|
6530
6585
|
irohInitialized = true;
|
|
6531
6586
|
// 挂载 agent-delegate app (manifest 协议 + agent_delegate)
|
|
6532
|
-
//
|
|
6533
|
-
|
|
6534
|
-
|
|
6535
|
-
|
|
6536
|
-
|
|
6537
|
-
|
|
6538
|
-
|
|
6539
|
-
|
|
6540
|
-
|
|
6587
|
+
// 2026-09-15: 已改为启动时提前挂载 (见 createWebServer 的 /api/agent 段), 这里不再重复挂.
|
|
6588
|
+
if (!agentDelegateMounted) {
|
|
6589
|
+
try {
|
|
6590
|
+
const delegateTransport = createIrohDelegateTransport({ verbose: true });
|
|
6591
|
+
const delegateApp = createAgentDelegateApp(delegateTransport);
|
|
6592
|
+
app.use(delegateApp);
|
|
6593
|
+
agentDelegateMounted = true;
|
|
6594
|
+
console.log('[iroh API] agent-delegate app 已挂载到 /api/agent (补挂)');
|
|
6595
|
+
}
|
|
6596
|
+
catch (e) {
|
|
6597
|
+
console.error('[iroh API] 挂载 agent-delegate app 失败:', e);
|
|
6598
|
+
}
|
|
6541
6599
|
}
|
|
6542
6600
|
// 设置消息处理
|
|
6543
6601
|
irohTransport.onMessage('chat', (msg) => {
|
package/dist/web/sw.js
CHANGED
|
@@ -1,5 +1,12 @@
|
|
|
1
|
-
/* Bolloon 手机端 Service Worker — app-shell 缓存, 让 iPhone 可"添加到主屏幕"独立运行
|
|
2
|
-
|
|
1
|
+
/* Bolloon 手机端 Service Worker — app-shell 缓存, 让 iPhone 可"添加到主屏幕"独立运行
|
|
2
|
+
*
|
|
3
|
+
* 2026-09-14 修: 原来是 cache-first + 固定缓存名 (bolloon-mobile-v1) →
|
|
4
|
+
* 一旦装上, 之后每次升级 APK / 重新部署站点, WebView 里跑的仍是**旧的 mobile.js/mobile-core.js**,
|
|
5
|
+
* 表现为「改了 UI 手机上没变化」「升级后还是老界面」。
|
|
6
|
+
* 现在: 代码类资源 (html/js/css/json) 一律 **network-first** (拿不到网才回退缓存),
|
|
7
|
+
* 缓存名带版本号, activate 时清掉所有旧缓存; 图标等静态资源仍 cache-first。
|
|
8
|
+
*/
|
|
9
|
+
const CACHE = 'bolloon-mobile-v1.1';
|
|
3
10
|
const SHELL = [
|
|
4
11
|
'./mobile.html',
|
|
5
12
|
'./mobile.css',
|
|
@@ -25,6 +32,9 @@ self.addEventListener('activate', (e) => {
|
|
|
25
32
|
);
|
|
26
33
|
});
|
|
27
34
|
|
|
35
|
+
// 代码类资源: 必须联网拿最新的 (离线才回退缓存); 图标/manifest 之类可以 cache-first
|
|
36
|
+
const CODE_EXT = /\.(?:html|js|mjs|css|json|webmanifest)$/i;
|
|
37
|
+
|
|
28
38
|
self.addEventListener('fetch', (e) => {
|
|
29
39
|
const req = e.request;
|
|
30
40
|
if (req.method !== 'GET') return;
|
|
@@ -32,6 +42,20 @@ self.addEventListener('fetch', (e) => {
|
|
|
32
42
|
try { url = new URL(req.url); } catch { return; }
|
|
33
43
|
// 跨域 / API / 实时通道不缓存 (registry fetch、WebSocket 等)
|
|
34
44
|
if (url.origin !== location.origin || url.pathname.includes('/api/')) return;
|
|
45
|
+
|
|
46
|
+
if (CODE_EXT.test(url.pathname) || req.mode === 'navigate') {
|
|
47
|
+
e.respondWith(
|
|
48
|
+
fetch(req).then((res) => {
|
|
49
|
+
if (res && res.ok) {
|
|
50
|
+
const copy = res.clone();
|
|
51
|
+
caches.open(CACHE).then((c) => c.put(req, copy)).catch(() => {});
|
|
52
|
+
}
|
|
53
|
+
return res;
|
|
54
|
+
}).catch(() => caches.match(req).then((hit) => hit || caches.match('./mobile.html'))),
|
|
55
|
+
);
|
|
56
|
+
return;
|
|
57
|
+
}
|
|
58
|
+
|
|
35
59
|
e.respondWith(
|
|
36
60
|
caches.match(req).then((hit) => hit || fetch(req).then((res) => {
|
|
37
61
|
const copy = res.clone();
|