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,420 @@
1
+ """Versioned, fixed-watermark JSONL exports for canonical RuntimeEvents.
2
+
3
+ New exports use the schema-v2 RuntimeEvent envelope. The legacy v1 log is
4
+ still accepted by :func:`verify_session_log` so existing diagnostic files stay
5
+ readable, but a v2 Store must never be coerced back into a v1 write model just
6
+ to produce an export.
7
+ """
8
+
9
+ from __future__ import annotations
10
+
11
+ import json
12
+ import os
13
+ import tempfile
14
+ from dataclasses import dataclass
15
+ from pathlib import Path
16
+ from typing import Any, TextIO
17
+
18
+ from ksadk.events.canonical import dump_runtime_event, parse_runtime_event
19
+ from ksadk.events.store import RuntimeEventStore
20
+ from ksadk.events.v1_compat import EventTypeV1, RuntimeEventV1
21
+ from ksadk.sessions.base import BaseSessionService
22
+
23
+ SESSION_LOG_SCHEMA = "ksadk.session-log/v2"
24
+ _SESSION_LOG_VERSION = 2
25
+ _LEGACY_SESSION_LOG_SCHEMA = "ksadk.session-log/v1"
26
+ _LEGACY_SESSION_LOG_VERSION = 1
27
+ _PAGE_SIZE = 500
28
+ _LEGACY_PACKED_EVENT_TYPES = {
29
+ EventTypeV1.TEXT_DELTA: "text-chunks",
30
+ EventTypeV1.REASONING_DELTA: "reasoning-chunks",
31
+ }
32
+ _LEGACY_PACKED_RECORD_TYPES = {value: key for key, value in _LEGACY_PACKED_EVENT_TYPES.items()}
33
+
34
+
35
+ class SessionLogError(ValueError):
36
+ """A stable Session Log export or validation failure."""
37
+
38
+
39
+ @dataclass(frozen=True)
40
+ class SessionLogResult:
41
+ path: Path
42
+ event_count: int
43
+ first_seq_id: int | None
44
+ last_seq_id: int | None
45
+ exported_through_seq_id: int | None
46
+
47
+
48
+ def _raise(code: str, message: str) -> None:
49
+ raise SessionLogError(f"{code}: {message}")
50
+
51
+
52
+ def _write_json_line(stream: TextIO, value: dict[str, Any]) -> None:
53
+ stream.write(
54
+ json.dumps(value, ensure_ascii=False, sort_keys=True, separators=(",", ":")) + "\n"
55
+ )
56
+
57
+
58
+ def _legacy_packed_base(event: RuntimeEventV1) -> dict[str, Any]:
59
+ value = event.to_dict()
60
+ for key in ("event_id", "seq_id", "timestamp"):
61
+ value.pop(key)
62
+ payload = dict(value["payload"])
63
+ payload.pop("text")
64
+ value["payload"] = payload
65
+ return value
66
+
67
+
68
+ def _write_legacy_event_run(stream: TextIO, events: list[RuntimeEventV1]) -> None:
69
+ if len(events) < 3:
70
+ for event in events:
71
+ _write_json_line(stream, event.to_dict())
72
+ return
73
+ _write_json_line(
74
+ stream,
75
+ {
76
+ "type": _LEGACY_PACKED_EVENT_TYPES[events[0].event_type],
77
+ "seq0": events[0].seq_id,
78
+ "data": {
79
+ "base": _legacy_packed_base(events[0]),
80
+ "event_ids": [event.event_id for event in events],
81
+ "timestamps": [event.timestamp for event in events],
82
+ "texts": [event.payload["text"] for event in events],
83
+ },
84
+ },
85
+ )
86
+
87
+
88
+ def _same_legacy_event_run(events: list[RuntimeEventV1], event: RuntimeEventV1) -> bool:
89
+ return (
90
+ bool(events)
91
+ and event.event_type == events[0].event_type
92
+ and event.seq_id == events[-1].seq_id + 1
93
+ and _legacy_packed_base(event) == _legacy_packed_base(events[0])
94
+ )
95
+
96
+
97
+ async def export_session_log(
98
+ session_service: BaseSessionService,
99
+ session_id: str,
100
+ target: Path | str,
101
+ *,
102
+ invocation_id: str | None = None,
103
+ ) -> SessionLogResult:
104
+ """Export committed RuntimeEvents through a fixed session cursor."""
105
+ session = await session_service.get_session_metadata(session_id)
106
+ if session is None:
107
+ _raise("SESSION_LOG_SESSION_NOT_FOUND", f"session {session_id!r} not found")
108
+
109
+ target_path = Path(target)
110
+ if target_path.exists():
111
+ _raise("SESSION_LOG_TARGET_EXISTS", f"target {target_path} already exists")
112
+
113
+ store = RuntimeEventStore(session_service)
114
+ tail = await store.list(session_id, limit=1)
115
+ cutoff = tail[-1].seq if tail else None
116
+ header: dict[str, Any] = {
117
+ "type": "session",
118
+ "schema": SESSION_LOG_SCHEMA,
119
+ "version": _SESSION_LOG_VERSION,
120
+ "session_id": session.id,
121
+ "agent_id": session.agent_id,
122
+ "user_id": session.user_id,
123
+ "created_at": session.created_at,
124
+ "updated_at": session.updated_at,
125
+ "exported_through_seq_id": cutoff,
126
+ "event_schema_version": 2,
127
+ }
128
+ if invocation_id is not None:
129
+ header["invocation_id"] = invocation_id
130
+
131
+ temporary_path: Path | None = None
132
+ published = False
133
+ event_count = 0
134
+ first_seq_id: int | None = None
135
+ last_seq_id: int | None = None
136
+ try:
137
+ descriptor, temporary_name = tempfile.mkstemp(
138
+ dir=target_path.parent,
139
+ prefix=".session-log-",
140
+ suffix=".tmp",
141
+ )
142
+ temporary_path = Path(temporary_name)
143
+ os.fchmod(descriptor, 0o600)
144
+ with os.fdopen(descriptor, "w", encoding="utf-8") as stream:
145
+ _write_json_line(stream, header)
146
+ cursor = 0
147
+ while cutoff is not None and cursor < cutoff:
148
+ window_end = min(cursor + _PAGE_SIZE, cutoff)
149
+ events = await store.page(
150
+ session_id,
151
+ after_seq=cursor,
152
+ before_seq=window_end + 1,
153
+ limit=_PAGE_SIZE,
154
+ )
155
+ for event in events:
156
+ if invocation_id is not None and event.run_id != invocation_id:
157
+ continue
158
+ # A v2 fact is the durable source of truth. The v1
159
+ # packed delta format cannot losslessly encode all v2
160
+ # item operations, so v2 logs retain one canonical event
161
+ # per row instead of silently projecting/dropping facts.
162
+ _write_json_line(stream, dump_runtime_event(event))
163
+ event_count += 1
164
+ first_seq_id = first_seq_id or event.seq
165
+ last_seq_id = event.seq
166
+ cursor = window_end
167
+ stream.flush()
168
+ os.fsync(stream.fileno())
169
+
170
+ try:
171
+ os.link(temporary_path, target_path)
172
+ published = True
173
+ except FileExistsError as exc:
174
+ raise SessionLogError(
175
+ f"SESSION_LOG_TARGET_EXISTS: target {target_path} already exists"
176
+ ) from exc
177
+ except OSError as exc:
178
+ raise SessionLogError(
179
+ "SESSION_LOG_ATOMIC_PUBLISH_UNSUPPORTED: "
180
+ f"cannot atomically publish {target_path}"
181
+ ) from exc
182
+
183
+ directory_fd = os.open(target_path.parent, os.O_RDONLY)
184
+ try:
185
+ os.fsync(directory_fd)
186
+ finally:
187
+ os.close(directory_fd)
188
+ except SessionLogError:
189
+ if published:
190
+ target_path.unlink(missing_ok=True)
191
+ raise
192
+ except OSError as exc:
193
+ if published:
194
+ target_path.unlink(missing_ok=True)
195
+ raise SessionLogError(f"SESSION_LOG_WRITE_FAILED: {target_path}") from exc
196
+ finally:
197
+ if temporary_path is not None:
198
+ temporary_path.unlink(missing_ok=True)
199
+
200
+ return SessionLogResult(
201
+ path=target_path,
202
+ event_count=event_count,
203
+ first_seq_id=first_seq_id,
204
+ last_seq_id=last_seq_id,
205
+ exported_through_seq_id=cutoff,
206
+ )
207
+
208
+
209
+ def _read_json_line(raw: str, line_number: int) -> dict[str, Any]:
210
+ try:
211
+ value = json.loads(raw)
212
+ except json.JSONDecodeError as exc:
213
+ raise SessionLogError(f"SESSION_LOG_INVALID: line {line_number} is not valid JSON") from exc
214
+ if not isinstance(value, dict):
215
+ _raise("SESSION_LOG_INVALID", f"line {line_number} must be an object")
216
+ return value
217
+
218
+
219
+ def _legacy_events_from_record(
220
+ value: dict[str, Any], line_number: int, *, allow_packed: bool
221
+ ) -> list[RuntimeEventV1]:
222
+ record_type = value.get("type")
223
+ if record_type not in _LEGACY_PACKED_RECORD_TYPES:
224
+ try:
225
+ return [RuntimeEventV1.from_dict(value)]
226
+ except (TypeError, ValueError) as exc:
227
+ raise SessionLogError(
228
+ f"SESSION_LOG_INVALID: line {line_number} is not a RuntimeEvent"
229
+ ) from exc
230
+ if not allow_packed:
231
+ _raise("SESSION_LOG_INVALID", f"line {line_number} uses packed rows in v1")
232
+
233
+ seq0 = value.get("seq0")
234
+ data = value.get("data")
235
+ if isinstance(seq0, bool) or not isinstance(seq0, int) or seq0 < 0:
236
+ _raise("SESSION_LOG_INVALID", f"line {line_number} packed seq0 is invalid")
237
+ if not isinstance(data, dict) or not isinstance(data.get("base"), dict):
238
+ _raise("SESSION_LOG_INVALID", f"line {line_number} packed data is invalid")
239
+ event_ids = data.get("event_ids")
240
+ timestamps = data.get("timestamps")
241
+ texts = data.get("texts")
242
+ if not all(isinstance(items, list) for items in (event_ids, timestamps, texts)):
243
+ _raise("SESSION_LOG_INVALID", f"line {line_number} packed arrays are invalid")
244
+ if len(event_ids) < 3 or len(event_ids) != len(timestamps) or len(event_ids) != len(texts):
245
+ _raise("SESSION_LOG_INVALID", f"line {line_number} packed arrays do not align")
246
+
247
+ base = dict(data["base"])
248
+ expected_event_type = _LEGACY_PACKED_RECORD_TYPES[record_type]
249
+ if base.get("event_type") != expected_event_type:
250
+ _raise("SESSION_LOG_INVALID", f"line {line_number} packed event type does not match")
251
+ payload = base.get("payload")
252
+ if not isinstance(payload, dict) or "text" in payload:
253
+ _raise("SESSION_LOG_INVALID", f"line {line_number} packed payload is invalid")
254
+
255
+ events: list[RuntimeEventV1] = []
256
+ for index, (event_id, timestamp, text) in enumerate(
257
+ zip(event_ids, timestamps, texts, strict=True)
258
+ ):
259
+ value = {
260
+ **base,
261
+ "event_id": event_id,
262
+ "seq_id": seq0 + index,
263
+ "timestamp": timestamp,
264
+ "payload": {**payload, "text": text},
265
+ }
266
+ try:
267
+ events.append(RuntimeEventV1.from_dict(value))
268
+ except (TypeError, ValueError) as exc:
269
+ raise SessionLogError(
270
+ f"SESSION_LOG_INVALID: line {line_number} contains an invalid packed event"
271
+ ) from exc
272
+ return events
273
+
274
+
275
+ def _validate_header(
276
+ header: dict[str, Any], *, schema: str, version: int
277
+ ) -> tuple[int | None, str | None]:
278
+ if header.get("type") != "session":
279
+ _raise("SESSION_LOG_INVALID", "first line must be a session header")
280
+ if header.get("schema") != schema or header.get("version") != version:
281
+ _raise("SESSION_LOG_INVALID", "unsupported schema")
282
+ session_id = header.get("session_id")
283
+ if not isinstance(session_id, str) or not session_id:
284
+ _raise("SESSION_LOG_INVALID", "header session id is required")
285
+ cutoff = header.get("exported_through_seq_id")
286
+ if cutoff is not None and (
287
+ isinstance(cutoff, bool) or not isinstance(cutoff, int) or cutoff < 0
288
+ ):
289
+ _raise("SESSION_LOG_INVALID", "exported watermark must be null or non-negative")
290
+ return cutoff, header.get("invocation_id")
291
+
292
+
293
+ def _finish_verification(
294
+ *,
295
+ source: Path,
296
+ event_count: int,
297
+ first_seq_id: int | None,
298
+ last_seq_id: int | None,
299
+ cutoff: int | None,
300
+ filtered: bool,
301
+ ) -> SessionLogResult:
302
+ if not filtered:
303
+ if cutoff is None and event_count:
304
+ _raise("SESSION_LOG_INVALID", "empty watermark cannot contain events")
305
+ if cutoff is not None and last_seq_id != cutoff:
306
+ _raise("SESSION_LOG_INVALID", "full session must end at exported watermark")
307
+ return SessionLogResult(
308
+ path=source,
309
+ event_count=event_count,
310
+ first_seq_id=first_seq_id,
311
+ last_seq_id=last_seq_id,
312
+ exported_through_seq_id=cutoff,
313
+ )
314
+
315
+
316
+ def _verify_v2(stream: TextIO, *, source: Path, header: dict[str, Any]) -> SessionLogResult:
317
+ cutoff, invocation_id = _validate_header(
318
+ header, schema=SESSION_LOG_SCHEMA, version=_SESSION_LOG_VERSION
319
+ )
320
+ filtered = invocation_id is not None
321
+ event_count = 0
322
+ first_seq_id: int | None = None
323
+ last_seq_id: int | None = None
324
+ for line_number, raw in enumerate(stream, start=2):
325
+ if not raw.strip():
326
+ _raise("SESSION_LOG_INVALID", f"line {line_number} is empty")
327
+ try:
328
+ event = parse_runtime_event(_read_json_line(raw, line_number))
329
+ except (TypeError, ValueError) as exc:
330
+ raise SessionLogError(
331
+ f"SESSION_LOG_INVALID: line {line_number} is not a RuntimeEvent/v2"
332
+ ) from exc
333
+ if filtered and event.run_id != invocation_id:
334
+ _raise("SESSION_LOG_INVALID", f"line {line_number} run id does not match")
335
+ if last_seq_id is not None and event.seq <= last_seq_id:
336
+ _raise("SESSION_LOG_INVALID", "event seq must be strictly increasing")
337
+ if cutoff is None or event.seq > cutoff:
338
+ _raise("SESSION_LOG_INVALID", "event seq exceeds exported watermark")
339
+ if not filtered:
340
+ expected = 1 if last_seq_id is None else last_seq_id + 1
341
+ if event.seq != expected:
342
+ _raise("SESSION_LOG_INVALID", "full session seq must be continuous")
343
+ event_count += 1
344
+ first_seq_id = first_seq_id or event.seq
345
+ last_seq_id = event.seq
346
+ return _finish_verification(
347
+ source=source,
348
+ event_count=event_count,
349
+ first_seq_id=first_seq_id,
350
+ last_seq_id=last_seq_id,
351
+ cutoff=cutoff,
352
+ filtered=filtered,
353
+ )
354
+
355
+
356
+ def _verify_v1(stream: TextIO, *, source: Path, header: dict[str, Any]) -> SessionLogResult:
357
+ cutoff, invocation_id = _validate_header(
358
+ header, schema=_LEGACY_SESSION_LOG_SCHEMA, version=_LEGACY_SESSION_LOG_VERSION
359
+ )
360
+ session_id = str(header["session_id"])
361
+ filtered = invocation_id is not None
362
+ event_count = 0
363
+ first_seq_id: int | None = None
364
+ last_seq_id: int | None = None
365
+ for line_number, raw in enumerate(stream, start=2):
366
+ if not raw.strip():
367
+ _raise("SESSION_LOG_INVALID", f"line {line_number} is empty")
368
+ value = _read_json_line(raw, line_number)
369
+ for event in _legacy_events_from_record(value, line_number, allow_packed=True):
370
+ if event.session_id != session_id:
371
+ _raise("SESSION_LOG_INVALID", f"line {line_number} session id does not match")
372
+ if filtered and event.invocation_id != invocation_id:
373
+ _raise("SESSION_LOG_INVALID", f"line {line_number} invocation id does not match")
374
+ if last_seq_id is not None and event.seq_id <= last_seq_id:
375
+ _raise("SESSION_LOG_INVALID", "event seq_id must be strictly increasing")
376
+ if cutoff is None or event.seq_id > cutoff:
377
+ _raise("SESSION_LOG_INVALID", "event seq_id exceeds exported watermark")
378
+ if not filtered:
379
+ expected = 1 if last_seq_id is None else last_seq_id + 1
380
+ if event.seq_id != expected:
381
+ _raise("SESSION_LOG_INVALID", "full session seq_id must be continuous")
382
+ event_count += 1
383
+ first_seq_id = first_seq_id or event.seq_id
384
+ last_seq_id = event.seq_id
385
+ return _finish_verification(
386
+ source=source,
387
+ event_count=event_count,
388
+ first_seq_id=first_seq_id,
389
+ last_seq_id=last_seq_id,
390
+ cutoff=cutoff,
391
+ filtered=filtered,
392
+ )
393
+
394
+
395
+ def verify_session_log(path: Path | str) -> SessionLogResult:
396
+ """Stream and validate a v2 Session Log or a legacy v1 diagnostic file."""
397
+ source = Path(path)
398
+ try:
399
+ stream = source.open(encoding="utf-8")
400
+ except OSError as exc:
401
+ raise SessionLogError(f"SESSION_LOG_READ_FAILED: {source}") from exc
402
+ with stream:
403
+ first_line = stream.readline()
404
+ if not first_line:
405
+ _raise("SESSION_LOG_INVALID", "missing session header")
406
+ header = _read_json_line(first_line, 1)
407
+ if header.get("schema") == SESSION_LOG_SCHEMA:
408
+ return _verify_v2(stream, source=source, header=header)
409
+ if header.get("schema") == _LEGACY_SESSION_LOG_SCHEMA:
410
+ return _verify_v1(stream, source=source, header=header)
411
+ _raise("SESSION_LOG_INVALID", "unsupported schema")
412
+
413
+
414
+ __all__ = [
415
+ "SESSION_LOG_SCHEMA",
416
+ "SessionLogError",
417
+ "SessionLogResult",
418
+ "export_session_log",
419
+ "verify_session_log",
420
+ ]
@@ -0,0 +1,105 @@
1
+ """Stable UI trajectory projection for canonical RuntimeEvents.
2
+
3
+ The durable store owns only RuntimeEvent/v2 facts. This module derives its
4
+ compact trajectory shape from the Studio v2 projection; it must not reach into
5
+ the read-only RuntimeEvent/v1 compatibility model.
6
+ """
7
+
8
+ from __future__ import annotations
9
+
10
+ import json
11
+ from typing import Any
12
+
13
+ from ksadk.events.canonical import RuntimeEvent, dump_runtime_event
14
+ from ksadk.studio.run_service import project_runtime_event
15
+
16
+ PROJECTION_VERSION = 1
17
+
18
+
19
+ def _record_id(event: RuntimeEvent, event_type: str, data: dict[str, Any]) -> str:
20
+ if event_type.startswith(("message.", "thinking.")):
21
+ return f"assistant:{data.get('itemId') or event.scope_id}"
22
+ if event_type.startswith(("tool.", "command.")):
23
+ return f"tool:{data.get('callId') or data.get('itemId') or event.event_id}"
24
+ if event_type.startswith("approval."):
25
+ return f"approval:{data.get('approvalId') or data.get('itemId') or event.event_id}"
26
+ if event_type.startswith("checkpoint."):
27
+ return f"checkpoint:{data.get('checkpointId') or data.get('itemId') or event.event_id}"
28
+ if event_type.startswith("a2ui.surface."):
29
+ return f"surface:{data.get('surfaceId') or data.get('itemId') or event.event_id}"
30
+ if event_type.startswith("context.compaction."):
31
+ return f"context:{event.scope_id}:compaction"
32
+ return f"system:{event.event_id}"
33
+
34
+
35
+ def _category(event_type: str) -> str:
36
+ if event_type.startswith(("message.", "thinking.")):
37
+ return "assistant"
38
+ if event_type.startswith(("tool.", "command.")):
39
+ return "tool"
40
+ if event_type.startswith("approval."):
41
+ return "approval"
42
+ if event_type.startswith("context.compaction."):
43
+ return "context"
44
+ if event_type.startswith("artifact."):
45
+ return "artifact"
46
+ return "system"
47
+
48
+
49
+ def _status(event_type: str, data: dict[str, Any]) -> str | None:
50
+ value = data.get("status")
51
+ if isinstance(value, str) and value:
52
+ return value
53
+ if event_type.endswith((".started", ".delta", ".requested", ".progress")):
54
+ return "running"
55
+ if event_type.endswith((".completed", ".resolved")):
56
+ return "completed"
57
+ if event_type.endswith(".failed"):
58
+ return "failed"
59
+ if event_type.endswith(".cancelled"):
60
+ return "canceled"
61
+ if event_type.endswith(".interrupted"):
62
+ return "interrupted"
63
+ return None
64
+
65
+
66
+ def _summary(event_type: str, data: dict[str, Any]) -> str:
67
+ if event_type.startswith(("message.", "thinking.")):
68
+ return "Message"
69
+ for key in ("tool", "command", "message", "reason", "error"):
70
+ value = data.get(key)
71
+ if isinstance(value, str) and value:
72
+ return value
73
+ return event_type
74
+
75
+
76
+ def project_trajectory_event(event: RuntimeEvent) -> dict[str, Any]:
77
+ """Project one immutable v2 fact into the stable trajectory display shape."""
78
+
79
+ event_type, data = project_runtime_event(event)
80
+ details = dict(data)
81
+ details.pop("runtimeEvent", None)
82
+ return {
83
+ "projectionVersion": PROJECTION_VERSION,
84
+ "seqId": event.seq,
85
+ "eventId": event.event_id,
86
+ "recordId": _record_id(event, event_type, details),
87
+ "type": event_type,
88
+ "category": _category(event_type),
89
+ "turnId": None,
90
+ "stepId": None,
91
+ "timestamp": event.timestamp,
92
+ "status": _status(event_type, details),
93
+ "durationMs": details.get("durationMs"),
94
+ "summary": _summary(event_type, details),
95
+ "details": details,
96
+ "source": dump_runtime_event(event),
97
+ }
98
+
99
+
100
+ def encode_sse(value: dict[str, Any], *, event_id: int) -> str:
101
+ data = json.dumps(value, ensure_ascii=False, sort_keys=True, separators=(",", ":"))
102
+ return f"id: {event_id}\nevent: runtime_event\ndata: {data}\n\n"
103
+
104
+
105
+ __all__ = ["PROJECTION_VERSION", "encode_sse", "project_trajectory_event"]
@@ -0,0 +1,71 @@
1
+ """Prompt 分区与编译数据模型(方案第 7 节)。
2
+
3
+ 第一个 PR 只导出稳定类型:``PromptSection`` / ``CompiledPrompt`` / ``PromptProjectionResult``。
4
+ ``PromptCompiler`` 的确定性编译、merge、hash、指令文件发现与预算留第二个 PR。
5
+ """
6
+
7
+ from ksadk.prompts.compiler import (
8
+ InconsistentSectionError,
9
+ PromptCompiler,
10
+ ProtectedSectionOverrideError,
11
+ compile_prompt,
12
+ )
13
+ from ksadk.prompts.models import (
14
+ PROMPT_COMPILER_VERSION,
15
+ CompiledPrompt,
16
+ PromptMergePolicy,
17
+ PromptProjectionResult,
18
+ PromptSection,
19
+ PromptSectionKind,
20
+ PromptStability,
21
+ PromptTrustLevel,
22
+ )
23
+ from ksadk.prompts.resolved import (
24
+ RESOLVED_PROMPT_SOURCES_VERSION,
25
+ EnvPlatformPolicySource,
26
+ PlatformPolicySource,
27
+ ResolvedPromptSources,
28
+ compile_resolved_prompt_dict,
29
+ get_default_platform_policy_source,
30
+ sections_from_resolved_sources,
31
+ )
32
+ from ksadk.prompts.sources import (
33
+ PLATFORM_SAFETY_TEXT,
34
+ agent_identity_section,
35
+ agent_policy_section,
36
+ discover_instruction_files,
37
+ platform_safety_section,
38
+ request_instructions_section,
39
+ resource_manifest_section,
40
+ sections_from_instructions,
41
+ )
42
+
43
+ __all__ = [
44
+ "PLATFORM_SAFETY_TEXT",
45
+ "PROMPT_COMPILER_VERSION",
46
+ "RESOLVED_PROMPT_SOURCES_VERSION",
47
+ "CompiledPrompt",
48
+ "EnvPlatformPolicySource",
49
+ "InconsistentSectionError",
50
+ "PlatformPolicySource",
51
+ "PromptCompiler",
52
+ "PromptMergePolicy",
53
+ "PromptProjectionResult",
54
+ "PromptSection",
55
+ "PromptSectionKind",
56
+ "PromptStability",
57
+ "PromptTrustLevel",
58
+ "ProtectedSectionOverrideError",
59
+ "ResolvedPromptSources",
60
+ "agent_identity_section",
61
+ "agent_policy_section",
62
+ "compile_prompt",
63
+ "compile_resolved_prompt_dict",
64
+ "discover_instruction_files",
65
+ "get_default_platform_policy_source",
66
+ "platform_safety_section",
67
+ "request_instructions_section",
68
+ "resource_manifest_section",
69
+ "sections_from_instructions",
70
+ "sections_from_resolved_sources",
71
+ ]