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
@@ -0,0 +1,164 @@
1
+ """TokenCounter 协议与启发式实现。
2
+
3
+ 对齐方案 8.9。实现顺序应是 provider 官方 tokenizer → 兼容 tokenizer → CJK+ASCII
4
+ 启发式。第一个 PR 只落地启发式实现(复用现有 ``estimate_text_tokens``),并记录所用
5
+ tokenizer 名称;只有 heuristic 可用时由调用方自行加安全系数。tiktoken/provider
6
+ tokenizer 接入留后续 PR。
7
+ """
8
+
9
+ from __future__ import annotations
10
+
11
+ import os
12
+ from typing import Any, Protocol, Sequence
13
+
14
+ HEURISTIC_TOKENIZER_NAME = "heuristic_cjk_ascii"
15
+
16
+
17
+ class TokenCounter(Protocol):
18
+ """token 计数协议。"""
19
+
20
+ name: str
21
+
22
+ def count_text(self, text: str, *, model: str | None = None) -> int: ...
23
+
24
+ def count_messages(self, messages: Sequence[Any], *, model: str | None = None) -> int: ...
25
+
26
+
27
+ class HeuristicTokenCounter:
28
+ """复用 ``ksadk.conversations.model_context.estimate_text_tokens`` 的启发式计数器。
29
+
30
+ CJK 字符按约 1.5 token,其他按 4 chars ~= 1 token。不是真实 tokenizer,但比纯英文
31
+ 口径更接近本地中文使用体验。第一个 PR 的 shadow ContextPlan 只用它做可观测估算,
32
+ 不进任何决策路径。
33
+ """
34
+
35
+ name = HEURISTIC_TOKENIZER_NAME
36
+
37
+ def count_text(self, text: str, *, model: str | None = None) -> int:
38
+ from ksadk.conversations.model_context import estimate_text_tokens
39
+
40
+ return estimate_text_tokens(text)
41
+
42
+ def count_messages(self, messages: Sequence[Any], *, model: str | None = None) -> int:
43
+ from ksadk.conversations.model_context import estimate_text_tokens
44
+
45
+ total = 0
46
+ for message in messages:
47
+ total += self._count_message(message, estimate_text_tokens)
48
+ return total
49
+
50
+ @staticmethod
51
+ def _count_message(message: Any, estimator: Any) -> int:
52
+ if isinstance(message, str):
53
+ return estimator(message)
54
+ if isinstance(message, dict):
55
+ total = 0
56
+ for key in ("content", "text", "output"):
57
+ value = message.get(key)
58
+ if isinstance(value, str):
59
+ total += estimator(value)
60
+ elif isinstance(value, list):
61
+ for part in value:
62
+ if isinstance(part, dict):
63
+ text = part.get("text") or part.get("content")
64
+ if isinstance(text, str):
65
+ total += estimator(text)
66
+ elif isinstance(part, str):
67
+ total += estimator(part)
68
+ role = message.get("role")
69
+ if isinstance(role, str):
70
+ total += estimator(role)
71
+ return total
72
+ # LangChain/BaseMessage 风格对象:尽量取 content。
73
+ content = getattr(message, "content", None)
74
+ if isinstance(content, str):
75
+ return estimator(content)
76
+ if isinstance(content, list):
77
+ total = 0
78
+ for part in content:
79
+ if isinstance(part, dict):
80
+ text = part.get("text") or part.get("content")
81
+ if isinstance(text, str):
82
+ total += estimator(text)
83
+ elif isinstance(part, str):
84
+ total += estimator(part)
85
+ return total
86
+ return estimator(str(message))
87
+
88
+
89
+ _DEFAULT_COUNTER: HeuristicTokenCounter | None = None
90
+ _PROVIDER_COUNTER: "TokenCounter | None" = None
91
+
92
+
93
+ class _TiktokenTokenCounter:
94
+ """tiktoken 兼容 tokenizer(方案 §8.9 实现顺序 2)。
95
+
96
+ 用于 OpenAI cl100k_base/o200k 系模型;非该系模型回退到 heuristic。``name`` 记录实际
97
+ tokenizer,供 ContextPlan ``tokenizer`` 字段如实标注。
98
+ """
99
+
100
+ def __init__(self, encoding_name: str = "cl100k_base") -> None:
101
+ try:
102
+ import tiktoken # type: ignore
103
+
104
+ self._enc = tiktoken.get_encoding(encoding_name)
105
+ self._encoding_name = encoding_name
106
+ except Exception: # noqa: BLE001
107
+ self._enc = None
108
+ self._encoding_name = encoding_name
109
+
110
+ @property
111
+ def name(self) -> str:
112
+ if self._enc is None:
113
+ return HEURISTIC_TOKENIZER_NAME
114
+ return f"tiktoken:{self._encoding_name}"
115
+
116
+ def count_text(self, text: str, *, model: str | None = None) -> int:
117
+ if self._enc is None:
118
+ return HeuristicTokenCounter().count_text(text)
119
+ try:
120
+ return len(self._enc.encode(str(text or "")))
121
+ except Exception: # noqa: BLE001
122
+ return HeuristicTokenCounter().count_text(text)
123
+
124
+ def count_messages(self, messages: Sequence[Any], *, model: str | None = None) -> int:
125
+ total = 0
126
+ for message in messages:
127
+ total += HeuristicTokenCounter._count_message(message, self.count_text)
128
+ return total
129
+
130
+
131
+ def _provider_counter_enabled() -> bool:
132
+ """是否启用 provider/兼容 tokenizer(方案 §8.9)。
133
+
134
+ 默认 **关闭**(保持 heuristic baseline,不静默改变既有计数口径——方案 §8.9 "先观测后接管");
135
+ 显式 ``KSADK_TOKENIZER_PROVIDER=auto|tiktoken`` 才尝试 tiktoken,不可用时回退 heuristic。
136
+ """
137
+ raw = str(os.environ.get("KSADK_TOKENIZER_PROVIDER", "") or "").strip().lower()
138
+ return raw in ("auto", "tiktoken")
139
+
140
+
141
+ def get_default_token_counter() -> TokenCounter:
142
+ """返回进程级默认 TokenCounter(方案 §8.9)。
143
+
144
+ 优先 provider/兼容 tokenizer(``KSADK_TOKENIZER_PROVIDER=auto`` 时尝试 tiktoken,不可用
145
+ 回退 heuristic);``auto`` 之外显式 ``heuristic`` 则只用启发式。名称如实记录,偏差监控由
146
+ 调用方按 model 维度做(方案 §8.9 末)。
147
+ """
148
+ global _PROVIDER_COUNTER
149
+ if _provider_counter_enabled() and _PROVIDER_COUNTER is None:
150
+ _PROVIDER_COUNTER = _TiktokenTokenCounter()
151
+ if _PROVIDER_COUNTER is not None and _provider_counter_enabled():
152
+ return _PROVIDER_COUNTER
153
+ global _DEFAULT_COUNTER
154
+ if _DEFAULT_COUNTER is None:
155
+ _DEFAULT_COUNTER = HeuristicTokenCounter()
156
+ return _DEFAULT_COUNTER
157
+
158
+
159
+ def set_default_token_counter(counter: TokenCounter | None) -> None:
160
+ """测试/注入用:覆盖默认 counter。``None`` 恢复自动解析。"""
161
+ global _PROVIDER_COUNTER, _DEFAULT_COUNTER
162
+ _PROVIDER_COUNTER = counter
163
+ if counter is None:
164
+ _DEFAULT_COUNTER = None
@@ -1,97 +1,88 @@
1
+ """Side-effect-free public exports for conversation preparation and persistence."""
2
+
1
3
  from __future__ import annotations
