openclaw-openagent 1.0.1 → 1.0.3

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.
Files changed (188) hide show
  1. package/dist/index.d.ts +25 -0
  2. package/dist/index.js +105 -0
  3. package/dist/src/app/channel-tools.d.ts +28 -0
  4. package/dist/src/app/channel-tools.js +251 -0
  5. package/dist/src/app/discovery-tools.d.ts +35 -0
  6. package/dist/src/app/discovery-tools.js +243 -0
  7. package/dist/src/app/download-file-tool.d.ts +10 -0
  8. package/dist/src/app/download-file-tool.js +104 -0
  9. package/dist/src/app/hooks.d.ts +14 -0
  10. package/dist/src/app/hooks.js +118 -0
  11. package/dist/src/app/index.d.ts +13 -0
  12. package/dist/src/app/index.js +44 -0
  13. package/dist/src/app/messaging-tools.d.ts +11 -0
  14. package/dist/src/app/messaging-tools.js +79 -0
  15. package/dist/src/app/ops-tools.d.ts +21 -0
  16. package/dist/src/app/ops-tools.js +158 -0
  17. package/dist/src/app/remote-agent-tool.d.ts +27 -0
  18. package/dist/src/app/remote-agent-tool.js +461 -0
  19. package/dist/src/app/types.d.ts +61 -0
  20. package/dist/src/app/types.js +11 -0
  21. package/dist/src/app/upload-file-tool.d.ts +16 -0
  22. package/dist/src/app/upload-file-tool.js +353 -0
  23. package/dist/src/app/verbose-preflight.d.ts +2 -0
  24. package/dist/src/app/verbose-preflight.js +145 -0
  25. package/dist/src/auth/config.d.ts +79 -0
  26. package/dist/src/auth/config.js +133 -0
  27. package/dist/src/auth/credential-manager.d.ts +65 -0
  28. package/dist/src/auth/credential-manager.js +122 -0
  29. package/dist/src/auth/index.d.ts +6 -0
  30. package/dist/src/auth/index.js +6 -0
  31. package/dist/src/auth/verify.d.ts +42 -0
  32. package/dist/src/auth/verify.js +60 -0
  33. package/dist/src/channel.d.ts +269 -0
  34. package/dist/src/channel.js +488 -0
  35. package/dist/src/compat.d.ts +37 -0
  36. package/dist/src/compat.js +70 -0
  37. package/dist/src/config/config-schema.d.ts +56 -0
  38. package/dist/src/config/config-schema.js +34 -0
  39. package/dist/src/messaging/aggregator.d.ts +25 -0
  40. package/dist/src/messaging/aggregator.js +90 -0
  41. package/dist/src/messaging/collector.d.ts +27 -0
  42. package/dist/src/messaging/collector.js +76 -0
  43. package/dist/src/messaging/executor.d.ts +14 -0
  44. package/dist/src/messaging/executor.js +59 -0
  45. package/dist/src/messaging/inbound.d.ts +97 -0
  46. package/dist/src/messaging/inbound.js +63 -0
  47. package/dist/src/messaging/index.d.ts +10 -0
  48. package/dist/src/messaging/index.js +9 -0
  49. package/dist/src/messaging/mention-protocol.d.ts +42 -0
  50. package/dist/src/messaging/mention-protocol.js +74 -0
  51. package/dist/src/messaging/process-c2c-request.d.ts +55 -0
  52. package/dist/src/messaging/process-c2c-request.js +445 -0
  53. package/dist/src/messaging/process-message.d.ts +62 -0
  54. package/dist/src/messaging/process-message.js +282 -0
  55. package/dist/src/messaging/scheduler.d.ts +17 -0
  56. package/dist/src/messaging/scheduler.js +47 -0
  57. package/dist/src/messaging/types.d.ts +34 -0
  58. package/dist/src/messaging/types.js +4 -0
  59. package/dist/src/plugin-ui/assets/openagent-override.js +9278 -0
  60. package/dist/src/plugin-ui/index.d.ts +13 -0
  61. package/dist/src/plugin-ui/index.js +16 -0
  62. package/dist/src/plugin-ui/ui-extension-loader/backup.d.ts +23 -0
  63. package/dist/src/plugin-ui/ui-extension-loader/backup.js +82 -0
  64. package/dist/src/plugin-ui/ui-extension-loader/index.d.ts +28 -0
  65. package/dist/src/plugin-ui/ui-extension-loader/index.js +240 -0
  66. package/dist/src/plugin-ui/ui-extension-loader/locator.d.ts +35 -0
  67. package/dist/src/plugin-ui/ui-extension-loader/locator.js +129 -0
  68. package/dist/src/plugin-ui/ui-extension-loader/manifest.d.ts +26 -0
  69. package/dist/src/plugin-ui/ui-extension-loader/manifest.js +45 -0
  70. package/dist/src/plugin-ui/ui-extension-loader/registry-regex.d.ts +9 -0
  71. package/dist/src/plugin-ui/ui-extension-loader/registry-regex.js +724 -0
  72. package/dist/src/plugin-ui/ui-extension-loader/removed-extensions.d.ts +8 -0
  73. package/dist/src/plugin-ui/ui-extension-loader/removed-extensions.js +58 -0
  74. package/dist/src/plugin-ui/ui-extension-loader/types.d.ts +55 -0
  75. package/dist/src/plugin-ui/ui-extension-loader/types.js +23 -0
  76. package/dist/src/proxy/auth-proxy.d.ts +20 -0
  77. package/dist/src/proxy/auth-proxy.js +337 -0
  78. package/dist/src/runtime/account.d.ts +156 -0
  79. package/dist/src/runtime/account.js +491 -0
  80. package/dist/src/runtime/index.d.ts +5 -0
  81. package/dist/src/runtime/index.js +6 -0
  82. package/dist/src/runtime/plugin-runtime.d.ts +40 -0
  83. package/dist/src/runtime/plugin-runtime.js +72 -0
  84. package/dist/src/runtime/registry.d.ts +41 -0
  85. package/dist/src/runtime/registry.js +60 -0
  86. package/dist/src/sdk/CLASS_MAP.md +143 -0
  87. package/dist/src/sdk/index.d.ts +126 -0
  88. package/dist/src/sdk/index.js +23990 -0
  89. package/dist/src/sdk/modules/cloud-search-module.js +1117 -0
  90. package/dist/src/sdk/modules/follow-module.js +1069 -0
  91. package/dist/src/sdk/modules/group-module.js +7397 -0
  92. package/dist/src/sdk/modules/relationship-module.js +2269 -0
  93. package/dist/src/sdk/modules/signaling-module.js +1468 -0
  94. package/dist/src/sdk/modules/tim-upload-plugin.js +730 -0
  95. package/dist/src/sdk/node-env/http-request.js +90 -0
  96. package/dist/src/sdk/node-env/index.js +57 -0
  97. package/dist/src/sdk/node-env/storage.js +114 -0
  98. package/dist/src/sdk/package.json +10 -0
  99. package/dist/src/sdk/sdk/CLASS_MAP.md +143 -0
  100. package/dist/src/sdk/sdk/index.d.ts +126 -0
  101. package/dist/src/sdk/sdk/index.js +23990 -0
  102. package/dist/src/sdk/sdk/modules/cloud-search-module.js +1117 -0
  103. package/dist/src/sdk/sdk/modules/follow-module.js +1069 -0
  104. package/dist/src/sdk/sdk/modules/group-module.js +7397 -0
  105. package/dist/src/sdk/sdk/modules/relationship-module.js +2269 -0
  106. package/dist/src/sdk/sdk/modules/signaling-module.js +1468 -0
  107. package/dist/src/sdk/sdk/modules/tim-upload-plugin.js +730 -0
  108. package/dist/src/sdk/sdk/node-env/http-request.js +90 -0
  109. package/dist/src/sdk/sdk/node-env/index.js +57 -0
  110. package/dist/src/sdk/sdk/node-env/storage.js +114 -0
  111. package/dist/src/sdk/sdk/package.json +10 -0
  112. package/dist/src/sdk/sdk/tsconfig.json +16 -0
  113. package/dist/src/sdk/tsconfig.json +16 -0
  114. package/dist/src/state/pending-invocation-store.d.ts +26 -0
  115. package/dist/src/state/pending-invocation-store.js +39 -0
  116. package/dist/src/state/store.d.ts +165 -0
  117. package/dist/src/state/store.js +535 -0
  118. package/dist/src/tim/c2c.d.ts +83 -0
  119. package/dist/src/tim/c2c.js +318 -0
  120. package/dist/src/tim/channels.d.ts +95 -0
  121. package/dist/src/tim/channels.js +279 -0
  122. package/dist/src/tim/client.d.ts +54 -0
  123. package/dist/src/tim/client.js +268 -0
  124. package/dist/src/tim/index.d.ts +6 -0
  125. package/dist/src/tim/index.js +6 -0
  126. package/dist/src/tim/messages.d.ts +50 -0
  127. package/dist/src/tim/messages.js +104 -0
  128. package/dist/src/tim/sdk-logger-init.d.ts +13 -0
  129. package/dist/src/tim/sdk-logger-init.js +46 -0
  130. package/dist/src/tools.d.ts +9 -0
  131. package/dist/src/tools.js +8 -0
  132. package/dist/src/transport/factory.d.ts +63 -0
  133. package/dist/src/transport/factory.js +54 -0
  134. package/dist/src/transport/oasn/index.d.ts +12 -0
  135. package/dist/src/transport/oasn/index.js +9 -0
  136. package/dist/src/transport/oasn/oasn-agent-card.d.ts +38 -0
  137. package/dist/src/transport/oasn/oasn-agent-card.js +102 -0
  138. package/dist/src/transport/oasn/oasn-discovery.d.ts +33 -0
  139. package/dist/src/transport/oasn/oasn-discovery.js +97 -0
  140. package/dist/src/transport/oasn/oasn-files.d.ts +64 -0
  141. package/dist/src/transport/oasn/oasn-files.js +174 -0
  142. package/dist/src/transport/oasn/oasn-http.d.ts +98 -0
  143. package/dist/src/transport/oasn/oasn-http.js +362 -0
  144. package/dist/src/transport/oasn/oasn-invocation.d.ts +154 -0
  145. package/dist/src/transport/oasn/oasn-invocation.js +432 -0
  146. package/dist/src/transport/oasn/oasn-normalize.d.ts +6 -0
  147. package/dist/src/transport/oasn/oasn-normalize.js +112 -0
  148. package/dist/src/transport/oasn/oasn-register.d.ts +19 -0
  149. package/dist/src/transport/oasn/oasn-register.js +24 -0
  150. package/dist/src/transport/oasn/oasn-transport.d.ts +114 -0
  151. package/dist/src/transport/oasn/oasn-transport.js +230 -0
  152. package/dist/src/transport/oasn/oasn-types.d.ts +331 -0
  153. package/dist/src/transport/oasn/oasn-types.js +44 -0
  154. package/dist/src/transport/tim/index.d.ts +7 -0
  155. package/dist/src/transport/tim/index.js +6 -0
  156. package/dist/src/transport/tim/tim-transport.d.ts +122 -0
  157. package/dist/src/transport/tim/tim-transport.js +402 -0
  158. package/dist/src/transport/types.d.ts +450 -0
  159. package/dist/src/transport/types.js +38 -0
  160. package/dist/src/util/http.d.ts +21 -0
  161. package/dist/src/util/http.js +93 -0
  162. package/dist/src/util/logger.d.ts +20 -0
  163. package/dist/src/util/logger.js +100 -0
  164. package/dist/src/util/url-resolver.d.ts +7 -0
  165. package/dist/src/util/url-resolver.js +20 -0
  166. package/index.ts +11 -0
  167. package/openclaw.plugin.json +9 -0
  168. package/package.json +7 -4
  169. package/src/app/download-file-tool.ts +133 -0
  170. package/src/app/hooks.ts +89 -5
  171. package/src/app/index.ts +6 -0
  172. package/src/app/remote-agent-tool.ts +46 -0
  173. package/src/app/types.ts +1 -0
  174. package/src/app/upload-file-tool.ts +411 -0
  175. package/src/plugin-ui/assets/openagent-override.js +15 -66
  176. package/src/plugin-ui/modules/agent-book/panel/agent-book.js +0 -61
  177. package/src/plugin-ui/modules/agent-book/panel/agent-data.js +0 -1
  178. package/src/plugin-ui/modules/agent-book/panel/inject-ui.js +14 -3
  179. package/src/plugin-ui/ui-extension-loader/registry-regex.ts +102 -63
  180. package/src/runtime/account.ts +0 -23
  181. package/src/transport/oasn/oasn-files.ts +5 -5
  182. package/src/transport/oasn/oasn-invocation.ts +44 -2
  183. package/src/transport/oasn/oasn-normalize.ts +0 -26
  184. package/src/transport/oasn/oasn-register.ts +8 -81
  185. package/src/transport/oasn/oasn-transport.ts +9 -32
  186. package/src/transport/oasn/oasn-types.ts +53 -6
  187. package/src/transport/types.ts +33 -36
  188. package/src/util/url-resolver.ts +17 -0
