agentengine-sdk-python 0.7.0__py3-none-any.whl → 0.8.0__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 (371) hide show
  1. {agentengine_sdk_python-0.7.0.dist-info → agentengine_sdk_python-0.8.0.dist-info}/METADATA +36 -20
  2. agentengine_sdk_python-0.8.0.dist-info/RECORD +578 -0
  3. ksadk/a2a/__init__.py +178 -11
  4. ksadk/a2a/bootstrap.py +334 -0
  5. ksadk/a2a/card.py +120 -0
  6. ksadk/a2a/context_store.py +203 -0
  7. ksadk/a2a/control_plane.py +818 -0
  8. ksadk/a2a/credential.py +99 -0
  9. ksadk/a2a/event_adapter.py +149 -0
  10. ksadk/a2a/executor.py +406 -89
  11. ksadk/a2a/external_transport.py +516 -0
  12. ksadk/a2a/identity.py +304 -0
  13. ksadk/a2a/ids.py +22 -0
  14. ksadk/a2a/langgraph.py +285 -0
  15. ksadk/a2a/resume_store.py +201 -0
  16. ksadk/a2a/routes.py +105 -0
  17. ksadk/a2a/server.py +107 -60
  18. ksadk/a2a/space_client.py +1101 -0
  19. ksadk/a2a/task_adapter.py +423 -0
  20. ksadk/a2a/task_event_dispatcher.py +167 -0
  21. ksadk/a2a/task_event_outbox.py +326 -0
  22. ksadk/a2a/task_store.py +206 -0
  23. ksadk/a2ui/__init__.py +27 -0
  24. ksadk/a2ui/core.py +186 -0
  25. ksadk/a2ui/models.py +166 -0
  26. ksadk/a2ui/renderer.py +198 -0
  27. ksadk/agui/__init__.py +9 -0
  28. ksadk/agui/a2ui_projection.py +92 -0
  29. ksadk/agui/agent.py +857 -0
  30. ksadk/agui/config.py +86 -0
  31. ksadk/agui/routes.py +55 -0
  32. ksadk/api/client.py +233 -191
  33. ksadk/builders/__init__.py +2 -0
  34. ksadk/builders/base.py +16 -14
  35. ksadk/builders/code_builder.py +318 -236
  36. ksadk/builders/container_builder.py +187 -167
  37. ksadk/builders/framework_requirements.py +29 -11
  38. ksadk/builders/ks3_uploader.py +58 -27
  39. ksadk/builders/managed_runtime_builder.py +145 -0
  40. ksadk/builders/mcp_builder.py +91 -92
  41. ksadk/builders/requirements_utils.py +1 -5
  42. ksadk/cli/__init__.py +89 -171
  43. ksadk/cli/cmd_a2a.py +254 -70
  44. ksadk/cli/cmd_agent.py +19 -5
  45. ksadk/cli/cmd_build.py +158 -29
  46. ksadk/cli/cmd_completion.py +47 -35
  47. ksadk/cli/cmd_config.py +267 -198
  48. ksadk/cli/cmd_create.py +500 -720
  49. ksadk/cli/cmd_dashboard.py +120 -45
  50. ksadk/cli/cmd_deploy.py +117 -58
  51. ksadk/cli/cmd_destroy.py +44 -14
  52. ksadk/cli/cmd_files.py +63 -24
  53. ksadk/cli/cmd_hermes.py +168 -89
  54. ksadk/cli/cmd_invoke.py +184 -122
  55. ksadk/cli/cmd_launch.py +64 -28
  56. ksadk/cli/cmd_mcp.py +98 -64
  57. ksadk/cli/cmd_model.py +14 -5
  58. ksadk/cli/cmd_openclaw.py +483 -227
  59. ksadk/cli/cmd_replay.py +71 -0
  60. ksadk/cli/cmd_run.py +33 -10
  61. ksadk/cli/cmd_status.py +80 -31
  62. ksadk/cli/cmd_version.py +20 -13
  63. ksadk/cli/cmd_web.py +89 -13
  64. ksadk/cli/deploy_utils.py +20 -20
  65. ksadk/cli/dry_run.py +5 -3
  66. ksadk/cli/error_utils.py +37 -12
  67. ksadk/cli/global_options.py +1 -2
  68. ksadk/cli/local_runtime.py +1 -2
  69. ksadk/cli/model_catalog.py +6 -2
  70. ksadk/cli/network_options.py +34 -14
  71. ksadk/cli/resource_common.py +6 -2
  72. ksadk/cli/storage.py +0 -1
  73. ksadk/cli/ui.py +5 -3
  74. ksadk/cli/workflow_common.py +51 -17
  75. ksadk/codex/__init__.py +12 -0
  76. ksadk/codex/client.py +408 -0
  77. ksadk/codex/phase.py +143 -0
  78. ksadk/codex/runtime.py +449 -0
  79. ksadk/common/aicp_env.py +0 -1
  80. ksadk/common/auth.py +2 -2
  81. ksadk/common/constants.py +1 -3
  82. ksadk/common/llm_utils.py +17 -13
  83. ksadk/compat/__init__.py +5 -0
  84. ksadk/compat/adk_compat.py +200 -0
  85. ksadk/compat/copilotkit_a2ui.py +330 -0
  86. ksadk/configs/__init__.py +12 -12
  87. ksadk/configs/env_registry.py +500 -100
  88. ksadk/configs/global_config.py +2 -1
  89. ksadk/configs/settings.py +151 -124
  90. ksadk/conversations/__init__.py +7 -5
  91. ksadk/conversations/attachment_storage.py +16 -11
  92. ksadk/conversations/attachments.py +44 -36
  93. ksadk/conversations/compaction_pipeline.py +12 -12
  94. ksadk/conversations/compaction_prompt.py +9 -5
  95. ksadk/conversations/context.py +221 -6
  96. ksadk/conversations/message_projection.py +438 -51
  97. ksadk/conversations/model_context.py +12 -6
  98. ksadk/conversations/model_options.py +0 -1
  99. ksadk/conversations/normalize.py +20 -16
  100. ksadk/conversations/reasoning_markup.py +1 -1
  101. ksadk/conversations/runtime.py +339 -5255
  102. ksadk/conversations/runtime_compaction.py +333 -0
  103. ksadk/conversations/runtime_constants.py +27 -0
  104. ksadk/conversations/runtime_governance.py +185 -0
  105. ksadk/conversations/runtime_input.py +652 -0
  106. ksadk/conversations/runtime_invocation.py +395 -0
  107. ksadk/conversations/runtime_metadata.py +475 -0
  108. ksadk/conversations/runtime_observability.py +355 -0
  109. ksadk/conversations/runtime_payloads.py +272 -0
  110. ksadk/conversations/runtime_persistence.py +440 -0
  111. ksadk/conversations/runtime_preparation.py +418 -0
  112. ksadk/conversations/runtime_resume.py +816 -0
  113. ksadk/conversations/runtime_stream_events.py +902 -0
  114. ksadk/conversations/runtime_streaming.py +547 -0
  115. ksadk/conversations/semantic_summary.py +17 -5
  116. ksadk/conversations/session_title.py +6 -3
  117. ksadk/deployment/__init__.py +15 -16
  118. ksadk/deployment/agent_access.py +12 -23
  119. ksadk/deployment/base.py +51 -38
  120. ksadk/deployment/manager.py +63 -65
  121. ksadk/deployment/providers/serverless.py +309 -202
  122. ksadk/deployment/registry.py +38 -32
  123. ksadk/deployment/state.py +11 -11
  124. ksadk/deployment/ui_config.py +1 -1
  125. ksadk/detection/__init__.py +1 -1
  126. ksadk/detection/detector.py +146 -83
  127. ksadk/detection/mcp_detector.py +9 -6
  128. ksadk/events/__init__.py +25 -0
  129. ksadk/events/parser.py +191 -0
  130. ksadk/events/replay.py +37 -0
  131. ksadk/events/runtime_event.py +264 -0
  132. ksadk/events/store.py +317 -0
  133. ksadk/harness/__init__.py +34 -0
  134. ksadk/harness/app.py +278 -0
  135. ksadk/harness/config.py +181 -0
  136. ksadk/harness/reasoner.py +105 -0
  137. ksadk/harness/runner.py +211 -0
  138. ksadk/harness/sandbox.py +141 -0
  139. ksadk/harness/tools.py +222 -0
  140. ksadk/hermes_terminal.py +23 -12
  141. ksadk/identity/resolver.py +15 -9
  142. ksadk/ids.py +32 -0
  143. ksadk/knowledge_base/adk_tool.py +1 -1
  144. ksadk/knowledge_base/client.py +23 -29
  145. ksadk/managed_runtime.py +188 -0
  146. ksadk/markdown.py +5 -2
  147. ksadk/mcp_runtime/__init__.py +9 -6
  148. ksadk/memory/__init__.py +1 -1
  149. ksadk/memory/adk/__init__.py +2 -0
  150. ksadk/memory/adk/backends/base_ltm_backend.py +2 -6
  151. ksadk/memory/adk/backends/http_ltm_backend.py +13 -21
  152. ksadk/memory/adk/backends/inmemory_ltm_backend.py +7 -13
  153. ksadk/memory/adk/backends/sdk_ltm_backend.py +26 -33
  154. ksadk/memory/adk/long_term_memory.py +31 -35
  155. ksadk/memory/adk/resilient_session_service.py +4 -5
  156. ksadk/memory/adk/short_term_memory.py +12 -21
  157. ksadk/memory/adk_tool.py +3 -2
  158. ksadk/memory/backends/base.py +19 -19
  159. ksadk/memory/backends/memory.py +24 -25
  160. ksadk/memory/backends/redis.py +31 -30
  161. ksadk/memory/langchain_tool.py +2 -1
  162. ksadk/memory/manager.py +52 -47
  163. ksadk/memory/service.py +10 -8
  164. ksadk/model_policy.py +15 -7
  165. ksadk/model_proxy/__init__.py +51 -0
  166. ksadk/model_proxy/bootstrap.py +80 -0
  167. ksadk/model_proxy/cache.py +165 -0
  168. ksadk/model_proxy/config.py +45 -0
  169. ksadk/model_proxy/demo_webui.py +115 -0
  170. ksadk/model_proxy/detect.py +145 -0
  171. ksadk/model_proxy/gate.py +68 -0
  172. ksadk/model_proxy/namespace.py +173 -0
  173. ksadk/model_proxy/protocol_proxy.py +22 -0
  174. ksadk/model_proxy/server.py +300 -0
  175. ksadk/model_proxy/transform.py +691 -0
  176. ksadk/openclaw_gateway.py +29 -14
  177. ksadk/runners/adk_runner.py +345 -120
  178. ksadk/runners/base_runner.py +46 -29
  179. ksadk/runners/codex_runner.py +132 -0
  180. ksadk/runners/deepagents_runner.py +0 -1
  181. ksadk/runners/factory.py +17 -5
  182. ksadk/runners/langchain_runner.py +29 -742
  183. ksadk/runners/langgraph_runner.py +352 -90
  184. ksadk/runners/patch_langchain.py +16 -16
  185. ksadk/runners/remote_runner.py +134 -33
  186. ksadk/runners/usage_accumulator.py +1 -0
  187. ksadk/runners/utils/langfuse.py +3 -3
  188. ksadk/runners/utils/loader.py +7 -7
  189. ksadk/runtime/__init__.py +41 -0
  190. ksadk/runtime/adapter.py +345 -0
  191. ksadk/runtime/framework_adapters.py +124 -0
  192. ksadk/runtime/preprocessing.py +118 -0
  193. ksadk/runtime/runner_adapter.py +873 -0
  194. ksadk/runtime_context.py +18 -3
  195. ksadk/runtime_state.py +0 -1
  196. ksadk/sandbox/__init__.py +4 -1
  197. ksadk/sandbox/backends/__init__.py +4 -1
  198. ksadk/sandbox/backends/e2b.py +13 -5
  199. ksadk/sandbox/backends/local_process.py +11 -3
  200. ksadk/sandbox/base.py +10 -15
  201. ksadk/sandbox/factory.py +14 -4
  202. ksadk/sandbox/registry.py +57 -6
  203. ksadk/server/api_models.py +15 -5
  204. ksadk/server/app.py +455 -3885
  205. ksadk/server/composition.py +21 -0
  206. ksadk/server/factory.py +624 -0
  207. ksadk/server/routes/__init__.py +1 -0
  208. ksadk/server/routes/checkpoint_resolution.py +116 -0
  209. ksadk/server/routes/common.py +713 -0
  210. ksadk/server/routes/control.py +327 -0
  211. ksadk/server/routes/dependencies.py +98 -0
  212. ksadk/server/routes/misc.py +448 -0
  213. ksadk/server/routes/models.py +443 -0
  214. ksadk/server/routes/openai_compat.py +207 -0
  215. ksadk/server/routes/projection.py +795 -0
  216. ksadk/server/routes/routers.py +52 -0
  217. ksadk/server/routes/run.py +726 -0
  218. ksadk/server/routes/sessions.py +649 -0
  219. ksadk/server/routes/streaming.py +223 -0
  220. ksadk/server/routes/workspace.py +381 -0
  221. ksadk/server/static/assets/{ArtifactsPanel-D-SSn2ee.js → ArtifactsPanel-Cjnqt-8W.js} +1 -1
  222. ksadk/server/static/assets/CodeBlock-BqyqZfuB.js +9 -0
  223. ksadk/server/static/assets/MathMessageMarkdown-BpH7jiFM.js +8 -0
  224. ksadk/server/static/assets/MermaidBlock-DWuxETaJ.js +303 -0
  225. ksadk/server/static/assets/NativeTerminalPanel-MDTopWMO.js +1 -0
  226. ksadk/server/static/assets/{arc-BA13sHc9.js → arc-CFKwSk_B.js} +1 -1
  227. ksadk/server/static/assets/architecture-7EHR7CIX-CynqOWjZ.js +1 -0
  228. ksadk/server/static/assets/{architectureDiagram-3BPJPVTR-DzJzgVoL.js → architectureDiagram-3BPJPVTR-Dej8jX8c.js} +1 -1
  229. ksadk/server/static/assets/{blockDiagram-GPEHLZMM-UTdVcZhn.js → blockDiagram-GPEHLZMM-1F64jqvy.js} +1 -1
  230. ksadk/server/static/assets/{c4Diagram-AAUBKEIU-Dix0GD4m.js → c4Diagram-AAUBKEIU-9q7AUAKb.js} +1 -1
  231. ksadk/server/static/assets/channel-iUGv2N24.js +1 -0
  232. ksadk/server/static/assets/{chunk-2J33WTMH-C2JxuZ42.js → chunk-2J33WTMH-6qgwJm7Q.js} +1 -1
  233. ksadk/server/static/assets/{chunk-4BX2VUAB-Be57QPgD.js → chunk-4BX2VUAB-CsWIQRhc.js} +1 -1
  234. ksadk/server/static/assets/{chunk-55IACEB6-WjSuy4nv.js → chunk-55IACEB6-BK8paA20.js} +1 -1
  235. ksadk/server/static/assets/{chunk-727SXJPM-BOovP-b5.js → chunk-727SXJPM-B-JEhy7h.js} +1 -1
  236. ksadk/server/static/assets/{chunk-AQP2D5EJ-DOmZNmWj.js → chunk-AQP2D5EJ-DYBvMHAa.js} +1 -1
  237. ksadk/server/static/assets/{chunk-FMBD7UC4-DzwlodkU.js → chunk-FMBD7UC4-BGhvzDYt.js} +1 -1
  238. ksadk/server/static/assets/{chunk-ND2GUHAM-DMqAikEU.js → chunk-ND2GUHAM-D98vPd-E.js} +1 -1
  239. ksadk/server/static/assets/chunk-QZHKN3VN-YQIEXeF6.js +1 -0
  240. ksadk/server/static/assets/classDiagram-4FO5ZUOK-CDAUuoXK.js +1 -0
  241. ksadk/server/static/assets/classDiagram-v2-Q7XG4LA2-CDAUuoXK.js +1 -0
  242. ksadk/server/static/assets/{cose-bilkent-S5V4N54A-Zhy2GBnP.js → cose-bilkent-S5V4N54A-CX3yotHq.js} +1 -1
  243. ksadk/server/static/assets/{dagre-BM42HDAG-CbKrtIUz.js → dagre-BM42HDAG-C7TguAWo.js} +1 -1
  244. ksadk/server/static/assets/{diagram-2AECGRRQ-BRApgQRK.js → diagram-2AECGRRQ-Dd17_kws.js} +1 -1
  245. ksadk/server/static/assets/{diagram-5GNKFQAL-D0xbnDiK.js → diagram-5GNKFQAL-DVIClIil.js} +1 -1
  246. ksadk/server/static/assets/{diagram-KO2AKTUF-CVugVI9L.js → diagram-KO2AKTUF-Df_3gYQa.js} +1 -1
  247. ksadk/server/static/assets/{diagram-LMA3HP47-DozUGgee.js → diagram-LMA3HP47-BhLk6ZtA.js} +1 -1
  248. ksadk/server/static/assets/{diagram-OG6HWLK6-ZOYsKlru.js → diagram-OG6HWLK6-D4GNGvuu.js} +1 -1
  249. ksadk/server/static/assets/{dist-DmFaq_Iy.js → dist-6CVKuTAe.js} +1 -1
  250. ksadk/server/static/assets/{dist-8EEyGgDx.js → dist-BUHRxvDG.js} +1 -1
  251. ksadk/server/static/assets/{dist-B0NP_Z0z.js → dist-BZ9n9AjO.js} +1 -1
  252. ksadk/server/static/assets/{dist-DMezvBGJ.js → dist-BibcG1V9.js} +1 -1
  253. ksadk/server/static/assets/{dist-C3HIIaN5.js → dist-Bs-jQcRX.js} +1 -1
  254. ksadk/server/static/assets/{dist-BrCcQ47T.js → dist-C2xjE7cO.js} +1 -1
  255. ksadk/server/static/assets/{dist-Dp0k7bWI.js → dist-C7-3jInC.js} +1 -1
  256. ksadk/server/static/assets/{dist-D-xOD048.js → dist-C99THtIA.js} +1 -1
  257. ksadk/server/static/assets/{dist-CkEKJFtk.js → dist-CGcp2ex8.js} +1 -1
  258. ksadk/server/static/assets/{dist-DyOkZmze.js → dist-CVQRZjPu.js} +1 -1
  259. ksadk/server/static/assets/{dist-BssVmjIo.js → dist-Cf23NY4L.js} +1 -1
  260. ksadk/server/static/assets/{dist-BIJVDMuB.js → dist-CgF3fj15.js} +1 -1
  261. ksadk/server/static/assets/{dist-2hInLS_J.js → dist-Cwt7koer.js} +1 -1
  262. ksadk/server/static/assets/{dist-DyWsb78Q.js → dist-D82mtD2s.js} +1 -1
  263. ksadk/server/static/assets/{dist-D-JMdWPQ.js → dist-DF06ORQo.js} +1 -1
  264. ksadk/server/static/assets/{dist-BmlMPsCc.js → dist-DHn6nBzr.js} +1 -1
  265. ksadk/server/static/assets/{dist-gX6GOLKq.js → dist-Djgl2wVZ.js} +1 -1
  266. ksadk/server/static/assets/{dist-DpKtt4Bo.js → dist-DlzCRy0S.js} +1 -1
  267. ksadk/server/static/assets/{dist-8_SfK1IP.js → dist-DqNnNFrw.js} +1 -1
  268. ksadk/server/static/assets/{dist-D57wnGWd.js → dist-DyvYLMW9.js} +1 -1
  269. ksadk/server/static/assets/{dist-CPBtqRTW.js → dist-eoW6tZXA.js} +1 -1
  270. ksadk/server/static/assets/{dist-DL_NKc_z.js → dist-ivOya1LD.js} +1 -1
  271. ksadk/server/static/assets/{erDiagram-TEJ5UH35-Bk-9bgE5.js → erDiagram-TEJ5UH35-CnfRcY2M.js} +1 -1
  272. ksadk/server/static/assets/eventmodeling-FCH6USID-ChYO-ijM.js +1 -0
  273. ksadk/server/static/assets/{flowDiagram-I6XJVG4X-Dn9kZVuZ.js → flowDiagram-I6XJVG4X-DGaJjGNJ.js} +1 -1
  274. ksadk/server/static/assets/{ganttDiagram-6RSMTGT7-BGxXlJqm.js → ganttDiagram-6RSMTGT7-DpCoB2g9.js} +1 -1
  275. ksadk/server/static/assets/gitGraph-WXDBUCRP-BN_0Fk-j.js +1 -0
  276. ksadk/server/static/assets/{gitGraphDiagram-PVQCEYII-C7Q0X-wi.js → gitGraphDiagram-PVQCEYII-9IKVFBVT.js} +1 -1
  277. ksadk/server/static/assets/index-QSwCHuB8.js +177 -0
  278. ksadk/server/static/assets/index-jOPmTOZH.css +2 -0
  279. ksadk/server/static/assets/info-J43DQDTF-Cp6o3vId.js +1 -0
  280. ksadk/server/static/assets/{infoDiagram-5YYISTIA-BO_CSqq5.js → infoDiagram-5YYISTIA-CYIIsb8y.js} +1 -1
  281. ksadk/server/static/assets/{ishikawaDiagram-YF4QCWOH-eYLPLd46.js → ishikawaDiagram-YF4QCWOH-DLOHGvWw.js} +1 -1
  282. ksadk/server/static/assets/{journeyDiagram-JHISSGLW-De9geSb0.js → journeyDiagram-JHISSGLW-BIzKeejT.js} +1 -1
  283. ksadk/server/static/assets/{kanban-definition-UN3LZRKU-Cs80kQto.js → kanban-definition-UN3LZRKU-BWHoFSw2.js} +1 -1
  284. ksadk/server/static/assets/{katex-DSrCFD8n.js → katex-DATssjp1.js} +1 -1
  285. ksadk/server/static/assets/{linear-CN9sbKTF.js → linear-CvMBw9cA.js} +1 -1
  286. ksadk/server/static/assets/{mermaid-parser.core-DlgSBU8l.js → mermaid-parser.core-mGAcEwcq.js} +2 -2
  287. ksadk/server/static/assets/{mindmap-definition-RKZ34NQL-9afz7Oug.js → mindmap-definition-RKZ34NQL-CSAQxEAe.js} +1 -1
  288. ksadk/server/static/assets/packet-YPE3B663-wQzct3cT.js +1 -0
  289. ksadk/server/static/assets/pie-LRSECV5Y-BgTQiv-9.js +1 -0
  290. ksadk/server/static/assets/{pieDiagram-4H26LBE5-DPv_VstN.js → pieDiagram-4H26LBE5-By-ra07M.js} +1 -1
  291. ksadk/server/static/assets/{quadrantDiagram-W4KKPZXB-o77wZ1XK.js → quadrantDiagram-W4KKPZXB-CxIR4JXI.js} +1 -1
  292. ksadk/server/static/assets/radar-GUYGQ44K-BIq5fXsn.js +1 -0
  293. ksadk/server/static/assets/{requirementDiagram-4Y6WPE33-BYVw81VC.js → requirementDiagram-4Y6WPE33-DpW90iu3.js} +1 -1
  294. ksadk/server/static/assets/{sankeyDiagram-5OEKKPKP-B7nZFMKT.js → sankeyDiagram-5OEKKPKP-DpGa6EAV.js} +1 -1
  295. ksadk/server/static/assets/{sequenceDiagram-3UESZ5HK-BGRRrFw5.js → sequenceDiagram-3UESZ5HK-NTKNGGe5.js} +1 -1
  296. ksadk/server/static/assets/{stateDiagram-AJRCARHV-BUfHCoPs.js → stateDiagram-AJRCARHV-DGpd9yFG.js} +1 -1
  297. ksadk/server/static/assets/stateDiagram-v2-BHNVJYJU-B3o579IQ.js +1 -0
  298. ksadk/server/static/assets/{timeline-definition-PNZ67QCA-FbCTGrf9.js → timeline-definition-PNZ67QCA-jqoYs3jQ.js} +1 -1
  299. ksadk/server/static/assets/treeView-BLDUP644-Dqi-E0EM.js +1 -0
  300. ksadk/server/static/assets/treemap-LRROVOQU-ClQP9CJ9.js +1 -0
  301. ksadk/server/static/assets/{vennDiagram-CIIHVFJN-DWgwtPsJ.js → vennDiagram-CIIHVFJN-l3Z7-wbP.js} +1 -1
  302. ksadk/server/static/assets/wardley-L42UT6IY-8XLvnNIs.js +1 -0
  303. ksadk/server/static/assets/{wardleyDiagram-YWT4CUSO-2x8G-tTM.js → wardleyDiagram-YWT4CUSO-BR54GPmr.js} +1 -1
  304. ksadk/server/static/assets/{xychartDiagram-2RQKCTM6-Drma3AYl.js → xychartDiagram-2RQKCTM6-SkiH8GsK.js} +1 -1
  305. ksadk/server/static/index.html +2 -2
  306. ksadk/server/terminal_sessions.py +111 -58
  307. ksadk/sessions/__init__.py +69 -19
  308. ksadk/sessions/base.py +31 -11
  309. ksadk/sessions/continuity.py +2 -3
  310. ksadk/sessions/in_memory.py +46 -2
  311. ksadk/sessions/local_service.py +148 -17
  312. ksadk/sessions/postgres_service.py +143 -25
  313. ksadk/sessions/resilient.py +36 -8
  314. ksadk/skills/models.py +17 -5
  315. ksadk/skills/package_store.py +5 -2
  316. ksadk/skills/runtime/agent.py +20 -5
  317. ksadk/skills/runtime/artifacts.py +1 -5
  318. ksadk/skills/runtime/backends/e2b.py +10 -4
  319. ksadk/skills/runtime/backends/local.py +15 -3
  320. ksadk/skills/runtime/base.py +1 -2
  321. ksadk/skills/runtime/executor.py +10 -3
  322. ksadk/skills/runtime/factory.py +4 -2
  323. ksadk/skills/runtime/loader.py +1 -2
  324. ksadk/skills/runtime/registry.py +15 -10
  325. ksadk/skills/runtime/request.py +3 -1
  326. ksadk/skills/service_client.py +38 -17
  327. ksadk/skills/tool_defs.py +15 -10
  328. ksadk/terminal_exec_policy.py +3 -4
  329. ksadk/tools/gateway.py +92 -15
  330. ksadk/tools/result_budget.py +12 -4
  331. ksadk/toolsets/__init__.py +134 -36
  332. ksadk/toolsets/platform.py +21 -5
  333. ksadk/toolsets/sandbox.py +82 -16
  334. ksadk/toolsets/skills.py +200 -39
  335. ksadk/toolsets/web.py +123 -26
  336. ksadk/toolsets/workspace.py +212 -101
  337. ksadk/tracing/exporters/inmemory_exporter.py +62 -51
  338. ksadk/tracing/exporters/langfuse_exporter.py +91 -76
  339. ksadk/tracing/setup.py +69 -53
  340. ksadk/tracing/span_utils.py +5 -2
  341. ksadk/tui/loop.py +78 -30
  342. ksadk/tui/stream_render.py +1 -0
  343. ksadk/ui_config.py +5 -3
  344. ksadk/version.py +1 -1
  345. ksadk_runtime_common/schemas/runtime_event_v1.json +95 -0
  346. agentengine_sdk_python-0.7.0.dist-info/RECORD +0 -482
  347. ksadk/server/static/assets/CodeBlock-P16VOLYi.js +0 -9
  348. ksadk/server/static/assets/MathMessageMarkdown-CdGiQWHR.js +0 -8
  349. ksadk/server/static/assets/MermaidBlock-IOcal8cm.js +0 -303
  350. ksadk/server/static/assets/NativeTerminalPanel-DGSDWsei.js +0 -1
  351. ksadk/server/static/assets/architecture-7EHR7CIX-BvUlsA6l.js +0 -1
  352. ksadk/server/static/assets/channel-CTuydARX.js +0 -1
  353. ksadk/server/static/assets/chunk-QZHKN3VN-BnCydivS.js +0 -1
  354. ksadk/server/static/assets/classDiagram-4FO5ZUOK-BNHg45Be.js +0 -1
  355. ksadk/server/static/assets/classDiagram-v2-Q7XG4LA2-BNHg45Be.js +0 -1
  356. ksadk/server/static/assets/eventmodeling-FCH6USID-DsAgWnlf.js +0 -1
  357. ksadk/server/static/assets/gitGraph-WXDBUCRP-BIao9Yjg.js +0 -1
  358. ksadk/server/static/assets/index-C00Lwg3L.js +0 -165
  359. ksadk/server/static/assets/index-DAURbCsP.css +0 -1
  360. ksadk/server/static/assets/info-J43DQDTF-CyipqGxU.js +0 -1
  361. ksadk/server/static/assets/packet-YPE3B663-CGkyRxlg.js +0 -1
  362. ksadk/server/static/assets/pie-LRSECV5Y-M0uWAf4n.js +0 -1
  363. ksadk/server/static/assets/radar-GUYGQ44K-Bdbm24-x.js +0 -1
  364. ksadk/server/static/assets/stateDiagram-v2-BHNVJYJU-8xBN_gLM.js +0 -1
  365. ksadk/server/static/assets/treeView-BLDUP644-npMo0ak1.js +0 -1
  366. ksadk/server/static/assets/treemap-LRROVOQU-CHdzrrdo.js +0 -1
  367. ksadk/server/static/assets/wardley-L42UT6IY-BEQz7wyy.js +0 -1
  368. {agentengine_sdk_python-0.7.0.dist-info → agentengine_sdk_python-0.8.0.dist-info}/WHEEL +0 -0
  369. {agentengine_sdk_python-0.7.0.dist-info → agentengine_sdk_python-0.8.0.dist-info}/entry_points.txt +0 -0
  370. {agentengine_sdk_python-0.7.0.dist-info → agentengine_sdk_python-0.8.0.dist-info}/licenses/LICENSE +0 -0
  371. {agentengine_sdk_python-0.7.0.dist-info → agentengine_sdk_python-0.8.0.dist-info}/top_level.txt +0 -0
