agentengine-sdk-python 0.8.4__py3-none-any.whl → 0.8.6__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.6.dist-info}/METADATA +17 -10
- agentengine_sdk_python-0.8.6.dist-info/RECORD +1731 -0
- ksadk/_async_iterators.py +79 -0
- ksadk/_build_provenance.json +1 -1
- ksadk/_model_anthropic.py +49 -0
- ksadk/_model_input.py +86 -0
- ksadk/_model_json.py +40 -0
- ksadk/_model_reasoning.py +17 -0
- ksadk/_model_refusal.py +20 -0
- ksadk/_model_sse.py +163 -0
- ksadk/_process.py +83 -0
- ksadk/_str_enum.py +17 -0
- ksadk/a2a/__init__.py +157 -167
- ksadk/a2a/_invocation_state.py +86 -0
- ksadk/a2a/_space_client_events.py +33 -22
- ksadk/a2a/adk.py +194 -0
- ksadk/a2a/adk_invocation_context.py +242 -0
- ksadk/a2a/adk_runtime.py +126 -0
- ksadk/a2a/adk_tools.py +319 -0
- ksadk/a2a/bootstrap.py +149 -23
- ksadk/a2a/build_validation.py +147 -0
- ksadk/a2a/card.py +23 -15
- ksadk/a2a/codex.py +160 -0
- ksadk/a2a/codex_checkpoint.py +111 -0
- ksadk/a2a/codex_recovery.py +96 -0
- ksadk/a2a/codex_recovery_events.py +123 -0
- ksadk/a2a/codex_runtime.py +198 -0
- ksadk/a2a/codex_session_checkpoint.py +162 -0
- ksadk/a2a/composition.py +88 -0
- ksadk/a2a/context_store.py +118 -19
- ksadk/a2a/control_plane.py +108 -106
- ksadk/a2a/event_adapter.py +92 -193
- ksadk/a2a/executor.py +257 -85
- ksadk/a2a/exposure.py +106 -0
- ksadk/a2a/external_transport.py +3 -4
- ksadk/a2a/identity.py +106 -12
- ksadk/a2a/ids.py +14 -3
- ksadk/a2a/inbound_kernel.py +133 -0
- ksadk/a2a/interaction_wire.py +76 -0
- ksadk/a2a/invocation_checkpoint.py +274 -0
- ksadk/a2a/invocation_policy.py +87 -0
- ksadk/a2a/invocation_publication.py +210 -0
- ksadk/a2a/invocation_service.py +972 -0
- ksadk/a2a/invocation_types.py +459 -0
- ksadk/a2a/kernel_task_adapter.py +259 -0
- ksadk/a2a/langgraph.py +20 -7
- ksadk/a2a/langgraph_invocation_context.py +136 -0
- ksadk/a2a/langgraph_managed.py +150 -0
- ksadk/a2a/langgraph_recovery.py +32 -0
- ksadk/a2a/langgraph_runtime.py +89 -0
- ksadk/a2a/langgraph_tool_runtime.py +132 -0
- ksadk/a2a/langgraph_tools.py +63 -0
- ksadk/a2a/message_digest.py +40 -0
- ksadk/a2a/platform.py +389 -0
- ksadk/a2a/policy_refs.py +13 -0
- ksadk/a2a/presentation.py +402 -0
- ksadk/a2a/product_kernel_facts.py +177 -0
- ksadk/a2a/product_key.py +99 -0
- ksadk/a2a/protocol_errors.py +116 -0
- ksadk/a2a/result_text.py +49 -0
- ksadk/a2a/resume_store.py +93 -3
- ksadk/a2a/routes.py +6 -1
- ksadk/a2a/runtime_approval.py +198 -0
- ksadk/a2a/runtime_input.py +151 -0
- ksadk/a2a/server.py +16 -7
- ksadk/a2a/space_client.py +101 -16
- ksadk/a2a/task_adapter.py +19 -5
- ksadk/a2a/task_event_dispatcher.py +39 -2
- ksadk/a2a/task_event_outbox.py +215 -0
- ksadk/a2a/task_event_outbox_owned.py +130 -0
- ksadk/a2a/task_store.py +37 -0
- ksadk/a2a/tool_activity.py +176 -0
- ksadk/a2a/workload_tokens.py +134 -0
- ksadk/a2ui/core.py +3 -3
- ksadk/api/client.py +38 -79
- ksadk/api/sse_stream.py +96 -0
- ksadk/builders/code_builder.py +121 -118
- ksadk/builders/container_builder.py +11 -29
- ksadk/builders/framework_requirements.py +22 -2
- ksadk/builders/managed_runtime_builder.py +12 -0
- ksadk/builders/source_provenance.py +87 -0
- ksadk/cli/__init__.py +36 -0
- ksadk/cli/cmd_a2a.py +43 -0
- ksadk/cli/cmd_build.py +9 -0
- ksadk/cli/cmd_config.py +4 -4
- ksadk/cli/cmd_create.py +12 -12
- ksadk/cli/cmd_deploy.py +27 -2
- ksadk/cli/cmd_hermes.py +24 -2
- ksadk/cli/cmd_invoke.py +64 -88
- ksadk/cli/cmd_openclaw.py +26 -1
- ksadk/cli/cmd_plugin.py +70 -12
- ksadk/cli/cmd_studio.py +69 -17
- ksadk/cli/cmd_web.py +2 -0
- ksadk/cli/hosted_invoke.py +206 -0
- ksadk/cli/invoke_content.py +60 -0
- ksadk/cli/openclaw_env.py +1 -1
- ksadk/cli/resource_common.py +26 -0
- ksadk/cli/runtime_bootstrap.py +27 -5
- ksadk/codex/_expert_request_reader.py +48 -0
- ksadk/codex/a2a_tools.py +140 -0
- ksadk/codex/async_approval.py +169 -0
- ksadk/codex/async_client.py +938 -0
- ksadk/codex/async_proxy.py +216 -0
- ksadk/codex/base_runtime.py +25 -0
- ksadk/codex/client.py +3 -1047
- ksadk/codex/client_payloads.py +85 -0
- ksadk/codex/rollout_checkpoint.py +264 -0
- ksadk/codex/runtime.py +290 -54
- ksadk/common/auth.py +2 -2
- ksadk/common/cloud_headers.py +36 -0
- ksadk/common/diagnostics.py +34 -0
- ksadk/common/kop_client.py +2 -1
- ksadk/configs/__init__.py +1 -1
- ksadk/configs/env_registry.py +216 -143
- ksadk/configs/env_registry_a2a.py +173 -0
- ksadk/configs/env_registry_studio.py +134 -0
- ksadk/configs/global_config.py +2 -1
- ksadk/configs/settings.py +9 -3
- ksadk/connector/__init__.py +17 -0
- ksadk/connector/channel.py +477 -0
- ksadk/context_engine/assembler.py +9 -0
- ksadk/context_engine/capabilities.py +52 -4
- ksadk/context_engine/contributors.py +80 -17
- ksadk/context_engine/instruction_authority.py +18 -0
- ksadk/conversations/attachment_storage.py +10 -3
- ksadk/conversations/attachments.py +69 -20
- ksadk/conversations/contracts.py +28 -9
- ksadk/conversations/message_projection.py +51 -155
- ksadk/conversations/message_projection_blocks.py +137 -0
- ksadk/conversations/model_context.py +11 -3
- ksadk/conversations/normalize.py +28 -10
- ksadk/conversations/projector.py +63 -0
- ksadk/conversations/runtime_baseline.py +37 -0
- ksadk/conversations/runtime_compaction.py +7 -2
- ksadk/conversations/runtime_input.py +16 -4
- ksadk/conversations/runtime_invocation.py +17 -4
- ksadk/conversations/runtime_observability.py +39 -10
- ksadk/conversations/runtime_payloads.py +12 -0
- ksadk/conversations/runtime_persistence.py +296 -32
- ksadk/conversations/runtime_preparation.py +98 -13
- ksadk/conversations/runtime_projection.py +217 -0
- ksadk/conversations/runtime_resume.py +141 -70
- ksadk/conversations/runtime_stream_events.py +29 -35
- ksadk/conversations/runtime_streaming.py +8 -0
- ksadk/conversations/tool_receipt_resume.py +387 -0
- ksadk/conversations/tool_receipts.py +32 -0
- ksadk/deployment/env_forward.py +5 -0
- ksadk/deployment/manager.py +15 -6
- ksadk/deployment/providers/serverless.py +76 -136
- ksadk/deployment/providers/serverless_payloads.py +122 -0
- ksadk/evaluation/agent_eval_client.py +2 -1
- ksadk/evaluation/contracts.py +78 -3
- ksadk/evaluation/evaluators.py +166 -1
- ksadk/evaluation/evidence.py +271 -4
- ksadk/evaluation/local_adapter.py +76 -12
- ksadk/evaluation/studio_build_adapter.py +73 -9
- ksadk/events/adapters/_a2a_checkpoint.py +151 -0
- ksadk/events/adapters/_a2a_snapshot.py +18 -14
- ksadk/events/adapters/_a2a_support.py +15 -3
- ksadk/events/adapters/_a2a_tool_activity.py +123 -0
- ksadk/events/adapters/_codex_errors.py +49 -0
- ksadk/events/adapters/_codex_items.py +16 -8
- ksadk/events/adapters/_langgraph_support.py +46 -1
- ksadk/events/adapters/a2a.py +54 -26
- ksadk/events/adapters/adk.py +188 -30
- ksadk/events/adapters/codex.py +33 -7
- ksadk/events/adapters/langgraph.py +16 -6
- ksadk/events/canonical.py +5 -0
- ksadk/events/canonical_store.py +200 -4
- ksadk/events/reducer.py +82 -0
- ksadk/events/run_authority.py +176 -0
- ksadk/events/session_event.py +2 -2
- ksadk/harness/__init__.py +18 -0
- ksadk/harness/app.py +11 -0
- ksadk/harness/artifact_adapters/__init__.py +1 -0
- ksadk/harness/artifact_adapters/native_page_budget.py +172 -0
- ksadk/harness/artifact_adapters/native_search.py +249 -0
- ksadk/harness/artifact_adapters/native_search_budget.py +134 -0
- ksadk/harness/artifact_adapters/native_store.py +115 -0
- ksadk/harness/artifact_adapters/native_tool.py +222 -0
- ksadk/harness/artifact_store.py +230 -0
- ksadk/harness/browser_adapters/__init__.py +6 -0
- ksadk/harness/browser_adapters/native_browser_tool.py +92 -0
- ksadk/harness/browser_adapters/native_dom_snapshot.py +187 -0
- ksadk/harness/browser_adapters/native_playwright.py +953 -0
- ksadk/harness/browser_adapters/native_vision.py +295 -0
- ksadk/harness/capabilities.py +115 -0
- ksadk/harness/capability_adapters/__init__.py +1 -0
- ksadk/harness/capability_adapters/native_dsh.py +289 -0
- ksadk/harness/capability_runtime.py +332 -0
- ksadk/harness/closure_contract.py +92 -0
- ksadk/harness/compaction_record.py +153 -0
- ksadk/harness/compiler.py +284 -0
- ksadk/harness/config.py +28 -5
- ksadk/harness/conformance/__init__.py +33 -0
- ksadk/harness/conformance/contract.py +504 -0
- ksadk/harness/conformance/fixtures.py +102 -0
- ksadk/harness/context_engine.py +388 -0
- ksadk/harness/context_maintenance.py +259 -0
- ksadk/harness/context_manifest.py +188 -0
- ksadk/harness/context_sections.py +397 -0
- ksadk/harness/context_tuning.py +168 -0
- ksadk/harness/diagnostic_adapters/__init__.py +1 -0
- ksadk/harness/diagnostic_adapters/contracts.py +70 -0
- ksadk/harness/diagnostic_adapters/lsp_rpc.py +210 -0
- ksadk/harness/diagnostic_adapters/native_lsp.py +286 -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 +57 -0
- ksadk/harness/engine/context_pipeline.py +1351 -0
- ksadk/harness/engine/graph_builder.py +352 -0
- ksadk/harness/engine/hooked_reasoner.py +380 -0
- ksadk/harness/engine/langgraph.py +1049 -0
- ksadk/harness/engine/mcp_disclosure.py +701 -0
- ksadk/harness/engine/phases/__init__.py +6 -0
- ksadk/harness/engine/phases/context.py +48 -0
- ksadk/harness/engine/phases/interaction.py +31 -0
- ksadk/harness/engine/phases/reason.py +552 -0
- ksadk/harness/engine/phases/tools.py +638 -0
- ksadk/harness/engine/policy_runtime.py +81 -0
- ksadk/harness/engine/postgres_checkpointer.py +386 -0
- ksadk/harness/engine/run_control_bridge.py +100 -0
- ksadk/harness/engine/run_types.py +98 -0
- ksadk/harness/engine/skill_disclosure.py +275 -0
- ksadk/harness/engine/spans.py +41 -0
- ksadk/harness/engine/steering.py +177 -0
- ksadk/harness/engine/subagents.py +360 -0
- ksadk/harness/engine/thread_ids.py +112 -0
- ksadk/harness/engine/tool_dispatch.py +249 -0
- ksadk/harness/event_tree.py +212 -0
- ksadk/harness/events.py +498 -0
- ksadk/harness/execution_policy.py +104 -0
- ksadk/harness/hooks.py +259 -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 +699 -0
- ksadk/harness/loop/tools.py +907 -0
- ksadk/harness/managed_runtime.py +1044 -0
- ksadk/harness/mcp_disclosure_contract.py +85 -0
- ksadk/harness/mcp_matrix.py +474 -0
- ksadk/harness/mcp_result_policy.py +44 -0
- ksadk/harness/mcp_runtime.py +504 -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/micro_compact.py +69 -0
- ksadk/harness/model_adapters/__init__.py +1 -0
- ksadk/harness/model_adapters/native_mcp_media.py +100 -0
- ksadk/harness/model_adapters/native_mcp_result.py +36 -0
- ksadk/harness/model_adapters/native_openai.py +703 -0
- ksadk/harness/model_capability.py +468 -0
- ksadk/harness/model_provider.py +430 -0
- ksadk/harness/multimodal.py +57 -0
- ksadk/harness/native/__init__.py +1 -0
- ksadk/harness/native/activation_contract.py +25 -0
- ksadk/harness/native/activation_recovery.py +29 -0
- ksadk/harness/native/adapters.py +291 -0
- ksadk/harness/native/artifact_contract.py +14 -0
- ksadk/harness/native/artifact_partial_read_capacity.py +171 -0
- ksadk/harness/native/artifact_read_capacity.py +182 -0
- ksadk/harness/native/artifact_read_contract.py +27 -0
- ksadk/harness/native/artifact_runtime.py +408 -0
- ksadk/harness/native/artifact_search_capacity.py +206 -0
- ksadk/harness/native/artifact_search_contract.py +40 -0
- ksadk/harness/native/artifact_single_read_capacity.py +170 -0
- ksadk/harness/native/browser_contract.py +229 -0
- ksadk/harness/native/browser_recovery.py +183 -0
- ksadk/harness/native/capabilities.py +204 -0
- ksadk/harness/native/child_approval.py +60 -0
- ksadk/harness/native/child_budget.py +136 -0
- ksadk/harness/native/child_cancellation.py +80 -0
- ksadk/harness/native/child_input.py +98 -0
- ksadk/harness/native/child_input_runtime.py +59 -0
- ksadk/harness/native/child_interruption.py +81 -0
- ksadk/harness/native/child_lifecycle.py +246 -0
- ksadk/harness/native/child_lifecycle_contract.py +91 -0
- ksadk/harness/native/child_notifications.py +75 -0
- ksadk/harness/native/child_promotion.py +66 -0
- ksadk/harness/native/command_runtime.py +99 -0
- ksadk/harness/native/completion.py +302 -0
- ksadk/harness/native/completion_text.py +116 -0
- ksadk/harness/native/context.py +358 -0
- ksadk/harness/native/context_artifact_page.py +75 -0
- ksadk/harness/native/context_compaction_projection.py +131 -0
- ksadk/harness/native/context_contributions.py +320 -0
- ksadk/harness/native/context_contributor_contract.py +133 -0
- ksadk/harness/native/context_driver.py +820 -0
- ksadk/harness/native/context_fresh_tools.py +49 -0
- ksadk/harness/native/context_history.py +272 -0
- ksadk/harness/native/context_microcompact.py +61 -0
- ksadk/harness/native/context_partial_summary.py +58 -0
- ksadk/harness/native/context_partition.py +492 -0
- ksadk/harness/native/context_pruning.py +275 -0
- ksadk/harness/native/context_reduction.py +60 -0
- ksadk/harness/native/context_replay.py +148 -0
- ksadk/harness/native/context_request_projection.py +526 -0
- ksadk/harness/native/context_runtime.py +976 -0
- ksadk/harness/native/context_runtime_contracts.py +409 -0
- ksadk/harness/native/context_search.py +112 -0
- ksadk/harness/native/context_source_fragments.py +188 -0
- ksadk/harness/native/context_source_progress.py +119 -0
- ksadk/harness/native/context_summary_planning.py +788 -0
- ksadk/harness/native/context_summary_recovery.py +105 -0
- ksadk/harness/native/delivery_review.py +331 -0
- ksadk/harness/native/delivery_review_contract.py +54 -0
- ksadk/harness/native/effect_admission.py +82 -0
- ksadk/harness/native/effect_control.py +318 -0
- ksadk/harness/native/effect_receipts.py +729 -0
- ksadk/harness/native/effect_runtime.py +303 -0
- ksadk/harness/native/effective_configuration.py +28 -0
- ksadk/harness/native/engine.py +945 -0
- ksadk/harness/native/final_output.py +34 -0
- ksadk/harness/native/final_submission.py +58 -0
- ksadk/harness/native/finalization_workspace.py +96 -0
- ksadk/harness/native/fork.py +151 -0
- ksadk/harness/native/guidance.py +91 -0
- ksadk/harness/native/history.py +381 -0
- ksadk/harness/native/hook_executor.py +205 -0
- ksadk/harness/native/hook_runtime_contract.py +282 -0
- ksadk/harness/native/interaction_observation.py +117 -0
- ksadk/harness/native/lease.py +103 -0
- ksadk/harness/native/machine.py +974 -0
- ksadk/harness/native/mcp_result_governance.py +156 -0
- ksadk/harness/native/model.py +570 -0
- ksadk/harness/native/model_feedback.py +63 -0
- ksadk/harness/native/model_input.py +30 -0
- ksadk/harness/native/model_recovery_contract.py +35 -0
- ksadk/harness/native/model_replay.py +128 -0
- ksadk/harness/native/model_request.py +133 -0
- ksadk/harness/native/model_runtime.py +196 -0
- ksadk/harness/native/model_takeover.py +419 -0
- ksadk/harness/native/model_tool_batch.py +40 -0
- ksadk/harness/native/observed_progress.py +46 -0
- ksadk/harness/native/operator_guidance.py +201 -0
- ksadk/harness/native/output_contract.py +80 -0
- ksadk/harness/native/output_recovery.py +24 -0
- ksadk/harness/native/ports.py +749 -0
- ksadk/harness/native/precompact_hook_runtime.py +171 -0
- ksadk/harness/native/replay_context.py +149 -0
- ksadk/harness/native/request_media.py +112 -0
- ksadk/harness/native/restore_contract.py +16 -0
- ksadk/harness/native/run_clock.py +120 -0
- ksadk/harness/native/state.py +436 -0
- ksadk/harness/native/steering.py +170 -0
- ksadk/harness/native/stop_hook_runtime.py +151 -0
- ksadk/harness/native/studio_admission.py +29 -0
- ksadk/harness/native/subagents.py +86 -0
- ksadk/harness/native/task_policy.py +99 -0
- ksadk/harness/native/task_progress.py +86 -0
- ksadk/harness/native/terminal_verification.py +43 -0
- ksadk/harness/native/tool_argument_feedback.py +178 -0
- ksadk/harness/native/tool_budget.py +253 -0
- ksadk/harness/native/tool_error_streak.py +89 -0
- ksadk/harness/native/tool_hook_runtime.py +343 -0
- ksadk/harness/native/tool_input_validation.py +58 -0
- ksadk/harness/native/tool_interruption.py +96 -0
- ksadk/harness/native/tool_observation.py +259 -0
- ksadk/harness/native/tool_progress.py +223 -0
- ksadk/harness/native/tool_recovery.py +25 -0
- ksadk/harness/native/tool_scheduling.py +33 -0
- ksadk/harness/native/tool_schema.py +126 -0
- ksadk/harness/native/transitions.py +151 -0
- ksadk/harness/native/turn_control.py +98 -0
- ksadk/harness/native/user_document.py +98 -0
- ksadk/harness/native/user_document_capture.py +49 -0
- ksadk/harness/native/user_input.py +87 -0
- ksadk/harness/native/verification.py +432 -0
- ksadk/harness/native/verification_binding.py +40 -0
- ksadk/harness/native/verification_runtime.py +233 -0
- ksadk/harness/native/verification_workspace.py +67 -0
- ksadk/harness/native_driver_failure.py +123 -0
- ksadk/harness/native_facade.py +977 -0
- ksadk/harness/native_factory.py +244 -0
- ksadk/harness/native_projection.py +503 -0
- ksadk/harness/native_runtime.py +621 -0
- ksadk/harness/native_shadow.py +250 -0
- ksadk/harness/native_shadow_inputs.py +146 -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/progress_adapters/__init__.py +5 -0
- ksadk/harness/progress_adapters/native_todo.py +75 -0
- ksadk/harness/prompt_cache.py +132 -0
- ksadk/harness/public_activity.py +213 -0
- ksadk/harness/public_output.py +30 -0
- ksadk/harness/public_summary.py +36 -0
- ksadk/harness/readiness.py +249 -0
- ksadk/harness/reasoner.py +779 -17
- ksadk/harness/release_readiness.py +140 -0
- ksadk/harness/resource_ref.py +69 -0
- ksadk/harness/rpc.py +200 -0
- ksadk/harness/run_control.py +773 -0
- ksadk/harness/runtime.py +157 -113
- ksadk/harness/runtime_capabilities.py +228 -0
- ksadk/harness/runtime_server.py +514 -0
- ksadk/harness/sandbox_adapters.py +739 -0
- ksadk/harness/sandbox_backend.py +733 -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/sdk.py +153 -0
- ksadk/harness/session_store.py +589 -0
- ksadk/harness/skill_adapters/__init__.py +1 -0
- ksadk/harness/skill_adapters/native_bundle.py +148 -0
- ksadk/harness/skill_adapters/native_disclosure.py +306 -0
- ksadk/harness/skill_composition.py +212 -0
- ksadk/harness/skill_feedback.py +123 -0
- ksadk/harness/skill_intent.py +47 -0
- ksadk/harness/skill_matrix.py +233 -0
- ksadk/harness/skill_runtime.py +317 -0
- ksadk/harness/spec.py +342 -0
- ksadk/harness/state.py +155 -0
- ksadk/harness/stores/__init__.py +14 -0
- ksadk/harness/stores/native_command_settlement.py +65 -0
- ksadk/harness/stores/native_contract.py +311 -0
- ksadk/harness/stores/native_memory.py +326 -0
- ksadk/harness/stores/native_memory_archive.py +70 -0
- ksadk/harness/stores/native_migration_cli.py +91 -0
- ksadk/harness/stores/native_outbox.py +56 -0
- ksadk/harness/stores/native_sqlite.py +782 -0
- ksadk/harness/stores/native_sqlite_audit.py +29 -0
- ksadk/harness/stores/native_sqlite_migration.py +252 -0
- ksadk/harness/strategies.py +149 -0
- ksadk/harness/subagent.py +263 -0
- ksadk/harness/subagent_adapters/checkpoint_recovery.py +120 -0
- ksadk/harness/subagent_adapters/native_background_child.py +803 -0
- ksadk/harness/subagent_adapters/native_child.py +819 -0
- ksadk/harness/subagent_adapters/native_child_approval.py +128 -0
- ksadk/harness/subagent_adapters/native_child_continuation.py +51 -0
- ksadk/harness/subagent_adapters/native_child_result.py +392 -0
- ksadk/harness/subagent_adapters/prepared_recovery.py +120 -0
- ksadk/harness/tool_display.py +75 -0
- ksadk/harness/tool_display_contract.py +134 -0
- ksadk/harness/tool_output.py +141 -0
- ksadk/harness/tool_policy.py +134 -0
- ksadk/harness/tool_receipts.py +96 -0
- ksadk/harness/tool_reliability.py +81 -0
- ksadk/harness/tool_result_policy.py +216 -0
- ksadk/harness/tools.py +52 -0
- ksadk/harness/user_errors.py +69 -0
- ksadk/harness/working_context.py +81 -0
- ksadk/harness/working_context_patch.py +99 -0
- ksadk/harness/workspace_adapters/__init__.py +6 -0
- ksadk/harness/workspace_adapters/native_directory.py +180 -0
- ksadk/harness/workspace_adapters/native_git.py +208 -0
- ksadk/harness/workspace_adapters/native_isolation.py +350 -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 +9 -2
- ksadk/kernel/__init__.py +10 -0
- ksadk/kernel/approval_presentation.py +91 -0
- ksadk/kernel/authorization.py +1 -1
- ksadk/kernel/bootstrap.py +220 -252
- ksadk/kernel/contract_fingerprints.py +45 -1
- ksadk/kernel/contracts.py +30 -0
- ksadk/kernel/control.py +180 -29
- ksadk/kernel/execution_grants.py +428 -0
- ksadk/kernel/execution_grants_memory.py +252 -0
- ksadk/kernel/execution_grants_postgres.py +395 -0
- ksadk/kernel/execution_grants_sqlite.py +435 -0
- ksadk/kernel/execution_host_ingress.py +1071 -0
- ksadk/kernel/history_projection.py +120 -0
- ksadk/kernel/ingress.py +139 -226
- ksadk/kernel/ingress_bootstrap.py +268 -0
- ksadk/kernel/legacy_history.py +179 -0
- ksadk/kernel/mapping.py +1 -1
- ksadk/kernel/memory_store.py +61 -58
- ksadk/kernel/memory_store_projection.py +63 -0
- ksadk/kernel/postgres_event_log.py +181 -0
- ksadk/kernel/postgres_store.py +230 -231
- ksadk/kernel/readiness.py +125 -0
- ksadk/kernel/recovery.py +166 -16
- ksadk/kernel/recovery_projection.py +124 -0
- ksadk/kernel/runtime_checkpoint.py +34 -0
- ksadk/kernel/sql/001_agent_kernel.sql +28 -0
- ksadk/kernel/sqlite_schema.py +100 -0
- ksadk/kernel/sqlite_store.py +410 -200
- ksadk/kernel/state.py +2 -3
- ksadk/kernel/store.py +104 -5
- ksadk/kernel/teams_artifact_tools.py +392 -0
- ksadk/kernel/teams_effects.py +851 -0
- ksadk/kernel/teams_execution_context.py +408 -0
- ksadk/kernel/teams_host_http.py +237 -0
- ksadk/kernel/teams_material_transport.py +245 -0
- ksadk/kernel/teams_materials.py +318 -0
- ksadk/kernel/teams_runtime_bootstrap.py +604 -0
- ksadk/kernel/teams_tool_runtime.py +273 -0
- ksadk/kernel/teams_workspace.py +259 -0
- ksadk/kernel/worker.py +369 -340
- ksadk/kernel/worker_controls.py +454 -0
- ksadk/kernel/worker_history.py +72 -0
- ksadk/kernel/worker_identity.py +74 -0
- ksadk/kernel/worker_interactions.py +197 -0
- ksadk/knowledge_base/client.py +15 -1
- ksadk/managed_runtime.py +29 -2
- ksadk/memory/adk/backends/http_ltm_backend.py +2 -1
- ksadk/memory/adk/backends/sdk_ltm_backend.py +15 -1
- ksadk/memory/adk/bounded_database_session_service.py +232 -0
- ksadk/memory/adk/resilient_session_service.py +115 -15
- ksadk/memory/adk/short_term_memory.py +8 -9
- ksadk/memory/coordinator.py +22 -6
- ksadk/memory/extraction.py +159 -7
- ksadk/memory/models.py +77 -1
- ksadk/memory/provider_resolver.py +5 -0
- ksadk/memory/providers/local_candidates.py +183 -0
- ksadk/memory/providers/local_postgres.py +200 -0
- ksadk/memory/providers/local_sqlite.py +280 -67
- ksadk/memory/resolved_policy.py +12 -7
- ksadk/memory/retrieval.py +189 -0
- ksadk/memory/store_adapter.py +150 -0
- ksadk/model_gateway/__init__.py +29 -0
- ksadk/model_gateway/client.py +253 -0
- ksadk/model_gateway/events.py +113 -0
- ksadk/model_gateway/matrix.py +297 -0
- ksadk/model_policy.py +2 -2
- ksadk/model_proxy/compat.py +670 -0
- ksadk/model_proxy/detect.py +254 -0
- ksadk/model_proxy/server.py +14 -9
- ksadk/model_proxy/transform.py +72 -6
- ksadk/plugins/__init__.py +1 -1
- ksadk/plugins/bridges/dsh.py +29 -20
- ksadk/plugins/bridges/dsh_profile_manifest.py +36 -0
- ksadk/plugins/builtin_resources.py +199 -0
- ksadk/plugins/builtins.py +417 -185
- ksadk/plugins/companion_artifacts.py +83 -0
- ksadk/plugins/companions.py +368 -0
- ksadk/plugins/context_contributor.py +15 -4
- ksadk/plugins/contracts.py +1 -1
- ksadk/plugins/dsh_channels.py +156 -0
- ksadk/plugins/dsh_dependency_policy.py +41 -0
- ksadk/plugins/dsh_home.py +140 -0
- ksadk/plugins/dsh_teams.py +105 -0
- ksadk/plugins/dsh_toolchain.py +92 -21
- ksadk/plugins/execution_host.py +107 -0
- ksadk/plugins/host.py +73 -5
- ksadk/plugins/kernel_adapter.py +44 -1
- ksadk/plugins/memory_provider.py +180 -0
- ksadk/plugins/providers/_process_group.py +50 -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/index.mjs +24 -2
- 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 +52 -40
- ksadk/plugins/providers/codex_native.py +20 -0
- ksadk/plugins/providers/codex_skills.py +46 -0
- ksadk/plugins/providers/dsh_capabilities.py +49 -143
- ksadk/plugins/providers/dsh_connector_lease.py +225 -0
- ksadk/plugins/providers/dsh_mcp.py +163 -1
- ksadk/plugins/providers/harness.py +413 -52
- ksadk/plugins/providers/harness_context.py +61 -0
- ksadk/plugins/providers/harness_contributions.py +241 -0
- ksadk/plugins/providers/harness_delegation.py +670 -0
- ksadk/plugins/providers/harness_hooks.py +121 -0
- ksadk/plugins/providers/harness_managed.py +550 -0
- ksadk/plugins/providers/harness_tools.py +455 -0
- ksadk/plugins/providers/legacy_catalog.py +1 -1
- ksadk/plugins/providers/mcp_projection.py +100 -3
- ksadk/plugins/providers/platform_resources.py +16 -6
- 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 +540 -0
- ksadk/plugins/teams/artifacts.py +60 -0
- ksadk/plugins/teams/build_artifacts.py +460 -0
- ksadk/plugins/teams/cloud_contract_fingerprints.py +22 -0
- ksadk/plugins/teams/cloud_contracts.py +928 -0
- ksadk/plugins/teams/cloud_permits.py +250 -0
- ksadk/plugins/teams/context.py +96 -0
- ksadk/plugins/teams/contracts.py +136 -0
- ksadk/plugins/teams/domain.py +1480 -0
- ksadk/plugins/teams/domain_values.py +24 -0
- ksadk/plugins/teams/effect_contracts.py +255 -0
- ksadk/plugins/teams/errors.py +13 -0
- ksadk/plugins/teams/execution_projection.py +255 -0
- ksadk/plugins/teams/leader_decisions.py +106 -0
- ksadk/plugins/teams/migration.py +311 -0
- ksadk/plugins/teams/migration_cli.py +322 -0
- ksadk/plugins/teams/postgres_store.py +352 -0
- ksadk/plugins/teams/release_contracts.py +60 -0
- ksadk/plugins/teams/runtime.py +853 -0
- ksadk/plugins/teams/source_projection.py +84 -0
- ksadk/plugins/teams/store.py +519 -0
- ksadk/plugins/teams/task_decisions.py +436 -0
- ksadk/plugins/teams/tool_service.py +152 -0
- ksadk/plugins/teams/transport.py +96 -0
- ksadk/plugins/teams/workspaces.py +255 -0
- ksadk/resource_runtime/skill_runtime.py +3 -0
- ksadk/resource_runtime/socket_server.py +11 -0
- ksadk/resource_runtime/worker.py +28 -4
- ksadk/runners/_adk_a2a_stream.py +122 -0
- ksadk/runners/_adk_canonical_stream.py +474 -0
- ksadk/runners/_langgraph_canonical_streams.py +527 -0
- ksadk/runners/_langgraph_runner_streams.py +83 -401
- ksadk/runners/_langgraph_state_reader.py +106 -0
- ksadk/runners/_langgraph_tool_projection.py +86 -0
- ksadk/runners/_langgraph_tools_transformer.py +27 -0
- ksadk/runners/_session_identity.py +285 -0
- ksadk/runners/adk_runner.py +220 -350
- ksadk/runners/base_runner.py +6 -5
- ksadk/runners/langgraph_runner.py +208 -195
- ksadk/runners/patch_langchain.py +47 -0
- ksadk/runners/usage_accumulator.py +11 -3
- ksadk/runners/utils/loader.py +28 -14
- ksadk/runtime/_runner_adapter/a2ui_surface.py +145 -0
- ksadk/runtime/_runner_adapter/gateway_approvals.py +93 -0
- ksadk/runtime/_runner_adapter/stream_mapping.py +134 -129
- ksadk/runtime/adapter.py +40 -3
- ksadk/runtime/conversation_execution.py +29 -3
- ksadk/runtime/executor.py +105 -7
- ksadk/runtime/factory.py +45 -3
- ksadk/runtime/framework_adapters.py +184 -10
- ksadk/runtime/hosted_finalizer.py +4 -6
- ksadk/runtime/launch.py +2 -0
- ksadk/runtime/preprocessing.py +11 -3
- ksadk/runtime/runner_adapter.py +160 -21
- ksadk/runtime/skill_eval_result.py +36 -0
- ksadk/runtime/timing.py +46 -0
- ksadk/runtime/usage.py +49 -18
- ksadk/runtime_context.py +105 -1
- ksadk/sandbox/backends/e2b.py +272 -24
- ksadk/sandbox/backends/local_process.py +73 -39
- ksadk/sandbox/base.py +62 -1
- ksadk/sandbox/diagnostics.py +82 -0
- ksadk/sandbox/e2b_connection.py +9 -1
- ksadk/sandbox/local_controls.py +776 -0
- ksadk/sandbox/local_launcher.py +124 -0
- ksadk/scheduler/dispatcher.py +1 -1
- ksadk/server/factory.py +178 -25
- ksadk/server/history_deadline.py +158 -0
- ksadk/server/history_page_cache.py +129 -0
- ksadk/server/invocation_identity.py +118 -0
- ksadk/server/routes/checkpoint_audit.py +88 -0
- ksadk/server/routes/checkpoint_listing.py +294 -0
- ksadk/server/routes/checkpoint_resolution.py +73 -20
- ksadk/server/routes/common.py +32 -3
- ksadk/server/routes/control.py +112 -9
- ksadk/server/routes/dependencies.py +2 -1
- ksadk/server/routes/display_projection.py +154 -0
- ksadk/server/routes/kernel_ingress.py +26 -3
- ksadk/server/routes/misc.py +331 -33
- ksadk/server/routes/models.py +28 -4
- ksadk/server/routes/openai_compat.py +82 -13
- ksadk/server/routes/projection.py +159 -216
- ksadk/server/routes/run.py +112 -37
- ksadk/server/routes/sessions.py +493 -358
- ksadk/server/routes/streaming.py +68 -15
- ksadk/server/routes/tool_receipt_claim_routes.py +107 -0
- ksadk/server/routes/workspace.py +135 -23
- ksadk/server/static/assets/{ArtifactsPanel-CGbWlMNh.js → ArtifactsPanel-CILaW-fC.js} +1 -1
- ksadk/server/static/assets/{CodeBlock-b4C7upmO.js → CodeBlock-BVrNVtJC.js} +10 -7
- ksadk/server/static/assets/MathMessageMarkdown-Dp7c4wWD.js +8 -0
- ksadk/server/static/assets/{MermaidBlock-BEBN4Ksz.js → MermaidBlock-Dxop8Rd7.js} +9 -9
- ksadk/server/static/assets/{NativeTerminalPanel-zvL-WpAn.js → NativeTerminalPanel-Cjjz8B30.js} +1 -1
- ksadk/server/static/assets/{abnfDiagram-VCTEODGH-BYafW7Za.js → abnfDiagram-VCTEODGH-ckWDmOzw.js} +1 -1
- ksadk/server/static/assets/{arc-bTohInsS.js → arc-DqxJede-.js} +1 -1
- ksadk/server/static/assets/architecture-7GRP2DOG-pn_DuLy6.js +1 -0
- ksadk/server/static/assets/{architectureDiagram-5GKGNRK7-Ch5Lbzsi.js → architectureDiagram-5GKGNRK7-SEQA4bVi.js} +1 -1
- ksadk/server/static/assets/{blockDiagram-NRAW4CY4-kqF4MDOG.js → blockDiagram-NRAW4CY4-pM0B-6NJ.js} +1 -1
- ksadk/server/static/assets/{c4Diagram-UCG6FXSJ-8uSRIODv.js → c4Diagram-UCG6FXSJ-m2tuCNVq.js} +1 -1
- ksadk/server/static/assets/channel-fySsnkft.js +1 -0
- ksadk/server/static/assets/chunk-2Q5K7J3B-BheGxKRQ.js +1 -0
- ksadk/server/static/assets/{chunk-5VM5RSS4-DkhehZDr.js → chunk-5VM5RSS4-GJHDr9Ww.js} +1 -1
- ksadk/server/static/assets/{chunk-F27PBJKO-BdXhtPe9.js → chunk-F27PBJKO-CbAN45AV.js} +1 -1
- ksadk/server/static/assets/{chunk-G27WJ6UU-DPTpvpwi.js → chunk-G27WJ6UU-D5ngbbzF.js} +1 -1
- ksadk/server/static/assets/{chunk-JWPE2WC7-Pqoh38el.js → chunk-JWPE2WC7-Cc5IwuYC.js} +1 -1
- ksadk/server/static/assets/{chunk-LCL6LL3I-DeU00qC-.js → chunk-LCL6LL3I-CprgDDdJ.js} +1 -1
- ksadk/server/static/assets/{chunk-POPQ4Y6H-CzxScFkr.js → chunk-POPQ4Y6H-CDZhSy82.js} +1 -1
- ksadk/server/static/assets/{chunk-RHFEMEQ7-DpqMx-ux.js → chunk-RHFEMEQ7-CZchUNro.js} +1 -1
- ksadk/server/static/assets/{chunk-SVP7TREG-C6t0SypQ.js → chunk-SVP7TREG-BVruqk6T.js} +1 -1
- ksadk/server/static/assets/{chunk-XXDRQBXY-DVaeafZk.js → chunk-XXDRQBXY-4ld9SxPN.js} +1 -1
- ksadk/server/static/assets/classDiagram-DTDB5LWJ-DSfLtNYm.js +1 -0
- ksadk/server/static/assets/classDiagram-v2-JRS7N3AN-DSfLtNYm.js +1 -0
- ksadk/server/static/assets/{cose-bilkent-JH36ORCC-Bf9D3tzJ.js → cose-bilkent-JH36ORCC-Dmyyk_Vp.js} +1 -1
- ksadk/server/static/assets/cynefin-OW5HDTMX-PFWIGtvA.js +1 -0
- ksadk/server/static/assets/{cynefinDiagram-5FMLGOSQ-B9cY3iTz.js → cynefinDiagram-5FMLGOSQ-BIyq3EJb.js} +1 -1
- ksadk/server/static/assets/{dagre-3AP2YEHR-CSwlx3CB.js → dagre-3AP2YEHR-eBw08Qdk.js} +1 -1
- ksadk/server/static/assets/{dagre-UBpgon5q.js → dagre-DfvnEf45.js} +1 -1
- ksadk/server/static/assets/{diagram-S7CK7UJ4-C9akhN9a.js → diagram-S7CK7UJ4-CUSrE3Mg.js} +1 -1
- ksadk/server/static/assets/{diagram-UQ7AKVKN-CgedhTPI.js → diagram-UQ7AKVKN-Dq5Zw2gy.js} +1 -1
- ksadk/server/static/assets/{diagram-VSXAHHWV-Cjucz5BY.js → diagram-VSXAHHWV-DyUHfNwT.js} +1 -1
- ksadk/server/static/assets/{diagram-VX7I27RA-Dd4Vleyn.js → diagram-VX7I27RA-CREmM89O.js} +1 -1
- ksadk/server/static/assets/{diagram-Z3DM3KII-CZ2jGtYW.js → diagram-Z3DM3KII-Dw9zhHUK.js} +1 -1
- ksadk/server/static/assets/{dist-Bj730Ib4.js → dist-0uJ4tdx6.js} +1 -1
- ksadk/server/static/assets/{dist-BnaTiyzN.js → dist-AEv-vXf-.js} +1 -1
- ksadk/server/static/assets/{dist-BgV_owcB.js → dist-B49GzZDb.js} +1 -1
- ksadk/server/static/assets/{dist-D_ctSS2i.js → dist-B8Myiet9.js} +1 -1
- ksadk/server/static/assets/{dist-ufY3F5p6.js → dist-BBsYarrI.js} +2 -2
- ksadk/server/static/assets/{dist-ClYUxfeK.js → dist-BQMrUwdI.js} +1 -1
- ksadk/server/static/assets/{dist-CFzsn6BG.js → dist-BX_-FENW.js} +1 -1
- ksadk/server/static/assets/{dist-B3FR1SKK.js → dist-CD4L6ymH.js} +1 -1
- ksadk/server/static/assets/{dist-Cf125P_m.js → dist-CHpW1BHj.js} +1 -1
- ksadk/server/static/assets/{dist-DVCOWtha.js → dist-CVPau3tn.js} +1 -1
- ksadk/server/static/assets/{dist-DFD6Qa6T.js → dist-C_qdxcSH.js} +1 -1
- ksadk/server/static/assets/{dist-BIr4DSRq.js → dist-Co68Apq4.js} +1 -1
- ksadk/server/static/assets/{dist-DiixqL0J.js → dist-Cp2PaOMY.js} +1 -1
- ksadk/server/static/assets/{dist-fBO2v5Kt.js → dist-CuR5Bgme.js} +1 -1
- ksadk/server/static/assets/{dist-DoVSwoDb.js → dist-DDSyLEOX.js} +1 -1
- ksadk/server/static/assets/{dist-C5_ZAZsG.js → dist-DUxO0R99.js} +1 -1
- ksadk/server/static/assets/{dist-C1NMAY5a.js → dist-QzbGrED_.js} +1 -1
- ksadk/server/static/assets/dist-bupkyEBZ.js +1 -0
- ksadk/server/static/assets/{dist-DvFK7p5S.js → dist-cxTGfdqx.js} +1 -1
- ksadk/server/static/assets/{dist-CB9iJrvg.js → dist-hL5p1til.js} +1 -1
- ksadk/server/static/assets/{dist-btbmmX5O.js → dist-lOy23y43.js} +1 -1
- ksadk/server/static/assets/{dist-QfkEHOlb.js → dist-pq-nD33R.js} +1 -1
- ksadk/server/static/assets/{ebnfDiagram-PWID7BFC-Ci8NqqZu.js → ebnfDiagram-PWID7BFC-BS5LdNoR.js} +1 -1
- ksadk/server/static/assets/{erDiagram-SSCWMZ5O-CCIOhLZG.js → erDiagram-SSCWMZ5O-Bv1QtiY-.js} +1 -1
- ksadk/server/static/assets/eventmodeling-NTZA5JFV-DsM4upQX.js +1 -0
- ksadk/server/static/assets/flowDiagram-A5DVABFB-D5NA16k9.js +1 -0
- ksadk/server/static/assets/{ganttDiagram-EL5Y4UJY-Cp_r9Hb6.js → ganttDiagram-EL5Y4UJY-musi-e0G.js} +1 -1
- ksadk/server/static/assets/gitGraph-4MIJSDKK-DUCVz-ih.js +1 -0
- ksadk/server/static/assets/{gitGraphDiagram-WWUBYQGX-Dlhc8Wr8.js → gitGraphDiagram-WWUBYQGX-DH37EGkG.js} +1 -1
- ksadk/server/static/assets/index-CZdkAvsv.js +244 -0
- ksadk/server/static/assets/index-CvXdHgF3.css +2 -0
- ksadk/server/static/assets/info-A6RAGUB7-rw0ZNHZp.js +1 -0
- ksadk/server/static/assets/{infoDiagram-RXCK75RN-CO0rRTRA.js → infoDiagram-RXCK75RN-C1kEtv2y.js} +1 -1
- ksadk/server/static/assets/{ishikawaDiagram-5VMMS53U-CHiaedSS.js → ishikawaDiagram-5VMMS53U-BCNPyMka.js} +1 -1
- ksadk/server/static/assets/{journeyDiagram-EYS64GPL-CHcCIB09.js → journeyDiagram-EYS64GPL--cDbKnjP.js} +1 -1
- ksadk/server/static/assets/{kanban-definition-3QL26DDD-CJ_ebBZf.js → kanban-definition-3QL26DDD-R1rAVw2f.js} +1 -1
- ksadk/server/static/assets/{katex-B4weu383.js → katex-BT-X-V7U.js} +1 -1
- ksadk/server/static/assets/{linear-V-MgYHW1.js → linear-DTR631iG.js} +1 -1
- ksadk/server/static/assets/{mermaid-parser.core-CBijEX_c.js → mermaid-parser.core-DfFzJhX8.js} +2 -2
- ksadk/server/static/assets/{mindmap-definition-FBJOCRG2-Bc-pQvpp.js → mindmap-definition-FBJOCRG2-D4by_rmk.js} +1 -1
- ksadk/server/static/assets/packet-AYTQ26CC-Ca4Hvki9.js +1 -0
- ksadk/server/static/assets/{pegDiagram-XKGWAZYB-D7genGLl.js → pegDiagram-XKGWAZYB-xWXPEh0c.js} +1 -1
- ksadk/server/static/assets/pie-WAS4IAKB-hwiz6fbw.js +1 -0
- ksadk/server/static/assets/{pieDiagram-E7YTZNPT-Bxj32zwD.js → pieDiagram-E7YTZNPT-BudBDlCI.js} +1 -1
- ksadk/server/static/assets/{quadrantDiagram-AXDQQJYC-BURv2mGh.js → quadrantDiagram-AXDQQJYC-DXZ0PCJF.js} +1 -1
- ksadk/server/static/assets/radar-RG4KPBEZ-BR1oZXLM.js +1 -0
- ksadk/server/static/assets/railroad-74A4TZTK-DfgEISfX.js +1 -0
- ksadk/server/static/assets/railroad-abnf-HS5TGJTU-CWOC3rdk.js +1 -0
- ksadk/server/static/assets/railroad-ebnf-LZEXJU2U-CiRvHCLY.js +1 -0
- ksadk/server/static/assets/railroad-peg-WCYAUIDC-DSDDyJ2f.js +1 -0
- ksadk/server/static/assets/{railroadDiagram-O6MQD6OU-CCsh3avW.js → railroadDiagram-O6MQD6OU-BdAYRYB8.js} +1 -1
- ksadk/server/static/assets/{requirementDiagram-EFPCY7ZU-_FRRBKEd.js → requirementDiagram-EFPCY7ZU-CBBmaL70.js} +1 -1
- ksadk/server/static/assets/{sankeyDiagram-P5KCCOFB-C-gr2o9M.js → sankeyDiagram-P5KCCOFB-Doc3rdwp.js} +1 -1
- ksadk/server/static/assets/{sequenceDiagram-WJ2MYXX4-D97NmfKg.js → sequenceDiagram-WJ2MYXX4-0J8R8hWW.js} +1 -1
- ksadk/server/static/assets/{sizeCapture-X5ZJPWSS-DjrPC5FX.js → sizeCapture-X5ZJPWSS-CfFLlWsK.js} +1 -1
- ksadk/server/static/assets/{stateDiagram-HBIQ2CUA-DzMNg1hh.js → stateDiagram-HBIQ2CUA-jBwkjtTy.js} +1 -1
- ksadk/server/static/assets/stateDiagram-v2-4QOOHH4V-Cw1fPb5w.js +1 -0
- ksadk/server/static/assets/{swimlanes-XN3QIQJK-Cssf_CsU.js → swimlanes-XN3QIQJK-B0WxTQf8.js} +1 -1
- ksadk/server/static/assets/swimlanesDiagram-VK2B7HYN-Cc3JMBAF.js +8 -0
- ksadk/server/static/assets/{timeline-definition-24CTP7MA-BWTHzyS1.js → timeline-definition-24CTP7MA-BfCT_75A.js} +1 -1
- ksadk/server/static/assets/treeView-Q6P3EWNA-C05SJHxo.js +1 -0
- ksadk/server/static/assets/treemap-WGGIJYW6-BqNLAhc3.js +1 -0
- ksadk/server/static/assets/{vennDiagram-4TSXK5OY-BSKgJsmR.js → vennDiagram-4TSXK5OY-9gX1VMDC.js} +1 -1
- ksadk/server/static/assets/wardley-WFR3VGLG-DokNktqB.js +1 -0
- ksadk/server/static/assets/{wardleyDiagram-VM6X3IG4-eflHNoaZ.js → wardleyDiagram-VM6X3IG4-sEs_BP6O.js} +1 -1
- ksadk/server/static/assets/{xychartDiagram-S5SC5T6Z-eYqrQ-v4.js → xychartDiagram-S5SC5T6Z-Ll4jvUN9.js} +1 -1
- ksadk/server/static/index.html +2 -2
- ksadk/server/terminal_sessions.py +34 -2
- ksadk/sessions/__init__.py +8 -1
- ksadk/sessions/_checkpoint_resume_audit.py +44 -0
- ksadk/sessions/_in_memory_query.py +112 -0
- ksadk/sessions/_local_service_sync.py +157 -156
- ksadk/sessions/_local_state_sync.py +152 -0
- ksadk/sessions/_local_tables.py +2 -0
- ksadk/sessions/_postgres_checkpoint_read.py +323 -0
- ksadk/sessions/_postgres_checkpoint_stats.py +330 -0
- ksadk/sessions/_postgres_history_read.py +678 -0
- ksadk/sessions/_postgres_schema.py +44 -2
- ksadk/sessions/_postgres_tables.py +2 -0
- ksadk/sessions/_postgres_tool_receipts.py +169 -0
- ksadk/sessions/_resilient_read.py +630 -0
- ksadk/sessions/_tool_receipt_sync.py +119 -0
- ksadk/sessions/agent_identity.py +16 -0
- ksadk/sessions/base.py +278 -0
- ksadk/sessions/db_budget.py +332 -0
- ksadk/sessions/errors.py +12 -0
- ksadk/sessions/history_budget.py +36 -0
- ksadk/sessions/history_identity.py +27 -0
- ksadk/sessions/in_memory.py +376 -113
- ksadk/sessions/invocation_identity.py +235 -0
- ksadk/sessions/local_service.py +345 -0
- ksadk/sessions/postgres_service.py +515 -549
- ksadk/sessions/resilience.py +21 -14
- ksadk/sessions/resilient.py +611 -504
- ksadk/skills/__init__.py +26 -0
- ksadk/skills/events.py +464 -0
- ksadk/skills/loader.py +44 -2
- 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 +400 -56
- 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/service_client.py +6 -1
- ksadk/skills/tool_defs.py +108 -3
- ksadk/studio/a2a_bindings.py +407 -0
- ksadk/studio/a2a_orchestration.py +178 -0
- ksadk/studio/active_run_output.py +92 -0
- ksadk/studio/activity_records.py +542 -0
- ksadk/studio/agent_configuration.py +173 -0
- ksadk/studio/api.py +784 -419
- ksadk/studio/api_a2a_routes.py +93 -0
- ksadk/studio/api_catalog_routes.py +13 -0
- ksadk/studio/api_cloud_chat_routes.py +382 -0
- ksadk/studio/api_contracts.py +31 -2
- ksadk/studio/api_plugin_routes.py +39 -12
- ksadk/studio/api_resource_connections.py +79 -41
- ksadk/studio/attachment_store.py +14 -2
- ksadk/studio/authoring.py +12 -6
- ksadk/studio/authoring_coordinator.py +4 -2
- ksadk/studio/build_resolution.py +117 -0
- ksadk/studio/build_singleflight.py +37 -0
- ksadk/studio/builder.py +32 -2
- ksadk/studio/capabilities.py +31 -9
- ksadk/studio/channel_connections.py +333 -0
- ksadk/studio/cloud.py +113 -387
- ksadk/studio/cloud_gateways.py +424 -0
- ksadk/studio/cloud_shared_web.py +82 -2
- ksadk/studio/codex_agent_service.py +19 -2
- ksadk/studio/codex_builder.py +1 -1
- ksadk/studio/codex_manifest.py +5 -1
- ksadk/studio/codex_provider_build.py +65 -0
- ksadk/studio/codex_run.py +6 -1
- ksadk/studio/compiler.py +112 -6
- ksadk/studio/configuration.py +182 -0
- ksadk/studio/contract_base.py +19 -0
- ksadk/studio/contracts.py +260 -202
- ksadk/studio/dsh_application.py +183 -27
- ksadk/studio/dsh_capability_service.py +302 -189
- ksadk/studio/dsh_lifecycle.py +58 -0
- ksadk/studio/dsh_mcp_transport.py +191 -0
- ksadk/studio/dsh_provider_registration.py +55 -16
- ksadk/studio/entry.py +53 -0
- ksadk/studio/event_store.py +53 -5
- ksadk/studio/execution_host.py +598 -0
- ksadk/studio/framework_run.py +50 -10
- ksadk/studio/hosted_kernel.py +1 -1
- ksadk/studio/interaction_submission.py +265 -0
- ksadk/studio/kernel_registry.py +429 -0
- ksadk/studio/kernel_sqlite_migration.py +181 -0
- ksadk/studio/lifecycle_status.py +43 -0
- ksadk/studio/model_buffered_wire.py +227 -0
- ksadk/studio/model_chat_tools.py +143 -0
- ksadk/studio/model_client.py +1939 -345
- ksadk/studio/model_content_stream.py +129 -0
- ksadk/studio/model_credentials.py +196 -0
- ksadk/studio/model_profile_service.py +89 -40
- ksadk/studio/model_request_projection.py +284 -0
- ksadk/studio/model_responses_content.py +296 -0
- ksadk/studio/model_usage.py +109 -0
- ksadk/studio/model_wire_failure.py +110 -0
- ksadk/studio/model_wire_identity.py +138 -0
- ksadk/studio/model_wire_snapshot.py +45 -0
- ksadk/studio/model_wire_tools.py +283 -0
- ksadk/studio/native_acceptance.py +68 -0
- ksadk/studio/native_approval.py +111 -0
- ksadk/studio/native_browser_port.py +861 -0
- ksadk/studio/native_child_mcp.py +87 -0
- ksadk/studio/native_child_publication.py +68 -0
- ksadk/studio/native_child_skills.py +72 -0
- ksadk/studio/native_child_workspace.py +176 -0
- ksadk/studio/native_command_policy.py +53 -0
- ksadk/studio/native_context_port.py +326 -0
- ksadk/studio/native_context_registration.py +54 -0
- ksadk/studio/native_document_input.py +88 -0
- ksadk/studio/native_documents.py +172 -0
- ksadk/studio/native_final_shape.py +852 -0
- ksadk/studio/native_gateway_stream.py +69 -0
- ksadk/studio/native_hook_port.py +145 -0
- ksadk/studio/native_hook_registration.py +70 -0
- ksadk/studio/native_inventory_disclosure.py +223 -0
- ksadk/studio/native_kernel_admission.py +84 -0
- ksadk/studio/native_language_diagnostics.py +320 -0
- ksadk/studio/native_mcp_disclosure.py +198 -0
- ksadk/studio/native_mcp_tool_port.py +219 -0
- ksadk/studio/native_memory_acceptance.py +362 -0
- ksadk/studio/native_memory_context.py +266 -0
- ksadk/studio/native_memory_flush.py +174 -0
- ksadk/studio/native_memory_sources.py +80 -0
- ksadk/studio/native_memory_tool_port.py +360 -0
- ksadk/studio/native_memory_turn.py +183 -0
- ksadk/studio/native_model_port.py +765 -0
- ksadk/studio/native_model_recovery.py +126 -0
- ksadk/studio/native_options.py +75 -0
- ksadk/studio/native_output_fields.py +58 -0
- ksadk/studio/native_planning.py +156 -0
- ksadk/studio/native_product.py +988 -0
- ksadk/studio/native_read_budget.py +426 -0
- ksadk/studio/native_recovery.py +171 -0
- ksadk/studio/native_scope.py +35 -0
- ksadk/studio/native_session_context_port.py +141 -0
- ksadk/studio/native_session_engine.py +14 -0
- ksadk/studio/native_skill_source.py +74 -0
- ksadk/studio/native_subagent_port.py +700 -0
- ksadk/studio/native_terminal_recovery.py +95 -0
- ksadk/studio/native_test_action.py +610 -0
- ksadk/studio/native_tool_port.py +477 -0
- ksadk/studio/native_user_input.py +60 -0
- ksadk/studio/native_verification_presentation.py +65 -0
- ksadk/studio/native_workspace_diagnostics.py +183 -0
- ksadk/studio/native_workspace_port.py +43 -0
- ksadk/studio/operations.py +34 -9
- ksadk/studio/plugin_composition.py +39 -12
- ksadk/studio/plugin_kernel_adapter.py +89 -0
- ksadk/studio/plugin_lifecycle.py +80 -0
- ksadk/studio/plugin_native_activation.py +163 -0
- ksadk/studio/plugin_runtime.py +832 -99
- ksadk/studio/plugin_runtime_admission.py +57 -0
- ksadk/studio/presentation.py +92 -0
- ksadk/studio/provider_recovery.py +59 -0
- ksadk/studio/public_output_store.py +69 -0
- ksadk/studio/recovery_page.py +70 -0
- ksadk/studio/resource_authority.py +69 -34
- ksadk/studio/resource_catalog.py +14 -12
- ksadk/studio/run_activity.py +848 -0
- ksadk/studio/run_controls.py +185 -0
- ksadk/studio/run_documents.py +127 -0
- ksadk/studio/run_service.py +1220 -335
- ksadk/studio/run_submission_receipts.py +68 -0
- ksadk/studio/runtime_catalog.py +73 -11
- ksadk/studio/runtime_prewarm.py +22 -0
- ksadk/studio/runtime_source.py +1 -1
- ksadk/studio/scheduler_assistant.py +4 -1
- ksadk/studio/scheduler_runtime.py +32 -289
- ksadk/studio/service.py +615 -246
- ksadk/studio/service_settings.py +229 -0
- ksadk/studio/shared_web.py +518 -181
- ksadk/studio/shared_web_response_events.py +180 -0
- ksadk/studio/shared_web_run_state.py +133 -0
- ksadk/studio/skill_discovery.py +305 -3
- ksadk/studio/static/assets/ChannelsPage-xX5HlMId.js +8 -0
- ksadk/studio/static/assets/CodeBlock-DMIf4h33-CkufcPYo.js +44 -0
- ksadk/studio/static/assets/ExecutionTree-v3HexvPo-Bk8wzGSy.js +1 -0
- ksadk/studio/static/assets/MathMessageMarkdown-BesSeCYl-DYG1Wzbx.js +8 -0
- ksadk/studio/static/assets/MermaidBlock-H_0qzQDf-BdXtxug_.js +11 -0
- ksadk/studio/static/assets/MessageMarkdown-CwMTvgFj-BeyLyQHu.js +59 -0
- ksadk/studio/static/assets/PrismRenderer-5pK6tUdb.js +3 -0
- ksadk/studio/static/assets/TeamsPage-CCaaGaVp.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-C7DNDik2.css +2 -0
- ksadk/studio/static/assets/index-Cy68gTlH.js +265 -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 +166 -0
- ksadk/studio/teams_installation.py +217 -0
- ksadk/studio/teams_node.py +549 -0
- ksadk/studio/teams_node_factory.py +558 -0
- ksadk/studio/teams_node_runner.py +72 -0
- ksadk/studio/teams_node_v1.py +935 -0
- ksadk/studio/teams_remote.py +496 -0
- ksadk/studio/templates.py +41 -19
- ksadk/studio/validator.py +13 -0
- ksadk/studio/workspace.py +19 -4
- ksadk/studio/workspace_plugins.py +138 -0
- ksadk/studio/workspace_registry.py +286 -0
- ksadk/tools/a2a_policy.py +5 -0
- ksadk/tools/artifact_observation.py +53 -0
- ksadk/tools/captured_source_artifact.py +68 -0
- ksadk/tools/schema.py +34 -0
- ksadk/toolsets/__init__.py +93 -88
- ksadk/toolsets/a2a.py +89 -89
- ksadk/toolsets/sandbox.py +377 -6
- ksadk/toolsets/skill_management.py +315 -0
- ksadk/toolsets/skills.py +446 -378
- ksadk/toolsets/tool_selection.py +94 -0
- ksadk/toolsets/workspace.py +344 -326
- ksadk/toolsets/workspace_editing.py +291 -0
- ksadk/toolsets/workspace_identity.py +15 -0
- ksadk/toolsets/workspace_model_observation.py +104 -0
- ksadk/toolsets/workspace_mutation.py +75 -0
- ksadk/toolsets/workspace_read_budget.py +216 -0
- ksadk/toolsets/workspace_search.py +192 -0
- ksadk/toolsets/workspace_search_process.py +129 -0
- ksadk/toolsets/workspace_state.py +6 -0
- ksadk/version.py +1 -1
- ksadk_runtime_common/http_headers.py +18 -0
- 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 +28 -14
- agentengine_sdk_python-0.8.4.dist-info/RECORD +0 -1070
- 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.6.dist-info}/WHEEL +0 -0
- {agentengine_sdk_python-0.8.4.dist-info → agentengine_sdk_python-0.8.6.dist-info}/entry_points.txt +0 -0
- {agentengine_sdk_python-0.8.4.dist-info → agentengine_sdk_python-0.8.6.dist-info}/licenses/LICENSE +0 -0
- {agentengine_sdk_python-0.8.4.dist-info → agentengine_sdk_python-0.8.6.dist-info}/top_level.txt +0 -0
- /ksadk/studio/static/assets/{MathMessageMarkdown-CBcDrAw--BEOyPC3w.css → MathMessageMarkdown-BesSeCYl-BEOyPC3w.css} +0 -0
|
@@ -0,0 +1,1071 @@
|
|
|
1
|
+
"""Trusted teams-host/v1 service over the existing Kernel, never a model path.
|
|
2
|
+
|
|
3
|
+
Production bootstrap must supply internal service authentication, trusted context
|
|
4
|
+
loading, a mounted policy resolver and the actual durable event store. This
|
|
5
|
+
module deliberately provides no unauthenticated/default HTTP router.
|
|
6
|
+
"""
|
|
7
|
+
|
|
8
|
+
from __future__ import annotations
|
|
9
|
+
|
|
10
|
+
import time
|
|
11
|
+
from collections.abc import Awaitable, Callable
|
|
12
|
+
from dataclasses import dataclass
|
|
13
|
+
from datetime import datetime, timezone
|
|
14
|
+
from typing import Any
|
|
15
|
+
|
|
16
|
+
from ksadk.conversations.projector import project_conversation_item
|
|
17
|
+
from ksadk.events.canonical import parse_runtime_event
|
|
18
|
+
from ksadk.harness.execution_policy import ExecutionPolicy
|
|
19
|
+
from ksadk.kernel.contracts import AgentControlCommand, AgentControlPermit
|
|
20
|
+
from ksadk.kernel.execution_grants import execution_grant_run_id
|
|
21
|
+
from ksadk.kernel.store import command_digest
|
|
22
|
+
from ksadk.kernel.teams_execution_context import (
|
|
23
|
+
ContextConflict,
|
|
24
|
+
PreparedTeamsContext,
|
|
25
|
+
StoreIdentityMismatch,
|
|
26
|
+
TeamsExecutionContextRegistry,
|
|
27
|
+
)
|
|
28
|
+
from ksadk.plugins.teams.cloud_contracts import (
|
|
29
|
+
CanonicalEventBatch,
|
|
30
|
+
CanonicalExecutionEvent,
|
|
31
|
+
EventSourceRef,
|
|
32
|
+
ExecutionGrantBarrierView,
|
|
33
|
+
ExecutionGrantSnapshot,
|
|
34
|
+
ExecutionGrantView,
|
|
35
|
+
GetGrantResult,
|
|
36
|
+
GrantCommandView,
|
|
37
|
+
GrantMutationReceipt,
|
|
38
|
+
HostReceipt,
|
|
39
|
+
MaterialProof,
|
|
40
|
+
PrepareResult,
|
|
41
|
+
SetAdmissionResult,
|
|
42
|
+
SetGrantResult,
|
|
43
|
+
TerminalEvidence,
|
|
44
|
+
digest,
|
|
45
|
+
)
|
|
46
|
+
from ksadk.plugins.teams.cloud_permits import (
|
|
47
|
+
BindingProbePermit,
|
|
48
|
+
PermitError,
|
|
49
|
+
TeamsExecutionPermit,
|
|
50
|
+
TeamsPermitVerifier,
|
|
51
|
+
timestamp,
|
|
52
|
+
)
|
|
53
|
+
|
|
54
|
+
TEAMS_HOST_PROTOCOL = "teams-host/v1"
|
|
55
|
+
_TERMINAL = {
|
|
56
|
+
"run.completed": "succeeded",
|
|
57
|
+
"run.failed": "failed",
|
|
58
|
+
"run.canceled": "cancelled",
|
|
59
|
+
"run.interrupted": "interrupted",
|
|
60
|
+
}
|
|
61
|
+
_RUN_STATUS = {
|
|
62
|
+
"pending": "queued",
|
|
63
|
+
"running": "running",
|
|
64
|
+
"paused": "waiting",
|
|
65
|
+
"waiting": "awaiting_approval",
|
|
66
|
+
"completed": "succeeded",
|
|
67
|
+
"failed": "failed",
|
|
68
|
+
"cancelled": "cancelled",
|
|
69
|
+
"interrupted": "interrupted",
|
|
70
|
+
}
|
|
71
|
+
|
|
72
|
+
|
|
73
|
+
def _time(value: str) -> datetime:
|
|
74
|
+
return datetime.fromisoformat(value.replace("Z", "+00:00"))
|
|
75
|
+
|
|
76
|
+
|
|
77
|
+
def grant_snapshot(barrier, store_incarnation: str) -> ExecutionGrantSnapshot:
|
|
78
|
+
"""Translate existing Kernel facts without introducing another state machine."""
|
|
79
|
+
grant = barrier.grant
|
|
80
|
+
if grant.attempt_epoch is None or grant.expires_at is None:
|
|
81
|
+
raise ContextConflict("Teams requires an expiring, attempt-scoped grant")
|
|
82
|
+
return ExecutionGrantSnapshot(
|
|
83
|
+
storeIncarnation=store_incarnation,
|
|
84
|
+
grant=ExecutionGrantView(
|
|
85
|
+
grantId=grant.grant_id,
|
|
86
|
+
state=grant.state,
|
|
87
|
+
revision=grant.revision,
|
|
88
|
+
attemptEpoch=grant.attempt_epoch,
|
|
89
|
+
expiresAt=timestamp(_time(grant.expires_at)),
|
|
90
|
+
admissionAllowed=grant.admission_allowed,
|
|
91
|
+
admissionRevision=grant.admission_revision,
|
|
92
|
+
),
|
|
93
|
+
barrier=ExecutionGrantBarrierView(
|
|
94
|
+
queuedMessageIds=list(barrier.queued_message_ids),
|
|
95
|
+
inFlightMessageIds=list(barrier.in_flight_message_ids),
|
|
96
|
+
discardedMessageIds=list(barrier.discarded_message_ids),
|
|
97
|
+
settledMessageIds=list(barrier.settled_message_ids),
|
|
98
|
+
commands=[
|
|
99
|
+
GrantCommandView(
|
|
100
|
+
messageId=item.message_id,
|
|
101
|
+
commandId=item.command_id,
|
|
102
|
+
idempotencyKey=item.idempotency_key,
|
|
103
|
+
inboxState=item.inbox_state,
|
|
104
|
+
runId=item.run_id,
|
|
105
|
+
runState=item.run_state,
|
|
106
|
+
)
|
|
107
|
+
for item in barrier.commands
|
|
108
|
+
],
|
|
109
|
+
),
|
|
110
|
+
)
|
|
111
|
+
|
|
112
|
+
|
|
113
|
+
@dataclass(frozen=True)
|
|
114
|
+
class TrustedGrantWindow:
|
|
115
|
+
"""Internal input from verified Server time; never parse an untrusted body.
|
|
116
|
+
|
|
117
|
+
Capture request_started_monotonic before the Server request. Response delay
|
|
118
|
+
and any time spent waiting for a DB lock count against the authorized TTL.
|
|
119
|
+
"""
|
|
120
|
+
|
|
121
|
+
expires_at: str
|
|
122
|
+
server_time: datetime
|
|
123
|
+
request_started_monotonic: float
|
|
124
|
+
safety_margin_seconds: float = 5.0
|
|
125
|
+
# Transport-only permission from the authenticated Server response. It is
|
|
126
|
+
# deliberately outside the immutable context and never grants a clock.
|
|
127
|
+
callback_permit: Any = None
|
|
128
|
+
|
|
129
|
+
def remaining(self, monotonic: Callable[[], float] = time.monotonic) -> float:
|
|
130
|
+
if self.server_time.tzinfo is None or self.safety_margin_seconds < 0:
|
|
131
|
+
raise ValueError("a trusted UTC grant window is required")
|
|
132
|
+
elapsed = monotonic() - self.request_started_monotonic
|
|
133
|
+
ttl = (_time(self.expires_at) - self.server_time).total_seconds()
|
|
134
|
+
if elapsed < 0 or not 0 < ttl <= 30:
|
|
135
|
+
raise PermitError("invalid trusted grant time window")
|
|
136
|
+
remaining = ttl - elapsed - self.safety_margin_seconds
|
|
137
|
+
if remaining <= 0:
|
|
138
|
+
raise PermitError("trusted grant time window expired in transit")
|
|
139
|
+
return remaining
|
|
140
|
+
|
|
141
|
+
|
|
142
|
+
@dataclass(frozen=True)
|
|
143
|
+
class TrustedPreparation:
|
|
144
|
+
context: PreparedTeamsContext
|
|
145
|
+
grant_window: TrustedGrantWindow
|
|
146
|
+
|
|
147
|
+
|
|
148
|
+
@dataclass(frozen=True)
|
|
149
|
+
class HostBinding:
|
|
150
|
+
authority_id: str
|
|
151
|
+
binding_ref: str
|
|
152
|
+
provider_ref: str
|
|
153
|
+
agent_instance_id: str
|
|
154
|
+
target: dict[str, Any]
|
|
155
|
+
bundle_digest: str
|
|
156
|
+
contract_digest: str
|
|
157
|
+
|
|
158
|
+
|
|
159
|
+
class KernelTeamsExecutionHost:
|
|
160
|
+
"""Injectable service; all execution still enters AgentKernel.submit.
|
|
161
|
+
|
|
162
|
+
A cloud binding is admissible only with a shared registry/event store and
|
|
163
|
+
the actual runtime policy resolver mounted. SQLite remains a local option.
|
|
164
|
+
The capability flags are deployment evidence, not inferred from methods.
|
|
165
|
+
"""
|
|
166
|
+
|
|
167
|
+
def __init__(
|
|
168
|
+
self,
|
|
169
|
+
*,
|
|
170
|
+
kernel,
|
|
171
|
+
store,
|
|
172
|
+
events,
|
|
173
|
+
registry: TeamsExecutionContextRegistry,
|
|
174
|
+
binding: HostBinding,
|
|
175
|
+
permit_verifier: TeamsPermitVerifier,
|
|
176
|
+
context_loader: Callable[[str], Awaitable[TrustedPreparation]],
|
|
177
|
+
session_ensurer: Callable[[PreparedTeamsContext], Awaitable[Any]] | None = None,
|
|
178
|
+
policy_factory: Callable[..., Awaitable[ExecutionPolicy]] | None = None,
|
|
179
|
+
material_preparer: Callable[[PreparedTeamsContext], Awaitable[MaterialProof]] | None = None,
|
|
180
|
+
renewal_loader: Callable[[str, str], Awaitable[TrustedGrantWindow]] | None = None,
|
|
181
|
+
callback_registrar: Callable[..., Awaitable[None]] | None = None,
|
|
182
|
+
effect_journal=None,
|
|
183
|
+
effect_adapters=None,
|
|
184
|
+
loaded_build_provider=None,
|
|
185
|
+
teams_tools_ready: bool = False,
|
|
186
|
+
callback_ready: bool = False,
|
|
187
|
+
policy_enforcement_ready: bool = False,
|
|
188
|
+
canonical_events_durable: bool = False,
|
|
189
|
+
canonical_events_shared: bool = False,
|
|
190
|
+
clock: Callable[[], datetime] = lambda: datetime.now(timezone.utc),
|
|
191
|
+
monotonic: Callable[[], float] = time.monotonic,
|
|
192
|
+
):
|
|
193
|
+
if (
|
|
194
|
+
registry.kernel_store is not store
|
|
195
|
+
or kernel._store is not store
|
|
196
|
+
or kernel._events is not events
|
|
197
|
+
):
|
|
198
|
+
raise ValueError("registry and Host must use the actual Kernel store and event log")
|
|
199
|
+
self.kernel, self.store, self.events, self.registry = kernel, store, events, registry
|
|
200
|
+
self.binding, self.verifier, self.loader = binding, permit_verifier, context_loader
|
|
201
|
+
self.session_ensurer, self.policy_factory = session_ensurer, policy_factory
|
|
202
|
+
self.material_preparer = material_preparer
|
|
203
|
+
self.renewal_loader = renewal_loader
|
|
204
|
+
self.effect_journal = effect_journal
|
|
205
|
+
self.effect_adapters = dict(effect_adapters or {})
|
|
206
|
+
if loaded_build_provider is not None:
|
|
207
|
+
from ksadk.plugins.teams.build_artifacts import LoadedBuildProvider
|
|
208
|
+
|
|
209
|
+
if not isinstance(loaded_build_provider, LoadedBuildProvider):
|
|
210
|
+
raise ValueError("loaded build evidence requires a trusted filesystem verifier")
|
|
211
|
+
self.loaded_build_provider = loaded_build_provider
|
|
212
|
+
self.teams_tools_ready, self.callback_ready = teams_tools_ready, callback_ready
|
|
213
|
+
self.callback_registrar = callback_registrar
|
|
214
|
+
self.policy_enforcement_ready = policy_enforcement_ready
|
|
215
|
+
self.events_durable, self.events_shared = canonical_events_durable, canonical_events_shared
|
|
216
|
+
self.clock, self.monotonic = clock, monotonic
|
|
217
|
+
|
|
218
|
+
def capability_snapshot(self) -> dict[str, Any]:
|
|
219
|
+
native = self.kernel.capabilities()
|
|
220
|
+
policy = bool(
|
|
221
|
+
native.execution_policy
|
|
222
|
+
and native.execution_policy.supported
|
|
223
|
+
and self.policy_factory is not None
|
|
224
|
+
and self.policy_enforcement_ready
|
|
225
|
+
)
|
|
226
|
+
durable = bool(self.registry.durable and self.events_durable)
|
|
227
|
+
shared = bool(self.registry.shared_across_hosts and self.events_shared)
|
|
228
|
+
from ksadk.kernel.teams_tool_runtime import adapter_capabilities
|
|
229
|
+
|
|
230
|
+
capabilities = {
|
|
231
|
+
"teamsTools": self.teams_tools_ready and policy,
|
|
232
|
+
"callbackReady": self.callback_ready,
|
|
233
|
+
"effectLedger": self.effect_journal is not None
|
|
234
|
+
and (
|
|
235
|
+
self.binding.target.get("kind") != "cloud_agent"
|
|
236
|
+
or self.effect_journal.shared_across_hosts
|
|
237
|
+
),
|
|
238
|
+
"effectAdapters": adapter_capabilities(self.effect_adapters),
|
|
239
|
+
"protocol": TEAMS_HOST_PROTOCOL,
|
|
240
|
+
"runtime": native.model_dump(mode="json"),
|
|
241
|
+
"durableLookup": bool(self.registry.durable),
|
|
242
|
+
"canonicalResult": self.events_durable,
|
|
243
|
+
"materialPreparation": self.material_preparer is not None,
|
|
244
|
+
"executionPolicy": policy,
|
|
245
|
+
"expiringGrant": True,
|
|
246
|
+
"admissionBarrier": True,
|
|
247
|
+
"ensureSession": self.session_ensurer is not None,
|
|
248
|
+
"sharedAcrossHosts": shared,
|
|
249
|
+
"teamsReady": policy
|
|
250
|
+
and durable
|
|
251
|
+
and self.session_ensurer is not None
|
|
252
|
+
and (self.binding.target.get("kind") != "cloud_agent" or shared),
|
|
253
|
+
}
|
|
254
|
+
if self.loaded_build_provider is not None:
|
|
255
|
+
try:
|
|
256
|
+
proof = self.loaded_build_provider()
|
|
257
|
+
except (OSError, ValueError):
|
|
258
|
+
# Losing immutable-source evidence invalidates the old digest.
|
|
259
|
+
# Ordinary Teams capability stays available without standby.
|
|
260
|
+
pass
|
|
261
|
+
else:
|
|
262
|
+
capabilities["loadedBuild"] = proof.model_dump(mode="json")
|
|
263
|
+
return capabilities
|
|
264
|
+
|
|
265
|
+
@property
|
|
266
|
+
def capabilities_digest(self) -> str:
|
|
267
|
+
return digest(self.capability_snapshot())
|
|
268
|
+
|
|
269
|
+
def _binding_check(self, context: PreparedTeamsContext) -> None:
|
|
270
|
+
ref, binding = context.ref, self.binding
|
|
271
|
+
if any(
|
|
272
|
+
(
|
|
273
|
+
ref.authorityId != binding.authority_id,
|
|
274
|
+
ref.bindingRef != binding.binding_ref,
|
|
275
|
+
ref.providerRef != binding.provider_ref,
|
|
276
|
+
context.grant.agent_instance_id != binding.agent_instance_id,
|
|
277
|
+
ref.target.model_dump(mode="json") != binding.target,
|
|
278
|
+
ref.bundleDigest != binding.bundle_digest,
|
|
279
|
+
ref.contractDigest != binding.contract_digest,
|
|
280
|
+
ref.capabilitiesDigest != self.capabilities_digest,
|
|
281
|
+
)
|
|
282
|
+
):
|
|
283
|
+
raise ContextConflict("original runtime binding or capability digest mismatch")
|
|
284
|
+
|
|
285
|
+
async def describe_binding(self, *, permit: BindingProbePermit | dict) -> dict[str, Any]:
|
|
286
|
+
# Probe id is a caller nonce, not authority. All target/digest claims
|
|
287
|
+
# are compared with the host's deployment and actual runtime snapshot.
|
|
288
|
+
probe = BindingProbePermit.model_validate(permit)
|
|
289
|
+
capabilities = self.capability_snapshot()
|
|
290
|
+
self.verifier.verify(
|
|
291
|
+
probe,
|
|
292
|
+
BindingProbePermit,
|
|
293
|
+
operation="describe",
|
|
294
|
+
now=self.clock(),
|
|
295
|
+
expected={
|
|
296
|
+
"authorityId": self.binding.authority_id,
|
|
297
|
+
"probeId": probe.probeId,
|
|
298
|
+
"bindingRef": self.binding.binding_ref,
|
|
299
|
+
"target": self.binding.target,
|
|
300
|
+
"expectedDigests": {
|
|
301
|
+
"bundle": self.binding.bundle_digest,
|
|
302
|
+
"contract": self.binding.contract_digest,
|
|
303
|
+
"capabilities": digest(capabilities),
|
|
304
|
+
},
|
|
305
|
+
},
|
|
306
|
+
)
|
|
307
|
+
return {
|
|
308
|
+
"capabilities": capabilities,
|
|
309
|
+
"capabilitiesDigest": digest(capabilities),
|
|
310
|
+
"contractDigest": self.binding.contract_digest,
|
|
311
|
+
"bundleDigest": self.binding.bundle_digest,
|
|
312
|
+
"storeIncarnation": await self.registry.incarnation(),
|
|
313
|
+
}
|
|
314
|
+
|
|
315
|
+
def _verify(self, context, permit, operation, *, revision, expires_at=None):
|
|
316
|
+
ref = context.ref
|
|
317
|
+
return self.verifier.verify(
|
|
318
|
+
permit,
|
|
319
|
+
TeamsExecutionPermit,
|
|
320
|
+
operation=operation,
|
|
321
|
+
now=self.clock(),
|
|
322
|
+
grant_expires_at=_time(expires_at) if expires_at else None,
|
|
323
|
+
expected={
|
|
324
|
+
"authorityId": ref.authorityId,
|
|
325
|
+
"subjectRef": context.owner_subject,
|
|
326
|
+
"agentInstanceId": context.grant.agent_instance_id,
|
|
327
|
+
"sessionId": ref.sessionId,
|
|
328
|
+
"commandId": ref.commandId,
|
|
329
|
+
"payloadDigest": context.payload_digest,
|
|
330
|
+
"policyDigest": context.policy_digest,
|
|
331
|
+
"attemptEpoch": ref.attemptEpoch,
|
|
332
|
+
"leaderEpoch": ref.leaderEpoch,
|
|
333
|
+
"dispatchEpoch": ref.dispatchEpoch,
|
|
334
|
+
"grantRevision": revision,
|
|
335
|
+
},
|
|
336
|
+
)
|
|
337
|
+
|
|
338
|
+
async def _context(self, context_ref: str, expected_incarnation: str) -> PreparedTeamsContext:
|
|
339
|
+
context = await self.registry.get(context_ref, expected_incarnation=expected_incarnation)
|
|
340
|
+
if context is None:
|
|
341
|
+
# Absence of trusted context is not proof that an old execution is missing.
|
|
342
|
+
raise StoreIdentityMismatch("original prepared context unavailable")
|
|
343
|
+
self._binding_check(context)
|
|
344
|
+
return context
|
|
345
|
+
|
|
346
|
+
async def _authorized(self, context_ref, expected_incarnation, permit, operation):
|
|
347
|
+
context = await self._context(context_ref, expected_incarnation)
|
|
348
|
+
barrier = await self.kernel.get_execution_grant(context.grant)
|
|
349
|
+
parsed = TeamsExecutionPermit.model_validate(permit)
|
|
350
|
+
if barrier is None and parsed.permitKind == "execute":
|
|
351
|
+
raise ContextConflict("prepared execution grant unavailable")
|
|
352
|
+
# Recovery's signed grantRevision is the Server's observation, not a
|
|
353
|
+
# current execution fence. Lost renewal ACKs make the current revision
|
|
354
|
+
# unknown to the caller. Recovery still verifies every immutable scope
|
|
355
|
+
# claim and cannot enqueue, approve, renew or reactivate the grant.
|
|
356
|
+
revision = (
|
|
357
|
+
parsed.grantRevision if parsed.permitKind == "recovery" else barrier.grant.revision
|
|
358
|
+
)
|
|
359
|
+
verified = self._verify(
|
|
360
|
+
context,
|
|
361
|
+
parsed,
|
|
362
|
+
operation,
|
|
363
|
+
revision=revision,
|
|
364
|
+
expires_at=barrier.grant.expires_at if barrier else None,
|
|
365
|
+
)
|
|
366
|
+
if verified.permitKind == "execute" and operation != "renew_grant":
|
|
367
|
+
await self.kernel.require_execution_grant(context.grant)
|
|
368
|
+
# A fresh authorized renewal may restore a missing restart clock anchor;
|
|
369
|
+
# the Kernel still rejects an elapsed/revoked grant and CAS conflicts.
|
|
370
|
+
return context, barrier
|
|
371
|
+
|
|
372
|
+
async def prepare_execution(self, *, context_ref, expected_incarnation, permit):
|
|
373
|
+
if not self.capability_snapshot()["teamsReady"]:
|
|
374
|
+
raise ContextConflict("runtime Teams enforcement is not ready")
|
|
375
|
+
preparation = await self.loader(context_ref)
|
|
376
|
+
context = PreparedTeamsContext.model_validate_json(preparation.context.model_dump_json())
|
|
377
|
+
if context.context_ref != context_ref:
|
|
378
|
+
raise ContextConflict("trusted loader returned a different context")
|
|
379
|
+
self._binding_check(context)
|
|
380
|
+
existing = await self.kernel.get_execution_grant(context.grant)
|
|
381
|
+
revision = existing.grant.revision if existing else 1
|
|
382
|
+
expires_at = existing.grant.expires_at if existing else preparation.grant_window.expires_at
|
|
383
|
+
self._verify(context, permit, "prepare", revision=revision, expires_at=expires_at)
|
|
384
|
+
preparation.grant_window.remaining(self.monotonic)
|
|
385
|
+
await self.registry.put(context, expected_incarnation=expected_incarnation)
|
|
386
|
+
await self._ensure_owned_session(context)
|
|
387
|
+
if context.material_manifest_ref is not None:
|
|
388
|
+
if self.material_preparer is None:
|
|
389
|
+
raise ContextConflict("trusted material verification is not configured")
|
|
390
|
+
proof = MaterialProof.model_validate(await self.material_preparer(context))
|
|
391
|
+
if (
|
|
392
|
+
proof.manifestRef != context.material_manifest_ref
|
|
393
|
+
or proof.digest != context.material_manifest_digest
|
|
394
|
+
):
|
|
395
|
+
raise ContextConflict("material proof differs from frozen manifest")
|
|
396
|
+
await self.kernel.ensure_execution_grant(
|
|
397
|
+
context.grant,
|
|
398
|
+
expires_at=preparation.grant_window.expires_at,
|
|
399
|
+
remaining_ttl_seconds=preparation.grant_window.remaining(self.monotonic),
|
|
400
|
+
)
|
|
401
|
+
# Replayed prepare cannot revive a process-local monotonic deadline.
|
|
402
|
+
await self.kernel.require_execution_grant(context.grant)
|
|
403
|
+
barrier = await self.kernel.get_execution_grant(context.grant)
|
|
404
|
+
if self.callback_registrar is not None:
|
|
405
|
+
await self.callback_registrar(context, preparation.grant_window, barrier)
|
|
406
|
+
return PrepareResult(
|
|
407
|
+
operation="prepare",
|
|
408
|
+
contextRef=context_ref,
|
|
409
|
+
contextDigest=context.context_digest,
|
|
410
|
+
snapshot=grant_snapshot(barrier, expected_incarnation),
|
|
411
|
+
)
|
|
412
|
+
|
|
413
|
+
async def ensure_session(self, *, context_ref, expected_incarnation, permit):
|
|
414
|
+
# Separate operation, using the same trusted reservation as prepare.
|
|
415
|
+
if self.session_ensurer is None:
|
|
416
|
+
raise ContextConflict("trusted session creation is not configured")
|
|
417
|
+
preparation = await self.loader(context_ref)
|
|
418
|
+
context = preparation.context
|
|
419
|
+
if context.context_ref != context_ref:
|
|
420
|
+
raise ContextConflict("trusted loader returned a different context")
|
|
421
|
+
self._binding_check(context)
|
|
422
|
+
existing = await self.kernel.get_execution_grant(context.grant)
|
|
423
|
+
self._verify(
|
|
424
|
+
context,
|
|
425
|
+
permit,
|
|
426
|
+
"ensure_session",
|
|
427
|
+
revision=existing.grant.revision if existing else 1,
|
|
428
|
+
expires_at=existing.grant.expires_at
|
|
429
|
+
if existing
|
|
430
|
+
else preparation.grant_window.expires_at,
|
|
431
|
+
)
|
|
432
|
+
if existing:
|
|
433
|
+
await self.kernel.require_execution_grant(context.grant)
|
|
434
|
+
preparation.grant_window.remaining(self.monotonic)
|
|
435
|
+
await self.registry.put(context, expected_incarnation=expected_incarnation)
|
|
436
|
+
await self._ensure_owned_session(context)
|
|
437
|
+
return {"sessionId": context.ref.sessionId, "storeIncarnation": expected_incarnation}
|
|
438
|
+
|
|
439
|
+
async def _ensure_owned_session(self, context):
|
|
440
|
+
session = await self.session_ensurer(context)
|
|
441
|
+
if (
|
|
442
|
+
getattr(session, "id", None) != context.ref.sessionId
|
|
443
|
+
or getattr(session, "user_id", None) != context.owner_subject
|
|
444
|
+
or getattr(session, "agent_id", None) != context.grant.agent_instance_id
|
|
445
|
+
):
|
|
446
|
+
raise ContextConflict("session owner or instance differs from trusted preparation")
|
|
447
|
+
|
|
448
|
+
async def validate_enqueue(self, command, *, expected_incarnation, permit):
|
|
449
|
+
command = AgentControlCommand.model_validate(command)
|
|
450
|
+
context, _ = await self._authorized(
|
|
451
|
+
command.payload.get("teams_context_ref"), expected_incarnation, permit, "enqueue"
|
|
452
|
+
)
|
|
453
|
+
if str(command.command_id) != context.ref.commandId or command_digest(
|
|
454
|
+
command
|
|
455
|
+
) != command_digest(context.command):
|
|
456
|
+
raise ContextConflict("enqueue must preserve the original prepared command")
|
|
457
|
+
return command
|
|
458
|
+
|
|
459
|
+
async def lookup_before_submit(self, command, *, expected_incarnation, permit):
|
|
460
|
+
"""Read only the signed enqueue's original inbox before attempting admission.
|
|
461
|
+
|
|
462
|
+
This internal submit step deliberately does not rebuild/require a local
|
|
463
|
+
clock anchor: after restart an already accepted command remains readable.
|
|
464
|
+
A missing receipt never authorizes execution; submit_execution still
|
|
465
|
+
performs the full live grant check and native permit verification.
|
|
466
|
+
"""
|
|
467
|
+
command = AgentControlCommand.model_validate(command)
|
|
468
|
+
context = await self._context(
|
|
469
|
+
command.payload.get("teams_context_ref"), expected_incarnation
|
|
470
|
+
)
|
|
471
|
+
barrier = await self.kernel.get_execution_grant(context.grant)
|
|
472
|
+
if barrier is None:
|
|
473
|
+
raise ContextConflict("prepared execution grant unavailable")
|
|
474
|
+
self._verify(
|
|
475
|
+
context,
|
|
476
|
+
permit,
|
|
477
|
+
"enqueue",
|
|
478
|
+
revision=barrier.grant.revision,
|
|
479
|
+
expires_at=barrier.grant.expires_at,
|
|
480
|
+
)
|
|
481
|
+
if str(command.command_id) != context.ref.commandId or command_digest(
|
|
482
|
+
command
|
|
483
|
+
) != command_digest(context.command):
|
|
484
|
+
raise ContextConflict("enqueue must preserve the original prepared command")
|
|
485
|
+
return await self._lookup(context, expected_incarnation)
|
|
486
|
+
|
|
487
|
+
async def validate_native_authorization(
|
|
488
|
+
self, native_permit, *, context_ref, expected_incarnation
|
|
489
|
+
):
|
|
490
|
+
"""The two independently signed permits must name the same owner/session.
|
|
491
|
+
|
|
492
|
+
The native Kernel still verifies signature, lifetime, nonce and allowed
|
|
493
|
+
operation. Instance-wide permits cannot be combined with a Teams permit
|
|
494
|
+
issued for a different principal or session.
|
|
495
|
+
"""
|
|
496
|
+
context = await self._context(context_ref, expected_incarnation)
|
|
497
|
+
native_permit = AgentControlPermit.model_validate(native_permit)
|
|
498
|
+
if (
|
|
499
|
+
native_permit.subject_ref != context.owner_subject
|
|
500
|
+
or native_permit.session_id != context.ref.sessionId
|
|
501
|
+
or native_permit.tenant_id != context.grant.tenant_id
|
|
502
|
+
or native_permit.agent_instance_id != context.grant.agent_instance_id
|
|
503
|
+
):
|
|
504
|
+
raise PermitError("native and Teams permit scopes differ")
|
|
505
|
+
return native_permit
|
|
506
|
+
|
|
507
|
+
async def submit_execution(
|
|
508
|
+
self, command, *, expected_incarnation, permit, native_permit: AgentControlPermit
|
|
509
|
+
):
|
|
510
|
+
command = await self.validate_enqueue(
|
|
511
|
+
command, expected_incarnation=expected_incarnation, permit=permit
|
|
512
|
+
)
|
|
513
|
+
native_permit = await self.validate_native_authorization(
|
|
514
|
+
native_permit,
|
|
515
|
+
context_ref=command.payload["teams_context_ref"],
|
|
516
|
+
expected_incarnation=expected_incarnation,
|
|
517
|
+
)
|
|
518
|
+
# Native permit verification, inbox idempotency and worker claim are unchanged.
|
|
519
|
+
return await self.kernel.submit(command, permit=native_permit)
|
|
520
|
+
|
|
521
|
+
async def lookup_execution(
|
|
522
|
+
self,
|
|
523
|
+
*,
|
|
524
|
+
context_ref,
|
|
525
|
+
expected_incarnation,
|
|
526
|
+
permit,
|
|
527
|
+
command_id,
|
|
528
|
+
idempotency_key,
|
|
529
|
+
payload_digest,
|
|
530
|
+
):
|
|
531
|
+
context, _ = await self._authorized(context_ref, expected_incarnation, permit, "lookup")
|
|
532
|
+
if (command_id, idempotency_key, payload_digest) != (
|
|
533
|
+
context.ref.commandId,
|
|
534
|
+
context.ref.idempotencyKey,
|
|
535
|
+
context.payload_digest,
|
|
536
|
+
):
|
|
537
|
+
raise ContextConflict("lookup must use the original command, key and digest")
|
|
538
|
+
return await self._lookup(context, expected_incarnation)
|
|
539
|
+
|
|
540
|
+
async def _lookup(self, context, incarnation):
|
|
541
|
+
message = await self.store.load_by_idempotency(
|
|
542
|
+
context.ref.sessionId, context.ref.idempotencyKey
|
|
543
|
+
)
|
|
544
|
+
if await self.registry.incarnation() != incarnation:
|
|
545
|
+
raise StoreIdentityMismatch("Kernel store identity changed during lookup")
|
|
546
|
+
values = {
|
|
547
|
+
"commandId": context.ref.commandId,
|
|
548
|
+
"idempotencyKey": context.ref.idempotencyKey,
|
|
549
|
+
"payloadDigest": context.payload_digest,
|
|
550
|
+
"storeIncarnation": incarnation,
|
|
551
|
+
}
|
|
552
|
+
if message is None:
|
|
553
|
+
return HostReceipt(status="missing", **values)
|
|
554
|
+
if (
|
|
555
|
+
message.command is None
|
|
556
|
+
or message.agent_instance_id != context.grant.agent_instance_id
|
|
557
|
+
or str(message.command.command_id) != context.ref.commandId
|
|
558
|
+
or "sha256:" + message.request_digest != context.payload_digest
|
|
559
|
+
):
|
|
560
|
+
raise ContextConflict("original inbox identity or payload differs")
|
|
561
|
+
run_id = execution_grant_run_id(context.command)
|
|
562
|
+
run = await self.store.load_run(run_id)
|
|
563
|
+
if run is not None and (
|
|
564
|
+
run.session_id != context.ref.sessionId
|
|
565
|
+
or run.agent_instance_id != context.grant.agent_instance_id
|
|
566
|
+
):
|
|
567
|
+
raise ContextConflict("original run scope differs")
|
|
568
|
+
return HostReceipt(
|
|
569
|
+
status="accepted",
|
|
570
|
+
runId=run_id,
|
|
571
|
+
acceptedSeq=message.accepted_seq,
|
|
572
|
+
nativeStatus=_RUN_STATUS.get(str(run.state)) if run else "queued",
|
|
573
|
+
**values,
|
|
574
|
+
)
|
|
575
|
+
|
|
576
|
+
async def lookup_control(self, *, context_ref, expected_incarnation, permit, command):
|
|
577
|
+
"""Read the original control inbox without resubmitting or claiming it.
|
|
578
|
+
|
|
579
|
+
The context permit proves the original execution. The independent
|
|
580
|
+
command/key/digest identify the control within its exact session/run.
|
|
581
|
+
An inbox ACK carries no terminal result or authority to execute again.
|
|
582
|
+
"""
|
|
583
|
+
context, _ = await self._authorized(context_ref, expected_incarnation, permit, "lookup")
|
|
584
|
+
command = AgentControlCommand.model_validate(command)
|
|
585
|
+
run_id = execution_grant_run_id(context.command)
|
|
586
|
+
if (
|
|
587
|
+
command.command_type not in {"interrupt", "submit_interaction"}
|
|
588
|
+
or command.tenant_id != context.grant.tenant_id
|
|
589
|
+
or command.agent_instance_id != context.grant.agent_instance_id
|
|
590
|
+
or command.session_id != context.ref.sessionId
|
|
591
|
+
or command.payload.get("run_id") != run_id
|
|
592
|
+
or str(command.command_id) == context.ref.commandId
|
|
593
|
+
or command.idempotency_key == context.ref.idempotencyKey
|
|
594
|
+
):
|
|
595
|
+
raise ContextConflict("control lookup must target the exact original execution")
|
|
596
|
+
run = await self.store.load_run(run_id)
|
|
597
|
+
if (
|
|
598
|
+
run is None
|
|
599
|
+
or run.session_id != context.ref.sessionId
|
|
600
|
+
or run.agent_instance_id != context.grant.agent_instance_id
|
|
601
|
+
or run.metadata.get("command_id") != context.ref.commandId
|
|
602
|
+
):
|
|
603
|
+
raise ContextConflict("control lookup original run is unavailable")
|
|
604
|
+
message = await self.store.load_by_idempotency(
|
|
605
|
+
context.ref.sessionId, command.idempotency_key
|
|
606
|
+
)
|
|
607
|
+
if await self.registry.incarnation() != expected_incarnation:
|
|
608
|
+
raise StoreIdentityMismatch("Kernel store identity changed during control lookup")
|
|
609
|
+
fingerprint = command_digest(command)
|
|
610
|
+
values = dict(
|
|
611
|
+
commandId=str(command.command_id),
|
|
612
|
+
idempotencyKey=command.idempotency_key,
|
|
613
|
+
payloadDigest="sha256:" + fingerprint,
|
|
614
|
+
storeIncarnation=expected_incarnation,
|
|
615
|
+
)
|
|
616
|
+
if message is None:
|
|
617
|
+
return HostReceipt(status="missing", **values)
|
|
618
|
+
if (
|
|
619
|
+
message.command is None
|
|
620
|
+
or message.agent_instance_id != command.agent_instance_id
|
|
621
|
+
or message.session_id != command.session_id
|
|
622
|
+
or str(message.command.command_id) != str(command.command_id)
|
|
623
|
+
or message.request_digest != fingerprint
|
|
624
|
+
or command_digest(message.command) != fingerprint
|
|
625
|
+
):
|
|
626
|
+
raise ContextConflict("original control inbox identity or payload differs")
|
|
627
|
+
return HostReceipt(
|
|
628
|
+
status="accepted", runId=run_id, acceptedSeq=message.accepted_seq, **values
|
|
629
|
+
)
|
|
630
|
+
|
|
631
|
+
async def get_execution_grant(
|
|
632
|
+
self, *, context_ref, expected_incarnation, permit, renewal_id=None
|
|
633
|
+
):
|
|
634
|
+
context, barrier = await self._authorized(
|
|
635
|
+
context_ref, expected_incarnation, permit, "get_grant"
|
|
636
|
+
)
|
|
637
|
+
receipt = None
|
|
638
|
+
if renewal_id is not None:
|
|
639
|
+
receipt = await self.kernel.lookup_execution_grant_operation(
|
|
640
|
+
context.grant, idempotency_key=renewal_id
|
|
641
|
+
)
|
|
642
|
+
return GetGrantResult(
|
|
643
|
+
operation="get_grant",
|
|
644
|
+
storeIncarnation=expected_incarnation,
|
|
645
|
+
current=grant_snapshot(barrier, expected_incarnation) if barrier else None,
|
|
646
|
+
lookupOperationId=renewal_id,
|
|
647
|
+
mutationReceipt=GrantMutationReceipt(
|
|
648
|
+
operationId=renewal_id, snapshot=grant_snapshot(receipt, expected_incarnation)
|
|
649
|
+
)
|
|
650
|
+
if receipt
|
|
651
|
+
else None,
|
|
652
|
+
)
|
|
653
|
+
|
|
654
|
+
async def renew_execution_grant(
|
|
655
|
+
self,
|
|
656
|
+
*,
|
|
657
|
+
context_ref,
|
|
658
|
+
expected_incarnation,
|
|
659
|
+
permit,
|
|
660
|
+
expected_revision,
|
|
661
|
+
renewal_id,
|
|
662
|
+
trusted_window: TrustedGrantWindow,
|
|
663
|
+
):
|
|
664
|
+
context, _ = await self._authorized(
|
|
665
|
+
context_ref, expected_incarnation, permit, "renew_grant"
|
|
666
|
+
)
|
|
667
|
+
barrier = await self.kernel.renew_execution_grant(
|
|
668
|
+
context.grant,
|
|
669
|
+
expected_revision=expected_revision,
|
|
670
|
+
renewal_id=renewal_id,
|
|
671
|
+
expires_at=trusted_window.expires_at,
|
|
672
|
+
remaining_ttl_seconds=trusted_window.remaining(self.monotonic),
|
|
673
|
+
)
|
|
674
|
+
if self.callback_registrar is not None:
|
|
675
|
+
await self.callback_registrar(context, trusted_window, barrier)
|
|
676
|
+
return SetGrantResult(
|
|
677
|
+
operation="set_grant",
|
|
678
|
+
mutationReceipt=GrantMutationReceipt(
|
|
679
|
+
operationId=renewal_id, snapshot=grant_snapshot(barrier, expected_incarnation)
|
|
680
|
+
),
|
|
681
|
+
)
|
|
682
|
+
|
|
683
|
+
async def set_execution_grant(
|
|
684
|
+
self, *, context_ref, expected_incarnation, permit, state, expected_revision, control_id
|
|
685
|
+
):
|
|
686
|
+
operation = "revoke" if state == "revoked" else "set_grant"
|
|
687
|
+
context, _ = await self._authorized(context_ref, expected_incarnation, permit, operation)
|
|
688
|
+
barrier = await self.kernel.set_execution_grant_state(
|
|
689
|
+
context.grant, state, expected_revision=expected_revision, idempotency_key=control_id
|
|
690
|
+
)
|
|
691
|
+
return SetGrantResult(
|
|
692
|
+
operation="set_grant",
|
|
693
|
+
mutationReceipt=GrantMutationReceipt(
|
|
694
|
+
operationId=control_id, snapshot=grant_snapshot(barrier, expected_incarnation)
|
|
695
|
+
),
|
|
696
|
+
)
|
|
697
|
+
|
|
698
|
+
async def set_execution_admission(
|
|
699
|
+
self, *, context_ref, expected_incarnation, permit, allowed, expected_revision, control_id
|
|
700
|
+
):
|
|
701
|
+
context, _ = await self._authorized(
|
|
702
|
+
context_ref, expected_incarnation, permit, "set_admission"
|
|
703
|
+
)
|
|
704
|
+
barrier = await self.kernel.set_execution_admission(
|
|
705
|
+
context.grant, allowed, expected_revision=expected_revision, idempotency_key=control_id
|
|
706
|
+
)
|
|
707
|
+
return SetAdmissionResult(
|
|
708
|
+
operation="set_admission",
|
|
709
|
+
mutationReceipt=GrantMutationReceipt(
|
|
710
|
+
operationId=control_id, snapshot=grant_snapshot(barrier, expected_incarnation)
|
|
711
|
+
),
|
|
712
|
+
)
|
|
713
|
+
|
|
714
|
+
async def validate_native_control(self, command, *, context_ref, expected_incarnation, permit):
|
|
715
|
+
"""Submit exact interrupt/interaction through the original Kernel path.
|
|
716
|
+
|
|
717
|
+
The trusted caller supplies the original stable control command and its
|
|
718
|
+
independent native permit. A cancel acknowledgement is never a terminal.
|
|
719
|
+
"""
|
|
720
|
+
command = AgentControlCommand.model_validate(command)
|
|
721
|
+
operation = {"interrupt": "cancel", "submit_interaction": "respond_interaction"}.get(
|
|
722
|
+
command.command_type
|
|
723
|
+
)
|
|
724
|
+
if operation is None:
|
|
725
|
+
raise ContextConflict("unsupported Teams native control")
|
|
726
|
+
context, _ = await self._authorized(context_ref, expected_incarnation, permit, operation)
|
|
727
|
+
run_id = execution_grant_run_id(context.command)
|
|
728
|
+
if (
|
|
729
|
+
command.tenant_id != context.grant.tenant_id
|
|
730
|
+
or command.agent_instance_id != context.grant.agent_instance_id
|
|
731
|
+
or command.session_id != context.ref.sessionId
|
|
732
|
+
or command.payload.get("run_id") != run_id
|
|
733
|
+
or str(command.command_id) == context.ref.commandId
|
|
734
|
+
or command.idempotency_key == context.ref.idempotencyKey
|
|
735
|
+
):
|
|
736
|
+
raise ContextConflict("native control must target the exact original execution")
|
|
737
|
+
run = await self.store.load_run(run_id)
|
|
738
|
+
if (
|
|
739
|
+
run is None
|
|
740
|
+
or run.agent_instance_id != context.grant.agent_instance_id
|
|
741
|
+
or run.session_id != context.ref.sessionId
|
|
742
|
+
or run.metadata.get("command_id") != context.ref.commandId
|
|
743
|
+
):
|
|
744
|
+
raise ContextConflict("native control original run is unavailable")
|
|
745
|
+
if operation == "respond_interaction":
|
|
746
|
+
interaction = await self.store.get(
|
|
747
|
+
command.payload["interaction_id"],
|
|
748
|
+
tenant_id=context.grant.tenant_id,
|
|
749
|
+
agent_instance_id=context.grant.agent_instance_id,
|
|
750
|
+
session_id=context.ref.sessionId,
|
|
751
|
+
run_id=run_id,
|
|
752
|
+
)
|
|
753
|
+
if interaction is None:
|
|
754
|
+
raise ContextConflict("interaction does not belong to the original execution")
|
|
755
|
+
return command
|
|
756
|
+
|
|
757
|
+
async def submit_native_control(
|
|
758
|
+
self, command, *, context_ref, expected_incarnation, permit, native_permit
|
|
759
|
+
):
|
|
760
|
+
command = await self.validate_native_control(
|
|
761
|
+
command,
|
|
762
|
+
context_ref=context_ref,
|
|
763
|
+
expected_incarnation=expected_incarnation,
|
|
764
|
+
permit=permit,
|
|
765
|
+
)
|
|
766
|
+
run_id = command.payload["run_id"]
|
|
767
|
+
native_permit = await self.validate_native_authorization(
|
|
768
|
+
native_permit,
|
|
769
|
+
context_ref=context_ref,
|
|
770
|
+
expected_incarnation=expected_incarnation,
|
|
771
|
+
)
|
|
772
|
+
receipt = await self.kernel.submit(
|
|
773
|
+
command, permit=AgentControlPermit.model_validate(native_permit)
|
|
774
|
+
)
|
|
775
|
+
status = (
|
|
776
|
+
receipt.status
|
|
777
|
+
if receipt.status in {"accepted", "duplicate", "rejected"}
|
|
778
|
+
else "uncertain"
|
|
779
|
+
)
|
|
780
|
+
return HostReceipt(
|
|
781
|
+
status=status,
|
|
782
|
+
commandId=str(command.command_id),
|
|
783
|
+
idempotencyKey=command.idempotency_key,
|
|
784
|
+
payloadDigest="sha256:" + command_digest(command),
|
|
785
|
+
storeIncarnation=expected_incarnation,
|
|
786
|
+
acceptedSeq=receipt.accepted_seq,
|
|
787
|
+
runId=run_id if status in {"accepted", "duplicate"} else None,
|
|
788
|
+
)
|
|
789
|
+
|
|
790
|
+
async def resolve(self, ref: str, *, request) -> ExecutionPolicy:
|
|
791
|
+
"""Mount this resolver explicitly in the ManagedRuntime bootstrap.
|
|
792
|
+
|
|
793
|
+
policy_factory must also wrap effectful tools with require_live_context;
|
|
794
|
+
resolver invocation alone is not per-tool authorization.
|
|
795
|
+
"""
|
|
796
|
+
if not self.capability_snapshot()["executionPolicy"]:
|
|
797
|
+
raise ContextConflict("runtime policy enforcement is not mounted")
|
|
798
|
+
context = await self.require_live_context(
|
|
799
|
+
request.metadata.get("teams_context_ref"), request=request
|
|
800
|
+
)
|
|
801
|
+
if ref != context.policy_ref:
|
|
802
|
+
raise ContextConflict("execution policy reference mismatch")
|
|
803
|
+
policy = await self.policy_factory(context, request=request)
|
|
804
|
+
if not isinstance(policy, ExecutionPolicy):
|
|
805
|
+
raise TypeError("trusted policy factory must return ExecutionPolicy")
|
|
806
|
+
return policy
|
|
807
|
+
|
|
808
|
+
async def require_live_context(self, context_ref, *, request):
|
|
809
|
+
context = await self._context(context_ref, await self.registry.incarnation())
|
|
810
|
+
metadata = request.metadata
|
|
811
|
+
if (
|
|
812
|
+
request.session_id != context.ref.sessionId
|
|
813
|
+
or request.user_id != context.owner_subject
|
|
814
|
+
or metadata.get("command_id") != context.ref.commandId
|
|
815
|
+
or metadata.get("run_id") != execution_grant_run_id(context.command)
|
|
816
|
+
or metadata.get("execution_policy_ref") != context.policy_ref
|
|
817
|
+
):
|
|
818
|
+
raise ContextConflict("runtime invocation does not match prepared execution")
|
|
819
|
+
await self.kernel.require_execution_grant(context.grant)
|
|
820
|
+
return context
|
|
821
|
+
|
|
822
|
+
async def observe_execution(
|
|
823
|
+
self,
|
|
824
|
+
*,
|
|
825
|
+
context_ref,
|
|
826
|
+
expected_incarnation,
|
|
827
|
+
permit,
|
|
828
|
+
after_seq=0,
|
|
829
|
+
limit=200,
|
|
830
|
+
snapshot_upper_seq=None,
|
|
831
|
+
):
|
|
832
|
+
"""Page original canonical facts with a fixed session scan watermark.
|
|
833
|
+
|
|
834
|
+
Child ancestry comes only from canonical source metadata. Unrelated
|
|
835
|
+
runs consume cursor positions but are never disclosed. A bounded scan
|
|
836
|
+
fails closed rather than pretending a partial scan is the final page.
|
|
837
|
+
"""
|
|
838
|
+
if not 0 <= after_seq or not 1 <= limit <= 200:
|
|
839
|
+
raise ContextConflict("invalid canonical event cursor")
|
|
840
|
+
context, _ = await self._authorized(context_ref, expected_incarnation, permit, "observe")
|
|
841
|
+
receipt = await self._lookup(context, expected_incarnation)
|
|
842
|
+
if receipt.status != "accepted":
|
|
843
|
+
raise ContextConflict("original execution has no accepted canonical identity")
|
|
844
|
+
rows, cursor = [], 0
|
|
845
|
+
while len(rows) < 10000:
|
|
846
|
+
page = await self.events.read(context.ref.sessionId, cursor, 200)
|
|
847
|
+
if not page:
|
|
848
|
+
break
|
|
849
|
+
for envelope in page:
|
|
850
|
+
if envelope.seq <= cursor:
|
|
851
|
+
raise ContextConflict("canonical event cursor did not advance")
|
|
852
|
+
cursor = envelope.seq
|
|
853
|
+
rows.append(envelope)
|
|
854
|
+
if snapshot_upper_seq is not None and cursor >= snapshot_upper_seq:
|
|
855
|
+
break
|
|
856
|
+
else:
|
|
857
|
+
raise ContextConflict("canonical snapshot scan budget exceeded")
|
|
858
|
+
upper = cursor if snapshot_upper_seq is None else snapshot_upper_seq
|
|
859
|
+
if not after_seq <= upper <= cursor:
|
|
860
|
+
raise ContextConflict("canonical snapshot watermark is unavailable")
|
|
861
|
+
authorized_runs = {receipt.runId}
|
|
862
|
+
# Native children may publish before the parent annotation is seen.
|
|
863
|
+
changed = True
|
|
864
|
+
while changed:
|
|
865
|
+
changed = False
|
|
866
|
+
for row in rows:
|
|
867
|
+
if row.seq > upper or row.family != "runtime" or row.family_version != 2:
|
|
868
|
+
continue
|
|
869
|
+
event = parse_runtime_event(row.payload)
|
|
870
|
+
parent = event.source.metadata.get("parent_run_id")
|
|
871
|
+
if parent in authorized_runs and event.run_id not in authorized_runs:
|
|
872
|
+
authorized_runs.add(event.run_id)
|
|
873
|
+
changed = True
|
|
874
|
+
scanned = [row for row in rows if after_seq < row.seq <= upper][:limit]
|
|
875
|
+
next_seq = scanned[-1].seq if scanned else upper
|
|
876
|
+
items = []
|
|
877
|
+
for row in scanned:
|
|
878
|
+
if row.run_id not in authorized_runs:
|
|
879
|
+
continue
|
|
880
|
+
metadata = {}
|
|
881
|
+
if row.family == "runtime" and row.family_version == 2:
|
|
882
|
+
event = parse_runtime_event(row.payload)
|
|
883
|
+
if event.run_id != row.run_id or event.seq != row.seq:
|
|
884
|
+
raise ContextConflict("canonical event identity mismatch")
|
|
885
|
+
metadata = event.source.metadata
|
|
886
|
+
item = CanonicalExecutionEvent(
|
|
887
|
+
eventId=str(row.event_id),
|
|
888
|
+
sessionId=row.session_id,
|
|
889
|
+
runId=row.run_id,
|
|
890
|
+
seq=row.seq,
|
|
891
|
+
family=row.family,
|
|
892
|
+
type=row.event_type,
|
|
893
|
+
payload=row.payload,
|
|
894
|
+
sourceRef=EventSourceRef(
|
|
895
|
+
nativeRunId=row.run_id,
|
|
896
|
+
parentRunId=metadata.get("parent_run_id"),
|
|
897
|
+
nativeEventType=metadata.get("native_event_type") or row.event_type,
|
|
898
|
+
),
|
|
899
|
+
)
|
|
900
|
+
items.append(item)
|
|
901
|
+
if await self.registry.incarnation() != expected_incarnation:
|
|
902
|
+
raise StoreIdentityMismatch("Kernel store identity changed during event read")
|
|
903
|
+
return CanonicalEventBatch(
|
|
904
|
+
sessionId=context.ref.sessionId,
|
|
905
|
+
storeIncarnation=expected_incarnation,
|
|
906
|
+
afterSeq=after_seq,
|
|
907
|
+
nextSeq=next_seq,
|
|
908
|
+
snapshotUpperSeq=upper,
|
|
909
|
+
hasMore=next_seq < upper,
|
|
910
|
+
items=items,
|
|
911
|
+
)
|
|
912
|
+
|
|
913
|
+
async def get_execution_effects(
|
|
914
|
+
self, *, context_ref, expected_incarnation, permit, after="", limit=100
|
|
915
|
+
):
|
|
916
|
+
"""Read original durable evidence with recovery authority; never execute."""
|
|
917
|
+
from ksadk.kernel.teams_tool_runtime import ExecutionEffectsPage
|
|
918
|
+
|
|
919
|
+
parsed = TeamsExecutionPermit.model_validate(permit)
|
|
920
|
+
if parsed.permitKind != "recovery":
|
|
921
|
+
raise PermitError("effect recovery requires a read-only recovery permission")
|
|
922
|
+
context, _ = await self._authorized(context_ref, expected_incarnation, parsed, "observe")
|
|
923
|
+
journal = self.effect_journal
|
|
924
|
+
if journal is None or journal.store_incarnation != expected_incarnation:
|
|
925
|
+
raise StoreIdentityMismatch("original effect journal unavailable")
|
|
926
|
+
receipt = await self._lookup(context, expected_incarnation)
|
|
927
|
+
run = await self.store.load_run(receipt.runId) if receipt.runId else None
|
|
928
|
+
if receipt.status != "accepted" or run is None:
|
|
929
|
+
raise ContextConflict("original native Run unavailable for effects")
|
|
930
|
+
rows = await journal.for_execution(context_ref, receipt.runId, after=after, limit=limit)
|
|
931
|
+
for row in rows:
|
|
932
|
+
expected = context.ref.model_dump(mode="json")
|
|
933
|
+
actual = row.request.ref.model_dump(mode="json")
|
|
934
|
+
for value in (expected, actual):
|
|
935
|
+
value.pop("schedulerEpoch")
|
|
936
|
+
value["nativeRunId"] = receipt.runId
|
|
937
|
+
if (
|
|
938
|
+
expected != actual
|
|
939
|
+
or row.request.store_incarnation != expected_incarnation
|
|
940
|
+
or row.request.journal_incarnation != journal.journal_incarnation
|
|
941
|
+
):
|
|
942
|
+
raise ContextConflict("effect history scope mismatch")
|
|
943
|
+
if await self.registry.incarnation() != expected_incarnation:
|
|
944
|
+
raise StoreIdentityMismatch("original store changed while reading effects")
|
|
945
|
+
return ExecutionEffectsPage(
|
|
946
|
+
contextRef=context_ref,
|
|
947
|
+
storeIncarnation=expected_incarnation,
|
|
948
|
+
nativeRunId=receipt.runId,
|
|
949
|
+
journalIncarnation=journal.journal_incarnation,
|
|
950
|
+
items=rows,
|
|
951
|
+
nextCursor=f"{rows[-1].request.effect_key}:{rows[-1].revision}"
|
|
952
|
+
if len(rows) == limit
|
|
953
|
+
else None,
|
|
954
|
+
)
|
|
955
|
+
|
|
956
|
+
async def get_execution_result(self, *, context_ref, expected_incarnation, permit):
|
|
957
|
+
context, _ = await self._authorized(context_ref, expected_incarnation, permit, "get_result")
|
|
958
|
+
receipt = await self._lookup(context, expected_incarnation)
|
|
959
|
+
if receipt.status != "accepted":
|
|
960
|
+
return {"status": "pending", "receipt": receipt}
|
|
961
|
+
# Canonical terminal is a fixed upper bound. Do not infer result from
|
|
962
|
+
# idle status, an arbitrary last message, child runs or transport EOF.
|
|
963
|
+
after = 0
|
|
964
|
+
items, phases, total_tokens = {}, {}, 0
|
|
965
|
+
terminal = None
|
|
966
|
+
scanned = 0
|
|
967
|
+
while terminal is None and scanned < 10000:
|
|
968
|
+
page = await self.events.read(context.ref.sessionId, after, 200)
|
|
969
|
+
if not page:
|
|
970
|
+
break
|
|
971
|
+
scanned += len(page)
|
|
972
|
+
for envelope in page:
|
|
973
|
+
if envelope.seq <= after:
|
|
974
|
+
raise ContextConflict("canonical event cursor did not advance")
|
|
975
|
+
after = envelope.seq
|
|
976
|
+
if (
|
|
977
|
+
envelope.run_id != receipt.runId
|
|
978
|
+
or envelope.family != "runtime"
|
|
979
|
+
or envelope.family_version != 2
|
|
980
|
+
):
|
|
981
|
+
continue
|
|
982
|
+
event = parse_runtime_event(envelope.payload)
|
|
983
|
+
if event.event_type != envelope.event_type or event.seq != envelope.seq:
|
|
984
|
+
raise ContextConflict("canonical envelope/payload identity mismatch")
|
|
985
|
+
if (
|
|
986
|
+
event.run_id != receipt.runId
|
|
987
|
+
or event.source.metadata.get("parent_run_id")
|
|
988
|
+
or event.parent_scope_id is not None
|
|
989
|
+
):
|
|
990
|
+
continue
|
|
991
|
+
if event.event_type == "usage.reported":
|
|
992
|
+
total_tokens += event.total_tokens
|
|
993
|
+
elif event.event_type == "item.started":
|
|
994
|
+
phases[(event.scope_id, event.item_id)] = event.phase
|
|
995
|
+
elif event.event_type == "item.completed":
|
|
996
|
+
items[(event.scope_id, event.item_id)] = event
|
|
997
|
+
elif event.event_type in _TERMINAL:
|
|
998
|
+
terminal = (envelope, event)
|
|
999
|
+
break
|
|
1000
|
+
if terminal is None:
|
|
1001
|
+
return {
|
|
1002
|
+
"status": "pending",
|
|
1003
|
+
"receipt": receipt,
|
|
1004
|
+
"reason": "scan_budget_exceeded"
|
|
1005
|
+
if scanned >= 10000
|
|
1006
|
+
else "canonical_terminal_pending",
|
|
1007
|
+
}
|
|
1008
|
+
envelope, event = terminal
|
|
1009
|
+
refs = getattr(event, "output_refs", ())
|
|
1010
|
+
selected = (
|
|
1011
|
+
[(ref.scope_id, ref.item_id) for ref in refs]
|
|
1012
|
+
if refs
|
|
1013
|
+
else [key for key in items if phases.get(key) == "final_answer"]
|
|
1014
|
+
)
|
|
1015
|
+
if any(key not in items for key in selected):
|
|
1016
|
+
return {
|
|
1017
|
+
"status": "pending",
|
|
1018
|
+
"reason": "canonical_output_unavailable",
|
|
1019
|
+
"receipt": receipt,
|
|
1020
|
+
}
|
|
1021
|
+
texts, artifacts = [], []
|
|
1022
|
+
for key in dict.fromkeys(selected):
|
|
1023
|
+
completed = items[key]
|
|
1024
|
+
parts = [ref.part_id for ref in refs if (ref.scope_id, ref.item_id) == key]
|
|
1025
|
+
if parts and None not in parts:
|
|
1026
|
+
snapshot_parts = tuple(
|
|
1027
|
+
part for part in completed.snapshot.parts if part.part_id in parts
|
|
1028
|
+
)
|
|
1029
|
+
if set(parts) - {part.part_id for part in snapshot_parts}:
|
|
1030
|
+
return {
|
|
1031
|
+
"status": "pending",
|
|
1032
|
+
"reason": "canonical_output_unavailable",
|
|
1033
|
+
"receipt": receipt,
|
|
1034
|
+
}
|
|
1035
|
+
completed = completed.model_copy(
|
|
1036
|
+
update={
|
|
1037
|
+
"snapshot": completed.snapshot.model_copy(update={"parts": snapshot_parts})
|
|
1038
|
+
}
|
|
1039
|
+
)
|
|
1040
|
+
item = project_conversation_item(completed, session_id=context.ref.sessionId)
|
|
1041
|
+
if item.kind == "assistant_text":
|
|
1042
|
+
texts.append(str(item.payload.get("text") or ""))
|
|
1043
|
+
# Teams results carry immutable uploaded IDs. Conversation payloads
|
|
1044
|
+
# are display DTOs (and can contain URLs), not trusted artifact refs.
|
|
1045
|
+
# Inspect every selected part so mixed text/artifact messages do not
|
|
1046
|
+
# silently lose their produced objects.
|
|
1047
|
+
for part in completed.snapshot.parts:
|
|
1048
|
+
if part.content_type == "artifact":
|
|
1049
|
+
reference = {"artifactId": part.artifact_id}
|
|
1050
|
+
if reference not in artifacts:
|
|
1051
|
+
artifacts.append(reference)
|
|
1052
|
+
candidate = {"result": "\n\n".join(texts), "artifacts": artifacts}
|
|
1053
|
+
evidence = TerminalEvidence(
|
|
1054
|
+
sessionId=context.ref.sessionId,
|
|
1055
|
+
runId=receipt.runId,
|
|
1056
|
+
commandId=context.ref.commandId,
|
|
1057
|
+
terminalSeq=envelope.seq,
|
|
1058
|
+
terminalEventDigest=digest(envelope.model_dump(mode="json")),
|
|
1059
|
+
resultDigest=digest(candidate),
|
|
1060
|
+
)
|
|
1061
|
+
if await self.registry.incarnation() != expected_incarnation:
|
|
1062
|
+
raise StoreIdentityMismatch("Kernel store identity changed during result read")
|
|
1063
|
+
return {
|
|
1064
|
+
"status": _TERMINAL[event.event_type],
|
|
1065
|
+
"candidate": candidate,
|
|
1066
|
+
"usage": {"totalTokens": total_tokens},
|
|
1067
|
+
"terminalEvidence": evidence,
|
|
1068
|
+
"receipt": receipt.model_copy(
|
|
1069
|
+
update={"nativeStatus": _TERMINAL[event.event_type], "terminalEvidence": evidence}
|
|
1070
|
+
),
|
|
1071
|
+
}
|