agentengine-sdk-python 0.8.1__py3-none-any.whl → 0.8.3__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 (476) hide show
  1. {agentengine_sdk_python-0.8.1.dist-info → agentengine_sdk_python-0.8.3.dist-info}/METADATA +25 -12
  2. {agentengine_sdk_python-0.8.1.dist-info → agentengine_sdk_python-0.8.3.dist-info}/RECORD +421 -232
  3. ksadk/_build_provenance.json +1 -0
  4. ksadk/a2a/_space_client_events.py +381 -0
  5. ksadk/a2a/event_adapter.py +156 -64
  6. ksadk/a2a/executor.py +179 -63
  7. ksadk/a2a/space_client.py +6 -333
  8. ksadk/a2ui/core.py +222 -53
  9. ksadk/agui/_agent_helpers.py +247 -0
  10. ksadk/agui/a2ui_projection.py +12 -5
  11. ksadk/agui/agent.py +443 -259
  12. ksadk/api/client.py +528 -27
  13. ksadk/builders/code_builder.py +284 -8
  14. ksadk/builders/container_builder.py +8 -1
  15. ksadk/builders/managed_runtime_builder.py +42 -35
  16. ksadk/cli/__init__.py +23 -0
  17. ksadk/cli/cmd_dashboard.py +15 -1
  18. ksadk/cli/cmd_deploy.py +10 -2
  19. ksadk/cli/cmd_eval.py +66 -9
  20. ksadk/cli/cmd_evalset.py +284 -0
  21. ksadk/cli/cmd_files.py +5 -1
  22. ksadk/cli/cmd_hermes.py +1 -126
  23. ksadk/cli/cmd_invoke.py +28 -38
  24. ksadk/cli/cmd_managed_runtime.py +95 -0
  25. ksadk/cli/cmd_observe.py +85 -0
  26. ksadk/cli/cmd_openclaw.py +1 -435
  27. ksadk/cli/cmd_plugin.py +657 -0
  28. ksadk/cli/cmd_replay.py +28 -4
  29. ksadk/cli/cmd_studio.py +99 -8
  30. ksadk/cli/cmd_web.py +10 -2
  31. ksadk/cli/hermes_env.py +151 -0
  32. ksadk/cli/invoke_payload.py +49 -0
  33. ksadk/cli/openclaw_env.py +458 -0
  34. ksadk/codex/client.py +180 -30
  35. ksadk/codex/runtime.py +475 -331
  36. ksadk/configs/env_registry.py +94 -12
  37. ksadk/configs/env_registry_pcm.py +181 -0
  38. ksadk/configs/env_var_spec.py +18 -0
  39. ksadk/configs/global_config.py +5 -0
  40. ksadk/configs/settings.py +9 -0
  41. ksadk/context_engine/__init__.py +98 -0
  42. ksadk/context_engine/assembler.py +176 -0
  43. ksadk/context_engine/baseline.py +419 -0
  44. ksadk/context_engine/cache_observability.py +228 -0
  45. ksadk/context_engine/capabilities.py +443 -0
  46. ksadk/context_engine/contributors.py +409 -0
  47. ksadk/context_engine/hosted_pipeline.py +417 -0
  48. ksadk/context_engine/models.py +117 -0
  49. ksadk/context_engine/planner.py +698 -0
  50. ksadk/context_engine/policies.py +319 -0
  51. ksadk/context_engine/projection.py +31 -0
  52. ksadk/context_engine/shadow_plan.py +266 -0
  53. ksadk/context_engine/tokenizer.py +164 -0
  54. ksadk/conversations/__init__.py +19 -0
  55. ksadk/conversations/context.py +230 -30
  56. ksadk/conversations/contracts.py +266 -0
  57. ksadk/conversations/message_projection.py +308 -26
  58. ksadk/conversations/model_context.py +49 -3
  59. ksadk/conversations/projector.py +616 -0
  60. ksadk/conversations/reducer.py +98 -0
  61. ksadk/conversations/runtime_compaction.py +207 -5
  62. ksadk/conversations/runtime_input.py +184 -2
  63. ksadk/conversations/runtime_invocation.py +81 -3
  64. ksadk/conversations/runtime_observability.py +141 -0
  65. ksadk/conversations/runtime_payloads.py +42 -0
  66. ksadk/conversations/runtime_preparation.py +272 -2
  67. ksadk/conversations/runtime_resume.py +20 -1
  68. ksadk/conversations/runtime_stream_events.py +94 -9
  69. ksadk/conversations/semantic_summary.py +311 -1
  70. ksadk/conversations/session_lock.py +51 -0
  71. ksadk/deployment/env_forward.py +72 -0
  72. ksadk/deployment/managed_runtime.py +5 -0
  73. ksadk/deployment/providers/serverless.py +143 -69
  74. ksadk/evaluation/__init__.py +32 -0
  75. ksadk/evaluation/a2a_adapter.py +9 -1
  76. ksadk/evaluation/adapters.py +18 -5
  77. ksadk/evaluation/agent_eval_client.py +395 -0
  78. ksadk/evaluation/cloud_binding.py +80 -0
  79. ksadk/evaluation/cloud_converter.py +194 -0
  80. ksadk/evaluation/cloud_service.py +199 -0
  81. ksadk/evaluation/contracts.py +73 -4
  82. ksadk/evaluation/evaluators.py +183 -17
  83. ksadk/evaluation/evidence.py +258 -0
  84. ksadk/evaluation/executor.py +31 -6
  85. ksadk/evaluation/local_adapter.py +550 -0
  86. ksadk/evaluation/service_env.py +27 -0
  87. ksadk/evaluation/studio_build_adapter.py +253 -0
  88. ksadk/evaluation/target.py +15 -6
  89. ksadk/events/__init__.py +13 -13
  90. ksadk/events/_v1_compat/__init__.py +1 -0
  91. ksadk/events/_v1_compat/models.py +299 -0
  92. ksadk/events/_v1_compat/parser.py +247 -0
  93. ksadk/events/_v1_compat/projection.py +755 -0
  94. ksadk/events/adapters/__init__.py +34 -0
  95. ksadk/events/adapters/_a2a_snapshot.py +622 -0
  96. ksadk/events/adapters/_a2a_support.py +275 -0
  97. ksadk/events/adapters/_codex_interactions.py +375 -0
  98. ksadk/events/adapters/_codex_items.py +801 -0
  99. ksadk/events/adapters/_codex_validators.py +311 -0
  100. ksadk/events/adapters/_langgraph_support.py +785 -0
  101. ksadk/events/adapters/a2a.py +841 -0
  102. ksadk/events/adapters/adk.py +503 -0
  103. ksadk/events/adapters/codex.py +907 -0
  104. ksadk/events/adapters/langgraph.py +745 -0
  105. ksadk/events/canonical.py +440 -0
  106. ksadk/events/canonical_replay.py +497 -0
  107. ksadk/events/canonical_store.py +468 -0
  108. ksadk/events/cold_recovery.py +257 -0
  109. ksadk/events/content.py +89 -0
  110. ksadk/events/identity.py +86 -0
  111. ksadk/events/pipeline.py +455 -0
  112. ksadk/events/projections.py +66 -0
  113. ksadk/events/reducer.py +661 -0
  114. ksadk/events/replay.py +3 -36
  115. ksadk/events/runtime_event.py +20 -265
  116. ksadk/events/session_event.py +324 -0
  117. ksadk/events/store.py +3 -316
  118. ksadk/events/v1_compat.py +41 -0
  119. ksadk/harness/__init__.py +45 -35
  120. ksadk/harness/runtime.py +220 -58
  121. ksadk/identity/resolver.py +4 -3
  122. ksadk/interaction/__init__.py +28 -0
  123. ksadk/interaction/contracts.py +136 -0
  124. ksadk/interaction/ledger.py +189 -0
  125. ksadk/interaction/provider.py +122 -0
  126. ksadk/interaction/providers/__init__.py +52 -0
  127. ksadk/interaction/providers/adk.py +40 -0
  128. ksadk/interaction/providers/codex.py +94 -0
  129. ksadk/interaction/providers/langgraph.py +58 -0
  130. ksadk/kernel/__init__.py +117 -0
  131. ksadk/kernel/authorization.py +258 -0
  132. ksadk/kernel/bootstrap.py +1074 -0
  133. ksadk/kernel/contract_fingerprints.py +62 -0
  134. ksadk/kernel/contracts.py +370 -0
  135. ksadk/kernel/control.py +220 -0
  136. ksadk/kernel/errors.py +79 -0
  137. ksadk/kernel/ingress.py +1123 -0
  138. ksadk/kernel/mapping.py +111 -0
  139. ksadk/kernel/memory_store.py +1134 -0
  140. ksadk/kernel/postgres_store.py +1757 -0
  141. ksadk/kernel/recovery.py +452 -0
  142. ksadk/kernel/runtime_identity.py +103 -0
  143. ksadk/kernel/sql/001_agent_kernel.sql +120 -0
  144. ksadk/kernel/sqlite_store.py +1411 -0
  145. ksadk/kernel/state.py +145 -0
  146. ksadk/kernel/store.py +232 -0
  147. ksadk/kernel/worker.py +964 -0
  148. ksadk/knowledge_base/client.py +7 -0
  149. ksadk/knowledge_base/service.py +32 -5
  150. ksadk/memory/__init__.py +61 -0
  151. ksadk/memory/adk/backends/base_ltm_backend.py +96 -1
  152. ksadk/memory/adk/backends/http_ltm_backend.py +14 -5
  153. ksadk/memory/adk/backends/inmemory_ltm_backend.py +136 -3
  154. ksadk/memory/adk/backends/sdk_ltm_backend.py +384 -2
  155. ksadk/memory/adk/backends/sqlite_ltm_backend.py +95 -0
  156. ksadk/memory/coordinator.py +461 -0
  157. ksadk/memory/events.py +202 -0
  158. ksadk/memory/extraction.py +228 -0
  159. ksadk/memory/ltm_backend_factory.py +16 -3
  160. ksadk/memory/models.py +316 -0
  161. ksadk/memory/policy.py +215 -0
  162. ksadk/memory/provider.py +47 -0
  163. ksadk/memory/provider_adapter.py +159 -0
  164. ksadk/memory/provider_resolver.py +71 -0
  165. ksadk/memory/providers/__init__.py +5 -0
  166. ksadk/memory/providers/local_sqlite.py +497 -0
  167. ksadk/memory/resolved_policy.py +145 -0
  168. ksadk/memory/service.py +188 -6
  169. ksadk/model_proxy/bootstrap.py +16 -9
  170. ksadk/model_proxy/detect.py +202 -9
  171. ksadk/model_proxy/namespace.py +39 -15
  172. ksadk/model_proxy/server.py +24 -5
  173. ksadk/model_proxy/transform.py +60 -2
  174. ksadk/observability/__init__.py +25 -0
  175. ksadk/observability/session_log.py +420 -0
  176. ksadk/observability/trajectory.py +105 -0
  177. ksadk/plugins/__init__.py +167 -0
  178. ksadk/plugins/bridges/__init__.py +45 -0
  179. ksadk/plugins/bridges/codex.py +552 -0
  180. ksadk/plugins/bridges/dsh.py +1116 -0
  181. ksadk/plugins/builtins.py +747 -0
  182. ksadk/plugins/bundle.py +246 -0
  183. ksadk/plugins/bundle_security.py +167 -0
  184. ksadk/plugins/composition.py +529 -0
  185. ksadk/plugins/context_contributor.py +437 -0
  186. ksadk/plugins/contracts.py +451 -0
  187. ksadk/plugins/dsh_toolchain.py +935 -0
  188. ksadk/plugins/ecosystem_bridge.py +1105 -0
  189. ksadk/plugins/ecosystem_probe.py +191 -0
  190. ksadk/plugins/host.py +724 -0
  191. ksadk/plugins/providers/__init__.py +85 -0
  192. ksadk/plugins/providers/bundles/ksadk-codex/cordis.patch.yml +3 -0
  193. ksadk/plugins/providers/bundles/ksadk-codex/index.mjs +18 -0
  194. ksadk/plugins/providers/bundles/ksadk-codex/package.json +19 -0
  195. ksadk/plugins/providers/bundles/ksadk-harness/cordis.patch.yml +3 -0
  196. ksadk/plugins/providers/bundles/ksadk-harness/index.mjs +19 -0
  197. ksadk/plugins/providers/bundles/ksadk-harness/package.json +19 -0
  198. ksadk/plugins/providers/codex.py +722 -0
  199. ksadk/plugins/providers/codex_dsh.py +83 -0
  200. ksadk/plugins/providers/dsh.py +951 -0
  201. ksadk/plugins/providers/dsh_descriptor_host.py +226 -0
  202. ksadk/plugins/providers/harness.py +627 -0
  203. ksadk/plugins/providers/harness_dsh.py +91 -0
  204. ksadk/plugins/providers/legacy.py +215 -0
  205. ksadk/plugins/providers/legacy_catalog.py +100 -0
  206. ksadk/plugins/providers/shipped_dsh.py +370 -0
  207. ksadk/plugins/resolver.py +331 -0
  208. ksadk/plugins/subagent_providers/__init__.py +12 -0
  209. ksadk/plugins/subagent_providers/codex.py +443 -0
  210. ksadk/plugins/subagents.py +333 -0
  211. ksadk/prompts/__init__.py +71 -0
  212. ksadk/prompts/compiler.py +215 -0
  213. ksadk/prompts/models.py +82 -0
  214. ksadk/prompts/projection.py +89 -0
  215. ksadk/prompts/resolved.py +137 -0
  216. ksadk/prompts/sources.py +233 -0
  217. ksadk/runners/_langgraph_runner_streams.py +822 -0
  218. ksadk/runners/adk_runner.py +5 -5
  219. ksadk/runners/base_runner.py +16 -0
  220. ksadk/runners/factory.py +1 -2
  221. ksadk/runners/langgraph_runner.py +198 -437
  222. ksadk/runtime/_runner_adapter/__init__.py +1 -0
  223. ksadk/runtime/_runner_adapter/stream_mapping.py +797 -0
  224. ksadk/runtime/adapter.py +119 -2
  225. ksadk/runtime/conversation_execution.py +316 -182
  226. ksadk/runtime/executor.py +144 -3
  227. ksadk/runtime/factory.py +268 -8
  228. ksadk/runtime/framework_adapters.py +18 -0
  229. ksadk/runtime/hosted_finalizer.py +268 -0
  230. ksadk/runtime/launch.py +14 -1
  231. ksadk/runtime/preprocessing.py +25 -3
  232. ksadk/runtime/runner_adapter.py +293 -508
  233. ksadk/runtime/usage.py +33 -0
  234. ksadk/sandbox/__init__.py +2 -1
  235. ksadk/sandbox/backends/e2b.py +35 -2
  236. ksadk/sandbox/factory.py +72 -0
  237. ksadk/scheduler/__init__.py +18 -0
  238. ksadk/scheduler/calendar.py +102 -0
  239. ksadk/scheduler/contracts.py +254 -0
  240. ksadk/scheduler/dispatcher.py +129 -0
  241. ksadk/scheduler/engine.py +416 -0
  242. ksadk/scheduler/sqlite_store.py +563 -0
  243. ksadk/server/composition.py +8 -0
  244. ksadk/server/factory.py +69 -6
  245. ksadk/server/routes/kernel_ingress.py +258 -0
  246. ksadk/server/routes/openai_compat.py +88 -8
  247. ksadk/server/routes/projection.py +35 -20
  248. ksadk/server/routes/run.py +94 -0
  249. ksadk/server/routes/sessions.py +2 -0
  250. ksadk/server/routes/streaming.py +5 -2
  251. ksadk/server/static/assets/{ArtifactsPanel-CakCqxEN.js → ArtifactsPanel-10GPXIJ6.js} +1 -1
  252. ksadk/server/static/assets/{CodeBlock-CynLknyO.js → CodeBlock-BXk1l-G1.js} +4 -4
  253. ksadk/server/static/assets/MathMessageMarkdown-BorAY7qD.css +1 -0
  254. ksadk/server/static/assets/{MathMessageMarkdown-3sQdOysS.js → MathMessageMarkdown-D9uB55Oh.js} +4 -4
  255. ksadk/server/static/assets/MermaidBlock--OEYoXIJ.js +312 -0
  256. ksadk/server/static/assets/NativeTerminalPanel-DrEe1syq.js +1 -0
  257. ksadk/server/static/assets/abnfDiagram-VCTEODGH-eeTFJLvo.js +1 -0
  258. ksadk/server/static/assets/arc-S3ZNbIAd.js +1 -0
  259. ksadk/server/static/assets/architecture-7GRP2DOG-Dk9nRQ6-.js +1 -0
  260. ksadk/server/static/assets/architectureDiagram-5GKGNRK7-CRjgEJDX.js +36 -0
  261. ksadk/server/static/assets/blockDiagram-NRAW4CY4-C7bsBoNH.js +129 -0
  262. ksadk/server/static/assets/c4Diagram-UCG6FXSJ-BX3c33Ob.js +38 -0
  263. ksadk/server/static/assets/channel-s354Yo6o.js +1 -0
  264. ksadk/server/static/assets/chunk-2Q5K7J3B-CDpPpKR5.js +1 -0
  265. ksadk/server/static/assets/{chunk-FMBD7UC4-B_fH2YuH.js → chunk-5VM5RSS4-bZ7ws-8m.js} +1 -1
  266. ksadk/server/static/assets/{chunk-ND2GUHAM-D6rFLaVV.js → chunk-F27PBJKO-D2r0pvhY.js} +1 -1
  267. ksadk/server/static/assets/chunk-G27WJ6UU-CZwF3oUP.js +231 -0
  268. ksadk/server/static/assets/{chunk-4BX2VUAB-B9drTgOW.js → chunk-JWPE2WC7-DigFYCML.js} +1 -1
  269. ksadk/server/static/assets/chunk-LCL6LL3I-CnorGV5q.js +206 -0
  270. ksadk/server/static/assets/chunk-POPQ4Y6H-CexntQA-.js +1 -0
  271. ksadk/server/static/assets/chunk-RHFEMEQ7-CHTC7UxA.js +168 -0
  272. ksadk/server/static/assets/chunk-SVP7TREG-BC1EWt_-.js +88 -0
  273. ksadk/server/static/assets/chunk-XXDRQBXY-BTG24xN0.js +1 -0
  274. ksadk/server/static/assets/classDiagram-DTDB5LWJ-Dd0nucl9.js +1 -0
  275. ksadk/server/static/assets/classDiagram-v2-JRS7N3AN-Dd0nucl9.js +1 -0
  276. ksadk/server/static/assets/{cose-bilkent-S5V4N54A-ChNs_Mdk.js → cose-bilkent-JH36ORCC-CkonRdAS.js} +1 -1
  277. ksadk/server/static/assets/cynefin-OW5HDTMX-BBlT4uMf.js +1 -0
  278. ksadk/server/static/assets/cynefinDiagram-5FMLGOSQ-DEOCBe15.js +62 -0
  279. ksadk/server/static/assets/cytoscape.esm-CyCl8rPi.js +321 -0
  280. ksadk/server/static/assets/dagre-3AP2YEHR-DBThPuLa.js +4 -0
  281. ksadk/server/static/assets/dagre-ClTPrTht.js +1 -0
  282. ksadk/server/static/assets/diagram-S7CK7UJ4-DsZHrnpJ.js +30 -0
  283. ksadk/server/static/assets/diagram-UQ7AKVKN-BJR4nhVr.js +41 -0
  284. ksadk/server/static/assets/diagram-VSXAHHWV-xzcERX0a.js +3 -0
  285. ksadk/server/static/assets/diagram-VX7I27RA-tn2xM1xu.js +24 -0
  286. ksadk/server/static/assets/diagram-Z3DM3KII-BZPGBkw5.js +24 -0
  287. ksadk/server/static/assets/{dist-gLnrGsoU.js → dist-4zN1_tq5.js} +1 -1
  288. ksadk/server/static/assets/{dist-C1sz5Eo3.js → dist-8VWI-2bZ.js} +1 -1
  289. ksadk/server/static/assets/{dist-BjOdlDjj.js → dist-B-46q3Hk.js} +1 -1
  290. ksadk/server/static/assets/{dist-o2OVmKvt.js → dist-B0gdk4rl.js} +1 -1
  291. ksadk/server/static/assets/{dist-4N2NMVYg.js → dist-B1oWRmrH.js} +1 -1
  292. ksadk/server/static/assets/{dist-CmZHzlwZ.js → dist-BI1qQH4n.js} +1 -1
  293. ksadk/server/static/assets/{dist-X4TnqwOK.js → dist-BJLUwH6W.js} +1 -1
  294. ksadk/server/static/assets/{dist-B5oS1zcj.js → dist-Bbwqa8TG.js} +1 -1
  295. ksadk/server/static/assets/{dist-j6Dxmf_j.js → dist-Btyo4vX4.js} +1 -1
  296. ksadk/server/static/assets/{dist-DQU9EWw-.js → dist-C71CsujO.js} +1 -1
  297. ksadk/server/static/assets/{dist-BIlKoW0k.js → dist-CXpH_Rdd.js} +1 -1
  298. ksadk/server/static/assets/{dist-DJN_6Y39.js → dist-Cq4OL6nO.js} +1 -1
  299. ksadk/server/static/assets/{dist-Dli7qW-B.js → dist-D1V3f1B4.js} +1 -1
  300. ksadk/server/static/assets/{dist-fhOuWds5.js → dist-DJmCPRVB.js} +1 -1
  301. ksadk/server/static/assets/{dist-CWV4lDr1.js → dist-DQAB0qn_.js} +2 -2
  302. ksadk/server/static/assets/{dist-D6MpCZtz.js → dist-DUwKa_l6.js} +1 -1
  303. ksadk/server/static/assets/dist-DdRBIceA.js +1 -0
  304. ksadk/server/static/assets/{dist-DWKByxWV.js → dist-DfGFrb0v.js} +1 -1
  305. ksadk/server/static/assets/{dist-DsHPdk3W.js → dist-DjhwGUgZ.js} +1 -1
  306. ksadk/server/static/assets/{dist-B-jNR6Vn.js → dist-DyqV4fL4.js} +1 -1
  307. ksadk/server/static/assets/{dist-BB3-OwTQ.js → dist-M67Hwu0n.js} +1 -1
  308. ksadk/server/static/assets/{dist-_pHPTyZ-.js → dist-u8tVH5Ak.js} +1 -1
  309. ksadk/server/static/assets/ebnfDiagram-PWID7BFC-DVfMsLge.js +1 -0
  310. ksadk/server/static/assets/erDiagram-SSCWMZ5O-CWEZSYaw.js +99 -0
  311. ksadk/server/static/assets/eventmodeling-NTZA5JFV-Dr5okd8V.js +1 -0
  312. ksadk/server/static/assets/flowDiagram-A5DVABFB-VEO-cVcO.js +1 -0
  313. ksadk/server/static/assets/ganttDiagram-EL5Y4UJY-TWIxoyYL.js +292 -0
  314. ksadk/server/static/assets/gitGraph-4MIJSDKK-CKiKY9Cf.js +1 -0
  315. ksadk/server/static/assets/gitGraphDiagram-WWUBYQGX-DDh2hd2S.js +106 -0
  316. ksadk/server/static/assets/index-B2k_urY8.js +241 -0
  317. ksadk/server/static/assets/index-ILPt6IWF.css +2 -0
  318. ksadk/server/static/assets/info-A6RAGUB7-ubA4Nm_p.js +1 -0
  319. ksadk/server/static/assets/infoDiagram-RXCK75RN-CgoyWiDR.js +2 -0
  320. ksadk/server/static/assets/{ishikawaDiagram-YF4QCWOH-K0OOfVna.js → ishikawaDiagram-5VMMS53U-CyRIu_om.js} +6 -6
  321. ksadk/server/static/assets/{journeyDiagram-JHISSGLW-8LeOJaZp.js → journeyDiagram-EYS64GPL-DN5JXHzN.js} +6 -6
  322. ksadk/server/static/assets/{kanban-definition-UN3LZRKU-C6uCgZrW.js → kanban-definition-3QL26DDD-CNP3ui66.js} +10 -10
  323. ksadk/server/static/assets/katex-DWEzQy1d.js +257 -0
  324. ksadk/server/static/assets/{linear-hdBcYzM8.js → linear-C-qHp7d2.js} +1 -1
  325. ksadk/server/static/assets/mermaid-parser.core-Cl-K943T.js +166 -0
  326. ksadk/server/static/assets/{mindmap-definition-RKZ34NQL-Bjy_2v4_.js → mindmap-definition-FBJOCRG2-D5DB5mYm.js} +29 -29
  327. ksadk/server/static/assets/packet-AYTQ26CC-C7R3NUlK.js +1 -0
  328. ksadk/server/static/assets/pegDiagram-XKGWAZYB-BQVc9ia_.js +1 -0
  329. ksadk/server/static/assets/pie-WAS4IAKB-BIT6qjr3.js +1 -0
  330. ksadk/server/static/assets/pieDiagram-E7YTZNPT-B6UCAvtY.js +39 -0
  331. ksadk/server/static/assets/{quadrantDiagram-W4KKPZXB-BmkRbwCg.js → quadrantDiagram-AXDQQJYC-mIr2d3eb.js} +6 -6
  332. ksadk/server/static/assets/radar-RG4KPBEZ-l5noef9X.js +1 -0
  333. ksadk/server/static/assets/railroad-74A4TZTK-Baea6ZvM.js +1 -0
  334. ksadk/server/static/assets/railroad-abnf-HS5TGJTU-OKn8zZnU.js +1 -0
  335. ksadk/server/static/assets/railroad-ebnf-LZEXJU2U-DdKAKC4l.js +1 -0
  336. ksadk/server/static/assets/railroad-peg-WCYAUIDC-Bds8udlG.js +1 -0
  337. ksadk/server/static/assets/railroadDiagram-O6MQD6OU-Dt3FFDmK.js +1 -0
  338. ksadk/server/static/assets/requirementDiagram-EFPCY7ZU-Cz_vQtgF.js +84 -0
  339. ksadk/server/static/assets/{sankeyDiagram-5OEKKPKP-l6iXmU65.js → sankeyDiagram-P5KCCOFB-wlO1TsH5.js} +7 -7
  340. ksadk/server/static/assets/{sequenceDiagram-3UESZ5HK-Cq6UBeQB.js → sequenceDiagram-WJ2MYXX4-CHRbElYq.js} +10 -10
  341. ksadk/server/static/assets/sizeCapture-X5ZJPWSS-DXX54iyO.js +1 -0
  342. ksadk/server/static/assets/stateDiagram-HBIQ2CUA-Dp_lw9II.js +1 -0
  343. ksadk/server/static/assets/stateDiagram-v2-4QOOHH4V-5b-8o2iS.js +1 -0
  344. ksadk/server/static/assets/swimlanes-XN3QIQJK-D8O5UlLG.js +1 -0
  345. ksadk/server/static/assets/swimlanesDiagram-VK2B7HYN-uf6WPRA4.js +8 -0
  346. ksadk/server/static/assets/{timeline-definition-PNZ67QCA-DEz24vV0.js → timeline-definition-24CTP7MA-8mfKcxvG.js} +7 -7
  347. ksadk/server/static/assets/treeView-Q6P3EWNA-CK5CSrSO.js +1 -0
  348. ksadk/server/static/assets/treemap-WGGIJYW6-Ch2BKgAM.js +1 -0
  349. ksadk/server/static/assets/vennDiagram-4TSXK5OY-EnNl0DE7.js +34 -0
  350. ksadk/server/static/assets/wardley-WFR3VGLG-YW3Q0ml_.js +1 -0
  351. ksadk/server/static/assets/wardleyDiagram-VM6X3IG4-DBu5fbYr.js +78 -0
  352. ksadk/server/static/assets/xychartDiagram-S5SC5T6Z-BSVXs4IY.js +7 -0
  353. ksadk/server/static/index.html +2 -2
  354. ksadk/sessions/__init__.py +26 -9
  355. ksadk/sessions/_local_service_sync.py +688 -0
  356. ksadk/sessions/_local_tables.py +21 -0
  357. ksadk/sessions/_postgres_schema.py +305 -0
  358. ksadk/sessions/_postgres_tables.py +15 -0
  359. ksadk/sessions/base.py +80 -1
  360. ksadk/sessions/in_memory.py +53 -2
  361. ksadk/sessions/local_service.py +63 -604
  362. ksadk/sessions/postgres_service.py +58 -148
  363. ksadk/sessions/resilient.py +35 -1
  364. ksadk/skills/service_client.py +48 -0
  365. ksadk/studio/agent_lifecycle.py +26 -20
  366. ksadk/studio/api.py +1063 -69
  367. ksadk/studio/api_catalog_routes.py +5 -0
  368. ksadk/studio/api_contracts.py +148 -6
  369. ksadk/studio/api_memory_routes.py +82 -0
  370. ksadk/studio/api_plugin_routes.py +480 -0
  371. ksadk/studio/attachment_store.py +187 -0
  372. ksadk/studio/authoring.py +259 -28
  373. ksadk/studio/authoring_coordinator.py +809 -67
  374. ksadk/studio/builder.py +197 -40
  375. ksadk/studio/capabilities.py +17 -0
  376. ksadk/studio/cloud.py +1920 -95
  377. ksadk/studio/codex_agent_service.py +137 -15
  378. ksadk/studio/codex_authoring.py +469 -0
  379. ksadk/studio/codex_builder.py +177 -25
  380. ksadk/studio/codex_manifest.py +71 -22
  381. ksadk/studio/codex_run.py +59 -4
  382. ksadk/studio/compatibility_report.py +445 -0
  383. ksadk/studio/compiler.py +7 -1
  384. ksadk/studio/contracts.py +234 -4
  385. ksadk/studio/dsh_provider_registration.py +768 -0
  386. ksadk/studio/event_store.py +79 -101
  387. ksadk/studio/framework_run.py +264 -3
  388. ksadk/studio/hosted_kernel.py +317 -0
  389. ksadk/studio/manifest_resolver.py +131 -0
  390. ksadk/studio/model_client.py +95 -9
  391. ksadk/studio/model_profile_service.py +1 -1
  392. ksadk/studio/operations.py +47 -5
  393. ksadk/studio/otel_trace.py +348 -42
  394. ksadk/studio/pcm_memory.py +85 -0
  395. ksadk/studio/plugin_composition.py +301 -0
  396. ksadk/studio/plugin_kernel_adapter.py +128 -0
  397. ksadk/studio/plugin_runtime.py +652 -0
  398. ksadk/studio/repository.py +23 -2
  399. ksadk/studio/resource_catalog.py +49 -1
  400. ksadk/studio/run_service.py +1266 -202
  401. ksadk/studio/runtime_source.py +51 -17
  402. ksadk/studio/scheduler_runtime.py +374 -0
  403. ksadk/studio/scheduler_service.py +211 -0
  404. ksadk/studio/service.py +1815 -117
  405. ksadk/studio/shared_web.py +199 -50
  406. ksadk/studio/soul.py +52 -0
  407. ksadk/studio/static/assets/index-DXs1Eq4M.css +1 -0
  408. ksadk/studio/static/assets/index-DeDqwTsD.js +283 -0
  409. ksadk/studio/static/index.html +2 -2
  410. ksadk/studio/templates.py +100 -8
  411. ksadk/studio/validator.py +20 -1
  412. ksadk/studio/workspace.py +31 -32
  413. ksadk/tracing/setup.py +304 -3
  414. ksadk/version.py +1 -1
  415. ksadk_runtime_common/schemas/runtime_event_v1.json +37 -0
  416. ksadk_runtime_common/schemas/runtime_event_v2.json +271 -0
  417. ksadk_runtime_common/workspace_files/path_utils.py +41 -0
  418. ksadk/events/parser.py +0 -191
  419. ksadk/server/static/assets/MathMessageMarkdown-DeYh8QPr.css +0 -1
  420. ksadk/server/static/assets/MermaidBlock-NERD_ef7.js +0 -303
  421. ksadk/server/static/assets/NativeTerminalPanel-CiHWf82q.js +0 -1
  422. ksadk/server/static/assets/arc-DrgjcKhl.js +0 -1
  423. ksadk/server/static/assets/architecture-7EHR7CIX-CpZLRCcY.js +0 -1
  424. ksadk/server/static/assets/architectureDiagram-3BPJPVTR-BXoVRbQ6.js +0 -36
  425. ksadk/server/static/assets/blockDiagram-GPEHLZMM-BnaB3Ywv.js +0 -132
  426. ksadk/server/static/assets/c4Diagram-AAUBKEIU-Dw4weZcp.js +0 -10
  427. ksadk/server/static/assets/channel-Dt3rQTFI.js +0 -1
  428. ksadk/server/static/assets/chunk-2J33WTMH-ChjpLK7j.js +0 -1
  429. ksadk/server/static/assets/chunk-55IACEB6-CK4ROATy.js +0 -1
  430. ksadk/server/static/assets/chunk-727SXJPM-B9KtTTgw.js +0 -206
  431. ksadk/server/static/assets/chunk-AQP2D5EJ-1O1mki3m.js +0 -231
  432. ksadk/server/static/assets/chunk-QZHKN3VN-iXEZtKQc.js +0 -1
  433. ksadk/server/static/assets/classDiagram-4FO5ZUOK-DIveV17Q.js +0 -1
  434. ksadk/server/static/assets/classDiagram-v2-Q7XG4LA2-DIveV17Q.js +0 -1
  435. ksadk/server/static/assets/cytoscape.esm-DelgaX4f.js +0 -321
  436. ksadk/server/static/assets/dagre-BM42HDAG-D0QXg_MQ.js +0 -4
  437. ksadk/server/static/assets/dagre-Bx709z4p.js +0 -1
  438. ksadk/server/static/assets/diagram-2AECGRRQ-DBDDKwBQ.js +0 -43
  439. ksadk/server/static/assets/diagram-5GNKFQAL-BkwDOxmO.js +0 -10
  440. ksadk/server/static/assets/diagram-KO2AKTUF-Bv8waYvY.js +0 -3
  441. ksadk/server/static/assets/diagram-LMA3HP47-e1VECDdu.js +0 -24
  442. ksadk/server/static/assets/diagram-OG6HWLK6-Ds9adfRl.js +0 -24
  443. ksadk/server/static/assets/dist-B5J2uhNk.js +0 -1
  444. ksadk/server/static/assets/erDiagram-TEJ5UH35-BPItFKH6.js +0 -85
  445. ksadk/server/static/assets/eventmodeling-FCH6USID-DYFSxbqr.js +0 -1
  446. ksadk/server/static/assets/flowDiagram-I6XJVG4X-BbYB9w5Y.js +0 -162
  447. ksadk/server/static/assets/ganttDiagram-6RSMTGT7-TQXa0KXv.js +0 -292
  448. ksadk/server/static/assets/gitGraph-WXDBUCRP-DyNYp6BN.js +0 -1
  449. ksadk/server/static/assets/gitGraphDiagram-PVQCEYII-bKblCnpa.js +0 -106
  450. ksadk/server/static/assets/graphlib-B8gBHxth.js +0 -1
  451. ksadk/server/static/assets/index-R52pJJvg.js +0 -177
  452. ksadk/server/static/assets/index-jJr3_955.css +0 -2
  453. ksadk/server/static/assets/info-J43DQDTF-WUx7qTde.js +0 -1
  454. ksadk/server/static/assets/infoDiagram-5YYISTIA-BGVT7J_i.js +0 -2
  455. ksadk/server/static/assets/katex-CYWseY5E.js +0 -265
  456. ksadk/server/static/assets/mermaid-parser.core-BWrDjSZM.js +0 -161
  457. ksadk/server/static/assets/packet-YPE3B663-BN13y_xl.js +0 -1
  458. ksadk/server/static/assets/pie-LRSECV5Y-ftSLXhhc.js +0 -1
  459. ksadk/server/static/assets/pieDiagram-4H26LBE5-GmmqNiVH.js +0 -30
  460. ksadk/server/static/assets/radar-GUYGQ44K-jaICkIeO.js +0 -1
  461. ksadk/server/static/assets/requirementDiagram-4Y6WPE33-DSWFqL7c.js +0 -84
  462. ksadk/server/static/assets/stateDiagram-AJRCARHV-qzTQpg3Y.js +0 -1
  463. ksadk/server/static/assets/stateDiagram-v2-BHNVJYJU-BYCoYGAN.js +0 -1
  464. ksadk/server/static/assets/treeView-BLDUP644-Cpib_vlz.js +0 -1
  465. ksadk/server/static/assets/treemap-LRROVOQU-DQxfmVHK.js +0 -1
  466. ksadk/server/static/assets/vennDiagram-CIIHVFJN-CMCixki2.js +0 -34
  467. ksadk/server/static/assets/wardley-L42UT6IY-BQYHnnkU.js +0 -1
  468. ksadk/server/static/assets/wardleyDiagram-YWT4CUSO-CVzB8F9K.js +0 -78
  469. ksadk/server/static/assets/xychartDiagram-2RQKCTM6-BFBqBLc1.js +0 -7
  470. ksadk/studio/evaluation.py +0 -192
  471. ksadk/studio/static/assets/index-CaEN0eTR.css +0 -1
  472. ksadk/studio/static/assets/index-DI2eY_NH.js +0 -252
  473. {agentengine_sdk_python-0.8.1.dist-info → agentengine_sdk_python-0.8.3.dist-info}/WHEEL +0 -0
  474. {agentengine_sdk_python-0.8.1.dist-info → agentengine_sdk_python-0.8.3.dist-info}/entry_points.txt +0 -0
  475. {agentengine_sdk_python-0.8.1.dist-info → agentengine_sdk_python-0.8.3.dist-info}/licenses/LICENSE +0 -0
  476. {agentengine_sdk_python-0.8.1.dist-info → agentengine_sdk_python-0.8.3.dist-info}/top_level.txt +0 -0
