agentengine-sdk-python 0.8.1__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 (411) hide show
  1. {agentengine_sdk_python-0.8.1.dist-info → agentengine_sdk_python-0.8.2.dist-info}/METADATA +22 -2
  2. {agentengine_sdk_python-0.8.1.dist-info → agentengine_sdk_python-0.8.2.dist-info}/RECORD +356 -222
  3. ksadk/a2a/_space_client_events.py +381 -0
  4. ksadk/a2a/event_adapter.py +156 -64
  5. ksadk/a2a/executor.py +179 -63
  6. ksadk/a2a/space_client.py +6 -333
  7. ksadk/a2ui/core.py +222 -53
  8. ksadk/agui/_agent_helpers.py +243 -0
  9. ksadk/agui/a2ui_projection.py +12 -5
  10. ksadk/agui/agent.py +443 -259
  11. ksadk/api/client.py +525 -27
  12. ksadk/builders/code_builder.py +284 -8
  13. ksadk/builders/container_builder.py +8 -1
  14. ksadk/builders/managed_runtime_builder.py +39 -35
  15. ksadk/cli/__init__.py +17 -0
  16. ksadk/cli/cmd_dashboard.py +15 -1
  17. ksadk/cli/cmd_deploy.py +10 -2
  18. ksadk/cli/cmd_eval.py +66 -9
  19. ksadk/cli/cmd_evalset.py +284 -0
  20. ksadk/cli/cmd_files.py +5 -1
  21. ksadk/cli/cmd_hermes.py +1 -126
  22. ksadk/cli/cmd_invoke.py +28 -38
  23. ksadk/cli/cmd_managed_runtime.py +95 -0
  24. ksadk/cli/cmd_observe.py +85 -0
  25. ksadk/cli/cmd_openclaw.py +1 -435
  26. ksadk/cli/cmd_replay.py +28 -4
  27. ksadk/cli/cmd_studio.py +99 -8
  28. ksadk/cli/cmd_web.py +10 -2
  29. ksadk/cli/hermes_env.py +151 -0
  30. ksadk/cli/invoke_payload.py +49 -0
  31. ksadk/cli/openclaw_env.py +458 -0
  32. ksadk/codex/client.py +180 -30
  33. ksadk/codex/runtime.py +428 -326
  34. ksadk/configs/env_registry.py +66 -12
  35. ksadk/configs/env_registry_pcm.py +181 -0
  36. ksadk/configs/env_var_spec.py +18 -0
  37. ksadk/configs/global_config.py +5 -0
  38. ksadk/context_engine/__init__.py +98 -0
  39. ksadk/context_engine/assembler.py +176 -0
  40. ksadk/context_engine/baseline.py +419 -0
  41. ksadk/context_engine/cache_observability.py +228 -0
  42. ksadk/context_engine/capabilities.py +443 -0
  43. ksadk/context_engine/contributors.py +344 -0
  44. ksadk/context_engine/hosted_pipeline.py +417 -0
  45. ksadk/context_engine/models.py +117 -0
  46. ksadk/context_engine/planner.py +698 -0
  47. ksadk/context_engine/policies.py +319 -0
  48. ksadk/context_engine/projection.py +31 -0
  49. ksadk/context_engine/shadow_plan.py +266 -0
  50. ksadk/context_engine/tokenizer.py +164 -0
  51. ksadk/conversations/context.py +126 -6
  52. ksadk/conversations/message_projection.py +292 -28
  53. ksadk/conversations/model_context.py +49 -3
  54. ksadk/conversations/runtime_compaction.py +207 -5
  55. ksadk/conversations/runtime_input.py +184 -2
  56. ksadk/conversations/runtime_invocation.py +81 -3
  57. ksadk/conversations/runtime_observability.py +141 -0
  58. ksadk/conversations/runtime_payloads.py +42 -0
  59. ksadk/conversations/runtime_preparation.py +272 -2
  60. ksadk/conversations/runtime_resume.py +20 -1
  61. ksadk/conversations/runtime_stream_events.py +94 -9
  62. ksadk/conversations/semantic_summary.py +311 -1
  63. ksadk/conversations/session_lock.py +51 -0
  64. ksadk/deployment/env_forward.py +72 -0
  65. ksadk/deployment/managed_runtime.py +5 -0
  66. ksadk/deployment/providers/serverless.py +143 -69
  67. ksadk/evaluation/__init__.py +32 -0
  68. ksadk/evaluation/a2a_adapter.py +9 -1
  69. ksadk/evaluation/adapters.py +18 -5
  70. ksadk/evaluation/agent_eval_client.py +395 -0
  71. ksadk/evaluation/cloud_binding.py +80 -0
  72. ksadk/evaluation/cloud_converter.py +194 -0
  73. ksadk/evaluation/cloud_service.py +199 -0
  74. ksadk/evaluation/contracts.py +73 -4
  75. ksadk/evaluation/evaluators.py +183 -17
  76. ksadk/evaluation/evidence.py +258 -0
  77. ksadk/evaluation/executor.py +31 -6
  78. ksadk/evaluation/local_adapter.py +550 -0
  79. ksadk/evaluation/service_env.py +27 -0
  80. ksadk/evaluation/studio_build_adapter.py +253 -0
  81. ksadk/evaluation/target.py +15 -6
  82. ksadk/events/__init__.py +13 -13
  83. ksadk/events/_v1_compat/__init__.py +1 -0
  84. ksadk/events/_v1_compat/models.py +299 -0
  85. ksadk/events/_v1_compat/parser.py +247 -0
  86. ksadk/events/_v1_compat/projection.py +753 -0
  87. ksadk/events/adapters/__init__.py +34 -0
  88. ksadk/events/adapters/_a2a_snapshot.py +622 -0
  89. ksadk/events/adapters/_a2a_support.py +275 -0
  90. ksadk/events/adapters/_codex_interactions.py +375 -0
  91. ksadk/events/adapters/_codex_items.py +801 -0
  92. ksadk/events/adapters/_codex_validators.py +311 -0
  93. ksadk/events/adapters/_langgraph_support.py +785 -0
  94. ksadk/events/adapters/a2a.py +841 -0
  95. ksadk/events/adapters/adk.py +503 -0
  96. ksadk/events/adapters/codex.py +717 -0
  97. ksadk/events/adapters/langgraph.py +745 -0
  98. ksadk/events/canonical.py +440 -0
  99. ksadk/events/canonical_replay.py +497 -0
  100. ksadk/events/canonical_store.py +468 -0
  101. ksadk/events/cold_recovery.py +257 -0
  102. ksadk/events/content.py +89 -0
  103. ksadk/events/identity.py +86 -0
  104. ksadk/events/pipeline.py +455 -0
  105. ksadk/events/projections.py +66 -0
  106. ksadk/events/reducer.py +661 -0
  107. ksadk/events/replay.py +3 -36
  108. ksadk/events/runtime_event.py +20 -265
  109. ksadk/events/session_event.py +324 -0
  110. ksadk/events/store.py +3 -316
  111. ksadk/events/v1_compat.py +41 -0
  112. ksadk/harness/runtime.py +160 -57
  113. ksadk/identity/resolver.py +4 -3
  114. ksadk/interaction/__init__.py +28 -0
  115. ksadk/interaction/contracts.py +136 -0
  116. ksadk/interaction/ledger.py +189 -0
  117. ksadk/interaction/provider.py +122 -0
  118. ksadk/interaction/providers/__init__.py +52 -0
  119. ksadk/interaction/providers/adk.py +40 -0
  120. ksadk/interaction/providers/codex.py +94 -0
  121. ksadk/interaction/providers/langgraph.py +58 -0
  122. ksadk/kernel/__init__.py +117 -0
  123. ksadk/kernel/authorization.py +258 -0
  124. ksadk/kernel/bootstrap.py +1074 -0
  125. ksadk/kernel/contract_fingerprints.py +61 -0
  126. ksadk/kernel/contracts.py +362 -0
  127. ksadk/kernel/control.py +219 -0
  128. ksadk/kernel/errors.py +79 -0
  129. ksadk/kernel/ingress.py +1102 -0
  130. ksadk/kernel/mapping.py +111 -0
  131. ksadk/kernel/memory_store.py +1133 -0
  132. ksadk/kernel/postgres_store.py +1756 -0
  133. ksadk/kernel/recovery.py +452 -0
  134. ksadk/kernel/runtime_identity.py +103 -0
  135. ksadk/kernel/sql/001_agent_kernel.sql +120 -0
  136. ksadk/kernel/sqlite_store.py +1410 -0
  137. ksadk/kernel/state.py +145 -0
  138. ksadk/kernel/store.py +232 -0
  139. ksadk/kernel/worker.py +953 -0
  140. ksadk/knowledge_base/client.py +7 -0
  141. ksadk/knowledge_base/service.py +32 -5
  142. ksadk/memory/__init__.py +61 -0
  143. ksadk/memory/adk/backends/base_ltm_backend.py +96 -1
  144. ksadk/memory/adk/backends/http_ltm_backend.py +14 -5
  145. ksadk/memory/adk/backends/inmemory_ltm_backend.py +136 -3
  146. ksadk/memory/adk/backends/sdk_ltm_backend.py +384 -2
  147. ksadk/memory/adk/backends/sqlite_ltm_backend.py +95 -0
  148. ksadk/memory/coordinator.py +461 -0
  149. ksadk/memory/events.py +202 -0
  150. ksadk/memory/extraction.py +228 -0
  151. ksadk/memory/ltm_backend_factory.py +16 -3
  152. ksadk/memory/models.py +316 -0
  153. ksadk/memory/policy.py +215 -0
  154. ksadk/memory/provider.py +47 -0
  155. ksadk/memory/provider_adapter.py +159 -0
  156. ksadk/memory/provider_resolver.py +71 -0
  157. ksadk/memory/providers/__init__.py +5 -0
  158. ksadk/memory/providers/local_sqlite.py +490 -0
  159. ksadk/memory/resolved_policy.py +145 -0
  160. ksadk/memory/service.py +188 -6
  161. ksadk/model_proxy/bootstrap.py +16 -9
  162. ksadk/model_proxy/detect.py +202 -9
  163. ksadk/model_proxy/namespace.py +39 -15
  164. ksadk/model_proxy/server.py +24 -5
  165. ksadk/model_proxy/transform.py +60 -2
  166. ksadk/observability/__init__.py +25 -0
  167. ksadk/observability/session_log.py +420 -0
  168. ksadk/observability/trajectory.py +105 -0
  169. ksadk/prompts/__init__.py +71 -0
  170. ksadk/prompts/compiler.py +215 -0
  171. ksadk/prompts/models.py +82 -0
  172. ksadk/prompts/projection.py +89 -0
  173. ksadk/prompts/resolved.py +137 -0
  174. ksadk/prompts/sources.py +233 -0
  175. ksadk/runners/_langgraph_runner_streams.py +822 -0
  176. ksadk/runners/adk_runner.py +5 -5
  177. ksadk/runners/base_runner.py +16 -0
  178. ksadk/runners/factory.py +1 -2
  179. ksadk/runners/langgraph_runner.py +198 -437
  180. ksadk/runtime/_runner_adapter/__init__.py +1 -0
  181. ksadk/runtime/_runner_adapter/stream_mapping.py +788 -0
  182. ksadk/runtime/adapter.py +118 -2
  183. ksadk/runtime/conversation_execution.py +316 -182
  184. ksadk/runtime/executor.py +144 -3
  185. ksadk/runtime/factory.py +193 -7
  186. ksadk/runtime/hosted_finalizer.py +268 -0
  187. ksadk/runtime/launch.py +14 -1
  188. ksadk/runtime/preprocessing.py +25 -3
  189. ksadk/runtime/runner_adapter.py +288 -508
  190. ksadk/runtime/usage.py +33 -0
  191. ksadk/sandbox/backends/e2b.py +35 -2
  192. ksadk/server/composition.py +8 -0
  193. ksadk/server/factory.py +69 -6
  194. ksadk/server/routes/kernel_ingress.py +258 -0
  195. ksadk/server/routes/openai_compat.py +88 -8
  196. ksadk/server/routes/projection.py +35 -20
  197. ksadk/server/routes/run.py +94 -0
  198. ksadk/server/routes/sessions.py +2 -0
  199. ksadk/server/routes/streaming.py +5 -2
  200. ksadk/server/static/assets/{ArtifactsPanel-CakCqxEN.js → ArtifactsPanel-DSU1sWD_.js} +1 -1
  201. ksadk/server/static/assets/{CodeBlock-CynLknyO.js → CodeBlock-DOH6MVcn.js} +4 -4
  202. ksadk/server/static/assets/{MathMessageMarkdown-3sQdOysS.js → MathMessageMarkdown-BL8my1R2.js} +4 -4
  203. ksadk/server/static/assets/MathMessageMarkdown-BorAY7qD.css +1 -0
  204. ksadk/server/static/assets/MermaidBlock-Dz4IP-Tx.js +312 -0
  205. ksadk/server/static/assets/NativeTerminalPanel-DUrK0JpZ.js +1 -0
  206. ksadk/server/static/assets/abnfDiagram-VCTEODGH-g20pFzNV.js +1 -0
  207. ksadk/server/static/assets/arc-C4FzinUA.js +1 -0
  208. ksadk/server/static/assets/architecture-7GRP2DOG-DjKratdf.js +1 -0
  209. ksadk/server/static/assets/architectureDiagram-5GKGNRK7-DpIqL5h4.js +36 -0
  210. ksadk/server/static/assets/blockDiagram-NRAW4CY4-BjkljTNz.js +129 -0
  211. ksadk/server/static/assets/c4Diagram-UCG6FXSJ-Dk_ieq2X.js +38 -0
  212. ksadk/server/static/assets/channel-4cQHKtx1.js +1 -0
  213. ksadk/server/static/assets/chunk-2Q5K7J3B-DmgWkESh.js +1 -0
  214. ksadk/server/static/assets/{chunk-FMBD7UC4-B_fH2YuH.js → chunk-5VM5RSS4-BVHAchFb.js} +1 -1
  215. ksadk/server/static/assets/{chunk-ND2GUHAM-D6rFLaVV.js → chunk-F27PBJKO-C-ipQzuS.js} +1 -1
  216. ksadk/server/static/assets/chunk-G27WJ6UU-C2EyJbIK.js +231 -0
  217. ksadk/server/static/assets/{chunk-4BX2VUAB-B9drTgOW.js → chunk-JWPE2WC7-vYvVJb_M.js} +1 -1
  218. ksadk/server/static/assets/chunk-LCL6LL3I-BcI6ysPT.js +206 -0
  219. ksadk/server/static/assets/chunk-POPQ4Y6H-C030x_Z1.js +1 -0
  220. ksadk/server/static/assets/chunk-RHFEMEQ7-yyGpsz4n.js +168 -0
  221. ksadk/server/static/assets/chunk-SVP7TREG-BLTlmMU7.js +88 -0
  222. ksadk/server/static/assets/chunk-XXDRQBXY-C_32ArgP.js +1 -0
  223. ksadk/server/static/assets/classDiagram-DTDB5LWJ-DLFd9Xi0.js +1 -0
  224. ksadk/server/static/assets/classDiagram-v2-JRS7N3AN-DLFd9Xi0.js +1 -0
  225. ksadk/server/static/assets/{cose-bilkent-S5V4N54A-ChNs_Mdk.js → cose-bilkent-JH36ORCC-9YQYwdl0.js} +1 -1
  226. ksadk/server/static/assets/cynefin-OW5HDTMX-DjEM48Qp.js +1 -0
  227. ksadk/server/static/assets/cynefinDiagram-5FMLGOSQ-ErLF5N13.js +62 -0
  228. ksadk/server/static/assets/cytoscape.esm-CyCl8rPi.js +321 -0
  229. ksadk/server/static/assets/dagre-3AP2YEHR-DFiQF-6f.js +4 -0
  230. ksadk/server/static/assets/dagre-BuhGnRI1.js +1 -0
  231. ksadk/server/static/assets/diagram-S7CK7UJ4-Bt1v8-GC.js +30 -0
  232. ksadk/server/static/assets/diagram-UQ7AKVKN-DSCxJdBK.js +41 -0
  233. ksadk/server/static/assets/diagram-VSXAHHWV-DHfYwp_9.js +3 -0
  234. ksadk/server/static/assets/diagram-VX7I27RA-DdzD-4Le.js +24 -0
  235. ksadk/server/static/assets/diagram-Z3DM3KII-Du-nAJ9F.js +24 -0
  236. ksadk/server/static/assets/{dist-Dli7qW-B.js → dist-8hqcx0sU.js} +1 -1
  237. ksadk/server/static/assets/dist-B7seoj3d.js +1 -0
  238. ksadk/server/static/assets/{dist-C1sz5Eo3.js → dist-BE7bu-DL.js} +1 -1
  239. ksadk/server/static/assets/{dist-fhOuWds5.js → dist-BVDffZ0U.js} +1 -1
  240. ksadk/server/static/assets/{dist-BjOdlDjj.js → dist-BX8z72IC.js} +1 -1
  241. ksadk/server/static/assets/{dist-DsHPdk3W.js → dist-Bf2M8m3N.js} +1 -1
  242. ksadk/server/static/assets/{dist-o2OVmKvt.js → dist-BjU6y-A2.js} +1 -1
  243. ksadk/server/static/assets/{dist-DWKByxWV.js → dist-BytlxIDT.js} +1 -1
  244. ksadk/server/static/assets/{dist-DJN_6Y39.js → dist-CSh_DE14.js} +1 -1
  245. ksadk/server/static/assets/{dist-DQU9EWw-.js → dist-CXYYBw3_.js} +1 -1
  246. ksadk/server/static/assets/{dist-4N2NMVYg.js → dist-C_wsv-Qd.js} +1 -1
  247. ksadk/server/static/assets/{dist-gLnrGsoU.js → dist-ClxGviKw.js} +1 -1
  248. ksadk/server/static/assets/{dist-j6Dxmf_j.js → dist-CttYUqzS.js} +1 -1
  249. ksadk/server/static/assets/{dist-D6MpCZtz.js → dist-DNp6rLRA.js} +1 -1
  250. ksadk/server/static/assets/{dist-BB3-OwTQ.js → dist-DUX-id_F.js} +1 -1
  251. ksadk/server/static/assets/{dist-_pHPTyZ-.js → dist-DmldrHd_.js} +1 -1
  252. ksadk/server/static/assets/{dist-CWV4lDr1.js → dist-DnfXs8Vn.js} +2 -2
  253. ksadk/server/static/assets/{dist-B5oS1zcj.js → dist-Dq9gLD7L.js} +1 -1
  254. ksadk/server/static/assets/{dist-B-jNR6Vn.js → dist-W-TIVntx.js} +1 -1
  255. ksadk/server/static/assets/{dist-BIlKoW0k.js → dist-dDdADKFA.js} +1 -1
  256. ksadk/server/static/assets/{dist-X4TnqwOK.js → dist-dydu68Fl.js} +1 -1
  257. ksadk/server/static/assets/{dist-CmZHzlwZ.js → dist-ngtN0DJB.js} +1 -1
  258. ksadk/server/static/assets/ebnfDiagram-PWID7BFC-Da9C9NO1.js +1 -0
  259. ksadk/server/static/assets/erDiagram-SSCWMZ5O-EAGqqR79.js +99 -0
  260. ksadk/server/static/assets/eventmodeling-NTZA5JFV-CMgMaJrC.js +1 -0
  261. ksadk/server/static/assets/flowDiagram-A5DVABFB-BBKL0x3P.js +1 -0
  262. ksadk/server/static/assets/ganttDiagram-EL5Y4UJY-DqJsKb59.js +292 -0
  263. ksadk/server/static/assets/gitGraph-4MIJSDKK-Dw63mrhw.js +1 -0
  264. ksadk/server/static/assets/gitGraphDiagram-WWUBYQGX-B6g4dtDi.js +106 -0
  265. ksadk/server/static/assets/index-8ipRcQ-M.js +240 -0
  266. ksadk/server/static/assets/index-ByFCqjlh.css +2 -0
  267. ksadk/server/static/assets/info-A6RAGUB7-B6iAblII.js +1 -0
  268. ksadk/server/static/assets/infoDiagram-RXCK75RN-Djm_nbd5.js +2 -0
  269. ksadk/server/static/assets/{ishikawaDiagram-YF4QCWOH-K0OOfVna.js → ishikawaDiagram-5VMMS53U-DWya9SG2.js} +6 -6
  270. ksadk/server/static/assets/{journeyDiagram-JHISSGLW-8LeOJaZp.js → journeyDiagram-EYS64GPL-DutxhSNI.js} +6 -6
  271. ksadk/server/static/assets/{kanban-definition-UN3LZRKU-C6uCgZrW.js → kanban-definition-3QL26DDD-DJdOF8Fm.js} +10 -10
  272. ksadk/server/static/assets/katex-vFWytM5c.js +257 -0
  273. ksadk/server/static/assets/{linear-hdBcYzM8.js → linear-BHjG8b-J.js} +1 -1
  274. ksadk/server/static/assets/mermaid-parser.core-KGSy4jWT.js +166 -0
  275. ksadk/server/static/assets/{mindmap-definition-RKZ34NQL-Bjy_2v4_.js → mindmap-definition-FBJOCRG2-9-HC88D4.js} +29 -29
  276. ksadk/server/static/assets/packet-AYTQ26CC-BOYAipuq.js +1 -0
  277. ksadk/server/static/assets/pegDiagram-XKGWAZYB-DrEZd4fD.js +1 -0
  278. ksadk/server/static/assets/pie-WAS4IAKB-Ctq0Kbku.js +1 -0
  279. ksadk/server/static/assets/pieDiagram-E7YTZNPT-DpjqOFFp.js +39 -0
  280. ksadk/server/static/assets/{quadrantDiagram-W4KKPZXB-BmkRbwCg.js → quadrantDiagram-AXDQQJYC-BiNhgOXX.js} +6 -6
  281. ksadk/server/static/assets/radar-RG4KPBEZ-DN0-ul_0.js +1 -0
  282. ksadk/server/static/assets/railroad-74A4TZTK-C6cC_to0.js +1 -0
  283. ksadk/server/static/assets/railroad-abnf-HS5TGJTU-BimjIuRc.js +1 -0
  284. ksadk/server/static/assets/railroad-ebnf-LZEXJU2U-CvY65ABq.js +1 -0
  285. ksadk/server/static/assets/railroad-peg-WCYAUIDC-D72Iq_Tv.js +1 -0
  286. ksadk/server/static/assets/railroadDiagram-O6MQD6OU-_Y3Ojg6G.js +1 -0
  287. ksadk/server/static/assets/requirementDiagram-EFPCY7ZU-DeCFdg9K.js +84 -0
  288. ksadk/server/static/assets/{sankeyDiagram-5OEKKPKP-l6iXmU65.js → sankeyDiagram-P5KCCOFB-CPH75rhw.js} +7 -7
  289. ksadk/server/static/assets/{sequenceDiagram-3UESZ5HK-Cq6UBeQB.js → sequenceDiagram-WJ2MYXX4-OEpQQdr4.js} +10 -10
  290. ksadk/server/static/assets/sizeCapture-X5ZJPWSS-heUErzhI.js +1 -0
  291. ksadk/server/static/assets/stateDiagram-HBIQ2CUA-DvA3jSMB.js +1 -0
  292. ksadk/server/static/assets/stateDiagram-v2-4QOOHH4V-BgQY03nz.js +1 -0
  293. ksadk/server/static/assets/swimlanes-XN3QIQJK-CR-dfN_t.js +1 -0
  294. ksadk/server/static/assets/swimlanesDiagram-VK2B7HYN-DLVw3q5Q.js +8 -0
  295. ksadk/server/static/assets/{timeline-definition-PNZ67QCA-DEz24vV0.js → timeline-definition-24CTP7MA-DAVJf1TX.js} +7 -7
  296. ksadk/server/static/assets/treeView-Q6P3EWNA-BMpO0wsB.js +1 -0
  297. ksadk/server/static/assets/treemap-WGGIJYW6-Et0aqzU3.js +1 -0
  298. ksadk/server/static/assets/vennDiagram-4TSXK5OY-DwM8eDkh.js +34 -0
  299. ksadk/server/static/assets/wardley-WFR3VGLG-CbY0mhpl.js +1 -0
  300. ksadk/server/static/assets/wardleyDiagram-VM6X3IG4-DZL-Zz2t.js +78 -0
  301. ksadk/server/static/assets/xychartDiagram-S5SC5T6Z-Dy6Yh_hu.js +7 -0
  302. ksadk/server/static/index.html +2 -2
  303. ksadk/sessions/__init__.py +26 -9
  304. ksadk/sessions/_local_service_sync.py +688 -0
  305. ksadk/sessions/_local_tables.py +21 -0
  306. ksadk/sessions/_postgres_schema.py +305 -0
  307. ksadk/sessions/_postgres_tables.py +15 -0
  308. ksadk/sessions/base.py +80 -1
  309. ksadk/sessions/in_memory.py +53 -2
  310. ksadk/sessions/local_service.py +63 -604
  311. ksadk/sessions/postgres_service.py +58 -148
  312. ksadk/sessions/resilient.py +35 -1
  313. ksadk/studio/api.py +577 -25
  314. ksadk/studio/api_contracts.py +114 -5
  315. ksadk/studio/api_memory_routes.py +82 -0
  316. ksadk/studio/authoring.py +252 -27
  317. ksadk/studio/authoring_coordinator.py +799 -67
  318. ksadk/studio/builder.py +88 -11
  319. ksadk/studio/capabilities.py +17 -0
  320. ksadk/studio/cloud.py +1916 -95
  321. ksadk/studio/codex_agent_service.py +125 -14
  322. ksadk/studio/codex_authoring.py +469 -0
  323. ksadk/studio/codex_builder.py +138 -25
  324. ksadk/studio/codex_manifest.py +51 -22
  325. ksadk/studio/codex_run.py +46 -3
  326. ksadk/studio/compiler.py +1 -0
  327. ksadk/studio/contracts.py +114 -3
  328. ksadk/studio/event_store.py +25 -95
  329. ksadk/studio/framework_run.py +231 -3
  330. ksadk/studio/hosted_kernel.py +317 -0
  331. ksadk/studio/manifest_resolver.py +131 -0
  332. ksadk/studio/model_client.py +95 -9
  333. ksadk/studio/model_profile_service.py +1 -1
  334. ksadk/studio/operations.py +37 -5
  335. ksadk/studio/otel_trace.py +348 -42
  336. ksadk/studio/pcm_memory.py +85 -0
  337. ksadk/studio/repository.py +23 -2
  338. ksadk/studio/resource_catalog.py +43 -0
  339. ksadk/studio/run_service.py +563 -137
  340. ksadk/studio/runtime_source.py +42 -16
  341. ksadk/studio/service.py +1180 -72
  342. ksadk/studio/shared_web.py +32 -22
  343. ksadk/studio/static/assets/index-BLpcdrgW.css +1 -0
  344. ksadk/studio/static/assets/index-CYekR2Xv.js +260 -0
  345. ksadk/studio/static/index.html +2 -2
  346. ksadk/studio/templates.py +100 -8
  347. ksadk/studio/validator.py +19 -0
  348. ksadk/studio/workspace.py +30 -32
  349. ksadk/tracing/setup.py +304 -3
  350. ksadk/version.py +1 -1
  351. ksadk_runtime_common/schemas/runtime_event_v1.json +37 -0
  352. ksadk_runtime_common/schemas/runtime_event_v2.json +271 -0
  353. ksadk/events/parser.py +0 -191
  354. ksadk/server/static/assets/MathMessageMarkdown-DeYh8QPr.css +0 -1
  355. ksadk/server/static/assets/MermaidBlock-NERD_ef7.js +0 -303
  356. ksadk/server/static/assets/NativeTerminalPanel-CiHWf82q.js +0 -1
  357. ksadk/server/static/assets/arc-DrgjcKhl.js +0 -1
  358. ksadk/server/static/assets/architecture-7EHR7CIX-CpZLRCcY.js +0 -1
  359. ksadk/server/static/assets/architectureDiagram-3BPJPVTR-BXoVRbQ6.js +0 -36
  360. ksadk/server/static/assets/blockDiagram-GPEHLZMM-BnaB3Ywv.js +0 -132
  361. ksadk/server/static/assets/c4Diagram-AAUBKEIU-Dw4weZcp.js +0 -10
  362. ksadk/server/static/assets/channel-Dt3rQTFI.js +0 -1
  363. ksadk/server/static/assets/chunk-2J33WTMH-ChjpLK7j.js +0 -1
  364. ksadk/server/static/assets/chunk-55IACEB6-CK4ROATy.js +0 -1
  365. ksadk/server/static/assets/chunk-727SXJPM-B9KtTTgw.js +0 -206
  366. ksadk/server/static/assets/chunk-AQP2D5EJ-1O1mki3m.js +0 -231
  367. ksadk/server/static/assets/chunk-QZHKN3VN-iXEZtKQc.js +0 -1
  368. ksadk/server/static/assets/classDiagram-4FO5ZUOK-DIveV17Q.js +0 -1
  369. ksadk/server/static/assets/classDiagram-v2-Q7XG4LA2-DIveV17Q.js +0 -1
  370. ksadk/server/static/assets/cytoscape.esm-DelgaX4f.js +0 -321
  371. ksadk/server/static/assets/dagre-BM42HDAG-D0QXg_MQ.js +0 -4
  372. ksadk/server/static/assets/dagre-Bx709z4p.js +0 -1
  373. ksadk/server/static/assets/diagram-2AECGRRQ-DBDDKwBQ.js +0 -43
  374. ksadk/server/static/assets/diagram-5GNKFQAL-BkwDOxmO.js +0 -10
  375. ksadk/server/static/assets/diagram-KO2AKTUF-Bv8waYvY.js +0 -3
  376. ksadk/server/static/assets/diagram-LMA3HP47-e1VECDdu.js +0 -24
  377. ksadk/server/static/assets/diagram-OG6HWLK6-Ds9adfRl.js +0 -24
  378. ksadk/server/static/assets/dist-B5J2uhNk.js +0 -1
  379. ksadk/server/static/assets/erDiagram-TEJ5UH35-BPItFKH6.js +0 -85
  380. ksadk/server/static/assets/eventmodeling-FCH6USID-DYFSxbqr.js +0 -1
  381. ksadk/server/static/assets/flowDiagram-I6XJVG4X-BbYB9w5Y.js +0 -162
  382. ksadk/server/static/assets/ganttDiagram-6RSMTGT7-TQXa0KXv.js +0 -292
  383. ksadk/server/static/assets/gitGraph-WXDBUCRP-DyNYp6BN.js +0 -1
  384. ksadk/server/static/assets/gitGraphDiagram-PVQCEYII-bKblCnpa.js +0 -106
  385. ksadk/server/static/assets/graphlib-B8gBHxth.js +0 -1
  386. ksadk/server/static/assets/index-R52pJJvg.js +0 -177
  387. ksadk/server/static/assets/index-jJr3_955.css +0 -2
  388. ksadk/server/static/assets/info-J43DQDTF-WUx7qTde.js +0 -1
  389. ksadk/server/static/assets/infoDiagram-5YYISTIA-BGVT7J_i.js +0 -2
  390. ksadk/server/static/assets/katex-CYWseY5E.js +0 -265
  391. ksadk/server/static/assets/mermaid-parser.core-BWrDjSZM.js +0 -161
  392. ksadk/server/static/assets/packet-YPE3B663-BN13y_xl.js +0 -1
  393. ksadk/server/static/assets/pie-LRSECV5Y-ftSLXhhc.js +0 -1
  394. ksadk/server/static/assets/pieDiagram-4H26LBE5-GmmqNiVH.js +0 -30
  395. ksadk/server/static/assets/radar-GUYGQ44K-jaICkIeO.js +0 -1
  396. ksadk/server/static/assets/requirementDiagram-4Y6WPE33-DSWFqL7c.js +0 -84
  397. ksadk/server/static/assets/stateDiagram-AJRCARHV-qzTQpg3Y.js +0 -1
  398. ksadk/server/static/assets/stateDiagram-v2-BHNVJYJU-BYCoYGAN.js +0 -1
  399. ksadk/server/static/assets/treeView-BLDUP644-Cpib_vlz.js +0 -1
  400. ksadk/server/static/assets/treemap-LRROVOQU-DQxfmVHK.js +0 -1
  401. ksadk/server/static/assets/vennDiagram-CIIHVFJN-CMCixki2.js +0 -34
  402. ksadk/server/static/assets/wardley-L42UT6IY-BQYHnnkU.js +0 -1
  403. ksadk/server/static/assets/wardleyDiagram-YWT4CUSO-CVzB8F9K.js +0 -78
  404. ksadk/server/static/assets/xychartDiagram-2RQKCTM6-BFBqBLc1.js +0 -7
  405. ksadk/studio/evaluation.py +0 -192
  406. ksadk/studio/static/assets/index-CaEN0eTR.css +0 -1
  407. ksadk/studio/static/assets/index-DI2eY_NH.js +0 -252
  408. {agentengine_sdk_python-0.8.1.dist-info → agentengine_sdk_python-0.8.2.dist-info}/WHEEL +0 -0
  409. {agentengine_sdk_python-0.8.1.dist-info → agentengine_sdk_python-0.8.2.dist-info}/entry_points.txt +0 -0
  410. {agentengine_sdk_python-0.8.1.dist-info → agentengine_sdk_python-0.8.2.dist-info}/licenses/LICENSE +0 -0
  411. {agentengine_sdk_python-0.8.1.dist-info → agentengine_sdk_python-0.8.2.dist-info}/top_level.txt +0 -0
