agentengine-sdk-python 0.8.4__py3-none-any.whl → 0.8.5__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.4.dist-info → agentengine_sdk_python-0.8.5.dist-info}/METADATA +6 -3
- {agentengine_sdk_python-0.8.4.dist-info → agentengine_sdk_python-0.8.5.dist-info}/RECORD +591 -365
- ksadk/_build_provenance.json +1 -1
- ksadk/_process.py +83 -0
- ksadk/_str_enum.py +17 -0
- ksadk/a2ui/core.py +3 -3
- ksadk/api/client.py +6 -0
- ksadk/builders/code_builder.py +38 -12
- ksadk/builders/framework_requirements.py +20 -2
- ksadk/cli/__init__.py +36 -0
- ksadk/cli/cmd_config.py +4 -4
- ksadk/cli/cmd_create.py +12 -12
- ksadk/cli/cmd_hermes.py +24 -2
- ksadk/cli/cmd_invoke.py +28 -5
- ksadk/cli/cmd_openclaw.py +26 -1
- ksadk/cli/cmd_plugin.py +70 -12
- ksadk/cli/cmd_studio.py +64 -16
- ksadk/cli/openclaw_env.py +1 -1
- ksadk/cli/resource_common.py +26 -0
- ksadk/codex/client.py +3 -2
- ksadk/configs/__init__.py +1 -1
- ksadk/configs/env_registry.py +125 -31
- ksadk/configs/env_registry_studio.py +86 -0
- ksadk/configs/global_config.py +1 -1
- ksadk/configs/settings.py +3 -3
- ksadk/connector/__init__.py +17 -0
- ksadk/connector/channel.py +477 -0
- ksadk/context_engine/capabilities.py +52 -4
- ksadk/conversations/attachment_storage.py +10 -3
- ksadk/conversations/attachments.py +16 -5
- ksadk/conversations/message_projection.py +23 -32
- ksadk/conversations/normalize.py +28 -10
- ksadk/conversations/runtime_baseline.py +37 -0
- ksadk/conversations/runtime_invocation.py +17 -4
- ksadk/conversations/runtime_observability.py +39 -10
- ksadk/conversations/runtime_payloads.py +8 -0
- ksadk/conversations/runtime_persistence.py +105 -9
- ksadk/conversations/runtime_preparation.py +13 -7
- ksadk/conversations/runtime_stream_events.py +29 -35
- ksadk/conversations/runtime_streaming.py +8 -0
- ksadk/events/adapters/_codex_items.py +16 -8
- ksadk/events/adapters/_langgraph_support.py +34 -0
- ksadk/events/session_event.py +2 -2
- ksadk/harness/__init__.py +14 -0
- ksadk/harness/app.py +11 -0
- ksadk/harness/artifact_store.py +213 -0
- ksadk/harness/capabilities.py +115 -0
- ksadk/harness/capability_runtime.py +237 -0
- ksadk/harness/closure_contract.py +92 -0
- ksadk/harness/compaction_record.py +122 -0
- ksadk/harness/compiler.py +284 -0
- ksadk/harness/conformance/__init__.py +33 -0
- ksadk/harness/conformance/contract.py +506 -0
- ksadk/harness/conformance/fixtures.py +102 -0
- ksadk/harness/context_engine.py +403 -0
- ksadk/harness/context_maintenance.py +259 -0
- ksadk/harness/context_manifest.py +188 -0
- ksadk/harness/context_tuning.py +168 -0
- ksadk/harness/draft_runtime.py +322 -0
- ksadk/harness/engine/__init__.py +40 -0
- ksadk/harness/engine/base.py +122 -0
- ksadk/harness/engine/budgets.py +108 -0
- ksadk/harness/engine/capability_declarations.py +59 -0
- ksadk/harness/engine/completion_guard.py +42 -0
- ksadk/harness/engine/context_pipeline.py +579 -0
- ksadk/harness/engine/graph_builder.py +859 -0
- ksadk/harness/engine/langgraph.py +931 -0
- ksadk/harness/engine/mcp_disclosure.py +750 -0
- ksadk/harness/engine/policy_runtime.py +70 -0
- ksadk/harness/engine/postgres_checkpointer.py +63 -0
- ksadk/harness/engine/run_control_bridge.py +80 -0
- ksadk/harness/engine/run_types.py +88 -0
- ksadk/harness/engine/skill_disclosure.py +189 -0
- ksadk/harness/engine/spans.py +41 -0
- ksadk/harness/engine/subagents.py +343 -0
- ksadk/harness/engine/thread_ids.py +112 -0
- ksadk/harness/engine/tool_dispatch.py +144 -0
- ksadk/harness/event_tree.py +212 -0
- ksadk/harness/events.py +461 -0
- ksadk/harness/execution_policy.py +94 -0
- ksadk/harness/insights.py +210 -0
- ksadk/harness/lifecycle.py +578 -0
- ksadk/harness/lifecycle_conformance.py +233 -0
- ksadk/harness/lifecycle_local_plane.py +104 -0
- ksadk/harness/loop/__init__.py +44 -0
- ksadk/harness/loop/reason.py +454 -0
- ksadk/harness/loop/tools.py +762 -0
- ksadk/harness/managed_runtime.py +884 -0
- ksadk/harness/mcp_matrix.py +474 -0
- ksadk/harness/mcp_runtime.py +471 -0
- ksadk/harness/memory_consolidation.py +157 -0
- ksadk/harness/memory_loop.py +156 -0
- ksadk/harness/memory_runtime.py +541 -0
- ksadk/harness/metrics.py +90 -0
- ksadk/harness/model_capability.py +253 -0
- ksadk/harness/model_provider.py +220 -0
- ksadk/harness/observability/__init__.py +29 -0
- ksadk/harness/observability/inspection.py +528 -0
- ksadk/harness/observability/metrics.py +167 -0
- ksadk/harness/observability/otel_exporter.py +218 -0
- ksadk/harness/prompt_cache.py +70 -0
- ksadk/harness/public_activity.py +154 -0
- ksadk/harness/readiness.py +249 -0
- ksadk/harness/reasoner.py +466 -13
- ksadk/harness/release_readiness.py +140 -0
- ksadk/harness/resource_ref.py +69 -0
- ksadk/harness/run_control.py +668 -0
- ksadk/harness/runtime.py +146 -111
- ksadk/harness/runtime_capabilities.py +158 -0
- ksadk/harness/runtime_server.py +514 -0
- ksadk/harness/sandbox_adapters.py +739 -0
- ksadk/harness/sandbox_backend.py +530 -0
- ksadk/harness/sandbox_conformance.py +288 -0
- ksadk/harness/sandbox_lease.py +77 -0
- ksadk/harness/sandbox_lease_conformance.py +259 -0
- ksadk/harness/sandbox_matrix.py +170 -0
- ksadk/harness/sandbox_reconciliation.py +140 -0
- ksadk/harness/sandbox_recovery.py +586 -0
- ksadk/harness/sandbox_recovery_conformance.py +246 -0
- ksadk/harness/session_store.py +243 -0
- ksadk/harness/skill_composition.py +212 -0
- ksadk/harness/skill_feedback.py +123 -0
- ksadk/harness/skill_matrix.py +233 -0
- ksadk/harness/skill_runtime.py +259 -0
- ksadk/harness/spec.py +332 -0
- ksadk/harness/state.py +153 -0
- ksadk/harness/strategies.py +149 -0
- ksadk/harness/subagent.py +253 -0
- ksadk/harness/tool_policy.py +131 -0
- ksadk/harness/tool_receipts.py +96 -0
- ksadk/harness/tool_reliability.py +81 -0
- ksadk/harness/user_errors.py +69 -0
- ksadk/harness/working_context.py +81 -0
- ksadk/harness/working_context_patch.py +99 -0
- ksadk/identity/resolver.py +18 -0
- ksadk/interaction/__init__.py +1 -1
- ksadk/interaction/ledger.py +1 -1
- ksadk/interaction/provider.py +1 -1
- ksadk/interaction/providers/__init__.py +3 -1
- ksadk/interaction/providers/adk.py +1 -1
- ksadk/interaction/providers/codex.py +1 -1
- ksadk/interaction/providers/harness.py +50 -0
- ksadk/interaction/providers/langgraph.py +1 -1
- ksadk/kernel/__init__.py +10 -0
- ksadk/kernel/approval_presentation.py +91 -0
- ksadk/kernel/authorization.py +1 -1
- ksadk/kernel/bootstrap.py +86 -102
- ksadk/kernel/contract_fingerprints.py +1 -1
- ksadk/kernel/contracts.py +5 -0
- ksadk/kernel/control.py +32 -1
- ksadk/kernel/execution_grants.py +221 -0
- ksadk/kernel/execution_grants_memory.py +133 -0
- ksadk/kernel/execution_grants_postgres.py +217 -0
- ksadk/kernel/execution_grants_sqlite.py +209 -0
- ksadk/kernel/ingress.py +27 -27
- ksadk/kernel/mapping.py +1 -1
- ksadk/kernel/memory_store.py +24 -11
- ksadk/kernel/postgres_store.py +63 -33
- ksadk/kernel/recovery.py +78 -14
- ksadk/kernel/sql/001_agent_kernel.sql +23 -0
- ksadk/kernel/sqlite_store.py +304 -25
- ksadk/kernel/state.py +2 -3
- ksadk/kernel/store.py +69 -2
- ksadk/kernel/worker.py +79 -41
- ksadk/kernel/worker_history.py +72 -0
- ksadk/kernel/worker_identity.py +47 -0
- ksadk/memory/coordinator.py +22 -6
- ksadk/memory/extraction.py +40 -1
- ksadk/memory/models.py +77 -1
- ksadk/memory/provider_resolver.py +5 -0
- ksadk/memory/providers/local_postgres.py +200 -0
- ksadk/memory/providers/local_sqlite.py +42 -3
- ksadk/memory/retrieval.py +189 -0
- ksadk/memory/store_adapter.py +150 -0
- ksadk/model_policy.py +2 -2
- ksadk/model_proxy/detect.py +254 -0
- ksadk/model_proxy/server.py +4 -2
- ksadk/model_proxy/transform.py +40 -2
- ksadk/plugins/__init__.py +1 -1
- ksadk/plugins/bridges/dsh.py +11 -0
- ksadk/plugins/builtins.py +40 -2
- ksadk/plugins/companion_artifacts.py +83 -0
- ksadk/plugins/companions.py +368 -0
- ksadk/plugins/contracts.py +1 -1
- ksadk/plugins/dsh_channels.py +156 -0
- ksadk/plugins/dsh_home.py +140 -0
- ksadk/plugins/dsh_teams.py +105 -0
- ksadk/plugins/dsh_toolchain.py +101 -19
- ksadk/plugins/execution_host.py +99 -0
- ksadk/plugins/providers/bundles/dsh-channels-client/client.js +19 -0
- ksadk/plugins/providers/bundles/dsh-channels-client/cordis.patch.yml +3 -0
- ksadk/plugins/providers/bundles/dsh-channels-client/index.mjs +7 -0
- ksadk/plugins/providers/bundles/dsh-channels-client/package.json +12 -0
- ksadk/plugins/providers/bundles/dsh-knowledge/package.json +1 -1
- ksadk/plugins/providers/bundles/dsh-memory/package.json +1 -1
- ksadk/plugins/providers/bundles/dsh-skill-center/package.json +1 -1
- ksadk/plugins/providers/bundles/dsh-teams-client/client.js +29 -0
- ksadk/plugins/providers/bundles/dsh-teams-client/cordis.patch.yml +3 -0
- ksadk/plugins/providers/bundles/dsh-teams-client/index.mjs +11 -0
- ksadk/plugins/providers/bundles/dsh-teams-client/package.json +35 -0
- ksadk/plugins/providers/bundles/dsh-teams-leader-policy/cordis.patch.yml +3 -0
- ksadk/plugins/providers/bundles/dsh-teams-leader-policy/index.mjs +13 -0
- ksadk/plugins/providers/bundles/dsh-teams-leader-policy/package.json +27 -0
- ksadk/plugins/providers/bundles/dsh-teams-profile/cordis.patch.yml +3 -0
- ksadk/plugins/providers/bundles/dsh-teams-profile/index.mjs +12 -0
- ksadk/plugins/providers/bundles/dsh-teams-profile/package.json +26 -0
- ksadk/plugins/providers/bundles/dsh-teams-router/cordis.patch.yml +3 -0
- ksadk/plugins/providers/bundles/dsh-teams-router/index.mjs +16 -0
- ksadk/plugins/providers/bundles/dsh-teams-router/package.json +27 -0
- ksadk/plugins/providers/bundles/dsh-teams-tasks/cordis.patch.yml +3 -0
- ksadk/plugins/providers/bundles/dsh-teams-tasks/index.mjs +16 -0
- ksadk/plugins/providers/bundles/dsh-teams-tasks/package.json +27 -0
- ksadk/plugins/providers/bundles/dsh-teams-tools/cordis.patch.yml +3 -0
- ksadk/plugins/providers/bundles/dsh-teams-tools/index.mjs +25 -0
- ksadk/plugins/providers/bundles/dsh-teams-tools/package.json +29 -0
- ksadk/plugins/providers/bundles/dsh-teams-tools/tools.json +235 -0
- ksadk/plugins/providers/bundles/ksadk-codex/index.mjs +1 -1
- ksadk/plugins/providers/bundles/ksadk-dsh-capability-host/index.mjs +51 -1
- ksadk/plugins/providers/bundles/ksadk-dsh-capability-host/package.json +2 -2
- ksadk/plugins/providers/bundles/ksadk-dsh-companion-host/client.mjs +133 -0
- ksadk/plugins/providers/bundles/ksadk-dsh-companion-host/index.mjs +14 -0
- ksadk/plugins/providers/bundles/ksadk-dsh-studio/client.js +27 -4
- ksadk/plugins/providers/bundles/ksadk-dsh-studio/index.mjs +9 -5
- ksadk/plugins/providers/bundles/ksadk-harness/index.mjs +1 -1
- ksadk/plugins/providers/codex.py +10 -2
- ksadk/plugins/providers/dsh_capabilities.py +61 -0
- ksadk/plugins/providers/harness.py +181 -33
- ksadk/plugins/providers/harness_delegation.py +593 -0
- ksadk/plugins/providers/harness_managed.py +456 -0
- ksadk/plugins/providers/harness_tools.py +326 -0
- ksadk/plugins/providers/shipped_dsh.py +4 -1
- ksadk/plugins/subagent_providers/codex.py +28 -6
- ksadk/plugins/teams/__init__.py +5 -0
- ksadk/plugins/teams/api.py +405 -0
- ksadk/plugins/teams/application.py +680 -0
- ksadk/plugins/teams/artifacts.py +60 -0
- ksadk/plugins/teams/context.py +96 -0
- ksadk/plugins/teams/contracts.py +136 -0
- ksadk/plugins/teams/domain.py +1427 -0
- ksadk/plugins/teams/domain_values.py +24 -0
- ksadk/plugins/teams/errors.py +13 -0
- ksadk/plugins/teams/migration.py +311 -0
- ksadk/plugins/teams/migration_cli.py +322 -0
- ksadk/plugins/teams/postgres_store.py +138 -0
- ksadk/plugins/teams/runtime.py +777 -0
- ksadk/plugins/teams/source_projection.py +84 -0
- ksadk/plugins/teams/store.py +311 -0
- ksadk/plugins/teams/task_decisions.py +423 -0
- ksadk/plugins/teams/transport.py +91 -0
- ksadk/plugins/teams/workspaces.py +255 -0
- ksadk/runners/_langgraph_runner_streams.py +121 -45
- ksadk/runners/_langgraph_state_reader.py +106 -0
- ksadk/runners/_session_identity.py +285 -0
- ksadk/runners/adk_runner.py +25 -60
- ksadk/runners/langgraph_runner.py +128 -111
- ksadk/runners/patch_langchain.py +47 -0
- ksadk/runners/usage_accumulator.py +11 -3
- ksadk/runtime/_runner_adapter/stream_mapping.py +52 -2
- ksadk/runtime/conversation_execution.py +25 -1
- ksadk/runtime/executor.py +9 -1
- ksadk/runtime/factory.py +36 -1
- ksadk/runtime/preprocessing.py +11 -3
- ksadk/runtime/runner_adapter.py +38 -9
- ksadk/runtime/skill_eval_result.py +36 -0
- ksadk/runtime/timing.py +46 -0
- ksadk/runtime/usage.py +49 -18
- ksadk/runtime_context.py +103 -1
- ksadk/sandbox/backends/e2b.py +245 -23
- ksadk/sandbox/backends/local_process.py +63 -39
- ksadk/sandbox/base.py +62 -1
- ksadk/sandbox/diagnostics.py +82 -0
- ksadk/sandbox/local_controls.py +746 -0
- ksadk/sandbox/local_launcher.py +90 -0
- ksadk/scheduler/dispatcher.py +1 -1
- ksadk/server/invocation_identity.py +118 -0
- ksadk/server/routes/common.py +32 -3
- ksadk/server/routes/control.py +64 -9
- ksadk/server/routes/dependencies.py +2 -1
- ksadk/server/routes/kernel_ingress.py +9 -1
- ksadk/server/routes/misc.py +233 -25
- ksadk/server/routes/models.py +3 -3
- ksadk/server/routes/openai_compat.py +76 -13
- ksadk/server/routes/run.py +106 -35
- ksadk/server/routes/sessions.py +244 -68
- ksadk/server/routes/workspace.py +130 -21
- ksadk/server/static/assets/{ArtifactsPanel-CGbWlMNh.js → ArtifactsPanel-C1YoaKhx.js} +1 -1
- ksadk/server/static/assets/{CodeBlock-b4C7upmO.js → CodeBlock-DHuAWfr5.js} +10 -7
- ksadk/server/static/assets/MathMessageMarkdown-cvdrBwYr.js +8 -0
- ksadk/server/static/assets/{MermaidBlock-BEBN4Ksz.js → MermaidBlock-DeBkbJvI.js} +9 -9
- ksadk/server/static/assets/{NativeTerminalPanel-zvL-WpAn.js → NativeTerminalPanel-oJj44_sV.js} +1 -1
- ksadk/server/static/assets/{abnfDiagram-VCTEODGH-BYafW7Za.js → abnfDiagram-VCTEODGH-Dhfv25o2.js} +1 -1
- ksadk/server/static/assets/{arc-bTohInsS.js → arc-C35w-pn1.js} +1 -1
- ksadk/server/static/assets/architecture-7GRP2DOG-BCsa26zi.js +1 -0
- ksadk/server/static/assets/{architectureDiagram-5GKGNRK7-Ch5Lbzsi.js → architectureDiagram-5GKGNRK7-FoMY_u6D.js} +1 -1
- ksadk/server/static/assets/{blockDiagram-NRAW4CY4-kqF4MDOG.js → blockDiagram-NRAW4CY4-zD4Rt7oE.js} +1 -1
- ksadk/server/static/assets/{c4Diagram-UCG6FXSJ-8uSRIODv.js → c4Diagram-UCG6FXSJ-BCtGGkhN.js} +1 -1
- ksadk/server/static/assets/channel-_KDifNys.js +1 -0
- ksadk/server/static/assets/chunk-2Q5K7J3B-HdVkJ9F0.js +1 -0
- ksadk/server/static/assets/{chunk-5VM5RSS4-DkhehZDr.js → chunk-5VM5RSS4-C2Ms13_k.js} +1 -1
- ksadk/server/static/assets/{chunk-F27PBJKO-BdXhtPe9.js → chunk-F27PBJKO-BoTj-qgx.js} +1 -1
- ksadk/server/static/assets/{chunk-G27WJ6UU-DPTpvpwi.js → chunk-G27WJ6UU-DOMyyjHH.js} +1 -1
- ksadk/server/static/assets/{chunk-JWPE2WC7-Pqoh38el.js → chunk-JWPE2WC7-DbJJqDli.js} +1 -1
- ksadk/server/static/assets/{chunk-LCL6LL3I-DeU00qC-.js → chunk-LCL6LL3I-CLuRCt_W.js} +1 -1
- ksadk/server/static/assets/{chunk-POPQ4Y6H-CzxScFkr.js → chunk-POPQ4Y6H-D0Dz847e.js} +1 -1
- ksadk/server/static/assets/{chunk-RHFEMEQ7-DpqMx-ux.js → chunk-RHFEMEQ7-BWSRzEcd.js} +1 -1
- ksadk/server/static/assets/{chunk-SVP7TREG-C6t0SypQ.js → chunk-SVP7TREG-CPoHqkCY.js} +1 -1
- ksadk/server/static/assets/{chunk-XXDRQBXY-DVaeafZk.js → chunk-XXDRQBXY-Bx1jS-X-.js} +1 -1
- ksadk/server/static/assets/classDiagram-DTDB5LWJ-BVCW3ZqZ.js +1 -0
- ksadk/server/static/assets/classDiagram-v2-JRS7N3AN-BVCW3ZqZ.js +1 -0
- ksadk/server/static/assets/{cose-bilkent-JH36ORCC-Bf9D3tzJ.js → cose-bilkent-JH36ORCC-LzyWm4m0.js} +1 -1
- ksadk/server/static/assets/cynefin-OW5HDTMX-CNXjFctL.js +1 -0
- ksadk/server/static/assets/{cynefinDiagram-5FMLGOSQ-B9cY3iTz.js → cynefinDiagram-5FMLGOSQ-BlW_bHED.js} +1 -1
- ksadk/server/static/assets/{dagre-3AP2YEHR-CSwlx3CB.js → dagre-3AP2YEHR-Bu_S86_i.js} +1 -1
- ksadk/server/static/assets/{dagre-UBpgon5q.js → dagre-B7nCawed.js} +1 -1
- ksadk/server/static/assets/{diagram-S7CK7UJ4-C9akhN9a.js → diagram-S7CK7UJ4-W_Zow2Km.js} +1 -1
- ksadk/server/static/assets/{diagram-UQ7AKVKN-CgedhTPI.js → diagram-UQ7AKVKN-CLIKAHON.js} +1 -1
- ksadk/server/static/assets/{diagram-VSXAHHWV-Cjucz5BY.js → diagram-VSXAHHWV-Dv6_QAlN.js} +1 -1
- ksadk/server/static/assets/{diagram-VX7I27RA-Dd4Vleyn.js → diagram-VX7I27RA-BWAWRDtZ.js} +1 -1
- ksadk/server/static/assets/{diagram-Z3DM3KII-CZ2jGtYW.js → diagram-Z3DM3KII-XA_rWMss.js} +1 -1
- ksadk/server/static/assets/dist-0X_j2Rcc.js +1 -0
- ksadk/server/static/assets/{dist-DiixqL0J.js → dist-1nXCdsej.js} +1 -1
- ksadk/server/static/assets/{dist-BIr4DSRq.js → dist-2vL2sAdF.js} +1 -1
- ksadk/server/static/assets/{dist-D_ctSS2i.js → dist-B3bA05-e.js} +1 -1
- ksadk/server/static/assets/{dist-ClYUxfeK.js → dist-BLpRy_Yx.js} +1 -1
- ksadk/server/static/assets/{dist-QfkEHOlb.js → dist-BO_UwatH.js} +1 -1
- ksadk/server/static/assets/{dist-B3FR1SKK.js → dist-BdNFAney.js} +1 -1
- ksadk/server/static/assets/{dist-BnaTiyzN.js → dist-C0J5_3qM.js} +1 -1
- ksadk/server/static/assets/{dist-Bj730Ib4.js → dist-CGt_UGeO.js} +1 -1
- ksadk/server/static/assets/{dist-CFzsn6BG.js → dist-CIRMvUM4.js} +1 -1
- ksadk/server/static/assets/{dist-BgV_owcB.js → dist-CIpWk_5f.js} +1 -1
- ksadk/server/static/assets/{dist-C5_ZAZsG.js → dist-CPyieXEf.js} +1 -1
- ksadk/server/static/assets/{dist-btbmmX5O.js → dist-D-92S-Fd.js} +1 -1
- ksadk/server/static/assets/{dist-fBO2v5Kt.js → dist-DNKuMzWc.js} +1 -1
- ksadk/server/static/assets/{dist-ufY3F5p6.js → dist-DWfdmz9s.js} +2 -2
- ksadk/server/static/assets/{dist-DVCOWtha.js → dist-DppE_r-D.js} +1 -1
- ksadk/server/static/assets/{dist-C1NMAY5a.js → dist-DyG6Ya-z.js} +1 -1
- ksadk/server/static/assets/{dist-CB9iJrvg.js → dist-M-SrdhhZ.js} +1 -1
- ksadk/server/static/assets/{dist-DvFK7p5S.js → dist-mqD5TZup.js} +1 -1
- ksadk/server/static/assets/{dist-Cf125P_m.js → dist-n3n6t_FO.js} +1 -1
- ksadk/server/static/assets/{dist-DFD6Qa6T.js → dist-qe8xjesy.js} +1 -1
- ksadk/server/static/assets/{dist-DoVSwoDb.js → dist-t6MzE0jU.js} +1 -1
- ksadk/server/static/assets/{ebnfDiagram-PWID7BFC-Ci8NqqZu.js → ebnfDiagram-PWID7BFC-BfCzF1Xi.js} +1 -1
- ksadk/server/static/assets/{erDiagram-SSCWMZ5O-CCIOhLZG.js → erDiagram-SSCWMZ5O-Dpz9_0zn.js} +1 -1
- ksadk/server/static/assets/eventmodeling-NTZA5JFV-B5-8RH9c.js +1 -0
- ksadk/server/static/assets/flowDiagram-A5DVABFB-BppFxEKw.js +1 -0
- ksadk/server/static/assets/{ganttDiagram-EL5Y4UJY-Cp_r9Hb6.js → ganttDiagram-EL5Y4UJY-DDaG1f4_.js} +1 -1
- ksadk/server/static/assets/gitGraph-4MIJSDKK-B-AhYj4C.js +1 -0
- ksadk/server/static/assets/{gitGraphDiagram-WWUBYQGX-Dlhc8Wr8.js → gitGraphDiagram-WWUBYQGX-DcxzRwYC.js} +1 -1
- ksadk/server/static/assets/index-BMd2mucF.css +2 -0
- ksadk/server/static/assets/index-D5qyyhTH.js +244 -0
- ksadk/server/static/assets/info-A6RAGUB7-0uiKrC35.js +1 -0
- ksadk/server/static/assets/{infoDiagram-RXCK75RN-CO0rRTRA.js → infoDiagram-RXCK75RN-CYMdn6lQ.js} +1 -1
- ksadk/server/static/assets/{ishikawaDiagram-5VMMS53U-CHiaedSS.js → ishikawaDiagram-5VMMS53U-CLHFAD6c.js} +1 -1
- ksadk/server/static/assets/{journeyDiagram-EYS64GPL-CHcCIB09.js → journeyDiagram-EYS64GPL-BHSKQGAl.js} +1 -1
- ksadk/server/static/assets/{kanban-definition-3QL26DDD-CJ_ebBZf.js → kanban-definition-3QL26DDD-D5W3tjTT.js} +1 -1
- ksadk/server/static/assets/{katex-B4weu383.js → katex-mtjOi4KM.js} +1 -1
- ksadk/server/static/assets/{linear-V-MgYHW1.js → linear-BETqsxE_.js} +1 -1
- ksadk/server/static/assets/{mermaid-parser.core-CBijEX_c.js → mermaid-parser.core-DPWrvs90.js} +2 -2
- ksadk/server/static/assets/{mindmap-definition-FBJOCRG2-Bc-pQvpp.js → mindmap-definition-FBJOCRG2-CJG2mfBP.js} +1 -1
- ksadk/server/static/assets/packet-AYTQ26CC-BVTmZ_cw.js +1 -0
- ksadk/server/static/assets/{pegDiagram-XKGWAZYB-D7genGLl.js → pegDiagram-XKGWAZYB-GjAPNaqn.js} +1 -1
- ksadk/server/static/assets/pie-WAS4IAKB-DyfxBU7V.js +1 -0
- ksadk/server/static/assets/{pieDiagram-E7YTZNPT-Bxj32zwD.js → pieDiagram-E7YTZNPT-ToIewrqr.js} +1 -1
- ksadk/server/static/assets/{quadrantDiagram-AXDQQJYC-BURv2mGh.js → quadrantDiagram-AXDQQJYC-4d78KiEY.js} +1 -1
- ksadk/server/static/assets/radar-RG4KPBEZ-FFontjL2.js +1 -0
- ksadk/server/static/assets/railroad-74A4TZTK-D0Uidzen.js +1 -0
- ksadk/server/static/assets/railroad-abnf-HS5TGJTU-BOo_9T2h.js +1 -0
- ksadk/server/static/assets/railroad-ebnf-LZEXJU2U-D6-BjW7Z.js +1 -0
- ksadk/server/static/assets/railroad-peg-WCYAUIDC-CXx__yMm.js +1 -0
- ksadk/server/static/assets/{railroadDiagram-O6MQD6OU-CCsh3avW.js → railroadDiagram-O6MQD6OU-DKzx4xfv.js} +1 -1
- ksadk/server/static/assets/{requirementDiagram-EFPCY7ZU-_FRRBKEd.js → requirementDiagram-EFPCY7ZU-CJYljxQS.js} +1 -1
- ksadk/server/static/assets/{sankeyDiagram-P5KCCOFB-C-gr2o9M.js → sankeyDiagram-P5KCCOFB-DLU2fV1w.js} +1 -1
- ksadk/server/static/assets/{sequenceDiagram-WJ2MYXX4-D97NmfKg.js → sequenceDiagram-WJ2MYXX4-CVqysrA9.js} +1 -1
- ksadk/server/static/assets/{sizeCapture-X5ZJPWSS-DjrPC5FX.js → sizeCapture-X5ZJPWSS-BUxfmTHc.js} +1 -1
- ksadk/server/static/assets/{stateDiagram-HBIQ2CUA-DzMNg1hh.js → stateDiagram-HBIQ2CUA-CNFgYI9E.js} +1 -1
- ksadk/server/static/assets/stateDiagram-v2-4QOOHH4V-BXAFScz8.js +1 -0
- ksadk/server/static/assets/{swimlanes-XN3QIQJK-Cssf_CsU.js → swimlanes-XN3QIQJK-B6qCMe8N.js} +1 -1
- ksadk/server/static/assets/swimlanesDiagram-VK2B7HYN-uIQ2lJKH.js +8 -0
- ksadk/server/static/assets/{timeline-definition-24CTP7MA-BWTHzyS1.js → timeline-definition-24CTP7MA-CMD3x_U_.js} +1 -1
- ksadk/server/static/assets/treeView-Q6P3EWNA-CK5GgucZ.js +1 -0
- ksadk/server/static/assets/treemap-WGGIJYW6-Bq1u1SpG.js +1 -0
- ksadk/server/static/assets/{vennDiagram-4TSXK5OY-BSKgJsmR.js → vennDiagram-4TSXK5OY-BqtUqvXM.js} +1 -1
- ksadk/server/static/assets/wardley-WFR3VGLG-QAt06uEz.js +1 -0
- ksadk/server/static/assets/{wardleyDiagram-VM6X3IG4-eflHNoaZ.js → wardleyDiagram-VM6X3IG4-B5KfDjI-.js} +1 -1
- ksadk/server/static/assets/{xychartDiagram-S5SC5T6Z-eYqrQ-v4.js → xychartDiagram-S5SC5T6Z-BaUlSZrn.js} +1 -1
- ksadk/server/static/index.html +2 -2
- ksadk/server/terminal_sessions.py +34 -2
- ksadk/sessions/invocation_identity.py +235 -0
- ksadk/skills/__init__.py +26 -0
- ksadk/skills/events.py +464 -0
- ksadk/skills/manifest_cache.py +263 -0
- ksadk/skills/mcp_server/__init__.py +0 -0
- ksadk/skills/mcp_server/_registry.py +33 -0
- ksadk/skills/mcp_server/_routing.py +26 -0
- ksadk/skills/mcp_server/_workspace_files.py +160 -0
- ksadk/skills/mcp_server/register.py +415 -0
- ksadk/skills/mcp_server/server.py +218 -0
- ksadk/skills/models.py +11 -0
- ksadk/skills/observability.py +132 -0
- ksadk/skills/package_store.py +75 -2
- ksadk/skills/runtime/agent.py +38 -5
- ksadk/skills/runtime/artifacts.py +87 -0
- ksadk/skills/runtime/backends/e2b.py +393 -52
- ksadk/skills/runtime/backends/local.py +621 -119
- ksadk/skills/runtime/base.py +78 -7
- ksadk/skills/runtime/executor.py +266 -1
- ksadk/skills/runtime/loader.py +108 -3
- ksadk/skills/runtime/request.py +18 -0
- ksadk/skills/tool_defs.py +108 -3
- ksadk/studio/api.py +592 -57
- ksadk/studio/api_contracts.py +8 -2
- ksadk/studio/api_plugin_routes.py +39 -12
- ksadk/studio/api_resource_connections.py +79 -41
- ksadk/studio/authoring.py +12 -6
- ksadk/studio/authoring_coordinator.py +4 -2
- ksadk/studio/builder.py +12 -0
- ksadk/studio/capabilities.py +23 -6
- ksadk/studio/channel_connections.py +333 -0
- ksadk/studio/cloud.py +30 -10
- ksadk/studio/cloud_shared_web.py +75 -2
- ksadk/studio/codex_agent_service.py +2 -2
- ksadk/studio/codex_builder.py +1 -1
- ksadk/studio/codex_run.py +6 -1
- ksadk/studio/compiler.py +10 -0
- ksadk/studio/configuration.py +182 -0
- ksadk/studio/contracts.py +33 -5
- ksadk/studio/dsh_application.py +135 -25
- ksadk/studio/dsh_capability_service.py +287 -20
- ksadk/studio/dsh_lifecycle.py +58 -0
- ksadk/studio/dsh_provider_registration.py +55 -16
- ksadk/studio/entry.py +53 -0
- ksadk/studio/event_store.py +36 -5
- ksadk/studio/execution_host.py +525 -0
- ksadk/studio/framework_run.py +32 -10
- ksadk/studio/hosted_kernel.py +1 -1
- ksadk/studio/kernel_registry.py +418 -0
- ksadk/studio/kernel_sqlite_migration.py +181 -0
- ksadk/studio/model_client.py +1178 -64
- ksadk/studio/model_profile_service.py +26 -11
- ksadk/studio/native_documents.py +172 -0
- ksadk/studio/plugin_composition.py +13 -2
- ksadk/studio/plugin_kernel_adapter.py +15 -0
- ksadk/studio/plugin_lifecycle.py +80 -0
- ksadk/studio/plugin_runtime.py +230 -17
- ksadk/studio/provider_recovery.py +59 -0
- ksadk/studio/recovery_page.py +70 -0
- ksadk/studio/resource_authority.py +59 -32
- ksadk/studio/resource_catalog.py +6 -0
- ksadk/studio/run_activity.py +895 -0
- ksadk/studio/run_documents.py +127 -0
- ksadk/studio/run_service.py +329 -33
- ksadk/studio/runtime_catalog.py +53 -10
- ksadk/studio/runtime_source.py +1 -1
- ksadk/studio/scheduler_runtime.py +32 -289
- ksadk/studio/service.py +398 -103
- ksadk/studio/shared_web.py +149 -36
- ksadk/studio/static/assets/ChannelsPage-D_PGmKVq.js +8 -0
- ksadk/studio/static/assets/CodeBlock-DMIf4h33-UIqo-BPW.js +44 -0
- ksadk/studio/static/assets/ExecutionTree-v3HexvPo-Bk8wzGSy.js +1 -0
- ksadk/studio/static/assets/MathMessageMarkdown-BesSeCYl-OhNwH4K9.js +8 -0
- ksadk/studio/static/assets/MermaidBlock-H_0qzQDf-BdXtxug_.js +11 -0
- ksadk/studio/static/assets/MessageMarkdown-CwMTvgFj-g0I-I4dD.js +59 -0
- ksadk/studio/static/assets/PrismRenderer-5pK6tUdb.js +3 -0
- ksadk/studio/static/assets/TeamsPage-DqX4HWKQ.js +3 -0
- ksadk/studio/static/assets/abnfDiagram-VCTEODGH-Bnb1O3tA.js +1 -0
- ksadk/studio/static/assets/architecture-7GRP2DOG-BMOPAkUC.js +1 -0
- ksadk/studio/static/assets/architectureDiagram-5GKGNRK7-5Zn1gqJv.js +36 -0
- ksadk/studio/static/assets/{blockDiagram-I7D4REHJ-CFmPl1de.js → blockDiagram-I7D4REHJ-CLB4L11u.js} +6 -6
- ksadk/studio/static/assets/{c4Diagram-7LVT6UL2-BRrGu8qt.js → c4Diagram-7LVT6UL2-BOma_Z_F.js} +7 -7
- ksadk/studio/static/assets/channel-r8itPEik.js +1 -0
- ksadk/studio/static/assets/chunk-2E4U76K2-BFf_huql.js +2 -0
- ksadk/studio/static/assets/chunk-2ZTRR5NV-C2qZJila.js +2 -0
- ksadk/studio/static/assets/chunk-3Z5EZCMW-DMniOlPd.js +1 -0
- ksadk/studio/static/assets/{chunk-4HAMMTFA-D220vUtq.js → chunk-4HAMMTFA-DVtDP4rm.js} +7 -7
- ksadk/studio/static/assets/chunk-5V3GS4D5-i-ZDOEnP.js +1 -0
- ksadk/studio/static/assets/chunk-6AZGARVD-BB6FqMl-.js +1 -0
- ksadk/studio/static/assets/chunk-6EIED4P4-DdUJkP0f.js +1 -0
- ksadk/studio/static/assets/chunk-6K3QC6MW-CqVsVn-y.js +1 -0
- ksadk/studio/static/assets/chunk-6TQVIW2G-DKlLbNIP.js +1 -0
- ksadk/studio/static/assets/chunk-747NJXEK-BFkZPlab.js +2 -0
- ksadk/studio/static/assets/chunk-75Z2AOVW-BZNhM4vB.js +2 -0
- ksadk/studio/static/assets/chunk-CLGD4ZFX-D-GTtyKs.js +1 -0
- ksadk/studio/static/assets/{chunk-DU6HZSFF-C4DtVpCu.js → chunk-DU6HZSFF-CpEZCUgg.js} +1 -1
- ksadk/studio/static/assets/chunk-F27PBJKO-D7pvKf0C.js +1 -0
- ksadk/studio/static/assets/{chunk-GMAD6QVW-DiQA-u2N.js → chunk-GMAD6QVW-DE_8H717.js} +6 -6
- ksadk/studio/static/assets/chunk-GVQU2GXP-BfEB0lNv.js +1 -0
- ksadk/studio/static/assets/chunk-I5DQTOEV-Hm2LfiYI.js +1 -0
- ksadk/studio/static/assets/chunk-ICYGCRZG-749o-pGJ.js +1 -0
- ksadk/studio/static/assets/chunk-IH6LHLGP-CC6I9F3i.js +1 -0
- ksadk/studio/static/assets/{chunk-IMKFNOWR-BSlbjT_b.js → chunk-IMKFNOWR-D38axYOR.js} +5 -5
- ksadk/studio/static/assets/chunk-KI3K4JFJ-Rma-0k_M.js +1 -0
- ksadk/studio/static/assets/chunk-L3NEJ4N5-Dq5xn7aL.js +1 -0
- ksadk/studio/static/assets/chunk-LNGE3PJU-DWpGwHrW.js +34 -0
- ksadk/studio/static/assets/{chunk-OSK3NFVY-M2m6G3j4.js → chunk-OSK3NFVY-DiCQjx9b.js} +5 -5
- ksadk/studio/static/assets/chunk-OUJLGHUK-D0j2JRSg.js +2 -0
- ksadk/studio/static/assets/{chunk-P2QGCYS3-DezaQxiK.js → chunk-P2QGCYS3-VdhKmfYq.js} +1 -1
- ksadk/studio/static/assets/chunk-POPQ4Y6H-C1_rzO5M.js +1 -0
- ksadk/studio/static/assets/chunk-PWAF6VOD-B45HvflI.js +1 -0
- ksadk/studio/static/assets/{chunk-SHT3W25Y-DAyIVp5H.js → chunk-SHT3W25Y-DsCFnRVE.js} +9 -9
- ksadk/studio/static/assets/{chunk-SVP7TREG-DulomOrS.js → chunk-SVP7TREG-DljApgRX.js} +1 -1
- ksadk/studio/static/assets/{chunk-TICWLB2K-bHJYoflj.js → chunk-TICWLB2K-DWqRtyqa.js} +6 -6
- ksadk/studio/static/assets/chunk-TLUHSLCS-DUeGgnD5.js +2 -0
- ksadk/studio/static/assets/chunk-UY3FDG6J-CnmaAkG5.js +1 -0
- ksadk/studio/static/assets/chunk-XHIXRSVI-BFQ6B8BE.js +1 -0
- ksadk/studio/static/assets/chunk-XXDRQBXY-DqAYeljN.js +1 -0
- ksadk/studio/static/assets/classDiagram-ZZMXUADV-DjeMNJmu.js +1 -0
- ksadk/studio/static/assets/classDiagram-v2-VYDZK3BY-DjeMNJmu.js +1 -0
- ksadk/studio/static/assets/clsx-DB0hHKMi.js +1 -0
- ksadk/studio/static/assets/cose-bilkent-JH36ORCC-om8AY0Mc.js +1 -0
- ksadk/studio/static/assets/createLucideIcon-DR0LGTP5.js +1 -0
- ksadk/studio/static/assets/cynefin-OW5HDTMX-7tP7QfM3.js +1 -0
- ksadk/studio/static/assets/cynefinDiagram-5FMLGOSQ-6BrmK52S.js +62 -0
- ksadk/studio/static/assets/dagre-GXQ25YYZ-buZBRlwz.js +4 -0
- ksadk/studio/static/assets/{diagram-S7CK7UJ4-0BZ98mya.js → diagram-S7CK7UJ4-C6aH78c4.js} +3 -3
- ksadk/studio/static/assets/diagram-UQ7AKVKN-DY_tQ6C_.js +41 -0
- ksadk/studio/static/assets/diagram-VSXAHHWV-DX9p5cQT.js +3 -0
- ksadk/studio/static/assets/diagram-VX7I27RA-DB2WSH8X.js +24 -0
- ksadk/studio/static/assets/diagram-Z3DM3KII-Ce1BJwHE.js +24 -0
- ksadk/studio/static/assets/ebnfDiagram-PWID7BFC-Daukxwqf.js +1 -0
- ksadk/studio/static/assets/{erDiagram-RLTQ6QDP-DLGry2Ap.js → erDiagram-RLTQ6QDP-CGthTMmJ.js} +6 -6
- ksadk/studio/static/assets/eventmodeling-NTZA5JFV-BR2FzK4R.js +1 -0
- ksadk/studio/static/assets/flowDiagram-HODETNUW-CZ1tEenp.js +1 -0
- ksadk/studio/static/assets/ganttDiagram-EL5Y4UJY-BfoAZW9X.js +292 -0
- ksadk/studio/static/assets/gitGraph-4MIJSDKK-DYlXv_yJ.js +1 -0
- ksadk/studio/static/assets/gitGraphDiagram-WWUBYQGX-S985OIJF.js +106 -0
- ksadk/studio/static/assets/iconfont-4HN3C9Pg.woff2 +0 -0
- ksadk/studio/static/assets/index-CfEnms6Y.css +2 -0
- ksadk/studio/static/assets/index-Dp61rOWZ.js +0 -0
- ksadk/studio/static/assets/index.dom-BQenBtFm.js +1 -0
- ksadk/studio/static/assets/info-A6RAGUB7-BlU-8_xu.js +1 -0
- ksadk/studio/static/assets/infoDiagram-27XIBGKW-CO3W8tFn.js +2 -0
- ksadk/studio/static/assets/{ishikawaDiagram-5VMMS53U-CljI2wyf.js → ishikawaDiagram-5VMMS53U-BUGEl8cO.js} +2 -2
- ksadk/studio/static/assets/{journeyDiagram-3NMN7TZE-D50Fo2sL.js → journeyDiagram-3NMN7TZE-Ch2ZYxvr.js} +6 -6
- ksadk/studio/static/assets/{kanban-definition-UXKFOSKX-DimfOTam.js → kanban-definition-UXKFOSKX-Da-Fp4vC.js} +3 -3
- ksadk/studio/static/assets/kingsoft-cloud-BOcLiQ3e.ico +0 -0
- ksadk/studio/static/assets/{line-CX5BOOUP.js → line-BDaeq300.js} +1 -1
- ksadk/studio/static/assets/linear-DmucvK78.js +1 -0
- ksadk/studio/static/assets/mermaid-parser.core-Cj5mYdBi.js +4 -0
- ksadk/studio/static/assets/{mindmap-definition-YA3MSWOX-Bizzqy5R.js → mindmap-definition-YA3MSWOX-CvlsVQ38.js} +1 -1
- ksadk/studio/static/assets/packet-AYTQ26CC-BSJEH9Lb.js +1 -0
- ksadk/studio/static/assets/pegDiagram-XKGWAZYB-BuHuNgT5.js +1 -0
- ksadk/studio/static/assets/pie-WAS4IAKB-qxv01Y8W.js +1 -0
- ksadk/studio/static/assets/{pieDiagram-E7YTZNPT-B9mrFSDF.js → pieDiagram-E7YTZNPT-DlrWiSOv.js} +1 -1
- ksadk/studio/static/assets/preload-helper-CO68xz6u.js +1 -0
- ksadk/studio/static/assets/presentation-yYw7xK60-BmcZriri.js +1 -0
- ksadk/studio/static/assets/{quadrantDiagram-AXDQQJYC-NzUfCbMR.js → quadrantDiagram-AXDQQJYC-BA3hpUZM.js} +6 -6
- ksadk/studio/static/assets/radar-RG4KPBEZ-B6h6pWOs.js +1 -0
- ksadk/studio/static/assets/railroad-74A4TZTK-CGtTWdGc.js +1 -0
- ksadk/studio/static/assets/railroad-abnf-HS5TGJTU-Cq7y22IA.js +1 -0
- ksadk/studio/static/assets/railroad-ebnf-LZEXJU2U-V0aQVv9m.js +1 -0
- ksadk/studio/static/assets/railroad-peg-WCYAUIDC-BQiIsX_p.js +1 -0
- ksadk/studio/static/assets/railroadDiagram-O6MQD6OU-BxpAazym.js +1 -0
- ksadk/studio/static/assets/{requirementDiagram-BXWQKSXE-BF3d103U.js → requirementDiagram-BXWQKSXE-E-Ge0FcV.js} +1 -1
- ksadk/studio/static/assets/sankeyDiagram-P5KCCOFB-CA6YKhQ3.js +40 -0
- ksadk/studio/static/assets/{sequenceDiagram-WJ2MYXX4-Dh4wZtUm.js → sequenceDiagram-WJ2MYXX4-CcElXGg4.js} +9 -9
- ksadk/studio/static/assets/src-B6xuSHsQ.js +1 -0
- ksadk/studio/static/assets/stateDiagram-D77RDMKH-DdXZOFqY.js +1 -0
- ksadk/studio/static/assets/stateDiagram-v2-MP3YSRHH-CJbOM-QK.js +1 -0
- ksadk/studio/static/assets/swimlanes-42K2YHIH-NtgEEHLY.js +1 -0
- ksadk/studio/static/assets/swimlanesDiagram-VR7AAH4N-D-AVlW8B.js +8 -0
- ksadk/studio/static/assets/{timeline-definition-24CTP7MA-DxmSSjRB.js → timeline-definition-24CTP7MA-CIuYhNy3.js} +7 -7
- ksadk/studio/static/assets/treeView-Q6P3EWNA-BTTYcvrF.js +1 -0
- ksadk/studio/static/assets/treemap-WGGIJYW6-Cg7tyfH8.js +1 -0
- ksadk/studio/static/assets/vennDiagram-4TSXK5OY-7HbApbrv.js +34 -0
- ksadk/studio/static/assets/wardley-WFR3VGLG-C6N1rULY.js +1 -0
- ksadk/studio/static/assets/{wardleyDiagram-VM6X3IG4-Ba1AOWoe.js → wardleyDiagram-VM6X3IG4-CMJiaedy.js} +1 -1
- ksadk/studio/static/assets/{xychartDiagram-S5SC5T6Z-Cr5pt5Y-.js → xychartDiagram-S5SC5T6Z-BdgtMvW2.js} +6 -6
- ksadk/studio/static/index.html +8 -2
- ksadk/studio/teams_catalog.py +133 -0
- ksadk/studio/teams_installation.py +214 -0
- ksadk/studio/teams_node.py +545 -0
- ksadk/studio/teams_node_runner.py +69 -0
- ksadk/studio/teams_remote.py +274 -0
- ksadk/studio/templates.py +40 -19
- ksadk/studio/validator.py +13 -0
- ksadk/studio/workspace.py +19 -4
- ksadk/studio/workspace_plugins.py +136 -0
- ksadk/studio/workspace_registry.py +286 -0
- ksadk/toolsets/__init__.py +11 -0
- ksadk/toolsets/skills.py +446 -378
- ksadk/toolsets/workspace.py +3 -3
- ksadk/toolsets/workspace_identity.py +15 -0
- ksadk/version.py +1 -1
- ksadk_runtime_common/memory_backend/providers/lancedb.py +56 -2
- ksadk_runtime_common/schemas/memory_backend_manifest.schema.json +148 -148
- ksadk_runtime_common/workspace_files/router.py +26 -13
- ksadk/server/static/assets/MathMessageMarkdown-DbdW5A4_.js +0 -8
- ksadk/server/static/assets/architecture-7GRP2DOG-BW5UtSnx.js +0 -1
- ksadk/server/static/assets/channel-CF5Up3hQ.js +0 -1
- ksadk/server/static/assets/chunk-2Q5K7J3B-KkXX47WI.js +0 -1
- ksadk/server/static/assets/classDiagram-DTDB5LWJ-Cz81acRQ.js +0 -1
- ksadk/server/static/assets/classDiagram-v2-JRS7N3AN-Cz81acRQ.js +0 -1
- ksadk/server/static/assets/cynefin-OW5HDTMX-DVWs8a2t.js +0 -1
- ksadk/server/static/assets/dist-B2_CVgKv.js +0 -1
- ksadk/server/static/assets/eventmodeling-NTZA5JFV-CQqR2hg3.js +0 -1
- ksadk/server/static/assets/flowDiagram-A5DVABFB-DDRRbGPm.js +0 -1
- ksadk/server/static/assets/gitGraph-4MIJSDKK-fgWEf7UD.js +0 -1
- ksadk/server/static/assets/index-DcTML1Up.css +0 -2
- ksadk/server/static/assets/index-Dh2XHqPK.js +0 -244
- ksadk/server/static/assets/info-A6RAGUB7-BUecLTdt.js +0 -1
- ksadk/server/static/assets/packet-AYTQ26CC-BeW-btFv.js +0 -1
- ksadk/server/static/assets/pie-WAS4IAKB-X0xh4SaT.js +0 -1
- ksadk/server/static/assets/radar-RG4KPBEZ-DzRMSqjd.js +0 -1
- ksadk/server/static/assets/railroad-74A4TZTK-Cc44icX-.js +0 -1
- ksadk/server/static/assets/railroad-abnf-HS5TGJTU-D6S4BdV-.js +0 -1
- ksadk/server/static/assets/railroad-ebnf-LZEXJU2U-vD3aVE2o.js +0 -1
- ksadk/server/static/assets/railroad-peg-WCYAUIDC-CYbW_b4T.js +0 -1
- ksadk/server/static/assets/stateDiagram-v2-4QOOHH4V-BIcjKFhF.js +0 -1
- ksadk/server/static/assets/swimlanesDiagram-VK2B7HYN-tq3K3Ybl.js +0 -8
- ksadk/server/static/assets/treeView-Q6P3EWNA-DBXt3GdU.js +0 -1
- ksadk/server/static/assets/treemap-WGGIJYW6-DrCy4E_l.js +0 -1
- ksadk/server/static/assets/wardley-WFR3VGLG-CefhOliM.js +0 -1
- ksadk/studio/static/assets/CodeBlock-DCUUY0PL-BLjA7kbS.js +0 -41
- ksadk/studio/static/assets/MathMessageMarkdown-CBcDrAw--CUYIXwgI.js +0 -8
- ksadk/studio/static/assets/MermaidBlock-DBFTztfQ-BTYKWEbD.js +0 -44
- ksadk/studio/static/assets/PrismRenderer-wiXRHURw.js +0 -3
- ksadk/studio/static/assets/abnfDiagram-VCTEODGH-CLETGjKq.js +0 -1
- ksadk/studio/static/assets/architecture-7GRP2DOG-hXMiO_AU.js +0 -1
- ksadk/studio/static/assets/architectureDiagram-5GKGNRK7-B5EQysk6.js +0 -36
- ksadk/studio/static/assets/channel-BqO-gtEw.js +0 -1
- ksadk/studio/static/assets/chunk-75Z2AOVW-C8lLv_qc.js +0 -2
- ksadk/studio/static/assets/chunk-F27PBJKO-Cpw14SNG.js +0 -1
- ksadk/studio/static/assets/chunk-GVQU2GXP-DUdNBUCi.js +0 -1
- ksadk/studio/static/assets/chunk-L3NEJ4N5-Db8Ab22W.js +0 -1
- ksadk/studio/static/assets/chunk-POPQ4Y6H-DOpufJ3t.js +0 -1
- ksadk/studio/static/assets/chunk-PWAF6VOD-CfLb1gSc.js +0 -1
- ksadk/studio/static/assets/chunk-XXDRQBXY-7PcdR2B1.js +0 -1
- ksadk/studio/static/assets/classDiagram-ZZMXUADV-D_bW8JjA.js +0 -1
- ksadk/studio/static/assets/classDiagram-v2-VYDZK3BY-D_bW8JjA.js +0 -1
- ksadk/studio/static/assets/cose-bilkent-JH36ORCC-snL88wkX.js +0 -1
- ksadk/studio/static/assets/cynefin-OW5HDTMX-Bd1YhRo1.js +0 -1
- ksadk/studio/static/assets/cynefinDiagram-5FMLGOSQ-BBrIG_mI.js +0 -62
- ksadk/studio/static/assets/dagre-GXQ25YYZ-DtF1nGdY.js +0 -4
- ksadk/studio/static/assets/diagram-UQ7AKVKN-6mLKEo6L.js +0 -41
- ksadk/studio/static/assets/diagram-VSXAHHWV-CJBIaiZ2.js +0 -3
- ksadk/studio/static/assets/diagram-VX7I27RA-BohLEE1C.js +0 -24
- ksadk/studio/static/assets/diagram-Z3DM3KII-D8KIGonG.js +0 -24
- ksadk/studio/static/assets/ebnfDiagram-PWID7BFC-C99HU61t.js +0 -1
- ksadk/studio/static/assets/eventmodeling-NTZA5JFV-B1_5Ac8j.js +0 -1
- ksadk/studio/static/assets/flowDiagram-HODETNUW-DD5hmicn.js +0 -1
- ksadk/studio/static/assets/ganttDiagram-EL5Y4UJY-BPJrVLSG.js +0 -292
- ksadk/studio/static/assets/gitGraph-4MIJSDKK-Cy_ZQBGi.js +0 -1
- ksadk/studio/static/assets/gitGraphDiagram-WWUBYQGX-CZCUz4MT.js +0 -106
- ksadk/studio/static/assets/index-CeHL9ARV.css +0 -2
- ksadk/studio/static/assets/index-D9QEcVpL.js +0 -320
- ksadk/studio/static/assets/info-A6RAGUB7-DBzDQB_I.js +0 -1
- ksadk/studio/static/assets/infoDiagram-27XIBGKW-B-sq07Hi.js +0 -2
- ksadk/studio/static/assets/linear-BCxN9JLv.js +0 -1
- ksadk/studio/static/assets/mermaid-parser.core-BdCz8fkS.js +0 -7
- ksadk/studio/static/assets/packet-AYTQ26CC-gPln-_kG.js +0 -1
- ksadk/studio/static/assets/pegDiagram-XKGWAZYB-Dy3fB-gW.js +0 -1
- ksadk/studio/static/assets/pie-WAS4IAKB-qZdHMr7B.js +0 -1
- ksadk/studio/static/assets/radar-RG4KPBEZ-BZlnaea9.js +0 -1
- ksadk/studio/static/assets/railroad-74A4TZTK-Ce3__H9c.js +0 -1
- ksadk/studio/static/assets/railroad-abnf-HS5TGJTU-DqQn7EzD.js +0 -1
- ksadk/studio/static/assets/railroad-ebnf-LZEXJU2U-B55kCA8F.js +0 -1
- ksadk/studio/static/assets/railroad-peg-WCYAUIDC-DfQnvkHd.js +0 -1
- ksadk/studio/static/assets/railroadDiagram-O6MQD6OU-DnhMjZCk.js +0 -1
- ksadk/studio/static/assets/sankeyDiagram-P5KCCOFB-Bo-JTwt0.js +0 -40
- ksadk/studio/static/assets/src-SFn9St9H.js +0 -1
- ksadk/studio/static/assets/stateDiagram-D77RDMKH-DH774G6d.js +0 -1
- ksadk/studio/static/assets/stateDiagram-v2-MP3YSRHH-DZvVWPBo.js +0 -1
- ksadk/studio/static/assets/swimlanes-42K2YHIH-Bl13OvTX.js +0 -1
- ksadk/studio/static/assets/swimlanesDiagram-VR7AAH4N-BnFOTALJ.js +0 -8
- ksadk/studio/static/assets/treeView-Q6P3EWNA-D5Nn9Swz.js +0 -1
- ksadk/studio/static/assets/treemap-WGGIJYW6-CgHgnQhE.js +0 -1
- ksadk/studio/static/assets/vennDiagram-4TSXK5OY-B9QEXcJq.js +0 -34
- ksadk/studio/static/assets/wardley-WFR3VGLG-DXrK2RRY.js +0 -1
- {agentengine_sdk_python-0.8.4.dist-info → agentengine_sdk_python-0.8.5.dist-info}/WHEEL +0 -0
- {agentengine_sdk_python-0.8.4.dist-info → agentengine_sdk_python-0.8.5.dist-info}/entry_points.txt +0 -0
- {agentengine_sdk_python-0.8.4.dist-info → agentengine_sdk_python-0.8.5.dist-info}/licenses/LICENSE +0 -0
- {agentengine_sdk_python-0.8.4.dist-info → agentengine_sdk_python-0.8.5.dist-info}/top_level.txt +0 -0
- /ksadk/studio/static/assets/{MathMessageMarkdown-CBcDrAw--BEOyPC3w.css → MathMessageMarkdown-BesSeCYl-BEOyPC3w.css} +0 -0
|
@@ -0,0 +1,477 @@
|
|
|
1
|
+
"""Outbound WebSocket connector for a local Agent and Channel Gateway."""
|
|
2
|
+
|
|
3
|
+
from __future__ import annotations
|
|
4
|
+
|
|
5
|
+
import asyncio
|
|
6
|
+
import contextlib
|
|
7
|
+
import inspect
|
|
8
|
+
import ipaddress
|
|
9
|
+
import json
|
|
10
|
+
import logging
|
|
11
|
+
import time
|
|
12
|
+
from collections import OrderedDict
|
|
13
|
+
from dataclasses import dataclass
|
|
14
|
+
from datetime import datetime, timezone
|
|
15
|
+
from typing import Any, Awaitable, Callable
|
|
16
|
+
from urllib.parse import parse_qsl, urlencode, urlsplit, urlunsplit
|
|
17
|
+
|
|
18
|
+
logger = logging.getLogger(__name__)
|
|
19
|
+
_MAX_BACKOFF = 60.0
|
|
20
|
+
_BASE_BACKOFF = 1.0
|
|
21
|
+
_DEFAULT_TIMEOUT = 300.0
|
|
22
|
+
_TERMINAL_CACHE_SIZE = 1024
|
|
23
|
+
_STOP_TASK_TIMEOUT = 2.0
|
|
24
|
+
_BACKOFF_RESET_AFTER = 5.0
|
|
25
|
+
|
|
26
|
+
|
|
27
|
+
@dataclass(frozen=True)
|
|
28
|
+
class InvokeRequest:
|
|
29
|
+
"""The complete invocation context delivered by the Channel Gateway."""
|
|
30
|
+
|
|
31
|
+
task_id: str
|
|
32
|
+
session_id: str
|
|
33
|
+
message: str
|
|
34
|
+
channel: str = ""
|
|
35
|
+
deadline: datetime | None = None
|
|
36
|
+
idempotency_key: str = ""
|
|
37
|
+
|
|
38
|
+
@classmethod
|
|
39
|
+
def from_payload(cls, payload: dict[str, Any]) -> "InvokeRequest":
|
|
40
|
+
task_id = str(payload.get("task_id") or "").strip()
|
|
41
|
+
if not task_id:
|
|
42
|
+
raise ProtocolError("invoke requires task_id")
|
|
43
|
+
deadline = payload.get("deadline")
|
|
44
|
+
parsed_deadline: datetime | None = None
|
|
45
|
+
if deadline:
|
|
46
|
+
if not isinstance(deadline, str):
|
|
47
|
+
raise ProtocolError("invoke deadline must be an ISO-8601 string")
|
|
48
|
+
try:
|
|
49
|
+
parsed_deadline = datetime.fromisoformat(deadline.replace("Z", "+00:00"))
|
|
50
|
+
except ValueError as exc:
|
|
51
|
+
raise ProtocolError("invoke deadline is not valid ISO-8601") from exc
|
|
52
|
+
if parsed_deadline.tzinfo is None:
|
|
53
|
+
parsed_deadline = parsed_deadline.replace(tzinfo=timezone.utc)
|
|
54
|
+
else:
|
|
55
|
+
parsed_deadline = parsed_deadline.astimezone(timezone.utc)
|
|
56
|
+
return cls(
|
|
57
|
+
task_id=task_id,
|
|
58
|
+
session_id=str(payload.get("session_id") or ""),
|
|
59
|
+
message=str(payload.get("message") or ""),
|
|
60
|
+
channel=str(payload.get("channel") or ""),
|
|
61
|
+
deadline=parsed_deadline,
|
|
62
|
+
idempotency_key=str(payload.get("idempotency_key") or ""),
|
|
63
|
+
)
|
|
64
|
+
|
|
65
|
+
def remaining_seconds(self, *, now: datetime | None = None) -> float | None:
|
|
66
|
+
if self.deadline is None:
|
|
67
|
+
return None
|
|
68
|
+
current = now or datetime.now(timezone.utc)
|
|
69
|
+
if current.tzinfo is None:
|
|
70
|
+
current = current.replace(tzinfo=timezone.utc)
|
|
71
|
+
return (self.deadline - current.astimezone(timezone.utc)).total_seconds()
|
|
72
|
+
|
|
73
|
+
|
|
74
|
+
InvokeFn = Callable[[InvokeRequest], Awaitable[str]]
|
|
75
|
+
|
|
76
|
+
|
|
77
|
+
@dataclass(frozen=True)
|
|
78
|
+
class ConnectorStatus:
|
|
79
|
+
"""Safe-to-display lifecycle snapshot; it never contains a token."""
|
|
80
|
+
|
|
81
|
+
state: str
|
|
82
|
+
connected: bool
|
|
83
|
+
active_tasks: int
|
|
84
|
+
last_error: str | None
|
|
85
|
+
|
|
86
|
+
|
|
87
|
+
@dataclass(frozen=True)
|
|
88
|
+
class _Terminal:
|
|
89
|
+
msg_type: str
|
|
90
|
+
payload: dict[str, Any]
|
|
91
|
+
|
|
92
|
+
|
|
93
|
+
class ChannelConnector:
|
|
94
|
+
"""Maintain an outbound WSS connection and execute gateway invocations."""
|
|
95
|
+
|
|
96
|
+
def __init__(
|
|
97
|
+
self,
|
|
98
|
+
*,
|
|
99
|
+
url: str,
|
|
100
|
+
token: str,
|
|
101
|
+
agent_id: str,
|
|
102
|
+
tenant_id: str,
|
|
103
|
+
workspace_id: str,
|
|
104
|
+
invoke: InvokeFn,
|
|
105
|
+
capabilities: list[str] | None = None,
|
|
106
|
+
default_timeout: float = _DEFAULT_TIMEOUT,
|
|
107
|
+
completed_cache_size: int = _TERMINAL_CACHE_SIZE,
|
|
108
|
+
) -> None:
|
|
109
|
+
if default_timeout <= 0:
|
|
110
|
+
raise ValueError("default_timeout must be positive")
|
|
111
|
+
if completed_cache_size <= 0:
|
|
112
|
+
raise ValueError("completed_cache_size must be positive")
|
|
113
|
+
parts = urlsplit(url)
|
|
114
|
+
try:
|
|
115
|
+
loopback = (
|
|
116
|
+
parts.hostname == "localhost"
|
|
117
|
+
or ipaddress.ip_address(parts.hostname or "").is_loopback
|
|
118
|
+
)
|
|
119
|
+
except ValueError:
|
|
120
|
+
loopback = False
|
|
121
|
+
if (
|
|
122
|
+
not parts.hostname
|
|
123
|
+
or parts.username
|
|
124
|
+
or parts.password
|
|
125
|
+
or parts.fragment
|
|
126
|
+
or any(ord(char) < 33 for char in url)
|
|
127
|
+
or not (parts.scheme == "wss" or parts.scheme == "ws" and loopback)
|
|
128
|
+
):
|
|
129
|
+
raise ValueError("connector requires WSS (loopback WS is allowed for development)")
|
|
130
|
+
_ = parts.port
|
|
131
|
+
self._url = url
|
|
132
|
+
self._token = token
|
|
133
|
+
self._agent_id = agent_id
|
|
134
|
+
self._tenant_id = tenant_id
|
|
135
|
+
self._workspace_id = workspace_id
|
|
136
|
+
self._invoke = invoke
|
|
137
|
+
self._capabilities = list(capabilities or ["invoke", "cancel"])
|
|
138
|
+
self._default_timeout = default_timeout
|
|
139
|
+
self._completed_cache_size = completed_cache_size
|
|
140
|
+
self._seq = 0
|
|
141
|
+
self._tasks: dict[str, asyncio.Task[None]] = {}
|
|
142
|
+
self._requests: dict[str, InvokeRequest] = {}
|
|
143
|
+
self._cancel_requested: set[str] = set()
|
|
144
|
+
self._completed: OrderedDict[str, _Terminal] = OrderedDict()
|
|
145
|
+
self._pending_terminal: set[str] = set()
|
|
146
|
+
self._stop = asyncio.Event()
|
|
147
|
+
self._send_lock = asyncio.Lock()
|
|
148
|
+
self._ws: Any = None
|
|
149
|
+
self._started = False
|
|
150
|
+
self._state = "new"
|
|
151
|
+
self._last_error: str | None = None
|
|
152
|
+
|
|
153
|
+
@property
|
|
154
|
+
def status(self) -> ConnectorStatus:
|
|
155
|
+
return ConnectorStatus(
|
|
156
|
+
state=self._state,
|
|
157
|
+
connected=self._ws is not None and self._state == "connected",
|
|
158
|
+
active_tasks=len(self._tasks),
|
|
159
|
+
last_error=self._last_error,
|
|
160
|
+
)
|
|
161
|
+
|
|
162
|
+
def _next_seq(self) -> int:
|
|
163
|
+
self._seq += 1
|
|
164
|
+
return self._seq
|
|
165
|
+
|
|
166
|
+
def _envelope(self, msg_type: str, payload: dict[str, Any]) -> str:
|
|
167
|
+
return json.dumps(
|
|
168
|
+
{
|
|
169
|
+
"type": msg_type,
|
|
170
|
+
"seq": self._next_seq(),
|
|
171
|
+
"ts": time.strftime("%Y-%m-%dT%H:%M:%SZ", time.gmtime()),
|
|
172
|
+
"payload": payload,
|
|
173
|
+
},
|
|
174
|
+
ensure_ascii=False,
|
|
175
|
+
)
|
|
176
|
+
|
|
177
|
+
def _connection_url(self) -> str:
|
|
178
|
+
parts = urlsplit(self._url)
|
|
179
|
+
query = [(key, value) for key, value in parse_qsl(parts.query) if key != "token"]
|
|
180
|
+
return urlunsplit(
|
|
181
|
+
(parts.scheme, parts.netloc, parts.path, urlencode(query), parts.fragment)
|
|
182
|
+
)
|
|
183
|
+
|
|
184
|
+
async def start(self) -> None:
|
|
185
|
+
"""Run until :meth:`stop` is called, reconnecting with bounded backoff."""
|
|
186
|
+
if self._started:
|
|
187
|
+
raise RuntimeError("channel connector already started")
|
|
188
|
+
self._started = True
|
|
189
|
+
import websockets
|
|
190
|
+
|
|
191
|
+
# websockets 14 renamed extra_headers when the asyncio client became
|
|
192
|
+
# the default. Keep the supported 12-15 range without putting bearer
|
|
193
|
+
# credentials into URLs that HTTP/WS access loggers commonly record.
|
|
194
|
+
header_option = (
|
|
195
|
+
"additional_headers"
|
|
196
|
+
if "additional_headers" in inspect.signature(websockets.connect).parameters
|
|
197
|
+
else "extra_headers"
|
|
198
|
+
)
|
|
199
|
+
connection_options = {header_option: {"Authorization": f"Bearer {self._token}"}}
|
|
200
|
+
backoff = _BASE_BACKOFF
|
|
201
|
+
self._state = "connecting"
|
|
202
|
+
try:
|
|
203
|
+
while not self._stop.is_set():
|
|
204
|
+
try:
|
|
205
|
+
self._state = "connecting"
|
|
206
|
+
async with websockets.connect(
|
|
207
|
+
self._connection_url(),
|
|
208
|
+
ping_interval=None,
|
|
209
|
+
close_timeout=5,
|
|
210
|
+
**connection_options,
|
|
211
|
+
) as ws:
|
|
212
|
+
self._ws = ws
|
|
213
|
+
self._state = "registering"
|
|
214
|
+
await self._register(ws)
|
|
215
|
+
self._state = "connected"
|
|
216
|
+
self._last_error = None
|
|
217
|
+
connected_at = time.monotonic()
|
|
218
|
+
await self._flush_pending_terminal(ws)
|
|
219
|
+
await self._read_loop(ws)
|
|
220
|
+
# A clean peer close is still a disconnect. Turn it
|
|
221
|
+
# into the same bounded backoff path as a socket error
|
|
222
|
+
# instead of spinning a hot reconnect loop.
|
|
223
|
+
if time.monotonic() - connected_at >= _BACKOFF_RESET_AFTER:
|
|
224
|
+
backoff = _BASE_BACKOFF
|
|
225
|
+
if not self._stop.is_set():
|
|
226
|
+
raise ConnectionError("connection closed by peer")
|
|
227
|
+
except asyncio.CancelledError:
|
|
228
|
+
raise
|
|
229
|
+
except Exception:
|
|
230
|
+
if self._stop.is_set():
|
|
231
|
+
break
|
|
232
|
+
self._state = "backoff"
|
|
233
|
+
self._last_error = "connection_failed"
|
|
234
|
+
logger.warning("channel connector disconnected; retrying in %.0fs", backoff)
|
|
235
|
+
with contextlib.suppress(asyncio.TimeoutError):
|
|
236
|
+
await asyncio.wait_for(self._stop.wait(), timeout=backoff)
|
|
237
|
+
backoff = min(backoff * 2, _MAX_BACKOFF)
|
|
238
|
+
finally:
|
|
239
|
+
self._ws = None
|
|
240
|
+
if not self._stop.is_set():
|
|
241
|
+
self._state = "connecting"
|
|
242
|
+
finally:
|
|
243
|
+
self._state = "stopped" if self._stop.is_set() else "disconnected"
|
|
244
|
+
self._started = False
|
|
245
|
+
|
|
246
|
+
async def stop(self) -> None:
|
|
247
|
+
self._stop.set()
|
|
248
|
+
self._state = "stopping"
|
|
249
|
+
ws = self._ws
|
|
250
|
+
if ws is not None:
|
|
251
|
+
with contextlib.suppress(Exception):
|
|
252
|
+
await ws.close()
|
|
253
|
+
await self._cancel_all_tasks()
|
|
254
|
+
self._state = "stopped"
|
|
255
|
+
|
|
256
|
+
async def _cancel_all_tasks(self) -> None:
|
|
257
|
+
current = asyncio.current_task()
|
|
258
|
+
tasks = [task for task in self._tasks.values() if task is not current]
|
|
259
|
+
for task in tasks:
|
|
260
|
+
task.cancel()
|
|
261
|
+
if tasks:
|
|
262
|
+
done, pending = await asyncio.wait(tasks, timeout=_STOP_TASK_TIMEOUT)
|
|
263
|
+
# Retrieve ordinary exceptions and CancelledError without masking
|
|
264
|
+
# cancellation of the caller of stop().
|
|
265
|
+
await asyncio.gather(*done, return_exceptions=True)
|
|
266
|
+
if pending:
|
|
267
|
+
logger.warning("%d channel invoke task(s) did not cancel promptly", len(pending))
|
|
268
|
+
for task in pending:
|
|
269
|
+
task.cancel()
|
|
270
|
+
task.add_done_callback(self._consume_task_result)
|
|
271
|
+
# A non-cooperative callback may outlive the bounded shutdown wait; it
|
|
272
|
+
# must not remain visible as an owned connector task or block shutdown.
|
|
273
|
+
self._tasks.clear()
|
|
274
|
+
self._requests.clear()
|
|
275
|
+
self._cancel_requested.clear()
|
|
276
|
+
|
|
277
|
+
@staticmethod
|
|
278
|
+
def _consume_task_result(task: asyncio.Task[Any]) -> None:
|
|
279
|
+
with contextlib.suppress(asyncio.CancelledError, Exception):
|
|
280
|
+
task.exception()
|
|
281
|
+
|
|
282
|
+
async def _send(self, ws: Any, msg_type: str, payload: dict[str, Any]) -> bool:
|
|
283
|
+
if self._ws is not ws:
|
|
284
|
+
return False
|
|
285
|
+
frame = self._envelope(msg_type, payload)
|
|
286
|
+
try:
|
|
287
|
+
async with self._send_lock:
|
|
288
|
+
if self._ws is not ws:
|
|
289
|
+
return False
|
|
290
|
+
await ws.send(frame)
|
|
291
|
+
return True
|
|
292
|
+
except Exception:
|
|
293
|
+
return False
|
|
294
|
+
|
|
295
|
+
async def _register(self, ws: Any) -> None:
|
|
296
|
+
await ws.send(
|
|
297
|
+
self._envelope(
|
|
298
|
+
"register",
|
|
299
|
+
{
|
|
300
|
+
"tenant_id": self._tenant_id,
|
|
301
|
+
"workspace_id": self._workspace_id,
|
|
302
|
+
"agent_id": self._agent_id,
|
|
303
|
+
"capabilities": self._capabilities,
|
|
304
|
+
"protocol_version": 1,
|
|
305
|
+
},
|
|
306
|
+
)
|
|
307
|
+
)
|
|
308
|
+
raw = await asyncio.wait_for(ws.recv(), timeout=5)
|
|
309
|
+
msg = json.loads(raw)
|
|
310
|
+
if msg.get("type") == "register_err":
|
|
311
|
+
error_payload = msg.get("payload") or {}
|
|
312
|
+
if not isinstance(error_payload, dict):
|
|
313
|
+
error_payload = {}
|
|
314
|
+
code = str(error_payload.get("code") or "registration_rejected")
|
|
315
|
+
raise ConnectionRefusedError(code)
|
|
316
|
+
if msg.get("type") != "register_ok":
|
|
317
|
+
raise ProtocolError(f"expected register_ok, got {msg.get('type')}")
|
|
318
|
+
payload = msg.get("payload") or {}
|
|
319
|
+
if not isinstance(payload, dict):
|
|
320
|
+
raise ProtocolError("register_ok payload must be an object")
|
|
321
|
+
identity = payload.get("identity") if isinstance(payload.get("identity"), dict) else payload
|
|
322
|
+
expected_identity = (
|
|
323
|
+
("tenant_id", self._tenant_id),
|
|
324
|
+
("workspace_id", self._workspace_id),
|
|
325
|
+
("agent_id", self._agent_id),
|
|
326
|
+
)
|
|
327
|
+
for key, expected in expected_identity:
|
|
328
|
+
returned = identity.get(key)
|
|
329
|
+
if returned is not None and str(returned) != expected:
|
|
330
|
+
raise ProtocolError(f"register identity mismatch: {key}")
|
|
331
|
+
|
|
332
|
+
async def _flush_pending_terminal(self, ws: Any) -> None:
|
|
333
|
+
for task_id in list(self._pending_terminal):
|
|
334
|
+
terminal = self._completed.get(task_id)
|
|
335
|
+
if terminal is None:
|
|
336
|
+
self._pending_terminal.discard(task_id)
|
|
337
|
+
continue
|
|
338
|
+
if await self._send(ws, terminal.msg_type, terminal.payload):
|
|
339
|
+
self._pending_terminal.discard(task_id)
|
|
340
|
+
|
|
341
|
+
async def _read_loop(self, ws: Any) -> None:
|
|
342
|
+
async for raw in ws:
|
|
343
|
+
msg = json.loads(raw)
|
|
344
|
+
if not isinstance(msg, dict):
|
|
345
|
+
raise ProtocolError("frame must be an object")
|
|
346
|
+
msg_type = msg.get("type")
|
|
347
|
+
payload = msg.get("payload") or {}
|
|
348
|
+
if not isinstance(payload, dict):
|
|
349
|
+
raise ProtocolError("payload must be an object")
|
|
350
|
+
if msg_type == "invoke":
|
|
351
|
+
await self._spawn_invoke(payload, ws)
|
|
352
|
+
elif msg_type == "ping":
|
|
353
|
+
await self._send(ws, "pong", {})
|
|
354
|
+
elif msg_type == "cancel":
|
|
355
|
+
await self._cancel_remote(str(payload.get("task_id") or ""))
|
|
356
|
+
|
|
357
|
+
async def _spawn_invoke(self, payload: dict[str, Any], ws: Any | None = None) -> None:
|
|
358
|
+
request = InvokeRequest.from_payload(payload)
|
|
359
|
+
if request.task_id in self._completed:
|
|
360
|
+
terminal = self._completed[request.task_id]
|
|
361
|
+
await self._send(ws or self._ws, terminal.msg_type, terminal.payload)
|
|
362
|
+
return
|
|
363
|
+
if request.task_id in self._tasks:
|
|
364
|
+
return
|
|
365
|
+
self._requests[request.task_id] = request
|
|
366
|
+
self._tasks[request.task_id] = asyncio.create_task(self._execute(request))
|
|
367
|
+
|
|
368
|
+
async def _cancel_remote(self, task_id: str) -> None:
|
|
369
|
+
if not task_id:
|
|
370
|
+
return
|
|
371
|
+
task = self._tasks.get(task_id)
|
|
372
|
+
if task is not None:
|
|
373
|
+
self._cancel_requested.add(task_id)
|
|
374
|
+
task.cancel()
|
|
375
|
+
|
|
376
|
+
async def _execute(self, request: InvokeRequest) -> None:
|
|
377
|
+
task_id = request.task_id
|
|
378
|
+
try:
|
|
379
|
+
remaining = request.remaining_seconds()
|
|
380
|
+
if remaining is not None and remaining <= 0:
|
|
381
|
+
await self._finish(
|
|
382
|
+
task_id,
|
|
383
|
+
"error",
|
|
384
|
+
{
|
|
385
|
+
"task_id": task_id,
|
|
386
|
+
"code": "deadline_exceeded",
|
|
387
|
+
"message": "deadline exceeded",
|
|
388
|
+
},
|
|
389
|
+
)
|
|
390
|
+
return
|
|
391
|
+
timeout = (
|
|
392
|
+
self._default_timeout
|
|
393
|
+
if remaining is None
|
|
394
|
+
else min(self._default_timeout, remaining)
|
|
395
|
+
)
|
|
396
|
+
result = await asyncio.wait_for(self._invoke(request), timeout=timeout)
|
|
397
|
+
await self._finish(task_id, "complete", {"task_id": task_id, "result": str(result)})
|
|
398
|
+
except asyncio.CancelledError:
|
|
399
|
+
if task_id in self._cancel_requested:
|
|
400
|
+
await self._finish(
|
|
401
|
+
task_id,
|
|
402
|
+
"error",
|
|
403
|
+
{"task_id": task_id, "code": "cancelled", "message": "task cancelled"},
|
|
404
|
+
)
|
|
405
|
+
raise
|
|
406
|
+
except asyncio.TimeoutError:
|
|
407
|
+
await self._finish(
|
|
408
|
+
task_id,
|
|
409
|
+
"error",
|
|
410
|
+
{"task_id": task_id, "code": "deadline_exceeded", "message": "deadline exceeded"},
|
|
411
|
+
)
|
|
412
|
+
except Exception as exc:
|
|
413
|
+
# Do not log exception text: Agent errors may contain credentials or
|
|
414
|
+
# user content. The wire error is intentionally generic as well.
|
|
415
|
+
logger.warning("channel invoke failed (%s)", type(exc).__name__)
|
|
416
|
+
await self._finish(
|
|
417
|
+
task_id,
|
|
418
|
+
"error",
|
|
419
|
+
{
|
|
420
|
+
"task_id": task_id,
|
|
421
|
+
"code": "execution_error",
|
|
422
|
+
"message": "agent invocation failed",
|
|
423
|
+
},
|
|
424
|
+
)
|
|
425
|
+
finally:
|
|
426
|
+
self._tasks.pop(task_id, None)
|
|
427
|
+
self._requests.pop(task_id, None)
|
|
428
|
+
self._cancel_requested.discard(task_id)
|
|
429
|
+
|
|
430
|
+
async def _finish(self, task_id: str, msg_type: str, payload: dict[str, Any]) -> None:
|
|
431
|
+
self._completed[task_id] = _Terminal(msg_type, payload)
|
|
432
|
+
self._completed.move_to_end(task_id)
|
|
433
|
+
while len(self._completed) > self._completed_cache_size:
|
|
434
|
+
old_task_id, _ = self._completed.popitem(last=False)
|
|
435
|
+
self._pending_terminal.discard(old_task_id)
|
|
436
|
+
ws = self._ws
|
|
437
|
+
if ws is None or not await self._send(ws, msg_type, payload):
|
|
438
|
+
self._pending_terminal.add(task_id)
|
|
439
|
+
|
|
440
|
+
|
|
441
|
+
class ProtocolError(Exception):
|
|
442
|
+
"""The peer sent a frame that violates the connector protocol."""
|
|
443
|
+
|
|
444
|
+
|
|
445
|
+
def create_channel_connector(
|
|
446
|
+
*,
|
|
447
|
+
url: str,
|
|
448
|
+
token: str,
|
|
449
|
+
agent_id: str,
|
|
450
|
+
tenant_id: str,
|
|
451
|
+
workspace_id: str,
|
|
452
|
+
invoke: InvokeFn,
|
|
453
|
+
capabilities: list[str] | None = None,
|
|
454
|
+
default_timeout: float = _DEFAULT_TIMEOUT,
|
|
455
|
+
completed_cache_size: int = _TERMINAL_CACHE_SIZE,
|
|
456
|
+
) -> ChannelConnector:
|
|
457
|
+
"""Create a connector; the host starts it with ``await connector.start()``."""
|
|
458
|
+
return ChannelConnector(
|
|
459
|
+
url=url,
|
|
460
|
+
token=token,
|
|
461
|
+
agent_id=agent_id,
|
|
462
|
+
tenant_id=tenant_id,
|
|
463
|
+
workspace_id=workspace_id,
|
|
464
|
+
invoke=invoke,
|
|
465
|
+
capabilities=capabilities,
|
|
466
|
+
default_timeout=default_timeout,
|
|
467
|
+
completed_cache_size=completed_cache_size,
|
|
468
|
+
)
|
|
469
|
+
|
|
470
|
+
|
|
471
|
+
__all__ = [
|
|
472
|
+
"ChannelConnector",
|
|
473
|
+
"ConnectorStatus",
|
|
474
|
+
"InvokeRequest",
|
|
475
|
+
"ProtocolError",
|
|
476
|
+
"create_channel_connector",
|
|
477
|
+
]
|
|
@@ -10,7 +10,7 @@
|
|
|
10
10
|
|
|
11
11
|
from __future__ import annotations
|
|
12
12
|
|
|
13
|
-
from dataclasses import dataclass
|
|
13
|
+
from dataclasses import dataclass, replace
|
|
14
14
|
from typing import Any, Literal
|
|
15
15
|
|
|
16
16
|
DeploymentMode = Literal["local", "ksadk_managed_cloud", "external_managed"]
|
|
@@ -277,6 +277,48 @@ def capability_hash(caps: ContextCapabilities) -> str:
|
|
|
277
277
|
return "sha256:" + hashlib.sha256(serialized.encode("utf-8")).hexdigest()
|
|
278
278
|
|
|
279
279
|
|
|
280
|
+
def _prepare_state_hook_exported(runner: Any) -> bool:
|
|
281
|
+
"""runner 模块是否导出可调用的 ``ksadk_prepare_state`` hook。
|
|
282
|
+
|
|
283
|
+
hook 模式下 runner 不走 ``_to_state`` 注入历史,messages 单一来源是 checkpointer
|
|
284
|
+
恢复(append-only reducer),ksadk compaction 的输出无法进入最终模型输入。
|
|
285
|
+
"""
|
|
286
|
+
module = getattr(runner, "_module", None)
|
|
287
|
+
hook = getattr(module, "ksadk_prepare_state", None)
|
|
288
|
+
return callable(hook)
|
|
289
|
+
|
|
290
|
+
|
|
291
|
+
def _durable_checkpoint_active(runner: Any) -> bool:
|
|
292
|
+
"""runner 图上是否已挂 durable checkpointer(托管重建 ready 或 capability 报告支持)。"""
|
|
293
|
+
describe = getattr(runner, "describe_checkpoint_capability", None)
|
|
294
|
+
if callable(describe):
|
|
295
|
+
try:
|
|
296
|
+
info = describe()
|
|
297
|
+
except Exception:
|
|
298
|
+
info = None
|
|
299
|
+
if isinstance(info, dict) and info.get("Supported"):
|
|
300
|
+
return True
|
|
301
|
+
return getattr(runner, "_managed_checkpoint_state", "") == "ready"
|
|
302
|
+
|
|
303
|
+
|
|
304
|
+
def _downgrade_compaction_owner_for_checkpoint_hook(
|
|
305
|
+
runner: Any, caps: ContextCapabilities
|
|
306
|
+
) -> ContextCapabilities:
|
|
307
|
+
"""durable checkpointer + ``ksadk_prepare_state`` hook 同时存在时,compaction 降级 framework。
|
|
308
|
+
|
|
309
|
+
该组合下 checkpointer 独占 messages(framework 侧压缩/摘要直接作用于 checkpointer
|
|
310
|
+
状态),ksadk compaction 只能写 session event store 的 append-only
|
|
311
|
+
``context_checkpoint`` 事件,对模型输入零贡献——继续声明 ``compaction_owner="ksadk"``
|
|
312
|
+
会让 compaction 门控在每个双阈值触发点白耗一次摘要 LLM 调用。降级后
|
|
313
|
+
``_plan_compaction`` 落 ``none`` 带,不产生 LLM 调用。其余字段不变。
|
|
314
|
+
"""
|
|
315
|
+
if caps.compaction_owner != "ksadk":
|
|
316
|
+
return caps
|
|
317
|
+
if not _prepare_state_hook_exported(runner) or not _durable_checkpoint_active(runner):
|
|
318
|
+
return caps
|
|
319
|
+
return replace(caps, compaction_owner="framework")
|
|
320
|
+
|
|
321
|
+
|
|
280
322
|
def capabilities_for_runner(runner: Any | None) -> ContextCapabilities:
|
|
281
323
|
"""统一 lookup:优先 runner 自身的 ``describe_context_capabilities()``,否则按 detection
|
|
282
324
|
type 显式分派,未知走 DEFAULT。
|
|
@@ -285,20 +327,26 @@ def capabilities_for_runner(runner: Any | None) -> ContextCapabilities:
|
|
|
285
327
|
``describe_context_capabilities``
|
|
286
328
|
走 ``_capabilities_for_detection_type``,故本函数对 BaseRunner 子类不会递归。已被 compaction
|
|
287
329
|
门控(``runtime_preparation`` proactive compaction)与 shadow plan / conformance 测试消费。
|
|
330
|
+
运行时证据覆盖:durable checkpointer + prepare_state hook 同时存在时,
|
|
331
|
+
``compaction_owner`` 从 ``ksadk`` 降级为 ``framework``(见
|
|
332
|
+
``_downgrade_compaction_owner_for_checkpoint_hook``)。
|
|
288
333
|
"""
|
|
289
334
|
if runner is None:
|
|
290
335
|
return DEFAULT_CONTEXT_CAPABILITIES()
|
|
291
336
|
|
|
337
|
+
caps: ContextCapabilities | None = None
|
|
292
338
|
describe = getattr(runner, "describe_context_capabilities", None)
|
|
293
339
|
if callable(describe):
|
|
294
340
|
try:
|
|
295
341
|
caps = describe()
|
|
296
342
|
except Exception:
|
|
297
343
|
caps = None
|
|
298
|
-
if isinstance(caps, ContextCapabilities):
|
|
299
|
-
|
|
344
|
+
if not isinstance(caps, ContextCapabilities):
|
|
345
|
+
caps = None
|
|
346
|
+
if caps is None:
|
|
347
|
+
caps = _capabilities_for_detection_type(_runner_type_value(runner))
|
|
300
348
|
|
|
301
|
-
return
|
|
349
|
+
return _downgrade_compaction_owner_for_checkpoint_hook(runner, caps)
|
|
302
350
|
|
|
303
351
|
|
|
304
352
|
# ---- Capability Mismatch 检测与熔断(方案 §6.1 / §8.3)----
|
|
@@ -103,8 +103,11 @@ def _region() -> str:
|
|
|
103
103
|
|
|
104
104
|
|
|
105
105
|
class AttachmentStorageService:
|
|
106
|
-
def __init__(self, *, root_dir: Path | None = None):
|
|
106
|
+
def __init__(self, *, root_dir: Path | None = None, owner_scope_ref: str | None = None):
|
|
107
107
|
self.root_dir = root_dir or uploads_dir()
|
|
108
|
+
self.owner_scope_ref = str(owner_scope_ref or "").strip()
|
|
109
|
+
if root_dir is None and self.owner_scope_ref:
|
|
110
|
+
self.root_dir = self.root_dir / "identities" / self.owner_scope_ref
|
|
108
111
|
|
|
109
112
|
async def store(
|
|
110
113
|
self,
|
|
@@ -149,6 +152,7 @@ class AttachmentStorageService:
|
|
|
149
152
|
"mime_type": resolved_mime,
|
|
150
153
|
"size_bytes": len(data),
|
|
151
154
|
"fallback_reason": "",
|
|
155
|
+
"owner_scope_ref": self.owner_scope_ref,
|
|
152
156
|
}
|
|
153
157
|
try:
|
|
154
158
|
self._run_async_sync(
|
|
@@ -363,11 +367,14 @@ class AttachmentStorageService:
|
|
|
363
367
|
local_path.write_bytes(data)
|
|
364
368
|
return local_path
|
|
365
369
|
|
|
366
|
-
|
|
367
|
-
def _object_key(*, file_id: str, display_name: str) -> str:
|
|
370
|
+
def _object_key(self, *, file_id: str, display_name: str) -> str:
|
|
368
371
|
suffix = Path(display_name).suffix
|
|
369
372
|
stored_name = file_id if suffix and file_id.endswith(suffix) else f"{file_id}{suffix}"
|
|
370
373
|
day = datetime.utcnow().strftime("%Y/%m/%d")
|
|
374
|
+
if self.owner_scope_ref:
|
|
375
|
+
return (
|
|
376
|
+
f"agents/_runtime/identities/{self.owner_scope_ref}/attachments/{day}/{stored_name}"
|
|
377
|
+
)
|
|
371
378
|
return f"agents/_runtime/attachments/{day}/{stored_name}"
|
|
372
379
|
|
|
373
380
|
@staticmethod
|
|
@@ -133,7 +133,9 @@ def _path_within_root(path: Path, root: Path) -> bool:
|
|
|
133
133
|
return resolved == resolved_root or resolved_root in resolved.parents
|
|
134
134
|
|
|
135
135
|
|
|
136
|
-
def resolve_attachment_storage_path(
|
|
136
|
+
def resolve_attachment_storage_path(
|
|
137
|
+
file_uri: str, *, owner_scope_ref: str | None = None
|
|
138
|
+
) -> Optional[Path]:
|
|
137
139
|
normalized_uri = (file_uri or "").strip()
|
|
138
140
|
if not normalized_uri:
|
|
139
141
|
return None
|
|
@@ -146,11 +148,17 @@ def resolve_attachment_storage_path(file_uri: str) -> Optional[Path]:
|
|
|
146
148
|
if not file_id:
|
|
147
149
|
return None
|
|
148
150
|
|
|
149
|
-
restored = AttachmentStorageService().ensure_local_path(
|
|
151
|
+
restored = AttachmentStorageService(owner_scope_ref=owner_scope_ref).ensure_local_path(
|
|
152
|
+
normalized_uri
|
|
153
|
+
)
|
|
150
154
|
if restored is not None and restored.is_file():
|
|
151
155
|
return restored.resolve()
|
|
152
156
|
|
|
153
|
-
uploads_dir = resolve_uploads_dir()
|
|
157
|
+
uploads_dir = resolve_uploads_dir()
|
|
158
|
+
normalized_owner = str(owner_scope_ref or "").strip()
|
|
159
|
+
if normalized_owner:
|
|
160
|
+
uploads_dir = uploads_dir / "identities" / normalized_owner
|
|
161
|
+
uploads_dir = uploads_dir.resolve()
|
|
154
162
|
safe_file_id = Path(file_id).name
|
|
155
163
|
if not safe_file_id:
|
|
156
164
|
return None
|
|
@@ -186,8 +194,11 @@ def read_attachment_uri_bytes(
|
|
|
186
194
|
file_uri: Any,
|
|
187
195
|
*,
|
|
188
196
|
size_limit: Optional[int] = None,
|
|
197
|
+
owner_scope_ref: str | None = None,
|
|
189
198
|
) -> Optional[bytes]:
|
|
190
|
-
storage_path = resolve_attachment_storage_path(
|
|
199
|
+
storage_path = resolve_attachment_storage_path(
|
|
200
|
+
str(file_uri or ""), owner_scope_ref=owner_scope_ref
|
|
201
|
+
)
|
|
191
202
|
if storage_path is None:
|
|
192
203
|
return None
|
|
193
204
|
return read_attachment_bytes(storage_path, size_limit=size_limit)
|
|
@@ -274,7 +285,7 @@ def build_attachment_prompt_text(result: Mapping[str, Any]) -> str:
|
|
|
274
285
|
|
|
275
286
|
size_bytes = result.get("size_bytes")
|
|
276
287
|
if size_bytes is not None:
|
|
277
|
-
return "[上传文件:
|
|
288
|
+
return f"[上传文件: {display_name}, mime={mime_type}, bytes={size_bytes}]"
|
|
278
289
|
|
|
279
290
|
return f"[上传文件引用: {display_name}, mime={mime_type}]"
|
|
280
291
|
|