2
4
 
3
- from ksadk.conversations.attachments import (
4
- decode_inline_data,
5
- resolve_attachment_storage_path,
6
- resolve_uploads_dir,
7
- )
8
- from ksadk.conversations.context import (
9
- CANONICAL_EVENT_TYPES,
10
- build_history_from_events,
11
- build_request_history,
12
- canonical_event_type,
13
- compacted_until_seq_id,
14
- extract_event_text,
15
- extract_text_from_event_parts,
16
- group_events_by_api_round,
17
- project_model_messages,
18
- summarize_event_groups,
19
- )
20
- from ksadk.conversations.normalize import (
21
- attachment_from_part,
22
- attachment_prompt_text,
23
- compact_attachment_for_session,
24
- display_content_from_parts,
25
- extract_user_input_from_parts,
26
- normalize_kop_message_content,
27
- normalize_kop_messages,
28
- normalize_parts_content,
29
- normalize_responses_input,
30
- )
31
- from ksadk.conversations.runtime import (
32
- CompactionPlan,
33
- PreparedConversationTurn,
34
- append_context_checkpoint_event,
35
- append_conversation_event,
36
- append_reasoning_event,
37
- append_run_checkpoint_event,
38
- append_run_resume_event,
39
- append_run_status_event,
40
- build_chat_completions_payload,
41
- build_compaction_sse_event,
42
- build_responses_payload,
43
- build_run_input,
44
- compact_conversation_history,
45
- ensure_conversation_session,
46
- extract_responses_resume_input,
47
- invoke_conversation_once,
48
- preview_auto_compaction,
49
- prime_session_metadata_for_user_turn,
50
- stream_conversation_turn,
51
- stream_responses_conversation_turn,
52
- )
5
+ from importlib import import_module
6
+ from typing import Any
7
+
8
+
9
+ def _exports(module: str, *names: str) -> dict[str, tuple[str, str]]:
10
+ return {name: (module, name) for name in names}
11
+
12
+
13
+ _EXPORTS = {
14
+ **_exports(
15
+ "ksadk.conversations.attachments",
16
+ "decode_inline_data",
17
+ "resolve_attachment_storage_path",
18
+ "resolve_uploads_dir",
19
+ ),
20
+ **_exports(
21
+ "ksadk.conversations.context",
22
+ "CANONICAL_EVENT_TYPES",
23
+ "build_history_from_events",
24
+ "build_request_history",
25
+ "canonical_event_type",
26
+ "compacted_until_seq_id",
27
+ "extract_event_text",
28
+ "extract_text_from_event_parts",
29
+ "group_events_by_api_round",
30
+ "project_model_messages",
31
+ "summarize_event_groups",
32
+ ),
33
+ **_exports(
34
+ "ksadk.conversations.normalize",
35
+ "attachment_from_part",
36
+ "attachment_prompt_text",
37
+ "compact_attachment_for_session",
38
+ "display_content_from_parts",
39
+ "extract_user_input_from_parts",
40
+ "normalize_kop_message_content",
41
+ "normalize_kop_messages",
42
+ "normalize_parts_content",
43
+ "normalize_responses_input",
44
+ ),
45
+ **_exports(
46
+ "ksadk.conversations.runtime",
47
+ "CompactionPlan",
48
+ "PreparedConversationTurn",
49
+ "append_context_checkpoint_event",
50
+ "append_conversation_event",
51
+ "append_reasoning_event",
52
+ "append_run_checkpoint_event",
53
+ "append_run_resume_event",
54
+ "append_run_status_event",
55
+ "build_chat_completions_payload",
56
+ "build_compaction_sse_event",
57
+ "build_responses_payload",
58
+ "build_run_input",
59
+ "compact_conversation_history",
60
+ "ensure_conversation_session",
61
+ "extract_responses_resume_input",
62
+ "invoke_conversation_once",
63
+ "preview_auto_compaction",
64
+ "prime_session_metadata_for_user_turn",
65
+ "stream_conversation_turn",
66
+ "stream_responses_conversation_turn",
67
+ ),
68
+ }
69
+
70
+ __all__ = list(_EXPORTS)
71
+
72
+
73
+ def __getattr__(name: str) -> Any:
74
+ if name == "runtime":
75
+ value = import_module("ksadk.conversations.runtime")
76
+ globals()[name] = value
77
+ return value
78
+ try:
79
+ module_name, attribute = _EXPORTS[name]
80
+ except KeyError:
81
+ raise AttributeError(f"module {__name__!r} has no attribute {name!r}") from None
82
+ value = getattr(import_module(module_name), attribute)
83
+ globals()[name] = value
84
+ return value
85
+
53
86
 
