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/cli/cmd_invoke.py
CHANGED
|
@@ -4,16 +4,18 @@ agentengine invoke - 与已部署的 Agent 进行交互
|
|
|
4
4
|
支持 OpenAI 兼容格式调用,支持流式输出
|
|
5
5
|
"""
|
|
6
6
|
|
|
7
|
-
import click
|
|
8
7
|
import asyncio
|
|
9
8
|
import io
|
|
10
9
|
import json
|
|
11
10
|
import os
|
|
11
|
+
import time
|
|
12
|
+
import uuid
|
|
12
13
|
from datetime import datetime
|
|
13
14
|
from pathlib import Path
|
|
14
15
|
from typing import Any, Callable, Dict, Optional
|
|
15
|
-
|
|
16
|
-
import
|
|
16
|
+
|
|
17
|
+
import click
|
|
18
|
+
|
|
17
19
|
from ksadk.api import AgentEngineAPIError, AgentEngineClient
|
|
18
20
|
from ksadk.cli.agent_ref import merge_agent_inputs, resolve_agent_ref, resolve_openclaw_ref
|
|
19
21
|
from ksadk.cli.cmd_files import (
|
|
@@ -24,20 +26,28 @@ from ksadk.cli.cmd_files import (
|
|
|
24
26
|
_normalize_workspace_dir,
|
|
25
27
|
_push_workspace_files,
|
|
26
28
|
)
|
|
27
|
-
from ksadk.cli.resource_common import
|
|
29
|
+
from ksadk.cli.resource_common import (
|
|
30
|
+
CONTEXT_SETTINGS,
|
|
31
|
+
CompatibilityAliasCommand,
|
|
32
|
+
print_compatibility_hint,
|
|
33
|
+
)
|
|
28
34
|
from ksadk.hermes_terminal import run_hermes_terminal_session
|
|
29
35
|
from ksadk.terminal_client import run_terminal_session
|
|
30
36
|
from ksadk_runtime_common.workspace_files.constants import DEFAULT_WORKSPACE_MAX_UPLOAD_BYTES
|
|
31
37
|
|
|
38
|
+
console: Any = None
|
|
39
|
+
Markdown: Any = None
|
|
40
|
+
Live: Any = None
|
|
32
41
|
try:
|
|
33
|
-
from rich.console import Console
|
|
34
|
-
from rich.
|
|
35
|
-
from rich.
|
|
36
|
-
|
|
42
|
+
from rich.console import Console as RichConsole
|
|
43
|
+
from rich.live import Live as RichLive
|
|
44
|
+
from rich.markdown import Markdown as RichMarkdown
|
|
45
|
+
|
|
46
|
+
console = RichConsole()
|
|
47
|
+
Markdown = RichMarkdown
|
|
48
|
+
Live = RichLive
|
|
37
49
|
except ImportError:
|
|
38
|
-
|
|
39
|
-
Markdown = None
|
|
40
|
-
Live = None
|
|
50
|
+
pass
|
|
41
51
|
|
|
42
52
|
|
|
43
53
|
@click.command(
|
|
@@ -147,9 +157,9 @@ def _resolve_remote_workspace_seed_path(
|
|
|
147
157
|
remote_workspace_path: str | None,
|
|
148
158
|
) -> str:
|
|
149
159
|
if remote_workspace_path:
|
|
150
|
-
return _normalize_workspace_dir(remote_workspace_path)
|
|
160
|
+
return str(_normalize_workspace_dir(remote_workspace_path))
|
|
151
161
|
default_name = local_workspace.resolve().name or local_workspace.name or "workspace"
|
|
152
|
-
return _normalize_workspace_dir(default_name)
|
|
162
|
+
return str(_normalize_workspace_dir(default_name))
|
|
153
163
|
|
|
154
164
|
|
|
155
165
|
def _summarize_local_workspace_dir(
|
|
@@ -200,10 +210,12 @@ def _describe_workspace_sync_phase(event: dict[str, Any] | None) -> str:
|
|
|
200
210
|
return "同步 workspace"
|
|
201
211
|
|
|
202
212
|
|
|
203
|
-
def _render_workspace_sync_progress_bar(
|
|
213
|
+
def _render_workspace_sync_progress_bar(
|
|
214
|
+
current: object | None, total: object | None, *, width: int = 20
|
|
215
|
+
) -> str:
|
|
204
216
|
try:
|
|
205
|
-
current_value = int(current or 0)
|
|
206
|
-
total_value = max(int(total or 0), 1)
|
|
217
|
+
current_value = int(str(current or 0))
|
|
218
|
+
total_value = max(int(str(total or 0)), 1)
|
|
207
219
|
except (TypeError, ValueError):
|
|
208
220
|
current_value = 0
|
|
209
221
|
total_value = 1
|
|
@@ -214,8 +226,8 @@ def _render_workspace_sync_progress_bar(current: object | None, total: object |
|
|
|
214
226
|
|
|
215
227
|
def _format_workspace_sync_percent(current: object | None, total: object | None) -> str:
|
|
216
228
|
try:
|
|
217
|
-
current_value = float(current or 0)
|
|
218
|
-
total_value = max(float(total or 0), 1.0)
|
|
229
|
+
current_value = float(str(current or 0))
|
|
230
|
+
total_value = max(float(str(total or 0)), 1.0)
|
|
219
231
|
except (TypeError, ValueError):
|
|
220
232
|
current_value = 0.0
|
|
221
233
|
total_value = 1.0
|
|
@@ -244,7 +256,8 @@ def _build_workspace_sync_progress_emitter(*, verbose: bool) -> Callable[[dict[s
|
|
|
244
256
|
click.secho(
|
|
245
257
|
"📂 准备同步 workspace: "
|
|
246
258
|
f"{event.get('total_files', 0)} 个文件,"
|
|
247
|
-
f"{_format_size(event.get('total_bytes', 0))} ->
|
|
259
|
+
f"{_format_size(event.get('total_bytes', 0))} -> "
|
|
260
|
+
f"workspace:/{event.get('remote_path', '.')}",
|
|
248
261
|
fg="blue",
|
|
249
262
|
)
|
|
250
263
|
ignored_artifacts = list(event.get("ignored_artifacts") or [])
|
|
@@ -324,7 +337,7 @@ def _extract_workspace_upload_limit(bootstrap: dict[str, Any] | None) -> int | N
|
|
|
324
337
|
return None
|
|
325
338
|
raw_limit = workspace.get("max_upload_bytes") or workspace.get("MaxUploadBytes")
|
|
326
339
|
try:
|
|
327
|
-
limit = int(raw_limit)
|
|
340
|
+
limit = int(str(raw_limit))
|
|
328
341
|
except (TypeError, ValueError):
|
|
329
342
|
return None
|
|
330
343
|
return limit if limit > 0 else None
|
|
@@ -336,7 +349,7 @@ async def _lookup_workspace_upload_limit(
|
|
|
336
349
|
region: str,
|
|
337
350
|
) -> int:
|
|
338
351
|
if not agent_ref:
|
|
339
|
-
return DEFAULT_WORKSPACE_MAX_UPLOAD_BYTES
|
|
352
|
+
return int(DEFAULT_WORKSPACE_MAX_UPLOAD_BYTES)
|
|
340
353
|
|
|
341
354
|
try:
|
|
342
355
|
async with AgentEngineClient(region=region) as client:
|
|
@@ -345,9 +358,9 @@ async def _lookup_workspace_upload_limit(
|
|
|
345
358
|
else:
|
|
346
359
|
payload = await client.get_agent_ui_bootstrap(name=agent_ref)
|
|
347
360
|
except Exception:
|
|
348
|
-
return DEFAULT_WORKSPACE_MAX_UPLOAD_BYTES
|
|
361
|
+
return int(DEFAULT_WORKSPACE_MAX_UPLOAD_BYTES)
|
|
349
362
|
|
|
350
|
-
return _extract_workspace_upload_limit(payload) or DEFAULT_WORKSPACE_MAX_UPLOAD_BYTES
|
|
363
|
+
return int(_extract_workspace_upload_limit(payload) or DEFAULT_WORKSPACE_MAX_UPLOAD_BYTES)
|
|
351
364
|
|
|
352
365
|
|
|
353
366
|
async def _sync_local_workspace_for_hermes_invoke(
|
|
@@ -394,7 +407,8 @@ async def _sync_local_workspace_for_hermes_invoke(
|
|
|
394
407
|
if item["size_bytes"] > max_upload_bytes:
|
|
395
408
|
raise click.ClickException(
|
|
396
409
|
"本地目录中存在超过远端 workspace 上传上限的文件:"
|
|
397
|
-
f"{item['path']}({_format_size(item['size_bytes'])} >
|
|
410
|
+
f"{item['path']}({_format_size(item['size_bytes'])} > "
|
|
411
|
+
f"{_format_size(max_upload_bytes)})"
|
|
398
412
|
)
|
|
399
413
|
|
|
400
414
|
if summary["total_bytes"] > max_upload_bytes:
|
|
@@ -412,7 +426,7 @@ async def _sync_local_workspace_for_hermes_invoke(
|
|
|
412
426
|
progress_callback(event)
|
|
413
427
|
|
|
414
428
|
try:
|
|
415
|
-
|
|
429
|
+
result = await _push_workspace_files(
|
|
416
430
|
agent_ref=agent_ref,
|
|
417
431
|
local_dir=local_dir,
|
|
418
432
|
remote_path=remote_path,
|
|
@@ -424,11 +438,12 @@ async def _sync_local_workspace_for_hermes_invoke(
|
|
|
424
438
|
ignore_dev_artifacts=True,
|
|
425
439
|
ignore_git_artifacts=".git" in list(summary.get("ignored_artifacts") or []),
|
|
426
440
|
)
|
|
441
|
+
if not isinstance(result, dict):
|
|
442
|
+
raise click.ClickException("同步远端 workspace 返回了无效响应")
|
|
443
|
+
return result
|
|
427
444
|
except AgentEngineAPIError as exc:
|
|
428
445
|
phase = _describe_workspace_sync_phase(last_progress)
|
|
429
|
-
raise click.ClickException(
|
|
430
|
-
f"同步远端 workspace 失败({phase}):{exc.message}"
|
|
431
|
-
) from exc
|
|
446
|
+
raise click.ClickException(f"同步远端 workspace 失败({phase}):{exc.message}") from exc
|
|
432
447
|
|
|
433
448
|
|
|
434
449
|
def run_invoke_command(
|
|
@@ -479,7 +494,7 @@ def run_invoke_command(
|
|
|
479
494
|
state = _load_state()
|
|
480
495
|
latest_access: dict[str, Any] = {}
|
|
481
496
|
target_agent: str | None = None
|
|
482
|
-
|
|
497
|
+
|
|
483
498
|
normalized_transport = (transport or "auto").strip().lower() or "auto"
|
|
484
499
|
|
|
485
500
|
# 确定 Endpoint
|
|
@@ -518,7 +533,7 @@ def run_invoke_command(
|
|
|
518
533
|
endpoint = latest_access["endpoint"]
|
|
519
534
|
elif not agent_input or _state_matches_target(state, target_agent):
|
|
520
535
|
endpoint = state.get("endpoint")
|
|
521
|
-
|
|
536
|
+
|
|
522
537
|
if not endpoint:
|
|
523
538
|
# 自动获取
|
|
524
539
|
endpoint = _get_endpoint(target_agent, region)
|
|
@@ -548,7 +563,7 @@ def run_invoke_command(
|
|
|
548
563
|
latest_access=latest_access,
|
|
549
564
|
)
|
|
550
565
|
|
|
551
|
-
click.secho(
|
|
566
|
+
click.secho("🤖 连接到 Agent", fg="blue", bold=True)
|
|
552
567
|
click.echo(f" Endpoint: {endpoint}")
|
|
553
568
|
if _is_openclaw_target(next_state, latest_access):
|
|
554
569
|
if runtime_api_key:
|
|
@@ -561,7 +576,7 @@ def run_invoke_command(
|
|
|
561
576
|
click.echo(f" Auth: Bearer {_mask_secret(api_key)}")
|
|
562
577
|
else:
|
|
563
578
|
click.secho(" ⚠️ 未发现 API Key,尝试匿名调用", fg="yellow")
|
|
564
|
-
|
|
579
|
+
|
|
565
580
|
if insecure:
|
|
566
581
|
click.secho(" ⚠️ SSL 证书验证已禁用", fg="yellow")
|
|
567
582
|
|
|
@@ -592,7 +607,6 @@ def run_invoke_command(
|
|
|
592
607
|
)
|
|
593
608
|
else:
|
|
594
609
|
is_hermes_target = _is_hermes_target(next_state, latest_access)
|
|
595
|
-
is_openclaw_target = _is_openclaw_target(next_state, latest_access)
|
|
596
610
|
if normalized_transport == "chat" and is_hermes_target:
|
|
597
611
|
click.secho("❌ Hermes 不再支持 ksadk 通用 chat TUI。", fg="red")
|
|
598
612
|
click.echo(" 浏览器聊天页请改用: agentengine hermes open --chat")
|
|
@@ -691,7 +705,9 @@ def run_invoke_command(
|
|
|
691
705
|
show_thinking,
|
|
692
706
|
api_format=api_format_resolved,
|
|
693
707
|
responses_session_header=(
|
|
694
|
-
"x-openclaw-session-key"
|
|
708
|
+
"x-openclaw-session-key"
|
|
709
|
+
if _is_openclaw_target(next_state, latest_access)
|
|
710
|
+
else None
|
|
695
711
|
),
|
|
696
712
|
no_alt_screen=no_alt_screen,
|
|
697
713
|
region=region,
|
|
@@ -699,14 +715,12 @@ def run_invoke_command(
|
|
|
699
715
|
)
|
|
700
716
|
|
|
701
717
|
|
|
702
|
-
|
|
703
|
-
|
|
704
718
|
def _invoke_tui(
|
|
705
719
|
endpoint: str,
|
|
706
|
-
api_key: str = None,
|
|
707
|
-
session_id: str = None,
|
|
720
|
+
api_key: Optional[str] = None,
|
|
721
|
+
session_id: Optional[str] = None,
|
|
708
722
|
insecure: bool = False,
|
|
709
|
-
model: str = None,
|
|
723
|
+
model: Optional[str] = None,
|
|
710
724
|
show_thinking: bool = False,
|
|
711
725
|
api_format: str = "chat_completions",
|
|
712
726
|
responses_session_header: str | None = None,
|
|
@@ -740,7 +754,7 @@ def _invoke_tui(
|
|
|
740
754
|
if matched is None and runner.available_models:
|
|
741
755
|
matched = runner.available_models[0]
|
|
742
756
|
if matched:
|
|
743
|
-
runner
|
|
757
|
+
setattr(runner, "model_metadata", matched)
|
|
744
758
|
# 用户未指定 --model 时,用 ListAgentModels 的 current 作为 runner.model,
|
|
745
759
|
# 让 TUI 启动即显示真实模型名(而非 unknown)。
|
|
746
760
|
if not runner.model and matched.get("id"):
|
|
@@ -751,7 +765,7 @@ def _invoke_tui(
|
|
|
751
765
|
_fetch_tui_model_metadata(endpoint=endpoint, api_key=api_key, model=model)
|
|
752
766
|
)
|
|
753
767
|
if model_metadata:
|
|
754
|
-
runner
|
|
768
|
+
setattr(runner, "model_metadata", model_metadata)
|
|
755
769
|
|
|
756
770
|
run_tui(runner, show_thinking=show_thinking, project_dir=".", no_alt_screen=no_alt_screen)
|
|
757
771
|
|
|
@@ -772,7 +786,8 @@ async def _fetch_tui_model_list(
|
|
|
772
786
|
from ksadk.api.client import AgentEngineClient
|
|
773
787
|
|
|
774
788
|
async with AgentEngineClient(region=region) as client:
|
|
775
|
-
|
|
789
|
+
payload = await client.list_agent_models(agent_id=agent_id)
|
|
790
|
+
return payload if isinstance(payload, dict) else None
|
|
776
791
|
except Exception:
|
|
777
792
|
return None
|
|
778
793
|
|
|
@@ -803,7 +818,8 @@ async def _fetch_tui_model_metadata(
|
|
|
803
818
|
raw_models = [item.get("_provider_raw_model") or item for item in catalog]
|
|
804
819
|
matched = find_model_in_catalog(raw_models, model)
|
|
805
820
|
if matched is not None:
|
|
806
|
-
|
|
821
|
+
metadata = normalize_model_metadata(matched)
|
|
822
|
+
return metadata if isinstance(metadata, dict) else None
|
|
807
823
|
if model:
|
|
808
824
|
return None
|
|
809
825
|
if len(catalog) == 1:
|
|
@@ -816,10 +832,11 @@ async def _fetch_tui_model_metadata(
|
|
|
816
832
|
def _load_state() -> dict:
|
|
817
833
|
"""从 .agentengine.state 加载状态"""
|
|
818
834
|
import yaml
|
|
835
|
+
|
|
819
836
|
state_file = Path(".") / ".agentengine.state"
|
|
820
837
|
if state_file.exists():
|
|
821
838
|
try:
|
|
822
|
-
with open(state_file,
|
|
839
|
+
with open(state_file, "r", encoding="utf-8") as f:
|
|
823
840
|
return yaml.safe_load(f) or {}
|
|
824
841
|
except Exception:
|
|
825
842
|
pass
|
|
@@ -847,15 +864,13 @@ def _extract_remote_access(detail: Dict[str, Any]) -> Dict[str, Any]:
|
|
|
847
864
|
if not isinstance(detail, dict):
|
|
848
865
|
return {}
|
|
849
866
|
|
|
850
|
-
|
|
851
|
-
|
|
852
|
-
|
|
853
|
-
|
|
854
|
-
|
|
855
|
-
|
|
856
|
-
|
|
857
|
-
or detail.get("framework")
|
|
858
|
-
)
|
|
867
|
+
basic_value = detail.get("basic")
|
|
868
|
+
quick_value = detail.get("quick_access")
|
|
869
|
+
deployment_value = detail.get("deployment")
|
|
870
|
+
basic: Dict[str, Any] = basic_value if isinstance(basic_value, dict) else {}
|
|
871
|
+
quick: Dict[str, Any] = quick_value if isinstance(quick_value, dict) else {}
|
|
872
|
+
deployment: Dict[str, Any] = deployment_value if isinstance(deployment_value, dict) else {}
|
|
873
|
+
framework = deployment.get("framework") or basic.get("framework") or detail.get("framework")
|
|
859
874
|
|
|
860
875
|
return {
|
|
861
876
|
"agent_id": basic.get("agent_id") or detail.get("agent_id"),
|
|
@@ -873,9 +888,13 @@ async def _fetch_remote_access(target_agent: str, region: str) -> Dict[str, Any]
|
|
|
873
888
|
|
|
874
889
|
async with AgentEngineClient(region=region) as client:
|
|
875
890
|
try:
|
|
876
|
-
return _extract_remote_access(
|
|
891
|
+
return _extract_remote_access(
|
|
892
|
+
await client.get_agent(agent_id=target_agent, include_api_key=True)
|
|
893
|
+
)
|
|
877
894
|
except Exception:
|
|
878
|
-
return _extract_remote_access(
|
|
895
|
+
return _extract_remote_access(
|
|
896
|
+
await client.get_agent(name=target_agent, include_api_key=True)
|
|
897
|
+
)
|
|
879
898
|
|
|
880
899
|
|
|
881
900
|
def _refresh_remote_access(
|
|
@@ -904,22 +923,20 @@ def _refresh_remote_access(
|
|
|
904
923
|
|
|
905
924
|
|
|
906
925
|
def _is_hermes_target(state: dict, latest_access: dict) -> bool:
|
|
907
|
-
framework =
|
|
908
|
-
latest_access.get("framework")
|
|
909
|
-
|
|
910
|
-
|
|
911
|
-
|
|
912
|
-
).strip().lower()
|
|
926
|
+
framework = (
|
|
927
|
+
str(latest_access.get("framework") or state.get("framework") or state.get("type") or "")
|
|
928
|
+
.strip()
|
|
929
|
+
.lower()
|
|
930
|
+
)
|
|
913
931
|
return framework == "hermes"
|
|
914
932
|
|
|
915
933
|
|
|
916
934
|
def _is_openclaw_target(state: dict, latest_access: dict) -> bool:
|
|
917
|
-
framework =
|
|
918
|
-
latest_access.get("framework")
|
|
919
|
-
|
|
920
|
-
|
|
921
|
-
|
|
922
|
-
).strip().lower()
|
|
935
|
+
framework = (
|
|
936
|
+
str(latest_access.get("framework") or state.get("framework") or state.get("type") or "")
|
|
937
|
+
.strip()
|
|
938
|
+
.lower()
|
|
939
|
+
)
|
|
923
940
|
return framework == "openclaw"
|
|
924
941
|
|
|
925
942
|
|
|
@@ -933,13 +950,17 @@ def _mask_secret(secret: str | None) -> str:
|
|
|
933
950
|
|
|
934
951
|
|
|
935
952
|
def _openclaw_auth_mode(state: dict, latest_access: dict) -> str:
|
|
936
|
-
return
|
|
937
|
-
|
|
938
|
-
|
|
939
|
-
|
|
940
|
-
|
|
941
|
-
|
|
942
|
-
|
|
953
|
+
return (
|
|
954
|
+
str(
|
|
955
|
+
latest_access.get("openclaw_auth_mode")
|
|
956
|
+
or latest_access.get("gateway_auth_mode")
|
|
957
|
+
or state.get("openclaw_auth_mode")
|
|
958
|
+
or state.get("gateway_auth_mode")
|
|
959
|
+
or ""
|
|
960
|
+
)
|
|
961
|
+
.strip()
|
|
962
|
+
.lower()
|
|
963
|
+
)
|
|
943
964
|
|
|
944
965
|
|
|
945
966
|
def _select_runtime_api_key(
|
|
@@ -967,11 +988,14 @@ def _select_runtime_api_key(
|
|
|
967
988
|
auth_mode = _openclaw_auth_mode(state, latest_access)
|
|
968
989
|
if auth_mode in {"token", "password"}:
|
|
969
990
|
raise click.ClickException(
|
|
970
|
-
"当前 OpenClaw Gateway 为 token/password 模式,
|
|
991
|
+
"当前 OpenClaw Gateway 为 token/password 模式,"
|
|
992
|
+
"agentengine invoke 需要 OpenClaw Gateway token。\n"
|
|
971
993
|
"请使用: agentengine invoke --gateway-token <token>\n"
|
|
972
994
|
"或设置: OPENCLAW_GATEWAY_TOKEN=<token> agentengine invoke\n"
|
|
973
|
-
"如果部署时传过 OPENCLAW_GATEWAY_TOKEN,请重新运行部署让本地
|
|
974
|
-
"
|
|
995
|
+
"如果部署时传过 OPENCLAW_GATEWAY_TOKEN,请重新运行部署让本地 "
|
|
996
|
+
".agentengine.state 记录该 token。\n"
|
|
997
|
+
"注意:这里不是 AgentEngine API Key(ak-*),而是 "
|
|
998
|
+
"OPENCLAW_GATEWAY_TOKEN/OPENCLAW_GATEWAY_PASSWORD。"
|
|
975
999
|
)
|
|
976
1000
|
|
|
977
1001
|
return api_key
|
|
@@ -1084,7 +1108,9 @@ async def _probe_responses_route(
|
|
|
1084
1108
|
return available
|
|
1085
1109
|
|
|
1086
1110
|
|
|
1087
|
-
def _should_use_hermes_native_tui(
|
|
1111
|
+
def _should_use_hermes_native_tui(
|
|
1112
|
+
*, transport: str, local: bool, state: dict, latest_access: dict
|
|
1113
|
+
) -> bool:
|
|
1088
1114
|
if transport == "chat":
|
|
1089
1115
|
return False
|
|
1090
1116
|
if transport == "native":
|
|
@@ -1094,7 +1120,9 @@ def _should_use_hermes_native_tui(*, transport: str, local: bool, state: dict, l
|
|
|
1094
1120
|
return _is_hermes_target(state, latest_access)
|
|
1095
1121
|
|
|
1096
1122
|
|
|
1097
|
-
def _should_use_openclaw_native_tui(
|
|
1123
|
+
def _should_use_openclaw_native_tui(
|
|
1124
|
+
*, transport: str, local: bool, state: dict, latest_access: dict
|
|
1125
|
+
) -> bool:
|
|
1098
1126
|
if transport == "chat":
|
|
1099
1127
|
return False
|
|
1100
1128
|
if transport == "native":
|
|
@@ -1106,14 +1134,16 @@ def _should_use_openclaw_native_tui(*, transport: str, local: bool, state: dict,
|
|
|
1106
1134
|
|
|
1107
1135
|
def _invoke_hermes_terminal_tui(
|
|
1108
1136
|
endpoint: str,
|
|
1109
|
-
api_key: str = None,
|
|
1110
|
-
session_id: str = None,
|
|
1137
|
+
api_key: Optional[str] = None,
|
|
1138
|
+
session_id: Optional[str] = None,
|
|
1111
1139
|
insecure: bool = False,
|
|
1112
1140
|
cwd: str | None = None,
|
|
1113
1141
|
):
|
|
1114
1142
|
click.secho("🖥️ Hermes Native Remote TUI", fg="blue", bold=True)
|
|
1115
1143
|
click.echo(" 退出: Ctrl-D 或 Ctrl-C")
|
|
1116
|
-
click.echo(
|
|
1144
|
+
click.echo(
|
|
1145
|
+
" 新 Pod 首次启动会加载 Hermes tools/skills,可能需要几十秒到 1 分钟;后续进入会更快。"
|
|
1146
|
+
)
|
|
1117
1147
|
try:
|
|
1118
1148
|
_warmup_hermes_terminal(
|
|
1119
1149
|
endpoint=endpoint,
|
|
@@ -1172,8 +1202,8 @@ def _warmup_hermes_terminal(
|
|
|
1172
1202
|
|
|
1173
1203
|
def _invoke_openclaw_terminal_tui(
|
|
1174
1204
|
endpoint: str,
|
|
1175
|
-
api_key: str = None,
|
|
1176
|
-
session_id: str = None,
|
|
1205
|
+
api_key: Optional[str] = None,
|
|
1206
|
+
session_id: Optional[str] = None,
|
|
1177
1207
|
insecure: bool = False,
|
|
1178
1208
|
):
|
|
1179
1209
|
click.secho("🖥️ OpenClaw Native Remote TUI", fg="blue", bold=True)
|
|
@@ -1206,15 +1236,16 @@ def _get_api_key() -> Optional[str]:
|
|
|
1206
1236
|
|
|
1207
1237
|
def _get_endpoint(agent_ref: str, region: str) -> str:
|
|
1208
1238
|
"""获取 Agent Endpoint(先按 ID,再按名称)"""
|
|
1209
|
-
from ksadk.api import AgentEngineClient
|
|
1210
1239
|
import asyncio
|
|
1211
1240
|
|
|
1212
|
-
|
|
1241
|
+
from ksadk.api import AgentEngineClient
|
|
1242
|
+
|
|
1243
|
+
async def _get() -> str:
|
|
1213
1244
|
async with AgentEngineClient(region=region) as client:
|
|
1214
1245
|
# 1) 优先按 ID 查询
|
|
1215
1246
|
try:
|
|
1216
1247
|
res = await client.get_agent(agent_id=agent_ref)
|
|
1217
|
-
endpoint = _extract_remote_access(res).get("endpoint"
|
|
1248
|
+
endpoint = str(_extract_remote_access(res).get("endpoint") or "").strip()
|
|
1218
1249
|
if endpoint:
|
|
1219
1250
|
return endpoint
|
|
1220
1251
|
except Exception:
|
|
@@ -1222,13 +1253,14 @@ def _get_endpoint(agent_ref: str, region: str) -> str:
|
|
|
1222
1253
|
|
|
1223
1254
|
# 2) 回退按名称查询
|
|
1224
1255
|
res = await client.get_agent(name=agent_ref)
|
|
1225
|
-
endpoint = _extract_remote_access(res).get("endpoint"
|
|
1256
|
+
endpoint = str(_extract_remote_access(res).get("endpoint") or "").strip()
|
|
1226
1257
|
if endpoint:
|
|
1227
1258
|
return endpoint
|
|
1228
1259
|
|
|
1229
1260
|
# endpoint 为空时,尽量提取真实 ID 供默认域名拼接
|
|
1230
|
-
|
|
1231
|
-
|
|
1261
|
+
basic_value = res.get("basic")
|
|
1262
|
+
basic = basic_value if isinstance(basic_value, dict) else {}
|
|
1263
|
+
return str(basic.get("agent_id") or res.get("agent_id") or "")
|
|
1232
1264
|
|
|
1233
1265
|
try:
|
|
1234
1266
|
resolved = asyncio.run(_get())
|
|
@@ -1248,16 +1280,16 @@ def _get_endpoint(agent_ref: str, region: str) -> str:
|
|
|
1248
1280
|
async def _invoke_once(
|
|
1249
1281
|
endpoint: str,
|
|
1250
1282
|
message: str,
|
|
1251
|
-
api_key: str = None,
|
|
1252
|
-
session_id: str = None,
|
|
1283
|
+
api_key: Optional[str] = None,
|
|
1284
|
+
session_id: Optional[str] = None,
|
|
1253
1285
|
stream: bool = True,
|
|
1254
1286
|
insecure: bool = False,
|
|
1255
|
-
model: str = None,
|
|
1287
|
+
model: Optional[str] = None,
|
|
1256
1288
|
api_format: str = "chat_completions",
|
|
1257
1289
|
):
|
|
1258
1290
|
"""单次调用"""
|
|
1259
1291
|
click.echo(f"\n👤 你: {message}")
|
|
1260
|
-
click.echo(
|
|
1292
|
+
click.echo("🤖 Agent: ", nl=False)
|
|
1261
1293
|
|
|
1262
1294
|
try:
|
|
1263
1295
|
if stream:
|
|
@@ -1265,12 +1297,19 @@ async def _invoke_once(
|
|
|
1265
1297
|
if Live and Markdown:
|
|
1266
1298
|
# 降低刷新率减少闪烁,vertical_overflow="visible"防止回滚丢失
|
|
1267
1299
|
# 手动控制刷新以减少闪烁
|
|
1268
|
-
with Live(
|
|
1269
|
-
|
|
1300
|
+
with Live(
|
|
1301
|
+
Markdown("", justify="left"),
|
|
1302
|
+
console=console,
|
|
1303
|
+
auto_refresh=False,
|
|
1304
|
+
vertical_overflow="visible",
|
|
1305
|
+
) as live:
|
|
1306
|
+
last_refresh_time = 0.0
|
|
1270
1307
|
full_reasoning = ""
|
|
1271
|
-
async for chunk in _stream_chat(
|
|
1308
|
+
async for chunk in _stream_chat(
|
|
1309
|
+
endpoint, message, api_key, session_id, True, insecure, model, api_format
|
|
1310
|
+
):
|
|
1272
1311
|
content, reasoning = _extract_content(chunk)
|
|
1273
|
-
|
|
1312
|
+
|
|
1274
1313
|
updated = False
|
|
1275
1314
|
if reasoning:
|
|
1276
1315
|
full_reasoning += reasoning
|
|
@@ -1278,25 +1317,27 @@ async def _invoke_once(
|
|
|
1278
1317
|
if content:
|
|
1279
1318
|
full_response += content
|
|
1280
1319
|
updated = True
|
|
1281
|
-
|
|
1320
|
+
|
|
1282
1321
|
if updated:
|
|
1283
1322
|
# 构造显示文本
|
|
1284
1323
|
display_text = ""
|
|
1285
1324
|
if full_reasoning:
|
|
1286
|
-
formatted_reasoning = full_reasoning.replace(
|
|
1325
|
+
formatted_reasoning = full_reasoning.replace("\n", "\n> ")
|
|
1287
1326
|
display_text += f"> 🧠 **Thinking:**\n> {formatted_reasoning}\n\n"
|
|
1288
1327
|
display_text += full_response
|
|
1289
|
-
|
|
1328
|
+
|
|
1290
1329
|
live.update(Markdown(display_text, justify="left"))
|
|
1291
|
-
|
|
1330
|
+
|
|
1292
1331
|
# 基于时间限流刷新 (每0.2秒一次 = 5 FPS)
|
|
1293
1332
|
now = time.time()
|
|
1294
1333
|
if now - last_refresh_time > 0.2:
|
|
1295
1334
|
live.refresh()
|
|
1296
1335
|
last_refresh_time = now
|
|
1297
|
-
live.refresh()
|
|
1336
|
+
live.refresh() # 确保最后一次刷新
|
|
1298
1337
|
else:
|
|
1299
|
-
|
|
1338
|
+
async for chunk in _stream_chat(
|
|
1339
|
+
endpoint, message, api_key, session_id, True, insecure, model, api_format
|
|
1340
|
+
):
|
|
1300
1341
|
content, reasoning = _extract_content(chunk)
|
|
1301
1342
|
if reasoning:
|
|
1302
1343
|
click.secho(reasoning, fg="bright_black", nl=False)
|
|
@@ -1304,7 +1345,9 @@ async def _invoke_once(
|
|
|
1304
1345
|
print(content, end="", flush=True)
|
|
1305
1346
|
click.echo() # 换行
|
|
1306
1347
|
else:
|
|
1307
|
-
response = await _chat(
|
|
1348
|
+
response = await _chat(
|
|
1349
|
+
endpoint, message, api_key, session_id, insecure, model, api_format
|
|
1350
|
+
)
|
|
1308
1351
|
content = _extract_response_content(response)
|
|
1309
1352
|
if console and Markdown:
|
|
1310
1353
|
console.print(Markdown(content))
|
|
@@ -1314,16 +1357,15 @@ async def _invoke_once(
|
|
|
1314
1357
|
click.secho(f"\n❌ 调用失败: {e}", fg="red")
|
|
1315
1358
|
|
|
1316
1359
|
|
|
1317
|
-
|
|
1318
1360
|
async def _chat(
|
|
1319
1361
|
endpoint: str,
|
|
1320
1362
|
message: str,
|
|
1321
|
-
api_key: str = None,
|
|
1322
|
-
session_id: str = None,
|
|
1363
|
+
api_key: Optional[str] = None,
|
|
1364
|
+
session_id: Optional[str] = None,
|
|
1323
1365
|
insecure: bool = False,
|
|
1324
|
-
model: str = None,
|
|
1366
|
+
model: Optional[str] = None,
|
|
1325
1367
|
api_format: str = "chat_completions",
|
|
1326
|
-
) -> dict:
|
|
1368
|
+
) -> dict[str, Any]:
|
|
1327
1369
|
"""非流式调用 (OpenAI 兼容格式)"""
|
|
1328
1370
|
try:
|
|
1329
1371
|
import httpx
|
|
@@ -1334,10 +1376,16 @@ async def _chat(
|
|
|
1334
1376
|
normalized_api_format = str(api_format or "chat_completions").strip().lower()
|
|
1335
1377
|
if normalized_api_format == "responses":
|
|
1336
1378
|
url = f"{endpoint.rstrip('/')}/v1/responses"
|
|
1337
|
-
payload
|
|
1379
|
+
payload: dict[str, Any] = {
|
|
1380
|
+
"input": [{"role": "user", "content": message}],
|
|
1381
|
+
"stream": False,
|
|
1382
|
+
}
|
|
1338
1383
|
else:
|
|
1339
1384
|
url = f"{endpoint.rstrip('/')}/v1/chat/completions"
|
|
1340
|
-
payload = {
|
|
1385
|
+
payload = {
|
|
1386
|
+
"messages": [{"role": "user", "content": message}],
|
|
1387
|
+
"stream": False,
|
|
1388
|
+
}
|
|
1341
1389
|
|
|
1342
1390
|
if session_id:
|
|
1343
1391
|
payload["session_id"] = session_id
|
|
@@ -1351,31 +1399,37 @@ async def _chat(
|
|
|
1351
1399
|
is_local = "localhost" in url or "127.0.0.1" in url or "0.0.0.0" in url
|
|
1352
1400
|
|
|
1353
1401
|
# 构造 httpx client 配置
|
|
1354
|
-
client_kwargs
|
|
1402
|
+
client_kwargs: dict[str, Any] = {
|
|
1403
|
+
"timeout": 60,
|
|
1404
|
+
"trust_env": not is_local,
|
|
1405
|
+
}
|
|
1355
1406
|
|
|
1356
1407
|
# 如果指定了 --insecure 参数,跳过 SSL 证书验证(类似 curl -k)
|
|
1357
1408
|
if insecure:
|
|
1358
1409
|
client_kwargs["verify"] = False
|
|
1359
1410
|
|
|
1360
1411
|
# 构造 Headers
|
|
1361
|
-
headers = {}
|
|
1412
|
+
headers: dict[str, str] = {}
|
|
1362
1413
|
if api_key:
|
|
1363
1414
|
headers["Authorization"] = f"Bearer {api_key}"
|
|
1364
1415
|
|
|
1365
1416
|
async with httpx.AsyncClient(**client_kwargs) as client:
|
|
1366
1417
|
response = await client.post(url, json=payload, headers=headers)
|
|
1367
1418
|
response.raise_for_status()
|
|
1368
|
-
|
|
1419
|
+
response_payload = response.json()
|
|
1420
|
+
if not isinstance(response_payload, dict):
|
|
1421
|
+
raise ValueError("Agent response must be a JSON object")
|
|
1422
|
+
return response_payload
|
|
1369
1423
|
|
|
1370
1424
|
|
|
1371
1425
|
async def _stream_chat(
|
|
1372
1426
|
endpoint: str,
|
|
1373
1427
|
message: str,
|
|
1374
|
-
api_key: str = None,
|
|
1375
|
-
session_id: str = None,
|
|
1428
|
+
api_key: Optional[str] = None,
|
|
1429
|
+
session_id: Optional[str] = None,
|
|
1376
1430
|
is_once: bool = False,
|
|
1377
1431
|
insecure: bool = False,
|
|
1378
|
-
model: str = None,
|
|
1432
|
+
model: Optional[str] = None,
|
|
1379
1433
|
api_format: str = "chat_completions",
|
|
1380
1434
|
):
|
|
1381
1435
|
"""流式调用 (SSE)"""
|
|
@@ -1388,7 +1442,10 @@ async def _stream_chat(
|
|
|
1388
1442
|
normalized_api_format = str(api_format or "chat_completions").strip().lower()
|
|
1389
1443
|
if normalized_api_format == "responses":
|
|
1390
1444
|
url = f"{endpoint.rstrip('/')}/v1/responses"
|
|
1391
|
-
payload
|
|
1445
|
+
payload: dict[str, Any] = {
|
|
1446
|
+
"input": [{"role": "user", "content": message}],
|
|
1447
|
+
"stream": True,
|
|
1448
|
+
}
|
|
1392
1449
|
else:
|
|
1393
1450
|
url = f"{endpoint.rstrip('/')}/v1/chat/completions"
|
|
1394
1451
|
payload = {"messages": [{"role": "user", "content": message}], "stream": True}
|
|
@@ -1405,14 +1462,17 @@ async def _stream_chat(
|
|
|
1405
1462
|
is_local = "localhost" in url or "127.0.0.1" in url or "0.0.0.0" in url
|
|
1406
1463
|
|
|
1407
1464
|
# 构造 httpx client 配置
|
|
1408
|
-
client_kwargs
|
|
1465
|
+
client_kwargs: dict[str, Any] = {
|
|
1466
|
+
"timeout": 60,
|
|
1467
|
+
"trust_env": not is_local,
|
|
1468
|
+
}
|
|
1409
1469
|
|
|
1410
1470
|
# 如果指定了 --insecure 参数,跳过 SSL 证书验证(类似 curl -k)
|
|
1411
1471
|
if insecure:
|
|
1412
1472
|
client_kwargs["verify"] = False
|
|
1413
1473
|
|
|
1414
1474
|
# 构造 Headers
|
|
1415
|
-
headers = {}
|
|
1475
|
+
headers: dict[str, str] = {}
|
|
1416
1476
|
if api_key:
|
|
1417
1477
|
headers["Authorization"] = f"Bearer {api_key}"
|
|
1418
1478
|
|
|
@@ -1437,6 +1497,8 @@ async def _stream_chat(
|
|
|
1437
1497
|
|
|
1438
1498
|
try:
|
|
1439
1499
|
data = json.loads(data_str)
|
|
1500
|
+
if not isinstance(data, dict):
|
|
1501
|
+
continue
|
|
1440
1502
|
if current_event and isinstance(data, dict):
|
|
1441
1503
|
data = {**data, "_event": current_event}
|
|
1442
1504
|
# 直接 yield 解析后的 JSON 数据,让 _extract_content 处理
|
|
@@ -1497,7 +1559,7 @@ def _extract_response_content(response: dict) -> str:
|
|
|
1497
1559
|
choices = response.get("choices", [])
|
|
1498
1560
|
if choices:
|
|
1499
1561
|
message = choices[0].get("message", {})
|
|
1500
|
-
return message.get("content"
|
|
1562
|
+
return str(message.get("content") or "")
|
|
1501
1563
|
except (KeyError, IndexError):
|
|
1502
1564
|
pass
|
|
1503
1565
|
return str(response)
|