@xyagent/cli 0.0.1

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 (385) hide show
  1. package/README.md +860 -0
  2. package/bin/agentlink +8585 -0
  3. package/bin/agentlink-agent +7 -0
  4. package/bin/agentlink-mcp-stdio +173 -0
  5. package/docs/LOGGING.md +159 -0
  6. package/package.json +38 -0
  7. package/src/core.mjs +320 -0
  8. package/src/tunnel.mjs +291 -0
  9. package/src/tunnel_proxy.mjs +913 -0
  10. package/src/tunnel_service.mjs +699 -0
  11. package/src/tunnel_state.mjs +301 -0
  12. package/src/unified_producer.mjs +259 -0
  13. package/src-ext/README.md +75 -0
  14. package/src-ext/bin.mjs +128 -0
  15. package/src-ext/commands/agent.mjs +66 -0
  16. package/src-ext/commands/help.mjs +31 -0
  17. package/src-ext/commands/pair.mjs +455 -0
  18. package/src-ext/commands/reload.mjs +78 -0
  19. package/src-ext/commands/service.mjs +64 -0
  20. package/src-ext/core/accountResolver.mjs +137 -0
  21. package/src-ext/core/activeRuns.mjs +76 -0
  22. package/src-ext/core/agentlinkToolsBootstrap.mjs +75 -0
  23. package/src-ext/core/agentlinkToolsRegistry.mjs +323 -0
  24. package/src-ext/core/agentlinkToolsServer.mjs +109 -0
  25. package/src-ext/core/approvalGateway.mjs +132 -0
  26. package/src-ext/core/attachAuditLog.mjs +79 -0
  27. package/src-ext/core/attachDenylist.mjs +128 -0
  28. package/src-ext/core/autoTunnelDetector.mjs +98 -0
  29. package/src-ext/core/autoTunnelGateway.mjs +393 -0
  30. package/src-ext/core/autoTunnelWiring.mjs +184 -0
  31. package/src-ext/core/boundedMap.mjs +98 -0
  32. package/src-ext/core/bridgeAttachAutoScanner.mjs +237 -0
  33. package/src-ext/core/bridgeHooks.mjs +168 -0
  34. package/src-ext/core/bridgeSelfUninstall.mjs +133 -0
  35. package/src-ext/core/claudeTrust.mjs +74 -0
  36. package/src-ext/core/codexTrust.mjs +77 -0
  37. package/src-ext/core/cosUploadClient.mjs +326 -0
  38. package/src-ext/core/createWorkspace.mjs +170 -0
  39. package/src-ext/core/daemonRestart.mjs +49 -0
  40. package/src-ext/core/defaultWorkspace.mjs +65 -0
  41. package/src-ext/core/ensureGitRepo.mjs +57 -0
  42. package/src-ext/core/hermesProfile.mjs +75 -0
  43. package/src-ext/core/interruptGateway.mjs +119 -0
  44. package/src-ext/core/interruptRunListener.mjs +106 -0
  45. package/src-ext/core/mcpRuntimeFanout.mjs +236 -0
  46. package/src-ext/core/mcpStdioClient.mjs +316 -0
  47. package/src-ext/core/openclawGatewayClient.mjs +230 -0
  48. package/src-ext/core/pairCodeClient.mjs +331 -0
  49. package/src-ext/core/pairInventory.mjs +59 -0
  50. package/src-ext/core/pathExpand.mjs +34 -0
  51. package/src-ext/core/preprocessAttachments.mjs +113 -0
  52. package/src-ext/core/relayWorker.mjs +284 -0
  53. package/src-ext/core/relayWorkerHttp.mjs +58 -0
  54. package/src-ext/core/scanWorkspaces.mjs +842 -0
  55. package/src-ext/core/sessionSlot.mjs +70 -0
  56. package/src-ext/core/stateMachine.mjs +85 -0
  57. package/src-ext/core/toolsServerLifecycle.mjs +169 -0
  58. package/src-ext/core/unifiedDispatchHandler.mjs +439 -0
  59. package/src-ext/core/usageReporter.mjs +207 -0
  60. package/src-ext/openclaw-plugin/envelope-builder.cjs +619 -0
  61. package/src-ext/openclaw-plugin/index.cjs +1919 -0
  62. package/src-ext/openclaw-plugin/openclaw.plugin.json +20 -0
  63. package/src-ext/openclaw-plugin/package.json +12 -0
  64. package/src-ext/openclaw-plugin/relay-defaults.json +3 -0
  65. package/src-ext/openclaw-plugin/todoTranslatorUtils.cjs +101 -0
  66. package/src-ext/runtime/_shared/cliExec.mjs +138 -0
  67. package/src-ext/runtime/_shared/cosTextRefs.mjs +120 -0
  68. package/src-ext/runtime/_shared/fetchAndBase64Encode.mjs +52 -0
  69. package/src-ext/runtime/_shared/relayObjectToBlock.mjs +307 -0
  70. package/src-ext/runtime/_shared/sessionPicker.mjs +418 -0
  71. package/src-ext/runtime/_shared/slashCommandRouter.mjs +1346 -0
  72. package/src-ext/runtime/_shared/todoTranslatorUtils.mjs +94 -0
  73. package/src-ext/runtime/claude/askUserQuestionTranslator.mjs +241 -0
  74. package/src-ext/runtime/claude/customCommandsCollector.mjs +132 -0
  75. package/src-ext/runtime/claude/handleRequest.mjs +1418 -0
  76. package/src-ext/runtime/claude/index.mjs +160 -0
  77. package/src-ext/runtime/claude/internalCommandNames.mjs +58 -0
  78. package/src-ext/runtime/claude/launcher.mjs +313 -0
  79. package/src-ext/runtime/claude/mcpConfigAdapter.mjs +174 -0
  80. package/src-ext/runtime/claude/mcpConfigWriter.mjs +57 -0
  81. package/src-ext/runtime/claude/modelContextWindow.mjs +30 -0
  82. package/src-ext/runtime/claude/modelScanner.mjs +257 -0
  83. package/src-ext/runtime/claude/permissionInterruptBlock.mjs +86 -0
  84. package/src-ext/runtime/claude/permissionPromptServer.mjs +170 -0
  85. package/src-ext/runtime/claude/permissionPromptServerWorker.mjs +214 -0
  86. package/src-ext/runtime/claude/preflight.mjs +62 -0
  87. package/src-ext/runtime/claude/stdoutParser.mjs +365 -0
  88. package/src-ext/runtime/claude/todoTranslator.mjs +66 -0
  89. package/src-ext/runtime/claude/usageProbe.mjs +576 -0
  90. package/src-ext/runtime/claude/usageProbeStrip.mjs +14 -0
  91. package/src-ext/runtime/codex/codexCustomCommandsCollector.mjs +87 -0
  92. package/src-ext/runtime/codex/elicitationHandler.mjs +91 -0
  93. package/src-ext/runtime/codex/eventMapper.mjs +154 -0
  94. package/src-ext/runtime/codex/handleRequest.mjs +1152 -0
  95. package/src-ext/runtime/codex/index.mjs +142 -0
  96. package/src-ext/runtime/codex/mcpConfigAdapter.mjs +155 -0
  97. package/src-ext/runtime/codex/modelScanner.mjs +305 -0
  98. package/src-ext/runtime/codex/planNotificationHandler.mjs +61 -0
  99. package/src-ext/runtime/codex/preflight.mjs +67 -0
  100. package/src-ext/runtime/hermes/commandBackend.mjs +117 -0
  101. package/src-ext/runtime/hermes/envSetup.mjs +229 -0
  102. package/src-ext/runtime/hermes/gatewayManager.mjs +625 -0
  103. package/src-ext/runtime/hermes/handleRequest.mjs +1257 -0
  104. package/src-ext/runtime/hermes/httpBackend.mjs +219 -0
  105. package/src-ext/runtime/hermes/index.mjs +196 -0
  106. package/src-ext/runtime/hermes/mcpConfigAdapter.mjs +189 -0
  107. package/src-ext/runtime/hermes/preflight.mjs +359 -0
  108. package/src-ext/runtime/hermes/responsesBackend.mjs +276 -0
  109. package/src-ext/runtime/hermes/sessionStore.mjs +78 -0
  110. package/src-ext/runtime/hermes/todoTranslator.mjs +90 -0
  111. package/src-ext/runtime/hermes/workspaceRpc.mjs +124 -0
  112. package/src-ext/runtime/openclaw/buildOpenclawDaemonInput.mjs +143 -0
  113. package/src-ext/runtime/openclaw/mcpConfigAdapter.mjs +91 -0
  114. package/src-ext/runtime/openclaw/openclawConfig.mjs +145 -0
  115. package/src-ext/runtime/picoclaw/constants.mjs +39 -0
  116. package/src-ext/runtime/picoclaw/handleRequest.mjs +289 -0
  117. package/src-ext/runtime/picoclaw/index.mjs +314 -0
  118. package/src-ext/runtime/picoclaw/pairFlow.mjs +224 -0
  119. package/src-ext/runtime/picoclaw/state.mjs +78 -0
  120. package/src-ext/runtime/picoclaw/todoTranslator.mjs +67 -0
  121. package/src-ext/runtime/picoclaw/translator.mjs +272 -0
  122. package/src-ext/runtime/picoclaw/wsClient.mjs +129 -0
  123. package/src-ext/service/serviceManager.mjs +521 -0
  124. package/src-shared/README.md +44 -0
  125. package/src-shared/chat_push_normalizer.mjs +113 -0
  126. package/src-shared/correlation.mjs +25 -0
  127. package/src-shared/envelope_builder.mjs +612 -0
  128. package/src-shared/logger.mjs +167 -0
  129. package/src-shared/relay-defaults.json +3 -0
  130. package/src-shared/relay_revoke.mjs +46 -0
  131. package/src-shared/vendor/README.md +60 -0
  132. package/src-shared/vendor/smol-toml/LICENSE +24 -0
  133. package/src-shared/vendor/smol-toml/README.md +236 -0
  134. package/src-shared/vendor/smol-toml/VENDORED.md +37 -0
  135. package/src-shared/vendor/smol-toml/dist/date.d.ts +41 -0
  136. package/src-shared/vendor/smol-toml/dist/date.js +127 -0
  137. package/src-shared/vendor/smol-toml/dist/error.d.ts +38 -0
  138. package/src-shared/vendor/smol-toml/dist/error.js +63 -0
  139. package/src-shared/vendor/smol-toml/dist/extract.d.ts +30 -0
  140. package/src-shared/vendor/smol-toml/dist/extract.js +109 -0
  141. package/src-shared/vendor/smol-toml/dist/index.cjs +900 -0
  142. package/src-shared/vendor/smol-toml/dist/index.d.ts +43 -0
  143. package/src-shared/vendor/smol-toml/dist/index.js +33 -0
  144. package/src-shared/vendor/smol-toml/dist/parse.d.ts +37 -0
  145. package/src-shared/vendor/smol-toml/dist/parse.js +148 -0
  146. package/src-shared/vendor/smol-toml/dist/primitive.d.ts +31 -0
  147. package/src-shared/vendor/smol-toml/dist/primitive.js +178 -0
  148. package/src-shared/vendor/smol-toml/dist/stringify.d.ts +31 -0
  149. package/src-shared/vendor/smol-toml/dist/stringify.js +163 -0
  150. package/src-shared/vendor/smol-toml/dist/struct.d.ts +32 -0
  151. package/src-shared/vendor/smol-toml/dist/struct.js +194 -0
  152. package/src-shared/vendor/smol-toml/dist/util.d.ts +42 -0
  153. package/src-shared/vendor/smol-toml/dist/util.js +100 -0
  154. package/src-shared/vendor/smol-toml/package.json +54 -0
  155. package/src-shared/vendor/yaml/LICENSE +13 -0
  156. package/src-shared/vendor/yaml/README.md +155 -0
  157. package/src-shared/vendor/yaml/VENDORED.md +29 -0
  158. package/src-shared/vendor/yaml/bin.mjs +11 -0
  159. package/src-shared/vendor/yaml/browser/dist/compose/compose-collection.js +88 -0
  160. package/src-shared/vendor/yaml/browser/dist/compose/compose-doc.js +42 -0
  161. package/src-shared/vendor/yaml/browser/dist/compose/compose-node.js +92 -0
  162. package/src-shared/vendor/yaml/browser/dist/compose/compose-scalar.js +80 -0
  163. package/src-shared/vendor/yaml/browser/dist/compose/composer.js +217 -0
  164. package/src-shared/vendor/yaml/browser/dist/compose/resolve-block-map.js +113 -0
  165. package/src-shared/vendor/yaml/browser/dist/compose/resolve-block-scalar.js +198 -0
  166. package/src-shared/vendor/yaml/browser/dist/compose/resolve-block-seq.js +47 -0
  167. package/src-shared/vendor/yaml/browser/dist/compose/resolve-end.js +37 -0
  168. package/src-shared/vendor/yaml/browser/dist/compose/resolve-flow-collection.js +203 -0
  169. package/src-shared/vendor/yaml/browser/dist/compose/resolve-flow-scalar.js +223 -0
  170. package/src-shared/vendor/yaml/browser/dist/compose/resolve-props.js +148 -0
  171. package/src-shared/vendor/yaml/browser/dist/compose/util-contains-newline.js +34 -0
  172. package/src-shared/vendor/yaml/browser/dist/compose/util-empty-scalar-position.js +27 -0
  173. package/src-shared/vendor/yaml/browser/dist/compose/util-flow-indent-check.js +15 -0
  174. package/src-shared/vendor/yaml/browser/dist/compose/util-map-includes.js +17 -0
  175. package/src-shared/vendor/yaml/browser/dist/doc/Document.js +334 -0
  176. package/src-shared/vendor/yaml/browser/dist/doc/anchors.js +72 -0
  177. package/src-shared/vendor/yaml/browser/dist/doc/applyReviver.js +55 -0
  178. package/src-shared/vendor/yaml/browser/dist/doc/createNode.js +89 -0
  179. package/src-shared/vendor/yaml/browser/dist/doc/directives.js +176 -0
  180. package/src-shared/vendor/yaml/browser/dist/errors.js +57 -0
  181. package/src-shared/vendor/yaml/browser/dist/index.js +17 -0
  182. package/src-shared/vendor/yaml/browser/dist/log.js +14 -0
  183. package/src-shared/vendor/yaml/browser/dist/nodes/Alias.js +101 -0
  184. package/src-shared/vendor/yaml/browser/dist/nodes/Collection.js +147 -0
  185. package/src-shared/vendor/yaml/browser/dist/nodes/Node.js +38 -0
  186. package/src-shared/vendor/yaml/browser/dist/nodes/Pair.js +36 -0
  187. package/src-shared/vendor/yaml/browser/dist/nodes/Scalar.js +24 -0
  188. package/src-shared/vendor/yaml/browser/dist/nodes/YAMLMap.js +144 -0
  189. package/src-shared/vendor/yaml/browser/dist/nodes/YAMLSeq.js +113 -0
  190. package/src-shared/vendor/yaml/browser/dist/nodes/addPairToJSMap.js +104 -0
  191. package/src-shared/vendor/yaml/browser/dist/nodes/identity.js +36 -0
  192. package/src-shared/vendor/yaml/browser/dist/nodes/toJS.js +37 -0
  193. package/src-shared/vendor/yaml/browser/dist/parse/cst-scalar.js +214 -0
  194. package/src-shared/vendor/yaml/browser/dist/parse/cst-stringify.js +61 -0
  195. package/src-shared/vendor/yaml/browser/dist/parse/cst-visit.js +97 -0
  196. package/src-shared/vendor/yaml/browser/dist/parse/cst.js +98 -0
  197. package/src-shared/vendor/yaml/browser/dist/parse/lexer.js +717 -0
  198. package/src-shared/vendor/yaml/browser/dist/parse/line-counter.js +39 -0
  199. package/src-shared/vendor/yaml/browser/dist/parse/parser.js +954 -0
  200. package/src-shared/vendor/yaml/browser/dist/public-api.js +99 -0
  201. package/src-shared/vendor/yaml/browser/dist/schema/Schema.js +38 -0
  202. package/src-shared/vendor/yaml/browser/dist/schema/common/map.js +17 -0
  203. package/src-shared/vendor/yaml/browser/dist/schema/common/null.js +15 -0
  204. package/src-shared/vendor/yaml/browser/dist/schema/common/seq.js +17 -0
  205. package/src-shared/vendor/yaml/browser/dist/schema/common/string.js +14 -0
  206. package/src-shared/vendor/yaml/browser/dist/schema/core/bool.js +19 -0
  207. package/src-shared/vendor/yaml/browser/dist/schema/core/float.js +43 -0
  208. package/src-shared/vendor/yaml/browser/dist/schema/core/int.js +38 -0
  209. package/src-shared/vendor/yaml/browser/dist/schema/core/schema.js +23 -0
  210. package/src-shared/vendor/yaml/browser/dist/schema/json/schema.js +62 -0
  211. package/src-shared/vendor/yaml/browser/dist/schema/tags.js +83 -0
  212. package/src-shared/vendor/yaml/browser/dist/schema/yaml-1.1/binary.js +66 -0
  213. package/src-shared/vendor/yaml/browser/dist/schema/yaml-1.1/bool.js +26 -0
  214. package/src-shared/vendor/yaml/browser/dist/schema/yaml-1.1/float.js +46 -0
  215. package/src-shared/vendor/yaml/browser/dist/schema/yaml-1.1/int.js +71 -0
  216. package/src-shared/vendor/yaml/browser/dist/schema/yaml-1.1/omap.js +74 -0
  217. package/src-shared/vendor/yaml/browser/dist/schema/yaml-1.1/pairs.js +78 -0
  218. package/src-shared/vendor/yaml/browser/dist/schema/yaml-1.1/schema.js +37 -0
  219. package/src-shared/vendor/yaml/browser/dist/schema/yaml-1.1/set.js +93 -0
  220. package/src-shared/vendor/yaml/browser/dist/schema/yaml-1.1/timestamp.js +101 -0
  221. package/src-shared/vendor/yaml/browser/dist/stringify/foldFlowLines.js +146 -0
  222. package/src-shared/vendor/yaml/browser/dist/stringify/stringify.js +124 -0
  223. package/src-shared/vendor/yaml/browser/dist/stringify/stringifyCollection.js +143 -0
  224. package/src-shared/vendor/yaml/browser/dist/stringify/stringifyComment.js +20 -0
  225. package/src-shared/vendor/yaml/browser/dist/stringify/stringifyDocument.js +85 -0
  226. package/src-shared/vendor/yaml/browser/dist/stringify/stringifyNumber.js +24 -0
  227. package/src-shared/vendor/yaml/browser/dist/stringify/stringifyPair.js +150 -0
  228. package/src-shared/vendor/yaml/browser/dist/stringify/stringifyString.js +328 -0
  229. package/src-shared/vendor/yaml/browser/dist/util.js +11 -0
  230. package/src-shared/vendor/yaml/browser/dist/visit.js +233 -0
  231. package/src-shared/vendor/yaml/browser/index.js +5 -0
  232. package/src-shared/vendor/yaml/browser/package.json +3 -0
  233. package/src-shared/vendor/yaml/dist/cli.d.ts +8 -0
  234. package/src-shared/vendor/yaml/dist/cli.mjs +199 -0
  235. package/src-shared/vendor/yaml/dist/compose/compose-collection.d.ts +11 -0
  236. package/src-shared/vendor/yaml/dist/compose/compose-collection.js +90 -0
  237. package/src-shared/vendor/yaml/dist/compose/compose-doc.d.ts +7 -0
  238. package/src-shared/vendor/yaml/dist/compose/compose-doc.js +44 -0
  239. package/src-shared/vendor/yaml/dist/compose/compose-node.d.ts +28 -0
  240. package/src-shared/vendor/yaml/dist/compose/compose-node.js +95 -0
  241. package/src-shared/vendor/yaml/dist/compose/compose-scalar.d.ts +5 -0
  242. package/src-shared/vendor/yaml/dist/compose/compose-scalar.js +82 -0
  243. package/src-shared/vendor/yaml/dist/compose/composer.d.ts +62 -0
  244. package/src-shared/vendor/yaml/dist/compose/composer.js +221 -0
  245. package/src-shared/vendor/yaml/dist/compose/resolve-block-map.d.ts +6 -0
  246. package/src-shared/vendor/yaml/dist/compose/resolve-block-map.js +115 -0
  247. package/src-shared/vendor/yaml/dist/compose/resolve-block-scalar.d.ts +11 -0
  248. package/src-shared/vendor/yaml/dist/compose/resolve-block-scalar.js +200 -0
  249. package/src-shared/vendor/yaml/dist/compose/resolve-block-seq.d.ts +6 -0
  250. package/src-shared/vendor/yaml/dist/compose/resolve-block-seq.js +49 -0
  251. package/src-shared/vendor/yaml/dist/compose/resolve-end.d.ts +6 -0
  252. package/src-shared/vendor/yaml/dist/compose/resolve-end.js +39 -0
  253. package/src-shared/vendor/yaml/dist/compose/resolve-flow-collection.d.ts +7 -0
  254. package/src-shared/vendor/yaml/dist/compose/resolve-flow-collection.js +205 -0
  255. package/src-shared/vendor/yaml/dist/compose/resolve-flow-scalar.d.ts +10 -0
  256. package/src-shared/vendor/yaml/dist/compose/resolve-flow-scalar.js +225 -0
  257. package/src-shared/vendor/yaml/dist/compose/resolve-props.d.ts +23 -0
  258. package/src-shared/vendor/yaml/dist/compose/resolve-props.js +150 -0
  259. package/src-shared/vendor/yaml/dist/compose/util-contains-newline.d.ts +2 -0
  260. package/src-shared/vendor/yaml/dist/compose/util-contains-newline.js +36 -0
  261. package/src-shared/vendor/yaml/dist/compose/util-empty-scalar-position.d.ts +2 -0
  262. package/src-shared/vendor/yaml/dist/compose/util-empty-scalar-position.js +29 -0
  263. package/src-shared/vendor/yaml/dist/compose/util-flow-indent-check.d.ts +3 -0
  264. package/src-shared/vendor/yaml/dist/compose/util-flow-indent-check.js +17 -0
  265. package/src-shared/vendor/yaml/dist/compose/util-map-includes.d.ts +4 -0
  266. package/src-shared/vendor/yaml/dist/compose/util-map-includes.js +19 -0
  267. package/src-shared/vendor/yaml/dist/doc/Document.d.ts +141 -0
  268. package/src-shared/vendor/yaml/dist/doc/Document.js +336 -0
  269. package/src-shared/vendor/yaml/dist/doc/anchors.d.ts +24 -0
  270. package/src-shared/vendor/yaml/dist/doc/anchors.js +77 -0
  271. package/src-shared/vendor/yaml/dist/doc/applyReviver.d.ts +9 -0
  272. package/src-shared/vendor/yaml/dist/doc/applyReviver.js +57 -0
  273. package/src-shared/vendor/yaml/dist/doc/createNode.d.ts +17 -0
  274. package/src-shared/vendor/yaml/dist/doc/createNode.js +91 -0
  275. package/src-shared/vendor/yaml/dist/doc/directives.d.ts +49 -0
  276. package/src-shared/vendor/yaml/dist/doc/directives.js +178 -0
  277. package/src-shared/vendor/yaml/dist/errors.d.ts +21 -0
  278. package/src-shared/vendor/yaml/dist/errors.js +62 -0
  279. package/src-shared/vendor/yaml/dist/index.d.ts +22 -0
  280. package/src-shared/vendor/yaml/dist/index.js +50 -0
  281. package/src-shared/vendor/yaml/dist/log.d.ts +3 -0
  282. package/src-shared/vendor/yaml/dist/log.js +17 -0
  283. package/src-shared/vendor/yaml/dist/nodes/Alias.d.ts +28 -0
  284. package/src-shared/vendor/yaml/dist/nodes/Alias.js +103 -0
  285. package/src-shared/vendor/yaml/dist/nodes/Collection.d.ts +73 -0
  286. package/src-shared/vendor/yaml/dist/nodes/Collection.js +151 -0
  287. package/src-shared/vendor/yaml/dist/nodes/Node.d.ts +47 -0
  288. package/src-shared/vendor/yaml/dist/nodes/Node.js +40 -0
  289. package/src-shared/vendor/yaml/dist/nodes/Pair.d.ts +21 -0
  290. package/src-shared/vendor/yaml/dist/nodes/Pair.js +39 -0
  291. package/src-shared/vendor/yaml/dist/nodes/Scalar.d.ts +42 -0
  292. package/src-shared/vendor/yaml/dist/nodes/Scalar.js +27 -0
  293. package/src-shared/vendor/yaml/dist/nodes/YAMLMap.d.ts +53 -0
  294. package/src-shared/vendor/yaml/dist/nodes/YAMLMap.js +147 -0
  295. package/src-shared/vendor/yaml/dist/nodes/YAMLSeq.d.ts +60 -0
  296. package/src-shared/vendor/yaml/dist/nodes/YAMLSeq.js +115 -0
  297. package/src-shared/vendor/yaml/dist/nodes/addPairToJSMap.d.ts +4 -0
  298. package/src-shared/vendor/yaml/dist/nodes/addPairToJSMap.js +106 -0
  299. package/src-shared/vendor/yaml/dist/nodes/identity.d.ts +23 -0
  300. package/src-shared/vendor/yaml/dist/nodes/identity.js +53 -0
  301. package/src-shared/vendor/yaml/dist/nodes/toJS.d.ts +27 -0
  302. package/src-shared/vendor/yaml/dist/nodes/toJS.js +39 -0
  303. package/src-shared/vendor/yaml/dist/options.d.ts +338 -0
  304. package/src-shared/vendor/yaml/dist/parse/cst-scalar.d.ts +64 -0
  305. package/src-shared/vendor/yaml/dist/parse/cst-scalar.js +218 -0
  306. package/src-shared/vendor/yaml/dist/parse/cst-stringify.d.ts +8 -0
  307. package/src-shared/vendor/yaml/dist/parse/cst-stringify.js +63 -0
  308. package/src-shared/vendor/yaml/dist/parse/cst-visit.d.ts +39 -0
  309. package/src-shared/vendor/yaml/dist/parse/cst-visit.js +99 -0
  310. package/src-shared/vendor/yaml/dist/parse/cst.d.ts +108 -0
  311. package/src-shared/vendor/yaml/dist/parse/cst.js +112 -0
  312. package/src-shared/vendor/yaml/dist/parse/lexer.d.ts +87 -0
  313. package/src-shared/vendor/yaml/dist/parse/lexer.js +719 -0
  314. package/src-shared/vendor/yaml/dist/parse/line-counter.d.ts +22 -0
  315. package/src-shared/vendor/yaml/dist/parse/line-counter.js +41 -0
  316. package/src-shared/vendor/yaml/dist/parse/parser.d.ts +84 -0
  317. package/src-shared/vendor/yaml/dist/parse/parser.js +958 -0
  318. package/src-shared/vendor/yaml/dist/public-api.d.ts +43 -0
  319. package/src-shared/vendor/yaml/dist/public-api.js +104 -0
  320. package/src-shared/vendor/yaml/dist/schema/Schema.d.ts +18 -0
  321. package/src-shared/vendor/yaml/dist/schema/Schema.js +40 -0
  322. package/src-shared/vendor/yaml/dist/schema/common/map.d.ts +2 -0
  323. package/src-shared/vendor/yaml/dist/schema/common/map.js +19 -0
  324. package/src-shared/vendor/yaml/dist/schema/common/null.d.ts +4 -0
  325. package/src-shared/vendor/yaml/dist/schema/common/null.js +17 -0
  326. package/src-shared/vendor/yaml/dist/schema/common/seq.d.ts +2 -0
  327. package/src-shared/vendor/yaml/dist/schema/common/seq.js +19 -0
  328. package/src-shared/vendor/yaml/dist/schema/common/string.d.ts +2 -0
  329. package/src-shared/vendor/yaml/dist/schema/common/string.js +16 -0
  330. package/src-shared/vendor/yaml/dist/schema/core/bool.d.ts +4 -0
  331. package/src-shared/vendor/yaml/dist/schema/core/bool.js +21 -0
  332. package/src-shared/vendor/yaml/dist/schema/core/float.d.ts +4 -0
  333. package/src-shared/vendor/yaml/dist/schema/core/float.js +47 -0
  334. package/src-shared/vendor/yaml/dist/schema/core/int.d.ts +4 -0
  335. package/src-shared/vendor/yaml/dist/schema/core/int.js +42 -0
  336. package/src-shared/vendor/yaml/dist/schema/core/schema.d.ts +1 -0
  337. package/src-shared/vendor/yaml/dist/schema/core/schema.js +25 -0
  338. package/src-shared/vendor/yaml/dist/schema/json/schema.d.ts +2 -0
  339. package/src-shared/vendor/yaml/dist/schema/json/schema.js +64 -0
  340. package/src-shared/vendor/yaml/dist/schema/json-schema.d.ts +69 -0
  341. package/src-shared/vendor/yaml/dist/schema/tags.d.ts +40 -0
  342. package/src-shared/vendor/yaml/dist/schema/tags.js +86 -0
  343. package/src-shared/vendor/yaml/dist/schema/types.d.ts +90 -0
  344. package/src-shared/vendor/yaml/dist/schema/yaml-1.1/binary.d.ts +2 -0
  345. package/src-shared/vendor/yaml/dist/schema/yaml-1.1/binary.js +68 -0
  346. package/src-shared/vendor/yaml/dist/schema/yaml-1.1/bool.d.ts +7 -0
  347. package/src-shared/vendor/yaml/dist/schema/yaml-1.1/bool.js +29 -0
  348. package/src-shared/vendor/yaml/dist/schema/yaml-1.1/float.d.ts +4 -0
  349. package/src-shared/vendor/yaml/dist/schema/yaml-1.1/float.js +50 -0
  350. package/src-shared/vendor/yaml/dist/schema/yaml-1.1/int.d.ts +5 -0
  351. package/src-shared/vendor/yaml/dist/schema/yaml-1.1/int.js +76 -0
  352. package/src-shared/vendor/yaml/dist/schema/yaml-1.1/omap.d.ts +28 -0
  353. package/src-shared/vendor/yaml/dist/schema/yaml-1.1/omap.js +77 -0
  354. package/src-shared/vendor/yaml/dist/schema/yaml-1.1/pairs.d.ts +10 -0
  355. package/src-shared/vendor/yaml/dist/schema/yaml-1.1/pairs.js +82 -0
  356. package/src-shared/vendor/yaml/dist/schema/yaml-1.1/schema.d.ts +1 -0
  357. package/src-shared/vendor/yaml/dist/schema/yaml-1.1/schema.js +39 -0
  358. package/src-shared/vendor/yaml/dist/schema/yaml-1.1/set.d.ts +28 -0
  359. package/src-shared/vendor/yaml/dist/schema/yaml-1.1/set.js +96 -0
  360. package/src-shared/vendor/yaml/dist/schema/yaml-1.1/timestamp.d.ts +6 -0
  361. package/src-shared/vendor/yaml/dist/schema/yaml-1.1/timestamp.js +105 -0
  362. package/src-shared/vendor/yaml/dist/stringify/foldFlowLines.d.ts +34 -0
  363. package/src-shared/vendor/yaml/dist/stringify/foldFlowLines.js +151 -0
  364. package/src-shared/vendor/yaml/dist/stringify/stringify.d.ts +21 -0
  365. package/src-shared/vendor/yaml/dist/stringify/stringify.js +127 -0
  366. package/src-shared/vendor/yaml/dist/stringify/stringifyCollection.d.ts +17 -0
  367. package/src-shared/vendor/yaml/dist/stringify/stringifyCollection.js +145 -0
  368. package/src-shared/vendor/yaml/dist/stringify/stringifyComment.d.ts +10 -0
  369. package/src-shared/vendor/yaml/dist/stringify/stringifyComment.js +24 -0
  370. package/src-shared/vendor/yaml/dist/stringify/stringifyDocument.d.ts +4 -0
  371. package/src-shared/vendor/yaml/dist/stringify/stringifyDocument.js +87 -0
  372. package/src-shared/vendor/yaml/dist/stringify/stringifyNumber.d.ts +2 -0
  373. package/src-shared/vendor/yaml/dist/stringify/stringifyNumber.js +26 -0
  374. package/src-shared/vendor/yaml/dist/stringify/stringifyPair.d.ts +3 -0
  375. package/src-shared/vendor/yaml/dist/stringify/stringifyPair.js +152 -0
  376. package/src-shared/vendor/yaml/dist/stringify/stringifyString.d.ts +9 -0
  377. package/src-shared/vendor/yaml/dist/stringify/stringifyString.js +330 -0
  378. package/src-shared/vendor/yaml/dist/test-events.d.ts +4 -0
  379. package/src-shared/vendor/yaml/dist/test-events.js +134 -0
  380. package/src-shared/vendor/yaml/dist/util.d.ts +12 -0
  381. package/src-shared/vendor/yaml/dist/util.js +28 -0
  382. package/src-shared/vendor/yaml/dist/visit.d.ts +102 -0
  383. package/src-shared/vendor/yaml/dist/visit.js +236 -0
  384. package/src-shared/vendor/yaml/package.json +96 -0
  385. package/src-shared/vendor/yaml/util.js +2 -0