ksadk/configs/settings.py CHANGED
@@ -6,32 +6,34 @@ AgentEngine 统一配置管理
6
6
 
7
7
  使用方式:
8
8
  from ksadk.configs import settings
9
-
9
+
10
10
  # 访问模型配置
11
11
  print(settings.model.api_key)
12
12
  print(settings.model.api_base)
13
-
13
+
14
14
  # 访问 Langfuse 配置
15
15
  print(settings.langfuse.public_key)
16
-
16
+
17
17
  # 访问 Agent 运行时信息
18
18
  print(settings.agent.agent_id)
19
19
  """
20
20
 
21
- import os
21
+ import importlib
22
22
  import json
23
23
  import logging
24
+ import os
24
25
  import time
25
- from typing import Optional, List, Dict, Any
26
26
  from dataclasses import dataclass, field
27
+ from pathlib import Path
28
+ from typing import Any, Dict, List, Optional
27
29
  from urllib.parse import urlsplit, urlunsplit
28
30
 
29
31
  logger = logging.getLogger(__name__)
30
32
 
31
33
 
32
- def _get_env(*keys: str, default: str = None) -> Optional[str]:
34
+ def _get_env(*keys: str, default: Optional[str] = None) -> Optional[str]:
33
35
  """从多个环境变量 key 中获取第一个存在的值