54
- __all__ = [
55
- "CANONICAL_EVENT_TYPES",
56
- "CompactionPlan",
57
- "PreparedConversationTurn",
58
- "append_conversation_event",
59
- "append_context_checkpoint_event",
60
- "append_reasoning_event",
61
- "append_run_checkpoint_event",
62
- "append_run_resume_event",
63
- "append_run_status_event",
64
- "attachment_from_part",
65
- "attachment_prompt_text",
66
- "build_chat_completions_payload",
67
- "build_compaction_sse_event",
68
- "build_history_from_events",
69
- "build_request_history",
70
- "build_responses_payload",
71
- "build_run_input",
72
- "canonical_event_type",
73
- "compact_conversation_history",
74
- "compact_attachment_for_session",
75
- "compacted_until_seq_id",
76
- "decode_inline_data",
77
- "display_content_from_parts",
78
- "ensure_conversation_session",
79
- "extract_event_text",
80
- "extract_text_from_event_parts",
81
- "extract_user_input_from_parts",
82
- "extract_responses_resume_input",
83
- "group_events_by_api_round",
84
- "invoke_conversation_once",
85
- "prime_session_metadata_for_user_turn",
86
- "normalize_kop_message_content",
87
- "normalize_kop_messages",
88
- "normalize_parts_content",
89
- "normalize_responses_input",
90
- "preview_auto_compaction",
91
- "project_model_messages",
92
- "resolve_attachment_storage_path",
93
- "resolve_uploads_dir",
94
- "stream_conversation_turn",
95
- "stream_responses_conversation_turn",
96
- "summarize_event_groups",
97
- ]
87
+ def __dir__() -> list[str]:
88
+ return sorted({*globals(), *__all__})
@@ -6,6 +6,11 @@ from collections.abc import Mapping, Sequence
6
6
  from typing import Any, Dict, Iterable, List