@@ -0,0 +1,333 @@
1
+ """Frozen SubagentProvider/v1 seam with explicit lineage and policy bounds.
2
+
3
+ The Kernel does not know whether a child is implemented by Codex, DSH,
4
+ Claude, another KsADK AgentProvider, or a remote service. It only routes a
5
+ bounded request to a named provider and retains the returned child identity.
6
+ Provider-private state and event logs remain with that provider; projected
7
+ child events keep their own ids and sequence numbers.
8
+ """
9
+
10
+ from __future__ import annotations
11
+
12
+ from collections.abc import AsyncIterator, Mapping, Sequence
13
+ from datetime import datetime
14
+ from typing import Any, Literal, Protocol, cast, runtime_checkable
15
+
16
+ from pydantic import Field, field_validator, model_validator
17
+
18
+ from ksadk.plugins.contracts import PluginContractModel, PluginReference
19
+
20
+
21
+ class SubagentPolicy(PluginContractModel):
22
+ """Parent-owned limits that a child provider may only narrow."""
23
+
24
+ max_depth: int = Field(default=1, ge=1, le=16)
25
+ timeout_seconds: int = Field(default=120, ge=1, le=86_400)
26
+ max_steps: int = Field(default=12, ge=1, le=10_000)
27
+ background: bool = False
28
+ allowed_tools: tuple[str, ...] = ()
29
+ allowed_permissions: tuple[str, ...] = ()
30
+
31
+ @field_validator("allowed_tools", "allowed_permissions")
32
+ @classmethod
33
+ def validate_unique_values(cls, value: tuple[str, ...]) -> tuple[str, ...]:
34
+ if any(not item.strip() for item in value):
35
+ raise ValueError("subagent policy entries must be non-empty")
36
+ if len(value) != len(set(value)):
37
+ raise ValueError("subagent policy entries must be unique")
38
+ return tuple(sorted(value))
39
+
40
+
41
+ class SpawnSubagentRequest(PluginContractModel):
42
+ """One bounded child task requested by an authenticated parent Run."""
43
+
44
+ request_format: Literal["ksadk.subagent-spawn/v1"] = "ksadk.subagent-spawn/v1"
45
+ provider_ref: str
46
+ parent_session_id: str = Field(min_length=1, max_length=256)
47
+ parent_run_id: str = Field(min_length=1, max_length=256)
48
+ task: str = Field(min_length=1, max_length=131_072)
49
+ depth: int = Field(default=1, ge=1, le=16)
50
+ policy: SubagentPolicy = Field(default_factory=SubagentPolicy)
51
+ metadata: dict[str, Any] = Field(default_factory=dict)
52
+
53
+ @field_validator("provider_ref")
54
+ @classmethod
55
+ def validate_provider_ref(cls, value: str) -> str:
56
+ return cast(str, PluginReference(ref=value).ref)
57
+
58
+ @field_validator("metadata")
59
+ @classmethod
60
+ def validate_metadata(cls, value: dict[str, Any]) -> dict[str, Any]:
61
+ _reject_secret_values(value)
62
+ return value
63
+
64
+ @model_validator(mode="after")
65
+ def validate_depth(self) -> "SpawnSubagentRequest":
66
+ if self.depth > self.policy.max_depth:
67
+ raise ValueError("subagent depth exceeds the parent policy maxDepth")
68
+ return self
69
+
70
+
71
+ class ChildHandle(PluginContractModel):
72
+ """Stable lineage and recovery descriptor for one provider-owned child."""
73
+
74
+ handle_format: Literal["ksadk.child-handle/v1"] = "ksadk.child-handle/v1"
75
+ handle_id: str = Field(min_length=1, max_length=256)
76
+ provider_ref: str
77
+ parent_session_id: str = Field(min_length=1, max_length=256)
78
+ parent_run_id: str = Field(min_length=1, max_length=256)
79
+ child_session_id: str | None = Field(default=None, max_length=256)
80
+ child_run_id: str | None = Field(default=None, max_length=256)
81
+ depth: int = Field(ge=1, le=16)
82
+ capabilities: tuple[str, ...] = ()
83
+ capability_digest: str = Field(pattern=r"^sha256:[0-9a-f]{64}$")
84
+ created_at: datetime
85
+ resumable: bool = False
86
+ resume_descriptor: dict[str, Any] | None = None
87
+
88
+ @field_validator("provider_ref")
89
+ @classmethod
90
+ def validate_provider_ref(cls, value: str) -> str:
91
+ return cast(str, PluginReference(ref=value).ref)
92
+
93
+ @field_validator("capabilities")
94
+ @classmethod
95
+ def validate_capabilities(cls, value: tuple[str, ...]) -> tuple[str, ...]:
96
+ if any(not item.strip() for item in value):
97
+ raise ValueError("child capabilities must be non-empty")
98
+ if len(value) != len(set(value)):
99
+ raise ValueError("child capabilities must be unique")
100
+ return tuple(sorted(value))
101
+
102
+ @field_validator("created_at")
103
+ @classmethod
104
+ def validate_created_at(cls, value: datetime) -> datetime:
105
+ if value.tzinfo is None or value.utcoffset() is None:
106
+ raise ValueError("child handle createdAt must include a timezone")
107
+ return value
108
+
109
+ @field_validator("resume_descriptor")
110
+ @classmethod
111
+ def validate_resume_descriptor(
112
+ cls, value: dict[str, Any] | None
113
+ ) -> dict[str, Any] | None:
114
+ if value is not None:
115
+ _reject_secret_values(value)
116
+ return value
117
+
118
+ @model_validator(mode="after")
119
+ def validate_recovery_shape(self) -> "ChildHandle":
120
+ if self.resumable and not self.resume_descriptor:
121
+ raise ValueError("resumable child handle requires a resumeDescriptor")
122
+ if not self.resumable and self.resume_descriptor is not None:
123
+ raise ValueError("non-resumable child handle cannot carry a resumeDescriptor")
124
+ return self
125
+
126
+
127
+ class SubagentStatus(PluginContractModel):
128
+ status_format: Literal["ksadk.subagent-status/v1"] = "ksadk.subagent-status/v1"
129
+ handle_id: str = Field(min_length=1, max_length=256)
130
+ state: Literal[
131
+ "accepted",
132
+ "running",
133
+ "waiting_input",
134
+ "succeeded",
135
+ "failed",
136
+ "cancelled",
137
+ "interrupted",
138
+ "disposed",
139
+ ]
140
+ last_seq: int = Field(default=0, ge=0)
141
+ updated_at: datetime
142
+ reason: str | None = Field(default=None, max_length=2048)
143
+
144
+ @field_validator("updated_at")
145
+ @classmethod
146
+ def validate_updated_at(cls, value: datetime) -> datetime:
147
+ if value.tzinfo is None or value.utcoffset() is None:
148
+ raise ValueError("subagent status updatedAt must include a timezone")
149
+ return value
150
+
151
+
152
+ class SubagentEvent(PluginContractModel):
153
+ """Identity-preserving child event; parent projection must not merge by text."""
154
+
155
+ event_format: Literal["ksadk.subagent-event/v1"] = "ksadk.subagent-event/v1"
156
+ handle_id: str = Field(min_length=1, max_length=256)
157
+ event_id: str = Field(min_length=1, max_length=256)
158
+ seq: int = Field(ge=1)
159
+ kind: Literal["progress", "item", "interaction", "terminal"]
160
+ payload: dict[str, Any] = Field(default_factory=dict)
161
+ native_ref: dict[str, str] = Field(default_factory=dict)
162
+
163
+ @field_validator("payload")
164
+ @classmethod
165
+ def validate_payload(cls, value: dict[str, Any]) -> dict[str, Any]:
166
+ _reject_secret_values(value)
167
+ return value
168
+
169
+
170
+ class SubagentResult(PluginContractModel):
171
+ result_format: Literal["ksadk.subagent-result/v1"] = "ksadk.subagent-result/v1"
172
+ handle_id: str = Field(min_length=1, max_length=256)
173
+ state: Literal["succeeded", "failed", "cancelled", "interrupted"]
174
+ output: Any = None
175
+ output_refs: tuple[str, ...] = ()
176
+ error_code: str | None = Field(default=None, max_length=256)
177
+ error_message: str | None = Field(default=None, max_length=2048)
178
+
179
+ @field_validator("output_refs")
180
+ @classmethod
181
+ def validate_output_refs(cls, value: tuple[str, ...]) -> tuple[str, ...]:
182
+ if any(not item.strip() for item in value):
183
+ raise ValueError("subagent output references must be non-empty")
184
+ if len(value) != len(set(value)):
185
+ raise ValueError("subagent output references must be unique")
186
+ return tuple(sorted(value))
187
+
188
+ @model_validator(mode="after")
189
+ def validate_terminal_shape(self) -> "SubagentResult":
190
+ if self.state == "succeeded" and (self.error_code or self.error_message):
191
+ raise ValueError("successful subagent result cannot carry an error")
192
+ if self.state == "failed" and not self.error_code:
193
+ raise ValueError("failed subagent result requires errorCode")
194
+ return self
195
+
196
+
197
+ @runtime_checkable
198
+ class SubagentProvider(Protocol):
199
+ """Named child execution provider; every method is provider-owned."""
200
+
201
+ async def describe(self) -> Mapping[str, Any]: ...
202
+
203
+ async def available(self) -> bool: ...
204
+
205
+ async def spawn(self, request: SpawnSubagentRequest) -> ChildHandle: ...
206
+
207
+ async def followup(self, handle: ChildHandle, input: Any) -> None: ...
208
+
209
+ async def status(self, handle: ChildHandle) -> SubagentStatus: ...
210
+
211
+ async def interrupt(self, handle: ChildHandle) -> None: ...
212
+
213
+ async def cancel(self, handle: ChildHandle) -> None: ...
214
+
215
+ def subscribe(
216
+ self, handle: ChildHandle, *, after_seq: int = 0
217
+ ) -> AsyncIterator[SubagentEvent]: ...
218
+
219
+ async def result(self, handle: ChildHandle) -> SubagentResult: ...
220
+
221
+ async def dispose(self, handle: ChildHandle) -> None: ...
222
+
223
+
224
+ class SubagentProviderError(RuntimeError):
225
+ """Stable typed failure at the provider routing boundary."""
226
+
227
+ def __init__(self, code: str, message: str) -> None:
228
+ super().__init__(message)
229
+ self.code = code
230
+
231
+
232
+ class SubagentProviderRouter:
233
+ """Route child handles to exact providers without interpreting their state."""
234
+
235
+ def __init__(self, providers: Mapping[str, SubagentProvider]) -> None:
236
+ self._providers = dict(providers)
237
+
238
+ async def spawn(self, request: SpawnSubagentRequest) -> ChildHandle:
239
+ provider = self._provider(request.provider_ref)
240
+ if not await provider.available():
241
+ raise SubagentProviderError(
242
+ "subagent_provider_unavailable",
243
+ f"SubagentProvider {request.provider_ref} is unavailable",
244
+ )
245
+ handle = await provider.spawn(request)
246
+ self._validate_handle(request, handle)
247
+ return handle
248
+
249
+ async def status(self, handle: ChildHandle) -> SubagentStatus:
250
+ return await self._provider_for_handle(handle).status(handle)
251
+
252
+ async def followup(self, handle: ChildHandle, input: Any) -> None:
253
+ await self._provider_for_handle(handle).followup(handle, input)
254
+
255
+ async def interrupt(self, handle: ChildHandle) -> None:
256
+ await self._provider_for_handle(handle).interrupt(handle)
257
+
258
+ async def cancel(self, handle: ChildHandle) -> None:
259
+ await self._provider_for_handle(handle).cancel(handle)
260
+
261
+ def subscribe(
262
+ self, handle: ChildHandle, *, after_seq: int = 0
263
+ ) -> AsyncIterator[SubagentEvent]:
264
+ if after_seq < 0:
265
+ raise SubagentProviderError(
266
+ "subagent_cursor_invalid", "subagent after_seq cannot be negative"
267
+ )
268
+ return self._provider_for_handle(handle).subscribe(handle, after_seq=after_seq)
269
+
270
+ async def result(self, handle: ChildHandle) -> SubagentResult:
271
+ return await self._provider_for_handle(handle).result(handle)
272
+
273
+ async def dispose(self, handle: ChildHandle) -> None:
274
+ await self._provider_for_handle(handle).dispose(handle)
275
+
276
+ def _provider_for_handle(self, handle: ChildHandle) -> SubagentProvider:
277
+ return self._provider(handle.provider_ref)
278
+
279
+ def _provider(self, provider_ref: str) -> SubagentProvider:
280
+ provider = self._providers.get(provider_ref)
281
+ if provider is None:
282
+ raise SubagentProviderError(
283
+ "subagent_provider_not_found",
284
+ f"SubagentProvider {provider_ref} is not registered",
285
+ )
286
+ return provider
287
+
288
+ @staticmethod
289
+ def _validate_handle(
290
+ request: SpawnSubagentRequest,
291
+ handle: ChildHandle,
292
+ ) -> None:
293
+ if (
294
+ handle.provider_ref != request.provider_ref
295
+ or handle.parent_session_id != request.parent_session_id
296
+ or handle.parent_run_id != request.parent_run_id
297
+ or handle.depth != request.depth
298
+ ):
299
+ raise SubagentProviderError(
300
+ "subagent_handle_mismatch",
301
+ "SubagentProvider returned a child handle outside the requested lineage",
302
+ )
303
+
304
+
305
+ _SECRET_KEY_PARTS = ("secret", "password", "token", "apikey", "api_key")
306
+ _SECRET_REF_PREFIXES = ("secret://", "env://", "credential://", "vault://")
307
+
308
+
309
+ def _reject_secret_values(value: Any, *, path: str = "payload") -> None:
310
+ if isinstance(value, Mapping):
311
+ for key, child in value.items():
312
+ key_text = str(key)
313
+ normalized = key_text.replace("-", "").lower()
314
+ if any(part in normalized for part in _SECRET_KEY_PARTS) and child is not None:
315
+ if not isinstance(child, str) or not child.startswith(_SECRET_REF_PREFIXES):
316
+ raise ValueError(f"{path}.{key_text} must contain a secret reference")
317
+ _reject_secret_values(child, path=f"{path}.{key_text}")
318
+ elif isinstance(value, Sequence) and not isinstance(value, (str, bytes, bytearray)):
319
+ for index, child in enumerate(value):
320
+ _reject_secret_values(child, path=f"{path}[{index}]")
321
+
322
+
323
+ __all__ = [
324
+ "ChildHandle",
325
+ "SpawnSubagentRequest",
326
+ "SubagentEvent",
327
+ "SubagentPolicy",
328
+ "SubagentProvider",
329
+ "SubagentProviderError",
330
+ "SubagentProviderRouter",
331
+ "SubagentResult",
332
+ "SubagentStatus",
333
+ ]
@@ -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)