agentengine-sdk-python 0.7.0__py3-none-any.whl → 0.8.1__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 (450) hide show
  1. {agentengine_sdk_python-0.7.0.dist-info → agentengine_sdk_python-0.8.1.dist-info}/METADATA +52 -20
  2. agentengine_sdk_python-0.8.1.dist-info/RECORD +644 -0
  3. {agentengine_sdk_python-0.7.0.dist-info → agentengine_sdk_python-0.8.1.dist-info}/WHEEL +1 -1
  4. ksadk/a2a/__init__.py +180 -11
  5. ksadk/a2a/bootstrap.py +332 -0
  6. ksadk/a2a/card.py +15 -0
  7. ksadk/a2a/context_store.py +203 -0
  8. ksadk/a2a/control_plane.py +1056 -0
  9. ksadk/a2a/credential.py +99 -0
  10. ksadk/a2a/event_adapter.py +149 -0
  11. ksadk/a2a/executor.py +361 -137
  12. ksadk/a2a/external_transport.py +516 -0
  13. ksadk/a2a/identity.py +304 -0
  14. ksadk/a2a/ids.py +22 -0
  15. ksadk/a2a/langgraph.py +285 -0
  16. ksadk/a2a/resume_store.py +201 -0
  17. ksadk/a2a/routes.py +112 -0
  18. ksadk/a2a/server.py +102 -62
  19. ksadk/a2a/service_env.py +33 -0
  20. ksadk/a2a/space_client.py +1122 -0
  21. ksadk/a2a/task_adapter.py +423 -0
  22. ksadk/a2a/task_event_dispatcher.py +167 -0
  23. ksadk/a2a/task_event_outbox.py +326 -0
  24. ksadk/a2a/task_store.py +206 -0
  25. ksadk/a2a_card.py +101 -0
  26. ksadk/a2ui/__init__.py +27 -0
  27. ksadk/a2ui/core.py +186 -0
  28. ksadk/a2ui/models.py +166 -0
  29. ksadk/a2ui/renderer.py +198 -0
  30. ksadk/agui/__init__.py +9 -0
  31. ksadk/agui/a2ui_projection.py +92 -0
  32. ksadk/agui/agent.py +872 -0
  33. ksadk/agui/config.py +92 -0
  34. ksadk/agui/routes.py +47 -0
  35. ksadk/api/client.py +238 -204
  36. ksadk/api/environment.py +27 -0
  37. ksadk/builders/__init__.py +2 -0
  38. ksadk/builders/base.py +16 -14
  39. ksadk/builders/code_builder.py +375 -270
  40. ksadk/builders/container_builder.py +240 -200
  41. ksadk/builders/framework_requirements.py +31 -12
  42. ksadk/builders/ks3_uploader.py +60 -29
  43. ksadk/builders/managed_runtime_builder.py +173 -0
  44. ksadk/builders/mcp_builder.py +91 -92
  45. ksadk/builders/requirements_utils.py +1 -5
  46. ksadk/cli/__init__.py +97 -171
  47. ksadk/cli/cmd_a2a.py +255 -84
  48. ksadk/cli/cmd_agent.py +19 -5
  49. ksadk/cli/cmd_build.py +158 -29
  50. ksadk/cli/cmd_completion.py +47 -35
  51. ksadk/cli/cmd_config.py +267 -198
  52. ksadk/cli/cmd_create.py +507 -740
  53. ksadk/cli/cmd_dashboard.py +120 -45
  54. ksadk/cli/cmd_deploy.py +135 -59
  55. ksadk/cli/cmd_destroy.py +44 -14
  56. ksadk/cli/cmd_eval.py +386 -0
  57. ksadk/cli/cmd_files.py +63 -24
  58. ksadk/cli/cmd_hermes.py +313 -135
  59. ksadk/cli/cmd_invoke.py +184 -122
  60. ksadk/cli/cmd_launch.py +76 -28
  61. ksadk/cli/cmd_mcp.py +98 -64
  62. ksadk/cli/cmd_model.py +14 -5
  63. ksadk/cli/cmd_openclaw.py +564 -268
  64. ksadk/cli/cmd_replay.py +71 -0
  65. ksadk/cli/cmd_run.py +58 -73
  66. ksadk/cli/cmd_status.py +80 -31
  67. ksadk/cli/cmd_studio.py +110 -0
  68. ksadk/cli/cmd_version.py +20 -13
  69. ksadk/cli/cmd_web.py +95 -18
  70. ksadk/cli/deploy_utils.py +20 -20
  71. ksadk/cli/dry_run.py +7 -4
  72. ksadk/cli/env_options.py +83 -0
  73. ksadk/cli/error_utils.py +37 -12
  74. ksadk/cli/global_options.py +4 -3
  75. ksadk/cli/local_runtime.py +1 -2
  76. ksadk/cli/model_catalog.py +6 -2
  77. ksadk/cli/network_options.py +41 -19
  78. ksadk/cli/resource_common.py +6 -2
  79. ksadk/cli/runtime_bootstrap.py +51 -0
  80. ksadk/cli/storage.py +0 -1
  81. ksadk/cli/ui.py +11 -3
  82. ksadk/cli/workflow_common.py +52 -18
  83. ksadk/codex/__init__.py +12 -0
  84. ksadk/codex/client.py +1042 -0
  85. ksadk/codex/phase.py +143 -0
  86. ksadk/codex/runtime.py +940 -0
  87. ksadk/common/aicp_env.py +0 -1
  88. ksadk/common/auth.py +2 -2
  89. ksadk/common/constants.py +1 -3
  90. ksadk/common/kop_client.py +232 -0
  91. ksadk/common/llm_utils.py +17 -13
  92. ksadk/compat/__init__.py +5 -0
  93. ksadk/compat/adk_compat.py +200 -0
  94. ksadk/compat/copilotkit_a2ui.py +330 -0
  95. ksadk/configs/__init__.py +12 -14
  96. ksadk/configs/env_registry.py +661 -116
  97. ksadk/configs/global_config.py +3 -2
  98. ksadk/configs/settings.py +133 -209
  99. ksadk/conversations/__init__.py +85 -92
  100. ksadk/conversations/attachment_storage.py +16 -11
  101. ksadk/conversations/attachments.py +44 -36
  102. ksadk/conversations/compaction_pipeline.py +12 -12
  103. ksadk/conversations/compaction_prompt.py +9 -5
  104. ksadk/conversations/context.py +221 -6
  105. ksadk/conversations/message_projection.py +438 -51
  106. ksadk/conversations/model_context.py +12 -6
  107. ksadk/conversations/model_options.py +0 -1
  108. ksadk/conversations/normalize.py +20 -16
  109. ksadk/conversations/reasoning_markup.py +1 -1
  110. ksadk/conversations/runtime.py +339 -5255
  111. ksadk/conversations/runtime_compaction.py +333 -0
  112. ksadk/conversations/runtime_constants.py +27 -0
  113. ksadk/conversations/runtime_governance.py +185 -0
  114. ksadk/conversations/runtime_input.py +660 -0
  115. ksadk/conversations/runtime_invocation.py +395 -0
  116. ksadk/conversations/runtime_metadata.py +475 -0
  117. ksadk/conversations/runtime_observability.py +367 -0
  118. ksadk/conversations/runtime_payloads.py +272 -0
  119. ksadk/conversations/runtime_persistence.py +440 -0
  120. ksadk/conversations/runtime_preparation.py +426 -0
  121. ksadk/conversations/runtime_resume.py +836 -0
  122. ksadk/conversations/runtime_stream_events.py +902 -0
  123. ksadk/conversations/runtime_streaming.py +700 -0
  124. ksadk/conversations/semantic_summary.py +17 -5
  125. ksadk/conversations/session_title.py +6 -3
  126. ksadk/deployment/__init__.py +15 -16
  127. ksadk/deployment/agent_access.py +12 -23
  128. ksadk/deployment/base.py +51 -38
  129. ksadk/deployment/managed_runtime.py +33 -0
  130. ksadk/deployment/manager.py +85 -71
  131. ksadk/deployment/providers/serverless.py +379 -210
  132. ksadk/deployment/registry.py +38 -32
  133. ksadk/deployment/state.py +11 -11
  134. ksadk/deployment/ui_config.py +1 -1
  135. ksadk/detection/__init__.py +1 -1
  136. ksadk/detection/detector.py +146 -83
  137. ksadk/detection/mcp_detector.py +9 -6
  138. ksadk/evaluation/__init__.py +84 -0
  139. ksadk/evaluation/a2a_adapter.py +444 -0
  140. ksadk/evaluation/adapters.py +54 -0
  141. ksadk/evaluation/contracts.py +409 -0
  142. ksadk/evaluation/evalset.py +351 -0
  143. ksadk/evaluation/evaluators.py +461 -0
  144. ksadk/evaluation/executor.py +118 -0
  145. ksadk/evaluation/storage.py +68 -0
  146. ksadk/evaluation/target.py +73 -0
  147. ksadk/events/__init__.py +25 -0
  148. ksadk/events/parser.py +191 -0
  149. ksadk/events/replay.py +37 -0
  150. ksadk/events/runtime_event.py +273 -0
  151. ksadk/events/store.py +317 -0
  152. ksadk/harness/__init__.py +35 -0
  153. ksadk/harness/app.py +269 -0
  154. ksadk/harness/config.py +181 -0
  155. ksadk/harness/reasoner.py +105 -0
  156. ksadk/harness/runtime.py +364 -0
  157. ksadk/harness/sandbox.py +141 -0
  158. ksadk/harness/tools.py +222 -0
  159. ksadk/hermes_terminal.py +28 -12
  160. ksadk/identity/resolver.py +15 -9
  161. ksadk/ids.py +32 -0
  162. ksadk/knowledge_base/adk_tool.py +1 -1
  163. ksadk/knowledge_base/client.py +38 -33
  164. ksadk/managed_a2a_card.py +160 -0
  165. ksadk/managed_runtime.py +195 -0
  166. ksadk/markdown.py +5 -2
  167. ksadk/mcp_runtime/__init__.py +9 -6
  168. ksadk/memory/__init__.py +1 -1
  169. ksadk/memory/adk/__init__.py +2 -0
  170. ksadk/memory/adk/backends/base_ltm_backend.py +2 -6
  171. ksadk/memory/adk/backends/http_ltm_backend.py +13 -21
  172. ksadk/memory/adk/backends/inmemory_ltm_backend.py +7 -13
  173. ksadk/memory/adk/backends/sdk_ltm_backend.py +36 -36
  174. ksadk/memory/adk/long_term_memory.py +34 -37
  175. ksadk/memory/adk/resilient_session_service.py +4 -5
  176. ksadk/memory/adk/short_term_memory.py +12 -21
  177. ksadk/memory/adk_tool.py +3 -2
  178. ksadk/memory/backends/base.py +19 -19
  179. ksadk/memory/backends/memory.py +24 -25
  180. ksadk/memory/backends/redis.py +31 -30
  181. ksadk/memory/langchain_tool.py +2 -1
  182. ksadk/memory/manager.py +52 -47
  183. ksadk/memory/service.py +16 -6
  184. ksadk/memory/tool.py +4 -0
  185. ksadk/model_policy.py +15 -7
  186. ksadk/model_proxy/__init__.py +51 -0
  187. ksadk/model_proxy/bootstrap.py +80 -0
  188. ksadk/model_proxy/cache.py +165 -0
  189. ksadk/model_proxy/config.py +66 -0
  190. ksadk/model_proxy/demo_webui.py +115 -0
  191. ksadk/model_proxy/detect.py +145 -0
  192. ksadk/model_proxy/gate.py +68 -0
  193. ksadk/model_proxy/namespace.py +201 -0
  194. ksadk/model_proxy/protocol_proxy.py +22 -0
  195. ksadk/model_proxy/server.py +443 -0
  196. ksadk/model_proxy/transform.py +735 -0
  197. ksadk/openclaw_gateway.py +29 -14
  198. ksadk/runners/adk_runner.py +354 -146
  199. ksadk/runners/base_runner.py +71 -29
  200. ksadk/runners/deepagents_runner.py +0 -1
  201. ksadk/runners/factory.py +18 -5
  202. ksadk/runners/langchain_runner.py +29 -742
  203. ksadk/runners/langgraph_runner.py +417 -97
  204. ksadk/runners/patch_langchain.py +16 -16
  205. ksadk/runners/remote_runner.py +134 -33
  206. ksadk/runners/usage_accumulator.py +1 -0
  207. ksadk/runners/utils/__init__.py +0 -10
  208. ksadk/runners/utils/loader.py +23 -7
  209. ksadk/runtime/__init__.py +67 -0
  210. ksadk/runtime/adapter.py +412 -0
  211. ksadk/runtime/conversation_execution.py +553 -0
  212. ksadk/runtime/executor.py +251 -0
  213. ksadk/runtime/factory.py +156 -0
  214. ksadk/runtime/framework_adapters.py +118 -0
  215. ksadk/runtime/launch.py +48 -0
  216. ksadk/runtime/preprocessing.py +131 -0
  217. ksadk/runtime/runner_adapter.py +1032 -0
  218. ksadk/runtime/runner_loading.py +36 -0
  219. ksadk/runtime_context.py +18 -3
  220. ksadk/runtime_state.py +0 -1
  221. ksadk/sandbox/__init__.py +4 -1
  222. ksadk/sandbox/backends/__init__.py +4 -1
  223. ksadk/sandbox/backends/e2b.py +13 -5
  224. ksadk/sandbox/backends/local_process.py +11 -3
  225. ksadk/sandbox/base.py +10 -15
  226. ksadk/sandbox/factory.py +14 -4
  227. ksadk/sandbox/registry.py +57 -6
  228. ksadk/server/__init__.py +39 -4
  229. ksadk/server/api_models.py +15 -5
  230. ksadk/server/app.py +24 -3928
  231. ksadk/server/composition.py +47 -0
  232. ksadk/server/factory.py +622 -0
  233. ksadk/server/routes/__init__.py +1 -0
  234. ksadk/server/routes/checkpoint_resolution.py +116 -0
  235. ksadk/server/routes/common.py +682 -0
  236. ksadk/server/routes/control.py +331 -0
  237. ksadk/server/routes/dependencies.py +98 -0
  238. ksadk/server/routes/misc.py +425 -0
  239. ksadk/server/routes/models.py +451 -0
  240. ksadk/server/routes/openai_compat.py +229 -0
  241. ksadk/server/routes/projection.py +848 -0
  242. ksadk/server/routes/routers.py +52 -0
  243. ksadk/server/routes/run.py +519 -0
  244. ksadk/server/routes/sessions.py +644 -0
  245. ksadk/server/routes/streaming.py +265 -0
  246. ksadk/server/routes/workspace.py +414 -0
  247. ksadk/server/static/assets/{ArtifactsPanel-D-SSn2ee.js → ArtifactsPanel-CakCqxEN.js} +1 -1
  248. ksadk/server/static/assets/CodeBlock-CynLknyO.js +9 -0
  249. ksadk/server/static/assets/MathMessageMarkdown-3sQdOysS.js +8 -0
  250. ksadk/server/static/assets/MermaidBlock-NERD_ef7.js +303 -0
  251. ksadk/server/static/assets/NativeTerminalPanel-CiHWf82q.js +1 -0
  252. ksadk/server/static/assets/{arc-BA13sHc9.js → arc-DrgjcKhl.js} +1 -1
  253. ksadk/server/static/assets/architecture-7EHR7CIX-CpZLRCcY.js +1 -0
  254. ksadk/server/static/assets/{architectureDiagram-3BPJPVTR-DzJzgVoL.js → architectureDiagram-3BPJPVTR-BXoVRbQ6.js} +1 -1
  255. ksadk/server/static/assets/{blockDiagram-GPEHLZMM-UTdVcZhn.js → blockDiagram-GPEHLZMM-BnaB3Ywv.js} +1 -1
  256. ksadk/server/static/assets/{c4Diagram-AAUBKEIU-Dix0GD4m.js → c4Diagram-AAUBKEIU-Dw4weZcp.js} +1 -1
  257. ksadk/server/static/assets/channel-Dt3rQTFI.js +1 -0
  258. ksadk/server/static/assets/{chunk-2J33WTMH-C2JxuZ42.js → chunk-2J33WTMH-ChjpLK7j.js} +1 -1
  259. ksadk/server/static/assets/{chunk-4BX2VUAB-Be57QPgD.js → chunk-4BX2VUAB-B9drTgOW.js} +1 -1
  260. ksadk/server/static/assets/{chunk-55IACEB6-WjSuy4nv.js → chunk-55IACEB6-CK4ROATy.js} +1 -1
  261. ksadk/server/static/assets/{chunk-727SXJPM-BOovP-b5.js → chunk-727SXJPM-B9KtTTgw.js} +1 -1
  262. ksadk/server/static/assets/{chunk-AQP2D5EJ-DOmZNmWj.js → chunk-AQP2D5EJ-1O1mki3m.js} +1 -1
  263. ksadk/server/static/assets/{chunk-FMBD7UC4-DzwlodkU.js → chunk-FMBD7UC4-B_fH2YuH.js} +1 -1
  264. ksadk/server/static/assets/{chunk-ND2GUHAM-DMqAikEU.js → chunk-ND2GUHAM-D6rFLaVV.js} +1 -1
  265. ksadk/server/static/assets/chunk-QZHKN3VN-iXEZtKQc.js +1 -0
  266. ksadk/server/static/assets/classDiagram-4FO5ZUOK-DIveV17Q.js +1 -0
  267. ksadk/server/static/assets/classDiagram-v2-Q7XG4LA2-DIveV17Q.js +1 -0
  268. ksadk/server/static/assets/{cose-bilkent-S5V4N54A-Zhy2GBnP.js → cose-bilkent-S5V4N54A-ChNs_Mdk.js} +1 -1
  269. ksadk/server/static/assets/{dagre-BM42HDAG-CbKrtIUz.js → dagre-BM42HDAG-D0QXg_MQ.js} +1 -1
  270. ksadk/server/static/assets/{diagram-2AECGRRQ-BRApgQRK.js → diagram-2AECGRRQ-DBDDKwBQ.js} +1 -1
  271. ksadk/server/static/assets/{diagram-5GNKFQAL-D0xbnDiK.js → diagram-5GNKFQAL-BkwDOxmO.js} +1 -1
  272. ksadk/server/static/assets/{diagram-KO2AKTUF-CVugVI9L.js → diagram-KO2AKTUF-Bv8waYvY.js} +1 -1
  273. ksadk/server/static/assets/{diagram-LMA3HP47-DozUGgee.js → diagram-LMA3HP47-e1VECDdu.js} +1 -1
  274. ksadk/server/static/assets/{diagram-OG6HWLK6-ZOYsKlru.js → diagram-OG6HWLK6-Ds9adfRl.js} +1 -1
  275. ksadk/server/static/assets/{dist-DpKtt4Bo.js → dist-4N2NMVYg.js} +1 -1
  276. ksadk/server/static/assets/{dist-CkEKJFtk.js → dist-B-jNR6Vn.js} +1 -1
  277. ksadk/server/static/assets/{dist-D57wnGWd.js → dist-B5J2uhNk.js} +1 -1
  278. ksadk/server/static/assets/{dist-8_SfK1IP.js → dist-B5oS1zcj.js} +1 -1
  279. ksadk/server/static/assets/{dist-DMezvBGJ.js → dist-BB3-OwTQ.js} +1 -1
  280. ksadk/server/static/assets/{dist-2hInLS_J.js → dist-BIlKoW0k.js} +1 -1
  281. ksadk/server/static/assets/{dist-BrCcQ47T.js → dist-BjOdlDjj.js} +1 -1
  282. ksadk/server/static/assets/{dist-BmlMPsCc.js → dist-C1sz5Eo3.js} +1 -1
  283. ksadk/server/static/assets/{dist-B0NP_Z0z.js → dist-CWV4lDr1.js} +1 -1
  284. ksadk/server/static/assets/{dist-D-xOD048.js → dist-CmZHzlwZ.js} +1 -1
  285. ksadk/server/static/assets/{dist-DL_NKc_z.js → dist-D6MpCZtz.js} +1 -1
  286. ksadk/server/static/assets/{dist-DyOkZmze.js → dist-DJN_6Y39.js} +1 -1
  287. ksadk/server/static/assets/{dist-DmFaq_Iy.js → dist-DQU9EWw-.js} +1 -1
  288. ksadk/server/static/assets/{dist-gX6GOLKq.js → dist-DWKByxWV.js} +1 -1
  289. ksadk/server/static/assets/{dist-DyWsb78Q.js → dist-Dli7qW-B.js} +1 -1
  290. ksadk/server/static/assets/{dist-BIJVDMuB.js → dist-DsHPdk3W.js} +1 -1
  291. ksadk/server/static/assets/{dist-Dp0k7bWI.js → dist-X4TnqwOK.js} +1 -1
  292. ksadk/server/static/assets/{dist-8EEyGgDx.js → dist-_pHPTyZ-.js} +1 -1
  293. ksadk/server/static/assets/{dist-CPBtqRTW.js → dist-fhOuWds5.js} +1 -1
  294. ksadk/server/static/assets/{dist-D-JMdWPQ.js → dist-gLnrGsoU.js} +1 -1
  295. ksadk/server/static/assets/{dist-BssVmjIo.js → dist-j6Dxmf_j.js} +1 -1
  296. ksadk/server/static/assets/{dist-C3HIIaN5.js → dist-o2OVmKvt.js} +1 -1
  297. ksadk/server/static/assets/{erDiagram-TEJ5UH35-Bk-9bgE5.js → erDiagram-TEJ5UH35-BPItFKH6.js} +1 -1
  298. ksadk/server/static/assets/eventmodeling-FCH6USID-DYFSxbqr.js +1 -0
  299. ksadk/server/static/assets/{flowDiagram-I6XJVG4X-Dn9kZVuZ.js → flowDiagram-I6XJVG4X-BbYB9w5Y.js} +1 -1
  300. ksadk/server/static/assets/{ganttDiagram-6RSMTGT7-BGxXlJqm.js → ganttDiagram-6RSMTGT7-TQXa0KXv.js} +1 -1
  301. ksadk/server/static/assets/gitGraph-WXDBUCRP-DyNYp6BN.js +1 -0
  302. ksadk/server/static/assets/{gitGraphDiagram-PVQCEYII-C7Q0X-wi.js → gitGraphDiagram-PVQCEYII-bKblCnpa.js} +1 -1
  303. ksadk/server/static/assets/index-R52pJJvg.js +177 -0
  304. ksadk/server/static/assets/index-jJr3_955.css +2 -0
  305. ksadk/server/static/assets/info-J43DQDTF-WUx7qTde.js +1 -0
  306. ksadk/server/static/assets/{infoDiagram-5YYISTIA-BO_CSqq5.js → infoDiagram-5YYISTIA-BGVT7J_i.js} +1 -1
  307. ksadk/server/static/assets/{ishikawaDiagram-YF4QCWOH-eYLPLd46.js → ishikawaDiagram-YF4QCWOH-K0OOfVna.js} +1 -1
  308. ksadk/server/static/assets/{journeyDiagram-JHISSGLW-De9geSb0.js → journeyDiagram-JHISSGLW-8LeOJaZp.js} +1 -1
  309. ksadk/server/static/assets/{kanban-definition-UN3LZRKU-Cs80kQto.js → kanban-definition-UN3LZRKU-C6uCgZrW.js} +1 -1
  310. ksadk/server/static/assets/{katex-DSrCFD8n.js → katex-CYWseY5E.js} +1 -1
  311. ksadk/server/static/assets/{linear-CN9sbKTF.js → linear-hdBcYzM8.js} +1 -1
  312. ksadk/server/static/assets/{mermaid-parser.core-DlgSBU8l.js → mermaid-parser.core-BWrDjSZM.js} +2 -2
  313. ksadk/server/static/assets/{mindmap-definition-RKZ34NQL-9afz7Oug.js → mindmap-definition-RKZ34NQL-Bjy_2v4_.js} +1 -1
  314. ksadk/server/static/assets/packet-YPE3B663-BN13y_xl.js +1 -0
  315. ksadk/server/static/assets/pie-LRSECV5Y-ftSLXhhc.js +1 -0
  316. ksadk/server/static/assets/{pieDiagram-4H26LBE5-DPv_VstN.js → pieDiagram-4H26LBE5-GmmqNiVH.js} +1 -1
  317. ksadk/server/static/assets/{quadrantDiagram-W4KKPZXB-o77wZ1XK.js → quadrantDiagram-W4KKPZXB-BmkRbwCg.js} +1 -1
  318. ksadk/server/static/assets/radar-GUYGQ44K-jaICkIeO.js +1 -0
  319. ksadk/server/static/assets/{requirementDiagram-4Y6WPE33-BYVw81VC.js → requirementDiagram-4Y6WPE33-DSWFqL7c.js} +1 -1
  320. ksadk/server/static/assets/{sankeyDiagram-5OEKKPKP-B7nZFMKT.js → sankeyDiagram-5OEKKPKP-l6iXmU65.js} +1 -1
  321. ksadk/server/static/assets/{sequenceDiagram-3UESZ5HK-BGRRrFw5.js → sequenceDiagram-3UESZ5HK-Cq6UBeQB.js} +1 -1
  322. ksadk/server/static/assets/{stateDiagram-AJRCARHV-BUfHCoPs.js → stateDiagram-AJRCARHV-qzTQpg3Y.js} +1 -1
  323. ksadk/server/static/assets/stateDiagram-v2-BHNVJYJU-BYCoYGAN.js +1 -0
  324. ksadk/server/static/assets/{timeline-definition-PNZ67QCA-FbCTGrf9.js → timeline-definition-PNZ67QCA-DEz24vV0.js} +1 -1
  325. ksadk/server/static/assets/treeView-BLDUP644-Cpib_vlz.js +1 -0
  326. ksadk/server/static/assets/treemap-LRROVOQU-DQxfmVHK.js +1 -0
  327. ksadk/server/static/assets/{vennDiagram-CIIHVFJN-DWgwtPsJ.js → vennDiagram-CIIHVFJN-CMCixki2.js} +1 -1
  328. ksadk/server/static/assets/wardley-L42UT6IY-BQYHnnkU.js +1 -0
  329. ksadk/server/static/assets/{wardleyDiagram-YWT4CUSO-2x8G-tTM.js → wardleyDiagram-YWT4CUSO-CVzB8F9K.js} +1 -1
  330. ksadk/server/static/assets/{xychartDiagram-2RQKCTM6-Drma3AYl.js → xychartDiagram-2RQKCTM6-BFBqBLc1.js} +1 -1
  331. ksadk/server/static/index.html +2 -2
  332. ksadk/server/terminal_sessions.py +111 -58
  333. ksadk/sessions/__init__.py +69 -19
  334. ksadk/sessions/base.py +31 -11
  335. ksadk/sessions/continuity.py +2 -3
  336. ksadk/sessions/in_memory.py +46 -2
  337. ksadk/sessions/local_service.py +148 -17
  338. ksadk/sessions/postgres_service.py +143 -25
  339. ksadk/sessions/resilient.py +36 -8
  340. ksadk/skills/models.py +17 -5
  341. ksadk/skills/package_store.py +5 -2
  342. ksadk/skills/runtime/agent.py +20 -5
  343. ksadk/skills/runtime/artifacts.py +1 -5
  344. ksadk/skills/runtime/backends/e2b.py +10 -4
  345. ksadk/skills/runtime/backends/local.py +15 -3
  346. ksadk/skills/runtime/base.py +1 -2
  347. ksadk/skills/runtime/executor.py +10 -3
  348. ksadk/skills/runtime/factory.py +4 -2
  349. ksadk/skills/runtime/loader.py +1 -2
  350. ksadk/skills/runtime/registry.py +15 -10
  351. ksadk/skills/runtime/request.py +3 -1
  352. ksadk/skills/service_client.py +47 -16
  353. ksadk/skills/tool_defs.py +15 -10
  354. ksadk/studio/__init__.py +5 -0
  355. ksadk/studio/agent_avatar_assets.py +120 -0
  356. ksadk/studio/agent_lifecycle.py +51 -0
  357. ksadk/studio/api.py +1046 -0
  358. ksadk/studio/api_catalog_routes.py +324 -0
  359. ksadk/studio/api_contracts.py +177 -0
  360. ksadk/studio/api_helpers.py +132 -0
  361. ksadk/studio/authoring.py +524 -0
  362. ksadk/studio/authoring_coordinator.py +285 -0
  363. ksadk/studio/builder.py +320 -0
  364. ksadk/studio/capabilities.py +351 -0
  365. ksadk/studio/cloud.py +278 -0
  366. ksadk/studio/codex_agent_service.py +583 -0
  367. ksadk/studio/codex_builder.py +324 -0
  368. ksadk/studio/codex_manifest.py +278 -0
  369. ksadk/studio/codex_run.py +352 -0
  370. ksadk/studio/compiler.py +189 -0
  371. ksadk/studio/contracts.py +644 -0
  372. ksadk/studio/errors.py +47 -0
  373. ksadk/studio/evaluation.py +192 -0
  374. ksadk/studio/event_store.py +284 -0
  375. ksadk/studio/framework_run.py +114 -0
  376. ksadk/studio/identifiers.py +33 -0
  377. ksadk/studio/mcp_runtime.py +229 -0
  378. ksadk/studio/model_client.py +543 -0
  379. ksadk/studio/model_profile_service.py +214 -0
  380. ksadk/studio/operations.py +243 -0
  381. ksadk/studio/otel_trace.py +754 -0
  382. ksadk/studio/pagination.py +182 -0
  383. ksadk/studio/python_tool_inspection.py +183 -0
  384. ksadk/studio/repository.py +306 -0
  385. ksadk/studio/resource_catalog.py +1217 -0
  386. ksadk/studio/run_service.py +707 -0
  387. ksadk/studio/runtime_catalog.py +74 -0
  388. ksadk/studio/runtime_source.py +339 -0
  389. ksadk/studio/service.py +1141 -0
  390. ksadk/studio/shared_web.py +994 -0
  391. ksadk/studio/skill_discovery.py +628 -0
  392. ksadk/studio/static/assets/PrismRenderer-IYN-ffww.js +3 -0
  393. ksadk/studio/static/assets/index-CaEN0eTR.css +1 -0
  394. ksadk/studio/static/assets/index-DI2eY_NH.js +252 -0
  395. ksadk/studio/static/assets/react-vendor-BNmTiJ-I.js +9 -0
  396. ksadk/studio/static/assets/rolldown-runtime-hePW80VL.js +1 -0
  397. ksadk/studio/static/index.html +15 -0
  398. ksadk/studio/templates.py +630 -0
  399. ksadk/studio/validator.py +246 -0
  400. ksadk/studio/workspace.py +137 -0
  401. ksadk/terminal_exec_policy.py +3 -4
  402. ksadk/tools/gateway.py +101 -15
  403. ksadk/tools/result_budget.py +12 -4
  404. ksadk/toolsets/__init__.py +161 -37
  405. ksadk/toolsets/a2a.py +426 -0
  406. ksadk/toolsets/platform.py +21 -5
  407. ksadk/toolsets/sandbox.py +82 -16
  408. ksadk/toolsets/skills.py +200 -39
  409. ksadk/toolsets/web.py +123 -26
  410. ksadk/toolsets/workspace.py +212 -101
  411. ksadk/tracing/__init__.py +19 -21
  412. ksadk/tracing/exporters/inmemory_exporter.py +62 -51
  413. ksadk/tracing/setup.py +135 -506
  414. ksadk/tracing/span_utils.py +0 -41
  415. ksadk/tui/loop.py +78 -30
  416. ksadk/tui/stream_render.py +1 -0
  417. ksadk/ui_config.py +5 -3
  418. ksadk/version.py +1 -1
  419. ksadk_runtime_common/memory_backend/registry.py +56 -56
  420. ksadk_runtime_common/schemas/runtime_event_v1.json +95 -0
  421. ksadk_runtime_common/workspace_files/router.py +8 -2
  422. agentengine_sdk_python-0.7.0.dist-info/RECORD +0 -482
  423. ksadk/a2a/card_builder.py +0 -64
  424. ksadk/a2a/client.py +0 -309
  425. ksadk/runners/utils/langfuse.py +0 -230
  426. ksadk/server/static/assets/CodeBlock-P16VOLYi.js +0 -9
  427. ksadk/server/static/assets/MathMessageMarkdown-CdGiQWHR.js +0 -8
  428. ksadk/server/static/assets/MermaidBlock-IOcal8cm.js +0 -303
  429. ksadk/server/static/assets/NativeTerminalPanel-DGSDWsei.js +0 -1
  430. ksadk/server/static/assets/architecture-7EHR7CIX-BvUlsA6l.js +0 -1
  431. ksadk/server/static/assets/channel-CTuydARX.js +0 -1
  432. ksadk/server/static/assets/chunk-QZHKN3VN-BnCydivS.js +0 -1
  433. ksadk/server/static/assets/classDiagram-4FO5ZUOK-BNHg45Be.js +0 -1
  434. ksadk/server/static/assets/classDiagram-v2-Q7XG4LA2-BNHg45Be.js +0 -1
  435. ksadk/server/static/assets/eventmodeling-FCH6USID-DsAgWnlf.js +0 -1
  436. ksadk/server/static/assets/gitGraph-WXDBUCRP-BIao9Yjg.js +0 -1
  437. ksadk/server/static/assets/index-C00Lwg3L.js +0 -165
  438. ksadk/server/static/assets/index-DAURbCsP.css +0 -1
  439. ksadk/server/static/assets/info-J43DQDTF-CyipqGxU.js +0 -1
  440. ksadk/server/static/assets/packet-YPE3B663-CGkyRxlg.js +0 -1
  441. ksadk/server/static/assets/pie-LRSECV5Y-M0uWAf4n.js +0 -1
  442. ksadk/server/static/assets/radar-GUYGQ44K-Bdbm24-x.js +0 -1
  443. ksadk/server/static/assets/stateDiagram-v2-BHNVJYJU-8xBN_gLM.js +0 -1
  444. ksadk/server/static/assets/treeView-BLDUP644-npMo0ak1.js +0 -1
  445. ksadk/server/static/assets/treemap-LRROVOQU-CHdzrrdo.js +0 -1
  446. ksadk/server/static/assets/wardley-L42UT6IY-BEQz7wyy.js +0 -1
  447. ksadk/tracing/exporters/langfuse_exporter.py +0 -445
  448. {agentengine_sdk_python-0.7.0.dist-info → agentengine_sdk_python-0.8.1.dist-info}/entry_points.txt +0 -0
  449. {agentengine_sdk_python-0.7.0.dist-info → agentengine_sdk_python-0.8.1.dist-info}/licenses/LICENSE +0 -0
  450. {agentengine_sdk_python-0.7.0.dist-info → agentengine_sdk_python-0.8.1.dist-info}/top_level.txt +0 -0
