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/tools/gateway.py
CHANGED
|
@@ -1,19 +1,28 @@
|
|
|
1
1
|
from __future__ import annotations
|
|
2
2
|
|
|
3
|
-
import os
|
|
4
3
|
import hashlib
|
|
5
4
|
import json
|
|
5
|
+
import os
|
|
6
6
|
import shlex
|
|
7
7
|
from collections.abc import Callable, Mapping, Sequence
|
|
8
8
|
from dataclasses import dataclass, field
|
|
9
9
|
from typing import Any
|
|
10
10
|
from uuid import uuid4
|
|
11
11
|
|
|
12
|
+
from ksadk.runtime_context import get_current_invocation_context
|
|
13
|
+
|
|
12
14
|
|
|
13
15
|
@dataclass(frozen=True)
|
|
14
16
|
class ToolPolicy:
|
|
15
17
|
risk_level: str = "low"
|
|
16
18
|
side_effects: Sequence[str] = field(default_factory=tuple)
|
|
19
|
+
# Approval scopes classify operations which might need an interactive
|
|
20
|
+
# decision. ``public_network`` is intentionally a read-only exception:
|
|
21
|
+
# web discovery must remain available in every approval profile.
|
|
22
|
+
approval_scopes: Sequence[str] = field(default_factory=tuple)
|
|
23
|
+
# Use only for tools whose operation is inherently safe to run without a
|
|
24
|
+
# human decision. This wins over a risk level or explicit legacy policy.
|
|
25
|
+
approval_exempt: bool = False
|
|
17
26
|
requires_approval: bool | None = None
|
|
18
27
|
|
|
19
28
|
|
|
@@ -50,8 +59,9 @@ class ToolGateway:
|
|
|
50
59
|
|
|
51
60
|
@staticmethod
|
|
52
61
|
def _approval_mode() -> str:
|
|
53
|
-
|
|
54
|
-
|
|
62
|
+
context = get_current_invocation_context()
|
|
63
|
+
requested_mode = context.tool_approval_mode if context is not None else None
|
|
64
|
+
return normalize_tool_approval_mode(requested_mode)
|
|
55
65
|
|
|
56
66
|
@staticmethod
|
|
57
67
|
def _is_approved(approval: Mapping[str, Any] | None) -> bool:
|
|
@@ -108,24 +118,76 @@ def tool_policy_requires_approval(
|
|
|
108
118
|
*,
|
|
109
119
|
approval_mode: str | None = None,
|
|
110
120
|
) -> bool:
|
|
111
|
-
mode = (approval_mode
|
|
121
|
+
mode = normalize_tool_approval_mode(approval_mode)
|
|
122
|
+
if policy.approval_exempt or _is_read_only_public_network_policy(policy):
|
|
123
|
+
return False
|
|
112
124
|
if policy.requires_approval is not None:
|
|
113
|
-
return policy.requires_approval and mode != "
|
|
114
|
-
if mode
|
|
125
|
+
return policy.requires_approval and mode != "full"
|
|
126
|
+
if mode == "full":
|
|
115
127
|
return False
|
|
128
|
+
if mode == "ask" and policy.approval_scopes:
|
|
129
|
+
return True
|
|
116
130
|
return policy.risk_level.lower() in {"medium", "high", "critical"}
|
|
117
131
|
|
|
118
132
|
|
|
133
|
+
def _is_read_only_public_network_policy(policy: ToolPolicy) -> bool:
|
|
134
|
+
"""Keep public web reads available even under the most cautious profile.
|
|
135
|
+
|
|
136
|
+
A network write must declare a side effect, so it does not match this
|
|
137
|
+
exemption and can still require approval.
|
|
138
|
+
"""
|
|
139
|
+
return bool(policy.approval_scopes) and set(policy.approval_scopes) <= {
|
|
140
|
+
"public_network"
|
|
141
|
+
} and not policy.side_effects
|
|
142
|
+
|
|
143
|
+
|
|
144
|
+
def normalize_tool_approval_mode(value: str | None = None) -> str:
|
|
145
|
+
"""Resolve the compact runtime approval profile.
|
|
146
|
+
|
|
147
|
+
``ask`` confirms risky and non-network scoped operations; ``risk``
|
|
148
|
+
confirms medium-and-higher risk only; ``full`` leaves default policies
|
|
149
|
+
unprompted. Public web reads remain approval-free in every profile. The
|
|
150
|
+
process environment remains a default for non-UI callers, while a
|
|
151
|
+
request-scoped mode wins for the duration of that invocation.
|
|
152
|
+
"""
|
|
153
|
+
raw = str(value or os.environ.get("KSADK_TOOL_APPROVAL_MODE", "risk")).strip().lower()
|
|
154
|
+
return raw if raw in {"ask", "risk", "full"} else "risk"
|
|
155
|
+
|
|
156
|
+
|
|
157
|
+
def tool_approval_capability() -> dict[str, Any]:
|
|
158
|
+
"""Describe the single profile interface exposed to hosted UIs."""
|
|
159
|
+
return {
|
|
160
|
+
"Modes": ["ask", "risk", "full"],
|
|
161
|
+
"DefaultMode": normalize_tool_approval_mode(),
|
|
162
|
+
"RuntimeOverride": True,
|
|
163
|
+
}
|
|
164
|
+
|
|
165
|
+
|
|
119
166
|
def check_command_policy(command: str) -> dict[str, Any]:
|
|
120
167
|
text = str(command or "").strip()
|
|
121
168
|
if not text:
|
|
122
|
-
return {
|
|
169
|
+
return {
|
|
170
|
+
"ok": False,
|
|
171
|
+
"decision": "reject",
|
|
172
|
+
"error_type": "command_required",
|
|
173
|
+
"error_message": "command is required",
|
|
174
|
+
}
|
|
123
175
|
try:
|
|
124
176
|
tokens = shlex.split(text)
|
|
125
177
|
except ValueError as exc:
|
|
126
|
-
return {
|
|
178
|
+
return {
|
|
179
|
+
"ok": False,
|
|
180
|
+
"decision": "reject",
|
|
181
|
+
"error_type": "invalid_command",
|
|
182
|
+
"error_message": str(exc),
|
|
183
|
+
}
|
|
127
184
|
if not tokens:
|
|
128
|
-
return {
|
|
185
|
+
return {
|
|
186
|
+
"ok": False,
|
|
187
|
+
"decision": "reject",
|
|
188
|
+
"error_type": "command_required",
|
|
189
|
+
"error_message": "command is required",
|
|
190
|
+
}
|
|
129
191
|
if _contains_recursive_rm(tokens):
|
|
130
192
|
return _command_rejected("recursive rm is not allowed without explicit approval")
|
|
131
193
|
if any(token in _DANGEROUS_COMMAND_TOKENS for token in tokens):
|
|
@@ -137,12 +199,19 @@ def check_command_policy(command: str) -> dict[str, Any]:
|
|
|
137
199
|
if subcommand in _DANGEROUS_GIT_COMMANDS:
|
|
138
200
|
return _command_rejected(f"git {subcommand} is not allowed without explicit approval")
|
|
139
201
|
if _references_metadata_endpoint(tokens):
|
|
140
|
-
return _command_rejected(
|
|
202
|
+
return _command_rejected(
|
|
203
|
+
"metadata/private endpoint access is not allowed by default policy"
|
|
204
|
+
)
|
|
141
205
|
return {"ok": True, "decision": "allow", "reason": "default_allow"}
|
|
142
206
|
|
|
143
207
|
|
|
144
208
|
def _command_rejected(message: str) -> dict[str, Any]:
|
|
145
|
-
return {
|
|
209
|
+
return {
|
|
210
|
+
"ok": False,
|
|
211
|
+
"decision": "reject",
|
|
212
|
+
"error_type": "command_rejected",
|
|
213
|
+
"error_message": message,
|
|
214
|
+
}
|
|
146
215
|
|
|
147
216
|
|
|
148
217
|
def _contains_recursive_rm(tokens: Sequence[str]) -> bool:
|
|
@@ -162,7 +231,9 @@ def _references_metadata_endpoint(tokens: Sequence[str]) -> bool:
|
|
|
162
231
|
|
|
163
232
|
def _canonical_tool_args(tool_args: Any) -> str:
|
|
164
233
|
try:
|
|
165
|
-
return json.dumps(
|
|
234
|
+
return json.dumps(
|
|
235
|
+
tool_args or {}, ensure_ascii=False, sort_keys=True, separators=(",", ":")
|
|
236
|
+
)
|
|
166
237
|
except TypeError:
|
|
167
238
|
return json.dumps(str(tool_args), ensure_ascii=False, separators=(",", ":"))
|
|
168
239
|
|
|
@@ -185,7 +256,9 @@ def build_tool_receipt_idempotency_key(
|
|
|
185
256
|
"tool_args": _canonical_tool_args(tool_args),
|
|
186
257
|
}
|
|
187
258
|
digest = hashlib.sha256(
|
|
188
|
-
json.dumps(payload, ensure_ascii=False, sort_keys=True, separators=(",", ":")).encode(
|
|
259
|
+
json.dumps(payload, ensure_ascii=False, sort_keys=True, separators=(",", ":")).encode(
|
|
260
|
+
"utf-8"
|
|
261
|
+
)
|
|
189
262
|
).hexdigest()
|
|
190
263
|
return f"tool_receipt:{digest}"
|
|
191
264
|
|
|
@@ -222,8 +295,12 @@ def approval_interrupt_info_from_result(
|
|
|
222
295
|
or {}
|
|
223
296
|
),
|
|
224
297
|
"risk_level": str(approval_request.get("risk_level") or result.get("risk_level") or ""),
|
|
225
|
-
"side_effects": list(
|
|
226
|
-
|
|
298
|
+
"side_effects": list(
|
|
299
|
+
approval_request.get("side_effects") or result.get("side_effects") or []
|
|
300
|
+
),
|
|
301
|
+
"server_label": str(
|
|
302
|
+
approval_request.get("server_label") or result.get("server_label") or "ksadk"
|
|
303
|
+
),
|
|
227
304
|
}
|
|
228
305
|
if run_id:
|
|
229
306
|
interrupt["run_id"] = str(run_id)
|
ksadk/tools/result_budget.py
CHANGED
|
@@ -10,7 +10,6 @@ from uuid import uuid4
|
|
|
10
10
|
|
|
11
11
|
from ksadk.sessions.local_service import resolve_local_session_dir
|
|
12
12
|
|
|
13
|
-
|
|
14
13
|
_SAFE_NAME_RE = re.compile(r"[^A-Za-z0-9_.-]+")
|
|
15
14
|
|
|
16
15
|
|
|
@@ -58,7 +57,10 @@ def budget_tool_output(
|
|
|
58
57
|
active_budget = budget or default_tool_result_budget()
|
|
59
58
|
text, mime_type, extension = _stringify_value(value)
|
|
60
59
|
original_chars = len(text)
|
|
61
|
-
should_persist =
|
|
60
|
+
should_persist = (
|
|
61
|
+
original_chars > active_budget.persist_threshold_chars
|
|
62
|
+
or original_chars > active_budget.max_chars
|
|
63
|
+
)
|
|
62
64
|
preview_limit = max(0, min(active_budget.preview_chars, active_budget.max_chars))
|
|
63
65
|
preview = text[:preview_limit] if should_persist else text[: active_budget.max_chars]
|
|
64
66
|
result: dict[str, Any] = {
|
|
@@ -126,7 +128,9 @@ def _persist_tool_output(
|
|
|
126
128
|
or metadata.get("id")
|
|
127
129
|
or uuid4().hex
|
|
128
130
|
)
|
|
129
|
-
stem = _safe_filename(f"{tool_use_id}.{field_name}") or _safe_filename(
|
|
131
|
+
stem = _safe_filename(f"{tool_use_id}.{field_name}") or _safe_filename(
|
|
132
|
+
f"{tool_name}.{field_name}.{uuid4().hex}"
|
|
133
|
+
)
|
|
130
134
|
path = (persist_dir / f"{stem}.{extension}").resolve()
|
|
131
135
|
if persist_dir not in path.parents and path != persist_dir:
|
|
132
136
|
raise ValueError("tool result path must stay inside persist_dir")
|
|
@@ -137,7 +141,11 @@ def _persist_tool_output(
|
|
|
137
141
|
def _stringify_value(value: Any) -> tuple[str, str, str]:
|
|
138
142
|
if isinstance(value, str):
|
|
139
143
|
return value, "text/plain", "txt"
|
|
140
|
-
return
|
|
144
|
+
return (
|
|
145
|
+
json.dumps(value, ensure_ascii=False, indent=2, sort_keys=True),
|
|
146
|
+
"application/json",
|
|
147
|
+
"json",
|
|
148
|
+
)
|
|
141
149
|
|
|
142
150
|
|
|
143
151
|
def _safe_filename(value: str) -> str:
|
ksadk/toolsets/__init__.py
CHANGED
|
@@ -3,34 +3,36 @@ from __future__ import annotations
|
|
|
3
3
|
import json
|
|
4
4
|
import os
|
|
5
5
|
import re
|
|
6
|
-
from collections.abc import Iterable
|
|
7
|
-
from collections.abc import Mapping
|
|
6
|
+
from collections.abc import Callable, Iterable, Mapping
|
|
8
7
|
from typing import Any
|
|
9
8
|
|
|
10
|
-
from ksadk.
|
|
11
|
-
from ksadk.toolsets.
|
|
12
|
-
from ksadk.toolsets.
|
|
9
|
+
from ksadk.tools.gateway import ToolPolicy, tool_policy_requires_approval
|
|
10
|
+
from ksadk.toolsets._langchain import as_tool
|
|
11
|
+
from ksadk.toolsets.platform import component_status, get_platform_tools
|
|
13
12
|
from ksadk.toolsets.sandbox import (
|
|
14
13
|
_SANDBOX_TOOL_POLICIES,
|
|
14
|
+
get_sandbox_tools,
|
|
15
15
|
run_code,
|
|
16
16
|
run_command,
|
|
17
17
|
sandbox_backend_name,
|
|
18
18
|
sandbox_status,
|
|
19
19
|
)
|
|
20
|
-
from ksadk.toolsets.skills import get_skill_tools
|
|
21
20
|
from ksadk.toolsets.skills import (
|
|
22
21
|
_SKILL_TOOL_POLICIES,
|
|
23
22
|
_skill_execution_backend,
|
|
24
23
|
execute_skills,
|
|
24
|
+
get_skill_tools,
|
|
25
|
+
list_skill_spaces,
|
|
25
26
|
list_skills,
|
|
26
27
|
load_skill,
|
|
27
28
|
search_skills,
|
|
28
29
|
)
|
|
29
|
-
from ksadk.toolsets.
|
|
30
|
+
from ksadk.toolsets.web import _WEB_TOOL_POLICIES, get_web_tools, web_fetch, web_search
|
|
30
31
|
from ksadk.toolsets.workspace import (
|
|
31
32
|
_WORKSPACE_TOOL_POLICIES,
|
|
32
33
|
delete_workspace_file,
|
|
33
34
|
edit_workspace_file,
|
|
35
|
+
get_workspace_tools,
|
|
34
36
|
lint_workspace_file,
|
|
35
37
|
list_workspace_files,
|
|
36
38
|
multi_edit_workspace_file,
|
|
@@ -40,10 +42,6 @@ from ksadk.toolsets.workspace import (
|
|
|
40
42
|
write_workspace_file,
|
|
41
43
|
write_workspace_files,
|
|
42
44
|
)
|
|
43
|
-
from ksadk.toolsets.web import get_web_tools
|
|
44
|
-
from ksadk.toolsets.web import web_fetch, web_search, _WEB_TOOL_POLICIES
|
|
45
|
-
from ksadk.tools.gateway import ToolPolicy, tool_policy_requires_approval
|
|
46
|
-
from ksadk.toolsets._langchain import as_tool
|
|
47
45
|
|
|
48
46
|
_DEFAULT_GROUPS = ("skill", "workspace", "platform", "sandbox", "web")
|
|
49
47
|
_DISPATCHER_TOOL_NAME = "tool_dispatcher"
|
|
@@ -79,9 +77,12 @@ _TOOLSET_FACTORIES = {
|
|
|
79
77
|
"web": get_web_tools,
|
|
80
78
|
}
|
|
81
79
|
|
|
82
|
-
_TOOLSET_DESCRIPTORS
|
|
80
|
+
_TOOLSET_DESCRIPTORS: dict[
|
|
81
|
+
str, tuple[tuple[Callable[..., Any], ToolPolicy, dict[str, Any]], ...]
|
|
82
|
+
] = {
|
|
83
83
|
"skill": (
|
|
84
84
|
(list_skills, _SKILL_TOOL_POLICIES["list_skills"], {}),
|
|
85
|
+
(list_skill_spaces, _SKILL_TOOL_POLICIES["list_skill_spaces"], {}),
|
|
85
86
|
(search_skills, _SKILL_TOOL_POLICIES["search_skills"], {}),
|
|
86
87
|
(load_skill, _SKILL_TOOL_POLICIES["load_skill"], {}),
|
|
87
88
|
(
|
|
@@ -95,20 +96,58 @@ _TOOLSET_DESCRIPTORS = {
|
|
|
95
96
|
),
|
|
96
97
|
),
|
|
97
98
|
"workspace": (
|
|
98
|
-
(
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
(
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
99
|
+
(
|
|
100
|
+
workspace_status,
|
|
101
|
+
_WORKSPACE_TOOL_POLICIES["workspace_status"],
|
|
102
|
+
{"boundary": "workspace_root"},
|
|
103
|
+
),
|
|
104
|
+
(
|
|
105
|
+
list_workspace_files,
|
|
106
|
+
_WORKSPACE_TOOL_POLICIES["list_workspace_files"],
|
|
107
|
+
{"boundary": "workspace_root"},
|
|
108
|
+
),
|
|
109
|
+
(
|
|
110
|
+
read_workspace_file,
|
|
111
|
+
_WORKSPACE_TOOL_POLICIES["read_workspace_file"],
|
|
112
|
+
{"boundary": "workspace_root"},
|
|
113
|
+
),
|
|
114
|
+
(
|
|
115
|
+
write_workspace_file,
|
|
116
|
+
_WORKSPACE_TOOL_POLICIES["write_workspace_file"],
|
|
117
|
+
{"boundary": "workspace_root"},
|
|
118
|
+
),
|
|
119
|
+
(
|
|
120
|
+
write_workspace_files,
|
|
121
|
+
_WORKSPACE_TOOL_POLICIES["write_workspace_files"],
|
|
122
|
+
{"boundary": "workspace_root"},
|
|
123
|
+
),
|
|
124
|
+
(
|
|
125
|
+
edit_workspace_file,
|
|
126
|
+
_WORKSPACE_TOOL_POLICIES["edit_workspace_file"],
|
|
127
|
+
{"boundary": "workspace_root"},
|
|
128
|
+
),
|
|
129
|
+
(
|
|
130
|
+
multi_edit_workspace_file,
|
|
131
|
+
_WORKSPACE_TOOL_POLICIES["multi_edit_workspace_file"],
|
|
132
|
+
{"boundary": "workspace_root"},
|
|
133
|
+
),
|
|
134
|
+
(
|
|
135
|
+
lint_workspace_file,
|
|
136
|
+
_WORKSPACE_TOOL_POLICIES["lint_workspace_file"],
|
|
137
|
+
{"boundary": "workspace_root"},
|
|
138
|
+
),
|
|
139
|
+
(
|
|
140
|
+
search_workspace_files,
|
|
141
|
+
_WORKSPACE_TOOL_POLICIES["search_workspace_files"],
|
|
142
|
+
{"boundary": "workspace_root"},
|
|
143
|
+
),
|
|
144
|
+
(
|
|
145
|
+
delete_workspace_file,
|
|
146
|
+
_WORKSPACE_TOOL_POLICIES["delete_workspace_file"],
|
|
147
|
+
{"boundary": "workspace_root"},
|
|
148
|
+
),
|
|
111
149
|
),
|
|
150
|
+
"platform": ((component_status, ToolPolicy(risk_level="low"), {}),),
|
|
112
151
|
"sandbox": (
|
|
113
152
|
(
|
|
114
153
|
sandbox_status,
|
|
@@ -218,9 +257,38 @@ def tool_dispatcher(
|
|
|
218
257
|
include: str | Iterable[str] | None = None,
|
|
219
258
|
profile: str = "default",
|
|
220
259
|
) -> dict[str, Any]:
|
|
221
|
-
"""List, describe, or call ksadk built-in tools through one governed entrypoint.
|
|
260
|
+
"""List, describe, or call ksadk built-in tools through one governed entrypoint.
|
|
261
|
+
|
|
262
|
+
Args:
|
|
263
|
+
action: One of "list" (list available tools), "describe" (get a tool's
|
|
264
|
+
spec), or "call" (execute a tool). Common synonyms "call_tool",
|
|
265
|
+
"execute", "run" are auto-mapped to "call"; "get" to "describe".
|
|
266
|
+
tool_name: Required for "describe" and "call"; ignored for "list".
|
|
267
|
+
arguments: Tool arguments (dict or JSON string); used with "call".
|
|
268
|
+
include: Comma-separated tool groups to scope (e.g. "skill,sandbox").
|
|
269
|
+
profile: Tool profile name (default: "default").
|
|
270
|
+
"""
|
|
222
271
|
|
|
223
272
|
normalized_action = str(action or "").strip().lower()
|
|
273
|
+
# 兼容 LLM 常见同义词,避免 "call_tool"/"execute"/"run" 等导致 unknown_action。
|
|
274
|
+
_ACTION_SYNONYMS = {
|
|
275
|
+
"call_tool": "call",
|
|
276
|
+
"execute": "call",
|
|
277
|
+
"run": "call",
|
|
278
|
+
"invoke": "call",
|
|
279
|
+
"get": "describe",
|
|
280
|
+
"info": "describe",
|
|
281
|
+
"ls": "list",
|
|
282
|
+
"search": "list",
|
|
283
|
+
}
|
|
284
|
+
normalized_action = _ACTION_SYNONYMS.get(normalized_action, normalized_action)
|
|
285
|
+
# LLM 常把 tool_name 塞进 action(如 "list_skills"/"search_skills"/"run_command")。
|
|
286
|
+
# 如果 action 不是合法值,无论 tool_name 是否有值,都自动当成 "call":
|
|
287
|
+
# 有 tool_name → 直接 call; 无 tool_name → 把 action 值当 tool_name 再 call。
|
|
288
|
+
if normalized_action not in ("list", "describe", "call"):
|
|
289
|
+
if not tool_name:
|
|
290
|
+
tool_name = normalized_action
|
|
291
|
+
normalized_action = "call"
|
|
224
292
|
requested_include = _normalize_include(include)
|
|
225
293
|
|
|
226
294
|
if normalized_action == "list":
|
|
@@ -231,17 +299,25 @@ def tool_dispatcher(
|
|
|
231
299
|
include_dispatcher=False,
|
|
232
300
|
)
|
|
233
301
|
except ValueError:
|
|
234
|
-
return _unknown_tool_error(
|
|
302
|
+
return _unknown_tool_error(
|
|
303
|
+
", ".join(requested_include) if requested_include else str(include or "")
|
|
304
|
+
)
|
|
235
305
|
return {"ok": True, "tools": specs, "tool_count": len(specs)}
|
|
236
306
|
|
|
237
307
|
if normalized_action == "describe":
|
|
238
308
|
target_name = _normalize_tool_name(tool_name)
|
|
239
309
|
if not target_name:
|
|
240
|
-
return {
|
|
310
|
+
return {
|
|
311
|
+
"ok": False,
|
|
312
|
+
"error_type": "missing_tool_name",
|
|
313
|
+
"error_message": "tool_name is required",
|
|
314
|
+
}
|
|
241
315
|
if target_name in {_DISPATCHER_TOOL_NAME, _LEGACY_DISPATCHER_TOOL_NAME}:
|
|
242
316
|
return _dispatcher_self_call_error()
|
|
243
317
|
try:
|
|
244
|
-
_, specs = _select_agentengine_tools(
|
|
318
|
+
_, specs = _select_agentengine_tools(
|
|
319
|
+
include=[target_name], profile=profile, include_dispatcher=False
|
|
320
|
+
)
|
|
245
321
|
except ValueError:
|
|
246
322
|
return _unknown_tool_error(target_name)
|
|
247
323
|
return {"ok": True, "tool": specs[0]}
|
|
@@ -249,15 +325,26 @@ def tool_dispatcher(
|
|
|
249
325
|
if normalized_action == "call":
|
|
250
326
|
target_name = _normalize_tool_name(tool_name)
|
|
251
327
|
if not target_name:
|
|
252
|
-
return {
|
|
328
|
+
return {
|
|
329
|
+
"ok": False,
|
|
330
|
+
"error_type": "missing_tool_name",
|
|
331
|
+
"error_message": "tool_name is required",
|
|
332
|
+
}
|
|
253
333
|
if target_name in {_DISPATCHER_TOOL_NAME, _LEGACY_DISPATCHER_TOOL_NAME}:
|
|
254
334
|
return _dispatcher_self_call_error()
|
|
255
335
|
try:
|
|
256
|
-
tools, specs = _select_agentengine_tools(
|
|
336
|
+
tools, specs = _select_agentengine_tools(
|
|
337
|
+
include=[target_name], profile=profile, include_dispatcher=False
|
|
338
|
+
)
|
|
257
339
|
except ValueError:
|
|
258
340
|
return _unknown_tool_error(target_name)
|
|
259
341
|
if specs and specs[0].get("enabled") is False:
|
|
260
|
-
return {
|
|
342
|
+
return {
|
|
343
|
+
"ok": False,
|
|
344
|
+
"error_type": "tool_disabled",
|
|
345
|
+
"error_message": f"Tool is disabled: {target_name}",
|
|
346
|
+
"tool_name": target_name,
|
|
347
|
+
}
|
|
261
348
|
tool_arguments, arguments_error = _normalize_tool_arguments(arguments)
|
|
262
349
|
if arguments_error:
|
|
263
350
|
return arguments_error
|
|
@@ -429,7 +516,9 @@ def _expand_requested_names(requested: list[str], tool_registry: Mapping[str, An
|
|
|
429
516
|
return names
|
|
430
517
|
|
|
431
518
|
|
|
432
|
-
def _expand_requested_descriptor_names(
|
|
519
|
+
def _expand_requested_descriptor_names(
|
|
520
|
+
requested: list[str], descriptor_registry: Mapping[str, Any]
|
|
521
|
+
) -> list[str]:
|
|
433
522
|
names: list[str] = []
|
|
434
523
|
for name in requested:
|
|
435
524
|
canonical_name = _canonical_toolset_group(name)
|
|
@@ -560,7 +649,9 @@ def _normalize_tool_name(tool_name: str | None) -> str:
|
|
|
560
649
|
return str(tool_name or "").strip()
|
|
561
650
|
|
|
562
651
|
|
|
563
|
-
def _normalize_tool_arguments(
|
|
652
|
+
def _normalize_tool_arguments(
|
|
653
|
+
arguments: dict[str, Any] | str | None,
|
|
654
|
+
) -> tuple[dict[str, Any], dict[str, Any] | None]:
|
|
564
655
|
if arguments is None:
|
|
565
656
|
return {}, None
|
|
566
657
|
if isinstance(arguments, dict):
|
|
@@ -594,7 +685,9 @@ def _normalize_tool_arguments(arguments: dict[str, Any] | str | None) -> tuple[d
|
|
|
594
685
|
}
|
|
595
686
|
|
|
596
687
|
|
|
597
|
-
def _normalize_dispatched_tool_arguments(
|
|
688
|
+
def _normalize_dispatched_tool_arguments(
|
|
689
|
+
tool_name: str, arguments: dict[str, Any]
|
|
690
|
+
) -> dict[str, Any]:
|
|
598
691
|
if tool_name == "save_memory" and "content" not in arguments:
|
|
599
692
|
if "key" in arguments and "value" in arguments:
|
|
600
693
|
return {"content": f"{arguments['key']}: {_stringify_memory_value(arguments['value'])}"}
|
|
@@ -819,13 +912,18 @@ def _tool_spec(
|
|
|
819
912
|
"risk_level": policy.risk_level,
|
|
820
913
|
"requires_approval": tool_policy_requires_approval(policy),
|
|
821
914
|
"side_effects": list(policy.side_effects),
|
|
915
|
+
"approval_scopes": list(policy.approval_scopes),
|
|
916
|
+
"approval_exempt": policy.approval_exempt,
|
|
822
917
|
"enabled": True,
|
|
823
918
|
}
|
|
824
919
|
for key, value in dict(extras or {}).items():
|
|
825
920
|
spec[key] = value() if callable(value) else value
|
|
826
921
|
enabled = bool(spec.get("enabled", True))
|
|
827
922
|
if name == "web_search":
|
|
828
|
-
enabled = bool(
|
|
923
|
+
enabled = bool(
|
|
924
|
+
os.environ.get("KSADK_WEB_SEARCH_PROVIDER")
|
|
925
|
+
or os.environ.get("OPENCLAW_WEB_SEARCH_PROVIDER")
|
|
926
|
+
)
|
|
829
927
|
if name in {"run_command", "run_code", "sandbox_status"}:
|
|
830
928
|
enabled = enabled and _enabled_backend(sandbox_backend_name())
|
|
831
929
|
spec["enabled"] = enabled
|
ksadk/toolsets/platform.py
CHANGED
|
@@ -34,8 +34,16 @@ def component_status() -> dict:
|
|
|
34
34
|
"knowledge_base_bound": bool(_env("KSADK_KB_DATASET_ID")),
|
|
35
35
|
"long_term_memory_bound": bool(_env("KSADK_LTM_NAMESPACE")),
|
|
36
36
|
"skill_space_bound": bool(spaces),
|
|
37
|
-
"isolated_execution":
|
|
38
|
-
|
|
37
|
+
"isolated_execution": (
|
|
38
|
+
"enabled"
|
|
39
|
+
if skill_runtime_backend not in {"", "disabled", "none", "off"}
|
|
40
|
+
else "not_enabled"
|
|
41
|
+
),
|
|
42
|
+
"sandbox_direct_tools": (
|
|
43
|
+
"enabled"
|
|
44
|
+
if sandbox_backend not in {"", "disabled", "none", "off"}
|
|
45
|
+
else "not_enabled"
|
|
46
|
+
),
|
|
39
47
|
},
|
|
40
48
|
"skill_space": {
|
|
41
49
|
"space_ids": spaces,
|
|
@@ -48,13 +56,17 @@ def component_status() -> dict:
|
|
|
48
56
|
"skill_runtime": {
|
|
49
57
|
"backend": skill_runtime_backend,
|
|
50
58
|
"enabled": skill_runtime_backend not in {"", "disabled", "none", "off"},
|
|
51
|
-
"template_bound": bool(
|
|
59
|
+
"template_bound": bool(
|
|
60
|
+
_env("KSADK_SANDBOX_TEMPLATE_ID") or _env("KSADK_SKILL_RUNTIME_TEMPLATE_ID")
|
|
61
|
+
),
|
|
52
62
|
"request_protocol": "--request-file JSON envelope",
|
|
53
63
|
},
|
|
54
64
|
"sandbox": {
|
|
55
65
|
"backend": sandbox_backend,
|
|
56
66
|
"enabled": sandbox_backend not in {"", "disabled", "none", "off"},
|
|
57
|
-
"template_bound": bool(
|
|
67
|
+
"template_bound": bool(
|
|
68
|
+
_env("KSADK_SANDBOX_TEMPLATE_ID") or _env("KSADK_SKILL_RUNTIME_TEMPLATE_ID")
|
|
69
|
+
),
|
|
58
70
|
"tools": ["sandbox_status", "run_command", "run_code"],
|
|
59
71
|
},
|
|
60
72
|
"workspace": {
|
|
@@ -71,7 +83,11 @@ def component_status() -> dict:
|
|
|
71
83
|
"delete_workspace_file",
|
|
72
84
|
],
|
|
73
85
|
"boundary": "Workspace tools are confined to the AgentEngine UI workspace directory.",
|
|
74
|
-
"editing_model":
|
|
86
|
+
"editing_model": (
|
|
87
|
+
"write tools support whole-file writes; edit_workspace_file supports "
|
|
88
|
+
"exact snippet replacement; lint_workspace_file provides lightweight "
|
|
89
|
+
"built-in checks."
|
|
90
|
+
),
|
|
75
91
|
},
|
|
76
92
|
}
|
|
77
93
|
|