agentengine-sdk-python 0.6.4__py3-none-any.whl → 0.7.0__py3-none-any.whl

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 (486) hide show
  1. agentengine_sdk_python-0.7.0.dist-info/METADATA +181 -0
  2. agentengine_sdk_python-0.7.0.dist-info/RECORD +482 -0
  3. {agentengine_sdk_python-0.6.4.dist-info → agentengine_sdk_python-0.7.0.dist-info}/WHEEL +1 -1
  4. agentengine_sdk_python-0.7.0.dist-info/entry_points.txt +3 -0
  5. agentengine_sdk_python-0.7.0.dist-info/licenses/LICENSE +175 -0
  6. agentengine_sdk_python-0.7.0.dist-info/top_level.txt +2 -0
  7. ksadk/__init__.py +13 -0
  8. ksadk/__main__.py +4 -0
  9. ksadk/a2a/__init__.py +15 -0
  10. ksadk/a2a/card_builder.py +64 -0
  11. ksadk/a2a/client.py +309 -0
  12. ksadk/a2a/executor.py +201 -0
  13. ksadk/a2a/server.py +79 -0
  14. ksadk/agents/__init__.py +20 -0
  15. ksadk/agents/base.py +370 -0
  16. ksadk/agents/context.py +38 -0
  17. ksadk/agents/event.py +35 -0
  18. ksadk/agents/loop_agent.py +71 -0
  19. ksadk/agents/parallel_agent.py +109 -0
  20. ksadk/agents/runner_adapter.py +24 -0
  21. ksadk/agents/sequential_agent.py +34 -0
  22. ksadk/api/__init__.py +3 -0
  23. ksadk/api/client.py +2246 -0
  24. ksadk/builders/__init__.py +20 -0
  25. ksadk/builders/base.py +66 -0
  26. ksadk/builders/code_builder.py +1990 -0
  27. ksadk/builders/container_builder.py +786 -0
  28. ksadk/builders/framework_requirements.py +59 -0
  29. ksadk/builders/ks3_uploader.py +389 -0
  30. ksadk/builders/mcp_builder.py +476 -0
  31. ksadk/builders/requirements_utils.py +75 -0
  32. ksadk/cli/__init__.py +531 -0
  33. ksadk/cli/__main__.py +4 -0
  34. ksadk/cli/agent_ref.py +204 -0
  35. ksadk/cli/cmd_a2a.py +167 -0
  36. ksadk/cli/cmd_agent.py +201 -0
  37. ksadk/cli/cmd_build.py +270 -0
  38. ksadk/cli/cmd_completion.py +304 -0
  39. ksadk/cli/cmd_config.py +758 -0
  40. ksadk/cli/cmd_create.py +2304 -0
  41. ksadk/cli/cmd_dashboard.py +900 -0
  42. ksadk/cli/cmd_deploy.py +704 -0
  43. ksadk/cli/cmd_destroy.py +345 -0
  44. ksadk/cli/cmd_files.py +1227 -0
  45. ksadk/cli/cmd_hermes.py +1263 -0
  46. ksadk/cli/cmd_invoke.py +1503 -0
  47. ksadk/cli/cmd_launch.py +564 -0
  48. ksadk/cli/cmd_mcp.py +1179 -0
  49. ksadk/cli/cmd_model.py +302 -0
  50. ksadk/cli/cmd_openclaw.py +3922 -0
  51. ksadk/cli/cmd_run.py +239 -0
  52. ksadk/cli/cmd_status.py +588 -0
  53. ksadk/cli/cmd_version.py +522 -0
  54. ksadk/cli/cmd_web.py +288 -0
  55. ksadk/cli/deploy_utils.py +87 -0
  56. ksadk/cli/dry_run.py +214 -0
  57. ksadk/cli/env_options.py +82 -0
  58. ksadk/cli/error_utils.py +525 -0
  59. ksadk/cli/global_options.py +31 -0
  60. ksadk/cli/local_runtime.py +97 -0
  61. ksadk/cli/model_catalog.py +136 -0
  62. ksadk/cli/network_options.py +412 -0
  63. ksadk/cli/resource_common.py +621 -0
  64. ksadk/cli/storage.py +84 -0
  65. ksadk/cli/ui.py +431 -0
  66. ksadk/cli/workflow_common.py +552 -0
  67. ksadk/common/__init__.py +14 -0
  68. ksadk/common/aicp_env.py +128 -0
  69. ksadk/common/auth.py +190 -0
  70. ksadk/common/constants.py +84 -0
  71. ksadk/common/llm_utils.py +61 -0
  72. ksadk/configs/__init__.py +61 -0
  73. ksadk/configs/env_registry.py +343 -0
  74. ksadk/configs/global_config.py +200 -0
  75. ksadk/configs/settings.py +706 -0
  76. ksadk/conversations/__init__.py +95 -0
  77. ksadk/conversations/attachment_storage.py +379 -0
  78. ksadk/conversations/attachments.py +774 -0
  79. ksadk/conversations/compaction_pipeline.py +387 -0
  80. ksadk/conversations/compaction_prompt.py +128 -0
  81. ksadk/conversations/context.py +303 -0
  82. ksadk/conversations/message_projection.py +269 -0
  83. ksadk/conversations/model_context.py +370 -0
  84. ksadk/conversations/model_options.py +136 -0
  85. ksadk/conversations/normalize.py +446 -0
  86. ksadk/conversations/reasoning_markup.py +91 -0
  87. ksadk/conversations/run_kinds.py +61 -0
  88. ksadk/conversations/run_status.py +53 -0
  89. ksadk/conversations/runtime.py +5276 -0
  90. ksadk/conversations/semantic_summary.py +359 -0
  91. ksadk/conversations/session_title.py +254 -0
  92. ksadk/deployment/__init__.py +83 -0
  93. ksadk/deployment/agent_access.py +226 -0
  94. ksadk/deployment/base.py +229 -0
  95. ksadk/deployment/manager.py +332 -0
  96. ksadk/deployment/providers/__init__.py +10 -0
  97. ksadk/deployment/providers/serverless.py +1115 -0
  98. ksadk/deployment/registry.py +120 -0
  99. ksadk/deployment/state.py +78 -0
  100. ksadk/deployment/ui_config.py +21 -0
  101. ksadk/detection/__init__.py +7 -0
  102. ksadk/detection/detector.py +431 -0
  103. ksadk/detection/mcp_detector.py +250 -0
  104. ksadk/hermes_terminal.py +467 -0
  105. ksadk/identity/__init__.py +17 -0
  106. ksadk/identity/resolver.py +385 -0
  107. ksadk/knowledge_base/__init__.py +62 -0
  108. ksadk/knowledge_base/adk_tool.py +47 -0
  109. ksadk/knowledge_base/client.py +297 -0
  110. ksadk/knowledge_base/langchain_tool.py +55 -0
  111. ksadk/knowledge_base/service.py +66 -0
  112. ksadk/knowledge_base/tool.py +50 -0
  113. ksadk/markdown.py +169 -0
  114. ksadk/mcp_runtime/__init__.py +231 -0
  115. ksadk/memory/__init__.py +57 -0
  116. ksadk/memory/adk/__init__.py +51 -0
  117. ksadk/memory/adk/backends/__init__.py +5 -0
  118. ksadk/memory/adk/backends/base_ltm_backend.py +52 -0
  119. ksadk/memory/adk/backends/http_ltm_backend.py +183 -0
  120. ksadk/memory/adk/backends/inmemory_ltm_backend.py +96 -0
  121. ksadk/memory/adk/backends/sdk_ltm_backend.py +456 -0
  122. ksadk/memory/adk/long_term_memory.py +273 -0
  123. ksadk/memory/adk/resilient_session_service.py +268 -0
  124. ksadk/memory/adk/short_term_memory.py +304 -0
  125. ksadk/memory/adk_tool.py +31 -0
  126. ksadk/memory/backends/__init__.py +6 -0
  127. ksadk/memory/backends/base.py +103 -0
  128. ksadk/memory/backends/memory.py +112 -0
  129. ksadk/memory/backends/redis.py +146 -0
  130. ksadk/memory/langchain_tool.py +39 -0
  131. ksadk/memory/ltm_backend_factory.py +24 -0
  132. ksadk/memory/manager.py +215 -0
  133. ksadk/memory/service.py +172 -0
  134. ksadk/memory/tool.py +96 -0
  135. ksadk/model_policy.py +223 -0
  136. ksadk/openclaw_gateway.py +378 -0
  137. ksadk/runners/__init__.py +8 -0
  138. ksadk/runners/adk_runner.py +1994 -0
  139. ksadk/runners/base_runner.py +305 -0
  140. ksadk/runners/deepagents_runner.py +13 -0
  141. ksadk/runners/factory.py +73 -0
  142. ksadk/runners/langchain_runner.py +751 -0
  143. ksadk/runners/langgraph_runner.py +985 -0
  144. ksadk/runners/patch_langchain.py +187 -0
  145. ksadk/runners/remote_runner.py +792 -0
  146. ksadk/runners/usage_accumulator.py +38 -0
  147. ksadk/runners/utils/__init__.py +19 -0
  148. ksadk/runners/utils/langfuse.py +230 -0
  149. ksadk/runners/utils/loader.py +62 -0
  150. ksadk/runtime_context.py +166 -0
  151. ksadk/runtime_state.py +25 -0
  152. ksadk/sandbox/__init__.py +28 -0
  153. ksadk/sandbox/backends/__init__.py +9 -0
  154. ksadk/sandbox/backends/e2b.py +154 -0
  155. ksadk/sandbox/backends/local_process.py +131 -0
  156. ksadk/sandbox/base.py +101 -0
  157. ksadk/sandbox/factory.py +53 -0
  158. ksadk/sandbox/registry.py +187 -0
  159. ksadk/server/__init__.py +7 -0
  160. ksadk/server/api_models.py +73 -0
  161. ksadk/server/app.py +3931 -0
  162. ksadk/server/static/assets/ArtifactsPanel-D-SSn2ee.js +1 -0
  163. ksadk/server/static/assets/CodeBlock-P16VOLYi.js +9 -0
  164. ksadk/server/static/assets/KaTeX_AMS-Regular-BQhdFMY1.woff2 +0 -0
  165. ksadk/server/static/assets/KaTeX_AMS-Regular-DMm9YOAa.woff +0 -0
  166. ksadk/server/static/assets/KaTeX_AMS-Regular-DRggAlZN.ttf +0 -0
  167. ksadk/server/static/assets/KaTeX_Caligraphic-Bold-ATXxdsX0.ttf +0 -0
  168. ksadk/server/static/assets/KaTeX_Caligraphic-Bold-BEiXGLvX.woff +0 -0
  169. ksadk/server/static/assets/KaTeX_Caligraphic-Bold-Dq_IR9rO.woff2 +0 -0
  170. ksadk/server/static/assets/KaTeX_Caligraphic-Regular-CTRA-rTL.woff +0 -0
  171. ksadk/server/static/assets/KaTeX_Caligraphic-Regular-Di6jR-x-.woff2 +0 -0
  172. ksadk/server/static/assets/KaTeX_Caligraphic-Regular-wX97UBjC.ttf +0 -0
  173. ksadk/server/static/assets/KaTeX_Fraktur-Bold-BdnERNNW.ttf +0 -0
  174. ksadk/server/static/assets/KaTeX_Fraktur-Bold-BsDP51OF.woff +0 -0
  175. ksadk/server/static/assets/KaTeX_Fraktur-Bold-CL6g_b3V.woff2 +0 -0
  176. ksadk/server/static/assets/KaTeX_Fraktur-Regular-CB_wures.ttf +0 -0
  177. ksadk/server/static/assets/KaTeX_Fraktur-Regular-CTYiF6lA.woff2 +0 -0
  178. ksadk/server/static/assets/KaTeX_Fraktur-Regular-Dxdc4cR9.woff +0 -0
  179. ksadk/server/static/assets/KaTeX_Main-Bold-Cx986IdX.woff2 +0 -0
  180. ksadk/server/static/assets/KaTeX_Main-Bold-Jm3AIy58.woff +0 -0
  181. ksadk/server/static/assets/KaTeX_Main-Bold-waoOVXN0.ttf +0 -0
  182. ksadk/server/static/assets/KaTeX_Main-BoldItalic-DxDJ3AOS.woff2 +0 -0
  183. ksadk/server/static/assets/KaTeX_Main-BoldItalic-DzxPMmG6.ttf +0 -0
  184. ksadk/server/static/assets/KaTeX_Main-BoldItalic-SpSLRI95.woff +0 -0
  185. ksadk/server/static/assets/KaTeX_Main-Italic-3WenGoN9.ttf +0 -0
  186. ksadk/server/static/assets/KaTeX_Main-Italic-BMLOBm91.woff +0 -0
  187. ksadk/server/static/assets/KaTeX_Main-Italic-NWA7e6Wa.woff2 +0 -0
  188. ksadk/server/static/assets/KaTeX_Main-Regular-B22Nviop.woff2 +0 -0
  189. ksadk/server/static/assets/KaTeX_Main-Regular-Dr94JaBh.woff +0 -0
  190. ksadk/server/static/assets/KaTeX_Main-Regular-ypZvNtVU.ttf +0 -0
  191. ksadk/server/static/assets/KaTeX_Math-BoldItalic-B3XSjfu4.ttf +0 -0
  192. ksadk/server/static/assets/KaTeX_Math-BoldItalic-CZnvNsCZ.woff2 +0 -0
  193. ksadk/server/static/assets/KaTeX_Math-BoldItalic-iY-2wyZ7.woff +0 -0
  194. ksadk/server/static/assets/KaTeX_Math-Italic-DA0__PXp.woff +0 -0
  195. ksadk/server/static/assets/KaTeX_Math-Italic-flOr_0UB.ttf +0 -0
  196. ksadk/server/static/assets/KaTeX_Math-Italic-t53AETM-.woff2 +0 -0
  197. ksadk/server/static/assets/KaTeX_SansSerif-Bold-CFMepnvq.ttf +0 -0
  198. ksadk/server/static/assets/KaTeX_SansSerif-Bold-D1sUS0GD.woff2 +0 -0
  199. ksadk/server/static/assets/KaTeX_SansSerif-Bold-DbIhKOiC.woff +0 -0
  200. ksadk/server/static/assets/KaTeX_SansSerif-Italic-C3H0VqGB.woff2 +0 -0
  201. ksadk/server/static/assets/KaTeX_SansSerif-Italic-DN2j7dab.woff +0 -0
  202. ksadk/server/static/assets/KaTeX_SansSerif-Italic-YYjJ1zSn.ttf +0 -0
  203. ksadk/server/static/assets/KaTeX_SansSerif-Regular-BNo7hRIc.ttf +0 -0
  204. ksadk/server/static/assets/KaTeX_SansSerif-Regular-CS6fqUqJ.woff +0 -0
  205. ksadk/server/static/assets/KaTeX_SansSerif-Regular-DDBCnlJ7.woff2 +0 -0
  206. ksadk/server/static/assets/KaTeX_Script-Regular-C5JkGWo-.ttf +0 -0
  207. ksadk/server/static/assets/KaTeX_Script-Regular-D3wIWfF6.woff2 +0 -0
  208. ksadk/server/static/assets/KaTeX_Script-Regular-D5yQViql.woff +0 -0
  209. ksadk/server/static/assets/KaTeX_Size1-Regular-C195tn64.woff +0 -0
  210. ksadk/server/static/assets/KaTeX_Size1-Regular-Dbsnue_I.ttf +0 -0
  211. ksadk/server/static/assets/KaTeX_Size1-Regular-mCD8mA8B.woff2 +0 -0
  212. ksadk/server/static/assets/KaTeX_Size2-Regular-B7gKUWhC.ttf +0 -0
  213. ksadk/server/static/assets/KaTeX_Size2-Regular-Dy4dx90m.woff2 +0 -0
  214. ksadk/server/static/assets/KaTeX_Size2-Regular-oD1tc_U0.woff +0 -0
  215. ksadk/server/static/assets/KaTeX_Size3-Regular-CTq5MqoE.woff +0 -0
  216. ksadk/server/static/assets/KaTeX_Size3-Regular-DgpXs0kz.ttf +0 -0
  217. ksadk/server/static/assets/KaTeX_Size4-Regular-BF-4gkZK.woff +0 -0
  218. ksadk/server/static/assets/KaTeX_Size4-Regular-DWFBv043.ttf +0 -0
  219. ksadk/server/static/assets/KaTeX_Size4-Regular-Dl5lxZxV.woff2 +0 -0
  220. ksadk/server/static/assets/KaTeX_Typewriter-Regular-C0xS9mPB.woff +0 -0
  221. ksadk/server/static/assets/KaTeX_Typewriter-Regular-CO6r4hn1.woff2 +0 -0
  222. ksadk/server/static/assets/KaTeX_Typewriter-Regular-D3Ib7_Hf.ttf +0 -0
  223. ksadk/server/static/assets/MathMessageMarkdown-CdGiQWHR.js +8 -0
  224. ksadk/server/static/assets/MathMessageMarkdown-DeYh8QPr.css +1 -0
  225. ksadk/server/static/assets/MermaidBlock-IOcal8cm.js +303 -0
  226. ksadk/server/static/assets/NativeTerminalPanel-CHOd7Rch.css +1 -0
  227. ksadk/server/static/assets/NativeTerminalPanel-DGSDWsei.js +1 -0
  228. ksadk/server/static/assets/addon-fit-DthTIhi3.js +1 -0
  229. ksadk/server/static/assets/apl-CnwPGSsG.js +1 -0
  230. ksadk/server/static/assets/arc-BA13sHc9.js +1 -0
  231. ksadk/server/static/assets/architecture-7EHR7CIX-BvUlsA6l.js +1 -0
  232. ksadk/server/static/assets/architectureDiagram-3BPJPVTR-DzJzgVoL.js +36 -0
  233. ksadk/server/static/assets/asciiarmor-qTkVPQu6.js +1 -0
  234. ksadk/server/static/assets/asn1-Dr8qZg38.js +1 -0
  235. ksadk/server/static/assets/asterisk-Bja0s6e1.js +1 -0
  236. ksadk/server/static/assets/blockDiagram-GPEHLZMM-UTdVcZhn.js +132 -0
  237. ksadk/server/static/assets/brainfuck-D5EjA2JK.js +1 -0
  238. ksadk/server/static/assets/c4Diagram-AAUBKEIU-Dix0GD4m.js +10 -0
  239. ksadk/server/static/assets/channel-CTuydARX.js +1 -0
  240. ksadk/server/static/assets/chunk-2J33WTMH-C2JxuZ42.js +1 -0
  241. ksadk/server/static/assets/chunk-4BX2VUAB-Be57QPgD.js +1 -0
  242. ksadk/server/static/assets/chunk-55IACEB6-WjSuy4nv.js +1 -0
  243. ksadk/server/static/assets/chunk-727SXJPM-BOovP-b5.js +206 -0
  244. ksadk/server/static/assets/chunk-AQP2D5EJ-DOmZNmWj.js +231 -0
  245. ksadk/server/static/assets/chunk-FMBD7UC4-DzwlodkU.js +15 -0
  246. ksadk/server/static/assets/chunk-ND2GUHAM-DMqAikEU.js +1 -0
  247. ksadk/server/static/assets/chunk-QZHKN3VN-BnCydivS.js +1 -0
  248. ksadk/server/static/assets/classDiagram-4FO5ZUOK-BNHg45Be.js +1 -0
  249. ksadk/server/static/assets/classDiagram-v2-Q7XG4LA2-BNHg45Be.js +1 -0
  250. ksadk/server/static/assets/clike-DHH8Ad3s.js +1 -0
  251. ksadk/server/static/assets/clojure-BflJGmDX.js +1 -0
  252. ksadk/server/static/assets/cmake-CyVbuzPu.js +1 -0
  253. ksadk/server/static/assets/cobol-B_OZ4V-R.js +1 -0
  254. ksadk/server/static/assets/coffeescript-B2pKbFk8.js +1 -0
  255. ksadk/server/static/assets/commonlisp-CcllspGY.js +1 -0
  256. ksadk/server/static/assets/cose-bilkent-S5V4N54A-Zhy2GBnP.js +1 -0
  257. ksadk/server/static/assets/crystal-M5-qzICs.js +1 -0
  258. ksadk/server/static/assets/css-CYpP4FRV.js +1 -0
  259. ksadk/server/static/assets/cypher-p9eYesGn.js +1 -0
  260. ksadk/server/static/assets/cytoscape.esm-DelgaX4f.js +321 -0
  261. ksadk/server/static/assets/d-BhMjBjQP.js +1 -0
  262. ksadk/server/static/assets/dagre-BM42HDAG-CbKrtIUz.js +4 -0
  263. ksadk/server/static/assets/dagre-Bx709z4p.js +1 -0
  264. ksadk/server/static/assets/defaultLocale-C8Fc0cco.js +1 -0
  265. ksadk/server/static/assets/diagram-2AECGRRQ-BRApgQRK.js +43 -0
  266. ksadk/server/static/assets/diagram-5GNKFQAL-D0xbnDiK.js +10 -0
  267. ksadk/server/static/assets/diagram-KO2AKTUF-CVugVI9L.js +3 -0
  268. ksadk/server/static/assets/diagram-LMA3HP47-DozUGgee.js +24 -0
  269. ksadk/server/static/assets/diagram-OG6HWLK6-ZOYsKlru.js +24 -0
  270. ksadk/server/static/assets/diff-ChtP43wD.js +1 -0
  271. ksadk/server/static/assets/dist-2hInLS_J.js +9 -0
  272. ksadk/server/static/assets/dist-8EEyGgDx.js +1 -0
  273. ksadk/server/static/assets/dist-8_SfK1IP.js +1 -0
  274. ksadk/server/static/assets/dist-B0NP_Z0z.js +23 -0
  275. ksadk/server/static/assets/dist-BIJVDMuB.js +1 -0
  276. ksadk/server/static/assets/dist-BmlMPsCc.js +2 -0
  277. ksadk/server/static/assets/dist-BrCcQ47T.js +1 -0
  278. ksadk/server/static/assets/dist-BssVmjIo.js +6 -0
  279. ksadk/server/static/assets/dist-C3HIIaN5.js +1 -0
  280. ksadk/server/static/assets/dist-CPBtqRTW.js +1 -0
  281. ksadk/server/static/assets/dist-CkEKJFtk.js +1 -0
  282. ksadk/server/static/assets/dist-D-JMdWPQ.js +1 -0
  283. ksadk/server/static/assets/dist-D-xOD048.js +1 -0
  284. ksadk/server/static/assets/dist-D57wnGWd.js +1 -0
  285. ksadk/server/static/assets/dist-DL_NKc_z.js +1 -0
  286. ksadk/server/static/assets/dist-DMezvBGJ.js +1 -0
  287. ksadk/server/static/assets/dist-DmFaq_Iy.js +1 -0
  288. ksadk/server/static/assets/dist-Dp0k7bWI.js +1 -0
  289. ksadk/server/static/assets/dist-DpKtt4Bo.js +1 -0
  290. ksadk/server/static/assets/dist-DyOkZmze.js +11 -0
  291. ksadk/server/static/assets/dist-DyWsb78Q.js +1 -0
  292. ksadk/server/static/assets/dist-gX6GOLKq.js +1 -0
  293. ksadk/server/static/assets/dockerfile-BLkNEvjs.js +1 -0
  294. ksadk/server/static/assets/dtd-DTF72YNO.js +1 -0
  295. ksadk/server/static/assets/dylan-C6jEEEk-.js +1 -0
  296. ksadk/server/static/assets/ebnf-D4c0_ac3.js +1 -0
  297. ksadk/server/static/assets/ecl-BSZaIHnp.js +1 -0
  298. ksadk/server/static/assets/eiffel-BEjRio4Q.js +1 -0
  299. ksadk/server/static/assets/elm-Cshzl8qu.js +1 -0
  300. ksadk/server/static/assets/erDiagram-TEJ5UH35-Bk-9bgE5.js +85 -0
  301. ksadk/server/static/assets/erlang-DaB2Rkuy.js +1 -0
  302. ksadk/server/static/assets/eventmodeling-FCH6USID-DsAgWnlf.js +1 -0
  303. ksadk/server/static/assets/factor-D7LVTn2l.js +1 -0
  304. ksadk/server/static/assets/fcl-ClOhbFR7.js +1 -0
  305. ksadk/server/static/assets/flowDiagram-I6XJVG4X-Dn9kZVuZ.js +162 -0
  306. ksadk/server/static/assets/forth-Cezjo90N.js +1 -0
  307. ksadk/server/static/assets/fortran-Bt6PBEDR.js +1 -0
  308. ksadk/server/static/assets/ganttDiagram-6RSMTGT7-BGxXlJqm.js +292 -0
  309. ksadk/server/static/assets/gas-BHEdbvp9.js +1 -0
  310. ksadk/server/static/assets/gherkin-oBAE_ms0.js +1 -0
  311. ksadk/server/static/assets/gitGraph-WXDBUCRP-BIao9Yjg.js +1 -0
  312. ksadk/server/static/assets/gitGraphDiagram-PVQCEYII-C7Q0X-wi.js +106 -0
  313. ksadk/server/static/assets/graphlib-B8gBHxth.js +1 -0
  314. ksadk/server/static/assets/groovy-BC3IOsC8.js +1 -0
  315. ksadk/server/static/assets/haskell-BRsoo5mP.js +1 -0
  316. ksadk/server/static/assets/haxe-DIz0ZZqd.js +1 -0
  317. ksadk/server/static/assets/http-CLVgA2GD.js +1 -0
  318. ksadk/server/static/assets/idl-BUZw3wgd.js +1 -0
  319. ksadk/server/static/assets/index-C00Lwg3L.js +165 -0
  320. ksadk/server/static/assets/index-DAURbCsP.css +1 -0
  321. ksadk/server/static/assets/info-J43DQDTF-CyipqGxU.js +1 -0
  322. ksadk/server/static/assets/infoDiagram-5YYISTIA-BO_CSqq5.js +2 -0
  323. ksadk/server/static/assets/init-D6jRqBbL.js +1 -0
  324. ksadk/server/static/assets/ishikawaDiagram-YF4QCWOH-eYLPLd46.js +70 -0
  325. ksadk/server/static/assets/javascript-9Tg8ixDm.js +1 -0
  326. ksadk/server/static/assets/journeyDiagram-JHISSGLW-De9geSb0.js +139 -0
  327. ksadk/server/static/assets/julia-CQfgDRfP.js +1 -0
  328. ksadk/server/static/assets/kanban-definition-UN3LZRKU-Cs80kQto.js +89 -0
  329. ksadk/server/static/assets/katex-DSrCFD8n.js +265 -0
  330. ksadk/server/static/assets/linear-CN9sbKTF.js +1 -0
  331. ksadk/server/static/assets/livescript-BXxG0Yva.js +1 -0
  332. ksadk/server/static/assets/lua-CiA1ziua.js +1 -0
  333. ksadk/server/static/assets/mathematica-u8YMmbU0.js +1 -0
  334. ksadk/server/static/assets/mbox-BEMVcqjs.js +1 -0
  335. ksadk/server/static/assets/mermaid-parser.core-DlgSBU8l.js +161 -0
  336. ksadk/server/static/assets/mindmap-definition-RKZ34NQL-9afz7Oug.js +96 -0
  337. ksadk/server/static/assets/mirc-C9zpzAZU.js +1 -0
  338. ksadk/server/static/assets/mllike-B45xgp2S.js +1 -0
  339. ksadk/server/static/assets/modelica-CqHI_q-D.js +1 -0
  340. ksadk/server/static/assets/mscgen-qgSLujhx.js +1 -0
  341. ksadk/server/static/assets/mumps-CW_TBmxz.js +1 -0
  342. ksadk/server/static/assets/nginx-BMaDbqW3.js +1 -0
  343. ksadk/server/static/assets/nsis-AQ_alPln.js +1 -0
  344. ksadk/server/static/assets/ntriples-d28e9m0E.js +1 -0
  345. ksadk/server/static/assets/octave-D2Q8cUp1.js +1 -0
  346. ksadk/server/static/assets/ordinal-hYBb2elL.js +1 -0
  347. ksadk/server/static/assets/oz-BwTct_5T.js +1 -0
  348. ksadk/server/static/assets/packet-YPE3B663-CGkyRxlg.js +1 -0
  349. ksadk/server/static/assets/pascal-Dp_KdFgX.js +1 -0
  350. ksadk/server/static/assets/perl-CdEHsPfU.js +1 -0
  351. ksadk/server/static/assets/pie-LRSECV5Y-M0uWAf4n.js +1 -0
  352. ksadk/server/static/assets/pieDiagram-4H26LBE5-DPv_VstN.js +30 -0
  353. ksadk/server/static/assets/pig-AF4Hwhju.js +1 -0
  354. ksadk/server/static/assets/powershell-CzG71I4L.js +1 -0
  355. ksadk/server/static/assets/properties-C357ku5U.js +1 -0
  356. ksadk/server/static/assets/protobuf-D1ij_kNL.js +1 -0
  357. ksadk/server/static/assets/pug-Bugr-47h.js +1 -0
  358. ksadk/server/static/assets/puppet-B4hC2X4m.js +1 -0
  359. ksadk/server/static/assets/python-BqYw9LYJ.js +1 -0
  360. ksadk/server/static/assets/q-B9NhS7L_.js +1 -0
  361. ksadk/server/static/assets/quadrantDiagram-W4KKPZXB-o77wZ1XK.js +7 -0
  362. ksadk/server/static/assets/r-DADKenSm.js +1 -0
  363. ksadk/server/static/assets/radar-GUYGQ44K-Bdbm24-x.js +1 -0
  364. ksadk/server/static/assets/requirementDiagram-4Y6WPE33-BYVw81VC.js +84 -0
  365. ksadk/server/static/assets/rpm-gpDK5sbt.js +1 -0
  366. ksadk/server/static/assets/ruby-DsYpTuWg.js +1 -0
  367. ksadk/server/static/assets/sankeyDiagram-5OEKKPKP-B7nZFMKT.js +40 -0
  368. ksadk/server/static/assets/sas-C2OyD2Y6.js +1 -0
  369. ksadk/server/static/assets/scheme-CyDdOh7e.js +1 -0
  370. ksadk/server/static/assets/sequenceDiagram-3UESZ5HK-BGRRrFw5.js +162 -0
  371. ksadk/server/static/assets/shell-Du5Qg9im.js +1 -0
  372. ksadk/server/static/assets/sieve-BAxa3IjF.js +1 -0
  373. ksadk/server/static/assets/simple-mode-DRpGK0lJ.js +1 -0
  374. ksadk/server/static/assets/smalltalk-BLp5-jwC.js +1 -0
  375. ksadk/server/static/assets/solr-BBopId9w.js +1 -0
  376. ksadk/server/static/assets/sparql-Dz-mlCAC.js +1 -0
  377. ksadk/server/static/assets/spreadsheet-CTIncYxj.js +1 -0
  378. ksadk/server/static/assets/sql-DcCJ9jop.js +1 -0
  379. ksadk/server/static/assets/stateDiagram-AJRCARHV-BUfHCoPs.js +1 -0
  380. ksadk/server/static/assets/stateDiagram-v2-BHNVJYJU-8xBN_gLM.js +1 -0
  381. ksadk/server/static/assets/stex-sDrdk2BW.js +1 -0
  382. ksadk/server/static/assets/stylus-DLLZ8dgm.js +1 -0
  383. ksadk/server/static/assets/swift-DKB6_1j6.js +1 -0
  384. ksadk/server/static/assets/tcl-BGfruO1u.js +1 -0
  385. ksadk/server/static/assets/textile-DWBqthVk.js +1 -0
  386. ksadk/server/static/assets/tiddlywiki-VlUiK86J.js +1 -0
  387. ksadk/server/static/assets/tiki-CxVlf5KZ.js +1 -0
  388. ksadk/server/static/assets/timeline-definition-PNZ67QCA-FbCTGrf9.js +120 -0
  389. ksadk/server/static/assets/toml-LvoKBwCs.js +1 -0
  390. ksadk/server/static/assets/treeView-BLDUP644-npMo0ak1.js +1 -0
  391. ksadk/server/static/assets/treemap-LRROVOQU-CHdzrrdo.js +1 -0
  392. ksadk/server/static/assets/troff-C2dAgh7P.js +1 -0
  393. ksadk/server/static/assets/ttcn-BePYh-hG.js +1 -0
  394. ksadk/server/static/assets/ttcn-cfg-CY0aot7Q.js +1 -0
  395. ksadk/server/static/assets/turtle-BDLWE2cD.js +1 -0
  396. ksadk/server/static/assets/vb-BthdM_4N.js +1 -0
  397. ksadk/server/static/assets/vbscript-D9f6rSsU.js +1 -0
  398. ksadk/server/static/assets/velocity-CqftRsjg.js +1 -0
  399. ksadk/server/static/assets/vennDiagram-CIIHVFJN-DWgwtPsJ.js +34 -0
  400. ksadk/server/static/assets/verilog-D-x6ne0Z.js +1 -0
  401. ksadk/server/static/assets/vhdl-CMrOq2q1.js +1 -0
  402. ksadk/server/static/assets/wardley-L42UT6IY-BEQz7wyy.js +1 -0
  403. ksadk/server/static/assets/wardleyDiagram-YWT4CUSO-2x8G-tTM.js +78 -0
  404. ksadk/server/static/assets/webidl-D5jiJvOU.js +1 -0
  405. ksadk/server/static/assets/xquery-fj_R-kMw.js +1 -0
  406. ksadk/server/static/assets/xterm-DooSxjI5.js +36 -0
  407. ksadk/server/static/assets/xychartDiagram-2RQKCTM6-Drma3AYl.js +7 -0
  408. ksadk/server/static/assets/yacas-CXXgtw0p.js +1 -0
  409. ksadk/server/static/assets/z80-CL1naaMV.js +1 -0
  410. ksadk/server/static/favicon.svg +1 -0
  411. ksadk/server/static/icons.svg +24 -0
  412. ksadk/server/static/index.html +14 -0
  413. ksadk/server/terminal_sessions.py +551 -0
  414. ksadk/sessions/__init__.py +279 -0
  415. ksadk/sessions/base.py +354 -0
  416. ksadk/sessions/continuity.py +337 -0
  417. ksadk/sessions/errors.py +7 -0
  418. ksadk/sessions/in_memory.py +273 -0
  419. ksadk/sessions/local_service.py +949 -0
  420. ksadk/sessions/postgres_service.py +901 -0
  421. ksadk/sessions/resilience.py +52 -0
  422. ksadk/sessions/resilient.py +360 -0
  423. ksadk/sessions/sqlite_service.py +13 -0
  424. ksadk/skills/__init__.py +9 -0
  425. ksadk/skills/loader.py +46 -0
  426. ksadk/skills/models.py +120 -0
  427. ksadk/skills/package_store.py +104 -0
  428. ksadk/skills/runtime/__init__.py +17 -0
  429. ksadk/skills/runtime/agent.py +183 -0
  430. ksadk/skills/runtime/artifacts.py +39 -0
  431. ksadk/skills/runtime/backends/__init__.py +1 -0
  432. ksadk/skills/runtime/backends/disabled.py +8 -0
  433. ksadk/skills/runtime/backends/e2b.py +168 -0
  434. ksadk/skills/runtime/backends/local.py +95 -0
  435. ksadk/skills/runtime/base.py +103 -0
  436. ksadk/skills/runtime/executor.py +219 -0
  437. ksadk/skills/runtime/factory.py +37 -0
  438. ksadk/skills/runtime/loader.py +131 -0
  439. ksadk/skills/runtime/registry.py +150 -0
  440. ksadk/skills/runtime/request.py +67 -0
  441. ksadk/skills/service_client.py +239 -0
  442. ksadk/skills/service_env.py +58 -0
  443. ksadk/skills/tool_defs.py +221 -0
  444. ksadk/terminal_client.py +69 -0
  445. ksadk/terminal_exec_policy.py +229 -0
  446. ksadk/tools/__init__.py +17 -0
  447. ksadk/tools/gateway.py +230 -0
  448. ksadk/tools/result_budget.py +154 -0
  449. ksadk/toolsets/__init__.py +854 -0
  450. ksadk/toolsets/_langchain.py +11 -0
  451. ksadk/toolsets/platform.py +93 -0
  452. ksadk/toolsets/sandbox.py +310 -0
  453. ksadk/toolsets/skills.py +217 -0
  454. ksadk/toolsets/web.py +266 -0
  455. ksadk/toolsets/workspace.py +917 -0
  456. ksadk/toolsets/workspace_state.py +44 -0
  457. ksadk/tracing/__init__.py +37 -0
  458. ksadk/tracing/exporters/__init__.py +1 -0
  459. ksadk/tracing/exporters/inmemory_exporter.py +116 -0
  460. ksadk/tracing/exporters/langfuse_exporter.py +445 -0
  461. ksadk/tracing/setup.py +892 -0
  462. ksadk/tracing/span_utils.py +114 -0
  463. ksadk/tui/__init__.py +27 -0
  464. ksadk/tui/loop.py +1877 -0
  465. ksadk/tui/stream_render.py +68 -0
  466. ksadk/ui_config.py +168 -0
  467. ksadk/version.py +4 -0
  468. ksadk_runtime_common/__init__.py +20 -0
  469. ksadk_runtime_common/memory_backend/__init__.py +29 -0
  470. ksadk_runtime_common/memory_backend/manifest.py +79 -0
  471. ksadk_runtime_common/memory_backend/providers/__init__.py +6 -0
  472. ksadk_runtime_common/memory_backend/providers/lancedb.py +151 -0
  473. ksadk_runtime_common/memory_backend/providers/mem0.py +74 -0
  474. ksadk_runtime_common/memory_backend/registry.py +56 -0
  475. ksadk_runtime_common/memory_backend/render.py +71 -0
  476. ksadk_runtime_common/schemas/memory_backend_manifest.schema.json +148 -0
  477. ksadk_runtime_common/workspace_files/__init__.py +29 -0
  478. ksadk_runtime_common/workspace_files/bootstrap.py +56 -0
  479. ksadk_runtime_common/workspace_files/constants.py +9 -0
  480. ksadk_runtime_common/workspace_files/path_utils.py +71 -0
  481. ksadk_runtime_common/workspace_files/preview.py +96 -0
  482. ksadk_runtime_common/workspace_files/router.py +254 -0
  483. agentengine_sdk_python/__init__.py +0 -3
  484. agentengine_sdk_python-0.6.4.dist-info/METADATA +0 -48
  485. agentengine_sdk_python-0.6.4.dist-info/RECORD +0 -5
  486. agentengine_sdk_python-0.6.4.dist-info/top_level.txt +0 -1