@@ -0,0 +1,113 @@
1
+ /**
2
+ * preprocessAttachments.mjs — bridge 侧 text-like mime attachment 预处理
3
+ *
4
+ * preprocessAttachmentsToText(blocks, { fetch, log })
5
+ * → Promise<block[]>
6
+ *
7
+ * 对 type="attachment" 且 mime 命中白名单(text-like)的 block:
8
+ * - fetch COS URL → UTF-8 解码 → 替换为 {type:"text", text:"[file: <name>]\n<content>\n"}
9
+ * - 超出 1,048,576 字符时截断 + 追加 "\n... [truncated, file too large]"
10
+ * - fetch 失败:替换为 {type:"text", text:"[file: <name>] (download failed: <error>)\n"}
11
+ *
12
+ * application/pdf:原样保留(各 runtime 自行翻译)
13
+ * 其他 mime attachment:替换为 {type:"text", text:"[file: <name>] (unsupported mime: <mime>)"}
14
+ * 非 attachment block(image、text 等):原样保留
15
+ *
16
+ * NOTE (Phase 5 — multimodal-attachment-llm-dispatch):
17
+ * relay_object blocks (source.kind="url" with attachment_kind field) は
18
+ * 各 runtime adapter で relayObjectToBlock (_shared/relayObjectToBlock.mjs) に
19
+ * よって処理される。このモジュール (preprocessAttachmentsToText) は、relay_object
20
+ * でない旧形式の type=attachment blocks(source.kind≠url、または attachment_kind
21
+ * フィールドなし)の後方互換処理として引き続き使用される。
22
+ * relay_object パスは relayObjectToBlock が接管済み。
23
+ *
24
+ * spec ref: openspec/changes/openclaw-multimodal-image-passthrough design.md D-attach-A
25
+ */
26
+
27
+ const TEXT_LIKE_MIMES = new Set([
28
+ "text/plain",
29
+ "text/markdown",
30
+ "text/csv",
31
+ "text/html",
32
+ "application/json",
33
+ ]);
34
+
35
+ const SIZE_CAP_CHARS = 1_048_576; // 1 MB
36
+
37
+ /**
38
+ * @param {any[]} blocks - 完整 input blocks 数组
39
+ * @param {{ fetch?: Function, log?: { info?, warn?, error? } }} opts
40
+ * @returns {Promise<any[]>} 处理后的 blocks 数组(新数组,原 blocks 不被修改)
41
+ */
42
+ export async function preprocessAttachmentsToText(blocks, { fetch: fetchFn, log } = {}) {
43
+ if (!Array.isArray(blocks) || blocks.length === 0) return [];
44
+
45
+ // 允许注入 fetch(测试 mock 用),默认用全局 fetch
46
+ const doFetch = fetchFn ?? globalThis.fetch;
47
+
48
+ const result = [];
49
+ for (const block of blocks) {
50
+ if (block?.type !== "attachment") {
51
+ result.push(block);
52
+ continue;
53
+ }
54
+
55
+ const name = block.name ?? "unknown";
56
+ const mime = block.mime ?? "";
57
+ const url = block.source?.url;
58
+
59
+ // PDF:原样保留,各 runtime 自行处理
60
+ if (mime === "application/pdf") {
61
+ result.push(block);
62
+ continue;
63
+ }
64
+
65
+ // 非 url source 的 attachment:原样保留(防御)
66
+ if (!url || block.source?.kind !== "url") {
67
+ result.push(block);
68
+ continue;
69
+ }
70
+
71
+ // 其他 mime(非 text-like 非 pdf):不支持,替换为占位
72
+ if (!TEXT_LIKE_MIMES.has(mime)) {
73
+ result.push({
74
+ type: "text",
75
+ text: `[file: ${name}] (unsupported mime: ${mime})`,
76
+ });
77
+ continue;
78
+ }
79
+
80
+ // text-like mime:fetch → 解码 → 替换为 text block
81
+ try {
82
+ const res = await doFetch(url);
83
+ if (!res.ok) {
84
+ throw new Error(`HTTP ${res.status} ${res.statusText}`);
85
+ }
86
+ let text = await res.text();
87
+
88
+ let truncated = false;
89
+ if (text.length > SIZE_CAP_CHARS) {
90
+ text = text.slice(0, SIZE_CAP_CHARS);
91
+ truncated = true;
92
+ }
93
+
94
+ const body = truncated
95
+ ? `[file: ${name}]\n${text}\n... [truncated, file too large]`
96
+ : `[file: ${name}]\n${text}\n`;
97
+
98
+ result.push({ type: "text", text: body });
99
+ } catch (err) {
100
+ const errMsg = err?.message ?? String(err);
101
+ log?.warn?.("preprocess.fetch_failed", `download failed for ${name}`, {
102
+ url,
103
+ err: errMsg,
104
+ });
105
+ result.push({
106
+ type: "text",
107
+ text: `[file: ${name}] (download failed: ${errMsg})\n`,
108
+ });
109
+ }
110
+ }
111
+
112
+ return result;
113
+ }
@@ -0,0 +1,284 @@
1
+ // relayWorker — bridge 端 long-poll 客户端,封装与服务端三个端点的所有通讯:
2
+ //
3
+ // GET /v1/gateways/<gw>/requests/next?waitSeconds=<N>
4
+ // POST /v1/gateways/<gw>/requests/<rid>/events
5
+ // POST /v1/gateways/<gw>/meta
6
+ //
7
+ // 任何 bridge(hermes / claude / codex)拿到 (relayUrl, gwId, bridgeToken) 后
8
+ // 用 createRelayWorker(...) 起一个 worker,然后 worker.run(handler) 进入主循环。
9
+ // 每条请求由 handler(request, ctx) 处理,ctx.publishEvent(event) 把 native 事件
10
+ // 推回服务端,服务端 adapter 自动翻译为 unified envelope 落库。
11
+ //
12
+ // 与旧的 unified_relay_shim 的本质差异:
13
+ // - 不再做"legacy kind → unified envelope"的客户端翻译;native event 直送
14
+ // - 不再走 SSE 订阅;用户消息只通过 long-poll 拉取
15
+ // - 心跳走 /meta(普通 PUT 接口),不再发 bridge.status envelope
16
+ // - publishEvent 是 fire-and-forget(失败 log 不抛),保证 handler 简洁
17
+ //
18
+ // 设计参考:src/tunnel_proxy.mjs 的 runHttpAgentLoop。
19
+
20
+ import { trimSlash } from "./relayWorkerHttp.mjs";
21
+ import {
22
+ fetchJson,
23
+ bridgeAuthHeaders,
24
+ extractError,
25
+ } from "./relayWorkerHttp.mjs";
26
+
27
+ // long-poll 等待秒数(服务端上限 60s)。多数情况下队列里就有请求,空闲时占用一个连接。
28
+ const POLL_WAIT_SECONDS = 25;
29
+ // 单次请求/响应的硬超时 = wait + buffer。HTTP 客户端比服务端 wait 多 5s 防边界 race。
30
+ const POLL_TIMEOUT_MS = (POLL_WAIT_SECONDS + 5) * 1000;
31
+ // 默认 publishEvent 超时:单条事件 10s 足够(数据通常 < 1MB)。
32
+ const PUBLISH_TIMEOUT_MS = 10_000;
33
+ // 心跳间隔。服务端 gateway meta TTL 是 30s(http_gateway.go::gatewayMetaTTL),
34
+ // 取 1/3 留充足容错(2 次心跳丢失仍保活)。
35
+ export const META_HEARTBEAT_MS = 10_000;
36
+ // 连续 poll 失败时的退避起点 + 上限,避免雪崩重试。
37
+ const POLL_BACKOFF_MS = 1_000;
38
+ const POLL_BACKOFF_MAX_MS = 15_000;
39
+
40
+ /**
41
+ * 创建一个 worker 实例。worker 不立即启动,调用方需调 run(handler) 进入主循环。
42
+ *
43
+ * @param {{
44
+ * relayUrl: string,
45
+ * gwId: string,
46
+ * bridgeToken: string,
47
+ * runtime: "hermes"|"claude"|"codex",
48
+ * log: any,
49
+ * }} opts
50
+ */
51
+ export function createRelayWorker(opts) {
52
+ if (!opts || !opts.log) throw new Error("createRelayWorker: log required");
53
+ if (!opts.relayUrl) throw new Error("createRelayWorker: relayUrl required");
54
+ if (!opts.gwId) throw new Error("createRelayWorker: gwId required");
55
+ if (!opts.bridgeToken) throw new Error("createRelayWorker: bridgeToken required");
56
+ const log = opts.log.child({ comp: "worker" });
57
+ const base = trimSlash(opts.relayUrl);
58
+ const gw = encodeURIComponent(opts.gwId);
59
+ const auth = bridgeAuthHeaders(opts.bridgeToken);
60
+
61
+ const stopState = { stopping: false };
62
+ let metaTimer = null;
63
+
64
+ // ---- 拉取下一条 request ----
65
+ async function readNextRequest() {
66
+ const url =
67
+ `${base}/v1/gateways/${gw}/requests/next?waitSeconds=${POLL_WAIT_SECONDS}`;
68
+ const res = await fetchJson(url, { method: "GET", headers: auth }, POLL_TIMEOUT_MS);
69
+ if (res.status === 204) return null;
70
+ if (!res.ok) {
71
+ // 状态码必须出现在 message 里 — run() 用 /HTTP 40[13]/ 识别永久错误并中止主循环。
72
+ const detail = extractError(res, "read next request failed");
73
+ throw new Error(`HTTP ${res.status} ${detail}`);
74
+ }
75
+ return res.body?.request ?? null;
76
+ }
77
+
78
+ // ---- 推送 native 事件到服务端 adapter ----
79
+ // event 形态由 runtime 决定;统一字段 `event`(必填) + 任意 native 字段。
80
+ // 失败仅 log,不抛;handler 不应感知 publish 失败(adapter 应有重试/兜底)。
81
+ async function publishEvent(requestId, event) {
82
+ if (!requestId || !event || typeof event !== "object") return false;
83
+ if (typeof event.event !== "string" || !event.event) {
84
+ log.warn("publish.skip", "missing event field", { requestId });
85
+ return false;
86
+ }
87
+ const url = `${base}/v1/gateways/${gw}/requests/${encodeURIComponent(requestId)}/events`;
88
+ try {
89
+ const res = await fetchJson(
90
+ url,
91
+ { method: "POST", headers: { ...auth, "Content-Type": "application/json" }, body: JSON.stringify(event) },
92
+ PUBLISH_TIMEOUT_MS,
93
+ );
94
+ if (!res.ok) {
95
+ log.warn("publish.fail", extractError(res, `publish failed (HTTP ${res.status})`), {
96
+ requestId, event: event.event, status: res.status,
97
+ });
98
+ return false;
99
+ }
100
+ return true;
101
+ } catch (err) {
102
+ log.warn("publish.err", "publish errored", {
103
+ requestId, event: event.event, err: err?.message || String(err),
104
+ });
105
+ return false;
106
+ }
107
+ }
108
+
109
+ // ---- 周期性心跳 ----
110
+ //
111
+ // App 端用 `meta.online ?? meta.connected ?? meta.alive ?? meta.state` 串行
112
+ // 兜底来判 bridge 是否在线(见 agent_app/matelink-app/lib/src/models/relay_models.dart:477)。
113
+ // legacy openclaw bridge 的 `buildBridgePresenceMeta` 一直会发这套字段,
114
+ // ext runtime(hermes / claude / codex / picoclaw)漏发会导致 onlineHint=null
115
+ // → App UI 兜底显示"离线"(即用户报"配对完显示离线"的根因)。
116
+ // detail === "stopped" 时表示主动下线,其它("ready" / "heartbeat" / "alive")都视为在线。
117
+ async function sendMeta(detail) {
118
+ const url = `${base}/v1/gateways/${gw}/meta`;
119
+ const isAlive = detail !== "stopped";
120
+ const stateLabel = detail === "stopped" ? "stopped"
121
+ : detail === "ready" ? "running"
122
+ : "running";
123
+ try {
124
+ const res = await fetchJson(
125
+ url,
126
+ {
127
+ method: "POST",
128
+ headers: { ...auth, "Content-Type": "application/json" },
129
+ body: JSON.stringify({
130
+ runtime: opts.runtime,
131
+ detail: detail || "alive",
132
+ collected_at_ms: Date.now(),
133
+ // ↓ App-facing presence 字段:用任一即可判 online
134
+ online: isAlive,
135
+ connected: isAlive,
136
+ alive: isAlive,
137
+ state: stateLabel,
138
+ heartbeatAt: new Date().toISOString(),
139
+ }),
140
+ },
141
+ PUBLISH_TIMEOUT_MS,
142
+ );
143
+ if (!res.ok) {
144
+ log.warn("meta.fail", extractError(res, `meta failed (HTTP ${res.status})`), {
145
+ status: res.status,
146
+ });
147
+ return false;
148
+ }
149
+ return true;
150
+ } catch (err) {
151
+ log.warn("meta.err", "meta heartbeat errored", { err: err?.message || String(err) });
152
+ return false;
153
+ }
154
+ }
155
+
156
+ function startHeartbeat() {
157
+ if (metaTimer) return;
158
+ // 立即发一次,让服务端立刻知道 bridge 起来了。
159
+ void sendMeta("ready");
160
+ metaTimer = setInterval(() => {
161
+ if (stopState.stopping) return;
162
+ void sendMeta("heartbeat");
163
+ }, META_HEARTBEAT_MS);
164
+ if (typeof metaTimer.unref === "function") metaTimer.unref();
165
+ }
166
+
167
+ function stopHeartbeat() {
168
+ if (metaTimer) {
169
+ clearInterval(metaTimer);
170
+ metaTimer = null;
171
+ }
172
+ }
173
+
174
+ // ---- 主循环:long-poll → 派发(rpc 并发 / chat 按会话串行) ----
175
+ // handler 形态: async (request, ctx) => void
176
+ // ctx.publishEvent(event) 把 native 事件推回服务端
177
+ // ctx.requestId 当前请求 id(便利字段,等价 request.requestId)
178
+ // ctx.signal 关闭信号(基于 AbortController)
179
+ async function run(handler) {
180
+ if (typeof handler !== "function") {
181
+ throw new Error("worker.run: handler must be a function");
182
+ }
183
+ // sessionKey → 该会话当前尾部 promise(chat 请求按会话串行、跨会话并行)
184
+ const sessionLanes = new Map();
185
+ startHeartbeat();
186
+ let backoff = POLL_BACKOFF_MS;
187
+ while (!stopState.stopping) {
188
+ let request;
189
+ try {
190
+ request = await readNextRequest();
191
+ backoff = POLL_BACKOFF_MS;
192
+ } catch (err) {
193
+ const msg = err?.message || String(err);
194
+ // 401/403 永久错误 — bridge token 失效,直接抛 bridge 主流程退出。
195
+ // 404/410 = pair session 已被服务端解绑(App 端 deleteContact /
196
+ // POST /v1/gateways/<gw>/reset 都走 deleted_at 标记),
197
+ // server 长 poll 查不到 session → "gateway session not
198
+ // found"。视为对端解绑,标记 revoked + 抛错让上层清理。
199
+ if (/HTTP 40[13]/.test(msg)) {
200
+ log.error("poll.auth_fail", "bridge token invalid, aborting", { err: msg });
201
+ stopState.stopping = true;
202
+ throw err;
203
+ }
204
+ if (/HTTP 404\b|HTTP 410\b/.test(msg) || /gateway session not found/i.test(msg)) {
205
+ log.error("poll.revoked", "binding revoked by remote, aborting", {
206
+ err: msg,
207
+ });
208
+ stopState.stopping = true;
209
+ // 把 revoked 标记打到错误对象上,bridge 主流程据此触发自卸载逻辑
210
+ // (清本地 pair state + spawn `agentlink uninstall` 卸 launchd plist)。
211
+ err.revoked = true;
212
+ throw err;
213
+ }
214
+ log.warn("poll.err", "long-poll errored, backing off", {
215
+ err: msg, backoff_ms: backoff,
216
+ });
217
+ await sleep(backoff);
218
+ backoff = Math.min(backoff * 2, POLL_BACKOFF_MAX_MS);
219
+ continue;
220
+ }
221
+ if (!request) continue; // 204 — 队列空,继续 poll
222
+ const requestId = String(request.requestId || "").trim();
223
+ if (!requestId) {
224
+ log.warn("poll.bad", "request missing requestId");
225
+ continue;
226
+ }
227
+ log.info("request.recv", "request received", {
228
+ requestId,
229
+ sessionKey: request.sessionKey || "",
230
+ agent: request.agentId || "",
231
+ stream: !!request.stream,
232
+ });
233
+ const ctx = {
234
+ requestId,
235
+ publishEvent: (event) => publishEvent(requestId, event),
236
+ };
237
+ const runOne = async () => {
238
+ try {
239
+ await handler(request, ctx);
240
+ } catch (err) {
241
+ const msg = err?.message || String(err);
242
+ log.error("handler.fail", "request handler threw", { requestId, err: msg });
243
+ // 未捕获的 handler 错误统一收尾发 error + end,避免 client 永远等不到结束。
244
+ await publishEvent(requestId, { event: "error", error: msg });
245
+ await publishEvent(requestId, { event: "end" });
246
+ }
247
+ };
248
+ // 派发策略(P0 停止按钮):
249
+ // - rpc 控制请求(workspaces.scan / sessions.abort 等)立即并发执行——
250
+ // 否则 abort 会排在正在执行的 chat 后面,永远停不掉。
251
+ // - chat 请求按 sessionKey 串行(同会话保序),不同会话并行;
252
+ // 主循环不再 await handler,long-poll 持续拉取。
253
+ if (request?.request?.__relayKind === "rpc") {
254
+ void runOne();
255
+ } else {
256
+ const laneKey = String(request.sessionKey || requestId);
257
+ const tail = sessionLanes.get(laneKey) || Promise.resolve();
258
+ const next = tail.then(runOne, runOne);
259
+ sessionLanes.set(laneKey, next);
260
+ void next.finally(() => {
261
+ if (sessionLanes.get(laneKey) === next) sessionLanes.delete(laneKey);
262
+ });
263
+ }
264
+ }
265
+ }
266
+
267
+ function stop(reason) {
268
+ stopState.stopping = true;
269
+ stopHeartbeat();
270
+ log.info("worker.stop", "worker stopping", { reason: reason || "" });
271
+ }
272
+
273
+ return {
274
+ run,
275
+ stop,
276
+ publishEvent,
277
+ sendMeta,
278
+ isStopping: () => stopState.stopping,
279
+ };
280
+ }
281
+
282
+ function sleep(ms) {
283
+ return new Promise((r) => setTimeout(r, ms));
284
+ }
@@ -0,0 +1,58 @@
1
+ // relayWorker 的 HTTP 工具(独立文件,便于单测 mock)。
2
+ //
3
+ // fetchJson 是 src/tunnel_state.mjs 同名函数的精简版 — 只做 JSON 请求/响应,
4
+ // 不处理流式、不处理 hop-by-hop。bridge worker 走的全是简单 JSON RPC 形态。
5
+
6
+ /** 去掉 URL 末尾的多余斜杠,但保留 scheme + host。 */
7
+ export function trimSlash(url) {
8
+ return String(url || "").replace(/\/+$/, "");
9
+ }
10
+
11
+ /**
12
+ * Bearer token header — bridge 端点要求 `Authorization: Bearer <bridgeToken>`。
13
+ *
14
+ * 服务端 requireGatewayAuth 接受同一 token 形式;X-Agent-Bridge-Token 是 unified
15
+ * 协议端点的 producer auth,这里**不**用,我们走 legacy gateway 路径。
16
+ */
17
+ export function bridgeAuthHeaders(bridgeToken) {
18
+ return { Authorization: `Bearer ${String(bridgeToken || "")}` };
19
+ }
20
+
21
+ /**
22
+ * 简化的 fetch wrapper:
23
+ * - 自动 AbortController 超时
24
+ * - body 是 JSON 时自动解析,否则保留 raw text
25
+ * - 不抛网络错以外的错(HTTP 4xx/5xx 通过 res.ok=false + body 透传)
26
+ *
27
+ * @param {string} url
28
+ * @param {RequestInit} init
29
+ * @param {number} [timeoutMs] 默认 30s
30
+ * @returns {Promise<{ok:boolean,status:number,body:any,bodyText:string}>}
31
+ */
32
+ export async function fetchJson(url, init, timeoutMs = 30_000) {
33
+ const ctrl = new AbortController();
34
+ const t = setTimeout(() => ctrl.abort(), timeoutMs);
35
+ let res;
36
+ try {
37
+ res = await fetch(url, { ...init, signal: ctrl.signal });
38
+ } finally {
39
+ clearTimeout(t);
40
+ }
41
+ const text = await res.text();
42
+ let body = null;
43
+ if (text) {
44
+ try { body = JSON.parse(text); } catch { body = null; }
45
+ }
46
+ return { ok: res.ok, status: res.status, body, bodyText: text };
47
+ }
48
+
49
+ /** 从 fetchJson 响应里榨出错误描述 — body.error 优先,否则原文截断。 */
50
+ export function extractError(res, fallback) {
51
+ if (res?.body && typeof res.body === "object" && typeof res.body.error === "string") {
52
+ return res.body.error;
53
+ }
54
+ if (typeof res?.bodyText === "string" && res.bodyText.trim()) {
55
+ return res.bodyText.slice(0, 200);
56
+ }
57
+ return fallback || "request failed";
58
+ }