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.
- agentengine_sdk_python-0.7.0.dist-info/METADATA +181 -0
- agentengine_sdk_python-0.7.0.dist-info/RECORD +482 -0
- {agentengine_sdk_python-0.6.4.dist-info → agentengine_sdk_python-0.7.0.dist-info}/WHEEL +1 -1
- agentengine_sdk_python-0.7.0.dist-info/entry_points.txt +3 -0
- agentengine_sdk_python-0.7.0.dist-info/licenses/LICENSE +175 -0
- agentengine_sdk_python-0.7.0.dist-info/top_level.txt +2 -0
- ksadk/__init__.py +13 -0
- ksadk/__main__.py +4 -0
- ksadk/a2a/__init__.py +15 -0
- ksadk/a2a/card_builder.py +64 -0
- ksadk/a2a/client.py +309 -0
- ksadk/a2a/executor.py +201 -0
- ksadk/a2a/server.py +79 -0
- ksadk/agents/__init__.py +20 -0
- ksadk/agents/base.py +370 -0
- ksadk/agents/context.py +38 -0
- ksadk/agents/event.py +35 -0
- ksadk/agents/loop_agent.py +71 -0
- ksadk/agents/parallel_agent.py +109 -0
- ksadk/agents/runner_adapter.py +24 -0
- ksadk/agents/sequential_agent.py +34 -0
- ksadk/api/__init__.py +3 -0
- ksadk/api/client.py +2246 -0
- ksadk/builders/__init__.py +20 -0
- ksadk/builders/base.py +66 -0
- ksadk/builders/code_builder.py +1990 -0
- ksadk/builders/container_builder.py +786 -0
- ksadk/builders/framework_requirements.py +59 -0
- ksadk/builders/ks3_uploader.py +389 -0
- ksadk/builders/mcp_builder.py +476 -0
- ksadk/builders/requirements_utils.py +75 -0
- ksadk/cli/__init__.py +531 -0
- ksadk/cli/__main__.py +4 -0
- ksadk/cli/agent_ref.py +204 -0
- ksadk/cli/cmd_a2a.py +167 -0
- ksadk/cli/cmd_agent.py +201 -0
- ksadk/cli/cmd_build.py +270 -0
- ksadk/cli/cmd_completion.py +304 -0
- ksadk/cli/cmd_config.py +758 -0
- ksadk/cli/cmd_create.py +2304 -0
- ksadk/cli/cmd_dashboard.py +900 -0
- ksadk/cli/cmd_deploy.py +704 -0
- ksadk/cli/cmd_destroy.py +345 -0
- ksadk/cli/cmd_files.py +1227 -0
- ksadk/cli/cmd_hermes.py +1263 -0
- ksadk/cli/cmd_invoke.py +1503 -0
- ksadk/cli/cmd_launch.py +564 -0
- ksadk/cli/cmd_mcp.py +1179 -0
- ksadk/cli/cmd_model.py +302 -0
- ksadk/cli/cmd_openclaw.py +3922 -0
- ksadk/cli/cmd_run.py +239 -0
- ksadk/cli/cmd_status.py +588 -0
- ksadk/cli/cmd_version.py +522 -0
- ksadk/cli/cmd_web.py +288 -0
- ksadk/cli/deploy_utils.py +87 -0
- ksadk/cli/dry_run.py +214 -0
- ksadk/cli/env_options.py +82 -0
- ksadk/cli/error_utils.py +525 -0
- ksadk/cli/global_options.py +31 -0
- ksadk/cli/local_runtime.py +97 -0
- ksadk/cli/model_catalog.py +136 -0
- ksadk/cli/network_options.py +412 -0
- ksadk/cli/resource_common.py +621 -0
- ksadk/cli/storage.py +84 -0
- ksadk/cli/ui.py +431 -0
- ksadk/cli/workflow_common.py +552 -0
- ksadk/common/__init__.py +14 -0
- ksadk/common/aicp_env.py +128 -0
- ksadk/common/auth.py +190 -0
- ksadk/common/constants.py +84 -0
- ksadk/common/llm_utils.py +61 -0
- ksadk/configs/__init__.py +61 -0
- ksadk/configs/env_registry.py +343 -0
- ksadk/configs/global_config.py +200 -0
- ksadk/configs/settings.py +706 -0
- ksadk/conversations/__init__.py +95 -0
- ksadk/conversations/attachment_storage.py +379 -0
- ksadk/conversations/attachments.py +774 -0
- ksadk/conversations/compaction_pipeline.py +387 -0
- ksadk/conversations/compaction_prompt.py +128 -0
- ksadk/conversations/context.py +303 -0
- ksadk/conversations/message_projection.py +269 -0
- ksadk/conversations/model_context.py +370 -0
- ksadk/conversations/model_options.py +136 -0
- ksadk/conversations/normalize.py +446 -0
- ksadk/conversations/reasoning_markup.py +91 -0
- ksadk/conversations/run_kinds.py +61 -0
- ksadk/conversations/run_status.py +53 -0
- ksadk/conversations/runtime.py +5276 -0
- ksadk/conversations/semantic_summary.py +359 -0
- ksadk/conversations/session_title.py +254 -0
- ksadk/deployment/__init__.py +83 -0
- ksadk/deployment/agent_access.py +226 -0
- ksadk/deployment/base.py +229 -0
- ksadk/deployment/manager.py +332 -0
- ksadk/deployment/providers/__init__.py +10 -0
- ksadk/deployment/providers/serverless.py +1115 -0
- ksadk/deployment/registry.py +120 -0
- ksadk/deployment/state.py +78 -0
- ksadk/deployment/ui_config.py +21 -0
- ksadk/detection/__init__.py +7 -0
- ksadk/detection/detector.py +431 -0
- ksadk/detection/mcp_detector.py +250 -0
- ksadk/hermes_terminal.py +467 -0
- ksadk/identity/__init__.py +17 -0
- ksadk/identity/resolver.py +385 -0
- ksadk/knowledge_base/__init__.py +62 -0
- ksadk/knowledge_base/adk_tool.py +47 -0
- ksadk/knowledge_base/client.py +297 -0
- ksadk/knowledge_base/langchain_tool.py +55 -0
- ksadk/knowledge_base/service.py +66 -0
- ksadk/knowledge_base/tool.py +50 -0
- ksadk/markdown.py +169 -0
- ksadk/mcp_runtime/__init__.py +231 -0
- ksadk/memory/__init__.py +57 -0
- ksadk/memory/adk/__init__.py +51 -0
- ksadk/memory/adk/backends/__init__.py +5 -0
- ksadk/memory/adk/backends/base_ltm_backend.py +52 -0
- ksadk/memory/adk/backends/http_ltm_backend.py +183 -0
- ksadk/memory/adk/backends/inmemory_ltm_backend.py +96 -0
- ksadk/memory/adk/backends/sdk_ltm_backend.py +456 -0
- ksadk/memory/adk/long_term_memory.py +273 -0
- ksadk/memory/adk/resilient_session_service.py +268 -0
- ksadk/memory/adk/short_term_memory.py +304 -0
- ksadk/memory/adk_tool.py +31 -0
- ksadk/memory/backends/__init__.py +6 -0
- ksadk/memory/backends/base.py +103 -0
- ksadk/memory/backends/memory.py +112 -0
- ksadk/memory/backends/redis.py +146 -0
- ksadk/memory/langchain_tool.py +39 -0
- ksadk/memory/ltm_backend_factory.py +24 -0
- ksadk/memory/manager.py +215 -0
- ksadk/memory/service.py +172 -0
- ksadk/memory/tool.py +96 -0
- ksadk/model_policy.py +223 -0
- ksadk/openclaw_gateway.py +378 -0
- ksadk/runners/__init__.py +8 -0
- ksadk/runners/adk_runner.py +1994 -0
- ksadk/runners/base_runner.py +305 -0
- ksadk/runners/deepagents_runner.py +13 -0
- ksadk/runners/factory.py +73 -0
- ksadk/runners/langchain_runner.py +751 -0
- ksadk/runners/langgraph_runner.py +985 -0
- ksadk/runners/patch_langchain.py +187 -0
- ksadk/runners/remote_runner.py +792 -0
- ksadk/runners/usage_accumulator.py +38 -0
- ksadk/runners/utils/__init__.py +19 -0
- ksadk/runners/utils/langfuse.py +230 -0
- ksadk/runners/utils/loader.py +62 -0
- ksadk/runtime_context.py +166 -0
- ksadk/runtime_state.py +25 -0
- ksadk/sandbox/__init__.py +28 -0
- ksadk/sandbox/backends/__init__.py +9 -0
- ksadk/sandbox/backends/e2b.py +154 -0
- ksadk/sandbox/backends/local_process.py +131 -0
- ksadk/sandbox/base.py +101 -0
- ksadk/sandbox/factory.py +53 -0
- ksadk/sandbox/registry.py +187 -0
- ksadk/server/__init__.py +7 -0
- ksadk/server/api_models.py +73 -0
- ksadk/server/app.py +3931 -0
- ksadk/server/static/assets/ArtifactsPanel-D-SSn2ee.js +1 -0
- ksadk/server/static/assets/CodeBlock-P16VOLYi.js +9 -0
- ksadk/server/static/assets/KaTeX_AMS-Regular-BQhdFMY1.woff2 +0 -0
- ksadk/server/static/assets/KaTeX_AMS-Regular-DMm9YOAa.woff +0 -0
- ksadk/server/static/assets/KaTeX_AMS-Regular-DRggAlZN.ttf +0 -0
- ksadk/server/static/assets/KaTeX_Caligraphic-Bold-ATXxdsX0.ttf +0 -0
- ksadk/server/static/assets/KaTeX_Caligraphic-Bold-BEiXGLvX.woff +0 -0
- ksadk/server/static/assets/KaTeX_Caligraphic-Bold-Dq_IR9rO.woff2 +0 -0
- ksadk/server/static/assets/KaTeX_Caligraphic-Regular-CTRA-rTL.woff +0 -0
- ksadk/server/static/assets/KaTeX_Caligraphic-Regular-Di6jR-x-.woff2 +0 -0
- ksadk/server/static/assets/KaTeX_Caligraphic-Regular-wX97UBjC.ttf +0 -0
- ksadk/server/static/assets/KaTeX_Fraktur-Bold-BdnERNNW.ttf +0 -0
- ksadk/server/static/assets/KaTeX_Fraktur-Bold-BsDP51OF.woff +0 -0
- ksadk/server/static/assets/KaTeX_Fraktur-Bold-CL6g_b3V.woff2 +0 -0
- ksadk/server/static/assets/KaTeX_Fraktur-Regular-CB_wures.ttf +0 -0
- ksadk/server/static/assets/KaTeX_Fraktur-Regular-CTYiF6lA.woff2 +0 -0
- ksadk/server/static/assets/KaTeX_Fraktur-Regular-Dxdc4cR9.woff +0 -0
- ksadk/server/static/assets/KaTeX_Main-Bold-Cx986IdX.woff2 +0 -0
- ksadk/server/static/assets/KaTeX_Main-Bold-Jm3AIy58.woff +0 -0
- ksadk/server/static/assets/KaTeX_Main-Bold-waoOVXN0.ttf +0 -0
- ksadk/server/static/assets/KaTeX_Main-BoldItalic-DxDJ3AOS.woff2 +0 -0
- ksadk/server/static/assets/KaTeX_Main-BoldItalic-DzxPMmG6.ttf +0 -0
- ksadk/server/static/assets/KaTeX_Main-BoldItalic-SpSLRI95.woff +0 -0
- ksadk/server/static/assets/KaTeX_Main-Italic-3WenGoN9.ttf +0 -0
- ksadk/server/static/assets/KaTeX_Main-Italic-BMLOBm91.woff +0 -0
- ksadk/server/static/assets/KaTeX_Main-Italic-NWA7e6Wa.woff2 +0 -0
- ksadk/server/static/assets/KaTeX_Main-Regular-B22Nviop.woff2 +0 -0
- ksadk/server/static/assets/KaTeX_Main-Regular-Dr94JaBh.woff +0 -0
- ksadk/server/static/assets/KaTeX_Main-Regular-ypZvNtVU.ttf +0 -0
- ksadk/server/static/assets/KaTeX_Math-BoldItalic-B3XSjfu4.ttf +0 -0
- ksadk/server/static/assets/KaTeX_Math-BoldItalic-CZnvNsCZ.woff2 +0 -0
- ksadk/server/static/assets/KaTeX_Math-BoldItalic-iY-2wyZ7.woff +0 -0
- ksadk/server/static/assets/KaTeX_Math-Italic-DA0__PXp.woff +0 -0
- ksadk/server/static/assets/KaTeX_Math-Italic-flOr_0UB.ttf +0 -0
- ksadk/server/static/assets/KaTeX_Math-Italic-t53AETM-.woff2 +0 -0
- ksadk/server/static/assets/KaTeX_SansSerif-Bold-CFMepnvq.ttf +0 -0
- ksadk/server/static/assets/KaTeX_SansSerif-Bold-D1sUS0GD.woff2 +0 -0
- ksadk/server/static/assets/KaTeX_SansSerif-Bold-DbIhKOiC.woff +0 -0
- ksadk/server/static/assets/KaTeX_SansSerif-Italic-C3H0VqGB.woff2 +0 -0
- ksadk/server/static/assets/KaTeX_SansSerif-Italic-DN2j7dab.woff +0 -0
- ksadk/server/static/assets/KaTeX_SansSerif-Italic-YYjJ1zSn.ttf +0 -0
- ksadk/server/static/assets/KaTeX_SansSerif-Regular-BNo7hRIc.ttf +0 -0
- ksadk/server/static/assets/KaTeX_SansSerif-Regular-CS6fqUqJ.woff +0 -0
- ksadk/server/static/assets/KaTeX_SansSerif-Regular-DDBCnlJ7.woff2 +0 -0
- ksadk/server/static/assets/KaTeX_Script-Regular-C5JkGWo-.ttf +0 -0
- ksadk/server/static/assets/KaTeX_Script-Regular-D3wIWfF6.woff2 +0 -0
- ksadk/server/static/assets/KaTeX_Script-Regular-D5yQViql.woff +0 -0
- ksadk/server/static/assets/KaTeX_Size1-Regular-C195tn64.woff +0 -0
- ksadk/server/static/assets/KaTeX_Size1-Regular-Dbsnue_I.ttf +0 -0
- ksadk/server/static/assets/KaTeX_Size1-Regular-mCD8mA8B.woff2 +0 -0
- ksadk/server/static/assets/KaTeX_Size2-Regular-B7gKUWhC.ttf +0 -0
- ksadk/server/static/assets/KaTeX_Size2-Regular-Dy4dx90m.woff2 +0 -0
- ksadk/server/static/assets/KaTeX_Size2-Regular-oD1tc_U0.woff +0 -0
- ksadk/server/static/assets/KaTeX_Size3-Regular-CTq5MqoE.woff +0 -0
- ksadk/server/static/assets/KaTeX_Size3-Regular-DgpXs0kz.ttf +0 -0
- ksadk/server/static/assets/KaTeX_Size4-Regular-BF-4gkZK.woff +0 -0
- ksadk/server/static/assets/KaTeX_Size4-Regular-DWFBv043.ttf +0 -0
- ksadk/server/static/assets/KaTeX_Size4-Regular-Dl5lxZxV.woff2 +0 -0
- ksadk/server/static/assets/KaTeX_Typewriter-Regular-C0xS9mPB.woff +0 -0
- ksadk/server/static/assets/KaTeX_Typewriter-Regular-CO6r4hn1.woff2 +0 -0
- ksadk/server/static/assets/KaTeX_Typewriter-Regular-D3Ib7_Hf.ttf +0 -0
- ksadk/server/static/assets/MathMessageMarkdown-CdGiQWHR.js +8 -0
- ksadk/server/static/assets/MathMessageMarkdown-DeYh8QPr.css +1 -0
- ksadk/server/static/assets/MermaidBlock-IOcal8cm.js +303 -0
- ksadk/server/static/assets/NativeTerminalPanel-CHOd7Rch.css +1 -0
- ksadk/server/static/assets/NativeTerminalPanel-DGSDWsei.js +1 -0
- ksadk/server/static/assets/addon-fit-DthTIhi3.js +1 -0
- ksadk/server/static/assets/apl-CnwPGSsG.js +1 -0
- ksadk/server/static/assets/arc-BA13sHc9.js +1 -0
- ksadk/server/static/assets/architecture-7EHR7CIX-BvUlsA6l.js +1 -0
- ksadk/server/static/assets/architectureDiagram-3BPJPVTR-DzJzgVoL.js +36 -0
- ksadk/server/static/assets/asciiarmor-qTkVPQu6.js +1 -0
- ksadk/server/static/assets/asn1-Dr8qZg38.js +1 -0
- ksadk/server/static/assets/asterisk-Bja0s6e1.js +1 -0
- ksadk/server/static/assets/blockDiagram-GPEHLZMM-UTdVcZhn.js +132 -0
- ksadk/server/static/assets/brainfuck-D5EjA2JK.js +1 -0
- ksadk/server/static/assets/c4Diagram-AAUBKEIU-Dix0GD4m.js +10 -0
- ksadk/server/static/assets/channel-CTuydARX.js +1 -0
- ksadk/server/static/assets/chunk-2J33WTMH-C2JxuZ42.js +1 -0
- ksadk/server/static/assets/chunk-4BX2VUAB-Be57QPgD.js +1 -0
- ksadk/server/static/assets/chunk-55IACEB6-WjSuy4nv.js +1 -0
- ksadk/server/static/assets/chunk-727SXJPM-BOovP-b5.js +206 -0
- ksadk/server/static/assets/chunk-AQP2D5EJ-DOmZNmWj.js +231 -0
- ksadk/server/static/assets/chunk-FMBD7UC4-DzwlodkU.js +15 -0
- ksadk/server/static/assets/chunk-ND2GUHAM-DMqAikEU.js +1 -0
- ksadk/server/static/assets/chunk-QZHKN3VN-BnCydivS.js +1 -0
- ksadk/server/static/assets/classDiagram-4FO5ZUOK-BNHg45Be.js +1 -0
- ksadk/server/static/assets/classDiagram-v2-Q7XG4LA2-BNHg45Be.js +1 -0
- ksadk/server/static/assets/clike-DHH8Ad3s.js +1 -0
- ksadk/server/static/assets/clojure-BflJGmDX.js +1 -0
- ksadk/server/static/assets/cmake-CyVbuzPu.js +1 -0
- ksadk/server/static/assets/cobol-B_OZ4V-R.js +1 -0
- ksadk/server/static/assets/coffeescript-B2pKbFk8.js +1 -0
- ksadk/server/static/assets/commonlisp-CcllspGY.js +1 -0
- ksadk/server/static/assets/cose-bilkent-S5V4N54A-Zhy2GBnP.js +1 -0
- ksadk/server/static/assets/crystal-M5-qzICs.js +1 -0
- ksadk/server/static/assets/css-CYpP4FRV.js +1 -0
- ksadk/server/static/assets/cypher-p9eYesGn.js +1 -0
- ksadk/server/static/assets/cytoscape.esm-DelgaX4f.js +321 -0
- ksadk/server/static/assets/d-BhMjBjQP.js +1 -0
- ksadk/server/static/assets/dagre-BM42HDAG-CbKrtIUz.js +4 -0
- ksadk/server/static/assets/dagre-Bx709z4p.js +1 -0
- ksadk/server/static/assets/defaultLocale-C8Fc0cco.js +1 -0
- ksadk/server/static/assets/diagram-2AECGRRQ-BRApgQRK.js +43 -0
- ksadk/server/static/assets/diagram-5GNKFQAL-D0xbnDiK.js +10 -0
- ksadk/server/static/assets/diagram-KO2AKTUF-CVugVI9L.js +3 -0
- ksadk/server/static/assets/diagram-LMA3HP47-DozUGgee.js +24 -0
- ksadk/server/static/assets/diagram-OG6HWLK6-ZOYsKlru.js +24 -0
- ksadk/server/static/assets/diff-ChtP43wD.js +1 -0
- ksadk/server/static/assets/dist-2hInLS_J.js +9 -0
- ksadk/server/static/assets/dist-8EEyGgDx.js +1 -0
- ksadk/server/static/assets/dist-8_SfK1IP.js +1 -0
- ksadk/server/static/assets/dist-B0NP_Z0z.js +23 -0
- ksadk/server/static/assets/dist-BIJVDMuB.js +1 -0
- ksadk/server/static/assets/dist-BmlMPsCc.js +2 -0
- ksadk/server/static/assets/dist-BrCcQ47T.js +1 -0
- ksadk/server/static/assets/dist-BssVmjIo.js +6 -0
- ksadk/server/static/assets/dist-C3HIIaN5.js +1 -0
- ksadk/server/static/assets/dist-CPBtqRTW.js +1 -0
- ksadk/server/static/assets/dist-CkEKJFtk.js +1 -0
- ksadk/server/static/assets/dist-D-JMdWPQ.js +1 -0
- ksadk/server/static/assets/dist-D-xOD048.js +1 -0
- ksadk/server/static/assets/dist-D57wnGWd.js +1 -0
- ksadk/server/static/assets/dist-DL_NKc_z.js +1 -0
- ksadk/server/static/assets/dist-DMezvBGJ.js +1 -0
- ksadk/server/static/assets/dist-DmFaq_Iy.js +1 -0
- ksadk/server/static/assets/dist-Dp0k7bWI.js +1 -0
- ksadk/server/static/assets/dist-DpKtt4Bo.js +1 -0
- ksadk/server/static/assets/dist-DyOkZmze.js +11 -0
- ksadk/server/static/assets/dist-DyWsb78Q.js +1 -0
- ksadk/server/static/assets/dist-gX6GOLKq.js +1 -0
- ksadk/server/static/assets/dockerfile-BLkNEvjs.js +1 -0
- ksadk/server/static/assets/dtd-DTF72YNO.js +1 -0
- ksadk/server/static/assets/dylan-C6jEEEk-.js +1 -0
- ksadk/server/static/assets/ebnf-D4c0_ac3.js +1 -0
- ksadk/server/static/assets/ecl-BSZaIHnp.js +1 -0
- ksadk/server/static/assets/eiffel-BEjRio4Q.js +1 -0
- ksadk/server/static/assets/elm-Cshzl8qu.js +1 -0
- ksadk/server/static/assets/erDiagram-TEJ5UH35-Bk-9bgE5.js +85 -0
- ksadk/server/static/assets/erlang-DaB2Rkuy.js +1 -0
- ksadk/server/static/assets/eventmodeling-FCH6USID-DsAgWnlf.js +1 -0
- ksadk/server/static/assets/factor-D7LVTn2l.js +1 -0
- ksadk/server/static/assets/fcl-ClOhbFR7.js +1 -0
- ksadk/server/static/assets/flowDiagram-I6XJVG4X-Dn9kZVuZ.js +162 -0
- ksadk/server/static/assets/forth-Cezjo90N.js +1 -0
- ksadk/server/static/assets/fortran-Bt6PBEDR.js +1 -0
- ksadk/server/static/assets/ganttDiagram-6RSMTGT7-BGxXlJqm.js +292 -0
- ksadk/server/static/assets/gas-BHEdbvp9.js +1 -0
- ksadk/server/static/assets/gherkin-oBAE_ms0.js +1 -0
- ksadk/server/static/assets/gitGraph-WXDBUCRP-BIao9Yjg.js +1 -0
- ksadk/server/static/assets/gitGraphDiagram-PVQCEYII-C7Q0X-wi.js +106 -0
- ksadk/server/static/assets/graphlib-B8gBHxth.js +1 -0
- ksadk/server/static/assets/groovy-BC3IOsC8.js +1 -0
- ksadk/server/static/assets/haskell-BRsoo5mP.js +1 -0
- ksadk/server/static/assets/haxe-DIz0ZZqd.js +1 -0
- ksadk/server/static/assets/http-CLVgA2GD.js +1 -0
- ksadk/server/static/assets/idl-BUZw3wgd.js +1 -0
- ksadk/server/static/assets/index-C00Lwg3L.js +165 -0
- ksadk/server/static/assets/index-DAURbCsP.css +1 -0
- ksadk/server/static/assets/info-J43DQDTF-CyipqGxU.js +1 -0
- ksadk/server/static/assets/infoDiagram-5YYISTIA-BO_CSqq5.js +2 -0
- ksadk/server/static/assets/init-D6jRqBbL.js +1 -0
- ksadk/server/static/assets/ishikawaDiagram-YF4QCWOH-eYLPLd46.js +70 -0
- ksadk/server/static/assets/javascript-9Tg8ixDm.js +1 -0
- ksadk/server/static/assets/journeyDiagram-JHISSGLW-De9geSb0.js +139 -0
- ksadk/server/static/assets/julia-CQfgDRfP.js +1 -0
- ksadk/server/static/assets/kanban-definition-UN3LZRKU-Cs80kQto.js +89 -0
- ksadk/server/static/assets/katex-DSrCFD8n.js +265 -0
- ksadk/server/static/assets/linear-CN9sbKTF.js +1 -0
- ksadk/server/static/assets/livescript-BXxG0Yva.js +1 -0
- ksadk/server/static/assets/lua-CiA1ziua.js +1 -0
- ksadk/server/static/assets/mathematica-u8YMmbU0.js +1 -0
- ksadk/server/static/assets/mbox-BEMVcqjs.js +1 -0
- ksadk/server/static/assets/mermaid-parser.core-DlgSBU8l.js +161 -0
- ksadk/server/static/assets/mindmap-definition-RKZ34NQL-9afz7Oug.js +96 -0
- ksadk/server/static/assets/mirc-C9zpzAZU.js +1 -0
- ksadk/server/static/assets/mllike-B45xgp2S.js +1 -0
- ksadk/server/static/assets/modelica-CqHI_q-D.js +1 -0
- ksadk/server/static/assets/mscgen-qgSLujhx.js +1 -0
- ksadk/server/static/assets/mumps-CW_TBmxz.js +1 -0
- ksadk/server/static/assets/nginx-BMaDbqW3.js +1 -0
- ksadk/server/static/assets/nsis-AQ_alPln.js +1 -0
- ksadk/server/static/assets/ntriples-d28e9m0E.js +1 -0
- ksadk/server/static/assets/octave-D2Q8cUp1.js +1 -0
- ksadk/server/static/assets/ordinal-hYBb2elL.js +1 -0
- ksadk/server/static/assets/oz-BwTct_5T.js +1 -0
- ksadk/server/static/assets/packet-YPE3B663-CGkyRxlg.js +1 -0
- ksadk/server/static/assets/pascal-Dp_KdFgX.js +1 -0
- ksadk/server/static/assets/perl-CdEHsPfU.js +1 -0
- ksadk/server/static/assets/pie-LRSECV5Y-M0uWAf4n.js +1 -0
- ksadk/server/static/assets/pieDiagram-4H26LBE5-DPv_VstN.js +30 -0
- ksadk/server/static/assets/pig-AF4Hwhju.js +1 -0
- ksadk/server/static/assets/powershell-CzG71I4L.js +1 -0
- ksadk/server/static/assets/properties-C357ku5U.js +1 -0
- ksadk/server/static/assets/protobuf-D1ij_kNL.js +1 -0
- ksadk/server/static/assets/pug-Bugr-47h.js +1 -0
- ksadk/server/static/assets/puppet-B4hC2X4m.js +1 -0
- ksadk/server/static/assets/python-BqYw9LYJ.js +1 -0
- ksadk/server/static/assets/q-B9NhS7L_.js +1 -0
- ksadk/server/static/assets/quadrantDiagram-W4KKPZXB-o77wZ1XK.js +7 -0
- ksadk/server/static/assets/r-DADKenSm.js +1 -0
- ksadk/server/static/assets/radar-GUYGQ44K-Bdbm24-x.js +1 -0
- ksadk/server/static/assets/requirementDiagram-4Y6WPE33-BYVw81VC.js +84 -0
- ksadk/server/static/assets/rpm-gpDK5sbt.js +1 -0
- ksadk/server/static/assets/ruby-DsYpTuWg.js +1 -0
- ksadk/server/static/assets/sankeyDiagram-5OEKKPKP-B7nZFMKT.js +40 -0
- ksadk/server/static/assets/sas-C2OyD2Y6.js +1 -0
- ksadk/server/static/assets/scheme-CyDdOh7e.js +1 -0
- ksadk/server/static/assets/sequenceDiagram-3UESZ5HK-BGRRrFw5.js +162 -0
- ksadk/server/static/assets/shell-Du5Qg9im.js +1 -0
- ksadk/server/static/assets/sieve-BAxa3IjF.js +1 -0
- ksadk/server/static/assets/simple-mode-DRpGK0lJ.js +1 -0
- ksadk/server/static/assets/smalltalk-BLp5-jwC.js +1 -0
- ksadk/server/static/assets/solr-BBopId9w.js +1 -0
- ksadk/server/static/assets/sparql-Dz-mlCAC.js +1 -0
- ksadk/server/static/assets/spreadsheet-CTIncYxj.js +1 -0
- ksadk/server/static/assets/sql-DcCJ9jop.js +1 -0
- ksadk/server/static/assets/stateDiagram-AJRCARHV-BUfHCoPs.js +1 -0
- ksadk/server/static/assets/stateDiagram-v2-BHNVJYJU-8xBN_gLM.js +1 -0
- ksadk/server/static/assets/stex-sDrdk2BW.js +1 -0
- ksadk/server/static/assets/stylus-DLLZ8dgm.js +1 -0
- ksadk/server/static/assets/swift-DKB6_1j6.js +1 -0
- ksadk/server/static/assets/tcl-BGfruO1u.js +1 -0
- ksadk/server/static/assets/textile-DWBqthVk.js +1 -0
- ksadk/server/static/assets/tiddlywiki-VlUiK86J.js +1 -0
- ksadk/server/static/assets/tiki-CxVlf5KZ.js +1 -0
- ksadk/server/static/assets/timeline-definition-PNZ67QCA-FbCTGrf9.js +120 -0
- ksadk/server/static/assets/toml-LvoKBwCs.js +1 -0
- ksadk/server/static/assets/treeView-BLDUP644-npMo0ak1.js +1 -0
- ksadk/server/static/assets/treemap-LRROVOQU-CHdzrrdo.js +1 -0
- ksadk/server/static/assets/troff-C2dAgh7P.js +1 -0
- ksadk/server/static/assets/ttcn-BePYh-hG.js +1 -0
- ksadk/server/static/assets/ttcn-cfg-CY0aot7Q.js +1 -0
- ksadk/server/static/assets/turtle-BDLWE2cD.js +1 -0
- ksadk/server/static/assets/vb-BthdM_4N.js +1 -0
- ksadk/server/static/assets/vbscript-D9f6rSsU.js +1 -0
- ksadk/server/static/assets/velocity-CqftRsjg.js +1 -0
- ksadk/server/static/assets/vennDiagram-CIIHVFJN-DWgwtPsJ.js +34 -0
- ksadk/server/static/assets/verilog-D-x6ne0Z.js +1 -0
- ksadk/server/static/assets/vhdl-CMrOq2q1.js +1 -0
- ksadk/server/static/assets/wardley-L42UT6IY-BEQz7wyy.js +1 -0
- ksadk/server/static/assets/wardleyDiagram-YWT4CUSO-2x8G-tTM.js +78 -0
- ksadk/server/static/assets/webidl-D5jiJvOU.js +1 -0
- ksadk/server/static/assets/xquery-fj_R-kMw.js +1 -0
- ksadk/server/static/assets/xterm-DooSxjI5.js +36 -0
- ksadk/server/static/assets/xychartDiagram-2RQKCTM6-Drma3AYl.js +7 -0
- ksadk/server/static/assets/yacas-CXXgtw0p.js +1 -0
- ksadk/server/static/assets/z80-CL1naaMV.js +1 -0
- ksadk/server/static/favicon.svg +1 -0
- ksadk/server/static/icons.svg +24 -0
- ksadk/server/static/index.html +14 -0
- ksadk/server/terminal_sessions.py +551 -0
- ksadk/sessions/__init__.py +279 -0
- ksadk/sessions/base.py +354 -0
- ksadk/sessions/continuity.py +337 -0
- ksadk/sessions/errors.py +7 -0
- ksadk/sessions/in_memory.py +273 -0
- ksadk/sessions/local_service.py +949 -0
- ksadk/sessions/postgres_service.py +901 -0
- ksadk/sessions/resilience.py +52 -0
- ksadk/sessions/resilient.py +360 -0
- ksadk/sessions/sqlite_service.py +13 -0
- ksadk/skills/__init__.py +9 -0
- ksadk/skills/loader.py +46 -0
- ksadk/skills/models.py +120 -0
- ksadk/skills/package_store.py +104 -0
- ksadk/skills/runtime/__init__.py +17 -0
- ksadk/skills/runtime/agent.py +183 -0
- ksadk/skills/runtime/artifacts.py +39 -0
- ksadk/skills/runtime/backends/__init__.py +1 -0
- ksadk/skills/runtime/backends/disabled.py +8 -0
- ksadk/skills/runtime/backends/e2b.py +168 -0
- ksadk/skills/runtime/backends/local.py +95 -0
- ksadk/skills/runtime/base.py +103 -0
- ksadk/skills/runtime/executor.py +219 -0
- ksadk/skills/runtime/factory.py +37 -0
- ksadk/skills/runtime/loader.py +131 -0
- ksadk/skills/runtime/registry.py +150 -0
- ksadk/skills/runtime/request.py +67 -0
- ksadk/skills/service_client.py +239 -0
- ksadk/skills/service_env.py +58 -0
- ksadk/skills/tool_defs.py +221 -0
- ksadk/terminal_client.py +69 -0
- ksadk/terminal_exec_policy.py +229 -0
- ksadk/tools/__init__.py +17 -0
- ksadk/tools/gateway.py +230 -0
- ksadk/tools/result_budget.py +154 -0
- ksadk/toolsets/__init__.py +854 -0
- ksadk/toolsets/_langchain.py +11 -0
- ksadk/toolsets/platform.py +93 -0
- ksadk/toolsets/sandbox.py +310 -0
- ksadk/toolsets/skills.py +217 -0
- ksadk/toolsets/web.py +266 -0
- ksadk/toolsets/workspace.py +917 -0
- ksadk/toolsets/workspace_state.py +44 -0
- ksadk/tracing/__init__.py +37 -0
- ksadk/tracing/exporters/__init__.py +1 -0
- ksadk/tracing/exporters/inmemory_exporter.py +116 -0
- ksadk/tracing/exporters/langfuse_exporter.py +445 -0
- ksadk/tracing/setup.py +892 -0
- ksadk/tracing/span_utils.py +114 -0
- ksadk/tui/__init__.py +27 -0
- ksadk/tui/loop.py +1877 -0
- ksadk/tui/stream_render.py +68 -0
- ksadk/ui_config.py +168 -0
- ksadk/version.py +4 -0
- ksadk_runtime_common/__init__.py +20 -0
- ksadk_runtime_common/memory_backend/__init__.py +29 -0
- ksadk_runtime_common/memory_backend/manifest.py +79 -0
- ksadk_runtime_common/memory_backend/providers/__init__.py +6 -0
- ksadk_runtime_common/memory_backend/providers/lancedb.py +151 -0
- ksadk_runtime_common/memory_backend/providers/mem0.py +74 -0
- ksadk_runtime_common/memory_backend/registry.py +56 -0
- ksadk_runtime_common/memory_backend/render.py +71 -0
- ksadk_runtime_common/schemas/memory_backend_manifest.schema.json +148 -0
- ksadk_runtime_common/workspace_files/__init__.py +29 -0
- ksadk_runtime_common/workspace_files/bootstrap.py +56 -0
- ksadk_runtime_common/workspace_files/constants.py +9 -0
- ksadk_runtime_common/workspace_files/path_utils.py +71 -0
- ksadk_runtime_common/workspace_files/preview.py +96 -0
- ksadk_runtime_common/workspace_files/router.py +254 -0
- agentengine_sdk_python/__init__.py +0 -3
- agentengine_sdk_python-0.6.4.dist-info/METADATA +0 -48
- agentengine_sdk_python-0.6.4.dist-info/RECORD +0 -5
- agentengine_sdk_python-0.6.4.dist-info/top_level.txt +0 -1
|
@@ -0,0 +1,52 @@
|
|
|
1
|
+
from __future__ import annotations
|
|
2
|
+
|
|
3
|
+
import logging
|
|
4
|
+
import os
|
|
5
|
+
from collections.abc import Iterator
|
|
6
|
+
|
|
7
|
+
from ksadk.sessions.errors import SessionBackendUnavailable
|
|
8
|
+
|
|
9
|
+
logger = logging.getLogger(__name__)
|
|
10
|
+
|
|
11
|
+
|
|
12
|
+
def session_backend_timeout_seconds() -> float:
|
|
13
|
+
raw = (
|
|
14
|
+
os.getenv("KSADK_SESSION_CONNECT_TIMEOUT")
|
|
15
|
+
or os.getenv("KSADK_SESSION_PG_CONNECT_TIMEOUT")
|
|
16
|
+
or ""
|
|
17
|
+
).strip()
|
|
18
|
+
if not raw:
|
|
19
|
+
return 5.0
|
|
20
|
+
try:
|
|
21
|
+
value = float(raw)
|
|
22
|
+
except ValueError:
|
|
23
|
+
logger.warning("Invalid KSADK_SESSION_CONNECT_TIMEOUT=%r; using 5 seconds", raw)
|
|
24
|
+
return 5.0
|
|
25
|
+
return max(0.1, value)
|
|
26
|
+
|
|
27
|
+
|
|
28
|
+
def _exception_chain(exc: BaseException) -> Iterator[BaseException]:
|
|
29
|
+
seen: set[int] = set()
|
|
30
|
+
current: BaseException | None = exc
|
|
31
|
+
while current is not None and id(current) not in seen:
|
|
32
|
+
seen.add(id(current))
|
|
33
|
+
yield current
|
|
34
|
+
original = getattr(current, "orig", None)
|
|
35
|
+
if isinstance(original, BaseException) and id(original) not in seen:
|
|
36
|
+
current = original
|
|
37
|
+
continue
|
|
38
|
+
current = current.__cause__ or current.__context__
|
|
39
|
+
|
|
40
|
+
|
|
41
|
+
def is_session_backend_failure(exc: BaseException) -> bool:
|
|
42
|
+
"""Return whether an exception represents an unavailable database backend."""
|
|
43
|
+
for current in _exception_chain(exc):
|
|
44
|
+
if isinstance(
|
|
45
|
+
current,
|
|
46
|
+
(SessionBackendUnavailable, TimeoutError, OSError, ConnectionError),
|
|
47
|
+
):
|
|
48
|
+
return True
|
|
49
|
+
module = type(current).__module__
|
|
50
|
+
if module.startswith("asyncpg.") or module.startswith("sqlalchemy."):
|
|
51
|
+
return True
|
|
52
|
+
return False
|
|
@@ -0,0 +1,360 @@
|
|
|
1
|
+
from __future__ import annotations
|
|
2
|
+
|
|
3
|
+
import asyncio
|
|
4
|
+
import logging
|
|
5
|
+
from typing import Any, Optional, cast
|
|
6
|
+
|
|
7
|
+
from ksadk.sessions.base import BaseSessionService, Session, SessionEvent, SessionState
|
|
8
|
+
from ksadk.sessions.in_memory import InMemorySessionService
|
|
9
|
+
from ksadk.sessions.resilience import is_session_backend_failure
|
|
10
|
+
|
|
11
|
+
logger = logging.getLogger(__name__)
|
|
12
|
+
|
|
13
|
+
|
|
14
|
+
class ResilientSessionService(BaseSessionService):
|
|
15
|
+
"""Keep live agent sessions available when durable persistence is unavailable.
|
|
16
|
+
|
|
17
|
+
The in-memory service is authoritative for the lifetime of this process. The
|
|
18
|
+
configured durable service is used as a read-through source and a best-effort
|
|
19
|
+
write-through sink. After its first failure it stays disabled until a
|
|
20
|
+
background probe confirms the durable backend is reachable again, at which
|
|
21
|
+
point it is re-enabled and an INFO log is emitted.
|
|
22
|
+
"""
|
|
23
|
+
|
|
24
|
+
_probe_interval_seconds: float = 30.0
|
|
25
|
+
|
|
26
|
+
def __init__(
|
|
27
|
+
self,
|
|
28
|
+
primary: BaseSessionService,
|
|
29
|
+
fallback: InMemorySessionService | None = None,
|
|
30
|
+
) -> None:
|
|
31
|
+
self.primary = primary
|
|
32
|
+
self.fallback = fallback or InMemorySessionService()
|
|
33
|
+
self._primary_enabled = True
|
|
34
|
+
self._hydrate_lock = asyncio.Lock()
|
|
35
|
+
self._primary_session_lock = asyncio.Lock()
|
|
36
|
+
self._primary_session_ids: set[str] = set()
|
|
37
|
+
self._probe_task: asyncio.Task[None] | None = None
|
|
38
|
+
|
|
39
|
+
@property
|
|
40
|
+
def degraded(self) -> bool:
|
|
41
|
+
return not self._primary_enabled
|
|
42
|
+
|
|
43
|
+
async def _call_primary(self, method_name: str, *args: Any, **kwargs: Any) -> tuple[bool, Any]:
|
|
44
|
+
if not self._primary_enabled:
|
|
45
|
+
return False, None
|
|
46
|
+
try:
|
|
47
|
+
method = getattr(self.primary, method_name)
|
|
48
|
+
return True, await method(*args, **kwargs)
|
|
49
|
+
except Exception as exc:
|
|
50
|
+
if not is_session_backend_failure(exc):
|
|
51
|
+
raise
|
|
52
|
+
self._disable_primary(exc)
|
|
53
|
+
return False, None
|
|
54
|
+
|
|
55
|
+
def _disable_primary(self, exc: Exception) -> None:
|
|
56
|
+
if not self._primary_enabled:
|
|
57
|
+
return
|
|
58
|
+
self._primary_enabled = False
|
|
59
|
+
logger.error(
|
|
60
|
+
"KSADK session persistence degraded; using in-memory live session: %s",
|
|
61
|
+
exc,
|
|
62
|
+
extra={
|
|
63
|
+
"session_backend_state": "degraded",
|
|
64
|
+
"session_backend": type(self.primary).__name__,
|
|
65
|
+
},
|
|
66
|
+
)
|
|
67
|
+
self._start_probe()
|
|
68
|
+
|
|
69
|
+
def _start_probe(self) -> None:
|
|
70
|
+
if self._probe_task is not None and not self._probe_task.done():
|
|
71
|
+
return
|
|
72
|
+
self._probe_task = asyncio.create_task(self._probe_loop())
|
|
73
|
+
|
|
74
|
+
async def _probe_loop(self) -> None:
|
|
75
|
+
while not self._primary_enabled:
|
|
76
|
+
await asyncio.sleep(self._probe_interval_seconds)
|
|
77
|
+
if self._primary_enabled:
|
|
78
|
+
break
|
|
79
|
+
try:
|
|
80
|
+
await self.primary.get_session("__ksadk_probe__")
|
|
81
|
+
except Exception:
|
|
82
|
+
continue
|
|
83
|
+
self._primary_enabled = True
|
|
84
|
+
logger.info(
|
|
85
|
+
"KSADK session persistence recovered; durable backend re-enabled",
|
|
86
|
+
extra={
|
|
87
|
+
"session_backend_state": "recovered",
|
|
88
|
+
"session_backend": type(self.primary).__name__,
|
|
89
|
+
},
|
|
90
|
+
)
|
|
91
|
+
|
|
92
|
+
async def _hydrate(self, session: Session) -> Session:
|
|
93
|
+
async with self._hydrate_lock:
|
|
94
|
+
self._primary_session_ids.add(session.id)
|
|
95
|
+
existing = await self.fallback.get_session(session.id)
|
|
96
|
+
if existing is None:
|
|
97
|
+
await self.fallback.create_session(
|
|
98
|
+
session.agent_id,
|
|
99
|
+
session.user_id,
|
|
100
|
+
session_id=session.id,
|
|
101
|
+
)
|
|
102
|
+
existing_events = await self.fallback.get_events(session.id)
|
|
103
|
+
existing_ids = {event.id for event in existing_events}
|
|
104
|
+
for event in sorted(session.events, key=lambda item: item.seq_id):
|
|
105
|
+
if event.id not in existing_ids:
|
|
106
|
+
await self.fallback.append_event(session.id, event)
|
|
107
|
+
await self.fallback.update_session_metadata(
|
|
108
|
+
session.id,
|
|
109
|
+
title=session.title,
|
|
110
|
+
title_source=session.title_source,
|
|
111
|
+
summary=session.summary,
|
|
112
|
+
first_prompt=session.first_prompt,
|
|
113
|
+
last_prompt=session.last_prompt,
|
|
114
|
+
)
|
|
115
|
+
current = await self.fallback.get_session(session.id)
|
|
116
|
+
if current is not None and session.state != current.state:
|
|
117
|
+
await self.fallback.update_state(
|
|
118
|
+
agent_id=session.agent_id,
|
|
119
|
+
user_id=session.user_id,
|
|
120
|
+
session_id=session.id,
|
|
121
|
+
scope="session",
|
|
122
|
+
state_delta=session.state,
|
|
123
|
+
)
|
|
124
|
+
hydrated = await self.fallback.get_session(session.id)
|
|
125
|
+
if hydrated is None:
|
|
126
|
+
raise RuntimeError(f"Failed to hydrate live session {session.id}")
|
|
127
|
+
return hydrated
|
|
128
|
+
|
|
129
|
+
async def create_session(
|
|
130
|
+
self,
|
|
131
|
+
agent_id: str,
|
|
132
|
+
user_id: str,
|
|
133
|
+
session_id: Optional[str] = None,
|
|
134
|
+
) -> Session:
|
|
135
|
+
if session_id:
|
|
136
|
+
ok, durable = await self._call_primary("get_session", session_id)
|
|
137
|
+
if ok and durable is not None:
|
|
138
|
+
return await self._hydrate(durable)
|
|
139
|
+
existing = await self.fallback.get_session(session_id)
|
|
140
|
+
if existing is not None:
|
|
141
|
+
return existing
|
|
142
|
+
|
|
143
|
+
live = await self.fallback.create_session(agent_id, user_id, session_id=session_id)
|
|
144
|
+
ok, durable = await self._call_primary(
|
|
145
|
+
"create_session",
|
|
146
|
+
agent_id,
|
|
147
|
+
user_id,
|
|
148
|
+
session_id=live.id,
|
|
149
|
+
)
|
|
150
|
+
if ok and durable is not None:
|
|
151
|
+
self._primary_session_ids.add(durable.id)
|
|
152
|
+
return await self._hydrate(durable)
|
|
153
|
+
return live
|
|
154
|
+
|
|
155
|
+
async def get_session(self, session_id: str) -> Optional[Session]:
|
|
156
|
+
live = await self.fallback.get_session(session_id)
|
|
157
|
+
ok, durable = await self._call_primary("get_session", session_id)
|
|
158
|
+
if ok and durable is not None:
|
|
159
|
+
return await self._hydrate(durable)
|
|
160
|
+
return live
|
|
161
|
+
|
|
162
|
+
async def list_sessions(
|
|
163
|
+
self,
|
|
164
|
+
agent_id: str,
|
|
165
|
+
user_id: Optional[str] = None,
|
|
166
|
+
offset: Optional[int] = None,
|
|
167
|
+
limit: Optional[int] = None,
|
|
168
|
+
) -> list[Session]:
|
|
169
|
+
ok, durable_sessions = await self._call_primary(
|
|
170
|
+
"list_sessions",
|
|
171
|
+
agent_id,
|
|
172
|
+
user_id,
|
|
173
|
+
offset,
|
|
174
|
+
limit,
|
|
175
|
+
)
|
|
176
|
+
if ok:
|
|
177
|
+
for session in durable_sessions or []:
|
|
178
|
+
await self._hydrate(session)
|
|
179
|
+
return cast(
|
|
180
|
+
list[Session],
|
|
181
|
+
await self.fallback.list_sessions(agent_id, user_id, offset, limit),
|
|
182
|
+
)
|
|
183
|
+
|
|
184
|
+
async def count_sessions(self, agent_id: str, user_id: Optional[str] = None) -> int:
|
|
185
|
+
sessions = await self.list_sessions(agent_id, user_id)
|
|
186
|
+
return len(sessions)
|
|
187
|
+
|
|
188
|
+
async def delete_session(self, session_id: str) -> bool:
|
|
189
|
+
deleted = await self.fallback.delete_session(session_id)
|
|
190
|
+
ok, durable_deleted = await self._call_primary("delete_session", session_id)
|
|
191
|
+
if ok:
|
|
192
|
+
self._primary_session_ids.discard(session_id)
|
|
193
|
+
return deleted or bool(durable_deleted) if ok else deleted
|
|
194
|
+
|
|
195
|
+
async def update_session_metadata(
|
|
196
|
+
self,
|
|
197
|
+
session_id: str,
|
|
198
|
+
*,
|
|
199
|
+
title: Optional[str] = None,
|
|
200
|
+
title_source: Optional[str] = None,
|
|
201
|
+
summary: Optional[str] = None,
|
|
202
|
+
first_prompt: Optional[str] = None,
|
|
203
|
+
last_prompt: Optional[str] = None,
|
|
204
|
+
) -> Session:
|
|
205
|
+
if await self.fallback.get_session(session_id) is None:
|
|
206
|
+
await self.get_session(session_id)
|
|
207
|
+
live = await self.fallback.update_session_metadata(
|
|
208
|
+
session_id,
|
|
209
|
+
title=title,
|
|
210
|
+
title_source=title_source,
|
|
211
|
+
summary=summary,
|
|
212
|
+
first_prompt=first_prompt,
|
|
213
|
+
last_prompt=last_prompt,
|
|
214
|
+
)
|
|
215
|
+
await self._ensure_primary_session(session_id)
|
|
216
|
+
await self._call_primary(
|
|
217
|
+
"update_session_metadata",
|
|
218
|
+
session_id,
|
|
219
|
+
title=title,
|
|
220
|
+
title_source=title_source,
|
|
221
|
+
summary=summary,
|
|
222
|
+
first_prompt=first_prompt,
|
|
223
|
+
last_prompt=last_prompt,
|
|
224
|
+
)
|
|
225
|
+
return live
|
|
226
|
+
|
|
227
|
+
async def _ensure_primary_session(self, session_id: str) -> None:
|
|
228
|
+
"""Create the session in PG if it only exists in memory (degraded-era)."""
|
|
229
|
+
if not self._primary_enabled or session_id in self._primary_session_ids:
|
|
230
|
+
return
|
|
231
|
+
async with self._primary_session_lock:
|
|
232
|
+
if not self._primary_enabled or session_id in self._primary_session_ids:
|
|
233
|
+
return
|
|
234
|
+
ok, durable = await self._call_primary("get_session", session_id)
|
|
235
|
+
if not ok:
|
|
236
|
+
return
|
|
237
|
+
if durable is None:
|
|
238
|
+
live = await self.fallback.get_session(session_id)
|
|
239
|
+
if live is None:
|
|
240
|
+
return
|
|
241
|
+
ok, durable = await self._call_primary(
|
|
242
|
+
"create_session",
|
|
243
|
+
live.agent_id,
|
|
244
|
+
live.user_id,
|
|
245
|
+
session_id=live.id,
|
|
246
|
+
)
|
|
247
|
+
if not ok or durable is None:
|
|
248
|
+
return
|
|
249
|
+
self._primary_session_ids.add(session_id)
|
|
250
|
+
|
|
251
|
+
async def append_event(self, session_id: str, event: SessionEvent) -> SessionEvent:
|
|
252
|
+
if await self.fallback.get_session(session_id) is None:
|
|
253
|
+
await self.get_session(session_id)
|
|
254
|
+
live = await self.fallback.append_event(session_id, event)
|
|
255
|
+
await self._ensure_primary_session(session_id)
|
|
256
|
+
await self._call_primary("append_event", session_id, event)
|
|
257
|
+
return live
|
|
258
|
+
|
|
259
|
+
async def get_events(
|
|
260
|
+
self,
|
|
261
|
+
session_id: str,
|
|
262
|
+
offset: Optional[int] = None,
|
|
263
|
+
limit: Optional[int] = None,
|
|
264
|
+
after_seq_id: Optional[int] = None,
|
|
265
|
+
before_seq_id: Optional[int] = None,
|
|
266
|
+
) -> list[SessionEvent]:
|
|
267
|
+
await self.get_session(session_id)
|
|
268
|
+
return cast(
|
|
269
|
+
list[SessionEvent],
|
|
270
|
+
await self.fallback.get_events(
|
|
271
|
+
session_id,
|
|
272
|
+
offset,
|
|
273
|
+
limit,
|
|
274
|
+
after_seq_id,
|
|
275
|
+
before_seq_id,
|
|
276
|
+
),
|
|
277
|
+
)
|
|
278
|
+
|
|
279
|
+
async def count_events(
|
|
280
|
+
self,
|
|
281
|
+
session_id: str,
|
|
282
|
+
after_seq_id: Optional[int] = None,
|
|
283
|
+
before_seq_id: Optional[int] = None,
|
|
284
|
+
) -> int:
|
|
285
|
+
await self.get_session(session_id)
|
|
286
|
+
return cast(
|
|
287
|
+
int,
|
|
288
|
+
await self.fallback.count_events(session_id, after_seq_id, before_seq_id),
|
|
289
|
+
)
|
|
290
|
+
|
|
291
|
+
async def get_state(
|
|
292
|
+
self,
|
|
293
|
+
agent_id: str,
|
|
294
|
+
user_id: Optional[str],
|
|
295
|
+
session_id: Optional[str],
|
|
296
|
+
scope: str = "session",
|
|
297
|
+
) -> Optional[SessionState]:
|
|
298
|
+
if session_id:
|
|
299
|
+
await self.get_session(session_id)
|
|
300
|
+
live = await self.fallback.get_state(agent_id, user_id, session_id, scope)
|
|
301
|
+
if live is not None or not self._primary_enabled:
|
|
302
|
+
return live
|
|
303
|
+
ok, durable = await self._call_primary(
|
|
304
|
+
"get_state",
|
|
305
|
+
agent_id,
|
|
306
|
+
user_id,
|
|
307
|
+
session_id,
|
|
308
|
+
scope,
|
|
309
|
+
)
|
|
310
|
+
if ok and durable is not None:
|
|
311
|
+
return await self.fallback.update_state(
|
|
312
|
+
agent_id=agent_id,
|
|
313
|
+
user_id=user_id,
|
|
314
|
+
session_id=session_id,
|
|
315
|
+
scope=scope,
|
|
316
|
+
state_delta=durable.state,
|
|
317
|
+
)
|
|
318
|
+
return live
|
|
319
|
+
|
|
320
|
+
async def update_state(
|
|
321
|
+
self,
|
|
322
|
+
*,
|
|
323
|
+
agent_id: str,
|
|
324
|
+
user_id: Optional[str],
|
|
325
|
+
session_id: Optional[str],
|
|
326
|
+
scope: str,
|
|
327
|
+
state_delta: dict[str, Any],
|
|
328
|
+
) -> SessionState:
|
|
329
|
+
if session_id and await self.fallback.get_session(session_id) is None:
|
|
330
|
+
await self.get_session(session_id)
|
|
331
|
+
live = await self.fallback.update_state(
|
|
332
|
+
agent_id=agent_id,
|
|
333
|
+
user_id=user_id,
|
|
334
|
+
session_id=session_id,
|
|
335
|
+
scope=scope,
|
|
336
|
+
state_delta=state_delta,
|
|
337
|
+
)
|
|
338
|
+
if session_id:
|
|
339
|
+
await self._ensure_primary_session(session_id)
|
|
340
|
+
await self._call_primary(
|
|
341
|
+
"update_state",
|
|
342
|
+
agent_id=agent_id,
|
|
343
|
+
user_id=user_id,
|
|
344
|
+
session_id=session_id,
|
|
345
|
+
scope=scope,
|
|
346
|
+
state_delta=state_delta,
|
|
347
|
+
)
|
|
348
|
+
return live
|
|
349
|
+
|
|
350
|
+
async def aclose(self) -> None:
|
|
351
|
+
if self._probe_task is not None and not self._probe_task.done():
|
|
352
|
+
self._probe_task.cancel()
|
|
353
|
+
try:
|
|
354
|
+
await self._probe_task
|
|
355
|
+
except asyncio.CancelledError:
|
|
356
|
+
pass
|
|
357
|
+
for service in (self.primary, self.fallback):
|
|
358
|
+
close = getattr(service, "aclose", None)
|
|
359
|
+
if close is not None:
|
|
360
|
+
await close()
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
"""Compatibility wrapper for the legacy sqlite-backed local session service path."""
|
|
2
|
+
|
|
3
|
+
from ksadk.sessions.local_service import (
|
|
4
|
+
LocalSessionService,
|
|
5
|
+
create_local_session_service,
|
|
6
|
+
resolve_local_session_dir,
|
|
7
|
+
)
|
|
8
|
+
|
|
9
|
+
__all__ = [
|
|
10
|
+
"LocalSessionService",
|
|
11
|
+
"create_local_session_service",
|
|
12
|
+
"resolve_local_session_dir",
|
|
13
|
+
]
|
ksadk/skills/__init__.py
ADDED
ksadk/skills/loader.py
ADDED
|
@@ -0,0 +1,46 @@
|
|
|
1
|
+
from __future__ import annotations
|
|
2
|
+
|
|
3
|
+
from dataclasses import dataclass
|
|
4
|
+
from pathlib import Path
|
|
5
|
+
|
|
6
|
+
|
|
7
|
+
@dataclass(frozen=True)
|
|
8
|
+
class LocalSkill:
|
|
9
|
+
name: str
|
|
10
|
+
description: str
|
|
11
|
+
root_dir: Path
|
|
12
|
+
skill_md: Path
|
|
13
|
+
body: str
|
|
14
|
+
|
|
15
|
+
|
|
16
|
+
def load_local_skill(root_dir: str | Path) -> LocalSkill:
|
|
17
|
+
root = Path(root_dir)
|
|
18
|
+
skill_md = root / "SKILL.md"
|
|
19
|
+
if not skill_md.exists():
|
|
20
|
+
raise FileNotFoundError(f"SKILL.md not found: {skill_md}")
|
|
21
|
+
content = skill_md.read_text(encoding="utf-8")
|
|
22
|
+
metadata, body = _parse_frontmatter(content)
|
|
23
|
+
return LocalSkill(
|
|
24
|
+
name=metadata.get("name") or root.name,
|
|
25
|
+
description=metadata.get("description") or "",
|
|
26
|
+
root_dir=root,
|
|
27
|
+
skill_md=skill_md,
|
|
28
|
+
body=body,
|
|
29
|
+
)
|
|
30
|
+
|
|
31
|
+
|
|
32
|
+
def _parse_frontmatter(content: str) -> tuple[dict[str, str], str]:
|
|
33
|
+
if not content.startswith("---\n"):
|
|
34
|
+
return {}, content
|
|
35
|
+
end = content.find("\n---\n", 4)
|
|
36
|
+
if end == -1:
|
|
37
|
+
return {}, content
|
|
38
|
+
raw_meta = content[4:end]
|
|
39
|
+
body = content[end + 5 :]
|
|
40
|
+
metadata: dict[str, str] = {}
|
|
41
|
+
for line in raw_meta.splitlines():
|
|
42
|
+
if ":" not in line:
|
|
43
|
+
continue
|
|
44
|
+
key, value = line.split(":", 1)
|
|
45
|
+
metadata[key.strip()] = value.strip().strip("\"'")
|
|
46
|
+
return metadata, body
|
ksadk/skills/models.py
ADDED
|
@@ -0,0 +1,120 @@
|
|
|
1
|
+
from __future__ import annotations
|
|
2
|
+
|
|
3
|
+
from dataclasses import dataclass
|
|
4
|
+
from typing import Any
|
|
5
|
+
|
|
6
|
+
|
|
7
|
+
@dataclass(frozen=True)
|
|
8
|
+
class ContentHash:
|
|
9
|
+
algorithm: str
|
|
10
|
+
value: str
|
|
11
|
+
|
|
12
|
+
@classmethod
|
|
13
|
+
def parse(cls, raw: str | None) -> "ContentHash | None":
|
|
14
|
+
normalized = str(raw or "").strip()
|
|
15
|
+
if not normalized:
|
|
16
|
+
return None
|
|
17
|
+
if ":" not in normalized:
|
|
18
|
+
return cls("sha256", normalized.lower())
|
|
19
|
+
algorithm, value = normalized.split(":", 1)
|
|
20
|
+
return cls(algorithm.strip().lower(), value.strip().lower())
|
|
21
|
+
|
|
22
|
+
def render(self) -> str:
|
|
23
|
+
return f"{self.algorithm}:{self.value}"
|
|
24
|
+
|
|
25
|
+
|
|
26
|
+
@dataclass(frozen=True)
|
|
27
|
+
class SkillRef:
|
|
28
|
+
skill_id: str
|
|
29
|
+
version_id: str
|
|
30
|
+
version: str
|
|
31
|
+
name: str
|
|
32
|
+
description: str = ""
|
|
33
|
+
status: str = ""
|
|
34
|
+
content_hash: ContentHash | None = None
|
|
35
|
+
archive_uri: str = ""
|
|
36
|
+
aliases: tuple[str, ...] = ()
|
|
37
|
+
tags: tuple[str, ...] = ()
|
|
38
|
+
examples: tuple[str, ...] = ()
|
|
39
|
+
input_schema: dict[str, Any] | None = None
|
|
40
|
+
runtime_requirements: dict[str, Any] | None = None
|
|
41
|
+
|
|
42
|
+
@classmethod
|
|
43
|
+
def from_payload(cls, payload: dict[str, Any]) -> "SkillRef":
|
|
44
|
+
return cls(
|
|
45
|
+
skill_id=str(payload.get("SkillId") or payload.get("skill_id") or ""),
|
|
46
|
+
version_id=str(payload.get("VersionId") or payload.get("version_id") or ""),
|
|
47
|
+
version=str(payload.get("Version") or payload.get("version") or ""),
|
|
48
|
+
name=str(payload.get("Name") or payload.get("name") or ""),
|
|
49
|
+
description=str(payload.get("Description") or payload.get("description") or ""),
|
|
50
|
+
status=str(payload.get("Status") or payload.get("status") or ""),
|
|
51
|
+
content_hash=ContentHash.parse(payload.get("ContentHash") or payload.get("content_hash")),
|
|
52
|
+
archive_uri=str(payload.get("ArchiveUri") or payload.get("archive_uri") or ""),
|
|
53
|
+
aliases=_string_tuple(payload.get("Aliases") or payload.get("aliases")),
|
|
54
|
+
tags=_string_tuple(payload.get("Tags") or payload.get("tags")),
|
|
55
|
+
examples=_string_tuple(payload.get("Examples") or payload.get("examples")),
|
|
56
|
+
input_schema=_dict_or_none(payload.get("InputSchema") or payload.get("input_schema")),
|
|
57
|
+
runtime_requirements=_dict_or_none(
|
|
58
|
+
payload.get("RuntimeRequirements") or payload.get("runtime_requirements")
|
|
59
|
+
),
|
|
60
|
+
)
|
|
61
|
+
|
|
62
|
+
@property
|
|
63
|
+
def cache_key(self) -> str:
|
|
64
|
+
identity = self.skill_id or self.name
|
|
65
|
+
version_key = self.version_id or self.version
|
|
66
|
+
if not version_key and self.content_hash:
|
|
67
|
+
version_key = self.content_hash.value
|
|
68
|
+
return "__".join(part.replace("/", "_").replace(":", "_") for part in (identity, version_key) if part)
|
|
69
|
+
|
|
70
|
+
@property
|
|
71
|
+
def is_active(self) -> bool:
|
|
72
|
+
return not self.status or self.status.lower() in {"active", "available", "enabled"}
|
|
73
|
+
|
|
74
|
+
|
|
75
|
+
@dataclass(frozen=True)
|
|
76
|
+
class SkillListResponse:
|
|
77
|
+
request_id: str
|
|
78
|
+
space_id: str
|
|
79
|
+
space_name: str
|
|
80
|
+
skills: list[SkillRef]
|
|
81
|
+
code: int = 0
|
|
82
|
+
message: str = ""
|
|
83
|
+
|
|
84
|
+
@classmethod
|
|
85
|
+
def from_payload(
|
|
86
|
+
cls,
|
|
87
|
+
payload: dict[str, Any],
|
|
88
|
+
*,
|
|
89
|
+
space_id: str = "",
|
|
90
|
+
space_name: str = "",
|
|
91
|
+
) -> "SkillListResponse":
|
|
92
|
+
data = payload.get("Data") or payload.get("data") or {}
|
|
93
|
+
skills_payload = data.get("Skills") or data.get("skills") or data.get("Items") or data.get("items") or []
|
|
94
|
+
return cls(
|
|
95
|
+
code=int(payload.get("Code") or payload.get("code") or 0),
|
|
96
|
+
message=str(payload.get("Message") or payload.get("message") or ""),
|
|
97
|
+
request_id=str(payload.get("RequestId") or payload.get("request_id") or ""),
|
|
98
|
+
space_id=str(data.get("SkillSpaceId") or data.get("skill_space_id") or space_id),
|
|
99
|
+
space_name=str(data.get("SkillSpaceName") or data.get("skill_space_name") or space_name),
|
|
100
|
+
skills=[SkillRef.from_payload(item) for item in skills_payload if isinstance(item, dict)],
|
|
101
|
+
)
|
|
102
|
+
|
|
103
|
+
def active_skills(self) -> list[SkillRef]:
|
|
104
|
+
return [skill for skill in self.skills if skill.is_active]
|
|
105
|
+
|
|
106
|
+
|
|
107
|
+
def _string_tuple(raw: Any) -> tuple[str, ...]:
|
|
108
|
+
if raw is None:
|
|
109
|
+
return ()
|
|
110
|
+
if isinstance(raw, str):
|
|
111
|
+
values = raw.split(",")
|
|
112
|
+
elif isinstance(raw, (list, tuple, set)):
|
|
113
|
+
values = raw
|
|
114
|
+
else:
|
|
115
|
+
return ()
|
|
116
|
+
return tuple(value for value in (str(item).strip() for item in values) if value)
|
|
117
|
+
|
|
118
|
+
|
|
119
|
+
def _dict_or_none(raw: Any) -> dict[str, Any] | None:
|
|
120
|
+
return dict(raw) if isinstance(raw, dict) else None
|