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
ksadk/runtime_context.py
CHANGED
|
@@ -7,6 +7,79 @@ from typing import Any, Iterator, Mapping
|
|
|
7
7
|
|
|
8
8
|
from ksadk.session_context import SessionContext
|
|
9
9
|
|
|
10
|
+
TRUSTED_IDENTITY_METADATA_KEY = "_agentengine_verified_identity"
|
|
11
|
+
|
|
12
|
+
|
|
13
|
+
def _identity_value(value: Any) -> str:
|
|
14
|
+
return value.strip() if isinstance(value, str) else ""
|
|
15
|
+
|
|
16
|
+
|
|
17
|
+
@dataclass(frozen=True)
|
|
18
|
+
class PlatformIdentityContext:
|
|
19
|
+
"""Verified application identity carried through one runtime invocation.
|
|
20
|
+
|
|
21
|
+
Authentication adapters create this value after validating credentials and
|
|
22
|
+
tenant membership. It is deliberately separate from caller metadata and
|
|
23
|
+
from the cloud ``account_id``/``user_id`` compatibility fields.
|
|
24
|
+
"""
|
|
25
|
+
|
|
26
|
+
identity_namespace: str = ""
|
|
27
|
+
tenant_id: str = ""
|
|
28
|
+
subject_type: str = ""
|
|
29
|
+
subject_id: str = ""
|
|
30
|
+
actor_type: str = ""
|
|
31
|
+
actor_id: str = ""
|
|
32
|
+
|
|
33
|
+
@classmethod
|
|
34
|
+
def from_payload(cls, payload: Mapping[str, Any] | None) -> "PlatformIdentityContext":
|
|
35
|
+
if not isinstance(payload, Mapping):
|
|
36
|
+
return cls()
|
|
37
|
+
return cls(
|
|
38
|
+
identity_namespace=_identity_value(payload.get("identity_namespace")),
|
|
39
|
+
tenant_id=_identity_value(payload.get("tenant_id")),
|
|
40
|
+
subject_type=_identity_value(payload.get("subject_type")),
|
|
41
|
+
subject_id=_identity_value(payload.get("subject_id")),
|
|
42
|
+
actor_type=_identity_value(payload.get("actor_type")),
|
|
43
|
+
actor_id=_identity_value(payload.get("actor_id")),
|
|
44
|
+
)
|
|
45
|
+
|
|
46
|
+
@property
|
|
47
|
+
def is_empty(self) -> bool:
|
|
48
|
+
return not any(self.to_payload().values())
|
|
49
|
+
|
|
50
|
+
@property
|
|
51
|
+
def is_complete(self) -> bool:
|
|
52
|
+
"""Whether the four authorization-scoping fields are all present."""
|
|
53
|
+
|
|
54
|
+
return all(self.user_scope)
|
|
55
|
+
|
|
56
|
+
@property
|
|
57
|
+
def tenant_scope(self) -> tuple[str, str]:
|
|
58
|
+
return self.identity_namespace, self.tenant_id
|
|
59
|
+
|
|
60
|
+
@property
|
|
61
|
+
def user_scope(self) -> tuple[str, str, str, str]:
|
|
62
|
+
return (
|
|
63
|
+
self.identity_namespace,
|
|
64
|
+
self.tenant_id,
|
|
65
|
+
self.subject_type,
|
|
66
|
+
self.subject_id,
|
|
67
|
+
)
|
|
68
|
+
|
|
69
|
+
def to_payload(self) -> dict[str, str]:
|
|
70
|
+
return {
|
|
71
|
+
key: value
|
|
72
|
+
for key, value in {
|
|
73
|
+
"identity_namespace": self.identity_namespace,
|
|
74
|
+
"tenant_id": self.tenant_id,
|
|
75
|
+
"subject_type": self.subject_type,
|
|
76
|
+
"subject_id": self.subject_id,
|
|
77
|
+
"actor_type": self.actor_type,
|
|
78
|
+
"actor_id": self.actor_id,
|
|
79
|
+
}.items()
|
|
80
|
+
if value
|
|
81
|
+
}
|
|
82
|
+
|
|
10
83
|
|
|
11
84
|
@dataclass
|
|
12
85
|
class PlatformInvocationContext:
|
|
@@ -24,6 +97,7 @@ class PlatformInvocationContext:
|
|
|
24
97
|
has_current_files: bool
|
|
25
98
|
runner_type: str
|
|
26
99
|
account_id: str = ""
|
|
100
|
+
identity: PlatformIdentityContext = field(default_factory=PlatformIdentityContext)
|
|
27
101
|
metadata: dict[str, Any] = field(default_factory=dict)
|
|
28
102
|
model: str | None = None
|
|
29
103
|
model_options: dict[str, Any] | None = None
|
|
@@ -57,6 +131,8 @@ class PlatformInvocationContext:
|
|
|
57
131
|
|
|
58
132
|
if self.session.tags or self.session.revision:
|
|
59
133
|
payload["session"] = self.session.to_payload()
|
|
134
|
+
if not self.identity.is_empty:
|
|
135
|
+
payload["identity"] = self.identity.to_payload()
|
|
60
136
|
return payload
|
|
61
137
|
|
|
62
138
|
|
|
@@ -125,6 +201,19 @@ def get_current_account_id(default: str = "") -> str:
|
|
|
125
201
|
return str(context.account_id or default)
|
|
126
202
|
|
|
127
203
|
|
|
204
|
+
def get_current_identity_context() -> PlatformIdentityContext:
|
|
205
|
+
context = get_current_invocation_context()
|
|
206
|
+
return context.identity if context is not None else PlatformIdentityContext()
|
|
207
|
+
|
|
208
|
+
|
|
209
|
+
def get_current_tenant_id(default: str = "") -> str:
|
|
210
|
+
return str(get_current_identity_context().tenant_id or default)
|
|
211
|
+
|
|
212
|
+
|
|
213
|
+
def get_current_subject_id(default: str = "") -> str:
|
|
214
|
+
return str(get_current_identity_context().subject_id or default)
|
|
215
|
+
|
|
216
|
+
|
|
128
217
|
def set_current_invocation_context(
|
|
129
218
|
context: PlatformInvocationContext | None,
|
|
130
219
|
) -> Token[PlatformInvocationContext | None]:
|
|
@@ -199,7 +288,15 @@ def get_current_session_tags() -> Mapping[str, str]:
|
|
|
199
288
|
return get_current_session_context().tags
|
|
200
289
|
|
|
201
290
|
|
|
202
|
-
def session_invocation_context(
|
|
291
|
+
def session_invocation_context(
|
|
292
|
+
snapshot,
|
|
293
|
+
*,
|
|
294
|
+
agent_id="",
|
|
295
|
+
user_id="",
|
|
296
|
+
session_id="",
|
|
297
|
+
runner_type="",
|
|
298
|
+
identity: PlatformIdentityContext | Mapping[str, Any] | None = None,
|
|
299
|
+
):
|
|
203
300
|
"""Build the narrow context for kernel starts without conversation preprocessing."""
|
|
204
301
|
return PlatformInvocationContext(
|
|
205
302
|
agent_id=agent_id,
|
|
@@ -216,4 +313,9 @@ def session_invocation_context(snapshot, *, agent_id="", user_id="", session_id=
|
|
|
216
313
|
current_attachment_results=[],
|
|
217
314
|
has_current_files=False,
|
|
218
315
|
session=SessionContext.from_payload(snapshot),
|
|
316
|
+
identity=(
|
|
317
|
+
identity
|
|
318
|
+
if isinstance(identity, PlatformIdentityContext)
|
|
319
|
+
else PlatformIdentityContext.from_payload(identity)
|
|
320
|
+
),
|
|
219
321
|
)
|
ksadk/sandbox/backends/e2b.py
CHANGED
|
@@ -2,16 +2,19 @@ from __future__ import annotations
|
|
|
2
2
|
|
|
3
3
|
import logging
|
|
4
4
|
import os
|
|
5
|
+
import posixpath
|
|
5
6
|
import time
|
|
6
7
|
from typing import Any
|
|
7
8
|
|
|
8
9
|
from ksadk.sandbox.base import (
|
|
10
|
+
ReconnectableSandboxCommandHandle,
|
|
9
11
|
SandboxCommandResult,
|
|
10
12
|
SandboxError,
|
|
11
13
|
SandboxInputFile,
|
|
12
14
|
SandboxSession,
|
|
13
15
|
SandboxSpec,
|
|
14
16
|
)
|
|
17
|
+
from ksadk.sandbox.diagnostics import e2b_diagnostic_step
|
|
15
18
|
from ksadk.sandbox.e2b_connection import ExplicitE2BConnection
|
|
16
19
|
|
|
17
20
|
logger = logging.getLogger(__name__)
|
|
@@ -26,6 +29,28 @@ _TRANSIENT_STARTUP_ERROR_NAMES = {
|
|
|
26
29
|
}
|
|
27
30
|
|
|
28
31
|
|
|
32
|
+
class E2BSandboxSessionError(SandboxError):
|
|
33
|
+
"""Carry sandbox lifecycle facts when session initialization fails."""
|
|
34
|
+
|
|
35
|
+
def __init__(
|
|
36
|
+
self,
|
|
37
|
+
cause: Exception,
|
|
38
|
+
*,
|
|
39
|
+
instance_status: str,
|
|
40
|
+
failure_stage: str,
|
|
41
|
+
runtime_id: str = "",
|
|
42
|
+
cleanup_status: str = "not_started",
|
|
43
|
+
cleanup_error: str | None = None,
|
|
44
|
+
) -> None:
|
|
45
|
+
super().__init__(str(cause))
|
|
46
|
+
self.cause = cause
|
|
47
|
+
self.instance_status = instance_status
|
|
48
|
+
self.failure_stage = failure_stage
|
|
49
|
+
self.runtime_id = runtime_id
|
|
50
|
+
self.cleanup_status = cleanup_status
|
|
51
|
+
self.cleanup_error = cleanup_error
|
|
52
|
+
|
|
53
|
+
|
|
29
54
|
def _startup_retry_attempts() -> int:
|
|
30
55
|
raw = os.environ.get("KSADK_SANDBOX_STARTUP_RETRY_ATTEMPTS", "6")
|
|
31
56
|
try:
|
|
@@ -46,7 +71,7 @@ def _is_transient_startup_error(exc: Exception) -> bool:
|
|
|
46
71
|
return type(exc).__name__ in _TRANSIENT_STARTUP_ERROR_NAMES
|
|
47
72
|
|
|
48
73
|
|
|
49
|
-
def _with_startup_retry(operation):
|
|
74
|
+
def _with_startup_retry(operation, *, step: str = "startup", runtime_id: str = ""):
|
|
50
75
|
attempts = _startup_retry_attempts()
|
|
51
76
|
delay = _startup_retry_delay()
|
|
52
77
|
last_exc: Exception | None = None
|
|
@@ -54,7 +79,18 @@ def _with_startup_retry(operation):
|
|
|
54
79
|
try:
|
|
55
80
|
return operation()
|
|
56
81
|
except Exception as exc:
|
|
57
|
-
|
|
82
|
+
retry = _is_transient_startup_error(exc) and attempt < attempts - 1
|
|
83
|
+
logger.warning(
|
|
84
|
+
"E2B_DIAGNOSTIC step=%s runtime_id=%s attempt=%d max_attempts=%d "
|
|
85
|
+
"error_type=%s retry=%s",
|
|
86
|
+
step,
|
|
87
|
+
runtime_id,
|
|
88
|
+
attempt + 1,
|
|
89
|
+
attempts,
|
|
90
|
+
type(exc).__name__,
|
|
91
|
+
retry,
|
|
92
|
+
)
|
|
93
|
+
if not retry:
|
|
58
94
|
raise
|
|
59
95
|
last_exc = exc
|
|
60
96
|
time.sleep(min(delay * (2**attempt), 1.0))
|
|
@@ -63,6 +99,43 @@ def _with_startup_retry(operation):
|
|
|
63
99
|
raise SandboxError("E2B sandbox startup retry failed unexpectedly")
|
|
64
100
|
|
|
65
101
|
|
|
102
|
+
class E2BCommandHandle:
|
|
103
|
+
"""Normalize an E2B background command to the SDK optional contract."""
|
|
104
|
+
|
|
105
|
+
def __init__(self, handle: Any):
|
|
106
|
+
self._handle = handle
|
|
107
|
+
|
|
108
|
+
@property
|
|
109
|
+
def process_id(self) -> int:
|
|
110
|
+
process_id = int(getattr(self._handle, "pid", 0) or 0)
|
|
111
|
+
if process_id <= 0:
|
|
112
|
+
raise SandboxError("E2B command handle did not expose a valid process ID")
|
|
113
|
+
return process_id
|
|
114
|
+
|
|
115
|
+
def wait(self) -> SandboxCommandResult:
|
|
116
|
+
try:
|
|
117
|
+
result = self._handle.wait()
|
|
118
|
+
except Exception as exc:
|
|
119
|
+
# E2B raises CommandExitException for an ordinary non-zero exit.
|
|
120
|
+
# Preserve the result contract instead of erasing stdout/stderr.
|
|
121
|
+
exit_code = getattr(exc, "exit_code", None)
|
|
122
|
+
if exit_code is None:
|
|
123
|
+
raise
|
|
124
|
+
return SandboxCommandResult(
|
|
125
|
+
stdout=str(getattr(exc, "stdout", "") or ""),
|
|
126
|
+
stderr=str(getattr(exc, "stderr", "") or ""),
|
|
127
|
+
exit_code=int(exit_code),
|
|
128
|
+
)
|
|
129
|
+
return SandboxCommandResult(
|
|
130
|
+
stdout=str(getattr(result, "stdout", "") or ""),
|
|
131
|
+
stderr=str(getattr(result, "stderr", "") or ""),
|
|
132
|
+
exit_code=getattr(result, "exit_code", None),
|
|
133
|
+
)
|
|
134
|
+
|
|
135
|
+
def kill(self) -> bool:
|
|
136
|
+
return bool(self._handle.kill())
|
|
137
|
+
|
|
138
|
+
|
|
66
139
|
class E2BSandboxSession:
|
|
67
140
|
def __init__(self, sandbox: Any):
|
|
68
141
|
self._sandbox = sandbox
|
|
@@ -120,6 +193,65 @@ class E2BSandboxSession:
|
|
|
120
193
|
exit_code=getattr(result, "exit_code", None),
|
|
121
194
|
)
|
|
122
195
|
|
|
196
|
+
def start_command(
|
|
197
|
+
self,
|
|
198
|
+
command: str,
|
|
199
|
+
*,
|
|
200
|
+
timeout: int | None = None,
|
|
201
|
+
env: dict[str, str] | None = None,
|
|
202
|
+
cwd: str | None = None,
|
|
203
|
+
) -> ReconnectableSandboxCommandHandle:
|
|
204
|
+
kwargs: dict[str, Any] = {"background": True}
|
|
205
|
+
if timeout is not None:
|
|
206
|
+
kwargs["timeout"] = timeout
|
|
207
|
+
if env is not None:
|
|
208
|
+
kwargs["envs"] = env
|
|
209
|
+
if cwd is not None:
|
|
210
|
+
kwargs["cwd"] = cwd
|
|
211
|
+
return E2BCommandHandle(self._sandbox.commands.run(command, **kwargs))
|
|
212
|
+
|
|
213
|
+
def connect_command(
|
|
214
|
+
self,
|
|
215
|
+
process_id: int,
|
|
216
|
+
*,
|
|
217
|
+
timeout: int | None = None,
|
|
218
|
+
) -> ReconnectableSandboxCommandHandle:
|
|
219
|
+
if process_id <= 0:
|
|
220
|
+
raise SandboxError("E2B command reconnect requires a positive process ID")
|
|
221
|
+
kwargs: dict[str, Any] = {}
|
|
222
|
+
if timeout is not None:
|
|
223
|
+
kwargs["timeout"] = timeout
|
|
224
|
+
return E2BCommandHandle(self._sandbox.commands.connect(process_id, **kwargs))
|
|
225
|
+
|
|
226
|
+
def list_files(self, root: str, *, recursive: bool = True) -> list[str]:
|
|
227
|
+
"""List file paths below ``root`` without exposing sibling paths."""
|
|
228
|
+
|
|
229
|
+
normalized_root = posixpath.normpath(root)
|
|
230
|
+
if not normalized_root.startswith("/"):
|
|
231
|
+
raise SandboxError("E2B artifact root must be an absolute path")
|
|
232
|
+
entries = self._sandbox.files.list(
|
|
233
|
+
normalized_root,
|
|
234
|
+
depth=None if recursive else 1,
|
|
235
|
+
)
|
|
236
|
+
files: list[str] = []
|
|
237
|
+
for entry in entries:
|
|
238
|
+
entry_path = posixpath.normpath(str(getattr(entry, "path", "") or ""))
|
|
239
|
+
if not entry_path.startswith("/"):
|
|
240
|
+
entry_path = posixpath.normpath(posixpath.join(normalized_root, entry_path))
|
|
241
|
+
entry_type = getattr(getattr(entry, "type", None), "value", "")
|
|
242
|
+
if getattr(entry, "symlink_target", None) is not None:
|
|
243
|
+
continue
|
|
244
|
+
try:
|
|
245
|
+
in_root = posixpath.commonpath((normalized_root, entry_path)) == normalized_root
|
|
246
|
+
except ValueError:
|
|
247
|
+
in_root = False
|
|
248
|
+
if not in_root or entry_type != "file":
|
|
249
|
+
continue
|
|
250
|
+
relative = posixpath.relpath(entry_path, normalized_root)
|
|
251
|
+
if relative != "." and not relative.startswith("../"):
|
|
252
|
+
files.append(relative)
|
|
253
|
+
return sorted(set(files))
|
|
254
|
+
|
|
123
255
|
def get_host(self, port: int) -> str:
|
|
124
256
|
return str(self._sandbox.get_host(port))
|
|
125
257
|
|
|
@@ -128,6 +260,17 @@ class E2BSandboxSession:
|
|
|
128
260
|
|
|
129
261
|
|
|
130
262
|
class E2BSandboxBackend:
|
|
263
|
+
def _diagnostic_step(self, step: str, *, runtime_id: str = "", env=None):
|
|
264
|
+
credentials = (
|
|
265
|
+
(self.connection.api_key.get_secret_value(),) if self.connection is not None else ()
|
|
266
|
+
)
|
|
267
|
+
return e2b_diagnostic_step(
|
|
268
|
+
step,
|
|
269
|
+
runtime_id=runtime_id,
|
|
270
|
+
sensitive_values=credentials,
|
|
271
|
+
env={**self.spec.env, **(env or {})},
|
|
272
|
+
)
|
|
273
|
+
|
|
131
274
|
def __init__(
|
|
132
275
|
self,
|
|
133
276
|
*,
|
|
@@ -141,9 +284,22 @@ class E2BSandboxBackend:
|
|
|
141
284
|
self.sandbox_cls = sandbox_cls
|
|
142
285
|
self.connection = (
|
|
143
286
|
ExplicitE2BConnection.model_validate(connection.model_dump())
|
|
144
|
-
if connection is not None
|
|
287
|
+
if connection is not None
|
|
288
|
+
else None
|
|
145
289
|
)
|
|
146
290
|
|
|
291
|
+
def _get_sandbox_cls(self) -> Any:
|
|
292
|
+
sandbox_cls = self.sandbox_cls
|
|
293
|
+
if sandbox_cls is not None:
|
|
294
|
+
return sandbox_cls
|
|
295
|
+
try:
|
|
296
|
+
from e2b import Sandbox # type: ignore[import-not-found, import-untyped]
|
|
297
|
+
except ImportError as exc:
|
|
298
|
+
raise SandboxError(
|
|
299
|
+
"e2b>=2.15.3,<2.25.0 is required for KSADK_SANDBOX_BACKEND=e2b"
|
|
300
|
+
) from exc
|
|
301
|
+
return Sandbox
|
|
302
|
+
|
|
147
303
|
def check_available(self) -> None:
|
|
148
304
|
"""Validate local SDK/connection configuration without creating a sandbox."""
|
|
149
305
|
if self.connection is not None:
|
|
@@ -179,26 +335,82 @@ class E2BSandboxBackend:
|
|
|
179
335
|
"session_id": session_id,
|
|
180
336
|
}
|
|
181
337
|
runtime_env = {**self.spec.env, **(env or {})}
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
|
|
189
|
-
|
|
338
|
+
try:
|
|
339
|
+
with self._diagnostic_step("create", env=runtime_env):
|
|
340
|
+
sandbox = sandbox_cls.create(
|
|
341
|
+
template=self.spec.template_id,
|
|
342
|
+
timeout=self.spec.timeout,
|
|
343
|
+
metadata=metadata,
|
|
344
|
+
envs=runtime_env,
|
|
345
|
+
allow_internet_access=self.spec.allow_internet_access,
|
|
346
|
+
**connection_options,
|
|
347
|
+
)
|
|
348
|
+
except Exception as exc:
|
|
349
|
+
# The transport can fail after the service accepted the request but before
|
|
350
|
+
# returning an instance id, so creation cannot be reported as not_created.
|
|
351
|
+
raise E2BSandboxSessionError(
|
|
352
|
+
exc,
|
|
353
|
+
instance_status="unknown",
|
|
354
|
+
failure_stage="create",
|
|
355
|
+
) from exc
|
|
190
356
|
session = self._wrap_sandbox(sandbox)
|
|
191
357
|
try:
|
|
192
|
-
self.
|
|
193
|
-
|
|
194
|
-
|
|
195
|
-
|
|
196
|
-
|
|
358
|
+
with self._diagnostic_step(
|
|
359
|
+
"initialize", runtime_id=session.sandbox_id, env=runtime_env
|
|
360
|
+
):
|
|
361
|
+
self._wait_until_ready(session, runtime_env)
|
|
362
|
+
with self._diagnostic_step(
|
|
363
|
+
"input_files.write", runtime_id=session.sandbox_id, env=runtime_env
|
|
364
|
+
):
|
|
365
|
+
session.write_files(
|
|
366
|
+
[(item.target_path, item.source.read_bytes()) for item in input_files or []]
|
|
367
|
+
)
|
|
368
|
+
except BaseException as exc:
|
|
369
|
+
cleanup_status = "not_started"
|
|
370
|
+
cleanup_error = None
|
|
197
371
|
try:
|
|
198
|
-
|
|
372
|
+
with self._diagnostic_step(
|
|
373
|
+
"initialize.cleanup", runtime_id=session.sandbox_id, env=runtime_env
|
|
374
|
+
):
|
|
375
|
+
session.kill()
|
|
376
|
+
cleanup_status = "completed"
|
|
199
377
|
except Exception:
|
|
378
|
+
cleanup_status = "failed"
|
|
379
|
+
cleanup_error = "cleanup_failed"
|
|
200
380
|
logger.warning("E2B sandbox cleanup failed after initialization failure")
|
|
201
|
-
|
|
381
|
+
if not isinstance(exc, Exception):
|
|
382
|
+
raise
|
|
383
|
+
raise E2BSandboxSessionError(
|
|
384
|
+
exc,
|
|
385
|
+
instance_status="created",
|
|
386
|
+
failure_stage="initialize",
|
|
387
|
+
runtime_id=session.sandbox_id,
|
|
388
|
+
cleanup_status=cleanup_status,
|
|
389
|
+
cleanup_error=cleanup_error,
|
|
390
|
+
) from exc
|
|
391
|
+
return session
|
|
392
|
+
|
|
393
|
+
def reconnect_session(self, *, session_locator: str) -> SandboxSession:
|
|
394
|
+
"""Reconnect to an existing E2B sandbox without recreating it."""
|
|
395
|
+
|
|
396
|
+
locator = session_locator.strip()
|
|
397
|
+
if not locator:
|
|
398
|
+
raise SandboxError("E2B reconnect requires a sandbox ID")
|
|
399
|
+
# Reconnection does not transfer ownership: failure must not kill an
|
|
400
|
+
# existing instance that may still be running another process's work.
|
|
401
|
+
with self._diagnostic_step("reconnect", runtime_id=locator):
|
|
402
|
+
sandbox_cls = self._get_sandbox_cls()
|
|
403
|
+
connection_options = (
|
|
404
|
+
self.connection.sdk_options() if self.connection is not None else {}
|
|
405
|
+
)
|
|
406
|
+
sandbox = sandbox_cls.connect(locator, timeout=self.spec.timeout, **connection_options)
|
|
407
|
+
session = self._wrap_sandbox(sandbox)
|
|
408
|
+
with self._diagnostic_step("reconnect.ready.command", runtime_id=session.sandbox_id):
|
|
409
|
+
_with_startup_retry(
|
|
410
|
+
lambda: session.run_command("true"),
|
|
411
|
+
step="reconnect.ready.command",
|
|
412
|
+
runtime_id=session.sandbox_id,
|
|
413
|
+
)
|
|
202
414
|
return session
|
|
203
415
|
|
|
204
416
|
def _wrap_sandbox(self, sandbox: Any) -> E2BSandboxSession:
|
|
@@ -207,9 +419,20 @@ class E2BSandboxBackend:
|
|
|
207
419
|
def _wait_until_ready(
|
|
208
420
|
self, session: E2BSandboxSession, env: dict[str, str] | None = None
|
|
209
421
|
) -> None:
|
|
210
|
-
|
|
211
|
-
|
|
212
|
-
|
|
422
|
+
with self._diagnostic_step("ready.command", runtime_id=session.sandbox_id, env=env):
|
|
423
|
+
_with_startup_retry(
|
|
424
|
+
lambda: session.run_command("true"),
|
|
425
|
+
step="ready.command",
|
|
426
|
+
runtime_id=session.sandbox_id,
|
|
427
|
+
)
|
|
428
|
+
with self._diagnostic_step("ready.file", runtime_id=session.sandbox_id, env=env):
|
|
429
|
+
_with_startup_retry(
|
|
430
|
+
lambda: session.write_file("/tmp/.ksadk-sandbox-ready", ""),
|
|
431
|
+
step="ready.file",
|
|
432
|
+
runtime_id=session.sandbox_id,
|
|
433
|
+
)
|
|
434
|
+
with self._diagnostic_step("ready.env", runtime_id=session.sandbox_id, env=env):
|
|
435
|
+
self._wait_env_applied(session, env or {})
|
|
213
436
|
|
|
214
437
|
def _wait_env_applied(self, session: E2BSandboxSession, env: dict[str, str]) -> None:
|
|
215
438
|
# create 返回后 envd 异步应用 envVars, 实测存在秒级延迟;
|
|
@@ -228,9 +451,8 @@ class E2BSandboxBackend:
|
|
|
228
451
|
# 不 raise: 模板可能预置同名空值覆盖 create 注入 (envd 合并优先级问题),
|
|
229
452
|
# 此时调用方仍可通过 run_command(env=...) 的 per-command 注入拿到正确值。
|
|
230
453
|
logger.warning(
|
|
231
|
-
"E2B sandbox env %s not applied after %d attempts
|
|
454
|
+
"E2B sandbox env %s not applied after %d attempts; "
|
|
232
455
|
"template may predefine an empty override",
|
|
233
456
|
key,
|
|
234
457
|
attempts,
|
|
235
|
-
expected,
|
|
236
458
|
)
|
|
@@ -1,17 +1,16 @@
|
|
|
1
1
|
from __future__ import annotations
|
|
2
2
|
|
|
3
3
|
import os
|
|
4
|
-
import signal
|
|
5
|
-
import subprocess
|
|
6
4
|
from pathlib import Path
|
|
7
5
|
|
|
8
6
|
from ksadk.sandbox.base import SandboxCommandResult, SandboxInputFile, SandboxSession
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
7
|
+
from ksadk.sandbox.local_controls import (
|
|
8
|
+
LocalControlSettings,
|
|
9
|
+
build_script_environment,
|
|
10
|
+
check_command,
|
|
11
|
+
resource_limit_reason,
|
|
12
|
+
run_bounded_process,
|
|
13
|
+
)
|
|
15
14
|
|
|
16
15
|
|
|
17
16
|
class LocalProcessSandboxSession:
|
|
@@ -22,6 +21,7 @@ class LocalProcessSandboxSession:
|
|
|
22
21
|
self._workspace_root = workspace_root.expanduser().resolve()
|
|
23
22
|
self._workspace_root.mkdir(parents=True, exist_ok=True)
|
|
24
23
|
self._backend_name = backend_name
|
|
24
|
+
self._controls = LocalControlSettings.from_trusted_host_env()
|
|
25
25
|
|
|
26
26
|
@property
|
|
27
27
|
def sandbox_id(self) -> str:
|
|
@@ -59,35 +59,56 @@ class LocalProcessSandboxSession:
|
|
|
59
59
|
resolved_cwd = self._resolve_cwd(cwd or (env or {}).get("KSADK_COMMAND_CWD"))
|
|
60
60
|
except ValueError as exc:
|
|
61
61
|
return SandboxCommandResult(stderr=str(exc), exit_code=126)
|
|
62
|
-
|
|
62
|
+
finding = check_command(
|
|
63
|
+
command,
|
|
64
|
+
cwd=resolved_cwd,
|
|
65
|
+
allowed_roots=(self._workspace_root,),
|
|
66
|
+
)
|
|
67
|
+
if finding is not None:
|
|
68
|
+
return SandboxCommandResult(
|
|
69
|
+
stderr=f"blocked by local-process policy: {finding.reason()}", exit_code=126
|
|
70
|
+
)
|
|
71
|
+
source_env = dict(os.environ)
|
|
72
|
+
source_env.update(env or {})
|
|
73
|
+
process_env = build_script_environment(source_env, settings=self._controls)
|
|
63
74
|
try:
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
75
|
+
effective_timeout = self._controls.wall_seconds
|
|
76
|
+
if timeout is not None:
|
|
77
|
+
effective_timeout = min(timeout, effective_timeout)
|
|
78
|
+
executed = run_bounded_process(
|
|
79
|
+
["/bin/sh", "-c", command],
|
|
67
80
|
cwd=resolved_cwd,
|
|
68
81
|
env=process_env,
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
stderr=subprocess.PIPE,
|
|
82
|
+
timeout=effective_timeout,
|
|
83
|
+
settings=self._controls,
|
|
72
84
|
start_new_session=True,
|
|
73
85
|
)
|
|
74
|
-
|
|
75
|
-
return SandboxCommandResult(
|
|
76
|
-
stdout=stdout,
|
|
77
|
-
stderr=stderr,
|
|
78
|
-
exit_code=process.returncode,
|
|
79
|
-
)
|
|
80
|
-
except subprocess.TimeoutExpired as exc:
|
|
81
|
-
try:
|
|
82
|
-
os.killpg(process.pid, signal.SIGKILL)
|
|
83
|
-
except Exception:
|
|
84
|
-
pass
|
|
85
|
-
stdout, stderr = process.communicate()
|
|
86
|
+
except (OSError, ValueError) as exc:
|
|
86
87
|
return SandboxCommandResult(
|
|
87
|
-
|
|
88
|
-
stderr=_coerce_output(stderr or exc.stderr) + "\ncommand timed out",
|
|
89
|
-
exit_code=124,
|
|
88
|
+
stderr=f"local-process controls failed: {exc}", exit_code=125
|
|
90
89
|
)
|
|
90
|
+
diagnostics: list[str] = []
|
|
91
|
+
if executed.controls.get("status") == "failed":
|
|
92
|
+
diagnostics.append("resource limits were not applied")
|
|
93
|
+
if executed.output_limit_exceeded:
|
|
94
|
+
diagnostics.append("command output limit exceeded")
|
|
95
|
+
if executed.timed_out:
|
|
96
|
+
diagnostics.append("command timed out")
|
|
97
|
+
if limit := resource_limit_reason(executed.exit_code):
|
|
98
|
+
diagnostics.append(f"command exceeded {limit} resource limit")
|
|
99
|
+
if executed.cleanup_error:
|
|
100
|
+
diagnostics.append("command process-group cleanup failed")
|
|
101
|
+
stderr = executed.stderr
|
|
102
|
+
if diagnostics:
|
|
103
|
+
stderr = (stderr.rstrip() + "\n" if stderr else "") + "; ".join(diagnostics)
|
|
104
|
+
exit_code = executed.exit_code
|
|
105
|
+
if executed.timed_out:
|
|
106
|
+
exit_code = 124
|
|
107
|
+
elif executed.output_limit_exceeded:
|
|
108
|
+
exit_code = 122
|
|
109
|
+
elif executed.controls.get("status") == "failed" or executed.cleanup_error:
|
|
110
|
+
exit_code = 125
|
|
111
|
+
return SandboxCommandResult(stdout=executed.stdout, stderr=stderr, exit_code=exit_code)
|
|
91
112
|
|
|
92
113
|
def get_host(self, port: int) -> str:
|
|
93
114
|
return f"http://127.0.0.1:{int(port)}"
|
|
@@ -104,24 +125,27 @@ class LocalProcessSandboxSession:
|
|
|
104
125
|
resolved = candidate.expanduser().resolve()
|
|
105
126
|
if resolved != self._workspace_root and self._workspace_root not in resolved.parents:
|
|
106
127
|
raise ValueError("cwd must stay inside the sandbox workspace")
|
|
128
|
+
self._reject_symlink_components(candidate)
|
|
107
129
|
return resolved
|
|
108
130
|
|
|
109
131
|
def _resolve_workspace_path(self, path: str) -> Path:
|
|
110
132
|
raw = str(path or "").strip().lstrip("/") or "."
|
|
133
|
+
self._reject_symlink_components(self._workspace_root / raw)
|
|
111
134
|
target = (self._workspace_root / raw).resolve()
|
|
112
135
|
if target != self._workspace_root and self._workspace_root not in target.parents:
|
|
113
136
|
raise ValueError("path must stay inside the sandbox workspace")
|
|
114
137
|
return target
|
|
115
138
|
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
139
|
+
def _reject_symlink_components(self, path: Path) -> None:
|
|
140
|
+
try:
|
|
141
|
+
relative = path.absolute().relative_to(self._workspace_root)
|
|
142
|
+
except ValueError:
|
|
143
|
+
raise ValueError("path must stay inside the sandbox workspace") from None
|
|
144
|
+
current = self._workspace_root
|
|
145
|
+
for part in relative.parts:
|
|
146
|
+
current = current / part
|
|
147
|
+
if current.is_symlink():
|
|
148
|
+
raise ValueError("sandbox file API does not follow symbolic links")
|
|
125
149
|
|
|
126
150
|
|
|
127
151
|
class LocalProcessSandboxBackend:
|