agentengine-sdk-python 0.8.1__py3-none-any.whl → 0.8.2__py3-none-any.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- {agentengine_sdk_python-0.8.1.dist-info → agentengine_sdk_python-0.8.2.dist-info}/METADATA +22 -2
- {agentengine_sdk_python-0.8.1.dist-info → agentengine_sdk_python-0.8.2.dist-info}/RECORD +356 -222
- ksadk/a2a/_space_client_events.py +381 -0
- ksadk/a2a/event_adapter.py +156 -64
- ksadk/a2a/executor.py +179 -63
- ksadk/a2a/space_client.py +6 -333
- ksadk/a2ui/core.py +222 -53
- ksadk/agui/_agent_helpers.py +243 -0
- ksadk/agui/a2ui_projection.py +12 -5
- ksadk/agui/agent.py +443 -259
- ksadk/api/client.py +525 -27
- ksadk/builders/code_builder.py +284 -8
- ksadk/builders/container_builder.py +8 -1
- ksadk/builders/managed_runtime_builder.py +39 -35
- ksadk/cli/__init__.py +17 -0
- ksadk/cli/cmd_dashboard.py +15 -1
- ksadk/cli/cmd_deploy.py +10 -2
- ksadk/cli/cmd_eval.py +66 -9
- ksadk/cli/cmd_evalset.py +284 -0
- ksadk/cli/cmd_files.py +5 -1
- ksadk/cli/cmd_hermes.py +1 -126
- ksadk/cli/cmd_invoke.py +28 -38
- ksadk/cli/cmd_managed_runtime.py +95 -0
- ksadk/cli/cmd_observe.py +85 -0
- ksadk/cli/cmd_openclaw.py +1 -435
- ksadk/cli/cmd_replay.py +28 -4
- ksadk/cli/cmd_studio.py +99 -8
- ksadk/cli/cmd_web.py +10 -2
- ksadk/cli/hermes_env.py +151 -0
- ksadk/cli/invoke_payload.py +49 -0
- ksadk/cli/openclaw_env.py +458 -0
- ksadk/codex/client.py +180 -30
- ksadk/codex/runtime.py +428 -326
- ksadk/configs/env_registry.py +66 -12
- ksadk/configs/env_registry_pcm.py +181 -0
- ksadk/configs/env_var_spec.py +18 -0
- ksadk/configs/global_config.py +5 -0
- ksadk/context_engine/__init__.py +98 -0
- ksadk/context_engine/assembler.py +176 -0
- ksadk/context_engine/baseline.py +419 -0
- ksadk/context_engine/cache_observability.py +228 -0
- ksadk/context_engine/capabilities.py +443 -0
- ksadk/context_engine/contributors.py +344 -0
- ksadk/context_engine/hosted_pipeline.py +417 -0
- ksadk/context_engine/models.py +117 -0
- ksadk/context_engine/planner.py +698 -0
- ksadk/context_engine/policies.py +319 -0
- ksadk/context_engine/projection.py +31 -0
- ksadk/context_engine/shadow_plan.py +266 -0
- ksadk/context_engine/tokenizer.py +164 -0
- ksadk/conversations/context.py +126 -6
- ksadk/conversations/message_projection.py +292 -28
- ksadk/conversations/model_context.py +49 -3
- ksadk/conversations/runtime_compaction.py +207 -5
- ksadk/conversations/runtime_input.py +184 -2
- ksadk/conversations/runtime_invocation.py +81 -3
- ksadk/conversations/runtime_observability.py +141 -0
- ksadk/conversations/runtime_payloads.py +42 -0
- ksadk/conversations/runtime_preparation.py +272 -2
- ksadk/conversations/runtime_resume.py +20 -1
- ksadk/conversations/runtime_stream_events.py +94 -9
- ksadk/conversations/semantic_summary.py +311 -1
- ksadk/conversations/session_lock.py +51 -0
- ksadk/deployment/env_forward.py +72 -0
- ksadk/deployment/managed_runtime.py +5 -0
- ksadk/deployment/providers/serverless.py +143 -69
- ksadk/evaluation/__init__.py +32 -0
- ksadk/evaluation/a2a_adapter.py +9 -1
- ksadk/evaluation/adapters.py +18 -5
- ksadk/evaluation/agent_eval_client.py +395 -0
- ksadk/evaluation/cloud_binding.py +80 -0
- ksadk/evaluation/cloud_converter.py +194 -0
- ksadk/evaluation/cloud_service.py +199 -0
- ksadk/evaluation/contracts.py +73 -4
- ksadk/evaluation/evaluators.py +183 -17
- ksadk/evaluation/evidence.py +258 -0
- ksadk/evaluation/executor.py +31 -6
- ksadk/evaluation/local_adapter.py +550 -0
- ksadk/evaluation/service_env.py +27 -0
- ksadk/evaluation/studio_build_adapter.py +253 -0
- ksadk/evaluation/target.py +15 -6
- ksadk/events/__init__.py +13 -13
- ksadk/events/_v1_compat/__init__.py +1 -0
- ksadk/events/_v1_compat/models.py +299 -0
- ksadk/events/_v1_compat/parser.py +247 -0
- ksadk/events/_v1_compat/projection.py +753 -0
- ksadk/events/adapters/__init__.py +34 -0
- ksadk/events/adapters/_a2a_snapshot.py +622 -0
- ksadk/events/adapters/_a2a_support.py +275 -0
- ksadk/events/adapters/_codex_interactions.py +375 -0
- ksadk/events/adapters/_codex_items.py +801 -0
- ksadk/events/adapters/_codex_validators.py +311 -0
- ksadk/events/adapters/_langgraph_support.py +785 -0
- ksadk/events/adapters/a2a.py +841 -0
- ksadk/events/adapters/adk.py +503 -0
- ksadk/events/adapters/codex.py +717 -0
- ksadk/events/adapters/langgraph.py +745 -0
- ksadk/events/canonical.py +440 -0
- ksadk/events/canonical_replay.py +497 -0
- ksadk/events/canonical_store.py +468 -0
- ksadk/events/cold_recovery.py +257 -0
- ksadk/events/content.py +89 -0
- ksadk/events/identity.py +86 -0
- ksadk/events/pipeline.py +455 -0
- ksadk/events/projections.py +66 -0
- ksadk/events/reducer.py +661 -0
- ksadk/events/replay.py +3 -36
- ksadk/events/runtime_event.py +20 -265
- ksadk/events/session_event.py +324 -0
- ksadk/events/store.py +3 -316
- ksadk/events/v1_compat.py +41 -0
- ksadk/harness/runtime.py +160 -57
- ksadk/identity/resolver.py +4 -3
- ksadk/interaction/__init__.py +28 -0
- ksadk/interaction/contracts.py +136 -0
- ksadk/interaction/ledger.py +189 -0
- ksadk/interaction/provider.py +122 -0
- ksadk/interaction/providers/__init__.py +52 -0
- ksadk/interaction/providers/adk.py +40 -0
- ksadk/interaction/providers/codex.py +94 -0
- ksadk/interaction/providers/langgraph.py +58 -0
- ksadk/kernel/__init__.py +117 -0
- ksadk/kernel/authorization.py +258 -0
- ksadk/kernel/bootstrap.py +1074 -0
- ksadk/kernel/contract_fingerprints.py +61 -0
- ksadk/kernel/contracts.py +362 -0
- ksadk/kernel/control.py +219 -0
- ksadk/kernel/errors.py +79 -0
- ksadk/kernel/ingress.py +1102 -0
- ksadk/kernel/mapping.py +111 -0
- ksadk/kernel/memory_store.py +1133 -0
- ksadk/kernel/postgres_store.py +1756 -0
- ksadk/kernel/recovery.py +452 -0
- ksadk/kernel/runtime_identity.py +103 -0
- ksadk/kernel/sql/001_agent_kernel.sql +120 -0
- ksadk/kernel/sqlite_store.py +1410 -0
- ksadk/kernel/state.py +145 -0
- ksadk/kernel/store.py +232 -0
- ksadk/kernel/worker.py +953 -0
- ksadk/knowledge_base/client.py +7 -0
- ksadk/knowledge_base/service.py +32 -5
- ksadk/memory/__init__.py +61 -0
- ksadk/memory/adk/backends/base_ltm_backend.py +96 -1
- ksadk/memory/adk/backends/http_ltm_backend.py +14 -5
- ksadk/memory/adk/backends/inmemory_ltm_backend.py +136 -3
- ksadk/memory/adk/backends/sdk_ltm_backend.py +384 -2
- ksadk/memory/adk/backends/sqlite_ltm_backend.py +95 -0
- ksadk/memory/coordinator.py +461 -0
- ksadk/memory/events.py +202 -0
- ksadk/memory/extraction.py +228 -0
- ksadk/memory/ltm_backend_factory.py +16 -3
- ksadk/memory/models.py +316 -0
- ksadk/memory/policy.py +215 -0
- ksadk/memory/provider.py +47 -0
- ksadk/memory/provider_adapter.py +159 -0
- ksadk/memory/provider_resolver.py +71 -0
- ksadk/memory/providers/__init__.py +5 -0
- ksadk/memory/providers/local_sqlite.py +490 -0
- ksadk/memory/resolved_policy.py +145 -0
- ksadk/memory/service.py +188 -6
- ksadk/model_proxy/bootstrap.py +16 -9
- ksadk/model_proxy/detect.py +202 -9
- ksadk/model_proxy/namespace.py +39 -15
- ksadk/model_proxy/server.py +24 -5
- ksadk/model_proxy/transform.py +60 -2
- ksadk/observability/__init__.py +25 -0
- ksadk/observability/session_log.py +420 -0
- ksadk/observability/trajectory.py +105 -0
- ksadk/prompts/__init__.py +71 -0
- ksadk/prompts/compiler.py +215 -0
- ksadk/prompts/models.py +82 -0
- ksadk/prompts/projection.py +89 -0
- ksadk/prompts/resolved.py +137 -0
- ksadk/prompts/sources.py +233 -0
- ksadk/runners/_langgraph_runner_streams.py +822 -0
- ksadk/runners/adk_runner.py +5 -5
- ksadk/runners/base_runner.py +16 -0
- ksadk/runners/factory.py +1 -2
- ksadk/runners/langgraph_runner.py +198 -437
- ksadk/runtime/_runner_adapter/__init__.py +1 -0
- ksadk/runtime/_runner_adapter/stream_mapping.py +788 -0
- ksadk/runtime/adapter.py +118 -2
- ksadk/runtime/conversation_execution.py +316 -182
- ksadk/runtime/executor.py +144 -3
- ksadk/runtime/factory.py +193 -7
- ksadk/runtime/hosted_finalizer.py +268 -0
- ksadk/runtime/launch.py +14 -1
- ksadk/runtime/preprocessing.py +25 -3
- ksadk/runtime/runner_adapter.py +288 -508
- ksadk/runtime/usage.py +33 -0
- ksadk/sandbox/backends/e2b.py +35 -2
- ksadk/server/composition.py +8 -0
- ksadk/server/factory.py +69 -6
- ksadk/server/routes/kernel_ingress.py +258 -0
- ksadk/server/routes/openai_compat.py +88 -8
- ksadk/server/routes/projection.py +35 -20
- ksadk/server/routes/run.py +94 -0
- ksadk/server/routes/sessions.py +2 -0
- ksadk/server/routes/streaming.py +5 -2
- ksadk/server/static/assets/{ArtifactsPanel-CakCqxEN.js → ArtifactsPanel-DSU1sWD_.js} +1 -1
- ksadk/server/static/assets/{CodeBlock-CynLknyO.js → CodeBlock-DOH6MVcn.js} +4 -4
- ksadk/server/static/assets/{MathMessageMarkdown-3sQdOysS.js → MathMessageMarkdown-BL8my1R2.js} +4 -4
- ksadk/server/static/assets/MathMessageMarkdown-BorAY7qD.css +1 -0
- ksadk/server/static/assets/MermaidBlock-Dz4IP-Tx.js +312 -0
- ksadk/server/static/assets/NativeTerminalPanel-DUrK0JpZ.js +1 -0
- ksadk/server/static/assets/abnfDiagram-VCTEODGH-g20pFzNV.js +1 -0
- ksadk/server/static/assets/arc-C4FzinUA.js +1 -0
- ksadk/server/static/assets/architecture-7GRP2DOG-DjKratdf.js +1 -0
- ksadk/server/static/assets/architectureDiagram-5GKGNRK7-DpIqL5h4.js +36 -0
- ksadk/server/static/assets/blockDiagram-NRAW4CY4-BjkljTNz.js +129 -0
- ksadk/server/static/assets/c4Diagram-UCG6FXSJ-Dk_ieq2X.js +38 -0
- ksadk/server/static/assets/channel-4cQHKtx1.js +1 -0
- ksadk/server/static/assets/chunk-2Q5K7J3B-DmgWkESh.js +1 -0
- ksadk/server/static/assets/{chunk-FMBD7UC4-B_fH2YuH.js → chunk-5VM5RSS4-BVHAchFb.js} +1 -1
- ksadk/server/static/assets/{chunk-ND2GUHAM-D6rFLaVV.js → chunk-F27PBJKO-C-ipQzuS.js} +1 -1
- ksadk/server/static/assets/chunk-G27WJ6UU-C2EyJbIK.js +231 -0
- ksadk/server/static/assets/{chunk-4BX2VUAB-B9drTgOW.js → chunk-JWPE2WC7-vYvVJb_M.js} +1 -1
- ksadk/server/static/assets/chunk-LCL6LL3I-BcI6ysPT.js +206 -0
- ksadk/server/static/assets/chunk-POPQ4Y6H-C030x_Z1.js +1 -0
- ksadk/server/static/assets/chunk-RHFEMEQ7-yyGpsz4n.js +168 -0
- ksadk/server/static/assets/chunk-SVP7TREG-BLTlmMU7.js +88 -0
- ksadk/server/static/assets/chunk-XXDRQBXY-C_32ArgP.js +1 -0
- ksadk/server/static/assets/classDiagram-DTDB5LWJ-DLFd9Xi0.js +1 -0
- ksadk/server/static/assets/classDiagram-v2-JRS7N3AN-DLFd9Xi0.js +1 -0
- ksadk/server/static/assets/{cose-bilkent-S5V4N54A-ChNs_Mdk.js → cose-bilkent-JH36ORCC-9YQYwdl0.js} +1 -1
- ksadk/server/static/assets/cynefin-OW5HDTMX-DjEM48Qp.js +1 -0
- ksadk/server/static/assets/cynefinDiagram-5FMLGOSQ-ErLF5N13.js +62 -0
- ksadk/server/static/assets/cytoscape.esm-CyCl8rPi.js +321 -0
- ksadk/server/static/assets/dagre-3AP2YEHR-DFiQF-6f.js +4 -0
- ksadk/server/static/assets/dagre-BuhGnRI1.js +1 -0
- ksadk/server/static/assets/diagram-S7CK7UJ4-Bt1v8-GC.js +30 -0
- ksadk/server/static/assets/diagram-UQ7AKVKN-DSCxJdBK.js +41 -0
- ksadk/server/static/assets/diagram-VSXAHHWV-DHfYwp_9.js +3 -0
- ksadk/server/static/assets/diagram-VX7I27RA-DdzD-4Le.js +24 -0
- ksadk/server/static/assets/diagram-Z3DM3KII-Du-nAJ9F.js +24 -0
- ksadk/server/static/assets/{dist-Dli7qW-B.js → dist-8hqcx0sU.js} +1 -1
- ksadk/server/static/assets/dist-B7seoj3d.js +1 -0
- ksadk/server/static/assets/{dist-C1sz5Eo3.js → dist-BE7bu-DL.js} +1 -1
- ksadk/server/static/assets/{dist-fhOuWds5.js → dist-BVDffZ0U.js} +1 -1
- ksadk/server/static/assets/{dist-BjOdlDjj.js → dist-BX8z72IC.js} +1 -1
- ksadk/server/static/assets/{dist-DsHPdk3W.js → dist-Bf2M8m3N.js} +1 -1
- ksadk/server/static/assets/{dist-o2OVmKvt.js → dist-BjU6y-A2.js} +1 -1
- ksadk/server/static/assets/{dist-DWKByxWV.js → dist-BytlxIDT.js} +1 -1
- ksadk/server/static/assets/{dist-DJN_6Y39.js → dist-CSh_DE14.js} +1 -1
- ksadk/server/static/assets/{dist-DQU9EWw-.js → dist-CXYYBw3_.js} +1 -1
- ksadk/server/static/assets/{dist-4N2NMVYg.js → dist-C_wsv-Qd.js} +1 -1
- ksadk/server/static/assets/{dist-gLnrGsoU.js → dist-ClxGviKw.js} +1 -1
- ksadk/server/static/assets/{dist-j6Dxmf_j.js → dist-CttYUqzS.js} +1 -1
- ksadk/server/static/assets/{dist-D6MpCZtz.js → dist-DNp6rLRA.js} +1 -1
- ksadk/server/static/assets/{dist-BB3-OwTQ.js → dist-DUX-id_F.js} +1 -1
- ksadk/server/static/assets/{dist-_pHPTyZ-.js → dist-DmldrHd_.js} +1 -1
- ksadk/server/static/assets/{dist-CWV4lDr1.js → dist-DnfXs8Vn.js} +2 -2
- ksadk/server/static/assets/{dist-B5oS1zcj.js → dist-Dq9gLD7L.js} +1 -1
- ksadk/server/static/assets/{dist-B-jNR6Vn.js → dist-W-TIVntx.js} +1 -1
- ksadk/server/static/assets/{dist-BIlKoW0k.js → dist-dDdADKFA.js} +1 -1
- ksadk/server/static/assets/{dist-X4TnqwOK.js → dist-dydu68Fl.js} +1 -1
- ksadk/server/static/assets/{dist-CmZHzlwZ.js → dist-ngtN0DJB.js} +1 -1
- ksadk/server/static/assets/ebnfDiagram-PWID7BFC-Da9C9NO1.js +1 -0
- ksadk/server/static/assets/erDiagram-SSCWMZ5O-EAGqqR79.js +99 -0
- ksadk/server/static/assets/eventmodeling-NTZA5JFV-CMgMaJrC.js +1 -0
- ksadk/server/static/assets/flowDiagram-A5DVABFB-BBKL0x3P.js +1 -0
- ksadk/server/static/assets/ganttDiagram-EL5Y4UJY-DqJsKb59.js +292 -0
- ksadk/server/static/assets/gitGraph-4MIJSDKK-Dw63mrhw.js +1 -0
- ksadk/server/static/assets/gitGraphDiagram-WWUBYQGX-B6g4dtDi.js +106 -0
- ksadk/server/static/assets/index-8ipRcQ-M.js +240 -0
- ksadk/server/static/assets/index-ByFCqjlh.css +2 -0
- ksadk/server/static/assets/info-A6RAGUB7-B6iAblII.js +1 -0
- ksadk/server/static/assets/infoDiagram-RXCK75RN-Djm_nbd5.js +2 -0
- ksadk/server/static/assets/{ishikawaDiagram-YF4QCWOH-K0OOfVna.js → ishikawaDiagram-5VMMS53U-DWya9SG2.js} +6 -6
- ksadk/server/static/assets/{journeyDiagram-JHISSGLW-8LeOJaZp.js → journeyDiagram-EYS64GPL-DutxhSNI.js} +6 -6
- ksadk/server/static/assets/{kanban-definition-UN3LZRKU-C6uCgZrW.js → kanban-definition-3QL26DDD-DJdOF8Fm.js} +10 -10
- ksadk/server/static/assets/katex-vFWytM5c.js +257 -0
- ksadk/server/static/assets/{linear-hdBcYzM8.js → linear-BHjG8b-J.js} +1 -1
- ksadk/server/static/assets/mermaid-parser.core-KGSy4jWT.js +166 -0
- ksadk/server/static/assets/{mindmap-definition-RKZ34NQL-Bjy_2v4_.js → mindmap-definition-FBJOCRG2-9-HC88D4.js} +29 -29
- ksadk/server/static/assets/packet-AYTQ26CC-BOYAipuq.js +1 -0
- ksadk/server/static/assets/pegDiagram-XKGWAZYB-DrEZd4fD.js +1 -0
- ksadk/server/static/assets/pie-WAS4IAKB-Ctq0Kbku.js +1 -0
- ksadk/server/static/assets/pieDiagram-E7YTZNPT-DpjqOFFp.js +39 -0
- ksadk/server/static/assets/{quadrantDiagram-W4KKPZXB-BmkRbwCg.js → quadrantDiagram-AXDQQJYC-BiNhgOXX.js} +6 -6
- ksadk/server/static/assets/radar-RG4KPBEZ-DN0-ul_0.js +1 -0
- ksadk/server/static/assets/railroad-74A4TZTK-C6cC_to0.js +1 -0
- ksadk/server/static/assets/railroad-abnf-HS5TGJTU-BimjIuRc.js +1 -0
- ksadk/server/static/assets/railroad-ebnf-LZEXJU2U-CvY65ABq.js +1 -0
- ksadk/server/static/assets/railroad-peg-WCYAUIDC-D72Iq_Tv.js +1 -0
- ksadk/server/static/assets/railroadDiagram-O6MQD6OU-_Y3Ojg6G.js +1 -0
- ksadk/server/static/assets/requirementDiagram-EFPCY7ZU-DeCFdg9K.js +84 -0
- ksadk/server/static/assets/{sankeyDiagram-5OEKKPKP-l6iXmU65.js → sankeyDiagram-P5KCCOFB-CPH75rhw.js} +7 -7
- ksadk/server/static/assets/{sequenceDiagram-3UESZ5HK-Cq6UBeQB.js → sequenceDiagram-WJ2MYXX4-OEpQQdr4.js} +10 -10
- ksadk/server/static/assets/sizeCapture-X5ZJPWSS-heUErzhI.js +1 -0
- ksadk/server/static/assets/stateDiagram-HBIQ2CUA-DvA3jSMB.js +1 -0
- ksadk/server/static/assets/stateDiagram-v2-4QOOHH4V-BgQY03nz.js +1 -0
- ksadk/server/static/assets/swimlanes-XN3QIQJK-CR-dfN_t.js +1 -0
- ksadk/server/static/assets/swimlanesDiagram-VK2B7HYN-DLVw3q5Q.js +8 -0
- ksadk/server/static/assets/{timeline-definition-PNZ67QCA-DEz24vV0.js → timeline-definition-24CTP7MA-DAVJf1TX.js} +7 -7
- ksadk/server/static/assets/treeView-Q6P3EWNA-BMpO0wsB.js +1 -0
- ksadk/server/static/assets/treemap-WGGIJYW6-Et0aqzU3.js +1 -0
- ksadk/server/static/assets/vennDiagram-4TSXK5OY-DwM8eDkh.js +34 -0
- ksadk/server/static/assets/wardley-WFR3VGLG-CbY0mhpl.js +1 -0
- ksadk/server/static/assets/wardleyDiagram-VM6X3IG4-DZL-Zz2t.js +78 -0
- ksadk/server/static/assets/xychartDiagram-S5SC5T6Z-Dy6Yh_hu.js +7 -0
- ksadk/server/static/index.html +2 -2
- ksadk/sessions/__init__.py +26 -9
- ksadk/sessions/_local_service_sync.py +688 -0
- ksadk/sessions/_local_tables.py +21 -0
- ksadk/sessions/_postgres_schema.py +305 -0
- ksadk/sessions/_postgres_tables.py +15 -0
- ksadk/sessions/base.py +80 -1
- ksadk/sessions/in_memory.py +53 -2
- ksadk/sessions/local_service.py +63 -604
- ksadk/sessions/postgres_service.py +58 -148
- ksadk/sessions/resilient.py +35 -1
- ksadk/studio/api.py +577 -25
- ksadk/studio/api_contracts.py +114 -5
- ksadk/studio/api_memory_routes.py +82 -0
- ksadk/studio/authoring.py +252 -27
- ksadk/studio/authoring_coordinator.py +799 -67
- ksadk/studio/builder.py +88 -11
- ksadk/studio/capabilities.py +17 -0
- ksadk/studio/cloud.py +1916 -95
- ksadk/studio/codex_agent_service.py +125 -14
- ksadk/studio/codex_authoring.py +469 -0
- ksadk/studio/codex_builder.py +138 -25
- ksadk/studio/codex_manifest.py +51 -22
- ksadk/studio/codex_run.py +46 -3
- ksadk/studio/compiler.py +1 -0
- ksadk/studio/contracts.py +114 -3
- ksadk/studio/event_store.py +25 -95
- ksadk/studio/framework_run.py +231 -3
- ksadk/studio/hosted_kernel.py +317 -0
- ksadk/studio/manifest_resolver.py +131 -0
- ksadk/studio/model_client.py +95 -9
- ksadk/studio/model_profile_service.py +1 -1
- ksadk/studio/operations.py +37 -5
- ksadk/studio/otel_trace.py +348 -42
- ksadk/studio/pcm_memory.py +85 -0
- ksadk/studio/repository.py +23 -2
- ksadk/studio/resource_catalog.py +43 -0
- ksadk/studio/run_service.py +563 -137
- ksadk/studio/runtime_source.py +42 -16
- ksadk/studio/service.py +1180 -72
- ksadk/studio/shared_web.py +32 -22
- ksadk/studio/static/assets/index-BLpcdrgW.css +1 -0
- ksadk/studio/static/assets/index-CYekR2Xv.js +260 -0
- ksadk/studio/static/index.html +2 -2
- ksadk/studio/templates.py +100 -8
- ksadk/studio/validator.py +19 -0
- ksadk/studio/workspace.py +30 -32
- ksadk/tracing/setup.py +304 -3
- ksadk/version.py +1 -1
- ksadk_runtime_common/schemas/runtime_event_v1.json +37 -0
- ksadk_runtime_common/schemas/runtime_event_v2.json +271 -0
- ksadk/events/parser.py +0 -191
- ksadk/server/static/assets/MathMessageMarkdown-DeYh8QPr.css +0 -1
- ksadk/server/static/assets/MermaidBlock-NERD_ef7.js +0 -303
- ksadk/server/static/assets/NativeTerminalPanel-CiHWf82q.js +0 -1
- ksadk/server/static/assets/arc-DrgjcKhl.js +0 -1
- ksadk/server/static/assets/architecture-7EHR7CIX-CpZLRCcY.js +0 -1
- ksadk/server/static/assets/architectureDiagram-3BPJPVTR-BXoVRbQ6.js +0 -36
- ksadk/server/static/assets/blockDiagram-GPEHLZMM-BnaB3Ywv.js +0 -132
- ksadk/server/static/assets/c4Diagram-AAUBKEIU-Dw4weZcp.js +0 -10
- ksadk/server/static/assets/channel-Dt3rQTFI.js +0 -1
- ksadk/server/static/assets/chunk-2J33WTMH-ChjpLK7j.js +0 -1
- ksadk/server/static/assets/chunk-55IACEB6-CK4ROATy.js +0 -1
- ksadk/server/static/assets/chunk-727SXJPM-B9KtTTgw.js +0 -206
- ksadk/server/static/assets/chunk-AQP2D5EJ-1O1mki3m.js +0 -231
- ksadk/server/static/assets/chunk-QZHKN3VN-iXEZtKQc.js +0 -1
- ksadk/server/static/assets/classDiagram-4FO5ZUOK-DIveV17Q.js +0 -1
- ksadk/server/static/assets/classDiagram-v2-Q7XG4LA2-DIveV17Q.js +0 -1
- ksadk/server/static/assets/cytoscape.esm-DelgaX4f.js +0 -321
- ksadk/server/static/assets/dagre-BM42HDAG-D0QXg_MQ.js +0 -4
- ksadk/server/static/assets/dagre-Bx709z4p.js +0 -1
- ksadk/server/static/assets/diagram-2AECGRRQ-DBDDKwBQ.js +0 -43
- ksadk/server/static/assets/diagram-5GNKFQAL-BkwDOxmO.js +0 -10
- ksadk/server/static/assets/diagram-KO2AKTUF-Bv8waYvY.js +0 -3
- ksadk/server/static/assets/diagram-LMA3HP47-e1VECDdu.js +0 -24
- ksadk/server/static/assets/diagram-OG6HWLK6-Ds9adfRl.js +0 -24
- ksadk/server/static/assets/dist-B5J2uhNk.js +0 -1
- ksadk/server/static/assets/erDiagram-TEJ5UH35-BPItFKH6.js +0 -85
- ksadk/server/static/assets/eventmodeling-FCH6USID-DYFSxbqr.js +0 -1
- ksadk/server/static/assets/flowDiagram-I6XJVG4X-BbYB9w5Y.js +0 -162
- ksadk/server/static/assets/ganttDiagram-6RSMTGT7-TQXa0KXv.js +0 -292
- ksadk/server/static/assets/gitGraph-WXDBUCRP-DyNYp6BN.js +0 -1
- ksadk/server/static/assets/gitGraphDiagram-PVQCEYII-bKblCnpa.js +0 -106
- ksadk/server/static/assets/graphlib-B8gBHxth.js +0 -1
- ksadk/server/static/assets/index-R52pJJvg.js +0 -177
- ksadk/server/static/assets/index-jJr3_955.css +0 -2
- ksadk/server/static/assets/info-J43DQDTF-WUx7qTde.js +0 -1
- ksadk/server/static/assets/infoDiagram-5YYISTIA-BGVT7J_i.js +0 -2
- ksadk/server/static/assets/katex-CYWseY5E.js +0 -265
- ksadk/server/static/assets/mermaid-parser.core-BWrDjSZM.js +0 -161
- ksadk/server/static/assets/packet-YPE3B663-BN13y_xl.js +0 -1
- ksadk/server/static/assets/pie-LRSECV5Y-ftSLXhhc.js +0 -1
- ksadk/server/static/assets/pieDiagram-4H26LBE5-GmmqNiVH.js +0 -30
- ksadk/server/static/assets/radar-GUYGQ44K-jaICkIeO.js +0 -1
- ksadk/server/static/assets/requirementDiagram-4Y6WPE33-DSWFqL7c.js +0 -84
- ksadk/server/static/assets/stateDiagram-AJRCARHV-qzTQpg3Y.js +0 -1
- ksadk/server/static/assets/stateDiagram-v2-BHNVJYJU-BYCoYGAN.js +0 -1
- ksadk/server/static/assets/treeView-BLDUP644-Cpib_vlz.js +0 -1
- ksadk/server/static/assets/treemap-LRROVOQU-DQxfmVHK.js +0 -1
- ksadk/server/static/assets/vennDiagram-CIIHVFJN-CMCixki2.js +0 -34
- ksadk/server/static/assets/wardley-L42UT6IY-BQYHnnkU.js +0 -1
- ksadk/server/static/assets/wardleyDiagram-YWT4CUSO-CVzB8F9K.js +0 -78
- ksadk/server/static/assets/xychartDiagram-2RQKCTM6-BFBqBLc1.js +0 -7
- ksadk/studio/evaluation.py +0 -192
- ksadk/studio/static/assets/index-CaEN0eTR.css +0 -1
- ksadk/studio/static/assets/index-DI2eY_NH.js +0 -252
- {agentengine_sdk_python-0.8.1.dist-info → agentengine_sdk_python-0.8.2.dist-info}/WHEEL +0 -0
- {agentengine_sdk_python-0.8.1.dist-info → agentengine_sdk_python-0.8.2.dist-info}/entry_points.txt +0 -0
- {agentengine_sdk_python-0.8.1.dist-info → agentengine_sdk_python-0.8.2.dist-info}/licenses/LICENSE +0 -0
- {agentengine_sdk_python-0.8.1.dist-info → agentengine_sdk_python-0.8.2.dist-info}/top_level.txt +0 -0
ksadk/api/client.py
CHANGED
|
@@ -4,6 +4,7 @@ AgentEngine Server API 客户端
|
|
|
4
4
|
支持 AWS V4 签名认证,用于通过 KOP 网关访问 AgentEngine Server。
|
|
5
5
|
"""
|
|
6
6
|
|
|
7
|
+
import asyncio
|
|
7
8
|
import json
|
|
8
9
|
import logging
|
|
9
10
|
import mimetypes
|
|
@@ -14,7 +15,7 @@ import uuid
|
|
|
14
15
|
from contextlib import contextmanager
|
|
15
16
|
from dataclasses import dataclass
|
|
16
17
|
from pathlib import Path
|
|
17
|
-
from typing import Any, Callable, Dict, Iterator, Optional, Sequence
|
|
18
|
+
from typing import Any, AsyncIterator, Callable, Dict, Iterator, Optional, Sequence
|
|
18
19
|
from urllib.parse import quote, unquote, urlparse, urlsplit
|
|
19
20
|
|
|
20
21
|
import requests
|
|
@@ -36,6 +37,69 @@ class AttachmentContent:
|
|
|
36
37
|
display_name: str
|
|
37
38
|
|
|
38
39
|
|
|
40
|
+
def _next_stream_chunk(iterator: Iterator[bytes]) -> bytes | None:
|
|
41
|
+
"""Read one non-empty requests chunk without leaking StopIteration to asyncio."""
|
|
42
|
+
|
|
43
|
+
while True:
|
|
44
|
+
try:
|
|
45
|
+
chunk = next(iterator)
|
|
46
|
+
except StopIteration:
|
|
47
|
+
return None
|
|
48
|
+
if chunk:
|
|
49
|
+
return chunk
|
|
50
|
+
|
|
51
|
+
|
|
52
|
+
class AgentEngineSSEStream(AsyncIterator[bytes]):
|
|
53
|
+
"""Async owner for one dedicated blocking requests SSE connection."""
|
|
54
|
+
|
|
55
|
+
def __init__(self, response: requests.Response, session: requests.Session) -> None:
|
|
56
|
+
self._response: requests.Response | None = response
|
|
57
|
+
self._session: requests.Session | None = session
|
|
58
|
+
# Read SSE as logical lines with the smallest requests read size. A
|
|
59
|
+
# fixed 8 KiB ``iter_content`` block makes short runs appear
|
|
60
|
+
# non-streaming, while ``chunk_size=None`` waits for EOF on urllib3.
|
|
61
|
+
# ``iter_lines`` performs the byte-at-a-time buffering inside the
|
|
62
|
+
# blocking worker and yields complete lines, avoiding one thread hop
|
|
63
|
+
# per byte. Re-add the delimiter so downstream SSE parsers keep their
|
|
64
|
+
# normal framing, including the blank line between events.
|
|
65
|
+
self._chunks = (line + b"\n" for line in response.iter_lines(chunk_size=1))
|
|
66
|
+
self._closed = False
|
|
67
|
+
|
|
68
|
+
def __aiter__(self) -> "AgentEngineSSEStream":
|
|
69
|
+
return self
|
|
70
|
+
|
|
71
|
+
async def __anext__(self) -> bytes:
|
|
72
|
+
if self._closed:
|
|
73
|
+
raise StopAsyncIteration
|
|
74
|
+
try:
|
|
75
|
+
chunk = await asyncio.to_thread(_next_stream_chunk, self._chunks)
|
|
76
|
+
except BaseException:
|
|
77
|
+
await self.aclose()
|
|
78
|
+
raise
|
|
79
|
+
if chunk is None:
|
|
80
|
+
await self.aclose()
|
|
81
|
+
raise StopAsyncIteration
|
|
82
|
+
return chunk
|
|
83
|
+
|
|
84
|
+
async def aclose(self) -> None:
|
|
85
|
+
if self._closed:
|
|
86
|
+
return
|
|
87
|
+
self._closed = True
|
|
88
|
+
response, session = self._response, self._session
|
|
89
|
+
self._response = None
|
|
90
|
+
self._session = None
|
|
91
|
+
|
|
92
|
+
def close_transport() -> None:
|
|
93
|
+
try:
|
|
94
|
+
if response is not None:
|
|
95
|
+
response.close()
|
|
96
|
+
finally:
|
|
97
|
+
if session is not None:
|
|
98
|
+
session.close()
|
|
99
|
+
|
|
100
|
+
await asyncio.to_thread(close_transport)
|
|
101
|
+
|
|
102
|
+
|
|
39
103
|
class DryRunExit(Exception):
|
|
40
104
|
"""DryRun 模式退出异常。"""
|
|
41
105
|
|
|
@@ -127,7 +191,16 @@ class AgentEngineClient:
|
|
|
127
191
|
logger.debug("AgentEngineClient: No credentials, signing disabled")
|
|
128
192
|
|
|
129
193
|
self._session: Optional[requests.Session] = None
|
|
194
|
+
# The public client keeps synchronous ``requests`` transport for CLI
|
|
195
|
+
# compatibility. Async callers (notably Studio's FastAPI process)
|
|
196
|
+
# must not run that transport on the event-loop thread, and the shared
|
|
197
|
+
# requests.Session must not be used by several worker threads at once.
|
|
198
|
+
self._async_action_lock = asyncio.Lock()
|
|
130
199
|
self._http_error_log_suppressors: list[HttpErrorLogSuppressor] = []
|
|
200
|
+
# A Server Action can be deployed before the external KOP publication
|
|
201
|
+
# finishes. Remember that result per client so an approval retry does
|
|
202
|
+
# not repeatedly hit the known-unpublished control-plane route.
|
|
203
|
+
self._unpublished_kop_actions: set[str] = set()
|
|
131
204
|
# 反查身份的实例缓存(避免同会话重复调 IAM);None=未尝试,ResolvedIdentity|None=已反查
|
|
132
205
|
self._resolved_identity: Any = None
|
|
133
206
|
self._identity_resolve_attempted: bool = False
|
|
@@ -708,6 +781,17 @@ class AgentEngineClient:
|
|
|
708
781
|
self._session.close()
|
|
709
782
|
self._session = None
|
|
710
783
|
|
|
784
|
+
async def _action_async(
|
|
785
|
+
self,
|
|
786
|
+
action: str,
|
|
787
|
+
params: Optional[Dict[str, Any]] = None,
|
|
788
|
+
**kwargs: Any,
|
|
789
|
+
) -> Dict[str, Any]:
|
|
790
|
+
"""Run the legacy blocking Action transport without freezing an event loop."""
|
|
791
|
+
|
|
792
|
+
async with self._async_action_lock:
|
|
793
|
+
return await asyncio.to_thread(self._action, action, params, **kwargs)
|
|
794
|
+
|
|
711
795
|
async def __aenter__(self):
|
|
712
796
|
return self
|
|
713
797
|
|
|
@@ -912,6 +996,83 @@ class AgentEngineClient:
|
|
|
912
996
|
)
|
|
913
997
|
return AgentEngineAPIError(response.status_code, message)
|
|
914
998
|
|
|
999
|
+
@staticmethod
|
|
1000
|
+
def _is_unregistered_kop_action(error: AgentEngineAPIError, action: str) -> bool:
|
|
1001
|
+
"""Return whether KOP rejected an otherwise valid Server Action.
|
|
1002
|
+
|
|
1003
|
+
Public Action publication is an infrastructure step independent of a
|
|
1004
|
+
Server rollout. During that window the per-Agent Gateway route is
|
|
1005
|
+
already authenticated and still forwards the exact same Action to
|
|
1006
|
+
Server admission, so callers can safely use it as the data-plane
|
|
1007
|
+
fallback instead of losing an approval response.
|
|
1008
|
+
"""
|
|
1009
|
+
|
|
1010
|
+
message = str(error.message or "").strip().lower()
|
|
1011
|
+
return (
|
|
1012
|
+
error.code == 400
|
|
1013
|
+
and f"action {action.lower()}" in message
|
|
1014
|
+
and "not valid for this web service" in message
|
|
1015
|
+
)
|
|
1016
|
+
|
|
1017
|
+
def _runtime_action(
|
|
1018
|
+
self,
|
|
1019
|
+
*,
|
|
1020
|
+
access: Dict[str, Any],
|
|
1021
|
+
action: str,
|
|
1022
|
+
params: Dict[str, Any],
|
|
1023
|
+
) -> Dict[str, Any]:
|
|
1024
|
+
endpoint = str(access.get("endpoint") or "").strip().rstrip("/")
|
|
1025
|
+
api_key = str(access.get("api_key") or "").strip()
|
|
1026
|
+
if not endpoint or not api_key:
|
|
1027
|
+
raise AgentEngineAPIError(404, "Agent runtime access is not ready")
|
|
1028
|
+
response = self._get_session().request(
|
|
1029
|
+
method="POST",
|
|
1030
|
+
url=f"{endpoint}/agentengine/api/v1/{action}",
|
|
1031
|
+
headers={"Authorization": f"Bearer {api_key}"},
|
|
1032
|
+
json=params,
|
|
1033
|
+
timeout=self.timeout,
|
|
1034
|
+
verify=self._ssl_verify_enabled(),
|
|
1035
|
+
)
|
|
1036
|
+
if response.status_code >= 400:
|
|
1037
|
+
raise self._workspace_runtime_error(response)
|
|
1038
|
+
try:
|
|
1039
|
+
result = response.json()
|
|
1040
|
+
except Exception as exc:
|
|
1041
|
+
raise AgentEngineAPIError(502, "Runtime Action returned invalid JSON") from exc
|
|
1042
|
+
if not isinstance(result, dict):
|
|
1043
|
+
raise AgentEngineAPIError(502, "Runtime Action returned a non-object payload")
|
|
1044
|
+
code = result.get("Code", 0)
|
|
1045
|
+
if code != 0:
|
|
1046
|
+
raise AgentEngineAPIError(
|
|
1047
|
+
code,
|
|
1048
|
+
str(result.get("Message") or "Unknown API error"),
|
|
1049
|
+
details={
|
|
1050
|
+
"request_id": result.get("RequestId"),
|
|
1051
|
+
"action": result.get("Action") or action,
|
|
1052
|
+
},
|
|
1053
|
+
)
|
|
1054
|
+
data = result.get("Data") if result.get("Data") is not None else result
|
|
1055
|
+
normalized = self._to_snake_case(data)
|
|
1056
|
+
if not isinstance(normalized, dict):
|
|
1057
|
+
raise AgentEngineAPIError(502, "Runtime Action returned non-object Data")
|
|
1058
|
+
return normalized
|
|
1059
|
+
|
|
1060
|
+
async def _runtime_action_for_agent(
|
|
1061
|
+
self,
|
|
1062
|
+
*,
|
|
1063
|
+
agent_id: str,
|
|
1064
|
+
action: str,
|
|
1065
|
+
params: Dict[str, Any],
|
|
1066
|
+
) -> Dict[str, Any]:
|
|
1067
|
+
detail = await self.get_agent(agent_id, include_api_key=True)
|
|
1068
|
+
access = self._extract_runtime_access(detail)
|
|
1069
|
+
return await asyncio.to_thread(
|
|
1070
|
+
self._runtime_action,
|
|
1071
|
+
access=access,
|
|
1072
|
+
action=action,
|
|
1073
|
+
params=params,
|
|
1074
|
+
)
|
|
1075
|
+
|
|
915
1076
|
@staticmethod
|
|
916
1077
|
def _compact_params(params: Dict[str, Any] | None) -> Dict[str, Any]:
|
|
917
1078
|
return {key: value for key, value in (params or {}).items() if value is not None}
|
|
@@ -1310,8 +1471,45 @@ class AgentEngineClient:
|
|
|
1310
1471
|
payload[key] = text
|
|
1311
1472
|
return payload
|
|
1312
1473
|
|
|
1474
|
+
@staticmethod
|
|
1475
|
+
def _managed_runtime_config_payload(data: Dict[str, Any]) -> Dict[str, Any]:
|
|
1476
|
+
"""Build the public declaration accepted by Server Create/UpdateAgent.
|
|
1477
|
+
|
|
1478
|
+
``runtime_config`` remains readable for older SDK callers, but it is a
|
|
1479
|
+
resolved read-model. New callers must send ``managed_runtime_config``
|
|
1480
|
+
so retries carry the complete YAML declaration Server needs to resolve
|
|
1481
|
+
a compatible immutable runtime image.
|
|
1482
|
+
"""
|
|
1483
|
+
declaration = data.get("managed_runtime_config")
|
|
1484
|
+
if isinstance(declaration, dict):
|
|
1485
|
+
manifest = str(declaration.get("manifest") or "").strip()
|
|
1486
|
+
runtime_name = declaration.get("runtime_name")
|
|
1487
|
+
runtime_version = declaration.get("runtime_version")
|
|
1488
|
+
manifest_sha256 = declaration.get("manifest_sha256")
|
|
1489
|
+
else:
|
|
1490
|
+
legacy = data.get("runtime_config") or {}
|
|
1491
|
+
manifest = str(legacy.get("manifest") or "").strip()
|
|
1492
|
+
runtime_name = legacy.get("name")
|
|
1493
|
+
runtime_version = legacy.get("version")
|
|
1494
|
+
manifest_sha256 = legacy.get("manifest_sha256")
|
|
1495
|
+
if not manifest:
|
|
1496
|
+
raise ValueError("ManagedRuntime requires managed_runtime_config.manifest")
|
|
1497
|
+
payload: Dict[str, Any] = {
|
|
1498
|
+
"Manifest": manifest,
|
|
1499
|
+
"RuntimeName": runtime_name,
|
|
1500
|
+
"RuntimeVersion": runtime_version,
|
|
1501
|
+
}
|
|
1502
|
+
if manifest_sha256:
|
|
1503
|
+
payload["ManifestSHA256"] = manifest_sha256
|
|
1504
|
+
return payload
|
|
1505
|
+
|
|
1313
1506
|
async def create_agent(self, data: Dict[str, Any]) -> Dict[str, Any]:
|
|
1314
|
-
"""
|
|
1507
|
+
"""Create an Agent through the established order workflow.
|
|
1508
|
+
|
|
1509
|
+
The control plane invokes the existing ``CreateAgent`` callback after
|
|
1510
|
+
``CreateAgentProduct``. Calling it a second time from Studio races
|
|
1511
|
+
that callback and can create an inconsistent lifecycle result.
|
|
1512
|
+
"""
|
|
1315
1513
|
framework = self._normalize_framework_name(data.get("framework"))
|
|
1316
1514
|
params = {
|
|
1317
1515
|
"Name": data.get("name"),
|
|
@@ -1357,7 +1555,7 @@ class AgentEngineClient:
|
|
|
1357
1555
|
"IamRole": data.get("iam_role", "KsyunAgentEngineDefaultRole"),
|
|
1358
1556
|
}
|
|
1359
1557
|
|
|
1360
|
-
if params["DeploymentType"]
|
|
1558
|
+
if params["DeploymentType"] == "Code":
|
|
1361
1559
|
ks3 = data.get("ks3", {})
|
|
1362
1560
|
params["CodeConfig"] = {
|
|
1363
1561
|
"Path": data.get("artifact_path", ""),
|
|
@@ -1365,14 +1563,11 @@ class AgentEngineClient:
|
|
|
1365
1563
|
"SecretKey": ks3.get("secret_key"),
|
|
1366
1564
|
"Region": self._normalize_payload_region(ks3.get("region", "cn-beijing-6")),
|
|
1367
1565
|
"Bucket": ks3.get("bucket"),
|
|
1566
|
+
"Command": data.get("code_command"),
|
|
1567
|
+
"Checksum": data.get("code_checksum"),
|
|
1368
1568
|
}
|
|
1369
|
-
|
|
1370
|
-
|
|
1371
|
-
params["RuntimeConfig"] = {
|
|
1372
|
-
"Name": runtime_config.get("name"),
|
|
1373
|
-
"Version": runtime_config.get("version"),
|
|
1374
|
-
"ManifestSha256": runtime_config.get("manifest_sha256"),
|
|
1375
|
-
}
|
|
1569
|
+
elif params["DeploymentType"] == "ManagedRuntime":
|
|
1570
|
+
params["ManagedRuntimeConfig"] = self._managed_runtime_config_payload(data)
|
|
1376
1571
|
else:
|
|
1377
1572
|
ic = data.get("image_credential", {}) or {}
|
|
1378
1573
|
artifact = (data.get("artifact_path", "") or "").strip()
|
|
@@ -1387,8 +1582,18 @@ class AgentEngineClient:
|
|
|
1387
1582
|
else:
|
|
1388
1583
|
env_vars = []
|
|
1389
1584
|
|
|
1585
|
+
# Keep create and update semantics aligned. In particular, an
|
|
1586
|
+
# explicit ``--no-observability`` must not be silently rewritten to
|
|
1587
|
+
# true while the order is being created.
|
|
1588
|
+
observability = data.get("observability")
|
|
1589
|
+
if isinstance(observability, dict) and "langfuse_enabled" in observability:
|
|
1590
|
+
enable_observability = bool(observability.get("langfuse_enabled"))
|
|
1591
|
+
elif "enable_observability" in data:
|
|
1592
|
+
enable_observability = bool(data.get("enable_observability"))
|
|
1593
|
+
else:
|
|
1594
|
+
enable_observability = True
|
|
1390
1595
|
advanced = {
|
|
1391
|
-
"EnableObservability":
|
|
1596
|
+
"EnableObservability": enable_observability,
|
|
1392
1597
|
"EnvironmentVariables": env_vars,
|
|
1393
1598
|
}
|
|
1394
1599
|
inbound_identity_auth = data.get("inbound_identity_auth")
|
|
@@ -1399,7 +1604,21 @@ class AgentEngineClient:
|
|
|
1399
1604
|
advanced["ProjectId"] = project_id
|
|
1400
1605
|
params["Advanced"] = advanced
|
|
1401
1606
|
|
|
1402
|
-
|
|
1607
|
+
# ManagedRuntime is an already-paid, platform-owned YAML runtime. It
|
|
1608
|
+
# has no Code/Container order callback to materialize later, so use
|
|
1609
|
+
# the existing CreateAgent action to create its Agent/Runtime now.
|
|
1610
|
+
# Code and Container keep the established CreateAgentProduct flow.
|
|
1611
|
+
action = (
|
|
1612
|
+
"CreateAgent"
|
|
1613
|
+
if params["DeploymentType"] == "ManagedRuntime"
|
|
1614
|
+
else "CreateAgentProduct"
|
|
1615
|
+
)
|
|
1616
|
+
if action == "CreateAgent":
|
|
1617
|
+
# CreateAgent is also used as an order callback and therefore
|
|
1618
|
+
# requires an InstanceId. A declarative runtime has no order to
|
|
1619
|
+
# allocate one for us, so the SDK supplies a stable request UUID.
|
|
1620
|
+
params["InstanceId"] = str(data.get("instance_id") or uuid.uuid4())
|
|
1621
|
+
return self._action(action, params)
|
|
1403
1622
|
|
|
1404
1623
|
async def get_agent(
|
|
1405
1624
|
self,
|
|
@@ -1639,7 +1858,9 @@ class AgentEngineClient:
|
|
|
1639
1858
|
if data.get("description"):
|
|
1640
1859
|
params["Description"] = data["description"]
|
|
1641
1860
|
|
|
1642
|
-
if
|
|
1861
|
+
if artifact_type == "ManagedRuntime":
|
|
1862
|
+
params["ManagedRuntimeConfig"] = self._managed_runtime_config_payload(data)
|
|
1863
|
+
elif data.get("artifact_path"):
|
|
1643
1864
|
artifact = (data.get("artifact_path", "") or "").strip()
|
|
1644
1865
|
if (artifact_type or "").lower() == "container":
|
|
1645
1866
|
ic = data.get("image_credential", {}) or {}
|
|
@@ -1655,14 +1876,9 @@ class AgentEngineClient:
|
|
|
1655
1876
|
"SecretKey": ks3.get("secret_key"),
|
|
1656
1877
|
"Region": self._normalize_payload_region(ks3.get("region", "cn-beijing-6")),
|
|
1657
1878
|
"Bucket": ks3.get("bucket"),
|
|
1879
|
+
"Command": data.get("code_command"),
|
|
1880
|
+
"Checksum": data.get("code_checksum"),
|
|
1658
1881
|
}
|
|
1659
|
-
if artifact_type == "ManagedRuntime":
|
|
1660
|
-
runtime_config = data.get("runtime_config") or {}
|
|
1661
|
-
params["RuntimeConfig"] = {
|
|
1662
|
-
"Name": runtime_config.get("name"),
|
|
1663
|
-
"Version": runtime_config.get("version"),
|
|
1664
|
-
"ManifestSha256": runtime_config.get("manifest_sha256"),
|
|
1665
|
-
}
|
|
1666
1882
|
|
|
1667
1883
|
if data.get("resources"):
|
|
1668
1884
|
params["Resource"] = {
|
|
@@ -1729,26 +1945,137 @@ class AgentEngineClient:
|
|
|
1729
1945
|
self, agent_id: str, user_id: Optional[str] = None, expires_hours: int = 24
|
|
1730
1946
|
) -> Dict[str, Any]:
|
|
1731
1947
|
"""创建会话"""
|
|
1732
|
-
return self.
|
|
1948
|
+
return await self._action_async(
|
|
1733
1949
|
"CreateSession", {"AgentId": agent_id, "UserId": user_id, "ExpiresHours": expires_hours}
|
|
1734
1950
|
)
|
|
1735
1951
|
|
|
1736
1952
|
async def get_session(self, session_id: str) -> Dict[str, Any]:
|
|
1737
1953
|
"""获取会话详情"""
|
|
1738
|
-
return self.
|
|
1954
|
+
return await self._action_async("GetSession", {"Id": session_id})
|
|
1739
1955
|
|
|
1740
1956
|
async def list_sessions(self, agent_id: str, page: int = 1, size: int = 20) -> Dict[str, Any]:
|
|
1741
1957
|
"""列出会话"""
|
|
1742
|
-
return self.
|
|
1958
|
+
return await self._action_async(
|
|
1959
|
+
"ListSessions", {"AgentId": agent_id, "Page": page, "PageSize": size}
|
|
1960
|
+
)
|
|
1743
1961
|
|
|
1744
1962
|
async def delete_session(self, session_id: str) -> bool:
|
|
1745
1963
|
"""删除会话"""
|
|
1746
1964
|
try:
|
|
1747
|
-
self.
|
|
1748
|
-
|
|
1965
|
+
result = await self._action_async("DeleteSession", {"Id": session_id})
|
|
1966
|
+
# Server may accept the request but retain the control-plane
|
|
1967
|
+
# record when runtime-side deletion is still pending. Do not
|
|
1968
|
+
# present that state as a completed delete to Studio callers.
|
|
1969
|
+
return bool(result.get("deleted"))
|
|
1749
1970
|
except Exception:
|
|
1750
1971
|
return False
|
|
1751
1972
|
|
|
1973
|
+
async def list_session_messages(
|
|
1974
|
+
self,
|
|
1975
|
+
*,
|
|
1976
|
+
agent_id: str,
|
|
1977
|
+
session_id: str,
|
|
1978
|
+
after_seq_id: int | None = None,
|
|
1979
|
+
before_seq_id: int | None = None,
|
|
1980
|
+
cursor_source: str | None = None,
|
|
1981
|
+
limit: int = 50,
|
|
1982
|
+
include_reasoning: bool = False,
|
|
1983
|
+
include_tool_events: bool = False,
|
|
1984
|
+
include_attachments: bool = True,
|
|
1985
|
+
) -> Dict[str, Any]:
|
|
1986
|
+
"""Read the Server-owned message projection for one cloud session.
|
|
1987
|
+
|
|
1988
|
+
This is intentionally an AgentEngine Action client method rather than
|
|
1989
|
+
a Hosted UI shortcut. Local Studio can retain AK/SK in its backend,
|
|
1990
|
+
call the same authenticated Server read path as the cloud console, and
|
|
1991
|
+
keep cursor ownership on the Server/Runtime boundary.
|
|
1992
|
+
"""
|
|
1993
|
+
|
|
1994
|
+
params: Dict[str, Any] = {
|
|
1995
|
+
"AgentId": agent_id,
|
|
1996
|
+
"SessionId": session_id,
|
|
1997
|
+
"Limit": limit,
|
|
1998
|
+
"IncludeReasoning": include_reasoning,
|
|
1999
|
+
"IncludeToolEvents": include_tool_events,
|
|
2000
|
+
"IncludeAttachments": include_attachments,
|
|
2001
|
+
}
|
|
2002
|
+
if after_seq_id is not None:
|
|
2003
|
+
params["AfterSeqId"] = after_seq_id
|
|
2004
|
+
if before_seq_id is not None:
|
|
2005
|
+
params["BeforeSeqId"] = before_seq_id
|
|
2006
|
+
if cursor_source is not None:
|
|
2007
|
+
params["CursorSource"] = cursor_source
|
|
2008
|
+
return await self._action_async("ListSessionMessages", params)
|
|
2009
|
+
|
|
2010
|
+
async def list_session_events(
|
|
2011
|
+
self,
|
|
2012
|
+
*,
|
|
2013
|
+
agent_id: str,
|
|
2014
|
+
session_id: str,
|
|
2015
|
+
after_seq_id: int | None = None,
|
|
2016
|
+
limit: int = 100,
|
|
2017
|
+
) -> Dict[str, Any]:
|
|
2018
|
+
"""Read canonical cloud session events through the Server Action API."""
|
|
2019
|
+
|
|
2020
|
+
params: Dict[str, Any] = {
|
|
2021
|
+
"AgentId": agent_id,
|
|
2022
|
+
"SessionId": session_id,
|
|
2023
|
+
"Limit": limit,
|
|
2024
|
+
}
|
|
2025
|
+
if after_seq_id is not None:
|
|
2026
|
+
params["AfterSeqId"] = after_seq_id
|
|
2027
|
+
return await self._action_async("ListSessionEvents", params)
|
|
2028
|
+
|
|
2029
|
+
async def submit_interaction(
|
|
2030
|
+
self,
|
|
2031
|
+
*,
|
|
2032
|
+
agent_id: str,
|
|
2033
|
+
session_id: str,
|
|
2034
|
+
run_id: str,
|
|
2035
|
+
interaction_id: str,
|
|
2036
|
+
expected_revision: int,
|
|
2037
|
+
action: str,
|
|
2038
|
+
response: Dict[str, Any] | None = None,
|
|
2039
|
+
idempotency_key: str,
|
|
2040
|
+
) -> Dict[str, Any]:
|
|
2041
|
+
"""Submit one Interaction/v1 response via Server admission.
|
|
2042
|
+
|
|
2043
|
+
The caller supplies only public interaction fields. Tenant,
|
|
2044
|
+
principal, AgentInstance and permit remain Server-derived.
|
|
2045
|
+
"""
|
|
2046
|
+
|
|
2047
|
+
params = {
|
|
2048
|
+
"AgentId": agent_id,
|
|
2049
|
+
"SessionId": session_id,
|
|
2050
|
+
"RunId": run_id,
|
|
2051
|
+
"InteractionId": interaction_id,
|
|
2052
|
+
"ExpectedRevision": expected_revision,
|
|
2053
|
+
# ``Action`` is reserved by the KOP envelope for the API operation
|
|
2054
|
+
# name. Keep the SDK argument ergonomic while using an
|
|
2055
|
+
# unambiguous public wire field.
|
|
2056
|
+
"InteractionAction": action,
|
|
2057
|
+
"Response": response or {},
|
|
2058
|
+
"IdempotencyKey": idempotency_key,
|
|
2059
|
+
}
|
|
2060
|
+
if "SubmitInteraction" not in self._unpublished_kop_actions:
|
|
2061
|
+
try:
|
|
2062
|
+
return await self._action_async("SubmitInteraction", params)
|
|
2063
|
+
except AgentEngineAPIError as exc:
|
|
2064
|
+
if not self._is_unregistered_kop_action(exc, "SubmitInteraction"):
|
|
2065
|
+
raise
|
|
2066
|
+
self._unpublished_kop_actions.add("SubmitInteraction")
|
|
2067
|
+
if "SubmitInteraction" in self._unpublished_kop_actions:
|
|
2068
|
+
# KOP publication can lag the Server/Gateway rollout. The
|
|
2069
|
+
# per-Agent endpoint is authenticated with the API key returned by
|
|
2070
|
+
# signed GetAgent and still traverses Gateway -> Server admission;
|
|
2071
|
+
# it never submits directly to Runtime.
|
|
2072
|
+
return await self._runtime_action_for_agent(
|
|
2073
|
+
agent_id=agent_id,
|
|
2074
|
+
action="SubmitInteraction",
|
|
2075
|
+
params=params,
|
|
2076
|
+
)
|
|
2077
|
+
raise AssertionError("unreachable SubmitInteraction transport state")
|
|
2078
|
+
|
|
1752
2079
|
async def list_workspace_files(
|
|
1753
2080
|
self,
|
|
1754
2081
|
*,
|
|
@@ -2200,17 +2527,188 @@ class AgentEngineClient:
|
|
|
2200
2527
|
# ===== Chat Actions =====
|
|
2201
2528
|
|
|
2202
2529
|
async def chat(
|
|
2203
|
-
self,
|
|
2530
|
+
self,
|
|
2531
|
+
agent_id: str,
|
|
2532
|
+
message: Any,
|
|
2533
|
+
session_id: Optional[str] = None,
|
|
2534
|
+
*,
|
|
2535
|
+
model: Optional[str] = None,
|
|
2536
|
+
model_options: Optional[Dict[str, Any]] = None,
|
|
2537
|
+
tool_approval_mode: Optional[str] = None,
|
|
2538
|
+
collaboration_mode: Optional[str] = None,
|
|
2539
|
+
goal_objective: Optional[str] = None,
|
|
2204
2540
|
) -> Dict[str, Any]:
|
|
2205
2541
|
"""调用 Agent"""
|
|
2206
2542
|
params = {
|
|
2207
2543
|
"AgentId": agent_id,
|
|
2544
|
+
# The public KOP contract validates ApiFormat before forwarding the
|
|
2545
|
+
# request to Server. Keep this legacy string helper on the chat
|
|
2546
|
+
# completions shape instead of relying on Server's newer Responses
|
|
2547
|
+
# default, otherwise KOP rejects an otherwise valid request.
|
|
2548
|
+
"ApiFormat": "chat_completions",
|
|
2208
2549
|
"Messages": [{"role": "user", "content": message}],
|
|
2209
2550
|
"Stream": False,
|
|
2210
2551
|
}
|
|
2211
2552
|
if session_id:
|
|
2212
2553
|
params["SessionId"] = session_id
|
|
2213
|
-
|
|
2554
|
+
if model:
|
|
2555
|
+
params["Model"] = model
|
|
2556
|
+
if model_options:
|
|
2557
|
+
params["ModelOptions"] = dict(model_options)
|
|
2558
|
+
execution_metadata: Dict[str, Any] = {}
|
|
2559
|
+
if tool_approval_mode:
|
|
2560
|
+
execution_metadata["tool_approval_mode"] = tool_approval_mode
|
|
2561
|
+
if collaboration_mode:
|
|
2562
|
+
execution_metadata["collaboration_mode"] = collaboration_mode
|
|
2563
|
+
if goal_objective:
|
|
2564
|
+
execution_metadata["goal_objective"] = goal_objective
|
|
2565
|
+
if execution_metadata:
|
|
2566
|
+
params["Metadata"] = {"agentengine": execution_metadata}
|
|
2567
|
+
return await self._action_async("RunAgent", params)
|
|
2568
|
+
|
|
2569
|
+
def _open_chat_stream(self, params: Dict[str, Any]) -> AgentEngineSSEStream:
|
|
2570
|
+
"""Open RunAgent SSE synchronously in a worker-owned requests session."""
|
|
2571
|
+
|
|
2572
|
+
path = "/agentengine/api/v1/RunAgent"
|
|
2573
|
+
_kop_mode, headers, full_url = self._build_action_request_target(path, "RunAgent")
|
|
2574
|
+
body_str = json.dumps(params, ensure_ascii=False)
|
|
2575
|
+
if self.dry_run:
|
|
2576
|
+
# Reuse the established dry-run contract, which raises DryRunExit
|
|
2577
|
+
# with the signed request rather than opening a socket.
|
|
2578
|
+
self._request("POST", path, params)
|
|
2579
|
+
raise AssertionError("dry-run request unexpectedly returned")
|
|
2580
|
+
|
|
2581
|
+
session = requests.Session()
|
|
2582
|
+
response: requests.Response | None = None
|
|
2583
|
+
retried_inner_endpoint = False
|
|
2584
|
+
try:
|
|
2585
|
+
while True:
|
|
2586
|
+
response = session.request(
|
|
2587
|
+
method="POST",
|
|
2588
|
+
url=full_url,
|
|
2589
|
+
data=body_str.encode("utf-8"),
|
|
2590
|
+
headers=headers,
|
|
2591
|
+
auth=self._auth.get_auth(),
|
|
2592
|
+
# A foreground Agent turn can legitimately spend minutes
|
|
2593
|
+
# reasoning before its next SSE chunk. Bound connection
|
|
2594
|
+
# establishment, not the lifetime of an admitted stream.
|
|
2595
|
+
timeout=(self.timeout, None),
|
|
2596
|
+
verify=self._ssl_verify_enabled(),
|
|
2597
|
+
stream=True,
|
|
2598
|
+
)
|
|
2599
|
+
content_type = str(response.headers.get("content-type") or "").lower()
|
|
2600
|
+
if response.status_code < 400 and "text/event-stream" in content_type:
|
|
2601
|
+
return AgentEngineSSEStream(response, session)
|
|
2602
|
+
|
|
2603
|
+
resp_text = response.text or ""
|
|
2604
|
+
details = self._extract_http_error_details(resp_text)
|
|
2605
|
+
details.setdefault("http_status", response.status_code)
|
|
2606
|
+
if response.status_code < 400:
|
|
2607
|
+
details["content_type"] = content_type or "<missing>"
|
|
2608
|
+
try:
|
|
2609
|
+
envelope = json.loads(resp_text)
|
|
2610
|
+
except (TypeError, ValueError):
|
|
2611
|
+
envelope = {}
|
|
2612
|
+
if not isinstance(envelope, dict):
|
|
2613
|
+
envelope = {}
|
|
2614
|
+
envelope_code = envelope.get("Code")
|
|
2615
|
+
error_code = (
|
|
2616
|
+
envelope_code
|
|
2617
|
+
if envelope_code not in {None, 0, "0"}
|
|
2618
|
+
else details.get("remote_error_code") or 502
|
|
2619
|
+
)
|
|
2620
|
+
message = (
|
|
2621
|
+
str(
|
|
2622
|
+
details.get("remote_error_message")
|
|
2623
|
+
or details.get("message")
|
|
2624
|
+
or ""
|
|
2625
|
+
).strip()
|
|
2626
|
+
or "RunAgent stream did not return text/event-stream"
|
|
2627
|
+
)
|
|
2628
|
+
raise AgentEngineAPIError(
|
|
2629
|
+
error_code,
|
|
2630
|
+
message,
|
|
2631
|
+
details=details,
|
|
2632
|
+
)
|
|
2633
|
+
if not retried_inner_endpoint and self._can_retry_with_inner_aicp_endpoint(details):
|
|
2634
|
+
retried_inner_endpoint = True
|
|
2635
|
+
response.close()
|
|
2636
|
+
response = None
|
|
2637
|
+
self._switch_to_inner_aicp_endpoint()
|
|
2638
|
+
_kop_mode, headers, full_url = self._build_action_request_target(
|
|
2639
|
+
path, "RunAgent"
|
|
2640
|
+
)
|
|
2641
|
+
continue
|
|
2642
|
+
|
|
2643
|
+
self._log_http_error(
|
|
2644
|
+
method="POST",
|
|
2645
|
+
full_url=full_url,
|
|
2646
|
+
status_code=response.status_code,
|
|
2647
|
+
details=details,
|
|
2648
|
+
)
|
|
2649
|
+
message = (
|
|
2650
|
+
str(
|
|
2651
|
+
details.get("remote_error_message")
|
|
2652
|
+
or details.get("message")
|
|
2653
|
+
or ""
|
|
2654
|
+
).strip()
|
|
2655
|
+
or resp_text
|
|
2656
|
+
)
|
|
2657
|
+
raise AgentEngineAPIError(
|
|
2658
|
+
response.status_code,
|
|
2659
|
+
message,
|
|
2660
|
+
details=details or None,
|
|
2661
|
+
)
|
|
2662
|
+
except BaseException:
|
|
2663
|
+
try:
|
|
2664
|
+
if response is not None:
|
|
2665
|
+
response.close()
|
|
2666
|
+
finally:
|
|
2667
|
+
session.close()
|
|
2668
|
+
raise
|
|
2669
|
+
|
|
2670
|
+
async def chat_stream(
|
|
2671
|
+
self,
|
|
2672
|
+
agent_id: str,
|
|
2673
|
+
message: Any,
|
|
2674
|
+
session_id: Optional[str] = None,
|
|
2675
|
+
*,
|
|
2676
|
+
model: Optional[str] = None,
|
|
2677
|
+
model_options: Optional[Dict[str, Any]] = None,
|
|
2678
|
+
tool_approval_mode: Optional[str] = None,
|
|
2679
|
+
collaboration_mode: Optional[str] = None,
|
|
2680
|
+
goal_objective: Optional[str] = None,
|
|
2681
|
+
) -> AgentEngineSSEStream:
|
|
2682
|
+
"""Open a signed foreground RunAgent SSE stream.
|
|
2683
|
+
|
|
2684
|
+
The upstream response is established before this method returns so an
|
|
2685
|
+
HTTP error remains a structured ``AgentEngineAPIError`` instead of a
|
|
2686
|
+
late exception after a downstream proxy has already emitted 200.
|
|
2687
|
+
"""
|
|
2688
|
+
|
|
2689
|
+
params: Dict[str, Any] = {
|
|
2690
|
+
"AgentId": agent_id,
|
|
2691
|
+
"ApiFormat": "chat_completions",
|
|
2692
|
+
"Messages": [{"role": "user", "content": message}],
|
|
2693
|
+
"Stream": True,
|
|
2694
|
+
"Background": False,
|
|
2695
|
+
}
|
|
2696
|
+
if session_id:
|
|
2697
|
+
params["SessionId"] = session_id
|
|
2698
|
+
if model:
|
|
2699
|
+
params["Model"] = model
|
|
2700
|
+
if model_options:
|
|
2701
|
+
params["ModelOptions"] = dict(model_options)
|
|
2702
|
+
execution_metadata: Dict[str, Any] = {}
|
|
2703
|
+
if tool_approval_mode:
|
|
2704
|
+
execution_metadata["tool_approval_mode"] = tool_approval_mode
|
|
2705
|
+
if collaboration_mode:
|
|
2706
|
+
execution_metadata["collaboration_mode"] = collaboration_mode
|
|
2707
|
+
if goal_objective:
|
|
2708
|
+
execution_metadata["goal_objective"] = goal_objective
|
|
2709
|
+
if execution_metadata:
|
|
2710
|
+
params["Metadata"] = {"agentengine": execution_metadata}
|
|
2711
|
+
return await asyncio.to_thread(self._open_chat_stream, params)
|
|
2214
2712
|
|
|
2215
2713
|
# ===== Version Actions =====
|
|
2216
2714
|
|