34
-
36
+
35
37
  按优先级顺序匹配,支持别名兼容。
36
38
  """
37
39
  for key in keys:
@@ -69,44 +71,45 @@ def _is_public_kspmas_url(url: Optional[str]) -> bool:
69
71
 
70
72
  def check_endpoint_reachable(host: str, port: int = 80, timeout: float = 1.0) -> bool:
71
73
  """检测指定端点是否可达
72
-
74
+
73
75
  通用函数,可用于检测任意服务的内网地址是否可达。
74
76
  结果会被缓存,相同 host 只检测一次。
75
-
77
+
76
78
  Args:
77
79
  host: 主机名或 IP 地址
78
80
  port: 端口号 (默认 80)
79
81
  timeout: 超时时间 (默认 1.0 秒)
80
-
82
+
81
83
  Returns:
82
84
  True 如果可达, False 否则
83
-
85
+
84
86
  Usage:
85
87
  # KSPMAS 内网检测
86
88
  if check_endpoint_reachable("kspmas-internal.sdns.ksyun.com"):
87
89
  api_base = "http://kspmas-internal.sdns.ksyun.com/v1"
88
-
90
+
89
91
  # KS3 内网检测
90
92
  if check_endpoint_reachable("ks3-cn-beijing-internal.ksyuncs.com"):