@@ -3,13 +3,12 @@ Container Builder - Docker 镜像构建
3
3
  """
4
4
 
5
5
  import os
6
- import subprocess
6
+ import platform
7
7
  import shutil
8
+ import subprocess
8
9
  import time
9
- import platform
10
- import asyncio
11
10
  from pathlib import Path
12
- from typing import Optional
11
+ from typing import TYPE_CHECKING, Optional
13
12
 
14
13
  import click
15
14
 
@@ -25,12 +24,15 @@ from ksadk.builders.requirements_utils import (
25
24
  parse_requirements_text,
26
25
  )
27
26
 
27
+ if TYPE_CHECKING:
28
+ from ksadk.deployment.base import PackageInfo
29
+
28
30
 
29
31
  def _registry_host(registry: str | None) -> str:
30
32
  value = str(registry or "").strip()
31
33
  for prefix in ("http://", "https://"):
32
34
  if value.startswith(prefix):
33
- value = value[len(prefix):]
35
+ value = value[len(prefix) :]
34
36
  break
35
37
  return value.split("/", 1)[0].strip()
36
38
 
@@ -100,8 +102,8 @@ def print_registry_credentials_help(registry: str | None, *, kind: str | None =
100
102
 
101
103
  def ensure_docker_running() -> bool:
102
104
  """确保 Docker 正在运行"""
103
- if not shutil.which('docker'):
104
- click.secho("❌ 未找到 docker 命令", fg='red')
105
+ if not shutil.which("docker"):
106
+ click.secho("❌ 未找到 docker 命令", fg="red")
105
107
  click.echo("")
106
108
  click.echo("请先安装 Docker:")
107
109
  if platform.system() == "Darwin":
@@ -113,36 +115,36 @@ def ensure_docker_running() -> bool:
113
115
  else:
114
116
  click.echo(" • 下载 Docker Desktop: https://www.docker.com/products/docker-desktop/")
115
117
  return False
116
-
118
+
117
119
  try:
118
- result = subprocess.run(['docker', 'info'], capture_output=True, timeout=10)
120
+ result = subprocess.run(["docker", "info"], capture_output=True, timeout=10)
119
121
  if result.returncode == 0:
120
122
  return True
121
- except:
123
+ except (OSError, subprocess.SubprocessError):
122
124
  pass
123
-
124
- click.secho("⚠️ Docker daemon 未运行", fg='yellow')
125
-
125
+
126
+ click.secho("⚠️ Docker daemon 未运行", fg="yellow")
127
+
126
128
  system_name = platform.system()
127
129
  if system_name == "Darwin":
128
130
  click.echo("🚀 正在启动 Docker Desktop...")
129
131
  try:
130
- subprocess.run(['open', '-a', 'Docker'], check=True)
132
+ subprocess.run(["open", "-a", "Docker"], check=True)
131
133
  for i in range(60):
132
134
  time.sleep(1)
133
135
  try:
134
- result = subprocess.run(['docker', 'info'], capture_output=True, timeout=5)
136
+ result = subprocess.run(["docker", "info"], capture_output=True, timeout=5)
135
137
  if result.returncode == 0:
136
- click.secho("✅ Docker Desktop 已启动", fg='green')
138
+ click.secho("✅ Docker Desktop 已启动", fg="green")
137
139
  return True
138
- except:
140
+ except (OSError, subprocess.SubprocessError):
139
141
  pass
140
142
  if i % 5 == 0 and i > 0:
141
143
  click.echo(f" 等待 Docker 启动中... ({i}秒)")
142
- click.secho("❌ Docker Desktop 启动超时", fg='red')
144
+ click.secho("❌ Docker Desktop 启动超时", fg="red")
143
145
  return False
144
- except:
145
- click.secho("❌ 无法启动 Docker Desktop", fg='red')
146
+ except (OSError, subprocess.SubprocessError):
147
+ click.secho("❌ 无法启动 Docker Desktop", fg="red")
146
148
  return False
147
149
  elif system_name == "Windows":
148
150
  click.echo("请启动 Docker Desktop,然后重试当前命令。")
@@ -154,81 +156,95 @@ def ensure_docker_running() -> bool:
154
156
 
155
157
  class ContainerBuilder(BaseBuilder):
156
158
  """Docker 镜像构建器"""
157
-
158
- def __init__(self, project_dir: Path, config: dict = None,
159
- tag: str = None, registry: str = None, no_cache: bool = False):
159
+
160
+ def __init__(
161
+ self,
162
+ project_dir: Path,
163
+ config: Optional[dict] = None,
164
+ tag: Optional[str] = None,
165
+ registry: Optional[str] = None,
166
+ no_cache: bool = False,
167
+ ):
160
168
  super().__init__(project_dir, config)
161
169
  self.tag = tag
162
170
  self.registry = registry
163
171
  self.no_cache = no_cache
164
-
172
+
165
173
  def _get_smart_kcr_endpoint(self, region: str) -> str:
166
174
  """智能选择 KCR endpoint
