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/deployment/registry.py
CHANGED
|
@@ -4,115 +4,121 @@
|
|
|
4
4
|
使用装饰器模式自动注册 Provider,支持动态扩展。
|
|
5
5
|
"""
|
|
6
6
|
|
|
7
|
-
from typing import Dict,
|
|
7
|
+
from typing import Dict, List, Optional, Type
|
|
8
|
+
|
|
8
9
|
from ksadk.deployment.base import BaseDeployProvider
|
|
9
10
|
|
|
10
11
|
|
|
11
12
|
class DeployProviderRegistry:
|
|
12
13
|
"""Provider 注册表
|
|
13
|
-
|
|
14
|
+
|
|
14
15
|
使用方式:
|
|
15
16
|
@DeployProviderRegistry.register("my-provider")
|
|
16
17
|
class MyProvider(BaseDeployProvider):
|
|
17
18
|
...
|
|
18
19
|
"""
|
|
19
|
-
|
|
20
|
+
|
|
20
21
|
_providers: Dict[str, Type[BaseDeployProvider]] = {}
|
|
21
22
|
_instances: Dict[str, BaseDeployProvider] = {}
|
|
22
|
-
|
|
23
|
+
|
|
23
24
|
@classmethod
|
|
24
25
|
def register(cls, name: str):
|
|
25
26
|
"""装饰器: 注册 Provider
|
|
26
|
-
|
|
27
|
+
|
|
27
28
|
Args:
|
|
28
29
|
name: Provider 名称 (如 "serverless", "k8s", "docker")
|
|
29
30
|
"""
|
|
31
|
+
|
|
30
32
|
def decorator(provider_class: Type[BaseDeployProvider]):
|
|
31
33
|
if not issubclass(provider_class, BaseDeployProvider):
|
|
32
34
|
raise TypeError(f"{provider_class} must inherit from BaseDeployProvider")
|
|
33
|
-
|
|
35
|
+
|
|
34
36
|
provider_class.name = name
|
|
35
37
|
cls._providers[name] = provider_class
|
|
36
38
|
return provider_class
|
|
37
|
-
|
|
39
|
+
|
|
38
40
|
return decorator
|
|
39
|
-
|
|
41
|
+
|
|
40
42
|
@classmethod
|
|
41
|
-
def get(cls, name: str, config: Dict = None) -> BaseDeployProvider:
|
|
43
|
+
def get(cls, name: str, config: Optional[Dict] = None) -> BaseDeployProvider:
|
|
42
44
|
"""获取 Provider 实例
|
|
43
|
-
|
|
45
|
+
|
|
44
46
|
Args:
|
|
45
47
|
name: Provider 名称
|
|
46
48
|
config: Provider 配置
|
|
47
|
-
|
|
49
|
+
|
|
48
50
|
Returns:
|
|
49
51
|
Provider 实例
|
|
50
52
|
"""
|
|
51
53
|
if name not in cls._providers:
|
|
52
54
|
available = ", ".join(cls._providers.keys())
|
|
53
55
|
raise ValueError(f"Unknown provider: {name}. Available: {available}")
|
|
54
|
-
|
|
56
|
+
|
|
55
57
|
# 缓存实例 (相同 name 返回相同实例)
|
|
56
58
|
cache_key = f"{name}:{hash(str(config))}"
|
|
57
59
|
if cache_key not in cls._instances:
|
|
58
60
|
cls._instances[cache_key] = cls._providers[name](config)
|
|
59
|
-
|
|
61
|
+
|
|
60
62
|
return cls._instances[cache_key]
|
|
61
|
-
|
|
63
|
+
|
|
62
64
|
@classmethod
|
|
63
65
|
def get_class(cls, name: str) -> Type[BaseDeployProvider]:
|
|
64
66
|
"""获取 Provider 类 (不实例化)
|
|
65
|
-
|
|
67
|
+
|
|
66
68
|
Args:
|
|
67
69
|
name: Provider 名称
|
|
68
|
-
|
|
70
|
+
|
|
69
71
|
Returns:
|
|
70
72
|
Provider 类
|
|
71
73
|
"""
|
|
72
74
|
if name not in cls._providers:
|
|
73
75
|
raise ValueError(f"Unknown provider: {name}")
|
|
74
76
|
return cls._providers[name]
|
|
75
|
-
|
|
77
|
+
|
|
76
78
|
@classmethod
|
|
77
79
|
def list_providers(cls) -> List[str]:
|
|
78
80
|
"""列出所有已注册的 Provider 名称
|
|
79
|
-
|
|
81
|
+
|
|
80
82
|
Returns:
|
|
81
83
|
Provider 名称列表
|
|
82
84
|
"""
|
|
83
85
|
return list(cls._providers.keys())
|
|
84
|
-
|
|
86
|
+
|
|
85
87
|
@classmethod
|
|
86
88
|
def get_provider_info(cls) -> List[Dict]:
|
|
87
89
|
"""获取所有 Provider 的详细信息
|
|
88
|
-
|
|
90
|
+
|
|
89
91
|
Returns:
|
|
90
92
|
Provider 信息列表
|
|
91
93
|
"""
|
|
92
94
|
result = []
|
|
93
95
|
for name, provider_class in cls._providers.items():
|
|
94
|
-
result.append(
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
96
|
+
result.append(
|
|
97
|
+
{
|
|
98
|
+
"name": name,
|
|
99
|
+
"display_name": getattr(provider_class, "display_name", name),
|
|
100
|
+
"description": getattr(provider_class, "description", ""),
|
|
101
|
+
"supports_streaming": getattr(provider_class, "supports_streaming", False),
|
|
102
|
+
"supports_scaling": getattr(provider_class, "supports_scaling", False),
|
|
103
|
+
"requires_image_registry": getattr(
|
|
104
|
+
provider_class, "requires_image_registry", False
|
|
105
|
+
),
|
|
106
|
+
}
|
|
107
|
+
)
|
|
102
108
|
return result
|
|
103
|
-
|
|
109
|
+
|
|
104
110
|
@classmethod
|
|
105
111
|
def has_provider(cls, name: str) -> bool:
|
|
106
112
|
"""检查 Provider 是否存在
|
|
107
|
-
|
|
113
|
+
|
|
108
114
|
Args:
|
|
109
115
|
name: Provider 名称
|
|
110
|
-
|
|
116
|
+
|
|
111
117
|
Returns:
|
|
112
118
|
是否存在
|
|
113
119
|
"""
|
|
114
120
|
return name in cls._providers
|
|
115
|
-
|
|
121
|
+
|
|
116
122
|
@classmethod
|
|
117
123
|
def clear(cls):
|
|
118
124
|
"""清空注册表 (主要用于测试)"""
|
ksadk/deployment/state.py
CHANGED
|
@@ -4,11 +4,11 @@
|
|
|
4
4
|
用于管理本地 .agentengine.state 文件,记录已部署的 Agent/MCP 信息。
|
|
5
5
|
"""
|
|
6
6
|
|
|
7
|
-
import yaml
|
|
8
|
-
from pathlib import Path
|
|
9
|
-
from typing import Optional, Dict, Any
|
|
10
7
|
from datetime import datetime
|
|
8
|
+
from pathlib import Path
|
|
9
|
+
from typing import Any, Dict, Optional
|
|
11
10
|
|
|
11
|
+
import yaml
|
|
12
12
|
|
|
13
13
|
STATE_FILE_NAME = ".agentengine.state"
|
|
14
14
|
|
|
@@ -23,9 +23,9 @@ def load_state(project_dir: Path) -> Dict[str, Any]:
|
|
|
23
23
|
state_file = get_state_file_path(project_dir)
|
|
24
24
|
if not state_file.exists():
|
|
25
25
|
return {}
|
|
26
|
-
|
|
26
|
+
|
|
27
27
|
try:
|
|
28
|
-
with open(state_file,
|
|
28
|
+
with open(state_file, "r", encoding="utf-8") as f:
|
|
29
29
|
return yaml.safe_load(f) or {}
|
|
30
30
|
except Exception:
|
|
31
31
|
return {}
|
|
@@ -34,12 +34,12 @@ def load_state(project_dir: Path) -> Dict[str, Any]:
|
|
|
34
34
|
def save_state(project_dir: Path, data: Dict[str, Any]) -> None:
|
|
35
35
|
"""保存状态文件"""
|
|
36
36
|
state_file = get_state_file_path(project_dir)
|
|
37
|
-
|
|
37
|
+
|
|
38
38
|
# 自动添加 updated_at
|
|
39
39
|
if "updated_at" not in data:
|
|
40
40
|
data["updated_at"] = datetime.now().isoformat()
|
|
41
|
-
|
|
42
|
-
with open(state_file,
|
|
41
|
+
|
|
42
|
+
with open(state_file, "w", encoding="utf-8") as f:
|
|
43
43
|
yaml.dump(data, f, default_flow_style=False, allow_unicode=True)
|
|
44
44
|
|
|
45
45
|
|
|
@@ -51,9 +51,9 @@ def update_state(project_dir: Path, updates: Dict[str, Any]) -> Dict[str, Any]:
|
|
|
51
51
|
return current_state
|
|
52
52
|
|
|
53
53
|
|
|
54
|
-
def clear_state(project_dir: Path, key: str = None) -> bool:
|
|
54
|
+
def clear_state(project_dir: Path, key: Optional[str] = None) -> bool:
|
|
55
55
|
"""清理状态文件
|
|
56
|
-
|
|
56
|
+
|
|
57
57
|
Args:
|
|
58
58
|
project_dir: 项目目录
|
|
59
59
|
key: 如果指定,仅当状态中的 ID 与 key 匹配时才删除
|
|
@@ -64,7 +64,7 @@ def clear_state(project_dir: Path, key: str = None) -> bool:
|
|
|
64
64
|
state_file = get_state_file_path(project_dir)
|
|
65
65
|
if not state_file.exists():
|
|
66
66
|
return False
|
|
67
|
-
|
|
67
|
+
|
|
68
68
|
if key:
|
|
69
69
|
# 检查是否匹配
|
|
70
70
|
state = load_state(project_dir)
|
ksadk/deployment/ui_config.py
CHANGED
|
@@ -2,13 +2,13 @@
|
|
|
2
2
|
|
|
3
3
|
from ksadk.ui_config import ( # noqa: F401
|
|
4
4
|
SUPPORTED_UI_PROFILES,
|
|
5
|
-
UIConfig,
|
|
6
5
|
UI_PROFILE_ADK,
|
|
7
6
|
UI_PROFILE_AUTO,
|
|
8
7
|
UI_PROFILE_CUSTOM,
|
|
9
8
|
UI_PROFILE_HERMES,
|
|
10
9
|
UI_PROFILE_LANGCHAIN,
|
|
11
10
|
UI_PROFILE_OPENCLAW,
|
|
11
|
+
UIConfig,
|
|
12
12
|
default_ui_path,
|
|
13
13
|
extract_ui_state,
|
|
14
14
|
infer_ui_profile_from_framework,
|
ksadk/detection/__init__.py
CHANGED
|
@@ -2,6 +2,6 @@
|
|
|
2
2
|
KsADK Detection - 框架自动检测模块
|
|
3
3
|
"""
|
|
4
4
|
|
|
5
|
-
from ksadk.detection.detector import
|
|
5
|
+
from ksadk.detection.detector import DetectionResult, FrameworkDetector, FrameworkType
|
|
6
6
|
|
|
7
7
|
__all__ = ["FrameworkDetector", "DetectionResult", "FrameworkType"]
|
ksadk/detection/detector.py
CHANGED
|
@@ -4,7 +4,7 @@
|
|
|
4
4
|
|
|
5
5
|
import ast
|
|
6
6
|
import json
|
|
7
|
-
from dataclasses import dataclass
|
|
7
|
+
from dataclasses import dataclass, field
|
|
8
8
|
from enum import Enum
|
|
9
9
|
from pathlib import Path
|
|
10
10
|
from typing import Optional
|
|
@@ -20,6 +20,8 @@ class FrameworkType(Enum):
|
|
|
20
20
|
LANGGRAPH = "langgraph"
|
|
21
21
|
DEEPAGENTS = "deepagents"
|
|
22
22
|
HERMES = "hermes"
|
|
23
|
+
FASTMCP = "fastmcp"
|
|
24
|
+
CODEX = "codex"
|
|
23
25
|
UNKNOWN = "unknown"
|
|
24
26
|
|
|
25
27
|
|
|
@@ -34,6 +36,9 @@ class DetectionResult:
|
|
|
34
36
|
agent_variable: str = "root_agent"
|
|
35
37
|
runner_class: str = ""
|
|
36
38
|
confidence: float = 0.0
|
|
39
|
+
# 配置文件的原始内容(ksadk.yaml/agentengine.yaml),供 runner 读 model/prompt 等
|
|
40
|
+
# 真实生效字段(codex 无 root_agent,配置全靠它)。默认空 dict,不影响既有构造。
|
|
41
|
+
raw_config: dict = field(default_factory=dict)
|
|
37
42
|
|
|
38
43
|
@property
|
|
39
44
|
def is_valid(self) -> bool:
|
|
@@ -44,6 +49,14 @@ class FrameworkDetector:
|
|
|
44
49
|
"""框架检测器"""
|
|
45
50
|
|
|
46
51
|
_ENTRY_FILES = ("agent.py", "main.py", "app.py")
|
|
52
|
+
_LANGCHAIN_MODULES = frozenset(
|
|
53
|
+
{
|
|
54
|
+
"langchain",
|
|
55
|
+
"langchain_openai",
|
|
56
|
+
"langchain_core",
|
|
57
|
+
"langchain_community",
|
|
58
|
+
}
|
|
59
|
+
)
|
|
47
60
|
|
|
48
61
|
def __init__(self, project_dir: str):
|
|
49
62
|
self.project_dir = Path(project_dir).resolve()
|
|
@@ -56,6 +69,11 @@ class FrameworkDetector:
|
|
|
56
69
|
if config_result:
|
|
57
70
|
return config_result
|
|
58
71
|
|
|
72
|
+
# 1.5 codex.yaml 标志文件(fallback 自动探测,优先级低于 ksadk.yaml framework)
|
|
73
|
+
codex_result = self._check_codex_yaml()
|
|
74
|
+
if codex_result:
|
|
75
|
+
return codex_result
|
|
76
|
+
|
|
59
77
|
graph_config_result = self._check_langgraph_json()
|
|
60
78
|
if graph_config_result:
|
|
61
79
|
return graph_config_result
|
|
@@ -104,12 +122,15 @@ class FrameworkDetector:
|
|
|
104
122
|
"langgraph": FrameworkType.LANGGRAPH,
|
|
105
123
|
"deepagents": FrameworkType.DEEPAGENTS,
|
|
106
124
|
"hermes": FrameworkType.HERMES,
|
|
125
|
+
"codex": FrameworkType.CODEX,
|
|
107
126
|
}.get(framework, FrameworkType.UNKNOWN)
|
|
108
127
|
|
|
109
128
|
artifact_type = str(config.get("artifact_type") or "").strip().lower()
|
|
110
129
|
is_hermes_container = (
|
|
111
130
|
framework_type == FrameworkType.HERMES and artifact_type == "container"
|
|
112
131
|
)
|
|
132
|
+
# codex 无 root_agent 变量(agent 逻辑在 prompt),跳过 entry_exposes_variable 校验
|
|
133
|
+
is_codex = framework_type == FrameworkType.CODEX
|
|
113
134
|
default_entry_point = (
|
|
114
135
|
"runtime/app.py"
|
|
115
136
|
if is_hermes_container and (self.project_dir / "runtime" / "app.py").is_file()
|
|
@@ -119,10 +140,13 @@ class FrameworkDetector:
|
|
|
119
140
|
agent_variable = config.get("agent_variable", "root_agent")
|
|
120
141
|
runner_class = str(config.get("runner_class") or "").strip()
|
|
121
142
|
entry_path = self.project_dir / str(entry_point).replace("\\", "/")
|
|
122
|
-
|
|
143
|
+
# codex 无 agent.py(逻辑在 prompt),容忍 entry_point 不存在
|
|
144
|
+
if not is_codex and (not entry_path.exists() or not entry_path.is_file()):
|
|
123
145
|
return None
|
|
124
|
-
if
|
|
125
|
-
|
|
146
|
+
if (
|
|
147
|
+
not is_codex
|
|
148
|
+
and not is_hermes_container
|
|
149
|
+
and not self._entry_exposes_variable(entry_path, agent_variable)
|
|
126
150
|
):
|
|
127
151
|
return None
|
|
128
152
|
package = str(config.get("package") or "").strip()
|
|
@@ -141,10 +165,30 @@ class FrameworkDetector:
|
|
|
141
165
|
agent_variable=agent_variable,
|
|
142
166
|
runner_class=runner_class,
|
|
143
167
|
confidence=1.0,
|
|
168
|
+
raw_config=config,
|
|
144
169
|
)
|
|
145
170
|
except Exception:
|
|
146
171
|
return None
|
|
147
172
|
|
|
173
|
+
def _check_codex_yaml(self) -> Optional[DetectionResult]:
|
|
174
|
+
"""fallback:项目根有 codex.yaml 即判 CODEX(最小标志文件,可含 model/sandbox)。
|
|
175
|
+
|
|
176
|
+
保守规则,不做源码 import 扫描(避免误判普通 Python 项目)。优先级低于
|
|
177
|
+
ksadk.yaml framework: codex 显式声明。
|
|
178
|
+
"""
|
|
179
|
+
codex_path = self.project_dir / "codex.yaml"
|
|
180
|
+
if not codex_path.exists():
|
|
181
|
+
return None
|
|
182
|
+
return DetectionResult(
|
|
183
|
+
type=FrameworkType.CODEX,
|
|
184
|
+
name=self.project_dir.name,
|
|
185
|
+
entry_point="",
|
|
186
|
+
package_path=str(self.project_dir),
|
|
187
|
+
agent_variable="",
|
|
188
|
+
runner_class="",
|
|
189
|
+
confidence=0.9,
|
|
190
|
+
)
|
|
191
|
+
|
|
148
192
|
def _find_package_dir(self) -> Optional[Path]:
|
|
149
193
|
"""查找 Python 包目录"""
|
|
150
194
|
# 优先查找与项目同名的包 (下划线版本)
|
|
@@ -270,19 +314,16 @@ class FrameworkDetector:
|
|
|
270
314
|
) -> FrameworkType:
|
|
271
315
|
try:
|
|
272
316
|
content = entry_path.read_text(encoding="utf-8-sig")
|
|
317
|
+
except Exception:
|
|
318
|
+
return fallback
|
|
319
|
+
try:
|
|
273
320
|
tree = ast.parse(content, filename=str(entry_path))
|
|
274
321
|
imports = self._extract_imports(tree)
|
|
322
|
+
calls = self._extract_call_names(tree)
|
|
323
|
+
framework = self._classify(imports, calls, content)
|
|
275
324
|
except Exception:
|
|
276
|
-
|
|
277
|
-
if
|
|
278
|
-
return FrameworkType.DEEPAGENTS
|
|
279
|
-
if self._is_langgraph(imports, content):
|
|
280
|
-
return FrameworkType.LANGGRAPH
|
|
281
|
-
if self._is_adk(imports, content):
|
|
282
|
-
return FrameworkType.ADK
|
|
283
|
-
if self._is_langchain(imports, content):
|
|
284
|
-
return FrameworkType.LANGCHAIN
|
|
285
|
-
return fallback
|
|
325
|
+
framework = self._classify_from_strings(content)
|
|
326
|
+
return framework if framework != FrameworkType.UNKNOWN else fallback
|
|
286
327
|
|
|
287
328
|
def _check_langgraph_json(self) -> Optional[DetectionResult]:
|
|
288
329
|
config_path = self.project_dir / "langgraph.json"
|
|
@@ -318,71 +359,79 @@ class FrameworkDetector:
|
|
|
318
359
|
|
|
319
360
|
def _analyze_code(self, agent_file: Path, package_path: Path) -> DetectionResult:
|
|
320
361
|
"""分析代码确定框架类型"""
|
|
362
|
+
entry_point = str(agent_file.relative_to(self.project_dir))
|
|
321
363
|
try:
|
|
322
364
|
# 使用 utf-8-sig 自动处理 BOM,兼容 Windows/编辑器带 BOM 的脚本
|
|
323
365
|
content = agent_file.read_text(encoding="utf-8-sig")
|
|
324
|
-
tree = ast.parse(content, filename=str(agent_file))
|
|
325
366
|
except Exception:
|
|
326
367
|
return DetectionResult(
|
|
327
368
|
type=FrameworkType.UNKNOWN,
|
|
328
369
|
name=self.project_dir.name,
|
|
329
|
-
entry_point=
|
|
330
|
-
package_path=str(package_path),
|
|
331
|
-
)
|
|
332
|
-
|
|
333
|
-
imports = self._extract_imports(tree)
|
|
334
|
-
|
|
335
|
-
# 检测 ADK
|
|
336
|
-
if self._is_adk(imports, content):
|
|
337
|
-
return DetectionResult(
|
|
338
|
-
type=FrameworkType.ADK,
|
|
339
|
-
name=package_path.name,
|
|
340
|
-
entry_point=str(agent_file.relative_to(self.project_dir)),
|
|
341
|
-
package_path=str(package_path),
|
|
342
|
-
agent_variable="root_agent",
|
|
343
|
-
confidence=0.9,
|
|
344
|
-
)
|
|
345
|
-
|
|
346
|
-
# 检测 DeepAgents (LangChain 生态, 底层基于 LangGraph)
|
|
347
|
-
if self._is_deepagents(imports, content):
|
|
348
|
-
return DetectionResult(
|
|
349
|
-
type=FrameworkType.DEEPAGENTS,
|
|
350
|
-
name=package_path.name,
|
|
351
|
-
entry_point=str(agent_file.relative_to(self.project_dir)),
|
|
352
|
-
package_path=str(package_path),
|
|
353
|
-
agent_variable="root_agent",
|
|
354
|
-
confidence=0.9,
|
|
355
|
-
)
|
|
356
|
-
|
|
357
|
-
# 检测 LangGraph
|
|
358
|
-
if self._is_langgraph(imports, content):
|
|
359
|
-
return DetectionResult(
|
|
360
|
-
type=FrameworkType.LANGGRAPH,
|
|
361
|
-
name=package_path.name,
|
|
362
|
-
entry_point=str(agent_file.relative_to(self.project_dir)),
|
|
370
|
+
entry_point=entry_point,
|
|
363
371
|
package_path=str(package_path),
|
|
364
|
-
agent_variable="root_agent",
|
|
365
|
-
confidence=0.9,
|
|
366
372
|
)
|
|
367
373
|
|
|
368
|
-
|
|
369
|
-
|
|
370
|
-
|
|
371
|
-
|
|
372
|
-
|
|
373
|
-
|
|
374
|
-
|
|
375
|
-
|
|
376
|
-
|
|
377
|
-
)
|
|
374
|
+
calls: set = set()
|
|
375
|
+
try:
|
|
376
|
+
tree = ast.parse(content, filename=str(agent_file))
|
|
377
|
+
imports = self._extract_imports(tree)
|
|
378
|
+
calls = self._extract_call_names(tree)
|
|
379
|
+
framework = self._classify(imports, calls, content)
|
|
380
|
+
except Exception:
|
|
381
|
+
# AST 解析失败(语法错误等)时退化为字符串判定,避免直接判 UNKNOWN
|
|
382
|
+
framework = self._classify_from_strings(content)
|
|
378
383
|
|
|
384
|
+
name = package_path.name if framework != FrameworkType.UNKNOWN else self.project_dir.name
|
|
379
385
|
return DetectionResult(
|
|
380
|
-
type=
|
|
381
|
-
name=
|
|
382
|
-
entry_point=
|
|
386
|
+
type=framework,
|
|
387
|
+
name=name,
|
|
388
|
+
entry_point=entry_point,
|
|
383
389
|
package_path=str(package_path),
|
|
390
|
+
agent_variable="root_agent",
|
|
391
|
+
confidence=self._confidence_for(framework, calls),
|
|
384
392
|
)
|
|
385
393
|
|
|
394
|
+
def _classify(self, imports: set, calls: set, content: str) -> FrameworkType:
|
|
395
|
+
"""AST 级统一分类,顺序:
|
|
396
|
+
ADK → DeepAgents → LangChain(高层) → LangGraph → LangChain(legacy) → UNKNOWN"""
|
|
397
|
+
if self._is_adk(imports, content):
|
|
398
|
+
return FrameworkType.ADK
|
|
399
|
+
if self._is_deepagents(imports, calls, content):
|
|
400
|
+
return FrameworkType.DEEPAGENTS
|
|
401
|
+
if self._is_langchain_high_level(imports, calls):
|
|
402
|
+
return FrameworkType.LANGCHAIN
|
|
403
|
+
if self._is_langgraph(calls):
|
|
404
|
+
return FrameworkType.LANGGRAPH
|
|
405
|
+
if self._is_langchain_legacy(imports, calls):
|
|
406
|
+
return FrameworkType.LANGCHAIN
|
|
407
|
+
return FrameworkType.UNKNOWN
|
|
408
|
+
|
|
409
|
+
def _classify_from_strings(self, content: str) -> FrameworkType:
|
|
410
|
+
"""AST 解析失败时的字符串兜底,顺序与 _classify 保持一致"""
|
|
411
|
+
if "google.adk" in content or "from google.adk" in content:
|
|
412
|
+
return FrameworkType.ADK
|
|
413
|
+
if "deepagents" in content or "create_deep_agent(" in content:
|
|
414
|
+
return FrameworkType.DEEPAGENTS
|
|
415
|
+
if "create_agent(" in content:
|
|
416
|
+
return FrameworkType.LANGCHAIN
|
|
417
|
+
if (
|
|
418
|
+
"StateGraph" in content
|
|
419
|
+
or "langgraph.graph" in content
|
|
420
|
+
or "create_react_agent(" in content
|
|
421
|
+
):
|
|
422
|
+
return FrameworkType.LANGGRAPH
|
|
423
|
+
if any(m in content for m in self._LANGCHAIN_MODULES):
|
|
424
|
+
return FrameworkType.LANGCHAIN
|
|
425
|
+
return FrameworkType.UNKNOWN
|
|
426
|
+
|
|
427
|
+
def _confidence_for(self, framework: FrameworkType, calls: set) -> float:
|
|
428
|
+
if framework == FrameworkType.UNKNOWN:
|
|
429
|
+
return 0.0
|
|
430
|
+
if framework == FrameworkType.LANGCHAIN:
|
|
431
|
+
# 高层(create_agent 调用) 0.9,legacy 兜底 0.8
|
|
432
|
+
return 0.9 if "create_agent" in calls else 0.8
|
|
433
|
+
return 0.9
|
|
434
|
+
|
|
386
435
|
def _extract_imports(self, tree: ast.AST) -> set:
|
|
387
436
|
"""提取导入的模块"""
|
|
388
437
|
imports = set()
|
|
@@ -395,6 +444,19 @@ class FrameworkDetector:
|
|
|
395
444
|
imports.add(node.module.split(".")[0])
|
|
396
445
|
return imports
|
|
397
446
|
|
|
447
|
+
def _extract_call_names(self, tree: ast.AST) -> set:
|
|
448
|
+
"""提取代码中实际调用的函数/方法名(AST 级,避免注释/字符串误判)"""
|
|
449
|
+
calls = set()
|
|
450
|
+
for node in ast.walk(tree):
|
|
451
|
+
if not isinstance(node, ast.Call):
|
|
452
|
+
continue
|
|
453
|
+
func = node.func
|
|
454
|
+
if isinstance(func, ast.Name):
|
|
455
|
+
calls.add(func.id)
|
|
456
|
+
elif isinstance(func, ast.Attribute):
|
|
457
|
+
calls.add(func.attr)
|
|
458
|
+
return calls
|
|
459
|
+
|
|
398
460
|
def _is_adk(self, imports: set, content: str) -> bool:
|
|
399
461
|
"""检测是否为 ADK 项目"""
|
|
400
462
|
# 检查 google.adk 导入
|
|
@@ -402,30 +464,31 @@ class FrameworkDetector:
|
|
|
402
464
|
return True
|
|
403
465
|
return False
|
|
404
466
|
|
|
405
|
-
def _is_langgraph(self,
|
|
406
|
-
"""检测是否为 LangGraph
|
|
407
|
-
|
|
408
|
-
|
|
409
|
-
|
|
410
|
-
return True
|
|
411
|
-
return False
|
|
467
|
+
def _is_langgraph(self, calls: set) -> bool:
|
|
468
|
+
"""检测是否为 LangGraph 项目:直接编排 StateGraph 或调用 create_react_agent。
|
|
469
|
+
不再用 `"StateGraph" in content` 字符串包含,避免注释/类型注解误命中
|
|
470
|
+
导致 deepagents/langchain 塌缩。"""
|
|
471
|
+
return "StateGraph" in calls or "create_react_agent" in calls
|
|
412
472
|
|
|
413
|
-
def
|
|
414
|
-
"""
|
|
415
|
-
|
|
416
|
-
|
|
417
|
-
|
|
418
|
-
|
|
419
|
-
|
|
420
|
-
|
|
421
|
-
|
|
422
|
-
|
|
423
|
-
|
|
473
|
+
def _is_langchain_high_level(self, imports: set, calls: set) -> bool:
|
|
474
|
+
"""新版 LangChain 高层 API:langchain 系 import 且调用 create_agent。"""
|
|
475
|
+
if not (self._LANGCHAIN_MODULES & imports):
|
|
476
|
+
return False
|
|
477
|
+
return "create_agent" in calls
|
|
478
|
+
|
|
479
|
+
def _is_langchain_legacy(self, imports: set, calls: set) -> bool:
|
|
480
|
+
"""LangChain legacy 兜底:langchain 系 import 且无 LangGraph 直接编排
|
|
481
|
+
信号(覆盖 LCEL 链等旧用法)。"""
|
|
482
|
+
if not (self._LANGCHAIN_MODULES & imports):
|
|
483
|
+
return False
|
|
484
|
+
return "StateGraph" not in calls and "create_react_agent" not in calls
|
|
424
485
|
|
|
425
|
-
def _is_deepagents(self, imports: set, content: str) -> bool:
|
|
486
|
+
def _is_deepagents(self, imports: set, calls: set, content: str) -> bool:
|
|
426
487
|
"""检测是否为 DeepAgents 项目"""
|
|
427
488
|
if "deepagents" in imports:
|
|
428
489
|
return True
|
|
490
|
+
if "create_deep_agent" in calls:
|
|
491
|
+
return True
|
|
429
492
|
if "from deepagents import" in content or "create_deep_agent(" in content:
|
|
430
493
|
return True
|
|
431
494
|
return False
|
ksadk/detection/mcp_detector.py
CHANGED
|
@@ -3,12 +3,14 @@ MCP 检测器 - 自动检测 FastMCP 项目
|
|
|
3
3
|
"""
|
|
4
4
|
|
|
5
5
|
import ast
|
|
6
|
-
from dataclasses import dataclass
|
|
6
|
+
from dataclasses import dataclass, field
|
|
7
7
|
from pathlib import Path
|
|
8
8
|
from typing import List, Optional
|
|
9
9
|
|
|
10
10
|
import yaml
|
|
11
11
|
|
|
12
|
+
from ksadk.detection.detector import FrameworkType
|
|
13
|
+
|
|
12
14
|
|
|
13
15
|
@dataclass
|
|
14
16
|
class MCPDetectionResult:
|
|
@@ -19,17 +21,18 @@ class MCPDetectionResult:
|
|
|
19
21
|
entry_point: str
|
|
20
22
|
package_path: str
|
|
21
23
|
mcp_variable: str = "mcp"
|
|
22
|
-
tools: List[str] =
|
|
24
|
+
tools: List[str] = field(default_factory=list) # 检测到的工具名称
|
|
23
25
|
confidence: float = 0.0
|
|
24
26
|
|
|
25
|
-
def __post_init__(self):
|
|
26
|
-
if self.tools is None:
|
|
27
|
-
self.tools = []
|
|
28
|
-
|
|
29
27
|
@property
|
|
30
28
|
def is_valid(self) -> bool:
|
|
31
29
|
return self.is_mcp
|
|
32
30
|
|
|
31
|
+
@property
|
|
32
|
+
def type(self) -> FrameworkType:
|
|
33
|
+
"""Expose the framework contract expected by shared builders."""
|
|
34
|
+
return FrameworkType.FASTMCP
|
|
35
|
+
|
|
33
36
|
|
|
34
37
|
class MCPDetector:
|
|
35
38
|
"""MCP 检测器 - 检测 FastMCP 项目"""
|