agentengine-sdk-python 0.6.2__py3-none-any.whl → 0.6.9__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.6.9.dist-info/METADATA +179 -0
- agentengine_sdk_python-0.6.9.dist-info/RECORD +487 -0
- {agentengine_sdk_python-0.6.2.dist-info → agentengine_sdk_python-0.6.9.dist-info}/WHEEL +1 -1
- agentengine_sdk_python-0.6.9.dist-info/entry_points.txt +3 -0
- agentengine_sdk_python-0.6.9.dist-info/licenses/LICENSE +175 -0
- agentengine_sdk_python-0.6.9.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 +2227 -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 +2277 -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 +1259 -0
- ksadk/cli/cmd_invoke.py +1336 -0
- ksadk/cli/cmd_launch.py +564 -0
- ksadk/cli/cmd_mcp.py +1174 -0
- ksadk/cli/cmd_model.py +302 -0
- ksadk/cli/cmd_openclaw.py +3918 -0
- ksadk/cli/cmd_run.py +232 -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 +410 -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 +342 -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/model_context.py +360 -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 +5208 -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 +1105 -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/short_term_memory.py +289 -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 +1135 -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 +539 -0
- ksadk/runners/langgraph_runner.py +852 -0
- ksadk/runners/patch_langchain.py +187 -0
- ksadk/runners/remote_runner.py +667 -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 +3789 -0
- ksadk/server/static/assets/ArtifactsPanel-C0meuOdi.js +1 -0
- ksadk/server/static/assets/CodeBlock-BbI4HPtJ.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-DMLQYoLp.js +8 -0
- ksadk/server/static/assets/MathMessageMarkdown-DeYh8QPr.css +1 -0
- ksadk/server/static/assets/MermaidBlock-DCR8WZ17.js +303 -0
- ksadk/server/static/assets/NativeTerminalPanel-CHOd7Rch.css +1 -0
- ksadk/server/static/assets/NativeTerminalPanel-CKUvWhUz.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-bj2rZnP5.js +1 -0
- ksadk/server/static/assets/architecture-7EHR7CIX-Cr6Xz1_c.js +1 -0
- ksadk/server/static/assets/architectureDiagram-3BPJPVTR-2u1ltDIj.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-D6fvdK20.js +132 -0
- ksadk/server/static/assets/brainfuck-D5EjA2JK.js +1 -0
- ksadk/server/static/assets/c4Diagram-AAUBKEIU-BK82L5n5.js +10 -0
- ksadk/server/static/assets/channel-BSSOwFIb.js +1 -0
- ksadk/server/static/assets/chunk-2J33WTMH-DLVdkeyQ.js +1 -0
- ksadk/server/static/assets/chunk-4BX2VUAB-BbwsYcbW.js +1 -0
- ksadk/server/static/assets/chunk-55IACEB6-DOairxzw.js +1 -0
- ksadk/server/static/assets/chunk-727SXJPM-hCO487gs.js +206 -0
- ksadk/server/static/assets/chunk-AQP2D5EJ-XU8vDOuG.js +231 -0
- ksadk/server/static/assets/chunk-FMBD7UC4-PrapyfMu.js +15 -0
- ksadk/server/static/assets/chunk-ND2GUHAM-CboKhTZ3.js +1 -0
- ksadk/server/static/assets/chunk-QZHKN3VN-XXpdiwUL.js +1 -0
- ksadk/server/static/assets/classDiagram-4FO5ZUOK-C5HvGiyK.js +1 -0
- ksadk/server/static/assets/classDiagram-v2-Q7XG4LA2-C5HvGiyK.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-_N8bJ-EU.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-FoDlo5J2.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-BBp6ebBw.js +43 -0
- ksadk/server/static/assets/diagram-5GNKFQAL-CqOvG1PR.js +10 -0
- ksadk/server/static/assets/diagram-KO2AKTUF-O9T3t6ba.js +3 -0
- ksadk/server/static/assets/diagram-LMA3HP47-CGG8ekBO.js +24 -0
- ksadk/server/static/assets/diagram-OG6HWLK6-4BmH1EEg.js +24 -0
- ksadk/server/static/assets/diff-ChtP43wD.js +1 -0
- ksadk/server/static/assets/dist-6kSZvCZh.js +1 -0
- ksadk/server/static/assets/dist-B67uF2uK.js +1 -0
- ksadk/server/static/assets/dist-BMKM66B4.js +1 -0
- ksadk/server/static/assets/dist-BVzcWa6D.js +1 -0
- ksadk/server/static/assets/dist-Bk1l05Ni.js +1 -0
- ksadk/server/static/assets/dist-BkJjNih3.js +1 -0
- ksadk/server/static/assets/dist-BmuTWcm7.js +9 -0
- ksadk/server/static/assets/dist-C2DKRFVK.js +1 -0
- ksadk/server/static/assets/dist-CWiTDN_V.js +6 -0
- ksadk/server/static/assets/dist-CZ6C3x8B.js +23 -0
- ksadk/server/static/assets/dist-CiZHB6ZW.js +1 -0
- ksadk/server/static/assets/dist-Cp1_jKwf.js +1 -0
- ksadk/server/static/assets/dist-Cwhk4lwI.js +2 -0
- ksadk/server/static/assets/dist-D5JGcxBx.js +11 -0
- ksadk/server/static/assets/dist-D99wf6_X.js +1 -0
- ksadk/server/static/assets/dist-DCpZrjaK.js +1 -0
- ksadk/server/static/assets/dist-DI-oVAXw.js +1 -0
- ksadk/server/static/assets/dist-DLMjL01k.js +1 -0
- ksadk/server/static/assets/dist-DLeM1OCK.js +1 -0
- ksadk/server/static/assets/dist-DM0rEQPk.js +1 -0
- ksadk/server/static/assets/dist-DbaH3p5h.js +1 -0
- ksadk/server/static/assets/dist-S4klkK5W.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-oJhaci7S.js +85 -0
- ksadk/server/static/assets/erlang-DaB2Rkuy.js +1 -0
- ksadk/server/static/assets/eventmodeling-FCH6USID-CIgwHJLL.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-DtTmUan-.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-BSsb_eij.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-BVAJ7uo0.js +1 -0
- ksadk/server/static/assets/gitGraphDiagram-PVQCEYII-BR5s6Pws.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-BH7-pC0B.js +165 -0
- ksadk/server/static/assets/index-DAURbCsP.css +1 -0
- ksadk/server/static/assets/info-J43DQDTF-MT80V4ge.js +1 -0
- ksadk/server/static/assets/infoDiagram-5YYISTIA-DYPc5cvh.js +2 -0
- ksadk/server/static/assets/init-D6jRqBbL.js +1 -0
- ksadk/server/static/assets/ishikawaDiagram-YF4QCWOH-MoBdALDg.js +70 -0
- ksadk/server/static/assets/javascript-9Tg8ixDm.js +1 -0
- ksadk/server/static/assets/journeyDiagram-JHISSGLW-DgLiQT8l.js +139 -0
- ksadk/server/static/assets/julia-CQfgDRfP.js +1 -0
- ksadk/server/static/assets/kanban-definition-UN3LZRKU-CsFx112F.js +89 -0
- ksadk/server/static/assets/katex-DRsiwpM2.js +265 -0
- ksadk/server/static/assets/linear-TNRQ5Orv.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-D2eMVOgo.js +161 -0
- ksadk/server/static/assets/mindmap-definition-RKZ34NQL-BtByYFhL.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-BLKhbXZB.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-DFOikjSY.js +1 -0
- ksadk/server/static/assets/pieDiagram-4H26LBE5-DPnuCB8c.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-miFpCPv4.js +7 -0
- ksadk/server/static/assets/r-DADKenSm.js +1 -0
- ksadk/server/static/assets/radar-GUYGQ44K-095b1Ikw.js +1 -0
- ksadk/server/static/assets/requirementDiagram-4Y6WPE33-mjB_yYkW.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-D7hSlZZZ.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-D9Cx6hC3.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-D_zrg47o.js +1 -0
- ksadk/server/static/assets/stateDiagram-v2-BHNVJYJU-J9kCb0nC.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-CwSec0Wa.js +120 -0
- ksadk/server/static/assets/toml-LvoKBwCs.js +1 -0
- ksadk/server/static/assets/treeView-BLDUP644-yinfJEY6.js +1 -0
- ksadk/server/static/assets/treemap-LRROVOQU-DosUqN1Q.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-agCVobiF.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-Bvp7-5uH.js +1 -0
- ksadk/server/static/assets/wardleyDiagram-YWT4CUSO-TmrlhWNt.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-DV71V-ah.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 +283 -0
- ksadk/sessions/base.py +354 -0
- ksadk/sessions/continuity.py +313 -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 +838 -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 +852 -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 +878 -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 +829 -0
- ksadk/tracing/span_utils.py +114 -0
- ksadk/tui/__init__.py +12 -0
- ksadk/tui/app.py +400 -0
- ksadk/tui/clipboard.py +100 -0
- ksadk/tui/widgets/__init__.py +22 -0
- ksadk/tui/widgets/assistant.py +89 -0
- ksadk/tui/widgets/base.py +54 -0
- ksadk/tui/widgets/chat_input.py +246 -0
- ksadk/tui/widgets/history.py +156 -0
- ksadk/tui/widgets/system.py +87 -0
- ksadk/tui/widgets/thinking.py +110 -0
- ksadk/tui/widgets/tool_call.py +161 -0
- ksadk/tui/widgets/user.py +37 -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-0.6.2.dist-info/METADATA +0 -46
- agentengine_sdk_python-0.6.2.dist-info/RECORD +0 -4
- agentengine_sdk_python-0.6.2.dist-info/top_level.txt +0 -1
|
@@ -0,0 +1,273 @@
|
|
|
1
|
+
"""LongTermMemory - 长期记忆服务
|
|
2
|
+
|
|
3
|
+
实现 Google ADK 的 BaseMemoryService 接口,提供跨 session 的记忆存储和检索。
|
|
4
|
+
通过环境变量配置后端类型和参数,由 ADKRunner 自动注入。
|
|
5
|
+
|
|
6
|
+
参考 VeADK: veadk/memory/long_term_memory.py
|
|
7
|
+
|
|
8
|
+
环境变量:
|
|
9
|
+
KSADK_LTM_BACKEND: 后端类型 (local / http)
|
|
10
|
+
KSADK_LTM_HTTP_URL: HTTP 记忆服务地址
|
|
11
|
+
KSADK_LTM_HTTP_TOKEN: HTTP 认证 Token
|
|
12
|
+
KSADK_LTM_TOP_K: 检索数量 (默认 5)
|
|
13
|
+
|
|
14
|
+
使用示例:
|
|
15
|
+
# 通过环境变量自动配置 (推荐)
|
|
16
|
+
# 设置 KSADK_LTM_BACKEND=local 即可
|
|
17
|
+
|
|
18
|
+
# 手动创建
|
|
19
|
+
from ksadk.memory.adk import LongTermMemory
|
|
20
|
+
ltm = LongTermMemory(backend="local", app_name="my_app")
|
|
21
|
+
"""
|
|
22
|
+
|
|
23
|
+
import json
|
|
24
|
+
import logging
|
|
25
|
+
import os
|
|
26
|
+
from typing import Any, List, Literal
|
|
27
|
+
|
|
28
|
+
from google.adk.events.event import Event
|
|
29
|
+
from google.adk.memory.base_memory_service import (
|
|
30
|
+
BaseMemoryService,
|
|
31
|
+
SearchMemoryResponse,
|
|
32
|
+
)
|
|
33
|
+
from google.adk.memory.memory_entry import MemoryEntry
|
|
34
|
+
from google.adk.sessions import Session
|
|
35
|
+
from google.genai import types
|
|
36
|
+
from pydantic import BaseModel, ConfigDict, Field
|
|
37
|
+
from typing_extensions import Union, override
|
|
38
|
+
|
|
39
|
+
from ksadk.memory.adk.backends.base_ltm_backend import BaseLongTermMemoryBackend
|
|
40
|
+
from ksadk.memory.service import LongTermMemoryService
|
|
41
|
+
|
|
42
|
+
logger = logging.getLogger(__name__)
|
|
43
|
+
|
|
44
|
+
|
|
45
|
+
class LongTermMemory(BaseMemoryService, BaseModel):
|
|
46
|
+
"""长期记忆服务 - 跨 session 的记忆管理
|
|
47
|
+
|
|
48
|
+
实现 Google ADK 的 BaseMemoryService 接口,支持:
|
|
49
|
+
- 将 session 中的用户消息持久化到记忆后端
|
|
50
|
+
- 通过语义/关键词检索历史记忆
|
|
51
|
+
|
|
52
|
+
Attributes:
|
|
53
|
+
backend: 后端类型或实例 ("local" / "http" / BaseLongTermMemoryBackend)
|
|
54
|
+
backend_config: 后端配置参数
|
|
55
|
+
top_k: 检索返回的最大记忆条数
|
|
56
|
+
index: 索引名称 (用于隔离不同应用的数据)
|
|
57
|
+
app_name: 应用名称 (备选 index)
|
|
58
|
+
|
|
59
|
+
Examples:
|
|
60
|
+
```python
|
|
61
|
+
# 本地开发
|
|
62
|
+
ltm = LongTermMemory(backend="local", app_name="my_app")
|
|
63
|
+
|
|
64
|
+
# 远程服务
|
|
65
|
+
ltm = LongTermMemory(
|
|
66
|
+
backend="http",
|
|
67
|
+
backend_config={
|
|
68
|
+
"base_url": "https://memory.ksyun.com/api/v1",
|
|
69
|
+
"token": "sk-xxx",
|
|
70
|
+
},
|
|
71
|
+
app_name="my_app"
|
|
72
|
+
)
|
|
73
|
+
```
|
|
74
|
+
"""
|
|
75
|
+
|
|
76
|
+
backend: Union[
|
|
77
|
+
Literal["local", "http", "sdk"],
|
|
78
|
+
BaseLongTermMemoryBackend,
|
|
79
|
+
] = "local"
|
|
80
|
+
|
|
81
|
+
backend_config: dict = Field(default_factory=dict)
|
|
82
|
+
top_k: int = 5
|
|
83
|
+
index: str = ""
|
|
84
|
+
app_name: str = ""
|
|
85
|
+
|
|
86
|
+
_backend: BaseLongTermMemoryBackend = None
|
|
87
|
+
_service: LongTermMemoryService = None
|
|
88
|
+
|
|
89
|
+
model_config = ConfigDict(arbitrary_types_allowed=True)
|
|
90
|
+
|
|
91
|
+
def model_post_init(self, __context: Any) -> None:
|
|
92
|
+
self._service = LongTermMemoryService(
|
|
93
|
+
backend=self.backend,
|
|
94
|
+
backend_config=self.backend_config,
|
|
95
|
+
top_k=self.top_k,
|
|
96
|
+
index=self.index,
|
|
97
|
+
app_name=self.app_name,
|
|
98
|
+
)
|
|
99
|
+
self._backend = self._service._backend
|
|
100
|
+
self.index = self._service.index
|
|
101
|
+
logger.info(
|
|
102
|
+
"LongTermMemory initialized: backend=%s, index=%s",
|
|
103
|
+
self.backend,
|
|
104
|
+
self.index,
|
|
105
|
+
)
|
|
106
|
+
|
|
107
|
+
def _get_service(self) -> LongTermMemoryService:
|
|
108
|
+
if self._service is None:
|
|
109
|
+
self.model_post_init(None)
|
|
110
|
+
if self._backend is not None and self._service._backend is not self._backend:
|
|
111
|
+
self._service.backend = self._backend
|
|
112
|
+
self._service._backend = self._backend
|
|
113
|
+
self._service.index = getattr(self._backend, "index", self._service.index)
|
|
114
|
+
self.index = self._service.index
|
|
115
|
+
return self._service
|
|
116
|
+
|
|
117
|
+
def _filter_and_convert_events(self, events: List[Event]) -> List[str]:
|
|
118
|
+
"""过滤并序列化 session 事件
|
|
119
|
+
|
|
120
|
+
参考 VeADK 的逻辑:
|
|
121
|
+
- 只保留用户消息 (author == "user")
|
|
122
|
+
- 过滤掉空内容、function call、function response
|
|
123
|
+
- 序列化为 JSON 字符串
|
|
124
|
+
"""
|
|
125
|
+
final_events = []
|
|
126
|
+
for event in events:
|
|
127
|
+
# 过滤: 无内容的事件
|
|
128
|
+
if not event.content or not event.content.parts:
|
|
129
|
+
continue
|
|
130
|
+
|
|
131
|
+
# 过滤: 只保留用户事件
|
|
132
|
+
if event.author != "user":
|
|
133
|
+
continue
|
|
134
|
+
|
|
135
|
+
# 过滤: 去除 function call / function response (无 text)
|
|
136
|
+
if not event.content.parts[0].text:
|
|
137
|
+
continue
|
|
138
|
+
|
|
139
|
+
# 转换: 序列化为 JSON
|
|
140
|
+
message = event.content.model_dump(exclude_none=True, mode="json")
|
|
141
|
+
final_events.append(json.dumps(message, ensure_ascii=False))
|
|
142
|
+
|
|
143
|
+
return final_events
|
|
144
|
+
|
|
145
|
+
@override
|
|
146
|
+
async def add_session_to_memory(
|
|
147
|
+
self,
|
|
148
|
+
session: Session,
|
|
149
|
+
**kwargs,
|
|
150
|
+
):
|
|
151
|
+
"""将 session 中的用户消息保存到长期记忆
|
|
152
|
+
|
|
153
|
+
Args:
|
|
154
|
+
session: Google ADK Session 对象
|
|
155
|
+
"""
|
|
156
|
+
user_id = session.user_id
|
|
157
|
+
event_strings = self._filter_and_convert_events(session.events)
|
|
158
|
+
|
|
159
|
+
if not event_strings:
|
|
160
|
+
logger.info(
|
|
161
|
+
f"No user events to save for session={session.id}"
|
|
162
|
+
)
|
|
163
|
+
return
|
|
164
|
+
|
|
165
|
+
logger.info(
|
|
166
|
+
f"Saving {len(event_strings)} events to long term memory: "
|
|
167
|
+
f"index={self.index}, user_id={user_id}"
|
|
168
|
+
)
|
|
169
|
+
|
|
170
|
+
self._get_service().save_event_strings(
|
|
171
|
+
user_id=user_id,
|
|
172
|
+
event_strings=event_strings,
|
|
173
|
+
metadata=kwargs.get("metadata"),
|
|
174
|
+
)
|
|
175
|
+
|
|
176
|
+
logger.info(
|
|
177
|
+
f"Saved {len(event_strings)} events to long term memory: "
|
|
178
|
+
f"index={self.index}, user_id={user_id}"
|
|
179
|
+
)
|
|
180
|
+
|
|
181
|
+
@override
|
|
182
|
+
async def search_memory(
|
|
183
|
+
self, *, app_name: str, user_id: str, query: str
|
|
184
|
+
) -> SearchMemoryResponse:
|
|
185
|
+
"""检索长期记忆
|
|
186
|
+
|
|
187
|
+
Args:
|
|
188
|
+
app_name: 应用名称
|
|
189
|
+
user_id: 用户 ID
|
|
190
|
+
query: 查询文本
|
|
191
|
+
|
|
192
|
+
Returns:
|
|
193
|
+
SearchMemoryResponse: 包含匹配记忆条目的响应
|
|
194
|
+
"""
|
|
195
|
+
logger.info(f"Searching memory: query='{query[:50]}' user_id={user_id}")
|
|
196
|
+
|
|
197
|
+
memory_chunks = []
|
|
198
|
+
try:
|
|
199
|
+
memory_chunks = self._get_service().search_entries(
|
|
200
|
+
query=query, top_k=self.top_k, user_id=user_id
|
|
201
|
+
)
|
|
202
|
+
except Exception as e:
|
|
203
|
+
logger.error(
|
|
204
|
+
f"Error during memory search: {e}. Returning empty results."
|
|
205
|
+
)
|
|
206
|
+
|
|
207
|
+
# 转换为 MemoryEntry 格式
|
|
208
|
+
memory_events = []
|
|
209
|
+
for memory in memory_chunks:
|
|
210
|
+
try:
|
|
211
|
+
memory_dict = json.loads(memory)
|
|
212
|
+
try:
|
|
213
|
+
text = memory_dict["parts"][0]["text"]
|
|
214
|
+
role = memory_dict.get("role", "user")
|
|
215
|
+
except (KeyError, IndexError):
|
|
216
|
+
logger.warning(
|
|
217
|
+
f"Non-standard memory format: {memory[:100]}. Skipping."
|
|
218
|
+
)
|
|
219
|
+
continue
|
|
220
|
+
except json.JSONDecodeError:
|
|
221
|
+
# 非 JSON 格式的记忆字符串,直接作为 text
|
|
222
|
+
text = memory
|
|
223
|
+
role = "user"
|
|
224
|
+
|
|
225
|
+
memory_events.append(
|
|
226
|
+
MemoryEntry(
|
|
227
|
+
author="user",
|
|
228
|
+
content=types.Content(
|
|
229
|
+
parts=[types.Part(text=text)], role=role
|
|
230
|
+
),
|
|
231
|
+
)
|
|
232
|
+
)
|
|
233
|
+
|
|
234
|
+
logger.info(
|
|
235
|
+
f"Found {len(memory_events)} memory entries for "
|
|
236
|
+
f"query='{query[:50]}' index={self.index} user_id={user_id}"
|
|
237
|
+
)
|
|
238
|
+
return SearchMemoryResponse(memories=memory_events)
|
|
239
|
+
|
|
240
|
+
@classmethod
|
|
241
|
+
def from_env(
|
|
242
|
+
cls,
|
|
243
|
+
*,
|
|
244
|
+
app_name: str = "",
|
|
245
|
+
backend: str | None = None,
|
|
246
|
+
) -> "LongTermMemory":
|
|
247
|
+
"""从环境变量创建 LongTermMemory
|
|
248
|
+
|
|
249
|
+
环境变量:
|
|
250
|
+
KSADK_LTM_BACKEND: local / http / sdk
|
|
251
|
+
KSADK_LTM_HTTP_URL: HTTP 记忆服务地址
|
|
252
|
+
KSADK_LTM_HTTP_TOKEN: HTTP 认证 Token
|
|
253
|
+
KSADK_LTM_ACCESS_KEY: SDK AK (fallback to KSYUN_ACCESS_KEY)
|
|
254
|
+
KSADK_LTM_SECRET_KEY: SDK SK (fallback to KSYUN_SECRET_KEY)
|
|
255
|
+
KSADK_LTM_TOP_K: 检索数量 (默认 5)
|
|
256
|
+
KSADK_LTM_INDEX: 索引名称
|
|
257
|
+
"""
|
|
258
|
+
service = LongTermMemoryService.from_env(app_name=app_name, backend=backend)
|
|
259
|
+
backend_name = (
|
|
260
|
+
backend
|
|
261
|
+
or os.environ.get("KSADK_LTM_BACKEND", "local")
|
|
262
|
+
)
|
|
263
|
+
backend_config = dict(service.backend_config)
|
|
264
|
+
if "index" in backend_config and backend_name != "local":
|
|
265
|
+
backend_config.pop("index", None)
|
|
266
|
+
|
|
267
|
+
return cls(
|
|
268
|
+
backend=backend_name,
|
|
269
|
+
backend_config=backend_config,
|
|
270
|
+
top_k=service.top_k,
|
|
271
|
+
index=service.index,
|
|
272
|
+
app_name=service.app_name,
|
|
273
|
+
)
|
|
@@ -0,0 +1,289 @@
|
|
|
1
|
+
"""ShortTermMemory - 短期记忆 (会话管理)
|
|
2
|
+
|
|
3
|
+
封装 Google ADK 的 SessionService,提供统一的会话创建和管理接口。
|
|
4
|
+
通过环境变量配置后端类型,由 ADKRunner 自动注入。
|
|
5
|
+
|
|
6
|
+
参考 VeADK: veadk/memory/short_term_memory.py
|
|
7
|
+
|
|
8
|
+
环境变量:
|
|
9
|
+
KSADK_SESSION_BACKEND: 统一 session 后端类型 (memory / local / sqlite / postgres)
|
|
10
|
+
KSADK_SESSION_DSN: 统一 session 数据库 DSN
|
|
11
|
+
KSADK_STM_BACKEND: 旧短期记忆后端类型 (local / sqlite / database)
|
|
12
|
+
KSADK_STM_DB_URL: 旧数据库连接 URL (sqlite/database 时需要)
|
|
13
|
+
|
|
14
|
+
使用示例:
|
|
15
|
+
# InMemory (默认,开发测试)
|
|
16
|
+
stm = ShortTermMemory(backend="local")
|
|
17
|
+
|
|
18
|
+
# SQLite 持久化
|
|
19
|
+
stm = ShortTermMemory(backend="sqlite")
|
|
20
|
+
|
|
21
|
+
# 自定义数据库
|
|
22
|
+
stm = ShortTermMemory(db_url="postgresql+asyncpg://user:pass@host/db")
|
|
23
|
+
"""
|
|
24
|
+
|
|
25
|
+
import logging
|
|
26
|
+
import os
|
|
27
|
+
from typing import Any, Literal, Optional
|
|
28
|
+
|
|
29
|
+
from google.adk.sessions import (
|
|
30
|
+
BaseSessionService,
|
|
31
|
+
InMemorySessionService,
|
|
32
|
+
Session,
|
|
33
|
+
)
|
|
34
|
+
from pydantic import BaseModel, PrivateAttr
|
|
35
|
+
|
|
36
|
+
logger = logging.getLogger(__name__)
|
|
37
|
+
|
|
38
|
+
|
|
39
|
+
def _env_first(*names: str) -> str:
|
|
40
|
+
for name in names:
|
|
41
|
+
value = str(os.environ.get(name, "")).strip()
|
|
42
|
+
if value:
|
|
43
|
+
return value
|
|
44
|
+
return ""
|
|
45
|
+
|
|
46
|
+
|
|
47
|
+
def _normalize_backend_name(backend: str) -> str:
|
|
48
|
+
normalized = str(backend or "").strip().lower()
|
|
49
|
+
if normalized == "memory":
|
|
50
|
+
return "local"
|
|
51
|
+
if normalized == "postgres":
|
|
52
|
+
return "database"
|
|
53
|
+
return normalized
|
|
54
|
+
|
|
55
|
+
|
|
56
|
+
def _normalize_database_url(db_url: str) -> str:
|
|
57
|
+
"""Normalize sqlite URLs for google.adk DatabaseSessionService.
|
|
58
|
+
|
|
59
|
+
ADK uses SQLAlchemy async engines underneath, so plain `sqlite:///...`
|
|
60
|
+
URLs fail while `sqlite+aiosqlite:///...` works.
|
|
61
|
+
"""
|
|
62
|
+
normalized = str(db_url or "").strip()
|
|
63
|
+
if not normalized:
|
|
64
|
+
return ""
|
|
65
|
+
if normalized.startswith("sqlite+aiosqlite:"):
|
|
66
|
+
return normalized
|
|
67
|
+
if normalized.startswith("sqlite:"):
|
|
68
|
+
return "sqlite+aiosqlite:" + normalized[len("sqlite:") :]
|
|
69
|
+
return normalized
|
|
70
|
+
|
|
71
|
+
|
|
72
|
+
def _session_backend_requires_database_url(backend: str) -> bool:
|
|
73
|
+
return _normalize_backend_name(backend) == "database"
|
|
74
|
+
|
|
75
|
+
|
|
76
|
+
class ShortTermMemory(BaseModel):
|
|
77
|
+
"""短期记忆 - 会话管理
|
|
78
|
+
|
|
79
|
+
封装 Google ADK 的 SessionService,所有短期记忆内容(系统提示、
|
|
80
|
+
历史消息、模型回复)都会发送给模型。
|
|
81
|
+
|
|
82
|
+
Attributes:
|
|
83
|
+
backend: 后端类型
|
|
84
|
+
- "local": InMemorySessionService (默认,开发测试)
|
|
85
|
+
- "sqlite": DatabaseSessionService (SQLite 本地持久化)
|
|
86
|
+
- "database": DatabaseSessionService (自定义数据库 URL)
|
|
87
|
+
db_url: 数据库连接 URL (backend 为 sqlite/database 时使用)
|
|
88
|
+
local_database_path: SQLite 文件路径 (backend 为 sqlite 时使用)
|
|
89
|
+
|
|
90
|
+
Examples:
|
|
91
|
+
```python
|
|
92
|
+
# InMemory (开发)
|
|
93
|
+
stm = ShortTermMemory(backend="local")
|
|
94
|
+
|
|
95
|
+
# SQLite 持久化
|
|
96
|
+
stm = ShortTermMemory(backend="sqlite", local_database_path="/tmp/ksadk.db")
|
|
97
|
+
|
|
98
|
+
# 从环境变量自动创建
|
|
99
|
+
stm = ShortTermMemory.from_env()
|
|
100
|
+
```
|
|
101
|
+
"""
|
|
102
|
+
|
|
103
|
+
backend: Literal["local", "sqlite", "database"] = "local"
|
|
104
|
+
db_url: str = ""
|
|
105
|
+
local_database_path: str = "/tmp/ksadk_local_database.db"
|
|
106
|
+
|
|
107
|
+
_session_service: BaseSessionService = PrivateAttr()
|
|
108
|
+
|
|
109
|
+
def model_post_init(self, __context: Any) -> None:
|
|
110
|
+
# 优先使用 db_url
|
|
111
|
+
if self.db_url:
|
|
112
|
+
logger.info(
|
|
113
|
+
f"ShortTermMemory: using db_url (ignoring backend option)"
|
|
114
|
+
)
|
|
115
|
+
self._init_database_service(self.db_url)
|
|
116
|
+
return
|
|
117
|
+
|
|
118
|
+
match self.backend:
|
|
119
|
+
case "local":
|
|
120
|
+
self._session_service = InMemorySessionService()
|
|
121
|
+
logger.info("ShortTermMemory: using InMemorySessionService")
|
|
122
|
+
|
|
123
|
+
case "sqlite":
|
|
124
|
+
db_url = _normalize_database_url(
|
|
125
|
+
f"sqlite:///{self.local_database_path}"
|
|
126
|
+
)
|
|
127
|
+
self._init_database_service(db_url)
|
|
128
|
+
logger.info(
|
|
129
|
+
f"ShortTermMemory: using SQLite at "
|
|
130
|
+
f"{self.local_database_path}"
|
|
131
|
+
)
|
|
132
|
+
|
|
133
|
+
case "database":
|
|
134
|
+
if not self.db_url:
|
|
135
|
+
raise ValueError(
|
|
136
|
+
"KSADK_SESSION_DSN is required when ADK session backend resolves to database/postgres"
|
|
137
|
+
)
|
|
138
|
+
else:
|
|
139
|
+
self._init_database_service(self.db_url)
|
|
140
|
+
|
|
141
|
+
case _:
|
|
142
|
+
logger.warning(
|
|
143
|
+
f"ShortTermMemory: unknown backend '{self.backend}', "
|
|
144
|
+
f"falling back to InMemorySessionService"
|
|
145
|
+
)
|
|
146
|
+
self._session_service = InMemorySessionService()
|
|
147
|
+
|
|
148
|
+
def _init_database_service(self, db_url: str) -> None:
|
|
149
|
+
"""初始化数据库 SessionService"""
|
|
150
|
+
normalized_db_url = _normalize_database_url(db_url)
|
|
151
|
+
try:
|
|
152
|
+
from google.adk.sessions import DatabaseSessionService
|
|
153
|
+
|
|
154
|
+
self._session_service = DatabaseSessionService(db_url=normalized_db_url)
|
|
155
|
+
logger.info(
|
|
156
|
+
f"ShortTermMemory: using DatabaseSessionService "
|
|
157
|
+
f"({normalized_db_url[:30]}...)"
|
|
158
|
+
)
|
|
159
|
+
except ImportError:
|
|
160
|
+
logger.warning(
|
|
161
|
+
"DatabaseSessionService not available. "
|
|
162
|
+
"Install google-adk with database support. "
|
|
163
|
+
"Falling back to InMemorySessionService."
|
|
164
|
+
)
|
|
165
|
+
self._session_service = InMemorySessionService()
|
|
166
|
+
except Exception as e:
|
|
167
|
+
logger.error(
|
|
168
|
+
f"Failed to create DatabaseSessionService: {e}. "
|
|
169
|
+
f"Falling back to InMemorySessionService."
|
|
170
|
+
)
|
|
171
|
+
self._session_service = InMemorySessionService()
|
|
172
|
+
|
|
173
|
+
@property
|
|
174
|
+
def session_service(self) -> BaseSessionService:
|
|
175
|
+
"""获取底层的 SessionService 实例"""
|
|
176
|
+
return self._session_service
|
|
177
|
+
|
|
178
|
+
async def create_session(
|
|
179
|
+
self,
|
|
180
|
+
app_name: str,
|
|
181
|
+
user_id: str,
|
|
182
|
+
session_id: str = "",
|
|
183
|
+
) -> Optional[Session]:
|
|
184
|
+
"""创建或获取 session
|
|
185
|
+
|
|
186
|
+
如果 session_id 对应的 session 已存在,直接返回。
|
|
187
|
+
否则创建新的 session。
|
|
188
|
+
|
|
189
|
+
Args:
|
|
190
|
+
app_name: 应用名称
|
|
191
|
+
user_id: 用户 ID
|
|
192
|
+
session_id: 会话 ID (可选,为空时由 ADK 自动生成)
|
|
193
|
+
|
|
194
|
+
Returns:
|
|
195
|
+
Session 对象,创建失败时返回 None
|
|
196
|
+
"""
|
|
197
|
+
# 尝试获取已存在的 session
|
|
198
|
+
if session_id:
|
|
199
|
+
try:
|
|
200
|
+
session = await self._session_service.get_session(
|
|
201
|
+
app_name=app_name,
|
|
202
|
+
user_id=user_id,
|
|
203
|
+
session_id=session_id,
|
|
204
|
+
)
|
|
205
|
+
if session:
|
|
206
|
+
logger.debug(
|
|
207
|
+
f"Session {session_id} already exists "
|
|
208
|
+
f"(app={app_name}, user={user_id})"
|
|
209
|
+
)
|
|
210
|
+
return session
|
|
211
|
+
except Exception as e:
|
|
212
|
+
logger.debug(f"Session {session_id} not found: {e}")
|
|
213
|
+
|
|
214
|
+
# 创建新 session
|
|
215
|
+
try:
|
|
216
|
+
if session_id:
|
|
217
|
+
session = await self._session_service.create_session(
|
|
218
|
+
app_name=app_name,
|
|
219
|
+
user_id=user_id,
|
|
220
|
+
session_id=session_id,
|
|
221
|
+
)
|
|
222
|
+
else:
|
|
223
|
+
session = await self._session_service.create_session(
|
|
224
|
+
app_name=app_name,
|
|
225
|
+
user_id=user_id,
|
|
226
|
+
)
|
|
227
|
+
logger.info(
|
|
228
|
+
f"Created session: id={session.id}, "
|
|
229
|
+
f"app={app_name}, user={user_id}"
|
|
230
|
+
)
|
|
231
|
+
return session
|
|
232
|
+
except Exception as e:
|
|
233
|
+
logger.error(f"Failed to create session: {e}")
|
|
234
|
+
return None
|
|
235
|
+
|
|
236
|
+
@classmethod
|
|
237
|
+
def from_env(cls) -> "ShortTermMemory":
|
|
238
|
+
"""从环境变量创建 ShortTermMemory
|
|
239
|
+
|
|
240
|
+
环境变量:
|
|
241
|
+
KSADK_ADK_SESSION_BACKEND: ADK 专用 backend
|
|
242
|
+
KSADK_ADK_SESSION_URL: ADK 专用数据库 URL
|
|
243
|
+
KSADK_ADK_SESSION_PATH: ADK 专用 SQLite 路径
|
|
244
|
+
KSADK_STM_BACKEND: 平台级 STM backend
|
|
245
|
+
KSADK_STM_URL / KSADK_STM_DB_URL: 平台级数据库 URL
|
|
246
|
+
KSADK_STM_PATH / KSADK_STM_DB_PATH: 平台级 SQLite 路径
|
|
247
|
+
KSADK_SESSION_BACKEND: 统一 session backend fallback
|
|
248
|
+
KSADK_SESSION_DSN: 统一 session DSN fallback
|
|
249
|
+
"""
|
|
250
|
+
explicit_backend = _normalize_backend_name(
|
|
251
|
+
_env_first(
|
|
252
|
+
"KSADK_ADK_SESSION_BACKEND",
|
|
253
|
+
"KSADK_STM_BACKEND",
|
|
254
|
+
"KSADK_SESSION_BACKEND",
|
|
255
|
+
)
|
|
256
|
+
)
|
|
257
|
+
db_url = _normalize_database_url(
|
|
258
|
+
_env_first(
|
|
259
|
+
"KSADK_ADK_SESSION_URL",
|
|
260
|
+
"KSADK_STM_URL",
|
|
261
|
+
"KSADK_STM_DB_URL",
|
|
262
|
+
"KSADK_SESSION_DSN",
|
|
263
|
+
)
|
|
264
|
+
)
|
|
265
|
+
configured_db_path = _env_first(
|
|
266
|
+
"KSADK_ADK_SESSION_PATH",
|
|
267
|
+
"KSADK_STM_PATH",
|
|
268
|
+
"KSADK_STM_DB_PATH",
|
|
269
|
+
)
|
|
270
|
+
db_path = configured_db_path or "/tmp/ksadk_local_database.db"
|
|
271
|
+
|
|
272
|
+
backend = explicit_backend
|
|
273
|
+
if _session_backend_requires_database_url(backend) and not db_url:
|
|
274
|
+
raise ValueError(
|
|
275
|
+
"KSADK_SESSION_DSN is required when ADK session backend resolves to database/postgres"
|
|
276
|
+
)
|
|
277
|
+
if not backend:
|
|
278
|
+
if db_url:
|
|
279
|
+
backend = "database"
|
|
280
|
+
elif configured_db_path:
|
|
281
|
+
backend = "sqlite"
|
|
282
|
+
else:
|
|
283
|
+
backend = "local"
|
|
284
|
+
|
|
285
|
+
return cls(
|
|
286
|
+
backend=backend,
|
|
287
|
+
db_url=db_url,
|
|
288
|
+
local_database_path=db_path,
|
|
289
|
+
)
|
ksadk/memory/adk_tool.py
ADDED
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
"""ADK wrapper for platform save_memory tool."""
|
|
2
|
+
|
|
3
|
+
from __future__ import annotations
|
|
4
|
+
|
|
5
|
+
import logging
|
|
6
|
+
|
|
7
|
+
from ksadk.memory.tool import save_memory as _save_memory
|
|
8
|
+
|
|
9
|
+
logger = logging.getLogger(__name__)
|
|
10
|
+
|
|
11
|
+
|
|
12
|
+
def save_memory(content: str) -> dict:
|
|
13
|
+
"""保存一条长期记忆。"""
|
|
14
|
+
|
|
15
|
+
result = _save_memory(content)
|
|
16
|
+
return {
|
|
17
|
+
"result": result.get("message", ""),
|
|
18
|
+
**result,
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
|
|
22
|
+
def create_adk_tool():
|
|
23
|
+
try:
|
|
24
|
+
from google.adk.tools import FunctionTool
|
|
25
|
+
|
|
26
|
+
return FunctionTool(func=save_memory)
|
|
27
|
+
except ImportError:
|
|
28
|
+
logger.warning(
|
|
29
|
+
"google-adk not installed, returning raw function as tool. Install with: pip install ksadk[adk]"
|
|
30
|
+
)
|
|
31
|
+
return save_memory
|
|
@@ -0,0 +1,103 @@
|
|
|
1
|
+
"""Base Memory Backend - 抽象基类"""
|
|
2
|
+
|
|
3
|
+
from abc import ABC, abstractmethod
|
|
4
|
+
from typing import Any, Optional, List, Dict
|
|
5
|
+
from datetime import timedelta
|
|
6
|
+
|
|
7
|
+
|
|
8
|
+
class BaseMemoryBackend(ABC):
|
|
9
|
+
"""记忆存储后端抽象基类
|
|
10
|
+
|
|
11
|
+
所有后端实现必须继承此类并实现以下方法。
|
|
12
|
+
"""
|
|
13
|
+
|
|
14
|
+
@abstractmethod
|
|
15
|
+
def get(self, key: str, session_id: Optional[str] = None) -> Optional[Any]:
|
|
16
|
+
"""获取值
|
|
17
|
+
|
|
18
|
+
Args:
|
|
19
|
+
key: 键名
|
|
20
|
+
session_id: 可选的会话 ID,用于隔离不同会话的数据
|
|
21
|
+
|
|
22
|
+
Returns:
|
|
23
|
+
存储的值,不存在返回 None
|
|
24
|
+
"""
|
|
25
|
+
pass
|
|
26
|
+
|
|
27
|
+
@abstractmethod
|
|
28
|
+
def set(
|
|
29
|
+
self,
|
|
30
|
+
key: str,
|
|
31
|
+
value: Any,
|
|
32
|
+
session_id: Optional[str] = None,
|
|
33
|
+
ttl: Optional[timedelta] = None,
|
|
34
|
+
) -> bool:
|
|
35
|
+
"""设置值
|
|
36
|
+
|
|
37
|
+
Args:
|
|
38
|
+
key: 键名
|
|
39
|
+
value: 值 (会自动序列化)
|
|
40
|
+
session_id: 可选的会话 ID
|
|
41
|
+
ttl: 可选的过期时间
|
|
42
|
+
|
|
43
|
+
Returns:
|
|
44
|
+
是否成功
|
|
45
|
+
"""
|
|
46
|
+
pass
|
|
47
|
+
|
|
48
|
+
@abstractmethod
|
|
49
|
+
def delete(self, key: str, session_id: Optional[str] = None) -> bool:
|
|
50
|
+
"""删除键
|
|
51
|
+
|
|
52
|
+
Args:
|
|
53
|
+
key: 键名
|
|
54
|
+
session_id: 可选的会话 ID
|
|
55
|
+
|
|
56
|
+
Returns:
|
|
57
|
+
是否成功
|
|
58
|
+
"""
|
|
59
|
+
pass
|
|
60
|
+
|
|
61
|
+
@abstractmethod
|
|
62
|
+
def exists(self, key: str, session_id: Optional[str] = None) -> bool:
|
|
63
|
+
"""检查键是否存在"""
|
|
64
|
+
pass
|
|
65
|
+
|
|
66
|
+
@abstractmethod
|
|
67
|
+
def clear_session(self, session_id: str) -> bool:
|
|
68
|
+
"""清除整个会话的所有数据"""
|
|
69
|
+
pass
|
|
70
|
+
|
|
71
|
+
# ===== 消息历史相关 (短期记忆) =====
|
|
72
|
+
|
|
73
|
+
@abstractmethod
|
|
74
|
+
def add_message(
|
|
75
|
+
self,
|
|
76
|
+
session_id: str,
|
|
77
|
+
role: str,
|
|
78
|
+
content: str,
|
|
79
|
+
metadata: Optional[Dict] = None,
|
|
80
|
+
) -> bool:
|
|
81
|
+
"""添加消息到会话历史"""
|
|
82
|
+
pass
|
|
83
|
+
|
|
84
|
+
@abstractmethod
|
|
85
|
+
def get_messages(
|
|
86
|
+
self,
|
|
87
|
+
session_id: str,
|
|
88
|
+
limit: Optional[int] = None,
|
|
89
|
+
) -> List[Dict]:
|
|
90
|
+
"""获取会话消息历史
|
|
91
|
+
|
|
92
|
+
Args:
|
|
93
|
+
session_id: 会话 ID
|
|
94
|
+
limit: 最近 N 条消息,None 表示全部
|
|
95
|
+
|
|
96
|
+
Returns:
|
|
97
|
+
消息列表 [{role, content, timestamp, ...}]
|
|
98
|
+
"""
|
|
99
|
+
pass
|
|
100
|
+
|
|
101
|
+
def close(self) -> None:
|
|
102
|
+
"""关闭连接 (可选实现)"""
|
|
103
|
+
pass
|