@@ -288,52 +288,64 @@ const toolcardRender: UIExtension = {
288
288
  const toolMessageAnchor = 'toolmsg:${';
289
289
  let patchedToolMessageWrapper = false;
290
290
  if (content.includes(toolMessageAnchor)) {
291
+ let toolMessageOk = true;
291
292
  const toolMessageFn = findFunctionByAnchor(content, toolMessageAnchor, 8000);
292
293
  if (!toolMessageFn) {
293
294
  logger.warn('[ui-ext:regex] toolcard-render: tool message wrapper function not found');
294
- return false;
295
+ toolMessageOk = false;
295
296
  }
296
297
 
297
- if (!toolMessageFn.body.includes('chat-tool-msg-collapse--manual')
298
- || !toolMessageFn.body.includes('chat-tool-msg-body')) {
298
+ if (toolMessageOk && (!toolMessageFn!.body.includes('chat-tool-msg-collapse--manual')
299
+ || !toolMessageFn!.body.includes('chat-tool-msg-body'))) {
299
300
  logger.warn('[ui-ext:regex] toolcard-render: tool message wrapper shape mismatch');
300
- return false;
301
+ toolMessageOk = false;
301
302
  }
302
303
 
303
- const toolMessageReturnTagMatch = toolMessageFn.body.match(/return\s+([a-zA-Z_$]\w*)\s*`/);
304
- if (!toolMessageReturnTagMatch) {
305
- logger.warn('[ui-ext:regex] toolcard-render: tool message Lit html tag not found');
306
- return false;
304
+ let toolMessageHtmlVar = '';
305
+ if (toolMessageOk) {
306
+ const toolMessageReturnTagMatch = toolMessageFn!.body.match(/return\s+([a-zA-Z_$]\w*)\s*`/);
307
+ if (!toolMessageReturnTagMatch) {
308
+ logger.warn('[ui-ext:regex] toolcard-render: tool message Lit html tag not found');
309
+ toolMessageOk = false;
310
+ } else {
311
+ toolMessageHtmlVar = toolMessageReturnTagMatch[1];
312
+ }
307
313
  }
308
- const toolMessageHtmlVar = toolMessageReturnTagMatch[1];
309
314
 
310
- const singleCardMatch = toolMessageFn.body.match(/(?:let\s+|,)([a-zA-Z_$]\w*)=([a-zA-Z_$]\w*)\.length===1\?\2\[0\]:null,\w+=\1&&!([a-zA-Z_$]\w*)&&!([a-zA-Z_$]\w*)\?/);
311
- if (!singleCardMatch) {
312
- logger.warn('[ui-ext:regex] toolcard-render: tool message single-card guard not found');
313
- return false;
314
- }
315
- const cardsVar = singleCardMatch[2];
316
- const mediaVar = singleCardMatch[4];
317
- const chatBubbleClassMatch = toolMessageFn.body.match(/[,;]([a-zA-Z_$]\w*)=\[`chat-bubble`,/);
318
- if (!chatBubbleClassMatch) {
319
- logger.warn('[ui-ext:regex] toolcard-render: tool message chat-bubble class var not found');
320
- return false;
321
- }
322
- const chatBubbleClassVar = chatBubbleClassMatch[1];
323
- const toolMessageParams = toolMessageFn.params.split(',').map((s: string) => s.trim());
324
- const toolMessageSidebarArg = toolMessageParams[3] || 'undefined';
325
- const toolMessageReturnIdx = toolMessageFn.body.indexOf(`return ${toolMessageHtmlVar}\``);
326
- if (toolMessageReturnIdx < 0) {
327
- logger.warn('[ui-ext:regex] toolcard-render: tool message return anchor not found');
328
- return false;
315
+ if (toolMessageOk) {
316
+ const singleCardMatch = toolMessageFn!.body.match(/(?:let\s+|,)([a-zA-Z_$]\w*)=([a-zA-Z_$]\w*)\.length===1\?\2\[0\]:null,\w+=\1&&!([a-zA-Z_$]\w*)&&!([a-zA-Z_$]\w*)\?/);
317
+ if (!singleCardMatch) {
318
+ logger.warn('[ui-ext:regex] toolcard-render: tool message single-card guard not found');
319
+ toolMessageOk = false;
320
+ }
321
+ if (toolMessageOk) {
322
+ const cardsVar = singleCardMatch![2];
323
+ const mediaVar = singleCardMatch![4];
324
+ const chatBubbleClassMatch = toolMessageFn!.body.match(/[,;]([a-zA-Z_$]\w*)=\[`chat-bubble`,/);
325
+ if (!chatBubbleClassMatch) {
326
+ logger.warn('[ui-ext:regex] toolcard-render: tool message chat-bubble class var not found');
327
+ toolMessageOk = false;
328
+ }
329
+ if (toolMessageOk) {
330
+ const chatBubbleClassVar = chatBubbleClassMatch![1];
331
+ const toolMessageParams = toolMessageFn!.params.split(',').map((s: string) => s.trim());
332
+ const toolMessageSidebarArg = toolMessageParams[3] || 'undefined';
333
+ const toolMessageReturnIdx = toolMessageFn!.body.indexOf(`return ${toolMessageHtmlVar}\``);
334
+ if (toolMessageReturnIdx < 0) {
335
+ logger.warn('[ui-ext:regex] toolcard-render: tool message return anchor not found');
336
+ toolMessageOk = false;
337
+ }
338
+ if (toolMessageOk) {
339
+ const toolMessageHook =
340
+ `${marker}let __openagentToolMsgCard=null;if(!${mediaVar}&&window.__openagentRenderToolCard){for(let __openagentI=${cardsVar}.length-1;__openagentI>=0&&!__openagentToolMsgCard;__openagentI--){let __openagentCandidate=${cardsVar}[__openagentI];if(__openagentCandidate&&(__openagentCandidate.outputText||__openagentCandidate.text))__openagentToolMsgCard=window.__openagentRenderToolCard(__openagentCandidate,${toolMessageSidebarArg})}for(let __openagentI=0;__openagentI<${cardsVar}.length&&!__openagentToolMsgCard;__openagentI++){__openagentToolMsgCard=window.__openagentRenderToolCard(${cardsVar}[__openagentI],${toolMessageSidebarArg})}}if(__openagentToolMsgCard)return ${toolMessageHtmlVar}\`<div class="\${${chatBubbleClassVar}}">\${__openagentToolMsgCard}</div>\`;`;
341
+ const toolMessageInsertAt = toolMessageFn!.bodyStart + toolMessageReturnIdx;
342
+ content = content.substring(0, toolMessageInsertAt) + toolMessageHook + content.substring(toolMessageInsertAt);
343
+ patchedToolMessageWrapper = true;
344
+ logger.info(`[ui-ext:regex] toolcard-render: patched tool message wrapper ${toolMessageFn!.funcName}(${toolMessageFn!.params.substring(0, 20)}) html=${toolMessageHtmlVar}`);
345
+ }
346
+ }
347
+ }
329
348
  }
330
-
331
- const toolMessageHook =
332
- `${marker}let __openagentToolMsgCard=null;if(!${mediaVar}&&window.__openagentRenderToolCard){for(let __openagentI=${cardsVar}.length-1;__openagentI>=0&&!__openagentToolMsgCard;__openagentI--){let __openagentCandidate=${cardsVar}[__openagentI];if(__openagentCandidate&&(__openagentCandidate.outputText||__openagentCandidate.text))__openagentToolMsgCard=window.__openagentRenderToolCard(__openagentCandidate,${toolMessageSidebarArg})}for(let __openagentI=0;__openagentI<${cardsVar}.length&&!__openagentToolMsgCard;__openagentI++){__openagentToolMsgCard=window.__openagentRenderToolCard(${cardsVar}[__openagentI],${toolMessageSidebarArg})}}if(__openagentToolMsgCard)return ${toolMessageHtmlVar}\`<div class="\${${chatBubbleClassVar}}">\${__openagentToolMsgCard}</div>\`;`;
333
- const toolMessageInsertAt = toolMessageFn.bodyStart + toolMessageReturnIdx;
334
- content = content.substring(0, toolMessageInsertAt) + toolMessageHook + content.substring(toolMessageInsertAt);
335
- patchedToolMessageWrapper = true;
336
- logger.info(`[ui-ext:regex] toolcard-render: patched tool message wrapper ${toolMessageFn.funcName}(${toolMessageFn.params.substring(0, 20)}) html=${toolMessageHtmlVar}`);
337
349
  }
338
350
 
339
351
  writeFileSync(bundlePath, content, 'utf-8');
@@ -440,7 +452,7 @@ const toolcallidPropagate: UIExtension = {
440
452
 
441
453
  // 计算注入内容
442
454
  const marker = makeMarker(this.id);
443
- const tcidCapture = `${marker}var __tcid=(typeof ${mVar}.toolCallId==='string'&&${mVar}.toolCallId)||(typeof ${mVar}.tool_call_id==='string'&&${mVar}.tool_call_id)||'';`;
455
+ const tcidCapture = `${marker}var __tcid=(typeof ${msgParam}.toolCallId==='string'&&${msgParam}.toolCallId)||(typeof ${msgParam}.tool_call_id==='string'&&${msgParam}.tool_call_id)||'';`;
444
456
 
445
457
  const inlinePatchCall = callLoopVar
446
458
  ? `,toolCallId:__tcid||${callLoopVar}.id||${callLoopVar}.toolCallId||${callLoopVar}.tool_call_id||''`
@@ -454,16 +466,16 @@ const toolcallidPropagate: UIExtension = {
454
466
  const arrInitPattern = `,${cardsVar}=[];`;
455
467
  let arrInitIdx = funcBody.indexOf(arrInitPattern);
456
468
  if (arrInitIdx < 0) {
457
- // v4.11+: 可能是 ,i=[](后接分号或逗号之前的位置不同)
469
+ // v4.11+: 可能是 ,i=[](后接逗号,如 a=[],o=...),不能直接插 var
458
470
  const altPattern = `,${cardsVar}=[]`;
459
471
  arrInitIdx = funcBody.indexOf(altPattern);
460
472
  if (arrInitIdx < 0) {
461
473
  logger.warn('[ui-ext:regex] toolcallid-propagate: cards init not found');
462
474
  return false;
463
475
  }
464
- // 找到 ] 后面的分隔符位置
465
- arrInitIdx += altPattern.length;
466
- // captureInsertOffset ; 或 , 之后
476
+ // altPattern 后面是逗号(逗号表达式),var 声明无法插入此处
477
+ // 改为插入到函数体开头,利用 var 提升特性
478
+ arrInitIdx = 0;
467
479
  } else {
468
480
  arrInitIdx += arrInitPattern.length;
469
481
  }
@@ -583,7 +595,7 @@ const toolcallidPropagate: UIExtension = {
583
595
  };
584
596
 
585
597
 
586
- // ── Extension 6: remote-agent-message-short-circuit(正则定位,双策略A+B)─
598
+ // ── Extension 6: remote-agent-message-short-circuit(三策略 A/B/C)───────
587
599
 
588
600
  const remoteAgentMessageShortCircuit: UIExtension = {
589
601
  id: 'remote-agent-message-short-circuit',
@@ -597,16 +609,16 @@ const remoteAgentMessageShortCircuit: UIExtension = {
597
609
  if (hasMarker(content, this.id)) { return true; }
598
610
  if (!backupFile(bundlePath)) return false;
599
611
 
600
- // 找 showToolCalls 赋值
612
+ // 找 showToolCalls 赋值 → 提取 toolCardsVar / hasToolCardsVar
601
613
  const assignRe = /(\w+)=\w+\.showToolCalls[^;]*\(\w+(?:,\w+)?\)\s*:\s*\[\]\s*,\s*(\w+)\s*=\s*\1\.length\s*>\s*0/;
602
614
  const assignMatch = content.match(assignRe);
603
615
  if (!assignMatch) {
604
- logger.warn('[ui-ext:regex] remote-agent-msg: showToolCalls pattern not found');
616
+ logger.warn('[ui-ext:regex] remote-agent-msg: showToolCalls assignment not found');
605
617
  return false;
606
618
  }
607
619
 
608
- const toolCardsVar = assignMatch[1];
609
- const hasToolCardsVar = assignMatch[2];
620
+ const toolCardsVar = assignMatch[1]!;
621
+ const hasToolCardsVar = assignMatch[2]!;
610
622
  const marker = makeMarker(this.id);
611
623
 
612
624
  // 策略A (v3.23~v4.10): if(!markdown&&hasToolCards&&isToolResult)
@@ -614,8 +626,8 @@ const remoteAgentMessageShortCircuit: UIExtension = {
614
626
  const ifMatchA = content.match(ifReA);
615
627
 
616
628
  if (ifMatchA) {
617
- const markdownVar = ifMatchA[1];
618
- const isToolResultVar = ifMatchA[2];
629
+ const markdownVar = ifMatchA[1]!;
630
+ const isToolResultVar = ifMatchA[2]!;
619
631
  const patched = `if(${marker}(!${markdownVar}||window.__openagentOwnsToolCards&&window.__openagentOwnsToolCards(${toolCardsVar}))&&${hasToolCardsVar}&&${isToolResultVar})`;
620
632
  content = content.substring(0, ifMatchA.index!) + patched + content.substring(ifMatchA.index! + ifMatchA[0].length);
621
633
  writeFileSync(bundlePath, content, 'utf-8');
@@ -623,15 +635,30 @@ const remoteAgentMessageShortCircuit: UIExtension = {
623
635
  return true;
624
636
  }
625
637
 
626
- // 策略B (v4.11+): compound = hasToolCards && (showToolCalls ?? !0)
638
+ // 策略C (2026.4.x): if(!VAR.showToolCalls&&...toolresult...)continue
639
+ // 直接匹配 continue 跳过语句,注入 openagentOwnsToolCards 条件
640
+ const continueRe = /if\(!(\w+)\.showToolCalls&&(\w+)\.role\.toLowerCase\(\)===`toolresult`\)continue/;
641
+ const continueMatch = content.match(continueRe);
642
+
643
+ if (continueMatch) {
644
+ const scVar = continueMatch[1]!;
645
+ const roleVar = continueMatch[2]!;
646
+ const patched = `if(!${scVar}.showToolCalls&&!window.__openagentOwnsToolCards?.(${toolCardsVar})&&${roleVar}.role.toLowerCase()===\`toolresult\`)continue`;
647
+ content = content.substring(0, continueMatch.index!) + marker + patched + content.substring(continueMatch.index! + continueMatch[0].length);
648
+ writeFileSync(bundlePath, content, 'utf-8');
649
+ logger.info(`[ui-ext:regex] remote-agent-msg: patched (strategy C, sc=${scVar})`);
650
+ return true;
651
+ }
652
+
653
+ // 策略B (v4.11~v4.1x fallback): compound = hasToolCards && (showToolCalls ?? !0)
627
654
  const compoundRe = new RegExp(`(\\w+)=${hasToolCardsVar}&&\\(\\w+\\.showToolCalls\\?\\?!0\\)`);
628
655
  const compoundMatch = content.match(compoundRe);
629
656
  if (!compoundMatch) {
630
- logger.warn('[ui-ext:regex] remote-agent-msg: both strategies failed');
657
+ logger.warn('[ui-ext:regex] remote-agent-msg: all strategies (A/C/B) failed');
631
658
  return false;
632
659
  }
633
660
 
634
- const compoundVar = compoundMatch[1];
661
+ const compoundVar = compoundMatch[1]!;
635
662
  const ifReB = new RegExp(`if\\(!(\\w+)&&!${compoundVar}&&`);
636
663
  const ifMatchB = content.match(ifReB);
637
664
  if (!ifMatchB) {
@@ -639,7 +666,7 @@ const remoteAgentMessageShortCircuit: UIExtension = {
639
666
  return false;
640
667
  }
641
668
 
642
- const markdownVarB = ifMatchB[1];
669
+ const markdownVarB = ifMatchB[1]!;
643
670
  const patchedCond = `if(${marker}(!${markdownVarB}||window.__openagentOwnsToolCards&&window.__openagentOwnsToolCards(${toolCardsVar}))&&!${compoundVar}&&`;
644
671
  content = content.substring(0, ifMatchB.index!) + patchedCond + content.substring(ifMatchB.index! + ifMatchB[0].length);
645
672
  writeFileSync(bundlePath, content, 'utf-8');
@@ -657,7 +684,7 @@ const remoteAgentMessageShortCircuit: UIExtension = {
657
684
 
658
685
  const mentionHooks: UIExtension = {
659
686
  id: 'mention-hooks',
660
- version: 2,
687
+ version: 3,
661
688
  sharedFile: 'index-bundle',
662
689
 
663
690
  apply(controlUiDir: string): boolean {
@@ -668,46 +695,58 @@ const mentionHooks: UIExtension = {
668
695
  if (!backupFile(bundlePath)) return false;
669
696
 
670
697
  // 注入点 A: handleKeyDown
671
- const keydownRe = /;return\}if\(([a-zA-Z_$][a-zA-Z0-9_$]*)\.key===`Enter`&&!\1\.shiftKey\)\{if\(\1\.isComposing/;
698
+ // 锚定 ;return}if(X.key===`Enter`&&!X.shiftKey){
699
+ // 不再依赖内层 isComposing:2026.6.10 已把 isComposing 检查拆到独立 handler
700
+ const keydownRe = /;return\}if\(([a-zA-Z_$][a-zA-Z0-9_$]*)\.key===`Enter`&&!\1\.shiftKey\)\{/;
672
701
  const keydownMatch = content.match(keydownRe);
673
702
  if (!keydownMatch) {
674
703
  logger.warn('[ui-ext:regex] mention-hooks: keydown anchor not found');
675
704
  return false;
676
705
  }
677
706
  const eventParam = keydownMatch[1];
678
- const keydownInsertIdx = content.indexOf(keydownMatch[0]) + ';return}'.length;
707
+ const keydownInsertIdx = content.indexOf(keydownMatch[0]) + keydownMatch[0].indexOf('if(');
679
708
  const markerA = makeMarker(this.id);
680
709
  const hookA = `${markerA}if(window.__clMention?.onKeyDown(${eventParam}))return;`;
681
710
  content = content.substring(0, keydownInsertIdx) + hookA + content.substring(keydownInsertIdx);
682
711
 
683
- // 注入点 B: handleInput — 支持两种形态
684
- // Shape A (old): .onDraftChange(target.value)}}
685
- // Shape B (4.11/latest): .onDraftChange(target.value) (arrow function 内,无 }})
712
+ // 注入点 B: handleInput — 支持三种形态
713
+ // Shape A (old): .onDraftChange(target.value)}}
714
+ // Shape B (4.11~4.x): .onDraftChange(target.value) (arrow function )
715
+ // Shape C (2026.6.x): be=t=>{let n=t.target;pL(e,n.value)} — 引入 pL helper,
716
+ // arrow body 末尾不再出现 onDraftChange 字面
686
717
  const inputReA = /\.onDraftChange\(([a-zA-Z_$][a-zA-Z0-9_$]*)\.value\)\}\}/;
687
718
  const inputReB = /\.onDraftChange\(([a-zA-Z_$][a-zA-Z0-9_$]*)\.value\)/;
719
+ const inputReC = /let ([a-zA-Z_$][a-zA-Z0-9_$]*)=[a-zA-Z_$][a-zA-Z0-9_$]*\.target;[a-zA-Z_$][a-zA-Z0-9_$]*\([a-zA-Z_$][a-zA-Z0-9_$]*,\1\.value\)\}/;
720
+
688
721
  let inputMatch = content.match(inputReA);
689
- let inputShape: 'A' | 'B' = 'A';
722
+ let inputShape: 'A' | 'B' | 'C' = 'A';
690
723
 
724
+ if (!inputMatch) {
725
+ inputMatch = content.match(inputReC);
726
+ inputShape = 'C';
727
+ }
691
728
  if (!inputMatch) {
692
729
  inputMatch = content.match(inputReB);
693
730
  inputShape = 'B';
694
731
  }
695
732
 
696
733
  if (!inputMatch) {
697
- logger.warn('[ui-ext:regex] mention-hooks: input anchor not found (neither Shape A nor B)');
734
+ logger.warn('[ui-ext:regex] mention-hooks: input anchor not found (Shape A/B/C all missed)');
698
735
  return false;
699
736
  }
700
737
  const targetVar = inputMatch[1];
701
738
  const inputAnchorIdx = content.indexOf(inputMatch[0]);
702
- // 计算 onDraftChange(x.value) 调用结束位置
739
+ // Shape A: }} 之前;Shape C: 末尾 } 之前;Shape B: ) 之后
703
740
  const draftCallEnd = inputShape === 'A'
704
- ? inputAnchorIdx + inputMatch[0].length - 2 // 在 }} 之前
705
- : inputAnchorIdx + inputMatch[0].length; // 在 ) 之后
741
+ ? inputAnchorIdx + inputMatch[0].length - 2
742
+ : inputShape === 'C'
743
+ ? inputAnchorIdx + inputMatch[0].length - 1
744
+ : inputAnchorIdx + inputMatch[0].length;
706
745
  const hookB = `;window.__clMention?.onInput?.(${targetVar})`;
707
746
  content = content.substring(0, draftCallEnd) + hookB + content.substring(draftCallEnd);
708
747
 
709
748
  writeFileSync(bundlePath, content, 'utf-8');
710
- logger.info(`[ui-ext:regex] mention-hooks: injected (event=${eventParam}, target=${targetVar})`);
749
+ logger.info(`[ui-ext:regex] mention-hooks: injected (shape=${inputShape}, event=${eventParam}, target=${targetVar})`);
711
750
  return true;
712
751
  },
713
752
 
@@ -39,7 +39,6 @@ import { createTransport } from '../transport/factory.js';
39
39
  import type {
40
40
  AgentTransport,
41
41
  AgentStatusResult,
42
- ClaimResult,
43
42
  OasnTransport,
44
43
  TransportCredentials,
45
44
  } from '../transport/types.js';
@@ -310,28 +309,6 @@ export class AccountRuntime {
310
309
  this._statusPollTimer = null;
311
310
  }
312
311
 
313
- async claimOwnerEmail(ownerEmail: string): Promise<ClaimResult> {
314
- if (this._transportType !== 'oasn') {
315
- throw new Error('Agent claim is only available in OASN mode');
316
- }
317
- await this.ensureConnected();
318
- const transport = this.transport;
319
- if (!transport || transport.transportType !== 'oasn') {
320
- throw new Error('OASN transport not ready');
321
- }
322
- const oasnTransport = transport as OasnTransport;
323
- const result = await oasnTransport.claimAgent({
324
- agent_id: this._config?.agentId,
325
- owner_email: ownerEmail,
326
- });
327
- this._claimStatus = 'claim_pending';
328
- this._claimExpiresAt = result.expires_at;
329
- this._saveOasnAccountConfig({ status: 'claim_pending' });
330
- this._scheduleOasnStatusPolling(oasnTransport);
331
- logger.info(`[runtime] OASN claim started: agent_id=${result.agent_id} owner=${result.owner_email_masked} expires_at=${result.expires_at}`);
332
- return result;
333
- }
334
-
335
312
  assertOasnInvocationAllowed(): void {
336
313
  if (this._transportType === 'oasn' && this._claimStatus !== 'claimed') {
337
314
  throw new Error(`OASN ClientAgent is not claimed yet (status=${this._claimStatus}). Complete claim before calling remote agents.`);
@@ -155,11 +155,11 @@ export class OasnFiles {
155
155
  );
156
156
 
157
157
  return {
158
- fileRef: resp.file_ref,
159
- displayName: resp.display_name,
160
- mimeType: resp.mime_type,
161
- sizeBytes: resp.size_bytes,
162
- expiresAt: this._parseExpiresAt(resp.expires_at),
158
+ fileRef: resp.fileRef ?? resp.file_ref ?? '',
159
+ displayName: resp.displayName ?? resp.display_name ?? 'unknown',
160
+ mimeType: resp.mimeType ?? resp.mime_type ?? 'application/octet-stream',
161
+ sizeBytes: resp.sizeBytes ?? resp.size_bytes ?? 0,
162
+ expiresAt: this._parseExpiresAt(resp.expiresAt ?? resp.expires_at ?? ''),
163
163
  };
164
164
  }
165
165
 
@@ -38,6 +38,7 @@ import {
38
38
  type TaskRequest,
39
39
  type TaskResult,
40
40
  type TransportError,
41
+ type WebuiContinuationRef,
41
42
  } from '../types.js';
42
43
  import type { OasnHttpClient } from './oasn-http.js';
43
44
  import {
@@ -48,6 +49,7 @@ import {
48
49
  type CreateInvocationResponse,
49
50
  type GetInvocationResponse,
50
51
  type InvocationStatus,
52
+ type VisibleResultResponse,
51
53
  } from './oasn-types.js';
52
54
 
53
55
  /** Invocation 持久化钩子(接 StateStore.pending_invocations,§11.1) */
@@ -378,31 +380,71 @@ export class OasnInvocation {
378
380
  /**
379
381
  * 把终态 Invocation 响应转换为 TaskResult。
380
382
  *
381
- * - succeeded → status:'complete' + content=summary + artifacts
383
+ * - succeeded → status:'complete' + content=summary + artifacts + webuiContinuation
382
384
  * - 其它终态 → status:'error' + content=user_error.message
385
+ *
386
+ * content 的归一路径:
387
+ * inlineResult.summary > visible_result.inline_result_summary > ''
388
+ *
389
+ * webui_continuation 仅在 succeeded 时抽取(失败场景后端不保证存在)。
383
390
  */
384
391
  private _toTaskResult(invocationId: string, final: GetInvocationResponse): TaskResult {
392
+ const webuiContinuation = this._toWebuiContinuation(final);
393
+
385
394
  if (final.status === 'succeeded') {
386
395
  const inlineResult = final.inlineResult ?? final.inline_result;
396
+ const visible = final.visibleResult ?? final.visible_result;
397
+ const summary = inlineResult?.summary
398
+ ?? visible?.inlineResultSummary
399
+ ?? visible?.inline_result_summary
400
+ ?? '';
387
401
  return {
388
402
  requestId: invocationId,
389
403
  status: 'complete',
390
- content: inlineResult?.summary ?? '',
404
+ content: summary,
391
405
  artifacts: (final.artifacts ?? []).map(this._toArtifactRef),
406
+ webuiContinuation,
392
407
  };
393
408
  }
394
409
 
395
410
  // 失败/超时/取消 —— 文本统一用 user_error.message 兜底
396
411
  const userError = final.userError ?? final.user_error;
397
412
  const inlineResult = final.inlineResult ?? final.inline_result;
413
+ const visible = final.visibleResult ?? final.visible_result;
398
414
  const message = userError?.message
399
415
  ?? inlineResult?.summary
416
+ ?? visible?.inlineResultSummary
417
+ ?? visible?.inline_result_summary
400
418
  ?? `Invocation ended with status=${final.status}`;
401
419
  return {
402
420
  requestId: invocationId,
403
421
  status: 'error',
404
422
  content: message,
405
423
  artifacts: (final.artifacts ?? []).map(this._toArtifactRef),
424
+ webuiContinuation,
425
+ };
426
+ }
427
+
428
+ /**
429
+ * 从终态响应里抽取 WebUI continuation(camelCase / snake_case 双归一)。
430
+ * 缺必要字段(id / launch_url)时返回 undefined,调用方按 falsy 处理即可。
431
+ */
432
+ private _toWebuiContinuation(final: GetInvocationResponse): WebuiContinuationRef | undefined {
433
+ const visible: VisibleResultResponse | undefined =
434
+ final.visibleResult ?? final.visible_result;
435
+ const raw = visible?.webuiContinuation ?? visible?.webui_continuation;
436
+ if (!raw) return undefined;
437
+
438
+ const id = raw.continuationId ?? raw.continuation_id;
439
+ const launchUrl = raw.launchUrl ?? raw.launch_url;
440
+ if (!id || !launchUrl) return undefined;
441
+
442
+ return {
443
+ id,
444
+ launchUrl,
445
+ displayName: raw.displayName ?? raw.display_name ?? 'Open WebUI',
446
+ visibleState: raw.visibleState ?? raw.visible_state ?? 'available',
447
+ sessionId: raw.sessionId ?? raw.session_id,
406
448
  };
407
449
  }
408
450
 
@@ -3,8 +3,6 @@ import type {
3
3
  AgentStatusResult,
4
4
  CategoryNode,
5
5
  CategoryTree,
6
- ClaimResult,
7
- RegisterResult,
8
6
  SearchResult,
9
7
  } from '../types.js';
10
8
  import type {
@@ -12,8 +10,6 @@ import type {
12
10
  AgentStatusResponse,
13
11
  CategoryNodeResponse,
14
12
  CategoryTreeResponse,
15
- ClaimAgentResponse,
16
- RegisterAgentResponse,
17
13
  SearchResponse,
18
14
  } from './oasn-types.js';
19
15
 
@@ -96,28 +92,6 @@ export function normalizeAgentCard(resp: AgentCardResponse | unknown): AgentCard
96
92
  };
97
93
  }
98
94
 
99
- export function normalizeRegisterResult(resp: RegisterAgentResponse | unknown): RegisterResult {
100
- const record = asRecord(resp);
101
- return {
102
- agent_id: pickString(record, 'agentId', 'agent_id'),
103
- agent_type: (pickString(record, 'agentType', 'agent_type') || 'client') as 'client',
104
- api_key: pickString(record, 'apiKey', 'api_key'),
105
- claim_url: pickString(record, 'claimUrl', 'claim_url'),
106
- status: (pickString(record, 'status') || 'unclaimed') as 'unclaimed',
107
- agent_card: normalizeAgentCard(pickRecord(record, 'agentCard', 'agent_card')),
108
- };
109
- }
110
-
111
- export function normalizeClaimResult(resp: ClaimAgentResponse | unknown): ClaimResult {
112
- const record = asRecord(resp);
113
- return {
114
- agent_id: pickString(record, 'agentId', 'agent_id'),
115
- status: (pickString(record, 'status') || 'claim_email_sent') as 'claim_email_sent',
116
- owner_email_masked: pickString(record, 'ownerEmailMasked', 'owner_email_masked'),
117
- expires_at: pickString(record, 'expiresAt', 'expires_at'),
118
- };
119
- }
120
-
121
95
  export function normalizeAgentStatus(resp: AgentStatusResponse | unknown): AgentStatusResult {
122
96
  const record = asRecord(resp);
123
97
  return {
@@ -1,101 +1,28 @@
1
1
  /**
2
- * OASN Agent 注册与认领
2
+ * OASN Agent 状态查询
3
3
  *
4
4
  * 设计依据:
5
- * - docs/specs/2026-06-16-oasn-api-module-mapping.md §2.1 / §2.2
5
+ * - docs/specs/2026-06-16-oasn-api-module-mapping.md §2.3
6
6
  *
7
- * 调用时机:
8
- * - registerAgent:插件首次安装、本地无 agent_id/api_key 时
9
- * - claimAgent:用户主动触发认领(带 owner_email)
10
- *
11
- * 关键约束:
12
- * - register 返回的 api_key **是明文且仅此一次**。调用方必须立即持久化(最好走 keychain,§11.6)
13
- * - 当前后端 RegisterAgentCommand 只定义 platform;install_id/device_hint 需先扩展后端契约
7
+ * 注意:register 和 claim 已迁移到 CLI(openclaw-plugin-openagent-cli),
8
+ * 本模块仅保留 getStatus(GET /api/agents/{agent_id})。
14
9
  */
15
10
 
16
11
  import { logger } from '../../util/logger.js';
17
- import type { AgentStatusResult, ClaimParams, ClaimResult, RegisterResult } from '../types.js';
12
+ import type { AgentStatusResult } from '../types.js';
18
13
  import type { OasnHttpClient } from './oasn-http.js';
19
14
  import {
20
15
  OASN_ENDPOINTS,
21
- type ClaimAgentRequest,
22
- type ClaimAgentResponse,
23
16
  type AgentStatusResponse,
24
- type RegisterAgentRequest,
25
- type RegisterAgentResponse,
26
17
  } from './oasn-types.js';
27
- import {
28
- normalizeAgentStatus,
29
- normalizeClaimResult,
30
- normalizeRegisterResult,
31
- } from './oasn-normalize.js';
18
+ import { normalizeAgentStatus } from './oasn-normalize.js';
32
19
 
33
20
  /**
34
- * OASN Agent 注册模块。
35
- *
36
- * 注意 register 和 claim 是 OASN-only 能力,TIM transport 不暴露这两个方法。
37
- * AccountRuntime 在 transport-type === 'oasn' 时才能调用。
21
+ * OASN Agent 状态查询模块。
38
22
  */
39
- export class OasnRegister {
23
+ export class OasnAgentStatus {
40
24
  constructor(private readonly _http: OasnHttpClient) {}
41
25
 
42
- /**
43
- * 注册新 Agent(首次安装流程)。
44
- *
45
- * @param platform OpenClaw 上固定为 "openclaw"
46
- * @returns 含一次性明文 api_key 的注册响应。调用方必须立即持久化。
47
- */
48
- async register(
49
- platform: string,
50
- _params?: { installId?: string; deviceHint?: string },
51
- ): Promise<RegisterResult> {
52
- const body: RegisterAgentRequest = { platform };
53
-
54
- logger.info(`[transport/oasn/register] register platform=${platform}`);
55
-
56
- // skipRetry=true:register 是不幂等的写入,重试可能创建多个 agent
57
- const resp = await this._http.post<RegisterAgentResponse>(
58
- OASN_ENDPOINTS.REGISTER,
59
- body,
60
- { skipRetry: true },
61
- );
62
-
63
- const result = normalizeRegisterResult(resp);
64
- logger.info(`[transport/oasn/register] registered agent_id=${result.agent_id} status=${result.status}`);
65
- return result;
66
- }
67
-
68
- /**
69
- * 触发认领邮件发送。
70
- * 认证方式由 OasnHttpClient 注入的 Bearer 决定:
71
- * - 带 api_key:传入 { agent_id, owner_email }
72
- * - 不带 api_key(首次进入):传入 { claim_token, owner_email }
73
- */
74
- async claim(params: ClaimParams): Promise<ClaimResult> {
75
- if (!params.agent_id && !params.claim_token) {
76
- throw new Error('OasnRegister.claim: must provide either agent_id or claim_token');
77
- }
78
- if (!params.owner_email) {
79
- throw new Error('OasnRegister.claim: owner_email required');
80
- }
81
-
82
- const body: ClaimAgentRequest = {
83
- ownerEmail: params.owner_email,
84
- };
85
- if (params.agent_id) body.agentId = params.agent_id;
86
- if (params.claim_token) body.claimToken = params.claim_token;
87
-
88
- logger.info(`[transport/oasn/register] claim email=${params.owner_email.replace(/(.).+(@.+)/, '$1***$2')}`);
89
-
90
- const resp = await this._http.post<ClaimAgentResponse>(
91
- OASN_ENDPOINTS.CLAIM,
92
- body,
93
- { skipRetry: true },
94
- );
95
-
96
- return normalizeClaimResult(resp);
97
- }
98
-
99
26
  async getStatus(agentId: string): Promise<AgentStatusResult> {
100
27
  const resp = await this._http.get<AgentStatusResponse>(
101
28
  OASN_ENDPOINTS.AGENT_STATUS(agentId),