@@ -0,0 +1,61 @@
1
+ # -*- coding: utf-8 -*-
2
+ """Package-resident fingerprints for the frozen Agent Kernel wire contract.
3
+
4
+ The contract manifest lives at repository root for schema review, so it is not
5
+ available from an installed wheel. Hosted Runtime therefore cannot trust an
6
+ environment value that merely *claims* compatibility: the supported aggregate
7
+ digest is shipped in this Python module. The contract regression test locks
8
+ this constant to ``contracts/agent-kernel/v1/manifest.json``.
9
+ """
10
+ from __future__ import annotations
11
+
12
+ import hashlib
13
+ import json
14
+ from typing import Any
15
+
16
+ AGENT_KERNEL_V1_CONTRACT_SET = "agent-kernel/v1"
17
+ AGENT_KERNEL_V1_AGGREGATE_DIGEST = (
18
+ "47e1003e03d97abeba232cc3e03a14b9cbcf78b1109870ccd2ce371f073b6211"
19
+ )
20
+
21
+
22
+ def runtime_capability_matrix_wire_value(matrix: Any) -> dict[str, Any]:
23
+ """Serialize the additive matrix without materializing absent v2 modes.
24
+
25
+ Pydantic includes optional ``None`` defaults in ``model_dump``. Omitting
26
+ those three top-level keys preserves the exact pre-extension wire value and
27
+ capability digest for runtimes that do not publish goal/loop/plan.
28
+ """
29
+
30
+ dump = matrix.model_dump(mode="json")
31
+ for key in ("goal", "loop", "plan"):
32
+ if dump.get(key) is None:
33
+ dump.pop(key, None)
34
+ return dump
35
+
36
+
37
+ def runtime_capability_matrix_digest(matrix: Any) -> str:
38
+ """Return the stable SHA-256 of the RuntimeCapabilityMatrix wire value.
39
+
40
+ ``model_dump(mode=\"json\")`` is deliberate: it binds the digest to the
41
+ public typed matrix rather than a framework object's in-memory layout.
42
+ JSON key sort and compact separators make the value independent of Python
43
+ dict insertion order and whitespace.
44
+ """
45
+
46
+ dump = runtime_capability_matrix_wire_value(matrix)
47
+ canonical = json.dumps(
48
+ dump,
49
+ ensure_ascii=False,
50
+ sort_keys=True,
51
+ separators=(",", ":"),
52
+ ).encode("utf-8")
53
+ return hashlib.sha256(canonical).hexdigest()
54
+
55
+
56
+ __all__ = [
57
+ "AGENT_KERNEL_V1_AGGREGATE_DIGEST",
58
+ "AGENT_KERNEL_V1_CONTRACT_SET",
59
+ "runtime_capability_matrix_digest",
60
+ "runtime_capability_matrix_wire_value",
61
+ ]
@@ -0,0 +1,362 @@
1
+ """Agent Kernel v1 冻结合同(Pydantic 判别模型)。
2
+
3
+ 对应 docs/superpowers/plans/2026-08-17-agent-runtime-v2-phase1-agent-kernel.md 第 2 节。
4
+ 所有 envelope 使用 extra="allow" 保存未知 optional 字段,保证 forward-compatible round-trip;
5
+ payload 按 command_type 判别为独立模型。
6
+ """
7
+ from __future__ import annotations
8
+
9
+ from typing import Annotated, Any, Literal, Union
10
+ from uuid import UUID
11
+
12
+ from pydantic import AfterValidator, BaseModel, ConfigDict, Field, model_validator
13
+
14
+
15
+ def _validate_json_value(value: Any) -> Any:
16
+ """运行时校验 JsonValue(py3.10 兼容取舍)。
17
+
18
+ Pydantic 2 对旧式递归 Union alias 在类型求值阶段直接 RecursionError
19
+ (实测 3.10/3.11 + pydantic 2.13 均如此),PEP 695 ``type`` 语句又是
20
+ 3.12+ 语法。因此 ``JsonValue = Annotated[Any, AfterValidator(...)]``:
21
+ 静态上不再递归,运行时保证值是合法 JSON(str key / 基本类型递归)。
22
+ """
23
+
24
+ def walk(node: Any) -> None:
25
+ if node is None or isinstance(node, (str, bool, int, float)):
26
+ return
27
+ if isinstance(node, dict):
28
+ for key, item in node.items():
29
+ if not isinstance(key, str):
30
+ raise ValueError(
31
+ f"JsonValue dict keys must be str, got {type(key).__name__}"
32
+ )
33
+ walk(item)
34
+ return
35
+ if isinstance(node, list):
36
+ for item in node:
37
+ walk(item)
38
+ return
39
+ raise ValueError(f"value is not JSON-serializable: {type(node).__name__}")
40
+
41
+ walk(value)
42
+ return value
43
+
44
+
45
+ JsonValue = Annotated[Any, AfterValidator(_validate_json_value)]
46
+
47
+
48
+ class WireModel(BaseModel):
49
+ model_config = ConfigDict(extra="allow", frozen=True)
50
+
51
+
52
+ # ------------------------------------------------------------------ payloads
53
+
54
+
55
+ class EnqueuePayload(WireModel):
56
+ content: JsonValue
57
+ reply_to: str | None = None
58
+
59
+
60
+ class SteerPayload(WireModel):
61
+ content: JsonValue
62
+ run_id: str | None = None
63
+
64
+
65
+ class InjectPayload(WireModel):
66
+ context: JsonValue
67
+ run_id: str | None = None
68
+
69
+
70
+ class InterruptPayload(WireModel):
71
+ run_id: str | None = None
72
+ reason: str | None = None
73
+
74
+
75
+ class PausePayload(WireModel):
76
+ run_id: str | None = None
77
+ reason: str | None = None
78
+
79
+
80
+ class ResumeTarget(WireModel):
81
+ kind: Literal["checkpoint", "continuation", "run"]
82
+ id: str
83
+
84
+
85
+ class ResumePayload(WireModel):
86
+ target: ResumeTarget
87
+ input: JsonValue = None
88
+
89
+
90
+ class SubmitInteractionPayload(WireModel):
91
+ run_id: str
92
+ interaction_id: str
93
+ # token_ref 是一次性 interaction 授权引用,不是可持久化的原始 token。
94
+ token_ref: str
95
+ response: JsonValue
96
+ # 以下为 additive 字段(Task 6):允许 wire 侧携带完整 submitInteractionRequest;
97
+ # 缺省时 Worker 以权威 InteractionRecord 补齐(expected_revision=当前 revision,
98
+ # action=submit,idempotency_key=command.idempotency_key)。
99
+ action: str | None = None
100
+ expected_revision: int | None = None
101
+ idempotency_key: str | None = None
102
+
103
+
104
+ PAYLOAD_MODELS: dict[str, type[WireModel]] = {
105
+ "enqueue": EnqueuePayload,
106
+ "steer": SteerPayload,
107
+ "inject": InjectPayload,
108
+ "interrupt": InterruptPayload,
109
+ "pause": PausePayload,
110
+ "resume": ResumePayload,
111
+ "submit_interaction": SubmitInteractionPayload,
112
+ }
113
+
114
+
115
+ # ----------------------------------------------------------------- commands
116
+
117
+
118
+ class ControlSource(WireModel):
119
+ kind: Literal[
120
+ "studio", "responses", "agui", "a2a", "parent_agent",
121
+ "scheduler", "workflow", "channel", "system",
122
+ ]
123
+ ref: str
124
+
125
+
126
+ class AgentControlCommand(WireModel):
127
+ schema_version: Literal[1] = 1
128
+ command_id: UUID
129
+ idempotency_key: str
130
+ tenant_id: str
131
+ agent_instance_id: str
132
+ session_id: str
133
+ command_type: Literal[
134
+ "enqueue", "steer", "inject", "interrupt",
135
+ "pause", "resume", "submit_interaction",
136
+ ]
137
+ payload: dict[str, JsonValue]
138
+ source: ControlSource
139
+ authorization_ref: str
140
+ submitted_at: str
141
+ causation_id: str | None = None
142
+ correlation_id: str | None = None
143
+
144
+ @model_validator(mode="after")
145
+ def _validate_payload_shape(self) -> "AgentControlCommand":
146
+ PAYLOAD_MODELS[self.command_type].model_validate(dict(self.payload))
147
+ return self
148
+
149
+
150
+ class AgentControlPermit(WireModel):
151
+ schema_version: Literal[1] = 1
152
+ permit_id: str
153
+ subject_ref: str
154
+ tenant_id: str
155
+ agent_instance_id: str
156
+ session_id: str | None
157
+ allowed_operations: list[Literal[
158
+ "enqueue", "steer", "inject", "interrupt", "pause", "resume",
159
+ "submit_interaction", "get_status", "subscribe_events",
160
+ ]]
161
+ issued_at: str
162
+ expires_at: str
163
+ nonce: str
164
+ key_id: str
165
+ alg: Literal["Ed25519"] = "Ed25519"
166
+ claims_digest: str
167
+ signature: str
168
+
169
+
170
+ # ----------------------------------------------------------------- receipts
171
+
172
+
173
+ class ControlError(WireModel):
174
+ code: str
175
+ message: str
176
+ retryable: bool
177
+ details: dict[str, JsonValue] = Field(default_factory=dict)
178
+
179
+
180
+ class AgentControlReceipt(WireModel):
181
+ schema_version: Literal[1] = 1
182
+ command_id: UUID
183
+ status: Literal[
184
+ "accepted", "duplicate", "rejected", "unsupported",
185
+ "queue_full", "persistence_uncertain",
186
+ ]
187
+ message_id: UUID | None = None
188
+ run_id: str | None = None
189
+ accepted_seq: int | None = None
190
+ error: ControlError | None = None
191
+
192
+ @model_validator(mode="after")
193
+ def _validate_receipt_constraints(self) -> "AgentControlReceipt":
194
+ if self.status in ("accepted", "duplicate"):
195
+ if self.message_id is None:
196
+ raise ValueError(f"{self.status} receipt must carry message_id")
197
+ else:
198
+ if self.error is None:
199
+ raise ValueError(f"{self.status} receipt must carry error")
200
+ return self
201
+
202
+
203
+ class AgentStatusQuery(WireModel):
204
+ schema_version: Literal[1] = 1
205
+ tenant_id: str
206
+ agent_instance_id: str
207
+ authorization_ref: str
208
+ session_id: str | None = None
209
+
210
+
211
+ class SessionEventSubscription(WireModel):
212
+ schema_version: Literal[1] = 1
213
+ tenant_id: str
214
+ agent_instance_id: str
215
+ session_id: str
216
+ authorization_ref: str
217
+ after_seq: int = 0
218
+
219
+
220
+ # ------------------------------------------------------------- session events
221
+
222
+
223
+ class SessionEventEnvelope(WireModel):
224
+ schema_version: Literal[1] = 1
225
+ event_id: UUID
226
+ session_id: str
227
+ seq: int
228
+ timestamp: str
229
+ family: Literal[
230
+ "control", "runtime", "workflow", "schedule", "job", "relationship",
231
+ "interaction",
232
+ ]
233
+ family_version: int
234
+ event_type: str
235
+ payload: dict[str, JsonValue]
236
+ run_id: str | None = None
237
+ causation_id: str | None = None
238
+ correlation_id: str | None = None
239
+ actor_ref: str | None = None
240
+
241
+ @model_validator(mode="after")
242
+ def _validate_family_version(self) -> "SessionEventEnvelope":
243
+ expected = {"control": 1, "runtime": 2, "interaction": 1}.get(self.family)
244
+ if expected is not None and self.family_version != expected:
245
+ raise ValueError(
246
+ f"family {self.family} requires family_version {expected}, "
247
+ f"got {self.family_version}"
248
+ )
249
+ return self
250
+
251
+
252
+ # ------------------------------------------------------------------- guards
253
+
254
+
255
+ class AdmissionWriteGuard(WireModel):
256
+ authorization_ref: str
257
+ command_id: UUID
258
+
259
+
260
+ class ActivationWriteGuard(WireModel):
261
+ activation_id: str
262
+ fencing_token: int
263
+
264
+
265
+ SessionEventWriteGuard = Union[AdmissionWriteGuard, ActivationWriteGuard]
266
+ WriteContext = ActivationWriteGuard
267
+
268
+
269
+ # -------------------------------------------------------------------- lease
270
+
271
+
272
+ class ActivationLease(WireModel):
273
+ schema_version: Literal[1] = 1
274
+ agent_instance_id: str
275
+ activation_id: str
276
+ fencing_token: int
277
+ lease_expires_at: str
278
+ bundle_digest: str
279
+ runtime_type: str
280
+ capability_digest: str
281
+
282
+
283
+ # --------------------------------------------------------------- capability
284
+
285
+
286
+ class RuntimeCapability(WireModel):
287
+ supported: bool
288
+ mode: Literal["native", "emulated", "unavailable"]
289
+ reason: str | None = None
290
+
291
+ @model_validator(mode="after")
292
+ def _validate_unavailable(self) -> "RuntimeCapability":
293
+ if not self.supported:
294
+ if self.mode != "unavailable":
295
+ raise ValueError("supported=false must pair with mode=unavailable")
296
+ if not self.reason:
297
+ raise ValueError("supported=false must carry a stable reason code")
298
+ return self
299
+
300
+
301
+ class RuntimeCapabilityMatrix(WireModel):
302
+ schema_version: Literal[1] = 1
303
+ cancel: RuntimeCapability
304
+ pause: RuntimeCapability
305
+ resume: RuntimeCapability
306
+ submit_interaction: RuntimeCapability
307
+ attach: RuntimeCapability
308
+ steer: RuntimeCapability
309
+ inject: RuntimeCapability
310
+ checkpoint: RuntimeCapability
311
+ durable_restore: RuntimeCapability
312
+ # Runtime v2 execution controls are additive optional capabilities. Older
313
+ # runtimes omit them; a runtime must never infer support from UI presence.
314
+ # ``loop`` specifically means an externally bounded, eval-driven
315
+ # improvement loop. It is not the runtime's ordinary agent loop and it is
316
+ # not an alias for collaboration_mode=default.
317
+ goal: RuntimeCapability | None = None
318
+ loop: RuntimeCapability | None = None
319
+ plan: RuntimeCapability | None = None
320
+
321
+
322
+ class AgentStatusSnapshot(WireModel):
323
+ schema_version: Literal[1] = 1
324
+ agent_instance_id: str
325
+ instance_state: Literal["ready", "degraded", "unavailable"]
326
+ session_id: str | None = None
327
+ active_run_id: str | None = None
328
+ active_run_state: Literal["pending", "running", "paused", "waiting"] | None = None
329
+ inbox_depth: int
330
+ activation_id: str | None = None
331
+ lease_expires_at: str | None = None
332
+ capability: RuntimeCapabilityMatrix
333
+
334
+
335
+ __all__ = [
336
+ "JsonValue",
337
+ "WireModel",
338
+ "EnqueuePayload",
339
+ "SteerPayload",
340
+ "InjectPayload",
341
+ "InterruptPayload",
342
+ "PausePayload",
343
+ "ResumeTarget",
344
+ "ResumePayload",
345
+ "SubmitInteractionPayload",
346
+ "ControlSource",
347
+ "AgentControlCommand",
348
+ "AgentControlPermit",
349
+ "ControlError",
350
+ "AgentControlReceipt",
351
+ "AgentStatusQuery",
352
+ "SessionEventSubscription",
353
+ "SessionEventEnvelope",
354
+ "AdmissionWriteGuard",
355
+ "ActivationWriteGuard",
356
+ "SessionEventWriteGuard",
357
+ "WriteContext",
358
+ "ActivationLease",
359
+ "RuntimeCapability",
360
+ "RuntimeCapabilityMatrix",
361
+ "AgentStatusSnapshot",
362
+ ]
@@ -0,0 +1,219 @@
1
+ # -*- coding: utf-8 -*-
2
+ """深模块 AgentKernel control facade(Phase 1 Task 6 Step 3)。
3
+
4
+ 小接口 ``submit`` / ``status`` / ``subscribe``:
5
+
6
+ - ``submit``:先 permit 验证(fail closed)、capability 判定、queue limit,
7
+ 再进入单个 Store transaction(accept_command 内部完成 Inbox 行 +
8
+ ``control.command_accepted`` 事件的 persist-before-ack)。
9
+ - ``status``:只读 Store(active Run / Inbox depth / lease)+ capability
10
+ matrix,不创建 Run。
11
+ - ``subscribe``:直接委托 SessionEventStore cursor(replay 后 live)。
12
+ """
13
+ from __future__ import annotations
14
+
15
+ from collections.abc import AsyncIterator, Awaitable, Callable
16
+ from datetime import datetime
17
+ from typing import Any
18
+
19
+ from ksadk.events.session_event import SessionEventStore
20
+ from ksadk.kernel.authorization import (
21
+ AgentControlPermitVerifier,
22
+ PermitExpiredError,
23
+ )
24
+ from ksadk.kernel.contracts import (
25
+ AgentControlCommand,
26
+ AgentControlPermit,
27
+ AgentControlReceipt,
28
+ AgentStatusQuery,
29
+ AgentStatusSnapshot,
30
+ RuntimeCapability,
31
+ RuntimeCapabilityMatrix,
32
+ SessionEventEnvelope,
33
+ SessionEventSubscription,
34
+ )
35
+ from ksadk.kernel.errors import InvalidPermitError
36
+ from ksadk.kernel.mapping import (
37
+ CapabilityProvider,
38
+ capability_of,
39
+ )
40
+ from ksadk.kernel.store import AgentKernelStore, command_digest, now_utc
41
+
42
+
43
+ def _unavailable(reason: str = "not_implemented") -> RuntimeCapability:
44
+ return RuntimeCapability(supported=False, mode="unavailable", reason=reason)
45
+
46
+
47
+ def default_capability_matrix() -> RuntimeCapabilityMatrix:
48
+ """未提供 adapter capability 时的诚实默认值(全部 unavailable)。"""
49
+
50
+ return RuntimeCapabilityMatrix(
51
+ cancel=_unavailable(),
52
+ pause=_unavailable(),
53
+ resume=_unavailable(),
54
+ submit_interaction=_unavailable(),
55
+ attach=_unavailable(),
56
+ steer=_unavailable("runtime_no_native_steer"),
57
+ inject=_unavailable("runtime_no_native_inject"),
58
+ checkpoint=_unavailable(),
59
+ durable_restore=_unavailable(),
60
+ )
61
+
62
+
63
+ class AgentKernel:
64
+ def __init__(
65
+ self,
66
+ store: AgentKernelStore,
67
+ session_events: SessionEventStore,
68
+ permit_verifier: AgentControlPermitVerifier,
69
+ *,
70
+ queue_limit: int = 100,
71
+ capabilities: CapabilityProvider | None = None,
72
+ clock: Callable[[], datetime] = now_utc,
73
+ ) -> None:
74
+ self._store = store
75
+ self._events = session_events
76
+ self._permit_verifier = permit_verifier
77
+ self._queue_limit = int(queue_limit)
78
+ self._capabilities = capabilities or default_capability_matrix
79
+ self._clock = clock
80
+
81
+ def capabilities(self) -> RuntimeCapabilityMatrix:
82
+ """Return the runtime's current typed capability snapshot.
83
+
84
+ Readiness propagation uses this same source as admission, so an
85
+ Operator/Server never treats a deploy-time digest as a substitute for
86
+ the actual operation support matrix.
87
+ """
88
+
89
+ return self._capabilities()
90
+
91
+ # ---------------------------------------------------------------- submit
92
+
93
+ async def submit(
94
+ self, command: AgentControlCommand, *, permit: AgentControlPermit
95
+ ) -> AgentControlReceipt:
96
+ try:
97
+ await self._permit_verifier.verify(
98
+ permit, command, command.command_type, self._clock()
99
+ )
100
+ except PermitExpiredError:
101
+ return await self._expired_permit_receipt(command)
102
+ except InvalidPermitError as error:
103
+ return await self._store.reject_command(
104
+ command,
105
+ status="rejected",
106
+ code="invalid_permit",
107
+ message=error.message,
108
+ )
109
+
110
+ field, capability = capability_of(command.command_type, self._capabilities())
111
+ if field is not None and not capability.supported:
112
+ # steer/inject 等绝不降级为 enqueue:直接 unsupported。
113
+ return await self._store.reject_command(
114
+ command,
115
+ status="unsupported",
116
+ code=capability.reason or "not_implemented",
117
+ message=f"runtime capability {field} is unavailable",
118
+ )
119
+
120
+ return await self._store.accept_command(
121
+ command, queue_limit=self._queue_limit
122
+ )
123
+
124
+ async def _expired_permit_receipt(
125
+ self, command: AgentControlCommand
126
+ ) -> AgentControlReceipt:
127
+ """permit 过期:只有 Store 已有完全相同请求(同 digest/幂等域)才 duplicate。"""
128
+
129
+ existing = await self._store.load_by_idempotency(
130
+ command.session_id, command.idempotency_key
131
+ )
132
+ if existing is not None and existing.request_digest == command_digest(command):
133
+ return AgentControlReceipt(
134
+ command_id=command.command_id,
135
+ status="duplicate",
136
+ message_id=existing.message_id,
137
+ accepted_seq=existing.accepted_seq,
138
+ )
139
+ return await self._store.reject_command(
140
+ command,
141
+ status="rejected",
142
+ code="invalid_permit",
143
+ message="permit_expired",
144
+ )
145
+
146
+ # ---------------------------------------------------------------- status
147
+
148
+ async def status(
149
+ self, query: AgentStatusQuery, *, permit: AgentControlPermit
150
+ ) -> AgentStatusSnapshot:
151
+ try:
152
+ await self._permit_verifier.verify(
153
+ permit, query, "get_status", self._clock()
154
+ )
155
+ except (InvalidPermitError, PermitExpiredError):
156
+ return AgentStatusSnapshot(
157
+ agent_instance_id=query.agent_instance_id,
158
+ instance_state="unavailable",
159
+ session_id=query.session_id,
160
+ inbox_depth=0,
161
+ capability=self._capabilities(),
162
+ )
163
+ active = await self._store.find_active_run(
164
+ query.agent_instance_id, query.session_id
165
+ )
166
+ lease = await self._store.current_lease(
167
+ query.agent_instance_id, query.session_id
168
+ )
169
+ return AgentStatusSnapshot(
170
+ agent_instance_id=query.agent_instance_id,
171
+ instance_state="ready" if lease is not None else "degraded",
172
+ session_id=query.session_id or (active.session_id if active else None),
173
+ active_run_id=active.run_id if active else None,
174
+ active_run_state=active.state.value if active else None,
175
+ inbox_depth=await self._store.inbox_depth(
176
+ query.agent_instance_id, query.session_id
177
+ ),
178
+ activation_id=lease.activation_id if lease else None,
179
+ lease_expires_at=lease.lease_expires_at if lease else None,
180
+ capability=self._capabilities(),
181
+ )
182
+
183
+ # ------------------------------------------------------------- subscribe
184
+
185
+ async def subscribe(
186
+ self,
187
+ subscription: SessionEventSubscription,
188
+ *,
189
+ permit: AgentControlPermit,
190
+ should_stop: Callable[[], Awaitable[bool]] | None = None,
191
+ timeout: float | None = None,
192
+ ) -> AsyncIterator[SessionEventEnvelope]:
193
+ await self._permit_verifier.verify(
194
+ permit, subscription, "subscribe_events", self._clock()
195
+ )
196
+ subscribe = self._events.subscribe
197
+ kwargs: dict[str, Any] = {}
198
+ try:
199
+ signature = signature_of(subscribe)
200
+ except (TypeError, ValueError):
201
+ signature = None
202
+ parameters = getattr(signature, "parameters", {}) or {}
203
+ if should_stop is not None and "should_stop" in parameters:
204
+ kwargs["should_stop"] = should_stop
205
+ if timeout is not None and "timeout" in parameters:
206
+ kwargs["timeout"] = timeout
207
+ async for envelope in subscribe(
208
+ subscription.session_id, subscription.after_seq, **kwargs
209
+ ):
210
+ yield envelope
211
+
212
+
213
+ def signature_of(func: Any) -> Any:
214
+ import inspect
215
+
216
+ return inspect.signature(func)
217
+
218
+
219
+ __all__ = ["AgentKernel", "default_capability_matrix"]