agentengine-sdk-python 0.8.4__py3-none-any.whl → 0.8.6__py3-none-any.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- {agentengine_sdk_python-0.8.4.dist-info → agentengine_sdk_python-0.8.6.dist-info}/METADATA +17 -10
- agentengine_sdk_python-0.8.6.dist-info/RECORD +1731 -0
- ksadk/_async_iterators.py +79 -0
- ksadk/_build_provenance.json +1 -1
- ksadk/_model_anthropic.py +49 -0
- ksadk/_model_input.py +86 -0
- ksadk/_model_json.py +40 -0
- ksadk/_model_reasoning.py +17 -0
- ksadk/_model_refusal.py +20 -0
- ksadk/_model_sse.py +163 -0
- ksadk/_process.py +83 -0
- ksadk/_str_enum.py +17 -0
- ksadk/a2a/__init__.py +157 -167
- ksadk/a2a/_invocation_state.py +86 -0
- ksadk/a2a/_space_client_events.py +33 -22
- ksadk/a2a/adk.py +194 -0
- ksadk/a2a/adk_invocation_context.py +242 -0
- ksadk/a2a/adk_runtime.py +126 -0
- ksadk/a2a/adk_tools.py +319 -0
- ksadk/a2a/bootstrap.py +149 -23
- ksadk/a2a/build_validation.py +147 -0
- ksadk/a2a/card.py +23 -15
- ksadk/a2a/codex.py +160 -0
- ksadk/a2a/codex_checkpoint.py +111 -0
- ksadk/a2a/codex_recovery.py +96 -0
- ksadk/a2a/codex_recovery_events.py +123 -0
- ksadk/a2a/codex_runtime.py +198 -0
- ksadk/a2a/codex_session_checkpoint.py +162 -0
- ksadk/a2a/composition.py +88 -0
- ksadk/a2a/context_store.py +118 -19
- ksadk/a2a/control_plane.py +108 -106
- ksadk/a2a/event_adapter.py +92 -193
- ksadk/a2a/executor.py +257 -85
- ksadk/a2a/exposure.py +106 -0
- ksadk/a2a/external_transport.py +3 -4
- ksadk/a2a/identity.py +106 -12
- ksadk/a2a/ids.py +14 -3
- ksadk/a2a/inbound_kernel.py +133 -0
- ksadk/a2a/interaction_wire.py +76 -0
- ksadk/a2a/invocation_checkpoint.py +274 -0
- ksadk/a2a/invocation_policy.py +87 -0
- ksadk/a2a/invocation_publication.py +210 -0
- ksadk/a2a/invocation_service.py +972 -0
- ksadk/a2a/invocation_types.py +459 -0
- ksadk/a2a/kernel_task_adapter.py +259 -0
- ksadk/a2a/langgraph.py +20 -7
- ksadk/a2a/langgraph_invocation_context.py +136 -0
- ksadk/a2a/langgraph_managed.py +150 -0
- ksadk/a2a/langgraph_recovery.py +32 -0
- ksadk/a2a/langgraph_runtime.py +89 -0
- ksadk/a2a/langgraph_tool_runtime.py +132 -0
- ksadk/a2a/langgraph_tools.py +63 -0
- ksadk/a2a/message_digest.py +40 -0
- ksadk/a2a/platform.py +389 -0
- ksadk/a2a/policy_refs.py +13 -0
- ksadk/a2a/presentation.py +402 -0
- ksadk/a2a/product_kernel_facts.py +177 -0
- ksadk/a2a/product_key.py +99 -0
- ksadk/a2a/protocol_errors.py +116 -0
- ksadk/a2a/result_text.py +49 -0
- ksadk/a2a/resume_store.py +93 -3
- ksadk/a2a/routes.py +6 -1
- ksadk/a2a/runtime_approval.py +198 -0
- ksadk/a2a/runtime_input.py +151 -0
- ksadk/a2a/server.py +16 -7
- ksadk/a2a/space_client.py +101 -16
- ksadk/a2a/task_adapter.py +19 -5
- ksadk/a2a/task_event_dispatcher.py +39 -2
- ksadk/a2a/task_event_outbox.py +215 -0
- ksadk/a2a/task_event_outbox_owned.py +130 -0
- ksadk/a2a/task_store.py +37 -0
- ksadk/a2a/tool_activity.py +176 -0
- ksadk/a2a/workload_tokens.py +134 -0
- ksadk/a2ui/core.py +3 -3
- ksadk/api/client.py +38 -79
- ksadk/api/sse_stream.py +96 -0
- ksadk/builders/code_builder.py +121 -118
- ksadk/builders/container_builder.py +11 -29
- ksadk/builders/framework_requirements.py +22 -2
- ksadk/builders/managed_runtime_builder.py +12 -0
- ksadk/builders/source_provenance.py +87 -0
- ksadk/cli/__init__.py +36 -0
- ksadk/cli/cmd_a2a.py +43 -0
- ksadk/cli/cmd_build.py +9 -0
- ksadk/cli/cmd_config.py +4 -4
- ksadk/cli/cmd_create.py +12 -12
- ksadk/cli/cmd_deploy.py +27 -2
- ksadk/cli/cmd_hermes.py +24 -2
- ksadk/cli/cmd_invoke.py +64 -88
- ksadk/cli/cmd_openclaw.py +26 -1
- ksadk/cli/cmd_plugin.py +70 -12
- ksadk/cli/cmd_studio.py +69 -17
- ksadk/cli/cmd_web.py +2 -0
- ksadk/cli/hosted_invoke.py +206 -0
- ksadk/cli/invoke_content.py +60 -0
- ksadk/cli/openclaw_env.py +1 -1
- ksadk/cli/resource_common.py +26 -0
- ksadk/cli/runtime_bootstrap.py +27 -5
- ksadk/codex/_expert_request_reader.py +48 -0
- ksadk/codex/a2a_tools.py +140 -0
- ksadk/codex/async_approval.py +169 -0
- ksadk/codex/async_client.py +938 -0
- ksadk/codex/async_proxy.py +216 -0
- ksadk/codex/base_runtime.py +25 -0
- ksadk/codex/client.py +3 -1047
- ksadk/codex/client_payloads.py +85 -0
- ksadk/codex/rollout_checkpoint.py +264 -0
- ksadk/codex/runtime.py +290 -54
- ksadk/common/auth.py +2 -2
- ksadk/common/cloud_headers.py +36 -0
- ksadk/common/diagnostics.py +34 -0
- ksadk/common/kop_client.py +2 -1
- ksadk/configs/__init__.py +1 -1
- ksadk/configs/env_registry.py +216 -143
- ksadk/configs/env_registry_a2a.py +173 -0
- ksadk/configs/env_registry_studio.py +134 -0
- ksadk/configs/global_config.py +2 -1
- ksadk/configs/settings.py +9 -3
- ksadk/connector/__init__.py +17 -0
- ksadk/connector/channel.py +477 -0
- ksadk/context_engine/assembler.py +9 -0
- ksadk/context_engine/capabilities.py +52 -4
- ksadk/context_engine/contributors.py +80 -17
- ksadk/context_engine/instruction_authority.py +18 -0
- ksadk/conversations/attachment_storage.py +10 -3
- ksadk/conversations/attachments.py +69 -20
- ksadk/conversations/contracts.py +28 -9
- ksadk/conversations/message_projection.py +51 -155
- ksadk/conversations/message_projection_blocks.py +137 -0
- ksadk/conversations/model_context.py +11 -3
- ksadk/conversations/normalize.py +28 -10
- ksadk/conversations/projector.py +63 -0
- ksadk/conversations/runtime_baseline.py +37 -0
- ksadk/conversations/runtime_compaction.py +7 -2
- ksadk/conversations/runtime_input.py +16 -4
- ksadk/conversations/runtime_invocation.py +17 -4
- ksadk/conversations/runtime_observability.py +39 -10
- ksadk/conversations/runtime_payloads.py +12 -0
- ksadk/conversations/runtime_persistence.py +296 -32
- ksadk/conversations/runtime_preparation.py +98 -13
- ksadk/conversations/runtime_projection.py +217 -0
- ksadk/conversations/runtime_resume.py +141 -70
- ksadk/conversations/runtime_stream_events.py +29 -35
- ksadk/conversations/runtime_streaming.py +8 -0
- ksadk/conversations/tool_receipt_resume.py +387 -0
- ksadk/conversations/tool_receipts.py +32 -0
- ksadk/deployment/env_forward.py +5 -0
- ksadk/deployment/manager.py +15 -6
- ksadk/deployment/providers/serverless.py +76 -136
- ksadk/deployment/providers/serverless_payloads.py +122 -0
- ksadk/evaluation/agent_eval_client.py +2 -1
- ksadk/evaluation/contracts.py +78 -3
- ksadk/evaluation/evaluators.py +166 -1
- ksadk/evaluation/evidence.py +271 -4
- ksadk/evaluation/local_adapter.py +76 -12
- ksadk/evaluation/studio_build_adapter.py +73 -9
- ksadk/events/adapters/_a2a_checkpoint.py +151 -0
- ksadk/events/adapters/_a2a_snapshot.py +18 -14
- ksadk/events/adapters/_a2a_support.py +15 -3
- ksadk/events/adapters/_a2a_tool_activity.py +123 -0
- ksadk/events/adapters/_codex_errors.py +49 -0
- ksadk/events/adapters/_codex_items.py +16 -8
- ksadk/events/adapters/_langgraph_support.py +46 -1
- ksadk/events/adapters/a2a.py +54 -26
- ksadk/events/adapters/adk.py +188 -30
- ksadk/events/adapters/codex.py +33 -7
- ksadk/events/adapters/langgraph.py +16 -6
- ksadk/events/canonical.py +5 -0
- ksadk/events/canonical_store.py +200 -4
- ksadk/events/reducer.py +82 -0
- ksadk/events/run_authority.py +176 -0
- ksadk/events/session_event.py +2 -2
- ksadk/harness/__init__.py +18 -0
- ksadk/harness/app.py +11 -0
- ksadk/harness/artifact_adapters/__init__.py +1 -0
- ksadk/harness/artifact_adapters/native_page_budget.py +172 -0
- ksadk/harness/artifact_adapters/native_search.py +249 -0
- ksadk/harness/artifact_adapters/native_search_budget.py +134 -0
- ksadk/harness/artifact_adapters/native_store.py +115 -0
- ksadk/harness/artifact_adapters/native_tool.py +222 -0
- ksadk/harness/artifact_store.py +230 -0
- ksadk/harness/browser_adapters/__init__.py +6 -0
- ksadk/harness/browser_adapters/native_browser_tool.py +92 -0
- ksadk/harness/browser_adapters/native_dom_snapshot.py +187 -0
- ksadk/harness/browser_adapters/native_playwright.py +953 -0
- ksadk/harness/browser_adapters/native_vision.py +295 -0
- ksadk/harness/capabilities.py +115 -0
- ksadk/harness/capability_adapters/__init__.py +1 -0
- ksadk/harness/capability_adapters/native_dsh.py +289 -0
- ksadk/harness/capability_runtime.py +332 -0
- ksadk/harness/closure_contract.py +92 -0
- ksadk/harness/compaction_record.py +153 -0
- ksadk/harness/compiler.py +284 -0
- ksadk/harness/config.py +28 -5
- ksadk/harness/conformance/__init__.py +33 -0
- ksadk/harness/conformance/contract.py +504 -0
- ksadk/harness/conformance/fixtures.py +102 -0
- ksadk/harness/context_engine.py +388 -0
- ksadk/harness/context_maintenance.py +259 -0
- ksadk/harness/context_manifest.py +188 -0
- ksadk/harness/context_sections.py +397 -0
- ksadk/harness/context_tuning.py +168 -0
- ksadk/harness/diagnostic_adapters/__init__.py +1 -0
- ksadk/harness/diagnostic_adapters/contracts.py +70 -0
- ksadk/harness/diagnostic_adapters/lsp_rpc.py +210 -0
- ksadk/harness/diagnostic_adapters/native_lsp.py +286 -0
- ksadk/harness/draft_runtime.py +322 -0
- ksadk/harness/engine/__init__.py +40 -0
- ksadk/harness/engine/base.py +122 -0
- ksadk/harness/engine/budgets.py +108 -0
- ksadk/harness/engine/capability_declarations.py +59 -0
- ksadk/harness/engine/completion_guard.py +57 -0
- ksadk/harness/engine/context_pipeline.py +1351 -0
- ksadk/harness/engine/graph_builder.py +352 -0
- ksadk/harness/engine/hooked_reasoner.py +380 -0
- ksadk/harness/engine/langgraph.py +1049 -0
- ksadk/harness/engine/mcp_disclosure.py +701 -0
- ksadk/harness/engine/phases/__init__.py +6 -0
- ksadk/harness/engine/phases/context.py +48 -0
- ksadk/harness/engine/phases/interaction.py +31 -0
- ksadk/harness/engine/phases/reason.py +552 -0
- ksadk/harness/engine/phases/tools.py +638 -0
- ksadk/harness/engine/policy_runtime.py +81 -0
- ksadk/harness/engine/postgres_checkpointer.py +386 -0
- ksadk/harness/engine/run_control_bridge.py +100 -0
- ksadk/harness/engine/run_types.py +98 -0
- ksadk/harness/engine/skill_disclosure.py +275 -0
- ksadk/harness/engine/spans.py +41 -0
- ksadk/harness/engine/steering.py +177 -0
- ksadk/harness/engine/subagents.py +360 -0
- ksadk/harness/engine/thread_ids.py +112 -0
- ksadk/harness/engine/tool_dispatch.py +249 -0
- ksadk/harness/event_tree.py +212 -0
- ksadk/harness/events.py +498 -0
- ksadk/harness/execution_policy.py +104 -0
- ksadk/harness/hooks.py +259 -0
- ksadk/harness/insights.py +210 -0
- ksadk/harness/lifecycle.py +578 -0
- ksadk/harness/lifecycle_conformance.py +233 -0
- ksadk/harness/lifecycle_local_plane.py +104 -0
- ksadk/harness/loop/__init__.py +44 -0
- ksadk/harness/loop/reason.py +699 -0
- ksadk/harness/loop/tools.py +907 -0
- ksadk/harness/managed_runtime.py +1044 -0
- ksadk/harness/mcp_disclosure_contract.py +85 -0
- ksadk/harness/mcp_matrix.py +474 -0
- ksadk/harness/mcp_result_policy.py +44 -0
- ksadk/harness/mcp_runtime.py +504 -0
- ksadk/harness/memory_consolidation.py +157 -0
- ksadk/harness/memory_loop.py +156 -0
- ksadk/harness/memory_runtime.py +541 -0
- ksadk/harness/metrics.py +90 -0
- ksadk/harness/micro_compact.py +69 -0
- ksadk/harness/model_adapters/__init__.py +1 -0
- ksadk/harness/model_adapters/native_mcp_media.py +100 -0
- ksadk/harness/model_adapters/native_mcp_result.py +36 -0
- ksadk/harness/model_adapters/native_openai.py +703 -0
- ksadk/harness/model_capability.py +468 -0
- ksadk/harness/model_provider.py +430 -0
- ksadk/harness/multimodal.py +57 -0
- ksadk/harness/native/__init__.py +1 -0
- ksadk/harness/native/activation_contract.py +25 -0
- ksadk/harness/native/activation_recovery.py +29 -0
- ksadk/harness/native/adapters.py +291 -0
- ksadk/harness/native/artifact_contract.py +14 -0
- ksadk/harness/native/artifact_partial_read_capacity.py +171 -0
- ksadk/harness/native/artifact_read_capacity.py +182 -0
- ksadk/harness/native/artifact_read_contract.py +27 -0
- ksadk/harness/native/artifact_runtime.py +408 -0
- ksadk/harness/native/artifact_search_capacity.py +206 -0
- ksadk/harness/native/artifact_search_contract.py +40 -0
- ksadk/harness/native/artifact_single_read_capacity.py +170 -0
- ksadk/harness/native/browser_contract.py +229 -0
- ksadk/harness/native/browser_recovery.py +183 -0
- ksadk/harness/native/capabilities.py +204 -0
- ksadk/harness/native/child_approval.py +60 -0
- ksadk/harness/native/child_budget.py +136 -0
- ksadk/harness/native/child_cancellation.py +80 -0
- ksadk/harness/native/child_input.py +98 -0
- ksadk/harness/native/child_input_runtime.py +59 -0
- ksadk/harness/native/child_interruption.py +81 -0
- ksadk/harness/native/child_lifecycle.py +246 -0
- ksadk/harness/native/child_lifecycle_contract.py +91 -0
- ksadk/harness/native/child_notifications.py +75 -0
- ksadk/harness/native/child_promotion.py +66 -0
- ksadk/harness/native/command_runtime.py +99 -0
- ksadk/harness/native/completion.py +302 -0
- ksadk/harness/native/completion_text.py +116 -0
- ksadk/harness/native/context.py +358 -0
- ksadk/harness/native/context_artifact_page.py +75 -0
- ksadk/harness/native/context_compaction_projection.py +131 -0
- ksadk/harness/native/context_contributions.py +320 -0
- ksadk/harness/native/context_contributor_contract.py +133 -0
- ksadk/harness/native/context_driver.py +820 -0
- ksadk/harness/native/context_fresh_tools.py +49 -0
- ksadk/harness/native/context_history.py +272 -0
- ksadk/harness/native/context_microcompact.py +61 -0
- ksadk/harness/native/context_partial_summary.py +58 -0
- ksadk/harness/native/context_partition.py +492 -0
- ksadk/harness/native/context_pruning.py +275 -0
- ksadk/harness/native/context_reduction.py +60 -0
- ksadk/harness/native/context_replay.py +148 -0
- ksadk/harness/native/context_request_projection.py +526 -0
- ksadk/harness/native/context_runtime.py +976 -0
- ksadk/harness/native/context_runtime_contracts.py +409 -0
- ksadk/harness/native/context_search.py +112 -0
- ksadk/harness/native/context_source_fragments.py +188 -0
- ksadk/harness/native/context_source_progress.py +119 -0
- ksadk/harness/native/context_summary_planning.py +788 -0
- ksadk/harness/native/context_summary_recovery.py +105 -0
- ksadk/harness/native/delivery_review.py +331 -0
- ksadk/harness/native/delivery_review_contract.py +54 -0
- ksadk/harness/native/effect_admission.py +82 -0
- ksadk/harness/native/effect_control.py +318 -0
- ksadk/harness/native/effect_receipts.py +729 -0
- ksadk/harness/native/effect_runtime.py +303 -0
- ksadk/harness/native/effective_configuration.py +28 -0
- ksadk/harness/native/engine.py +945 -0
- ksadk/harness/native/final_output.py +34 -0
- ksadk/harness/native/final_submission.py +58 -0
- ksadk/harness/native/finalization_workspace.py +96 -0
- ksadk/harness/native/fork.py +151 -0
- ksadk/harness/native/guidance.py +91 -0
- ksadk/harness/native/history.py +381 -0
- ksadk/harness/native/hook_executor.py +205 -0
- ksadk/harness/native/hook_runtime_contract.py +282 -0
- ksadk/harness/native/interaction_observation.py +117 -0
- ksadk/harness/native/lease.py +103 -0
- ksadk/harness/native/machine.py +974 -0
- ksadk/harness/native/mcp_result_governance.py +156 -0
- ksadk/harness/native/model.py +570 -0
- ksadk/harness/native/model_feedback.py +63 -0
- ksadk/harness/native/model_input.py +30 -0
- ksadk/harness/native/model_recovery_contract.py +35 -0
- ksadk/harness/native/model_replay.py +128 -0
- ksadk/harness/native/model_request.py +133 -0
- ksadk/harness/native/model_runtime.py +196 -0
- ksadk/harness/native/model_takeover.py +419 -0
- ksadk/harness/native/model_tool_batch.py +40 -0
- ksadk/harness/native/observed_progress.py +46 -0
- ksadk/harness/native/operator_guidance.py +201 -0
- ksadk/harness/native/output_contract.py +80 -0
- ksadk/harness/native/output_recovery.py +24 -0
- ksadk/harness/native/ports.py +749 -0
- ksadk/harness/native/precompact_hook_runtime.py +171 -0
- ksadk/harness/native/replay_context.py +149 -0
- ksadk/harness/native/request_media.py +112 -0
- ksadk/harness/native/restore_contract.py +16 -0
- ksadk/harness/native/run_clock.py +120 -0
- ksadk/harness/native/state.py +436 -0
- ksadk/harness/native/steering.py +170 -0
- ksadk/harness/native/stop_hook_runtime.py +151 -0
- ksadk/harness/native/studio_admission.py +29 -0
- ksadk/harness/native/subagents.py +86 -0
- ksadk/harness/native/task_policy.py +99 -0
- ksadk/harness/native/task_progress.py +86 -0
- ksadk/harness/native/terminal_verification.py +43 -0
- ksadk/harness/native/tool_argument_feedback.py +178 -0
- ksadk/harness/native/tool_budget.py +253 -0
- ksadk/harness/native/tool_error_streak.py +89 -0
- ksadk/harness/native/tool_hook_runtime.py +343 -0
- ksadk/harness/native/tool_input_validation.py +58 -0
- ksadk/harness/native/tool_interruption.py +96 -0
- ksadk/harness/native/tool_observation.py +259 -0
- ksadk/harness/native/tool_progress.py +223 -0
- ksadk/harness/native/tool_recovery.py +25 -0
- ksadk/harness/native/tool_scheduling.py +33 -0
- ksadk/harness/native/tool_schema.py +126 -0
- ksadk/harness/native/transitions.py +151 -0
- ksadk/harness/native/turn_control.py +98 -0
- ksadk/harness/native/user_document.py +98 -0
- ksadk/harness/native/user_document_capture.py +49 -0
- ksadk/harness/native/user_input.py +87 -0
- ksadk/harness/native/verification.py +432 -0
- ksadk/harness/native/verification_binding.py +40 -0
- ksadk/harness/native/verification_runtime.py +233 -0
- ksadk/harness/native/verification_workspace.py +67 -0
- ksadk/harness/native_driver_failure.py +123 -0
- ksadk/harness/native_facade.py +977 -0
- ksadk/harness/native_factory.py +244 -0
- ksadk/harness/native_projection.py +503 -0
- ksadk/harness/native_runtime.py +621 -0
- ksadk/harness/native_shadow.py +250 -0
- ksadk/harness/native_shadow_inputs.py +146 -0
- ksadk/harness/observability/__init__.py +29 -0
- ksadk/harness/observability/inspection.py +528 -0
- ksadk/harness/observability/metrics.py +167 -0
- ksadk/harness/observability/otel_exporter.py +218 -0
- ksadk/harness/progress_adapters/__init__.py +5 -0
- ksadk/harness/progress_adapters/native_todo.py +75 -0
- ksadk/harness/prompt_cache.py +132 -0
- ksadk/harness/public_activity.py +213 -0
- ksadk/harness/public_output.py +30 -0
- ksadk/harness/public_summary.py +36 -0
- ksadk/harness/readiness.py +249 -0
- ksadk/harness/reasoner.py +779 -17
- ksadk/harness/release_readiness.py +140 -0
- ksadk/harness/resource_ref.py +69 -0
- ksadk/harness/rpc.py +200 -0
- ksadk/harness/run_control.py +773 -0
- ksadk/harness/runtime.py +157 -113
- ksadk/harness/runtime_capabilities.py +228 -0
- ksadk/harness/runtime_server.py +514 -0
- ksadk/harness/sandbox_adapters.py +739 -0
- ksadk/harness/sandbox_backend.py +733 -0
- ksadk/harness/sandbox_conformance.py +288 -0
- ksadk/harness/sandbox_lease.py +77 -0
- ksadk/harness/sandbox_lease_conformance.py +259 -0
- ksadk/harness/sandbox_matrix.py +170 -0
- ksadk/harness/sandbox_reconciliation.py +140 -0
- ksadk/harness/sandbox_recovery.py +586 -0
- ksadk/harness/sandbox_recovery_conformance.py +246 -0
- ksadk/harness/sdk.py +153 -0
- ksadk/harness/session_store.py +589 -0
- ksadk/harness/skill_adapters/__init__.py +1 -0
- ksadk/harness/skill_adapters/native_bundle.py +148 -0
- ksadk/harness/skill_adapters/native_disclosure.py +306 -0
- ksadk/harness/skill_composition.py +212 -0
- ksadk/harness/skill_feedback.py +123 -0
- ksadk/harness/skill_intent.py +47 -0
- ksadk/harness/skill_matrix.py +233 -0
- ksadk/harness/skill_runtime.py +317 -0
- ksadk/harness/spec.py +342 -0
- ksadk/harness/state.py +155 -0
- ksadk/harness/stores/__init__.py +14 -0
- ksadk/harness/stores/native_command_settlement.py +65 -0
- ksadk/harness/stores/native_contract.py +311 -0
- ksadk/harness/stores/native_memory.py +326 -0
- ksadk/harness/stores/native_memory_archive.py +70 -0
- ksadk/harness/stores/native_migration_cli.py +91 -0
- ksadk/harness/stores/native_outbox.py +56 -0
- ksadk/harness/stores/native_sqlite.py +782 -0
- ksadk/harness/stores/native_sqlite_audit.py +29 -0
- ksadk/harness/stores/native_sqlite_migration.py +252 -0
- ksadk/harness/strategies.py +149 -0
- ksadk/harness/subagent.py +263 -0
- ksadk/harness/subagent_adapters/checkpoint_recovery.py +120 -0
- ksadk/harness/subagent_adapters/native_background_child.py +803 -0
- ksadk/harness/subagent_adapters/native_child.py +819 -0
- ksadk/harness/subagent_adapters/native_child_approval.py +128 -0
- ksadk/harness/subagent_adapters/native_child_continuation.py +51 -0
- ksadk/harness/subagent_adapters/native_child_result.py +392 -0
- ksadk/harness/subagent_adapters/prepared_recovery.py +120 -0
- ksadk/harness/tool_display.py +75 -0
- ksadk/harness/tool_display_contract.py +134 -0
- ksadk/harness/tool_output.py +141 -0
- ksadk/harness/tool_policy.py +134 -0
- ksadk/harness/tool_receipts.py +96 -0
- ksadk/harness/tool_reliability.py +81 -0
- ksadk/harness/tool_result_policy.py +216 -0
- ksadk/harness/tools.py +52 -0
- ksadk/harness/user_errors.py +69 -0
- ksadk/harness/working_context.py +81 -0
- ksadk/harness/working_context_patch.py +99 -0
- ksadk/harness/workspace_adapters/__init__.py +6 -0
- ksadk/harness/workspace_adapters/native_directory.py +180 -0
- ksadk/harness/workspace_adapters/native_git.py +208 -0
- ksadk/harness/workspace_adapters/native_isolation.py +350 -0
- ksadk/identity/resolver.py +18 -0
- ksadk/interaction/__init__.py +1 -1
- ksadk/interaction/ledger.py +1 -1
- ksadk/interaction/provider.py +1 -1
- ksadk/interaction/providers/__init__.py +3 -1
- ksadk/interaction/providers/adk.py +1 -1
- ksadk/interaction/providers/codex.py +1 -1
- ksadk/interaction/providers/harness.py +50 -0
- ksadk/interaction/providers/langgraph.py +9 -2
- ksadk/kernel/__init__.py +10 -0
- ksadk/kernel/approval_presentation.py +91 -0
- ksadk/kernel/authorization.py +1 -1
- ksadk/kernel/bootstrap.py +220 -252
- ksadk/kernel/contract_fingerprints.py +45 -1
- ksadk/kernel/contracts.py +30 -0
- ksadk/kernel/control.py +180 -29
- ksadk/kernel/execution_grants.py +428 -0
- ksadk/kernel/execution_grants_memory.py +252 -0
- ksadk/kernel/execution_grants_postgres.py +395 -0
- ksadk/kernel/execution_grants_sqlite.py +435 -0
- ksadk/kernel/execution_host_ingress.py +1071 -0
- ksadk/kernel/history_projection.py +120 -0
- ksadk/kernel/ingress.py +139 -226
- ksadk/kernel/ingress_bootstrap.py +268 -0
- ksadk/kernel/legacy_history.py +179 -0
- ksadk/kernel/mapping.py +1 -1
- ksadk/kernel/memory_store.py +61 -58
- ksadk/kernel/memory_store_projection.py +63 -0
- ksadk/kernel/postgres_event_log.py +181 -0
- ksadk/kernel/postgres_store.py +230 -231
- ksadk/kernel/readiness.py +125 -0
- ksadk/kernel/recovery.py +166 -16
- ksadk/kernel/recovery_projection.py +124 -0
- ksadk/kernel/runtime_checkpoint.py +34 -0
- ksadk/kernel/sql/001_agent_kernel.sql +28 -0
- ksadk/kernel/sqlite_schema.py +100 -0
- ksadk/kernel/sqlite_store.py +410 -200
- ksadk/kernel/state.py +2 -3
- ksadk/kernel/store.py +104 -5
- ksadk/kernel/teams_artifact_tools.py +392 -0
- ksadk/kernel/teams_effects.py +851 -0
- ksadk/kernel/teams_execution_context.py +408 -0
- ksadk/kernel/teams_host_http.py +237 -0
- ksadk/kernel/teams_material_transport.py +245 -0
- ksadk/kernel/teams_materials.py +318 -0
- ksadk/kernel/teams_runtime_bootstrap.py +604 -0
- ksadk/kernel/teams_tool_runtime.py +273 -0
- ksadk/kernel/teams_workspace.py +259 -0
- ksadk/kernel/worker.py +369 -340
- ksadk/kernel/worker_controls.py +454 -0
- ksadk/kernel/worker_history.py +72 -0
- ksadk/kernel/worker_identity.py +74 -0
- ksadk/kernel/worker_interactions.py +197 -0
- ksadk/knowledge_base/client.py +15 -1
- ksadk/managed_runtime.py +29 -2
- ksadk/memory/adk/backends/http_ltm_backend.py +2 -1
- ksadk/memory/adk/backends/sdk_ltm_backend.py +15 -1
- ksadk/memory/adk/bounded_database_session_service.py +232 -0
- ksadk/memory/adk/resilient_session_service.py +115 -15
- ksadk/memory/adk/short_term_memory.py +8 -9
- ksadk/memory/coordinator.py +22 -6
- ksadk/memory/extraction.py +159 -7
- ksadk/memory/models.py +77 -1
- ksadk/memory/provider_resolver.py +5 -0
- ksadk/memory/providers/local_candidates.py +183 -0
- ksadk/memory/providers/local_postgres.py +200 -0
- ksadk/memory/providers/local_sqlite.py +280 -67
- ksadk/memory/resolved_policy.py +12 -7
- ksadk/memory/retrieval.py +189 -0
- ksadk/memory/store_adapter.py +150 -0
- ksadk/model_gateway/__init__.py +29 -0
- ksadk/model_gateway/client.py +253 -0
- ksadk/model_gateway/events.py +113 -0
- ksadk/model_gateway/matrix.py +297 -0
- ksadk/model_policy.py +2 -2
- ksadk/model_proxy/compat.py +670 -0
- ksadk/model_proxy/detect.py +254 -0
- ksadk/model_proxy/server.py +14 -9
- ksadk/model_proxy/transform.py +72 -6
- ksadk/plugins/__init__.py +1 -1
- ksadk/plugins/bridges/dsh.py +29 -20
- ksadk/plugins/bridges/dsh_profile_manifest.py +36 -0
- ksadk/plugins/builtin_resources.py +199 -0
- ksadk/plugins/builtins.py +417 -185
- ksadk/plugins/companion_artifacts.py +83 -0
- ksadk/plugins/companions.py +368 -0
- ksadk/plugins/context_contributor.py +15 -4
- ksadk/plugins/contracts.py +1 -1
- ksadk/plugins/dsh_channels.py +156 -0
- ksadk/plugins/dsh_dependency_policy.py +41 -0
- ksadk/plugins/dsh_home.py +140 -0
- ksadk/plugins/dsh_teams.py +105 -0
- ksadk/plugins/dsh_toolchain.py +92 -21
- ksadk/plugins/execution_host.py +107 -0
- ksadk/plugins/host.py +73 -5
- ksadk/plugins/kernel_adapter.py +44 -1
- ksadk/plugins/memory_provider.py +180 -0
- ksadk/plugins/providers/_process_group.py +50 -0
- ksadk/plugins/providers/bundles/dsh-channels-client/client.js +19 -0
- ksadk/plugins/providers/bundles/dsh-channels-client/cordis.patch.yml +3 -0
- ksadk/plugins/providers/bundles/dsh-channels-client/index.mjs +7 -0
- ksadk/plugins/providers/bundles/dsh-channels-client/package.json +12 -0
- ksadk/plugins/providers/bundles/dsh-knowledge/index.mjs +24 -2
- ksadk/plugins/providers/bundles/dsh-knowledge/package.json +1 -1
- ksadk/plugins/providers/bundles/dsh-memory/package.json +1 -1
- ksadk/plugins/providers/bundles/dsh-skill-center/package.json +1 -1
- ksadk/plugins/providers/bundles/dsh-teams-client/client.js +29 -0
- ksadk/plugins/providers/bundles/dsh-teams-client/cordis.patch.yml +3 -0
- ksadk/plugins/providers/bundles/dsh-teams-client/index.mjs +11 -0
- ksadk/plugins/providers/bundles/dsh-teams-client/package.json +35 -0
- ksadk/plugins/providers/bundles/dsh-teams-leader-policy/cordis.patch.yml +3 -0
- ksadk/plugins/providers/bundles/dsh-teams-leader-policy/index.mjs +13 -0
- ksadk/plugins/providers/bundles/dsh-teams-leader-policy/package.json +27 -0
- ksadk/plugins/providers/bundles/dsh-teams-profile/cordis.patch.yml +3 -0
- ksadk/plugins/providers/bundles/dsh-teams-profile/index.mjs +12 -0
- ksadk/plugins/providers/bundles/dsh-teams-profile/package.json +26 -0
- ksadk/plugins/providers/bundles/dsh-teams-router/cordis.patch.yml +3 -0
- ksadk/plugins/providers/bundles/dsh-teams-router/index.mjs +16 -0
- ksadk/plugins/providers/bundles/dsh-teams-router/package.json +27 -0
- ksadk/plugins/providers/bundles/dsh-teams-tasks/cordis.patch.yml +3 -0
- ksadk/plugins/providers/bundles/dsh-teams-tasks/index.mjs +16 -0
- ksadk/plugins/providers/bundles/dsh-teams-tasks/package.json +27 -0
- ksadk/plugins/providers/bundles/dsh-teams-tools/cordis.patch.yml +3 -0
- ksadk/plugins/providers/bundles/dsh-teams-tools/index.mjs +25 -0
- ksadk/plugins/providers/bundles/dsh-teams-tools/package.json +29 -0
- ksadk/plugins/providers/bundles/dsh-teams-tools/tools.json +235 -0
- ksadk/plugins/providers/bundles/ksadk-codex/index.mjs +1 -1
- ksadk/plugins/providers/bundles/ksadk-dsh-capability-host/index.mjs +51 -1
- ksadk/plugins/providers/bundles/ksadk-dsh-capability-host/package.json +2 -2
- ksadk/plugins/providers/bundles/ksadk-dsh-companion-host/client.mjs +133 -0
- ksadk/plugins/providers/bundles/ksadk-dsh-companion-host/index.mjs +14 -0
- ksadk/plugins/providers/bundles/ksadk-dsh-studio/client.js +27 -4
- ksadk/plugins/providers/bundles/ksadk-dsh-studio/index.mjs +9 -5
- ksadk/plugins/providers/bundles/ksadk-harness/index.mjs +1 -1
- ksadk/plugins/providers/codex.py +52 -40
- ksadk/plugins/providers/codex_native.py +20 -0
- ksadk/plugins/providers/codex_skills.py +46 -0
- ksadk/plugins/providers/dsh_capabilities.py +49 -143
- ksadk/plugins/providers/dsh_connector_lease.py +225 -0
- ksadk/plugins/providers/dsh_mcp.py +163 -1
- ksadk/plugins/providers/harness.py +413 -52
- ksadk/plugins/providers/harness_context.py +61 -0
- ksadk/plugins/providers/harness_contributions.py +241 -0
- ksadk/plugins/providers/harness_delegation.py +670 -0
- ksadk/plugins/providers/harness_hooks.py +121 -0
- ksadk/plugins/providers/harness_managed.py +550 -0
- ksadk/plugins/providers/harness_tools.py +455 -0
- ksadk/plugins/providers/legacy_catalog.py +1 -1
- ksadk/plugins/providers/mcp_projection.py +100 -3
- ksadk/plugins/providers/platform_resources.py +16 -6
- ksadk/plugins/providers/shipped_dsh.py +4 -1
- ksadk/plugins/subagent_providers/codex.py +28 -6
- ksadk/plugins/teams/__init__.py +5 -0
- ksadk/plugins/teams/api.py +405 -0
- ksadk/plugins/teams/application.py +540 -0
- ksadk/plugins/teams/artifacts.py +60 -0
- ksadk/plugins/teams/build_artifacts.py +460 -0
- ksadk/plugins/teams/cloud_contract_fingerprints.py +22 -0
- ksadk/plugins/teams/cloud_contracts.py +928 -0
- ksadk/plugins/teams/cloud_permits.py +250 -0
- ksadk/plugins/teams/context.py +96 -0
- ksadk/plugins/teams/contracts.py +136 -0
- ksadk/plugins/teams/domain.py +1480 -0
- ksadk/plugins/teams/domain_values.py +24 -0
- ksadk/plugins/teams/effect_contracts.py +255 -0
- ksadk/plugins/teams/errors.py +13 -0
- ksadk/plugins/teams/execution_projection.py +255 -0
- ksadk/plugins/teams/leader_decisions.py +106 -0
- ksadk/plugins/teams/migration.py +311 -0
- ksadk/plugins/teams/migration_cli.py +322 -0
- ksadk/plugins/teams/postgres_store.py +352 -0
- ksadk/plugins/teams/release_contracts.py +60 -0
- ksadk/plugins/teams/runtime.py +853 -0
- ksadk/plugins/teams/source_projection.py +84 -0
- ksadk/plugins/teams/store.py +519 -0
- ksadk/plugins/teams/task_decisions.py +436 -0
- ksadk/plugins/teams/tool_service.py +152 -0
- ksadk/plugins/teams/transport.py +96 -0
- ksadk/plugins/teams/workspaces.py +255 -0
- ksadk/resource_runtime/skill_runtime.py +3 -0
- ksadk/resource_runtime/socket_server.py +11 -0
- ksadk/resource_runtime/worker.py +28 -4
- ksadk/runners/_adk_a2a_stream.py +122 -0
- ksadk/runners/_adk_canonical_stream.py +474 -0
- ksadk/runners/_langgraph_canonical_streams.py +527 -0
- ksadk/runners/_langgraph_runner_streams.py +83 -401
- ksadk/runners/_langgraph_state_reader.py +106 -0
- ksadk/runners/_langgraph_tool_projection.py +86 -0
- ksadk/runners/_langgraph_tools_transformer.py +27 -0
- ksadk/runners/_session_identity.py +285 -0
- ksadk/runners/adk_runner.py +220 -350
- ksadk/runners/base_runner.py +6 -5
- ksadk/runners/langgraph_runner.py +208 -195
- ksadk/runners/patch_langchain.py +47 -0
- ksadk/runners/usage_accumulator.py +11 -3
- ksadk/runners/utils/loader.py +28 -14
- ksadk/runtime/_runner_adapter/a2ui_surface.py +145 -0
- ksadk/runtime/_runner_adapter/gateway_approvals.py +93 -0
- ksadk/runtime/_runner_adapter/stream_mapping.py +134 -129
- ksadk/runtime/adapter.py +40 -3
- ksadk/runtime/conversation_execution.py +29 -3
- ksadk/runtime/executor.py +105 -7
- ksadk/runtime/factory.py +45 -3
- ksadk/runtime/framework_adapters.py +184 -10
- ksadk/runtime/hosted_finalizer.py +4 -6
- ksadk/runtime/launch.py +2 -0
- ksadk/runtime/preprocessing.py +11 -3
- ksadk/runtime/runner_adapter.py +160 -21
- ksadk/runtime/skill_eval_result.py +36 -0
- ksadk/runtime/timing.py +46 -0
- ksadk/runtime/usage.py +49 -18
- ksadk/runtime_context.py +105 -1
- ksadk/sandbox/backends/e2b.py +272 -24
- ksadk/sandbox/backends/local_process.py +73 -39
- ksadk/sandbox/base.py +62 -1
- ksadk/sandbox/diagnostics.py +82 -0
- ksadk/sandbox/e2b_connection.py +9 -1
- ksadk/sandbox/local_controls.py +776 -0
- ksadk/sandbox/local_launcher.py +124 -0
- ksadk/scheduler/dispatcher.py +1 -1
- ksadk/server/factory.py +178 -25
- ksadk/server/history_deadline.py +158 -0
- ksadk/server/history_page_cache.py +129 -0
- ksadk/server/invocation_identity.py +118 -0
- ksadk/server/routes/checkpoint_audit.py +88 -0
- ksadk/server/routes/checkpoint_listing.py +294 -0
- ksadk/server/routes/checkpoint_resolution.py +73 -20
- ksadk/server/routes/common.py +32 -3
- ksadk/server/routes/control.py +112 -9
- ksadk/server/routes/dependencies.py +2 -1
- ksadk/server/routes/display_projection.py +154 -0
- ksadk/server/routes/kernel_ingress.py +26 -3
- ksadk/server/routes/misc.py +331 -33
- ksadk/server/routes/models.py +28 -4
- ksadk/server/routes/openai_compat.py +82 -13
- ksadk/server/routes/projection.py +159 -216
- ksadk/server/routes/run.py +112 -37
- ksadk/server/routes/sessions.py +493 -358
- ksadk/server/routes/streaming.py +68 -15
- ksadk/server/routes/tool_receipt_claim_routes.py +107 -0
- ksadk/server/routes/workspace.py +135 -23
- ksadk/server/static/assets/{ArtifactsPanel-CGbWlMNh.js → ArtifactsPanel-CILaW-fC.js} +1 -1
- ksadk/server/static/assets/{CodeBlock-b4C7upmO.js → CodeBlock-BVrNVtJC.js} +10 -7
- ksadk/server/static/assets/MathMessageMarkdown-Dp7c4wWD.js +8 -0
- ksadk/server/static/assets/{MermaidBlock-BEBN4Ksz.js → MermaidBlock-Dxop8Rd7.js} +9 -9
- ksadk/server/static/assets/{NativeTerminalPanel-zvL-WpAn.js → NativeTerminalPanel-Cjjz8B30.js} +1 -1
- ksadk/server/static/assets/{abnfDiagram-VCTEODGH-BYafW7Za.js → abnfDiagram-VCTEODGH-ckWDmOzw.js} +1 -1
- ksadk/server/static/assets/{arc-bTohInsS.js → arc-DqxJede-.js} +1 -1
- ksadk/server/static/assets/architecture-7GRP2DOG-pn_DuLy6.js +1 -0
- ksadk/server/static/assets/{architectureDiagram-5GKGNRK7-Ch5Lbzsi.js → architectureDiagram-5GKGNRK7-SEQA4bVi.js} +1 -1
- ksadk/server/static/assets/{blockDiagram-NRAW4CY4-kqF4MDOG.js → blockDiagram-NRAW4CY4-pM0B-6NJ.js} +1 -1
- ksadk/server/static/assets/{c4Diagram-UCG6FXSJ-8uSRIODv.js → c4Diagram-UCG6FXSJ-m2tuCNVq.js} +1 -1
- ksadk/server/static/assets/channel-fySsnkft.js +1 -0
- ksadk/server/static/assets/chunk-2Q5K7J3B-BheGxKRQ.js +1 -0
- ksadk/server/static/assets/{chunk-5VM5RSS4-DkhehZDr.js → chunk-5VM5RSS4-GJHDr9Ww.js} +1 -1
- ksadk/server/static/assets/{chunk-F27PBJKO-BdXhtPe9.js → chunk-F27PBJKO-CbAN45AV.js} +1 -1
- ksadk/server/static/assets/{chunk-G27WJ6UU-DPTpvpwi.js → chunk-G27WJ6UU-D5ngbbzF.js} +1 -1
- ksadk/server/static/assets/{chunk-JWPE2WC7-Pqoh38el.js → chunk-JWPE2WC7-Cc5IwuYC.js} +1 -1
- ksadk/server/static/assets/{chunk-LCL6LL3I-DeU00qC-.js → chunk-LCL6LL3I-CprgDDdJ.js} +1 -1
- ksadk/server/static/assets/{chunk-POPQ4Y6H-CzxScFkr.js → chunk-POPQ4Y6H-CDZhSy82.js} +1 -1
- ksadk/server/static/assets/{chunk-RHFEMEQ7-DpqMx-ux.js → chunk-RHFEMEQ7-CZchUNro.js} +1 -1
- ksadk/server/static/assets/{chunk-SVP7TREG-C6t0SypQ.js → chunk-SVP7TREG-BVruqk6T.js} +1 -1
- ksadk/server/static/assets/{chunk-XXDRQBXY-DVaeafZk.js → chunk-XXDRQBXY-4ld9SxPN.js} +1 -1
- ksadk/server/static/assets/classDiagram-DTDB5LWJ-DSfLtNYm.js +1 -0
- ksadk/server/static/assets/classDiagram-v2-JRS7N3AN-DSfLtNYm.js +1 -0
- ksadk/server/static/assets/{cose-bilkent-JH36ORCC-Bf9D3tzJ.js → cose-bilkent-JH36ORCC-Dmyyk_Vp.js} +1 -1
- ksadk/server/static/assets/cynefin-OW5HDTMX-PFWIGtvA.js +1 -0
- ksadk/server/static/assets/{cynefinDiagram-5FMLGOSQ-B9cY3iTz.js → cynefinDiagram-5FMLGOSQ-BIyq3EJb.js} +1 -1
- ksadk/server/static/assets/{dagre-3AP2YEHR-CSwlx3CB.js → dagre-3AP2YEHR-eBw08Qdk.js} +1 -1
- ksadk/server/static/assets/{dagre-UBpgon5q.js → dagre-DfvnEf45.js} +1 -1
- ksadk/server/static/assets/{diagram-S7CK7UJ4-C9akhN9a.js → diagram-S7CK7UJ4-CUSrE3Mg.js} +1 -1
- ksadk/server/static/assets/{diagram-UQ7AKVKN-CgedhTPI.js → diagram-UQ7AKVKN-Dq5Zw2gy.js} +1 -1
- ksadk/server/static/assets/{diagram-VSXAHHWV-Cjucz5BY.js → diagram-VSXAHHWV-DyUHfNwT.js} +1 -1
- ksadk/server/static/assets/{diagram-VX7I27RA-Dd4Vleyn.js → diagram-VX7I27RA-CREmM89O.js} +1 -1
- ksadk/server/static/assets/{diagram-Z3DM3KII-CZ2jGtYW.js → diagram-Z3DM3KII-Dw9zhHUK.js} +1 -1
- ksadk/server/static/assets/{dist-Bj730Ib4.js → dist-0uJ4tdx6.js} +1 -1
- ksadk/server/static/assets/{dist-BnaTiyzN.js → dist-AEv-vXf-.js} +1 -1
- ksadk/server/static/assets/{dist-BgV_owcB.js → dist-B49GzZDb.js} +1 -1
- ksadk/server/static/assets/{dist-D_ctSS2i.js → dist-B8Myiet9.js} +1 -1
- ksadk/server/static/assets/{dist-ufY3F5p6.js → dist-BBsYarrI.js} +2 -2
- ksadk/server/static/assets/{dist-ClYUxfeK.js → dist-BQMrUwdI.js} +1 -1
- ksadk/server/static/assets/{dist-CFzsn6BG.js → dist-BX_-FENW.js} +1 -1
- ksadk/server/static/assets/{dist-B3FR1SKK.js → dist-CD4L6ymH.js} +1 -1
- ksadk/server/static/assets/{dist-Cf125P_m.js → dist-CHpW1BHj.js} +1 -1
- ksadk/server/static/assets/{dist-DVCOWtha.js → dist-CVPau3tn.js} +1 -1
- ksadk/server/static/assets/{dist-DFD6Qa6T.js → dist-C_qdxcSH.js} +1 -1
- ksadk/server/static/assets/{dist-BIr4DSRq.js → dist-Co68Apq4.js} +1 -1
- ksadk/server/static/assets/{dist-DiixqL0J.js → dist-Cp2PaOMY.js} +1 -1
- ksadk/server/static/assets/{dist-fBO2v5Kt.js → dist-CuR5Bgme.js} +1 -1
- ksadk/server/static/assets/{dist-DoVSwoDb.js → dist-DDSyLEOX.js} +1 -1
- ksadk/server/static/assets/{dist-C5_ZAZsG.js → dist-DUxO0R99.js} +1 -1
- ksadk/server/static/assets/{dist-C1NMAY5a.js → dist-QzbGrED_.js} +1 -1
- ksadk/server/static/assets/dist-bupkyEBZ.js +1 -0
- ksadk/server/static/assets/{dist-DvFK7p5S.js → dist-cxTGfdqx.js} +1 -1
- ksadk/server/static/assets/{dist-CB9iJrvg.js → dist-hL5p1til.js} +1 -1
- ksadk/server/static/assets/{dist-btbmmX5O.js → dist-lOy23y43.js} +1 -1
- ksadk/server/static/assets/{dist-QfkEHOlb.js → dist-pq-nD33R.js} +1 -1
- ksadk/server/static/assets/{ebnfDiagram-PWID7BFC-Ci8NqqZu.js → ebnfDiagram-PWID7BFC-BS5LdNoR.js} +1 -1
- ksadk/server/static/assets/{erDiagram-SSCWMZ5O-CCIOhLZG.js → erDiagram-SSCWMZ5O-Bv1QtiY-.js} +1 -1
- ksadk/server/static/assets/eventmodeling-NTZA5JFV-DsM4upQX.js +1 -0
- ksadk/server/static/assets/flowDiagram-A5DVABFB-D5NA16k9.js +1 -0
- ksadk/server/static/assets/{ganttDiagram-EL5Y4UJY-Cp_r9Hb6.js → ganttDiagram-EL5Y4UJY-musi-e0G.js} +1 -1
- ksadk/server/static/assets/gitGraph-4MIJSDKK-DUCVz-ih.js +1 -0
- ksadk/server/static/assets/{gitGraphDiagram-WWUBYQGX-Dlhc8Wr8.js → gitGraphDiagram-WWUBYQGX-DH37EGkG.js} +1 -1
- ksadk/server/static/assets/index-CZdkAvsv.js +244 -0
- ksadk/server/static/assets/index-CvXdHgF3.css +2 -0
- ksadk/server/static/assets/info-A6RAGUB7-rw0ZNHZp.js +1 -0
- ksadk/server/static/assets/{infoDiagram-RXCK75RN-CO0rRTRA.js → infoDiagram-RXCK75RN-C1kEtv2y.js} +1 -1
- ksadk/server/static/assets/{ishikawaDiagram-5VMMS53U-CHiaedSS.js → ishikawaDiagram-5VMMS53U-BCNPyMka.js} +1 -1
- ksadk/server/static/assets/{journeyDiagram-EYS64GPL-CHcCIB09.js → journeyDiagram-EYS64GPL--cDbKnjP.js} +1 -1
- ksadk/server/static/assets/{kanban-definition-3QL26DDD-CJ_ebBZf.js → kanban-definition-3QL26DDD-R1rAVw2f.js} +1 -1
- ksadk/server/static/assets/{katex-B4weu383.js → katex-BT-X-V7U.js} +1 -1
- ksadk/server/static/assets/{linear-V-MgYHW1.js → linear-DTR631iG.js} +1 -1
- ksadk/server/static/assets/{mermaid-parser.core-CBijEX_c.js → mermaid-parser.core-DfFzJhX8.js} +2 -2
- ksadk/server/static/assets/{mindmap-definition-FBJOCRG2-Bc-pQvpp.js → mindmap-definition-FBJOCRG2-D4by_rmk.js} +1 -1
- ksadk/server/static/assets/packet-AYTQ26CC-Ca4Hvki9.js +1 -0
- ksadk/server/static/assets/{pegDiagram-XKGWAZYB-D7genGLl.js → pegDiagram-XKGWAZYB-xWXPEh0c.js} +1 -1
- ksadk/server/static/assets/pie-WAS4IAKB-hwiz6fbw.js +1 -0
- ksadk/server/static/assets/{pieDiagram-E7YTZNPT-Bxj32zwD.js → pieDiagram-E7YTZNPT-BudBDlCI.js} +1 -1
- ksadk/server/static/assets/{quadrantDiagram-AXDQQJYC-BURv2mGh.js → quadrantDiagram-AXDQQJYC-DXZ0PCJF.js} +1 -1
- ksadk/server/static/assets/radar-RG4KPBEZ-BR1oZXLM.js +1 -0
- ksadk/server/static/assets/railroad-74A4TZTK-DfgEISfX.js +1 -0
- ksadk/server/static/assets/railroad-abnf-HS5TGJTU-CWOC3rdk.js +1 -0
- ksadk/server/static/assets/railroad-ebnf-LZEXJU2U-CiRvHCLY.js +1 -0
- ksadk/server/static/assets/railroad-peg-WCYAUIDC-DSDDyJ2f.js +1 -0
- ksadk/server/static/assets/{railroadDiagram-O6MQD6OU-CCsh3avW.js → railroadDiagram-O6MQD6OU-BdAYRYB8.js} +1 -1
- ksadk/server/static/assets/{requirementDiagram-EFPCY7ZU-_FRRBKEd.js → requirementDiagram-EFPCY7ZU-CBBmaL70.js} +1 -1
- ksadk/server/static/assets/{sankeyDiagram-P5KCCOFB-C-gr2o9M.js → sankeyDiagram-P5KCCOFB-Doc3rdwp.js} +1 -1
- ksadk/server/static/assets/{sequenceDiagram-WJ2MYXX4-D97NmfKg.js → sequenceDiagram-WJ2MYXX4-0J8R8hWW.js} +1 -1
- ksadk/server/static/assets/{sizeCapture-X5ZJPWSS-DjrPC5FX.js → sizeCapture-X5ZJPWSS-CfFLlWsK.js} +1 -1
- ksadk/server/static/assets/{stateDiagram-HBIQ2CUA-DzMNg1hh.js → stateDiagram-HBIQ2CUA-jBwkjtTy.js} +1 -1
- ksadk/server/static/assets/stateDiagram-v2-4QOOHH4V-Cw1fPb5w.js +1 -0
- ksadk/server/static/assets/{swimlanes-XN3QIQJK-Cssf_CsU.js → swimlanes-XN3QIQJK-B0WxTQf8.js} +1 -1
- ksadk/server/static/assets/swimlanesDiagram-VK2B7HYN-Cc3JMBAF.js +8 -0
- ksadk/server/static/assets/{timeline-definition-24CTP7MA-BWTHzyS1.js → timeline-definition-24CTP7MA-BfCT_75A.js} +1 -1
- ksadk/server/static/assets/treeView-Q6P3EWNA-C05SJHxo.js +1 -0
- ksadk/server/static/assets/treemap-WGGIJYW6-BqNLAhc3.js +1 -0
- ksadk/server/static/assets/{vennDiagram-4TSXK5OY-BSKgJsmR.js → vennDiagram-4TSXK5OY-9gX1VMDC.js} +1 -1
- ksadk/server/static/assets/wardley-WFR3VGLG-DokNktqB.js +1 -0
- ksadk/server/static/assets/{wardleyDiagram-VM6X3IG4-eflHNoaZ.js → wardleyDiagram-VM6X3IG4-sEs_BP6O.js} +1 -1
- ksadk/server/static/assets/{xychartDiagram-S5SC5T6Z-eYqrQ-v4.js → xychartDiagram-S5SC5T6Z-Ll4jvUN9.js} +1 -1
- ksadk/server/static/index.html +2 -2
- ksadk/server/terminal_sessions.py +34 -2
- ksadk/sessions/__init__.py +8 -1
- ksadk/sessions/_checkpoint_resume_audit.py +44 -0
- ksadk/sessions/_in_memory_query.py +112 -0
- ksadk/sessions/_local_service_sync.py +157 -156
- ksadk/sessions/_local_state_sync.py +152 -0
- ksadk/sessions/_local_tables.py +2 -0
- ksadk/sessions/_postgres_checkpoint_read.py +323 -0
- ksadk/sessions/_postgres_checkpoint_stats.py +330 -0
- ksadk/sessions/_postgres_history_read.py +678 -0
- ksadk/sessions/_postgres_schema.py +44 -2
- ksadk/sessions/_postgres_tables.py +2 -0
- ksadk/sessions/_postgres_tool_receipts.py +169 -0
- ksadk/sessions/_resilient_read.py +630 -0
- ksadk/sessions/_tool_receipt_sync.py +119 -0
- ksadk/sessions/agent_identity.py +16 -0
- ksadk/sessions/base.py +278 -0
- ksadk/sessions/db_budget.py +332 -0
- ksadk/sessions/errors.py +12 -0
- ksadk/sessions/history_budget.py +36 -0
- ksadk/sessions/history_identity.py +27 -0
- ksadk/sessions/in_memory.py +376 -113
- ksadk/sessions/invocation_identity.py +235 -0
- ksadk/sessions/local_service.py +345 -0
- ksadk/sessions/postgres_service.py +515 -549
- ksadk/sessions/resilience.py +21 -14
- ksadk/sessions/resilient.py +611 -504
- ksadk/skills/__init__.py +26 -0
- ksadk/skills/events.py +464 -0
- ksadk/skills/loader.py +44 -2
- ksadk/skills/manifest_cache.py +263 -0
- ksadk/skills/mcp_server/__init__.py +0 -0
- ksadk/skills/mcp_server/_registry.py +33 -0
- ksadk/skills/mcp_server/_routing.py +26 -0
- ksadk/skills/mcp_server/_workspace_files.py +160 -0
- ksadk/skills/mcp_server/register.py +415 -0
- ksadk/skills/mcp_server/server.py +218 -0
- ksadk/skills/models.py +11 -0
- ksadk/skills/observability.py +132 -0
- ksadk/skills/package_store.py +75 -2
- ksadk/skills/runtime/agent.py +38 -5
- ksadk/skills/runtime/artifacts.py +87 -0
- ksadk/skills/runtime/backends/e2b.py +400 -56
- ksadk/skills/runtime/backends/local.py +621 -119
- ksadk/skills/runtime/base.py +78 -7
- ksadk/skills/runtime/executor.py +266 -1
- ksadk/skills/runtime/loader.py +108 -3
- ksadk/skills/runtime/request.py +18 -0
- ksadk/skills/service_client.py +6 -1
- ksadk/skills/tool_defs.py +108 -3
- ksadk/studio/a2a_bindings.py +407 -0
- ksadk/studio/a2a_orchestration.py +178 -0
- ksadk/studio/active_run_output.py +92 -0
- ksadk/studio/activity_records.py +542 -0
- ksadk/studio/agent_configuration.py +173 -0
- ksadk/studio/api.py +784 -419
- ksadk/studio/api_a2a_routes.py +93 -0
- ksadk/studio/api_catalog_routes.py +13 -0
- ksadk/studio/api_cloud_chat_routes.py +382 -0
- ksadk/studio/api_contracts.py +31 -2
- ksadk/studio/api_plugin_routes.py +39 -12
- ksadk/studio/api_resource_connections.py +79 -41
- ksadk/studio/attachment_store.py +14 -2
- ksadk/studio/authoring.py +12 -6
- ksadk/studio/authoring_coordinator.py +4 -2
- ksadk/studio/build_resolution.py +117 -0
- ksadk/studio/build_singleflight.py +37 -0
- ksadk/studio/builder.py +32 -2
- ksadk/studio/capabilities.py +31 -9
- ksadk/studio/channel_connections.py +333 -0
- ksadk/studio/cloud.py +113 -387
- ksadk/studio/cloud_gateways.py +424 -0
- ksadk/studio/cloud_shared_web.py +82 -2
- ksadk/studio/codex_agent_service.py +19 -2
- ksadk/studio/codex_builder.py +1 -1
- ksadk/studio/codex_manifest.py +5 -1
- ksadk/studio/codex_provider_build.py +65 -0
- ksadk/studio/codex_run.py +6 -1
- ksadk/studio/compiler.py +112 -6
- ksadk/studio/configuration.py +182 -0
- ksadk/studio/contract_base.py +19 -0
- ksadk/studio/contracts.py +260 -202
- ksadk/studio/dsh_application.py +183 -27
- ksadk/studio/dsh_capability_service.py +302 -189
- ksadk/studio/dsh_lifecycle.py +58 -0
- ksadk/studio/dsh_mcp_transport.py +191 -0
- ksadk/studio/dsh_provider_registration.py +55 -16
- ksadk/studio/entry.py +53 -0
- ksadk/studio/event_store.py +53 -5
- ksadk/studio/execution_host.py +598 -0
- ksadk/studio/framework_run.py +50 -10
- ksadk/studio/hosted_kernel.py +1 -1
- ksadk/studio/interaction_submission.py +265 -0
- ksadk/studio/kernel_registry.py +429 -0
- ksadk/studio/kernel_sqlite_migration.py +181 -0
- ksadk/studio/lifecycle_status.py +43 -0
- ksadk/studio/model_buffered_wire.py +227 -0
- ksadk/studio/model_chat_tools.py +143 -0
- ksadk/studio/model_client.py +1939 -345
- ksadk/studio/model_content_stream.py +129 -0
- ksadk/studio/model_credentials.py +196 -0
- ksadk/studio/model_profile_service.py +89 -40
- ksadk/studio/model_request_projection.py +284 -0
- ksadk/studio/model_responses_content.py +296 -0
- ksadk/studio/model_usage.py +109 -0
- ksadk/studio/model_wire_failure.py +110 -0
- ksadk/studio/model_wire_identity.py +138 -0
- ksadk/studio/model_wire_snapshot.py +45 -0
- ksadk/studio/model_wire_tools.py +283 -0
- ksadk/studio/native_acceptance.py +68 -0
- ksadk/studio/native_approval.py +111 -0
- ksadk/studio/native_browser_port.py +861 -0
- ksadk/studio/native_child_mcp.py +87 -0
- ksadk/studio/native_child_publication.py +68 -0
- ksadk/studio/native_child_skills.py +72 -0
- ksadk/studio/native_child_workspace.py +176 -0
- ksadk/studio/native_command_policy.py +53 -0
- ksadk/studio/native_context_port.py +326 -0
- ksadk/studio/native_context_registration.py +54 -0
- ksadk/studio/native_document_input.py +88 -0
- ksadk/studio/native_documents.py +172 -0
- ksadk/studio/native_final_shape.py +852 -0
- ksadk/studio/native_gateway_stream.py +69 -0
- ksadk/studio/native_hook_port.py +145 -0
- ksadk/studio/native_hook_registration.py +70 -0
- ksadk/studio/native_inventory_disclosure.py +223 -0
- ksadk/studio/native_kernel_admission.py +84 -0
- ksadk/studio/native_language_diagnostics.py +320 -0
- ksadk/studio/native_mcp_disclosure.py +198 -0
- ksadk/studio/native_mcp_tool_port.py +219 -0
- ksadk/studio/native_memory_acceptance.py +362 -0
- ksadk/studio/native_memory_context.py +266 -0
- ksadk/studio/native_memory_flush.py +174 -0
- ksadk/studio/native_memory_sources.py +80 -0
- ksadk/studio/native_memory_tool_port.py +360 -0
- ksadk/studio/native_memory_turn.py +183 -0
- ksadk/studio/native_model_port.py +765 -0
- ksadk/studio/native_model_recovery.py +126 -0
- ksadk/studio/native_options.py +75 -0
- ksadk/studio/native_output_fields.py +58 -0
- ksadk/studio/native_planning.py +156 -0
- ksadk/studio/native_product.py +988 -0
- ksadk/studio/native_read_budget.py +426 -0
- ksadk/studio/native_recovery.py +171 -0
- ksadk/studio/native_scope.py +35 -0
- ksadk/studio/native_session_context_port.py +141 -0
- ksadk/studio/native_session_engine.py +14 -0
- ksadk/studio/native_skill_source.py +74 -0
- ksadk/studio/native_subagent_port.py +700 -0
- ksadk/studio/native_terminal_recovery.py +95 -0
- ksadk/studio/native_test_action.py +610 -0
- ksadk/studio/native_tool_port.py +477 -0
- ksadk/studio/native_user_input.py +60 -0
- ksadk/studio/native_verification_presentation.py +65 -0
- ksadk/studio/native_workspace_diagnostics.py +183 -0
- ksadk/studio/native_workspace_port.py +43 -0
- ksadk/studio/operations.py +34 -9
- ksadk/studio/plugin_composition.py +39 -12
- ksadk/studio/plugin_kernel_adapter.py +89 -0
- ksadk/studio/plugin_lifecycle.py +80 -0
- ksadk/studio/plugin_native_activation.py +163 -0
- ksadk/studio/plugin_runtime.py +832 -99
- ksadk/studio/plugin_runtime_admission.py +57 -0
- ksadk/studio/presentation.py +92 -0
- ksadk/studio/provider_recovery.py +59 -0
- ksadk/studio/public_output_store.py +69 -0
- ksadk/studio/recovery_page.py +70 -0
- ksadk/studio/resource_authority.py +69 -34
- ksadk/studio/resource_catalog.py +14 -12
- ksadk/studio/run_activity.py +848 -0
- ksadk/studio/run_controls.py +185 -0
- ksadk/studio/run_documents.py +127 -0
- ksadk/studio/run_service.py +1220 -335
- ksadk/studio/run_submission_receipts.py +68 -0
- ksadk/studio/runtime_catalog.py +73 -11
- ksadk/studio/runtime_prewarm.py +22 -0
- ksadk/studio/runtime_source.py +1 -1
- ksadk/studio/scheduler_assistant.py +4 -1
- ksadk/studio/scheduler_runtime.py +32 -289
- ksadk/studio/service.py +615 -246
- ksadk/studio/service_settings.py +229 -0
- ksadk/studio/shared_web.py +518 -181
- ksadk/studio/shared_web_response_events.py +180 -0
- ksadk/studio/shared_web_run_state.py +133 -0
- ksadk/studio/skill_discovery.py +305 -3
- ksadk/studio/static/assets/ChannelsPage-xX5HlMId.js +8 -0
- ksadk/studio/static/assets/CodeBlock-DMIf4h33-CkufcPYo.js +44 -0
- ksadk/studio/static/assets/ExecutionTree-v3HexvPo-Bk8wzGSy.js +1 -0
- ksadk/studio/static/assets/MathMessageMarkdown-BesSeCYl-DYG1Wzbx.js +8 -0
- ksadk/studio/static/assets/MermaidBlock-H_0qzQDf-BdXtxug_.js +11 -0
- ksadk/studio/static/assets/MessageMarkdown-CwMTvgFj-BeyLyQHu.js +59 -0
- ksadk/studio/static/assets/PrismRenderer-5pK6tUdb.js +3 -0
- ksadk/studio/static/assets/TeamsPage-CCaaGaVp.js +3 -0
- ksadk/studio/static/assets/abnfDiagram-VCTEODGH-Bnb1O3tA.js +1 -0
- ksadk/studio/static/assets/architecture-7GRP2DOG-BMOPAkUC.js +1 -0
- ksadk/studio/static/assets/architectureDiagram-5GKGNRK7-5Zn1gqJv.js +36 -0
- ksadk/studio/static/assets/{blockDiagram-I7D4REHJ-CFmPl1de.js → blockDiagram-I7D4REHJ-CLB4L11u.js} +6 -6
- ksadk/studio/static/assets/{c4Diagram-7LVT6UL2-BRrGu8qt.js → c4Diagram-7LVT6UL2-BOma_Z_F.js} +7 -7
- ksadk/studio/static/assets/channel-r8itPEik.js +1 -0
- ksadk/studio/static/assets/chunk-2E4U76K2-BFf_huql.js +2 -0
- ksadk/studio/static/assets/chunk-2ZTRR5NV-C2qZJila.js +2 -0
- ksadk/studio/static/assets/chunk-3Z5EZCMW-DMniOlPd.js +1 -0
- ksadk/studio/static/assets/{chunk-4HAMMTFA-D220vUtq.js → chunk-4HAMMTFA-DVtDP4rm.js} +7 -7
- ksadk/studio/static/assets/chunk-5V3GS4D5-i-ZDOEnP.js +1 -0
- ksadk/studio/static/assets/chunk-6AZGARVD-BB6FqMl-.js +1 -0
- ksadk/studio/static/assets/chunk-6EIED4P4-DdUJkP0f.js +1 -0
- ksadk/studio/static/assets/chunk-6K3QC6MW-CqVsVn-y.js +1 -0
- ksadk/studio/static/assets/chunk-6TQVIW2G-DKlLbNIP.js +1 -0
- ksadk/studio/static/assets/chunk-747NJXEK-BFkZPlab.js +2 -0
- ksadk/studio/static/assets/chunk-75Z2AOVW-BZNhM4vB.js +2 -0
- ksadk/studio/static/assets/chunk-CLGD4ZFX-D-GTtyKs.js +1 -0
- ksadk/studio/static/assets/{chunk-DU6HZSFF-C4DtVpCu.js → chunk-DU6HZSFF-CpEZCUgg.js} +1 -1
- ksadk/studio/static/assets/chunk-F27PBJKO-D7pvKf0C.js +1 -0
- ksadk/studio/static/assets/{chunk-GMAD6QVW-DiQA-u2N.js → chunk-GMAD6QVW-DE_8H717.js} +6 -6
- ksadk/studio/static/assets/chunk-GVQU2GXP-BfEB0lNv.js +1 -0
- ksadk/studio/static/assets/chunk-I5DQTOEV-Hm2LfiYI.js +1 -0
- ksadk/studio/static/assets/chunk-ICYGCRZG-749o-pGJ.js +1 -0
- ksadk/studio/static/assets/chunk-IH6LHLGP-CC6I9F3i.js +1 -0
- ksadk/studio/static/assets/{chunk-IMKFNOWR-BSlbjT_b.js → chunk-IMKFNOWR-D38axYOR.js} +5 -5
- ksadk/studio/static/assets/chunk-KI3K4JFJ-Rma-0k_M.js +1 -0
- ksadk/studio/static/assets/chunk-L3NEJ4N5-Dq5xn7aL.js +1 -0
- ksadk/studio/static/assets/chunk-LNGE3PJU-DWpGwHrW.js +34 -0
- ksadk/studio/static/assets/{chunk-OSK3NFVY-M2m6G3j4.js → chunk-OSK3NFVY-DiCQjx9b.js} +5 -5
- ksadk/studio/static/assets/chunk-OUJLGHUK-D0j2JRSg.js +2 -0
- ksadk/studio/static/assets/{chunk-P2QGCYS3-DezaQxiK.js → chunk-P2QGCYS3-VdhKmfYq.js} +1 -1
- ksadk/studio/static/assets/chunk-POPQ4Y6H-C1_rzO5M.js +1 -0
- ksadk/studio/static/assets/chunk-PWAF6VOD-B45HvflI.js +1 -0
- ksadk/studio/static/assets/{chunk-SHT3W25Y-DAyIVp5H.js → chunk-SHT3W25Y-DsCFnRVE.js} +9 -9
- ksadk/studio/static/assets/{chunk-SVP7TREG-DulomOrS.js → chunk-SVP7TREG-DljApgRX.js} +1 -1
- ksadk/studio/static/assets/{chunk-TICWLB2K-bHJYoflj.js → chunk-TICWLB2K-DWqRtyqa.js} +6 -6
- ksadk/studio/static/assets/chunk-TLUHSLCS-DUeGgnD5.js +2 -0
- ksadk/studio/static/assets/chunk-UY3FDG6J-CnmaAkG5.js +1 -0
- ksadk/studio/static/assets/chunk-XHIXRSVI-BFQ6B8BE.js +1 -0
- ksadk/studio/static/assets/chunk-XXDRQBXY-DqAYeljN.js +1 -0
- ksadk/studio/static/assets/classDiagram-ZZMXUADV-DjeMNJmu.js +1 -0
- ksadk/studio/static/assets/classDiagram-v2-VYDZK3BY-DjeMNJmu.js +1 -0
- ksadk/studio/static/assets/clsx-DB0hHKMi.js +1 -0
- ksadk/studio/static/assets/cose-bilkent-JH36ORCC-om8AY0Mc.js +1 -0
- ksadk/studio/static/assets/createLucideIcon-DR0LGTP5.js +1 -0
- ksadk/studio/static/assets/cynefin-OW5HDTMX-7tP7QfM3.js +1 -0
- ksadk/studio/static/assets/cynefinDiagram-5FMLGOSQ-6BrmK52S.js +62 -0
- ksadk/studio/static/assets/dagre-GXQ25YYZ-buZBRlwz.js +4 -0
- ksadk/studio/static/assets/{diagram-S7CK7UJ4-0BZ98mya.js → diagram-S7CK7UJ4-C6aH78c4.js} +3 -3
- ksadk/studio/static/assets/diagram-UQ7AKVKN-DY_tQ6C_.js +41 -0
- ksadk/studio/static/assets/diagram-VSXAHHWV-DX9p5cQT.js +3 -0
- ksadk/studio/static/assets/diagram-VX7I27RA-DB2WSH8X.js +24 -0
- ksadk/studio/static/assets/diagram-Z3DM3KII-Ce1BJwHE.js +24 -0
- ksadk/studio/static/assets/ebnfDiagram-PWID7BFC-Daukxwqf.js +1 -0
- ksadk/studio/static/assets/{erDiagram-RLTQ6QDP-DLGry2Ap.js → erDiagram-RLTQ6QDP-CGthTMmJ.js} +6 -6
- ksadk/studio/static/assets/eventmodeling-NTZA5JFV-BR2FzK4R.js +1 -0
- ksadk/studio/static/assets/flowDiagram-HODETNUW-CZ1tEenp.js +1 -0
- ksadk/studio/static/assets/ganttDiagram-EL5Y4UJY-BfoAZW9X.js +292 -0
- ksadk/studio/static/assets/gitGraph-4MIJSDKK-DYlXv_yJ.js +1 -0
- ksadk/studio/static/assets/gitGraphDiagram-WWUBYQGX-S985OIJF.js +106 -0
- ksadk/studio/static/assets/iconfont-4HN3C9Pg.woff2 +0 -0
- ksadk/studio/static/assets/index-C7DNDik2.css +2 -0
- ksadk/studio/static/assets/index-Cy68gTlH.js +265 -0
- ksadk/studio/static/assets/index.dom-BQenBtFm.js +1 -0
- ksadk/studio/static/assets/info-A6RAGUB7-BlU-8_xu.js +1 -0
- ksadk/studio/static/assets/infoDiagram-27XIBGKW-CO3W8tFn.js +2 -0
- ksadk/studio/static/assets/{ishikawaDiagram-5VMMS53U-CljI2wyf.js → ishikawaDiagram-5VMMS53U-BUGEl8cO.js} +2 -2
- ksadk/studio/static/assets/{journeyDiagram-3NMN7TZE-D50Fo2sL.js → journeyDiagram-3NMN7TZE-Ch2ZYxvr.js} +6 -6
- ksadk/studio/static/assets/{kanban-definition-UXKFOSKX-DimfOTam.js → kanban-definition-UXKFOSKX-Da-Fp4vC.js} +3 -3
- ksadk/studio/static/assets/kingsoft-cloud-BOcLiQ3e.ico +0 -0
- ksadk/studio/static/assets/{line-CX5BOOUP.js → line-BDaeq300.js} +1 -1
- ksadk/studio/static/assets/linear-DmucvK78.js +1 -0
- ksadk/studio/static/assets/mermaid-parser.core-Cj5mYdBi.js +4 -0
- ksadk/studio/static/assets/{mindmap-definition-YA3MSWOX-Bizzqy5R.js → mindmap-definition-YA3MSWOX-CvlsVQ38.js} +1 -1
- ksadk/studio/static/assets/packet-AYTQ26CC-BSJEH9Lb.js +1 -0
- ksadk/studio/static/assets/pegDiagram-XKGWAZYB-BuHuNgT5.js +1 -0
- ksadk/studio/static/assets/pie-WAS4IAKB-qxv01Y8W.js +1 -0
- ksadk/studio/static/assets/{pieDiagram-E7YTZNPT-B9mrFSDF.js → pieDiagram-E7YTZNPT-DlrWiSOv.js} +1 -1
- ksadk/studio/static/assets/preload-helper-CO68xz6u.js +1 -0
- ksadk/studio/static/assets/presentation-yYw7xK60-BmcZriri.js +1 -0
- ksadk/studio/static/assets/{quadrantDiagram-AXDQQJYC-NzUfCbMR.js → quadrantDiagram-AXDQQJYC-BA3hpUZM.js} +6 -6
- ksadk/studio/static/assets/radar-RG4KPBEZ-B6h6pWOs.js +1 -0
- ksadk/studio/static/assets/railroad-74A4TZTK-CGtTWdGc.js +1 -0
- ksadk/studio/static/assets/railroad-abnf-HS5TGJTU-Cq7y22IA.js +1 -0
- ksadk/studio/static/assets/railroad-ebnf-LZEXJU2U-V0aQVv9m.js +1 -0
- ksadk/studio/static/assets/railroad-peg-WCYAUIDC-BQiIsX_p.js +1 -0
- ksadk/studio/static/assets/railroadDiagram-O6MQD6OU-BxpAazym.js +1 -0
- ksadk/studio/static/assets/{requirementDiagram-BXWQKSXE-BF3d103U.js → requirementDiagram-BXWQKSXE-E-Ge0FcV.js} +1 -1
- ksadk/studio/static/assets/sankeyDiagram-P5KCCOFB-CA6YKhQ3.js +40 -0
- ksadk/studio/static/assets/{sequenceDiagram-WJ2MYXX4-Dh4wZtUm.js → sequenceDiagram-WJ2MYXX4-CcElXGg4.js} +9 -9
- ksadk/studio/static/assets/src-B6xuSHsQ.js +1 -0
- ksadk/studio/static/assets/stateDiagram-D77RDMKH-DdXZOFqY.js +1 -0
- ksadk/studio/static/assets/stateDiagram-v2-MP3YSRHH-CJbOM-QK.js +1 -0
- ksadk/studio/static/assets/swimlanes-42K2YHIH-NtgEEHLY.js +1 -0
- ksadk/studio/static/assets/swimlanesDiagram-VR7AAH4N-D-AVlW8B.js +8 -0
- ksadk/studio/static/assets/{timeline-definition-24CTP7MA-DxmSSjRB.js → timeline-definition-24CTP7MA-CIuYhNy3.js} +7 -7
- ksadk/studio/static/assets/treeView-Q6P3EWNA-BTTYcvrF.js +1 -0
- ksadk/studio/static/assets/treemap-WGGIJYW6-Cg7tyfH8.js +1 -0
- ksadk/studio/static/assets/vennDiagram-4TSXK5OY-7HbApbrv.js +34 -0
- ksadk/studio/static/assets/wardley-WFR3VGLG-C6N1rULY.js +1 -0
- ksadk/studio/static/assets/{wardleyDiagram-VM6X3IG4-Ba1AOWoe.js → wardleyDiagram-VM6X3IG4-CMJiaedy.js} +1 -1
- ksadk/studio/static/assets/{xychartDiagram-S5SC5T6Z-Cr5pt5Y-.js → xychartDiagram-S5SC5T6Z-BdgtMvW2.js} +6 -6
- ksadk/studio/static/index.html +8 -2
- ksadk/studio/teams_catalog.py +166 -0
- ksadk/studio/teams_installation.py +217 -0
- ksadk/studio/teams_node.py +549 -0
- ksadk/studio/teams_node_factory.py +558 -0
- ksadk/studio/teams_node_runner.py +72 -0
- ksadk/studio/teams_node_v1.py +935 -0
- ksadk/studio/teams_remote.py +496 -0
- ksadk/studio/templates.py +41 -19
- ksadk/studio/validator.py +13 -0
- ksadk/studio/workspace.py +19 -4
- ksadk/studio/workspace_plugins.py +138 -0
- ksadk/studio/workspace_registry.py +286 -0
- ksadk/tools/a2a_policy.py +5 -0
- ksadk/tools/artifact_observation.py +53 -0
- ksadk/tools/captured_source_artifact.py +68 -0
- ksadk/tools/schema.py +34 -0
- ksadk/toolsets/__init__.py +93 -88
- ksadk/toolsets/a2a.py +89 -89
- ksadk/toolsets/sandbox.py +377 -6
- ksadk/toolsets/skill_management.py +315 -0
- ksadk/toolsets/skills.py +446 -378
- ksadk/toolsets/tool_selection.py +94 -0
- ksadk/toolsets/workspace.py +344 -326
- ksadk/toolsets/workspace_editing.py +291 -0
- ksadk/toolsets/workspace_identity.py +15 -0
- ksadk/toolsets/workspace_model_observation.py +104 -0
- ksadk/toolsets/workspace_mutation.py +75 -0
- ksadk/toolsets/workspace_read_budget.py +216 -0
- ksadk/toolsets/workspace_search.py +192 -0
- ksadk/toolsets/workspace_search_process.py +129 -0
- ksadk/toolsets/workspace_state.py +6 -0
- ksadk/version.py +1 -1
- ksadk_runtime_common/http_headers.py +18 -0
- ksadk_runtime_common/memory_backend/providers/lancedb.py +56 -2
- ksadk_runtime_common/schemas/memory_backend_manifest.schema.json +148 -148
- ksadk_runtime_common/workspace_files/router.py +28 -14
- agentengine_sdk_python-0.8.4.dist-info/RECORD +0 -1070
- ksadk/server/static/assets/MathMessageMarkdown-DbdW5A4_.js +0 -8
- ksadk/server/static/assets/architecture-7GRP2DOG-BW5UtSnx.js +0 -1
- ksadk/server/static/assets/channel-CF5Up3hQ.js +0 -1
- ksadk/server/static/assets/chunk-2Q5K7J3B-KkXX47WI.js +0 -1
- ksadk/server/static/assets/classDiagram-DTDB5LWJ-Cz81acRQ.js +0 -1
- ksadk/server/static/assets/classDiagram-v2-JRS7N3AN-Cz81acRQ.js +0 -1
- ksadk/server/static/assets/cynefin-OW5HDTMX-DVWs8a2t.js +0 -1
- ksadk/server/static/assets/dist-B2_CVgKv.js +0 -1
- ksadk/server/static/assets/eventmodeling-NTZA5JFV-CQqR2hg3.js +0 -1
- ksadk/server/static/assets/flowDiagram-A5DVABFB-DDRRbGPm.js +0 -1
- ksadk/server/static/assets/gitGraph-4MIJSDKK-fgWEf7UD.js +0 -1
- ksadk/server/static/assets/index-DcTML1Up.css +0 -2
- ksadk/server/static/assets/index-Dh2XHqPK.js +0 -244
- ksadk/server/static/assets/info-A6RAGUB7-BUecLTdt.js +0 -1
- ksadk/server/static/assets/packet-AYTQ26CC-BeW-btFv.js +0 -1
- ksadk/server/static/assets/pie-WAS4IAKB-X0xh4SaT.js +0 -1
- ksadk/server/static/assets/radar-RG4KPBEZ-DzRMSqjd.js +0 -1
- ksadk/server/static/assets/railroad-74A4TZTK-Cc44icX-.js +0 -1
- ksadk/server/static/assets/railroad-abnf-HS5TGJTU-D6S4BdV-.js +0 -1
- ksadk/server/static/assets/railroad-ebnf-LZEXJU2U-vD3aVE2o.js +0 -1
- ksadk/server/static/assets/railroad-peg-WCYAUIDC-CYbW_b4T.js +0 -1
- ksadk/server/static/assets/stateDiagram-v2-4QOOHH4V-BIcjKFhF.js +0 -1
- ksadk/server/static/assets/swimlanesDiagram-VK2B7HYN-tq3K3Ybl.js +0 -8
- ksadk/server/static/assets/treeView-Q6P3EWNA-DBXt3GdU.js +0 -1
- ksadk/server/static/assets/treemap-WGGIJYW6-DrCy4E_l.js +0 -1
- ksadk/server/static/assets/wardley-WFR3VGLG-CefhOliM.js +0 -1
- ksadk/studio/static/assets/CodeBlock-DCUUY0PL-BLjA7kbS.js +0 -41
- ksadk/studio/static/assets/MathMessageMarkdown-CBcDrAw--CUYIXwgI.js +0 -8
- ksadk/studio/static/assets/MermaidBlock-DBFTztfQ-BTYKWEbD.js +0 -44
- ksadk/studio/static/assets/PrismRenderer-wiXRHURw.js +0 -3
- ksadk/studio/static/assets/abnfDiagram-VCTEODGH-CLETGjKq.js +0 -1
- ksadk/studio/static/assets/architecture-7GRP2DOG-hXMiO_AU.js +0 -1
- ksadk/studio/static/assets/architectureDiagram-5GKGNRK7-B5EQysk6.js +0 -36
- ksadk/studio/static/assets/channel-BqO-gtEw.js +0 -1
- ksadk/studio/static/assets/chunk-75Z2AOVW-C8lLv_qc.js +0 -2
- ksadk/studio/static/assets/chunk-F27PBJKO-Cpw14SNG.js +0 -1
- ksadk/studio/static/assets/chunk-GVQU2GXP-DUdNBUCi.js +0 -1
- ksadk/studio/static/assets/chunk-L3NEJ4N5-Db8Ab22W.js +0 -1
- ksadk/studio/static/assets/chunk-POPQ4Y6H-DOpufJ3t.js +0 -1
- ksadk/studio/static/assets/chunk-PWAF6VOD-CfLb1gSc.js +0 -1
- ksadk/studio/static/assets/chunk-XXDRQBXY-7PcdR2B1.js +0 -1
- ksadk/studio/static/assets/classDiagram-ZZMXUADV-D_bW8JjA.js +0 -1
- ksadk/studio/static/assets/classDiagram-v2-VYDZK3BY-D_bW8JjA.js +0 -1
- ksadk/studio/static/assets/cose-bilkent-JH36ORCC-snL88wkX.js +0 -1
- ksadk/studio/static/assets/cynefin-OW5HDTMX-Bd1YhRo1.js +0 -1
- ksadk/studio/static/assets/cynefinDiagram-5FMLGOSQ-BBrIG_mI.js +0 -62
- ksadk/studio/static/assets/dagre-GXQ25YYZ-DtF1nGdY.js +0 -4
- ksadk/studio/static/assets/diagram-UQ7AKVKN-6mLKEo6L.js +0 -41
- ksadk/studio/static/assets/diagram-VSXAHHWV-CJBIaiZ2.js +0 -3
- ksadk/studio/static/assets/diagram-VX7I27RA-BohLEE1C.js +0 -24
- ksadk/studio/static/assets/diagram-Z3DM3KII-D8KIGonG.js +0 -24
- ksadk/studio/static/assets/ebnfDiagram-PWID7BFC-C99HU61t.js +0 -1
- ksadk/studio/static/assets/eventmodeling-NTZA5JFV-B1_5Ac8j.js +0 -1
- ksadk/studio/static/assets/flowDiagram-HODETNUW-DD5hmicn.js +0 -1
- ksadk/studio/static/assets/ganttDiagram-EL5Y4UJY-BPJrVLSG.js +0 -292
- ksadk/studio/static/assets/gitGraph-4MIJSDKK-Cy_ZQBGi.js +0 -1
- ksadk/studio/static/assets/gitGraphDiagram-WWUBYQGX-CZCUz4MT.js +0 -106
- ksadk/studio/static/assets/index-CeHL9ARV.css +0 -2
- ksadk/studio/static/assets/index-D9QEcVpL.js +0 -320
- ksadk/studio/static/assets/info-A6RAGUB7-DBzDQB_I.js +0 -1
- ksadk/studio/static/assets/infoDiagram-27XIBGKW-B-sq07Hi.js +0 -2
- ksadk/studio/static/assets/linear-BCxN9JLv.js +0 -1
- ksadk/studio/static/assets/mermaid-parser.core-BdCz8fkS.js +0 -7
- ksadk/studio/static/assets/packet-AYTQ26CC-gPln-_kG.js +0 -1
- ksadk/studio/static/assets/pegDiagram-XKGWAZYB-Dy3fB-gW.js +0 -1
- ksadk/studio/static/assets/pie-WAS4IAKB-qZdHMr7B.js +0 -1
- ksadk/studio/static/assets/radar-RG4KPBEZ-BZlnaea9.js +0 -1
- ksadk/studio/static/assets/railroad-74A4TZTK-Ce3__H9c.js +0 -1
- ksadk/studio/static/assets/railroad-abnf-HS5TGJTU-DqQn7EzD.js +0 -1
- ksadk/studio/static/assets/railroad-ebnf-LZEXJU2U-B55kCA8F.js +0 -1
- ksadk/studio/static/assets/railroad-peg-WCYAUIDC-DfQnvkHd.js +0 -1
- ksadk/studio/static/assets/railroadDiagram-O6MQD6OU-DnhMjZCk.js +0 -1
- ksadk/studio/static/assets/sankeyDiagram-P5KCCOFB-Bo-JTwt0.js +0 -40
- ksadk/studio/static/assets/src-SFn9St9H.js +0 -1
- ksadk/studio/static/assets/stateDiagram-D77RDMKH-DH774G6d.js +0 -1
- ksadk/studio/static/assets/stateDiagram-v2-MP3YSRHH-DZvVWPBo.js +0 -1
- ksadk/studio/static/assets/swimlanes-42K2YHIH-Bl13OvTX.js +0 -1
- ksadk/studio/static/assets/swimlanesDiagram-VR7AAH4N-BnFOTALJ.js +0 -8
- ksadk/studio/static/assets/treeView-Q6P3EWNA-D5Nn9Swz.js +0 -1
- ksadk/studio/static/assets/treemap-WGGIJYW6-CgHgnQhE.js +0 -1
- ksadk/studio/static/assets/vennDiagram-4TSXK5OY-B9QEXcJq.js +0 -34
- ksadk/studio/static/assets/wardley-WFR3VGLG-DXrK2RRY.js +0 -1
- {agentengine_sdk_python-0.8.4.dist-info → agentengine_sdk_python-0.8.6.dist-info}/WHEEL +0 -0
- {agentengine_sdk_python-0.8.4.dist-info → agentengine_sdk_python-0.8.6.dist-info}/entry_points.txt +0 -0
- {agentengine_sdk_python-0.8.4.dist-info → agentengine_sdk_python-0.8.6.dist-info}/licenses/LICENSE +0 -0
- {agentengine_sdk_python-0.8.4.dist-info → agentengine_sdk_python-0.8.6.dist-info}/top_level.txt +0 -0
- /ksadk/studio/static/assets/{MathMessageMarkdown-CBcDrAw--BEOyPC3w.css → MathMessageMarkdown-BesSeCYl-BEOyPC3w.css} +0 -0
ksadk/studio/plugin_runtime.py
CHANGED
|
@@ -4,7 +4,8 @@ from __future__ import annotations
|
|
|
4
4
|
|
|
5
5
|
import asyncio
|
|
6
6
|
import json
|
|
7
|
-
|
|
7
|
+
import os
|
|
8
|
+
from collections.abc import Callable, Mapping, Sequence
|
|
8
9
|
from dataclasses import dataclass
|
|
9
10
|
from pathlib import Path
|
|
10
11
|
from typing import Any, cast
|
|
@@ -29,6 +30,8 @@ from ksadk.plugins.providers.dsh_mcp import (
|
|
|
29
30
|
dsh_profile_mcp_manifest,
|
|
30
31
|
)
|
|
31
32
|
from ksadk.plugins.providers.harness import (
|
|
33
|
+
HarnessEngineSelector,
|
|
34
|
+
HarnessNativeAdapterBuilder,
|
|
32
35
|
HarnessTurnResult,
|
|
33
36
|
KsADKHarnessProviderFactory,
|
|
34
37
|
)
|
|
@@ -60,13 +63,67 @@ from ksadk.studio.contracts import (
|
|
|
60
63
|
)
|
|
61
64
|
from ksadk.studio.errors import StudioError
|
|
62
65
|
from ksadk.studio.model_client import OpenAICompatibleModelClient
|
|
66
|
+
from ksadk.studio.native_context_registration import StudioNativeContextRegistration
|
|
67
|
+
from ksadk.studio.native_hook_registration import StudioNativeHookRegistration
|
|
63
68
|
from ksadk.studio.plugin_kernel_adapter import StudioPluginKernelAdapter
|
|
69
|
+
from ksadk.studio.plugin_native_activation import StudioNativeActivationMixin, _NativeActivation
|
|
70
|
+
from ksadk.studio.plugin_runtime_admission import RuntimeAdmissionGate
|
|
64
71
|
from ksadk.studio.repository import BuildRepository
|
|
65
72
|
from ksadk.studio.run_service import StudioRunSpec
|
|
66
73
|
from ksadk.studio.workspace import Workspace
|
|
67
74
|
from ksadk.tools.gateway import normalize_tool_approval_mode
|
|
68
75
|
|
|
69
76
|
_COMPOSED_RUNTIME_TYPES = frozenset({"harness", "plugin"})
|
|
77
|
+
_DEFAULT_REASONING_ONLY_ACTION_BUDGET_CHARS = 8_192
|
|
78
|
+
|
|
79
|
+
|
|
80
|
+
def _model_request_timeout_seconds(execution: Mapping[str, Any]) -> int:
|
|
81
|
+
"""Cap a stalled provider request independently from the complete run budget."""
|
|
82
|
+
|
|
83
|
+
run_timeout = int(
|
|
84
|
+
execution.get("timeoutSeconds") or execution.get("timeout_seconds") or 300
|
|
85
|
+
)
|
|
86
|
+
raw_idle_timeout = os.getenv("KSADK_MODEL_REQUEST_IDLE_TIMEOUT_SECONDS")
|
|
87
|
+
default_idle_timeout = min(180, max(60, run_timeout // 10))
|
|
88
|
+
try:
|
|
89
|
+
idle_timeout = (
|
|
90
|
+
int(raw_idle_timeout)
|
|
91
|
+
if raw_idle_timeout is not None
|
|
92
|
+
else default_idle_timeout
|
|
93
|
+
)
|
|
94
|
+
except (TypeError, ValueError):
|
|
95
|
+
idle_timeout = default_idle_timeout
|
|
96
|
+
return max(1, min(run_timeout, max(1, idle_timeout)))
|
|
97
|
+
|
|
98
|
+
|
|
99
|
+
def _model_total_timeout_seconds(execution: Mapping[str, Any]) -> int:
|
|
100
|
+
"""整个 run 的模型预算,用作增量传输的硬上限。
|
|
101
|
+
|
|
102
|
+
``_model_request_timeout_seconds`` 是"无进度"超时(可能只有 60s);增量流在
|
|
103
|
+
持续吐字时不受它约束,所以还需要一个上限,防止一条只发 keepalive 的流把
|
|
104
|
+
整个 run 拖死。
|
|
105
|
+
"""
|
|
106
|
+
|
|
107
|
+
return max(1, int(execution.get("timeoutSeconds") or execution.get("timeout_seconds") or 300))
|
|
108
|
+
|
|
109
|
+
|
|
110
|
+
def _reasoning_only_action_budget_chars() -> int:
|
|
111
|
+
"""Bound a tool-capable turn that produces reasoning but no action.
|
|
112
|
+
|
|
113
|
+
The threshold is deliberately semantic rather than a socket timeout: a
|
|
114
|
+
provider can keep the TCP stream healthy for minutes while emitting only
|
|
115
|
+
reasoning. The 8 KiB default is roughly 2K tokens and is comfortably
|
|
116
|
+
above the 143 reasoning tokens observed before a successful Pi tool call,
|
|
117
|
+
while stopping the 20K-chunk GLM failure long before the one-hour run
|
|
118
|
+
deadline.
|
|
119
|
+
"""
|
|
120
|
+
|
|
121
|
+
raw = os.getenv("KSADK_REASONING_ONLY_ACTION_BUDGET_CHARS")
|
|
122
|
+
try:
|
|
123
|
+
value = int(raw) if raw is not None else _DEFAULT_REASONING_ONLY_ACTION_BUDGET_CHARS
|
|
124
|
+
except (TypeError, ValueError):
|
|
125
|
+
value = _DEFAULT_REASONING_ONLY_ACTION_BUDGET_CHARS
|
|
126
|
+
return max(1_024, min(value, 65_536))
|
|
70
127
|
|
|
71
128
|
|
|
72
129
|
@dataclass(frozen=True)
|
|
@@ -87,6 +144,22 @@ class _HostEntry:
|
|
|
87
144
|
host: PluginHost
|
|
88
145
|
|
|
89
146
|
|
|
147
|
+
|
|
148
|
+
|
|
149
|
+
def _parse_tool_arguments(raw: str | None) -> dict[str, Any] | None:
|
|
150
|
+
"""解析模型给出的工具参数;非 JSON 对象一律返回 None(不抛错)。
|
|
151
|
+
|
|
152
|
+
返回 None 表示"参数形状不可用":调用方要么修复一次,要么把它作为
|
|
153
|
+
invalid_arguments 回灌给模型,绝不允许升级成整轮致命错误。
|
|
154
|
+
"""
|
|
155
|
+
|
|
156
|
+
try:
|
|
157
|
+
arguments = json.loads(raw or "{}")
|
|
158
|
+
except json.JSONDecodeError:
|
|
159
|
+
return None
|
|
160
|
+
return arguments if isinstance(arguments, dict) else None
|
|
161
|
+
|
|
162
|
+
|
|
90
163
|
class _StudioHarnessReasoner:
|
|
91
164
|
"""Bind the Harness loop to the immutable Studio model/network policy."""
|
|
92
165
|
|
|
@@ -95,17 +168,62 @@ class _StudioHarnessReasoner:
|
|
|
95
168
|
client: OpenAICompatibleModelClient,
|
|
96
169
|
*,
|
|
97
170
|
model: ResolvedModel,
|
|
171
|
+
fallback_models: Sequence[ResolvedModel] = (),
|
|
98
172
|
network_policy: NetworkPolicy,
|
|
99
173
|
timeout_seconds: int,
|
|
100
174
|
max_attempts: int,
|
|
101
175
|
backoff_seconds: float,
|
|
176
|
+
total_timeout_seconds: int | None = None,
|
|
102
177
|
) -> None:
|
|
103
178
|
self._client = client
|
|
104
179
|
self._model = model
|
|
180
|
+
self._models = {
|
|
181
|
+
item.model: item for item in (model, *tuple(fallback_models))
|
|
182
|
+
}
|
|
105
183
|
self._network_policy = network_policy
|
|
106
184
|
self._timeout_seconds = timeout_seconds
|
|
107
185
|
self._max_attempts = max_attempts
|
|
108
186
|
self._backoff_seconds = backoff_seconds
|
|
187
|
+
# 整个 run 的预算:增量传输的硬上限(防止"一直吐 keepalive"的流永不结束)。
|
|
188
|
+
self._total_timeout_seconds = max(
|
|
189
|
+
timeout_seconds, int(total_timeout_seconds or timeout_seconds)
|
|
190
|
+
)
|
|
191
|
+
# 传输模式来自"端点声明"(见 ksadk/model_proxy/compat.py),不是代码里的
|
|
192
|
+
# 模型名分支:默认流式;只有真正不支持增量的端点才声明
|
|
193
|
+
# prefer_buffered_transport。曾经的 kspmas 档整条走缓冲,代价是一次
|
|
194
|
+
# 模型调用从发出到返回之间前端没有任何可显示内容("像卡住")。
|
|
195
|
+
from ksadk.model_proxy import compat as provider_compat
|
|
196
|
+
|
|
197
|
+
self._streaming = not provider_compat.prefer_buffered_transport(
|
|
198
|
+
base_url=self._model.endpoint_url,
|
|
199
|
+
model=self._model.model,
|
|
200
|
+
)
|
|
201
|
+
if hasattr(self._client, "supports_streaming"):
|
|
202
|
+
self._streaming = self._client.supports_streaming(
|
|
203
|
+
self._model, requested=self._streaming
|
|
204
|
+
)
|
|
205
|
+
# "空闲进度"超时:连续这么久没有**内容** chunk 才算卡住(keepalive 不算),
|
|
206
|
+
# 所以慢但持续吐字的回合不会被误杀。
|
|
207
|
+
self._stream_idle_timeout_seconds = max(
|
|
208
|
+
0.001,
|
|
209
|
+
float(
|
|
210
|
+
provider_compat.stream_idle_timeout(
|
|
211
|
+
base_url=self._model.endpoint_url,
|
|
212
|
+
model=self._model.model,
|
|
213
|
+
fallback=timeout_seconds,
|
|
214
|
+
)
|
|
215
|
+
or timeout_seconds
|
|
216
|
+
),
|
|
217
|
+
)
|
|
218
|
+
|
|
219
|
+
def _require_model(self, model: str) -> ResolvedModel:
|
|
220
|
+
try:
|
|
221
|
+
return self._models[model]
|
|
222
|
+
except KeyError as error:
|
|
223
|
+
raise PluginHostError(
|
|
224
|
+
"harness_model_not_bound",
|
|
225
|
+
f"Harness requested unbound model {model!r}",
|
|
226
|
+
) from error
|
|
109
227
|
|
|
110
228
|
async def complete(
|
|
111
229
|
self,
|
|
@@ -114,15 +232,13 @@ class _StudioHarnessReasoner:
|
|
|
114
232
|
prompt: str,
|
|
115
233
|
messages: Sequence[dict[str, Any]],
|
|
116
234
|
tools: Sequence[Any],
|
|
235
|
+
max_output_tokens: int | None = None,
|
|
236
|
+
reasoning_effort: str | None = None,
|
|
117
237
|
) -> HarnessReasoningTurn:
|
|
118
238
|
del prompt
|
|
119
|
-
|
|
120
|
-
raise PluginHostError(
|
|
121
|
-
"harness_model_not_bound",
|
|
122
|
-
f"Harness requested unbound model {model!r}",
|
|
123
|
-
)
|
|
239
|
+
selected_model = self._require_model(model)
|
|
124
240
|
response = await self._client.complete(
|
|
125
|
-
|
|
241
|
+
selected_model,
|
|
126
242
|
messages=[dict(message) for message in messages],
|
|
127
243
|
network_policy=self._network_policy,
|
|
128
244
|
timeout_seconds=self._timeout_seconds,
|
|
@@ -130,35 +246,552 @@ class _StudioHarnessReasoner:
|
|
|
130
246
|
backoff_seconds=self._backoff_seconds,
|
|
131
247
|
tools=[dict(tool.openai_schema) for tool in tools],
|
|
132
248
|
allow_empty=bool(tools),
|
|
249
|
+
max_output_tokens=max_output_tokens,
|
|
250
|
+
reasoning_effort=reasoning_effort,
|
|
251
|
+
# 触顶一次性升级(对齐 Claude Code 的 max_output_tokens_escalate):
|
|
252
|
+
# 平时给 slot 友好的小预算,真被截断才扩容重试一次。
|
|
253
|
+
retry_on_length=True,
|
|
133
254
|
)
|
|
134
255
|
calls: list[HarnessToolCall] = []
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
256
|
+
invalid_names: list[str] = []
|
|
257
|
+
|
|
258
|
+
def _collect(source_calls: Sequence[Any]) -> list[HarnessToolCall]:
|
|
259
|
+
collected: list[HarnessToolCall] = []
|
|
260
|
+
for call in source_calls:
|
|
261
|
+
arguments = _parse_tool_arguments(call.arguments)
|
|
262
|
+
if arguments is None:
|
|
263
|
+
invalid_names.append(call.name)
|
|
264
|
+
collected.append(
|
|
265
|
+
HarnessToolCall(
|
|
266
|
+
call_id=call.id,
|
|
267
|
+
name=call.name,
|
|
268
|
+
arguments={},
|
|
269
|
+
invalid_reason="model emitted non-JSON-object tool arguments",
|
|
270
|
+
)
|
|
271
|
+
)
|
|
272
|
+
continue
|
|
273
|
+
collected.append(
|
|
274
|
+
HarnessToolCall(call_id=call.id, name=call.name, arguments=arguments)
|
|
153
275
|
)
|
|
276
|
+
return collected
|
|
277
|
+
|
|
278
|
+
calls = _collect(response.tool_calls)
|
|
279
|
+
if any(call.invalid_reason for call in calls):
|
|
280
|
+
# 与流式路径同策略:先给一次修复(更大预算 + 明确要求合法 JSON),
|
|
281
|
+
# 修复仍不可用则保留 invalid_reason,由循环层以 invalid_arguments 的
|
|
282
|
+
# tool result 回灌给模型重试——参数形状问题不中断整轮。
|
|
283
|
+
repair = await self._client.complete(
|
|
284
|
+
selected_model,
|
|
285
|
+
messages=[
|
|
286
|
+
*[dict(message) for message in messages],
|
|
287
|
+
{
|
|
288
|
+
"role": "system",
|
|
289
|
+
"content": (
|
|
290
|
+
"The previous tool call could not be parsed. "
|
|
291
|
+
f"Retry the intended {invalid_names[0]} call once with valid "
|
|
292
|
+
"JSON arguments. Keep the arguments concise enough to fit in "
|
|
293
|
+
"one tool call and do not repeat the analysis."
|
|
294
|
+
),
|
|
295
|
+
},
|
|
296
|
+
],
|
|
297
|
+
network_policy=self._network_policy,
|
|
298
|
+
timeout_seconds=self._timeout_seconds,
|
|
299
|
+
max_attempts=self._max_attempts,
|
|
300
|
+
backoff_seconds=self._backoff_seconds,
|
|
301
|
+
tools=[dict(tool.openai_schema) for tool in tools],
|
|
302
|
+
allow_empty=bool(tools),
|
|
303
|
+
retry_on_length=True,
|
|
304
|
+
max_output_tokens=max(
|
|
305
|
+
16_384,
|
|
306
|
+
int(max_output_tokens or selected_model.parameters.max_tokens or 0),
|
|
307
|
+
),
|
|
308
|
+
reasoning_effort=reasoning_effort,
|
|
154
309
|
)
|
|
310
|
+
repaired = _collect(repair.tool_calls)
|
|
311
|
+
if any(not call.invalid_reason for call in repaired):
|
|
312
|
+
calls = repaired
|
|
313
|
+
reported_usage = response.usage if response.usage.reported else None
|
|
155
314
|
return HarnessReasoningTurn(
|
|
156
315
|
final_text=response.content or None,
|
|
157
316
|
tool_calls=tuple(calls),
|
|
317
|
+
reasoning=response.reasoning or None,
|
|
318
|
+
degraded=(
|
|
319
|
+
"reasoning_only_turn"
|
|
320
|
+
if getattr(response, "empty_reasoning_only", False)
|
|
321
|
+
else None
|
|
322
|
+
),
|
|
323
|
+
usage=None
|
|
324
|
+
if reported_usage is None
|
|
325
|
+
else {
|
|
326
|
+
"input_tokens": max(0, int(reported_usage.input_tokens)),
|
|
327
|
+
"output_tokens": max(0, int(reported_usage.output_tokens)),
|
|
328
|
+
"cached_tokens": max(0, int(reported_usage.cached_input_tokens)),
|
|
329
|
+
"reasoning_tokens": max(0, int(reported_usage.reasoning_output_tokens)),
|
|
330
|
+
},
|
|
331
|
+
)
|
|
332
|
+
|
|
333
|
+
async def stream_complete(
|
|
334
|
+
self,
|
|
335
|
+
*,
|
|
336
|
+
model: str,
|
|
337
|
+
prompt: str,
|
|
338
|
+
messages: Sequence[dict[str, Any]],
|
|
339
|
+
tools: Sequence[Any],
|
|
340
|
+
max_output_tokens: int | None = None,
|
|
341
|
+
reasoning_effort: str | None = None,
|
|
342
|
+
):
|
|
343
|
+
"""Pass model deltas through the Harness loop as soon as they arrive.
|
|
344
|
+
|
|
345
|
+
传输纪律(本轮修复的"像卡住"根因):
|
|
346
|
+
|
|
347
|
+
- 正文、思考、工具调用或完成信号都是真实传输进展,会顺延空闲
|
|
348
|
+
计时。不能把思考型模型持续返回的 ``reasoning_content`` 当成
|
|
349
|
+
“无进展”;这会在模型正常思考时误杀连接。
|
|
350
|
+
- usage/keepalive 不续命。一条始终只产生思考的流仍受
|
|
351
|
+
``total_timeout_seconds`` 硬上限约束,不会无限运行。
|
|
352
|
+
- 连续 ``stream_idle_timeout_seconds`` 没有任何内容(只有 keepalive 或
|
|
353
|
+
干脆静默)即判定为卡住:关闭当前流并抛出可重试的超时。外层统一
|
|
354
|
+
provider policy 会立即记录 ``model.call.failed``,再按策略重试或切换
|
|
355
|
+
provider。这里不能偷偷再发一次完整缓冲请求,否则一次 60 秒的流超时
|
|
356
|
+
后还会叠加完整请求超时,Studio 会无进展地假死数分钟。
|
|
357
|
+
- 卡住前已经流出的半截内容会由循环层在失败时清理,不会污染答案或模型
|
|
358
|
+
上下文。
|
|
359
|
+
"""
|
|
360
|
+
selected_model = self._require_model(model)
|
|
361
|
+
from ksadk.model_proxy import compat as provider_compat
|
|
362
|
+
|
|
363
|
+
stream_idle_timeout_seconds = max(
|
|
364
|
+
0.001,
|
|
365
|
+
float(
|
|
366
|
+
provider_compat.stream_idle_timeout(
|
|
367
|
+
base_url=selected_model.endpoint_url,
|
|
368
|
+
model=selected_model.model,
|
|
369
|
+
fallback=self._timeout_seconds,
|
|
370
|
+
)
|
|
371
|
+
or self._timeout_seconds
|
|
372
|
+
),
|
|
158
373
|
)
|
|
374
|
+
text_parts: list[str] = []
|
|
375
|
+
reasoning_parts: list[str] = []
|
|
376
|
+
reasoning_only_action_chars = 0
|
|
377
|
+
tool_calls: list[HarnessToolCall] = []
|
|
378
|
+
invalid_tool_name: str | None = None
|
|
379
|
+
usage = None
|
|
380
|
+
stream_kwargs = {
|
|
381
|
+
"messages": [dict(message) for message in messages],
|
|
382
|
+
"network_policy": self._network_policy,
|
|
383
|
+
"timeout_seconds": self._timeout_seconds,
|
|
384
|
+
"tools": [dict(tool.openai_schema) for tool in tools],
|
|
385
|
+
"max_output_tokens": max_output_tokens,
|
|
386
|
+
"reasoning_effort": reasoning_effort,
|
|
387
|
+
}
|
|
388
|
+
if hasattr(self._client, "stream_events"):
|
|
389
|
+
# Studio and direct SDK execution both consume the canonical model
|
|
390
|
+
# event vocabulary. This small compatibility projection preserves
|
|
391
|
+
# the established HarnessReasoner protocol while keeping provider
|
|
392
|
+
# wire chunks out of the loop and UI layers.
|
|
393
|
+
from ksadk.model_gateway.events import ModelStreamEventType
|
|
394
|
+
from ksadk.studio.contracts import Usage
|
|
395
|
+
from ksadk.studio.model_client import ModelStreamChunk, ToolCall
|
|
159
396
|
|
|
397
|
+
async def _canonical_chunks():
|
|
398
|
+
async for event in self._client.stream_events(
|
|
399
|
+
selected_model, **stream_kwargs
|
|
400
|
+
):
|
|
401
|
+
if event.type is ModelStreamEventType.TEXT_DELTA:
|
|
402
|
+
yield ModelStreamChunk(
|
|
403
|
+
text=event.text,
|
|
404
|
+
provider_request_id=event.provider_request_id,
|
|
405
|
+
)
|
|
406
|
+
elif event.type is ModelStreamEventType.REASONING_DELTA:
|
|
407
|
+
yield ModelStreamChunk(
|
|
408
|
+
reasoning=event.text,
|
|
409
|
+
provider_request_id=event.provider_request_id,
|
|
410
|
+
)
|
|
411
|
+
elif event.type is ModelStreamEventType.TOOL_CALL_COMPLETED:
|
|
412
|
+
yield ModelStreamChunk(
|
|
413
|
+
tool_calls=(
|
|
414
|
+
ToolCall(
|
|
415
|
+
id=event.call_id,
|
|
416
|
+
name=event.tool_name,
|
|
417
|
+
arguments=event.arguments,
|
|
418
|
+
),
|
|
419
|
+
),
|
|
420
|
+
provider_request_id=event.provider_request_id,
|
|
421
|
+
)
|
|
422
|
+
elif event.type is ModelStreamEventType.USAGE_UPDATED:
|
|
423
|
+
values = event.usage or {}
|
|
424
|
+
yield ModelStreamChunk(
|
|
425
|
+
usage=Usage(
|
|
426
|
+
input_tokens=int(values.get("input_tokens") or 0),
|
|
427
|
+
output_tokens=int(values.get("output_tokens") or 0),
|
|
428
|
+
total_tokens=int(values.get("input_tokens") or 0)
|
|
429
|
+
+ int(values.get("output_tokens") or 0),
|
|
430
|
+
cached_input_tokens=int(values.get("cached_tokens") or 0),
|
|
431
|
+
reasoning_output_tokens=int(
|
|
432
|
+
values.get("reasoning_tokens") or 0
|
|
433
|
+
),
|
|
434
|
+
reported=True,
|
|
435
|
+
source="model-gateway",
|
|
436
|
+
),
|
|
437
|
+
provider_request_id=event.provider_request_id,
|
|
438
|
+
)
|
|
439
|
+
elif event.type is ModelStreamEventType.TURN_COMPLETED:
|
|
440
|
+
yield ModelStreamChunk(
|
|
441
|
+
done=True,
|
|
442
|
+
finish_reason=str(
|
|
443
|
+
event.metadata.get("finish_reason") or ""
|
|
444
|
+
),
|
|
445
|
+
provider_request_id=event.provider_request_id,
|
|
446
|
+
)
|
|
447
|
+
|
|
448
|
+
stream = _canonical_chunks()
|
|
449
|
+
else:
|
|
450
|
+
stream = self._client.stream(selected_model, **stream_kwargs)
|
|
451
|
+
iterator = stream.__aiter__()
|
|
452
|
+
loop = asyncio.get_running_loop()
|
|
453
|
+
total_deadline = loop.time() + self._total_timeout_seconds
|
|
454
|
+
idle_deadline = loop.time() + stream_idle_timeout_seconds
|
|
160
455
|
|
|
161
|
-
|
|
456
|
+
async def _raise_idle_timeout(*, close_stream: bool) -> None:
|
|
457
|
+
"""终止无进展流,把重试决策交给统一 provider policy。"""
|
|
458
|
+
|
|
459
|
+
# ``asyncio.wait_for(iterator.__anext__())`` 超时会先取消并等待当前
|
|
460
|
+
# ``__anext__``,取消会沿着 httpx 流自动释放连接。此时再次并发
|
|
461
|
+
# ``aclose`` 会让 Python 的异步生成器终结器报
|
|
462
|
+
# ``aclose(): asynchronous generator is already running``。只有尚未
|
|
463
|
+
# 启动 ``__anext__`` 就发现预算耗尽时,才需要在这里主动关闭。
|
|
464
|
+
if close_stream:
|
|
465
|
+
try:
|
|
466
|
+
await stream.aclose()
|
|
467
|
+
except Exception: # noqa: BLE001 - 关闭失败不能遮蔽真正的空闲超时
|
|
468
|
+
pass
|
|
469
|
+
raise TimeoutError(
|
|
470
|
+
"model stream made no progress for "
|
|
471
|
+
f"{stream_idle_timeout_seconds:g} seconds"
|
|
472
|
+
)
|
|
473
|
+
|
|
474
|
+
while True:
|
|
475
|
+
now = loop.time()
|
|
476
|
+
if now >= total_deadline:
|
|
477
|
+
# 整轮预算耗尽:不再发起新请求,保持原有硬失败语义(由循环层
|
|
478
|
+
# 决定重试或切换候选模型),不做缓冲回退。
|
|
479
|
+
raise TimeoutError("model stream exceeded the run budget")
|
|
480
|
+
budget = min(idle_deadline, total_deadline) - now
|
|
481
|
+
if budget <= 0:
|
|
482
|
+
# 走到这里只可能是空闲进度超时(总预算已在上面拦下)。
|
|
483
|
+
await _raise_idle_timeout(close_stream=True)
|
|
484
|
+
try:
|
|
485
|
+
chunk = await asyncio.wait_for(iterator.__anext__(), timeout=budget)
|
|
486
|
+
except StopAsyncIteration:
|
|
487
|
+
break
|
|
488
|
+
except (asyncio.TimeoutError, TimeoutError):
|
|
489
|
+
if loop.time() >= total_deadline:
|
|
490
|
+
raise TimeoutError(
|
|
491
|
+
"model stream exceeded the run budget"
|
|
492
|
+
) from None
|
|
493
|
+
await _raise_idle_timeout(close_stream=False)
|
|
494
|
+
if (chunk.text or chunk.reasoning or chunk.public_summary
|
|
495
|
+
or chunk.tool_calls or chunk.done):
|
|
496
|
+
# 真实内容增量证明运输活着:正文、思考、工具调用和完成
|
|
497
|
+
# 信号都顺延空闲计时。无限 reasoning-only 回合由 total_deadline
|
|
498
|
+
# 截止;usage/keepalive 仍不续命。
|
|
499
|
+
idle_deadline = loop.time() + stream_idle_timeout_seconds
|
|
500
|
+
if chunk.text:
|
|
501
|
+
text_parts.append(chunk.text)
|
|
502
|
+
yield {"text_delta": chunk.text}
|
|
503
|
+
if chunk.public_summary:
|
|
504
|
+
yield {"summary_delta": chunk.public_summary}
|
|
505
|
+
if chunk.reasoning:
|
|
506
|
+
reasoning_parts.append(chunk.reasoning)
|
|
507
|
+
reasoning_only_action_chars += len(chunk.reasoning)
|
|
508
|
+
yield {"reasoning_delta": chunk.reasoning}
|
|
509
|
+
if (
|
|
510
|
+
tools
|
|
511
|
+
and not text_parts
|
|
512
|
+
and not tool_calls
|
|
513
|
+
and reasoning_only_action_chars
|
|
514
|
+
>= _reasoning_only_action_budget_chars()
|
|
515
|
+
):
|
|
516
|
+
# The transport is healthy, but the Agent has made no
|
|
517
|
+
# observable progress. Live GLM 5.3 Flash comparison
|
|
518
|
+
# produced 20,366 reasoning chunks and zero tool calls in
|
|
519
|
+
# Studio; native DeepAgents and bare Pi showed the same
|
|
520
|
+
# first-response failure. A measured provider probe
|
|
521
|
+
# recovered in 1.13s only when thinking was disabled and
|
|
522
|
+
# one tool call was required. Apply that narrow recovery
|
|
523
|
+
# once, then return to the ordinary auto policy on the
|
|
524
|
+
# following turn.
|
|
525
|
+
try:
|
|
526
|
+
await stream.aclose()
|
|
527
|
+
except Exception: # noqa: BLE001 - recovery owns the next request
|
|
528
|
+
pass
|
|
529
|
+
recovery = await self._client.complete(
|
|
530
|
+
selected_model,
|
|
531
|
+
messages=[
|
|
532
|
+
*[dict(message) for message in messages],
|
|
533
|
+
{
|
|
534
|
+
"role": "system",
|
|
535
|
+
"content": (
|
|
536
|
+
"This tool-capable turn spent its action budget on "
|
|
537
|
+
"reasoning without making progress. Call exactly one "
|
|
538
|
+
"small, relevant tool now to inspect or advance the "
|
|
539
|
+
"task. Do not draft the complete implementation or "
|
|
540
|
+
"return more reasoning in this recovery turn."
|
|
541
|
+
),
|
|
542
|
+
},
|
|
543
|
+
],
|
|
544
|
+
network_policy=self._network_policy,
|
|
545
|
+
timeout_seconds=self._timeout_seconds,
|
|
546
|
+
max_attempts=1,
|
|
547
|
+
backoff_seconds=0,
|
|
548
|
+
tools=[dict(tool.openai_schema) for tool in tools],
|
|
549
|
+
allow_empty=False,
|
|
550
|
+
retry_on_length=True,
|
|
551
|
+
max_output_tokens=min(2_048, int(max_output_tokens or 2_048)),
|
|
552
|
+
reasoning_effort=reasoning_effort,
|
|
553
|
+
tool_choice="required",
|
|
554
|
+
)
|
|
555
|
+
recovered_calls: list[HarnessToolCall] = []
|
|
556
|
+
for call in recovery.tool_calls:
|
|
557
|
+
arguments = _parse_tool_arguments(call.arguments)
|
|
558
|
+
recovered_calls.append(
|
|
559
|
+
HarnessToolCall(
|
|
560
|
+
call_id=call.id,
|
|
561
|
+
name=call.name,
|
|
562
|
+
arguments=arguments or {},
|
|
563
|
+
invalid_reason=(
|
|
564
|
+
None
|
|
565
|
+
if arguments is not None
|
|
566
|
+
else "model emitted non-JSON-object tool arguments"
|
|
567
|
+
),
|
|
568
|
+
)
|
|
569
|
+
)
|
|
570
|
+
reported_usage = recovery.usage if recovery.usage.reported else None
|
|
571
|
+
yield {
|
|
572
|
+
"turn": HarnessReasoningTurn(
|
|
573
|
+
final_text=recovery.content or None,
|
|
574
|
+
tool_calls=tuple(recovered_calls),
|
|
575
|
+
reasoning=recovery.reasoning or None,
|
|
576
|
+
degraded="reasoning_only_action_recovered",
|
|
577
|
+
usage=None
|
|
578
|
+
if reported_usage is None
|
|
579
|
+
else {
|
|
580
|
+
"input_tokens": max(
|
|
581
|
+
0, int(reported_usage.input_tokens)
|
|
582
|
+
),
|
|
583
|
+
"output_tokens": max(
|
|
584
|
+
0, int(reported_usage.output_tokens)
|
|
585
|
+
),
|
|
586
|
+
"cached_tokens": max(
|
|
587
|
+
0, int(reported_usage.cached_input_tokens)
|
|
588
|
+
),
|
|
589
|
+
"reasoning_tokens": max(
|
|
590
|
+
0, int(reported_usage.reasoning_output_tokens)
|
|
591
|
+
),
|
|
592
|
+
},
|
|
593
|
+
)
|
|
594
|
+
}
|
|
595
|
+
return
|
|
596
|
+
if chunk.usage is not None:
|
|
597
|
+
usage = chunk.usage
|
|
598
|
+
if chunk.tool_calls:
|
|
599
|
+
tool_calls = []
|
|
600
|
+
for call in chunk.tool_calls:
|
|
601
|
+
try:
|
|
602
|
+
arguments = json.loads(call.arguments or "{}")
|
|
603
|
+
except json.JSONDecodeError:
|
|
604
|
+
invalid_tool_name = call.name
|
|
605
|
+
continue
|
|
606
|
+
if not isinstance(arguments, dict):
|
|
607
|
+
invalid_tool_name = call.name
|
|
608
|
+
continue
|
|
609
|
+
tool_calls.append(
|
|
610
|
+
HarnessToolCall(call_id=call.id, name=call.name, arguments=arguments)
|
|
611
|
+
)
|
|
612
|
+
if chunk.done:
|
|
613
|
+
if (
|
|
614
|
+
chunk.finish_reason
|
|
615
|
+
in {"length", "incomplete", "max_tokens", "max_output_tokens"}
|
|
616
|
+
and tools
|
|
617
|
+
and not tool_calls
|
|
618
|
+
):
|
|
619
|
+
# Pi's native auto-continuation treats a length stop as an
|
|
620
|
+
# unfinished turn. Live KSPMAS evidence showed the same
|
|
621
|
+
# GLM request drafting prose until the 2K cap with
|
|
622
|
+
# ``tool_choice=auto``, while a required-action recovery
|
|
623
|
+
# returned a valid tool call in about one second. Do not
|
|
624
|
+
# publish the truncated plan as a final answer.
|
|
625
|
+
recovery = await self._client.complete(
|
|
626
|
+
selected_model,
|
|
627
|
+
messages=[
|
|
628
|
+
*[dict(message) for message in messages],
|
|
629
|
+
{
|
|
630
|
+
"role": "system",
|
|
631
|
+
"content": (
|
|
632
|
+
"The previous tool-capable response was truncated "
|
|
633
|
+
"before it took action. Call exactly one small, "
|
|
634
|
+
"relevant tool now to advance the task. Do not "
|
|
635
|
+
"repeat the plan or draft the complete implementation "
|
|
636
|
+
"in this recovery turn."
|
|
637
|
+
),
|
|
638
|
+
},
|
|
639
|
+
],
|
|
640
|
+
network_policy=self._network_policy,
|
|
641
|
+
timeout_seconds=self._timeout_seconds,
|
|
642
|
+
max_attempts=1,
|
|
643
|
+
backoff_seconds=0,
|
|
644
|
+
tools=[dict(tool.openai_schema) for tool in tools],
|
|
645
|
+
allow_empty=False,
|
|
646
|
+
retry_on_length=True,
|
|
647
|
+
# Unlike reasoning-only recovery, this branch often
|
|
648
|
+
# carries a whole file in structured arguments. The
|
|
649
|
+
# original 2K cap simply truncated the required tool
|
|
650
|
+
# call a second time. Match the existing malformed-
|
|
651
|
+
# argument repair budget so one large write can remain
|
|
652
|
+
# valid JSON.
|
|
653
|
+
max_output_tokens=max(
|
|
654
|
+
16_384,
|
|
655
|
+
int(
|
|
656
|
+
max_output_tokens
|
|
657
|
+
or selected_model.parameters.max_tokens
|
|
658
|
+
or 0
|
|
659
|
+
),
|
|
660
|
+
),
|
|
661
|
+
reasoning_effort=reasoning_effort,
|
|
662
|
+
tool_choice="required",
|
|
663
|
+
)
|
|
664
|
+
recovered_calls: list[HarnessToolCall] = []
|
|
665
|
+
for call in recovery.tool_calls:
|
|
666
|
+
arguments = _parse_tool_arguments(call.arguments)
|
|
667
|
+
recovered_calls.append(
|
|
668
|
+
HarnessToolCall(
|
|
669
|
+
call_id=call.id,
|
|
670
|
+
name=call.name,
|
|
671
|
+
arguments=arguments or {},
|
|
672
|
+
invalid_reason=(
|
|
673
|
+
None
|
|
674
|
+
if arguments is not None
|
|
675
|
+
else "model emitted non-JSON-object tool arguments"
|
|
676
|
+
),
|
|
677
|
+
)
|
|
678
|
+
)
|
|
679
|
+
reported_usage = recovery.usage if recovery.usage.reported else None
|
|
680
|
+
yield {
|
|
681
|
+
"turn": HarnessReasoningTurn(
|
|
682
|
+
tool_calls=tuple(recovered_calls),
|
|
683
|
+
reasoning=recovery.reasoning or None,
|
|
684
|
+
degraded="length_truncated_action_recovered",
|
|
685
|
+
usage=None
|
|
686
|
+
if reported_usage is None
|
|
687
|
+
else {
|
|
688
|
+
"input_tokens": max(
|
|
689
|
+
0, int(reported_usage.input_tokens)
|
|
690
|
+
),
|
|
691
|
+
"output_tokens": max(
|
|
692
|
+
0, int(reported_usage.output_tokens)
|
|
693
|
+
),
|
|
694
|
+
"cached_tokens": max(
|
|
695
|
+
0, int(reported_usage.cached_input_tokens)
|
|
696
|
+
),
|
|
697
|
+
"reasoning_tokens": max(
|
|
698
|
+
0, int(reported_usage.reasoning_output_tokens)
|
|
699
|
+
),
|
|
700
|
+
},
|
|
701
|
+
)
|
|
702
|
+
}
|
|
703
|
+
return
|
|
704
|
+
if invalid_tool_name:
|
|
705
|
+
# Some OpenAI-compatible GLM gateways truncate or slightly
|
|
706
|
+
# corrupt a large native function-call JSON object. The
|
|
707
|
+
# first attempt's public prose has already streamed, so ask
|
|
708
|
+
# once for the intended call again with a larger budget and
|
|
709
|
+
# consume only its structured call. Raw invalid arguments
|
|
710
|
+
# are never placed back into model context or Studio events.
|
|
711
|
+
repair = await self._client.complete(
|
|
712
|
+
selected_model,
|
|
713
|
+
messages=[
|
|
714
|
+
*[dict(message) for message in messages],
|
|
715
|
+
{
|
|
716
|
+
"role": "system",
|
|
717
|
+
"content": (
|
|
718
|
+
"The previous tool call could not be parsed. "
|
|
719
|
+
f"Retry the intended {invalid_tool_name} call once with "
|
|
720
|
+
"valid JSON arguments. Keep the file content concise enough "
|
|
721
|
+
"to fit in one tool call and do not repeat the analysis."
|
|
722
|
+
),
|
|
723
|
+
},
|
|
724
|
+
],
|
|
725
|
+
network_policy=self._network_policy,
|
|
726
|
+
timeout_seconds=self._timeout_seconds,
|
|
727
|
+
max_attempts=self._max_attempts,
|
|
728
|
+
backoff_seconds=self._backoff_seconds,
|
|
729
|
+
tools=[dict(tool.openai_schema) for tool in tools],
|
|
730
|
+
allow_empty=bool(tools),
|
|
731
|
+
retry_on_length=True,
|
|
732
|
+
max_output_tokens=max(
|
|
733
|
+
16_384,
|
|
734
|
+
int(
|
|
735
|
+
max_output_tokens
|
|
736
|
+
or selected_model.parameters.max_tokens
|
|
737
|
+
or 0
|
|
738
|
+
),
|
|
739
|
+
),
|
|
740
|
+
reasoning_effort=reasoning_effort,
|
|
741
|
+
)
|
|
742
|
+
tool_calls = []
|
|
743
|
+
for call in repair.tool_calls:
|
|
744
|
+
arguments = _parse_tool_arguments(call.arguments)
|
|
745
|
+
if arguments is None:
|
|
746
|
+
# 修复轮仍给出坏参数:保留 invalid_reason,交给循环层
|
|
747
|
+
# 以 invalid_arguments 回灌,不中断整轮。
|
|
748
|
+
tool_calls.append(
|
|
749
|
+
HarnessToolCall(
|
|
750
|
+
call_id=call.id,
|
|
751
|
+
name=call.name,
|
|
752
|
+
arguments={},
|
|
753
|
+
invalid_reason=(
|
|
754
|
+
"model emitted non-JSON-object tool arguments"
|
|
755
|
+
),
|
|
756
|
+
)
|
|
757
|
+
)
|
|
758
|
+
continue
|
|
759
|
+
tool_calls.append(
|
|
760
|
+
HarnessToolCall(
|
|
761
|
+
call_id=call.id,
|
|
762
|
+
name=call.name,
|
|
763
|
+
arguments=arguments,
|
|
764
|
+
)
|
|
765
|
+
)
|
|
766
|
+
# 修复轮完全没有给出调用:按"纯文本回合"收尾(不加人造调用,
|
|
767
|
+
# 否则会产生没有配对 tool_call 的 tool result)。
|
|
768
|
+
usage = repair.usage
|
|
769
|
+
yield {
|
|
770
|
+
"turn": HarnessReasoningTurn(
|
|
771
|
+
final_text=(
|
|
772
|
+
"".join(text_parts)
|
|
773
|
+
or (repair.content if invalid_tool_name else "")
|
|
774
|
+
or None
|
|
775
|
+
),
|
|
776
|
+
tool_calls=tuple(tool_calls),
|
|
777
|
+
reasoning=(
|
|
778
|
+
"".join(reasoning_parts)
|
|
779
|
+
or (repair.reasoning if invalid_tool_name else "")
|
|
780
|
+
or None
|
|
781
|
+
),
|
|
782
|
+
usage=None
|
|
783
|
+
if usage is None
|
|
784
|
+
else {
|
|
785
|
+
"input_tokens": max(0, int(usage.input_tokens)),
|
|
786
|
+
"output_tokens": max(0, int(usage.output_tokens)),
|
|
787
|
+
"cached_tokens": max(0, int(usage.cached_input_tokens)),
|
|
788
|
+
"reasoning_tokens": max(0, int(usage.reasoning_output_tokens)),
|
|
789
|
+
},
|
|
790
|
+
)
|
|
791
|
+
}
|
|
792
|
+
|
|
793
|
+
|
|
794
|
+
class StudioPluginRuntime(StudioNativeActivationMixin):
|
|
162
795
|
"""Resolve, activate, and retain composed providers for Studio sessions."""
|
|
163
796
|
|
|
164
797
|
def __init__(
|
|
@@ -170,14 +803,21 @@ class StudioPluginRuntime:
|
|
|
170
803
|
model_client: OpenAICompatibleModelClient,
|
|
171
804
|
secret_resolver: Any,
|
|
172
805
|
harness_reasoner: HarnessReasoner | None = None,
|
|
806
|
+
harness_engine_selector: HarnessEngineSelector | None = None,
|
|
807
|
+
harness_native_adapter_builder: HarnessNativeAdapterBuilder | None = None,
|
|
808
|
+
harness_native_session_enabled: Callable[[str, str], bool] | None = None,
|
|
173
809
|
provider_manifests: Mapping[str, PluginManifest] | None = None,
|
|
174
810
|
provider_factories: Mapping[str, Any] | None = None,
|
|
811
|
+
hook_registrations: tuple[StudioNativeHookRegistration, ...] = (),
|
|
812
|
+
context_registrations: tuple[StudioNativeContextRegistration, ...] = (),
|
|
175
813
|
legacy_harness_sources: Sequence[LegacyHarnessSource] = (),
|
|
176
814
|
dsh_capability_service: Any | None = None,
|
|
177
815
|
resource_dsh_capability_service: Any | None = None,
|
|
178
816
|
resource_authority: Any | None = None,
|
|
179
817
|
resource_connections: Any | None = None,
|
|
180
818
|
resource_actor_ref: str = "local-user",
|
|
819
|
+
native_tenant_id: str = "local-studio",
|
|
820
|
+
native_workspace_id: str | None = None,
|
|
181
821
|
codex_local_launch_resolver: Any = None,
|
|
182
822
|
runtime_executor: RuntimeExecutor | None = None,
|
|
183
823
|
) -> None:
|
|
@@ -187,8 +827,15 @@ class StudioPluginRuntime:
|
|
|
187
827
|
self._model_client = model_client
|
|
188
828
|
self._secret_resolver = secret_resolver
|
|
189
829
|
self._harness_reasoner = harness_reasoner
|
|
830
|
+
if (harness_engine_selector is None) != (harness_native_adapter_builder is None):
|
|
831
|
+
raise ValueError("Native Harness requires both host selector and adapter builder")
|
|
832
|
+
self._harness_engine_selector = harness_engine_selector
|
|
833
|
+
self._harness_native_adapter_builder = harness_native_adapter_builder
|
|
834
|
+
self._harness_native_session_enabled = harness_native_session_enabled
|
|
190
835
|
self._provider_manifests = dict(provider_manifests or {})
|
|
191
836
|
self._provider_factories = dict(provider_factories or {})
|
|
837
|
+
self._hook_registrations = tuple(hook_registrations)
|
|
838
|
+
self._context_registrations = tuple(context_registrations)
|
|
192
839
|
self._dsh_capability_service = dsh_capability_service
|
|
193
840
|
self._resource_dsh_capability_service = (
|
|
194
841
|
resource_dsh_capability_service or dsh_capability_service
|
|
@@ -196,14 +843,23 @@ class StudioPluginRuntime:
|
|
|
196
843
|
self._resource_authority = resource_authority
|
|
197
844
|
self._resource_connections = resource_connections
|
|
198
845
|
self._resource_actor_ref = resource_actor_ref
|
|
846
|
+
self._native_tenant_id = native_tenant_id
|
|
847
|
+
self._native_workspace_id = native_workspace_id
|
|
199
848
|
self._codex_local_launch_resolver = codex_local_launch_resolver
|
|
200
849
|
self._runtime_executor = runtime_executor
|
|
201
850
|
self._legacy_bundles = LegacyBundleAdapter(legacy_harness_sources)
|
|
202
851
|
self._lock = asyncio.Lock()
|
|
203
852
|
self._hosts: dict[str, _HostEntry] = {}
|
|
853
|
+
self._native_activations: dict[tuple[str, str], _NativeActivation] = {}
|
|
854
|
+
self._activation_locks: dict[str, asyncio.Lock] = {}
|
|
204
855
|
self._resource_write_modes: dict[str, str] = {}
|
|
205
|
-
self.
|
|
856
|
+
self._admission = RuntimeAdmissionGate()
|
|
206
857
|
self._closed = False
|
|
858
|
+
self.execution_policy_resolver: Any | None = None
|
|
859
|
+
|
|
860
|
+
@property
|
|
861
|
+
def _admission_open(self) -> bool:
|
|
862
|
+
return self._admission.is_open
|
|
207
863
|
|
|
208
864
|
def replace_provider_registrations(
|
|
209
865
|
self,
|
|
@@ -251,8 +907,29 @@ class StudioPluginRuntime:
|
|
|
251
907
|
dynamic_dsh_mcp = self._bundle_uses_dynamic_dsh(bundle)
|
|
252
908
|
selected_model = self._select_model(build, model)
|
|
253
909
|
resolved = bundle.resolved_agent_spec
|
|
910
|
+
primary_model = resolved.get("model")
|
|
911
|
+
candidate_models = [primary_model]
|
|
912
|
+
fallback_models = resolved.get("fallbackModels") or resolved.get("fallback_models")
|
|
913
|
+
if isinstance(fallback_models, list):
|
|
914
|
+
candidate_models.extend(fallback_models)
|
|
915
|
+
selected_model_spec = next(
|
|
916
|
+
(
|
|
917
|
+
item
|
|
918
|
+
for item in candidate_models
|
|
919
|
+
if isinstance(item, Mapping) and str(item.get("model") or "") == selected_model
|
|
920
|
+
),
|
|
921
|
+
primary_model if isinstance(primary_model, Mapping) else {},
|
|
922
|
+
)
|
|
254
923
|
instructions = resolved.get("instructions")
|
|
255
924
|
instructions = instructions if isinstance(instructions, Mapping) else {}
|
|
925
|
+
context_spec = resolved.get("context")
|
|
926
|
+
context_spec = context_spec if isinstance(context_spec, Mapping) else {}
|
|
927
|
+
max_input_tokens = context_spec.get("maxInputTokens") or context_spec.get(
|
|
928
|
+
"max_input_tokens"
|
|
929
|
+
)
|
|
930
|
+
reserve_output_tokens = context_spec.get(
|
|
931
|
+
"reserveOutputTokens"
|
|
932
|
+
) or context_spec.get("reserve_output_tokens")
|
|
256
933
|
provider_id, _provider_version = _parse_plugin_ref(
|
|
257
934
|
bundle.composition.profile.agent_provider.ref
|
|
258
935
|
)
|
|
@@ -260,6 +937,9 @@ class StudioPluginRuntime:
|
|
|
260
937
|
CODEX_AGENT_PROVIDER_PLUGIN_ID: "codex",
|
|
261
938
|
KSADK_HARNESS_AGENT_PROVIDER_PLUGIN_ID: "harness",
|
|
262
939
|
}.get(provider_id)
|
|
940
|
+
execution_spec = resolved.get("execution")
|
|
941
|
+
execution_spec = execution_spec if isinstance(execution_spec, Mapping) else {}
|
|
942
|
+
approval_timeout = execution_spec.get("approvalTimeoutSeconds")
|
|
263
943
|
return StudioRunSpec(
|
|
264
944
|
launch_context=RuntimeLaunchContext(
|
|
265
945
|
runtime_type=runtime_type,
|
|
@@ -269,6 +949,7 @@ class StudioPluginRuntime:
|
|
|
269
949
|
build_id=build.id,
|
|
270
950
|
agent_id=build.agent_id,
|
|
271
951
|
model=selected_model,
|
|
952
|
+
model_metadata=dict(selected_model_spec.get("metadata") or {}),
|
|
272
953
|
request_config={
|
|
273
954
|
"agent_system": str(instructions.get("system") or ""),
|
|
274
955
|
"agent_task": str(instructions.get("task") or ""),
|
|
@@ -278,10 +959,27 @@ class StudioPluginRuntime:
|
|
|
278
959
|
"provider_runtime_type": provider_runtime_type or "",
|
|
279
960
|
"provider_ref": bundle.composition.profile.agent_provider.ref,
|
|
280
961
|
**(
|
|
281
|
-
{"
|
|
282
|
-
if
|
|
962
|
+
{"approval_timeout_seconds": int(approval_timeout)}
|
|
963
|
+
if provider_runtime_type == "harness" and approval_timeout is not None
|
|
964
|
+
else {}
|
|
965
|
+
),
|
|
966
|
+
# Provider-backed Harness runs use this resolver rather than
|
|
967
|
+
# FrameworkRunSpecResolver. Preserve the immutable AgentVersion
|
|
968
|
+
# budget here as well, otherwise ManagedHarnessRuntimeAdapter
|
|
969
|
+
# cannot derive the real model window and silently falls back
|
|
970
|
+
# to 32K for every Studio run.
|
|
971
|
+
**(
|
|
972
|
+
{"max_input_tokens": int(max_input_tokens)}
|
|
973
|
+
if max_input_tokens is not None
|
|
974
|
+
else {}
|
|
975
|
+
),
|
|
976
|
+
**(
|
|
977
|
+
{"reserve_output_tokens": int(reserve_output_tokens)}
|
|
978
|
+
if reserve_output_tokens is not None
|
|
283
979
|
else {}
|
|
284
980
|
),
|
|
981
|
+
**({"tool_approval_mode": normalize_tool_approval_mode(approval_mode)}
|
|
982
|
+
if provider_runtime_type == "harness" or approval_mode else {}),
|
|
285
983
|
},
|
|
286
984
|
manifest_sha256=build.resolved_digest,
|
|
287
985
|
plugin_bundle_root=bundle_root,
|
|
@@ -298,7 +996,7 @@ class StudioPluginRuntime:
|
|
|
298
996
|
raise PluginHostError(
|
|
299
997
|
"plugin_bundle_unavailable", "Studio run has no PluginHost Bundle"
|
|
300
998
|
)
|
|
301
|
-
entry = await self._host_for(spec.plugin_bundle_root)
|
|
999
|
+
entry = await self._admission.resolve(lambda: self._host_for(spec.plugin_bundle_root))
|
|
302
1000
|
if entry.agent_id != spec.agent_id:
|
|
303
1001
|
raise PluginHostError(
|
|
304
1002
|
"plugin_bundle_agent_mismatch",
|
|
@@ -311,6 +1009,7 @@ class StudioPluginRuntime:
|
|
|
311
1009
|
activation = await entry.host.open_activation(
|
|
312
1010
|
entry.bundle,
|
|
313
1011
|
activation_key=session_id,
|
|
1012
|
+
activation_claims=await self._native_activation_claims(spec, session_id),
|
|
314
1013
|
)
|
|
315
1014
|
except BaseException:
|
|
316
1015
|
self._resource_write_modes.pop(session_id, None)
|
|
@@ -339,64 +1038,34 @@ class StudioPluginRuntime:
|
|
|
339
1038
|
)
|
|
340
1039
|
return lambda: StudioPluginKernelAdapter(self, spec)
|
|
341
1040
|
|
|
342
|
-
async def kernel_adapter(
|
|
343
|
-
self,
|
|
344
|
-
spec: StudioRunSpec,
|
|
345
|
-
*,
|
|
346
|
-
session_id: str,
|
|
347
|
-
) -> Any:
|
|
348
|
-
"""Bind a Scheduler run to the provider-owned activation adapter."""
|
|
349
1041
|
|
|
350
|
-
if spec.plugin_bundle_root is None:
|
|
351
|
-
raise StudioError(
|
|
352
|
-
"PLUGIN_RUNTIME_UNAVAILABLE",
|
|
353
|
-
"Studio Build 没有 PluginHost Bundle",
|
|
354
|
-
status_code=409,
|
|
355
|
-
)
|
|
356
|
-
entry = await self._host_for(spec.plugin_bundle_root)
|
|
357
|
-
if entry.agent_id != spec.agent_id:
|
|
358
|
-
raise PluginHostError(
|
|
359
|
-
"plugin_bundle_agent_mismatch",
|
|
360
|
-
"Studio run Agent does not match its immutable PluginHost Bundle",
|
|
361
|
-
)
|
|
362
|
-
self._resource_write_modes[session_id] = str(
|
|
363
|
-
spec.request_config.get("tool_approval_mode") or ""
|
|
364
|
-
)
|
|
365
|
-
try:
|
|
366
|
-
activation = await entry.host.open_activation(
|
|
367
|
-
entry.bundle,
|
|
368
|
-
activation_key=session_id,
|
|
369
|
-
)
|
|
370
|
-
except BaseException:
|
|
371
|
-
self._resource_write_modes.pop(session_id, None)
|
|
372
|
-
raise
|
|
373
|
-
try:
|
|
374
|
-
return await activation.runtime_adapter()
|
|
375
|
-
except BaseException:
|
|
376
|
-
try:
|
|
377
|
-
await activation.close()
|
|
378
|
-
finally:
|
|
379
|
-
self._resource_write_modes.pop(session_id, None)
|
|
380
|
-
raise
|
|
381
1042
|
|
|
382
|
-
|
|
383
|
-
|
|
384
|
-
entries = tuple(self._hosts.values())
|
|
385
|
-
try:
|
|
386
|
-
for entry in entries:
|
|
387
|
-
await entry.host.close_activation(session_id)
|
|
388
|
-
finally:
|
|
389
|
-
self._resource_write_modes.pop(session_id, None)
|
|
1043
|
+
|
|
1044
|
+
|
|
390
1045
|
|
|
391
1046
|
async def close_session_if_dynamic(self, spec: StudioRunSpec, session_id: str) -> None:
|
|
392
|
-
|
|
393
|
-
|
|
1047
|
+
# 每轮运行后关闭 dynamic-DSH MCP 激活会让下一轮重新 spawn/health/list
|
|
1048
|
+
# 全部 MCP server(实测 ~12s),这是 harness 首 token 延迟的主因。
|
|
1049
|
+
# open_activation 以 session 为 key 复用同一激活(图与 Bundle digest
|
|
1050
|
+
# 不变),因此跨轮保留激活;激活只在会话删除(close_session)与
|
|
1051
|
+
# Studio 退出(aclose)时释放。
|
|
1052
|
+
return None
|
|
1053
|
+
|
|
1054
|
+
def check_configuration_mutable(self) -> None:
|
|
1055
|
+
if self._hosts:
|
|
1056
|
+
raise StudioError(
|
|
1057
|
+
"SETTINGS_RUNTIME_BUSY", "请通过设置接口刷新运行配置", status_code=409
|
|
1058
|
+
)
|
|
1059
|
+
|
|
1060
|
+
def replace_resource_authority(self, authority: Any) -> None:
|
|
1061
|
+
self.check_configuration_mutable()
|
|
1062
|
+
self._resource_authority = authority
|
|
394
1063
|
|
|
395
1064
|
async def suspend_admission(self) -> None:
|
|
396
1065
|
"""Stop new activations and drain every currently owned host."""
|
|
397
1066
|
|
|
398
1067
|
async with self._lock:
|
|
399
|
-
self.
|
|
1068
|
+
self._admission.suspend()
|
|
400
1069
|
entries = tuple(self._hosts.values())
|
|
401
1070
|
self._hosts.clear()
|
|
402
1071
|
cleanup = asyncio.create_task(self._dispose_entries(entries))
|
|
@@ -417,7 +1086,7 @@ class StudioPluginRuntime:
|
|
|
417
1086
|
"plugin_runtime_closed",
|
|
418
1087
|
"Studio plugin runtime is closed",
|
|
419
1088
|
)
|
|
420
|
-
self.
|
|
1089
|
+
self._admission.resume()
|
|
421
1090
|
|
|
422
1091
|
@staticmethod
|
|
423
1092
|
async def _dispose_entries(entries: Sequence[_HostEntry]) -> None:
|
|
@@ -435,7 +1104,7 @@ class StudioPluginRuntime:
|
|
|
435
1104
|
if self._closed:
|
|
436
1105
|
return
|
|
437
1106
|
self._closed = True
|
|
438
|
-
self.
|
|
1107
|
+
self._admission.close()
|
|
439
1108
|
entries = tuple(self._hosts.values())
|
|
440
1109
|
self._hosts.clear()
|
|
441
1110
|
cleanup = asyncio.create_task(self._dispose_entries(entries))
|
|
@@ -453,14 +1122,24 @@ class StudioPluginRuntime:
|
|
|
453
1122
|
# Re-resolve every turn. This deliberately rechecks enabled receipts and
|
|
454
1123
|
# package digests rather than trusting a previously healthy child.
|
|
455
1124
|
bundle = self._resolve_bundle(bundle_root)
|
|
1125
|
+
if any(
|
|
1126
|
+
item.ref == PLATFORM_RESOURCE_MCP_REF
|
|
1127
|
+
for item in bundle.composition.profile.capabilities
|
|
1128
|
+
) and not callable(getattr(self._resource_authority, "admit_runtime", None)):
|
|
1129
|
+
raise StudioError(
|
|
1130
|
+
"PLATFORM_RESOURCE_CONFIGURATION_REQUIRED",
|
|
1131
|
+
"平台资源连接尚未配置,请在设置的云端连接中填写账号凭据和控制面地址",
|
|
1132
|
+
status_code=422,
|
|
1133
|
+
)
|
|
456
1134
|
key = bundle.bundle_digest
|
|
1135
|
+
await self._admission.wait()
|
|
457
1136
|
async with self._lock:
|
|
458
1137
|
if self._closed:
|
|
459
1138
|
raise PluginHostError(
|
|
460
1139
|
"plugin_runtime_closed",
|
|
461
1140
|
"Studio plugin runtime is closed",
|
|
462
1141
|
)
|
|
463
|
-
if not self.
|
|
1142
|
+
if not self._admission.is_open:
|
|
464
1143
|
raise PluginHostError(
|
|
465
1144
|
"plugin_runtime_reconfiguring",
|
|
466
1145
|
"Studio plugin runtime is reconfiguring",
|
|
@@ -481,8 +1160,15 @@ class StudioPluginRuntime:
|
|
|
481
1160
|
# Providers resolve credential *references* at activation time.
|
|
482
1161
|
# The DSH discovery host never receives this service.
|
|
483
1162
|
"credential_resolver": self._secret_resolver,
|
|
1163
|
+
# Harness Provider 持久 Checkpoint/RunStore/Receipt 的状态根
|
|
1164
|
+
# (与 builtin capability factories 同一 Workspace 命名空间)。
|
|
1165
|
+
"harness_state_dir": str(self.workspace.resolve(".agentkit/plugin-runtime/state")),
|
|
1166
|
+
# 用户当前选择的 Studio 工作区:harness 的文件工具应写在这里,
|
|
1167
|
+
# 而不是 plugin-runtime state 的哈希目录里。
|
|
1168
|
+
"harness_workspace_root": str(self.workspace.root),
|
|
484
1169
|
"codex_local_launch_resolver": self._codex_local_launch_resolver,
|
|
485
1170
|
"runtime_executor": self._runtime_executor,
|
|
1171
|
+
"execution_policy_resolver": self.execution_policy_resolver,
|
|
486
1172
|
"dsh_capability_service": self._resource_dsh_capability_service,
|
|
487
1173
|
"resource_authority": self._resource_authority,
|
|
488
1174
|
"resource_connections": self._resource_connections,
|
|
@@ -496,6 +1182,11 @@ class StudioPluginRuntime:
|
|
|
496
1182
|
services["harness_reasoner"] = (
|
|
497
1183
|
self._harness_reasoner or self._bound_harness_reasoner(verified)
|
|
498
1184
|
)
|
|
1185
|
+
if self._harness_engine_selector is not None:
|
|
1186
|
+
services["harness_engine_selector"] = self._harness_engine_selector
|
|
1187
|
+
services["harness_native_adapter_builder"] = (
|
|
1188
|
+
self._harness_native_adapter_builder
|
|
1189
|
+
)
|
|
499
1190
|
host = PluginHost(
|
|
500
1191
|
registry,
|
|
501
1192
|
factories,
|
|
@@ -512,15 +1203,10 @@ class StudioPluginRuntime:
|
|
|
512
1203
|
bundle=verified,
|
|
513
1204
|
host=host,
|
|
514
1205
|
)
|
|
515
|
-
stale = [
|
|
516
|
-
(digest, entry)
|
|
517
|
-
for digest, entry in self._hosts.items()
|
|
518
|
-
if entry.agent_id == candidate.agent_id and digest != key
|
|
519
|
-
]
|
|
520
1206
|
self._hosts[key] = candidate
|
|
521
|
-
|
|
522
|
-
|
|
523
|
-
|
|
1207
|
+
# Distinct immutable Builds of the same Agent may be active in
|
|
1208
|
+
# different authorized sessions. Their profile graphs are owned
|
|
1209
|
+
# until explicit maintenance/close, never evicted by another Build.
|
|
524
1210
|
return candidate
|
|
525
1211
|
|
|
526
1212
|
def _resource_write_authorizer(
|
|
@@ -539,8 +1225,7 @@ class StudioPluginRuntime:
|
|
|
539
1225
|
)
|
|
540
1226
|
dynamic_refs = {reference, PLATFORM_RESOURCE_MCP_REF}
|
|
541
1227
|
return any(
|
|
542
|
-
capability.ref in dynamic_refs
|
|
543
|
-
for capability in bundle.composition.profile.capabilities
|
|
1228
|
+
capability.ref in dynamic_refs for capability in bundle.composition.profile.capabilities
|
|
544
1229
|
)
|
|
545
1230
|
|
|
546
1231
|
def _resolve_bundle(self, bundle_root: Path) -> ResolvedPluginBundle:
|
|
@@ -605,6 +1290,10 @@ class StudioPluginRuntime:
|
|
|
605
1290
|
*builtin_capability_manifests(),
|
|
606
1291
|
dsh_profile_mcp_manifest(),
|
|
607
1292
|
platform_resource_mcp_manifest(),
|
|
1293
|
+
*(item.manifest for item in self._hook_registrations
|
|
1294
|
+
if manifest.agent_id in item.agent_ids),
|
|
1295
|
+
*(item.manifest for item in self._context_registrations
|
|
1296
|
+
if manifest.agent_id in item.agent_ids),
|
|
608
1297
|
]
|
|
609
1298
|
external = self._external_manifest(profile)
|
|
610
1299
|
if external is not None:
|
|
@@ -635,6 +1324,10 @@ class StudioPluginRuntime:
|
|
|
635
1324
|
)
|
|
636
1325
|
factories[DSH_PROFILE_MCP_PLUGIN_ID] = DshProfileMCPFactory(self._dsh_capability_service)
|
|
637
1326
|
factories[PLATFORM_RESOURCE_MCP_PLUGIN_ID] = PlatformResourceMCPFactory()
|
|
1327
|
+
for item in (*self._hook_registrations, *self._context_registrations):
|
|
1328
|
+
if bundle.manifest.agent_id in item.agent_ids:
|
|
1329
|
+
manifests.append(item.manifest)
|
|
1330
|
+
factories[item.manifest.metadata.id] = item.factory
|
|
638
1331
|
provider_id, provider_version = _parse_plugin_ref(
|
|
639
1332
|
bundle.composition.profile.agent_provider.ref
|
|
640
1333
|
)
|
|
@@ -697,6 +1390,13 @@ class StudioPluginRuntime:
|
|
|
697
1390
|
try:
|
|
698
1391
|
host.preflight(bundle.composition.profile)
|
|
699
1392
|
except PluginHostError as error:
|
|
1393
|
+
if error.code == "plugin_permission_denied":
|
|
1394
|
+
raise StudioError(
|
|
1395
|
+
"PLUGIN_PERMISSION_DENIED",
|
|
1396
|
+
"Agent 插件组合未通过运行前检查",
|
|
1397
|
+
status_code=409,
|
|
1398
|
+
details=_permission_denial_details(error),
|
|
1399
|
+
) from error
|
|
700
1400
|
code = (
|
|
701
1401
|
"PLUGIN_PERMISSION_DENIED"
|
|
702
1402
|
if error.code == "plugin_permission_denied"
|
|
@@ -712,22 +1412,33 @@ class StudioPluginRuntime:
|
|
|
712
1412
|
def _bound_harness_reasoner(self, bundle: ResolvedPluginBundle) -> HarnessReasoner:
|
|
713
1413
|
spec = bundle.resolved_agent_spec
|
|
714
1414
|
model = ResolvedModel.model_validate(spec.get("model"))
|
|
1415
|
+
raw_fallback_models = spec.get("fallbackModels") or spec.get("fallback_models") or []
|
|
1416
|
+
fallback_models = tuple(
|
|
1417
|
+
ResolvedModel.model_validate(item)
|
|
1418
|
+
for item in raw_fallback_models
|
|
1419
|
+
if isinstance(item, Mapping)
|
|
1420
|
+
)
|
|
715
1421
|
security = spec.get("security")
|
|
716
1422
|
security = security if isinstance(security, Mapping) else {}
|
|
717
1423
|
network = NetworkPolicy.model_validate(security.get("network") or {})
|
|
718
1424
|
execution = spec.get("execution")
|
|
719
1425
|
execution = execution if isinstance(execution, Mapping) else {}
|
|
720
|
-
retry
|
|
721
|
-
|
|
1426
|
+
# Managed Harness owns provider retry/failover in ModelProviderPolicy.
|
|
1427
|
+
# Retrying again inside the HTTP client multiplies attempts (for
|
|
1428
|
+
# example 3 outer attempts x 2 hidden HTTP attempts), makes the public
|
|
1429
|
+
# attempt counter dishonest, and applies two independent backoffs.
|
|
1430
|
+
# Keep this transport call single-shot; the Harness loop performs the
|
|
1431
|
+
# visible ten-attempt policy and emits one durable event per retry.
|
|
722
1432
|
return _StudioHarnessReasoner(
|
|
723
1433
|
self._model_client,
|
|
724
1434
|
model=model,
|
|
1435
|
+
fallback_models=fallback_models,
|
|
725
1436
|
network_policy=network,
|
|
726
|
-
timeout_seconds=
|
|
727
|
-
|
|
728
|
-
),
|
|
729
|
-
max_attempts=
|
|
730
|
-
backoff_seconds=
|
|
1437
|
+
timeout_seconds=_model_request_timeout_seconds(execution),
|
|
1438
|
+
# 增量传输的硬上限用整个 run 的预算;上面的 timeout 只用于"无进度"。
|
|
1439
|
+
total_timeout_seconds=_model_total_timeout_seconds(execution),
|
|
1440
|
+
max_attempts=1,
|
|
1441
|
+
backoff_seconds=0,
|
|
731
1442
|
)
|
|
732
1443
|
|
|
733
1444
|
def _external_manifest(self, profile: CompositionProfile) -> PluginManifest | None:
|
|
@@ -801,6 +1512,28 @@ def _parse_plugin_ref(value: str) -> tuple[str, str]:
|
|
|
801
1512
|
return plugin_id, version
|
|
802
1513
|
|
|
803
1514
|
|
|
1515
|
+
_PERMISSION_DENIAL_MARKER = "requests unapproved permissions:"
|
|
1516
|
+
|
|
1517
|
+
|
|
1518
|
+
def _permission_denial_details(error: PluginHostError) -> dict[str, Any]:
|
|
1519
|
+
"""把权限拒绝错误转成可自助修复的 details(缺失权限 + 修复指引)。"""
|
|
1520
|
+
|
|
1521
|
+
message = str(error)
|
|
1522
|
+
missing: list[str] = []
|
|
1523
|
+
if _PERMISSION_DENIAL_MARKER in message:
|
|
1524
|
+
tail = message.split(_PERMISSION_DENIAL_MARKER, 1)[1]
|
|
1525
|
+
missing = [item.strip() for item in tail.split(",") if item.strip()]
|
|
1526
|
+
return {
|
|
1527
|
+
"reason": error.code,
|
|
1528
|
+
"missingPermissions": missing,
|
|
1529
|
+
"hint": (
|
|
1530
|
+
"在 Agent 安全设置的允许权限中加入缺失权限后重新构建并运行"
|
|
1531
|
+
if missing
|
|
1532
|
+
else "在 Agent 安全设置中调整允许权限后重新构建并运行"
|
|
1533
|
+
),
|
|
1534
|
+
}
|
|
1535
|
+
|
|
1536
|
+
|
|
804
1537
|
def _normalize_result(raw: Any, *, session_id: str) -> StudioPluginTurnResult:
|
|
805
1538
|
if isinstance(raw, (CodexTurnResult, HarnessTurnResult)):
|
|
806
1539
|
return StudioPluginTurnResult(
|