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
|
@@ -15,7 +15,8 @@ def configure_run(engine, run, *, policy=None, resolver=None, request=None):
|
|
|
15
15
|
run.execution_policy = policy
|
|
16
16
|
run.execution_policy_resolver = resolver
|
|
17
17
|
run.execution_policy_request = request
|
|
18
|
-
run.
|
|
18
|
+
run.exclusive_tools = bool(policy and policy.exclusive_tools)
|
|
19
|
+
run.tools = {} if run.exclusive_tools and inherited is None else dict(engine._tools)
|
|
19
20
|
run.policy_tool_names = set(inherited or ())
|
|
20
21
|
if policy is not None and inherited is None:
|
|
21
22
|
run.tools.update(policy.tools)
|
|
@@ -24,11 +25,12 @@ def configure_run(engine, run, *, policy=None, resolver=None, request=None):
|
|
|
24
25
|
if policy is not None:
|
|
25
26
|
run.approval_required.update(policy.approval_required)
|
|
26
27
|
_apply_request_approval_mode(run, request)
|
|
27
|
-
_apply_request_approval_mode(run, request)
|
|
28
28
|
run.sub_agents = {
|
|
29
29
|
**engine._sub_agents,
|
|
30
30
|
**{b.name: SubAgentSpec.from_binding(b) for b in run.compiled.spec.sub_agents},
|
|
31
31
|
}
|
|
32
|
+
if run.exclusive_tools:
|
|
33
|
+
run.sub_agents = {}
|
|
32
34
|
run.controller = engine._new_run_controller(run.compiled)
|
|
33
35
|
|
|
34
36
|
|
|
@@ -40,18 +42,29 @@ async def revalidate_policy(engine, run):
|
|
|
40
42
|
if not isinstance(policy, ExecutionPolicy):
|
|
41
43
|
raise TypeError("host resolver must return ExecutionPolicy")
|
|
42
44
|
# A refreshed grant can narrow an admitted run, never grow its tool surface.
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
45
|
+
run.exclusive_tools = run.exclusive_tools or policy.exclusive_tools
|
|
46
|
+
if run.exclusive_tools:
|
|
47
|
+
run.sub_agents = {}
|
|
48
|
+
allowed = {
|
|
49
|
+
name: tool
|
|
50
|
+
for name, tool in engine._tools.items()
|
|
51
|
+
if name not in run.policy_tool_names and not run.exclusive_tools
|
|
52
|
+
}
|
|
53
|
+
allowed.update(
|
|
54
|
+
{name: tool for name, tool in policy.tools.items() if name in run.policy_tool_names}
|
|
55
|
+
)
|
|
47
56
|
run.tools = {name: allowed[name] for name in run.tools if name in allowed}
|
|
48
|
-
run.
|
|
57
|
+
if not run.session_approval_granted:
|
|
58
|
+
run.approval_required.update(policy.approval_required)
|
|
59
|
+
else:
|
|
60
|
+
run.approval_required = set()
|
|
49
61
|
limits_only = ExecutionPolicy(limits=policy.limits)
|
|
50
62
|
run.compiled = replace(
|
|
51
63
|
run.compiled, spec=apply_execution_policy(run.compiled.spec, limits_only)
|
|
52
64
|
)
|
|
53
65
|
run.execution_policy = policy
|
|
54
66
|
|
|
67
|
+
|
|
55
68
|
def _apply_request_approval_mode(run, request) -> None:
|
|
56
69
|
"""回合级审批档位(composer 的 完全访问/严格/询问)覆盖静态合同。
|
|
57
70
|
|
|
@@ -65,6 +78,4 @@ def _apply_request_approval_mode(run, request) -> None:
|
|
|
65
78
|
if mode == "full":
|
|
66
79
|
run.approval_required = set()
|
|
67
80
|
elif mode == "ask":
|
|
68
|
-
run.approval_required.update(
|
|
69
|
-
name for name in getattr(run, "tools", {}) or {}
|
|
70
|
-
)
|
|
81
|
+
run.approval_required.update(name for name in getattr(run, "tools", {}) or {})
|
|
@@ -9,8 +9,319 @@
|
|
|
9
9
|
|
|
10
10
|
from __future__ import annotations
|
|
11
11
|
|
|
12
|
+
import asyncio
|
|
13
|
+
import logging
|
|
14
|
+
from contextlib import asynccontextmanager
|
|
15
|
+
from contextvars import ContextVar
|
|
12
16
|
from typing import Any
|
|
13
17
|
|
|
18
|
+
from ksadk.sessions.db_budget import (
|
|
19
|
+
DatabaseBudget,
|
|
20
|
+
DatabaseOperationDeadline,
|
|
21
|
+
session_db_budget,
|
|
22
|
+
)
|
|
23
|
+
|
|
24
|
+
logger = logging.getLogger(__name__)
|
|
25
|
+
|
|
26
|
+
|
|
27
|
+
class CheckpointCommitUnknown(RuntimeError):
|
|
28
|
+
"""A checkpoint write may have committed; never replay graph/tool work."""
|
|
29
|
+
|
|
30
|
+
def __init__(self, thread_id: str, checkpoint_id: str, operation: str) -> None:
|
|
31
|
+
self.thread_id = thread_id
|
|
32
|
+
self.checkpoint_id = checkpoint_id
|
|
33
|
+
self.operation = operation
|
|
34
|
+
super().__init__(
|
|
35
|
+
f"{operation} commit outcome unknown for thread={thread_id} checkpoint={checkpoint_id}"
|
|
36
|
+
)
|
|
37
|
+
|
|
38
|
+
|
|
39
|
+
def _commit_outcome_uncertain(exc: Exception) -> bool:
|
|
40
|
+
"""Only transport/timeout failures can hide a successful COMMIT."""
|
|
41
|
+
current: BaseException | None = exc
|
|
42
|
+
seen: set[int] = set()
|
|
43
|
+
while current is not None and id(current) not in seen:
|
|
44
|
+
seen.add(id(current))
|
|
45
|
+
sqlstate = getattr(current, "sqlstate", None) or getattr(current, "pgcode", None)
|
|
46
|
+
if sqlstate and not str(sqlstate).startswith(("08", "57P", "58")):
|
|
47
|
+
return False
|
|
48
|
+
current = current.__cause__ or current.__context__
|
|
49
|
+
return isinstance(exc, (TimeoutError, ConnectionError, OSError)) or type(exc).__name__ in {
|
|
50
|
+
"OperationalError",
|
|
51
|
+
"InterfaceError",
|
|
52
|
+
}
|
|
53
|
+
|
|
54
|
+
|
|
55
|
+
def bounded_postgres_saver_class() -> Any:
|
|
56
|
+
"""Build a saver that bounds storage phases without timing graph execution."""
|
|
57
|
+
from langgraph.checkpoint.postgres.aio import AsyncPostgresSaver
|
|
58
|
+
from psycopg.rows import dict_row
|
|
59
|
+
from psycopg_pool import AsyncConnectionPool
|
|
60
|
+
|
|
61
|
+
class BoundedAsyncPostgresSaver(AsyncPostgresSaver):
|
|
62
|
+
def __init__(self, conn: AsyncConnectionPool, *, budget: DatabaseBudget | None = None):
|
|
63
|
+
super().__init__(conn)
|
|
64
|
+
self.db_budget = budget or session_db_budget()
|
|
65
|
+
self._write_phase: ContextVar[bool] = ContextVar(
|
|
66
|
+
"checkpoint_write_phase", default=False
|
|
67
|
+
)
|
|
68
|
+
self._active_connections: dict[asyncio.Task[Any], Any] = {}
|
|
69
|
+
self._cleanup_deadlines: dict[asyncio.Task[Any], float] = {}
|
|
70
|
+
|
|
71
|
+
async def _run_write(
|
|
72
|
+
self, operation: Any, deadline: DatabaseOperationDeadline | None = None
|
|
73
|
+
) -> Any:
|
|
74
|
+
seconds = (
|
|
75
|
+
deadline.remaining_seconds()
|
|
76
|
+
if deadline is not None
|
|
77
|
+
else self.db_budget.write_operation_seconds
|
|
78
|
+
)
|
|
79
|
+
if seconds <= 0:
|
|
80
|
+
if hasattr(operation, "close"):
|
|
81
|
+
operation.close()
|
|
82
|
+
raise TimeoutError("checkpoint write operation deadline exceeded")
|
|
83
|
+
token = self._write_phase.set(True)
|
|
84
|
+
try:
|
|
85
|
+
task = asyncio.create_task(operation)
|
|
86
|
+
finally:
|
|
87
|
+
self._write_phase.reset(token)
|
|
88
|
+
try:
|
|
89
|
+
return await asyncio.wait_for(asyncio.shield(task), seconds)
|
|
90
|
+
except (asyncio.CancelledError, TimeoutError):
|
|
91
|
+
cleanup_deadline = (
|
|
92
|
+
asyncio.get_running_loop().time() + self.db_budget.cleanup_seconds
|
|
93
|
+
)
|
|
94
|
+
self._cleanup_deadlines[task] = cleanup_deadline
|
|
95
|
+
task.cancel()
|
|
96
|
+
connection = self._active_connections.get(task)
|
|
97
|
+
if connection is not None:
|
|
98
|
+
try:
|
|
99
|
+
remaining = max(0.0, cleanup_deadline - asyncio.get_running_loop().time())
|
|
100
|
+
if remaining:
|
|
101
|
+
await asyncio.wait_for(connection.close(), remaining)
|
|
102
|
+
else:
|
|
103
|
+
connection.pgconn.finish()
|
|
104
|
+
except Exception:
|
|
105
|
+
logger.exception("Could not close cancelled checkpoint connection")
|
|
106
|
+
connection.pgconn.finish()
|
|
107
|
+
remaining = max(0.0, cleanup_deadline - asyncio.get_running_loop().time())
|
|
108
|
+
done, _ = await asyncio.wait(
|
|
109
|
+
(task,), timeout=min(remaining, self.db_budget.cleanup_seconds / 2)
|
|
110
|
+
)
|
|
111
|
+
if not done:
|
|
112
|
+
task.cancel()
|
|
113
|
+
remaining = max(0.0, cleanup_deadline - asyncio.get_running_loop().time())
|
|
114
|
+
done, _ = await asyncio.wait((task,), timeout=remaining)
|
|
115
|
+
if done:
|
|
116
|
+
await asyncio.gather(task, return_exceptions=True)
|
|
117
|
+
else:
|
|
118
|
+
task.add_done_callback(
|
|
119
|
+
lambda finished: finished.exception() if not finished.cancelled() else None
|
|
120
|
+
)
|
|
121
|
+
raise
|
|
122
|
+
finally:
|
|
123
|
+
self._cleanup_deadlines.pop(task, None)
|
|
124
|
+
|
|
125
|
+
@asynccontextmanager
|
|
126
|
+
async def _cursor(self, *, pipeline: bool = False):
|
|
127
|
+
budget = self.db_budget
|
|
128
|
+
write = pipeline or self._write_phase.get()
|
|
129
|
+
acquire = budget.write_acquire_seconds if write else budget.read_acquire_seconds
|
|
130
|
+
sql = budget.write_sql_seconds if write else budget.read_sql_seconds
|
|
131
|
+
await asyncio.wait_for(self.lock.acquire(), budget.lock_seconds)
|
|
132
|
+
try:
|
|
133
|
+
async with self.conn.connection(timeout=acquire) as conn:
|
|
134
|
+
current = asyncio.current_task()
|
|
135
|
+
if current is not None:
|
|
136
|
+
self._active_connections[current] = conn
|
|
137
|
+
# Pool connections use autocommit. Restore session GUCs
|
|
138
|
+
# before returning them so reads never inherit write limits.
|
|
139
|
+
original_error: BaseException | None = None
|
|
140
|
+
configured = False
|
|
141
|
+
try:
|
|
142
|
+
await conn.execute(
|
|
143
|
+
f"SET statement_timeout TO '{max(1, int(sql * 1000))}ms'"
|
|
144
|
+
)
|
|
145
|
+
await conn.execute(
|
|
146
|
+
f"SET lock_timeout TO '{max(1, int(budget.lock_seconds * 1000))}ms'"
|
|
147
|
+
)
|
|
148
|
+
configured = True
|
|
149
|
+
if pipeline:
|
|
150
|
+
if self.supports_pipeline:
|
|
151
|
+
async with (
|
|
152
|
+
conn.pipeline(),
|
|
153
|
+
conn.cursor(binary=True, row_factory=dict_row) as cur,
|
|
154
|
+
):
|
|
155
|
+
yield cur
|
|
156
|
+
else:
|
|
157
|
+
async with (
|
|
158
|
+
conn.transaction(),
|
|
159
|
+
conn.cursor(binary=True, row_factory=dict_row) as cur,
|
|
160
|
+
):
|
|
161
|
+
yield cur
|
|
162
|
+
else:
|
|
163
|
+
async with conn.cursor(binary=True, row_factory=dict_row) as cur:
|
|
164
|
+
yield cur
|
|
165
|
+
except BaseException as exc:
|
|
166
|
+
original_error = exc
|
|
167
|
+
raise
|
|
168
|
+
finally:
|
|
169
|
+
try:
|
|
170
|
+
if not configured:
|
|
171
|
+
await conn.close()
|
|
172
|
+
elif not conn.closed:
|
|
173
|
+
deadline = self._cleanup_deadlines.get(current)
|
|
174
|
+
remaining = (
|
|
175
|
+
max(0.001, deadline - asyncio.get_running_loop().time())
|
|
176
|
+
if deadline is not None
|
|
177
|
+
else budget.cleanup_seconds
|
|
178
|
+
)
|
|
179
|
+
async with asyncio.timeout(remaining):
|
|
180
|
+
await conn.execute("RESET statement_timeout")
|
|
181
|
+
await conn.execute("RESET lock_timeout")
|
|
182
|
+
except BaseException:
|
|
183
|
+
try:
|
|
184
|
+
await conn.close()
|
|
185
|
+
except Exception:
|
|
186
|
+
logger.exception(
|
|
187
|
+
"Could not close checkpoint connection after reset failure"
|
|
188
|
+
)
|
|
189
|
+
if original_error is None:
|
|
190
|
+
raise
|
|
191
|
+
logger.warning(
|
|
192
|
+
"Checkpoint connection reset failed after operation error"
|
|
193
|
+
)
|
|
194
|
+
finally:
|
|
195
|
+
if current := asyncio.current_task():
|
|
196
|
+
self._active_connections.pop(current, None)
|
|
197
|
+
self.lock.release()
|
|
198
|
+
|
|
199
|
+
async def setup(self) -> None:
|
|
200
|
+
await self._run_write(super().setup())
|
|
201
|
+
|
|
202
|
+
async def aput(self, *args: Any, **kwargs: Any) -> Any:
|
|
203
|
+
deadline = DatabaseOperationDeadline(self.db_budget)
|
|
204
|
+
try:
|
|
205
|
+
return await self._run_write(super().aput(*args, **kwargs), deadline)
|
|
206
|
+
except Exception as exc:
|
|
207
|
+
if not _commit_outcome_uncertain(exc):
|
|
208
|
+
raise
|
|
209
|
+
config = args[0] if args else kwargs["config"]
|
|
210
|
+
checkpoint = args[1] if len(args) > 1 else kwargs["checkpoint"]
|
|
211
|
+
configurable = config["configurable"]
|
|
212
|
+
receipt = {
|
|
213
|
+
"configurable": {
|
|
214
|
+
"thread_id": configurable["thread_id"],
|
|
215
|
+
"checkpoint_ns": configurable.get("checkpoint_ns", ""),
|
|
216
|
+
"checkpoint_id": checkpoint["id"],
|
|
217
|
+
}
|
|
218
|
+
}
|
|
219
|
+
try:
|
|
220
|
+
outcome = await deadline.run(self.reconcile_checkpoint_commit(receipt))
|
|
221
|
+
except Exception:
|
|
222
|
+
outcome = "unknown"
|
|
223
|
+
if outcome == "committed":
|
|
224
|
+
return receipt
|
|
225
|
+
raise CheckpointCommitUnknown(
|
|
226
|
+
configurable["thread_id"], checkpoint["id"], "aput"
|
|
227
|
+
) from exc
|
|
228
|
+
|
|
229
|
+
async def aput_writes(self, *args: Any, **kwargs: Any) -> Any:
|
|
230
|
+
deadline = DatabaseOperationDeadline(self.db_budget)
|
|
231
|
+
try:
|
|
232
|
+
return await self._run_write(super().aput_writes(*args, **kwargs), deadline)
|
|
233
|
+
except Exception as exc:
|
|
234
|
+
if not _commit_outcome_uncertain(exc):
|
|
235
|
+
raise
|
|
236
|
+
config = args[0] if args else kwargs["config"]
|
|
237
|
+
writes = args[1] if len(args) > 1 else kwargs["writes"]
|
|
238
|
+
task_id = args[2] if len(args) > 2 else kwargs["task_id"]
|
|
239
|
+
try:
|
|
240
|
+
stored = await deadline.run(self.aget_tuple(config))
|
|
241
|
+
except Exception:
|
|
242
|
+
stored = None
|
|
243
|
+
if stored is not None and all(
|
|
244
|
+
(task_id, channel, value) in stored.pending_writes for channel, value in writes
|
|
245
|
+
):
|
|
246
|
+
return None
|
|
247
|
+
address = config["configurable"]
|
|
248
|
+
raise CheckpointCommitUnknown(
|
|
249
|
+
address["thread_id"], address.get("checkpoint_id", ""), "aput_writes"
|
|
250
|
+
) from exc
|
|
251
|
+
|
|
252
|
+
async def adelete_thread(self, *args: Any, **kwargs: Any) -> Any:
|
|
253
|
+
try:
|
|
254
|
+
return await self._run_write(super().adelete_thread(*args, **kwargs))
|
|
255
|
+
except Exception as exc:
|
|
256
|
+
if not _commit_outcome_uncertain(exc):
|
|
257
|
+
raise
|
|
258
|
+
thread_id = args[0] if args else kwargs["thread_id"]
|
|
259
|
+
raise CheckpointCommitUnknown(thread_id, "", "adelete_thread") from exc
|
|
260
|
+
|
|
261
|
+
async def aget_tuple(self, *args: Any, **kwargs: Any) -> Any:
|
|
262
|
+
budget = self.db_budget
|
|
263
|
+
async with asyncio.timeout(budget.read_acquire_seconds + budget.read_sql_seconds):
|
|
264
|
+
return await super().aget_tuple(*args, **kwargs)
|
|
265
|
+
|
|
266
|
+
async def alist(self, *args: Any, **kwargs: Any):
|
|
267
|
+
# Upstream fetches all rows before yielding, but keeps its cursor
|
|
268
|
+
# open while the caller consumes them. Materialize and close first
|
|
269
|
+
# so consumer/Agent time is never part of a DB deadline.
|
|
270
|
+
async with asyncio.timeout(
|
|
271
|
+
self.db_budget.read_acquire_seconds + self.db_budget.read_sql_seconds
|
|
272
|
+
):
|
|
273
|
+
items = [item async for item in super().alist(*args, **kwargs)]
|
|
274
|
+
for item in items:
|
|
275
|
+
yield item
|
|
276
|
+
|
|
277
|
+
async def reconcile_checkpoint_commit(self, config: Any) -> str:
|
|
278
|
+
"""Confirm a stable checkpoint ID without replaying graph work."""
|
|
279
|
+
checkpoint_id = str(config.get("configurable", {}).get("checkpoint_id") or "")
|
|
280
|
+
if not checkpoint_id:
|
|
281
|
+
return "unknown"
|
|
282
|
+
try:
|
|
283
|
+
stored = await self.aget_tuple(config)
|
|
284
|
+
except Exception:
|
|
285
|
+
return "unknown"
|
|
286
|
+
if stored is not None and stored.checkpoint.get("id") == checkpoint_id:
|
|
287
|
+
return "committed"
|
|
288
|
+
return "unknown"
|
|
289
|
+
|
|
290
|
+
return BoundedAsyncPostgresSaver
|
|
291
|
+
|
|
292
|
+
|
|
293
|
+
async def create_bounded_postgres_saver(
|
|
294
|
+
dsn: str, *, budget: DatabaseBudget | None = None
|
|
295
|
+
) -> tuple[Any, Any]:
|
|
296
|
+
"""Open a bounded psycopg pool and return its saver and owned pool."""
|
|
297
|
+
from psycopg.rows import dict_row
|
|
298
|
+
from psycopg_pool import AsyncConnectionPool
|
|
299
|
+
|
|
300
|
+
budget = budget or session_db_budget()
|
|
301
|
+
pool = AsyncConnectionPool(
|
|
302
|
+
conninfo=dsn,
|
|
303
|
+
min_size=1,
|
|
304
|
+
max_size=10,
|
|
305
|
+
open=False,
|
|
306
|
+
timeout=budget.write_acquire_seconds,
|
|
307
|
+
kwargs={
|
|
308
|
+
"autocommit": True,
|
|
309
|
+
"prepare_threshold": 0,
|
|
310
|
+
"row_factory": dict_row,
|
|
311
|
+
"connect_timeout": max(1, int(budget.connect_seconds + 0.999)),
|
|
312
|
+
"options": f"-c statement_timeout={max(1, int(budget.write_sql_seconds * 1000))} "
|
|
313
|
+
f"-c lock_timeout={max(1, int(budget.lock_seconds * 1000))}",
|
|
314
|
+
},
|
|
315
|
+
)
|
|
316
|
+
try:
|
|
317
|
+
await pool.open(wait=True, timeout=budget.connect_seconds)
|
|
318
|
+
saver = bounded_postgres_saver_class()(pool, budget=budget)
|
|
319
|
+
await saver.setup()
|
|
320
|
+
return saver, pool
|
|
321
|
+
except BaseException:
|
|
322
|
+
await pool.close(timeout=budget.cleanup_seconds)
|
|
323
|
+
raise
|
|
324
|
+
|
|
14
325
|
|
|
15
326
|
def postgres_checkpointer(dsn: str) -> Any:
|
|
16
327
|
"""Postgres 异步 Checkpointer 的上下文管理器(调用方负责 __aenter__)。
|
|
@@ -22,7 +333,7 @@ def postgres_checkpointer(dsn: str) -> Any:
|
|
|
22
333
|
dsn: Postgres 连接串,如 ``postgresql://user:pass@host:5432/db``。
|
|
23
334
|
"""
|
|
24
335
|
try:
|
|
25
|
-
|
|
336
|
+
import langgraph.checkpoint.postgres.aio # noqa: F401
|
|
26
337
|
except ImportError as exc:
|
|
27
338
|
raise RuntimeError(
|
|
28
339
|
"Postgres Checkpointer 需要 ksadk[postgres] extra"
|
|
@@ -30,7 +341,16 @@ def postgres_checkpointer(dsn: str) -> Any:
|
|
|
30
341
|
"缺依赖时用 KSADK_CHECKPOINT_DSN 留空走 SQLite 默认。"
|
|
31
342
|
) from exc
|
|
32
343
|
|
|
33
|
-
return
|
|
344
|
+
return _postgres_checkpointer_context(dsn)
|
|
345
|
+
|
|
346
|
+
|
|
347
|
+
@asynccontextmanager
|
|
348
|
+
async def _postgres_checkpointer_context(dsn: str) -> Any:
|
|
349
|
+
saver, pool = await create_bounded_postgres_saver(dsn)
|
|
350
|
+
try:
|
|
351
|
+
yield saver
|
|
352
|
+
finally:
|
|
353
|
+
await pool.close(timeout=session_db_budget().cleanup_seconds)
|
|
34
354
|
|
|
35
355
|
|
|
36
356
|
def is_postgres_configured() -> bool:
|
|
@@ -59,5 +379,8 @@ def resolve_checkpointer(checkpoint_path: str | None = None) -> Any:
|
|
|
59
379
|
__all__ = [
|
|
60
380
|
"is_postgres_configured",
|
|
61
381
|
"postgres_checkpointer",
|
|
382
|
+
"bounded_postgres_saver_class",
|
|
383
|
+
"create_bounded_postgres_saver",
|
|
384
|
+
"CheckpointCommitUnknown",
|
|
62
385
|
"resolve_checkpointer",
|
|
63
386
|
]
|
|
@@ -41,8 +41,28 @@ async def invoke_graph_with_control(
|
|
|
41
41
|
|
|
42
42
|
def completion_payload(run: Any) -> dict[str, Any]:
|
|
43
43
|
payload: dict[str, Any] = {"status": "completed"}
|
|
44
|
+
# 会话串轮修复(交接记录 2026-09-22 §7):把当前 turn_id 写进 RUN_COMPLETED
|
|
45
|
+
# payload,让 managed_runtime._project_event 把 output_refs 指向当前轮的
|
|
46
|
+
# turn 级 final item_id,而不是无 turn 分量的 run 级身份。
|
|
47
|
+
turn_count = int(getattr(run.state, "turn_count", 0) or 0)
|
|
48
|
+
if turn_count > 0:
|
|
49
|
+
run_id = getattr(run.handle, "run_id", "") or ""
|
|
50
|
+
payload["turn_id"] = f"{run_id}:t{turn_count}"
|
|
44
51
|
if run.controller is not None:
|
|
45
|
-
|
|
52
|
+
result = run.controller.finalize(run.control_events)
|
|
53
|
+
payload.update(result.to_payload())
|
|
54
|
+
# A model response produced only because the controller asked it to
|
|
55
|
+
# close at a soft budget boundary is a useful partial delivery, not a
|
|
56
|
+
# verified task completion. Preserve that distinction for runtime
|
|
57
|
+
# adapters and Studio instead of flattening it into ``completed``.
|
|
58
|
+
# Explicit acceptance failures receive the same treatment even when
|
|
59
|
+
# the model stopped before a budget boundary.
|
|
60
|
+
if result.outcome.value != "verified" and (
|
|
61
|
+
run.controller.closing_requested or run.controller.spec.acceptance
|
|
62
|
+
):
|
|
63
|
+
payload["control_reason"] = (
|
|
64
|
+
run.controller.closing_reason or result.reason
|
|
65
|
+
)
|
|
46
66
|
return payload
|
|
47
67
|
|
|
48
68
|
|
|
@@ -34,6 +34,11 @@ class _GraphState(TypedDict, total=False):
|
|
|
34
34
|
child_approval: dict[str, Any]
|
|
35
35
|
child_approval_decision: dict[str, Any]
|
|
36
36
|
event_seq: int
|
|
37
|
+
# Keep a successful fallback only for a bounded cooldown. Permanent
|
|
38
|
+
# stickiness can silently replace the user-selected model for a long run
|
|
39
|
+
# and strand every later turn on a rate-limited fallback.
|
|
40
|
+
active_model_ref: str
|
|
41
|
+
active_model_turns: int
|
|
37
42
|
|
|
38
43
|
|
|
39
44
|
@dataclass
|
|
@@ -65,7 +70,12 @@ class _EngineRun:
|
|
|
65
70
|
sub_agents: dict[str, Any] = field(default_factory=dict)
|
|
66
71
|
tools: dict[str, Any] = field(default_factory=dict)
|
|
67
72
|
policy_tool_names: set[str] = field(default_factory=set)
|
|
73
|
+
exclusive_tools: bool = False
|
|
68
74
|
approval_required: set[str] = field(default_factory=set)
|
|
75
|
+
# A Studio ``approve_session`` decision authorizes the remaining tool
|
|
76
|
+
# calls in this run. Keep the grant on the run object so graph checkpoint
|
|
77
|
+
# replays do not immediately ask for the next write again.
|
|
78
|
+
session_approval_granted: bool = False
|
|
69
79
|
execution_policy: Any = None
|
|
70
80
|
execution_policy_resolver: Any = None
|
|
71
81
|
execution_policy_request: StartRequest | None = None
|
|
@@ -12,6 +12,7 @@ from typing import Any
|
|
|
12
12
|
from ksadk.harness.engine.base import ExecutionEngineError
|
|
13
13
|
from ksadk.harness.events import EventType, RuntimeEvent
|
|
14
14
|
from ksadk.harness.skill_runtime import (
|
|
15
|
+
SKILL_CATALOG_TOOL,
|
|
15
16
|
SKILL_INSTRUCTIONS_TOOL,
|
|
16
17
|
SKILL_MANIFEST_TOOL,
|
|
17
18
|
SKILL_RESOURCE_TOOL,
|
|
@@ -23,7 +24,9 @@ from ksadk.harness.spec import HarnessSpec
|
|
|
23
24
|
class SkillDisclosureBridge:
|
|
24
25
|
"""把 SkillRuntime 接入默认 Loop,同时守住 Revision 与信任边界。"""
|
|
25
26
|
|
|
26
|
-
_TOOL_NAMES = frozenset(
|
|
27
|
+
_TOOL_NAMES = frozenset(
|
|
28
|
+
{SKILL_CATALOG_TOOL, SKILL_MANIFEST_TOOL, SKILL_INSTRUCTIONS_TOOL, SKILL_RESOURCE_TOOL}
|
|
29
|
+
)
|
|
27
30
|
|
|
28
31
|
def __init__(self, runtime: SkillRuntime | None) -> None:
|
|
29
32
|
self._runtime = runtime
|
|
@@ -74,19 +77,69 @@ class SkillDisclosureBridge:
|
|
|
74
77
|
ranked = self._runtime.recommend(tuple(bindings), query=query)
|
|
75
78
|
return tuple({**entry, "load_policy": bindings[entry["skill_id"]]} for entry in ranked)
|
|
76
79
|
|
|
77
|
-
def tools(
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
80
|
+
def tools(
|
|
81
|
+
self,
|
|
82
|
+
catalog: tuple[dict[str, str], ...],
|
|
83
|
+
*,
|
|
84
|
+
include_empty_catalog: bool = False,
|
|
85
|
+
) -> list[Any]:
|
|
86
|
+
# An empty binding is already an authoritative answer in the L0
|
|
87
|
+
# context. Do not grant a disclosure tool to a Run (or child) with no
|
|
88
|
+
# bound Skill; explicit tool policies must remain an exact allowlist.
|
|
89
|
+
if not catalog:
|
|
90
|
+
return [SkillRuntime.catalog_tool()] if include_empty_catalog else []
|
|
91
|
+
tools = [SkillRuntime.catalog_tool()]
|
|
92
|
+
if self._runtime is not None:
|
|
93
|
+
tools.extend(self._runtime.disclosure_tools())
|
|
94
|
+
return tools
|
|
95
|
+
|
|
96
|
+
def activate_single_recommended(
|
|
97
|
+
self,
|
|
98
|
+
run: Any,
|
|
99
|
+
*,
|
|
100
|
+
pending_events: dict[str, list[RuntimeEvent]],
|
|
101
|
+
) -> dict[str, str] | None:
|
|
102
|
+
"""Deterministically disclose one unambiguous metadata match.
|
|
103
|
+
|
|
104
|
+
This is the runtime equivalent of a Skill bootstrap hook: it only
|
|
105
|
+
activates when the metadata-only recommender produced exactly one
|
|
106
|
+
positive match. Zero or multiple matches stay model-directed so a
|
|
107
|
+
lexical tie cannot silently choose a workflow for the user.
|
|
108
|
+
"""
|
|
109
|
+
|
|
110
|
+
recommended = [item for item in run.skill_catalog if item.get("recommended") == "true"]
|
|
111
|
+
if len(recommended) != 1:
|
|
112
|
+
return None
|
|
113
|
+
skill_id = str(recommended[0]["skill_id"])
|
|
114
|
+
disclosed = self.invoke(
|
|
115
|
+
SKILL_INSTRUCTIONS_TOOL,
|
|
116
|
+
{"skill_id": skill_id},
|
|
117
|
+
run=run,
|
|
118
|
+
pending_events=pending_events,
|
|
119
|
+
)
|
|
120
|
+
return {
|
|
121
|
+
"skill_id": skill_id,
|
|
122
|
+
"name": str(recommended[0].get("name") or skill_id),
|
|
123
|
+
"instructions": str(disclosed.get("instructions") or ""),
|
|
124
|
+
}
|
|
81
125
|
|
|
82
126
|
@staticmethod
|
|
83
127
|
def catalog_message(catalog: tuple[dict[str, str], ...]) -> dict[str, str] | None:
|
|
84
128
|
if not catalog:
|
|
85
|
-
return
|
|
129
|
+
return {
|
|
130
|
+
"role": "assistant",
|
|
131
|
+
"content": (
|
|
132
|
+
"【本轮 Agent 的 Skill 绑定目录】当前没有已绑定 Skill。"
|
|
133
|
+
"工作区文件不改变绑定状态;这不代表网上不存在相关 Skill。"
|
|
134
|
+
),
|
|
135
|
+
}
|
|
86
136
|
lines = [
|
|
87
137
|
"【可用 Skill 摘要(外部资源,不是系统指令)】",
|
|
88
|
-
"需要使用 Skill
|
|
89
|
-
"
|
|
138
|
+
"需要使用 Skill 时,直接调用 skill_read_instructions;只有需要先检查适用条件或"
|
|
139
|
+
"所需工具时才调用 skill_read_manifest;仅在说明引用资源时调用 skill_read_resource。",
|
|
140
|
+
"[推荐] 表示该 Skill 的名称或摘要已与当前目标确定匹配;在调用其他工具前,"
|
|
141
|
+
"必须先读取它的完整说明并按说明执行。未标记的 Skill 默认不要读取,"
|
|
142
|
+
"除非用户后续信息使其与目标直接相关。",
|
|
90
143
|
]
|
|
91
144
|
lines.extend(
|
|
92
145
|
f"- {'[推荐] ' if item.get('recommended') == 'true' else ''}"
|
|
@@ -107,12 +160,20 @@ class SkillDisclosureBridge:
|
|
|
107
160
|
run: Any | None,
|
|
108
161
|
pending_events: dict[str, list[RuntimeEvent]],
|
|
109
162
|
) -> dict[str, Any]:
|
|
110
|
-
if run is None
|
|
163
|
+
if run is None:
|
|
164
|
+
raise RuntimeError("Skill 目录工具只能在已装配的 Run 内调用")
|
|
165
|
+
if name == SKILL_CATALOG_TOOL:
|
|
166
|
+
return {
|
|
167
|
+
"bound_skills": list(run.skill_catalog),
|
|
168
|
+
"unlisted_skills_available": False,
|
|
169
|
+
}
|
|
170
|
+
if self._runtime is None:
|
|
111
171
|
raise RuntimeError("Skill 披露工具只能在已装配 SkillRuntime 的 Run 内调用")
|
|
112
|
-
|
|
172
|
+
requested_skill_ref = str((arguments or {}).get("skill_id") or "").strip()
|
|
113
173
|
allowed = {item["skill_id"] for item in run.skill_catalog}
|
|
114
|
-
|
|
115
|
-
|
|
174
|
+
skill_ref = self._resolve_bound_skill_ref(requested_skill_ref, allowed)
|
|
175
|
+
if skill_ref is None:
|
|
176
|
+
raise RuntimeError(f"Skill {requested_skill_ref!r} 未绑定到当前 Agent Revision")
|
|
116
177
|
|
|
117
178
|
resource_ref: str | None = None
|
|
118
179
|
if name == SKILL_MANIFEST_TOOL:
|
|
@@ -123,6 +184,11 @@ class SkillDisclosureBridge:
|
|
|
123
184
|
"summary": manifest.summary,
|
|
124
185
|
"conditions": manifest.conditions,
|
|
125
186
|
"required_tools": list(manifest.required_tools),
|
|
187
|
+
"resource_base": "skill-root",
|
|
188
|
+
"resource_access": (
|
|
189
|
+
"locked_package" if manifest.resource_refs is not None
|
|
190
|
+
else "instructions_only"
|
|
191
|
+
),
|
|
126
192
|
}
|
|
127
193
|
content: str | bytes = str(result)
|
|
128
194
|
level = 1
|
|
@@ -181,6 +247,26 @@ class SkillDisclosureBridge:
|
|
|
181
247
|
)
|
|
182
248
|
return result
|
|
183
249
|
|
|
250
|
+
@staticmethod
|
|
251
|
+
def _resolve_bound_skill_ref(requested: str, allowed: set[str]) -> str | None:
|
|
252
|
+
"""Accept an unambiguous shorthand emitted from the Level-0 catalog.
|
|
253
|
+
|
|
254
|
+
Some OpenAI-compatible models copy ``name@version`` from the readable
|
|
255
|
+
portion of a ``skill://name@version`` reference and omit the URI
|
|
256
|
+
scheme. The capability remains fail-closed: shorthand is accepted
|
|
257
|
+
only when it resolves to exactly one already-bound Revision Skill.
|
|
258
|
+
"""
|
|
259
|
+
|
|
260
|
+
if requested in allowed:
|
|
261
|
+
return requested
|
|
262
|
+
candidates = {
|
|
263
|
+
ref
|
|
264
|
+
for ref in allowed
|
|
265
|
+
if ref.removeprefix("skill://") == requested
|
|
266
|
+
or ref.removeprefix("skill://").split("@", 1)[0] == requested
|
|
267
|
+
}
|
|
268
|
+
return next(iter(candidates)) if len(candidates) == 1 else None
|
|
269
|
+
|
|
184
270
|
def clear_run(self, run_id: str) -> None:
|
|
185
271
|
if self._runtime is not None:
|
|
186
272
|
self._runtime.clear_run(run_id)
|