91
93
  ks3_endpoint = "http://ks3-cn-beijing-internal.ksyuncs.com"
92
94
  """
93
95
  if host in _endpoint_cache:
94
96
  return _endpoint_cache[host]
95
-
97
+
96
98
  try:
97
99
  import socket
100
+
98
101
  # 尝试建立 TCP 连接 (比 ping 更可靠,且不依赖 ICMP)
99
102
  s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
100
103
  s.settimeout(timeout)
101
104
  s.connect((host, port))
102
105
  s.close()
103
-
106
+
104
107
  _endpoint_cache[host] = True
105
108
  logger.debug(f"Endpoint reachable: {host}:{port}")
106
109
  except (socket.timeout, socket.error, OSError):
107
110
  _endpoint_cache[host] = False
108
111
  logger.debug(f"Endpoint not reachable: {host}:{port}")
109
-
112
+
110
113
  return _endpoint_cache[host]
111
114
 
112
115
 
@@ -125,13 +128,13 @@ DEFAULT_MODEL_NAME = "glm-5.2"
125
128
 
126
129
  def optimize_kspmas_url(url: str) -> str:
127
130
  """优化 KSPMAS URL
128
-
131
+
129
132
  如果是 KSPMAS 的公网地址,且检测到内网可达(或在 Serverless 环境),
