agentengine-sdk-python 0.7.0__py3-none-any.whl → 0.8.0__py3-none-any.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- {agentengine_sdk_python-0.7.0.dist-info → agentengine_sdk_python-0.8.0.dist-info}/METADATA +36 -20
- agentengine_sdk_python-0.8.0.dist-info/RECORD +578 -0
- ksadk/a2a/__init__.py +178 -11
- ksadk/a2a/bootstrap.py +334 -0
- ksadk/a2a/card.py +120 -0
- ksadk/a2a/context_store.py +203 -0
- ksadk/a2a/control_plane.py +818 -0
- ksadk/a2a/credential.py +99 -0
- ksadk/a2a/event_adapter.py +149 -0
- ksadk/a2a/executor.py +406 -89
- ksadk/a2a/external_transport.py +516 -0
- ksadk/a2a/identity.py +304 -0
- ksadk/a2a/ids.py +22 -0
- ksadk/a2a/langgraph.py +285 -0
- ksadk/a2a/resume_store.py +201 -0
- ksadk/a2a/routes.py +105 -0
- ksadk/a2a/server.py +107 -60
- ksadk/a2a/space_client.py +1101 -0
- ksadk/a2a/task_adapter.py +423 -0
- ksadk/a2a/task_event_dispatcher.py +167 -0
- ksadk/a2a/task_event_outbox.py +326 -0
- ksadk/a2a/task_store.py +206 -0
- ksadk/a2ui/__init__.py +27 -0
- ksadk/a2ui/core.py +186 -0
- ksadk/a2ui/models.py +166 -0
- ksadk/a2ui/renderer.py +198 -0
- ksadk/agui/__init__.py +9 -0
- ksadk/agui/a2ui_projection.py +92 -0
- ksadk/agui/agent.py +857 -0
- ksadk/agui/config.py +86 -0
- ksadk/agui/routes.py +55 -0
- ksadk/api/client.py +233 -191
- ksadk/builders/__init__.py +2 -0
- ksadk/builders/base.py +16 -14
- ksadk/builders/code_builder.py +318 -236
- ksadk/builders/container_builder.py +187 -167
- ksadk/builders/framework_requirements.py +29 -11
- ksadk/builders/ks3_uploader.py +58 -27
- ksadk/builders/managed_runtime_builder.py +145 -0
- ksadk/builders/mcp_builder.py +91 -92
- ksadk/builders/requirements_utils.py +1 -5
- ksadk/cli/__init__.py +89 -171
- ksadk/cli/cmd_a2a.py +254 -70
- ksadk/cli/cmd_agent.py +19 -5
- ksadk/cli/cmd_build.py +158 -29
- ksadk/cli/cmd_completion.py +47 -35
- ksadk/cli/cmd_config.py +267 -198
- ksadk/cli/cmd_create.py +500 -720
- ksadk/cli/cmd_dashboard.py +120 -45
- ksadk/cli/cmd_deploy.py +117 -58
- ksadk/cli/cmd_destroy.py +44 -14
- ksadk/cli/cmd_files.py +63 -24
- ksadk/cli/cmd_hermes.py +168 -89
- ksadk/cli/cmd_invoke.py +184 -122
- ksadk/cli/cmd_launch.py +64 -28
- ksadk/cli/cmd_mcp.py +98 -64
- ksadk/cli/cmd_model.py +14 -5
- ksadk/cli/cmd_openclaw.py +483 -227
- ksadk/cli/cmd_replay.py +71 -0
- ksadk/cli/cmd_run.py +33 -10
- ksadk/cli/cmd_status.py +80 -31
- ksadk/cli/cmd_version.py +20 -13
- ksadk/cli/cmd_web.py +89 -13
- ksadk/cli/deploy_utils.py +20 -20
- ksadk/cli/dry_run.py +5 -3
- ksadk/cli/error_utils.py +37 -12
- ksadk/cli/global_options.py +1 -2
- ksadk/cli/local_runtime.py +1 -2
- ksadk/cli/model_catalog.py +6 -2
- ksadk/cli/network_options.py +34 -14
- ksadk/cli/resource_common.py +6 -2
- ksadk/cli/storage.py +0 -1
- ksadk/cli/ui.py +5 -3
- ksadk/cli/workflow_common.py +51 -17
- ksadk/codex/__init__.py +12 -0
- ksadk/codex/client.py +408 -0
- ksadk/codex/phase.py +143 -0
- ksadk/codex/runtime.py +449 -0
- ksadk/common/aicp_env.py +0 -1
- ksadk/common/auth.py +2 -2
- ksadk/common/constants.py +1 -3
- ksadk/common/llm_utils.py +17 -13
- ksadk/compat/__init__.py +5 -0
- ksadk/compat/adk_compat.py +200 -0
- ksadk/compat/copilotkit_a2ui.py +330 -0
- ksadk/configs/__init__.py +12 -12
- ksadk/configs/env_registry.py +500 -100
- ksadk/configs/global_config.py +2 -1
- ksadk/configs/settings.py +151 -124
- ksadk/conversations/__init__.py +7 -5
- ksadk/conversations/attachment_storage.py +16 -11
- ksadk/conversations/attachments.py +44 -36
- ksadk/conversations/compaction_pipeline.py +12 -12
- ksadk/conversations/compaction_prompt.py +9 -5
- ksadk/conversations/context.py +221 -6
- ksadk/conversations/message_projection.py +438 -51
- ksadk/conversations/model_context.py +12 -6
- ksadk/conversations/model_options.py +0 -1
- ksadk/conversations/normalize.py +20 -16
- ksadk/conversations/reasoning_markup.py +1 -1
- ksadk/conversations/runtime.py +339 -5255
- ksadk/conversations/runtime_compaction.py +333 -0
- ksadk/conversations/runtime_constants.py +27 -0
- ksadk/conversations/runtime_governance.py +185 -0
- ksadk/conversations/runtime_input.py +652 -0
- ksadk/conversations/runtime_invocation.py +395 -0
- ksadk/conversations/runtime_metadata.py +475 -0
- ksadk/conversations/runtime_observability.py +355 -0
- ksadk/conversations/runtime_payloads.py +272 -0
- ksadk/conversations/runtime_persistence.py +440 -0
- ksadk/conversations/runtime_preparation.py +418 -0
- ksadk/conversations/runtime_resume.py +816 -0
- ksadk/conversations/runtime_stream_events.py +902 -0
- ksadk/conversations/runtime_streaming.py +547 -0
- ksadk/conversations/semantic_summary.py +17 -5
- ksadk/conversations/session_title.py +6 -3
- ksadk/deployment/__init__.py +15 -16
- ksadk/deployment/agent_access.py +12 -23
- ksadk/deployment/base.py +51 -38
- ksadk/deployment/manager.py +63 -65
- ksadk/deployment/providers/serverless.py +309 -202
- ksadk/deployment/registry.py +38 -32
- ksadk/deployment/state.py +11 -11
- ksadk/deployment/ui_config.py +1 -1
- ksadk/detection/__init__.py +1 -1
- ksadk/detection/detector.py +146 -83
- ksadk/detection/mcp_detector.py +9 -6
- ksadk/events/__init__.py +25 -0
- ksadk/events/parser.py +191 -0
- ksadk/events/replay.py +37 -0
- ksadk/events/runtime_event.py +264 -0
- ksadk/events/store.py +317 -0
- ksadk/harness/__init__.py +34 -0
- ksadk/harness/app.py +278 -0
- ksadk/harness/config.py +181 -0
- ksadk/harness/reasoner.py +105 -0
- ksadk/harness/runner.py +211 -0
- ksadk/harness/sandbox.py +141 -0
- ksadk/harness/tools.py +222 -0
- ksadk/hermes_terminal.py +23 -12
- ksadk/identity/resolver.py +15 -9
- ksadk/ids.py +32 -0
- ksadk/knowledge_base/adk_tool.py +1 -1
- ksadk/knowledge_base/client.py +23 -29
- ksadk/managed_runtime.py +188 -0
- ksadk/markdown.py +5 -2
- ksadk/mcp_runtime/__init__.py +9 -6
- ksadk/memory/__init__.py +1 -1
- ksadk/memory/adk/__init__.py +2 -0
- ksadk/memory/adk/backends/base_ltm_backend.py +2 -6
- ksadk/memory/adk/backends/http_ltm_backend.py +13 -21
- ksadk/memory/adk/backends/inmemory_ltm_backend.py +7 -13
- ksadk/memory/adk/backends/sdk_ltm_backend.py +26 -33
- ksadk/memory/adk/long_term_memory.py +31 -35
- ksadk/memory/adk/resilient_session_service.py +4 -5
- ksadk/memory/adk/short_term_memory.py +12 -21
- ksadk/memory/adk_tool.py +3 -2
- ksadk/memory/backends/base.py +19 -19
- ksadk/memory/backends/memory.py +24 -25
- ksadk/memory/backends/redis.py +31 -30
- ksadk/memory/langchain_tool.py +2 -1
- ksadk/memory/manager.py +52 -47
- ksadk/memory/service.py +10 -8
- ksadk/model_policy.py +15 -7
- ksadk/model_proxy/__init__.py +51 -0
- ksadk/model_proxy/bootstrap.py +80 -0
- ksadk/model_proxy/cache.py +165 -0
- ksadk/model_proxy/config.py +45 -0
- ksadk/model_proxy/demo_webui.py +115 -0
- ksadk/model_proxy/detect.py +145 -0
- ksadk/model_proxy/gate.py +68 -0
- ksadk/model_proxy/namespace.py +173 -0
- ksadk/model_proxy/protocol_proxy.py +22 -0
- ksadk/model_proxy/server.py +300 -0
- ksadk/model_proxy/transform.py +691 -0
- ksadk/openclaw_gateway.py +29 -14
- ksadk/runners/adk_runner.py +345 -120
- ksadk/runners/base_runner.py +46 -29
- ksadk/runners/codex_runner.py +132 -0
- ksadk/runners/deepagents_runner.py +0 -1
- ksadk/runners/factory.py +17 -5
- ksadk/runners/langchain_runner.py +29 -742
- ksadk/runners/langgraph_runner.py +352 -90
- ksadk/runners/patch_langchain.py +16 -16
- ksadk/runners/remote_runner.py +134 -33
- ksadk/runners/usage_accumulator.py +1 -0
- ksadk/runners/utils/langfuse.py +3 -3
- ksadk/runners/utils/loader.py +7 -7
- ksadk/runtime/__init__.py +41 -0
- ksadk/runtime/adapter.py +345 -0
- ksadk/runtime/framework_adapters.py +124 -0
- ksadk/runtime/preprocessing.py +118 -0
- ksadk/runtime/runner_adapter.py +873 -0
- ksadk/runtime_context.py +18 -3
- ksadk/runtime_state.py +0 -1
- ksadk/sandbox/__init__.py +4 -1
- ksadk/sandbox/backends/__init__.py +4 -1
- ksadk/sandbox/backends/e2b.py +13 -5
- ksadk/sandbox/backends/local_process.py +11 -3
- ksadk/sandbox/base.py +10 -15
- ksadk/sandbox/factory.py +14 -4
- ksadk/sandbox/registry.py +57 -6
- ksadk/server/api_models.py +15 -5
- ksadk/server/app.py +455 -3885
- ksadk/server/composition.py +21 -0
- ksadk/server/factory.py +624 -0
- ksadk/server/routes/__init__.py +1 -0
- ksadk/server/routes/checkpoint_resolution.py +116 -0
- ksadk/server/routes/common.py +713 -0
- ksadk/server/routes/control.py +327 -0
- ksadk/server/routes/dependencies.py +98 -0
- ksadk/server/routes/misc.py +448 -0
- ksadk/server/routes/models.py +443 -0
- ksadk/server/routes/openai_compat.py +207 -0
- ksadk/server/routes/projection.py +795 -0
- ksadk/server/routes/routers.py +52 -0
- ksadk/server/routes/run.py +726 -0
- ksadk/server/routes/sessions.py +649 -0
- ksadk/server/routes/streaming.py +223 -0
- ksadk/server/routes/workspace.py +381 -0
- ksadk/server/static/assets/{ArtifactsPanel-D-SSn2ee.js → ArtifactsPanel-Cjnqt-8W.js} +1 -1
- ksadk/server/static/assets/CodeBlock-BqyqZfuB.js +9 -0
- ksadk/server/static/assets/MathMessageMarkdown-BpH7jiFM.js +8 -0
- ksadk/server/static/assets/MermaidBlock-DWuxETaJ.js +303 -0
- ksadk/server/static/assets/NativeTerminalPanel-MDTopWMO.js +1 -0
- ksadk/server/static/assets/{arc-BA13sHc9.js → arc-CFKwSk_B.js} +1 -1
- ksadk/server/static/assets/architecture-7EHR7CIX-CynqOWjZ.js +1 -0
- ksadk/server/static/assets/{architectureDiagram-3BPJPVTR-DzJzgVoL.js → architectureDiagram-3BPJPVTR-Dej8jX8c.js} +1 -1
- ksadk/server/static/assets/{blockDiagram-GPEHLZMM-UTdVcZhn.js → blockDiagram-GPEHLZMM-1F64jqvy.js} +1 -1
- ksadk/server/static/assets/{c4Diagram-AAUBKEIU-Dix0GD4m.js → c4Diagram-AAUBKEIU-9q7AUAKb.js} +1 -1
- ksadk/server/static/assets/channel-iUGv2N24.js +1 -0
- ksadk/server/static/assets/{chunk-2J33WTMH-C2JxuZ42.js → chunk-2J33WTMH-6qgwJm7Q.js} +1 -1
- ksadk/server/static/assets/{chunk-4BX2VUAB-Be57QPgD.js → chunk-4BX2VUAB-CsWIQRhc.js} +1 -1
- ksadk/server/static/assets/{chunk-55IACEB6-WjSuy4nv.js → chunk-55IACEB6-BK8paA20.js} +1 -1
- ksadk/server/static/assets/{chunk-727SXJPM-BOovP-b5.js → chunk-727SXJPM-B-JEhy7h.js} +1 -1
- ksadk/server/static/assets/{chunk-AQP2D5EJ-DOmZNmWj.js → chunk-AQP2D5EJ-DYBvMHAa.js} +1 -1
- ksadk/server/static/assets/{chunk-FMBD7UC4-DzwlodkU.js → chunk-FMBD7UC4-BGhvzDYt.js} +1 -1
- ksadk/server/static/assets/{chunk-ND2GUHAM-DMqAikEU.js → chunk-ND2GUHAM-D98vPd-E.js} +1 -1
- ksadk/server/static/assets/chunk-QZHKN3VN-YQIEXeF6.js +1 -0
- ksadk/server/static/assets/classDiagram-4FO5ZUOK-CDAUuoXK.js +1 -0
- ksadk/server/static/assets/classDiagram-v2-Q7XG4LA2-CDAUuoXK.js +1 -0
- ksadk/server/static/assets/{cose-bilkent-S5V4N54A-Zhy2GBnP.js → cose-bilkent-S5V4N54A-CX3yotHq.js} +1 -1
- ksadk/server/static/assets/{dagre-BM42HDAG-CbKrtIUz.js → dagre-BM42HDAG-C7TguAWo.js} +1 -1
- ksadk/server/static/assets/{diagram-2AECGRRQ-BRApgQRK.js → diagram-2AECGRRQ-Dd17_kws.js} +1 -1
- ksadk/server/static/assets/{diagram-5GNKFQAL-D0xbnDiK.js → diagram-5GNKFQAL-DVIClIil.js} +1 -1
- ksadk/server/static/assets/{diagram-KO2AKTUF-CVugVI9L.js → diagram-KO2AKTUF-Df_3gYQa.js} +1 -1
- ksadk/server/static/assets/{diagram-LMA3HP47-DozUGgee.js → diagram-LMA3HP47-BhLk6ZtA.js} +1 -1
- ksadk/server/static/assets/{diagram-OG6HWLK6-ZOYsKlru.js → diagram-OG6HWLK6-D4GNGvuu.js} +1 -1
- ksadk/server/static/assets/{dist-DmFaq_Iy.js → dist-6CVKuTAe.js} +1 -1
- ksadk/server/static/assets/{dist-8EEyGgDx.js → dist-BUHRxvDG.js} +1 -1
- ksadk/server/static/assets/{dist-B0NP_Z0z.js → dist-BZ9n9AjO.js} +1 -1
- ksadk/server/static/assets/{dist-DMezvBGJ.js → dist-BibcG1V9.js} +1 -1
- ksadk/server/static/assets/{dist-C3HIIaN5.js → dist-Bs-jQcRX.js} +1 -1
- ksadk/server/static/assets/{dist-BrCcQ47T.js → dist-C2xjE7cO.js} +1 -1
- ksadk/server/static/assets/{dist-Dp0k7bWI.js → dist-C7-3jInC.js} +1 -1
- ksadk/server/static/assets/{dist-D-xOD048.js → dist-C99THtIA.js} +1 -1
- ksadk/server/static/assets/{dist-CkEKJFtk.js → dist-CGcp2ex8.js} +1 -1
- ksadk/server/static/assets/{dist-DyOkZmze.js → dist-CVQRZjPu.js} +1 -1
- ksadk/server/static/assets/{dist-BssVmjIo.js → dist-Cf23NY4L.js} +1 -1
- ksadk/server/static/assets/{dist-BIJVDMuB.js → dist-CgF3fj15.js} +1 -1
- ksadk/server/static/assets/{dist-2hInLS_J.js → dist-Cwt7koer.js} +1 -1
- ksadk/server/static/assets/{dist-DyWsb78Q.js → dist-D82mtD2s.js} +1 -1
- ksadk/server/static/assets/{dist-D-JMdWPQ.js → dist-DF06ORQo.js} +1 -1
- ksadk/server/static/assets/{dist-BmlMPsCc.js → dist-DHn6nBzr.js} +1 -1
- ksadk/server/static/assets/{dist-gX6GOLKq.js → dist-Djgl2wVZ.js} +1 -1
- ksadk/server/static/assets/{dist-DpKtt4Bo.js → dist-DlzCRy0S.js} +1 -1
- ksadk/server/static/assets/{dist-8_SfK1IP.js → dist-DqNnNFrw.js} +1 -1
- ksadk/server/static/assets/{dist-D57wnGWd.js → dist-DyvYLMW9.js} +1 -1
- ksadk/server/static/assets/{dist-CPBtqRTW.js → dist-eoW6tZXA.js} +1 -1
- ksadk/server/static/assets/{dist-DL_NKc_z.js → dist-ivOya1LD.js} +1 -1
- ksadk/server/static/assets/{erDiagram-TEJ5UH35-Bk-9bgE5.js → erDiagram-TEJ5UH35-CnfRcY2M.js} +1 -1
- ksadk/server/static/assets/eventmodeling-FCH6USID-ChYO-ijM.js +1 -0
- ksadk/server/static/assets/{flowDiagram-I6XJVG4X-Dn9kZVuZ.js → flowDiagram-I6XJVG4X-DGaJjGNJ.js} +1 -1
- ksadk/server/static/assets/{ganttDiagram-6RSMTGT7-BGxXlJqm.js → ganttDiagram-6RSMTGT7-DpCoB2g9.js} +1 -1
- ksadk/server/static/assets/gitGraph-WXDBUCRP-BN_0Fk-j.js +1 -0
- ksadk/server/static/assets/{gitGraphDiagram-PVQCEYII-C7Q0X-wi.js → gitGraphDiagram-PVQCEYII-9IKVFBVT.js} +1 -1
- ksadk/server/static/assets/index-QSwCHuB8.js +177 -0
- ksadk/server/static/assets/index-jOPmTOZH.css +2 -0
- ksadk/server/static/assets/info-J43DQDTF-Cp6o3vId.js +1 -0
- ksadk/server/static/assets/{infoDiagram-5YYISTIA-BO_CSqq5.js → infoDiagram-5YYISTIA-CYIIsb8y.js} +1 -1
- ksadk/server/static/assets/{ishikawaDiagram-YF4QCWOH-eYLPLd46.js → ishikawaDiagram-YF4QCWOH-DLOHGvWw.js} +1 -1
- ksadk/server/static/assets/{journeyDiagram-JHISSGLW-De9geSb0.js → journeyDiagram-JHISSGLW-BIzKeejT.js} +1 -1
- ksadk/server/static/assets/{kanban-definition-UN3LZRKU-Cs80kQto.js → kanban-definition-UN3LZRKU-BWHoFSw2.js} +1 -1
- ksadk/server/static/assets/{katex-DSrCFD8n.js → katex-DATssjp1.js} +1 -1
- ksadk/server/static/assets/{linear-CN9sbKTF.js → linear-CvMBw9cA.js} +1 -1
- ksadk/server/static/assets/{mermaid-parser.core-DlgSBU8l.js → mermaid-parser.core-mGAcEwcq.js} +2 -2
- ksadk/server/static/assets/{mindmap-definition-RKZ34NQL-9afz7Oug.js → mindmap-definition-RKZ34NQL-CSAQxEAe.js} +1 -1
- ksadk/server/static/assets/packet-YPE3B663-wQzct3cT.js +1 -0
- ksadk/server/static/assets/pie-LRSECV5Y-BgTQiv-9.js +1 -0
- ksadk/server/static/assets/{pieDiagram-4H26LBE5-DPv_VstN.js → pieDiagram-4H26LBE5-By-ra07M.js} +1 -1
- ksadk/server/static/assets/{quadrantDiagram-W4KKPZXB-o77wZ1XK.js → quadrantDiagram-W4KKPZXB-CxIR4JXI.js} +1 -1
- ksadk/server/static/assets/radar-GUYGQ44K-BIq5fXsn.js +1 -0
- ksadk/server/static/assets/{requirementDiagram-4Y6WPE33-BYVw81VC.js → requirementDiagram-4Y6WPE33-DpW90iu3.js} +1 -1
- ksadk/server/static/assets/{sankeyDiagram-5OEKKPKP-B7nZFMKT.js → sankeyDiagram-5OEKKPKP-DpGa6EAV.js} +1 -1
- ksadk/server/static/assets/{sequenceDiagram-3UESZ5HK-BGRRrFw5.js → sequenceDiagram-3UESZ5HK-NTKNGGe5.js} +1 -1
- ksadk/server/static/assets/{stateDiagram-AJRCARHV-BUfHCoPs.js → stateDiagram-AJRCARHV-DGpd9yFG.js} +1 -1
- ksadk/server/static/assets/stateDiagram-v2-BHNVJYJU-B3o579IQ.js +1 -0
- ksadk/server/static/assets/{timeline-definition-PNZ67QCA-FbCTGrf9.js → timeline-definition-PNZ67QCA-jqoYs3jQ.js} +1 -1
- ksadk/server/static/assets/treeView-BLDUP644-Dqi-E0EM.js +1 -0
- ksadk/server/static/assets/treemap-LRROVOQU-ClQP9CJ9.js +1 -0
- ksadk/server/static/assets/{vennDiagram-CIIHVFJN-DWgwtPsJ.js → vennDiagram-CIIHVFJN-l3Z7-wbP.js} +1 -1
- ksadk/server/static/assets/wardley-L42UT6IY-8XLvnNIs.js +1 -0
- ksadk/server/static/assets/{wardleyDiagram-YWT4CUSO-2x8G-tTM.js → wardleyDiagram-YWT4CUSO-BR54GPmr.js} +1 -1
- ksadk/server/static/assets/{xychartDiagram-2RQKCTM6-Drma3AYl.js → xychartDiagram-2RQKCTM6-SkiH8GsK.js} +1 -1
- ksadk/server/static/index.html +2 -2
- ksadk/server/terminal_sessions.py +111 -58
- ksadk/sessions/__init__.py +69 -19
- ksadk/sessions/base.py +31 -11
- ksadk/sessions/continuity.py +2 -3
- ksadk/sessions/in_memory.py +46 -2
- ksadk/sessions/local_service.py +148 -17
- ksadk/sessions/postgres_service.py +143 -25
- ksadk/sessions/resilient.py +36 -8
- ksadk/skills/models.py +17 -5
- ksadk/skills/package_store.py +5 -2
- ksadk/skills/runtime/agent.py +20 -5
- ksadk/skills/runtime/artifacts.py +1 -5
- ksadk/skills/runtime/backends/e2b.py +10 -4
- ksadk/skills/runtime/backends/local.py +15 -3
- ksadk/skills/runtime/base.py +1 -2
- ksadk/skills/runtime/executor.py +10 -3
- ksadk/skills/runtime/factory.py +4 -2
- ksadk/skills/runtime/loader.py +1 -2
- ksadk/skills/runtime/registry.py +15 -10
- ksadk/skills/runtime/request.py +3 -1
- ksadk/skills/service_client.py +38 -17
- ksadk/skills/tool_defs.py +15 -10
- ksadk/terminal_exec_policy.py +3 -4
- ksadk/tools/gateway.py +92 -15
- ksadk/tools/result_budget.py +12 -4
- ksadk/toolsets/__init__.py +134 -36
- ksadk/toolsets/platform.py +21 -5
- ksadk/toolsets/sandbox.py +82 -16
- ksadk/toolsets/skills.py +200 -39
- ksadk/toolsets/web.py +123 -26
- ksadk/toolsets/workspace.py +212 -101
- ksadk/tracing/exporters/inmemory_exporter.py +62 -51
- ksadk/tracing/exporters/langfuse_exporter.py +91 -76
- ksadk/tracing/setup.py +69 -53
- ksadk/tracing/span_utils.py +5 -2
- ksadk/tui/loop.py +78 -30
- ksadk/tui/stream_render.py +1 -0
- ksadk/ui_config.py +5 -3
- ksadk/version.py +1 -1
- ksadk_runtime_common/schemas/runtime_event_v1.json +95 -0
- agentengine_sdk_python-0.7.0.dist-info/RECORD +0 -482
- ksadk/server/static/assets/CodeBlock-P16VOLYi.js +0 -9
- ksadk/server/static/assets/MathMessageMarkdown-CdGiQWHR.js +0 -8
- ksadk/server/static/assets/MermaidBlock-IOcal8cm.js +0 -303
- ksadk/server/static/assets/NativeTerminalPanel-DGSDWsei.js +0 -1
- ksadk/server/static/assets/architecture-7EHR7CIX-BvUlsA6l.js +0 -1
- ksadk/server/static/assets/channel-CTuydARX.js +0 -1
- ksadk/server/static/assets/chunk-QZHKN3VN-BnCydivS.js +0 -1
- ksadk/server/static/assets/classDiagram-4FO5ZUOK-BNHg45Be.js +0 -1
- ksadk/server/static/assets/classDiagram-v2-Q7XG4LA2-BNHg45Be.js +0 -1
- ksadk/server/static/assets/eventmodeling-FCH6USID-DsAgWnlf.js +0 -1
- ksadk/server/static/assets/gitGraph-WXDBUCRP-BIao9Yjg.js +0 -1
- ksadk/server/static/assets/index-C00Lwg3L.js +0 -165
- ksadk/server/static/assets/index-DAURbCsP.css +0 -1
- ksadk/server/static/assets/info-J43DQDTF-CyipqGxU.js +0 -1
- ksadk/server/static/assets/packet-YPE3B663-CGkyRxlg.js +0 -1
- ksadk/server/static/assets/pie-LRSECV5Y-M0uWAf4n.js +0 -1
- ksadk/server/static/assets/radar-GUYGQ44K-Bdbm24-x.js +0 -1
- ksadk/server/static/assets/stateDiagram-v2-BHNVJYJU-8xBN_gLM.js +0 -1
- ksadk/server/static/assets/treeView-BLDUP644-npMo0ak1.js +0 -1
- ksadk/server/static/assets/treemap-LRROVOQU-CHdzrrdo.js +0 -1
- ksadk/server/static/assets/wardley-L42UT6IY-BEQz7wyy.js +0 -1
- {agentengine_sdk_python-0.7.0.dist-info → agentengine_sdk_python-0.8.0.dist-info}/WHEEL +0 -0
- {agentengine_sdk_python-0.7.0.dist-info → agentengine_sdk_python-0.8.0.dist-info}/entry_points.txt +0 -0
- {agentengine_sdk_python-0.7.0.dist-info → agentengine_sdk_python-0.8.0.dist-info}/licenses/LICENSE +0 -0
- {agentengine_sdk_python-0.7.0.dist-info → agentengine_sdk_python-0.8.0.dist-info}/top_level.txt +0 -0
ksadk/managed_runtime.py
ADDED
|
@@ -0,0 +1,188 @@
|
|
|
1
|
+
"""Managed runtime configuration and version resolution."""
|
|
2
|
+
|
|
3
|
+
from __future__ import annotations
|
|
4
|
+
|
|
5
|
+
import subprocess
|
|
6
|
+
from dataclasses import dataclass
|
|
7
|
+
from importlib.metadata import PackageNotFoundError
|
|
8
|
+
from importlib.metadata import version as package_version
|
|
9
|
+
from typing import Any
|
|
10
|
+
|
|
11
|
+
|
|
12
|
+
class ManagedRuntimeError(ValueError):
|
|
13
|
+
"""Raised when a managed runtime contract cannot be resolved safely."""
|
|
14
|
+
|
|
15
|
+
|
|
16
|
+
@dataclass(frozen=True)
|
|
17
|
+
class ResolvedRuntime:
|
|
18
|
+
name: str
|
|
19
|
+
version: str
|
|
20
|
+
source: str
|
|
21
|
+
package_requirement: str = ""
|
|
22
|
+
|
|
23
|
+
|
|
24
|
+
def runtime_config(config: dict[str, Any]) -> tuple[str, str]:
|
|
25
|
+
value = config.get("runtime")
|
|
26
|
+
if not isinstance(value, dict):
|
|
27
|
+
raise ManagedRuntimeError("ManagedRuntime 项目缺少 runtime 配置")
|
|
28
|
+
name = str(value.get("name") or "").strip().lower()
|
|
29
|
+
requested_version = str(value.get("version") or "").strip()
|
|
30
|
+
if not name:
|
|
31
|
+
raise ManagedRuntimeError("ManagedRuntime 项目缺少 runtime.name")
|
|
32
|
+
return name, requested_version
|
|
33
|
+
|
|
34
|
+
|
|
35
|
+
def extract_bootstrap_runtime(
|
|
36
|
+
bootstrap: dict[str, Any] | None,
|
|
37
|
+
runtime_name: str,
|
|
38
|
+
) -> ResolvedRuntime | None:
|
|
39
|
+
if not isinstance(bootstrap, dict):
|
|
40
|
+
return None
|
|
41
|
+
configs = bootstrap.get("configs") or bootstrap.get("Configs")
|
|
42
|
+
if not isinstance(configs, dict):
|
|
43
|
+
return None
|
|
44
|
+
version = str(
|
|
45
|
+
configs.get("runtime.default_version")
|
|
46
|
+
or configs.get(f"runtime.{runtime_name}.default_version")
|
|
47
|
+
or ""
|
|
48
|
+
).strip()
|
|
49
|
+
if not version:
|
|
50
|
+
return None
|
|
51
|
+
package = str(
|
|
52
|
+
configs.get("runtime.package")
|
|
53
|
+
or configs.get(f"runtime.{runtime_name}.package")
|
|
54
|
+
or ""
|
|
55
|
+
).strip()
|
|
56
|
+
return ResolvedRuntime(
|
|
57
|
+
name=runtime_name,
|
|
58
|
+
version=version,
|
|
59
|
+
source="server",
|
|
60
|
+
package_requirement=package,
|
|
61
|
+
)
|
|
62
|
+
|
|
63
|
+
|
|
64
|
+
async def resolve_managed_runtime(
|
|
65
|
+
config: dict[str, Any],
|
|
66
|
+
*,
|
|
67
|
+
region: str,
|
|
68
|
+
bootstrap: dict[str, Any] | None = None,
|
|
69
|
+
) -> ResolvedRuntime:
|
|
70
|
+
name, requested_version = runtime_config(config)
|
|
71
|
+
if requested_version:
|
|
72
|
+
return ResolvedRuntime(name=name, version=requested_version, source="manifest")
|
|
73
|
+
|
|
74
|
+
resolved = extract_bootstrap_runtime(bootstrap, name)
|
|
75
|
+
if resolved is not None:
|
|
76
|
+
return resolved
|
|
77
|
+
|
|
78
|
+
if bootstrap is None:
|
|
79
|
+
from ksadk.api.client import AgentEngineClient
|
|
80
|
+
from ksadk.version import VERSION as CLI_VERSION
|
|
81
|
+
|
|
82
|
+
try:
|
|
83
|
+
async with AgentEngineClient(region=region) as client:
|
|
84
|
+
payload = await client.get_client_bootstrap_config(
|
|
85
|
+
product="agentengine",
|
|
86
|
+
framework=name,
|
|
87
|
+
region=region,
|
|
88
|
+
client_type="cli",
|
|
89
|
+
client_version=CLI_VERSION,
|
|
90
|
+
ignore_dry_run=True,
|
|
91
|
+
)
|
|
92
|
+
except Exception as exc:
|
|
93
|
+
raise ManagedRuntimeError(
|
|
94
|
+
"无法从 AgentEngine 获取 ManagedRuntime 默认版本;"
|
|
95
|
+
"请连接服务端或在 agentengine.yaml 中显式配置 runtime.version"
|
|
96
|
+
) from exc
|
|
97
|
+
resolved = extract_bootstrap_runtime(payload, name)
|
|
98
|
+
if resolved is not None:
|
|
99
|
+
return resolved
|
|
100
|
+
|
|
101
|
+
raise ManagedRuntimeError(
|
|
102
|
+
f"AgentEngine 未下发 {name} 的默认 Runtime 版本;"
|
|
103
|
+
"请配置服务端 Runtime catalog 或显式设置 runtime.version"
|
|
104
|
+
)
|
|
105
|
+
|
|
106
|
+
|
|
107
|
+
def installed_runtime_version(runtime_name: str) -> str:
|
|
108
|
+
package_name = {"codex": "openai-codex"}.get(runtime_name, runtime_name)
|
|
109
|
+
try:
|
|
110
|
+
return package_version(package_name)
|
|
111
|
+
except PackageNotFoundError:
|
|
112
|
+
return ""
|
|
113
|
+
|
|
114
|
+
|
|
115
|
+
def validate_installed_runtime(resolved: ResolvedRuntime) -> str:
|
|
116
|
+
installed = installed_runtime_version(resolved.name)
|
|
117
|
+
if not installed:
|
|
118
|
+
raise ManagedRuntimeError(
|
|
119
|
+
f"本地缺少 {resolved.name} runtime;请安装 `pip install 'ksadk[{resolved.name}]'`"
|
|
120
|
+
)
|
|
121
|
+
if resolved.version and installed != resolved.version:
|
|
122
|
+
raise ManagedRuntimeError(
|
|
123
|
+
f"本地 {resolved.name} runtime 版本为 {installed},"
|
|
124
|
+
f"配置要求 {resolved.version};请安装匹配版本后重试"
|
|
125
|
+
)
|
|
126
|
+
validate_runtime_binary(resolved)
|
|
127
|
+
return installed
|
|
128
|
+
|
|
129
|
+
|
|
130
|
+
def validate_runtime_binary(resolved: ResolvedRuntime) -> str:
|
|
131
|
+
if resolved.name != "codex":
|
|
132
|
+
return ""
|
|
133
|
+
try:
|
|
134
|
+
from codex_cli_bin import bundled_codex_path
|
|
135
|
+
|
|
136
|
+
codex_bin = bundled_codex_path()
|
|
137
|
+
completed = subprocess.run(
|
|
138
|
+
[str(codex_bin), "--version"],
|
|
139
|
+
check=True,
|
|
140
|
+
capture_output=True,
|
|
141
|
+
text=True,
|
|
142
|
+
timeout=15,
|
|
143
|
+
)
|
|
144
|
+
except (ImportError, OSError, subprocess.SubprocessError) as exc:
|
|
145
|
+
raise ManagedRuntimeError(
|
|
146
|
+
"本地 Codex 平台二进制不可用;请重新安装 `pip install --force-reinstall "
|
|
147
|
+
"'ksadk[codex]'`"
|
|
148
|
+
) from exc
|
|
149
|
+
output = f"{completed.stdout}\n{completed.stderr}".strip()
|
|
150
|
+
if resolved.version and resolved.version not in output:
|
|
151
|
+
raise ManagedRuntimeError(
|
|
152
|
+
f"Codex CLI 版本输出为 {output or '(empty)'},配置要求 {resolved.version}"
|
|
153
|
+
)
|
|
154
|
+
return output
|
|
155
|
+
|
|
156
|
+
|
|
157
|
+
async def resolve_local_managed_runtime(
|
|
158
|
+
config: dict[str, Any],
|
|
159
|
+
*,
|
|
160
|
+
region: str,
|
|
161
|
+
) -> ResolvedRuntime:
|
|
162
|
+
"""Resolve and verify the native runtime used by ``ksadk web``."""
|
|
163
|
+
name, requested_version = runtime_config(config)
|
|
164
|
+
if requested_version:
|
|
165
|
+
resolved = ResolvedRuntime(name=name, version=requested_version, source="manifest")
|
|
166
|
+
validate_installed_runtime(resolved)
|
|
167
|
+
return resolved
|
|
168
|
+
|
|
169
|
+
try:
|
|
170
|
+
resolved = await resolve_managed_runtime(config, region=region)
|
|
171
|
+
except ManagedRuntimeError:
|
|
172
|
+
resolved = None
|
|
173
|
+
if resolved is not None:
|
|
174
|
+
validate_installed_runtime(resolved)
|
|
175
|
+
return resolved
|
|
176
|
+
|
|
177
|
+
installed = installed_runtime_version(name)
|
|
178
|
+
if not installed:
|
|
179
|
+
raise ManagedRuntimeError(
|
|
180
|
+
f"本地缺少 {name} runtime;请安装 `pip install 'ksadk[{name}]'`"
|
|
181
|
+
)
|
|
182
|
+
resolved = ResolvedRuntime(
|
|
183
|
+
name=name,
|
|
184
|
+
version=installed,
|
|
185
|
+
source="installed-unlocked",
|
|
186
|
+
)
|
|
187
|
+
validate_runtime_binary(resolved)
|
|
188
|
+
return resolved
|
ksadk/markdown.py
CHANGED
|
@@ -2,7 +2,6 @@ from __future__ import annotations
|
|
|
2
2
|
|
|
3
3
|
from typing import Any
|
|
4
4
|
|
|
5
|
-
|
|
6
5
|
_FENCE_MARKER_CHARS = ("`", "~")
|
|
7
6
|
_LIST_PREFIXES = ("- ", "* ", "+ ")
|
|
8
7
|
|
|
@@ -157,7 +156,11 @@ def _is_closing_fence(candidate: str, open_marker: str) -> bool:
|
|
|
157
156
|
|
|
158
157
|
|
|
159
158
|
def _is_table_line(stripped_line: str) -> bool:
|
|
160
|
-
return
|
|
159
|
+
return (
|
|
160
|
+
stripped_line.startswith("|")
|
|
161
|
+
and stripped_line.endswith("|")
|
|
162
|
+
and stripped_line.count("|") >= 2
|
|
163
|
+
)
|
|
161
164
|
|
|
162
165
|
|
|
163
166
|
def _is_list_line(stripped_line: str) -> bool:
|
ksadk/mcp_runtime/__init__.py
CHANGED
|
@@ -1,18 +1,19 @@
|
|
|
1
1
|
from __future__ import annotations
|
|
2
2
|
|
|
3
|
+
import inspect
|
|
3
4
|
import json
|
|
4
5
|
import os
|
|
5
|
-
import inspect
|
|
6
6
|
from dataclasses import dataclass
|
|
7
|
-
from typing import Any, Sequence
|
|
7
|
+
from typing import Any, Coroutine, Sequence, cast
|
|
8
8
|
from urllib.parse import urlparse
|
|
9
9
|
|
|
10
10
|
import httpx
|
|
11
|
-
|
|
11
|
+
|
|
12
|
+
from ksadk.compat.adk_compat import (
|
|
12
13
|
CheckableMcpHttpClientFactory,
|
|
14
|
+
McpToolset,
|
|
13
15
|
StreamableHTTPConnectionParams,
|
|
14
16
|
)
|
|
15
|
-
from google.adk.tools.mcp_tool.mcp_toolset import McpToolset
|
|
16
17
|
|
|
17
18
|
MCP_TOOLSET_KEY_ATTR = "_ksadk_mcp_toolset_key"
|
|
18
19
|
|
|
@@ -64,7 +65,9 @@ def build_connection_params(
|
|
|
64
65
|
httpx_client_factory: CheckableMcpHttpClientFactory | None = None,
|
|
65
66
|
) -> StreamableHTTPConnectionParams:
|
|
66
67
|
kwargs: dict[str, Any] = {"url": config.url, "headers": config.headers}
|
|
67
|
-
kwargs["httpx_client_factory"] = httpx_client_factory or _default_httpx_client_factory(
|
|
68
|
+
kwargs["httpx_client_factory"] = httpx_client_factory or _default_httpx_client_factory(
|
|
69
|
+
config.url
|
|
70
|
+
)
|
|
68
71
|
return StreamableHTTPConnectionParams(**kwargs)
|
|
69
72
|
|
|
70
73
|
|
|
@@ -146,7 +149,7 @@ def _mcp_toolset_tools_sync(toolset: Any) -> list[Any]:
|
|
|
146
149
|
try:
|
|
147
150
|
asyncio.get_running_loop()
|
|
148
151
|
except RuntimeError:
|
|
149
|
-
result = asyncio.run(result)
|
|
152
|
+
result = asyncio.run(cast(Coroutine[Any, Any, Any], result))
|
|
150
153
|
else:
|
|
151
154
|
close = getattr(result, "close", None)
|
|
152
155
|
if callable(close):
|
ksadk/memory/__init__.py
CHANGED
|
@@ -13,9 +13,9 @@
|
|
|
13
13
|
|
|
14
14
|
from typing import TYPE_CHECKING
|
|
15
15
|
|
|
16
|
-
from ksadk.memory.manager import MemoryManager, get_memory_manager
|
|
17
16
|
from ksadk.memory.backends.base import BaseMemoryBackend
|
|
18
17
|
from ksadk.memory.backends.memory import InMemoryBackend
|
|
18
|
+
from ksadk.memory.manager import MemoryManager, get_memory_manager
|
|
19
19
|
|
|
20
20
|
if TYPE_CHECKING:
|
|
21
21
|
from ksadk.memory.service import LongTermMemoryService
|
ksadk/memory/adk/__init__.py
CHANGED
|
@@ -39,10 +39,12 @@ if TYPE_CHECKING:
|
|
|
39
39
|
def __getattr__(name):
|
|
40
40
|
if name == "ShortTermMemory":
|
|
41
41
|
from ksadk.memory.adk.short_term_memory import ShortTermMemory
|
|
42
|
+
|
|
42
43
|
return ShortTermMemory
|
|
43
44
|
|
|
44
45
|
if name == "LongTermMemory":
|
|
45
46
|
from ksadk.memory.adk.long_term_memory import LongTermMemory
|
|
47
|
+
|
|
46
48
|
return LongTermMemory
|
|
47
49
|
|
|
48
50
|
raise AttributeError(f"module 'ksadk.memory.adk' has no attribute '{name}'")
|
|
@@ -21,9 +21,7 @@ class BaseLongTermMemoryBackend(ABC, BaseModel):
|
|
|
21
21
|
index: str = ""
|
|
22
22
|
|
|
23
23
|
@abstractmethod
|
|
24
|
-
def save_memory(
|
|
25
|
-
self, user_id: str, event_strings: List[str], **kwargs
|
|
26
|
-
) -> bool:
|
|
24
|
+
def save_memory(self, user_id: str, event_strings: List[str], **kwargs) -> bool:
|
|
27
25
|
"""保存记忆
|
|
28
26
|
|
|
29
27
|
Args:
|
|
@@ -36,9 +34,7 @@ class BaseLongTermMemoryBackend(ABC, BaseModel):
|
|
|
36
34
|
pass
|
|
37
35
|
|
|
38
36
|
@abstractmethod
|
|
39
|
-
def search_memory(
|
|
40
|
-
self, user_id: str, query: str, top_k: int = 5, **kwargs
|
|
41
|
-
) -> List[str]:
|
|
37
|
+
def search_memory(self, user_id: str, query: str, top_k: int = 5, **kwargs) -> List[str]:
|
|
42
38
|
"""检索记忆
|
|
43
39
|
|
|
44
40
|
Args:
|
|
@@ -12,7 +12,7 @@ import logging
|
|
|
12
12
|
from typing import List, Optional
|
|
13
13
|
|
|
14
14
|
import httpx
|
|
15
|
-
from pydantic import ConfigDict
|
|
15
|
+
from pydantic import ConfigDict
|
|
16
16
|
|
|
17
17
|
from ksadk.memory.adk.backends.base_ltm_backend import BaseLongTermMemoryBackend
|
|
18
18
|
|
|
@@ -52,12 +52,10 @@ class HttpLTMBackend(BaseLongTermMemoryBackend):
|
|
|
52
52
|
def model_post_init(self, __context) -> None:
|
|
53
53
|
if not self.base_url:
|
|
54
54
|
logger.warning(
|
|
55
|
-
"HttpLTMBackend: base_url is empty. "
|
|
56
|
-
"Set KSADK_LTM_HTTP_URL environment variable."
|
|
55
|
+
"HttpLTMBackend: base_url is empty. " "Set KSADK_LTM_HTTP_URL environment variable."
|
|
57
56
|
)
|
|
58
57
|
logger.info(
|
|
59
|
-
f"HttpLTMBackend initialized: base_url={self.base_url[:50]}... "
|
|
60
|
-
f"index={self.index}"
|
|
58
|
+
f"HttpLTMBackend initialized: base_url={self.base_url[:50]}... " f"index={self.index}"
|
|
61
59
|
)
|
|
62
60
|
|
|
63
61
|
@property
|
|
@@ -75,9 +73,7 @@ class HttpLTMBackend(BaseLongTermMemoryBackend):
|
|
|
75
73
|
)
|
|
76
74
|
return self._client
|
|
77
75
|
|
|
78
|
-
def save_memory(
|
|
79
|
-
self, user_id: str, event_strings: List[str], **kwargs
|
|
80
|
-
) -> bool:
|
|
76
|
+
def save_memory(self, user_id: str, event_strings: List[str], **kwargs) -> bool:
|
|
81
77
|
"""保存记忆到远程服务
|
|
82
78
|
|
|
83
79
|
TODO: 对接金山云记忆服务 API
|
|
@@ -105,24 +101,20 @@ class HttpLTMBackend(BaseLongTermMemoryBackend):
|
|
|
105
101
|
response.raise_for_status()
|
|
106
102
|
|
|
107
103
|
logger.info(
|
|
108
|
-
f"Saved {len(event_strings)} events to remote memory service "
|
|
109
|
-
f"for user={user_id}"
|
|
104
|
+
f"Saved {len(event_strings)} events to remote memory service " f"for user={user_id}"
|
|
110
105
|
)
|
|
111
106
|
return True
|
|
112
107
|
|
|
113
108
|
except httpx.HTTPStatusError as e:
|
|
114
109
|
logger.error(
|
|
115
|
-
f"HTTP error saving memory: {e.response.status_code} "
|
|
116
|
-
f"{e.response.text[:200]}"
|
|
110
|
+
f"HTTP error saving memory: {e.response.status_code} " f"{e.response.text[:200]}"
|
|
117
111
|
)
|
|
118
112
|
return False
|
|
119
113
|
except Exception as e:
|
|
120
114
|
logger.error(f"Error saving memory to remote service: {e}")
|
|
121
115
|
return False
|
|
122
116
|
|
|
123
|
-
def search_memory(
|
|
124
|
-
self, user_id: str, query: str, top_k: int = 5, **kwargs
|
|
125
|
-
) -> List[str]:
|
|
117
|
+
def search_memory(self, user_id: str, query: str, top_k: int = 5, **kwargs) -> List[str]:
|
|
126
118
|
"""从远程服务检索记忆
|
|
127
119
|
|
|
128
120
|
TODO: 对接金山云记忆服务 API
|
|
@@ -140,9 +132,7 @@ class HttpLTMBackend(BaseLongTermMemoryBackend):
|
|
|
140
132
|
}
|
|
141
133
|
"""
|
|
142
134
|
if not self.base_url:
|
|
143
|
-
logger.warning(
|
|
144
|
-
"HttpLTMBackend: base_url not configured, return empty results."
|
|
145
|
-
)
|
|
135
|
+
logger.warning("HttpLTMBackend: base_url not configured, return empty results.")
|
|
146
136
|
return []
|
|
147
137
|
|
|
148
138
|
try:
|
|
@@ -158,7 +148,10 @@ class HttpLTMBackend(BaseLongTermMemoryBackend):
|
|
|
158
148
|
response.raise_for_status()
|
|
159
149
|
|
|
160
150
|
data = response.json()
|
|
161
|
-
|
|
151
|
+
raw_memories = data.get("memories", [])
|
|
152
|
+
memories = (
|
|
153
|
+
[str(memory) for memory in raw_memories] if isinstance(raw_memories, list) else []
|
|
154
|
+
)
|
|
162
155
|
|
|
163
156
|
logger.info(
|
|
164
157
|
f"Retrieved {len(memories)} memories from remote service "
|
|
@@ -168,8 +161,7 @@ class HttpLTMBackend(BaseLongTermMemoryBackend):
|
|
|
168
161
|
|
|
169
162
|
except httpx.HTTPStatusError as e:
|
|
170
163
|
logger.error(
|
|
171
|
-
f"HTTP error searching memory: {e.response.status_code} "
|
|
172
|
-
f"{e.response.text[:200]}"
|
|
164
|
+
f"HTTP error searching memory: {e.response.status_code} " f"{e.response.text[:200]}"
|
|
173
165
|
)
|
|
174
166
|
return []
|
|
175
167
|
except Exception as e:
|
|
@@ -8,6 +8,8 @@ import logging
|
|
|
8
8
|
from collections import defaultdict
|
|
9
9
|
from typing import List
|
|
10
10
|
|
|
11
|
+
from pydantic import PrivateAttr
|
|
12
|
+
|
|
11
13
|
from ksadk.memory.adk.backends.base_ltm_backend import BaseLongTermMemoryBackend
|
|
12
14
|
|
|
13
15
|
logger = logging.getLogger(__name__)
|
|
@@ -27,19 +29,13 @@ class InMemoryLTMBackend(BaseLongTermMemoryBackend):
|
|
|
27
29
|
```
|
|
28
30
|
"""
|
|
29
31
|
|
|
30
|
-
|
|
31
|
-
_storage: dict = None
|
|
32
|
+
_storage: defaultdict[str, list[str]] = PrivateAttr(default_factory=lambda: defaultdict(list))
|
|
32
33
|
|
|
33
34
|
def model_post_init(self, __context) -> None:
|
|
34
35
|
# {user_id: [event_string, ...]}
|
|
35
|
-
|
|
36
|
-
logger.info(
|
|
37
|
-
f"InMemoryLTMBackend initialized: index={self.index}"
|
|
38
|
-
)
|
|
36
|
+
logger.info(f"InMemoryLTMBackend initialized: index={self.index}")
|
|
39
37
|
|
|
40
|
-
def save_memory(
|
|
41
|
-
self, user_id: str, event_strings: List[str], **kwargs
|
|
42
|
-
) -> bool:
|
|
38
|
+
def save_memory(self, user_id: str, event_strings: List[str], **kwargs) -> bool:
|
|
43
39
|
"""保存记忆到内存"""
|
|
44
40
|
if not event_strings:
|
|
45
41
|
return True
|
|
@@ -51,9 +47,7 @@ class InMemoryLTMBackend(BaseLongTermMemoryBackend):
|
|
|
51
47
|
)
|
|
52
48
|
return True
|
|
53
49
|
|
|
54
|
-
def search_memory(
|
|
55
|
-
self, user_id: str, query: str, top_k: int = 5, **kwargs
|
|
56
|
-
) -> List[str]:
|
|
50
|
+
def search_memory(self, user_id: str, query: str, top_k: int = 5, **kwargs) -> List[str]:
|
|
57
51
|
"""基于关键词匹配检索记忆
|
|
58
52
|
|
|
59
53
|
简单实现:对 query 分词后,按匹配关键词数量排序。
|
|
@@ -68,7 +62,7 @@ class InMemoryLTMBackend(BaseLongTermMemoryBackend):
|
|
|
68
62
|
# 按字符分词(支持中英文混合)
|
|
69
63
|
query_terms = query_lower.split()
|
|
70
64
|
|
|
71
|
-
scored = []
|
|
65
|
+
scored: list[tuple[int, str]] = []
|
|
72
66
|
for memory in user_memories:
|
|
73
67
|
memory_lower = memory.lower()
|
|
74
68
|
# 计算匹配分数:完整 query 匹配得高分,部分关键词匹配得低分
|
|
@@ -105,9 +105,13 @@ class SdkLTMBackend(BaseLongTermMemoryBackend):
|
|
|
105
105
|
return self._aicp_client
|
|
106
106
|
|
|
107
107
|
try:
|
|
108
|
-
from ksyun.common import credential
|
|
109
|
-
from ksyun.common.profile.client_profile import
|
|
110
|
-
|
|
108
|
+
from ksyun.common import credential # type: ignore[import-untyped]
|
|
109
|
+
from ksyun.common.profile.client_profile import ( # type: ignore[import-untyped]
|
|
110
|
+
ClientProfile,
|
|
111
|
+
)
|
|
112
|
+
from ksyun.common.profile.http_profile import ( # type: ignore[import-untyped]
|
|
113
|
+
HttpProfile,
|
|
114
|
+
)
|
|
111
115
|
except ImportError:
|
|
112
116
|
raise ImportError(
|
|
113
117
|
"kingsoftcloud-sdk-python is required for SDK memory backend. "
|
|
@@ -144,9 +148,7 @@ class SdkLTMBackend(BaseLongTermMemoryBackend):
|
|
|
144
148
|
client_profile = ClientProfile()
|
|
145
149
|
client_profile.httpProfile = http_profile
|
|
146
150
|
|
|
147
|
-
self._aicp_client = aicp_module.AicpClient(
|
|
148
|
-
cred, self.region, profile=client_profile
|
|
149
|
-
)
|
|
151
|
+
self._aicp_client = aicp_module.AicpClient(cred, self.region, profile=client_profile)
|
|
150
152
|
|
|
151
153
|
# 强制覆写 API 版本为记忆库 API 所需的 2025-11-14
|
|
152
154
|
self._aicp_client._apiVersion = "2025-11-14"
|
|
@@ -181,12 +183,14 @@ class SdkLTMBackend(BaseLongTermMemoryBackend):
|
|
|
181
183
|
if not text:
|
|
182
184
|
continue
|
|
183
185
|
|
|
184
|
-
conversation.append(
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
|
|
189
|
-
|
|
186
|
+
conversation.append(
|
|
187
|
+
{
|
|
188
|
+
"Role": role,
|
|
189
|
+
"CreatedAt": int(time.time() * 1000),
|
|
190
|
+
"MessageId": str(uuid.uuid4()),
|
|
191
|
+
"Content": [{"Type": "input_text", "Text": text}],
|
|
192
|
+
}
|
|
193
|
+
)
|
|
190
194
|
return conversation
|
|
191
195
|
|
|
192
196
|
def _effective_memory_collection_id(self) -> str:
|
|
@@ -195,9 +199,7 @@ class SdkLTMBackend(BaseLongTermMemoryBackend):
|
|
|
195
199
|
def _effective_scene_id(self) -> str:
|
|
196
200
|
return self.scene_id or DEFAULT_SCENE_ID
|
|
197
201
|
|
|
198
|
-
def save_memory(
|
|
199
|
-
self, user_id: str, event_strings: list[str], **kwargs
|
|
200
|
-
) -> bool:
|
|
202
|
+
def save_memory(self, user_id: str, event_strings: list[str], **kwargs) -> bool:
|
|
201
203
|
"""调用 CreateMemorySdk 写入记忆
|
|
202
204
|
|
|
203
205
|
Args:
|
|
@@ -221,7 +223,10 @@ class SdkLTMBackend(BaseLongTermMemoryBackend):
|
|
|
221
223
|
logger.info("No valid conversation items to save")
|
|
222
224
|
return True
|
|
223
225
|
|
|
224
|
-
|
|
226
|
+
metadata_value = kwargs.get("metadata")
|
|
227
|
+
metadata: dict[str, Any] = (
|
|
228
|
+
dict(metadata_value) if isinstance(metadata_value, dict) else {}
|
|
229
|
+
)
|
|
225
230
|
agent_id = metadata.get("agent_id") or self.agent_id
|
|
226
231
|
session_id = metadata.get("session_id") or kwargs.get("session_id")
|
|
227
232
|
params = {
|
|
@@ -241,9 +246,7 @@ class SdkLTMBackend(BaseLongTermMemoryBackend):
|
|
|
241
246
|
f"user_id={user_id}, messages={len(conversation)}"
|
|
242
247
|
)
|
|
243
248
|
|
|
244
|
-
response = client.call(
|
|
245
|
-
"CreateMemorySdk", params, options={"IsPostJson": True}
|
|
246
|
-
)
|
|
249
|
+
response = client.call("CreateMemorySdk", params, options={"IsPostJson": True})
|
|
247
250
|
self.last_create_response = self._parse_json_response(response) or {}
|
|
248
251
|
self.last_session_status = {
|
|
249
252
|
"SessionId": session_id,
|
|
@@ -252,8 +255,7 @@ class SdkLTMBackend(BaseLongTermMemoryBackend):
|
|
|
252
255
|
}
|
|
253
256
|
|
|
254
257
|
logger.info(
|
|
255
|
-
f"Saved {len(conversation)} messages to AICP memory service "
|
|
256
|
-
f"for user={user_id}"
|
|
258
|
+
f"Saved {len(conversation)} messages to AICP memory service " f"for user={user_id}"
|
|
257
259
|
)
|
|
258
260
|
return True
|
|
259
261
|
|
|
@@ -262,9 +264,7 @@ class SdkLTMBackend(BaseLongTermMemoryBackend):
|
|
|
262
264
|
logger.error(f"CreateMemorySdk failed: {e}")
|
|
263
265
|
return False
|
|
264
266
|
|
|
265
|
-
def search_memory(
|
|
266
|
-
self, user_id: str, query: str, top_k: int = 5, **kwargs
|
|
267
|
-
) -> list[str]:
|
|
267
|
+
def search_memory(self, user_id: str, query: str, top_k: int = 5, **kwargs) -> list[str]:
|
|
268
268
|
"""调用 QueryMemorySdk 检索记忆
|
|
269
269
|
|
|
270
270
|
Args:
|
|
@@ -306,9 +306,7 @@ class SdkLTMBackend(BaseLongTermMemoryBackend):
|
|
|
306
306
|
f"user_id={user_id}, query='{query[:50]}'"
|
|
307
307
|
)
|
|
308
308
|
|
|
309
|
-
response = client.call(
|
|
310
|
-
"QueryMemorySdk", params, options={"IsPostJson": True}
|
|
311
|
-
)
|
|
309
|
+
response = client.call("QueryMemorySdk", params, options={"IsPostJson": True})
|
|
312
310
|
|
|
313
311
|
# 解析响应
|
|
314
312
|
memories = self._parse_query_response(response)
|
|
@@ -443,12 +441,7 @@ class SdkLTMBackend(BaseLongTermMemoryBackend):
|
|
|
443
441
|
parsed.extend(self._parse_memory_item(memory))
|
|
444
442
|
return parsed
|
|
445
443
|
|
|
446
|
-
text = (
|
|
447
|
-
item.get("Content")
|
|
448
|
-
or item.get("Text")
|
|
449
|
-
or item.get("Memory")
|
|
450
|
-
or item.get("Data")
|
|
451
|
-
)
|
|
444
|
+
text = item.get("Content") or item.get("Text") or item.get("Memory") or item.get("Data")
|
|
452
445
|
if text is None:
|
|
453
446
|
return []
|
|
454
447
|
if isinstance(text, (dict, list)):
|