agentengine-sdk-python 0.8.0__py3-none-any.whl → 0.8.2__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 (494) hide show
  1. {agentengine_sdk_python-0.8.0.dist-info → agentengine_sdk_python-0.8.2.dist-info}/METADATA +43 -7
  2. agentengine_sdk_python-0.8.2.dist-info/RECORD +778 -0
  3. {agentengine_sdk_python-0.8.0.dist-info → agentengine_sdk_python-0.8.2.dist-info}/WHEEL +1 -1
  4. ksadk/a2a/__init__.py +2 -0
  5. ksadk/a2a/_space_client_events.py +381 -0
  6. ksadk/a2a/bootstrap.py +0 -2
  7. ksadk/a2a/card.py +6 -111
  8. ksadk/a2a/control_plane.py +239 -1
  9. ksadk/a2a/event_adapter.py +156 -64
  10. ksadk/a2a/executor.py +195 -172
  11. ksadk/a2a/routes.py +12 -5
  12. ksadk/a2a/server.py +1 -8
  13. ksadk/a2a/service_env.py +33 -0
  14. ksadk/a2a/space_client.py +43 -349
  15. ksadk/a2a_card.py +101 -0
  16. ksadk/a2ui/core.py +222 -53
  17. ksadk/agui/_agent_helpers.py +243 -0
  18. ksadk/agui/a2ui_projection.py +12 -5
  19. ksadk/agui/agent.py +474 -275
  20. ksadk/agui/config.py +11 -5
  21. ksadk/agui/routes.py +7 -15
  22. ksadk/api/client.py +530 -40
  23. ksadk/api/environment.py +27 -0
  24. ksadk/builders/code_builder.py +352 -53
  25. ksadk/builders/container_builder.py +71 -44
  26. ksadk/builders/framework_requirements.py +2 -1
  27. ksadk/builders/ks3_uploader.py +2 -2
  28. ksadk/builders/managed_runtime_builder.py +60 -28
  29. ksadk/cli/__init__.py +25 -0
  30. ksadk/cli/cmd_a2a.py +18 -31
  31. ksadk/cli/cmd_create.py +13 -26
  32. ksadk/cli/cmd_dashboard.py +15 -1
  33. ksadk/cli/cmd_deploy.py +28 -3
  34. ksadk/cli/cmd_eval.py +443 -0
  35. ksadk/cli/cmd_evalset.py +284 -0
  36. ksadk/cli/cmd_files.py +5 -1
  37. ksadk/cli/cmd_hermes.py +137 -163
  38. ksadk/cli/cmd_invoke.py +28 -38
  39. ksadk/cli/cmd_launch.py +12 -0
  40. ksadk/cli/cmd_managed_runtime.py +95 -0
  41. ksadk/cli/cmd_observe.py +85 -0
  42. ksadk/cli/cmd_openclaw.py +85 -479
  43. ksadk/cli/cmd_replay.py +28 -4
  44. ksadk/cli/cmd_run.py +29 -67
  45. ksadk/cli/cmd_studio.py +201 -0
  46. ksadk/cli/cmd_web.py +15 -6
  47. ksadk/cli/dry_run.py +2 -1
  48. ksadk/cli/env_options.py +83 -0
  49. ksadk/cli/global_options.py +3 -1
  50. ksadk/cli/hermes_env.py +151 -0
  51. ksadk/cli/invoke_payload.py +49 -0
  52. ksadk/cli/network_options.py +7 -5
  53. ksadk/cli/openclaw_env.py +458 -0
  54. ksadk/cli/runtime_bootstrap.py +51 -0
  55. ksadk/cli/ui.py +6 -0
  56. ksadk/cli/workflow_common.py +5 -5
  57. ksadk/codex/__init__.py +3 -3
  58. ksadk/codex/client.py +833 -49
  59. ksadk/codex/phase.py +1 -1
  60. ksadk/codex/runtime.py +720 -127
  61. ksadk/common/kop_client.py +232 -0
  62. ksadk/configs/__init__.py +1 -3
  63. ksadk/configs/env_registry.py +244 -45
  64. ksadk/configs/env_registry_pcm.py +181 -0
  65. ksadk/configs/env_var_spec.py +18 -0
  66. ksadk/configs/global_config.py +6 -1
  67. ksadk/configs/settings.py +5 -108
  68. ksadk/context_engine/__init__.py +98 -0
  69. ksadk/context_engine/assembler.py +176 -0
  70. ksadk/context_engine/baseline.py +419 -0
  71. ksadk/context_engine/cache_observability.py +228 -0
  72. ksadk/context_engine/capabilities.py +443 -0
  73. ksadk/context_engine/contributors.py +344 -0
  74. ksadk/context_engine/hosted_pipeline.py +417 -0
  75. ksadk/context_engine/models.py +117 -0
  76. ksadk/context_engine/planner.py +698 -0
  77. ksadk/context_engine/policies.py +319 -0
  78. ksadk/context_engine/projection.py +31 -0
  79. ksadk/context_engine/shadow_plan.py +266 -0
  80. ksadk/context_engine/tokenizer.py +164 -0
  81. ksadk/conversations/__init__.py +85 -94
  82. ksadk/conversations/context.py +126 -6
  83. ksadk/conversations/message_projection.py +292 -28
  84. ksadk/conversations/model_context.py +49 -3
  85. ksadk/conversations/runtime_compaction.py +207 -5
  86. ksadk/conversations/runtime_input.py +193 -3
  87. ksadk/conversations/runtime_invocation.py +81 -3
  88. ksadk/conversations/runtime_observability.py +157 -4
  89. ksadk/conversations/runtime_payloads.py +42 -0
  90. ksadk/conversations/runtime_preparation.py +280 -2
  91. ksadk/conversations/runtime_resume.py +71 -32
  92. ksadk/conversations/runtime_stream_events.py +94 -9
  93. ksadk/conversations/runtime_streaming.py +175 -22
  94. ksadk/conversations/semantic_summary.py +311 -1
  95. ksadk/conversations/session_lock.py +51 -0
  96. ksadk/deployment/env_forward.py +72 -0
  97. ksadk/deployment/managed_runtime.py +38 -0
  98. ksadk/deployment/manager.py +24 -8
  99. ksadk/deployment/providers/serverless.py +228 -92
  100. ksadk/evaluation/__init__.py +116 -0
  101. ksadk/evaluation/a2a_adapter.py +452 -0
  102. ksadk/evaluation/adapters.py +67 -0
  103. ksadk/evaluation/agent_eval_client.py +395 -0
  104. ksadk/evaluation/cloud_binding.py +80 -0
  105. ksadk/evaluation/cloud_converter.py +194 -0
  106. ksadk/evaluation/cloud_service.py +199 -0
  107. ksadk/evaluation/contracts.py +478 -0
  108. ksadk/evaluation/evalset.py +351 -0
  109. ksadk/evaluation/evaluators.py +627 -0
  110. ksadk/evaluation/evidence.py +258 -0
  111. ksadk/evaluation/executor.py +143 -0
  112. ksadk/evaluation/local_adapter.py +550 -0
  113. ksadk/evaluation/service_env.py +27 -0
  114. ksadk/evaluation/storage.py +68 -0
  115. ksadk/evaluation/studio_build_adapter.py +253 -0
  116. ksadk/evaluation/target.py +82 -0
  117. ksadk/events/__init__.py +13 -13
  118. ksadk/events/_v1_compat/__init__.py +1 -0
  119. ksadk/events/_v1_compat/models.py +299 -0
  120. ksadk/events/_v1_compat/parser.py +247 -0
  121. ksadk/events/_v1_compat/projection.py +753 -0
  122. ksadk/events/adapters/__init__.py +34 -0
  123. ksadk/events/adapters/_a2a_snapshot.py +622 -0
  124. ksadk/events/adapters/_a2a_support.py +275 -0
  125. ksadk/events/adapters/_codex_interactions.py +375 -0
  126. ksadk/events/adapters/_codex_items.py +801 -0
  127. ksadk/events/adapters/_codex_validators.py +311 -0
  128. ksadk/events/adapters/_langgraph_support.py +785 -0
  129. ksadk/events/adapters/a2a.py +841 -0
  130. ksadk/events/adapters/adk.py +503 -0
  131. ksadk/events/adapters/codex.py +717 -0
  132. ksadk/events/adapters/langgraph.py +745 -0
  133. ksadk/events/canonical.py +440 -0
  134. ksadk/events/canonical_replay.py +497 -0
  135. ksadk/events/canonical_store.py +468 -0
  136. ksadk/events/cold_recovery.py +257 -0
  137. ksadk/events/content.py +89 -0
  138. ksadk/events/identity.py +86 -0
  139. ksadk/events/pipeline.py +455 -0
  140. ksadk/events/projections.py +66 -0
  141. ksadk/events/reducer.py +661 -0
  142. ksadk/events/replay.py +3 -36
  143. ksadk/events/runtime_event.py +20 -256
  144. ksadk/events/session_event.py +324 -0
  145. ksadk/events/store.py +3 -316
  146. ksadk/events/v1_compat.py +41 -0
  147. ksadk/harness/__init__.py +3 -2
  148. ksadk/harness/app.py +114 -123
  149. ksadk/harness/config.py +1 -1
  150. ksadk/harness/runtime.py +467 -0
  151. ksadk/hermes_terminal.py +5 -0
  152. ksadk/identity/resolver.py +4 -3
  153. ksadk/interaction/__init__.py +28 -0
  154. ksadk/interaction/contracts.py +136 -0
  155. ksadk/interaction/ledger.py +189 -0
  156. ksadk/interaction/provider.py +122 -0
  157. ksadk/interaction/providers/__init__.py +52 -0
  158. ksadk/interaction/providers/adk.py +40 -0
  159. ksadk/interaction/providers/codex.py +94 -0
  160. ksadk/interaction/providers/langgraph.py +58 -0
  161. ksadk/kernel/__init__.py +117 -0
  162. ksadk/kernel/authorization.py +258 -0
  163. ksadk/kernel/bootstrap.py +1074 -0
  164. ksadk/kernel/contract_fingerprints.py +61 -0
  165. ksadk/kernel/contracts.py +362 -0
  166. ksadk/kernel/control.py +219 -0
  167. ksadk/kernel/errors.py +79 -0
  168. ksadk/kernel/ingress.py +1102 -0
  169. ksadk/kernel/mapping.py +111 -0
  170. ksadk/kernel/memory_store.py +1133 -0
  171. ksadk/kernel/postgres_store.py +1756 -0
  172. ksadk/kernel/recovery.py +452 -0
  173. ksadk/kernel/runtime_identity.py +103 -0
  174. ksadk/kernel/sql/001_agent_kernel.sql +120 -0
  175. ksadk/kernel/sqlite_store.py +1410 -0
  176. ksadk/kernel/state.py +145 -0
  177. ksadk/kernel/store.py +232 -0
  178. ksadk/kernel/worker.py +953 -0
  179. ksadk/knowledge_base/client.py +22 -4
  180. ksadk/knowledge_base/service.py +32 -5
  181. ksadk/managed_a2a_card.py +160 -0
  182. ksadk/managed_runtime.py +16 -9
  183. ksadk/memory/__init__.py +61 -0
  184. ksadk/memory/adk/backends/base_ltm_backend.py +96 -1
  185. ksadk/memory/adk/backends/http_ltm_backend.py +14 -5
  186. ksadk/memory/adk/backends/inmemory_ltm_backend.py +136 -3
  187. ksadk/memory/adk/backends/sdk_ltm_backend.py +394 -5
  188. ksadk/memory/adk/backends/sqlite_ltm_backend.py +95 -0
  189. ksadk/memory/adk/long_term_memory.py +3 -2
  190. ksadk/memory/coordinator.py +461 -0
  191. ksadk/memory/events.py +202 -0
  192. ksadk/memory/extraction.py +228 -0
  193. ksadk/memory/ltm_backend_factory.py +16 -3
  194. ksadk/memory/models.py +316 -0
  195. ksadk/memory/policy.py +215 -0
  196. ksadk/memory/provider.py +47 -0
  197. ksadk/memory/provider_adapter.py +159 -0
  198. ksadk/memory/provider_resolver.py +71 -0
  199. ksadk/memory/providers/__init__.py +5 -0
  200. ksadk/memory/providers/local_sqlite.py +490 -0
  201. ksadk/memory/resolved_policy.py +145 -0
  202. ksadk/memory/service.py +198 -8
  203. ksadk/memory/tool.py +4 -0
  204. ksadk/model_proxy/bootstrap.py +16 -9
  205. ksadk/model_proxy/config.py +22 -1
  206. ksadk/model_proxy/detect.py +202 -9
  207. ksadk/model_proxy/namespace.py +67 -15
  208. ksadk/model_proxy/server.py +168 -6
  209. ksadk/model_proxy/transform.py +105 -3
  210. ksadk/observability/__init__.py +25 -0
  211. ksadk/observability/session_log.py +420 -0
  212. ksadk/observability/trajectory.py +105 -0
  213. ksadk/prompts/__init__.py +71 -0
  214. ksadk/prompts/compiler.py +215 -0
  215. ksadk/prompts/models.py +82 -0
  216. ksadk/prompts/projection.py +89 -0
  217. ksadk/prompts/resolved.py +137 -0
  218. ksadk/prompts/sources.py +233 -0
  219. ksadk/runners/_langgraph_runner_streams.py +822 -0
  220. ksadk/runners/adk_runner.py +14 -31
  221. ksadk/runners/base_runner.py +44 -3
  222. ksadk/runners/factory.py +3 -3
  223. ksadk/runners/langgraph_runner.py +252 -433
  224. ksadk/runners/utils/__init__.py +0 -10
  225. ksadk/runners/utils/loader.py +16 -0
  226. ksadk/runtime/__init__.py +67 -41
  227. ksadk/runtime/_runner_adapter/__init__.py +1 -0
  228. ksadk/runtime/_runner_adapter/stream_mapping.py +788 -0
  229. ksadk/runtime/adapter.py +199 -16
  230. ksadk/runtime/conversation_execution.py +687 -0
  231. ksadk/runtime/executor.py +392 -0
  232. ksadk/runtime/factory.py +342 -0
  233. ksadk/runtime/framework_adapters.py +6 -12
  234. ksadk/runtime/hosted_finalizer.py +268 -0
  235. ksadk/runtime/launch.py +61 -0
  236. ksadk/runtime/preprocessing.py +49 -14
  237. ksadk/runtime/runner_adapter.py +330 -391
  238. ksadk/runtime/runner_loading.py +36 -0
  239. ksadk/runtime/usage.py +33 -0
  240. ksadk/sandbox/backends/e2b.py +36 -3
  241. ksadk/server/__init__.py +39 -4
  242. ksadk/server/app.py +18 -492
  243. ksadk/server/composition.py +36 -2
  244. ksadk/server/factory.py +210 -149
  245. ksadk/server/routes/common.py +15 -46
  246. ksadk/server/routes/control.py +13 -9
  247. ksadk/server/routes/kernel_ingress.py +258 -0
  248. ksadk/server/routes/misc.py +10 -33
  249. ksadk/server/routes/models.py +14 -6
  250. ksadk/server/routes/openai_compat.py +129 -27
  251. ksadk/server/routes/projection.py +84 -16
  252. ksadk/server/routes/run.py +347 -460
  253. ksadk/server/routes/sessions.py +37 -40
  254. ksadk/server/routes/streaming.py +52 -7
  255. ksadk/server/routes/workspace.py +54 -21
  256. ksadk/server/static/assets/{ArtifactsPanel-Cjnqt-8W.js → ArtifactsPanel-DSU1sWD_.js} +1 -1
  257. ksadk/server/static/assets/{CodeBlock-BqyqZfuB.js → CodeBlock-DOH6MVcn.js} +4 -4
  258. ksadk/server/static/assets/{MathMessageMarkdown-BpH7jiFM.js → MathMessageMarkdown-BL8my1R2.js} +4 -4
  259. ksadk/server/static/assets/MathMessageMarkdown-BorAY7qD.css +1 -0
  260. ksadk/server/static/assets/MermaidBlock-Dz4IP-Tx.js +312 -0
  261. ksadk/server/static/assets/NativeTerminalPanel-DUrK0JpZ.js +1 -0
  262. ksadk/server/static/assets/abnfDiagram-VCTEODGH-g20pFzNV.js +1 -0
  263. ksadk/server/static/assets/arc-C4FzinUA.js +1 -0
  264. ksadk/server/static/assets/architecture-7GRP2DOG-DjKratdf.js +1 -0
  265. ksadk/server/static/assets/architectureDiagram-5GKGNRK7-DpIqL5h4.js +36 -0
  266. ksadk/server/static/assets/blockDiagram-NRAW4CY4-BjkljTNz.js +129 -0
  267. ksadk/server/static/assets/c4Diagram-UCG6FXSJ-Dk_ieq2X.js +38 -0
  268. ksadk/server/static/assets/channel-4cQHKtx1.js +1 -0
  269. ksadk/server/static/assets/chunk-2Q5K7J3B-DmgWkESh.js +1 -0
  270. ksadk/server/static/assets/{chunk-FMBD7UC4-BGhvzDYt.js → chunk-5VM5RSS4-BVHAchFb.js} +1 -1
  271. ksadk/server/static/assets/{chunk-ND2GUHAM-D98vPd-E.js → chunk-F27PBJKO-C-ipQzuS.js} +1 -1
  272. ksadk/server/static/assets/chunk-G27WJ6UU-C2EyJbIK.js +231 -0
  273. ksadk/server/static/assets/{chunk-4BX2VUAB-CsWIQRhc.js → chunk-JWPE2WC7-vYvVJb_M.js} +1 -1
  274. ksadk/server/static/assets/chunk-LCL6LL3I-BcI6ysPT.js +206 -0
  275. ksadk/server/static/assets/chunk-POPQ4Y6H-C030x_Z1.js +1 -0
  276. ksadk/server/static/assets/chunk-RHFEMEQ7-yyGpsz4n.js +168 -0
  277. ksadk/server/static/assets/chunk-SVP7TREG-BLTlmMU7.js +88 -0
  278. ksadk/server/static/assets/chunk-XXDRQBXY-C_32ArgP.js +1 -0
  279. ksadk/server/static/assets/classDiagram-DTDB5LWJ-DLFd9Xi0.js +1 -0
  280. ksadk/server/static/assets/classDiagram-v2-JRS7N3AN-DLFd9Xi0.js +1 -0
  281. ksadk/server/static/assets/{cose-bilkent-S5V4N54A-CX3yotHq.js → cose-bilkent-JH36ORCC-9YQYwdl0.js} +1 -1
  282. ksadk/server/static/assets/cynefin-OW5HDTMX-DjEM48Qp.js +1 -0
  283. ksadk/server/static/assets/cynefinDiagram-5FMLGOSQ-ErLF5N13.js +62 -0
  284. ksadk/server/static/assets/cytoscape.esm-CyCl8rPi.js +321 -0
  285. ksadk/server/static/assets/dagre-3AP2YEHR-DFiQF-6f.js +4 -0
  286. ksadk/server/static/assets/dagre-BuhGnRI1.js +1 -0
  287. ksadk/server/static/assets/diagram-S7CK7UJ4-Bt1v8-GC.js +30 -0
  288. ksadk/server/static/assets/diagram-UQ7AKVKN-DSCxJdBK.js +41 -0
  289. ksadk/server/static/assets/diagram-VSXAHHWV-DHfYwp_9.js +3 -0
  290. ksadk/server/static/assets/diagram-VX7I27RA-DdzD-4Le.js +24 -0
  291. ksadk/server/static/assets/diagram-Z3DM3KII-Du-nAJ9F.js +24 -0
  292. ksadk/server/static/assets/{dist-D82mtD2s.js → dist-8hqcx0sU.js} +1 -1
  293. ksadk/server/static/assets/dist-B7seoj3d.js +1 -0
  294. ksadk/server/static/assets/{dist-DHn6nBzr.js → dist-BE7bu-DL.js} +1 -1
  295. ksadk/server/static/assets/{dist-eoW6tZXA.js → dist-BVDffZ0U.js} +1 -1
  296. ksadk/server/static/assets/{dist-C2xjE7cO.js → dist-BX8z72IC.js} +1 -1
  297. ksadk/server/static/assets/{dist-CgF3fj15.js → dist-Bf2M8m3N.js} +1 -1
  298. ksadk/server/static/assets/{dist-Bs-jQcRX.js → dist-BjU6y-A2.js} +1 -1
  299. ksadk/server/static/assets/{dist-Djgl2wVZ.js → dist-BytlxIDT.js} +1 -1
  300. ksadk/server/static/assets/{dist-CVQRZjPu.js → dist-CSh_DE14.js} +1 -1
  301. ksadk/server/static/assets/{dist-6CVKuTAe.js → dist-CXYYBw3_.js} +1 -1
  302. ksadk/server/static/assets/{dist-DlzCRy0S.js → dist-C_wsv-Qd.js} +1 -1
  303. ksadk/server/static/assets/{dist-DF06ORQo.js → dist-ClxGviKw.js} +1 -1
  304. ksadk/server/static/assets/{dist-Cf23NY4L.js → dist-CttYUqzS.js} +1 -1
  305. ksadk/server/static/assets/{dist-ivOya1LD.js → dist-DNp6rLRA.js} +1 -1
  306. ksadk/server/static/assets/{dist-BibcG1V9.js → dist-DUX-id_F.js} +1 -1
  307. ksadk/server/static/assets/{dist-BUHRxvDG.js → dist-DmldrHd_.js} +1 -1
  308. ksadk/server/static/assets/{dist-BZ9n9AjO.js → dist-DnfXs8Vn.js} +2 -2
  309. ksadk/server/static/assets/{dist-DqNnNFrw.js → dist-Dq9gLD7L.js} +1 -1
  310. ksadk/server/static/assets/{dist-CGcp2ex8.js → dist-W-TIVntx.js} +1 -1
  311. ksadk/server/static/assets/{dist-Cwt7koer.js → dist-dDdADKFA.js} +1 -1
  312. ksadk/server/static/assets/{dist-C7-3jInC.js → dist-dydu68Fl.js} +1 -1
  313. ksadk/server/static/assets/{dist-C99THtIA.js → dist-ngtN0DJB.js} +1 -1
  314. ksadk/server/static/assets/ebnfDiagram-PWID7BFC-Da9C9NO1.js +1 -0
  315. ksadk/server/static/assets/erDiagram-SSCWMZ5O-EAGqqR79.js +99 -0
  316. ksadk/server/static/assets/eventmodeling-NTZA5JFV-CMgMaJrC.js +1 -0
  317. ksadk/server/static/assets/flowDiagram-A5DVABFB-BBKL0x3P.js +1 -0
  318. ksadk/server/static/assets/ganttDiagram-EL5Y4UJY-DqJsKb59.js +292 -0
  319. ksadk/server/static/assets/gitGraph-4MIJSDKK-Dw63mrhw.js +1 -0
  320. ksadk/server/static/assets/gitGraphDiagram-WWUBYQGX-B6g4dtDi.js +106 -0
  321. ksadk/server/static/assets/index-8ipRcQ-M.js +240 -0
  322. ksadk/server/static/assets/index-ByFCqjlh.css +2 -0
  323. ksadk/server/static/assets/info-A6RAGUB7-B6iAblII.js +1 -0
  324. ksadk/server/static/assets/infoDiagram-RXCK75RN-Djm_nbd5.js +2 -0
  325. ksadk/server/static/assets/{ishikawaDiagram-YF4QCWOH-DLOHGvWw.js → ishikawaDiagram-5VMMS53U-DWya9SG2.js} +6 -6
  326. ksadk/server/static/assets/{journeyDiagram-JHISSGLW-BIzKeejT.js → journeyDiagram-EYS64GPL-DutxhSNI.js} +6 -6
  327. ksadk/server/static/assets/{kanban-definition-UN3LZRKU-BWHoFSw2.js → kanban-definition-3QL26DDD-DJdOF8Fm.js} +10 -10
  328. ksadk/server/static/assets/katex-vFWytM5c.js +257 -0
  329. ksadk/server/static/assets/{linear-CvMBw9cA.js → linear-BHjG8b-J.js} +1 -1
  330. ksadk/server/static/assets/mermaid-parser.core-KGSy4jWT.js +166 -0
  331. ksadk/server/static/assets/{mindmap-definition-RKZ34NQL-CSAQxEAe.js → mindmap-definition-FBJOCRG2-9-HC88D4.js} +29 -29
  332. ksadk/server/static/assets/packet-AYTQ26CC-BOYAipuq.js +1 -0
  333. ksadk/server/static/assets/pegDiagram-XKGWAZYB-DrEZd4fD.js +1 -0
  334. ksadk/server/static/assets/pie-WAS4IAKB-Ctq0Kbku.js +1 -0
  335. ksadk/server/static/assets/pieDiagram-E7YTZNPT-DpjqOFFp.js +39 -0
  336. ksadk/server/static/assets/{quadrantDiagram-W4KKPZXB-CxIR4JXI.js → quadrantDiagram-AXDQQJYC-BiNhgOXX.js} +6 -6
  337. ksadk/server/static/assets/radar-RG4KPBEZ-DN0-ul_0.js +1 -0
  338. ksadk/server/static/assets/railroad-74A4TZTK-C6cC_to0.js +1 -0
  339. ksadk/server/static/assets/railroad-abnf-HS5TGJTU-BimjIuRc.js +1 -0
  340. ksadk/server/static/assets/railroad-ebnf-LZEXJU2U-CvY65ABq.js +1 -0
  341. ksadk/server/static/assets/railroad-peg-WCYAUIDC-D72Iq_Tv.js +1 -0
  342. ksadk/server/static/assets/railroadDiagram-O6MQD6OU-_Y3Ojg6G.js +1 -0
  343. ksadk/server/static/assets/requirementDiagram-EFPCY7ZU-DeCFdg9K.js +84 -0
  344. ksadk/server/static/assets/{sankeyDiagram-5OEKKPKP-DpGa6EAV.js → sankeyDiagram-P5KCCOFB-CPH75rhw.js} +7 -7
  345. ksadk/server/static/assets/{sequenceDiagram-3UESZ5HK-NTKNGGe5.js → sequenceDiagram-WJ2MYXX4-OEpQQdr4.js} +10 -10
  346. ksadk/server/static/assets/sizeCapture-X5ZJPWSS-heUErzhI.js +1 -0
  347. ksadk/server/static/assets/stateDiagram-HBIQ2CUA-DvA3jSMB.js +1 -0
  348. ksadk/server/static/assets/stateDiagram-v2-4QOOHH4V-BgQY03nz.js +1 -0
  349. ksadk/server/static/assets/swimlanes-XN3QIQJK-CR-dfN_t.js +1 -0
  350. ksadk/server/static/assets/swimlanesDiagram-VK2B7HYN-DLVw3q5Q.js +8 -0
  351. ksadk/server/static/assets/{timeline-definition-PNZ67QCA-jqoYs3jQ.js → timeline-definition-24CTP7MA-DAVJf1TX.js} +7 -7
  352. ksadk/server/static/assets/treeView-Q6P3EWNA-BMpO0wsB.js +1 -0
  353. ksadk/server/static/assets/treemap-WGGIJYW6-Et0aqzU3.js +1 -0
  354. ksadk/server/static/assets/vennDiagram-4TSXK5OY-DwM8eDkh.js +34 -0
  355. ksadk/server/static/assets/wardley-WFR3VGLG-CbY0mhpl.js +1 -0
  356. ksadk/server/static/assets/wardleyDiagram-VM6X3IG4-DZL-Zz2t.js +78 -0
  357. ksadk/server/static/assets/xychartDiagram-S5SC5T6Z-Dy6Yh_hu.js +7 -0
  358. ksadk/server/static/index.html +2 -2
  359. ksadk/sessions/__init__.py +26 -9
  360. ksadk/sessions/_local_service_sync.py +688 -0
  361. ksadk/sessions/_local_tables.py +21 -0
  362. ksadk/sessions/_postgres_schema.py +305 -0
  363. ksadk/sessions/_postgres_tables.py +15 -0
  364. ksadk/sessions/base.py +80 -1
  365. ksadk/sessions/in_memory.py +53 -2
  366. ksadk/sessions/local_service.py +63 -604
  367. ksadk/sessions/postgres_service.py +58 -148
  368. ksadk/sessions/resilient.py +35 -1
  369. ksadk/skills/runtime/backends/e2b.py +1 -1
  370. ksadk/skills/service_client.py +13 -3
  371. ksadk/studio/__init__.py +5 -0
  372. ksadk/studio/agent_avatar_assets.py +120 -0
  373. ksadk/studio/agent_lifecycle.py +51 -0
  374. ksadk/studio/api.py +1598 -0
  375. ksadk/studio/api_catalog_routes.py +324 -0
  376. ksadk/studio/api_contracts.py +286 -0
  377. ksadk/studio/api_helpers.py +132 -0
  378. ksadk/studio/api_memory_routes.py +82 -0
  379. ksadk/studio/authoring.py +749 -0
  380. ksadk/studio/authoring_coordinator.py +1017 -0
  381. ksadk/studio/builder.py +397 -0
  382. ksadk/studio/capabilities.py +368 -0
  383. ksadk/studio/cloud.py +2099 -0
  384. ksadk/studio/codex_agent_service.py +694 -0
  385. ksadk/studio/codex_authoring.py +469 -0
  386. ksadk/studio/codex_builder.py +437 -0
  387. ksadk/studio/codex_manifest.py +307 -0
  388. ksadk/studio/codex_run.py +395 -0
  389. ksadk/studio/compiler.py +190 -0
  390. ksadk/studio/contracts.py +755 -0
  391. ksadk/studio/errors.py +47 -0
  392. ksadk/studio/event_store.py +214 -0
  393. ksadk/studio/framework_run.py +342 -0
  394. ksadk/studio/hosted_kernel.py +317 -0
  395. ksadk/studio/identifiers.py +33 -0
  396. ksadk/studio/manifest_resolver.py +131 -0
  397. ksadk/studio/mcp_runtime.py +229 -0
  398. ksadk/studio/model_client.py +629 -0
  399. ksadk/studio/model_profile_service.py +214 -0
  400. ksadk/studio/operations.py +275 -0
  401. ksadk/studio/otel_trace.py +1060 -0
  402. ksadk/studio/pagination.py +182 -0
  403. ksadk/studio/pcm_memory.py +85 -0
  404. ksadk/studio/python_tool_inspection.py +183 -0
  405. ksadk/studio/repository.py +327 -0
  406. ksadk/studio/resource_catalog.py +1260 -0
  407. ksadk/studio/run_service.py +1133 -0
  408. ksadk/studio/runtime_catalog.py +74 -0
  409. ksadk/studio/runtime_source.py +365 -0
  410. ksadk/studio/service.py +2249 -0
  411. ksadk/studio/shared_web.py +1004 -0
  412. ksadk/studio/skill_discovery.py +628 -0
  413. ksadk/studio/static/assets/PrismRenderer-IYN-ffww.js +3 -0
  414. ksadk/studio/static/assets/index-BLpcdrgW.css +1 -0
  415. ksadk/studio/static/assets/index-CYekR2Xv.js +260 -0
  416. ksadk/studio/static/assets/react-vendor-BNmTiJ-I.js +9 -0
  417. ksadk/studio/static/assets/rolldown-runtime-hePW80VL.js +1 -0
  418. ksadk/studio/static/index.html +15 -0
  419. ksadk/studio/templates.py +722 -0
  420. ksadk/studio/validator.py +265 -0
  421. ksadk/studio/workspace.py +135 -0
  422. ksadk/tools/gateway.py +9 -0
  423. ksadk/toolsets/__init__.py +27 -1
  424. ksadk/toolsets/a2a.py +426 -0
  425. ksadk/tracing/__init__.py +19 -21
  426. ksadk/tracing/setup.py +317 -403
  427. ksadk/tracing/span_utils.py +0 -44
  428. ksadk/version.py +1 -1
  429. ksadk_runtime_common/memory_backend/registry.py +56 -56
  430. ksadk_runtime_common/schemas/runtime_event_v1.json +37 -0
  431. ksadk_runtime_common/schemas/runtime_event_v2.json +271 -0
  432. ksadk_runtime_common/workspace_files/router.py +8 -2
  433. agentengine_sdk_python-0.8.0.dist-info/RECORD +0 -578
  434. ksadk/a2a/card_builder.py +0 -64
  435. ksadk/a2a/client.py +0 -309
  436. ksadk/events/parser.py +0 -191
  437. ksadk/harness/runner.py +0 -211
  438. ksadk/runners/codex_runner.py +0 -132
  439. ksadk/runners/utils/langfuse.py +0 -230
  440. ksadk/server/static/assets/MathMessageMarkdown-DeYh8QPr.css +0 -1
  441. ksadk/server/static/assets/MermaidBlock-DWuxETaJ.js +0 -303
  442. ksadk/server/static/assets/NativeTerminalPanel-MDTopWMO.js +0 -1
  443. ksadk/server/static/assets/arc-CFKwSk_B.js +0 -1
  444. ksadk/server/static/assets/architecture-7EHR7CIX-CynqOWjZ.js +0 -1
  445. ksadk/server/static/assets/architectureDiagram-3BPJPVTR-Dej8jX8c.js +0 -36
  446. ksadk/server/static/assets/blockDiagram-GPEHLZMM-1F64jqvy.js +0 -132
  447. ksadk/server/static/assets/c4Diagram-AAUBKEIU-9q7AUAKb.js +0 -10
  448. ksadk/server/static/assets/channel-iUGv2N24.js +0 -1
  449. ksadk/server/static/assets/chunk-2J33WTMH-6qgwJm7Q.js +0 -1
  450. ksadk/server/static/assets/chunk-55IACEB6-BK8paA20.js +0 -1
  451. ksadk/server/static/assets/chunk-727SXJPM-B-JEhy7h.js +0 -206
  452. ksadk/server/static/assets/chunk-AQP2D5EJ-DYBvMHAa.js +0 -231
  453. ksadk/server/static/assets/chunk-QZHKN3VN-YQIEXeF6.js +0 -1
  454. ksadk/server/static/assets/classDiagram-4FO5ZUOK-CDAUuoXK.js +0 -1
  455. ksadk/server/static/assets/classDiagram-v2-Q7XG4LA2-CDAUuoXK.js +0 -1
  456. ksadk/server/static/assets/cytoscape.esm-DelgaX4f.js +0 -321
  457. ksadk/server/static/assets/dagre-BM42HDAG-C7TguAWo.js +0 -4
  458. ksadk/server/static/assets/dagre-Bx709z4p.js +0 -1
  459. ksadk/server/static/assets/diagram-2AECGRRQ-Dd17_kws.js +0 -43
  460. ksadk/server/static/assets/diagram-5GNKFQAL-DVIClIil.js +0 -10
  461. ksadk/server/static/assets/diagram-KO2AKTUF-Df_3gYQa.js +0 -3
  462. ksadk/server/static/assets/diagram-LMA3HP47-BhLk6ZtA.js +0 -24
  463. ksadk/server/static/assets/diagram-OG6HWLK6-D4GNGvuu.js +0 -24
  464. ksadk/server/static/assets/dist-DyvYLMW9.js +0 -1
  465. ksadk/server/static/assets/erDiagram-TEJ5UH35-CnfRcY2M.js +0 -85
  466. ksadk/server/static/assets/eventmodeling-FCH6USID-ChYO-ijM.js +0 -1
  467. ksadk/server/static/assets/flowDiagram-I6XJVG4X-DGaJjGNJ.js +0 -162
  468. ksadk/server/static/assets/ganttDiagram-6RSMTGT7-DpCoB2g9.js +0 -292
  469. ksadk/server/static/assets/gitGraph-WXDBUCRP-BN_0Fk-j.js +0 -1
  470. ksadk/server/static/assets/gitGraphDiagram-PVQCEYII-9IKVFBVT.js +0 -106
  471. ksadk/server/static/assets/graphlib-B8gBHxth.js +0 -1
  472. ksadk/server/static/assets/index-QSwCHuB8.js +0 -177
  473. ksadk/server/static/assets/index-jOPmTOZH.css +0 -2
  474. ksadk/server/static/assets/info-J43DQDTF-Cp6o3vId.js +0 -1
  475. ksadk/server/static/assets/infoDiagram-5YYISTIA-CYIIsb8y.js +0 -2
  476. ksadk/server/static/assets/katex-DATssjp1.js +0 -265
  477. ksadk/server/static/assets/mermaid-parser.core-mGAcEwcq.js +0 -161
  478. ksadk/server/static/assets/packet-YPE3B663-wQzct3cT.js +0 -1
  479. ksadk/server/static/assets/pie-LRSECV5Y-BgTQiv-9.js +0 -1
  480. ksadk/server/static/assets/pieDiagram-4H26LBE5-By-ra07M.js +0 -30
  481. ksadk/server/static/assets/radar-GUYGQ44K-BIq5fXsn.js +0 -1
  482. ksadk/server/static/assets/requirementDiagram-4Y6WPE33-DpW90iu3.js +0 -84
  483. ksadk/server/static/assets/stateDiagram-AJRCARHV-DGpd9yFG.js +0 -1
  484. ksadk/server/static/assets/stateDiagram-v2-BHNVJYJU-B3o579IQ.js +0 -1
  485. ksadk/server/static/assets/treeView-BLDUP644-Dqi-E0EM.js +0 -1
  486. ksadk/server/static/assets/treemap-LRROVOQU-ClQP9CJ9.js +0 -1
  487. ksadk/server/static/assets/vennDiagram-CIIHVFJN-l3Z7-wbP.js +0 -34
  488. ksadk/server/static/assets/wardley-L42UT6IY-8XLvnNIs.js +0 -1
  489. ksadk/server/static/assets/wardleyDiagram-YWT4CUSO-BR54GPmr.js +0 -78
  490. ksadk/server/static/assets/xychartDiagram-2RQKCTM6-SkiH8GsK.js +0 -7
  491. ksadk/tracing/exporters/langfuse_exporter.py +0 -460
  492. {agentengine_sdk_python-0.8.0.dist-info → agentengine_sdk_python-0.8.2.dist-info}/entry_points.txt +0 -0
  493. {agentengine_sdk_python-0.8.0.dist-info → agentengine_sdk_python-0.8.2.dist-info}/licenses/LICENSE +0 -0
  494. {agentengine_sdk_python-0.8.0.dist-info → agentengine_sdk_python-0.8.2.dist-info}/top_level.txt +0 -0