130
133
  将其替换为内网地址以提高速度和稳定性。
131
134
  """
132
135
  if not url:
133
136
  return url
134
-
137
+
135
138
  parsed = urlsplit(url)
136
139
  if parsed.hostname != "kspmas.ksyun.com":
137
140
  return url
@@ -147,13 +150,13 @@ def optimize_kspmas_url(url: str) -> str:
147
150
  if parsed.port:
148
151
  netloc = f"{netloc}:{parsed.port}"
149
152
  return urlunsplit(("http", netloc, parsed.path, parsed.query, parsed.fragment))
150
-
153
+
151
154
  return url
152
155
 
153
156
 
154
157
  def get_kspmas_api_base() -> str:
155
158
  """获取 KSPMAS 模型服务的 API Base URL
156
-
159
+
157
160
  自动检测内网可达性,优先使用内网地址。
158
161
  **特殊逻辑**: 如果在 Serverless 托管环境 (AGENT_RUNTIME_ID 存在),强制使用内网地址。
159
162
  """
@@ -164,7 +167,7 @@ def get_kspmas_api_base() -> str:
164
167
  # 2. 自动检测内网可达性
165
168
  if check_endpoint_reachable(KSPMAS_INTERNAL_HOST):
166
169
  return KSPMAS_INTERNAL_URL
167
-
170
+
168
171
  # 3. 默认使用公网
169
172
  return KSPMAS_PUBLIC_URL
170
173
 
@@ -173,82 +176,83 @@ def get_kspmas_api_base() -> str:
173
176
  # 模型配置 (LLM)
174
177
  # =============================================================================
175
178
 
179
+
176
180
  @dataclass
177
181
  class ModelConfig:
178
182
  """模型配置
179
-
183
+
180
184
  标准环境变量 (优先):
181
185
  OPENAI_API_KEY - API Key (OpenAI 标准)
182
186
  OPENAI_BASE_URL - API Base URL (OpenAI 标准)
183
187
  OPENAI_MODEL_NAME - 模型名称
184
-
188
+
185
189
  通用格式:
186
190
  MODEL_NAME - 模型名称
187
-
191
+
188
192
  Serverless 平台兼容:
189
193
  LLM_API_KEY - 模型 API Key
190
194
  LLM_API_BASE - 模型 API 地址
