agentengine-sdk-python 0.8.1__py3-none-any.whl → 0.8.2__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.8.1.dist-info → agentengine_sdk_python-0.8.2.dist-info}/METADATA +22 -2
- {agentengine_sdk_python-0.8.1.dist-info → agentengine_sdk_python-0.8.2.dist-info}/RECORD +356 -222
- ksadk/a2a/_space_client_events.py +381 -0
- ksadk/a2a/event_adapter.py +156 -64
- ksadk/a2a/executor.py +179 -63
- ksadk/a2a/space_client.py +6 -333
- ksadk/a2ui/core.py +222 -53
- ksadk/agui/_agent_helpers.py +243 -0
- ksadk/agui/a2ui_projection.py +12 -5
- ksadk/agui/agent.py +443 -259
- ksadk/api/client.py +525 -27
- ksadk/builders/code_builder.py +284 -8
- ksadk/builders/container_builder.py +8 -1
- ksadk/builders/managed_runtime_builder.py +39 -35
- ksadk/cli/__init__.py +17 -0
- ksadk/cli/cmd_dashboard.py +15 -1
- ksadk/cli/cmd_deploy.py +10 -2
- ksadk/cli/cmd_eval.py +66 -9
- ksadk/cli/cmd_evalset.py +284 -0
- ksadk/cli/cmd_files.py +5 -1
- ksadk/cli/cmd_hermes.py +1 -126
- ksadk/cli/cmd_invoke.py +28 -38
- ksadk/cli/cmd_managed_runtime.py +95 -0
- ksadk/cli/cmd_observe.py +85 -0
- ksadk/cli/cmd_openclaw.py +1 -435
- ksadk/cli/cmd_replay.py +28 -4
- ksadk/cli/cmd_studio.py +99 -8
- ksadk/cli/cmd_web.py +10 -2
- ksadk/cli/hermes_env.py +151 -0
- ksadk/cli/invoke_payload.py +49 -0
- ksadk/cli/openclaw_env.py +458 -0
- ksadk/codex/client.py +180 -30
- ksadk/codex/runtime.py +428 -326
- ksadk/configs/env_registry.py +66 -12
- ksadk/configs/env_registry_pcm.py +181 -0
- ksadk/configs/env_var_spec.py +18 -0
- ksadk/configs/global_config.py +5 -0
- ksadk/context_engine/__init__.py +98 -0
- ksadk/context_engine/assembler.py +176 -0
- ksadk/context_engine/baseline.py +419 -0
- ksadk/context_engine/cache_observability.py +228 -0
- ksadk/context_engine/capabilities.py +443 -0
- ksadk/context_engine/contributors.py +344 -0
- ksadk/context_engine/hosted_pipeline.py +417 -0
- ksadk/context_engine/models.py +117 -0
- ksadk/context_engine/planner.py +698 -0
- ksadk/context_engine/policies.py +319 -0
- ksadk/context_engine/projection.py +31 -0
- ksadk/context_engine/shadow_plan.py +266 -0
- ksadk/context_engine/tokenizer.py +164 -0
- ksadk/conversations/context.py +126 -6
- ksadk/conversations/message_projection.py +292 -28
- ksadk/conversations/model_context.py +49 -3
- ksadk/conversations/runtime_compaction.py +207 -5
- ksadk/conversations/runtime_input.py +184 -2
- ksadk/conversations/runtime_invocation.py +81 -3
- ksadk/conversations/runtime_observability.py +141 -0
- ksadk/conversations/runtime_payloads.py +42 -0
- ksadk/conversations/runtime_preparation.py +272 -2
- ksadk/conversations/runtime_resume.py +20 -1
- ksadk/conversations/runtime_stream_events.py +94 -9
- ksadk/conversations/semantic_summary.py +311 -1
- ksadk/conversations/session_lock.py +51 -0
- ksadk/deployment/env_forward.py +72 -0
- ksadk/deployment/managed_runtime.py +5 -0
- ksadk/deployment/providers/serverless.py +143 -69
- ksadk/evaluation/__init__.py +32 -0
- ksadk/evaluation/a2a_adapter.py +9 -1
- ksadk/evaluation/adapters.py +18 -5
- ksadk/evaluation/agent_eval_client.py +395 -0
- ksadk/evaluation/cloud_binding.py +80 -0
- ksadk/evaluation/cloud_converter.py +194 -0
- ksadk/evaluation/cloud_service.py +199 -0
- ksadk/evaluation/contracts.py +73 -4
- ksadk/evaluation/evaluators.py +183 -17
- ksadk/evaluation/evidence.py +258 -0
- ksadk/evaluation/executor.py +31 -6
- ksadk/evaluation/local_adapter.py +550 -0
- ksadk/evaluation/service_env.py +27 -0
- ksadk/evaluation/studio_build_adapter.py +253 -0
- ksadk/evaluation/target.py +15 -6
- ksadk/events/__init__.py +13 -13
- ksadk/events/_v1_compat/__init__.py +1 -0
- ksadk/events/_v1_compat/models.py +299 -0
- ksadk/events/_v1_compat/parser.py +247 -0
- ksadk/events/_v1_compat/projection.py +753 -0
- ksadk/events/adapters/__init__.py +34 -0
- ksadk/events/adapters/_a2a_snapshot.py +622 -0
- ksadk/events/adapters/_a2a_support.py +275 -0
- ksadk/events/adapters/_codex_interactions.py +375 -0
- ksadk/events/adapters/_codex_items.py +801 -0
- ksadk/events/adapters/_codex_validators.py +311 -0
- ksadk/events/adapters/_langgraph_support.py +785 -0
- ksadk/events/adapters/a2a.py +841 -0
- ksadk/events/adapters/adk.py +503 -0
- ksadk/events/adapters/codex.py +717 -0
- ksadk/events/adapters/langgraph.py +745 -0
- ksadk/events/canonical.py +440 -0
- ksadk/events/canonical_replay.py +497 -0
- ksadk/events/canonical_store.py +468 -0
- ksadk/events/cold_recovery.py +257 -0
- ksadk/events/content.py +89 -0
- ksadk/events/identity.py +86 -0
- ksadk/events/pipeline.py +455 -0
- ksadk/events/projections.py +66 -0
- ksadk/events/reducer.py +661 -0
- ksadk/events/replay.py +3 -36
- ksadk/events/runtime_event.py +20 -265
- ksadk/events/session_event.py +324 -0
- ksadk/events/store.py +3 -316
- ksadk/events/v1_compat.py +41 -0
- ksadk/harness/runtime.py +160 -57
- ksadk/identity/resolver.py +4 -3
- ksadk/interaction/__init__.py +28 -0
- ksadk/interaction/contracts.py +136 -0
- ksadk/interaction/ledger.py +189 -0
- ksadk/interaction/provider.py +122 -0
- ksadk/interaction/providers/__init__.py +52 -0
- ksadk/interaction/providers/adk.py +40 -0
- ksadk/interaction/providers/codex.py +94 -0
- ksadk/interaction/providers/langgraph.py +58 -0
- ksadk/kernel/__init__.py +117 -0
- ksadk/kernel/authorization.py +258 -0
- ksadk/kernel/bootstrap.py +1074 -0
- ksadk/kernel/contract_fingerprints.py +61 -0
- ksadk/kernel/contracts.py +362 -0
- ksadk/kernel/control.py +219 -0
- ksadk/kernel/errors.py +79 -0
- ksadk/kernel/ingress.py +1102 -0
- ksadk/kernel/mapping.py +111 -0
- ksadk/kernel/memory_store.py +1133 -0
- ksadk/kernel/postgres_store.py +1756 -0
- ksadk/kernel/recovery.py +452 -0
- ksadk/kernel/runtime_identity.py +103 -0
- ksadk/kernel/sql/001_agent_kernel.sql +120 -0
- ksadk/kernel/sqlite_store.py +1410 -0
- ksadk/kernel/state.py +145 -0
- ksadk/kernel/store.py +232 -0
- ksadk/kernel/worker.py +953 -0
- ksadk/knowledge_base/client.py +7 -0
- ksadk/knowledge_base/service.py +32 -5
- ksadk/memory/__init__.py +61 -0
- ksadk/memory/adk/backends/base_ltm_backend.py +96 -1
- ksadk/memory/adk/backends/http_ltm_backend.py +14 -5
- ksadk/memory/adk/backends/inmemory_ltm_backend.py +136 -3
- ksadk/memory/adk/backends/sdk_ltm_backend.py +384 -2
- ksadk/memory/adk/backends/sqlite_ltm_backend.py +95 -0
- ksadk/memory/coordinator.py +461 -0
- ksadk/memory/events.py +202 -0
- ksadk/memory/extraction.py +228 -0
- ksadk/memory/ltm_backend_factory.py +16 -3
- ksadk/memory/models.py +316 -0
- ksadk/memory/policy.py +215 -0
- ksadk/memory/provider.py +47 -0
- ksadk/memory/provider_adapter.py +159 -0
- ksadk/memory/provider_resolver.py +71 -0
- ksadk/memory/providers/__init__.py +5 -0
- ksadk/memory/providers/local_sqlite.py +490 -0
- ksadk/memory/resolved_policy.py +145 -0
- ksadk/memory/service.py +188 -6
- ksadk/model_proxy/bootstrap.py +16 -9
- ksadk/model_proxy/detect.py +202 -9
- ksadk/model_proxy/namespace.py +39 -15
- ksadk/model_proxy/server.py +24 -5
- ksadk/model_proxy/transform.py +60 -2
- ksadk/observability/__init__.py +25 -0
- ksadk/observability/session_log.py +420 -0
- ksadk/observability/trajectory.py +105 -0
- ksadk/prompts/__init__.py +71 -0
- ksadk/prompts/compiler.py +215 -0
- ksadk/prompts/models.py +82 -0
- ksadk/prompts/projection.py +89 -0
- ksadk/prompts/resolved.py +137 -0
- ksadk/prompts/sources.py +233 -0
- ksadk/runners/_langgraph_runner_streams.py +822 -0
- ksadk/runners/adk_runner.py +5 -5
- ksadk/runners/base_runner.py +16 -0
- ksadk/runners/factory.py +1 -2
- ksadk/runners/langgraph_runner.py +198 -437
- ksadk/runtime/_runner_adapter/__init__.py +1 -0
- ksadk/runtime/_runner_adapter/stream_mapping.py +788 -0
- ksadk/runtime/adapter.py +118 -2
- ksadk/runtime/conversation_execution.py +316 -182
- ksadk/runtime/executor.py +144 -3
- ksadk/runtime/factory.py +193 -7
- ksadk/runtime/hosted_finalizer.py +268 -0
- ksadk/runtime/launch.py +14 -1
- ksadk/runtime/preprocessing.py +25 -3
- ksadk/runtime/runner_adapter.py +288 -508
- ksadk/runtime/usage.py +33 -0
- ksadk/sandbox/backends/e2b.py +35 -2
- ksadk/server/composition.py +8 -0
- ksadk/server/factory.py +69 -6
- ksadk/server/routes/kernel_ingress.py +258 -0
- ksadk/server/routes/openai_compat.py +88 -8
- ksadk/server/routes/projection.py +35 -20
- ksadk/server/routes/run.py +94 -0
- ksadk/server/routes/sessions.py +2 -0
- ksadk/server/routes/streaming.py +5 -2
- ksadk/server/static/assets/{ArtifactsPanel-CakCqxEN.js → ArtifactsPanel-DSU1sWD_.js} +1 -1
- ksadk/server/static/assets/{CodeBlock-CynLknyO.js → CodeBlock-DOH6MVcn.js} +4 -4
- ksadk/server/static/assets/{MathMessageMarkdown-3sQdOysS.js → MathMessageMarkdown-BL8my1R2.js} +4 -4
- ksadk/server/static/assets/MathMessageMarkdown-BorAY7qD.css +1 -0
- ksadk/server/static/assets/MermaidBlock-Dz4IP-Tx.js +312 -0
- ksadk/server/static/assets/NativeTerminalPanel-DUrK0JpZ.js +1 -0
- ksadk/server/static/assets/abnfDiagram-VCTEODGH-g20pFzNV.js +1 -0
- ksadk/server/static/assets/arc-C4FzinUA.js +1 -0
- ksadk/server/static/assets/architecture-7GRP2DOG-DjKratdf.js +1 -0
- ksadk/server/static/assets/architectureDiagram-5GKGNRK7-DpIqL5h4.js +36 -0
- ksadk/server/static/assets/blockDiagram-NRAW4CY4-BjkljTNz.js +129 -0
- ksadk/server/static/assets/c4Diagram-UCG6FXSJ-Dk_ieq2X.js +38 -0
- ksadk/server/static/assets/channel-4cQHKtx1.js +1 -0
- ksadk/server/static/assets/chunk-2Q5K7J3B-DmgWkESh.js +1 -0
- ksadk/server/static/assets/{chunk-FMBD7UC4-B_fH2YuH.js → chunk-5VM5RSS4-BVHAchFb.js} +1 -1
- ksadk/server/static/assets/{chunk-ND2GUHAM-D6rFLaVV.js → chunk-F27PBJKO-C-ipQzuS.js} +1 -1
- ksadk/server/static/assets/chunk-G27WJ6UU-C2EyJbIK.js +231 -0
- ksadk/server/static/assets/{chunk-4BX2VUAB-B9drTgOW.js → chunk-JWPE2WC7-vYvVJb_M.js} +1 -1
- ksadk/server/static/assets/chunk-LCL6LL3I-BcI6ysPT.js +206 -0
- ksadk/server/static/assets/chunk-POPQ4Y6H-C030x_Z1.js +1 -0
- ksadk/server/static/assets/chunk-RHFEMEQ7-yyGpsz4n.js +168 -0
- ksadk/server/static/assets/chunk-SVP7TREG-BLTlmMU7.js +88 -0
- ksadk/server/static/assets/chunk-XXDRQBXY-C_32ArgP.js +1 -0
- ksadk/server/static/assets/classDiagram-DTDB5LWJ-DLFd9Xi0.js +1 -0
- ksadk/server/static/assets/classDiagram-v2-JRS7N3AN-DLFd9Xi0.js +1 -0
- ksadk/server/static/assets/{cose-bilkent-S5V4N54A-ChNs_Mdk.js → cose-bilkent-JH36ORCC-9YQYwdl0.js} +1 -1
- ksadk/server/static/assets/cynefin-OW5HDTMX-DjEM48Qp.js +1 -0
- ksadk/server/static/assets/cynefinDiagram-5FMLGOSQ-ErLF5N13.js +62 -0
- ksadk/server/static/assets/cytoscape.esm-CyCl8rPi.js +321 -0
- ksadk/server/static/assets/dagre-3AP2YEHR-DFiQF-6f.js +4 -0
- ksadk/server/static/assets/dagre-BuhGnRI1.js +1 -0
- ksadk/server/static/assets/diagram-S7CK7UJ4-Bt1v8-GC.js +30 -0
- ksadk/server/static/assets/diagram-UQ7AKVKN-DSCxJdBK.js +41 -0
- ksadk/server/static/assets/diagram-VSXAHHWV-DHfYwp_9.js +3 -0
- ksadk/server/static/assets/diagram-VX7I27RA-DdzD-4Le.js +24 -0
- ksadk/server/static/assets/diagram-Z3DM3KII-Du-nAJ9F.js +24 -0
- ksadk/server/static/assets/{dist-Dli7qW-B.js → dist-8hqcx0sU.js} +1 -1
- ksadk/server/static/assets/dist-B7seoj3d.js +1 -0
- ksadk/server/static/assets/{dist-C1sz5Eo3.js → dist-BE7bu-DL.js} +1 -1
- ksadk/server/static/assets/{dist-fhOuWds5.js → dist-BVDffZ0U.js} +1 -1
- ksadk/server/static/assets/{dist-BjOdlDjj.js → dist-BX8z72IC.js} +1 -1
- ksadk/server/static/assets/{dist-DsHPdk3W.js → dist-Bf2M8m3N.js} +1 -1
- ksadk/server/static/assets/{dist-o2OVmKvt.js → dist-BjU6y-A2.js} +1 -1
- ksadk/server/static/assets/{dist-DWKByxWV.js → dist-BytlxIDT.js} +1 -1
- ksadk/server/static/assets/{dist-DJN_6Y39.js → dist-CSh_DE14.js} +1 -1
- ksadk/server/static/assets/{dist-DQU9EWw-.js → dist-CXYYBw3_.js} +1 -1
- ksadk/server/static/assets/{dist-4N2NMVYg.js → dist-C_wsv-Qd.js} +1 -1
- ksadk/server/static/assets/{dist-gLnrGsoU.js → dist-ClxGviKw.js} +1 -1
- ksadk/server/static/assets/{dist-j6Dxmf_j.js → dist-CttYUqzS.js} +1 -1
- ksadk/server/static/assets/{dist-D6MpCZtz.js → dist-DNp6rLRA.js} +1 -1
- ksadk/server/static/assets/{dist-BB3-OwTQ.js → dist-DUX-id_F.js} +1 -1
- ksadk/server/static/assets/{dist-_pHPTyZ-.js → dist-DmldrHd_.js} +1 -1
- ksadk/server/static/assets/{dist-CWV4lDr1.js → dist-DnfXs8Vn.js} +2 -2
- ksadk/server/static/assets/{dist-B5oS1zcj.js → dist-Dq9gLD7L.js} +1 -1
- ksadk/server/static/assets/{dist-B-jNR6Vn.js → dist-W-TIVntx.js} +1 -1
- ksadk/server/static/assets/{dist-BIlKoW0k.js → dist-dDdADKFA.js} +1 -1
- ksadk/server/static/assets/{dist-X4TnqwOK.js → dist-dydu68Fl.js} +1 -1
- ksadk/server/static/assets/{dist-CmZHzlwZ.js → dist-ngtN0DJB.js} +1 -1
- ksadk/server/static/assets/ebnfDiagram-PWID7BFC-Da9C9NO1.js +1 -0
- ksadk/server/static/assets/erDiagram-SSCWMZ5O-EAGqqR79.js +99 -0
- ksadk/server/static/assets/eventmodeling-NTZA5JFV-CMgMaJrC.js +1 -0
- ksadk/server/static/assets/flowDiagram-A5DVABFB-BBKL0x3P.js +1 -0
- ksadk/server/static/assets/ganttDiagram-EL5Y4UJY-DqJsKb59.js +292 -0
- ksadk/server/static/assets/gitGraph-4MIJSDKK-Dw63mrhw.js +1 -0
- ksadk/server/static/assets/gitGraphDiagram-WWUBYQGX-B6g4dtDi.js +106 -0
- ksadk/server/static/assets/index-8ipRcQ-M.js +240 -0
- ksadk/server/static/assets/index-ByFCqjlh.css +2 -0
- ksadk/server/static/assets/info-A6RAGUB7-B6iAblII.js +1 -0
- ksadk/server/static/assets/infoDiagram-RXCK75RN-Djm_nbd5.js +2 -0
- ksadk/server/static/assets/{ishikawaDiagram-YF4QCWOH-K0OOfVna.js → ishikawaDiagram-5VMMS53U-DWya9SG2.js} +6 -6
- ksadk/server/static/assets/{journeyDiagram-JHISSGLW-8LeOJaZp.js → journeyDiagram-EYS64GPL-DutxhSNI.js} +6 -6
- ksadk/server/static/assets/{kanban-definition-UN3LZRKU-C6uCgZrW.js → kanban-definition-3QL26DDD-DJdOF8Fm.js} +10 -10
- ksadk/server/static/assets/katex-vFWytM5c.js +257 -0
- ksadk/server/static/assets/{linear-hdBcYzM8.js → linear-BHjG8b-J.js} +1 -1
- ksadk/server/static/assets/mermaid-parser.core-KGSy4jWT.js +166 -0
- ksadk/server/static/assets/{mindmap-definition-RKZ34NQL-Bjy_2v4_.js → mindmap-definition-FBJOCRG2-9-HC88D4.js} +29 -29
- ksadk/server/static/assets/packet-AYTQ26CC-BOYAipuq.js +1 -0
- ksadk/server/static/assets/pegDiagram-XKGWAZYB-DrEZd4fD.js +1 -0
- ksadk/server/static/assets/pie-WAS4IAKB-Ctq0Kbku.js +1 -0
- ksadk/server/static/assets/pieDiagram-E7YTZNPT-DpjqOFFp.js +39 -0
- ksadk/server/static/assets/{quadrantDiagram-W4KKPZXB-BmkRbwCg.js → quadrantDiagram-AXDQQJYC-BiNhgOXX.js} +6 -6
- ksadk/server/static/assets/radar-RG4KPBEZ-DN0-ul_0.js +1 -0
- ksadk/server/static/assets/railroad-74A4TZTK-C6cC_to0.js +1 -0
- ksadk/server/static/assets/railroad-abnf-HS5TGJTU-BimjIuRc.js +1 -0
- ksadk/server/static/assets/railroad-ebnf-LZEXJU2U-CvY65ABq.js +1 -0
- ksadk/server/static/assets/railroad-peg-WCYAUIDC-D72Iq_Tv.js +1 -0
- ksadk/server/static/assets/railroadDiagram-O6MQD6OU-_Y3Ojg6G.js +1 -0
- ksadk/server/static/assets/requirementDiagram-EFPCY7ZU-DeCFdg9K.js +84 -0
- ksadk/server/static/assets/{sankeyDiagram-5OEKKPKP-l6iXmU65.js → sankeyDiagram-P5KCCOFB-CPH75rhw.js} +7 -7
- ksadk/server/static/assets/{sequenceDiagram-3UESZ5HK-Cq6UBeQB.js → sequenceDiagram-WJ2MYXX4-OEpQQdr4.js} +10 -10
- ksadk/server/static/assets/sizeCapture-X5ZJPWSS-heUErzhI.js +1 -0
- ksadk/server/static/assets/stateDiagram-HBIQ2CUA-DvA3jSMB.js +1 -0
- ksadk/server/static/assets/stateDiagram-v2-4QOOHH4V-BgQY03nz.js +1 -0
- ksadk/server/static/assets/swimlanes-XN3QIQJK-CR-dfN_t.js +1 -0
- ksadk/server/static/assets/swimlanesDiagram-VK2B7HYN-DLVw3q5Q.js +8 -0
- ksadk/server/static/assets/{timeline-definition-PNZ67QCA-DEz24vV0.js → timeline-definition-24CTP7MA-DAVJf1TX.js} +7 -7
- ksadk/server/static/assets/treeView-Q6P3EWNA-BMpO0wsB.js +1 -0
- ksadk/server/static/assets/treemap-WGGIJYW6-Et0aqzU3.js +1 -0
- ksadk/server/static/assets/vennDiagram-4TSXK5OY-DwM8eDkh.js +34 -0
- ksadk/server/static/assets/wardley-WFR3VGLG-CbY0mhpl.js +1 -0
- ksadk/server/static/assets/wardleyDiagram-VM6X3IG4-DZL-Zz2t.js +78 -0
- ksadk/server/static/assets/xychartDiagram-S5SC5T6Z-Dy6Yh_hu.js +7 -0
- ksadk/server/static/index.html +2 -2
- ksadk/sessions/__init__.py +26 -9
- ksadk/sessions/_local_service_sync.py +688 -0
- ksadk/sessions/_local_tables.py +21 -0
- ksadk/sessions/_postgres_schema.py +305 -0
- ksadk/sessions/_postgres_tables.py +15 -0
- ksadk/sessions/base.py +80 -1
- ksadk/sessions/in_memory.py +53 -2
- ksadk/sessions/local_service.py +63 -604
- ksadk/sessions/postgres_service.py +58 -148
- ksadk/sessions/resilient.py +35 -1
- ksadk/studio/api.py +577 -25
- ksadk/studio/api_contracts.py +114 -5
- ksadk/studio/api_memory_routes.py +82 -0
- ksadk/studio/authoring.py +252 -27
- ksadk/studio/authoring_coordinator.py +799 -67
- ksadk/studio/builder.py +88 -11
- ksadk/studio/capabilities.py +17 -0
- ksadk/studio/cloud.py +1916 -95
- ksadk/studio/codex_agent_service.py +125 -14
- ksadk/studio/codex_authoring.py +469 -0
- ksadk/studio/codex_builder.py +138 -25
- ksadk/studio/codex_manifest.py +51 -22
- ksadk/studio/codex_run.py +46 -3
- ksadk/studio/compiler.py +1 -0
- ksadk/studio/contracts.py +114 -3
- ksadk/studio/event_store.py +25 -95
- ksadk/studio/framework_run.py +231 -3
- ksadk/studio/hosted_kernel.py +317 -0
- ksadk/studio/manifest_resolver.py +131 -0
- ksadk/studio/model_client.py +95 -9
- ksadk/studio/model_profile_service.py +1 -1
- ksadk/studio/operations.py +37 -5
- ksadk/studio/otel_trace.py +348 -42
- ksadk/studio/pcm_memory.py +85 -0
- ksadk/studio/repository.py +23 -2
- ksadk/studio/resource_catalog.py +43 -0
- ksadk/studio/run_service.py +563 -137
- ksadk/studio/runtime_source.py +42 -16
- ksadk/studio/service.py +1180 -72
- ksadk/studio/shared_web.py +32 -22
- ksadk/studio/static/assets/index-BLpcdrgW.css +1 -0
- ksadk/studio/static/assets/index-CYekR2Xv.js +260 -0
- ksadk/studio/static/index.html +2 -2
- ksadk/studio/templates.py +100 -8
- ksadk/studio/validator.py +19 -0
- ksadk/studio/workspace.py +30 -32
- ksadk/tracing/setup.py +304 -3
- ksadk/version.py +1 -1
- ksadk_runtime_common/schemas/runtime_event_v1.json +37 -0
- ksadk_runtime_common/schemas/runtime_event_v2.json +271 -0
- ksadk/events/parser.py +0 -191
- ksadk/server/static/assets/MathMessageMarkdown-DeYh8QPr.css +0 -1
- ksadk/server/static/assets/MermaidBlock-NERD_ef7.js +0 -303
- ksadk/server/static/assets/NativeTerminalPanel-CiHWf82q.js +0 -1
- ksadk/server/static/assets/arc-DrgjcKhl.js +0 -1
- ksadk/server/static/assets/architecture-7EHR7CIX-CpZLRCcY.js +0 -1
- ksadk/server/static/assets/architectureDiagram-3BPJPVTR-BXoVRbQ6.js +0 -36
- ksadk/server/static/assets/blockDiagram-GPEHLZMM-BnaB3Ywv.js +0 -132
- ksadk/server/static/assets/c4Diagram-AAUBKEIU-Dw4weZcp.js +0 -10
- ksadk/server/static/assets/channel-Dt3rQTFI.js +0 -1
- ksadk/server/static/assets/chunk-2J33WTMH-ChjpLK7j.js +0 -1
- ksadk/server/static/assets/chunk-55IACEB6-CK4ROATy.js +0 -1
- ksadk/server/static/assets/chunk-727SXJPM-B9KtTTgw.js +0 -206
- ksadk/server/static/assets/chunk-AQP2D5EJ-1O1mki3m.js +0 -231
- ksadk/server/static/assets/chunk-QZHKN3VN-iXEZtKQc.js +0 -1
- ksadk/server/static/assets/classDiagram-4FO5ZUOK-DIveV17Q.js +0 -1
- ksadk/server/static/assets/classDiagram-v2-Q7XG4LA2-DIveV17Q.js +0 -1
- ksadk/server/static/assets/cytoscape.esm-DelgaX4f.js +0 -321
- ksadk/server/static/assets/dagre-BM42HDAG-D0QXg_MQ.js +0 -4
- ksadk/server/static/assets/dagre-Bx709z4p.js +0 -1
- ksadk/server/static/assets/diagram-2AECGRRQ-DBDDKwBQ.js +0 -43
- ksadk/server/static/assets/diagram-5GNKFQAL-BkwDOxmO.js +0 -10
- ksadk/server/static/assets/diagram-KO2AKTUF-Bv8waYvY.js +0 -3
- ksadk/server/static/assets/diagram-LMA3HP47-e1VECDdu.js +0 -24
- ksadk/server/static/assets/diagram-OG6HWLK6-Ds9adfRl.js +0 -24
- ksadk/server/static/assets/dist-B5J2uhNk.js +0 -1
- ksadk/server/static/assets/erDiagram-TEJ5UH35-BPItFKH6.js +0 -85
- ksadk/server/static/assets/eventmodeling-FCH6USID-DYFSxbqr.js +0 -1
- ksadk/server/static/assets/flowDiagram-I6XJVG4X-BbYB9w5Y.js +0 -162
- ksadk/server/static/assets/ganttDiagram-6RSMTGT7-TQXa0KXv.js +0 -292
- ksadk/server/static/assets/gitGraph-WXDBUCRP-DyNYp6BN.js +0 -1
- ksadk/server/static/assets/gitGraphDiagram-PVQCEYII-bKblCnpa.js +0 -106
- ksadk/server/static/assets/graphlib-B8gBHxth.js +0 -1
- ksadk/server/static/assets/index-R52pJJvg.js +0 -177
- ksadk/server/static/assets/index-jJr3_955.css +0 -2
- ksadk/server/static/assets/info-J43DQDTF-WUx7qTde.js +0 -1
- ksadk/server/static/assets/infoDiagram-5YYISTIA-BGVT7J_i.js +0 -2
- ksadk/server/static/assets/katex-CYWseY5E.js +0 -265
- ksadk/server/static/assets/mermaid-parser.core-BWrDjSZM.js +0 -161
- ksadk/server/static/assets/packet-YPE3B663-BN13y_xl.js +0 -1
- ksadk/server/static/assets/pie-LRSECV5Y-ftSLXhhc.js +0 -1
- ksadk/server/static/assets/pieDiagram-4H26LBE5-GmmqNiVH.js +0 -30
- ksadk/server/static/assets/radar-GUYGQ44K-jaICkIeO.js +0 -1
- ksadk/server/static/assets/requirementDiagram-4Y6WPE33-DSWFqL7c.js +0 -84
- ksadk/server/static/assets/stateDiagram-AJRCARHV-qzTQpg3Y.js +0 -1
- ksadk/server/static/assets/stateDiagram-v2-BHNVJYJU-BYCoYGAN.js +0 -1
- ksadk/server/static/assets/treeView-BLDUP644-Cpib_vlz.js +0 -1
- ksadk/server/static/assets/treemap-LRROVOQU-DQxfmVHK.js +0 -1
- ksadk/server/static/assets/vennDiagram-CIIHVFJN-CMCixki2.js +0 -34
- ksadk/server/static/assets/wardley-L42UT6IY-BQYHnnkU.js +0 -1
- ksadk/server/static/assets/wardleyDiagram-YWT4CUSO-CVzB8F9K.js +0 -78
- ksadk/server/static/assets/xychartDiagram-2RQKCTM6-BFBqBLc1.js +0 -7
- ksadk/studio/evaluation.py +0 -192
- ksadk/studio/static/assets/index-CaEN0eTR.css +0 -1
- ksadk/studio/static/assets/index-DI2eY_NH.js +0 -252
- {agentengine_sdk_python-0.8.1.dist-info → agentengine_sdk_python-0.8.2.dist-info}/WHEEL +0 -0
- {agentengine_sdk_python-0.8.1.dist-info → agentengine_sdk_python-0.8.2.dist-info}/entry_points.txt +0 -0
- {agentengine_sdk_python-0.8.1.dist-info → agentengine_sdk_python-0.8.2.dist-info}/licenses/LICENSE +0 -0
- {agentengine_sdk_python-0.8.1.dist-info → agentengine_sdk_python-0.8.2.dist-info}/top_level.txt +0 -0
ksadk/cli/cmd_openclaw.py
CHANGED
|
@@ -81,7 +81,7 @@ from ksadk.cli.ui import (
|
|
|
81
81
|
from ksadk.configs.env_registry import is_sensitive_env_var
|
|
82
82
|
from ksadk.conversations.model_context import normalize_model_metadata
|
|
83
83
|
from ksadk.deployment.agent_access import get_latest_agent_access
|
|
84
|
-
from ksadk.
|
|
84
|
+
from ksadk.cli.openclaw_env import _build_openclaw_env_vars, _normalize_openclaw_gateway_auth_env
|
|
85
85
|
from ksadk.openclaw_gateway import (
|
|
86
86
|
OpenClawGatewayClient,
|
|
87
87
|
OpenClawGatewayError,
|
|
@@ -97,15 +97,6 @@ DEFAULT_OPENCLAW_REPO = "openclaw"
|
|
|
97
97
|
DEFAULT_OPENCLAW_VERSION = "2026.6.1"
|
|
98
98
|
DEFAULT_OPENCLAW_REGISTRY = "ghcr.io/kingsoftcloud"
|
|
99
99
|
DEFAULT_OPENCLAW_NAME = "openclaw-gateway"
|
|
100
|
-
DEFAULT_TRUSTED_PROXY_USER_HEADER = "x-forwarded-user"
|
|
101
|
-
DEFAULT_TRUSTED_PROXY_CIDRS = [
|
|
102
|
-
"127.0.0.1",
|
|
103
|
-
"::1",
|
|
104
|
-
"10.0.0.0/8",
|
|
105
|
-
"172.16.0.0/12",
|
|
106
|
-
"192.168.0.0/16",
|
|
107
|
-
"35.0.0.0/8",
|
|
108
|
-
]
|
|
109
100
|
_GLOBAL_ENV_CACHE: Optional[Dict[str, str]] = None
|
|
110
101
|
OPENCLAW_SECURITY_PROFILES = ("relaxed", "strict", "strictest")
|
|
111
102
|
OPENCLAW_CHANNELS = ("weixin", "feishu", "wps-xiezuo")
|
|
@@ -386,33 +377,6 @@ def _openclaw_registry_env() -> dict[str, str]:
|
|
|
386
377
|
return env
|
|
387
378
|
|
|
388
379
|
|
|
389
|
-
def _resolve_model_base_url(cli_value: Optional[str]) -> Optional[str]:
|
|
390
|
-
"""解析模型 Base URL,缺失时回退到 settings.model.api_base(KSPMAS 自动探测)。"""
|
|
391
|
-
if cli_value and str(cli_value).strip():
|
|
392
|
-
return str(cli_value).strip()
|
|
393
|
-
|
|
394
|
-
from_env = _resolve_env(
|
|
395
|
-
"OPENCLAW_MODEL_BASE_URL",
|
|
396
|
-
"OPENAI_BASE_URL",
|
|
397
|
-
"OPENAI_API_BASE",
|
|
398
|
-
"LLM_API_BASE",
|
|
399
|
-
"MODEL_API_BASE",
|
|
400
|
-
)
|
|
401
|
-
if from_env:
|
|
402
|
-
return from_env
|
|
403
|
-
|
|
404
|
-
try:
|
|
405
|
-
from ksadk.configs.settings import settings
|
|
406
|
-
|
|
407
|
-
api_base = settings.model.api_base
|
|
408
|
-
if api_base and str(api_base).strip():
|
|
409
|
-
return str(api_base).strip()
|
|
410
|
-
except Exception:
|
|
411
|
-
pass
|
|
412
|
-
|
|
413
|
-
return None
|
|
414
|
-
|
|
415
|
-
|
|
416
380
|
def _summarize_openclaw_account(agents: list[Dict[str, Any]]) -> str:
|
|
417
381
|
"""汇总列表所属账号,优先使用响应字段,缺失时回退当前 CLI 上下文。"""
|
|
418
382
|
accounts = sorted(
|
|
@@ -455,88 +419,6 @@ def _print_openclaw_list_summary(table: RichTable, summary_text: str) -> None:
|
|
|
455
419
|
console.print(f"[muted]{summary_text}[/]")
|
|
456
420
|
|
|
457
421
|
|
|
458
|
-
def _normalize_ui_locale(raw: Optional[str]) -> str:
|
|
459
|
-
"""标准化 UI 语言代码,默认 zh-CN。"""
|
|
460
|
-
text = str(raw or "").strip()
|
|
461
|
-
if not text:
|
|
462
|
-
return "zh-CN"
|
|
463
|
-
|
|
464
|
-
base = text.split(".", 1)[0].replace("_", "-").strip()
|
|
465
|
-
low = base.lower()
|
|
466
|
-
|
|
467
|
-
if low in {"c", "c-utf-8", "c.utf-8", "posix"}:
|
|
468
|
-
return "zh-CN"
|
|
469
|
-
if (
|
|
470
|
-
low.startswith("zh-tw")
|
|
471
|
-
or low.startswith("zh-hk")
|
|
472
|
-
or low.startswith("zh-mo")
|
|
473
|
-
or low.startswith("zh-hant")
|
|
474
|
-
):
|
|
475
|
-
return "zh-TW"
|
|
476
|
-
if low.startswith("zh"):
|
|
477
|
-
return "zh-CN"
|
|
478
|
-
if low.startswith("pt"):
|
|
479
|
-
return "pt-BR"
|
|
480
|
-
if low.startswith("de"):
|
|
481
|
-
return "de"
|
|
482
|
-
if low.startswith("en"):
|
|
483
|
-
return "en"
|
|
484
|
-
|
|
485
|
-
return "zh-CN"
|
|
486
|
-
|
|
487
|
-
|
|
488
|
-
def _is_truthy(raw: Optional[str]) -> bool:
|
|
489
|
-
text = str(raw or "").strip().lower()
|
|
490
|
-
return text in {"1", "true", "yes", "on"}
|
|
491
|
-
|
|
492
|
-
|
|
493
|
-
def _resolve_exec_profile_overrides(security_profile: Optional[str]) -> Dict[str, str]:
|
|
494
|
-
"""根据 CLI 安全预设返回 OpenClaw 运行时环境变量覆盖项。"""
|
|
495
|
-
profile = str(security_profile or "").strip().lower()
|
|
496
|
-
if not profile:
|
|
497
|
-
return {}
|
|
498
|
-
|
|
499
|
-
common = {
|
|
500
|
-
"OPENCLAW_EXEC_HOST": "gateway",
|
|
501
|
-
"OPENCLAW_EXEC_AUTO_ALLOW_SKILLS": "false",
|
|
502
|
-
"OPENCLAW_ELEVATED_ENABLED": "false",
|
|
503
|
-
}
|
|
504
|
-
if profile == "relaxed":
|
|
505
|
-
return {
|
|
506
|
-
**common,
|
|
507
|
-
"OPENCLAW_EXEC_STRICT_MODE": "false",
|
|
508
|
-
"OPENCLAW_EXEC_UNSAFE_MODE": "true",
|
|
509
|
-
"OPENCLAW_EXEC_SECURITY": "full",
|
|
510
|
-
"OPENCLAW_EXEC_ASK": "off",
|
|
511
|
-
"OPENCLAW_EXEC_ASK_FALLBACK": "full",
|
|
512
|
-
"OPENCLAW_EXEC_DEFAULT_ALLOWLIST_ENABLED": "false",
|
|
513
|
-
"OPENCLAW_FS_WORKSPACE_ONLY": "false",
|
|
514
|
-
}
|
|
515
|
-
if profile == "strict":
|
|
516
|
-
return {
|
|
517
|
-
**common,
|
|
518
|
-
"OPENCLAW_EXEC_STRICT_MODE": "true",
|
|
519
|
-
"OPENCLAW_EXEC_UNSAFE_MODE": "false",
|
|
520
|
-
"OPENCLAW_EXEC_SECURITY": "allowlist",
|
|
521
|
-
"OPENCLAW_EXEC_ASK": "off",
|
|
522
|
-
"OPENCLAW_EXEC_ASK_FALLBACK": "allowlist",
|
|
523
|
-
"OPENCLAW_EXEC_DEFAULT_ALLOWLIST_ENABLED": "true",
|
|
524
|
-
"OPENCLAW_FS_WORKSPACE_ONLY": "false",
|
|
525
|
-
}
|
|
526
|
-
if profile == "strictest":
|
|
527
|
-
return {
|
|
528
|
-
**common,
|
|
529
|
-
"OPENCLAW_EXEC_STRICT_MODE": "true",
|
|
530
|
-
"OPENCLAW_EXEC_UNSAFE_MODE": "false",
|
|
531
|
-
"OPENCLAW_EXEC_SECURITY": "deny",
|
|
532
|
-
"OPENCLAW_EXEC_ASK": "off",
|
|
533
|
-
"OPENCLAW_EXEC_ASK_FALLBACK": "deny",
|
|
534
|
-
"OPENCLAW_EXEC_DEFAULT_ALLOWLIST_ENABLED": "false",
|
|
535
|
-
"OPENCLAW_FS_WORKSPACE_ONLY": "true",
|
|
536
|
-
}
|
|
537
|
-
raise ValueError(f"unsupported OpenClaw security profile: {security_profile}")
|
|
538
|
-
|
|
539
|
-
|
|
540
422
|
def _strip_provider_prefix(provider_id: str, model_id: str) -> str:
|
|
541
423
|
provider = str(provider_id or "").strip()
|
|
542
424
|
model = str(model_id or "").strip()
|
|
@@ -739,322 +621,6 @@ def _filter_openclaw_provider_catalog(
|
|
|
739
621
|
return selected
|
|
740
622
|
|
|
741
623
|
|
|
742
|
-
def _build_openclaw_env_vars(
|
|
743
|
-
*,
|
|
744
|
-
model_base_url: Optional[str] = None,
|
|
745
|
-
model_api_key: Optional[str] = None,
|
|
746
|
-
default_model: Optional[str] = None,
|
|
747
|
-
model_provider_id: Optional[str] = None,
|
|
748
|
-
gateway_port: Optional[str] = None,
|
|
749
|
-
public_port: Optional[str] = None,
|
|
750
|
-
security_profile: Optional[str] = None,
|
|
751
|
-
) -> dict:
|
|
752
|
-
"""构建 OpenClaw 所需的环境变量,自动复用 OPENAI_* 环境变量"""
|
|
753
|
-
env = {}
|
|
754
|
-
default_provider_id = "ksyun"
|
|
755
|
-
default_model_api = "openai-completions"
|
|
756
|
-
default_model_base_url = "https://kspmas.ksyun.com/v1"
|
|
757
|
-
exec_profile_overrides = _resolve_exec_profile_overrides(security_profile)
|
|
758
|
-
|
|
759
|
-
# 模型配置:客户端只透传用户显式配置和可选的 API Key;
|
|
760
|
-
# 其余默认值交给镜像 bootstrap 兜底,避免创建请求把服务端默认行为短路掉。
|
|
761
|
-
openclaw_explicit_model = default_model or _resolve_env("OPENCLAW_DEFAULT_MODEL")
|
|
762
|
-
generic_model_preference = _resolve_env("OPENAI_MODEL_NAME", "MODEL_NAME", "LLM_MODEL")
|
|
763
|
-
model_preference = openclaw_explicit_model or generic_model_preference
|
|
764
|
-
explicit_base_url = model_base_url or _resolve_env(
|
|
765
|
-
"OPENCLAW_MODEL_BASE_URL", "OPENAI_BASE_URL", "OPENAI_API_BASE"
|
|
766
|
-
)
|
|
767
|
-
base_url = _resolve_model_base_url(explicit_base_url)
|
|
768
|
-
api_key = model_api_key or _resolve_env(
|
|
769
|
-
"OPENCLAW_MODEL_API_KEY", "OPENAI_API_KEY", "LLM_API_KEY", "MODEL_API_KEY"
|
|
770
|
-
)
|
|
771
|
-
model = model_preference or "glm-5.2"
|
|
772
|
-
explicit_provider_id = model_provider_id or _resolve_env("OPENCLAW_MODEL_PROVIDER_ID")
|
|
773
|
-
inferred_provider_id = explicit_provider_id
|
|
774
|
-
if not inferred_provider_id and model and "/" in model:
|
|
775
|
-
inferred_provider_id = model.split("/", 1)[0].strip()
|
|
776
|
-
provider_id = inferred_provider_id or default_provider_id
|
|
777
|
-
resolved_gateway_port = gateway_port or _resolve_env("OPENCLAW_GATEWAY_PORT", "PORT") or "8080"
|
|
778
|
-
resolved_public_port = public_port or _resolve_env("OPENCLAW_PUBLIC_PORT") or "80"
|
|
779
|
-
explicit_model_api = _resolve_env("OPENCLAW_MODEL_API")
|
|
780
|
-
model_api = explicit_model_api or default_model_api
|
|
781
|
-
trusted_proxy_user_header = (
|
|
782
|
-
(
|
|
783
|
-
_resolve_env(
|
|
784
|
-
"OPENCLAW_TRUSTED_PROXY_USER_HEADER",
|
|
785
|
-
"OPENCLAW_GATEWAY_TRUSTED_PROXY_USER_HEADER",
|
|
786
|
-
)
|
|
787
|
-
or DEFAULT_TRUSTED_PROXY_USER_HEADER
|
|
788
|
-
)
|
|
789
|
-
.strip()
|
|
790
|
-
.lower()
|
|
791
|
-
)
|
|
792
|
-
internal_trusted_proxy_user = (
|
|
793
|
-
_resolve_env("OPENCLAW_INTERNAL_TRUSTED_PROXY_USER") or "openclaw-backend"
|
|
794
|
-
)
|
|
795
|
-
internal_trusted_proxy_user_header = (
|
|
796
|
-
(
|
|
797
|
-
_resolve_env("OPENCLAW_INTERNAL_TRUSTED_PROXY_USER_HEADER")
|
|
798
|
-
or trusted_proxy_user_header
|
|
799
|
-
or DEFAULT_TRUSTED_PROXY_USER_HEADER
|
|
800
|
-
)
|
|
801
|
-
.strip()
|
|
802
|
-
.lower()
|
|
803
|
-
)
|
|
804
|
-
trusted_proxies = _normalize_csv_list(
|
|
805
|
-
_resolve_env("OPENCLAW_TRUSTED_PROXIES") or "",
|
|
806
|
-
default_items=DEFAULT_TRUSTED_PROXY_CIDRS,
|
|
807
|
-
)
|
|
808
|
-
browser_enabled = _resolve_env("OPENCLAW_BROWSER_ENABLED")
|
|
809
|
-
browser_no_sandbox = _resolve_env("OPENCLAW_BROWSER_NO_SANDBOX") or "true"
|
|
810
|
-
browser_headless = _resolve_env("OPENCLAW_BROWSER_HEADLESS") or "true"
|
|
811
|
-
browser_executable = _resolve_env(
|
|
812
|
-
"OPENCLAW_BROWSER_EXECUTABLE_PATH", "OPENCLAW_BROWSER_EXECUTABLE"
|
|
813
|
-
)
|
|
814
|
-
ui_locale = _normalize_ui_locale(_resolve_env("OPENCLAW_UI_LOCALE", "LANG", "LC_ALL"))
|
|
815
|
-
exec_strict_mode_raw = (
|
|
816
|
-
exec_profile_overrides.get("OPENCLAW_EXEC_STRICT_MODE")
|
|
817
|
-
or _resolve_env("OPENCLAW_EXEC_STRICT_MODE", "OPENCLAW_EXEC_SAFE_MODE")
|
|
818
|
-
or "false"
|
|
819
|
-
)
|
|
820
|
-
exec_strict_mode = _is_truthy(exec_strict_mode_raw)
|
|
821
|
-
|
|
822
|
-
exec_host = (
|
|
823
|
-
exec_profile_overrides.get("OPENCLAW_EXEC_HOST")
|
|
824
|
-
or _resolve_env("OPENCLAW_EXEC_HOST")
|
|
825
|
-
or "gateway"
|
|
826
|
-
)
|
|
827
|
-
exec_security = (
|
|
828
|
-
exec_profile_overrides.get("OPENCLAW_EXEC_SECURITY")
|
|
829
|
-
or _resolve_env("OPENCLAW_EXEC_SECURITY")
|
|
830
|
-
or ("allowlist" if exec_strict_mode else "full")
|
|
831
|
-
)
|
|
832
|
-
exec_ask = (
|
|
833
|
-
exec_profile_overrides.get("OPENCLAW_EXEC_ASK")
|
|
834
|
-
or _resolve_env("OPENCLAW_EXEC_ASK")
|
|
835
|
-
or "off"
|
|
836
|
-
)
|
|
837
|
-
exec_ask_fallback = (
|
|
838
|
-
exec_profile_overrides.get("OPENCLAW_EXEC_ASK_FALLBACK")
|
|
839
|
-
or _resolve_env("OPENCLAW_EXEC_ASK_FALLBACK")
|
|
840
|
-
or ("allowlist" if exec_strict_mode else "full")
|
|
841
|
-
)
|
|
842
|
-
exec_auto_allow_skills = (
|
|
843
|
-
exec_profile_overrides.get("OPENCLAW_EXEC_AUTO_ALLOW_SKILLS")
|
|
844
|
-
or _resolve_env("OPENCLAW_EXEC_AUTO_ALLOW_SKILLS")
|
|
845
|
-
or "false"
|
|
846
|
-
)
|
|
847
|
-
elevated_enabled = (
|
|
848
|
-
exec_profile_overrides.get("OPENCLAW_ELEVATED_ENABLED")
|
|
849
|
-
or _resolve_env("OPENCLAW_ELEVATED_ENABLED")
|
|
850
|
-
or "false"
|
|
851
|
-
)
|
|
852
|
-
exec_default_allowlist_enabled = (
|
|
853
|
-
exec_profile_overrides.get("OPENCLAW_EXEC_DEFAULT_ALLOWLIST_ENABLED")
|
|
854
|
-
or _resolve_env("OPENCLAW_EXEC_DEFAULT_ALLOWLIST_ENABLED")
|
|
855
|
-
or ("true" if exec_strict_mode else "false")
|
|
856
|
-
)
|
|
857
|
-
exec_allowlist = _resolve_env("OPENCLAW_EXEC_ALLOWLIST")
|
|
858
|
-
fs_workspace_only = (
|
|
859
|
-
exec_profile_overrides.get("OPENCLAW_FS_WORKSPACE_ONLY")
|
|
860
|
-
or _resolve_env("OPENCLAW_FS_WORKSPACE_ONLY")
|
|
861
|
-
or "false"
|
|
862
|
-
)
|
|
863
|
-
model_api_key_secret_source = _resolve_env("OPENCLAW_MODEL_API_KEY_SECRET_SOURCE") or "file"
|
|
864
|
-
model_api_key_secret_file_path = _resolve_env("OPENCLAW_MODEL_API_KEY_SECRET_FILE_PATH")
|
|
865
|
-
gateway_auth_mode = _resolve_env("OPENCLAW_GATEWAY_AUTH_MODE")
|
|
866
|
-
gateway_token = _resolve_env("OPENCLAW_GATEWAY_TOKEN")
|
|
867
|
-
gateway_password = _resolve_env("OPENCLAW_GATEWAY_PASSWORD")
|
|
868
|
-
|
|
869
|
-
env["OPENCLAW_GATEWAY_BIND"] = "lan"
|
|
870
|
-
if gateway_auth_mode:
|
|
871
|
-
env["OPENCLAW_GATEWAY_AUTH_MODE"] = gateway_auth_mode
|
|
872
|
-
env["OPENCLAW_TRUSTED_PROXY_USER_HEADER"] = (
|
|
873
|
-
trusted_proxy_user_header or DEFAULT_TRUSTED_PROXY_USER_HEADER
|
|
874
|
-
)
|
|
875
|
-
env["OPENCLAW_INTERNAL_TRUSTED_PROXY_USER"] = internal_trusted_proxy_user
|
|
876
|
-
env["OPENCLAW_INTERNAL_TRUSTED_PROXY_USER_HEADER"] = (
|
|
877
|
-
internal_trusted_proxy_user_header
|
|
878
|
-
or trusted_proxy_user_header
|
|
879
|
-
or DEFAULT_TRUSTED_PROXY_USER_HEADER
|
|
880
|
-
)
|
|
881
|
-
env["OPENCLAW_TRUSTED_PROXIES"] = trusted_proxies
|
|
882
|
-
env["OPENCLAW_GATEWAY_PORT"] = str(resolved_gateway_port)
|
|
883
|
-
env["OPENCLAW_PUBLIC_PORT"] = str(resolved_public_port)
|
|
884
|
-
if browser_enabled:
|
|
885
|
-
env["OPENCLAW_BROWSER_ENABLED"] = browser_enabled
|
|
886
|
-
env["OPENCLAW_BROWSER_NO_SANDBOX"] = browser_no_sandbox
|
|
887
|
-
env["OPENCLAW_BROWSER_HEADLESS"] = browser_headless
|
|
888
|
-
if browser_executable:
|
|
889
|
-
env["OPENCLAW_BROWSER_EXECUTABLE_PATH"] = browser_executable
|
|
890
|
-
env["OPENCLAW_UI_LOCALE"] = ui_locale
|
|
891
|
-
env["OPENCLAW_EXEC_HOST"] = exec_host
|
|
892
|
-
env["OPENCLAW_EXEC_STRICT_MODE"] = "true" if exec_strict_mode else "false"
|
|
893
|
-
env["OPENCLAW_EXEC_UNSAFE_MODE"] = "false" if exec_strict_mode else "true"
|
|
894
|
-
env["OPENCLAW_EXEC_SECURITY"] = exec_security
|
|
895
|
-
env["OPENCLAW_EXEC_ASK"] = exec_ask
|
|
896
|
-
env["OPENCLAW_EXEC_ASK_FALLBACK"] = exec_ask_fallback
|
|
897
|
-
env["OPENCLAW_EXEC_AUTO_ALLOW_SKILLS"] = exec_auto_allow_skills
|
|
898
|
-
env["OPENCLAW_ELEVATED_ENABLED"] = elevated_enabled
|
|
899
|
-
env["OPENCLAW_EXEC_DEFAULT_ALLOWLIST_ENABLED"] = exec_default_allowlist_enabled
|
|
900
|
-
env["OPENCLAW_FS_WORKSPACE_ONLY"] = fs_workspace_only
|
|
901
|
-
env["OPENCLAW_MODEL_API_KEY_SECRET_SOURCE"] = model_api_key_secret_source
|
|
902
|
-
if exec_allowlist:
|
|
903
|
-
env["OPENCLAW_EXEC_ALLOWLIST"] = exec_allowlist
|
|
904
|
-
if model_api_key_secret_file_path:
|
|
905
|
-
env["OPENCLAW_MODEL_API_KEY_SECRET_FILE_PATH"] = model_api_key_secret_file_path
|
|
906
|
-
|
|
907
|
-
if explicit_provider_id and provider_id != default_provider_id:
|
|
908
|
-
env["OPENCLAW_MODEL_PROVIDER_ID"] = provider_id
|
|
909
|
-
elif not explicit_provider_id and provider_id and provider_id != default_provider_id:
|
|
910
|
-
env["OPENCLAW_MODEL_PROVIDER_ID"] = provider_id
|
|
911
|
-
if explicit_model_api and model_api != default_model_api:
|
|
912
|
-
env["OPENCLAW_MODEL_API"] = model_api
|
|
913
|
-
if explicit_base_url and base_url and base_url != default_model_base_url:
|
|
914
|
-
env["OPENCLAW_MODEL_BASE_URL"] = base_url
|
|
915
|
-
if api_key:
|
|
916
|
-
env["OPENCLAW_MODEL_API_KEY"] = api_key
|
|
917
|
-
normalized_model = model.strip() if model else None
|
|
918
|
-
catalog_model_id = None
|
|
919
|
-
resolved_model = None
|
|
920
|
-
if normalized_model:
|
|
921
|
-
if "/" in normalized_model:
|
|
922
|
-
_, catalog_model_id = normalized_model.split("/", 1)
|
|
923
|
-
resolved_model = normalized_model
|
|
924
|
-
else:
|
|
925
|
-
resolved_model = (
|
|
926
|
-
f"{provider_id}/{normalized_model}" if provider_id else normalized_model
|
|
927
|
-
)
|
|
928
|
-
if openclaw_explicit_model:
|
|
929
|
-
env["OPENCLAW_DEFAULT_MODEL"] = resolved_model
|
|
930
|
-
elif generic_model_preference:
|
|
931
|
-
env["OPENAI_MODEL_NAME"] = resolved_model
|
|
932
|
-
|
|
933
|
-
# 额外的可选配置
|
|
934
|
-
catalog = _resolve_env("OPENCLAW_MODEL_CATALOG_JSON")
|
|
935
|
-
if catalog:
|
|
936
|
-
env["OPENCLAW_MODEL_CATALOG_JSON"] = catalog
|
|
937
|
-
openclaw_model_allowlist = _resolve_env("OPENCLAW_MODEL_ALLOWLIST")
|
|
938
|
-
agentengine_model_allowlist = _resolve_env("AGENTENGINE_MODEL_ALLOWLIST")
|
|
939
|
-
if openclaw_model_allowlist:
|
|
940
|
-
env["OPENCLAW_MODEL_ALLOWLIST"] = openclaw_model_allowlist
|
|
941
|
-
elif agentengine_model_allowlist:
|
|
942
|
-
env["AGENTENGINE_MODEL_ALLOWLIST"] = agentengine_model_allowlist
|
|
943
|
-
origins = _resolve_env("OPENCLAW_ALLOWED_ORIGINS")
|
|
944
|
-
if origins:
|
|
945
|
-
env["OPENCLAW_ALLOWED_ORIGINS"] = _normalize_allowed_origins(origins)
|
|
946
|
-
else:
|
|
947
|
-
# 统一输出 JSON 数组字符串,兼容旧版 bootstrap(仅支持 JSON.parse)。
|
|
948
|
-
env["OPENCLAW_ALLOWED_ORIGINS"] = json.dumps(["*"])
|
|
949
|
-
allow_insecure_auth = _resolve_env("OPENCLAW_ALLOW_INSECURE_AUTH")
|
|
950
|
-
env["OPENCLAW_ALLOW_INSECURE_AUTH"] = allow_insecure_auth if allow_insecure_auth else "true"
|
|
951
|
-
disable_device_auth = _resolve_env("OPENCLAW_DISABLE_DEVICE_AUTH")
|
|
952
|
-
env["OPENCLAW_DISABLE_DEVICE_AUTH"] = disable_device_auth if disable_device_auth else "true"
|
|
953
|
-
if gateway_token:
|
|
954
|
-
env["OPENCLAW_GATEWAY_TOKEN"] = gateway_token
|
|
955
|
-
if gateway_password:
|
|
956
|
-
env["OPENCLAW_GATEWAY_PASSWORD"] = gateway_password
|
|
957
|
-
for passthrough_key in [
|
|
958
|
-
"OPENCLAW_CHANNEL_BOOTSTRAP_JSON",
|
|
959
|
-
"OPENCLAW_BROWSER_SSRF_POLICY_JSON",
|
|
960
|
-
"OPENCLAW_WEB_FETCH_ENABLED",
|
|
961
|
-
"OPENCLAW_WEB_SEARCH_PROVIDER",
|
|
962
|
-
"OPENCLAW_WEB_SEARCH_BASE_URL",
|
|
963
|
-
"OPENCLAW_WEB_SEARCH_MODEL",
|
|
964
|
-
"OPENCLAW_WEB_SEARCH_API_KEY",
|
|
965
|
-
"OPENCLAW_WEB_SEARCH_API_KEY_SECRET_SOURCE",
|
|
966
|
-
"OPENCLAW_WEB_SEARCH_API_KEY_SECRET_PROVIDER",
|
|
967
|
-
"OPENCLAW_WEB_SEARCH_API_KEY_SECRET_ID",
|
|
968
|
-
]:
|
|
969
|
-
passthrough_value = _resolve_env(passthrough_key)
|
|
970
|
-
if passthrough_value:
|
|
971
|
-
env[passthrough_key] = passthrough_value
|
|
972
|
-
|
|
973
|
-
env = _normalize_openclaw_gateway_auth_env(env)
|
|
974
|
-
return build_runtime_model_policy_env(env, runtime="openclaw")
|
|
975
|
-
|
|
976
|
-
|
|
977
|
-
def _normalize_allowed_origins(raw: str) -> str:
|
|
978
|
-
"""标准化 OPENCLAW_ALLOWED_ORIGINS,统一输出 JSON 数组字符串。"""
|
|
979
|
-
text = (raw or "").strip()
|
|
980
|
-
if not text:
|
|
981
|
-
return ""
|
|
982
|
-
|
|
983
|
-
origins = []
|
|
984
|
-
try:
|
|
985
|
-
parsed = json.loads(text)
|
|
986
|
-
if isinstance(parsed, list):
|
|
987
|
-
origins = [str(x).strip() for x in parsed if str(x).strip()]
|
|
988
|
-
except Exception:
|
|
989
|
-
# Backward compatible: 支持逗号/分号/空白分隔字符串。
|
|
990
|
-
parts = [p.strip() for p in text.replace(";", ",").replace(" ", ",").split(",")]
|
|
991
|
-
origins = [p.strip() for p in parts if p.strip()]
|
|
992
|
-
|
|
993
|
-
if not origins:
|
|
994
|
-
origins = [text]
|
|
995
|
-
|
|
996
|
-
deduped = list(dict.fromkeys(origins))
|
|
997
|
-
return json.dumps(deduped, ensure_ascii=False)
|
|
998
|
-
|
|
999
|
-
|
|
1000
|
-
def _normalize_csv_list(raw: str, *, default_items: Optional[list[str]] = None) -> str:
|
|
1001
|
-
"""标准化字符串列表为逗号分隔格式。"""
|
|
1002
|
-
text = (raw or "").strip()
|
|
1003
|
-
items: list[str] = []
|
|
1004
|
-
if text:
|
|
1005
|
-
try:
|
|
1006
|
-
parsed = json.loads(text)
|
|
1007
|
-
if isinstance(parsed, list):
|
|
1008
|
-
items = [str(x).strip() for x in parsed if str(x).strip()]
|
|
1009
|
-
except Exception:
|
|
1010
|
-
parts = [p.strip() for p in text.replace(";", ",").replace(" ", ",").split(",")]
|
|
1011
|
-
items = [p for p in parts if p]
|
|
1012
|
-
|
|
1013
|
-
if not items:
|
|
1014
|
-
items = [str(x).strip() for x in (default_items or []) if str(x).strip()]
|
|
1015
|
-
|
|
1016
|
-
return ",".join(list(dict.fromkeys(items)))
|
|
1017
|
-
|
|
1018
|
-
|
|
1019
|
-
def _normalize_openclaw_gateway_auth_env(env: dict[str, str]) -> dict[str, str]:
|
|
1020
|
-
"""标准化 OpenClaw gateway 鉴权模式与共享密钥配置。"""
|
|
1021
|
-
normalized_env = dict(env or {})
|
|
1022
|
-
raw_mode = str(normalized_env.get("OPENCLAW_GATEWAY_AUTH_MODE") or "").strip().lower()
|
|
1023
|
-
raw_token = str(normalized_env.get("OPENCLAW_GATEWAY_TOKEN") or "").strip()
|
|
1024
|
-
raw_password = str(normalized_env.get("OPENCLAW_GATEWAY_PASSWORD") or "").strip()
|
|
1025
|
-
|
|
1026
|
-
if raw_mode and raw_mode not in {"trusted-proxy", "token", "none"}:
|
|
1027
|
-
raise ValueError("OPENCLAW_GATEWAY_AUTH_MODE 仅支持 trusted-proxy、token 或 none")
|
|
1028
|
-
|
|
1029
|
-
auth_mode = raw_mode or ("token" if raw_token or raw_password else "trusted-proxy")
|
|
1030
|
-
if auth_mode == "token":
|
|
1031
|
-
if raw_token and raw_password and raw_token != raw_password:
|
|
1032
|
-
raise ValueError(
|
|
1033
|
-
"OPENCLAW_GATEWAY_TOKEN 与 OPENCLAW_GATEWAY_PASSWORD 同时提供时必须一致"
|
|
1034
|
-
)
|
|
1035
|
-
shared_secret = raw_token or raw_password
|
|
1036
|
-
if not shared_secret:
|
|
1037
|
-
raise ValueError(
|
|
1038
|
-
"OPENCLAW_GATEWAY_AUTH_MODE=token 时必须提供 "
|
|
1039
|
-
"OPENCLAW_GATEWAY_TOKEN 或 OPENCLAW_GATEWAY_PASSWORD"
|
|
1040
|
-
)
|
|
1041
|
-
normalized_env["OPENCLAW_GATEWAY_AUTH_MODE"] = "token"
|
|
1042
|
-
normalized_env["OPENCLAW_GATEWAY_TOKEN"] = shared_secret
|
|
1043
|
-
normalized_env["OPENCLAW_GATEWAY_PASSWORD"] = shared_secret
|
|
1044
|
-
return normalized_env
|
|
1045
|
-
|
|
1046
|
-
if raw_token or raw_password:
|
|
1047
|
-
raise ValueError(
|
|
1048
|
-
"仅在 OPENCLAW_GATEWAY_AUTH_MODE=token 时支持 "
|
|
1049
|
-
"OPENCLAW_GATEWAY_TOKEN 或 OPENCLAW_GATEWAY_PASSWORD"
|
|
1050
|
-
)
|
|
1051
|
-
|
|
1052
|
-
normalized_env["OPENCLAW_GATEWAY_AUTH_MODE"] = auth_mode
|
|
1053
|
-
normalized_env.pop("OPENCLAW_GATEWAY_TOKEN", None)
|
|
1054
|
-
normalized_env.pop("OPENCLAW_GATEWAY_PASSWORD", None)
|
|
1055
|
-
return normalized_env
|
|
1056
|
-
|
|
1057
|
-
|
|
1058
624
|
def _parse_extra_openclaw_env_pairs(items: tuple[str, ...] | list[str] | None) -> dict[str, str]:
|
|
1059
625
|
"""解析 deploy --env 传入的自定义环境变量,并对 gateway 鉴权模式做早期归一化。"""
|
|
1060
626
|
parsed = parse_env_pairs(items)
|
ksadk/cli/cmd_replay.py
CHANGED
|
@@ -17,8 +17,13 @@ import json
|
|
|
17
17
|
import click
|
|
18
18
|
|
|
19
19
|
from ksadk.cli.resource_common import CONTEXT_SETTINGS
|
|
20
|
-
from ksadk.events.
|
|
20
|
+
from ksadk.events.reducer import StreamReducer
|
|
21
21
|
from ksadk.events.store import RuntimeEventStore
|
|
22
|
+
from ksadk.events.v1_compat import (
|
|
23
|
+
RuntimeEventV1Parser,
|
|
24
|
+
RuntimeEventV1ProjectionContext,
|
|
25
|
+
project_to_v1,
|
|
26
|
+
)
|
|
22
27
|
|
|
23
28
|
_HELP = dict(help_option_names=["-h", "--help"])
|
|
24
29
|
|
|
@@ -43,9 +48,28 @@ async def _run(session_id: str, *, after_seq_id: int, before_seq_id: int | None,
|
|
|
43
48
|
from ksadk.sessions import resolve_session_service
|
|
44
49
|
|
|
45
50
|
store = RuntimeEventStore(resolve_session_service())
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
)
|
|
51
|
+
service = resolve_session_service()
|
|
52
|
+
session = await service.get_session(session_id)
|
|
53
|
+
events = await store.list(session_id)
|
|
54
|
+
parser = RuntimeEventV1Parser()
|
|
55
|
+
reducers: dict[str, StreamReducer] = {}
|
|
56
|
+
for event in events:
|
|
57
|
+
reducer = reducers.get(event.run_id)
|
|
58
|
+
if reducer is not None and reducer.snapshot().status in {"completed", "failed", "canceled"}:
|
|
59
|
+
reducer = None
|
|
60
|
+
if reducer is None:
|
|
61
|
+
reducer = StreamReducer()
|
|
62
|
+
reducers[event.run_id] = reducer
|
|
63
|
+
reducer.apply(event)
|
|
64
|
+
projection = reducer.snapshot()
|
|
65
|
+
context = RuntimeEventV1ProjectionContext(
|
|
66
|
+
agent_id=session.agent_id if session else "",
|
|
67
|
+
user_id=session.user_id if session else "",
|
|
68
|
+
session_id=session_id,
|
|
69
|
+
projection=projection,
|
|
70
|
+
)
|
|
71
|
+
for v1_event in project_to_v1(event, mode="identity_replace", context=context):
|
|
72
|
+
parser.feed(v1_event)
|
|
49
73
|
transcript = parser.transcript()
|
|
50
74
|
if fmt == "json":
|
|
51
75
|
click.echo(json.dumps(transcript, ensure_ascii=False, sort_keys=True))
|
ksadk/cli/cmd_studio.py
CHANGED
|
@@ -2,6 +2,7 @@
|
|
|
2
2
|
|
|
3
3
|
from __future__ import annotations
|
|
4
4
|
|
|
5
|
+
import logging
|
|
5
6
|
import os
|
|
6
7
|
import secrets
|
|
7
8
|
import webbrowser
|
|
@@ -12,14 +13,67 @@ import uvicorn
|
|
|
12
13
|
|
|
13
14
|
from ksadk.cli.env_options import load_env_file
|
|
14
15
|
from ksadk.cli.ui import print_info, print_kv, print_success, print_title
|
|
16
|
+
|
|
17
|
+
# veadk 风格:日志行带模块名与行号(filename:lineno),本地排障时能直接定位代码。
|
|
18
|
+
_LOG_FORMAT = "%(asctime)s %(levelname)s %(name)s %(filename)s:%(lineno)d %(message)s"
|
|
19
|
+
|
|
20
|
+
_STUDIO_LOG_CONFIG = {
|
|
21
|
+
"version": 1,
|
|
22
|
+
"disable_existing_loggers": False,
|
|
23
|
+
"formatters": {
|
|
24
|
+
"default": {"format": _LOG_FORMAT},
|
|
25
|
+
"access": {"format": _LOG_FORMAT},
|
|
26
|
+
},
|
|
27
|
+
"handlers": {
|
|
28
|
+
"default": {
|
|
29
|
+
"class": "logging.StreamHandler",
|
|
30
|
+
"formatter": "default",
|
|
31
|
+
"stream": "ext://sys.stderr",
|
|
32
|
+
},
|
|
33
|
+
"access": {
|
|
34
|
+
"class": "logging.StreamHandler",
|
|
35
|
+
"formatter": "access",
|
|
36
|
+
"stream": "ext://sys.stdout",
|
|
37
|
+
},
|
|
38
|
+
},
|
|
39
|
+
"loggers": {
|
|
40
|
+
"uvicorn": {"handlers": ["default"], "level": "INFO", "propagate": False},
|
|
41
|
+
"uvicorn.error": {"level": "INFO"},
|
|
42
|
+
"uvicorn.access": {"handlers": ["access"], "level": "INFO", "propagate": False},
|
|
43
|
+
},
|
|
44
|
+
"root": {"handlers": ["default"], "level": "INFO"},
|
|
45
|
+
}
|
|
46
|
+
|
|
15
47
|
from ksadk.studio.api import create_studio_app
|
|
16
48
|
from ksadk.studio.service import StudioService
|
|
17
49
|
|
|
50
|
+
# 模型环境变量白名单。OPENAI_BASE_URL 与 OPENAI_API_BASE 互为别名,两者都接受;
|
|
51
|
+
# 加载时做别名归一(见 studio()),运行时统一 OPENAI_BASE_URL 优先(与 cmd_config/cmd_model
|
|
52
|
+
# /api.py 一致,方案 §2.4 第 5 点)。
|
|
18
53
|
_MODEL_ENV_KEYS = (
|
|
54
|
+
"OPENAI_BASE_URL",
|
|
19
55
|
"OPENAI_API_BASE",
|
|
20
56
|
"OPENAI_API_KEY",
|
|
21
57
|
"OPENAI_MODEL_NAME",
|
|
22
58
|
)
|
|
59
|
+
# Cloud-control credentials are intentionally process-only as well. Studio
|
|
60
|
+
# needs them to use the Server Action API for a deployed Agent, but they must
|
|
61
|
+
# never become browser settings, workspace files, or runtime environment.
|
|
62
|
+
_CLOUD_CONTROL_ENV_KEYS = (
|
|
63
|
+
"KSYUN_ACCESS_KEY",
|
|
64
|
+
"KSYUN_SECRET_KEY",
|
|
65
|
+
"KSYUN_REGION",
|
|
66
|
+
"AGENTENGINE_REGION",
|
|
67
|
+
"AGENTENGINE_SERVER_URL",
|
|
68
|
+
"AGENTENGINE_STREAM_SERVER_URL",
|
|
69
|
+
"AGENTENGINE_SIGN_SERVICE",
|
|
70
|
+
"KS3_BUCKET",
|
|
71
|
+
"KS3_ACCESS_KEY",
|
|
72
|
+
"KS3_SECRET_KEY",
|
|
73
|
+
)
|
|
74
|
+
_STUDIO_ENV_FILE_KEYS = (*_MODEL_ENV_KEYS, *_CLOUD_CONTROL_ENV_KEYS)
|
|
75
|
+
# 别名归一:两者任一有值时,把另一个也设上,保证下游无论读哪个都命中。
|
|
76
|
+
_MODEL_BASE_URL_ALIASES = ("OPENAI_BASE_URL", "OPENAI_API_BASE")
|
|
23
77
|
|
|
24
78
|
|
|
25
79
|
@click.command(context_settings=dict(help_option_names=["-h", "--help"]))
|
|
@@ -29,7 +83,10 @@ _MODEL_ENV_KEYS = (
|
|
|
29
83
|
@click.option(
|
|
30
84
|
"--env-file",
|
|
31
85
|
type=click.Path(exists=True, dir_okay=False),
|
|
32
|
-
help=
|
|
86
|
+
help=(
|
|
87
|
+
"本地模型与云端控制环境文件;只读取允许的 OPENAI/KSYUN/KS3 "
|
|
88
|
+
"字段,且仅保留在 Studio 进程"
|
|
89
|
+
),
|
|
33
90
|
)
|
|
34
91
|
@click.option(
|
|
35
92
|
"--codex-proxy",
|
|
@@ -52,7 +109,7 @@ def studio(
|
|
|
52
109
|
"""
|
|
53
110
|
|
|
54
111
|
root = Path(workspace).expanduser().resolve()
|
|
55
|
-
managed_keys = (*
|
|
112
|
+
managed_keys = (*_STUDIO_ENV_FILE_KEYS, "KSADK_CODEX_USE_PROXY")
|
|
56
113
|
previous = {key: os.environ.get(key) for key in managed_keys}
|
|
57
114
|
previously_present = {key for key in managed_keys if key in os.environ}
|
|
58
115
|
try:
|
|
@@ -61,14 +118,42 @@ def studio(
|
|
|
61
118
|
values = load_env_file(env_file)
|
|
62
119
|
except ValueError as exc:
|
|
63
120
|
raise click.ClickException(str(exc)) from exc
|
|
64
|
-
|
|
121
|
+
loaded_models = 0
|
|
122
|
+
loaded_cloud_control = 0
|
|
65
123
|
for key, value in values.items():
|
|
66
|
-
if key not in
|
|
124
|
+
if key not in _STUDIO_ENV_FILE_KEYS or not value:
|
|
67
125
|
continue
|
|
68
|
-
|
|
69
|
-
|
|
126
|
+
if key in _MODEL_ENV_KEYS:
|
|
127
|
+
loaded_models += 1
|
|
128
|
+
else:
|
|
129
|
+
loaded_cloud_control += 1
|
|
130
|
+
# An explicit --env-file is the operator's selected cloud
|
|
131
|
+
# identity. Do not silently reuse inherited AK/SK from the
|
|
132
|
+
# shell, which can point Studio at another tenant. Model
|
|
133
|
+
# values keep their historical shell-first precedence.
|
|
134
|
+
if key in _CLOUD_CONTROL_ENV_KEYS or key not in os.environ:
|
|
70
135
|
os.environ[key] = value
|
|
71
|
-
|
|
136
|
+
# 别名归一(方案 §2.4 第 5 点):OPENAI_BASE_URL 与 OPENAI_API_BASE 互为别名。
|
|
137
|
+
# 加载后任一有值则把另一个也设上,保证下游无论读哪个都命中;OPENAI_BASE_URL 优先。
|
|
138
|
+
resolved_base_url = os.environ.get("OPENAI_BASE_URL") or os.environ.get(
|
|
139
|
+
"OPENAI_API_BASE"
|
|
140
|
+
)
|
|
141
|
+
if resolved_base_url:
|
|
142
|
+
os.environ["OPENAI_BASE_URL"] = resolved_base_url
|
|
143
|
+
os.environ["OPENAI_API_BASE"] = resolved_base_url
|
|
144
|
+
# base_url 至少算一次,避免显示 0/4 误导。
|
|
145
|
+
loaded_models = max(loaded_models, 2)
|
|
146
|
+
print_kv(
|
|
147
|
+
"模型环境",
|
|
148
|
+
f"已安全加载 {loaded_models}/{len(_MODEL_ENV_KEYS)} 个字段",
|
|
149
|
+
)
|
|
150
|
+
if loaded_cloud_control:
|
|
151
|
+
print_kv(
|
|
152
|
+
"云端控制",
|
|
153
|
+
"已安全加载 "
|
|
154
|
+
f"{loaded_cloud_control}/{len(_CLOUD_CONTROL_ENV_KEYS)} 个字段"
|
|
155
|
+
"(仅本地进程)",
|
|
156
|
+
)
|
|
72
157
|
if codex_proxy == "forced":
|
|
73
158
|
os.environ["KSADK_CODEX_USE_PROXY"] = "1"
|
|
74
159
|
elif codex_proxy == "direct":
|
|
@@ -95,12 +180,18 @@ def studio(
|
|
|
95
180
|
print_info("按 Ctrl+C 停止")
|
|
96
181
|
if not no_open:
|
|
97
182
|
webbrowser.open(launch_url)
|
|
183
|
+
# 业务日志(ksadk.*)走 root handler,同样带 filename:lineno。
|
|
184
|
+
logging.basicConfig(level=logging.INFO, format=_LOG_FORMAT)
|
|
98
185
|
uvicorn.run(
|
|
99
186
|
app,
|
|
100
187
|
host="127.0.0.1",
|
|
101
188
|
port=port,
|
|
102
189
|
log_level="info",
|
|
103
|
-
|
|
190
|
+
# Access logging stays enabled through the Studio log config while
|
|
191
|
+
# retaining filename/line-number context for both API and business
|
|
192
|
+
# logs. This preserves master's observability intent and the
|
|
193
|
+
# branch's richer diagnostic format.
|
|
194
|
+
log_config=_STUDIO_LOG_CONFIG,
|
|
104
195
|
)
|
|
105
196
|
finally:
|
|
106
197
|
for key in managed_keys:
|