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,395 @@
|
|
|
1
|
+
"""HTTP adapter for the EvalSmith-backed agent-eval dataset API."""
|
|
2
|
+
|
|
3
|
+
from __future__ import annotations
|
|
4
|
+
|
|
5
|
+
import asyncio
|
|
6
|
+
import json
|
|
7
|
+
import os
|
|
8
|
+
from typing import Any, Protocol
|
|
9
|
+
|
|
10
|
+
import httpx
|
|
11
|
+
|
|
12
|
+
from ksadk.common.kop_client import KOPClient, KOPError
|
|
13
|
+
|
|
14
|
+
from .cloud_converter import CloudDatasetColumn, CloudDatasetRow, CloudDatasetSnapshot
|
|
15
|
+
from .cloud_service import CloudEvalSetCatalogItem, CloudEvalSetPublishResult
|
|
16
|
+
from .service_env import resolve_agent_eval_direct_url, resolve_agent_eval_kop_connection
|
|
17
|
+
|
|
18
|
+
|
|
19
|
+
class AgentEvalCloudClientError(RuntimeError):
|
|
20
|
+
"""The agent-eval cloud dataset API rejected or could not process a request."""
|
|
21
|
+
|
|
22
|
+
|
|
23
|
+
class _KOPActionClient(Protocol):
|
|
24
|
+
def post_action(self, action: str, payload: dict[str, Any] | None = None) -> dict[str, Any]: ...
|
|
25
|
+
|
|
26
|
+
|
|
27
|
+
class AgentEvalCloudDatasetClient:
|
|
28
|
+
"""Publish immutable KsADK EvalSet snapshots through agent-eval and EvalSmith."""
|
|
29
|
+
|
|
30
|
+
_PUBLISH_PATH = "/agentengine/eval/api/v1/PublishEvaluationSetSnapshot"
|
|
31
|
+
_READ_PATH = "/agentengine/eval/api/v1/DescribeEvaluationSet"
|
|
32
|
+
_LIST_PATH = "/agentengine/eval/api/v1/ListEvaluationSet"
|
|
33
|
+
_READ_PAGE_SIZE = 200
|
|
34
|
+
_LIST_PAGE_SIZE = 100
|
|
35
|
+
|
|
36
|
+
def __init__(
|
|
37
|
+
self,
|
|
38
|
+
base_url: str | None = None,
|
|
39
|
+
*,
|
|
40
|
+
api_token: str | None = None,
|
|
41
|
+
account_id: str | None = None,
|
|
42
|
+
timeout_seconds: float = 30.0,
|
|
43
|
+
http_client: httpx.AsyncClient | None = None,
|
|
44
|
+
kop_client: _KOPActionClient | None = None,
|
|
45
|
+
) -> None:
|
|
46
|
+
explicit_base_url = str(base_url).strip().rstrip("/") if base_url is not None else None
|
|
47
|
+
if explicit_base_url is None:
|
|
48
|
+
explicit_base_url = resolve_agent_eval_direct_url()
|
|
49
|
+
self._base_url = explicit_base_url or ""
|
|
50
|
+
self._api_token = str(
|
|
51
|
+
api_token if api_token is not None else os.environ.get("AGENT_EVAL_API_TOKEN", "")
|
|
52
|
+
).strip()
|
|
53
|
+
self._account_id = str(
|
|
54
|
+
account_id
|
|
55
|
+
or os.environ.get("AGENT_EVAL_ACCOUNT_ID")
|
|
56
|
+
or os.environ.get("KSYUN_ACCOUNT_ID")
|
|
57
|
+
or ""
|
|
58
|
+
).strip()
|
|
59
|
+
self._timeout_seconds = timeout_seconds
|
|
60
|
+
self._http_client = http_client
|
|
61
|
+
self._kop_client: _KOPActionClient | None = None
|
|
62
|
+
if not self._base_url:
|
|
63
|
+
if http_client is not None:
|
|
64
|
+
raise ValueError("http_client requires AGENT_EVAL_BASE_URL direct mode")
|
|
65
|
+
connection = resolve_agent_eval_kop_connection()
|
|
66
|
+
self._kop_client = kop_client or KOPClient(
|
|
67
|
+
base_url=connection["base_url"],
|
|
68
|
+
access_key=os.environ.get("KSYUN_ACCESS_KEY"),
|
|
69
|
+
secret_key=os.environ.get("KSYUN_SECRET_KEY"),
|
|
70
|
+
account_id=os.environ.get("KSYUN_ACCOUNT_ID"),
|
|
71
|
+
region=connection["region"],
|
|
72
|
+
timeout=timeout_seconds,
|
|
73
|
+
)
|
|
74
|
+
elif kop_client is not None:
|
|
75
|
+
raise ValueError("kop_client cannot be used with AGENT_EVAL_BASE_URL direct mode")
|
|
76
|
+
|
|
77
|
+
@property
|
|
78
|
+
def uses_kop(self) -> bool:
|
|
79
|
+
return self._kop_client is not None
|
|
80
|
+
|
|
81
|
+
async def publish_snapshot(
|
|
82
|
+
self,
|
|
83
|
+
snapshot: CloudDatasetSnapshot,
|
|
84
|
+
*,
|
|
85
|
+
dataset_id: str | None,
|
|
86
|
+
base_version: int | None,
|
|
87
|
+
idempotency_key: str,
|
|
88
|
+
) -> CloudEvalSetPublishResult:
|
|
89
|
+
columns: list[dict[str, Any]] = []
|
|
90
|
+
for column in snapshot.columns:
|
|
91
|
+
item: dict[str, Any] = {
|
|
92
|
+
"Key": column.name,
|
|
93
|
+
"Name": column.name,
|
|
94
|
+
"ValueType": column.value_type,
|
|
95
|
+
"Required": column.required,
|
|
96
|
+
"Description": column.description,
|
|
97
|
+
}
|
|
98
|
+
if column.text_schema is not None:
|
|
99
|
+
item["TextSchema"] = column.text_schema
|
|
100
|
+
columns.append(item)
|
|
101
|
+
|
|
102
|
+
payload: dict[str, Any] = {
|
|
103
|
+
"Name": snapshot.name,
|
|
104
|
+
"Description": snapshot.description,
|
|
105
|
+
"Columns": columns,
|
|
106
|
+
"Rows": [
|
|
107
|
+
{"values": row.values, "split": "default", "source": "ksadk"}
|
|
108
|
+
for row in snapshot.rows
|
|
109
|
+
],
|
|
110
|
+
"ContentDigest": snapshot.content_digest,
|
|
111
|
+
"SchemaHash": snapshot.schema_hash,
|
|
112
|
+
"IdempotencyKey": idempotency_key,
|
|
113
|
+
}
|
|
114
|
+
if dataset_id:
|
|
115
|
+
payload["DatasetId"] = dataset_id
|
|
116
|
+
if base_version is not None:
|
|
117
|
+
payload["BaseVersion"] = base_version
|
|
118
|
+
data = await self._request(
|
|
119
|
+
"PublishEvaluationSetSnapshot",
|
|
120
|
+
self._PUBLISH_PATH,
|
|
121
|
+
payload,
|
|
122
|
+
)
|
|
123
|
+
try:
|
|
124
|
+
return CloudEvalSetPublishResult(
|
|
125
|
+
dataset_id=data["DatasetId"],
|
|
126
|
+
dataset_version=data["DatasetVersion"],
|
|
127
|
+
project_id=data.get("ProjectId"),
|
|
128
|
+
schema_hash=data["SchemaHash"],
|
|
129
|
+
content_digest=data["ContentDigest"],
|
|
130
|
+
row_count=data["RowCount"],
|
|
131
|
+
)
|
|
132
|
+
except (KeyError, TypeError, ValueError) as exc:
|
|
133
|
+
raise AgentEvalCloudClientError(
|
|
134
|
+
"agent-eval snapshot publish returned an invalid result"
|
|
135
|
+
) from exc
|
|
136
|
+
|
|
137
|
+
async def read_snapshot(
|
|
138
|
+
self,
|
|
139
|
+
dataset_id: str,
|
|
140
|
+
version: int,
|
|
141
|
+
*,
|
|
142
|
+
project_id: str | None = None,
|
|
143
|
+
) -> CloudDatasetSnapshot:
|
|
144
|
+
if not dataset_id.strip() or version < 1:
|
|
145
|
+
raise ValueError("datasetId and version must be valid")
|
|
146
|
+
del project_id # DescribeEvaluationSet resolves the project from the account context.
|
|
147
|
+
page = 1
|
|
148
|
+
first_page: dict[str, Any] | None = None
|
|
149
|
+
raw_items: list[dict[str, Any]] = []
|
|
150
|
+
while True:
|
|
151
|
+
data = await self._request(
|
|
152
|
+
"DescribeEvaluationSet",
|
|
153
|
+
self._READ_PATH,
|
|
154
|
+
{
|
|
155
|
+
"DatasetId": dataset_id,
|
|
156
|
+
"DatasetVersion": version,
|
|
157
|
+
"Page": page,
|
|
158
|
+
"PageSize": self._READ_PAGE_SIZE,
|
|
159
|
+
},
|
|
160
|
+
)
|
|
161
|
+
if first_page is None:
|
|
162
|
+
first_page = data
|
|
163
|
+
page_items = data.get("Items")
|
|
164
|
+
if not isinstance(page_items, list) or not all(
|
|
165
|
+
isinstance(item, dict) for item in page_items
|
|
166
|
+
):
|
|
167
|
+
raise AgentEvalCloudClientError("agent-eval snapshot read returned invalid items")
|
|
168
|
+
raw_items.extend(page_items)
|
|
169
|
+
if not data.get("HasMore"):
|
|
170
|
+
break
|
|
171
|
+
page += 1
|
|
172
|
+
|
|
173
|
+
assert first_page is not None
|
|
174
|
+
try:
|
|
175
|
+
current_version = int(first_page["CurrentVersion"])
|
|
176
|
+
if current_version != version:
|
|
177
|
+
raise ValueError("version mismatch")
|
|
178
|
+
raw_rows = [item["Row"] for item in raw_items]
|
|
179
|
+
rows = [CloudDatasetRow(values=dict(row)) for row in raw_rows if isinstance(row, dict)]
|
|
180
|
+
if len(rows) != len(raw_rows):
|
|
181
|
+
raise ValueError("invalid row")
|
|
182
|
+
expected_row_count = first_page.get("RowCount")
|
|
183
|
+
if expected_row_count is not None and int(expected_row_count) != len(rows):
|
|
184
|
+
raise ValueError("row count mismatch")
|
|
185
|
+
columns = [self._column_from_remote(column) for column in first_page["Columns"]]
|
|
186
|
+
content_digests = {
|
|
187
|
+
str(row.values.get("ksadk_content_digest") or "").strip() for row in rows
|
|
188
|
+
}
|
|
189
|
+
content_digests.discard("")
|
|
190
|
+
if len(content_digests) != 1:
|
|
191
|
+
raise ValueError("content digest mismatch")
|
|
192
|
+
source_formats = {str(row.values.get("source_format") or "").strip() for row in rows}
|
|
193
|
+
source_formats.discard("")
|
|
194
|
+
if len(source_formats) != 1:
|
|
195
|
+
raise ValueError("source format mismatch")
|
|
196
|
+
return CloudDatasetSnapshot(
|
|
197
|
+
name=first_page["Name"],
|
|
198
|
+
description=first_page.get("Description"),
|
|
199
|
+
content_digest=content_digests.pop(),
|
|
200
|
+
source_format=source_formats.pop(),
|
|
201
|
+
evalset_metadata={},
|
|
202
|
+
columns=columns,
|
|
203
|
+
rows=rows,
|
|
204
|
+
)
|
|
205
|
+
except (KeyError, TypeError, ValueError) as exc:
|
|
206
|
+
raise AgentEvalCloudClientError(
|
|
207
|
+
"agent-eval snapshot read returned an invalid result"
|
|
208
|
+
) from exc
|
|
209
|
+
|
|
210
|
+
async def list_datasets(
|
|
211
|
+
self,
|
|
212
|
+
*,
|
|
213
|
+
project_id: str | None = None,
|
|
214
|
+
) -> list[CloudEvalSetCatalogItem]:
|
|
215
|
+
payload: dict[str, Any] = {
|
|
216
|
+
"DatasetType": "Manual",
|
|
217
|
+
"Page": 1,
|
|
218
|
+
"PageSize": self._LIST_PAGE_SIZE,
|
|
219
|
+
}
|
|
220
|
+
if project_id:
|
|
221
|
+
payload["ProjectId"] = project_id
|
|
222
|
+
raw_items: list[dict[str, Any]] = []
|
|
223
|
+
while True:
|
|
224
|
+
data = await self._request("ListEvaluationSet", self._LIST_PATH, payload)
|
|
225
|
+
page_items = data.get("Items", data.get("items", data.get("EvaluationSets", [])))
|
|
226
|
+
if not isinstance(page_items, list):
|
|
227
|
+
raise AgentEvalCloudClientError("agent-eval dataset list returned invalid items")
|
|
228
|
+
raw_items.extend(item for item in page_items if isinstance(item, dict))
|
|
229
|
+
|
|
230
|
+
page = data.get("Page", payload["Page"])
|
|
231
|
+
page_size = data.get("PageSize", payload["PageSize"])
|
|
232
|
+
total = data.get("Total")
|
|
233
|
+
try:
|
|
234
|
+
has_next_page = bool(data.get("HasMore")) or (
|
|
235
|
+
total is not None and int(page) * int(page_size) < int(total)
|
|
236
|
+
)
|
|
237
|
+
except (TypeError, ValueError):
|
|
238
|
+
has_next_page = False
|
|
239
|
+
if not has_next_page:
|
|
240
|
+
break
|
|
241
|
+
payload["Page"] = int(payload["Page"]) + 1
|
|
242
|
+
items: list[CloudEvalSetCatalogItem] = []
|
|
243
|
+
for item in raw_items:
|
|
244
|
+
dataset_id = str(item.get("DatasetId", item.get("datasetId", ""))).strip()
|
|
245
|
+
version = item.get(
|
|
246
|
+
"Version",
|
|
247
|
+
item.get("version", item.get("CurrentVersion", item.get("currentVersion"))),
|
|
248
|
+
)
|
|
249
|
+
try:
|
|
250
|
+
version = int(version)
|
|
251
|
+
except (TypeError, ValueError):
|
|
252
|
+
continue
|
|
253
|
+
if not dataset_id or version < 1:
|
|
254
|
+
continue
|
|
255
|
+
|
|
256
|
+
schema_hash = item.get("SchemaHash", item.get("schemaHash"))
|
|
257
|
+
content_digest = item.get("ContentDigest", item.get("contentDigest"))
|
|
258
|
+
row_count = item.get("RowCount", item.get("rowCount"))
|
|
259
|
+
name = item.get("Name", item.get("name"))
|
|
260
|
+
item_project_id = item.get("ProjectId", item.get("projectId", project_id))
|
|
261
|
+
# Standard ListEvaluationSet omits KsADK's digest fields. Recover them
|
|
262
|
+
# from the immutable version and omit unrelated product datasets.
|
|
263
|
+
if not (
|
|
264
|
+
isinstance(schema_hash, str)
|
|
265
|
+
and len(schema_hash) == 64
|
|
266
|
+
and isinstance(content_digest, str)
|
|
267
|
+
and len(content_digest) == 64
|
|
268
|
+
):
|
|
269
|
+
try:
|
|
270
|
+
snapshot = await self.read_snapshot(
|
|
271
|
+
dataset_id,
|
|
272
|
+
version,
|
|
273
|
+
project_id=item_project_id,
|
|
274
|
+
)
|
|
275
|
+
except AgentEvalCloudClientError:
|
|
276
|
+
continue
|
|
277
|
+
schema_hash = snapshot.schema_hash
|
|
278
|
+
content_digest = snapshot.content_digest
|
|
279
|
+
row_count = len(snapshot.rows)
|
|
280
|
+
name = name or snapshot.name
|
|
281
|
+
try:
|
|
282
|
+
items.append(
|
|
283
|
+
CloudEvalSetCatalogItem(
|
|
284
|
+
dataset_id=dataset_id,
|
|
285
|
+
name=name,
|
|
286
|
+
project_id=item_project_id,
|
|
287
|
+
version=version,
|
|
288
|
+
schema_hash=schema_hash,
|
|
289
|
+
content_digest=content_digest,
|
|
290
|
+
row_count=row_count,
|
|
291
|
+
)
|
|
292
|
+
)
|
|
293
|
+
except (TypeError, ValueError):
|
|
294
|
+
continue
|
|
295
|
+
return items
|
|
296
|
+
|
|
297
|
+
async def _request(
|
|
298
|
+
self,
|
|
299
|
+
action: str,
|
|
300
|
+
path: str,
|
|
301
|
+
payload: dict[str, Any],
|
|
302
|
+
) -> dict[str, Any]:
|
|
303
|
+
if self._kop_client is not None:
|
|
304
|
+
try:
|
|
305
|
+
data = await asyncio.to_thread(self._kop_client.post_action, action, payload)
|
|
306
|
+
except KOPError as exc:
|
|
307
|
+
raise AgentEvalCloudClientError(
|
|
308
|
+
f"agent-eval KOP action {action} failed: {exc.message}"
|
|
309
|
+
) from exc
|
|
310
|
+
except Exception as exc:
|
|
311
|
+
raise AgentEvalCloudClientError(
|
|
312
|
+
f"agent-eval KOP action {action} failed"
|
|
313
|
+
) from exc
|
|
314
|
+
if not isinstance(data, dict):
|
|
315
|
+
raise AgentEvalCloudClientError(
|
|
316
|
+
f"agent-eval KOP action {action} returned invalid data"
|
|
317
|
+
)
|
|
318
|
+
return data
|
|
319
|
+
|
|
320
|
+
headers = {"Content-Type": "application/json"}
|
|
321
|
+
if self._api_token:
|
|
322
|
+
headers["Authorization"] = f"Bearer {self._api_token}"
|
|
323
|
+
if self._account_id:
|
|
324
|
+
headers["X-Ksc-Account-Id"] = self._account_id
|
|
325
|
+
try:
|
|
326
|
+
if self._http_client is not None:
|
|
327
|
+
response = await self._http_client.post(
|
|
328
|
+
f"{self._base_url}{path}", headers=headers, json=payload
|
|
329
|
+
)
|
|
330
|
+
else:
|
|
331
|
+
async with httpx.AsyncClient(
|
|
332
|
+
timeout=httpx.Timeout(self._timeout_seconds),
|
|
333
|
+
follow_redirects=False,
|
|
334
|
+
trust_env=False,
|
|
335
|
+
) as client:
|
|
336
|
+
response = await client.post(
|
|
337
|
+
f"{self._base_url}{path}", headers=headers, json=payload
|
|
338
|
+
)
|
|
339
|
+
except httpx.HTTPError as exc:
|
|
340
|
+
raise AgentEvalCloudClientError("agent-eval snapshot request failed") from exc
|
|
341
|
+
if response.status_code >= 400:
|
|
342
|
+
raise AgentEvalCloudClientError(
|
|
343
|
+
f"agent-eval snapshot request failed with HTTP {response.status_code}"
|
|
344
|
+
)
|
|
345
|
+
try:
|
|
346
|
+
envelope = response.json()
|
|
347
|
+
except ValueError as exc:
|
|
348
|
+
raise AgentEvalCloudClientError(
|
|
349
|
+
"agent-eval snapshot request returned invalid JSON"
|
|
350
|
+
) from exc
|
|
351
|
+
if not isinstance(envelope, dict) or envelope.get("Code") != 0:
|
|
352
|
+
raise AgentEvalCloudClientError("agent-eval snapshot request was rejected")
|
|
353
|
+
data = envelope.get("Data")
|
|
354
|
+
if not isinstance(data, dict):
|
|
355
|
+
raise AgentEvalCloudClientError("agent-eval request returned no result")
|
|
356
|
+
return data
|
|
357
|
+
|
|
358
|
+
@staticmethod
|
|
359
|
+
def _parse_text_schema(value: Any) -> dict[str, Any] | None:
|
|
360
|
+
if value is None:
|
|
361
|
+
return None
|
|
362
|
+
if isinstance(value, dict):
|
|
363
|
+
return value
|
|
364
|
+
if isinstance(value, str):
|
|
365
|
+
parsed = json.loads(value)
|
|
366
|
+
if isinstance(parsed, dict):
|
|
367
|
+
return parsed
|
|
368
|
+
raise ValueError("invalid text schema")
|
|
369
|
+
|
|
370
|
+
@staticmethod
|
|
371
|
+
def _normalize_value_type(value: Any) -> str:
|
|
372
|
+
normalized = str(value or "").strip()
|
|
373
|
+
if normalized.lower().startswith("array<"):
|
|
374
|
+
return "Array"
|
|
375
|
+
return normalized
|
|
376
|
+
|
|
377
|
+
@classmethod
|
|
378
|
+
def _column_from_remote(cls, column: dict[str, Any]) -> CloudDatasetColumn:
|
|
379
|
+
name = column.get("name") or column.get("Key") or column.get("Name")
|
|
380
|
+
text_schema = cls._parse_text_schema(
|
|
381
|
+
column.get("textSchema")
|
|
382
|
+
or column.get("TextSchema")
|
|
383
|
+
or column.get("textSchemaRaw")
|
|
384
|
+
or column.get("TextSchemaRaw")
|
|
385
|
+
)
|
|
386
|
+
value_type = cls._normalize_value_type(column.get("valueType") or column.get("ValueType"))
|
|
387
|
+
if text_schema == {"type": "string", "title": name}:
|
|
388
|
+
text_schema = None
|
|
389
|
+
return CloudDatasetColumn(
|
|
390
|
+
name=name,
|
|
391
|
+
value_type=value_type,
|
|
392
|
+
required=column.get("required", column.get("Required", False)),
|
|
393
|
+
description=column.get("description") or column.get("Description"),
|
|
394
|
+
text_schema=text_schema,
|
|
395
|
+
)
|
|
@@ -0,0 +1,80 @@
|
|
|
1
|
+
"""Local, atomic bindings between workspace EvalSets and cloud Dataset versions."""
|
|
2
|
+
|
|
3
|
+
from __future__ import annotations
|
|
4
|
+
|
|
5
|
+
import hashlib
|
|
6
|
+
from pathlib import Path
|
|
7
|
+
|
|
8
|
+
import yaml
|
|
9
|
+
from pydantic import Field, field_validator
|
|
10
|
+
|
|
11
|
+
from .contracts import EvaluationModel
|
|
12
|
+
|
|
13
|
+
|
|
14
|
+
class CloudBindingError(RuntimeError):
|
|
15
|
+
"""Raised when a cloud binding cannot be read or safely persisted."""
|
|
16
|
+
|
|
17
|
+
|
|
18
|
+
class CloudBinding(EvaluationModel):
|
|
19
|
+
"""Non-sensitive reference to one immutable cloud Dataset version."""
|
|
20
|
+
|
|
21
|
+
schema_version: str = "ksadk.eval.cloud/v1"
|
|
22
|
+
evalset_path: str = Field(min_length=1)
|
|
23
|
+
content_digest: str = Field(min_length=64, max_length=64)
|
|
24
|
+
provider: str = Field(min_length=1)
|
|
25
|
+
project_id: str | None = None
|
|
26
|
+
dataset_id: str = Field(min_length=1)
|
|
27
|
+
dataset_version: int = Field(ge=1)
|
|
28
|
+
schema_hash: str = Field(min_length=64, max_length=64)
|
|
29
|
+
|
|
30
|
+
@field_validator("evalset_path")
|
|
31
|
+
@classmethod
|
|
32
|
+
def validate_evalset_path(cls, value: str) -> str:
|
|
33
|
+
return _workspace_relative_path(value)
|
|
34
|
+
|
|
35
|
+
|
|
36
|
+
class CloudBindingStore:
|
|
37
|
+
"""Persist bindings under the workspace without accepting arbitrary output paths."""
|
|
38
|
+
|
|
39
|
+
def __init__(self, workspace_root: str | Path):
|
|
40
|
+
self.workspace_root = Path(workspace_root).expanduser().resolve()
|
|
41
|
+
self.root = self.workspace_root / ".agentkit" / "evaluation-bindings"
|
|
42
|
+
|
|
43
|
+
def binding_path(self, evalset_path: str) -> Path:
|
|
44
|
+
normalized = _workspace_relative_path(evalset_path)
|
|
45
|
+
file_name = hashlib.sha256(normalized.encode("utf-8")).hexdigest() + ".yaml"
|
|
46
|
+
return self.root / file_name
|
|
47
|
+
|
|
48
|
+
def write(self, binding: CloudBinding) -> Path:
|
|
49
|
+
path = self.binding_path(binding.evalset_path)
|
|
50
|
+
path.parent.mkdir(parents=True, exist_ok=True)
|
|
51
|
+
temporary = path.with_name(f".{path.name}.tmp")
|
|
52
|
+
payload = yaml.safe_dump(
|
|
53
|
+
binding.model_dump(mode="json", by_alias=True, exclude_none=True),
|
|
54
|
+
allow_unicode=True,
|
|
55
|
+
sort_keys=True,
|
|
56
|
+
)
|
|
57
|
+
try:
|
|
58
|
+
temporary.write_text(payload, encoding="utf-8")
|
|
59
|
+
temporary.replace(path)
|
|
60
|
+
except OSError as exc:
|
|
61
|
+
temporary.unlink(missing_ok=True)
|
|
62
|
+
raise CloudBindingError("云端评测集绑定写入失败") from exc
|
|
63
|
+
return path
|
|
64
|
+
|
|
65
|
+
def read(self, evalset_path: str) -> CloudBinding | None:
|
|
66
|
+
path = self.binding_path(evalset_path)
|
|
67
|
+
if not path.is_file():
|
|
68
|
+
return None
|
|
69
|
+
try:
|
|
70
|
+
loaded = yaml.safe_load(path.read_text(encoding="utf-8"))
|
|
71
|
+
return CloudBinding.model_validate(loaded)
|
|
72
|
+
except (OSError, ValueError, yaml.YAMLError) as exc:
|
|
73
|
+
raise CloudBindingError("云端评测集绑定损坏或不可读") from exc
|
|
74
|
+
|
|
75
|
+
|
|
76
|
+
def _workspace_relative_path(value: str) -> str:
|
|
77
|
+
candidate = Path(value)
|
|
78
|
+
if candidate.is_absolute() or ".." in candidate.parts or not candidate.parts:
|
|
79
|
+
raise CloudBindingError("EvalSet 路径必须位于工作区内")
|
|
80
|
+
return candidate.as_posix()
|
|
@@ -0,0 +1,194 @@
|
|
|
1
|
+
"""Lossless conversion between local EvalSets and cloud Dataset snapshots."""
|
|
2
|
+
|
|
3
|
+
from __future__ import annotations
|
|
4
|
+
|
|
5
|
+
import hashlib
|
|
6
|
+
import json
|
|
7
|
+
from typing import Any
|
|
8
|
+
|
|
9
|
+
from pydantic import Field, model_validator
|
|
10
|
+
|
|
11
|
+
from .contracts import EvalCase, EvalSetVersion, EvaluationModel
|
|
12
|
+
|
|
13
|
+
|
|
14
|
+
class EvalSetCloudConversionError(ValueError):
|
|
15
|
+
"""Raised when a cloud Dataset cannot be represented as an EvalSet."""
|
|
16
|
+
|
|
17
|
+
|
|
18
|
+
class CloudDatasetColumn(EvaluationModel):
|
|
19
|
+
"""A fixed cloud Dataset field used by the EvalSet converter."""
|
|
20
|
+
|
|
21
|
+
name: str = Field(min_length=1)
|
|
22
|
+
value_type: str = Field(min_length=1)
|
|
23
|
+
required: bool = False
|
|
24
|
+
description: str | None = None
|
|
25
|
+
text_schema: dict[str, Any] | None = None
|
|
26
|
+
|
|
27
|
+
|
|
28
|
+
class CloudDatasetRow(EvaluationModel):
|
|
29
|
+
"""One cloud Dataset row with its server-independent field values."""
|
|
30
|
+
|
|
31
|
+
values: dict[str, Any]
|
|
32
|
+
|
|
33
|
+
|
|
34
|
+
class CloudDatasetSnapshot(EvaluationModel):
|
|
35
|
+
"""A portable fixed Dataset version before it is sent to a cloud provider."""
|
|
36
|
+
|
|
37
|
+
name: str = Field(min_length=1, max_length=256)
|
|
38
|
+
description: str | None = None
|
|
39
|
+
content_digest: str = Field(min_length=64, max_length=64)
|
|
40
|
+
source_format: str = Field(min_length=1)
|
|
41
|
+
evalset_metadata: dict[str, Any] = Field(default_factory=dict)
|
|
42
|
+
columns: list[CloudDatasetColumn] = Field(min_length=1)
|
|
43
|
+
rows: list[CloudDatasetRow] = Field(min_length=1)
|
|
44
|
+
schema_hash: str = ""
|
|
45
|
+
|
|
46
|
+
@model_validator(mode="after")
|
|
47
|
+
def validate_schema_hash(self) -> "CloudDatasetSnapshot":
|
|
48
|
+
expected = _schema_hash(self.columns)
|
|
49
|
+
if self.schema_hash and self.schema_hash != expected:
|
|
50
|
+
raise ValueError("schemaHash 与列定义不一致")
|
|
51
|
+
self.schema_hash = expected
|
|
52
|
+
return self
|
|
53
|
+
|
|
54
|
+
|
|
55
|
+
_COLUMNS = (
|
|
56
|
+
CloudDatasetColumn(
|
|
57
|
+
name="case_id", value_type="String", required=True, description="KsADK Case ID"
|
|
58
|
+
),
|
|
59
|
+
CloudDatasetColumn(
|
|
60
|
+
name="turns",
|
|
61
|
+
value_type="Array",
|
|
62
|
+
required=True,
|
|
63
|
+
description="Ordered Eval turns",
|
|
64
|
+
text_schema={
|
|
65
|
+
"type": "array",
|
|
66
|
+
"items": {"type": "object", "additionalProperties": True},
|
|
67
|
+
},
|
|
68
|
+
),
|
|
69
|
+
CloudDatasetColumn(
|
|
70
|
+
name="assertions",
|
|
71
|
+
value_type="Array",
|
|
72
|
+
required=True,
|
|
73
|
+
description="Eval assertions",
|
|
74
|
+
text_schema={
|
|
75
|
+
"type": "array",
|
|
76
|
+
"items": {"type": "object", "additionalProperties": True},
|
|
77
|
+
},
|
|
78
|
+
),
|
|
79
|
+
CloudDatasetColumn(
|
|
80
|
+
name="case_metadata",
|
|
81
|
+
value_type="Object",
|
|
82
|
+
description="Case metadata",
|
|
83
|
+
text_schema={"type": "object", "additionalProperties": True},
|
|
84
|
+
),
|
|
85
|
+
CloudDatasetColumn(
|
|
86
|
+
name="source_format", value_type="String", required=True, description="Source format"
|
|
87
|
+
),
|
|
88
|
+
CloudDatasetColumn(
|
|
89
|
+
name="ksadk_content_digest",
|
|
90
|
+
value_type="String",
|
|
91
|
+
required=True,
|
|
92
|
+
description="Normalized EvalSet content digest",
|
|
93
|
+
),
|
|
94
|
+
)
|
|
95
|
+
_COLUMN_NAMES = tuple(column.name for column in _COLUMNS)
|
|
96
|
+
|
|
97
|
+
|
|
98
|
+
def evalset_to_dataset_snapshot(evalset: EvalSetVersion) -> CloudDatasetSnapshot:
|
|
99
|
+
"""Convert a normalized EvalSet into the single supported cloud Dataset schema."""
|
|
100
|
+
|
|
101
|
+
return CloudDatasetSnapshot(
|
|
102
|
+
name=evalset.name,
|
|
103
|
+
content_digest=evalset.content_digest,
|
|
104
|
+
source_format=evalset.source_format,
|
|
105
|
+
evalset_metadata=evalset.metadata,
|
|
106
|
+
columns=list(_COLUMNS),
|
|
107
|
+
rows=[
|
|
108
|
+
CloudDatasetRow(
|
|
109
|
+
values={
|
|
110
|
+
"case_id": case.id,
|
|
111
|
+
"turns": [turn.model_dump(mode="json", by_alias=True) for turn in case.turns],
|
|
112
|
+
"assertions": [
|
|
113
|
+
assertion.model_dump(mode="json", by_alias=True)
|
|
114
|
+
for assertion in case.assertions
|
|
115
|
+
],
|
|
116
|
+
"case_metadata": case.metadata,
|
|
117
|
+
"source_format": evalset.source_format,
|
|
118
|
+
"ksadk_content_digest": evalset.content_digest,
|
|
119
|
+
}
|
|
120
|
+
)
|
|
121
|
+
for case in evalset.cases
|
|
122
|
+
],
|
|
123
|
+
)
|
|
124
|
+
|
|
125
|
+
|
|
126
|
+
def evalset_from_dataset_snapshot(snapshot: CloudDatasetSnapshot) -> EvalSetVersion:
|
|
127
|
+
"""Restore an EvalSet from one fixed Dataset snapshot without losing supported data."""
|
|
128
|
+
|
|
129
|
+
_validate_columns(snapshot.columns)
|
|
130
|
+
cases: list[EvalCase] = []
|
|
131
|
+
source_formats: set[str] = set()
|
|
132
|
+
row_digests: set[str] = set()
|
|
133
|
+
for index, row in enumerate(snapshot.rows, start=1):
|
|
134
|
+
values = row.values
|
|
135
|
+
_validate_row(values, index)
|
|
136
|
+
source_formats.add(str(values["source_format"]))
|
|
137
|
+
row_digests.add(str(values["ksadk_content_digest"]))
|
|
138
|
+
try:
|
|
139
|
+
cases.append(
|
|
140
|
+
EvalCase.model_validate(
|
|
141
|
+
{
|
|
142
|
+
"id": values["case_id"],
|
|
143
|
+
"turns": values["turns"],
|
|
144
|
+
"assertions": values["assertions"],
|
|
145
|
+
"metadata": values["case_metadata"],
|
|
146
|
+
}
|
|
147
|
+
)
|
|
148
|
+
)
|
|
149
|
+
except ValueError as exc:
|
|
150
|
+
raise EvalSetCloudConversionError(f"第 {index} 行不能转换为 EvalCase") from exc
|
|
151
|
+
|
|
152
|
+
if len(source_formats) != 1 or snapshot.source_format not in source_formats:
|
|
153
|
+
raise EvalSetCloudConversionError("Rows 中的 source_format 必须与 Dataset snapshot 一致")
|
|
154
|
+
if row_digests != {snapshot.content_digest}:
|
|
155
|
+
raise EvalSetCloudConversionError(
|
|
156
|
+
"Rows 中的 ksadk_content_digest 必须与 Dataset snapshot 一致"
|
|
157
|
+
)
|
|
158
|
+
try:
|
|
159
|
+
return EvalSetVersion(
|
|
160
|
+
name=snapshot.name,
|
|
161
|
+
cases=cases,
|
|
162
|
+
metadata=snapshot.evalset_metadata,
|
|
163
|
+
source_format=snapshot.source_format,
|
|
164
|
+
content_digest=snapshot.content_digest,
|
|
165
|
+
)
|
|
166
|
+
except ValueError as exc:
|
|
167
|
+
raise EvalSetCloudConversionError("Dataset snapshot 内容无效") from exc
|
|
168
|
+
|
|
169
|
+
|
|
170
|
+
def _validate_columns(columns: list[CloudDatasetColumn]) -> None:
|
|
171
|
+
if [column.name for column in columns] != list(_COLUMN_NAMES):
|
|
172
|
+
raise EvalSetCloudConversionError("Dataset 列定义必须匹配 KsADK EvalSet 固定 schema")
|
|
173
|
+
for actual, expected in zip(columns, _COLUMNS):
|
|
174
|
+
if actual.value_type != expected.value_type or actual.required != expected.required:
|
|
175
|
+
raise EvalSetCloudConversionError(f"Dataset 列 {actual.name} 的类型或必填属性不匹配")
|
|
176
|
+
|
|
177
|
+
|
|
178
|
+
def _validate_row(values: dict[str, Any], index: int) -> None:
|
|
179
|
+
missing = [name for name in _COLUMN_NAMES if name not in values]
|
|
180
|
+
if missing:
|
|
181
|
+
raise EvalSetCloudConversionError(f"第 {index} 行缺少字段: {', '.join(missing)}")
|
|
182
|
+
unknown = sorted(set(values) - set(_COLUMN_NAMES))
|
|
183
|
+
if unknown:
|
|
184
|
+
raise EvalSetCloudConversionError(f"第 {index} 行包含未知字段: {', '.join(unknown)}")
|
|
185
|
+
|
|
186
|
+
|
|
187
|
+
def _schema_hash(columns: list[CloudDatasetColumn]) -> str:
|
|
188
|
+
payload = [
|
|
189
|
+
column.model_dump(mode="json", by_alias=True, exclude_none=True) for column in columns
|
|
190
|
+
]
|
|
191
|
+
encoded = json.dumps(payload, ensure_ascii=False, sort_keys=True, separators=(",", ":")).encode(
|
|
192
|
+
"utf-8"
|
|
193
|
+
)
|
|
194
|
+
return hashlib.sha256(encoded).hexdigest()
|