191
195
  LLM_MODEL - 模型名称
192
-
196
+
193
197
  别名 (兼容):
194
198
  OPENAI_API_BASE - API Base URL 别名
195
-
199
+
196
200
  默认值:
197
201
  OPENAI_BASE_URL: 自动检测内网/外网,使用金山云模型服务
198
202
  MODEL_NAME: glm-5.2
199
203
  """
200
-
204
+
201
205
  @property
202
206
  def api_key(self) -> Optional[str]:
203
207
  """获取模型 API Key"""
204
208
  return _get_env(
205
- "OPENAI_API_KEY", # OpenAI 标准 (优先)
206
- "LLM_API_KEY", # Serverless 平台兼容
207
- "MODEL_API_KEY", # 通用
209
+ "OPENAI_API_KEY", # OpenAI 标准 (优先)
210
+ "LLM_API_KEY", # Serverless 平台兼容
211
+ "MODEL_API_KEY", # 通用
208
212
  )
209
-
213
+
210
214
  @property
211
215
  def api_base(self) -> str:
212
216
  """获取模型 API Base URL
213
-
217
+
214
218
  如果未配置,默认使用金山云模型服务地址(自动检测内网)。
215
219
  如果已配置且为 KSPMAS 公网地址,也会尝试优化为内网地址。
216
220
  """
217
221
  configured = _get_env(
218
- "OPENAI_BASE_URL", # OpenAI 标准 (优先)
219
- "OPENAI_API_BASE", # OpenAI 别名 (兼容)
220
- "LLM_API_BASE", # Serverless 平台兼容
221
- "MODEL_API_BASE", # 通用
222
+ "OPENAI_BASE_URL", # OpenAI 标准 (优先)
223
+ "OPENAI_API_BASE", # OpenAI 别名 (兼容)
224
+ "LLM_API_BASE", # Serverless 平台兼容
225
+ "MODEL_API_BASE", # 通用
222
226
  )
223
-
227
+
224
228
  if configured:
225
229
  return optimize_kspmas_url(configured)
226
-
230
+
227
231
  return get_kspmas_api_base()
228
-
232
+
229
233
  @property
230
234
  def model_name(self) -> str:
231
235
  """获取模型名称
232
-
236
+
233
237
  如果未配置,默认使用 glm-5.2。
234
238
  """
235
239
  configured = _get_env(
236
- "OPENAI_MODEL_NAME", # OpenAI 格式 (优先)
237
- "MODEL_NAME", # 通用
238
- "LLM_MODEL", # Serverless 平台兼容
240
+ "OPENAI_MODEL_NAME", # OpenAI 格式 (优先)
241
+ "MODEL_NAME", # 通用
242
+ "LLM_MODEL", # Serverless 平台兼容
239
243
  )
240
244
  return configured or DEFAULT_MODEL_NAME
241
-
245
+
242
246
  @property
243
247
  def is_configured(self) -> bool:
244
248
  """是否已配置 API Key"""
245
249
  return bool(self.api_key)
246
-
250
+
247
251
  @property
248
252
  def is_using_internal_network(self) -> bool:
249
253
  """是否使用内网地址"""
250
254
  return KSPMAS_INTERNAL_URL in self.api_base
251
-
255
+
252
256
  def to_dict(self) -> dict:
253
257
  """转换为字典 (用于 LiteLLM 等)"""
254
258
  result = {}
@@ -263,56 +267,60 @@ class ModelConfig:
263
267
  # Langfuse 配置
264
268
  # =============================================================================
265
269
 
270
+
266
271
  @dataclass
267
272
  class LangfuseConfig:
268
273
  """Langfuse 可观测性配置
269
-
274
+
270
275
  标准环境变量 (Langfuse 官方):
271
276
  LANGFUSE_PUBLIC_KEY - API Public Key
272
277
  LANGFUSE_SECRET_KEY - API Secret Key
273
278
  LANGFUSE_HOST - Langfuse 服务地址
274
-
279
+
275
280
  Serverless 平台扩展:
276
281
  LANGFUSE_PROJECT_ID - 项目 ID (区分用户)
277
282
  LANGCHAIN_TRACING_V2 - 启用 LangChain 追踪
278
283
  """
279
-
284
+
280
285
  @property
281
286
  def public_key(self) -> Optional[str]:
282
287
  return os.getenv("LANGFUSE_PUBLIC_KEY")
283
-
288
+
284
289
  @property
285
290
  def secret_key(self) -> Optional[str]:
286
291
  return os.getenv("LANGFUSE_SECRET_KEY")
287
-
292
+
288
293
  @property
289
294
  def host(self) -> str:
290
- return _get_env(
291
- "LANGFUSE_HOST",
292
- "LANGFUSE_BASE_URL",
293
- default="http://localhost:3000"
295
+ return (
296
+ _get_env(
297
+ "LANGFUSE_HOST",
298
+ "LANGFUSE_BASE_URL",
299
+ default="http://localhost:3000",
300
+ )
301
+ or "http://localhost:3000"
294
302
  )
295
-
303
+
296
304
  @property
297
305
  def project_id(self) -> Optional[str]:
298
306
  """Langfuse 项目 ID (Serverless 平台扩展)"""
299
307
  return os.getenv("LANGFUSE_PROJECT_ID")
300
-
308
+
301
309
  @property
302
310
  def tracing_enabled(self) -> bool:
303
311
  """是否启用 LangChain tracing"""
304
312
  return os.getenv("LANGCHAIN_TRACING_V2", "").lower() == "true"
305
-
313
+
306
314
  @property
307
315
  def is_enabled(self) -> bool:
308
316
  """是否启用 Langfuse (有 public_key 就启用)"""
309
317
  return bool(self.public_key)
310
-
318
+
311
319
  @property
312
320
  def is_configured(self) -> bool:
313
321
  """是否完整配置"""
314
322
  return bool(self.public_key and self.secret_key)
315
-
323
+
316
324
  def to_dict(self) -> dict:
317
325
  """转换为字典"""
318
326
  return {
@@ -326,14 +334,15 @@ class LangfuseConfig:
326
334
  # Agent 配置
327
335
  # =============================================================================
328
336
 
337
+
329
338
  @dataclass
330
339
  class AgentConfig:
331
340
  """Agent 配置
332
-
341
+
333
342
  标准环境变量 (OpenTelemetry 兼容):
334
343
  OTEL_SERVICE_NAME - 服务名称 (映射到 agent_name)
335
344
  OTEL_RESOURCE_ATTRIBUTES - 资源属性 (key=value 格式)
336
-
345
+
337
346
  通用环境变量:
338
347
  AGENT_ID - Agent 唯一 ID
339
348
  AGENT_NAME - Agent 名称
@@ -341,70 +350,70 @@ class AgentConfig:
341
350
  USER_ID - 用户 ID
342
351
  ENVIRONMENT - 运行环境 (dev/staging/prod)
343
352
  VERSION - 版本号
344
-
353
+
345
354
  Serverless 平台兼容:
346
355
  AGENT_RUNTIME_ID - Agent 唯一 ID
347
356
  AGENT_RUNTIME_NAME - Agent 名称
348
357
  ACCOUNT_ID - 账户 ID (租户)