7
7
 
8
8
  from ksadk.sessions.base import SessionEvent
9
+ from ksadk.tools.result_budget import (
10
+ ToolResultBudget,
11
+ budget_tool_output,
12
+ default_tool_result_budget,
13
+ )
9
14
 
10
15
  CANONICAL_EVENT_TYPES = {
11
16
  "user_message",
@@ -34,11 +39,23 @@ TRANSCRIPT_EVENT_TYPES = {
34
39
  "context_checkpoint",
35
40
  }
36
41
 
42
+ _RUNTIME_PLACEHOLDER_EVENT_TYPES = {
43
+ "tool_call",
44
+ "tool_result",
45
+ "approval_request",
46
+ "approval_response",
47
+ }
48
+
37
49
  DATA_URL_RE = re.compile(r"data:(?P<mime>[A-Za-z0-9.+-]+/[A-Za-z0-9.+-]+);base64,[A-Za-z0-9+/=_-]+")
38
50
  BASE64_FIELD_RE = re.compile(
39
51
  r"(?P<prefix>['\"](?P<field>file_data|data|bytes|base64)['\"]\s*:\s*['\"])(?P<value>[A-Za-z0-9+/=_-]{512,})(?P<suffix>['\"])",
40
52
  re.IGNORECASE,
41
53
  )
54
+ _CORRECTION_MARKER_RE = re.compile(
55
+ r"(?:修正|更正|改为|更新为|最新(?:的)?|废弃|作废|不再使用|不是.+而是|不要|不得|禁止)"
56
+ )
57
+ _LATEST_USER_INSTRUCTION_MAX_CHARS = 8192
58
+ _CORRECTION_SUMMARY_MAX_CHARS = 2048
42
59
 
43
60
 
44
61
  def sanitize_event_text_for_context(text: Any) -> str:
@@ -55,8 +72,7 @@ def sanitize_event_text_for_context(text: Any) -> str:
55
72
  value = DATA_URL_RE.sub(_replace_data_url, value)
56
73
  value = BASE64_FIELD_RE.sub(
57
74
  lambda match: (
58
- f"{match.group('prefix')}[base64 {match.group('field')} omitted]"
59
- f"{match.group('suffix')}"
75
+ f"{match.group('prefix')}[base64 {match.group('field')} omitted]{match.group('suffix')}"
60
76
  ),
61
77
  value,
62
78
  )
@@ -146,6 +162,70 @@ def _stringify_part_text(value: Any) -> str:
146
162
  return str(value)
147
163
 
148
164
 
165
+ def budget_tool_result_for_event(
166
+ *,
167
+ tool_name: str,
168
+ tool_output: Any,
169
+ tool_call_id: str | None,
170
+ enabled: bool,
171
+ budget: ToolResultBudget | None = None,
172
+ ) -> tuple[str, dict[str, Any]]:
173
+ """PR C:tool_result 落 SessionEvent 前的单项预算(ksadk_hosted 门控)。
174
+
175
+ 返回 ``(session_event_text, metadata_extras)``:
176
+
177
+ - ``enabled=False`` → ``(str(tool_output), {})``:与旧
178
+ ``text=str(tool_output)`` **字节级一致**,非ksadk_hosted / framework / native
179
+ 路径零行为变更。
180
+ - ``enabled=True``:先 ``_stringify_part_text`` 干净渲染(已预算的 toolset dict →
181
+ ``"preview\\n[persisted-output] path (mime)"``;裸串 → 原串),再若仍超 ``max_chars`` 则
182
+ ``budget_tool_output`` 落盘+截断,``text = "preview\\n[persisted-output] path (mime)"``,
183
+ ``extras = {"tool_result_budget": {truncated, original_chars, preview_chars, persisted}}``。
184
+ 未超阈值 → ``(rendered, {})``。
185
+
186
+ **不碰 ``metadata.tool_output``**:调用方保留原值(UI/Responses 读取方不受影响,
187
+ 会话存储节省留后续)。
188
+ 只 bound 进 ``content.parts[0].text``——即下一轮 ``extract_event_text`` → ``payload["history"]``
189
+ → 模型输入的那条 text。已预算 dict 经 ``_stringify_part_text`` 渲染后必小于阈值,不重复落盘。
190
+ """
191
+ if not enabled:
192
+ return str(tool_output), {}
193
+ active = budget or default_tool_result_budget()
194
+ rendered = _stringify_part_text(tool_output)
195
+ if len(rendered) <= active.max_chars:
196
+ return rendered, {}
197
+ budgeted = budget_tool_output(
198
+ tool_name=tool_name,
199
+ field_name="output",
200
+ value=tool_output,
201
+ metadata={"tool_call_id": tool_call_id or ""},
202
+ budget=active,
203
+ )
204
+ preview = str(budgeted.get("output") or "")
205
+ persisted = budgeted.get("persisted")
206
+ if not isinstance(persisted, Mapping) or not persisted.get("path"):
207
+ # 无落盘(不应发生,但兜底)→ 退回 rendered 截断标记,不谎报 persisted。
208
+ marker = f"\n[truncated {len(rendered) - active.max_chars} chars]"
209
+ return (rendered[: active.max_chars] + marker), {
210
+ "tool_result_budget": {
211
+ "truncated": True,
212
+ "original_chars": int(budgeted.get("original_chars") or len(rendered)),
213
+ "preview_chars": active.max_chars,
214
+ }
215
+ }
216
+ mime_type = persisted.get("mime_type") or "text/plain"
217
+ text = f"{preview}\n[persisted-output] {persisted['path']} ({mime_type})"
218
+ extras = {
219
+ "tool_result_budget": {
220
+ "truncated": bool(budgeted.get("truncated")),
221
+ "original_chars": int(budgeted.get("original_chars") or 0),
222
+ "preview_chars": int(budgeted.get("preview_chars") or len(preview)),
223
+ "persisted": dict(persisted),
224
+ }
225
+ }
226
+ return text, extras
227
+
228
+
149
229
  def build_request_history(messages: Iterable[Dict[str, Any]]) -> List[Dict[str, str]]:
150
230
  history: List[Dict[str, str]] = []
151
231
  for message in messages or []:
@@ -191,14 +271,16 @@ def summarize_event_groups(
191
271
  ) -> str:
192
272
  """把要折叠的旧轮次压成一段 checkpoint 文本。
193
273
 
194
- 这里没有直接照搬 Claude Code 的 LLM summarizer,而是先落一个可预测、
195
- 可恢复的结构化摘要骨架,后续再替换成真正的 summarize agent 也不需要改
196
- event contract。
274
+ extractive fallback:结构化骨架 + 有界保留错误修正和最新长 user 指令。
275
+ 无摘要模型时,关键修正可能位于长消息尾部,也可能不是最后一条 user 消息;
276
+ 因此跨消息提取修正,并在预算上限内保留最新长指令首尾(方案 §9.4)。
197
277
  """
198
278
  lines: List[str] = []
199
279
  if previous_summary:
200
280
  lines.append(previous_summary)
201
281
  lines.append("Earlier conversation summary:")
282
+ last_user_text = ""
283
+ correction_snippets: list[str] = []
202
284
  for group in groups:
203
285
  snippets: List[str] = []
204
286
  for event in group:
@@ -216,9 +298,34 @@ def summarize_event_groups(
216
298
  role = "assistant"
217
299
  else:
218
300
  role = "user"
301
+ last_user_text = text
302
+ for sentence in re.split(r"[\n。;;]+", text):
303
+ normalized = sentence.strip()
304
+ if normalized and _CORRECTION_MARKER_RE.search(normalized):
305
+ correction_snippets.append(normalized[:512])
219
306
  snippets.append(f"{role}: {text[:180]}")
220
307
  if snippets:
221
308
  lines.append(" | ".join(snippets))
309
+ # 修正不一定是 compact 范围内最后一条 user 消息;单独形成结构化段,供
310
+ # Working State 确定性解析。总量有界,避免用“保留完整”重新撑爆上下文。
311
+ if correction_snippets:
312
+ unique: list[str] = []
313
+ for snippet in correction_snippets:
314
+ if snippet not in unique:
315
+ unique.append(snippet)
316
+ correction_text = ";".join(unique[-8:])[-_CORRECTION_SUMMARY_MAX_CHARS:]
317
+ lines.append(f"错误修正:{correction_text}")
318
+ # 末尾追加最新 user 指令的有界首尾内容。短消息已在摘要骨架里,不重复。
319
+ if last_user_text and len(last_user_text) > 180:
320
+ preserved = last_user_text
321
+ if len(preserved) > _LATEST_USER_INSTRUCTION_MAX_CHARS:
322
+ half = _LATEST_USER_INSTRUCTION_MAX_CHARS // 2
323
+ preserved = (
324
+ preserved[:half]
325
+ + "\n...[中间内容因上下文预算省略]...\n"
326
+ + preserved[-half:]
327
+ )
328
+ lines.append(f"最新用户指令(有界保留): {preserved}")
222
329
  return "\n".join(line for line in lines if line).strip()
223
330
 
224
331
 
@@ -235,6 +342,7 @@ def project_model_messages(
235
342
  3. tool/approval/attachment 仍保留成可解释的文本占位,避免状态丢失。
236
343
  """
237
344
  projected: List[Dict[str, str]] = []
345
+ placeholder_flags: list[bool] = []
238
346
  compacted_until = compacted_until_seq_id(events)
239
347
  checkpoint = next(
240
348
  (
@@ -253,6 +361,7 @@ def project_model_messages(
253
361
  "content": summary_text,
254
362
  }
255
363
  )
364
+ placeholder_flags.append(False)
256
365
 
257
366
  for event in events:
258
367
  event_type = canonical_event_type(
@@ -291,10 +400,17 @@ def project_model_messages(
291
400
  else:
292
401
  role = "user"
293
402
 
294
- if projected and projected[-1]["role"] == role:
403
+ is_placeholder = event_type in _RUNTIME_PLACEHOLDER_EVENT_TYPES
404
+ if (
405
+ projected
406
+ and projected[-1]["role"] == role
407
+ and not placeholder_flags[-1]
408
+ and not is_placeholder
409
+ ):
295
410
  projected[-1]["content"] = f"{projected[-1]['content']}\n{text}".strip()
296
411
  else:
297
412
  projected.append({"role": role, "content": text})
413
+ placeholder_flags.append(is_placeholder)
298
414
 
299
415
  return projected
300
416
 
@@ -430,6 +546,10 @@ def project_responses_history(events: List[SessionEvent]) -> List[dict[str, Any]
430
546
  from a text summary. Events without a reliable call id fall back to the
431
547
  existing explanatory message representation instead of emitting an invalid
432
548
  ``function_call_output`` item.
549
+
550
+ 公开承诺(契约声明见 ``ksadk/events/projections.py``):仅 OpenAI Responses
551
+ input item 形态(``type``/``call_id``/``output``/role 消息);内部不保证
552
+ compacted 前缀的重放方式与占位消息的具体措辞。
433
553
  """
434
554
  projected: List[dict[str, Any]] = []
435
555
  projected_call_ids: set[str] = set()