@@ -1,5 +1,7 @@
1
1
  from __future__ import annotations
2
2
 
3
+ import asyncio
4
+ import logging
3
5
  import uuid
4
6
  from typing import Any, Callable, Dict, Mapping, Optional, Sequence
5
7
 
@@ -13,6 +15,8 @@ from ksadk.conversations.context import (
13
15
  )
14
16
  from ksadk.conversations.model_context import (
15
17
  estimate_text_tokens,
18
+ get_auto_compact_hard_limit_tokens,
19
+ get_auto_compact_soft_limit_tokens,
16
20
  get_auto_compact_threshold_percentage,
17
21
  get_auto_compact_threshold_tokens,
18
22
  )
@@ -33,11 +37,14 @@ from ksadk.conversations.runtime_payloads import CompactionPlan
33
37
  from ksadk.conversations.runtime_persistence import append_context_checkpoint_event
34
38
  from ksadk.conversations.semantic_summary import (
35
39
  extract_pinned_state,
40
+ extract_working_state,
36
41
  find_pinned_group_indexes,
37
42
  summarize_compaction,
38
43
  )
39
44
  from ksadk.sessions import SessionEvent, resolve_session_service
40
45
 
46
+ logger = logging.getLogger(__name__)
47
+
41
48
 
42
49
  def _plan_compaction(
43
50
  events: Sequence[SessionEvent],
@@ -47,8 +54,19 @@ def _plan_compaction(
47
54
  pending_events: Sequence[SessionEvent] | None = None,
48
55
  force: bool = False,
49
56
  keep_tail_groups: int | None = None,
57
+ prompt_integration_mode: str = "",
58
+ compaction_owner: str = "",
50
59
  ) -> CompactionPlan:
51
- """根据当前 transcript 计算是否需要做 checkpoint compaction。"""
60
+ """根据当前 transcript 计算是否需要做 checkpoint compaction。
61
+
62
+ ``compaction_owner=="ksadk"`` 时走双阈值(soft 50% / hard ~84%),命中且
63
+ ``len(groups) > tail_groups`` 时触发 proactive compact(soft=整理,hard=强制止血)。
64
+ 未显式提供 owner 的旧调用继续以 ``ksadk_hosted`` 作为兼容判据。
65
+ ``force=True``(PTL)始终绕过阈值,``trigger_band="emergency"``。
66
+
67
+ compaction_owner 硬门控(方案 §6.2):native/framework owner 不运行 KsADK 第二套
68
+ 压缩;framework-assisted Runner 可显式声明 owner=ksadk 使用平台压缩。
69
+ """
52
70
 
53
71
  compacted_until = compacted_until_seq_id(list(events))
54
72
  transcript_events = [
@@ -82,9 +100,46 @@ def _plan_compaction(
82
100
  total_estimated_tokens = sum(
83
101
  estimate_text_tokens(extract_event_text(event)) for event in combined_events
84
102
  )
85
- if not force and (
86
- len(groups) <= tail_groups or total_estimated_tokens <= auto_compact_threshold_tokens
87
- ):
103
+ # 是否启用双阈值由 compaction ownership 决定,而不是由 Prompt 接管模式决定。
104
+ # framework-assisted LangGraph 也可以把压缩明确交给 KsADK;native/framework
105
+ # owner 则继续使用各自原生机制,避免双重压缩。
106
+ is_ksadk_hosted = compaction_owner == "ksadk" or (
107
+ not compaction_owner and prompt_integration_mode == "ksadk_hosted"
108
+ )
109
+ soft_limit_tokens = (
110
+ get_auto_compact_soft_limit_tokens(resolved_model_metadata) if is_ksadk_hosted else None
111
+ )
112
+ hard_limit_tokens = (
113
+ get_auto_compact_hard_limit_tokens(resolved_model_metadata) if is_ksadk_hosted else None
114
+ )
115
+
116
+ # 触发带判定。force(PTL)优先 → emergency,绕过阈值。
117
+ groups_enough = len(groups) > tail_groups
118
+ if force:
119
+ trigger_band = "emergency"
120
+ should_by_threshold = True
121
+ elif is_ksadk_hosted and soft_limit_tokens is not None and hard_limit_tokens is not None:
122
+ # 双阈值:hard 优先于 soft。二者都需 groups 充足,否则 none(避免每轮压缩)。
123
+ if not groups_enough:
124
+ trigger_band = "none"
125
+ should_by_threshold = False
126
+ elif total_estimated_tokens > hard_limit_tokens:
127
+ trigger_band = "hard"
128
+ should_by_threshold = True
129
+ elif total_estimated_tokens > soft_limit_tokens:
130
+ trigger_band = "soft"
131
+ should_by_threshold = True
132
+ else:
133
+ trigger_band = "none"
134
+ should_by_threshold = False
135
+ else:
136
+ # 非 ksadk_hosted → 旧单阈值。trigger_band="" 表示门控未启用(旧路径)。
137
+ trigger_band = ""
138
+ should_by_threshold = total_estimated_tokens > auto_compact_threshold_tokens
139
+
140
+ # early-return:groups 不足或(非 force 且未超阈值)。保留 len(groups)<=tail_groups 早退,
141
+ # 避免每轮压缩。force 仍绕过此早退的阈值部分,但 groups 不足时 force 也无可压缩(下方)。
142
+ if not force and (len(groups) <= tail_groups or not should_by_threshold):
88
143
  return CompactionPlan(
89
144
  should_compact=False,
90
145
  groups_to_compact=[],
@@ -96,6 +151,9 @@ def _plan_compaction(
96
151
  auto_compact_threshold_percentage=auto_compact_threshold_percentage,
97
152
  pinned_group_indexes=pinned_group_indexes,
98
153
  pinned_state=pinned_state,
154
+ soft_limit_tokens=soft_limit_tokens,
155
+ hard_limit_tokens=hard_limit_tokens,
156
+ trigger_band=trigger_band,
99
157
  )
100
158
 
101
159
  compactable_indexes = [
@@ -121,6 +179,9 @@ def _plan_compaction(
121
179
  auto_compact_threshold_percentage=auto_compact_threshold_percentage,
122
180
  pinned_group_indexes=pinned_group_indexes,
123
181
  pinned_state=pinned_state,
182
+ soft_limit_tokens=soft_limit_tokens,
183
+ hard_limit_tokens=hard_limit_tokens,
184
+ trigger_band=trigger_band,
124
185
  )
125
186
 
126
187
  compacted_until_seq_id_value = groups_to_compact[-1][-1].seq_id or None
@@ -136,6 +197,9 @@ def _plan_compaction(
136
197
  compacted_until_seq_id=compacted_until_seq_id_value,
137
198
  pinned_group_indexes=pinned_group_indexes,
138
199
  pinned_state=pinned_state,
200
+ soft_limit_tokens=soft_limit_tokens,
201
+ hard_limit_tokens=hard_limit_tokens,
202
+ trigger_band=trigger_band,
139
203
  )
140
204
 
141
205
 
@@ -148,6 +212,7 @@ async def preview_auto_compaction(
148
212
  model: Optional[str] = None,
149
213
  model_metadata: Mapping[str, Any] | None = None,
150
214
  session_service_provider: Callable[[], Any] | None = None,
215
+ prompt_integration_mode: str = "",
151
216
  ) -> CompactionPlan:
152
217
  """在真正写入 turn 之前预估是否会触发自动压缩。
153
218
 
@@ -214,9 +279,81 @@ async def preview_auto_compaction(
214
279
  model=model,
215
280
  model_metadata=resolved_model_metadata,
216
281
  pending_events=[pending_event],
282
+ prompt_integration_mode=prompt_integration_mode,
283
+ )
284
+
285
+
286
+ def _working_state_from_checkpoint(checkpoint: Any) -> Any:
287
+ """§8.1:从上一个 context_checkpoint 事件解析 WorkingState(用于缺失字段合并)。
288
+
289
+ checkpoint metadata 由 compact_conversation_history 写入(仅 ksadk_hosted)。无 checkpoint
290
+ 或无 working_state 键时返回 None。重建的 WorkingState 仅用于回填 current_goal/constraints
291
+ 等关键字段,不恢复 pending_tools/approvals(那些以事实事件为准)。
292
+ """
293
+ if checkpoint is None:
294
+ return None
295
+ meta = getattr(checkpoint, "metadata", None) or {}
296
+ ws_audit = meta.get("working_state")
297
+ if not isinstance(ws_audit, dict):
298
+ return None
299
+ from ksadk.conversations.semantic_summary import WorkingState
300
+
301
+ return WorkingState(
302
+ current_goal=str(ws_audit.get("current_goal") or ""),
303
+ next_action=ws_audit.get("next_action"),
304
+ completed_steps=list(ws_audit.get("completed_steps") or []),
305
+ constraints=list(ws_audit.get("constraints") or []),
306
+ source_seq_range=tuple(ws_audit.get("source_seq_range") or (0, 0)), # type: ignore[arg-type]
217
307
  )
218
308
 
219
309
 
310
+ async def _maybe_memory_flush(
311
+ events: Sequence[SessionEvent],
312
+ *,
313
+ user_id: str = "",
314
+ agent_id: str = "",
315
+ ) -> dict[str, Any] | None:
316
+ """压缩前 best-effort Memory Flush(方案 §9.2)。
317
+
318
+ 门控:``KSADK_MEMORY_FLUSH_ENABLED``(默认关,避免在无 Memory Provider 时改变行为)+
319
+ ``KSADK_MEMORY_FLUSH_BEFORE_COMPACTION``(默认开,但需前者总开关)。提取候选交
320
+ ``MemoryCoordinator.flush_candidates``,Policy 决定 commit/reject。失败返回 ``failed``,不抛。
321
+ """
322
+ import os as _os
323
+
324
+ if _os.environ.get("KSADK_MEMORY_FLUSH_ENABLED", "").strip().lower() not in (
325
+ "1",
326
+ "true",
327
+ "yes",
328
+ "on",
329
+ ):
330
+ return None
331
+ try:
332
+ from ksadk.context_engine.policies import ContextPolicy
333
+ from ksadk.memory.coordinator import MemoryCoordinator
334
+ from ksadk.memory.extraction import propose_memory_candidates
335
+ from ksadk.memory.providers.local_sqlite import resolve_default_memory_provider
336
+
337
+ policy = ContextPolicy.from_env()
338
+ if not policy.compaction.flush_memory_before_compaction:
339
+ return None
340
+ # 持久化 Memory Provider(替换临时 :memory:,方案 §10/§12)。云端应经
341
+ # LongTermMemoryService/HTTP/SDK Provider;本地默认 SQLite 文件库。
342
+ provider = resolve_default_memory_provider()
343
+ coordinator = MemoryCoordinator(provider)
344
+ from ksadk.memory.coordinator import agent_user_scope_id
345
+
346
+ _scope_id = agent_user_scope_id(agent_id=agent_id, user_id=str(user_id or ""))
347
+ candidates = propose_memory_candidates(list(events), scope="user", scope_id=_scope_id)
348
+ if not candidates:
349
+ return {"status": "skipped", "proposed": 0, "committed": 0, "rejected": 0}
350
+ result = coordinator.flush_candidates(candidates)
351
+ return result.to_audit_dict()
352
+ except Exception as exc: # noqa: BLE001
353
+ logger.warning("memory flush failed: %s", exc)
354
+ return {"status": "failed", "error": str(exc), "proposed": 0, "committed": 0, "rejected": 0}
355
+
356
+
220
357
  async def compact_conversation_history(
221
358
  *,
222
359
  session_id: str,
@@ -228,21 +365,29 @@ async def compact_conversation_history(
228
365
  trigger: str = "auto",
229
366
  keep_tail_groups: Optional[int] = None,
230
367
  session_service_provider: Callable[[], Any] | None = None,
368
+ prompt_integration_mode: str = "",
369
+ compaction_owner: str = "",
231
370
  ) -> SessionEvent | None:
232
371
  """把旧轮次折叠为 checkpoint。
233
372
 
234
373
  这是本地版的 compaction:先按 API round 分组,再保留尾部若干轮,把更早
235
374
  的部分压成 append-only summary 事件。force=True 时用于 PTL 恢复。
375
+
376
+ compaction_owner 硬门控(方案 §6.2):非 ksadk 时不走 KsADK 双阈值压缩。
236
377
  """
237
378
  provider = session_service_provider or resolve_session_service
238
379
  service = provider()
239
380
  events = await service.get_events(session_id)
381
+ session = await service.get_session(session_id)
382
+ memory_user_id = str(getattr(session, "user_id", "") or "")
240
383
  plan = _plan_compaction(
241
384
  events,
242
385
  model=model,
243
386
  model_metadata=model_metadata,
244
387
  force=force,
245
388
  keep_tail_groups=keep_tail_groups,
389
+ prompt_integration_mode=prompt_integration_mode,
390
+ compaction_owner=compaction_owner,
246
391
  )
247
392
  if not plan.should_compact:
248
393
  return None
@@ -285,7 +430,38 @@ async def compact_conversation_history(
285
430
  # L5 working set 恢复(保守版):只记 metadata,不读文件内容。
286
431
  working_set = build_working_set_metadata(pinned_state=plan.pinned_state)
287
432
 
288
- return await append_context_checkpoint_event(
433
+ # PR D2:Session Working State(仅 ksadk_hosted)。从事实事件确定性提取,
434
+ # 写进 checkpoint metadata 供下一轮门控重注入。非门控不写(向后兼容)。
435
+ working_state_audit: dict[str, Any] | None = None
436
+ # PR D2.5:Memory Flush(方案 §9.2)。仅 ksadk_hosted + policy 开启时,压缩前 best-effort
437
+ # 提取候选并提交;失败不阻止 compaction(§9.2 失败语义)。非门控不执行(向后兼容)。
438
+ memory_flush_audit: dict[str, Any] | None = None
439
+ if (
440
+ compaction_owner == "ksadk"
441
+ or (not compaction_owner and prompt_integration_mode == "ksadk_hosted")
442
+ ) and plan.groups_to_compact:
443
+ compacted_events = [event for group in plan.groups_to_compact for event in group]
444
+ seq_range = (
445
+ int(plan.groups_to_compact[0][0].seq_id or 0),
446
+ int(plan.groups_to_compact[-1][-1].seq_id or 0),
447
+ )
448
+ working_state = extract_working_state(
449
+ compacted_events,
450
+ pinned_state=plan.pinned_state,
451
+ summary_text=summary_result.summary_text,
452
+ source_seq_range=seq_range,
453
+ )
454
+ # §8.1:关键字段缺失时用压缩前 checkpoint 的 WorkingState 合并,不接受空值覆盖。
455
+ previous_ws = _working_state_from_checkpoint(latest_checkpoint)
456
+ working_state.merge_missing_from(previous_ws)
457
+ working_state_audit = working_state.to_audit_dict()
458
+ memory_flush_audit = await _maybe_memory_flush(
459
+ compacted_events, user_id=memory_user_id, agent_id=author
460
+ )
461
+
462
+ # PR D2.6:per-session compaction lock + stale guard(方案 §9.6)。同一 session 同时只
463
+ # 允许一个 checkpoint/WorkingState 提交;拿不到锁则放弃本次提交避免并发覆盖。
464
+ _checkpoint_kwargs = dict(
289
465
  session_id=session_id,
290
466
  author=author,
291
467
  compacted_until_seq_id=compacted_until_seq_id_value,
@@ -328,6 +504,32 @@ async def compact_conversation_history(
328
504
  else None
329
505
  ),
330
506
  "working_set": working_set,
507
+ # PR D1:双阈值带标记(""=非门控旧路径 / "soft" / "hard" / "emergency"=PTL)。
508
+ # 仅审计用,不改变既有 trigger 字段;trigger 仍为调用方值。
509
+ "trigger_band": plan.trigger_band,
510
+ # PR D2:Session Working State(仅 ksadk_hosted)。结构化工作面,供下一轮门控重注入。
511
+ # 含 content_hash/source_seq_range/status,无 prompt 明文。非门控不写该键(向后兼容)。
512
+ **({"working_state": working_state_audit} if working_state_audit is not None else {}),
513
+ # PR D2.5:Memory Flush 审计(方案 §9.2)。失败不阻止 compaction。
514
+ **({"memory_flush": memory_flush_audit} if memory_flush_audit is not None else {}),
515
+ # PR D2:tokens_by_kind before/after(从 pipeline stats 取,审计用)。
516
+ "tokens_by_kind_before": {"transcript": pipeline_result["tokens_before"]},
517
+ "tokens_by_kind_after": {"transcript": pipeline_result["tokens_after"]},
331
518
  },
332
519
  session_service_provider=provider,
333
520
  )
521
+ try:
522
+ from ksadk.conversations.session_lock import session_compaction_lock
523
+ except Exception: # noqa: BLE001
524
+ session_compaction_lock = None # type: ignore[assignment]
525
+ if session_compaction_lock is None:
526
+ return await append_context_checkpoint_event(**_checkpoint_kwargs)
527
+ try:
528
+ async with session_compaction_lock(session_id):
529
+ return await append_context_checkpoint_event(**_checkpoint_kwargs)
530
+ except asyncio.TimeoutError:
531
+ logger.warning(
532
+ "session compaction lock timeout for %s; skipping checkpoint commit",
533
+ session_id,
534
+ )
535
+ return None
@@ -48,6 +48,74 @@ def _env_flag(name: str, default: bool = True) -> bool:
48
48
  return normalized not in {"0", "false", "no", "off"}
49
49
 
50
50
 
51
+ def _prompt_compiler_enabled() -> bool:
52
+ """PR B:全局 kill switch。默认关——关闭时 Runner 输入与旧逻辑字节级一致。
53
+
54
+ 接管由三重门控共同决定:本 flag × per-Agent ``prompt_integration_mode``
55
+ (由 ``prompt_ownership=ksadk`` 标记的 per-Build)× runner 类型限定 LangGraph。
56
+ 任一不满足 → ``_should_project_compiled_prompt`` 返回 False → 走旧 ``instructions`` 分支。
57
+ """
58
+ return _env_flag("KSADK_PROMPT_COMPILER_ENABLED", False)
59
+
60
+
61
+ def _should_project_compiled_prompt(
62
+ *, prepared: PreparedConversationTurn, runner: Any | None
63
+ ) -> bool:
64
+ """PR B:判断本 turn 是否用 ``compiled_prompt`` 接管 ``payload["instructions"]``。
65
+
66
+ 满足全部条件才接管:
67
+ 1. 全局 flag 开(``KSADK_PROMPT_COMPILER_ENABLED``);
68
+ 2. per-Build 接管标记 ``prompt_integration_mode=="ksadk_hosted"``
69
+ (仅 ``prompt_ownership=ksadk``);
70
+ 3. 已编译出真实 CompiledPrompt 且含非空 ``prompt_content``(agent_system/agent_task 非空,
71
+ 非 resume 旁路);
72
+ 4. runner 类型为 langgraph(ADK/Codex 接管错位,排除)。
73
+
74
+ 任一不满足 → 返回 False → 调用方走 ``elif`` 分支 == 旧 ``if``,字节级一致。
75
+ """
76
+ if not _prompt_compiler_enabled():
77
+ return False
78
+ if prepared.prompt_integration_mode != "ksadk_hosted":
79
+ return False
80
+ compiled = prepared.compiled_prompt
81
+ if not isinstance(compiled, Mapping):
82
+ return False
83
+ content = compiled.get("prompt_content")
84
+ if not isinstance(content, str) or not content.strip():
85
+ return False
86
+ return _runner_type_name(runner) == "langgraph"
87
+
88
+
89
+ def _should_use_hosted_assembly(*, prepared: PreparedConversationTurn, runner: Any | None) -> bool:
90
+ """PR E:判断本 turn 是否用 hosted pipeline 的 assembled_input 接管 payload。
91
+
92
+ 条件:``assembled_input`` 已生成(build_run_input 在 V2 门控下产出)且 runner 为
93
+ langgraph 系(prompt_owner=ksadk)。该分支优先于 PR B/D2;满足时直接 return,不双重注入。
94
+ native_runtime(codex)的 ``assembled_input`` 恒为 None(build_run_input 不为它生成),
95
+ 故 Managed Codex 不受影响(方案 §6.2 / PCM-RUNNER-003)。
96
+ """
97
+ if not isinstance(prepared.assembled_input, Mapping):
98
+ return False
99
+ if not str(prepared.assembled_input.get("system") or "").strip():
100
+ return False
101
+ return _runner_type_name(runner) == "langgraph"
102
+
103
+
104
+ def _assembled_input(prepared: PreparedConversationTurn) -> Any:
105
+ """把 prepared.assembled_input 的 plain dict 还原成 assembler 能消费的形式。"""
106
+ from ksadk.context_engine.assembler import AssembledInput
107
+
108
+ d = prepared.assembled_input
109
+ return AssembledInput(
110
+ format=d.get("format", "chat"),
111
+ system=str(d.get("system") or ""),
112
+ messages=list(d.get("messages") or []),
113
+ responses_items=[],
114
+ estimated_tokens=int(d.get("estimated_tokens") or 0),
115
+ warnings=tuple(d.get("warnings") or ()),
116
+ )
117
+
118
+
51
119
  def _ltm_auto_save_enabled() -> bool:
52
120
  backend = str(os.getenv("KSADK_LTM_BACKEND") or "").strip().lower()
53
121
  namespace = str(os.getenv("KSADK_LTM_NAMESPACE") or "").strip()
@@ -83,10 +151,19 @@ def _ambient_context_has_error(context: Any) -> bool:
83
151
  if not isinstance(context, dict):
84
152
  return True
85
153
 
154
+ # 显式 error 字段(PR:Memory Recall 失败语义):build_context 失败时把原因放
155
+ # 独立 ``error`` 字段、``formatted_text`` 置空,错误不进模型上下文。
156
+ if str(context.get("error") or "").strip():
157
+ return True
158
+
86
159
  formatted_text = str(context.get("formatted_text") or "").strip()
160
+ # 真无记忆不是可注入的上下文。它不是 provider failure,但对投影层而言
161
+ # 同样应被丢弃,避免 UI 和审计把空召回误报成“已使用长期记忆”。
87
162
  if not formatted_text:
88
163
  return True
89
164
 
165
+ # 纵深防御:``search_text``(工具路径)仍会把错误塞进正文,这里按前缀兜底,
166
+ # 防止任何直接调 ``search_text`` 拼上下文的路径把错误字符串注入。
90
167
  failure_prefixes = (
91
168
  "知识库检索失败",
92
169
  "长期记忆检索失败",
@@ -350,6 +427,7 @@ def _build_runner_ambient_contexts(
350
427
  contexts: dict[str, Any] = {
351
428
  "kb_context": None,
352
429
  "memory_context": None,
430
+ "memory_recall_events": [],
353
431
  }
354
432
  normalized_input = str(user_input or "").strip()
355
433
  if not normalized_input or not _should_use_platform_ambient_context(runner):
@@ -379,8 +457,18 @@ def _build_runner_ambient_contexts(
379
457
  )
380
458
  if not _ambient_context_has_error(memory_context):
381
459
  contexts["memory_context"] = memory_context
460
+ contexts.setdefault("memory_recall_events", []).append(
461
+ {"type": "memory.recall.completed", "count": 1}
462
+ )
463
+ else:
464
+ contexts.setdefault("memory_recall_events", []).append(
465
+ {"type": "memory.recall.empty"}
466
+ )
382
467
  except Exception as exc:
383
468
  logger.warning("Failed to build ambient memory context: %s", exc)
469
+ contexts.setdefault("memory_recall_events", []).append(
470
+ {"type": "memory.recall.failed", "error": str(exc)[:200]}
471
+ )
384
472
 
385
473
  return contexts
386
474
 
@@ -417,7 +505,31 @@ def _build_runner_request_payload(
417
505
  # (for example, its conversation approval profile) without leaking
418
506
  # caller public metadata into the agent payload.
419
507
  payload["request_metadata"] = dict(prepared.request_metadata)
420
- if prepared.instructions:
508
+ # PR E:hosted pipeline 接管(最高优先级)。当 build_run_input 产出 assembled_input 时,
509
+ # 用组装好的 system/input/history 直接覆盖 payload——它已含 compiled_prompt + working_state
510
+ # + planner 决策后的有序 messages。此分支满足后不再走 PR B/D2(避免双重注入)。
511
+ if _should_use_hosted_assembly(prepared=prepared, runner=runner):
512
+ from ksadk.context_engine.hosted_pipeline import assembled_to_payload
513
+
514
+ override = assembled_to_payload(_assembled_input(prepared))
515
+ if override["instructions"]:
516
+ payload["instructions"] = override["instructions"]
517
+ if override["input"]:
518
+ payload["input"] = override["input"]
519
+ # An empty assembled history is authoritative: on the first turn the
520
+ # just-persisted user event must not survive from ``prepared.history``
521
+ # and be injected alongside the canonical current input.
522
+ payload["history"] = override["history"]
523
+ payload["context_plan_id"] = (
524
+ prepared.context_plan.get("plan_id") if prepared.context_plan else None
525
+ )
526
+ return payload
527
+ # PR B:LangGraph CompiledPrompt→instructions 接管。三重门控满足时,把
528
+ # payload["instructions"] 替换为 CompiledPrompt.content(XML),使 agent_system/
529
+ # agent_task 首次进模型输入。任一门控不满足 → elif == 旧逻辑(字节级一致)。
530
+ if _should_project_compiled_prompt(prepared=prepared, runner=runner):
531
+ payload["instructions"] = prepared.compiled_prompt["prompt_content"]
532
+ elif prepared.instructions:
421
533
  payload["instructions"] = prepared.instructions
422
534
  if prepared.resume_input is not None:
423
535
  if _is_checkpoint_resume_input(prepared.resume_input):
@@ -431,7 +543,15 @@ def _build_runner_request_payload(
431
543
  prepared.resume_input.get("checkpoint_metadata") or {}
432
544
  )
433
545
  else:
434
- payload["input"] = prepared.resume_input
546
+ resume_input = dict(prepared.resume_input)
547
+ gateway_approval_resume = bool(
548
+ resume_input.pop("_ksadk_gateway_approval_resume", False)
549
+ )
550
+ if gateway_approval_resume and bool(
551
+ getattr(runner, "supports_gateway_approval_semantic_resume", False)
552
+ ):
553
+ resume_input["_ksadk_gateway_approval_resume"] = True
554
+ payload["input"] = resume_input
435
555
  payload["resume"] = True
436
556
  previous_response_id = prepared.request_metadata.get("previous_response_id")
437
557
  if previous_response_id:
@@ -446,9 +566,74 @@ def _build_runner_request_payload(
446
566
  deferred_tool_names = _extract_deferred_tool_names(prepared.request_metadata)
447
567
  if deferred_tool_names:
448
568
  payload["deferred_tool_names"] = deferred_tool_names
569
+ # PR D2:WorkingState 门控重注入。仅 ksadk_hosted + 有 working_state 时,把结构化工作面
570
+ # 渲染成 XML 段追加进 instructions(与 CompiledPrompt.content 风格一致,LangGraph _to_state
571
+ # 能消费 instructions 字符串)。非门控或有 CompiledPrompt 接管时仍由前者决定 instructions。
572
+ _maybe_inject_working_state(payload, prepared)
449
573
  return payload
450
574
 
451
575
 
576
+ def _maybe_inject_working_state(
577
+ payload: dict[str, Any], prepared: PreparedConversationTurn
578
+ ) -> None:
579
+ """PR D2:把 working_state 渲染成 <working_state> XML 段追加进 payload instructions。
580
+
581
+ 门控:仅 ``prompt_integration_mode=="ksadk_hosted"`` 且 ``working_state`` 非空时注入。
582
+ 与 PR B 的 CompiledPrompt 接管叠加:若 instructions 已被 CompiledPrompt 接管(XML),
583
+ WorkingState 段追加在其后;否则追加在 request instructions 后。非门控零注入。
584
+ Prompt 明文不进 Trace(working_state 不进 shadow plan/trace)。
585
+ """
586
+ if prepared.prompt_integration_mode != "ksadk_hosted":
587
+ return
588
+ ws = prepared.working_state
589
+ if not isinstance(ws, Mapping) or not ws:
590
+ return
591
+ xml = _render_working_state_xml(ws)
592
+ if not xml:
593
+ return
594
+ existing = str(payload.get("instructions") or "").strip()
595
+ if existing:
596
+ payload["instructions"] = f"{existing}\n\n{xml}"
597
+ else:
598
+ payload["instructions"] = xml
599
+
600
+
601
+ def _render_working_state_xml(ws: Mapping[str, Any]) -> str:
602
+ """把 working_state 审计 dict 渲染成 <working_state> XML 段(供模型理解当前工作面)。"""
603
+ current_goal = str(ws.get("current_goal") or "").strip()
604
+ next_action = str(ws.get("next_action") or "").strip()
605
+ active_files = ws.get("active_files") or []
606
+ pending_tools = ws.get("pending_tools") or []
607
+ pending_approvals = ws.get("pending_approvals") or []
608
+ lines: list[str] = []
609
+ if current_goal:
610
+ lines.append(f"当前目标:{current_goal}")
611
+ if next_action:
612
+ lines.append(f"下一步:{next_action}")
613
+ if isinstance(active_files, list) and active_files:
614
+ files = ", ".join(
615
+ str((f.get("path") if isinstance(f, Mapping) else "") or "") for f in active_files
616
+ ).strip(", ")
617
+ if files:
618
+ lines.append(f"活跃文件:{files}")
619
+ if isinstance(pending_tools, list) and pending_tools:
620
+ tools = "; ".join(
621
+ str((t.get("text") if isinstance(t, Mapping) else "") or "") for t in pending_tools
622
+ ).strip("; ")
623
+ if tools:
624
+ lines.append(f"未完成工具:{tools}")
625
+ if isinstance(pending_approvals, list) and pending_approvals:
626
+ approvals = "; ".join(
627
+ str((a.get("text") if isinstance(a, Mapping) else "") or "") for a in pending_approvals
628
+ ).strip("; ")
629
+ if approvals:
630
+ lines.append(f"待审批:{approvals}")
631
+ if not lines:
632
+ return ""
633
+ body = "\n".join(lines)
634
+ return f"<working_state>\n{body}\n</working_state>"
635
+
636
+
452
637
  def _inject_runner_deferred_tools_for_request(
453
638
  runner: Any, prepared: PreparedConversationTurn
454
639
  ) -> None:
@@ -563,7 +748,12 @@ async def _auto_save_ltm_turn(
563
748
  runner_type: str,
564
749
  model: str | None,
565
750
  ) -> None:
566
- if prepared.resume_input is not None or not _ltm_auto_save_enabled():
751
+ if prepared.resume_input is not None:
752
+ return
753
+ memory_rollout = str(prepared.memory_write_rollout or "").strip().lower()
754
+ if memory_rollout in {"off", "shadow"}:
755
+ return
756
+ if not memory_rollout and not _ltm_auto_save_enabled():
567
757
  return
568
758
 
569
759
  metadata: dict[str, Any] = {