@bolloon/bolloon-agent 0.4.22 → 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.
@@ -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
- // 必须在 irohInitialized 之后挂, 因为适配器要监听 irohTransport.onMessage
6533
- try {
6534
- const delegateTransport = createIrohDelegateTransport({ verbose: true });
6535
- const delegateApp = createAgentDelegateApp(delegateTransport);
6536
- app.use('/api/agent', delegateApp);
6537
- console.log('[iroh API] agent-delegate app 已挂载到 /api/agent');
6538
- }
6539
- catch (e) {
6540
- console.error('[iroh API] 挂载 agent-delegate app 失败:', e);
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
- const CACHE = 'bolloon-mobile-v1';
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();
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@bolloon/bolloon-agent",
3
- "version": "0.4.22",
3
+ "version": "0.4.23",
4
4
  "type": "module",
5
5
  "description": "P2P AI Document Agent - 全局安装后执行 `bolloon` 启动产品",
6
6
  "main": "dist/cli-entry.js",