agentengine-sdk-python 0.8.0__py3-none-any.whl → 0.8.2__py3-none-any.whl

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (494) hide show
  1. {agentengine_sdk_python-0.8.0.dist-info → agentengine_sdk_python-0.8.2.dist-info}/METADATA +43 -7
  2. agentengine_sdk_python-0.8.2.dist-info/RECORD +778 -0
  3. {agentengine_sdk_python-0.8.0.dist-info → agentengine_sdk_python-0.8.2.dist-info}/WHEEL +1 -1
  4. ksadk/a2a/__init__.py +2 -0
  5. ksadk/a2a/_space_client_events.py +381 -0
  6. ksadk/a2a/bootstrap.py +0 -2
  7. ksadk/a2a/card.py +6 -111
  8. ksadk/a2a/control_plane.py +239 -1
  9. ksadk/a2a/event_adapter.py +156 -64
  10. ksadk/a2a/executor.py +195 -172
  11. ksadk/a2a/routes.py +12 -5
  12. ksadk/a2a/server.py +1 -8
  13. ksadk/a2a/service_env.py +33 -0
  14. ksadk/a2a/space_client.py +43 -349
  15. ksadk/a2a_card.py +101 -0
  16. ksadk/a2ui/core.py +222 -53
  17. ksadk/agui/_agent_helpers.py +243 -0
  18. ksadk/agui/a2ui_projection.py +12 -5
  19. ksadk/agui/agent.py +474 -275
  20. ksadk/agui/config.py +11 -5
  21. ksadk/agui/routes.py +7 -15
  22. ksadk/api/client.py +530 -40
  23. ksadk/api/environment.py +27 -0
  24. ksadk/builders/code_builder.py +352 -53
  25. ksadk/builders/container_builder.py +71 -44
  26. ksadk/builders/framework_requirements.py +2 -1
  27. ksadk/builders/ks3_uploader.py +2 -2
  28. ksadk/builders/managed_runtime_builder.py +60 -28
  29. ksadk/cli/__init__.py +25 -0
  30. ksadk/cli/cmd_a2a.py +18 -31
  31. ksadk/cli/cmd_create.py +13 -26
  32. ksadk/cli/cmd_dashboard.py +15 -1
  33. ksadk/cli/cmd_deploy.py +28 -3
  34. ksadk/cli/cmd_eval.py +443 -0
  35. ksadk/cli/cmd_evalset.py +284 -0
  36. ksadk/cli/cmd_files.py +5 -1
  37. ksadk/cli/cmd_hermes.py +137 -163
  38. ksadk/cli/cmd_invoke.py +28 -38
  39. ksadk/cli/cmd_launch.py +12 -0
  40. ksadk/cli/cmd_managed_runtime.py +95 -0
  41. ksadk/cli/cmd_observe.py +85 -0
  42. ksadk/cli/cmd_openclaw.py +85 -479
  43. ksadk/cli/cmd_replay.py +28 -4
  44. ksadk/cli/cmd_run.py +29 -67
  45. ksadk/cli/cmd_studio.py +201 -0
  46. ksadk/cli/cmd_web.py +15 -6
  47. ksadk/cli/dry_run.py +2 -1
  48. ksadk/cli/env_options.py +83 -0
  49. ksadk/cli/global_options.py +3 -1
  50. ksadk/cli/hermes_env.py +151 -0
  51. ksadk/cli/invoke_payload.py +49 -0
  52. ksadk/cli/network_options.py +7 -5
  53. ksadk/cli/openclaw_env.py +458 -0
  54. ksadk/cli/runtime_bootstrap.py +51 -0
  55. ksadk/cli/ui.py +6 -0
  56. ksadk/cli/workflow_common.py +5 -5
  57. ksadk/codex/__init__.py +3 -3
  58. ksadk/codex/client.py +833 -49
  59. ksadk/codex/phase.py +1 -1
  60. ksadk/codex/runtime.py +720 -127
  61. ksadk/common/kop_client.py +232 -0
  62. ksadk/configs/__init__.py +1 -3
  63. ksadk/configs/env_registry.py +244 -45
  64. ksadk/configs/env_registry_pcm.py +181 -0
  65. ksadk/configs/env_var_spec.py +18 -0
  66. ksadk/configs/global_config.py +6 -1
  67. ksadk/configs/settings.py +5 -108
  68. ksadk/context_engine/__init__.py +98 -0
  69. ksadk/context_engine/assembler.py +176 -0
  70. ksadk/context_engine/baseline.py +419 -0
  71. ksadk/context_engine/cache_observability.py +228 -0
  72. ksadk/context_engine/capabilities.py +443 -0
  73. ksadk/context_engine/contributors.py +344 -0
  74. ksadk/context_engine/hosted_pipeline.py +417 -0
  75. ksadk/context_engine/models.py +117 -0
  76. ksadk/context_engine/planner.py +698 -0
  77. ksadk/context_engine/policies.py +319 -0
  78. ksadk/context_engine/projection.py +31 -0
  79. ksadk/context_engine/shadow_plan.py +266 -0
  80. ksadk/context_engine/tokenizer.py +164 -0
  81. ksadk/conversations/__init__.py +85 -94
  82. ksadk/conversations/context.py +126 -6
  83. ksadk/conversations/message_projection.py +292 -28
  84. ksadk/conversations/model_context.py +49 -3
  85. ksadk/conversations/runtime_compaction.py +207 -5
  86. ksadk/conversations/runtime_input.py +193 -3
  87. ksadk/conversations/runtime_invocation.py +81 -3
  88. ksadk/conversations/runtime_observability.py +157 -4
  89. ksadk/conversations/runtime_payloads.py +42 -0
  90. ksadk/conversations/runtime_preparation.py +280 -2
  91. ksadk/conversations/runtime_resume.py +71 -32
  92. ksadk/conversations/runtime_stream_events.py +94 -9
  93. ksadk/conversations/runtime_streaming.py +175 -22
  94. ksadk/conversations/semantic_summary.py +311 -1
  95. ksadk/conversations/session_lock.py +51 -0
  96. ksadk/deployment/env_forward.py +72 -0
  97. ksadk/deployment/managed_runtime.py +38 -0
  98. ksadk/deployment/manager.py +24 -8
  99. ksadk/deployment/providers/serverless.py +228 -92
  100. ksadk/evaluation/__init__.py +116 -0
  101. ksadk/evaluation/a2a_adapter.py +452 -0
  102. ksadk/evaluation/adapters.py +67 -0
  103. ksadk/evaluation/agent_eval_client.py +395 -0
  104. ksadk/evaluation/cloud_binding.py +80 -0
  105. ksadk/evaluation/cloud_converter.py +194 -0
  106. ksadk/evaluation/cloud_service.py +199 -0
  107. ksadk/evaluation/contracts.py +478 -0
  108. ksadk/evaluation/evalset.py +351 -0
  109. ksadk/evaluation/evaluators.py +627 -0
  110. ksadk/evaluation/evidence.py +258 -0
  111. ksadk/evaluation/executor.py +143 -0
  112. ksadk/evaluation/local_adapter.py +550 -0
  113. ksadk/evaluation/service_env.py +27 -0
  114. ksadk/evaluation/storage.py +68 -0
  115. ksadk/evaluation/studio_build_adapter.py +253 -0
  116. ksadk/evaluation/target.py +82 -0
  117. ksadk/events/__init__.py +13 -13
  118. ksadk/events/_v1_compat/__init__.py +1 -0
  119. ksadk/events/_v1_compat/models.py +299 -0
  120. ksadk/events/_v1_compat/parser.py +247 -0
  121. ksadk/events/_v1_compat/projection.py +753 -0
  122. ksadk/events/adapters/__init__.py +34 -0
  123. ksadk/events/adapters/_a2a_snapshot.py +622 -0
  124. ksadk/events/adapters/_a2a_support.py +275 -0
  125. ksadk/events/adapters/_codex_interactions.py +375 -0
  126. ksadk/events/adapters/_codex_items.py +801 -0
  127. ksadk/events/adapters/_codex_validators.py +311 -0
  128. ksadk/events/adapters/_langgraph_support.py +785 -0
  129. ksadk/events/adapters/a2a.py +841 -0
  130. ksadk/events/adapters/adk.py +503 -0
  131. ksadk/events/adapters/codex.py +717 -0
  132. ksadk/events/adapters/langgraph.py +745 -0
  133. ksadk/events/canonical.py +440 -0
  134. ksadk/events/canonical_replay.py +497 -0
  135. ksadk/events/canonical_store.py +468 -0
  136. ksadk/events/cold_recovery.py +257 -0
  137. ksadk/events/content.py +89 -0
  138. ksadk/events/identity.py +86 -0
  139. ksadk/events/pipeline.py +455 -0
  140. ksadk/events/projections.py +66 -0
  141. ksadk/events/reducer.py +661 -0
  142. ksadk/events/replay.py +3 -36
  143. ksadk/events/runtime_event.py +20 -256
  144. ksadk/events/session_event.py +324 -0
  145. ksadk/events/store.py +3 -316
  146. ksadk/events/v1_compat.py +41 -0
  147. ksadk/harness/__init__.py +3 -2
  148. ksadk/harness/app.py +114 -123
  149. ksadk/harness/config.py +1 -1
  150. ksadk/harness/runtime.py +467 -0
  151. ksadk/hermes_terminal.py +5 -0
  152. ksadk/identity/resolver.py +4 -3
  153. ksadk/interaction/__init__.py +28 -0
  154. ksadk/interaction/contracts.py +136 -0
  155. ksadk/interaction/ledger.py +189 -0
  156. ksadk/interaction/provider.py +122 -0
  157. ksadk/interaction/providers/__init__.py +52 -0
  158. ksadk/interaction/providers/adk.py +40 -0
  159. ksadk/interaction/providers/codex.py +94 -0
  160. ksadk/interaction/providers/langgraph.py +58 -0
  161. ksadk/kernel/__init__.py +117 -0
  162. ksadk/kernel/authorization.py +258 -0
  163. ksadk/kernel/bootstrap.py +1074 -0
  164. ksadk/kernel/contract_fingerprints.py +61 -0
  165. ksadk/kernel/contracts.py +362 -0
  166. ksadk/kernel/control.py +219 -0
  167. ksadk/kernel/errors.py +79 -0
  168. ksadk/kernel/ingress.py +1102 -0
  169. ksadk/kernel/mapping.py +111 -0
  170. ksadk/kernel/memory_store.py +1133 -0
  171. ksadk/kernel/postgres_store.py +1756 -0
  172. ksadk/kernel/recovery.py +452 -0
  173. ksadk/kernel/runtime_identity.py +103 -0
  174. ksadk/kernel/sql/001_agent_kernel.sql +120 -0
  175. ksadk/kernel/sqlite_store.py +1410 -0
  176. ksadk/kernel/state.py +145 -0
  177. ksadk/kernel/store.py +232 -0
  178. ksadk/kernel/worker.py +953 -0
  179. ksadk/knowledge_base/client.py +22 -4
  180. ksadk/knowledge_base/service.py +32 -5
  181. ksadk/managed_a2a_card.py +160 -0
  182. ksadk/managed_runtime.py +16 -9
  183. ksadk/memory/__init__.py +61 -0
  184. ksadk/memory/adk/backends/base_ltm_backend.py +96 -1
  185. ksadk/memory/adk/backends/http_ltm_backend.py +14 -5
  186. ksadk/memory/adk/backends/inmemory_ltm_backend.py +136 -3
  187. ksadk/memory/adk/backends/sdk_ltm_backend.py +394 -5
  188. ksadk/memory/adk/backends/sqlite_ltm_backend.py +95 -0
  189. ksadk/memory/adk/long_term_memory.py +3 -2
  190. ksadk/memory/coordinator.py +461 -0
  191. ksadk/memory/events.py +202 -0
  192. ksadk/memory/extraction.py +228 -0
  193. ksadk/memory/ltm_backend_factory.py +16 -3
  194. ksadk/memory/models.py +316 -0
  195. ksadk/memory/policy.py +215 -0
  196. ksadk/memory/provider.py +47 -0
  197. ksadk/memory/provider_adapter.py +159 -0
  198. ksadk/memory/provider_resolver.py +71 -0
  199. ksadk/memory/providers/__init__.py +5 -0
  200. ksadk/memory/providers/local_sqlite.py +490 -0
  201. ksadk/memory/resolved_policy.py +145 -0
  202. ksadk/memory/service.py +198 -8
  203. ksadk/memory/tool.py +4 -0
  204. ksadk/model_proxy/bootstrap.py +16 -9
  205. ksadk/model_proxy/config.py +22 -1
  206. ksadk/model_proxy/detect.py +202 -9
  207. ksadk/model_proxy/namespace.py +67 -15
  208. ksadk/model_proxy/server.py +168 -6
  209. ksadk/model_proxy/transform.py +105 -3
  210. ksadk/observability/__init__.py +25 -0
  211. ksadk/observability/session_log.py +420 -0
  212. ksadk/observability/trajectory.py +105 -0
  213. ksadk/prompts/__init__.py +71 -0
  214. ksadk/prompts/compiler.py +215 -0
  215. ksadk/prompts/models.py +82 -0
  216. ksadk/prompts/projection.py +89 -0
  217. ksadk/prompts/resolved.py +137 -0
  218. ksadk/prompts/sources.py +233 -0
  219. ksadk/runners/_langgraph_runner_streams.py +822 -0
  220. ksadk/runners/adk_runner.py +14 -31
  221. ksadk/runners/base_runner.py +44 -3
  222. ksadk/runners/factory.py +3 -3
  223. ksadk/runners/langgraph_runner.py +252 -433
  224. ksadk/runners/utils/__init__.py +0 -10
  225. ksadk/runners/utils/loader.py +16 -0
  226. ksadk/runtime/__init__.py +67 -41
  227. ksadk/runtime/_runner_adapter/__init__.py +1 -0
  228. ksadk/runtime/_runner_adapter/stream_mapping.py +788 -0
  229. ksadk/runtime/adapter.py +199 -16
  230. ksadk/runtime/conversation_execution.py +687 -0
  231. ksadk/runtime/executor.py +392 -0
  232. ksadk/runtime/factory.py +342 -0
  233. ksadk/runtime/framework_adapters.py +6 -12
  234. ksadk/runtime/hosted_finalizer.py +268 -0
  235. ksadk/runtime/launch.py +61 -0
  236. ksadk/runtime/preprocessing.py +49 -14
  237. ksadk/runtime/runner_adapter.py +330 -391
  238. ksadk/runtime/runner_loading.py +36 -0
  239. ksadk/runtime/usage.py +33 -0
  240. ksadk/sandbox/backends/e2b.py +36 -3
  241. ksadk/server/__init__.py +39 -4
  242. ksadk/server/app.py +18 -492
  243. ksadk/server/composition.py +36 -2
  244. ksadk/server/factory.py +210 -149
  245. ksadk/server/routes/common.py +15 -46
  246. ksadk/server/routes/control.py +13 -9
  247. ksadk/server/routes/kernel_ingress.py +258 -0
  248. ksadk/server/routes/misc.py +10 -33
  249. ksadk/server/routes/models.py +14 -6
  250. ksadk/server/routes/openai_compat.py +129 -27
  251. ksadk/server/routes/projection.py +84 -16
  252. ksadk/server/routes/run.py +347 -460
  253. ksadk/server/routes/sessions.py +37 -40
  254. ksadk/server/routes/streaming.py +52 -7
  255. ksadk/server/routes/workspace.py +54 -21
  256. ksadk/server/static/assets/{ArtifactsPanel-Cjnqt-8W.js → ArtifactsPanel-DSU1sWD_.js} +1 -1
  257. ksadk/server/static/assets/{CodeBlock-BqyqZfuB.js → CodeBlock-DOH6MVcn.js} +4 -4
  258. ksadk/server/static/assets/{MathMessageMarkdown-BpH7jiFM.js → MathMessageMarkdown-BL8my1R2.js} +4 -4
  259. ksadk/server/static/assets/MathMessageMarkdown-BorAY7qD.css +1 -0
  260. ksadk/server/static/assets/MermaidBlock-Dz4IP-Tx.js +312 -0
  261. ksadk/server/static/assets/NativeTerminalPanel-DUrK0JpZ.js +1 -0
  262. ksadk/server/static/assets/abnfDiagram-VCTEODGH-g20pFzNV.js +1 -0
  263. ksadk/server/static/assets/arc-C4FzinUA.js +1 -0
  264. ksadk/server/static/assets/architecture-7GRP2DOG-DjKratdf.js +1 -0
  265. ksadk/server/static/assets/architectureDiagram-5GKGNRK7-DpIqL5h4.js +36 -0
  266. ksadk/server/static/assets/blockDiagram-NRAW4CY4-BjkljTNz.js +129 -0
  267. ksadk/server/static/assets/c4Diagram-UCG6FXSJ-Dk_ieq2X.js +38 -0
  268. ksadk/server/static/assets/channel-4cQHKtx1.js +1 -0
  269. ksadk/server/static/assets/chunk-2Q5K7J3B-DmgWkESh.js +1 -0
  270. ksadk/server/static/assets/{chunk-FMBD7UC4-BGhvzDYt.js → chunk-5VM5RSS4-BVHAchFb.js} +1 -1
  271. ksadk/server/static/assets/{chunk-ND2GUHAM-D98vPd-E.js → chunk-F27PBJKO-C-ipQzuS.js} +1 -1
  272. ksadk/server/static/assets/chunk-G27WJ6UU-C2EyJbIK.js +231 -0
  273. ksadk/server/static/assets/{chunk-4BX2VUAB-CsWIQRhc.js → chunk-JWPE2WC7-vYvVJb_M.js} +1 -1
  274. ksadk/server/static/assets/chunk-LCL6LL3I-BcI6ysPT.js +206 -0
  275. ksadk/server/static/assets/chunk-POPQ4Y6H-C030x_Z1.js +1 -0
  276. ksadk/server/static/assets/chunk-RHFEMEQ7-yyGpsz4n.js +168 -0
  277. ksadk/server/static/assets/chunk-SVP7TREG-BLTlmMU7.js +88 -0
  278. ksadk/server/static/assets/chunk-XXDRQBXY-C_32ArgP.js +1 -0
  279. ksadk/server/static/assets/classDiagram-DTDB5LWJ-DLFd9Xi0.js +1 -0
  280. ksadk/server/static/assets/classDiagram-v2-JRS7N3AN-DLFd9Xi0.js +1 -0
  281. ksadk/server/static/assets/{cose-bilkent-S5V4N54A-CX3yotHq.js → cose-bilkent-JH36ORCC-9YQYwdl0.js} +1 -1
  282. ksadk/server/static/assets/cynefin-OW5HDTMX-DjEM48Qp.js +1 -0
  283. ksadk/server/static/assets/cynefinDiagram-5FMLGOSQ-ErLF5N13.js +62 -0
  284. ksadk/server/static/assets/cytoscape.esm-CyCl8rPi.js +321 -0
  285. ksadk/server/static/assets/dagre-3AP2YEHR-DFiQF-6f.js +4 -0
  286. ksadk/server/static/assets/dagre-BuhGnRI1.js +1 -0
  287. ksadk/server/static/assets/diagram-S7CK7UJ4-Bt1v8-GC.js +30 -0
  288. ksadk/server/static/assets/diagram-UQ7AKVKN-DSCxJdBK.js +41 -0
  289. ksadk/server/static/assets/diagram-VSXAHHWV-DHfYwp_9.js +3 -0
  290. ksadk/server/static/assets/diagram-VX7I27RA-DdzD-4Le.js +24 -0
  291. ksadk/server/static/assets/diagram-Z3DM3KII-Du-nAJ9F.js +24 -0
  292. ksadk/server/static/assets/{dist-D82mtD2s.js → dist-8hqcx0sU.js} +1 -1
  293. ksadk/server/static/assets/dist-B7seoj3d.js +1 -0
  294. ksadk/server/static/assets/{dist-DHn6nBzr.js → dist-BE7bu-DL.js} +1 -1
  295. ksadk/server/static/assets/{dist-eoW6tZXA.js → dist-BVDffZ0U.js} +1 -1
  296. ksadk/server/static/assets/{dist-C2xjE7cO.js → dist-BX8z72IC.js} +1 -1
  297. ksadk/server/static/assets/{dist-CgF3fj15.js → dist-Bf2M8m3N.js} +1 -1
  298. ksadk/server/static/assets/{dist-Bs-jQcRX.js → dist-BjU6y-A2.js} +1 -1
  299. ksadk/server/static/assets/{dist-Djgl2wVZ.js → dist-BytlxIDT.js} +1 -1
  300. ksadk/server/static/assets/{dist-CVQRZjPu.js → dist-CSh_DE14.js} +1 -1
  301. ksadk/server/static/assets/{dist-6CVKuTAe.js → dist-CXYYBw3_.js} +1 -1
  302. ksadk/server/static/assets/{dist-DlzCRy0S.js → dist-C_wsv-Qd.js} +1 -1
  303. ksadk/server/static/assets/{dist-DF06ORQo.js → dist-ClxGviKw.js} +1 -1
  304. ksadk/server/static/assets/{dist-Cf23NY4L.js → dist-CttYUqzS.js} +1 -1
  305. ksadk/server/static/assets/{dist-ivOya1LD.js → dist-DNp6rLRA.js} +1 -1
  306. ksadk/server/static/assets/{dist-BibcG1V9.js → dist-DUX-id_F.js} +1 -1
  307. ksadk/server/static/assets/{dist-BUHRxvDG.js → dist-DmldrHd_.js} +1 -1
  308. ksadk/server/static/assets/{dist-BZ9n9AjO.js → dist-DnfXs8Vn.js} +2 -2
  309. ksadk/server/static/assets/{dist-DqNnNFrw.js → dist-Dq9gLD7L.js} +1 -1
  310. ksadk/server/static/assets/{dist-CGcp2ex8.js → dist-W-TIVntx.js} +1 -1
  311. ksadk/server/static/assets/{dist-Cwt7koer.js → dist-dDdADKFA.js} +1 -1
  312. ksadk/server/static/assets/{dist-C7-3jInC.js → dist-dydu68Fl.js} +1 -1
  313. ksadk/server/static/assets/{dist-C99THtIA.js → dist-ngtN0DJB.js} +1 -1
  314. ksadk/server/static/assets/ebnfDiagram-PWID7BFC-Da9C9NO1.js +1 -0
  315. ksadk/server/static/assets/erDiagram-SSCWMZ5O-EAGqqR79.js +99 -0
  316. ksadk/server/static/assets/eventmodeling-NTZA5JFV-CMgMaJrC.js +1 -0
  317. ksadk/server/static/assets/flowDiagram-A5DVABFB-BBKL0x3P.js +1 -0
  318. ksadk/server/static/assets/ganttDiagram-EL5Y4UJY-DqJsKb59.js +292 -0
  319. ksadk/server/static/assets/gitGraph-4MIJSDKK-Dw63mrhw.js +1 -0
  320. ksadk/server/static/assets/gitGraphDiagram-WWUBYQGX-B6g4dtDi.js +106 -0
  321. ksadk/server/static/assets/index-8ipRcQ-M.js +240 -0
  322. ksadk/server/static/assets/index-ByFCqjlh.css +2 -0
  323. ksadk/server/static/assets/info-A6RAGUB7-B6iAblII.js +1 -0
  324. ksadk/server/static/assets/infoDiagram-RXCK75RN-Djm_nbd5.js +2 -0
  325. ksadk/server/static/assets/{ishikawaDiagram-YF4QCWOH-DLOHGvWw.js → ishikawaDiagram-5VMMS53U-DWya9SG2.js} +6 -6
  326. ksadk/server/static/assets/{journeyDiagram-JHISSGLW-BIzKeejT.js → journeyDiagram-EYS64GPL-DutxhSNI.js} +6 -6
  327. ksadk/server/static/assets/{kanban-definition-UN3LZRKU-BWHoFSw2.js → kanban-definition-3QL26DDD-DJdOF8Fm.js} +10 -10
  328. ksadk/server/static/assets/katex-vFWytM5c.js +257 -0
  329. ksadk/server/static/assets/{linear-CvMBw9cA.js → linear-BHjG8b-J.js} +1 -1
  330. ksadk/server/static/assets/mermaid-parser.core-KGSy4jWT.js +166 -0
  331. ksadk/server/static/assets/{mindmap-definition-RKZ34NQL-CSAQxEAe.js → mindmap-definition-FBJOCRG2-9-HC88D4.js} +29 -29
  332. ksadk/server/static/assets/packet-AYTQ26CC-BOYAipuq.js +1 -0
  333. ksadk/server/static/assets/pegDiagram-XKGWAZYB-DrEZd4fD.js +1 -0
  334. ksadk/server/static/assets/pie-WAS4IAKB-Ctq0Kbku.js +1 -0
  335. ksadk/server/static/assets/pieDiagram-E7YTZNPT-DpjqOFFp.js +39 -0
  336. ksadk/server/static/assets/{quadrantDiagram-W4KKPZXB-CxIR4JXI.js → quadrantDiagram-AXDQQJYC-BiNhgOXX.js} +6 -6
  337. ksadk/server/static/assets/radar-RG4KPBEZ-DN0-ul_0.js +1 -0
  338. ksadk/server/static/assets/railroad-74A4TZTK-C6cC_to0.js +1 -0
  339. ksadk/server/static/assets/railroad-abnf-HS5TGJTU-BimjIuRc.js +1 -0
  340. ksadk/server/static/assets/railroad-ebnf-LZEXJU2U-CvY65ABq.js +1 -0
  341. ksadk/server/static/assets/railroad-peg-WCYAUIDC-D72Iq_Tv.js +1 -0
  342. ksadk/server/static/assets/railroadDiagram-O6MQD6OU-_Y3Ojg6G.js +1 -0
  343. ksadk/server/static/assets/requirementDiagram-EFPCY7ZU-DeCFdg9K.js +84 -0
  344. ksadk/server/static/assets/{sankeyDiagram-5OEKKPKP-DpGa6EAV.js → sankeyDiagram-P5KCCOFB-CPH75rhw.js} +7 -7
  345. ksadk/server/static/assets/{sequenceDiagram-3UESZ5HK-NTKNGGe5.js → sequenceDiagram-WJ2MYXX4-OEpQQdr4.js} +10 -10
  346. ksadk/server/static/assets/sizeCapture-X5ZJPWSS-heUErzhI.js +1 -0
  347. ksadk/server/static/assets/stateDiagram-HBIQ2CUA-DvA3jSMB.js +1 -0
  348. ksadk/server/static/assets/stateDiagram-v2-4QOOHH4V-BgQY03nz.js +1 -0
  349. ksadk/server/static/assets/swimlanes-XN3QIQJK-CR-dfN_t.js +1 -0
  350. ksadk/server/static/assets/swimlanesDiagram-VK2B7HYN-DLVw3q5Q.js +8 -0
  351. ksadk/server/static/assets/{timeline-definition-PNZ67QCA-jqoYs3jQ.js → timeline-definition-24CTP7MA-DAVJf1TX.js} +7 -7
  352. ksadk/server/static/assets/treeView-Q6P3EWNA-BMpO0wsB.js +1 -0
  353. ksadk/server/static/assets/treemap-WGGIJYW6-Et0aqzU3.js +1 -0
  354. ksadk/server/static/assets/vennDiagram-4TSXK5OY-DwM8eDkh.js +34 -0
  355. ksadk/server/static/assets/wardley-WFR3VGLG-CbY0mhpl.js +1 -0
  356. ksadk/server/static/assets/wardleyDiagram-VM6X3IG4-DZL-Zz2t.js +78 -0
  357. ksadk/server/static/assets/xychartDiagram-S5SC5T6Z-Dy6Yh_hu.js +7 -0
  358. ksadk/server/static/index.html +2 -2
  359. ksadk/sessions/__init__.py +26 -9
  360. ksadk/sessions/_local_service_sync.py +688 -0
  361. ksadk/sessions/_local_tables.py +21 -0
  362. ksadk/sessions/_postgres_schema.py +305 -0
  363. ksadk/sessions/_postgres_tables.py +15 -0
  364. ksadk/sessions/base.py +80 -1
  365. ksadk/sessions/in_memory.py +53 -2
  366. ksadk/sessions/local_service.py +63 -604
  367. ksadk/sessions/postgres_service.py +58 -148
  368. ksadk/sessions/resilient.py +35 -1
  369. ksadk/skills/runtime/backends/e2b.py +1 -1
  370. ksadk/skills/service_client.py +13 -3
  371. ksadk/studio/__init__.py +5 -0
  372. ksadk/studio/agent_avatar_assets.py +120 -0
  373. ksadk/studio/agent_lifecycle.py +51 -0
  374. ksadk/studio/api.py +1598 -0
  375. ksadk/studio/api_catalog_routes.py +324 -0
  376. ksadk/studio/api_contracts.py +286 -0
  377. ksadk/studio/api_helpers.py +132 -0
  378. ksadk/studio/api_memory_routes.py +82 -0
  379. ksadk/studio/authoring.py +749 -0
  380. ksadk/studio/authoring_coordinator.py +1017 -0
  381. ksadk/studio/builder.py +397 -0
  382. ksadk/studio/capabilities.py +368 -0
  383. ksadk/studio/cloud.py +2099 -0
  384. ksadk/studio/codex_agent_service.py +694 -0
  385. ksadk/studio/codex_authoring.py +469 -0
  386. ksadk/studio/codex_builder.py +437 -0
  387. ksadk/studio/codex_manifest.py +307 -0
  388. ksadk/studio/codex_run.py +395 -0
  389. ksadk/studio/compiler.py +190 -0
  390. ksadk/studio/contracts.py +755 -0
  391. ksadk/studio/errors.py +47 -0
  392. ksadk/studio/event_store.py +214 -0
  393. ksadk/studio/framework_run.py +342 -0
  394. ksadk/studio/hosted_kernel.py +317 -0
  395. ksadk/studio/identifiers.py +33 -0
  396. ksadk/studio/manifest_resolver.py +131 -0
  397. ksadk/studio/mcp_runtime.py +229 -0
  398. ksadk/studio/model_client.py +629 -0
  399. ksadk/studio/model_profile_service.py +214 -0
  400. ksadk/studio/operations.py +275 -0
  401. ksadk/studio/otel_trace.py +1060 -0
  402. ksadk/studio/pagination.py +182 -0
  403. ksadk/studio/pcm_memory.py +85 -0
  404. ksadk/studio/python_tool_inspection.py +183 -0
  405. ksadk/studio/repository.py +327 -0
  406. ksadk/studio/resource_catalog.py +1260 -0
  407. ksadk/studio/run_service.py +1133 -0
  408. ksadk/studio/runtime_catalog.py +74 -0
  409. ksadk/studio/runtime_source.py +365 -0
  410. ksadk/studio/service.py +2249 -0
  411. ksadk/studio/shared_web.py +1004 -0
  412. ksadk/studio/skill_discovery.py +628 -0
  413. ksadk/studio/static/assets/PrismRenderer-IYN-ffww.js +3 -0
  414. ksadk/studio/static/assets/index-BLpcdrgW.css +1 -0
  415. ksadk/studio/static/assets/index-CYekR2Xv.js +260 -0
  416. ksadk/studio/static/assets/react-vendor-BNmTiJ-I.js +9 -0
  417. ksadk/studio/static/assets/rolldown-runtime-hePW80VL.js +1 -0
  418. ksadk/studio/static/index.html +15 -0
  419. ksadk/studio/templates.py +722 -0
  420. ksadk/studio/validator.py +265 -0
  421. ksadk/studio/workspace.py +135 -0
  422. ksadk/tools/gateway.py +9 -0
  423. ksadk/toolsets/__init__.py +27 -1
  424. ksadk/toolsets/a2a.py +426 -0
  425. ksadk/tracing/__init__.py +19 -21
  426. ksadk/tracing/setup.py +317 -403
  427. ksadk/tracing/span_utils.py +0 -44
  428. ksadk/version.py +1 -1
  429. ksadk_runtime_common/memory_backend/registry.py +56 -56
  430. ksadk_runtime_common/schemas/runtime_event_v1.json +37 -0
  431. ksadk_runtime_common/schemas/runtime_event_v2.json +271 -0
  432. ksadk_runtime_common/workspace_files/router.py +8 -2
  433. agentengine_sdk_python-0.8.0.dist-info/RECORD +0 -578
  434. ksadk/a2a/card_builder.py +0 -64
  435. ksadk/a2a/client.py +0 -309
  436. ksadk/events/parser.py +0 -191
  437. ksadk/harness/runner.py +0 -211
  438. ksadk/runners/codex_runner.py +0 -132
  439. ksadk/runners/utils/langfuse.py +0 -230
  440. ksadk/server/static/assets/MathMessageMarkdown-DeYh8QPr.css +0 -1
  441. ksadk/server/static/assets/MermaidBlock-DWuxETaJ.js +0 -303
  442. ksadk/server/static/assets/NativeTerminalPanel-MDTopWMO.js +0 -1
  443. ksadk/server/static/assets/arc-CFKwSk_B.js +0 -1
  444. ksadk/server/static/assets/architecture-7EHR7CIX-CynqOWjZ.js +0 -1
  445. ksadk/server/static/assets/architectureDiagram-3BPJPVTR-Dej8jX8c.js +0 -36
  446. ksadk/server/static/assets/blockDiagram-GPEHLZMM-1F64jqvy.js +0 -132
  447. ksadk/server/static/assets/c4Diagram-AAUBKEIU-9q7AUAKb.js +0 -10
  448. ksadk/server/static/assets/channel-iUGv2N24.js +0 -1
  449. ksadk/server/static/assets/chunk-2J33WTMH-6qgwJm7Q.js +0 -1
  450. ksadk/server/static/assets/chunk-55IACEB6-BK8paA20.js +0 -1
  451. ksadk/server/static/assets/chunk-727SXJPM-B-JEhy7h.js +0 -206
  452. ksadk/server/static/assets/chunk-AQP2D5EJ-DYBvMHAa.js +0 -231
  453. ksadk/server/static/assets/chunk-QZHKN3VN-YQIEXeF6.js +0 -1
  454. ksadk/server/static/assets/classDiagram-4FO5ZUOK-CDAUuoXK.js +0 -1
  455. ksadk/server/static/assets/classDiagram-v2-Q7XG4LA2-CDAUuoXK.js +0 -1
  456. ksadk/server/static/assets/cytoscape.esm-DelgaX4f.js +0 -321
  457. ksadk/server/static/assets/dagre-BM42HDAG-C7TguAWo.js +0 -4
  458. ksadk/server/static/assets/dagre-Bx709z4p.js +0 -1
  459. ksadk/server/static/assets/diagram-2AECGRRQ-Dd17_kws.js +0 -43
  460. ksadk/server/static/assets/diagram-5GNKFQAL-DVIClIil.js +0 -10
  461. ksadk/server/static/assets/diagram-KO2AKTUF-Df_3gYQa.js +0 -3
  462. ksadk/server/static/assets/diagram-LMA3HP47-BhLk6ZtA.js +0 -24
  463. ksadk/server/static/assets/diagram-OG6HWLK6-D4GNGvuu.js +0 -24
  464. ksadk/server/static/assets/dist-DyvYLMW9.js +0 -1
  465. ksadk/server/static/assets/erDiagram-TEJ5UH35-CnfRcY2M.js +0 -85
  466. ksadk/server/static/assets/eventmodeling-FCH6USID-ChYO-ijM.js +0 -1
  467. ksadk/server/static/assets/flowDiagram-I6XJVG4X-DGaJjGNJ.js +0 -162
  468. ksadk/server/static/assets/ganttDiagram-6RSMTGT7-DpCoB2g9.js +0 -292
  469. ksadk/server/static/assets/gitGraph-WXDBUCRP-BN_0Fk-j.js +0 -1
  470. ksadk/server/static/assets/gitGraphDiagram-PVQCEYII-9IKVFBVT.js +0 -106
  471. ksadk/server/static/assets/graphlib-B8gBHxth.js +0 -1
  472. ksadk/server/static/assets/index-QSwCHuB8.js +0 -177
  473. ksadk/server/static/assets/index-jOPmTOZH.css +0 -2
  474. ksadk/server/static/assets/info-J43DQDTF-Cp6o3vId.js +0 -1
  475. ksadk/server/static/assets/infoDiagram-5YYISTIA-CYIIsb8y.js +0 -2
  476. ksadk/server/static/assets/katex-DATssjp1.js +0 -265
  477. ksadk/server/static/assets/mermaid-parser.core-mGAcEwcq.js +0 -161
  478. ksadk/server/static/assets/packet-YPE3B663-wQzct3cT.js +0 -1
  479. ksadk/server/static/assets/pie-LRSECV5Y-BgTQiv-9.js +0 -1
  480. ksadk/server/static/assets/pieDiagram-4H26LBE5-By-ra07M.js +0 -30
  481. ksadk/server/static/assets/radar-GUYGQ44K-BIq5fXsn.js +0 -1
  482. ksadk/server/static/assets/requirementDiagram-4Y6WPE33-DpW90iu3.js +0 -84
  483. ksadk/server/static/assets/stateDiagram-AJRCARHV-DGpd9yFG.js +0 -1
  484. ksadk/server/static/assets/stateDiagram-v2-BHNVJYJU-B3o579IQ.js +0 -1
  485. ksadk/server/static/assets/treeView-BLDUP644-Dqi-E0EM.js +0 -1
  486. ksadk/server/static/assets/treemap-LRROVOQU-ClQP9CJ9.js +0 -1
  487. ksadk/server/static/assets/vennDiagram-CIIHVFJN-l3Z7-wbP.js +0 -34
  488. ksadk/server/static/assets/wardley-L42UT6IY-8XLvnNIs.js +0 -1
  489. ksadk/server/static/assets/wardleyDiagram-YWT4CUSO-BR54GPmr.js +0 -78
  490. ksadk/server/static/assets/xychartDiagram-2RQKCTM6-SkiH8GsK.js +0 -7
  491. ksadk/tracing/exporters/langfuse_exporter.py +0 -460
  492. {agentengine_sdk_python-0.8.0.dist-info → agentengine_sdk_python-0.8.2.dist-info}/entry_points.txt +0 -0
  493. {agentengine_sdk_python-0.8.0.dist-info → agentengine_sdk_python-0.8.2.dist-info}/licenses/LICENSE +0 -0
  494. {agentengine_sdk_python-0.8.0.dist-info → agentengine_sdk_python-0.8.2.dist-info}/top_level.txt +0 -0