167
-
175
+
168
176
  使用企业版 KCR (hub.kce.ksyun.com/agentengine/)。
169
177
  优先使用内网 VPC endpoint,如果内网不可达则使用公网。
170
178
  """
171
179
  from ksadk.configs.settings import check_endpoint_reachable
172
-
180
+
173
181
  # 企业版 KCR 地址 (带 agentengine 命名空间)
174
182
  vpc_endpoint = "hub-vpc.kce.ksyun.com/agentengine"
175
183
  public_endpoint = "hub.kce.ksyun.com/agentengine"
176
-
177
- click.echo(f"🔍 检测 KCR 内网连通性...")
178
-
184
+
185
+ click.echo("🔍 检测 KCR 内网连通性...")
186
+
179
187
  # 检测 VPC 内网是否可达 (端口 443 for HTTPS registry)
180
188
  if check_endpoint_reachable("hub-vpc.kce.ksyun.com", port=443, timeout=2.0):
181
- click.secho(f" ✅ 使用内网: {vpc_endpoint}", fg='green')
189
+ click.secho(f" ✅ 使用内网: {vpc_endpoint}", fg="green")
182
190
  return vpc_endpoint
183
191
  else:
184
192
  click.echo(f" ℹ️ 使用公网: {public_endpoint}")
185
193
  return public_endpoint
186
-
194
+
187
195
  def _optimize_kcr_endpoint(self, registry: str) -> str:
188
196
  """优化 KCR endpoint
