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/builders/code_builder.py
CHANGED
|
@@ -9,6 +9,7 @@ Code Builder - zip 打包模式构建
|
|
|
9
9
|
|
|
10
10
|
import ast
|
|
11
11
|
import hashlib
|
|
12
|
+
import importlib.metadata as importlib_metadata
|
|
12
13
|
import json
|
|
13
14
|
import os
|
|
14
15
|
import re
|
|
@@ -19,8 +20,9 @@ import threading
|
|
|
19
20
|
import time
|
|
20
21
|
import zipfile
|
|
21
22
|
from concurrent.futures import ThreadPoolExecutor, as_completed
|
|
23
|
+
from datetime import datetime, timezone
|
|
22
24
|
from pathlib import Path
|
|
23
|
-
from typing import List, Optional, Set
|
|
25
|
+
from typing import Any, List, Optional, Set
|
|
24
26
|
from urllib.parse import urlparse
|
|
25
27
|
from urllib.request import Request, urlopen
|
|
26
28
|
|
|
@@ -39,6 +41,154 @@ from ksadk.builders.requirements_utils import (
|
|
|
39
41
|
parse_requirements_text,
|
|
40
42
|
)
|
|
41
43
|
|
|
44
|
+
BUILD_INFO_SCHEMA = "ksadk-build-info/v1"
|
|
45
|
+
BUILD_INFO_ARCNAME = "ksadk/BUILD-INFO.json"
|
|
46
|
+
|
|
47
|
+
|
|
48
|
+
def _sha256_file(path: Path) -> str:
|
|
49
|
+
digest = hashlib.sha256()
|
|
50
|
+
with open(path, "rb") as f:
|
|
51
|
+
for chunk in iter(lambda: f.read(1024 * 1024), b""):
|
|
52
|
+
digest.update(chunk)
|
|
53
|
+
return digest.hexdigest()
|
|
54
|
+
|
|
55
|
+
|
|
56
|
+
def _bundled_content_fingerprint(files: List[Any]) -> str:
|
|
57
|
+
"""对 (relative, file_path) 列表计算确定性内容指纹。
|
|
58
|
+
|
|
59
|
+
指纹只依赖相对路径与逐文件 sha256,同一来源目录重复打包结果一致,
|
|
60
|
+
可用于在线上快速判断 zip 里的源码快照是否与某次构建/提交一致。
|
|
61
|
+
"""
|
|
62
|
+
|
|
63
|
+
digest = hashlib.sha256()
|
|
64
|
+
digest.update(f"fingerprint:{BUILD_INFO_SCHEMA}\n".encode("utf-8"))
|
|
65
|
+
for relative, file_path in sorted(files, key=lambda item: item[0]):
|
|
66
|
+
digest.update(relative.encode("utf-8"))
|
|
67
|
+
digest.update(b"\0")
|
|
68
|
+
digest.update(_sha256_file(file_path).encode("ascii"))
|
|
69
|
+
digest.update(b"\n")
|
|
70
|
+
return digest.hexdigest()
|
|
71
|
+
|
|
72
|
+
|
|
73
|
+
def _git_provenance(start: Path) -> Optional[dict]:
|
|
74
|
+
"""返回 start 所在 git 仓库的提交信息;非 git 目录返回 None。"""
|
|
75
|
+
|
|
76
|
+
def _git(*args: str) -> Optional[str]:
|
|
77
|
+
try:
|
|
78
|
+
proc = subprocess.run(
|
|
79
|
+
["git", "-C", str(start), *args],
|
|
80
|
+
capture_output=True,
|
|
81
|
+
text=True,
|
|
82
|
+
timeout=10,
|
|
83
|
+
)
|
|
84
|
+
except Exception:
|
|
85
|
+
return None
|
|
86
|
+
if proc.returncode != 0:
|
|
87
|
+
return None
|
|
88
|
+
return proc.stdout.strip()
|
|
89
|
+
|
|
90
|
+
toplevel = _git("rev-parse", "--show-toplevel")
|
|
91
|
+
if not toplevel:
|
|
92
|
+
return None
|
|
93
|
+
commit = _git("rev-parse", "HEAD")
|
|
94
|
+
branch = _git("rev-parse", "--abbrev-ref", "HEAD")
|
|
95
|
+
status = _git("status", "--porcelain")
|
|
96
|
+
return {
|
|
97
|
+
"repo_root": toplevel,
|
|
98
|
+
"commit": commit,
|
|
99
|
+
"branch": branch or None,
|
|
100
|
+
"dirty": bool(status),
|
|
101
|
+
}
|
|
102
|
+
|
|
103
|
+
|
|
104
|
+
def _package_provenance(package_name: str, package_root: Path) -> dict:
|
|
105
|
+
"""采集被 vendored 包的安装来源:dist 元信息 / 本地路径 / git 提交。"""
|
|
106
|
+
|
|
107
|
+
info: dict[str, Any] = {
|
|
108
|
+
"source_dir": str(package_root),
|
|
109
|
+
"dist_version": None,
|
|
110
|
+
"installer": None,
|
|
111
|
+
"direct_url": None,
|
|
112
|
+
"source_type": "unknown",
|
|
113
|
+
"git": None,
|
|
114
|
+
}
|
|
115
|
+
try:
|
|
116
|
+
dist = importlib_metadata.distribution(package_name)
|
|
117
|
+
except Exception:
|
|
118
|
+
dist = None
|
|
119
|
+
if dist is not None:
|
|
120
|
+
info["dist_version"] = dist.version
|
|
121
|
+
installer = (dist.read_text("INSTALLER") or "").strip()
|
|
122
|
+
info["installer"] = installer or None
|
|
123
|
+
raw_direct_url = dist.read_text("direct_url.json")
|
|
124
|
+
if raw_direct_url:
|
|
125
|
+
try:
|
|
126
|
+
direct_url = json.loads(raw_direct_url)
|
|
127
|
+
except ValueError:
|
|
128
|
+
direct_url = None
|
|
129
|
+
if isinstance(direct_url, dict):
|
|
130
|
+
info["direct_url"] = direct_url.get("url")
|
|
131
|
+
url = str(direct_url.get("url") or "")
|
|
132
|
+
dir_info = direct_url.get("dir_info") or {}
|
|
133
|
+
archive_info = direct_url.get("archive_info") or {}
|
|
134
|
+
if url.startswith("file://"):
|
|
135
|
+
if dir_info.get("editable"):
|
|
136
|
+
info["source_type"] = "editable-install"
|
|
137
|
+
elif url.endswith(".whl"):
|
|
138
|
+
info["source_type"] = "local-wheel"
|
|
139
|
+
else:
|
|
140
|
+
info["source_type"] = "local-path"
|
|
141
|
+
elif archive_info:
|
|
142
|
+
info["source_type"] = "remote-dist"
|
|
143
|
+
if info["direct_url"] is None and info["dist_version"] is not None:
|
|
144
|
+
# pip 从 index 安装的常规 dist 通常不写 direct_url.json
|
|
145
|
+
info["source_type"] = "installed-dist"
|
|
146
|
+
if info["source_type"] in {"editable-install", "local-path", "unknown"}:
|
|
147
|
+
info["git"] = _git_provenance(package_root)
|
|
148
|
+
return info
|
|
149
|
+
|
|
150
|
+
|
|
151
|
+
def build_bundled_source_manifest(
|
|
152
|
+
package_roots: dict,
|
|
153
|
+
bundled_files: List[Any],
|
|
154
|
+
) -> dict:
|
|
155
|
+
"""生成随 zip 下发的 BUILD-INFO 内容。
|
|
156
|
+
|
|
157
|
+
- ``package_roots``: {package_name: 源码目录}
|
|
158
|
+
- ``bundled_files``: _iter_bundled_source_files() 的 (name, relative, path) 三元组
|
|
159
|
+
"""
|
|
160
|
+
|
|
161
|
+
grouped: dict[str, List[Any]] = {}
|
|
162
|
+
for package_name, relative, file_path in bundled_files:
|
|
163
|
+
grouped.setdefault(package_name, []).append((relative, file_path))
|
|
164
|
+
|
|
165
|
+
packages: dict[str, Any] = {}
|
|
166
|
+
for package_name, files in sorted(grouped.items()):
|
|
167
|
+
package_root = package_roots.get(package_name)
|
|
168
|
+
provenance = (
|
|
169
|
+
_package_provenance(package_name, package_root)
|
|
170
|
+
if package_root is not None
|
|
171
|
+
else {"source_dir": None, "source_type": "unknown"}
|
|
172
|
+
)
|
|
173
|
+
packages[package_name] = {
|
|
174
|
+
**provenance,
|
|
175
|
+
"file_count": len(files),
|
|
176
|
+
"content_fingerprint_sha256": _bundled_content_fingerprint(files),
|
|
177
|
+
}
|
|
178
|
+
|
|
179
|
+
return {
|
|
180
|
+
"schema": BUILD_INFO_SCHEMA,
|
|
181
|
+
"built_at": datetime.now(timezone.utc).isoformat(timespec="seconds"),
|
|
182
|
+
"packages": packages,
|
|
183
|
+
}
|
|
184
|
+
|
|
185
|
+
|
|
186
|
+
_NONRELEASE_SOURCE_TYPES = {"editable-install", "local-path", "local-wheel", "unknown"}
|
|
187
|
+
|
|
188
|
+
|
|
189
|
+
def _is_release_like_source(provenance: dict) -> bool:
|
|
190
|
+
return provenance.get("source_type") in {"installed-dist", "remote-dist"}
|
|
191
|
+
|
|
42
192
|
|
|
43
193
|
class CodeBuilder(BaseBuilder):
|
|
44
194
|
"""Code 模式构建器 - 打包 zip + 依赖"""
|
|
@@ -229,6 +379,7 @@ class CodeBuilder(BaseBuilder):
|
|
|
229
379
|
self._save_input_fingerprint(zip_path, detection_result)
|
|
230
380
|
zip_size = zip_path.stat().st_size / (1024 * 1024)
|
|
231
381
|
click.secho(f"\n✅ 使用已有构建: {zip_path.name} ({zip_size:.2f} MB)", fg="green")
|
|
382
|
+
self._emit_bundled_ksadk_identity(zip_path)
|
|
232
383
|
click.echo(
|
|
233
384
|
" (如需只重新打包当前代码/runtime,请使用 --repackage;"
|
|
234
385
|
"如需重装依赖,请使用 --no-cache)"
|
|
@@ -275,6 +426,7 @@ class CodeBuilder(BaseBuilder):
|
|
|
275
426
|
package_started_at = time.monotonic()
|
|
276
427
|
self._package_zip(zip_path, detection_result)
|
|
277
428
|
click.echo(f" ✓ 打包耗时: {self._format_elapsed(package_started_at)}")
|
|
429
|
+
self._emit_bundled_ksadk_identity(zip_path)
|
|
278
430
|
self._save_input_fingerprint(zip_path, detection_result)
|
|
279
431
|
|
|
280
432
|
zip_size = zip_path.stat().st_size
|
|
@@ -657,15 +809,18 @@ class CodeBuilder(BaseBuilder):
|
|
|
657
809
|
"file_digests": file_digests,
|
|
658
810
|
}
|
|
659
811
|
|
|
660
|
-
def
|
|
812
|
+
def _bundled_source_package_roots(self) -> dict:
|
|
661
813
|
import ksadk
|
|
662
814
|
import ksadk_runtime_common
|
|
663
815
|
|
|
664
|
-
|
|
665
|
-
|
|
666
|
-
"ksadk_runtime_common",
|
|
667
|
-
|
|
668
|
-
|
|
816
|
+
return {
|
|
817
|
+
"ksadk": Path(ksadk.__file__).resolve().parent,
|
|
818
|
+
"ksadk_runtime_common": Path(ksadk_runtime_common.__file__).resolve().parent,
|
|
819
|
+
}
|
|
820
|
+
|
|
821
|
+
def _iter_bundled_source_files(self):
|
|
822
|
+
for package_name, package_root in self._bundled_source_package_roots().items():
|
|
823
|
+
yield from self._iter_bundled_source_package(package_name, package_root)
|
|
669
824
|
|
|
670
825
|
def _iter_bundled_source_package(self, package_name: str, package_root: Path):
|
|
671
826
|
for file_path in sorted(package_root.rglob("*")):
|
|
@@ -685,6 +840,32 @@ class CodeBuilder(BaseBuilder):
|
|
|
685
840
|
parts = relative_path.parts
|
|
686
841
|
return len(parts) >= 2 and parts[0] == "server" and parts[1] == "web-ui"
|
|
687
842
|
|
|
843
|
+
def _warn_on_nonrelease_bundled_source(self, build_info: dict) -> None:
|
|
844
|
+
"""vendored ksadk 源码来自本地路径/editable/来源不明时给出醒目提示。
|
|
845
|
+
|
|
846
|
+
历史事故:打包机 environment 里的 ksadk 是正式 release 之前的 dev 快照,
|
|
847
|
+
vendored 进 zip 上线后 runtime 行为与正式版不一致且无从追溯。
|
|
848
|
+
"""
|
|
849
|
+
|
|
850
|
+
for package_name, package_info in (build_info.get("packages") or {}).items():
|
|
851
|
+
if _is_release_like_source(package_info):
|
|
852
|
+
continue
|
|
853
|
+
source_desc = (
|
|
854
|
+
f"type={package_info.get('source_type')} " f"dir={package_info.get('source_dir')}"
|
|
855
|
+
)
|
|
856
|
+
git_info = package_info.get("git") or {}
|
|
857
|
+
if git_info.get("commit"):
|
|
858
|
+
dirty = " (有未提交改动)" if git_info.get("dirty") else ""
|
|
859
|
+
source_desc += (
|
|
860
|
+
f" git={git_info.get('branch') or '?'}@{str(git_info['commit'])[:12]}{dirty}"
|
|
861
|
+
)
|
|
862
|
+
click.secho(
|
|
863
|
+
f" ⚠ 打包进 zip 的 {package_name} 不是正式发行版来源 ({source_desc})。"
|
|
864
|
+
"若这不是有意为之,请先用官方渠道的正式版本重装后再打包; "
|
|
865
|
+
f"解压 zip 后查看 {BUILD_INFO_ARCNAME} 可核对来源与内容指纹。",
|
|
866
|
+
fg="yellow",
|
|
867
|
+
)
|
|
868
|
+
|
|
688
869
|
def _iter_project_files(self):
|
|
689
870
|
for item in sorted(self.project_dir.iterdir(), key=lambda p: p.name):
|
|
690
871
|
if self._should_skip_root_path(item):
|
|
@@ -1617,6 +1798,26 @@ class CodeBuilder(BaseBuilder):
|
|
|
1617
1798
|
)
|
|
1618
1799
|
self._finish_package_progress()
|
|
1619
1800
|
|
|
1801
|
+
# This provenance module is written after the bundled source so a
|
|
1802
|
+
# Code archive can attest to the KsADK source it actually imports.
|
|
1803
|
+
# It deliberately comes from local package bytes / Git only; no
|
|
1804
|
+
# environment value is copied into the archive.
|
|
1805
|
+
zf.writestr(
|
|
1806
|
+
"ksadk/_bundle_identity.py",
|
|
1807
|
+
self._bundle_runtime_identity_source(bundled_source_files),
|
|
1808
|
+
)
|
|
1809
|
+
# 写入 runtime 来源清单:排查"zip 里 vendored 的 ksadk 到底是什么快照"时,
|
|
1810
|
+
# 解压 ksadk/BUILD-INFO.json 即可看到来源/版本/commit/内容指纹,不用进 pod 翻文件。
|
|
1811
|
+
build_info = build_bundled_source_manifest(
|
|
1812
|
+
self._bundled_source_package_roots(),
|
|
1813
|
+
bundled_source_files,
|
|
1814
|
+
)
|
|
1815
|
+
zf.writestr(
|
|
1816
|
+
BUILD_INFO_ARCNAME,
|
|
1817
|
+
json.dumps(build_info, ensure_ascii=False, indent=2, sort_keys=True) + "\n",
|
|
1818
|
+
)
|
|
1819
|
+
self._warn_on_nonrelease_bundled_source(build_info)
|
|
1820
|
+
|
|
1620
1821
|
click.echo(f" ✓ 打包运行时源码: {bundled_source_count} 个文件")
|
|
1621
1822
|
|
|
1622
1823
|
# 添加 entrypoint
|
|
@@ -1626,6 +1827,75 @@ class CodeBuilder(BaseBuilder):
|
|
|
1626
1827
|
click.echo(f" ✓ 打包完成: {len(project_files)} 个项目文件 + {deps_count} 个依赖文件")
|
|
1627
1828
|
self._emit_package_size_report(zip_path)
|
|
1628
1829
|
|
|
1830
|
+
def _bundle_runtime_identity_source(self, bundled_source_files) -> str:
|
|
1831
|
+
"""Generate package-local provenance for a Code archive."""
|
|
1832
|
+
|
|
1833
|
+
digest = hashlib.sha256()
|
|
1834
|
+
for package_name, relative, file_path in bundled_source_files:
|
|
1835
|
+
if package_name != "ksadk":
|
|
1836
|
+
continue
|
|
1837
|
+
digest.update(relative.encode("utf-8"))
|
|
1838
|
+
digest.update(b"\0")
|
|
1839
|
+
digest.update(file_path.read_bytes())
|
|
1840
|
+
digest.update(b"\0")
|
|
1841
|
+
|
|
1842
|
+
import ksadk
|
|
1843
|
+
from ksadk.version import VERSION
|
|
1844
|
+
|
|
1845
|
+
source_root = Path(ksadk.__file__).resolve().parent
|
|
1846
|
+
commit = ""
|
|
1847
|
+
try:
|
|
1848
|
+
result = subprocess.run(
|
|
1849
|
+
["git", "-C", str(source_root.parent), "rev-parse", "HEAD"],
|
|
1850
|
+
capture_output=True,
|
|
1851
|
+
check=True,
|
|
1852
|
+
text=True,
|
|
1853
|
+
timeout=3,
|
|
1854
|
+
)
|
|
1855
|
+
candidate = result.stdout.strip().lower()
|
|
1856
|
+
if re.fullmatch(r"[0-9a-f]{40,64}", candidate):
|
|
1857
|
+
commit = candidate
|
|
1858
|
+
except (OSError, subprocess.SubprocessError):
|
|
1859
|
+
pass
|
|
1860
|
+
|
|
1861
|
+
payload = {
|
|
1862
|
+
"ksadk_version": VERSION,
|
|
1863
|
+
"ksadk_commit": commit,
|
|
1864
|
+
"ksadk_source_digest": digest.hexdigest(),
|
|
1865
|
+
}
|
|
1866
|
+
return (
|
|
1867
|
+
"# Generated by KsADK CodeBuilder; do not edit.\n"
|
|
1868
|
+
f"BUNDLE_IDENTITY = {payload!r}\n"
|
|
1869
|
+
)
|
|
1870
|
+
|
|
1871
|
+
def _emit_bundled_ksadk_identity(self, zip_path: Path) -> None:
|
|
1872
|
+
"""Print the KsADK provenance embedded in *this exact* Code archive.
|
|
1873
|
+
|
|
1874
|
+
The code archive shadows packages from the base image. Reading the
|
|
1875
|
+
generated archive back here prevents a build log from accidentally
|
|
1876
|
+
describing the local CLI environment instead of what will run in the
|
|
1877
|
+
workload.
|
|
1878
|
+
"""
|
|
1879
|
+
|
|
1880
|
+
try:
|
|
1881
|
+
with zipfile.ZipFile(zip_path) as zf:
|
|
1882
|
+
source = zf.read("ksadk/_bundle_identity.py").decode("utf-8")
|
|
1883
|
+
_prefix, raw_payload = source.split("=", 1)
|
|
1884
|
+
identity = ast.literal_eval(raw_payload.strip())
|
|
1885
|
+
except (OSError, KeyError, UnicodeDecodeError, ValueError, SyntaxError):
|
|
1886
|
+
click.secho(" ⚠ 未能读取 ZIP 内的 KsADK 来源信息", fg="yellow")
|
|
1887
|
+
return
|
|
1888
|
+
|
|
1889
|
+
if not isinstance(identity, dict):
|
|
1890
|
+
click.secho(" ⚠ ZIP 内的 KsADK 来源信息格式无效", fg="yellow")
|
|
1891
|
+
return
|
|
1892
|
+
version = str(identity.get("ksadk_version") or "unknown")
|
|
1893
|
+
commit = str(identity.get("ksadk_commit") or "unavailable")
|
|
1894
|
+
source_digest = str(identity.get("ksadk_source_digest") or "unavailable")
|
|
1895
|
+
click.echo(f" KsADK: version={version}")
|
|
1896
|
+
click.echo(f" KsADK source: commit={commit}")
|
|
1897
|
+
click.echo(f" KsADK source digest: sha256={source_digest}")
|
|
1898
|
+
|
|
1629
1899
|
def _emit_package_size_report(self, zip_path: Path, *, limit: int = 8) -> None:
|
|
1630
1900
|
try:
|
|
1631
1901
|
with zipfile.ZipFile(zip_path, "r") as zf:
|
|
@@ -1741,6 +2011,9 @@ class CodeBuilder(BaseBuilder):
|
|
|
1741
2011
|
def _generate_entrypoint(self, detection_result) -> str:
|
|
1742
2012
|
"""生成 entrypoint.py"""
|
|
1743
2013
|
package_name = Path(detection_result.package_path).name
|
|
2014
|
+
runtime_config_json = json.dumps(
|
|
2015
|
+
self._load_config(), ensure_ascii=False, separators=(",", ":"), default=str
|
|
2016
|
+
)
|
|
1744
2017
|
return f'''"""
|
|
1745
2018
|
AgentEngine Code 模式入口
|
|
1746
2019
|
|
|
@@ -1754,6 +2027,7 @@ zip 包结构:
|
|
|
1754
2027
|
import sys
|
|
1755
2028
|
import os
|
|
1756
2029
|
import logging
|
|
2030
|
+
import json
|
|
1757
2031
|
from pathlib import Path
|
|
1758
2032
|
|
|
1759
2033
|
# ========== 日志配置 ==========
|
|
@@ -1878,13 +2152,15 @@ if has_otlp or has_cloud_monitor_otlp:
|
|
|
1878
2152
|
logger.warning(f"Tracing 初始化失败: {{e}}")
|
|
1879
2153
|
|
|
1880
2154
|
# 只装配统一 RuntimeAdapter 执行链;具体 Adapter 在请求开始时由 Registry 创建。
|
|
2155
|
+
runtime_build_config = json.loads({runtime_config_json!r})
|
|
1881
2156
|
runtime_context = RuntimeLaunchContext(
|
|
1882
2157
|
runtime_type=detection_result.type.value,
|
|
1883
2158
|
project_dir=Path(CODE_ROOT),
|
|
1884
2159
|
detection=detection_result,
|
|
1885
|
-
config=dict(
|
|
2160
|
+
config=dict(runtime_build_config),
|
|
1886
2161
|
)
|
|
1887
2162
|
# managed A2A:KSADK_A2A_RUNTIME_ID 非空时挂 discovery card + 完整数据面 route。
|
|
2163
|
+
_managed_a2a_card = None
|
|
1888
2164
|
_a2a_config = None
|
|
1889
2165
|
_a2a_adapter = None
|
|
1890
2166
|
if os.environ.get("KSADK_A2A_RUNTIME_ID", "").strip():
|
|
@@ -2,6 +2,7 @@
|
|
|
2
2
|
Container Builder - Docker 镜像构建
|
|
3
3
|
"""
|
|
4
4
|
|
|
5
|
+
import json
|
|
5
6
|
import os
|
|
6
7
|
import platform
|
|
7
8
|
import shutil
|
|
@@ -441,6 +442,9 @@ CMD ["python", "entrypoint.py"]
|
|
|
441
442
|
|
|
442
443
|
def _generate_entrypoint(self, detection_result, package_name: str) -> str:
|
|
443
444
|
"""生成 entrypoint.py"""
|
|
445
|
+
runtime_config_json = json.dumps(
|
|
446
|
+
self._load_config(), ensure_ascii=False, separators=(",", ":"), default=str
|
|
447
|
+
)
|
|
444
448
|
return f'''"""
|
|
445
449
|
AgentEngine Container 模式入口
|
|
446
450
|
"""
|
|
@@ -448,6 +452,7 @@ AgentEngine Container 模式入口
|
|
|
448
452
|
import sys
|
|
449
453
|
import os
|
|
450
454
|
import logging
|
|
455
|
+
import json
|
|
451
456
|
from pathlib import Path
|
|
452
457
|
|
|
453
458
|
# ========== 日志配置 ==========
|
|
@@ -549,15 +554,17 @@ if has_otlp or has_cloud_monitor_otlp:
|
|
|
549
554
|
logger.warning(f"Tracing 初始化失败: {{e}}")
|
|
550
555
|
|
|
551
556
|
# 只装配统一 RuntimeAdapter 执行链;具体 Adapter 在请求开始时由 Registry 创建。
|
|
557
|
+
runtime_build_config = json.loads({runtime_config_json!r})
|
|
552
558
|
runtime_context = RuntimeLaunchContext(
|
|
553
559
|
runtime_type=detection_result.type.value,
|
|
554
560
|
project_dir=Path("/app"),
|
|
555
561
|
detection=detection_result,
|
|
556
|
-
config=dict(
|
|
562
|
+
config=dict(runtime_build_config),
|
|
557
563
|
)
|
|
558
564
|
# managed A2A:KSADK_A2A_RUNTIME_ID 非空时挂 discovery card + 完整数据面 route。
|
|
559
565
|
# discovery card 让 server 探测;数据面 route 让 gateway 转发的 JSON-RPC/REST
|
|
560
566
|
# 能真正落到本 runtime 的 A2A 协议端点(路线 C 直连)。
|
|
567
|
+
_managed_a2a_card = None
|
|
561
568
|
_a2a_config = None
|
|
562
569
|
_a2a_adapter = None
|
|
563
570
|
if os.environ.get("KSADK_A2A_RUNTIME_ID", "").strip():
|
|
@@ -4,7 +4,6 @@ from __future__ import annotations
|
|
|
4
4
|
|
|
5
5
|
import hashlib
|
|
6
6
|
import json
|
|
7
|
-
import zipfile
|
|
8
7
|
from pathlib import Path
|
|
9
8
|
from typing import Any
|
|
10
9
|
|
|
@@ -22,35 +21,47 @@ _MANIFEST_KEYS = (
|
|
|
22
21
|
"model",
|
|
23
22
|
"models",
|
|
24
23
|
"prompt",
|
|
24
|
+
"task_prompt",
|
|
25
25
|
"skills",
|
|
26
26
|
"mcp_servers",
|
|
27
27
|
"sandbox",
|
|
28
28
|
"approval_mode",
|
|
29
|
+
"context",
|
|
30
|
+
"memory",
|
|
29
31
|
)
|
|
30
32
|
|
|
31
33
|
|
|
32
|
-
|
|
33
|
-
"""
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
def _represent_manifest_string(dumper: yaml.SafeDumper, value: str):
|
|
37
|
-
style = "|" if "\n" in value else None
|
|
38
|
-
return dumper.represent_scalar("tag:yaml.org,2002:str", value, style=style)
|
|
34
|
+
def managed_runtime_lock_path(manifest_path: Path) -> Path:
|
|
35
|
+
"""Return the immutable lock that accompanies a YAML-only declaration.
|
|
39
36
|
|
|
37
|
+
``ManagedRuntime`` is not a user-code artifact. Keeping its two small
|
|
38
|
+
declaration files next to one another makes that visible in both the
|
|
39
|
+
workspace and the build receipt, while still preserving a historical
|
|
40
|
+
manifest for rollback.
|
|
41
|
+
"""
|
|
40
42
|
|
|
41
|
-
|
|
43
|
+
return manifest_path.with_suffix(".lock.json")
|
|
42
44
|
|
|
43
45
|
|
|
44
46
|
def serialize_managed_runtime_manifest(manifest: dict[str, Any]) -> bytes:
|
|
45
|
-
"""Serialize the canonical ManagedRuntime
|
|
47
|
+
"""Serialize the Server-canonical ManagedRuntime declaration.
|
|
48
|
+
|
|
49
|
+
The Server validates ``ManifestSHA256`` after parsing and re-dumping YAML
|
|
50
|
+
with sorted keys. Clients must hash those exact canonical bytes instead
|
|
51
|
+
of the editable source formatting, otherwise a valid Studio/CLI build is
|
|
52
|
+
rejected during ``CreateAgent``/``UpdateAgent`` admission.
|
|
53
|
+
"""
|
|
46
54
|
|
|
47
|
-
|
|
55
|
+
canonical = yaml.safe_dump(
|
|
48
56
|
manifest,
|
|
49
|
-
Dumper=_RuntimeManifestDumper,
|
|
50
57
|
allow_unicode=True,
|
|
51
|
-
sort_keys=
|
|
58
|
+
sort_keys=True,
|
|
52
59
|
default_flow_style=False,
|
|
53
|
-
|
|
60
|
+
width=10_000,
|
|
61
|
+
)
|
|
62
|
+
if not canonical.endswith("\n"):
|
|
63
|
+
canonical += "\n"
|
|
64
|
+
return canonical.encode("utf-8")
|
|
54
65
|
|
|
55
66
|
|
|
56
67
|
class ManagedRuntimeBuilder(BaseBuilder):
|
|
@@ -102,25 +113,28 @@ class ManagedRuntimeBuilder(BaseBuilder):
|
|
|
102
113
|
"runtime": runtime,
|
|
103
114
|
"manifest_sha256": manifest_sha256,
|
|
104
115
|
}
|
|
105
|
-
lock_bytes = (
|
|
106
|
-
|
|
107
|
-
)
|
|
116
|
+
lock_bytes = (json.dumps(lock, ensure_ascii=False, indent=2, sort_keys=True) + "\n").encode(
|
|
117
|
+
"utf-8"
|
|
118
|
+
)
|
|
108
119
|
|
|
109
120
|
self.build_dir.mkdir(parents=True, exist_ok=True)
|
|
110
121
|
name = str(config.get("name") or self.project_dir.name).strip() or self.project_dir.name
|
|
111
122
|
project_version = str(config.get("version") or "1.0.0").strip() or "1.0.0"
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
}
|
|
123
|
+
# This local declaration receipt is retained for Studio rollback.
|
|
124
|
+
# It is deliberately *not* a ZIP: YAML agents have no user code, no
|
|
125
|
+
# KS3 artifact and no code-downloader path. Version alone is mutable
|
|
126
|
+
# in an editable Agent, so retain the exact canonical YAML plus its
|
|
127
|
+
# lock under the content digest.
|
|
128
|
+
artifact_path = self.build_dir / (
|
|
129
|
+
f"{name}-{project_version}-{manifest_sha256[:16]}-runtime.yaml"
|
|
119
130
|
)
|
|
131
|
+
lock_path = managed_runtime_lock_path(artifact_path)
|
|
132
|
+
artifact_path.write_bytes(manifest_bytes)
|
|
133
|
+
lock_path.write_bytes(lock_bytes)
|
|
120
134
|
return BuildResult(
|
|
121
135
|
success=True,
|
|
122
136
|
artifact_path=artifact_path,
|
|
123
|
-
artifact_size=artifact_path.stat().st_size,
|
|
137
|
+
artifact_size=artifact_path.stat().st_size + lock_path.stat().st_size,
|
|
124
138
|
metadata={
|
|
125
139
|
"agent_name": name,
|
|
126
140
|
"framework": str(config.get("framework") or ""),
|
|
@@ -161,13 +175,3 @@ class ManagedRuntimeBuilder(BaseBuilder):
|
|
|
161
175
|
elif key in config:
|
|
162
176
|
normalized[key] = config[key]
|
|
163
177
|
return normalized
|
|
164
|
-
|
|
165
|
-
@staticmethod
|
|
166
|
-
def _write_bundle(path: Path, files: dict[str, bytes]) -> None:
|
|
167
|
-
with zipfile.ZipFile(path, "w", compression=zipfile.ZIP_DEFLATED) as archive:
|
|
168
|
-
for name in sorted(files):
|
|
169
|
-
info = zipfile.ZipInfo(name)
|
|
170
|
-
info.date_time = (1980, 1, 1, 0, 0, 0)
|
|
171
|
-
info.compress_type = zipfile.ZIP_DEFLATED
|
|
172
|
-
info.external_attr = 0o100644 << 16
|
|
173
|
-
archive.writestr(info, files[name])
|
ksadk/cli/__init__.py
CHANGED
|
@@ -68,11 +68,14 @@ ROOT_HELP_COMMANDS = {
|
|
|
68
68
|
"dashboard",
|
|
69
69
|
"deploy",
|
|
70
70
|
"eval",
|
|
71
|
+
"evalset",
|
|
71
72
|
"files",
|
|
72
73
|
"init",
|
|
73
74
|
"hermes",
|
|
74
75
|
"launch",
|
|
76
|
+
"managed-runtime",
|
|
75
77
|
"mcp",
|
|
78
|
+
"observe",
|
|
76
79
|
"openclaw",
|
|
77
80
|
"run",
|
|
78
81
|
"studio",
|
|
@@ -90,11 +93,14 @@ SHORT_HELP_MAP = {
|
|
|
90
93
|
"dashboard": "打开云端 Agent Dashboard",
|
|
91
94
|
"deploy": "部署到云端",
|
|
92
95
|
"eval": "评测本地、A2A 或 Codex Agent",
|
|
96
|
+
"evalset": "预览或上传 EvalSet 云端快照",
|
|
93
97
|
"files": "管理 workspace 文件",
|
|
94
98
|
"hermes": "Hermes Agent 资源管理",
|
|
95
99
|
"init": "创建新项目",
|
|
96
100
|
"launch": "一键构建+部署",
|
|
101
|
+
"managed-runtime": "启动平台托管的 YAML Agent",
|
|
97
102
|
"mcp": "MCP 资源管理",
|
|
103
|
+
"observe": "导出本地 Agent 观测数据",
|
|
98
104
|
"openclaw": "OpenClaw 资源管理",
|
|
99
105
|
"run": "运行 Agent",
|
|
100
106
|
"studio": "启动本地 Agent 构建控制台",
|
|
@@ -179,12 +185,19 @@ class ColoredHelpGroup(click.Group):
|
|
|
179
185
|
_write_colored_help_row(formatter, "agentengine web", "本地调试 Agent Invoke UI")
|
|
180
186
|
_write_colored_help_row(formatter, "agentengine studio", "本地 Agent 构建控制台")
|
|
181
187
|
_write_colored_help_row(formatter, "agentengine eval", "评测本地、A2A 或 Codex Agent")
|
|
188
|
+
_write_colored_help_row(formatter, "agentengine evalset", "预览或上传 EvalSet 云端快照")
|
|
189
|
+
_write_colored_help_row(formatter, "agentengine observe", "导出本地 Agent 观测数据")
|
|
182
190
|
|
|
183
191
|
# 云端部署
|
|
184
192
|
formatter.write(click.style(" 🚀 云端部署:\n\n", fg="blue", bold=True))
|
|
185
193
|
_write_colored_help_row(formatter, "agentengine build", "构建部署制品")
|
|
186
194
|
_write_colored_help_row(formatter, "agentengine deploy", "部署到云端")
|
|
187
195
|
_write_colored_help_row(formatter, "agentengine launch", "一键构建+部署")
|
|
196
|
+
_write_colored_help_row(
|
|
197
|
+
formatter,
|
|
198
|
+
"agentengine managed-runtime",
|
|
199
|
+
"启动平台托管的 YAML Agent",
|
|
200
|
+
)
|
|
188
201
|
_write_colored_help_row(formatter, "agentengine agent", "Agent 资源管理")
|
|
189
202
|
_write_colored_help_row(formatter, "agentengine version", "Agent 版本管理")
|
|
190
203
|
_write_colored_help_row(formatter, "agentengine mcp", "MCP 资源管理")
|
|
@@ -325,6 +338,7 @@ def _register_optional_command(cli: click.Group, module_path: str, *cmd_names: s
|
|
|
325
338
|
def _register_commands():
|
|
326
339
|
from ksadk.cli.cmd_create import create
|
|
327
340
|
from ksadk.cli.cmd_deploy import deploy
|
|
341
|
+
from ksadk.cli.cmd_managed_runtime import managed_runtime
|
|
328
342
|
from ksadk.cli.cmd_run import run
|
|
329
343
|
from ksadk.cli.cmd_web import web
|
|
330
344
|
|
|
@@ -332,6 +346,7 @@ def _register_commands():
|
|
|
332
346
|
_add_command_once(cli, run)
|
|
333
347
|
_add_command_once(cli, deploy)
|
|
334
348
|
_add_command_once(cli, web)
|
|
349
|
+
_add_command_once(cli, managed_runtime)
|
|
335
350
|
|
|
336
351
|
# init 作为主命令 (PRD 规范)
|
|
337
352
|
_add_command_once(cli, create, name="init")
|
|
@@ -344,6 +359,8 @@ def _register_commands():
|
|
|
344
359
|
_register_optional_command(cli, "ksadk.cli.cmd_build", "build")
|
|
345
360
|
_register_optional_command(cli, "ksadk.cli.cmd_studio", "studio")
|
|
346
361
|
_register_optional_command(cli, "ksadk.cli.cmd_eval", "eval")
|
|
362
|
+
_register_optional_command(cli, "ksadk.cli.cmd_evalset", "evalset")
|
|
363
|
+
_register_optional_command(cli, "ksadk.cli.cmd_observe", "observe")
|
|
347
364
|
_register_optional_command(cli, "ksadk.cli.cmd_launch", "launch")
|
|
348
365
|
_register_optional_command(cli, "ksadk.cli.cmd_agent", "agent")
|
|
349
366
|
_register_optional_command(cli, "ksadk.cli.cmd_status", "status")
|
ksadk/cli/cmd_dashboard.py
CHANGED
|
@@ -64,6 +64,10 @@ _PATH_EMBEDDED_OPTION_HINTS = (
|
|
|
64
64
|
DEFAULT_PRIVATE_LINK_EXPIRES_SECONDS = 24 * 60 * 60
|
|
65
65
|
MAX_PRIVATE_LINK_EXPIRES_SECONDS = 365 * 24 * 60 * 60
|
|
66
66
|
DEFAULT_REGION = "cn-beijing-6"
|
|
67
|
+
# Hosted UI is the shared interaction surface for platform-managed Agents.
|
|
68
|
+
# The access link keeps the user/session/Agent binding while this path keeps
|
|
69
|
+
# the Web release independent from the Agent runtime image.
|
|
70
|
+
HOSTED_INTERACTION_UI_PATH = "/hosted-ui/chat"
|
|
67
71
|
|
|
68
72
|
DASHBOARD_RESOURCE = ResourceDescriptor(
|
|
69
73
|
name="Dashboard",
|
|
@@ -528,7 +532,17 @@ def _open_dashboard(
|
|
|
528
532
|
)
|
|
529
533
|
normalized_path = _normalize_ui_path(resolved_ui.path or "/")
|
|
530
534
|
custom_ui_enabled = str(resolved_ui.profile or "").strip().lower() == "custom"
|
|
531
|
-
|
|
535
|
+
# Hermes owns its own dashboard surface and OpenClaw takes its gateway
|
|
536
|
+
# branch below. The shared Hosted UI is the default only for the generic
|
|
537
|
+
# ADK/LangChain-compatible profiles; an explicit/custom path always wins.
|
|
538
|
+
use_hosted_interaction_ui = resolved_ui.profile in {"adk", "langchain"}
|
|
539
|
+
link_path = (
|
|
540
|
+
normalized_path
|
|
541
|
+
if ui_path is not None or custom_ui_enabled
|
|
542
|
+
else HOSTED_INTERACTION_UI_PATH
|
|
543
|
+
if use_hosted_interaction_ui
|
|
544
|
+
else None
|
|
545
|
+
)
|
|
532
546
|
base_url = _build_base_ui_url(endpoint, normalized_path)
|
|
533
547
|
|
|
534
548
|
if direct:
|
ksadk/cli/cmd_deploy.py
CHANGED
|
@@ -328,7 +328,7 @@ async def _deploy_async(
|
|
|
328
328
|
agent_id: str | None = None,
|
|
329
329
|
):
|
|
330
330
|
"""异步部署流程"""
|
|
331
|
-
from ksadk.deployment import DeploymentManager, DeployTarget
|
|
331
|
+
from ksadk.deployment import DeploymentManager, DeployStatus, DeployTarget
|
|
332
332
|
from ksadk.detection import FrameworkDetector
|
|
333
333
|
|
|
334
334
|
agent_path = Path(agent_dir).resolve()
|
|
@@ -606,7 +606,15 @@ async def _deploy_async(
|
|
|
606
606
|
result = await provider.deploy(package_info, deploy_target)
|
|
607
607
|
|
|
608
608
|
if result.is_success():
|
|
609
|
-
|
|
609
|
+
# ``DEPLOYING`` only acknowledges that the control plane accepted
|
|
610
|
+
# the request. Runtime creation and the asynchronous
|
|
611
|
+
# CreateAgent callback may still be pending, so presenting it as a
|
|
612
|
+
# completed deployment is misleading (and hides a broken
|
|
613
|
+
# callback/data-plane handoff).
|
|
614
|
+
if result.status == DeployStatus.RUNNING:
|
|
615
|
+
print_success("部署成功")
|
|
616
|
+
else:
|
|
617
|
+
print_info("部署请求已提交,等待实例就绪")
|
|
610
618
|
print_rule()
|
|
611
619
|
print_kv("名称", result.agent_name or deploy_name)
|
|
612
620
|
if result.agent_id:
|