@@ -0,0 +1,550 @@
1
+ """Local source evaluation target backed by the unified RuntimeAdapter stack."""
2
+
3
+ from __future__ import annotations
4
+
5
+ import asyncio
6
+ import hashlib
7
+ import os
8
+ import subprocess
9
+ import tempfile
10
+ import time
11
+ from collections.abc import Awaitable, Callable
12
+ from dataclasses import dataclass, replace
13
+ from pathlib import Path
14
+ from typing import Any
15
+
16
+ from ksadk.detection.detector import DetectionResult, FrameworkDetector, FrameworkType
17
+ from ksadk.evaluation.adapters import TargetAdapterError
18
+ from ksadk.evaluation.contracts import (
19
+ EvalCase,
20
+ EvalRunSpec,
21
+ TargetKind,
22
+ TargetRef,
23
+ TargetRun,
24
+ TargetRunStatus,
25
+ TargetSnapshot,
26
+ ToolCallEvidence,
27
+ TraceRef,
28
+ UsageSnapshot,
29
+ )
30
+ from ksadk.evaluation.evidence import EvidenceStore, project_tool_calls
31
+ from ksadk.events.store import RuntimeEventStore
32
+ from ksadk.runtime import RuntimeExecutor, RuntimeLaunchContext
33
+ from ksadk.runtime.conversation_execution import invoke_runtime_conversation_once
34
+ from ksadk.runtime.factory import build_default_runtime_registry
35
+ from ksadk.sessions.in_memory import InMemorySessionService
36
+
37
+ _SUPPORTED_FRAMEWORKS = {
38
+ FrameworkType.ADK: "adk",
39
+ FrameworkType.LANGGRAPH: "langgraph",
40
+ FrameworkType.LANGCHAIN: "langgraph",
41
+ FrameworkType.DEEPAGENTS: "langgraph",
42
+ }
43
+ _EXCLUDED_DIRECTORIES = {
44
+ ".agentengine",
45
+ ".agentkit",
46
+ ".aws",
47
+ ".azure",
48
+ ".docker",
49
+ ".git",
50
+ ".hg",
51
+ ".kube",
52
+ ".mypy_cache",
53
+ ".pytest_cache",
54
+ ".ruff_cache",
55
+ ".ssh",
56
+ ".tox",
57
+ ".venv",
58
+ "__pycache__",
59
+ "build",
60
+ "dist",
61
+ "node_modules",
62
+ "tmp",
63
+ "venv",
64
+ }
65
+ _EXCLUDED_FILE_NAMES = {
66
+ ".env",
67
+ ".netrc",
68
+ ".npmrc",
69
+ ".pypirc",
70
+ "auth.json",
71
+ "credentials.json",
72
+ "dockerconfigjson",
73
+ "kubeconfig",
74
+ "secrets.json",
75
+ "service-account.json",
76
+ }
77
+ _EXCLUDED_SUFFIXES = {
78
+ ".db",
79
+ ".jks",
80
+ ".key",
81
+ ".keystore",
82
+ ".log",
83
+ ".p12",
84
+ ".pem",
85
+ ".pfx",
86
+ ".pyc",
87
+ ".pyo",
88
+ ".sqlite",
89
+ }
90
+ _MAX_SNAPSHOT_FILES = 10_000
91
+ _MAX_SNAPSHOT_BYTES = 256 * 1024 * 1024
92
+ _HASH_CHUNK_BYTES = 1024 * 1024
93
+
94
+ _Invoke = Callable[..., Awaitable[tuple[str, dict[str, Any]]]]
95
+
96
+
97
+ @dataclass(frozen=True)
98
+ class _ResolvedLocalTarget:
99
+ snapshot: TargetSnapshot
100
+ detection: DetectionResult
101
+ launch_context: RuntimeLaunchContext
102
+ agent_id: str
103
+ workspace: tempfile.TemporaryDirectory
104
+
105
+
106
+ @dataclass(frozen=True)
107
+ class _LocalTurnResult:
108
+ output: str
109
+ usage: UsageSnapshot
110
+ invocation_id: str
111
+
112
+
113
+ @dataclass(frozen=True)
114
+ class _LocalCaseResult:
115
+ status: TargetRunStatus
116
+ turns: tuple[_LocalTurnResult, ...]
117
+ duration_ms: int
118
+ error_code: str | None = None
119
+ error_message: str | None = None
120
+ trace_ref: TraceRef | None = None
121
+ trace_refs: tuple[TraceRef, ...] = ()
122
+ tool_calls: tuple[ToolCallEvidence, ...] = ()
123
+
124
+
125
+ class LocalTargetError(TargetAdapterError):
126
+ """Classified failure while resolving a local source target."""
127
+
128
+ def __init__(self, code: str, message: str) -> None:
129
+ super().__init__(code, message)
130
+
131
+
132
+ class LocalSourceTargetAdapter:
133
+ """Snapshot local ADK/LangGraph-family projects for evaluation."""
134
+
135
+ kind = TargetKind.LOCAL_SOURCE
136
+
137
+ def __init__(
138
+ self,
139
+ *,
140
+ timeout_seconds: int,
141
+ invoke: _Invoke = invoke_runtime_conversation_once,
142
+ evidence_store: EvidenceStore | None = None,
143
+ ) -> None:
144
+ self._timeout_seconds = timeout_seconds
145
+ self._invoke = invoke
146
+ self._evidence_store = evidence_store
147
+ self._executor = RuntimeExecutor(build_default_runtime_registry())
148
+ self._session_service = InMemorySessionService()
149
+ self._resolved: _ResolvedLocalTarget | None = None
150
+
151
+ async def snapshot(self, target: TargetRef) -> TargetSnapshot:
152
+ if target.kind is not self.kind:
153
+ raise LocalTargetError(
154
+ "LOCAL_TARGET_KIND_INVALID",
155
+ "Local Source adapter received a non-local target",
156
+ )
157
+
158
+ project_dir = await asyncio.to_thread(_resolve_project_dir, target.locator)
159
+ workspace, source_digest = await asyncio.to_thread(_materialize_snapshot, project_dir)
160
+ snapshot_dir = Path(workspace.name)
161
+ try:
162
+ detection = await asyncio.to_thread(
163
+ lambda: FrameworkDetector(str(snapshot_dir)).detect()
164
+ )
165
+ except BaseException:
166
+ workspace.cleanup()
167
+ raise
168
+ runtime_type = _SUPPORTED_FRAMEWORKS.get(detection.type)
169
+ if runtime_type is None:
170
+ workspace.cleanup()
171
+ raise LocalTargetError(
172
+ "LOCAL_FRAMEWORK_UNSUPPORTED",
173
+ f"Unsupported local Agent framework: {detection.type.value}",
174
+ )
175
+
176
+ try:
177
+ entrypoint = await asyncio.to_thread(
178
+ _resolve_entrypoint,
179
+ snapshot_dir,
180
+ target.entrypoint or detection.entry_point,
181
+ )
182
+ except BaseException:
183
+ workspace.cleanup()
184
+ raise
185
+ detection = replace(detection, entry_point=entrypoint.as_posix())
186
+ git_head, git_dirty = await asyncio.to_thread(_git_state, project_dir)
187
+ metadata: dict[str, object] = {
188
+ "detectedFramework": detection.type.value,
189
+ "agentVariable": detection.agent_variable,
190
+ }
191
+ if git_head is not None:
192
+ metadata["gitHead"] = git_head
193
+ if git_dirty is not None:
194
+ metadata["gitDirty"] = git_dirty
195
+
196
+ snapshot = TargetSnapshot(
197
+ kind=self.kind,
198
+ entrypoint=entrypoint.as_posix(),
199
+ revision_digest=f"sha256:{source_digest}",
200
+ runtime=runtime_type,
201
+ metadata=metadata,
202
+ )
203
+ previous = self._resolved
204
+ self._resolved = _ResolvedLocalTarget(
205
+ snapshot=snapshot,
206
+ detection=detection,
207
+ launch_context=RuntimeLaunchContext(
208
+ runtime_type=runtime_type,
209
+ project_dir=snapshot_dir,
210
+ detection=detection,
211
+ config={
212
+ **dict(detection.raw_config or {}),
213
+ "turn_timeout_seconds": self._timeout_seconds,
214
+ },
215
+ ),
216
+ agent_id=detection.name or project_dir.name,
217
+ workspace=workspace,
218
+ )
219
+ if previous is not None:
220
+ previous.workspace.cleanup()
221
+ return snapshot
222
+
223
+ async def run_case(
224
+ self,
225
+ spec: EvalRunSpec,
226
+ case: EvalCase,
227
+ *,
228
+ attempt: int,
229
+ ) -> TargetRun:
230
+ resolved = self._resolved
231
+ if resolved is None:
232
+ raise RuntimeError("Local Source target must be snapshotted before execution")
233
+ if spec.target != resolved.snapshot:
234
+ raise RuntimeError("EvalRunSpec target does not match the snapshotted local target")
235
+
236
+ started_at = time.perf_counter()
237
+ turns: list[_LocalTurnResult] = []
238
+ session_id = _scoped_id("eval-session", spec.id, case.id, str(attempt))
239
+ invocation_id: str | None = None
240
+ trace_ref: TraceRef | None = None
241
+ trace_refs: list[TraceRef] = []
242
+ tool_calls: list[ToolCallEvidence] = []
243
+ try:
244
+ for turn_index, turn in enumerate(case.turns, start=1):
245
+ invocation_id = _scoped_id(
246
+ "eval-invocation",
247
+ spec.id,
248
+ case.id,
249
+ str(attempt),
250
+ str(turn_index),
251
+ )
252
+ session_id, runtime_result = await asyncio.wait_for(
253
+ self._invoke(
254
+ executor=self._executor,
255
+ launch_context=resolved.launch_context,
256
+ agent_id=resolved.agent_id,
257
+ user_id="eval-user",
258
+ messages=[{"role": "user", "content": turn.input}],
259
+ session_id=session_id,
260
+ model=_configured_model(resolved.detection),
261
+ invocation_id=invocation_id,
262
+ session_service_provider=lambda: self._session_service,
263
+ ),
264
+ timeout=self._timeout_seconds,
265
+ )
266
+ turns.append(
267
+ _LocalTurnResult(
268
+ output=str(runtime_result.get("output_text") or ""),
269
+ usage=_usage_snapshot(runtime_result.get("usage")),
270
+ invocation_id=invocation_id,
271
+ )
272
+ )
273
+ if self._evidence_store is not None:
274
+ events = await RuntimeEventStore(self._session_service).list(
275
+ session_id,
276
+ run_id=invocation_id,
277
+ )
278
+ if events:
279
+ trace_ref = self._evidence_store.write_trace(
280
+ spec.id,
281
+ events,
282
+ session_id=session_id,
283
+ policy=spec.config.data_policy,
284
+ )
285
+ trace_refs.append(trace_ref)
286
+ tool_calls.extend(project_tool_calls(events))
287
+ except asyncio.CancelledError:
288
+ raise
289
+ except TimeoutError:
290
+ result = _LocalCaseResult(
291
+ status=TargetRunStatus.ERROR,
292
+ turns=tuple(turns),
293
+ duration_ms=_elapsed_ms(started_at),
294
+ error_code="LOCAL_RUNTIME_TIMEOUT",
295
+ error_message="Local Agent runtime timed out",
296
+ trace_ref=trace_ref,
297
+ trace_refs=tuple(trace_refs),
298
+ tool_calls=tuple(tool_calls),
299
+ )
300
+ return _to_target_run(result, runtime=resolved.snapshot.runtime)
301
+ except Exception:
302
+ result = _LocalCaseResult(
303
+ status=TargetRunStatus.ERROR,
304
+ turns=tuple(turns),
305
+ duration_ms=_elapsed_ms(started_at),
306
+ error_code="LOCAL_RUNTIME_ERROR",
307
+ error_message="Local Agent runtime failed",
308
+ trace_ref=trace_ref,
309
+ trace_refs=tuple(trace_refs),
310
+ tool_calls=tuple(tool_calls),
311
+ )
312
+ return _to_target_run(result, runtime=resolved.snapshot.runtime)
313
+ finally:
314
+ await asyncio.shield(self._session_service.delete_session(session_id))
315
+
316
+ status = (
317
+ TargetRunStatus.PASSED if turns and turns[-1].output else TargetRunStatus.UNAVAILABLE
318
+ )
319
+ result = _LocalCaseResult(
320
+ status=status,
321
+ turns=tuple(turns),
322
+ duration_ms=_elapsed_ms(started_at),
323
+ error_code=(None if status is TargetRunStatus.PASSED else "LOCAL_OUTPUT_UNAVAILABLE"),
324
+ error_message=(
325
+ None
326
+ if status is TargetRunStatus.PASSED
327
+ else "Local Agent did not provide evaluable text output"
328
+ ),
329
+ trace_ref=trace_ref,
330
+ trace_refs=tuple(trace_refs),
331
+ tool_calls=tuple(tool_calls),
332
+ )
333
+ return _to_target_run(result, runtime=resolved.snapshot.runtime)
334
+
335
+
336
+ def _resolve_project_dir(locator: str) -> Path:
337
+ project_dir = Path(locator).expanduser().resolve()
338
+ if not project_dir.is_dir():
339
+ raise LocalTargetError(
340
+ "LOCAL_PROJECT_INVALID",
341
+ "Local Source target locator must be an existing directory",
342
+ )
343
+ return project_dir
344
+
345
+
346
+ def _resolve_entrypoint(project_dir: Path, value: str) -> Path:
347
+ if not value:
348
+ raise LocalTargetError(
349
+ "LOCAL_ENTRYPOINT_INVALID",
350
+ "Local Agent entrypoint was not detected",
351
+ )
352
+ project_dir = project_dir.resolve()
353
+ candidate = (project_dir / Path(value.replace("\\", "/"))).resolve()
354
+ try:
355
+ relative = candidate.relative_to(project_dir)
356
+ except ValueError as exc:
357
+ raise LocalTargetError(
358
+ "LOCAL_ENTRYPOINT_INVALID",
359
+ "Local Agent entrypoint must remain inside the project directory",
360
+ ) from exc
361
+ if not candidate.is_file():
362
+ raise LocalTargetError(
363
+ "LOCAL_ENTRYPOINT_INVALID",
364
+ "Local Agent entrypoint must be an existing file",
365
+ )
366
+ return relative
367
+
368
+
369
+ def _materialize_snapshot(
370
+ project_dir: Path,
371
+ ) -> tuple[tempfile.TemporaryDirectory, str]:
372
+ workspace = tempfile.TemporaryDirectory(prefix="ksadk-eval-local-")
373
+ snapshot_dir = Path(workspace.name)
374
+ digest = hashlib.sha256()
375
+ file_count = 0
376
+ total_bytes = 0
377
+ try:
378
+ for path in _snapshot_files(project_dir):
379
+ relative = path.relative_to(project_dir)
380
+ if (
381
+ not path.is_file()
382
+ or _exclude_from_snapshot(relative)
383
+ or not _is_within_project(path, project_dir)
384
+ ):
385
+ continue
386
+ file_count += 1
387
+ if file_count > _MAX_SNAPSHOT_FILES:
388
+ raise LocalTargetError(
389
+ "LOCAL_SNAPSHOT_TOO_LARGE",
390
+ "Local Agent snapshot exceeds the supported size limit",
391
+ )
392
+ destination = snapshot_dir / relative
393
+ destination.parent.mkdir(parents=True, exist_ok=True)
394
+ digest.update(relative.as_posix().encode("utf-8"))
395
+ digest.update(b"\0")
396
+ with path.open("rb") as source, destination.open("wb") as target:
397
+ while chunk := source.read(_HASH_CHUNK_BYTES):
398
+ total_bytes += len(chunk)
399
+ if total_bytes > _MAX_SNAPSHOT_BYTES:
400
+ raise LocalTargetError(
401
+ "LOCAL_SNAPSHOT_TOO_LARGE",
402
+ "Local Agent snapshot exceeds the supported size limit",
403
+ )
404
+ digest.update(chunk)
405
+ target.write(chunk)
406
+ digest.update(b"\0")
407
+ return workspace, digest.hexdigest()
408
+ except LocalTargetError:
409
+ workspace.cleanup()
410
+ raise
411
+ except OSError as exc:
412
+ workspace.cleanup()
413
+ raise LocalTargetError(
414
+ "LOCAL_SNAPSHOT_FAILED",
415
+ "Unable to materialize a Local Agent snapshot input",
416
+ ) from exc
417
+
418
+
419
+ def _snapshot_files(project_dir: Path) -> list[Path]:
420
+ files: list[Path] = []
421
+ for root, directories, names in os.walk(project_dir, followlinks=False):
422
+ directories[:] = sorted(
423
+ name for name in directories if name.lower() not in _EXCLUDED_DIRECTORIES
424
+ )
425
+ root_path = Path(root)
426
+ files.extend(root_path / name for name in sorted(names))
427
+ return files
428
+
429
+
430
+ def _configured_model(detection: DetectionResult) -> str | None:
431
+ value = detection.raw_config.get("model") if detection.raw_config else None
432
+ model = str(value or "").strip()
433
+ return model or None
434
+
435
+
436
+ def _usage_snapshot(raw_usage: object) -> UsageSnapshot:
437
+ usage = raw_usage if isinstance(raw_usage, dict) else {}
438
+ reported = any(key in usage for key in ("input_tokens", "output_tokens", "total_tokens"))
439
+ return UsageSnapshot(
440
+ input_tokens=_non_negative_int(usage.get("input_tokens")),
441
+ output_tokens=_non_negative_int(usage.get("output_tokens")),
442
+ total_tokens=_non_negative_int(usage.get("total_tokens")),
443
+ reported=reported,
444
+ )
445
+
446
+
447
+ def _non_negative_int(value: object) -> int:
448
+ if isinstance(value, bool):
449
+ return 0
450
+ try:
451
+ return max(0, int(value or 0))
452
+ except (TypeError, ValueError):
453
+ return 0
454
+
455
+
456
+ def _sum_usage(turns: tuple[_LocalTurnResult, ...]) -> UsageSnapshot:
457
+ reported = any(turn.usage.reported for turn in turns)
458
+ return UsageSnapshot(
459
+ input_tokens=sum(turn.usage.input_tokens for turn in turns),
460
+ output_tokens=sum(turn.usage.output_tokens for turn in turns),
461
+ total_tokens=sum(turn.usage.total_tokens for turn in turns),
462
+ reported=reported,
463
+ )
464
+
465
+
466
+ def _to_target_run(result: _LocalCaseResult, *, runtime: str) -> TargetRun:
467
+ final_turn = result.turns[-1] if result.turns else None
468
+ return TargetRun(
469
+ status=result.status,
470
+ output=(
471
+ final_turn.output
472
+ if final_turn is not None and result.status is TargetRunStatus.PASSED
473
+ else ""
474
+ ),
475
+ duration_ms=result.duration_ms,
476
+ usage=_sum_usage(result.turns),
477
+ error_code=result.error_code,
478
+ error_message=result.error_message,
479
+ trace_ref=result.trace_ref,
480
+ trace_refs=list(result.trace_refs),
481
+ tool_calls=list(result.tool_calls),
482
+ metadata={
483
+ "runtime": runtime,
484
+ "turnCount": len(result.turns),
485
+ },
486
+ )
487
+
488
+
489
+ def _scoped_id(prefix: str, *parts: str) -> str:
490
+ payload = "\0".join(parts).encode("utf-8")
491
+ return f"{prefix}-{hashlib.sha256(payload).hexdigest()[:24]}"
492
+
493
+
494
+ def _elapsed_ms(started_at: float) -> int:
495
+ return max(0, round((time.perf_counter() - started_at) * 1000))
496
+
497
+
498
+ def _exclude_from_snapshot(relative: Path) -> bool:
499
+ if any(part.lower() in _EXCLUDED_DIRECTORIES for part in relative.parts[:-1]):
500
+ return True
501
+ name = relative.name.lower()
502
+ if name in _EXCLUDED_FILE_NAMES:
503
+ return True
504
+ if name.startswith(".env.") and name not in {
505
+ ".env.example",
506
+ ".env.sample",
507
+ ".env.template",
508
+ }:
509
+ return True
510
+ return relative.suffix.lower() in _EXCLUDED_SUFFIXES
511
+
512
+
513
+ def _is_within_project(path: Path, project_dir: Path) -> bool:
514
+ try:
515
+ path.resolve().relative_to(project_dir)
516
+ return True
517
+ except (OSError, ValueError):
518
+ return False
519
+
520
+
521
+ def _git_state(project_dir: Path) -> tuple[str | None, bool | None]:
522
+ try:
523
+ head = _run_git(project_dir, "rev-parse", "HEAD")
524
+ dirty = bool(
525
+ _run_git(
526
+ project_dir,
527
+ "status",
528
+ "--porcelain",
529
+ "--untracked-files=normal",
530
+ "--",
531
+ ".",
532
+ )
533
+ )
534
+ return head, dirty
535
+ except (OSError, subprocess.SubprocessError, ValueError):
536
+ return None, None
537
+
538
+
539
+ def _run_git(project_dir: Path, *args: str) -> str:
540
+ completed = subprocess.run(
541
+ ["git", "-C", str(project_dir), *args],
542
+ check=True,
543
+ capture_output=True,
544
+ text=True,
545
+ timeout=5,
546
+ )
547
+ return completed.stdout.strip()
548
+
549
+
550
+ __all__ = ["LocalSourceTargetAdapter", "LocalTargetError"]
@@ -0,0 +1,27 @@
1
+ """Endpoint resolution for the agent-eval cloud Dataset transport."""
2
+
3
+ from __future__ import annotations
4
+
5
+ import os
6
+
7
+ from ksadk.common.aicp_env import DEFAULT_AICP_REGION, resolve_aicp_connection
8
+
9
+ AGENT_EVAL_BASE_URL_ENV = "AGENT_EVAL_BASE_URL"
10
+
11
+
12
+ def resolve_agent_eval_direct_url() -> str | None:
13
+ """Return the explicit direct-HTTP override, if one was configured."""
14
+
15
+ value = os.environ.get(AGENT_EVAL_BASE_URL_ENV, "").strip().rstrip("/")
16
+ return value or None
17
+
18
+
19
+ def resolve_agent_eval_kop_connection() -> dict[str, str]:
20
+ """Resolve the AICP origin used by the default signed KOP transport."""
21
+
22
+ connection = resolve_aicp_connection("KSADK_AGENT_EVAL")
23
+ return {
24
+ "base_url": f"{connection['scheme']}://{connection['endpoint']}".rstrip("/"),
25
+ # pre-online is a routing marker, not an AWS V4 signing region.
26
+ "region": DEFAULT_AICP_REGION,
27
+ }
@@ -0,0 +1,68 @@
1
+ """Local, atomic storage for the shared evaluation report contract."""
2
+
3
+ from __future__ import annotations
4
+
5
+ import json
6
+ from pathlib import Path
7
+
8
+ from .contracts import EvalRunReport
9
+
10
+
11
+ class EvaluationStorageError(RuntimeError):
12
+ """Raised when a report cannot be read or safely persisted."""
13
+
14
+
15
+ class EvaluationStorage:
16
+ """Persist reports below one workspace-owned evaluation directory."""
17
+
18
+ def __init__(self, root: str | Path):
19
+ self.root = Path(root).expanduser().resolve()
20
+
21
+ def report_path(self, run_id: str) -> Path:
22
+ """Return the only report location allowed for a run identifier."""
23
+
24
+ if not run_id or Path(run_id).name != run_id:
25
+ raise EvaluationStorageError("run_id 只能包含文件名,不允许路径穿越")
26
+ return self.root / run_id / "report.json"
27
+
28
+ def write_report(self, report: EvalRunReport) -> Path:
29
+ """Write the completed report atomically after its artifact directory exists."""
30
+
31
+ path = self.report_path(report.spec.id)
32
+ path.parent.mkdir(parents=True, exist_ok=True)
33
+ temporary = path.with_name(f".{path.name}.{report.report_digest}.tmp")
34
+ payload = json.dumps(
35
+ report.model_dump(mode="json", by_alias=True, exclude_none=True),
36
+ ensure_ascii=False,
37
+ sort_keys=True,
38
+ indent=2,
39
+ ) + "\n"
40
+ try:
41
+ temporary.write_text(payload, encoding="utf-8")
42
+ temporary.replace(path)
43
+ except OSError as exc:
44
+ temporary.unlink(missing_ok=True)
45
+ raise EvaluationStorageError("评测报告写入失败") from exc
46
+ return path
47
+
48
+ def read_report(self, run_id: str) -> EvalRunReport:
49
+ path = self.report_path(run_id)
50
+ try:
51
+ return EvalRunReport.model_validate_json(path.read_text(encoding="utf-8"))
52
+ except FileNotFoundError as exc:
53
+ raise EvaluationStorageError("评测报告不存在") from exc
54
+ except (OSError, ValueError) as exc:
55
+ raise EvaluationStorageError("评测报告损坏或不可读") from exc
56
+
57
+ def list_reports(self) -> list[EvalRunReport]:
58
+ if not self.root.is_dir():
59
+ return []
60
+ reports: list[EvalRunReport] = []
61
+ for path in sorted(self.root.glob("*/report.json")):
62
+ try:
63
+ reports.append(
64
+ EvalRunReport.model_validate_json(path.read_text(encoding="utf-8"))
65
+ )
66
+ except (OSError, ValueError):
67
+ continue
68
+ return reports