agentengine-sdk-python 0.8.0__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.0.dist-info → agentengine_sdk_python-0.8.2.dist-info}/METADATA +43 -7
- agentengine_sdk_python-0.8.2.dist-info/RECORD +778 -0
- {agentengine_sdk_python-0.8.0.dist-info → agentengine_sdk_python-0.8.2.dist-info}/WHEEL +1 -1
- ksadk/a2a/__init__.py +2 -0
- ksadk/a2a/_space_client_events.py +381 -0
- ksadk/a2a/bootstrap.py +0 -2
- ksadk/a2a/card.py +6 -111
- ksadk/a2a/control_plane.py +239 -1
- ksadk/a2a/event_adapter.py +156 -64
- ksadk/a2a/executor.py +195 -172
- ksadk/a2a/routes.py +12 -5
- ksadk/a2a/server.py +1 -8
- ksadk/a2a/service_env.py +33 -0
- ksadk/a2a/space_client.py +43 -349
- ksadk/a2a_card.py +101 -0
- ksadk/a2ui/core.py +222 -53
- ksadk/agui/_agent_helpers.py +243 -0
- ksadk/agui/a2ui_projection.py +12 -5
- ksadk/agui/agent.py +474 -275
- ksadk/agui/config.py +11 -5
- ksadk/agui/routes.py +7 -15
- ksadk/api/client.py +530 -40
- ksadk/api/environment.py +27 -0
- ksadk/builders/code_builder.py +352 -53
- ksadk/builders/container_builder.py +71 -44
- ksadk/builders/framework_requirements.py +2 -1
- ksadk/builders/ks3_uploader.py +2 -2
- ksadk/builders/managed_runtime_builder.py +60 -28
- ksadk/cli/__init__.py +25 -0
- ksadk/cli/cmd_a2a.py +18 -31
- ksadk/cli/cmd_create.py +13 -26
- ksadk/cli/cmd_dashboard.py +15 -1
- ksadk/cli/cmd_deploy.py +28 -3
- ksadk/cli/cmd_eval.py +443 -0
- ksadk/cli/cmd_evalset.py +284 -0
- ksadk/cli/cmd_files.py +5 -1
- ksadk/cli/cmd_hermes.py +137 -163
- ksadk/cli/cmd_invoke.py +28 -38
- ksadk/cli/cmd_launch.py +12 -0
- ksadk/cli/cmd_managed_runtime.py +95 -0
- ksadk/cli/cmd_observe.py +85 -0
- ksadk/cli/cmd_openclaw.py +85 -479
- ksadk/cli/cmd_replay.py +28 -4
- ksadk/cli/cmd_run.py +29 -67
- ksadk/cli/cmd_studio.py +201 -0
- ksadk/cli/cmd_web.py +15 -6
- ksadk/cli/dry_run.py +2 -1
- ksadk/cli/env_options.py +83 -0
- ksadk/cli/global_options.py +3 -1
- ksadk/cli/hermes_env.py +151 -0
- ksadk/cli/invoke_payload.py +49 -0
- ksadk/cli/network_options.py +7 -5
- ksadk/cli/openclaw_env.py +458 -0
- ksadk/cli/runtime_bootstrap.py +51 -0
- ksadk/cli/ui.py +6 -0
- ksadk/cli/workflow_common.py +5 -5
- ksadk/codex/__init__.py +3 -3
- ksadk/codex/client.py +833 -49
- ksadk/codex/phase.py +1 -1
- ksadk/codex/runtime.py +720 -127
- ksadk/common/kop_client.py +232 -0
- ksadk/configs/__init__.py +1 -3
- ksadk/configs/env_registry.py +244 -45
- ksadk/configs/env_registry_pcm.py +181 -0
- ksadk/configs/env_var_spec.py +18 -0
- ksadk/configs/global_config.py +6 -1
- ksadk/configs/settings.py +5 -108
- 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/__init__.py +85 -94
- 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 +193 -3
- ksadk/conversations/runtime_invocation.py +81 -3
- ksadk/conversations/runtime_observability.py +157 -4
- ksadk/conversations/runtime_payloads.py +42 -0
- ksadk/conversations/runtime_preparation.py +280 -2
- ksadk/conversations/runtime_resume.py +71 -32
- ksadk/conversations/runtime_stream_events.py +94 -9
- ksadk/conversations/runtime_streaming.py +175 -22
- 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 +38 -0
- ksadk/deployment/manager.py +24 -8
- ksadk/deployment/providers/serverless.py +228 -92
- ksadk/evaluation/__init__.py +116 -0
- ksadk/evaluation/a2a_adapter.py +452 -0
- ksadk/evaluation/adapters.py +67 -0
- 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 +478 -0
- ksadk/evaluation/evalset.py +351 -0
- ksadk/evaluation/evaluators.py +627 -0
- ksadk/evaluation/evidence.py +258 -0
- ksadk/evaluation/executor.py +143 -0
- ksadk/evaluation/local_adapter.py +550 -0
- ksadk/evaluation/service_env.py +27 -0
- ksadk/evaluation/storage.py +68 -0
- ksadk/evaluation/studio_build_adapter.py +253 -0
- ksadk/evaluation/target.py +82 -0
- 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 -256
- ksadk/events/session_event.py +324 -0
- ksadk/events/store.py +3 -316
- ksadk/events/v1_compat.py +41 -0
- ksadk/harness/__init__.py +3 -2
- ksadk/harness/app.py +114 -123
- ksadk/harness/config.py +1 -1
- ksadk/harness/runtime.py +467 -0
- ksadk/hermes_terminal.py +5 -0
- 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 +22 -4
- ksadk/knowledge_base/service.py +32 -5
- ksadk/managed_a2a_card.py +160 -0
- ksadk/managed_runtime.py +16 -9
- 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 +394 -5
- ksadk/memory/adk/backends/sqlite_ltm_backend.py +95 -0
- ksadk/memory/adk/long_term_memory.py +3 -2
- 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 +198 -8
- ksadk/memory/tool.py +4 -0
- ksadk/model_proxy/bootstrap.py +16 -9
- ksadk/model_proxy/config.py +22 -1
- ksadk/model_proxy/detect.py +202 -9
- ksadk/model_proxy/namespace.py +67 -15
- ksadk/model_proxy/server.py +168 -6
- ksadk/model_proxy/transform.py +105 -3
- 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 +14 -31
- ksadk/runners/base_runner.py +44 -3
- ksadk/runners/factory.py +3 -3
- ksadk/runners/langgraph_runner.py +252 -433
- ksadk/runners/utils/__init__.py +0 -10
- ksadk/runners/utils/loader.py +16 -0
- ksadk/runtime/__init__.py +67 -41
- ksadk/runtime/_runner_adapter/__init__.py +1 -0
- ksadk/runtime/_runner_adapter/stream_mapping.py +788 -0
- ksadk/runtime/adapter.py +199 -16
- ksadk/runtime/conversation_execution.py +687 -0
- ksadk/runtime/executor.py +392 -0
- ksadk/runtime/factory.py +342 -0
- ksadk/runtime/framework_adapters.py +6 -12
- ksadk/runtime/hosted_finalizer.py +268 -0
- ksadk/runtime/launch.py +61 -0
- ksadk/runtime/preprocessing.py +49 -14
- ksadk/runtime/runner_adapter.py +330 -391
- ksadk/runtime/runner_loading.py +36 -0
- ksadk/runtime/usage.py +33 -0
- ksadk/sandbox/backends/e2b.py +36 -3
- ksadk/server/__init__.py +39 -4
- ksadk/server/app.py +18 -492
- ksadk/server/composition.py +36 -2
- ksadk/server/factory.py +210 -149
- ksadk/server/routes/common.py +15 -46
- ksadk/server/routes/control.py +13 -9
- ksadk/server/routes/kernel_ingress.py +258 -0
- ksadk/server/routes/misc.py +10 -33
- ksadk/server/routes/models.py +14 -6
- ksadk/server/routes/openai_compat.py +129 -27
- ksadk/server/routes/projection.py +84 -16
- ksadk/server/routes/run.py +347 -460
- ksadk/server/routes/sessions.py +37 -40
- ksadk/server/routes/streaming.py +52 -7
- ksadk/server/routes/workspace.py +54 -21
- ksadk/server/static/assets/{ArtifactsPanel-Cjnqt-8W.js → ArtifactsPanel-DSU1sWD_.js} +1 -1
- ksadk/server/static/assets/{CodeBlock-BqyqZfuB.js → CodeBlock-DOH6MVcn.js} +4 -4
- ksadk/server/static/assets/{MathMessageMarkdown-BpH7jiFM.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-BGhvzDYt.js → chunk-5VM5RSS4-BVHAchFb.js} +1 -1
- ksadk/server/static/assets/{chunk-ND2GUHAM-D98vPd-E.js → chunk-F27PBJKO-C-ipQzuS.js} +1 -1
- ksadk/server/static/assets/chunk-G27WJ6UU-C2EyJbIK.js +231 -0
- ksadk/server/static/assets/{chunk-4BX2VUAB-CsWIQRhc.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-CX3yotHq.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-D82mtD2s.js → dist-8hqcx0sU.js} +1 -1
- ksadk/server/static/assets/dist-B7seoj3d.js +1 -0
- ksadk/server/static/assets/{dist-DHn6nBzr.js → dist-BE7bu-DL.js} +1 -1
- ksadk/server/static/assets/{dist-eoW6tZXA.js → dist-BVDffZ0U.js} +1 -1
- ksadk/server/static/assets/{dist-C2xjE7cO.js → dist-BX8z72IC.js} +1 -1
- ksadk/server/static/assets/{dist-CgF3fj15.js → dist-Bf2M8m3N.js} +1 -1
- ksadk/server/static/assets/{dist-Bs-jQcRX.js → dist-BjU6y-A2.js} +1 -1
- ksadk/server/static/assets/{dist-Djgl2wVZ.js → dist-BytlxIDT.js} +1 -1
- ksadk/server/static/assets/{dist-CVQRZjPu.js → dist-CSh_DE14.js} +1 -1
- ksadk/server/static/assets/{dist-6CVKuTAe.js → dist-CXYYBw3_.js} +1 -1
- ksadk/server/static/assets/{dist-DlzCRy0S.js → dist-C_wsv-Qd.js} +1 -1
- ksadk/server/static/assets/{dist-DF06ORQo.js → dist-ClxGviKw.js} +1 -1
- ksadk/server/static/assets/{dist-Cf23NY4L.js → dist-CttYUqzS.js} +1 -1
- ksadk/server/static/assets/{dist-ivOya1LD.js → dist-DNp6rLRA.js} +1 -1
- ksadk/server/static/assets/{dist-BibcG1V9.js → dist-DUX-id_F.js} +1 -1
- ksadk/server/static/assets/{dist-BUHRxvDG.js → dist-DmldrHd_.js} +1 -1
- ksadk/server/static/assets/{dist-BZ9n9AjO.js → dist-DnfXs8Vn.js} +2 -2
- ksadk/server/static/assets/{dist-DqNnNFrw.js → dist-Dq9gLD7L.js} +1 -1
- ksadk/server/static/assets/{dist-CGcp2ex8.js → dist-W-TIVntx.js} +1 -1
- ksadk/server/static/assets/{dist-Cwt7koer.js → dist-dDdADKFA.js} +1 -1
- ksadk/server/static/assets/{dist-C7-3jInC.js → dist-dydu68Fl.js} +1 -1
- ksadk/server/static/assets/{dist-C99THtIA.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-DLOHGvWw.js → ishikawaDiagram-5VMMS53U-DWya9SG2.js} +6 -6
- ksadk/server/static/assets/{journeyDiagram-JHISSGLW-BIzKeejT.js → journeyDiagram-EYS64GPL-DutxhSNI.js} +6 -6
- ksadk/server/static/assets/{kanban-definition-UN3LZRKU-BWHoFSw2.js → kanban-definition-3QL26DDD-DJdOF8Fm.js} +10 -10
- ksadk/server/static/assets/katex-vFWytM5c.js +257 -0
- ksadk/server/static/assets/{linear-CvMBw9cA.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-CSAQxEAe.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-CxIR4JXI.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-DpGa6EAV.js → sankeyDiagram-P5KCCOFB-CPH75rhw.js} +7 -7
- ksadk/server/static/assets/{sequenceDiagram-3UESZ5HK-NTKNGGe5.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-jqoYs3jQ.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/skills/runtime/backends/e2b.py +1 -1
- ksadk/skills/service_client.py +13 -3
- ksadk/studio/__init__.py +5 -0
- ksadk/studio/agent_avatar_assets.py +120 -0
- ksadk/studio/agent_lifecycle.py +51 -0
- ksadk/studio/api.py +1598 -0
- ksadk/studio/api_catalog_routes.py +324 -0
- ksadk/studio/api_contracts.py +286 -0
- ksadk/studio/api_helpers.py +132 -0
- ksadk/studio/api_memory_routes.py +82 -0
- ksadk/studio/authoring.py +749 -0
- ksadk/studio/authoring_coordinator.py +1017 -0
- ksadk/studio/builder.py +397 -0
- ksadk/studio/capabilities.py +368 -0
- ksadk/studio/cloud.py +2099 -0
- ksadk/studio/codex_agent_service.py +694 -0
- ksadk/studio/codex_authoring.py +469 -0
- ksadk/studio/codex_builder.py +437 -0
- ksadk/studio/codex_manifest.py +307 -0
- ksadk/studio/codex_run.py +395 -0
- ksadk/studio/compiler.py +190 -0
- ksadk/studio/contracts.py +755 -0
- ksadk/studio/errors.py +47 -0
- ksadk/studio/event_store.py +214 -0
- ksadk/studio/framework_run.py +342 -0
- ksadk/studio/hosted_kernel.py +317 -0
- ksadk/studio/identifiers.py +33 -0
- ksadk/studio/manifest_resolver.py +131 -0
- ksadk/studio/mcp_runtime.py +229 -0
- ksadk/studio/model_client.py +629 -0
- ksadk/studio/model_profile_service.py +214 -0
- ksadk/studio/operations.py +275 -0
- ksadk/studio/otel_trace.py +1060 -0
- ksadk/studio/pagination.py +182 -0
- ksadk/studio/pcm_memory.py +85 -0
- ksadk/studio/python_tool_inspection.py +183 -0
- ksadk/studio/repository.py +327 -0
- ksadk/studio/resource_catalog.py +1260 -0
- ksadk/studio/run_service.py +1133 -0
- ksadk/studio/runtime_catalog.py +74 -0
- ksadk/studio/runtime_source.py +365 -0
- ksadk/studio/service.py +2249 -0
- ksadk/studio/shared_web.py +1004 -0
- ksadk/studio/skill_discovery.py +628 -0
- ksadk/studio/static/assets/PrismRenderer-IYN-ffww.js +3 -0
- ksadk/studio/static/assets/index-BLpcdrgW.css +1 -0
- ksadk/studio/static/assets/index-CYekR2Xv.js +260 -0
- ksadk/studio/static/assets/react-vendor-BNmTiJ-I.js +9 -0
- ksadk/studio/static/assets/rolldown-runtime-hePW80VL.js +1 -0
- ksadk/studio/static/index.html +15 -0
- ksadk/studio/templates.py +722 -0
- ksadk/studio/validator.py +265 -0
- ksadk/studio/workspace.py +135 -0
- ksadk/tools/gateway.py +9 -0
- ksadk/toolsets/__init__.py +27 -1
- ksadk/toolsets/a2a.py +426 -0
- ksadk/tracing/__init__.py +19 -21
- ksadk/tracing/setup.py +317 -403
- ksadk/tracing/span_utils.py +0 -44
- ksadk/version.py +1 -1
- ksadk_runtime_common/memory_backend/registry.py +56 -56
- ksadk_runtime_common/schemas/runtime_event_v1.json +37 -0
- ksadk_runtime_common/schemas/runtime_event_v2.json +271 -0
- ksadk_runtime_common/workspace_files/router.py +8 -2
- agentengine_sdk_python-0.8.0.dist-info/RECORD +0 -578
- ksadk/a2a/card_builder.py +0 -64
- ksadk/a2a/client.py +0 -309
- ksadk/events/parser.py +0 -191
- ksadk/harness/runner.py +0 -211
- ksadk/runners/codex_runner.py +0 -132
- ksadk/runners/utils/langfuse.py +0 -230
- ksadk/server/static/assets/MathMessageMarkdown-DeYh8QPr.css +0 -1
- ksadk/server/static/assets/MermaidBlock-DWuxETaJ.js +0 -303
- ksadk/server/static/assets/NativeTerminalPanel-MDTopWMO.js +0 -1
- ksadk/server/static/assets/arc-CFKwSk_B.js +0 -1
- ksadk/server/static/assets/architecture-7EHR7CIX-CynqOWjZ.js +0 -1
- ksadk/server/static/assets/architectureDiagram-3BPJPVTR-Dej8jX8c.js +0 -36
- ksadk/server/static/assets/blockDiagram-GPEHLZMM-1F64jqvy.js +0 -132
- ksadk/server/static/assets/c4Diagram-AAUBKEIU-9q7AUAKb.js +0 -10
- ksadk/server/static/assets/channel-iUGv2N24.js +0 -1
- ksadk/server/static/assets/chunk-2J33WTMH-6qgwJm7Q.js +0 -1
- ksadk/server/static/assets/chunk-55IACEB6-BK8paA20.js +0 -1
- ksadk/server/static/assets/chunk-727SXJPM-B-JEhy7h.js +0 -206
- ksadk/server/static/assets/chunk-AQP2D5EJ-DYBvMHAa.js +0 -231
- ksadk/server/static/assets/chunk-QZHKN3VN-YQIEXeF6.js +0 -1
- ksadk/server/static/assets/classDiagram-4FO5ZUOK-CDAUuoXK.js +0 -1
- ksadk/server/static/assets/classDiagram-v2-Q7XG4LA2-CDAUuoXK.js +0 -1
- ksadk/server/static/assets/cytoscape.esm-DelgaX4f.js +0 -321
- ksadk/server/static/assets/dagre-BM42HDAG-C7TguAWo.js +0 -4
- ksadk/server/static/assets/dagre-Bx709z4p.js +0 -1
- ksadk/server/static/assets/diagram-2AECGRRQ-Dd17_kws.js +0 -43
- ksadk/server/static/assets/diagram-5GNKFQAL-DVIClIil.js +0 -10
- ksadk/server/static/assets/diagram-KO2AKTUF-Df_3gYQa.js +0 -3
- ksadk/server/static/assets/diagram-LMA3HP47-BhLk6ZtA.js +0 -24
- ksadk/server/static/assets/diagram-OG6HWLK6-D4GNGvuu.js +0 -24
- ksadk/server/static/assets/dist-DyvYLMW9.js +0 -1
- ksadk/server/static/assets/erDiagram-TEJ5UH35-CnfRcY2M.js +0 -85
- ksadk/server/static/assets/eventmodeling-FCH6USID-ChYO-ijM.js +0 -1
- ksadk/server/static/assets/flowDiagram-I6XJVG4X-DGaJjGNJ.js +0 -162
- ksadk/server/static/assets/ganttDiagram-6RSMTGT7-DpCoB2g9.js +0 -292
- ksadk/server/static/assets/gitGraph-WXDBUCRP-BN_0Fk-j.js +0 -1
- ksadk/server/static/assets/gitGraphDiagram-PVQCEYII-9IKVFBVT.js +0 -106
- ksadk/server/static/assets/graphlib-B8gBHxth.js +0 -1
- ksadk/server/static/assets/index-QSwCHuB8.js +0 -177
- ksadk/server/static/assets/index-jOPmTOZH.css +0 -2
- ksadk/server/static/assets/info-J43DQDTF-Cp6o3vId.js +0 -1
- ksadk/server/static/assets/infoDiagram-5YYISTIA-CYIIsb8y.js +0 -2
- ksadk/server/static/assets/katex-DATssjp1.js +0 -265
- ksadk/server/static/assets/mermaid-parser.core-mGAcEwcq.js +0 -161
- ksadk/server/static/assets/packet-YPE3B663-wQzct3cT.js +0 -1
- ksadk/server/static/assets/pie-LRSECV5Y-BgTQiv-9.js +0 -1
- ksadk/server/static/assets/pieDiagram-4H26LBE5-By-ra07M.js +0 -30
- ksadk/server/static/assets/radar-GUYGQ44K-BIq5fXsn.js +0 -1
- ksadk/server/static/assets/requirementDiagram-4Y6WPE33-DpW90iu3.js +0 -84
- ksadk/server/static/assets/stateDiagram-AJRCARHV-DGpd9yFG.js +0 -1
- ksadk/server/static/assets/stateDiagram-v2-BHNVJYJU-B3o579IQ.js +0 -1
- ksadk/server/static/assets/treeView-BLDUP644-Dqi-E0EM.js +0 -1
- ksadk/server/static/assets/treemap-LRROVOQU-ClQP9CJ9.js +0 -1
- ksadk/server/static/assets/vennDiagram-CIIHVFJN-l3Z7-wbP.js +0 -34
- ksadk/server/static/assets/wardley-L42UT6IY-8XLvnNIs.js +0 -1
- ksadk/server/static/assets/wardleyDiagram-YWT4CUSO-BR54GPmr.js +0 -78
- ksadk/server/static/assets/xychartDiagram-2RQKCTM6-SkiH8GsK.js +0 -7
- ksadk/tracing/exporters/langfuse_exporter.py +0 -460
- {agentengine_sdk_python-0.8.0.dist-info → agentengine_sdk_python-0.8.2.dist-info}/entry_points.txt +0 -0
- {agentengine_sdk_python-0.8.0.dist-info → agentengine_sdk_python-0.8.2.dist-info}/licenses/LICENSE +0 -0
- {agentengine_sdk_python-0.8.0.dist-info → agentengine_sdk_python-0.8.2.dist-info}/top_level.txt +0 -0
|
@@ -0,0 +1,317 @@
|
|
|
1
|
+
"""Content-addressed preflight for Studio Code bundles hosted by Agent Kernel.
|
|
2
|
+
|
|
3
|
+
This module deliberately proves only properties available in the local bundle:
|
|
4
|
+
the frozen Agent Kernel wire-contract digest and the launch layout generated by
|
|
5
|
+
Studio. Whether the target Server-selected image implements that digest remains
|
|
6
|
+
a separate control-plane/readiness check.
|
|
7
|
+
"""
|
|
8
|
+
|
|
9
|
+
from __future__ import annotations
|
|
10
|
+
|
|
11
|
+
import io
|
|
12
|
+
import json
|
|
13
|
+
import zipfile
|
|
14
|
+
from dataclasses import dataclass
|
|
15
|
+
from pathlib import PurePosixPath
|
|
16
|
+
from typing import Any
|
|
17
|
+
|
|
18
|
+
from ksadk.studio.capabilities import canonical_json, sha256_digest
|
|
19
|
+
from ksadk.studio.errors import StudioError
|
|
20
|
+
|
|
21
|
+
AGENT_KERNEL_V1_CONTRACT_SET = "agent-kernel/v1"
|
|
22
|
+
# This mirrors contracts/agent-kernel/v1/manifest.json. A Studio test compares
|
|
23
|
+
# the two, so a frozen-contract update cannot leave packaged preflight stale.
|
|
24
|
+
AGENT_KERNEL_V1_CONTRACT_DIGEST = "47e1003e03d97abeba232cc3e03a14b9cbcf78b1109870ccd2ce371f073b6211"
|
|
25
|
+
HOSTED_KERNEL_REQUIREMENTS_PATH = "hosted-kernel-requirements.json"
|
|
26
|
+
HOSTED_KERNEL_REQUIREMENTS_FORMAT = "agentkit.hosted-kernel-requirements/v1"
|
|
27
|
+
HOSTED_KERNEL_RUNTIME_CONTRACT = "agentkit.runtime/v1"
|
|
28
|
+
HOSTED_KERNEL_BUNDLE_FORMAT = "agentkit.bundle/v2"
|
|
29
|
+
_RUNTIME_TYPES = frozenset({"adk", "codex", "langgraph"})
|
|
30
|
+
|
|
31
|
+
|
|
32
|
+
@dataclass(frozen=True)
|
|
33
|
+
class HostedKernelBundle:
|
|
34
|
+
"""Facts proved from the exact ZIP bytes that will be uploaded."""
|
|
35
|
+
|
|
36
|
+
manifest: dict[str, Any]
|
|
37
|
+
provenance: dict[str, Any]
|
|
38
|
+
requirement: dict[str, Any]
|
|
39
|
+
requirement_digest: str
|
|
40
|
+
|
|
41
|
+
|
|
42
|
+
def build_hosted_kernel_requirement(
|
|
43
|
+
*,
|
|
44
|
+
runtime_type: str,
|
|
45
|
+
entry_point: str | None,
|
|
46
|
+
agent_variable: str | None,
|
|
47
|
+
launch_config: bytes | None,
|
|
48
|
+
) -> dict[str, Any]:
|
|
49
|
+
"""Build the immutable local requirement embedded into every Studio ZIP."""
|
|
50
|
+
|
|
51
|
+
return {
|
|
52
|
+
"format": HOSTED_KERNEL_REQUIREMENTS_FORMAT,
|
|
53
|
+
"kernelContract": {
|
|
54
|
+
"set": AGENT_KERNEL_V1_CONTRACT_SET,
|
|
55
|
+
"digest": AGENT_KERNEL_V1_CONTRACT_DIGEST,
|
|
56
|
+
},
|
|
57
|
+
"bundleLayout": HOSTED_KERNEL_BUNDLE_FORMAT,
|
|
58
|
+
"runtimeContract": HOSTED_KERNEL_RUNTIME_CONTRACT,
|
|
59
|
+
"runtime": {
|
|
60
|
+
"type": runtime_type,
|
|
61
|
+
"entryPoint": entry_point or "",
|
|
62
|
+
"agentVariable": agent_variable or "",
|
|
63
|
+
"launchConfig": "runtime/agentengine.yaml" if launch_config is not None else "",
|
|
64
|
+
"launchConfigSha256": sha256_digest(launch_config) if launch_config is not None else "",
|
|
65
|
+
},
|
|
66
|
+
}
|
|
67
|
+
|
|
68
|
+
|
|
69
|
+
def hosted_kernel_requirement_digest(requirement: dict[str, Any]) -> str:
|
|
70
|
+
return sha256_digest(canonical_json(requirement))
|
|
71
|
+
|
|
72
|
+
|
|
73
|
+
def preflight_hosted_kernel_bundle(bundle: bytes) -> HostedKernelBundle:
|
|
74
|
+
"""Reject a ZIP that cannot be proved compatible before CreateAgent.
|
|
75
|
+
|
|
76
|
+
This validates the uploaded bytes, including their file manifest, instead
|
|
77
|
+
of trusting a writable sibling directory from a local Build.
|
|
78
|
+
"""
|
|
79
|
+
|
|
80
|
+
try:
|
|
81
|
+
with zipfile.ZipFile(io.BytesIO(bundle)) as archive:
|
|
82
|
+
names = _validated_zip_names(archive)
|
|
83
|
+
entries = {name: archive.read(name) for name in names}
|
|
84
|
+
except (OSError, zipfile.BadZipFile, zipfile.LargeZipFile) as error:
|
|
85
|
+
raise _integrity_error("Bundle 不是可验证的 ZIP 文件", reason="invalid_zip") from error
|
|
86
|
+
|
|
87
|
+
manifest = _json_object(entries, "manifest.json")
|
|
88
|
+
provenance = _json_object(entries, "provenance.json")
|
|
89
|
+
requirement = _json_object(entries, HOSTED_KERNEL_REQUIREMENTS_PATH)
|
|
90
|
+
requirement_digest = hosted_kernel_requirement_digest(requirement)
|
|
91
|
+
|
|
92
|
+
_validate_requirement(manifest, provenance, requirement, requirement_digest, entries)
|
|
93
|
+
_validate_content_manifest(manifest, entries)
|
|
94
|
+
_validate_declared_bundle_digest(manifest)
|
|
95
|
+
return HostedKernelBundle(
|
|
96
|
+
manifest=manifest,
|
|
97
|
+
provenance=provenance,
|
|
98
|
+
requirement=requirement,
|
|
99
|
+
requirement_digest=requirement_digest,
|
|
100
|
+
)
|
|
101
|
+
|
|
102
|
+
|
|
103
|
+
def _validated_zip_names(archive: zipfile.ZipFile) -> list[str]:
|
|
104
|
+
names = archive.namelist()
|
|
105
|
+
if not names:
|
|
106
|
+
raise _integrity_error("Bundle 为空", reason="empty_zip")
|
|
107
|
+
if len(names) != len(set(names)):
|
|
108
|
+
raise _integrity_error("Bundle 含有重复文件名", reason="duplicate_path")
|
|
109
|
+
for name in names:
|
|
110
|
+
path = PurePosixPath(name)
|
|
111
|
+
if (
|
|
112
|
+
not name
|
|
113
|
+
or "\\" in name
|
|
114
|
+
or name.endswith("/")
|
|
115
|
+
or path.is_absolute()
|
|
116
|
+
or any(part in {"", ".", ".."} for part in path.parts)
|
|
117
|
+
):
|
|
118
|
+
raise _integrity_error("Bundle 含有不安全文件路径", reason="unsafe_path")
|
|
119
|
+
return names
|
|
120
|
+
|
|
121
|
+
|
|
122
|
+
def _json_object(entries: dict[str, bytes], path: str) -> dict[str, Any]:
|
|
123
|
+
raw = entries.get(path)
|
|
124
|
+
if raw is None:
|
|
125
|
+
raise _incompatible_error(f"Bundle 缺少 {path}", reason="missing_required_file")
|
|
126
|
+
try:
|
|
127
|
+
parsed = json.loads(raw.decode("utf-8"))
|
|
128
|
+
except (UnicodeDecodeError, json.JSONDecodeError) as error:
|
|
129
|
+
raise _incompatible_error(
|
|
130
|
+
f"Bundle 中的 {path} 不是 JSON 对象", reason="invalid_json"
|
|
131
|
+
) from error
|
|
132
|
+
if not isinstance(parsed, dict):
|
|
133
|
+
raise _incompatible_error(f"Bundle 中的 {path} 不是 JSON 对象", reason="invalid_json")
|
|
134
|
+
return parsed
|
|
135
|
+
|
|
136
|
+
|
|
137
|
+
def _validate_requirement(
|
|
138
|
+
manifest: dict[str, Any],
|
|
139
|
+
provenance: dict[str, Any],
|
|
140
|
+
requirement: dict[str, Any],
|
|
141
|
+
requirement_digest: str,
|
|
142
|
+
entries: dict[str, bytes],
|
|
143
|
+
) -> None:
|
|
144
|
+
if manifest.get("bundleFormat") != HOSTED_KERNEL_BUNDLE_FORMAT:
|
|
145
|
+
raise _incompatible_error(
|
|
146
|
+
"Bundle 不是受支持的 Studio Code bundle 格式", reason="bundle_format"
|
|
147
|
+
)
|
|
148
|
+
if manifest.get("runtimeContract") != HOSTED_KERNEL_RUNTIME_CONTRACT:
|
|
149
|
+
raise _incompatible_error(
|
|
150
|
+
"Bundle runtime contract 不受 Hosted Agent Kernel 支持", reason="runtime_contract"
|
|
151
|
+
)
|
|
152
|
+
if requirement.get("format") != HOSTED_KERNEL_REQUIREMENTS_FORMAT:
|
|
153
|
+
raise _incompatible_error(
|
|
154
|
+
"Bundle 缺少 Hosted Agent Kernel requirement 格式声明", reason="requirement_format"
|
|
155
|
+
)
|
|
156
|
+
if requirement.get("bundleLayout") != manifest.get("bundleFormat"):
|
|
157
|
+
raise _incompatible_error(
|
|
158
|
+
"Bundle requirement 与 bundle layout 不一致", reason="bundle_layout"
|
|
159
|
+
)
|
|
160
|
+
if requirement.get("runtimeContract") != manifest.get("runtimeContract"):
|
|
161
|
+
raise _incompatible_error(
|
|
162
|
+
"Bundle requirement 与 runtime contract 不一致", reason="runtime_contract"
|
|
163
|
+
)
|
|
164
|
+
|
|
165
|
+
contract = requirement.get("kernelContract")
|
|
166
|
+
if not isinstance(contract, dict):
|
|
167
|
+
raise _incompatible_error(
|
|
168
|
+
"Bundle 缺少 Agent Kernel contract requirement", reason="missing_contract"
|
|
169
|
+
)
|
|
170
|
+
if contract.get("set") != AGENT_KERNEL_V1_CONTRACT_SET:
|
|
171
|
+
raise _incompatible_error(
|
|
172
|
+
"Bundle Agent Kernel contract set 不受支持", reason="contract_set"
|
|
173
|
+
)
|
|
174
|
+
if contract.get("digest") != AGENT_KERNEL_V1_CONTRACT_DIGEST:
|
|
175
|
+
raise _incompatible_error(
|
|
176
|
+
"Bundle Agent Kernel contract digest 与当前 KsADK 不一致,请重新 Build 后部署",
|
|
177
|
+
reason="contract_digest",
|
|
178
|
+
)
|
|
179
|
+
|
|
180
|
+
hosted = provenance.get("hostedKernel")
|
|
181
|
+
if not isinstance(hosted, dict):
|
|
182
|
+
raise _incompatible_error(
|
|
183
|
+
"Bundle provenance 缺少 Hosted Agent Kernel requirement", reason="missing_provenance"
|
|
184
|
+
)
|
|
185
|
+
if hosted.get("requirementsPath") != HOSTED_KERNEL_REQUIREMENTS_PATH:
|
|
186
|
+
raise _incompatible_error(
|
|
187
|
+
"Bundle provenance 的 requirement 路径不一致", reason="provenance_path"
|
|
188
|
+
)
|
|
189
|
+
if hosted.get("requirementDigest") != requirement_digest:
|
|
190
|
+
raise _incompatible_error(
|
|
191
|
+
"Bundle provenance 的 requirement digest 不一致", reason="provenance_digest"
|
|
192
|
+
)
|
|
193
|
+
if hosted.get("contractSet") != contract.get("set") or hosted.get(
|
|
194
|
+
"contractDigest"
|
|
195
|
+
) != contract.get("digest"):
|
|
196
|
+
raise _incompatible_error(
|
|
197
|
+
"Bundle provenance 的 Agent Kernel contract 不一致", reason="provenance_contract"
|
|
198
|
+
)
|
|
199
|
+
if manifest.get("hostedKernelRequirementDigest") != requirement_digest:
|
|
200
|
+
raise _incompatible_error(
|
|
201
|
+
"Bundle manifest 的 requirement digest 不一致", reason="manifest_digest"
|
|
202
|
+
)
|
|
203
|
+
|
|
204
|
+
runtime = requirement.get("runtime")
|
|
205
|
+
if not isinstance(runtime, dict):
|
|
206
|
+
raise _incompatible_error(
|
|
207
|
+
"Bundle 缺少受支持的 runtime 启动 requirement", reason="missing_runtime"
|
|
208
|
+
)
|
|
209
|
+
runtime_type = str(runtime.get("type") or "").strip().lower()
|
|
210
|
+
entry_point = str(runtime.get("entryPoint") or "").strip()
|
|
211
|
+
agent_variable = str(runtime.get("agentVariable") or "").strip()
|
|
212
|
+
launch_path = str(runtime.get("launchConfig") or "").strip()
|
|
213
|
+
launch_digest = str(runtime.get("launchConfigSha256") or "").strip()
|
|
214
|
+
if runtime_type not in _RUNTIME_TYPES:
|
|
215
|
+
raise _incompatible_error(
|
|
216
|
+
"Bundle runtime 类型不受 Hosted Agent Kernel 支持", reason="runtime_type"
|
|
217
|
+
)
|
|
218
|
+
if (
|
|
219
|
+
runtime_type != str(manifest.get("runtimeType") or "").strip().lower()
|
|
220
|
+
or not entry_point
|
|
221
|
+
or not agent_variable
|
|
222
|
+
or launch_path != "runtime/agentengine.yaml"
|
|
223
|
+
or not launch_digest
|
|
224
|
+
):
|
|
225
|
+
raise _incompatible_error("Bundle 缺少可验证的 runtime 启动配置", reason="runtime_launch")
|
|
226
|
+
if not _safe_relative_file(entry_point) or f"runtime/{entry_point}" not in entries:
|
|
227
|
+
raise _incompatible_error("Bundle runtime entryPoint 不存在或不安全", reason="entry_point")
|
|
228
|
+
launch_bytes = entries.get(launch_path)
|
|
229
|
+
if launch_bytes is None or sha256_digest(launch_bytes) != launch_digest:
|
|
230
|
+
raise _incompatible_error("Bundle runtime 启动配置 digest 不一致", reason="launch_digest")
|
|
231
|
+
launch = _json_object(entries, launch_path)
|
|
232
|
+
if (
|
|
233
|
+
str(launch.get("framework") or "").strip().lower() != runtime_type
|
|
234
|
+
or launch.get("entry_point") != entry_point
|
|
235
|
+
or launch.get("agent_variable") != agent_variable
|
|
236
|
+
or launch.get("package") != "."
|
|
237
|
+
):
|
|
238
|
+
raise _incompatible_error(
|
|
239
|
+
"Bundle runtime 启动配置与 requirement 不一致", reason="launch_config"
|
|
240
|
+
)
|
|
241
|
+
runtime_lock = _json_object(entries, "runtime-lock.json")
|
|
242
|
+
if (
|
|
243
|
+
str(runtime_lock.get("type") or "").strip().lower() != runtime_type
|
|
244
|
+
or runtime_lock.get("entryPoint") != entry_point
|
|
245
|
+
or runtime_lock.get("agentVariable") != agent_variable
|
|
246
|
+
):
|
|
247
|
+
raise _incompatible_error(
|
|
248
|
+
"Bundle runtime lock 与 requirement 不一致", reason="runtime_lock"
|
|
249
|
+
)
|
|
250
|
+
|
|
251
|
+
|
|
252
|
+
def _validate_content_manifest(manifest: dict[str, Any], entries: dict[str, bytes]) -> None:
|
|
253
|
+
files = manifest.get("files")
|
|
254
|
+
if not isinstance(files, list):
|
|
255
|
+
raise _integrity_error("Bundle manifest 缺少文件清单", reason="missing_file_manifest")
|
|
256
|
+
recorded: dict[str, dict[str, Any]] = {}
|
|
257
|
+
for item in files:
|
|
258
|
+
if not isinstance(item, dict) or not isinstance(item.get("path"), str):
|
|
259
|
+
raise _integrity_error("Bundle manifest 的文件清单无效", reason="invalid_file_manifest")
|
|
260
|
+
path = item["path"]
|
|
261
|
+
if path in recorded or not _safe_relative_file(path) or path == "manifest.json":
|
|
262
|
+
raise _integrity_error("Bundle manifest 的文件路径无效", reason="invalid_file_manifest")
|
|
263
|
+
recorded[path] = item
|
|
264
|
+
if set(entries) != set(recorded) | {"manifest.json"}:
|
|
265
|
+
raise _integrity_error("Bundle ZIP 与 manifest 文件清单不一致", reason="file_membership")
|
|
266
|
+
for path, item in recorded.items():
|
|
267
|
+
content = entries[path]
|
|
268
|
+
if item.get("sha256") != sha256_digest(content) or item.get("size") != len(content):
|
|
269
|
+
raise _integrity_error("Bundle 文件摘要与 manifest 不一致", reason="file_digest")
|
|
270
|
+
|
|
271
|
+
|
|
272
|
+
def _validate_declared_bundle_digest(manifest: dict[str, Any]) -> None:
|
|
273
|
+
declared = manifest.get("bundleDigest")
|
|
274
|
+
digest_payload = dict(manifest)
|
|
275
|
+
digest_payload.pop("bundleDigest", None)
|
|
276
|
+
if declared != sha256_digest(canonical_json(digest_payload)):
|
|
277
|
+
raise _integrity_error("Bundle manifest 的 bundle digest 不一致", reason="bundle_digest")
|
|
278
|
+
|
|
279
|
+
|
|
280
|
+
def _safe_relative_file(value: str) -> bool:
|
|
281
|
+
path = PurePosixPath(value)
|
|
282
|
+
return (
|
|
283
|
+
bool(value)
|
|
284
|
+
and "\\" not in value
|
|
285
|
+
and not path.is_absolute()
|
|
286
|
+
and all(part not in {"", ".", ".."} for part in path.parts)
|
|
287
|
+
)
|
|
288
|
+
|
|
289
|
+
|
|
290
|
+
def _incompatible_error(message: str, *, reason: str) -> StudioError:
|
|
291
|
+
return StudioError(
|
|
292
|
+
"HOSTED_KERNEL_BUNDLE_INCOMPATIBLE",
|
|
293
|
+
message,
|
|
294
|
+
status_code=422,
|
|
295
|
+
details={"reason": reason},
|
|
296
|
+
)
|
|
297
|
+
|
|
298
|
+
|
|
299
|
+
def _integrity_error(message: str, *, reason: str) -> StudioError:
|
|
300
|
+
return StudioError(
|
|
301
|
+
"HOSTED_KERNEL_BUNDLE_INTEGRITY_INVALID",
|
|
302
|
+
message,
|
|
303
|
+
status_code=422,
|
|
304
|
+
details={"reason": reason},
|
|
305
|
+
)
|
|
306
|
+
|
|
307
|
+
|
|
308
|
+
__all__ = [
|
|
309
|
+
"AGENT_KERNEL_V1_CONTRACT_DIGEST",
|
|
310
|
+
"AGENT_KERNEL_V1_CONTRACT_SET",
|
|
311
|
+
"HOSTED_KERNEL_REQUIREMENTS_FORMAT",
|
|
312
|
+
"HOSTED_KERNEL_REQUIREMENTS_PATH",
|
|
313
|
+
"HostedKernelBundle",
|
|
314
|
+
"build_hosted_kernel_requirement",
|
|
315
|
+
"hosted_kernel_requirement_digest",
|
|
316
|
+
"preflight_hosted_kernel_bundle",
|
|
317
|
+
]
|
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
"""Server-owned local identifiers for Studio resources."""
|
|
2
|
+
|
|
3
|
+
from __future__ import annotations
|
|
4
|
+
|
|
5
|
+
import re
|
|
6
|
+
import secrets
|
|
7
|
+
from collections.abc import Callable
|
|
8
|
+
|
|
9
|
+
from ksadk.studio.errors import StudioError
|
|
10
|
+
|
|
11
|
+
_GENERATED_AGENT_SLUG = re.compile(r"^agentkit-[0-9a-f]{8}$")
|
|
12
|
+
|
|
13
|
+
|
|
14
|
+
def generate_agent_slug(exists: Callable[[str], bool]) -> str:
|
|
15
|
+
"""Allocate a short opaque Agent ID without trusting a client-side default."""
|
|
16
|
+
|
|
17
|
+
for _attempt in range(32):
|
|
18
|
+
candidate = f"agentkit-{secrets.token_hex(4)}"
|
|
19
|
+
if not exists(candidate):
|
|
20
|
+
return candidate
|
|
21
|
+
raise StudioError(
|
|
22
|
+
"AGENT_ID_EXHAUSTED",
|
|
23
|
+
"无法分配唯一的本地标识",
|
|
24
|
+
status_code=503,
|
|
25
|
+
field="slug",
|
|
26
|
+
)
|
|
27
|
+
|
|
28
|
+
|
|
29
|
+
def is_generated_agent_slug(value: str) -> bool:
|
|
30
|
+
return bool(_GENERATED_AGENT_SLUG.fullmatch(str(value or "").strip()))
|
|
31
|
+
|
|
32
|
+
|
|
33
|
+
__all__ = ["generate_agent_slug", "is_generated_agent_slug"]
|
|
@@ -0,0 +1,131 @@
|
|
|
1
|
+
"""ManifestResolver —— 统一识别工作区根 Manifest 的种类(方案 §6.1)。
|
|
2
|
+
|
|
3
|
+
当前问题(方案 §2.4 第 1 点):标准 LangGraph/ADK 项目作为 Studio workspace 启动后,根
|
|
4
|
+
``agentengine.yaml`` 可能先进入 Codex Manifest 解析,导致 ``CODEX_MANIFEST_INVALID``。
|
|
5
|
+
|
|
6
|
+
本模块提供统一入口:根 manifest 存在时先读 ``framework`` / ``runtime.type`` 字段决定 kind,
|
|
7
|
+
只有明确 ``framework: codex`` 才走 ``CodexAgentManifest`` 解析;明确为 ADK/LangGraph 等框架时
|
|
8
|
+
返回 framework kind(交给 ``FrameworkDetector`` 与标准 Code 项目导入);无法判定时返回
|
|
9
|
+
``MANIFEST_KIND_AMBIGUOUS``,列出候选,不猜测为 Codex。
|
|
10
|
+
|
|
11
|
+
解析顺序(方案 §6.1):
|
|
12
|
+
1. 根 manifest 不存在 → ``none``
|
|
13
|
+
2. 显式 ``framework: codex`` 或 ``runtime.name: codex`` → ``codex``
|
|
14
|
+
3. 显式 ``framework: adk|langgraph|...`` 或 ``runtime.type: adk|langgraph|...`` → ``framework``
|
|
15
|
+
4. 仍无法判定 → ``ambiguous``(列出已读到的关键字段,便于诊断)
|
|
16
|
+
"""
|
|
17
|
+
|
|
18
|
+
from __future__ import annotations
|
|
19
|
+
|
|
20
|
+
from dataclasses import dataclass, field
|
|
21
|
+
from pathlib import Path
|
|
22
|
+
from typing import Any, Literal
|
|
23
|
+
|
|
24
|
+
import yaml
|
|
25
|
+
|
|
26
|
+
ManifestKind = Literal["none", "codex", "framework", "ambiguous"]
|
|
27
|
+
|
|
28
|
+
# framework/runtime 字段的已知 codex / framework 取值。
|
|
29
|
+
_CODEX_FRAMEWORK_VALUES = frozenset({"codex"})
|
|
30
|
+
_CODEX_RUNTIME_VALUES = frozenset({"codex"})
|
|
31
|
+
_FRAMEWORK_VALUES = frozenset({"adk", "langgraph", "langchain", "deepagents", "hermes", "openclaw"})
|
|
32
|
+
|
|
33
|
+
|
|
34
|
+
@dataclass(frozen=True)
|
|
35
|
+
class ManifestKindResult:
|
|
36
|
+
"""根 manifest 识别结果。"""
|
|
37
|
+
|
|
38
|
+
kind: ManifestKind
|
|
39
|
+
path: Path
|
|
40
|
+
framework: str = ""
|
|
41
|
+
runtime_type: str = ""
|
|
42
|
+
artifact_type: str = ""
|
|
43
|
+
# ambiguous 时列出已读字段,供诊断与错误返回。
|
|
44
|
+
detected_fields: dict[str, Any] = field(default_factory=dict)
|
|
45
|
+
|
|
46
|
+
@property
|
|
47
|
+
def is_codex(self) -> bool:
|
|
48
|
+
return self.kind == "codex"
|
|
49
|
+
|
|
50
|
+
|
|
51
|
+
def _safe_yaml(path: Path) -> dict[str, Any]:
|
|
52
|
+
try:
|
|
53
|
+
with open(path, "r", encoding="utf-8-sig") as f:
|
|
54
|
+
payload = yaml.safe_load(f)
|
|
55
|
+
except (OSError, yaml.YAMLError):
|
|
56
|
+
return {}
|
|
57
|
+
if not isinstance(payload, dict):
|
|
58
|
+
return {}
|
|
59
|
+
return payload
|
|
60
|
+
|
|
61
|
+
|
|
62
|
+
def detect_manifest_kind(workspace_root: Path | str) -> ManifestKindResult:
|
|
63
|
+
"""识别工作区根 manifest 的种类(方案 §6.1)。
|
|
64
|
+
|
|
65
|
+
``workspace_root`` 指工作区目录;本函数查其下的 ``agentengine.yaml``(不存在时返回 ``none``)。
|
|
66
|
+
"""
|
|
67
|
+
root = Path(workspace_root)
|
|
68
|
+
path = root / "agentengine.yaml"
|
|
69
|
+
if not path.is_file():
|
|
70
|
+
return ManifestKindResult(kind="none", path=path)
|
|
71
|
+
|
|
72
|
+
payload = _safe_yaml(path)
|
|
73
|
+
if not payload:
|
|
74
|
+
# 文件存在但无法解析为 dict → ambiguous(不猜测为 codex)
|
|
75
|
+
return ManifestKindResult(kind="ambiguous", path=path, detected_fields={"unparsable": True})
|
|
76
|
+
|
|
77
|
+
framework = str(payload.get("framework") or "").strip().lower()
|
|
78
|
+
runtime = payload.get("runtime") or {}
|
|
79
|
+
runtime_type = (
|
|
80
|
+
str(runtime.get("type") or runtime.get("name") or "").strip().lower()
|
|
81
|
+
if isinstance(runtime, dict)
|
|
82
|
+
else ""
|
|
83
|
+
)
|
|
84
|
+
artifact_type = str(payload.get("artifact_type") or "").strip().lower()
|
|
85
|
+
detected = {
|
|
86
|
+
"framework": framework,
|
|
87
|
+
"runtimeType": runtime_type,
|
|
88
|
+
"artifactType": artifact_type,
|
|
89
|
+
"topLevelKeys": sorted(payload.keys()),
|
|
90
|
+
}
|
|
91
|
+
|
|
92
|
+
# 2. 显式 codex
|
|
93
|
+
if framework in _CODEX_FRAMEWORK_VALUES or runtime_type in _CODEX_RUNTIME_VALUES:
|
|
94
|
+
return ManifestKindResult(
|
|
95
|
+
kind="codex",
|
|
96
|
+
path=path,
|
|
97
|
+
framework=framework,
|
|
98
|
+
runtime_type=runtime_type,
|
|
99
|
+
artifact_type=artifact_type,
|
|
100
|
+
)
|
|
101
|
+
# 3. 显式 framework
|
|
102
|
+
if framework in _FRAMEWORK_VALUES or runtime_type in _FRAMEWORK_VALUES:
|
|
103
|
+
return ManifestKindResult(
|
|
104
|
+
kind="framework",
|
|
105
|
+
path=path,
|
|
106
|
+
framework=framework or runtime_type,
|
|
107
|
+
runtime_type=runtime_type,
|
|
108
|
+
artifact_type=artifact_type,
|
|
109
|
+
)
|
|
110
|
+
# 4. 无法判定(例如只有 name/version 但无 framework/runtime)
|
|
111
|
+
return ManifestKindResult(
|
|
112
|
+
kind="ambiguous",
|
|
113
|
+
path=path,
|
|
114
|
+
framework=framework,
|
|
115
|
+
runtime_type=runtime_type,
|
|
116
|
+
artifact_type=artifact_type,
|
|
117
|
+
detected_fields=detected,
|
|
118
|
+
)
|
|
119
|
+
|
|
120
|
+
|
|
121
|
+
def root_manifest_is_codex(workspace_root: Path | str) -> bool:
|
|
122
|
+
"""便捷判定:根 manifest 是否应走 Codex 解析(方案 §6.1)。"""
|
|
123
|
+
return detect_manifest_kind(workspace_root).is_codex
|
|
124
|
+
|
|
125
|
+
|
|
126
|
+
__all__ = [
|
|
127
|
+
"ManifestKind",
|
|
128
|
+
"ManifestKindResult",
|
|
129
|
+
"detect_manifest_kind",
|
|
130
|
+
"root_manifest_is_codex",
|
|
131
|
+
]
|