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/configs/settings.py
CHANGED
|
@@ -6,32 +6,34 @@ AgentEngine 统一配置管理
|
|
|
6
6
|
|
|
7
7
|
使用方式:
|
|
8
8
|
from ksadk.configs import settings
|
|
9
|
-
|
|
9
|
+
|
|
10
10
|
# 访问模型配置
|
|
11
11
|
print(settings.model.api_key)
|
|
12
12
|
print(settings.model.api_base)
|
|
13
|
-
|
|
13
|
+
|
|
14
14
|
# 访问 Langfuse 配置
|
|
15
15
|
print(settings.langfuse.public_key)
|
|
16
|
-
|
|
16
|
+
|
|
17
17
|
# 访问 Agent 运行时信息
|
|
18
18
|
print(settings.agent.agent_id)
|
|
19
19
|
"""
|
|
20
20
|
|
|
21
|
-
import
|
|
21
|
+
import importlib
|
|
22
22
|
import json
|
|
23
23
|
import logging
|
|
24
|
+
import os
|
|
24
25
|
import time
|
|
25
|
-
from typing import Optional, List, Dict, Any
|
|
26
26
|
from dataclasses import dataclass, field
|
|
27
|
+
from pathlib import Path
|
|
28
|
+
from typing import Any, Dict, List, Optional
|
|
27
29
|
from urllib.parse import urlsplit, urlunsplit
|
|
28
30
|
|
|
29
31
|
logger = logging.getLogger(__name__)
|
|
30
32
|
|
|
31
33
|
|
|
32
|
-
def _get_env(*keys: str, default: str = None) -> Optional[str]:
|
|
34
|
+
def _get_env(*keys: str, default: Optional[str] = None) -> Optional[str]:
|
|
33
35
|
"""从多个环境变量 key 中获取第一个存在的值
|
|
34
|
-
|
|
36
|
+
|
|
35
37
|
按优先级顺序匹配,支持别名兼容。
|
|
36
38
|
"""
|
|
37
39
|
for key in keys:
|
|
@@ -69,44 +71,45 @@ def _is_public_kspmas_url(url: Optional[str]) -> bool:
|
|
|
69
71
|
|
|
70
72
|
def check_endpoint_reachable(host: str, port: int = 80, timeout: float = 1.0) -> bool:
|
|
71
73
|
"""检测指定端点是否可达
|
|
72
|
-
|
|
74
|
+
|
|
73
75
|
通用函数,可用于检测任意服务的内网地址是否可达。
|
|
74
76
|
结果会被缓存,相同 host 只检测一次。
|
|
75
|
-
|
|
77
|
+
|
|
76
78
|
Args:
|
|
77
79
|
host: 主机名或 IP 地址
|
|
78
80
|
port: 端口号 (默认 80)
|
|
79
81
|
timeout: 超时时间 (默认 1.0 秒)
|
|
80
|
-
|
|
82
|
+
|
|
81
83
|
Returns:
|
|
82
84
|
True 如果可达, False 否则
|
|
83
|
-
|
|
85
|
+
|
|
84
86
|
Usage:
|
|
85
87
|
# KSPMAS 内网检测
|
|
86
88
|
if check_endpoint_reachable("kspmas-internal.sdns.ksyun.com"):
|
|
87
89
|
api_base = "http://kspmas-internal.sdns.ksyun.com/v1"
|
|
88
|
-
|
|
90
|
+
|
|
89
91
|
# KS3 内网检测
|
|
90
92
|
if check_endpoint_reachable("ks3-cn-beijing-internal.ksyuncs.com"):
|
|
91
93
|
ks3_endpoint = "http://ks3-cn-beijing-internal.ksyuncs.com"
|
|
92
94
|
"""
|
|
93
95
|
if host in _endpoint_cache:
|
|
94
96
|
return _endpoint_cache[host]
|
|
95
|
-
|
|
97
|
+
|
|
96
98
|
try:
|
|
97
99
|
import socket
|
|
100
|
+
|
|
98
101
|
# 尝试建立 TCP 连接 (比 ping 更可靠,且不依赖 ICMP)
|
|
99
102
|
s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
|
|
100
103
|
s.settimeout(timeout)
|
|
101
104
|
s.connect((host, port))
|
|
102
105
|
s.close()
|
|
103
|
-
|
|
106
|
+
|
|
104
107
|
_endpoint_cache[host] = True
|
|
105
108
|
logger.debug(f"Endpoint reachable: {host}:{port}")
|
|
106
109
|
except (socket.timeout, socket.error, OSError):
|
|
107
110
|
_endpoint_cache[host] = False
|
|
108
111
|
logger.debug(f"Endpoint not reachable: {host}:{port}")
|
|
109
|
-
|
|
112
|
+
|
|
110
113
|
return _endpoint_cache[host]
|
|
111
114
|
|
|
112
115
|
|
|
@@ -125,13 +128,13 @@ DEFAULT_MODEL_NAME = "glm-5.2"
|
|
|
125
128
|
|
|
126
129
|
def optimize_kspmas_url(url: str) -> str:
|
|
127
130
|
"""优化 KSPMAS URL
|
|
128
|
-
|
|
131
|
+
|
|
129
132
|
如果是 KSPMAS 的公网地址,且检测到内网可达(或在 Serverless 环境),
|
|
130
133
|
将其替换为内网地址以提高速度和稳定性。
|
|
131
134
|
"""
|
|
132
135
|
if not url:
|
|
133
136
|
return url
|
|
134
|
-
|
|
137
|
+
|
|
135
138
|
parsed = urlsplit(url)
|
|
136
139
|
if parsed.hostname != "kspmas.ksyun.com":
|
|
137
140
|
return url
|
|
@@ -147,13 +150,13 @@ def optimize_kspmas_url(url: str) -> str:
|
|
|
147
150
|
if parsed.port:
|
|
148
151
|
netloc = f"{netloc}:{parsed.port}"
|
|
149
152
|
return urlunsplit(("http", netloc, parsed.path, parsed.query, parsed.fragment))
|
|
150
|
-
|
|
153
|
+
|
|
151
154
|
return url
|
|
152
155
|
|
|
153
156
|
|
|
154
157
|
def get_kspmas_api_base() -> str:
|
|
155
158
|
"""获取 KSPMAS 模型服务的 API Base URL
|
|
156
|
-
|
|
159
|
+
|
|
157
160
|
自动检测内网可达性,优先使用内网地址。
|
|
158
161
|
**特殊逻辑**: 如果在 Serverless 托管环境 (AGENT_RUNTIME_ID 存在),强制使用内网地址。
|
|
159
162
|
"""
|
|
@@ -164,7 +167,7 @@ def get_kspmas_api_base() -> str:
|
|
|
164
167
|
# 2. 自动检测内网可达性
|
|
165
168
|
if check_endpoint_reachable(KSPMAS_INTERNAL_HOST):
|
|
166
169
|
return KSPMAS_INTERNAL_URL
|
|
167
|
-
|
|
170
|
+
|
|
168
171
|
# 3. 默认使用公网
|
|
169
172
|
return KSPMAS_PUBLIC_URL
|
|
170
173
|
|
|
@@ -173,82 +176,83 @@ def get_kspmas_api_base() -> str:
|
|
|
173
176
|
# 模型配置 (LLM)
|
|
174
177
|
# =============================================================================
|
|
175
178
|
|
|
179
|
+
|
|
176
180
|
@dataclass
|
|
177
181
|
class ModelConfig:
|
|
178
182
|
"""模型配置
|
|
179
|
-
|
|
183
|
+
|
|
180
184
|
标准环境变量 (优先):
|
|
181
185
|
OPENAI_API_KEY - API Key (OpenAI 标准)
|
|
182
186
|
OPENAI_BASE_URL - API Base URL (OpenAI 标准)
|
|
183
187
|
OPENAI_MODEL_NAME - 模型名称
|
|
184
|
-
|
|
188
|
+
|
|
185
189
|
通用格式:
|
|
186
190
|
MODEL_NAME - 模型名称
|
|
187
|
-
|
|
191
|
+
|
|
188
192
|
Serverless 平台兼容:
|
|
189
193
|
LLM_API_KEY - 模型 API Key
|
|
190
194
|
LLM_API_BASE - 模型 API 地址
|
|
191
195
|
LLM_MODEL - 模型名称
|
|
192
|
-
|
|
196
|
+
|
|
193
197
|
别名 (兼容):
|
|
194
198
|
OPENAI_API_BASE - API Base URL 别名
|
|
195
|
-
|
|
199
|
+
|
|
196
200
|
默认值:
|
|
197
201
|
OPENAI_BASE_URL: 自动检测内网/外网,使用金山云模型服务
|
|
198
202
|
MODEL_NAME: glm-5.2
|
|
199
203
|
"""
|
|
200
|
-
|
|
204
|
+
|
|
201
205
|
@property
|
|
202
206
|
def api_key(self) -> Optional[str]:
|
|
203
207
|
"""获取模型 API Key"""
|
|
204
208
|
return _get_env(
|
|
205
|
-
"OPENAI_API_KEY",
|
|
206
|
-
"LLM_API_KEY",
|
|
207
|
-
"MODEL_API_KEY",
|
|
209
|
+
"OPENAI_API_KEY", # OpenAI 标准 (优先)
|
|
210
|
+
"LLM_API_KEY", # Serverless 平台兼容
|
|
211
|
+
"MODEL_API_KEY", # 通用
|
|
208
212
|
)
|
|
209
|
-
|
|
213
|
+
|
|
210
214
|
@property
|
|
211
215
|
def api_base(self) -> str:
|
|
212
216
|
"""获取模型 API Base URL
|
|
213
|
-
|
|
217
|
+
|
|
214
218
|
如果未配置,默认使用金山云模型服务地址(自动检测内网)。
|
|
215
219
|
如果已配置且为 KSPMAS 公网地址,也会尝试优化为内网地址。
|
|
216
220
|
"""
|
|
217
221
|
configured = _get_env(
|
|
218
|
-
"OPENAI_BASE_URL",
|
|
219
|
-
"OPENAI_API_BASE",
|
|
220
|
-
"LLM_API_BASE",
|
|
221
|
-
"MODEL_API_BASE",
|
|
222
|
+
"OPENAI_BASE_URL", # OpenAI 标准 (优先)
|
|
223
|
+
"OPENAI_API_BASE", # OpenAI 别名 (兼容)
|
|
224
|
+
"LLM_API_BASE", # Serverless 平台兼容
|
|
225
|
+
"MODEL_API_BASE", # 通用
|
|
222
226
|
)
|
|
223
|
-
|
|
227
|
+
|
|
224
228
|
if configured:
|
|
225
229
|
return optimize_kspmas_url(configured)
|
|
226
|
-
|
|
230
|
+
|
|
227
231
|
return get_kspmas_api_base()
|
|
228
|
-
|
|
232
|
+
|
|
229
233
|
@property
|
|
230
234
|
def model_name(self) -> str:
|
|
231
235
|
"""获取模型名称
|
|
232
|
-
|
|
236
|
+
|
|
233
237
|
如果未配置,默认使用 glm-5.2。
|
|
234
238
|
"""
|
|
235
239
|
configured = _get_env(
|
|
236
|
-
"OPENAI_MODEL_NAME",
|
|
237
|
-
"MODEL_NAME",
|
|
238
|
-
"LLM_MODEL",
|
|
240
|
+
"OPENAI_MODEL_NAME", # OpenAI 格式 (优先)
|
|
241
|
+
"MODEL_NAME", # 通用
|
|
242
|
+
"LLM_MODEL", # Serverless 平台兼容
|
|
239
243
|
)
|
|
240
244
|
return configured or DEFAULT_MODEL_NAME
|
|
241
|
-
|
|
245
|
+
|
|
242
246
|
@property
|
|
243
247
|
def is_configured(self) -> bool:
|
|
244
248
|
"""是否已配置 API Key"""
|
|
245
249
|
return bool(self.api_key)
|
|
246
|
-
|
|
250
|
+
|
|
247
251
|
@property
|
|
248
252
|
def is_using_internal_network(self) -> bool:
|
|
249
253
|
"""是否使用内网地址"""
|
|
250
254
|
return KSPMAS_INTERNAL_URL in self.api_base
|
|
251
|
-
|
|
255
|
+
|
|
252
256
|
def to_dict(self) -> dict:
|
|
253
257
|
"""转换为字典 (用于 LiteLLM 等)"""
|
|
254
258
|
result = {}
|
|
@@ -263,56 +267,60 @@ class ModelConfig:
|
|
|
263
267
|
# Langfuse 配置
|
|
264
268
|
# =============================================================================
|
|
265
269
|
|
|
270
|
+
|
|
266
271
|
@dataclass
|
|
267
272
|
class LangfuseConfig:
|
|
268
273
|
"""Langfuse 可观测性配置
|
|
269
|
-
|
|
274
|
+
|
|
270
275
|
标准环境变量 (Langfuse 官方):
|
|
271
276
|
LANGFUSE_PUBLIC_KEY - API Public Key
|
|
272
277
|
LANGFUSE_SECRET_KEY - API Secret Key
|
|
273
278
|
LANGFUSE_HOST - Langfuse 服务地址
|
|
274
|
-
|
|
279
|
+
|
|
275
280
|
Serverless 平台扩展:
|
|
276
281
|
LANGFUSE_PROJECT_ID - 项目 ID (区分用户)
|
|
277
282
|
LANGCHAIN_TRACING_V2 - 启用 LangChain 追踪
|
|
278
283
|
"""
|
|
279
|
-
|
|
284
|
+
|
|
280
285
|
@property
|
|
281
286
|
def public_key(self) -> Optional[str]:
|
|
282
287
|
return os.getenv("LANGFUSE_PUBLIC_KEY")
|
|
283
|
-
|
|
288
|
+
|
|
284
289
|
@property
|
|
285
290
|
def secret_key(self) -> Optional[str]:
|
|
286
291
|
return os.getenv("LANGFUSE_SECRET_KEY")
|
|
287
|
-
|
|
292
|
+
|
|
288
293
|
@property
|
|
289
294
|
def host(self) -> str:
|
|
290
|
-
return
|
|
291
|
-
|
|
292
|
-
|
|
293
|
-
|
|
295
|
+
return (
|
|
296
|
+
_get_env(
|
|
297
|
+
"LANGFUSE_HOST",
|
|
298
|
+
"LANGFUSE_BASE_URL",
|
|
299
|
+
default="http://localhost:3000",
|
|
300
|
+
)
|
|
301
|
+
or "http://localhost:3000"
|
|
294
302
|
)
|
|
295
|
-
|
|
303
|
+
|
|
296
304
|
@property
|
|
297
305
|
def project_id(self) -> Optional[str]:
|
|
298
306
|
"""Langfuse 项目 ID (Serverless 平台扩展)"""
|
|
299
307
|
return os.getenv("LANGFUSE_PROJECT_ID")
|
|
300
|
-
|
|
308
|
+
|
|
301
309
|
@property
|
|
302
310
|
def tracing_enabled(self) -> bool:
|
|
303
311
|
"""是否启用 LangChain tracing"""
|
|
304
312
|
return os.getenv("LANGCHAIN_TRACING_V2", "").lower() == "true"
|
|
305
|
-
|
|
313
|
+
|
|
306
314
|
@property
|
|
307
315
|
def is_enabled(self) -> bool:
|
|
308
316
|
"""是否启用 Langfuse (有 public_key 就启用)"""
|
|
309
317
|
return bool(self.public_key)
|
|
310
|
-
|
|
318
|
+
|
|
311
319
|
@property
|
|
312
320
|
def is_configured(self) -> bool:
|
|
313
321
|
"""是否完整配置"""
|
|
314
322
|
return bool(self.public_key and self.secret_key)
|
|
315
|
-
|
|
323
|
+
|
|
316
324
|
def to_dict(self) -> dict:
|
|
317
325
|
"""转换为字典"""
|
|
318
326
|
return {
|
|
@@ -326,14 +334,15 @@ class LangfuseConfig:
|
|
|
326
334
|
# Agent 配置
|
|
327
335
|
# =============================================================================
|
|
328
336
|
|
|
337
|
+
|
|
329
338
|
@dataclass
|
|
330
339
|
class AgentConfig:
|
|
331
340
|
"""Agent 配置
|
|
332
|
-
|
|
341
|
+
|
|
333
342
|
标准环境变量 (OpenTelemetry 兼容):
|
|
334
343
|
OTEL_SERVICE_NAME - 服务名称 (映射到 agent_name)
|
|
335
344
|
OTEL_RESOURCE_ATTRIBUTES - 资源属性 (key=value 格式)
|
|
336
|
-
|
|
345
|
+
|
|
337
346
|
通用环境变量:
|
|
338
347
|
AGENT_ID - Agent 唯一 ID
|
|
339
348
|
AGENT_NAME - Agent 名称
|
|
@@ -341,70 +350,70 @@ class AgentConfig:
|
|
|
341
350
|
USER_ID - 用户 ID
|
|
342
351
|
ENVIRONMENT - 运行环境 (dev/staging/prod)
|
|
343
352
|
VERSION - 版本号
|
|
344
|
-
|
|
353
|
+
|
|
345
354
|
Serverless 平台兼容:
|
|
346
355
|
AGENT_RUNTIME_ID - Agent 唯一 ID
|
|
347
356
|
AGENT_RUNTIME_NAME - Agent 名称
|
|
348
357
|
ACCOUNT_ID - 账户 ID (租户)
|
|
349
358
|
"""
|
|
350
|
-
|
|
359
|
+
|
|
351
360
|
@property
|
|
352
361
|
def agent_id(self) -> Optional[str]:
|
|
353
362
|
"""Agent 唯一 ID"""
|
|
354
363
|
return _get_env(
|
|
355
|
-
"AGENT_ID",
|
|
356
|
-
"AGENT_RUNTIME_ID",
|
|
364
|
+
"AGENT_ID", # 通用 (优先)
|
|
365
|
+
"AGENT_RUNTIME_ID", # Serverless 平台兼容
|
|
357
366
|
)
|
|
358
|
-
|
|
367
|
+
|
|
359
368
|
@property
|
|
360
369
|
def agent_name(self) -> Optional[str]:
|
|
361
370
|
"""Agent 名称"""
|
|
362
371
|
return _get_env(
|
|
363
|
-
"AGENT_NAME",
|
|
364
|
-
"AGENT_RUNTIME_NAME",
|
|
365
|
-
"OTEL_SERVICE_NAME",
|
|
372
|
+
"AGENT_NAME", # 通用 (优先)
|
|
373
|
+
"AGENT_RUNTIME_NAME", # Serverless 平台兼容
|
|
374
|
+
"OTEL_SERVICE_NAME", # OpenTelemetry 标准
|
|
366
375
|
)
|
|
367
|
-
|
|
376
|
+
|
|
368
377
|
@property
|
|
369
378
|
def tenant_id(self) -> Optional[str]:
|
|
370
379
|
"""租户 ID"""
|
|
371
380
|
return _get_env(
|
|
372
|
-
"TENANT_ID",
|
|
373
|
-
"ACCOUNT_ID",
|
|
381
|
+
"TENANT_ID", # 通用 (优先)
|
|
382
|
+
"ACCOUNT_ID", # Serverless 平台兼容
|
|
374
383
|
)
|
|
375
|
-
|
|
384
|
+
|
|
376
385
|
@property
|
|
377
386
|
def user_id(self) -> Optional[str]:
|
|
378
387
|
"""用户 ID"""
|
|
379
388
|
return os.getenv("USER_ID")
|
|
380
|
-
|
|
389
|
+
|
|
381
390
|
@property
|
|
382
391
|
def session_id(self) -> Optional[str]:
|
|
383
392
|
"""会话 ID (用于 Langfuse Sessions 功能)"""
|
|
384
393
|
return os.getenv("SESSION_ID")
|
|
385
|
-
|
|
394
|
+
|
|
386
395
|
@property
|
|
387
396
|
def environment(self) -> Optional[str]:
|
|
388
397
|
"""运行环境 (dev/staging/prod)"""
|
|
389
398
|
return os.getenv("ENVIRONMENT")
|
|
390
|
-
|
|
399
|
+
|
|
391
400
|
@property
|
|
392
401
|
def version(self) -> Optional[str]:
|
|
393
402
|
"""Agent 版本"""
|
|
394
403
|
return os.getenv("VERSION")
|
|
395
|
-
|
|
404
|
+
|
|
396
405
|
@property
|
|
397
406
|
def tags(self) -> Optional[List[str]]:
|
|
398
407
|
"""标签列表 (逗号分隔)"""
|
|
399
408
|
tags_str = os.getenv("TAGS", "")
|
|
400
409
|
tags = [t.strip() for t in tags_str.split(",") if t.strip()]
|
|
401
410
|
return tags if tags else None
|
|
402
|
-
|
|
411
|
+
|
|
403
412
|
@property
|
|
404
413
|
def extra_metadata(self) -> Optional[Dict[str, Any]]:
|
|
405
414
|
"""额外的元数据"""
|
|
406
415
|
extra = {}
|
|
407
|
-
|
|
416
|
+
|
|
408
417
|
# 1. 解析 JSON 格式的 metadata
|
|
409
418
|
extra_json = os.getenv("METADATA")
|
|
410
419
|
if extra_json:
|
|
@@ -412,7 +421,7 @@ class AgentConfig:
|
|
|
412
421
|
extra.update(json.loads(extra_json))
|
|
413
422
|
except json.JSONDecodeError:
|
|
414
423
|
logger.warning(f"Invalid METADATA JSON: {extra_json}")
|
|
415
|
-
|
|
424
|
+
|
|
416
425
|
# 2. 解析 OTEL_RESOURCE_ATTRIBUTES
|
|
417
426
|
otel_attrs = os.getenv("OTEL_RESOURCE_ATTRIBUTES", "")
|
|
418
427
|
if otel_attrs:
|
|
@@ -421,21 +430,21 @@ class AgentConfig:
|
|
|
421
430
|
key, value = pair.split("=", 1)
|
|
422
431
|
if key not in ("service.name", "service.version"):
|
|
423
432
|
extra[key] = value
|
|
424
|
-
|
|
433
|
+
|
|
425
434
|
return extra if extra else None
|
|
426
|
-
|
|
435
|
+
|
|
427
436
|
@property
|
|
428
437
|
def is_configured(self) -> bool:
|
|
429
438
|
"""是否有 Agent 信息"""
|
|
430
439
|
return bool(self.agent_id or self.agent_name)
|
|
431
|
-
|
|
440
|
+
|
|
432
441
|
# ------------------
|
|
433
442
|
# Langfuse 集成方法
|
|
434
443
|
# ------------------
|
|
435
|
-
|
|
444
|
+
|
|
436
445
|
def to_langfuse_params(self) -> dict:
|
|
437
446
|
"""转换为 Langfuse trace() 方法的原生参数"""
|
|
438
|
-
params = {}
|
|
447
|
+
params: Dict[str, Any] = {}
|
|
439
448
|
if self.session_id:
|
|
440
449
|
params["session_id"] = self.session_id
|
|
441
450
|
if self.user_id:
|
|
@@ -445,7 +454,7 @@ class AgentConfig:
|
|
|
445
454
|
if self.version:
|
|
446
455
|
params["version"] = self.version
|
|
447
456
|
return params
|
|
448
|
-
|
|
457
|
+
|
|
449
458
|
def to_langfuse_metadata(self) -> dict:
|
|
450
459
|
"""转换为 Langfuse metadata 字段"""
|
|
451
460
|
metadata = {}
|
|
@@ -466,28 +475,29 @@ class AgentConfig:
|
|
|
466
475
|
# 金山云配置
|
|
467
476
|
# =============================================================================
|
|
468
477
|
|
|
478
|
+
|
|
469
479
|
@dataclass
|
|
470
480
|
class KingsoftCloudConfig:
|
|
471
481
|
"""金山云 SDK 配置
|
|
472
|
-
|
|
482
|
+
|
|
473
483
|
环境变量:
|
|
474
484
|
KS_ACCESS_KEY_ID - Access Key ID
|
|
475
485
|
KS_SECRET_ACCESS_KEY - Secret Access Key
|
|
476
486
|
KS_REGION - 区域 (默认 cn-beijing-6)
|
|
477
487
|
"""
|
|
478
|
-
|
|
488
|
+
|
|
479
489
|
@property
|
|
480
490
|
def access_key_id(self) -> Optional[str]:
|
|
481
491
|
return os.getenv("KS_ACCESS_KEY_ID")
|
|
482
|
-
|
|
492
|
+
|
|
483
493
|
@property
|
|
484
494
|
def secret_access_key(self) -> Optional[str]:
|
|
485
495
|
return os.getenv("KS_SECRET_ACCESS_KEY")
|
|
486
|
-
|
|
496
|
+
|
|
487
497
|
@property
|
|
488
498
|
def region(self) -> str:
|
|
489
499
|
return os.getenv("KS_REGION", "cn-beijing-6")
|
|
490
|
-
|
|
500
|
+
|
|
491
501
|
@property
|
|
492
502
|
def is_configured(self) -> bool:
|
|
493
503
|
"""是否已配置"""
|
|
@@ -498,23 +508,24 @@ class KingsoftCloudConfig:
|
|
|
498
508
|
# Code 模式配置
|
|
499
509
|
# =============================================================================
|
|
500
510
|
|
|
511
|
+
|
|
501
512
|
@dataclass
|
|
502
513
|
class CodeModeConfig:
|
|
503
514
|
"""Code 模式配置 (Serverless 平台)
|
|
504
|
-
|
|
515
|
+
|
|
505
516
|
环境变量:
|
|
506
517
|
PYTHONPATH - Python 模块路径
|
|
507
518
|
CODE_PATH - 代码目录
|
|
508
519
|
"""
|
|
509
|
-
|
|
520
|
+
|
|
510
521
|
@property
|
|
511
522
|
def python_path(self) -> Optional[str]:
|
|
512
523
|
return os.getenv("PYTHONPATH")
|
|
513
|
-
|
|
524
|
+
|
|
514
525
|
@property
|
|
515
526
|
def code_path(self) -> Optional[str]:
|
|
516
527
|
return os.getenv("CODE_PATH")
|
|
517
|
-
|
|
528
|
+
|
|
518
529
|
@property
|
|
519
530
|
def is_code_mode(self) -> bool:
|
|
520
531
|
"""是否为 Code 模式"""
|
|
@@ -525,41 +536,42 @@ class CodeModeConfig:
|
|
|
525
536
|
# OpenTelemetry 配置
|
|
526
537
|
# =============================================================================
|
|
527
538
|
|
|
539
|
+
|
|
528
540
|
@dataclass
|
|
529
541
|
class OTelConfig:
|
|
530
542
|
"""OpenTelemetry 配置 (标准环境变量)
|
|
531
|
-
|
|
543
|
+
|
|
532
544
|
环境变量:
|
|
533
545
|
OTEL_SERVICE_NAME - 服务名称
|
|
534
546
|
OTEL_RESOURCE_ATTRIBUTES - 资源属性 (key=value,key2=value2)
|
|
535
547
|
OTEL_EXPORTER_OTLP_ENDPOINT - OTLP 导出端点
|
|
536
548
|
"""
|
|
537
|
-
|
|
549
|
+
|
|
538
550
|
@property
|
|
539
551
|
def service_name(self) -> Optional[str]:
|
|
540
552
|
return os.getenv("OTEL_SERVICE_NAME")
|
|
541
|
-
|
|
553
|
+
|
|
542
554
|
@property
|
|
543
555
|
def resource_attributes(self) -> Optional[Dict[str, str]]:
|
|
544
556
|
"""解析 OTEL_RESOURCE_ATTRIBUTES"""
|
|
545
557
|
attrs_str = os.getenv("OTEL_RESOURCE_ATTRIBUTES", "")
|
|
546
558
|
if not attrs_str:
|
|
547
559
|
return None
|
|
548
|
-
|
|
560
|
+
|
|
549
561
|
attrs = {}
|
|
550
562
|
for pair in attrs_str.split(","):
|
|
551
563
|
if "=" in pair:
|
|
552
564
|
key, value = pair.split("=", 1)
|
|
553
565
|
attrs[key] = value
|
|
554
566
|
return attrs if attrs else None
|
|
555
|
-
|
|
567
|
+
|
|
556
568
|
@property
|
|
557
569
|
def otlp_endpoint(self) -> Optional[str]:
|
|
558
570
|
return _get_env(
|
|
559
571
|
"OTEL_EXPORTER_OTLP_ENDPOINT",
|
|
560
572
|
"OTEL_EXPORTER_OTLP_TRACES_ENDPOINT",
|
|
561
573
|
)
|
|
562
|
-
|
|
574
|
+
|
|
563
575
|
@property
|
|
564
576
|
def is_enabled(self) -> bool:
|
|
565
577
|
"""是否启用 OTLP 导出"""
|
|
@@ -570,45 +582,52 @@ class OTelConfig:
|
|
|
570
582
|
# 统一配置入口
|
|
571
583
|
# =============================================================================
|
|
572
584
|
|
|
585
|
+
|
|
573
586
|
@dataclass
|
|
574
587
|
class Settings:
|
|
575
588
|
"""统一配置入口
|
|
576
|
-
|
|
589
|
+
|
|
577
590
|
使用方式:
|
|
578
591
|
from ksadk.configs import settings
|
|
579
|
-
|
|
592
|
+
|
|
580
593
|
# 模型配置
|
|
581
594
|
if settings.model.is_configured:
|
|
582
595
|
llm = LiteLLM(api_key=settings.model.api_key)
|
|
583
|
-
|
|
596
|
+
|
|
584
597
|
# Langfuse 配置
|
|
585
598
|
if settings.langfuse.is_enabled:
|
|
586
599
|
setup_tracing(langfuse_config=settings.langfuse.to_dict())
|
|
587
|
-
|
|
600
|
+
|
|
588
601
|
# Agent 信息
|
|
589
602
|
print(settings.agent.agent_id)
|
|
590
603
|
"""
|
|
604
|
+
|
|
591
605
|
model: ModelConfig = field(default_factory=ModelConfig)
|
|
592
606
|
langfuse: LangfuseConfig = field(default_factory=LangfuseConfig)
|
|
593
607
|
agent: AgentConfig = field(default_factory=AgentConfig)
|
|
594
608
|
cloud: KingsoftCloudConfig = field(default_factory=KingsoftCloudConfig)
|
|
595
609
|
code: CodeModeConfig = field(default_factory=CodeModeConfig)
|
|
596
610
|
otel: OTelConfig = field(default_factory=OTelConfig)
|
|
597
|
-
|
|
611
|
+
|
|
598
612
|
def summary(self) -> str:
|
|
599
613
|
"""输出配置摘要"""
|
|
600
614
|
lines = ["AgentEngine Configuration:"]
|
|
601
|
-
lines.append(
|
|
615
|
+
lines.append(
|
|
616
|
+
f" Model: {'✅ Configured' if self.model.is_configured else '❌ Not configured'}"
|
|
617
|
+
)
|
|
602
618
|
lines.append(f" Langfuse: {'✅ Enabled' if self.langfuse.is_enabled else '⚪ Disabled'}")
|
|
603
|
-
|
|
619
|
+
|
|
604
620
|
agent_info = self.agent.agent_id or self.agent.agent_name
|
|
605
621
|
lines.append(f" Agent: {'✅ ' + agent_info if agent_info else '⚪ No info'}")
|
|
606
|
-
|
|
607
|
-
lines.append(
|
|
608
|
-
|
|
622
|
+
|
|
623
|
+
lines.append(
|
|
624
|
+
f" Cloud: {'✅ Configured' if self.cloud.is_configured else '⚪ Not configured'}"
|
|
625
|
+
)
|
|
626
|
+
code_path = self.code.code_path
|
|
627
|
+
lines.append(f" CodeMode: {'✅ ' + code_path if code_path else '⚪ Container mode'}")
|
|
609
628
|
lines.append(f" OTEL: {'✅ Enabled' if self.otel.is_enabled else '⚪ Disabled'}")
|
|
610
629
|
return "\n".join(lines)
|
|
611
|
-
|
|
630
|
+
|
|
612
631
|
def __repr__(self) -> str:
|
|
613
632
|
return self.summary()
|
|
614
633
|
|
|
@@ -624,32 +643,30 @@ settings = Settings()
|
|
|
624
643
|
DEFAULT_RUNTIME_TIMEZONE = "Asia/Shanghai"
|
|
625
644
|
|
|
626
645
|
|
|
627
|
-
def setup_environment(agent_path:
|
|
646
|
+
def setup_environment(agent_path: Path | str):
|
|
628
647
|
"""加载环境变量并注入智能默认配置
|
|
629
|
-
|
|
648
|
+
|
|
630
649
|
1. 加载项目根目录的 .env 文件 (override=True)
|
|
631
650
|
2. 注入 OPENAI_API_BASE (智能检测)
|
|
632
651
|
3. 注入 OPENAI_MODEL_NAME (默认值)
|
|
633
652
|
"""
|
|
634
653
|
import click
|
|
635
|
-
|
|
636
|
-
from pathlib import Path
|
|
654
|
+
|
|
637
655
|
try:
|
|
638
|
-
|
|
656
|
+
dotenv_module = importlib.import_module("dotenv")
|
|
639
657
|
except ImportError:
|
|
640
|
-
|
|
641
|
-
|
|
642
|
-
|
|
658
|
+
dotenv_module = None
|
|
659
|
+
|
|
643
660
|
# 1. 加载 .env
|
|
644
|
-
if
|
|
661
|
+
if dotenv_module is not None:
|
|
645
662
|
# Ensure agent_path is a Path object
|
|
646
663
|
if isinstance(agent_path, str):
|
|
647
664
|
agent_path = Path(agent_path)
|
|
648
|
-
|
|
665
|
+
|
|
649
666
|
env_file = agent_path / ".env"
|
|
650
667
|
if env_file.exists():
|
|
651
668
|
# override=False: 保留通过 API/Serverless 平台注入的环境变量 (优先级高)
|
|
652
|
-
load_dotenv(env_file, override=False)
|
|
669
|
+
dotenv_module.load_dotenv(env_file, override=False)
|
|
653
670
|
|
|
654
671
|
# 本地调试与托管运行时统一默认北京时间;用户通过 shell/.env/平台显式指定 TZ 时不覆盖。
|
|
655
672
|
os.environ.setdefault("TZ", DEFAULT_RUNTIME_TIMEZONE)
|
|
@@ -696,7 +713,7 @@ def setup_environment(agent_path: "Path"):
|
|
|
696
713
|
if not os.getenv("OPENAI_API_BASE"):
|
|
697
714
|
os.environ["OPENAI_API_BASE"] = api_base
|
|
698
715
|
click.echo(f"🔧 API Base: {click.style(api_base, fg='cyan')} (Auto-detected)")
|
|
699
|
-
|
|
716
|
+
|
|
700
717
|
# Model Name
|
|
701
718
|
if not os.getenv("OPENAI_MODEL_NAME"):
|
|
702
719
|
model_name = settings.model.model_name
|
|
@@ -704,3 +721,13 @@ def setup_environment(agent_path: "Path"):
|
|
|
704
721
|
click.echo(f"🧠 Model: {click.style(model_name, fg='cyan')} (Default)")
|
|
705
722
|
if not os.getenv("MODEL_NAME") and os.getenv("OPENAI_MODEL_NAME"):
|
|
706
723
|
os.environ["MODEL_NAME"] = os.getenv("OPENAI_MODEL_NAME", "")
|
|
724
|
+
|
|
725
|
+
# 4. 模型出口协议转换层(v2.2):gate 开启且模型在白名单时懒起进程内 ProxyServer,
|
|
726
|
+
# 把 OPENAI_BASE_URL 重定向到它。默认 gate 关,不重定向,历史路径零影响。
|
|
727
|
+
# codex 不走此路(它走 AsyncCodexClient 的 v2.1 provider 注入)。
|
|
728
|
+
try:
|
|
729
|
+
from ksadk.model_proxy.bootstrap import setup_proxy_redirect_if_enabled
|
|
730
|
+
|
|
731
|
+
setup_proxy_redirect_if_enabled()
|
|
732
|
+
except Exception: # noqa: BLE001 代理可选,失败不影响主流程(默认关时本就不触发)
|
|
733
|
+
pass
|