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,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
+ ]
@@ -0,0 +1,215 @@
1
+ """PromptCompiler —— 确定性编译 Prompt 分区(方案第 7 节)。
2
+
3
+ 第一个 PR 只落地稳定数据模型;本(第二个)PR 实现 ``compile()`` 的确定性行为:排序、
4
+ 标准化、merge policy、protected 覆盖检测、SHA-256、section token 与 stable_prefix_hash。
5
+
6
+ PR2 仍是 shadow:``CompiledPrompt`` 仅用于 hash/可观测/未来 projection,**不替换** Runner
7
+ 实际发送的 instructions→new_message/SystemMessage/base_instructions 拼装,线上行为不变。
8
+ ``CompiledPrompt.content`` 不保证等于 Runner 最终物理输入(方案 7.2)。
9
+ """
10
+
11
+ from __future__ import annotations
12
+
13
+ import hashlib
14
+ import re
15
+ from dataclasses import dataclass, replace
16
+ from typing import Iterable
17
+
18
+ from ksadk.context_engine.tokenizer import get_default_token_counter
19
+ from ksadk.prompts.models import (
20
+ PROMPT_COMPILER_VERSION,
21
+ CompiledPrompt,
22
+ PromptSection,
23
+ PromptSectionKind,
24
+ )
25
+
26
+ # canonical 顺序:按 priority 升序,priority 相同按 kind 字典序。同一 section_id 的
27
+ # source/stability/merge_policy 必须固定,不因 Runner 遍历顺序变化(方案 7.3 第 8 条)。
28
+ _KIND_ORDER: tuple[PromptSectionKind, ...] = (
29
+ "platform_safety",
30
+ "agent_identity",
31
+ "agent_policy",
32
+ "runtime_capabilities",
33
+ "resource_manifest",
34
+ "request_instructions",
35
+ )
36
+
37
+
38
+ def _section_sort_key(section: PromptSection) -> tuple[int, str, str]:
39
+ kind_rank = _KIND_ORDER.index(section.kind) if section.kind in _KIND_ORDER else len(_KIND_ORDER)
40
+ kind_key = _KIND_ORDER[kind_rank] if kind_rank < len(_KIND_ORDER) else section.kind
41
+ return (section.priority, kind_key, section.section_id)
42
+
43
+
44
+ def _normalize_text(text: str) -> str:
45
+ """标准化换行与尾部空白,但不改变正文语义(方案 7.3 第 2 条)。
46
+
47
+ - CRLF/CR → LF
48
+ - 去除每行尾部空白
49
+ - 合并 3+ 连续空行为 1 行,去除首尾空白
50
+ """
51
+ if not text:
52
+ return ""
53
+ normalized = str(text).replace("\r\n", "\n").replace("\r", "\n")
54
+ lines = [line.rstrip() for line in normalized.split("\n")]
55
+ # 合并 2+ 连续空行 → 单空行(统一段落间距,不改变正文语义)
56
+ collapsed: list[str] = []
57
+ blank_run = 0
58
+ for line in lines:
59
+ if line == "":
60
+ blank_run += 1
61
+ if blank_run >= 2:
62
+ continue
63
+ collapsed.append(line)
64
+ else:
65
+ blank_run = 0
66
+ collapsed.append(line)
67
+ return "\n".join(collapsed).strip()
68
+
69
+
70
+ def _content_sha256(text: str) -> str:
71
+ return "sha256:" + hashlib.sha256(text.encode("utf-8")).hexdigest()
72
+
73
+
74
+ def _wrap_section(section: PromptSection, content: str) -> str:
75
+ """用标签消除区段歧义,但不应把所有动态上下文拼成 XML(方案 7.3 推荐格式)。"""
76
+ body = content.strip()
77
+ if not body:
78
+ return ""
79
+ return f"<{section.kind}>\n{body}\n</{section.kind}>"
80
+
81
+
82
+ def _merge_sections(sections: list[PromptSection]) -> list[PromptSection]:
83
+ """同 kind 多来源时执行显式 merge policy,禁止"最后写入悄悄覆盖"(方案 7.3 第 3 条)。
84
+
85
+ - ``replace``: 保留最后一条(同 section_id 之内)
86
+ - ``append``: 按顺序拼接
87
+ - ``merge_unique``: 去重拼接
88
+ - ``protected``: 不允许覆盖;发生覆盖尝试时抛 ``ProtectedSectionOverrideError``
89
+ """
90
+ grouped: dict[str, list[PromptSection]] = {}
91
+ order: list[str] = []
92
+ for section in sections:
93
+ if section.section_id not in grouped:
94
+ grouped[section.section_id] = []
95
+ order.append(section.section_id)
96
+ grouped[section.section_id].append(section)
97
+
98
+ merged: list[PromptSection] = []
99
+ for section_id in order:
100
+ bucket = grouped[section_id]
101
+ head = bucket[0]
102
+ if len(bucket) == 1:
103
+ merged.append(head)
104
+ continue
105
+ policy = head.merge_policy
106
+ # 同一 section_id 的来源/稳定性/merge_policy 必须固定(方案 7.3 第 8 条)。
107
+ inconsistent = any(
108
+ b.merge_policy != policy or b.stability != head.stability or b.kind != head.kind
109
+ for b in bucket[1:]
110
+ )
111
+ if inconsistent:
112
+ raise InconsistentSectionError(
113
+ f"section {section_id!r} 的来源/稳定性/merge_policy 不一致"
114
+ )
115
+ if policy == "replace":
116
+ merged.append(replace(head, content=bucket[-1].content))
117
+ elif policy == "protected":
118
+ # 任意两条同 section_id 内容不同即视为覆盖尝试。
119
+ contents = {b.content for b in bucket}
120
+ if len(contents) > 1:
121
+ raise ProtectedSectionOverrideError(
122
+ f"protected section {section_id!r} 发生覆盖尝试"
123
+ )
124
+ merged.append(head)
125
+ elif policy == "merge_unique":
126
+ seen: set[str] = set()
127
+ parts: list[str] = []
128
+ for b in bucket:
129
+ for chunk in re.split(r"\n{2,}", b.content.strip()):
130
+ chunk = chunk.strip()
131
+ if chunk and chunk not in seen:
132
+ seen.add(chunk)
133
+ parts.append(chunk)
134
+ merged.append(replace(head, content="\n\n".join(parts)))
135
+ else: # append
136
+ merged.append(
137
+ replace(
138
+ head,
139
+ content="\n\n".join(b.content.strip() for b in bucket if b.content.strip()),
140
+ )
141
+ )
142
+ return merged
143
+
144
+
145
+ class ProtectedSectionOverrideError(RuntimeError):
146
+ """``protected`` section 被尝试覆盖。编译失败并产生审计事件,不静默忽略(方案 7.3 第 9 条)。"""
147
+
148
+
149
+ class InconsistentSectionError(RuntimeError):
150
+ """同一 section_id 的来源/稳定性/merge_policy 不固定。"""
151
+
152
+
153
+ @dataclass(frozen=True)
154
+ class PromptCompiler:
155
+ """确定性 Prompt 编译器。
156
+
157
+ ``compile()`` 必须对相同输入产生相同输出(方案 7.3)。构造器无状态,可复用。
158
+ """
159
+
160
+ compiler_version: str = PROMPT_COMPILER_VERSION
161
+
162
+ def compile(self, sections: Iterable[PromptSection]) -> CompiledPrompt:
163
+ # 1. 排序(确定性)
164
+ ordered = sorted(sections, key=_section_sort_key)
165
+ # 2. merge(同 section_id 的多来源按 merge policy 合并)
166
+ merged = _merge_sections(ordered)
167
+ # 3. platform_safety 不允许被 request_instructions 覆盖(方案 7.3 第 4 条)。
168
+ # protected/replace 在 _merge_sections 内已处理;这里额外校验跨 section_id 的
169
+ # 信任边界:request_instructions 不得声明 platform 的 kind。
170
+ for section in merged:
171
+ if (
172
+ section.kind == "platform_safety"
173
+ and section.trust_level in ("untrusted", "user")
174
+ ):
175
+ raise ProtectedSectionOverrideError(
176
+ "platform_safety 不得由 untrusted/user 来源声明"
177
+ )
178
+
179
+ counter = get_default_token_counter()
180
+ # 4. 空 section 不输出占位文本(方案 7.3 第 5 条)。
181
+ section_hashes: dict[str, str] = {}
182
+ tokens_by_section: dict[str, int] = {}
183
+ wrapped_blocks: list[str] = []
184
+ for section in merged:
185
+ body = _normalize_text(section.content)
186
+ section_hashes[section.section_id] = _content_sha256(body)
187
+ tokens_by_section[section.section_id] = counter.count_text(body)
188
+ if body:
189
+ wrapped_blocks.append(_wrap_section(section, body))
190
+ canonical_content = "\n\n".join(block for block in wrapped_blocks if block).strip()
191
+
192
+ # 5. stable_prefix_hash:仅覆盖 stability="stable" 的 section(platform_safety /
193
+ # agent_identity / agent_policy)。部署级/动态 section 不进稳定前缀(方案 7.4)。
194
+ stable_body = "\n\n".join(
195
+ _wrap_section(s, _normalize_text(s.content))
196
+ for s in merged
197
+ if s.stability == "stable" and _normalize_text(s.content)
198
+ ).strip()
199
+ stable_prefix_hash = _content_sha256(stable_body) if stable_body else ""
200
+
201
+ return CompiledPrompt(
202
+ sections=tuple(merged),
203
+ content=canonical_content,
204
+ content_hash=_content_sha256(canonical_content),
205
+ estimated_tokens=counter.count_text(canonical_content),
206
+ stable_prefix_hash=stable_prefix_hash,
207
+ section_hashes=section_hashes,
208
+ tokens_by_section=tokens_by_section,
209
+ compiler_version=self.compiler_version,
210
+ )
211
+
212
+
213
+ def compile_prompt(sections: Iterable[PromptSection]) -> CompiledPrompt:
214
+ """便捷入口:用默认 compiler 编译。"""
215
+ return PromptCompiler().compile(sections)
@@ -0,0 +1,82 @@
1
+ """Prompt 分区数据模型(方案第 7 节)。
2
+
3
+ 第一个 PR 只落地稳定数据结构,公开类型从第一批开始版本化。``compiler.py`` / ``sources.py``
4
+ (确定性编译、merge、hash、指令文件发现)留第二个 PR;本模块不接管线,不改任何 Runner
5
+ 现有 instructions→new_message/SystemMessage/base_instructions 的拼装。
6
+ """
7
+
8
+ from __future__ import annotations
9
+
10
+ from dataclasses import dataclass, field
11
+ from typing import Literal
12
+
13
+ from ksadk.context_engine.capabilities import ContextAccuracy, ContextIntegrationMode
14
+
15
+ PROMPT_COMPILER_VERSION = "v1"
16
+
17
+ PromptSectionKind = Literal[
18
+ "platform_safety",
19
+ "agent_identity",
20
+ "agent_policy",
21
+ "runtime_capabilities",
22
+ "resource_manifest",
23
+ "request_instructions",
24
+ ]
25
+ """统一语义分区(方案 7.1)。动态历史、记忆和工具结果不属于 PromptSection。"""
26
+
27
+ PromptTrustLevel = Literal["platform", "developer", "resource", "untrusted", "user"]
28
+ PromptStability = Literal["stable", "deployment", "volatile"]
29
+ PromptMergePolicy = Literal["replace", "append", "merge_unique", "protected"]
30
+
31
+
32
+ @dataclass(frozen=True)
33
+ class PromptSection:
34
+ """一个 Prompt 分区单元(方案 7.2)。"""
35
+
36
+ section_id: str
37
+ kind: PromptSectionKind
38
+ content: str
39
+ source: str
40
+ priority: int
41
+ trust_level: PromptTrustLevel
42
+ stability: PromptStability = "stable"
43
+ merge_policy: PromptMergePolicy = "append"
44
+ overridable: bool = False
45
+ metadata: dict[str, object] = field(default_factory=dict)
46
+
47
+
48
+ @dataclass(frozen=True)
49
+ class CompiledPrompt:
50
+ """按确定规则编译后的稳定 Prompt(方案 7.2)。
51
+
52
+ ``content`` 是 canonical content,不保证等于 Runner 最终物理输入。``stable_prefix_hash``
53
+ 覆盖稳定前缀(platform_safety / agent_identity / agent_policy),用于 Prompt Cache
54
+ 失效诊断(第二个 PR 实现)。
55
+ """
56
+
57
+ sections: tuple[PromptSection, ...]
58
+ content: str
59
+ content_hash: str
60
+ estimated_tokens: int
61
+ stable_prefix_hash: str
62
+ section_hashes: dict[str, str]
63
+ tokens_by_section: dict[str, int]
64
+ compiler_version: str = PROMPT_COMPILER_VERSION
65
+
66
+
67
+ @dataclass(frozen=True)
68
+ class PromptProjectionResult:
69
+ """Runner 投影 Prompt 后的可审计结果(方案 7.2)。
70
+
71
+ 第一个 PR 只保留类型信封,不接管线;由后续 PR 的 projection 逻辑填充。
72
+ """
73
+
74
+ projection_id: str
75
+ runner_type: str
76
+ integration_mode: ContextIntegrationMode
77
+ projection_version: str
78
+ section_hashes: tuple[str, ...]
79
+ projected_roles: tuple[str, ...]
80
+ accounting_accuracy: ContextAccuracy
81
+ estimated_tokens: int | None
82
+ warnings: tuple[str, ...] = ()
@@ -0,0 +1,89 @@
1
+ """Prompt Projection —— CompiledPrompt → 目标 Runner 的可审计投影(方案 §7.1 / §7.2)。
2
+
3
+ Projection 把 ``CompiledPrompt`` 的 canonical section 按目标 Runner 的合法承载形式映射
4
+ (Codex ``base_instructions``、ADK ``instruction``、LangGraph ``system_message``),并输出
5
+ 可审计的 ``PromptProjectionResult``。Projection 可以改变物理承载形式,但必须保留 section
6
+ source、hash、信任级别和覆盖决策;不得改变安全优先级与信任边界(方案 §7.1)。
7
+
8
+ PR B 之前 Projection 仅用于可观测/审计,不替换 Runner 实际发送的 instructions。
9
+ """
10
+
11
+ from __future__ import annotations
12
+
13
+ import uuid
14
+ from typing import Any
15
+
16
+ from ksadk.context_engine.capabilities import ContextAccuracy, ContextIntegrationMode
17
+ from ksadk.prompts.models import CompiledPrompt, PromptProjectionResult
18
+
19
+ PROJECTION_VERSION = "v1"
20
+
21
+ # 各 integration_mode 的合法投影承载形式(方案 §6.2 / §7.1)。
22
+ _PROJECTION_ROLES: dict[ContextIntegrationMode, tuple[str, ...]] = {
23
+ "ksadk_hosted": ("system_message", "instruction"),
24
+ "framework_assisted": ("system_message", "state", "instruction", "session", "memory_service"),
25
+ "native_runtime": ("base_instructions", "thread"),
26
+ }
27
+
28
+
29
+ def project_compiled_prompt(
30
+ compiled: CompiledPrompt,
31
+ *,
32
+ runner_type: str,
33
+ integration_mode: ContextIntegrationMode,
34
+ accounting_accuracy: ContextAccuracy,
35
+ warnings: tuple[str, ...] = (),
36
+ ) -> PromptProjectionResult:
37
+ """投影 CompiledPrompt 到目标 Runner,输出可审计结果(方案 §7.2)。
38
+
39
+ 只读 ``compiled``,不改 Runner 输入。``projected_roles`` 反映该 integration_mode 的合法承载
40
+ 形式集合;``section_hashes`` 直接取自编译结果,保证投影前后 hash 一致、可校验顺序漂移。
41
+ """
42
+ roles = _PROJECTION_ROLES.get(integration_mode, ())
43
+ if not roles:
44
+ warnings = (*warnings, f"unknown_integration_mode:{integration_mode}")
45
+ # 校验安全优先级未被投影改变:platform_safety 必须存在且 trust_level=platform(若编译含它)。
46
+ safety_sections = [s for s in compiled.sections if s.kind == "platform_safety"]
47
+ for s in safety_sections:
48
+ if s.trust_level != "platform":
49
+ warnings = (*warnings, f"platform_safety_wrong_trust:{s.trust_level}")
50
+ return PromptProjectionResult(
51
+ projection_id=f"pj_{uuid.uuid4().hex[:16]}",
52
+ runner_type=runner_type,
53
+ integration_mode=integration_mode,
54
+ projection_version=PROJECTION_VERSION,
55
+ section_hashes=tuple(
56
+ compiled.section_hashes.get(s.section_id, "") for s in compiled.sections
57
+ ),
58
+ projected_roles=roles,
59
+ accounting_accuracy=accounting_accuracy,
60
+ estimated_tokens=compiled.estimated_tokens,
61
+ warnings=warnings,
62
+ )
63
+
64
+
65
+ def project_to_runner_payload(
66
+ compiled: CompiledPrompt,
67
+ *,
68
+ integration_mode: ContextIntegrationMode,
69
+ ) -> dict[str, Any]:
70
+ """把 CompiledPrompt.content 投影成目标 Runner 的 payload 字段(方案 §7.1)。
71
+
72
+ ksadk_hosted/framework_assisted(LangGraph 系) → ``{"system_message": content}``;
73
+ framework_assisted(ADK) → ``{"instruction": content}``;
74
+ native_runtime(Codex) → ``{"base_instructions": content}``。调用方据 capability 选字段。
75
+ """
76
+ if integration_mode == "native_runtime":
77
+ return {"base_instructions": compiled.content}
78
+ if integration_mode == "framework_assisted":
79
+ # ADK 用 instruction;LangGraph 用 system_message。两者都返回,调用方按 capability 选。
80
+ return {"instruction": compiled.content, "system_message": compiled.content}
81
+ # ksadk_hosted
82
+ return {"system_message": compiled.content, "instruction": compiled.content}
83
+
84
+
85
+ __all__ = [
86
+ "PROJECTION_VERSION",
87
+ "project_compiled_prompt",
88
+ "project_to_runner_payload",
89
+ ]