189
-
197
+
190
198
  如果是金山云 KCR 公网地址,且内网可达,则替换为内网地址。
191
199
  """
192
200
  from ksadk.configs.settings import check_endpoint_reachable
193
-
201
+
202
+ registry_text = str(registry).strip()
203
+ scheme, separator, reference = registry_text.partition("://")
204
+ prefix = f"{scheme}://" if separator else ""
205
+ target = reference if separator else registry_text
206
+ host, slash, remainder = target.partition("/")
207
+ normalized_host = host.lower()
208
+
194
209
  # 已经是内网地址
195
- if 'hub-vpc' in registry:
210
+ if normalized_host == "hub-vpc.kce.ksyun.com":
196
211
  return registry
197
-
198
- # 匹配企业版 KCR: hub.kce.ksyun.com
199
- if 'hub.kce.ksyun.com' in registry:
200
- click.echo(f"🔍 检测 KCR 内网连通性...")
212
+
213
+ # 仅匹配完整 registry host,避免改写路径或攻击者域名中的同名子串。
214
+ if normalized_host == "hub.kce.ksyun.com":
215
+ click.echo("🔍 检测 KCR 内网连通性...")
201
216
  if check_endpoint_reachable("hub-vpc.kce.ksyun.com", port=443, timeout=2.0):
202
- optimized = registry.replace("hub.kce.ksyun.com", "hub-vpc.kce.ksyun.com")
203
- click.secho(f" ✅ 优化为内网: {optimized}", fg='green')
217
+ optimized = f"{prefix}hub-vpc.kce.ksyun.com{slash}{remainder}"
218
+ click.secho(f" ✅ 优化为内网: {optimized}", fg="green")
204
219
  return optimized
205
220
  else:
206
221
  click.echo(f" ℹ️ 使用公网: {registry}")
207
-
222
+
208
223
  return registry
209
-
210
- def _package(self, detection_result) -> 'PackageInfo':
224
+
225
+ def _package(self, detection_result) -> "PackageInfo":
211
226
  """打包项目 - 复制文件并生成 Dockerfile/requirements/entrypoint"""
212
227
  from ksadk.deployment.base import PackageInfo
213
-
228
+
214
229
  project_path = self.project_dir
215
230
  output_dir = project_path / ".agentengine" / "build"
216
231
  output_dir.mkdir(parents=True, exist_ok=True)
217
-
232
+
218
233
  package_name = Path(detection_result.package_path).name
219
234
  is_container_first_template = (
220
235
  getattr(getattr(detection_result, "type", None), "value", "") == "hermes"
221
236
  and (project_path / "Dockerfile").exists()
222
237
  and (project_path / "entrypoint.sh").exists()
223
238
  )
224
-
239
+
225
240
  # 复制项目文件。真实 .env 只通过 deploy payload 注入,不进入镜像上下文。
226
241
  for item in project_path.iterdir():
227
242
  if CodeBuilder._is_real_dotenv_file(item.name):
228
243
  continue
229
- if (
230
- (item.name.startswith('.') and item.name != '.env.example')
231
- or item.name in ('__pycache__', '.git', 'node_modules')
244
+ if (item.name.startswith(".") and item.name != ".env.example") or item.name in (
245
+ "__pycache__",
246
+ ".git",
247
+ "node_modules",
232
248
  ):
233
249
  continue
234
250
  dest = output_dir / item.name
@@ -249,9 +265,10 @@ class ContainerBuilder(BaseBuilder):
249
265
  )
250
266
  else:
251
267
  shutil.copy2(item, dest)
252
-
268
+
253
269
  # 复制 ksadk 源码 (确保容器内可用)
254
270
  import ksadk
271
+
255
272
  ksadk_src = Path(ksadk.__file__).parent
256
273
  ksadk_dest = output_dir / "ksadk"
257
274
  if ksadk_dest.exists():
@@ -274,14 +291,15 @@ class ContainerBuilder(BaseBuilder):
274
291
  return ignored
275
292
 
276
293
  shutil.copytree(
277
- ksadk_src,
278
- ksadk_dest,
294
+ ksadk_src,
295
+ ksadk_dest,
279
296
  ignore=_ignore_ksadk_source,
280
297
  )
281
298
 
282
299
  # 复制 ksadk_runtime_common (如果存在)
283
300
  try:
284
301
  import ksadk_runtime_common
302
+
285
303
  runtime_common_src = Path(ksadk_runtime_common.__file__).parent
286
304
  runtime_common_dest = output_dir / "ksadk_runtime_common"
287
305
  if runtime_common_dest.exists():
@@ -305,21 +323,22 @@ class ContainerBuilder(BaseBuilder):
305
323
  ignore=shutil.ignore_patterns("__pycache__", "*.pyc"),
306
324
  )
307
325
  else:
308
- click.echo(click.style(
309
- "⚠️ 警告: 未找到 ksadk_runtime_common,镜像可能无法正常运行",
310
- fg="yellow"
311
- ))
312
-
326
+ click.echo(
327
+ click.style(
328
+ "⚠️ 警告: 未找到 ksadk_runtime_common,镜像可能无法正常运行", fg="yellow"
329
+ )
330
+ )
331
+
313
332
  dockerfile_path = output_dir / "Dockerfile"
314
333
  if not is_container_first_template:
315
334
  dockerfile = self._generate_dockerfile(detection_result)
316
335
  dockerfile_path.write_text(dockerfile)
317
-
336
+
318
337
  # 生成 requirements.txt (合并用户依赖)
319
338
  requirements = self._generate_requirements(detection_result, project_path)
320
339
  requirements_path = output_dir / "requirements.txt"
321
340
  requirements_path.write_text(requirements)
322
-
341
+
323
342
  # 生成启动脚本
324
343
  if is_container_first_template:
325
344
  entrypoint_path = output_dir / "entrypoint.sh"
@@ -327,7 +346,7 @@ class ContainerBuilder(BaseBuilder):
327
346
  entrypoint = self._generate_entrypoint(detection_result, package_name)
328
347
  entrypoint_path = output_dir / "entrypoint.py"
329
348
  entrypoint_path.write_text(entrypoint)
330
-
349
+
331
350
  return PackageInfo(
332
351
  name=detection_result.name or project_path.name,
333
352
  framework=detection_result.type.value,
@@ -339,14 +358,14 @@ class ContainerBuilder(BaseBuilder):
339
358
  "package_name": package_name,
340
359
  "requirements": str(requirements_path),
341
360
  "entrypoint": str(entrypoint_path),
342
- }
361
+ },
343
362
  )
344
-
363
+
345
364
  def _generate_dockerfile(self, detection_result) -> str:
346
365
  """生成优化的 Dockerfile"""
347
366
  base_image = "python:3.12-slim"
348
-
349
- return f'''FROM {base_image}
367
+
368
+ return f"""FROM {base_image}
350
369
 
