@blade-hq/agent-client 1.1.1 → 1.1.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 (583) hide show
  1. package/README.md +48 -25
  2. package/dist/blade-client.d.ts +2 -14
  3. package/dist/index.d.ts +5 -2
  4. package/dist/index.js +212 -106
  5. package/dist/index.js.map +1 -1
  6. package/dist/resources/models.d.ts +15 -0
  7. package/dist/resources/sessions.d.ts +8 -1
  8. package/dist/session/agent-session.d.ts +10 -0
  9. package/dist/session/definition.d.ts +49 -0
  10. package/dist/shared/projection/helpers.d.ts +1 -1
  11. package/dist/types/rest.d.ts +378 -10
  12. package/dist/version.d.ts +4 -42
  13. package/node_modules/@ark/schema/LICENSE +7 -0
  14. package/node_modules/@ark/schema/README.md +18 -0
  15. package/node_modules/@ark/schema/out/config.d.ts +58 -0
  16. package/node_modules/@ark/schema/out/config.js +95 -0
  17. package/node_modules/@ark/schema/out/constraint.d.ts +67 -0
  18. package/node_modules/@ark/schema/out/constraint.js +136 -0
  19. package/node_modules/@ark/schema/out/generic.d.ts +73 -0
  20. package/node_modules/@ark/schema/out/generic.js +76 -0
  21. package/node_modules/@ark/schema/out/index.d.ts +47 -0
  22. package/node_modules/@ark/schema/out/index.js +47 -0
  23. package/node_modules/@ark/schema/out/intrinsic.d.ts +24 -0
  24. package/node_modules/@ark/schema/out/intrinsic.js +56 -0
  25. package/node_modules/@ark/schema/out/kinds.d.ts +73 -0
  26. package/node_modules/@ark/schema/out/kinds.js +71 -0
  27. package/node_modules/@ark/schema/out/module.d.ts +24 -0
  28. package/node_modules/@ark/schema/out/module.js +15 -0
  29. package/node_modules/@ark/schema/out/node.d.ts +154 -0
  30. package/node_modules/@ark/schema/out/node.js +438 -0
  31. package/node_modules/@ark/schema/out/parse.d.ts +52 -0
  32. package/node_modules/@ark/schema/out/parse.js +215 -0
  33. package/node_modules/@ark/schema/out/predicate.d.ts +52 -0
  34. package/node_modules/@ark/schema/out/predicate.js +63 -0
  35. package/node_modules/@ark/schema/out/refinements/after.d.ts +41 -0
  36. package/node_modules/@ark/schema/out/refinements/after.js +35 -0
  37. package/node_modules/@ark/schema/out/refinements/before.d.ts +41 -0
  38. package/node_modules/@ark/schema/out/refinements/before.js +41 -0
  39. package/node_modules/@ark/schema/out/refinements/divisor.d.ts +43 -0
  40. package/node_modules/@ark/schema/out/refinements/divisor.js +58 -0
  41. package/node_modules/@ark/schema/out/refinements/exactLength.d.ts +49 -0
  42. package/node_modules/@ark/schema/out/refinements/exactLength.js +55 -0
  43. package/node_modules/@ark/schema/out/refinements/kinds.d.ts +34 -0
  44. package/node_modules/@ark/schema/out/refinements/kinds.js +25 -0
  45. package/node_modules/@ark/schema/out/refinements/max.d.ts +37 -0
  46. package/node_modules/@ark/schema/out/refinements/max.js +45 -0
  47. package/node_modules/@ark/schema/out/refinements/maxLength.d.ts +40 -0
  48. package/node_modules/@ark/schema/out/refinements/maxLength.js +49 -0
  49. package/node_modules/@ark/schema/out/refinements/min.d.ts +37 -0
  50. package/node_modules/@ark/schema/out/refinements/min.js +39 -0
  51. package/node_modules/@ark/schema/out/refinements/minLength.d.ts +40 -0
  52. package/node_modules/@ark/schema/out/refinements/minLength.js +47 -0
  53. package/node_modules/@ark/schema/out/refinements/pattern.d.ts +43 -0
  54. package/node_modules/@ark/schema/out/refinements/pattern.js +52 -0
  55. package/node_modules/@ark/schema/out/refinements/range.d.ts +106 -0
  56. package/node_modules/@ark/schema/out/refinements/range.js +103 -0
  57. package/node_modules/@ark/schema/out/roots/alias.d.ts +45 -0
  58. package/node_modules/@ark/schema/out/roots/alias.js +115 -0
  59. package/node_modules/@ark/schema/out/roots/basis.d.ts +12 -0
  60. package/node_modules/@ark/schema/out/roots/basis.js +26 -0
  61. package/node_modules/@ark/schema/out/roots/domain.d.ts +45 -0
  62. package/node_modules/@ark/schema/out/roots/domain.js +72 -0
  63. package/node_modules/@ark/schema/out/roots/intersection.d.ts +98 -0
  64. package/node_modules/@ark/schema/out/roots/intersection.js +292 -0
  65. package/node_modules/@ark/schema/out/roots/morph.d.ts +62 -0
  66. package/node_modules/@ark/schema/out/roots/morph.js +159 -0
  67. package/node_modules/@ark/schema/out/roots/proto.d.ts +53 -0
  68. package/node_modules/@ark/schema/out/roots/proto.js +101 -0
  69. package/node_modules/@ark/schema/out/roots/root.d.ts +145 -0
  70. package/node_modules/@ark/schema/out/roots/root.js +455 -0
  71. package/node_modules/@ark/schema/out/roots/union.d.ts +99 -0
  72. package/node_modules/@ark/schema/out/roots/union.js +718 -0
  73. package/node_modules/@ark/schema/out/roots/unit.d.ts +41 -0
  74. package/node_modules/@ark/schema/out/roots/unit.js +86 -0
  75. package/node_modules/@ark/schema/out/roots/utils.d.ts +3 -0
  76. package/node_modules/@ark/schema/out/roots/utils.js +6 -0
  77. package/node_modules/@ark/schema/out/scope.d.ts +158 -0
  78. package/node_modules/@ark/schema/out/scope.js +481 -0
  79. package/node_modules/@ark/schema/out/shared/compile.d.ts +62 -0
  80. package/node_modules/@ark/schema/out/shared/compile.js +145 -0
  81. package/node_modules/@ark/schema/out/shared/declare.d.ts +80 -0
  82. package/node_modules/@ark/schema/out/shared/declare.js +1 -0
  83. package/node_modules/@ark/schema/out/shared/disjoint.d.ts +41 -0
  84. package/node_modules/@ark/schema/out/shared/disjoint.js +65 -0
  85. package/node_modules/@ark/schema/out/shared/errors.d.ts +145 -0
  86. package/node_modules/@ark/schema/out/shared/errors.js +252 -0
  87. package/node_modules/@ark/schema/out/shared/implement.d.ts +151 -0
  88. package/node_modules/@ark/schema/out/shared/implement.js +98 -0
  89. package/node_modules/@ark/schema/out/shared/intersections.d.ts +10 -0
  90. package/node_modules/@ark/schema/out/shared/intersections.js +132 -0
  91. package/node_modules/@ark/schema/out/shared/jsonSchema.d.ts +93 -0
  92. package/node_modules/@ark/schema/out/shared/jsonSchema.js +1 -0
  93. package/node_modules/@ark/schema/out/shared/registry.d.ts +7 -0
  94. package/node_modules/@ark/schema/out/shared/registry.js +10 -0
  95. package/node_modules/@ark/schema/out/shared/standardSchema.d.ts +122 -0
  96. package/node_modules/@ark/schema/out/shared/standardSchema.js +2 -0
  97. package/node_modules/@ark/schema/out/shared/toJsonSchema.d.ts +139 -0
  98. package/node_modules/@ark/schema/out/shared/toJsonSchema.js +40 -0
  99. package/node_modules/@ark/schema/out/shared/traversal.d.ts +117 -0
  100. package/node_modules/@ark/schema/out/shared/traversal.js +226 -0
  101. package/node_modules/@ark/schema/out/shared/utils.d.ts +34 -0
  102. package/node_modules/@ark/schema/out/shared/utils.js +8 -0
  103. package/node_modules/@ark/schema/out/structure/index.d.ts +46 -0
  104. package/node_modules/@ark/schema/out/structure/index.js +89 -0
  105. package/node_modules/@ark/schema/out/structure/optional.d.ts +49 -0
  106. package/node_modules/@ark/schema/out/structure/optional.js +127 -0
  107. package/node_modules/@ark/schema/out/structure/prop.d.ts +45 -0
  108. package/node_modules/@ark/schema/out/structure/prop.js +85 -0
  109. package/node_modules/@ark/schema/out/structure/required.d.ts +39 -0
  110. package/node_modules/@ark/schema/out/structure/required.js +38 -0
  111. package/node_modules/@ark/schema/out/structure/sequence.d.ts +110 -0
  112. package/node_modules/@ark/schema/out/structure/sequence.js +521 -0
  113. package/node_modules/@ark/schema/out/structure/shared.d.ts +4 -0
  114. package/node_modules/@ark/schema/out/structure/shared.js +4 -0
  115. package/node_modules/@ark/schema/out/structure/structure.d.ts +113 -0
  116. package/node_modules/@ark/schema/out/structure/structure.js +747 -0
  117. package/node_modules/@ark/schema/package.json +51 -0
  118. package/node_modules/@ark/util/LICENSE +7 -0
  119. package/node_modules/@ark/util/out/arrays.d.ts +166 -0
  120. package/node_modules/@ark/util/out/arrays.js +147 -0
  121. package/node_modules/@ark/util/out/clone.d.ts +4 -0
  122. package/node_modules/@ark/util/out/clone.js +33 -0
  123. package/node_modules/@ark/util/out/describe.d.ts +25 -0
  124. package/node_modules/@ark/util/out/describe.js +1 -0
  125. package/node_modules/@ark/util/out/domain.d.ts +48 -0
  126. package/node_modules/@ark/util/out/domain.js +25 -0
  127. package/node_modules/@ark/util/out/errors.d.ts +29 -0
  128. package/node_modules/@ark/util/out/errors.js +17 -0
  129. package/node_modules/@ark/util/out/flatMorph.d.ts +41 -0
  130. package/node_modules/@ark/util/out/flatMorph.js +24 -0
  131. package/node_modules/@ark/util/out/functions.d.ts +33 -0
  132. package/node_modules/@ark/util/out/functions.js +53 -0
  133. package/node_modules/@ark/util/out/generics.d.ts +59 -0
  134. package/node_modules/@ark/util/out/generics.js +5 -0
  135. package/node_modules/@ark/util/out/get.d.ts +9 -0
  136. package/node_modules/@ark/util/out/get.js +7 -0
  137. package/node_modules/@ark/util/out/hkt.d.ts +27 -0
  138. package/node_modules/@ark/util/out/hkt.js +5 -0
  139. package/node_modules/@ark/util/out/index.d.ts +24 -0
  140. package/node_modules/@ark/util/out/index.js +24 -0
  141. package/node_modules/@ark/util/out/intersections.d.ts +50 -0
  142. package/node_modules/@ark/util/out/intersections.js +1 -0
  143. package/node_modules/@ark/util/out/isomorphic.d.ts +5 -0
  144. package/node_modules/@ark/util/out/isomorphic.js +19 -0
  145. package/node_modules/@ark/util/out/keys.d.ts +18 -0
  146. package/node_modules/@ark/util/out/keys.js +1 -0
  147. package/node_modules/@ark/util/out/lazily.d.ts +1 -0
  148. package/node_modules/@ark/util/out/lazily.js +16 -0
  149. package/node_modules/@ark/util/out/numbers.d.ts +72 -0
  150. package/node_modules/@ark/util/out/numbers.js +138 -0
  151. package/node_modules/@ark/util/out/objectKinds.d.ts +205 -0
  152. package/node_modules/@ark/util/out/objectKinds.js +150 -0
  153. package/node_modules/@ark/util/out/path.d.ts +22 -0
  154. package/node_modules/@ark/util/out/path.js +65 -0
  155. package/node_modules/@ark/util/out/primitive.d.ts +16 -0
  156. package/node_modules/@ark/util/out/primitive.js +3 -0
  157. package/node_modules/@ark/util/out/records.d.ts +183 -0
  158. package/node_modules/@ark/util/out/records.js +63 -0
  159. package/node_modules/@ark/util/out/registry.d.ts +21 -0
  160. package/node_modules/@ark/util/out/registry.js +49 -0
  161. package/node_modules/@ark/util/out/scanner.d.ts +44 -0
  162. package/node_modules/@ark/util/out/scanner.js +87 -0
  163. package/node_modules/@ark/util/out/serialize.d.ts +34 -0
  164. package/node_modules/@ark/util/out/serialize.js +150 -0
  165. package/node_modules/@ark/util/out/strings.d.ts +33 -0
  166. package/node_modules/@ark/util/out/strings.js +59 -0
  167. package/node_modules/@ark/util/out/traits.d.ts +89 -0
  168. package/node_modules/@ark/util/out/traits.js +75 -0
  169. package/node_modules/@ark/util/out/unionToTuple.d.ts +14 -0
  170. package/node_modules/@ark/util/out/unionToTuple.js +1 -0
  171. package/node_modules/@ark/util/package.json +39 -0
  172. package/node_modules/@ark/util/tsconfig.base.json +18 -0
  173. package/node_modules/@socket.io/component-emitter/LICENSE +24 -0
  174. package/node_modules/@socket.io/component-emitter/Readme.md +79 -0
  175. package/node_modules/@socket.io/component-emitter/lib/cjs/index.d.ts +179 -0
  176. package/node_modules/@socket.io/component-emitter/lib/cjs/index.js +176 -0
  177. package/node_modules/@socket.io/component-emitter/lib/cjs/package.json +4 -0
  178. package/node_modules/@socket.io/component-emitter/lib/esm/index.d.ts +179 -0
  179. package/node_modules/@socket.io/component-emitter/lib/esm/index.js +169 -0
  180. package/node_modules/@socket.io/component-emitter/lib/esm/package.json +4 -0
  181. package/node_modules/@socket.io/component-emitter/package.json +28 -0
  182. package/node_modules/arkregex/LICENSE +7 -0
  183. package/node_modules/arkregex/README.md +61 -0
  184. package/node_modules/arkregex/out/charset.d.ts +15 -0
  185. package/node_modules/arkregex/out/charset.js +1 -0
  186. package/node_modules/arkregex/out/escape.d.ts +29 -0
  187. package/node_modules/arkregex/out/escape.js +10 -0
  188. package/node_modules/arkregex/out/execArray.d.ts +23 -0
  189. package/node_modules/arkregex/out/execArray.js +1 -0
  190. package/node_modules/arkregex/out/group.d.ts +33 -0
  191. package/node_modules/arkregex/out/group.js +6 -0
  192. package/node_modules/arkregex/out/index.d.ts +1 -0
  193. package/node_modules/arkregex/out/index.js +1 -0
  194. package/node_modules/arkregex/out/parse.d.ts +10 -0
  195. package/node_modules/arkregex/out/parse.js +1 -0
  196. package/node_modules/arkregex/out/quantify.d.ts +43 -0
  197. package/node_modules/arkregex/out/quantify.js +2 -0
  198. package/node_modules/arkregex/out/regex.d.ts +38 -0
  199. package/node_modules/arkregex/out/regex.js +2 -0
  200. package/node_modules/arkregex/out/state.d.ts +359 -0
  201. package/node_modules/arkregex/out/state.js +2 -0
  202. package/node_modules/arkregex/package.json +42 -0
  203. package/node_modules/arktype/LICENSE +7 -0
  204. package/node_modules/arktype/README.md +157 -0
  205. package/node_modules/arktype/out/attributes.d.ts +104 -0
  206. package/node_modules/arktype/out/attributes.js +3 -0
  207. package/node_modules/arktype/out/config.d.ts +35 -0
  208. package/node_modules/arktype/out/config.js +3 -0
  209. package/node_modules/arktype/out/declare.d.ts +35 -0
  210. package/node_modules/arktype/out/declare.js +1 -0
  211. package/node_modules/arktype/out/fn.d.ts +61 -0
  212. package/node_modules/arktype/out/fn.js +54 -0
  213. package/node_modules/arktype/out/generic.d.ts +118 -0
  214. package/node_modules/arktype/out/generic.js +37 -0
  215. package/node_modules/arktype/out/index.d.ts +12 -0
  216. package/node_modules/arktype/out/index.js +9 -0
  217. package/node_modules/arktype/out/keywords/Array.d.ts +20 -0
  218. package/node_modules/arktype/out/keywords/Array.js +21 -0
  219. package/node_modules/arktype/out/keywords/FormData.d.ts +15 -0
  220. package/node_modules/arktype/out/keywords/FormData.js +40 -0
  221. package/node_modules/arktype/out/keywords/TypedArray.d.ts +19 -0
  222. package/node_modules/arktype/out/keywords/TypedArray.js +16 -0
  223. package/node_modules/arktype/out/keywords/builtins.d.ts +18 -0
  224. package/node_modules/arktype/out/keywords/builtins.js +11 -0
  225. package/node_modules/arktype/out/keywords/constructors.d.ts +31 -0
  226. package/node_modules/arktype/out/keywords/constructors.js +16 -0
  227. package/node_modules/arktype/out/keywords/keywords.d.ts +70 -0
  228. package/node_modules/arktype/out/keywords/keywords.js +48 -0
  229. package/node_modules/arktype/out/keywords/number.d.ts +23 -0
  230. package/node_modules/arktype/out/keywords/number.js +49 -0
  231. package/node_modules/arktype/out/keywords/string.d.ts +334 -0
  232. package/node_modules/arktype/out/keywords/string.js +463 -0
  233. package/node_modules/arktype/out/keywords/ts.d.ts +108 -0
  234. package/node_modules/arktype/out/keywords/ts.js +82 -0
  235. package/node_modules/arktype/out/match.d.ts +152 -0
  236. package/node_modules/arktype/out/match.js +95 -0
  237. package/node_modules/arktype/out/module.d.ts +22 -0
  238. package/node_modules/arktype/out/module.js +3 -0
  239. package/node_modules/arktype/out/nary.d.ts +473 -0
  240. package/node_modules/arktype/out/nary.js +1 -0
  241. package/node_modules/arktype/out/parser/ast/bounds.d.ts +18 -0
  242. package/node_modules/arktype/out/parser/ast/bounds.js +1 -0
  243. package/node_modules/arktype/out/parser/ast/default.d.ts +8 -0
  244. package/node_modules/arktype/out/parser/ast/default.js +1 -0
  245. package/node_modules/arktype/out/parser/ast/divisor.d.ts +9 -0
  246. package/node_modules/arktype/out/parser/ast/divisor.js +1 -0
  247. package/node_modules/arktype/out/parser/ast/generic.d.ts +17 -0
  248. package/node_modules/arktype/out/parser/ast/generic.js +1 -0
  249. package/node_modules/arktype/out/parser/ast/infer.d.ts +25 -0
  250. package/node_modules/arktype/out/parser/ast/infer.js +1 -0
  251. package/node_modules/arktype/out/parser/ast/keyof.d.ts +7 -0
  252. package/node_modules/arktype/out/parser/ast/keyof.js +1 -0
  253. package/node_modules/arktype/out/parser/ast/utils.d.ts +8 -0
  254. package/node_modules/arktype/out/parser/ast/utils.js +1 -0
  255. package/node_modules/arktype/out/parser/ast/validate.d.ts +30 -0
  256. package/node_modules/arktype/out/parser/ast/validate.js +3 -0
  257. package/node_modules/arktype/out/parser/definition.d.ts +30 -0
  258. package/node_modules/arktype/out/parser/definition.js +74 -0
  259. package/node_modules/arktype/out/parser/objectLiteral.d.ts +70 -0
  260. package/node_modules/arktype/out/parser/objectLiteral.js +113 -0
  261. package/node_modules/arktype/out/parser/property.d.ts +34 -0
  262. package/node_modules/arktype/out/parser/property.js +16 -0
  263. package/node_modules/arktype/out/parser/reduce/dynamic.d.ts +42 -0
  264. package/node_modules/arktype/out/parser/reduce/dynamic.js +153 -0
  265. package/node_modules/arktype/out/parser/reduce/shared.d.ts +39 -0
  266. package/node_modules/arktype/out/parser/reduce/shared.js +25 -0
  267. package/node_modules/arktype/out/parser/reduce/static.d.ts +186 -0
  268. package/node_modules/arktype/out/parser/reduce/static.js +1 -0
  269. package/node_modules/arktype/out/parser/shift/operand/date.d.ts +11 -0
  270. package/node_modules/arktype/out/parser/shift/operand/date.js +23 -0
  271. package/node_modules/arktype/out/parser/shift/operand/enclosed.d.ts +57 -0
  272. package/node_modules/arktype/out/parser/shift/operand/enclosed.js +78 -0
  273. package/node_modules/arktype/out/parser/shift/operand/genericArgs.d.ts +27 -0
  274. package/node_modules/arktype/out/parser/shift/operand/genericArgs.js +16 -0
  275. package/node_modules/arktype/out/parser/shift/operand/operand.d.ts +8 -0
  276. package/node_modules/arktype/out/parser/shift/operand/operand.js +16 -0
  277. package/node_modules/arktype/out/parser/shift/operand/unenclosed.d.ts +43 -0
  278. package/node_modules/arktype/out/parser/shift/operand/unenclosed.js +59 -0
  279. package/node_modules/arktype/out/parser/shift/operator/bounds.d.ts +24 -0
  280. package/node_modules/arktype/out/parser/shift/operator/bounds.js +91 -0
  281. package/node_modules/arktype/out/parser/shift/operator/brand.d.ts +7 -0
  282. package/node_modules/arktype/out/parser/shift/operator/brand.js +6 -0
  283. package/node_modules/arktype/out/parser/shift/operator/default.d.ts +24 -0
  284. package/node_modules/arktype/out/parser/shift/operator/default.js +15 -0
  285. package/node_modules/arktype/out/parser/shift/operator/divisor.d.ts +8 -0
  286. package/node_modules/arktype/out/parser/shift/operator/divisor.js +13 -0
  287. package/node_modules/arktype/out/parser/shift/operator/operator.d.ts +14 -0
  288. package/node_modules/arktype/out/parser/shift/operator/operator.js +28 -0
  289. package/node_modules/arktype/out/parser/shift/tokens.d.ts +33 -0
  290. package/node_modules/arktype/out/parser/shift/tokens.js +37 -0
  291. package/node_modules/arktype/out/parser/string.d.ts +30 -0
  292. package/node_modules/arktype/out/parser/string.js +42 -0
  293. package/node_modules/arktype/out/parser/tupleExpressions.d.ts +79 -0
  294. package/node_modules/arktype/out/parser/tupleExpressions.js +75 -0
  295. package/node_modules/arktype/out/parser/tupleLiteral.d.ts +95 -0
  296. package/node_modules/arktype/out/parser/tupleLiteral.js +128 -0
  297. package/node_modules/arktype/out/scope.d.ts +158 -0
  298. package/node_modules/arktype/out/scope.js +106 -0
  299. package/node_modules/arktype/out/type.d.ts +144 -0
  300. package/node_modules/arktype/out/type.js +55 -0
  301. package/node_modules/arktype/out/variants/array.d.ts +12 -0
  302. package/node_modules/arktype/out/variants/array.js +1 -0
  303. package/node_modules/arktype/out/variants/base.d.ts +542 -0
  304. package/node_modules/arktype/out/variants/base.js +1 -0
  305. package/node_modules/arktype/out/variants/date.d.ts +10 -0
  306. package/node_modules/arktype/out/variants/date.js +1 -0
  307. package/node_modules/arktype/out/variants/instantiate.d.ts +12 -0
  308. package/node_modules/arktype/out/variants/instantiate.js +1 -0
  309. package/node_modules/arktype/out/variants/number.d.ts +11 -0
  310. package/node_modules/arktype/out/variants/number.js +1 -0
  311. package/node_modules/arktype/out/variants/object.d.ts +107 -0
  312. package/node_modules/arktype/out/variants/object.js +1 -0
  313. package/node_modules/arktype/out/variants/string.d.ts +15 -0
  314. package/node_modules/arktype/out/variants/string.js +1 -0
  315. package/node_modules/arktype/package.json +57 -0
  316. package/node_modules/debug/LICENSE +20 -0
  317. package/node_modules/debug/README.md +481 -0
  318. package/node_modules/debug/package.json +64 -0
  319. package/node_modules/debug/src/browser.js +272 -0
  320. package/node_modules/debug/src/common.js +292 -0
  321. package/node_modules/debug/src/index.js +10 -0
  322. package/node_modules/debug/src/node.js +263 -0
  323. package/node_modules/engine.io-client/LICENSE +22 -0
  324. package/node_modules/engine.io-client/README.md +331 -0
  325. package/node_modules/engine.io-client/build/cjs/browser-entrypoint.d.ts +3 -0
  326. package/node_modules/engine.io-client/build/cjs/browser-entrypoint.js +4 -0
  327. package/node_modules/engine.io-client/build/cjs/contrib/has-cors.d.ts +1 -0
  328. package/node_modules/engine.io-client/build/cjs/contrib/has-cors.js +14 -0
  329. package/node_modules/engine.io-client/build/cjs/contrib/parseqs.d.ts +15 -0
  330. package/node_modules/engine.io-client/build/cjs/contrib/parseqs.js +38 -0
  331. package/node_modules/engine.io-client/build/cjs/contrib/parseuri.d.ts +1 -0
  332. package/node_modules/engine.io-client/build/cjs/contrib/parseuri.js +67 -0
  333. package/node_modules/engine.io-client/build/cjs/globals.d.ts +4 -0
  334. package/node_modules/engine.io-client/build/cjs/globals.js +26 -0
  335. package/node_modules/engine.io-client/build/cjs/globals.node.d.ts +21 -0
  336. package/node_modules/engine.io-client/build/cjs/globals.node.js +97 -0
  337. package/node_modules/engine.io-client/build/cjs/index.d.ts +15 -0
  338. package/node_modules/engine.io-client/build/cjs/index.js +32 -0
  339. package/node_modules/engine.io-client/build/cjs/package.json +10 -0
  340. package/node_modules/engine.io-client/build/cjs/socket.d.ts +482 -0
  341. package/node_modules/engine.io-client/build/cjs/socket.js +765 -0
  342. package/node_modules/engine.io-client/build/cjs/transport.d.ts +106 -0
  343. package/node_modules/engine.io-client/build/cjs/transport.js +153 -0
  344. package/node_modules/engine.io-client/build/cjs/transports/index.d.ts +8 -0
  345. package/node_modules/engine.io-client/build/cjs/transports/index.js +11 -0
  346. package/node_modules/engine.io-client/build/cjs/transports/polling-fetch.d.ts +15 -0
  347. package/node_modules/engine.io-client/build/cjs/transports/polling-fetch.js +60 -0
  348. package/node_modules/engine.io-client/build/cjs/transports/polling-xhr.d.ts +108 -0
  349. package/node_modules/engine.io-client/build/cjs/transports/polling-xhr.js +285 -0
  350. package/node_modules/engine.io-client/build/cjs/transports/polling-xhr.node.d.ts +11 -0
  351. package/node_modules/engine.io-client/build/cjs/transports/polling-xhr.node.js +44 -0
  352. package/node_modules/engine.io-client/build/cjs/transports/polling.d.ts +52 -0
  353. package/node_modules/engine.io-client/build/cjs/transports/polling.js +165 -0
  354. package/node_modules/engine.io-client/build/cjs/transports/websocket.d.ts +36 -0
  355. package/node_modules/engine.io-client/build/cjs/transports/websocket.js +136 -0
  356. package/node_modules/engine.io-client/build/cjs/transports/websocket.node.d.ts +14 -0
  357. package/node_modules/engine.io-client/build/cjs/transports/websocket.node.js +68 -0
  358. package/node_modules/engine.io-client/build/cjs/transports/webtransport.d.ts +18 -0
  359. package/node_modules/engine.io-client/build/cjs/transports/webtransport.js +94 -0
  360. package/node_modules/engine.io-client/build/cjs/util.d.ts +7 -0
  361. package/node_modules/engine.io-client/build/cjs/util.js +65 -0
  362. package/node_modules/engine.io-client/build/esm/browser-entrypoint.d.ts +3 -0
  363. package/node_modules/engine.io-client/build/esm/browser-entrypoint.js +2 -0
  364. package/node_modules/engine.io-client/build/esm/contrib/has-cors.d.ts +1 -0
  365. package/node_modules/engine.io-client/build/esm/contrib/has-cors.js +11 -0
  366. package/node_modules/engine.io-client/build/esm/contrib/parseqs.d.ts +15 -0
  367. package/node_modules/engine.io-client/build/esm/contrib/parseqs.js +34 -0
  368. package/node_modules/engine.io-client/build/esm/contrib/parseuri.d.ts +1 -0
  369. package/node_modules/engine.io-client/build/esm/contrib/parseuri.js +64 -0
  370. package/node_modules/engine.io-client/build/esm/globals.d.ts +4 -0
  371. package/node_modules/engine.io-client/build/esm/globals.js +22 -0
  372. package/node_modules/engine.io-client/build/esm/globals.node.d.ts +21 -0
  373. package/node_modules/engine.io-client/build/esm/globals.node.js +91 -0
  374. package/node_modules/engine.io-client/build/esm/index.d.ts +15 -0
  375. package/node_modules/engine.io-client/build/esm/index.js +15 -0
  376. package/node_modules/engine.io-client/build/esm/package.json +10 -0
  377. package/node_modules/engine.io-client/build/esm/socket.d.ts +482 -0
  378. package/node_modules/engine.io-client/build/esm/socket.js +727 -0
  379. package/node_modules/engine.io-client/build/esm/transport.d.ts +106 -0
  380. package/node_modules/engine.io-client/build/esm/transport.js +142 -0
  381. package/node_modules/engine.io-client/build/esm/transports/index.d.ts +8 -0
  382. package/node_modules/engine.io-client/build/esm/transports/index.js +8 -0
  383. package/node_modules/engine.io-client/build/esm/transports/polling-fetch.d.ts +15 -0
  384. package/node_modules/engine.io-client/build/esm/transports/polling-fetch.js +56 -0
  385. package/node_modules/engine.io-client/build/esm/transports/polling-xhr.d.ts +108 -0
  386. package/node_modules/engine.io-client/build/esm/transports/polling-xhr.js +271 -0
  387. package/node_modules/engine.io-client/build/esm/transports/polling-xhr.node.d.ts +11 -0
  388. package/node_modules/engine.io-client/build/esm/transports/polling-xhr.node.js +17 -0
  389. package/node_modules/engine.io-client/build/esm/transports/polling.d.ts +52 -0
  390. package/node_modules/engine.io-client/build/esm/transports/polling.js +145 -0
  391. package/node_modules/engine.io-client/build/esm/transports/websocket.d.ts +36 -0
  392. package/node_modules/engine.io-client/build/esm/transports/websocket.js +125 -0
  393. package/node_modules/engine.io-client/build/esm/transports/websocket.node.d.ts +14 -0
  394. package/node_modules/engine.io-client/build/esm/transports/websocket.node.js +41 -0
  395. package/node_modules/engine.io-client/build/esm/transports/webtransport.d.ts +18 -0
  396. package/node_modules/engine.io-client/build/esm/transports/webtransport.js +80 -0
  397. package/node_modules/engine.io-client/build/esm/util.d.ts +7 -0
  398. package/node_modules/engine.io-client/build/esm/util.js +59 -0
  399. package/node_modules/engine.io-client/build/esm-debug/browser-entrypoint.d.ts +3 -0
  400. package/node_modules/engine.io-client/build/esm-debug/browser-entrypoint.js +2 -0
  401. package/node_modules/engine.io-client/build/esm-debug/contrib/has-cors.d.ts +1 -0
  402. package/node_modules/engine.io-client/build/esm-debug/contrib/has-cors.js +11 -0
  403. package/node_modules/engine.io-client/build/esm-debug/contrib/parseqs.d.ts +15 -0
  404. package/node_modules/engine.io-client/build/esm-debug/contrib/parseqs.js +34 -0
  405. package/node_modules/engine.io-client/build/esm-debug/contrib/parseuri.d.ts +1 -0
  406. package/node_modules/engine.io-client/build/esm-debug/contrib/parseuri.js +64 -0
  407. package/node_modules/engine.io-client/build/esm-debug/globals.d.ts +4 -0
  408. package/node_modules/engine.io-client/build/esm-debug/globals.js +22 -0
  409. package/node_modules/engine.io-client/build/esm-debug/globals.node.d.ts +21 -0
  410. package/node_modules/engine.io-client/build/esm-debug/globals.node.js +91 -0
  411. package/node_modules/engine.io-client/build/esm-debug/index.d.ts +15 -0
  412. package/node_modules/engine.io-client/build/esm-debug/index.js +15 -0
  413. package/node_modules/engine.io-client/build/esm-debug/package.json +10 -0
  414. package/node_modules/engine.io-client/build/esm-debug/socket.d.ts +482 -0
  415. package/node_modules/engine.io-client/build/esm-debug/socket.js +756 -0
  416. package/node_modules/engine.io-client/build/esm-debug/transport.d.ts +106 -0
  417. package/node_modules/engine.io-client/build/esm-debug/transport.js +145 -0
  418. package/node_modules/engine.io-client/build/esm-debug/transports/index.d.ts +8 -0
  419. package/node_modules/engine.io-client/build/esm-debug/transports/index.js +8 -0
  420. package/node_modules/engine.io-client/build/esm-debug/transports/polling-fetch.d.ts +15 -0
  421. package/node_modules/engine.io-client/build/esm-debug/transports/polling-fetch.js +56 -0
  422. package/node_modules/engine.io-client/build/esm-debug/transports/polling-xhr.d.ts +108 -0
  423. package/node_modules/engine.io-client/build/esm-debug/transports/polling-xhr.js +276 -0
  424. package/node_modules/engine.io-client/build/esm-debug/transports/polling-xhr.node.d.ts +11 -0
  425. package/node_modules/engine.io-client/build/esm-debug/transports/polling-xhr.node.js +17 -0
  426. package/node_modules/engine.io-client/build/esm-debug/transports/polling.d.ts +52 -0
  427. package/node_modules/engine.io-client/build/esm-debug/transports/polling.js +158 -0
  428. package/node_modules/engine.io-client/build/esm-debug/transports/websocket.d.ts +36 -0
  429. package/node_modules/engine.io-client/build/esm-debug/transports/websocket.js +128 -0
  430. package/node_modules/engine.io-client/build/esm-debug/transports/websocket.node.d.ts +14 -0
  431. package/node_modules/engine.io-client/build/esm-debug/transports/websocket.node.js +41 -0
  432. package/node_modules/engine.io-client/build/esm-debug/transports/webtransport.d.ts +18 -0
  433. package/node_modules/engine.io-client/build/esm-debug/transports/webtransport.js +87 -0
  434. package/node_modules/engine.io-client/build/esm-debug/util.d.ts +7 -0
  435. package/node_modules/engine.io-client/build/esm-debug/util.js +59 -0
  436. package/node_modules/engine.io-client/dist/engine.io.esm.min.js +7 -0
  437. package/node_modules/engine.io-client/dist/engine.io.esm.min.js.map +1 -0
  438. package/node_modules/engine.io-client/dist/engine.io.js +3064 -0
  439. package/node_modules/engine.io-client/dist/engine.io.js.map +1 -0
  440. package/node_modules/engine.io-client/dist/engine.io.min.js +7 -0
  441. package/node_modules/engine.io-client/dist/engine.io.min.js.map +1 -0
  442. package/node_modules/engine.io-client/package.json +95 -0
  443. package/node_modules/engine.io-parser/LICENSE +22 -0
  444. package/node_modules/engine.io-parser/Readme.md +158 -0
  445. package/node_modules/engine.io-parser/build/cjs/commons.d.ts +14 -0
  446. package/node_modules/engine.io-parser/build/cjs/commons.js +19 -0
  447. package/node_modules/engine.io-parser/build/cjs/contrib/base64-arraybuffer.d.ts +2 -0
  448. package/node_modules/engine.io-parser/build/cjs/contrib/base64-arraybuffer.js +48 -0
  449. package/node_modules/engine.io-parser/build/cjs/decodePacket.browser.d.ts +2 -0
  450. package/node_modules/engine.io-parser/build/cjs/decodePacket.browser.js +66 -0
  451. package/node_modules/engine.io-parser/build/cjs/decodePacket.d.ts +2 -0
  452. package/node_modules/engine.io-parser/build/cjs/decodePacket.js +59 -0
  453. package/node_modules/engine.io-parser/build/cjs/encodePacket.browser.d.ts +4 -0
  454. package/node_modules/engine.io-parser/build/cjs/encodePacket.browser.js +72 -0
  455. package/node_modules/engine.io-parser/build/cjs/encodePacket.d.ts +3 -0
  456. package/node_modules/engine.io-parser/build/cjs/encodePacket.js +38 -0
  457. package/node_modules/engine.io-parser/build/cjs/index.d.ts +9 -0
  458. package/node_modules/engine.io-parser/build/cjs/index.js +164 -0
  459. package/node_modules/engine.io-parser/build/cjs/package.json +8 -0
  460. package/node_modules/engine.io-parser/build/esm/commons.d.ts +14 -0
  461. package/node_modules/engine.io-parser/build/esm/commons.js +14 -0
  462. package/node_modules/engine.io-parser/build/esm/contrib/base64-arraybuffer.d.ts +2 -0
  463. package/node_modules/engine.io-parser/build/esm/contrib/base64-arraybuffer.js +43 -0
  464. package/node_modules/engine.io-parser/build/esm/decodePacket.browser.d.ts +2 -0
  465. package/node_modules/engine.io-parser/build/esm/decodePacket.browser.js +62 -0
  466. package/node_modules/engine.io-parser/build/esm/decodePacket.d.ts +2 -0
  467. package/node_modules/engine.io-parser/build/esm/decodePacket.js +55 -0
  468. package/node_modules/engine.io-parser/build/esm/encodePacket.browser.d.ts +4 -0
  469. package/node_modules/engine.io-parser/build/esm/encodePacket.browser.js +68 -0
  470. package/node_modules/engine.io-parser/build/esm/encodePacket.d.ts +3 -0
  471. package/node_modules/engine.io-parser/build/esm/encodePacket.js +33 -0
  472. package/node_modules/engine.io-parser/build/esm/index.d.ts +9 -0
  473. package/node_modules/engine.io-parser/build/esm/index.js +156 -0
  474. package/node_modules/engine.io-parser/build/esm/package.json +8 -0
  475. package/node_modules/engine.io-parser/package.json +46 -0
  476. package/node_modules/ms/index.js +162 -0
  477. package/node_modules/ms/license.md +21 -0
  478. package/node_modules/ms/package.json +38 -0
  479. package/node_modules/ms/readme.md +59 -0
  480. package/node_modules/socket.io-client/LICENSE +21 -0
  481. package/node_modules/socket.io-client/README.md +29 -0
  482. package/node_modules/socket.io-client/build/cjs/browser-entrypoint.d.ts +2 -0
  483. package/node_modules/socket.io-client/build/cjs/browser-entrypoint.js +4 -0
  484. package/node_modules/socket.io-client/build/cjs/contrib/backo2.d.ts +12 -0
  485. package/node_modules/socket.io-client/build/cjs/contrib/backo2.js +69 -0
  486. package/node_modules/socket.io-client/build/cjs/index.d.ts +29 -0
  487. package/node_modules/socket.io-client/build/cjs/index.js +76 -0
  488. package/node_modules/socket.io-client/build/cjs/manager.d.ts +295 -0
  489. package/node_modules/socket.io-client/build/cjs/manager.js +416 -0
  490. package/node_modules/socket.io-client/build/cjs/on.d.ts +2 -0
  491. package/node_modules/socket.io-client/build/cjs/on.js +9 -0
  492. package/node_modules/socket.io-client/build/cjs/socket.d.ts +593 -0
  493. package/node_modules/socket.io-client/build/cjs/socket.js +909 -0
  494. package/node_modules/socket.io-client/build/cjs/url.d.ts +33 -0
  495. package/node_modules/socket.io-client/build/cjs/url.js +69 -0
  496. package/node_modules/socket.io-client/build/esm/browser-entrypoint.d.ts +2 -0
  497. package/node_modules/socket.io-client/build/esm/browser-entrypoint.js +2 -0
  498. package/node_modules/socket.io-client/build/esm/contrib/backo2.d.ts +12 -0
  499. package/node_modules/socket.io-client/build/esm/contrib/backo2.js +66 -0
  500. package/node_modules/socket.io-client/build/esm/index.d.ts +29 -0
  501. package/node_modules/socket.io-client/build/esm/index.js +58 -0
  502. package/node_modules/socket.io-client/build/esm/manager.d.ts +295 -0
  503. package/node_modules/socket.io-client/build/esm/manager.js +367 -0
  504. package/node_modules/socket.io-client/build/esm/on.d.ts +2 -0
  505. package/node_modules/socket.io-client/build/esm/on.js +6 -0
  506. package/node_modules/socket.io-client/build/esm/package.json +5 -0
  507. package/node_modules/socket.io-client/build/esm/socket.d.ts +593 -0
  508. package/node_modules/socket.io-client/build/esm/socket.js +880 -0
  509. package/node_modules/socket.io-client/build/esm/url.d.ts +33 -0
  510. package/node_modules/socket.io-client/build/esm/url.js +59 -0
  511. package/node_modules/socket.io-client/build/esm-debug/browser-entrypoint.d.ts +2 -0
  512. package/node_modules/socket.io-client/build/esm-debug/browser-entrypoint.js +2 -0
  513. package/node_modules/socket.io-client/build/esm-debug/contrib/backo2.d.ts +12 -0
  514. package/node_modules/socket.io-client/build/esm-debug/contrib/backo2.js +66 -0
  515. package/node_modules/socket.io-client/build/esm-debug/index.d.ts +29 -0
  516. package/node_modules/socket.io-client/build/esm-debug/index.js +62 -0
  517. package/node_modules/socket.io-client/build/esm-debug/manager.d.ts +295 -0
  518. package/node_modules/socket.io-client/build/esm-debug/manager.js +386 -0
  519. package/node_modules/socket.io-client/build/esm-debug/on.d.ts +2 -0
  520. package/node_modules/socket.io-client/build/esm-debug/on.js +6 -0
  521. package/node_modules/socket.io-client/build/esm-debug/package.json +5 -0
  522. package/node_modules/socket.io-client/build/esm-debug/socket.d.ts +593 -0
  523. package/node_modules/socket.io-client/build/esm-debug/socket.js +902 -0
  524. package/node_modules/socket.io-client/build/esm-debug/url.d.ts +33 -0
  525. package/node_modules/socket.io-client/build/esm-debug/url.js +63 -0
  526. package/node_modules/socket.io-client/dist/socket.io.esm.min.js +7 -0
  527. package/node_modules/socket.io-client/dist/socket.io.esm.min.js.map +1 -0
  528. package/node_modules/socket.io-client/dist/socket.io.js +4955 -0
  529. package/node_modules/socket.io-client/dist/socket.io.js.map +1 -0
  530. package/node_modules/socket.io-client/dist/socket.io.min.js +7 -0
  531. package/node_modules/socket.io-client/dist/socket.io.min.js.map +1 -0
  532. package/node_modules/socket.io-client/dist/socket.io.msgpack.min.js +7 -0
  533. package/node_modules/socket.io-client/dist/socket.io.msgpack.min.js.map +1 -0
  534. package/node_modules/socket.io-client/package.json +101 -0
  535. package/node_modules/socket.io-parser/LICENSE +20 -0
  536. package/node_modules/socket.io-parser/Readme.md +81 -0
  537. package/node_modules/socket.io-parser/build/cjs/binary.d.ts +20 -0
  538. package/node_modules/socket.io-parser/build/cjs/binary.js +87 -0
  539. package/node_modules/socket.io-parser/build/cjs/index.d.ts +91 -0
  540. package/node_modules/socket.io-parser/build/cjs/index.js +359 -0
  541. package/node_modules/socket.io-parser/build/cjs/is-binary.d.ts +7 -0
  542. package/node_modules/socket.io-parser/build/cjs/is-binary.js +54 -0
  543. package/node_modules/socket.io-parser/build/cjs/package.json +3 -0
  544. package/node_modules/socket.io-parser/build/esm/binary.d.ts +20 -0
  545. package/node_modules/socket.io-parser/build/esm/binary.js +83 -0
  546. package/node_modules/socket.io-parser/build/esm/index.d.ts +91 -0
  547. package/node_modules/socket.io-parser/build/esm/index.js +348 -0
  548. package/node_modules/socket.io-parser/build/esm/is-binary.d.ts +7 -0
  549. package/node_modules/socket.io-parser/build/esm/is-binary.js +50 -0
  550. package/node_modules/socket.io-parser/build/esm/package.json +3 -0
  551. package/node_modules/socket.io-parser/build/esm-debug/binary.d.ts +20 -0
  552. package/node_modules/socket.io-parser/build/esm-debug/binary.js +83 -0
  553. package/node_modules/socket.io-parser/build/esm-debug/index.d.ts +91 -0
  554. package/node_modules/socket.io-parser/build/esm-debug/index.js +353 -0
  555. package/node_modules/socket.io-parser/build/esm-debug/is-binary.d.ts +7 -0
  556. package/node_modules/socket.io-parser/build/esm-debug/is-binary.js +50 -0
  557. package/node_modules/socket.io-parser/build/esm-debug/package.json +3 -0
  558. package/node_modules/socket.io-parser/package.json +44 -0
  559. package/node_modules/ws/LICENSE +20 -0
  560. package/node_modules/ws/README.md +548 -0
  561. package/node_modules/ws/browser.js +8 -0
  562. package/node_modules/ws/index.js +13 -0
  563. package/node_modules/ws/lib/buffer-util.js +131 -0
  564. package/node_modules/ws/lib/constants.js +18 -0
  565. package/node_modules/ws/lib/event-target.js +292 -0
  566. package/node_modules/ws/lib/extension.js +203 -0
  567. package/node_modules/ws/lib/limiter.js +55 -0
  568. package/node_modules/ws/lib/permessage-deflate.js +528 -0
  569. package/node_modules/ws/lib/receiver.js +706 -0
  570. package/node_modules/ws/lib/sender.js +602 -0
  571. package/node_modules/ws/lib/stream.js +161 -0
  572. package/node_modules/ws/lib/subprotocol.js +62 -0
  573. package/node_modules/ws/lib/validation.js +152 -0
  574. package/node_modules/ws/lib/websocket-server.js +550 -0
  575. package/node_modules/ws/lib/websocket.js +1388 -0
  576. package/node_modules/ws/package.json +69 -0
  577. package/node_modules/ws/wrapper.mjs +8 -0
  578. package/node_modules/xmlhttprequest-ssl/LICENSE +22 -0
  579. package/node_modules/xmlhttprequest-ssl/README.md +67 -0
  580. package/node_modules/xmlhttprequest-ssl/lib/XMLHttpRequest.js +689 -0
  581. package/node_modules/xmlhttprequest-ssl/package.json +40 -0
  582. package/package.json +34 -4
  583. package/public-api.md +85 -23
package/dist/index.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/auth-login.ts","../src/rest.ts","../src/resources/auth.ts","../src/resources/headless.ts","../src/shared/projection/helpers.ts","../src/schemas/message.ts","../src/shared/projection/state.ts","../src/shared/projection/builder.ts","../src/shared/projection/history.ts","../src/resources/sessions.ts","../src/commands/registry.ts","../src/session/events.ts","../src/schemas/message-utils.ts","../src/session/state.ts","../src/session/agent-session.ts","../src/session/hub.ts","../src/socket.ts","../src/auth.ts","../src/version.ts","../src/blade-client.ts","../src/commands/protocol.ts","../src/commands/embedded.ts","../src/schemas/session.ts","../src/schemas/solution.ts","../src/schemas/task.ts"],"sourcesContent":["import type { BladeClient } from \"./blade-client\"\n\n/**\n * 弹窗授权登录,与 Chrome 扩展共用同一套后端授权内核(见 server/routes/sdk_auth.py):\n *\n * 1. 弹窗打开 `GET /api/auth/sdk/authorize?client_origin=<本页 origin>&state=<随机值>`\n * 2. 用户点击「许可授权」→ 回调页把 `{ type: \"blade-agent:sdk-auth\", state, code }`\n * postMessage 定向发回本页(code 一次性、5 分钟有效)\n * 3. SDK 用 `POST /api/auth/sdk/token`(code + state + client_origin)换取 PAT,\n * 存储并热挂载(REST 与 Socket.IO 同时生效)\n */\n\nexport interface LoginOptions {\n /** 弹窗尺寸,默认 480x640。 */\n width?: number\n height?: number\n /** 超时毫秒数,默认 5 分钟(与后端授权码有效期一致)。 */\n timeoutMs?: number\n}\n\nexport interface LoginResult {\n token: string\n user?: { id?: string; username?: string; display_name?: string }\n}\n\n/** 回调页 postMessage 的消息契约(对齐后端 _completion_page)。 */\ninterface AuthCallbackMessage {\n type: \"blade-agent:sdk-auth\"\n version: number\n status: \"success\" | \"denied\" | \"error\"\n state: string\n code?: string\n error?: string\n}\n\nfunction isAuthCallbackMessage(value: unknown): value is AuthCallbackMessage {\n return (\n typeof value === \"object\" &&\n value !== null &&\n (value as Record<string, unknown>).type === \"blade-agent:sdk-auth\"\n )\n}\n\nfunction randomState(): string {\n const bytes = new Uint8Array(24)\n crypto.getRandomValues(bytes)\n return Array.from(bytes, (b) => b.toString(16).padStart(2, \"0\")).join(\"\")\n}\n\nexport type TokenStorageMode = \"local\" | \"memory\"\n\nconst storageKeyFor = (baseUrl: string) => `blade-sdk-token:${baseUrl}`\n\nexport function readStoredToken(baseUrl: string): string | null {\n if (typeof localStorage === \"undefined\") return null\n try {\n return localStorage.getItem(storageKeyFor(baseUrl))\n } catch {\n return null\n }\n}\n\nexport function writeStoredToken(baseUrl: string, token: string | null, mode: TokenStorageMode): void {\n if (mode !== \"local\" || typeof localStorage === \"undefined\") return\n try {\n if (token) {\n localStorage.setItem(storageKeyFor(baseUrl), token)\n } else {\n localStorage.removeItem(storageKeyFor(baseUrl))\n }\n } catch {\n // 隐私模式等场景写入失败时静默降级为内存态\n }\n}\n\nexport async function loginWithPopup(\n client: BladeClient,\n options: LoginOptions = {},\n): Promise<LoginResult> {\n if (typeof window === \"undefined\") {\n throw new Error(\"client.auth.login() 只能在浏览器中调用;Node.js 场景请直接传入 token。\")\n }\n // file:// 打开的本地 HTML(智能体生成的交付物被双击打开)没有可声明的\n // origin,按 opaque(\"null\")走:授权页会向用户展示「本地文件页面」,\n // 回传的一次性 code 由 \"*\" 投递给本窗口,state 校验不变。\n const rawOrigin = window.location.origin\n const clientOrigin = /^https?:\\/\\//.test(rawOrigin) ? rawOrigin : \"null\"\n\n const width = options.width ?? 480\n const height = options.height ?? 640\n const left = Math.max(0, (window.screen.width - width) / 2)\n const top = Math.max(0, (window.screen.height - height) / 2)\n const state = randomState()\n const authorizeUrl = new URL(\n \"/api/auth/sdk/authorize\",\n client.options.baseUrl || window.location.origin,\n )\n authorizeUrl.searchParams.set(\"client_origin\", clientOrigin)\n authorizeUrl.searchParams.set(\"state\", state)\n\n const popup = window.open(\n authorizeUrl.toString(),\n \"blade-sdk-login\",\n `popup=yes,width=${width},height=${height},left=${left},top=${top}`,\n )\n if (!popup) {\n throw new Error(\"登录弹窗被浏览器拦截了。请允许本站打开弹窗后重试。\")\n }\n\n const expectedOrigin = new URL(client.options.baseUrl || window.location.origin).origin\n\n return new Promise<LoginResult>((resolve, reject) => {\n const timeoutMs = options.timeoutMs ?? 5 * 60 * 1000\n let settled = false\n\n const cleanup = () => {\n window.removeEventListener(\"message\", onMessage)\n globalThis.clearInterval(closeWatcher)\n globalThis.clearTimeout(timeoutHandle)\n }\n const settle = (fn: () => void) => {\n if (settled) return\n settled = true\n cleanup()\n fn()\n }\n\n const onMessage = (event: MessageEvent) => {\n // 回调页部署在后端域名下,只信任来自后端 origin、且 state 匹配的消息\n if (event.origin !== expectedOrigin) return\n if (!isAuthCallbackMessage(event.data)) return\n if (event.data.state !== state) return\n const message = event.data\n try {\n popup.close()\n } catch {\n // 跨域限制下 close 可能失败,忽略\n }\n if (message.status === \"denied\") {\n settle(() => reject(new Error(\"你取消了授权,未完成登录。\")))\n return\n }\n if (message.status !== \"success\" || !message.code) {\n settle(() => reject(new Error(message.error || \"登录失败,未取得授权码。\")))\n return\n }\n // code 一次性、5 分钟有效;连同 state 与 client_origin 一起换取 PAT\n client\n .json<{\n access_token: string\n user?: LoginResult[\"user\"]\n }>(\"POST\", \"/api/auth/sdk/token\", {\n code: message.code,\n state,\n client_origin: clientOrigin,\n })\n .then((response) => {\n settle(() => resolve({ token: response.access_token, user: response.user }))\n })\n .catch((error) => {\n settle(() =>\n reject(error instanceof Error ? error : new Error(\"授权码换取令牌失败,请重试。\")),\n )\n })\n }\n\n const closeWatcher = globalThis.setInterval(() => {\n if (popup.closed && !settled) {\n // 回调消息可能仍在路上,稍等一拍再判定为用户关窗\n globalThis.setTimeout(() => {\n settle(() => reject(new Error(\"登录窗口已关闭,未完成授权。\")))\n }, 400)\n }\n }, 500)\n\n const timeoutHandle = globalThis.setTimeout(() => {\n settle(() => reject(new Error(\"登录超时,请重试。\")))\n }, timeoutMs)\n\n window.addEventListener(\"message\", onMessage)\n })\n}\n","const DOCS_URL = \"https://blade-hq.github.io/public-skills/\"\n\nexport class BladeApiError extends Error {\n readonly response: Response\n readonly status: number\n readonly statusText: string\n\n constructor(response: Response, message?: string) {\n super(message ?? `请求失败(${response.status} ${response.statusText})`)\n this.name = \"BladeApiError\"\n this.response = response\n this.status = response.status\n this.statusText = response.statusText\n }\n}\n\n/**\n * 从 FastAPI 风格的错误响应中提取 detail 字段,作为用户可读的中文错误文案。\n * 失败时返回 undefined,调用方会回退到默认提示。\n */\nexport async function extractErrorDetail(response: Response): Promise<string | undefined> {\n try {\n const cloned = response.clone()\n const contentType = cloned.headers.get(\"content-type\") ?? \"\"\n if (contentType.includes(\"application/json\")) {\n const data = (await cloned.json()) as { detail?: unknown }\n const detail = data?.detail\n if (typeof detail === \"string\" && detail.trim()) return detail\n if (Array.isArray(detail) && detail.length > 0) {\n const first = detail[0] as { msg?: unknown }\n if (first && typeof first.msg === \"string\") return first.msg\n }\n } else {\n const text = (await cloned.text()).trim()\n if (text) return text\n }\n } catch {\n // 读取失败时忽略,使用默认提示\n }\n return undefined\n}\n\n/** 401/403 补充\"怎么办\"的指引,避免初级开发者对着裸状态码发呆。 */\nexport function decorateAuthError(error: unknown): unknown {\n if (!(error instanceof BladeApiError)) return error\n if (error.status === 401) {\n error.message =\n `${error.message}(未登录或凭证已失效。浏览器场景调用 client.auth.login() 弹窗登录,` +\n `自动化场景在 new BladeClient({ token }) 传入 PAT。接入指南:${DOCS_URL})`\n } else if (error.status === 403) {\n error.message = `${error.message}(当前账号无权访问该资源。接入指南:${DOCS_URL})`\n }\n return error\n}\n\nexport type HttpMethod = \"DELETE\" | \"GET\" | \"PATCH\" | \"POST\" | \"PUT\" | (string & {})\n\nexport interface BladeFetchInit {\n body?: BodyInit | null\n credentials?: RequestCredentials\n expectOk?: boolean\n headers?: HeadersInit\n signal?: AbortSignal | null\n}\n","import type { BladeClient } from \"../blade-client\"\nimport type { LoginOptions, LoginResult } from \"../auth-login\"\n\nexport interface UserInfo {\n id: string\n username: string\n display_name?: string | null\n avatar_url: string | null\n token: string\n auth_type: \"casdoor\"\n is_admin?: boolean\n}\n\nexport interface ProvidersResponse {\n providers: Array<{\n name: string\n authorize_url: string\n }>\n password_enabled: boolean\n}\n\nexport class AuthResource {\n constructor(private client: BladeClient) {}\n\n /**\n * 弹窗授权登录(浏览器专用):弹出后端授权页,用户点击\"许可授权\"后\n * 自动取得 PAT 并热挂载到当前 client。等价于 client.login()。\n */\n login(options?: LoginOptions): Promise<LoginResult> {\n return this.client.login(options)\n }\n\n /** 清除 login() 存储的令牌。 */\n logoutToken(): void {\n this.client.logoutToken()\n }\n\n getProviders(): Promise<ProvidersResponse> {\n return this.client.json(\"GET\", \"/api/auth/providers\")\n }\n\n getMe(): Promise<UserInfo> {\n return this.client.json(\"GET\", \"/api/auth/me\")\n }\n\n logout(): Promise<{ logout_url: string }> {\n return this.client.json(\"POST\", \"/api/auth/logout\")\n }\n}\n","import type { BladeClient } from \"../blade-client\"\nimport type { ChatEndPayload, ChatSendPayload, ChatStartPayload, SystemErrorPayload } from \"../types/socket-events\"\n\nexport type JsonSchemaObject = Record<string, unknown>\n\nexport interface HeadlessRunOptions {\n schema?: JsonSchemaObject | null\n model?: string | null\n timeoutMs?: number\n}\n\nexport interface HeadlessRunInSessionResult<T = unknown> {\n session_id: string\n chat_run_id: string | null\n result: T | string\n}\n\nexport class HeadlessError extends Error {\n constructor(\n message: string,\n readonly detail?: unknown,\n ) {\n super(message)\n this.name = \"HeadlessError\"\n }\n}\n\nconst SYSTEM_ERROR_CHAT_END_GRACE_MS = 1_000\n\nexport class HeadlessResource {\n constructor(private client: BladeClient) {}\n\n async run<T = unknown>(prompt: string, options: HeadlessRunOptions & { schema: JsonSchemaObject }): Promise<T>\n async run(prompt: string, options?: HeadlessRunOptions): Promise<string>\n async run<T = unknown>(prompt: string, options: HeadlessRunOptions = {}): Promise<T | string> {\n const { session_id } = await this.client.sessions.createSessionWithRequest({\n intent: prompt,\n model: options.model ?? null,\n })\n return this.runTracked<T>(session_id, prompt, options, false) as Promise<T | string>\n }\n\n async runInSession<T = unknown>(\n sessionId: string,\n prompt: string,\n options: HeadlessRunOptions & { schema: JsonSchemaObject },\n ): Promise<T>\n async runInSession(sessionId: string, prompt: string, options?: HeadlessRunOptions): Promise<string>\n async runInSession<T = unknown>(\n sessionId: string,\n prompt: string,\n options: HeadlessRunOptions = {},\n ): Promise<T | string> {\n return this.runTracked<T>(sessionId, prompt, options, false) as Promise<T | string>\n }\n\n async runWithSession<T = unknown>(\n prompt: string,\n options: HeadlessRunOptions & { schema: JsonSchemaObject },\n ): Promise<HeadlessRunInSessionResult<T>>\n async runWithSession(prompt: string, options?: HeadlessRunOptions): Promise<HeadlessRunInSessionResult<string>>\n async runWithSession<T = unknown>(\n prompt: string,\n options: HeadlessRunOptions = {},\n ): Promise<HeadlessRunInSessionResult<T>> {\n const { session_id } = await this.client.sessions.createSessionWithRequest({\n intent: prompt,\n model: options.model ?? null,\n })\n return this.runTracked<T>(session_id, prompt, options, true) as Promise<HeadlessRunInSessionResult<T>>\n }\n\n private async runTracked<T = unknown>(\n sessionId: string,\n prompt: string,\n options: HeadlessRunOptions,\n returnEnvelope: boolean,\n ): Promise<T | string | HeadlessRunInSessionResult<T>> {\n const timeoutMs = options.timeoutMs ?? 300_000\n const session_id = sessionId\n const socket = this.client.socket()\n await ensureSocketConnected(socket, timeoutMs, { session_id })\n\n return new Promise<T | string | HeadlessRunInSessionResult<T>>((resolve, reject) => {\n let settled = false\n let stopSent = false\n let started = false\n let chatRunId: string | null = null\n let systemErrorTimeout: ReturnType<typeof setTimeout> | null = null\n const timeout = setTimeout(() => {\n fail(new HeadlessError(`headless run timed out after ${timeoutMs}ms`, { session_id, chat_run_id: chatRunId }))\n }, timeoutMs)\n\n const cleanup = (sendStop: boolean) => {\n clearTimeout(timeout)\n if (systemErrorTimeout) {\n clearTimeout(systemErrorTimeout)\n systemErrorTimeout = null\n }\n socket.off(\"chat:start\", onChatStart)\n socket.off(\"chat:end\", onChatEnd)\n socket.off(\"system:error\", onSystemError)\n if (sendStop && !stopSent) {\n stopSent = true\n socket.emit(\"chat:stop\", { session_id }, () => undefined)\n }\n socket.emit(\"session:unsubscribe\", { session_id })\n }\n\n const finish = (value: T | string) => {\n if (settled) return\n settled = true\n cleanup(false)\n if (returnEnvelope) {\n resolve({ session_id, chat_run_id: chatRunId, result: value })\n return\n }\n resolve(value)\n }\n const fail = (error: unknown) => {\n if (settled) return\n settled = true\n cleanup(true)\n reject(error)\n }\n const failWithoutStop = (error: unknown) => {\n if (settled) return\n settled = true\n cleanup(false)\n reject(error)\n }\n const rejectAfterChatEnd = (error: unknown) => {\n if (settled) return\n settled = true\n cleanup(false)\n reject(error)\n }\n\n function onChatStart(payload: ChatStartPayload) {\n if (payload.session_id && payload.session_id !== session_id) return\n started = true\n }\n\n function onSystemError(payload: SystemErrorPayload) {\n if (payload.session_id !== session_id) return\n if (!started) {\n failWithoutStop(new HeadlessError(payload.message || \"headless run failed\", {\n session_id,\n chat_run_id: chatRunId,\n event: payload,\n }))\n return\n }\n if (systemErrorTimeout) {\n clearTimeout(systemErrorTimeout)\n }\n systemErrorTimeout = setTimeout(() => {\n systemErrorTimeout = null\n fail(new HeadlessError(payload.message || \"headless run failed\", {\n session_id,\n chat_run_id: chatRunId,\n event: payload,\n }))\n }, SYSTEM_ERROR_CHAT_END_GRACE_MS)\n }\n\n function onChatEnd(payload: ChatEndPayload) {\n if (payload.session_id && payload.session_id !== session_id) return\n chatRunId = typeof payload.chat_run_id === \"string\" ? payload.chat_run_id : chatRunId\n const result = payload.result\n if (payload.status === \"failed\") {\n rejectAfterChatEnd(new HeadlessError(errorMessageFromResult(result) ?? \"headless run failed\", {\n session_id,\n chat_run_id: chatRunId,\n event: payload,\n }))\n return\n }\n try {\n finish(normalizeResult<T>(result, Boolean(options.schema)))\n } catch (error) {\n rejectAfterChatEnd(error)\n }\n }\n\n socket.on(\"chat:start\", onChatStart)\n socket.on(\"chat:end\", onChatEnd)\n socket.on(\"system:error\", onSystemError)\n socket.emit(\"session:subscribe\", { session_id, event_format: \"raw\" })\n socket.emit(\"chat:send\", {\n session_id,\n message: prompt as unknown as ChatSendPayload[\"message\"],\n headless: true,\n output_schema: options.schema ?? null,\n model: options.model ?? null,\n })\n })\n }\n}\n\nfunction normalizeResult<T>(result: unknown, hasSchema: boolean): T | string {\n if (!isRecord(result)) {\n throw new HeadlessError(\"headless run finished without a result\", result)\n }\n const errMsg = typeof result.err_msg === \"string\" ? result.err_msg : \"\"\n if (errMsg) {\n throw new HeadlessError(errMsg, result)\n }\n if (!hasSchema) {\n const text = result.result\n return typeof text === \"string\" ? text : String(text ?? \"\")\n }\n const { err_msg: _errMsg, ...businessResult } = result\n return businessResult as T\n}\n\nfunction errorMessageFromResult(result: unknown): string | null {\n if (isRecord(result) && typeof result.err_msg === \"string\" && result.err_msg) {\n return result.err_msg\n }\n return null\n}\n\nfunction isRecord(value: unknown): value is Record<string, unknown> {\n return typeof value === \"object\" && value !== null && !Array.isArray(value)\n}\n\nfunction ensureSocketConnected(\n socket: ReturnType<BladeClient[\"socket\"]>,\n timeoutMs: number,\n detail: Record<string, unknown>,\n): Promise<void> {\n if (socket.connected) {\n return Promise.resolve()\n }\n return new Promise((resolve, reject) => {\n let settled = false\n const timeout = setTimeout(() => {\n finish(() => reject(new HeadlessError(`socket connection timed out after ${timeoutMs}ms`, detail)))\n }, timeoutMs)\n const onConnect = () => finish(resolve)\n const onConnectError = (error: unknown) => {\n finish(() => reject(new HeadlessError(\"socket connection failed\", { ...detail, event: error })))\n }\n const finish = (callback: () => void) => {\n if (settled) return\n settled = true\n clearTimeout(timeout)\n socket.off(\"connect\", onConnect)\n socket.off(\"connect_error\", onConnectError)\n callback()\n }\n socket.on(\"connect\", onConnect)\n socket.on(\"connect_error\", onConnectError)\n socket.connect()\n })\n}\n","import type {\n ContentBlock,\n PendingQuestionRef,\n ToolCallProjection,\n TurnProjection,\n} from \"../../schemas/projection\"\nimport type { TurnState } from \"./state\"\n\n// --- Tool call upsert ---\n\nexport function upsertToolCall(\n state: TurnState,\n toolCallId: string,\n toolName: string,\n displayName: string,\n args: string,\n): void {\n if (!toolCallId) return\n\n let found = false\n for (let i = 0; i < state.toolCalls.length; i++) {\n if (state.toolCalls[i].id !== toolCallId) continue\n const tc = state.toolCalls[i]\n state.toolCalls[i] = {\n ...tc,\n tool_name: toolName || tc.tool_name,\n display_name: displayName || tc.display_name,\n arguments: args || tc.arguments,\n }\n found = true\n break\n }\n if (!found) {\n state.toolCalls.push({\n id: toolCallId,\n tool_name: toolName,\n display_name: displayName,\n arguments: args,\n status: \"pending\",\n })\n }\n\n let blockFound = false\n for (let i = 0; i < state.blocks.length; i++) {\n const b = state.blocks[i]\n if (b.type !== \"tool_use\" || b.tool_call_id !== toolCallId) continue\n state.blocks[i] = {\n ...b,\n content: args || b.content,\n tool_name: toolName || b.tool_name,\n display_name: displayName || b.display_name,\n }\n blockFound = true\n break\n }\n if (!blockFound) {\n state.blocks.push({\n type: \"tool_use\",\n content: args,\n tool_call_id: toolCallId,\n tool_name: toolName || null,\n display_name: displayName || null,\n })\n }\n}\n\n// --- Tool result application ---\n\nexport function applyToolResult(\n state: TurnState,\n toolCallId: string,\n result: unknown,\n status: ToolCallProjection[\"status\"],\n durationMs: number | null,\n sourceLoop: { loop_name: string; description: string } | null,\n): void {\n let toolName = \"\"\n let displayName = \"\"\n let finalResult = result\n\n for (let i = 0; i < state.toolCalls.length; i++) {\n const tc = state.toolCalls[i]\n if (tc.id !== toolCallId) continue\n\n if (typeof result === \"string\") {\n finalResult = maybeEnrichAskUserResult(tc.tool_name, result, sourceLoop)\n }\n\n const update: Partial<ToolCallProjection> = { status, result: finalResult }\n if (durationMs != null) update.duration_ms = durationMs\n state.toolCalls[i] = { ...tc, ...update }\n toolName = tc.tool_name\n displayName = tc.display_name\n break\n }\n\n upsertToolResultBlock(state, toolCallId, finalResult, toolName, displayName)\n}\n\nexport function appendToolResultDelta(\n state: TurnState,\n toolCallId: string,\n delta: string,\n): void {\n if (!toolCallId || !delta) return\n\n let toolName = \"\"\n let displayName = \"\"\n let currentResult = \"\"\n\n for (let i = 0; i < state.toolCalls.length; i++) {\n const tc = state.toolCalls[i]\n if (tc.id !== toolCallId) continue\n toolName = tc.tool_name\n displayName = tc.display_name\n if (typeof tc.result === \"string\") currentResult = tc.result\n state.toolCalls[i] = { ...tc, result: currentResult + delta }\n break\n }\n\n for (const block of state.blocks) {\n if (block.type !== \"tool_result\" || block.tool_call_id !== toolCallId) continue\n if (typeof block.content === \"string\") currentResult = block.content\n break\n }\n\n upsertToolResultBlock(state, toolCallId, currentResult + delta, toolName, displayName)\n}\n\nfunction upsertToolResultBlock(\n state: TurnState,\n toolCallId: string,\n content: unknown,\n toolName: string,\n displayName: string,\n): void {\n for (let i = 0; i < state.blocks.length; i++) {\n const block = state.blocks[i]\n if (block.type !== \"tool_result\" || block.tool_call_id !== toolCallId) continue\n state.blocks[i] = {\n ...block,\n content,\n tool_name: toolName || block.tool_name,\n display_name: displayName || block.display_name,\n }\n return\n }\n\n state.blocks.push({\n type: \"tool_result\",\n content,\n tool_call_id: toolCallId,\n tool_name: toolName || null,\n display_name: displayName || null,\n })\n}\n\n// --- Text block append ---\n\nexport function appendTextBlock(\n state: TurnState,\n blockType: ContentBlock[\"type\"],\n content: unknown,\n): void {\n if (content == null || content === \"\") return\n const text = String(content)\n const lastBlock = state.blocks[state.blocks.length - 1]\n if (lastBlock && lastBlock.type === blockType && typeof lastBlock.content === \"string\") {\n state.blocks[state.blocks.length - 1] = {\n ...lastBlock,\n content: lastBlock.content + text,\n }\n return\n }\n state.blocks.push({ type: blockType, content: text })\n}\n\n// --- Tool call arguments append ---\n\nexport function appendToolCallArguments(\n state: TurnState,\n toolCallId: string,\n delta: string,\n): void {\n let newArgs = \"\"\n for (let i = 0; i < state.toolCalls.length; i++) {\n const tc = state.toolCalls[i]\n if (tc.id === toolCallId) {\n newArgs = tc.arguments + delta\n state.toolCalls[i] = { ...tc, arguments: newArgs }\n break\n }\n }\n if (!newArgs) return\n\n for (let i = 0; i < state.blocks.length; i++) {\n const b = state.blocks[i]\n if (b.type === \"tool_use\" && b.tool_call_id === toolCallId) {\n state.blocks[i] = { ...b, content: newArgs }\n break\n }\n }\n}\n\n// --- AskUserQuestion enrichment ---\n\nfunction maybeEnrichAskUserResult(\n toolName: string,\n result: string,\n sourceLoop: { loop_name: string; description: string } | null,\n): string {\n if (!sourceLoop) return result\n const normalized = toolName.includes(\":\") ? toolName.split(\":\").pop()! : toolName\n if (normalized !== \"AskUserQuestion\") return result\n try {\n const payload = JSON.parse(result)\n if (typeof payload !== \"object\" || payload === null) return result\n payload.source_loop = sourceLoop\n return JSON.stringify(payload)\n } catch {\n return result\n }\n}\n\n// --- System notification ---\n\nexport function buildSystemNotificationTurn(\n sequence: number,\n turnId: string,\n loopId: string,\n notificationType: string,\n status: string,\n title: string,\n detail: string | null,\n metadata: Record<string, unknown>,\n): TurnProjection {\n return {\n id: turnId,\n sequence,\n turn_id: turnId,\n loop_id: loopId,\n kind: \"message\",\n role: \"system\",\n status: \"completed\",\n blocks: [\n {\n type: \"system_notification\",\n content: {\n notification_type: notificationType,\n status,\n title,\n detail,\n metadata,\n },\n },\n ],\n tool_calls: [],\n model: null,\n usage: null,\n duration_ms: 0,\n }\n}\n\nexport function buildSystemNotificationBlock(\n notificationType: string,\n status: string,\n title: string,\n detail: string | null,\n metadata: Record<string, unknown>,\n): ContentBlock {\n return {\n type: \"system_notification\",\n content: {\n notification_type: notificationType,\n status,\n title,\n detail,\n metadata,\n },\n }\n}\n\n// --- Marker turn ---\n\nexport function buildMarkerTurn(\n sequence: number,\n turnId: string,\n loopId: string,\n blockType: ContentBlock[\"type\"],\n content: unknown,\n): TurnProjection {\n return {\n id: turnId,\n sequence,\n turn_id: turnId,\n loop_id: loopId,\n kind: \"message\",\n role: \"assistant\",\n status: \"completed\",\n blocks: [{ type: blockType, content }],\n tool_calls: [],\n model: null,\n usage: null,\n duration_ms: 0,\n }\n}\n\n// --- Compaction turn ---\n\nexport function buildCompactionTurn(\n sequence: number,\n compactionId: string,\n loopId: string,\n status: TurnProjection[\"status\"],\n data: Record<string, unknown>,\n): TurnProjection {\n const tokensBefore = asInt(data.tokens_before)\n const tokensAfter = asInt(data.tokens_after)\n let savedRatio: number | null = null\n if (tokensBefore && tokensBefore > 0 && tokensAfter != null) {\n savedRatio = 1 - tokensAfter / tokensBefore\n } else {\n savedRatio = asFloat(data.saved_ratio)\n }\n let archivedCount = asInt(data.archived_count)\n if (archivedCount == null && Array.isArray(data.archived_files)) {\n archivedCount = data.archived_files.length\n }\n\n const content = data.content\n const summaryFull = compactionSummaryFull(content)\n const summaryPreview = summaryFull\n ? summaryFull\n .split(\"\\n\")\n .map((l) => l.trim())\n .filter(Boolean)\n .join(\" \")\n .slice(0, 200)\n : null\n\n return {\n id: `compaction:${compactionId}`,\n sequence,\n turn_id: `compaction:${compactionId}`,\n loop_id: loopId,\n kind: \"compaction\",\n role: \"system\",\n status,\n blocks: [],\n tool_calls: [],\n model: null,\n usage: null,\n duration_ms: 0,\n compaction_id: compactionId,\n summary_preview: summaryPreview,\n summary_full: summaryFull,\n archived_count: archivedCount,\n tokens_before: tokensBefore,\n tokens_after: tokensAfter,\n saved_ratio: savedRatio,\n trigger: asTrigger(data.trigger),\n failure_reason:\n typeof data.reason === \"string\" && data.reason ? (data.reason as string) : null,\n fallback_applied: typeof data.fallback_applied === \"boolean\" ? data.fallback_applied : null,\n }\n}\n\nfunction compactionSummaryFull(content: unknown): string | null {\n const text = String(content ?? \"\")\n if (!text) return null\n const cleaned = text\n .replace(\"<compaction-summary>\", \"\")\n .replace(\"</compaction-summary>\", \"\")\n .replace(/\\r\\n/g, \"\\n\")\n .replace(/\\r/g, \"\\n\")\n .trim()\n return cleaned || null\n}\n\nfunction asInt(value: unknown): number | null {\n if (typeof value === \"boolean\") return null\n if (typeof value === \"number\") return Math.trunc(value)\n return null\n}\n\nfunction asFloat(value: unknown): number | null {\n if (typeof value === \"boolean\") return null\n if (typeof value === \"number\") return value\n return null\n}\n\nfunction asTrigger(value: unknown): \"auto\" | \"manual\" | \"forced_retry\" | null {\n if (value === \"auto\" || value === \"manual\" || value === \"forced_retry\") return value\n return null\n}\n\n// --- Child pause helpers ---\n\nexport interface ChildPauseInfo {\n parentLoopName: string\n parentToolCallId: string\n childLoopName: string\n childToolCallId: string\n description: string\n}\n\nexport function setToolCallStatus(\n turn: TurnState | TurnProjection | null | undefined,\n toolCallId: string,\n status: ToolCallProjection[\"status\"],\n result: unknown,\n pendingQuestionRef: PendingQuestionRef | null,\n): void {\n if (!turn || !toolCallId) return\n const toolCalls = \"toolCalls\" in turn ? turn.toolCalls : turn.tool_calls\n for (let i = 0; i < toolCalls.length; i++) {\n if (toolCalls[i].id !== toolCallId) continue\n toolCalls[i] = {\n ...toolCalls[i],\n status,\n result,\n pending_question_ref: pendingQuestionRef,\n }\n return\n }\n}\n\nexport function applyAskUserPauseToTurn(\n turn: TurnState | TurnProjection | null | undefined,\n pauseToolData: Record<string, unknown>,\n toolCallId: string,\n childLoopName: string,\n description: string,\n displayNameResolver: (name: string) => string,\n): void {\n if (!turn || !toolCallId) return\n\n const sourceLoop = childLoopName\n ? { loop_name: childLoopName, description }\n : null\n const toolName = String(pauseToolData.name ?? \"AskUserQuestion\")\n const args = JSON.stringify(pauseToolData.arguments ?? {})\n const result = askUserResultFromPausePayload(pauseToolData, sourceLoop)\n\n const isTurnState = \"toolCalls\" in turn\n const toolCalls = isTurnState ? turn.toolCalls : turn.tool_calls\n const blocks = turn.blocks\n\n // upsert tool call\n const displayName = displayNameResolver(toolName)\n let found = false\n for (let i = 0; i < toolCalls.length; i++) {\n if (toolCalls[i].id !== toolCallId) continue\n toolCalls[i] = {\n ...toolCalls[i],\n tool_name: toolName || toolCalls[i].tool_name,\n display_name: displayName || toolCalls[i].display_name,\n arguments: args || toolCalls[i].arguments,\n }\n found = true\n break\n }\n if (!found) {\n toolCalls.push({\n id: toolCallId,\n tool_name: toolName,\n display_name: displayName,\n arguments: args,\n status: \"pending\",\n })\n }\n\n // upsert tool_use block\n let blockFound = false\n for (let i = 0; i < blocks.length; i++) {\n if (blocks[i].type !== \"tool_use\" || blocks[i].tool_call_id !== toolCallId) continue\n blocks[i] = { ...blocks[i], content: args, tool_name: toolName, display_name: displayName }\n blockFound = true\n break\n }\n if (!blockFound) {\n blocks.push({\n type: \"tool_use\",\n content: args,\n tool_call_id: toolCallId,\n tool_name: toolName,\n display_name: displayName,\n })\n }\n\n // set status\n setToolCallStatus(turn, toolCallId, \"awaiting_answer\", result, null)\n\n // upsert tool_result block\n let resultBlockFound = false\n for (let i = 0; i < blocks.length; i++) {\n if (blocks[i].type !== \"tool_result\" || blocks[i].tool_call_id !== toolCallId) continue\n blocks[i] = { ...blocks[i], content: result }\n resultBlockFound = true\n break\n }\n if (!resultBlockFound) {\n blocks.push({\n type: \"tool_result\",\n content: result,\n tool_call_id: toolCallId,\n tool_name: toolName,\n display_name: displayName,\n })\n }\n}\n\nexport function applyChildPauseToParent(\n parentTurn: TurnState | TurnProjection | null | undefined,\n parentToolCallId: string,\n childLoopName: string,\n childToolCallId: string,\n description: string,\n displayNameResolver: (name: string) => string,\n): void {\n if (!parentTurn || !parentToolCallId) return\n\n const toolCalls = \"toolCalls\" in parentTurn ? parentTurn.toolCalls : parentTurn.tool_calls\n const blocks = parentTurn.blocks\n\n const displayName = displayNameResolver(\"Agent\")\n let found = false\n for (let i = 0; i < toolCalls.length; i++) {\n if (toolCalls[i].id !== parentToolCallId) continue\n toolCalls[i] = {\n ...toolCalls[i],\n tool_name: \"Agent\",\n display_name: displayName || toolCalls[i].display_name,\n }\n found = true\n break\n }\n if (!found) {\n toolCalls.push({\n id: parentToolCallId,\n tool_name: \"Agent\",\n display_name: displayName,\n arguments: \"\",\n status: \"pending\",\n })\n }\n\n // upsert tool_use block\n let blockFound = false\n for (let i = 0; i < blocks.length; i++) {\n if (blocks[i].type !== \"tool_use\" || blocks[i].tool_call_id !== parentToolCallId) continue\n blockFound = true\n break\n }\n if (!blockFound) {\n blocks.push({\n type: \"tool_use\",\n content: \"\",\n tool_call_id: parentToolCallId,\n tool_name: \"Agent\",\n display_name: displayName,\n })\n }\n\n setToolCallStatus(parentTurn, parentToolCallId, \"awaiting_answer\", null, {\n child_loop_name: childLoopName,\n child_tool_call_id: childToolCallId,\n description: description || null,\n })\n}\n\nfunction askUserResultFromPausePayload(\n pauseToolData: Record<string, unknown>,\n sourceLoop: { loop_name: string; description: string } | null,\n): string {\n const args =\n typeof pauseToolData.arguments === \"object\" && pauseToolData.arguments !== null\n ? (pauseToolData.arguments as Record<string, unknown>)\n : {}\n const payload: Record<string, unknown> = { questions: args.questions ?? [] }\n if (sourceLoop) payload.source_loop = sourceLoop\n return JSON.stringify(payload)\n}\n\nexport function sourceLoopFor(\n loopId: string,\n loopDescriptions: Map<string, string>,\n): { loop_name: string; description: string } | null {\n if (loopId === \"root\") return null\n const description = loopDescriptions.get(loopId)\n if (!description) return null\n return { loop_name: loopId, description }\n}\n\nexport function normalizeChildPause(\n pausePayload: Record<string, unknown>,\n): {\n pauseToolData: Record<string, unknown>\n childLoopName: string\n childToolCallId: string\n description: string\n} {\n const rawPtd = pausePayload.pause_tool_data\n const pauseToolData: Record<string, unknown> =\n typeof rawPtd === \"object\" && rawPtd !== null\n ? { ...(rawPtd as Record<string, unknown>) }\n : { ...pausePayload }\n\n let sourceLoop = pauseToolData.source_loop as Record<string, unknown> | undefined\n if (typeof sourceLoop !== \"object\" || sourceLoop === null) {\n sourceLoop = pausePayload.source_loop as Record<string, unknown> | undefined\n }\n\n const childLoopName =\n String(pausePayload.child_loop_name ?? \"\") ||\n (typeof sourceLoop === \"object\" && sourceLoop ? String(sourceLoop.name ?? \"\") : \"\")\n\n const childToolCallId =\n String(\n pausePayload.child_pause_tool_call_id ?? pauseToolData.tool_call_id ?? \"\",\n )\n\n const description =\n typeof sourceLoop === \"object\" && sourceLoop ? String(sourceLoop.description ?? \"\") : \"\"\n\n if (childLoopName && description) {\n pauseToolData.source_loop = { name: childLoopName, description }\n }\n\n return { pauseToolData, childLoopName, childToolCallId, description }\n}\n","import type { ContentBlock, PendingQuestionRef, ToolBridgeContent } from \"./projection\"\n\nexport interface TextContentPart {\n type: \"text\"\n text: string\n}\n\nexport interface ImageUrlContentPart {\n type: \"image_url\"\n image_url: {\n url: string\n }\n}\n\nexport interface FileContentPart {\n type: \"file\"\n name: string\n data: string\n}\n\nexport type MessageContentPart = TextContentPart | ImageUrlContentPart | FileContentPart\nexport type MessageContent = string | MessageContentPart[]\n\nexport interface ToolCallInfo {\n id: string\n name: string\n display_name?: string | null\n arguments: string\n result?: unknown\n status?: \"pending\" | \"done\" | \"error\" | \"cancelled\" | \"awaiting_answer\"\n duration_ms?: number | null\n pending_question_ref?: PendingQuestionRef | null\n}\n\nexport type { ToolBridgeContent }\n\n/** Derive tool status from the result content string. */\nexport function inferToolStatus(\n resultStr: string,\n): \"done\" | \"error\" | \"cancelled\" {\n if (resultStr.includes('\"Cancelled by user\"')) return \"cancelled\"\n try {\n const parsed = JSON.parse(resultStr)\n if (typeof parsed === \"object\" && parsed !== null) {\n // Direct error: {\"error\": \"...\"}\n if (\"error\" in parsed && parsed.error) return \"error\"\n // 部分工具把输出包装为 {\"result\": {\"error\": \"...\"}, ...}\n const nested = parsed.result\n if (typeof nested === \"object\" && nested !== null && \"error\" in nested && nested.error) {\n return \"error\"\n }\n }\n } catch {\n // not JSON, treat as success\n }\n return \"done\"\n}\n\nexport interface MemoryRefInfo {\n id: number\n content_preview: string\n skill_name?: string | null\n}\n\nexport interface CompactionInfo {\n compaction_id: string\n summary_preview?: string | null\n summary_full?: string | null\n archived_count?: number | null\n archived_files?: ArchivedFileInfo[] | null\n archived_tool_calls?: ArchivedToolCallInfo[] | null\n tokens_before?: number | null\n tokens_after?: number | null\n saved_ratio?: number | null\n trigger?: \"auto\" | \"manual\" | \"forced_retry\" | null\n failure_reason?: string | null\n fallback_applied?: boolean | null\n}\n\nexport interface ArchivedFileInfo {\n tool_name?: string | null\n filename?: string | null\n relative_path?: string | null\n size_bytes?: number | null\n}\n\nexport interface ArchivedToolCallInfo {\n tool_call_id?: string | null\n tool_name?: string | null\n archive_path?: string | null\n replacement_content?: string | null\n entry_id?: string | null\n}\n\nexport interface ChatMessage {\n role: \"user\" | \"assistant\" | \"tool\" | \"error\"\n content: MessageContent\n reasoning?: string\n tool_calls?: ToolCallInfo[]\n status?: \"streaming\" | \"completed\" | \"paused\" | \"failed\" | \"interrupted\"\n duration_ms?: number\n timestamp?: string\n entry_id?: string\n parent_id?: string | null\n loop_name?: string\n /** Entry kind from backend -- present for non-message entries like mode changes. */\n kind?: string\n /** Memory references injected into this turn's context */\n memory_refs?: MemoryRefInfo[]\n /** Raw projection blocks for block-level UI rendering. */\n blocks?: ContentBlock[]\n /** Compaction metadata for compaction turns. */\n compaction?: CompactionInfo\n}\n","import { inferToolStatus } from \"../../schemas/message\"\nimport type {\n ContentBlock,\n MemoryRef,\n ToolCallProjection,\n TurnProjection,\n} from \"../../schemas/projection\"\n\nexport interface TurnState {\n turnId: string\n loopId: string\n role: \"user\" | \"assistant\" | \"system\"\n model: string | null\n startedAt: number\n contextWindow: number\n blocks: ContentBlock[]\n toolCalls: ToolCallProjection[]\n usage: Record<string, unknown> | null\n memoryRefs: MemoryRef[] | null\n parentForkToolCallId: string | null\n}\n\nexport function createTurnState(\n turnId: string,\n loopId: string,\n opts: {\n model?: string | null\n contextWindow?: number\n memoryRefs?: MemoryRef[] | null\n } = {},\n): TurnState {\n return {\n turnId,\n loopId,\n role: \"assistant\",\n model: opts.model ?? null,\n startedAt: Date.now(),\n contextWindow: opts.contextWindow ?? 0,\n blocks: [],\n toolCalls: [],\n usage: null,\n memoryRefs: opts.memoryRefs ?? null,\n parentForkToolCallId: null,\n }\n}\n\nexport function snapshot(\n state: TurnState,\n sequence: number,\n status: TurnProjection[\"status\"],\n): TurnProjection {\n return {\n id: state.turnId,\n sequence,\n turn_id: state.turnId,\n loop_id: state.loopId,\n kind: \"message\",\n role: state.role,\n status,\n blocks: [...state.blocks],\n tool_calls: [...state.toolCalls],\n model: state.model,\n usage: state.usage ? { ...state.usage } : null,\n duration_ms: Math.max(0, Date.now() - state.startedAt),\n started_at: new Date(state.startedAt).toISOString(),\n context_window: state.contextWindow,\n memory_refs: state.memoryRefs,\n parent_fork_tool_call_id: state.parentForkToolCallId,\n }\n}\n\nexport const PAUSE_TOOL_NAMES = new Set([\"AskUserQuestion\", \"ExitPlanMode\"])\n\nexport function toolStatusFromResult(result: unknown): ToolCallProjection[\"status\"] {\n const text =\n typeof result === \"string\"\n ? result\n : Array.isArray(result)\n ? result\n .filter(\n (p): p is { type: string; text: string } =>\n typeof p === \"object\" && p !== null && p.type === \"text\",\n )\n .map((p) => p.text ?? \"\")\n .join(\"\\n\")\n : String(result ?? \"\")\n return inferToolStatus(text)\n}\n","import type { MemoryRef, TurnProjection } from \"../../schemas/projection\"\nimport {\n applyAskUserPauseToTurn,\n applyChildPauseToParent,\n appendTextBlock,\n appendToolCallArguments,\n appendToolResultDelta,\n applyToolResult,\n buildCompactionTurn,\n buildMarkerTurn,\n buildSystemNotificationBlock,\n buildSystemNotificationTurn,\n type ChildPauseInfo,\n normalizeChildPause,\n setToolCallStatus,\n sourceLoopFor,\n upsertToolCall,\n} from \"./helpers\"\nimport { createTurnState, PAUSE_TOOL_NAMES, snapshot, toolStatusFromResult, type TurnState } from \"./state\"\n\nexport interface RawEvent {\n type: string\n payload: Record<string, unknown>\n}\n\nexport type ProjectionUpdate =\n | { kind: \"upsert\"; turn: TurnProjection }\n | { kind: \"workspace_changed\"; loopId: string; toolCallId?: string; toolName?: string }\n\nexport class ClientProjectionBuilder {\n private activeTurns = new Map<string, TurnState>()\n private lastTurnIds = new Map<string, string>()\n private latestTurns = new Map<string, TurnProjection>()\n private loopDescriptions = new Map<string, string>()\n private pendingChildPauses = new Map<string, ChildPauseInfo>()\n private pendingMemoryRefs = new Map<string, { turnId: string; refs: MemoryRef[] }>()\n private activeCompactions = new Map<string, Record<string, unknown>>()\n private seq = 0\n private syntheticCounter = 0\n private displayNameResolver: (name: string) => string\n\n constructor(displayNameResolver?: (name: string) => string) {\n this.displayNameResolver = displayNameResolver ?? ((n) => n)\n }\n\n processBatch(events: RawEvent[]): ProjectionUpdate[] {\n const lastUpsertByTurn = new Map<string, ProjectionUpdate & { kind: \"upsert\" }>()\n const nonUpserts: ProjectionUpdate[] = []\n for (const event of events) {\n const updates = this.processEvent(event)\n if (!updates) continue\n for (const u of updates) {\n if (u.kind === \"upsert\") {\n lastUpsertByTurn.set(u.turn.turn_id, u)\n } else {\n nonUpserts.push(u)\n }\n }\n }\n return [...nonUpserts, ...lastUpsertByTurn.values()]\n }\n\n processEvent(event: RawEvent): ProjectionUpdate[] | null {\n const payload = event.payload\n const loopId = String(payload.loop_name ?? \"root\")\n\n switch (event.type) {\n case \"memory:inject:done\":\n return this.onMemoryInject(loopId, payload)\n case \"memory:inject:none\":\n return null\n case \"loop:turn\":\n return this.onLoopTurn(loopId, payload)\n case \"mode:change\":\n return this.onModeChange(loopId, payload)\n case \"plan:status:update\":\n return this.onPlanStatusUpdate(loopId, payload)\n case \"workspace:changed\":\n return this.onWorkspaceChanged(loopId, payload)\n case \"agent:start\":\n return this.onAgentStart(loopId, payload)\n case \"bg:started\":\n return this.onBgStarted(loopId, payload)\n case \"bg:tasks_completed\":\n return this.onBgTasksCompleted(loopId, payload)\n case \"loop:ask_user_answer\":\n return this.onAskUserAnswer(loopId, payload)\n case \"user:message\":\n return this.onUserMessage(loopId, payload)\n }\n\n if (event.type.startsWith(\"compaction:\"))\n return this.onCompaction(event.type, loopId, payload)\n\n const state = this.activeTurns.get(loopId)\n if (!state) {\n if (event.type === \"chat:end\") {\n this.pendingMemoryRefs.delete(loopId)\n return null\n }\n if (event.type === \"agent:end\") return this.onAgentEnd(null, loopId, payload)\n return null\n }\n\n switch (event.type) {\n case \"llm:thinking:delta\":\n return this.onDelta(state, \"thinking\", \"\", String(payload.content ?? \"\"))\n case \"llm:content:delta\":\n return this.onDelta(state, \"text\", \"\", String(payload.content ?? \"\"))\n case \"llm:tool_call:created\":\n return this.onToolCallCreated(state, payload)\n case \"llm:response:done\":\n return this.onResponseDone(state, loopId, payload)\n case \"tool:result:delta\":\n return this.onToolResultDelta(state, payload)\n case \"tool:result:done\":\n return this.onToolResultDone(state, loopId, payload)\n case \"loop:tool_ui\":\n return this.onToolUi(state, payload)\n case \"loop:tool_bridge\":\n return this.onToolBridge(state, payload)\n case \"tool:approval:required\":\n return this.onToolApprovalRequired(state, payload)\n case \"loop:child_pause\":\n return this.onChildPause(state, loopId, payload)\n case \"chat:end\":\n return this.onChatEnd(state, loopId, payload)\n case \"agent:end\":\n return this.onAgentEnd(state, loopId, payload)\n default:\n return null\n }\n }\n\n reset(): void {\n this.activeTurns.clear()\n this.lastTurnIds.clear()\n this.latestTurns.clear()\n this.loopDescriptions.clear()\n this.pendingChildPauses.clear()\n this.pendingMemoryRefs.clear()\n this.activeCompactions.clear()\n this.seq = 0\n this.syntheticCounter = 0\n }\n\n seedSequence(maxSeq: number): void {\n if (maxSeq > this.seq) {\n this.seq = maxSeq\n }\n }\n\n // --- Event handlers ---\n\n private onMemoryInject(\n loopId: string,\n payload: Record<string, unknown>,\n ): null {\n const refs = payload.memory_refs\n const turnId = String(payload.turn_id ?? \"\")\n if (Array.isArray(refs) && refs.length > 0) {\n this.pendingMemoryRefs.set(loopId, {\n turnId,\n refs: refs.map((r: Record<string, unknown>) => ({\n id: Number(r.id),\n content_preview: String(r.content_preview ?? \"\"),\n skill_name: r.skill_name != null ? String(r.skill_name) : null,\n })),\n })\n }\n return null\n }\n\n private onLoopTurn(\n loopId: string,\n payload: Record<string, unknown>,\n ): ProjectionUpdate[] {\n let turnId = String(payload.turn_id ?? this.nextTurnId(`turn:${loopId}`))\n let memoryRefs: MemoryRef[] | null = null\n\n const pending = this.pendingMemoryRefs.get(loopId)\n if (pending) {\n this.pendingMemoryRefs.delete(loopId)\n if (pending.turnId) turnId = pending.turnId\n memoryRefs = pending.refs\n }\n\n const rawCw = payload.context_window\n const contextWindow =\n typeof rawCw === \"number\" && rawCw > 0 ? Math.trunc(rawCw) : 0\n\n const state = createTurnState(turnId, loopId, {\n model: optStr(payload.model),\n contextWindow,\n memoryRefs,\n })\n\n this.activeTurns.set(loopId, state)\n this.lastTurnIds.set(loopId, turnId)\n\n const turn = snapshot(state, this.nextSeq(), \"streaming\")\n this.latestTurns.set(loopId, turn)\n return [{ kind: \"upsert\", turn }]\n }\n\n private onModeChange(\n loopId: string,\n payload: Record<string, unknown>,\n ): ProjectionUpdate[] {\n const content: Record<string, string> = {}\n if (payload.from != null && payload.from !== \"\") content.from = String(payload.from)\n if (payload.to != null && payload.to !== \"\") content.to = String(payload.to)\n const turn = buildMarkerTurn(\n this.nextSeq(),\n this.nextTurnId(\"mode_change\"),\n loopId,\n \"mode_change\",\n content,\n )\n return [{ kind: \"upsert\", turn }]\n }\n\n private onPlanStatusUpdate(\n loopId: string,\n payload: Record<string, unknown>,\n ): ProjectionUpdate[] {\n let statuses = payload.statuses\n if (typeof statuses !== \"object\" || statuses === null) {\n statuses = payload._statuses ?? {}\n }\n const turn = buildMarkerTurn(\n this.nextSeq(),\n this.nextTurnId(\"plan_status\"),\n loopId,\n \"plan_status\",\n { plan_yaml: payload.plan_yaml ?? \"\", statuses },\n )\n return [{ kind: \"upsert\", turn }]\n }\n\n private onWorkspaceChanged(\n loopId: string,\n payload: Record<string, unknown>,\n ): ProjectionUpdate[] {\n const updates: ProjectionUpdate[] = [\n {\n kind: \"workspace_changed\",\n loopId,\n toolCallId: optStr(payload.tool_call_id) ?? undefined,\n toolName: toolNameFromPayload(payload) ?? undefined,\n },\n ]\n const state = this.activeTurns.get(loopId)\n if (state) {\n const turn = snapshot(state, this.nextSeq(), \"streaming\")\n this.latestTurns.set(loopId, turn)\n this.lastTurnIds.set(loopId, turn.turn_id)\n updates.push({ kind: \"upsert\", turn })\n }\n return updates\n }\n\n private onAgentStart(\n loopId: string,\n payload: Record<string, unknown>,\n ): ProjectionUpdate[] {\n const description = optStr(payload.description)\n if (description) this.loopDescriptions.set(loopId, description)\n const turn = buildSystemNotificationTurn(\n this.nextSeq(),\n this.nextTurnId(\"agent:start\"),\n loopId,\n \"agent:start\",\n \"running\",\n `Agent: ${payload.description ?? payload.skill_id ?? \"agent\"}`,\n optStr(payload.prompt),\n {\n skill_id: optStr(payload.skill_id),\n description: optStr(payload.description),\n parent_fork_tool_call_id: optStr(payload.parent_fork_tool_call_id),\n },\n )\n return [{ kind: \"upsert\", turn }]\n }\n\n private onBgStarted(\n loopId: string,\n payload: Record<string, unknown>,\n ): ProjectionUpdate[] {\n const taskId = optStr(payload.task_id) ?? \"\"\n const command = optStr(payload.command)\n const description = optStr(payload.description)\n const turn = buildSystemNotificationTurn(\n this.nextSeq(),\n this.nextTurnId(\"bg:started\"),\n loopId,\n \"bg:started\",\n \"running\",\n description ?? `Background: ${taskId || \"task\"}`,\n command,\n { task_id: taskId, command, description },\n )\n return [{ kind: \"upsert\", turn }]\n }\n\n private onBgTasksCompleted(\n loopId: string,\n payload: Record<string, unknown>,\n ): ProjectionUpdate[] {\n const taskIds = Array.isArray(payload.task_ids) ? payload.task_ids : []\n const count = typeof payload.count === \"number\" ? payload.count : taskIds.length\n const detail = taskIds.map(String).join(\", \")\n const turn = buildSystemNotificationTurn(\n this.nextSeq(),\n this.nextTurnId(\"bg:tasks_completed\"),\n loopId,\n \"bg:tasks_completed\",\n \"done\",\n `Background tasks completed (${count})`,\n detail || null,\n { task_ids: taskIds, count },\n )\n return [{ kind: \"upsert\", turn }]\n }\n\n private onAskUserAnswer(\n loopId: string,\n payload: Record<string, unknown>,\n ): ProjectionUpdate[] {\n const toolCallId = String(payload.tool_call_id ?? \"\")\n const pending = this.pendingChildPauses.get(toolCallId)\n const parentLoopId = pending?.parentLoopName\n\n // clear child pause\n if (pending) {\n this.pendingChildPauses.delete(toolCallId)\n const childTurn =\n this.activeTurns.get(pending.childLoopName) ??\n this.latestTurns.get(pending.childLoopName)\n setToolCallStatus(childTurn, pending.childToolCallId, \"done\", null, null)\n const parentTurn =\n this.activeTurns.get(pending.parentLoopName) ??\n this.latestTurns.get(pending.parentLoopName)\n setToolCallStatus(parentTurn, pending.parentToolCallId, \"done\", null, null)\n }\n\n // clear direct ask-user pause\n const directTurn = this.activeTurns.get(loopId) ?? this.latestTurns.get(loopId)\n setToolCallStatus(directTurn, toolCallId, \"done\", null, null)\n\n return this.collectLoopUpdates(loopId, parentLoopId)\n }\n\n private onUserMessage(\n _loopId: string,\n payload: Record<string, unknown>,\n ): ProjectionUpdate[] {\n const entryId = String(payload.entry_id ?? this.nextTurnId(\"user\"))\n const displayContent = payload.display_content ?? payload.content ?? \"\"\n const turn: TurnProjection = {\n id: entryId,\n sequence: this.nextSeq(),\n turn_id: entryId,\n loop_id: \"root\",\n kind: \"message\",\n role: \"user\",\n status: \"completed\",\n blocks: [{ type: \"text\", content: displayContent }],\n tool_calls: [],\n model: null,\n usage: null,\n duration_ms: 0,\n }\n return [{ kind: \"upsert\", turn }]\n }\n\n // --- Delta / streaming events ---\n\n private onDelta(\n state: TurnState,\n blockType: \"thinking\" | \"text\",\n _toolCallId: string,\n content: string,\n ): ProjectionUpdate[] | null {\n if (!content) return null\n appendTextBlock(state, blockType, content)\n return this.syncPatch(state)\n }\n\n private onToolCallCreated(\n state: TurnState,\n payload: Record<string, unknown>,\n ): ProjectionUpdate[] | null {\n if (\"arguments_delta\" in payload) {\n const delta = String(payload.arguments_delta ?? \"\")\n const toolCallId = String(payload.id ?? \"\")\n if (delta && toolCallId) {\n appendToolCallArguments(state, toolCallId, delta)\n return this.syncPatch(state)\n }\n return null\n }\n const toolCallId = String(payload.id ?? \"\")\n const toolName = toolNameFromPayload(payload)\n const displayName = String(payload.display_name ?? \"\") || this.displayNameResolver(toolName)\n const args = toolArgsFromPayload(payload)\n upsertToolCall(state, toolCallId, toolName, displayName, args)\n return this.syncPatch(state)\n }\n\n private onResponseDone(\n state: TurnState,\n loopId: string,\n payload: Record<string, unknown>,\n ): ProjectionUpdate[] | null {\n const model = optStr(payload.model)\n if (model) state.model = model\n if (typeof payload.usage === \"object\" && payload.usage !== null) {\n state.usage = { ...(payload.usage as Record<string, unknown>) }\n }\n\n // apply tool calls from full response\n const toolCalls = payload.tool_calls\n if (Array.isArray(toolCalls)) {\n for (const raw of toolCalls) {\n if (typeof raw !== \"object\" || raw === null) continue\n const tc = raw as Record<string, unknown>\n const fn = (tc.function ?? {}) as Record<string, unknown>\n const toolName = String(fn.name ?? \"\")\n const displayName =\n String(tc.display_name ?? \"\") || this.displayNameResolver(toolName)\n upsertToolCall(\n state,\n String(tc.id ?? \"\"),\n toolName,\n displayName,\n String(fn.arguments ?? \"\"),\n )\n }\n }\n\n if (state.toolCalls.length === 0) {\n return this.finalize(loopId, \"completed\")\n }\n return this.syncPatch(state)\n }\n\n private onToolResultDone(\n state: TurnState,\n loopId: string,\n payload: Record<string, unknown>,\n ): ProjectionUpdate[] | null {\n const toolCallId = String(payload.tool_call_id ?? \"\")\n const content = payload.content ?? \"\"\n const status = toolStatusFromResult(content)\n const rawDuration = payload.duration_ms\n const durationMs =\n typeof rawDuration === \"number\" && rawDuration >= 0\n ? Math.round(rawDuration)\n : null\n\n const sl = sourceLoopFor(state.loopId, this.loopDescriptions)\n applyToolResult(state, toolCallId, content, status, durationMs, sl)\n\n if (this.shouldFinalizeAfterToolResults(state)) {\n return this.finalize(loopId, \"completed\")\n }\n return this.syncPatch(state)\n }\n\n private onToolResultDelta(\n state: TurnState,\n payload: Record<string, unknown>,\n ): ProjectionUpdate[] | null {\n appendToolResultDelta(\n state,\n String(payload.tool_call_id ?? \"\"),\n String(payload.content ?? \"\"),\n )\n return this.syncPatch(state)\n }\n\n private onToolUi(\n state: TurnState,\n payload: Record<string, unknown>,\n ): ProjectionUpdate[] | null {\n const toolCallId = String(payload.tool_call_id ?? \"\")\n const ui = payload.ui\n if (toolCallId && typeof ui === \"object\" && ui !== null) {\n state.blocks.push({\n type: \"tool_ui\",\n content: ui,\n tool_call_id: toolCallId,\n })\n }\n return this.syncPatch(state)\n }\n\n private onToolBridge(\n state: TurnState,\n payload: Record<string, unknown>,\n ): ProjectionUpdate[] | null {\n const bridge = payload.bridge\n if (typeof bridge !== \"object\" || bridge === null) return null\n state.blocks.push({\n type: \"tool_bridge\",\n content: bridge,\n tool_call_id: String(payload.tool_call_id ?? \"\") || null,\n })\n return this.syncPatch(state)\n }\n\n private onToolApprovalRequired(\n state: TurnState,\n payload: Record<string, unknown>,\n ): ProjectionUpdate[] | null {\n const toolCallId = String(payload.tool_call_id ?? \"\")\n const toolName = String(payload.tool_name ?? \"\")\n const displayName = this.displayNameResolver(toolName)\n upsertToolCall(state, toolCallId, toolName, displayName, \"\")\n return this.syncPatch(state)\n }\n\n private onChildPause(\n state: TurnState,\n loopId: string,\n payload: Record<string, unknown>,\n ): ProjectionUpdate[] | null {\n const pauseToolData = payload.pause_tool_data\n if (typeof pauseToolData !== \"object\" || pauseToolData === null)\n return this.syncPatch(state)\n\n const ptd = pauseToolData as Record<string, unknown>\n const sourceLoop = ptd.source_loop as Record<string, unknown> | undefined\n if (typeof sourceLoop === \"object\" && sourceLoop) {\n const slName = String(sourceLoop.name ?? \"\")\n const slDesc = optStr(sourceLoop.description)\n if (slName && slDesc) this.loopDescriptions.set(slName, slDesc)\n }\n\n const { childLoopName, childToolCallId, description } =\n normalizeChildPause(payload as Record<string, unknown>)\n\n if (!childToolCallId) return this.syncPatch(state)\n\n const existing = this.pendingChildPauses.get(childToolCallId)\n const parentLoopName = String(\n payload.parent_loop_name ?? existing?.parentLoopName ?? \"root\",\n )\n const parentToolCallId = String(\n payload.parent_fork_tool_call_id ?? existing?.parentToolCallId ?? \"\",\n )\n const resolvedChildLoopName =\n String(payload.child_loop_name ?? \"\") || existing?.childLoopName || childLoopName || loopId\n\n this.pendingChildPauses.set(childToolCallId, {\n parentLoopName,\n parentToolCallId,\n childLoopName: resolvedChildLoopName,\n childToolCallId,\n description: description || existing?.description || \"\",\n })\n\n // apply to child\n applyAskUserPauseToTurn(\n state,\n ptd,\n childToolCallId,\n resolvedChildLoopName,\n this.pendingChildPauses.get(childToolCallId)!.description,\n this.displayNameResolver,\n )\n\n // apply to parent\n const parentTurn =\n this.activeTurns.get(parentLoopName) ?? this.latestTurns.get(parentLoopName)\n if (parentTurn) {\n applyChildPauseToParent(\n parentTurn,\n parentToolCallId,\n resolvedChildLoopName,\n childToolCallId,\n this.pendingChildPauses.get(childToolCallId)!.description,\n this.displayNameResolver,\n )\n }\n\n return this.collectLoopUpdates(loopId, parentLoopName)\n }\n\n private onChatEnd(\n state: TurnState,\n loopId: string,\n payload: Record<string, unknown>,\n ): ProjectionUpdate[] | null {\n const status = String(payload.status ?? \"completed\")\n\n const pauseToolData = payload.pause_tool_data\n if (typeof pauseToolData === \"object\" && pauseToolData !== null) {\n const ptd = pauseToolData as Record<string, unknown>\n const pauseToolName = String(ptd.name ?? \"\")\n const normalized = pauseToolName.includes(\":\")\n ? pauseToolName.split(\":\").pop()!\n : pauseToolName\n const sourceLoop = ptd.source_loop as Record<string, unknown> | undefined\n\n if (typeof sourceLoop === \"object\" && sourceLoop) {\n const slName = String(sourceLoop.name ?? \"\")\n const slDesc = optStr(sourceLoop.description)\n if (slName && slDesc) this.loopDescriptions.set(slName, slDesc)\n\n if (status === \"paused\" && slName) {\n applyChildPauseToParent(\n state,\n String(ptd.parent_fork_tool_call_id ?? \"\"),\n slName,\n String(ptd.tool_call_id ?? \"\"),\n slDesc ?? \"\",\n this.displayNameResolver,\n )\n\n const childTurn = this.activeTurns.get(slName)\n if (childTurn) {\n applyAskUserPauseToTurn(\n childTurn,\n ptd,\n String(ptd.tool_call_id ?? \"\"),\n slName,\n slDesc ?? \"\",\n this.displayNameResolver,\n )\n }\n }\n } else if (status === \"paused\" && normalized === \"AskUserQuestion\") {\n applyAskUserPauseToTurn(\n state,\n ptd,\n String(ptd.tool_call_id ?? \"\"),\n \"\",\n \"\",\n this.displayNameResolver,\n )\n }\n }\n\n const finalStatus = (\n { completed: \"completed\", paused: \"paused\", failed: \"failed\", interrupted: \"interrupted\" } as Record<string, TurnProjection[\"status\"]>\n )[status]\n\n if (!finalStatus) return null\n if (!this.activeTurns.has(loopId)) {\n this.pendingMemoryRefs.delete(loopId)\n }\n return this.finalize(loopId, finalStatus)\n }\n\n private onAgentEnd(\n state: TurnState | null,\n loopId: string,\n payload: Record<string, unknown>,\n ): ProjectionUpdate[] | null {\n const ok = payload.ok !== false\n const status = ok ? \"done\" : \"error\"\n const title = `Agent: ${payload.description ?? payload.skill_id ?? \"agent\"}`\n const detail = optStr(payload.error)\n const metadata = {\n skill_id: optStr(payload.skill_id),\n description: optStr(payload.description),\n parent_fork_tool_call_id: optStr(payload.parent_fork_tool_call_id),\n ok,\n }\n if (state) {\n state.blocks.push(buildSystemNotificationBlock(\"agent:end\", status, title, detail, metadata))\n return this.finalize(loopId, ok ? \"completed\" : \"failed\")\n }\n const turn = buildSystemNotificationTurn(\n this.nextSeq(), this.nextTurnId(\"agent:end\"), loopId, \"agent:end\", status, title, detail, metadata,\n )\n return [{ kind: \"upsert\", turn }]\n }\n\n private onCompaction(\n eventType: string,\n loopId: string,\n payload: Record<string, unknown>,\n ): ProjectionUpdate[] | null {\n const compactionId = String(payload.compaction_id ?? \"\")\n if (!compactionId) return null\n\n const current = {\n ...(this.activeCompactions.get(compactionId) ?? {}),\n ...payload,\n loop_id: loopId,\n }\n\n let status: TurnProjection[\"status\"]\n switch (eventType) {\n case \"compaction:start\":\n status = \"streaming\"\n this.activeCompactions.set(compactionId, current)\n break\n case \"compaction:end\":\n status = \"completed\"\n this.activeCompactions.delete(compactionId)\n break\n case \"compaction:abort\":\n status = \"interrupted\"\n this.activeCompactions.delete(compactionId)\n break\n case \"compaction:error\":\n status = \"failed\"\n this.activeCompactions.delete(compactionId)\n break\n default:\n status = \"streaming\"\n this.activeCompactions.set(compactionId, current)\n }\n\n const turn = buildCompactionTurn(this.nextSeq(), compactionId, loopId, status, current)\n return [{ kind: \"upsert\", turn }]\n }\n\n // --- Internal helpers ---\n\n private syncPatch(state: TurnState): ProjectionUpdate[] {\n const turn = snapshot(state, this.nextSeq(), \"streaming\")\n this.latestTurns.set(state.loopId, turn)\n this.lastTurnIds.set(state.loopId, turn.turn_id)\n return [{ kind: \"upsert\", turn }]\n }\n\n private finalize(\n loopId: string,\n status: TurnProjection[\"status\"],\n ): ProjectionUpdate[] | null {\n const state = this.activeTurns.get(loopId)\n if (!state) return null\n this.activeTurns.delete(loopId)\n const turn = snapshot(state, this.nextSeq(), status)\n this.lastTurnIds.set(loopId, turn.turn_id)\n this.latestTurns.set(loopId, turn)\n return [{ kind: \"upsert\", turn }]\n }\n\n private shouldFinalizeAfterToolResults(state: TurnState): boolean {\n if (state.toolCalls.length === 0) return true\n if (state.toolCalls.some((tc) => tc.status === \"pending\")) return false\n return !state.toolCalls.some((tc) => {\n const normalized = tc.tool_name.includes(\":\")\n ? tc.tool_name.split(\":\").pop()!\n : tc.tool_name\n return PAUSE_TOOL_NAMES.has(normalized)\n })\n }\n\n private collectLoopUpdates(\n ...loopIds: (string | undefined | null)[]\n ): ProjectionUpdate[] {\n const updates: ProjectionUpdate[] = []\n for (const loopId of loopIds) {\n if (!loopId) continue\n const state = this.activeTurns.get(loopId)\n if (state) {\n updates.push(...this.syncPatch(state))\n continue\n }\n const proj = this.latestTurns.get(loopId)\n if (proj) {\n const updated = { ...proj, sequence: this.nextSeq() }\n this.latestTurns.set(loopId, updated)\n updates.push({ kind: \"upsert\", turn: updated })\n }\n }\n return updates\n }\n\n private nextSeq(): number {\n return ++this.seq\n }\n\n private nextTurnId(prefix: string): string {\n this.syntheticCounter++\n const hex = Math.random().toString(16).slice(2, 10)\n return `${prefix}:${this.syntheticCounter}:${hex}`\n }\n}\n\n// --- Utility functions ---\n\nfunction optStr(value: unknown): string | null {\n if (value == null || value === \"\") return null\n return String(value)\n}\n\nfunction toolNameFromPayload(payload: Record<string, unknown>): string {\n const fn = payload.function\n if (typeof fn === \"object\" && fn !== null) {\n return String((fn as Record<string, unknown>).name ?? \"\")\n }\n return String(payload.tool_name ?? \"\")\n}\n\nfunction toolArgsFromPayload(payload: Record<string, unknown>): string {\n const fn = payload.function\n if (typeof fn === \"object\" && fn !== null) {\n return String((fn as Record<string, unknown>).arguments ?? \"\")\n }\n return \"\"\n}\n","import type {\n ContentBlock,\n ToolCallProjection,\n TurnProjection,\n} from \"../../schemas/projection\"\nimport { inferToolStatus } from \"../../schemas/message\"\nimport {\n applyAskUserPauseToTurn,\n applyChildPauseToParent,\n buildCompactionTurn,\n setToolCallStatus,\n} from \"./helpers\"\n\nexport interface RawHistoryEntry {\n id?: string\n kind?: string\n loop_name?: string\n message?: Record<string, unknown>\n data?: Record<string, unknown>\n timestamp?: string\n [key: string]: unknown\n}\n\n/** Rebuild completed UI turns from raw persisted history entries. */\nexport function projectHistory(entries: RawHistoryEntry[]): TurnProjection[] {\n const turns: TurnProjection[] = []\n const toolOwners = new Map<string, TurnProjection>()\n const latestAssistantByLoop = new Map<string, TurnProjection>()\n const pendingChildPauses = new Map<\n string,\n { childLoopId: string; parentLoopId: string; parentToolCallId: string }\n >()\n let sequence = 0\n\n for (const entry of entries) {\n const kind = String(entry.kind ?? \"\")\n const loopId = String(entry.loop_name ?? \"root\")\n const id = String(entry.id ?? `history-${sequence + 1}`)\n if (kind === \"message\" && isRecord(entry.message)) {\n const message = entry.message\n const role = String(message.role ?? \"\")\n if (role === \"tool\") {\n const toolCallId = String(message.tool_call_id ?? \"\")\n const owner = toolOwners.get(toolCallId)\n const toolCall = owner?.tool_calls.find((item) => item.id === toolCallId)\n if (owner && toolCall) {\n toolCall.status = message._error\n ? \"error\"\n : inferToolStatus(String(message.content ?? \"\"))\n toolCall.result = message.content ?? \"\"\n owner.blocks.push({\n type: \"tool_result\",\n content: message.content ?? \"\",\n tool_call_id: toolCallId,\n })\n }\n continue\n }\n if (role !== \"user\" && role !== \"assistant\" && role !== \"system\") continue\n\n const toolCalls = role === \"assistant\" ? buildToolCalls(message.tool_calls) : []\n const blocks = buildBlocks(message, toolCalls)\n const turn: TurnProjection = {\n id,\n sequence: ++sequence,\n turn_id: id,\n loop_id: loopId,\n kind: \"message\",\n role,\n status: message._error ? \"failed\" : \"completed\",\n blocks,\n tool_calls: toolCalls,\n model: stringOrNull(message.model),\n usage: isRecord(message._usage) ? { ...message._usage } : null,\n duration_ms: numberOrZero(message._duration_ms),\n started_at: typeof entry.timestamp === \"string\" ? entry.timestamp : undefined,\n }\n turns.push(turn)\n if (role === \"assistant\") latestAssistantByLoop.set(loopId, turn)\n for (const toolCall of toolCalls) toolOwners.set(toolCall.id, turn)\n continue\n }\n\n if (kind === \"mode_change\") {\n turns.push(markerTurn(id, ++sequence, loopId, \"mode_change\", entry.data ?? {}))\n } else if (kind === \"plan_status\") {\n const data = entry.data ?? {}\n turns.push(\n markerTurn(id, ++sequence, loopId, \"plan_status\", {\n plan_yaml: data.plan_yaml ?? \"\",\n statuses: data.statuses ?? data._statuses ?? {},\n }),\n )\n } else if (kind === \"tool_ui\" || kind === \"tool_bridge\") {\n const data = entry.data ?? {}\n const toolCallId = String(data.tool_call_id ?? \"\")\n const owner = toolOwners.get(toolCallId) ?? findLatestAssistant(turns, loopId)\n const content = kind === \"tool_ui\" ? data.ui : data.bridge\n if (owner && content !== undefined) {\n owner.blocks.push({\n type: kind,\n content,\n tool_call_id: toolCallId || null,\n })\n }\n } else if (kind === \"compaction\" || kind === \"tool_result_archive\") {\n const data = entry.data ?? {}\n const compactionId = String(data.compaction_id ?? entry.id ?? `history-${sequence + 1}`)\n let content = isRecord(entry.message) ? entry.message.content : undefined\n if (kind === \"tool_result_archive\") {\n const archivedCount = Array.isArray(data.archived_files) ? data.archived_files.length : 0\n content = `<compaction-summary>\\n已归档 ${archivedCount} 个大型工具结果。\\n</compaction-summary>`\n }\n turns.push(\n buildCompactionTurn(++sequence, compactionId, loopId, \"completed\", {\n ...data,\n content,\n }),\n )\n } else if (kind === \"child_pause\") {\n const data = entry.data ?? {}\n const sourceLoop = isRecord(data.source_loop) ? data.source_loop : {}\n const childLoopId = String(data.child_loop_name ?? sourceLoop.name ?? \"\")\n const childToolCallId = String(data.child_pause_tool_call_id ?? \"\")\n const parentToolCallId = String(data.parent_fork_tool_call_id ?? \"\")\n const pauseToolData = isRecord(data.pause_tool_data) ? data.pause_tool_data : {}\n const description = String(sourceLoop.description ?? \"\")\n applyAskUserPauseToTurn(\n latestAssistantByLoop.get(childLoopId),\n pauseToolData,\n childToolCallId,\n childLoopId,\n description,\n (name) => name,\n )\n applyChildPauseToParent(\n latestAssistantByLoop.get(loopId),\n parentToolCallId,\n childLoopId,\n childToolCallId,\n description,\n (name) => name,\n )\n if (childToolCallId) {\n pendingChildPauses.set(childToolCallId, {\n childLoopId,\n parentLoopId: loopId,\n parentToolCallId,\n })\n }\n } else if (kind === \"ask_user_answer\") {\n const data = entry.data ?? {}\n const toolCallId = String(data.tool_call_id ?? \"\")\n const pending = pendingChildPauses.get(toolCallId)\n if (pending) {\n setToolCallStatus(latestAssistantByLoop.get(pending.childLoopId), toolCallId, \"done\", null, null)\n setToolCallStatus(\n latestAssistantByLoop.get(pending.parentLoopId),\n pending.parentToolCallId,\n \"done\",\n null,\n null,\n )\n pendingChildPauses.delete(toolCallId)\n } else {\n setToolCallStatus(latestAssistantByLoop.get(loopId), toolCallId, \"done\", null, null)\n }\n turns.push(\n markerTurn(\n id,\n ++sequence,\n loopId,\n \"ask_user_answer\",\n data,\n toolCallId || null,\n ),\n )\n }\n }\n return turns\n}\n\nfunction buildToolCalls(value: unknown): ToolCallProjection[] {\n if (!Array.isArray(value)) return []\n return value.filter(isRecord).map((raw) => {\n const fn = isRecord(raw.function) ? raw.function : {}\n const name = String(fn.name ?? \"\")\n return {\n id: String(raw.id ?? \"\"),\n tool_name: name,\n display_name: String(raw.display_name ?? name),\n arguments: typeof fn.arguments === \"string\" ? fn.arguments : JSON.stringify(fn.arguments ?? {}),\n status: \"running\",\n result: null,\n }\n })\n}\n\nfunction buildBlocks(\n message: Record<string, unknown>,\n toolCalls: ToolCallProjection[],\n): ContentBlock[] {\n // 平台注入的用户消息(如 Factory 项目初始化指引)会带 _display_content:\n // 完整指令给 LLM,用户只看展示文案。缺了这条会把内部提醒整段泄露到聊天区。\n const displayContent = message.role === \"user\" ? message._display_content : undefined\n const stored = message._blocks\n const blocks: ContentBlock[] = []\n if (displayContent !== undefined) {\n blocks.push({ type: \"text\", content: displayContent })\n } else if (Array.isArray(stored)) {\n for (const raw of stored) {\n if (!isRecord(raw)) continue\n const type = String(raw.type ?? \"\")\n if (type === \"thinking\") blocks.push({ type, content: raw.thinking ?? raw.content ?? \"\" })\n if (type === \"text\") blocks.push({ type, content: raw.text ?? raw.content ?? \"\" })\n }\n } else if (message.content !== undefined && message.content !== \"\") {\n blocks.push({ type: \"text\", content: message.content })\n }\n for (const toolCall of toolCalls) {\n blocks.push({\n type: \"tool_use\",\n content: { name: toolCall.tool_name, arguments: toolCall.arguments },\n tool_call_id: toolCall.id,\n })\n }\n return blocks\n}\n\nfunction markerTurn(\n id: string,\n sequence: number,\n loopId: string,\n type: \"mode_change\" | \"plan_status\" | \"ask_user_answer\",\n content: Record<string, unknown>,\n toolCallId: string | null = null,\n): TurnProjection {\n return {\n id,\n sequence,\n turn_id: id,\n loop_id: loopId,\n kind: type as TurnProjection[\"kind\"],\n role: \"system\",\n status: \"completed\",\n blocks: [{ type, content, tool_call_id: toolCallId }],\n tool_calls: [],\n model: null,\n usage: null,\n duration_ms: 0,\n }\n}\n\nfunction isRecord(value: unknown): value is Record<string, unknown> {\n return typeof value === \"object\" && value !== null && !Array.isArray(value)\n}\n\nfunction stringOrNull(value: unknown): string | null {\n return typeof value === \"string\" ? value : null\n}\n\nfunction numberOrZero(value: unknown): number {\n return typeof value === \"number\" ? value : 0\n}\n\nfunction findLatestAssistant(\n turns: TurnProjection[],\n loopId: string,\n): TurnProjection | undefined {\n for (let index = turns.length - 1; index >= 0; index -= 1) {\n const turn = turns[index]\n if (turn?.role === \"assistant\" && turn.loop_id === loopId) return turn\n }\n return undefined\n}\n","import type { BackgroundTask } from \"../schemas/background\"\nimport type { TurnProjection } from \"../schemas/projection\"\nimport type { SessionDetail, SessionInfo, TemplateId } from \"../schemas/session\"\nimport type { Task } from \"../schemas/task\"\nimport type { BladeClient, UploadProgress } from \"../blade-client\"\nimport type { AgentSession } from \"../session/agent-session\"\nimport type { SessionProfile } from \"../types/sdk-profile\"\nimport { projectHistory, type RawHistoryEntry } from \"../shared/projection\"\n\nexport interface CreateSessionRequest {\n intent?: string\n template_id?: TemplateId\n solution_id?: string\n biz_role_id?: string | null\n primary_skill_id?: string | null\n model?: string | null\n enable_thinking?: boolean | null\n memory_enabled?: boolean | null\n env?: Record<string, string>\n disable_tools?: string[] | null\n session_solution_asset_id?: string | null\n compaction_ratio?: number | null\n runtime_type?: \"sandbox\" | \"daemon\" | null\n daemon_id?: string | null\n}\n\nexport interface CheckpointNode {\n id: string\n parent_id: string | null\n content_preview: string\n content: string\n timestamp: string\n}\n\nexport type ContentPart =\n | { type: \"text\"; text: string }\n | { type: \"image_url\"; image_url: { url: string; detail?: string } }\n\nexport interface HistoryNode {\n id: string\n parent_id: string | null\n kind: string\n role: string\n timestamp: string\n preview: string\n content: string | ContentPart[]\n tool_calls: Array<{\n id?: string\n type?: string\n function?: { name?: string; arguments?: string }\n }> | null\n usage: { prompt_tokens?: number; completion_tokens?: number; total_tokens?: number } | null\n total_tokens: number\n token_diff: number\n is_deprecated: boolean\n loop_name: string\n}\n\nexport interface SessionHistory {\n nodes: HistoryNode[]\n active_branch: string | null\n branches: string[]\n system_prompt_tokens?: number | null\n tools_tokens?: number | null\n tokenizer_model?: string | null\n}\n\nexport interface TokenizeResult {\n model: string\n prompt_tokens: number\n prompt: string\n}\n\nexport interface PaginatedSessionsResult {\n items: SessionInfo[]\n total: number\n limit: number\n offset: number\n content_match_truncated?: boolean\n}\n\ninterface ListSessionsPageParams {\n limit: number\n offset: number\n template_id_prefix?: string\n solution_id?: string\n q?: string\n}\n\nexport interface SkillDevSession {\n session: SessionInfo\n skill_id: string\n display_name: string\n skill_description: string\n}\n\nexport interface ShareLinkResult {\n token: string\n url: string\n expires_at: string | null\n}\n\nexport interface SessionContextStats {\n tokens_used: number\n context_window: number\n compaction_ratio: number\n}\n\nexport interface FileEntry {\n name: string\n path: string\n is_dir: boolean\n created_at: number\n tags?: string[]\n}\n\nexport type UploadFileEntry = File | { file: File; name: string }\n\nexport interface UploadFilesOptions {\n onProgress?: (progress: UploadProgress) => void\n}\n\nexport interface ImportPreviewSkill {\n name: string\n description: string\n path: string\n}\n\nexport interface ImportPreviewScenario {\n scenario?: { name?: string }\n skills?: string[]\n preview_urls?: string[]\n init_script?: string\n generated_at?: string\n}\n\nexport interface ImportPreview {\n user_messages: string[]\n turn_count: number\n skills: ImportPreviewSkill[]\n scenario: ImportPreviewScenario | null\n}\n\nfunction toCreateSessionPayload(request: CreateSessionRequest) {\n return {\n intent: request.intent ?? \"\",\n template_id: request.template_id,\n solution_id: request.solution_id,\n biz_role_id: request.biz_role_id ?? null,\n model: request.model ?? null,\n enable_thinking: request.enable_thinking ?? null,\n memory_enabled: request.memory_enabled ?? null,\n primary_skill_id: request.primary_skill_id ?? null,\n env: request.env,\n disable_tools: request.disable_tools ?? null,\n session_solution_asset_id: request.session_solution_asset_id ?? null,\n compaction_ratio: request.compaction_ratio ?? null,\n ...(request.runtime_type ? { runtime_type: request.runtime_type } : {}),\n ...(request.daemon_id ? { daemon_id: request.daemon_id } : {}),\n }\n}\n\nexport class SessionsResource {\n constructor(private client: BladeClient) {}\n\n /**\n * 连接一个已存在的会话,返回实时会话对象 AgentSession\n * (自动完成历史加载、Socket.IO 订阅、断线重连补数)。\n */\n connect(sessionId: string): Promise<AgentSession> {\n return this.client.hub.connect(sessionId)\n }\n\n /** 创建新会话并直接连接,返回可收发消息的 AgentSession。 */\n async create(request: CreateSessionRequest = {}): Promise<AgentSession> {\n // 先握手再建会话:否则会在旧 Server 上留下一个永远连不上的空会话。\n await this.client.ensureVersionCompatible()\n const { session_id } = await this.createSessionWithRequest(request)\n return this.connect(session_id)\n }\n\n private fetchSessionsPage({\n limit,\n offset,\n template_id_prefix,\n solution_id,\n q,\n }: ListSessionsPageParams): Promise<PaginatedSessionsResult> {\n const searchParams = new URLSearchParams()\n searchParams.set(\"limit\", String(limit))\n searchParams.set(\"offset\", String(offset))\n if (template_id_prefix) searchParams.set(\"template_id_prefix\", template_id_prefix)\n if (solution_id) searchParams.set(\"solution_id\", solution_id)\n const trimmedQuery = q?.trim()\n if (trimmedQuery) searchParams.set(\"q\", trimmedQuery)\n return this.client.json(\"GET\", `/api/sessions?${searchParams.toString()}`)\n }\n\n async listSessions(template_id_prefix?: string, solution_id?: string): Promise<SessionInfo[]> {\n const pageSize = 100\n const sessions: SessionInfo[] = []\n let offset = 0\n while (true) {\n const page = await this.fetchSessionsPage({ limit: pageSize, offset, template_id_prefix, solution_id })\n sessions.push(...page.items)\n if (sessions.length >= page.total || page.items.length === 0) return sessions\n offset += page.items.length\n }\n }\n\n listSessionsPaginated(params: {\n limit: number\n offset: number\n template_id_prefix?: string\n solution_id?: string\n q?: string\n }): Promise<PaginatedSessionsResult> {\n return this.fetchSessionsPage(params)\n }\n\n listSessionsWithSkillData(): Promise<SkillDevSession[]> {\n return this.client.json(\"GET\", \"/api/sessions/with-skill-data\")\n }\n\n createSession(\n intent?: string,\n template_id?: TemplateId,\n primary_skill_id?: string | null,\n ): Promise<{ session_id: string }> {\n return this.createSessionWithRequest({ intent, template_id, primary_skill_id })\n }\n\n createSessionWithRequest(request: CreateSessionRequest): Promise<{ session_id: string }> {\n return this.client.json(\"POST\", \"/api/sessions\", toCreateSessionPayload(request))\n }\n\n createWithProfile(params: {\n intent: string\n profile: SessionProfile\n }): Promise<{ session_id: string }> {\n const { intent, profile } = params\n return this.createSessionWithRequest({\n intent,\n ...profileToCreateSessionRequest(profile),\n })\n }\n\n getSession(sessionId: string, init?: RequestInit): Promise<SessionDetail> {\n return this.client.jsonFromInit(`/api/sessions/${sessionId}`, init)\n }\n\n updateSession(sessionId: string, payload: { intent?: string }): Promise<SessionDetail> {\n return this.client.json(\"PATCH\", `/api/sessions/${sessionId}`, payload)\n }\n\n setSessionEnv(sessionId: string, env: Record<string, string>): Promise<SessionDetail> {\n return this.client.json(\"PUT\", `/api/sessions/${sessionId}/env`, { env })\n }\n\n pinSession(sessionId: string, pinned: boolean): Promise<SessionInfo> {\n return this.client.json(\"PATCH\", `/api/sessions/${sessionId}/pin`, { pinned })\n }\n\n startReplaySession(sourceSessionId: string, speed: 1 | 2 | 5 = 5): Promise<{ session_id: string }> {\n return this.client.json(\"POST\", `/api/sessions/${sourceSessionId}/replay`, { speed })\n }\n\n updateReplaySession(\n sessionId: string,\n payload: { speed?: 1 | 2 | 5; status?: \"autonomous\" },\n ): Promise<{ replay_state: SessionInfo[\"replay_state\"] }> {\n return this.client.json(\"PATCH\", `/api/sessions/${sessionId}/replay`, payload)\n }\n\n updateSharing(sessionId: string, shared: boolean): Promise<{ shared: boolean }> {\n return this.client.json(\"PATCH\", `/api/sessions/${sessionId}/sharing`, { shared })\n }\n\n updateSessionMemory(sessionId: string, memoryEnabled: boolean): Promise<{ memory_enabled: boolean }> {\n return this.client.json(\"PATCH\", `/api/sessions/${sessionId}/memory`, {\n memory_enabled: memoryEnabled,\n })\n }\n\n createShare(sessionId: string): Promise<ShareLinkResult> {\n return this.client.json(\"POST\", `/api/sessions/${sessionId}/share`, {})\n }\n\n revokeShare(sessionId: string, token: string): Promise<{ revoked: boolean }> {\n return this.client.json(\"DELETE\", `/api/sessions/${sessionId}/share/${encodeURIComponent(token)}`)\n }\n\n async getSharedSession(token: string): Promise<TurnProjection[]> {\n const entries = await this.client.jsonFromInit<RawHistoryEntry[]>(`/api/share/${encodeURIComponent(token)}`, {\n credentials: \"omit\",\n headers: { Accept: \"application/json\" },\n })\n return projectHistory(entries)\n }\n\n getSessionTasks(sessionId: string): Promise<Task[]> {\n return this.client.json(\"GET\", `/api/sessions/${sessionId}/tasks`)\n }\n\n async getSessionTurns(sessionId: string): Promise<TurnProjection[]> {\n const entries = await this.client.json<RawHistoryEntry[]>(\n \"GET\",\n `/api/sessions/${sessionId}/messages`,\n )\n return projectHistory(entries)\n }\n\n getSessionContextStats(sessionId: string, init?: RequestInit): Promise<SessionContextStats> {\n return this.client.jsonFromInit(`/api/sessions/${sessionId}/context-stats`, init)\n }\n\n getSessionHistory(sessionId: string, init?: RequestInit): Promise<SessionHistory> {\n return this.client.jsonFromInit(`/api/sessions/${sessionId}/history`, init)\n }\n\n tokenizePrompt(prompt: string, model?: string): Promise<TokenizeResult> {\n return this.client.json(\"POST\", \"/api/sessions/tokenize/prompt\", { prompt, model })\n }\n\n tokenizeMessages(\n messages: Array<Record<string, unknown>>,\n options?: {\n model?: string\n add_generation_prompt?: boolean\n enable_thinking?: boolean | null\n tools?: Array<Record<string, unknown>>\n },\n ): Promise<TokenizeResult> {\n return this.client.json(\"POST\", \"/api/sessions/tokenize/messages\", {\n messages,\n model: options?.model,\n add_generation_prompt: options?.add_generation_prompt ?? true,\n enable_thinking: options?.enable_thinking ?? null,\n tools: options?.tools ?? null,\n })\n }\n\n getSessionCheckpoints(\n sessionId: string,\n init?: RequestInit,\n ): Promise<{ nodes: CheckpointNode[]; leaf_id: string | null }> {\n return this.client.jsonFromInit(`/api/sessions/${sessionId}/checkpoints`, init)\n }\n\n checkoutSession(\n sessionId: string,\n checkpointId: string,\n position: \"before\" | \"turn_end\",\n mode?: \"both\" | \"conversation\" | \"code\",\n linear?: boolean,\n ): Promise<{\n id: string\n content: string\n position: string\n mode?: string\n files_restored?: boolean\n linear?: boolean\n }> {\n return this.client.json(\"POST\", `/api/sessions/${sessionId}/checkout`, {\n checkpoint_id: checkpointId,\n position,\n ...(mode ? { mode } : {}),\n ...(linear ? { linear } : {}),\n })\n }\n\n async rewindSession(sessionId: string, checkpointId: string): Promise<{ id: string; content: string }> {\n const result = await this.checkoutSession(sessionId, checkpointId, \"before\")\n return { id: result.id, content: result.content }\n }\n\n switchBranch(sessionId: string, checkpointId: string): Promise<{ id: string; leaf_id: string }> {\n return this.client.json(\"POST\", `/api/sessions/${sessionId}/switch-branch`, {\n checkpoint_id: checkpointId,\n })\n }\n\n deleteSession(sessionId: string): Promise<{ deleted: boolean }> {\n return this.client.json(\"DELETE\", `/api/sessions/${sessionId}`)\n }\n\n listBackgroundTasks(sessionId: string, init?: RequestInit): Promise<BackgroundTask[]> {\n return this.client.jsonFromInit(`/api/sessions/${sessionId}/background-tasks`, init)\n }\n\n getBackgroundTask(\n sessionId: string,\n taskId: string,\n tail = 100,\n init?: RequestInit,\n ): Promise<BackgroundTask> {\n return this.client.jsonFromInit(`/api/sessions/${sessionId}/background-tasks/${taskId}?tail=${tail}`, init)\n }\n\n stopBackgroundTask(\n sessionId: string,\n taskId: string,\n ): Promise<{ message: string; task?: BackgroundTask | null }> {\n return this.client.json(\"POST\", `/api/sessions/${sessionId}/background-tasks/${taskId}/stop`)\n }\n\n\n probeSessionUrl(sessionId: string, url: string): Promise<{ reachable: boolean }> {\n return this.client.json(\n \"GET\",\n `/api/sessions/${sessionId}/probe-url?url=${encodeURIComponent(url)}`,\n )\n }\n\n listDir(sessionId: string, dirPath: string): Promise<FileEntry[]> {\n return this.client.json(\"GET\", `/api/sessions/${sessionId}/ls/${encodeURIComponent(dirPath)}`)\n }\n\n async uploadFiles(\n sessionId: string,\n dirPath: string,\n files: FileList | File[] | UploadFileEntry[],\n options: UploadFilesOptions = {},\n ): Promise<{ uploaded: string[]; failed: string[] }> {\n const formData = new FormData()\n const entries = Array.from(files).map((f) =>\n f instanceof File ? { file: f, name: f.name } : (f as { file: File; name: string }),\n )\n for (const entry of entries) {\n formData.append(\"files\", entry.file, entry.name)\n }\n // webkitdirectory 选择的文件带 webkitRelativePath;拖入的文件夹把相对路径放在 name 里。\n // 任一形式包含目录分隔符时都发送 paths,供服务端重建目录结构。\n const relativePaths = entries.map((e) => e.file.webkitRelativePath || e.name)\n if (relativePaths.some((p) => p.includes(\"/\"))) {\n formData.append(\"paths\", JSON.stringify(relativePaths))\n }\n const response = await this.client.formData(\n \"POST\",\n `/api/sessions/${sessionId}/upload/${encodeURIComponent(dirPath)}`,\n formData,\n { expectOk: false, onUploadProgress: options.onProgress },\n )\n return response.json()\n }\n\n async deleteFile(sessionId: string, filePath: string): Promise<void> {\n await this.client.json(\"DELETE\", `/api/sessions/${sessionId}/files/${encodeURIComponent(filePath)}`)\n }\n\n writeFile(sessionId: string, filePath: string, content: string): Promise<{ success: boolean }> {\n return this.client.json(\"PUT\", `/api/sessions/${sessionId}/files/${encodeURIComponent(filePath)}`, {\n content,\n })\n }\n\n renameFile(sessionId: string, filePath: string, newName: string): Promise<{ path: string }> {\n return this.client.json(\"POST\", `/api/sessions/${sessionId}/files/${encodeURIComponent(filePath)}/rename`, {\n new_name: newName,\n })\n }\n\n copyFile(sessionId: string, filePath: string): Promise<{ path: string }> {\n return this.client.json(\"POST\", `/api/sessions/${sessionId}/files/${encodeURIComponent(filePath)}/copy`)\n }\n\n shareFile(\n sessionId: string,\n sourcePath: string,\n linkName?: string,\n shareFolder?: string,\n ): Promise<{ path: string; target: string }> {\n return this.client.json(\"POST\", `/api/sessions/${sessionId}/share-file`, {\n source_path: sourcePath,\n link_name: linkName ?? \"\",\n share_folder: shareFolder ?? \"\",\n })\n }\n\n getDownloadDirUrl(sessionId: string, dirPath: string): string {\n return this.client.buildAuthedUrl(`/api/sessions/${sessionId}/download-dir/${encodeURIComponent(dirPath)}`)\n }\n\n async exportSession(sessionId: string): Promise<void> {\n await this.getSession(sessionId)\n const a = document.createElement(\"a\")\n a.href = this.client.buildAuthedUrl(`/api/sessions/${sessionId}/export`)\n a.download = `${sessionId}.zip`\n document.body.appendChild(a)\n a.click()\n a.remove()\n }\n\n async previewImport(file: File): Promise<ImportPreview> {\n const form = new FormData()\n form.append(\"file\", file)\n const res = await this.client.formData(\"POST\", \"/api/sessions/preview-import\", form)\n return res.json()\n }\n\n async importSession(\n file: File,\n name?: string,\n solutionId?: string | null,\n ): Promise<{ session_id: string }> {\n const form = new FormData()\n form.append(\"file\", file)\n if (name) form.append(\"name\", name)\n if (solutionId) form.append(\"solution_id\", solutionId)\n const res = await this.client.formData(\"POST\", \"/api/sessions/import\", form)\n return res.json()\n }\n}\n\nfunction profileToCreateSessionRequest(profile: SessionProfile): CreateSessionRequest {\n const solution = profile.solution\n return {\n solution_id: solution?.kind === \"existing\" ? solution.solutionId : undefined,\n session_solution_asset_id: solution?.kind === \"prepared\" ? solution.assetId : undefined,\n biz_role_id: solution?.bizRoleId ?? null,\n model: profile.model ?? null,\n compaction_ratio: profile.compactionRatio ?? null,\n enable_thinking: profile.enableThinking ?? null,\n memory_enabled: profile.memoryEnabled ?? null,\n disable_tools: profile.disableTools ?? null,\n env: profile.env,\n }\n}\n","export type CommandHandler = (payload: unknown, meta: { toolCallId?: string }) => void\n\ninterface BufferedCommand {\n payload: unknown\n meta: { toolCallId?: string }\n}\n\n/** 每个 action 在 handler 注册前最多缓冲的指令条数,超出丢最旧的。 */\nconst BUFFER_LIMIT_PER_ACTION = 20\n\n/**\n * 指令注册表:onCommand 事后注册 + 注册前缓冲补投。\n *\n * action 的来源见 ./protocol.ts 顶部说明——它由技能作者在工具返回值的\n * `_meta.bridge` 字段里写入,是技能作者与宿主页面开发者的业务契约。\n * 缓冲的意义:指令可能在页面还没来得及调用 onCommand 时就到达(比如\n * 历史回放),先存起来、注册时立刻补投,消除\"注册晚了漏事件\"的坑。\n */\nexport class CommandRegistry {\n private handlers = new Map<string, Set<CommandHandler>>()\n private buffered = new Map<string, BufferedCommand[]>()\n\n onCommand(action: string, handler: CommandHandler): () => void {\n let set = this.handlers.get(action)\n if (!set) {\n set = new Set()\n this.handlers.set(action, set)\n }\n set.add(handler)\n\n const pending = this.buffered.get(action)\n if (pending?.length) {\n this.buffered.delete(action)\n for (const command of pending) {\n this.invoke(handler, action, command)\n }\n }\n return () => {\n this.handlers.get(action)?.delete(handler)\n }\n }\n\n dispatch(action: string, payload: unknown, meta: { toolCallId?: string } = {}): void {\n const set = this.handlers.get(action)\n if (set && set.size > 0) {\n for (const handler of [...set]) {\n this.invoke(handler, action, { payload, meta })\n }\n return\n }\n let pending = this.buffered.get(action)\n if (!pending) {\n pending = []\n this.buffered.set(action, pending)\n }\n pending.push({ payload, meta })\n if (pending.length > BUFFER_LIMIT_PER_ACTION) {\n pending.shift()\n console.warn(\n `[agent-client] 指令 \"${action}\" 无人处理且缓冲已满,最旧的一条已丢弃。` +\n `请调用 onCommand(\"${action}\", handler) 注册处理函数。`,\n )\n }\n }\n\n private invoke(handler: CommandHandler, action: string, command: BufferedCommand): void {\n try {\n handler(command.payload, command.meta)\n } catch (error) {\n console.warn(`[agent-client] 指令 \"${action}\" 的处理函数抛出异常:`, error)\n }\n }\n\n clear(): void {\n this.handlers.clear()\n this.buffered.clear()\n }\n}\n","import type { ChatMessage, ToolCallInfo } from \"../schemas/message\"\nimport type { TurnProjection } from \"../schemas/projection\"\nimport type { SessionStatus } from \"../schemas/session\"\n\n/**\n * AgentSession 的语义事件表。\n *\n * 这是\"底层逃生舱\"(L1):React 使用者优先用 useChat() 的响应式状态(L2)\n * 或 <ChatView onToolCall/commands> 的声明式入口(L3),一般不需要直接监听。\n * Vue / 无框架集成者用 session.on(...) 精确订阅。\n */\nexport interface AgentSessionEvents {\n /** 一条消息物化完成(turn 离开 streaming 状态)。 */\n message: { message: ChatMessage; turn: TurnProjection }\n /** 智能体发起了一次工具调用(首次出现)。 */\n toolCall: { toolCall: ToolCallInfo; turn: TurnProjection }\n /** 一次工具调用出结果(done / error / cancelled)。 */\n toolResult: { toolCall: ToolCallInfo; turn: TurnProjection }\n /** 一轮回复结束。status: completed / paused / interrupted / failed。 */\n chatEnd: { status: string }\n /** 运行错误(system:error、发送失败等)。 */\n error: { message: string }\n /** planning / executing 模式切换。 */\n modeChange: { mode: \"planning\" | \"executing\" }\n /**\n * 智能体给宿主页面下发指令。\n *\n * action 的来源:技能作者在工具实现的返回值 JSON 里写 `_meta.bridge:\n * { action, payload }`,后端剥离后经事件流送达前端。action 是技能作者与\n * 宿主页面开发者约定的业务契约字符串(如 \"map.highlight\"),LLM 不参与、\n * SDK 不做枚举。一般用 session.onCommand(action, fn) 消费,而不是监听本事件。\n */\n command: { action: string; payload: unknown; toolCallId?: string }\n /** 系统通知(技能阶段提示、后台任务启动等)。 */\n notification: {\n type: string\n title: string\n detail?: string\n status: \"info\" | \"running\" | \"done\" | \"error\"\n loopId?: string\n metadata?: Record<string, unknown>\n }\n /** 工作区文件发生变化(写文件、重命名等)。 */\n workspaceChanged: { filePath?: string }\n /** 智能体产出了文件成果(artifact:created / artifact:updated)。 */\n artifact: {\n filePath: string\n contentType: string\n title: string\n content: string\n oldString?: string\n newString?: string\n kind: \"created\" | \"updated\"\n }\n /** 工具返回值带 _meta.ui 的可视化预览(resource HTML / URI)。 */\n toolPreview: {\n toolCallId: string\n type: \"resource-html\" | \"resource-uri\"\n content: string\n title: string\n }\n /** 任务清单(TaskCreate 等)更新。 */\n taskListUpdated: { tasks: unknown[] }\n /** 沙盒后台命令状态更新。 */\n backgroundTask: {\n id: string\n command: string\n description?: string\n status: \"running\" | \"done\" | \"failed\"\n exitCode?: number | null\n elapsedSeconds: number\n output?: string\n }\n /** 会话被回溯到某个检查点。 */\n rewind: { checkpointId: string }\n /** 会话属性(名称、状态、绑定技能等)被服务端更新。 */\n sessionUpdated: {\n intent?: string\n status?: SessionStatus\n model?: string | null\n boundSkillId?: string | null\n replayState?: Record<string, unknown> | null\n }\n /** 回放输入不匹配,需要决定保持回放还是转自主模式。 */\n replayMismatch: {\n actualMessage?: string\n expectedMessage?: string\n respond: (decision: \"keep_replay\" | \"continue_replay\") => void\n }\n /** 沙盒内存超限自动重启。 */\n sandboxOom: { toolCallId: string }\n /** session.attach() 被调用,渲染层(ChatView/useChat)应把它显示为输入框附件。 */\n attachRequested: { label: string; content: string }\n /** session.insertText() 被调用,渲染层应把文字追加到输入框。 */\n insertTextRequested: { text: string }\n}\n\nexport type AgentSessionEventName = keyof AgentSessionEvents\n\ntype Handler<E> = (event: E) => void\n\nexport class Emitter<Events> {\n private handlers = new Map<keyof Events, Set<Handler<never>>>()\n\n on<K extends keyof Events>(name: K, handler: Handler<Events[K]>): () => void {\n let set = this.handlers.get(name)\n if (!set) {\n set = new Set()\n this.handlers.set(name, set)\n }\n set.add(handler as Handler<never>)\n return () => this.off(name, handler)\n }\n\n off<K extends keyof Events>(name: K, handler: Handler<Events[K]>): void {\n this.handlers.get(name)?.delete(handler as Handler<never>)\n }\n\n emit<K extends keyof Events>(name: K, event: Events[K]): void {\n const set = this.handlers.get(name)\n if (!set) return\n for (const handler of [...set]) {\n try {\n ;(handler as Handler<Events[K]>)(event)\n } catch (error) {\n // handler 异常只告警,不中断会话流\n console.warn(`[agent-client] \"${String(name)}\" 事件处理器抛出异常:`, error)\n }\n }\n }\n\n /**\n * 只把事件交给最先注册的处理器。用于必须由单一交互入口作答的事件,\n * 避免多个 UI 同时弹窗并提交相互冲突的决定。\n */\n emitFirst<K extends keyof Events>(name: K, event: Events[K]): boolean {\n const handler = this.handlers.get(name)?.values().next().value\n if (!handler) return false\n try {\n ;(handler as Handler<Events[K]>)(event)\n } catch (error) {\n console.warn(`[agent-client] \"${String(name)}\" 事件处理器抛出异常:`, error)\n return false\n }\n return true\n }\n\n listenerCount(name: keyof Events): number {\n return this.handlers.get(name)?.size ?? 0\n }\n\n clear(): void {\n this.handlers.clear()\n }\n}\n","import type {\n ChatMessage,\n FileContentPart,\n ImageUrlContentPart,\n MessageContent,\n MessageContentPart,\n} from \"./message\"\n\nconst SYSTEM_REMINDER_PATTERN = /^<system-reminder>\\s*[\\s\\S]*?\\s*<\\/system-reminder>$/i\nconst LEGACY_FORK_CONTEXT_MARKERS = [\n \"父智能体在派生你之前已经完成了一些操作。\",\n \"可通过 `read_file` 读取。\",\n \"# 你的任务\",\n]\n\nexport function normalizeMessageContent(content: unknown): MessageContent {\n if (typeof content === \"string\") return content\n if (Array.isArray(content)) return content as MessageContentPart[]\n return String(content ?? \"\")\n}\n\nexport function getTextContent(content: MessageContent): string {\n if (typeof content === \"string\") return content\n return content\n .filter((part) => part.type === \"text\")\n .map((part) => part.text)\n .join(\"\")\n}\n\nexport function isSystemReminderText(text: string): boolean {\n return SYSTEM_REMINDER_PATTERN.test(text.trim())\n}\n\nexport function isLegacyForkContextText(text: string): boolean {\n const normalized = text.trim()\n return LEGACY_FORK_CONTEXT_MARKERS.every((marker) => normalized.includes(marker))\n}\n\nexport function isHiddenInternalMessage(message: Pick<ChatMessage, \"role\" | \"content\">): boolean {\n if (message.role !== \"user\") return false\n const text = getTextContent(normalizeMessageContent(message.content))\n return isSystemReminderText(text) || isLegacyForkContextText(text)\n}\n\nexport function buildMessageContent(\n text: string,\n attachments: Array<{\n kind: \"file\"\n name: string\n uploadedPath?: string\n textContent?: string | null\n mimeType?: string\n }>,\n): MessageContent {\n if (attachments.length === 0) return text\n const textSegments: string[] = []\n\n if (text.trim()) {\n textSegments.push(text)\n }\n\n for (const attachment of attachments) {\n let fileText: string\n if (attachment.uploadedPath) {\n const displayName = attachment.uploadedPath.split(\"/\").pop() || attachment.name\n fileText = `[附件: ${displayName}] 已上传到工作区路径: ${attachment.uploadedPath}`\n } else if (attachment.textContent) {\n const MAX_TEXT_CHARS = 100_000\n const content =\n attachment.textContent.length > MAX_TEXT_CHARS\n ? `${attachment.textContent.slice(0, MAX_TEXT_CHARS)}\\n\\n[内容已截断,原始共 ${attachment.textContent.length} 字符]`\n : attachment.textContent\n fileText = `[附件: ${attachment.name}]\\n${content}`\n } else {\n fileText = `[附件: ${attachment.name}]`\n }\n textSegments.push(fileText)\n }\n\n return textSegments.join(\"\\n\\n\")\n}\n\nexport function contentPreview(content: MessageContent, maxLen = 80): string {\n const text = getTextContent(content).trim()\n return text.length > maxLen ? `${text.slice(0, maxLen)}…` : text\n}\n\n/**\n * Transform a skill mention into a natural language skill invocation.\n * Strips the `<skill>name</skill>` tag from the raw input and prepends the instruction.\n */\nexport function transformSlashCommand(skillName: string, rawInput: string): string {\n const prompt = rawInput.replace(`<skill>${skillName}</skill>`, \"\").trim()\n return prompt\n ? `请使用 ${skillName} skill 完成任务\\n${prompt}`\n : `请使用 ${skillName} skill 完成任务`\n}\n\nconst ATTACHMENT_TAG_RE = /\\[附件:\\s*([^\\]]+)\\](?:[ \\t]*已上传到工作区路径:[ \\t]*([^\\r\\n]+))?/g\n// 来自 addContext 的 context 在发送时序列化为独立 text part:`[上下文: LABEL]\\nCONTENT`\n// 整块 part 匹配而非行内替换,避免破坏正文中可能出现的\"[上下文:\"字样\nconst CONTEXT_PART_RE = /^\\[上下文:\\s*([^\\]]+)\\]\\n([\\s\\S]*)$/\n\nexport interface ParsedTextAttachment {\n name: string\n uploadedPath?: string\n}\n\nexport interface ParsedTextContext {\n label: string\n content: string\n}\n\n/**\n * Extract `[附件: name]` and `[上下文: label]` tags from text parts and return\n * the cleaned text plus the collected attachment / context metadata. 每个 text\n * part 独立匹配,以避免跨 part 拼接打乱正则。\n */\nexport function extractTextAttachments(content: MessageContent): {\n cleanText: string\n attachments: ParsedTextAttachment[]\n contexts: ParsedTextContext[]\n} {\n if (typeof content === \"string\") {\n const attachments: ParsedTextAttachment[] = []\n const contexts: ParsedTextContext[] = []\n const ctxMatch = CONTEXT_PART_RE.exec(content)\n let working = content\n if (ctxMatch) {\n contexts.push({ label: ctxMatch[1].trim(), content: ctxMatch[2].trim() })\n working = \"\"\n }\n for (const match of working.matchAll(ATTACHMENT_TAG_RE)) {\n attachments.push({\n name: match[1].trim(),\n uploadedPath: match[2]?.trim() || undefined,\n })\n }\n return {\n cleanText: working.replace(ATTACHMENT_TAG_RE, \"\"),\n attachments,\n contexts,\n }\n }\n\n const attachments: ParsedTextAttachment[] = []\n const contexts: ParsedTextContext[] = []\n const cleanParts: string[] = []\n\n for (const part of content) {\n if (part.type !== \"text\") continue\n\n const ctxMatch = CONTEXT_PART_RE.exec(part.text)\n if (ctxMatch) {\n contexts.push({ label: ctxMatch[1].trim(), content: ctxMatch[2].trim() })\n continue\n }\n\n let hasAttachment = false\n for (const match of part.text.matchAll(ATTACHMENT_TAG_RE)) {\n attachments.push({\n name: match[1].trim(),\n uploadedPath: match[2]?.trim() || undefined,\n })\n hasAttachment = true\n }\n if (hasAttachment) {\n const remaining = part.text.replace(ATTACHMENT_TAG_RE, \"\")\n if (remaining.trim()) cleanParts.push(remaining)\n } else {\n cleanParts.push(part.text)\n }\n }\n\n return { cleanText: cleanParts.join(\"\\n\"), attachments, contexts }\n}\n\nexport function getImageParts(content: MessageContent): ImageUrlContentPart[] {\n if (typeof content === \"string\") return []\n return content.filter((part): part is ImageUrlContentPart => part.type === \"image_url\")\n}\n\nexport function getFileParts(content: MessageContent): FileContentPart[] {\n if (typeof content === \"string\") return []\n return content.filter((part): part is FileContentPart => part.type === \"file\")\n}\n\ninterface MessageGroup {\n root: ChatMessage | null\n childLoops: { loopName: string; messages: ChatMessage[] }[]\n}\n\nexport function groupMessagesByLoop(messages: ChatMessage[]): MessageGroup[] {\n const groups: MessageGroup[] = []\n let currentGroup: MessageGroup | null = null\n\n for (const msg of messages) {\n const loop = msg.loop_name ?? \"root\"\n\n if (loop === \"root\") {\n currentGroup = { root: msg, childLoops: [] }\n groups.push(currentGroup)\n } else {\n if (!currentGroup) {\n currentGroup = { root: null, childLoops: [] }\n groups.push(currentGroup)\n }\n const existingLoop = currentGroup.childLoops.find((l) => l.loopName === loop)\n if (existingLoop) {\n existingLoop.messages.push(msg)\n } else {\n currentGroup.childLoops.push({ loopName: loop, messages: [msg] })\n }\n }\n }\n\n return groups\n}\n","import type { ChatMessage, CompactionInfo, MessageContent, ToolCallInfo } from \"../schemas/message\"\nimport { normalizeMessageContent } from \"../schemas/message-utils\"\nimport type { ContentBlock, PatchEnvelope, TurnProjection } from \"../schemas/projection\"\nimport type { SessionStatus } from \"../schemas/session\"\n\n/** 一次 AskUserQuestion 的用户作答(选项选择 + 自定义输入)。 */\nexport interface AskUserAnswerData {\n selections: Record<number, number[]>\n custom: Record<number, string>\n}\n\nexport interface AgentLoopInfo {\n toolCallId: string\n description: string\n status: \"running\" | \"done\" | \"error\" | \"cancelled\" | \"awaiting_answer\"\n}\n\nexport interface ActiveCompactionState extends CompactionInfo {\n turn_id: string\n status: \"streaming\" | \"completed\" | \"paused\" | \"failed\" | \"interrupted\"\n}\n\nexport type ConnectionStatus = \"connecting\" | \"connected\" | \"reconnecting\" | \"disconnected\"\n\n/**\n * 一个会话的完整快照。引用不可变:任何变更都会产生新对象,\n * 满足 React `useSyncExternalStore` / Vue `shallowRef` 的订阅契约。\n */\nexport interface SessionState {\n sessionId: string\n /** 服务端投影的原始 turn 列表(按 sequence 有序)。 */\n turns: TurnProjection[]\n /** 由 turns 物化出的聊天消息列表,UI 直接渲染。 */\n messages: ChatMessage[]\n /** 智能体是否正在流式回复。 */\n isStreaming: boolean\n /** 会话状态(running / completed / failed / waiting_for_input / interrupted …)。 */\n status: SessionStatus | null\n /** 当前模式(planning / executing),来自 mode_change 事件。 */\n mode: \"planning\" | \"executing\" | null\n /** Socket.IO 连接状态(同一 client 下所有会话共享)。 */\n connection: ConnectionStatus\n /** 最近一次运行错误消息(system:error 等)。 */\n errorMessage: string | null\n askAnswers: Record<string, AskUserAnswerData>\n agentLoops: Record<string, AgentLoopInfo>\n activeCompaction: ActiveCompactionState | null\n}\n\nexport function createInitialSessionState(sessionId: string): SessionState {\n return {\n sessionId,\n turns: [],\n messages: [],\n isStreaming: false,\n status: null,\n mode: null,\n connection: \"disconnected\",\n errorMessage: null,\n askAnswers: {},\n agentLoops: {},\n activeCompaction: null,\n }\n}\n\nfunction parseAgentDescription(argumentsJson: string): string {\n try {\n return JSON.parse(argumentsJson)?.description ?? \"子智能体\"\n } catch {\n return \"子智能体\"\n }\n}\n\n/** 与 react 端 display-utils.formatToolName 保持一致:去掉 provider 前缀(如 \"fork:Agent\" → \"Agent\")。 */\nfunction normalizedToolName(name: string): string {\n const separatorIndex = name.lastIndexOf(\":\")\n return separatorIndex >= 0 ? name.slice(separatorIndex + 1) : name\n}\n\nfunction inferLoopStatusFromMessages(messages: ChatMessage[]): AgentLoopInfo[\"status\"] {\n const toolCalls = messages.flatMap((message) => message.tool_calls ?? [])\n if (messages.some((message) => message.status === \"streaming\")) return \"running\"\n if (toolCalls.some((toolCall) => toolCall.status === \"awaiting_answer\")) return \"awaiting_answer\"\n if (toolCalls.some((toolCall) => toolCall.status === \"error\")) return \"error\"\n if (toolCalls.some((toolCall) => toolCall.status === \"cancelled\")) return \"cancelled\"\n if (toolCalls.some((toolCall) => toolCall.status === \"pending\")) return \"running\"\n return \"done\"\n}\n\nfunction inferLoopStatusFromTurns(\n turns: TurnProjection[],\n messages: ChatMessage[],\n): AgentLoopInfo[\"status\"] {\n const latestAgentNotification = [...turns]\n .reverse()\n .flatMap((turn) => turn.blocks)\n .find((block) => {\n if (block.type !== \"system_notification\" || !isRecord(block.content)) return false\n return (\n block.content.notification_type === \"agent:start\" ||\n block.content.notification_type === \"agent:end\"\n )\n })\n if (\n latestAgentNotification?.type === \"system_notification\" &&\n isRecord(latestAgentNotification.content)\n ) {\n const notificationType = latestAgentNotification.content.notification_type\n const status = latestAgentNotification.content.status\n if (notificationType === \"agent:start\" || status === \"running\") return \"running\"\n if (status === \"error\") return \"error\"\n if (status === \"cancelled\") return \"cancelled\"\n }\n return inferLoopStatusFromMessages(messages)\n}\n\nfunction isRecord(value: unknown): value is Record<string, unknown> {\n return typeof value === \"object\" && value !== null && !Array.isArray(value)\n}\n\nfunction parentForkToolCallIdFromTurn(turn: TurnProjection): string | null {\n if (\n typeof turn.parent_fork_tool_call_id === \"string\" &&\n turn.parent_fork_tool_call_id.length > 0\n ) {\n return turn.parent_fork_tool_call_id\n }\n for (const block of turn.blocks) {\n if (block.type !== \"system_notification\" || !isRecord(block.content)) continue\n const metadata = block.content.metadata\n if (!isRecord(metadata)) continue\n const parentId = metadata.parent_fork_tool_call_id\n if (typeof parentId === \"string\" && parentId.length > 0) return parentId\n }\n return null\n}\n\nfunction buildMessageContent(turn: TurnProjection): MessageContent {\n const textBlocks = turn.blocks.filter((block) => block.type === \"text\")\n if (textBlocks.length === 0) return \"\"\n if (textBlocks.length === 1) return normalizeMessageContent(textBlocks[0].content)\n return textBlocks\n .map((block) => {\n if (typeof block.content === \"string\") return block.content\n return JSON.stringify(block.content)\n })\n .join(\"\")\n}\n\nfunction askUserAnswerContent(turn: TurnProjection): string | null {\n const answerBlock = turn.blocks.find((block) => block.type === \"ask_user_answer\")\n if (!answerBlock || !isRecord(answerBlock.content)) return null\n const answer = answerBlock.content.answer\n return typeof answer === \"string\" && answer.trim().length > 0 ? answer : null\n}\n\nfunction buildReasoning(turn: TurnProjection): string | undefined {\n const thinking = turn.blocks\n .filter((block) => block.type === \"thinking\")\n .map((block) => (typeof block.content === \"string\" ? block.content : JSON.stringify(block.content)))\n .filter(Boolean)\n if (thinking.length === 0) return undefined\n return thinking.join(\"\\n\\n\")\n}\n\nfunction isModeChangeContent(value: unknown): value is { from: string; to: string } {\n return (\n typeof value === \"object\" &&\n value !== null &&\n typeof (value as { from?: unknown }).from === \"string\" &&\n typeof (value as { to?: unknown }).to === \"string\"\n )\n}\n\nexport function extractModeFromBlocks(blocks: ContentBlock[]): \"planning\" | \"executing\" | null {\n const modeBlock = blocks.find((block) => block.type === \"mode_change\")\n if (modeBlock && isModeChangeContent(modeBlock.content)) {\n return modeBlock.content.to === \"planning\" || modeBlock.content.to === \"executing\"\n ? modeBlock.content.to\n : null\n }\n return null\n}\n\nfunction projectionToMessage(turn: TurnProjection): ChatMessage | null {\n if (turn.kind === \"compaction\" && turn.compaction_id) {\n return {\n role: \"assistant\",\n content: turn.summary_preview ?? \"\",\n kind: \"compaction\",\n loop_name: turn.loop_id,\n entry_id: turn.turn_id,\n status: turn.status,\n compaction: {\n compaction_id: turn.compaction_id,\n summary_preview: turn.summary_preview,\n summary_full: turn.summary_full,\n archived_count: turn.archived_count,\n archived_files: turn.archived_files,\n archived_tool_calls: turn.archived_tool_calls,\n tokens_before: turn.tokens_before,\n tokens_after: turn.tokens_after,\n saved_ratio: turn.saved_ratio,\n trigger: turn.trigger,\n failure_reason: turn.failure_reason,\n fallback_applied: turn.fallback_applied,\n },\n }\n }\n\n const planningBlock = turn.blocks.find(\n (block) => block.type === \"mode_change\" || block.type === \"plan_status\",\n )\n if (planningBlock) {\n if (planningBlock.type === \"plan_status\") {\n return {\n role: \"tool\",\n content:\n typeof planningBlock.content === \"string\"\n ? planningBlock.content\n : JSON.stringify(planningBlock.content ?? {}, null, 2),\n kind: \"plan_status\",\n loop_name: turn.loop_id,\n entry_id: turn.turn_id,\n status: turn.status,\n }\n }\n return {\n role: \"assistant\",\n content:\n typeof planningBlock.content === \"string\"\n ? planningBlock.content\n : JSON.stringify(planningBlock.content ?? {}),\n kind: planningBlock.type,\n loop_name: turn.loop_id,\n entry_id: turn.turn_id,\n status: turn.status,\n }\n }\n\n const askAnswer = askUserAnswerContent(turn)\n if (askAnswer !== null) {\n return {\n role: \"user\",\n content: askAnswer,\n blocks: turn.blocks,\n loop_name: turn.loop_id,\n entry_id: turn.turn_id,\n status: turn.status,\n ...(typeof turn.duration_ms === \"number\" ? { duration_ms: turn.duration_ms } : {}),\n ...(turn.started_at ? { timestamp: turn.started_at } : {}),\n }\n }\n\n const content = buildMessageContent(turn)\n const reasoning = buildReasoning(turn)\n const toolCalls: ToolCallInfo[] | undefined =\n turn.tool_calls.length > 0\n ? turn.tool_calls.map((toolCall) => ({\n id: toolCall.id,\n name: toolCall.tool_name,\n display_name: toolCall.display_name,\n arguments: toolCall.arguments,\n result: toolCall.result ?? undefined,\n pending_question_ref: toolCall.pending_question_ref ?? undefined,\n status:\n toolCall.status === \"pending\" ||\n toolCall.status === \"awaiting_answer\" ||\n toolCall.status === \"done\" ||\n toolCall.status === \"error\" ||\n toolCall.status === \"cancelled\"\n ? toolCall.status\n : \"pending\",\n ...(typeof toolCall.duration_ms === \"number\" ? { duration_ms: toolCall.duration_ms } : {}),\n }))\n : undefined\n\n if (turn.role === \"system\" && !content && !toolCalls?.length) {\n return null\n }\n\n return {\n role: turn.role === \"system\" ? \"assistant\" : turn.role,\n content,\n blocks: turn.blocks,\n ...(reasoning ? { reasoning } : {}),\n ...(toolCalls ? { tool_calls: toolCalls } : {}),\n loop_name: turn.loop_id,\n entry_id: turn.turn_id,\n status: turn.status,\n ...(typeof turn.duration_ms === \"number\" ? { duration_ms: turn.duration_ms } : {}),\n ...(turn.started_at ? { timestamp: turn.started_at } : {}),\n ...(turn.memory_refs?.length ? { memory_refs: turn.memory_refs } : {}),\n }\n}\n\nconst messageProjectionCache = new WeakMap<TurnProjection, ChatMessage | null>()\n\nfunction cachedProjectionToMessage(turn: TurnProjection): ChatMessage | null {\n if (messageProjectionCache.has(turn)) {\n return messageProjectionCache.get(turn) ?? null\n }\n const message = projectionToMessage(turn)\n messageProjectionCache.set(turn, message)\n return message\n}\n\nfunction rebuildAgentLoops(\n turns: TurnProjection[],\n messages: ChatMessage[],\n): Record<string, AgentLoopInfo> {\n const childLoopNames = [\n ...new Set(turns.map((turn) => turn.loop_id).filter((name) => name !== \"root\")),\n ]\n if (childLoopNames.length === 0) return {}\n\n const agentToolCalls = messages\n .filter((message) => message.role === \"assistant\" && (message.loop_name ?? \"root\") === \"root\")\n .flatMap((message) => message.tool_calls ?? [])\n .filter((toolCall) => normalizedToolName(toolCall.name) === \"Agent\")\n\n const loops: Record<string, AgentLoopInfo> = {}\n const agentToolCallsById = new Map(agentToolCalls.map((toolCall) => [toolCall.id, toolCall]))\n const explicitParentToolCallIds = new Set(\n turns.map(parentForkToolCallIdFromTurn).filter((id): id is string => id !== null),\n )\n const usedToolCallIds = new Set<string>()\n for (const loopName of childLoopNames) {\n const loopMessages = messages.filter((message) => (message.loop_name ?? \"root\") === loopName)\n const loopTurns = turns.filter((turn) => turn.loop_id === loopName)\n const parentToolCallId = loopTurns.map(parentForkToolCallIdFromTurn).find(Boolean)\n const explicitToolCall =\n parentToolCallId && !usedToolCallIds.has(parentToolCallId)\n ? (agentToolCallsById.get(parentToolCallId) ?? null)\n : null\n const fallbackToolCall =\n explicitToolCall === null\n ? agentToolCalls.find(\n (toolCall) =>\n !usedToolCallIds.has(toolCall.id) && !explicitParentToolCallIds.has(toolCall.id),\n )\n : null\n const toolCall = explicitToolCall ?? fallbackToolCall\n if (!toolCall) continue\n usedToolCallIds.add(toolCall.id)\n loops[loopName] = {\n toolCallId: toolCall.id,\n description: parseAgentDescription(toolCall.arguments),\n status: inferLoopStatusFromTurns(loopTurns, loopMessages),\n }\n }\n return loops\n}\n\nfunction materialize(turns: TurnProjection[]) {\n const projectedMessages = turns\n .map(cachedProjectionToMessage)\n .filter((message): message is ChatMessage => message !== null)\n const messages = projectedMessages.filter((message, index, allMessages) => {\n if (!message.blocks?.some((block) => block.type === \"ask_user_answer\")) return true\n const next = allMessages[index + 1]\n return !(next?.role === \"user\" && next.content === message.content)\n })\n const activeCompaction = [...turns]\n .reverse()\n .find(\n (turn): turn is TurnProjection =>\n turn.kind === \"compaction\" &&\n turn.status === \"streaming\" &&\n typeof turn.compaction_id === \"string\",\n )\n return {\n messages,\n agentLoops: rebuildAgentLoops(turns, projectedMessages),\n activeCompaction: activeCompaction\n ? {\n turn_id: activeCompaction.turn_id,\n status: activeCompaction.status,\n compaction_id: activeCompaction.compaction_id!,\n summary_preview: activeCompaction.summary_preview,\n summary_full: activeCompaction.summary_full,\n archived_count: activeCompaction.archived_count,\n archived_files: activeCompaction.archived_files,\n archived_tool_calls: activeCompaction.archived_tool_calls,\n tokens_before: activeCompaction.tokens_before,\n tokens_after: activeCompaction.tokens_after,\n saved_ratio: activeCompaction.saved_ratio,\n trigger: activeCompaction.trigger,\n failure_reason: activeCompaction.failure_reason,\n fallback_applied: activeCompaction.fallback_applied,\n }\n : null,\n }\n}\n\nconst ERROR_ANCHOR_PREFIX = \"error-anchor:\"\n\nfunction orderTurns(turns: TurnProjection[]) {\n for (let index = 1; index < turns.length; index += 1) {\n if (turns[index - 1].sequence > turns[index].sequence) {\n return [...turns].sort((left, right) => left.sequence - right.sequence)\n }\n }\n return turns\n}\n\nfunction areAgentLoopsEqual(\n left: Record<string, AgentLoopInfo> | undefined,\n right: Record<string, AgentLoopInfo>,\n) {\n if (!left) return Object.keys(right).length === 0\n const leftEntries = Object.entries(left)\n const rightKeys = Object.keys(right)\n if (leftEntries.length !== rightKeys.length) return false\n return leftEntries.every(([key, value]) => {\n const next = right[key]\n return (\n next !== undefined &&\n value.toolCallId === next.toolCallId &&\n value.description === next.description &&\n value.status === next.status\n )\n })\n}\n\n/**\n * 用一份新的 turn 列表重建会话状态。\n * addErrorMessage 注入的 role===\"error\" 消息不在 turns 里,默认会被物化过程抹掉;\n * 这里沿用锚点策略:只保留锚定在\"当前最后一个 turn\"上的错误气泡,\n * turn 推进(新消息 / rewind / 重连)时旧错误自动消失。\n */\nexport function withTurns(state: SessionState, turns: TurnProjection[]): SessionState {\n const orderedTurns = orderTurns(turns)\n const { messages, agentLoops, activeCompaction } = materialize(orderedTurns)\n const isWaitingForInput = orderedTurns.some((turn) =>\n turn.tool_calls.some((toolCall) => toolCall.status === \"awaiting_answer\"),\n )\n const stableAgentLoops = areAgentLoopsEqual(state.agentLoops, agentLoops)\n ? state.agentLoops\n : agentLoops\n const lastTurnId = orderedTurns[orderedTurns.length - 1]?.turn_id ?? null\n const preservedErrors = lastTurnId\n ? state.messages.filter(\n (m) =>\n m.role === \"error\" &&\n typeof m.entry_id === \"string\" &&\n m.entry_id.startsWith(`${ERROR_ANCHOR_PREFIX}${lastTurnId}:`),\n )\n : []\n const mergedMessages = preservedErrors.length > 0 ? [...messages, ...preservedErrors] : messages\n const latestMode = [...orderedTurns]\n .reverse()\n .map((turn) => extractModeFromBlocks(turn.blocks))\n .find((mode): mode is \"planning\" | \"executing\" => mode !== null)\n return {\n ...state,\n turns: orderedTurns,\n messages: mergedMessages,\n agentLoops: stableAgentLoops,\n activeCompaction,\n mode: latestMode ?? state.mode,\n // 历史恢复时 chat:end(paused) 可能已不在 socket replay 缓存中;\n // awaiting_answer 是投影里的持久权威状态,必须据此恢复问答交互。\n status: isWaitingForInput ? \"waiting_for_input\" : state.status,\n }\n}\n\nlet localTurnCounter = 0\n\nexport function addUserMessage(state: SessionState, content: MessageContent): SessionState {\n localTurnCounter += 1\n const turnId = `local-user-${Date.now()}-${localTurnCounter}`\n const optimisticTurn: TurnProjection = {\n id: turnId,\n sequence: Math.max(0, ...state.turns.map((turn) => turn.sequence)) + 1,\n turn_id: turnId,\n loop_id: \"root\",\n role: \"user\",\n status: \"streaming\",\n blocks: [{ type: \"text\", content }],\n tool_calls: [],\n model: null,\n usage: null,\n duration_ms: 0,\n }\n return withTurns(state, [...state.turns, optimisticTurn])\n}\n\nexport function upsertTurn(state: SessionState, turn: TurnProjection): SessionState {\n let existing = [...state.turns]\n if (turn.role === \"user\" && !turn.turn_id.startsWith(\"local-user-\")) {\n existing = existing.filter((t) => !t.turn_id.startsWith(\"local-user-\"))\n }\n const index = existing.findIndex((item) => item.turn_id === turn.turn_id)\n if (index >= 0) {\n existing[index] = turn\n } else {\n existing.push(turn)\n }\n return withTurns(state, existing)\n}\n\nexport function applyTurnPatch(state: SessionState, patch: PatchEnvelope): SessionState {\n const turn = patch.data.turn\n if (!turn) return state\n\n const existing = [...state.turns]\n const index = existing.findIndex((item) => item.turn_id === turn.turn_id)\n const lastSequence = index >= 0 ? existing[index].sequence : null\n if (lastSequence !== null && patch.sequence <= lastSequence) {\n return state\n }\n\n const nextTurn = { ...turn, sequence: patch.sequence }\n if (index >= 0) {\n existing[index] = nextTurn\n } else {\n existing.push(nextTurn)\n }\n return withTurns(state, existing)\n}\n\nexport function addErrorMessage(state: SessionState, content: string): SessionState {\n const anchorTurnId = state.turns[state.turns.length - 1]?.turn_id ?? null\n const entry_id = anchorTurnId\n ? `${ERROR_ANCHOR_PREFIX}${anchorTurnId}:${Date.now()}`\n : undefined\n return {\n ...state,\n messages: [...state.messages, { role: \"error\", content, loop_name: \"root\", entry_id }],\n }\n}\n\nexport function markInterrupted(state: SessionState): SessionState {\n return markStreamingTurns(state, \"interrupted\", \"cancelled\")\n}\n\nexport function markFailed(state: SessionState): SessionState {\n return markStreamingTurns(state, \"failed\", \"error\")\n}\n\nfunction markStreamingTurns(\n state: SessionState,\n turnStatus: \"interrupted\" | \"failed\",\n toolCallStatus: \"cancelled\" | \"error\",\n): SessionState {\n const turns = state.turns.map((turn) => {\n if (turn.status !== \"streaming\") return turn\n return {\n ...turn,\n status: turnStatus,\n tool_calls: turn.tool_calls.map((toolCall) =>\n toolCall.status === \"pending\" || toolCall.status === \"awaiting_answer\"\n ? { ...toolCall, status: toolCallStatus }\n : toolCall,\n ),\n }\n })\n return withTurns(state, turns)\n}\n","import { ClientProjectionBuilder, type RawEvent } from \"../shared/projection\"\nimport type { MessageContent, ToolBridgeContent, ToolCallInfo } from \"../schemas/message\"\nimport type { ContentBlock, PatchEnvelope, TurnProjection } from \"../schemas/projection\"\nimport type { SessionStatus } from \"../schemas/session\"\nimport { CommandRegistry, type CommandHandler } from \"../commands/registry\"\nimport { Emitter, type AgentSessionEvents } from \"./events\"\nimport {\n addErrorMessage,\n addUserMessage,\n applyTurnPatch,\n createInitialSessionState,\n extractModeFromBlocks,\n markFailed,\n markInterrupted,\n upsertTurn,\n withTurns,\n type AskUserAnswerData,\n type ConnectionStatus,\n type SessionState,\n} from \"./state\"\n\n/** SessionHub 注入给 AgentSession 的运行时依赖(socket 收发 + REST 补数)。 */\nexport interface SessionRuntime {\n emitEvent(event: string, data: unknown): void\n emitWithAck(\n event: string,\n data: unknown,\n timeoutMs: number,\n ): Promise<Record<string, unknown> | undefined>\n ensureConnected(): void\n fetchTurns(sessionId: string): Promise<TurnProjection[]>\n onDispose(session: AgentSession): void\n}\n\nexport interface SendOptions {\n /** planning / executing 模式。 */\n mode?: string\n /** AskUserQuestion 的作答(tool_call_id + 选项)。 */\n askUserAnswer?: Record<string, unknown>\n /** 本次运行的模型覆盖。 */\n model?: string\n /** 本次运行是否强制开/关思考。 */\n thinkingOverride?: boolean\n whatif?: {\n from_step: number\n quotes: Array<Record<string, unknown>>\n deprecate_entry_ids: string[]\n }\n replayDecision?: \"keep_replay\" | \"continue_replay\"\n}\n\nconst OOM_MESSAGE = \"沙盒内存使用超出限制,已自动重启。如果经常触发,可以联系管理员调整额度。\"\n\n// ASCII 关键词用 \\b;中文\"退出码\"不能依赖 \\b(CJK 在 JS 正则里不算 word),\n// 137 两端用 (?<!\\d)(?!\\d) 锚定,避免 1370 之类误判。\nconst OOM_KEYWORDS_RE = /(?:\\b(?:exit_code|ExitedWith|exited with)|退出码)\\D*(?<!\\d)137(?!\\d)/i\n\nfunction isRecord(value: unknown): value is Record<string, unknown> {\n return typeof value === \"object\" && value !== null && !Array.isArray(value)\n}\n\nfunction isOomText(value: unknown): boolean {\n return typeof value === \"string\" && OOM_KEYWORDS_RE.test(value)\n}\n\nfunction parseJsonRecord(value: unknown): Record<string, unknown> | null {\n if (isRecord(value)) return value\n if (typeof value !== \"string\") return null\n try {\n const parsed = JSON.parse(value)\n return isRecord(parsed) ? parsed : null\n } catch {\n return null\n }\n}\n\nfunction isOomResult(value: unknown): boolean {\n if (Array.isArray(value)) {\n return value.some((part) => isOomResult(part))\n }\n if (typeof value === \"object\" && value !== null) {\n const record = value as Record<string, unknown>\n if (record.exit_code === 137) return true\n if (typeof record.text === \"string\" && isOomText(record.text)) return true\n if (typeof record.content === \"string\" && isOomText(record.content)) return true\n return false\n }\n if (typeof value === \"string\") {\n const parsed = parseJsonRecord(value)\n if (parsed?.exit_code === 137) return true\n return isOomText(value)\n }\n return false\n}\n\nfunction isToolBridgeContent(value: unknown): value is ToolBridgeContent {\n return (\n typeof value === \"object\" &&\n value !== null &&\n !Array.isArray(value) &&\n typeof (value as { action?: unknown }).action === \"string\"\n )\n}\n\nexport function sessionStatusFromChatEnd(status: string | undefined): SessionStatus {\n if (status === \"paused\") return \"waiting_for_input\"\n if (status === \"interrupted\") return \"interrupted\"\n if (status === \"failed\") return \"failed\"\n return \"completed\"\n}\n\nfunction extractTerminalChatEndStatus(events: RawEvent[]): string | null {\n for (let i = events.length - 1; i >= 0; i--) {\n const event = events[i]\n if (event?.type !== \"chat:end\") continue\n const status = event.payload?.status\n return typeof status === \"string\" ? status : \"completed\"\n }\n return null\n}\n\ninterface UiMetaLike {\n target?: string\n title?: string\n resourceHTML?: string\n resourceUri?: string\n resourceURI?: string\n}\n\nfunction isUiMetaLike(value: unknown): value is UiMetaLike {\n return isRecord(value) && (\"resourceHTML\" in value || \"resourceUri\" in value || \"resourceURI\" in value)\n}\n\n/**\n * 一个会话的实时状态机:封装 Socket.IO 订阅、历史 + 流式合流、断线补数,\n * 对外只有三样东西——状态快照(getState/subscribe)、动作(send/stop/…)、\n * 语义事件(on/onCommand)。\n *\n * 状态完全归属实例:同一页面创建多个 AgentSession 互不干扰。\n */\nexport class AgentSession {\n readonly sessionId: string\n\n private state: SessionState\n private readonly listeners = new Set<() => void>()\n private readonly emitter = new Emitter<AgentSessionEvents>()\n private readonly commands = new CommandRegistry()\n private readonly runtime: SessionRuntime\n private readonly projectionBuilder = new ClientProjectionBuilder()\n\n private readonly pendingTurnPatches = new Map<string, PatchEnvelope>()\n private patchFlushHandle: number | ReturnType<typeof globalThis.setTimeout> | null = null\n private patchFlushCancel: (() => void) | null = null\n\n private joined = false\n private joinPending: Promise<void> | null = null\n private pendingReplayMessage: MessageContent | null = null\n private pendingReplayMode: string | undefined\n private recentChatEndAt = 0\n private disposed = false\n\n private readonly deliveredCommandKeys = new Set<string>()\n private readonly deliveredToolPreviews = new Map<string, string>()\n private readonly oomNotifiedKeys = new Set<string>()\n private readonly seenToolCallIds = new Set<string>()\n private readonly finishedToolCallIds = new Set<string>()\n private readonly emittedMessageTurnIds = new Set<string>()\n\n constructor(sessionId: string, runtime: SessionRuntime, connection: ConnectionStatus) {\n this.sessionId = sessionId\n this.runtime = runtime\n this.state = { ...createInitialSessionState(sessionId), connection }\n }\n\n /** 从一份静态 turn 快照构造只展示历史的会话(例如公开分享页)。 */\n static fromTurns(sessionId: string, turns: TurnProjection[]): AgentSession {\n const readonlyError = () => {\n throw new Error(\"静态会话只用于展示历史,不能执行会话操作\")\n }\n const session = new AgentSession(\n sessionId,\n {\n emitEvent: readonlyError,\n emitWithAck: async () => readonlyError(),\n ensureConnected: readonlyError,\n fetchTurns: async () => turns,\n onDispose: () => undefined,\n },\n \"connected\",\n )\n session.state = {\n ...withTurns(session.state, turns),\n status: \"completed\",\n }\n return session\n }\n\n // ---------------------------------------------------------------- 状态订阅\n\n /** 返回当前会话快照。引用稳定:状态未变化时返回同一对象。 */\n getState(): SessionState {\n return this.state\n }\n\n /** 订阅状态变化。返回取消订阅函数。 */\n subscribe(listener: () => void): () => void {\n this.listeners.add(listener)\n return () => {\n this.listeners.delete(listener)\n }\n }\n\n private setState(next: SessionState): void {\n if (next === this.state) return\n this.state = next\n for (const listener of [...this.listeners]) {\n try {\n listener()\n } catch (error) {\n console.warn(\"[agent-client] 状态订阅回调抛出异常:\", error)\n }\n }\n }\n\n private update(fn: (state: SessionState) => SessionState): void {\n this.setState(fn(this.state))\n }\n\n // ---------------------------------------------------------------- 语义事件\n\n /** 监听语义事件(底层逃生舱,见 events.ts)。返回取消函数。 */\n on<K extends keyof AgentSessionEvents>(\n name: K,\n handler: (event: AgentSessionEvents[K]) => void,\n ): () => void {\n return this.emitter.on(name, handler)\n }\n\n off<K extends keyof AgentSessionEvents>(\n name: K,\n handler: (event: AgentSessionEvents[K]) => void,\n ): void {\n this.emitter.off(name, handler)\n }\n\n /**\n * 监听智能体下发给宿主页面的指令。\n *\n * action 是技能作者在工具返回值 `_meta.bridge` 里写的契约字符串(如\n * \"map.highlight\"),由你和技能作者约定;注册前到达的指令会被缓冲补投。\n */\n onCommand(action: string, handler: CommandHandler): () => void {\n return this.commands.onCommand(action, handler)\n }\n\n // ---------------------------------------------------------------- 动作\n\n /** 发送一条消息。字符串或多模态内容均可。 */\n async send(content: MessageContent, options: SendOptions = {}): Promise<void> {\n this.runtime.ensureConnected()\n if (this.state.isStreaming) {\n this.update((s) => addErrorMessage(s, \"当前回复尚未结束,请稍后再发送。\"))\n return\n }\n await this.ensureIdleBeforeSend()\n if (this.state.isStreaming) {\n this.update((s) => addErrorMessage(s, \"当前回复尚未结束,请稍后再发送。\"))\n return\n }\n const askUserAnswer = options.askUserAnswer\n if (!(askUserAnswer && typeof askUserAnswer.tool_call_id === \"string\")) {\n this.update((s) => addUserMessage(s, content))\n }\n this.update((s) => ({ ...s, isStreaming: true }))\n if (askUserAnswer && typeof askUserAnswer.tool_call_id === \"string\") {\n const { tool_call_id, ...rest } = askUserAnswer\n this.update((s) => ({\n ...s,\n askAnswers: { ...s.askAnswers, [tool_call_id as string]: rest as unknown as AskUserAnswerData },\n }))\n }\n if (!options.replayDecision) {\n this.pendingReplayMessage = content\n this.pendingReplayMode = options.mode\n }\n const payload = {\n session_id: this.sessionId,\n message: content,\n mode: options.mode,\n askuser_answer: askUserAnswer,\n model: options.model,\n thinking_override: options.thinkingOverride,\n whatif: options.whatif,\n replay_decision: options.replayDecision,\n }\n try {\n await this.ensureJoined()\n } catch (error) {\n this.update((s) =>\n addErrorMessage(\n { ...s, isStreaming: false, status: \"failed\" },\n error instanceof Error && error.message ? error.message : \"会话订阅失败,消息未发送\",\n ),\n )\n return\n }\n this.runtime.emitEvent(\"chat:send\", payload)\n }\n\n /** 智能体运行期间追加补充说明(不打断当前回复)。 */\n append(text: string): void {\n this.runtime.ensureConnected()\n this.runtime.emitEvent(\"chat:append\", { session_id: this.sessionId, message: text })\n this.update((s) => addUserMessage(s, text))\n }\n\n /** 停止当前回复。 */\n stop(): Promise<Record<string, unknown>> {\n return this.runtime\n .emitWithAck(\"chat:stop\", { session_id: this.sessionId }, 35_000)\n .then((response) => response ?? {})\n }\n\n /** 手动触发上下文压缩。 */\n compact(): Promise<Record<string, unknown>> {\n return this.runtime\n .emitWithAck(\"chat:compact\", { session_id: this.sessionId }, 30_000)\n .then((response) => response ?? {})\n }\n\n /**\n * 把一段业务数据作为附件放进聊天输入框(比如地图上选中的点位)。\n * 附件随下一条消息一起发给智能体。需要 ChatView / useChat 渲染层配合展示;\n * 无 UI 场景可直接用 send()。\n */\n attach(label: string, data: unknown): void {\n const content = typeof data === \"string\" ? data : JSON.stringify(data, null, 2)\n this.emitter.emit(\"attachRequested\", { label, content })\n }\n\n /** 往聊天输入框追加一段文字(不发送)。 */\n insertText(text: string): void {\n this.emitter.emit(\"insertTextRequested\", { text })\n }\n\n /** 释放订阅与监听器。之后该实例不再接收任何事件。 */\n dispose(): void {\n if (this.disposed) return\n this.disposed = true\n this.cancelPatchFlush()\n this.listeners.clear()\n this.emitter.clear()\n this.commands.clear()\n this.runtime.onDispose(this)\n }\n\n get isDisposed(): boolean {\n return this.disposed\n }\n\n // ------------------------------------------------------- Hub 回调(内部)\n\n /** @internal 连接状态变化(同 client 下所有会话共享一条连接)。 */\n _setConnection(connection: ConnectionStatus): void {\n if (this.state.connection === connection) return\n this.update((s) => ({ ...s, connection }))\n }\n\n /** @internal socket 重连后由 Hub 调用:重新加入房间并补数。 */\n async _rejoinAfterReconnect(): Promise<void> {\n const turnsBeforeRejoin = this.state.turns\n this.joined = false\n this.joinPending = null\n try {\n await this.ensureJoined()\n await this.syncTurnsFromHistory({\n clearOnEmpty: true,\n preserveChangesSince: turnsBeforeRejoin,\n })\n } catch {\n // 重连补数尽力而为;后续 Socket 重连仍会再次尝试\n }\n }\n\n /** @internal 首次连接:加载历史 + 加入房间。 */\n async _bootstrap(): Promise<void> {\n await this.syncTurnsFromHistory({ suppressErrors: false })\n await this.ensureJoined()\n }\n\n /** @internal */\n _handleTurnStart(turn: TurnProjection): void {\n this.markRunningIfIdle()\n this.applyTurn(turn)\n }\n\n /** @internal */\n _handleTurnPatch(patch: PatchEnvelope): void {\n this.markRunningIfIdle()\n if (patch.data.workspace_changed) {\n this.emitter.emit(\"workspaceChanged\", {})\n }\n const current = this.pendingTurnPatches.get(patch.turn_id)\n if (!current || patch.sequence >= current.sequence) {\n this.pendingTurnPatches.set(patch.turn_id, patch)\n }\n this.schedulePatchFlush()\n }\n\n /** @internal */\n _handleTurnEnd(turn: TurnProjection): void {\n this.applyTurn(turn)\n }\n\n /** @internal 历史回放通道(event_format: raw)。 */\n _handleTurnEvents(events: RawEvent[]): void {\n if (!events.length) return\n const terminalChatEndStatus = extractTerminalChatEndStatus(events)\n if (!terminalChatEndStatus) {\n this.markRunningIfIdle()\n }\n if (this.state.turns.length) {\n this.projectionBuilder.seedSequence(Math.max(...this.state.turns.map((t) => t.sequence)))\n }\n const updates = this.projectionBuilder.processBatch(events)\n for (const update of updates) {\n if (update.kind === \"upsert\") {\n this.applyTurn(update.turn)\n } else if (update.kind === \"workspace_changed\") {\n this.emitter.emit(\"workspaceChanged\", {})\n }\n }\n if (terminalChatEndStatus) {\n this.finishStreaming(terminalChatEndStatus)\n }\n }\n\n /** @internal */\n _handleChatStart(): void {\n this.update((s) => ({ ...s, status: \"running\", errorMessage: null, isStreaming: true }))\n }\n\n /** @internal */\n _handleChatEnd(status: string): void {\n this.flushPatches()\n this.finishStreaming(status)\n this.recentChatEndAt = Date.now()\n void this.syncTurnsFromHistory()\n this.emitter.emit(\"chatEnd\", { status })\n }\n\n /** @internal */\n _handleSystemError(message: string): void {\n this.flushPatches()\n const finalMessage = isOomText(message) ? OOM_MESSAGE : message\n this.update((s) =>\n addErrorMessage(markFailed({ ...s, status: \"failed\", errorMessage: finalMessage, isStreaming: false }), finalMessage),\n )\n this.recentChatEndAt = Date.now()\n this.emitter.emit(\"error\", { message: finalMessage })\n }\n\n /** @internal */\n _handleTaskUpdated(tasks: unknown[]): void {\n this.emitter.emit(\"taskListUpdated\", { tasks })\n }\n\n /** @internal */\n _handleWorkspaceFilesChanged(filePath?: string): void {\n this.emitter.emit(\"workspaceChanged\", { filePath })\n }\n\n /** @internal */\n _handleSessionUpdated(data: {\n intent?: string\n status?: SessionStatus\n model?: string | null\n bound_skill_id?: string | null\n replay_state?: Record<string, unknown> | null\n }): void {\n if (data.status) {\n this.update((s) => ({ ...s, status: data.status ?? s.status }))\n }\n this.emitter.emit(\"sessionUpdated\", {\n intent: data.intent,\n status: data.status,\n model: data.model,\n boundSkillId: data.bound_skill_id,\n replayState: data.replay_state,\n })\n }\n\n /** @internal */\n _handleRewind(checkpointId: string): void {\n this.update((s) => ({ ...s, mode: null, errorMessage: null }))\n void this.syncTurnsFromHistory({ clearOnEmpty: true })\n this.emitter.emit(\"rewind\", { checkpointId })\n }\n\n /** @internal */\n _handleReplayMismatch(data: { actual_message?: string; expected_message?: string }): void {\n const message = this.pendingReplayMessage ?? data.actual_message ?? \"\"\n const mode = this.pendingReplayMode\n this.pendingReplayMessage = null\n this.pendingReplayMode = undefined\n const respond = (decision: \"keep_replay\" | \"continue_replay\") => {\n this.runtime.emitEvent(\"chat:send\", {\n session_id: this.sessionId,\n message,\n mode,\n replay_decision: decision,\n })\n }\n const handled = this.emitter.emitFirst(\"replayMismatch\", {\n actualMessage: data.actual_message,\n expectedMessage: data.expected_message,\n respond,\n })\n if (!handled) {\n respond(\"continue_replay\")\n }\n }\n\n /** @internal */\n _handleSystemNotification(loopId: string, notification: Record<string, unknown>): void {\n const notificationType =\n typeof notification.notification_type === \"string\"\n ? notification.notification_type\n : \"system_notification\"\n const title = typeof notification.title === \"string\" ? notification.title : notificationType\n const detail =\n typeof notification.detail === \"string\"\n ? notification.detail\n : notification.detail == null\n ? undefined\n : JSON.stringify(notification.detail)\n const status =\n notification.status === \"running\" || notification.status === \"done\" || notification.status === \"error\"\n ? notification.status\n : \"info\"\n this.emitter.emit(\"notification\", {\n type: notificationType,\n title,\n detail,\n status,\n loopId,\n metadata: isRecord(notification.metadata) ? notification.metadata : undefined,\n })\n if (notificationType === \"bg:started\" && isRecord(notification.metadata)) {\n const taskId =\n typeof notification.metadata.task_id === \"string\" ? notification.metadata.task_id : \"\"\n if (taskId) {\n this.emitter.emit(\"backgroundTask\", {\n id: taskId,\n command:\n typeof notification.metadata.command === \"string\" ? notification.metadata.command : \"\",\n description:\n typeof notification.metadata.description === \"string\"\n ? notification.metadata.description\n : undefined,\n status: \"running\",\n elapsedSeconds: 0,\n })\n }\n }\n }\n\n /** @internal */\n _handleBackgroundTask(task: {\n id: string\n command: string\n description?: string\n status: \"running\" | \"done\" | \"failed\"\n exitCode?: number | null\n elapsedSeconds: number\n output?: string\n }): void {\n this.emitter.emit(\"backgroundTask\", task)\n }\n\n /** @internal */\n _handleArtifact(event: AgentSessionEvents[\"artifact\"]): void {\n this.emitter.emit(\"artifact\", event)\n }\n\n /** @internal 加入房间的应答里带 is_running,据此校准流式状态。 */\n _applyRunningState(isRunning: boolean): void {\n if (isRunning) {\n this.update((s) => ({ ...s, status: \"running\", isStreaming: true }))\n } else if (this.state.isStreaming) {\n this.update((s) => ({ ...s, isStreaming: false }))\n void this.syncTurnsFromHistory()\n }\n }\n\n // ---------------------------------------------------------------- 内部实现\n\n private markRunningIfIdle(): void {\n if (!this.state.isStreaming) {\n this.update((s) => ({ ...s, status: \"running\", isStreaming: true }))\n }\n }\n\n private finishStreaming(status: string): void {\n const sessionStatus = sessionStatusFromChatEnd(status)\n this.update((s) => {\n let next: SessionState = { ...s, status: sessionStatus, isStreaming: false }\n if (status === \"interrupted\") next = markInterrupted(next)\n else if (status === \"failed\") next = markFailed(next)\n return next\n })\n }\n\n private applyTurn(turn: TurnProjection): void {\n this.flushPatches()\n const previous = this.state\n this.update((s) => upsertTurn(s, turn))\n this.emitTurnDerivedEvents(previous, turn)\n }\n\n private schedulePatchFlush(): void {\n if (this.patchFlushHandle != null) return\n const flush = () => {\n this.patchFlushHandle = null\n this.patchFlushCancel = null\n this.flushPatches()\n }\n if (typeof window !== \"undefined\" && typeof window.requestAnimationFrame === \"function\") {\n const handle = window.requestAnimationFrame(flush)\n this.patchFlushHandle = handle\n this.patchFlushCancel = () => window.cancelAnimationFrame(handle)\n return\n }\n const handle = globalThis.setTimeout(flush, 33)\n this.patchFlushHandle = handle\n this.patchFlushCancel = () => globalThis.clearTimeout(handle)\n }\n\n private cancelPatchFlush(): void {\n this.patchFlushCancel?.()\n this.patchFlushHandle = null\n this.patchFlushCancel = null\n this.pendingTurnPatches.clear()\n }\n\n private flushPatches(): void {\n if (this.pendingTurnPatches.size === 0) return\n const patches = [...this.pendingTurnPatches.values()].sort(\n (left, right) => left.sequence - right.sequence,\n )\n this.pendingTurnPatches.clear()\n for (const patch of patches) {\n const previous = this.state\n this.update((s) => applyTurnPatch(s, patch))\n const turn = patch.data.turn\n if (turn) {\n this.emitTurnDerivedEvents(previous, turn)\n }\n }\n if (this.patchFlushCancel) {\n this.patchFlushCancel()\n this.patchFlushHandle = null\n this.patchFlushCancel = null\n }\n }\n\n /** turn 数据落地后统一派生语义事件(指令 / 工具调用 / 消息 / 模式 / 预览 / OOM)。 */\n private emitTurnDerivedEvents(previous: SessionState, turn: TurnProjection): void {\n const mode = extractModeFromBlocks(turn.blocks)\n if (mode && previous.mode !== mode) {\n this.emitter.emit(\"modeChange\", { mode })\n }\n\n for (const block of turn.blocks) {\n if (block.type === \"tool_result\" && isOomResult(block.content)) {\n this.notifySandboxOom(block.tool_call_id ?? turn.id)\n }\n if (block.type === \"tool_bridge\" && isToolBridgeContent(block.content)) {\n this.dispatchCommand(turn, block)\n continue\n }\n if (block.type === \"tool_ui\" && block.tool_call_id && isUiMetaLike(block.content)) {\n const ui = block.content\n if (ui.target !== \"preview\") continue\n const previewType = ui.resourceHTML ? (\"resource-html\" as const) : (\"resource-uri\" as const)\n const previewContent = ui.resourceHTML ?? ui.resourceUri ?? ui.resourceURI\n if (!previewContent) continue\n const key = `${block.tool_call_id}:${previewType}`\n if (this.deliveredToolPreviews.get(key) === previewContent) continue\n this.deliveredToolPreviews.set(key, previewContent)\n this.emitter.emit(\"toolPreview\", {\n toolCallId: block.tool_call_id,\n type: previewType,\n content: previewContent,\n title: ui.title ?? \"工具预览\",\n })\n }\n if (block.type === \"system_notification\" && isRecord(block.content)) {\n this._handleSystemNotification(turn.loop_id, block.content)\n }\n }\n\n for (const toolCall of turn.tool_calls) {\n const info: ToolCallInfo = {\n id: toolCall.id,\n name: toolCall.tool_name,\n display_name: toolCall.display_name,\n arguments: toolCall.arguments,\n result: toolCall.result ?? undefined,\n status:\n toolCall.status === \"pending\" ||\n toolCall.status === \"awaiting_answer\" ||\n toolCall.status === \"done\" ||\n toolCall.status === \"error\" ||\n toolCall.status === \"cancelled\"\n ? toolCall.status\n : (\"pending\" as const),\n }\n if (!this.seenToolCallIds.has(toolCall.id)) {\n this.seenToolCallIds.add(toolCall.id)\n this.emitter.emit(\"toolCall\", { toolCall: info, turn })\n }\n const finished =\n toolCall.status === \"done\" || toolCall.status === \"error\" || toolCall.status === \"cancelled\"\n if (finished && !this.finishedToolCallIds.has(toolCall.id)) {\n this.finishedToolCallIds.add(toolCall.id)\n this.emitter.emit(\"toolResult\", { toolCall: info, turn })\n if (isOomResult(toolCall.result)) {\n this.notifySandboxOom(toolCall.id)\n }\n }\n }\n\n if (turn.status !== \"streaming\" && !this.emittedMessageTurnIds.has(turn.turn_id)) {\n const message = this.state.messages.find((m) => m.entry_id === turn.turn_id)\n if (message) {\n this.emittedMessageTurnIds.add(turn.turn_id)\n this.emitter.emit(\"message\", { message, turn })\n }\n }\n }\n\n private dispatchCommand(turn: TurnProjection, block: ContentBlock): void {\n if (!isToolBridgeContent(block.content)) return\n const { action, payload } = block.content\n let payloadKey = \"\"\n try {\n payloadKey = JSON.stringify(payload ?? null)\n } catch {\n payloadKey = String(payload ?? \"\")\n }\n const deliveryKey = [block.tool_call_id ?? turn.id, action, payloadKey].join(\"\u0000\")\n if (this.deliveredCommandKeys.has(deliveryKey)) return\n this.deliveredCommandKeys.add(deliveryKey)\n const meta = { toolCallId: block.tool_call_id ?? undefined }\n this.emitter.emit(\"command\", { action, payload, toolCallId: meta.toolCallId })\n this.commands.dispatch(action, payload, meta)\n }\n\n private notifySandboxOom(key: string): void {\n if (this.oomNotifiedKeys.has(key)) return\n this.oomNotifiedKeys.add(key)\n this.update((s) => addErrorMessage(s, OOM_MESSAGE))\n this.emitter.emit(\"sandboxOom\", { toolCallId: key })\n }\n\n private async syncTurnsFromHistory(\n options: {\n clearOnEmpty?: boolean\n suppressErrors?: boolean\n preserveChangesSince?: TurnProjection[]\n } = {},\n ): Promise<void> {\n const { clearOnEmpty = false, suppressErrors = true, preserveChangesSince } = options\n const turnsAtRequestStart = this.state.turns\n try {\n const turns = await this.runtime.fetchTurns(this.sessionId)\n if (turns.length === 0 && !clearOnEmpty) return\n this.update((state) => {\n const mergeBaseline = preserveChangesSince ?? turnsAtRequestStart\n if (state.turns === mergeBaseline) return withTurns(state, turns)\n\n // REST 补数与刚恢复的实时事件可能并发。历史响应只覆盖补数流程开始前的\n // 快照;期间新到或 sequence 更新的 turn 必须保留,不能被旧响应抹掉。\n const historyById = new Map(turns.map((turn) => [turn.turn_id, turn]))\n let merged = withTurns(state, turns)\n for (const current of state.turns) {\n const fromHistory = historyById.get(current.turn_id)\n if (!fromHistory || current.sequence > fromHistory.sequence) {\n merged = upsertTurn(merged, current)\n }\n }\n return merged\n })\n this.replayCommandsFromTurns(turns)\n } catch (error) {\n if (!suppressErrors) throw error\n // 尽力而为的历史补数,失败时保留现有内存状态\n }\n }\n\n /**\n * 把历史里的指令补投给宿主页面。\n *\n * 重开会话、断线补数时,地图高亮这类\"页面当前状态\"必须能恢复——\n * 否则刷新一次页面,之前智能体让页面做的事就全丢了。\n * 只回放指令:toolCall / message 这些事件如果按历史全量重放,\n * 监听器会在挂载瞬间收到几百条陈年事件。\n * dispatch 内部按 deliveredCommandKeys 去重,重复调用安全。\n */\n private replayCommandsFromTurns(turns: TurnProjection[]): void {\n for (const turn of turns) {\n for (const block of turn.blocks) {\n if (block.type === \"tool_bridge\" && isToolBridgeContent(block.content)) {\n this.dispatchCommand(turn, block)\n }\n }\n }\n }\n\n private ensureJoined(): Promise<void> {\n if (this.joined) return Promise.resolve()\n if (this.joinPending) return this.joinPending\n\n const join = this.runtime\n .emitWithAck(\n \"session:subscribe\",\n { session_id: this.sessionId, event_format: \"raw\", resume: true },\n 5_000,\n )\n .then((response) => {\n if (response && response.ok === false) {\n throw new Error(\n typeof response.message === \"string\" && response.message\n ? response.message\n : \"Session subscription failed\",\n )\n }\n this.joined = true\n this._applyRunningState(Boolean(response?.is_running))\n })\n .finally(() => {\n this.joinPending = null\n })\n\n this.joinPending = join\n return join\n }\n\n private async ensureIdleBeforeSend(): Promise<void> {\n if (Date.now() - this.recentChatEndAt > 3000) return\n const deadline = Date.now() + 3000\n while (Date.now() < deadline) {\n const response = await this.stop()\n const status = String(response.status ?? \"\")\n if (status !== \"stopping\") return\n await new Promise((resolve) => globalThis.setTimeout(resolve, 150))\n }\n }\n}\n","import type { BladeClient } from \"../blade-client\"\nimport type { PatchEnvelope, TurnProjection } from \"../schemas/projection\"\nimport type { RawEvent } from \"../shared/projection\"\nimport { AgentSession, type SessionRuntime } from \"./agent-session\"\nimport type { ConnectionStatus } from \"./state\"\n\ntype BackgroundTaskEvent = {\n id?: string\n task_id?: string\n command?: string\n description?: string\n status?: string\n exit_code?: number | null\n elapsed_seconds?: number\n output_lines_count?: number\n output_preview?: string[]\n}\n\n/**\n * 每个 BladeClient 一个:管理一条 Socket.IO 连接,按 session_id 把事件\n * 路由给各 AgentSession 实例。多会话共享连接、状态互不干扰。\n */\nexport class SessionHub {\n private readonly client: BladeClient\n private readonly sessions = new Map<string, AgentSession>()\n private readonly bootstrapPending = new Map<string, Promise<AgentSession>>()\n private connection: ConnectionStatus = \"disconnected\"\n private readonly connectionListeners = new Set<(status: ConnectionStatus) => void>()\n private bound = false\n private hasConnected = false\n\n constructor(client: BladeClient) {\n this.client = client\n }\n\n /** 当前 Socket.IO 连接状态。 */\n getConnection(): ConnectionStatus {\n return this.connection\n }\n\n /** 订阅连接状态变化。 */\n onConnectionChange(listener: (status: ConnectionStatus) => void): () => void {\n this.connectionListeners.add(listener)\n return () => {\n this.connectionListeners.delete(listener)\n }\n }\n\n /** 取得(或复用)一个会话的 AgentSession,并完成历史加载 + 房间订阅。 */\n async connect(sessionId: string): Promise<AgentSession> {\n // 版本握手在建立实时连接前完成:对着旧 Server 应该报「版本不匹配」,\n // 而不是握手成功后在事件格式上莫名其妙地崩掉。\n await this.client.ensureVersionCompatible()\n const existing = this.sessions.get(sessionId)\n if (existing && !existing.isDisposed) {\n return this.bootstrapPending.get(sessionId) ?? existing\n }\n this.ensureBound()\n const session = new AgentSession(sessionId, this.runtimeFor(), this.connection)\n this.sessions.set(sessionId, session)\n this.ensureConnected()\n const bootstrap = session._bootstrap().then(() => session)\n this.bootstrapPending.set(sessionId, bootstrap)\n try {\n return await bootstrap\n } catch (error) {\n session.dispose()\n throw error\n } finally {\n if (this.bootstrapPending.get(sessionId) === bootstrap) {\n this.bootstrapPending.delete(sessionId)\n }\n }\n }\n\n /** 已有实例则返回,不触发网络请求。 */\n peek(sessionId: string): AgentSession | undefined {\n if (this.bootstrapPending.has(sessionId)) return undefined\n const session = this.sessions.get(sessionId)\n return session && !session.isDisposed ? session : undefined\n }\n\n /** 手动重连(例如登录态变化后)。 */\n reconnect(): void {\n // 登录态可能早于首个 AgentSession 初始化;必须先绑定连接监听,\n // 否则 connect 事件会在 hub 尚未监听时丢失,状态永久停在 connecting。\n this.ensureBound()\n const socket = this.client.socket()\n socket.disconnect()\n this.setConnection(\"connecting\")\n socket.connect()\n }\n\n /** 断开连接(不清理 session 实例)。 */\n disconnect(): void {\n this.client.socket().disconnect()\n this.setConnection(\"disconnected\")\n }\n\n /** 清理当前身份下缓存的全部会话,避免切换登录身份后复用旧快照。 */\n disposeAll(): void {\n this.bootstrapPending.clear()\n for (const session of [...this.sessions.values()]) {\n session.dispose()\n }\n }\n\n /**\n * @internal 底层 socket 被换掉时由 BladeClient 调用(如 setBaseUrl)。\n * 事件监听器绑在旧 socket 实例上,换新实例后必须重绑,否则所有\n * turn:* / chat:* 事件都会静默丢弃。\n */\n _handleSocketReplaced(): void {\n this.bound = false\n this.setConnection(\"disconnected\")\n if (this.sessions.size === 0) return\n // 已有会话:在新 socket 上重建监听;连接成功事件会重新加入房间并补数\n this.ensureBound()\n this.ensureConnected()\n }\n\n private runtimeFor(): SessionRuntime {\n return {\n emitEvent: (event, data) => {\n // biome-ignore lint/suspicious/noExplicitAny: 泛化 emit,事件名由调用方保证\n ;(this.client.socket() as any).emit(event, data)\n },\n emitWithAck: (event, data, timeoutMs) =>\n new Promise((resolve, reject) => {\n // biome-ignore lint/suspicious/noExplicitAny: 泛化 emit,事件名由调用方保证\n ;(this.client.socket() as any)\n .timeout(timeoutMs)\n .emit(event, data, (err: Error | null, response?: Record<string, unknown>) => {\n if (err) {\n reject(err)\n return\n }\n resolve(response)\n })\n }),\n ensureConnected: () => this.ensureConnected(),\n fetchTurns: (sessionId) => this.client.sessions.getSessionTurns(sessionId),\n onDispose: (session) => {\n if (this.sessions.get(session.sessionId) === session) {\n this.sessions.delete(session.sessionId)\n }\n // biome-ignore lint/suspicious/noExplicitAny: session:unsubscribe 是后端自定义事件\n ;(this.client.socket() as any).emit(\"session:unsubscribe\", { session_id: session.sessionId })\n },\n }\n }\n\n private ensureConnected(): void {\n const socket = this.client.socket()\n if (socket.connected || socket.active) return\n this.setConnection(\"connecting\")\n socket.connect()\n }\n\n private setConnection(status: ConnectionStatus): void {\n if (this.connection === status) return\n this.connection = status\n for (const session of this.sessions.values()) {\n session._setConnection(status)\n }\n for (const listener of [...this.connectionListeners]) {\n try {\n listener(status)\n } catch (error) {\n console.warn(\"[agent-client] 连接状态回调抛出异常:\", error)\n }\n }\n }\n\n /** 事件带 session_id 时精确路由;缺省时按当前唯一活跃会话兜底。 */\n private route(sessionId: string | null | undefined): AgentSession[] {\n if (sessionId) {\n const session = this.sessions.get(sessionId)\n return session && !session.isDisposed ? [session] : []\n }\n const active = [...this.sessions.values()].filter((session) => !session.isDisposed)\n return active.length === 1 ? active : []\n }\n\n private ensureBound(): void {\n if (this.bound) return\n this.bound = true\n // biome-ignore lint/suspicious/noExplicitAny: 事件桥接层统一收敛混合 payload\n const socket = this.client.socket() as any\n\n socket.on(\"connect\", () => {\n const isReconnect = this.hasConnected\n this.hasConnected = true\n this.setConnection(\"connected\")\n if (isReconnect) {\n for (const session of this.sessions.values()) {\n void session._rejoinAfterReconnect()\n }\n }\n })\n socket.on(\"connect_error\", () => this.setConnection(\"disconnected\"))\n socket.on(\"disconnect\", () => this.setConnection(\"disconnected\"))\n socket.io.on(\"reconnect_attempt\", () => this.setConnection(\"reconnecting\"))\n\n socket.on(\"turn:start\", (data: TurnProjection & { session_id?: string }) => {\n for (const session of this.route(data.session_id)) session._handleTurnStart(data)\n })\n socket.on(\"turn:patch\", (data: PatchEnvelope & { session_id?: string }) => {\n for (const session of this.route(data.session_id)) session._handleTurnPatch(data)\n })\n socket.on(\"turn:end\", (data: TurnProjection & { session_id?: string }) => {\n for (const session of this.route(data.session_id)) session._handleTurnEnd(data)\n })\n socket.on(\"turn:events\", (data: { session_id?: string; events: RawEvent[] }) => {\n for (const session of this.route(data.session_id)) session._handleTurnEvents(data.events ?? [])\n })\n socket.on(\"chat:start\", (data?: { session_id?: string }) => {\n for (const session of this.route(data?.session_id)) session._handleChatStart()\n })\n socket.on(\"chat:end\", (data?: { status?: string; session_id?: string }) => {\n for (const session of this.route(data?.session_id)) {\n session._handleChatEnd(data?.status ?? \"completed\")\n }\n })\n socket.on(\"system:error\", (data: { message: string; session_id?: string }) => {\n for (const session of this.route(data.session_id)) session._handleSystemError(data.message)\n })\n socket.on(\n \"system:notification\",\n (data: { session_id?: string } & Record<string, unknown>) => {\n for (const session of this.route(data.session_id)) {\n session._handleSystemNotification(\"root\", data)\n }\n },\n )\n socket.on(\"task:updated\", (data: { tasks: unknown[]; session_id?: string }) => {\n for (const session of this.route(data.session_id)) session._handleTaskUpdated(data.tasks)\n })\n socket.on(\"task:synced\", (data: { tasks: unknown[]; session_id?: string }) => {\n for (const session of this.route(data.session_id)) session._handleTaskUpdated(data.tasks)\n })\n socket.on(\n \"workspace:files_changed\",\n (data: { session_id?: string; file_path?: string }) => {\n for (const session of this.route(data.session_id)) {\n session._handleWorkspaceFilesChanged(data.file_path)\n }\n },\n )\n socket.on(\n \"session:updated\",\n (data: {\n session_id?: string\n intent?: string\n status?: import(\"../schemas/session\").SessionStatus\n model?: string | null\n bound_skill_id?: string | null\n replay_state?: Record<string, unknown> | null\n }) => {\n for (const session of this.route(data.session_id)) {\n session._handleSessionUpdated(data)\n }\n },\n )\n socket.on(\"session:rewind\", (data: { checkpoint_id: string; session_id?: string }) => {\n for (const session of this.route(data.session_id)) {\n session._handleRewind(data.checkpoint_id)\n }\n })\n socket.on(\n \"replay:input_mismatch\",\n (data: { session_id?: string; actual_message?: string; expected_message?: string }) => {\n for (const session of this.route(data.session_id)) session._handleReplayMismatch(data)\n },\n )\n socket.on(\"artifact:created\", (data: Record<string, unknown> & { session_id?: string }) => {\n this.routeArtifact(data, \"created\")\n })\n socket.on(\"artifact:updated\", (data: Record<string, unknown> & { session_id?: string }) => {\n this.routeArtifact(data, \"updated\")\n })\n socket.on(\"bg:started\", (data: BackgroundTaskEvent & { session_id?: string }) => {\n const taskId =\n typeof data.task_id === \"string\" ? data.task_id : typeof data.id === \"string\" ? data.id : \"\"\n if (!taskId) return\n for (const session of this.route(data.session_id)) {\n session._handleBackgroundTask({\n id: taskId,\n command: typeof data.command === \"string\" ? data.command : \"\",\n description: typeof data.description === \"string\" ? data.description : undefined,\n status: \"running\",\n elapsedSeconds: typeof data.elapsed_seconds === \"number\" ? data.elapsed_seconds : 0,\n })\n }\n })\n socket.on(\n \"bg:tasks_completed\",\n (data: { tasks?: BackgroundTaskEvent[]; session_id?: string }) => {\n for (const session of this.route(data.session_id)) {\n for (const task of data.tasks ?? []) {\n const taskId =\n typeof task.id === \"string\"\n ? task.id\n : typeof task.task_id === \"string\"\n ? task.task_id\n : \"\"\n if (!taskId) continue\n session._handleBackgroundTask({\n id: taskId,\n command: typeof task.command === \"string\" ? task.command : \"\",\n description: typeof task.description === \"string\" ? task.description : undefined,\n status: task.status === \"running\" || task.status === \"failed\" ? task.status : \"done\",\n exitCode:\n typeof task.exit_code === \"number\" || task.exit_code === null\n ? task.exit_code\n : undefined,\n elapsedSeconds: typeof task.elapsed_seconds === \"number\" ? task.elapsed_seconds : 0,\n output:\n Array.isArray(task.output_preview) && task.output_preview.length > 0\n ? task.output_preview.join(\"\\n\")\n : undefined,\n })\n }\n }\n },\n )\n }\n\n private routeArtifact(\n data: Record<string, unknown> & { session_id?: string },\n kind: \"created\" | \"updated\",\n ): void {\n const filePath = typeof data.file_path === \"string\" ? data.file_path : \"\"\n if (!filePath) return\n for (const session of this.route(data.session_id)) {\n session._handleWorkspaceFilesChanged(filePath)\n session._handleArtifact({\n filePath,\n contentType: typeof data.content_type === \"string\" ? data.content_type : \"\",\n title: typeof data.title === \"string\" ? data.title : filePath,\n content: typeof data.content === \"string\" ? data.content : \"\",\n oldString: typeof data.old_string === \"string\" ? data.old_string : undefined,\n newString: typeof data.new_string === \"string\" ? data.new_string : undefined,\n kind,\n })\n }\n }\n}\n","import { io, type Socket } from \"socket.io-client\"\nimport { buildSocketAuth, resolveAuthToken, type AuthOptions } from \"./auth\"\nimport type { ClientToServerEvents, ServerToClientEvents } from \"./types/socket-events\"\nimport { SDK_NAME, SDK_VERSION } from \"./version\"\n\nexport type TypedSocket = Socket<ServerToClientEvents, ClientToServerEvents>\n\nexport interface CreateSocketOptions extends AuthOptions {\n baseUrl: string\n path?: string\n}\n\n/** 握手时声明 SDK 身份,让 Server 能把旧 agent-kit 挡在门外并给出升级提示。 */\nfunction withSdkIdentity(auth: { token: string } | undefined): Record<string, string> {\n return { ...(auth ?? {}), sdk: SDK_NAME, sdk_version: SDK_VERSION }\n}\n\nexport function createSocket(options: CreateSocketOptions): TypedSocket {\n const token = resolveAuthToken(options)\n return io(options.baseUrl, {\n path: options.path ?? \"/socket.io\",\n withCredentials: true,\n query: token ? { token } : undefined,\n auth:\n typeof options.token === \"function\"\n ? (cb) => cb(withSdkIdentity(buildSocketAuth(options)))\n : withSdkIdentity(buildSocketAuth(options)),\n autoConnect: false,\n })\n}\n","export interface AuthOptions {\n token?: string | (() => string | null | undefined)\n}\n\nexport function buildAuthHeaders(options: AuthOptions): Record<string, string> {\n const token = resolveAuthToken(options)\n if (!token) {\n return {}\n }\n return {\n Authorization: `Bearer ${token}`,\n }\n}\n\nexport function buildSocketAuth(options: AuthOptions): { token: string } | undefined {\n const token = resolveAuthToken(options)\n return token ? { token } : undefined\n}\n\nexport function resolveAuthToken(options: AuthOptions): string | null {\n const token = typeof options.token === \"function\" ? options.token() : options.token\n return token ? token : null\n}\n","/**\n * SDK 与 Server 的版本握手。\n *\n * 本次 SDK 拆分是一次性破坏性升级:旧 agent-kit 与新 Server、新 SDK 与旧 Server\n * 都不能工作。握手的目的不是兼容,而是把「新旧组合失配」从难以理解的运行时异常\n * 变成一句明确的升级指引。\n *\n * 方向一(本文件):SDK 在首次连接前查询 Server 版本,不匹配就拒绝连接。\n * 方向二(Server 侧):Server 校验请求头 X-Blade-SDK,旧客户端收到结构化错误。\n */\n\n/** 本 SDK 的名称与版本,随请求头与 Socket.IO 握手一并声明。 */\nexport const SDK_NAME = \"agent-client\"\nexport const SDK_VERSION = \"2.0.0\"\n\n/** REST 请求与 Socket 握手中声明 SDK 身份的标头名。 */\nexport const SDK_HEADER = \"X-Blade-SDK\"\n\n/** 新协议起始的 Server 版本;低于此版本的正式版 Server 只能配 agent-kit 1.1.0。 */\nexport const MIN_SERVER_VERSION = \"1.1.1\"\n\n/** 旧 SDK 包名,用于给旧 Server 的使用者指路。 */\nconst LEGACY_SDK = \"@blade-hq/agent-kit@1.1.0\"\n\nexport interface ServerVersionInfo {\n /** Server 自身版本号,如 \"1.1.1\"。 */\n version: string\n /**\n * Server 要求的最低 SDK 版本。未来再出现协议不兼容时,Server 抬高本字段即可,\n * SDK 侧无需改判断逻辑——这是避免下一次破坏性升级再痛一遍的关键。\n */\n min_sdk?: string\n}\n\nexport class VersionMismatchError extends Error {\n readonly serverVersion: string | null\n readonly sdkVersion: string\n readonly hint: string\n\n constructor(options: { serverVersion: string | null; hint: string }) {\n super(\n `SDK 与 Server 版本不匹配(SDK ${SDK_NAME}@${SDK_VERSION},` +\n `Server ${options.serverVersion ?? \"版本未知(不支持 /api/version)\"}):${options.hint}`,\n )\n this.name = \"VersionMismatchError\"\n this.serverVersion = options.serverVersion\n this.sdkVersion = SDK_VERSION\n this.hint = options.hint\n }\n}\n\n/**\n * 解析 `主.次.修订` 前缀,忽略预发布与构建元数据后缀。\n * 返回 null 表示无法解析(不参与比较,按预发布处理)。\n */\nfunction parseCoreVersion(version: string): [number, number, number] | null {\n const match = /^(\\d+)\\.(\\d+)\\.(\\d+)/.exec(version.trim())\n if (!match) return null\n return [Number(match[1]), Number(match[2]), Number(match[3])]\n}\n\n/** 预发布/开发版(如 1.1.1-dev.3、0.0.0+local)不参与拦截,避免卡住开发环境。 */\nexport function isPrerelease(version: string): boolean {\n const trimmed = version.trim()\n if (!parseCoreVersion(trimmed)) return true\n return /[-+]/.test(trimmed)\n}\n\n/** a < b 返回负数,相等返回 0,a > b 返回正数。无法解析时返回 0。 */\nexport function compareVersions(a: string, b: string): number {\n const left = parseCoreVersion(a)\n const right = parseCoreVersion(b)\n if (!left || !right) return 0\n for (let i = 0; i < 3; i++) {\n if (left[i] !== right[i]) return left[i] - right[i]\n }\n return 0\n}\n\n/**\n * 校验 Server 版本信息。不匹配抛 VersionMismatchError,匹配则正常返回。\n *\n * @param info Server /api/version 的响应;null 表示该接口不存在或不可达(旧 Server)。\n */\nexport function assertVersionCompatible(info: ServerVersionInfo | null): void {\n if (info === null) {\n throw new VersionMismatchError({\n serverVersion: null,\n hint:\n `该 Server 不提供 /api/version,说明版本低于 ${MIN_SERVER_VERSION}。` +\n `请改用 ${LEGACY_SDK} 接入,或把 Server 升级到 ${MIN_SERVER_VERSION} 及以上。`,\n })\n }\n\n // 预发布/开发版一律放行:本地 dev 构建的版本号不可靠,拦截只会挡住自己人。\n if (!isPrerelease(info.version) && compareVersions(info.version, MIN_SERVER_VERSION) < 0) {\n throw new VersionMismatchError({\n serverVersion: info.version,\n hint:\n `本 SDK 需要 Server ${MIN_SERVER_VERSION} 及以上。` +\n `请改用 ${LEGACY_SDK} 接入该 Server,或把 Server 升级到 ${MIN_SERVER_VERSION} 及以上。`,\n })\n }\n\n const minSdk = info.min_sdk\n if (minSdk && !isPrerelease(SDK_VERSION) && compareVersions(SDK_VERSION, minSdk) < 0) {\n throw new VersionMismatchError({\n serverVersion: info.version,\n hint: `该 Server 要求 SDK ${minSdk} 及以上,请把 ${SDK_NAME} 升级到 ${minSdk} 及以上。`,\n })\n }\n}\n","import {\n loginWithPopup,\n readStoredToken,\n writeStoredToken,\n type LoginOptions,\n type LoginResult,\n type TokenStorageMode,\n} from \"./auth-login\"\nimport {\n BladeApiError,\n type BladeFetchInit,\n type HttpMethod,\n decorateAuthError,\n extractErrorDetail,\n} from \"./rest\"\nimport { AuthResource } from \"./resources/auth\"\nimport { HeadlessResource } from \"./resources/headless\"\nimport { SessionsResource } from \"./resources/sessions\"\nimport { SessionHub } from \"./session/hub\"\nimport { createSocket, type TypedSocket } from \"./socket\"\nimport {\n type ServerVersionInfo,\n assertVersionCompatible,\n} from \"./version\"\n\nexport interface BladeClientOptions {\n /** 后端地址,如 \"https://blade.example.com\"。浏览器里传空字符串则使用当前域名。 */\n baseUrl: string\n /**\n * 访问令牌(PAT)。不传时按 cookie 会话模式工作;\n * 浏览器场景也可以不传,改用 client.auth.login() 弹窗登录。\n */\n token?: string | (() => string | null | undefined)\n /**\n * Socket.IO 专用令牌。第一方应用可在 REST 继续使用 cookie 刷新的同时,\n * 把 cookie 换得的短期令牌只用于实时连接;不传时复用 token。\n */\n socketToken?: string | (() => string | null | undefined)\n /** login() 取得的令牌存放位置,默认 \"local\"(localStorage,刷新页面不掉登录)。 */\n tokenStorage?: TokenStorageMode\n fetchImpl?: typeof fetch\n onRefreshSuccess?: () => void | Promise<void>\n}\n\nconst REFRESH_PATH = \"/api/auth/refresh\"\n\nexport class BladeClient {\n private refreshPromise: Promise<boolean> | null = null\n private socketInstance: TypedSocket | null = null\n private readonly socketReplacementListeners = new Set<() => void>()\n /** login() / setToken() 热挂载的令牌,优先级高于构造参数。 */\n private runtimeToken: string | null = null\n readonly options: BladeClientOptions\n readonly auth: AuthResource\n readonly headless: HeadlessResource\n readonly sessions: SessionsResource\n /** 实时会话中枢:client.sessions.connect() 内部使用,一般不直接访问。 */\n readonly hub: SessionHub\n /** 版本握手结果缓存:每个 client 实例只探测一次,不逐请求重复。 */\n private versionCheck: Promise<void> | null = null\n\n constructor(options: BladeClientOptions) {\n this.options = {\n ...options,\n baseUrl: normalizeBaseUrl(options.baseUrl),\n }\n this.auth = new AuthResource(this)\n this.headless = new HeadlessResource(this)\n this.sessions = new SessionsResource(this)\n this.hub = new SessionHub(this)\n if (this.options.token === undefined) {\n this.runtimeToken = readStoredToken(this.options.baseUrl)\n }\n }\n\n /**\n * 弹窗授权登录:用户在弹出的授权页点击\"许可授权\"后自动取得 PAT,\n * REST 与 Socket.IO 立即生效。只在浏览器可用。\n */\n async login(options?: LoginOptions): Promise<LoginResult> {\n const result = await loginWithPopup(this, options)\n this.setToken(result.token)\n return result\n }\n\n /** 退出登录:清除 login() 存储的令牌并断开实时连接。 */\n logoutToken(): void {\n this.setToken(null)\n this.hub.disconnect()\n }\n\n /** 热挂载访问令牌(null 表示清除)。会重建 Socket.IO 连接以携带新凭证。 */\n setToken(token: string | null): void {\n const previousToken = this.resolveToken()\n this.runtimeToken = token\n const nextToken = this.resolveToken()\n if (previousToken !== nextToken) {\n this.hub.disposeAll()\n }\n writeStoredToken(this.options.baseUrl, token, this.options.tokenStorage ?? \"local\")\n if (this.socketInstance) {\n const wasConnected = this.socketInstance.connected || this.socketInstance.active\n this.socketInstance.disconnect()\n if (wasConnected || token) {\n this.socketInstance.connect()\n }\n }\n }\n\n /** 当前是否持有访问令牌(不代表令牌一定有效)。 */\n hasToken(): boolean {\n return Boolean(this.resolveRestToken())\n }\n\n /**\n * 当前访问令牌(PAT),未登录时为 null。\n *\n * SDK 只封装会话相关接口;其余长尾接口对照后端 Swagger(`<baseUrl>/docs`)\n * 用原生 fetch 自行调用,把本令牌填入 Authorization 头即可:\n *\n * ```ts\n * fetch(`${baseUrl}/api/memories/search?q=xxx`, {\n * headers: { Authorization: `Bearer ${client.token}` },\n * })\n * ```\n *\n * 安全约束:该令牌只应发往 baseUrl 同源接口,不要附加到第三方域名的请求上。\n */\n get token(): string | null {\n return this.resolveRestToken()\n }\n\n /**\n * 版本握手:首次连接前查询 Server 版本,不匹配则抛 VersionMismatchError。\n * 结果缓存在实例上,失败的探测不缓存以便重试。\n */\n async ensureVersionCompatible(): Promise<void> {\n if (!this.versionCheck) {\n this.versionCheck = this.fetchServerVersion()\n .then(assertVersionCompatible)\n .catch((error) => {\n this.versionCheck = null\n throw error\n })\n }\n return this.versionCheck\n }\n\n /**\n * 读取 /api/version。接口存在但 404/响应不合法 → null(按旧 Server 处理);\n * 网络层不可达(后端没启动、端口不通、代理配错)→ 抛连接错误。\n * 两者必须区分:把「后端没起」误报成「版本不匹配,请改用 agent-kit」\n * 会把开发者引向完全错误的排查方向。\n */\n private async fetchServerVersion(): Promise<ServerVersionInfo | null> {\n let response: Response\n try {\n response = await this.fetch(\"GET\", \"/api/version\", { expectOk: false })\n } catch (error) {\n throw new Error(\n `无法连接到 Server(${this.options.baseUrl || \"当前域名\"})。请确认后端已启动、地址与端口正确。`,\n { cause: error },\n )\n }\n if (!response.ok) return null\n try {\n const info = (await response.json()) as ServerVersionInfo\n return typeof info?.version === \"string\" ? info : null\n } catch {\n return null\n }\n }\n\n setBaseUrl(baseUrl: string): void {\n const nextBaseUrl = normalizeBaseUrl(baseUrl)\n if (nextBaseUrl === this.options.baseUrl) {\n return\n }\n // 后端地址是会话身份边界,不是普通传输重连。旧 session_id、历史快照\n // 和房间订阅都不能带到另一个后端;先在旧 socket 上释放并驱逐缓存。\n this.hub.disposeAll()\n this.options.baseUrl = nextBaseUrl\n // 换了后端就是换了一台 Server,旧的版本握手结论不再成立。\n this.versionCheck = null\n if (this.socketInstance) {\n this.socketInstance.removeAllListeners()\n this.socketInstance.disconnect()\n this.socketInstance = null\n // 换掉 socket 实例后必须让 hub 重绑监听:监听器绑在旧实例上,\n // 不重绑的话新连接上的事件全部收不到。\n this.hub._handleSocketReplaced()\n for (const listener of [...this.socketReplacementListeners]) {\n try {\n listener()\n } catch (error) {\n console.warn(\"[agent-client] socket 替换回调抛出异常:\", error)\n }\n }\n }\n }\n\n /** 底层 Socket.IO 实例因后端地址变化而被替换时通知高级集成层。 */\n onSocketReplaced(listener: () => void): () => void {\n this.socketReplacementListeners.add(listener)\n return () => {\n this.socketReplacementListeners.delete(listener)\n }\n }\n\n socket(): TypedSocket {\n if (!this.socketInstance) {\n this.socketInstance = createSocket({\n baseUrl: this.options.baseUrl,\n token: () => this.resolveSocketToken(),\n })\n }\n return this.socketInstance\n }\n\n async json<T>(method: HttpMethod, path: string, body?: unknown): Promise<T> {\n const response = await this.fetch(method, path, {\n body: body === undefined ? undefined : JSON.stringify(body),\n headers: body === undefined ? undefined : { \"content-type\": \"application/json\" },\n })\n return readJsonResponse(response)\n }\n\n async jsonFromInit<T>(path: string, init: RequestInit = {}): Promise<T> {\n const method = (init.method ?? \"GET\").toUpperCase() as HttpMethod\n const headers = new Headers(init.headers)\n if (init.body != null && !isFormData(init.body) && !headers.has(\"content-type\")) {\n headers.set(\"content-type\", \"application/json\")\n }\n const response = await this.fetch(method, path, {\n body: init.body,\n credentials: init.credentials,\n headers,\n signal: init.signal,\n })\n return readJsonResponse(response)\n }\n\n async text(method: HttpMethod, path: string): Promise<string> {\n const response = await this.fetch(method, path)\n return response.text()\n }\n\n async textFromInit(path: string, init: RequestInit = {}): Promise<string> {\n const method = (init.method ?? \"GET\").toUpperCase() as HttpMethod\n const response = await this.fetch(method, path, {\n body: init.body,\n credentials: init.credentials,\n headers: init.headers,\n signal: init.signal,\n })\n return response.text()\n }\n\n async responseFromInit(path: string, init: RequestInit = {}): Promise<Response> {\n const method = (init.method ?? \"GET\").toUpperCase() as HttpMethod\n return this.fetch(method, path, {\n body: init.body,\n credentials: init.credentials,\n headers: init.headers,\n signal: init.signal,\n })\n }\n\n async blob(method: HttpMethod, path: string): Promise<Blob> {\n const response = await this.fetch(method, path)\n return response.blob()\n }\n\n async formData(\n method: HttpMethod,\n path: string,\n form: FormData,\n options: { expectOk?: boolean; onUploadProgress?: (progress: UploadProgress) => void } = {},\n ): Promise<Response> {\n if (options.onUploadProgress && !this.options.fetchImpl && typeof XMLHttpRequest !== \"undefined\") {\n return this.formDataWithUploadProgress(method, path, form, options)\n }\n return this.fetch(method, path, { body: form, expectOk: options.expectOk })\n }\n\n async fetch(\n method: HttpMethod,\n path: string,\n init: BladeFetchInit = {},\n isRetry = false,\n ): Promise<Response> {\n const url = this.buildUrl(path)\n const response = await (this.options.fetchImpl ?? fetch)(url.toString(), {\n method,\n body: init.body,\n credentials: init.credentials ?? \"include\",\n headers: this.buildHeaders(url, init.headers),\n signal: init.signal,\n })\n\n if (response.status === 401 && !isRetry && this.shouldRefreshFor401(url)) {\n const refreshed = await this.tryRefresh()\n if (refreshed) {\n return this.fetch(method, path, init, true)\n }\n }\n\n if (init.expectOk !== false && !response.ok) {\n const detail = await extractErrorDetail(response)\n throw decorateAuthError(new BladeApiError(response, detail))\n }\n return response\n }\n\n buildAuthedUrl(path: string): string {\n const url = new URL(this.toBaseRelativePath(path), this.baseUrlWithTrailingSlash())\n const token = this.resolveTokenForUrl(url)\n if (token) {\n url.searchParams.set(\"token\", token)\n }\n return url.toString()\n }\n\n private buildHeaders(url: URL, headers?: HeadersInit): Headers {\n const result = new Headers(headers)\n if (!this.isSameBackendUrl(url)) {\n return result\n }\n // REST 不做版本校验:SDK 身份只在 Socket.IO 握手声明(见 socket.ts)。\n // 长尾接口设计上就让第三方用原生 fetch 直接调,这里不该塞额外标头。\n const token = this.resolveRestToken()\n if (token) {\n result.set(\"Authorization\", `Bearer ${token}`)\n }\n return result\n }\n\n private buildUrl(path: string): URL {\n return new URL(this.toBaseRelativePath(path), this.baseUrlWithTrailingSlash())\n }\n\n private baseUrlWithTrailingSlash(): string {\n return this.options.baseUrl.endsWith(\"/\") ? this.options.baseUrl : `${this.options.baseUrl}/`\n }\n\n private toBaseRelativePath(path: string): string {\n return path.startsWith(\"/\") ? path.slice(1) : path\n }\n\n private isSameBackendUrl(url: URL): boolean {\n const base = new URL(this.baseUrlWithTrailingSlash())\n if (url.origin !== base.origin) {\n return false\n }\n const basePath = base.pathname.replace(/\\/+$/, \"\")\n if (basePath === \"\") {\n return true\n }\n return url.pathname === basePath || url.pathname.startsWith(`${basePath}/`)\n }\n\n private shouldRefreshFor401(url: URL): boolean {\n const refreshUrl = this.buildUrl(REFRESH_PATH)\n return (\n this.isSameBackendUrl(url) &&\n url.pathname !== refreshUrl.pathname &&\n !this.hasExplicitBearerToken()\n )\n }\n\n private hasExplicitBearerToken(): boolean {\n return Boolean(this.resolveRestToken())\n }\n\n private async tryRefresh(): Promise<boolean> {\n if (this.refreshPromise) {\n return this.refreshPromise\n }\n\n this.refreshPromise = (async () => {\n try {\n const response = await (this.options.fetchImpl ?? fetch)(\n this.buildUrl(REFRESH_PATH).toString(),\n {\n method: \"POST\",\n credentials: \"include\",\n },\n )\n if (!response.ok) {\n return false\n }\n await this.options.onRefreshSuccess?.()\n return true\n } catch {\n return false\n } finally {\n this.refreshPromise = null\n }\n })()\n\n return this.refreshPromise\n }\n\n private resolveTokenForUrl(url: URL): string | null {\n if (!this.isSameBackendUrl(url)) {\n return null\n }\n return this.resolveRestToken()\n }\n\n private resolveRestToken(): string | null {\n return this.resolveToken()\n }\n\n private resolveSocketToken(): string | null {\n if (this.runtimeToken) return this.runtimeToken\n return resolveTokenOption(this.options.socketToken ?? this.options.token)\n }\n\n private resolveToken(): string | null {\n if (this.runtimeToken) return this.runtimeToken\n return resolveTokenOption(this.options.token)\n }\n\n private formDataWithUploadProgress(\n method: HttpMethod,\n path: string,\n form: FormData,\n options: { expectOk?: boolean; onUploadProgress?: (progress: UploadProgress) => void },\n isRetry = false,\n ): Promise<Response> {\n const url = this.buildUrl(path)\n const headers = this.buildHeaders(url)\n\n return new Promise((resolve, reject) => {\n const xhr = new XMLHttpRequest()\n xhr.open(method, url.toString(), true)\n xhr.withCredentials = true\n\n headers.forEach((value, key) => {\n xhr.setRequestHeader(key, value)\n })\n\n xhr.upload.onprogress = (event) => {\n options.onUploadProgress?.({\n loaded: event.loaded,\n total: event.lengthComputable ? event.total : undefined,\n percent: event.lengthComputable && event.total > 0 ? event.loaded / event.total : undefined,\n })\n }\n\n xhr.onerror = () => reject(new TypeError(\"Network request failed\"))\n xhr.ontimeout = () => reject(new TypeError(\"Network request timed out\"))\n xhr.onabort = () => reject(new DOMException(\"Request aborted\", \"AbortError\"))\n xhr.onload = async () => {\n if (xhr.status === 401 && !isRetry && this.shouldRefreshFor401(url)) {\n const refreshed = await this.tryRefresh()\n if (refreshed) {\n resolve(this.formDataWithUploadProgress(method, path, form, options, true))\n return\n }\n }\n\n const response = new Response(xhr.responseText, {\n status: xhr.status,\n statusText: xhr.statusText,\n headers: parseXhrHeaders(xhr.getAllResponseHeaders()),\n })\n if (options.expectOk !== false && !response.ok) {\n const detail = await extractErrorDetail(response.clone())\n reject(new BladeApiError(response, detail))\n return\n }\n options.onUploadProgress?.({ loaded: 1, total: 1, percent: 1 })\n resolve(response)\n }\n\n xhr.send(form)\n })\n }\n}\n\nfunction resolveTokenOption(\n tokenOption: string | (() => string | null | undefined) | undefined,\n): string | null {\n const token = typeof tokenOption === \"function\" ? tokenOption() : tokenOption\n return token ? token : null\n}\n\nexport interface UploadProgress {\n loaded: number\n total?: number\n percent?: number\n}\n\nfunction normalizeBaseUrl(baseUrl: string): string {\n const normalized = baseUrl.trim().replace(/\\/+$/, \"\")\n if (normalized || typeof window === \"undefined\") {\n return normalized\n }\n return window.location.origin\n}\n\nfunction isFormData(value: BodyInit): boolean {\n return typeof FormData !== \"undefined\" && value instanceof FormData\n}\n\nfunction readJsonResponse<T>(response: Response): Promise<T> {\n if (response.status === 204 || response.headers.get(\"content-length\") === \"0\") {\n return Promise.resolve(undefined as T)\n }\n return response.json() as Promise<T>\n}\n\nfunction parseXhrHeaders(rawHeaders: string): Headers {\n const headers = new Headers()\n for (const line of rawHeaders.trim().split(/[\\r\\n]+/)) {\n const separatorIndex = line.indexOf(\":\")\n if (separatorIndex <= 0) continue\n headers.append(line.slice(0, separatorIndex).trim(), line.slice(separatorIndex + 1).trim())\n }\n return headers\n}\n","/**\n * 页面协作协议(对应后端 `_meta.bridge` 通道,见 docs/specs/260417-embed-bridge)。\n *\n * ## action 从哪里来\n *\n * 智能体 → 宿主方向的每一条指令,都源自**技能作者写的工具代码**:工具返回值\n * JSON 里带 `_meta.bridge: { action, payload }`,后端在持久化前把它剥离成独立\n * 事件送达前端(LLM 的对话历史里读不到它)。因此:\n *\n * - action 字符串(如 \"map.highlight\")是**技能作者与宿主页面开发者之间的业务\n * 契约**,LLM 不参与协议、SDK 不做枚举校验;\n * - 宿主页面用 `session.onCommand(\"map.highlight\", fn)` 消费;\n * - 未注册 handler 的 action 会进入有限缓冲等待注册,超限后丢弃并 console 告警。\n *\n * 宿主 → 智能体方向只有三个白名单动作:attach(附件入输入框)/ insertText\n * (追加输入文本)/ send(直接发消息),对应协议层的 addContext / appendInput /\n * sendMessage。\n */\n\nexport interface CommandEnvelope {\n __bladeBridge: true\n direction: \"agent-to-host\"\n action: string\n payload: unknown\n meta: {\n sessionId: string\n toolCallId?: string\n timestamp: number\n }\n}\n\nexport type InboundAction = \"addContext\" | \"appendInput\" | \"sendMessage\"\n\nexport interface InboundEnvelope {\n __bladeBridge: true\n direction: \"host-to-agent\"\n action: InboundAction\n payload: unknown\n}\n\nexport function isCommandEnvelope(value: unknown): value is CommandEnvelope {\n if (typeof value !== \"object\" || value === null) return false\n const record = value as Record<string, unknown>\n return (\n record.__bladeBridge === true &&\n record.direction === \"agent-to-host\" &&\n typeof record.action === \"string\"\n )\n}\n\nexport function isInboundEnvelope(value: unknown): value is InboundEnvelope {\n if (typeof value !== \"object\" || value === null) return false\n const record = value as Record<string, unknown>\n return (\n record.__bladeBridge === true &&\n record.direction === \"host-to-agent\" &&\n (record.action === \"addContext\" || record.action === \"appendInput\" || record.action === \"sendMessage\")\n )\n}\n","import { CommandRegistry, type CommandHandler } from \"./registry\"\nimport { isCommandEnvelope, type InboundAction } from \"./protocol\"\n\n/**\n * iframe 嵌入形态的宿主端协作对象:当你把 Blade 的聊天页面用 iframe 嵌进\n * 自己的系统时,用它与 iframe 里的智能体互通——API 与同页嵌入的\n * AgentSession 完全一致(onCommand / attach / insertText / send)。\n *\n * action 的来源与同页形态相同:技能作者在工具返回值 JSON 的 `_meta.bridge`\n * 字段里写 `{ action, payload }`,Blade 页面检测到自己处于 iframe 中时会把\n * 它 postMessage 给宿主页面(见 docs/specs/260417-embed-bridge)。\n */\nexport interface EmbeddedChatOptions {\n /** 嵌入 Blade 页面的 iframe 元素。不传则监听来自任意子窗口的消息。 */\n iframe?: HTMLIFrameElement\n /**\n * 允许接收消息的来源(Blade 页面的 origin,如 \"https://blade.example.com\")。\n * 必填:不校验来源会让任意第三方页面伪造智能体指令。\n */\n allowedOrigins: string[]\n}\n\nexport interface EmbeddedChat {\n /** 监听智能体下发的指令(注册前到达的会缓冲补投)。返回取消函数。 */\n onCommand(action: string, handler: CommandHandler): () => void\n /** 把业务数据作为附件放进 iframe 里的聊天输入框。 */\n attach(label: string, data: unknown): void\n /** 往 iframe 里的聊天输入框追加文字。 */\n insertText(text: string): void\n /** 直接代用户发送一条消息。 */\n send(text: string): void\n /** 停止监听并释放资源。 */\n dispose(): void\n}\n\nexport function connectEmbedded(options: EmbeddedChatOptions): EmbeddedChat {\n if (typeof window === \"undefined\") {\n throw new Error(\"connectEmbedded() 只能在浏览器中使用。\")\n }\n if (!options.allowedOrigins?.length) {\n throw new Error(\n \"connectEmbedded() 需要 allowedOrigins(Blade 页面的 origin),否则无法安全接收消息。\",\n )\n }\n const registry = new CommandRegistry()\n const allowed = new Set(options.allowedOrigins)\n\n const onMessage = (event: MessageEvent) => {\n if (!allowed.has(event.origin)) return\n if (options.iframe && event.source !== options.iframe.contentWindow) return\n if (!isCommandEnvelope(event.data)) return\n registry.dispatch(event.data.action, event.data.payload, {\n toolCallId: event.data.meta?.toolCallId,\n })\n }\n window.addEventListener(\"message\", onMessage)\n\n const post = (action: InboundAction, payload: unknown) => {\n const target = options.iframe?.contentWindow\n if (!target) {\n console.warn(\"[agent-client] connectEmbedded 未绑定 iframe,无法向智能体发送消息。\")\n return\n }\n // 发往 iframe 的 targetOrigin 用配置的第一个 origin,避免 \"*\"\n target.postMessage(\n { __bladeBridge: true, direction: \"host-to-agent\", action, payload },\n options.allowedOrigins[0],\n )\n }\n\n return {\n onCommand: (action, handler) => registry.onCommand(action, handler),\n attach: (label, data) => {\n const content = typeof data === \"string\" ? data : JSON.stringify(data, null, 2)\n post(\"addContext\", { label, content })\n },\n insertText: (text) => post(\"appendInput\", { text }),\n send: (text) => post(\"sendMessage\", { text }),\n dispose: () => {\n window.removeEventListener(\"message\", onMessage)\n registry.clear()\n },\n }\n}\n","import { type } from \"arktype\"\nimport type { Solution } from \"./solution\"\n\nexport const SessionStatus = type(\n \"'created' | 'running' | 'completed' | 'failed' | 'interrupted' | 'waiting_for_input'\",\n)\nexport type SessionStatus = typeof SessionStatus.infer\n\nexport type TemplateId =\n | \"default\"\n | \"skill_editor\"\n // ship-attack v2:用户从 ship-attack 页面点\"新建 session\"创建的会话。\n // 后端 _maybe_bind_first_skill 只对此模板触发首次绑定。\n | \"ship_attack\"\n\nexport type SkillEditorTemplateId = \"skill_editor\"\n\nexport type ModeId = \"planning\" | \"executing\"\n\nexport interface ReplayState {\n source_session_id?: string\n status?: \"replay\" | \"autonomous\"\n speed?: 1 | 2 | 5\n next_source_entry_id?: string | null\n ended_at?: string | null\n autonomous_reason?: string | null\n}\n\nexport interface SessionPortMapping {\n container_port: number\n host_port: number\n}\n\n/**\n * 列表搜索时单条会话的命中信息。\n * - field='title':关键词出现在 intent 里,snippet 为 null(标题本身就在 UI 上)\n * - field='content':关键词出现在历史消息里,snippet 含截窗预览与角色\n */\nexport interface SessionSearchMatch {\n field: \"title\" | \"content\"\n snippet: { role: string; text: string } | null\n}\n\nexport const SessionInfo = type({\n id: \"string\",\n intent: \"string\",\n status: SessionStatus,\n created_at: \"string\",\n updated_at: \"string\",\n \"shared?\": \"boolean\",\n \"memory_enabled?\": \"boolean\",\n \"is_persistent?\": \"boolean\",\n \"is_headless?\": \"boolean\",\n \"viewer_role?\": \"'owner' | 'viewer'\",\n \"template_id?\": \"string | null\",\n \"model?\": \"string | null\",\n \"enable_thinking?\": \"boolean | null\",\n \"solution_id?\": \"string | null\",\n \"biz_role_id?\": \"string | null\",\n \"solution?\": \"unknown\",\n \"plan_summary?\": \"string | null\",\n \"primary_skill_id?\": \"string | null\",\n // ship-attack v2:后端 engine.set_bound_skill 写入的\"绑定 skill id\"。\n // 未绑定 / 非 ship-attack session 为 null。\n \"bound_skill_id?\": \"string | null\",\n \"replay_state?\": \"unknown\",\n \"is_pinned?\": \"boolean\",\n \"pinned_at?\": \"string | null\",\n \"is_example?\": \"boolean\",\n \"ports?\": \"unknown\",\n \"disable_tools?\": \"string[]\",\n \"runtime_type?\": \"string | null\",\n \"daemon_id?\": \"string | null\",\n \"match?\": \"unknown\",\n})\nexport type SessionInfo = Omit<\n typeof SessionInfo.infer,\n \"template_id\" | \"solution\" | \"ports\" | \"match\"\n> & {\n shared?: boolean\n memory_enabled?: boolean\n is_persistent?: boolean\n is_headless?: boolean\n viewer_role?: \"owner\" | \"viewer\"\n template_id?: TemplateId | null\n model?: string | null\n enable_thinking?: boolean | null\n solution_id?: string | null\n biz_role_id?: string | null\n solution?: Solution | null\n primary_skill_id?: string | null\n bound_skill_id?: string | null\n replay_state?: ReplayState | null\n is_pinned?: boolean\n pinned_at?: string | null\n is_example?: boolean\n ports?: SessionPortMapping[]\n disable_tools?: string[]\n runtime_type?: \"sandbox\" | \"daemon\" | string | null\n daemon_id?: string | null\n /** 仅在带 q 搜索的列表响应中出现;普通列表里此字段缺省。 */\n match?: SessionSearchMatch | null\n}\n\n/**\n * 主 skill 配置快照(v2)。创建 session 时从 SKILL.md frontmatter 抽出并\n * 固化到 session_root/.blade/primary-skill.json;ship-attack 页面骨架的唯\n * 一数据源。\n */\nexport interface PrimarySkillStepSpec {\n n: number\n label: string\n}\n\nexport interface PrimarySkillStageSpec {\n id: string\n name: string\n steps: PrimarySkillStepSpec[]\n}\n\nexport interface PrimarySkillParallelMode {\n id: string\n name: string\n prompt_hint: string\n}\n\nexport interface PrimarySkillSnapshot {\n version: number\n skill_id: string\n title: string\n description: string\n stages: PrimarySkillStageSpec[]\n parallel_modes: PrimarySkillParallelMode[]\n captured_at: string\n}\n\n/**\n * 单 session detail(GET /api/sessions/:id)。列表接口返回 SessionInfo,\n * detail 在此基础上附加 primary_skill_snapshot。\n */\nexport interface SessionDetail extends SessionInfo {\n primary_skill_snapshot?: PrimarySkillSnapshot | null\n preview_url?: string | null\n /**\n * 会话级环境变量(owner-only)。后端仅在 GET detail 和 PUT /env 响应中返回,\n * 列表/搜索响应不带此字段。调用 setSessionEnv 后可类型安全地读回。\n */\n env?: Record<string, string>\n}\n","export enum LayoutType {\n Default = \"default\",\n SkillEditor = \"skill-editor\",\n BladeCoa = \"blade-coa\",\n SolutionEditor = \"solution-editor\",\n SolutionEditor2 = \"solution-editor2\",\n ChatPreview = \"chat-preview\",\n ChatOnly = \"chat-only\",\n SolutionApp = \"solution-app\",\n Custom = \"custom\",\n}\n\nexport interface Solution {\n id: string\n name: string\n version: string\n description?: string | null\n source?: \"builtin\" | \"personal\" | string | null\n layout_type: LayoutType | string\n initial_mode?: \"planning\" | \"executing\" | string | null\n initial_message?: string | null\n preview?: { url: string; title?: string | null } | null\n layout?: {\n available?: boolean\n source_dir?: string\n entry?: string\n export?: string\n } | null\n roles?: BizRole[] | null\n data?: Record<string, unknown> | null\n ui_config?: SolutionAppUiConfig | null\n}\n\nexport interface SolutionAppUiConfig {\n branding: {\n name: string\n subtitle?: string\n icon_text: string\n icon_gradient?: string\n }\n list: {\n title: string\n create_button: string\n card?: {\n subtitle?: string\n stats?: Array<{\n label: string\n value: string\n color?: string\n }>\n }\n }\n create: {\n title: string\n description?: string\n submit_button: string\n sections: Array<{\n id: string\n title: string\n description?: string\n fields: Array<SolutionAppField>\n }>\n }\n}\n\nexport type SolutionAppField =\n | {\n id: string\n kind: \"textarea\"\n label: string\n placeholder?: string\n }\n | {\n id: string\n kind: \"file-upload\"\n accept?: string[]\n categories?: Array<{\n label: string\n description: string\n color: string\n }>\n }\n\nexport interface SolutionAppState {\n pipeline: Array<{\n id: string\n label: string\n status: \"done\" | \"active\" | \"pending\" | \"error\"\n }>\n meta: Record<\n string,\n {\n label: string\n value: string\n color?: string\n }\n >\n}\n\nexport interface BizRole {\n id: string\n name: string\n description?: string | null\n preview?: { url: string; title?: string | null } | null\n}\n","import { type } from \"arktype\"\n\nexport const TaskStatus = type(\"'pending' | 'in_progress' | 'done' | 'failed' | 'skipped'\")\nexport type TaskStatus = typeof TaskStatus.infer\n\nexport const Task = type({\n id: \"string\",\n goal: \"string\",\n skills: \"string[]\",\n depends_on: \"string[]\",\n status: TaskStatus,\n result_summary: \"string\",\n number: \"string\",\n})\nexport type Task = typeof Task.infer\n"],"mappings":"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","names":["toolCallId","isRecord","type","attachments","contexts","isRecord","buildMessageContent","toolCall","isRecord","handle","LayoutType","type"]}
1
+ {"version":3,"sources":["../src/auth-login.ts","../src/rest.ts","../src/resources/auth.ts","../src/resources/headless.ts","../src/resources/models.ts","../src/session/definition.ts","../src/shared/projection/helpers.ts","../src/schemas/message.ts","../src/shared/projection/state.ts","../src/shared/projection/builder.ts","../src/shared/projection/history.ts","../src/resources/sessions.ts","../src/commands/registry.ts","../src/session/events.ts","../src/schemas/message-utils.ts","../src/session/state.ts","../src/session/agent-session.ts","../src/session/hub.ts","../src/socket.ts","../src/auth.ts","../src/version.ts","../src/blade-client.ts","../src/commands/protocol.ts","../src/commands/embedded.ts","../src/schemas/session.ts","../src/schemas/solution.ts","../src/schemas/task.ts"],"sourcesContent":["import type { BladeClient } from \"./blade-client\"\n\n/**\n * 弹窗授权登录,与 Chrome 扩展共用同一套后端授权内核(见 server/routes/sdk_auth.py):\n *\n * 1. 弹窗打开 `GET /api/auth/sdk/authorize?client_origin=<本页 origin>&state=<随机值>`\n * 2. 用户点击「许可授权」→ 回调页把 `{ type: \"blade-agent:sdk-auth\", state, code }`\n * postMessage 定向发回本页(code 一次性、5 分钟有效)\n * 3. SDK 用 `POST /api/auth/sdk/token`(code + state + client_origin)换取 PAT,\n * 存储并热挂载(REST 与 Socket.IO 同时生效)\n */\n\nexport interface LoginOptions {\n /** 弹窗尺寸,默认 480x640。 */\n width?: number\n height?: number\n /** 超时毫秒数,默认 5 分钟(与后端授权码有效期一致)。 */\n timeoutMs?: number\n}\n\nexport interface LoginResult {\n token: string\n user?: { id?: string; username?: string; display_name?: string }\n}\n\n/** 回调页 postMessage 的消息契约(对齐后端 _completion_page)。 */\ninterface AuthCallbackMessage {\n type: \"blade-agent:sdk-auth\"\n version: number\n status: \"success\" | \"denied\" | \"error\"\n state: string\n code?: string\n error?: string\n}\n\nfunction isAuthCallbackMessage(value: unknown): value is AuthCallbackMessage {\n return (\n typeof value === \"object\" &&\n value !== null &&\n (value as Record<string, unknown>).type === \"blade-agent:sdk-auth\"\n )\n}\n\nfunction randomState(): string {\n const bytes = new Uint8Array(24)\n crypto.getRandomValues(bytes)\n return Array.from(bytes, (b) => b.toString(16).padStart(2, \"0\")).join(\"\")\n}\n\nexport type TokenStorageMode = \"local\" | \"memory\"\n\nconst storageKeyFor = (baseUrl: string) => `blade-sdk-token:${baseUrl}`\n\nexport function readStoredToken(baseUrl: string): string | null {\n if (typeof localStorage === \"undefined\") return null\n try {\n return localStorage.getItem(storageKeyFor(baseUrl))\n } catch {\n return null\n }\n}\n\nexport function writeStoredToken(baseUrl: string, token: string | null, mode: TokenStorageMode): void {\n if (mode !== \"local\" || typeof localStorage === \"undefined\") return\n try {\n if (token) {\n localStorage.setItem(storageKeyFor(baseUrl), token)\n } else {\n localStorage.removeItem(storageKeyFor(baseUrl))\n }\n } catch {\n // 隐私模式等场景写入失败时静默降级为内存态\n }\n}\n\nexport async function loginWithPopup(\n client: BladeClient,\n options: LoginOptions = {},\n): Promise<LoginResult> {\n if (typeof window === \"undefined\") {\n throw new Error(\"client.auth.login() 只能在浏览器中调用;Node.js 场景请直接传入 token。\")\n }\n // file:// 打开的本地 HTML(智能体生成的交付物被双击打开)没有可声明的\n // origin,按 opaque(\"null\")走:授权页会向用户展示「本地文件页面」,\n // 回传的一次性 code 由 \"*\" 投递给本窗口,state 校验不变。\n const rawOrigin = window.location.origin\n const clientOrigin = /^https?:\\/\\//.test(rawOrigin) ? rawOrigin : \"null\"\n\n const width = options.width ?? 480\n const height = options.height ?? 640\n const left = Math.max(0, (window.screen.width - width) / 2)\n const top = Math.max(0, (window.screen.height - height) / 2)\n const state = randomState()\n const authorizeUrl = new URL(\n \"/api/auth/sdk/authorize\",\n client.options.baseUrl || window.location.origin,\n )\n authorizeUrl.searchParams.set(\"client_origin\", clientOrigin)\n authorizeUrl.searchParams.set(\"state\", state)\n\n const popup = window.open(\n authorizeUrl.toString(),\n \"blade-sdk-login\",\n `popup=yes,width=${width},height=${height},left=${left},top=${top}`,\n )\n if (!popup) {\n throw new Error(\"登录弹窗被浏览器拦截了。请允许本站打开弹窗后重试。\")\n }\n\n const expectedOrigin = new URL(client.options.baseUrl || window.location.origin).origin\n\n return new Promise<LoginResult>((resolve, reject) => {\n const timeoutMs = options.timeoutMs ?? 5 * 60 * 1000\n let settled = false\n\n const cleanup = () => {\n window.removeEventListener(\"message\", onMessage)\n globalThis.clearInterval(closeWatcher)\n globalThis.clearTimeout(timeoutHandle)\n }\n const settle = (fn: () => void) => {\n if (settled) return\n settled = true\n cleanup()\n fn()\n }\n\n const onMessage = (event: MessageEvent) => {\n // 回调页部署在后端域名下,只信任来自后端 origin、且 state 匹配的消息\n if (event.origin !== expectedOrigin) return\n if (!isAuthCallbackMessage(event.data)) return\n if (event.data.state !== state) return\n const message = event.data\n try {\n popup.close()\n } catch {\n // 跨域限制下 close 可能失败,忽略\n }\n if (message.status === \"denied\") {\n settle(() => reject(new Error(\"你取消了授权,未完成登录。\")))\n return\n }\n if (message.status !== \"success\" || !message.code) {\n settle(() => reject(new Error(message.error || \"登录失败,未取得授权码。\")))\n return\n }\n // code 一次性、5 分钟有效;连同 state 与 client_origin 一起换取 PAT\n client\n .json<{\n access_token: string\n user?: LoginResult[\"user\"]\n }>(\"POST\", \"/api/auth/sdk/token\", {\n code: message.code,\n state,\n client_origin: clientOrigin,\n })\n .then((response) => {\n settle(() => resolve({ token: response.access_token, user: response.user }))\n })\n .catch((error) => {\n settle(() =>\n reject(error instanceof Error ? error : new Error(\"授权码换取令牌失败,请重试。\")),\n )\n })\n }\n\n const closeWatcher = globalThis.setInterval(() => {\n if (popup.closed && !settled) {\n // 回调消息可能仍在路上,稍等一拍再判定为用户关窗\n globalThis.setTimeout(() => {\n settle(() => reject(new Error(\"登录窗口已关闭,未完成授权。\")))\n }, 400)\n }\n }, 500)\n\n const timeoutHandle = globalThis.setTimeout(() => {\n settle(() => reject(new Error(\"登录超时,请重试。\")))\n }, timeoutMs)\n\n window.addEventListener(\"message\", onMessage)\n })\n}\n","const DOCS_URL = \"https://blade-hq.github.io/public-skills/\"\n\nexport class BladeApiError extends Error {\n readonly response: Response\n readonly status: number\n readonly statusText: string\n\n constructor(response: Response, message?: string) {\n super(message ?? `请求失败(${response.status} ${response.statusText})`)\n this.name = \"BladeApiError\"\n this.response = response\n this.status = response.status\n this.statusText = response.statusText\n }\n}\n\n/**\n * 从 FastAPI 风格的错误响应中提取 detail 字段,作为用户可读的中文错误文案。\n * 失败时返回 undefined,调用方会回退到默认提示。\n */\nexport async function extractErrorDetail(response: Response): Promise<string | undefined> {\n try {\n const cloned = response.clone()\n const contentType = cloned.headers.get(\"content-type\") ?? \"\"\n if (contentType.includes(\"application/json\")) {\n const data = (await cloned.json()) as { detail?: unknown }\n const detail = data?.detail\n if (typeof detail === \"string\" && detail.trim()) return detail\n if (Array.isArray(detail) && detail.length > 0) {\n const first = detail[0] as { msg?: unknown }\n if (first && typeof first.msg === \"string\") return first.msg\n }\n } else {\n const text = (await cloned.text()).trim()\n if (text) return text\n }\n } catch {\n // 读取失败时忽略,使用默认提示\n }\n return undefined\n}\n\n/** 401/403 补充\"怎么办\"的指引,避免初级开发者对着裸状态码发呆。 */\nexport function decorateAuthError(error: unknown): unknown {\n if (!(error instanceof BladeApiError)) return error\n if (error.status === 401) {\n error.message =\n `${error.message}(未登录或凭证已失效。浏览器场景调用 client.auth.login() 弹窗登录,` +\n `自动化场景在 new BladeClient({ token }) 传入 PAT。接入指南:${DOCS_URL})`\n } else if (error.status === 403) {\n error.message = `${error.message}(当前账号无权访问该资源。接入指南:${DOCS_URL})`\n }\n return error\n}\n\nexport type HttpMethod = \"DELETE\" | \"GET\" | \"PATCH\" | \"POST\" | \"PUT\" | (string & {})\n\nexport interface BladeFetchInit {\n body?: BodyInit | null\n credentials?: RequestCredentials\n expectOk?: boolean\n headers?: HeadersInit\n signal?: AbortSignal | null\n}\n","import type { BladeClient } from \"../blade-client\"\nimport type { LoginOptions, LoginResult } from \"../auth-login\"\n\nexport interface UserInfo {\n id: string\n username: string\n display_name?: string | null\n avatar_url: string | null\n token: string\n auth_type: \"casdoor\"\n is_admin?: boolean\n}\n\nexport interface ProvidersResponse {\n providers: Array<{\n name: string\n authorize_url: string\n }>\n password_enabled: boolean\n}\n\nexport class AuthResource {\n constructor(private client: BladeClient) {}\n\n /**\n * 弹窗授权登录(浏览器专用):弹出后端授权页,用户点击\"许可授权\"后\n * 自动取得 PAT 并热挂载到当前 client。等价于 client.login()。\n */\n login(options?: LoginOptions): Promise<LoginResult> {\n return this.client.login(options)\n }\n\n /** 清除 login() 存储的令牌。 */\n logoutToken(): void {\n this.client.logoutToken()\n }\n\n getProviders(): Promise<ProvidersResponse> {\n return this.client.json(\"GET\", \"/api/auth/providers\")\n }\n\n getMe(): Promise<UserInfo> {\n return this.client.json(\"GET\", \"/api/auth/me\")\n }\n\n logout(): Promise<{ logout_url: string }> {\n return this.client.json(\"POST\", \"/api/auth/logout\")\n }\n}\n","import type { BladeClient } from \"../blade-client\"\nimport type { ChatEndPayload, ChatSendPayload, ChatStartPayload, SystemErrorPayload } from \"../types/socket-events\"\n\nexport type JsonSchemaObject = Record<string, unknown>\n\nexport interface HeadlessRunOptions {\n schema?: JsonSchemaObject | null\n model?: string | null\n timeoutMs?: number\n}\n\nexport interface HeadlessRunInSessionResult<T = unknown> {\n session_id: string\n chat_run_id: string | null\n result: T | string\n}\n\nexport class HeadlessError extends Error {\n constructor(\n message: string,\n readonly detail?: unknown,\n ) {\n super(message)\n this.name = \"HeadlessError\"\n }\n}\n\nconst SYSTEM_ERROR_CHAT_END_GRACE_MS = 1_000\n\nexport class HeadlessResource {\n constructor(private client: BladeClient) {}\n\n async run<T = unknown>(prompt: string, options: HeadlessRunOptions & { schema: JsonSchemaObject }): Promise<T>\n async run(prompt: string, options?: HeadlessRunOptions): Promise<string>\n async run<T = unknown>(prompt: string, options: HeadlessRunOptions = {}): Promise<T | string> {\n const { session_id } = await this.client.sessions.createSessionWithRequest({\n intent: prompt,\n model: options.model ?? null,\n })\n return this.runTracked<T>(session_id, prompt, options, false) as Promise<T | string>\n }\n\n async runInSession<T = unknown>(\n sessionId: string,\n prompt: string,\n options: HeadlessRunOptions & { schema: JsonSchemaObject },\n ): Promise<T>\n async runInSession(sessionId: string, prompt: string, options?: HeadlessRunOptions): Promise<string>\n async runInSession<T = unknown>(\n sessionId: string,\n prompt: string,\n options: HeadlessRunOptions = {},\n ): Promise<T | string> {\n return this.runTracked<T>(sessionId, prompt, options, false) as Promise<T | string>\n }\n\n async runWithSession<T = unknown>(\n prompt: string,\n options: HeadlessRunOptions & { schema: JsonSchemaObject },\n ): Promise<HeadlessRunInSessionResult<T>>\n async runWithSession(prompt: string, options?: HeadlessRunOptions): Promise<HeadlessRunInSessionResult<string>>\n async runWithSession<T = unknown>(\n prompt: string,\n options: HeadlessRunOptions = {},\n ): Promise<HeadlessRunInSessionResult<T>> {\n const { session_id } = await this.client.sessions.createSessionWithRequest({\n intent: prompt,\n model: options.model ?? null,\n })\n return this.runTracked<T>(session_id, prompt, options, true) as Promise<HeadlessRunInSessionResult<T>>\n }\n\n private async runTracked<T = unknown>(\n sessionId: string,\n prompt: string,\n options: HeadlessRunOptions,\n returnEnvelope: boolean,\n ): Promise<T | string | HeadlessRunInSessionResult<T>> {\n const timeoutMs = options.timeoutMs ?? 300_000\n const session_id = sessionId\n const socket = this.client.socket()\n await ensureSocketConnected(socket, timeoutMs, { session_id })\n\n return new Promise<T | string | HeadlessRunInSessionResult<T>>((resolve, reject) => {\n let settled = false\n let stopSent = false\n let started = false\n let chatRunId: string | null = null\n let systemErrorTimeout: ReturnType<typeof setTimeout> | null = null\n const timeout = setTimeout(() => {\n fail(new HeadlessError(`headless run timed out after ${timeoutMs}ms`, { session_id, chat_run_id: chatRunId }))\n }, timeoutMs)\n\n const cleanup = (sendStop: boolean) => {\n clearTimeout(timeout)\n if (systemErrorTimeout) {\n clearTimeout(systemErrorTimeout)\n systemErrorTimeout = null\n }\n socket.off(\"chat:start\", onChatStart)\n socket.off(\"chat:end\", onChatEnd)\n socket.off(\"system:error\", onSystemError)\n if (sendStop && !stopSent) {\n stopSent = true\n socket.emit(\"chat:stop\", { session_id }, () => undefined)\n }\n socket.emit(\"session:unsubscribe\", { session_id })\n }\n\n const finish = (value: T | string) => {\n if (settled) return\n settled = true\n cleanup(false)\n if (returnEnvelope) {\n resolve({ session_id, chat_run_id: chatRunId, result: value })\n return\n }\n resolve(value)\n }\n const fail = (error: unknown) => {\n if (settled) return\n settled = true\n cleanup(true)\n reject(error)\n }\n const failWithoutStop = (error: unknown) => {\n if (settled) return\n settled = true\n cleanup(false)\n reject(error)\n }\n const rejectAfterChatEnd = (error: unknown) => {\n if (settled) return\n settled = true\n cleanup(false)\n reject(error)\n }\n\n function onChatStart(payload: ChatStartPayload) {\n if (payload.session_id && payload.session_id !== session_id) return\n started = true\n }\n\n function onSystemError(payload: SystemErrorPayload) {\n if (payload.session_id !== session_id) return\n if (!started) {\n failWithoutStop(new HeadlessError(payload.message || \"headless run failed\", {\n session_id,\n chat_run_id: chatRunId,\n event: payload,\n }))\n return\n }\n if (systemErrorTimeout) {\n clearTimeout(systemErrorTimeout)\n }\n systemErrorTimeout = setTimeout(() => {\n systemErrorTimeout = null\n fail(new HeadlessError(payload.message || \"headless run failed\", {\n session_id,\n chat_run_id: chatRunId,\n event: payload,\n }))\n }, SYSTEM_ERROR_CHAT_END_GRACE_MS)\n }\n\n function onChatEnd(payload: ChatEndPayload) {\n if (payload.session_id && payload.session_id !== session_id) return\n chatRunId = typeof payload.chat_run_id === \"string\" ? payload.chat_run_id : chatRunId\n const result = payload.result\n if (payload.status === \"failed\") {\n rejectAfterChatEnd(new HeadlessError(errorMessageFromResult(result) ?? \"headless run failed\", {\n session_id,\n chat_run_id: chatRunId,\n event: payload,\n }))\n return\n }\n try {\n finish(normalizeResult<T>(result, Boolean(options.schema)))\n } catch (error) {\n rejectAfterChatEnd(error)\n }\n }\n\n socket.on(\"chat:start\", onChatStart)\n socket.on(\"chat:end\", onChatEnd)\n socket.on(\"system:error\", onSystemError)\n socket.emit(\"session:subscribe\", { session_id, event_format: \"raw\" })\n socket.emit(\"chat:send\", {\n session_id,\n message: prompt as unknown as ChatSendPayload[\"message\"],\n headless: true,\n output_schema: options.schema ?? null,\n model: options.model ?? null,\n })\n })\n }\n}\n\nfunction normalizeResult<T>(result: unknown, hasSchema: boolean): T | string {\n if (!isRecord(result)) {\n throw new HeadlessError(\"headless run finished without a result\", result)\n }\n const errMsg = typeof result.err_msg === \"string\" ? result.err_msg : \"\"\n if (errMsg) {\n throw new HeadlessError(errMsg, result)\n }\n if (!hasSchema) {\n const text = result.result\n return typeof text === \"string\" ? text : String(text ?? \"\")\n }\n const { err_msg: _errMsg, ...businessResult } = result\n return businessResult as T\n}\n\nfunction errorMessageFromResult(result: unknown): string | null {\n if (isRecord(result) && typeof result.err_msg === \"string\" && result.err_msg) {\n return result.err_msg\n }\n return null\n}\n\nfunction isRecord(value: unknown): value is Record<string, unknown> {\n return typeof value === \"object\" && value !== null && !Array.isArray(value)\n}\n\nfunction ensureSocketConnected(\n socket: ReturnType<BladeClient[\"socket\"]>,\n timeoutMs: number,\n detail: Record<string, unknown>,\n): Promise<void> {\n if (socket.connected) {\n return Promise.resolve()\n }\n return new Promise((resolve, reject) => {\n let settled = false\n const timeout = setTimeout(() => {\n finish(() => reject(new HeadlessError(`socket connection timed out after ${timeoutMs}ms`, detail)))\n }, timeoutMs)\n const onConnect = () => finish(resolve)\n const onConnectError = (error: unknown) => {\n finish(() => reject(new HeadlessError(\"socket connection failed\", { ...detail, event: error })))\n }\n const finish = (callback: () => void) => {\n if (settled) return\n settled = true\n clearTimeout(timeout)\n socket.off(\"connect\", onConnect)\n socket.off(\"connect_error\", onConnectError)\n callback()\n }\n socket.on(\"connect\", onConnect)\n socket.on(\"connect_error\", onConnectError)\n socket.connect()\n })\n}\n","import type { BladeClient } from \"../blade-client\"\n\nexport interface ModelOption {\n id: string\n label: string\n}\n\nexport interface ModelCatalog {\n default: string\n models: ModelOption[]\n}\n\n/** Server 可供当前用户选择的模型目录。 */\nexport class ModelsResource {\n constructor(private client: BladeClient) {}\n\n list(): Promise<ModelCatalog> {\n return this.client.json(\"GET\", \"/api/config/models\")\n }\n}\n\n","export type TextFile = {\n path: string\n content: string\n}\n\nexport type SolutionDefinition =\n | { id: string; role?: string }\n /** 自定义 Solution:文本文件路径均相对于 Solution 根目录。 */\n | { files: TextFile[]; role?: string }\n\nexport interface SkillDefinition {\n /** 会话内安装名,格式为 `组织/名称`。 */\n name: string\n /** 必须包含根目录的 SKILL.md。 */\n files: TextFile[]\n}\n\nexport interface SessionConfig {\n /** Server 模型目录中的 model ID。 */\n model?: string\n enableThinking?: boolean\n memoryEnabled?: boolean\n compactionRatio?: number\n env?: Record<string, string>\n disableTools?: string[]\n}\n\n/**\n * 声明一个待创建的会话。传给 `client.sessions.create(...)` 后,SDK 会先准备\n * Solution,再创建会话并安装 Skill;Promise resolve 时会话已经可以使用。\n */\nexport interface SessionDefinition {\n intent?: string\n solution?: SolutionDefinition\n skills?: SkillDefinition[]\n config?: SessionConfig\n}\n\nexport type SessionSetupStage = \"solution\" | \"session\" | \"skill\" | \"connection\"\n\n/** 声明式会话准备失败;stage 和 sessionId 可直接用于界面提示或日志。 */\nexport class SessionSetupError extends Error {\n readonly name = \"SessionSetupError\"\n readonly cause?: unknown\n\n constructor(\n message: string,\n readonly stage: SessionSetupStage,\n readonly sessionId?: string,\n options?: { cause?: unknown },\n ) {\n super(message)\n this.cause = options?.cause\n }\n}\n","import type {\n ContentBlock,\n PendingQuestionRef,\n ToolCallProjection,\n TurnProjection,\n} from \"../../schemas/projection\"\nimport type { TurnState } from \"./state\"\n\n// --- Tool call upsert ---\n\nexport function upsertToolCall(\n state: TurnState,\n toolCallId: string,\n toolName: string,\n displayName: string,\n args: string,\n): void {\n if (!toolCallId) return\n\n let found = false\n for (let i = 0; i < state.toolCalls.length; i++) {\n if (state.toolCalls[i].id !== toolCallId) continue\n const tc = state.toolCalls[i]\n state.toolCalls[i] = {\n ...tc,\n tool_name: toolName || tc.tool_name,\n display_name: displayName || tc.display_name,\n arguments: args || tc.arguments,\n }\n found = true\n break\n }\n if (!found) {\n state.toolCalls.push({\n id: toolCallId,\n tool_name: toolName,\n display_name: displayName,\n arguments: args,\n status: \"pending\",\n })\n }\n\n let blockFound = false\n for (let i = 0; i < state.blocks.length; i++) {\n const b = state.blocks[i]\n if (b.type !== \"tool_use\" || b.tool_call_id !== toolCallId) continue\n state.blocks[i] = {\n ...b,\n content: args || b.content,\n tool_name: toolName || b.tool_name,\n display_name: displayName || b.display_name,\n }\n blockFound = true\n break\n }\n if (!blockFound) {\n state.blocks.push({\n type: \"tool_use\",\n content: args,\n tool_call_id: toolCallId,\n tool_name: toolName || null,\n display_name: displayName || null,\n })\n }\n}\n\n// --- Tool result application ---\n\nexport function applyToolResult(\n state: TurnState,\n toolCallId: string,\n result: unknown,\n status: ToolCallProjection[\"status\"],\n durationMs: number | null,\n sourceLoop: { loop_name: string; description: string } | null,\n): void {\n let toolName = \"\"\n let displayName = \"\"\n let finalResult = result\n\n for (let i = 0; i < state.toolCalls.length; i++) {\n const tc = state.toolCalls[i]\n if (tc.id !== toolCallId) continue\n\n if (typeof result === \"string\") {\n finalResult = maybeEnrichAskUserResult(tc.tool_name, result, sourceLoop)\n }\n\n const update: Partial<ToolCallProjection> = { status, result: finalResult }\n if (durationMs != null) update.duration_ms = durationMs\n state.toolCalls[i] = { ...tc, ...update }\n toolName = tc.tool_name\n displayName = tc.display_name\n break\n }\n\n upsertToolResultBlock(state, toolCallId, finalResult, toolName, displayName)\n}\n\nexport function appendToolResultDelta(\n state: TurnState,\n toolCallId: string,\n delta: string,\n reset = false,\n): void {\n if (!toolCallId || !delta) return\n\n let toolName = \"\"\n let displayName = \"\"\n let currentResult = \"\"\n\n for (let i = 0; i < state.toolCalls.length; i++) {\n const tc = state.toolCalls[i]\n if (tc.id !== toolCallId) continue\n toolName = tc.tool_name\n displayName = tc.display_name\n if (!reset && typeof tc.result === \"string\") currentResult = tc.result\n state.toolCalls[i] = { ...tc, result: currentResult + delta }\n break\n }\n\n for (const block of state.blocks) {\n if (block.type !== \"tool_result\" || block.tool_call_id !== toolCallId) continue\n if (!reset && typeof block.content === \"string\") currentResult = block.content\n break\n }\n\n upsertToolResultBlock(state, toolCallId, currentResult + delta, toolName, displayName)\n}\n\nfunction upsertToolResultBlock(\n state: TurnState,\n toolCallId: string,\n content: unknown,\n toolName: string,\n displayName: string,\n): void {\n for (let i = 0; i < state.blocks.length; i++) {\n const block = state.blocks[i]\n if (block.type !== \"tool_result\" || block.tool_call_id !== toolCallId) continue\n state.blocks[i] = {\n ...block,\n content,\n tool_name: toolName || block.tool_name,\n display_name: displayName || block.display_name,\n }\n return\n }\n\n state.blocks.push({\n type: \"tool_result\",\n content,\n tool_call_id: toolCallId,\n tool_name: toolName || null,\n display_name: displayName || null,\n })\n}\n\n// --- Text block append ---\n\nexport function appendTextBlock(\n state: TurnState,\n blockType: ContentBlock[\"type\"],\n content: unknown,\n): void {\n if (content == null || content === \"\") return\n const text = String(content)\n const lastBlock = state.blocks[state.blocks.length - 1]\n if (lastBlock && lastBlock.type === blockType && typeof lastBlock.content === \"string\") {\n state.blocks[state.blocks.length - 1] = {\n ...lastBlock,\n content: lastBlock.content + text,\n }\n return\n }\n state.blocks.push({ type: blockType, content: text })\n}\n\n// --- Tool call arguments append ---\n\nexport function appendToolCallArguments(\n state: TurnState,\n toolCallId: string,\n delta: string,\n): void {\n let newArgs = \"\"\n for (let i = 0; i < state.toolCalls.length; i++) {\n const tc = state.toolCalls[i]\n if (tc.id === toolCallId) {\n newArgs = tc.arguments + delta\n state.toolCalls[i] = { ...tc, arguments: newArgs }\n break\n }\n }\n if (!newArgs) return\n\n for (let i = 0; i < state.blocks.length; i++) {\n const b = state.blocks[i]\n if (b.type === \"tool_use\" && b.tool_call_id === toolCallId) {\n state.blocks[i] = { ...b, content: newArgs }\n break\n }\n }\n}\n\n// --- AskUserQuestion enrichment ---\n\nfunction maybeEnrichAskUserResult(\n toolName: string,\n result: string,\n sourceLoop: { loop_name: string; description: string } | null,\n): string {\n if (!sourceLoop) return result\n const normalized = toolName.includes(\":\") ? toolName.split(\":\").pop()! : toolName\n if (normalized !== \"AskUserQuestion\") return result\n try {\n const payload = JSON.parse(result)\n if (typeof payload !== \"object\" || payload === null) return result\n payload.source_loop = sourceLoop\n return JSON.stringify(payload)\n } catch {\n return result\n }\n}\n\n// --- System notification ---\n\nexport function buildSystemNotificationTurn(\n sequence: number,\n turnId: string,\n loopId: string,\n notificationType: string,\n status: string,\n title: string,\n detail: string | null,\n metadata: Record<string, unknown>,\n): TurnProjection {\n return {\n id: turnId,\n sequence,\n turn_id: turnId,\n loop_id: loopId,\n kind: \"message\",\n role: \"system\",\n status: \"completed\",\n blocks: [\n {\n type: \"system_notification\",\n content: {\n notification_type: notificationType,\n status,\n title,\n detail,\n metadata,\n },\n },\n ],\n tool_calls: [],\n model: null,\n usage: null,\n duration_ms: 0,\n }\n}\n\nexport function buildSystemNotificationBlock(\n notificationType: string,\n status: string,\n title: string,\n detail: string | null,\n metadata: Record<string, unknown>,\n): ContentBlock {\n return {\n type: \"system_notification\",\n content: {\n notification_type: notificationType,\n status,\n title,\n detail,\n metadata,\n },\n }\n}\n\n// --- Marker turn ---\n\nexport function buildMarkerTurn(\n sequence: number,\n turnId: string,\n loopId: string,\n blockType: ContentBlock[\"type\"],\n content: unknown,\n): TurnProjection {\n return {\n id: turnId,\n sequence,\n turn_id: turnId,\n loop_id: loopId,\n kind: \"message\",\n role: \"assistant\",\n status: \"completed\",\n blocks: [{ type: blockType, content }],\n tool_calls: [],\n model: null,\n usage: null,\n duration_ms: 0,\n }\n}\n\n// --- Compaction turn ---\n\nexport function buildCompactionTurn(\n sequence: number,\n compactionId: string,\n loopId: string,\n status: TurnProjection[\"status\"],\n data: Record<string, unknown>,\n): TurnProjection {\n const tokensBefore = asInt(data.tokens_before)\n const tokensAfter = asInt(data.tokens_after)\n let savedRatio: number | null = null\n if (tokensBefore && tokensBefore > 0 && tokensAfter != null) {\n savedRatio = 1 - tokensAfter / tokensBefore\n } else {\n savedRatio = asFloat(data.saved_ratio)\n }\n let archivedCount = asInt(data.archived_count)\n if (archivedCount == null && Array.isArray(data.archived_files)) {\n archivedCount = data.archived_files.length\n }\n\n const content = data.content\n const summaryFull = compactionSummaryFull(content)\n const summaryPreview = summaryFull\n ? summaryFull\n .split(\"\\n\")\n .map((l) => l.trim())\n .filter(Boolean)\n .join(\" \")\n .slice(0, 200)\n : null\n\n return {\n id: `compaction:${compactionId}`,\n sequence,\n turn_id: `compaction:${compactionId}`,\n loop_id: loopId,\n kind: \"compaction\",\n role: \"system\",\n status,\n blocks: [],\n tool_calls: [],\n model: null,\n usage: null,\n duration_ms: 0,\n compaction_id: compactionId,\n summary_preview: summaryPreview,\n summary_full: summaryFull,\n archived_count: archivedCount,\n tokens_before: tokensBefore,\n tokens_after: tokensAfter,\n saved_ratio: savedRatio,\n trigger: asTrigger(data.trigger),\n failure_reason:\n typeof data.reason === \"string\" && data.reason ? (data.reason as string) : null,\n fallback_applied: typeof data.fallback_applied === \"boolean\" ? data.fallback_applied : null,\n }\n}\n\nfunction compactionSummaryFull(content: unknown): string | null {\n const text = String(content ?? \"\")\n if (!text) return null\n const cleaned = text\n .replace(\"<compaction-summary>\", \"\")\n .replace(\"</compaction-summary>\", \"\")\n .replace(/\\r\\n/g, \"\\n\")\n .replace(/\\r/g, \"\\n\")\n .trim()\n return cleaned || null\n}\n\nfunction asInt(value: unknown): number | null {\n if (typeof value === \"boolean\") return null\n if (typeof value === \"number\") return Math.trunc(value)\n return null\n}\n\nfunction asFloat(value: unknown): number | null {\n if (typeof value === \"boolean\") return null\n if (typeof value === \"number\") return value\n return null\n}\n\nfunction asTrigger(value: unknown): \"auto\" | \"manual\" | \"forced_retry\" | null {\n if (value === \"auto\" || value === \"manual\" || value === \"forced_retry\") return value\n return null\n}\n\n// --- Child pause helpers ---\n\nexport interface ChildPauseInfo {\n parentLoopName: string\n parentToolCallId: string\n childLoopName: string\n childToolCallId: string\n description: string\n}\n\nexport function setToolCallStatus(\n turn: TurnState | TurnProjection | null | undefined,\n toolCallId: string,\n status: ToolCallProjection[\"status\"],\n result: unknown,\n pendingQuestionRef: PendingQuestionRef | null,\n): void {\n if (!turn || !toolCallId) return\n const toolCalls = \"toolCalls\" in turn ? turn.toolCalls : turn.tool_calls\n for (let i = 0; i < toolCalls.length; i++) {\n if (toolCalls[i].id !== toolCallId) continue\n toolCalls[i] = {\n ...toolCalls[i],\n status,\n result,\n pending_question_ref: pendingQuestionRef,\n }\n return\n }\n}\n\nexport function applyAskUserPauseToTurn(\n turn: TurnState | TurnProjection | null | undefined,\n pauseToolData: Record<string, unknown>,\n toolCallId: string,\n childLoopName: string,\n description: string,\n displayNameResolver: (name: string) => string,\n): void {\n if (!turn || !toolCallId) return\n\n const sourceLoop = childLoopName\n ? { loop_name: childLoopName, description }\n : null\n const toolName = String(pauseToolData.name ?? \"AskUserQuestion\")\n const args = JSON.stringify(pauseToolData.arguments ?? {})\n const result = askUserResultFromPausePayload(pauseToolData, sourceLoop)\n\n const isTurnState = \"toolCalls\" in turn\n const toolCalls = isTurnState ? turn.toolCalls : turn.tool_calls\n const blocks = turn.blocks\n\n // upsert tool call\n const displayName = displayNameResolver(toolName)\n let found = false\n for (let i = 0; i < toolCalls.length; i++) {\n if (toolCalls[i].id !== toolCallId) continue\n toolCalls[i] = {\n ...toolCalls[i],\n tool_name: toolName || toolCalls[i].tool_name,\n display_name: displayName || toolCalls[i].display_name,\n arguments: args || toolCalls[i].arguments,\n }\n found = true\n break\n }\n if (!found) {\n toolCalls.push({\n id: toolCallId,\n tool_name: toolName,\n display_name: displayName,\n arguments: args,\n status: \"pending\",\n })\n }\n\n // upsert tool_use block\n let blockFound = false\n for (let i = 0; i < blocks.length; i++) {\n if (blocks[i].type !== \"tool_use\" || blocks[i].tool_call_id !== toolCallId) continue\n blocks[i] = { ...blocks[i], content: args, tool_name: toolName, display_name: displayName }\n blockFound = true\n break\n }\n if (!blockFound) {\n blocks.push({\n type: \"tool_use\",\n content: args,\n tool_call_id: toolCallId,\n tool_name: toolName,\n display_name: displayName,\n })\n }\n\n // set status\n setToolCallStatus(turn, toolCallId, \"awaiting_answer\", result, null)\n\n // upsert tool_result block\n let resultBlockFound = false\n for (let i = 0; i < blocks.length; i++) {\n if (blocks[i].type !== \"tool_result\" || blocks[i].tool_call_id !== toolCallId) continue\n blocks[i] = { ...blocks[i], content: result }\n resultBlockFound = true\n break\n }\n if (!resultBlockFound) {\n blocks.push({\n type: \"tool_result\",\n content: result,\n tool_call_id: toolCallId,\n tool_name: toolName,\n display_name: displayName,\n })\n }\n}\n\nexport function applyChildPauseToParent(\n parentTurn: TurnState | TurnProjection | null | undefined,\n parentToolCallId: string,\n childLoopName: string,\n childToolCallId: string,\n description: string,\n displayNameResolver: (name: string) => string,\n): void {\n if (!parentTurn || !parentToolCallId) return\n\n const toolCalls = \"toolCalls\" in parentTurn ? parentTurn.toolCalls : parentTurn.tool_calls\n const blocks = parentTurn.blocks\n\n const displayName = displayNameResolver(\"Agent\")\n let found = false\n for (let i = 0; i < toolCalls.length; i++) {\n if (toolCalls[i].id !== parentToolCallId) continue\n toolCalls[i] = {\n ...toolCalls[i],\n tool_name: \"Agent\",\n display_name: displayName || toolCalls[i].display_name,\n }\n found = true\n break\n }\n if (!found) {\n toolCalls.push({\n id: parentToolCallId,\n tool_name: \"Agent\",\n display_name: displayName,\n arguments: \"\",\n status: \"pending\",\n })\n }\n\n // upsert tool_use block\n let blockFound = false\n for (let i = 0; i < blocks.length; i++) {\n if (blocks[i].type !== \"tool_use\" || blocks[i].tool_call_id !== parentToolCallId) continue\n blockFound = true\n break\n }\n if (!blockFound) {\n blocks.push({\n type: \"tool_use\",\n content: \"\",\n tool_call_id: parentToolCallId,\n tool_name: \"Agent\",\n display_name: displayName,\n })\n }\n\n setToolCallStatus(parentTurn, parentToolCallId, \"awaiting_answer\", null, {\n child_loop_name: childLoopName,\n child_tool_call_id: childToolCallId,\n description: description || null,\n })\n}\n\nfunction askUserResultFromPausePayload(\n pauseToolData: Record<string, unknown>,\n sourceLoop: { loop_name: string; description: string } | null,\n): string {\n const args =\n typeof pauseToolData.arguments === \"object\" && pauseToolData.arguments !== null\n ? (pauseToolData.arguments as Record<string, unknown>)\n : {}\n const payload: Record<string, unknown> = { questions: args.questions ?? [] }\n if (sourceLoop) payload.source_loop = sourceLoop\n return JSON.stringify(payload)\n}\n\nexport function sourceLoopFor(\n loopId: string,\n loopDescriptions: Map<string, string>,\n): { loop_name: string; description: string } | null {\n if (loopId === \"root\") return null\n const description = loopDescriptions.get(loopId)\n if (!description) return null\n return { loop_name: loopId, description }\n}\n\nexport function normalizeChildPause(\n pausePayload: Record<string, unknown>,\n): {\n pauseToolData: Record<string, unknown>\n childLoopName: string\n childToolCallId: string\n description: string\n} {\n const rawPtd = pausePayload.pause_tool_data\n const pauseToolData: Record<string, unknown> =\n typeof rawPtd === \"object\" && rawPtd !== null\n ? { ...(rawPtd as Record<string, unknown>) }\n : { ...pausePayload }\n\n let sourceLoop = pauseToolData.source_loop as Record<string, unknown> | undefined\n if (typeof sourceLoop !== \"object\" || sourceLoop === null) {\n sourceLoop = pausePayload.source_loop as Record<string, unknown> | undefined\n }\n\n const childLoopName =\n String(pausePayload.child_loop_name ?? \"\") ||\n (typeof sourceLoop === \"object\" && sourceLoop ? String(sourceLoop.name ?? \"\") : \"\")\n\n const childToolCallId =\n String(\n pausePayload.child_pause_tool_call_id ?? pauseToolData.tool_call_id ?? \"\",\n )\n\n const description =\n typeof sourceLoop === \"object\" && sourceLoop ? String(sourceLoop.description ?? \"\") : \"\"\n\n if (childLoopName && description) {\n pauseToolData.source_loop = { name: childLoopName, description }\n }\n\n return { pauseToolData, childLoopName, childToolCallId, description }\n}\n","import type { ContentBlock, PendingQuestionRef, ToolBridgeContent } from \"./projection\"\n\nexport interface TextContentPart {\n type: \"text\"\n text: string\n}\n\nexport interface ImageUrlContentPart {\n type: \"image_url\"\n image_url: {\n url: string\n }\n}\n\nexport interface FileContentPart {\n type: \"file\"\n name: string\n data: string\n}\n\nexport type MessageContentPart = TextContentPart | ImageUrlContentPart | FileContentPart\nexport type MessageContent = string | MessageContentPart[]\n\nexport interface ToolCallInfo {\n id: string\n name: string\n display_name?: string | null\n arguments: string\n result?: unknown\n status?: \"pending\" | \"done\" | \"error\" | \"cancelled\" | \"awaiting_answer\"\n duration_ms?: number | null\n pending_question_ref?: PendingQuestionRef | null\n}\n\nexport type { ToolBridgeContent }\n\n/** Derive tool status from the result content string. */\nexport function inferToolStatus(\n resultStr: string,\n): \"done\" | \"error\" | \"cancelled\" {\n if (resultStr.includes('\"Cancelled by user\"')) return \"cancelled\"\n try {\n const parsed = JSON.parse(resultStr)\n if (typeof parsed === \"object\" && parsed !== null) {\n // Direct error: {\"error\": \"...\"}\n if (\"error\" in parsed && parsed.error) return \"error\"\n // 部分工具把输出包装为 {\"result\": {\"error\": \"...\"}, ...}\n const nested = parsed.result\n if (typeof nested === \"object\" && nested !== null && \"error\" in nested && nested.error) {\n return \"error\"\n }\n }\n } catch {\n // not JSON, treat as success\n }\n return \"done\"\n}\n\nexport interface MemoryRefInfo {\n id: number\n content_preview: string\n skill_name?: string | null\n}\n\nexport interface CompactionInfo {\n compaction_id: string\n summary_preview?: string | null\n summary_full?: string | null\n archived_count?: number | null\n archived_files?: ArchivedFileInfo[] | null\n archived_tool_calls?: ArchivedToolCallInfo[] | null\n tokens_before?: number | null\n tokens_after?: number | null\n saved_ratio?: number | null\n trigger?: \"auto\" | \"manual\" | \"forced_retry\" | null\n failure_reason?: string | null\n fallback_applied?: boolean | null\n}\n\nexport interface ArchivedFileInfo {\n tool_name?: string | null\n filename?: string | null\n relative_path?: string | null\n size_bytes?: number | null\n}\n\nexport interface ArchivedToolCallInfo {\n tool_call_id?: string | null\n tool_name?: string | null\n archive_path?: string | null\n replacement_content?: string | null\n entry_id?: string | null\n}\n\nexport interface ChatMessage {\n role: \"user\" | \"assistant\" | \"tool\" | \"error\"\n content: MessageContent\n reasoning?: string\n tool_calls?: ToolCallInfo[]\n status?: \"streaming\" | \"completed\" | \"paused\" | \"failed\" | \"interrupted\"\n duration_ms?: number\n timestamp?: string\n entry_id?: string\n parent_id?: string | null\n loop_name?: string\n /** Entry kind from backend -- present for non-message entries like mode changes. */\n kind?: string\n /** Memory references injected into this turn's context */\n memory_refs?: MemoryRefInfo[]\n /** Raw projection blocks for block-level UI rendering. */\n blocks?: ContentBlock[]\n /** Compaction metadata for compaction turns. */\n compaction?: CompactionInfo\n}\n","import { inferToolStatus } from \"../../schemas/message\"\nimport type {\n ContentBlock,\n MemoryRef,\n ToolCallProjection,\n TurnProjection,\n} from \"../../schemas/projection\"\n\nexport interface TurnState {\n turnId: string\n loopId: string\n role: \"user\" | \"assistant\" | \"system\"\n model: string | null\n startedAt: number\n contextWindow: number\n blocks: ContentBlock[]\n toolCalls: ToolCallProjection[]\n usage: Record<string, unknown> | null\n memoryRefs: MemoryRef[] | null\n parentForkToolCallId: string | null\n}\n\nexport function createTurnState(\n turnId: string,\n loopId: string,\n opts: {\n model?: string | null\n contextWindow?: number\n memoryRefs?: MemoryRef[] | null\n } = {},\n): TurnState {\n return {\n turnId,\n loopId,\n role: \"assistant\",\n model: opts.model ?? null,\n startedAt: Date.now(),\n contextWindow: opts.contextWindow ?? 0,\n blocks: [],\n toolCalls: [],\n usage: null,\n memoryRefs: opts.memoryRefs ?? null,\n parentForkToolCallId: null,\n }\n}\n\nexport function snapshot(\n state: TurnState,\n sequence: number,\n status: TurnProjection[\"status\"],\n): TurnProjection {\n return {\n id: state.turnId,\n sequence,\n turn_id: state.turnId,\n loop_id: state.loopId,\n kind: \"message\",\n role: state.role,\n status,\n blocks: [...state.blocks],\n tool_calls: [...state.toolCalls],\n model: state.model,\n usage: state.usage ? { ...state.usage } : null,\n duration_ms: Math.max(0, Date.now() - state.startedAt),\n started_at: new Date(state.startedAt).toISOString(),\n context_window: state.contextWindow,\n memory_refs: state.memoryRefs,\n parent_fork_tool_call_id: state.parentForkToolCallId,\n }\n}\n\nexport const PAUSE_TOOL_NAMES = new Set([\"AskUserQuestion\", \"ExitPlanMode\"])\n\nexport function toolStatusFromResult(result: unknown): ToolCallProjection[\"status\"] {\n const text =\n typeof result === \"string\"\n ? result\n : Array.isArray(result)\n ? result\n .filter(\n (p): p is { type: string; text: string } =>\n typeof p === \"object\" && p !== null && p.type === \"text\",\n )\n .map((p) => p.text ?? \"\")\n .join(\"\\n\")\n : String(result ?? \"\")\n return inferToolStatus(text)\n}\n","import type { MemoryRef, TurnProjection } from \"../../schemas/projection\"\nimport {\n applyAskUserPauseToTurn,\n applyChildPauseToParent,\n appendTextBlock,\n appendToolCallArguments,\n appendToolResultDelta,\n applyToolResult,\n buildCompactionTurn,\n buildMarkerTurn,\n buildSystemNotificationBlock,\n buildSystemNotificationTurn,\n type ChildPauseInfo,\n normalizeChildPause,\n setToolCallStatus,\n sourceLoopFor,\n upsertToolCall,\n} from \"./helpers\"\nimport { createTurnState, PAUSE_TOOL_NAMES, snapshot, toolStatusFromResult, type TurnState } from \"./state\"\n\nexport interface RawEvent {\n type: string\n payload: Record<string, unknown>\n}\n\nexport type ProjectionUpdate =\n | { kind: \"upsert\"; turn: TurnProjection }\n | { kind: \"workspace_changed\"; loopId: string; toolCallId?: string; toolName?: string }\n\nexport class ClientProjectionBuilder {\n private activeTurns = new Map<string, TurnState>()\n private lastTurnIds = new Map<string, string>()\n private latestTurns = new Map<string, TurnProjection>()\n private loopDescriptions = new Map<string, string>()\n private pendingChildPauses = new Map<string, ChildPauseInfo>()\n private pendingMemoryRefs = new Map<string, { turnId: string; refs: MemoryRef[] }>()\n private activeCompactions = new Map<string, Record<string, unknown>>()\n private seq = 0\n private syntheticCounter = 0\n private displayNameResolver: (name: string) => string\n\n constructor(displayNameResolver?: (name: string) => string) {\n this.displayNameResolver = displayNameResolver ?? ((n) => n)\n }\n\n processBatch(events: RawEvent[]): ProjectionUpdate[] {\n const lastUpsertByTurn = new Map<string, ProjectionUpdate & { kind: \"upsert\" }>()\n const nonUpserts: ProjectionUpdate[] = []\n for (const event of events) {\n const updates = this.processEvent(event)\n if (!updates) continue\n for (const u of updates) {\n if (u.kind === \"upsert\") {\n lastUpsertByTurn.set(u.turn.turn_id, u)\n } else {\n nonUpserts.push(u)\n }\n }\n }\n return [...nonUpserts, ...lastUpsertByTurn.values()]\n }\n\n processEvent(event: RawEvent): ProjectionUpdate[] | null {\n const payload = event.payload\n const loopId = String(payload.loop_name ?? \"root\")\n\n switch (event.type) {\n case \"memory:inject:done\":\n return this.onMemoryInject(loopId, payload)\n case \"memory:inject:none\":\n return null\n case \"loop:turn\":\n return this.onLoopTurn(loopId, payload)\n case \"mode:change\":\n return this.onModeChange(loopId, payload)\n case \"plan:status:update\":\n return this.onPlanStatusUpdate(loopId, payload)\n case \"workspace:changed\":\n return this.onWorkspaceChanged(loopId, payload)\n case \"agent:start\":\n return this.onAgentStart(loopId, payload)\n case \"bg:started\":\n return this.onBgStarted(loopId, payload)\n case \"bg:tasks_completed\":\n return this.onBgTasksCompleted(loopId, payload)\n case \"loop:ask_user_answer\":\n return this.onAskUserAnswer(loopId, payload)\n case \"user:message\":\n return this.onUserMessage(loopId, payload)\n }\n\n if (event.type.startsWith(\"compaction:\"))\n return this.onCompaction(event.type, loopId, payload)\n\n const state = this.activeTurns.get(loopId)\n if (!state) {\n if (event.type === \"chat:end\") {\n this.pendingMemoryRefs.delete(loopId)\n return null\n }\n if (event.type === \"agent:end\") return this.onAgentEnd(null, loopId, payload)\n return null\n }\n\n switch (event.type) {\n case \"llm:thinking:delta\":\n return this.onDelta(state, \"thinking\", \"\", String(payload.content ?? \"\"))\n case \"llm:content:delta\":\n return this.onDelta(state, \"text\", \"\", String(payload.content ?? \"\"))\n case \"llm:tool_call:created\":\n return this.onToolCallCreated(state, payload)\n case \"llm:response:done\":\n return this.onResponseDone(state, loopId, payload)\n case \"tool:result:delta\":\n return this.onToolResultDelta(state, payload)\n case \"tool:result:done\":\n return this.onToolResultDone(state, loopId, payload)\n case \"loop:tool_ui\":\n return this.onToolUi(state, payload)\n case \"loop:tool_bridge\":\n return this.onToolBridge(state, payload)\n case \"tool:approval:required\":\n return this.onToolApprovalRequired(state, payload)\n case \"loop:child_pause\":\n return this.onChildPause(state, loopId, payload)\n case \"chat:end\":\n return this.onChatEnd(state, loopId, payload)\n case \"agent:end\":\n return this.onAgentEnd(state, loopId, payload)\n default:\n return null\n }\n }\n\n reset(): void {\n this.activeTurns.clear()\n this.lastTurnIds.clear()\n this.latestTurns.clear()\n this.loopDescriptions.clear()\n this.pendingChildPauses.clear()\n this.pendingMemoryRefs.clear()\n this.activeCompactions.clear()\n this.seq = 0\n this.syntheticCounter = 0\n }\n\n seedSequence(maxSeq: number): void {\n if (maxSeq > this.seq) {\n this.seq = maxSeq\n }\n }\n\n // --- Event handlers ---\n\n private onMemoryInject(\n loopId: string,\n payload: Record<string, unknown>,\n ): null {\n const refs = payload.memory_refs\n const turnId = String(payload.turn_id ?? \"\")\n if (Array.isArray(refs) && refs.length > 0) {\n this.pendingMemoryRefs.set(loopId, {\n turnId,\n refs: refs.map((r: Record<string, unknown>) => ({\n id: Number(r.id),\n content_preview: String(r.content_preview ?? \"\"),\n skill_name: r.skill_name != null ? String(r.skill_name) : null,\n })),\n })\n }\n return null\n }\n\n private onLoopTurn(\n loopId: string,\n payload: Record<string, unknown>,\n ): ProjectionUpdate[] {\n let turnId = String(payload.turn_id ?? this.nextTurnId(`turn:${loopId}`))\n let memoryRefs: MemoryRef[] | null = null\n\n const pending = this.pendingMemoryRefs.get(loopId)\n if (pending) {\n this.pendingMemoryRefs.delete(loopId)\n if (pending.turnId) turnId = pending.turnId\n memoryRefs = pending.refs\n }\n\n const rawCw = payload.context_window\n const contextWindow =\n typeof rawCw === \"number\" && rawCw > 0 ? Math.trunc(rawCw) : 0\n\n const state = createTurnState(turnId, loopId, {\n model: optStr(payload.model),\n contextWindow,\n memoryRefs,\n })\n\n this.activeTurns.set(loopId, state)\n this.lastTurnIds.set(loopId, turnId)\n\n const turn = snapshot(state, this.nextSeq(), \"streaming\")\n this.latestTurns.set(loopId, turn)\n return [{ kind: \"upsert\", turn }]\n }\n\n private onModeChange(\n loopId: string,\n payload: Record<string, unknown>,\n ): ProjectionUpdate[] {\n const content: Record<string, string> = {}\n if (payload.from != null && payload.from !== \"\") content.from = String(payload.from)\n if (payload.to != null && payload.to !== \"\") content.to = String(payload.to)\n const turn = buildMarkerTurn(\n this.nextSeq(),\n this.nextTurnId(\"mode_change\"),\n loopId,\n \"mode_change\",\n content,\n )\n return [{ kind: \"upsert\", turn }]\n }\n\n private onPlanStatusUpdate(\n loopId: string,\n payload: Record<string, unknown>,\n ): ProjectionUpdate[] {\n let statuses = payload.statuses\n if (typeof statuses !== \"object\" || statuses === null) {\n statuses = payload._statuses ?? {}\n }\n const turn = buildMarkerTurn(\n this.nextSeq(),\n this.nextTurnId(\"plan_status\"),\n loopId,\n \"plan_status\",\n { plan_yaml: payload.plan_yaml ?? \"\", statuses },\n )\n return [{ kind: \"upsert\", turn }]\n }\n\n private onWorkspaceChanged(\n loopId: string,\n payload: Record<string, unknown>,\n ): ProjectionUpdate[] {\n const updates: ProjectionUpdate[] = [\n {\n kind: \"workspace_changed\",\n loopId,\n toolCallId: optStr(payload.tool_call_id) ?? undefined,\n toolName: toolNameFromPayload(payload) ?? undefined,\n },\n ]\n const state = this.activeTurns.get(loopId)\n if (state) {\n const turn = snapshot(state, this.nextSeq(), \"streaming\")\n this.latestTurns.set(loopId, turn)\n this.lastTurnIds.set(loopId, turn.turn_id)\n updates.push({ kind: \"upsert\", turn })\n }\n return updates\n }\n\n private onAgentStart(\n loopId: string,\n payload: Record<string, unknown>,\n ): ProjectionUpdate[] {\n const description = optStr(payload.description)\n if (description) this.loopDescriptions.set(loopId, description)\n const turn = buildSystemNotificationTurn(\n this.nextSeq(),\n this.nextTurnId(\"agent:start\"),\n loopId,\n \"agent:start\",\n \"running\",\n `Agent: ${payload.description ?? payload.skill_id ?? \"agent\"}`,\n optStr(payload.prompt),\n {\n skill_id: optStr(payload.skill_id),\n description: optStr(payload.description),\n parent_fork_tool_call_id: optStr(payload.parent_fork_tool_call_id),\n },\n )\n return [{ kind: \"upsert\", turn }]\n }\n\n private onBgStarted(\n loopId: string,\n payload: Record<string, unknown>,\n ): ProjectionUpdate[] {\n const taskId = optStr(payload.task_id) ?? \"\"\n const command = optStr(payload.command)\n const description = optStr(payload.description)\n const turn = buildSystemNotificationTurn(\n this.nextSeq(),\n this.nextTurnId(\"bg:started\"),\n loopId,\n \"bg:started\",\n \"running\",\n description ?? `Background: ${taskId || \"task\"}`,\n command,\n { task_id: taskId, command, description },\n )\n return [{ kind: \"upsert\", turn }]\n }\n\n private onBgTasksCompleted(\n loopId: string,\n payload: Record<string, unknown>,\n ): ProjectionUpdate[] {\n const taskIds = Array.isArray(payload.task_ids) ? payload.task_ids : []\n const count = typeof payload.count === \"number\" ? payload.count : taskIds.length\n const detail = taskIds.map(String).join(\", \")\n const turn = buildSystemNotificationTurn(\n this.nextSeq(),\n this.nextTurnId(\"bg:tasks_completed\"),\n loopId,\n \"bg:tasks_completed\",\n \"done\",\n `Background tasks completed (${count})`,\n detail || null,\n { task_ids: taskIds, count },\n )\n return [{ kind: \"upsert\", turn }]\n }\n\n private onAskUserAnswer(\n loopId: string,\n payload: Record<string, unknown>,\n ): ProjectionUpdate[] {\n const toolCallId = String(payload.tool_call_id ?? \"\")\n const pending = this.pendingChildPauses.get(toolCallId)\n const parentLoopId = pending?.parentLoopName\n\n // clear child pause\n if (pending) {\n this.pendingChildPauses.delete(toolCallId)\n const childTurn =\n this.activeTurns.get(pending.childLoopName) ??\n this.latestTurns.get(pending.childLoopName)\n setToolCallStatus(childTurn, pending.childToolCallId, \"done\", null, null)\n const parentTurn =\n this.activeTurns.get(pending.parentLoopName) ??\n this.latestTurns.get(pending.parentLoopName)\n setToolCallStatus(parentTurn, pending.parentToolCallId, \"done\", null, null)\n }\n\n // clear direct ask-user pause\n const directTurn = this.activeTurns.get(loopId) ?? this.latestTurns.get(loopId)\n setToolCallStatus(directTurn, toolCallId, \"done\", null, null)\n\n return this.collectLoopUpdates(loopId, parentLoopId)\n }\n\n private onUserMessage(\n _loopId: string,\n payload: Record<string, unknown>,\n ): ProjectionUpdate[] {\n const entryId = String(payload.entry_id ?? this.nextTurnId(\"user\"))\n const displayContent = payload.display_content ?? payload.content ?? \"\"\n const turn: TurnProjection = {\n id: entryId,\n sequence: this.nextSeq(),\n turn_id: entryId,\n loop_id: \"root\",\n kind: \"message\",\n role: \"user\",\n status: \"completed\",\n blocks: [{ type: \"text\", content: displayContent }],\n tool_calls: [],\n model: null,\n usage: null,\n duration_ms: 0,\n }\n return [{ kind: \"upsert\", turn }]\n }\n\n // --- Delta / streaming events ---\n\n private onDelta(\n state: TurnState,\n blockType: \"thinking\" | \"text\",\n _toolCallId: string,\n content: string,\n ): ProjectionUpdate[] | null {\n if (!content) return null\n appendTextBlock(state, blockType, content)\n return this.syncPatch(state)\n }\n\n private onToolCallCreated(\n state: TurnState,\n payload: Record<string, unknown>,\n ): ProjectionUpdate[] | null {\n if (\"arguments_delta\" in payload) {\n const delta = String(payload.arguments_delta ?? \"\")\n const toolCallId = String(payload.id ?? \"\")\n if (delta && toolCallId) {\n appendToolCallArguments(state, toolCallId, delta)\n return this.syncPatch(state)\n }\n return null\n }\n const toolCallId = String(payload.id ?? \"\")\n const toolName = toolNameFromPayload(payload)\n const displayName = String(payload.display_name ?? \"\") || this.displayNameResolver(toolName)\n const args = toolArgsFromPayload(payload)\n upsertToolCall(state, toolCallId, toolName, displayName, args)\n return this.syncPatch(state)\n }\n\n private onResponseDone(\n state: TurnState,\n loopId: string,\n payload: Record<string, unknown>,\n ): ProjectionUpdate[] | null {\n const model = optStr(payload.model)\n if (model) state.model = model\n if (typeof payload.usage === \"object\" && payload.usage !== null) {\n state.usage = { ...(payload.usage as Record<string, unknown>) }\n }\n\n // apply tool calls from full response\n const toolCalls = payload.tool_calls\n if (Array.isArray(toolCalls)) {\n for (const raw of toolCalls) {\n if (typeof raw !== \"object\" || raw === null) continue\n const tc = raw as Record<string, unknown>\n const fn = (tc.function ?? {}) as Record<string, unknown>\n const toolName = String(fn.name ?? \"\")\n const displayName =\n String(tc.display_name ?? \"\") || this.displayNameResolver(toolName)\n upsertToolCall(\n state,\n String(tc.id ?? \"\"),\n toolName,\n displayName,\n String(fn.arguments ?? \"\"),\n )\n }\n }\n\n if (state.toolCalls.length === 0) {\n return this.finalize(loopId, \"completed\")\n }\n return this.syncPatch(state)\n }\n\n private onToolResultDone(\n state: TurnState,\n loopId: string,\n payload: Record<string, unknown>,\n ): ProjectionUpdate[] | null {\n const toolCallId = String(payload.tool_call_id ?? \"\")\n const streamedResult = state.toolCalls.find((toolCall) => toolCall.id === toolCallId)?.result\n const content =\n payload.content_from_deltas === true ? (streamedResult ?? \"\") : payload.content ?? \"\"\n const status = toolStatusFromResult(content)\n const rawDuration = payload.duration_ms\n const durationMs =\n typeof rawDuration === \"number\" && rawDuration >= 0\n ? Math.round(rawDuration)\n : null\n\n const sl = sourceLoopFor(state.loopId, this.loopDescriptions)\n applyToolResult(state, toolCallId, content, status, durationMs, sl)\n\n if (this.shouldFinalizeAfterToolResults(state)) {\n return this.finalize(loopId, \"completed\")\n }\n return this.syncPatch(state)\n }\n\n private onToolResultDelta(\n state: TurnState,\n payload: Record<string, unknown>,\n ): ProjectionUpdate[] | null {\n appendToolResultDelta(\n state,\n String(payload.tool_call_id ?? \"\"),\n String(payload.content ?? \"\"),\n payload.content_reset === true,\n )\n return this.syncPatch(state)\n }\n\n private onToolUi(\n state: TurnState,\n payload: Record<string, unknown>,\n ): ProjectionUpdate[] | null {\n const toolCallId = String(payload.tool_call_id ?? \"\")\n const ui = payload.ui\n if (toolCallId && typeof ui === \"object\" && ui !== null) {\n state.blocks.push({\n type: \"tool_ui\",\n content: ui,\n tool_call_id: toolCallId,\n })\n }\n return this.syncPatch(state)\n }\n\n private onToolBridge(\n state: TurnState,\n payload: Record<string, unknown>,\n ): ProjectionUpdate[] | null {\n const bridge = payload.bridge\n if (typeof bridge !== \"object\" || bridge === null) return null\n state.blocks.push({\n type: \"tool_bridge\",\n content: bridge,\n tool_call_id: String(payload.tool_call_id ?? \"\") || null,\n })\n return this.syncPatch(state)\n }\n\n private onToolApprovalRequired(\n state: TurnState,\n payload: Record<string, unknown>,\n ): ProjectionUpdate[] | null {\n const toolCallId = String(payload.tool_call_id ?? \"\")\n const toolName = String(payload.tool_name ?? \"\")\n const displayName = this.displayNameResolver(toolName)\n upsertToolCall(state, toolCallId, toolName, displayName, \"\")\n return this.syncPatch(state)\n }\n\n private onChildPause(\n state: TurnState,\n loopId: string,\n payload: Record<string, unknown>,\n ): ProjectionUpdate[] | null {\n const pauseToolData = payload.pause_tool_data\n if (typeof pauseToolData !== \"object\" || pauseToolData === null)\n return this.syncPatch(state)\n\n const ptd = pauseToolData as Record<string, unknown>\n const sourceLoop = ptd.source_loop as Record<string, unknown> | undefined\n if (typeof sourceLoop === \"object\" && sourceLoop) {\n const slName = String(sourceLoop.name ?? \"\")\n const slDesc = optStr(sourceLoop.description)\n if (slName && slDesc) this.loopDescriptions.set(slName, slDesc)\n }\n\n const { childLoopName, childToolCallId, description } =\n normalizeChildPause(payload as Record<string, unknown>)\n\n if (!childToolCallId) return this.syncPatch(state)\n\n const existing = this.pendingChildPauses.get(childToolCallId)\n const parentLoopName = String(\n payload.parent_loop_name ?? existing?.parentLoopName ?? \"root\",\n )\n const parentToolCallId = String(\n payload.parent_fork_tool_call_id ?? existing?.parentToolCallId ?? \"\",\n )\n const resolvedChildLoopName =\n String(payload.child_loop_name ?? \"\") || existing?.childLoopName || childLoopName || loopId\n\n this.pendingChildPauses.set(childToolCallId, {\n parentLoopName,\n parentToolCallId,\n childLoopName: resolvedChildLoopName,\n childToolCallId,\n description: description || existing?.description || \"\",\n })\n\n // apply to child\n applyAskUserPauseToTurn(\n state,\n ptd,\n childToolCallId,\n resolvedChildLoopName,\n this.pendingChildPauses.get(childToolCallId)!.description,\n this.displayNameResolver,\n )\n\n // apply to parent\n const parentTurn =\n this.activeTurns.get(parentLoopName) ?? this.latestTurns.get(parentLoopName)\n if (parentTurn) {\n applyChildPauseToParent(\n parentTurn,\n parentToolCallId,\n resolvedChildLoopName,\n childToolCallId,\n this.pendingChildPauses.get(childToolCallId)!.description,\n this.displayNameResolver,\n )\n }\n\n return this.collectLoopUpdates(loopId, parentLoopName)\n }\n\n private onChatEnd(\n state: TurnState,\n loopId: string,\n payload: Record<string, unknown>,\n ): ProjectionUpdate[] | null {\n const status = String(payload.status ?? \"completed\")\n\n const pauseToolData = payload.pause_tool_data\n if (typeof pauseToolData === \"object\" && pauseToolData !== null) {\n const ptd = pauseToolData as Record<string, unknown>\n const pauseToolName = String(ptd.name ?? \"\")\n const normalized = pauseToolName.includes(\":\")\n ? pauseToolName.split(\":\").pop()!\n : pauseToolName\n const sourceLoop = ptd.source_loop as Record<string, unknown> | undefined\n\n if (typeof sourceLoop === \"object\" && sourceLoop) {\n const slName = String(sourceLoop.name ?? \"\")\n const slDesc = optStr(sourceLoop.description)\n if (slName && slDesc) this.loopDescriptions.set(slName, slDesc)\n\n if (status === \"paused\" && slName) {\n applyChildPauseToParent(\n state,\n String(ptd.parent_fork_tool_call_id ?? \"\"),\n slName,\n String(ptd.tool_call_id ?? \"\"),\n slDesc ?? \"\",\n this.displayNameResolver,\n )\n\n const childTurn = this.activeTurns.get(slName)\n if (childTurn) {\n applyAskUserPauseToTurn(\n childTurn,\n ptd,\n String(ptd.tool_call_id ?? \"\"),\n slName,\n slDesc ?? \"\",\n this.displayNameResolver,\n )\n }\n }\n } else if (status === \"paused\" && normalized === \"AskUserQuestion\") {\n applyAskUserPauseToTurn(\n state,\n ptd,\n String(ptd.tool_call_id ?? \"\"),\n \"\",\n \"\",\n this.displayNameResolver,\n )\n }\n }\n\n const finalStatus = (\n { completed: \"completed\", paused: \"paused\", failed: \"failed\", interrupted: \"interrupted\" } as Record<string, TurnProjection[\"status\"]>\n )[status]\n\n if (!finalStatus) return null\n if (!this.activeTurns.has(loopId)) {\n this.pendingMemoryRefs.delete(loopId)\n }\n return this.finalize(loopId, finalStatus)\n }\n\n private onAgentEnd(\n state: TurnState | null,\n loopId: string,\n payload: Record<string, unknown>,\n ): ProjectionUpdate[] | null {\n const ok = payload.ok !== false\n const status = ok ? \"done\" : \"error\"\n const title = `Agent: ${payload.description ?? payload.skill_id ?? \"agent\"}`\n const detail = optStr(payload.error)\n const metadata = {\n skill_id: optStr(payload.skill_id),\n description: optStr(payload.description),\n parent_fork_tool_call_id: optStr(payload.parent_fork_tool_call_id),\n ok,\n }\n if (state) {\n state.blocks.push(buildSystemNotificationBlock(\"agent:end\", status, title, detail, metadata))\n return this.finalize(loopId, ok ? \"completed\" : \"failed\")\n }\n const turn = buildSystemNotificationTurn(\n this.nextSeq(), this.nextTurnId(\"agent:end\"), loopId, \"agent:end\", status, title, detail, metadata,\n )\n return [{ kind: \"upsert\", turn }]\n }\n\n private onCompaction(\n eventType: string,\n loopId: string,\n payload: Record<string, unknown>,\n ): ProjectionUpdate[] | null {\n const compactionId = String(payload.compaction_id ?? \"\")\n if (!compactionId) return null\n\n const current = {\n ...(this.activeCompactions.get(compactionId) ?? {}),\n ...payload,\n loop_id: loopId,\n }\n\n let status: TurnProjection[\"status\"]\n switch (eventType) {\n case \"compaction:start\":\n status = \"streaming\"\n this.activeCompactions.set(compactionId, current)\n break\n case \"compaction:end\":\n status = \"completed\"\n this.activeCompactions.delete(compactionId)\n break\n case \"compaction:abort\":\n status = \"interrupted\"\n this.activeCompactions.delete(compactionId)\n break\n case \"compaction:error\":\n status = \"failed\"\n this.activeCompactions.delete(compactionId)\n break\n default:\n status = \"streaming\"\n this.activeCompactions.set(compactionId, current)\n }\n\n const turn = buildCompactionTurn(this.nextSeq(), compactionId, loopId, status, current)\n return [{ kind: \"upsert\", turn }]\n }\n\n // --- Internal helpers ---\n\n private syncPatch(state: TurnState): ProjectionUpdate[] {\n const turn = snapshot(state, this.nextSeq(), \"streaming\")\n this.latestTurns.set(state.loopId, turn)\n this.lastTurnIds.set(state.loopId, turn.turn_id)\n return [{ kind: \"upsert\", turn }]\n }\n\n private finalize(\n loopId: string,\n status: TurnProjection[\"status\"],\n ): ProjectionUpdate[] | null {\n const state = this.activeTurns.get(loopId)\n if (!state) return null\n this.activeTurns.delete(loopId)\n const turn = snapshot(state, this.nextSeq(), status)\n this.lastTurnIds.set(loopId, turn.turn_id)\n this.latestTurns.set(loopId, turn)\n return [{ kind: \"upsert\", turn }]\n }\n\n private shouldFinalizeAfterToolResults(state: TurnState): boolean {\n if (state.toolCalls.length === 0) return true\n if (state.toolCalls.some((tc) => tc.status === \"pending\")) return false\n return !state.toolCalls.some((tc) => {\n const normalized = tc.tool_name.includes(\":\")\n ? tc.tool_name.split(\":\").pop()!\n : tc.tool_name\n return PAUSE_TOOL_NAMES.has(normalized)\n })\n }\n\n private collectLoopUpdates(\n ...loopIds: (string | undefined | null)[]\n ): ProjectionUpdate[] {\n const updates: ProjectionUpdate[] = []\n for (const loopId of loopIds) {\n if (!loopId) continue\n const state = this.activeTurns.get(loopId)\n if (state) {\n updates.push(...this.syncPatch(state))\n continue\n }\n const proj = this.latestTurns.get(loopId)\n if (proj) {\n const updated = { ...proj, sequence: this.nextSeq() }\n this.latestTurns.set(loopId, updated)\n updates.push({ kind: \"upsert\", turn: updated })\n }\n }\n return updates\n }\n\n private nextSeq(): number {\n return ++this.seq\n }\n\n private nextTurnId(prefix: string): string {\n this.syntheticCounter++\n const hex = Math.random().toString(16).slice(2, 10)\n return `${prefix}:${this.syntheticCounter}:${hex}`\n }\n}\n\n// --- Utility functions ---\n\nfunction optStr(value: unknown): string | null {\n if (value == null || value === \"\") return null\n return String(value)\n}\n\nfunction toolNameFromPayload(payload: Record<string, unknown>): string {\n const fn = payload.function\n if (typeof fn === \"object\" && fn !== null) {\n return String((fn as Record<string, unknown>).name ?? \"\")\n }\n return String(payload.tool_name ?? \"\")\n}\n\nfunction toolArgsFromPayload(payload: Record<string, unknown>): string {\n const fn = payload.function\n if (typeof fn === \"object\" && fn !== null) {\n return String((fn as Record<string, unknown>).arguments ?? \"\")\n }\n return \"\"\n}\n","import type {\n ContentBlock,\n ToolCallProjection,\n TurnProjection,\n} from \"../../schemas/projection\"\nimport { inferToolStatus } from \"../../schemas/message\"\nimport {\n applyAskUserPauseToTurn,\n applyChildPauseToParent,\n buildCompactionTurn,\n setToolCallStatus,\n} from \"./helpers\"\n\nexport interface RawHistoryEntry {\n id?: string\n kind?: string\n loop_name?: string\n message?: Record<string, unknown>\n data?: Record<string, unknown>\n timestamp?: string\n [key: string]: unknown\n}\n\n/** Rebuild completed UI turns from raw persisted history entries. */\nexport function projectHistory(entries: RawHistoryEntry[]): TurnProjection[] {\n const turns: TurnProjection[] = []\n const toolOwners = new Map<string, TurnProjection>()\n const latestAssistantByLoop = new Map<string, TurnProjection>()\n const pendingChildPauses = new Map<\n string,\n { childLoopId: string; parentLoopId: string; parentToolCallId: string }\n >()\n let sequence = 0\n\n for (const entry of entries) {\n const kind = String(entry.kind ?? \"\")\n const loopId = String(entry.loop_name ?? \"root\")\n const id = String(entry.id ?? `history-${sequence + 1}`)\n if (kind === \"message\" && isRecord(entry.message)) {\n const message = entry.message\n const role = String(message.role ?? \"\")\n if (role === \"tool\") {\n const toolCallId = String(message.tool_call_id ?? \"\")\n const owner = toolOwners.get(toolCallId)\n const toolCall = owner?.tool_calls.find((item) => item.id === toolCallId)\n if (owner && toolCall) {\n toolCall.status = message._error\n ? \"error\"\n : inferToolStatus(String(message.content ?? \"\"))\n toolCall.result = message.content ?? \"\"\n owner.blocks.push({\n type: \"tool_result\",\n content: message.content ?? \"\",\n tool_call_id: toolCallId,\n })\n }\n continue\n }\n if (role !== \"user\" && role !== \"assistant\" && role !== \"system\") continue\n\n const toolCalls = role === \"assistant\" ? buildToolCalls(message.tool_calls) : []\n const blocks = buildBlocks(message, toolCalls)\n const turn: TurnProjection = {\n id,\n sequence: ++sequence,\n turn_id: id,\n loop_id: loopId,\n kind: \"message\",\n role,\n status: message._error ? \"failed\" : \"completed\",\n blocks,\n tool_calls: toolCalls,\n model: stringOrNull(message.model),\n usage: isRecord(message._usage) ? { ...message._usage } : null,\n duration_ms: numberOrZero(message._duration_ms),\n started_at: typeof entry.timestamp === \"string\" ? entry.timestamp : undefined,\n }\n turns.push(turn)\n if (role === \"assistant\") latestAssistantByLoop.set(loopId, turn)\n for (const toolCall of toolCalls) toolOwners.set(toolCall.id, turn)\n continue\n }\n\n if (kind === \"mode_change\") {\n turns.push(markerTurn(id, ++sequence, loopId, \"mode_change\", entry.data ?? {}))\n } else if (kind === \"plan_status\") {\n const data = entry.data ?? {}\n turns.push(\n markerTurn(id, ++sequence, loopId, \"plan_status\", {\n plan_yaml: data.plan_yaml ?? \"\",\n statuses: data.statuses ?? data._statuses ?? {},\n }),\n )\n } else if (kind === \"tool_ui\" || kind === \"tool_bridge\") {\n const data = entry.data ?? {}\n const toolCallId = String(data.tool_call_id ?? \"\")\n const owner = toolOwners.get(toolCallId) ?? findLatestAssistant(turns, loopId)\n const content = kind === \"tool_ui\" ? data.ui : data.bridge\n if (owner && content !== undefined) {\n owner.blocks.push({\n type: kind,\n content,\n tool_call_id: toolCallId || null,\n })\n }\n } else if (kind === \"compaction\" || kind === \"tool_result_archive\") {\n const data = entry.data ?? {}\n const compactionId = String(data.compaction_id ?? entry.id ?? `history-${sequence + 1}`)\n let content = isRecord(entry.message) ? entry.message.content : undefined\n if (kind === \"tool_result_archive\") {\n const archivedCount = Array.isArray(data.archived_files) ? data.archived_files.length : 0\n content = `<compaction-summary>\\n已归档 ${archivedCount} 个大型工具结果。\\n</compaction-summary>`\n }\n turns.push(\n buildCompactionTurn(++sequence, compactionId, loopId, \"completed\", {\n ...data,\n content,\n }),\n )\n } else if (kind === \"child_pause\") {\n const data = entry.data ?? {}\n const sourceLoop = isRecord(data.source_loop) ? data.source_loop : {}\n const childLoopId = String(data.child_loop_name ?? sourceLoop.name ?? \"\")\n const childToolCallId = String(data.child_pause_tool_call_id ?? \"\")\n const parentToolCallId = String(data.parent_fork_tool_call_id ?? \"\")\n const pauseToolData = isRecord(data.pause_tool_data) ? data.pause_tool_data : {}\n const description = String(sourceLoop.description ?? \"\")\n applyAskUserPauseToTurn(\n latestAssistantByLoop.get(childLoopId),\n pauseToolData,\n childToolCallId,\n childLoopId,\n description,\n (name) => name,\n )\n applyChildPauseToParent(\n latestAssistantByLoop.get(loopId),\n parentToolCallId,\n childLoopId,\n childToolCallId,\n description,\n (name) => name,\n )\n if (childToolCallId) {\n pendingChildPauses.set(childToolCallId, {\n childLoopId,\n parentLoopId: loopId,\n parentToolCallId,\n })\n }\n } else if (kind === \"ask_user_answer\") {\n const data = entry.data ?? {}\n const toolCallId = String(data.tool_call_id ?? \"\")\n const pending = pendingChildPauses.get(toolCallId)\n if (pending) {\n setToolCallStatus(latestAssistantByLoop.get(pending.childLoopId), toolCallId, \"done\", null, null)\n setToolCallStatus(\n latestAssistantByLoop.get(pending.parentLoopId),\n pending.parentToolCallId,\n \"done\",\n null,\n null,\n )\n pendingChildPauses.delete(toolCallId)\n } else {\n setToolCallStatus(latestAssistantByLoop.get(loopId), toolCallId, \"done\", null, null)\n }\n turns.push(\n markerTurn(\n id,\n ++sequence,\n loopId,\n \"ask_user_answer\",\n data,\n toolCallId || null,\n ),\n )\n }\n }\n return turns\n}\n\nfunction buildToolCalls(value: unknown): ToolCallProjection[] {\n if (!Array.isArray(value)) return []\n return value.filter(isRecord).map((raw) => {\n const fn = isRecord(raw.function) ? raw.function : {}\n const name = String(fn.name ?? \"\")\n return {\n id: String(raw.id ?? \"\"),\n tool_name: name,\n display_name: String(raw.display_name ?? name),\n arguments: typeof fn.arguments === \"string\" ? fn.arguments : JSON.stringify(fn.arguments ?? {}),\n status: \"running\",\n result: null,\n }\n })\n}\n\nfunction buildBlocks(\n message: Record<string, unknown>,\n toolCalls: ToolCallProjection[],\n): ContentBlock[] {\n // 平台注入的用户消息(如 Factory 项目初始化指引)会带 _display_content:\n // 完整指令给 LLM,用户只看展示文案。缺了这条会把内部提醒整段泄露到聊天区。\n const displayContent = message.role === \"user\" ? message._display_content : undefined\n const stored = message._blocks\n const blocks: ContentBlock[] = []\n if (displayContent !== undefined) {\n blocks.push({ type: \"text\", content: displayContent })\n } else if (Array.isArray(stored)) {\n for (const raw of stored) {\n if (!isRecord(raw)) continue\n const type = String(raw.type ?? \"\")\n if (type === \"thinking\") blocks.push({ type, content: raw.thinking ?? raw.content ?? \"\" })\n if (type === \"text\") blocks.push({ type, content: raw.text ?? raw.content ?? \"\" })\n }\n } else if (message.content !== undefined && message.content !== \"\") {\n blocks.push({ type: \"text\", content: message.content })\n }\n for (const toolCall of toolCalls) {\n blocks.push({\n type: \"tool_use\",\n content: { name: toolCall.tool_name, arguments: toolCall.arguments },\n tool_call_id: toolCall.id,\n })\n }\n return blocks\n}\n\nfunction markerTurn(\n id: string,\n sequence: number,\n loopId: string,\n type: \"mode_change\" | \"plan_status\" | \"ask_user_answer\",\n content: Record<string, unknown>,\n toolCallId: string | null = null,\n): TurnProjection {\n return {\n id,\n sequence,\n turn_id: id,\n loop_id: loopId,\n kind: type as TurnProjection[\"kind\"],\n role: \"system\",\n status: \"completed\",\n blocks: [{ type, content, tool_call_id: toolCallId }],\n tool_calls: [],\n model: null,\n usage: null,\n duration_ms: 0,\n }\n}\n\nfunction isRecord(value: unknown): value is Record<string, unknown> {\n return typeof value === \"object\" && value !== null && !Array.isArray(value)\n}\n\nfunction stringOrNull(value: unknown): string | null {\n return typeof value === \"string\" ? value : null\n}\n\nfunction numberOrZero(value: unknown): number {\n return typeof value === \"number\" ? value : 0\n}\n\nfunction findLatestAssistant(\n turns: TurnProjection[],\n loopId: string,\n): TurnProjection | undefined {\n for (let index = turns.length - 1; index >= 0; index -= 1) {\n const turn = turns[index]\n if (turn?.role === \"assistant\" && turn.loop_id === loopId) return turn\n }\n return undefined\n}\n","import type { BackgroundTask } from \"../schemas/background\"\nimport type { TurnProjection } from \"../schemas/projection\"\nimport type { SessionDetail, SessionInfo, TemplateId } from \"../schemas/session\"\nimport type { Task } from \"../schemas/task\"\nimport type { BladeClient, UploadProgress } from \"../blade-client\"\nimport type { AgentSession } from \"../session/agent-session\"\nimport {\n SessionSetupError,\n type SessionDefinition,\n type SkillDefinition,\n type SolutionDefinition,\n} from \"../session/definition\"\nimport type { SessionProfile } from \"../types/sdk-profile\"\nimport { projectHistory, type RawHistoryEntry } from \"../shared/projection\"\n\nexport interface CreateSessionRequest {\n intent?: string\n template_id?: TemplateId\n solution_id?: string\n biz_role_id?: string | null\n primary_skill_id?: string | null\n model?: string | null\n enable_thinking?: boolean | null\n memory_enabled?: boolean | null\n env?: Record<string, string>\n disable_tools?: string[] | null\n session_solution_asset_id?: string | null\n compaction_ratio?: number | null\n runtime_type?: \"sandbox\" | \"daemon\" | null\n daemon_id?: string | null\n}\n\nexport interface CheckpointNode {\n id: string\n parent_id: string | null\n content_preview: string\n content: string\n timestamp: string\n}\n\nexport type ContentPart =\n | { type: \"text\"; text: string }\n | { type: \"image_url\"; image_url: { url: string; detail?: string } }\n\nexport interface HistoryNode {\n id: string\n parent_id: string | null\n kind: string\n role: string\n timestamp: string\n preview: string\n content: string | ContentPart[]\n tool_calls: Array<{\n id?: string\n type?: string\n function?: { name?: string; arguments?: string }\n }> | null\n usage: { prompt_tokens?: number; completion_tokens?: number; total_tokens?: number } | null\n total_tokens: number\n token_diff: number\n is_deprecated: boolean\n loop_name: string\n}\n\nexport interface SessionHistory {\n nodes: HistoryNode[]\n active_branch: string | null\n branches: string[]\n system_prompt_tokens?: number | null\n tools_tokens?: number | null\n tokenizer_model?: string | null\n}\n\nexport interface TokenizeResult {\n model: string\n prompt_tokens: number\n prompt: string\n}\n\nexport interface PaginatedSessionsResult {\n items: SessionInfo[]\n total: number\n limit: number\n offset: number\n content_match_truncated?: boolean\n}\n\ninterface ListSessionsPageParams {\n limit: number\n offset: number\n template_id_prefix?: string\n solution_id?: string\n q?: string\n}\n\nexport interface SkillDevSession {\n session: SessionInfo\n skill_id: string\n display_name: string\n skill_description: string\n}\n\nexport interface ShareLinkResult {\n token: string\n url: string\n expires_at: string | null\n}\n\nexport interface SessionContextStats {\n tokens_used: number\n context_window: number\n compaction_ratio: number\n}\n\nexport interface FileEntry {\n name: string\n path: string\n is_dir: boolean\n created_at: number\n tags?: string[]\n}\n\nexport type UploadFileEntry = File | { file: File; name: string }\n\nexport interface UploadFilesOptions {\n onProgress?: (progress: UploadProgress) => void\n}\n\nexport interface ImportPreviewSkill {\n name: string\n description: string\n path: string\n}\n\nexport interface ImportPreviewScenario {\n scenario?: { name?: string }\n skills?: string[]\n preview_urls?: string[]\n init_script?: string\n generated_at?: string\n}\n\nexport interface ImportPreview {\n user_messages: string[]\n turn_count: number\n skills: ImportPreviewSkill[]\n scenario: ImportPreviewScenario | null\n}\n\nfunction toCreateSessionPayload(request: CreateSessionRequest) {\n return {\n intent: request.intent ?? \"\",\n template_id: request.template_id,\n solution_id: request.solution_id,\n biz_role_id: request.biz_role_id ?? null,\n model: request.model ?? null,\n enable_thinking: request.enable_thinking ?? null,\n memory_enabled: request.memory_enabled ?? null,\n primary_skill_id: request.primary_skill_id ?? null,\n env: request.env,\n disable_tools: request.disable_tools ?? null,\n session_solution_asset_id: request.session_solution_asset_id ?? null,\n compaction_ratio: request.compaction_ratio ?? null,\n ...(request.runtime_type ? { runtime_type: request.runtime_type } : {}),\n ...(request.daemon_id ? { daemon_id: request.daemon_id } : {}),\n }\n}\n\nexport class SessionsResource {\n constructor(private client: BladeClient) {}\n\n /**\n * 连接一个已存在的会话,返回实时会话对象 AgentSession\n * (自动完成历史加载、Socket.IO 订阅、断线重连补数)。\n */\n connect(sessionId: string): Promise<AgentSession> {\n return this.client.hub.connect(sessionId)\n }\n\n /** 创建新会话并直接连接,返回可收发消息的 AgentSession。 */\n async create(request: CreateSessionRequest | SessionDefinition = {}): Promise<AgentSession> {\n if (isSessionDefinition(request)) {\n return this.createDeclared(request)\n }\n const { session_id } = await this.createSessionWithRequest(request)\n return this.connect(session_id)\n }\n\n private async createDeclared(definition: SessionDefinition): Promise<AgentSession> {\n const { intent, solution, skills = [], config } = definition\n validateDefinition(definition)\n let solutionRequest: Pick<CreateSessionRequest, \"solution_id\" | \"session_solution_asset_id\" | \"biz_role_id\"> = {}\n try {\n solutionRequest = solution ? await this.prepareSolution(solution) : {}\n } catch (error) {\n throw setupError(\"solution\", \"Solution 准备失败\", error)\n }\n\n let session_id: string\n try {\n const created = await this.createSessionWithRequest({\n intent,\n ...solutionRequest,\n model: config?.model,\n enable_thinking: config?.enableThinking,\n memory_enabled: config?.memoryEnabled,\n compaction_ratio: config?.compactionRatio,\n env: config?.env,\n disable_tools: config?.disableTools,\n })\n session_id = created.session_id\n } catch (error) {\n const assetId = solutionRequest.session_solution_asset_id\n const assetCleaned = await this.cleanupSolutionAsset(assetId)\n const cleanupMessage = assetId\n ? assetCleaned\n ? \";临时 Solution 已清理\"\n : `;临时 Solution ${assetId} 清理失败`\n : \"\"\n throw setupError(\"session\", `会话创建失败${cleanupMessage}`, error)\n }\n\n let installingSkill = \"\"\n try {\n for (const skill of skills) {\n installingSkill = skill.name\n await this.client.json(\"POST\", `/api/sessions/${encodeURIComponent(session_id)}/skills:upload`, {\n name: skill.name,\n files: skill.files,\n })\n }\n } catch (error) {\n const sessionCleaned = await this.deleteSession(session_id).then(\n () => true,\n () => false,\n )\n const assetCleaned = await this.cleanupSolutionAsset(solutionRequest.session_solution_asset_id)\n const cleanupMessage = sessionCleaned ? \"未完成的会话已清理\" : `请手动删除会话 ${session_id}`\n const assetCleanupMessage = assetCleaned ? \"\" : \";临时 Solution 清理失败\"\n throw setupError(\n \"skill\",\n `Skill \"${installingSkill}\" 安装失败;${cleanupMessage}${assetCleanupMessage}`,\n error,\n session_id,\n )\n }\n\n // 会话创建时 Server 已把声明式 Solution 持久化到会话目录,临时资产不再需要。\n await this.cleanupSolutionAsset(solutionRequest.session_solution_asset_id)\n\n try {\n return await this.connect(session_id)\n } catch (error) {\n throw setupError(\"connection\", `会话连接失败;可使用 sessionId ${session_id} 重试`, error, session_id)\n }\n }\n\n private async prepareSolution(\n solution: SolutionDefinition,\n ): Promise<Pick<CreateSessionRequest, \"solution_id\" | \"session_solution_asset_id\" | \"biz_role_id\">> {\n if (\"id\" in solution) {\n return { solution_id: solution.id, biz_role_id: solution.role ?? null }\n }\n\n const prepared = await this.client.json<{ asset_id: string }>(\n \"POST\",\n \"/api/session-assets/solutions\",\n { files: solution.files },\n )\n return {\n session_solution_asset_id: prepared.asset_id,\n biz_role_id: solution.role ?? null,\n }\n }\n\n private async cleanupSolutionAsset(assetId?: string | null): Promise<boolean> {\n if (!assetId) return true\n try {\n await this.client.json(\"DELETE\", `/api/session-assets/solutions/${encodeURIComponent(assetId)}`)\n return true\n } catch {\n return false\n }\n }\n\n private fetchSessionsPage({\n limit,\n offset,\n template_id_prefix,\n solution_id,\n q,\n }: ListSessionsPageParams): Promise<PaginatedSessionsResult> {\n const searchParams = new URLSearchParams()\n searchParams.set(\"limit\", String(limit))\n searchParams.set(\"offset\", String(offset))\n if (template_id_prefix) searchParams.set(\"template_id_prefix\", template_id_prefix)\n if (solution_id) searchParams.set(\"solution_id\", solution_id)\n const trimmedQuery = q?.trim()\n if (trimmedQuery) searchParams.set(\"q\", trimmedQuery)\n return this.client.json(\"GET\", `/api/sessions?${searchParams.toString()}`)\n }\n\n async listSessions(template_id_prefix?: string, solution_id?: string): Promise<SessionInfo[]> {\n const pageSize = 100\n const sessions: SessionInfo[] = []\n let offset = 0\n while (true) {\n const page = await this.fetchSessionsPage({ limit: pageSize, offset, template_id_prefix, solution_id })\n sessions.push(...page.items)\n if (sessions.length >= page.total || page.items.length === 0) return sessions\n offset += page.items.length\n }\n }\n\n listSessionsPaginated(params: {\n limit: number\n offset: number\n template_id_prefix?: string\n solution_id?: string\n q?: string\n }): Promise<PaginatedSessionsResult> {\n return this.fetchSessionsPage(params)\n }\n\n listSessionsWithSkillData(): Promise<SkillDevSession[]> {\n return this.client.json(\"GET\", \"/api/sessions/with-skill-data\")\n }\n\n createSession(\n intent?: string,\n template_id?: TemplateId,\n primary_skill_id?: string | null,\n ): Promise<{ session_id: string }> {\n return this.createSessionWithRequest({ intent, template_id, primary_skill_id })\n }\n\n createSessionWithRequest(request: CreateSessionRequest): Promise<{ session_id: string }> {\n return this.client.json(\"POST\", \"/api/sessions\", toCreateSessionPayload(request))\n }\n\n createWithProfile(params: {\n intent: string\n profile: SessionProfile\n }): Promise<{ session_id: string }> {\n const { intent, profile } = params\n return this.createSessionWithRequest({\n intent,\n ...profileToCreateSessionRequest(profile),\n })\n }\n\n getSession(sessionId: string, init?: RequestInit): Promise<SessionDetail> {\n return this.client.jsonFromInit(`/api/sessions/${sessionId}`, init)\n }\n\n updateSession(sessionId: string, payload: { intent?: string }): Promise<SessionDetail> {\n return this.client.json(\"PATCH\", `/api/sessions/${sessionId}`, payload)\n }\n\n setSessionEnv(sessionId: string, env: Record<string, string>): Promise<SessionDetail> {\n return this.client.json(\"PUT\", `/api/sessions/${sessionId}/env`, { env })\n }\n\n pinSession(sessionId: string, pinned: boolean): Promise<SessionInfo> {\n return this.client.json(\"PATCH\", `/api/sessions/${sessionId}/pin`, { pinned })\n }\n\n startReplaySession(sourceSessionId: string, speed: 1 | 2 | 5 = 5): Promise<{ session_id: string }> {\n return this.client.json(\"POST\", `/api/sessions/${sourceSessionId}/replay`, { speed })\n }\n\n updateReplaySession(\n sessionId: string,\n payload: { speed?: 1 | 2 | 5; status?: \"autonomous\" },\n ): Promise<{ replay_state: SessionInfo[\"replay_state\"] }> {\n return this.client.json(\"PATCH\", `/api/sessions/${sessionId}/replay`, payload)\n }\n\n updateSharing(sessionId: string, shared: boolean): Promise<{ shared: boolean }> {\n return this.client.json(\"PATCH\", `/api/sessions/${sessionId}/sharing`, { shared })\n }\n\n updateSessionMemory(sessionId: string, memoryEnabled: boolean): Promise<{ memory_enabled: boolean }> {\n return this.client.json(\"PATCH\", `/api/sessions/${sessionId}/memory`, {\n memory_enabled: memoryEnabled,\n })\n }\n\n createShare(sessionId: string): Promise<ShareLinkResult> {\n return this.client.json(\"POST\", `/api/sessions/${sessionId}/share`, {})\n }\n\n revokeShare(sessionId: string, token: string): Promise<{ revoked: boolean }> {\n return this.client.json(\"DELETE\", `/api/sessions/${sessionId}/share/${encodeURIComponent(token)}`)\n }\n\n async getSharedSession(token: string): Promise<TurnProjection[]> {\n const entries = await this.client.jsonFromInit<RawHistoryEntry[]>(`/api/share/${encodeURIComponent(token)}`, {\n credentials: \"omit\",\n headers: { Accept: \"application/json\" },\n })\n return projectHistory(entries)\n }\n\n getSessionTasks(sessionId: string): Promise<Task[]> {\n return this.client.json(\"GET\", `/api/sessions/${sessionId}/tasks`)\n }\n\n async getSessionTurns(sessionId: string): Promise<TurnProjection[]> {\n const entries = await this.client.json<RawHistoryEntry[]>(\n \"GET\",\n `/api/sessions/${sessionId}/messages`,\n )\n return projectHistory(entries)\n }\n\n getSessionContextStats(sessionId: string, init?: RequestInit): Promise<SessionContextStats> {\n return this.client.jsonFromInit(`/api/sessions/${sessionId}/context-stats`, init)\n }\n\n getSessionHistory(sessionId: string, init?: RequestInit): Promise<SessionHistory> {\n return this.client.jsonFromInit(`/api/sessions/${sessionId}/history`, init)\n }\n\n tokenizePrompt(prompt: string, model?: string): Promise<TokenizeResult> {\n return this.client.json(\"POST\", \"/api/sessions/tokenize/prompt\", { prompt, model })\n }\n\n tokenizeMessages(\n messages: Array<Record<string, unknown>>,\n options?: {\n model?: string\n add_generation_prompt?: boolean\n enable_thinking?: boolean | null\n tools?: Array<Record<string, unknown>>\n },\n ): Promise<TokenizeResult> {\n return this.client.json(\"POST\", \"/api/sessions/tokenize/messages\", {\n messages,\n model: options?.model,\n add_generation_prompt: options?.add_generation_prompt ?? true,\n enable_thinking: options?.enable_thinking ?? null,\n tools: options?.tools ?? null,\n })\n }\n\n getSessionCheckpoints(\n sessionId: string,\n init?: RequestInit,\n ): Promise<{ nodes: CheckpointNode[]; leaf_id: string | null }> {\n return this.client.jsonFromInit(`/api/sessions/${sessionId}/checkpoints`, init)\n }\n\n checkoutSession(\n sessionId: string,\n checkpointId: string,\n position: \"before\" | \"turn_end\",\n mode?: \"both\" | \"conversation\" | \"code\",\n linear?: boolean,\n ): Promise<{\n id: string\n content: string\n position: string\n mode?: string\n files_restored?: boolean\n linear?: boolean\n }> {\n return this.client.json(\"POST\", `/api/sessions/${sessionId}/checkout`, {\n checkpoint_id: checkpointId,\n position,\n ...(mode ? { mode } : {}),\n ...(linear ? { linear } : {}),\n })\n }\n\n async rewindSession(sessionId: string, checkpointId: string): Promise<{ id: string; content: string }> {\n const result = await this.checkoutSession(sessionId, checkpointId, \"before\")\n return { id: result.id, content: result.content }\n }\n\n switchBranch(sessionId: string, checkpointId: string): Promise<{ id: string; leaf_id: string }> {\n return this.client.json(\"POST\", `/api/sessions/${sessionId}/switch-branch`, {\n checkpoint_id: checkpointId,\n })\n }\n\n deleteSession(sessionId: string): Promise<{ deleted: boolean }> {\n return this.client.json(\"DELETE\", `/api/sessions/${sessionId}`)\n }\n\n listBackgroundTasks(sessionId: string, init?: RequestInit): Promise<BackgroundTask[]> {\n return this.client.jsonFromInit(`/api/sessions/${sessionId}/background-tasks`, init)\n }\n\n getBackgroundTask(\n sessionId: string,\n taskId: string,\n tail = 100,\n init?: RequestInit,\n ): Promise<BackgroundTask> {\n return this.client.jsonFromInit(`/api/sessions/${sessionId}/background-tasks/${taskId}?tail=${tail}`, init)\n }\n\n stopBackgroundTask(\n sessionId: string,\n taskId: string,\n ): Promise<{ message: string; task?: BackgroundTask | null }> {\n return this.client.json(\"POST\", `/api/sessions/${sessionId}/background-tasks/${taskId}/stop`)\n }\n\n\n probeSessionUrl(sessionId: string, url: string): Promise<{ reachable: boolean }> {\n return this.client.json(\n \"GET\",\n `/api/sessions/${sessionId}/probe-url?url=${encodeURIComponent(url)}`,\n )\n }\n\n listDir(sessionId: string, dirPath: string): Promise<FileEntry[]> {\n return this.client.json(\"GET\", `/api/sessions/${sessionId}/ls/${encodeURIComponent(dirPath)}`)\n }\n\n async countFiles(sessionId: string, dirPath = \"\"): Promise<number> {\n const entries = await this.listDir(sessionId, dirPath)\n let count = 0\n for (const entry of entries) {\n count += entry.is_dir ? await this.countFiles(sessionId, entry.path) : 1\n }\n return count\n }\n\n /** 在浏览器中下载一个会话文件。 */\n async downloadFile(sessionId: string, filePath: string, downloadName?: string): Promise<void> {\n if (typeof document === \"undefined\") {\n throw new Error(\"downloadFile 只能在浏览器中使用\")\n }\n const response = await this.client.fetch(\n \"GET\",\n `/api/sessions/${encodeURIComponent(sessionId)}/files/${encodeURIComponent(filePath)}`,\n )\n const objectUrl = URL.createObjectURL(await response.blob())\n const anchor = document.createElement(\"a\")\n anchor.href = objectUrl\n anchor.download = downloadName || filePath.split(\"/\").pop() || \"download\"\n anchor.style.display = \"none\"\n document.body.appendChild(anchor)\n anchor.click()\n anchor.remove()\n globalThis.setTimeout(() => URL.revokeObjectURL(objectUrl), 1_000)\n }\n\n async uploadFiles(\n sessionId: string,\n dirPath: string,\n files: FileList | File[] | UploadFileEntry[],\n options: UploadFilesOptions = {},\n ): Promise<{ uploaded: string[]; failed: string[] }> {\n const formData = new FormData()\n const entries = Array.from(files).map((f) =>\n f instanceof File ? { file: f, name: f.name } : (f as { file: File; name: string }),\n )\n for (const entry of entries) {\n formData.append(\"files\", entry.file, entry.name)\n }\n // webkitdirectory 选择的文件带 webkitRelativePath;拖入的文件夹把相对路径放在 name 里。\n // 任一形式包含目录分隔符时都发送 paths,供服务端重建目录结构。\n const relativePaths = entries.map((e) => e.file.webkitRelativePath || e.name)\n if (relativePaths.some((p) => p.includes(\"/\"))) {\n formData.append(\"paths\", JSON.stringify(relativePaths))\n }\n const response = await this.client.formData(\n \"POST\",\n `/api/sessions/${sessionId}/upload/${encodeURIComponent(dirPath)}`,\n formData,\n { expectOk: false, onUploadProgress: options.onProgress },\n )\n return response.json()\n }\n\n async deleteFile(sessionId: string, filePath: string): Promise<void> {\n await this.client.json(\"DELETE\", `/api/sessions/${sessionId}/files/${encodeURIComponent(filePath)}`)\n }\n\n writeFile(sessionId: string, filePath: string, content: string): Promise<{ success: boolean }> {\n return this.client.json(\"PUT\", `/api/sessions/${sessionId}/files/${encodeURIComponent(filePath)}`, {\n content,\n })\n }\n\n renameFile(sessionId: string, filePath: string, newName: string): Promise<{ path: string }> {\n return this.client.json(\"POST\", `/api/sessions/${sessionId}/files/${encodeURIComponent(filePath)}/rename`, {\n new_name: newName,\n })\n }\n\n copyFile(sessionId: string, filePath: string): Promise<{ path: string }> {\n return this.client.json(\"POST\", `/api/sessions/${sessionId}/files/${encodeURIComponent(filePath)}/copy`)\n }\n\n shareFile(\n sessionId: string,\n sourcePath: string,\n linkName?: string,\n shareFolder?: string,\n ): Promise<{ path: string; target: string }> {\n return this.client.json(\"POST\", `/api/sessions/${sessionId}/share-file`, {\n source_path: sourcePath,\n link_name: linkName ?? \"\",\n share_folder: shareFolder ?? \"\",\n })\n }\n\n getDownloadDirUrl(sessionId: string, dirPath: string): string {\n return this.client.buildAuthedUrl(`/api/sessions/${sessionId}/download-dir/${encodeURIComponent(dirPath)}`)\n }\n\n async exportSession(sessionId: string): Promise<void> {\n await this.getSession(sessionId)\n const a = document.createElement(\"a\")\n a.href = this.client.buildAuthedUrl(`/api/sessions/${sessionId}/export`)\n a.download = `${sessionId}.zip`\n document.body.appendChild(a)\n a.click()\n a.remove()\n }\n\n async previewImport(file: File): Promise<ImportPreview> {\n const form = new FormData()\n form.append(\"file\", file)\n const res = await this.client.formData(\"POST\", \"/api/sessions/preview-import\", form)\n return res.json()\n }\n\n async importSession(\n file: File,\n name?: string,\n solutionId?: string | null,\n ): Promise<{ session_id: string }> {\n const form = new FormData()\n form.append(\"file\", file)\n if (name) form.append(\"name\", name)\n if (solutionId) form.append(\"solution_id\", solutionId)\n const res = await this.client.formData(\"POST\", \"/api/sessions/import\", form)\n return res.json()\n }\n}\n\nfunction isSessionDefinition(request: CreateSessionRequest | SessionDefinition): request is SessionDefinition {\n return \"solution\" in request || \"skills\" in request || \"config\" in request\n}\n\nfunction validateDefinition(definition: SessionDefinition): void {\n if (definition.solution) {\n if (\"id\" in definition.solution) {\n if (!definition.solution.id.trim()) {\n throw new SessionSetupError(\"Solution id 不能为空\", \"solution\")\n }\n } else {\n validateTextFiles(definition.solution.files, \"solution\", \"Solution\")\n if (!definition.solution.files.some((file) => file.path === \"solution.yaml\")) {\n throw new SessionSetupError(\"Solution 缺少根目录 solution.yaml\", \"solution\")\n }\n }\n }\n for (const skill of definition.skills ?? []) validateSkill(skill)\n}\n\nfunction validateSkill(skill: SkillDefinition): void {\n if (!/^[a-z0-9-]+\\/[a-z0-9-]+$/.test(skill.name)) {\n throw new SessionSetupError(`Skill name \"${skill.name}\" 必须是小写的 组织/名称`, \"skill\")\n }\n validateTextFiles(skill.files, \"skill\", `Skill \"${skill.name}\"`)\n if (!skill.files.some((file) => file.path === \"SKILL.md\")) {\n throw new SessionSetupError(`Skill \"${skill.name}\" 缺少根目录 SKILL.md`, \"skill\")\n }\n}\n\nfunction validateTextFiles(\n files: Array<{ path: string; content: string }>,\n stage: ConstructorParameters<typeof SessionSetupError>[1],\n label: string,\n): void {\n if (files.length === 0) throw new SessionSetupError(`${label} files 不能为空`, stage)\n const paths = new Set<string>()\n for (const file of files) {\n const path = file.path\n if (\n !path\n || path !== path.trim()\n || path.startsWith(\"/\")\n || path.includes(\"\\\\\")\n || path.split(\"/\").some((part) => !part || part === \".\" || part === \"..\")\n || /^[a-zA-Z]:/.test(path)\n ) {\n throw new SessionSetupError(`${label} 文件路径不安全:\"${path}\"`, stage)\n }\n if (paths.has(path)) {\n throw new SessionSetupError(`${label} 文件路径重复:\"${path}\"`, stage)\n }\n paths.add(path)\n }\n}\n\nfunction setupError(\n stage: ConstructorParameters<typeof SessionSetupError>[1],\n message: string,\n cause: unknown,\n sessionId?: string,\n): SessionSetupError {\n const detail = cause instanceof Error ? cause.message : String(cause)\n return new SessionSetupError(`${message}:${detail}`, stage, sessionId, { cause })\n}\n\nfunction profileToCreateSessionRequest(profile: SessionProfile): CreateSessionRequest {\n const solution = profile.solution\n return {\n solution_id: solution?.kind === \"existing\" ? solution.solutionId : undefined,\n session_solution_asset_id: solution?.kind === \"prepared\" ? solution.assetId : undefined,\n biz_role_id: solution?.bizRoleId ?? null,\n model: profile.model ?? null,\n compaction_ratio: profile.compactionRatio ?? null,\n enable_thinking: profile.enableThinking ?? null,\n memory_enabled: profile.memoryEnabled ?? null,\n disable_tools: profile.disableTools ?? null,\n env: profile.env,\n }\n}\n","export type CommandHandler = (payload: unknown, meta: { toolCallId?: string }) => void\n\ninterface BufferedCommand {\n payload: unknown\n meta: { toolCallId?: string }\n}\n\n/** 每个 action 在 handler 注册前最多缓冲的指令条数,超出丢最旧的。 */\nconst BUFFER_LIMIT_PER_ACTION = 20\n\n/**\n * 指令注册表:onCommand 事后注册 + 注册前缓冲补投。\n *\n * action 的来源见 ./protocol.ts 顶部说明——它由技能作者在工具返回值的\n * `_meta.bridge` 字段里写入,是技能作者与宿主页面开发者的业务契约。\n * 缓冲的意义:指令可能在页面还没来得及调用 onCommand 时就到达(比如\n * 历史回放),先存起来、注册时立刻补投,消除\"注册晚了漏事件\"的坑。\n */\nexport class CommandRegistry {\n private handlers = new Map<string, Set<CommandHandler>>()\n private buffered = new Map<string, BufferedCommand[]>()\n\n onCommand(action: string, handler: CommandHandler): () => void {\n let set = this.handlers.get(action)\n if (!set) {\n set = new Set()\n this.handlers.set(action, set)\n }\n set.add(handler)\n\n const pending = this.buffered.get(action)\n if (pending?.length) {\n this.buffered.delete(action)\n for (const command of pending) {\n this.invoke(handler, action, command)\n }\n }\n return () => {\n this.handlers.get(action)?.delete(handler)\n }\n }\n\n dispatch(action: string, payload: unknown, meta: { toolCallId?: string } = {}): void {\n const set = this.handlers.get(action)\n if (set && set.size > 0) {\n for (const handler of [...set]) {\n this.invoke(handler, action, { payload, meta })\n }\n return\n }\n let pending = this.buffered.get(action)\n if (!pending) {\n pending = []\n this.buffered.set(action, pending)\n }\n pending.push({ payload, meta })\n if (pending.length > BUFFER_LIMIT_PER_ACTION) {\n pending.shift()\n console.warn(\n `[agent-client] 指令 \"${action}\" 无人处理且缓冲已满,最旧的一条已丢弃。` +\n `请调用 onCommand(\"${action}\", handler) 注册处理函数。`,\n )\n }\n }\n\n private invoke(handler: CommandHandler, action: string, command: BufferedCommand): void {\n try {\n handler(command.payload, command.meta)\n } catch (error) {\n console.warn(`[agent-client] 指令 \"${action}\" 的处理函数抛出异常:`, error)\n }\n }\n\n clear(): void {\n this.handlers.clear()\n this.buffered.clear()\n }\n}\n","import type { ChatMessage, ToolCallInfo } from \"../schemas/message\"\nimport type { TurnProjection } from \"../schemas/projection\"\nimport type { SessionStatus } from \"../schemas/session\"\n\n/**\n * AgentSession 的语义事件表。\n *\n * 这是\"底层逃生舱\"(L1):React 使用者优先用 useChat() 的响应式状态(L2)\n * 或 <ChatView onToolCall/commands> 的声明式入口(L3),一般不需要直接监听。\n * Vue / 无框架集成者用 session.on(...) 精确订阅。\n */\nexport interface AgentSessionEvents {\n /** 一条消息物化完成(turn 离开 streaming 状态)。 */\n message: { message: ChatMessage; turn: TurnProjection }\n /** 智能体发起了一次工具调用(首次出现)。 */\n toolCall: { toolCall: ToolCallInfo; turn: TurnProjection }\n /** 一次工具调用出结果(done / error / cancelled)。 */\n toolResult: { toolCall: ToolCallInfo; turn: TurnProjection }\n /** 一轮回复结束。status: completed / paused / interrupted / failed。 */\n chatEnd: { status: string }\n /** 运行错误(system:error、发送失败等)。 */\n error: { message: string }\n /** planning / executing 模式切换。 */\n modeChange: { mode: \"planning\" | \"executing\" }\n /**\n * 智能体给宿主页面下发指令。\n *\n * action 的来源:技能作者在工具实现的返回值 JSON 里写 `_meta.bridge:\n * { action, payload }`,后端剥离后经事件流送达前端。action 是技能作者与\n * 宿主页面开发者约定的业务契约字符串(如 \"map.highlight\"),LLM 不参与、\n * SDK 不做枚举。一般用 session.onCommand(action, fn) 消费,而不是监听本事件。\n */\n command: { action: string; payload: unknown; toolCallId?: string }\n /** 系统通知(技能阶段提示、后台任务启动等)。 */\n notification: {\n type: string\n title: string\n detail?: string\n status: \"info\" | \"running\" | \"done\" | \"error\"\n loopId?: string\n metadata?: Record<string, unknown>\n }\n /** 工作区文件发生变化(写文件、重命名等)。 */\n workspaceChanged: { filePath?: string }\n /** 智能体产出了文件成果(artifact:created / artifact:updated)。 */\n artifact: {\n filePath: string\n contentType: string\n title: string\n content: string\n oldString?: string\n newString?: string\n kind: \"created\" | \"updated\"\n }\n /** 工具返回值带 _meta.ui 的可视化预览(resource HTML / URI)。 */\n toolPreview: {\n toolCallId: string\n type: \"resource-html\" | \"resource-uri\"\n content: string\n title: string\n }\n /** 任务清单(TaskCreate 等)更新。 */\n taskListUpdated: { tasks: unknown[] }\n /** 沙盒后台命令状态更新。 */\n backgroundTask: {\n id: string\n command: string\n description?: string\n status: \"running\" | \"done\" | \"failed\"\n exitCode?: number | null\n elapsedSeconds: number\n output?: string\n }\n /** 会话被回溯到某个检查点。 */\n rewind: { checkpointId: string }\n /** 会话属性(名称、状态、绑定技能等)被服务端更新。 */\n sessionUpdated: {\n intent?: string\n status?: SessionStatus\n model?: string | null\n boundSkillId?: string | null\n replayState?: Record<string, unknown> | null\n }\n /** 回放输入不匹配,需要决定保持回放还是转自主模式。 */\n replayMismatch: {\n actualMessage?: string\n expectedMessage?: string\n respond: (decision: \"keep_replay\" | \"continue_replay\") => void\n }\n /** 沙盒内存超限自动重启。 */\n sandboxOom: { toolCallId: string }\n /** session.attach() 被调用,渲染层(ChatView/useChat)应把它显示为输入框附件。 */\n attachRequested: { label: string; content: string }\n /** session.insertText() 被调用,渲染层应把文字追加到输入框。 */\n insertTextRequested: { text: string }\n}\n\nexport type AgentSessionEventName = keyof AgentSessionEvents\n\ntype Handler<E> = (event: E) => void\n\nexport class Emitter<Events> {\n private handlers = new Map<keyof Events, Set<Handler<never>>>()\n\n on<K extends keyof Events>(name: K, handler: Handler<Events[K]>): () => void {\n let set = this.handlers.get(name)\n if (!set) {\n set = new Set()\n this.handlers.set(name, set)\n }\n set.add(handler as Handler<never>)\n return () => this.off(name, handler)\n }\n\n off<K extends keyof Events>(name: K, handler: Handler<Events[K]>): void {\n this.handlers.get(name)?.delete(handler as Handler<never>)\n }\n\n emit<K extends keyof Events>(name: K, event: Events[K]): void {\n const set = this.handlers.get(name)\n if (!set) return\n for (const handler of [...set]) {\n try {\n ;(handler as Handler<Events[K]>)(event)\n } catch (error) {\n // handler 异常只告警,不中断会话流\n console.warn(`[agent-client] \"${String(name)}\" 事件处理器抛出异常:`, error)\n }\n }\n }\n\n /**\n * 只把事件交给最先注册的处理器。用于必须由单一交互入口作答的事件,\n * 避免多个 UI 同时弹窗并提交相互冲突的决定。\n */\n emitFirst<K extends keyof Events>(name: K, event: Events[K]): boolean {\n const handler = this.handlers.get(name)?.values().next().value\n if (!handler) return false\n try {\n ;(handler as Handler<Events[K]>)(event)\n } catch (error) {\n console.warn(`[agent-client] \"${String(name)}\" 事件处理器抛出异常:`, error)\n return false\n }\n return true\n }\n\n listenerCount(name: keyof Events): number {\n return this.handlers.get(name)?.size ?? 0\n }\n\n clear(): void {\n this.handlers.clear()\n }\n}\n","import type {\n ChatMessage,\n FileContentPart,\n ImageUrlContentPart,\n MessageContent,\n MessageContentPart,\n} from \"./message\"\n\nconst SYSTEM_REMINDER_PATTERN = /^<system-reminder>\\s*[\\s\\S]*?\\s*<\\/system-reminder>$/i\nconst LEGACY_FORK_CONTEXT_MARKERS = [\n \"父智能体在派生你之前已经完成了一些操作。\",\n \"可通过 `read_file` 读取。\",\n \"# 你的任务\",\n]\n\nexport function normalizeMessageContent(content: unknown): MessageContent {\n if (typeof content === \"string\") return content\n if (Array.isArray(content)) return content as MessageContentPart[]\n return String(content ?? \"\")\n}\n\nexport function getTextContent(content: MessageContent): string {\n if (typeof content === \"string\") return content\n return content\n .filter((part) => part.type === \"text\")\n .map((part) => part.text)\n .join(\"\")\n}\n\nexport function isSystemReminderText(text: string): boolean {\n return SYSTEM_REMINDER_PATTERN.test(text.trim())\n}\n\nexport function isLegacyForkContextText(text: string): boolean {\n const normalized = text.trim()\n return LEGACY_FORK_CONTEXT_MARKERS.every((marker) => normalized.includes(marker))\n}\n\nexport function isHiddenInternalMessage(message: Pick<ChatMessage, \"role\" | \"content\">): boolean {\n if (message.role !== \"user\") return false\n const text = getTextContent(normalizeMessageContent(message.content))\n return isSystemReminderText(text) || isLegacyForkContextText(text)\n}\n\nexport function buildMessageContent(\n text: string,\n attachments: Array<{\n kind: \"file\"\n name: string\n uploadedPath?: string\n textContent?: string | null\n mimeType?: string\n }>,\n): MessageContent {\n if (attachments.length === 0) return text\n const textSegments: string[] = []\n\n if (text.trim()) {\n textSegments.push(text)\n }\n\n for (const attachment of attachments) {\n let fileText: string\n if (attachment.uploadedPath) {\n const displayName = attachment.uploadedPath.split(\"/\").pop() || attachment.name\n fileText = `[附件: ${displayName}] 已上传到工作区路径: ${attachment.uploadedPath}`\n } else if (attachment.textContent) {\n const MAX_TEXT_CHARS = 100_000\n const content =\n attachment.textContent.length > MAX_TEXT_CHARS\n ? `${attachment.textContent.slice(0, MAX_TEXT_CHARS)}\\n\\n[内容已截断,原始共 ${attachment.textContent.length} 字符]`\n : attachment.textContent\n fileText = `[附件: ${attachment.name}]\\n${content}`\n } else {\n fileText = `[附件: ${attachment.name}]`\n }\n textSegments.push(fileText)\n }\n\n return textSegments.join(\"\\n\\n\")\n}\n\nexport function contentPreview(content: MessageContent, maxLen = 80): string {\n const text = getTextContent(content).trim()\n return text.length > maxLen ? `${text.slice(0, maxLen)}…` : text\n}\n\n/**\n * Transform a skill mention into a natural language skill invocation.\n * Strips the `<skill>name</skill>` tag from the raw input and prepends the instruction.\n */\nexport function transformSlashCommand(skillName: string, rawInput: string): string {\n const prompt = rawInput.replace(`<skill>${skillName}</skill>`, \"\").trim()\n return prompt\n ? `请使用 ${skillName} skill 完成任务\\n${prompt}`\n : `请使用 ${skillName} skill 完成任务`\n}\n\nconst ATTACHMENT_TAG_RE = /\\[附件:\\s*([^\\]]+)\\](?:[ \\t]*已上传到工作区路径:[ \\t]*([^\\r\\n]+))?/g\n// 来自 addContext 的 context 在发送时序列化为独立 text part:`[上下文: LABEL]\\nCONTENT`\n// 整块 part 匹配而非行内替换,避免破坏正文中可能出现的\"[上下文:\"字样\nconst CONTEXT_PART_RE = /^\\[上下文:\\s*([^\\]]+)\\]\\n([\\s\\S]*)$/\n\nexport interface ParsedTextAttachment {\n name: string\n uploadedPath?: string\n}\n\nexport interface ParsedTextContext {\n label: string\n content: string\n}\n\n/**\n * Extract `[附件: name]` and `[上下文: label]` tags from text parts and return\n * the cleaned text plus the collected attachment / context metadata. 每个 text\n * part 独立匹配,以避免跨 part 拼接打乱正则。\n */\nexport function extractTextAttachments(content: MessageContent): {\n cleanText: string\n attachments: ParsedTextAttachment[]\n contexts: ParsedTextContext[]\n} {\n if (typeof content === \"string\") {\n const attachments: ParsedTextAttachment[] = []\n const contexts: ParsedTextContext[] = []\n const ctxMatch = CONTEXT_PART_RE.exec(content)\n let working = content\n if (ctxMatch) {\n contexts.push({ label: ctxMatch[1].trim(), content: ctxMatch[2].trim() })\n working = \"\"\n }\n for (const match of working.matchAll(ATTACHMENT_TAG_RE)) {\n attachments.push({\n name: match[1].trim(),\n uploadedPath: match[2]?.trim() || undefined,\n })\n }\n return {\n cleanText: working.replace(ATTACHMENT_TAG_RE, \"\"),\n attachments,\n contexts,\n }\n }\n\n const attachments: ParsedTextAttachment[] = []\n const contexts: ParsedTextContext[] = []\n const cleanParts: string[] = []\n\n for (const part of content) {\n if (part.type !== \"text\") continue\n\n const ctxMatch = CONTEXT_PART_RE.exec(part.text)\n if (ctxMatch) {\n contexts.push({ label: ctxMatch[1].trim(), content: ctxMatch[2].trim() })\n continue\n }\n\n let hasAttachment = false\n for (const match of part.text.matchAll(ATTACHMENT_TAG_RE)) {\n attachments.push({\n name: match[1].trim(),\n uploadedPath: match[2]?.trim() || undefined,\n })\n hasAttachment = true\n }\n if (hasAttachment) {\n const remaining = part.text.replace(ATTACHMENT_TAG_RE, \"\")\n if (remaining.trim()) cleanParts.push(remaining)\n } else {\n cleanParts.push(part.text)\n }\n }\n\n return { cleanText: cleanParts.join(\"\\n\"), attachments, contexts }\n}\n\nexport function getImageParts(content: MessageContent): ImageUrlContentPart[] {\n if (typeof content === \"string\") return []\n return content.filter((part): part is ImageUrlContentPart => part.type === \"image_url\")\n}\n\nexport function getFileParts(content: MessageContent): FileContentPart[] {\n if (typeof content === \"string\") return []\n return content.filter((part): part is FileContentPart => part.type === \"file\")\n}\n\ninterface MessageGroup {\n root: ChatMessage | null\n childLoops: { loopName: string; messages: ChatMessage[] }[]\n}\n\nexport function groupMessagesByLoop(messages: ChatMessage[]): MessageGroup[] {\n const groups: MessageGroup[] = []\n let currentGroup: MessageGroup | null = null\n\n for (const msg of messages) {\n const loop = msg.loop_name ?? \"root\"\n\n if (loop === \"root\") {\n currentGroup = { root: msg, childLoops: [] }\n groups.push(currentGroup)\n } else {\n if (!currentGroup) {\n currentGroup = { root: null, childLoops: [] }\n groups.push(currentGroup)\n }\n const existingLoop = currentGroup.childLoops.find((l) => l.loopName === loop)\n if (existingLoop) {\n existingLoop.messages.push(msg)\n } else {\n currentGroup.childLoops.push({ loopName: loop, messages: [msg] })\n }\n }\n }\n\n return groups\n}\n","import type { ChatMessage, CompactionInfo, MessageContent, ToolCallInfo } from \"../schemas/message\"\nimport { normalizeMessageContent } from \"../schemas/message-utils\"\nimport type { ContentBlock, PatchEnvelope, TurnProjection } from \"../schemas/projection\"\nimport type { SessionStatus } from \"../schemas/session\"\n\n/** 一次 AskUserQuestion 的用户作答(选项选择 + 自定义输入)。 */\nexport interface AskUserAnswerData {\n selections: Record<number, number[]>\n custom: Record<number, string>\n}\n\nexport interface AgentLoopInfo {\n toolCallId: string\n description: string\n status: \"running\" | \"done\" | \"error\" | \"cancelled\" | \"awaiting_answer\"\n}\n\nexport interface ActiveCompactionState extends CompactionInfo {\n turn_id: string\n status: \"streaming\" | \"completed\" | \"paused\" | \"failed\" | \"interrupted\"\n}\n\nexport type ConnectionStatus = \"connecting\" | \"connected\" | \"reconnecting\" | \"disconnected\"\n\n/**\n * 一个会话的完整快照。引用不可变:任何变更都会产生新对象,\n * 满足 React `useSyncExternalStore` / Vue `shallowRef` 的订阅契约。\n */\nexport interface SessionState {\n sessionId: string\n /** 服务端投影的原始 turn 列表(按 sequence 有序)。 */\n turns: TurnProjection[]\n /** 由 turns 物化出的聊天消息列表,UI 直接渲染。 */\n messages: ChatMessage[]\n /** 智能体是否正在流式回复。 */\n isStreaming: boolean\n /** 会话状态(running / completed / failed / waiting_for_input / interrupted …)。 */\n status: SessionStatus | null\n /** 当前模式(planning / executing),来自 mode_change 事件。 */\n mode: \"planning\" | \"executing\" | null\n /** Socket.IO 连接状态(同一 client 下所有会话共享)。 */\n connection: ConnectionStatus\n /** 最近一次运行错误消息(system:error 等)。 */\n errorMessage: string | null\n askAnswers: Record<string, AskUserAnswerData>\n agentLoops: Record<string, AgentLoopInfo>\n activeCompaction: ActiveCompactionState | null\n}\n\nexport function createInitialSessionState(sessionId: string): SessionState {\n return {\n sessionId,\n turns: [],\n messages: [],\n isStreaming: false,\n status: null,\n mode: null,\n connection: \"disconnected\",\n errorMessage: null,\n askAnswers: {},\n agentLoops: {},\n activeCompaction: null,\n }\n}\n\nfunction parseAgentDescription(argumentsJson: string): string {\n try {\n return JSON.parse(argumentsJson)?.description ?? \"子智能体\"\n } catch {\n return \"子智能体\"\n }\n}\n\n/** 与 react 端 display-utils.formatToolName 保持一致:去掉 provider 前缀(如 \"fork:Agent\" → \"Agent\")。 */\nfunction normalizedToolName(name: string): string {\n const separatorIndex = name.lastIndexOf(\":\")\n return separatorIndex >= 0 ? name.slice(separatorIndex + 1) : name\n}\n\nfunction inferLoopStatusFromMessages(messages: ChatMessage[]): AgentLoopInfo[\"status\"] {\n const toolCalls = messages.flatMap((message) => message.tool_calls ?? [])\n if (messages.some((message) => message.status === \"streaming\")) return \"running\"\n if (toolCalls.some((toolCall) => toolCall.status === \"awaiting_answer\")) return \"awaiting_answer\"\n if (toolCalls.some((toolCall) => toolCall.status === \"error\")) return \"error\"\n if (toolCalls.some((toolCall) => toolCall.status === \"cancelled\")) return \"cancelled\"\n if (toolCalls.some((toolCall) => toolCall.status === \"pending\")) return \"running\"\n return \"done\"\n}\n\nfunction inferLoopStatusFromTurns(\n turns: TurnProjection[],\n messages: ChatMessage[],\n): AgentLoopInfo[\"status\"] {\n const latestAgentNotification = [...turns]\n .reverse()\n .flatMap((turn) => turn.blocks)\n .find((block) => {\n if (block.type !== \"system_notification\" || !isRecord(block.content)) return false\n return (\n block.content.notification_type === \"agent:start\" ||\n block.content.notification_type === \"agent:end\"\n )\n })\n if (\n latestAgentNotification?.type === \"system_notification\" &&\n isRecord(latestAgentNotification.content)\n ) {\n const notificationType = latestAgentNotification.content.notification_type\n const status = latestAgentNotification.content.status\n if (notificationType === \"agent:start\" || status === \"running\") return \"running\"\n if (status === \"error\") return \"error\"\n if (status === \"cancelled\") return \"cancelled\"\n }\n return inferLoopStatusFromMessages(messages)\n}\n\nfunction isRecord(value: unknown): value is Record<string, unknown> {\n return typeof value === \"object\" && value !== null && !Array.isArray(value)\n}\n\nfunction parentForkToolCallIdFromTurn(turn: TurnProjection): string | null {\n if (\n typeof turn.parent_fork_tool_call_id === \"string\" &&\n turn.parent_fork_tool_call_id.length > 0\n ) {\n return turn.parent_fork_tool_call_id\n }\n for (const block of turn.blocks) {\n if (block.type !== \"system_notification\" || !isRecord(block.content)) continue\n const metadata = block.content.metadata\n if (!isRecord(metadata)) continue\n const parentId = metadata.parent_fork_tool_call_id\n if (typeof parentId === \"string\" && parentId.length > 0) return parentId\n }\n return null\n}\n\nfunction buildMessageContent(turn: TurnProjection): MessageContent {\n const textBlocks = turn.blocks.filter((block) => block.type === \"text\")\n if (textBlocks.length === 0) return \"\"\n if (textBlocks.length === 1) return normalizeMessageContent(textBlocks[0].content)\n return textBlocks\n .map((block) => {\n if (typeof block.content === \"string\") return block.content\n return JSON.stringify(block.content)\n })\n .join(\"\")\n}\n\nfunction askUserAnswerContent(turn: TurnProjection): string | null {\n const answerBlock = turn.blocks.find((block) => block.type === \"ask_user_answer\")\n if (!answerBlock || !isRecord(answerBlock.content)) return null\n const answer = answerBlock.content.answer\n return typeof answer === \"string\" && answer.trim().length > 0 ? answer : null\n}\n\nfunction buildReasoning(turn: TurnProjection): string | undefined {\n const thinking = turn.blocks\n .filter((block) => block.type === \"thinking\")\n .map((block) => (typeof block.content === \"string\" ? block.content : JSON.stringify(block.content)))\n .filter(Boolean)\n if (thinking.length === 0) return undefined\n return thinking.join(\"\\n\\n\")\n}\n\nfunction isModeChangeContent(value: unknown): value is { from: string; to: string } {\n return (\n typeof value === \"object\" &&\n value !== null &&\n typeof (value as { from?: unknown }).from === \"string\" &&\n typeof (value as { to?: unknown }).to === \"string\"\n )\n}\n\nexport function extractModeFromBlocks(blocks: ContentBlock[]): \"planning\" | \"executing\" | null {\n const modeBlock = blocks.find((block) => block.type === \"mode_change\")\n if (modeBlock && isModeChangeContent(modeBlock.content)) {\n return modeBlock.content.to === \"planning\" || modeBlock.content.to === \"executing\"\n ? modeBlock.content.to\n : null\n }\n return null\n}\n\nfunction projectionToMessage(turn: TurnProjection): ChatMessage | null {\n if (turn.kind === \"compaction\" && turn.compaction_id) {\n return {\n role: \"assistant\",\n content: turn.summary_preview ?? \"\",\n kind: \"compaction\",\n loop_name: turn.loop_id,\n entry_id: turn.turn_id,\n status: turn.status,\n compaction: {\n compaction_id: turn.compaction_id,\n summary_preview: turn.summary_preview,\n summary_full: turn.summary_full,\n archived_count: turn.archived_count,\n archived_files: turn.archived_files,\n archived_tool_calls: turn.archived_tool_calls,\n tokens_before: turn.tokens_before,\n tokens_after: turn.tokens_after,\n saved_ratio: turn.saved_ratio,\n trigger: turn.trigger,\n failure_reason: turn.failure_reason,\n fallback_applied: turn.fallback_applied,\n },\n }\n }\n\n const planningBlock = turn.blocks.find(\n (block) => block.type === \"mode_change\" || block.type === \"plan_status\",\n )\n if (planningBlock) {\n if (planningBlock.type === \"plan_status\") {\n return {\n role: \"tool\",\n content:\n typeof planningBlock.content === \"string\"\n ? planningBlock.content\n : JSON.stringify(planningBlock.content ?? {}, null, 2),\n kind: \"plan_status\",\n loop_name: turn.loop_id,\n entry_id: turn.turn_id,\n status: turn.status,\n }\n }\n return {\n role: \"assistant\",\n content:\n typeof planningBlock.content === \"string\"\n ? planningBlock.content\n : JSON.stringify(planningBlock.content ?? {}),\n kind: planningBlock.type,\n loop_name: turn.loop_id,\n entry_id: turn.turn_id,\n status: turn.status,\n }\n }\n\n const askAnswer = askUserAnswerContent(turn)\n if (askAnswer !== null) {\n return {\n role: \"user\",\n content: askAnswer,\n blocks: turn.blocks,\n loop_name: turn.loop_id,\n entry_id: turn.turn_id,\n status: turn.status,\n ...(typeof turn.duration_ms === \"number\" ? { duration_ms: turn.duration_ms } : {}),\n ...(turn.started_at ? { timestamp: turn.started_at } : {}),\n }\n }\n\n const content = buildMessageContent(turn)\n const reasoning = buildReasoning(turn)\n const toolCalls: ToolCallInfo[] | undefined =\n turn.tool_calls.length > 0\n ? turn.tool_calls.map((toolCall) => ({\n id: toolCall.id,\n name: toolCall.tool_name,\n display_name: toolCall.display_name,\n arguments: toolCall.arguments,\n result: toolCall.result ?? undefined,\n pending_question_ref: toolCall.pending_question_ref ?? undefined,\n status:\n toolCall.status === \"pending\" ||\n toolCall.status === \"awaiting_answer\" ||\n toolCall.status === \"done\" ||\n toolCall.status === \"error\" ||\n toolCall.status === \"cancelled\"\n ? toolCall.status\n : \"pending\",\n ...(typeof toolCall.duration_ms === \"number\" ? { duration_ms: toolCall.duration_ms } : {}),\n }))\n : undefined\n\n if (turn.role === \"system\" && !content && !toolCalls?.length) {\n return null\n }\n\n return {\n role: turn.role === \"system\" ? \"assistant\" : turn.role,\n content,\n blocks: turn.blocks,\n ...(reasoning ? { reasoning } : {}),\n ...(toolCalls ? { tool_calls: toolCalls } : {}),\n loop_name: turn.loop_id,\n entry_id: turn.turn_id,\n status: turn.status,\n ...(typeof turn.duration_ms === \"number\" ? { duration_ms: turn.duration_ms } : {}),\n ...(turn.started_at ? { timestamp: turn.started_at } : {}),\n ...(turn.memory_refs?.length ? { memory_refs: turn.memory_refs } : {}),\n }\n}\n\nconst messageProjectionCache = new WeakMap<TurnProjection, ChatMessage | null>()\n\nfunction cachedProjectionToMessage(turn: TurnProjection): ChatMessage | null {\n if (messageProjectionCache.has(turn)) {\n return messageProjectionCache.get(turn) ?? null\n }\n const message = projectionToMessage(turn)\n messageProjectionCache.set(turn, message)\n return message\n}\n\nfunction rebuildAgentLoops(\n turns: TurnProjection[],\n messages: ChatMessage[],\n): Record<string, AgentLoopInfo> {\n const childLoopNames = [\n ...new Set(turns.map((turn) => turn.loop_id).filter((name) => name !== \"root\")),\n ]\n if (childLoopNames.length === 0) return {}\n\n const agentToolCalls = messages\n .filter((message) => message.role === \"assistant\" && (message.loop_name ?? \"root\") === \"root\")\n .flatMap((message) => message.tool_calls ?? [])\n .filter((toolCall) => normalizedToolName(toolCall.name) === \"Agent\")\n\n const loops: Record<string, AgentLoopInfo> = {}\n const agentToolCallsById = new Map(agentToolCalls.map((toolCall) => [toolCall.id, toolCall]))\n const explicitParentToolCallIds = new Set(\n turns.map(parentForkToolCallIdFromTurn).filter((id): id is string => id !== null),\n )\n const usedToolCallIds = new Set<string>()\n for (const loopName of childLoopNames) {\n const loopMessages = messages.filter((message) => (message.loop_name ?? \"root\") === loopName)\n const loopTurns = turns.filter((turn) => turn.loop_id === loopName)\n const parentToolCallId = loopTurns.map(parentForkToolCallIdFromTurn).find(Boolean)\n const explicitToolCall =\n parentToolCallId && !usedToolCallIds.has(parentToolCallId)\n ? (agentToolCallsById.get(parentToolCallId) ?? null)\n : null\n const fallbackToolCall =\n explicitToolCall === null\n ? agentToolCalls.find(\n (toolCall) =>\n !usedToolCallIds.has(toolCall.id) && !explicitParentToolCallIds.has(toolCall.id),\n )\n : null\n const toolCall = explicitToolCall ?? fallbackToolCall\n if (!toolCall) continue\n usedToolCallIds.add(toolCall.id)\n loops[loopName] = {\n toolCallId: toolCall.id,\n description: parseAgentDescription(toolCall.arguments),\n status: inferLoopStatusFromTurns(loopTurns, loopMessages),\n }\n }\n return loops\n}\n\nfunction materialize(turns: TurnProjection[]) {\n const projectedMessages = turns\n .map(cachedProjectionToMessage)\n .filter((message): message is ChatMessage => message !== null)\n const messages = projectedMessages.filter((message, index, allMessages) => {\n if (!message.blocks?.some((block) => block.type === \"ask_user_answer\")) return true\n const next = allMessages[index + 1]\n return !(next?.role === \"user\" && next.content === message.content)\n })\n const activeCompaction = [...turns]\n .reverse()\n .find(\n (turn): turn is TurnProjection =>\n turn.kind === \"compaction\" &&\n turn.status === \"streaming\" &&\n typeof turn.compaction_id === \"string\",\n )\n return {\n messages,\n agentLoops: rebuildAgentLoops(turns, projectedMessages),\n activeCompaction: activeCompaction\n ? {\n turn_id: activeCompaction.turn_id,\n status: activeCompaction.status,\n compaction_id: activeCompaction.compaction_id!,\n summary_preview: activeCompaction.summary_preview,\n summary_full: activeCompaction.summary_full,\n archived_count: activeCompaction.archived_count,\n archived_files: activeCompaction.archived_files,\n archived_tool_calls: activeCompaction.archived_tool_calls,\n tokens_before: activeCompaction.tokens_before,\n tokens_after: activeCompaction.tokens_after,\n saved_ratio: activeCompaction.saved_ratio,\n trigger: activeCompaction.trigger,\n failure_reason: activeCompaction.failure_reason,\n fallback_applied: activeCompaction.fallback_applied,\n }\n : null,\n }\n}\n\nconst ERROR_ANCHOR_PREFIX = \"error-anchor:\"\n\nfunction orderTurns(turns: TurnProjection[]) {\n for (let index = 1; index < turns.length; index += 1) {\n if (turns[index - 1].sequence > turns[index].sequence) {\n return [...turns].sort((left, right) => left.sequence - right.sequence)\n }\n }\n return turns\n}\n\nfunction areAgentLoopsEqual(\n left: Record<string, AgentLoopInfo> | undefined,\n right: Record<string, AgentLoopInfo>,\n) {\n if (!left) return Object.keys(right).length === 0\n const leftEntries = Object.entries(left)\n const rightKeys = Object.keys(right)\n if (leftEntries.length !== rightKeys.length) return false\n return leftEntries.every(([key, value]) => {\n const next = right[key]\n return (\n next !== undefined &&\n value.toolCallId === next.toolCallId &&\n value.description === next.description &&\n value.status === next.status\n )\n })\n}\n\n/**\n * 用一份新的 turn 列表重建会话状态。\n * addErrorMessage 注入的 role===\"error\" 消息不在 turns 里,默认会被物化过程抹掉;\n * 这里沿用锚点策略:只保留锚定在\"当前最后一个 turn\"上的错误气泡,\n * turn 推进(新消息 / rewind / 重连)时旧错误自动消失。\n */\nexport function withTurns(state: SessionState, turns: TurnProjection[]): SessionState {\n const orderedTurns = orderTurns(turns)\n const { messages, agentLoops, activeCompaction } = materialize(orderedTurns)\n const isWaitingForInput = orderedTurns.some((turn) =>\n turn.tool_calls.some((toolCall) => toolCall.status === \"awaiting_answer\"),\n )\n const stableAgentLoops = areAgentLoopsEqual(state.agentLoops, agentLoops)\n ? state.agentLoops\n : agentLoops\n const lastTurnId = orderedTurns[orderedTurns.length - 1]?.turn_id ?? null\n const preservedErrors = lastTurnId\n ? state.messages.filter(\n (m) =>\n m.role === \"error\" &&\n typeof m.entry_id === \"string\" &&\n m.entry_id.startsWith(`${ERROR_ANCHOR_PREFIX}${lastTurnId}:`),\n )\n : []\n const mergedMessages = preservedErrors.length > 0 ? [...messages, ...preservedErrors] : messages\n const latestMode = [...orderedTurns]\n .reverse()\n .map((turn) => extractModeFromBlocks(turn.blocks))\n .find((mode): mode is \"planning\" | \"executing\" => mode !== null)\n return {\n ...state,\n turns: orderedTurns,\n messages: mergedMessages,\n agentLoops: stableAgentLoops,\n activeCompaction,\n mode: latestMode ?? state.mode,\n // 历史恢复时 chat:end(paused) 可能已不在 socket replay 缓存中;\n // awaiting_answer 是投影里的持久权威状态,必须据此恢复问答交互。\n status: isWaitingForInput ? \"waiting_for_input\" : state.status,\n }\n}\n\nlet localTurnCounter = 0\n\nexport function addUserMessage(state: SessionState, content: MessageContent): SessionState {\n localTurnCounter += 1\n const turnId = `local-user-${Date.now()}-${localTurnCounter}`\n const optimisticTurn: TurnProjection = {\n id: turnId,\n sequence: Math.max(0, ...state.turns.map((turn) => turn.sequence)) + 1,\n turn_id: turnId,\n loop_id: \"root\",\n role: \"user\",\n status: \"streaming\",\n blocks: [{ type: \"text\", content }],\n tool_calls: [],\n model: null,\n usage: null,\n duration_ms: 0,\n }\n return withTurns(state, [...state.turns, optimisticTurn])\n}\n\nexport function upsertTurn(state: SessionState, turn: TurnProjection): SessionState {\n let existing = [...state.turns]\n if (turn.role === \"user\" && !turn.turn_id.startsWith(\"local-user-\")) {\n existing = existing.filter((t) => !t.turn_id.startsWith(\"local-user-\"))\n }\n const index = existing.findIndex((item) => item.turn_id === turn.turn_id)\n if (index >= 0) {\n existing[index] = turn\n } else {\n existing.push(turn)\n }\n return withTurns(state, existing)\n}\n\nexport function applyTurnPatch(state: SessionState, patch: PatchEnvelope): SessionState {\n const turn = patch.data.turn\n if (!turn) return state\n\n const existing = [...state.turns]\n const index = existing.findIndex((item) => item.turn_id === turn.turn_id)\n const lastSequence = index >= 0 ? existing[index].sequence : null\n if (lastSequence !== null && patch.sequence <= lastSequence) {\n return state\n }\n\n const nextTurn = { ...turn, sequence: patch.sequence }\n if (index >= 0) {\n existing[index] = nextTurn\n } else {\n existing.push(nextTurn)\n }\n return withTurns(state, existing)\n}\n\nexport function addErrorMessage(state: SessionState, content: string): SessionState {\n const anchorTurnId = state.turns[state.turns.length - 1]?.turn_id ?? null\n const entry_id = anchorTurnId\n ? `${ERROR_ANCHOR_PREFIX}${anchorTurnId}:${Date.now()}`\n : undefined\n return {\n ...state,\n messages: [...state.messages, { role: \"error\", content, loop_name: \"root\", entry_id }],\n }\n}\n\nexport function markInterrupted(state: SessionState): SessionState {\n return markStreamingTurns(state, \"interrupted\", \"cancelled\")\n}\n\nexport function markFailed(state: SessionState): SessionState {\n return markStreamingTurns(state, \"failed\", \"error\")\n}\n\nfunction markStreamingTurns(\n state: SessionState,\n turnStatus: \"interrupted\" | \"failed\",\n toolCallStatus: \"cancelled\" | \"error\",\n): SessionState {\n const turns = state.turns.map((turn) => {\n if (turn.status !== \"streaming\") return turn\n return {\n ...turn,\n status: turnStatus,\n tool_calls: turn.tool_calls.map((toolCall) =>\n toolCall.status === \"pending\" || toolCall.status === \"awaiting_answer\"\n ? { ...toolCall, status: toolCallStatus }\n : toolCall,\n ),\n }\n })\n return withTurns(state, turns)\n}\n","import { ClientProjectionBuilder, type RawEvent } from \"../shared/projection\"\nimport type { MessageContent, ToolBridgeContent, ToolCallInfo } from \"../schemas/message\"\nimport type { ContentBlock, PatchEnvelope, TurnProjection } from \"../schemas/projection\"\nimport type { SessionStatus } from \"../schemas/session\"\nimport { CommandRegistry, type CommandHandler } from \"../commands/registry\"\nimport { Emitter, type AgentSessionEvents } from \"./events\"\nimport type { FileEntry } from \"../resources/sessions\"\nimport {\n addErrorMessage,\n addUserMessage,\n applyTurnPatch,\n createInitialSessionState,\n extractModeFromBlocks,\n markFailed,\n markInterrupted,\n upsertTurn,\n withTurns,\n type AskUserAnswerData,\n type ConnectionStatus,\n type SessionState,\n} from \"./state\"\n\n/** SessionHub 注入给 AgentSession 的运行时依赖(socket 收发 + REST 补数)。 */\nexport interface SessionRuntime {\n emitEvent(event: string, data: unknown): void\n emitWithAck(\n event: string,\n data: unknown,\n timeoutMs: number,\n ): Promise<Record<string, unknown> | undefined>\n ensureConnected(): void\n fetchTurns(sessionId: string): Promise<TurnProjection[]>\n listDir(sessionId: string, dirPath: string): Promise<FileEntry[]>\n countFiles(sessionId: string, dirPath?: string): Promise<number>\n downloadFile(sessionId: string, filePath: string, downloadName?: string): Promise<void>\n onDispose(session: AgentSession): void\n}\n\nexport interface SendOptions {\n /** planning / executing 模式。 */\n mode?: string\n /** AskUserQuestion 的作答(tool_call_id + 选项)。 */\n askUserAnswer?: Record<string, unknown>\n /** 本次运行的模型覆盖。 */\n model?: string\n /** 本次运行是否强制开/关思考。 */\n thinkingOverride?: boolean\n whatif?: {\n from_step: number\n quotes: Array<Record<string, unknown>>\n deprecate_entry_ids: string[]\n }\n replayDecision?: \"keep_replay\" | \"continue_replay\"\n}\n\nconst OOM_MESSAGE = \"沙盒内存使用超出限制,已自动重启。如果经常触发,可以联系管理员调整额度。\"\n\n// ASCII 关键词用 \\b;中文\"退出码\"不能依赖 \\b(CJK 在 JS 正则里不算 word),\n// 137 两端用 (?<!\\d)(?!\\d) 锚定,避免 1370 之类误判。\nconst OOM_KEYWORDS_RE = /(?:\\b(?:exit_code|ExitedWith|exited with)|退出码)\\D*(?<!\\d)137(?!\\d)/i\n\nfunction isRecord(value: unknown): value is Record<string, unknown> {\n return typeof value === \"object\" && value !== null && !Array.isArray(value)\n}\n\nfunction isOomText(value: unknown): boolean {\n return typeof value === \"string\" && OOM_KEYWORDS_RE.test(value)\n}\n\nfunction parseJsonRecord(value: unknown): Record<string, unknown> | null {\n if (isRecord(value)) return value\n if (typeof value !== \"string\") return null\n try {\n const parsed = JSON.parse(value)\n return isRecord(parsed) ? parsed : null\n } catch {\n return null\n }\n}\n\nfunction isOomResult(value: unknown): boolean {\n if (Array.isArray(value)) {\n return value.some((part) => isOomResult(part))\n }\n if (typeof value === \"object\" && value !== null) {\n const record = value as Record<string, unknown>\n if (record.exit_code === 137) return true\n if (typeof record.text === \"string\" && isOomText(record.text)) return true\n if (typeof record.content === \"string\" && isOomText(record.content)) return true\n return false\n }\n if (typeof value === \"string\") {\n const parsed = parseJsonRecord(value)\n if (parsed?.exit_code === 137) return true\n return isOomText(value)\n }\n return false\n}\n\nfunction isToolBridgeContent(value: unknown): value is ToolBridgeContent {\n return (\n typeof value === \"object\" &&\n value !== null &&\n !Array.isArray(value) &&\n typeof (value as { action?: unknown }).action === \"string\"\n )\n}\n\nexport function sessionStatusFromChatEnd(status: string | undefined): SessionStatus {\n if (status === \"paused\") return \"waiting_for_input\"\n if (status === \"interrupted\") return \"interrupted\"\n if (status === \"failed\") return \"failed\"\n return \"completed\"\n}\n\nfunction extractTerminalChatEndStatus(events: RawEvent[]): string | null {\n for (let i = events.length - 1; i >= 0; i--) {\n const event = events[i]\n if (event?.type !== \"chat:end\") continue\n const status = event.payload?.status\n return typeof status === \"string\" ? status : \"completed\"\n }\n return null\n}\n\ninterface UiMetaLike {\n target?: string\n title?: string\n resourceHTML?: string\n resourceUri?: string\n resourceURI?: string\n}\n\nfunction isUiMetaLike(value: unknown): value is UiMetaLike {\n return isRecord(value) && (\"resourceHTML\" in value || \"resourceUri\" in value || \"resourceURI\" in value)\n}\n\n/**\n * 一个会话的实时状态机:封装 Socket.IO 订阅、历史 + 流式合流、断线补数,\n * 对外只有三样东西——状态快照(getState/subscribe)、动作(send/stop/…)、\n * 语义事件(on/onCommand)。\n *\n * 状态完全归属实例:同一页面创建多个 AgentSession 互不干扰。\n */\nexport class AgentSession {\n readonly sessionId: string\n\n private state: SessionState\n private readonly listeners = new Set<() => void>()\n private readonly emitter = new Emitter<AgentSessionEvents>()\n private readonly commands = new CommandRegistry()\n private readonly runtime: SessionRuntime\n private readonly projectionBuilder = new ClientProjectionBuilder()\n\n private readonly pendingTurnPatches = new Map<string, PatchEnvelope>()\n private patchFlushHandle: number | ReturnType<typeof globalThis.setTimeout> | null = null\n private patchFlushCancel: (() => void) | null = null\n\n private joined = false\n private joinPending: Promise<void> | null = null\n private pendingReplayMessage: MessageContent | null = null\n private pendingReplayMode: string | undefined\n private recentChatEndAt = 0\n private disposed = false\n\n private readonly deliveredCommandKeys = new Set<string>()\n private readonly deliveredToolPreviews = new Map<string, string>()\n private readonly oomNotifiedKeys = new Set<string>()\n private readonly seenToolCallIds = new Set<string>()\n private readonly finishedToolCallIds = new Set<string>()\n private readonly emittedMessageTurnIds = new Set<string>()\n\n constructor(sessionId: string, runtime: SessionRuntime, connection: ConnectionStatus) {\n this.sessionId = sessionId\n this.runtime = runtime\n this.state = { ...createInitialSessionState(sessionId), connection }\n }\n\n /** 从一份静态 turn 快照构造只展示历史的会话(例如公开分享页)。 */\n static fromTurns(sessionId: string, turns: TurnProjection[]): AgentSession {\n const readonlyError = () => {\n throw new Error(\"静态会话只用于展示历史,不能执行会话操作\")\n }\n const session = new AgentSession(\n sessionId,\n {\n emitEvent: readonlyError,\n emitWithAck: async () => readonlyError(),\n ensureConnected: readonlyError,\n fetchTurns: async () => turns,\n listDir: async () => readonlyError(),\n countFiles: async () => readonlyError(),\n downloadFile: async () => readonlyError(),\n onDispose: () => undefined,\n },\n \"connected\",\n )\n session.state = {\n ...withTurns(session.state, turns),\n status: \"completed\",\n }\n return session\n }\n\n // ---------------------------------------------------------------- 状态订阅\n\n /** 返回当前会话快照。引用稳定:状态未变化时返回同一对象。 */\n getState(): SessionState {\n return this.state\n }\n\n /** 订阅状态变化。返回取消订阅函数。 */\n subscribe(listener: () => void): () => void {\n this.listeners.add(listener)\n return () => {\n this.listeners.delete(listener)\n }\n }\n\n private setState(next: SessionState): void {\n if (next === this.state) return\n this.state = next\n for (const listener of [...this.listeners]) {\n try {\n listener()\n } catch (error) {\n console.warn(\"[agent-client] 状态订阅回调抛出异常:\", error)\n }\n }\n }\n\n private update(fn: (state: SessionState) => SessionState): void {\n this.setState(fn(this.state))\n }\n\n // ---------------------------------------------------------------- 语义事件\n\n /** 监听语义事件(底层逃生舱,见 events.ts)。返回取消函数。 */\n on<K extends keyof AgentSessionEvents>(\n name: K,\n handler: (event: AgentSessionEvents[K]) => void,\n ): () => void {\n return this.emitter.on(name, handler)\n }\n\n off<K extends keyof AgentSessionEvents>(\n name: K,\n handler: (event: AgentSessionEvents[K]) => void,\n ): void {\n this.emitter.off(name, handler)\n }\n\n /**\n * 监听智能体下发给宿主页面的指令。\n *\n * action 是技能作者在工具返回值 `_meta.bridge` 里写的契约字符串(如\n * \"map.highlight\"),由你和技能作者约定;注册前到达的指令会被缓冲补投。\n */\n onCommand(action: string, handler: CommandHandler): () => void {\n return this.commands.onCommand(action, handler)\n }\n\n // ---------------------------------------------------------------- 动作\n\n /** 发送一条消息。字符串或多模态内容均可。 */\n async send(content: MessageContent, options: SendOptions = {}): Promise<void> {\n this.runtime.ensureConnected()\n if (this.state.isStreaming) {\n this.update((s) => addErrorMessage(s, \"当前回复尚未结束,请稍后再发送。\"))\n return\n }\n await this.ensureIdleBeforeSend()\n if (this.state.isStreaming) {\n this.update((s) => addErrorMessage(s, \"当前回复尚未结束,请稍后再发送。\"))\n return\n }\n const askUserAnswer = options.askUserAnswer\n if (!(askUserAnswer && typeof askUserAnswer.tool_call_id === \"string\")) {\n this.update((s) => addUserMessage(s, content))\n }\n this.update((s) => ({ ...s, isStreaming: true }))\n if (askUserAnswer && typeof askUserAnswer.tool_call_id === \"string\") {\n const { tool_call_id, ...rest } = askUserAnswer\n this.update((s) => ({\n ...s,\n askAnswers: { ...s.askAnswers, [tool_call_id as string]: rest as unknown as AskUserAnswerData },\n }))\n }\n if (!options.replayDecision) {\n this.pendingReplayMessage = content\n this.pendingReplayMode = options.mode\n }\n const payload = {\n session_id: this.sessionId,\n message: content,\n mode: options.mode,\n askuser_answer: askUserAnswer,\n model: options.model,\n thinking_override: options.thinkingOverride,\n whatif: options.whatif,\n replay_decision: options.replayDecision,\n }\n try {\n await this.ensureJoined()\n } catch (error) {\n this.update((s) =>\n addErrorMessage(\n { ...s, isStreaming: false, status: \"failed\" },\n error instanceof Error && error.message ? error.message : \"会话订阅失败,消息未发送\",\n ),\n )\n return\n }\n this.runtime.emitEvent(\"chat:send\", payload)\n }\n\n /** 智能体运行期间追加补充说明(不打断当前回复)。 */\n append(text: string): void {\n this.runtime.ensureConnected()\n this.runtime.emitEvent(\"chat:append\", { session_id: this.sessionId, message: text })\n this.update((s) => addUserMessage(s, text))\n }\n\n /** 停止当前回复。 */\n stop(): Promise<Record<string, unknown>> {\n return this.runtime\n .emitWithAck(\"chat:stop\", { session_id: this.sessionId }, 35_000)\n .then((response) => response ?? {})\n }\n\n /** 手动触发上下文压缩。 */\n compact(): Promise<Record<string, unknown>> {\n return this.runtime\n .emitWithAck(\"chat:compact\", { session_id: this.sessionId }, 30_000)\n .then((response) => response ?? {})\n }\n\n /**\n * 把一段业务数据作为附件放进聊天输入框(比如地图上选中的点位)。\n * 附件随下一条消息一起发给智能体。需要 ChatView / useChat 渲染层配合展示;\n * 无 UI 场景可直接用 send()。\n */\n attach(label: string, data: unknown): void {\n const content = typeof data === \"string\" ? data : JSON.stringify(data, null, 2)\n this.emitter.emit(\"attachRequested\", { label, content })\n }\n\n /** 往聊天输入框追加一段文字(不发送)。 */\n insertText(text: string): void {\n this.emitter.emit(\"insertTextRequested\", { text })\n }\n\n /** 列出工作区的一层目录。 */\n listDir(dirPath = \"\"): Promise<FileEntry[]> {\n return this.runtime.listDir(this.sessionId, dirPath)\n }\n\n /** 递归统计工作区文件数(不含目录)。 */\n countFiles(dirPath = \"\"): Promise<number> {\n return this.runtime.countFiles(this.sessionId, dirPath)\n }\n\n /** 在浏览器中下载一个工作区文件。 */\n downloadFile(filePath: string, downloadName?: string): Promise<void> {\n return this.runtime.downloadFile(this.sessionId, filePath, downloadName)\n }\n\n /** 释放订阅与监听器。之后该实例不再接收任何事件。 */\n dispose(): void {\n if (this.disposed) return\n this.disposed = true\n this.cancelPatchFlush()\n this.listeners.clear()\n this.emitter.clear()\n this.commands.clear()\n this.runtime.onDispose(this)\n }\n\n get isDisposed(): boolean {\n return this.disposed\n }\n\n // ------------------------------------------------------- Hub 回调(内部)\n\n /** @internal 连接状态变化(同 client 下所有会话共享一条连接)。 */\n _setConnection(connection: ConnectionStatus): void {\n if (this.state.connection === connection) return\n this.update((s) => ({ ...s, connection }))\n }\n\n /** @internal socket 重连后由 Hub 调用:重新加入房间并补数。 */\n async _rejoinAfterReconnect(): Promise<void> {\n const turnsBeforeRejoin = this.state.turns\n this.joined = false\n this.joinPending = null\n try {\n await this.ensureJoined()\n await this.syncTurnsFromHistory({\n clearOnEmpty: true,\n preserveChangesSince: turnsBeforeRejoin,\n })\n } catch {\n // 重连补数尽力而为;后续 Socket 重连仍会再次尝试\n }\n }\n\n /** @internal 首次连接:加载历史 + 加入房间。 */\n async _bootstrap(): Promise<void> {\n await this.syncTurnsFromHistory({ suppressErrors: false })\n await this.ensureJoined()\n }\n\n /** @internal */\n _handleTurnStart(turn: TurnProjection): void {\n this.markRunningIfIdle()\n this.applyTurn(turn)\n }\n\n /** @internal */\n _handleTurnPatch(patch: PatchEnvelope): void {\n this.markRunningIfIdle()\n if (patch.data.workspace_changed) {\n this.emitter.emit(\"workspaceChanged\", {})\n }\n const current = this.pendingTurnPatches.get(patch.turn_id)\n if (!current || patch.sequence >= current.sequence) {\n this.pendingTurnPatches.set(patch.turn_id, patch)\n }\n this.schedulePatchFlush()\n }\n\n /** @internal */\n _handleTurnEnd(turn: TurnProjection): void {\n this.applyTurn(turn)\n }\n\n /** @internal 历史回放通道(event_format: raw)。 */\n _handleTurnEvents(events: RawEvent[]): void {\n if (!events.length) return\n const terminalChatEndStatus = extractTerminalChatEndStatus(events)\n if (!terminalChatEndStatus) {\n this.markRunningIfIdle()\n }\n if (this.state.turns.length) {\n this.projectionBuilder.seedSequence(Math.max(...this.state.turns.map((t) => t.sequence)))\n }\n const updates = this.projectionBuilder.processBatch(events)\n for (const update of updates) {\n if (update.kind === \"upsert\") {\n this.applyTurn(update.turn)\n } else if (update.kind === \"workspace_changed\") {\n this.emitter.emit(\"workspaceChanged\", {})\n }\n }\n if (terminalChatEndStatus) {\n this.finishStreaming(terminalChatEndStatus)\n }\n }\n\n /** @internal */\n _handleChatStart(): void {\n this.update((s) => ({ ...s, status: \"running\", errorMessage: null, isStreaming: true }))\n }\n\n /** @internal */\n _handleChatEnd(status: string): void {\n this.flushPatches()\n this.finishStreaming(status)\n this.recentChatEndAt = Date.now()\n void this.syncTurnsFromHistory()\n this.emitter.emit(\"chatEnd\", { status })\n }\n\n /** @internal */\n _handleSystemError(message: string): void {\n this.flushPatches()\n const finalMessage = isOomText(message) ? OOM_MESSAGE : message\n this.update((s) =>\n addErrorMessage(markFailed({ ...s, status: \"failed\", errorMessage: finalMessage, isStreaming: false }), finalMessage),\n )\n this.recentChatEndAt = Date.now()\n this.emitter.emit(\"error\", { message: finalMessage })\n }\n\n /** @internal */\n _handleTaskUpdated(tasks: unknown[]): void {\n this.emitter.emit(\"taskListUpdated\", { tasks })\n }\n\n /** @internal */\n _handleWorkspaceFilesChanged(filePath?: string): void {\n this.emitter.emit(\"workspaceChanged\", { filePath })\n }\n\n /** @internal */\n _handleSessionUpdated(data: {\n intent?: string\n status?: SessionStatus\n model?: string | null\n bound_skill_id?: string | null\n replay_state?: Record<string, unknown> | null\n }): void {\n if (data.status) {\n this.update((s) => ({ ...s, status: data.status ?? s.status }))\n }\n this.emitter.emit(\"sessionUpdated\", {\n intent: data.intent,\n status: data.status,\n model: data.model,\n boundSkillId: data.bound_skill_id,\n replayState: data.replay_state,\n })\n }\n\n /** @internal */\n _handleRewind(checkpointId: string): void {\n this.update((s) => ({ ...s, mode: null, errorMessage: null }))\n void this.syncTurnsFromHistory({ clearOnEmpty: true })\n this.emitter.emit(\"rewind\", { checkpointId })\n }\n\n /** @internal */\n _handleReplayMismatch(data: { actual_message?: string; expected_message?: string }): void {\n const message = this.pendingReplayMessage ?? data.actual_message ?? \"\"\n const mode = this.pendingReplayMode\n this.pendingReplayMessage = null\n this.pendingReplayMode = undefined\n const respond = (decision: \"keep_replay\" | \"continue_replay\") => {\n this.runtime.emitEvent(\"chat:send\", {\n session_id: this.sessionId,\n message,\n mode,\n replay_decision: decision,\n })\n }\n const handled = this.emitter.emitFirst(\"replayMismatch\", {\n actualMessage: data.actual_message,\n expectedMessage: data.expected_message,\n respond,\n })\n if (!handled) {\n respond(\"continue_replay\")\n }\n }\n\n /** @internal */\n _handleSystemNotification(loopId: string, notification: Record<string, unknown>): void {\n const notificationType =\n typeof notification.notification_type === \"string\"\n ? notification.notification_type\n : \"system_notification\"\n const title = typeof notification.title === \"string\" ? notification.title : notificationType\n const detail =\n typeof notification.detail === \"string\"\n ? notification.detail\n : notification.detail == null\n ? undefined\n : JSON.stringify(notification.detail)\n const status =\n notification.status === \"running\" || notification.status === \"done\" || notification.status === \"error\"\n ? notification.status\n : \"info\"\n this.emitter.emit(\"notification\", {\n type: notificationType,\n title,\n detail,\n status,\n loopId,\n metadata: isRecord(notification.metadata) ? notification.metadata : undefined,\n })\n if (notificationType === \"bg:started\" && isRecord(notification.metadata)) {\n const taskId =\n typeof notification.metadata.task_id === \"string\" ? notification.metadata.task_id : \"\"\n if (taskId) {\n this.emitter.emit(\"backgroundTask\", {\n id: taskId,\n command:\n typeof notification.metadata.command === \"string\" ? notification.metadata.command : \"\",\n description:\n typeof notification.metadata.description === \"string\"\n ? notification.metadata.description\n : undefined,\n status: \"running\",\n elapsedSeconds: 0,\n })\n }\n }\n }\n\n /** @internal */\n _handleBackgroundTask(task: {\n id: string\n command: string\n description?: string\n status: \"running\" | \"done\" | \"failed\"\n exitCode?: number | null\n elapsedSeconds: number\n output?: string\n }): void {\n this.emitter.emit(\"backgroundTask\", task)\n }\n\n /** @internal */\n _handleArtifact(event: AgentSessionEvents[\"artifact\"]): void {\n this.emitter.emit(\"artifact\", event)\n }\n\n /** @internal 加入房间的应答里带 is_running,据此校准流式状态。 */\n _applyRunningState(isRunning: boolean): void {\n if (isRunning) {\n this.update((s) => ({ ...s, status: \"running\", isStreaming: true }))\n } else if (this.state.isStreaming) {\n this.update((s) => ({ ...s, isStreaming: false }))\n void this.syncTurnsFromHistory()\n }\n }\n\n // ---------------------------------------------------------------- 内部实现\n\n private markRunningIfIdle(): void {\n if (!this.state.isStreaming) {\n this.update((s) => ({ ...s, status: \"running\", isStreaming: true }))\n }\n }\n\n private finishStreaming(status: string): void {\n const sessionStatus = sessionStatusFromChatEnd(status)\n this.update((s) => {\n let next: SessionState = { ...s, status: sessionStatus, isStreaming: false }\n if (status === \"interrupted\") next = markInterrupted(next)\n else if (status === \"failed\") next = markFailed(next)\n return next\n })\n }\n\n private applyTurn(turn: TurnProjection): void {\n this.flushPatches()\n const previous = this.state\n this.update((s) => upsertTurn(s, turn))\n this.emitTurnDerivedEvents(previous, turn)\n }\n\n private schedulePatchFlush(): void {\n if (this.patchFlushHandle != null) return\n const flush = () => {\n this.patchFlushHandle = null\n this.patchFlushCancel = null\n this.flushPatches()\n }\n if (typeof window !== \"undefined\" && typeof window.requestAnimationFrame === \"function\") {\n const handle = window.requestAnimationFrame(flush)\n this.patchFlushHandle = handle\n this.patchFlushCancel = () => window.cancelAnimationFrame(handle)\n return\n }\n const handle = globalThis.setTimeout(flush, 33)\n this.patchFlushHandle = handle\n this.patchFlushCancel = () => globalThis.clearTimeout(handle)\n }\n\n private cancelPatchFlush(): void {\n this.patchFlushCancel?.()\n this.patchFlushHandle = null\n this.patchFlushCancel = null\n this.pendingTurnPatches.clear()\n }\n\n private flushPatches(): void {\n if (this.pendingTurnPatches.size === 0) return\n const patches = [...this.pendingTurnPatches.values()].sort(\n (left, right) => left.sequence - right.sequence,\n )\n this.pendingTurnPatches.clear()\n for (const patch of patches) {\n const previous = this.state\n this.update((s) => applyTurnPatch(s, patch))\n const turn = patch.data.turn\n if (turn) {\n this.emitTurnDerivedEvents(previous, turn)\n }\n }\n if (this.patchFlushCancel) {\n this.patchFlushCancel()\n this.patchFlushHandle = null\n this.patchFlushCancel = null\n }\n }\n\n /** turn 数据落地后统一派生语义事件(指令 / 工具调用 / 消息 / 模式 / 预览 / OOM)。 */\n private emitTurnDerivedEvents(previous: SessionState, turn: TurnProjection): void {\n const mode = extractModeFromBlocks(turn.blocks)\n if (mode && previous.mode !== mode) {\n this.emitter.emit(\"modeChange\", { mode })\n }\n\n for (const block of turn.blocks) {\n if (block.type === \"tool_result\" && isOomResult(block.content)) {\n this.notifySandboxOom(block.tool_call_id ?? turn.id)\n }\n if (block.type === \"tool_bridge\" && isToolBridgeContent(block.content)) {\n this.dispatchCommand(turn, block)\n continue\n }\n if (block.type === \"tool_ui\" && block.tool_call_id && isUiMetaLike(block.content)) {\n const ui = block.content\n if (ui.target !== \"preview\") continue\n const previewType = ui.resourceHTML ? (\"resource-html\" as const) : (\"resource-uri\" as const)\n const previewContent = ui.resourceHTML ?? ui.resourceUri ?? ui.resourceURI\n if (!previewContent) continue\n const key = `${block.tool_call_id}:${previewType}`\n if (this.deliveredToolPreviews.get(key) === previewContent) continue\n this.deliveredToolPreviews.set(key, previewContent)\n this.emitter.emit(\"toolPreview\", {\n toolCallId: block.tool_call_id,\n type: previewType,\n content: previewContent,\n title: ui.title ?? \"工具预览\",\n })\n }\n if (block.type === \"system_notification\" && isRecord(block.content)) {\n this._handleSystemNotification(turn.loop_id, block.content)\n }\n }\n\n for (const toolCall of turn.tool_calls) {\n const info: ToolCallInfo = {\n id: toolCall.id,\n name: toolCall.tool_name,\n display_name: toolCall.display_name,\n arguments: toolCall.arguments,\n result: toolCall.result ?? undefined,\n status:\n toolCall.status === \"pending\" ||\n toolCall.status === \"awaiting_answer\" ||\n toolCall.status === \"done\" ||\n toolCall.status === \"error\" ||\n toolCall.status === \"cancelled\"\n ? toolCall.status\n : (\"pending\" as const),\n }\n if (!this.seenToolCallIds.has(toolCall.id)) {\n this.seenToolCallIds.add(toolCall.id)\n this.emitter.emit(\"toolCall\", { toolCall: info, turn })\n }\n const finished =\n toolCall.status === \"done\" || toolCall.status === \"error\" || toolCall.status === \"cancelled\"\n if (finished && !this.finishedToolCallIds.has(toolCall.id)) {\n this.finishedToolCallIds.add(toolCall.id)\n this.emitter.emit(\"toolResult\", { toolCall: info, turn })\n if (isOomResult(toolCall.result)) {\n this.notifySandboxOom(toolCall.id)\n }\n }\n }\n\n if (turn.status !== \"streaming\" && !this.emittedMessageTurnIds.has(turn.turn_id)) {\n const message = this.state.messages.find((m) => m.entry_id === turn.turn_id)\n if (message) {\n this.emittedMessageTurnIds.add(turn.turn_id)\n this.emitter.emit(\"message\", { message, turn })\n }\n }\n }\n\n private dispatchCommand(turn: TurnProjection, block: ContentBlock): void {\n if (!isToolBridgeContent(block.content)) return\n const { action, payload } = block.content\n let payloadKey = \"\"\n try {\n payloadKey = JSON.stringify(payload ?? null)\n } catch {\n payloadKey = String(payload ?? \"\")\n }\n const deliveryKey = [block.tool_call_id ?? turn.id, action, payloadKey].join(\"\u0000\")\n if (this.deliveredCommandKeys.has(deliveryKey)) return\n this.deliveredCommandKeys.add(deliveryKey)\n const meta = { toolCallId: block.tool_call_id ?? undefined }\n this.emitter.emit(\"command\", { action, payload, toolCallId: meta.toolCallId })\n this.commands.dispatch(action, payload, meta)\n }\n\n private notifySandboxOom(key: string): void {\n if (this.oomNotifiedKeys.has(key)) return\n this.oomNotifiedKeys.add(key)\n this.update((s) => addErrorMessage(s, OOM_MESSAGE))\n this.emitter.emit(\"sandboxOom\", { toolCallId: key })\n }\n\n private async syncTurnsFromHistory(\n options: {\n clearOnEmpty?: boolean\n suppressErrors?: boolean\n preserveChangesSince?: TurnProjection[]\n } = {},\n ): Promise<void> {\n const { clearOnEmpty = false, suppressErrors = true, preserveChangesSince } = options\n const turnsAtRequestStart = this.state.turns\n try {\n const turns = await this.runtime.fetchTurns(this.sessionId)\n if (turns.length === 0 && !clearOnEmpty) return\n this.update((state) => {\n const mergeBaseline = preserveChangesSince ?? turnsAtRequestStart\n if (state.turns === mergeBaseline) return withTurns(state, turns)\n\n // REST 补数与刚恢复的实时事件可能并发。历史响应只覆盖补数流程开始前的\n // 快照;期间新到或 sequence 更新的 turn 必须保留,不能被旧响应抹掉。\n const historyById = new Map(turns.map((turn) => [turn.turn_id, turn]))\n let merged = withTurns(state, turns)\n for (const current of state.turns) {\n const fromHistory = historyById.get(current.turn_id)\n if (!fromHistory || current.sequence > fromHistory.sequence) {\n merged = upsertTurn(merged, current)\n }\n }\n return merged\n })\n this.replayCommandsFromTurns(turns)\n } catch (error) {\n if (!suppressErrors) throw error\n // 尽力而为的历史补数,失败时保留现有内存状态\n }\n }\n\n /**\n * 把历史里的指令补投给宿主页面。\n *\n * 重开会话、断线补数时,地图高亮这类\"页面当前状态\"必须能恢复——\n * 否则刷新一次页面,之前智能体让页面做的事就全丢了。\n * 只回放指令:toolCall / message 这些事件如果按历史全量重放,\n * 监听器会在挂载瞬间收到几百条陈年事件。\n * dispatch 内部按 deliveredCommandKeys 去重,重复调用安全。\n */\n private replayCommandsFromTurns(turns: TurnProjection[]): void {\n for (const turn of turns) {\n for (const block of turn.blocks) {\n if (block.type === \"tool_bridge\" && isToolBridgeContent(block.content)) {\n this.dispatchCommand(turn, block)\n }\n }\n }\n }\n\n private ensureJoined(): Promise<void> {\n if (this.joined) return Promise.resolve()\n if (this.joinPending) return this.joinPending\n\n const join = this.runtime\n .emitWithAck(\n \"session:subscribe\",\n { session_id: this.sessionId, event_format: \"raw\", resume: true },\n 5_000,\n )\n .then((response) => {\n if (response && response.ok === false) {\n throw new Error(\n typeof response.message === \"string\" && response.message\n ? response.message\n : \"Session subscription failed\",\n )\n }\n this.joined = true\n this._applyRunningState(Boolean(response?.is_running))\n })\n .finally(() => {\n this.joinPending = null\n })\n\n this.joinPending = join\n return join\n }\n\n private async ensureIdleBeforeSend(): Promise<void> {\n if (Date.now() - this.recentChatEndAt > 3000) return\n const deadline = Date.now() + 3000\n while (Date.now() < deadline) {\n const response = await this.stop()\n const status = String(response.status ?? \"\")\n if (status !== \"stopping\") return\n await new Promise((resolve) => globalThis.setTimeout(resolve, 150))\n }\n }\n}\n","import type { BladeClient } from \"../blade-client\"\nimport type { PatchEnvelope, TurnProjection } from \"../schemas/projection\"\nimport type { RawEvent } from \"../shared/projection\"\nimport { AgentSession, type SessionRuntime } from \"./agent-session\"\nimport type { ConnectionStatus } from \"./state\"\n\ntype BackgroundTaskEvent = {\n id?: string\n task_id?: string\n command?: string\n description?: string\n status?: string\n exit_code?: number | null\n elapsed_seconds?: number\n output_lines_count?: number\n output_preview?: string[]\n}\n\n/**\n * 每个 BladeClient 一个:管理一条 Socket.IO 连接,按 session_id 把事件\n * 路由给各 AgentSession 实例。多会话共享连接、状态互不干扰。\n */\nexport class SessionHub {\n private readonly client: BladeClient\n private readonly sessions = new Map<string, AgentSession>()\n private readonly bootstrapPending = new Map<string, Promise<AgentSession>>()\n private connection: ConnectionStatus = \"disconnected\"\n private readonly connectionListeners = new Set<(status: ConnectionStatus) => void>()\n private bound = false\n private hasConnected = false\n\n constructor(client: BladeClient) {\n this.client = client\n }\n\n /** 当前 Socket.IO 连接状态。 */\n getConnection(): ConnectionStatus {\n return this.connection\n }\n\n /** 订阅连接状态变化。 */\n onConnectionChange(listener: (status: ConnectionStatus) => void): () => void {\n this.connectionListeners.add(listener)\n return () => {\n this.connectionListeners.delete(listener)\n }\n }\n\n /** 取得(或复用)一个会话的 AgentSession,并完成历史加载 + 房间订阅。 */\n async connect(sessionId: string): Promise<AgentSession> {\n const existing = this.sessions.get(sessionId)\n if (existing && !existing.isDisposed) {\n return this.bootstrapPending.get(sessionId) ?? existing\n }\n this.ensureBound()\n const session = new AgentSession(sessionId, this.runtimeFor(), this.connection)\n this.sessions.set(sessionId, session)\n this.ensureConnected()\n const bootstrap = session._bootstrap().then(() => session)\n this.bootstrapPending.set(sessionId, bootstrap)\n try {\n return await bootstrap\n } catch (error) {\n session.dispose()\n throw error\n } finally {\n if (this.bootstrapPending.get(sessionId) === bootstrap) {\n this.bootstrapPending.delete(sessionId)\n }\n }\n }\n\n /** 已有实例则返回,不触发网络请求。 */\n peek(sessionId: string): AgentSession | undefined {\n if (this.bootstrapPending.has(sessionId)) return undefined\n const session = this.sessions.get(sessionId)\n return session && !session.isDisposed ? session : undefined\n }\n\n /** 手动重连(例如登录态变化后)。 */\n reconnect(): void {\n // 登录态可能早于首个 AgentSession 初始化;必须先绑定连接监听,\n // 否则 connect 事件会在 hub 尚未监听时丢失,状态永久停在 connecting。\n this.ensureBound()\n const socket = this.client.socket()\n socket.disconnect()\n this.setConnection(\"connecting\")\n socket.connect()\n }\n\n /** 断开连接(不清理 session 实例)。 */\n disconnect(): void {\n this.client.socket().disconnect()\n this.setConnection(\"disconnected\")\n }\n\n /** 清理当前身份下缓存的全部会话,避免切换登录身份后复用旧快照。 */\n disposeAll(): void {\n this.bootstrapPending.clear()\n for (const session of [...this.sessions.values()]) {\n session.dispose()\n }\n }\n\n /**\n * @internal 底层 socket 被换掉时由 BladeClient 调用(如 setBaseUrl)。\n * 事件监听器绑在旧 socket 实例上,换新实例后必须重绑,否则所有\n * turn:* / chat:* 事件都会静默丢弃。\n */\n _handleSocketReplaced(): void {\n this.bound = false\n this.setConnection(\"disconnected\")\n if (this.sessions.size === 0) return\n // 已有会话:在新 socket 上重建监听;连接成功事件会重新加入房间并补数\n this.ensureBound()\n this.ensureConnected()\n }\n\n private runtimeFor(): SessionRuntime {\n return {\n emitEvent: (event, data) => {\n // biome-ignore lint/suspicious/noExplicitAny: 泛化 emit,事件名由调用方保证\n ;(this.client.socket() as any).emit(event, data)\n },\n emitWithAck: (event, data, timeoutMs) =>\n new Promise((resolve, reject) => {\n // biome-ignore lint/suspicious/noExplicitAny: 泛化 emit,事件名由调用方保证\n ;(this.client.socket() as any)\n .timeout(timeoutMs)\n .emit(event, data, (err: Error | null, response?: Record<string, unknown>) => {\n if (err) {\n reject(err)\n return\n }\n resolve(response)\n })\n }),\n ensureConnected: () => this.ensureConnected(),\n fetchTurns: (sessionId) => this.client.sessions.getSessionTurns(sessionId),\n listDir: (sessionId, dirPath) => this.client.sessions.listDir(sessionId, dirPath),\n countFiles: (sessionId, dirPath) => this.client.sessions.countFiles(sessionId, dirPath),\n downloadFile: (sessionId, filePath, downloadName) =>\n this.client.sessions.downloadFile(sessionId, filePath, downloadName),\n onDispose: (session) => {\n if (this.sessions.get(session.sessionId) === session) {\n this.sessions.delete(session.sessionId)\n }\n // biome-ignore lint/suspicious/noExplicitAny: session:unsubscribe 是后端自定义事件\n ;(this.client.socket() as any).emit(\"session:unsubscribe\", { session_id: session.sessionId })\n },\n }\n }\n\n private ensureConnected(): void {\n const socket = this.client.socket()\n if (socket.connected || socket.active) return\n this.setConnection(\"connecting\")\n socket.connect()\n }\n\n private setConnection(status: ConnectionStatus): void {\n if (this.connection === status) return\n this.connection = status\n for (const session of this.sessions.values()) {\n session._setConnection(status)\n }\n for (const listener of [...this.connectionListeners]) {\n try {\n listener(status)\n } catch (error) {\n console.warn(\"[agent-client] 连接状态回调抛出异常:\", error)\n }\n }\n }\n\n /** 事件带 session_id 时精确路由;缺省时按当前唯一活跃会话兜底。 */\n private route(sessionId: string | null | undefined): AgentSession[] {\n if (sessionId) {\n const session = this.sessions.get(sessionId)\n return session && !session.isDisposed ? [session] : []\n }\n const active = [...this.sessions.values()].filter((session) => !session.isDisposed)\n return active.length === 1 ? active : []\n }\n\n private ensureBound(): void {\n if (this.bound) return\n this.bound = true\n // biome-ignore lint/suspicious/noExplicitAny: 事件桥接层统一收敛混合 payload\n const socket = this.client.socket() as any\n\n socket.on(\"connect\", () => {\n const isReconnect = this.hasConnected\n this.hasConnected = true\n this.setConnection(\"connected\")\n if (isReconnect) {\n for (const session of this.sessions.values()) {\n void session._rejoinAfterReconnect()\n }\n }\n })\n socket.on(\"connect_error\", () => this.setConnection(\"disconnected\"))\n socket.on(\"disconnect\", () => this.setConnection(\"disconnected\"))\n socket.io.on(\"reconnect_attempt\", () => this.setConnection(\"reconnecting\"))\n\n socket.on(\"turn:start\", (data: TurnProjection & { session_id?: string }) => {\n for (const session of this.route(data.session_id)) session._handleTurnStart(data)\n })\n socket.on(\"turn:patch\", (data: PatchEnvelope & { session_id?: string }) => {\n for (const session of this.route(data.session_id)) session._handleTurnPatch(data)\n })\n socket.on(\"turn:end\", (data: TurnProjection & { session_id?: string }) => {\n for (const session of this.route(data.session_id)) session._handleTurnEnd(data)\n })\n socket.on(\"turn:events\", (data: { session_id?: string; events: RawEvent[] }) => {\n for (const session of this.route(data.session_id)) session._handleTurnEvents(data.events ?? [])\n })\n socket.on(\"chat:start\", (data?: { session_id?: string }) => {\n for (const session of this.route(data?.session_id)) session._handleChatStart()\n })\n socket.on(\"chat:end\", (data?: { status?: string; session_id?: string }) => {\n for (const session of this.route(data?.session_id)) {\n session._handleChatEnd(data?.status ?? \"completed\")\n }\n })\n socket.on(\"system:error\", (data: { message: string; session_id?: string }) => {\n for (const session of this.route(data.session_id)) session._handleSystemError(data.message)\n })\n socket.on(\n \"system:notification\",\n (data: { session_id?: string } & Record<string, unknown>) => {\n for (const session of this.route(data.session_id)) {\n session._handleSystemNotification(\"root\", data)\n }\n },\n )\n socket.on(\"task:updated\", (data: { tasks: unknown[]; session_id?: string }) => {\n for (const session of this.route(data.session_id)) session._handleTaskUpdated(data.tasks)\n })\n socket.on(\"task:synced\", (data: { tasks: unknown[]; session_id?: string }) => {\n for (const session of this.route(data.session_id)) session._handleTaskUpdated(data.tasks)\n })\n socket.on(\n \"workspace:files_changed\",\n (data: { session_id?: string; file_path?: string }) => {\n for (const session of this.route(data.session_id)) {\n session._handleWorkspaceFilesChanged(data.file_path)\n }\n },\n )\n socket.on(\n \"session:updated\",\n (data: {\n session_id?: string\n intent?: string\n status?: import(\"../schemas/session\").SessionStatus\n model?: string | null\n bound_skill_id?: string | null\n replay_state?: Record<string, unknown> | null\n }) => {\n for (const session of this.route(data.session_id)) {\n session._handleSessionUpdated(data)\n }\n },\n )\n socket.on(\"session:rewind\", (data: { checkpoint_id: string; session_id?: string }) => {\n for (const session of this.route(data.session_id)) {\n session._handleRewind(data.checkpoint_id)\n }\n })\n socket.on(\n \"replay:input_mismatch\",\n (data: { session_id?: string; actual_message?: string; expected_message?: string }) => {\n for (const session of this.route(data.session_id)) session._handleReplayMismatch(data)\n },\n )\n socket.on(\"artifact:created\", (data: Record<string, unknown> & { session_id?: string }) => {\n this.routeArtifact(data, \"created\")\n })\n socket.on(\"artifact:updated\", (data: Record<string, unknown> & { session_id?: string }) => {\n this.routeArtifact(data, \"updated\")\n })\n socket.on(\"bg:started\", (data: BackgroundTaskEvent & { session_id?: string }) => {\n const taskId =\n typeof data.task_id === \"string\" ? data.task_id : typeof data.id === \"string\" ? data.id : \"\"\n if (!taskId) return\n for (const session of this.route(data.session_id)) {\n session._handleBackgroundTask({\n id: taskId,\n command: typeof data.command === \"string\" ? data.command : \"\",\n description: typeof data.description === \"string\" ? data.description : undefined,\n status: \"running\",\n elapsedSeconds: typeof data.elapsed_seconds === \"number\" ? data.elapsed_seconds : 0,\n })\n }\n })\n socket.on(\n \"bg:tasks_completed\",\n (data: { tasks?: BackgroundTaskEvent[]; session_id?: string }) => {\n for (const session of this.route(data.session_id)) {\n for (const task of data.tasks ?? []) {\n const taskId =\n typeof task.id === \"string\"\n ? task.id\n : typeof task.task_id === \"string\"\n ? task.task_id\n : \"\"\n if (!taskId) continue\n session._handleBackgroundTask({\n id: taskId,\n command: typeof task.command === \"string\" ? task.command : \"\",\n description: typeof task.description === \"string\" ? task.description : undefined,\n status: task.status === \"running\" || task.status === \"failed\" ? task.status : \"done\",\n exitCode:\n typeof task.exit_code === \"number\" || task.exit_code === null\n ? task.exit_code\n : undefined,\n elapsedSeconds: typeof task.elapsed_seconds === \"number\" ? task.elapsed_seconds : 0,\n output:\n Array.isArray(task.output_preview) && task.output_preview.length > 0\n ? task.output_preview.join(\"\\n\")\n : undefined,\n })\n }\n }\n },\n )\n }\n\n private routeArtifact(\n data: Record<string, unknown> & { session_id?: string },\n kind: \"created\" | \"updated\",\n ): void {\n const filePath = typeof data.file_path === \"string\" ? data.file_path : \"\"\n if (!filePath) return\n for (const session of this.route(data.session_id)) {\n session._handleWorkspaceFilesChanged(filePath)\n session._handleArtifact({\n filePath,\n contentType: typeof data.content_type === \"string\" ? data.content_type : \"\",\n title: typeof data.title === \"string\" ? data.title : filePath,\n content: typeof data.content === \"string\" ? data.content : \"\",\n oldString: typeof data.old_string === \"string\" ? data.old_string : undefined,\n newString: typeof data.new_string === \"string\" ? data.new_string : undefined,\n kind,\n })\n }\n }\n}\n","import { io, type Socket } from \"socket.io-client\"\nimport { buildSocketAuth, resolveAuthToken, type AuthOptions } from \"./auth\"\nimport type { ClientToServerEvents, ServerToClientEvents } from \"./types/socket-events\"\nimport { SDK_NAME, SDK_VERSION } from \"./version\"\n\nexport type TypedSocket = Socket<ServerToClientEvents, ClientToServerEvents>\n\nexport interface CreateSocketOptions extends AuthOptions {\n baseUrl: string\n path?: string\n}\n\n/** 握手时声明 SDK 身份,让 Server 能把旧 agent-kit 挡在门外并给出升级提示。 */\nfunction withSdkIdentity(auth: { token: string } | undefined): Record<string, string> {\n return { ...(auth ?? {}), sdk: SDK_NAME, sdk_version: SDK_VERSION }\n}\n\nexport function createSocket(options: CreateSocketOptions): TypedSocket {\n const token = resolveAuthToken(options)\n return io(options.baseUrl, {\n path: options.path ?? \"/socket.io\",\n withCredentials: true,\n query: token ? { token } : undefined,\n auth:\n typeof options.token === \"function\"\n ? (cb) => cb(withSdkIdentity(buildSocketAuth(options)))\n : withSdkIdentity(buildSocketAuth(options)),\n autoConnect: false,\n })\n}\n","export interface AuthOptions {\n token?: string | (() => string | null | undefined)\n}\n\nexport function buildAuthHeaders(options: AuthOptions): Record<string, string> {\n const token = resolveAuthToken(options)\n if (!token) {\n return {}\n }\n return {\n Authorization: `Bearer ${token}`,\n }\n}\n\nexport function buildSocketAuth(options: AuthOptions): { token: string } | undefined {\n const token = resolveAuthToken(options)\n return token ? { token } : undefined\n}\n\nexport function resolveAuthToken(options: AuthOptions): string | null {\n const token = typeof options.token === \"function\" ? options.token() : options.token\n return token ? token : null\n}\n","/** Socket.IO 握手使用的 SDK 身份。Server 只校验 1.1.1 这次破坏性变更。 */\n\ndeclare const __BLADE_SDK_VERSION__: string | undefined\n\n/**\n * 本 SDK 的 npm 包版本,随 Socket.IO 握手一并声明。\n * Release 构建由 Git Tag 注入;本地开发回退到当前源码版本。\n */\nexport const SDK_NAME = \"agent-client\"\nexport const SDK_VERSION =\n typeof __BLADE_SDK_VERSION__ === \"string\" ? __BLADE_SDK_VERSION__ : \"1.1.1\"\n","import {\n loginWithPopup,\n readStoredToken,\n writeStoredToken,\n type LoginOptions,\n type LoginResult,\n type TokenStorageMode,\n} from \"./auth-login\"\nimport {\n BladeApiError,\n type BladeFetchInit,\n type HttpMethod,\n decorateAuthError,\n extractErrorDetail,\n} from \"./rest\"\nimport { AuthResource } from \"./resources/auth\"\nimport { HeadlessResource } from \"./resources/headless\"\nimport { ModelsResource } from \"./resources/models\"\nimport { SessionsResource } from \"./resources/sessions\"\nimport { SessionHub } from \"./session/hub\"\nimport { createSocket, type TypedSocket } from \"./socket\"\n\nexport interface BladeClientOptions {\n /** 后端地址,如 \"https://blade.example.com\"。浏览器里传空字符串则使用当前域名。 */\n baseUrl: string\n /**\n * 访问令牌(PAT)。不传时按 cookie 会话模式工作;\n * 浏览器场景也可以不传,改用 client.auth.login() 弹窗登录。\n */\n token?: string | (() => string | null | undefined)\n /**\n * Socket.IO 专用令牌。第一方应用可在 REST 继续使用 cookie 刷新的同时,\n * 把 cookie 换得的短期令牌只用于实时连接;不传时复用 token。\n */\n socketToken?: string | (() => string | null | undefined)\n /** login() 取得的令牌存放位置,默认 \"local\"(localStorage,刷新页面不掉登录)。 */\n tokenStorage?: TokenStorageMode\n fetchImpl?: typeof fetch\n onRefreshSuccess?: () => void | Promise<void>\n}\n\nconst REFRESH_PATH = \"/api/auth/refresh\"\n\nexport class BladeClient {\n private refreshPromise: Promise<boolean> | null = null\n private socketInstance: TypedSocket | null = null\n private readonly socketReplacementListeners = new Set<() => void>()\n /** login() / setToken() 热挂载的令牌,优先级高于构造参数。 */\n private runtimeToken: string | null = null\n readonly options: BladeClientOptions\n readonly auth: AuthResource\n readonly headless: HeadlessResource\n readonly models: ModelsResource\n readonly sessions: SessionsResource\n /** 实时会话中枢:client.sessions.connect() 内部使用,一般不直接访问。 */\n readonly hub: SessionHub\n\n constructor(options: BladeClientOptions) {\n this.options = {\n ...options,\n baseUrl: normalizeBaseUrl(options.baseUrl),\n }\n this.auth = new AuthResource(this)\n this.headless = new HeadlessResource(this)\n this.models = new ModelsResource(this)\n this.sessions = new SessionsResource(this)\n this.hub = new SessionHub(this)\n if (this.options.token === undefined) {\n this.runtimeToken = readStoredToken(this.options.baseUrl)\n }\n }\n\n /**\n * 弹窗授权登录:用户在弹出的授权页点击\"许可授权\"后自动取得 PAT,\n * REST 与 Socket.IO 立即生效。只在浏览器可用。\n */\n async login(options?: LoginOptions): Promise<LoginResult> {\n const result = await loginWithPopup(this, options)\n this.setToken(result.token)\n return result\n }\n\n /** 退出登录:清除 login() 存储的令牌并断开实时连接。 */\n logoutToken(): void {\n this.setToken(null)\n this.hub.disconnect()\n }\n\n /** 热挂载访问令牌(null 表示清除)。会重建 Socket.IO 连接以携带新凭证。 */\n setToken(token: string | null): void {\n const previousToken = this.resolveToken()\n this.runtimeToken = token\n const nextToken = this.resolveToken()\n if (previousToken !== nextToken) {\n this.hub.disposeAll()\n }\n writeStoredToken(this.options.baseUrl, token, this.options.tokenStorage ?? \"local\")\n if (this.socketInstance) {\n const wasConnected = this.socketInstance.connected || this.socketInstance.active\n this.socketInstance.disconnect()\n if (wasConnected || token) {\n this.socketInstance.connect()\n }\n }\n }\n\n /** 当前是否持有访问令牌(不代表令牌一定有效)。 */\n hasToken(): boolean {\n return Boolean(this.resolveRestToken())\n }\n\n /**\n * 当前访问令牌(PAT),未登录时为 null。\n *\n * SDK 只封装会话相关接口;其余长尾接口对照后端 Swagger(`<baseUrl>/docs`)\n * 用原生 fetch 自行调用,把本令牌填入 Authorization 头即可:\n *\n * ```ts\n * fetch(`${baseUrl}/api/memories/search?q=xxx`, {\n * headers: { Authorization: `Bearer ${client.token}` },\n * })\n * ```\n *\n * 安全约束:该令牌只应发往 baseUrl 同源接口,不要附加到第三方域名的请求上。\n */\n get token(): string | null {\n return this.resolveRestToken()\n }\n\n setBaseUrl(baseUrl: string): void {\n const nextBaseUrl = normalizeBaseUrl(baseUrl)\n if (nextBaseUrl === this.options.baseUrl) {\n return\n }\n // 后端地址是会话身份边界,不是普通传输重连。旧 session_id、历史快照\n // 和房间订阅都不能带到另一个后端;先在旧 socket 上释放并驱逐缓存。\n this.hub.disposeAll()\n this.options.baseUrl = nextBaseUrl\n if (this.socketInstance) {\n this.socketInstance.removeAllListeners()\n this.socketInstance.disconnect()\n this.socketInstance = null\n // 换掉 socket 实例后必须让 hub 重绑监听:监听器绑在旧实例上,\n // 不重绑的话新连接上的事件全部收不到。\n this.hub._handleSocketReplaced()\n for (const listener of [...this.socketReplacementListeners]) {\n try {\n listener()\n } catch (error) {\n console.warn(\"[agent-client] socket 替换回调抛出异常:\", error)\n }\n }\n }\n }\n\n /** 底层 Socket.IO 实例因后端地址变化而被替换时通知高级集成层。 */\n onSocketReplaced(listener: () => void): () => void {\n this.socketReplacementListeners.add(listener)\n return () => {\n this.socketReplacementListeners.delete(listener)\n }\n }\n\n socket(): TypedSocket {\n if (!this.socketInstance) {\n this.socketInstance = createSocket({\n baseUrl: this.options.baseUrl,\n token: () => this.resolveSocketToken(),\n })\n }\n return this.socketInstance\n }\n\n async json<T>(method: HttpMethod, path: string, body?: unknown): Promise<T> {\n const response = await this.fetch(method, path, {\n body: body === undefined ? undefined : JSON.stringify(body),\n headers: body === undefined ? undefined : { \"content-type\": \"application/json\" },\n })\n return readJsonResponse(response)\n }\n\n async jsonFromInit<T>(path: string, init: RequestInit = {}): Promise<T> {\n const method = (init.method ?? \"GET\").toUpperCase() as HttpMethod\n const headers = new Headers(init.headers)\n if (init.body != null && !isFormData(init.body) && !headers.has(\"content-type\")) {\n headers.set(\"content-type\", \"application/json\")\n }\n const response = await this.fetch(method, path, {\n body: init.body,\n credentials: init.credentials,\n headers,\n signal: init.signal,\n })\n return readJsonResponse(response)\n }\n\n async text(method: HttpMethod, path: string): Promise<string> {\n const response = await this.fetch(method, path)\n return response.text()\n }\n\n async textFromInit(path: string, init: RequestInit = {}): Promise<string> {\n const method = (init.method ?? \"GET\").toUpperCase() as HttpMethod\n const response = await this.fetch(method, path, {\n body: init.body,\n credentials: init.credentials,\n headers: init.headers,\n signal: init.signal,\n })\n return response.text()\n }\n\n async responseFromInit(path: string, init: RequestInit = {}): Promise<Response> {\n const method = (init.method ?? \"GET\").toUpperCase() as HttpMethod\n return this.fetch(method, path, {\n body: init.body,\n credentials: init.credentials,\n headers: init.headers,\n signal: init.signal,\n })\n }\n\n async blob(method: HttpMethod, path: string): Promise<Blob> {\n const response = await this.fetch(method, path)\n return response.blob()\n }\n\n async formData(\n method: HttpMethod,\n path: string,\n form: FormData,\n options: { expectOk?: boolean; onUploadProgress?: (progress: UploadProgress) => void } = {},\n ): Promise<Response> {\n if (options.onUploadProgress && !this.options.fetchImpl && typeof XMLHttpRequest !== \"undefined\") {\n return this.formDataWithUploadProgress(method, path, form, options)\n }\n return this.fetch(method, path, { body: form, expectOk: options.expectOk })\n }\n\n async fetch(\n method: HttpMethod,\n path: string,\n init: BladeFetchInit = {},\n isRetry = false,\n ): Promise<Response> {\n const url = this.buildUrl(path)\n const response = await (this.options.fetchImpl ?? fetch)(url.toString(), {\n method,\n body: init.body,\n credentials: init.credentials ?? \"include\",\n headers: this.buildHeaders(url, init.headers),\n signal: init.signal,\n })\n\n if (response.status === 401 && !isRetry && this.shouldRefreshFor401(url)) {\n const refreshed = await this.tryRefresh()\n if (refreshed) {\n return this.fetch(method, path, init, true)\n }\n }\n\n if (init.expectOk !== false && !response.ok) {\n const detail = await extractErrorDetail(response)\n throw decorateAuthError(new BladeApiError(response, detail))\n }\n return response\n }\n\n buildAuthedUrl(path: string): string {\n const url = new URL(this.toBaseRelativePath(path), this.baseUrlWithTrailingSlash())\n const token = this.resolveTokenForUrl(url)\n if (token) {\n url.searchParams.set(\"token\", token)\n }\n return url.toString()\n }\n\n private buildHeaders(url: URL, headers?: HeadersInit): Headers {\n const result = new Headers(headers)\n if (!this.isSameBackendUrl(url)) {\n return result\n }\n // REST 不做版本校验:SDK 身份只在 Socket.IO 握手声明(见 socket.ts)。\n // 长尾接口设计上就让第三方用原生 fetch 直接调,这里不该塞额外标头。\n const token = this.resolveRestToken()\n if (token) {\n result.set(\"Authorization\", `Bearer ${token}`)\n }\n return result\n }\n\n private buildUrl(path: string): URL {\n return new URL(this.toBaseRelativePath(path), this.baseUrlWithTrailingSlash())\n }\n\n private baseUrlWithTrailingSlash(): string {\n return this.options.baseUrl.endsWith(\"/\") ? this.options.baseUrl : `${this.options.baseUrl}/`\n }\n\n private toBaseRelativePath(path: string): string {\n return path.startsWith(\"/\") ? path.slice(1) : path\n }\n\n private isSameBackendUrl(url: URL): boolean {\n const base = new URL(this.baseUrlWithTrailingSlash())\n if (url.origin !== base.origin) {\n return false\n }\n const basePath = base.pathname.replace(/\\/+$/, \"\")\n if (basePath === \"\") {\n return true\n }\n return url.pathname === basePath || url.pathname.startsWith(`${basePath}/`)\n }\n\n private shouldRefreshFor401(url: URL): boolean {\n const refreshUrl = this.buildUrl(REFRESH_PATH)\n return (\n this.isSameBackendUrl(url) &&\n url.pathname !== refreshUrl.pathname &&\n !this.hasExplicitBearerToken()\n )\n }\n\n private hasExplicitBearerToken(): boolean {\n return Boolean(this.resolveRestToken())\n }\n\n private async tryRefresh(): Promise<boolean> {\n if (this.refreshPromise) {\n return this.refreshPromise\n }\n\n this.refreshPromise = (async () => {\n try {\n const response = await (this.options.fetchImpl ?? fetch)(\n this.buildUrl(REFRESH_PATH).toString(),\n {\n method: \"POST\",\n credentials: \"include\",\n },\n )\n if (!response.ok) {\n return false\n }\n await this.options.onRefreshSuccess?.()\n return true\n } catch {\n return false\n } finally {\n this.refreshPromise = null\n }\n })()\n\n return this.refreshPromise\n }\n\n private resolveTokenForUrl(url: URL): string | null {\n if (!this.isSameBackendUrl(url)) {\n return null\n }\n return this.resolveRestToken()\n }\n\n private resolveRestToken(): string | null {\n return this.resolveToken()\n }\n\n private resolveSocketToken(): string | null {\n if (this.runtimeToken) return this.runtimeToken\n return resolveTokenOption(this.options.socketToken ?? this.options.token)\n }\n\n private resolveToken(): string | null {\n if (this.runtimeToken) return this.runtimeToken\n return resolveTokenOption(this.options.token)\n }\n\n private formDataWithUploadProgress(\n method: HttpMethod,\n path: string,\n form: FormData,\n options: { expectOk?: boolean; onUploadProgress?: (progress: UploadProgress) => void },\n isRetry = false,\n ): Promise<Response> {\n const url = this.buildUrl(path)\n const headers = this.buildHeaders(url)\n\n return new Promise((resolve, reject) => {\n const xhr = new XMLHttpRequest()\n xhr.open(method, url.toString(), true)\n xhr.withCredentials = true\n\n headers.forEach((value, key) => {\n xhr.setRequestHeader(key, value)\n })\n\n xhr.upload.onprogress = (event) => {\n options.onUploadProgress?.({\n loaded: event.loaded,\n total: event.lengthComputable ? event.total : undefined,\n percent: event.lengthComputable && event.total > 0 ? event.loaded / event.total : undefined,\n })\n }\n\n xhr.onerror = () => reject(new TypeError(\"Network request failed\"))\n xhr.ontimeout = () => reject(new TypeError(\"Network request timed out\"))\n xhr.onabort = () => reject(new DOMException(\"Request aborted\", \"AbortError\"))\n xhr.onload = async () => {\n if (xhr.status === 401 && !isRetry && this.shouldRefreshFor401(url)) {\n const refreshed = await this.tryRefresh()\n if (refreshed) {\n resolve(this.formDataWithUploadProgress(method, path, form, options, true))\n return\n }\n }\n\n const response = new Response(xhr.responseText, {\n status: xhr.status,\n statusText: xhr.statusText,\n headers: parseXhrHeaders(xhr.getAllResponseHeaders()),\n })\n if (options.expectOk !== false && !response.ok) {\n const detail = await extractErrorDetail(response.clone())\n reject(new BladeApiError(response, detail))\n return\n }\n options.onUploadProgress?.({ loaded: 1, total: 1, percent: 1 })\n resolve(response)\n }\n\n xhr.send(form)\n })\n }\n}\n\nfunction resolveTokenOption(\n tokenOption: string | (() => string | null | undefined) | undefined,\n): string | null {\n const token = typeof tokenOption === \"function\" ? tokenOption() : tokenOption\n return token ? token : null\n}\n\nexport interface UploadProgress {\n loaded: number\n total?: number\n percent?: number\n}\n\nfunction normalizeBaseUrl(baseUrl: string): string {\n const normalized = baseUrl.trim().replace(/\\/+$/, \"\")\n if (normalized || typeof window === \"undefined\") {\n return normalized\n }\n return window.location.origin\n}\n\nfunction isFormData(value: BodyInit): boolean {\n return typeof FormData !== \"undefined\" && value instanceof FormData\n}\n\nfunction readJsonResponse<T>(response: Response): Promise<T> {\n if (response.status === 204 || response.headers.get(\"content-length\") === \"0\") {\n return Promise.resolve(undefined as T)\n }\n return response.json() as Promise<T>\n}\n\nfunction parseXhrHeaders(rawHeaders: string): Headers {\n const headers = new Headers()\n for (const line of rawHeaders.trim().split(/[\\r\\n]+/)) {\n const separatorIndex = line.indexOf(\":\")\n if (separatorIndex <= 0) continue\n headers.append(line.slice(0, separatorIndex).trim(), line.slice(separatorIndex + 1).trim())\n }\n return headers\n}\n","/**\n * 页面协作协议(对应后端 `_meta.bridge` 通道,见 docs/specs/260417-embed-bridge)。\n *\n * ## action 从哪里来\n *\n * 智能体 → 宿主方向的每一条指令,都源自**技能作者写的工具代码**:工具返回值\n * JSON 里带 `_meta.bridge: { action, payload }`,后端在持久化前把它剥离成独立\n * 事件送达前端(LLM 的对话历史里读不到它)。因此:\n *\n * - action 字符串(如 \"map.highlight\")是**技能作者与宿主页面开发者之间的业务\n * 契约**,LLM 不参与协议、SDK 不做枚举校验;\n * - 宿主页面用 `session.onCommand(\"map.highlight\", fn)` 消费;\n * - 未注册 handler 的 action 会进入有限缓冲等待注册,超限后丢弃并 console 告警。\n *\n * 宿主 → 智能体方向只有三个白名单动作:attach(附件入输入框)/ insertText\n * (追加输入文本)/ send(直接发消息),对应协议层的 addContext / appendInput /\n * sendMessage。\n */\n\nexport interface CommandEnvelope {\n __bladeBridge: true\n direction: \"agent-to-host\"\n action: string\n payload: unknown\n meta: {\n sessionId: string\n toolCallId?: string\n timestamp: number\n }\n}\n\nexport type InboundAction = \"addContext\" | \"appendInput\" | \"sendMessage\"\n\nexport interface InboundEnvelope {\n __bladeBridge: true\n direction: \"host-to-agent\"\n action: InboundAction\n payload: unknown\n}\n\nexport function isCommandEnvelope(value: unknown): value is CommandEnvelope {\n if (typeof value !== \"object\" || value === null) return false\n const record = value as Record<string, unknown>\n return (\n record.__bladeBridge === true &&\n record.direction === \"agent-to-host\" &&\n typeof record.action === \"string\"\n )\n}\n\nexport function isInboundEnvelope(value: unknown): value is InboundEnvelope {\n if (typeof value !== \"object\" || value === null) return false\n const record = value as Record<string, unknown>\n return (\n record.__bladeBridge === true &&\n record.direction === \"host-to-agent\" &&\n (record.action === \"addContext\" || record.action === \"appendInput\" || record.action === \"sendMessage\")\n )\n}\n","import { CommandRegistry, type CommandHandler } from \"./registry\"\nimport { isCommandEnvelope, type InboundAction } from \"./protocol\"\n\n/**\n * iframe 嵌入形态的宿主端协作对象:当你把 Blade 的聊天页面用 iframe 嵌进\n * 自己的系统时,用它与 iframe 里的智能体互通——API 与同页嵌入的\n * AgentSession 完全一致(onCommand / attach / insertText / send)。\n *\n * action 的来源与同页形态相同:技能作者在工具返回值 JSON 的 `_meta.bridge`\n * 字段里写 `{ action, payload }`,Blade 页面检测到自己处于 iframe 中时会把\n * 它 postMessage 给宿主页面(见 docs/specs/260417-embed-bridge)。\n */\nexport interface EmbeddedChatOptions {\n /** 嵌入 Blade 页面的 iframe 元素。不传则监听来自任意子窗口的消息。 */\n iframe?: HTMLIFrameElement\n /**\n * 允许接收消息的来源(Blade 页面的 origin,如 \"https://blade.example.com\")。\n * 必填:不校验来源会让任意第三方页面伪造智能体指令。\n */\n allowedOrigins: string[]\n}\n\nexport interface EmbeddedChat {\n /** 监听智能体下发的指令(注册前到达的会缓冲补投)。返回取消函数。 */\n onCommand(action: string, handler: CommandHandler): () => void\n /** 把业务数据作为附件放进 iframe 里的聊天输入框。 */\n attach(label: string, data: unknown): void\n /** 往 iframe 里的聊天输入框追加文字。 */\n insertText(text: string): void\n /** 直接代用户发送一条消息。 */\n send(text: string): void\n /** 停止监听并释放资源。 */\n dispose(): void\n}\n\nexport function connectEmbedded(options: EmbeddedChatOptions): EmbeddedChat {\n if (typeof window === \"undefined\") {\n throw new Error(\"connectEmbedded() 只能在浏览器中使用。\")\n }\n if (!options.allowedOrigins?.length) {\n throw new Error(\n \"connectEmbedded() 需要 allowedOrigins(Blade 页面的 origin),否则无法安全接收消息。\",\n )\n }\n const registry = new CommandRegistry()\n const allowed = new Set(options.allowedOrigins)\n\n const onMessage = (event: MessageEvent) => {\n if (!allowed.has(event.origin)) return\n if (options.iframe && event.source !== options.iframe.contentWindow) return\n if (!isCommandEnvelope(event.data)) return\n registry.dispatch(event.data.action, event.data.payload, {\n toolCallId: event.data.meta?.toolCallId,\n })\n }\n window.addEventListener(\"message\", onMessage)\n\n const post = (action: InboundAction, payload: unknown) => {\n const target = options.iframe?.contentWindow\n if (!target) {\n console.warn(\"[agent-client] connectEmbedded 未绑定 iframe,无法向智能体发送消息。\")\n return\n }\n // 发往 iframe 的 targetOrigin 用配置的第一个 origin,避免 \"*\"\n target.postMessage(\n { __bladeBridge: true, direction: \"host-to-agent\", action, payload },\n options.allowedOrigins[0],\n )\n }\n\n return {\n onCommand: (action, handler) => registry.onCommand(action, handler),\n attach: (label, data) => {\n const content = typeof data === \"string\" ? data : JSON.stringify(data, null, 2)\n post(\"addContext\", { label, content })\n },\n insertText: (text) => post(\"appendInput\", { text }),\n send: (text) => post(\"sendMessage\", { text }),\n dispose: () => {\n window.removeEventListener(\"message\", onMessage)\n registry.clear()\n },\n }\n}\n","import { type } from \"arktype\"\nimport type { Solution } from \"./solution\"\n\nexport const SessionStatus = type(\n \"'created' | 'running' | 'completed' | 'failed' | 'interrupted' | 'waiting_for_input'\",\n)\nexport type SessionStatus = typeof SessionStatus.infer\n\nexport type TemplateId =\n | \"default\"\n | \"skill_editor\"\n // ship-attack v2:用户从 ship-attack 页面点\"新建 session\"创建的会话。\n // 后端 _maybe_bind_first_skill 只对此模板触发首次绑定。\n | \"ship_attack\"\n\nexport type SkillEditorTemplateId = \"skill_editor\"\n\nexport type ModeId = \"planning\" | \"executing\"\n\nexport interface ReplayState {\n source_session_id?: string\n status?: \"replay\" | \"autonomous\"\n speed?: 1 | 2 | 5\n next_source_entry_id?: string | null\n ended_at?: string | null\n autonomous_reason?: string | null\n}\n\nexport interface SessionPortMapping {\n container_port: number\n host_port: number\n}\n\n/**\n * 列表搜索时单条会话的命中信息。\n * - field='title':关键词出现在 intent 里,snippet 为 null(标题本身就在 UI 上)\n * - field='content':关键词出现在历史消息里,snippet 含截窗预览与角色\n */\nexport interface SessionSearchMatch {\n field: \"title\" | \"content\"\n snippet: { role: string; text: string } | null\n}\n\nexport const SessionInfo = type({\n id: \"string\",\n intent: \"string\",\n status: SessionStatus,\n created_at: \"string\",\n updated_at: \"string\",\n \"shared?\": \"boolean\",\n \"memory_enabled?\": \"boolean\",\n \"is_persistent?\": \"boolean\",\n \"is_headless?\": \"boolean\",\n \"viewer_role?\": \"'owner' | 'viewer'\",\n \"template_id?\": \"string | null\",\n \"model?\": \"string | null\",\n \"enable_thinking?\": \"boolean | null\",\n \"solution_id?\": \"string | null\",\n \"biz_role_id?\": \"string | null\",\n \"solution?\": \"unknown\",\n \"plan_summary?\": \"string | null\",\n \"primary_skill_id?\": \"string | null\",\n // ship-attack v2:后端 engine.set_bound_skill 写入的\"绑定 skill id\"。\n // 未绑定 / 非 ship-attack session 为 null。\n \"bound_skill_id?\": \"string | null\",\n \"replay_state?\": \"unknown\",\n \"is_pinned?\": \"boolean\",\n \"pinned_at?\": \"string | null\",\n \"is_example?\": \"boolean\",\n \"ports?\": \"unknown\",\n \"disable_tools?\": \"string[]\",\n \"runtime_type?\": \"string | null\",\n \"daemon_id?\": \"string | null\",\n \"match?\": \"unknown\",\n})\nexport type SessionInfo = Omit<\n typeof SessionInfo.infer,\n \"template_id\" | \"solution\" | \"ports\" | \"match\"\n> & {\n shared?: boolean\n memory_enabled?: boolean\n is_persistent?: boolean\n is_headless?: boolean\n viewer_role?: \"owner\" | \"viewer\"\n template_id?: TemplateId | null\n model?: string | null\n enable_thinking?: boolean | null\n solution_id?: string | null\n biz_role_id?: string | null\n solution?: Solution | null\n primary_skill_id?: string | null\n bound_skill_id?: string | null\n replay_state?: ReplayState | null\n is_pinned?: boolean\n pinned_at?: string | null\n is_example?: boolean\n ports?: SessionPortMapping[]\n disable_tools?: string[]\n runtime_type?: \"sandbox\" | \"daemon\" | string | null\n daemon_id?: string | null\n /** 仅在带 q 搜索的列表响应中出现;普通列表里此字段缺省。 */\n match?: SessionSearchMatch | null\n}\n\n/**\n * 主 skill 配置快照(v2)。创建 session 时从 SKILL.md frontmatter 抽出并\n * 固化到 session_root/.blade/primary-skill.json;ship-attack 页面骨架的唯\n * 一数据源。\n */\nexport interface PrimarySkillStepSpec {\n n: number\n label: string\n}\n\nexport interface PrimarySkillStageSpec {\n id: string\n name: string\n steps: PrimarySkillStepSpec[]\n}\n\nexport interface PrimarySkillParallelMode {\n id: string\n name: string\n prompt_hint: string\n}\n\nexport interface PrimarySkillSnapshot {\n version: number\n skill_id: string\n title: string\n description: string\n stages: PrimarySkillStageSpec[]\n parallel_modes: PrimarySkillParallelMode[]\n captured_at: string\n}\n\n/**\n * 单 session detail(GET /api/sessions/:id)。列表接口返回 SessionInfo,\n * detail 在此基础上附加 primary_skill_snapshot。\n */\nexport interface SessionDetail extends SessionInfo {\n primary_skill_snapshot?: PrimarySkillSnapshot | null\n preview_url?: string | null\n /**\n * 会话级环境变量(owner-only)。后端仅在 GET detail 和 PUT /env 响应中返回,\n * 列表/搜索响应不带此字段。调用 setSessionEnv 后可类型安全地读回。\n */\n env?: Record<string, string>\n}\n","export enum LayoutType {\n Default = \"default\",\n SkillEditor = \"skill-editor\",\n BladeCoa = \"blade-coa\",\n SolutionEditor = \"solution-editor\",\n SolutionEditor2 = \"solution-editor2\",\n ChatPreview = \"chat-preview\",\n ChatOnly = \"chat-only\",\n SolutionApp = \"solution-app\",\n Custom = \"custom\",\n}\n\nexport interface Solution {\n id: string\n name: string\n version: string\n description?: string | null\n source?: \"builtin\" | \"personal\" | string | null\n layout_type: LayoutType | string\n initial_mode?: \"planning\" | \"executing\" | string | null\n initial_message?: string | null\n preview?: { url: string; title?: string | null } | null\n layout?: {\n available?: boolean\n source_dir?: string\n entry?: string\n export?: string\n } | null\n roles?: BizRole[] | null\n data?: Record<string, unknown> | null\n ui_config?: SolutionAppUiConfig | null\n}\n\nexport interface SolutionAppUiConfig {\n branding: {\n name: string\n subtitle?: string\n icon_text: string\n icon_gradient?: string\n }\n list: {\n title: string\n create_button: string\n card?: {\n subtitle?: string\n stats?: Array<{\n label: string\n value: string\n color?: string\n }>\n }\n }\n create: {\n title: string\n description?: string\n submit_button: string\n sections: Array<{\n id: string\n title: string\n description?: string\n fields: Array<SolutionAppField>\n }>\n }\n}\n\nexport type SolutionAppField =\n | {\n id: string\n kind: \"textarea\"\n label: string\n placeholder?: string\n }\n | {\n id: string\n kind: \"file-upload\"\n accept?: string[]\n categories?: Array<{\n label: string\n description: string\n color: string\n }>\n }\n\nexport interface SolutionAppState {\n pipeline: Array<{\n id: string\n label: string\n status: \"done\" | \"active\" | \"pending\" | \"error\"\n }>\n meta: Record<\n string,\n {\n label: string\n value: string\n color?: string\n }\n >\n}\n\nexport interface BizRole {\n id: string\n name: string\n description?: string | null\n preview?: { url: string; title?: string | null } | null\n}\n","import { type } from \"arktype\"\n\nexport const TaskStatus = type(\"'pending' | 'in_progress' | 'done' | 'failed' | 'skipped'\")\nexport type TaskStatus = typeof TaskStatus.infer\n\nexport const Task = type({\n id: \"string\",\n goal: \"string\",\n skills: \"string[]\",\n depends_on: \"string[]\",\n status: TaskStatus,\n result_summary: \"string\",\n number: \"string\",\n})\nexport type Task = typeof Task.infer\n"],"mappings":"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","names":["toolCallId","isRecord","type","attachments","contexts","isRecord","buildMessageContent","toolCall","isRecord","handle","LayoutType","type"]}