agentengine-sdk-python 0.6.9__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.6.9.dist-info → agentengine_sdk_python-0.8.0.dist-info}/METADATA +41 -23
- 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 +252 -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 +533 -726
- 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 +173 -90
- ksadk/cli/cmd_invoke.py +388 -159
- ksadk/cli/cmd_launch.py +64 -28
- ksadk/cli/cmd_mcp.py +103 -64
- ksadk/cli/cmd_model.py +14 -5
- ksadk/cli/cmd_openclaw.py +488 -228
- ksadk/cli/cmd_replay.py +71 -0
- ksadk/cli/cmd_run.py +44 -14
- 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 +38 -16
- 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 +501 -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 +656 -0
- ksadk/conversations/model_context.py +22 -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 -5187
- 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 +52 -39
- ksadk/deployment/manager.py +63 -65
- ksadk/deployment/providers/serverless.py +326 -209
- 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 +267 -0
- ksadk/memory/adk/short_term_memory.py +33 -27
- 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 +1248 -164
- 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 -530
- ksadk/runners/langgraph_runner.py +490 -95
- ksadk/runners/patch_langchain.py +16 -16
- ksadk/runners/remote_runner.py +264 -38
- 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 -3743
- 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-C0meuOdi.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-bj2rZnP5.js → arc-CFKwSk_B.js} +1 -1
- ksadk/server/static/assets/architecture-7EHR7CIX-CynqOWjZ.js +1 -0
- ksadk/server/static/assets/{architectureDiagram-3BPJPVTR-2u1ltDIj.js → architectureDiagram-3BPJPVTR-Dej8jX8c.js} +1 -1
- ksadk/server/static/assets/{blockDiagram-GPEHLZMM-D6fvdK20.js → blockDiagram-GPEHLZMM-1F64jqvy.js} +1 -1
- ksadk/server/static/assets/{c4Diagram-AAUBKEIU-BK82L5n5.js → c4Diagram-AAUBKEIU-9q7AUAKb.js} +1 -1
- ksadk/server/static/assets/channel-iUGv2N24.js +1 -0
- ksadk/server/static/assets/{chunk-2J33WTMH-DLVdkeyQ.js → chunk-2J33WTMH-6qgwJm7Q.js} +1 -1
- ksadk/server/static/assets/{chunk-4BX2VUAB-BbwsYcbW.js → chunk-4BX2VUAB-CsWIQRhc.js} +1 -1
- ksadk/server/static/assets/{chunk-55IACEB6-DOairxzw.js → chunk-55IACEB6-BK8paA20.js} +1 -1
- ksadk/server/static/assets/{chunk-727SXJPM-hCO487gs.js → chunk-727SXJPM-B-JEhy7h.js} +1 -1
- ksadk/server/static/assets/{chunk-AQP2D5EJ-XU8vDOuG.js → chunk-AQP2D5EJ-DYBvMHAa.js} +1 -1
- ksadk/server/static/assets/{chunk-FMBD7UC4-PrapyfMu.js → chunk-FMBD7UC4-BGhvzDYt.js} +1 -1
- ksadk/server/static/assets/{chunk-ND2GUHAM-CboKhTZ3.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-_N8bJ-EU.js → cose-bilkent-S5V4N54A-CX3yotHq.js} +1 -1
- ksadk/server/static/assets/{dagre-BM42HDAG-FoDlo5J2.js → dagre-BM42HDAG-C7TguAWo.js} +1 -1
- ksadk/server/static/assets/{diagram-2AECGRRQ-BBp6ebBw.js → diagram-2AECGRRQ-Dd17_kws.js} +1 -1
- ksadk/server/static/assets/{diagram-5GNKFQAL-CqOvG1PR.js → diagram-5GNKFQAL-DVIClIil.js} +1 -1
- ksadk/server/static/assets/{diagram-KO2AKTUF-O9T3t6ba.js → diagram-KO2AKTUF-Df_3gYQa.js} +1 -1
- ksadk/server/static/assets/{diagram-LMA3HP47-CGG8ekBO.js → diagram-LMA3HP47-BhLk6ZtA.js} +1 -1
- ksadk/server/static/assets/{diagram-OG6HWLK6-4BmH1EEg.js → diagram-OG6HWLK6-D4GNGvuu.js} +1 -1
- ksadk/server/static/assets/{dist-CiZHB6ZW.js → dist-6CVKuTAe.js} +1 -1
- ksadk/server/static/assets/{dist-BMKM66B4.js → dist-BUHRxvDG.js} +1 -1
- ksadk/server/static/assets/{dist-CZ6C3x8B.js → dist-BZ9n9AjO.js} +1 -1
- ksadk/server/static/assets/{dist-DbaH3p5h.js → dist-BibcG1V9.js} +1 -1
- ksadk/server/static/assets/{dist-BVzcWa6D.js → dist-Bs-jQcRX.js} +1 -1
- ksadk/server/static/assets/{dist-D99wf6_X.js → dist-C2xjE7cO.js} +1 -1
- ksadk/server/static/assets/{dist-DLMjL01k.js → dist-C7-3jInC.js} +1 -1
- ksadk/server/static/assets/{dist-DI-oVAXw.js → dist-C99THtIA.js} +1 -1
- ksadk/server/static/assets/{dist-BkJjNih3.js → dist-CGcp2ex8.js} +1 -1
- ksadk/server/static/assets/{dist-D5JGcxBx.js → dist-CVQRZjPu.js} +1 -1
- ksadk/server/static/assets/{dist-CWiTDN_V.js → dist-Cf23NY4L.js} +1 -1
- ksadk/server/static/assets/{dist-DLeM1OCK.js → dist-CgF3fj15.js} +1 -1
- ksadk/server/static/assets/{dist-BmuTWcm7.js → dist-Cwt7koer.js} +1 -1
- ksadk/server/static/assets/{dist-C2DKRFVK.js → dist-D82mtD2s.js} +1 -1
- ksadk/server/static/assets/{dist-B67uF2uK.js → dist-DF06ORQo.js} +1 -1
- ksadk/server/static/assets/{dist-Cwhk4lwI.js → dist-DHn6nBzr.js} +1 -1
- ksadk/server/static/assets/{dist-S4klkK5W.js → dist-Djgl2wVZ.js} +1 -1
- ksadk/server/static/assets/{dist-DCpZrjaK.js → dist-DlzCRy0S.js} +1 -1
- ksadk/server/static/assets/{dist-Cp1_jKwf.js → dist-DqNnNFrw.js} +1 -1
- ksadk/server/static/assets/{dist-6kSZvCZh.js → dist-DyvYLMW9.js} +1 -1
- ksadk/server/static/assets/{dist-DM0rEQPk.js → dist-eoW6tZXA.js} +1 -1
- ksadk/server/static/assets/{dist-Bk1l05Ni.js → dist-ivOya1LD.js} +1 -1
- ksadk/server/static/assets/{erDiagram-TEJ5UH35-oJhaci7S.js → erDiagram-TEJ5UH35-CnfRcY2M.js} +1 -1
- ksadk/server/static/assets/eventmodeling-FCH6USID-ChYO-ijM.js +1 -0
- ksadk/server/static/assets/{flowDiagram-I6XJVG4X-DtTmUan-.js → flowDiagram-I6XJVG4X-DGaJjGNJ.js} +1 -1
- ksadk/server/static/assets/{ganttDiagram-6RSMTGT7-BSsb_eij.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-BR5s6Pws.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-DYPc5cvh.js → infoDiagram-5YYISTIA-CYIIsb8y.js} +1 -1
- ksadk/server/static/assets/{ishikawaDiagram-YF4QCWOH-MoBdALDg.js → ishikawaDiagram-YF4QCWOH-DLOHGvWw.js} +1 -1
- ksadk/server/static/assets/{journeyDiagram-JHISSGLW-DgLiQT8l.js → journeyDiagram-JHISSGLW-BIzKeejT.js} +1 -1
- ksadk/server/static/assets/{kanban-definition-UN3LZRKU-CsFx112F.js → kanban-definition-UN3LZRKU-BWHoFSw2.js} +1 -1
- ksadk/server/static/assets/{katex-DRsiwpM2.js → katex-DATssjp1.js} +1 -1
- ksadk/server/static/assets/{linear-TNRQ5Orv.js → linear-CvMBw9cA.js} +1 -1
- ksadk/server/static/assets/{mermaid-parser.core-D2eMVOgo.js → mermaid-parser.core-mGAcEwcq.js} +2 -2
- ksadk/server/static/assets/{mindmap-definition-RKZ34NQL-BtByYFhL.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-DPnuCB8c.js → pieDiagram-4H26LBE5-By-ra07M.js} +1 -1
- ksadk/server/static/assets/{quadrantDiagram-W4KKPZXB-miFpCPv4.js → quadrantDiagram-W4KKPZXB-CxIR4JXI.js} +1 -1
- ksadk/server/static/assets/radar-GUYGQ44K-BIq5fXsn.js +1 -0
- ksadk/server/static/assets/{requirementDiagram-4Y6WPE33-mjB_yYkW.js → requirementDiagram-4Y6WPE33-DpW90iu3.js} +1 -1
- ksadk/server/static/assets/{sankeyDiagram-5OEKKPKP-D7hSlZZZ.js → sankeyDiagram-5OEKKPKP-DpGa6EAV.js} +1 -1
- ksadk/server/static/assets/{sequenceDiagram-3UESZ5HK-D9Cx6hC3.js → sequenceDiagram-3UESZ5HK-NTKNGGe5.js} +1 -1
- ksadk/server/static/assets/{stateDiagram-AJRCARHV-D_zrg47o.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-CwSec0Wa.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-agCVobiF.js → vennDiagram-CIIHVFJN-l3Z7-wbP.js} +1 -1
- ksadk/server/static/assets/wardley-L42UT6IY-8XLvnNIs.js +1 -0
- ksadk/server/static/assets/{wardleyDiagram-YWT4CUSO-TmrlhWNt.js → wardleyDiagram-YWT4CUSO-BR54GPmr.js} +1 -1
- ksadk/server/static/assets/{xychartDiagram-2RQKCTM6-DV71V-ah.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 +86 -40
- ksadk/sessions/base.py +31 -11
- ksadk/sessions/continuity.py +28 -5
- ksadk/sessions/in_memory.py +46 -2
- ksadk/sessions/local_service.py +148 -17
- ksadk/sessions/postgres_service.py +216 -35
- ksadk/sessions/resilience.py +52 -0
- ksadk/sessions/resilient.py +388 -0
- 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 +136 -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 +264 -114
- ksadk/tracing/exporters/inmemory_exporter.py +62 -51
- ksadk/tracing/exporters/langfuse_exporter.py +91 -76
- ksadk/tracing/setup.py +132 -53
- ksadk/tracing/span_utils.py +5 -2
- ksadk/tui/__init__.py +22 -7
- ksadk/tui/loop.py +1925 -0
- ksadk/tui/stream_render.py +69 -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.6.9.dist-info/RECORD +0 -487
- ksadk/server/static/assets/CodeBlock-BbI4HPtJ.js +0 -9
- ksadk/server/static/assets/MathMessageMarkdown-DMLQYoLp.js +0 -8
- ksadk/server/static/assets/MermaidBlock-DCR8WZ17.js +0 -303
- ksadk/server/static/assets/NativeTerminalPanel-CKUvWhUz.js +0 -1
- ksadk/server/static/assets/architecture-7EHR7CIX-Cr6Xz1_c.js +0 -1
- ksadk/server/static/assets/channel-BSSOwFIb.js +0 -1
- ksadk/server/static/assets/chunk-QZHKN3VN-XXpdiwUL.js +0 -1
- ksadk/server/static/assets/classDiagram-4FO5ZUOK-C5HvGiyK.js +0 -1
- ksadk/server/static/assets/classDiagram-v2-Q7XG4LA2-C5HvGiyK.js +0 -1
- ksadk/server/static/assets/eventmodeling-FCH6USID-CIgwHJLL.js +0 -1
- ksadk/server/static/assets/gitGraph-WXDBUCRP-BVAJ7uo0.js +0 -1
- ksadk/server/static/assets/index-BH7-pC0B.js +0 -165
- ksadk/server/static/assets/index-DAURbCsP.css +0 -1
- ksadk/server/static/assets/info-J43DQDTF-MT80V4ge.js +0 -1
- ksadk/server/static/assets/packet-YPE3B663-BLKhbXZB.js +0 -1
- ksadk/server/static/assets/pie-LRSECV5Y-DFOikjSY.js +0 -1
- ksadk/server/static/assets/radar-GUYGQ44K-095b1Ikw.js +0 -1
- ksadk/server/static/assets/stateDiagram-v2-BHNVJYJU-J9kCb0nC.js +0 -1
- ksadk/server/static/assets/treeView-BLDUP644-yinfJEY6.js +0 -1
- ksadk/server/static/assets/treemap-LRROVOQU-DosUqN1Q.js +0 -1
- ksadk/server/static/assets/wardley-L42UT6IY-Bvp7-5uH.js +0 -1
- ksadk/tui/app.py +0 -400
- ksadk/tui/clipboard.py +0 -100
- ksadk/tui/widgets/__init__.py +0 -22
- ksadk/tui/widgets/assistant.py +0 -89
- ksadk/tui/widgets/base.py +0 -54
- ksadk/tui/widgets/chat_input.py +0 -246
- ksadk/tui/widgets/history.py +0 -156
- ksadk/tui/widgets/system.py +0 -87
- ksadk/tui/widgets/thinking.py +0 -110
- ksadk/tui/widgets/tool_call.py +0 -161
- ksadk/tui/widgets/user.py +0 -37
- {agentengine_sdk_python-0.6.9.dist-info → agentengine_sdk_python-0.8.0.dist-info}/WHEEL +0 -0
- {agentengine_sdk_python-0.6.9.dist-info → agentengine_sdk_python-0.8.0.dist-info}/entry_points.txt +0 -0
- {agentengine_sdk_python-0.6.9.dist-info → agentengine_sdk_python-0.8.0.dist-info}/licenses/LICENSE +0 -0
- {agentengine_sdk_python-0.6.9.dist-info → agentengine_sdk_python-0.8.0.dist-info}/top_level.txt +0 -0
ksadk/runners/patch_langchain.py
CHANGED
|
@@ -5,12 +5,6 @@ Monkey patch for langchain-openai to support reasoning_content field (e.g. for D
|
|
|
5
5
|
import logging
|
|
6
6
|
from typing import Any, Mapping, cast
|
|
7
7
|
|
|
8
|
-
from ksadk.conversations.model_options import (
|
|
9
|
-
model_options_for_chat_completions,
|
|
10
|
-
model_options_for_responses,
|
|
11
|
-
)
|
|
12
|
-
from ksadk.runtime_context import get_current_invocation_context
|
|
13
|
-
|
|
14
8
|
from langchain_core.messages import (
|
|
15
9
|
AIMessageChunk,
|
|
16
10
|
BaseMessageChunk,
|
|
@@ -22,6 +16,12 @@ from langchain_core.messages import (
|
|
|
22
16
|
)
|
|
23
17
|
from langchain_core.messages.tool import tool_call_chunk
|
|
24
18
|
|
|
19
|
+
from ksadk.conversations.model_options import (
|
|
20
|
+
model_options_for_chat_completions,
|
|
21
|
+
model_options_for_responses,
|
|
22
|
+
)
|
|
23
|
+
from ksadk.runtime_context import get_current_invocation_context
|
|
24
|
+
|
|
25
25
|
logger = logging.getLogger(__name__)
|
|
26
26
|
|
|
27
27
|
# Original function reference (to avoid recursion if patched multiple times)
|
|
@@ -95,22 +95,22 @@ _original_chat_get_request_payload = None
|
|
|
95
95
|
def _patched_convert_message_to_dict(message, *args, **kwargs):
|
|
96
96
|
"""Patched version to include reasoning_content in outgoing requests."""
|
|
97
97
|
from langchain_core.messages import AIMessage
|
|
98
|
-
|
|
98
|
+
|
|
99
99
|
# Call original function first
|
|
100
100
|
result = _original_convert_message_to_dict(message, *args, **kwargs)
|
|
101
|
-
|
|
101
|
+
|
|
102
102
|
# If this is an AIMessage with tool_calls and reasoning_content in additional_kwargs
|
|
103
103
|
if isinstance(message, AIMessage):
|
|
104
|
-
additional_kwargs = getattr(message,
|
|
105
|
-
reasoning = additional_kwargs.get(
|
|
106
|
-
|
|
104
|
+
additional_kwargs = getattr(message, "additional_kwargs", {}) or {}
|
|
105
|
+
reasoning = additional_kwargs.get("reasoning_content")
|
|
106
|
+
|
|
107
107
|
# Only add if we have tool_calls (required by some thinking models)
|
|
108
108
|
if message.tool_calls and reasoning is not None:
|
|
109
|
-
result[
|
|
109
|
+
result["reasoning_content"] = reasoning
|
|
110
110
|
elif message.tool_calls and reasoning is None:
|
|
111
111
|
# Force add empty reasoning_content for thinking models
|
|
112
|
-
result[
|
|
113
|
-
|
|
112
|
+
result["reasoning_content"] = ""
|
|
113
|
+
|
|
114
114
|
return result
|
|
115
115
|
|
|
116
116
|
|
|
@@ -168,7 +168,7 @@ def apply_patch():
|
|
|
168
168
|
# Patch 1: Fix receiving responses (capture reasoning_content)
|
|
169
169
|
_original_convert_delta = base_module._convert_delta_to_message_chunk
|
|
170
170
|
base_module._convert_delta_to_message_chunk = _patched_convert_delta_to_message_chunk
|
|
171
|
-
|
|
171
|
+
|
|
172
172
|
# Patch 2: Fix sending requests (include reasoning_content for tool_call messages)
|
|
173
173
|
_original_convert_message_to_dict = base_module._convert_message_to_dict
|
|
174
174
|
base_module._convert_message_to_dict = _patched_convert_message_to_dict
|
|
@@ -177,7 +177,7 @@ def apply_patch():
|
|
|
177
177
|
base_module.BaseChatOpenAI._get_request_payload = _patched_base_get_request_payload
|
|
178
178
|
_original_chat_get_request_payload = base_module.ChatOpenAI._get_request_payload
|
|
179
179
|
base_module.ChatOpenAI._get_request_payload = _patched_chat_get_request_payload
|
|
180
|
-
|
|
180
|
+
|
|
181
181
|
base_module._ksadk_patched = True
|
|
182
182
|
|
|
183
183
|
# logger.info("Applied langchain-openai patch for reasoning_content support")
|
ksadk/runners/remote_runner.py
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
"""
|
|
2
2
|
RemoteRunner - 远程 Agent 运行时
|
|
3
3
|
|
|
4
|
-
与
|
|
4
|
+
与 InteractionLoop 配合使用,提供和本地 Runner 一致的接口
|
|
5
5
|
"""
|
|
6
6
|
|
|
7
7
|
import json
|
|
@@ -43,6 +43,13 @@ class RemoteRunner(BaseRunner):
|
|
|
43
43
|
self._agent = None # 兼容 BaseRunner
|
|
44
44
|
self._responses_tool_names: dict[str, str] = {}
|
|
45
45
|
self._responses_tool_args: dict[str, str] = {}
|
|
46
|
+
self._responses_streamed_item_keys: set[str] = set()
|
|
47
|
+
self._responses_text_streamed = False
|
|
48
|
+
self._responses_reasoning_streamed = False
|
|
49
|
+
self._observed_model: str | None = None # 流式回包里观察到的真实模型名
|
|
50
|
+
self.available_models: list[dict[str, Any]] | None = (
|
|
51
|
+
None # ListAgentModels 拿到的可选模型列表
|
|
52
|
+
)
|
|
46
53
|
|
|
47
54
|
@staticmethod
|
|
48
55
|
def _normalize_api_format(api_format: Optional[str]) -> str:
|
|
@@ -107,19 +114,45 @@ class RemoteRunner(BaseRunner):
|
|
|
107
114
|
return str(user_input or "")
|
|
108
115
|
|
|
109
116
|
@staticmethod
|
|
110
|
-
def _build_responses_conversation_history(
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
):
|
|
117
|
+
def _build_responses_conversation_history(
|
|
118
|
+
history: Any, current_input: Any
|
|
119
|
+
) -> list[dict[str, Any]]:
|
|
120
|
+
if not isinstance(history, Sequence) or isinstance(history, (str, bytes, bytearray)):
|
|
114
121
|
return []
|
|
115
122
|
|
|
116
123
|
messages: list[dict[str, Any]] = []
|
|
124
|
+
current_output_call_ids: set[str] = set()
|
|
125
|
+
if isinstance(current_input, Mapping):
|
|
126
|
+
current_items = [current_input]
|
|
127
|
+
elif isinstance(current_input, Sequence) and not isinstance(
|
|
128
|
+
current_input, (str, bytes, bytearray)
|
|
129
|
+
):
|
|
130
|
+
current_items = [item for item in current_input if isinstance(item, Mapping)]
|
|
131
|
+
else:
|
|
132
|
+
current_items = []
|
|
133
|
+
for item in current_items:
|
|
134
|
+
if str(item.get("type") or "").strip().lower() != "function_call_output":
|
|
135
|
+
continue
|
|
136
|
+
call_id = str(item.get("call_id") or "").strip()
|
|
137
|
+
if call_id:
|
|
138
|
+
current_output_call_ids.add(call_id)
|
|
117
139
|
current_text = RemoteRunner._responses_message_text(
|
|
118
140
|
{"role": "user", "content": current_input}
|
|
119
141
|
).strip()
|
|
120
142
|
for item in history:
|
|
121
143
|
if not isinstance(item, Mapping):
|
|
122
144
|
continue
|
|
145
|
+
item_type = str(item.get("type") or "").strip().lower()
|
|
146
|
+
if item_type in {"function_call", "function_call_output"}:
|
|
147
|
+
# Responses tool items are already protocol-shaped. Do not
|
|
148
|
+
# reinterpret them as chat messages or they lose call_id.
|
|
149
|
+
if (
|
|
150
|
+
item_type == "function_call_output"
|
|
151
|
+
and str(item.get("call_id") or "").strip() in current_output_call_ids
|
|
152
|
+
):
|
|
153
|
+
continue
|
|
154
|
+
messages.append(dict(item))
|
|
155
|
+
continue
|
|
123
156
|
role = str(item.get("role") or "").strip().lower()
|
|
124
157
|
if role == "model":
|
|
125
158
|
role = "assistant"
|
|
@@ -139,7 +172,9 @@ class RemoteRunner(BaseRunner):
|
|
|
139
172
|
return messages
|
|
140
173
|
|
|
141
174
|
@staticmethod
|
|
142
|
-
def _responses_conversation_name(
|
|
175
|
+
def _responses_conversation_name(
|
|
176
|
+
input_data: Mapping[str, Any], session_id: Optional[str]
|
|
177
|
+
) -> str:
|
|
143
178
|
if not session_id:
|
|
144
179
|
return ""
|
|
145
180
|
platform_context = input_data.get("platform_context")
|
|
@@ -176,10 +211,27 @@ class RemoteRunner(BaseRunner):
|
|
|
176
211
|
"input": self._build_responses_input(user_input),
|
|
177
212
|
"stream": stream,
|
|
178
213
|
}
|
|
179
|
-
history_enabled =
|
|
214
|
+
history_enabled = (
|
|
215
|
+
bool(input_data.get("responses_conversation"))
|
|
216
|
+
or bool(input_data.get("responses_history"))
|
|
217
|
+
) and not previous_response_id
|
|
180
218
|
if history_enabled:
|
|
219
|
+
structured_history = input_data.get("responses_history")
|
|
220
|
+
history_input: Sequence[Any] | None
|
|
221
|
+
if isinstance(structured_history, Sequence) and not isinstance(
|
|
222
|
+
structured_history, (str, bytes, bytearray)
|
|
223
|
+
):
|
|
224
|
+
history_input = structured_history
|
|
225
|
+
else:
|
|
226
|
+
fallback_history = input_data.get("history")
|
|
227
|
+
history_input = (
|
|
228
|
+
fallback_history
|
|
229
|
+
if isinstance(fallback_history, Sequence)
|
|
230
|
+
and not isinstance(fallback_history, (str, bytes, bytearray))
|
|
231
|
+
else None
|
|
232
|
+
)
|
|
181
233
|
history = self._build_responses_conversation_history(
|
|
182
|
-
|
|
234
|
+
history_input,
|
|
183
235
|
user_input,
|
|
184
236
|
)
|
|
185
237
|
if history:
|
|
@@ -188,9 +240,7 @@ class RemoteRunner(BaseRunner):
|
|
|
188
240
|
if conversation and not previous_response_id:
|
|
189
241
|
payload["conversation"] = conversation
|
|
190
242
|
elif (
|
|
191
|
-
input_data.get("responses_conversation")
|
|
192
|
-
and session_id
|
|
193
|
-
and not previous_response_id
|
|
243
|
+
input_data.get("responses_conversation") and session_id and not previous_response_id
|
|
194
244
|
):
|
|
195
245
|
conversation = self._responses_conversation_name(input_data, str(session_id))
|
|
196
246
|
if conversation:
|
|
@@ -204,9 +254,15 @@ class RemoteRunner(BaseRunner):
|
|
|
204
254
|
return payload
|
|
205
255
|
|
|
206
256
|
@staticmethod
|
|
207
|
-
def _builtin_response_tool_schemas(
|
|
257
|
+
def _builtin_response_tool_schemas(
|
|
258
|
+
input_data: Mapping[str, Any] | None = None,
|
|
259
|
+
) -> list[dict[str, Any]]:
|
|
208
260
|
try:
|
|
209
|
-
from ksadk.toolsets import
|
|
261
|
+
from ksadk.toolsets import (
|
|
262
|
+
builtin_tool_descriptors_for_runtime,
|
|
263
|
+
builtin_tools_mode,
|
|
264
|
+
describe_agentengine_tools,
|
|
265
|
+
)
|
|
210
266
|
|
|
211
267
|
mode = builtin_tools_mode(default="off")
|
|
212
268
|
descriptors = builtin_tool_descriptors_for_runtime(mode=mode)
|
|
@@ -215,7 +271,9 @@ class RemoteRunner(BaseRunner):
|
|
|
215
271
|
deferred_names = RemoteRunner._deferred_tool_names(input_data)
|
|
216
272
|
if deferred_names:
|
|
217
273
|
try:
|
|
218
|
-
direct_descriptors = describe_agentengine_tools(
|
|
274
|
+
direct_descriptors = describe_agentengine_tools(
|
|
275
|
+
include=deferred_names, profile="coding"
|
|
276
|
+
)
|
|
219
277
|
except Exception:
|
|
220
278
|
direct_descriptors = []
|
|
221
279
|
direct_descriptors = [
|
|
@@ -342,7 +400,9 @@ class RemoteRunner(BaseRunner):
|
|
|
342
400
|
usage = self._response_usage_payload(data)
|
|
343
401
|
|
|
344
402
|
if self.api_format == "responses":
|
|
345
|
-
result = {
|
|
403
|
+
result: dict[str, Any] = {
|
|
404
|
+
"output": self._extract_responses_output_text(data) or str(data)
|
|
405
|
+
}
|
|
346
406
|
if usage:
|
|
347
407
|
result["usage"] = usage
|
|
348
408
|
return result
|
|
@@ -362,6 +422,14 @@ class RemoteRunner(BaseRunner):
|
|
|
362
422
|
"""流式调用远程 Agent"""
|
|
363
423
|
import httpx
|
|
364
424
|
|
|
425
|
+
# 工具 item/call_id 只在单次 response 内有效。RemoteRunner 会被 TUI 多轮复用,
|
|
426
|
+
# 若保留上一轮的追踪状态,runtime 复用 id 时 response.completed 会被误判为重放。
|
|
427
|
+
self._responses_tool_names.clear()
|
|
428
|
+
self._responses_tool_args.clear()
|
|
429
|
+
self._responses_streamed_item_keys.clear()
|
|
430
|
+
self._responses_text_streamed = False
|
|
431
|
+
self._responses_reasoning_streamed = False
|
|
432
|
+
|
|
365
433
|
user_input = input_data.get("input", "")
|
|
366
434
|
session_id = input_data.get("session_id") or self.session_id
|
|
367
435
|
|
|
@@ -406,6 +474,17 @@ class RemoteRunner(BaseRunner):
|
|
|
406
474
|
try:
|
|
407
475
|
data = json.loads(data_str)
|
|
408
476
|
|
|
477
|
+
# 记录回包里的真实模型名:
|
|
478
|
+
# chat completions 顶层 data.model;responses 格式在
|
|
479
|
+
# data.response.model(response.completed 事件的 response 对象)。
|
|
480
|
+
observed = data.get("model") if isinstance(data, Mapping) else None
|
|
481
|
+
if not observed and isinstance(data, Mapping):
|
|
482
|
+
resp = data.get("response")
|
|
483
|
+
if isinstance(resp, Mapping):
|
|
484
|
+
observed = resp.get("model")
|
|
485
|
+
if observed and not isinstance(observed, (list, dict)):
|
|
486
|
+
self._observed_model = str(observed)
|
|
487
|
+
|
|
409
488
|
if self.api_format == "responses":
|
|
410
489
|
async for item in self._iter_responses_stream_events(
|
|
411
490
|
data, event_name=event_name
|
|
@@ -413,11 +492,28 @@ class RemoteRunner(BaseRunner):
|
|
|
413
492
|
yield item
|
|
414
493
|
continue
|
|
415
494
|
|
|
495
|
+
# 兜底:api_format 标成 chat 但 runtime 实发 responses 格式
|
|
496
|
+
# 事件(event_name 或 data.type 以 response. 开头)→ 按 responses
|
|
497
|
+
# 解析,否则 response.reasoning.delta 会被 chat 路径当顶层 text 显示。
|
|
498
|
+
_ev = event_name or (
|
|
499
|
+
str(data.get("type")) if isinstance(data, Mapping) else ""
|
|
500
|
+
)
|
|
501
|
+
if _ev.startswith("response."):
|
|
502
|
+
async for item in self._iter_responses_stream_events(
|
|
503
|
+
data, event_name=event_name
|
|
504
|
+
):
|
|
505
|
+
yield item
|
|
506
|
+
continue
|
|
507
|
+
|
|
416
508
|
# 解析 OpenAI Chat Completions 流式格式
|
|
417
509
|
choices = data.get("choices", [])
|
|
418
510
|
usage = data.get("usage")
|
|
419
511
|
if isinstance(usage, Mapping):
|
|
420
|
-
|
|
512
|
+
final_chunk = {"type": "final", "usage": dict(usage)}
|
|
513
|
+
metadata = data.get("metadata")
|
|
514
|
+
if isinstance(metadata, Mapping):
|
|
515
|
+
final_chunk["metadata"] = dict(metadata)
|
|
516
|
+
yield final_chunk
|
|
421
517
|
final_sent = True
|
|
422
518
|
if choices:
|
|
423
519
|
delta = choices[0].get("delta", {})
|
|
@@ -429,6 +525,13 @@ class RemoteRunner(BaseRunner):
|
|
|
429
525
|
if content:
|
|
430
526
|
accumulated_text += content
|
|
431
527
|
yield {"delta": content, "type": "text"}
|
|
528
|
+
else:
|
|
529
|
+
# 非标准简化流(runtime 直发顶层 delta,无 choices 包装):
|
|
530
|
+
# 兜底提取顶层 delta 作为正文,与 _extract_content 口径一致。
|
|
531
|
+
top_delta = data.get("delta")
|
|
532
|
+
if isinstance(top_delta, str) and top_delta:
|
|
533
|
+
accumulated_text += top_delta
|
|
534
|
+
yield {"delta": top_delta, "type": "text"}
|
|
432
535
|
|
|
433
536
|
except json.JSONDecodeError:
|
|
434
537
|
pass
|
|
@@ -484,11 +587,14 @@ class RemoteRunner(BaseRunner):
|
|
|
484
587
|
def _remember_responses_tool(
|
|
485
588
|
self, key: str, item: Dict[str, Any], name: str, args: str
|
|
486
589
|
) -> None:
|
|
590
|
+
if key:
|
|
591
|
+
self._responses_streamed_item_keys.add(key)
|
|
487
592
|
if key:
|
|
488
593
|
self._responses_tool_names[key] = name
|
|
489
594
|
self._responses_tool_args[key] = args
|
|
490
595
|
call_id = str(item.get("call_id") or "")
|
|
491
596
|
if call_id:
|
|
597
|
+
self._responses_streamed_item_keys.add(call_id)
|
|
492
598
|
self._responses_tool_names[call_id] = name
|
|
493
599
|
self._responses_tool_args[call_id] = args
|
|
494
600
|
|
|
@@ -526,6 +632,8 @@ class RemoteRunner(BaseRunner):
|
|
|
526
632
|
data: Dict[str, Any],
|
|
527
633
|
*,
|
|
528
634
|
status: str,
|
|
635
|
+
replay_completed_text: bool = False,
|
|
636
|
+
replay_completed_reasoning: bool = False,
|
|
529
637
|
) -> AsyncIterator[Dict[str, Any]]:
|
|
530
638
|
item = data.get("item") or data.get("output_item") or data
|
|
531
639
|
if not isinstance(item, dict):
|
|
@@ -541,15 +649,31 @@ class RemoteRunner(BaseRunner):
|
|
|
541
649
|
else item.get("args", item.get("input"))
|
|
542
650
|
)
|
|
543
651
|
self._remember_responses_tool(key, item, name, args)
|
|
544
|
-
yield {
|
|
652
|
+
yield {
|
|
653
|
+
"type": "tool_call",
|
|
654
|
+
"tool_name": name,
|
|
655
|
+
"tool_args": args,
|
|
656
|
+
"status": status,
|
|
657
|
+
"call_id": key,
|
|
658
|
+
}
|
|
545
659
|
return
|
|
546
660
|
|
|
547
661
|
if item_type == "function_call_output":
|
|
548
662
|
name = self._responses_tool_name(key, item)
|
|
663
|
+
if key:
|
|
664
|
+
self._responses_streamed_item_keys.add(key)
|
|
665
|
+
call_id = str(item.get("call_id") or "")
|
|
666
|
+
if call_id:
|
|
667
|
+
self._responses_streamed_item_keys.add(call_id)
|
|
549
668
|
output = self._stringify_responses_payload(
|
|
550
669
|
item.get("output") if "output" in item else item.get("result", item.get("content"))
|
|
551
670
|
)
|
|
552
|
-
yield {
|
|
671
|
+
yield {
|
|
672
|
+
"type": "tool_result",
|
|
673
|
+
"tool_name": name,
|
|
674
|
+
"tool_output": output,
|
|
675
|
+
"call_id": call_id or key,
|
|
676
|
+
}
|
|
553
677
|
return
|
|
554
678
|
|
|
555
679
|
if item_type == "mcp_approval_request":
|
|
@@ -576,13 +700,15 @@ class RemoteRunner(BaseRunner):
|
|
|
576
700
|
|
|
577
701
|
if item_type in {"reasoning", "reasoning_summary", "reasoning_summary_text"}:
|
|
578
702
|
text = self._responses_item_text(item)
|
|
579
|
-
if text:
|
|
703
|
+
if text and (status != "completed" or replay_completed_reasoning):
|
|
704
|
+
self._responses_reasoning_streamed = True
|
|
580
705
|
yield {"delta": text, "type": "thinking"}
|
|
581
706
|
return
|
|
582
707
|
|
|
583
708
|
if item_type == "message":
|
|
584
709
|
text = self._responses_item_text(item)
|
|
585
|
-
if text and status != "completed":
|
|
710
|
+
if text and (status != "completed" or replay_completed_text):
|
|
711
|
+
self._responses_text_streamed = True
|
|
586
712
|
yield {"delta": text, "type": "text"}
|
|
587
713
|
return
|
|
588
714
|
|
|
@@ -596,6 +722,7 @@ class RemoteRunner(BaseRunner):
|
|
|
596
722
|
if event_name == "response.reasoning.delta":
|
|
597
723
|
delta = data.get("delta")
|
|
598
724
|
if delta:
|
|
725
|
+
self._responses_reasoning_streamed = True
|
|
599
726
|
yield {"delta": str(delta), "type": "thinking"}
|
|
600
727
|
return
|
|
601
728
|
if event_type in {
|
|
@@ -606,12 +733,16 @@ class RemoteRunner(BaseRunner):
|
|
|
606
733
|
}:
|
|
607
734
|
delta = data.get("delta") or data.get("text")
|
|
608
735
|
if delta:
|
|
736
|
+
self._responses_reasoning_streamed = True
|
|
609
737
|
yield {"delta": str(delta), "type": "thinking"}
|
|
610
738
|
return
|
|
611
|
-
if event_type
|
|
612
|
-
|
|
613
|
-
if
|
|
614
|
-
|
|
739
|
+
if event_type in {"response.output_text.delta", "response.output_text.done"}:
|
|
740
|
+
text = data.get("delta") or data.get("text")
|
|
741
|
+
if text and (
|
|
742
|
+
event_type == "response.output_text.delta" or not self._responses_text_streamed
|
|
743
|
+
):
|
|
744
|
+
self._responses_text_streamed = True
|
|
745
|
+
yield {"delta": str(text), "type": "text"}
|
|
615
746
|
return
|
|
616
747
|
if event_type == "response.output_item.added":
|
|
617
748
|
async for item in self._iter_responses_output_item(data, status="running"):
|
|
@@ -621,13 +752,51 @@ class RemoteRunner(BaseRunner):
|
|
|
621
752
|
async for item in self._iter_responses_output_item(data, status="completed"):
|
|
622
753
|
yield item
|
|
623
754
|
return
|
|
755
|
+
# ksadk/runtime 特有 tool 事件(对标 hosted UI responses-stream.js:176-186)
|
|
756
|
+
if event_type in {"response.tool_call", "response.ksadk.stage_tool_call"}:
|
|
757
|
+
name = str(data.get("name") or data.get("tool_name") or "tool")
|
|
758
|
+
args = self._stringify_responses_payload(
|
|
759
|
+
data.get("args") if "args" in data else data.get("arguments")
|
|
760
|
+
)
|
|
761
|
+
cid = str(data.get("call_id") or data.get("item_id") or data.get("run_id") or "")
|
|
762
|
+
yield {
|
|
763
|
+
"type": "tool_call",
|
|
764
|
+
"tool_name": name,
|
|
765
|
+
"tool_args": args,
|
|
766
|
+
"status": "running",
|
|
767
|
+
"call_id": cid,
|
|
768
|
+
}
|
|
769
|
+
return
|
|
770
|
+
if event_type in {
|
|
771
|
+
"response.tool_result",
|
|
772
|
+
"response.ksadk.tool_result",
|
|
773
|
+
"response.ksadk.stage_tool_result",
|
|
774
|
+
}:
|
|
775
|
+
name = str(data.get("name") or data.get("tool_name") or "tool")
|
|
776
|
+
output = self._stringify_responses_payload(
|
|
777
|
+
data.get("output") if "output" in data else data.get("result")
|
|
778
|
+
)
|
|
779
|
+
cid = str(data.get("call_id") or data.get("item_id") or data.get("run_id") or "")
|
|
780
|
+
yield {
|
|
781
|
+
"type": "tool_result",
|
|
782
|
+
"tool_name": name,
|
|
783
|
+
"tool_output": output,
|
|
784
|
+
"call_id": cid,
|
|
785
|
+
}
|
|
786
|
+
return
|
|
624
787
|
if event_type == "response.function_call_arguments.delta":
|
|
625
788
|
key = str(data.get("item_id") or data.get("call_id") or "")
|
|
626
789
|
name = self._responses_tool_name(key, data)
|
|
627
790
|
args = f"{self._responses_tool_args.get(key, '')}{str(data.get('delta') or '')}"
|
|
628
791
|
if key:
|
|
629
792
|
self._responses_tool_args[key] = args
|
|
630
|
-
yield {
|
|
793
|
+
yield {
|
|
794
|
+
"type": "tool_call",
|
|
795
|
+
"tool_name": name,
|
|
796
|
+
"tool_args": args,
|
|
797
|
+
"status": "running",
|
|
798
|
+
"call_id": key,
|
|
799
|
+
}
|
|
631
800
|
return
|
|
632
801
|
if event_type == "response.function_call_arguments.done":
|
|
633
802
|
key = str(data.get("item_id") or data.get("call_id") or "")
|
|
@@ -637,31 +806,88 @@ class RemoteRunner(BaseRunner):
|
|
|
637
806
|
)
|
|
638
807
|
if key:
|
|
639
808
|
self._responses_tool_args[key] = args
|
|
640
|
-
yield {
|
|
809
|
+
yield {
|
|
810
|
+
"type": "tool_call",
|
|
811
|
+
"tool_name": name,
|
|
812
|
+
"tool_args": args,
|
|
813
|
+
"status": "running",
|
|
814
|
+
"call_id": key,
|
|
815
|
+
}
|
|
641
816
|
return
|
|
642
817
|
if event_type == "response.completed":
|
|
643
|
-
|
|
644
|
-
|
|
645
|
-
|
|
818
|
+
nested_response = data.get("response")
|
|
819
|
+
response_data: dict[str, Any] = (
|
|
820
|
+
dict(nested_response) if isinstance(nested_response, dict) else data
|
|
821
|
+
)
|
|
822
|
+
completed_output = (
|
|
823
|
+
response_data.get("output") if isinstance(response_data, dict) else None
|
|
824
|
+
)
|
|
825
|
+
if isinstance(completed_output, list):
|
|
826
|
+
replayed_item_keys = set(self._responses_streamed_item_keys)
|
|
827
|
+
replay_completed_text = not self._responses_text_streamed
|
|
828
|
+
replay_completed_reasoning = not self._responses_reasoning_streamed
|
|
829
|
+
for item in completed_output:
|
|
830
|
+
if isinstance(item, dict):
|
|
831
|
+
key = self._responses_item_key(item, {"item": item})
|
|
832
|
+
call_id = str(item.get("call_id") or "")
|
|
833
|
+
if (key and key in replayed_item_keys) or (
|
|
834
|
+
call_id and call_id in replayed_item_keys
|
|
835
|
+
):
|
|
836
|
+
continue
|
|
837
|
+
async for projected in self._iter_responses_output_item(
|
|
838
|
+
{"item": item},
|
|
839
|
+
status="completed",
|
|
840
|
+
replay_completed_text=replay_completed_text,
|
|
841
|
+
replay_completed_reasoning=replay_completed_reasoning,
|
|
842
|
+
):
|
|
843
|
+
yield projected
|
|
646
844
|
chunk = {
|
|
647
845
|
"type": "responses_output",
|
|
648
|
-
"output":
|
|
649
|
-
"response_id":
|
|
846
|
+
"output": completed_output,
|
|
847
|
+
"response_id": response_data.get("id"),
|
|
650
848
|
}
|
|
651
|
-
usage =
|
|
849
|
+
usage = response_data.get("usage")
|
|
652
850
|
if isinstance(usage, Mapping):
|
|
653
851
|
chunk["usage"] = dict(usage)
|
|
852
|
+
metadata = response_data.get("metadata")
|
|
853
|
+
if isinstance(metadata, Mapping):
|
|
854
|
+
chunk["metadata"] = dict(metadata)
|
|
654
855
|
yield chunk
|
|
655
856
|
return
|
|
857
|
+
# response.content_part.delta:glm 等模型把 reasoning 走这个事件,
|
|
858
|
+
# partType 含 "reasoning" → thinking(不显示),否则 text(对标 hosted UI)。
|
|
859
|
+
if event_type == "response.content_part.delta":
|
|
860
|
+
part_value = data.get("part")
|
|
861
|
+
part: dict[str, Any] = dict(part_value) if isinstance(part_value, dict) else {}
|
|
862
|
+
delta = data.get("delta")
|
|
863
|
+
part_type = str(
|
|
864
|
+
part.get("type")
|
|
865
|
+
or (delta.get("type") if isinstance(delta, dict) else "")
|
|
866
|
+
or data.get("content_type")
|
|
867
|
+
or ""
|
|
868
|
+
)
|
|
869
|
+
text = ""
|
|
870
|
+
if isinstance(delta, dict):
|
|
871
|
+
text = str(delta.get("text") or delta.get("content") or "")
|
|
872
|
+
elif isinstance(delta, str):
|
|
873
|
+
text = delta
|
|
874
|
+
if not text:
|
|
875
|
+
text = str(data.get("text") or "")
|
|
876
|
+
if not text:
|
|
877
|
+
return
|
|
878
|
+
if "reasoning" in part_type:
|
|
879
|
+
self._responses_reasoning_streamed = True
|
|
880
|
+
yield {"delta": text, "type": "thinking"}
|
|
881
|
+
else:
|
|
882
|
+
self._responses_text_streamed = True
|
|
883
|
+
yield {"delta": text, "type": "text"}
|
|
884
|
+
return
|
|
656
885
|
if event_type == "response.failed":
|
|
657
886
|
yield {"type": "error", "message": self._responses_error_message(data)}
|
|
658
887
|
return
|
|
659
888
|
if event_type == "response.incomplete":
|
|
660
889
|
yield {"type": "error", "message": "Agent 响应未完成"}
|
|
661
890
|
return
|
|
662
|
-
|
|
663
|
-
|
|
664
|
-
|
|
665
|
-
output_text = RemoteRunner._extract_responses_output_text(data)
|
|
666
|
-
if output_text and event_type != "response.completed":
|
|
667
|
-
yield {"delta": output_text, "type": "text"}
|
|
891
|
+
# 未知事件默认丢弃(对标 hosted UI responses-stream.js: 未知事件 return [])。
|
|
892
|
+
# 之前默认把 data.delta 当 text 显示,会导致 reasoning 走未识别事件时漏进正文。
|
|
893
|
+
# 正文已由 output_text.delta / content_part.delta 显式处理,未知事件不该当正文。
|
ksadk/runners/utils/langfuse.py
CHANGED
|
@@ -157,7 +157,7 @@ def get_langfuse_callbacks() -> list[Any]:
|
|
|
157
157
|
return callbacks
|
|
158
158
|
|
|
159
159
|
|
|
160
|
-
def get_langfuse_metadata(session_id: str = None) -> dict:
|
|
160
|
+
def get_langfuse_metadata(session_id: str | None = None) -> dict[str, Any]:
|
|
161
161
|
"""获取 Langfuse 的 metadata 字典
|
|
162
162
|
|
|
163
163
|
通过 metadata 字段传递 trace 属性:
|
|
@@ -171,7 +171,7 @@ def get_langfuse_metadata(session_id: str = None) -> dict:
|
|
|
171
171
|
Returns:
|
|
172
172
|
包含 Langfuse 属性的 metadata 字典
|
|
173
173
|
"""
|
|
174
|
-
metadata = {}
|
|
174
|
+
metadata: dict[str, Any] = {}
|
|
175
175
|
|
|
176
176
|
if session_id:
|
|
177
177
|
metadata["langfuse_session_id"] = session_id
|
|
@@ -201,7 +201,7 @@ def get_langfuse_metadata(session_id: str = None) -> dict:
|
|
|
201
201
|
return metadata
|
|
202
202
|
|
|
203
203
|
|
|
204
|
-
def prepare_trace_metadata(session_id: str = None) -> tuple:
|
|
204
|
+
def prepare_trace_metadata(session_id: str | None = None) -> tuple[Any, list[Any], Any, Any]:
|
|
205
205
|
"""准备 Trace 元数据
|
|
206
206
|
|
|
207
207
|
Returns:
|
ksadk/runners/utils/loader.py
CHANGED
|
@@ -18,37 +18,37 @@ def load_agent_module(
|
|
|
18
18
|
force_reload: bool = False,
|
|
19
19
|
) -> Any:
|
|
20
20
|
"""加载 Agent 模块
|
|
21
|
-
|
|
21
|
+
|
|
22
22
|
Args:
|
|
23
23
|
project_dir: 项目目录
|
|
24
24
|
entry_point: 入口文件 (e.g., "agent.py")
|
|
25
25
|
agent_variable: Agent 变量名 (e.g., "root_agent", "graph")
|
|
26
|
-
|
|
26
|
+
|
|
27
27
|
Returns:
|
|
28
28
|
加载的 Agent 对象
|
|
29
|
-
|
|
29
|
+
|
|
30
30
|
Raises:
|
|
31
31
|
ImportError: 模块导入失败
|
|
32
32
|
AttributeError: 未找到 Agent 变量
|
|
33
33
|
"""
|
|
34
34
|
project_path = Path(project_dir).resolve()
|
|
35
|
-
|
|
35
|
+
|
|
36
36
|
# 添加项目目录到 Python 路径
|
|
37
37
|
if str(project_path) not in sys.path:
|
|
38
38
|
sys.path.insert(0, str(project_path))
|
|
39
39
|
src_path = project_path / "src"
|
|
40
40
|
if src_path.is_dir() and str(src_path) not in sys.path:
|
|
41
41
|
sys.path.insert(0, str(src_path))
|
|
42
|
-
|
|
42
|
+
|
|
43
43
|
# 确定模块名
|
|
44
44
|
if entry_point.endswith(".py"):
|
|
45
45
|
module_name = entry_point[:-3]
|
|
46
46
|
else:
|
|
47
47
|
module_name = entry_point
|
|
48
|
-
|
|
48
|
+
|
|
49
49
|
# 路径转换为模块路径
|
|
50
50
|
module_name = module_name.replace("/", ".").replace("\\", ".")
|
|
51
|
-
|
|
51
|
+
|
|
52
52
|
try:
|
|
53
53
|
if force_reload and module_name in sys.modules:
|
|
54
54
|
module = importlib.reload(sys.modules[module_name])
|