agentengine-sdk-python 0.7.0__py3-none-any.whl → 0.8.1__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.1.dist-info}/METADATA +52 -20
- agentengine_sdk_python-0.8.1.dist-info/RECORD +644 -0
- {agentengine_sdk_python-0.7.0.dist-info → agentengine_sdk_python-0.8.1.dist-info}/WHEEL +1 -1
- ksadk/a2a/__init__.py +180 -11
- ksadk/a2a/bootstrap.py +332 -0
- ksadk/a2a/card.py +15 -0
- ksadk/a2a/context_store.py +203 -0
- ksadk/a2a/control_plane.py +1056 -0
- ksadk/a2a/credential.py +99 -0
- ksadk/a2a/event_adapter.py +149 -0
- ksadk/a2a/executor.py +361 -137
- 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 +112 -0
- ksadk/a2a/server.py +102 -62
- ksadk/a2a/service_env.py +33 -0
- ksadk/a2a/space_client.py +1122 -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/a2a_card.py +101 -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 +872 -0
- ksadk/agui/config.py +92 -0
- ksadk/agui/routes.py +47 -0
- ksadk/api/client.py +238 -204
- ksadk/api/environment.py +27 -0
- ksadk/builders/__init__.py +2 -0
- ksadk/builders/base.py +16 -14
- ksadk/builders/code_builder.py +375 -270
- ksadk/builders/container_builder.py +240 -200
- ksadk/builders/framework_requirements.py +31 -12
- ksadk/builders/ks3_uploader.py +60 -29
- ksadk/builders/managed_runtime_builder.py +173 -0
- ksadk/builders/mcp_builder.py +91 -92
- ksadk/builders/requirements_utils.py +1 -5
- ksadk/cli/__init__.py +97 -171
- ksadk/cli/cmd_a2a.py +255 -84
- 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 +507 -740
- ksadk/cli/cmd_dashboard.py +120 -45
- ksadk/cli/cmd_deploy.py +135 -59
- ksadk/cli/cmd_destroy.py +44 -14
- ksadk/cli/cmd_eval.py +386 -0
- ksadk/cli/cmd_files.py +63 -24
- ksadk/cli/cmd_hermes.py +313 -135
- ksadk/cli/cmd_invoke.py +184 -122
- ksadk/cli/cmd_launch.py +76 -28
- ksadk/cli/cmd_mcp.py +98 -64
- ksadk/cli/cmd_model.py +14 -5
- ksadk/cli/cmd_openclaw.py +564 -268
- ksadk/cli/cmd_replay.py +71 -0
- ksadk/cli/cmd_run.py +58 -73
- ksadk/cli/cmd_status.py +80 -31
- ksadk/cli/cmd_studio.py +110 -0
- ksadk/cli/cmd_version.py +20 -13
- ksadk/cli/cmd_web.py +95 -18
- ksadk/cli/deploy_utils.py +20 -20
- ksadk/cli/dry_run.py +7 -4
- ksadk/cli/env_options.py +83 -0
- ksadk/cli/error_utils.py +37 -12
- ksadk/cli/global_options.py +4 -3
- ksadk/cli/local_runtime.py +1 -2
- ksadk/cli/model_catalog.py +6 -2
- ksadk/cli/network_options.py +41 -19
- ksadk/cli/resource_common.py +6 -2
- ksadk/cli/runtime_bootstrap.py +51 -0
- ksadk/cli/storage.py +0 -1
- ksadk/cli/ui.py +11 -3
- ksadk/cli/workflow_common.py +52 -18
- ksadk/codex/__init__.py +12 -0
- ksadk/codex/client.py +1042 -0
- ksadk/codex/phase.py +143 -0
- ksadk/codex/runtime.py +940 -0
- ksadk/common/aicp_env.py +0 -1
- ksadk/common/auth.py +2 -2
- ksadk/common/constants.py +1 -3
- ksadk/common/kop_client.py +232 -0
- 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 -14
- ksadk/configs/env_registry.py +661 -116
- ksadk/configs/global_config.py +3 -2
- ksadk/configs/settings.py +133 -209
- ksadk/conversations/__init__.py +85 -92
- 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 +660 -0
- ksadk/conversations/runtime_invocation.py +395 -0
- ksadk/conversations/runtime_metadata.py +475 -0
- ksadk/conversations/runtime_observability.py +367 -0
- ksadk/conversations/runtime_payloads.py +272 -0
- ksadk/conversations/runtime_persistence.py +440 -0
- ksadk/conversations/runtime_preparation.py +426 -0
- ksadk/conversations/runtime_resume.py +836 -0
- ksadk/conversations/runtime_stream_events.py +902 -0
- ksadk/conversations/runtime_streaming.py +700 -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/managed_runtime.py +33 -0
- ksadk/deployment/manager.py +85 -71
- ksadk/deployment/providers/serverless.py +379 -210
- 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/evaluation/__init__.py +84 -0
- ksadk/evaluation/a2a_adapter.py +444 -0
- ksadk/evaluation/adapters.py +54 -0
- ksadk/evaluation/contracts.py +409 -0
- ksadk/evaluation/evalset.py +351 -0
- ksadk/evaluation/evaluators.py +461 -0
- ksadk/evaluation/executor.py +118 -0
- ksadk/evaluation/storage.py +68 -0
- ksadk/evaluation/target.py +73 -0
- ksadk/events/__init__.py +25 -0
- ksadk/events/parser.py +191 -0
- ksadk/events/replay.py +37 -0
- ksadk/events/runtime_event.py +273 -0
- ksadk/events/store.py +317 -0
- ksadk/harness/__init__.py +35 -0
- ksadk/harness/app.py +269 -0
- ksadk/harness/config.py +181 -0
- ksadk/harness/reasoner.py +105 -0
- ksadk/harness/runtime.py +364 -0
- ksadk/harness/sandbox.py +141 -0
- ksadk/harness/tools.py +222 -0
- ksadk/hermes_terminal.py +28 -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 +38 -33
- ksadk/managed_a2a_card.py +160 -0
- ksadk/managed_runtime.py +195 -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 +36 -36
- ksadk/memory/adk/long_term_memory.py +34 -37
- 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 +16 -6
- ksadk/memory/tool.py +4 -0
- 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 +66 -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 +201 -0
- ksadk/model_proxy/protocol_proxy.py +22 -0
- ksadk/model_proxy/server.py +443 -0
- ksadk/model_proxy/transform.py +735 -0
- ksadk/openclaw_gateway.py +29 -14
- ksadk/runners/adk_runner.py +354 -146
- ksadk/runners/base_runner.py +71 -29
- ksadk/runners/deepagents_runner.py +0 -1
- ksadk/runners/factory.py +18 -5
- ksadk/runners/langchain_runner.py +29 -742
- ksadk/runners/langgraph_runner.py +417 -97
- ksadk/runners/patch_langchain.py +16 -16
- ksadk/runners/remote_runner.py +134 -33
- ksadk/runners/usage_accumulator.py +1 -0
- ksadk/runners/utils/__init__.py +0 -10
- ksadk/runners/utils/loader.py +23 -7
- ksadk/runtime/__init__.py +67 -0
- ksadk/runtime/adapter.py +412 -0
- ksadk/runtime/conversation_execution.py +553 -0
- ksadk/runtime/executor.py +251 -0
- ksadk/runtime/factory.py +156 -0
- ksadk/runtime/framework_adapters.py +118 -0
- ksadk/runtime/launch.py +48 -0
- ksadk/runtime/preprocessing.py +131 -0
- ksadk/runtime/runner_adapter.py +1032 -0
- ksadk/runtime/runner_loading.py +36 -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/__init__.py +39 -4
- ksadk/server/api_models.py +15 -5
- ksadk/server/app.py +24 -3928
- ksadk/server/composition.py +47 -0
- ksadk/server/factory.py +622 -0
- ksadk/server/routes/__init__.py +1 -0
- ksadk/server/routes/checkpoint_resolution.py +116 -0
- ksadk/server/routes/common.py +682 -0
- ksadk/server/routes/control.py +331 -0
- ksadk/server/routes/dependencies.py +98 -0
- ksadk/server/routes/misc.py +425 -0
- ksadk/server/routes/models.py +451 -0
- ksadk/server/routes/openai_compat.py +229 -0
- ksadk/server/routes/projection.py +848 -0
- ksadk/server/routes/routers.py +52 -0
- ksadk/server/routes/run.py +519 -0
- ksadk/server/routes/sessions.py +644 -0
- ksadk/server/routes/streaming.py +265 -0
- ksadk/server/routes/workspace.py +414 -0
- ksadk/server/static/assets/{ArtifactsPanel-D-SSn2ee.js → ArtifactsPanel-CakCqxEN.js} +1 -1
- ksadk/server/static/assets/CodeBlock-CynLknyO.js +9 -0
- ksadk/server/static/assets/MathMessageMarkdown-3sQdOysS.js +8 -0
- ksadk/server/static/assets/MermaidBlock-NERD_ef7.js +303 -0
- ksadk/server/static/assets/NativeTerminalPanel-CiHWf82q.js +1 -0
- ksadk/server/static/assets/{arc-BA13sHc9.js → arc-DrgjcKhl.js} +1 -1
- ksadk/server/static/assets/architecture-7EHR7CIX-CpZLRCcY.js +1 -0
- ksadk/server/static/assets/{architectureDiagram-3BPJPVTR-DzJzgVoL.js → architectureDiagram-3BPJPVTR-BXoVRbQ6.js} +1 -1
- ksadk/server/static/assets/{blockDiagram-GPEHLZMM-UTdVcZhn.js → blockDiagram-GPEHLZMM-BnaB3Ywv.js} +1 -1
- ksadk/server/static/assets/{c4Diagram-AAUBKEIU-Dix0GD4m.js → c4Diagram-AAUBKEIU-Dw4weZcp.js} +1 -1
- ksadk/server/static/assets/channel-Dt3rQTFI.js +1 -0
- ksadk/server/static/assets/{chunk-2J33WTMH-C2JxuZ42.js → chunk-2J33WTMH-ChjpLK7j.js} +1 -1
- ksadk/server/static/assets/{chunk-4BX2VUAB-Be57QPgD.js → chunk-4BX2VUAB-B9drTgOW.js} +1 -1
- ksadk/server/static/assets/{chunk-55IACEB6-WjSuy4nv.js → chunk-55IACEB6-CK4ROATy.js} +1 -1
- ksadk/server/static/assets/{chunk-727SXJPM-BOovP-b5.js → chunk-727SXJPM-B9KtTTgw.js} +1 -1
- ksadk/server/static/assets/{chunk-AQP2D5EJ-DOmZNmWj.js → chunk-AQP2D5EJ-1O1mki3m.js} +1 -1
- ksadk/server/static/assets/{chunk-FMBD7UC4-DzwlodkU.js → chunk-FMBD7UC4-B_fH2YuH.js} +1 -1
- ksadk/server/static/assets/{chunk-ND2GUHAM-DMqAikEU.js → chunk-ND2GUHAM-D6rFLaVV.js} +1 -1
- ksadk/server/static/assets/chunk-QZHKN3VN-iXEZtKQc.js +1 -0
- ksadk/server/static/assets/classDiagram-4FO5ZUOK-DIveV17Q.js +1 -0
- ksadk/server/static/assets/classDiagram-v2-Q7XG4LA2-DIveV17Q.js +1 -0
- ksadk/server/static/assets/{cose-bilkent-S5V4N54A-Zhy2GBnP.js → cose-bilkent-S5V4N54A-ChNs_Mdk.js} +1 -1
- ksadk/server/static/assets/{dagre-BM42HDAG-CbKrtIUz.js → dagre-BM42HDAG-D0QXg_MQ.js} +1 -1
- ksadk/server/static/assets/{diagram-2AECGRRQ-BRApgQRK.js → diagram-2AECGRRQ-DBDDKwBQ.js} +1 -1
- ksadk/server/static/assets/{diagram-5GNKFQAL-D0xbnDiK.js → diagram-5GNKFQAL-BkwDOxmO.js} +1 -1
- ksadk/server/static/assets/{diagram-KO2AKTUF-CVugVI9L.js → diagram-KO2AKTUF-Bv8waYvY.js} +1 -1
- ksadk/server/static/assets/{diagram-LMA3HP47-DozUGgee.js → diagram-LMA3HP47-e1VECDdu.js} +1 -1
- ksadk/server/static/assets/{diagram-OG6HWLK6-ZOYsKlru.js → diagram-OG6HWLK6-Ds9adfRl.js} +1 -1
- ksadk/server/static/assets/{dist-DpKtt4Bo.js → dist-4N2NMVYg.js} +1 -1
- ksadk/server/static/assets/{dist-CkEKJFtk.js → dist-B-jNR6Vn.js} +1 -1
- ksadk/server/static/assets/{dist-D57wnGWd.js → dist-B5J2uhNk.js} +1 -1
- ksadk/server/static/assets/{dist-8_SfK1IP.js → dist-B5oS1zcj.js} +1 -1
- ksadk/server/static/assets/{dist-DMezvBGJ.js → dist-BB3-OwTQ.js} +1 -1
- ksadk/server/static/assets/{dist-2hInLS_J.js → dist-BIlKoW0k.js} +1 -1
- ksadk/server/static/assets/{dist-BrCcQ47T.js → dist-BjOdlDjj.js} +1 -1
- ksadk/server/static/assets/{dist-BmlMPsCc.js → dist-C1sz5Eo3.js} +1 -1
- ksadk/server/static/assets/{dist-B0NP_Z0z.js → dist-CWV4lDr1.js} +1 -1
- ksadk/server/static/assets/{dist-D-xOD048.js → dist-CmZHzlwZ.js} +1 -1
- ksadk/server/static/assets/{dist-DL_NKc_z.js → dist-D6MpCZtz.js} +1 -1
- ksadk/server/static/assets/{dist-DyOkZmze.js → dist-DJN_6Y39.js} +1 -1
- ksadk/server/static/assets/{dist-DmFaq_Iy.js → dist-DQU9EWw-.js} +1 -1
- ksadk/server/static/assets/{dist-gX6GOLKq.js → dist-DWKByxWV.js} +1 -1
- ksadk/server/static/assets/{dist-DyWsb78Q.js → dist-Dli7qW-B.js} +1 -1
- ksadk/server/static/assets/{dist-BIJVDMuB.js → dist-DsHPdk3W.js} +1 -1
- ksadk/server/static/assets/{dist-Dp0k7bWI.js → dist-X4TnqwOK.js} +1 -1
- ksadk/server/static/assets/{dist-8EEyGgDx.js → dist-_pHPTyZ-.js} +1 -1
- ksadk/server/static/assets/{dist-CPBtqRTW.js → dist-fhOuWds5.js} +1 -1
- ksadk/server/static/assets/{dist-D-JMdWPQ.js → dist-gLnrGsoU.js} +1 -1
- ksadk/server/static/assets/{dist-BssVmjIo.js → dist-j6Dxmf_j.js} +1 -1
- ksadk/server/static/assets/{dist-C3HIIaN5.js → dist-o2OVmKvt.js} +1 -1
- ksadk/server/static/assets/{erDiagram-TEJ5UH35-Bk-9bgE5.js → erDiagram-TEJ5UH35-BPItFKH6.js} +1 -1
- ksadk/server/static/assets/eventmodeling-FCH6USID-DYFSxbqr.js +1 -0
- ksadk/server/static/assets/{flowDiagram-I6XJVG4X-Dn9kZVuZ.js → flowDiagram-I6XJVG4X-BbYB9w5Y.js} +1 -1
- ksadk/server/static/assets/{ganttDiagram-6RSMTGT7-BGxXlJqm.js → ganttDiagram-6RSMTGT7-TQXa0KXv.js} +1 -1
- ksadk/server/static/assets/gitGraph-WXDBUCRP-DyNYp6BN.js +1 -0
- ksadk/server/static/assets/{gitGraphDiagram-PVQCEYII-C7Q0X-wi.js → gitGraphDiagram-PVQCEYII-bKblCnpa.js} +1 -1
- ksadk/server/static/assets/index-R52pJJvg.js +177 -0
- ksadk/server/static/assets/index-jJr3_955.css +2 -0
- ksadk/server/static/assets/info-J43DQDTF-WUx7qTde.js +1 -0
- ksadk/server/static/assets/{infoDiagram-5YYISTIA-BO_CSqq5.js → infoDiagram-5YYISTIA-BGVT7J_i.js} +1 -1
- ksadk/server/static/assets/{ishikawaDiagram-YF4QCWOH-eYLPLd46.js → ishikawaDiagram-YF4QCWOH-K0OOfVna.js} +1 -1
- ksadk/server/static/assets/{journeyDiagram-JHISSGLW-De9geSb0.js → journeyDiagram-JHISSGLW-8LeOJaZp.js} +1 -1
- ksadk/server/static/assets/{kanban-definition-UN3LZRKU-Cs80kQto.js → kanban-definition-UN3LZRKU-C6uCgZrW.js} +1 -1
- ksadk/server/static/assets/{katex-DSrCFD8n.js → katex-CYWseY5E.js} +1 -1
- ksadk/server/static/assets/{linear-CN9sbKTF.js → linear-hdBcYzM8.js} +1 -1
- ksadk/server/static/assets/{mermaid-parser.core-DlgSBU8l.js → mermaid-parser.core-BWrDjSZM.js} +2 -2
- ksadk/server/static/assets/{mindmap-definition-RKZ34NQL-9afz7Oug.js → mindmap-definition-RKZ34NQL-Bjy_2v4_.js} +1 -1
- ksadk/server/static/assets/packet-YPE3B663-BN13y_xl.js +1 -0
- ksadk/server/static/assets/pie-LRSECV5Y-ftSLXhhc.js +1 -0
- ksadk/server/static/assets/{pieDiagram-4H26LBE5-DPv_VstN.js → pieDiagram-4H26LBE5-GmmqNiVH.js} +1 -1
- ksadk/server/static/assets/{quadrantDiagram-W4KKPZXB-o77wZ1XK.js → quadrantDiagram-W4KKPZXB-BmkRbwCg.js} +1 -1
- ksadk/server/static/assets/radar-GUYGQ44K-jaICkIeO.js +1 -0
- ksadk/server/static/assets/{requirementDiagram-4Y6WPE33-BYVw81VC.js → requirementDiagram-4Y6WPE33-DSWFqL7c.js} +1 -1
- ksadk/server/static/assets/{sankeyDiagram-5OEKKPKP-B7nZFMKT.js → sankeyDiagram-5OEKKPKP-l6iXmU65.js} +1 -1
- ksadk/server/static/assets/{sequenceDiagram-3UESZ5HK-BGRRrFw5.js → sequenceDiagram-3UESZ5HK-Cq6UBeQB.js} +1 -1
- ksadk/server/static/assets/{stateDiagram-AJRCARHV-BUfHCoPs.js → stateDiagram-AJRCARHV-qzTQpg3Y.js} +1 -1
- ksadk/server/static/assets/stateDiagram-v2-BHNVJYJU-BYCoYGAN.js +1 -0
- ksadk/server/static/assets/{timeline-definition-PNZ67QCA-FbCTGrf9.js → timeline-definition-PNZ67QCA-DEz24vV0.js} +1 -1
- ksadk/server/static/assets/treeView-BLDUP644-Cpib_vlz.js +1 -0
- ksadk/server/static/assets/treemap-LRROVOQU-DQxfmVHK.js +1 -0
- ksadk/server/static/assets/{vennDiagram-CIIHVFJN-DWgwtPsJ.js → vennDiagram-CIIHVFJN-CMCixki2.js} +1 -1
- ksadk/server/static/assets/wardley-L42UT6IY-BQYHnnkU.js +1 -0
- ksadk/server/static/assets/{wardleyDiagram-YWT4CUSO-2x8G-tTM.js → wardleyDiagram-YWT4CUSO-CVzB8F9K.js} +1 -1
- ksadk/server/static/assets/{xychartDiagram-2RQKCTM6-Drma3AYl.js → xychartDiagram-2RQKCTM6-BFBqBLc1.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 +47 -16
- ksadk/skills/tool_defs.py +15 -10
- ksadk/studio/__init__.py +5 -0
- ksadk/studio/agent_avatar_assets.py +120 -0
- ksadk/studio/agent_lifecycle.py +51 -0
- ksadk/studio/api.py +1046 -0
- ksadk/studio/api_catalog_routes.py +324 -0
- ksadk/studio/api_contracts.py +177 -0
- ksadk/studio/api_helpers.py +132 -0
- ksadk/studio/authoring.py +524 -0
- ksadk/studio/authoring_coordinator.py +285 -0
- ksadk/studio/builder.py +320 -0
- ksadk/studio/capabilities.py +351 -0
- ksadk/studio/cloud.py +278 -0
- ksadk/studio/codex_agent_service.py +583 -0
- ksadk/studio/codex_builder.py +324 -0
- ksadk/studio/codex_manifest.py +278 -0
- ksadk/studio/codex_run.py +352 -0
- ksadk/studio/compiler.py +189 -0
- ksadk/studio/contracts.py +644 -0
- ksadk/studio/errors.py +47 -0
- ksadk/studio/evaluation.py +192 -0
- ksadk/studio/event_store.py +284 -0
- ksadk/studio/framework_run.py +114 -0
- ksadk/studio/identifiers.py +33 -0
- ksadk/studio/mcp_runtime.py +229 -0
- ksadk/studio/model_client.py +543 -0
- ksadk/studio/model_profile_service.py +214 -0
- ksadk/studio/operations.py +243 -0
- ksadk/studio/otel_trace.py +754 -0
- ksadk/studio/pagination.py +182 -0
- ksadk/studio/python_tool_inspection.py +183 -0
- ksadk/studio/repository.py +306 -0
- ksadk/studio/resource_catalog.py +1217 -0
- ksadk/studio/run_service.py +707 -0
- ksadk/studio/runtime_catalog.py +74 -0
- ksadk/studio/runtime_source.py +339 -0
- ksadk/studio/service.py +1141 -0
- ksadk/studio/shared_web.py +994 -0
- ksadk/studio/skill_discovery.py +628 -0
- ksadk/studio/static/assets/PrismRenderer-IYN-ffww.js +3 -0
- ksadk/studio/static/assets/index-CaEN0eTR.css +1 -0
- ksadk/studio/static/assets/index-DI2eY_NH.js +252 -0
- ksadk/studio/static/assets/react-vendor-BNmTiJ-I.js +9 -0
- ksadk/studio/static/assets/rolldown-runtime-hePW80VL.js +1 -0
- ksadk/studio/static/index.html +15 -0
- ksadk/studio/templates.py +630 -0
- ksadk/studio/validator.py +246 -0
- ksadk/studio/workspace.py +137 -0
- ksadk/terminal_exec_policy.py +3 -4
- ksadk/tools/gateway.py +101 -15
- ksadk/tools/result_budget.py +12 -4
- ksadk/toolsets/__init__.py +161 -37
- ksadk/toolsets/a2a.py +426 -0
- 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/__init__.py +19 -21
- ksadk/tracing/exporters/inmemory_exporter.py +62 -51
- ksadk/tracing/setup.py +135 -506
- ksadk/tracing/span_utils.py +0 -41
- 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/memory_backend/registry.py +56 -56
- ksadk_runtime_common/schemas/runtime_event_v1.json +95 -0
- ksadk_runtime_common/workspace_files/router.py +8 -2
- agentengine_sdk_python-0.7.0.dist-info/RECORD +0 -482
- ksadk/a2a/card_builder.py +0 -64
- ksadk/a2a/client.py +0 -309
- ksadk/runners/utils/langfuse.py +0 -230
- 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
- ksadk/tracing/exporters/langfuse_exporter.py +0 -445
- {agentengine_sdk_python-0.7.0.dist-info → agentengine_sdk_python-0.8.1.dist-info}/entry_points.txt +0 -0
- {agentengine_sdk_python-0.7.0.dist-info → agentengine_sdk_python-0.8.1.dist-info}/licenses/LICENSE +0 -0
- {agentengine_sdk_python-0.7.0.dist-info → agentengine_sdk_python-0.8.1.dist-info}/top_level.txt +0 -0
ksadk/memory/backends/base.py
CHANGED
|
@@ -1,29 +1,29 @@
|
|
|
1
1
|
"""Base Memory Backend - 抽象基类"""
|
|
2
2
|
|
|
3
3
|
from abc import ABC, abstractmethod
|
|
4
|
-
from typing import Any, Optional, List, Dict
|
|
5
4
|
from datetime import timedelta
|
|
5
|
+
from typing import Any, Dict, List, Optional
|
|
6
6
|
|
|
7
7
|
|
|
8
8
|
class BaseMemoryBackend(ABC):
|
|
9
9
|
"""记忆存储后端抽象基类
|
|
10
|
-
|
|
10
|
+
|
|
11
11
|
所有后端实现必须继承此类并实现以下方法。
|
|
12
12
|
"""
|
|
13
|
-
|
|
13
|
+
|
|
14
14
|
@abstractmethod
|
|
15
15
|
def get(self, key: str, session_id: Optional[str] = None) -> Optional[Any]:
|
|
16
16
|
"""获取值
|
|
17
|
-
|
|
17
|
+
|
|
18
18
|
Args:
|
|
19
19
|
key: 键名
|
|
20
20
|
session_id: 可选的会话 ID,用于隔离不同会话的数据
|
|
21
|
-
|
|
21
|
+
|
|
22
22
|
Returns:
|
|
23
23
|
存储的值,不存在返回 None
|
|
24
24
|
"""
|
|
25
25
|
pass
|
|
26
|
-
|
|
26
|
+
|
|
27
27
|
@abstractmethod
|
|
28
28
|
def set(
|
|
29
29
|
self,
|
|
@@ -33,43 +33,43 @@ class BaseMemoryBackend(ABC):
|
|
|
33
33
|
ttl: Optional[timedelta] = None,
|
|
34
34
|
) -> bool:
|
|
35
35
|
"""设置值
|
|
36
|
-
|
|
36
|
+
|
|
37
37
|
Args:
|
|
38
38
|
key: 键名
|
|
39
39
|
value: 值 (会自动序列化)
|
|
40
40
|
session_id: 可选的会话 ID
|
|
41
41
|
ttl: 可选的过期时间
|
|
42
|
-
|
|
42
|
+
|
|
43
43
|
Returns:
|
|
44
44
|
是否成功
|
|
45
45
|
"""
|
|
46
46
|
pass
|
|
47
|
-
|
|
47
|
+
|
|
48
48
|
@abstractmethod
|
|
49
49
|
def delete(self, key: str, session_id: Optional[str] = None) -> bool:
|
|
50
50
|
"""删除键
|
|
51
|
-
|
|
51
|
+
|
|
52
52
|
Args:
|
|
53
53
|
key: 键名
|
|
54
54
|
session_id: 可选的会话 ID
|
|
55
|
-
|
|
55
|
+
|
|
56
56
|
Returns:
|
|
57
57
|
是否成功
|
|
58
58
|
"""
|
|
59
59
|
pass
|
|
60
|
-
|
|
60
|
+
|
|
61
61
|
@abstractmethod
|
|
62
62
|
def exists(self, key: str, session_id: Optional[str] = None) -> bool:
|
|
63
63
|
"""检查键是否存在"""
|
|
64
64
|
pass
|
|
65
|
-
|
|
65
|
+
|
|
66
66
|
@abstractmethod
|
|
67
67
|
def clear_session(self, session_id: str) -> bool:
|
|
68
68
|
"""清除整个会话的所有数据"""
|
|
69
69
|
pass
|
|
70
|
-
|
|
70
|
+
|
|
71
71
|
# ===== 消息历史相关 (短期记忆) =====
|
|
72
|
-
|
|
72
|
+
|
|
73
73
|
@abstractmethod
|
|
74
74
|
def add_message(
|
|
75
75
|
self,
|
|
@@ -80,7 +80,7 @@ class BaseMemoryBackend(ABC):
|
|
|
80
80
|
) -> bool:
|
|
81
81
|
"""添加消息到会话历史"""
|
|
82
82
|
pass
|
|
83
|
-
|
|
83
|
+
|
|
84
84
|
@abstractmethod
|
|
85
85
|
def get_messages(
|
|
86
86
|
self,
|
|
@@ -88,16 +88,16 @@ class BaseMemoryBackend(ABC):
|
|
|
88
88
|
limit: Optional[int] = None,
|
|
89
89
|
) -> List[Dict]:
|
|
90
90
|
"""获取会话消息历史
|
|
91
|
-
|
|
91
|
+
|
|
92
92
|
Args:
|
|
93
93
|
session_id: 会话 ID
|
|
94
94
|
limit: 最近 N 条消息,None 表示全部
|
|
95
|
-
|
|
95
|
+
|
|
96
96
|
Returns:
|
|
97
97
|
消息列表 [{role, content, timestamp, ...}]
|
|
98
98
|
"""
|
|
99
99
|
pass
|
|
100
|
-
|
|
100
|
+
|
|
101
101
|
def close(self) -> None:
|
|
102
102
|
"""关闭连接 (可选实现)"""
|
|
103
103
|
pass
|
ksadk/memory/backends/memory.py
CHANGED
|
@@ -1,49 +1,48 @@
|
|
|
1
1
|
"""In-Memory Backend - 内存存储 (开发/测试用)"""
|
|
2
2
|
|
|
3
|
-
import json
|
|
4
|
-
from datetime import datetime, timedelta
|
|
5
|
-
from typing import Any, Optional, List, Dict
|
|
6
3
|
from collections import defaultdict
|
|
4
|
+
from datetime import datetime, timedelta
|
|
5
|
+
from typing import Any, Dict, List, Optional
|
|
7
6
|
|
|
8
7
|
from ksadk.memory.backends.base import BaseMemoryBackend
|
|
9
8
|
|
|
10
9
|
|
|
11
10
|
class InMemoryBackend(BaseMemoryBackend):
|
|
12
11
|
"""内存存储后端
|
|
13
|
-
|
|
12
|
+
|
|
14
13
|
适用于开发和测试,数据在进程退出后丢失。
|
|
15
14
|
"""
|
|
16
|
-
|
|
15
|
+
|
|
17
16
|
def __init__(self):
|
|
18
17
|
# {session_id: {key: (value, expires_at)}}
|
|
19
18
|
self._data: Dict[str, Dict[str, tuple]] = defaultdict(dict)
|
|
20
19
|
# {session_id: [messages]}
|
|
21
20
|
self._messages: Dict[str, List[Dict]] = defaultdict(list)
|
|
22
|
-
|
|
21
|
+
|
|
23
22
|
def _make_key(self, key: str, session_id: Optional[str]) -> tuple:
|
|
24
23
|
"""生成复合键"""
|
|
25
24
|
sid = session_id or "__global__"
|
|
26
25
|
return sid, key
|
|
27
|
-
|
|
26
|
+
|
|
28
27
|
def _is_expired(self, expires_at: Optional[datetime]) -> bool:
|
|
29
28
|
if expires_at is None:
|
|
30
29
|
return False
|
|
31
30
|
return datetime.utcnow() > expires_at
|
|
32
|
-
|
|
31
|
+
|
|
33
32
|
def get(self, key: str, session_id: Optional[str] = None) -> Optional[Any]:
|
|
34
33
|
sid, k = self._make_key(key, session_id)
|
|
35
|
-
|
|
34
|
+
|
|
36
35
|
if sid not in self._data or k not in self._data[sid]:
|
|
37
36
|
return None
|
|
38
|
-
|
|
37
|
+
|
|
39
38
|
value, expires_at = self._data[sid][k]
|
|
40
|
-
|
|
39
|
+
|
|
41
40
|
if self._is_expired(expires_at):
|
|
42
41
|
del self._data[sid][k]
|
|
43
42
|
return None
|
|
44
|
-
|
|
43
|
+
|
|
45
44
|
return value
|
|
46
|
-
|
|
45
|
+
|
|
47
46
|
def set(
|
|
48
47
|
self,
|
|
49
48
|
key: str,
|
|
@@ -52,32 +51,32 @@ class InMemoryBackend(BaseMemoryBackend):
|
|
|
52
51
|
ttl: Optional[timedelta] = None,
|
|
53
52
|
) -> bool:
|
|
54
53
|
sid, k = self._make_key(key, session_id)
|
|
55
|
-
|
|
54
|
+
|
|
56
55
|
expires_at = None
|
|
57
56
|
if ttl:
|
|
58
57
|
expires_at = datetime.utcnow() + ttl
|
|
59
|
-
|
|
58
|
+
|
|
60
59
|
self._data[sid][k] = (value, expires_at)
|
|
61
60
|
return True
|
|
62
|
-
|
|
61
|
+
|
|
63
62
|
def delete(self, key: str, session_id: Optional[str] = None) -> bool:
|
|
64
63
|
sid, k = self._make_key(key, session_id)
|
|
65
|
-
|
|
64
|
+
|
|
66
65
|
if sid in self._data and k in self._data[sid]:
|
|
67
66
|
del self._data[sid][k]
|
|
68
67
|
return True
|
|
69
68
|
return False
|
|
70
|
-
|
|
69
|
+
|
|
71
70
|
def exists(self, key: str, session_id: Optional[str] = None) -> bool:
|
|
72
71
|
return self.get(key, session_id) is not None
|
|
73
|
-
|
|
72
|
+
|
|
74
73
|
def clear_session(self, session_id: str) -> bool:
|
|
75
74
|
if session_id in self._data:
|
|
76
75
|
del self._data[session_id]
|
|
77
76
|
if session_id in self._messages:
|
|
78
77
|
del self._messages[session_id]
|
|
79
78
|
return True
|
|
80
|
-
|
|
79
|
+
|
|
81
80
|
def add_message(
|
|
82
81
|
self,
|
|
83
82
|
session_id: str,
|
|
@@ -85,28 +84,28 @@ class InMemoryBackend(BaseMemoryBackend):
|
|
|
85
84
|
content: str,
|
|
86
85
|
metadata: Optional[Dict] = None,
|
|
87
86
|
) -> bool:
|
|
88
|
-
msg = {
|
|
87
|
+
msg: Dict[str, Any] = {
|
|
89
88
|
"role": role,
|
|
90
89
|
"content": content,
|
|
91
90
|
"timestamp": datetime.utcnow().isoformat() + "Z",
|
|
92
91
|
}
|
|
93
92
|
if metadata:
|
|
94
93
|
msg["metadata"] = metadata
|
|
95
|
-
|
|
94
|
+
|
|
96
95
|
self._messages[session_id].append(msg)
|
|
97
96
|
return True
|
|
98
|
-
|
|
97
|
+
|
|
99
98
|
def get_messages(
|
|
100
99
|
self,
|
|
101
100
|
session_id: str,
|
|
102
101
|
limit: Optional[int] = None,
|
|
103
102
|
) -> List[Dict]:
|
|
104
103
|
messages = self._messages.get(session_id, [])
|
|
105
|
-
|
|
104
|
+
|
|
106
105
|
if limit:
|
|
107
106
|
return messages[-limit:]
|
|
108
107
|
return messages.copy()
|
|
109
|
-
|
|
108
|
+
|
|
110
109
|
def close(self) -> None:
|
|
111
110
|
self._data.clear()
|
|
112
111
|
self._messages.clear()
|
ksadk/memory/backends/redis.py
CHANGED
|
@@ -2,20 +2,20 @@
|
|
|
2
2
|
|
|
3
3
|
import json
|
|
4
4
|
from datetime import datetime, timedelta
|
|
5
|
-
from typing import Any,
|
|
5
|
+
from typing import Any, Dict, List, Optional
|
|
6
6
|
|
|
7
7
|
from ksadk.memory.backends.base import BaseMemoryBackend
|
|
8
8
|
|
|
9
9
|
|
|
10
10
|
class RedisBackend(BaseMemoryBackend):
|
|
11
11
|
"""Redis 存储后端
|
|
12
|
-
|
|
12
|
+
|
|
13
13
|
适用于短期记忆和会话状态存储。
|
|
14
|
-
|
|
14
|
+
|
|
15
15
|
使用示例:
|
|
16
16
|
backend = RedisBackend(url="redis://localhost:6379/0")
|
|
17
17
|
"""
|
|
18
|
-
|
|
18
|
+
|
|
19
19
|
def __init__(
|
|
20
20
|
self,
|
|
21
21
|
url: str = "redis://localhost:6379/0",
|
|
@@ -26,39 +26,40 @@ class RedisBackend(BaseMemoryBackend):
|
|
|
26
26
|
self.prefix = prefix
|
|
27
27
|
self.default_ttl = default_ttl
|
|
28
28
|
self._client = None
|
|
29
|
-
|
|
29
|
+
|
|
30
30
|
@property
|
|
31
31
|
def client(self):
|
|
32
32
|
"""懒加载 Redis 客户端"""
|
|
33
33
|
if self._client is None:
|
|
34
34
|
try:
|
|
35
35
|
import redis
|
|
36
|
+
|
|
36
37
|
self._client = redis.from_url(self.url, decode_responses=True)
|
|
37
38
|
except ImportError:
|
|
38
39
|
raise ImportError("redis package required. Install with: pip install redis")
|
|
39
40
|
return self._client
|
|
40
|
-
|
|
41
|
+
|
|
41
42
|
def _make_key(self, key: str, session_id: Optional[str]) -> str:
|
|
42
43
|
"""生成 Redis 键"""
|
|
43
44
|
if session_id:
|
|
44
45
|
return f"{self.prefix}session:{session_id}:{key}"
|
|
45
46
|
return f"{self.prefix}global:{key}"
|
|
46
|
-
|
|
47
|
+
|
|
47
48
|
def _messages_key(self, session_id: str) -> str:
|
|
48
49
|
return f"{self.prefix}messages:{session_id}"
|
|
49
|
-
|
|
50
|
+
|
|
50
51
|
def get(self, key: str, session_id: Optional[str] = None) -> Optional[Any]:
|
|
51
52
|
redis_key = self._make_key(key, session_id)
|
|
52
53
|
value = self.client.get(redis_key)
|
|
53
|
-
|
|
54
|
+
|
|
54
55
|
if value is None:
|
|
55
56
|
return None
|
|
56
|
-
|
|
57
|
+
|
|
57
58
|
try:
|
|
58
59
|
return json.loads(value)
|
|
59
60
|
except json.JSONDecodeError:
|
|
60
61
|
return value
|
|
61
|
-
|
|
62
|
+
|
|
62
63
|
def set(
|
|
63
64
|
self,
|
|
64
65
|
key: str,
|
|
@@ -67,40 +68,40 @@ class RedisBackend(BaseMemoryBackend):
|
|
|
67
68
|
ttl: Optional[timedelta] = None,
|
|
68
69
|
) -> bool:
|
|
69
70
|
redis_key = self._make_key(key, session_id)
|
|
70
|
-
|
|
71
|
+
|
|
71
72
|
# 序列化
|
|
72
73
|
if not isinstance(value, str):
|
|
73
74
|
value = json.dumps(value, ensure_ascii=False)
|
|
74
|
-
|
|
75
|
+
|
|
75
76
|
# 设置过期时间
|
|
76
77
|
ex = None
|
|
77
78
|
if ttl:
|
|
78
79
|
ex = int(ttl.total_seconds())
|
|
79
80
|
elif self.default_ttl:
|
|
80
81
|
ex = int(self.default_ttl.total_seconds())
|
|
81
|
-
|
|
82
|
+
|
|
82
83
|
self.client.set(redis_key, value, ex=ex)
|
|
83
84
|
return True
|
|
84
|
-
|
|
85
|
+
|
|
85
86
|
def delete(self, key: str, session_id: Optional[str] = None) -> bool:
|
|
86
87
|
redis_key = self._make_key(key, session_id)
|
|
87
|
-
return self.client.delete(redis_key) > 0
|
|
88
|
-
|
|
88
|
+
return bool(self.client.delete(redis_key) > 0)
|
|
89
|
+
|
|
89
90
|
def exists(self, key: str, session_id: Optional[str] = None) -> bool:
|
|
90
91
|
redis_key = self._make_key(key, session_id)
|
|
91
|
-
return self.client.exists(redis_key) > 0
|
|
92
|
-
|
|
92
|
+
return bool(self.client.exists(redis_key) > 0)
|
|
93
|
+
|
|
93
94
|
def clear_session(self, session_id: str) -> bool:
|
|
94
95
|
pattern = f"{self.prefix}session:{session_id}:*"
|
|
95
96
|
keys = list(self.client.scan_iter(match=pattern))
|
|
96
|
-
|
|
97
|
+
|
|
97
98
|
# 也删除消息
|
|
98
99
|
keys.append(self._messages_key(session_id))
|
|
99
|
-
|
|
100
|
+
|
|
100
101
|
if keys:
|
|
101
102
|
self.client.delete(*keys)
|
|
102
103
|
return True
|
|
103
|
-
|
|
104
|
+
|
|
104
105
|
def add_message(
|
|
105
106
|
self,
|
|
106
107
|
session_id: str,
|
|
@@ -108,38 +109,38 @@ class RedisBackend(BaseMemoryBackend):
|
|
|
108
109
|
content: str,
|
|
109
110
|
metadata: Optional[Dict] = None,
|
|
110
111
|
) -> bool:
|
|
111
|
-
msg = {
|
|
112
|
+
msg: dict[str, Any] = {
|
|
112
113
|
"role": role,
|
|
113
114
|
"content": content,
|
|
114
115
|
"timestamp": datetime.utcnow().isoformat() + "Z",
|
|
115
116
|
}
|
|
116
117
|
if metadata:
|
|
117
118
|
msg["metadata"] = metadata
|
|
118
|
-
|
|
119
|
+
|
|
119
120
|
redis_key = self._messages_key(session_id)
|
|
120
121
|
self.client.rpush(redis_key, json.dumps(msg, ensure_ascii=False))
|
|
121
|
-
|
|
122
|
+
|
|
122
123
|
# 可以设置消息历史的过期时间
|
|
123
124
|
if self.default_ttl:
|
|
124
125
|
self.client.expire(redis_key, int(self.default_ttl.total_seconds()))
|
|
125
|
-
|
|
126
|
+
|
|
126
127
|
return True
|
|
127
|
-
|
|
128
|
+
|
|
128
129
|
def get_messages(
|
|
129
130
|
self,
|
|
130
131
|
session_id: str,
|
|
131
132
|
limit: Optional[int] = None,
|
|
132
133
|
) -> List[Dict]:
|
|
133
134
|
redis_key = self._messages_key(session_id)
|
|
134
|
-
|
|
135
|
+
|
|
135
136
|
if limit:
|
|
136
137
|
# 获取最后 N 条
|
|
137
138
|
raw = self.client.lrange(redis_key, -limit, -1)
|
|
138
139
|
else:
|
|
139
140
|
raw = self.client.lrange(redis_key, 0, -1)
|
|
140
|
-
|
|
141
|
+
|
|
141
142
|
return [json.loads(m) for m in raw]
|
|
142
|
-
|
|
143
|
+
|
|
143
144
|
def close(self) -> None:
|
|
144
145
|
if self._client:
|
|
145
146
|
self._client.close()
|
ksadk/memory/langchain_tool.py
CHANGED
|
@@ -31,7 +31,8 @@ def create_langchain_tools():
|
|
|
31
31
|
return load_memory_tool, save_memory_tool
|
|
32
32
|
except ImportError:
|
|
33
33
|
logger.warning(
|
|
34
|
-
"langchain-core not installed, returning raw functions.
|
|
34
|
+
"langchain-core not installed, returning raw functions. "
|
|
35
|
+
"Install with: pip install langchain-core"
|
|
35
36
|
)
|
|
36
37
|
return _load_memory, _save_memory
|
|
37
38
|
|
ksadk/memory/manager.py
CHANGED
|
@@ -1,9 +1,9 @@
|
|
|
1
1
|
"""Memory Manager - 统一记忆管理接口"""
|
|
2
2
|
|
|
3
|
-
import os
|
|
4
3
|
import logging
|
|
4
|
+
import os
|
|
5
5
|
from datetime import timedelta
|
|
6
|
-
from typing import Any,
|
|
6
|
+
from typing import Any, Dict, List, Optional, Type, cast
|
|
7
7
|
|
|
8
8
|
from ksadk.memory.backends.base import BaseMemoryBackend
|
|
9
9
|
from ksadk.memory.backends.memory import InMemoryBackend
|
|
@@ -24,26 +24,26 @@ def register_backend(name: str, backend_class: Type[BaseMemoryBackend]):
|
|
|
24
24
|
|
|
25
25
|
class MemoryManager:
|
|
26
26
|
"""统一记忆管理器
|
|
27
|
-
|
|
27
|
+
|
|
28
28
|
支持可插拔后端,自动从环境变量读取配置。
|
|
29
|
-
|
|
29
|
+
|
|
30
30
|
使用示例:
|
|
31
31
|
# 从环境变量自动配置
|
|
32
32
|
memory = MemoryManager.from_env()
|
|
33
|
-
|
|
33
|
+
|
|
34
34
|
# 手动配置
|
|
35
35
|
memory = MemoryManager(backend="redis", url="redis://localhost:6379")
|
|
36
|
-
|
|
36
|
+
|
|
37
37
|
# 存取数据
|
|
38
38
|
memory.set("key", {"data": "value"}, session_id="sess-123")
|
|
39
39
|
data = memory.get("key", session_id="sess-123")
|
|
40
|
-
|
|
40
|
+
|
|
41
41
|
# 消息历史
|
|
42
42
|
memory.add_message("sess-123", "user", "你好")
|
|
43
43
|
memory.add_message("sess-123", "assistant", "你好!有什么可以帮助你的?")
|
|
44
44
|
messages = memory.get_messages("sess-123")
|
|
45
45
|
"""
|
|
46
|
-
|
|
46
|
+
|
|
47
47
|
def __init__(
|
|
48
48
|
self,
|
|
49
49
|
backend: str = "memory",
|
|
@@ -53,7 +53,7 @@ class MemoryManager:
|
|
|
53
53
|
**kwargs,
|
|
54
54
|
):
|
|
55
55
|
"""初始化 Memory Manager
|
|
56
|
-
|
|
56
|
+
|
|
57
57
|
Args:
|
|
58
58
|
backend: 后端类型 ("memory", "redis")
|
|
59
59
|
url: 后端连接 URL
|
|
@@ -63,7 +63,7 @@ class MemoryManager:
|
|
|
63
63
|
"""
|
|
64
64
|
self.backend_name = backend
|
|
65
65
|
self._backend = self._create_backend(backend, url, prefix, default_ttl, **kwargs)
|
|
66
|
-
|
|
66
|
+
|
|
67
67
|
def _create_backend(
|
|
68
68
|
self,
|
|
69
69
|
backend: str,
|
|
@@ -76,25 +76,29 @@ class MemoryManager:
|
|
|
76
76
|
# 延迟导入 Redis backend
|
|
77
77
|
if backend == "redis":
|
|
78
78
|
from ksadk.memory.backends.redis import RedisBackend
|
|
79
|
+
|
|
79
80
|
_BACKENDS["redis"] = RedisBackend
|
|
80
|
-
|
|
81
|
+
|
|
81
82
|
if backend not in _BACKENDS:
|
|
82
83
|
raise ValueError(f"Unknown backend: {backend}. Available: {list(_BACKENDS.keys())}")
|
|
83
|
-
|
|
84
|
-
backend_class = _BACKENDS[backend]
|
|
85
|
-
|
|
84
|
+
|
|
85
|
+
backend_class: Any = _BACKENDS[backend]
|
|
86
|
+
|
|
86
87
|
# 根据后端类型传递参数
|
|
87
88
|
if backend == "memory":
|
|
88
|
-
return backend_class()
|
|
89
|
+
return cast(BaseMemoryBackend, backend_class())
|
|
89
90
|
elif backend == "redis":
|
|
90
|
-
return
|
|
91
|
+
return cast(
|
|
92
|
+
BaseMemoryBackend,
|
|
93
|
+
backend_class(url=url, prefix=prefix, default_ttl=default_ttl, **kwargs),
|
|
94
|
+
)
|
|
91
95
|
else:
|
|
92
|
-
return backend_class(**kwargs)
|
|
93
|
-
|
|
96
|
+
return cast(BaseMemoryBackend, backend_class(**kwargs))
|
|
97
|
+
|
|
94
98
|
@classmethod
|
|
95
99
|
def from_env(cls) -> "MemoryManager":
|
|
96
100
|
"""从环境变量创建 MemoryManager
|
|
97
|
-
|
|
101
|
+
|
|
98
102
|
环境变量:
|
|
99
103
|
KSADK_MEMORY_BACKEND: 后端类型 (默认 "memory")
|
|
100
104
|
KSADK_MEMORY_URL: 连接 URL (如 redis://localhost:6379)
|
|
@@ -104,27 +108,27 @@ class MemoryManager:
|
|
|
104
108
|
backend = os.environ.get("KSADK_MEMORY_BACKEND", "memory")
|
|
105
109
|
url = os.environ.get("KSADK_MEMORY_URL", "")
|
|
106
110
|
prefix = os.environ.get("KSADK_MEMORY_PREFIX", "ksadk:memory:")
|
|
107
|
-
|
|
111
|
+
|
|
108
112
|
ttl = None
|
|
109
113
|
ttl_str = os.environ.get("KSADK_MEMORY_TTL", "")
|
|
110
114
|
if ttl_str:
|
|
111
115
|
ttl = timedelta(seconds=int(ttl_str))
|
|
112
|
-
|
|
116
|
+
|
|
113
117
|
logger.debug(f"MemoryManager.from_env: backend={backend}, url={url[:20]}...")
|
|
114
|
-
|
|
118
|
+
|
|
115
119
|
return cls(
|
|
116
120
|
backend=backend,
|
|
117
121
|
url=url or None,
|
|
118
122
|
prefix=prefix,
|
|
119
123
|
default_ttl=ttl,
|
|
120
124
|
)
|
|
121
|
-
|
|
125
|
+
|
|
122
126
|
# ===== 键值操作 =====
|
|
123
|
-
|
|
127
|
+
|
|
124
128
|
def get(self, key: str, session_id: Optional[str] = None) -> Optional[Any]:
|
|
125
129
|
"""获取值"""
|
|
126
130
|
return self._backend.get(key, session_id)
|
|
127
|
-
|
|
131
|
+
|
|
128
132
|
def set(
|
|
129
133
|
self,
|
|
130
134
|
key: str,
|
|
@@ -133,24 +137,24 @@ class MemoryManager:
|
|
|
133
137
|
ttl: Optional[timedelta] = None,
|
|
134
138
|
) -> bool:
|
|
135
139
|
"""设置值"""
|
|
136
|
-
return self._backend.set(key, value, session_id, ttl)
|
|
137
|
-
|
|
140
|
+
return bool(self._backend.set(key, value, session_id, ttl))
|
|
141
|
+
|
|
138
142
|
def delete(self, key: str, session_id: Optional[str] = None) -> bool:
|
|
139
143
|
"""删除键"""
|
|
140
|
-
return self._backend.delete(key, session_id)
|
|
141
|
-
|
|
144
|
+
return bool(self._backend.delete(key, session_id))
|
|
145
|
+
|
|
142
146
|
def exists(self, key: str, session_id: Optional[str] = None) -> bool:
|
|
143
147
|
"""检查键是否存在"""
|
|
144
|
-
return self._backend.exists(key, session_id)
|
|
145
|
-
|
|
148
|
+
return bool(self._backend.exists(key, session_id))
|
|
149
|
+
|
|
146
150
|
# ===== 会话操作 =====
|
|
147
|
-
|
|
151
|
+
|
|
148
152
|
def clear_session(self, session_id: str) -> bool:
|
|
149
153
|
"""清除会话所有数据"""
|
|
150
|
-
return self._backend.clear_session(session_id)
|
|
151
|
-
|
|
154
|
+
return bool(self._backend.clear_session(session_id))
|
|
155
|
+
|
|
152
156
|
# ===== 消息历史 =====
|
|
153
|
-
|
|
157
|
+
|
|
154
158
|
def add_message(
|
|
155
159
|
self,
|
|
156
160
|
session_id: str,
|
|
@@ -159,39 +163,40 @@ class MemoryManager:
|
|
|
159
163
|
metadata: Optional[Dict] = None,
|
|
160
164
|
) -> bool:
|
|
161
165
|
"""添加消息"""
|
|
162
|
-
return self._backend.add_message(session_id, role, content, metadata)
|
|
163
|
-
|
|
166
|
+
return bool(self._backend.add_message(session_id, role, content, metadata))
|
|
167
|
+
|
|
164
168
|
def get_messages(
|
|
165
169
|
self,
|
|
166
170
|
session_id: str,
|
|
167
171
|
limit: Optional[int] = None,
|
|
168
172
|
) -> List[Dict]:
|
|
169
173
|
"""获取消息历史"""
|
|
170
|
-
|
|
171
|
-
|
|
174
|
+
messages = self._backend.get_messages(session_id, limit)
|
|
175
|
+
return list(messages)
|
|
176
|
+
|
|
172
177
|
# ===== 便捷方法 =====
|
|
173
|
-
|
|
178
|
+
|
|
174
179
|
def get_state(self, session_id: str) -> Dict:
|
|
175
180
|
"""获取会话状态 (短期记忆)"""
|
|
176
181
|
return self.get("__state__", session_id) or {}
|
|
177
|
-
|
|
182
|
+
|
|
178
183
|
def set_state(self, session_id: str, state: Dict, ttl: Optional[timedelta] = None) -> bool:
|
|
179
184
|
"""设置会话状态"""
|
|
180
185
|
return self.set("__state__", state, session_id, ttl)
|
|
181
|
-
|
|
186
|
+
|
|
182
187
|
def update_state(self, session_id: str, updates: Dict) -> bool:
|
|
183
188
|
"""更新会话状态 (合并)"""
|
|
184
189
|
current = self.get_state(session_id)
|
|
185
190
|
current.update(updates)
|
|
186
191
|
return self.set_state(session_id, current)
|
|
187
|
-
|
|
192
|
+
|
|
188
193
|
def close(self) -> None:
|
|
189
194
|
"""关闭连接"""
|
|
190
195
|
self._backend.close()
|
|
191
|
-
|
|
196
|
+
|
|
192
197
|
def __enter__(self):
|
|
193
198
|
return self
|
|
194
|
-
|
|
199
|
+
|
|
195
200
|
def __exit__(self, exc_type, exc_val, exc_tb):
|
|
196
201
|
self.close()
|
|
197
202
|
|
|
@@ -202,10 +207,10 @@ _global_manager: Optional[MemoryManager] = None
|
|
|
202
207
|
|
|
203
208
|
def get_memory_manager() -> MemoryManager:
|
|
204
209
|
"""获取全局 MemoryManager 单例
|
|
205
|
-
|
|
210
|
+
|
|
206
211
|
在 Agent 代码中使用:
|
|
207
212
|
from ksadk.memory import get_memory_manager
|
|
208
|
-
|
|
213
|
+
|
|
209
214
|
memory = get_memory_manager()
|
|
210
215
|
memory.set("key", "value")
|
|
211
216
|
"""
|