351
370
  # 设置环境变量
352
371
  ENV PYTHONUNBUFFERED=1 \\
@@ -373,9 +392,9 @@ EXPOSE 8080
373
392
 
374
393
  # 使用 exec 形式确保信号正确传递
375
394
  CMD ["python", "entrypoint.py"]
376
- '''
377
-
378
- def _generate_requirements(self, detection_result, project_path: Path = None) -> str:
395
+ """
396
+
397
+ def _generate_requirements(self, detection_result, project_path: Optional[Path] = None) -> str:
379
398
  """生成 requirements.txt"""
380
399
  base_deps = [
381
400
  # Core
@@ -385,14 +404,14 @@ CMD ["python", "entrypoint.py"]
385
404
  "pydantic>=2.0.0",
386
405
  "pyyaml>=6.0.0",
387
406
  "httpx>=0.24.0",
388
- # Tracing
407
+ # Tracing — OTLP 双写收敛:只用 OTel + openinference 自动插桩,
408
+ # 不再安装 Langfuse SDK(callback 路径已删除,Langfuse 通过标准 OTLP 接收)。
389
409
  "opentelemetry-api>=1.37.0",
390
410
  "opentelemetry-sdk>=1.37.0",
391
411
  "opentelemetry-exporter-otlp>=1.37.0",
392
412
  "openinference-instrumentation-langchain>=0.1.0",
393
- "langfuse>=2.0.0",
394
413
  ]
395
-
414
+
396
415
  framework = detection_result.type.value
397
416
  base_deps += requirements_for_framework(framework)
398
417
 
@@ -400,20 +419,26 @@ CMD ["python", "entrypoint.py"]
400
419
  base_deps,
401
420
  CodeBuilder(project_path or self.project_dir)._bundled_runtime_requirements(),
402
421
  )
403
-
422
+
404
423
  # 合并用户 requirements.txt (如果存在)
405
424
  if project_path:
406
425
  user_requirements = project_path / "requirements.txt"
407
426
  if user_requirements.exists():
408
427
  user_content = user_requirements.read_text()
428
+ parsed_user_requirements = parse_requirements_text(user_content)
429
+ bundled_builder = CodeBuilder(project_path or self.project_dir)
430
+ base_deps = merge_requirement_lists(
431
+ base_deps,
432
+ bundled_builder._bundled_ksadk_extra_requirements(parsed_user_requirements),
433
+ )
409
434
  user_deps = exclude_requirement_names(
410
- parse_requirements_text(user_content),
435
+ parsed_user_requirements,
411
436
  excluded_names={"ksadk"},
412
437
  )
413
438
  base_deps = merge_requirement_lists(base_deps, user_deps)
414
-
439
+
415
440
  return "\n".join(base_deps)
416
-
441
+
417
442
  def _generate_entrypoint(self, detection_result, package_name: str) -> str:
418
443
  """生成 entrypoint.py"""
419
444
  return f'''"""
@@ -464,15 +489,11 @@ except ImportError:
464
489
 
465
490
  env_keys = [
466
491
  "AGENT_RUNTIME_NAME", "AGENT_RUNTIME_ID", "ACCOUNT_ID", "PORT",
467
- "LANGFUSE_BASE_URL", "LANGFUSE_HOST", "LANGFUSE_PUBLIC_KEY",
468
- "LANGFUSE_SECRET_KEY", "LANGFUSE_USE_CALLBACK",
469
492
  "OTEL_EXPORTER_OTLP_ENDPOINT", "OTEL_EXPORTER_OTLP_TRACES_ENDPOINT",
470
493
  "OTEL_EXPORTER_OTLP_HEADERS", "OTEL_EXPORTER_OTLP_TRACES_HEADERS",
471
- "OTEL_SERVICE_NAME", "CLOUD_MONITOR_APP_KEY",
472
- "CLOUD_MONITOR_OTLP_ENABLED", "CLOUD_MONITOR_OTLP_ENDPOINT",
473
- "CLOUD_MONITOR_OTLP_TRACES_ENDPOINT", "CLOUD_MONITOR_OTLP_HEADERS",
474
- "CLOUD_MONITOR_LANGFUSE_HOST", "CLOUD_MONITOR_LANGFUSE_PUBLIC_KEY",
475
- "CLOUD_MONITOR_LANGFUSE_SECRET_KEY", "CLOUD_MONITOR_LANGFUSE_ENABLED",
494
+ "OTEL_SERVICE_NAME",
495
+ "CLOUD_MONITOR_OTLP_ENDPOINT", "CLOUD_MONITOR_OTLP_TRACES_ENDPOINT",
496
+ "CLOUD_MONITOR_OTLP_HEADERS", "CLOUD_MONITOR_OTLP_TRACES_HEADERS",
476
497
  "LANGCHAIN_TRACING_V2", "MODEL_NAME",
477
498
  ]
478
499
  for key in env_keys:
@@ -486,15 +507,9 @@ for key in env_keys:
486
507
  from ksadk.configs import setup_environment
487
508
  setup_environment(Path("/app"))
488
509
 
489
- try:
490
- from ksadk.runners.patch_langchain import apply_patch as apply_langchain_patch
491
- apply_langchain_patch()
492
- except ImportError:
493
- pass
494
-
495
- from ksadk.runners import create_runner
496
510
  from ksadk.detection import DetectionResult, FrameworkType
497
- from ksadk.server import app, set_runner
511
+ from ksadk.runtime import RuntimeExecutor, RuntimeLaunchContext, build_default_runtime_registry
512
+ from ksadk.server import RuntimeAppConfig, configure_runtime_app, create_runtime_app
498
513
  import uvicorn
499
514
 
500
515
  # 检测结果 (构建时固化)
@@ -504,121 +519,154 @@ detection_result = DetectionResult(
504
519
  entry_point="{detection_result.entry_point}",
505
520
  package_path="/app/{package_name}",
506
521
  agent_variable="{detection_result.agent_variable}",
507
- runner_class="{getattr(detection_result, 'runner_class', '')}"
522
+ runner_class="{getattr(detection_result, "runner_class", "")}"
508
523
  )
509
524
 
510
525
  logger.info(f"框架: {{detection_result.name}}")
511
526
  logger.info(f"入口: {{detection_result.entry_point}}")
512
527
 
513
- # 初始化 Tracing (如果配置了 Langfuse、标准 OTLP HTTP 或 CloudMonitor OTLP)
514
- has_otlp = bool(os.environ.get("OTEL_EXPORTER_OTLP_ENDPOINT") or os.environ.get("OTEL_EXPORTER_OTLP_TRACES_ENDPOINT"))
528
+ # 初始化 Tracing (如果配置了标准 OTLP HTTP 或 CloudMonitor OTLP)
529
+ has_otlp = bool(
530
+ os.environ.get("OTEL_EXPORTER_OTLP_ENDPOINT")
531
+ or os.environ.get("OTEL_EXPORTER_OTLP_TRACES_ENDPOINT")
532
+ )
515
533
  has_cloud_monitor_otlp = bool(
516
- os.environ.get("CLOUD_MONITOR_APP_KEY")
534
+ os.environ.get("CLOUD_MONITOR_OTLP_TRACES_HEADERS")
535
+ or os.environ.get("CLOUD_MONITOR_OTLP_HEADERS")
517
536
  or os.environ.get("CLOUD_MONITOR_OTLP_ENDPOINT")
518
537
  or os.environ.get("CLOUD_MONITOR_OTLP_TRACES_ENDPOINT")
538
+ or os.environ.get("CLOUD_MONITOR_APP_KEY")
519
539
  )
520
- has_cloud_monitor_langfuse = bool(
521
- os.environ.get("CLOUD_MONITOR_LANGFUSE_PUBLIC_KEY")
522
- or os.environ.get("CLOUD_MONITOR_LANGFUSE_SECRET_KEY")
523
- or os.environ.get("CLOUD_MONITOR_LANGFUSE_HOST")
524
- )
525
- if os.environ.get("LANGFUSE_PUBLIC_KEY") or has_otlp or has_cloud_monitor_otlp or has_cloud_monitor_langfuse:
540
+ if has_otlp or has_cloud_monitor_otlp:
526
541
  try:
527
542
  from ksadk.tracing import setup_tracing
528
- use_callback_only = os.environ.get("LANGFUSE_USE_CALLBACK", "").strip().lower() in ("1", "true", "yes", "on")
529
- setup_tracing(use_callback_only=use_callback_only)
543
+ setup_tracing()
530
544
  logger.info(
531
545
  f"Tracing 已启用 (OTLP={{has_otlp}}, "
532
- f"CloudMonitorOTLP={{has_cloud_monitor_otlp}}, "
533
- f"CloudMonitorLangfuse={{has_cloud_monitor_langfuse}}, "
534
- f"CallbackOnly={{use_callback_only}})"
546
+ f"CloudMonitorOTLP={{has_cloud_monitor_otlp}})"
535
547
  )
536
548
  except Exception as e:
537
549
  logger.warning(f"Tracing 初始化失败: {{e}}")
538
550
 
539
- # 创建 Runner 并加载 Agent
540
- logger.info("正在加载 Agent...")
541
- runner = create_runner(detection_result, "/app")
542
- runner.load_agent()
543
- set_runner(runner)
544
- logger.info("Agent 加载成功!")
551
+ # 只装配统一 RuntimeAdapter 执行链;具体 Adapter 在请求开始时由 Registry 创建。
552
+ runtime_context = RuntimeLaunchContext(
553
+ runtime_type=detection_result.type.value,
554
+ project_dir=Path("/app"),
555
+ detection=detection_result,
556
+ config=dict(getattr(detection_result, "raw_config", None) or {{}}),
557
+ )
558
+ # managed A2A:KSADK_A2A_RUNTIME_ID 非空时挂 discovery card + 完整数据面 route。
559
+ # discovery card 让 server 探测;数据面 route 让 gateway 转发的 JSON-RPC/REST
560
+ # 能真正落到本 runtime 的 A2A 协议端点(路线 C 直连)。
561
+ _a2a_config = None
562
+ _a2a_adapter = None
563
+ if os.environ.get("KSADK_A2A_RUNTIME_ID", "").strip():
564
+ from ksadk.managed_a2a_card import build_managed_a2a_card_if_configured
565
+
566
+ _managed_a2a_card = build_managed_a2a_card_if_configured()
567
+ try:
568
+ from ksadk.a2a.routes import A2AConfig
569
+ from ksadk.runtime.factory import create_runtime_adapter
570
+
571
+ _a2a_adapter = create_runtime_adapter(runtime_context)
572
+ _base = (
573
+ os.environ.get("KSADK_A2A_INTERNAL_BASE_URL", "").strip()
574
+ or "http://localhost:8080"
575
+ )
576
+ _a2a_config = A2AConfig(
577
+ enabled=True,
578
+ base_url=_base,
579
+ agent_name=(
580
+ os.environ.get("KSADK_A2A_AGENT_NAME", "").strip()
581
+ or os.environ.get("KSADK_A2A_RUNTIME_ID", "").strip()
582
+ ),
583
+ streaming=True,
584
+ task_store_dsn="sqlite+aiosqlite:///.agentengine/a2a_tasks.db",
585
+ )
586
+ except Exception as _e:
587
+ logger.warning(f"managed A2A 数据面装配失败,回退 discovery-only: {{_e}}")
588
+ _a2a_config = None
589
+ _a2a_adapter = None
590
+ app = create_runtime_app(
591
+ RuntimeAppConfig(
592
+ runtime_type=detection_result.type.value,
593
+ runtime_executor=RuntimeExecutor(build_default_runtime_registry()),
594
+ launch_context=runtime_context,
595
+ a2a=_a2a_config or _managed_a2a_card,
596
+ a2a_runtime_adapter=_a2a_adapter,
597
+ ),
598
+ configure_runtime_app,
599
+ )
600
+ logger.info("RuntimeAdapter 执行链装配成功!")
545
601
 
546
602
  if __name__ == "__main__":
547
603
  port = int(os.environ.get("PORT", 8080))
548
604
  logger.info(f"启动 HTTP Server: 0.0.0.0:{{port}}")
549
605
  uvicorn.run(app, host="0.0.0.0", port=port, log_level=LOG_LEVEL.lower())
550
606
  '''
551
-
607
+
552
608
  def build(self) -> BuildResult:
553
609
  """构建 Docker 镜像"""
554
610
  from ksadk.detection import FrameworkDetector
555
-
611
+
556
612
  self._load_dotenv()
557
613
  config = self._load_config()
558
-
614
+
559
615
  # 检测框架
560
616
  detector = FrameworkDetector(str(self.project_dir))
561
617
  result = detector.detect()
562
-
618
+
563
619
  if result.type.value == "unknown":
564
- return BuildResult(
565
- success=False,
566
- error_message="未检测到支持的框架"
567
- )
568
-
620
+ return BuildResult(success=False, error_message="未检测到支持的框架")
621
+
569
622
  click.echo(f"📦 框架: {click.style(result.name, fg='green')}")
570
-
623
+
571
624
  # 确定镜像名称
572
- image_name = config.get('name', self.project_dir.name).replace('-', '_').replace('.', '_')
573
-
625
+ image_name = config.get("name", self.project_dir.name).replace("-", "_").replace(".", "_")
626
+
574
627
  # Tag 优先级: 命令行 > agentengine.yaml version > config image.tag > latest
575
628
  image_tag = self.tag
576
629
  if not image_tag:
577
- image_tag = config.get('version', '') # 使用项目版本作为 tag
630
+ image_tag = config.get("version", "") # 使用项目版本作为 tag
578
631
  if not image_tag:
579
- image_tag = config.get('image', {}).get('tag', 'latest')
580
-
632
+ image_tag = config.get("image", {}).get("tag", "latest")
633
+
581
634
  # Registry 优先级: 命令行 > .env KCR_REGISTRY > agentengine.yaml > 默认企业版 KCR
582
635
  import os
636
+
583
637
  image_registry = self.registry
584
638
  if not image_registry:
585
- image_registry = os.getenv('KCR_REGISTRY', '')
639
+ image_registry = os.getenv("KCR_REGISTRY", "")
586
640
  if not image_registry:
587
- image_registry = config.get('image', {}).get('registry', '')
641
+ image_registry = config.get("image", {}).get("registry", "")
588
642
  if not image_registry:
589
643
  # 默认使用企业版 KCR,智能选择内网/公网
590
- image_registry = self._get_smart_kcr_endpoint(os.getenv('KSYUN_REGION', 'cn-beijing-6'))
644
+ image_registry = self._get_smart_kcr_endpoint(os.getenv("KSYUN_REGION", "cn-beijing-6"))
591
645
  else:
592
646
  # 即使设置了 registry,如果是金山云公网地址,也尝试优化为内网
593
647
  image_registry = self._optimize_kcr_endpoint(image_registry)
594
-
648
+
595
649
  full_image = f"{image_registry}/{image_name}:{image_tag}"
596
-
650
+
597
651
  click.echo(f"🏷️ 镜像名称: {full_image}")
598
-
652
+
599
653
  # 打包 (内置打包逻辑,不再依赖 DockerProvider)
600
654
  click.echo("\n📦 打包中...")
601
655
  try:
602
656
  package_info = self._package(result)
603
657
  click.echo("✅ 打包完成")
604
658
  except Exception as e:
605
- return BuildResult(
606
- success=False,
607
- error_message=f"打包失败: {e}"
608
- )
609
-
659
+ return BuildResult(success=False, error_message=f"打包失败: {e}")
660
+
610
661
  # Docker 构建
611
662
  if not ensure_docker_running():
612
- return BuildResult(
613
- success=False,
614
- error_message="Docker 未运行"
615
- )
616
-
663
+ return BuildResult(success=False, error_message="Docker 未运行")
664
+
617
665
  click.echo("\n🔨 构建 Docker 镜像 (目标平台: linux/amd64)...")
618
666
  try:
619
- cmd = ['docker', 'build', '--platform', 'linux/amd64', '-t', full_image]
667
+ cmd = ["docker", "build", "--platform", "linux/amd64", "-t", full_image]
620
668
  if self.no_cache:
621
- cmd.append('--no-cache')
669
+ cmd.append("--no-cache")
622
670
  cmd.append(package_info.build_dir)
623
671
 
624
672
  quiet_mode = os.getenv("AGENTENGINE_OUTPUT_MODE", "").strip().lower() == "json"
@@ -628,16 +676,16 @@ if __name__ == "__main__":
628
676
  capture_output=quiet_mode,
629
677
  text=quiet_mode,
630
678
  )
631
- click.secho(f"\n✅ 镜像构建成功: {full_image}", fg='green')
632
-
679
+ click.secho(f"\n✅ 镜像构建成功: {full_image}", fg="green")
680
+
633
681
  return BuildResult(
634
682
  success=True,
635
683
  artifact_path=None, # Docker 镜像没有本地文件路径
636
684
  metadata={
637
685
  "image": full_image,
638
686
  "framework": result.type.value,
639
- "build_dir": package_info.build_dir
640
- }
687
+ "build_dir": package_info.build_dir,
688
+ },
641
689
  )
642
690
  except subprocess.CalledProcessError as e:
643
691
  error_message = f"镜像构建失败: {e}"
@@ -647,138 +695,130 @@ if __name__ == "__main__":
647
695
  detail = stderr or stdout
648
696
  if detail:
649
697
  error_message = f"{error_message}: {detail}"
650
- return BuildResult(
651
- success=False,
652
- error_message=error_message
653
- )
654
-
698
+ return BuildResult(success=False, error_message=error_message)
699
+
655
700
  def push(self, image_name: str) -> bool:
656
701
  """推送镜像到仓库"""
657
702
  # 检查镜像仓库认证
658
703
  registry = self._extract_registry(image_name)
659
-
704
+
660
705
  # 尝试使用 .env 中的认证信息自动登录
661
706
  if registry:
662
707
  if not self._auto_login_from_env(registry):
663
708
  # 自动登录失败,检查是否已有认证
664
709
  if not self._check_registry_auth(registry):
665
710
  return False
666
-
667
- click.echo(f"\n📤 推送镜像...")
711
+
712
+ click.echo("\n📤 推送镜像...")
668
713
  try:
669
- result = subprocess.run(
670
- ['docker', 'push', image_name],
671
- capture_output=True,
672
- text=True
673
- )
714
+ result = subprocess.run(["docker", "push", image_name], capture_output=True, text=True)
674
715
  if result.returncode != 0:
675
716
  # 检查是否是认证问题
676
- if 'denied' in result.stderr.lower() or 'unauthorized' in result.stderr.lower():
677
- self._print_auth_help(registry or 'docker.io')
717
+ if "denied" in result.stderr.lower() or "unauthorized" in result.stderr.lower():
718
+ self._print_auth_help(registry or "docker.io")
678
719
  return False
679
- click.secho(f"❌ 镜像推送失败: {result.stderr}", fg='red')
720
+ click.secho(f"❌ 镜像推送失败: {result.stderr}", fg="red")
680
721
  return False
681
-
682
- click.secho(f"✅ 镜像推送成功", fg='green')
722
+
723
+ click.secho("✅ 镜像推送成功", fg="green")
683
724
  return True
684
725
  except subprocess.CalledProcessError as e:
685
- click.secho(f"❌ 镜像推送失败: {e}", fg='red')
726
+ click.secho(f"❌ 镜像推送失败: {e}", fg="red")
686
727
  return False
687
-
728
+
688
729
  def _auto_login_from_env(self, registry: str) -> bool:
689
730
  """尝试使用 .env 中的凭证自动登录"""
690
731
  import os
732
+
691
733
  from dotenv import load_dotenv
692
-
734
+
693
735
  # 加载 .env
694
736
  load_dotenv()
695
-
696
- # KCR_REGISTRY is a generic registry/namespace target used for KCR and third-party registries.
697
- kcr_registry = os.getenv('KCR_REGISTRY', '')
737
+
738
+ # KCR_REGISTRY is the registry/namespace target for KCR and third parties.
739
+ kcr_registry = os.getenv("KCR_REGISTRY", "")
698
740
  if not kcr_registry:
699
741
  kcr_registry = "hub.kce.ksyun.com/agentengine"
700
-
742
+
701
743
  kcr_username, kcr_password, registry_kind = resolve_registry_credentials(registry)
702
-
744
+
703
745
  # 检查是否匹配当前 registry (支持部分匹配)
704
746
  if registry not in kcr_registry and kcr_registry not in registry:
705
747
  return False
706
-
748
+
707
749
  if not kcr_username or not kcr_password:
708
750
  print_registry_credentials_help(registry, kind=registry_kind)
709
751
  return False
710
-
752
+
711
753
  click.echo(f"🔐 使用 .env 中的凭证登录 {registry}...")
712
754
  try:
713
755
  result = subprocess.run(
714
- ['docker', 'login', registry, '-u', kcr_username, '--password-stdin'],
756
+ ["docker", "login", registry, "-u", kcr_username, "--password-stdin"],
715
757
  input=kcr_password,
716
758
  capture_output=True,
717
759
  text=True,
718
- timeout=30
760
+ timeout=30,
719
761
  )
720
762
  if result.returncode == 0:
721
- click.secho(f"✅ 登录成功", fg='green')
763
+ click.secho("✅ 登录成功", fg="green")
722
764
  return True
723
765
  else:
724
- click.secho(f"⚠️ 自动登录失败: {result.stderr.strip()}", fg='yellow')
766
+ click.secho(f"⚠️ 自动登录失败: {result.stderr.strip()}", fg="yellow")
725
767
  return False
726
768
  except Exception as e:
727
- click.secho(f"⚠️ 自动登录异常: {e}", fg='yellow')
769
+ click.secho(f"⚠️ 自动登录异常: {e}", fg="yellow")
728
770
  return False
729
-
771
+
730
772
  def get_registry_credentials(self, registry: str | None = None) -> dict:
731
773
  """获取镜像仓库凭证 (用于传给 Serverless)