349
358
  """
350
-
359
+
351
360
  @property
352
361
  def agent_id(self) -> Optional[str]:
353
362
  """Agent 唯一 ID"""
354
363
  return _get_env(
355
- "AGENT_ID", # 通用 (优先)
356
- "AGENT_RUNTIME_ID", # Serverless 平台兼容
364
+ "AGENT_ID", # 通用 (优先)
365
+ "AGENT_RUNTIME_ID", # Serverless 平台兼容
357
366
  )
358
-
367
+
359
368
  @property
360
369
  def agent_name(self) -> Optional[str]:
361
370
  """Agent 名称"""
362
371
  return _get_env(
363
- "AGENT_NAME", # 通用 (优先)
364
- "AGENT_RUNTIME_NAME", # Serverless 平台兼容
365
- "OTEL_SERVICE_NAME", # OpenTelemetry 标准
372
+ "AGENT_NAME", # 通用 (优先)
373
+ "AGENT_RUNTIME_NAME", # Serverless 平台兼容
374
+ "OTEL_SERVICE_NAME", # OpenTelemetry 标准
366
375
  )
367
-
376
+
368
377
  @property
369
378
  def tenant_id(self) -> Optional[str]:
370
379
  """租户 ID"""
371
380
  return _get_env(
372
- "TENANT_ID", # 通用 (优先)
373
- "ACCOUNT_ID", # Serverless 平台兼容
381
+ "TENANT_ID", # 通用 (优先)
382
+ "ACCOUNT_ID", # Serverless 平台兼容
374
383
  )
375
-
384
+
376
385
  @property
377
386
  def user_id(self) -> Optional[str]:
378
387
  """用户 ID"""
379
388
  return os.getenv("USER_ID")
380
-
389
+
381
390
  @property
382
391
  def session_id(self) -> Optional[str]:
383
392
  """会话 ID (用于 Langfuse Sessions 功能)"""
384
393
  return os.getenv("SESSION_ID")
385
-
394
+
386
395
  @property
387
396
  def environment(self) -> Optional[str]:
388
397
  """运行环境 (dev/staging/prod)"""
389
398
  return os.getenv("ENVIRONMENT")
390
-
399
+
391
400
  @property
392
401
  def version(self) -> Optional[str]:
393
402
  """Agent 版本"""
394
403
  return os.getenv("VERSION")
395
-
404
+
396
405
  @property
397
406
  def tags(self) -> Optional[List[str]]:
398
407
  """标签列表 (逗号分隔)"""
399
408
  tags_str = os.getenv("TAGS", "")
400
409
  tags = [t.strip() for t in tags_str.split(",") if t.strip()]
401
410
  return tags if tags else None
402
-
411
+
403
412
  @property
404
413
  def extra_metadata(self) -> Optional[Dict[str, Any]]:
405
414
  """额外的元数据"""
406
415
  extra = {}
407
-
416
+
408
417
  # 1. 解析 JSON 格式的 metadata
409
418
  extra_json = os.getenv("METADATA")
410
419
  if extra_json:
@@ -412,7 +421,7 @@ class AgentConfig:
412
421
  extra.update(json.loads(extra_json))
413
422
  except json.JSONDecodeError:
414
423
  logger.warning(f"Invalid METADATA JSON: {extra_json}")
415
-
424
+
416
425
  # 2. 解析 OTEL_RESOURCE_ATTRIBUTES
417
426
  otel_attrs = os.getenv("OTEL_RESOURCE_ATTRIBUTES", "")
418
427
  if otel_attrs:
@@ -421,21 +430,21 @@ class AgentConfig:
421
430
  key, value = pair.split("=", 1)
422
431
  if key not in ("service.name", "service.version"):
423
432
  extra[key] = value
424
-
433
+
425
434
  return extra if extra else None
426
-
435
+
427
436
  @property
428
437
  def is_configured(self) -> bool:
429
438
  """是否有 Agent 信息"""
430
439
  return bool(self.agent_id or self.agent_name)
431
-
440
+
432
441
  # ------------------
433
442
  # Langfuse 集成方法
434
443
  # ------------------
435
-
444
+
436
445
  def to_langfuse_params(self) -> dict:
437
446
  """转换为 Langfuse trace() 方法的原生参数"""
438
- params = {}
447
+ params: Dict[str, Any] = {}
439
448
  if self.session_id:
440
449
  params["session_id"] = self.session_id
441
450
  if self.user_id:
@@ -445,7 +454,7 @@ class AgentConfig:
445
454
  if self.version:
446
455
  params["version"] = self.version
447
456
  return params
448
-
457
+
449
458
  def to_langfuse_metadata(self) -> dict:
450
459
  """转换为 Langfuse metadata 字段"""
451
460
  metadata = {}
@@ -466,28 +475,29 @@ class AgentConfig:
466
475
  # 金山云配置
467
476
  # =============================================================================
468
477
 
478
+
469
479
  @dataclass
470
480
  class KingsoftCloudConfig:
471
481
  """金山云 SDK 配置
472
-
482
+
473
483
  环境变量:
474
484
  KS_ACCESS_KEY_ID - Access Key ID
475
485
  KS_SECRET_ACCESS_KEY - Secret Access Key
476
486
  KS_REGION - 区域 (默认 cn-beijing-6)
477
487
  """
478
-
488
+
479
489
  @property
480
490
  def access_key_id(self) -> Optional[str]:
481
491
  return os.getenv("KS_ACCESS_KEY_ID")
482
-
492
+
483
493
  @property
484
494
  def secret_access_key(self) -> Optional[str]:
485
495
  return os.getenv("KS_SECRET_ACCESS_KEY")
486
-
496
+
487
497
  @property
488
498
  def region(self) -> str:
489
499
  return os.getenv("KS_REGION", "cn-beijing-6")
490
-
500
+
491
501
  @property
492
502
  def is_configured(self) -> bool:
493
503
  """是否已配置"""
@@ -498,23 +508,24 @@ class KingsoftCloudConfig:
498
508
  # Code 模式配置
499
509
  # =============================================================================
500
510
 
511
+
501
512
  @dataclass
502
513
  class CodeModeConfig:
503
514
  """Code 模式配置 (Serverless 平台)
504
-
515
+
505
516
  环境变量:
506
517
  PYTHONPATH - Python 模块路径
507
518
  CODE_PATH - 代码目录
508
519
  """
509
-
520
+
510
521
  @property
511
522
  def python_path(self) -> Optional[str]:
512
523
  return os.getenv("PYTHONPATH")
513
-
524
+
514
525
  @property
515
526
  def code_path(self) -> Optional[str]:
516
527
  return os.getenv("CODE_PATH")
517
-
528
+
518
529
  @property
519
530
  def is_code_mode(self) -> bool:
520
531
  """是否为 Code 模式"""
@@ -525,41 +536,42 @@ class CodeModeConfig:
525
536
  # OpenTelemetry 配置
526
537
  # =============================================================================
527
538
 
539
+
528
540
  @dataclass
529
541
  class OTelConfig:
530
542
  """OpenTelemetry 配置 (标准环境变量)
531
-
543
+
532
544
  环境变量:
533
545
  OTEL_SERVICE_NAME - 服务名称
534
546
  OTEL_RESOURCE_ATTRIBUTES - 资源属性 (key=value,key2=value2)
535
547
  OTEL_EXPORTER_OTLP_ENDPOINT - OTLP 导出端点
