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/toolsets/sandbox.py
CHANGED
|
@@ -1,9 +1,9 @@
|
|
|
1
1
|
from __future__ import annotations
|
|
2
2
|
|
|
3
|
+
import logging
|
|
3
4
|
import os
|
|
4
5
|
import shlex
|
|
5
6
|
import time
|
|
6
|
-
import logging
|
|
7
7
|
from typing import Any
|
|
8
8
|
from uuid import uuid4
|
|
9
9
|
|
|
@@ -15,7 +15,6 @@ from ksadk.tools.result_budget import budget_text_fields
|
|
|
15
15
|
from ksadk.toolsets._langchain import as_tool
|
|
16
16
|
from ksadk.toolsets.workspace import workspace_root
|
|
17
17
|
|
|
18
|
-
|
|
19
18
|
logger = logging.getLogger(__name__)
|
|
20
19
|
|
|
21
20
|
|
|
@@ -30,11 +29,19 @@ def _gateway():
|
|
|
30
29
|
return default_tool_gateway(_SANDBOX_TOOL_POLICIES)
|
|
31
30
|
|
|
32
31
|
|
|
32
|
+
def _dict_result(value: Any, *, tool_name: str) -> dict[str, Any]:
|
|
33
|
+
if not isinstance(value, dict):
|
|
34
|
+
raise TypeError(f"{tool_name} returned {type(value).__name__}, expected dict")
|
|
35
|
+
return dict(value)
|
|
36
|
+
|
|
37
|
+
|
|
33
38
|
def sandbox_backend_name() -> str:
|
|
34
39
|
explicit = os.environ.get("KSADK_SANDBOX_BACKEND", "").strip().lower()
|
|
35
40
|
if explicit:
|
|
36
41
|
return explicit
|
|
37
|
-
if os.environ.get("KSADK_SANDBOX_TEMPLATE_ID") or os.environ.get(
|
|
42
|
+
if os.environ.get("KSADK_SANDBOX_TEMPLATE_ID") or os.environ.get(
|
|
43
|
+
"KSADK_SKILL_RUNTIME_TEMPLATE_ID"
|
|
44
|
+
):
|
|
38
45
|
return "e2b"
|
|
39
46
|
return "none"
|
|
40
47
|
|
|
@@ -47,15 +54,26 @@ def _sandbox_execution_backend_name() -> str:
|
|
|
47
54
|
def sandbox_status() -> dict:
|
|
48
55
|
"""Report configured AgentEngine sandbox status and boundaries."""
|
|
49
56
|
|
|
50
|
-
return
|
|
57
|
+
return _dict_result(
|
|
58
|
+
_gateway().invoke("sandbox_status", _sandbox_status_impl),
|
|
59
|
+
tool_name="sandbox_status",
|
|
60
|
+
)
|
|
51
61
|
|
|
52
62
|
|
|
53
63
|
def _sandbox_status_impl() -> dict[str, Any]:
|
|
54
64
|
backend = sandbox_backend_name()
|
|
55
|
-
timeout = int(
|
|
65
|
+
timeout = int(
|
|
66
|
+
os.environ.get("KSADK_SANDBOX_TIMEOUT")
|
|
67
|
+
or os.environ.get("KSADK_SKILL_RUNTIME_TIMEOUT")
|
|
68
|
+
or "600"
|
|
69
|
+
)
|
|
56
70
|
idle_ttl = _int_env("KSADK_SANDBOX_IDLE_TTL_SECONDS", 300)
|
|
57
71
|
max_sessions = _int_env("KSADK_SANDBOX_MAX_SESSIONS", 0)
|
|
58
|
-
template_id =
|
|
72
|
+
template_id = (
|
|
73
|
+
os.environ.get("KSADK_SANDBOX_TEMPLATE_ID")
|
|
74
|
+
or os.environ.get("KSADK_SKILL_RUNTIME_TEMPLATE_ID")
|
|
75
|
+
or ""
|
|
76
|
+
)
|
|
59
77
|
isolated = backend not in {"local", "local_process", "pod", "pod_process"}
|
|
60
78
|
latest = GLOBAL_SANDBOX_REGISTRY.latest()
|
|
61
79
|
now = time.time()
|
|
@@ -89,7 +107,19 @@ def run_command(
|
|
|
89
107
|
) -> dict[str, Any]:
|
|
90
108
|
"""Run a shell command inside the configured isolated sandbox."""
|
|
91
109
|
|
|
92
|
-
return
|
|
110
|
+
return _dict_result(
|
|
111
|
+
_gateway().invoke(
|
|
112
|
+
"run_command",
|
|
113
|
+
_run_command_impl,
|
|
114
|
+
command,
|
|
115
|
+
cwd,
|
|
116
|
+
timeout,
|
|
117
|
+
env,
|
|
118
|
+
background,
|
|
119
|
+
approval=approval,
|
|
120
|
+
),
|
|
121
|
+
tool_name="run_command",
|
|
122
|
+
)
|
|
93
123
|
|
|
94
124
|
|
|
95
125
|
def _run_command_impl(
|
|
@@ -102,11 +132,15 @@ def _run_command_impl(
|
|
|
102
132
|
command_text = str(command or "").strip()
|
|
103
133
|
if not command_text:
|
|
104
134
|
return {"ok": False, "error_message": "command is required"}
|
|
105
|
-
policy = check_command_policy(command_text)
|
|
135
|
+
policy = _dict_result(check_command_policy(command_text), tool_name="check_command_policy")
|
|
106
136
|
if not policy.get("ok"):
|
|
107
137
|
return policy
|
|
108
138
|
if background:
|
|
109
|
-
return {
|
|
139
|
+
return {
|
|
140
|
+
"ok": False,
|
|
141
|
+
"error_type": "background_not_supported",
|
|
142
|
+
"error_message": "background commands are not supported in P0",
|
|
143
|
+
}
|
|
110
144
|
try:
|
|
111
145
|
entry, _created = _sandbox_entry("ksadk-direct")
|
|
112
146
|
result = entry.session.run_command(command_text, timeout=timeout, env=env, cwd=cwd)
|
|
@@ -119,7 +153,15 @@ def _run_command_impl(
|
|
|
119
153
|
"stderr": result.stderr,
|
|
120
154
|
"exit_code": result.exit_code,
|
|
121
155
|
}
|
|
122
|
-
return
|
|
156
|
+
return _dict_result(
|
|
157
|
+
budget_text_fields(
|
|
158
|
+
payload,
|
|
159
|
+
tool_name="run_command",
|
|
160
|
+
fields=("stdout", "stderr"),
|
|
161
|
+
metadata={"tool_use_id": entry.sandbox_id},
|
|
162
|
+
),
|
|
163
|
+
tool_name="run_command",
|
|
164
|
+
)
|
|
123
165
|
except SandboxError as exc:
|
|
124
166
|
return {"ok": False, "error_type": type(exc).__name__, "error_message": str(exc)}
|
|
125
167
|
except Exception as exc:
|
|
@@ -135,7 +177,12 @@ def run_code(
|
|
|
135
177
|
) -> dict[str, Any]:
|
|
136
178
|
"""Run a code snippet through the sandbox; this is not a shell replacement."""
|
|
137
179
|
|
|
138
|
-
return
|
|
180
|
+
return _dict_result(
|
|
181
|
+
_gateway().invoke(
|
|
182
|
+
"run_code", _run_code_impl, code, language, timeout, env, approval=approval
|
|
183
|
+
),
|
|
184
|
+
tool_name="run_code",
|
|
185
|
+
)
|
|
139
186
|
|
|
140
187
|
|
|
141
188
|
def _run_code_impl(
|
|
@@ -152,7 +199,10 @@ def _run_code_impl(
|
|
|
152
199
|
return {
|
|
153
200
|
"ok": False,
|
|
154
201
|
"error_type": "isolated_sandbox_required",
|
|
155
|
-
"error_message":
|
|
202
|
+
"error_message": (
|
|
203
|
+
"run_code requires an isolated sandbox backend; local_process and "
|
|
204
|
+
"pod_process are not supported for snippet execution"
|
|
205
|
+
),
|
|
156
206
|
"backend": backend_name,
|
|
157
207
|
"boundary": _sandbox_boundary(backend_name),
|
|
158
208
|
}
|
|
@@ -181,7 +231,15 @@ def _run_code_impl(
|
|
|
181
231
|
"stderr": result.stderr,
|
|
182
232
|
"exit_code": result.exit_code,
|
|
183
233
|
}
|
|
184
|
-
return
|
|
234
|
+
return _dict_result(
|
|
235
|
+
budget_text_fields(
|
|
236
|
+
payload,
|
|
237
|
+
tool_name="run_code",
|
|
238
|
+
fields=("stdout", "stderr"),
|
|
239
|
+
metadata={"tool_use_id": entry.sandbox_id},
|
|
240
|
+
),
|
|
241
|
+
tool_name="run_code",
|
|
242
|
+
)
|
|
185
243
|
except SandboxError as exc:
|
|
186
244
|
return {"ok": False, "error_type": type(exc).__name__, "error_message": str(exc)}
|
|
187
245
|
except Exception as exc:
|
|
@@ -300,10 +358,18 @@ def _int_env(name: str, default: int) -> int:
|
|
|
300
358
|
|
|
301
359
|
def _sandbox_boundary(backend: str) -> str:
|
|
302
360
|
if backend in {"local", "local_process"}:
|
|
303
|
-
return
|
|
361
|
+
return (
|
|
362
|
+
"executes as a local child process; shares local filesystem, env allowlist, and network"
|
|
363
|
+
)
|
|
304
364
|
if backend in {"pod", "pod_process"}:
|
|
305
|
-
return
|
|
306
|
-
|
|
365
|
+
return (
|
|
366
|
+
"executes inside the agent pod; shares pod filesystem, env allowlist, "
|
|
367
|
+
"network, and service account"
|
|
368
|
+
)
|
|
369
|
+
return (
|
|
370
|
+
"Sandbox tools execute commands and code only through the configured isolated "
|
|
371
|
+
"sandbox backend; they never expose the host shell."
|
|
372
|
+
)
|
|
307
373
|
|
|
308
374
|
|
|
309
375
|
def get_sandbox_tools() -> list:
|
ksadk/toolsets/skills.py
CHANGED
|
@@ -18,15 +18,18 @@ from ksadk.skills.service_env import (
|
|
|
18
18
|
user_skill_space_ids,
|
|
19
19
|
)
|
|
20
20
|
from ksadk.skills.tool_defs import (
|
|
21
|
-
|
|
21
|
+
_skill_manifest_item,
|
|
22
22
|
load_remote_skill_manifests,
|
|
23
23
|
resolve_skill_space_ids,
|
|
24
24
|
)
|
|
25
|
+
from ksadk.skills.tool_defs import (
|
|
26
|
+
build_execute_skills_tool as build_runtime_execute_skills_tool,
|
|
27
|
+
)
|
|
25
28
|
from ksadk.tools.gateway import ToolPolicy, default_tool_gateway
|
|
26
29
|
from ksadk.toolsets._langchain import as_tool
|
|
27
30
|
|
|
28
|
-
|
|
29
31
|
_SKILL_TOOL_POLICIES = {
|
|
32
|
+
"list_skill_spaces": ToolPolicy(risk_level="low"),
|
|
30
33
|
"list_skills": ToolPolicy(risk_level="low"),
|
|
31
34
|
"search_skills": ToolPolicy(risk_level="low"),
|
|
32
35
|
"load_skill": ToolPolicy(risk_level="low", side_effects=("skill_cache_write",)),
|
|
@@ -38,27 +41,132 @@ def _gateway():
|
|
|
38
41
|
return default_tool_gateway(_SKILL_TOOL_POLICIES)
|
|
39
42
|
|
|
40
43
|
|
|
41
|
-
def
|
|
42
|
-
|
|
44
|
+
def _dict_result(value: Any, *, tool_name: str) -> dict[str, Any]:
|
|
45
|
+
if not isinstance(value, dict):
|
|
46
|
+
raise TypeError(f"{tool_name} returned {type(value).__name__}, expected dict")
|
|
47
|
+
return dict(value)
|
|
48
|
+
|
|
43
49
|
|
|
50
|
+
def list_skill_spaces() -> dict[str, Any]:
|
|
51
|
+
"""List visible Skill Spaces with id/name/description, so the model can pick one by intent.
|
|
52
|
+
|
|
53
|
+
多 space 场景下,先调用本工具了解可选 space,再按用户意图用
|
|
54
|
+
``search_skills(query, space_id=...)`` 或 ``load_skill(name, space_id=...)`` 定向查找。
|
|
55
|
+
"""
|
|
56
|
+
|
|
57
|
+
configured = resolve_skill_space_ids()
|
|
44
58
|
try:
|
|
45
|
-
|
|
59
|
+
client = _skill_service_client()
|
|
60
|
+
payload = client.list_skill_spaces()
|
|
61
|
+
spaces = _parse_skill_spaces(payload)
|
|
62
|
+
configured_set = set(configured)
|
|
63
|
+
for space in spaces:
|
|
64
|
+
space["configured"] = space["space_id"] in configured_set
|
|
65
|
+
if not spaces:
|
|
66
|
+
# 服务不支持 ListSkillSpaces 时,退化为返回已配置的 space id。
|
|
67
|
+
spaces = [
|
|
68
|
+
{"space_id": sid, "space_name": "", "description": "", "configured": True}
|
|
69
|
+
for sid in configured
|
|
70
|
+
]
|
|
71
|
+
return {
|
|
72
|
+
"ok": True,
|
|
73
|
+
"configured_space_ids": configured,
|
|
74
|
+
"spaces": spaces,
|
|
75
|
+
"usage": (
|
|
76
|
+
"根据用户意图从这些 space 中选一个 space_id,再用 "
|
|
77
|
+
"search_skills(query, space_id=...) 在该 space 内搜索,或用 "
|
|
78
|
+
"load_skill(skill_name, space_id=...) 精确加载该 space 下的 skill。"
|
|
79
|
+
),
|
|
80
|
+
}
|
|
81
|
+
except Exception as exc:
|
|
82
|
+
return {
|
|
83
|
+
"ok": False,
|
|
84
|
+
"error_type": type(exc).__name__,
|
|
85
|
+
"error_message": str(exc),
|
|
86
|
+
"configured_space_ids": configured,
|
|
87
|
+
"spaces": [
|
|
88
|
+
{"space_id": sid, "space_name": "", "description": "", "configured": True}
|
|
89
|
+
for sid in configured
|
|
90
|
+
],
|
|
91
|
+
}
|
|
92
|
+
|
|
93
|
+
|
|
94
|
+
def _parse_skill_spaces(payload: dict[str, Any]) -> list[dict[str, Any]]:
|
|
95
|
+
data = payload.get("Data") or payload.get("data") or {}
|
|
96
|
+
raw = (
|
|
97
|
+
data.get("SkillSpaces")
|
|
98
|
+
or data.get("skill_spaces")
|
|
99
|
+
or data.get("Spaces")
|
|
100
|
+
or data.get("spaces")
|
|
101
|
+
or data.get("Items")
|
|
102
|
+
or data.get("items")
|
|
103
|
+
or []
|
|
104
|
+
)
|
|
105
|
+
spaces: list[dict[str, Any]] = []
|
|
106
|
+
for item in raw:
|
|
107
|
+
if not isinstance(item, dict):
|
|
108
|
+
continue
|
|
109
|
+
spaces.append(
|
|
110
|
+
{
|
|
111
|
+
"space_id": str(
|
|
112
|
+
item.get("SkillSpaceId")
|
|
113
|
+
or item.get("skill_space_id")
|
|
114
|
+
or item.get("SpaceId")
|
|
115
|
+
or item.get("space_id")
|
|
116
|
+
or ""
|
|
117
|
+
),
|
|
118
|
+
"space_name": str(
|
|
119
|
+
item.get("SkillSpaceName")
|
|
120
|
+
or item.get("skill_space_name")
|
|
121
|
+
or item.get("SpaceName")
|
|
122
|
+
or item.get("space_name")
|
|
123
|
+
or ""
|
|
124
|
+
),
|
|
125
|
+
"description": str(item.get("Description") or item.get("description") or ""),
|
|
126
|
+
}
|
|
127
|
+
)
|
|
128
|
+
return spaces
|
|
129
|
+
|
|
130
|
+
|
|
131
|
+
def list_skills(space_id: str | None = None) -> dict[str, Any]:
|
|
132
|
+
"""List skills discoverable from configured Skill Spaces, optionally limited to one space.
|
|
133
|
+
|
|
134
|
+
``space_id`` 指定时只列该 space(user space id 或 ``"public"``);缺省列出全部已配置 space。
|
|
135
|
+
"""
|
|
136
|
+
|
|
137
|
+
space_ids = [space_id] if space_id else resolve_skill_space_ids()
|
|
138
|
+
try:
|
|
139
|
+
if space_id:
|
|
140
|
+
client = _skill_service_client()
|
|
141
|
+
manifests = [
|
|
142
|
+
_skill_manifest_item(skill, space_id=sid)
|
|
143
|
+
for sid, skill in _iter_remote_skills(client, space_id=space_id)
|
|
144
|
+
if skill.name
|
|
145
|
+
]
|
|
146
|
+
else:
|
|
147
|
+
manifests = load_remote_skill_manifests(space_ids)
|
|
46
148
|
return {
|
|
47
149
|
"ok": True,
|
|
48
150
|
"skills": manifests,
|
|
49
|
-
"skill_space_ids":
|
|
151
|
+
"skill_space_ids": space_ids,
|
|
152
|
+
"space_id": space_id,
|
|
50
153
|
}
|
|
51
154
|
except Exception as exc:
|
|
52
155
|
return {
|
|
53
156
|
"ok": False,
|
|
54
157
|
"error_type": type(exc).__name__,
|
|
55
158
|
"error_message": str(exc),
|
|
56
|
-
"skill_space_ids":
|
|
159
|
+
"skill_space_ids": space_ids,
|
|
160
|
+
"space_id": space_id,
|
|
57
161
|
}
|
|
58
162
|
|
|
59
163
|
|
|
60
|
-
def load_skill(skill_name: str) -> dict[str, Any]:
|
|
61
|
-
"""Download and load a skill's SKILL.md instructions from configured Skill Spaces.
|
|
164
|
+
def load_skill(skill_name: str, space_id: str | None = None) -> dict[str, Any]:
|
|
165
|
+
"""Download and load a skill's SKILL.md instructions from configured Skill Spaces.
|
|
166
|
+
|
|
167
|
+
``space_id`` 指定时只在该 space 内按名匹配,用于多 space 下精确定位、避免同名冲突;
|
|
168
|
+
缺省按配置顺序(user space 优先于 public)取第一个匹配。
|
|
169
|
+
"""
|
|
62
170
|
|
|
63
171
|
target = str(skill_name or "").strip().lower()
|
|
64
172
|
if not target:
|
|
@@ -66,7 +174,7 @@ def load_skill(skill_name: str) -> dict[str, Any]:
|
|
|
66
174
|
try:
|
|
67
175
|
client = _skill_service_client()
|
|
68
176
|
available: list[str] = []
|
|
69
|
-
for
|
|
177
|
+
for sid, skill in _iter_remote_skills(client, space_id=space_id):
|
|
70
178
|
if not skill.name:
|
|
71
179
|
continue
|
|
72
180
|
available.append(skill.name)
|
|
@@ -79,7 +187,7 @@ def load_skill(skill_name: str) -> dict[str, Any]:
|
|
|
79
187
|
"execution_context": "outer_agent",
|
|
80
188
|
"name": local_skill.name,
|
|
81
189
|
"description": local_skill.description,
|
|
82
|
-
"space_id":
|
|
190
|
+
"space_id": sid,
|
|
83
191
|
"skill_id": skill.skill_id,
|
|
84
192
|
"version_id": skill.version_id,
|
|
85
193
|
"version": skill.version,
|
|
@@ -88,31 +196,52 @@ def load_skill(skill_name: str) -> dict[str, Any]:
|
|
|
88
196
|
"has_scripts_dir": (local_skill.root_dir / "scripts").is_dir(),
|
|
89
197
|
"script_files": _script_files(local_skill.root_dir),
|
|
90
198
|
"instructions": local_skill.body,
|
|
91
|
-
"usage":
|
|
199
|
+
"usage": (
|
|
200
|
+
"Read these instructions and complete the user's task in the outer "
|
|
201
|
+
"agent unless the skill explicitly requires isolated execution."
|
|
202
|
+
),
|
|
92
203
|
}
|
|
93
204
|
return {
|
|
94
205
|
"ok": False,
|
|
95
206
|
"error_message": f"Skill not found: {skill_name}",
|
|
207
|
+
"space_id": space_id,
|
|
96
208
|
"available_skills": available,
|
|
97
209
|
}
|
|
98
210
|
except Exception as exc:
|
|
99
211
|
return {"ok": False, "error_type": type(exc).__name__, "error_message": str(exc)}
|
|
100
212
|
|
|
101
213
|
|
|
102
|
-
def search_skills(query: str, max_results: int = 10) -> dict[str, Any]:
|
|
103
|
-
"""Search skills by name, aliases, tags, description, and examples.
|
|
214
|
+
def search_skills(query: str, max_results: int = 10, space_id: str | None = None) -> dict[str, Any]:
|
|
215
|
+
"""Search skills by name, aliases, tags, description, and examples.
|
|
216
|
+
|
|
217
|
+
``space_id`` 指定时只在该 space 内搜索;缺省聚合全部已配置 space。结果带 ``space_id``,
|
|
218
|
+
便于后续 ``load_skill(name, space_id=...)`` 精确定位。
|
|
219
|
+
"""
|
|
104
220
|
|
|
105
221
|
query_text = str(query or "").strip()
|
|
106
222
|
if not query_text:
|
|
107
223
|
return {"ok": False, "error_message": "query is required"}
|
|
108
224
|
try:
|
|
109
225
|
client = _skill_service_client()
|
|
110
|
-
|
|
226
|
+
pairs = list(_iter_remote_skills(client, space_id=space_id))
|
|
227
|
+
# 建立 skill 标识 -> space_id 映射,给结果回填来源 space(cache_key 与 match 去重一致)。
|
|
228
|
+
space_of: dict[str, str] = {}
|
|
229
|
+
for sid, skill in pairs:
|
|
230
|
+
space_of.setdefault(skill.cache_key or skill.skill_id or skill.name, sid)
|
|
231
|
+
refs = [skill for _, skill in pairs]
|
|
111
232
|
matches = match_skill_refs(refs, query_text, limit=max_results)
|
|
233
|
+
results = []
|
|
234
|
+
for match in matches:
|
|
235
|
+
item = match.to_dict()
|
|
236
|
+
item["space_id"] = space_of.get(
|
|
237
|
+
match.skill.cache_key or match.skill.skill_id or match.skill.name, ""
|
|
238
|
+
)
|
|
239
|
+
results.append(item)
|
|
112
240
|
return {
|
|
113
241
|
"ok": True,
|
|
114
242
|
"query": query,
|
|
115
|
-
"
|
|
243
|
+
"space_id": space_id,
|
|
244
|
+
"results": results,
|
|
116
245
|
}
|
|
117
246
|
except Exception as exc:
|
|
118
247
|
return {"ok": False, "error_type": type(exc).__name__, "error_message": str(exc)}
|
|
@@ -125,43 +254,64 @@ def execute_skills(
|
|
|
125
254
|
) -> dict[str, Any]:
|
|
126
255
|
"""Execute a workflow through the configured Skill Runtime."""
|
|
127
256
|
|
|
128
|
-
return
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
257
|
+
return _dict_result(
|
|
258
|
+
_gateway().invoke(
|
|
259
|
+
"execute_skills",
|
|
260
|
+
_execute_skills_impl,
|
|
261
|
+
workflow_prompt,
|
|
262
|
+
skill_names,
|
|
263
|
+
approval=approval,
|
|
264
|
+
),
|
|
265
|
+
tool_name="execute_skills",
|
|
134
266
|
)
|
|
135
267
|
|
|
136
268
|
|
|
137
|
-
def _execute_skills_impl(
|
|
269
|
+
def _execute_skills_impl(
|
|
270
|
+
workflow_prompt: str, skill_names: list[str] | str | None = None
|
|
271
|
+
) -> dict[str, Any]:
|
|
138
272
|
try:
|
|
139
273
|
backend = create_skill_runtime_backend()
|
|
140
274
|
raw_tool = build_runtime_execute_skills_tool(backend=backend)
|
|
141
275
|
result = raw_tool(workflow_prompt, skill_names)
|
|
142
|
-
if isinstance(result, dict):
|
|
143
|
-
|
|
144
|
-
|
|
276
|
+
if not isinstance(result, dict):
|
|
277
|
+
return {
|
|
278
|
+
"ok": False,
|
|
279
|
+
"error_type": "invalid_skill_runtime_result",
|
|
280
|
+
"error_message": (f"skill runtime returned {type(result).__name__}, expected dict"),
|
|
281
|
+
}
|
|
282
|
+
result.setdefault("execution_context", f"skill-runtime/{_skill_execution_backend()}")
|
|
283
|
+
return dict(result)
|
|
145
284
|
except SkillRuntimeError as exc:
|
|
146
285
|
return {
|
|
147
286
|
"ok": False,
|
|
148
287
|
"error_type": "skill_runtime_disabled",
|
|
149
288
|
"error_message": str(exc),
|
|
150
|
-
"hint":
|
|
289
|
+
"hint": (
|
|
290
|
+
"Configure KSADK_SKILL_RUNTIME_BACKEND=local_process/e2b or "
|
|
291
|
+
"KSADK_SANDBOX_TEMPLATE_ID for isolated Skill workflow execution."
|
|
292
|
+
),
|
|
151
293
|
}
|
|
152
294
|
except Exception as exc:
|
|
153
295
|
return {"ok": False, "error_type": type(exc).__name__, "error_message": str(exc)}
|
|
154
296
|
|
|
155
297
|
|
|
156
298
|
def get_skill_tools() -> list:
|
|
157
|
-
return [
|
|
299
|
+
return [
|
|
300
|
+
as_tool(list_skills),
|
|
301
|
+
as_tool(list_skill_spaces),
|
|
302
|
+
as_tool(search_skills),
|
|
303
|
+
as_tool(load_skill),
|
|
304
|
+
as_tool(execute_skills),
|
|
305
|
+
]
|
|
158
306
|
|
|
159
307
|
|
|
160
308
|
def _skill_execution_backend() -> str:
|
|
161
309
|
explicit = os.environ.get("KSADK_SKILL_RUNTIME_BACKEND", "").strip().lower()
|
|
162
310
|
if explicit:
|
|
163
311
|
return explicit
|
|
164
|
-
if os.environ.get("KSADK_SANDBOX_TEMPLATE_ID") or os.environ.get(
|
|
312
|
+
if os.environ.get("KSADK_SANDBOX_TEMPLATE_ID") or os.environ.get(
|
|
313
|
+
"KSADK_SKILL_RUNTIME_TEMPLATE_ID"
|
|
314
|
+
):
|
|
165
315
|
return "e2b"
|
|
166
316
|
return "disabled"
|
|
167
317
|
|
|
@@ -177,21 +327,34 @@ def _skill_service_client() -> SkillServiceClient:
|
|
|
177
327
|
)
|
|
178
328
|
|
|
179
329
|
|
|
180
|
-
def
|
|
181
|
-
|
|
330
|
+
def _iter_space_skills(client: SkillServiceClient, space_id: str):
|
|
331
|
+
"""遍历单个 space 的 active skill;space_id="public" 走 premade 列表。"""
|
|
332
|
+
|
|
333
|
+
if space_id == "public":
|
|
334
|
+
listing = client.list_available_premade_skills()
|
|
335
|
+
for skill in select_public_skill_refs(listing.active_skills()):
|
|
336
|
+
yield listing.space_id or "public", skill
|
|
337
|
+
else:
|
|
182
338
|
listing = client.list_skills_by_space_id(space_id)
|
|
183
339
|
for skill in listing.active_skills():
|
|
184
340
|
yield space_id, skill
|
|
341
|
+
|
|
342
|
+
|
|
343
|
+
def _iter_remote_skills(client: SkillServiceClient, space_id: str | None = None):
|
|
344
|
+
"""遍历配置的 space;space_id 指定时只遍历该 space(user 或 "public")。"""
|
|
345
|
+
|
|
346
|
+
if space_id:
|
|
347
|
+
yield from _iter_space_skills(client, space_id)
|
|
348
|
+
return
|
|
349
|
+
for user_space_id in user_skill_space_ids():
|
|
350
|
+
yield from _iter_space_skills(client, user_space_id)
|
|
185
351
|
if public_skill_space_ids():
|
|
186
|
-
|
|
187
|
-
for skill in select_public_skill_refs(listing.active_skills()):
|
|
188
|
-
yield listing.space_id or "public", skill
|
|
352
|
+
yield from _iter_space_skills(client, "public")
|
|
189
353
|
|
|
190
354
|
|
|
191
355
|
def _get_or_download_package(client: SkillServiceClient, skill):
|
|
192
356
|
cache_dir = Path(
|
|
193
|
-
os.environ.get("KSADK_SKILL_CACHE_DIR")
|
|
194
|
-
or Path(tempfile.gettempdir()) / "ksadk-skill-cache"
|
|
357
|
+
os.environ.get("KSADK_SKILL_CACHE_DIR") or Path(tempfile.gettempdir()) / "ksadk-skill-cache"
|
|
195
358
|
)
|
|
196
359
|
store = PackageStore(cache_dir=cache_dir)
|
|
197
360
|
package = store.get_cached(skill)
|
|
@@ -211,7 +374,5 @@ def _script_files(root_dir: Path) -> list[str]:
|
|
|
211
374
|
if not scripts_dir.is_dir():
|
|
212
375
|
return []
|
|
213
376
|
return [
|
|
214
|
-
str(path.relative_to(root_dir))
|
|
215
|
-
for path in sorted(scripts_dir.rglob("*"))
|
|
216
|
-
if path.is_file()
|
|
377
|
+
str(path.relative_to(root_dir)) for path in sorted(scripts_dir.rglob("*")) if path.is_file()
|
|
217
378
|
][:20]
|