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,550 @@
|
|
|
1
|
+
"""Local source evaluation target backed by the unified RuntimeAdapter stack."""
|
|
2
|
+
|
|
3
|
+
from __future__ import annotations
|
|
4
|
+
|
|
5
|
+
import asyncio
|
|
6
|
+
import hashlib
|
|
7
|
+
import os
|
|
8
|
+
import subprocess
|
|
9
|
+
import tempfile
|
|
10
|
+
import time
|
|
11
|
+
from collections.abc import Awaitable, Callable
|
|
12
|
+
from dataclasses import dataclass, replace
|
|
13
|
+
from pathlib import Path
|
|
14
|
+
from typing import Any
|
|
15
|
+
|
|
16
|
+
from ksadk.detection.detector import DetectionResult, FrameworkDetector, FrameworkType
|
|
17
|
+
from ksadk.evaluation.adapters import TargetAdapterError
|
|
18
|
+
from ksadk.evaluation.contracts import (
|
|
19
|
+
EvalCase,
|
|
20
|
+
EvalRunSpec,
|
|
21
|
+
TargetKind,
|
|
22
|
+
TargetRef,
|
|
23
|
+
TargetRun,
|
|
24
|
+
TargetRunStatus,
|
|
25
|
+
TargetSnapshot,
|
|
26
|
+
ToolCallEvidence,
|
|
27
|
+
TraceRef,
|
|
28
|
+
UsageSnapshot,
|
|
29
|
+
)
|
|
30
|
+
from ksadk.evaluation.evidence import EvidenceStore, project_tool_calls
|
|
31
|
+
from ksadk.events.store import RuntimeEventStore
|
|
32
|
+
from ksadk.runtime import RuntimeExecutor, RuntimeLaunchContext
|
|
33
|
+
from ksadk.runtime.conversation_execution import invoke_runtime_conversation_once
|
|
34
|
+
from ksadk.runtime.factory import build_default_runtime_registry
|
|
35
|
+
from ksadk.sessions.in_memory import InMemorySessionService
|
|
36
|
+
|
|
37
|
+
_SUPPORTED_FRAMEWORKS = {
|
|
38
|
+
FrameworkType.ADK: "adk",
|
|
39
|
+
FrameworkType.LANGGRAPH: "langgraph",
|
|
40
|
+
FrameworkType.LANGCHAIN: "langgraph",
|
|
41
|
+
FrameworkType.DEEPAGENTS: "langgraph",
|
|
42
|
+
}
|
|
43
|
+
_EXCLUDED_DIRECTORIES = {
|
|
44
|
+
".agentengine",
|
|
45
|
+
".agentkit",
|
|
46
|
+
".aws",
|
|
47
|
+
".azure",
|
|
48
|
+
".docker",
|
|
49
|
+
".git",
|
|
50
|
+
".hg",
|
|
51
|
+
".kube",
|
|
52
|
+
".mypy_cache",
|
|
53
|
+
".pytest_cache",
|
|
54
|
+
".ruff_cache",
|
|
55
|
+
".ssh",
|
|
56
|
+
".tox",
|
|
57
|
+
".venv",
|
|
58
|
+
"__pycache__",
|
|
59
|
+
"build",
|
|
60
|
+
"dist",
|
|
61
|
+
"node_modules",
|
|
62
|
+
"tmp",
|
|
63
|
+
"venv",
|
|
64
|
+
}
|
|
65
|
+
_EXCLUDED_FILE_NAMES = {
|
|
66
|
+
".env",
|
|
67
|
+
".netrc",
|
|
68
|
+
".npmrc",
|
|
69
|
+
".pypirc",
|
|
70
|
+
"auth.json",
|
|
71
|
+
"credentials.json",
|
|
72
|
+
"dockerconfigjson",
|
|
73
|
+
"kubeconfig",
|
|
74
|
+
"secrets.json",
|
|
75
|
+
"service-account.json",
|
|
76
|
+
}
|
|
77
|
+
_EXCLUDED_SUFFIXES = {
|
|
78
|
+
".db",
|
|
79
|
+
".jks",
|
|
80
|
+
".key",
|
|
81
|
+
".keystore",
|
|
82
|
+
".log",
|
|
83
|
+
".p12",
|
|
84
|
+
".pem",
|
|
85
|
+
".pfx",
|
|
86
|
+
".pyc",
|
|
87
|
+
".pyo",
|
|
88
|
+
".sqlite",
|
|
89
|
+
}
|
|
90
|
+
_MAX_SNAPSHOT_FILES = 10_000
|
|
91
|
+
_MAX_SNAPSHOT_BYTES = 256 * 1024 * 1024
|
|
92
|
+
_HASH_CHUNK_BYTES = 1024 * 1024
|
|
93
|
+
|
|
94
|
+
_Invoke = Callable[..., Awaitable[tuple[str, dict[str, Any]]]]
|
|
95
|
+
|
|
96
|
+
|
|
97
|
+
@dataclass(frozen=True)
|
|
98
|
+
class _ResolvedLocalTarget:
|
|
99
|
+
snapshot: TargetSnapshot
|
|
100
|
+
detection: DetectionResult
|
|
101
|
+
launch_context: RuntimeLaunchContext
|
|
102
|
+
agent_id: str
|
|
103
|
+
workspace: tempfile.TemporaryDirectory
|
|
104
|
+
|
|
105
|
+
|
|
106
|
+
@dataclass(frozen=True)
|
|
107
|
+
class _LocalTurnResult:
|
|
108
|
+
output: str
|
|
109
|
+
usage: UsageSnapshot
|
|
110
|
+
invocation_id: str
|
|
111
|
+
|
|
112
|
+
|
|
113
|
+
@dataclass(frozen=True)
|
|
114
|
+
class _LocalCaseResult:
|
|
115
|
+
status: TargetRunStatus
|
|
116
|
+
turns: tuple[_LocalTurnResult, ...]
|
|
117
|
+
duration_ms: int
|
|
118
|
+
error_code: str | None = None
|
|
119
|
+
error_message: str | None = None
|
|
120
|
+
trace_ref: TraceRef | None = None
|
|
121
|
+
trace_refs: tuple[TraceRef, ...] = ()
|
|
122
|
+
tool_calls: tuple[ToolCallEvidence, ...] = ()
|
|
123
|
+
|
|
124
|
+
|
|
125
|
+
class LocalTargetError(TargetAdapterError):
|
|
126
|
+
"""Classified failure while resolving a local source target."""
|
|
127
|
+
|
|
128
|
+
def __init__(self, code: str, message: str) -> None:
|
|
129
|
+
super().__init__(code, message)
|
|
130
|
+
|
|
131
|
+
|
|
132
|
+
class LocalSourceTargetAdapter:
|
|
133
|
+
"""Snapshot local ADK/LangGraph-family projects for evaluation."""
|
|
134
|
+
|
|
135
|
+
kind = TargetKind.LOCAL_SOURCE
|
|
136
|
+
|
|
137
|
+
def __init__(
|
|
138
|
+
self,
|
|
139
|
+
*,
|
|
140
|
+
timeout_seconds: int,
|
|
141
|
+
invoke: _Invoke = invoke_runtime_conversation_once,
|
|
142
|
+
evidence_store: EvidenceStore | None = None,
|
|
143
|
+
) -> None:
|
|
144
|
+
self._timeout_seconds = timeout_seconds
|
|
145
|
+
self._invoke = invoke
|
|
146
|
+
self._evidence_store = evidence_store
|
|
147
|
+
self._executor = RuntimeExecutor(build_default_runtime_registry())
|
|
148
|
+
self._session_service = InMemorySessionService()
|
|
149
|
+
self._resolved: _ResolvedLocalTarget | None = None
|
|
150
|
+
|
|
151
|
+
async def snapshot(self, target: TargetRef) -> TargetSnapshot:
|
|
152
|
+
if target.kind is not self.kind:
|
|
153
|
+
raise LocalTargetError(
|
|
154
|
+
"LOCAL_TARGET_KIND_INVALID",
|
|
155
|
+
"Local Source adapter received a non-local target",
|
|
156
|
+
)
|
|
157
|
+
|
|
158
|
+
project_dir = await asyncio.to_thread(_resolve_project_dir, target.locator)
|
|
159
|
+
workspace, source_digest = await asyncio.to_thread(_materialize_snapshot, project_dir)
|
|
160
|
+
snapshot_dir = Path(workspace.name)
|
|
161
|
+
try:
|
|
162
|
+
detection = await asyncio.to_thread(
|
|
163
|
+
lambda: FrameworkDetector(str(snapshot_dir)).detect()
|
|
164
|
+
)
|
|
165
|
+
except BaseException:
|
|
166
|
+
workspace.cleanup()
|
|
167
|
+
raise
|
|
168
|
+
runtime_type = _SUPPORTED_FRAMEWORKS.get(detection.type)
|
|
169
|
+
if runtime_type is None:
|
|
170
|
+
workspace.cleanup()
|
|
171
|
+
raise LocalTargetError(
|
|
172
|
+
"LOCAL_FRAMEWORK_UNSUPPORTED",
|
|
173
|
+
f"Unsupported local Agent framework: {detection.type.value}",
|
|
174
|
+
)
|
|
175
|
+
|
|
176
|
+
try:
|
|
177
|
+
entrypoint = await asyncio.to_thread(
|
|
178
|
+
_resolve_entrypoint,
|
|
179
|
+
snapshot_dir,
|
|
180
|
+
target.entrypoint or detection.entry_point,
|
|
181
|
+
)
|
|
182
|
+
except BaseException:
|
|
183
|
+
workspace.cleanup()
|
|
184
|
+
raise
|
|
185
|
+
detection = replace(detection, entry_point=entrypoint.as_posix())
|
|
186
|
+
git_head, git_dirty = await asyncio.to_thread(_git_state, project_dir)
|
|
187
|
+
metadata: dict[str, object] = {
|
|
188
|
+
"detectedFramework": detection.type.value,
|
|
189
|
+
"agentVariable": detection.agent_variable,
|
|
190
|
+
}
|
|
191
|
+
if git_head is not None:
|
|
192
|
+
metadata["gitHead"] = git_head
|
|
193
|
+
if git_dirty is not None:
|
|
194
|
+
metadata["gitDirty"] = git_dirty
|
|
195
|
+
|
|
196
|
+
snapshot = TargetSnapshot(
|
|
197
|
+
kind=self.kind,
|
|
198
|
+
entrypoint=entrypoint.as_posix(),
|
|
199
|
+
revision_digest=f"sha256:{source_digest}",
|
|
200
|
+
runtime=runtime_type,
|
|
201
|
+
metadata=metadata,
|
|
202
|
+
)
|
|
203
|
+
previous = self._resolved
|
|
204
|
+
self._resolved = _ResolvedLocalTarget(
|
|
205
|
+
snapshot=snapshot,
|
|
206
|
+
detection=detection,
|
|
207
|
+
launch_context=RuntimeLaunchContext(
|
|
208
|
+
runtime_type=runtime_type,
|
|
209
|
+
project_dir=snapshot_dir,
|
|
210
|
+
detection=detection,
|
|
211
|
+
config={
|
|
212
|
+
**dict(detection.raw_config or {}),
|
|
213
|
+
"turn_timeout_seconds": self._timeout_seconds,
|
|
214
|
+
},
|
|
215
|
+
),
|
|
216
|
+
agent_id=detection.name or project_dir.name,
|
|
217
|
+
workspace=workspace,
|
|
218
|
+
)
|
|
219
|
+
if previous is not None:
|
|
220
|
+
previous.workspace.cleanup()
|
|
221
|
+
return snapshot
|
|
222
|
+
|
|
223
|
+
async def run_case(
|
|
224
|
+
self,
|
|
225
|
+
spec: EvalRunSpec,
|
|
226
|
+
case: EvalCase,
|
|
227
|
+
*,
|
|
228
|
+
attempt: int,
|
|
229
|
+
) -> TargetRun:
|
|
230
|
+
resolved = self._resolved
|
|
231
|
+
if resolved is None:
|
|
232
|
+
raise RuntimeError("Local Source target must be snapshotted before execution")
|
|
233
|
+
if spec.target != resolved.snapshot:
|
|
234
|
+
raise RuntimeError("EvalRunSpec target does not match the snapshotted local target")
|
|
235
|
+
|
|
236
|
+
started_at = time.perf_counter()
|
|
237
|
+
turns: list[_LocalTurnResult] = []
|
|
238
|
+
session_id = _scoped_id("eval-session", spec.id, case.id, str(attempt))
|
|
239
|
+
invocation_id: str | None = None
|
|
240
|
+
trace_ref: TraceRef | None = None
|
|
241
|
+
trace_refs: list[TraceRef] = []
|
|
242
|
+
tool_calls: list[ToolCallEvidence] = []
|
|
243
|
+
try:
|
|
244
|
+
for turn_index, turn in enumerate(case.turns, start=1):
|
|
245
|
+
invocation_id = _scoped_id(
|
|
246
|
+
"eval-invocation",
|
|
247
|
+
spec.id,
|
|
248
|
+
case.id,
|
|
249
|
+
str(attempt),
|
|
250
|
+
str(turn_index),
|
|
251
|
+
)
|
|
252
|
+
session_id, runtime_result = await asyncio.wait_for(
|
|
253
|
+
self._invoke(
|
|
254
|
+
executor=self._executor,
|
|
255
|
+
launch_context=resolved.launch_context,
|
|
256
|
+
agent_id=resolved.agent_id,
|
|
257
|
+
user_id="eval-user",
|
|
258
|
+
messages=[{"role": "user", "content": turn.input}],
|
|
259
|
+
session_id=session_id,
|
|
260
|
+
model=_configured_model(resolved.detection),
|
|
261
|
+
invocation_id=invocation_id,
|
|
262
|
+
session_service_provider=lambda: self._session_service,
|
|
263
|
+
),
|
|
264
|
+
timeout=self._timeout_seconds,
|
|
265
|
+
)
|
|
266
|
+
turns.append(
|
|
267
|
+
_LocalTurnResult(
|
|
268
|
+
output=str(runtime_result.get("output_text") or ""),
|
|
269
|
+
usage=_usage_snapshot(runtime_result.get("usage")),
|
|
270
|
+
invocation_id=invocation_id,
|
|
271
|
+
)
|
|
272
|
+
)
|
|
273
|
+
if self._evidence_store is not None:
|
|
274
|
+
events = await RuntimeEventStore(self._session_service).list(
|
|
275
|
+
session_id,
|
|
276
|
+
run_id=invocation_id,
|
|
277
|
+
)
|
|
278
|
+
if events:
|
|
279
|
+
trace_ref = self._evidence_store.write_trace(
|
|
280
|
+
spec.id,
|
|
281
|
+
events,
|
|
282
|
+
session_id=session_id,
|
|
283
|
+
policy=spec.config.data_policy,
|
|
284
|
+
)
|
|
285
|
+
trace_refs.append(trace_ref)
|
|
286
|
+
tool_calls.extend(project_tool_calls(events))
|
|
287
|
+
except asyncio.CancelledError:
|
|
288
|
+
raise
|
|
289
|
+
except TimeoutError:
|
|
290
|
+
result = _LocalCaseResult(
|
|
291
|
+
status=TargetRunStatus.ERROR,
|
|
292
|
+
turns=tuple(turns),
|
|
293
|
+
duration_ms=_elapsed_ms(started_at),
|
|
294
|
+
error_code="LOCAL_RUNTIME_TIMEOUT",
|
|
295
|
+
error_message="Local Agent runtime timed out",
|
|
296
|
+
trace_ref=trace_ref,
|
|
297
|
+
trace_refs=tuple(trace_refs),
|
|
298
|
+
tool_calls=tuple(tool_calls),
|
|
299
|
+
)
|
|
300
|
+
return _to_target_run(result, runtime=resolved.snapshot.runtime)
|
|
301
|
+
except Exception:
|
|
302
|
+
result = _LocalCaseResult(
|
|
303
|
+
status=TargetRunStatus.ERROR,
|
|
304
|
+
turns=tuple(turns),
|
|
305
|
+
duration_ms=_elapsed_ms(started_at),
|
|
306
|
+
error_code="LOCAL_RUNTIME_ERROR",
|
|
307
|
+
error_message="Local Agent runtime failed",
|
|
308
|
+
trace_ref=trace_ref,
|
|
309
|
+
trace_refs=tuple(trace_refs),
|
|
310
|
+
tool_calls=tuple(tool_calls),
|
|
311
|
+
)
|
|
312
|
+
return _to_target_run(result, runtime=resolved.snapshot.runtime)
|
|
313
|
+
finally:
|
|
314
|
+
await asyncio.shield(self._session_service.delete_session(session_id))
|
|
315
|
+
|
|
316
|
+
status = (
|
|
317
|
+
TargetRunStatus.PASSED if turns and turns[-1].output else TargetRunStatus.UNAVAILABLE
|
|
318
|
+
)
|
|
319
|
+
result = _LocalCaseResult(
|
|
320
|
+
status=status,
|
|
321
|
+
turns=tuple(turns),
|
|
322
|
+
duration_ms=_elapsed_ms(started_at),
|
|
323
|
+
error_code=(None if status is TargetRunStatus.PASSED else "LOCAL_OUTPUT_UNAVAILABLE"),
|
|
324
|
+
error_message=(
|
|
325
|
+
None
|
|
326
|
+
if status is TargetRunStatus.PASSED
|
|
327
|
+
else "Local Agent did not provide evaluable text output"
|
|
328
|
+
),
|
|
329
|
+
trace_ref=trace_ref,
|
|
330
|
+
trace_refs=tuple(trace_refs),
|
|
331
|
+
tool_calls=tuple(tool_calls),
|
|
332
|
+
)
|
|
333
|
+
return _to_target_run(result, runtime=resolved.snapshot.runtime)
|
|
334
|
+
|
|
335
|
+
|
|
336
|
+
def _resolve_project_dir(locator: str) -> Path:
|
|
337
|
+
project_dir = Path(locator).expanduser().resolve()
|
|
338
|
+
if not project_dir.is_dir():
|
|
339
|
+
raise LocalTargetError(
|
|
340
|
+
"LOCAL_PROJECT_INVALID",
|
|
341
|
+
"Local Source target locator must be an existing directory",
|
|
342
|
+
)
|
|
343
|
+
return project_dir
|
|
344
|
+
|
|
345
|
+
|
|
346
|
+
def _resolve_entrypoint(project_dir: Path, value: str) -> Path:
|
|
347
|
+
if not value:
|
|
348
|
+
raise LocalTargetError(
|
|
349
|
+
"LOCAL_ENTRYPOINT_INVALID",
|
|
350
|
+
"Local Agent entrypoint was not detected",
|
|
351
|
+
)
|
|
352
|
+
project_dir = project_dir.resolve()
|
|
353
|
+
candidate = (project_dir / Path(value.replace("\\", "/"))).resolve()
|
|
354
|
+
try:
|
|
355
|
+
relative = candidate.relative_to(project_dir)
|
|
356
|
+
except ValueError as exc:
|
|
357
|
+
raise LocalTargetError(
|
|
358
|
+
"LOCAL_ENTRYPOINT_INVALID",
|
|
359
|
+
"Local Agent entrypoint must remain inside the project directory",
|
|
360
|
+
) from exc
|
|
361
|
+
if not candidate.is_file():
|
|
362
|
+
raise LocalTargetError(
|
|
363
|
+
"LOCAL_ENTRYPOINT_INVALID",
|
|
364
|
+
"Local Agent entrypoint must be an existing file",
|
|
365
|
+
)
|
|
366
|
+
return relative
|
|
367
|
+
|
|
368
|
+
|
|
369
|
+
def _materialize_snapshot(
|
|
370
|
+
project_dir: Path,
|
|
371
|
+
) -> tuple[tempfile.TemporaryDirectory, str]:
|
|
372
|
+
workspace = tempfile.TemporaryDirectory(prefix="ksadk-eval-local-")
|
|
373
|
+
snapshot_dir = Path(workspace.name)
|
|
374
|
+
digest = hashlib.sha256()
|
|
375
|
+
file_count = 0
|
|
376
|
+
total_bytes = 0
|
|
377
|
+
try:
|
|
378
|
+
for path in _snapshot_files(project_dir):
|
|
379
|
+
relative = path.relative_to(project_dir)
|
|
380
|
+
if (
|
|
381
|
+
not path.is_file()
|
|
382
|
+
or _exclude_from_snapshot(relative)
|
|
383
|
+
or not _is_within_project(path, project_dir)
|
|
384
|
+
):
|
|
385
|
+
continue
|
|
386
|
+
file_count += 1
|
|
387
|
+
if file_count > _MAX_SNAPSHOT_FILES:
|
|
388
|
+
raise LocalTargetError(
|
|
389
|
+
"LOCAL_SNAPSHOT_TOO_LARGE",
|
|
390
|
+
"Local Agent snapshot exceeds the supported size limit",
|
|
391
|
+
)
|
|
392
|
+
destination = snapshot_dir / relative
|
|
393
|
+
destination.parent.mkdir(parents=True, exist_ok=True)
|
|
394
|
+
digest.update(relative.as_posix().encode("utf-8"))
|
|
395
|
+
digest.update(b"\0")
|
|
396
|
+
with path.open("rb") as source, destination.open("wb") as target:
|
|
397
|
+
while chunk := source.read(_HASH_CHUNK_BYTES):
|
|
398
|
+
total_bytes += len(chunk)
|
|
399
|
+
if total_bytes > _MAX_SNAPSHOT_BYTES:
|
|
400
|
+
raise LocalTargetError(
|
|
401
|
+
"LOCAL_SNAPSHOT_TOO_LARGE",
|
|
402
|
+
"Local Agent snapshot exceeds the supported size limit",
|
|
403
|
+
)
|
|
404
|
+
digest.update(chunk)
|
|
405
|
+
target.write(chunk)
|
|
406
|
+
digest.update(b"\0")
|
|
407
|
+
return workspace, digest.hexdigest()
|
|
408
|
+
except LocalTargetError:
|
|
409
|
+
workspace.cleanup()
|
|
410
|
+
raise
|
|
411
|
+
except OSError as exc:
|
|
412
|
+
workspace.cleanup()
|
|
413
|
+
raise LocalTargetError(
|
|
414
|
+
"LOCAL_SNAPSHOT_FAILED",
|
|
415
|
+
"Unable to materialize a Local Agent snapshot input",
|
|
416
|
+
) from exc
|
|
417
|
+
|
|
418
|
+
|
|
419
|
+
def _snapshot_files(project_dir: Path) -> list[Path]:
|
|
420
|
+
files: list[Path] = []
|
|
421
|
+
for root, directories, names in os.walk(project_dir, followlinks=False):
|
|
422
|
+
directories[:] = sorted(
|
|
423
|
+
name for name in directories if name.lower() not in _EXCLUDED_DIRECTORIES
|
|
424
|
+
)
|
|
425
|
+
root_path = Path(root)
|
|
426
|
+
files.extend(root_path / name for name in sorted(names))
|
|
427
|
+
return files
|
|
428
|
+
|
|
429
|
+
|
|
430
|
+
def _configured_model(detection: DetectionResult) -> str | None:
|
|
431
|
+
value = detection.raw_config.get("model") if detection.raw_config else None
|
|
432
|
+
model = str(value or "").strip()
|
|
433
|
+
return model or None
|
|
434
|
+
|
|
435
|
+
|
|
436
|
+
def _usage_snapshot(raw_usage: object) -> UsageSnapshot:
|
|
437
|
+
usage = raw_usage if isinstance(raw_usage, dict) else {}
|
|
438
|
+
reported = any(key in usage for key in ("input_tokens", "output_tokens", "total_tokens"))
|
|
439
|
+
return UsageSnapshot(
|
|
440
|
+
input_tokens=_non_negative_int(usage.get("input_tokens")),
|
|
441
|
+
output_tokens=_non_negative_int(usage.get("output_tokens")),
|
|
442
|
+
total_tokens=_non_negative_int(usage.get("total_tokens")),
|
|
443
|
+
reported=reported,
|
|
444
|
+
)
|
|
445
|
+
|
|
446
|
+
|
|
447
|
+
def _non_negative_int(value: object) -> int:
|
|
448
|
+
if isinstance(value, bool):
|
|
449
|
+
return 0
|
|
450
|
+
try:
|
|
451
|
+
return max(0, int(value or 0))
|
|
452
|
+
except (TypeError, ValueError):
|
|
453
|
+
return 0
|
|
454
|
+
|
|
455
|
+
|
|
456
|
+
def _sum_usage(turns: tuple[_LocalTurnResult, ...]) -> UsageSnapshot:
|
|
457
|
+
reported = any(turn.usage.reported for turn in turns)
|
|
458
|
+
return UsageSnapshot(
|
|
459
|
+
input_tokens=sum(turn.usage.input_tokens for turn in turns),
|
|
460
|
+
output_tokens=sum(turn.usage.output_tokens for turn in turns),
|
|
461
|
+
total_tokens=sum(turn.usage.total_tokens for turn in turns),
|
|
462
|
+
reported=reported,
|
|
463
|
+
)
|
|
464
|
+
|
|
465
|
+
|
|
466
|
+
def _to_target_run(result: _LocalCaseResult, *, runtime: str) -> TargetRun:
|
|
467
|
+
final_turn = result.turns[-1] if result.turns else None
|
|
468
|
+
return TargetRun(
|
|
469
|
+
status=result.status,
|
|
470
|
+
output=(
|
|
471
|
+
final_turn.output
|
|
472
|
+
if final_turn is not None and result.status is TargetRunStatus.PASSED
|
|
473
|
+
else ""
|
|
474
|
+
),
|
|
475
|
+
duration_ms=result.duration_ms,
|
|
476
|
+
usage=_sum_usage(result.turns),
|
|
477
|
+
error_code=result.error_code,
|
|
478
|
+
error_message=result.error_message,
|
|
479
|
+
trace_ref=result.trace_ref,
|
|
480
|
+
trace_refs=list(result.trace_refs),
|
|
481
|
+
tool_calls=list(result.tool_calls),
|
|
482
|
+
metadata={
|
|
483
|
+
"runtime": runtime,
|
|
484
|
+
"turnCount": len(result.turns),
|
|
485
|
+
},
|
|
486
|
+
)
|
|
487
|
+
|
|
488
|
+
|
|
489
|
+
def _scoped_id(prefix: str, *parts: str) -> str:
|
|
490
|
+
payload = "\0".join(parts).encode("utf-8")
|
|
491
|
+
return f"{prefix}-{hashlib.sha256(payload).hexdigest()[:24]}"
|
|
492
|
+
|
|
493
|
+
|
|
494
|
+
def _elapsed_ms(started_at: float) -> int:
|
|
495
|
+
return max(0, round((time.perf_counter() - started_at) * 1000))
|
|
496
|
+
|
|
497
|
+
|
|
498
|
+
def _exclude_from_snapshot(relative: Path) -> bool:
|
|
499
|
+
if any(part.lower() in _EXCLUDED_DIRECTORIES for part in relative.parts[:-1]):
|
|
500
|
+
return True
|
|
501
|
+
name = relative.name.lower()
|
|
502
|
+
if name in _EXCLUDED_FILE_NAMES:
|
|
503
|
+
return True
|
|
504
|
+
if name.startswith(".env.") and name not in {
|
|
505
|
+
".env.example",
|
|
506
|
+
".env.sample",
|
|
507
|
+
".env.template",
|
|
508
|
+
}:
|
|
509
|
+
return True
|
|
510
|
+
return relative.suffix.lower() in _EXCLUDED_SUFFIXES
|
|
511
|
+
|
|
512
|
+
|
|
513
|
+
def _is_within_project(path: Path, project_dir: Path) -> bool:
|
|
514
|
+
try:
|
|
515
|
+
path.resolve().relative_to(project_dir)
|
|
516
|
+
return True
|
|
517
|
+
except (OSError, ValueError):
|
|
518
|
+
return False
|
|
519
|
+
|
|
520
|
+
|
|
521
|
+
def _git_state(project_dir: Path) -> tuple[str | None, bool | None]:
|
|
522
|
+
try:
|
|
523
|
+
head = _run_git(project_dir, "rev-parse", "HEAD")
|
|
524
|
+
dirty = bool(
|
|
525
|
+
_run_git(
|
|
526
|
+
project_dir,
|
|
527
|
+
"status",
|
|
528
|
+
"--porcelain",
|
|
529
|
+
"--untracked-files=normal",
|
|
530
|
+
"--",
|
|
531
|
+
".",
|
|
532
|
+
)
|
|
533
|
+
)
|
|
534
|
+
return head, dirty
|
|
535
|
+
except (OSError, subprocess.SubprocessError, ValueError):
|
|
536
|
+
return None, None
|
|
537
|
+
|
|
538
|
+
|
|
539
|
+
def _run_git(project_dir: Path, *args: str) -> str:
|
|
540
|
+
completed = subprocess.run(
|
|
541
|
+
["git", "-C", str(project_dir), *args],
|
|
542
|
+
check=True,
|
|
543
|
+
capture_output=True,
|
|
544
|
+
text=True,
|
|
545
|
+
timeout=5,
|
|
546
|
+
)
|
|
547
|
+
return completed.stdout.strip()
|
|
548
|
+
|
|
549
|
+
|
|
550
|
+
__all__ = ["LocalSourceTargetAdapter", "LocalTargetError"]
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
"""Endpoint resolution for the agent-eval cloud Dataset transport."""
|
|
2
|
+
|
|
3
|
+
from __future__ import annotations
|
|
4
|
+
|
|
5
|
+
import os
|
|
6
|
+
|
|
7
|
+
from ksadk.common.aicp_env import DEFAULT_AICP_REGION, resolve_aicp_connection
|
|
8
|
+
|
|
9
|
+
AGENT_EVAL_BASE_URL_ENV = "AGENT_EVAL_BASE_URL"
|
|
10
|
+
|
|
11
|
+
|
|
12
|
+
def resolve_agent_eval_direct_url() -> str | None:
|
|
13
|
+
"""Return the explicit direct-HTTP override, if one was configured."""
|
|
14
|
+
|
|
15
|
+
value = os.environ.get(AGENT_EVAL_BASE_URL_ENV, "").strip().rstrip("/")
|
|
16
|
+
return value or None
|
|
17
|
+
|
|
18
|
+
|
|
19
|
+
def resolve_agent_eval_kop_connection() -> dict[str, str]:
|
|
20
|
+
"""Resolve the AICP origin used by the default signed KOP transport."""
|
|
21
|
+
|
|
22
|
+
connection = resolve_aicp_connection("KSADK_AGENT_EVAL")
|
|
23
|
+
return {
|
|
24
|
+
"base_url": f"{connection['scheme']}://{connection['endpoint']}".rstrip("/"),
|
|
25
|
+
# pre-online is a routing marker, not an AWS V4 signing region.
|
|
26
|
+
"region": DEFAULT_AICP_REGION,
|
|
27
|
+
}
|
|
@@ -0,0 +1,68 @@
|
|
|
1
|
+
"""Local, atomic storage for the shared evaluation report contract."""
|
|
2
|
+
|
|
3
|
+
from __future__ import annotations
|
|
4
|
+
|
|
5
|
+
import json
|
|
6
|
+
from pathlib import Path
|
|
7
|
+
|
|
8
|
+
from .contracts import EvalRunReport
|
|
9
|
+
|
|
10
|
+
|
|
11
|
+
class EvaluationStorageError(RuntimeError):
|
|
12
|
+
"""Raised when a report cannot be read or safely persisted."""
|
|
13
|
+
|
|
14
|
+
|
|
15
|
+
class EvaluationStorage:
|
|
16
|
+
"""Persist reports below one workspace-owned evaluation directory."""
|
|
17
|
+
|
|
18
|
+
def __init__(self, root: str | Path):
|
|
19
|
+
self.root = Path(root).expanduser().resolve()
|
|
20
|
+
|
|
21
|
+
def report_path(self, run_id: str) -> Path:
|
|
22
|
+
"""Return the only report location allowed for a run identifier."""
|
|
23
|
+
|
|
24
|
+
if not run_id or Path(run_id).name != run_id:
|
|
25
|
+
raise EvaluationStorageError("run_id 只能包含文件名,不允许路径穿越")
|
|
26
|
+
return self.root / run_id / "report.json"
|
|
27
|
+
|
|
28
|
+
def write_report(self, report: EvalRunReport) -> Path:
|
|
29
|
+
"""Write the completed report atomically after its artifact directory exists."""
|
|
30
|
+
|
|
31
|
+
path = self.report_path(report.spec.id)
|
|
32
|
+
path.parent.mkdir(parents=True, exist_ok=True)
|
|
33
|
+
temporary = path.with_name(f".{path.name}.{report.report_digest}.tmp")
|
|
34
|
+
payload = json.dumps(
|
|
35
|
+
report.model_dump(mode="json", by_alias=True, exclude_none=True),
|
|
36
|
+
ensure_ascii=False,
|
|
37
|
+
sort_keys=True,
|
|
38
|
+
indent=2,
|
|
39
|
+
) + "\n"
|
|
40
|
+
try:
|
|
41
|
+
temporary.write_text(payload, encoding="utf-8")
|
|
42
|
+
temporary.replace(path)
|
|
43
|
+
except OSError as exc:
|
|
44
|
+
temporary.unlink(missing_ok=True)
|
|
45
|
+
raise EvaluationStorageError("评测报告写入失败") from exc
|
|
46
|
+
return path
|
|
47
|
+
|
|
48
|
+
def read_report(self, run_id: str) -> EvalRunReport:
|
|
49
|
+
path = self.report_path(run_id)
|
|
50
|
+
try:
|
|
51
|
+
return EvalRunReport.model_validate_json(path.read_text(encoding="utf-8"))
|
|
52
|
+
except FileNotFoundError as exc:
|
|
53
|
+
raise EvaluationStorageError("评测报告不存在") from exc
|
|
54
|
+
except (OSError, ValueError) as exc:
|
|
55
|
+
raise EvaluationStorageError("评测报告损坏或不可读") from exc
|
|
56
|
+
|
|
57
|
+
def list_reports(self) -> list[EvalRunReport]:
|
|
58
|
+
if not self.root.is_dir():
|
|
59
|
+
return []
|
|
60
|
+
reports: list[EvalRunReport] = []
|
|
61
|
+
for path in sorted(self.root.glob("*/report.json")):
|
|
62
|
+
try:
|
|
63
|
+
reports.append(
|
|
64
|
+
EvalRunReport.model_validate_json(path.read_text(encoding="utf-8"))
|
|
65
|
+
)
|
|
66
|
+
except (OSError, ValueError):
|
|
67
|
+
continue
|
|
68
|
+
return reports
|