536
548
  """
537
-
549
+
538
550
  @property
539
551
  def service_name(self) -> Optional[str]:
540
552
  return os.getenv("OTEL_SERVICE_NAME")
541
-
553
+
542
554
  @property
543
555
  def resource_attributes(self) -> Optional[Dict[str, str]]:
544
556
  """解析 OTEL_RESOURCE_ATTRIBUTES"""
545
557
  attrs_str = os.getenv("OTEL_RESOURCE_ATTRIBUTES", "")
546
558
  if not attrs_str:
547
559
  return None
548
-
560
+
549
561
  attrs = {}
550
562
  for pair in attrs_str.split(","):
551
563
  if "=" in pair:
552
564
  key, value = pair.split("=", 1)
553
565
  attrs[key] = value
554
566
  return attrs if attrs else None
555
-
567
+
556
568
  @property
557
569
  def otlp_endpoint(self) -> Optional[str]:
558
570
  return _get_env(
559
571
  "OTEL_EXPORTER_OTLP_ENDPOINT",
560
572
  "OTEL_EXPORTER_OTLP_TRACES_ENDPOINT",
561
573
  )
562
-
574
+
563
575
  @property
564
576
  def is_enabled(self) -> bool:
565
577
  """是否启用 OTLP 导出"""
@@ -570,45 +582,52 @@ class OTelConfig:
570
582
  # 统一配置入口
571
583
  # =============================================================================
572
584
 
585
+
573
586
  @dataclass
574
587
  class Settings:
575
588
  """统一配置入口
576
-
589
+
577
590
  使用方式:
578
591
  from ksadk.configs import settings
579
-
592
+
580
593
  # 模型配置
581
594
  if settings.model.is_configured:
582
595
  llm = LiteLLM(api_key=settings.model.api_key)
583
-
596
+
584
597
  # Langfuse 配置
585
598
  if settings.langfuse.is_enabled:
586
599
  setup_tracing(langfuse_config=settings.langfuse.to_dict())
587
-
600
+
588
601
  # Agent 信息
589
602
  print(settings.agent.agent_id)
590
603
  """
604
+
591
605
  model: ModelConfig = field(default_factory=ModelConfig)
592
606
  langfuse: LangfuseConfig = field(default_factory=LangfuseConfig)
593
607
  agent: AgentConfig = field(default_factory=AgentConfig)
594
608
  cloud: KingsoftCloudConfig = field(default_factory=KingsoftCloudConfig)
595
609
  code: CodeModeConfig = field(default_factory=CodeModeConfig)
596
610
  otel: OTelConfig = field(default_factory=OTelConfig)
597
-
611
+
598
612
  def summary(self) -> str:
599
613
  """输出配置摘要"""
600
614
  lines = ["AgentEngine Configuration:"]
601
- lines.append(f" Model: {'✅ Configured' if self.model.is_configured else '❌ Not configured'}")
615
+ lines.append(
616
+ f" Model: {'✅ Configured' if self.model.is_configured else '❌ Not configured'}"
617
+ )
602
618
  lines.append(f" Langfuse: {'✅ Enabled' if self.langfuse.is_enabled else '⚪ Disabled'}")
603
-
619
+
604
620
  agent_info = self.agent.agent_id or self.agent.agent_name
605
621
  lines.append(f" Agent: {'✅ ' + agent_info if agent_info else '⚪ No info'}")
606
-
607
- lines.append(f" Cloud: {'✅ Configured' if self.cloud.is_configured else '⚪ Not configured'}")
608
- lines.append(f" CodeMode: {'✅ ' + self.code.code_path if self.code.is_code_mode else '⚪ Container mode'}")
622
+
623
+ lines.append(
624
+ f" Cloud: {'✅ Configured' if self.cloud.is_configured else '⚪ Not configured'}"
625
+ )
626
+ code_path = self.code.code_path
627
+ lines.append(f" CodeMode: {'✅ ' + code_path if code_path else '⚪ Container mode'}")
609
628
  lines.append(f" OTEL: {'✅ Enabled' if self.otel.is_enabled else '⚪ Disabled'}")
610
629
  return "\n".join(lines)
611
-
630
+
612
631
  def __repr__(self) -> str:
613
632
  return self.summary()
614
633
 
@@ -624,32 +643,30 @@ settings = Settings()
624
643
  DEFAULT_RUNTIME_TIMEZONE = "Asia/Shanghai"
625
644
 
626
645
 
627
- def setup_environment(agent_path: "Path"):
646
+ def setup_environment(agent_path: Path | str):
628
647
  """加载环境变量并注入智能默认配置
629
-
648
+
630
649
  1. 加载项目根目录的 .env 文件 (override=True)
631
650
  2. 注入 OPENAI_API_BASE (智能检测)
632
651
  3. 注入 OPENAI_MODEL_NAME (默认值)
633
652
  """
634
653
  import click
635
- import os
636
- from pathlib import Path
654
+
637
655
  try:
638
- from dotenv import load_dotenv
656
+ dotenv_module = importlib.import_module("dotenv")
639
657
  except ImportError:
640
- # 如果没有安装 python-dotenv,则跳过 loading .env
641
- load_dotenv = None
642
-
658
+ dotenv_module = None
659
+
643
660
  # 1. 加载 .env
644
- if load_dotenv:
661
+ if dotenv_module is not None:
645
662
  # Ensure agent_path is a Path object
646
663
  if isinstance(agent_path, str):
647
664
  agent_path = Path(agent_path)
648
-
665
+
649
666
  env_file = agent_path / ".env"
650
667
  if env_file.exists():
651
668
  # override=False: 保留通过 API/Serverless 平台注入的环境变量 (优先级高)
652
- load_dotenv(env_file, override=False)
669
+ dotenv_module.load_dotenv(env_file, override=False)
653
670
 
654
671
  # 本地调试与托管运行时统一默认北京时间;用户通过 shell/.env/平台显式指定 TZ 时不覆盖。
655
672
  os.environ.setdefault("TZ", DEFAULT_RUNTIME_TIMEZONE)
@@ -696,7 +713,7 @@ def setup_environment(agent_path: "Path"):
696
713
  if not os.getenv("OPENAI_API_BASE"):
697
714
  os.environ["OPENAI_API_BASE"] = api_base
698
715
  click.echo(f"🔧 API Base: {click.style(api_base, fg='cyan')} (Auto-detected)")
699
-
716
+
700
717
  # Model Name
701
718
  if not os.getenv("OPENAI_MODEL_NAME"):
702
719
  model_name = settings.model.model_name
@@ -704,3 +721,13 @@ def setup_environment(agent_path: "Path"):
704
721
  click.echo(f"🧠 Model: {click.style(model_name, fg='cyan')} (Default)")
705
722
  if not os.getenv("MODEL_NAME") and os.getenv("OPENAI_MODEL_NAME"):
706
723
  os.environ["MODEL_NAME"] = os.getenv("OPENAI_MODEL_NAME", "")
724
+
725
+ # 4. 模型出口协议转换层(v2.2):gate 开启且模型在白名单时懒起进程内 ProxyServer,
726
+ # 把 OPENAI_BASE_URL 重定向到它。默认 gate 关,不重定向,历史路径零影响。
727
+ # codex 不走此路(它走 AsyncCodexClient 的 v2.1 provider 注入)。
728
+ try:
729
+ from ksadk.model_proxy.bootstrap import setup_proxy_redirect_if_enabled
730
+
731
+ setup_proxy_redirect_if_enabled()
732
+ except Exception: # noqa: BLE001 代理可选,失败不影响主流程(默认关时本就不触发)
733
+ pass