732
-
774
+
733
775
  返回扁平化结构: {"username": "...", "password": "..."}
734
776
  """
735
777
  import os
778
+
736
779
  from dotenv import load_dotenv
737
-
780
+
738
781
  load_dotenv()
739
-
782
+
740
783
  registry = registry or os.getenv("KCR_REGISTRY", "")
741
784
  username, password, _ = resolve_registry_credentials(registry)
742
-
785
+
743
786
  if username and password:
744
- return {
745
- 'username': username,
746
- 'password': password
747
- }
787
+ return {"username": username, "password": password}
748
788
  return {}
749
-
789
+
750
790
  def _extract_registry(self, image_name: str) -> Optional[str]:
751
791
  """从镜像名称提取仓库地址"""
752
792
  # 格式: registry/namespace/image:tag 或 namespace/image:tag (默认 docker.io)
753
- parts = image_name.split('/')
754
- if len(parts) >= 2 and ('.' in parts[0] or ':' in parts[0]):
793
+ parts = image_name.split("/")
794
+ if len(parts) >= 2 and ("." in parts[0] or ":" in parts[0]):
755
795
  return parts[0]
756
796
  return None # 使用默认 docker.io
757
-
797
+
758
798
  def _check_registry_auth(self, registry: str) -> bool:
759
799
  """检查是否已登录镜像仓库"""
760
800
  try:
761
801
  # 尝试获取 docker 配置
762
802
  import json
763
803
  from pathlib import Path
764
-
765
- docker_config = Path.home() / '.docker' / 'config.json'
804
+
805
+ docker_config = Path.home() / ".docker" / "config.json"
766
806
  if docker_config.exists():
767
807
  with open(docker_config) as f:
768
808
  config = json.load(f)
769
- auths = config.get('auths', {})
809
+ auths = config.get("auths", {})
770
810
  # 检查是否有该仓库的认证信息
771
- if registry in auths or f'https://{registry}' in auths:
811
+ if registry in auths or f"https://{registry}" in auths:
772
812
  return True
773
-
813
+
774
814
  # 没有找到认证信息,提示用户
775
- click.secho(f"\n⚠️ 未检测到 {registry} 的登录凭证", fg='yellow')
815
+ click.secho(f"\n⚠️ 未检测到 {registry} 的登录凭证", fg="yellow")
776
816
  self._print_auth_help(registry)
777
817
  return False
778
818
  except Exception:
779
819
  # 无法检查,继续尝试推送
780
820
  return True
781
-
821
+
782
822
  def _print_auth_help(self, registry: str):
783
823
  """打印认证帮助信息"""
784
824
  print_registry_credentials_help(registry)