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/workspace.py
CHANGED
|
@@ -8,7 +8,7 @@ import re
|
|
|
8
8
|
import shutil
|
|
9
9
|
import subprocess
|
|
10
10
|
from pathlib import Path
|
|
11
|
-
from typing import Any
|
|
11
|
+
from typing import Any, Callable
|
|
12
12
|
|
|
13
13
|
from ksadk.sessions.local_service import resolve_local_session_dir
|
|
14
14
|
from ksadk.tools.gateway import ToolPolicy, default_tool_gateway
|
|
@@ -16,7 +16,6 @@ from ksadk.tools.result_budget import budget_tool_output, default_tool_result_bu
|
|
|
16
16
|
from ksadk.toolsets._langchain import as_tool
|
|
17
17
|
from ksadk.toolsets.workspace_state import WorkspaceReadState, get_read_state, record_read_state
|
|
18
18
|
|
|
19
|
-
|
|
20
19
|
_WORKSPACE_TOOL_POLICIES = {
|
|
21
20
|
"workspace_status": ToolPolicy(risk_level="low"),
|
|
22
21
|
"list_workspace_files": ToolPolicy(risk_level="low"),
|
|
@@ -35,8 +34,14 @@ def _gateway():
|
|
|
35
34
|
return default_tool_gateway(_WORKSPACE_TOOL_POLICIES)
|
|
36
35
|
|
|
37
36
|
|
|
37
|
+
def _dict_result(value: Any, *, tool_name: str) -> dict[str, Any]:
|
|
38
|
+
if not isinstance(value, dict):
|
|
39
|
+
raise TypeError(f"{tool_name} returned {type(value).__name__}, expected dict")
|
|
40
|
+
return dict(value)
|
|
41
|
+
|
|
42
|
+
|
|
38
43
|
def workspace_root() -> Path:
|
|
39
|
-
return resolve_local_session_dir() / "workspace"
|
|
44
|
+
return Path(resolve_local_session_dir()) / "workspace"
|
|
40
45
|
|
|
41
46
|
|
|
42
47
|
def resolve_workspace_path(relative_path: str) -> Path:
|
|
@@ -55,7 +60,10 @@ def workspace_relative(path: Path) -> str:
|
|
|
55
60
|
def workspace_status() -> dict[str, Any]:
|
|
56
61
|
"""Return current AgentEngine workspace status."""
|
|
57
62
|
|
|
58
|
-
return
|
|
63
|
+
return _dict_result(
|
|
64
|
+
_gateway().invoke("workspace_status", _workspace_status_impl),
|
|
65
|
+
tool_name="workspace_status",
|
|
66
|
+
)
|
|
59
67
|
|
|
60
68
|
|
|
61
69
|
def _workspace_status_impl() -> dict[str, Any]:
|
|
@@ -83,15 +91,18 @@ def list_workspace_files(
|
|
|
83
91
|
) -> dict[str, Any]:
|
|
84
92
|
"""List files under the AgentEngine workspace."""
|
|
85
93
|
|
|
86
|
-
return
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
94
|
+
return _dict_result(
|
|
95
|
+
_gateway().invoke(
|
|
96
|
+
"list_workspace_files",
|
|
97
|
+
_list_workspace_files_impl,
|
|
98
|
+
path,
|
|
99
|
+
glob,
|
|
100
|
+
recursive,
|
|
101
|
+
include_dirs,
|
|
102
|
+
max_results,
|
|
103
|
+
sort_by,
|
|
104
|
+
),
|
|
105
|
+
tool_name="list_workspace_files",
|
|
95
106
|
)
|
|
96
107
|
|
|
97
108
|
|
|
@@ -117,17 +128,31 @@ def _list_workspace_files_impl(
|
|
|
117
128
|
items = [
|
|
118
129
|
item
|
|
119
130
|
for item in items
|
|
120
|
-
if fnmatch.fnmatch(workspace_relative(item), pattern)
|
|
131
|
+
if fnmatch.fnmatch(workspace_relative(item), pattern)
|
|
132
|
+
or fnmatch.fnmatch(item.name, pattern)
|
|
121
133
|
]
|
|
122
134
|
if not include_dirs:
|
|
123
135
|
items = [item for item in items if item.is_file()]
|
|
124
136
|
sort_key = str(sort_by or "name").strip().lower()
|
|
137
|
+
key: Callable[[Path], tuple[Any, ...]]
|
|
125
138
|
if sort_key == "mtime":
|
|
126
|
-
|
|
139
|
+
|
|
140
|
+
def key(candidate: Path) -> tuple[Any, ...]:
|
|
141
|
+
return candidate.stat().st_mtime_ns, workspace_relative(candidate)
|
|
142
|
+
|
|
127
143
|
elif sort_key == "size":
|
|
128
|
-
|
|
144
|
+
|
|
145
|
+
def key(candidate: Path) -> tuple[Any, ...]:
|
|
146
|
+
return (
|
|
147
|
+
candidate.stat().st_size if candidate.is_file() else 0,
|
|
148
|
+
workspace_relative(candidate),
|
|
149
|
+
)
|
|
150
|
+
|
|
129
151
|
else:
|
|
130
|
-
|
|
152
|
+
|
|
153
|
+
def key(candidate: Path) -> tuple[Any, ...]:
|
|
154
|
+
return workspace_relative(candidate).lower(), candidate.is_file()
|
|
155
|
+
|
|
131
156
|
limit = max(1, min(int(max_results or 500), 5000))
|
|
132
157
|
sorted_items = sorted(items, key=key)
|
|
133
158
|
entries = [
|
|
@@ -140,7 +165,13 @@ def _list_workspace_files_impl(
|
|
|
140
165
|
}
|
|
141
166
|
for item in sorted_items[:limit]
|
|
142
167
|
]
|
|
143
|
-
return {
|
|
168
|
+
return {
|
|
169
|
+
"ok": True,
|
|
170
|
+
"path": path,
|
|
171
|
+
"recursive": recursive,
|
|
172
|
+
"entries": entries,
|
|
173
|
+
"truncated": len(sorted_items) > len(entries),
|
|
174
|
+
}
|
|
144
175
|
|
|
145
176
|
|
|
146
177
|
def read_workspace_file(
|
|
@@ -155,14 +186,17 @@ def read_workspace_file(
|
|
|
155
186
|
Do not issue a dependent read and edit in the same parallel tool-call batch.
|
|
156
187
|
"""
|
|
157
188
|
|
|
158
|
-
return
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
|
|
189
|
+
return _dict_result(
|
|
190
|
+
_gateway().invoke(
|
|
191
|
+
"read_workspace_file",
|
|
192
|
+
_read_workspace_file_impl,
|
|
193
|
+
path,
|
|
194
|
+
start_line,
|
|
195
|
+
end_line,
|
|
196
|
+
max_chars,
|
|
197
|
+
include_line_numbers,
|
|
198
|
+
),
|
|
199
|
+
tool_name="read_workspace_file",
|
|
166
200
|
)
|
|
167
201
|
|
|
168
202
|
|
|
@@ -201,7 +235,9 @@ def _read_workspace_file_impl(
|
|
|
201
235
|
field_name="content",
|
|
202
236
|
value=content,
|
|
203
237
|
metadata={"tool_use_id": f"read_{relative.replace('/', '_')}"},
|
|
204
|
-
budget=default_tool_result_budget(
|
|
238
|
+
budget=default_tool_result_budget(
|
|
239
|
+
max_chars=limit, preview_chars=limit, persist_threshold_chars=limit
|
|
240
|
+
),
|
|
205
241
|
)
|
|
206
242
|
partial = start != 1 or end != total_lines
|
|
207
243
|
record_read_state(
|
|
@@ -251,13 +287,16 @@ def write_workspace_file(
|
|
|
251
287
|
) -> dict[str, Any]:
|
|
252
288
|
"""Write a UTF-8 text file inside the AgentEngine workspace."""
|
|
253
289
|
|
|
254
|
-
return
|
|
255
|
-
|
|
256
|
-
|
|
257
|
-
|
|
258
|
-
|
|
259
|
-
|
|
260
|
-
|
|
290
|
+
return _dict_result(
|
|
291
|
+
_gateway().invoke(
|
|
292
|
+
"write_workspace_file",
|
|
293
|
+
_write_workspace_file_impl,
|
|
294
|
+
path,
|
|
295
|
+
content,
|
|
296
|
+
overwrite,
|
|
297
|
+
approval=approval,
|
|
298
|
+
),
|
|
299
|
+
tool_name="write_workspace_file",
|
|
261
300
|
)
|
|
262
301
|
|
|
263
302
|
|
|
@@ -282,16 +321,21 @@ def write_workspace_files(
|
|
|
282
321
|
) -> dict[str, Any]:
|
|
283
322
|
"""Write multiple UTF-8 text files inside the AgentEngine workspace."""
|
|
284
323
|
|
|
285
|
-
return
|
|
286
|
-
|
|
287
|
-
|
|
288
|
-
|
|
289
|
-
|
|
290
|
-
|
|
324
|
+
return _dict_result(
|
|
325
|
+
_gateway().invoke(
|
|
326
|
+
"write_workspace_files",
|
|
327
|
+
_write_workspace_files_impl,
|
|
328
|
+
files,
|
|
329
|
+
overwrite,
|
|
330
|
+
approval=approval,
|
|
331
|
+
),
|
|
332
|
+
tool_name="write_workspace_files",
|
|
291
333
|
)
|
|
292
334
|
|
|
293
335
|
|
|
294
|
-
def _write_workspace_files_impl(
|
|
336
|
+
def _write_workspace_files_impl(
|
|
337
|
+
files: list[dict[str, Any]], overwrite: bool = True
|
|
338
|
+
) -> dict[str, Any]:
|
|
295
339
|
if not isinstance(files, list) or not files:
|
|
296
340
|
return {"ok": False, "error_message": "files must be a non-empty list"}
|
|
297
341
|
written = []
|
|
@@ -301,7 +345,9 @@ def _write_workspace_files_impl(files: list[dict[str, Any]], overwrite: bool = T
|
|
|
301
345
|
path = str(item.get("path") or "").strip()
|
|
302
346
|
if not path:
|
|
303
347
|
return {"ok": False, "error_message": "each file item requires path"}
|
|
304
|
-
result = _write_workspace_file_impl(
|
|
348
|
+
result = _write_workspace_file_impl(
|
|
349
|
+
path, str(item.get("content") or ""), overwrite=overwrite
|
|
350
|
+
)
|
|
305
351
|
if not result.get("ok"):
|
|
306
352
|
return result
|
|
307
353
|
written.append({"path": result["path"], "size": result["size"]})
|
|
@@ -321,15 +367,18 @@ def edit_workspace_file(
|
|
|
321
367
|
The read must complete before this call; do not batch a dependent read and edit.
|
|
322
368
|
"""
|
|
323
369
|
|
|
324
|
-
return
|
|
325
|
-
|
|
326
|
-
|
|
327
|
-
|
|
328
|
-
|
|
329
|
-
|
|
330
|
-
|
|
331
|
-
|
|
332
|
-
|
|
370
|
+
return _dict_result(
|
|
371
|
+
_gateway().invoke(
|
|
372
|
+
"edit_workspace_file",
|
|
373
|
+
_edit_workspace_file_impl,
|
|
374
|
+
path,
|
|
375
|
+
old_text,
|
|
376
|
+
new_text,
|
|
377
|
+
expected_replacements,
|
|
378
|
+
replace_all,
|
|
379
|
+
approval=approval,
|
|
380
|
+
),
|
|
381
|
+
tool_name="edit_workspace_file",
|
|
333
382
|
)
|
|
334
383
|
|
|
335
384
|
|
|
@@ -351,6 +400,8 @@ def _edit_workspace_file_impl(
|
|
|
351
400
|
text, error = _read_workspace_text(target)
|
|
352
401
|
if error is not None:
|
|
353
402
|
return {**error, "path": path}
|
|
403
|
+
if text is None:
|
|
404
|
+
return {"ok": False, "path": path, "error_message": "workspace file read failed"}
|
|
354
405
|
edit_result = _apply_single_edit(
|
|
355
406
|
text,
|
|
356
407
|
old_text,
|
|
@@ -390,13 +441,16 @@ def multi_edit_workspace_file(
|
|
|
390
441
|
The read must complete before this call; do not batch a dependent read and edit.
|
|
391
442
|
"""
|
|
392
443
|
|
|
393
|
-
return
|
|
394
|
-
|
|
395
|
-
|
|
396
|
-
|
|
397
|
-
|
|
398
|
-
|
|
399
|
-
|
|
444
|
+
return _dict_result(
|
|
445
|
+
_gateway().invoke(
|
|
446
|
+
"multi_edit_workspace_file",
|
|
447
|
+
_multi_edit_workspace_file_impl,
|
|
448
|
+
path,
|
|
449
|
+
edits,
|
|
450
|
+
replace_all,
|
|
451
|
+
approval=approval,
|
|
452
|
+
),
|
|
453
|
+
tool_name="multi_edit_workspace_file",
|
|
400
454
|
)
|
|
401
455
|
|
|
402
456
|
|
|
@@ -478,7 +532,10 @@ def _multi_edit_workspace_file_impl(
|
|
|
478
532
|
def lint_workspace_file(path: str, language: str = "auto") -> dict[str, Any]:
|
|
479
533
|
"""Run lightweight built-in lint checks for a UTF-8 workspace text file."""
|
|
480
534
|
|
|
481
|
-
return
|
|
535
|
+
return _dict_result(
|
|
536
|
+
_gateway().invoke("lint_workspace_file", _lint_workspace_file_impl, path, language),
|
|
537
|
+
tool_name="lint_workspace_file",
|
|
538
|
+
)
|
|
482
539
|
|
|
483
540
|
|
|
484
541
|
def _lint_workspace_file_impl(path: str, language: str = "auto") -> dict[str, Any]:
|
|
@@ -515,9 +572,23 @@ def _lint_workspace_file_impl(path: str, language: str = "auto") -> dict[str, An
|
|
|
515
572
|
else:
|
|
516
573
|
for line_no, line in enumerate((text or "").splitlines(), start=1):
|
|
517
574
|
if "\x00" in line:
|
|
518
|
-
issues.append(
|
|
575
|
+
issues.append(
|
|
576
|
+
{
|
|
577
|
+
"severity": "error",
|
|
578
|
+
"line": line_no,
|
|
579
|
+
"column": line.index("\x00") + 1,
|
|
580
|
+
"message": "NUL byte found",
|
|
581
|
+
}
|
|
582
|
+
)
|
|
519
583
|
if line.rstrip("\n\r") != line.rstrip():
|
|
520
|
-
issues.append(
|
|
584
|
+
issues.append(
|
|
585
|
+
{
|
|
586
|
+
"severity": "warning",
|
|
587
|
+
"line": line_no,
|
|
588
|
+
"column": len(line),
|
|
589
|
+
"message": "trailing whitespace",
|
|
590
|
+
}
|
|
591
|
+
)
|
|
521
592
|
if len(issues) >= 20:
|
|
522
593
|
break
|
|
523
594
|
return {
|
|
@@ -557,16 +628,19 @@ def search_workspace_files(
|
|
|
557
628
|
) -> dict[str, Any]:
|
|
558
629
|
"""Search UTF-8 text files in the AgentEngine workspace."""
|
|
559
630
|
|
|
560
|
-
return
|
|
561
|
-
|
|
562
|
-
|
|
563
|
-
|
|
564
|
-
|
|
565
|
-
|
|
566
|
-
|
|
567
|
-
|
|
568
|
-
|
|
569
|
-
|
|
631
|
+
return _dict_result(
|
|
632
|
+
_gateway().invoke(
|
|
633
|
+
"search_workspace_files",
|
|
634
|
+
_search_workspace_files_impl,
|
|
635
|
+
query,
|
|
636
|
+
path,
|
|
637
|
+
is_regex,
|
|
638
|
+
glob,
|
|
639
|
+
case_sensitive,
|
|
640
|
+
context_lines,
|
|
641
|
+
max_results,
|
|
642
|
+
),
|
|
643
|
+
tool_name="search_workspace_files",
|
|
570
644
|
)
|
|
571
645
|
|
|
572
646
|
|
|
@@ -584,15 +658,23 @@ def _search_workspace_files_impl(
|
|
|
584
658
|
return {"ok": False, "error_message": "query is required"}
|
|
585
659
|
base = resolve_workspace_path(path)
|
|
586
660
|
if shutil.which("rg") and not context_lines:
|
|
587
|
-
rg_result = _search_with_rg(
|
|
661
|
+
rg_result = _search_with_rg(
|
|
662
|
+
needle, base, is_regex, glob, case_sensitive, context_lines, max_results
|
|
663
|
+
)
|
|
588
664
|
if rg_result is not None:
|
|
589
|
-
return _search_payload(
|
|
665
|
+
return _search_payload(
|
|
666
|
+
query, path, rg_result["results"], rg_result["truncated"], context_lines, "rg"
|
|
667
|
+
)
|
|
590
668
|
candidates = [base] if base.is_file() else [item for item in base.rglob("*") if item.is_file()]
|
|
591
669
|
if glob:
|
|
592
|
-
candidates = [
|
|
670
|
+
candidates = [
|
|
671
|
+
item
|
|
672
|
+
for item in candidates
|
|
673
|
+
if fnmatch.fnmatch(workspace_relative(item), glob) or fnmatch.fnmatch(item.name, glob)
|
|
674
|
+
]
|
|
593
675
|
flags = 0 if case_sensitive else re.IGNORECASE
|
|
594
676
|
pattern = re.compile(needle if is_regex else re.escape(needle), flags)
|
|
595
|
-
results = []
|
|
677
|
+
results: list[dict[str, Any]] = []
|
|
596
678
|
limit = max(1, min(int(max_results or 100), 5000))
|
|
597
679
|
context_limit = max(0, min(int(context_lines or 0), 20))
|
|
598
680
|
truncated = False
|
|
@@ -665,7 +747,7 @@ def _search_with_rg(
|
|
|
665
747
|
return None
|
|
666
748
|
if completed.returncode not in {0, 1}:
|
|
667
749
|
return None
|
|
668
|
-
results = []
|
|
750
|
+
results: list[dict[str, Any]] = []
|
|
669
751
|
limit = max(1, min(int(max_results or 100), 5000))
|
|
670
752
|
truncated = False
|
|
671
753
|
for raw_line in completed.stdout.splitlines():
|
|
@@ -725,13 +807,19 @@ def _validate_read_state(target: Path, relative: str) -> dict[str, Any] | None:
|
|
|
725
807
|
"suggested_action": f"Call read_workspace_file(path={relative!r}) before editing.",
|
|
726
808
|
}
|
|
727
809
|
stat = target.stat() if target.exists() else None
|
|
728
|
-
if
|
|
810
|
+
if (
|
|
811
|
+
stat is None
|
|
812
|
+
or stat.st_mtime_ns != read_state.mtime_ns
|
|
813
|
+
or stat.st_size != read_state.size_bytes
|
|
814
|
+
):
|
|
729
815
|
return {
|
|
730
816
|
"ok": False,
|
|
731
817
|
"path": relative,
|
|
732
818
|
"error_type": "file_modified_since_read",
|
|
733
819
|
"error_message": "workspace file changed since last read",
|
|
734
|
-
"suggested_action":
|
|
820
|
+
"suggested_action": (
|
|
821
|
+
f"Re-read the file with read_workspace_file(path={relative!r}) " "and retry."
|
|
822
|
+
),
|
|
735
823
|
}
|
|
736
824
|
return None
|
|
737
825
|
|
|
@@ -761,7 +849,17 @@ def _apply_single_edit(
|
|
|
761
849
|
"error_message": "old_text was not found in the workspace file",
|
|
762
850
|
"occurrences": 0,
|
|
763
851
|
"nearby_candidates": _nearby_candidates(text, old),
|
|
764
|
-
"suggested_action":
|
|
852
|
+
"suggested_action": (
|
|
853
|
+
"Use one nearby candidate as old_text, or call read_workspace_file "
|
|
854
|
+
"with line numbers and retry."
|
|
855
|
+
),
|
|
856
|
+
}
|
|
857
|
+
if actual_old is None:
|
|
858
|
+
return {
|
|
859
|
+
"ok": False,
|
|
860
|
+
"path": relative,
|
|
861
|
+
"error_type": "snippet_not_found",
|
|
862
|
+
"error_message": "old_text was not found in the workspace file",
|
|
765
863
|
}
|
|
766
864
|
if not replace_all and occurrences != expected:
|
|
767
865
|
return {
|
|
@@ -772,7 +870,10 @@ def _apply_single_edit(
|
|
|
772
870
|
"occurrences": occurrences,
|
|
773
871
|
"expected_replacements": expected,
|
|
774
872
|
"matches": matches,
|
|
775
|
-
"suggested_action":
|
|
873
|
+
"suggested_action": (
|
|
874
|
+
"Provide a larger unique old_text snippet, set expected_replacements, "
|
|
875
|
+
"or use replace_all=true."
|
|
876
|
+
),
|
|
776
877
|
}
|
|
777
878
|
replacements = occurrences if replace_all else expected
|
|
778
879
|
return {
|
|
@@ -809,11 +910,15 @@ def _match_previews(text: str, needle: str, limit: int = 20) -> list[dict[str, A
|
|
|
809
910
|
|
|
810
911
|
def _nearby_candidates(text: str, old: str, limit: int = 5) -> list[dict[str, Any]]:
|
|
811
912
|
old_norm = _normalize_quotes(old).strip()
|
|
812
|
-
candidates = []
|
|
913
|
+
candidates: list[dict[str, Any]] = []
|
|
813
914
|
for line_no, line in enumerate(text.splitlines(), start=1):
|
|
814
915
|
ratio = difflib.SequenceMatcher(None, old_norm, _normalize_quotes(line).strip()).ratio()
|
|
815
|
-
if old_norm and (
|
|
816
|
-
|
|
916
|
+
if old_norm and (
|
|
917
|
+
old_norm[: max(1, min(4, len(old_norm)))] in _normalize_quotes(line) or ratio > 0.45
|
|
918
|
+
):
|
|
919
|
+
candidates.append(
|
|
920
|
+
{"line": line_no, "text": line.strip(), "snippet": line, "score": round(ratio, 3)}
|
|
921
|
+
)
|
|
817
922
|
candidates.sort(key=lambda item: (-float(item["score"]), int(item["line"])))
|
|
818
923
|
return candidates[:limit]
|
|
819
924
|
|
|
@@ -830,11 +935,14 @@ def _build_diff(relative: str, before: str, after: str) -> str:
|
|
|
830
935
|
|
|
831
936
|
|
|
832
937
|
def _budget_diff(tool_name: str, diff: str, relative: str) -> dict[str, Any]:
|
|
833
|
-
return
|
|
938
|
+
return _dict_result(
|
|
939
|
+
budget_tool_output(
|
|
940
|
+
tool_name=tool_name,
|
|
941
|
+
field_name="diff",
|
|
942
|
+
value=diff,
|
|
943
|
+
metadata={"tool_use_id": f"{tool_name}_{relative.replace('/', '_')}"},
|
|
944
|
+
),
|
|
834
945
|
tool_name=tool_name,
|
|
835
|
-
field_name="diff",
|
|
836
|
-
value=diff,
|
|
837
|
-
metadata={"tool_use_id": f"{tool_name}_{relative.replace('/', '_')}"},
|
|
838
946
|
)
|
|
839
947
|
|
|
840
948
|
|
|
@@ -857,7 +965,8 @@ def _find_actual_string(text: str, old: str) -> tuple[str | None, bool]:
|
|
|
857
965
|
if old in text:
|
|
858
966
|
return old, False
|
|
859
967
|
normalized_old = _normalize_quotes(old)
|
|
860
|
-
|
|
968
|
+
smart_quote_map: dict[str, str | int | None] = {'"': "“", "'": "‘"}
|
|
969
|
+
for candidate in {normalized_old, old.translate(str.maketrans(smart_quote_map))}:
|
|
861
970
|
if candidate and candidate in text:
|
|
862
971
|
return candidate, True
|
|
863
972
|
normalized_text = _normalize_quotes(text)
|
|
@@ -868,24 +977,26 @@ def _find_actual_string(text: str, old: str) -> tuple[str | None, bool]:
|
|
|
868
977
|
|
|
869
978
|
|
|
870
979
|
def _normalize_quotes(value: str) -> str:
|
|
871
|
-
|
|
872
|
-
|
|
873
|
-
|
|
874
|
-
|
|
875
|
-
|
|
876
|
-
|
|
877
|
-
|
|
878
|
-
|
|
879
|
-
|
|
880
|
-
}
|
|
881
|
-
)
|
|
882
|
-
)
|
|
980
|
+
quote_map: dict[str, str | int | None] = {
|
|
981
|
+
"“": '"',
|
|
982
|
+
"”": '"',
|
|
983
|
+
"„": '"',
|
|
984
|
+
"‘": "'",
|
|
985
|
+
"’": "'",
|
|
986
|
+
"‚": "'",
|
|
987
|
+
}
|
|
988
|
+
return value.translate(str.maketrans(quote_map))
|
|
883
989
|
|
|
884
990
|
|
|
885
991
|
def delete_workspace_file(path: str, approval: dict[str, Any] | None = None) -> dict[str, Any]:
|
|
886
992
|
"""Delete a file or empty directory inside the AgentEngine workspace."""
|
|
887
993
|
|
|
888
|
-
return
|
|
994
|
+
return _dict_result(
|
|
995
|
+
_gateway().invoke(
|
|
996
|
+
"delete_workspace_file", _delete_workspace_file_impl, path, approval=approval
|
|
997
|
+
),
|
|
998
|
+
tool_name="delete_workspace_file",
|
|
999
|
+
)
|
|
889
1000
|
|
|
890
1001
|
|
|
891
1002
|
def _delete_workspace_file_impl(path: str) -> dict[str, Any]:
|