agentengine-sdk-python 0.6.4__py3-none-any.whl → 0.7.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 (486) hide show
  1. agentengine_sdk_python-0.7.0.dist-info/METADATA +181 -0
  2. agentengine_sdk_python-0.7.0.dist-info/RECORD +482 -0
  3. {agentengine_sdk_python-0.6.4.dist-info → agentengine_sdk_python-0.7.0.dist-info}/WHEEL +1 -1
  4. agentengine_sdk_python-0.7.0.dist-info/entry_points.txt +3 -0
  5. agentengine_sdk_python-0.7.0.dist-info/licenses/LICENSE +175 -0
  6. agentengine_sdk_python-0.7.0.dist-info/top_level.txt +2 -0
  7. ksadk/__init__.py +13 -0
  8. ksadk/__main__.py +4 -0
  9. ksadk/a2a/__init__.py +15 -0
  10. ksadk/a2a/card_builder.py +64 -0
  11. ksadk/a2a/client.py +309 -0
  12. ksadk/a2a/executor.py +201 -0
  13. ksadk/a2a/server.py +79 -0
  14. ksadk/agents/__init__.py +20 -0
  15. ksadk/agents/base.py +370 -0
  16. ksadk/agents/context.py +38 -0
  17. ksadk/agents/event.py +35 -0
  18. ksadk/agents/loop_agent.py +71 -0
  19. ksadk/agents/parallel_agent.py +109 -0
  20. ksadk/agents/runner_adapter.py +24 -0
  21. ksadk/agents/sequential_agent.py +34 -0
  22. ksadk/api/__init__.py +3 -0
  23. ksadk/api/client.py +2246 -0
  24. ksadk/builders/__init__.py +20 -0
  25. ksadk/builders/base.py +66 -0
  26. ksadk/builders/code_builder.py +1990 -0
  27. ksadk/builders/container_builder.py +786 -0
  28. ksadk/builders/framework_requirements.py +59 -0
  29. ksadk/builders/ks3_uploader.py +389 -0
  30. ksadk/builders/mcp_builder.py +476 -0
  31. ksadk/builders/requirements_utils.py +75 -0
  32. ksadk/cli/__init__.py +531 -0
  33. ksadk/cli/__main__.py +4 -0
  34. ksadk/cli/agent_ref.py +204 -0
  35. ksadk/cli/cmd_a2a.py +167 -0
  36. ksadk/cli/cmd_agent.py +201 -0
  37. ksadk/cli/cmd_build.py +270 -0
  38. ksadk/cli/cmd_completion.py +304 -0
  39. ksadk/cli/cmd_config.py +758 -0
  40. ksadk/cli/cmd_create.py +2304 -0
  41. ksadk/cli/cmd_dashboard.py +900 -0
  42. ksadk/cli/cmd_deploy.py +704 -0
  43. ksadk/cli/cmd_destroy.py +345 -0
  44. ksadk/cli/cmd_files.py +1227 -0
  45. ksadk/cli/cmd_hermes.py +1263 -0
  46. ksadk/cli/cmd_invoke.py +1503 -0
  47. ksadk/cli/cmd_launch.py +564 -0
  48. ksadk/cli/cmd_mcp.py +1179 -0
  49. ksadk/cli/cmd_model.py +302 -0
  50. ksadk/cli/cmd_openclaw.py +3922 -0
  51. ksadk/cli/cmd_run.py +239 -0
  52. ksadk/cli/cmd_status.py +588 -0
  53. ksadk/cli/cmd_version.py +522 -0
  54. ksadk/cli/cmd_web.py +288 -0
  55. ksadk/cli/deploy_utils.py +87 -0
  56. ksadk/cli/dry_run.py +214 -0
  57. ksadk/cli/env_options.py +82 -0
  58. ksadk/cli/error_utils.py +525 -0
  59. ksadk/cli/global_options.py +31 -0
  60. ksadk/cli/local_runtime.py +97 -0
  61. ksadk/cli/model_catalog.py +136 -0
  62. ksadk/cli/network_options.py +412 -0
  63. ksadk/cli/resource_common.py +621 -0
  64. ksadk/cli/storage.py +84 -0
  65. ksadk/cli/ui.py +431 -0
  66. ksadk/cli/workflow_common.py +552 -0
  67. ksadk/common/__init__.py +14 -0
  68. ksadk/common/aicp_env.py +128 -0
  69. ksadk/common/auth.py +190 -0
  70. ksadk/common/constants.py +84 -0
  71. ksadk/common/llm_utils.py +61 -0
  72. ksadk/configs/__init__.py +61 -0
  73. ksadk/configs/env_registry.py +343 -0
  74. ksadk/configs/global_config.py +200 -0
  75. ksadk/configs/settings.py +706 -0
  76. ksadk/conversations/__init__.py +95 -0
  77. ksadk/conversations/attachment_storage.py +379 -0
  78. ksadk/conversations/attachments.py +774 -0
  79. ksadk/conversations/compaction_pipeline.py +387 -0
  80. ksadk/conversations/compaction_prompt.py +128 -0
  81. ksadk/conversations/context.py +303 -0
  82. ksadk/conversations/message_projection.py +269 -0
  83. ksadk/conversations/model_context.py +370 -0
  84. ksadk/conversations/model_options.py +136 -0
  85. ksadk/conversations/normalize.py +446 -0
  86. ksadk/conversations/reasoning_markup.py +91 -0
  87. ksadk/conversations/run_kinds.py +61 -0
  88. ksadk/conversations/run_status.py +53 -0
  89. ksadk/conversations/runtime.py +5276 -0
  90. ksadk/conversations/semantic_summary.py +359 -0
  91. ksadk/conversations/session_title.py +254 -0
  92. ksadk/deployment/__init__.py +83 -0
  93. ksadk/deployment/agent_access.py +226 -0
  94. ksadk/deployment/base.py +229 -0
  95. ksadk/deployment/manager.py +332 -0
  96. ksadk/deployment/providers/__init__.py +10 -0
  97. ksadk/deployment/providers/serverless.py +1115 -0
  98. ksadk/deployment/registry.py +120 -0
  99. ksadk/deployment/state.py +78 -0
  100. ksadk/deployment/ui_config.py +21 -0
  101. ksadk/detection/__init__.py +7 -0
  102. ksadk/detection/detector.py +431 -0
  103. ksadk/detection/mcp_detector.py +250 -0
  104. ksadk/hermes_terminal.py +467 -0
  105. ksadk/identity/__init__.py +17 -0
  106. ksadk/identity/resolver.py +385 -0
  107. ksadk/knowledge_base/__init__.py +62 -0
  108. ksadk/knowledge_base/adk_tool.py +47 -0
  109. ksadk/knowledge_base/client.py +297 -0
  110. ksadk/knowledge_base/langchain_tool.py +55 -0
  111. ksadk/knowledge_base/service.py +66 -0
  112. ksadk/knowledge_base/tool.py +50 -0
  113. ksadk/markdown.py +169 -0
  114. ksadk/mcp_runtime/__init__.py +231 -0
  115. ksadk/memory/__init__.py +57 -0
  116. ksadk/memory/adk/__init__.py +51 -0
  117. ksadk/memory/adk/backends/__init__.py +5 -0
  118. ksadk/memory/adk/backends/base_ltm_backend.py +52 -0
  119. ksadk/memory/adk/backends/http_ltm_backend.py +183 -0
  120. ksadk/memory/adk/backends/inmemory_ltm_backend.py +96 -0
  121. ksadk/memory/adk/backends/sdk_ltm_backend.py +456 -0
  122. ksadk/memory/adk/long_term_memory.py +273 -0
  123. ksadk/memory/adk/resilient_session_service.py +268 -0
  124. ksadk/memory/adk/short_term_memory.py +304 -0
  125. ksadk/memory/adk_tool.py +31 -0
  126. ksadk/memory/backends/__init__.py +6 -0
  127. ksadk/memory/backends/base.py +103 -0
  128. ksadk/memory/backends/memory.py +112 -0
  129. ksadk/memory/backends/redis.py +146 -0
  130. ksadk/memory/langchain_tool.py +39 -0
  131. ksadk/memory/ltm_backend_factory.py +24 -0
  132. ksadk/memory/manager.py +215 -0
  133. ksadk/memory/service.py +172 -0
  134. ksadk/memory/tool.py +96 -0
  135. ksadk/model_policy.py +223 -0
  136. ksadk/openclaw_gateway.py +378 -0
  137. ksadk/runners/__init__.py +8 -0
  138. ksadk/runners/adk_runner.py +1994 -0
  139. ksadk/runners/base_runner.py +305 -0
  140. ksadk/runners/deepagents_runner.py +13 -0
  141. ksadk/runners/factory.py +73 -0
  142. ksadk/runners/langchain_runner.py +751 -0
  143. ksadk/runners/langgraph_runner.py +985 -0
  144. ksadk/runners/patch_langchain.py +187 -0
  145. ksadk/runners/remote_runner.py +792 -0
  146. ksadk/runners/usage_accumulator.py +38 -0
  147. ksadk/runners/utils/__init__.py +19 -0
  148. ksadk/runners/utils/langfuse.py +230 -0
  149. ksadk/runners/utils/loader.py +62 -0
  150. ksadk/runtime_context.py +166 -0
  151. ksadk/runtime_state.py +25 -0
  152. ksadk/sandbox/__init__.py +28 -0
  153. ksadk/sandbox/backends/__init__.py +9 -0
  154. ksadk/sandbox/backends/e2b.py +154 -0
  155. ksadk/sandbox/backends/local_process.py +131 -0
  156. ksadk/sandbox/base.py +101 -0
  157. ksadk/sandbox/factory.py +53 -0
  158. ksadk/sandbox/registry.py +187 -0
  159. ksadk/server/__init__.py +7 -0
  160. ksadk/server/api_models.py +73 -0
  161. ksadk/server/app.py +3931 -0
  162. ksadk/server/static/assets/ArtifactsPanel-D-SSn2ee.js +1 -0
  163. ksadk/server/static/assets/CodeBlock-P16VOLYi.js +9 -0
  164. ksadk/server/static/assets/KaTeX_AMS-Regular-BQhdFMY1.woff2 +0 -0
  165. ksadk/server/static/assets/KaTeX_AMS-Regular-DMm9YOAa.woff +0 -0
  166. ksadk/server/static/assets/KaTeX_AMS-Regular-DRggAlZN.ttf +0 -0
  167. ksadk/server/static/assets/KaTeX_Caligraphic-Bold-ATXxdsX0.ttf +0 -0
  168. ksadk/server/static/assets/KaTeX_Caligraphic-Bold-BEiXGLvX.woff +0 -0
  169. ksadk/server/static/assets/KaTeX_Caligraphic-Bold-Dq_IR9rO.woff2 +0 -0
  170. ksadk/server/static/assets/KaTeX_Caligraphic-Regular-CTRA-rTL.woff +0 -0
  171. ksadk/server/static/assets/KaTeX_Caligraphic-Regular-Di6jR-x-.woff2 +0 -0
  172. ksadk/server/static/assets/KaTeX_Caligraphic-Regular-wX97UBjC.ttf +0 -0
  173. ksadk/server/static/assets/KaTeX_Fraktur-Bold-BdnERNNW.ttf +0 -0
  174. ksadk/server/static/assets/KaTeX_Fraktur-Bold-BsDP51OF.woff +0 -0
  175. ksadk/server/static/assets/KaTeX_Fraktur-Bold-CL6g_b3V.woff2 +0 -0
  176. ksadk/server/static/assets/KaTeX_Fraktur-Regular-CB_wures.ttf +0 -0
  177. ksadk/server/static/assets/KaTeX_Fraktur-Regular-CTYiF6lA.woff2 +0 -0
  178. ksadk/server/static/assets/KaTeX_Fraktur-Regular-Dxdc4cR9.woff +0 -0
  179. ksadk/server/static/assets/KaTeX_Main-Bold-Cx986IdX.woff2 +0 -0
  180. ksadk/server/static/assets/KaTeX_Main-Bold-Jm3AIy58.woff +0 -0
  181. ksadk/server/static/assets/KaTeX_Main-Bold-waoOVXN0.ttf +0 -0
  182. ksadk/server/static/assets/KaTeX_Main-BoldItalic-DxDJ3AOS.woff2 +0 -0
  183. ksadk/server/static/assets/KaTeX_Main-BoldItalic-DzxPMmG6.ttf +0 -0
  184. ksadk/server/static/assets/KaTeX_Main-BoldItalic-SpSLRI95.woff +0 -0
  185. ksadk/server/static/assets/KaTeX_Main-Italic-3WenGoN9.ttf +0 -0
  186. ksadk/server/static/assets/KaTeX_Main-Italic-BMLOBm91.woff +0 -0
  187. ksadk/server/static/assets/KaTeX_Main-Italic-NWA7e6Wa.woff2 +0 -0
  188. ksadk/server/static/assets/KaTeX_Main-Regular-B22Nviop.woff2 +0 -0
  189. ksadk/server/static/assets/KaTeX_Main-Regular-Dr94JaBh.woff +0 -0
  190. ksadk/server/static/assets/KaTeX_Main-Regular-ypZvNtVU.ttf +0 -0
  191. ksadk/server/static/assets/KaTeX_Math-BoldItalic-B3XSjfu4.ttf +0 -0
  192. ksadk/server/static/assets/KaTeX_Math-BoldItalic-CZnvNsCZ.woff2 +0 -0
  193. ksadk/server/static/assets/KaTeX_Math-BoldItalic-iY-2wyZ7.woff +0 -0
  194. ksadk/server/static/assets/KaTeX_Math-Italic-DA0__PXp.woff +0 -0
  195. ksadk/server/static/assets/KaTeX_Math-Italic-flOr_0UB.ttf +0 -0
  196. ksadk/server/static/assets/KaTeX_Math-Italic-t53AETM-.woff2 +0 -0
  197. ksadk/server/static/assets/KaTeX_SansSerif-Bold-CFMepnvq.ttf +0 -0
  198. ksadk/server/static/assets/KaTeX_SansSerif-Bold-D1sUS0GD.woff2 +0 -0
  199. ksadk/server/static/assets/KaTeX_SansSerif-Bold-DbIhKOiC.woff +0 -0
  200. ksadk/server/static/assets/KaTeX_SansSerif-Italic-C3H0VqGB.woff2 +0 -0
  201. ksadk/server/static/assets/KaTeX_SansSerif-Italic-DN2j7dab.woff +0 -0
  202. ksadk/server/static/assets/KaTeX_SansSerif-Italic-YYjJ1zSn.ttf +0 -0
  203. ksadk/server/static/assets/KaTeX_SansSerif-Regular-BNo7hRIc.ttf +0 -0
  204. ksadk/server/static/assets/KaTeX_SansSerif-Regular-CS6fqUqJ.woff +0 -0
  205. ksadk/server/static/assets/KaTeX_SansSerif-Regular-DDBCnlJ7.woff2 +0 -0
  206. ksadk/server/static/assets/KaTeX_Script-Regular-C5JkGWo-.ttf +0 -0
  207. ksadk/server/static/assets/KaTeX_Script-Regular-D3wIWfF6.woff2 +0 -0
  208. ksadk/server/static/assets/KaTeX_Script-Regular-D5yQViql.woff +0 -0
  209. ksadk/server/static/assets/KaTeX_Size1-Regular-C195tn64.woff +0 -0
  210. ksadk/server/static/assets/KaTeX_Size1-Regular-Dbsnue_I.ttf +0 -0
  211. ksadk/server/static/assets/KaTeX_Size1-Regular-mCD8mA8B.woff2 +0 -0
  212. ksadk/server/static/assets/KaTeX_Size2-Regular-B7gKUWhC.ttf +0 -0
  213. ksadk/server/static/assets/KaTeX_Size2-Regular-Dy4dx90m.woff2 +0 -0
  214. ksadk/server/static/assets/KaTeX_Size2-Regular-oD1tc_U0.woff +0 -0
  215. ksadk/server/static/assets/KaTeX_Size3-Regular-CTq5MqoE.woff +0 -0
  216. ksadk/server/static/assets/KaTeX_Size3-Regular-DgpXs0kz.ttf +0 -0
  217. ksadk/server/static/assets/KaTeX_Size4-Regular-BF-4gkZK.woff +0 -0
  218. ksadk/server/static/assets/KaTeX_Size4-Regular-DWFBv043.ttf +0 -0
  219. ksadk/server/static/assets/KaTeX_Size4-Regular-Dl5lxZxV.woff2 +0 -0
  220. ksadk/server/static/assets/KaTeX_Typewriter-Regular-C0xS9mPB.woff +0 -0
  221. ksadk/server/static/assets/KaTeX_Typewriter-Regular-CO6r4hn1.woff2 +0 -0
  222. ksadk/server/static/assets/KaTeX_Typewriter-Regular-D3Ib7_Hf.ttf +0 -0
  223. ksadk/server/static/assets/MathMessageMarkdown-CdGiQWHR.js +8 -0
  224. ksadk/server/static/assets/MathMessageMarkdown-DeYh8QPr.css +1 -0
  225. ksadk/server/static/assets/MermaidBlock-IOcal8cm.js +303 -0
  226. ksadk/server/static/assets/NativeTerminalPanel-CHOd7Rch.css +1 -0
  227. ksadk/server/static/assets/NativeTerminalPanel-DGSDWsei.js +1 -0
  228. ksadk/server/static/assets/addon-fit-DthTIhi3.js +1 -0
  229. ksadk/server/static/assets/apl-CnwPGSsG.js +1 -0
  230. ksadk/server/static/assets/arc-BA13sHc9.js +1 -0
  231. ksadk/server/static/assets/architecture-7EHR7CIX-BvUlsA6l.js +1 -0
  232. ksadk/server/static/assets/architectureDiagram-3BPJPVTR-DzJzgVoL.js +36 -0
  233. ksadk/server/static/assets/asciiarmor-qTkVPQu6.js +1 -0
  234. ksadk/server/static/assets/asn1-Dr8qZg38.js +1 -0
  235. ksadk/server/static/assets/asterisk-Bja0s6e1.js +1 -0
  236. ksadk/server/static/assets/blockDiagram-GPEHLZMM-UTdVcZhn.js +132 -0
  237. ksadk/server/static/assets/brainfuck-D5EjA2JK.js +1 -0
  238. ksadk/server/static/assets/c4Diagram-AAUBKEIU-Dix0GD4m.js +10 -0
  239. ksadk/server/static/assets/channel-CTuydARX.js +1 -0
  240. ksadk/server/static/assets/chunk-2J33WTMH-C2JxuZ42.js +1 -0
  241. ksadk/server/static/assets/chunk-4BX2VUAB-Be57QPgD.js +1 -0
  242. ksadk/server/static/assets/chunk-55IACEB6-WjSuy4nv.js +1 -0
  243. ksadk/server/static/assets/chunk-727SXJPM-BOovP-b5.js +206 -0
  244. ksadk/server/static/assets/chunk-AQP2D5EJ-DOmZNmWj.js +231 -0
  245. ksadk/server/static/assets/chunk-FMBD7UC4-DzwlodkU.js +15 -0
  246. ksadk/server/static/assets/chunk-ND2GUHAM-DMqAikEU.js +1 -0
  247. ksadk/server/static/assets/chunk-QZHKN3VN-BnCydivS.js +1 -0
  248. ksadk/server/static/assets/classDiagram-4FO5ZUOK-BNHg45Be.js +1 -0
  249. ksadk/server/static/assets/classDiagram-v2-Q7XG4LA2-BNHg45Be.js +1 -0
  250. ksadk/server/static/assets/clike-DHH8Ad3s.js +1 -0
  251. ksadk/server/static/assets/clojure-BflJGmDX.js +1 -0
  252. ksadk/server/static/assets/cmake-CyVbuzPu.js +1 -0
  253. ksadk/server/static/assets/cobol-B_OZ4V-R.js +1 -0
  254. ksadk/server/static/assets/coffeescript-B2pKbFk8.js +1 -0
  255. ksadk/server/static/assets/commonlisp-CcllspGY.js +1 -0
  256. ksadk/server/static/assets/cose-bilkent-S5V4N54A-Zhy2GBnP.js +1 -0
  257. ksadk/server/static/assets/crystal-M5-qzICs.js +1 -0
  258. ksadk/server/static/assets/css-CYpP4FRV.js +1 -0
  259. ksadk/server/static/assets/cypher-p9eYesGn.js +1 -0
  260. ksadk/server/static/assets/cytoscape.esm-DelgaX4f.js +321 -0
  261. ksadk/server/static/assets/d-BhMjBjQP.js +1 -0
  262. ksadk/server/static/assets/dagre-BM42HDAG-CbKrtIUz.js +4 -0
  263. ksadk/server/static/assets/dagre-Bx709z4p.js +1 -0
  264. ksadk/server/static/assets/defaultLocale-C8Fc0cco.js +1 -0
  265. ksadk/server/static/assets/diagram-2AECGRRQ-BRApgQRK.js +43 -0
  266. ksadk/server/static/assets/diagram-5GNKFQAL-D0xbnDiK.js +10 -0
  267. ksadk/server/static/assets/diagram-KO2AKTUF-CVugVI9L.js +3 -0
  268. ksadk/server/static/assets/diagram-LMA3HP47-DozUGgee.js +24 -0
  269. ksadk/server/static/assets/diagram-OG6HWLK6-ZOYsKlru.js +24 -0
  270. ksadk/server/static/assets/diff-ChtP43wD.js +1 -0
  271. ksadk/server/static/assets/dist-2hInLS_J.js +9 -0
  272. ksadk/server/static/assets/dist-8EEyGgDx.js +1 -0
  273. ksadk/server/static/assets/dist-8_SfK1IP.js +1 -0
  274. ksadk/server/static/assets/dist-B0NP_Z0z.js +23 -0
  275. ksadk/server/static/assets/dist-BIJVDMuB.js +1 -0
  276. ksadk/server/static/assets/dist-BmlMPsCc.js +2 -0
  277. ksadk/server/static/assets/dist-BrCcQ47T.js +1 -0
  278. ksadk/server/static/assets/dist-BssVmjIo.js +6 -0
  279. ksadk/server/static/assets/dist-C3HIIaN5.js +1 -0
  280. ksadk/server/static/assets/dist-CPBtqRTW.js +1 -0
  281. ksadk/server/static/assets/dist-CkEKJFtk.js +1 -0
  282. ksadk/server/static/assets/dist-D-JMdWPQ.js +1 -0
  283. ksadk/server/static/assets/dist-D-xOD048.js +1 -0
  284. ksadk/server/static/assets/dist-D57wnGWd.js +1 -0
  285. ksadk/server/static/assets/dist-DL_NKc_z.js +1 -0
  286. ksadk/server/static/assets/dist-DMezvBGJ.js +1 -0
  287. ksadk/server/static/assets/dist-DmFaq_Iy.js +1 -0
  288. ksadk/server/static/assets/dist-Dp0k7bWI.js +1 -0
  289. ksadk/server/static/assets/dist-DpKtt4Bo.js +1 -0
  290. ksadk/server/static/assets/dist-DyOkZmze.js +11 -0
  291. ksadk/server/static/assets/dist-DyWsb78Q.js +1 -0
  292. ksadk/server/static/assets/dist-gX6GOLKq.js +1 -0
  293. ksadk/server/static/assets/dockerfile-BLkNEvjs.js +1 -0
  294. ksadk/server/static/assets/dtd-DTF72YNO.js +1 -0
  295. ksadk/server/static/assets/dylan-C6jEEEk-.js +1 -0
  296. ksadk/server/static/assets/ebnf-D4c0_ac3.js +1 -0
  297. ksadk/server/static/assets/ecl-BSZaIHnp.js +1 -0
  298. ksadk/server/static/assets/eiffel-BEjRio4Q.js +1 -0
  299. ksadk/server/static/assets/elm-Cshzl8qu.js +1 -0
  300. ksadk/server/static/assets/erDiagram-TEJ5UH35-Bk-9bgE5.js +85 -0
  301. ksadk/server/static/assets/erlang-DaB2Rkuy.js +1 -0
  302. ksadk/server/static/assets/eventmodeling-FCH6USID-DsAgWnlf.js +1 -0
  303. ksadk/server/static/assets/factor-D7LVTn2l.js +1 -0
  304. ksadk/server/static/assets/fcl-ClOhbFR7.js +1 -0
  305. ksadk/server/static/assets/flowDiagram-I6XJVG4X-Dn9kZVuZ.js +162 -0
  306. ksadk/server/static/assets/forth-Cezjo90N.js +1 -0
  307. ksadk/server/static/assets/fortran-Bt6PBEDR.js +1 -0
  308. ksadk/server/static/assets/ganttDiagram-6RSMTGT7-BGxXlJqm.js +292 -0
  309. ksadk/server/static/assets/gas-BHEdbvp9.js +1 -0
  310. ksadk/server/static/assets/gherkin-oBAE_ms0.js +1 -0
  311. ksadk/server/static/assets/gitGraph-WXDBUCRP-BIao9Yjg.js +1 -0
  312. ksadk/server/static/assets/gitGraphDiagram-PVQCEYII-C7Q0X-wi.js +106 -0
  313. ksadk/server/static/assets/graphlib-B8gBHxth.js +1 -0
  314. ksadk/server/static/assets/groovy-BC3IOsC8.js +1 -0
  315. ksadk/server/static/assets/haskell-BRsoo5mP.js +1 -0
  316. ksadk/server/static/assets/haxe-DIz0ZZqd.js +1 -0
  317. ksadk/server/static/assets/http-CLVgA2GD.js +1 -0
  318. ksadk/server/static/assets/idl-BUZw3wgd.js +1 -0
  319. ksadk/server/static/assets/index-C00Lwg3L.js +165 -0
  320. ksadk/server/static/assets/index-DAURbCsP.css +1 -0
  321. ksadk/server/static/assets/info-J43DQDTF-CyipqGxU.js +1 -0
  322. ksadk/server/static/assets/infoDiagram-5YYISTIA-BO_CSqq5.js +2 -0
  323. ksadk/server/static/assets/init-D6jRqBbL.js +1 -0
  324. ksadk/server/static/assets/ishikawaDiagram-YF4QCWOH-eYLPLd46.js +70 -0
  325. ksadk/server/static/assets/javascript-9Tg8ixDm.js +1 -0
  326. ksadk/server/static/assets/journeyDiagram-JHISSGLW-De9geSb0.js +139 -0
  327. ksadk/server/static/assets/julia-CQfgDRfP.js +1 -0
  328. ksadk/server/static/assets/kanban-definition-UN3LZRKU-Cs80kQto.js +89 -0
  329. ksadk/server/static/assets/katex-DSrCFD8n.js +265 -0
  330. ksadk/server/static/assets/linear-CN9sbKTF.js +1 -0
  331. ksadk/server/static/assets/livescript-BXxG0Yva.js +1 -0
  332. ksadk/server/static/assets/lua-CiA1ziua.js +1 -0
  333. ksadk/server/static/assets/mathematica-u8YMmbU0.js +1 -0
  334. ksadk/server/static/assets/mbox-BEMVcqjs.js +1 -0
  335. ksadk/server/static/assets/mermaid-parser.core-DlgSBU8l.js +161 -0
  336. ksadk/server/static/assets/mindmap-definition-RKZ34NQL-9afz7Oug.js +96 -0
  337. ksadk/server/static/assets/mirc-C9zpzAZU.js +1 -0
  338. ksadk/server/static/assets/mllike-B45xgp2S.js +1 -0
  339. ksadk/server/static/assets/modelica-CqHI_q-D.js +1 -0
  340. ksadk/server/static/assets/mscgen-qgSLujhx.js +1 -0
  341. ksadk/server/static/assets/mumps-CW_TBmxz.js +1 -0
  342. ksadk/server/static/assets/nginx-BMaDbqW3.js +1 -0
  343. ksadk/server/static/assets/nsis-AQ_alPln.js +1 -0
  344. ksadk/server/static/assets/ntriples-d28e9m0E.js +1 -0
  345. ksadk/server/static/assets/octave-D2Q8cUp1.js +1 -0
  346. ksadk/server/static/assets/ordinal-hYBb2elL.js +1 -0
  347. ksadk/server/static/assets/oz-BwTct_5T.js +1 -0
  348. ksadk/server/static/assets/packet-YPE3B663-CGkyRxlg.js +1 -0
  349. ksadk/server/static/assets/pascal-Dp_KdFgX.js +1 -0
  350. ksadk/server/static/assets/perl-CdEHsPfU.js +1 -0
  351. ksadk/server/static/assets/pie-LRSECV5Y-M0uWAf4n.js +1 -0
  352. ksadk/server/static/assets/pieDiagram-4H26LBE5-DPv_VstN.js +30 -0
  353. ksadk/server/static/assets/pig-AF4Hwhju.js +1 -0
  354. ksadk/server/static/assets/powershell-CzG71I4L.js +1 -0
  355. ksadk/server/static/assets/properties-C357ku5U.js +1 -0
  356. ksadk/server/static/assets/protobuf-D1ij_kNL.js +1 -0
  357. ksadk/server/static/assets/pug-Bugr-47h.js +1 -0
  358. ksadk/server/static/assets/puppet-B4hC2X4m.js +1 -0
  359. ksadk/server/static/assets/python-BqYw9LYJ.js +1 -0
  360. ksadk/server/static/assets/q-B9NhS7L_.js +1 -0
  361. ksadk/server/static/assets/quadrantDiagram-W4KKPZXB-o77wZ1XK.js +7 -0
  362. ksadk/server/static/assets/r-DADKenSm.js +1 -0
  363. ksadk/server/static/assets/radar-GUYGQ44K-Bdbm24-x.js +1 -0
  364. ksadk/server/static/assets/requirementDiagram-4Y6WPE33-BYVw81VC.js +84 -0
  365. ksadk/server/static/assets/rpm-gpDK5sbt.js +1 -0
  366. ksadk/server/static/assets/ruby-DsYpTuWg.js +1 -0
  367. ksadk/server/static/assets/sankeyDiagram-5OEKKPKP-B7nZFMKT.js +40 -0
  368. ksadk/server/static/assets/sas-C2OyD2Y6.js +1 -0
  369. ksadk/server/static/assets/scheme-CyDdOh7e.js +1 -0
  370. ksadk/server/static/assets/sequenceDiagram-3UESZ5HK-BGRRrFw5.js +162 -0
  371. ksadk/server/static/assets/shell-Du5Qg9im.js +1 -0
  372. ksadk/server/static/assets/sieve-BAxa3IjF.js +1 -0
  373. ksadk/server/static/assets/simple-mode-DRpGK0lJ.js +1 -0
  374. ksadk/server/static/assets/smalltalk-BLp5-jwC.js +1 -0
  375. ksadk/server/static/assets/solr-BBopId9w.js +1 -0
  376. ksadk/server/static/assets/sparql-Dz-mlCAC.js +1 -0
  377. ksadk/server/static/assets/spreadsheet-CTIncYxj.js +1 -0
  378. ksadk/server/static/assets/sql-DcCJ9jop.js +1 -0
  379. ksadk/server/static/assets/stateDiagram-AJRCARHV-BUfHCoPs.js +1 -0
  380. ksadk/server/static/assets/stateDiagram-v2-BHNVJYJU-8xBN_gLM.js +1 -0
  381. ksadk/server/static/assets/stex-sDrdk2BW.js +1 -0
  382. ksadk/server/static/assets/stylus-DLLZ8dgm.js +1 -0
  383. ksadk/server/static/assets/swift-DKB6_1j6.js +1 -0
  384. ksadk/server/static/assets/tcl-BGfruO1u.js +1 -0
  385. ksadk/server/static/assets/textile-DWBqthVk.js +1 -0
  386. ksadk/server/static/assets/tiddlywiki-VlUiK86J.js +1 -0
  387. ksadk/server/static/assets/tiki-CxVlf5KZ.js +1 -0
  388. ksadk/server/static/assets/timeline-definition-PNZ67QCA-FbCTGrf9.js +120 -0
  389. ksadk/server/static/assets/toml-LvoKBwCs.js +1 -0
  390. ksadk/server/static/assets/treeView-BLDUP644-npMo0ak1.js +1 -0
  391. ksadk/server/static/assets/treemap-LRROVOQU-CHdzrrdo.js +1 -0
  392. ksadk/server/static/assets/troff-C2dAgh7P.js +1 -0
  393. ksadk/server/static/assets/ttcn-BePYh-hG.js +1 -0
  394. ksadk/server/static/assets/ttcn-cfg-CY0aot7Q.js +1 -0
  395. ksadk/server/static/assets/turtle-BDLWE2cD.js +1 -0
  396. ksadk/server/static/assets/vb-BthdM_4N.js +1 -0
  397. ksadk/server/static/assets/vbscript-D9f6rSsU.js +1 -0
  398. ksadk/server/static/assets/velocity-CqftRsjg.js +1 -0
  399. ksadk/server/static/assets/vennDiagram-CIIHVFJN-DWgwtPsJ.js +34 -0
  400. ksadk/server/static/assets/verilog-D-x6ne0Z.js +1 -0
  401. ksadk/server/static/assets/vhdl-CMrOq2q1.js +1 -0
  402. ksadk/server/static/assets/wardley-L42UT6IY-BEQz7wyy.js +1 -0
  403. ksadk/server/static/assets/wardleyDiagram-YWT4CUSO-2x8G-tTM.js +78 -0
  404. ksadk/server/static/assets/webidl-D5jiJvOU.js +1 -0
  405. ksadk/server/static/assets/xquery-fj_R-kMw.js +1 -0
  406. ksadk/server/static/assets/xterm-DooSxjI5.js +36 -0
  407. ksadk/server/static/assets/xychartDiagram-2RQKCTM6-Drma3AYl.js +7 -0
  408. ksadk/server/static/assets/yacas-CXXgtw0p.js +1 -0
  409. ksadk/server/static/assets/z80-CL1naaMV.js +1 -0
  410. ksadk/server/static/favicon.svg +1 -0
  411. ksadk/server/static/icons.svg +24 -0
  412. ksadk/server/static/index.html +14 -0
  413. ksadk/server/terminal_sessions.py +551 -0
  414. ksadk/sessions/__init__.py +279 -0
  415. ksadk/sessions/base.py +354 -0
  416. ksadk/sessions/continuity.py +337 -0
  417. ksadk/sessions/errors.py +7 -0
  418. ksadk/sessions/in_memory.py +273 -0
  419. ksadk/sessions/local_service.py +949 -0
  420. ksadk/sessions/postgres_service.py +901 -0
  421. ksadk/sessions/resilience.py +52 -0
  422. ksadk/sessions/resilient.py +360 -0
  423. ksadk/sessions/sqlite_service.py +13 -0
  424. ksadk/skills/__init__.py +9 -0
  425. ksadk/skills/loader.py +46 -0
  426. ksadk/skills/models.py +120 -0
  427. ksadk/skills/package_store.py +104 -0
  428. ksadk/skills/runtime/__init__.py +17 -0
  429. ksadk/skills/runtime/agent.py +183 -0
  430. ksadk/skills/runtime/artifacts.py +39 -0
  431. ksadk/skills/runtime/backends/__init__.py +1 -0
  432. ksadk/skills/runtime/backends/disabled.py +8 -0
  433. ksadk/skills/runtime/backends/e2b.py +168 -0
  434. ksadk/skills/runtime/backends/local.py +95 -0
  435. ksadk/skills/runtime/base.py +103 -0
  436. ksadk/skills/runtime/executor.py +219 -0
  437. ksadk/skills/runtime/factory.py +37 -0
  438. ksadk/skills/runtime/loader.py +131 -0
  439. ksadk/skills/runtime/registry.py +150 -0
  440. ksadk/skills/runtime/request.py +67 -0
  441. ksadk/skills/service_client.py +239 -0
  442. ksadk/skills/service_env.py +58 -0
  443. ksadk/skills/tool_defs.py +221 -0
  444. ksadk/terminal_client.py +69 -0
  445. ksadk/terminal_exec_policy.py +229 -0
  446. ksadk/tools/__init__.py +17 -0
  447. ksadk/tools/gateway.py +230 -0
  448. ksadk/tools/result_budget.py +154 -0
  449. ksadk/toolsets/__init__.py +854 -0
  450. ksadk/toolsets/_langchain.py +11 -0
  451. ksadk/toolsets/platform.py +93 -0
  452. ksadk/toolsets/sandbox.py +310 -0
  453. ksadk/toolsets/skills.py +217 -0
  454. ksadk/toolsets/web.py +266 -0
  455. ksadk/toolsets/workspace.py +917 -0
  456. ksadk/toolsets/workspace_state.py +44 -0
  457. ksadk/tracing/__init__.py +37 -0
  458. ksadk/tracing/exporters/__init__.py +1 -0
  459. ksadk/tracing/exporters/inmemory_exporter.py +116 -0
  460. ksadk/tracing/exporters/langfuse_exporter.py +445 -0
  461. ksadk/tracing/setup.py +892 -0
  462. ksadk/tracing/span_utils.py +114 -0
  463. ksadk/tui/__init__.py +27 -0
  464. ksadk/tui/loop.py +1877 -0
  465. ksadk/tui/stream_render.py +68 -0
  466. ksadk/ui_config.py +168 -0
  467. ksadk/version.py +4 -0
  468. ksadk_runtime_common/__init__.py +20 -0
  469. ksadk_runtime_common/memory_backend/__init__.py +29 -0
  470. ksadk_runtime_common/memory_backend/manifest.py +79 -0
  471. ksadk_runtime_common/memory_backend/providers/__init__.py +6 -0
  472. ksadk_runtime_common/memory_backend/providers/lancedb.py +151 -0
  473. ksadk_runtime_common/memory_backend/providers/mem0.py +74 -0
  474. ksadk_runtime_common/memory_backend/registry.py +56 -0
  475. ksadk_runtime_common/memory_backend/render.py +71 -0
  476. ksadk_runtime_common/schemas/memory_backend_manifest.schema.json +148 -0
  477. ksadk_runtime_common/workspace_files/__init__.py +29 -0
  478. ksadk_runtime_common/workspace_files/bootstrap.py +56 -0
  479. ksadk_runtime_common/workspace_files/constants.py +9 -0
  480. ksadk_runtime_common/workspace_files/path_utils.py +71 -0
  481. ksadk_runtime_common/workspace_files/preview.py +96 -0
  482. ksadk_runtime_common/workspace_files/router.py +254 -0
  483. agentengine_sdk_python/__init__.py +0 -3
  484. agentengine_sdk_python-0.6.4.dist-info/METADATA +0 -48
  485. agentengine_sdk_python-0.6.4.dist-info/RECORD +0 -5
  486. agentengine_sdk_python-0.6.4.dist-info/top_level.txt +0 -1
