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,151 @@
|
|
|
1
|
+
"""Durable Stop proposals before final verification, without completion grants."""
|
|
2
|
+
|
|
3
|
+
from __future__ import annotations
|
|
4
|
+
|
|
5
|
+
import json
|
|
6
|
+
from typing import TYPE_CHECKING
|
|
7
|
+
|
|
8
|
+
from pydantic import Field, JsonValue
|
|
9
|
+
|
|
10
|
+
from .completion_text import candidate_model_message
|
|
11
|
+
from .hook_runtime_contract import (
|
|
12
|
+
HookInvocationRequest,
|
|
13
|
+
HookInvocationResult,
|
|
14
|
+
_json_bytes,
|
|
15
|
+
validate_hook_result,
|
|
16
|
+
)
|
|
17
|
+
from .state import Contract, RunPhase, RunSnapshot, move
|
|
18
|
+
from .transitions import finish, prepare_effect
|
|
19
|
+
|
|
20
|
+
if TYPE_CHECKING:
|
|
21
|
+
from .ports import RunConfiguration
|
|
22
|
+
|
|
23
|
+
|
|
24
|
+
class StopHookState(Contract):
|
|
25
|
+
goal_revision: int = Field(strict=True, ge=0)
|
|
26
|
+
candidate_id: str | None = None
|
|
27
|
+
next_hook_index: int = Field(default=0, strict=True, ge=0)
|
|
28
|
+
continuation_count: int = Field(default=0, strict=True, ge=0)
|
|
29
|
+
feedback: tuple[dict[str, JsonValue], ...] = ()
|
|
30
|
+
|
|
31
|
+
|
|
32
|
+
def stop_hook_state(snapshot: RunSnapshot) -> StopHookState:
|
|
33
|
+
if snapshot.stop_hook_state is not None:
|
|
34
|
+
state = StopHookState.model_validate_json(_json_bytes(snapshot.stop_hook_state))
|
|
35
|
+
if state.goal_revision == snapshot.goal_revision:
|
|
36
|
+
return state
|
|
37
|
+
return StopHookState(goal_revision=snapshot.goal_revision)
|
|
38
|
+
|
|
39
|
+
|
|
40
|
+
def hook_feedback_messages(snapshot: RunSnapshot, messages: tuple[dict, ...]) -> tuple[dict, ...]:
|
|
41
|
+
"""Reproject pending feedback before context budgeting, even after pruning."""
|
|
42
|
+
state = stop_hook_state(snapshot)
|
|
43
|
+
seen = {message.get("hook_operation_key") for message in messages}
|
|
44
|
+
return (*messages, *(item for item in state.feedback
|
|
45
|
+
if item["hook_operation_key"] not in seen))
|
|
46
|
+
|
|
47
|
+
|
|
48
|
+
def stop_hook_request(
|
|
49
|
+
snapshot: RunSnapshot, config: RunConfiguration, operation_key: str,
|
|
50
|
+
) -> HookInvocationRequest:
|
|
51
|
+
candidate = snapshot.candidate or {}
|
|
52
|
+
if (snapshot.phase != RunPhase.VERIFYING or candidate.get("purpose") == "checkpoint"
|
|
53
|
+
or not candidate.get("candidate_id") or "final_text" not in candidate):
|
|
54
|
+
raise ValueError("Stop requires a final completion candidate")
|
|
55
|
+
state = stop_hook_state(snapshot)
|
|
56
|
+
index = state.next_hook_index if state.candidate_id == candidate["candidate_id"] else 0
|
|
57
|
+
hooks = tuple(hook for hook in config.hooks if "Stop" in hook.events)
|
|
58
|
+
if index >= len(hooks):
|
|
59
|
+
raise ValueError("no pending Stop Hook")
|
|
60
|
+
return HookInvocationRequest(
|
|
61
|
+
scope=snapshot.scope, run_id=snapshot.run_id, session_id=snapshot.session_id,
|
|
62
|
+
turn_id=snapshot.turn_id, operation_key=operation_key,
|
|
63
|
+
goal_revision=snapshot.goal_revision, goal=snapshot.goal,
|
|
64
|
+
tool_call_count=snapshot.tool_calls, stop_continuation_count=state.continuation_count,
|
|
65
|
+
event="Stop", definition=hooks[index],
|
|
66
|
+
candidate_id=candidate["candidate_id"], candidate_text=candidate["final_text"],
|
|
67
|
+
)
|
|
68
|
+
|
|
69
|
+
|
|
70
|
+
def prepare_stop_hook(snapshot: RunSnapshot, config: RunConfiguration):
|
|
71
|
+
candidate = snapshot.candidate or {}
|
|
72
|
+
if (snapshot.phase != RunPhase.VERIFYING or snapshot.browser_reobservation_required
|
|
73
|
+
or candidate.get("purpose") == "checkpoint"):
|
|
74
|
+
return None
|
|
75
|
+
hooks = tuple(hook for hook in config.hooks if "Stop" in hook.events)
|
|
76
|
+
if not hooks:
|
|
77
|
+
return None
|
|
78
|
+
state = stop_hook_state(snapshot)
|
|
79
|
+
index = state.next_hook_index if state.candidate_id == candidate.get("candidate_id") else 0
|
|
80
|
+
if index >= len(hooks):
|
|
81
|
+
return None
|
|
82
|
+
key = f"{snapshot.run_id}:effect:{snapshot.revision + 1}"
|
|
83
|
+
request = stop_hook_request(snapshot, config, key)
|
|
84
|
+
return prepare_effect(snapshot, "hook", {"request": request.model_dump(mode="json")})
|
|
85
|
+
|
|
86
|
+
|
|
87
|
+
def reduce_stop_hook(
|
|
88
|
+
snapshot: RunSnapshot, config: RunConfiguration, operation_key: str, result: dict,
|
|
89
|
+
) -> RunSnapshot:
|
|
90
|
+
request = stop_hook_request(snapshot, config, operation_key)
|
|
91
|
+
result = validate_hook_result(request, HookInvocationResult.model_validate(result))
|
|
92
|
+
state = stop_hook_state(snapshot)
|
|
93
|
+
index = state.next_hook_index if state.candidate_id == request.candidate_id else 0
|
|
94
|
+
state = state.model_copy(update={"candidate_id": request.candidate_id,
|
|
95
|
+
"next_hook_index": index + 1})
|
|
96
|
+
updated = snapshot.model_copy(update={"pending_intent": None})
|
|
97
|
+
if result.status == "uncertain" or result.reason == "binding_unavailable":
|
|
98
|
+
return finish(updated.model_copy(update={"candidate": None}),
|
|
99
|
+
"unverified", "effect_outcome_unknown")
|
|
100
|
+
if result.status == "failed":
|
|
101
|
+
optional_failure = result.reason in {
|
|
102
|
+
"producer_failed", "producer_invalid", "producer_timeout",
|
|
103
|
+
"input_budget_exceeded", "output_budget_exceeded",
|
|
104
|
+
}
|
|
105
|
+
if not optional_failure or request.definition.failure_mode != "warn":
|
|
106
|
+
return finish(updated.model_copy(update={"candidate": None}),
|
|
107
|
+
"blocked", "hook_" + result.reason)
|
|
108
|
+
else:
|
|
109
|
+
output = result.output
|
|
110
|
+
if output.action == "deny":
|
|
111
|
+
return finish(updated.model_copy(update={"candidate": None}),
|
|
112
|
+
"blocked", "stop_hook_denied")
|
|
113
|
+
if output.additional_context or output.action == "repair":
|
|
114
|
+
message = {
|
|
115
|
+
"role": "user", "kind": "hook_context", "hook_operation_key": operation_key,
|
|
116
|
+
"hook_goal_revision": snapshot.goal_revision,
|
|
117
|
+
"content": json.dumps({
|
|
118
|
+
"event": "Stop", "hook_id": request.definition.hook_id,
|
|
119
|
+
"source_ref": request.definition.source_ref,
|
|
120
|
+
"binding_digest": request.definition.binding_digest,
|
|
121
|
+
"action": output.action,
|
|
122
|
+
"candidate_status": "rejected" if output.action == "repair" else "unverified",
|
|
123
|
+
"data": output.additional_context,
|
|
124
|
+
}, ensure_ascii=False, sort_keys=True),
|
|
125
|
+
}
|
|
126
|
+
state = state.model_copy(update={"feedback": (*state.feedback, message)})
|
|
127
|
+
updated = updated.model_copy(update={"messages": (*updated.messages, message)})
|
|
128
|
+
if not request.definition.read_only:
|
|
129
|
+
updated = updated.model_copy(update={"workspace_observation_cursor": None})
|
|
130
|
+
if output.action == "repair":
|
|
131
|
+
limit = config.hook_stop_continuation_limit
|
|
132
|
+
if limit is None or state.continuation_count >= limit:
|
|
133
|
+
return finish(updated.model_copy(update={"candidate": None}),
|
|
134
|
+
"blocked", "stop_hook_continuation_limit")
|
|
135
|
+
state = state.model_copy(update={
|
|
136
|
+
"candidate_id": None, "next_hook_index": 0,
|
|
137
|
+
"continuation_count": state.continuation_count + 1,
|
|
138
|
+
})
|
|
139
|
+
updated = move(updated, RunPhase.PREPARING_CONTEXT).model_copy(update={
|
|
140
|
+
"messages": (
|
|
141
|
+
*snapshot.messages,
|
|
142
|
+
candidate_model_message(snapshot),
|
|
143
|
+
*updated.messages[len(snapshot.messages):],
|
|
144
|
+
),
|
|
145
|
+
"candidate": None, "candidate_replay": None, "prepared_context": None,
|
|
146
|
+
"verification": None, "verification_tool_calls": None, "delivery_review": None,
|
|
147
|
+
# A Hook repair asks for a new answer, not the rejected
|
|
148
|
+
# candidate's suffix. Its separate Stop cap remains charged.
|
|
149
|
+
"continuations": 0,
|
|
150
|
+
})
|
|
151
|
+
return updated.model_copy(update={"stop_hook_state": state.model_dump(mode="json")})
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
"""Host-frozen Studio Build identity for opt-in Native runtime admission."""
|
|
2
|
+
|
|
3
|
+
from __future__ import annotations
|
|
4
|
+
|
|
5
|
+
import hashlib
|
|
6
|
+
import json
|
|
7
|
+
from collections.abc import Mapping
|
|
8
|
+
from typing import Any
|
|
9
|
+
|
|
10
|
+
from pydantic import Field
|
|
11
|
+
|
|
12
|
+
from .state import Contract
|
|
13
|
+
|
|
14
|
+
|
|
15
|
+
def studio_mapping_digest(value: Mapping[str, Any]) -> str:
|
|
16
|
+
"""Hash only JSON configuration; opaque objects cannot silently pass admission."""
|
|
17
|
+
encoded = json.dumps(
|
|
18
|
+
dict(value), ensure_ascii=False, sort_keys=True, separators=(",", ":"), allow_nan=False
|
|
19
|
+
).encode("utf-8")
|
|
20
|
+
return "sha256:" + hashlib.sha256(encoded).hexdigest()
|
|
21
|
+
|
|
22
|
+
|
|
23
|
+
class StudioAdmission(Contract):
|
|
24
|
+
build_id: str = Field(min_length=1)
|
|
25
|
+
manifest_sha256: str
|
|
26
|
+
model: str = Field(min_length=1)
|
|
27
|
+
project_dir: str = Field(min_length=1)
|
|
28
|
+
launch_config_digest: str = Field(pattern=r"^sha256:[0-9a-f]{64}$")
|
|
29
|
+
request_config_digest: str = Field(pattern=r"^sha256:[0-9a-f]{64}$")
|
|
@@ -0,0 +1,86 @@
|
|
|
1
|
+
"""Host-issued delegation grants and child observations, never parent acceptance."""
|
|
2
|
+
|
|
3
|
+
from __future__ import annotations
|
|
4
|
+
|
|
5
|
+
from typing import Literal
|
|
6
|
+
|
|
7
|
+
from pydantic import Field, model_serializer, model_validator
|
|
8
|
+
|
|
9
|
+
from .ports import ToolBudget
|
|
10
|
+
from .state import Contract, RunScope
|
|
11
|
+
|
|
12
|
+
|
|
13
|
+
class ChildRole(Contract):
|
|
14
|
+
role_id: str = Field(min_length=1, pattern=r"\S")
|
|
15
|
+
description: str
|
|
16
|
+
agent_id: str | None = Field(default=None, min_length=1)
|
|
17
|
+
tool_names: tuple[str, ...] = ()
|
|
18
|
+
workspace_access: Literal["read_only", "isolated_write"] = "read_only"
|
|
19
|
+
concurrent_safe: bool = False
|
|
20
|
+
|
|
21
|
+
|
|
22
|
+
class ChildRunRequest(Contract):
|
|
23
|
+
scope: RunScope
|
|
24
|
+
parent_scope: RunScope
|
|
25
|
+
child_run_id: str
|
|
26
|
+
child_session_id: str
|
|
27
|
+
parent_run_id: str
|
|
28
|
+
parent_tool_call_id: str
|
|
29
|
+
parent_operation_key: str
|
|
30
|
+
task: str = Field(min_length=1, max_length=32000, pattern=r"\S")
|
|
31
|
+
# Immutable initial mode for an explicitly host-declared dual-mode tool.
|
|
32
|
+
# Promotion changes delivery through parent events, not this request.
|
|
33
|
+
delivery_mode: Literal["foreground", "background"] | None = Field(
|
|
34
|
+
default=None, exclude_if=lambda value: value is None
|
|
35
|
+
)
|
|
36
|
+
# A caller-declared delivery type, separate from the prose task and role
|
|
37
|
+
# capability grant. Absence retains the original request wire identity.
|
|
38
|
+
output_format: Literal["text", "json_object"] | None = None
|
|
39
|
+
# Select the host's current parent delivery shape. This does not inherit
|
|
40
|
+
# parent acceptance, tools, budget or any model-selected schema values.
|
|
41
|
+
output_contract: Literal["parent"] | None = None
|
|
42
|
+
# Host-bound source of a fresh turn in an already accounted child Session.
|
|
43
|
+
# It is not a request to reopen the source Run or replay its effects.
|
|
44
|
+
continuation_of: str | None = Field(default=None, min_length=1, max_length=256, pattern=r"\S")
|
|
45
|
+
continuation_parent_run_id: str | None = Field(
|
|
46
|
+
default=None, min_length=1, max_length=256, pattern=r"\S",
|
|
47
|
+
)
|
|
48
|
+
role: ChildRole
|
|
49
|
+
budget: ToolBudget
|
|
50
|
+
|
|
51
|
+
@model_serializer(mode="wrap")
|
|
52
|
+
def omit_unconfigured_output(self, serialize):
|
|
53
|
+
payload = serialize(self)
|
|
54
|
+
if self.output_format is None:
|
|
55
|
+
payload.pop("output_format", None)
|
|
56
|
+
if self.output_contract is None:
|
|
57
|
+
payload.pop("output_contract", None)
|
|
58
|
+
if self.continuation_of is None:
|
|
59
|
+
payload.pop("continuation_of", None)
|
|
60
|
+
if self.continuation_parent_run_id is None:
|
|
61
|
+
payload.pop("continuation_parent_run_id", None)
|
|
62
|
+
return payload
|
|
63
|
+
|
|
64
|
+
@model_validator(mode="after")
|
|
65
|
+
def explicit_parent_delivery(self):
|
|
66
|
+
if self.output_contract is not None and self.output_format != "json_object":
|
|
67
|
+
raise ValueError("parent output contract requires explicit object delivery")
|
|
68
|
+
if (self.continuation_of is None) != (self.continuation_parent_run_id is None):
|
|
69
|
+
raise ValueError("child continuation requires its source parent identity")
|
|
70
|
+
return self
|
|
71
|
+
|
|
72
|
+
|
|
73
|
+
class ChildObservation(Contract):
|
|
74
|
+
schema_version: Literal["ksadk.child-observation/v1"] = "ksadk.child-observation/v1"
|
|
75
|
+
child_run_id: str
|
|
76
|
+
child_scope: RunScope
|
|
77
|
+
parent_run_id: str
|
|
78
|
+
parent_tool_call_id: str
|
|
79
|
+
phase: str
|
|
80
|
+
outcome: str | None = None
|
|
81
|
+
error_code: str | None = None
|
|
82
|
+
final_text: str = ""
|
|
83
|
+
text_truncated: bool = False
|
|
84
|
+
evidence_refs: tuple[str, ...] = ()
|
|
85
|
+
parent_acceptance: Literal["not_evaluated"] = "not_evaluated"
|
|
86
|
+
resource_usage_unknown: bool = False
|
|
@@ -0,0 +1,99 @@
|
|
|
1
|
+
"""Host-pinned task policies layered above generic tool and budget execution.
|
|
2
|
+
|
|
3
|
+
Web observation rules are activated by an explicit configuration. The Kernel
|
|
4
|
+
contains no implicit extension table or model-authored policy authority.
|
|
5
|
+
"""
|
|
6
|
+
|
|
7
|
+
from .ports import RunConfiguration, ToolResult, WorkspaceObservationPolicy
|
|
8
|
+
from .state import RunSnapshot
|
|
9
|
+
|
|
10
|
+
|
|
11
|
+
def invalidates_browser_observation(
|
|
12
|
+
result: ToolResult, policy: WorkspaceObservationPolicy | None
|
|
13
|
+
) -> bool:
|
|
14
|
+
return bool(
|
|
15
|
+
policy
|
|
16
|
+
and any(
|
|
17
|
+
path.lower().endswith(policy.path_suffixes) for path in result.workspace_changed_paths
|
|
18
|
+
)
|
|
19
|
+
)
|
|
20
|
+
|
|
21
|
+
|
|
22
|
+
def browser_observation_available(config: RunConfiguration) -> bool:
|
|
23
|
+
"""Registered capabilities do not override the active goal's tool scope."""
|
|
24
|
+
allowed = config.contract.allowed_tool_names
|
|
25
|
+
return any(
|
|
26
|
+
tool.observation_role == "browser" and (allowed is None or tool.name in allowed)
|
|
27
|
+
for tool in config.tools
|
|
28
|
+
)
|
|
29
|
+
|
|
30
|
+
|
|
31
|
+
def web_verification_only(snapshot: RunSnapshot, config: RunConfiguration) -> bool:
|
|
32
|
+
"""Keep observation available after the last allowed late web mutation.
|
|
33
|
+
|
|
34
|
+
This gate is activated only for a Run that actually changed web files and
|
|
35
|
+
has a browser observation port. The preceding call can still repair; the
|
|
36
|
+
final tool-capable call cannot make its own browser evidence stale.
|
|
37
|
+
"""
|
|
38
|
+
if config.workspace_observation_policy is None:
|
|
39
|
+
return False
|
|
40
|
+
reserve = config.limits.verification_reserve_model_calls
|
|
41
|
+
remaining = (
|
|
42
|
+
config.limits.max_model_calls - snapshot.model_budget_claimed
|
|
43
|
+
)
|
|
44
|
+
return bool(
|
|
45
|
+
reserve > 1
|
|
46
|
+
and config.limits.finalization_reserve_model_calls > 0
|
|
47
|
+
and snapshot.last_web_mutation_tool_call is not None
|
|
48
|
+
and browser_observation_available(config)
|
|
49
|
+
and 0 < remaining < reserve
|
|
50
|
+
and (
|
|
51
|
+
reserve < config.limits.finalization_reserve_model_calls + 4
|
|
52
|
+
or remaining <= config.limits.finalization_reserve_model_calls + 1
|
|
53
|
+
)
|
|
54
|
+
and remaining > config.limits.finalization_reserve_model_calls
|
|
55
|
+
)
|
|
56
|
+
|
|
57
|
+
|
|
58
|
+
def web_observation_due(snapshot: RunSnapshot, config: RunConfiguration) -> bool:
|
|
59
|
+
"""Require browser attempts before prolonged blind edits and near the limit.
|
|
60
|
+
|
|
61
|
+
A failed browser attempt counts as an attempt, not as successful evidence.
|
|
62
|
+
It unlocks the remaining repair window; later web edits can require a new
|
|
63
|
+
attempt. The final tool-capable turn still requires a fresh observation.
|
|
64
|
+
"""
|
|
65
|
+
if config.workspace_observation_policy is None:
|
|
66
|
+
return False
|
|
67
|
+
limits = config.limits
|
|
68
|
+
reserve = limits.verification_reserve_model_calls
|
|
69
|
+
interval = limits.browser_observation_interval_tool_calls
|
|
70
|
+
remaining = limits.max_model_calls - snapshot.model_budget_claimed
|
|
71
|
+
last_mutation = snapshot.last_web_mutation_tool_call
|
|
72
|
+
if (
|
|
73
|
+
last_mutation is None
|
|
74
|
+
or remaining <= limits.finalization_reserve_model_calls
|
|
75
|
+
or not browser_observation_available(config)
|
|
76
|
+
):
|
|
77
|
+
return False
|
|
78
|
+
observed = snapshot.last_browser_observation
|
|
79
|
+
unresolved = snapshot.unresolved_interaction_observation
|
|
80
|
+
last_attempt = max(
|
|
81
|
+
(
|
|
82
|
+
item
|
|
83
|
+
for item in (
|
|
84
|
+
snapshot.last_browser_attempt_tool_call,
|
|
85
|
+
*(
|
|
86
|
+
entry["tool_call"]
|
|
87
|
+
for entry in (observed, unresolved)
|
|
88
|
+
if isinstance(entry, dict) and type(entry.get("tool_call")) is int
|
|
89
|
+
),
|
|
90
|
+
)
|
|
91
|
+
if type(item) is int
|
|
92
|
+
),
|
|
93
|
+
default=-1,
|
|
94
|
+
)
|
|
95
|
+
if last_attempt >= last_mutation:
|
|
96
|
+
return False
|
|
97
|
+
early_due = interval > 0 and snapshot.tool_calls - max(last_attempt, 0) >= interval
|
|
98
|
+
reserved_due = reserve >= limits.finalization_reserve_model_calls + 4 and remaining <= reserve
|
|
99
|
+
return early_due or reserved_due
|
|
@@ -0,0 +1,86 @@
|
|
|
1
|
+
"""Model-authored task planning kept separate from acceptance authority."""
|
|
2
|
+
|
|
3
|
+
from __future__ import annotations
|
|
4
|
+
|
|
5
|
+
from typing import Literal
|
|
6
|
+
|
|
7
|
+
from pydantic import Field, JsonValue, model_validator
|
|
8
|
+
|
|
9
|
+
from .ports import ToolDefinition
|
|
10
|
+
from .state import Contract
|
|
11
|
+
|
|
12
|
+
TODO_WRITE_NAME = "TodoWrite"
|
|
13
|
+
|
|
14
|
+
|
|
15
|
+
class TaskProgressItem(Contract):
|
|
16
|
+
# Optional for old clients. Explicit IDs survive editing/reordering; public
|
|
17
|
+
# projections derive deterministic content IDs for legacy items.
|
|
18
|
+
id: str | None = Field(default=None, min_length=1, max_length=180,
|
|
19
|
+
exclude_if=lambda value: value is None)
|
|
20
|
+
content: str = Field(min_length=1, max_length=500, pattern=r"\S")
|
|
21
|
+
status: Literal["pending", "in_progress", "completed"]
|
|
22
|
+
priority: Literal["high", "medium", "low"]
|
|
23
|
+
|
|
24
|
+
|
|
25
|
+
class TaskProgressUpdate(Contract):
|
|
26
|
+
todos: tuple[TaskProgressItem, ...] = Field(max_length=64)
|
|
27
|
+
|
|
28
|
+
@model_validator(mode="after")
|
|
29
|
+
def unique_content(self) -> TaskProgressUpdate:
|
|
30
|
+
normalized = [item.content.strip().casefold() for item in self.todos]
|
|
31
|
+
if len(set(normalized)) != len(normalized):
|
|
32
|
+
raise ValueError("task progress items must have unique content")
|
|
33
|
+
identities = [item.id for item in self.todos if item.id is not None]
|
|
34
|
+
if len(identities) != len(set(identities)):
|
|
35
|
+
raise ValueError("task progress items must have unique ids")
|
|
36
|
+
return self
|
|
37
|
+
|
|
38
|
+
|
|
39
|
+
TODO_WRITE_DEFINITION = ToolDefinition(
|
|
40
|
+
name=TODO_WRITE_NAME,
|
|
41
|
+
context_role="task_planning",
|
|
42
|
+
description=(
|
|
43
|
+
"Replace the current session task list used to track multi-step work. "
|
|
44
|
+
"Send the complete list. Mark completed only after the work and required validation; "
|
|
45
|
+
"this planning status never substitutes for task acceptance."
|
|
46
|
+
),
|
|
47
|
+
parameters={
|
|
48
|
+
"type": "object",
|
|
49
|
+
"additionalProperties": False,
|
|
50
|
+
"required": ["todos"],
|
|
51
|
+
"properties": {
|
|
52
|
+
"todos": {
|
|
53
|
+
"type": "array",
|
|
54
|
+
"maxItems": 64,
|
|
55
|
+
"items": {
|
|
56
|
+
"type": "object",
|
|
57
|
+
"additionalProperties": False,
|
|
58
|
+
"required": ["content", "status", "priority"],
|
|
59
|
+
"properties": {
|
|
60
|
+
"id": {"type": "string", "minLength": 1, "maxLength": 180},
|
|
61
|
+
"content": {"type": "string", "minLength": 1, "maxLength": 500},
|
|
62
|
+
"status": {
|
|
63
|
+
"type": "string",
|
|
64
|
+
"enum": ["pending", "in_progress", "completed"],
|
|
65
|
+
},
|
|
66
|
+
"priority": {"type": "string", "enum": ["high", "medium", "low"]},
|
|
67
|
+
},
|
|
68
|
+
},
|
|
69
|
+
}
|
|
70
|
+
},
|
|
71
|
+
},
|
|
72
|
+
)
|
|
73
|
+
|
|
74
|
+
|
|
75
|
+
def parse_task_progress(arguments: dict[str, JsonValue]) -> tuple[dict[str, JsonValue], ...]:
|
|
76
|
+
update = TaskProgressUpdate.model_validate(arguments)
|
|
77
|
+
return tuple(item.model_dump(mode="json") for item in update.todos)
|
|
78
|
+
|
|
79
|
+
|
|
80
|
+
def summarize_task_progress(items: tuple[dict[str, JsonValue], ...]) -> dict[str, int]:
|
|
81
|
+
return {
|
|
82
|
+
"total": len(items),
|
|
83
|
+
"pending": sum(item["status"] == "pending" for item in items),
|
|
84
|
+
"in_progress": sum(item["status"] == "in_progress" for item in items),
|
|
85
|
+
"completed": sum(item["status"] == "completed" for item in items),
|
|
86
|
+
}
|
|
@@ -0,0 +1,43 @@
|
|
|
1
|
+
"""Qualify the final report against the current candidate and execution facts."""
|
|
2
|
+
|
|
3
|
+
from .completion import CompletionCandidate, VerificationReport, _report_mismatch, reduce_completion
|
|
4
|
+
from .ports import RunConfiguration
|
|
5
|
+
from .state import RunSnapshot
|
|
6
|
+
from .verification_binding import verification_subject_context_digest
|
|
7
|
+
|
|
8
|
+
|
|
9
|
+
def prepare_terminal_verification(snapshot: RunSnapshot, config: RunConfiguration) -> RunSnapshot:
|
|
10
|
+
"""Retire stale report pointers, preserving the original effect receipts.
|
|
11
|
+
|
|
12
|
+
A checkpoint or rejected final report can remain useful during the loop.
|
|
13
|
+
It cannot be published as the verdict for a different final candidate.
|
|
14
|
+
This happens in the authoritative terminal commit, never in the UI.
|
|
15
|
+
"""
|
|
16
|
+
report = None
|
|
17
|
+
try:
|
|
18
|
+
candidate = CompletionCandidate.model_validate(snapshot.candidate)
|
|
19
|
+
observed = VerificationReport.model_validate(snapshot.verification)
|
|
20
|
+
if (
|
|
21
|
+
(snapshot.candidate or {}).get("purpose") != "checkpoint"
|
|
22
|
+
and candidate.final_text == snapshot.final_text
|
|
23
|
+
and snapshot.verification_tool_calls == snapshot.tool_calls
|
|
24
|
+
and candidate.subject_context_digest == verification_subject_context_digest(snapshot)
|
|
25
|
+
and _report_mismatch(config.contract, candidate, observed) is None
|
|
26
|
+
):
|
|
27
|
+
report = observed
|
|
28
|
+
except (ValueError, TypeError):
|
|
29
|
+
# Old or rejected metadata is still available in its original receipt;
|
|
30
|
+
# absence of a qualified final report is not evidence of a passed check.
|
|
31
|
+
pass
|
|
32
|
+
updates = {
|
|
33
|
+
"verification": report.model_dump(mode="json") if report is not None else None,
|
|
34
|
+
"verification_tool_calls": snapshot.verification_tool_calls if report is not None else None,
|
|
35
|
+
}
|
|
36
|
+
if snapshot.outcome == "verified" and (
|
|
37
|
+
report is None
|
|
38
|
+
or reduce_completion(
|
|
39
|
+
config.contract, candidate, report, max_repairs=0,
|
|
40
|
+
).outcome != "verified"
|
|
41
|
+
):
|
|
42
|
+
updates.update(outcome="unverified", reason="terminal_verification_unavailable")
|
|
43
|
+
return snapshot.model_copy(update=updates)
|
|
@@ -0,0 +1,178 @@
|
|
|
1
|
+
"""Bounded schema-derived diagnostics; they never normalize or admit a call."""
|
|
2
|
+
|
|
3
|
+
from __future__ import annotations
|
|
4
|
+
|
|
5
|
+
import json
|
|
6
|
+
import re
|
|
7
|
+
|
|
8
|
+
from jsonschema.exceptions import ValidationError
|
|
9
|
+
from pydantic import JsonValue
|
|
10
|
+
|
|
11
|
+
|
|
12
|
+
def _pointer(path) -> str:
|
|
13
|
+
return "/" + "/".join(
|
|
14
|
+
str(part).replace("~", "~0").replace("/", "~1") for part in path
|
|
15
|
+
)
|
|
16
|
+
|
|
17
|
+
|
|
18
|
+
def _select_failure(error: ValidationError, validator):
|
|
19
|
+
"""Narrow only an unambiguously tagged object union using declared consts."""
|
|
20
|
+
selected, relative_path = error, tuple(error.absolute_schema_path)
|
|
21
|
+
while selected.validator in {"oneOf", "anyOf"} and isinstance(selected.instance, dict):
|
|
22
|
+
branches = selected.validator_value
|
|
23
|
+
if not isinstance(branches, list):
|
|
24
|
+
break
|
|
25
|
+
matches = []
|
|
26
|
+
for index, branch in enumerate(branches):
|
|
27
|
+
properties = branch.get("properties", {}) if isinstance(branch, dict) else {}
|
|
28
|
+
if not isinstance(properties, dict):
|
|
29
|
+
continue
|
|
30
|
+
tags = {name: item["const"] for name, item in properties.items()
|
|
31
|
+
if isinstance(item, dict) and "const" in item}
|
|
32
|
+
if tags and all(
|
|
33
|
+
name in selected.instance
|
|
34
|
+
and validator.evolve(schema={"const": value}).is_valid(selected.instance[name])
|
|
35
|
+
for name, value in tags.items()
|
|
36
|
+
):
|
|
37
|
+
matches.append(index)
|
|
38
|
+
if len(matches) != 1:
|
|
39
|
+
break # Unknown/ambiguous tags must not produce invented repair facts.
|
|
40
|
+
failures = [child for child in selected.context
|
|
41
|
+
if child.schema_path and child.schema_path[0] == matches[0]]
|
|
42
|
+
if not failures:
|
|
43
|
+
break
|
|
44
|
+
selected = next(
|
|
45
|
+
(child for child in failures if child.validator == "type" and child.path),
|
|
46
|
+
failures[0],
|
|
47
|
+
)
|
|
48
|
+
# Retain the existing branch-relative diagnostic for action consumers.
|
|
49
|
+
# The original ValidationError parent chain retains the true origin.
|
|
50
|
+
relative_path = tuple(selected.schema_path)[1:]
|
|
51
|
+
return selected, relative_path
|
|
52
|
+
|
|
53
|
+
|
|
54
|
+
def _physical_schema_path(schema: dict, selected: ValidationError) -> str | None:
|
|
55
|
+
value = schema
|
|
56
|
+
path = tuple(selected.absolute_schema_path)
|
|
57
|
+
try:
|
|
58
|
+
for part in path:
|
|
59
|
+
value = value[part]
|
|
60
|
+
# Local $ref validation may report a resolved rather than physical
|
|
61
|
+
# path. Only advertise an origin that actually exists in the definition.
|
|
62
|
+
if json.dumps(value, sort_keys=True) == json.dumps(
|
|
63
|
+
selected.validator_value, sort_keys=True
|
|
64
|
+
):
|
|
65
|
+
pointer = _pointer(path)
|
|
66
|
+
return pointer if len(pointer) <= 2048 else None
|
|
67
|
+
except (KeyError, IndexError, TypeError):
|
|
68
|
+
pass
|
|
69
|
+
return None
|
|
70
|
+
|
|
71
|
+
|
|
72
|
+
_JSON_TYPES = {"array", "boolean", "integer", "null", "number", "object", "string"}
|
|
73
|
+
|
|
74
|
+
|
|
75
|
+
def _union_type_hint(error: ValidationError) -> list[str] | None:
|
|
76
|
+
"""Describe only pure type alternatives, never enum values or other failures."""
|
|
77
|
+
|
|
78
|
+
def types(value):
|
|
79
|
+
values = [value] if isinstance(value, str) else value
|
|
80
|
+
if not isinstance(values, list) or not values or any(
|
|
81
|
+
not isinstance(item, str) or item not in _JSON_TYPES for item in values
|
|
82
|
+
):
|
|
83
|
+
return None
|
|
84
|
+
return values
|
|
85
|
+
|
|
86
|
+
if error.validator != "anyOf" or not isinstance(error.validator_value, list):
|
|
87
|
+
return None
|
|
88
|
+
branches = error.validator_value
|
|
89
|
+
if not branches or len(error.context) != len(branches) or any(
|
|
90
|
+
child.validator != "type" or child.absolute_path != error.absolute_path
|
|
91
|
+
for child in error.context
|
|
92
|
+
):
|
|
93
|
+
return None
|
|
94
|
+
result = []
|
|
95
|
+
for branch in branches:
|
|
96
|
+
if not isinstance(branch, dict) or set(branch) != {"type"}:
|
|
97
|
+
return None
|
|
98
|
+
allowed = types(branch["type"])
|
|
99
|
+
if allowed is None:
|
|
100
|
+
return None
|
|
101
|
+
result.extend(item for item in allowed if item not in result)
|
|
102
|
+
return result
|
|
103
|
+
|
|
104
|
+
|
|
105
|
+
def _declared_names(schema_path) -> list[str]:
|
|
106
|
+
path, names, index = list(schema_path), [], 0
|
|
107
|
+
while index < len(path):
|
|
108
|
+
if path[index] == "properties" and index + 1 < len(path) and isinstance(
|
|
109
|
+
path[index + 1], str
|
|
110
|
+
):
|
|
111
|
+
names.append(path[index + 1])
|
|
112
|
+
index += 2
|
|
113
|
+
else:
|
|
114
|
+
index += 1
|
|
115
|
+
return names
|
|
116
|
+
|
|
117
|
+
|
|
118
|
+
def _declared_instance_path(selected: ValidationError) -> bool:
|
|
119
|
+
"""Instance keys may be private map keys; repeat only host-declared names."""
|
|
120
|
+
keys = [part for part in selected.absolute_path if isinstance(part, str)]
|
|
121
|
+
return keys == _declared_names(selected.absolute_schema_path)
|
|
122
|
+
|
|
123
|
+
|
|
124
|
+
def _schema_field(selected: ValidationError) -> str | None:
|
|
125
|
+
path = list(selected.absolute_schema_path)
|
|
126
|
+
if len(path) >= 3 and path[-3] == "properties" and isinstance(path[-2], str):
|
|
127
|
+
return path[-2]
|
|
128
|
+
return None
|
|
129
|
+
|
|
130
|
+
|
|
131
|
+
def argument_error(error: ValidationError, schema: dict, validator) -> dict[str, JsonValue]:
|
|
132
|
+
selected, path = _select_failure(error, validator)
|
|
133
|
+
content: dict[str, JsonValue] = {
|
|
134
|
+
"code": "invalid_arguments",
|
|
135
|
+
"feedback_version": "schema-argument-feedback/v2",
|
|
136
|
+
"constraint": str(selected.validator),
|
|
137
|
+
"schema_path": _pointer(path)[:2048],
|
|
138
|
+
"instruction": "Correct arguments against this tool schema before retrying.",
|
|
139
|
+
}
|
|
140
|
+
if origin := _physical_schema_path(schema, selected):
|
|
141
|
+
content["source_schema_path"] = origin
|
|
142
|
+
declared = _declared_instance_path(selected)
|
|
143
|
+
instance_path = _pointer(selected.absolute_path) if selected.absolute_path else ""
|
|
144
|
+
if not declared:
|
|
145
|
+
content["instance_path_redacted"] = True
|
|
146
|
+
elif len(instance_path) <= 2048:
|
|
147
|
+
content["instance_path"] = instance_path
|
|
148
|
+
else:
|
|
149
|
+
content["instance_path_truncated"] = True
|
|
150
|
+
if selected.validator == "required" and isinstance(selected.instance, dict):
|
|
151
|
+
missing = [name for name in selected.validator_value if name not in selected.instance]
|
|
152
|
+
content["missing_fields"] = [name for name in missing[:20] if len(name) <= 256]
|
|
153
|
+
if len(missing) > 20 or any(len(name) > 256 for name in missing[:20]):
|
|
154
|
+
content["missing_fields_truncated"] = True
|
|
155
|
+
if (selected.validator == "additionalProperties" and selected.validator_value is False
|
|
156
|
+
and isinstance(selected.instance, dict)):
|
|
157
|
+
properties = selected.schema.get("properties", {})
|
|
158
|
+
patterns = selected.schema.get("patternProperties", {})
|
|
159
|
+
unexpected = [name for name in selected.instance if name not in properties
|
|
160
|
+
and not any(re.search(pattern, name) for pattern in patterns)]
|
|
161
|
+
content["unexpected_fields"] = [name for name in unexpected[:20] if len(name) <= 256]
|
|
162
|
+
if len(unexpected) > 20 or any(len(name) > 256 for name in unexpected[:20]):
|
|
163
|
+
content["unexpected_fields_truncated"] = True
|
|
164
|
+
union_types = _union_type_hint(selected) if selected.path else None
|
|
165
|
+
if (selected.validator == "type" and selected.path) or union_types:
|
|
166
|
+
last = next(reversed(selected.path))
|
|
167
|
+
field = last if declared and isinstance(last, str) else _schema_field(selected)
|
|
168
|
+
if field is not None:
|
|
169
|
+
content["field"] = field[:80]
|
|
170
|
+
content["received_type"] = type(selected.instance).__name__
|
|
171
|
+
expected = selected.validator_value
|
|
172
|
+
if union_types:
|
|
173
|
+
content["expected_types"] = union_types[:8]
|
|
174
|
+
elif isinstance(expected, str):
|
|
175
|
+
content["expected_type"] = expected[:40]
|
|
176
|
+
elif isinstance(expected, list):
|
|
177
|
+
content["expected_types"] = expected[:8]
|
|
178
|
+
return content
|