@@ -0,0 +1,387 @@
1
+ """分层 compaction pipeline(L2 Snip + L3 Microcompact + L5 working set)。
2
+
3
+ 接入 ``compact_conversation_history``(runtime.py),在送 LLM summarizer 前做零成本确定性裁剪。
4
+
5
+ 核心纪律(Codex review):
6
+ - transcript 是 append-only,绝不删事件。L2/L3 只作用于"送 summarizer 的 candidate 投影":
7
+ 浅拷贝 groups + 过滤/合成,返回新的 candidate groups。原始 SessionEvent 实例和 transcript 不动。
8
+ - L3 不伪造 transcript 事件:合成的摘要 event 只存在于 candidate 投影里,不写回 transcript。
9
+ - checkpoint metadata 记录 pipeline 执行情况(snip_stats/microcompact_stats/preserved_receipts),
10
+ 便于审计和恢复。
11
+ """
12
+
13
+ from __future__ import annotations
14
+
15
+ import hashlib
16
+ import os
17
+ from dataclasses import dataclass, field
18
+ from typing import Any, Mapping, Sequence
19
+
20
+ from ksadk.conversations.context import (
21
+ canonical_event_type,
22
+ extract_event_text,
23
+ summarize_event_groups,
24
+ )
25
+ from ksadk.conversations.model_context import estimate_text_tokens
26
+ from ksadk.sessions.base import SessionEvent
27
+
28
+
29
+ @dataclass
30
+ class SnipStats:
31
+ """L2 Snip 执行统计,写入 checkpoint metadata 便于审计。"""
32
+
33
+ removed_redundant_tool_results: int = 0
34
+ tokens_before: int = 0
35
+ tokens_after: int = 0
36
+ covered_seq_range: tuple[int, int] | None = None
37
+
38
+
39
+ @dataclass
40
+ class SnipResult:
41
+ groups: list[list[SessionEvent]]
42
+ stats: SnipStats
43
+
44
+
45
+ @dataclass
46
+ class MicrocompactStats:
47
+ """L3 Microcompact 执行统计。"""
48
+
49
+ compacted_groups: int = 0
50
+ tokens_before: int = 0
51
+ tokens_after: int = 0
52
+ preserved_receipts: list[str] = field(default_factory=list)
53
+
54
+
55
+ @dataclass
56
+ class MicrocompactResult:
57
+ groups: list[list[SessionEvent]]
58
+ stats: MicrocompactStats
59
+
60
+
61
+ def _snip_enabled() -> bool:
62
+ return _bool_env("KSADK_COMPACT_SNIP_ENABLED", True)
63
+
64
+
65
+ def _microcompact_enabled() -> bool:
66
+ return _bool_env("KSADK_COMPACT_MICROCOMPACT_ENABLED", True)
67
+
68
+
69
+ def _microcompact_cold_rounds() -> int:
70
+ """超过多少轮未引用的组算冷组,默认 3。"""
71
+ raw = os.environ.get("KSADK_COMPACT_MICROCOMPACT_COLD_ROUNDS", "3")
72
+ try:
73
+ return max(1, int(raw))
74
+ except (TypeError, ValueError):
75
+ return 3
76
+
77
+
78
+ def _bool_env(name: str, default: bool) -> bool:
79
+ raw = (os.environ.get(name) or "").strip().lower()
80
+ if raw in {"1", "true", "yes", "on"}:
81
+ return True
82
+ if raw in {"0", "false", "no", "off"}:
83
+ return False
84
+ return default
85
+
86
+
87
+ def candidate_tokens(groups: Sequence[Sequence[SessionEvent]]) -> int:
88
+ """估算 candidate groups 的总 token(用于 pipeline 渐进停止判断)。"""
89
+ return sum(
90
+ estimate_text_tokens(extract_event_text(event))
91
+ for group in groups
92
+ for event in group
93
+ )
94
+
95
+
96
+ def _tool_signature(event: SessionEvent) -> str | None:
97
+ """识别 tool_call 事件的 tool 名 + 参数 hash,用于判断是否被后续组覆盖。
98
+
99
+ 兼容真实 runtime event 形态(tool 名在 metadata.tool_name,参数在 metadata.tool_args)
100
+ 和历史/合成形态(tool 名在 content.name,参数在 content.arguments)。
101
+ """
102
+ event_type = canonical_event_type(
103
+ event.event_type,
104
+ author=event.author,
105
+ role=str((event.content or {}).get("role") or ""),
106
+ )
107
+ if event_type != "tool_call":
108
+ return None
109
+ content = event.content or {}
110
+ metadata = event.metadata or {}
111
+ name = str(
112
+ metadata.get("tool_name")
113
+ or content.get("name")
114
+ or content.get("tool_name")
115
+ or ""
116
+ )
117
+ # 参数优先取 metadata.tool_args(真实 runtime),回退 content.arguments(合成/历史)。
118
+ arguments = (
119
+ metadata.get("tool_args")
120
+ or content.get("arguments")
121
+ or content.get("input")
122
+ or content.get("args")
123
+ or ""
124
+ )
125
+ if not isinstance(arguments, str):
126
+ try:
127
+ arguments_hash_input = repr(arguments)
128
+ except Exception:
129
+ arguments_hash_input = ""
130
+ else:
131
+ arguments_hash_input = arguments
132
+ if not name:
133
+ return None
134
+ digest = hashlib.sha1(f"{name}:{arguments_hash_input}".encode("utf-8")).hexdigest()[:12]
135
+ return f"{name}:{digest}"
136
+
137
+
138
+ def _event_run_id(event: SessionEvent) -> str | None:
139
+ """取 event 的 run_id(真实 runtime 把 run_id 放 metadata,tool_call/tool_result 都有)。
140
+
141
+ 用于精确配对 tool_call 和 tool_result:同一工具调用的 call 和 result 共享同一 run_id。
142
+ 比"邻接配对"更可靠,支持 parallel_tool_calls(同一轮多个 tool_call 交错 result)。
143
+ """
144
+ metadata = event.metadata or {}
145
+ run_id = metadata.get("run_id")
146
+ if run_id:
147
+ return str(run_id)
148
+ # 兼容 tool_receipt 里也可能带 run_id/tool_call_id 的形态。
149
+ receipt = metadata.get("tool_receipt")
150
+ if isinstance(receipt, Mapping):
151
+ for key in ("run_id", "tool_call_id"):
152
+ value = receipt.get(key)
153
+ if value:
154
+ return str(value)
155
+ return None
156
+
157
+
158
+ def snip_redundant_groups(
159
+ groups: Sequence[Sequence[SessionEvent]],
160
+ *,
161
+ pinned_state: Mapping[str, Any] | None = None,
162
+ ) -> SnipResult:
163
+ """L2 Snip:在 candidate 投影上移除冗余 tool_result。
164
+
165
+ 只作用于 candidate 副本(浅拷贝 groups + 过滤 event),不改原 SessionEvent,不改 transcript。
166
+
167
+ 移除规则:
168
+ - 被**后续组**同 tool_name 同参数覆盖的旧 tool_call(含其配对 tool_result)——
169
+ 旧结果已无参考价值,模型只需看最新结果。但**最后一组的 tool 保留**(tail 保护)。
170
+ - tool_call 与 tool_result 按 **metadata.run_id 精确配对**删除(不靠邻接),
171
+ 支持 parallel_tool_calls=True 时同一轮多 tool_call 交错的场景。
172
+
173
+ 失败 tool_call/tool_result 配对的去重本期不做(保守起见,避免误删有诊断价值的失败记录)。
174
+ pinned_state 里的 pending tool/approval 不动(它们在 pinned 组,不在 groups_to_compact)。
175
+ """
176
+ tokens_before = candidate_tokens(groups)
177
+ if not _snip_enabled() or not groups:
178
+ return SnipResult(
179
+ groups=[list(group) for group in groups],
180
+ stats=SnipStats(tokens_before=tokens_before, tokens_after=tokens_before),
181
+ )
182
+
183
+ # 第一遍:记录每个 tool_signature 最后一次出现的组索引,以及每个 run_id 对应的 signature。
184
+ # run_id 来自 tool_call 的 metadata,用于精确配对 tool_result。
185
+ last_signature_group: dict[str, int] = {}
186
+ run_id_to_signature: dict[str, str] = {}
187
+ for index, group in enumerate(groups):
188
+ for event in group:
189
+ sig = _tool_signature(event)
190
+ if sig is not None:
191
+ last_signature_group[sig] = index
192
+ run_id = _event_run_id(event)
193
+ if run_id:
194
+ run_id_to_signature[run_id] = sig
195
+
196
+ # 被覆盖的 tool_call:其 signature 最后一次出现不在当前组。
197
+ # 收集这些被覆盖 tool_call 的 run_id,用于精确删除配对 tool_result(不靠邻接)。
198
+ covered_run_ids: set[str] = set()
199
+ for index, group in enumerate(groups):
200
+ for event in group:
201
+ sig = _tool_signature(event)
202
+ if sig is not None and last_signature_group.get(sig) != index:
203
+ run_id = _event_run_id(event)
204
+ if run_id:
205
+ covered_run_ids.add(run_id)
206
+
207
+ removed_redundant = 0
208
+ result_groups: list[list[SessionEvent]] = []
209
+ for index, group in enumerate(groups):
210
+ kept: list[SessionEvent] = []
211
+ for event in group:
212
+ sig = _tool_signature(event)
213
+ if sig is not None:
214
+ # 被后续组覆盖的旧 tool_call 移除(保留最后一次出现)。
215
+ if last_signature_group.get(sig) != index:
216
+ removed_redundant += 1
217
+ continue
218
+ else:
219
+ event_type = canonical_event_type(
220
+ event.event_type,
221
+ author=event.author,
222
+ role=str((event.content or {}).get("role") or ""),
223
+ )
224
+ if event_type == "tool_result":
225
+ run_id = _event_run_id(event)
226
+ # 配对的 tool_call 已被覆盖删除,按 run_id 精确删除该 result(避免孤儿)。
227
+ if run_id and run_id in covered_run_ids:
228
+ removed_redundant += 1
229
+ continue
230
+ kept.append(event)
231
+ result_groups.append(kept)
232
+
233
+ tokens_after = candidate_tokens(result_groups)
234
+ head_seq = groups[0][0].seq_id if groups and groups[0] else 0
235
+ tail_seq = groups[-1][-1].seq_id if groups and groups[-1] else 0
236
+ return SnipResult(
237
+ groups=result_groups,
238
+ stats=SnipStats(
239
+ removed_redundant_tool_results=removed_redundant,
240
+ tokens_before=tokens_before,
241
+ tokens_after=tokens_after,
242
+ covered_seq_range=(head_seq, tail_seq) if groups else None,
243
+ ),
244
+ )
245
+
246
+
247
+ def microcompact_cold_groups(
248
+ groups: Sequence[Sequence[SessionEvent]],
249
+ *,
250
+ pinned_state: Mapping[str, Any] | None = None,
251
+ previous_summary: str = "",
252
+ ) -> MicrocompactResult:
253
+ """L3 Microcompact:对冷组做 extractive 摘要,整组替换成合成摘要 event(candidate 投影)。
254
+
255
+ 只作用于 candidate 副本,不写回 transcript。合成 event 只存在于送 summarizer 的 candidate 里。
256
+ 保留 receipt_key/framework_ref(从 pinned_state 和 event metadata 提取,记入 stats)。
257
+ """
258
+ tokens_before = candidate_tokens(groups)
259
+ if not _microcompact_enabled() or len(groups) <= _microcompact_cold_rounds():
260
+ return MicrocompactResult(
261
+ groups=[list(group) for group in groups],
262
+ stats=MicrocompactStats(tokens_before=tokens_before, tokens_after=tokens_before),
263
+ )
264
+
265
+ # 尾部 N 组保留(它们可能还被模型需要),更早的组视为冷组。
266
+ cold_rounds = _microcompact_cold_rounds()
267
+ cold_groups = list(groups[:-cold_rounds]) if cold_rounds < len(groups) else []
268
+ tail_groups = list(groups[-cold_rounds:]) if cold_rounds < len(groups) else list(groups)
269
+
270
+ if not cold_groups:
271
+ return MicrocompactResult(
272
+ groups=[list(group) for group in groups],
273
+ stats=MicrocompactStats(tokens_before=tokens_before, tokens_after=tokens_before),
274
+ )
275
+
276
+ # 用现有 extractive summarizer 生成结构化摘要文本(不调 LLM)。
277
+ summary_text = summarize_event_groups(cold_groups, previous_summary=previous_summary)
278
+
279
+ # 收集冷组里的 receipt_key/framework_ref,记入 stats(preserved_receipts)。
280
+ preserved_receipts: list[str] = []
281
+ for group in cold_groups:
282
+ for event in group:
283
+ metadata = event.metadata or {}
284
+ receipt = str(metadata.get("receipt_key") or "").strip()
285
+ if receipt and receipt not in preserved_receipts:
286
+ preserved_receipts.append(receipt)
287
+
288
+ # 合成一个摘要 event 放入 candidate 头部(不写回 transcript)。
289
+ # event_type 用 assistant_message 避免下游误判为真实 tool 事件。
290
+ summary_event = SessionEvent(
291
+ event_type="assistant_message",
292
+ author="system",
293
+ content={
294
+ "role": "assistant",
295
+ "text": f"[earlier rounds microcompact summary]\n{summary_text}",
296
+ },
297
+ metadata={
298
+ "compaction_projection": True,
299
+ "compaction_stage": "microcompact",
300
+ "preserved_receipts": preserved_receipts,
301
+ },
302
+ seq_id=cold_groups[0][0].seq_id if cold_groups and cold_groups[0] else 0,
303
+ )
304
+
305
+ result_groups = [[summary_event], *tail_groups]
306
+ tokens_after = candidate_tokens(result_groups)
307
+ return MicrocompactResult(
308
+ groups=result_groups,
309
+ stats=MicrocompactStats(
310
+ compacted_groups=len(cold_groups),
311
+ tokens_before=tokens_before,
312
+ tokens_after=tokens_after,
313
+ preserved_receipts=preserved_receipts,
314
+ ),
315
+ )
316
+
317
+
318
+ def build_working_set_metadata(
319
+ *,
320
+ pinned_state: Mapping[str, Any] | None,
321
+ recent_files: Sequence[Mapping[str, Any]] | None = None,
322
+ active_tools: Sequence[str] | None = None,
323
+ ) -> dict[str, Any]:
324
+ """L5 working set 恢复(保守版):只记 metadata,不读文件内容。
325
+
326
+ recent_files: 调用方从 workspace_state 取最近 N 个文件的 {path, mtime_ns, size_bytes, read_range}。
327
+ active_tools: 调用方从 describe_agentengine_tools 取 enabled 工具名。
328
+ 下一轮 prompt 注入时只提示"这些文件最近读过",不注入内容(避免 token 膨胀)。
329
+ """
330
+ return {
331
+ "recent_files": list(recent_files or [])[: _working_set_max_files()],
332
+ "active_tools": list(active_tools or []),
333
+ "pinned_approvals": list((pinned_state or {}).get("pending_approvals") or []),
334
+ "pinned_tools": list((pinned_state or {}).get("pending_tools") or []),
335
+ "current_user_goal": str((pinned_state or {}).get("current_user_goal") or ""),
336
+ }
337
+
338
+
339
+ def _working_set_max_files() -> int:
340
+ raw = os.environ.get("KSADK_WORKING_SET_MAX_FILES", "5")
341
+ try:
342
+ return max(0, int(raw))
343
+ except (TypeError, ValueError):
344
+ return 5
345
+
346
+
347
+ def run_pipeline(
348
+ groups: Sequence[Sequence[SessionEvent]],
349
+ *,
350
+ threshold_tokens: int,
351
+ pinned_state: Mapping[str, Any] | None = None,
352
+ previous_summary: str = "",
353
+ ) -> dict[str, Any]:
354
+ """编排 L2 → L3,渐进停止。返回 candidate groups + 各层 stats。
355
+
356
+ L4(LLM compact)由调用方(summarize_compaction)继续处理 candidate。
357
+ L5(working set)由调用方在写 checkpoint 时调 build_working_set_metadata。
358
+ """
359
+ snip = snip_redundant_groups(groups, pinned_state=pinned_state)
360
+ candidate = snip.groups
361
+ snip_released = snip.stats.tokens_before - snip.stats.tokens_after
362
+
363
+ micro: MicrocompactResult | None = None
364
+ if candidate_tokens(candidate) > threshold_tokens:
365
+ micro = microcompact_cold_groups(
366
+ candidate,
367
+ pinned_state=pinned_state,
368
+ previous_summary=previous_summary,
369
+ )
370
+ candidate = micro.groups
371
+
372
+ return {
373
+ "candidate_groups": candidate,
374
+ "snip_stats": snip.stats,
375
+ "microcompact_stats": micro.stats if micro else None,
376
+ "tokens_before": snip.stats.tokens_before,
377
+ "tokens_after": candidate_tokens(candidate),
378
+ "snip_released_tokens": snip_released,
379
+ "pipeline_stages": [
380
+ stage
381
+ for stage, used in (
382
+ ("snip", True),
383
+ ("microcompact", micro is not None),
384
+ )
385
+ if used
386
+ ],
387
+ }
@@ -0,0 +1,128 @@
1
+ from __future__ import annotations
2
+
3
+ import json
4
+ import re
5
+ from typing import Any, Mapping, Sequence
6
+
7
+ from ksadk.conversations.context import canonical_event_type, extract_event_text
8
+ from ksadk.sessions.base import SessionEvent
9
+
10
+ _NO_TOOLS_PROMPT = """CRITICAL: Respond with TEXT ONLY. Do NOT call any tools.
11
+
12
+ - Do NOT use any tool or function call.
13
+ - You already have all required context in this request.
14
+ - Your entire response must be plain text with exactly two blocks:
15
+ <analysis>...</analysis>
16
+ <summary>...</summary>
17
+ - The <summary> block must use Chinese and contain exactly these sections:
18
+ 当前用户目标
19
+ 关键约束与偏好
20
+ 已完成进展
21
+ 重要决策/代码上下文
22
+ 未完成事项
23
+ 下一步工作位置
24
+ """
25
+
26
+ _SUMMARY_USER_PROMPT = """你正在为一个 append-only 会话日志生成压缩摘要。
27
+
28
+ 目标:
29
+ 1. 帮助系统在压缩较早对话后,仍然能稳定恢复当前工作上下文。
30
+ 2. 明确保留用户目标、约束、已完成进展、关键代码上下文、未完成事项。
31
+ 3. 不要编造不存在的事实;不确定时明确写“未明确”。
32
+
33
+ 输出要求:
34
+ - 先输出 <analysis>,仅作为草稿。
35
+ - 再输出 <summary>。
36
+ - <summary> 内必须只包含以下固定标题,且顺序不能变:
37
+ 当前用户目标
38
+ 关键约束与偏好
39
+ 已完成进展
40
+ 重要决策/代码上下文
41
+ 未完成事项
42
+ 下一步工作位置
43
+
44
+ 模型上下文信息:
45
+ {model_metadata}
46
+
47
+ 上一个 checkpoint 摘要:
48
+ {previous_summary}
49
+
50
+ 需要强制保真的 pinned state:
51
+ {pinned_state}
52
+
53
+ 本次要压缩的旧轮次:
54
+ {groups_text}
55
+ """
56
+
57
+
58
+ def _truncate_text(text: str, *, limit: int = 400) -> str:
59
+ stripped = str(text or "").strip()
60
+ if len(stripped) <= limit:
61
+ return stripped
62
+ return f"{stripped[:limit]}...(已截断)"
63
+
64
+
65
+ def _format_group(group: Sequence[SessionEvent], *, index: int) -> str:
66
+ lines = [f"## Round {index}"]
67
+ for event in group:
68
+ event_type = canonical_event_type(
69
+ event.event_type,
70
+ author=event.author,
71
+ role=str((event.content or {}).get("role") or ""),
72
+ )
73
+ text = _truncate_text(extract_event_text(event), limit=320)
74
+ if not text:
75
+ continue
76
+ lines.append(
77
+ f"- seq={event.seq_id} type={event_type} author={event.author or 'unknown'} text={text}"
78
+ )
79
+ return "\n".join(lines)
80
+
81
+
82
+ def build_compaction_prompt_messages(
83
+ *,
84
+ previous_summary: str,
85
+ groups_to_compact: Sequence[Sequence[SessionEvent]],
86
+ pinned_state: Mapping[str, Any],
87
+ model_metadata: Mapping[str, Any] | None,
88
+ ) -> list[dict[str, str]]:
89
+ """构造 semantic compaction 的固定 prompt。
90
+
91
+ 这里单独抽成 builder,是为了让本地和云端后续都能稳定复用同一套摘要结构,
92
+ 不把 prompt 字符串散落到 runtime 编排里。
93
+ """
94
+
95
+ groups_text = "\n\n".join(
96
+ _format_group(group, index=index + 1)
97
+ for index, group in enumerate(groups_to_compact)
98
+ ).strip() or "无可压缩内容"
99
+ user_prompt = _SUMMARY_USER_PROMPT.format(
100
+ model_metadata=json.dumps(dict(model_metadata or {}), ensure_ascii=False, indent=2),
101
+ previous_summary=previous_summary.strip() or "无",
102
+ pinned_state=json.dumps(dict(pinned_state or {}), ensure_ascii=False, indent=2),
103
+ groups_text=groups_text,
104
+ )
105
+ return [
106
+ {"role": "system", "content": _NO_TOOLS_PROMPT},
107
+ {"role": "user", "content": user_prompt},
108
+ ]
109
+
110
+
111
+ def extract_summary_text(response_text: str) -> str:
112
+ """提取 <summary>,并丢弃 <analysis> 草稿。"""
113
+
114
+ raw = str(response_text or "").strip()
115
+ if not raw:
116
+ return ""
117
+
118
+ summary_match = re.search(r"<summary>\s*(.*?)\s*</summary>", raw, flags=re.DOTALL | re.IGNORECASE)
119
+ if summary_match:
120
+ return summary_match.group(1).strip()
121
+
122
+ without_analysis = re.sub(
123
+ r"<analysis>.*?</analysis>",
124
+ "",
125
+ raw,
126
+ flags=re.DOTALL | re.IGNORECASE,
127
+ )
128
+ return without_analysis.strip()