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,182 @@
|
|
|
1
|
+
"""Pure capacity estimates for a declared, canonical artifact read batch.
|
|
2
|
+
|
|
3
|
+
Estimates are never receipts or facts. They apply only to ordinary completion
|
|
4
|
+
of the current read-only group without intervening commands or host changes.
|
|
5
|
+
The real ContextPlanner remains the hard admission authority after execution.
|
|
6
|
+
"""
|
|
7
|
+
|
|
8
|
+
from __future__ import annotations
|
|
9
|
+
|
|
10
|
+
import json
|
|
11
|
+
from dataclasses import dataclass
|
|
12
|
+
|
|
13
|
+
from .artifact_read_contract import ARTIFACT_READ_DEFINITION
|
|
14
|
+
from .effective_configuration import effective_run_configuration
|
|
15
|
+
from .machine import next_transition, reduce_parallel_readonly_tools, reduce_tool
|
|
16
|
+
from .model import ModelToolCall
|
|
17
|
+
from .ports import ToolResult, digest
|
|
18
|
+
from .state import RunPhase
|
|
19
|
+
from .tool_budget import model_instructions, model_tool_surface, model_turn_control
|
|
20
|
+
from .transitions import commit_transition
|
|
21
|
+
|
|
22
|
+
ARTIFACT_CAPACITY_POLICY = "sealed-artifact-batch/v1"
|
|
23
|
+
|
|
24
|
+
|
|
25
|
+
@dataclass(frozen=True)
|
|
26
|
+
class ArtifactGroupCapacity:
|
|
27
|
+
"""An estimate in the bound planner's units, not persistent execution state."""
|
|
28
|
+
|
|
29
|
+
source_units: int
|
|
30
|
+
result_message_units: int
|
|
31
|
+
fixed_tokens: int
|
|
32
|
+
summary_tokens: int
|
|
33
|
+
group_size: int
|
|
34
|
+
|
|
35
|
+
|
|
36
|
+
def _declared_group(snapshot):
|
|
37
|
+
index = next((i for i in range(len(snapshot.messages)-1, -1, -1)
|
|
38
|
+
if snapshot.messages[i].get("role") == "assistant"
|
|
39
|
+
and snapshot.messages[i].get("tool_calls")), None)
|
|
40
|
+
if index is None:
|
|
41
|
+
return None
|
|
42
|
+
declared = snapshot.messages[index]
|
|
43
|
+
calls = declared["tool_calls"]
|
|
44
|
+
tail = snapshot.messages[index+1:]
|
|
45
|
+
if (not calls or len({c["id"] for c in calls}) != len(calls)
|
|
46
|
+
or len(tail) + len(snapshot.pending_tools) != len(calls)):
|
|
47
|
+
return None
|
|
48
|
+
try:
|
|
49
|
+
arguments = [json.loads(c["function"]["arguments"]) for c in calls]
|
|
50
|
+
# Duplicate requests can produce a separate loop-warning observation;
|
|
51
|
+
# their future framing is deliberately outside this bounded quote.
|
|
52
|
+
if len({json.dumps(a, sort_keys=True) for a in arguments}) != len(calls):
|
|
53
|
+
return None
|
|
54
|
+
if any(c["function"]["name"] != "ArtifactRead" for c in calls):
|
|
55
|
+
return None
|
|
56
|
+
if any(m.get("role") != "tool" or m.get("tool_call_id") != c["id"]
|
|
57
|
+
or m.get("receipt_goal_revision") != snapshot.goal_revision
|
|
58
|
+
or json.loads(m["content"]).get("status") != "ok"
|
|
59
|
+
for m, c in zip(tail, calls)):
|
|
60
|
+
return None
|
|
61
|
+
expected = tuple(ModelToolCall(call_id=c["id"], name=c["function"]["name"],
|
|
62
|
+
arguments=a).model_dump(mode="json")
|
|
63
|
+
for c, a in zip(calls[len(tail):], arguments[len(tail):]))
|
|
64
|
+
if expected != snapshot.pending_tools:
|
|
65
|
+
return None
|
|
66
|
+
if len(calls) == 1:
|
|
67
|
+
previous = next((m for m in reversed(snapshot.messages[:index])
|
|
68
|
+
if m.get("role") == "assistant" and m.get("tool_calls")), None)
|
|
69
|
+
if previous:
|
|
70
|
+
prior = previous["tool_calls"][-1]["function"]
|
|
71
|
+
if (prior["name"] == "ArtifactRead"
|
|
72
|
+
and json.loads(prior["arguments"]) == arguments[0]):
|
|
73
|
+
return None
|
|
74
|
+
except (KeyError, TypeError, ValueError):
|
|
75
|
+
return None
|
|
76
|
+
return declared, tail
|
|
77
|
+
|
|
78
|
+
|
|
79
|
+
def artifact_group_capacity(snapshot, configuration, driver):
|
|
80
|
+
"""Quote no-command batch completion using the same pure native reducers.
|
|
81
|
+
|
|
82
|
+
Receipts, progress digits, capped receipt digests, tool-budget controls and
|
|
83
|
+
real summary framing are remeasured rather than estimated by fixed magic
|
|
84
|
+
constants or by guessing the future operation-key revision width.
|
|
85
|
+
"""
|
|
86
|
+
if (snapshot.configuration_digest != configuration.digest
|
|
87
|
+
or snapshot.profile_digest != digest(configuration.profile)
|
|
88
|
+
or snapshot.context_binding != driver.binding):
|
|
89
|
+
raise ValueError("source_read_configuration_mismatch")
|
|
90
|
+
planner = driver.planner
|
|
91
|
+
if (planner is None or not planner.policy.read_working_set_count
|
|
92
|
+
or snapshot.phase != RunPhase.EXECUTING_TOOLS):
|
|
93
|
+
return None
|
|
94
|
+
group = _declared_group(snapshot)
|
|
95
|
+
if group is None or not snapshot.pending_tools or not snapshot.pending_intent:
|
|
96
|
+
return None
|
|
97
|
+
declared, sealed = group
|
|
98
|
+
# The planner's retained-source count is a bound on source identities,
|
|
99
|
+
# not on the number of atomic call groups. The original declared count
|
|
100
|
+
# is a safe upper bound without pretending overlapping sources are new.
|
|
101
|
+
if len(declared["tool_calls"]) > planner.policy.read_working_set_count:
|
|
102
|
+
return None
|
|
103
|
+
config = effective_run_configuration(configuration, snapshot)
|
|
104
|
+
|
|
105
|
+
installed = [t for t in config.tools if t.name == ARTIFACT_READ_DEFINITION.name]
|
|
106
|
+
if (len(installed) != 1 or installed[0].model_copy(update={"feedback_profile_digest": None})
|
|
107
|
+
!= ARTIFACT_READ_DEFINITION):
|
|
108
|
+
return None
|
|
109
|
+
if (snapshot.tool_calls + snapshot.descendant_tool_calls + len(snapshot.pending_tools)
|
|
110
|
+
> config.limits.max_tool_calls):
|
|
111
|
+
return None
|
|
112
|
+
# An intervening committed command breaks this finite no-command estimate.
|
|
113
|
+
# It must not be disguised by deriving new keys from an old pending intent.
|
|
114
|
+
if snapshot.pending_intent != f"{snapshot.run_id}:effect:{snapshot.revision}":
|
|
115
|
+
return None
|
|
116
|
+
current = snapshot.model_copy(deep=True)
|
|
117
|
+
first = True
|
|
118
|
+
remaining = len(snapshot.pending_tools)
|
|
119
|
+
while current.pending_tools:
|
|
120
|
+
before = (current.model_copy(update={"revision": current.revision-1,
|
|
121
|
+
"pending_intent": None}) if first else current)
|
|
122
|
+
prepared = next_transition(before, config)
|
|
123
|
+
if (prepared is None or not prepared.intents
|
|
124
|
+
or prepared.intents[0].kind != "tool"):
|
|
125
|
+
return None
|
|
126
|
+
intent = prepared.intents[0]
|
|
127
|
+
if first and intent.operation_key != current.pending_intent:
|
|
128
|
+
return None
|
|
129
|
+
current = prepared.snapshot
|
|
130
|
+
calls = intent.payload.get("calls") or [intent.payload["call"]]
|
|
131
|
+
# Only synthetic result shapes enter these detached reducers. The
|
|
132
|
+
# parent intent owns its child intents; never price them as separate
|
|
133
|
+
# tool groups or execute their ports while making this estimate.
|
|
134
|
+
results = [ToolResult(status="ok", content={"capacity_call": call["call_id"]})
|
|
135
|
+
for call in calls]
|
|
136
|
+
if intent.payload.get("parallel_readonly") is True:
|
|
137
|
+
updated = reduce_parallel_readonly_tools(
|
|
138
|
+
current, ToolResult(status="ok", content={
|
|
139
|
+
"batch_results": [result.model_dump(mode="json") for result in results],
|
|
140
|
+
}), calls, definitions=config.tools,
|
|
141
|
+
)
|
|
142
|
+
else:
|
|
143
|
+
updated = reduce_tool(current, results[0], definition=installed[0])
|
|
144
|
+
current = commit_transition(current, updated, "effect.received").snapshot
|
|
145
|
+
first = False
|
|
146
|
+
completed = next_transition(current, config)
|
|
147
|
+
if completed is None or completed.snapshot.phase != RunPhase.PREPARING_CONTEXT:
|
|
148
|
+
return None
|
|
149
|
+
current = completed.snapshot
|
|
150
|
+
fixed = []
|
|
151
|
+
# Novelty can advance anywhere from zero to the remaining call count. A
|
|
152
|
+
# real tokenizer need not assign monotonic costs across numeric digit runs.
|
|
153
|
+
for progress in range(snapshot.observed_progress_revision,
|
|
154
|
+
snapshot.observed_progress_revision + remaining + 1):
|
|
155
|
+
projected = current.model_copy(update={"observed_progress_revision": progress})
|
|
156
|
+
fixed.append(planner.fixed_request_cost(
|
|
157
|
+
instructions=model_instructions(projected, config),
|
|
158
|
+
continuity=driver.continuity(projected, config), contract=config.contract,
|
|
159
|
+
tools=model_tool_surface(projected, config),
|
|
160
|
+
turn_control=model_turn_control(projected, config),
|
|
161
|
+
))
|
|
162
|
+
profile = config.profile
|
|
163
|
+
def count(message):
|
|
164
|
+
return planner.count_model_message(message, profile)
|
|
165
|
+
|
|
166
|
+
goal = {"role": "user", "content": snapshot.goal}
|
|
167
|
+
# Existing sealed receipts are still in this original group. They cannot
|
|
168
|
+
# disappear from the denominator or be silently charged as older history.
|
|
169
|
+
size = len(declared["tool_calls"])
|
|
170
|
+
available = (profile.context_window - profile.max_output_tokens - max(fixed)
|
|
171
|
+
- count(goal) - count(declared)
|
|
172
|
+
- sum(count(m) for m in snapshot.messages if m.get("role") == "system"))
|
|
173
|
+
results = min(available - planner.summary_reservation(profile),
|
|
174
|
+
planner.policy.read_working_set_max_tokens - count(declared),
|
|
175
|
+
planner.policy.read_working_set_total_max_tokens - count(declared))
|
|
176
|
+
result_units = min(results // size,
|
|
177
|
+
(results - sum(count(m) for m in sealed)) // remaining)
|
|
178
|
+
return ArtifactGroupCapacity(
|
|
179
|
+
source_units=available // 2 // size, result_message_units=result_units,
|
|
180
|
+
fixed_tokens=max(fixed), summary_tokens=planner.summary_reservation(profile),
|
|
181
|
+
group_size=size,
|
|
182
|
+
)
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
"""Pure, reserved host artifact-reader contract; no adapter or storage effects."""
|
|
2
|
+
|
|
3
|
+
from .ports import ToolDefinition
|
|
4
|
+
|
|
5
|
+
ARTIFACT_READ_NAME = "ArtifactRead"
|
|
6
|
+
ARTIFACT_READ_DEFINITION = ToolDefinition(
|
|
7
|
+
name=ARTIFACT_READ_NAME,
|
|
8
|
+
description=(
|
|
9
|
+
"Read a bounded character page from a host-owned ArtifactRef supplied with user input "
|
|
10
|
+
"or returned by an earlier tool call in this session. Continue with next_offset_chars "
|
|
11
|
+
"until complete."
|
|
12
|
+
),
|
|
13
|
+
parameters={
|
|
14
|
+
"type": "object",
|
|
15
|
+
"properties": {
|
|
16
|
+
"uri": {"type": "string", "minLength": 1},
|
|
17
|
+
"offset_chars": {"type": "integer", "minimum": 0},
|
|
18
|
+
"limit_chars": {"type": "integer", "minimum": 1, "maximum": 32000},
|
|
19
|
+
},
|
|
20
|
+
"required": ["uri"],
|
|
21
|
+
"additionalProperties": False,
|
|
22
|
+
},
|
|
23
|
+
read_only=True,
|
|
24
|
+
concurrent_safe=True,
|
|
25
|
+
progress_observation=True,
|
|
26
|
+
context_role="artifact_read",
|
|
27
|
+
)
|
|
@@ -0,0 +1,408 @@
|
|
|
1
|
+
"""Runtime-owned large tool result governance.
|
|
2
|
+
|
|
3
|
+
The tool effect remains successful when its observation is too large for model
|
|
4
|
+
context. Exact text is persisted through an injected ArtifactPort; only a
|
|
5
|
+
bounded preview and a typed host reference enter the model view. An explicitly
|
|
6
|
+
locked v3 policy also retains original content in the canonical receipt for
|
|
7
|
+
historical compaction. Artifact I/O stays outside reducers and never grants
|
|
8
|
+
completion or verification authority.
|
|
9
|
+
"""
|
|
10
|
+
|
|
11
|
+
from __future__ import annotations
|
|
12
|
+
|
|
13
|
+
import hashlib
|
|
14
|
+
import json
|
|
15
|
+
|
|
16
|
+
from ksadk.tools.artifact_observation import (
|
|
17
|
+
ARCHIVE_MODEL_POLICY,
|
|
18
|
+
ARCHIVE_SEARCH_MODEL_POLICY,
|
|
19
|
+
CANONICAL_ARCHIVE_MODEL_POLICY,
|
|
20
|
+
OBSERVED_ARCHIVE_MODEL_POLICY,
|
|
21
|
+
SOURCE_ARCHIVE_MODEL_POLICY,
|
|
22
|
+
archived_observation,
|
|
23
|
+
)
|
|
24
|
+
from ksadk.tools.captured_source_artifact import CAPTURED_SOURCE_MIME, encode_captured_source
|
|
25
|
+
|
|
26
|
+
from .model import ModelImageContent, ModelTextContent
|
|
27
|
+
from .ports import (
|
|
28
|
+
ArtifactPort,
|
|
29
|
+
ArtifactRef,
|
|
30
|
+
ArtifactWriteRequest,
|
|
31
|
+
ToolModelObservation,
|
|
32
|
+
ToolRequest,
|
|
33
|
+
ToolResult,
|
|
34
|
+
)
|
|
35
|
+
|
|
36
|
+
_ARTIFACT_MIME = "application/vnd.ksadk.tool-result+json"
|
|
37
|
+
_MAX_IMAGES = 8
|
|
38
|
+
|
|
39
|
+
|
|
40
|
+
def _json(value: object) -> str:
|
|
41
|
+
return json.dumps(value, ensure_ascii=False, sort_keys=True, separators=(",", ":"))
|
|
42
|
+
|
|
43
|
+
|
|
44
|
+
def _text_payload(result: ToolResult) -> str:
|
|
45
|
+
return _json(
|
|
46
|
+
{
|
|
47
|
+
"status": result.status,
|
|
48
|
+
"content": result.content,
|
|
49
|
+
"content_blocks": [
|
|
50
|
+
block.model_dump(mode="json")
|
|
51
|
+
for block in result.content_blocks
|
|
52
|
+
if not isinstance(block, ModelImageContent)
|
|
53
|
+
],
|
|
54
|
+
}
|
|
55
|
+
)
|
|
56
|
+
|
|
57
|
+
|
|
58
|
+
def _preview(text: str, max_bytes: int) -> str:
|
|
59
|
+
encoded = text.encode("utf-8")
|
|
60
|
+
budget = max(64, min(8192, max_bytes // 3))
|
|
61
|
+
if len(encoded) <= budget:
|
|
62
|
+
return text
|
|
63
|
+
half = max(1, budget // 2)
|
|
64
|
+
return (
|
|
65
|
+
encoded[:half].decode("utf-8", errors="ignore")
|
|
66
|
+
+ "\n…[middle omitted]…\n"
|
|
67
|
+
+ encoded[-half:].decode("utf-8", errors="ignore")
|
|
68
|
+
)
|
|
69
|
+
|
|
70
|
+
|
|
71
|
+
def _valid_ref(ref: ArtifactRef, content: str, mime_type: str = _ARTIFACT_MIME) -> bool:
|
|
72
|
+
encoded = content.encode("utf-8")
|
|
73
|
+
return (
|
|
74
|
+
ref.size_bytes == len(encoded)
|
|
75
|
+
and ref.content_hash == "sha256:" + hashlib.sha256(encoded).hexdigest()
|
|
76
|
+
and ref.mime_type == mime_type
|
|
77
|
+
)
|
|
78
|
+
|
|
79
|
+
|
|
80
|
+
def _bounded_content(content: dict, status: str, max_bytes: int) -> dict:
|
|
81
|
+
"""Reserve disclosure and the locator before fitting a text preview."""
|
|
82
|
+
|
|
83
|
+
def size(value: dict) -> int:
|
|
84
|
+
# The reducer uses the ordinary JSON envelope, including its spaces.
|
|
85
|
+
return len(json.dumps({"status": status, "content": value}, ensure_ascii=False).encode())
|
|
86
|
+
|
|
87
|
+
if size(content) <= max_bytes:
|
|
88
|
+
return content
|
|
89
|
+
compact = {key: value for key, value in content.items() if key != "preview"}
|
|
90
|
+
if "artifact" in compact:
|
|
91
|
+
compact["artifact"] = {"uri": compact["artifact"]["uri"]}
|
|
92
|
+
compact["instruction"] = "Use ArtifactRead to read the saved text."
|
|
93
|
+
else:
|
|
94
|
+
compact["instruction"] = "Use a narrower request to read the full text."
|
|
95
|
+
if "media_observation" in compact:
|
|
96
|
+
compact["media_observation"] = {
|
|
97
|
+
"image_observation_status": "not_observed",
|
|
98
|
+
"instruction": compact["media_observation"]["instruction"],
|
|
99
|
+
}
|
|
100
|
+
if size(compact) > max_bytes:
|
|
101
|
+
# A locator which cannot fit must not be admitted as available.
|
|
102
|
+
raise ValueError("artifact disclosure exceeds result budget")
|
|
103
|
+
preview = content.get("preview", "")
|
|
104
|
+
low, high = 0, len(preview)
|
|
105
|
+
while low < high:
|
|
106
|
+
mid = (low + high + 1) // 2
|
|
107
|
+
candidate = {**compact, "preview": preview[:mid] + "…"}
|
|
108
|
+
if size(candidate) <= max_bytes:
|
|
109
|
+
low = mid
|
|
110
|
+
else:
|
|
111
|
+
high = mid - 1
|
|
112
|
+
return {**compact, "preview": preview[:low] + "…"} if low else compact
|
|
113
|
+
|
|
114
|
+
|
|
115
|
+
async def govern_tool_result(
|
|
116
|
+
*,
|
|
117
|
+
request: ToolRequest,
|
|
118
|
+
result: ToolResult,
|
|
119
|
+
artifacts: ArtifactPort | None,
|
|
120
|
+
max_result_bytes: int,
|
|
121
|
+
max_image_bytes: int,
|
|
122
|
+
) -> ToolResult:
|
|
123
|
+
"""Return a detached, bounded model observation with trusted refs only."""
|
|
124
|
+
|
|
125
|
+
# ArtifactRef is runtime authority. A tool callback may return similarly
|
|
126
|
+
# shaped JSON as content, but cannot add to the trusted snapshot ledger.
|
|
127
|
+
clean = ToolResult.model_validate_json(
|
|
128
|
+
result.model_copy(update={"artifact_refs": ()}).model_dump_json()
|
|
129
|
+
)
|
|
130
|
+
if request.definition.result_disclosure_policy == "mcp-default/v1":
|
|
131
|
+
from .mcp_result_governance import govern_mcp_disclosure
|
|
132
|
+
|
|
133
|
+
governed = await govern_mcp_disclosure(
|
|
134
|
+
request=request, result=clean, artifacts=artifacts, payload=_text_payload(clean),
|
|
135
|
+
max_result_bytes=max_result_bytes, max_image_bytes=max_image_bytes,
|
|
136
|
+
)
|
|
137
|
+
if governed is not None:
|
|
138
|
+
return governed
|
|
139
|
+
if clean.model_observation is not None:
|
|
140
|
+
if request.definition.result_model_policy == clean.model_observation.version:
|
|
141
|
+
return await _govern_typed_observation(
|
|
142
|
+
request=request, result=clean, artifacts=artifacts,
|
|
143
|
+
max_result_bytes=min(max_result_bytes, 65536), max_image_bytes=max_image_bytes,
|
|
144
|
+
)
|
|
145
|
+
# Missing host policy cannot grant an alternate view. Fall back to
|
|
146
|
+
# governance of the original known result, without repeating its effect.
|
|
147
|
+
clean = clean.model_copy(update={"model_observation": None})
|
|
148
|
+
images = tuple(block for block in clean.content_blocks if isinstance(block, ModelImageContent))
|
|
149
|
+
media_bytes = sum(len(_json(image.model_dump(mode="json")).encode("utf-8")) for image in images)
|
|
150
|
+
media_observation = None
|
|
151
|
+
if media_bytes > max_image_bytes or len(images) > _MAX_IMAGES:
|
|
152
|
+
# Refuse the images, not the already observed execution fact. Turning
|
|
153
|
+
# a successful mutation into an error here invites duplicate effects.
|
|
154
|
+
media_observation = {
|
|
155
|
+
"code": "tool_media_too_large",
|
|
156
|
+
"image_observation_status": "not_observed",
|
|
157
|
+
"image_count": len(images),
|
|
158
|
+
"original_bytes": media_bytes,
|
|
159
|
+
"limit_bytes": max_image_bytes,
|
|
160
|
+
"instruction": (
|
|
161
|
+
"Images were not observed (media budget). Do not repeat solely for missing "
|
|
162
|
+
"images; use a smaller read-only observation."
|
|
163
|
+
),
|
|
164
|
+
}
|
|
165
|
+
model_content = clean.model_content
|
|
166
|
+
if model_content is not None:
|
|
167
|
+
try:
|
|
168
|
+
view = json.loads(model_content)
|
|
169
|
+
except ValueError:
|
|
170
|
+
view = None
|
|
171
|
+
model_content = (
|
|
172
|
+
_json({**view, "media_observation": media_observation})
|
|
173
|
+
if isinstance(view, dict)
|
|
174
|
+
else model_content + "\n" + _json(media_observation)
|
|
175
|
+
)
|
|
176
|
+
clean = clean.model_copy(
|
|
177
|
+
update={
|
|
178
|
+
"model_content": model_content,
|
|
179
|
+
"content_blocks": (
|
|
180
|
+
*(b for b in clean.content_blocks if not isinstance(b, ModelImageContent)),
|
|
181
|
+
ModelTextContent(text=_json(media_observation)),
|
|
182
|
+
),
|
|
183
|
+
}
|
|
184
|
+
)
|
|
185
|
+
images = ()
|
|
186
|
+
# A callback cannot use the alternate model view to bypass this Run's
|
|
187
|
+
# observation budget when the auditable raw result happens to be small.
|
|
188
|
+
# The omission disclosure above must fit this same bound.
|
|
189
|
+
if clean.model_content is not None and len(clean.model_content.encode("utf-8")) > min(
|
|
190
|
+
max_result_bytes, 65536
|
|
191
|
+
):
|
|
192
|
+
clean = clean.model_copy(update={"model_content": None})
|
|
193
|
+
|
|
194
|
+
payload = _text_payload(clean)
|
|
195
|
+
original_bytes = len(payload.encode("utf-8"))
|
|
196
|
+
archive_required = (
|
|
197
|
+
request.definition.result_archive_policy
|
|
198
|
+
in {
|
|
199
|
+
ARCHIVE_MODEL_POLICY,
|
|
200
|
+
ARCHIVE_SEARCH_MODEL_POLICY,
|
|
201
|
+
CANONICAL_ARCHIVE_MODEL_POLICY,
|
|
202
|
+
OBSERVED_ARCHIVE_MODEL_POLICY,
|
|
203
|
+
SOURCE_ARCHIVE_MODEL_POLICY,
|
|
204
|
+
}
|
|
205
|
+
and clean.status == "ok"
|
|
206
|
+
)
|
|
207
|
+
preserve_view = archive_required and clean.model_content is not None
|
|
208
|
+
archive_policy = request.definition.result_archive_policy or ARCHIVE_MODEL_POLICY
|
|
209
|
+
archive_payload, archive_mime = payload, _ARTIFACT_MIME
|
|
210
|
+
if archive_policy == SOURCE_ARCHIVE_MODEL_POLICY:
|
|
211
|
+
source = encode_captured_source(clean.content)
|
|
212
|
+
if source is not None:
|
|
213
|
+
archive_payload, archive_mime = source, CAPTURED_SOURCE_MIME
|
|
214
|
+
if preserve_view:
|
|
215
|
+
try:
|
|
216
|
+
archived_observation(clean.model_content, None, policy=archive_policy)
|
|
217
|
+
except (ValueError, TypeError):
|
|
218
|
+
preserve_view = False
|
|
219
|
+
if original_bytes <= max_result_bytes and not archive_required:
|
|
220
|
+
return clean
|
|
221
|
+
|
|
222
|
+
def offloaded_content(ref: ArtifactRef | None) -> dict:
|
|
223
|
+
content = {
|
|
224
|
+
"code": "tool_result_offloaded" if ref is not None else "tool_result_truncated",
|
|
225
|
+
"execution_status": clean.status,
|
|
226
|
+
"original_bytes": original_bytes,
|
|
227
|
+
"preview": _preview(
|
|
228
|
+
clean.model_content if preserve_view else payload, max_result_bytes
|
|
229
|
+
),
|
|
230
|
+
"artifact_state": "available" if ref is not None else "unavailable",
|
|
231
|
+
"instruction": (
|
|
232
|
+
"Use ArtifactRead with the artifact URI to read bounded pages."
|
|
233
|
+
if ref is not None
|
|
234
|
+
else "The full result could not be persisted; use a narrower tool request."
|
|
235
|
+
),
|
|
236
|
+
}
|
|
237
|
+
if ref is not None:
|
|
238
|
+
content["artifact"] = ref.model_dump(mode="json")
|
|
239
|
+
else:
|
|
240
|
+
content["limit_bytes"] = max_result_bytes
|
|
241
|
+
if media_observation is not None:
|
|
242
|
+
content["media_observation"] = media_observation
|
|
243
|
+
return _bounded_content(content, clean.status, max_result_bytes)
|
|
244
|
+
|
|
245
|
+
ref: ArtifactRef | None = None
|
|
246
|
+
if artifacts is not None:
|
|
247
|
+
try:
|
|
248
|
+
written = await artifacts.write(
|
|
249
|
+
ArtifactWriteRequest(
|
|
250
|
+
scope=request.scope,
|
|
251
|
+
run_id=request.run_id,
|
|
252
|
+
operation_key=request.operation_key,
|
|
253
|
+
tool_call_id=request.call.call_id,
|
|
254
|
+
tool_name=request.call.name,
|
|
255
|
+
content=archive_payload,
|
|
256
|
+
mime_type=archive_mime,
|
|
257
|
+
)
|
|
258
|
+
)
|
|
259
|
+
candidate = ArtifactRef.model_validate_json(written.model_dump_json())
|
|
260
|
+
if not _valid_ref(candidate, archive_payload, archive_mime):
|
|
261
|
+
raise ValueError("artifact receipt does not bind persisted content")
|
|
262
|
+
if preserve_view:
|
|
263
|
+
# Validate the complete bounded projection before admitting the
|
|
264
|
+
# reference. An invalid/overlong locator must not enter context.
|
|
265
|
+
projected = archived_observation(
|
|
266
|
+
clean.model_content, candidate.uri, policy=archive_policy
|
|
267
|
+
)
|
|
268
|
+
if len(projected.encode("utf-8")) > max_result_bytes:
|
|
269
|
+
raise ValueError("archive model view exceeds result budget")
|
|
270
|
+
else:
|
|
271
|
+
offloaded_content(candidate)
|
|
272
|
+
ref = candidate
|
|
273
|
+
except Exception:
|
|
274
|
+
# ZCode's result serialization falls back to bounded truncation when
|
|
275
|
+
# persistence fails. Preserve the actual execution status and never
|
|
276
|
+
# leak the full payload into context.
|
|
277
|
+
pass
|
|
278
|
+
|
|
279
|
+
content = offloaded_content(ref)
|
|
280
|
+
model_content = (
|
|
281
|
+
archived_observation(
|
|
282
|
+
clean.model_content, ref.uri if ref is not None else None, policy=archive_policy
|
|
283
|
+
)
|
|
284
|
+
if preserve_view
|
|
285
|
+
else None
|
|
286
|
+
)
|
|
287
|
+
if model_content is not None and len(model_content.encode("utf-8")) > max_result_bytes:
|
|
288
|
+
model_content = None
|
|
289
|
+
canonical = (
|
|
290
|
+
archive_policy
|
|
291
|
+
in {
|
|
292
|
+
CANONICAL_ARCHIVE_MODEL_POLICY,
|
|
293
|
+
OBSERVED_ARCHIVE_MODEL_POLICY,
|
|
294
|
+
SOURCE_ARCHIVE_MODEL_POLICY,
|
|
295
|
+
}
|
|
296
|
+
and clean.status == "ok"
|
|
297
|
+
)
|
|
298
|
+
if canonical and model_content is None:
|
|
299
|
+
model_content = _json({"status": clean.status, "content": content})
|
|
300
|
+
observation_digest = clean.progress_observation_digest
|
|
301
|
+
if observation_digest is None and preserve_view:
|
|
302
|
+
# A newly issued storage locator is not new source evidence. Compare
|
|
303
|
+
# the original model observation, excluding this operation's URI.
|
|
304
|
+
observation_digest = (
|
|
305
|
+
"sha256:"
|
|
306
|
+
+ hashlib.sha256(_json(json.loads(clean.model_content)).encode("utf-8")).hexdigest()
|
|
307
|
+
)
|
|
308
|
+
return ToolResult(
|
|
309
|
+
status=clean.status,
|
|
310
|
+
progress_observation_digest=observation_digest,
|
|
311
|
+
content=clean.content if canonical else content,
|
|
312
|
+
model_content=model_content,
|
|
313
|
+
content_blocks=clean.content_blocks if canonical else images,
|
|
314
|
+
artifact_refs=(ref,) if ref is not None else (),
|
|
315
|
+
resource_usage=clean.resource_usage,
|
|
316
|
+
child_budget_reservation=clean.child_budget_reservation,
|
|
317
|
+
child_budget_settlement=clean.child_budget_settlement,
|
|
318
|
+
workspace_changed_paths=clean.workspace_changed_paths,
|
|
319
|
+
browser_session_ref=clean.browser_session_ref,
|
|
320
|
+
browser_session_closed=clean.browser_session_closed,
|
|
321
|
+
interaction_id=clean.interaction_id,
|
|
322
|
+
)
|
|
323
|
+
|
|
324
|
+
|
|
325
|
+
async def _govern_typed_observation(
|
|
326
|
+
*, request: ToolRequest, result: ToolResult, artifacts: ArtifactPort | None,
|
|
327
|
+
max_result_bytes: int, max_image_bytes: int,
|
|
328
|
+
) -> ToolResult:
|
|
329
|
+
observation = result.model_observation
|
|
330
|
+
images = tuple(b for b in observation.content_blocks if isinstance(b, ModelImageContent))
|
|
331
|
+
media_bytes = sum(len(_json(b.model_dump(mode="json")).encode()) for b in images)
|
|
332
|
+
warning = None
|
|
333
|
+
if media_bytes > max_image_bytes or len(images) > _MAX_IMAGES:
|
|
334
|
+
warning = {
|
|
335
|
+
"image_observation_status": "not_observed",
|
|
336
|
+
"instruction": "Images were not observed. Do not repeat solely for missing images.",
|
|
337
|
+
}
|
|
338
|
+
content = {"observation": observation.content, "media_observation": warning}
|
|
339
|
+
observation = observation.model_copy(update={
|
|
340
|
+
"content": content,
|
|
341
|
+
"content_blocks": tuple(
|
|
342
|
+
b for b in observation.content_blocks if not isinstance(b, ModelImageContent)
|
|
343
|
+
),
|
|
344
|
+
})
|
|
345
|
+
images = ()
|
|
346
|
+
|
|
347
|
+
def text_size(value: ToolModelObservation) -> int:
|
|
348
|
+
return len(json.dumps({"status": value.status, "content": value.content},
|
|
349
|
+
ensure_ascii=False).encode()) + sum(
|
|
350
|
+
len(_json(b.model_dump(mode="json")).encode()) + 1
|
|
351
|
+
for b in value.content_blocks if isinstance(b, ModelTextContent)
|
|
352
|
+
)
|
|
353
|
+
|
|
354
|
+
raw = _text_payload(result)
|
|
355
|
+
original_bytes = len(raw.encode())
|
|
356
|
+
if original_bytes <= max_result_bytes and text_size(observation) <= max_result_bytes:
|
|
357
|
+
return result.model_copy(update={"model_observation": observation})
|
|
358
|
+
|
|
359
|
+
# The saved receipt is exact. The model preview comes from the textual
|
|
360
|
+
# observation, never from the raw envelope containing binary base64.
|
|
361
|
+
preview_source = json.dumps(observation.content, ensure_ascii=False) + "\n" + "\n".join(
|
|
362
|
+
b.text for b in observation.content_blocks if isinstance(b, ModelTextContent)
|
|
363
|
+
)
|
|
364
|
+
|
|
365
|
+
def bounded(ref: ArtifactRef | None) -> ToolModelObservation:
|
|
366
|
+
content = {
|
|
367
|
+
"code": "tool_result_offloaded" if ref is not None else "tool_result_truncated",
|
|
368
|
+
"execution_status": result.status,
|
|
369
|
+
"artifact_state": "available" if ref is not None else "unavailable",
|
|
370
|
+
"original_bytes": original_bytes,
|
|
371
|
+
"preview": _preview(preview_source, max_result_bytes),
|
|
372
|
+
"instruction": (
|
|
373
|
+
"Use ArtifactRead to read the saved result; binary JSON is not visual evidence."
|
|
374
|
+
if ref is not None
|
|
375
|
+
else "Full result unavailable; use a narrower read-only observation."
|
|
376
|
+
),
|
|
377
|
+
}
|
|
378
|
+
if ref is not None:
|
|
379
|
+
content["artifact"] = ref.model_dump(mode="json")
|
|
380
|
+
if warning is not None:
|
|
381
|
+
content["media_observation"] = warning
|
|
382
|
+
return ToolModelObservation(
|
|
383
|
+
status=result.status,
|
|
384
|
+
content=_bounded_content(content, result.status, max_result_bytes),
|
|
385
|
+
content_blocks=images,
|
|
386
|
+
)
|
|
387
|
+
|
|
388
|
+
ref = None
|
|
389
|
+
if artifacts is not None:
|
|
390
|
+
try:
|
|
391
|
+
written = await artifacts.write(ArtifactWriteRequest(
|
|
392
|
+
scope=request.scope, run_id=request.run_id, operation_key=request.operation_key,
|
|
393
|
+
tool_call_id=request.call.call_id, tool_name=request.call.name,
|
|
394
|
+
content=raw, mime_type=_ARTIFACT_MIME,
|
|
395
|
+
))
|
|
396
|
+
candidate = ArtifactRef.model_validate_json(written.model_dump_json())
|
|
397
|
+
if not _valid_ref(candidate, raw):
|
|
398
|
+
raise ValueError("artifact receipt does not bind persisted content")
|
|
399
|
+
bounded(candidate)
|
|
400
|
+
ref = candidate
|
|
401
|
+
except Exception:
|
|
402
|
+
pass
|
|
403
|
+
return result.model_copy(update={
|
|
404
|
+
"model_observation": bounded(ref), "artifact_refs": (ref,) if ref is not None else (),
|
|
405
|
+
})
|
|
406
|
+
|
|
407
|
+
|
|
408
|
+
__all__ = ["govern_tool_result"]
|