@@ -0,0 +1,446 @@
1
+ from __future__ import annotations
2
+
3
+ from typing import Any, Dict, List, Optional
4
+ from pathlib import Path
5
+
6
+ from ksadk.conversations.attachments import (
7
+ build_attachment_prompt_text,
8
+ build_attachment_results,
9
+ compact_attachment_result_for_session,
10
+ decode_inline_data,
11
+ extract_pdf_text,
12
+ is_textual_mime,
13
+ looks_like_textual_attachment,
14
+ read_attachment_bytes,
15
+ resolve_attachment_storage_path,
16
+ resolve_uploads_dir,
17
+ )
18
+ from ksadk.conversations.context import canonical_event_type
19
+ from ksadk.server.api_models import Part
20
+
21
+
22
+ def _extract_openai_image_url(value: Any) -> str:
23
+ if isinstance(value, str):
24
+ return value.strip()
25
+ if isinstance(value, dict):
26
+ url = value.get("url")
27
+ if isinstance(url, str):
28
+ return url.strip()
29
+ return ""
30
+
31
+
32
+ def _data_url_from_inline_data(inline_data: Dict[str, Any]) -> str:
33
+ data = str(inline_data.get("data") or "").strip()
34
+ if not data:
35
+ return ""
36
+ mime_type = str(inline_data.get("mimeType") or "application/octet-stream").strip()
37
+ return f"data:{mime_type};base64,{data}"
38
+
39
+
40
+ def _inline_data_from_data_url(url: str, *, display_name: str) -> Optional[Dict[str, Any]]:
41
+ normalized = (url or "").strip()
42
+ if not normalized.lower().startswith("data:") or "," not in normalized:
43
+ return None
44
+
45
+ metadata, data = normalized.split(",", 1)
46
+ if ";base64" not in metadata.lower():
47
+ return None
48
+
49
+ mime_type = metadata[5:].split(";", 1)[0].strip() or "application/octet-stream"
50
+ return {
51
+ "data": data.strip(),
52
+ "mimeType": mime_type,
53
+ "displayName": display_name,
54
+ }
55
+
56
+
57
+ def _file_data_from_openai_image_url(url: str, *, display_name: str) -> Optional[Dict[str, Any]]:
58
+ normalized = (url or "").strip()
59
+ if not normalized or normalized.lower().startswith("data:"):
60
+ return None
61
+ return {
62
+ "fileUri": normalized,
63
+ "mimeType": "image/*",
64
+ "displayName": display_name,
65
+ }
66
+
67
+
68
+ def _guess_mime_type(display_name: str) -> str:
69
+ suffix = Path(display_name or "").suffix.lower()
70
+ if suffix == ".pdf":
71
+ return "application/pdf"
72
+ if suffix == ".txt":
73
+ return "text/plain"
74
+ if suffix in {".md", ".markdown"}:
75
+ return "text/markdown"
76
+ if suffix == ".json":
77
+ return "application/json"
78
+ if suffix in {".yaml", ".yml"}:
79
+ return "application/yaml"
80
+ if suffix == ".csv":
81
+ return "text/csv"
82
+ if suffix == ".html" or suffix == ".htm":
83
+ return "text/html"
84
+ if suffix == ".docx":
85
+ return "application/vnd.openxmlformats-officedocument.wordprocessingml.document"
86
+ if suffix == ".pptx":
87
+ return "application/vnd.openxmlformats-officedocument.presentationml.presentation"
88
+ if suffix == ".xlsx":
89
+ return "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet"
90
+ if suffix == ".zip":
91
+ return "application/zip"
92
+ if suffix in {".png", ".jpg", ".jpeg", ".webp"}:
93
+ return f"image/{'jpeg' if suffix in {'.jpg', '.jpeg'} else suffix.removeprefix('.')}"
94
+ return "application/octet-stream"
95
+
96
+
97
+ def _openai_file_display_name(item: Dict[str, Any]) -> str:
98
+ return str(
99
+ item.get("filename")
100
+ or item.get("displayName")
101
+ or item.get("display_name")
102
+ or "uploaded_file"
103
+ )
104
+
105
+
106
+ def _inline_data_from_openai_file(item: Dict[str, Any]) -> Optional[Dict[str, Any]]:
107
+ data = item.get("file_data")
108
+ if not isinstance(data, str) or not data.strip():
109
+ return None
110
+ display_name = _openai_file_display_name(item)
111
+ return {
112
+ "data": data.strip(),
113
+ "mimeType": str(item.get("mime_type") or item.get("mimeType") or _guess_mime_type(display_name)),
114
+ "displayName": display_name,
115
+ }
116
+
117
+
118
+ def _file_data_from_openai_file(item: Dict[str, Any]) -> Optional[Dict[str, Any]]:
119
+ file_uri = item.get("file_url") or item.get("file_id") or item.get("fileUri")
120
+ if not isinstance(file_uri, str) or not file_uri.strip():
121
+ return None
122
+ display_name = _openai_file_display_name(item)
123
+ return {
124
+ "fileUri": file_uri.strip(),
125
+ "mimeType": str(item.get("mime_type") or item.get("mimeType") or _guess_mime_type(display_name)),
126
+ "displayName": display_name,
127
+ }
128
+
129
+
130
+ def _canonical_input_content_from_part_payload(payload: Dict[str, Any]) -> Optional[Dict[str, Any]]:
131
+ text = payload.get("text")
132
+ if text is not None:
133
+ return {"type": "input_text", "text": str(text or "")}
134
+
135
+ inline_data = payload.get("inlineData")
136
+ if isinstance(inline_data, dict):
137
+ data = str(inline_data.get("data") or "").strip()
138
+ if not data:
139
+ return None
140
+ display_name = str(inline_data.get("displayName") or "uploaded_file")
141
+ mime_type = str(inline_data.get("mimeType") or _guess_mime_type(display_name)).strip()
142
+ if mime_type.startswith("image/"):
143
+ return {
144
+ "type": "input_image",
145
+ "image_url": _data_url_from_inline_data(inline_data),
146
+ }
147
+ return {
148
+ "type": "input_file",
149
+ "filename": display_name,
150
+ "file_data": data,
151
+ }
152
+
153
+ file_data = payload.get("fileData")
154
+ if isinstance(file_data, dict):
155
+ file_uri = str(file_data.get("fileUri") or "").strip()
156
+ display_name = str(file_data.get("displayName") or file_uri or "uploaded_file")
157
+ mime_type = str(file_data.get("mimeType") or _guess_mime_type(display_name)).strip()
158
+ if mime_type.startswith("image/") and file_uri:
159
+ return {
160
+ "type": "input_image",
161
+ "image_url": file_uri,
162
+ }
163
+ block: Dict[str, Any] = {
164
+ "type": "input_file",
165
+ "filename": display_name,
166
+ }
167
+ if file_uri:
168
+ block["file_url"] = file_uri
169
+ return block
170
+
171
+ return None
172
+
173
+
174
+ def _canonical_input_content_from_item(item: Dict[str, Any]) -> Optional[Dict[str, Any]]:
175
+ item_type = str(item.get("type") or "").strip()
176
+ if item_type in {"input_text", "text"} or (
177
+ not item_type and item.get("text") is not None
178
+ ):
179
+ return {"type": "input_text", "text": str(item.get("text") or "")}
180
+
181
+ if item_type in {"input_image", "image_url"}:
182
+ image_url = _extract_openai_image_url(item.get("image_url"))
183
+ if not image_url:
184
+ return None
185
+ block: Dict[str, Any] = {"type": "input_image", "image_url": image_url}
186
+ if item.get("detail") is not None:
187
+ block["detail"] = item.get("detail")
188
+ return block
189
+
190
+ if item_type == "input_file":
191
+ block = {"type": "input_file"}
192
+ filename = item.get("filename") or item.get("displayName") or item.get("display_name")
193
+ if filename is not None:
194
+ block["filename"] = str(filename)
195
+ if item.get("file_data") is not None:
196
+ block["file_data"] = str(item.get("file_data") or "")
197
+ if item.get("file_url") is not None:
198
+ block["file_url"] = str(item.get("file_url") or "")
199
+ elif item.get("fileUri") is not None:
200
+ block["file_url"] = str(item.get("fileUri") or "")
201
+ if item.get("file_id") is not None:
202
+ block["file_id"] = str(item.get("file_id") or "")
203
+ if len(block) > 1:
204
+ return block
205
+
206
+ legacy_block = _canonical_input_content_from_part_payload(item)
207
+ if legacy_block is not None:
208
+ return legacy_block
209
+ return None
210
+
211
+
212
+ def canonical_input_content_from_parts(parts: List[Dict[str, Any]]) -> List[Dict[str, Any]]:
213
+ canonical: List[Dict[str, Any]] = []
214
+ for part in parts or []:
215
+ if not isinstance(part, dict):
216
+ continue
217
+ block = _canonical_input_content_from_part_payload(part)
218
+ if block is not None:
219
+ canonical.append(block)
220
+ return canonical
221
+
222
+
223
+ def canonical_input_content_from_message_content(content: Any) -> List[Dict[str, Any]]:
224
+ if isinstance(content, list):
225
+ canonical: List[Dict[str, Any]] = []
226
+ for item in content:
227
+ if not isinstance(item, dict):
228
+ continue
229
+ block = _canonical_input_content_from_item(item)
230
+ if block is not None:
231
+ canonical.append(block)
232
+ return canonical
233
+ text = str(content or "")
234
+ return [{"type": "input_text", "text": text}] if text else []
235
+
236
+
237
+ def _part_payload_from_content_item(item: Dict[str, Any]) -> Dict[str, Any]:
238
+ payload: Dict[str, Any] = {}
239
+ if item.get("text") is not None:
240
+ payload["text"] = str(item.get("text") or "")
241
+ if item.get("inlineData") is not None:
242
+ payload["inlineData"] = item.get("inlineData")
243
+ if item.get("fileData") is not None:
244
+ payload["fileData"] = item.get("fileData")
245
+
246
+ item_type = str(item.get("type") or "").strip()
247
+ if item_type == "input_image" and "inlineData" not in payload and "fileData" not in payload:
248
+ display_name = str(item.get("displayName") or item.get("display_name") or "uploaded_image")
249
+ image_url = _extract_openai_image_url(item.get("image_url"))
250
+ inline_data = _inline_data_from_data_url(image_url, display_name=display_name)
251
+ if inline_data is not None:
252
+ payload["inlineData"] = inline_data
253
+ else:
254
+ file_data = _file_data_from_openai_image_url(image_url, display_name=display_name)
255
+ if file_data is not None:
256
+ payload["fileData"] = file_data
257
+ if item_type == "image_url" and "inlineData" not in payload and "fileData" not in payload:
258
+ display_name = str(item.get("displayName") or item.get("display_name") or "uploaded_image")
259
+ image_url = _extract_openai_image_url(item.get("image_url"))
260
+ inline_data = _inline_data_from_data_url(image_url, display_name=display_name)
261
+ if inline_data is not None:
262
+ payload["inlineData"] = inline_data
263
+ else:
264
+ file_data = _file_data_from_openai_image_url(image_url, display_name=display_name)
265
+ if file_data is not None:
266
+ payload["fileData"] = file_data
267
+ if item_type == "input_file" and "inlineData" not in payload and "fileData" not in payload:
268
+ inline_data = _inline_data_from_openai_file(item)
269
+ if inline_data is not None:
270
+ payload["inlineData"] = inline_data
271
+ else:
272
+ file_data = _file_data_from_openai_file(item)
273
+ if file_data is not None:
274
+ payload["fileData"] = file_data
275
+
276
+ return payload
277
+
278
+
279
+ def attachment_prompt_text(attachment: Dict[str, Any]) -> str:
280
+ result = build_attachment_results([attachment])[0]
281
+ return build_attachment_prompt_text(result)
282
+
283
+
284
+ def extract_user_input_from_parts(parts: List[Part]) -> str:
285
+ return str(normalize_parts_content(parts).get("content") or "")
286
+
287
+
288
+ def compact_attachment_for_session(attachment: Dict[str, Any]) -> Dict[str, Any]:
289
+ return {
290
+ key: value
291
+ for key, value in attachment.items()
292
+ if key in {"display_name", "mime_type", "transport", "size_bytes", "is_text", "file_uri"}
293
+ and value not in (None, "")
294
+ }
295
+
296
+
297
+ def attachment_from_part(part: Part) -> Optional[Dict[str, Any]]:
298
+ inline = part.inlineData
299
+ if inline and inline.data:
300
+ display_name = inline.displayName or "uploaded_file"
301
+ mime_type = (inline.mimeType or "").strip() or "application/octet-stream"
302
+ try:
303
+ raw = decode_inline_data(inline.data)
304
+ except Exception:
305
+ raw = b""
306
+ return {
307
+ "display_name": display_name,
308
+ "mime_type": mime_type,
309
+ "transport": "inline",
310
+ "data": inline.data.strip(),
311
+ "is_text": looks_like_textual_attachment(mime_type, display_name),
312
+ "size_bytes": len(raw),
313
+ }
314
+
315
+ file_data = part.fileData
316
+ if file_data and (file_data.fileUri or file_data.displayName):
317
+ display_name = file_data.displayName or file_data.fileUri or "uploaded_file"
318
+ mime_type = (file_data.mimeType or "").strip() or "application/octet-stream"
319
+ storage_path = resolve_attachment_storage_path(file_data.fileUri or "")
320
+ try:
321
+ size_bytes = storage_path.stat().st_size if storage_path and storage_path.exists() else None
322
+ except OSError:
323
+ size_bytes = None
324
+ return {
325
+ "display_name": display_name,
326
+ "mime_type": mime_type,
327
+ "transport": "reference",
328
+ "file_uri": file_data.fileUri or "",
329
+ "is_text": looks_like_textual_attachment(mime_type, display_name),
330
+ "size_bytes": size_bytes,
331
+ "storage_path": str(storage_path) if storage_path else None,
332
+ }
333
+
334
+ return None
335
+
336
+
337
+ def display_content_from_parts(parts: List[Part]) -> str:
338
+ text_segments: List[str] = []
339
+ attachment_names: List[str] = []
340
+
341
+ for part in parts or []:
342
+ if part.text:
343
+ text_segments.append(part.text)
344
+ continue
345
+
346
+ inline = part.inlineData
347
+ if inline and (inline.displayName or inline.data):
348
+ attachment_names.append(inline.displayName or "uploaded_file")
349
+ continue
350
+
351
+ file_data = part.fileData
352
+ if file_data and (file_data.displayName or file_data.fileUri):
353
+ attachment_names.append(file_data.displayName or file_data.fileUri or "uploaded_file")
354
+
355
+ blocks = [segment.strip() for segment in text_segments if str(segment).strip()]
356
+ if attachment_names:
357
+ attachment_block = "## 附件\n" + "\n".join(f"- {name}" for name in attachment_names)
358
+ blocks.append(attachment_block)
359
+ return "\n\n".join(blocks).strip()
360
+
361
+
362
+ def normalize_parts_content(parts: List[Part]) -> dict[str, Any]:
363
+ attachments = [attachment for attachment in (attachment_from_part(part) for part in parts) if attachment]
364
+ attachment_results = build_attachment_results(attachments)
365
+ display_content = display_content_from_parts(parts)
366
+ segments: List[str] = []
367
+ attachment_index = 0
368
+ for part in parts or []:
369
+ if part.text:
370
+ segments.append(part.text)
371
+ continue
372
+ if attachment_index < len(attachment_results):
373
+ segments.append(build_attachment_prompt_text(attachment_results[attachment_index]))
374
+ attachment_index += 1
375
+ return {
376
+ "content": "\n\n".join(segment.strip() for segment in segments if str(segment).strip()).strip(),
377
+ "display_content": display_content,
378
+ "parts": [part.model_dump(exclude_none=True) for part in parts],
379
+ "attachments": attachments,
380
+ "attachment_results": attachment_results,
381
+ }
382
+
383
+
384
+ def normalize_kop_message_content(content: Any) -> dict[str, Any]:
385
+ input_content = canonical_input_content_from_message_content(content)
386
+ if isinstance(content, list):
387
+ parts: List[Part] = []
388
+ for item in content:
389
+ if not isinstance(item, dict):
390
+ continue
391
+ payload = _part_payload_from_content_item(item)
392
+ if not payload:
393
+ continue
394
+ try:
395
+ parts.append(Part.model_validate(payload))
396
+ except Exception:
397
+ continue
398
+ normalized = normalize_parts_content(parts)
399
+ normalized["input_content"] = input_content
400
+ return normalized
401
+ text = str(content or "")
402
+ return {
403
+ "content": text,
404
+ "display_content": text,
405
+ "parts": [{"text": text}] if text else [],
406
+ "input_content": input_content,
407
+ "attachments": [],
408
+ "attachment_results": [],
409
+ }
410
+
411
+
412
+ def normalize_kop_messages(messages: List[Dict[str, Any]]) -> List[Dict[str, Any]]:
413
+ normalized: List[Dict[str, Any]] = []
414
+ for message in messages or []:
415
+ role = str(message.get("role") or "user")
416
+ normalized_content = normalize_kop_message_content(message.get("content", ""))
417
+ normalized.append(
418
+ {
419
+ "role": role,
420
+ "content": str(normalized_content.get("content") or ""),
421
+ "display_content": str(normalized_content.get("display_content") or ""),
422
+ "parts": list(normalized_content.get("parts") or []),
423
+ "input_content": list(normalized_content.get("input_content") or []),
424
+ "attachments": list(normalized_content.get("attachments") or []),
425
+ "attachment_results": list(normalized_content.get("attachment_results") or []),
426
+ }
427
+ )
428
+ return normalized
429
+
430
+
431
+ def normalize_responses_input(input_payload: Any) -> List[Dict[str, Any]]:
432
+ if isinstance(input_payload, str):
433
+ return [
434
+ {
435
+ "role": "user",
436
+ "content": input_payload,
437
+ "display_content": input_payload,
438
+ "parts": [{"text": input_payload}] if input_payload else [],
439
+ "input_content": [{"type": "input_text", "text": input_payload}] if input_payload else [],
440
+ "attachments": [],
441
+ "attachment_results": [],
442
+ }
443
+ ]
444
+ if isinstance(input_payload, list):
445
+ return normalize_kop_messages(input_payload)
446
+ return []
@@ -0,0 +1,91 @@
1
+ from __future__ import annotations
2
+
3
+ import re
4
+ from dataclasses import dataclass, field
5
+ from typing import Literal
6
+
7
+ ReasoningPartKind = Literal["thinking", "text"]
8
+
9
+
10
+ @dataclass(frozen=True)
11
+ class ReasoningMarkupPart:
12
+ kind: ReasoningPartKind
13
+ text: str
14
+
15
+
16
+ @dataclass
17
+ class ReasoningMarkupParser:
18
+ """Incrementally split inline <think> markup out of streamed text."""
19
+
20
+ _buffer: str = ""
21
+ _in_think: bool = False
22
+ _pending: list[ReasoningMarkupPart] = field(default_factory=list)
23
+
24
+ def feed(self, chunk: str) -> list[ReasoningMarkupPart]:
25
+ self._buffer += str(chunk or "")
26
+ parts: list[ReasoningMarkupPart] = []
27
+
28
+ while self._buffer:
29
+ tag = "</think>" if self._in_think else "<think>"
30
+ index = self._buffer.find(tag)
31
+ if index >= 0:
32
+ self._append(parts, self._buffer[:index])
33
+ self._buffer = self._buffer[index + len(tag):]
34
+ self._in_think = not self._in_think
35
+ continue
36
+
37
+ prefix_len = self._partial_tag_prefix_len(self._buffer, tag)
38
+ if self._in_think:
39
+ break
40
+ emit_len = len(self._buffer) - prefix_len
41
+ if emit_len <= 0:
42
+ break
43
+ self._append(parts, self._buffer[:emit_len])
44
+ self._buffer = self._buffer[emit_len:]
45
+ break
46
+
47
+ return self._merge(parts)
48
+
49
+ def flush(self) -> list[ReasoningMarkupPart]:
50
+ if not self._buffer:
51
+ return []
52
+ parts: list[ReasoningMarkupPart] = []
53
+ self._append(parts, self._buffer)
54
+ self._buffer = ""
55
+ return self._merge(parts)
56
+
57
+ def _append(self, parts: list[ReasoningMarkupPart], text: str) -> None:
58
+ if not text:
59
+ return
60
+ parts.append(ReasoningMarkupPart("thinking" if self._in_think else "text", text))
61
+
62
+ @staticmethod
63
+ def _merge(parts: list[ReasoningMarkupPart]) -> list[ReasoningMarkupPart]:
64
+ merged: list[ReasoningMarkupPart] = []
65
+ for part in parts:
66
+ if not part.text:
67
+ continue
68
+ if merged and merged[-1].kind == part.kind:
69
+ merged[-1] = ReasoningMarkupPart(part.kind, merged[-1].text + part.text)
70
+ else:
71
+ merged.append(part)
72
+ return merged
73
+
74
+ @staticmethod
75
+ def _partial_tag_prefix_len(value: str, tag: str) -> int:
76
+ max_len = min(len(value), len(tag) - 1)
77
+ for size in range(max_len, 0, -1):
78
+ if tag.startswith(value[-size:]):
79
+ return size
80
+ return 0
81
+
82
+
83
+ def strip_reasoning_markup(text: str) -> str:
84
+ """Remove inline <think> blocks from text used as final answer or title input."""
85
+ value = str(text or "")
86
+ if not value:
87
+ return ""
88
+ value = re.sub(r"<think\b[^>]*>.*?</think>", "", value, flags=re.IGNORECASE | re.DOTALL)
89
+ value = re.sub(r"<think\b[^>]*>.*$", "", value, flags=re.IGNORECASE | re.DOTALL)
90
+ value = re.sub(r"</?think\b[^>]*>", "", value, flags=re.IGNORECASE)
91
+ return value
@@ -0,0 +1,61 @@
1
+ """run_status 事件的 run_mode / run_trigger 枚举常量。
2
+
3
+ canonical 定义,供 ksadk runtime 与 server 各自维护同名常量保持一致。
4
+ 两个维度独立:
5
+ - run_mode:怎么跑(background/foreground/unknown)
6
+ - run_trigger:怎么开始(new_run/checkpoint_resume/approval_resume/unknown)
7
+ """
8
+
9
+ from __future__ import annotations
10
+
11
+ from typing import Literal, Mapping
12
+
13
+ RunMode = Literal["background", "foreground", "unknown"]
14
+ RunTrigger = Literal["new_run", "checkpoint_resume", "approval_resume", "unknown"]
15
+
16
+ RUN_MODE_BACKGROUND = "background"
17
+ RUN_MODE_FOREGROUND = "foreground"
18
+ RUN_MODE_UNKNOWN = "unknown"
19
+
20
+ RUN_TRIGGER_NEW_RUN = "new_run"
21
+ RUN_TRIGGER_CHECKPOINT_RESUME = "checkpoint_resume"
22
+ RUN_TRIGGER_APPROVAL_RESUME = "approval_resume"
23
+ RUN_TRIGGER_UNKNOWN = "unknown"
24
+
25
+ _VALID_RUN_MODES = {"background", "foreground", "unknown"}
26
+ _VALID_RUN_TRIGGERS = {"new_run", "checkpoint_resume", "approval_resume", "unknown"}
27
+
28
+
29
+ def validate_run_mode(value: str | None) -> str:
30
+ """非法值或 None 降级为 unknown,避免脏值落库。"""
31
+ return value if value in _VALID_RUN_MODES else RUN_MODE_UNKNOWN
32
+
33
+
34
+ def validate_run_trigger(value: str | None) -> str:
35
+ """非法值或 None 降级为 unknown,避免脏值落库。"""
36
+ return value if value in _VALID_RUN_TRIGGERS else RUN_TRIGGER_UNKNOWN
37
+
38
+
39
+ def trigger_from_resume_input(resume_input: dict | Mapping | None) -> str:
40
+ """从 resume_input 推导 run_trigger。
41
+
42
+ - checkpoint resume(agentengine.resume_checkpoint)→ checkpoint_resume
43
+ - approval resume(mcp_approval_response)→ approval_resume
44
+ - None / 无 type → new_run
45
+ - 其他未知 type → unknown
46
+ """
47
+ if resume_input is None:
48
+ return RUN_TRIGGER_NEW_RUN
49
+ resume_type = str(resume_input.get("type") or "").strip()
50
+ if resume_type == "agentengine.resume_checkpoint":
51
+ return RUN_TRIGGER_CHECKPOINT_RESUME
52
+ if resume_type in {
53
+ "mcp_approval_response",
54
+ "function_call_output",
55
+ "ksadk.approval_response",
56
+ "ksadk_resume",
57
+ }:
58
+ return RUN_TRIGGER_APPROVAL_RESUME
59
+ if not resume_type:
60
+ return RUN_TRIGGER_NEW_RUN
61
+ return RUN_TRIGGER_UNKNOWN
@@ -0,0 +1,53 @@
1
+ """Agent run 状态枚举。
2
+
3
+ run_status 事件 content.status / metadata.status 的合法值集合。
4
+ 用 Literal + frozenset 常量(非 Enum),因为值要直接序列化进 JSON 事件,
5
+ Enum 还需 .value 转换。
6
+
7
+ 此模块刻意不依赖 ksadk 任何其他模块,避免 conversations.runtime ↔ server.app
8
+ 之间的循环导入。canonical 定义在这里,runtime.py 和 server/app.py 都从本模块导入。
9
+ """
10
+
11
+ from __future__ import annotations
12
+
13
+ from typing import Literal
14
+
15
+ RunStatus = Literal[
16
+ # active
17
+ "in_progress",
18
+ "running",
19
+ "resuming",
20
+ "starting",
21
+ # terminal
22
+ "completed",
23
+ "failed",
24
+ "cancelled",
25
+ "interrupted",
26
+ "resume_failed",
27
+ # 派生 / 兼容别名
28
+ "checkpointed",
29
+ "error",
30
+ "canceled",
31
+ "aborted",
32
+ ]
33
+
34
+ RUN_STATUS_TERMINAL: frozenset[str] = frozenset(
35
+ {
36
+ "completed",
37
+ "failed",
38
+ "error",
39
+ "cancelled",
40
+ "canceled",
41
+ "aborted",
42
+ "interrupted",
43
+ "resume_failed",
44
+ }
45
+ )
46
+ RUN_STATUS_ACTIVE: frozenset[str] = frozenset(
47
+ {
48
+ "in_progress",
49
+ "running",
50
+ "resuming",
51
+ "starting",
52
+ }
53
+ )