agentengine-sdk-python 0.8.5__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.5.dist-info → agentengine_sdk_python-0.8.6.dist-info}/METADATA +12 -8
- {agentengine_sdk_python-0.8.5.dist-info → agentengine_sdk_python-0.8.6.dist-info}/RECORD +823 -388
- 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/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/api/client.py +32 -79
- ksadk/api/sse_stream.py +96 -0
- ksadk/builders/code_builder.py +83 -106
- ksadk/builders/container_builder.py +11 -29
- ksadk/builders/framework_requirements.py +2 -0
- ksadk/builders/managed_runtime_builder.py +12 -0
- ksadk/builders/source_provenance.py +87 -0
- ksadk/cli/cmd_a2a.py +43 -0
- ksadk/cli/cmd_build.py +9 -0
- ksadk/cli/cmd_deploy.py +27 -2
- ksadk/cli/cmd_invoke.py +45 -92
- ksadk/cli/cmd_studio.py +5 -1
- ksadk/cli/cmd_web.py +2 -0
- ksadk/cli/hosted_invoke.py +206 -0
- ksadk/cli/invoke_content.py +60 -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 -1048
- 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/env_registry.py +106 -127
- ksadk/configs/env_registry_a2a.py +173 -0
- ksadk/configs/env_registry_studio.py +53 -5
- ksadk/configs/global_config.py +1 -0
- ksadk/configs/settings.py +6 -0
- ksadk/context_engine/assembler.py +9 -0
- ksadk/context_engine/contributors.py +80 -17
- ksadk/context_engine/instruction_authority.py +18 -0
- ksadk/conversations/attachments.py +53 -15
- ksadk/conversations/contracts.py +28 -9
- ksadk/conversations/message_projection.py +30 -125
- ksadk/conversations/message_projection_blocks.py +137 -0
- ksadk/conversations/model_context.py +11 -3
- ksadk/conversations/projector.py +63 -0
- ksadk/conversations/runtime_compaction.py +7 -2
- ksadk/conversations/runtime_input.py +16 -4
- ksadk/conversations/runtime_payloads.py +4 -0
- ksadk/conversations/runtime_persistence.py +192 -24
- ksadk/conversations/runtime_preparation.py +85 -6
- ksadk/conversations/runtime_projection.py +217 -0
- ksadk/conversations/runtime_resume.py +141 -70
- 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/_langgraph_support.py +12 -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/harness/__init__.py +4 -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 +26 -9
- 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/capability_adapters/__init__.py +1 -0
- ksadk/harness/capability_adapters/native_dsh.py +289 -0
- ksadk/harness/capability_runtime.py +104 -9
- ksadk/harness/compaction_record.py +31 -0
- ksadk/harness/compiler.py +3 -3
- ksadk/harness/config.py +28 -5
- ksadk/harness/conformance/contract.py +9 -11
- ksadk/harness/context_engine.py +18 -33
- ksadk/harness/context_sections.py +397 -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/engine/completion_guard.py +16 -1
- ksadk/harness/engine/context_pipeline.py +864 -92
- ksadk/harness/engine/graph_builder.py +123 -630
- ksadk/harness/engine/hooked_reasoner.py +380 -0
- ksadk/harness/engine/langgraph.py +126 -8
- ksadk/harness/engine/mcp_disclosure.py +65 -114
- 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 +21 -10
- ksadk/harness/engine/postgres_checkpointer.py +325 -2
- ksadk/harness/engine/run_control_bridge.py +21 -1
- ksadk/harness/engine/run_types.py +10 -0
- ksadk/harness/engine/skill_disclosure.py +98 -12
- ksadk/harness/engine/steering.py +177 -0
- ksadk/harness/engine/subagents.py +18 -1
- ksadk/harness/engine/tool_dispatch.py +112 -7
- ksadk/harness/events.py +39 -2
- ksadk/harness/execution_policy.py +10 -0
- ksadk/harness/hooks.py +259 -0
- ksadk/harness/loop/reason.py +281 -36
- ksadk/harness/loop/tools.py +157 -12
- ksadk/harness/managed_runtime.py +254 -94
- ksadk/harness/mcp_disclosure_contract.py +85 -0
- ksadk/harness/mcp_result_policy.py +44 -0
- ksadk/harness/mcp_runtime.py +33 -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 +223 -8
- ksadk/harness/model_provider.py +214 -4
- 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/progress_adapters/__init__.py +5 -0
- ksadk/harness/progress_adapters/native_todo.py +75 -0
- ksadk/harness/prompt_cache.py +65 -3
- ksadk/harness/public_activity.py +59 -0
- ksadk/harness/public_output.py +30 -0
- ksadk/harness/public_summary.py +36 -0
- ksadk/harness/reasoner.py +331 -22
- ksadk/harness/rpc.py +200 -0
- ksadk/harness/run_control.py +107 -2
- ksadk/harness/runtime.py +11 -2
- ksadk/harness/runtime_capabilities.py +71 -1
- ksadk/harness/sandbox_backend.py +203 -0
- ksadk/harness/sdk.py +153 -0
- ksadk/harness/session_store.py +370 -24
- 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_intent.py +47 -0
- ksadk/harness/skill_runtime.py +74 -16
- ksadk/harness/spec.py +20 -10
- ksadk/harness/state.py +2 -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/subagent.py +12 -2
- 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 +3 -0
- ksadk/harness/tool_result_policy.py +216 -0
- ksadk/harness/tools.py +52 -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/interaction/providers/langgraph.py +8 -1
- ksadk/kernel/bootstrap.py +144 -160
- ksadk/kernel/contract_fingerprints.py +45 -1
- ksadk/kernel/contracts.py +25 -0
- ksadk/kernel/control.py +153 -33
- ksadk/kernel/execution_grants.py +209 -2
- ksadk/kernel/execution_grants_memory.py +127 -8
- ksadk/kernel/execution_grants_postgres.py +188 -10
- ksadk/kernel/execution_grants_sqlite.py +235 -9
- ksadk/kernel/execution_host_ingress.py +1071 -0
- ksadk/kernel/history_projection.py +120 -0
- ksadk/kernel/ingress.py +117 -204
- ksadk/kernel/ingress_bootstrap.py +268 -0
- ksadk/kernel/legacy_history.py +179 -0
- ksadk/kernel/memory_store.py +38 -48
- ksadk/kernel/memory_store_projection.py +63 -0
- ksadk/kernel/postgres_event_log.py +181 -0
- ksadk/kernel/postgres_store.py +167 -198
- ksadk/kernel/readiness.py +125 -0
- ksadk/kernel/recovery.py +89 -3
- ksadk/kernel/recovery_projection.py +124 -0
- ksadk/kernel/runtime_checkpoint.py +34 -0
- ksadk/kernel/sql/001_agent_kernel.sql +5 -0
- ksadk/kernel/sqlite_schema.py +100 -0
- ksadk/kernel/sqlite_store.py +147 -216
- ksadk/kernel/store.py +47 -15
- 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 +323 -332
- ksadk/kernel/worker_controls.py +454 -0
- ksadk/kernel/worker_identity.py +27 -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/extraction.py +120 -7
- ksadk/memory/providers/local_candidates.py +183 -0
- ksadk/memory/providers/local_sqlite.py +252 -78
- ksadk/memory/resolved_policy.py +12 -7
- 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_proxy/compat.py +670 -0
- ksadk/model_proxy/server.py +10 -7
- ksadk/model_proxy/transform.py +37 -9
- ksadk/plugins/bridges/dsh.py +18 -20
- ksadk/plugins/bridges/dsh_profile_manifest.py +36 -0
- ksadk/plugins/builtin_resources.py +199 -0
- ksadk/plugins/builtins.py +380 -186
- ksadk/plugins/context_contributor.py +15 -4
- ksadk/plugins/dsh_dependency_policy.py +41 -0
- ksadk/plugins/dsh_toolchain.py +24 -35
- ksadk/plugins/execution_host.py +8 -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-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-tools/package.json +1 -1
- ksadk/plugins/providers/bundles/ksadk-dsh-capability-host/package.json +1 -1
- ksadk/plugins/providers/codex.py +42 -38
- ksadk/plugins/providers/codex_native.py +20 -0
- ksadk/plugins/providers/codex_skills.py +46 -0
- ksadk/plugins/providers/dsh_capabilities.py +16 -171
- ksadk/plugins/providers/dsh_connector_lease.py +225 -0
- ksadk/plugins/providers/dsh_mcp.py +163 -1
- ksadk/plugins/providers/harness.py +247 -34
- ksadk/plugins/providers/harness_context.py +61 -0
- ksadk/plugins/providers/harness_contributions.py +241 -0
- ksadk/plugins/providers/harness_delegation.py +91 -14
- ksadk/plugins/providers/harness_hooks.py +121 -0
- ksadk/plugins/providers/harness_managed.py +269 -175
- ksadk/plugins/providers/harness_tools.py +165 -36
- 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/teams/application.py +3 -143
- 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/domain.py +201 -148
- ksadk/plugins/teams/effect_contracts.py +255 -0
- ksadk/plugins/teams/execution_projection.py +255 -0
- ksadk/plugins/teams/leader_decisions.py +106 -0
- ksadk/plugins/teams/postgres_store.py +299 -85
- ksadk/plugins/teams/release_contracts.py +60 -0
- ksadk/plugins/teams/runtime.py +116 -40
- ksadk/plugins/teams/store.py +214 -6
- ksadk/plugins/teams/task_decisions.py +21 -8
- ksadk/plugins/teams/tool_service.py +152 -0
- ksadk/plugins/teams/transport.py +8 -3
- 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 +6 -400
- ksadk/runners/_langgraph_tool_projection.py +86 -0
- ksadk/runners/_langgraph_tools_transformer.py +27 -0
- ksadk/runners/adk_runner.py +195 -290
- ksadk/runners/base_runner.py +6 -5
- ksadk/runners/langgraph_runner.py +82 -86
- 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 +83 -128
- ksadk/runtime/adapter.py +40 -3
- ksadk/runtime/conversation_execution.py +4 -2
- ksadk/runtime/executor.py +97 -7
- ksadk/runtime/factory.py +13 -6
- ksadk/runtime/framework_adapters.py +184 -10
- ksadk/runtime/hosted_finalizer.py +4 -6
- ksadk/runtime/launch.py +2 -0
- ksadk/runtime/runner_adapter.py +123 -13
- ksadk/runtime_context.py +2 -0
- ksadk/sandbox/backends/e2b.py +30 -4
- ksadk/sandbox/backends/local_process.py +10 -0
- ksadk/sandbox/e2b_connection.py +9 -1
- ksadk/sandbox/local_controls.py +32 -2
- ksadk/sandbox/local_launcher.py +34 -0
- ksadk/server/factory.py +178 -25
- ksadk/server/history_deadline.py +158 -0
- ksadk/server/history_page_cache.py +129 -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/control.py +51 -3
- ksadk/server/routes/display_projection.py +154 -0
- ksadk/server/routes/kernel_ingress.py +17 -2
- ksadk/server/routes/misc.py +102 -12
- ksadk/server/routes/models.py +25 -1
- ksadk/server/routes/openai_compat.py +6 -0
- ksadk/server/routes/projection.py +159 -216
- ksadk/server/routes/run.py +6 -2
- ksadk/server/routes/sessions.py +301 -342
- ksadk/server/routes/streaming.py +68 -15
- ksadk/server/routes/tool_receipt_claim_routes.py +107 -0
- ksadk/server/routes/workspace.py +5 -2
- ksadk/server/static/assets/{ArtifactsPanel-C1YoaKhx.js → ArtifactsPanel-CILaW-fC.js} +1 -1
- ksadk/server/static/assets/{CodeBlock-DHuAWfr5.js → CodeBlock-BVrNVtJC.js} +1 -1
- ksadk/server/static/assets/{MathMessageMarkdown-cvdrBwYr.js → MathMessageMarkdown-Dp7c4wWD.js} +1 -1
- ksadk/server/static/assets/{MermaidBlock-DeBkbJvI.js → MermaidBlock-Dxop8Rd7.js} +6 -6
- ksadk/server/static/assets/{NativeTerminalPanel-oJj44_sV.js → NativeTerminalPanel-Cjjz8B30.js} +1 -1
- ksadk/server/static/assets/{abnfDiagram-VCTEODGH-Dhfv25o2.js → abnfDiagram-VCTEODGH-ckWDmOzw.js} +1 -1
- ksadk/server/static/assets/{arc-C35w-pn1.js → arc-DqxJede-.js} +1 -1
- ksadk/server/static/assets/architecture-7GRP2DOG-pn_DuLy6.js +1 -0
- ksadk/server/static/assets/{architectureDiagram-5GKGNRK7-FoMY_u6D.js → architectureDiagram-5GKGNRK7-SEQA4bVi.js} +1 -1
- ksadk/server/static/assets/{blockDiagram-NRAW4CY4-zD4Rt7oE.js → blockDiagram-NRAW4CY4-pM0B-6NJ.js} +1 -1
- ksadk/server/static/assets/{c4Diagram-UCG6FXSJ-BCtGGkhN.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-C2Ms13_k.js → chunk-5VM5RSS4-GJHDr9Ww.js} +1 -1
- ksadk/server/static/assets/{chunk-F27PBJKO-BoTj-qgx.js → chunk-F27PBJKO-CbAN45AV.js} +1 -1
- ksadk/server/static/assets/{chunk-G27WJ6UU-DOMyyjHH.js → chunk-G27WJ6UU-D5ngbbzF.js} +1 -1
- ksadk/server/static/assets/{chunk-JWPE2WC7-DbJJqDli.js → chunk-JWPE2WC7-Cc5IwuYC.js} +1 -1
- ksadk/server/static/assets/{chunk-LCL6LL3I-CLuRCt_W.js → chunk-LCL6LL3I-CprgDDdJ.js} +1 -1
- ksadk/server/static/assets/{chunk-POPQ4Y6H-D0Dz847e.js → chunk-POPQ4Y6H-CDZhSy82.js} +1 -1
- ksadk/server/static/assets/{chunk-RHFEMEQ7-BWSRzEcd.js → chunk-RHFEMEQ7-CZchUNro.js} +1 -1
- ksadk/server/static/assets/{chunk-SVP7TREG-CPoHqkCY.js → chunk-SVP7TREG-BVruqk6T.js} +1 -1
- ksadk/server/static/assets/{chunk-XXDRQBXY-Bx1jS-X-.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-LzyWm4m0.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-BlW_bHED.js → cynefinDiagram-5FMLGOSQ-BIyq3EJb.js} +1 -1
- ksadk/server/static/assets/{dagre-3AP2YEHR-Bu_S86_i.js → dagre-3AP2YEHR-eBw08Qdk.js} +1 -1
- ksadk/server/static/assets/{dagre-B7nCawed.js → dagre-DfvnEf45.js} +1 -1
- ksadk/server/static/assets/{diagram-S7CK7UJ4-W_Zow2Km.js → diagram-S7CK7UJ4-CUSrE3Mg.js} +1 -1
- ksadk/server/static/assets/{diagram-UQ7AKVKN-CLIKAHON.js → diagram-UQ7AKVKN-Dq5Zw2gy.js} +1 -1
- ksadk/server/static/assets/{diagram-VSXAHHWV-Dv6_QAlN.js → diagram-VSXAHHWV-DyUHfNwT.js} +1 -1
- ksadk/server/static/assets/{diagram-VX7I27RA-BWAWRDtZ.js → diagram-VX7I27RA-CREmM89O.js} +1 -1
- ksadk/server/static/assets/{diagram-Z3DM3KII-XA_rWMss.js → diagram-Z3DM3KII-Dw9zhHUK.js} +1 -1
- ksadk/server/static/assets/{dist-CGt_UGeO.js → dist-0uJ4tdx6.js} +1 -1
- ksadk/server/static/assets/{dist-C0J5_3qM.js → dist-AEv-vXf-.js} +1 -1
- ksadk/server/static/assets/{dist-CIpWk_5f.js → dist-B49GzZDb.js} +1 -1
- ksadk/server/static/assets/{dist-B3bA05-e.js → dist-B8Myiet9.js} +1 -1
- ksadk/server/static/assets/{dist-DWfdmz9s.js → dist-BBsYarrI.js} +1 -1
- ksadk/server/static/assets/{dist-BLpRy_Yx.js → dist-BQMrUwdI.js} +1 -1
- ksadk/server/static/assets/{dist-CIRMvUM4.js → dist-BX_-FENW.js} +1 -1
- ksadk/server/static/assets/{dist-BdNFAney.js → dist-CD4L6ymH.js} +1 -1
- ksadk/server/static/assets/{dist-n3n6t_FO.js → dist-CHpW1BHj.js} +1 -1
- ksadk/server/static/assets/{dist-DppE_r-D.js → dist-CVPau3tn.js} +1 -1
- ksadk/server/static/assets/{dist-qe8xjesy.js → dist-C_qdxcSH.js} +1 -1
- ksadk/server/static/assets/{dist-2vL2sAdF.js → dist-Co68Apq4.js} +1 -1
- ksadk/server/static/assets/{dist-1nXCdsej.js → dist-Cp2PaOMY.js} +1 -1
- ksadk/server/static/assets/{dist-DNKuMzWc.js → dist-CuR5Bgme.js} +1 -1
- ksadk/server/static/assets/{dist-t6MzE0jU.js → dist-DDSyLEOX.js} +1 -1
- ksadk/server/static/assets/{dist-CPyieXEf.js → dist-DUxO0R99.js} +1 -1
- ksadk/server/static/assets/{dist-DyG6Ya-z.js → dist-QzbGrED_.js} +1 -1
- ksadk/server/static/assets/{dist-0X_j2Rcc.js → dist-bupkyEBZ.js} +1 -1
- ksadk/server/static/assets/{dist-mqD5TZup.js → dist-cxTGfdqx.js} +1 -1
- ksadk/server/static/assets/{dist-M-SrdhhZ.js → dist-hL5p1til.js} +1 -1
- ksadk/server/static/assets/{dist-D-92S-Fd.js → dist-lOy23y43.js} +1 -1
- ksadk/server/static/assets/{dist-BO_UwatH.js → dist-pq-nD33R.js} +1 -1
- ksadk/server/static/assets/{ebnfDiagram-PWID7BFC-BfCzF1Xi.js → ebnfDiagram-PWID7BFC-BS5LdNoR.js} +1 -1
- ksadk/server/static/assets/{erDiagram-SSCWMZ5O-Dpz9_0zn.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-DDaG1f4_.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-DcxzRwYC.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-CYMdn6lQ.js → infoDiagram-RXCK75RN-C1kEtv2y.js} +1 -1
- ksadk/server/static/assets/{ishikawaDiagram-5VMMS53U-CLHFAD6c.js → ishikawaDiagram-5VMMS53U-BCNPyMka.js} +1 -1
- ksadk/server/static/assets/{journeyDiagram-EYS64GPL-BHSKQGAl.js → journeyDiagram-EYS64GPL--cDbKnjP.js} +1 -1
- ksadk/server/static/assets/{kanban-definition-3QL26DDD-D5W3tjTT.js → kanban-definition-3QL26DDD-R1rAVw2f.js} +1 -1
- ksadk/server/static/assets/{katex-mtjOi4KM.js → katex-BT-X-V7U.js} +1 -1
- ksadk/server/static/assets/{linear-BETqsxE_.js → linear-DTR631iG.js} +1 -1
- ksadk/server/static/assets/{mermaid-parser.core-DPWrvs90.js → mermaid-parser.core-DfFzJhX8.js} +2 -2
- ksadk/server/static/assets/{mindmap-definition-FBJOCRG2-CJG2mfBP.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-GjAPNaqn.js → pegDiagram-XKGWAZYB-xWXPEh0c.js} +1 -1
- ksadk/server/static/assets/pie-WAS4IAKB-hwiz6fbw.js +1 -0
- ksadk/server/static/assets/{pieDiagram-E7YTZNPT-ToIewrqr.js → pieDiagram-E7YTZNPT-BudBDlCI.js} +1 -1
- ksadk/server/static/assets/{quadrantDiagram-AXDQQJYC-4d78KiEY.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-DKzx4xfv.js → railroadDiagram-O6MQD6OU-BdAYRYB8.js} +1 -1
- ksadk/server/static/assets/{requirementDiagram-EFPCY7ZU-CJYljxQS.js → requirementDiagram-EFPCY7ZU-CBBmaL70.js} +1 -1
- ksadk/server/static/assets/{sankeyDiagram-P5KCCOFB-DLU2fV1w.js → sankeyDiagram-P5KCCOFB-Doc3rdwp.js} +1 -1
- ksadk/server/static/assets/{sequenceDiagram-WJ2MYXX4-CVqysrA9.js → sequenceDiagram-WJ2MYXX4-0J8R8hWW.js} +1 -1
- ksadk/server/static/assets/{sizeCapture-X5ZJPWSS-BUxfmTHc.js → sizeCapture-X5ZJPWSS-CfFLlWsK.js} +1 -1
- ksadk/server/static/assets/{stateDiagram-HBIQ2CUA-CNFgYI9E.js → stateDiagram-HBIQ2CUA-jBwkjtTy.js} +1 -1
- ksadk/server/static/assets/stateDiagram-v2-4QOOHH4V-Cw1fPb5w.js +1 -0
- ksadk/server/static/assets/{swimlanes-XN3QIQJK-B6qCMe8N.js → swimlanes-XN3QIQJK-B0WxTQf8.js} +1 -1
- ksadk/server/static/assets/swimlanesDiagram-VK2B7HYN-Cc3JMBAF.js +8 -0
- ksadk/server/static/assets/{timeline-definition-24CTP7MA-CMD3x_U_.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-BqtUqvXM.js → vennDiagram-4TSXK5OY-9gX1VMDC.js} +1 -1
- ksadk/server/static/assets/wardley-WFR3VGLG-DokNktqB.js +1 -0
- ksadk/server/static/assets/{wardleyDiagram-VM6X3IG4-B5KfDjI-.js → wardleyDiagram-VM6X3IG4-sEs_BP6O.js} +1 -1
- ksadk/server/static/assets/{xychartDiagram-S5SC5T6Z-BaUlSZrn.js → xychartDiagram-S5SC5T6Z-Ll4jvUN9.js} +1 -1
- ksadk/server/static/index.html +2 -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/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/loader.py +44 -2
- ksadk/skills/runtime/backends/e2b.py +17 -14
- ksadk/skills/service_client.py +6 -1
- 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 +219 -389
- 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 +23 -0
- ksadk/studio/attachment_store.py +14 -2
- ksadk/studio/build_resolution.py +117 -0
- ksadk/studio/build_singleflight.py +37 -0
- ksadk/studio/builder.py +20 -2
- ksadk/studio/capabilities.py +8 -3
- ksadk/studio/cloud.py +83 -377
- ksadk/studio/cloud_gateways.py +424 -0
- ksadk/studio/cloud_shared_web.py +7 -0
- ksadk/studio/codex_agent_service.py +17 -0
- ksadk/studio/codex_manifest.py +5 -1
- ksadk/studio/codex_provider_build.py +65 -0
- ksadk/studio/compiler.py +102 -6
- ksadk/studio/contract_base.py +19 -0
- ksadk/studio/contracts.py +231 -201
- ksadk/studio/dsh_application.py +58 -12
- ksadk/studio/dsh_capability_service.py +17 -171
- ksadk/studio/dsh_mcp_transport.py +191 -0
- ksadk/studio/event_store.py +17 -0
- ksadk/studio/execution_host.py +84 -11
- ksadk/studio/framework_run.py +18 -0
- ksadk/studio/interaction_submission.py +265 -0
- ksadk/studio/kernel_registry.py +12 -1
- 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 +1241 -761
- ksadk/studio/model_content_stream.py +129 -0
- ksadk/studio/model_credentials.py +196 -0
- ksadk/studio/model_profile_service.py +65 -31
- 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_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 +26 -10
- ksadk/studio/plugin_kernel_adapter.py +75 -1
- ksadk/studio/plugin_native_activation.py +163 -0
- ksadk/studio/plugin_runtime.py +639 -119
- ksadk/studio/plugin_runtime_admission.py +57 -0
- ksadk/studio/presentation.py +92 -0
- ksadk/studio/public_output_store.py +69 -0
- ksadk/studio/resource_authority.py +11 -3
- ksadk/studio/resource_catalog.py +8 -12
- ksadk/studio/run_activity.py +338 -385
- ksadk/studio/run_controls.py +185 -0
- ksadk/studio/run_service.py +908 -319
- ksadk/studio/run_submission_receipts.py +68 -0
- ksadk/studio/runtime_catalog.py +23 -4
- ksadk/studio/runtime_prewarm.py +22 -0
- ksadk/studio/scheduler_assistant.py +4 -1
- ksadk/studio/service.py +356 -282
- ksadk/studio/service_settings.py +229 -0
- ksadk/studio/shared_web.py +393 -169
- 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-UIqo-BPW.js → CodeBlock-DMIf4h33-CkufcPYo.js} +3 -3
- ksadk/studio/static/assets/{MathMessageMarkdown-BesSeCYl-OhNwH4K9.js → MathMessageMarkdown-BesSeCYl-DYG1Wzbx.js} +1 -1
- ksadk/studio/static/assets/{MessageMarkdown-CwMTvgFj-g0I-I4dD.js → MessageMarkdown-CwMTvgFj-BeyLyQHu.js} +2 -2
- ksadk/studio/static/assets/TeamsPage-CCaaGaVp.js +3 -0
- ksadk/studio/static/assets/index-C7DNDik2.css +2 -0
- ksadk/studio/static/assets/index-Cy68gTlH.js +265 -0
- ksadk/studio/static/index.html +3 -3
- ksadk/studio/teams_catalog.py +33 -0
- ksadk/studio/teams_installation.py +4 -1
- ksadk/studio/teams_node.py +4 -0
- ksadk/studio/teams_node_factory.py +558 -0
- ksadk/studio/teams_node_runner.py +3 -0
- ksadk/studio/teams_node_v1.py +935 -0
- ksadk/studio/teams_remote.py +259 -37
- ksadk/studio/templates.py +1 -0
- ksadk/studio/workspace_plugins.py +3 -1
- 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 +82 -88
- ksadk/toolsets/a2a.py +89 -89
- ksadk/toolsets/sandbox.py +377 -6
- ksadk/toolsets/skill_management.py +315 -0
- ksadk/toolsets/tool_selection.py +94 -0
- ksadk/toolsets/workspace.py +342 -324
- ksadk/toolsets/workspace_editing.py +291 -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/workspace_files/router.py +2 -1
- ksadk/server/static/assets/architecture-7GRP2DOG-BCsa26zi.js +0 -1
- ksadk/server/static/assets/channel-_KDifNys.js +0 -1
- ksadk/server/static/assets/chunk-2Q5K7J3B-HdVkJ9F0.js +0 -1
- ksadk/server/static/assets/classDiagram-DTDB5LWJ-BVCW3ZqZ.js +0 -1
- ksadk/server/static/assets/classDiagram-v2-JRS7N3AN-BVCW3ZqZ.js +0 -1
- ksadk/server/static/assets/cynefin-OW5HDTMX-CNXjFctL.js +0 -1
- ksadk/server/static/assets/eventmodeling-NTZA5JFV-B5-8RH9c.js +0 -1
- ksadk/server/static/assets/flowDiagram-A5DVABFB-BppFxEKw.js +0 -1
- ksadk/server/static/assets/gitGraph-4MIJSDKK-B-AhYj4C.js +0 -1
- ksadk/server/static/assets/index-BMd2mucF.css +0 -2
- ksadk/server/static/assets/index-D5qyyhTH.js +0 -244
- ksadk/server/static/assets/info-A6RAGUB7-0uiKrC35.js +0 -1
- ksadk/server/static/assets/packet-AYTQ26CC-BVTmZ_cw.js +0 -1
- ksadk/server/static/assets/pie-WAS4IAKB-DyfxBU7V.js +0 -1
- ksadk/server/static/assets/radar-RG4KPBEZ-FFontjL2.js +0 -1
- ksadk/server/static/assets/railroad-74A4TZTK-D0Uidzen.js +0 -1
- ksadk/server/static/assets/railroad-abnf-HS5TGJTU-BOo_9T2h.js +0 -1
- ksadk/server/static/assets/railroad-ebnf-LZEXJU2U-D6-BjW7Z.js +0 -1
- ksadk/server/static/assets/railroad-peg-WCYAUIDC-CXx__yMm.js +0 -1
- ksadk/server/static/assets/stateDiagram-v2-4QOOHH4V-BXAFScz8.js +0 -1
- ksadk/server/static/assets/swimlanesDiagram-VK2B7HYN-uIQ2lJKH.js +0 -8
- ksadk/server/static/assets/treeView-Q6P3EWNA-CK5GgucZ.js +0 -1
- ksadk/server/static/assets/treemap-WGGIJYW6-Bq1u1SpG.js +0 -1
- ksadk/server/static/assets/wardley-WFR3VGLG-QAt06uEz.js +0 -1
- ksadk/studio/static/assets/ChannelsPage-D_PGmKVq.js +0 -8
- ksadk/studio/static/assets/TeamsPage-DqX4HWKQ.js +0 -3
- ksadk/studio/static/assets/index-CfEnms6Y.css +0 -2
- ksadk/studio/static/assets/index-Dp61rOWZ.js +0 -0
- {agentengine_sdk_python-0.8.5.dist-info → agentengine_sdk_python-0.8.6.dist-info}/WHEEL +0 -0
- {agentengine_sdk_python-0.8.5.dist-info → agentengine_sdk_python-0.8.6.dist-info}/entry_points.txt +0 -0
- {agentengine_sdk_python-0.8.5.dist-info → agentengine_sdk_python-0.8.6.dist-info}/licenses/LICENSE +0 -0
- {agentengine_sdk_python-0.8.5.dist-info → agentengine_sdk_python-0.8.6.dist-info}/top_level.txt +0 -0
|
@@ -0,0 +1,381 @@
|
|
|
1
|
+
"""Native session-history projection; source transcripts remain immutable.
|
|
2
|
+
|
|
3
|
+
Keep actual tool observations and complete protocol pairs across user turns.
|
|
4
|
+
Imported call IDs have stable historical identities so providers may reuse a
|
|
5
|
+
local call ID in a later turn. Summary/provisional text is never promoted into
|
|
6
|
+
the final answer. This is Native-to-Native projection, not a cross-runtime wire
|
|
7
|
+
format; other runtimes need an explicit canonical export adapter.
|
|
8
|
+
"""
|
|
9
|
+
|
|
10
|
+
from __future__ import annotations
|
|
11
|
+
|
|
12
|
+
import hashlib
|
|
13
|
+
import json
|
|
14
|
+
from copy import deepcopy
|
|
15
|
+
|
|
16
|
+
from pydantic import JsonValue
|
|
17
|
+
|
|
18
|
+
from .context_history import _historical_message
|
|
19
|
+
from .model import ModelReplayMetadata, ModelTurnResult
|
|
20
|
+
from .model_replay import remap_anthropic_replay, replay_fields
|
|
21
|
+
from .operator_guidance import HISTORICAL_FRAME_KIND, journaled_guidance
|
|
22
|
+
from .state import InterruptedToolCall, RunPhase, RunSnapshot
|
|
23
|
+
from .tool_interruption import interrupted_tool_calls
|
|
24
|
+
|
|
25
|
+
_TRANSIENT_PHASES = {"provisional", "text_delta", "final_candidate"}
|
|
26
|
+
# A new Session inherits user-authored turns and committed tool receipts. The
|
|
27
|
+
# observations below carry prior task facts; current verifier feedback is
|
|
28
|
+
# quoted once on import. Other typed messages are control for the old Run.
|
|
29
|
+
_INHERITED_OBSERVATION_KINDS = {
|
|
30
|
+
"user_document_observation",
|
|
31
|
+
"verification_observation",
|
|
32
|
+
"historical_verification_observation",
|
|
33
|
+
"historical_tool_observation",
|
|
34
|
+
"background_child_observation",
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
|
|
38
|
+
def _retained_history_message(message: dict, *, preserve_model_frames: bool = False) -> bool:
|
|
39
|
+
role, kind = message.get("role"), message.get("kind")
|
|
40
|
+
if kind == "delivery_review_source":
|
|
41
|
+
# The raw model/tool batch stays in the Run. A later Session receives
|
|
42
|
+
# executed observations as quotes, never the reviewer's private prose.
|
|
43
|
+
return False
|
|
44
|
+
return (
|
|
45
|
+
role in ({"system", "developer", "user", "assistant", "tool"}
|
|
46
|
+
if preserve_model_frames else {"user", "assistant", "tool"})
|
|
47
|
+
and (preserve_model_frames or role == "tool" or kind in {None, "user_guidance"}
|
|
48
|
+
or kind in _INHERITED_OBSERVATION_KINDS)
|
|
49
|
+
and message.get("phase") not in _TRANSIENT_PHASES
|
|
50
|
+
and message.get("summary") is not True
|
|
51
|
+
)
|
|
52
|
+
|
|
53
|
+
|
|
54
|
+
def _observation_identity(message: dict) -> tuple[str, int, str] | None:
|
|
55
|
+
"""Identify an exact derived observation, never deduplicate arbitrary prose."""
|
|
56
|
+
run, index, content = (
|
|
57
|
+
message.get("source_run_id"), message.get("source_message_index"), message.get("content")
|
|
58
|
+
)
|
|
59
|
+
if (
|
|
60
|
+
message.get("history_projection_version") == 1
|
|
61
|
+
and isinstance(run, str) and run
|
|
62
|
+
and type(index) is int and index >= 0
|
|
63
|
+
and isinstance(content, str)
|
|
64
|
+
):
|
|
65
|
+
return run, index, content
|
|
66
|
+
return None
|
|
67
|
+
|
|
68
|
+
|
|
69
|
+
def _identity(prefix: str, *values: object) -> str:
|
|
70
|
+
raw = json.dumps(values, sort_keys=True, ensure_ascii=False, separators=(",", ":"))
|
|
71
|
+
return prefix + hashlib.sha256(raw.encode()).hexdigest()[:32]
|
|
72
|
+
|
|
73
|
+
|
|
74
|
+
def _source(message: dict, parent: RunSnapshot, index: int) -> dict:
|
|
75
|
+
if message.get("history_projection_version") == 1:
|
|
76
|
+
if (
|
|
77
|
+
not isinstance(message.get("source_run_id"), str)
|
|
78
|
+
or not message["source_run_id"]
|
|
79
|
+
or type(message.get("source_message_index")) is not int
|
|
80
|
+
or message["source_message_index"] < 0
|
|
81
|
+
):
|
|
82
|
+
raise ValueError("invalid historical source reference")
|
|
83
|
+
return {
|
|
84
|
+
name: message[name]
|
|
85
|
+
for name in ("history_projection_version", "source_run_id", "source_message_index")
|
|
86
|
+
}
|
|
87
|
+
return {
|
|
88
|
+
"history_projection_version": 1,
|
|
89
|
+
"source_run_id": parent.run_id,
|
|
90
|
+
"source_message_index": index,
|
|
91
|
+
}
|
|
92
|
+
|
|
93
|
+
|
|
94
|
+
def project_session_history(
|
|
95
|
+
parent: RunSnapshot | None, *, profile_digest: str | None = None,
|
|
96
|
+
configuration_digest: str | None = None,
|
|
97
|
+
) -> tuple[dict[str, JsonValue], ...]:
|
|
98
|
+
"""Import a terminal parent's history once, preserving bounded observations.
|
|
99
|
+
|
|
100
|
+
Content bounding belongs to ContextPlanner and tool-result shaping. Removing
|
|
101
|
+
all tool messages here would erase the facts needed for the next user turn.
|
|
102
|
+
A missing result is closed as unknown, never treated as successful or safe
|
|
103
|
+
to re-execute. An unchanged, uncompressed host journal retains prior model
|
|
104
|
+
frames as history; only the new run's config and current frame grant control.
|
|
105
|
+
"""
|
|
106
|
+
if parent is None:
|
|
107
|
+
return ()
|
|
108
|
+
if not parent.phase.terminal:
|
|
109
|
+
raise ValueError("session history requires a terminal parent")
|
|
110
|
+
preserve_model_frames = (
|
|
111
|
+
profile_digest is not None and profile_digest == parent.profile_digest
|
|
112
|
+
and configuration_digest == parent.configuration_digest
|
|
113
|
+
and not parent.compaction_history.get("count", 0)
|
|
114
|
+
and parent.phase == RunPhase.COMPLETED
|
|
115
|
+
and journaled_guidance(parent.messages, parent.profile_digest) is not None
|
|
116
|
+
)
|
|
117
|
+
output: list[dict[str, JsonValue]] = []
|
|
118
|
+
pending: dict[str, tuple[str, dict, InterruptedToolCall | None]] = {}
|
|
119
|
+
hook_inputs: list[dict[str, JsonValue]] = []
|
|
120
|
+
seen: set[str] = set()
|
|
121
|
+
scope = parent.scope.model_dump(mode="json")
|
|
122
|
+
inherited_observations = {
|
|
123
|
+
identity
|
|
124
|
+
for message in parent.messages
|
|
125
|
+
if message.get("role") == "user"
|
|
126
|
+
and message.get("kind") == "historical_tool_observation"
|
|
127
|
+
and _retained_history_message(message)
|
|
128
|
+
and (identity := _observation_identity(message)) is not None
|
|
129
|
+
}
|
|
130
|
+
derived_inputs: set[tuple[str, int, str]] = set()
|
|
131
|
+
retained_inputs: set[tuple[str, int, str]] = set()
|
|
132
|
+
|
|
133
|
+
def flush_hook_inputs() -> None:
|
|
134
|
+
output.extend(hook_inputs)
|
|
135
|
+
hook_inputs.clear()
|
|
136
|
+
|
|
137
|
+
def close_pending() -> None:
|
|
138
|
+
status = (
|
|
139
|
+
"uncertain"
|
|
140
|
+
if parent.phase in {RunPhase.INTERRUPTED, RunPhase.CANCELED}
|
|
141
|
+
or parent.reason == "effect_outcome_unknown"
|
|
142
|
+
else "not_completed"
|
|
143
|
+
)
|
|
144
|
+
for mapped, source, observation in pending.values():
|
|
145
|
+
not_dispatched = observation is not None and (
|
|
146
|
+
observation.execution_status == "not_dispatched"
|
|
147
|
+
)
|
|
148
|
+
data = {
|
|
149
|
+
"status": "not_completed" if not_dispatched else (
|
|
150
|
+
"uncertain" if observation is not None else status
|
|
151
|
+
),
|
|
152
|
+
"execution_status": "not_dispatched" if not_dispatched else "unknown",
|
|
153
|
+
"reason": "not_dispatched" if not_dispatched else (
|
|
154
|
+
"previous_turn_ended_without_tool_result"
|
|
155
|
+
),
|
|
156
|
+
"instruction": (
|
|
157
|
+
"The host did not dispatch this call before the turn ended. "
|
|
158
|
+
"It has no execution result. Any new attempt requires fresh admission."
|
|
159
|
+
if not_dispatched else
|
|
160
|
+
"No committed result is available. Check actual state "
|
|
161
|
+
"before assuming success or repeating any side effect."
|
|
162
|
+
),
|
|
163
|
+
}
|
|
164
|
+
if observation is not None:
|
|
165
|
+
data["interruption_reason"] = parent.tool_batch_interruption.reason
|
|
166
|
+
if observation.operation_key is not None:
|
|
167
|
+
data["operation_key"] = observation.operation_key
|
|
168
|
+
output.append(
|
|
169
|
+
{
|
|
170
|
+
"role": "tool",
|
|
171
|
+
"tool_call_id": mapped,
|
|
172
|
+
**source,
|
|
173
|
+
"kind": "incomplete_tool_observation",
|
|
174
|
+
"content": json.dumps(data, sort_keys=True),
|
|
175
|
+
}
|
|
176
|
+
)
|
|
177
|
+
pending.clear()
|
|
178
|
+
flush_hook_inputs()
|
|
179
|
+
|
|
180
|
+
from .context_replay import _mark
|
|
181
|
+
from .context_runtime_contracts import source_context_digest
|
|
182
|
+
from .replay_context import replay_identity
|
|
183
|
+
|
|
184
|
+
abandoned = set(parent.compaction_history.get("abandoned_replay_digests", ()))
|
|
185
|
+
abandoned_root = source_context_digest(parent.messages) if abandoned else None
|
|
186
|
+
for index, original in enumerate(parent.messages):
|
|
187
|
+
interruptions = interrupted_tool_calls(parent, index, original)
|
|
188
|
+
if original.get("role") == "assistant" and original.get("provider_replay") is not None:
|
|
189
|
+
replay = ModelReplayMetadata.model_validate(original["provider_replay"])
|
|
190
|
+
if abandoned and replay_identity(replay) in abandoned:
|
|
191
|
+
original = _mark(original, f"inherited-message:{index}",
|
|
192
|
+
abandoned_root)
|
|
193
|
+
role = original.get("role")
|
|
194
|
+
kind = original.get("kind")
|
|
195
|
+
if not _retained_history_message(original, preserve_model_frames=preserve_model_frames):
|
|
196
|
+
continue
|
|
197
|
+
source = _source(original, parent, index)
|
|
198
|
+
message = {**deepcopy(original), **source}
|
|
199
|
+
if preserve_model_frames and role != "tool" and (
|
|
200
|
+
role in {"system", "developer"}
|
|
201
|
+
or kind not in {None, "user_guidance", *_INHERITED_OBSERVATION_KINDS}
|
|
202
|
+
or kind == "verification_observation"
|
|
203
|
+
):
|
|
204
|
+
# Keep the model-visible role/content where they were. Only host
|
|
205
|
+
# provenance changes: the old frame is no current control, goal or
|
|
206
|
+
# verifier authority. A new Run stages its own current host frame.
|
|
207
|
+
message["history_original_kind"] = original.get("history_original_kind", kind)
|
|
208
|
+
message["kind"] = HISTORICAL_FRAME_KIND
|
|
209
|
+
if role == "user" and kind == "verification_observation" and not preserve_model_frames:
|
|
210
|
+
# Preserve the old verdict exactly as quoted data. Its repair
|
|
211
|
+
# instruction belongs to that old goal, not the new user turn.
|
|
212
|
+
quoted, images = _historical_message(message)
|
|
213
|
+
message["kind"] = "historical_verification_observation"
|
|
214
|
+
content = json.dumps({
|
|
215
|
+
"observation": "previous_turn_verification",
|
|
216
|
+
"current_task_authority": False,
|
|
217
|
+
"source_run_id": source["source_run_id"],
|
|
218
|
+
"source_message_index": source["source_message_index"],
|
|
219
|
+
"content": quoted.get("content"),
|
|
220
|
+
}, ensure_ascii=False)
|
|
221
|
+
# Keep explicit pixels for the ordinary media admission path;
|
|
222
|
+
# base64 inside quoted JSON would only be prose for the model.
|
|
223
|
+
message["content"] = (
|
|
224
|
+
[{"type": "text", "text": content}, *images] if images else content
|
|
225
|
+
)
|
|
226
|
+
if role == "tool":
|
|
227
|
+
call_id = message.get("tool_call_id")
|
|
228
|
+
if isinstance(call_id, str) and call_id in pending:
|
|
229
|
+
mapped, _, _ = pending.pop(call_id)
|
|
230
|
+
message["tool_call_id"] = mapped
|
|
231
|
+
output.append(message)
|
|
232
|
+
if (not preserve_model_frames
|
|
233
|
+
and isinstance(message.get("hook_effective_arguments"), dict)):
|
|
234
|
+
observation = {
|
|
235
|
+
"role": "user", "kind": "historical_tool_observation", **source,
|
|
236
|
+
"content": json.dumps({
|
|
237
|
+
"observation": "kernel_effective_tool_input",
|
|
238
|
+
"tool_call_id": mapped, "receipt_ref": message.get("receipt_ref"),
|
|
239
|
+
"effective_arguments": message["hook_effective_arguments"],
|
|
240
|
+
"instruction": (
|
|
241
|
+
"This records the effective input for this attempt, "
|
|
242
|
+
"not an approval "
|
|
243
|
+
"or proof of successful execution. Consult the tool result."
|
|
244
|
+
),
|
|
245
|
+
}, ensure_ascii=False),
|
|
246
|
+
}
|
|
247
|
+
# A previously imported receipt already has this derived
|
|
248
|
+
# note. Keep that source frame instead of adding one per
|
|
249
|
+
# new turn; identical prose from other receipts is distinct.
|
|
250
|
+
identity = _observation_identity(observation)
|
|
251
|
+
if identity is None:
|
|
252
|
+
raise ValueError("invalid derived historical source reference")
|
|
253
|
+
derived_inputs.add(identity)
|
|
254
|
+
if identity not in inherited_observations:
|
|
255
|
+
hook_inputs.append(observation)
|
|
256
|
+
inherited_observations.add(identity)
|
|
257
|
+
retained_inputs.add(identity)
|
|
258
|
+
if not pending:
|
|
259
|
+
flush_hook_inputs()
|
|
260
|
+
else:
|
|
261
|
+
close_pending()
|
|
262
|
+
output.append(
|
|
263
|
+
{
|
|
264
|
+
"role": "user",
|
|
265
|
+
"kind": "historical_tool_observation",
|
|
266
|
+
**source,
|
|
267
|
+
"content": json.dumps(
|
|
268
|
+
{"status": "unmatched_tool_result", "content": message.get("content")},
|
|
269
|
+
ensure_ascii=False,
|
|
270
|
+
),
|
|
271
|
+
}
|
|
272
|
+
)
|
|
273
|
+
continue
|
|
274
|
+
if (not preserve_model_frames and role == "user"
|
|
275
|
+
and kind == "historical_tool_observation"):
|
|
276
|
+
identity = _observation_identity(message)
|
|
277
|
+
if identity in derived_inputs:
|
|
278
|
+
# Only collapse a frame reproduced from a matching receipt.
|
|
279
|
+
# Arbitrary or orphaned historical observations stay intact.
|
|
280
|
+
if identity in retained_inputs:
|
|
281
|
+
continue
|
|
282
|
+
retained_inputs.add(identity)
|
|
283
|
+
close_pending()
|
|
284
|
+
calls = message.get("tool_calls")
|
|
285
|
+
if calls:
|
|
286
|
+
if role != "assistant" or not isinstance(calls, list):
|
|
287
|
+
raise ValueError("malformed native tool history")
|
|
288
|
+
identities = {}
|
|
289
|
+
for call_index, call in enumerate(calls):
|
|
290
|
+
call_id = call.get("id") if isinstance(call, dict) else None
|
|
291
|
+
if not isinstance(call_id, str) or not call_id or call_id in pending:
|
|
292
|
+
raise ValueError("malformed native tool identity")
|
|
293
|
+
mapped = (
|
|
294
|
+
call_id
|
|
295
|
+
if original.get("history_projection_version") == 1
|
|
296
|
+
else _identity(
|
|
297
|
+
"hist_",
|
|
298
|
+
scope,
|
|
299
|
+
source["source_run_id"],
|
|
300
|
+
source["source_message_index"],
|
|
301
|
+
call_id,
|
|
302
|
+
call_index,
|
|
303
|
+
)
|
|
304
|
+
)
|
|
305
|
+
if mapped in seen:
|
|
306
|
+
raise ValueError("duplicate imported tool identity")
|
|
307
|
+
seen.add(mapped)
|
|
308
|
+
call["id"] = mapped
|
|
309
|
+
identities[call_id] = mapped
|
|
310
|
+
pending[call_id] = (mapped, source, interruptions.get(call_id))
|
|
311
|
+
if message.get("provider_replay") is not None:
|
|
312
|
+
message.update(replay_fields(remap_anthropic_replay(
|
|
313
|
+
ModelReplayMetadata.model_validate(message["provider_replay"]), identities,
|
|
314
|
+
)))
|
|
315
|
+
output.append(message)
|
|
316
|
+
close_pending()
|
|
317
|
+
final = parent.final_text
|
|
318
|
+
if final and parent.phase in {RunPhase.COMPLETED, RunPhase.INTERRUPTED}:
|
|
319
|
+
last = output[-1] if output else {}
|
|
320
|
+
if not (
|
|
321
|
+
last.get("role") == "assistant"
|
|
322
|
+
and not last.get("tool_calls")
|
|
323
|
+
and last.get("content") == final
|
|
324
|
+
):
|
|
325
|
+
output.append(
|
|
326
|
+
{
|
|
327
|
+
"role": "assistant", "content": final,
|
|
328
|
+
**_source({}, parent, len(parent.messages)),
|
|
329
|
+
**replay_fields(
|
|
330
|
+
parent.candidate_replay
|
|
331
|
+
if (parent.candidate or {}).get("final_text") == final
|
|
332
|
+
else None
|
|
333
|
+
),
|
|
334
|
+
}
|
|
335
|
+
)
|
|
336
|
+
from .context_replay import imported_compaction_replay
|
|
337
|
+
|
|
338
|
+
return imported_compaction_replay(
|
|
339
|
+
tuple(output), policy=parent.compaction_history.get("provider_replay_projection_policy"),
|
|
340
|
+
root_prefix_digest=parent.compaction_history.get("prefix_digest", ""),
|
|
341
|
+
)
|
|
342
|
+
|
|
343
|
+
|
|
344
|
+
def normalize_tool_identities(snapshot: RunSnapshot, result: ModelTurnResult) -> ModelTurnResult:
|
|
345
|
+
"""Project only colliding new call IDs; callers persist the raw result receipt.
|
|
346
|
+
|
|
347
|
+
The same request gets the same replacement identities. No incomplete calls
|
|
348
|
+
become executable, and text/usage/provider result semantics remain unchanged.
|
|
349
|
+
"""
|
|
350
|
+
if result.response_kind != "tool_calls":
|
|
351
|
+
return result
|
|
352
|
+
existing = {
|
|
353
|
+
call.get("id")
|
|
354
|
+
for message in snapshot.messages
|
|
355
|
+
for call in message.get("tool_calls", ())
|
|
356
|
+
if isinstance(call, dict)
|
|
357
|
+
}
|
|
358
|
+
existing.update(call.get("call_id") for call in snapshot.pending_tools)
|
|
359
|
+
reserved = existing | {call.call_id for call in result.tool_calls}
|
|
360
|
+
changed, projected = False, []
|
|
361
|
+
for index, call in enumerate(result.tool_calls):
|
|
362
|
+
if call.call_id not in existing:
|
|
363
|
+
projected.append(call)
|
|
364
|
+
continue
|
|
365
|
+
salt = 0
|
|
366
|
+
mapped = _identity("call_", result.request_id, call.call_id, index, salt)
|
|
367
|
+
while mapped in reserved:
|
|
368
|
+
salt += 1
|
|
369
|
+
mapped = _identity("call_", result.request_id, call.call_id, index, salt)
|
|
370
|
+
reserved.add(mapped)
|
|
371
|
+
projected.append(call.model_copy(deep=True, update={"call_id": mapped}))
|
|
372
|
+
changed = True
|
|
373
|
+
if not changed:
|
|
374
|
+
return result
|
|
375
|
+
replay = remap_anthropic_replay(result.provider_replay, {
|
|
376
|
+
original.call_id: current.call_id
|
|
377
|
+
for original, current in zip(result.tool_calls, projected)
|
|
378
|
+
})
|
|
379
|
+
return ModelTurnResult.model_validate({
|
|
380
|
+
**result.model_dump(), "tool_calls": tuple(projected), "provider_replay": replay,
|
|
381
|
+
})
|
|
@@ -0,0 +1,205 @@
|
|
|
1
|
+
"""Scoped host callbacks for Native HookPort; Kernel owns effect admission.
|
|
2
|
+
|
|
3
|
+
This executor is not a command/HTTP sandbox or a legacy ProviderHook bridge.
|
|
4
|
+
The host must supply authorized callbacks, pinned definitions and live policy.
|
|
5
|
+
No result grants a task verdict, tool approval, model budget or replay right.
|
|
6
|
+
"""
|
|
7
|
+
|
|
8
|
+
from __future__ import annotations
|
|
9
|
+
|
|
10
|
+
import asyncio
|
|
11
|
+
import inspect
|
|
12
|
+
from collections.abc import Awaitable, Callable, Sequence
|
|
13
|
+
from contextlib import suppress
|
|
14
|
+
from dataclasses import dataclass
|
|
15
|
+
|
|
16
|
+
from .hook_runtime_contract import (
|
|
17
|
+
HookDefinition,
|
|
18
|
+
HookInvocationRequest,
|
|
19
|
+
HookInvocationResult,
|
|
20
|
+
HookOutput,
|
|
21
|
+
_json_bytes,
|
|
22
|
+
hook_execution_policy_digest,
|
|
23
|
+
validate_hook_result,
|
|
24
|
+
)
|
|
25
|
+
from .state import RunScope
|
|
26
|
+
|
|
27
|
+
HookCallback = Callable[[HookInvocationRequest], Awaitable[HookOutput]]
|
|
28
|
+
HookAuthorizer = Callable[[HookInvocationRequest], Awaitable[str]]
|
|
29
|
+
HookAvailability = Callable[[], bool | Awaitable[bool]]
|
|
30
|
+
|
|
31
|
+
|
|
32
|
+
def _detached(value):
|
|
33
|
+
return type(value).model_validate_json(_json_bytes(value.model_dump(mode="json")))
|
|
34
|
+
|
|
35
|
+
|
|
36
|
+
@dataclass(frozen=True)
|
|
37
|
+
class HookBinding:
|
|
38
|
+
definition: HookDefinition
|
|
39
|
+
callback: HookCallback
|
|
40
|
+
available: HookAvailability | None = None
|
|
41
|
+
|
|
42
|
+
|
|
43
|
+
class ScopedHookExecutor:
|
|
44
|
+
"""A HookPort with explicit policy, deadline, byte limits and Task ownership.
|
|
45
|
+
|
|
46
|
+
Callback errors are failed only under the host's read-only declaration.
|
|
47
|
+
An admitted mutating callback's missing/invalid outcome remains uncertain.
|
|
48
|
+
Uncooperative tasks remain owned until terminal; their late values are
|
|
49
|
+
discarded. The declared cleanup wait bounds caller/close latency only.
|
|
50
|
+
"""
|
|
51
|
+
|
|
52
|
+
def __init__(
|
|
53
|
+
self, *, scope: RunScope, bindings: Sequence[HookBinding],
|
|
54
|
+
authorize: HookAuthorizer | None, cleanup_timeout_seconds: float,
|
|
55
|
+
):
|
|
56
|
+
policy_digest = hook_execution_policy_digest(
|
|
57
|
+
cleanup_timeout_seconds=cleanup_timeout_seconds,
|
|
58
|
+
)
|
|
59
|
+
self._scope = _detached(scope)
|
|
60
|
+
self._authorize = authorize
|
|
61
|
+
self._cleanup_timeout = cleanup_timeout_seconds
|
|
62
|
+
self._bindings: dict[str, HookBinding] = {}
|
|
63
|
+
for item in bindings:
|
|
64
|
+
definition = _detached(item.definition)
|
|
65
|
+
if definition.execution_policy_digest != policy_digest:
|
|
66
|
+
raise ValueError("Hook execution policy mismatch")
|
|
67
|
+
if (not callable(item.callback) or definition.hook_id in self._bindings
|
|
68
|
+
or (item.available is not None and not callable(item.available))):
|
|
69
|
+
raise ValueError("invalid or duplicate Hook binding")
|
|
70
|
+
self._bindings[definition.hook_id] = HookBinding(
|
|
71
|
+
definition, item.callback, item.available,
|
|
72
|
+
)
|
|
73
|
+
self._tasks: set[asyncio.Task] = set()
|
|
74
|
+
self._closed = False
|
|
75
|
+
|
|
76
|
+
def _forget(self, task: asyncio.Task) -> None:
|
|
77
|
+
self._tasks.discard(task)
|
|
78
|
+
with suppress(asyncio.CancelledError, Exception):
|
|
79
|
+
task.exception()
|
|
80
|
+
|
|
81
|
+
async def _available(self, binding: HookBinding) -> bool:
|
|
82
|
+
if self._closed:
|
|
83
|
+
return False
|
|
84
|
+
if binding.available is None:
|
|
85
|
+
return True
|
|
86
|
+
try:
|
|
87
|
+
value = binding.available()
|
|
88
|
+
if inspect.isawaitable(value):
|
|
89
|
+
value = await value
|
|
90
|
+
return value is True and not self._closed
|
|
91
|
+
except asyncio.CancelledError:
|
|
92
|
+
raise
|
|
93
|
+
except Exception:
|
|
94
|
+
return False
|
|
95
|
+
|
|
96
|
+
async def _stop(self, task: asyncio.Task) -> None:
|
|
97
|
+
if not task.done():
|
|
98
|
+
task.cancel()
|
|
99
|
+
await asyncio.wait((task,), timeout=self._cleanup_timeout)
|
|
100
|
+
|
|
101
|
+
async def invoke(self, request: HookInvocationRequest) -> HookInvocationResult:
|
|
102
|
+
sealed = _detached(request)
|
|
103
|
+
if sealed.scope != self._scope:
|
|
104
|
+
raise ValueError("Hook scope mismatch")
|
|
105
|
+
binding = self._bindings.get(sealed.definition.hook_id)
|
|
106
|
+
if binding is None or binding.definition != sealed.definition:
|
|
107
|
+
raise ValueError("Hook definition mismatch")
|
|
108
|
+
|
|
109
|
+
def rejected(reason, *, uncertain=False):
|
|
110
|
+
return HookInvocationResult.for_request(sealed, reason=reason, uncertain=uncertain)
|
|
111
|
+
|
|
112
|
+
if sealed.input_bytes > sealed.definition.max_input_bytes:
|
|
113
|
+
return rejected("input_budget_exceeded")
|
|
114
|
+
executed = False
|
|
115
|
+
revoked = False
|
|
116
|
+
loop = asyncio.get_running_loop()
|
|
117
|
+
deadline = loop.time() + sealed.definition.timeout_seconds
|
|
118
|
+
|
|
119
|
+
def expired():
|
|
120
|
+
# Task.cancel() is cooperative. A host policy may swallow it;
|
|
121
|
+
# invocation authority must not revive with a late "allow".
|
|
122
|
+
return revoked or loop.time() >= deadline
|
|
123
|
+
|
|
124
|
+
async def work():
|
|
125
|
+
nonlocal executed
|
|
126
|
+
if not await self._available(binding):
|
|
127
|
+
return rejected("binding_unavailable")
|
|
128
|
+
if expired():
|
|
129
|
+
return rejected("producer_timeout")
|
|
130
|
+
if self._authorize is None:
|
|
131
|
+
return rejected("policy_denied")
|
|
132
|
+
try:
|
|
133
|
+
decision = await self._authorize(_detached(sealed))
|
|
134
|
+
except asyncio.CancelledError:
|
|
135
|
+
raise
|
|
136
|
+
except Exception:
|
|
137
|
+
return rejected("policy_error")
|
|
138
|
+
if expired():
|
|
139
|
+
return rejected("producer_timeout")
|
|
140
|
+
if type(decision) is not str or decision not in {"allow", "deny"}:
|
|
141
|
+
return rejected("policy_error")
|
|
142
|
+
if decision == "deny":
|
|
143
|
+
return rejected("policy_denied")
|
|
144
|
+
if not await self._available(binding):
|
|
145
|
+
return rejected("binding_unavailable")
|
|
146
|
+
if expired():
|
|
147
|
+
return rejected("producer_timeout")
|
|
148
|
+
executed = True
|
|
149
|
+
try:
|
|
150
|
+
output = await binding.callback(_detached(sealed))
|
|
151
|
+
except asyncio.CancelledError:
|
|
152
|
+
raise
|
|
153
|
+
except Exception:
|
|
154
|
+
return rejected("producer_failed", uncertain=not sealed.definition.read_only)
|
|
155
|
+
if not await self._available(binding):
|
|
156
|
+
return rejected("binding_unavailable", uncertain=not sealed.definition.read_only)
|
|
157
|
+
if expired():
|
|
158
|
+
return rejected("producer_timeout", uncertain=not sealed.definition.read_only)
|
|
159
|
+
try:
|
|
160
|
+
if not isinstance(output, HookOutput):
|
|
161
|
+
raise ValueError("invalid Hook output type")
|
|
162
|
+
output = _detached(output)
|
|
163
|
+
output_bytes = len(_json_bytes(output.model_dump(mode="json")))
|
|
164
|
+
if output_bytes > binding.definition.max_output_bytes:
|
|
165
|
+
return rejected(
|
|
166
|
+
"output_budget_exceeded", uncertain=not sealed.definition.read_only,
|
|
167
|
+
)
|
|
168
|
+
result = HookInvocationResult.for_request(sealed, output=output)
|
|
169
|
+
result = validate_hook_result(sealed, result)
|
|
170
|
+
if expired():
|
|
171
|
+
return rejected("producer_timeout", uncertain=not sealed.definition.read_only)
|
|
172
|
+
return result
|
|
173
|
+
except (ValueError, TypeError):
|
|
174
|
+
return rejected("producer_invalid", uncertain=not sealed.definition.read_only)
|
|
175
|
+
|
|
176
|
+
task = asyncio.create_task(work())
|
|
177
|
+
self._tasks.add(task)
|
|
178
|
+
task.add_done_callback(self._forget)
|
|
179
|
+
try:
|
|
180
|
+
done, _ = await asyncio.wait((task,), timeout=sealed.definition.timeout_seconds)
|
|
181
|
+
if not done:
|
|
182
|
+
revoked = True
|
|
183
|
+
await self._stop(task)
|
|
184
|
+
return rejected(
|
|
185
|
+
"producer_timeout", uncertain=executed and not sealed.definition.read_only,
|
|
186
|
+
)
|
|
187
|
+
if task.cancelled():
|
|
188
|
+
return rejected(
|
|
189
|
+
"binding_unavailable" if self._closed else "producer_failed",
|
|
190
|
+
uncertain=executed,
|
|
191
|
+
)
|
|
192
|
+
return task.result()
|
|
193
|
+
except asyncio.CancelledError:
|
|
194
|
+
revoked = True
|
|
195
|
+
await self._stop(task)
|
|
196
|
+
raise
|
|
197
|
+
|
|
198
|
+
async def aclose(self) -> None:
|
|
199
|
+
self._closed = True
|
|
200
|
+
tasks = tuple(self._tasks)
|
|
201
|
+
for task in tasks:
|
|
202
|
+
if not task.done():
|
|
203
|
+
task.cancel()
|
|
204
|
+
if tasks:
|
|
205
|
+
await asyncio.wait(tasks, timeout=self._cleanup_timeout)
|